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
134 WARN(
"Failed to allocate aligned disk read buffer using AllocatePool, trying MmAllocateMemoryWithType (buffer size = 0x%X, alignment %lu)\n",
141 ERR(
"Failed to allocate aligned disk read buffer (buffer size = 0x%X, alignment %lu)\n",
154 ERR(
"Aligned disk read buffer is not properly aligned (align %lu)\n", RequiredAlignment);
197 (
VOID**)&BootBlockIo);
201 ERR(
"Failed to get Block I/O protocol for boot handle\n");
209 TRACE(
"Boot partition: Size=%llu blocks, BlockSize=%lu\n",
215 TRACE(
"Boot handle is root device, using partition 0\n");
221 PartitionEntry->StartingOffset.QuadPart = 0
ULL;
222 PartitionEntry->PartitionLength.QuadPart = (BootPartitionSize * BootBlockIo->
Media->
BlockSize);
223 PartitionEntry->HiddenSectors = 0;
224 PartitionEntry->PartitionNumber = *BootPartition;
226 PartitionEntry->BootIndicator =
TRUE;
227 PartitionEntry->RecognizedPartition =
TRUE;
228 PartitionEntry->RewritePartition =
FALSE;
242 ULONG EntriesPerBlock;
250 (
VOID**)&RootBlockIo);
285 TRACE(
"GPT Partition %lu: StartLba=%llu, EndLba=%llu, SizeBlocks=%llu\n",
289 if (PartitionSizeBlocks == BootPartitionSize ||
290 (PartitionSizeBlocks > 0 &&
291 (PartitionSizeBlocks - 1 <= BootPartitionSize &&
292 BootPartitionSize <= PartitionSizeBlocks + 1)))
294 TRACE(
"Found matching GPT partition %lu: Size matches (%llu blocks)\n",
295 i + 1, BootPartitionSize);
297 *BootPartition =
i + 1;
302 PartitionEntry->StartingOffset.QuadPart = (GptEntry.
StartingLba * BlockSize);
303 PartitionEntry->PartitionLength.QuadPart = ((
ULONGLONG)PartitionSizeBlocks * BlockSize);
304 PartitionEntry->HiddenSectors = 0;
305 PartitionEntry->PartitionNumber = *BootPartition;
308 PartitionEntry->RecognizedPartition =
TRUE;
309 PartitionEntry->RewritePartition =
FALSE;
327 ULONGLONG EndingLba = StartingLba + PartitionSizeBlocks - 1;
329 TRACE(
"Partition %lu: StartLba=%llu, EndLba=%llu, SizeBlocks=%llu\n",
330 PartitionNum, StartingLba, EndingLba, PartitionSizeBlocks);
333 if (PartitionSizeBlocks == BootPartitionSize ||
334 (PartitionSizeBlocks > 0 &&
335 (PartitionSizeBlocks - 1 <= BootPartitionSize &&
336 BootPartitionSize <= PartitionSizeBlocks + 1)))
338 TRACE(
"Found matching partition %lu: Size matches (%llu blocks)\n",
339 PartitionNum, BootPartitionSize);
341 *BootPartition = PartitionNum;
343 RtlCopyMemory(PartitionEntry, &TempPartitionEntry,
sizeof(*PartitionEntry));
354 TRACE(
"Boot device is CD-ROM, using partition 0xFF\n");
355 *BootPartition = 0xFF;
360 PartitionEntry->StartingOffset.QuadPart = 0
ULL;
361 PartitionEntry->PartitionLength.QuadPart = (BootPartitionSize * BootBlockIo->
Media->
BlockSize);
362 PartitionEntry->HiddenSectors = 0;
363 PartitionEntry->PartitionNumber = *BootPartition;
365 PartitionEntry->BootIndicator =
TRUE;
366 PartitionEntry->RecognizedPartition =
TRUE;
367 PartitionEntry->RewritePartition =
FALSE;
373 ERR(
"Could not determine boot partition, using partition 1 as fallback\n");
376 PartitionNum, &TempPartitionEntry))
378 *BootPartition = PartitionNum;
380 RtlCopyMemory(PartitionEntry, &TempPartitionEntry,
sizeof(*PartitionEntry));
431 TRACE(
"UefiDiskOpen: File ID: %p, Path: %s\n", FileId,
Path);
435 ERR(
"DiskOpen(): DiskReadBufferSize is 0, something is wrong.\n");
443 TRACE(
"Opening disk: DriveNumber: %d, DrivePartition: %d\n", DriveNumber, DrivePartition);
460 ERR(
"Failed to get Block I/O protocol for drive %d\n", DriveNumber);
467 ERR(
"Media not present for drive %d\n", DriveNumber);
478 if (DrivePartition != 0xff && DrivePartition != 0)
497 Context->DriveNumber = DriveNumber;
513 ULONG Length, TotalSectors, MaxSectors, ReadSectors;
532 ERR(
"MaxSectors is 0, cannot read\n");
540 ERR(
"Invalid drive number %d\n",
Context->DriveNumber);
553 ERR(
"Failed to get Block I/O protocol\n");
560 ERR(
"Failed to align disk read buffer\n");
569 ReadSectors =
min(TotalSectors, MaxSectors);
575 ReadSectors *
Context->SectorSize,
593 TotalSectors -= ReadSectors;
648 static const CHAR Hex[] =
"0123456789abcdef";
660 if (ArcDriveIndex >= 32)
666 "multi(0)disk(0)rdisk(%u)",
671 &Checksum, &
Signature, &ValidPartitionTable);
700 Identifier[18] = (ValidPartitionTable ?
'A' :
'X');
709 ULONG BlockDeviceIndex;
710 ULONG SystemHandleCount;
713 UINTN HandleSize = 0;
729 ERR(
"Failed to get handle buffer size: Status = 0x%lx\n", (
ULONG)
Status);
733 SystemHandleCount = HandleSize /
sizeof(
EFI_HANDLE);
734 if (SystemHandleCount == 0)
736 ERR(
"No block devices found\n");
744 ERR(
"Failed to allocate memory for handles\n");
758 ERR(
"Failed to locate block device handles: Status = 0x%lx\n", (
ULONG)
Status);
771 ERR(
"Failed to allocate memory for internal disk structure\n");
779 for (
i = 0;
i < SystemHandleCount;
i++)
784 TRACE(
"Found boot handle at index %lu\n",
i);
794 TRACE(
"Boot handle: LogicalPartition=%s, RemovableMedia=%s, BlockSize=%lu\n",
795 BlockIo->Media->LogicalPartition ?
"TRUE" :
"FALSE",
796 BlockIo->Media->RemovableMedia ?
"TRUE" :
"FALSE",
797 BlockIo->Media->BlockSize);
804 BlockDeviceIndex = 0;
805 for (
i = 0;
i < SystemHandleCount;
i++)
814 TRACE(
"HandleProtocol failed for handle %lu: Status = 0x%lx\n",
i, (
ULONG)
Status);
820 TRACE(
"BlockIo is NULL for handle %lu\n",
i);
824 if (!BlockIo->Media->MediaPresent)
826 TRACE(
"Media not present for handle %lu\n",
i);
830 if (BlockIo->Media->BlockSize == 0)
832 TRACE(
"Invalid block size (0) for handle %lu\n",
i);
839 TRACE(
"Block size too large (%lu) for handle %lu, skipping\n",
840 BlockIo->Media->BlockSize,
i);
845 if (BlockIo->Media->LogicalPartition)
849 TRACE(
"Skipping logical partition handle %lu\n",
i);
854 TRACE(
"Found root block device at index %lu: BlockSize=%lu, LastBlock=%llu\n",
855 i, BlockIo->Media->BlockSize, BlockIo->Media->LastBlock);
869 TRACE(
"Boot device is at ARC drive index %lu (root device)\n", BlockDeviceIndex);
876 TRACE(
"Calling GetHarddiskInformation for drive %d (BlockDeviceIndex=%lu)\n",
880 ERR(
"Failed to align disk read buffer for drive %d\n", BlockDeviceIndex +
FIRST_BIOS_DISK);
898 TRACE(
"Boot handle is a logical partition, searching for parent root device\n");
899 TRACE(
"Boot partition: BlockSize=%lu, RemovableMedia=%s\n",
900 BlockIo->Media->BlockSize,
901 BlockIo->Media->RemovableMedia ?
"TRUE" :
"FALSE");
907 for (
i = 0;
i < BlockDeviceIndex;
i++)
913 (
VOID**)&RootBlockIo);
919 if (BlockIo->Media->BlockSize == 2048 && BlockIo->Media->RemovableMedia)
927 FoundBootDevice =
TRUE;
928 TRACE(
"Found CD-ROM boot device at ARC drive index %lu\n",
i);
943 FoundBootDevice =
TRUE;
944 TRACE(
"Found potential hard disk boot device at ARC drive index %lu\n",
i);
953 TRACE(
"Could not determine boot device, assuming first drive\n");
969 TRACE(
"UefiSetBootpath: Setting up boot path\n");
973 ERR(
"Invalid boot root index\n");
980 ERR(
"Invalid boot arc disk index\n");
987 (
VOID**)&BootBlockIo);
991 ERR(
"Failed to get Block I/O protocol for boot handle\n");
1004 "multi(0)disk(0)cdrom(%u)", ArcDriveIndex);
1009 ULONG BootPartition;
1019 TRACE(
"Boot handle is logical partition, using partition %lu\n", BootPartition);
1026 ERR(
"Failed to get boot partition entry\n");
1032 "multi(0)disk(0)rdisk(%u)partition(%lu)",
1033 ArcDriveIndex, BootPartition);
1045 ULONG ArcDriveIndex;
1054 ERR(
"Failed to allocate disk read buffer\n");
1062 ERR(
"No block devices found\n");
1068 ERR(
"Failed to set boot path\n");
1076 ERR(
"Invalid boot arc disk index\n");
1087 ERR(
"Failed to get Block I/O protocol\n");
1123 ULONG ArcDriveIndex;
1136 ERR(
"InternalUefiDisk not initialized\n");
1140 if (ArcDriveIndex >= 32)
1142 ERR(
"Drive index out of bounds: %d (ArcDriveIndex=%lu)\n", DriveNumber, ArcDriveIndex);
1150 ERR(
"Invalid drive number: %d (ArcDriveIndex=%lu, PcBiosDiskCount=%lu, Handle=NULL)\n",
1162 ERR(
"Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1168 ERR(
"Media not present for drive %d\n", DriveNumber);
1177 ERR(
"Failed to align disk read buffer for drive %d\n", DriveNumber);
1188 if (MaxSectors == 0)
1190 ERR(
"DiskReadBufferSize too small for block size %lu\n", BlockSize);
1194 while (TotalSectors)
1196 ULONG ReadSectors =
min(TotalSectors, MaxSectors);
1197 UINTN ReadSize = ReadSectors * BlockSize;
1208 ERR(
"ReadBlocks failed: DriveNumber=%d, SectorNumber=%llu, SectorCount=%lu, Status=0x%lx\n",
1209 DriveNumber, CurrentSector, ReadSectors, (
ULONG)
Status);
1210 ERR(
"ReadBlocks details: BlockSize=%lu, IoAlign=%lu, Buffer=%p, DiskReadBuffer=%p, MediaId=0x%lx\n",
1212 ERR(
"ReadBlocks media: LastBlock=%llu, LogicalPartition=%s, RemovableMedia=%s\n",
1221 CurrentSector += ReadSectors;
1222 TotalSectors -= ReadSectors;
1237 ERR(
"ReadBlocks failed: DriveNumber=%d, SectorNumber=%llu, SectorCount=%lu, Status=0x%lx\n",
1239 ERR(
"ReadBlocks details: BlockSize=%lu, IoAlign=%lu, Buffer=%p, DiskReadBuffer=%p, MediaId=0x%lx\n",
1241 ERR(
"ReadBlocks media: LastBlock=%llu, LogicalPartition=%s, RemovableMedia=%s\n",
1254 ULONG ArcDriveIndex;
1265 ERR(
"InternalUefiDisk not initialized\n");
1271 ERR(
"Invalid drive number: %d\n", DriveNumber);
1282 ERR(
"Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1288 ERR(
"Media not present for drive %d\n", DriveNumber);
1293 Geometry->
Heads = 1;
1304 ULONG ArcDriveIndex;
1315 ERR(
"InternalUefiDisk not initialized\n");
1321 ERR(
"Invalid drive number: %d\n", DriveNumber);
1332 ERR(
"Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1338 ERR(
"Media not present for drive %d\n", DriveNumber);
#define BLOCK_IO_PROTOCOL
PRTL_UNICODE_STRING_BUFFER Path
BOOLEAN DissectArcPath(IN PCSTR ArcPath, OUT PCSTR *Path OPTIONAL, OUT PUCHAR DriveNumber, OUT PULONG PartitionNumber)
ARC_STATUS DiskInitialize(_In_ UCHAR DriveNumber, _In_ PCSTR DeviceName, _In_ CONFIGURATION_TYPE DeviceType, _In_ const DEVVTBL *FuncTable, _Out_opt_ PULONG pChecksum, _Out_opt_ PULONG pSignature, _Out_opt_ PBOOLEAN pValidPartitionTable)
LONG DiskReportError(_In_ BOOLEAN bShowError)
BOOLEAN DiskGetPartitionEntry(_In_ UCHAR DriveNumber, _In_opt_ ULONG SectorSize, _In_ ULONG PartitionNumber, _Out_ PPARTITION_INFORMATION PartitionEntry)
#define DBG_DEFAULT_CHANNEL(ch)
PVOID FsGetDeviceSpecific(ULONG FileId)
VOID FsSetDeviceSpecific(ULONG FileId, PVOID Specific)
#define MachDiskGetDriveGeometry(Drive, Geom)
VOID MmFreeMemory(PVOID MemoryPointer)
VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
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
#define RtlEqualMemory(dst, src, len)
_In_ NDIS_ERROR_CODE ErrorCode
_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,...)
#define EFI_PART_TYPE_EFI_SYSTEM_PART_GUID
#define EFI_PART_TYPE_UNUSED_GUID
@ LoaderFirmwareTemporary
EFI_LOCATE_HANDLE LocateHandle
EFI_HANDLE_PROTOCOL HandleProtocol
EFI_ALLOCATE_POOL AllocatePool
EFI_BOOT_SERVICES * BootServices
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.
BOOLEAN IsThisTheBootDrive
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
static ULONG PublicBootArcDisk
PCSTR DiskGetErrorCodeString(_In_ ULONG ErrorCode)
BOOLEAN UefiDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
#define TAG_HW_DISK_CONTEXT
BOOLEAN DiskReadGptHeader(_In_ UCHAR DriveNumber, _Out_ PGPT_TABLE_HEADER GptHeader)
BOOLEAN UefiDiskReadLogicalSectors(IN UCHAR DriveNumber, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
struct tagDISKCONTEXT DISKCONTEXT
static BOOLEAN DiskReadBufferFromPool
static EFI_GUID BlockIoGuid
BOOLEAN UefiInitializeBootDevices(VOID)
static ARC_STATUS UefiDiskGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
static BOOLEAN DiskReadBufferFallbackPool
EFI_HANDLE PublicBootHandle
static ULONG DiskReadBufferAlignment
EFI_SYSTEM_TABLE * GlobalSystemTable
static BOOLEAN UefiGetBootPartitionEntry(_In_ UCHAR DriveNumber, _Out_opt_ PPARTITION_INFORMATION PartitionEntry, _Out_ PULONG BootPartition)
static const DEVVTBL UefiDiskVtbl
static BOOLEAN UefiEnsureDiskReadBufferAligned(IN ULONG Alignment)
static VOID UefiSetupBlockDevices(VOID)
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 VOID GetHarddiskInformation(_In_ UCHAR DriveNumber)
static INTERNAL_UEFI_DISK * InternalUefiDisk
static ARC_STATUS UefiDiskClose(ULONG FileId)
static ARC_STATUS UefiDiskRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
EFI_HANDLE GlobalImageHandle
struct _INTERNAL_UEFI_DISK INTERNAL_UEFI_DISK
static UCHAR PcBiosDiskCount
static EFI_HANDLE * handles
UCHAR UefiGetFloppyCount(VOID)
SIZE_T DiskReadBufferSize
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