mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[efi] add Windows 7 EFI support for XP and Vista
* Requires 7-Zip for WIM extraction as wimgapi.dll is not available * Also add more comprehensive choice between MBR/GPT and BIOS/UEFI
This commit is contained in:
parent
84e4aecfcd
commit
0196de6f4d
6 changed files with 233 additions and 88 deletions
23
src/format.c
23
src/format.c
|
@ -749,7 +749,7 @@ static BOOL ClearMBRGPT(HANDLE hPhysicalDrive, LONGLONG DiskSize, DWORD SectorSi
|
||||||
uint64_t i, last_sector = DiskSize/SectorSize;
|
uint64_t i, last_sector = DiskSize/SectorSize;
|
||||||
unsigned char* pBuf = (unsigned char*) calloc(SectorSize, 1);
|
unsigned char* pBuf = (unsigned char*) calloc(SectorSize, 1);
|
||||||
|
|
||||||
PrintStatus(0, TRUE, "Clearing MBR & GPT structures...");
|
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;
|
||||||
|
@ -818,7 +818,6 @@ static BOOL WriteMBR(HANDLE hPhysicalDrive)
|
||||||
|
|
||||||
// FormatEx rewrites the MBR and removes the LBA attribute of FAT16
|
// FormatEx rewrites the MBR and removes the LBA attribute of FAT16
|
||||||
// and FAT32 partitions - we need to correct this in the MBR
|
// and FAT32 partitions - we need to correct this in the MBR
|
||||||
// TODO: Something else for bootable GPT
|
|
||||||
buf = (unsigned char*)malloc(SecSize * nSecs);
|
buf = (unsigned char*)malloc(SecSize * nSecs);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
uprintf("Could not allocate memory for MBR");
|
uprintf("Could not allocate memory for MBR");
|
||||||
|
@ -1110,10 +1109,7 @@ static BOOL RemountVolume(char drive_letter)
|
||||||
*/
|
*/
|
||||||
DWORD WINAPI FormatThread(LPVOID param)
|
DWORD WINAPI FormatThread(LPVOID param)
|
||||||
{
|
{
|
||||||
int r;
|
int r, pt, bt, fs, dt;
|
||||||
int fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
|
|
||||||
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;
|
||||||
|
@ -1126,6 +1122,11 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
char efi_dst[] = "?:\\efi\\boot\\bootx64.efi";
|
char efi_dst[] = "?:\\efi\\boot\\bootx64.efi";
|
||||||
FILE* log_fd;
|
FILE* log_fd;
|
||||||
|
|
||||||
|
fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
|
||||||
|
dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType));
|
||||||
|
pt = GETPARTTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)));
|
||||||
|
bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)));
|
||||||
|
|
||||||
hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE);
|
hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE);
|
||||||
if (hPhysicalDrive == INVALID_HANDLE_VALUE) {
|
if (hPhysicalDrive == INVALID_HANDLE_VALUE) {
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
|
||||||
|
@ -1239,7 +1240,7 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pt == PT_MBR) {
|
if (pt == PARTITION_STYLE_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)
|
||||||
|
@ -1250,7 +1251,7 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsChecked(IDC_DOS)) {
|
if (IsChecked(IDC_DOS)) {
|
||||||
if (pt == PT_GPT) {
|
if (bt == BT_UEFI) {
|
||||||
// For once, no need to do anything - just check our sanity
|
// For once, no need to do anything - just check our sanity
|
||||||
if ( (dt != DT_ISO) || (!IS_EFI(iso_report)) || (fs > FS_FAT32) ) {
|
if ( (dt != DT_ISO) || (!IS_EFI(iso_report)) || (fs > FS_FAT32) ) {
|
||||||
uprintf("Spock gone crazy error!\n");
|
uprintf("Spock gone crazy error!\n");
|
||||||
|
@ -1312,7 +1313,7 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if ((pt == PT_GPT) && (!iso_report.has_efi) && (iso_report.has_win7_efi)) {
|
if ((bt == BT_UEFI) && (!iso_report.has_efi) && (iso_report.has_win7_efi)) {
|
||||||
// TODO: progress
|
// TODO: progress
|
||||||
PrintStatus(0, TRUE, "Win7 EFI boot setup (this may take a while)...");
|
PrintStatus(0, TRUE, "Win7 EFI boot setup (this may take a while)...");
|
||||||
wim_image[0] = drive_name[0];
|
wim_image[0] = drive_name[0];
|
||||||
|
@ -1323,14 +1324,14 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
||||||
} else {
|
} else {
|
||||||
efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = '\\';
|
efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = '\\';
|
||||||
if (!WIMExtractFile(wim_image, 1, "Windows\\Boot\\EFI\\bootmgfw.efi", efi_dst)) {
|
if (!WimExtractFile(wim_image, 1, "Windows\\Boot\\EFI\\bootmgfw.efi", efi_dst)) {
|
||||||
uprintf("Failed to setup Win7 EFI boot\n");
|
uprintf("Failed to setup Win7 EFI boot\n");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( (pt == PT_MBR) && (IS_WINPE(iso_report.winpe)) ) {
|
if ( (bt == BT_BIOS) && (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,24 +57,39 @@ static __inline BOOL DeleteRegistryKey(const char* key_name)
|
||||||
return ((s == ERROR_SUCCESS) || (s == ERROR_FILE_NOT_FOUND));
|
return ((s == ERROR_SUCCESS) || (s == ERROR_FILE_NOT_FOUND));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a generic registry key value (create the key if it doesn't exist) */
|
/* Read a generic registry key value. If a short key_name is used, assume that it belongs to
|
||||||
|
the application and create the app subkey if required */
|
||||||
static __inline BOOL _GetRegistryKey(const char* key_name, DWORD reg_type, LPBYTE dest, DWORD dest_size)
|
static __inline BOOL _GetRegistryKey(const char* key_name, DWORD reg_type, LPBYTE dest, DWORD dest_size)
|
||||||
{
|
{
|
||||||
BOOL r = FALSE;
|
BOOL r = FALSE;
|
||||||
|
size_t i = 0;
|
||||||
LONG s;
|
LONG s;
|
||||||
HKEY hSoftware = NULL, hApp = NULL;
|
HKEY hSoftware = NULL, hApp = NULL;
|
||||||
DWORD dwDisp, dwType = -1, dwSize = dest_size;
|
DWORD dwDisp, dwType = -1, dwSize = dest_size;
|
||||||
|
char long_key_name[256] = "SOFTWARE\\";
|
||||||
memset(dest, 0, dest_size);
|
memset(dest, 0, dest_size);
|
||||||
|
|
||||||
|
for (i=safe_strlen(key_name); i>0; i--) {
|
||||||
|
if (key_name[i] == '\\')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i != 0) {
|
||||||
|
safe_strcat(long_key_name, sizeof(long_key_name), key_name);
|
||||||
|
long_key_name[sizeof("SOFTWARE\\") + i-1] = 0;
|
||||||
|
i++;
|
||||||
|
if (RegOpenKeyExA(HKEY_CURRENT_USER, long_key_name, 0, KEY_READ, &hApp) != ERROR_SUCCESS)
|
||||||
|
goto out;
|
||||||
|
} else {
|
||||||
if ( (RegOpenKeyExA(HKEY_CURRENT_USER, "SOFTWARE", 0, KEY_READ|KEY_CREATE_SUB_KEY, &hSoftware) != ERROR_SUCCESS)
|
if ( (RegOpenKeyExA(HKEY_CURRENT_USER, "SOFTWARE", 0, KEY_READ|KEY_CREATE_SUB_KEY, &hSoftware) != ERROR_SUCCESS)
|
||||||
|| (RegCreateKeyExA(hSoftware, COMPANY_NAME "\\" APPLICATION_NAME, 0, NULL, 0,
|
|| (RegCreateKeyExA(hSoftware, COMPANY_NAME "\\" APPLICATION_NAME, 0, NULL, 0,
|
||||||
KEY_SET_VALUE|KEY_QUERY_VALUE|KEY_CREATE_SUB_KEY, NULL, &hApp, &dwDisp) != ERROR_SUCCESS) ) {
|
KEY_SET_VALUE|KEY_QUERY_VALUE|KEY_CREATE_SUB_KEY, NULL, &hApp, &dwDisp) != ERROR_SUCCESS) )
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = RegQueryValueExA(hApp, key_name, NULL, &dwType, (LPBYTE)dest, &dwSize);
|
s = RegQueryValueExA(hApp, &key_name[i], NULL, &dwType, (LPBYTE)dest, &dwSize);
|
||||||
// No key means default value of 0 or empty string
|
// No key means default value of 0 or empty string
|
||||||
if ((s == ERROR_FILE_NOT_FOUND) || ((s == ERROR_SUCCESS) && (dwType = reg_type) && (dwSize = dest_size))) {
|
if ((s == ERROR_FILE_NOT_FOUND) || ((s == ERROR_SUCCESS) && (dwType = reg_type) && (dwSize > 0))) {
|
||||||
r = TRUE;
|
r = TRUE;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
|
113
src/rufus.c
113
src/rufus.c
|
@ -86,7 +86,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* PartitionSchemeName[PT_MAX] = { "MBR", "GPT" };
|
static const char* BiosTypeName[BT_MAX] = { "BIOS", "UEFI" };
|
||||||
|
static const char* PartitionTypeName[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;
|
||||||
|
@ -350,7 +351,7 @@ static __inline char* size_to_hr(LARGE_INTEGER size)
|
||||||
/*
|
/*
|
||||||
* Fill the drive properties (size, FS, etc)
|
* Fill the drive properties (size, FS, etc)
|
||||||
*/
|
*/
|
||||||
static BOOL GetDriveInfo(void)
|
static BOOL GetDriveInfo(DWORD DeviceNumber)
|
||||||
{
|
{
|
||||||
BOOL r;
|
BOOL r;
|
||||||
HANDLE hDrive;
|
HANDLE hDrive;
|
||||||
|
@ -363,7 +364,8 @@ static BOOL GetDriveInfo(void)
|
||||||
char DrivePath[] = "#:\\", tmp[256], fs_type[32];
|
char DrivePath[] = "#:\\", tmp[256], fs_type[32];
|
||||||
DWORD i, nb_partitions = 0;
|
DWORD i, nb_partitions = 0;
|
||||||
|
|
||||||
SelectedDrive.DiskSize = 0;
|
memset(&SelectedDrive, 0, sizeof(SelectedDrive));
|
||||||
|
SelectedDrive.DeviceNumber = DeviceNumber;
|
||||||
|
|
||||||
hDrive = GetDriveHandle(SelectedDrive.DeviceNumber, DrivePath, FALSE, FALSE);
|
hDrive = GetDriveHandle(SelectedDrive.DeviceNumber, DrivePath, FALSE, FALSE);
|
||||||
if (hDrive == INVALID_HANDLE_VALUE)
|
if (hDrive == INVALID_HANDLE_VALUE)
|
||||||
|
@ -389,7 +391,7 @@ static BOOL GetDriveInfo(void)
|
||||||
} else {
|
} else {
|
||||||
switch (DriveLayout->PartitionStyle) {
|
switch (DriveLayout->PartitionStyle) {
|
||||||
case PARTITION_STYLE_MBR:
|
case PARTITION_STYLE_MBR:
|
||||||
SelectedDrive.PartitionType = PT_MBR;
|
SelectedDrive.PartitionType = PARTITION_STYLE_MBR;
|
||||||
for (i=0; i<DriveLayout->PartitionCount; i++) {
|
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++;
|
||||||
|
@ -406,11 +408,13 @@ static BOOL GetDriveInfo(void)
|
||||||
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");
|
||||||
|
if (part_type == 0xee) // Flag a protective MBR for non GPT platforms (XP)
|
||||||
|
SelectedDrive.has_protective_mbr = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PARTITION_STYLE_GPT:
|
case PARTITION_STYLE_GPT:
|
||||||
SelectedDrive.PartitionType = PT_GPT;
|
SelectedDrive.PartitionType = PARTITION_STYLE_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("Disk GUID: %s\n", GuidToString(&DriveLayout->Gpt.DiskId));
|
||||||
uprintf("Max parts: %d, Start Offset: %lld, Usable = %lld bytes\n",
|
uprintf("Max parts: %d, Start Offset: %lld, Usable = %lld bytes\n",
|
||||||
|
@ -428,7 +432,7 @@ static BOOL GetDriveInfo(void)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SelectedDrive.PartitionType = PT_MBR;
|
SelectedDrive.PartitionType = PARTITION_STYLE_MBR;
|
||||||
uprintf("Partition type: RAW\n");
|
uprintf("Partition type: RAW\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -480,6 +484,7 @@ static void SetFSFromISO(void)
|
||||||
{
|
{
|
||||||
int i, fs, selected_fs = FS_UNKNOWN;
|
int i, fs, selected_fs = FS_UNKNOWN;
|
||||||
uint32_t fs_mask = 0;
|
uint32_t fs_mask = 0;
|
||||||
|
int bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)));
|
||||||
|
|
||||||
if (iso_path == NULL)
|
if (iso_path == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -490,8 +495,8 @@ static void SetFSFromISO(void)
|
||||||
fs_mask |= 1<<fs;
|
fs_mask |= 1<<fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Syslinux and EFI have precedence over bootmgr
|
// Syslinux and EFI have precedence over bootmgr (unless the user selected BIOS as target type)
|
||||||
if ((iso_report.has_isolinux) || (IS_EFI(iso_report))) {
|
if ((iso_report.has_isolinux) || ( (IS_EFI(iso_report)) && (bt == BT_UEFI))) {
|
||||||
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)) {
|
||||||
|
@ -549,7 +554,7 @@ static BOOL PopulateProperties(int ComboIndex)
|
||||||
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, j, fs;
|
int i, j, pt, bt, fs;
|
||||||
|
|
||||||
IGNORE_RETVAL(ComboBox_ResetContent(hPartitionScheme));
|
IGNORE_RETVAL(ComboBox_ResetContent(hPartitionScheme));
|
||||||
IGNORE_RETVAL(ComboBox_ResetContent(hFileSystem));
|
IGNORE_RETVAL(ComboBox_ResetContent(hFileSystem));
|
||||||
|
@ -561,8 +566,7 @@ static BOOL PopulateProperties(int ComboIndex)
|
||||||
if (ComboIndex < 0)
|
if (ComboIndex < 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
SelectedDrive.DeviceNumber = (DWORD)ComboBox_GetItemData(hDeviceList, ComboIndex);
|
if (!GetDriveInfo((DWORD)ComboBox_GetItemData(hDeviceList, ComboIndex))) // This also populates FS
|
||||||
if (!GetDriveInfo()) // 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));
|
||||||
|
@ -572,17 +576,31 @@ 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) {
|
||||||
for (j=0; j<PT_MAX; j++) {
|
for (j=0; j<3; j++) {
|
||||||
safe_sprintf(capacity, sizeof(capacity), "%s (1 Partition of %0.2f %s)",
|
// Populate BIOS/MBR, UEFI/MBR and UEFI/GPT targets, with an exception
|
||||||
PartitionSchemeName[j], HumanReadableSize, suffix[i]);
|
// for XP, as it doesn't support GPT at all
|
||||||
IGNORE_RETVAL(ComboBox_SetItemData(hPartitionScheme, ComboBox_AddStringU(hPartitionScheme, capacity), j));
|
if ((j == 2) && (nWindowsVersion <= WINDOWS_XP))
|
||||||
|
continue;
|
||||||
|
bt = (j==0)?BT_BIOS:BT_UEFI;
|
||||||
|
pt = (j==2)?PARTITION_STYLE_GPT:PARTITION_STYLE_MBR;
|
||||||
|
safe_sprintf(capacity, sizeof(capacity), "%s/%s (1 Partition of %0.2f %s)",
|
||||||
|
PartitionTypeName[pt], BiosTypeName[bt], HumanReadableSize, suffix[i]);
|
||||||
|
IGNORE_RETVAL(ComboBox_SetItemData(hPartitionScheme, ComboBox_AddStringU(hPartitionScheme, capacity), (bt<<16)|pt));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i >= ARRAYSIZE(suffix))
|
if (i >= ARRAYSIZE(suffix))
|
||||||
uprintf("Could not populate partition scheme data\n");
|
uprintf("Could not populate partition scheme data\n");
|
||||||
IGNORE_RETVAL(ComboBox_SetCurSel(hPartitionScheme, SelectedDrive.PartitionType));
|
if (SelectedDrive.PartitionType == PARTITION_STYLE_GPT) {
|
||||||
|
j = 2;
|
||||||
|
} else if (SelectedDrive.has_protective_mbr) {
|
||||||
|
j = 1;
|
||||||
|
} else {
|
||||||
|
j = 0;
|
||||||
|
}
|
||||||
|
IGNORE_RETVAL(ComboBox_SetCurSel(hPartitionScheme, j));
|
||||||
|
// TODO: create a tooltip for hPartitionScheme
|
||||||
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")
|
||||||
|
@ -638,11 +656,11 @@ BOOL CreatePartition(HANDLE hDrive)
|
||||||
BOOL r;
|
BOOL r;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
LONGLONG size_in_sectors;
|
LONGLONG size_in_sectors;
|
||||||
int pt = (int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme));
|
int pt = GETPARTTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)));
|
||||||
|
|
||||||
PrintStatus(0, TRUE, "Partitioning (%s)...", PartitionSchemeName[pt]);
|
PrintStatus(0, TRUE, "Partitioning (%s)...", PartitionTypeName[pt]);
|
||||||
|
|
||||||
if ((pt == PT_GPT) || (!IsChecked(IDC_EXTRA_PARTITION))) {
|
if ((pt == PARTITION_STYLE_GPT) || (!IsChecked(IDC_EXTRA_PARTITION))) {
|
||||||
// Go with the MS 1 MB wastage at the beginning...
|
// Go with the MS 1 MB wastage at the beginning...
|
||||||
DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart = 1024*1024;
|
DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart = 1024*1024;
|
||||||
} else {
|
} else {
|
||||||
|
@ -653,7 +671,7 @@ BOOL CreatePartition(HANDLE hDrive)
|
||||||
size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart) / SelectedDrive.Geometry.BytesPerSector;
|
size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart) / SelectedDrive.Geometry.BytesPerSector;
|
||||||
|
|
||||||
switch (pt) {
|
switch (pt) {
|
||||||
case PT_MBR:
|
case PARTITION_STYLE_MBR:
|
||||||
CreateDisk.PartitionStyle = PARTITION_STYLE_MBR;
|
CreateDisk.PartitionStyle = PARTITION_STYLE_MBR;
|
||||||
CreateDisk.Mbr.Signature = GetTickCount();
|
CreateDisk.Mbr.Signature = GetTickCount();
|
||||||
|
|
||||||
|
@ -672,7 +690,7 @@ BOOL CreatePartition(HANDLE hDrive)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PT_GPT:
|
case PARTITION_STYLE_GPT:
|
||||||
CreateDisk.PartitionStyle = PARTITION_STYLE_GPT;
|
CreateDisk.PartitionStyle = PARTITION_STYLE_GPT;
|
||||||
IGNORE_RETVAL(CoCreateGuid(&CreateDisk.Gpt.DiskId));
|
IGNORE_RETVAL(CoCreateGuid(&CreateDisk.Gpt.DiskId));
|
||||||
CreateDisk.Gpt.MaxPartitionCount = MAX_GPT_PARTITIONS;
|
CreateDisk.Gpt.MaxPartitionCount = MAX_GPT_PARTITIONS;
|
||||||
|
@ -698,7 +716,7 @@ BOOL CreatePartition(HANDLE hDrive)
|
||||||
DriveLayoutEx.PartitionEntry[0].RewritePartition = TRUE;
|
DriveLayoutEx.PartitionEntry[0].RewritePartition = TRUE;
|
||||||
|
|
||||||
switch (pt) {
|
switch (pt) {
|
||||||
case PT_MBR:
|
case PARTITION_STYLE_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:
|
||||||
|
@ -730,7 +748,7 @@ BOOL CreatePartition(HANDLE hDrive)
|
||||||
// For the remaining partitions, PartitionStyle & PartitionType have already
|
// For the remaining partitions, PartitionStyle & PartitionType have already
|
||||||
// been zeroed => already set to MBR/unused
|
// been zeroed => already set to MBR/unused
|
||||||
break;
|
break;
|
||||||
case PT_GPT:
|
case PARTITION_STYLE_GPT:
|
||||||
DriveLayoutEx.PartitionEntry[0].Gpt.PartitionType = PARTITION_BASIC_DATA_GUID;
|
DriveLayoutEx.PartitionEntry[0].Gpt.PartitionType = PARTITION_BASIC_DATA_GUID;
|
||||||
wcscpy(DriveLayoutEx.PartitionEntry[0].Gpt.Name, L"Microsoft Basic Data");
|
wcscpy(DriveLayoutEx.PartitionEntry[0].Gpt.Name, L"Microsoft Basic Data");
|
||||||
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[0].Gpt.PartitionId));
|
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[0].Gpt.PartitionId));
|
||||||
|
@ -749,7 +767,7 @@ BOOL CreatePartition(HANDLE hDrive)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = sizeof(DriveLayoutEx) - ((pt == PT_GPT)?(3*sizeof(PARTITION_INFORMATION_EX)):0);
|
size = sizeof(DriveLayoutEx) - ((pt == PARTITION_STYLE_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, size, NULL, 0, &size, NULL );
|
(BYTE*)&DriveLayoutEx, size, NULL, 0, &size, NULL );
|
||||||
if (!r) {
|
if (!r) {
|
||||||
|
@ -1241,10 +1259,6 @@ BOOL CALLBACK LogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// case WM_SHOWWINDOW:
|
|
||||||
// if (wParam)
|
|
||||||
// SendMessage(hLog, EM_LINESCROLL, 0, SendMessage(hLog, EM_GETLINECOUNT, 0, 0));
|
|
||||||
// return FALSE;
|
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
ShowWindow(hDlg, SW_HIDE);
|
ShowWindow(hDlg, SW_HIDE);
|
||||||
log_displayed = FALSE;
|
log_displayed = FALSE;
|
||||||
|
@ -1637,7 +1651,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, pt, i, nWidth, nHeight;
|
int nDeviceIndex, fs, bt, 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;
|
||||||
|
@ -1787,7 +1801,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
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));
|
bt = GETBIOSTYPE((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)) {
|
||||||
|
@ -1812,7 +1826,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((fs == FS_EXFAT) || ((pt == PT_GPT) && (fs == FS_NTFS))) {
|
if (fs == FS_EXFAT) {
|
||||||
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));
|
||||||
|
@ -1824,13 +1838,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 ((pt == PT_MBR) && ((fs == FS_FAT16) || (fs == FS_FAT32))) {
|
if ((bt == BT_BIOS) && ((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 ( (pt == PT_MBR) && (((fs == FS_FAT16) || (fs == FS_FAT32)) && (advanced_mode)) )
|
if ( (bt == BT_BIOS) && (((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;
|
||||||
|
@ -1923,24 +1937,37 @@ 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));
|
||||||
pt = (int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme));
|
bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)));
|
||||||
if ((pt == PT_GPT) && ((!IS_EFI(iso_report)) || ((fs > FS_FAT32)))) {
|
if (bt == BT_UEFI) {
|
||||||
MessageBoxA(hMainDialog, "When using GPT, only EFI bootable ISOs are supported. "
|
if (!IS_EFI(iso_report)) {
|
||||||
"Please select an EFI bootable ISO or change the Partition Scheme to MBR.", "Unsupported GPT ISO...", MB_OK|MB_ICONERROR);
|
MessageBoxA(hMainDialog, "When using UEFI Target Type, only EFI bootable ISO images are supported. "
|
||||||
|
"Please select an EFI bootable ISO or set the Target Type to BIOS.", "Unsupported ISO...", MB_OK|MB_ICONERROR);
|
||||||
|
break;
|
||||||
|
} else if (fs > FS_FAT32) {
|
||||||
|
MessageBoxA(hMainDialog, "When using UEFI Target Type, only FAT/FAT32 is supported. "
|
||||||
|
"Please select FAT/FAT32 as the File system or set the Target Type to BIOS.", "Unsupported filesystem...", MB_OK|MB_ICONERROR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if ((fs == FS_NTFS) && (!iso_report.has_bootmgr) && (!IS_WINPE(iso_report.winpe))) {
|
} 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 FAT/FAT32 is supported for this type of ISO. "
|
||||||
"Please revert the filesystem back from NTFS to FAT32.", "Unsupported filesystem...", MB_OK|MB_ICONERROR);
|
"Please select FAT/FAT32 as the File system.", "Unsupported filesystem...", MB_OK|MB_ICONERROR);
|
||||||
} else {
|
} else {
|
||||||
MessageBoxA(hMainDialog, "Only 'bootmgr' or 'WinPE' based ISO "
|
MessageBoxA(hMainDialog, "Only 'bootmgr' or 'WinPE' based ISO "
|
||||||
"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) && (pt != PT_GPT))) {
|
} else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && (!iso_report.has_isolinux)) {
|
||||||
MessageBoxA(hMainDialog, "Only isolinux or EFI based ISO "
|
MessageBoxA(hMainDialog, "FAT/FAT32 can only be used for isolinux based ISO images "
|
||||||
"images can currently be used with FAT/FAT32.", "Unsupported ISO...", MB_OK|MB_ICONERROR);
|
"or when the Target Type is UEFI.", "Unsupported ISO...", MB_OK|MB_ICONERROR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((bt == BT_UEFI) && (iso_report.has_win7_efi) && (!WimExtractCheck())) {
|
||||||
|
if (MessageBoxA(hMainDialog, "Your platform cannot extract files from WIM archives. WIM extraction "
|
||||||
|
"is required to create EFI bootable Windows 7 and Windows Vista USB drives. You can fix that "
|
||||||
|
"by installing a recent version of 7-Zip.\r\nDo you want to visit the 7-zip download page?",
|
||||||
|
"Missing WIM support...", MB_YESNO|MB_ICONERROR) == IDYES)
|
||||||
|
ShellExecuteA(hDlg, "open", SEVENZIP_URL, NULL, NULL, SW_SHOWNORMAL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
src/rufus.h
16
src/rufus.h
|
@ -51,6 +51,7 @@
|
||||||
#define WHITE RGB(255,255,255)
|
#define WHITE RGB(255,255,255)
|
||||||
#define SEPARATOR_GREY RGB(223,223,223)
|
#define SEPARATOR_GREY RGB(223,223,223)
|
||||||
#define RUFUS_URL "http://rufus.akeo.ie"
|
#define RUFUS_URL "http://rufus.akeo.ie"
|
||||||
|
#define SEVENZIP_URL "http://sourceforge.net/projects/sevenzip/files/7-Zip/"
|
||||||
#define IGNORE_RETVAL(expr) do { (void)(expr); } while(0)
|
#define IGNORE_RETVAL(expr) do { (void)(expr); } while(0)
|
||||||
#ifndef ARRAYSIZE
|
#ifndef ARRAYSIZE
|
||||||
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
||||||
|
@ -150,11 +151,14 @@ enum dos_type {
|
||||||
DT_MAX
|
DT_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
enum part_type {
|
enum bios_type {
|
||||||
PT_MBR = 0,
|
BT_BIOS = 0,
|
||||||
PT_GPT,
|
BT_UEFI,
|
||||||
PT_MAX
|
BT_MAX
|
||||||
};
|
};
|
||||||
|
// For the partition types we'll use Microsoft's PARTITION_STYLE_### constants
|
||||||
|
#define GETBIOSTYPE(x) (((x) >> 16) & 0xFFFF)
|
||||||
|
#define GETPARTTYPE(x) ((x) & 0xFFFF);
|
||||||
|
|
||||||
/* Current drive info */
|
/* Current drive info */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -165,6 +169,7 @@ typedef struct {
|
||||||
char proposed_label[16];
|
char proposed_label[16];
|
||||||
int PartitionType;
|
int PartitionType;
|
||||||
int FSType;
|
int FSType;
|
||||||
|
BOOL has_protective_mbr;
|
||||||
struct {
|
struct {
|
||||||
ULONG Allowed;
|
ULONG Allowed;
|
||||||
ULONG Default;
|
ULONG Default;
|
||||||
|
@ -298,7 +303,8 @@ extern char* get_token_data_buffer(const char* token, unsigned int n, const char
|
||||||
extern char* insert_section_data(const char* filename, const char* section, const char* data, BOOL dos2unix);
|
extern char* insert_section_data(const char* filename, const char* section, const char* data, BOOL dos2unix);
|
||||||
extern char* replace_in_token_data(const char* filename, const char* token, const char* src, const char* rep, BOOL dos2unix);
|
extern char* replace_in_token_data(const char* filename, const char* token, const char* src, const char* rep, BOOL dos2unix);
|
||||||
extern void parse_update(char* buf, size_t len);
|
extern void parse_update(char* buf, size_t len);
|
||||||
extern BOOL WIMExtractFile(const char* wim_image, int index, const char* src, const char* dst);
|
extern BOOL WimExtractCheck(void);
|
||||||
|
extern BOOL WimExtractFile(const char* wim_image, int index, const char* src, const char* dst);
|
||||||
|
|
||||||
__inline static BOOL UnlockDrive(HANDLE hDrive)
|
__inline static BOOL UnlockDrive(HANDLE hDrive)
|
||||||
{
|
{
|
||||||
|
|
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.224"
|
CAPTION "Rufus v1.3.1.225"
|
||||||
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
|
||||||
|
@ -40,7 +40,7 @@ BEGIN
|
||||||
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_SCHEME,8,46,190,30,CBS_DROPDOWNLIST | 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 and Target Type",IDC_STATIC,9,35,176,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
|
||||||
PUSHBUTTON "About...",IDC_ABOUT,8,278,50,14
|
PUSHBUTTON "About...",IDC_ABOUT,8,278,50,14
|
||||||
|
@ -274,8 +274,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,3,1,224
|
FILEVERSION 1,3,1,225
|
||||||
PRODUCTVERSION 1,3,1,224
|
PRODUCTVERSION 1,3,1,225
|
||||||
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.224"
|
VALUE "FileVersion", "1.3.1.225"
|
||||||
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.224"
|
VALUE "ProductVersion", "1.3.1.225"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
126
src/vhd.c
126
src/vhd.c
|
@ -17,8 +17,14 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <io.h>
|
||||||
|
|
||||||
#include "rufus.h"
|
#include "rufus.h"
|
||||||
#include "msapi_utf8.h"
|
#include "msapi_utf8.h"
|
||||||
|
#include "registry.h"
|
||||||
|
|
||||||
|
static BOOL has_wimgapi = FALSE, has_7z = FALSE;
|
||||||
|
|
||||||
#define WIM_GENERIC_READ GENERIC_READ
|
#define WIM_GENERIC_READ GENERIC_READ
|
||||||
#define WIM_OPEN_EXISTING OPEN_EXISTING
|
#define WIM_OPEN_EXISTING OPEN_EXISTING
|
||||||
|
@ -53,9 +59,39 @@ typedef BOOL (WINAPI *WIMCloseHandle_t)(
|
||||||
HANDLE hObj
|
HANDLE hObj
|
||||||
);
|
);
|
||||||
|
|
||||||
// Extract a file from a WIM image
|
// WIM API Prototypes
|
||||||
|
static PF_DECL(WIMCreateFile);
|
||||||
|
static PF_DECL(WIMSetTemporaryPath);
|
||||||
|
static PF_DECL(WIMLoadImage);
|
||||||
|
static PF_DECL(WIMExtractImagePath);
|
||||||
|
static PF_DECL(WIMCloseHandle);
|
||||||
|
|
||||||
|
// Find out if we have any way to extraxt WIM files on this platform
|
||||||
|
BOOL WimExtractCheck(void)
|
||||||
|
{
|
||||||
|
char sevenzip_path[MAX_PATH];
|
||||||
|
|
||||||
|
PF_INIT(WIMCreateFile, wimgapi);
|
||||||
|
PF_INIT(WIMSetTemporaryPath, wimgapi);
|
||||||
|
PF_INIT(WIMLoadImage, wimgapi);
|
||||||
|
PF_INIT(WIMExtractImagePath, wimgapi);
|
||||||
|
PF_INIT(WIMCloseHandle, wimgapi);
|
||||||
|
|
||||||
|
has_wimgapi = (pfWIMCreateFile && pfWIMSetTemporaryPath && pfWIMLoadImage && pfWIMExtractImagePath && pfWIMCloseHandle);
|
||||||
|
if (GetRegistryKeyStr("7-Zip\\Path", sevenzip_path, sizeof(sevenzip_path))) {
|
||||||
|
safe_strcat(sevenzip_path, sizeof(sevenzip_path), "\\7z.exe");
|
||||||
|
has_7z = (_access(sevenzip_path, 0) != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
uprintf("WIM extraction method(s) supported: %s%s%s\n", has_7z?"7z":(has_wimgapi?"":"NONE"),
|
||||||
|
(has_wimgapi && has_7z)?", ":"", has_wimgapi?"wimgapi.dll":"");
|
||||||
|
return (has_wimgapi || has_7z);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Extract a file from a WIM image using wimgapi.dll (Windows 7 or later)
|
||||||
// NB: Don't bother trying to get progress from a WIM callback - it doesn't work!
|
// NB: Don't bother trying to get progress from a WIM callback - it doesn't work!
|
||||||
BOOL WIMExtractFile(const char* image, int index, const char* src, const char* dst)
|
static BOOL WimExtractFile_API(const char* image, int index, const char* src, const char* dst)
|
||||||
{
|
{
|
||||||
BOOL r = FALSE;
|
BOOL r = FALSE;
|
||||||
DWORD dw = 0;
|
DWORD dw = 0;
|
||||||
|
@ -65,11 +101,6 @@ BOOL WIMExtractFile(const char* image, int index, const char* src, const char* d
|
||||||
wchar_t* wimage = utf8_to_wchar(image);
|
wchar_t* wimage = utf8_to_wchar(image);
|
||||||
wchar_t* wsrc = utf8_to_wchar(src);
|
wchar_t* wsrc = utf8_to_wchar(src);
|
||||||
wchar_t* wdst = utf8_to_wchar(dst);
|
wchar_t* wdst = utf8_to_wchar(dst);
|
||||||
PF_DECL(WIMCreateFile);
|
|
||||||
PF_DECL(WIMSetTemporaryPath);
|
|
||||||
PF_DECL(WIMLoadImage);
|
|
||||||
PF_DECL(WIMExtractImagePath);
|
|
||||||
PF_DECL(WIMCloseHandle);
|
|
||||||
|
|
||||||
PF_INIT_OR_OUT(WIMCreateFile, wimgapi);
|
PF_INIT_OR_OUT(WIMCreateFile, wimgapi);
|
||||||
PF_INIT_OR_OUT(WIMSetTemporaryPath, wimgapi);
|
PF_INIT_OR_OUT(WIMSetTemporaryPath, wimgapi);
|
||||||
|
@ -77,37 +108,36 @@ BOOL WIMExtractFile(const char* image, int index, const char* src, const char* d
|
||||||
PF_INIT_OR_OUT(WIMExtractImagePath, wimgapi);
|
PF_INIT_OR_OUT(WIMExtractImagePath, wimgapi);
|
||||||
PF_INIT_OR_OUT(WIMCloseHandle, wimgapi);
|
PF_INIT_OR_OUT(WIMCloseHandle, wimgapi);
|
||||||
|
|
||||||
// TODO: check for NULL and missing wimgapi.dll
|
uprintf("Opening: %s:[%d] (API)\n", image, index);
|
||||||
|
|
||||||
if (GetTempPathW(ARRAYSIZE(wtemp), wtemp) == 0) {
|
if (GetTempPathW(ARRAYSIZE(wtemp), wtemp) == 0) {
|
||||||
uprintf("Could not fetch temp path: %s\n", WindowsErrorString());
|
uprintf(" Could not fetch temp path: %s\n", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
uprintf("Opening: %s (index #%d)\n", image, index);
|
|
||||||
hWim = pfWIMCreateFile(wimage, WIM_GENERIC_READ, WIM_OPEN_EXISTING, 0, 0, &dw);
|
hWim = pfWIMCreateFile(wimage, WIM_GENERIC_READ, WIM_OPEN_EXISTING, 0, 0, &dw);
|
||||||
if (hWim == NULL) {
|
if (hWim == NULL) {
|
||||||
uprintf(" Error: '%s': %s\n", WindowsErrorString());
|
uprintf(" Could not access image: %s\n", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pfWIMSetTemporaryPath(hWim, wtemp)) {
|
if (!pfWIMSetTemporaryPath(hWim, wtemp)) {
|
||||||
uprintf(" Error setting temp path: %s\n", WindowsErrorString());
|
uprintf(" Could not set temp path: %s\n", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
hImage = pfWIMLoadImage(hWim, (DWORD)index);
|
hImage = pfWIMLoadImage(hWim, (DWORD)index);
|
||||||
if (hImage == NULL) {
|
if (hImage == NULL) {
|
||||||
uprintf(" Error setting index: %s.\n", WindowsErrorString());
|
uprintf(" Could not set index: %s\n", WindowsErrorString());
|
||||||
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;
|
||||||
}
|
}
|
||||||
r = TRUE;
|
r = TRUE;
|
||||||
|
UpdateProgress(OP_FINALIZE, -1.0f);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if ((hImage != NULL) || (hWim != NULL)) {
|
if ((hImage != NULL) || (hWim != NULL)) {
|
||||||
|
@ -120,3 +150,69 @@ out:
|
||||||
safe_free(wdst);
|
safe_free(wdst);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extract a file from a WIM image using 7-Zip
|
||||||
|
static BOOL WimExtractFile_7z(const char* image, int index, const char* src, const char* dst)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
STARTUPINFOA si = {0};
|
||||||
|
PROCESS_INFORMATION pi = {0};
|
||||||
|
char sevenzip_path[MAX_PATH];
|
||||||
|
char cmdline[MAX_PATH];
|
||||||
|
char tmpdst[MAX_PATH];
|
||||||
|
|
||||||
|
uprintf("Opening: %s:[%d] (7-Zip)\n", image, index);
|
||||||
|
if (!GetRegistryKeyStr("7-Zip\\Path", sevenzip_path, sizeof(sevenzip_path))) {
|
||||||
|
uprintf(" Could not read 7-Zip path from registry\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
safe_strcat(sevenzip_path, sizeof(sevenzip_path), "\\7z.exe");
|
||||||
|
|
||||||
|
if (_access(sevenzip_path, 0) == -1) {
|
||||||
|
uprintf(" Could not locate 7z.exe at '%s'\n", sevenzip_path);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
safe_strcpy(tmpdst, sizeof(tmpdst), dst);
|
||||||
|
for (i=safe_strlen(tmpdst); i>0; i--) {
|
||||||
|
if (tmpdst[i] == '\\')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tmpdst[i] = 0;
|
||||||
|
|
||||||
|
si.cb = sizeof(si);
|
||||||
|
safe_sprintf(cmdline, sizeof(cmdline), "7z -y e \"%s\" %d\\Windows\\Boot\\EFI\\bootmgfw.efi", image, index);
|
||||||
|
uprintf("Extracting: %s (From \\%s)\n", dst, src);
|
||||||
|
if (!CreateProcessU(sevenzip_path, cmdline, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, tmpdst, &si, &pi)) {
|
||||||
|
uprintf(" Could not launch 7z.exe: %s\n", WindowsErrorString());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||||
|
UpdateProgress(OP_FINALIZE, -1.0f);
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
|
||||||
|
safe_strcat(tmpdst, sizeof(tmpdst), "\\bootmgfw.efi");
|
||||||
|
if (_access(tmpdst, 0) == -1) {
|
||||||
|
uprintf(" 7z.exe did not extract %s\n", tmpdst);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (rename(tmpdst, dst) != 0) {
|
||||||
|
uprintf(" Could not rename %s to %s\n", tmpdst, dst);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract a file from a WIM image
|
||||||
|
BOOL WimExtractFile(const char* image, int index, const char* src, const char* dst)
|
||||||
|
{
|
||||||
|
if ((!has_wimgapi) && (!has_7z) && (!WimExtractCheck()))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// Prefer 7-Zip as, unsurprisingly, it's faster than the Microsoft way,
|
||||||
|
// but allow fallback if 7-Zip doesn't succeed
|
||||||
|
return ( (has_7z && WimExtractFile_7z(image, index, src, dst))
|
||||||
|
|| (has_wimgapi && WimExtractFile_API(image, index, src, dst)) );
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue