1
1
Fork 0
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:
Pete Batard 2013-01-18 01:39:24 +00:00
parent 6b8833bcfb
commit 997c0a0f28
8 changed files with 257 additions and 114 deletions

View file

@ -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,20 +743,29 @@ 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
goto out; // 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;
}
}
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;
@ -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,14 +1208,14 @@ 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;
} }
UpdateProgress(OP_ZERO_MBR, -1.0f); UpdateProgress(OP_ZERO_MBR, -1.0f);
if (!CreatePartition(hPhysicalDrive)) { if (!CreatePartition(hPhysicalDrive)) {
@ -1227,16 +1237,25 @@ DWORD WINAPI FormatThread(LPVOID param)
goto out; goto out;
} }
PrintStatus(0, TRUE, "Writing master boot record..."); if (pt == PT_MBR) {
if (!WriteMBR(hPhysicalDrive)) { PrintStatus(0, TRUE, "Writing master boot record...");
if (!FormatStatus) if (!WriteMBR(hPhysicalDrive)) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; if (!FormatStatus)
goto out; FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT;
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);

View file

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

View file

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

View file

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

View file

@ -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,68 +627,131 @@ 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..."); PrintStatus(0, TRUE, "Partitioning (%s)...", PartitionSchemeName[pt]);
DriveLayoutEx.PartitionStyle = PARTITION_STYLE_MBR;
DriveLayoutEx.PartitionCount = 4; // Must be multiple of 4 for MBR
DriveLayoutEx.Type.Mbr.Signature = GetTickCount();
DriveLayoutEx.PartitionEntry[0].PartitionStyle = PARTITION_STYLE_MBR;
// 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
// ms-sys's write_partition_number_of_heads() and write_partition_start_sector_number() can be used if needed
DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart = if ((pt == PT_GPT) || (!IsChecked(IDC_EXTRA_PARTITION))) {
SelectedDrive.Geometry.BytesPerSector * SelectedDrive.Geometry.SectorsPerTrack; // Go with the MS 1 MB wastage at the beginning...
sector_size = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart) / SelectedDrive.Geometry.BytesPerSector; DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart = 1024*1024;
// Align on sector boundary if the extra part option is checked } else {
if (IsChecked(IDC_EXTRA_PARTITION)) { // Align on Cylinder
sector_size = ((sector_size / SelectedDrive.Geometry.SectorsPerTrack)-1) * SelectedDrive.Geometry.SectorsPerTrack; DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart =
if (sector_size <= 0) return FALSE; SelectedDrive.Geometry.BytesPerSector * SelectedDrive.Geometry.SectorsPerTrack;
} }
DriveLayoutEx.PartitionEntry[0].PartitionLength.QuadPart = sector_size * SelectedDrive.Geometry.BytesPerSector; size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart) / SelectedDrive.Geometry.BytesPerSector;
DriveLayoutEx.PartitionEntry[0].PartitionNumber = 1;
DriveLayoutEx.PartitionEntry[0].RewritePartition = TRUE; switch (pt) {
DriveLayoutEx.PartitionEntry[0].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack; case PT_MBR:
switch (ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem))) { CreateDisk.PartitionStyle = PARTITION_STYLE_MBR;
case FS_FAT16: CreateDisk.Mbr.Signature = GetTickCount();
DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType = 0x0e; // FAT16 LBA
DriveLayoutEx.PartitionStyle = PARTITION_STYLE_MBR;
DriveLayoutEx.PartitionCount = 4; // Must be multiple of 4 for MBR
DriveLayoutEx.Type.Mbr.Signature = CreateDisk.Mbr.Signature;
DriveLayoutEx.PartitionEntry[0].PartitionStyle = PARTITION_STYLE_MBR;
// 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
// ms-sys's write_partition_number_of_heads() and write_partition_start_sector_number() can be used if needed
// Align on sector boundary if the extra part option is checked
if (IsChecked(IDC_EXTRA_PARTITION)) {
size_in_sectors = ((size_in_sectors / SelectedDrive.Geometry.SectorsPerTrack)-1) * SelectedDrive.Geometry.SectorsPerTrack;
if (size_in_sectors <= 0)
return FALSE;
}
break; break;
case FS_NTFS: case PT_GPT:
case FS_EXFAT: CreateDisk.PartitionStyle = PARTITION_STYLE_GPT;
DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType = 0x07; // NTFS IGNORE_RETVAL(CoCreateGuid(&CreateDisk.Gpt.DiskId));
break; CreateDisk.Gpt.MaxPartitionCount = MAX_GPT_PARTITIONS;
case FS_FAT32:
DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType = 0x0c; // FAT32 LBA 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; break;
default: default:
uprintf("Unsupported file system\n"); break;
}
DriveLayoutEx.PartitionEntry[0].PartitionLength.QuadPart = size_in_sectors * SelectedDrive.Geometry.BytesPerSector;
DriveLayoutEx.PartitionEntry[0].PartitionNumber = 1;
DriveLayoutEx.PartitionEntry[0].RewritePartition = TRUE;
switch (pt) {
case PT_MBR:
DriveLayoutEx.PartitionEntry[0].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack;
switch (ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem))) {
case FS_FAT16:
DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType = 0x0e; // FAT16 LBA
break;
case FS_NTFS:
case FS_EXFAT:
DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType = 0x07; // NTFS
break;
case FS_FAT32:
DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType = 0x0c; // FAT32 LBA
break;
default:
uprintf("Unsupported file system\n");
return FALSE;
}
// Create an extra partition on request - can improve BIOS detection as HDD for older BIOSes
if (IsChecked(IDC_EXTRA_PARTITION)) {
DriveLayoutEx.PartitionEntry[1].PartitionStyle = PARTITION_STYLE_MBR;
// Should end on a sector boundary
DriveLayoutEx.PartitionEntry[1].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart +
DriveLayoutEx.PartitionEntry[0].PartitionLength.QuadPart;
DriveLayoutEx.PartitionEntry[1].PartitionLength.QuadPart = SelectedDrive.Geometry.SectorsPerTrack*SelectedDrive.Geometry.BytesPerSector;
DriveLayoutEx.PartitionEntry[1].PartitionNumber = 2;
DriveLayoutEx.PartitionEntry[1].RewritePartition = TRUE;
DriveLayoutEx.PartitionEntry[1].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack*SelectedDrive.Geometry.BytesPerSector;
DriveLayoutEx.PartitionEntry[1].Mbr.PartitionType = DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType + 0x10; // Hidden whatever
}
// For the remaining partitions, PartitionStyle & PartitionType have already
// 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; return FALSE;
} }
// Create an extra partition on request - can improve BIOS detection as HDD for older BIOSes size = sizeof(DriveLayoutEx) - ((pt == PT_GPT)?(3*sizeof(PARTITION_INFORMATION_EX)):0);
if (IsChecked(IDC_EXTRA_PARTITION)) { r = DeviceIoControl(hDrive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX,
DriveLayoutEx.PartitionEntry[1].PartitionStyle = PARTITION_STYLE_MBR; (BYTE*)&DriveLayoutEx, size, NULL, 0, &size, NULL );
// Should end on a sector boundary
DriveLayoutEx.PartitionEntry[1].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart +
DriveLayoutEx.PartitionEntry[0].PartitionLength.QuadPart;
DriveLayoutEx.PartitionEntry[1].PartitionLength.QuadPart = SelectedDrive.Geometry.SectorsPerTrack*SelectedDrive.Geometry.BytesPerSector;
DriveLayoutEx.PartitionEntry[1].PartitionNumber = 2;
DriveLayoutEx.PartitionEntry[1].RewritePartition = TRUE;
DriveLayoutEx.PartitionEntry[1].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack*SelectedDrive.Geometry.BytesPerSector;
DriveLayoutEx.PartitionEntry[1].Mbr.PartitionType = DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType + 0x10; // Hidden whatever
}
// For the remaining partitions, PartitionStyle & PartitionType have already
// been zeroed => set to MBR/unused
r = DeviceIoControl(hDrive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX,
(BYTE*)&DriveLayoutEx, sizeof(DriveLayoutEx), 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;

View file

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

View file

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

View file

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