mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[togo] Add Windows To Go support - part 4
* Ignore partitions we don't care about * Fix issues with AltMountVolume() * Try to support 4k drives when setting up MS EFI partition * Zero the start of the MSR partition to prevent leftover detection * Fix unwanted use of MBR hidden sectors and redundant CloseHandle() * Fix addon of BIOS compatibility extra partition * Print apply image progress to info box
This commit is contained in:
parent
ed9fae7c81
commit
4b76cb2555
9 changed files with 129 additions and 85 deletions
|
@ -415,8 +415,10 @@ t MSG_195 "Using embedded version of %s file(s)"
|
|||
t MSG_196 "IMPORTANT: THIS DRIVE USES A NONSTANDARD SECTOR SIZE!!\n\n"
|
||||
"Conventional drives use a 512-byte sector size but this drive uses a %d-byte one. "
|
||||
"In many cases, this means that you will NOT be able to boot from this drive.\n"
|
||||
"Rufus can still try to create a bootable drive, but there is NO WARRANTY that it will work."
|
||||
"Rufus can try to create a bootable drive, but there is NO WARRANTY that it will work."
|
||||
t MSG_197 "Nonstandard sector size detected"
|
||||
t MSG_198 "Windows To Go can only be installed on a GPT partitioned drive if it has "
|
||||
"the FIXED attribute set. The current drive was not detected as FIXED."
|
||||
|
||||
# Status messages - these messages will appear on the status bar
|
||||
t MSG_201 "Cancelling - Please wait..."
|
||||
|
@ -505,6 +507,9 @@ t MSG_263 "Use PROPER size units"
|
|||
t MSG_264 "Deleting directory '%s'"
|
||||
t MSG_265 "VMWare disk detection"
|
||||
t MSG_266 "Dual UEFI/BIOS mode"
|
||||
t MSG_267 "Applying Windows image: %d%% completed"
|
||||
t MSG_268 "Applying Windows image..."
|
||||
|
||||
################################################################################
|
||||
############################# TRANSLATOR END COPY ##############################
|
||||
################################################################################
|
||||
|
|
81
src/drive.c
81
src/drive.c
|
@ -654,7 +654,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
|
|||
{
|
||||
// MBR partition types that can be mounted in Windows
|
||||
const uint8_t mbr_mountable[] = { 0x01, 0x04, 0x06, 0x07, 0x0b, 0x0c, 0x0e, 0xef };
|
||||
BOOL r, hasRufusExtra = FALSE, ret = FALSE, isUefiTogo;
|
||||
BOOL r, ret = FALSE, isUefiTogo;
|
||||
HANDLE hPhysical;
|
||||
DWORD size;
|
||||
BYTE geometry[256], layout[4096], part_type;
|
||||
|
@ -743,7 +743,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
|
|||
DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No");
|
||||
if ((part_type == RUFUS_EXTRA_PARTITION_TYPE) || (isUefiTogo))
|
||||
// This is a partition Rufus created => we can safely ignore it
|
||||
hasRufusExtra = TRUE;
|
||||
--SelectedDrive.nPartitions;
|
||||
if (part_type == 0xee) // Flag a protective MBR for non GPT platforms (XP)
|
||||
SelectedDrive.has_protective_mbr = TRUE;
|
||||
}
|
||||
|
@ -765,8 +765,11 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
|
|||
GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionId), SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength.QuadPart, TRUE, FALSE),
|
||||
DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].StartingOffset.QuadPart / DiskGeometry->Geometry.BytesPerSector,
|
||||
DriveLayout->PartitionEntry[i].Gpt.Attributes);
|
||||
if (strcmp(tmp, "UEFI:TOGO") == 0)
|
||||
hasRufusExtra = TRUE;
|
||||
// Don't register the partitions that we don't care about destroying
|
||||
if ( (strcmp(tmp, "UEFI:TOGO") == 0) ||
|
||||
(CompareGUID(&DriveLayout->PartitionEntry[i].Gpt.PartitionType, &PARTITION_MSFT_RESERVED_GUID)) ||
|
||||
(CompareGUID(&DriveLayout->PartitionEntry[i].Gpt.PartitionType, &PARTITION_SYSTEM_GUID)) )
|
||||
--SelectedDrive.nPartitions;
|
||||
if ( (memcmp(&PARTITION_BASIC_DATA_GUID, &DriveLayout->PartitionEntry[i].Gpt.PartitionType, sizeof(GUID)) == 0) &&
|
||||
(nWindowsVersion >= WINDOWS_VISTA) )
|
||||
ret = TRUE;
|
||||
|
@ -782,8 +785,6 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
|
|||
#endif
|
||||
safe_closehandle(hPhysical);
|
||||
|
||||
if (hasRufusExtra)
|
||||
SelectedDrive.nPartitions--;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -893,8 +894,8 @@ char* AltMountVolume(const char* drive_name, uint8_t part_nr)
|
|||
|
||||
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());
|
||||
if (!QueryDosDeviceA(drive_name, target[0], MAX_PATH) || (strlen(target[0]) == 0)) {
|
||||
uprintf("Could not get the DOS volume name for '%s': %s", drive_name, WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -932,8 +933,8 @@ char* AltMountVolume(const char* drive_name, uint8_t 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());
|
||||
if (!QueryDosDeviceA(p, target[0], MAX_PATH) || (strlen(target[0]) == 0)) {
|
||||
uprintf("Could not find the DOS volume name for partition '%s': %s", p, WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -955,6 +956,8 @@ out:
|
|||
*/
|
||||
BOOL AltUnmountVolume(const char* drive_name)
|
||||
{
|
||||
if (drive_name == NULL)
|
||||
return FALSE;
|
||||
if (!DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_NO_BROADCAST_SYSTEM, drive_name, NULL)) {
|
||||
uprintf("Could not unmount '%s': %s", drive_name, WindowsErrorString());
|
||||
return FALSE;
|
||||
|
@ -1017,7 +1020,8 @@ 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 main_part_size_in_sectors, extra_part_size_in_tracks = 0;
|
||||
LONGLONG main_part_size_in_sectors, extra_part_size_in_tracks = 0, ms_efi_size;
|
||||
const LONGLONG bytes_per_track = SelectedDrive.Geometry.SectorsPerTrack * SelectedDrive.Geometry.BytesPerSector;
|
||||
|
||||
PrintInfoDebug(0, MSG_238, PartitionTypeName[partition_style]);
|
||||
|
||||
|
@ -1030,8 +1034,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
|||
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = 1024*1024;
|
||||
} else {
|
||||
// Align on Cylinder
|
||||
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart =
|
||||
SelectedDrive.Geometry.BytesPerSector * SelectedDrive.Geometry.SectorsPerTrack;
|
||||
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = bytes_per_track;
|
||||
}
|
||||
|
||||
// If required, set the MSR partition (GPT only - must be created before the data part)
|
||||
|
@ -1044,24 +1047,42 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
|||
pn++;
|
||||
DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn-1].StartingOffset.QuadPart +
|
||||
DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart;
|
||||
|
||||
// We must zero the beginning of this partition, else we get FAT leftovers and stuff
|
||||
if (SetFilePointerEx(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, NULL, FILE_BEGIN)) {
|
||||
bufsize = 65536; // 64K should be enough for everyone
|
||||
buffer = calloc(bufsize, 1);
|
||||
if (buffer != NULL) {
|
||||
if ((!WriteFile(hDrive, buffer, bufsize, &size, NULL)) || (size != bufsize))
|
||||
uprintf(" Could not zero MSR: %s", WindowsErrorString());
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set our main data partition
|
||||
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
|
||||
// Adjust the size according to extra partitions (which we always align to a track)
|
||||
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 {
|
||||
uprintf("Adding extra partition");
|
||||
if (extra_partitions & XP_EFI) {
|
||||
// The size of the EFI partition depends on the minimum size we're able to format in FAT32,
|
||||
// which in turn depends on the cluster size used, which in turn depends on the disk sector size.
|
||||
if (SelectedDrive.Geometry.BytesPerSector <= 1024)
|
||||
ms_efi_size = 100*1024*1024;
|
||||
else if (SelectedDrive.Geometry.BytesPerSector <= 4096)
|
||||
ms_efi_size = 300*1024*1024;
|
||||
else
|
||||
ms_efi_size = 1200*1024*1024; // That'll teach you to have a nonstandard disk!
|
||||
extra_part_size_in_tracks = (ms_efi_size + bytes_per_track - 1) / bytes_per_track;
|
||||
} else if (extra_partitions & XP_UEFI_TOGO)
|
||||
extra_part_size_in_tracks = (MIN_EXTRA_PART_SIZE + bytes_per_track - 1) / bytes_per_track;
|
||||
else if (extra_partitions & XP_COMPAT)
|
||||
extra_part_size_in_tracks = 1; // One track for the extra partition
|
||||
}
|
||||
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));
|
||||
uprintf("Reserved %lld tracks (%s) for extra partition", extra_part_size_in_tracks,
|
||||
SizeToHumanReadable(extra_part_size_in_tracks * bytes_per_track, 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)
|
||||
|
@ -1070,7 +1091,6 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
|||
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;
|
||||
switch (file_system) {
|
||||
case FS_FAT16:
|
||||
DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = 0x0e; // FAT16 LBA
|
||||
|
@ -1108,7 +1128,9 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
|||
wcscpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, (extra_partitions & XP_UEFI_TOGO)?L"UEFI:TOGO":L"EFI system partition");
|
||||
} else {
|
||||
DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = (extra_partitions & XP_UEFI_TOGO)?0x01:RUFUS_EXTRA_PARTITION_TYPE;
|
||||
DriveLayoutEx.PartitionEntry[pn].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack;
|
||||
if (extra_partitions & XP_COMPAT)
|
||||
// Set the one track compatibility partition to be all hidden sectors
|
||||
DriveLayoutEx.PartitionEntry[pn].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack;
|
||||
}
|
||||
|
||||
// We need to write the TOGO partition before we refresh the disk
|
||||
|
@ -1116,13 +1138,11 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
|||
uprintf("Writing UEFI:TOGO partition...");
|
||||
if (!SetFilePointerEx(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, NULL, FILE_BEGIN)) {
|
||||
uprintf("Unable to set position");
|
||||
safe_closehandle(hDrive);
|
||||
return FALSE;
|
||||
}
|
||||
buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_UEFI_TOGO), _RT_RCDATA, "uefi-togo.img", &bufsize, FALSE);
|
||||
if (buffer == NULL) {
|
||||
uprintf("Could not access uefi-togo.img");
|
||||
safe_closehandle(hDrive);
|
||||
return FALSE;
|
||||
}
|
||||
r = WriteFile(hDrive, buffer, bufsize, &size, NULL);
|
||||
|
@ -1131,7 +1151,6 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
|||
uprintf("Write error: %s", WindowsErrorString());
|
||||
else
|
||||
uprintf("Write error: Wrote %d bytes, expected %d bytes\n", size, bufsize);
|
||||
safe_closehandle(hDrive);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -1185,7 +1204,6 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
|||
r = DeviceIoControl(hDrive, IOCTL_DISK_CREATE_DISK, (BYTE*)&CreateDisk, size, NULL, 0, &size, NULL );
|
||||
if (!r) {
|
||||
uprintf("Could not reset disk: %s\n", WindowsErrorString());
|
||||
safe_closehandle(hDrive);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1193,14 +1211,11 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
|||
r = DeviceIoControl(hDrive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX, (BYTE*)&DriveLayoutEx, size, NULL, 0, &size, NULL );
|
||||
if (!r) {
|
||||
uprintf("Could not set drive layout: %s\n", WindowsErrorString());
|
||||
safe_closehandle(hDrive);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!RefreshDriveLayout(hDrive)) {
|
||||
safe_closehandle(hDrive);
|
||||
if (!RefreshDriveLayout(hDrive))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#define XP_MSR 0x01
|
||||
#define XP_EFI 0x02
|
||||
#define XP_UEFI_TOGO 0x04
|
||||
#define XP_COMPAT 0x08
|
||||
|
||||
/* We need a redef of these MS structure */
|
||||
typedef struct {
|
||||
|
|
77
src/format.c
77
src/format.c
|
@ -1229,21 +1229,26 @@ out:
|
|||
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, *ms_efi, image[128], cmd[128];
|
||||
char *mounted_iso, *ms_efi = NULL, image[128], cmd[128];
|
||||
wchar_t wVolumeName[] = L"?:";
|
||||
unsigned char *buffer;
|
||||
DWORD bufsize;
|
||||
ULONG cluster_size;
|
||||
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");
|
||||
// Additional sanity checks
|
||||
if ( ((use_ms_efi) && (SelectedDrive.Geometry.MediaType != FixedMedia)) ||
|
||||
((nWindowsVersion < WINDOWS_8) || ((WimExtractCheck() & 4) == 0)) ) {
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED;
|
||||
return FALSE;
|
||||
}
|
||||
if (ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)) != FS_NTFS) {
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_INCOMPATIBLE_FS);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// First, we need to access the install.wim image, that resides on the ISO
|
||||
mounted_iso = MountISO(image_path);
|
||||
|
@ -1274,13 +1279,23 @@ BOOL SetupWinToGo(const char* drive_name, BOOL use_ms_efi)
|
|||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_ASSIGN_LETTER);
|
||||
return FALSE;
|
||||
}
|
||||
fs_index = 0;
|
||||
uprintf("Formatting EFI system partition %s", ms_efi);
|
||||
// According to Ubuntu (https://bugs.launchpad.net/ubuntu/+source/partman-efi/+bug/811485) you want to use FAT32.
|
||||
// However, you have to be careful that the cluster size needs to be greater or equal to the sector size, which
|
||||
// in turn has an impact on the minimum EFI partition size we can create (see ms_efi_size_MB in drive.c)
|
||||
if (SelectedDrive.Geometry.BytesPerSector <= 1024)
|
||||
cluster_size = 1024;
|
||||
else if (SelectedDrive.Geometry.BytesPerSector <= 4096)
|
||||
cluster_size = 4096;
|
||||
else // Go for broke
|
||||
cluster_size = (ULONG)SelectedDrive.Geometry.BytesPerSector;
|
||||
fs_index = 1; // FAT32
|
||||
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);
|
||||
|
||||
// Boy do you *NOT* want to specify a label here, and spend HOURS figuring out why your EFI partition cannot boot...
|
||||
// TODO: Can we avoid resetting the progress bar here?
|
||||
pfFormatEx(wVolumeName, SelectedDrive.Geometry.MediaType, L"FAT32", L"", TRUE, cluster_size, FormatExCallback);
|
||||
if (IS_ERROR(FormatStatus)) {
|
||||
uprintf("Failed to format EFI partition");
|
||||
AltUnmountVolume(ms_efi);
|
||||
|
@ -1445,6 +1460,8 @@ DWORD WINAPI FormatThread(void* param)
|
|||
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;
|
||||
else if (IsChecked(IDC_EXTRA_PARTITION))
|
||||
extra_partitions = XP_COMPAT;
|
||||
|
||||
PrintInfoDebug(0, MSG_225);
|
||||
hPhysicalDrive = GetPhysicalHandle(DriveIndex, TRUE, TRUE);
|
||||
|
@ -1808,27 +1825,19 @@ DWORD WINAPI FormatThread(void* param)
|
|||
IGNORE_RETVAL(_chdirU(app_dir));
|
||||
if (!CopyFileU(FILES_DIR "\\grub4dos\\grldr", grub4dos_dst, FALSE))
|
||||
uprintf("Failed to copy file: %s", WindowsErrorString());
|
||||
} else if (dt == DT_ISO) {
|
||||
if (image_path != NULL) {
|
||||
UpdateProgress(OP_DOS, 0.0f);
|
||||
} else if ((dt == DT_ISO) && (image_path != NULL)) {
|
||||
UpdateProgress(OP_DOS, 0.0f);
|
||||
drive_name[2] = 0; // Ensure our drive is something like 'D:'
|
||||
if (windows_to_go) {
|
||||
PrintInfoDebug(0, MSG_268);
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
PrintInfoDebug(0, MSG_231);
|
||||
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);
|
||||
goto out;
|
||||
}
|
||||
if ((nWindowsVersion < WINDOWS_8) || ((WimExtractCheck() & 4) == 0)) {
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED;
|
||||
goto out;
|
||||
}
|
||||
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;
|
||||
}
|
||||
} else if (!ExtractISO(image_path, drive_name, FALSE)) {
|
||||
if (!ExtractISO(image_path, drive_name, FALSE)) {
|
||||
if (!IS_ERROR(FormatStatus))
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT);
|
||||
goto out;
|
||||
|
@ -1858,11 +1867,11 @@ DWORD WINAPI FormatThread(void* param)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( (bt == BT_BIOS) && (IS_WINPE(iso_report.winpe)) ) {
|
||||
// Apply WinPe fixup
|
||||
if (!SetupWinPE(drive_name[0]))
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
||||
if ( (bt == BT_BIOS) && (IS_WINPE(iso_report.winpe)) ) {
|
||||
// Apply WinPe fixup
|
||||
if (!SetupWinPE(drive_name[0]))
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateProgress(OP_FINALIZE, -1.0f);
|
||||
|
|
10
src/rufus.c
10
src/rufus.c
|
@ -919,7 +919,6 @@ static void DisplayISOProps(void)
|
|||
uprintf(" Has Symlinks: %s", YesNo(iso_report.has_symlinks));
|
||||
uprintf(" Has a >4GB file: %s", YesNo(iso_report.has_4GB_file));
|
||||
uprintf(" Uses Bootmgr: %s", YesNo(iso_report.has_bootmgr));
|
||||
// TODO: report x86, x64, Arm, Itanic?
|
||||
uprintf(" Uses EFI: %s%s", YesNo(iso_report.has_efi), IS_WIN7_EFI(iso_report) ? " (win7_x64)" : "");
|
||||
uprintf(" Uses Grub 2: %s", YesNo(iso_report.has_grub2));
|
||||
uprintf(" Uses Grub4DOS: %s", YesNo(iso_report.has_grub4dos));
|
||||
|
@ -1156,7 +1155,7 @@ static void ToggleToGo(void)
|
|||
|
||||
static BOOL BootCheck(void)
|
||||
{
|
||||
int i, fs, bt, dt, r;
|
||||
int i, fs, bt, dt, pt, r;
|
||||
FILE *fd;
|
||||
DWORD len;
|
||||
BOOL in_files_dir = FALSE;
|
||||
|
@ -1170,6 +1169,7 @@ static BOOL BootCheck(void)
|
|||
syslinux_ldlinux_len[0] = 0; syslinux_ldlinux_len[1] = 0;
|
||||
safe_free(grub2_buf);
|
||||
dt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType));
|
||||
pt = GETPARTTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)));
|
||||
if ((dt == DT_ISO) || (dt == DT_IMG)) {
|
||||
if (image_path == NULL) {
|
||||
// Please click on the disc button to select a bootable ISO
|
||||
|
@ -1195,6 +1195,12 @@ static BOOL BootCheck(void)
|
|||
MessageBoxU(hMainDialog, lmprintf(MSG_097), lmprintf(MSG_092), MB_OK|MB_ICONERROR|MB_IS_RTL);
|
||||
return FALSE;
|
||||
} else if (SelectedDrive.Geometry.MediaType != FixedMedia) {
|
||||
if ((bt == BT_UEFI) && (pt == PARTITION_STYLE_GPT)) {
|
||||
// We're screwed since we need access to 2 partitions at the same time to set this, which
|
||||
// Windows can't do. Cue in Arthur's Theme: "♫ I know it's stupid... but it's true. ♫"
|
||||
MessageBoxU(hMainDialog, lmprintf(MSG_198), lmprintf(MSG_190), MB_OK|MB_ICONERROR|MB_IS_RTL);
|
||||
return FALSE;
|
||||
}
|
||||
// I never had any success with drives that have the REMOVABLE attribute set, no matter the
|
||||
// method or tool I tried. If you manage to get this working, I'd like to hear from you!
|
||||
if (MessageBoxU(hMainDialog, lmprintf(MSG_098), lmprintf(MSG_190), MB_YESNO|MB_ICONWARNING|MB_IS_RTL) != IDYES)
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#define DRIVE_ACCESS_RETRIES 60 // How many times we should retry
|
||||
#define DRIVE_INDEX_MIN 0x00000080
|
||||
#define DRIVE_INDEX_MAX 0x000000C0
|
||||
#define MIN_EXTRA_PART_SIZE 2048 // Minimum size of the extra partition, in sectors
|
||||
#define MIN_EXTRA_PART_SIZE (1024*1024) // Minimum size of the extra partition, in bytes
|
||||
#define MAX_DRIVES (DRIVE_INDEX_MAX - DRIVE_INDEX_MIN)
|
||||
#define MAX_TOOLTIPS 128
|
||||
#define MAX_SIZE_SUFFIXES 6 // bytes, KB, MB, GB, TB, PB
|
||||
|
@ -210,7 +210,7 @@ typedef struct {
|
|||
DWORD FirstSector;
|
||||
char proposed_label[16];
|
||||
int PartitionType;
|
||||
int nPartitions;
|
||||
int nPartitions; // number of partitions we actually care about
|
||||
int FSType;
|
||||
BOOL has_protective_mbr;
|
||||
BOOL has_mbr_uefi_marker;
|
||||
|
@ -396,6 +396,7 @@ extern BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size);
|
|||
extern unsigned char* GetResource(HMODULE module, char* name, char* type, const char* desc, DWORD* len, BOOL duplicate);
|
||||
extern DWORD GetResourceSize(HMODULE module, char* name, char* type, const char* desc);
|
||||
extern DWORD RunCommand(const char* cmdline, const char* dir, BOOL log);
|
||||
extern BOOL CompareGUID(const GUID *guid1, const GUID *guid2);
|
||||
extern BOOL GetUSBDevices(DWORD devnum);
|
||||
extern BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue);
|
||||
extern LONG GetEntryWidth(HWND hDropDown, const char* entry);
|
||||
|
|
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.579"
|
||||
CAPTION "Rufus 2.0.0.580"
|
||||
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.579"
|
||||
CAPTION "Rufus 2.0.0.580"
|
||||
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.579"
|
||||
CAPTION "Rufus 2.0.0.580"
|
||||
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.579"
|
||||
CAPTION "Rufus 2.0.0.580"
|
||||
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,579
|
||||
PRODUCTVERSION 2,0,0,579
|
||||
FILEVERSION 2,0,0,580
|
||||
PRODUCTVERSION 2,0,0,580
|
||||
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.579"
|
||||
VALUE "FileVersion", "2.0.0.580"
|
||||
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.579"
|
||||
VALUE "ProductVersion", "2.0.0.580"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
15
src/stdfn.c
15
src/stdfn.c
|
@ -590,13 +590,20 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
BOOL CompareGUID(const GUID *guid1, const GUID *guid2) {
|
||||
if ((guid1 != NULL) && (guid2 != NULL)) {
|
||||
return (memcmp(guid1, guid2, sizeof(GUID)) == 0);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set or restore a Local Group Policy DWORD key indexed by szPath/SzPolicy
|
||||
*/
|
||||
#pragma push_macro("INTERFACE")
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IGroupPolicyObject
|
||||
#define REGISTRY_EXTENSION_GUID { 0x35378EAC, 0x683F, 0x11D2, {0xA8, 0x9A, 0x00, 0xC0, 0x4F, 0xBB, 0xCF, 0xA2} }
|
||||
#define REGISTRY_EXTENSION_GUID { 0x35378EACL, 0x683F, 0x11D2, {0xA8, 0x9A, 0x00, 0xC0, 0x4F, 0xBB, 0xCF, 0xA2} }
|
||||
#define GPO_OPEN_LOAD_REGISTRY 1
|
||||
#define GPO_SECTION_MACHINE 2
|
||||
typedef enum _GROUP_POLICY_OBJECT_TYPE {
|
||||
|
@ -650,12 +657,12 @@ DWORD WINAPI SetLGPThread(LPVOID param)
|
|||
HKEY path_key = NULL, policy_key = NULL;
|
||||
// MSVC is finicky about these ones => redefine them
|
||||
const IID my_IID_IGroupPolicyObject =
|
||||
{ 0xea502723, 0xa23d, 0x11d1, { 0xa7, 0xd3, 0x0, 0x0, 0xf8, 0x75, 0x71, 0xe3 } };
|
||||
{ 0xea502723L, 0xa23d, 0x11d1, { 0xa7, 0xd3, 0x0, 0x0, 0xf8, 0x75, 0x71, 0xe3 } };
|
||||
const IID my_CLSID_GroupPolicyObject =
|
||||
{ 0xea502722, 0xa23d, 0x11d1, { 0xa7, 0xd3, 0x0, 0x0, 0xf8, 0x75, 0x71, 0xe3 } };
|
||||
{ 0xea502722L, 0xa23d, 0x11d1, { 0xa7, 0xd3, 0x0, 0x0, 0xf8, 0x75, 0x71, 0xe3 } };
|
||||
GUID ext_guid = REGISTRY_EXTENSION_GUID;
|
||||
// Can be anything really
|
||||
GUID snap_guid = { 0x3D271CFC, 0x2BC6, 0x4AC2, {0xB6, 0x33, 0x3B, 0xDF, 0xF5, 0xBD, 0xAB, 0x2A} };
|
||||
GUID snap_guid = { 0x3D271CFCL, 0x2BC6, 0x4AC2, {0xB6, 0x33, 0x3B, 0xDF, 0xF5, 0xBD, 0xAB, 0x2A} };
|
||||
|
||||
// Reinitialize COM since it's not shared between threads
|
||||
IGNORE_RETVAL(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
|
||||
|
|
|
@ -509,7 +509,7 @@ DWORD WINAPI WimProgressCallback(DWORD dwMsgId, WPARAM wParam, LPARAM lParam, PV
|
|||
|
||||
switch (dwMsgId) {
|
||||
case WIM_MSG_PROGRESS:
|
||||
uprintf(" %d%% completed", (DWORD)wParam);
|
||||
PrintInfo(0, MSG_267, (DWORD)wParam);
|
||||
UpdateProgress(OP_DOS, 0.98f*(DWORD)wParam);
|
||||
break;
|
||||
case WIM_MSG_PROCESS:
|
||||
|
|
Loading…
Reference in a new issue