mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[gpt] add support for GPT partitioning and EFI boot
* Contains the bulk of the code required to address #11 * Tested with Windows 8 Pro x64 (en-gb_windows_8_x64_dvd_915412.iso) and Arch Linux (archlinux-2013.01.04-dual.iso) against an UEFI 2.1 BIOS * Also fixes missing status report beta versions check
This commit is contained in:
parent
6b8833bcfb
commit
997c0a0f28
8 changed files with 257 additions and 114 deletions
45
src/format.c
45
src/format.c
|
@ -2,7 +2,7 @@
|
||||||
* Rufus: The Reliable USB Formatting Utility
|
* Rufus: The Reliable USB Formatting Utility
|
||||||
* Formatting function calls
|
* Formatting function calls
|
||||||
* Copyright (c) 2007-2009 Tom Thornhill/Ridgecrop
|
* Copyright (c) 2007-2009 Tom Thornhill/Ridgecrop
|
||||||
* Copyright (c) 2011-2012 Pete Batard <pete@akeo.ie>
|
* Copyright (c) 2011-2013 Pete Batard <pete@akeo.ie>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -743,21 +743,30 @@ static BOOL AnalyzePBR(HANDLE hLogicalVolume)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL ClearMBR(HANDLE hPhysicalDrive)
|
static BOOL ClearMBRGPT(HANDLE hPhysicalDrive, LONGLONG DiskSize, DWORD SectorSize)
|
||||||
{
|
{
|
||||||
BOOL r = FALSE;
|
BOOL r = FALSE;
|
||||||
// Clearing the first 64K seems to help with reluctant access to large drive
|
uint64_t i, last_sector = DiskSize/SectorSize;
|
||||||
size_t SectorSize = 65536;
|
|
||||||
unsigned char* pBuf = (unsigned char*) calloc(SectorSize, 1);
|
unsigned char* pBuf = (unsigned char*) calloc(SectorSize, 1);
|
||||||
|
|
||||||
PrintStatus(0, TRUE, "Clearing MBR...");
|
PrintStatus(0, TRUE, "Clearing MBR & GPT structures...");
|
||||||
if (pBuf == NULL) {
|
if (pBuf == NULL) {
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if ((IS_ERROR(FormatStatus)) || (write_sectors(hPhysicalDrive, SectorSize, 0, 1, pBuf) != SectorSize)) {
|
// http://en.wikipedia.org/wiki/GUID_Partition_Table tells us we should clear 34 sectors at the
|
||||||
|
// beginning and 33 at the end. We bump these values to MAX_SECTORS_TO_CLEAR each end to help
|
||||||
|
// with reluctant access to large drive.
|
||||||
|
for (i=0; i<MAX_SECTORS_TO_CLEAR; i++) {
|
||||||
|
if ((IS_ERROR(FormatStatus)) || (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) != SectorSize)) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
for (i=last_sector-MAX_SECTORS_TO_CLEAR; i<last_sector; i++) {
|
||||||
|
if ((IS_ERROR(FormatStatus)) || (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) != SectorSize)) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
r = TRUE;
|
r = TRUE;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -1104,6 +1113,7 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
int r;
|
int r;
|
||||||
int fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
|
int fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
|
||||||
int dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType));
|
int dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType));
|
||||||
|
int pt = (int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme));
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
DWORD num = (DWORD)(uintptr_t)param;
|
DWORD num = (DWORD)(uintptr_t)param;
|
||||||
HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;
|
HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;
|
||||||
|
@ -1161,7 +1171,7 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
if (!FormatStatus)
|
if (!FormatStatus)
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|
|
||||||
APPERR(ERROR_BADBLOCKS_FAILURE);
|
APPERR(ERROR_BADBLOCKS_FAILURE);
|
||||||
ClearMBR(hPhysicalDrive);
|
ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.Geometry.BytesPerSector);
|
||||||
fclose(log_fd);
|
fclose(log_fd);
|
||||||
_unlink(logfile);
|
_unlink(logfile);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1198,10 +1208,10 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
// Close the (unmounted) volume before formatting, but keep the lock
|
// Close the (unmounted) volume before formatting, but keep the lock
|
||||||
safe_closehandle(hLogicalVolume);
|
safe_closehandle(hLogicalVolume);
|
||||||
|
|
||||||
// Especially after destructive badblocks test, you must zero the MBR completely
|
// Especially after destructive badblocks test, you must zero the MBR/GPT completely
|
||||||
// before repartitioning. Else, all kind of bad things happen
|
// before repartitioning. Else, all kind of bad things can happen.
|
||||||
if (!ClearMBR(hPhysicalDrive)) {
|
if (!ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.Geometry.BytesPerSector)) {
|
||||||
uprintf("unable to zero MBR\n");
|
uprintf("unable to zero MBR/GPT\n");
|
||||||
if (!FormatStatus)
|
if (!FormatStatus)
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1227,6 +1237,7 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pt == PT_MBR) {
|
||||||
PrintStatus(0, TRUE, "Writing master boot record...");
|
PrintStatus(0, TRUE, "Writing master boot record...");
|
||||||
if (!WriteMBR(hPhysicalDrive)) {
|
if (!WriteMBR(hPhysicalDrive)) {
|
||||||
if (!FormatStatus)
|
if (!FormatStatus)
|
||||||
|
@ -1234,9 +1245,17 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
UpdateProgress(OP_FIX_MBR, -1.0f);
|
UpdateProgress(OP_FIX_MBR, -1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
if (IsChecked(IDC_DOS)) {
|
if (IsChecked(IDC_DOS)) {
|
||||||
if ((dt == DT_WINME) || (dt == DT_FREEDOS) || ((dt == DT_ISO) && (fs == FS_NTFS))) {
|
if (pt == PT_GPT) {
|
||||||
|
// For once, no need to do anything - just check our sanity
|
||||||
|
if ( (dt != DT_ISO) || (!iso_report.has_efi) || (fs > FS_FAT32) ) {
|
||||||
|
uprintf("Spock gone crazy error!\n");
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INSTALL_FAILURE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else if ((dt == DT_WINME) || (dt == DT_FREEDOS) || ((dt == DT_ISO) && (fs == FS_NTFS))) {
|
||||||
// We still have a lock, which we need to modify the volume boot record
|
// We still have a lock, which we need to modify the volume boot record
|
||||||
// => no need to reacquire the lock...
|
// => no need to reacquire the lock...
|
||||||
hLogicalVolume = GetDriveHandle(num, drive_name, TRUE, FALSE);
|
hLogicalVolume = GetDriveHandle(num, drive_name, TRUE, FALSE);
|
||||||
|
@ -1292,7 +1311,7 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IS_WINPE(iso_report.winpe)) {
|
if ( (pt == PT_MBR) && (IS_WINPE(iso_report.winpe)) ) {
|
||||||
// Apply WinPe fixup
|
// Apply WinPe fixup
|
||||||
if (!SetupWinPE(drive_name[0]))
|
if (!SetupWinPE(drive_name[0]))
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
||||||
|
|
|
@ -57,6 +57,7 @@ int64_t iso_blocking_status = -1;
|
||||||
static const char* psz_extract_dir;
|
static const char* psz_extract_dir;
|
||||||
static const char* bootmgr_name = "bootmgr";
|
static const char* bootmgr_name = "bootmgr";
|
||||||
static const char* ldlinux_name = "ldlinux.sys";
|
static const char* ldlinux_name = "ldlinux.sys";
|
||||||
|
static const char* efi_dirname = "/efi/boot";
|
||||||
static const char* isolinux_name[] = { "isolinux.cfg", "syslinux.cfg", "extlinux.conf"};
|
static const char* isolinux_name[] = { "isolinux.cfg", "syslinux.cfg", "extlinux.conf"};
|
||||||
static const char* pe_dirname[] = { "/i386", "/minint" };
|
static const char* pe_dirname[] = { "/i386", "/minint" };
|
||||||
static const char* pe_file[] = { "ntdetect.com", "setupldr.bin", "txtsetup.sif" };
|
static const char* pe_file[] = { "ntdetect.com", "setupldr.bin", "txtsetup.sif" };
|
||||||
|
@ -126,6 +127,10 @@ static __inline BOOL check_iso_props(const char* psz_dirname, BOOL* is_syslinux_
|
||||||
if ((*psz_dirname == 0) && (safe_stricmp(psz_basename, bootmgr_name) == 0))
|
if ((*psz_dirname == 0) && (safe_stricmp(psz_basename, bootmgr_name) == 0))
|
||||||
iso_report.has_bootmgr = TRUE;
|
iso_report.has_bootmgr = TRUE;
|
||||||
|
|
||||||
|
// Check for the EFI boot directory
|
||||||
|
if (safe_stricmp(psz_dirname, efi_dirname) == 0)
|
||||||
|
iso_report.has_efi = TRUE;
|
||||||
|
|
||||||
// Check for PE (XP) specific files in "/i386" or "/minint"
|
// Check for PE (XP) specific files in "/i386" or "/minint"
|
||||||
for (i=0; i<ARRAYSIZE(pe_dirname); i++)
|
for (i=0; i<ARRAYSIZE(pe_dirname); i++)
|
||||||
if (safe_stricmp(psz_dirname, pe_dirname[i]) == 0)
|
if (safe_stricmp(psz_dirname, pe_dirname[i]) == 0)
|
||||||
|
|
|
@ -607,7 +607,8 @@ out:
|
||||||
PrintStatus(3000, TRUE, "Updates: Unable to access version data.\n");
|
PrintStatus(3000, TRUE, "Updates: Unable to access version data.\n");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
PrintStatus(3000, FALSE, " %s new version of " APPLICATION_NAME " %s\n",
|
case 4:
|
||||||
|
PrintStatus(3000, FALSE, "%s new version of " APPLICATION_NAME " %s\n",
|
||||||
found_new_version?"A":"No", found_new_version?"is available!":"was found.");
|
found_new_version?"A":"No", found_new_version?"is available!":"was found.");
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
#define IDC_DEVICE 1001
|
#define IDC_DEVICE 1001
|
||||||
#define IDC_FILESYSTEM 1002
|
#define IDC_FILESYSTEM 1002
|
||||||
#define IDC_START 1003
|
#define IDC_START 1003
|
||||||
#define IDC_PARTITION 1004
|
#define IDC_PARTITION_SCHEME 1004
|
||||||
#define IDC_CLUSTERSIZE 1005
|
#define IDC_CLUSTERSIZE 1005
|
||||||
#define IDC_STATUS 1006
|
#define IDC_STATUS 1006
|
||||||
#define IDC_ABOUT 1007
|
#define IDC_ABOUT 1007
|
||||||
|
|
192
src/rufus.c
192
src/rufus.c
|
@ -86,6 +86,7 @@ static const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "exFAT" }
|
||||||
static const char* ClusterSizeLabel[] = { "512 bytes", "1024 bytes","2048 bytes","4096 bytes","8192 bytes",
|
static const char* ClusterSizeLabel[] = { "512 bytes", "1024 bytes","2048 bytes","4096 bytes","8192 bytes",
|
||||||
"16 kilobytes", "32 kilobytes", "64 kilobytes", "128 kilobytes", "256 kilobytes", "512 kilobytes",
|
"16 kilobytes", "32 kilobytes", "64 kilobytes", "128 kilobytes", "256 kilobytes", "512 kilobytes",
|
||||||
"1024 kilobytes","2048 kilobytes","4096 kilobytes","8192 kilobytes","16 megabytes","32 megabytes" };
|
"1024 kilobytes","2048 kilobytes","4096 kilobytes","8192 kilobytes","16 megabytes","32 megabytes" };
|
||||||
|
static const char* PartitionSchemeName[PT_MAX] = { "MBR", "GPT" };
|
||||||
static BOOL existing_key = FALSE; // For LGP set/restore
|
static BOOL existing_key = FALSE; // For LGP set/restore
|
||||||
static BOOL iso_size_check = TRUE;
|
static BOOL iso_size_check = TRUE;
|
||||||
static BOOL log_displayed = FALSE;
|
static BOOL log_displayed = FALSE;
|
||||||
|
@ -101,7 +102,7 @@ char szFolderPath[MAX_PATH], app_dir[MAX_PATH];
|
||||||
char* iso_path = NULL;
|
char* iso_path = NULL;
|
||||||
float fScale = 1.0f;
|
float fScale = 1.0f;
|
||||||
int default_fs;
|
int default_fs;
|
||||||
HWND hDeviceList, hPartition, hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses, hLog = NULL;
|
HWND hDeviceList, hPartitionScheme, hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses, hLog = NULL;
|
||||||
HWND hISOProgressDlg = NULL, hLogDlg = NULL, hISOProgressBar, hISOFileName, hDiskID;
|
HWND hISOProgressDlg = NULL, hLogDlg = NULL, hISOProgressBar, hISOFileName, hDiskID;
|
||||||
BOOL use_own_c32[NB_OLD_C32] = {FALSE, FALSE}, detect_fakes = TRUE, mbr_selected_by_user = FALSE;
|
BOOL use_own_c32[NB_OLD_C32] = {FALSE, FALSE}, detect_fakes = TRUE, mbr_selected_by_user = FALSE;
|
||||||
BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE;
|
BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE;
|
||||||
|
@ -359,9 +360,8 @@ static BOOL GetDriveInfo(void)
|
||||||
void* drive_layout = (void*)layout;
|
void* drive_layout = (void*)layout;
|
||||||
PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)disk_geometry;
|
PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)disk_geometry;
|
||||||
PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)drive_layout;
|
PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)drive_layout;
|
||||||
char DrivePath[] = "#:\\", tmp[512], fs_type[32];
|
char DrivePath[] = "#:\\", tmp[256], fs_type[32];
|
||||||
DWORD i, nb_partitions = 0;
|
DWORD i, nb_partitions = 0;
|
||||||
int tmp_pos;
|
|
||||||
|
|
||||||
SelectedDrive.DiskSize = 0;
|
SelectedDrive.DiskSize = 0;
|
||||||
|
|
||||||
|
@ -378,9 +378,9 @@ static BOOL GetDriveInfo(void)
|
||||||
}
|
}
|
||||||
SelectedDrive.DiskSize = DiskGeometry->DiskSize.QuadPart;
|
SelectedDrive.DiskSize = DiskGeometry->DiskSize.QuadPart;
|
||||||
memcpy(&SelectedDrive.Geometry, &DiskGeometry->Geometry, sizeof(DISK_GEOMETRY));
|
memcpy(&SelectedDrive.Geometry, &DiskGeometry->Geometry, sizeof(DISK_GEOMETRY));
|
||||||
uprintf("Cylinders: %lld, TracksPerCylinder: %d, SectorsPerTrack: %d, BytesPerSector: %d\n",
|
uprintf("Sector Size: %d bytes\n", DiskGeometry->Geometry.BytesPerSector);
|
||||||
DiskGeometry->Geometry.Cylinders, DiskGeometry->Geometry.TracksPerCylinder,
|
uprintf("Cylinders: %lld, TracksPerCylinder: %d, SectorsPerTrack: %d\n",
|
||||||
DiskGeometry->Geometry.SectorsPerTrack, DiskGeometry->Geometry.BytesPerSector);
|
DiskGeometry->Geometry.Cylinders, DiskGeometry->Geometry.TracksPerCylinder, DiskGeometry->Geometry.SectorsPerTrack);
|
||||||
|
|
||||||
r = DeviceIoControl(hDrive, IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
|
r = DeviceIoControl(hDrive, IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
|
||||||
NULL, 0, layout, sizeof(layout), &size, NULL );
|
NULL, 0, layout, sizeof(layout), &size, NULL );
|
||||||
|
@ -389,28 +389,46 @@ static BOOL GetDriveInfo(void)
|
||||||
} else {
|
} else {
|
||||||
switch (DriveLayout->PartitionStyle) {
|
switch (DriveLayout->PartitionStyle) {
|
||||||
case PARTITION_STYLE_MBR:
|
case PARTITION_STYLE_MBR:
|
||||||
for (tmp_pos=0, i=0; (i<DriveLayout->PartitionCount)&&(tmp_pos>=0); i++) {
|
SelectedDrive.PartitionType = PT_MBR;
|
||||||
|
for (i=0; i<DriveLayout->PartitionCount; i++) {
|
||||||
if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) {
|
if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) {
|
||||||
nb_partitions++;
|
nb_partitions++;
|
||||||
uprintf("Partition %d:\n", i+1);
|
|
||||||
part_type = DriveLayout->PartitionEntry[i].Mbr.PartitionType;
|
|
||||||
uprintf(" Type: %s (0x%02x)\r\n Size: %s\r\n Boot: %s\r\n Recognized: %s\r\n Hidden Sectors: %d\n",
|
|
||||||
GetPartitionType(part_type), part_type, size_to_hr(DriveLayout->PartitionEntry[i].PartitionLength),
|
|
||||||
DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No",
|
|
||||||
DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No",
|
|
||||||
DriveLayout->PartitionEntry[i].Mbr.HiddenSectors);
|
|
||||||
tmp_pos = _snprintf(&tmp[tmp_pos], sizeof(tmp)-tmp_pos, "Partition %d: %s (%s)\n",
|
|
||||||
i+1, GetPartitionType(part_type), size_to_hr(DriveLayout->PartitionEntry[i].PartitionLength));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uprintf("Partition type: MBR, NB Partitions: %d\n", nb_partitions);
|
uprintf("Partition type: MBR, NB Partitions: %d\n", nb_partitions);
|
||||||
tmp[sizeof(tmp)-1] = 0;
|
uprintf("Disk ID: 0x%08X\n", DriveLayout->Mbr.Signature);
|
||||||
CreateTooltip(hPartition, tmp, -1);
|
for (i=0; i<DriveLayout->PartitionCount; i++) {
|
||||||
|
if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) {
|
||||||
|
uprintf("Partition %d:\n", DriveLayout->PartitionEntry[i].PartitionNumber);
|
||||||
|
part_type = DriveLayout->PartitionEntry[i].Mbr.PartitionType;
|
||||||
|
uprintf(" Type: %s (0x%02x)\r\n Size: %s (%lld bytes)\r\n Start Sector: %d, Boot: %s, Recognized: %s\n",
|
||||||
|
GetPartitionType(part_type), part_type, size_to_hr(DriveLayout->PartitionEntry[i].PartitionLength),
|
||||||
|
DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].Mbr.HiddenSectors,
|
||||||
|
DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No",
|
||||||
|
DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No");
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PARTITION_STYLE_GPT:
|
case PARTITION_STYLE_GPT:
|
||||||
|
SelectedDrive.PartitionType = PT_GPT;
|
||||||
uprintf("Partition type: GPT, NB Partitions: %d\n", DriveLayout->PartitionCount);
|
uprintf("Partition type: GPT, NB Partitions: %d\n", DriveLayout->PartitionCount);
|
||||||
|
uprintf("Disk GUID: %s\n", GuidToString(&DriveLayout->Gpt.DiskId));
|
||||||
|
uprintf("Max parts: %d, Start Offset: %lld, Usable = %lld bytes\n",
|
||||||
|
DriveLayout->Gpt.MaxPartitionCount, DriveLayout->Gpt.StartingUsableOffset.QuadPart, DriveLayout->Gpt.UsableLength.QuadPart);
|
||||||
|
for (i=0; i<DriveLayout->PartitionCount; i++) {
|
||||||
|
nb_partitions++;
|
||||||
|
tmp[0] = 0;
|
||||||
|
wchar_to_utf8_no_alloc(DriveLayout->PartitionEntry[i].Gpt.Name, tmp, sizeof(tmp));
|
||||||
|
uprintf("Partition %d:\r\n Type: %s\r\n Name: '%s'\n", DriveLayout->PartitionEntry[i].PartitionNumber,
|
||||||
|
GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionType), tmp);
|
||||||
|
uprintf(" ID: %s\r\n Size: %s (%lld bytes)\r\n Start Sector: %lld, Attributes: 0x%016llX\n",
|
||||||
|
GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionId), size_to_hr(DriveLayout->PartitionEntry[i].PartitionLength),
|
||||||
|
DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].StartingOffset.QuadPart / DiskGeometry->Geometry.BytesPerSector,
|
||||||
|
DriveLayout->PartitionEntry[i].Gpt.Attributes);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
SelectedDrive.PartitionType = PT_MBR;
|
||||||
uprintf("Partition type: RAW\n");
|
uprintf("Partition type: RAW\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -472,8 +490,8 @@ static void SetFSFromISO(void)
|
||||||
fs_mask |= 1<<fs;
|
fs_mask |= 1<<fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Syslinux has precedence over bootmgr
|
// Syslinux and EFI have precedence over bootmgr
|
||||||
if (iso_report.has_isolinux) {
|
if ((iso_report.has_isolinux) || (iso_report.has_efi)) {
|
||||||
if (fs_mask & (1<<FS_FAT32)) {
|
if (fs_mask & (1<<FS_FAT32)) {
|
||||||
selected_fs = FS_FAT32;
|
selected_fs = FS_FAT32;
|
||||||
} else if (fs_mask & (1<<FS_FAT16)) {
|
} else if (fs_mask & (1<<FS_FAT16)) {
|
||||||
|
@ -529,11 +547,11 @@ static BOOL PopulateProperties(int ComboIndex)
|
||||||
{
|
{
|
||||||
double HumanReadableSize;
|
double HumanReadableSize;
|
||||||
char capacity[64];
|
char capacity[64];
|
||||||
static char *suffix[] = { "B", "KB", "MB", "GB", "TB", "PB"};
|
static char* suffix[] = { "B", "KB", "MB", "GB", "TB", "PB"};
|
||||||
char no_label[] = STR_NO_LABEL;
|
char no_label[] = STR_NO_LABEL;
|
||||||
int i, fs;
|
int i, j, fs;
|
||||||
|
|
||||||
IGNORE_RETVAL(ComboBox_ResetContent(hPartition));
|
IGNORE_RETVAL(ComboBox_ResetContent(hPartitionScheme));
|
||||||
IGNORE_RETVAL(ComboBox_ResetContent(hFileSystem));
|
IGNORE_RETVAL(ComboBox_ResetContent(hFileSystem));
|
||||||
IGNORE_RETVAL(ComboBox_ResetContent(hClusterSize));
|
IGNORE_RETVAL(ComboBox_ResetContent(hClusterSize));
|
||||||
EnableWindow(GetDlgItem(hMainDialog, IDC_START), FALSE);
|
EnableWindow(GetDlgItem(hMainDialog, IDC_START), FALSE);
|
||||||
|
@ -554,12 +572,17 @@ static BOOL PopulateProperties(int ComboIndex)
|
||||||
for (i=1; i<ARRAYSIZE(suffix); i++) {
|
for (i=1; i<ARRAYSIZE(suffix); i++) {
|
||||||
HumanReadableSize /= 1024.0;
|
HumanReadableSize /= 1024.0;
|
||||||
if (HumanReadableSize < 512.0) {
|
if (HumanReadableSize < 512.0) {
|
||||||
safe_sprintf(capacity, sizeof(capacity), "MBR (1 Partition of %0.2f %s)", HumanReadableSize, suffix[i]);
|
for (j=0; j<PT_MAX; j++) {
|
||||||
|
safe_sprintf(capacity, sizeof(capacity), "%s (1 Partition of %0.2f %s)",
|
||||||
|
PartitionSchemeName[j], HumanReadableSize, suffix[i]);
|
||||||
|
IGNORE_RETVAL(ComboBox_SetItemData(hPartitionScheme, ComboBox_AddStringU(hPartitionScheme, capacity), j));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IGNORE_RETVAL(ComboBox_AddStringU(hPartition, capacity));
|
if (i >= ARRAYSIZE(suffix))
|
||||||
IGNORE_RETVAL(ComboBox_SetCurSel(hPartition, 0));
|
uprintf("Could not populate partition scheme data\n");
|
||||||
|
IGNORE_RETVAL(ComboBox_SetCurSel(hPartitionScheme, SelectedDrive.PartitionType));
|
||||||
CreateTooltip(hDeviceList, DriveID.Table[ComboIndex], -1);
|
CreateTooltip(hDeviceList, DriveID.Table[ComboIndex], -1);
|
||||||
|
|
||||||
// Set a proposed label according to the size (eg: "256MB", "8GB")
|
// Set a proposed label according to the size (eg: "256MB", "8GB")
|
||||||
|
@ -604,33 +627,78 @@ typedef struct _DRIVE_LAYOUT_INFORMATION_EX4 {
|
||||||
/*
|
/*
|
||||||
* Create a partition table
|
* Create a partition table
|
||||||
*/
|
*/
|
||||||
|
// See http://technet.microsoft.com/en-us/library/cc739412.aspx for some background info
|
||||||
|
#if !defined(PARTITION_BASIC_DATA_GUID)
|
||||||
|
const GUID PARTITION_BASIC_DATA_GUID = { 0xebd0a0a2, 0xb9e5, 0x4433, {0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7} };
|
||||||
|
#endif
|
||||||
BOOL CreatePartition(HANDLE hDrive)
|
BOOL CreatePartition(HANDLE hDrive)
|
||||||
{
|
{
|
||||||
|
CREATE_DISK CreateDisk = {PARTITION_STYLE_RAW, {0}};
|
||||||
DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = {0};
|
DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = {0};
|
||||||
BOOL r;
|
BOOL r;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
LONGLONG sector_size;
|
LONGLONG size_in_sectors;
|
||||||
|
int pt = (int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme));
|
||||||
|
|
||||||
|
PrintStatus(0, TRUE, "Partitioning (%s)...", PartitionSchemeName[pt]);
|
||||||
|
|
||||||
|
if ((pt == PT_GPT) || (!IsChecked(IDC_EXTRA_PARTITION))) {
|
||||||
|
// Go with the MS 1 MB wastage at the beginning...
|
||||||
|
DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart = 1024*1024;
|
||||||
|
} else {
|
||||||
|
// Align on Cylinder
|
||||||
|
DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart =
|
||||||
|
SelectedDrive.Geometry.BytesPerSector * SelectedDrive.Geometry.SectorsPerTrack;
|
||||||
|
}
|
||||||
|
size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart) / SelectedDrive.Geometry.BytesPerSector;
|
||||||
|
|
||||||
|
switch (pt) {
|
||||||
|
case PT_MBR:
|
||||||
|
CreateDisk.PartitionStyle = PARTITION_STYLE_MBR;
|
||||||
|
CreateDisk.Mbr.Signature = GetTickCount();
|
||||||
|
|
||||||
PrintStatus(0, TRUE, "Partitioning...");
|
|
||||||
DriveLayoutEx.PartitionStyle = PARTITION_STYLE_MBR;
|
DriveLayoutEx.PartitionStyle = PARTITION_STYLE_MBR;
|
||||||
DriveLayoutEx.PartitionCount = 4; // Must be multiple of 4 for MBR
|
DriveLayoutEx.PartitionCount = 4; // Must be multiple of 4 for MBR
|
||||||
DriveLayoutEx.Type.Mbr.Signature = GetTickCount();
|
DriveLayoutEx.Type.Mbr.Signature = CreateDisk.Mbr.Signature;
|
||||||
DriveLayoutEx.PartitionEntry[0].PartitionStyle = PARTITION_STYLE_MBR;
|
DriveLayoutEx.PartitionEntry[0].PartitionStyle = PARTITION_STYLE_MBR;
|
||||||
// TODO: CHS fixup (32 sectors/track) through a cheat mode, if requested
|
// TODO: CHS fixup (32 sectors/track) through a cheat mode, if requested
|
||||||
// NB: disk geometry is computed by BIOS & co. by finding a match between LBA and CHS value of first partition
|
// NB: disk geometry is computed by BIOS & co. by finding a match between LBA and CHS value of first partition
|
||||||
// ms-sys's write_partition_number_of_heads() and write_partition_start_sector_number() can be used if needed
|
// ms-sys's write_partition_number_of_heads() and write_partition_start_sector_number() can be used if needed
|
||||||
|
|
||||||
DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart =
|
|
||||||
SelectedDrive.Geometry.BytesPerSector * SelectedDrive.Geometry.SectorsPerTrack;
|
|
||||||
sector_size = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart) / SelectedDrive.Geometry.BytesPerSector;
|
|
||||||
// Align on sector boundary if the extra part option is checked
|
// Align on sector boundary if the extra part option is checked
|
||||||
if (IsChecked(IDC_EXTRA_PARTITION)) {
|
if (IsChecked(IDC_EXTRA_PARTITION)) {
|
||||||
sector_size = ((sector_size / SelectedDrive.Geometry.SectorsPerTrack)-1) * SelectedDrive.Geometry.SectorsPerTrack;
|
size_in_sectors = ((size_in_sectors / SelectedDrive.Geometry.SectorsPerTrack)-1) * SelectedDrive.Geometry.SectorsPerTrack;
|
||||||
if (sector_size <= 0) return FALSE;
|
if (size_in_sectors <= 0)
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
DriveLayoutEx.PartitionEntry[0].PartitionLength.QuadPart = sector_size * SelectedDrive.Geometry.BytesPerSector;
|
break;
|
||||||
|
case PT_GPT:
|
||||||
|
CreateDisk.PartitionStyle = PARTITION_STYLE_GPT;
|
||||||
|
IGNORE_RETVAL(CoCreateGuid(&CreateDisk.Gpt.DiskId));
|
||||||
|
CreateDisk.Gpt.MaxPartitionCount = MAX_GPT_PARTITIONS;
|
||||||
|
|
||||||
|
DriveLayoutEx.PartitionStyle = PARTITION_STYLE_GPT;
|
||||||
|
DriveLayoutEx.PartitionCount = 1;
|
||||||
|
// At the very least, a GPT disk has atv least 34 reserved (512 bytes) blocks at the beginning
|
||||||
|
// and 33 at the end.
|
||||||
|
DriveLayoutEx.Type.Gpt.StartingUsableOffset.QuadPart = 34*512;
|
||||||
|
DriveLayoutEx.Type.Gpt.UsableLength.QuadPart = SelectedDrive.DiskSize - (34+33)*512;
|
||||||
|
DriveLayoutEx.Type.Gpt.MaxPartitionCount = MAX_GPT_PARTITIONS;
|
||||||
|
DriveLayoutEx.Type.Gpt.DiskId = CreateDisk.Gpt.DiskId;
|
||||||
|
DriveLayoutEx.PartitionEntry[0].PartitionStyle = PARTITION_STYLE_GPT;
|
||||||
|
|
||||||
|
size_in_sectors -= 33; // Need 33 sectors at the end for secondary GPT
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DriveLayoutEx.PartitionEntry[0].PartitionLength.QuadPart = size_in_sectors * SelectedDrive.Geometry.BytesPerSector;
|
||||||
DriveLayoutEx.PartitionEntry[0].PartitionNumber = 1;
|
DriveLayoutEx.PartitionEntry[0].PartitionNumber = 1;
|
||||||
DriveLayoutEx.PartitionEntry[0].RewritePartition = TRUE;
|
DriveLayoutEx.PartitionEntry[0].RewritePartition = TRUE;
|
||||||
|
|
||||||
|
switch (pt) {
|
||||||
|
case PT_MBR:
|
||||||
DriveLayoutEx.PartitionEntry[0].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack;
|
DriveLayoutEx.PartitionEntry[0].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack;
|
||||||
switch (ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem))) {
|
switch (ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem))) {
|
||||||
case FS_FAT16:
|
case FS_FAT16:
|
||||||
|
@ -647,7 +715,6 @@ BOOL CreatePartition(HANDLE hDrive)
|
||||||
uprintf("Unsupported file system\n");
|
uprintf("Unsupported file system\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an extra partition on request - can improve BIOS detection as HDD for older BIOSes
|
// Create an extra partition on request - can improve BIOS detection as HDD for older BIOSes
|
||||||
if (IsChecked(IDC_EXTRA_PARTITION)) {
|
if (IsChecked(IDC_EXTRA_PARTITION)) {
|
||||||
DriveLayoutEx.PartitionEntry[1].PartitionStyle = PARTITION_STYLE_MBR;
|
DriveLayoutEx.PartitionEntry[1].PartitionStyle = PARTITION_STYLE_MBR;
|
||||||
|
@ -660,12 +727,31 @@ BOOL CreatePartition(HANDLE hDrive)
|
||||||
DriveLayoutEx.PartitionEntry[1].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack*SelectedDrive.Geometry.BytesPerSector;
|
DriveLayoutEx.PartitionEntry[1].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack*SelectedDrive.Geometry.BytesPerSector;
|
||||||
DriveLayoutEx.PartitionEntry[1].Mbr.PartitionType = DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType + 0x10; // Hidden whatever
|
DriveLayoutEx.PartitionEntry[1].Mbr.PartitionType = DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType + 0x10; // Hidden whatever
|
||||||
}
|
}
|
||||||
|
|
||||||
// For the remaining partitions, PartitionStyle & PartitionType have already
|
// For the remaining partitions, PartitionStyle & PartitionType have already
|
||||||
// been zeroed => set to MBR/unused
|
// been zeroed => already set to MBR/unused
|
||||||
|
break;
|
||||||
|
case PT_GPT:
|
||||||
|
DriveLayoutEx.PartitionEntry[0].Gpt.PartitionType = PARTITION_BASIC_DATA_GUID;
|
||||||
|
wcscpy(DriveLayoutEx.PartitionEntry[0].Gpt.Name, L"Microsoft Basic Data");
|
||||||
|
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[0].Gpt.PartitionId));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If you don't call IOCTL_DISK_CREATE_DISK, the next call will fail
|
||||||
|
size = sizeof(CreateDisk);
|
||||||
|
r = DeviceIoControl(hDrive, IOCTL_DISK_CREATE_DISK,
|
||||||
|
(BYTE*)&CreateDisk, size, NULL, 0, &size, NULL );
|
||||||
|
if (!r) {
|
||||||
|
uprintf("IOCTL_DISK_CREATE_DISK failed: %s\n", WindowsErrorString());
|
||||||
|
safe_closehandle(hDrive);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = sizeof(DriveLayoutEx) - ((pt == PT_GPT)?(3*sizeof(PARTITION_INFORMATION_EX)):0);
|
||||||
r = DeviceIoControl(hDrive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX,
|
r = DeviceIoControl(hDrive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX,
|
||||||
(BYTE*)&DriveLayoutEx, sizeof(DriveLayoutEx), NULL, 0, &size, NULL );
|
(BYTE*)&DriveLayoutEx, size, NULL, 0, &size, NULL );
|
||||||
if (!r) {
|
if (!r) {
|
||||||
uprintf("IOCTL_DISK_SET_DRIVE_LAYOUT_EX failed: %s\n", WindowsErrorString());
|
uprintf("IOCTL_DISK_SET_DRIVE_LAYOUT_EX failed: %s\n", WindowsErrorString());
|
||||||
safe_closehandle(hDrive);
|
safe_closehandle(hDrive);
|
||||||
|
@ -1072,7 +1158,7 @@ static void EnableControls(BOOL bEnable)
|
||||||
int fs;
|
int fs;
|
||||||
|
|
||||||
EnableWindow(GetDlgItem(hMainDialog, IDC_DEVICE), bEnable);
|
EnableWindow(GetDlgItem(hMainDialog, IDC_DEVICE), bEnable);
|
||||||
EnableWindow(GetDlgItem(hMainDialog, IDC_PARTITION), bEnable);
|
EnableWindow(GetDlgItem(hMainDialog, IDC_PARTITION_SCHEME), bEnable);
|
||||||
EnableWindow(GetDlgItem(hMainDialog, IDC_FILESYSTEM), bEnable);
|
EnableWindow(GetDlgItem(hMainDialog, IDC_FILESYSTEM), bEnable);
|
||||||
EnableWindow(GetDlgItem(hMainDialog, IDC_CLUSTERSIZE), bEnable);
|
EnableWindow(GetDlgItem(hMainDialog, IDC_CLUSTERSIZE), bEnable);
|
||||||
EnableWindow(GetDlgItem(hMainDialog, IDC_LABEL), bEnable);
|
EnableWindow(GetDlgItem(hMainDialog, IDC_LABEL), bEnable);
|
||||||
|
@ -1268,8 +1354,8 @@ DWORD WINAPI ISOScanThread(LPVOID param)
|
||||||
safe_free(iso_path);
|
safe_free(iso_path);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
uprintf("ISO label: '%s'\r\n Size: %lld bytes\r\n Has a >4GB file: %s\r\n Uses Bootmgr: %s\r\n Uses WinPE: %s%s\r\n Uses isolinux: %s\n",
|
uprintf("ISO label: '%s'\r\n Size: %lld bytes\r\n Has a >4GB file: %s\r\n Uses EFI: %s\r\n Uses Bootmgr: %s\r\n Uses WinPE: %s%s\r\n Uses isolinux: %s\n",
|
||||||
iso_report.label, iso_report.projected_size, iso_report.has_4GB_file?"Yes":"No", iso_report.has_bootmgr?"Yes":"No",
|
iso_report.label, iso_report.projected_size, iso_report.has_4GB_file?"Yes":"No", iso_report.has_efi?"Yes":"No", iso_report.has_bootmgr?"Yes":"No",
|
||||||
IS_WINPE(iso_report.winpe)?"Yes":"No", (iso_report.uses_minint)?" (with /minint)":"", iso_report.has_isolinux?"Yes":"No");
|
IS_WINPE(iso_report.winpe)?"Yes":"No", (iso_report.uses_minint)?" (with /minint)":"", iso_report.has_isolinux?"Yes":"No");
|
||||||
if (iso_report.has_isolinux) {
|
if (iso_report.has_isolinux) {
|
||||||
for (i=0; i<NB_OLD_C32; i++) {
|
for (i=0; i<NB_OLD_C32; i++) {
|
||||||
|
@ -1404,7 +1490,7 @@ void InitDialog(HWND hDlg)
|
||||||
// Quite a burden to carry around as parameters
|
// Quite a burden to carry around as parameters
|
||||||
hMainDialog = hDlg;
|
hMainDialog = hDlg;
|
||||||
hDeviceList = GetDlgItem(hDlg, IDC_DEVICE);
|
hDeviceList = GetDlgItem(hDlg, IDC_DEVICE);
|
||||||
hPartition = GetDlgItem(hDlg, IDC_PARTITION);
|
hPartitionScheme = GetDlgItem(hDlg, IDC_PARTITION_SCHEME);
|
||||||
hFileSystem = GetDlgItem(hDlg, IDC_FILESYSTEM);
|
hFileSystem = GetDlgItem(hDlg, IDC_FILESYSTEM);
|
||||||
hClusterSize = GetDlgItem(hDlg, IDC_CLUSTERSIZE);
|
hClusterSize = GetDlgItem(hDlg, IDC_CLUSTERSIZE);
|
||||||
hLabel = GetDlgItem(hDlg, IDC_LABEL);
|
hLabel = GetDlgItem(hDlg, IDC_LABEL);
|
||||||
|
@ -1549,7 +1635,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
DRAWITEMSTRUCT* pDI;
|
DRAWITEMSTRUCT* pDI;
|
||||||
POINT Point;
|
POINT Point;
|
||||||
RECT DialogRect, DesktopRect;
|
RECT DialogRect, DesktopRect;
|
||||||
int nDeviceIndex, fs, i, nWidth, nHeight;
|
int nDeviceIndex, fs, pt, i, nWidth, nHeight;
|
||||||
static DWORD DeviceNum = 0;
|
static DWORD DeviceNum = 0;
|
||||||
wchar_t wtmp[128], wstr[MAX_PATH];
|
wchar_t wtmp[128], wstr[MAX_PATH];
|
||||||
static UINT uDOSChecked = BST_CHECKED, uQFChecked;
|
static UINT uDOSChecked = BST_CHECKED, uQFChecked;
|
||||||
|
@ -1694,10 +1780,12 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IDC_PARTITION_SCHEME:
|
||||||
case IDC_FILESYSTEM:
|
case IDC_FILESYSTEM:
|
||||||
if (HIWORD(wParam) != CBN_SELCHANGE)
|
if (HIWORD(wParam) != CBN_SELCHANGE)
|
||||||
break;
|
break;
|
||||||
fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
|
fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
|
||||||
|
pt = (int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme));
|
||||||
SetClusterSizes(fs);
|
SetClusterSizes(fs);
|
||||||
// Disable/restore the quick format control depending on large FAT32
|
// Disable/restore the quick format control depending on large FAT32
|
||||||
if ((fs == FS_FAT32) && (SelectedDrive.DiskSize > LARGE_FAT32_SIZE)) {
|
if ((fs == FS_FAT32) && (SelectedDrive.DiskSize > LARGE_FAT32_SIZE)) {
|
||||||
|
@ -1722,7 +1810,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (fs == FS_EXFAT) {
|
if ((fs == FS_EXFAT) || ((pt == PT_GPT) && (fs == FS_NTFS))) {
|
||||||
if (IsWindowEnabled(hDOS)) {
|
if (IsWindowEnabled(hDOS)) {
|
||||||
// unlikely to be supported by BIOSes => don't bother
|
// unlikely to be supported by BIOSes => don't bother
|
||||||
IGNORE_RETVAL(ComboBox_SetCurSel(hDOSType, 0));
|
IGNORE_RETVAL(ComboBox_SetCurSel(hDOSType, 0));
|
||||||
|
@ -1734,13 +1822,13 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
IGNORE_RETVAL(ComboBox_ResetContent(hDOSType));
|
IGNORE_RETVAL(ComboBox_ResetContent(hDOSType));
|
||||||
if ((fs == FS_FAT16) || (fs == FS_FAT32)) {
|
if ((pt == PT_MBR) && ((fs == FS_FAT16) || (fs == FS_FAT32))) {
|
||||||
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "MS-DOS"), DT_WINME));
|
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "MS-DOS"), DT_WINME));
|
||||||
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "FreeDOS"), DT_FREEDOS));
|
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "FreeDOS"), DT_FREEDOS));
|
||||||
}
|
}
|
||||||
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "ISO Image"), DT_ISO));
|
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "ISO Image"), DT_ISO));
|
||||||
// If needed (advanced mode) also append a Syslinux option
|
// If needed (advanced mode) also append a Syslinux option
|
||||||
if ( ((fs == FS_FAT16) || (fs == FS_FAT32)) && (advanced_mode) )
|
if ( (pt == PT_MBR) && (((fs == FS_FAT16) || (fs == FS_FAT32)) && (advanced_mode)) )
|
||||||
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "SysLinux"), DT_SYSLINUX));
|
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "SysLinux"), DT_SYSLINUX));
|
||||||
if ( ((!advanced_mode) && (selection_default == DT_SYSLINUX)) ) {
|
if ( ((!advanced_mode) && (selection_default == DT_SYSLINUX)) ) {
|
||||||
selection_default = DT_FREEDOS;
|
selection_default = DT_FREEDOS;
|
||||||
|
@ -1833,7 +1921,13 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
|
fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
|
||||||
if ((fs == FS_NTFS) && (!iso_report.has_bootmgr) && (!IS_WINPE(iso_report.winpe))) {
|
pt = (int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme));
|
||||||
|
if ((pt == PT_GPT) && ((!iso_report.has_efi) || ((fs > FS_FAT32)))) {
|
||||||
|
MessageBoxA(hMainDialog, "When using GPT, only EFI bootable ISOs are supported. "
|
||||||
|
"Please select an EFI bootable ISO or change the Partition Scheme to MBR.", "Unsupported GPT ISO...", MB_OK|MB_ICONERROR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ((fs == FS_NTFS) && (!iso_report.has_bootmgr) && (!IS_WINPE(iso_report.winpe))) {
|
||||||
if (iso_report.has_isolinux) {
|
if (iso_report.has_isolinux) {
|
||||||
MessageBoxA(hMainDialog, "Only FAT32 is supported for this type of ISO. "
|
MessageBoxA(hMainDialog, "Only FAT32 is supported for this type of ISO. "
|
||||||
"Please revert the filesystem back from NTFS to FAT32.", "Unsupported filesystem...", MB_OK|MB_ICONERROR);
|
"Please revert the filesystem back from NTFS to FAT32.", "Unsupported filesystem...", MB_OK|MB_ICONERROR);
|
||||||
|
@ -1842,7 +1936,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
"images can currently be used with NTFS.", "Unsupported ISO...", MB_OK|MB_ICONERROR);
|
"images can currently be used with NTFS.", "Unsupported ISO...", MB_OK|MB_ICONERROR);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && (!iso_report.has_isolinux)) {
|
} else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && ((!iso_report.has_isolinux) && (pt != PT_GPT))) {
|
||||||
MessageBoxA(hMainDialog, "Only 'isolinux' based ISO "
|
MessageBoxA(hMainDialog, "Only 'isolinux' based ISO "
|
||||||
"images can currently be used with FAT.", "Unsupported ISO...", MB_OK|MB_ICONERROR);
|
"images can currently be used with FAT.", "Unsupported ISO...", MB_OK|MB_ICONERROR);
|
||||||
break;
|
break;
|
||||||
|
|
14
src/rufus.h
14
src/rufus.h
|
@ -42,6 +42,9 @@
|
||||||
#define MAX_TOOLTIPS 32
|
#define MAX_TOOLTIPS 32
|
||||||
#define MAX_PROGRESS (0xFFFF-1) // leave room for 1 more for insta-progress workaround
|
#define MAX_PROGRESS (0xFFFF-1) // leave room for 1 more for insta-progress workaround
|
||||||
#define MAX_LOG_SIZE 0x7FFFFFFE
|
#define MAX_LOG_SIZE 0x7FFFFFFE
|
||||||
|
#define MAX_GUID_STRING_LENGTH 40
|
||||||
|
#define MAX_GPT_PARTITIONS 128
|
||||||
|
#define MAX_SECTORS_TO_CLEAR 128 // nb sectors to zap when clearing the MBR/GPT (must be >34)
|
||||||
#define PROPOSEDLABEL_TOLERANCE 0.10
|
#define PROPOSEDLABEL_TOLERANCE 0.10
|
||||||
#define FS_DEFAULT FS_FAT32
|
#define FS_DEFAULT FS_FAT32
|
||||||
#define LARGE_FAT32_SIZE (32*1073741824LL) // Size at which we need to use fat32format
|
#define LARGE_FAT32_SIZE (32*1073741824LL) // Size at which we need to use fat32format
|
||||||
|
@ -147,6 +150,12 @@ enum dos_type {
|
||||||
DT_MAX
|
DT_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum part_type {
|
||||||
|
PT_MBR = 0,
|
||||||
|
PT_GPT,
|
||||||
|
PT_MAX
|
||||||
|
};
|
||||||
|
|
||||||
/* Current drive info */
|
/* Current drive info */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DWORD DeviceNumber;
|
DWORD DeviceNumber;
|
||||||
|
@ -154,6 +163,7 @@ typedef struct {
|
||||||
DISK_GEOMETRY Geometry;
|
DISK_GEOMETRY Geometry;
|
||||||
DWORD FirstSector;
|
DWORD FirstSector;
|
||||||
char proposed_label[16];
|
char proposed_label[16];
|
||||||
|
int PartitionType;
|
||||||
int FSType;
|
int FSType;
|
||||||
struct {
|
struct {
|
||||||
ULONG Allowed;
|
ULONG Allowed;
|
||||||
|
@ -180,6 +190,7 @@ typedef struct {
|
||||||
uint8_t winpe;
|
uint8_t winpe;
|
||||||
BOOL has_4GB_file;
|
BOOL has_4GB_file;
|
||||||
BOOL has_bootmgr;
|
BOOL has_bootmgr;
|
||||||
|
BOOL has_efi;
|
||||||
BOOL has_isolinux;
|
BOOL has_isolinux;
|
||||||
BOOL has_autorun;
|
BOOL has_autorun;
|
||||||
BOOL has_old_c32[NB_OLD_C32];
|
BOOL has_old_c32[NB_OLD_C32];
|
||||||
|
@ -221,7 +232,7 @@ enum WindowsVersion {
|
||||||
*/
|
*/
|
||||||
extern HINSTANCE hMainInstance;
|
extern HINSTANCE hMainInstance;
|
||||||
extern HWND hMainDialog, hLogDlg, hStatus, hDeviceList, hCapacity;
|
extern HWND hMainDialog, hLogDlg, hStatus, hDeviceList, hCapacity;
|
||||||
extern HWND hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses, hLog;
|
extern HWND hPartitionScheme, hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses, hLog;
|
||||||
extern HWND hISOProgressDlg, hISOProgressBar, hISOFileName, hDiskID;
|
extern HWND hISOProgressDlg, hISOProgressBar, hISOFileName, hDiskID;
|
||||||
extern float fScale;
|
extern float fScale;
|
||||||
extern char szFolderPath[MAX_PATH], app_dir[MAX_PATH];
|
extern char szFolderPath[MAX_PATH], app_dir[MAX_PATH];
|
||||||
|
@ -246,6 +257,7 @@ extern void DumpBufferHex(void *buf, size_t size);
|
||||||
extern void PrintStatus(unsigned int duration, BOOL debug, const char *format, ...);
|
extern void PrintStatus(unsigned int duration, BOOL debug, const char *format, ...);
|
||||||
extern void UpdateProgress(int op, float percent);
|
extern void UpdateProgress(int op, float percent);
|
||||||
extern const char* StrError(DWORD error_code);
|
extern const char* StrError(DWORD error_code);
|
||||||
|
extern char* GuidToString(const GUID* guid);
|
||||||
extern void CenterDialog(HWND hDlg);
|
extern void CenterDialog(HWND hDlg);
|
||||||
extern void CreateStatusBar(void);
|
extern void CreateStatusBar(void);
|
||||||
extern void SetTitleBarIcon(HWND hDlg);
|
extern void SetTitleBarIcon(HWND hDlg);
|
||||||
|
|
12
src/rufus.rc
12
src/rufus.rc
|
@ -30,7 +30,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
||||||
IDD_DIALOG DIALOGEX 12, 12, 206, 316
|
IDD_DIALOG DIALOGEX 12, 12, 206, 316
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
EXSTYLE WS_EX_APPWINDOW
|
EXSTYLE WS_EX_APPWINDOW
|
||||||
CAPTION "Rufus v1.3.1.222"
|
CAPTION "Rufus v1.3.1.223"
|
||||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "Start",IDC_START,94,278,50,14
|
DEFPUSHBUTTON "Start",IDC_START,94,278,50,14
|
||||||
|
@ -39,7 +39,7 @@ BEGIN
|
||||||
CONTROL "Device",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,9,6,22,8
|
CONTROL "Device",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,9,6,22,8
|
||||||
COMBOBOX IDC_FILESYSTEM,8,75,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_FILESYSTEM,8,75,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||||
LTEXT "File system",IDC_STATIC,9,64,51,10
|
LTEXT "File system",IDC_STATIC,9,64,51,10
|
||||||
COMBOBOX IDC_PARTITION,8,46,190,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_PARTITION_SCHEME,8,46,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||||
LTEXT "Partition Scheme",IDC_STATIC,9,35,75,8
|
LTEXT "Partition Scheme",IDC_STATIC,9,35,75,8
|
||||||
COMBOBOX IDC_CLUSTERSIZE,8,104,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_CLUSTERSIZE,8,104,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||||
LTEXT "Cluster size",IDC_STATIC,9,93,105,10
|
LTEXT "Cluster size",IDC_STATIC,9,93,105,10
|
||||||
|
@ -274,8 +274,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,3,1,222
|
FILEVERSION 1,3,1,223
|
||||||
PRODUCTVERSION 1,3,1,222
|
PRODUCTVERSION 1,3,1,223
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -292,13 +292,13 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "1.3.1.222"
|
VALUE "FileVersion", "1.3.1.223"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "(c) 2011-2012 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "(c) 2011-2012 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
||||||
VALUE "OriginalFilename", "rufus.exe"
|
VALUE "OriginalFilename", "rufus.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "1.3.1.222"
|
VALUE "ProductVersion", "1.3.1.223"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
12
src/stdio.c
12
src/stdio.c
|
@ -177,6 +177,18 @@ void PrintStatus(unsigned int duration, BOOL debug, const char *format, ...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* GuidToString(const GUID* guid)
|
||||||
|
{
|
||||||
|
static char guid_string[MAX_GUID_STRING_LENGTH];
|
||||||
|
|
||||||
|
if (guid == NULL) return NULL;
|
||||||
|
sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
|
||||||
|
(unsigned int)guid->Data1, guid->Data2, guid->Data3,
|
||||||
|
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
|
||||||
|
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
|
||||||
|
return guid_string;
|
||||||
|
}
|
||||||
|
|
||||||
const char* StrError(DWORD error_code)
|
const char* StrError(DWORD error_code)
|
||||||
{
|
{
|
||||||
if ( (!IS_ERROR(error_code)) || (SCODE_CODE(error_code) == ERROR_SUCCESS)) {
|
if ( (!IS_ERROR(error_code)) || (SCODE_CODE(error_code) == ERROR_SUCCESS)) {
|
||||||
|
|
Loading…
Reference in a new issue