diff --git a/configure b/configure index 4f721934..535b2d0a 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for rufus 2.16. +# Generated by GNU Autoconf 2.69 for rufus 2.17. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='rufus' PACKAGE_TARNAME='rufus' -PACKAGE_VERSION='2.16' -PACKAGE_STRING='rufus 2.16' +PACKAGE_VERSION='2.17' +PACKAGE_STRING='rufus 2.17' PACKAGE_BUGREPORT='https://github.com/pbatard/rufus/issues' PACKAGE_URL='https://rufus.akeo.ie' @@ -1228,7 +1228,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures rufus 2.16 to adapt to many kinds of systems. +\`configure' configures rufus 2.17 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1294,7 +1294,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of rufus 2.16:";; + short | recursive ) echo "Configuration of rufus 2.17:";; esac cat <<\_ACEOF @@ -1385,7 +1385,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -rufus configure 2.16 +rufus configure 2.17 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1440,7 +1440,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by rufus $as_me 2.16, which was +It was created by rufus $as_me 2.17, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2303,7 +2303,7 @@ fi # Define the identity of the package. PACKAGE='rufus' - VERSION='2.16' + VERSION='2.17' cat >>confdefs.h <<_ACEOF @@ -4483,7 +4483,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by rufus $as_me 2.16, which was +This file was extended by rufus $as_me 2.17, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4537,7 +4537,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -rufus config.status 2.16 +rufus config.status 2.17 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 83399a5b..339ab2aa 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([rufus], [2.16], [https://github.com/pbatard/rufus/issues], [rufus], [https://rufus.akeo.ie]) +AC_INIT([rufus], [2.17], [https://github.com/pbatard/rufus/issues], [rufus], [https://rufus.akeo.ie]) AM_INIT_AUTOMAKE([-Wno-portability foreign no-dist no-dependencies]) AC_CONFIG_SRCDIR([src/rufus.c]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/res/appstore/AppxManifest.xml b/res/appstore/AppxManifest.xml index 2aeb1e97..88e18572 100644 --- a/res/appstore/AppxManifest.xml +++ b/res/appstore/AppxManifest.xml @@ -8,7 +8,7 @@ for an interesting struggle, when you also happen to have a comma in one of the fields... --> diff --git a/res/appstore/packme.cmd b/res/appstore/packme.cmd index 738e3c7a..11e33f84 100644 --- a/res/appstore/packme.cmd +++ b/res/appstore/packme.cmd @@ -1,5 +1,5 @@ @echo off -set VERSION=2.16 +set VERSION=2.17 rem Make sure you don't have anything you don't want included in the package, as anything residing in the rem current directory will be included, including any previous .appx, which makes for nice recursion... diff --git a/res/localization/rufus.loc b/res/localization/rufus.loc index 018340e4..00bca720 100644 --- a/res/localization/rufus.loc +++ b/res/localization/rufus.loc @@ -569,7 +569,7 @@ t MSG_298 "The ISO file you have selected does not match its declared size: %s o l "ar-SA" "Arabic (العربية)" 0x0401, 0x0801, 0x0c01, 0x1001, 0x1401, 0x1801, 0x1c01, 0x2001, 0x2401, 0x2801, 0x2c01, 0x3001, 0x3401, 0x3801, 0x3c01, 0x4001 a "r" -v 1.0.18 +v 1.0.22 b "en-US" g IDD_DIALOG @@ -864,7 +864,7 @@ t MSG_173 "إضغط لاختيار..." # POP DIRECTIONAL FORMATTING (UTF-8: 0xE2 0x80 0xAC) at the end. t MSG_174 "‫Rufus - أداة فرمتة الـ USB جديرة بالثقة‬" t MSG_175 "إصدار %d.%d (بناء %d)" -t MSG_176 "الترجمة العربية: عمر الصمد، تحديث: جلال شفرور (mailto:ch_djalel@yahoo.com)" +t MSG_176 "الترجمة العربية: عمر الصمد، تحديث: فراس الشيخ" t MSG_177 "إخبار عن مشكلة أو طلب تعديلات على:" t MSG_178 "حقوق الطبع والنشر الإضافية:" t MSG_179 "تحديث البوليصة:" @@ -998,6 +998,26 @@ t MSG_278 "نوع الإقلاع" t MSG_279 "لا يمكن الإقلاع منه" t MSG_280 "اختيار الصورة" t MSG_281 "(فضلا اختر صورة)" +t MSG_282 "القفل الحصري للUSB" +t MSG_283 "التوفيع الرقمي غير صالح" +t MSG_284 "الملف التنفيذي المحمل ينقصه توقيع رقمي معين" +t MSG_285 "الملف التنفيذي المحمل موقع من قبل '%s'.\nهذا ليس بتوقيع رقمي موثوق من قبلنا وقد يسبب" + "نشاطات تخريبية...\nهل أنت متأكد من الأستمرار؟" +t MSG_286 "تصفير القرص: %0.01%% أكتمل" +t MSG_287 "الكشف عن أقراص الUSB القابلة للإزالة" +t MSG_288 "صلاحيات رفيعة مفقوده" +t MSG_289 "هذا التطبيق يمكنه العمل فقط عند وجود صلاحيات رفيعة" +t MSG_290 "فهرسة الملفات" +t MSG_291 "إختيار الإصدار" +t MSG_292 "الرجاء إختيار إصدار الويندوز المراد تنصيبه:" +t MSG_293 "إصدار ويندوز غير مدعوم" +t MSG_294 "هذا الإصدار من الويندوز لم يعد مدعوماً من قبل روفوس" +t MSG_295 "تحذير: إصدار غير رسمي" +t MSG_296 "هذا الإصدار من روفوس لم يتم إنتاجه من قبل المطورين الرسميين.\n\n؟هل أنت متأكد من الأستمرار" +t MSG_297 "إكتشاف ISO مقطوعة" +t MSG_298 "ملف الISO المحدد لا يطابق حجمه المعلن من قبله: %s من البيانات مفقود!\n\nإذا قمت بالحصول " + "على هذا الملف من الإنترنت, يجب عليك تحميل نسخة جديدة و التحقق من أن المجموع الإختباري لMD5 و SHA مطابق " + "للنسخ(ة) الأصلية.\n\nعلماُ بانه يمكنك مقارنة الMD5 و SHA في روفوس عن طريق الضغط على زر '#'" ################################################################################ l "az-AZ" "Azerbaijani (Azərbaycanca)" 0x042c, 0x782c @@ -8893,7 +8913,7 @@ t MSG_298 "選択されたISOファイルは定義されているファイルサ ################################################################################ l "ko-KR" "Korean (한국어)" 0x0412 -v 1.0.21 +v 1.0.22 b "en-US" # Main dialog @@ -9333,6 +9353,12 @@ t MSG_291 "버전 선택" t MSG_292 "설치할 Windows 버전을 선택하십시오.:" t MSG_293 "지원되지 않는 Windows 버전" t MSG_294 "이 Windows 버전은 Rufus에서 더 이상 지원하지 않습니다." +t MSG_295 "비공식 버전" +t MSG_296 "이 버전의 Rufus는 개발자의 공식 버전이 아닙니다.\n\n그래도 실행하시겠습니까?" +t MSG_297 "깨진 ISO가 감지 됨." +t MSG_298 "선택한 ISO파일이 선언된 것과 일치하지 않습니다. 크기 데이터 %s이(가) 없습니다!\n\n만약 이 파일을 인터넷에서 가져왔다면 " + "새로운 사본을 다운로드 하고 MD5 또는 SHA Checksum이 공식 버전과 일치하는지 확인하십시오.\n\nRufus에서 MD5 또는 SHA를 계산하려면 " + "'#' 버튼을 클릭하십시오." ################################################################################ l "lv-LV" "Latvian (Latviešu)" 0x0426 diff --git a/src/.editorconfig b/src/.editorconfig index dadc965c..13d6cf4a 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -4,7 +4,5 @@ root = true [*] trim_trailing_whitespace = true insert_final_newline = true -# Of course the following is broken in VS2017 release. -# Hopefully will be fixed with next update: -# https://developercommunity.visualstudio.com/content/problem/22922/editorconfig-support-interprets-charset-utf-8-as-u.html -#charset = utf-8 +# Finally, having a default of UTF-8 *without* BOM got fixed in VS2017 15.3 +charset = utf-8 diff --git a/src/dev.c b/src/dev.c index 3297c8c6..04fe943f 100644 --- a/src/dev.c +++ b/src/dev.c @@ -184,7 +184,7 @@ BOOL GetOpticalMedia(IMG_SAVE* img_save) if (!SetupDiGetDeviceRegistryPropertyU(dev_info, &dev_info_data, SPDRP_FRIENDLYNAME, &datatype, (LPBYTE)str, sizeof(str), &size)) { uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %s\n", WindowsErrorString()); - safe_strcpy(str, sizeof(str), "Generic Optical Drive"); + static_strcpy(str, "Generic Optical Drive"); } uprintf("Found '%s' optical device", str); devint_data.cbSize = sizeof(devint_data); @@ -245,7 +245,7 @@ BOOL GetOpticalMedia(IMG_SAVE* img_save) label[k] = 0; img_save->Label = label; } - safe_strcpy(str, sizeof(str), devint_detail_data->DevicePath); + static_strcpy(str, devint_detail_data->DevicePath); img_save->DevicePath = str; img_save->DeviceSize = DiskGeometry->DiskSize.QuadPart; safe_closehandle(hDrive); @@ -296,7 +296,7 @@ BOOL GetDevices(DWORD devnum) // Oh, and we also have card devices (e.g. 'SCSI\DiskO2Micro_SD_...') under the SCSI enumerator... const char* scsi_disk_prefix = "SCSI\\Disk"; const char* scsi_card_name[] = { - "_SD_", "_MMC_", "_MS_", "_MSPro_", "_xDPicture_", "_O2Media_" + "_SD_", "_SDHC_", "_MMC_", "_MS_", "_MSPro_", "_xDPicture_", "_O2Media_" }; const char* usb_speed_name[USB_SPEED_MAX] = { "USB", "USB 1.0", "USB 1.1", "USB 2.0", "USB 3.0" }; // Hash table and String Array used to match a Device ID with the parent hub's Device Interface Path @@ -305,6 +305,7 @@ BOOL GetDevices(DWORD devnum) char letter_name[] = " (?:)"; char drive_name[] = "?:\\"; char uefi_togo_check[] = "?:\\EFI\\Rufus\\ntfs_x64.efi"; + char scsi_card_name_copy[16]; BOOL r = FALSE, found = FALSE, post_backslash; HDEVINFO dev_info = NULL; SP_DEVINFO_DATA dev_info_data; @@ -490,7 +491,15 @@ BOOL GetDevices(DWORD devnum) // Additional detection for SCSI card readers if ((!props.is_CARD) && (safe_strnicmp(buffer, scsi_disk_prefix, sizeof(scsi_disk_prefix)-1) == 0)) { for (j = 0; j < ARRAYSIZE(scsi_card_name); j++) { - if (safe_strstr(buffer, scsi_card_name[j]) != NULL) { + static_strcpy(scsi_card_name_copy, scsi_card_name[j]); + if (safe_strstr(buffer, scsi_card_name_copy) != NULL) { + props.is_CARD = TRUE; + break; + } + // Also test for "_SD&" instead of "_SD_" and so on to allow for devices like + // "SCSI\DiskRicoh_Storage_SD&REV_3.0" to be detected. + scsi_card_name_copy[strlen(scsi_card_name_copy) - 1] = '&'; + if (safe_strstr(buffer, scsi_card_name_copy) != NULL) { props.is_CARD = TRUE; break; } @@ -507,7 +516,7 @@ BOOL GetDevices(DWORD devnum) &datatype, (LPBYTE)buffer, sizeof(buffer), &size)) { uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %s\n", WindowsErrorString()); // We can afford a failure on this call - just replace the name with "USB Storage Device (Generic)" - safe_strcpy(buffer, sizeof(buffer), lmprintf(MSG_045)); + static_strcpy(buffer, lmprintf(MSG_045)); } else if ((!props.is_VHD) && (devid_list != NULL)) { // Get the properties of the device. We could avoid doing this lookup every time by keeping // a lookup table, but there shouldn't be that many USB storage devices connected... @@ -580,7 +589,7 @@ BOOL GetDevices(DWORD devnum) #ifdef FORCED_DEVICE props.vid = FORCED_VID; props.pid = FORCED_PID; - safe_strcpy(buffer, sizeof(buffer), FORCED_NAME); + static_strcpy(buffer, FORCED_NAME); #endif } break; @@ -605,7 +614,7 @@ BOOL GetDevices(DWORD devnum) uuprintf("Found non-USB non-removable device '%s' => Eliminated", buffer); continue; } - safe_strcpy(str, sizeof(str), "????:????"); // Couldn't figure VID:PID + static_strcpy(str, "????:????"); // Couldn't figure VID:PID } else { static_sprintf(str, "%04X:%04X", props.vid, props.pid); } @@ -731,14 +740,14 @@ BOOL GetDevices(DWORD devnum) } // We have multiple volumes assigned to the same device (multiple partitions) // If that is the case, use "Multiple Volumes" instead of the label - safe_strcpy(entry_msg, sizeof(entry_msg), (((drive_letters[0] != 0) && (drive_letters[1] != 0))? + static_strcpy(entry_msg, (((drive_letters[0] != 0) && (drive_letters[1] != 0))? lmprintf(MSG_047):label)); for (k=0, remove_drive=0; drive_letters[k] && (!remove_drive); k++) { // Append all the drive letters we detected letter_name[2] = drive_letters[k]; if (right_to_left_mode) - safe_strcat(entry_msg, sizeof(entry_msg), RIGHT_TO_LEFT_MARK); - safe_strcat(entry_msg, sizeof(entry_msg), letter_name); + static_strcat(entry_msg, RIGHT_TO_LEFT_MARK); + static_strcat(entry_msg, letter_name); if (drive_letters[k] == (PathGetDriveNumberU(app_dir) + 'A')) remove_drive = 1; if (drive_letters[k] == (PathGetDriveNumberU(system_dir) + 'A')) diff --git a/src/dos.c b/src/dos.c index 220a28ed..c73b17ce 100644 --- a/src/dos.c +++ b/src/dos.c @@ -301,8 +301,8 @@ static BOOL ExtractMSDOS(const char* path) return FALSE; // Reduce the visible mess by placing all the locale files into a subdir - safe_strcpy(locale_path, sizeof(locale_path), path); - safe_strcat(locale_path, sizeof(locale_path), "LOCALE\\"); + static_strcpy(locale_path, path); + static_strcat(locale_path, "LOCALE\\"); CreateDirectoryA(locale_path, NULL); len = GetSystemDirectoryA(dllname, sizeof(dllname)); @@ -310,7 +310,7 @@ static BOOL ExtractMSDOS(const char* path) uprintf("Unable to get system directory: %s\n", WindowsErrorString()); goto out; } - safe_strcat(dllname, sizeof(dllname), "\\diskcopy.dll"); + static_strcat(dllname, "\\diskcopy.dll"); hDLL = LoadLibraryA(dllname); if (hDLL == NULL) { uprintf("Unable to open %s: %s\n", dllname, WindowsErrorString()); @@ -375,15 +375,15 @@ BOOL ExtractFreeDOS(const char* path) } // Reduce the visible mess by placing all the locale files into a subdir - safe_strcpy(locale_path, sizeof(locale_path), path); - safe_strcat(locale_path, sizeof(locale_path), "LOCALE\\"); + static_strcpy(locale_path, path); + static_strcat(locale_path, "LOCALE\\"); CreateDirectoryA(locale_path, NULL); for (i=0; iPartitionEntry[0].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) && (DriveLayout->PartitionEntry[0].StartingOffset.QuadPart == 0LL)) { suprintf("Partition type: SFD (Super Floppy Disk) or Unpartitioned"); - big_floppy = TRUE; + super_floppy_disk = TRUE; } else { suprintf("Partition type: MBR, NB Partitions: %d\n", SelectedDrive.nPartitions); SelectedDrive.has_mbr_uefi_marker = (DriveLayout->Mbr.Signature == MBR_UEFI_MARKER); @@ -780,7 +780,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys part_type = DriveLayout->PartitionEntry[i].Mbr.PartitionType; isUefiNtfs = (i == 1) && (part_type == 0xef) && (DriveLayout->PartitionEntry[i].PartitionLength.QuadPart <= 1*MB); - suprintf("Partition %d%s:\n", i+(big_floppy?0:1), isUefiNtfs?" (UEFI:NTFS)":""); + suprintf("Partition %d%s:\n", i+(super_floppy_disk?0:1), isUefiNtfs?" (UEFI:NTFS)":""); for (j=0; jPartitionEntry[i].PartitionLength.QuadPart, TRUE, FALSE), DriveLayout->PartitionEntry[i].PartitionLength.QuadPart, DriveLayout->PartitionEntry[i].StartingOffset.QuadPart / SelectedDrive.SectorSize, @@ -1078,7 +1078,7 @@ typedef struct _DRIVE_LAYOUT_INFORMATION_EX4 { */ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, uint8_t extra_partitions) { - const char* PartitionTypeName[2] = { "MBR", "GPT" }; + const char* PartitionTypeName[] = { "MBR", "GPT", "SFD" }; unsigned char* buffer; size_t uefi_ntfs_size = 0; CREATE_DISK CreateDisk = {PARTITION_STYLE_RAW, {{0}}}; @@ -1090,6 +1090,10 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m PrintInfoDebug(0, MSG_238, PartitionTypeName[partition_style]); + if (partition_style == PARTITION_STYLE_SFD) + // Nothing to do + return TRUE; + if (extra_partitions & XP_UEFI_NTFS) { uefi_ntfs_size = GetResourceSize(hMainInstance, MAKEINTRESOURCEA(IDR_UEFI_NTFS), _RT_RCDATA, "uefi-ntfs.img"); if (uefi_ntfs_size == 0) diff --git a/src/format.c b/src/format.c index c0ba4a1c..7c6d559e 100644 --- a/src/format.c +++ b/src/format.c @@ -712,8 +712,8 @@ static BOOL FormatDrive(DWORD DriveIndex) // Check if Windows picked the UEFI:NTFS partition // NB: No need to do this for Large FAT32, as this only applies to NTFS - safe_strcpy(path, MAX_PATH, VolumeName); - safe_strcat(path, MAX_PATH, "EFI\\Rufus\\ntfs_x64.efi"); + static_strcpy(path, VolumeName); + static_strcat(path, "EFI\\Rufus\\ntfs_x64.efi"); if (PathFileExistsA(path)) { uprintf("Windows selected the UEFI:NTFS partition for formatting - Retry needed", VolumeName); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_RETRY; @@ -1167,16 +1167,16 @@ static BOOL SetupWinPE(char drive_letter) index = ((img_report.winpe&WINPE_I386) == WINPE_I386)?0:1; // Allow other values than harddisk 1, as per user choice for disk ID - safe_sprintf(setupsrcdev, sizeof(setupsrcdev), - "SetupSourceDevice = \"\\device\\harddisk%d\\partition1\"", ComboBox_GetCurSel(hDiskID)); + static_sprintf(setupsrcdev, "SetupSourceDevice = \"\\device\\harddisk%d\\partition1\"", + ComboBox_GetCurSel(hDiskID)); // Copy of ntdetect.com in root - safe_sprintf(src, sizeof(src), "%c:\\%s\\ntdetect.com", drive_letter, basedir[index]); - safe_sprintf(dst, sizeof(dst), "%c:\\ntdetect.com", drive_letter); + static_sprintf(src, "%c:\\%s\\ntdetect.com", drive_letter, basedir[index]); + static_sprintf(dst, "%c:\\ntdetect.com", drive_letter); CopyFileA(src, dst, TRUE); if (!img_report.uses_minint) { // Create a copy of txtsetup.sif, as we want to keep the i386 files unmodified - safe_sprintf(src, sizeof(src), "%c:\\%s\\txtsetup.sif", drive_letter, basedir[index]); - safe_sprintf(dst, sizeof(dst), "%c:\\txtsetup.sif", drive_letter); + static_sprintf(src, "%c:\\%s\\txtsetup.sif", drive_letter, basedir[index]); + static_sprintf(dst, "%c:\\txtsetup.sif", drive_letter); if (!CopyFileA(src, dst, TRUE)) { uprintf("Did not copy %s as %s: %s\n", src, dst, WindowsErrorString()); } @@ -1187,8 +1187,8 @@ static BOOL SetupWinPE(char drive_letter) uprintf("Successfully added '%s' to %s\n", setupsrcdev, dst); } - safe_sprintf(src, sizeof(src), "%c:\\%s\\setupldr.bin", drive_letter, basedir[index]); - safe_sprintf(dst, sizeof(dst), "%c:\\BOOTMGR", drive_letter); + static_sprintf(src, "%c:\\%s\\setupldr.bin", drive_letter, basedir[index]); + static_sprintf(dst, "%c:\\BOOTMGR", drive_letter); if (!CopyFileA(src, dst, TRUE)) { uprintf("Did not copy %s as %s: %s\n", src, dst, WindowsErrorString()); } @@ -1288,6 +1288,7 @@ int SetWinToGoIndex(void) char tmp_path[MAX_PATH] = "", xml_file[MAX_PATH] = ""; StrArray version_name, version_index; int i, build_nr = 0; + BOOL bNonStandard = FALSE; // Sanity checks wintogo_index = -1; @@ -1307,8 +1308,8 @@ int SetWinToGoIndex(void) if ((GetTempPathU(sizeof(tmp_path), tmp_path) == 0) || (GetTempFileNameU(tmp_path, APPLICATION_NAME, 0, xml_file) == 0) || (xml_file[0] == 0)) { - // Last ditch effort to get a loc file - just extract it to the current directory - safe_strcpy(xml_file, sizeof(xml_file), ".\\RufVXml.tmp"); + // Last ditch effort to get a tmp file - just extract it to the current directory + static_strcpy(xml_file, ".\\RufVXml.tmp"); } // GetTempFileName() may leave a file behind DeleteFileU(xml_file); @@ -1321,8 +1322,24 @@ int SetWinToGoIndex(void) StrArrayCreate(&version_name, 16); StrArrayCreate(&version_index, 16); - for (i = 0; (StrArrayAdd(&version_name, get_token_data_file_indexed("DISPLAYNAME", xml_file, i + 1), FALSE) >= 0) && - (StrArrayAdd(&version_index, get_token_data_file_indexed("IMAGE INDEX", xml_file, i + 1), FALSE) >= 0); i++); + for (i = 0; StrArrayAdd(&version_index, get_token_data_file_indexed("IMAGE INDEX", xml_file, i + 1), FALSE) >= 0; i++) { + // Some people are apparently creating *unofficial* Windows ISOs that don't have DISPLAYNAME elements. + // If we are parsing such an ISO, try to fall back to using DESCRIPTION. Of course, since we don't use + // a formal XML parser, if an ISO mixes entries with both DISPLAYNAME and DESCRIPTION and others with + // only DESCRIPTION, the version names we report will be wrong. + // But hey, there's only so far I'm willing to go to help people who, not content to have demonstrated + // their utter ignorance on development matters, are also trying to lecture experienced developers + // about specific "noob mistakes"... that don't exist in the code they are trying to criticize. + if (StrArrayAdd(&version_name, get_token_data_file_indexed("DISPLAYNAME", xml_file, i + 1), FALSE) < 0) { + bNonStandard = TRUE; + if (StrArrayAdd(&version_name, get_token_data_file_indexed("DESCRIPTION", xml_file, i + 1), FALSE) < 0) { + uprintf("Warning: Could not find a description for image index %d", i + 1); + StrArrayAdd(&version_name, "Unknown Windows Version", TRUE); + } + } + } + if (bNonStandard) + uprintf("Warning: Nonstandard Windows image (missing entries)"); if (i > 1) i = SelectionDialog(lmprintf(MSG_291), lmprintf(MSG_292), version_name.String, i); @@ -1333,7 +1350,7 @@ int SetWinToGoIndex(void) } else { wintogo_index = atoi(version_index.String[i - 1]); } - if (i >= 0) { + if (i > 0) { // Get the build version build = get_token_data_file_indexed("BUILD", xml_file, i); if (build != NULL) @@ -1754,7 +1771,7 @@ DWORD WINAPI FormatThread(void* param) // create a log file for bad blocks report. Since %USERPROFILE% may // have localized characters, we use the UTF-8 API. userdir = getenvU("USERPROFILE"); - safe_strcpy(logfile, MAX_PATH, userdir); + static_strcpy(logfile, userdir); safe_free(userdir); GetLocalTime(<); safe_sprintf(&logfile[strlen(logfile)], sizeof(logfile)-strlen(logfile)-1, @@ -2025,7 +2042,7 @@ DWORD WINAPI FormatThread(void* param) efi_dst[0] = drive_name[0]; efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = 0; if (!CreateDirectoryA(efi_dst, 0)) { - uprintf("Could not create directory '%s': %s\n", WindowsErrorString()); + uprintf("Could not create directory '%s': %s\n", efi_dst, WindowsErrorString()); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); } else { efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = '\\'; diff --git a/src/icon.c b/src/icon.c index 8b9b02f5..3bd5cb4d 100644 --- a/src/icon.c +++ b/src/icon.c @@ -160,7 +160,7 @@ BOOL SetAutorun(const char* path) char filename[64]; wchar_t wlabel[128], wRufusVersion[32]; - safe_sprintf(filename, sizeof(filename), "%sautorun.inf", path); + static_sprintf(filename, "%sautorun.inf", path); fd = fopen(filename, "r"); // If there's an existing autorun, don't overwrite if (fd != NULL) { uprintf("%s already exists - keeping it", filename); diff --git a/src/iso.c b/src/iso.c index 2b468c8c..4f49538e 100644 --- a/src/iso.c +++ b/src/iso.c @@ -39,6 +39,7 @@ #include #include "rufus.h" +#include "libfat.h" #include "missing.h" #include "resource.h" #include "msapi_utf8.h" @@ -73,6 +74,7 @@ static const char* grldr_name = "grldr"; static const char* ldlinux_name = "ldlinux.sys"; static const char* ldlinux_c32 = "ldlinux.c32"; static const char* efi_dirname = "/efi/boot"; +static const char* efi_img_name = "efi.img"; // Used by Debian Live ISOHybrids static const char* efi_bootname[] = { "bootia32.efi", "bootia64.efi", "bootx64.efi", "bootarm.efi", "bootaa64.efi", "bootebc.efi" }; static const char* install_wim_path = "/sources"; static const char* install_wim_name[] = { "install.wim", "install.swm" }; @@ -200,7 +202,11 @@ static BOOL check_iso_props(const char* psz_dirname, int64_t i_file_length, cons // Check for ReactOS' setupldr.sys anywhere if ((img_report.reactos_path[0] == 0) && (safe_stricmp(psz_basename, reactos_name) == 0)) - safe_strcpy(img_report.reactos_path, sizeof(img_report.reactos_path), psz_fullpath); + static_strcpy(img_report.reactos_path, psz_fullpath); + + // Check for the first 'efi.img' we can find (that hopefully contains EFI boot files) + if (!HAS_EFI_IMG(img_report) && (safe_stricmp(psz_basename, efi_img_name) == 0)) + static_strcpy(img_report.efi_img_path, psz_fullpath); // Check for the EFI boot entries if (safe_stricmp(psz_dirname, efi_dirname) == 0) { @@ -626,7 +632,7 @@ void GetGrubVersion(char* buf, size_t buf_size) for (i=0; i= safe_strlen(config_path.String[i])) - safe_strcpy(img_report.cfg_path, sizeof(img_report.cfg_path), config_path.String[i]); + static_strcpy(img_report.cfg_path, config_path.String[i]); } uprintf(" Will use '%s' for Syslinux", img_report.cfg_path); // Extract all of the isolinux.bin files we found to identify their versions @@ -805,7 +811,7 @@ out: fclose(fd); sl_version = GetSyslinuxVersion(buf, size, &ext); if (img_report.sl_version == 0) { - safe_strcpy(img_report.sl_version_ext, sizeof(img_report.sl_version_ext), ext); + static_strcpy(img_report.sl_version_ext, ext); img_report.sl_version = sl_version; sl_index = i; } else if ((img_report.sl_version != sl_version) || (safe_strcmp(img_report.sl_version_ext, ext) != 0)) { @@ -816,7 +822,7 @@ out: // Where possible, prefer to the one that resides in the same directory as the config file. for (j=safe_strlen(img_report.cfg_path); (j>0) && (img_report.cfg_path[j]!='/'); j--); if (safe_strnicmp(img_report.cfg_path, isolinux_path.String[i], j) == 0) { - safe_strcpy(img_report.sl_version_ext, sizeof(img_report.sl_version_ext), ext); + static_strcpy(img_report.sl_version_ext, ext); img_report.sl_version = sl_version; sl_index = i; } @@ -841,12 +847,15 @@ out: uprintf(" Warning: Could not detect Isolinux version - Forcing to %s (embedded)", img_report.sl_version_str); } + if (!IS_EFI_BOOTABLE(img_report) && HAS_EFI_IMG(img_report) && ExtractEfiImgFiles(NULL)) { + img_report.has_efi = 0x80; + } } if (HAS_WINPE(img_report)) { // In case we have a WinPE 1.x based iso, we extract and parse txtsetup.sif // during scan, to see if /minint was provided for OsLoadOptions, as it decides // whether we should use 0x80 or 0x81 as the disk ID in the MBR - safe_sprintf(path, sizeof(path), "/%s/txtsetup.sif", + static_sprintf(path, "/%s/txtsetup.sif", basedir[((img_report.winpe&WINPE_I386) == WINPE_I386)?0:1]); ExtractISOFile(src_iso, path, tmp_sif, FILE_ATTRIBUTE_NORMAL); tmp = get_token_data_file("OsLoadOptions", tmp_sif); @@ -889,35 +898,40 @@ out: StrArrayDestroy(&config_path); StrArrayDestroy(&isolinux_path); SendMessage(hMainDialog, UM_PROGRESS_EXIT, 0, 0); - } else if (HAS_SYSLINUX(img_report)) { - 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"); - if (fd != NULL && img_report.needs_syslinux_overwrite) { - fclose(fd); - fd = NULL; - safe_sprintf(path2, sizeof(path2), "%s\\syslinux.org", dest_dir); - uprintf("Renaming: %s ➔ %s", path, path2); - IGNORE_RETVAL(rename(path, path2)); - } - if (fd == NULL) { - fd = fopen(path, "w"); // No "/syslinux.cfg" => create a new one - if (fd == NULL) { - uprintf("Unable to create %s - booting from USB will not work", path); - r = 1; - } else { - fprintf(fd, "DEFAULT loadconfig\n\nLABEL loadconfig\n CONFIG %s\n", img_report.cfg_path); - for (i=safe_strlen(img_report.cfg_path); (i>0)&&(img_report.cfg_path[i]!='/'); i--); - if (i>0) { - img_report.cfg_path[i] = 0; - fprintf(fd, " APPEND %s/\n", img_report.cfg_path); - img_report.cfg_path[i] = '/'; - } - uprintf("Created: %s", path); + } else { + // For Debian live ISOs, that only provide EFI boot files in a FAT efi.img + if (img_report.has_efi == 0x80) + ExtractEfiImgFiles(dest_dir); + if (HAS_SYSLINUX(img_report)) { + static_sprintf(path, "%s\\syslinux.cfg", dest_dir); + // Create a /syslinux.cfg (if none exists) that points to the existing isolinux cfg + fd = fopen(path, "r"); + if (fd != NULL && img_report.needs_syslinux_overwrite) { + fclose(fd); + fd = NULL; + static_sprintf(path2, "%s\\syslinux.org", dest_dir); + uprintf("Renaming: %s ➔ %s", path, path2); + IGNORE_RETVAL(rename(path, path2)); } + if (fd == NULL) { + fd = fopen(path, "w"); // No "/syslinux.cfg" => create a new one + if (fd == NULL) { + uprintf("Unable to create %s - booting from USB will not work", path); + r = 1; + } else { + fprintf(fd, "DEFAULT loadconfig\n\nLABEL loadconfig\n CONFIG %s\n", img_report.cfg_path); + for (i = safe_strlen(img_report.cfg_path); (i > 0) && (img_report.cfg_path[i] != '/'); i--); + if (i > 0) { + img_report.cfg_path[i] = 0; + fprintf(fd, " APPEND %s/\n", img_report.cfg_path); + img_report.cfg_path[i] = '/'; + } + uprintf("Created: %s", path); + } + } + if (fd != NULL) + fclose(fd); } - if (fd != NULL) - fclose(fd); } if (p_iso != NULL) iso9660_close(p_iso); @@ -945,7 +959,7 @@ int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_f file_handle = CreateFileU(dest_file, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, attributes, NULL); if (file_handle == INVALID_HANDLE_VALUE) { - uprintf(" Unable to create file %s: %s\n", dest_file, WindowsErrorString()); + uprintf(" Could not create file %s: %s", dest_file, WindowsErrorString()); goto out; } @@ -956,12 +970,12 @@ int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_f p_udf_root = udf_get_root(p_udf, true, 0); if (p_udf_root == NULL) { - uprintf("Could not locate UDF root directory\n"); + uprintf("Could not locate UDF root directory"); goto out; } p_udf_file = udf_fopen(p_udf_root, iso_file); if (!p_udf_file) { - uprintf("Could not locate file %s in ISO image\n", iso_file); + uprintf("Could not locate file %s in ISO image", iso_file); goto out; } file_length = udf_get_file_length(p_udf_file); @@ -969,12 +983,12 @@ int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_f memset(buf, 0, UDF_BLOCKSIZE); read_size = udf_read_block(p_udf_file, buf, 1); if (read_size < 0) { - uprintf("Error reading UDF file %s\n", iso_file); + uprintf("Error reading UDF file %s", iso_file); goto out; } buf_size = (DWORD)MIN(file_length, read_size); if (!WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES)) { - uprintf(" Error writing file %s: %s\n", dest_file, WindowsErrorString()); + uprintf(" Error writing file %s: %s", dest_file, WindowsErrorString()); goto out; } file_length -= read_size; @@ -985,13 +999,13 @@ int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_f try_iso: p_iso = iso9660_open(iso); if (p_iso == NULL) { - uprintf("Unable to open image '%s'.\n", iso); + uprintf("Unable to open image '%s'", iso); goto out; } p_statbuf = iso9660_ifs_stat_translate(p_iso, iso_file); if (p_statbuf == NULL) { - uprintf("Could not get ISO-9660 file information for file %s\n", iso_file); + uprintf("Could not get ISO-9660 file information for file %s", iso_file); goto out; } @@ -1000,12 +1014,12 @@ try_iso: memset(buf, 0, ISO_BLOCKSIZE); lsn = p_statbuf->lsn + (lsn_t)i; if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) { - uprintf(" Error reading ISO9660 file %s at LSN %lu\n", iso_file, (long unsigned int)lsn); + uprintf(" Error reading ISO9660 file %s at LSN %lu", iso_file, (long unsigned int)lsn); goto out; } buf_size = (DWORD)MIN(file_length, ISO_BLOCKSIZE); if (!WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES)) { - uprintf(" Error writing file %s: %s\n", dest_file, WindowsErrorString()); + uprintf(" Error writing file %s: %s", dest_file, WindowsErrorString()); goto out; } file_length -= ISO_BLOCKSIZE; @@ -1052,16 +1066,16 @@ uint32_t GetInstallWimVersion(const char* iso) p_udf_root = udf_get_root(p_udf, true, 0); if (p_udf_root == NULL) { - uprintf("Could not locate UDF root directory\n"); + uprintf("Could not locate UDF root directory"); goto out; } p_udf_file = udf_fopen(p_udf_root, wim_path); if (!p_udf_file) { - uprintf("Could not locate file %s in ISO image\n", wim_path); + uprintf("Could not locate file %s in ISO image", wim_path); goto out; } if (udf_read_block(p_udf_file, buf, 1) != UDF_BLOCKSIZE) { - uprintf("Error reading UDF file %s\n", wim_path); + uprintf("Error reading UDF file %s", wim_path); goto out; } r = wim_header[3]; @@ -1070,16 +1084,16 @@ uint32_t GetInstallWimVersion(const char* iso) try_iso: p_iso = iso9660_open(iso); if (p_iso == NULL) { - uprintf("Unable to open image '%s'.\n", iso); + uprintf("Could not open image '%s'", iso); goto out; } p_statbuf = iso9660_ifs_stat_translate(p_iso, wim_path); if (p_statbuf == NULL) { - uprintf("Could not get ISO-9660 file information for file %s\n", wim_path); + uprintf("Could not get ISO-9660 file information for file %s", wim_path); goto out; } if (iso9660_iso_seek_read(p_iso, buf, p_statbuf->lsn, 1) != ISO_BLOCKSIZE) { - uprintf("Error reading ISO9660 file %s at LSN %lu\n", wim_path, (long unsigned int)p_statbuf->lsn); + uprintf("Error reading ISO-9660 file %s at LSN %lu", wim_path, (long unsigned int)p_statbuf->lsn); goto out; } r = wim_header[3]; @@ -1100,6 +1114,184 @@ out: return bswap_uint32(r); } +#define ISO_NB_BLOCKS 16 +typedef struct { + iso9660_t* p_iso; + lsn_t lsn; + libfat_sector_t sec_start; + // Use a multi block buffer, to improve sector reads + uint8_t buf[ISO_BLOCKSIZE * ISO_NB_BLOCKS]; +} iso9660_readfat_private; + +/* + * Read sectors from a FAT img file residing on an ISO-9660 filesystem. + * NB: This assumes that the img file sectors are contiguous on the ISO. + */ +int iso9660_readfat(intptr_t pp, void *buf, size_t secsize, libfat_sector_t sec) +{ + iso9660_readfat_private* p_private = (iso9660_readfat_private*)pp; + + if (sizeof(p_private->buf) % secsize != 0) { + uprintf("iso9660_readfat: Sector size %d is not a divisor of %d", secsize, sizeof(p_private->buf)); + return 0; + } + + if ((sec < p_private->sec_start) || (sec >= p_private->sec_start + sizeof(p_private->buf) / secsize)) { + // Sector being queried is not in our multi block buffer -> Update it + p_private->sec_start = (((sec * secsize) / ISO_BLOCKSIZE) * ISO_BLOCKSIZE) / secsize; + if (iso9660_iso_seek_read(p_private->p_iso, p_private->buf, + p_private->lsn + (lsn_t)((p_private->sec_start * secsize) / ISO_BLOCKSIZE), ISO_NB_BLOCKS) + != ISO_NB_BLOCKS * ISO_BLOCKSIZE) { + uprintf("Error reading ISO-9660 file %s at LSN %lu\n", img_report.efi_img_path, + (long unsigned int)(p_private->lsn + (p_private->sec_start * secsize) / ISO_BLOCKSIZE)); + return 0; + } + } + memcpy(buf, &p_private->buf[(sec - p_private->sec_start)*secsize], secsize); + return (int)secsize; +} + +/* + * Extract EFI bootloaders files from an ISO-9660 FAT img file into directory . + * If is NULL, returns TRUE if an EFI bootloader exists in the img. + * If is not NULL, returns TRUE if any if the bootloaders was properly written. + */ +BOOL ExtractEfiImgFiles(const char* dir) +{ + BOOL ret = FALSE; + HANDLE handle; + DWORD size, file_size, written; + iso9660_t* p_iso = NULL; + iso9660_stat_t* p_statbuf = NULL; + iso9660_readfat_private* p_private = NULL; + libfat_sector_t s; + int32_t dc, c; + struct libfat_filesystem *fs = NULL; + struct libfat_direntry direntry; + char name[12] = { 0 }; + char path[64]; + int i, j, k; + void* buf; + + if ((image_path == NULL) || !HAS_EFI_IMG(img_report)) + return FALSE; + + p_iso = iso9660_open(image_path); + if (p_iso == NULL) { + uprintf("Could not open image '%s' as an ISO-9660 file system", image_path); + goto out; + } + p_statbuf = iso9660_ifs_stat_translate(p_iso, img_report.efi_img_path); + if (p_statbuf == NULL) { + uprintf("Could not get ISO-9660 file information for file %s\n", img_report.efi_img_path); + goto out; + } + p_private = malloc(sizeof(iso9660_readfat_private)); + if (p_private == NULL) + goto out; + p_private->p_iso = p_iso; + p_private->lsn = p_statbuf->lsn; + p_private->sec_start = 0; + // Populate our intial buffer + if (iso9660_iso_seek_read(p_private->p_iso, p_private->buf, p_private->lsn, ISO_NB_BLOCKS) != ISO_NB_BLOCKS * ISO_BLOCKSIZE) { + uprintf("Error reading ISO-9660 file %s at LSN %lu\n", img_report.efi_img_path, (long unsigned int)p_private->lsn); + goto out; + } + fs = libfat_open(iso9660_readfat, (intptr_t)p_private); + if (fs == NULL) { + uprintf("FAT access error"); + goto out; + } + + // Navigate to /EFI/BOOT + if (libfat_searchdir(fs, 0, "EFI ", &direntry) < 0) + goto out; + dc = direntry.entry[26] + (direntry.entry[27] << 8); + if (libfat_searchdir(fs, dc, "BOOT ", &direntry) < 0) + goto out; + dc = direntry.entry[26] + (direntry.entry[27] << 8); + + for (i = 0; i < ARRAYSIZE(efi_bootname); i++) { + // Sanity check in case the EFI forum comes up with a 'bootmips64.efi' or something... + if (strlen(efi_bootname[i]) > 12) { + uprintf("Internal error: FAT 8.3"); + continue; + } + for (j = 0, k = 0; efi_bootname[i][j] != 0; j++) { + if (efi_bootname[i][j] == '.') { + while (k < 8) + name[k++] = ' '; + } else + name[k++] = toupper(efi_bootname[i][j]); + } + c = libfat_searchdir(fs, dc, name, &direntry); + if (c > 0) { + if (dir == NULL) { + if (!ret) + uprintf(" Detected EFI bootloader(s) (from '%s'):", img_report.efi_img_path); + uprintf(" ● '%s'", efi_bootname[i]); + ret = TRUE; + } else { + file_size = direntry.entry[28] + (direntry.entry[29] << 8) + (direntry.entry[30] << 16) + + (direntry.entry[31] << 24); + // Sanity check + if (file_size > 64 * MB) { + uprintf("Warning: File size is larger than 64 MB => not extracted"); + continue; + } + static_sprintf(path, "%s\\efi", dir); + if (!CreateDirectoryA(path, 0) && (GetLastError() != ERROR_ALREADY_EXISTS)) { + uprintf("Could not create directory '%s': %s\n", path, WindowsErrorString()); + continue; + } + static_strcat(path, "\\boot"); + if (!CreateDirectoryA(path, 0) && (GetLastError() != ERROR_ALREADY_EXISTS)) { + uprintf("Could not create directory '%s': %s\n", path, WindowsErrorString()); + continue; + } + static_strcat(path, "\\"); + static_strcat(path, efi_bootname[i]); + uprintf("Extracting: %s (from '%s', %s)", path, img_report.efi_img_path, + SizeToHumanReadable(file_size, FALSE, FALSE)); + handle = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, + NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (handle == INVALID_HANDLE_VALUE) { + uprintf("Unable to create '%s': %s", path, WindowsErrorString()); + continue; + } + + written = 0; + s = libfat_clustertosector(fs, c); + while ((s != 0) && (s < 0xFFFFFFFFULL) && (written < file_size)) { + buf = libfat_get_sector(fs, s); + size = MIN(LIBFAT_SECTOR_SIZE, file_size - written); + if (!WriteFileWithRetry(handle, buf, size, &size, WRITE_RETRIES) || + (size != MIN(LIBFAT_SECTOR_SIZE, file_size - written))) { + uprintf("Error writing '%s': %s", path, WindowsErrorString()); + CloseHandle(handle); + continue; + } + written += size; + s = libfat_nextsector(fs, s); + } + CloseHandle(handle); + ret = TRUE; + } + } + } + +out: + if (fs != NULL) + libfat_close(fs); + if (p_statbuf != NULL) + safe_free(p_statbuf->rr.psz_symlink); + safe_free(p_statbuf); + safe_free(p_private); + if (p_iso != NULL) + iso9660_close(p_iso); + return ret; +} + // VirtDisk API Prototypes - Only available for Windows 8 or later PF_TYPE_DECL(WINAPI, DWORD, OpenVirtualDisk, (PVIRTUAL_STORAGE_TYPE, PCWSTR, VIRTUAL_DISK_ACCESS_MASK, OPEN_VIRTUAL_DISK_FLAG, POPEN_VIRTUAL_DISK_PARAMETERS, PHANDLE)); diff --git a/src/license.h b/src/license.h index dfc83094..f2ad6031 100644 --- a/src/license.h +++ b/src/license.h @@ -762,4 +762,4 @@ const char* gplv3 = "Program, unless a warranty or assumption of liability accompanies a\r\n" "copy of the Program in return for a fee.\r\n" "\r\n" -" END OF TERMS AND CONDITIONS"; \ No newline at end of file +" END OF TERMS AND CONDITIONS"; diff --git a/src/msapi_utf8.h b/src/msapi_utf8.h index a0b2c0e5..d220fc2e 100644 --- a/src/msapi_utf8.h +++ b/src/msapi_utf8.h @@ -293,6 +293,18 @@ static __inline int LoadStringU(HINSTANCE hInstance, UINT uID, LPSTR lpBuffer, i return ret; } +static __inline HMODULE LoadLibraryU(LPCSTR lpFileName) +{ + HMODULE ret; + DWORD err = ERROR_INVALID_DATA; + wconvert(lpFileName); + ret = LoadLibraryW(wlpFileName); + err = GetLastError(); + wfree(lpFileName); + SetLastError(err); + return ret; +} + static __inline int DrawTextU(HDC hDC, LPCSTR lpText, int nCount, LPRECT lpRect, UINT uFormat) { int ret; @@ -1027,15 +1039,6 @@ static __inline BOOL GetVolumeInformationU(LPCSTR lpRootPathName, LPSTR lpVolume return ret; } -static __inline HMODULE LoadLibraryU(LPCSTR lpFileName) -{ - HMODULE h; - wconvert(lpFileName); - h = LoadLibraryW(wlpFileName); - wfree(lpFileName); - return h; -} - #ifdef __cplusplus } #endif diff --git a/src/net.c b/src/net.c index 2e77d589..453851a2 100644 --- a/src/net.c +++ b/src/net.c @@ -205,7 +205,7 @@ const char* WinInetErrorString(void) InternetGetLastResponseInfoA(&error_code, error_string, &size); return error_string; default: - safe_sprintf(error_string, sizeof(error_string), "Unknown internet error 0x%08lX", error_code); + static_sprintf(error_string, "Unknown internet error 0x%08lX", error_code); return error_string; } } @@ -275,7 +275,7 @@ DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog) uprintf("Network is unavailable: %s\n", WinInetErrorString()); goto out; } - safe_sprintf(agent, ARRAYSIZE(agent), APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)", + static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)", rufus_version[0], rufus_version[1], rufus_version[2], nWindowsVersion>>4, nWindowsVersion&0x0F, is_x64()?"; WOW64":""); hSession = InternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); @@ -404,7 +404,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) { BOOL releases_only, found_new_version = FALSE; int status = 0; - const char* server_url = UPDATE_URL "/"; + const char* server_url = RUFUS_NO_SSL_URL "/"; int i, j, k, max_channel, verbose = 0, verpos[4]; static const char* archname[] = {"win_x86", "win_x64"}; static const char* channel[] = {"release", "beta", "test"}; // release channel @@ -467,7 +467,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) goto out; hostname[sizeof(hostname)-1] = 0; - safe_sprintf(agent, ARRAYSIZE(agent), APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)", + static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)", rufus_version[0], rufus_version[1], rufus_version[2], nWindowsVersion >> 4, nWindowsVersion & 0x0F, is_x64() ? "; WOW64" : ""); hSession = InternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); @@ -493,7 +493,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) // and then remove each each of the components until we find our match. For instance, we may first // look for rufus_win_x64_6.2.ver (Win8 x64) but only get a match for rufus_win_x64_6.ver (Vista x64 or later) // This allows sunsetting OS versions (eg XP) or providing different downloads for different archs/groups. - safe_sprintf(urlpath, sizeof(urlpath), "%s%s%s_%s_%lu.%lu.ver", APPLICATION_NAME, (k==0)?"":"_", + static_sprintf(urlpath, "%s%s%s_%s_%lu.%lu.ver", APPLICATION_NAME, (k==0)?"":"_", (k==0)?"":channel[k], archname[is_x64()?1:0], os_version.dwMajorVersion, os_version.dwMinorVersion); vuprintf("Base update check: %s\n", urlpath); for (i=0, j=(int)safe_strlen(urlpath)-5; (j>0)&&(i Just craft a default process name that includes the PID if (!bGotExePath) { - safe_sprintf(exe_path, MAX_PATH, "Unknown_Process_%" PRIu64, + static_sprintf(exe_path, "Unknown_Process_%" PRIu64, (ULONGLONG)handleInfo->UniqueProcessId); } } diff --git a/src/registry.h b/src/registry.h index 151ca751..81eb6803 100644 --- a/src/registry.h +++ b/src/registry.h @@ -89,12 +89,12 @@ static __inline BOOL _GetRegistryKey(HKEY key_root, const char* key_name, DWORD if (i + sizeof(software_prefix) >= sizeof(long_key_name)) return FALSE; strcpy(long_key_name, software_prefix); - safe_strcat(long_key_name, sizeof(long_key_name), key_name); + static_strcat(long_key_name, key_name); long_key_name[sizeof(software_prefix) + i - 1] = 0; } else { if (i >= sizeof(long_key_name)) return FALSE; - safe_strcpy(long_key_name, sizeof(long_key_name), key_name); + static_strcpy(long_key_name, key_name); long_key_name[i] = 0; } i++; @@ -164,12 +164,12 @@ static __inline BOOL _SetRegistryKey(HKEY key_root, const char* key_name, DWORD if (i + sizeof(software_prefix) >= sizeof(long_key_name)) goto out; strcpy(long_key_name, software_prefix); - safe_strcat(long_key_name, sizeof(long_key_name), key_name); + static_strcat(long_key_name, key_name); long_key_name[sizeof(software_prefix) + i - 1] = 0; } else { if (i >= sizeof(long_key_name)) goto out; - safe_strcpy(long_key_name, sizeof(long_key_name), key_name); + static_strcpy(long_key_name, key_name); long_key_name[i] = 0; } i++; diff --git a/src/rufus.c b/src/rufus.c index 2a8def1c..3254bf58 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -305,8 +305,8 @@ static BOOL DefineClusterSizes(void) tmp[0] = 0; // Tell the user if we're going to use Large FAT32 or regular if ((fs == FS_FAT32) && ((SelectedDrive.DiskSize > LARGE_FAT32_SIZE) || (force_large_fat32))) - safe_strcat(tmp, sizeof(tmp), "Large "); - safe_strcat(tmp, sizeof(tmp), FileSystemLabel[fs]); + static_strcat(tmp, "Large "); + static_strcat(tmp, FileSystemLabel[fs]); if (default_fs == FS_UNKNOWN) { entry = lmprintf(MSG_030, tmp); default_fs = fs; @@ -456,6 +456,10 @@ static BOOL SetDriveInfo(int ComboIndex) lmprintf(MSG_033, PartitionTypeLabel[pt])), (TT_UEFI<<16)|pt)); } } + if (advanced_mode) { + IGNORE_RETVAL(ComboBox_SetItemData(hPartitionScheme, + ComboBox_AddStringU(hPartitionScheme, "Super Floppy Disk"), PARTITION_STYLE_SFD)); + } // At least one filesystem is go => enable formatting EnableWindow(hStart, TRUE); @@ -578,13 +582,17 @@ static void SetPartitionSchemeTooltip(void) int tt = GETTARGETTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); int pt = GETPARTTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); if (tt == TT_BIOS) { - CreateTooltip(hPartitionScheme, lmprintf(MSG_150), 15000); + if (pt != PARTITION_STYLE_SFD) + CreateTooltip(hPartitionScheme, lmprintf(MSG_150), 15000); + else + DestroyTooltip(hPartitionScheme); } else { - if (pt == PARTITION_STYLE_MBR) { + if (pt == PARTITION_STYLE_MBR) CreateTooltip(hPartitionScheme, lmprintf(MSG_151), 15000); - } else { + else if (pt == PARTITION_STYLE_GPT) CreateTooltip(hPartitionScheme, lmprintf(MSG_152), 15000); - } + else + DestroyTooltip(hPartitionScheme); } } @@ -665,7 +673,7 @@ static BOOL PopulateProperties(int ComboIndex) EnableBootOptions(TRUE, TRUE); // Set a proposed label according to the size (eg: "256MB", "8GB") - safe_sprintf(SelectedDrive.proposed_label, sizeof(SelectedDrive.proposed_label), + static_sprintf(SelectedDrive.proposed_label, SizeToHumanReadable(SelectedDrive.DiskSize, FALSE, use_fake_units)); // Add a tooltip (with the size of the device in parenthesis) @@ -925,8 +933,7 @@ BOOL CALLBACK LogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) static void CALLBACK ClockTimer(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { timer++; - safe_sprintf(szTimer, sizeof(szTimer), "%02d:%02d:%02d", - timer/3600, (timer%3600)/60, timer%60); + static_sprintf(szTimer, "%02d:%02d:%02d", timer/3600, (timer%3600)/60, timer%60); SendMessageA(hStatus, SB_SETTEXTA, SBT_OWNERDRAW | SB_SECTION_RIGHT, (LPARAM)szTimer); } @@ -992,7 +999,10 @@ static void DisplayISOProps(void) PRINT_ISO_PROP(HAS_REACTOS(img_report), " Uses: ReactOS"); PRINT_ISO_PROP(img_report.has_grub4dos, " Uses: Grub4DOS"); PRINT_ISO_PROP(img_report.has_grub2, " Uses: GRUB2"); - PRINT_ISO_PROP(img_report.has_efi, " Uses: EFI %s", HAS_WIN7_EFI(img_report) ? "(win7_x64)" : ""); + if (img_report.has_efi == 0x80) + uprintf(" Uses: EFI (through '%s')", img_report.efi_img_path); + else + PRINT_ISO_PROP(img_report.has_efi, " Uses: EFI %s", HAS_WIN7_EFI(img_report) ? "(win7_x64)" : ""); PRINT_ISO_PROP(HAS_BOOTMGR(img_report), " Uses: Bootmgr"); PRINT_ISO_PROP(HAS_WINPE(img_report), " Uses: WinPE %s", (img_report.uses_minint) ? "(with /minint)" : ""); if (HAS_INSTALL_WIM(img_report)) { @@ -1120,7 +1130,8 @@ static void ToggleAdvanced(BOOL enable) float dialog_shift = -3.22807f*fScale*fScale*fScale + 6.69173f*fScale*fScale + 15.8822f*fScale + 62.9737f; RECT rect; POINT point; - int toggle; + BOOL needs_resel = FALSE; + int i, toggle; if (!enable) dialog_shift = -dialog_shift; @@ -1169,6 +1180,21 @@ static void ToggleAdvanced(BOOL enable) ShowWindow(GetDlgItem(hMainDialog, IDC_DISK_ID), toggle); ShowWindow(GetDlgItem(hMainDialog, IDS_ADVANCED_OPTIONS_GRP), toggle); + if (enable) { + IGNORE_RETVAL(ComboBox_SetItemData(hPartitionScheme, + ComboBox_AddStringU(hPartitionScheme, "Super Floppy Disk"), PARTITION_STYLE_SFD)); + } else { + for (i = 0; i < ComboBox_GetCount(hPartitionScheme); i++) { + if (ComboBox_GetItemData(hPartitionScheme, i) == PARTITION_STYLE_SFD) { + if (ComboBox_GetCurSel(hPartitionScheme) == i) + needs_resel = TRUE; + ComboBox_DeleteString(hPartitionScheme, i); + } + } + if (needs_resel) + SetTargetSystem(); + } + // Toggle the up/down icon SendMessage(GetDlgItem(hMainDialog, IDC_ADVANCED), BCM_SETIMAGELIST, 0, (LPARAM)(enable?&bi_up:&bi_down)); @@ -1399,7 +1425,7 @@ static BOOL BootCheck(void) if ((grub2_len == 0) && (DownloadStatus == 404)) { // Couldn't locate the file on the server => try to download without the version extra uprintf("Extended version was not found, trying main version..."); - safe_strcpy(tmp2, sizeof(tmp2), img_report.grub2_version); + static_strcpy(tmp2, img_report.grub2_version); // Isolate the #.### part for (i = 0; ((tmp2[i] >= '0') && (tmp2[i] <= '9')) || (tmp2[i] == '.'); i++); tmp2[i] = 0; @@ -1749,7 +1775,7 @@ static void InitDialog(HWND hDlg) } else { embedded_sl_version[i] = GetSyslinuxVersion(buf, len, &ext); static_sprintf(embedded_sl_version_str[i], "%d.%02d", SL_MAJOR(embedded_sl_version[i]), SL_MINOR(embedded_sl_version[i])); - safe_strcpy(embedded_sl_version_ext[i], sizeof(embedded_sl_version_ext[i]), ext); + static_strcpy(embedded_sl_version_ext[i], ext); free(buf); } } @@ -1969,7 +1995,7 @@ static void ShowLanguageMenu(RECT rcExclude) static_sprintf(lang, LEFT_TO_RIGHT_EMBEDDING "(%s) " POP_DIRECTIONAL_FORMATTING "%s", r, l); safe_free(str); } else { - safe_strcpy(lang, sizeof(lang), lcmd->txt[1]); + static_strcpy(lang, lcmd->txt[1]); } InsertMenuU(menu, -1, MF_BYPOSITION|((selected_locale == lcmd)?MF_CHECKED:0), UM_LANGUAGE_MENU_MAX++, lang); } @@ -1984,7 +2010,7 @@ static void ShowLanguageMenu(RECT rcExclude) DestroyMenu(menu); } -static void SetBoot(int fs, int tt) +static void SetBoot(int fs, int tt, int pt) { int i; char tmp[32]; @@ -2024,7 +2050,7 @@ static void SetBoot(int fs, int tt) if (i == ComboBox_GetCount(hBootType)) IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, 0)); - if (!IsWindowEnabled(hBoot)) { + if ((pt != PARTITION_STYLE_SFD) && !IsWindowEnabled(hBoot)) { EnableWindow(hBoot, TRUE); EnableWindow(hBootType, TRUE); EnableWindow(hSelectISO, TRUE); @@ -2044,7 +2070,7 @@ static void SaveVHD(void) ULARGE_INTEGER free_space; if (DriveIndex >= 0) - safe_sprintf(filename, sizeof(filename), "%s.vhd", DriveLabel.String[DriveIndex]); + static_sprintf(filename, "%s.vhd", DriveLabel.String[DriveIndex]); if ((DriveIndex != CB_ERR) && (!format_op_in_progress) && (format_thid == NULL)) { img_save.Type = IMG_SAVE_TYPE_VHD; img_save.DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, DriveIndex); @@ -2072,7 +2098,7 @@ static void SaveVHD(void) uprintf("\r\nSave to VHD operation started"); PrintInfo(0, -1); timer = 0; - safe_sprintf(szTimer, sizeof(szTimer), "00:00:00"); + static_sprintf(szTimer, "00:00:00"); SendMessageA(hStatus, SB_SETTEXTA, SBT_OWNERDRAW | SB_SECTION_RIGHT, (LPARAM)szTimer); SetTimer(hMainDialog, TID_APP_TIMER, 1000, ClockTimer); } else { @@ -2117,7 +2143,7 @@ static void SaveISO(void) (img_save.BufSize > 8 * MB) && (img_save.DeviceSize <= img_save.BufSize * 64); img_save.BufSize /= 2); if ((img_save.Label != NULL) && (img_save.Label[0] != 0)) - safe_sprintf(filename, sizeof(filename), "%s.iso", img_save.Label); + static_sprintf(filename, "%s.iso", img_save.Label); uprintf("ISO media size %s", SizeToHumanReadable(img_save.DeviceSize, FALSE, FALSE)); img_save.ImagePath = FileDialog(TRUE, NULL, &img_ext, 0); @@ -2138,7 +2164,7 @@ static void SaveISO(void) uprintf("\r\nSave to ISO operation started"); PrintInfo(0, -1); timer = 0; - safe_sprintf(szTimer, sizeof(szTimer), "00:00:00"); + static_sprintf(szTimer, "00:00:00"); SendMessageA(hStatus, SB_SETTEXTA, SBT_OWNERDRAW | SB_SECTION_RIGHT, (LPARAM)szTimer); SetTimer(hMainDialog, TID_APP_TIMER, 1000, ClockTimer); } else { @@ -2259,7 +2285,9 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA case WM_COMMAND: #ifdef RUFUS_TEST if (LOWORD(wParam) == IDC_TEST) { - uprintf("Proceed = %s", CheckDriveAccess(2000)?"True":"False"); + ExtractEfiImgFiles("C:\\rufus"); +// ExtractEFI("C:\\rufus\\efi.img", "C:\\rufus\\efi"); +// uprintf("Proceed = %s", CheckDriveAccess(2000)?"True":"False"); // char* choices[] = { "Choice 1", "Choice 2", "Choice 3" }; // SelectionDyn("Test Choice", "Unused", choices, ARRAYSIZE(choices)); break; @@ -2407,10 +2435,11 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA break; fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); tt = GETTARGETTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); + pt = GETPARTTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); if ((selection_default == BT_IMG) && IsChecked(IDC_BOOT)) { ToggleImage(FALSE); EnableAdvancedBootOptions(FALSE, TRUE); - SetBoot(fs, tt); + SetBoot(fs, tt, pt); SetToGo(); break; } @@ -2439,7 +2468,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA } break; } - if ((fs == FS_EXFAT) || (fs == FS_UDF) || (fs == FS_REFS)) { + if ((fs == FS_EXFAT) || (fs == FS_UDF) || (fs == FS_REFS) || (pt == PARTITION_STYLE_SFD)) { if (IsWindowEnabled(hBoot)) { // unlikely to be supported by BIOSes => don't bother IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, 0)); @@ -2454,7 +2483,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA break; } EnableAdvancedBootOptions(TRUE, TRUE); - SetBoot(fs, tt); + SetBoot(fs, tt, pt); SetMBRProps(); SetToGo(); break; @@ -2607,7 +2636,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA uprintf("\r\nFormat operation started"); PrintInfo(0, -1); timer = 0; - safe_sprintf(szTimer, sizeof(szTimer), "00:00:00"); + static_sprintf(szTimer, "00:00:00"); SendMessageA(hStatus, SB_SETTEXTA, SBT_OWNERDRAW | SB_SECTION_RIGHT, (LPARAM)szTimer); SetTimer(hMainDialog, TID_APP_TIMER, 1000, ClockTimer); } @@ -2640,7 +2669,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA if (format_thid != NULL) { PrintInfo(0, -1); timer = 0; - safe_sprintf(szTimer, sizeof(szTimer), "00:00:00"); + static_sprintf(szTimer, "00:00:00"); SendMessageA(hStatus, SB_SETTEXTA, SBT_OWNERDRAW | SB_SECTION_RIGHT, (LPARAM)szTimer); SetTimer(hMainDialog, TID_APP_TIMER, 1000, ClockTimer); } else { @@ -3111,24 +3140,24 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine } if (GetSystemDirectoryU(system_dir, sizeof(system_dir)) == 0) { uprintf("Could not get system directory: %s", WindowsErrorString()); - safe_strcpy(system_dir, sizeof(system_dir), "C:\\Windows\\System32"); + static_strcpy(system_dir, "C:\\Windows\\System32"); } if (GetTempPathU(sizeof(temp_dir), temp_dir) == 0) { uprintf("Could not get temp directory: %s", WindowsErrorString()); - safe_strcpy(temp_dir, sizeof(temp_dir), ".\\"); + static_strcpy(temp_dir, ".\\"); } // Construct Sysnative ourselves as there is no GetSysnativeDirectory() call // By default (64bit app running on 64 bit OS or 32 bit app running on 32 bit OS) // Sysnative and System32 are the same - safe_strcpy(sysnative_dir, sizeof(sysnative_dir), system_dir); + static_strcpy(sysnative_dir, system_dir); // But if the app is 32 bit and the OS is 64 bit, Sysnative must differ from System32 #if (!defined(_WIN64) && !defined(BUILD64)) if (is_x64()) { if (GetSystemWindowsDirectoryU(sysnative_dir, sizeof(sysnative_dir)) == 0) { uprintf("Could not get Windows directory: %s", WindowsErrorString()); - safe_strcpy(sysnative_dir, sizeof(sysnative_dir), "C:\\Windows"); + static_strcpy(sysnative_dir, "C:\\Windows"); } - safe_strcat(sysnative_dir, sizeof(sysnative_dir), "\\Sysnative"); + static_strcat(sysnative_dir, "\\Sysnative"); } #endif @@ -3176,7 +3205,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine loc_data = (BYTE*)GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_LC_RUFUS_LOC), _RT_RCDATA, "embedded.loc", &loc_size, FALSE); if ( (GetTempFileNameU(temp_dir, APPLICATION_NAME, 0, loc_file) == 0) || (loc_file[0] == 0) ) { // Last ditch effort to get a loc file - just extract it to the current directory - safe_strcpy(loc_file, sizeof(loc_file), rufus_loc); + static_strcpy(loc_file, rufus_loc); } hFile = CreateFileU(loc_file, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, @@ -3189,7 +3218,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine uprintf("localization: extracted data to '%s'", loc_file); safe_closehandle(hFile); } else { - safe_sprintf(loc_file, sizeof(loc_file), "%s\\%s", app_dir, rufus_loc); + static_sprintf(loc_file, "%s\\%s", app_dir, rufus_loc); external_loc_file = TRUE; uprintf("using external loc file '%s'", loc_file); } diff --git a/src/rufus.h b/src/rufus.h index 70094dac..2edfb86d 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -73,9 +73,9 @@ #define DD_BUFFER_SIZE 65536 // Minimum size of the buffer we use for DD operations #define UBUFFER_SIZE 2048 #define RUFUS_URL "https://rufus.akeo.ie" -#define UPDATE_URL "http://rufus.akeo.ie" // Stupid XP can't handle a recent SSL implementation... -#define DOWNLOAD_URL RUFUS_URL "/downloads" -#define FILES_URL RUFUS_URL "/files" +#define RUFUS_NO_SSL_URL "http://rufus.akeo.ie" // Stupid XP can't handle a recent SSL implementation... +#define DOWNLOAD_URL RUFUS_NO_SSL_URL "/downloads" +#define FILES_URL RUFUS_NO_SSL_URL "/files" #define SEVENZIP_URL "http://www.7-zip.org" #define FILES_DIR "rufus_files" #define IGNORE_RETVAL(expr) do { (void)(expr); } while(0) @@ -95,8 +95,10 @@ #define safe_strcp(dst, dst_max, src, count) do {memcpy(dst, src, safe_min(count, dst_max)); \ ((char*)dst)[safe_min(count, dst_max)-1] = 0;} while(0) #define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src)+1) +#define static_strcpy(dst, src) safe_strcpy(dst, sizeof(dst), src) #define safe_strncat(dst, dst_max, src, count) strncat(dst, src, safe_min(count, dst_max - safe_strlen(dst) - 1)) #define safe_strcat(dst, dst_max, src) safe_strncat(dst, dst_max, src, safe_strlen(src)+1) +#define static_strcat(dst, src) safe_strcat(dst, sizeof(dst), src) #define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"":str1), ((str2==NULL)?"":str2)) #define safe_strstr(str1, str2) strstr(((str1==NULL)?"":str1), ((str2==NULL)?"":str2)) #define safe_stricmp(str1, str2) _stricmp(((str1==NULL)?"":str1), ((str2==NULL)?"":str2)) @@ -233,6 +235,7 @@ enum target_type { TT_MAX }; // For the partition types we'll use Microsoft's PARTITION_STYLE_### constants +#define PARTITION_STYLE_SFD PARTITION_STYLE_RAW #define GETTARGETTYPE(x) (((x)>0)?(((x) >> 16) & 0xFFFF):0) #define GETPARTTYPE(x) (((x)>0)?((x) & 0xFFFF):0); @@ -261,8 +264,9 @@ enum checksum_type { #define HAS_WINPE(r) (((r.winpe & WINPE_MININT) == WINPE_MININT)||((r.winpe & WINPE_I386) == WINPE_I386)) #define HAS_WINDOWS(r) (HAS_BOOTMGR(r) || (r.uses_minint) || HAS_WINPE(r)) #define HAS_WIN7_EFI(r) ((r.has_efi == 1) && HAS_INSTALL_WIM(r)) +#define HAS_EFI_IMG(r) (r.efi_img_path[0] != 0) #define IS_DD_BOOTABLE(r) (r.is_bootable_img) -#define IS_EFI_BOOTABLE(r) (r.has_efi) +#define IS_EFI_BOOTABLE(r) (r.has_efi != 0) #define IS_BIOS_BOOTABLE(r) (HAS_BOOTMGR(r) || HAS_SYSLINUX(r) || HAS_WINPE(r) || HAS_GRUB(r) || HAS_REACTOS(r) || HAS_KOLIBRIOS(r)) #define HAS_WINTOGO(r) (HAS_BOOTMGR(r) && IS_EFI_BOOTABLE(r) && HAS_INSTALL_WIM(r) && (r.install_wim_version < MAX_WIM_VERSION)) #define IS_FAT(fs) ((fs == FS_FAT16) || (fs == FS_FAT32)) @@ -273,6 +277,7 @@ typedef struct { char cfg_path[128]; /* path to the ISO's isolinux.cfg */ char reactos_path[128]; /* path to the ISO's freeldr.sys or setupldr.sys */ char install_wim_path[64]; /* path to install.wim or install.swm */ + char efi_img_path[128]; /* path to an efi.img file */ uint64_t image_size; uint64_t projected_size; int64_t mismatch_size; @@ -440,6 +445,7 @@ extern SIZE GetTextSize(HWND hCtrl); extern BOOL ExtractDOS(const char* path); extern BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan); extern int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file, DWORD attributes); +extern BOOL ExtractEfiImgFiles(const char* dir); extern char* MountISO(const char* path); extern void UnMountISO(void); extern BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int fs); diff --git a/src/rufus.rc b/src/rufus.rc index ee67705f..d42dfb35 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 2.16.1171" +CAPTION "Rufus 2.17.1182" FONT 8, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -366,8 +366,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,16,1171,0 - PRODUCTVERSION 2,16,1171,0 + FILEVERSION 2,17,1182,0 + PRODUCTVERSION 2,17,1182,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -384,13 +384,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "2.16.1171" + VALUE "FileVersion", "2.17.1182" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", " 2011-2017 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "2.16.1171" + VALUE "ProductVersion", "2.17.1182" END END BLOCK "VarFileInfo" diff --git a/src/settings.h b/src/settings.h index 9b2a57c5..39364c87 100644 --- a/src/settings.h +++ b/src/settings.h @@ -94,7 +94,7 @@ static __inline char* ReadIniKeyStr(const char* key) { str[0] = 0; val = get_token_data_file(key, ini_file); if (val != NULL) { - safe_strcpy(str, sizeof(str), val); + static_strcpy(str, val); free(val); } return str; diff --git a/src/smart.c b/src/smart.c index 72b60149..7b32e328 100644 --- a/src/smart.c +++ b/src/smart.c @@ -68,7 +68,7 @@ const char* SptStrerr(int errcode) static char scsi_err[64]; if ((errcode > 0) && (errcode <= 0xff)) { - safe_sprintf(scsi_err, sizeof(scsi_err), "SCSI status: 0x%02X", (uint8_t)errcode); + static_sprintf(scsi_err, "SCSI status: 0x%02X", (uint8_t)errcode); return (const char*)scsi_err; } diff --git a/src/stdfn.c b/src/stdfn.c index 1874574a..90ef4b8c 100644 --- a/src/stdfn.c +++ b/src/stdfn.c @@ -235,7 +235,7 @@ void GetWindowsVersion(void) BOOL ws; nWindowsVersion = WINDOWS_UNDEFINED; - safe_strcpy(WindowsVersionStr, sizeof(WindowsVersionStr), "Windows Undefined"); + static_strcpy(WindowsVersionStr, "Windows Undefined"); memset(&vi, 0, sizeof(vi)); vi.dwOSVersionInfoSize = sizeof(vi); @@ -329,9 +329,9 @@ void GetWindowsVersion(void) GetRegistryKeyStr(REGKEY_HKLM, "Microsoft\\Windows NT\\CurrentVersion\\CurrentBuildNumber", build_number, sizeof(build_number)); if (build_number[0] != 0) { nWindowsBuildNumber = atoi(build_number); // Keep a global copy - safe_strcat(WindowsVersionStr, sizeof(WindowsVersionStr), " (Build "); - safe_strcat(WindowsVersionStr, sizeof(WindowsVersionStr), build_number); - safe_strcat(WindowsVersionStr, sizeof(WindowsVersionStr), ")"); + static_strcat(WindowsVersionStr, " (Build "); + static_strcat(WindowsVersionStr, build_number); + static_strcat(WindowsVersionStr, ")"); } } @@ -905,7 +905,7 @@ char* GetCurrentMUI(void) (pfLCIDToLocaleName(GetUserDefaultUILanguage(), wmui_str, LOCALE_NAME_MAX_LENGTH, 0) > 0) ) { wchar_to_utf8_no_alloc(wmui_str, mui_str, LOCALE_NAME_MAX_LENGTH); } else { - safe_strcpy(mui_str, LOCALE_NAME_MAX_LENGTH, "en-US"); + static_strcpy(mui_str, "en-US"); } return mui_str; } diff --git a/src/stdio.c b/src/stdio.c index c3975f36..c5b0707f 100644 --- a/src/stdio.c +++ b/src/stdio.c @@ -73,7 +73,7 @@ void _uprintf(const char *format, ...) Edit_ReplaceSel(hLog, wbuf); // Make sure the message scrolls into view // (Or see code commented in LogProc:WM_SHOWWINDOW for a less forceful scroll) - Edit_Scroll(hLog, 0, Edit_GetLineCount(hLog)); + Edit_Scroll(hLog, Edit_GetLineCount(hLog), 0); } free(wbuf); } @@ -151,7 +151,7 @@ static char err_string[256] = {0}; error_code = GetLastError(); - safe_sprintf(err_string, sizeof(err_string), "[0x%08lX] ", error_code); + static_sprintf(err_string, "[0x%08lX] ", error_code); size = FormatMessageU(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, HRESULT_CODE(error_code), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[strlen(err_string)], @@ -159,10 +159,10 @@ static char err_string[256] = {0}; if (size == 0) { format_error = GetLastError(); if ((format_error) && (format_error != 0x13D)) // 0x13D, decode error, is returned for unknown codes - safe_sprintf(err_string, sizeof(err_string), - "Windows error code 0x%08lX (FormatMessage error code 0x%08lX)", error_code, format_error); + static_sprintf(err_string, "Windows error code 0x%08lX (FormatMessage error code 0x%08lX)", + error_code, format_error); else - safe_sprintf(err_string, sizeof(err_string), "Unknown error 0x%08lX", error_code); + static_sprintf(err_string, "Unknown error 0x%08lX", error_code); } SetLastError(error_code); // Make sure we don't change the errorcode on exit diff --git a/src/stdlg.c b/src/stdlg.c index d2524bbc..29eccaef 100644 --- a/src/stdlg.c +++ b/src/stdlg.c @@ -202,7 +202,7 @@ void BrowseForFolder(void) { if (tmp_path == NULL) { uprintf("Could not convert path\n"); } else { - safe_strcpy(szFolderPath, MAX_PATH, tmp_path); + static_strcpy(szFolderPath, tmp_path); safe_free(tmp_path); } } else { @@ -630,7 +630,7 @@ INT_PTR CALLBACK AboutCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP CenterDialog(hDlg); if (settings_commcheck) ShowWindow(GetDlgItem(hDlg, IDC_ABOUT_UPDATES), SW_SHOW); - safe_sprintf(about_blurb, sizeof(about_blurb), about_blurb_format, lmprintf(MSG_174|MSG_RTF), + static_sprintf(about_blurb, about_blurb_format, lmprintf(MSG_174|MSG_RTF), lmprintf(MSG_175|MSG_RTF, rufus_version[0], rufus_version[1], rufus_version[2]), right_to_left_mode?"Akeo \\\\ Pete Batard 2011-2017 © Copyright":"Copyright © 2011-2017 Pete Batard / Akeo", lmprintf(MSG_176|MSG_RTF), lmprintf(MSG_177|MSG_RTF), lmprintf(MSG_178|MSG_RTF)); @@ -1459,7 +1459,7 @@ INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM l IGNORE_RETVAL(ComboBox_SetCurSel(hBeta, ReadSettingBool(SETTING_INCLUDE_BETAS)?0:1)); hPolicy = GetDlgItem(hDlg, IDC_POLICY); SendMessage(hPolicy, EM_AUTOURLDETECT, 1, 0); - safe_sprintf(update_policy_text, sizeof(update_policy_text), update_policy, lmprintf(MSG_179|MSG_RTF), + static_sprintf(update_policy_text, update_policy, lmprintf(MSG_179|MSG_RTF), lmprintf(MSG_180|MSG_RTF), lmprintf(MSG_181|MSG_RTF), lmprintf(MSG_182|MSG_RTF), lmprintf(MSG_183|MSG_RTF), lmprintf(MSG_184|MSG_RTF), lmprintf(MSG_185|MSG_RTF), lmprintf(MSG_186|MSG_RTF)); SendMessageA(hPolicy, EM_SETTEXTEX, (WPARAM)&friggin_microsoft_unicode_amateurs, (LPARAM)update_policy_text); diff --git a/src/vhd.c b/src/vhd.c index c1972989..31042602 100644 --- a/src/vhd.c +++ b/src/vhd.c @@ -110,7 +110,7 @@ static BOOL Get7ZipPath(void) { if ( (GetRegistryKeyStr(REGKEY_HKCU, "7-Zip\\Path", sevenzip_path, sizeof(sevenzip_path))) || (GetRegistryKeyStr(REGKEY_HKLM, "7-Zip\\Path", sevenzip_path, sizeof(sevenzip_path))) ) { - safe_strcat(sevenzip_path, sizeof(sevenzip_path), "\\7z.exe"); + static_strcat(sevenzip_path, "\\7z.exe"); return (_access(sevenzip_path, 0) != -1); } return FALSE; @@ -471,11 +471,11 @@ BOOL WimExtractFile_7z(const char* image, int index, const char* src, const char // return an error code if it can't extract the file), we need // to issue 2 passes. See github issue #680. for (n = 0; n < 2; n++) { - safe_strcpy(tmpdst, sizeof(tmpdst), dst); + static_strcpy(tmpdst, dst); for (i = strlen(tmpdst) - 1; (i > 0) && (tmpdst[i] != '\\') && (tmpdst[i] != '/'); i--); tmpdst[i] = 0; - safe_sprintf(cmdline, sizeof(cmdline), "\"%s\" -y e \"%s\" %s%s", sevenzip_path, + static_sprintf(cmdline, "\"%s\" -y e \"%s\" %s%s", sevenzip_path, image, (n == 0) ? index_prefix : "", src); if (RunCommand(cmdline, tmpdst, FALSE) != 0) { uprintf(" Could not launch 7z.exe: %s", WindowsErrorString()); @@ -484,8 +484,8 @@ BOOL WimExtractFile_7z(const char* image, int index, const char* src, const char for (i = safe_strlen(src); (i > 0) && (src[i] != '\\') && (src[i] != '/'); i--); if (i == 0) - safe_strcat(tmpdst, sizeof(tmpdst), "\\"); - safe_strcat(tmpdst, sizeof(tmpdst), &src[i]); + static_strcat(tmpdst, "\\"); + static_strcat(tmpdst, &src[i]); if (_access(tmpdst, 0) == 0) // File was extracted => move on break;