[syslinux] fix support for recent Syslinux versions

* Detect Syslinux version from isolinux.bin (Closes #272)
* Download required Syslinux v5+ files where needed (Closes #165)
* Also fix an issue where using a Syslinux based ISO didn't switch to ISO mode
* Also alter DownloadFile and ExtractISOFile to return a size
This commit is contained in:
Pete Batard 2014-01-21 17:08:41 +00:00
parent 7e81ec2838
commit 299506056a
9 changed files with 352 additions and 162 deletions

View File

@ -6,6 +6,11 @@ the same changes.
Remember to also update the version number for your translation ('v x.y.z')
once you have matched all the changes that occurred for the en-US translation.
o Version 1.0.8 (2014.01.21)
- MSG_234: 'v%d' is replaced with '%s' (change already applied to existing translations)
- *NEW* MSG_114 "This image uses Syslinux %s but this application only includes Syslinux %s
- *NEW* MSG_115 "Download required"
o Version 1.0.7 (2014.01.01)
- Added MSG_092 again
- Added English example for OK button in About box (IDOK)

View File

@ -286,7 +286,14 @@ t MSG_111 "Incompatible Cluster size"
t MSG_112 "Formatting a large UDF volumes can take a lot of time. At USB 2.0 speeds, the estimated formatting "
"duration is %d:%02d, during which the progress bar will appear frozen. Please be patient!"
t MSG_113 "Large UDF volume"
t MSG_114 "This image uses Syslinux %s but this application only includes Syslinux %s.\n\n"
"As new versions of Syslinux are not compatible with one another, and it is not possible to "
"include them all, Rufus needs to download two additional files ('ldlinux.sys' and 'ldlinux.bss'):\n"
"- Select 'Yes' to connect to the internet and download these files\n"
"- Select 'No' to cancel the operation\n\n"
"Note: The files will be downloaded in the current directory and once "
"they exist there, they will be reused automatically.\n"
t MSG_115 "Download required"
# Tootips
# Partition Scheme and Target Type
t MSG_150 "Usually the safest choice. If you have an UEFI computer and want to install "
@ -384,8 +391,8 @@ t MSG_230 "Copying DOS files..."
t MSG_231 "Copying ISO files..."
t MSG_232 "Win7 EFI boot setup (this may take a while)..."
t MSG_233 "Finalizing, please wait..."
# Takes the Syslinux version as parameter, eg. "Installing Syslinux v5..."
t MSG_234 "Installing Syslinux v%d..."
# Takes a Syslinux version as parameter, eg. "Installing Syslinux v5.10..."
t MSG_234 "Installing Syslinux %s..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "Bad Blocks: PASS %d/%d - %0.2f%% (%d/%d/%d errors)"
t MSG_236 "Bad Blocks: Testing with random pattern"
@ -731,7 +738,7 @@ t MSG_231 "复制 ISO 文件..."
t MSG_232 "设置 Win7 EFI 启动,请耐心等待..."
t MSG_233 "完成中,请稍等候..."
# Takes the Syslinux version as parameter.
t MSG_234 "安装 Syslinux v%d..."
t MSG_234 "安装 Syslinux %s..."
# Bad blocks status.
t MSG_235 "检查坏块:第 %d/%d 遍 - %0.2f%% (%d/%d/%d 错误)"
t MSG_236 "检查坏块:测试中 - 随机模式"
@ -1078,7 +1085,7 @@ t MSG_231 "複製 ISO 檔案..."
t MSG_232 "建置 Win7 EFI 開機架構 (可能要一段時間,請耐心等候)..."
t MSG_233 "收尾中,請稍候..."
# Takes the Syslinux version as paramete. eg. "Installing Syslinux v5..."
t MSG_234 "Syslinux v%d 安裝中..."
t MSG_234 "Syslinux %s 安裝中..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "損毀磁區: 第 %d/%d 回 - %0.2f%% (%d/%d/%d 錯誤)"
t MSG_236 "損毀磁區: 掃描中 (隨機模式)"
@ -1458,7 +1465,7 @@ t MSG_231 "ISO bestanden aan het kopiëren..."
t MSG_232 "Win7 EFI opstart setup (Dit kan een tijdje duren)..."
t MSG_233 "Finaliseren, een moment geduld a.u.b..."
# Takes the Syslinux version as paramete. eg. "Installing Syslinux v5..."
t MSG_234 "Bezig met installeren Syslinux v%d..."
t MSG_234 "Bezig met installeren Syslinux %s..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "Slechte Blokken: Ronde %d/%d - %0.2f%% (%d/%d/%d fouten)"
t MSG_236 "Slechte Blokken: Testen met willekeurig patroon"
@ -1698,7 +1705,7 @@ t MSG_102 "Votre plateforme ne peut pas extraire les fichiers depuis les archive
"est nécéssaire pour créer des médias USB démarrable avec EFI pour Windows 7/8 ou Windows Vista. Vous pouvez addresser "
"ce problème en téléchargeant une version récente de l'utilitaire 7-Zip.\nVoulez-vous visiter la page de téléchargements de 7-zip?"
t MSG_103 "Télécharger %s?"
t MSG_104 "Syslinux v5.0 ou plus récent requiert l'installtion d'un fichier '%s'.\n"
t MSG_104 "Syslinux v5.0 ou plus récent requiert l'installation d'un fichier '%s'.\n"
"Puisque ce fichier fait plus de 100 Ko et est toujours présent sur les images ISO à base de Syslinux v5+, "
"il n'est pas inclus dans l'application.\n\nRufus peut télécharger ce fichier pour vous:\n"
"- Choisissez 'Oui' pour télécharger le fichier depuis Internet\n"
@ -1717,6 +1724,14 @@ t MSG_111 "Taille de clusters incompatible"
t MSG_112 "Le formattage d'un volume UDF de grande taille peut prendre beaucoup de temps. Aux vitesses USB 2.0, "
"la durée de formattage estimée est %d:%02d, pendant laquelle la barre de progrès semblera gelée. Veuillez être patient !"
t MSG_113 "Volume UDF de grand taille"
t MSG_114 "Cette image utilise Syslinux %s mais l'application inclus seulement Syslinux %s.\n\n"
"Comme les nouvelles versions de Syslinux sont incompatibles, et il n'est pas possible toutes "
"les inclure, Rufus doit télécharger 2 fichiers supplémentaires ('ldlinux.sys' et 'ldlinux.bss'):\n"
"- Choisissez 'Oui' pour télécharger ces fichier depuis Internet\n"
"- Choisissez 'Non' pour annuler l'opération\n"
"Note: Ces fichier seront téléchargés dans le répertoire courrant et une fois qu'ils"
"existent à cet endroit, il seront réutilisés automatiquement."
t MSG_115 "Téléchargement nécessaire"
# Tootips
t MSG_150 "Ce choix est le plus sûr. Mais si vous possédez un ordinateur à base de UEFI et voulez installer "
@ -1804,7 +1819,7 @@ t MSG_230 "Copie des fichiers DOS..."
t MSG_231 "Copie des fichiers ISO..."
t MSG_232 "Ecriture boot Win7 EFI (peut prendre du temps)..."
t MSG_233 "Finalisation, veuillez patienter..."
t MSG_234 "Installation de Syslinux v%d..."
t MSG_234 "Installation de Syslinux %s..."
t MSG_235 "Défauts: PASSE %d/%d - %0.2f%% (%d/%d/%d erreurs)"
t MSG_236 "Défauts: Test avec motif aléatoire"
t MSG_237 "Défauts: Test avec motif 0x%02X"
@ -2173,7 +2188,7 @@ t MSG_231 "Kopiere ISO-Dateien..."
t MSG_232 "Win7 EFI Boot setup (kann etwas dauern)..."
t MSG_233 "Abschließen, bitte warten..."
# Takes the Syslinux version as parameter, eg. "Installing Syslinux v5..."
t MSG_234 "Installiere Syslinux v%d..."
t MSG_234 "Installiere Syslinux %s..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "Fehlerhafte Blöcke: Durchlauf %d/%d - %0.2f%% (%d/%d/%d Fehler)"
t MSG_236 "Fehlerhafte Blöcke: Prüfe mit zufälligen Mustern"
@ -2582,7 +2597,7 @@ t MSG_231 "Αντιγραφή αρχείων ISO..."
t MSG_232 "Ρυθμίσεις εκκίνησης Win7 EFI (η διαδικασία ίσως διαρκέσει αρκετά)..."
t MSG_233 "Οριστικοποίηση, παρακαλώ περιμένετε..."
# Takes the Syslinux version as paramete. eg. "Installing Syslinux v5..."
t MSG_234 "Εγκατάσταση Syslinux v%d..."
t MSG_234 "Εγκατάσταση Syslinux %s..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "Κατεστραμμένοι τομείς: πέρασμα %d/%d - %0.2f%% (%d/%d/%d σφάλματα)"
t MSG_236 "Κατεστραμμένοι τομείς: Έλεγχος με τυχαίο διάταξη"
@ -2940,7 +2955,7 @@ t MSG_231 "ISO fájlok másolása..."
t MSG_232 "Win7 EFI boot telepítő (ez eltarthat egy kis ideig)..."
t MSG_233 "Véglegesítés, kérlek, várj..."
# Takes the Syslinux version as parameter, eg. "Installing Syslinux v5..."
t MSG_234 "Syslinux v%d telepítése..."
t MSG_234 "Syslinux %s telepítése..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "Hibás blokkok: Próbálkozás %d/%d - %0.2f%% (%d/%d/%d hiba)"
t MSG_236 "Hibás blokkok: Véletlenszerű paraméterrel való tesztelés"
@ -3337,7 +3352,7 @@ t MSG_231 "Menyalin file ISO..."
t MSG_232 "Konfigurasi Win7 EFI boot (ini mungkin memakan waktu cukup lama)..."
t MSG_233 "Menyelesaikan, harap tunggu..."
# Takes the Syslinux version as parameter, eg. "Installing Syslinux v5..."
t MSG_234 "Memasang Syslinux v%d..."
t MSG_234 "Memasang Syslinux %s..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "Blok Buruk: LULUS %d/%d - %0.2f%% (%d/%d/%d kerusakan)"
t MSG_236 "Blok Buruk: Pengujian dengan pola acak"
@ -3699,7 +3714,7 @@ t MSG_230 "Copia file DOS..."
t MSG_231 "Copia file immagine ISO..."
t MSG_232 "Impostazione avvio EFI Windows 7 (potrebbe richiedere del tempo)..."
t MSG_233 "Finalizzazione..."
t MSG_234 "Installazione Syslinux v. %d..."
t MSG_234 "Installazione Syslinux %s..."
t MSG_235 "Blocchi danneggiati: pattern %d/%d - %0.2f%% (errori %d/%d/%d)"
t MSG_236 "Blocchi danneggiati: test con pattern casuali"
t MSG_237 "Blocchi danneggiati: testing con pattern 0x%02X"
@ -4070,7 +4085,7 @@ t MSG_231 "ISO 파일을 복사..."
t MSG_232 "WIN7 EFI 부팅 설정 (잠시만)..."
t MSG_233 "마무리 하는 중... 잠시만..."
# Takes the Syslinux version as parameter, eg. "Installing Syslinux v5..."
t MSG_234 "Syslinux v%d를 설치..."
t MSG_234 "Syslinux %s를 설치..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "배드 섹터: PASS %d/%d - %0.2f%% (%d/%d/%d errors)"
t MSG_236 "배드 섹터: 랜덤 패턴 테스트"
@ -4468,7 +4483,7 @@ t MSG_231 "Kopijuojami ISO failai..."
t MSG_232 "Win7 EFI įkelties sąranka (gali užtrukti)..."
t MSG_233 "Baigiama, prašome palaukti..."
# Takes the Syslinux version as parameter, eg. "Installing Syslinux v5..."
t MSG_234 "Įdiegiama Syslinux v%d..."
t MSG_234 "Įdiegiama Syslinux %s..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "Blogi blokai: BANDYMAS %d/%d - %0.2f%% (%d/%d/%d klaidos)"
t MSG_236 "Blogi blokai: tikrinama su atsitiktiniu šablonu"
@ -4870,7 +4885,7 @@ t MSG_231 "Menyalin fail ISO..."
t MSG_232 "Persediaan boot EFI Win7 (ini mungkin mengambil sedikit masa)..."
t MSG_233 "Memuktamadkan, sila tunggu..."
# Takes the Syslinux version as parameter, eg. "Installing Syslinux v5..."
t MSG_234 "Memasang Syslinux v%d..."
t MSG_234 "Memasang Syslinux %s..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "Blok rosak: PASS %d/%d - %0.2f%% (%d/%d/%d errors)"
t MSG_236 "Blok rosak: menguji dengan corak rawak"
@ -5270,7 +5285,7 @@ t MSG_231 "Kopiowanie plików ISO..."
t MSG_232 "Ustawianie bootowania Win7 EFI (to może chwilę potrwać)..."
t MSG_233 "Finalizacja, proszę czekać..."
# Takes the Syslinux version as paramete. eg. "Installing Syslinux v5..."
t MSG_234 "Instalowanie Syslinux v%d..."
t MSG_234 "Instalowanie Syslinux %s..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "Błędne Sektory: UKOŃCZONO %d/%d - %0.2f%% (%d/%d/%d błędów)"
t MSG_236 "Błędne Sektory: Testowanie z losowym wzorem"
@ -5679,7 +5694,7 @@ t MSG_231 "A copiar arquivos ISO..."
t MSG_232 "Configuração de arranque Win7 EFI (pode demorar um pouco)..."
t MSG_233 "A finalizar, por favor espere..."
# Takes the Syslinux version as parameter, eg. "Installing Syslinux v5..."
t MSG_234 "A instalar Syslinux v%d..."
t MSG_234 "A instalar Syslinux %s..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "Blocos com erro: PASSO %d/%d - %0.2f%% (%d/%d/%d erros)"
t MSG_236 "Blocos com erro: A verificar com teste padrão"
@ -6034,7 +6049,7 @@ t MSG_230 "Copierea fişierului DOS..."
t MSG_231 "Copierea fişierului imagine ISO..."
t MSG_232 "Setarea UEFI de boot Windows 7 (poate dura ceva timp)..."
t MSG_233 "Finalizarea..."
t MSG_234 "Instalarea Syslinux v. %d..."
t MSG_234 "Instalarea Syslinux %s..."
t MSG_235 "Blocuri defecte: model %d/%d - %0.2f%% (erori %d/%d/%d)"
t MSG_236 "Blocuri defecte: testarea cu modele aleatoare"
t MSG_237 "Blocuri defecte: testarea cu model 0x%02X"
@ -6422,7 +6437,7 @@ t MSG_231 "Копирование ISO-файлов..."
t MSG_232 "Настройка Win7 EFI boot (Это может занять время)..."
t MSG_233 "Завершение, пожалуйста, ждите..."
# Takes the Syslinux version as paramete. eg. "Installing Syslinux v5..."
t MSG_234 "Установка Syslinux v%d..."
t MSG_234 "Установка Syslinux %s..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "Плохие блоки: Проход %d/%d - %0.2f%% (%d/%d/%d ошибок)"
t MSG_236 "Плохие блоки: Тестирование случайным образом"
@ -6808,7 +6823,7 @@ t MSG_231 "Kopiram ISO datoteke…"
t MSG_232 "Pripravljam pogon za zagon Windows 7 na EFI (to lahko traja)…"
t MSG_233 "Zaključujem; prosim, počakajte…"
# Takes the Syslinux version as parameter, eg. "Installing Syslinux v5…"
t MSG_234 "Nameščam Syslinux v%d…"
t MSG_234 "Nameščam Syslinux %s…"
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "Slabi bloki: prehod %d/%d - %0.2f%% (%d/%d/%d napak)"
t MSG_236 "Slabi bloki: testiram z naključnim vzorcem"
@ -7210,7 +7225,7 @@ t MSG_231 "Copiando archivos ISO..."
t MSG_232 "Configuración de arranque Win7 EFI (puede tardar un rato)..."
t MSG_233 "Finalización, por favor espere..."
# Takes the Syslinux version as parameter, eg. "Installing Syslinux v5..."
t MSG_234 "Instalando Syslinux v%d..."
t MSG_234 "Instalando Syslinux %s..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "Bloques dañados: PASO %d/%d - %0.2f%% (%d/%d/%d errores)"
t MSG_236 "Bloques dañados: Probando con patrones aleatorios"
@ -7605,7 +7620,7 @@ t MSG_231 "ISO Dosyaları Kopyalanıyor..."
t MSG_232 "Win7 EFI Açılış Kurulumu (Biraz zaman alabilir)..."
t MSG_233 "Bitiriliyor, Lütfen Bekleyin..."
# Takes the Syslinux version as parameter, eg. "Installing Syslinux v5..."
t MSG_234 "Syslinux v%d Yükleniyor..."
t MSG_234 "Syslinux %s Yükleniyor..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "Hatalı Bloklar: Geçiş %d/%d - %0.2f%% (%d/%d/%d hata)"
t MSG_236 "Hatalı Bloklar: Rasgele kalıpla deneniyor"

105
src/iso.c
View File

@ -55,14 +55,16 @@ void cdio_destroy (CdIo_t* p_cdio) {}
RUFUS_ISO_REPORT iso_report;
int64_t iso_blocking_status = -1;
BOOL enable_joliet = TRUE, enable_rockridge = TRUE;
BOOL enable_joliet = TRUE, enable_rockridge = TRUE, has_ldlinux_c32;
#define ISO_BLOCKING(x) do {x; iso_blocking_status++; } while(0)
static const char* psz_extract_dir;
static const char* bootmgr_efi_name = "bootmgr.efi";
static const char* ldlinux_name = "ldlinux.sys";
static const char* syslinux_v5_file = "ldlinux.c32";
static const char* ldlinux_c32 = "ldlinux.c32";
static const char* efi_dirname = "/efi/boot";
static const char* isolinux_name[] = { "isolinux.cfg", "syslinux.cfg", "extlinux.conf"};
static const char* syslinux_cfg[] = { "isolinux.cfg", "syslinux.cfg", "extlinux.conf"};
static const char dot_isolinux_bin[] = ".\\isolinux.bin";
static const char* isolinux_bin = &dot_isolinux_bin[2];
static const char* pe_dirname[] = { "/i386", "/minint" };
static const char* pe_file[] = { "ntdetect.com", "setupldr.bin", "txtsetup.sif" };
static const char* reactos_name = "setupldr.sys"; // TODO: freeldr.sys doesn't seem to work
@ -72,7 +74,7 @@ static const int64_t old_c32_threshold[NB_OLD_C32] = OLD_C32_THRESHOLD;
static uint8_t i_joliet_level = 0;
static uint64_t total_blocks, nb_blocks;
static BOOL scan_only = FALSE;
static StrArray config_path;
static StrArray config_path, isolinux_path;
// TODO: Timestamp & permissions preservation
@ -117,6 +119,7 @@ static void log_handler (cdio_log_level_t level, const char *message)
{
switch(level) {
case CDIO_LOG_DEBUG:
// TODO: use a registry key to enable libcdio debug?
return;
default:
uprintf("libcdio: %s\n", message);
@ -134,14 +137,14 @@ static BOOL check_iso_props(const char* psz_dirname, BOOL* is_syslinux_cfg, BOOL
// Check for an isolinux/syslinux config file anywhere
*is_syslinux_cfg = FALSE;
for (i=0; i<ARRAYSIZE(isolinux_name); i++) {
if (safe_stricmp(psz_basename, isolinux_name[i]) == 0)
for (i=0; i<ARRAYSIZE(syslinux_cfg); i++) {
if (safe_stricmp(psz_basename, syslinux_cfg[i]) == 0)
*is_syslinux_cfg = TRUE;
}
// Check for a syslinux v5.0 file anywhere
if (safe_stricmp(psz_basename, syslinux_v5_file) == 0) {
iso_report.has_syslinux_v5 = TRUE;
// Check for a syslinux v5.0+ file anywhere
if (safe_stricmp(psz_basename, ldlinux_c32) == 0) {
has_ldlinux_c32 = TRUE;
}
// Check for an old incompatible c32 file anywhere
@ -178,10 +181,14 @@ static BOOL check_iso_props(const char* psz_dirname, BOOL* is_syslinux_cfg, BOOL
iso_report.winpe |= (1<<i)<<(ARRAYSIZE(pe_dirname)*j);
if (*is_syslinux_cfg) {
iso_report.has_isolinux = TRUE;
// Maintain a list of all the isolinux/syslinux configs identified so far
StrArrayAdd(&config_path, psz_fullpath);
}
if (safe_stricmp(psz_basename, isolinux_bin) == 0) {
// Maintain a list of all the isolinux.bin files found
StrArrayAdd(&isolinux_path, psz_fullpath);
}
for (i=0; i<NB_OLD_C32; i++) {
if (is_old_c32[i])
iso_report.has_old_c32[i] = TRUE;
@ -465,18 +472,20 @@ out:
BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan)
{
size_t i;
size_t i, k, size;
int j;
uint16_t sl_version;
FILE* fd;
BOOL r = FALSE;
iso9660_t* p_iso = NULL;
udf_t* p_udf = NULL;
udf_dirent_t* p_udf_root;
LONG progress_style;
char* tmp;
char path[64];
char *tmp, *buf;
char path[MAX_PATH];
const char* basedir[] = { "i386", "minint" };
const char* tmp_sif = ".\\txtsetup.sif~";
const char ISOLINUX[] = { 'I', 'S', 'O', 'L', 'I', 'N', 'U', 'X', ' ' };
iso_extension_mask_t iso_extension_mask = ISO_EXTENSION_ALL;
if ((src_iso == NULL) || (dest_dir == NULL))
@ -489,8 +498,10 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan)
if (scan_only) {
total_blocks = 0;
memset(&iso_report, 0, sizeof(iso_report));
has_ldlinux_c32 = FALSE;
// String array of all isolinux/syslinux locations
StrArrayCreate(&config_path, 8);
StrArrayCreate(&isolinux_path, 8);
// Change the Window title and static text
SetWindowTextU(hISOProgressDlg, lmprintf(MSG_202));
SetWindowTextU(hISOFileName, lmprintf(MSG_202));
@ -566,14 +577,65 @@ out:
// We use the fact that UDF_BLOCKSIZE and ISO_BLOCKSIZE are the same here
iso_report.projected_size = total_blocks * ISO_BLOCKSIZE;
// We will link the existing isolinux.cfg from a syslinux.cfg we create
// If multiple config file exist, choose the one with the shortest path
if (iso_report.has_isolinux) {
// If multiple config files exist, choose the one with the shortest path
// (so that a '/syslinux.cfg' is preferred over a '/isolinux/isolinux.cfg')
if (!IsStrArrayEmpty(config_path)) {
safe_strcpy(iso_report.cfg_path, sizeof(iso_report.cfg_path), config_path.Table[0]);
for (i=1; i<config_path.Index; i++) {
if (safe_strlen(iso_report.cfg_path) > safe_strlen(config_path.Table[i]))
safe_strcpy(iso_report.cfg_path, sizeof(iso_report.cfg_path), config_path.Table[i]);
}
uprintf("Will use %s for Syslinux\n", iso_report.cfg_path);
// Extract all of the isolinux.bin files we found to identify their versions
for (i=0; i<isolinux_path.Index; i++) {
size = (size_t)ExtractISOFile(src_iso, isolinux_path.Table[i], dot_isolinux_bin);
if (size == 0) {
uprintf("Could not access %s\n", isolinux_path.Table[i]);
} else {
buf = (char*)calloc(size, 1);
if (buf == NULL) break;
fd = fopen(dot_isolinux_bin, "rb");
if (fd == NULL) {
free(buf);
continue;
}
fread(buf, 1, size, fd);
fclose(fd);
for (k=0; k<size-16; k++) {
if (memcmp(&buf[k], ISOLINUX, sizeof(ISOLINUX)) == 0) {
k += sizeof(ISOLINUX);
sl_version = (((uint8_t)strtoul(&buf[k], &tmp, 10))<<8) + (uint8_t)strtoul(&tmp[1], NULL, 10);
if (iso_report.sl_version == 0) {
iso_report.sl_version = sl_version;
j = (int)i;
} else if (iso_report.sl_version != sl_version) {
uprintf("Found conflicting %s versions:\n '%s' (v%d.%02d) vs '%s' (v%d.%02d)\n", isolinux_bin,
isolinux_path.Table[j], SL_MAJOR(iso_report.sl_version), SL_MINOR(iso_report.sl_version),
isolinux_path.Table[i], SL_MAJOR(sl_version), SL_MINOR(sl_version));
}
break;
}
}
free(buf);
_unlink(dot_isolinux_bin);
}
}
if (iso_report.sl_version != 0) {
static_sprintf(iso_report.sl_version_str, "v%d.%02d",
SL_MAJOR(iso_report.sl_version), SL_MINOR(iso_report.sl_version));
uprintf("Detected Isolinux version: %s (from '%s')",
iso_report.sl_version_str, isolinux_path.Table[j]);
if ( (has_ldlinux_c32 && (SL_MAJOR(iso_report.sl_version) < 5))
|| (!has_ldlinux_c32 && (SL_MAJOR(iso_report.sl_version) >= 5)) )
uprintf("Warning: Conflict between Isolinux version and the presence of ldlinux.c32...\n");
} else {
// Couldn't find a version from isolinux.bin. Force set to the versions we embed
iso_report.sl_version = embedded_sl_version[has_ldlinux_c32?1:0];
static_sprintf(iso_report.sl_version_str, "v%d.%02d",
SL_MAJOR(iso_report.sl_version), SL_MINOR(iso_report.sl_version));
uprintf("Warning: Could not detect Isolinux version - Forcing to %s (embedded)",
iso_report.sl_version_str);
}
}
if (IS_WINPE(iso_report.winpe)) {
// In case we have a WinPE 1.x based iso, we extract and parse txtsetup.sif
@ -593,7 +655,8 @@ out:
safe_free(tmp);
}
StrArrayDestroy(&config_path);
} else if (iso_report.has_isolinux) {
StrArrayDestroy(&isolinux_path);
} else if (!IsStrArrayEmpty(config_path)) {
safe_sprintf(path, sizeof(path), "%s\\syslinux.cfg", dest_dir);
// Create a /syslinux.cfg (if none exists) that points to the existing isolinux cfg
fd = fopen(path, "r");
@ -626,14 +689,14 @@ out:
return (r == 0);
}
BOOL ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file)
int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file)
{
size_t i;
ssize_t read_size;
int64_t file_length;
char buf[UDF_BLOCKSIZE];
DWORD buf_size, wr_size;
BOOL s, r = FALSE;
BOOL s, r = 0;
iso9660_t* p_iso = NULL;
udf_t* p_udf = NULL;
udf_dirent_t *p_udf_root = NULL, *p_udf_file = NULL;
@ -678,8 +741,8 @@ BOOL ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file
goto out;
}
file_length -= read_size;
r += read_size;
}
r = TRUE;
goto out;
try_iso:
@ -710,8 +773,8 @@ try_iso:
goto out;
}
file_length -= ISO_BLOCKSIZE;
r += ISO_BLOCKSIZE;
}
r = TRUE;
out:
safe_closehandle(file_handle);
@ -726,5 +789,5 @@ out:
iso9660_close(p_iso);
if (p_udf != NULL)
udf_close(p_udf);
return (r == 0);
return r;
}

View File

@ -1,7 +1,7 @@
/*
* Rufus: The Reliable USB Formatting Utility
* Networking functionality (web file download, check for update, etc.)
* Copyright © 2012-2013 Pete Batard <pete@akeo.ie>
* Copyright © 2012-2014 Pete Batard <pete@akeo.ie>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -239,7 +239,7 @@ const char* WinInetErrorString(void)
* to the dialog in question, with WPARAM being set to nonzero for EXIT on success
* and also attempt to indicate progress using an IDC_PROGRESS control
*/
BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog)
DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog)
{
HWND hProgressBar = NULL;
BOOL r = FALSE;
@ -251,6 +251,7 @@ BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog)
HINTERNET hSession = NULL, hConnection = NULL, hRequest = NULL;
URL_COMPONENTSA UrlParts = {sizeof(URL_COMPONENTSA), NULL, 1, (INTERNET_SCHEME)0,
hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1};
size_t last_slash;
int i;
if (hProgressDialog != NULL) {
@ -264,8 +265,15 @@ BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog)
SendMessage(hProgressDialog, UM_ISO_INIT, 0, 0);
}
PrintStatus(0, FALSE, MSG_240, file);
uprintf("Downloading %s from %s\n", file, url);
for (last_slash = safe_strlen(file); last_slash != 0; last_slash--) {
if ((file[last_slash] == '/') || (file[last_slash] == '\\')) {
last_slash++;
break;
}
}
PrintStatus(0, FALSE, MSG_240, &file[last_slash]);
uprintf("Downloading '%s' from %s\n", &file[last_slash], url);
if (!InternetCrackUrlA(url, (DWORD)safe_strlen(url), 0, &UrlParts)) {
uprintf("Unable to decode URL: %s\n", WinInetErrorString());
@ -286,7 +294,7 @@ BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog)
_snprintf(agent, ARRAYSIZE(agent), APPLICATION_NAME "/%d.%d.%d.%d", rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]);
hSession = InternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hSession == NULL) {
uprintf("Could not open internet session: %s\n", WinInetErrorString());
uprintf("Could not open Internet session: %s\n", WinInetErrorString());
goto out;
}
@ -300,7 +308,7 @@ BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog)
INTERNET_FLAG_HYPERLINK|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS|INTERNET_FLAG_NO_COOKIES|
INTERNET_FLAG_NO_UI|INTERNET_FLAG_NO_CACHE_WRITE, (DWORD_PTR)NULL);
if (hRequest == NULL) {
uprintf("Could not open url %s: %s\n", url, WinInetErrorString());
uprintf("Could not open URL %s: %s\n", url, WinInetErrorString());
goto out;
}
@ -327,7 +335,7 @@ BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog)
fd = fopenU(file, "wb");
if (fd == NULL) {
uprintf("Unable to create file '%s': %s\n", file, WinInetErrorString());
uprintf("Unable to create file '%s': %s\n", &file[last_slash], WinInetErrorString());
goto out;
}
@ -343,7 +351,7 @@ BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog)
SendMessage(hProgressBar, PBM_SETPOS, (WPARAM)(MAX_PROGRESS*((1.0f*dwSize)/(1.0f*dwTotalSize))), 0);
PrintStatus(0, FALSE, MSG_241, (100.0f*dwSize)/(1.0f*dwTotalSize));
if (fwrite(buf, 1, dwDownloaded, fd) != dwDownloaded) {
uprintf("Error writing file '%s': %s\n", file, WinInetErrorString());
uprintf("Error writing file '%s': %s\n", &file[last_slash], WinInetErrorString());
goto out;
}
}
@ -354,7 +362,7 @@ BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog)
goto out;
} else {
r = TRUE;
uprintf("Successfully downloaded '%s'\n", file);
uprintf("Successfully downloaded '%s'\n", &file[last_slash]);
}
out:
@ -372,7 +380,7 @@ out:
if (hConnection) InternetCloseHandle(hConnection);
if (hSession) InternetCloseHandle(hSession);
return r;
return r?dwSize:0;
}
/* Threaded download */
@ -380,7 +388,7 @@ static const char *_url, *_file;
static HWND _hProgressDialog;
static DWORD WINAPI _DownloadFileThread(LPVOID param)
{
ExitThread(DownloadFile(_url, _file, _hProgressDialog));
ExitThread(DownloadFile(_url, _file, _hProgressDialog) != 0);
}
HANDLE DownloadFileThreaded(const char* url, const char* file, HWND hProgressDialog)

View File

@ -141,7 +141,8 @@ BOOL use_own_c32[NB_OLD_C32] = {FALSE, FALSE}, detect_fakes = TRUE, mbr_selected
BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE;
BOOL enable_HDDs = FALSE, advanced_mode = TRUE, force_update = FALSE;
int dialog_showing = 0;
uint16_t rufus_version[4];
uint16_t rufus_version[4], embedded_sl_version[2];
char embedded_sl_version_str[2][12] = { "v?.??", "v?.??" };
RUFUS_UPDATE update = { {0,0,0,0}, {0,0}, NULL, NULL};
extern char szStatusMessage[256];
@ -445,7 +446,7 @@ static void SetFSFromISO(void)
}
// Syslinux and EFI have precedence over bootmgr (unless the user selected BIOS as target type)
if ((iso_report.has_isolinux) || (IS_REACTOS(iso_report)) || ( (IS_EFI(iso_report)) && (bt == BT_UEFI))) {
if ((HAS_SYSLINUX(iso_report)) || (IS_REACTOS(iso_report)) || ( (IS_EFI(iso_report)) && (bt == BT_UEFI))) {
if (fs_mask & (1<<FS_FAT32)) {
selected_fs = FS_FAT32;
} else if (fs_mask & (1<<FS_FAT16)) {
@ -531,7 +532,7 @@ static void SetTargetSystem(void)
if (SelectedDrive.PartitionType == PARTITION_STYLE_GPT) {
ts = 2; // GPT/UEFI
} else if (SelectedDrive.has_protective_mbr || SelectedDrive.has_mbr_uefi_marker || (IS_EFI(iso_report) &&
(!iso_report.has_isolinux) && (!iso_report.has_bootmgr) && (!IS_WINPE(iso_report.winpe))) ) {
(!HAS_SYSLINUX(iso_report)) && (!iso_report.has_bootmgr) && (!IS_WINPE(iso_report.winpe))) ) {
ts = 1; // MBR/UEFI
} else {
ts = 0; // MBR/BIOS|UEFI
@ -1171,6 +1172,7 @@ DWORD WINAPI ISOScanThread(LPVOID param)
FILE* fd;
const char* old_c32_name[NB_OLD_C32] = OLD_C32_NAMES;
const char* new_c32_url[NB_OLD_C32] = NEW_C32_URL;
char isolinux_str[16] = "No";
if (iso_path == NULL)
goto out;
@ -1185,41 +1187,45 @@ DWORD WINAPI ISOScanThread(LPVOID param)
safe_free(iso_path);
goto out;
}
if (HAS_SYSLINUX(iso_report)) {
safe_sprintf(isolinux_str, sizeof(isolinux_str), "Yes (%s)", iso_report.sl_version_str);
}
uprintf("ISO label: '%s'\r\n Size: %lld bytes\r\n Has a >64 chars filename: %s\r\n Has a >4GB file: %s\r\n"
" ReactOS: %s\r\n Uses EFI: %s%s\r\n Uses Bootmgr: %s\r\n Uses WinPE: %s%s\r\n Uses isolinux: %s %s\r\n",
" ReactOS: %s\r\n Uses EFI: %s%s\r\n Uses Bootmgr: %s\r\n Uses WinPE: %s%s\r\n Uses isolinux: %s\r\n",
iso_report.label, iso_report.projected_size, iso_report.has_long_filename?"Yes":"No", iso_report.has_4GB_file?"Yes":"No",
IS_REACTOS(iso_report)?"Yes":"No", (iso_report.has_efi || iso_report.has_win7_efi)?"Yes":"No",
(iso_report.has_win7_efi && (!iso_report.has_efi))?" (win7_x64)":"", iso_report.has_bootmgr?"Yes":"No",
IS_WINPE(iso_report.winpe)?"Yes":"No", (iso_report.uses_minint)?" (with /minint)":"", iso_report.has_isolinux?"Yes":"No",
iso_report.has_syslinux_v5?"(v5.0 or later)":iso_report.has_isolinux?"(v4.x or earlier)":"");
if (iso_report.has_isolinux && !iso_report.has_syslinux_v5) {
IS_WINPE(iso_report.winpe)?"Yes":"No", (iso_report.uses_minint)?" (with /minint)":"", isolinux_str);
if (HAS_SYSLINUX(iso_report) && (SL_MAJOR(iso_report.sl_version) < 5)) {
for (i=0; i<NB_OLD_C32; i++) {
uprintf(" With an old %s: %s\n", old_c32_name[i], iso_report.has_old_c32[i]?"Yes":"No");
}
}
if ( (!iso_report.has_bootmgr) && (!iso_report.has_isolinux) && (!IS_WINPE(iso_report.winpe))
if ( (!iso_report.has_bootmgr) && (!HAS_SYSLINUX(iso_report)) && (!IS_WINPE(iso_report.winpe))
&& (!iso_report.has_efi) && (!IS_REACTOS(iso_report)) ) {
MessageBoxU(hMainDialog, lmprintf(MSG_082), lmprintf(MSG_081), MB_OK|MB_ICONINFORMATION);
safe_free(iso_path);
SetMBRProps();
} else if (!iso_report.has_syslinux_v5) { // This check is for Syslinux v4.x or earlier
_chdirU(app_dir);
for (i=0; i<NB_OLD_C32; i++) {
if (iso_report.has_old_c32[i]) {
fd = fopen(old_c32_name[i], "rb");
if (fd != NULL) {
// If a file already exists in the current directory, use that one
uprintf("Will replace obsolete '%s' from ISO with the one found in current directory\n", old_c32_name[i]);
fclose(fd);
use_own_c32[i] = TRUE;
} else {
PrintStatus(0, FALSE, MSG_204, old_c32_name[i]);
if (MessageBoxU(hMainDialog, lmprintf(MSG_084, old_c32_name[i], old_c32_name[i]),
lmprintf(MSG_083, old_c32_name[i]), MB_YESNO|MB_ICONWARNING) == IDYES) {
SetWindowTextU(hISOProgressDlg, lmprintf(MSG_085, old_c32_name[i]));
SetWindowTextU(hISOFileName, new_c32_url[i]);
if (DownloadFile(new_c32_url[i], old_c32_name[i], hISOProgressDlg))
use_own_c32[i] = TRUE;
} else if (HAS_SYSLINUX(iso_report)) {
if (SL_MAJOR(iso_report.sl_version) < 5) {
_chdirU(app_dir);
for (i=0; i<NB_OLD_C32; i++) {
if (iso_report.has_old_c32[i]) {
fd = fopen(old_c32_name[i], "rb");
if (fd != NULL) {
// If a file already exists in the current directory, use that one
uprintf("Will replace obsolete '%s' from ISO with the one found in current directory\n", old_c32_name[i]);
fclose(fd);
use_own_c32[i] = TRUE;
} else {
PrintStatus(0, FALSE, MSG_204, old_c32_name[i]);
if (MessageBoxU(hMainDialog, lmprintf(MSG_084, old_c32_name[i], old_c32_name[i]),
lmprintf(MSG_083, old_c32_name[i]), MB_YESNO|MB_ICONWARNING) == IDYES) {
SetWindowTextU(hISOProgressDlg, lmprintf(MSG_085, old_c32_name[i]));
SetWindowTextU(hISOFileName, new_c32_url[i]);
if (DownloadFile(new_c32_url[i], old_c32_name[i], hISOProgressDlg))
use_own_c32[i] = TRUE;
}
}
}
}
@ -1319,10 +1325,14 @@ void ToggleAdvanced(void)
static BOOL BootCheck(void)
{
int fs, bt, dt, r;
int i, fs, bt, dt, r;
FILE* fd;
const char* ldlinux_name = "ldlinux.c32";
const char* ldlinux = "ldlinux";
const char* syslinux = "syslinux";
const char* ldlinux_ext[3] = { "sys", "bss", "c32" };
char tmp[MAX_PATH];
syslinux_ldlinux_len[0] = 0; syslinux_ldlinux_len[1] = 0;
dt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType));
if (dt == DT_ISO) {
if (iso_path == NULL) {
@ -1350,7 +1360,7 @@ static BOOL BootCheck(void)
return FALSE;
}
} else if ((fs == FS_NTFS) && (!iso_report.has_bootmgr) && (!IS_WINPE(iso_report.winpe))) {
if (iso_report.has_isolinux) {
if (HAS_SYSLINUX(iso_report)) {
// Only FAT/FAT32 is supported for this type of ISO
MessageBoxU(hMainDialog, lmprintf(MSG_096), lmprintf(MSG_092), MB_OK|MB_ICONERROR);
} else {
@ -1358,7 +1368,7 @@ static BOOL BootCheck(void)
MessageBoxU(hMainDialog, lmprintf(MSG_097), lmprintf(MSG_090), MB_OK|MB_ICONERROR);
}
return FALSE;
} else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && (!iso_report.has_isolinux) && (!IS_REACTOS(iso_report))) {
} else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && (!HAS_SYSLINUX(iso_report)) && (!IS_REACTOS(iso_report))) {
// FAT/FAT32 can only be used for isolinux based ISO images or when the Target Type is UEFI
MessageBoxU(hMainDialog, lmprintf(MSG_098), lmprintf(MSG_090), MB_OK|MB_ICONERROR);
return FALSE;
@ -1368,23 +1378,68 @@ static BOOL BootCheck(void)
MessageBoxU(hMainDialog, lmprintf(MSG_100), lmprintf(MSG_099), MB_OK|MB_ICONERROR);
return FALSE;
}
if ((SL_MAJOR(iso_report.sl_version) >= 5) && (iso_report.sl_version != embedded_sl_version[1])) {
// Unlike what was the case for v4 and earlier, Syslinux v5+ versions are INCOMPATIBLE with one another!
_chdirU(app_dir);
_mkdir(FILES_DIR);
_chdir(FILES_DIR);
for (i=0; i<2; i++) {
// Check if we already have the relevant ldlinux_v#.##.sys & ldlinux_v#.##.bss files
static_sprintf(tmp, "%s-%s/%s.%s", syslinux, &iso_report.sl_version_str[1], ldlinux, ldlinux_ext[i]);
fd = fopen(tmp, "rb");
if (fd != NULL) {
fseek(fd, 0, SEEK_END);
syslinux_ldlinux_len[i] = (DWORD)ftell(fd);
fclose(fd);
}
}
if ((syslinux_ldlinux_len[0] != 0) && (syslinux_ldlinux_len[1] != 0)) {
uprintf("Will reuse '%s.%s' and '%s.%s' from './%s/%s-%s/' for Syslinux installation\n",
ldlinux, ldlinux_ext[0], ldlinux, ldlinux_ext[1], FILES_DIR, syslinux, &iso_report.sl_version_str[1]);
} else {
r = MessageBoxU(hMainDialog, lmprintf(MSG_114, iso_report.sl_version_str, embedded_sl_version_str[1]),
lmprintf(MSG_115), MB_YESNO|MB_ICONWARNING);
if (r != IDYES)
return FALSE;
for (i=0; i<2; i++) {
static_sprintf(tmp, "%s-%s", syslinux, &iso_report.sl_version_str[1]);
_mkdir(tmp);
static_sprintf(tmp, "%s.%s %s", ldlinux, ldlinux_ext[i], iso_report.sl_version_str);
SetWindowTextU(hISOProgressDlg, lmprintf(MSG_085, tmp));
static_sprintf(tmp, "%s/%s-%s/%s.%s", FILES_URL, syslinux, &iso_report.sl_version_str[1], ldlinux, ldlinux_ext[i]);
SetWindowTextU(hISOFileName, tmp);
syslinux_ldlinux_len[i] = DownloadFile(tmp, &tmp[sizeof(FILES_URL)], hISOProgressDlg);
if (syslinux_ldlinux_len[i] == 0) {
uprintf("Couldn't download the files - cancelling\n");
return FALSE;
}
}
}
}
} else if (dt == DT_SYSLINUX_V5) {
_chdirU(app_dir);
fd = fopen(ldlinux_name, "rb");
_mkdir(FILES_DIR);
_chdir(FILES_DIR);
static_sprintf(tmp, "%s-%s/%s.%s", syslinux, &embedded_sl_version_str[1][1], ldlinux, ldlinux_ext[2]);
fd = fopenU(tmp, "rb");
if (fd != NULL) {
uprintf("Will reuse '%s' for Syslinux v5\n", ldlinux_name);
uprintf("Will reuse './%s/%s' for Syslinux installation\n", FILES_DIR, tmp);
fclose(fd);
} else {
PrintStatus(0, FALSE, MSG_206, ldlinux_name);
// Syslinux v5.0 or later requires a '%s' file to be installed
r = MessageBoxU(hMainDialog, lmprintf(MSG_104, ldlinux_name, ldlinux_name),
lmprintf(MSG_103, ldlinux_name), MB_YESNOCANCEL|MB_ICONWARNING);
static_sprintf(tmp, "%s.%s", ldlinux, ldlinux_ext[2]);
PrintStatus(0, FALSE, MSG_206, tmp);
// MSG_104: "Syslinux v5.0 or later requires a '%s' file to be installed"
r = MessageBoxU(hMainDialog, lmprintf(MSG_104, tmp, tmp),
lmprintf(MSG_103, tmp), MB_YESNOCANCEL|MB_ICONWARNING);
if (r == IDCANCEL)
return FALSE;
if (r == IDYES) {
SetWindowTextU(hISOProgressDlg, lmprintf(MSG_085, ldlinux_name));
SetWindowTextU(hISOFileName, LDLINUX_C32_URL);
DownloadFile(LDLINUX_C32_URL, ldlinux_name, hISOProgressDlg);
static_sprintf(tmp, "%s-%s", syslinux, &embedded_sl_version_str[1][1]);
_mkdir(tmp);
static_sprintf(tmp, "%s/%s-%s/%s.%s", FILES_URL, syslinux, &embedded_sl_version_str[1][1], ldlinux, ldlinux_ext[2]);
SetWindowTextU(hISOProgressDlg, lmprintf(MSG_085, tmp));
SetWindowTextU(hISOFileName, tmp);
DownloadFile(tmp, &tmp[sizeof(FILES_URL)], hISOProgressDlg);
}
}
} else if (dt == DT_WINME) {
@ -1401,9 +1456,11 @@ static BOOL BootCheck(void)
void InitDialog(HWND hDlg)
{
HINSTANCE hDllInst;
DWORD len;
HDC hDC;
int i, i16, s16;
char tmp[128], *token;
char tmp[128], *token, *buf;
static char* resource[2] = { MAKEINTRESOURCEA(IDR_SL_LDLINUX_V4_SYS), MAKEINTRESOURCEA(IDR_SL_LDLINUX_V5_SYS) };
#ifdef RUFUS_TEST
ShowWindow(GetDlgItem(hDlg, IDC_TEST), SW_SHOW);
@ -1449,6 +1506,16 @@ void InitDialog(HWND hDlg)
rufus_version[i] = (uint16_t)atoi(token);
uprintf(APPLICATION_NAME " version %d.%d.%d.%d\n", rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]);
uprintf("Windows version: %s\n", WindowsVersionStr);
for (i=0; i<ARRAYSIZE(resource); i++) {
buf = (char*)GetResource(hMainInstance, resource[i], _RT_RCDATA, "ldlinux_sys", &len, FALSE);
if ((buf == NULL) || (len < 16)) {
uprintf("Warning: could not read embedded Syslinux v%d version", i+4);
} else {
embedded_sl_version[i] = (((uint8_t)strtoul(&buf[0xb], &token, 10))<<8) + (uint8_t)strtoul(&token[1], NULL, 10);
static_sprintf(embedded_sl_version_str[i], "v%d.%02d", SL_MAJOR(embedded_sl_version[i]), SL_MINOR(embedded_sl_version[i]));
}
}
uprintf("Syslinux version: %s, %s", embedded_sl_version_str[0], embedded_sl_version_str[1]);
uprintf("LCID: 0x%04X\n", GetUserDefaultUILanguage());
SetClusterSizeLabels();

View File

@ -59,7 +59,10 @@
#define WHITE RGB(255,255,255)
#define SEPARATOR_GREY RGB(223,223,223)
#define RUFUS_URL "http://rufus.akeo.ie"
#define DOWNLOAD_URL RUFUS_URL "/downloads"
#define FILES_URL RUFUS_URL "/files"
#define SEVENZIP_URL "http://sourceforge.net/projects/sevenzip/files/7-Zip/"
#define FILES_DIR "rufus_files"
#define IGNORE_RETVAL(expr) do { (void)(expr); } while(0)
#ifndef ARRAYSIZE
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
@ -80,6 +83,7 @@
#define safe_closehandle(h) do {if ((h != INVALID_HANDLE_VALUE) && (h != NULL)) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
#define safe_unlockclose(h) do {if ((h != INVALID_HANDLE_VALUE) && (h != NULL)) {UnlockDrive(h); CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
#define safe_sprintf(dst, count, ...) do {_snprintf(dst, count, __VA_ARGS__); (dst)[(count)-1] = 0; } while(0)
#define static_sprintf(dst, ...) safe_sprintf(dst, sizeof(dst), __VA_ARGS__)
#define safe_strlen(str) ((((char*)str)==NULL)?0:strlen(str))
#define safe_strdup _strdup
#if defined(_MSC_VER)
@ -203,14 +207,14 @@ typedef struct {
/* Special handling for old .c32 files we need to replace */
#define NB_OLD_C32 2
#define OLD_C32_NAMES {"menu.c32", "vesamenu.c32"}
#define OLD_C32_THRESHOLD {53500, 148000}
#define NEW_C32_URL {RUFUS_URL "/downloads/menu.c32", RUFUS_URL "/downloads/vesamenu.c32"}
#define LDLINUX_C32_URL RUFUS_URL "/downloads/ldlinux.c32"
#define OLD_C32_NAMES { "menu.c32", "vesamenu.c32" }
#define OLD_C32_THRESHOLD { 53500, 148000 }
#define NEW_C32_URL { DOWNLOAD_URL "/menu.c32", DOWNLOAD_URL "/vesamenu.c32" }
/* ISO details that the application may want */
#define WINPE_MININT 0x2A
#define WINPE_I386 0x15
#define HAS_SYSLINUX(r) (r.sl_version != 0)
#define IS_WINPE(r) (((r&WINPE_MININT) == WINPE_MININT)||((r&WINPE_I386) == WINPE_I386))
#define IS_EFI(r) ((r.has_efi) || (r.has_win7_efi))
#define IS_REACTOS(r) (r.reactos_path[0] != 0)
@ -228,14 +232,18 @@ typedef struct {
BOOL has_bootmgr;
BOOL has_efi;
BOOL has_win7_efi;
BOOL has_isolinux;
BOOL has_autorun;
BOOL has_old_c32[NB_OLD_C32];
BOOL has_old_vesamenu;
BOOL has_syslinux_v5;
BOOL uses_minint;
uint16_t sl_version; // Syslinux/Isolinux version
char sl_version_str[12];
} RUFUS_ISO_REPORT;
/* Isolate the Syslinux version numbers */
#define SL_MAJOR(x) ((uint8_t)((x)>>8))
#define SL_MINOR(x) ((uint8_t)(x))
typedef struct {
uint16_t version[4];
uint32_t platform_min[2]; // minimum platform version required
@ -277,14 +285,16 @@ extern float fScale;
extern char szFolderPath[MAX_PATH], app_dir[MAX_PATH];
extern char* iso_path;
extern DWORD FormatStatus;
extern DWORD syslinux_ldlinux_len[2];
extern RUFUS_DRIVE_INFO SelectedDrive;
extern const int nb_steps[FS_MAX];
extern BOOL use_own_c32[NB_OLD_C32], detect_fakes, iso_op_in_progress, format_op_in_progress;
extern RUFUS_ISO_REPORT iso_report;
extern int64_t iso_blocking_status;
extern uint16_t rufus_version[4];
extern uint16_t rufus_version[4], embedded_sl_version[2];
extern int nWindowsVersion;
extern char WindowsVersionStr[128];
extern char embedded_sl_version_str[2][12];
extern RUFUS_UPDATE update;
extern int dialog_showing;
@ -316,7 +326,7 @@ extern BOOL Notification(int type, const notification_info* more_info, char* tit
extern BOOL Question(char* title, char* format, ...);
extern BOOL ExtractDOS(const char* path);
extern BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan);
extern BOOL ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file);
extern int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file);
extern BOOL InstallSyslinux(DWORD drive_index, char drive_letter);
DWORD WINAPI FormatThread(void* param);
extern BOOL CreateProgress(void);
@ -326,7 +336,7 @@ extern BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size);
extern unsigned char* GetResource(HMODULE module, char* name, char* type, const char* desc, DWORD* len, BOOL duplicate);
extern BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue);
extern LONG GetEntryWidth(HWND hDropDown, const char* entry);
extern BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog);
extern DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog);
extern HANDLE DownloadFileThreaded(const char* url, const char* file, HWND hProgressDialog);
extern INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
extern BOOL SetUpdateCheck(void);
@ -358,6 +368,7 @@ static __inline void *_reallocf(void *ptr, size_t size)
/* Basic String Array */
typedef struct {
// TODO: rename 'Table' to 'String'
char** Table;
size_t Index; // Current array size
size_t Max; // Maximum array size
@ -366,6 +377,7 @@ extern void StrArrayCreate(StrArray* arr, size_t initial_size);
extern void StrArrayAdd(StrArray* arr, const char* str);
extern void StrArrayClear(StrArray* arr);
extern void StrArrayDestroy(StrArray* arr);
#define IsStrArrayEmpty(arr) (arr.Index == 0)
/*
* typedefs for the function prototypes. Use the something like:
@ -389,7 +401,7 @@ static __inline HMODULE GetDLLHandle(char* szDLLName)
#define PF_INIT(proc, dllname) pf##proc = (proc##_t) GetProcAddress(GetDLLHandle(#dllname), #proc)
#define PF_INIT_OR_OUT(proc, dllname) \
PF_INIT(proc, dllname); if (pf##proc == NULL) { \
uprintf("Unable to access %s DLL: %s\n", #dllname, \
uprintf("Unable to locate %s() in %s.dll: %s\n", #proc, #dllname, \
WindowsErrorString()); goto out; }
/* Clang/MinGW32 has an issue with intptr_t */

View File

@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 206, 329
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Rufus v1.4.3.385"
CAPTION "Rufus v1.4.3.386"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,94,291,50,14
@ -288,8 +288,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,4,3,385
PRODUCTVERSION 1,4,3,385
FILEVERSION 1,4,3,386
PRODUCTVERSION 1,4,3,386
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -306,13 +306,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "1.4.3.385"
VALUE "FileVersion", "1.4.3.386"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2014 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "1.4.3.385"
VALUE "ProductVersion", "1.4.3.386"
END
END
BLOCK "VarFileInfo"

View File

@ -30,16 +30,15 @@
#include "drive.h"
#include "resource.h"
#include "localization.h"
#include "msapi_utf8.h"
#include "syslinux.h"
#include "syslxfs.h"
#include "libfat.h"
#include "setadv.h"
unsigned char* syslinux_ldlinux = NULL;
DWORD syslinux_ldlinux_len;
unsigned char* syslinux_bootsect = NULL;
DWORD syslinux_bootsect_len;
unsigned char* syslinux_ldlinux[2] = { NULL, NULL };
DWORD syslinux_ldlinux_len[2];
unsigned char* syslinux_mboot = NULL;
DWORD syslinux_mboot_len;
@ -78,68 +77,90 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter)
DWORD bytes_written;
BOOL r = FALSE;
FILE* fd;
size_t len;
static unsigned char sectbuf[SECTOR_SIZE];
static char* resource[2][2] = {
{ MAKEINTRESOURCEA(IDR_SL_LDLINUX_V4_SYS), MAKEINTRESOURCEA(IDR_SL_LDLINUX_V4_BSS) },
{ MAKEINTRESOURCEA(IDR_SL_LDLINUX_V5_SYS), MAKEINTRESOURCEA(IDR_SL_LDLINUX_V5_BSS) } };
static char ldlinux_path[] = "?:\\ldlinux.sys";
static char* ldlinux_sys = &ldlinux_path[3];
const char* ldlinux_c32 = "ldlinux.c32";
const char* ldlinux = "ldlinux";
const char* syslinux = "syslinux";
const char* ldlinux_ext[3] = { "sys", "bss", "c32" };
const char* mboot_c32 = "mboot.c32";
char path[MAX_PATH];
char path[MAX_PATH], tmp[64];
struct libfat_filesystem *fs;
libfat_sector_t s, *secp;
libfat_sector_t *sectors = NULL;
int ldlinux_sectors;
uint32_t ldlinux_cluster;
int nsectors;
int i, nsectors;
int dt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType));
BOOL use_v5 = (dt == DT_SYSLINUX_V5) || ((dt == DT_ISO) && (iso_report.has_syslinux_v5));
BOOL use_v5 = (dt == DT_SYSLINUX_V5) || ((dt == DT_ISO) && (SL_MAJOR(iso_report.sl_version) >= 5));
PrintStatus(0, TRUE, MSG_234, use_v5?5:4);
ldlinux_path[0] = drive_letter;
PrintStatus(0, TRUE, MSG_234, (dt == DT_ISO)?iso_report.sl_version_str:embedded_sl_version_str[use_v5?1:0]);
/* Initialize the ADV -- this should be smarter */
syslinux_reset_adv(syslinux_adv);
/* Access a copy of the ldlinux.sys & ldlinux.bss resources */
syslinux_ldlinux = GetResource(hMainInstance, resource[use_v5?1:0][0],
_RT_RCDATA, ldlinux_sys, &syslinux_ldlinux_len, TRUE);
syslinux_bootsect = GetResource(hMainInstance, resource[use_v5?1:0][1],
_RT_RCDATA, "ldlinux.bss", &syslinux_bootsect_len, TRUE);
if ((syslinux_ldlinux == NULL) || (syslinux_bootsect == NULL)) {
goto out;
/* Access a copy of the ldlinux.sys & ldlinux.bss resources (downloaded or embedded) */
if ((syslinux_ldlinux_len[0] != 0) && (syslinux_ldlinux_len[1] != 0)) {
_chdirU(app_dir);
for (i=0; i<2; i++) {
syslinux_ldlinux[i] = (unsigned char*) malloc(syslinux_ldlinux_len[i]);
if (syslinux_ldlinux[i] == NULL)
goto out;
static_sprintf(path, "%s/%s-%s/%s.%s", FILES_DIR, syslinux, &iso_report.sl_version_str[1], ldlinux, i==0?"sys":"bss");
fd = fopen(path, "rb");
if (fd == NULL) {
uprintf("Could not open %s\n", path);
goto out;
}
len = fread(syslinux_ldlinux[i], 1, (size_t)syslinux_ldlinux_len[i], fd);
fclose(fd);
if (len != (size_t)syslinux_ldlinux_len[i]) {
uprintf("Could not read %s\n", path);
goto out;
}
uprintf("Using existing './%s'\n", path);
}
} else {
for (i=0; i<2; i++) {
static_sprintf(tmp, "%s.%s", ldlinux, ldlinux_ext[i]);
syslinux_ldlinux[i] = GetResource(hMainInstance, resource[use_v5?1:0][i],
_RT_RCDATA, tmp, &syslinux_ldlinux_len[i], TRUE);
if (syslinux_ldlinux[i] == NULL)
goto out;
}
}
/* Create ldlinux.sys file */
f_handle = CreateFileA(ldlinux_path, GENERIC_READ | GENERIC_WRITE,
static_sprintf(path, "%C:\\%s.%s", drive_letter, ldlinux, ldlinux_ext[0]);
f_handle = CreateFileA(path, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM |
FILE_ATTRIBUTE_HIDDEN, NULL);
if (f_handle == INVALID_HANDLE_VALUE) {
uprintf("Unable to create '%s'\n", ldlinux_sys);
uprintf("Unable to create '%s'\n", &path[3]);
goto out;
}
/* Write ldlinux.sys file */
if (!WriteFile(f_handle, syslinux_ldlinux, syslinux_ldlinux_len,
if (!WriteFile(f_handle, syslinux_ldlinux[0], syslinux_ldlinux_len[0],
&bytes_written, NULL) ||
bytes_written != syslinux_ldlinux_len) {
uprintf("Could not write '%s'\n", ldlinux_sys);
bytes_written != syslinux_ldlinux_len[0]) {
uprintf("Could not write '%s'\n", &path[3]);
goto out;
}
if (!WriteFile(f_handle, syslinux_adv, 2 * ADV_SIZE,
&bytes_written, NULL) ||
bytes_written != 2 * ADV_SIZE) {
uprintf("Could not write ADV to '%s'\n", ldlinux_sys);
uprintf("Could not write ADV to '%s'\n", &path[3]);
goto out;
}
uprintf("Successfully wrote '%s'\n", ldlinux_sys);
uprintf("Successfully wrote '%s'\n", &path[3]);
if (dt != DT_ISO)
UpdateProgress(OP_DOS, -1.0f);
@ -157,7 +178,7 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter)
}
/* Map the file (is there a better way to do this?) */
ldlinux_sectors = (syslinux_ldlinux_len + 2 * ADV_SIZE + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
ldlinux_sectors = (syslinux_ldlinux_len[0] + 2 * ADV_SIZE + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
sectors = (libfat_sector_t*) calloc(ldlinux_sectors, sizeof *sectors);
if (sectors == NULL)
goto out;
@ -182,10 +203,10 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter)
/* Rewrite the file */
if (SetFilePointer(f_handle, 0, NULL, FILE_BEGIN) != 0 ||
!WriteFile(f_handle, syslinux_ldlinux, syslinux_ldlinux_len,
!WriteFile(f_handle, syslinux_ldlinux[0], syslinux_ldlinux_len[0],
&bytes_written, NULL)
|| bytes_written != syslinux_ldlinux_len) {
uprintf("Could not write '%s': %s\n", ldlinux_sys, WindowsErrorString());
|| bytes_written != syslinux_ldlinux_len[0]) {
uprintf("Could not write '%s': %s\n", &path[3], WindowsErrorString());
goto out;
}
@ -216,16 +237,19 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter)
uprintf("Successfully wrote Syslinux boot record\n");
if (dt == DT_SYSLINUX_V5) {
fd = fopen(ldlinux_c32, "rb");
_chdirU(app_dir);
static_sprintf(path, "%s/%s-%s", FILES_DIR, syslinux, &embedded_sl_version_str[1][1]);
_chdir(path);
static_sprintf(path, "%C:\\%s.%s", drive_letter, ldlinux, ldlinux_ext[2]);
fd = fopen(&path[3], "rb");
if (fd == NULL) {
uprintf("Caution: No '%s' was provided. The target will be missing a required Syslinux file!\n", ldlinux_c32);
uprintf("Caution: No '%s' was provided. The target will be missing a required Syslinux file!\n", &path[3]);
} else {
fclose(fd);
ldlinux_path[11] = 'c'; ldlinux_path[12] = '3'; ldlinux_path[13] = '2';
if (CopyFileA(ldlinux_c32, ldlinux_path, TRUE)) {
uprintf("Created '%s' (from local copy)", ldlinux_path);
if (CopyFileA(&path[3], path, TRUE)) {
uprintf("Created '%s' (from '%s/%s-%s/%s')", path, FILES_DIR, syslinux, &embedded_sl_version_str[1][1], &path[3]);
} else {
uprintf("Failed to create '%s': %s\n", ldlinux_path, WindowsErrorString());
uprintf("Failed to create '%s': %s\n", path, WindowsErrorString());
}
}
} else if (IS_REACTOS(iso_report)) {
@ -236,7 +260,7 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter)
goto out;
}
/* Create mboot.c32 file */
safe_sprintf(path, sizeof(path), "%c:\\%s", drive_letter, mboot_c32);
static_sprintf(path, "%C:\\%s", drive_letter, mboot_c32);
f_handle = CreateFileA(path, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
@ -251,7 +275,7 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter)
goto out;
}
safe_closehandle(f_handle);
safe_sprintf(path, sizeof(path), "%c:\\syslinux.cfg", drive_letter);
static_sprintf(path, "%C:\\syslinux.cfg", drive_letter);
fd = fopen(path, "w");
if (fd == NULL) {
uprintf("Could not create ReactOS 'syslinux.cfg'\n");
@ -269,8 +293,8 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter)
r = TRUE;
out:
safe_free(syslinux_ldlinux);
safe_free(syslinux_bootsect);
safe_free(syslinux_ldlinux[0]);
safe_free(syslinux_ldlinux[1]);
safe_free(sectors);
safe_closehandle(d_handle);
safe_closehandle(f_handle);

View File

@ -19,18 +19,14 @@
#include "setadv.h"
/* The standard boot sector and ldlinux image */
extern unsigned char* syslinux_bootsect;
extern DWORD syslinux_bootsect_len;
extern const int syslinux_bootsect_mtime;
extern unsigned char* syslinux_ldlinux[2];
extern DWORD syslinux_ldlinux_len[2];
extern const int syslinux_ldlinux_mtime[2];
extern unsigned char* syslinux_ldlinux;
extern DWORD syslinux_ldlinux_len;
extern const int syslinux_ldlinux_mtime;
#define boot_sector syslinux_bootsect
#define boot_sector_len syslinux_bootsect_len
#define boot_image syslinux_ldlinux
#define boot_image_len syslinux_ldlinux_len
#define boot_sector syslinux_ldlinux[1]
#define boot_sector_len syslinux_ldlinux_len[1]
#define boot_image syslinux_ldlinux[0]
#define boot_image_len syslinux_ldlinux_len[0]
extern unsigned char syslinux_mbr[];
extern const unsigned int syslinux_mbr_len;