[core] enable UEFI NTFS support

* This allows no-sweat UEFI support of Windows installation ISOs
  that contain a >4GB file for instance
* This is done through UEFI:TOGO (https://github.com/pbatard/uefi-togo)
  and the efifs NTFS driver (http://efi.akeo.ie)
* Closes #414
* This will also be part of our implementation of #126
This commit is contained in:
Pete Batard 2014-12-20 00:22:00 +00:00
parent 420db67ce1
commit d81f83c110
11 changed files with 115 additions and 34 deletions

View File

@ -4,7 +4,6 @@ This directory contains the Grub 2.0 boot records that are used by Rufus
commit 72ec399ad8d6348b6c74ea63d80c79784c8b84ae, on a Debian 7.7.0 x64 system.
This was done following the guide from:
http://pete.akeo.ie/2014/05/compiling-and-installing-grub2-for.html.
Note that exFAT was not included in core.img in order to keep it under 31.5 KB.
* boot.img has been modified to nop the jump @ 0x66 as per grub2's setup.c comments:
/* If DEST_DRIVE is a hard disk, enable the workaround, which is

12
res/uefi/readme.txt Normal file
View File

@ -0,0 +1,12 @@
This directory contains a flat image of the FAT UEFI:TOGO partition added by
Rufus for Windows To Go UEFI mode support as well as seamless installation of
Windows in UEFI, in the case where the original media contains a >4GB file.
This image, which you can mount as FAT filesystem or open in 7-zip, contains
the following data:
o The NTFS UEFI driver from efifs (https://github.com/pbatard/efifs) which was
compiled, with compression disabled, using Visual Studio 2013 Community Edition.
This is the \EFI\Rufus\ntfs_x64.efi file.
o The UEFI:TOGO binary (https://github.com/pbatard/uefi-togo), which was compiled
using Visual Studio 2013 Community Edition.
This is the \EFI\Boot\bootx64.efi file.

BIN
res/uefi/uefi-togo.img Normal file

Binary file not shown.

View File

@ -645,7 +645,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
{
// MBR partition types that can be mounted in Windows
const uint8_t mbr_mountable[] = { 0x01, 0x04, 0x06, 0x07, 0x0b, 0x0c, 0x0e, 0xef };
BOOL r, hasRufusExtra = FALSE, ret = FALSE;
BOOL r, hasRufusExtra = FALSE, ret = FALSE, isUefiTogo;
HANDLE hPhysical;
DWORD size;
BYTE geometry[256], layout[4096], part_type;
@ -695,6 +695,10 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
return 0;
}
#if defined(__GNUC__)
// GCC 4.9 bug us about the fact that MS defined an expandable array as array[1]
#pragma GCC diagnostic ignored "-Warray-bounds"
#endif
switch (DriveLayout->PartitionStyle) {
case PARTITION_STYLE_MBR:
SelectedDrive.PartitionType = PARTITION_STYLE_MBR;
@ -709,8 +713,10 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
AnalyzeMBR(hPhysical, "Drive");
for (i=0; i<DriveLayout->PartitionCount; i++) {
if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) {
suprintf("Partition %d:\n", i+1);
part_type = DriveLayout->PartitionEntry[i].Mbr.PartitionType;
isUefiTogo = (i == 1) && (part_type == 0x01) &&
(DriveLayout->PartitionEntry[i].PartitionLength.QuadPart == 131072);
suprintf("Partition %d%s:\n", i+1, isUefiTogo?" (UEFI:TOGO)":"");
for (j=0; j<ARRAYSIZE(mbr_mountable); j++) {
if (part_type == mbr_mountable[j]) {
ret = TRUE;
@ -723,7 +729,8 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].Mbr.HiddenSectors,
DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No",
DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No");
if (part_type == RUFUS_EXTRA_PARTITION_TYPE) // This is a partition Rufus created => we can safely ignore it
if ((part_type == RUFUS_EXTRA_PARTITION_TYPE) || (isUefiTogo))
// This is a partition Rufus created => we can safely ignore it
hasRufusExtra = TRUE;
if (part_type == 0xee) // Flag a protective MBR for non GPT platforms (XP)
SelectedDrive.has_protective_mbr = TRUE;
@ -746,6 +753,8 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionId), SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength.QuadPart, TRUE, FALSE),
DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].StartingOffset.QuadPart / DiskGeometry->Geometry.BytesPerSector,
DriveLayout->PartitionEntry[i].Gpt.Attributes);
if (safe_strcmp(tmp, "UEFI:TOGO") == 0)
hasRufusExtra = TRUE;
if ( (memcmp(&PARTITION_BASIC_DATA_GUID, &DriveLayout->PartitionEntry[i].Gpt.PartitionType, sizeof(GUID)) == 0) &&
(nWindowsVersion >= WINDOWS_VISTA) )
ret = TRUE;
@ -756,6 +765,9 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
suprintf("Partition type: RAW\n");
break;
}
#if defined(__GNUC__)
#pragma GCC diagnostic warning "-Warray-bounds"
#endif
safe_closehandle(hPhysical);
if (hasRufusExtra)
@ -889,14 +901,15 @@ typedef struct _DRIVE_LAYOUT_INFORMATION_EX4 {
* copy it got from the last IOCTL, and ignores your changes until you replug the drive
* or issue an IOCTL_DISK_UPDATE_PROPERTIES.
*/
BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker)
BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, BOOL add_uefi_togo)
{
const char* PartitionTypeName[2] = { "MBR", "GPT" };
unsigned char* buffer;
CREATE_DISK CreateDisk = {PARTITION_STYLE_RAW, {{0}}};
DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = {0};
BOOL r;
DWORD size;
LONGLONG size_in_sectors;
DWORD size, bufsize;
LONGLONG size_in_sectors, extra_size_in_tracks = 1;
PrintStatus(0, TRUE, MSG_238, PartitionTypeName[partition_style]);
@ -908,8 +921,18 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart =
SelectedDrive.Geometry.BytesPerSector * SelectedDrive.Geometry.SectorsPerTrack;
}
// TODO: should we try to align the following to the cluster size as well?
size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart) / SelectedDrive.Geometry.BytesPerSector;
// Align on track boundary if the extra part option is checked
if ((partition_style == PARTITION_STYLE_MBR) && ((IsChecked(IDC_EXTRA_PARTITION)) || (add_uefi_togo))) {
if (add_uefi_togo) // Already set to 1 track in non To_Go mode
extra_size_in_tracks = (MIN_EXTRA_PART_SIZE + SelectedDrive.Geometry.SectorsPerTrack - 1) /
SelectedDrive.Geometry.SectorsPerTrack;
uprintf("Reserving %d tracks for extra partition", extra_size_in_tracks);
size_in_sectors = ((size_in_sectors / SelectedDrive.Geometry.SectorsPerTrack) - extra_size_in_tracks) *
SelectedDrive.Geometry.SectorsPerTrack;
if (size_in_sectors <= 0)
return FALSE;
}
switch (partition_style) {
case PARTITION_STYLE_MBR:
@ -927,13 +950,6 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
// 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:
// TODO: (?) As per MSDN: "When specifying a GUID partition table (GPT) as the PARTITION_STYLE of the CREATE_DISK
@ -945,7 +961,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
CreateDisk.Gpt.MaxPartitionCount = MAX_GPT_PARTITIONS;
DriveLayoutEx.PartitionStyle = PARTITION_STYLE_GPT;
DriveLayoutEx.PartitionCount = 1;
DriveLayoutEx.PartitionCount = (add_uefi_togo)?2:1;
// At the very least, a GPT disk has 34 reserved sectors at the beginning and 33 at the end.
DriveLayoutEx.Type.Gpt.StartingUsableOffset.QuadPart = 34 * SelectedDrive.Geometry.BytesPerSector;
DriveLayoutEx.Type.Gpt.UsableLength.QuadPart = SelectedDrive.DiskSize - (34+33) * SelectedDrive.Geometry.BytesPerSector;
@ -984,18 +1000,24 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
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)) {
// Create an extra partition on request
if (IsChecked(IDC_EXTRA_PARTITION) || (add_uefi_togo)) {
DriveLayoutEx.PartitionEntry[1].PartitionStyle = PARTITION_STYLE_MBR;
// Should end on a sector boundary
// Should end on a track 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;
if (add_uefi_togo) {
DriveLayoutEx.PartitionEntry[1].PartitionLength.QuadPart =
GetResourceSize(hMainInstance, MAKEINTRESOURCEA(IDR_UEFI_TOGO), _RT_RCDATA, "uefi-togo.img");
} else {
DriveLayoutEx.PartitionEntry[1].PartitionLength.QuadPart = extra_size_in_tracks *
SelectedDrive.Geometry.SectorsPerTrack * SelectedDrive.Geometry.BytesPerSector;
}
DriveLayoutEx.PartitionEntry[1].PartitionNumber = 2;
DriveLayoutEx.PartitionEntry[1].RewritePartition = TRUE;
DriveLayoutEx.PartitionEntry[1].Mbr.BootIndicator = FALSE;
DriveLayoutEx.PartitionEntry[1].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack*SelectedDrive.Geometry.BytesPerSector;
DriveLayoutEx.PartitionEntry[1].Mbr.PartitionType = RUFUS_EXTRA_PARTITION_TYPE;
DriveLayoutEx.PartitionEntry[1].Mbr.PartitionType = (add_uefi_togo)?0x01:RUFUS_EXTRA_PARTITION_TYPE;
}
// For the remaining partitions, PartitionStyle & PartitionType have already
// been zeroed => already set to MBR/unused
@ -1003,12 +1025,48 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
case PARTITION_STYLE_GPT:
DriveLayoutEx.PartitionEntry[0].Gpt.PartitionType = PARTITION_BASIC_DATA_GUID;
wcscpy(DriveLayoutEx.PartitionEntry[0].Gpt.Name, L"Microsoft Basic Data");
if (add_uefi_togo) {
DriveLayoutEx.PartitionEntry[1].Gpt.PartitionType = PARTITION_BASIC_DATA_GUID;
wcscpy(DriveLayoutEx.PartitionEntry[1].Gpt.Name, L"UEFI:TOGO");
DriveLayoutEx.PartitionEntry[1].PartitionNumber = 2;
DriveLayoutEx.PartitionEntry[1].RewritePartition = TRUE;
DriveLayoutEx.PartitionEntry[1].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart +
DriveLayoutEx.PartitionEntry[0].PartitionLength.QuadPart;
DriveLayoutEx.PartitionEntry[1].PartitionLength.QuadPart =
GetResourceSize(hMainInstance, MAKEINTRESOURCEA(IDR_UEFI_TOGO), _RT_RCDATA, "uefi-togo.img");
}
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[0].Gpt.PartitionId));
IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[1].Gpt.PartitionId));
break;
default:
break;
}
// We need to write the extra partition before we refresh the disk
if (add_uefi_togo) {
uprintf("Writing UEFI:TOGO partition...");
if (!SetFilePointerEx(hDrive, DriveLayoutEx.PartitionEntry[1].StartingOffset, NULL, FILE_BEGIN)) {
uprintf("Unable to set position");
safe_closehandle(hDrive);
return FALSE;
}
buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_UEFI_TOGO), _RT_RCDATA, "uefi-togo.img", &bufsize, FALSE);
if (buffer == NULL) {
uprintf("Could not access uefi-togo.img");
safe_closehandle(hDrive);
return FALSE;
}
r = WriteFile(hDrive, buffer, bufsize, &size, NULL);
if ((!r) || (size != bufsize)) {
if (!r)
uprintf("Write error: %s", WindowsErrorString());
else
uprintf("Write error: Wrote %d bytes, expected %d bytes\n", size, bufsize);
safe_closehandle(hDrive);
return FALSE;
}
}
// If you don't call IOCTL_DISK_CREATE_DISK, the next call will fail
size = sizeof(CreateDisk);
r = DeviceIoControl(hDrive, IOCTL_DISK_CREATE_DISK,
@ -1019,7 +1077,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
return FALSE;
}
size = sizeof(DriveLayoutEx) - ((partition_style == PARTITION_STYLE_GPT)?(3*sizeof(PARTITION_INFORMATION_EX)):0);
size = sizeof(DriveLayoutEx) - ((partition_style == PARTITION_STYLE_GPT)?((add_uefi_togo?2:3)*sizeof(PARTITION_INFORMATION_EX)):0);
r = DeviceIoControl(hDrive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX,
(BYTE*)&DriveLayoutEx, size, NULL, 0, &size, NULL );
if (!r) {

View File

@ -63,7 +63,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
BOOL UnmountVolume(HANDLE hDrive);
BOOL MountVolume(char* drive_name, char *drive_guid);
BOOL RemountVolume(char* drive_name);
BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker);
BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, BOOL add_uefi_togo);
BOOL DeletePartitions(HANDLE hDrive);
BOOL RefreshDriveLayout(HANDLE hDrive);
const char* GetPartitionType(BYTE Type);

View File

@ -1271,7 +1271,7 @@ DWORD WINAPI CloseFormatPromptThread(LPVOID param) {
DWORD WINAPI FormatThread(void* param)
{
int i, r, pt, bt, fs, dt;
BOOL s, ret, use_large_fat32;
BOOL s, ret, use_large_fat32, add_uefi_togo;
const DWORD SectorSize = SelectedDrive.Geometry.BytesPerSector;
DWORD rSize, wSize, BufSize, LastRefresh = 0, DriveIndex = (DWORD)(uintptr_t)param;
HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;
@ -1301,6 +1301,7 @@ DWORD WINAPI FormatThread(void* param)
pt = GETPARTTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)));
bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)));
use_large_fat32 = (fs == FS_FAT32) && ((SelectedDrive.DiskSize > LARGE_FAT32_SIZE) || (force_large_fat32));
add_uefi_togo = (fs == FS_NTFS) && (dt == DT_ISO) && (IS_EFI(iso_report)) && (bt == BT_UEFI);
PrintStatus(0, TRUE, MSG_225);
hPhysicalDrive = GetPhysicalHandle(DriveIndex, TRUE, TRUE);
@ -1531,7 +1532,7 @@ DWORD WINAPI FormatThread(void* param)
UpdateProgress(OP_ZERO_MBR, -1.0f);
CHECK_FOR_USER_CANCEL;
if (!CreatePartition(hPhysicalDrive, pt, fs, (pt==PARTITION_STYLE_MBR)&&(bt==BT_UEFI))) {
if (!CreatePartition(hPhysicalDrive, pt, fs, (pt==PARTITION_STYLE_MBR) && (bt==BT_UEFI), add_uefi_togo)) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE;
goto out;
}

View File

@ -73,6 +73,7 @@
#define IDR_GR_GRUB2_CORE_IMG 451
#define IDR_LC_RUFUS_LOC 500
#define IDR_XT_HOGGER 501
#define IDR_UEFI_TOGO 502
#define IDC_DEVICE 1001
#define IDC_FILESYSTEM 1002
#define IDC_START 1003

View File

@ -460,7 +460,8 @@ static void SetFSFromISO(void)
}
// Syslinux and EFI have precedence over bootmgr (unless the user selected BIOS as target type)
if ((HAS_SYSLINUX(iso_report)) || (IS_REACTOS(iso_report)) || (iso_report.has_kolibrios) || ( (IS_EFI(iso_report)) && (bt == BT_UEFI))) {
if ((HAS_SYSLINUX(iso_report)) || (IS_REACTOS(iso_report)) || (iso_report.has_kolibrios) ||
((IS_EFI(iso_report)) && (bt == BT_UEFI) && (!iso_report.has_4GB_file))) {
if (fs_mask & (1<<FS_FAT32)) {
selected_fs = FS_FAT32;
} else if ((fs_mask & (1<<FS_FAT16)) && (!iso_report.has_kolibrios)) {

View File

@ -42,6 +42,7 @@
#define DRIVE_ACCESS_RETRIES 60 // How many times we should retry
#define DRIVE_INDEX_MIN 0x00000080
#define DRIVE_INDEX_MAX 0x000000C0
#define MIN_EXTRA_PART_SIZE 2048 // Minimum size of the extra partition, in sectors
#define MAX_DRIVES (DRIVE_INDEX_MAX - DRIVE_INDEX_MIN)
#define MAX_TOOLTIPS 128
#define MAX_SIZE_SUFFIXES 6 // bytes, KB, MB, GB, TB, PB
@ -384,6 +385,7 @@ extern BOOL SetAutorun(const char* path);
extern char* FileDialog(BOOL save, char* path, const ext_t* ext, DWORD options);
extern BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size);
extern unsigned char* GetResource(HMODULE module, char* name, char* type, const char* desc, DWORD* len, BOOL duplicate);
extern DWORD GetResourceSize(HMODULE module, char* name, char* type, const char* desc);
extern BOOL GetUSBDevices(DWORD devnum);
extern BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue);
extern LONG GetEntryWidth(HWND hDropDown, const char* entry);

View File

@ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 242, 329
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Rufus 1.5.0.559"
CAPTION "Rufus 1.5.0.560"
FONT 8, "Segoe UI", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,291,50,14
@ -164,7 +164,7 @@ END
IDD_DIALOG_XP DIALOGEX 12, 12, 242, 329
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Rufus 1.5.0.559"
CAPTION "Rufus 1.5.0.560"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,291,50,14
@ -297,7 +297,7 @@ END
IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 329
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL
CAPTION "Rufus 1.5.0.559"
CAPTION "Rufus 1.5.0.560"
FONT 8, "Segoe UI", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,291,50,14
@ -437,7 +437,7 @@ END
IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 329
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL
CAPTION "Rufus 1.5.0.559"
CAPTION "Rufus 1.5.0.560"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,291,50,14
@ -641,6 +641,7 @@ BEGIN
"IDR_FD_EGA17_CPX RCDATA ""../res/freedos/ega17.cpx""\r\n"
"IDR_FD_EGA18_CPX RCDATA ""../res/freedos/ega18.cpx""\r\n"
"IDR_XT_HOGGER RCDATA ""../res/hogger/hogger.exe""\r\n"
"IDR_UEFI_TOGO RCDATA ""../res/uefi/uefi-togo.img""\r\n"
"\r\n"
"// Must reference a manifest for visual styles and elevation\r\n"
"// Oh, and it must happen at the end, or MinGW will ignore it!\r\n"
@ -702,8 +703,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,5,0,559
PRODUCTVERSION 1,5,0,559
FILEVERSION 1,5,0,560
PRODUCTVERSION 1,5,0,560
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -720,13 +721,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "1.5.0.559"
VALUE "FileVersion", "1.5.0.560"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2014 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "1.5.0.559"
VALUE "ProductVersion", "1.5.0.560"
END
END
BLOCK "VarFileInfo"
@ -797,6 +798,7 @@ IDR_FD_EGA16_CPX RCDATA "../res/freedos/ega16.cpx"
IDR_FD_EGA17_CPX RCDATA "../res/freedos/ega17.cpx"
IDR_FD_EGA18_CPX RCDATA "../res/freedos/ega18.cpx"
IDR_XT_HOGGER RCDATA "../res/hogger/hogger.exe"
IDR_UEFI_TOGO RCDATA "../res/uefi/uefi-togo.img"
// Must reference a manifest for visual styles and elevation
// Oh, and it must happen at the end, or MinGW will ignore it!

View File

@ -522,6 +522,11 @@ out:
return p;
}
DWORD GetResourceSize(HMODULE module, char* name, char* type, const char* desc)
{
DWORD len = 0;
return (GetResource(module, name, type, desc, &len, FALSE) == NULL)?0:len;
}
/*
* Set or restore a Local Group Policy DWORD key indexed by szPath/SzPolicy