[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:
Pete Batard 2015-01-20 21:50:24 +00:00
parent ed9fae7c81
commit 4b76cb2555
9 changed files with 129 additions and 85 deletions

View File

@ -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 ##############################
################################################################################

View File

@ -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;
}

View File

@ -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 {

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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"

View File

@ -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));

View File

@ -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: