1
1
Fork 0
mirror of https://github.com/pbatard/rufus.git synced 2024-08-14 23:57:05 +00:00

[misc] cleanup and refactoring + fix WIM 7z minor issue

* remove hardcoded path from WimExtractFile_7z
* move some drive related functions to drive.c
* cleanup
This commit is contained in:
Pete Batard 2013-01-22 02:40:43 +00:00
parent 8ff8b41273
commit c8acf1b84a
8 changed files with 209 additions and 202 deletions

View file

@ -1,3 +1,7 @@
o Version 1.3.2 BETA (2012.01.20)
Re-Fix support for newer ArchLinux ISOs, that was removed in 1.3.1
Add support for UEFI boot, as well as GPT - This means Rufus can now produce UEFI
bootable UFDs from EFI compatible ISOs (Windows 7 x64, Windows 8, ArchLinux...)
o Version 1.3.1 (2013.01.09) o Version 1.3.1 (2013.01.09)
Fix Windows XP ISO support, that was broken in 1.3.0 Fix Windows XP ISO support, that was broken in 1.3.0
Drop support for newer ArchLinux ISOs - this will be fixed in 1.3.2 Drop support for newer ArchLinux ISOs - this will be fixed in 1.3.2

View file

@ -29,6 +29,7 @@
#include "msapi_utf8.h" #include "msapi_utf8.h"
#include "rufus.h" #include "rufus.h"
#include "resource.h" #include "resource.h"
#include "sys_types.h"
/* /*
* Globals * Globals
@ -199,3 +200,165 @@ BOOL UnmountDrive(HANDLE hDrive)
} }
return TRUE; return TRUE;
} }
/* MinGW is unhappy about accessing partitions beside the first unless we redef */
typedef struct _DRIVE_LAYOUT_INFORMATION_EX4 {
DWORD PartitionStyle;
DWORD PartitionCount;
union {
DRIVE_LAYOUT_INFORMATION_MBR Mbr;
DRIVE_LAYOUT_INFORMATION_GPT Gpt;
} Type;
PARTITION_INFORMATION_EX PartitionEntry[4];
} DRIVE_LAYOUT_INFORMATION_EX4,*PDRIVE_LAYOUT_INFORMATION_EX4;
/*
* 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, int partition_style, int file_system)
{
const char* PartitionTypeName[2] = { "MBR", "GPT" };
CREATE_DISK CreateDisk = {PARTITION_STYLE_RAW, {{0}}};
DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = {0};
BOOL r;
DWORD size;
LONGLONG size_in_sectors;
PrintStatus(0, TRUE, "Partitioning (%s)...", PartitionTypeName[partition_style]);
if ((partition_style == PARTITION_STYLE_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 (partition_style) {
case PARTITION_STYLE_MBR:
CreateDisk.PartitionStyle = PARTITION_STYLE_MBR;
CreateDisk.Mbr.Signature = GetTickCount();
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;
case PARTITION_STYLE_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].RewritePartition = TRUE;
switch (partition_style) {
case PARTITION_STYLE_MBR:
DriveLayoutEx.PartitionEntry[0].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack;
switch (file_system) {
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 PARTITION_STYLE_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) - ((partition_style == PARTITION_STYLE_GPT)?(3*sizeof(PARTITION_INFORMATION_EX)):0);
r = DeviceIoControl(hDrive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX,
(BYTE*)&DriveLayoutEx, size, NULL, 0, &size, NULL );
if (!r) {
uprintf("IOCTL_DISK_SET_DRIVE_LAYOUT_EX failed: %s\n", WindowsErrorString());
safe_closehandle(hDrive);
return FALSE;
}
return TRUE;
}
/*
* Convert a partition type to its human readable form using
* (slightly modified) entries from GNU fdisk
*/
const char* GetPartitionType(BYTE Type)
{
int i;
for (i=0; i<ARRAYSIZE(msdos_systypes); i++) {
if (msdos_systypes[i].type == Type)
return msdos_systypes[i].name;
}
return "Unknown";
}

View file

@ -1221,7 +1221,7 @@ DWORD WINAPI FormatThread(LPVOID param)
} }
UpdateProgress(OP_ZERO_MBR, -1.0f); UpdateProgress(OP_ZERO_MBR, -1.0f);
if (!CreatePartition(hPhysicalDrive)) { if (!CreatePartition(hPhysicalDrive, pt, fs)) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE; FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE;
goto out; goto out;
} }

View file

@ -37,7 +37,6 @@
#include "msapi_utf8.h" #include "msapi_utf8.h"
#include "resource.h" #include "resource.h"
#include "rufus.h" #include "rufus.h"
#include "sys_types.h"
#include "registry.h" #include "registry.h"
/* Redefinitions for the WDK */ /* Redefinitions for the WDK */
@ -86,8 +85,8 @@ 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* BiosTypeName[BT_MAX] = { "BIOS", "UEFI" }; static const char* BiosTypeLabel[BT_MAX] = { "BIOS", "UEFI" };
static const char* PartitionTypeName[2] = { "MBR", "GPT" }; static const char* PartitionTypeLabel[2] = { "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;
@ -132,20 +131,6 @@ static int nb_slots[OP_MAX];
static float slot_end[OP_MAX+1]; // shifted +1 so that we can substract 1 to OP indexes static float slot_end[OP_MAX+1]; // shifted +1 so that we can substract 1 to OP indexes
static float previous_end; static float previous_end;
/*
* Convert a partition type to its human readable form using
* (slightly modified) entries from GNU fdisk
*/
static const char* GetPartitionType(BYTE Type)
{
int i;
for (i=0; i<ARRAYSIZE(msdos_systypes); i++) {
if (msdos_systypes[i].type == Type)
return msdos_systypes[i].name;
}
return "Unknown";
}
#define KB 1024LL #define KB 1024LL
#define MB 1048576LL #define MB 1048576LL
@ -329,29 +314,10 @@ static BOOL SetClusterSizes(int FSType)
return TRUE; return TRUE;
} }
// Convert a file size to human readable
static __inline char* size_to_hr(LARGE_INTEGER size)
{
int suffix = 0;
static char str_size[24];
const char* sizes[] = { "", "KB", "MB", "GB", "TB" };
double hr_size = (double)size.QuadPart;
while ((suffix < ARRAYSIZE(sizes)) && (hr_size >= 1024.0)) {
hr_size /= 1024.0;
suffix++;
}
if (suffix == 0) {
safe_sprintf(str_size, sizeof(str_size), "%d bytes", (int)hr_size);
} else {
safe_sprintf(str_size, sizeof(str_size), "%0.1f %s", hr_size, sizes[suffix]);
}
return str_size;
}
/* /*
* Fill the drive properties (size, FS, etc) * Fill the drive properties (size, FS, etc)
*/ */
static BOOL GetDriveInfo(DWORD DeviceNumber) static BOOL GetDriveInfo(int ComboIndex)
{ {
BOOL r; BOOL r;
HANDLE hDrive; HANDLE hDrive;
@ -365,7 +331,7 @@ static BOOL GetDriveInfo(DWORD DeviceNumber)
DWORD i, nb_partitions = 0; DWORD i, nb_partitions = 0;
memset(&SelectedDrive, 0, sizeof(SelectedDrive)); memset(&SelectedDrive, 0, sizeof(SelectedDrive));
SelectedDrive.DeviceNumber = DeviceNumber; SelectedDrive.DeviceNumber = (DWORD)ComboBox_GetItemData(hDeviceList, ComboIndex);
hDrive = GetDriveHandle(SelectedDrive.DeviceNumber, DrivePath, FALSE, FALSE); hDrive = GetDriveHandle(SelectedDrive.DeviceNumber, DrivePath, FALSE, FALSE);
if (hDrive == INVALID_HANDLE_VALUE) if (hDrive == INVALID_HANDLE_VALUE)
@ -404,7 +370,7 @@ static BOOL GetDriveInfo(DWORD DeviceNumber)
uprintf("Partition %d:\n", DriveLayout->PartitionEntry[i].PartitionNumber); uprintf("Partition %d:\n", DriveLayout->PartitionEntry[i].PartitionNumber);
part_type = DriveLayout->PartitionEntry[i].Mbr.PartitionType; 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", 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), GetPartitionType(part_type), part_type, SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength),
DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].Mbr.HiddenSectors, DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].Mbr.HiddenSectors,
DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No", DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No",
DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No"); DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No");
@ -426,7 +392,7 @@ static BOOL GetDriveInfo(DWORD DeviceNumber)
uprintf("Partition %d:\r\n Type: %s\r\n Name: '%s'\n", DriveLayout->PartitionEntry[i].PartitionNumber, uprintf("Partition %d:\r\n Type: %s\r\n Name: '%s'\n", DriveLayout->PartitionEntry[i].PartitionNumber,
GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionType), tmp); 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", 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), GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionId), SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength),
DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].StartingOffset.QuadPart / DiskGeometry->Geometry.BytesPerSector, DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].StartingOffset.QuadPart / DiskGeometry->Geometry.BytesPerSector,
DriveLayout->PartitionEntry[i].Gpt.Attributes); DriveLayout->PartitionEntry[i].Gpt.Attributes);
} }
@ -566,7 +532,7 @@ static BOOL PopulateProperties(int ComboIndex)
if (ComboIndex < 0) if (ComboIndex < 0)
return TRUE; return TRUE;
if (!GetDriveInfo((DWORD)ComboBox_GetItemData(hDeviceList, ComboIndex))) // This also populates FS if (!GetDriveInfo(ComboIndex)) // This also populates FS
return FALSE; return FALSE;
SetFSFromISO(); SetFSFromISO();
fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
@ -577,14 +543,14 @@ static BOOL PopulateProperties(int ComboIndex)
HumanReadableSize /= 1024.0; HumanReadableSize /= 1024.0;
if (HumanReadableSize < 512.0) { if (HumanReadableSize < 512.0) {
for (j=0; j<3; j++) { for (j=0; j<3; j++) {
// Populate BIOS/MBR, UEFI/MBR and UEFI/GPT targets, with an exception // Populate MBR/BIOS, MBR/UEFI and GPT/UEFI targets, with an exception
// for XP, as it doesn't support GPT at all // for XP, as it doesn't support GPT at all
if ((j == 2) && (nWindowsVersion <= WINDOWS_XP)) if ((j == 2) && (nWindowsVersion <= WINDOWS_XP))
continue; continue;
bt = (j==0)?BT_BIOS:BT_UEFI; bt = (j==0)?BT_BIOS:BT_UEFI;
pt = (j==2)?PARTITION_STYLE_GPT:PARTITION_STYLE_MBR; pt = (j==2)?PARTITION_STYLE_GPT:PARTITION_STYLE_MBR;
safe_sprintf(capacity, sizeof(capacity), "%s/%s (1 Partition of %0.2f %s)", safe_sprintf(capacity, sizeof(capacity), "%s/%s (1 Partition of %0.2f %s)",
PartitionTypeName[pt], BiosTypeName[bt], HumanReadableSize, suffix[i]); PartitionTypeLabel[pt], BiosTypeLabel[bt], HumanReadableSize, suffix[i]);
IGNORE_RETVAL(ComboBox_SetItemData(hPartitionScheme, ComboBox_AddStringU(hPartitionScheme, capacity), (bt<<16)|pt)); IGNORE_RETVAL(ComboBox_SetItemData(hPartitionScheme, ComboBox_AddStringU(hPartitionScheme, capacity), (bt<<16)|pt));
} }
break; break;
@ -600,7 +566,8 @@ static BOOL PopulateProperties(int ComboIndex)
j = 0; j = 0;
} }
IGNORE_RETVAL(ComboBox_SetCurSel(hPartitionScheme, j)); IGNORE_RETVAL(ComboBox_SetCurSel(hPartitionScheme, j));
// TODO: create a tooltip for hPartitionScheme CreateTooltip(hPartitionScheme, "When using an EFI bootable image, and if your target system is UEFI based "
"(most post 2011 PCs), you should try to select an UEFI option here.", 15000);
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")
@ -631,154 +598,6 @@ static BOOL PopulateProperties(int ComboIndex)
return TRUE; return TRUE;
} }
/* MinGW is unhappy about accessing partitions beside the first unless we redef */
typedef struct _DRIVE_LAYOUT_INFORMATION_EX4 {
DWORD PartitionStyle;
DWORD PartitionCount;
union {
DRIVE_LAYOUT_INFORMATION_MBR Mbr;
DRIVE_LAYOUT_INFORMATION_GPT Gpt;
} Type;
PARTITION_INFORMATION_EX PartitionEntry[4];
} DRIVE_LAYOUT_INFORMATION_EX4,*PDRIVE_LAYOUT_INFORMATION_EX4;
/*
* 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)
{
CREATE_DISK CreateDisk = {PARTITION_STYLE_RAW, {{0}}};
DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = {0};
BOOL r;
DWORD size;
LONGLONG size_in_sectors;
int pt = GETPARTTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)));
PrintStatus(0, TRUE, "Partitioning (%s)...", PartitionTypeName[pt]);
if ((pt == PARTITION_STYLE_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 PARTITION_STYLE_MBR:
CreateDisk.PartitionStyle = PARTITION_STYLE_MBR;
CreateDisk.Mbr.Signature = GetTickCount();
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;
case PARTITION_STYLE_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].RewritePartition = TRUE;
switch (pt) {
case PARTITION_STYLE_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 PARTITION_STYLE_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 == PARTITION_STYLE_GPT)?(3*sizeof(PARTITION_INFORMATION_EX)):0);
r = DeviceIoControl(hDrive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX,
(BYTE*)&DriveLayoutEx, size, NULL, 0, &size, NULL );
if (!r) {
uprintf("IOCTL_DISK_SET_DRIVE_LAYOUT_EX failed: %s\n", WindowsErrorString());
safe_closehandle(hDrive);
return FALSE;
}
return TRUE;
}
/* /*
* Refresh the list of USB devices * Refresh the list of USB devices
*/ */

View file

@ -265,6 +265,7 @@ 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 char* GuidToString(const GUID* guid);
extern char* SizeToHumanReadable(LARGE_INTEGER size);
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);
@ -282,7 +283,8 @@ extern BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan);
extern BOOL ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file); extern BOOL ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file);
extern BOOL InstallSyslinux(DWORD num, const char* drive_name); extern BOOL InstallSyslinux(DWORD num, const char* drive_name);
DWORD WINAPI FormatThread(void* param); DWORD WINAPI FormatThread(void* param);
extern BOOL CreatePartition(HANDLE hDrive); extern BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system);
extern const char* GetPartitionType(BYTE Type);
extern HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive); extern HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive);
extern BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label); extern BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label);
extern BOOL UnmountDrive(HANDLE hDrive); extern BOOL UnmountDrive(HANDLE hDrive);

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.2.226" CAPTION "Rufus v1.3.2.227"
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
@ -274,8 +274,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,3,2,226 FILEVERSION 1,3,2,227
PRODUCTVERSION 1,3,2,226 PRODUCTVERSION 1,3,2,227
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.2.226" VALUE "FileVersion", "1.3.2.227"
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.2.226" VALUE "ProductVersion", "1.3.2.227"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -189,6 +189,25 @@ char* GuidToString(const GUID* guid)
return guid_string; return guid_string;
} }
// Convert a file size to human readable
char* SizeToHumanReadable(LARGE_INTEGER size)
{
int suffix = 0;
static char str_size[24];
const char* sizes[] = { "", "KB", "MB", "GB", "TB" };
double hr_size = (double)size.QuadPart;
while ((suffix < ARRAYSIZE(sizes)) && (hr_size >= 1024.0)) {
hr_size /= 1024.0;
suffix++;
}
if (suffix == 0) {
safe_sprintf(str_size, sizeof(str_size), "%d bytes", (int)hr_size);
} else {
safe_sprintf(str_size, sizeof(str_size), "%0.1f %s", hr_size, sizes[suffix]);
}
return str_size;
}
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)) {

View file

@ -131,7 +131,7 @@ static BOOL WimExtractFile_API(const char* image, int index, const char* src, co
goto out; goto out;
} }
uprintf("Extracting: %s (From \\%s)\n", dst, src); uprintf("Extracting: %s (From %s)\n", dst, src);
if (!pfWIMExtractImagePath(hImage, wsrc, wdst, 0)) { if (!pfWIMExtractImagePath(hImage, wsrc, wdst, 0)) {
uprintf(" Could not extract file: %s\n", WindowsErrorString()); uprintf(" Could not extract file: %s\n", WindowsErrorString());
goto out; goto out;
@ -181,8 +181,8 @@ static BOOL WimExtractFile_7z(const char* image, int index, const char* src, con
tmpdst[i] = 0; tmpdst[i] = 0;
si.cb = sizeof(si); si.cb = sizeof(si);
safe_sprintf(cmdline, sizeof(cmdline), "7z -y e \"%s\" %d\\Windows\\Boot\\EFI\\bootmgfw.efi", image, index); safe_sprintf(cmdline, sizeof(cmdline), "7z -y e \"%s\" %d\\%s", image, index, src);
uprintf("Extracting: %s (From \\%s)\n", dst, src); uprintf("Extracting: %s (From %s)\n", dst, src);
if (!CreateProcessU(sevenzip_path, cmdline, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, tmpdst, &si, &pi)) { if (!CreateProcessU(sevenzip_path, cmdline, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, tmpdst, &si, &pi)) {
uprintf(" Could not launch 7z.exe: %s\n", WindowsErrorString()); uprintf(" Could not launch 7z.exe: %s\n", WindowsErrorString());
return FALSE; return FALSE;