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

[core] fix MBR protective message overwriting the primary GPT

* We distractedly chose to populate the message from our protective MBR
  for GPT/UEFI-only boot media into the 4KB that directly followed the
  MBR, which of course is space that is being used by the primary GPT.
* This resulted on systems having to fall back to using the secondary
  GPT, which not all appear to be designed to do.
* Alter the code to ensure the protective message is written at LBA 34,
  after the primary GPT.
* Closes #1507
This commit is contained in:
Pete Batard 2020-04-13 17:05:33 +01:00
parent 129aa64394
commit 2dd538b7cb
No known key found for this signature in database
GPG key ID: 38E0CF5E69EDD671
9 changed files with 60 additions and 57 deletions

View file

@ -53,9 +53,11 @@ dis: $(TEST_TARGET).out
# Run the MBR in a Bochs environment (append msg.txt in subsequent blocks) # Run the MBR in a Bochs environment (append msg.txt in subsequent blocks)
test: $(TEST_TARGET).bin test: $(TEST_TARGET).bin
@test -s $(BOCHS) || { echo "Error: $(BOCHS) was not found on this system"; exit 1; } @test -s $(BOCHS) || { echo "Error: $(BOCHS) was not found on this system"; exit 1; }
@cat $(TEST_TARGET).bin msg.txt > disk.img @cp $(TEST_TARGET).bin disk.img
@truncate -c -s 17K disk.img
@cat msg.txt >> disk.img
@truncate -c -s 10M disk.img @truncate -c -s 10M disk.img
-@$(BOCHS) -f bochsrc.bxrc -q @-$(BOCHS) -f bochsrc.bxrc -q
%.out: %.o mbr.ld %.out: %.o mbr.ld
@echo "[LD] $@" @echo "[LD] $@"

Binary file not shown.

View file

@ -31,6 +31,7 @@
/********************************************************************************/ /********************************************************************************/
MBR_ADDR = 0x7c00 MBR_ADDR = 0x7c00
MBR_RESERVED = 0x1b8 # Start of the reserved section (partition table, etc.) MBR_RESERVED = 0x1b8 # Start of the reserved section (partition table, etc.)
MSG_SECTOR = 0x22 # First sector of the message (must be after the GPT)
NB_SECTORS = 0x08 # Number of sectors to read NB_SECTORS = 0x08 # Number of sectors to read
PT_MAX = 0x04 # Number of partition entries in the partition table PT_MAX = 0x04 # Number of partition entries in the partition table
PT_ENTRY_SIZE = 0x10 # Size of a partition entry in the partition table PT_ENTRY_SIZE = 0x10 # Size of a partition entry in the partition table
@ -109,10 +110,9 @@ read_sectors: # Copy the next sectors into RAM
ext: # http://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D42h:_Extended_Read_Sectors_From_Drive ext: # http://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D42h:_Extended_Read_Sectors_From_Drive
xor eax, eax xor eax, eax
push eax # bits 32-63 of sector address push eax # bits 32-63 of sector address
inc eax push MSG_SECTOR # bits 0-31 of sector address
push eax # bits 0-31 of sector address
push es # destination segment push es # destination segment
push 0x0000 # destination address push eax # destination address (0)
push NB_SECTORS # number of sectors to be read push NB_SECTORS # number of sectors to be read
push 0x0010 # size of DAP struct push 0x0010 # size of DAP struct
mov si, sp # DAP address (= stack) mov si, sp # DAP address (= stack)
@ -125,7 +125,7 @@ ext: # http://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D42h:_Extended_Read_Sect
no_ext: # http://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D02h:_Read_Sectors_From_Drive no_ext: # http://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D02h:_Read_Sectors_From_Drive
mov ax, 0x0200 + NB_SECTORS mov ax, 0x0200 + NB_SECTORS
mov cx, 0x0002 # Sector address (starts at 1) mov cx, (MSG_SECTOR + 1) # Sector address (starts at 1)
mov dx, 0x0080 # Drive ID mov dx, 0x0080 # Drive ID
xor bx, bx # Destination address in ES xor bx, bx # Destination address in ES
int 0x13 int 0x13

Binary file not shown.

View file

@ -10,8 +10,8 @@
boot it in BIOS/Legacy mode. THIS WILL NOT WORK! boot it in BIOS/Legacy mode. THIS WILL NOT WORK!
To remove this message you need to do \02ONE\07 of the following: To remove this message you need to do \02ONE\07 of the following:
o If this computer supports UEFI, go to the UEFI settings o If this computer supports UEFI, go to your UEFI settings
and disable or lower the priority of \09CSM/Legacy mode\07. and lower or disable the priority of \09CSM/Legacy mode\07.
o \02OR\07 Recreate the drive in Rufus and use: o \02OR\07 Recreate the drive in Rufus and use:
* \09Partition scheme\07 -> \09MBR\07. * \09Partition scheme\07 -> \09MBR\07.
* \09Target system\07 -> \09BIOS (...)\07 * \09Target system\07 -> \09BIOS (...)\07

View file

@ -15,7 +15,8 @@ the partition table lists the disk ID for the first partition as 0x81, then it
will be swapped for 0x80. will be swapped for 0x80.
An additional MBR (msg.S) also exists in this directory, that can be used to An additional MBR (msg.S) also exists in this directory, that can be used to
display an ASCII message contained in the sectors directly following the MBR. display an ASCII message contained in the sectors following the primary GPT
(LBA sectors 34 and later).
This can be used, for instance, to display a notice for media that cannot be This can be used, for instance, to display a notice for media that cannot be
booted in BIOS/Legacy mode. booted in BIOS/Legacy mode.

View file

@ -906,7 +906,7 @@ out:
static BOOL WriteSBR(HANDLE hPhysicalDrive) static BOOL WriteSBR(HANDLE hPhysicalDrive)
{ {
// TODO: Do we need anything special for 4K sectors? // TODO: Do we need anything special for 4K sectors?
DWORD size, max_size, mbr_size = 0x200; DWORD size, max_size, br_size = 0x200;
int r, sub_type = boot_type; int r, sub_type = boot_type;
unsigned char* buf = NULL; unsigned char* buf = NULL;
FAKE_FD fake_fd = { 0 }; FAKE_FD fake_fd = { 0 };
@ -914,10 +914,6 @@ static BOOL WriteSBR(HANDLE hPhysicalDrive)
fake_fd._handle = (char*)hPhysicalDrive; fake_fd._handle = (char*)hPhysicalDrive;
set_bytes_per_sector(SelectedDrive.SectorSize); set_bytes_per_sector(SelectedDrive.SectorSize);
// Ensure that we have sufficient space for the SBR
max_size = IsChecked(IDC_OLD_BIOS_FIXES) ?
(DWORD)(SelectedDrive.SectorsPerTrack * SelectedDrive.SectorSize) : 1 * MB;
max_size -= mbr_size;
// Syslinux has precedence over Grub // Syslinux has precedence over Grub
if ((boot_type == BT_IMAGE) && (!HAS_SYSLINUX(img_report))) { if ((boot_type == BT_IMAGE) && (!HAS_SYSLINUX(img_report))) {
if (img_report.has_grub4dos) if (img_report.has_grub4dos)
@ -932,12 +928,12 @@ static BOOL WriteSBR(HANDLE hPhysicalDrive)
case BT_GRUB4DOS: case BT_GRUB4DOS:
uprintf("Writing Grub4Dos SBR"); uprintf("Writing Grub4Dos SBR");
buf = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_GR_GRUB_GRLDR_MBR), _RT_RCDATA, "grldr.mbr", &size, FALSE); buf = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_GR_GRUB_GRLDR_MBR), _RT_RCDATA, "grldr.mbr", &size, FALSE);
if ((buf == NULL) || (size <= mbr_size)) { if ((buf == NULL) || (size <= br_size)) {
uprintf("grldr.mbr is either not present or too small"); uprintf("grldr.mbr is either not present or too small");
return FALSE; return FALSE;
} }
buf = &buf[mbr_size]; buf = &buf[br_size];
size -= mbr_size; size -= br_size;
break; break;
case BT_GRUB2: case BT_GRUB2:
if (grub2_buf != NULL) { if (grub2_buf != NULL) {
@ -957,6 +953,7 @@ static BOOL WriteSBR(HANDLE hPhysicalDrive)
case BT_NON_BOOTABLE: case BT_NON_BOOTABLE:
uprintf("Writing protective message SBR"); uprintf("Writing protective message SBR");
size = 4 * KB; size = 4 * KB;
br_size = 17 * KB; // 34 sectors are reserved for protective MBR + primary GPT
buf = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_SBR_MSG), _RT_RCDATA, "msg.txt", &size, TRUE); buf = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_SBR_MSG), _RT_RCDATA, "msg.txt", &size, TRUE);
if (buf == NULL) { if (buf == NULL) {
uprintf("Could not access message"); uprintf("Could not access message");
@ -968,11 +965,15 @@ static BOOL WriteSBR(HANDLE hPhysicalDrive)
return TRUE; return TRUE;
} }
if (size > max_size) { // Ensure that we have sufficient space for the SBR
max_size = IsChecked(IDC_OLD_BIOS_FIXES) ?
(DWORD)(SelectedDrive.SectorsPerTrack * SelectedDrive.SectorSize) : 1 * MB;
if (br_size + size > max_size) {
uprintf(" SBR size is too large - You may need to uncheck 'Add fixes for old BIOSes'."); uprintf(" SBR size is too large - You may need to uncheck 'Add fixes for old BIOSes'.");
return FALSE; return FALSE;
} }
r = write_data(fp, mbr_size, buf, (uint64_t)size);
r = write_data(fp, br_size, buf, (uint64_t)size);
safe_free(grub2_buf); safe_free(grub2_buf);
if (sub_type == BT_NON_BOOTABLE) if (sub_type == BT_NON_BOOTABLE)
safe_free(buf); safe_free(buf);

View file

@ -1,6 +1,6 @@
/* /*
* Rufus message MBR - Displays an ASCII text message contained in the * Rufus message MBR - Displays an ASCII text message contained in the
* next 4 KB of sectors that follow. * 4 KB of sectors starting at LBA 34 (i.e. after the primary GPT if any).
* See https://github.com/pbatard/rufus/tree/master/res/mbr * See https://github.com/pbatard/rufus/tree/master/res/mbr
* Copyright © 2019-2020 Pete Batard <pete@akeo.ie> * Copyright © 2019-2020 Pete Batard <pete@akeo.ie>
*/ */
@ -11,36 +11,35 @@ unsigned char mbr_msg_rufus_0x0[] = {
0x89, 0x07, 0xC1, 0xE0, 0x06, 0x8E, 0xC0, 0xB7, 0x07, 0xB8, 0x7F, 0x00, 0x89, 0x07, 0xC1, 0xE0, 0x06, 0x8E, 0xC0, 0xB7, 0x07, 0xB8, 0x7F, 0x00,
0xCD, 0x10, 0x31, 0xDB, 0x31, 0xC9, 0xBA, 0x4F, 0x18, 0xB8, 0x00, 0x06, 0xCD, 0x10, 0x31, 0xDB, 0x31, 0xC9, 0xBA, 0x4F, 0x18, 0xB8, 0x00, 0x06,
0xCD, 0x10, 0x31, 0xD2, 0xB4, 0x02, 0xCD, 0x10, 0xB4, 0x41, 0xBB, 0xAA, 0xCD, 0x10, 0x31, 0xD2, 0xB4, 0x02, 0xCD, 0x10, 0xB4, 0x41, 0xBB, 0xAA,
0x55, 0xCD, 0x13, 0x72, 0x29, 0x81, 0xFB, 0x55, 0xAA, 0x75, 0x23, 0xF7, 0x55, 0xCD, 0x13, 0x72, 0x27, 0x81, 0xFB, 0x55, 0xAA, 0x75, 0x21, 0xF7,
0xC1, 0x01, 0x00, 0x74, 0x1D, 0x66, 0x31, 0xC0, 0x66, 0x50, 0x66, 0x40, 0xC1, 0x01, 0x00, 0x74, 0x1B, 0x66, 0x31, 0xC0, 0x66, 0x50, 0x6A, 0x22,
0x66, 0x50, 0x06, 0x6A, 0x00, 0x6A, 0x08, 0x6A, 0x10, 0x89, 0xE6, 0xB4, 0x06, 0x66, 0x50, 0x6A, 0x08, 0x6A, 0x10, 0x89, 0xE6, 0xB4, 0x42, 0xCD,
0x42, 0xCD, 0x13, 0x9F, 0x83, 0xC4, 0x10, 0x9E, 0xEB, 0x0D, 0xB8, 0x08, 0x13, 0x9F, 0x83, 0xC4, 0x10, 0x9E, 0xEB, 0x0D, 0xB8, 0x08, 0x02, 0xB9,
0x02, 0xB9, 0x02, 0x00, 0xBA, 0x80, 0x00, 0x31, 0xDB, 0xCD, 0x13, 0xBB, 0x23, 0x00, 0xBA, 0x80, 0x00, 0x31, 0xDB, 0xCD, 0x13, 0xBB, 0x07, 0x00,
0x07, 0x00, 0x72, 0x0B, 0x31, 0xF6, 0x8C, 0xC0, 0x8E, 0xD8, 0xE8, 0x3F, 0x72, 0x0B, 0x31, 0xF6, 0x8C, 0xC0, 0x8E, 0xD8, 0xE8, 0x3F, 0x00, 0xEB,
0x00, 0xEB, 0x06, 0xBE, 0x19, 0x7D, 0xE8, 0x37, 0x00, 0x31, 0xC0, 0x8E, 0x06, 0xBE, 0x17, 0x7D, 0xE8, 0x37, 0x00, 0x31, 0xC0, 0x8E, 0xD8, 0xBE,
0xD8, 0xBE, 0x65, 0x7D, 0xE8, 0x2D, 0x00, 0xE8, 0x1D, 0x00, 0xB4, 0x01, 0x63, 0x7D, 0xE8, 0x2D, 0x00, 0xE8, 0x1D, 0x00, 0xB4, 0x01, 0xCD, 0x16,
0xCD, 0x16, 0x75, 0x08, 0xB4, 0x02, 0xCD, 0x16, 0x24, 0x04, 0x74, 0xF2, 0x75, 0x08, 0xB4, 0x02, 0xCD, 0x16, 0x24, 0x04, 0x74, 0xF2, 0x31, 0xC0,
0x31, 0xC0, 0x8E, 0xD8, 0xB8, 0x34, 0x12, 0xA3, 0x73, 0x04, 0xEA, 0x00, 0x8E, 0xD8, 0xB8, 0x34, 0x12, 0xA3, 0x73, 0x04, 0xEA, 0x00, 0x00, 0xFF,
0x00, 0xFF, 0xFF, 0xB4, 0x01, 0xCD, 0x16, 0x74, 0x06, 0xB4, 0x00, 0xCD, 0xFF, 0xB4, 0x01, 0xCD, 0x16, 0x74, 0x06, 0xB4, 0x00, 0xCD, 0x16, 0xE2,
0x16, 0xE2, 0xF4, 0xC3, 0xAC, 0x3C, 0x00, 0x74, 0x4F, 0x3C, 0x0D, 0x74, 0xF4, 0xC3, 0xAC, 0x3C, 0x00, 0x74, 0x4F, 0x3C, 0x0D, 0x74, 0xF7, 0x3C,
0xF7, 0x3C, 0x0A, 0x75, 0x10, 0x53, 0xB4, 0x03, 0xCD, 0x10, 0xFE, 0xC6, 0x0A, 0x75, 0x10, 0x53, 0xB4, 0x03, 0xCD, 0x10, 0xFE, 0xC6, 0xB2, 0x00,
0xB2, 0x00, 0xB4, 0x02, 0xCD, 0x10, 0x5B, 0xEB, 0xE3, 0x3C, 0x5C, 0x75, 0xB4, 0x02, 0xCD, 0x10, 0x5B, 0xEB, 0xE3, 0x3C, 0x5C, 0x75, 0x1C, 0xB1,
0x1C, 0xB1, 0x02, 0xAC, 0x3C, 0x46, 0x7F, 0xD8, 0x2C, 0x30, 0x3C, 0x09, 0x02, 0xAC, 0x3C, 0x46, 0x7F, 0xD8, 0x2C, 0x30, 0x3C, 0x09, 0x7E, 0x02,
0x7E, 0x02, 0x2C, 0x07, 0xC0, 0xE3, 0x04, 0x24, 0x0F, 0x08, 0xC3, 0xFE, 0x2C, 0x07, 0xC0, 0xE3, 0x04, 0x24, 0x0F, 0x08, 0xC3, 0xFE, 0xC9, 0x75,
0xC9, 0x75, 0xE8, 0xEB, 0xC3, 0xB9, 0x01, 0x00, 0xB4, 0x09, 0xCD, 0x10, 0xE8, 0xEB, 0xC3, 0xB9, 0x01, 0x00, 0xB4, 0x09, 0xCD, 0x10, 0x53, 0x31,
0x53, 0x31, 0xDB, 0xB4, 0x03, 0xCD, 0x10, 0xFE, 0xC2, 0xB4, 0x02, 0xCD, 0xDB, 0xB4, 0x03, 0xCD, 0x10, 0xFE, 0xC2, 0xB4, 0x02, 0xCD, 0x10, 0x5B,
0x10, 0x5B, 0xEB, 0xAC, 0xC3, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0xEB, 0xAC, 0xC3, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5C, 0x30, 0x34, 0x2A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5C, 0x30, 0x34, 0x2A, 0x2A, 0x2A,
0x2A, 0x2A, 0x20, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x3A, 0x20, 0x54, 0x48, 0x20, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x3A, 0x20, 0x54, 0x48, 0x49, 0x53,
0x49, 0x53, 0x20, 0x4D, 0x45, 0x44, 0x49, 0x41, 0x20, 0x43, 0x41, 0x4E, 0x20, 0x4D, 0x45, 0x44, 0x49, 0x41, 0x20, 0x43, 0x41, 0x4E, 0x4E, 0x4F,
0x4E, 0x4F, 0x54, 0x20, 0x42, 0x4F, 0x4F, 0x54, 0x20, 0x49, 0x4E, 0x20, 0x54, 0x20, 0x42, 0x4F, 0x4F, 0x54, 0x20, 0x49, 0x4E, 0x20, 0x4C, 0x45,
0x4C, 0x45, 0x47, 0x41, 0x43, 0x59, 0x20, 0x4D, 0x4F, 0x44, 0x45, 0x20, 0x47, 0x41, 0x43, 0x59, 0x20, 0x4D, 0x4F, 0x44, 0x45, 0x20, 0x2A, 0x2A,
0x2A, 0x2A, 0x2A, 0x5C, 0x30, 0x37, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x0D, 0x2A, 0x5C, 0x30, 0x37, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x0D, 0x0A, 0x20,
0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x5C, 0x37, 0x30, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x5C, 0x37, 0x30, 0x50, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x20, 0x72, 0x65,
0x72, 0x65, 0x6D, 0x6F, 0x76, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6D, 0x6F, 0x76, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6D, 0x65,
0x6D, 0x65, 0x64, 0x69, 0x61, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x70, 0x72, 0x64, 0x69, 0x61, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x70, 0x72, 0x65, 0x73,
0x65, 0x73, 0x73, 0x20, 0x61, 0x6E, 0x79, 0x20, 0x6B, 0x65, 0x79, 0x20, 0x73, 0x20, 0x61, 0x6E, 0x79, 0x20, 0x6B, 0x65, 0x79, 0x20, 0x74, 0x6F,
0x74, 0x6F, 0x20, 0x72, 0x65, 0x62, 0x6F, 0x6F, 0x74, 0x5C, 0x30, 0x37, 0x20, 0x72, 0x65, 0x62, 0x6F, 0x6F, 0x74, 0x5C, 0x30, 0x37, 0x00, 0x00,
0x00,
}; };

View file

@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 232, 326 IDD_DIALOG DIALOGEX 12, 12, 232, 326
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_ACCEPTFILES EXSTYLE WS_EX_ACCEPTFILES
CAPTION "Rufus 3.10.1639" CAPTION "Rufus 3.10.1640"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0 FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@ -395,8 +395,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,10,1639,0 FILEVERSION 3,10,1640,0
PRODUCTVERSION 3,10,1639,0 PRODUCTVERSION 3,10,1640,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -414,13 +414,13 @@ BEGIN
VALUE "Comments", "https://rufus.ie" VALUE "Comments", "https://rufus.ie"
VALUE "CompanyName", "Akeo Consulting" VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus" VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "3.10.1639" VALUE "FileVersion", "3.10.1640"
VALUE "InternalName", "Rufus" VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)" VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
VALUE "OriginalFilename", "rufus-3.10.exe" VALUE "OriginalFilename", "rufus-3.10.exe"
VALUE "ProductName", "Rufus" VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "3.10.1639" VALUE "ProductVersion", "3.10.1640"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"