mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[togo] Add Windows To Go support - part 2
* Enable the creation of MSR and MS EFI partition in GPT mode * Closes #432
This commit is contained in:
parent
ec761dfb41
commit
ed9fae7c81
5 changed files with 205 additions and 51 deletions
155
src/drive.c
155
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");
|
||||
|
|
|
@ -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);
|
||||
|
|
73
src/format.c
73
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;
|
||||
|
|
16
src/rufus.rc
16
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"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Rufus: The Reliable USB Formatting Utility
|
||||
* Standard User I/O Routines (logging, status, etc.)
|
||||
* Copyright © 2011-2013 Pete Batard <pete@akeo.ie>
|
||||
* Copyright © 2011-2015 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
|
||||
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue