15#define TAG_HW_RESOURCE_LIST 'lRwH'
16#define TAG_HW_DISK_CONTEXT 'cDwH'
17#define FIRST_BIOS_DISK 0x80
18#define FIRST_PARTITION 1
21#define MAX_SUPPORTED_BLOCK_SIZE 8192
24#define EFI_PARTITION_HEADER_SIGNATURE "EFI PART"
25#define EFI_HEADER_LOCATION 1ULL
26#define EFI_TABLE_REVISION 0x00010000
27#define EFI_PARTITION_ENTRIES_BLOCK 2ULL
28#define EFI_PARTITION_ENTRY_COUNT 128
29#define EFI_PARTITION_ENTRY_SIZE 128
30#define EFI_PARTITION_NAME_LENGTH 36
33#define EFI_PART_TYPE_UNUSED_GUID \
34 {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
36#define EFI_PART_TYPE_EFI_SYSTEM_PART_GUID \
37 {0xc12a7328, 0xf81f, 0x11d2, {0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b}}
164 ERR(
"Failed to allocate aligned disk read buffer (align %lu)\n", RequiredAlignment);
173 ERR(
"Aligned disk read buffer is not properly aligned (align %lu)\n", RequiredAlignment);
185 TRACE(
"GetHarddiskIdentifier: DriveNumber: %d\n", DriveNumber);
241 ERR(
"Failed to align disk read buffer for drive %d\n", DriveNumber);
265 TRACE(
"GPT header has unsupported revision: 0x%x\n", GptHeader->Revision);
286 ULONG EntriesPerBlock;
339 RtlZeroMemory(PartitionTableEntry,
sizeof(*PartitionTableEntry));
348 ULONGLONG StartSector = (StartLba * BlockSize) / 512;
351 PartitionTableEntry->SectorCountBeforePartition = (
ULONG)StartSector;
352 PartitionTableEntry->PartitionSectorCount = (
ULONG)SectorCount512;
385 (
VOID**)&BootBlockIo);
389 ERR(
"Failed to get Block I/O protocol for boot handle\n");
397 TRACE(
"Boot partition: Size=%llu blocks, BlockSize=%lu\n",
403 TRACE(
"Boot handle is root device, using partition 0\n");
405 if (PartitionTableEntry !=
NULL)
407 RtlZeroMemory(PartitionTableEntry,
sizeof(*PartitionTableEntry));
427 ULONG EntriesPerBlock;
433 ERR(
"Failed to read GPT header\n");
440 (
VOID**)&RootBlockIo);
475 TRACE(
"GPT Partition %lu: StartLba=%llu, EndLba=%llu, SizeBlocks=%llu\n",
479 if (PartitionSizeBlocks == BootPartitionSize ||
480 (PartitionSizeBlocks > 0 &&
481 (PartitionSizeBlocks - 1 <= BootPartitionSize &&
482 BootPartitionSize <= PartitionSizeBlocks + 1)))
484 TRACE(
"Found matching GPT partition %lu: Size matches (%llu blocks)\n",
485 i + 1, BootPartitionSize);
487 *BootPartition =
i + 1;
490 if (PartitionTableEntry !=
NULL)
492 RtlZeroMemory(PartitionTableEntry,
sizeof(*PartitionTableEntry));
495 PartitionTableEntry->SectorCountBeforePartition = (
ULONG)StartSector;
516 ULONGLONG PartitionSizeBytes = PartitionSizeSectors * 512ULL;
517 PartitionSizeBlocks = PartitionSizeBytes / BootBlockIo->
Media->
BlockSize;
519 TRACE(
"Partition %lu: SizeSectors=%llu, SizeBlocks=%llu\n",
520 PartitionNum, PartitionSizeSectors, PartitionSizeBlocks);
523 if (PartitionSizeBlocks == BootPartitionSize ||
524 (PartitionSizeBlocks > 0 &&
525 (PartitionSizeBlocks - 1 <= BootPartitionSize &&
526 BootPartitionSize <= PartitionSizeBlocks + 1)))
528 TRACE(
"Found matching partition %lu: Size matches (%llu blocks)\n",
529 PartitionNum, BootPartitionSize);
531 *BootPartition = PartitionNum;
532 if (PartitionTableEntry !=
NULL)
534 RtlCopyMemory(PartitionTableEntry, &TempPartitionEntry,
sizeof(*PartitionTableEntry));
546 TRACE(
"Boot device is CD-ROM, using partition 0xFF\n");
547 *BootPartition = 0xFF;
548 if (PartitionTableEntry !=
NULL)
550 RtlZeroMemory(PartitionTableEntry,
sizeof(*PartitionTableEntry));
556 ERR(
"Could not determine boot partition, using partition 1 as fallback\n");
560 *BootPartition = PartitionNum;
561 if (PartitionTableEntry !=
NULL)
563 RtlCopyMemory(PartitionTableEntry, &TempPartitionEntry,
sizeof(*PartitionTableEntry));
616 TRACE(
"UefiDiskOpen: File ID: %p, Path: %s\n", FileId,
Path);
620 ERR(
"DiskOpen(): DiskReadBufferSize is 0, something is wrong.\n");
628 TRACE(
"Opening disk: DriveNumber: %d, DrivePartition: %d\n", DriveNumber, DrivePartition);
645 ERR(
"Failed to get Block I/O protocol for drive %d\n", DriveNumber);
652 ERR(
"Media not present for drive %d\n", DriveNumber);
658 if (DrivePartition != 0xff && DrivePartition != 0)
674 ERR(
"SectorSize (%lu) != Geometry.BytesPerSector (%lu), expect problems!\n",
686 Context->DriveNumber = DriveNumber;
701 ULONG Length, TotalSectors, MaxSectors, ReadSectors;
721 ERR(
"MaxSectors is 0, cannot read\n");
729 ERR(
"Invalid drive number %d\n",
Context->DriveNumber);
742 ERR(
"Failed to get Block I/O protocol\n");
749 ERR(
"Failed to align disk read buffer\n");
758 ReadSectors =
min(TotalSectors, MaxSectors);
764 ReadSectors *
Context->SectorSize,
782 TotalSectors -= ReadSectors;
849 if (ArcDriveIndex >= 32)
860 ERR(
"Reading MBR failed\n");
874 for (
i = 0;
i < 512 /
sizeof(
ULONG);
i++)
878 Checksum = ~Checksum + 1;
879 TRACE(
"Checksum: %x\n", Checksum);
884 sprintf(ArcName,
"multi(0)disk(0)rdisk(%u)", ArcDriveIndex);
887 sprintf(ArcName,
"multi(0)disk(0)rdisk(%u)partition(0)", ArcDriveIndex);
897 sprintf(ArcName,
"multi(0)disk(0)rdisk(%u)partition(%lu)", ArcDriveIndex,
i);
928 Identifier[18] = (ValidPartitionTable ?
'A' :
'X');
937 ULONG BlockDeviceIndex;
938 ULONG SystemHandleCount;
941 UINTN HandleSize = 0;
957 ERR(
"Failed to get handle buffer size: Status = 0x%lx\n", (
ULONG)
Status);
961 SystemHandleCount = HandleSize /
sizeof(
EFI_HANDLE);
962 if (SystemHandleCount == 0)
964 ERR(
"No block devices found\n");
972 ERR(
"Failed to allocate memory for handles\n");
986 ERR(
"Failed to locate block device handles: Status = 0x%lx\n", (
ULONG)
Status);
999 ERR(
"Failed to allocate memory for internal disk structure\n");
1007 for (
i = 0;
i < SystemHandleCount;
i++)
1012 TRACE(
"Found boot handle at index %lu\n",
i);
1022 TRACE(
"Boot handle: LogicalPartition=%s, RemovableMedia=%s, BlockSize=%lu\n",
1023 BlockIo->Media->LogicalPartition ?
"TRUE" :
"FALSE",
1024 BlockIo->Media->RemovableMedia ?
"TRUE" :
"FALSE",
1025 BlockIo->Media->BlockSize);
1032 BlockDeviceIndex = 0;
1033 for (
i = 0;
i < SystemHandleCount;
i++)
1042 TRACE(
"HandleProtocol failed for handle %lu: Status = 0x%lx\n",
i, (
ULONG)
Status);
1046 if (BlockIo ==
NULL)
1048 TRACE(
"BlockIo is NULL for handle %lu\n",
i);
1052 if (!BlockIo->Media->MediaPresent)
1054 TRACE(
"Media not present for handle %lu\n",
i);
1058 if (BlockIo->Media->BlockSize == 0)
1060 TRACE(
"Invalid block size (0) for handle %lu\n",
i);
1067 TRACE(
"Block size too large (%lu) for handle %lu, skipping\n",
1068 BlockIo->Media->BlockSize,
i);
1073 if (BlockIo->Media->LogicalPartition)
1077 TRACE(
"Skipping logical partition handle %lu\n",
i);
1082 TRACE(
"Found root block device at index %lu: BlockSize=%lu, LastBlock=%llu\n",
1083 i, BlockIo->Media->BlockSize, BlockIo->Media->LastBlock);
1097 TRACE(
"Boot device is at ARC drive index %lu (root device)\n", BlockDeviceIndex);
1104 TRACE(
"Calling GetHarddiskInformation for drive %d (BlockDeviceIndex=%lu)\n",
1108 ERR(
"Failed to align disk read buffer for drive %d\n", BlockDeviceIndex +
FIRST_BIOS_DISK);
1126 TRACE(
"Boot handle is a logical partition, searching for parent root device\n");
1127 TRACE(
"Boot partition: BlockSize=%lu, RemovableMedia=%s\n",
1128 BlockIo->Media->BlockSize,
1129 BlockIo->Media->RemovableMedia ?
"TRUE" :
"FALSE");
1135 for (
i = 0;
i < BlockDeviceIndex;
i++)
1141 (
VOID**)&RootBlockIo);
1147 if (BlockIo->Media->BlockSize == 2048 && BlockIo->Media->RemovableMedia)
1155 FoundBootDevice =
TRUE;
1156 TRACE(
"Found CD-ROM boot device at ARC drive index %lu\n",
i);
1164 if (RootBlockIo->
Media->
BlockSize == BlockIo->Media->BlockSize &&
1171 FoundBootDevice =
TRUE;
1172 TRACE(
"Found potential hard disk boot device at ARC drive index %lu\n",
i);
1181 TRACE(
"Could not determine boot device, assuming first drive\n");
1196 ULONG ArcDriveIndex;
1198 TRACE(
"UefiSetBootpath: Setting up boot path\n");
1202 ERR(
"Invalid boot root index\n");
1209 ERR(
"Invalid boot arc disk index\n");
1216 (
VOID**)&BootBlockIo);
1220 ERR(
"Failed to get Block I/O protocol for boot handle\n");
1227 (
VOID**)&RootBlockIo);
1231 ERR(
"Failed to get Block I/O protocol for boot root device\n");
1244 "multi(0)disk(0)cdrom(%u)", ArcDriveIndex);
1249 ULONG BootPartition;
1260 TRACE(
"Boot handle is logical partition, using partition %lu\n", BootPartition);
1267 ERR(
"Failed to get boot partition entry\n");
1273 "multi(0)disk(0)rdisk(%u)partition(%lu)",
1274 ArcDriveIndex, BootPartition);
1286 ULONG ArcDriveIndex;
1300 ERR(
"Failed to allocate disk read buffer\n");
1308 ERR(
"No block devices found\n");
1314 ERR(
"Failed to set boot path\n");
1322 ERR(
"Invalid boot arc disk index\n");
1333 ERR(
"Failed to get Block I/O protocol\n");
1342 ERR(
"Reading MBR from CD-ROM failed\n");
1353 for (
i = 0;
i < 2048 /
sizeof(
ULONG);
i++)
1357 Checksum = ~Checksum + 1;
1358 TRACE(
"CD-ROM Checksum: %x\n", Checksum);
1384 ULONG ArcDriveIndex;
1397 ERR(
"InternalUefiDisk not initialized\n");
1401 if (ArcDriveIndex >= 32)
1403 ERR(
"Drive index out of bounds: %d (ArcDriveIndex=%lu)\n", DriveNumber, ArcDriveIndex);
1411 ERR(
"Invalid drive number: %d (ArcDriveIndex=%lu, PcBiosDiskCount=%lu, Handle=NULL)\n",
1423 ERR(
"Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1429 ERR(
"Media not present for drive %d\n", DriveNumber);
1438 ERR(
"Failed to align disk read buffer for drive %d\n", DriveNumber);
1449 if (MaxSectors == 0)
1451 ERR(
"DiskReadBufferSize too small for block size %lu\n", BlockSize);
1455 while (TotalSectors)
1457 ULONG ReadSectors =
min(TotalSectors, MaxSectors);
1458 UINTN ReadSize = ReadSectors * BlockSize;
1469 ERR(
"ReadBlocks failed: DriveNumber=%d, SectorNumber=%llu, SectorCount=%lu, Status=0x%lx\n",
1470 DriveNumber, CurrentSector, ReadSectors, (
ULONG)
Status);
1471 ERR(
"ReadBlocks details: BlockSize=%lu, IoAlign=%lu, Buffer=%p, DiskReadBuffer=%p, MediaId=0x%lx\n",
1473 ERR(
"ReadBlocks media: LastBlock=%llu, LogicalPartition=%s, RemovableMedia=%s\n",
1482 CurrentSector += ReadSectors;
1483 TotalSectors -= ReadSectors;
1498 ERR(
"ReadBlocks failed: DriveNumber=%d, SectorNumber=%llu, SectorCount=%lu, Status=0x%lx\n",
1500 ERR(
"ReadBlocks details: BlockSize=%lu, IoAlign=%lu, Buffer=%p, DiskReadBuffer=%p, MediaId=0x%lx\n",
1502 ERR(
"ReadBlocks media: LastBlock=%llu, LogicalPartition=%s, RemovableMedia=%s\n",
1515 ULONG ArcDriveIndex;
1526 ERR(
"InternalUefiDisk not initialized\n");
1532 ERR(
"Invalid drive number: %d\n", DriveNumber);
1543 ERR(
"Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1549 ERR(
"Media not present for drive %d\n", DriveNumber);
1554 Geometry->
Heads = 1;
1565 ULONG ArcDriveIndex;
1576 ERR(
"InternalUefiDisk not initialized\n");
1582 ERR(
"Invalid drive number: %d\n", DriveNumber);
1593 ERR(
"Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1599 ERR(
"Media not present for drive %d\n", DriveNumber);
#define BLOCK_IO_PROTOCOL
unsigned long long UINT64
PRTL_UNICODE_STRING_BUFFER Path
VOID AddReactOSArcDiskInfo(IN PSTR ArcName, IN ULONG Signature, IN ULONG Checksum, IN BOOLEAN ValidPartitionTable)
BOOLEAN DissectArcPath(IN PCSTR ArcPath, OUT PCSTR *Path OPTIONAL, OUT PUCHAR DriveNumber, OUT PULONG PartitionNumber)
BOOLEAN DiskGetPartitionEntry(IN UCHAR DriveNumber, IN ULONG PartitionNumber, OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
VOID DiskDetectPartitionType(IN UCHAR DriveNumber)
#define DBG_DEFAULT_CHANNEL(ch)
#define PARTITION_ENTRY_UNUSED
struct _MASTER_BOOT_RECORD * PMASTER_BOOT_RECORD
PVOID FsGetDeviceSpecific(ULONG FileId)
VOID FsSetDeviceSpecific(ULONG FileId, PVOID Specific)
VOID FsRegisterDevice(_In_ PCSTR DeviceName, _In_ const DEVVTBL *FuncTable)
#define MachDiskGetDriveGeometry(Drive, Geom)
#define MachDiskReadLogicalSectors(Drive, Start, Count, Buf)
VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
static const WCHAR Signature[]
CCHAR FrLdrBootPath[MAX_PATH]
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
_In_ ULONG _In_ ULONG _In_ ULONG Length
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
@ LoaderFirmwareTemporary
EFI_LOCATE_HANDLE LocateHandle
EFI_HANDLE_PROTOCOL HandleProtocol
EFI_ALLOCATE_POOL AllocatePool
EFI_BOOT_SERVICES * BootServices
ULONG PartitionSectorCount
ULONG SectorCountBeforePartition
EFI_BLOCK_IO_MEDIA * Media
EFI_BLOCK_READ ReadBlocks
ULONG BytesPerSector
Number of bytes per sector.
ULONG Cylinders
Number of cylinders on the disk.
ULONGLONG Sectors
Total number of disk sectors/LBA blocks.
ULONG SectorsPerTrack
Number of sectors per track.
ULONG Heads
Number of heads on the disk.
EFI_GUID PartitionTypeGuid
EFI_GUID UniquePartitionGuid
CHAR16 PartitionName[EFI_PARTITION_NAME_LENGTH]
BOOLEAN IsThisTheBootDrive
USHORT MasterBootRecordMagic
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
#define EFI_PARTITION_HEADER_SIGNATURE
#define EFI_PARTITION_NAME_LENGTH
static ULONG PublicBootArcDisk
BOOLEAN UefiDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
static BOOLEAN UefiReadGptHeader(IN UCHAR DriveNumber, OUT PGPT_TABLE_HEADER GptHeader)
#define TAG_HW_DISK_CONTEXT
static BOOLEAN UefiGetBootPartitionEntry(IN UCHAR DriveNumber, OUT PPARTITION_TABLE_ENTRY PartitionTableEntry, OUT PULONG BootPartition)
BOOLEAN UefiDiskReadLogicalSectors(IN UCHAR DriveNumber, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
struct tagDISKCONTEXT DISKCONTEXT
static BOOLEAN DiskReadBufferFromPool
struct _GPT_PARTITION_ENTRY GPT_PARTITION_ENTRY
static CHAR PcDiskIdentifier[32][20]
static EFI_GUID BlockIoGuid
BOOLEAN UefiInitializeBootDevices(VOID)
static ARC_STATUS UefiDiskGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
#define EFI_TABLE_REVISION
#define EFI_PART_TYPE_UNUSED_GUID
EFI_HANDLE PublicBootHandle
static ULONG DiskReadBufferAlignment
EFI_SYSTEM_TABLE * GlobalSystemTable
LONG DiskReportError(BOOLEAN bShowError)
static const DEVVTBL UefiDiskVtbl
static BOOLEAN UefiEnsureDiskReadBufferAligned(IN ULONG Alignment)
static VOID UefiSetupBlockDevices(VOID)
struct _GPT_TABLE_HEADER GPT_TABLE_HEADER
#define EFI_HEADER_LOCATION
BOOLEAN UefiGetGptPartitionEntry(IN UCHAR DriveNumber, IN ULONG PartitionNumber, OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
struct _GPT_TABLE_HEADER * PGPT_TABLE_HEADER
static ULONG UefiBootRootIndex
static PVOID DiskReadBufferRaw
#define MAX_SUPPORTED_BLOCK_SIZE
static ARC_STATUS UefiDiskOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
static ARC_STATUS UefiDiskSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
static INTERNAL_UEFI_DISK * InternalUefiDisk
static ARC_STATUS UefiDiskClose(ULONG FileId)
static VOID GetHarddiskInformation(UCHAR DriveNumber)
PCHAR GetHarddiskIdentifier(UCHAR DriveNumber)
static ARC_STATUS UefiDiskRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
EFI_HANDLE GlobalImageHandle
struct _INTERNAL_UEFI_DISK INTERNAL_UEFI_DISK
static EFI_HANDLE * handles
UCHAR UefiGetFloppyCount(VOID)
SIZE_T DiskReadBufferSize
struct _GPT_PARTITION_ENTRY * PGPT_PARTITION_ENTRY
static BOOLEAN UefiIsAlignedPointer(IN PVOID Pointer, IN ULONG Alignment)
ULONG UefiDiskGetCacheableBlockCount(UCHAR DriveNumber)
static BOOLEAN UefiSetBootpath(VOID)
struct _INTERNAL_UEFI_DISK * PINTERNAL_UEFI_DISK
#define ALIGN_UP_POINTER_BY(ptr, align)
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
_In_ ULONG _In_ ULONG PartitionNumber