diff --git a/src/drive.c b/src/drive.c index d14e5cfa..76de027d 100644 --- a/src/drive.c +++ b/src/drive.c @@ -45,6 +45,10 @@ const GUID PARTITION_BASIC_DATA_GUID = const GUID PARTITION_MSFT_RESERVED_GUID = { 0xe3c9e316L, 0x0b5c, 0x4db8, {0x81, 0x7d, 0xf9, 0x2d, 0xf0, 0x02, 0x15, 0xae} }; #endif +#if !defined(PARTITION_SYSTEM_GUID) +const GUID PARTITION_SYSTEM_GUID = + { 0xc12a7328L, 0xf81f, 0x11d2, {0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b} }; +#endif /* * Globals @@ -102,7 +106,7 @@ BOOL GetAutoMount(BOOL* enabled) */ #define CheckDriveIndex(DriveIndex) do { \ if ((DriveIndex < DRIVE_INDEX_MIN) || (DriveIndex > DRIVE_INDEX_MAX)) { \ - uprintf("WARNING: Bad index value. Please check the code!\n"); \ + uprintf("ERROR: Bad index value. Please check the code!\n"); \ goto out; \ } \ DriveIndex -= DRIVE_INDEX_MIN; } while (0) @@ -403,7 +407,7 @@ static BOOL _GetDriveLettersAndType(DWORD DriveIndex, char* drive_letters, UINT* hDrive = CreateFileA(logical_drive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hDrive == INVALID_HANDLE_VALUE) { - uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString()); +// uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString()); continue; } @@ -684,7 +688,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys return 0; } if (DiskGeometry->Geometry.BytesPerSector < 512) { - suprintf("WARNING: Drive 0x%02x reports a sector size of %d - Correcting to 512 bytes.\n", + suprintf("Warning: Drive 0x%02x reports a sector size of %d - Correcting to 512 bytes.\n", DriveIndex, DiskGeometry->Geometry.BytesPerSector); DiskGeometry->Geometry.BytesPerSector = 512; } @@ -863,6 +867,102 @@ BOOL MountVolume(char* drive_name, char *drive_guid) return TRUE; } +/* + * Mount partition #part_nr, residing on the same disk as drive_name to an available + * drive letter. Returns the newly allocated drive string. + * We need to do this because, for instance, EFI System partitions are not assigned + * Volume GUIDs by the OS, and we need to have a letter assigned, for when we invoke + * bcdtool for Windows To Go. All in all, the process looks like this: + * 1. F: = \Device\HarddiskVolume9 (SINGLE LOOKUP) + * 2. Harddisk5Partition1 = \Device\HarddiskVolume9 (FULL LOOKUP) + * 3. Harddisk5Partition2 = \Device\HarddiskVolume10 (SINGLE LOOKUP) + * 4. DefineDosDevice(letter, \Device\HarddiskVolume10) + */ +char* AltMountVolume(const char* drive_name, uint8_t part_nr) +{ + static char mounted_drive[] = "?:"; + const size_t bufsize = 65536; + char *buffer = NULL, *p, target[2][MAX_PATH], *ret = NULL; + int i; + + mounted_drive[0] = GetUnusedDriveLetter(); + if (mounted_drive[0] == 0) { + uprintf("Could not find an unused drive letter"); + goto out; + } + + target[0][0] = 0; + // Convert our drive letter to something like "\Device\HarddiskVolume9" + if (!QueryDosDeviceA(drive_name, target[0], MAX_PATH) && (strlen(target[0]) == 0)) { + uprintf("Could not get the DOS device name for '%s': %s", drive_name, WindowsErrorString()); + goto out; + } + + // Now parse the whole DOS device list to find the 'Harddisk#Partition#' that matches the above + // TODO: realloc if someone ever manages to burst through 64K of DOS devices + buffer = malloc(bufsize); + if (buffer == NULL) + goto out; + + buffer[0] = 0; + if (!QueryDosDeviceA(NULL, buffer, bufsize)) { + uprintf("Could not get the DOS device list: %s", WindowsErrorString()); + goto out; + } + + p = buffer; + while (strlen(p) != 0) { + if ((strncmp("Harddisk", p, 8) == 0) && (strstr(&p[9], "Partition") != NULL)) { + target[1][0] = 0; + if (QueryDosDeviceA(p, target[1], MAX_PATH) && (strlen(target[1]) != 0)) + if ((strcmp(target[1], target[0]) == 0) && (p[1] != ':')) + break; + } + p += strlen(p) + 1; + } + + i = strlen(p); + if (i == 0) { + uprintf("Could not find partition mapping for %s", target[0]); + goto out; + } + + while ((--i > 0) && (isdigit(p[i]))); + p[++i] = '0' + part_nr; + p[++i] = 0; + + target[0][0] = 0; + if (!QueryDosDeviceA(p, target[0], MAX_PATH) && (strlen(target[0]) == 0)) { + uprintf("Could not get DOS device name for partition '%s': %s", drive_name, WindowsErrorString()); + goto out; + } + + if (!DefineDosDeviceA(DDD_RAW_TARGET_PATH | DDD_NO_BROADCAST_SYSTEM, mounted_drive, target[0])) { + uprintf("Could not mount '%s' to '%s': %s", target[0], mounted_drive, WindowsErrorString()); + goto out; + } + + uprintf("Successfully mounted '%s' (USB partition %d) as '%s'", target[0], part_nr, mounted_drive); + ret = mounted_drive; + +out: + safe_free(buffer); + return ret; +} + +/* + * Unmount a volume that was mounted by AltmountVolume() + */ +BOOL AltUnmountVolume(const char* drive_name) +{ + if (!DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_NO_BROADCAST_SYSTEM, drive_name, NULL)) { + uprintf("Could not unmount '%s': %s", drive_name, WindowsErrorString()); + return FALSE; + } + uprintf("Successfully unmounted '%s'", drive_name); + return TRUE; +} + /* * Issue a complete remount of the volume */ @@ -909,7 +1009,7 @@ typedef struct _DRIVE_LAYOUT_INFORMATION_EX4 { * copy it got from the last IOCTL, and ignores your changes until you replug the drive * or issue an IOCTL_DISK_UPDATE_PROPERTIES. */ -BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, BOOL add_uefi_togo) +BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, uint8_t extra_partitions) { const char* PartitionTypeName[2] = { "MBR", "GPT" }; unsigned char* buffer; @@ -917,12 +1017,11 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = {0}; BOOL r; DWORD i, size, bufsize, pn = 0; - LONGLONG size_in_sectors, extra_part_size_in_tracks = 0; - BOOL add_msr = FALSE; //TRUE; + LONGLONG main_part_size_in_sectors, extra_part_size_in_tracks = 0; PrintInfoDebug(0, MSG_238, PartitionTypeName[partition_style]); - if (uefi_togo_size == 0) + if ((extra_partitions & XP_UEFI_TOGO) && (uefi_togo_size == 0)) uefi_togo_size = GetResourceSize(hMainInstance, MAKEINTRESOURCEA(IDR_UEFI_TOGO), _RT_RCDATA, "uefi-togo.img"); // Compute the start offset of our first partition @@ -936,7 +1035,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m } // If required, set the MSR partition (GPT only - must be created before the data part) - if ((partition_style == PARTITION_STYLE_GPT) && (add_msr)) { + if ((partition_style == PARTITION_STYLE_GPT) && (extra_partitions & XP_MSR)) { uprintf("Adding MSR partition"); DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = 128*1024*1024; DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_MSFT_RESERVED_GUID; @@ -948,24 +1047,27 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m } // Set our main data partition - size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart) / + main_part_size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart) / // Need 33 sectors at the end for secondary GPT SelectedDrive.Geometry.BytesPerSector - ((partition_style == PARTITION_STYLE_GPT)?33:0); // Adjust the size according to extra partitions - if ((add_uefi_togo) || ((partition_style == PARTITION_STYLE_MBR) && (IsChecked(IDC_EXTRA_PARTITION)))) { - if (add_uefi_togo) { - extra_part_size_in_tracks = (MIN_EXTRA_PART_SIZE + SelectedDrive.Geometry.SectorsPerTrack - 1) / - SelectedDrive.Geometry.SectorsPerTrack; + if (extra_partitions) { + if (extra_partitions & (XP_UEFI_TOGO | XP_EFI)) { + // TODO: this will explode to 800MB instead of 100MB on 4K sectors... + extra_part_size_in_tracks = ((MIN_EXTRA_PART_SIZE*((extra_partitions & XP_EFI)?100:1)) + + SelectedDrive.Geometry.SectorsPerTrack - 1) / SelectedDrive.Geometry.SectorsPerTrack; } else { - extra_part_size_in_tracks = 1; // One track for the extra part in non togo mode + extra_part_size_in_tracks = 1; // One track for the extra partition } - uprintf("Reserving %d tracks for extra partition", extra_part_size_in_tracks); - size_in_sectors = ((size_in_sectors / SelectedDrive.Geometry.SectorsPerTrack) - extra_part_size_in_tracks) * - SelectedDrive.Geometry.SectorsPerTrack; - if (size_in_sectors <= 0) + uprintf("Reserving %lld tracks (%s) for extra partition", extra_part_size_in_tracks, + SizeToHumanReadable(extra_part_size_in_tracks * SelectedDrive.Geometry.SectorsPerTrack * + SelectedDrive.Geometry.BytesPerSector, TRUE, FALSE)); + main_part_size_in_sectors = ((main_part_size_in_sectors / SelectedDrive.Geometry.SectorsPerTrack) - + extra_part_size_in_tracks) * SelectedDrive.Geometry.SectorsPerTrack; + if (main_part_size_in_sectors <= 0) return FALSE; } - DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = size_in_sectors * SelectedDrive.Geometry.BytesPerSector; + DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = main_part_size_in_sectors * SelectedDrive.Geometry.BytesPerSector; if (partition_style == PARTITION_STYLE_MBR) { DriveLayoutEx.PartitionEntry[pn].Mbr.BootIndicator = IsChecked(IDC_BOOT); DriveLayoutEx.PartitionEntry[pn].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack; @@ -994,24 +1096,23 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m pn++; // Set the optional extra partition - if (IsChecked(IDC_EXTRA_PARTITION) || (add_uefi_togo)) { + if (extra_partitions) { // Should end on a track boundary DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn-1].StartingOffset.QuadPart + - DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart; - DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = (add_uefi_togo)?uefi_togo_size: + DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart; + DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = (extra_partitions & XP_UEFI_TOGO)?uefi_togo_size: extra_part_size_in_tracks * SelectedDrive.Geometry.SectorsPerTrack * SelectedDrive.Geometry.BytesPerSector; if (partition_style == PARTITION_STYLE_GPT) { - if (add_uefi_togo) // already set to UNUSED GUID (000...000) otherwise - DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_BASIC_DATA_GUID; + DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_SYSTEM_GUID; IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId)); - wcscpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, (add_uefi_togo)?L"UEFI:TOGO":L"Rufus Extra Partition"); + wcscpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, (extra_partitions & XP_UEFI_TOGO)?L"UEFI:TOGO":L"EFI system partition"); } else { - DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = (add_uefi_togo)?0x01:RUFUS_EXTRA_PARTITION_TYPE; + DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = (extra_partitions & XP_UEFI_TOGO)?0x01:RUFUS_EXTRA_PARTITION_TYPE; DriveLayoutEx.PartitionEntry[pn].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack; } // We need to write the TOGO partition before we refresh the disk - if (add_uefi_togo) { + if (extra_partitions & XP_UEFI_TOGO) { uprintf("Writing UEFI:TOGO partition..."); if (!SetFilePointerEx(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, NULL, FILE_BEGIN)) { uprintf("Unable to set position"); diff --git a/src/drive.h b/src/drive.h index 619d2565..133b54bd 100644 --- a/src/drive.h +++ b/src/drive.h @@ -30,6 +30,10 @@ #define IOCTL_MOUNTMGR_SET_AUTO_MOUNT \ CTL_CODE(MOUNTMGRCONTROLTYPE, 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define XP_MSR 0x01 +#define XP_EFI 0x02 +#define XP_UEFI_TOGO 0x04 + /* We need a redef of these MS structure */ typedef struct { DWORD DeviceType; @@ -62,8 +66,10 @@ BOOL AnalyzePBR(HANDLE hLogicalVolume); BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSystemNameSize, BOOL bSilent); BOOL UnmountVolume(HANDLE hDrive); BOOL MountVolume(char* drive_name, char *drive_guid); +BOOL AltUnmountVolume(const char* drive_name); +char* AltMountVolume(const char* drive_name, uint8_t part_nr); BOOL RemountVolume(char* drive_name); -BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, BOOL add_uefi_togo); +BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, uint8_t extra_partitions); BOOL DeletePartitions(HANDLE hDrive); BOOL RefreshDriveLayout(HANDLE hDrive); const char* GetPartitionType(BYTE Type); diff --git a/src/format.c b/src/format.c index ecf348bb..e2fa0eca 100644 --- a/src/format.c +++ b/src/format.c @@ -1226,15 +1226,24 @@ out: } // http://technet.microsoft.com/en-ie/library/jj721578.aspx -static BOOL SetupWinToGo(const char* drive_name) +BOOL SetupWinToGo(const char* drive_name, BOOL use_ms_efi) { char san_policy_path[] = "?:\\san_policy.xml", unattend_path[] = "?:\\Windows\\System32\\sysprep\\unattend.xml"; - char *mounted_iso, image[128], cmd[128]; + char *mounted_iso, *ms_efi, image[128], cmd[128]; + wchar_t wVolumeName[] = L"?:"; unsigned char *buffer; DWORD bufsize; FILE* fd; + PF_DECL(FormatEx); + PF_INIT(FormatEx, Fmifs); uprintf("Windows To Go mode selected"); + if ((use_ms_efi) && (SelectedDrive.Geometry.MediaType != FixedMedia)) { + // Arthur's Theme: "♫ I know it's stupid... but it's true. ♫" + uprintf("Cannot set 'Windows To Go' for a GPT target unless it is a fixed drive"); + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED; + return FALSE; + } // First, we need to access the install.wim image, that resides on the ISO mounted_iso = MountISO(image_path); @@ -1256,15 +1265,46 @@ static BOOL SetupWinToGo(const char* drive_name) } UnMountISO(); - uprintf("Setting up boot for Windows To Go..."); - static_sprintf(cmd, "%C:\\Windows\\System32\\bcdboot.exe %C:\\Windows /f ALL /s %C:", - drive_name[0], drive_name[0], drive_name[0]); + if (use_ms_efi) { + uprintf("Setting up MS EFI system partition"); + if (pfFormatEx == NULL) + return FALSE; + ms_efi = AltMountVolume(drive_name, 3); // MSR, main, EFI + if (ms_efi == NULL) { + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_ASSIGN_LETTER); + return FALSE; + } + fs_index = 0; + task_number = 0; + wVolumeName[0] = ms_efi[0]; + // Boy do you *NOT* want to specify a label here, and spend + // HOURS figuring out why your EFI partition cannot boot... + pfFormatEx(wVolumeName, SelectedDrive.Geometry.MediaType, L"FAT32", L"", + TRUE, 1024, FormatExCallback); + if (IS_ERROR(FormatStatus)) { + uprintf("Failed to format EFI partition"); + AltUnmountVolume(ms_efi); + return FALSE; + } + } + + // TODO: Don't use ALL but adjust to what we effectively support + static_sprintf(cmd, "%s\\Windows\\System32\\bcdboot.exe %s\\Windows /f ALL /s %s", + drive_name, drive_name, (use_ms_efi)?ms_efi:drive_name); + uprintf("Enabling boot: '%s'", cmd); if (RunCommand(cmd, NULL, TRUE) != 0) { // Fatal, as the UFD is unlikely to boot then uprintf("Command '%s' failed to run", cmd); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT); + if (use_ms_efi) + AltUnmountVolume(ms_efi); return FALSE; } + + if (use_ms_efi) { + Sleep(200); + AltUnmountVolume(ms_efi); + } UpdateProgress(OP_DOS, 99.0f); // The following are non fatal if they fail @@ -1279,7 +1319,7 @@ static BOOL SetupWinToGo(const char* drive_name) fclose(fd); } else { fclose(fd); - static_sprintf(cmd, "dism /Image:%C:\\ /Apply-Unattend:%s", drive_name[0], san_policy_path); + static_sprintf(cmd, "dism /Image:%s\\ /Apply-Unattend:%s", drive_name, san_policy_path); if (RunCommand(cmd, NULL, TRUE) != 0) uprintf("Command '%s' failed to run"); } @@ -1367,7 +1407,7 @@ void update_progress(const uint64_t processed_bytes) DWORD WINAPI FormatThread(void* param) { int i, r, pt, bt, fs, dt; - BOOL s, ret, use_large_fat32, add_uefi_togo; + BOOL s, ret, use_large_fat32, windows_to_go; const DWORD SectorSize = SelectedDrive.Geometry.BytesPerSector; DWORD rSize, wSize, BufSize, DriveIndex = (DWORD)(uintptr_t)param; HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE; @@ -1377,7 +1417,7 @@ DWORD WINAPI FormatThread(void* param) FILE* log_fd; LARGE_INTEGER li; uint64_t wb; - uint8_t *buffer = NULL, *aligned_buffer; + uint8_t *buffer = NULL, *aligned_buffer, extra_partitions = 0; char *bb_msg, *guid_volume = NULL; char drive_name[] = "?:\\"; char drive_letters[27]; @@ -1397,7 +1437,14 @@ DWORD WINAPI FormatThread(void* param) pt = GETPARTTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); use_large_fat32 = (fs == FS_FAT32) && ((SelectedDrive.DiskSize > LARGE_FAT32_SIZE) || (force_large_fat32)); - add_uefi_togo = (fs == FS_NTFS) && (dt == DT_ISO) && (iso_report.has_efi) && (bt == BT_UEFI); + windows_to_go = HAS_TOGO(iso_report) && (Button_GetCheck(GetDlgItem(hMainDialog, IDC_WINDOWS_TO_GO)) == BST_CHECKED); + // Find out if we need to add any extra partitions + if ((windows_to_go) && (bt == BT_UEFI) && (pt == PARTITION_STYLE_GPT)) + // According to Microsoft, every GPT disk (we RUN Windows from) must have an MSR due to not having hidden sectors + // http://msdn.microsoft.com/en-us/library/windows/hardware/dn640535.aspx#gpt_faq_what_disk_require_msr + extra_partitions = XP_MSR | XP_EFI; + else if ((fs == FS_NTFS) && (dt == DT_ISO) && (iso_report.has_efi) && ((bt == BT_UEFI) || (windows_to_go))) + extra_partitions = XP_UEFI_TOGO; PrintInfoDebug(0, MSG_225); hPhysicalDrive = GetPhysicalHandle(DriveIndex, TRUE, TRUE); @@ -1636,7 +1683,7 @@ DWORD WINAPI FormatThread(void* param) UpdateProgress(OP_ZERO_MBR, -1.0f); CHECK_FOR_USER_CANCEL; - if (!CreatePartition(hPhysicalDrive, pt, fs, (pt==PARTITION_STYLE_MBR) && (bt==BT_UEFI), add_uefi_togo)) { + if (!CreatePartition(hPhysicalDrive, pt, fs, (pt==PARTITION_STYLE_MBR) && (bt==BT_UEFI), extra_partitions)) { FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE; goto out; } @@ -1765,8 +1812,8 @@ DWORD WINAPI FormatThread(void* param) if (image_path != NULL) { UpdateProgress(OP_DOS, 0.0f); PrintInfoDebug(0, MSG_231); - drive_name[2] = 0; - if (HAS_TOGO(iso_report) && (Button_GetCheck(GetDlgItem(hMainDialog, IDC_WINDOWS_TO_GO)) == BST_CHECKED)) { + drive_name[2] = 0; // Ensure our drive is something like 'D:' + if (windows_to_go) { // Sanity checks if (fs != FS_NTFS) { FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_INCOMPATIBLE_FS); @@ -1776,7 +1823,7 @@ DWORD WINAPI FormatThread(void* param) FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED; goto out; } - if (!SetupWinToGo(drive_name)) { + if (!SetupWinToGo(drive_name, (extra_partitions & XP_EFI))) { if (!IS_ERROR(FormatStatus)) FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT); goto out; diff --git a/src/rufus.rc b/src/rufus.rc index 945fa2bf..7f8f1b06 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -32,7 +32,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 -CAPTION "Rufus 2.0.0.578" +CAPTION "Rufus 2.0.0.579" FONT 8, "Segoe UI", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,127,339,50,14 @@ -157,7 +157,7 @@ END IDD_DIALOG_XP DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Rufus 2.0.0.578" +CAPTION "Rufus 2.0.0.579" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,127,339,50,14 @@ -283,7 +283,7 @@ END IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL -CAPTION "Rufus 2.0.0.578" +CAPTION "Rufus 2.0.0.579" FONT 8, "Segoe UI", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,127,339,50,14 @@ -415,7 +415,7 @@ END IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL -CAPTION "Rufus 2.0.0.578" +CAPTION "Rufus 2.0.0.579" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,127,339,50,14 @@ -671,8 +671,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,0,0,578 - PRODUCTVERSION 2,0,0,578 + FILEVERSION 2,0,0,579 + PRODUCTVERSION 2,0,0,579 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -689,13 +689,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "2.0.0.578" + VALUE "FileVersion", "2.0.0.579" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2015 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "2.0.0.578" + VALUE "ProductVersion", "2.0.0.579" END END BLOCK "VarFileInfo" diff --git a/src/stdio.c b/src/stdio.c index 295c0bea..f865bb14 100644 --- a/src/stdio.c +++ b/src/stdio.c @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Standard User I/O Routines (logging, status, etc.) - * Copyright © 2011-2013 Pete Batard + * Copyright © 2011-2015 Pete Batard * * 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 @@ -181,7 +181,7 @@ char* SizeToHumanReadable(uint64_t size, BOOL log, BOOL fake_units) } else if (fake_units) { if (hr_size < 8) { static_sprintf(str_size, (fabs((hr_size*10.0)-(floor(hr_size + 0.5)*10.0)) < 0.5)?"%0.0f%s":"%0.1f%s", - hr_size, _msg_table[MSG_020+suffix-MSG_000]); + hr_size, _msg_table[MSG_020+suffix-MSG_000]); } else { t = (double)upo2((uint16_t)hr_size); i_size = (uint16_t)((fabs(1.0f-(hr_size / t)) < 0.05f)?t:hr_size);