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
133 WARN(
"Failed to allocate aligned disk read buffer using AllocatePool, trying MmAllocateMemoryWithType (buffer size = 0x%X, alignment %lu)\n",
140 ERR(
"Failed to allocate aligned disk read buffer (buffer size = 0x%X, alignment %lu)\n",
153 ERR(
"Aligned disk read buffer is not properly aligned (align %lu)\n", RequiredAlignment);
196 (
VOID**)&BootBlockIo);
200 ERR(
"Failed to get Block I/O protocol for boot handle\n");
208 TRACE(
"Boot partition: Size=%llu blocks, BlockSize=%lu\n",
214 TRACE(
"Boot handle is root device, using partition 0\n");
220 PartitionEntry->StartingOffset.QuadPart = 0
ULL;
221 PartitionEntry->PartitionLength.QuadPart = (BootPartitionSize * BootBlockIo->
Media->
BlockSize);
222 PartitionEntry->HiddenSectors = 0;
223 PartitionEntry->PartitionNumber = *BootPartition;
225 PartitionEntry->BootIndicator =
TRUE;
226 PartitionEntry->RecognizedPartition =
TRUE;
227 PartitionEntry->RewritePartition =
FALSE;
241 ULONG EntriesPerBlock;
249 (
VOID**)&RootBlockIo);
284 TRACE(
"GPT Partition %lu: StartLba=%llu, EndLba=%llu, SizeBlocks=%llu\n",
288 if (PartitionSizeBlocks == BootPartitionSize ||
289 (PartitionSizeBlocks > 0 &&
290 (PartitionSizeBlocks - 1 <= BootPartitionSize &&
291 BootPartitionSize <= PartitionSizeBlocks + 1)))
293 TRACE(
"Found matching GPT partition %lu: Size matches (%llu blocks)\n",
294 i + 1, BootPartitionSize);
296 *BootPartition =
i + 1;
301 PartitionEntry->StartingOffset.QuadPart = (GptEntry.
StartingLba * BlockSize);
302 PartitionEntry->PartitionLength.QuadPart = ((
ULONGLONG)PartitionSizeBlocks * BlockSize);
303 PartitionEntry->HiddenSectors = 0;
304 PartitionEntry->PartitionNumber = *BootPartition;
307 PartitionEntry->RecognizedPartition =
TRUE;
308 PartitionEntry->RewritePartition =
FALSE;
326 ULONGLONG EndingLba = StartingLba + PartitionSizeBlocks - 1;
328 TRACE(
"Partition %lu: StartLba=%llu, EndLba=%llu, SizeBlocks=%llu\n",
329 PartitionNum, StartingLba, EndingLba, PartitionSizeBlocks);
332 if (PartitionSizeBlocks == BootPartitionSize ||
333 (PartitionSizeBlocks > 0 &&
334 (PartitionSizeBlocks - 1 <= BootPartitionSize &&
335 BootPartitionSize <= PartitionSizeBlocks + 1)))
337 TRACE(
"Found matching partition %lu: Size matches (%llu blocks)\n",
338 PartitionNum, BootPartitionSize);
340 *BootPartition = PartitionNum;
342 RtlCopyMemory(PartitionEntry, &TempPartitionEntry,
sizeof(*PartitionEntry));
353 TRACE(
"Boot device is CD-ROM, using partition 0xFF\n");
354 *BootPartition = 0xFF;
359 PartitionEntry->StartingOffset.QuadPart = 0
ULL;
360 PartitionEntry->PartitionLength.QuadPart = (BootPartitionSize * BootBlockIo->
Media->
BlockSize);
361 PartitionEntry->HiddenSectors = 0;
362 PartitionEntry->PartitionNumber = *BootPartition;
364 PartitionEntry->BootIndicator =
TRUE;
365 PartitionEntry->RecognizedPartition =
TRUE;
366 PartitionEntry->RewritePartition =
FALSE;
372 ERR(
"Could not determine boot partition, using partition 1 as fallback\n");
375 PartitionNum, &TempPartitionEntry))
377 *BootPartition = PartitionNum;
379 RtlCopyMemory(PartitionEntry, &TempPartitionEntry,
sizeof(*PartitionEntry));
430 TRACE(
"UefiDiskOpen: File ID: %p, Path: %s\n", FileId,
Path);
434 ERR(
"DiskOpen(): DiskReadBufferSize is 0, something is wrong.\n");
442 TRACE(
"Opening disk: DriveNumber: %d, DrivePartition: %d\n", DriveNumber, DrivePartition);
459 ERR(
"Failed to get Block I/O protocol for drive %d\n", DriveNumber);
466 ERR(
"Media not present for drive %d\n", DriveNumber);
477 if (DrivePartition != 0xff && DrivePartition != 0)
496 Context->DriveNumber = DriveNumber;
512 ULONG Length, TotalSectors, MaxSectors, ReadSectors;
531 ERR(
"MaxSectors is 0, cannot read\n");
539 ERR(
"Invalid drive number %d\n",
Context->DriveNumber);
552 ERR(
"Failed to get Block I/O protocol\n");
559 ERR(
"Failed to align disk read buffer\n");
568 ReadSectors =
min(TotalSectors, MaxSectors);
574 ReadSectors *
Context->SectorSize,
592 TotalSectors -= ReadSectors;
647 static const CHAR Hex[] =
"0123456789abcdef";
659 if (ArcDriveIndex >= 32)
665 "multi(0)disk(0)rdisk(%u)",
670 &Checksum, &
Signature, &ValidPartitionTable);
699 Identifier[18] = (ValidPartitionTable ?
'A' :
'X');
708 ULONG BlockDeviceIndex;
709 ULONG SystemHandleCount;
712 UINTN HandleSize = 0;
728 ERR(
"Failed to get handle buffer size: Status = 0x%lx\n", (
ULONG)
Status);
732 SystemHandleCount = HandleSize /
sizeof(
EFI_HANDLE);
733 if (SystemHandleCount == 0)
735 ERR(
"No block devices found\n");
743 ERR(
"Failed to allocate memory for handles\n");
757 ERR(
"Failed to locate block device handles: Status = 0x%lx\n", (
ULONG)
Status);
770 ERR(
"Failed to allocate memory for internal disk structure\n");
778 for (
i = 0;
i < SystemHandleCount;
i++)
783 TRACE(
"Found boot handle at index %lu\n",
i);
793 TRACE(
"Boot handle: LogicalPartition=%s, RemovableMedia=%s, BlockSize=%lu\n",
794 BlockIo->Media->LogicalPartition ?
"TRUE" :
"FALSE",
795 BlockIo->Media->RemovableMedia ?
"TRUE" :
"FALSE",
796 BlockIo->Media->BlockSize);
803 BlockDeviceIndex = 0;
804 for (
i = 0;
i < SystemHandleCount;
i++)
813 TRACE(
"HandleProtocol failed for handle %lu: Status = 0x%lx\n",
i, (
ULONG)
Status);
819 TRACE(
"BlockIo is NULL for handle %lu\n",
i);
823 if (!BlockIo->Media->MediaPresent)
825 TRACE(
"Media not present for handle %lu\n",
i);
829 if (BlockIo->Media->BlockSize == 0)
831 TRACE(
"Invalid block size (0) for handle %lu\n",
i);
838 TRACE(
"Block size too large (%lu) for handle %lu, skipping\n",
839 BlockIo->Media->BlockSize,
i);
844 if (BlockIo->Media->LogicalPartition)
848 TRACE(
"Skipping logical partition handle %lu\n",
i);
853 TRACE(
"Found root block device at index %lu: BlockSize=%lu, LastBlock=%llu\n",
854 i, BlockIo->Media->BlockSize, BlockIo->Media->LastBlock);
868 TRACE(
"Boot device is at ARC drive index %lu (root device)\n", BlockDeviceIndex);
875 TRACE(
"Calling GetHarddiskInformation for drive %d (BlockDeviceIndex=%lu)\n",
879 ERR(
"Failed to align disk read buffer for drive %d\n", BlockDeviceIndex +
FIRST_BIOS_DISK);
897 TRACE(
"Boot handle is a logical partition, searching for parent root device\n");
898 TRACE(
"Boot partition: BlockSize=%lu, RemovableMedia=%s\n",
899 BlockIo->Media->BlockSize,
900 BlockIo->Media->RemovableMedia ?
"TRUE" :
"FALSE");
906 for (
i = 0;
i < BlockDeviceIndex;
i++)
912 (
VOID**)&RootBlockIo);
918 if (BlockIo->Media->BlockSize == 2048 && BlockIo->Media->RemovableMedia)
926 FoundBootDevice =
TRUE;
927 TRACE(
"Found CD-ROM boot device at ARC drive index %lu\n",
i);
942 FoundBootDevice =
TRUE;
943 TRACE(
"Found potential hard disk boot device at ARC drive index %lu\n",
i);
952 TRACE(
"Could not determine boot device, assuming first drive\n");
968 TRACE(
"UefiSetBootpath: Setting up boot path\n");
972 ERR(
"Invalid boot root index\n");
979 ERR(
"Invalid boot arc disk index\n");
986 (
VOID**)&BootBlockIo);
990 ERR(
"Failed to get Block I/O protocol for boot handle\n");
1003 "multi(0)disk(0)cdrom(%u)", ArcDriveIndex);
1008 ULONG BootPartition;
1018 TRACE(
"Boot handle is logical partition, using partition %lu\n", BootPartition);
1025 ERR(
"Failed to get boot partition entry\n");
1031 "multi(0)disk(0)rdisk(%u)partition(%lu)",
1032 ArcDriveIndex, BootPartition);
1044 ULONG ArcDriveIndex;
1053 ERR(
"Failed to allocate disk read buffer\n");
1061 ERR(
"No block devices found\n");
1067 ERR(
"Failed to set boot path\n");
1075 ERR(
"Invalid boot arc disk index\n");
1086 ERR(
"Failed to get Block I/O protocol\n");
1122 ULONG ArcDriveIndex;
1135 ERR(
"InternalUefiDisk not initialized\n");
1139 if (ArcDriveIndex >= 32)
1141 ERR(
"Drive index out of bounds: %d (ArcDriveIndex=%lu)\n", DriveNumber, ArcDriveIndex);
1149 ERR(
"Invalid drive number: %d (ArcDriveIndex=%lu, PcBiosDiskCount=%lu, Handle=NULL)\n",
1161 ERR(
"Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1167 ERR(
"Media not present for drive %d\n", DriveNumber);
1176 ERR(
"Failed to align disk read buffer for drive %d\n", DriveNumber);
1187 if (MaxSectors == 0)
1189 ERR(
"DiskReadBufferSize too small for block size %lu\n", BlockSize);
1193 while (TotalSectors)
1195 ULONG ReadSectors =
min(TotalSectors, MaxSectors);
1196 UINTN ReadSize = ReadSectors * BlockSize;
1207 ERR(
"ReadBlocks failed: DriveNumber=%d, SectorNumber=%llu, SectorCount=%lu, Status=0x%lx\n",
1208 DriveNumber, CurrentSector, ReadSectors, (
ULONG)
Status);
1209 ERR(
"ReadBlocks details: BlockSize=%lu, IoAlign=%lu, Buffer=%p, DiskReadBuffer=%p, MediaId=0x%lx\n",
1211 ERR(
"ReadBlocks media: LastBlock=%llu, LogicalPartition=%s, RemovableMedia=%s\n",
1220 CurrentSector += ReadSectors;
1221 TotalSectors -= ReadSectors;
1236 ERR(
"ReadBlocks failed: DriveNumber=%d, SectorNumber=%llu, SectorCount=%lu, Status=0x%lx\n",
1238 ERR(
"ReadBlocks details: BlockSize=%lu, IoAlign=%lu, Buffer=%p, DiskReadBuffer=%p, MediaId=0x%lx\n",
1240 ERR(
"ReadBlocks media: LastBlock=%llu, LogicalPartition=%s, RemovableMedia=%s\n",
1253 ULONG ArcDriveIndex;
1264 ERR(
"InternalUefiDisk not initialized\n");
1270 ERR(
"Invalid drive number: %d\n", DriveNumber);
1281 ERR(
"Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1287 ERR(
"Media not present for drive %d\n", DriveNumber);
1292 Geometry->
Heads = 1;
1303 ULONG ArcDriveIndex;
1314 ERR(
"InternalUefiDisk not initialized\n");
1320 ERR(
"Invalid drive number: %d\n", DriveNumber);
1331 ERR(
"Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1337 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