[FREELDR] Retrieve and store the disk GUID signature if the disk is GPT partitioned (#8843)

For fixed-disks (i.e. not floppy nor CD-ROM), check in `disk.c!DiskInitialize()`
whether the disk being enumerated is GPT. If so, retrieve its disk GUID.
Pass this information to `AddReactOSArcDiskInfo()` when filling the ARC
disk information block, which sets the `IsGpt` and `GptSignature` members
of the `ARC_DISK_SIGNATURE` structure accordingly.

Debugging output example, where the first disk (0x80) is MBR, while the
second (0x81) is GPT:
```
(freeldr\disk\disk.c:100) err: DiskInitialize(0x80, 'multi(0)disk(0)rdisk(0)', Type: 25)
(freeldr\disk\disk.c:125) err: Signature: 163fbb9d
(freeldr\disk\disk.c:134) err: Checksum: 47699104
(freeldr\disk\disk.c:137) err: IsPartitionValid: TRUE
(freeldr\disk\disk.c:100) err: DiskInitialize(0x81, 'multi(0)disk(0)rdisk(1)', Type: 25)
(freeldr\disk\disk.c:125) err: Signature: 0
(freeldr\disk\disk.c:134) err: Checksum: 9cb5ff90
(freeldr\disk\disk.c:137) err: IsPartitionValid: TRUE
(freeldr\disk\disk.c:157) err: Disk 0x81 is GPT, DiskGuid: {1e4e8972-e026-4d5f-b213-7be3f2fad3f8}
```

----

This fixes the BSOD 0x7B `INACCESSIBLE_BOOT_DEVICE` that happens when
trying to boot a ReactOS installation present in a partition on a GPT
partitioned disk.

In the kernel IO manager:
`IopCreateArcNamesDisk()`, invoked by `IopCreateArcNames()`, tries to
map the list of disks dynamically detected by the boot disk drivers
with those detected by the bootloader, by matching their disk signatures.

- The signatures of the disks detected by the boot disk drivers are
  obtained when querying their drive layout and partition table (which
  also tells whether the disk is MBR or GPT partitioned);

- while the signatures of the disks detected by the bootloader are
  enumerated in the `LoaderBlock->ArcDiskInformation->DiskSignatureListHead`
  linked-list (inside `ARC_DISK_SIGNATURE` structures).

The routine compares the disk signatures by invoking `IopVerifyDiskSignature()`,
which, depending on whether the disk is MBR or GPT (as reported in the
drive layout), compares the signature with that of `ARC_DISK_SIGNATURE`
`Signature` (for MBR) or `GptSignature` (for GPT) structure members.

In case the boot disk turns out to not be mapped -- which was the case
until now if it was GPT-partitioned -- then the `IopMarkBootPartition()`
routine invoked later, wouldn't be able to find and open the boot disk,
and would trigger the BSOD 0x7B, as the result.
This commit is contained in:
Hermès Bélusca-Maïto
2026-04-06 18:04:56 +02:00
parent 00ed55bcba
commit 7779fb4459
4 changed files with 78 additions and 35 deletions

View File

@@ -62,6 +62,9 @@ const PCSTR ArcTypes[MaximumType + 1] = // CmTypeName
"Undefined"
};
#define TAG_HW_COMPONENT_DATA 'DCwH'
#define TAG_HW_NAME 'mNwH'
PCONFIGURATION_COMPONENT_DATA FldrArcHwTreeRoot;
// ARC Disk Information
@@ -70,31 +73,54 @@ ARC_DISK_SIGNATURE_EX reactos_arc_disk_info[32];
/* FUNCTIONS ******************************************************************/
#define TAG_HW_COMPONENT_DATA 'DCwH'
#define TAG_HW_NAME 'mNwH'
VOID
AddReactOSArcDiskInfo(
IN PCSTR ArcName,
IN ULONG Signature,
IN ULONG Checksum,
IN BOOLEAN ValidPartitionTable)
_In_ PCSTR ArcName,
_In_opt_ PGUID GptDiskGuid,
_In_ ULONG Signature,
_In_ ULONG Checksum,
_In_ BOOLEAN ValidPartitionTable)
{
ASSERT(reactos_disk_count < sizeof(reactos_arc_disk_info)/sizeof(reactos_arc_disk_info[0]));
PARC_DISK_SIGNATURE ArcDiskSignature;
C_ASSERT(sizeof(*GptDiskGuid) == sizeof(ArcDiskSignature->GptSignature));
ASSERT(reactos_disk_count < RTL_NUMBER_OF(reactos_arc_disk_info));
/* Fill out the ARC disk block */
RtlZeroMemory(&reactos_arc_disk_info[reactos_disk_count],
sizeof(reactos_arc_disk_info[reactos_disk_count]));
ArcDiskSignature = &(reactos_arc_disk_info[reactos_disk_count].DiskSignature);
reactos_arc_disk_info[reactos_disk_count].DiskSignature.Signature = Signature;
reactos_arc_disk_info[reactos_disk_count].DiskSignature.CheckSum = Checksum;
reactos_arc_disk_info[reactos_disk_count].DiskSignature.ValidPartitionTable = ValidPartitionTable;
ArcDiskSignature->Signature = Signature;
ArcDiskSignature->CheckSum = Checksum;
ArcDiskSignature->ValidPartitionTable = ValidPartitionTable;
ArcDiskSignature->IsGpt = (GptDiskGuid != NULL);
if (GptDiskGuid)
{
RtlCopyMemory(&ArcDiskSignature->GptSignature,
GptDiskGuid, sizeof(*GptDiskGuid));
}
strcpy(reactos_arc_disk_info[reactos_disk_count].ArcName, ArcName);
reactos_arc_disk_info[reactos_disk_count].DiskSignature.ArcName =
reactos_arc_disk_info[reactos_disk_count].ArcName;
ArcDiskSignature->ArcName = reactos_arc_disk_info[reactos_disk_count].ArcName;
reactos_disk_count++;
++reactos_disk_count;
}
ULONG ArcGetDiskCount(VOID)
{
return reactos_disk_count;
}
PARC_DISK_SIGNATURE_EX ArcGetDiskInfo(ULONG Index)
{
if (Index >= reactos_disk_count)
return NULL;
return &reactos_arc_disk_info[Index];
}
//
// ARC Component Configuration Routines
//
@@ -243,18 +269,3 @@ FldrCreateComponentKey(
/* Return the child */
*ComponentKey = ComponentData;
}
ULONG ArcGetDiskCount(VOID)
{
return reactos_disk_count;
}
PARC_DISK_SIGNATURE_EX ArcGetDiskInfo(ULONG Index)
{
if (Index >= reactos_disk_count)
{
return NULL;
}
return &reactos_arc_disk_info[Index];
}

View File

@@ -127,7 +127,7 @@ ArmHwDetect(
RamDiskInitialize(TRUE, NULL, NULL);
/* Fill out the ARC disk block */
AddReactOSArcDiskInfo("ramdisk(0)", 0xBADAB00F, 0xDEADBABE, TRUE);
AddReactOSArcDiskInfo("ramdisk(0)", NULL, 0xBADAB00F, 0xDEADBABE, TRUE);
ASSERT(reactos_disk_count == 1);
/* Return the root node */

View File

@@ -13,6 +13,20 @@
#include <debug.h>
DBG_DEFAULT_CHANNEL(DISK);
#include "disk/part_gpt.h"
// Defined in part_gpt.c
extern BOOLEAN
DiskReadGptHeader(
_In_ UCHAR DriveNumber,
_Out_ PGPT_TABLE_HEADER GptHeader);
#define GUID_FORMAT_STR "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"
#define GUID_ELEMENTS(Guid) \
(Guid)->Data1, (Guid)->Data2, (Guid)->Data3, \
(Guid)->Data4[0], (Guid)->Data4[1], (Guid)->Data4[2], (Guid)->Data4[3], \
(Guid)->Data4[4], (Guid)->Data4[5], (Guid)->Data4[6], (Guid)->Data4[7]
#define FIRST_PARTITION 1
/* DISK IO ERROR SUPPORT *****************************************************/
@@ -77,10 +91,14 @@ DiskInitialize(
ULONG Checksum, Signature;
BOOLEAN ValidPartitionTable;
BOOLEAN IsCdRom;
PGUID GptDiskGuid = NULL;
GPT_TABLE_HEADER GptHeader;
PARTITION_TABLE_ENTRY PartitionTableEntry;
CHAR ArcName[MAX_PATH];
NTSTATUS NtStatus;
TRACE("DiskInitialize(0x%02X, '%s', Type: %lu)\n", DriveNumber, DeviceName, DeviceType);
IsCdRom = (DeviceType == CdromController);
if (IsCdRom)
{
@@ -128,8 +146,21 @@ DiskInitialize(
return ENOMEM;
}
/* GPT disk signature support */
if (DeviceType == DiskPeripheral)
{
if (DiskReadGptHeader(DriveNumber, &GptHeader))
GptDiskGuid = &GptHeader.DiskGuid;
}
if (GptDiskGuid)
{
TRACE("Disk 0x%02X is GPT, DiskGuid: {" GUID_FORMAT_STR "}\n",
DriveNumber, GUID_ELEMENTS(GptDiskGuid));
}
/* Fill out the ARC disk block */
AddReactOSArcDiskInfo(DeviceName, Signature, Checksum, ValidPartitionTable);
AddReactOSArcDiskInfo(DeviceName, GptDiskGuid, Signature,
Checksum, ValidPartitionTable);
if (pChecksum)
*pChecksum = Checksum;

View File

@@ -24,10 +24,11 @@
VOID
AddReactOSArcDiskInfo(
IN PCSTR ArcName,
IN ULONG Signature,
IN ULONG Checksum,
IN BOOLEAN ValidPartitionTable);
_In_ PCSTR ArcName,
_In_opt_ PGUID GptDiskGuid,
_In_ ULONG Signature,
_In_ ULONG Checksum,
_In_ BOOLEAN ValidPartitionTable);
//
// ARC Component Configuration Routines