ReactOS 0.4.17-dev-116-ga4b6fe9
uefidisk.c File Reference
#include <uefildr.h>
#include <debug.h>
#include "disk/part_gpt.h"
Include dependency graph for uefidisk.c:

Go to the source code of this file.

Classes

struct  tagDISKCONTEXT
 
struct  _INTERNAL_UEFI_DISK
 

Macros

#define TAG_HW_RESOURCE_LIST   'lRwH'
 
#define TAG_HW_DISK_CONTEXT   'cDwH'
 
#define FIRST_BIOS_DISK   0x80
 
#define FIRST_PARTITION   1
 
#define MAX_SUPPORTED_BLOCK_SIZE   8192
 

Typedefs

typedef struct tagDISKCONTEXT DISKCONTEXT
 
typedef struct _INTERNAL_UEFI_DISK INTERNAL_UEFI_DISK
 
typedef struct _INTERNAL_UEFI_DISKPINTERNAL_UEFI_DISK
 

Functions

 DBG_DEFAULT_CHANNEL (DISK)
 
PCSTR DiskGetErrorCodeString (_In_ ULONG ErrorCode)
 
static BOOLEAN UefiIsAlignedPointer (IN PVOID Pointer, IN ULONG Alignment)
 
static BOOLEAN UefiEnsureDiskReadBufferAligned (IN ULONG Alignment)
 
BOOLEAN DiskReadGptHeader (_In_ UCHAR DriveNumber, _Out_ PGPT_TABLE_HEADER GptHeader)
 
static BOOLEAN UefiGetBootPartitionEntry (_In_ UCHAR DriveNumber, _Out_opt_ PPARTITION_INFORMATION PartitionEntry, _Out_ PULONG BootPartition)
 
static ARC_STATUS UefiDiskClose (ULONG FileId)
 
static ARC_STATUS UefiDiskGetFileInformation (ULONG FileId, FILEINFORMATION *Information)
 
static ARC_STATUS UefiDiskOpen (CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
 
static ARC_STATUS UefiDiskRead (ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
 
static ARC_STATUS UefiDiskSeek (ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
 
static VOID GetHarddiskInformation (_In_ UCHAR DriveNumber)
 
static VOID UefiSetupBlockDevices (VOID)
 
static BOOLEAN UefiSetBootpath (VOID)
 
BOOLEAN UefiInitializeBootDevices (VOID)
 
UCHAR UefiGetFloppyCount (VOID)
 
BOOLEAN UefiDiskReadLogicalSectors (IN UCHAR DriveNumber, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
 
BOOLEAN UefiDiskGetDriveGeometry (UCHAR DriveNumber, PGEOMETRY Geometry)
 
ULONG UefiDiskGetCacheableBlockCount (UCHAR DriveNumber)
 

Variables

EFI_SYSTEM_TABLEGlobalSystemTable
 
EFI_HANDLE GlobalImageHandle
 
EFI_HANDLE PublicBootHandle
 
PVOID DiskReadBuffer
 
static PVOID DiskReadBufferRaw
 
static ULONG DiskReadBufferAlignment
 
static BOOLEAN DiskReadBufferFromPool
 
static BOOLEAN DiskReadBufferFallbackPool = FALSE
 
static UCHAR PcBiosDiskCount
 
UCHAR FrldrBootDrive
 
ULONG FrldrBootPartition
 
SIZE_T DiskReadBufferSize
 
static ULONG UefiBootRootIndex = 0
 
static ULONG PublicBootArcDisk = 0
 
static INTERNAL_UEFI_DISKInternalUefiDisk = NULL
 
static EFI_GUID BlockIoGuid = BLOCK_IO_PROTOCOL
 
static EFI_HANDLEhandles = NULL
 
static ULONG HandleCount = 0
 
static const DEVVTBL UefiDiskVtbl
 

Macro Definition Documentation

◆ FIRST_BIOS_DISK

#define FIRST_BIOS_DISK   0x80

Definition at line 17 of file uefidisk.c.

◆ FIRST_PARTITION

#define FIRST_PARTITION   1

Definition at line 18 of file uefidisk.c.

◆ MAX_SUPPORTED_BLOCK_SIZE

#define MAX_SUPPORTED_BLOCK_SIZE   8192

Definition at line 21 of file uefidisk.c.

◆ TAG_HW_DISK_CONTEXT

#define TAG_HW_DISK_CONTEXT   'cDwH'

Definition at line 16 of file uefidisk.c.

◆ TAG_HW_RESOURCE_LIST

#define TAG_HW_RESOURCE_LIST   'lRwH'

Definition at line 15 of file uefidisk.c.

Typedef Documentation

◆ DISKCONTEXT

◆ INTERNAL_UEFI_DISK

◆ PINTERNAL_UEFI_DISK

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( DISK  )

◆ DiskGetErrorCodeString()

PCSTR DiskGetErrorCodeString ( _In_ ULONG  ErrorCode)

Definition at line 73 of file uefidisk.c.

75{
76 return NULL;
77}
#define NULL
Definition: types.h:112

◆ DiskReadGptHeader()

BOOLEAN DiskReadGptHeader ( _In_ UCHAR  DriveNumber,
_Out_ PGPT_TABLE_HEADER  GptHeader 
)

Definition at line 22 of file part_gpt.c.

25{
26 /* Read GPT header (1 sector) from LBA 1 */
28 return FALSE;
29 RtlCopyMemory(GptHeader, DiskReadBuffer, sizeof(*GptHeader));
30
31 /* Verify GPT signature */
32 if (!RtlEqualMemory(GptHeader->Signature, EFI_PARTITION_HEADER_SIGNATURE, 8))
33 return FALSE;
34
35 /* Verify revision */
36 if (GptHeader->Revision != EFI_TABLE_REVISION)
37 {
38 TRACE("GPT header has unsupported revision: 0x%x\n", GptHeader->Revision);
39 return FALSE;
40 }
41
42 return TRUE;
43}
#define DiskReadBuffer
Definition: hardware.h:33
#define MachDiskReadLogicalSectors(Drive, Start, Count, Buf)
Definition: machine.h:120
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define RtlEqualMemory(dst, src, len)
Definition: kdvm.h:18
#define EFI_PARTITION_HEADER_SIGNATURE
Definition: part_gpt.h:11
#define EFI_TABLE_REVISION
Definition: part_gpt.h:13
#define EFI_HEADER_LOCATION
Definition: part_gpt.h:12
#define TRACE(s)
Definition: solgame.cpp:4
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by DiskDetectPartitionType(), and UefiGetBootPartitionEntry().

◆ GetHarddiskInformation()

static VOID GetHarddiskInformation ( _In_ UCHAR  DriveNumber)
static

Definition at line 644 of file uefidisk.c.

646{
647 static const CHAR Hex[] = "0123456789abcdef";
648
650 ULONG Checksum, Signature;
651 BOOLEAN ValidPartitionTable;
652 ULONG ArcDriveIndex;
654 CHAR DiskName[64];
655
657
658 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
659 if (ArcDriveIndex >= 32)
660 return;
661
663
664 RtlStringCbPrintfA(DiskName, sizeof(DiskName),
665 "multi(0)disk(0)rdisk(%u)",
666 ArcDriveIndex);
667
669 Status = DiskInitialize(DriveNumber, DiskName, DiskPeripheral, &UefiDiskVtbl,
670 &Checksum, &Signature, &ValidPartitionTable);
672
673 if (Status != ESUCCESS)
674 {
675 /* The disk failed to be initialized, use a default identifier */
676 RtlStringCbPrintfA(Identifier, 20, "BIOSDISK%u", ArcDriveIndex + 1);
677 return;
678 }
679
680 /* Convert checksum and signature to identifier string */
681 Identifier[0] = Hex[(Checksum >> 28) & 0x0F];
682 Identifier[1] = Hex[(Checksum >> 24) & 0x0F];
683 Identifier[2] = Hex[(Checksum >> 20) & 0x0F];
684 Identifier[3] = Hex[(Checksum >> 16) & 0x0F];
685 Identifier[4] = Hex[(Checksum >> 12) & 0x0F];
686 Identifier[5] = Hex[(Checksum >> 8) & 0x0F];
687 Identifier[6] = Hex[(Checksum >> 4) & 0x0F];
688 Identifier[7] = Hex[Checksum & 0x0F];
689 Identifier[8] = '-';
690 Identifier[9] = Hex[(Signature >> 28) & 0x0F];
691 Identifier[10] = Hex[(Signature >> 24) & 0x0F];
692 Identifier[11] = Hex[(Signature >> 20) & 0x0F];
693 Identifier[12] = Hex[(Signature >> 16) & 0x0F];
694 Identifier[13] = Hex[(Signature >> 12) & 0x0F];
695 Identifier[14] = Hex[(Signature >> 8) & 0x0F];
696 Identifier[15] = Hex[(Signature >> 4) & 0x0F];
697 Identifier[16] = Hex[Signature & 0x0F];
698 Identifier[17] = '-';
699 Identifier[18] = (ValidPartitionTable ? 'A' : 'X');
700 Identifier[19] = ANSI_NULL;
701 TRACE("Identifier: %s\n", Identifier);
702}
unsigned char BOOLEAN
Definition: actypes.h:127
@ Identifier
Definition: asmpp.cpp:95
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)
Definition: disk.c:78
LONG DiskReportError(_In_ BOOLEAN bShowError)
Definition: disk.c:38
static const WCHAR Signature[]
Definition: parser.c:141
Status
Definition: gdiplustypes.h:25
#define ASSERT(a)
Definition: mode.c:44
#define ANSI_NULL
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
char CHAR
Definition: pedump.c:57
static char Hex[]
Definition: pnpdump.c:50
@ ESUCCESS
Definition: arc.h:32
ULONG ARC_STATUS
Definition: arc.h:4
@ DiskPeripheral
Definition: arc.h:138
CHAR DiskIdentifier[20]
Definition: uefidisk.c:40
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
static const DEVVTBL UefiDiskVtbl
Definition: uefidisk.c:634
#define FIRST_BIOS_DISK
Definition: uefidisk.c:17
static INTERNAL_UEFI_DISK * InternalUefiDisk
Definition: uefidisk.c:64

Referenced by UefiSetupBlockDevices().

◆ UefiDiskClose()

static ARC_STATUS UefiDiskClose ( ULONG  FileId)
static

Definition at line 388 of file uefidisk.c.

389{
392 return ESUCCESS;
393}
PVOID FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:711
VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: heap.c:553
_In_ PVOID Context
Definition: storport.h:2269
#define TAG_HW_DISK_CONTEXT
Definition: uefidisk.c:16

◆ UefiDiskGetCacheableBlockCount()

ULONG UefiDiskGetCacheableBlockCount ( UCHAR  DriveNumber)

Definition at line 1301 of file uefidisk.c.

1302{
1303 ULONG ArcDriveIndex;
1304 EFI_BLOCK_IO* BlockIo;
1306
1307 if (DriveNumber < FIRST_BIOS_DISK)
1308 return 0;
1309
1310 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
1311
1312 if (InternalUefiDisk == NULL)
1313 {
1314 ERR("InternalUefiDisk not initialized\n");
1315 return 0;
1316 }
1317
1318 if (ArcDriveIndex >= 32 || InternalUefiDisk[ArcDriveIndex].Handle == NULL)
1319 {
1320 ERR("Invalid drive number: %d\n", DriveNumber);
1321 return 0;
1322 }
1323
1325 InternalUefiDisk[ArcDriveIndex].Handle,
1326 &BlockIoGuid,
1327 (VOID**)&BlockIo);
1328
1329 if (EFI_ERROR(Status) || BlockIo == NULL)
1330 {
1331 ERR("Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1332 return 0;
1333 }
1334
1335 if (!BlockIo->Media->MediaPresent)
1336 {
1337 ERR("Media not present for drive %d\n", DriveNumber);
1338 return 0;
1339 }
1340
1341 return (ULONG)(BlockIo->Media->LastBlock + 1);
1342}
#define EFI_ERROR(A)
Definition: UefiBaseType.h:165
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:31
#define ERR(fmt,...)
Definition: precomp.h:57
ULONG Handle
Definition: gdb_input.c:15
EFI_HANDLE_PROTOCOL HandleProtocol
Definition: UefiSpec.h:1832
EFI_BOOT_SERVICES * BootServices
Definition: UefiSpec.h:1959
static EFI_GUID BlockIoGuid
Definition: uefidisk.c:65
EFI_SYSTEM_TABLE * GlobalSystemTable
Definition: uefildr.c:16

Referenced by MachInit().

◆ UefiDiskGetDriveGeometry()

BOOLEAN UefiDiskGetDriveGeometry ( UCHAR  DriveNumber,
PGEOMETRY  Geometry 
)

Definition at line 1251 of file uefidisk.c.

1252{
1253 ULONG ArcDriveIndex;
1254 EFI_BLOCK_IO* BlockIo;
1256
1257 if (DriveNumber < FIRST_BIOS_DISK)
1258 return FALSE;
1259
1260 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
1261
1262 if (InternalUefiDisk == NULL)
1263 {
1264 ERR("InternalUefiDisk not initialized\n");
1265 return FALSE;
1266 }
1267
1268 if (ArcDriveIndex >= 32 || InternalUefiDisk[ArcDriveIndex].Handle == NULL)
1269 {
1270 ERR("Invalid drive number: %d\n", DriveNumber);
1271 return FALSE;
1272 }
1273
1275 InternalUefiDisk[ArcDriveIndex].Handle,
1276 &BlockIoGuid,
1277 (VOID**)&BlockIo);
1278
1279 if (EFI_ERROR(Status) || BlockIo == NULL)
1280 {
1281 ERR("Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1282 return FALSE;
1283 }
1284
1285 if (!BlockIo->Media->MediaPresent)
1286 {
1287 ERR("Media not present for drive %d\n", DriveNumber);
1288 return FALSE;
1289 }
1290
1291 Geometry->Cylinders = 1; /* Not relevant for UEFI Block I/O protocol */
1292 Geometry->Heads = 1; /* Not relevant for UEFI Block I/O protocol */
1293 Geometry->SectorsPerTrack = (ULONG)(BlockIo->Media->LastBlock + 1);
1294 Geometry->BytesPerSector = BlockIo->Media->BlockSize;
1295 Geometry->Sectors = BlockIo->Media->LastBlock + 1;
1296
1297 return TRUE;
1298}
ULONG BytesPerSector
Number of bytes per sector.
Definition: disk.h:28
ULONG Cylinders
Number of cylinders on the disk.
Definition: disk.h:25
ULONGLONG Sectors
Total number of disk sectors/LBA blocks.
Definition: disk.h:29
ULONG SectorsPerTrack
Number of sectors per track.
Definition: disk.h:27
ULONG Heads
Number of heads on the disk.
Definition: disk.h:26

Referenced by MachInit().

◆ UefiDiskGetFileInformation()

static ARC_STATUS UefiDiskGetFileInformation ( ULONG  FileId,
FILEINFORMATION Information 
)
static

Definition at line 397 of file uefidisk.c.

398{
401
402 /*
403 * The ARC specification mentions that for partitions, StartingAddress and
404 * EndingAddress are the start and end positions of the partition in terms
405 * of byte offsets from the start of the disk.
406 * CurrentAddress is the current offset into (i.e. relative to) the partition.
407 */
408 Information->StartingAddress.QuadPart = Context->SectorOffset * Context->SectorSize;
409 Information->EndingAddress.QuadPart = (Context->SectorOffset + Context->SectorCount) * Context->SectorSize;
410 Information->CurrentAddress.QuadPart = Context->SectorNumber * Context->SectorSize;
411
412 Information->Type = DiskPeripheral; /* No floppy for you for now... */
413
414 return ESUCCESS;
415}
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049

◆ UefiDiskOpen()

static ARC_STATUS UefiDiskOpen ( CHAR Path,
OPENMODE  OpenMode,
ULONG FileId 
)
static

Definition at line 419 of file uefidisk.c.

420{
422 UCHAR DriveNumber;
423 ULONG DrivePartition, SectorSize;
426 ULONG ArcDriveIndex;
427 EFI_BLOCK_IO* BlockIo;
429
430 TRACE("UefiDiskOpen: File ID: %p, Path: %s\n", FileId, Path);
431
432 if (DiskReadBufferSize == 0)
433 {
434 ERR("DiskOpen(): DiskReadBufferSize is 0, something is wrong.\n");
435 ASSERT(FALSE);
436 return ENOMEM;
437 }
438
439 if (!DissectArcPath(Path, NULL, &DriveNumber, &DrivePartition))
440 return EINVAL;
441
442 TRACE("Opening disk: DriveNumber: %d, DrivePartition: %d\n", DriveNumber, DrivePartition);
443
444 if (DriveNumber < FIRST_BIOS_DISK)
445 return EINVAL;
446
447 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
448 if (ArcDriveIndex >= PcBiosDiskCount || InternalUefiDisk == NULL)
449 return EINVAL;
450
451 /* Get Block I/O protocol for this drive */
453 InternalUefiDisk[ArcDriveIndex].Handle,
455 (VOID**)&BlockIo);
456
457 if (EFI_ERROR(Status) || BlockIo == NULL)
458 {
459 ERR("Failed to get Block I/O protocol for drive %d\n", DriveNumber);
460 return EINVAL;
461 }
462
463 /* Check media is present */
464 if (!BlockIo->Media->MediaPresent)
465 {
466 ERR("Media not present for drive %d\n", DriveNumber);
467 return ENXIO;
468 }
469
470#if 0
471 GEOMETRY Geometry;
472 if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
473 return EIO;
474#endif
475 SectorSize = BlockIo->Media->BlockSize;
476
477 if (DrivePartition != 0xff && DrivePartition != 0)
478 {
479 PARTITION_INFORMATION PartitionEntry;
480 if (!DiskGetPartitionEntry(DriveNumber, SectorSize, DrivePartition, &PartitionEntry))
481 return EIO;
482
485 }
486 else
487 {
488 SectorOffset = 0;
489 SectorCount = BlockIo->Media->LastBlock + 1; // Geometry.Sectors;
490 }
491
493 if (!Context)
494 return ENOMEM;
495
496 Context->DriveNumber = DriveNumber;
497 Context->SectorSize = SectorSize;
498 Context->SectorOffset = SectorOffset;
499 Context->SectorCount = SectorCount;
500 Context->SectorNumber = 0;
502
503 return ESUCCESS;
504}
PRTL_UNICODE_STRING_BUFFER Path
BOOLEAN DissectArcPath(IN PCSTR ArcPath, OUT PCSTR *Path OPTIONAL, OUT PUCHAR DriveNumber, OUT PULONG PartitionNumber)
Definition: arcname.c:25
BOOLEAN DiskGetPartitionEntry(_In_ UCHAR DriveNumber, _In_opt_ ULONG SectorSize, _In_ ULONG PartitionNumber, _Out_ PPARTITION_INFORMATION PartitionEntry)
Definition: partition.c:178
VOID FsSetDeviceSpecific(ULONG FileId, PVOID Specific)
Definition: fs.c:704
#define MachDiskGetDriveGeometry(Drive, Geom)
Definition: machine.h:122
PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: heap.c:545
#define SectorOffset(L)
Definition: cdprocs.h:1622
#define ENXIO
Definition: errno.h:29
#define EINVAL
Definition: errno.h:44
#define ENOMEM
Definition: errno.h:35
#define EIO
Definition: errno.h:28
ULONG SectorCount
Definition: part_brfr.c:22
Definition: disk.h:24
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:408
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:409
unsigned char UCHAR
Definition: typedefs.h:53
uint64_t ULONGLONG
Definition: typedefs.h:67
static UCHAR PcBiosDiskCount
Definition: uefidisk.c:55
SIZE_T DiskReadBufferSize
Definition: uefidisk.c:59
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ ULONG SectorSize
Definition: halfuncs.h:291

◆ UefiDiskRead()

static ARC_STATUS UefiDiskRead ( ULONG  FileId,
VOID Buffer,
ULONG  N,
ULONG Count 
)
static

Definition at line 508 of file uefidisk.c.

509{
511 UCHAR* Ptr = (UCHAR*)Buffer;
512 ULONG Length, TotalSectors, MaxSectors, ReadSectors;
514 BOOLEAN ret;
515 EFI_BLOCK_IO* BlockIo;
517 ULONG ArcDriveIndex;
518
520
521 TotalSectors = (N + Context->SectorSize - 1) / Context->SectorSize;
522 MaxSectors = DiskReadBufferSize / Context->SectorSize;
523 SectorOffset = Context->SectorOffset + Context->SectorNumber;
524
525 // If MaxSectors is 0, this will lead to infinite loop.
526 // In release builds assertions are disabled, however we also have sanity checks in DiskOpen()
527 ASSERT(MaxSectors > 0);
528
529 if (MaxSectors == 0)
530 {
531 ERR("MaxSectors is 0, cannot read\n");
532 *Count = 0;
533 return EIO;
534 }
535
536 ArcDriveIndex = Context->DriveNumber - FIRST_BIOS_DISK;
537 if (ArcDriveIndex >= PcBiosDiskCount || InternalUefiDisk == NULL)
538 {
539 ERR("Invalid drive number %d\n", Context->DriveNumber);
540 *Count = 0;
541 return EINVAL;
542 }
543
544 /* Get Block I/O protocol */
546 InternalUefiDisk[ArcDriveIndex].Handle,
548 (VOID**)&BlockIo);
549
550 if (EFI_ERROR(Status) || BlockIo == NULL)
551 {
552 ERR("Failed to get Block I/O protocol\n");
553 *Count = 0;
554 return EIO;
555 }
556
557 if (!UefiEnsureDiskReadBufferAligned(BlockIo->Media->IoAlign))
558 {
559 ERR("Failed to align disk read buffer\n");
560 *Count = 0;
561 return EIO;
562 }
563
564 ret = TRUE;
565
566 while (TotalSectors)
567 {
568 ReadSectors = min(TotalSectors, MaxSectors);
569
570 Status = BlockIo->ReadBlocks(
571 BlockIo,
572 BlockIo->Media->MediaId,
574 ReadSectors * Context->SectorSize,
576
577 if (EFI_ERROR(Status))
578 {
579 ERR("ReadBlocks failed: Status = 0x%lx\n", (ULONG)Status);
580 ret = FALSE;
581 break;
582 }
583
584 Length = ReadSectors * Context->SectorSize;
585 Length = min(Length, N);
586
588
589 Ptr += Length;
590 N -= Length;
591 SectorOffset += ReadSectors;
592 TotalSectors -= ReadSectors;
593 }
594
596 Context->SectorNumber = SectorOffset - Context->SectorOffset;
597
598 return (ret ? ESUCCESS : EIO);
599}
#define N
Definition: crc32.c:57
Definition: bufpool.h:45
return ret
Definition: mutex.c:146
#define ULONG_PTR
Definition: config.h:101
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define min(a, b)
Definition: monoChain.cc:55
int Count
Definition: noreturn.cpp:7
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
uint32_t ULONG_PTR
Definition: typedefs.h:65
PVOID DiskReadBuffer
Definition: uefidisk.c:50
static BOOLEAN UefiEnsureDiskReadBufferAligned(IN ULONG Alignment)
Definition: uefidisk.c:96

◆ UefiDiskReadLogicalSectors()

BOOLEAN UefiDiskReadLogicalSectors ( IN UCHAR  DriveNumber,
IN ULONGLONG  SectorNumber,
IN ULONG  SectorCount,
OUT PVOID  Buffer 
)

Definition at line 1116 of file uefidisk.c.

1121{
1122 ULONG ArcDriveIndex;
1123 EFI_BLOCK_IO* BlockIo;
1125 ULONG BlockSize;
1126 ULONG IoAlign;
1127
1128 if (DriveNumber < FIRST_BIOS_DISK)
1129 return FALSE;
1130
1131 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
1132
1133 if (InternalUefiDisk == NULL)
1134 {
1135 ERR("InternalUefiDisk not initialized\n");
1136 return FALSE;
1137 }
1138
1139 if (ArcDriveIndex >= 32)
1140 {
1141 ERR("Drive index out of bounds: %d (ArcDriveIndex=%lu)\n", DriveNumber, ArcDriveIndex);
1142 return FALSE;
1143 }
1144
1145 /* Allow access during initialization: check if handle is set up.
1146 * During initialization, Handle is set before GetHarddiskInformation is called. */
1147 if (InternalUefiDisk[ArcDriveIndex].Handle == NULL)
1148 {
1149 ERR("Invalid drive number: %d (ArcDriveIndex=%lu, PcBiosDiskCount=%lu, Handle=NULL)\n",
1150 DriveNumber, ArcDriveIndex, PcBiosDiskCount);
1151 return FALSE;
1152 }
1153
1155 InternalUefiDisk[ArcDriveIndex].Handle,
1156 &BlockIoGuid,
1157 (VOID**)&BlockIo);
1158
1159 if (EFI_ERROR(Status) || BlockIo == NULL)
1160 {
1161 ERR("Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1162 return FALSE;
1163 }
1164
1165 if (!BlockIo->Media->MediaPresent)
1166 {
1167 ERR("Media not present for drive %d\n", DriveNumber);
1168 return FALSE;
1169 }
1170
1171 BlockSize = BlockIo->Media->BlockSize;
1172 IoAlign = BlockIo->Media->IoAlign;
1173
1174 if (!UefiEnsureDiskReadBufferAligned(IoAlign))
1175 {
1176 ERR("Failed to align disk read buffer for drive %d\n", DriveNumber);
1177 return FALSE;
1178 }
1179
1180 if (!UefiIsAlignedPointer(Buffer, (IoAlign == 0) ? 1 : IoAlign))
1181 {
1182 ULONG TotalSectors = SectorCount;
1183 ULONG MaxSectors = DiskReadBufferSize / BlockSize;
1184 ULONGLONG CurrentSector = SectorNumber;
1185 PUCHAR OutPtr = (PUCHAR)Buffer;
1186
1187 if (MaxSectors == 0)
1188 {
1189 ERR("DiskReadBufferSize too small for block size %lu\n", BlockSize);
1190 return FALSE;
1191 }
1192
1193 while (TotalSectors)
1194 {
1195 ULONG ReadSectors = min(TotalSectors, MaxSectors);
1196 UINTN ReadSize = ReadSectors * BlockSize;
1197
1198 Status = BlockIo->ReadBlocks(
1199 BlockIo,
1200 BlockIo->Media->MediaId,
1201 CurrentSector,
1202 ReadSize,
1204
1205 if (EFI_ERROR(Status))
1206 {
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",
1210 BlockSize, IoAlign, Buffer, DiskReadBuffer, (ULONG)BlockIo->Media->MediaId);
1211 ERR("ReadBlocks media: LastBlock=%llu, LogicalPartition=%s, RemovableMedia=%s\n",
1212 BlockIo->Media->LastBlock,
1213 BlockIo->Media->LogicalPartition ? "TRUE" : "FALSE",
1214 BlockIo->Media->RemovableMedia ? "TRUE" : "FALSE");
1215 return FALSE;
1216 }
1217
1218 RtlCopyMemory(OutPtr, DiskReadBuffer, ReadSize);
1219 OutPtr += ReadSize;
1220 CurrentSector += ReadSectors;
1221 TotalSectors -= ReadSectors;
1222 }
1223
1224 return TRUE;
1225 }
1226
1227 Status = BlockIo->ReadBlocks(
1228 BlockIo,
1229 BlockIo->Media->MediaId,
1230 SectorNumber,
1231 SectorCount * BlockSize,
1232 Buffer);
1233
1234 if (EFI_ERROR(Status))
1235 {
1236 ERR("ReadBlocks failed: DriveNumber=%d, SectorNumber=%llu, SectorCount=%lu, Status=0x%lx\n",
1237 DriveNumber, SectorNumber, SectorCount, (ULONG)Status);
1238 ERR("ReadBlocks details: BlockSize=%lu, IoAlign=%lu, Buffer=%p, DiskReadBuffer=%p, MediaId=0x%lx\n",
1239 BlockSize, IoAlign, Buffer, DiskReadBuffer, (ULONG)BlockIo->Media->MediaId);
1240 ERR("ReadBlocks media: LastBlock=%llu, LogicalPartition=%s, RemovableMedia=%s\n",
1241 BlockIo->Media->LastBlock,
1242 BlockIo->Media->LogicalPartition ? "TRUE" : "FALSE",
1243 BlockIo->Media->RemovableMedia ? "TRUE" : "FALSE");
1244 return FALSE;
1245 }
1246
1247 return TRUE;
1248}
UINT32 UINTN
unsigned char * PUCHAR
Definition: typedefs.h:53
static BOOLEAN UefiIsAlignedPointer(IN PVOID Pointer, IN ULONG Alignment)
Definition: uefidisk.c:81

Referenced by MachInit().

◆ UefiDiskSeek()

static ARC_STATUS UefiDiskSeek ( ULONG  FileId,
LARGE_INTEGER Position,
SEEKMODE  SeekMode 
)
static

Definition at line 603 of file uefidisk.c.

604{
606 LARGE_INTEGER NewPosition = *Position;
607
608 switch (SeekMode)
609 {
610 case SeekAbsolute:
611 break;
612 case SeekRelative:
613 NewPosition.QuadPart += (Context->SectorNumber * Context->SectorSize);
614 break;
615 default:
616 ASSERT(FALSE);
617 return EINVAL;
618 }
619
620 if (NewPosition.QuadPart & (Context->SectorSize - 1))
621 return EINVAL;
622
623 /* Convert in number of sectors */
624 NewPosition.QuadPart /= Context->SectorSize;
625
626 /* HACK: CDROMs may have a SectorCount of 0 */
627 if (Context->SectorCount != 0 && NewPosition.QuadPart >= Context->SectorCount)
628 return EINVAL;
629
630 Context->SectorNumber = NewPosition.QuadPart;
631 return ESUCCESS;
632}
@ SeekRelative
Definition: arc.h:60
@ SeekAbsolute
Definition: arc.h:59
static COORD Position
Definition: mouse.c:34

◆ UefiEnsureDiskReadBufferAligned()

static BOOLEAN UefiEnsureDiskReadBufferAligned ( IN ULONG  Alignment)
static

Definition at line 96 of file uefidisk.c.

98{
99 ULONG RequiredAlignment = (Alignment == 0) ? 1 : Alignment;
101
102 if (DiskReadBuffer != NULL && DiskReadBufferAlignment >= RequiredAlignment &&
103 UefiIsAlignedPointer(DiskReadBuffer, RequiredAlignment))
104 {
105 return TRUE;
106 }
107
108 DiskReadBufferAlignment = RequiredAlignment;
109
111 {
113 {
115 }
116 else
117 {
119 }
120
125 }
126
128 DiskReadBufferSize + RequiredAlignment,
129 (void**)&DiskReadBufferRaw);
131 {
132 /* This can sometimes happen on Mac firmware and probably happens on other EFI 1.x devices as well. */
133 WARN("Failed to allocate aligned disk read buffer using AllocatePool, trying MmAllocateMemoryWithType (buffer size = 0x%X, alignment %lu)\n",
134 DiskReadBufferSize, RequiredAlignment);
137 if (DiskReadBufferRaw == NULL)
138 {
139 /* That failed too */
140 ERR("Failed to allocate aligned disk read buffer (buffer size = 0x%X, alignment %lu)\n",
141 DiskReadBufferSize, RequiredAlignment);
142 return FALSE;
143 }
144
146 }
147
149
151 if (!UefiIsAlignedPointer(DiskReadBuffer, RequiredAlignment))
152 {
153 ERR("Aligned disk read buffer is not properly aligned (align %lu)\n", RequiredAlignment);
154 return FALSE;
155 }
156
157 return TRUE;
158}
@ EfiLoaderData
#define WARN(fmt,...)
Definition: precomp.h:61
VOID MmFreeMemory(PVOID MemoryPointer)
Definition: mm.c:215
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
@ LoaderFirmwareTemporary
Definition: arc.h:298
EFI_FREE_POOL FreePool
Definition: UefiSpec.h:1814
EFI_ALLOCATE_POOL AllocatePool
Definition: UefiSpec.h:1813
void * PVOID
Definition: typedefs.h:50
static BOOLEAN DiskReadBufferFromPool
Definition: uefidisk.c:53
static BOOLEAN DiskReadBufferFallbackPool
Definition: uefidisk.c:54
static ULONG DiskReadBufferAlignment
Definition: uefidisk.c:52
static PVOID DiskReadBufferRaw
Definition: uefidisk.c:51
#define ALIGN_UP_POINTER_BY(ptr, align)
Definition: umtypes.h:85

Referenced by UefiDiskRead(), UefiDiskReadLogicalSectors(), UefiInitializeBootDevices(), and UefiSetupBlockDevices().

◆ UefiGetBootPartitionEntry()

static BOOLEAN UefiGetBootPartitionEntry ( _In_ UCHAR  DriveNumber,
_Out_opt_ PPARTITION_INFORMATION  PartitionEntry,
_Out_ PULONG  BootPartition 
)
static

Definition at line 170 of file uefidisk.c.

174{
175 ULONG PartitionNum;
176 ULONG ArcDriveIndex;
177 EFI_BLOCK_IO* BootBlockIo;
179 ULONG BlockSize;
180 ULONGLONG BootPartitionSize;
181 PARTITION_INFORMATION TempPartitionEntry;
182
183 TRACE("UefiGetBootPartitionEntry: DriveNumber: %d\n", DriveNumber - FIRST_BIOS_DISK);
184
185 if (DriveNumber < FIRST_BIOS_DISK)
186 return FALSE;
187
188 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
189 if (ArcDriveIndex >= PcBiosDiskCount || handles == NULL || UefiBootRootIndex >= HandleCount)
190 return FALSE;
191
192 /* Get the boot handle's Block I/O protocol to determine partition offset/size */
196 (VOID**)&BootBlockIo);
197
198 if (EFI_ERROR(Status) || BootBlockIo == NULL)
199 {
200 ERR("Failed to get Block I/O protocol for boot handle\n");
201 return FALSE;
202 }
203
204 /* For logical partitions, UEFI Block I/O protocol starts at block 0.
205 * We need to find which partition it corresponds to by comparing sizes. */
206 BootPartitionSize = BootBlockIo->Media->LastBlock + 1;
207
208 TRACE("Boot partition: Size=%llu blocks, BlockSize=%lu\n",
209 BootPartitionSize, BootBlockIo->Media->BlockSize);
210
211 /* If boot handle is the root device itself (not a logical partition) */
212 if (!BootBlockIo->Media->LogicalPartition)
213 {
214 TRACE("Boot handle is root device, using partition 0\n");
215 *BootPartition = 0;
216 if (PartitionEntry)
217 {
218 // RtlZeroMemory(PartitionEntry, sizeof(*PartitionEntry));
219 /* Represent the whole disk */
220 PartitionEntry->StartingOffset.QuadPart = 0ULL;
221 PartitionEntry->PartitionLength.QuadPart = (BootPartitionSize * BootBlockIo->Media->BlockSize);
222 PartitionEntry->HiddenSectors = 0;
223 PartitionEntry->PartitionNumber = *BootPartition;
224 PartitionEntry->PartitionType = PARTITION_GPT; /* Mark as GPT partition */
225 PartitionEntry->BootIndicator = TRUE;
226 PartitionEntry->RecognizedPartition = TRUE;
227 PartitionEntry->RewritePartition = FALSE;
228 }
229 return TRUE;
230 }
231
232 /* Boot handle is a logical partition - find matching partition entry.
233 * Try to detect GPT first by reading the GPT header. */
234 GPT_TABLE_HEADER GptHeader;
235 BOOLEAN IsGpt = DiskReadGptHeader(DriveNumber, &GptHeader);
236 if (IsGpt)
237 {
238 /* For GPT, iterate through GPT partition entries */
239 GPT_PARTITION_ENTRY GptEntry;
240 EFI_BLOCK_IO* RootBlockIo;
241 ULONG EntriesPerBlock;
245
247 InternalUefiDisk[ArcDriveIndex].Handle,
249 (VOID**)&RootBlockIo);
250
251 if (EFI_ERROR(Status) || RootBlockIo == NULL)
252 return FALSE;
253
254 BlockSize = RootBlockIo->Media->BlockSize;
255 EntriesPerBlock = BlockSize / GptHeader.SizeOfPartitionEntry;
256
257 /* Iterate through GPT partition entries */
258 for (ULONG i = 0; i < GptHeader.NumberOfPartitionEntries; i++)
259 {
260 ULONGLONG EntryLba = GptHeader.PartitionEntryLba + (i / EntriesPerBlock);
261 ULONG EntryOffset = (i % EntriesPerBlock) * GptHeader.SizeOfPartitionEntry;
262
263 /* Read the block containing the partition entry */
264 Status = RootBlockIo->ReadBlocks(
265 RootBlockIo,
266 RootBlockIo->Media->MediaId,
267 EntryLba,
268 BlockSize,
270
271 if (EFI_ERROR(Status))
272 continue;
273
274 /* Extract partition entry */
275 RtlCopyMemory(&GptEntry, (PUCHAR)DiskReadBuffer + EntryOffset, sizeof(GptEntry));
276
277 /* Skip unused partitions */
278 if (RtlEqualMemory(&GptEntry.PartitionTypeGuid, &UnusedGuid, sizeof(UnusedGuid)))
279 continue;
280
281 /* Calculate partition size in blocks */
282 ULONGLONG PartitionSizeBlocks = GptEntry.EndingLba - GptEntry.StartingLba + 1;
283
284 TRACE("GPT Partition %lu: StartLba=%llu, EndLba=%llu, SizeBlocks=%llu\n",
285 i + 1, GptEntry.StartingLba, GptEntry.EndingLba, PartitionSizeBlocks);
286
287 /* Match partition by size (within 1 block tolerance for rounding) */
288 if (PartitionSizeBlocks == BootPartitionSize ||
289 (PartitionSizeBlocks > 0 &&
290 (PartitionSizeBlocks - 1 <= BootPartitionSize &&
291 BootPartitionSize <= PartitionSizeBlocks + 1)))
292 {
293 TRACE("Found matching GPT partition %lu: Size matches (%llu blocks)\n",
294 i + 1, BootPartitionSize);
295
296 *BootPartition = i + 1; /* GPT partitions are 1-indexed */
297
298 /* Convert GPT entry to standard-style entry */
299 if (PartitionEntry)
300 {
301 PartitionEntry->StartingOffset.QuadPart = (GptEntry.StartingLba * BlockSize);
302 PartitionEntry->PartitionLength.QuadPart = ((ULONGLONG)PartitionSizeBlocks * BlockSize);
303 PartitionEntry->HiddenSectors = 0;
304 PartitionEntry->PartitionNumber = *BootPartition;
305 PartitionEntry->PartitionType = PARTITION_GPT; /* Mark as GPT partition */
306 PartitionEntry->BootIndicator = RtlEqualMemory(&GptEntry.PartitionTypeGuid, &SystemGuid, sizeof(SystemGuid));
307 PartitionEntry->RecognizedPartition = TRUE;
308 PartitionEntry->RewritePartition = FALSE;
309 }
310 return TRUE;
311 }
312 }
313 }
314 else
315 {
316 /* MBR partition matching */
317
318 BlockSize = BootBlockIo->Media->BlockSize;
319
320 PartitionNum = FIRST_PARTITION;
321 while (DiskGetPartitionEntry(DriveNumber, BlockSize, PartitionNum, &TempPartitionEntry))
322 {
323 /* Convert partition size to UEFI blocks */
324 ULONGLONG PartitionSizeBlocks = TempPartitionEntry.PartitionLength.QuadPart / BlockSize;
325 ULONGLONG StartingLba = TempPartitionEntry.StartingOffset.QuadPart / BlockSize;
326 ULONGLONG EndingLba = StartingLba + PartitionSizeBlocks - 1;
327
328 TRACE("Partition %lu: StartLba=%llu, EndLba=%llu, SizeBlocks=%llu\n",
329 PartitionNum, StartingLba, EndingLba, PartitionSizeBlocks);
330
331 /* Match partition by size (within 1 block tolerance for rounding) */
332 if (PartitionSizeBlocks == BootPartitionSize ||
333 (PartitionSizeBlocks > 0 &&
334 (PartitionSizeBlocks - 1 <= BootPartitionSize &&
335 BootPartitionSize <= PartitionSizeBlocks + 1)))
336 {
337 TRACE("Found matching partition %lu: Size matches (%llu blocks)\n",
338 PartitionNum, BootPartitionSize);
339
340 *BootPartition = PartitionNum;
341 if (PartitionEntry)
342 RtlCopyMemory(PartitionEntry, &TempPartitionEntry, sizeof(*PartitionEntry));
343 return TRUE;
344 }
345
346 PartitionNum++;
347 }
348 }
349
350 /* If we couldn't find a match, check if it's a CD-ROM (special case) */
351 if (BootBlockIo->Media->RemovableMedia && BootBlockIo->Media->BlockSize == 2048)
352 {
353 TRACE("Boot device is CD-ROM, using partition 0xFF\n");
354 *BootPartition = 0xFF;
355 if (PartitionEntry)
356 {
357 // RtlZeroMemory(PartitionEntry, sizeof(*PartitionEntry));
358 /* Represent the whole disk */
359 PartitionEntry->StartingOffset.QuadPart = 0ULL;
360 PartitionEntry->PartitionLength.QuadPart = (BootPartitionSize * BootBlockIo->Media->BlockSize);
361 PartitionEntry->HiddenSectors = 0;
362 PartitionEntry->PartitionNumber = *BootPartition;
363 PartitionEntry->PartitionType = PARTITION_GPT; /* Mark as GPT partition */
364 PartitionEntry->BootIndicator = TRUE;
365 PartitionEntry->RecognizedPartition = TRUE;
366 PartitionEntry->RewritePartition = FALSE;
367 }
368 return TRUE;
369 }
370
371 /* Fallback: if we can't determine, use partition 1 */
372 ERR("Could not determine boot partition, using partition 1 as fallback\n");
373 PartitionNum = FIRST_PARTITION;
374 if (DiskGetPartitionEntry(DriveNumber, BootBlockIo->Media->BlockSize,
375 PartitionNum, &TempPartitionEntry))
376 {
377 *BootPartition = PartitionNum;
378 if (PartitionEntry)
379 RtlCopyMemory(PartitionEntry, &TempPartitionEntry, sizeof(*PartitionEntry));
380 return TRUE;
381 }
382
383 return FALSE;
384}
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
Definition: glfuncs.h:248
#define ULL(a, b)
Definition: format_msg.c:27
#define EFI_PART_TYPE_EFI_SYSTEM_PART_GUID
Definition: part_gpt.h:23
#define EFI_PART_TYPE_UNUSED_GUID
Definition: part_gpt.h:20
#define PARTITION_GPT
Definition: part_gpt.h:27
Definition: part_gpt.h:54
UINT64 EndingLba
Definition: part_gpt.h:58
UINT64 StartingLba
Definition: part_gpt.h:57
GUID PartitionTypeGuid
Definition: part_gpt.h:55
UINT32 NumberOfPartitionEntries
Definition: part_gpt.h:46
UINT32 SizeOfPartitionEntry
Definition: part_gpt.h:47
UINT64 PartitionEntryLba
Definition: part_gpt.h:45
BOOLEAN DiskReadGptHeader(_In_ UCHAR DriveNumber, _Out_ PGPT_TABLE_HEADER GptHeader)
Definition: part_gpt.c:22
static ULONG UefiBootRootIndex
Definition: uefidisk.c:62
static ULONG HandleCount
Definition: uefidisk.c:67
static EFI_HANDLE * handles
Definition: uefidisk.c:66
#define FIRST_PARTITION
Definition: uefidisk.c:18

Referenced by UefiSetBootpath().

◆ UefiGetFloppyCount()

UCHAR UefiGetFloppyCount ( VOID  )

Definition at line 1109 of file uefidisk.c.

1110{
1111 /* No floppy support in UEFI */
1112 return 0;
1113}

Referenced by MachInit().

◆ UefiInitializeBootDevices()

BOOLEAN UefiInitializeBootDevices ( VOID  )

Definition at line 1040 of file uefidisk.c.

1041{
1042 EFI_BLOCK_IO* BlockIo;
1044 ULONG ArcDriveIndex;
1045
1052 {
1053 ERR("Failed to allocate disk read buffer\n");
1054 return FALSE;
1055 }
1056
1058
1059 if (PcBiosDiskCount == 0)
1060 {
1061 ERR("No block devices found\n");
1062 return FALSE;
1063 }
1064
1065 if (!UefiSetBootpath())
1066 {
1067 ERR("Failed to set boot path\n");
1068 return FALSE;
1069 }
1070
1071 /* Handle CD-ROM boot device registration */
1072 ArcDriveIndex = PublicBootArcDisk;
1073 if (ArcDriveIndex >= PcBiosDiskCount || InternalUefiDisk == NULL)
1074 {
1075 ERR("Invalid boot arc disk index\n");
1076 return FALSE;
1077 }
1078
1080 InternalUefiDisk[ArcDriveIndex].Handle,
1081 &BlockIoGuid,
1082 (VOID**)&BlockIo);
1083
1084 if (EFI_ERROR(Status) || BlockIo == NULL)
1085 {
1086 ERR("Failed to get Block I/O protocol\n");
1087 return FALSE;
1088 }
1089
1090 if (BlockIo->Media->RemovableMedia == TRUE && BlockIo->Media->BlockSize == 2048)
1091 {
1093
1098
1099 if (Status == ESUCCESS)
1100 TRACE("Registered CD-ROM boot device: 0x%02X\n", FrldrBootDrive);
1101 else
1102 ERR("CD-ROM boot device 0x%02X failed\n", FrldrBootDrive);
1103 }
1104
1105 return TRUE;
1106}
#define EFI_PAGE_SIZE
Definition: UefiBaseType.h:189
CCHAR FrLdrBootPath[MAX_PATH]
Definition: freeldr.c:29
@ CdromController
Definition: arc.h:128
static ULONG PublicBootArcDisk
Definition: uefidisk.c:63
static VOID UefiSetupBlockDevices(VOID)
Definition: uefidisk.c:706
UCHAR FrldrBootDrive
Definition: uefidisk.c:57
static BOOLEAN UefiSetBootpath(VOID)
Definition: uefidisk.c:962

Referenced by MachInit().

◆ UefiIsAlignedPointer()

static BOOLEAN UefiIsAlignedPointer ( IN PVOID  Pointer,
IN ULONG  Alignment 
)
static

Definition at line 81 of file uefidisk.c.

84{
86
87 if (Alignment <= 1)
88 return TRUE;
89
90 Value = (ULONG_PTR)Pointer;
91 return ((Value & (Alignment - 1)) == 0);
92}
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by UefiDiskReadLogicalSectors(), and UefiEnsureDiskReadBufferAligned().

◆ UefiSetBootpath()

static BOOLEAN UefiSetBootpath ( VOID  )
static

Definition at line 962 of file uefidisk.c.

963{
964 EFI_BLOCK_IO* BootBlockIo = NULL;
966 ULONG ArcDriveIndex;
967
968 TRACE("UefiSetBootpath: Setting up boot path\n");
969
971 {
972 ERR("Invalid boot root index\n");
973 return FALSE;
974 }
975
976 ArcDriveIndex = PublicBootArcDisk;
977 if (ArcDriveIndex >= PcBiosDiskCount || InternalUefiDisk == NULL)
978 {
979 ERR("Invalid boot arc disk index\n");
980 return FALSE;
981 }
982
986 (VOID**)&BootBlockIo);
987
988 if (EFI_ERROR(Status) || BootBlockIo == NULL)
989 {
990 ERR("Failed to get Block I/O protocol for boot handle\n");
991 return FALSE;
992 }
993
994 FrldrBootDrive = (FIRST_BIOS_DISK + ArcDriveIndex);
995
996 /* Check if booting from CD-ROM by checking the boot handle properties.
997 * CD-ROMs have BlockSize=2048 and RemovableMedia=TRUE. */
998 if (BootBlockIo->Media->RemovableMedia == TRUE && BootBlockIo->Media->BlockSize == 2048)
999 {
1000 /* Boot Partition 0xFF is the magic value that indicates booting from CD-ROM */
1001 FrldrBootPartition = 0xFF;
1003 "multi(0)disk(0)cdrom(%u)", ArcDriveIndex);
1004 TRACE("Boot path set to CD-ROM: %s\n", FrLdrBootPath);
1005 }
1006 else
1007 {
1008 ULONG BootPartition;
1009
1010 /* This is a hard disk */
1011 /* If boot handle is a logical partition, we need to determine which partition number */
1012 if (BootBlockIo->Media->LogicalPartition)
1013 {
1014 /* For logical partitions, we need to find the partition number.
1015 * This is tricky - we'll use partition 1 as default for now. */
1016 // TODO: Properly determine partition number from boot handle.
1017 BootPartition = FIRST_PARTITION;
1018 TRACE("Boot handle is logical partition, using partition %lu\n", BootPartition);
1019 }
1020 else
1021 {
1022 /* Boot handle is the root device itself */
1023 if (!UefiGetBootPartitionEntry(FrldrBootDrive, NULL, &BootPartition))
1024 {
1025 ERR("Failed to get boot partition entry\n");
1026 return FALSE;
1027 }
1028 }
1029
1031 "multi(0)disk(0)rdisk(%u)partition(%lu)",
1032 ArcDriveIndex, BootPartition);
1033 TRACE("Boot path set to hard disk: %s\n", FrLdrBootPath);
1034 }
1035
1036 return TRUE;
1037}
static BOOLEAN UefiGetBootPartitionEntry(_In_ UCHAR DriveNumber, _Out_opt_ PPARTITION_INFORMATION PartitionEntry, _Out_ PULONG BootPartition)
Definition: uefidisk.c:170
ULONG FrldrBootPartition
Definition: uefidisk.c:58

Referenced by UefiInitializeBootDevices().

◆ UefiSetupBlockDevices()

static VOID UefiSetupBlockDevices ( VOID  )
static

Definition at line 706 of file uefidisk.c.

707{
708 ULONG BlockDeviceIndex;
709 ULONG SystemHandleCount;
711 ULONG i;
712 UINTN HandleSize = 0;
713 EFI_BLOCK_IO* BlockIo;
714
715 PcBiosDiskCount = 0;
717
718 /* Step 1: Get the size needed for handles buffer - no matter how it fails we're good */
722 NULL,
723 &HandleSize,
724 NULL);
725
726 if (HandleSize == 0)
727 {
728 ERR("Failed to get handle buffer size: Status = 0x%lx\n", (ULONG)Status);
729 return;
730 }
731
732 SystemHandleCount = HandleSize / sizeof(EFI_HANDLE);
733 if (SystemHandleCount == 0)
734 {
735 ERR("No block devices found\n");
736 return;
737 }
738
739 /* Step 2: Allocate buffer for handles */
741 if (handles == NULL)
742 {
743 ERR("Failed to allocate memory for handles\n");
744 return;
745 }
746
747 /* Step 3: Get actual handles */
751 NULL,
752 &HandleSize,
753 handles);
754
755 if (EFI_ERROR(Status))
756 {
757 ERR("Failed to locate block device handles: Status = 0x%lx\n", (ULONG)Status);
758 return;
759 }
760
761 HandleCount = SystemHandleCount;
762
763 /* Step 4: Allocate internal disk structure */
765 sizeof(INTERNAL_UEFI_DISK) * SystemHandleCount,
767
768 if (InternalUefiDisk == NULL)
769 {
770 ERR("Failed to allocate memory for internal disk structure\n");
771 return;
772 }
773
774 RtlZeroMemory(InternalUefiDisk, sizeof(INTERNAL_UEFI_DISK) * SystemHandleCount);
775
776 /* Step 5: Find boot handle and determine if it's a root device or partition */
778 for (i = 0; i < SystemHandleCount; i++)
779 {
780 if (handles[i] == PublicBootHandle)
781 {
783 TRACE("Found boot handle at index %lu\n", i);
784
785 /* Check if boot handle is a root device or partition */
787 handles[i],
789 (VOID**)&BlockIo);
790
791 if (!EFI_ERROR(Status) && BlockIo != NULL)
792 {
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);
797 }
798 break;
799 }
800 }
801
802 /* Step 6: Enumerate root block devices (skip logical partitions) */
803 BlockDeviceIndex = 0;
804 for (i = 0; i < SystemHandleCount; i++)
805 {
807 handles[i],
809 (VOID**)&BlockIo);
810
811 if (EFI_ERROR(Status))
812 {
813 TRACE("HandleProtocol failed for handle %lu: Status = 0x%lx\n", i, (ULONG)Status);
814 continue;
815 }
816
817 if (BlockIo == NULL)
818 {
819 TRACE("BlockIo is NULL for handle %lu\n", i);
820 continue;
821 }
822
823 if (!BlockIo->Media->MediaPresent)
824 {
825 TRACE("Media not present for handle %lu\n", i);
826 continue;
827 }
828
829 if (BlockIo->Media->BlockSize == 0)
830 {
831 TRACE("Invalid block size (0) for handle %lu\n", i);
832 continue;
833 }
834
835 /* Filter out devices with unusually large block sizes (flash devices) */
836 if (BlockIo->Media->BlockSize > MAX_SUPPORTED_BLOCK_SIZE)
837 {
838 TRACE("Block size too large (%lu) for handle %lu, skipping\n",
839 BlockIo->Media->BlockSize, i);
840 continue;
841 }
842
843 /* Logical partitions are handled separately by partition scanning */
844 if (BlockIo->Media->LogicalPartition)
845 {
846 /* If boot handle is a logical partition, we need to find its parent root device */
847 /* For now, we'll handle this after enumeration by matching handles */
848 TRACE("Skipping logical partition handle %lu\n", i);
849 continue;
850 }
851
852 /* This is a root block device */
853 TRACE("Found root block device at index %lu: BlockSize=%lu, LastBlock=%llu\n",
854 i, BlockIo->Media->BlockSize, BlockIo->Media->LastBlock);
855
856 InternalUefiDisk[BlockDeviceIndex].ArcDriveNumber = BlockDeviceIndex;
857 InternalUefiDisk[BlockDeviceIndex].UefiHandleIndex = i;
858 InternalUefiDisk[BlockDeviceIndex].Handle = handles[i];
859 InternalUefiDisk[BlockDeviceIndex].IsThisTheBootDrive = FALSE;
860
861 /* Check if this root device contains the boot partition */
862 /* If boot handle is a logical partition, we need to find which root device it belongs to */
863 /* For now, if boot handle index matches, mark it as boot device */
864 if (i == UefiBootRootIndex)
865 {
866 InternalUefiDisk[BlockDeviceIndex].IsThisTheBootDrive = TRUE;
867 PublicBootArcDisk = BlockDeviceIndex;
868 TRACE("Boot device is at ARC drive index %lu (root device)\n", BlockDeviceIndex);
869 }
870
871 /* Increment PcBiosDiskCount BEFORE calling GetHarddiskInformation
872 * so that UefiDiskReadLogicalSectors can validate the drive number */
873 PcBiosDiskCount = BlockDeviceIndex + 1;
874
875 TRACE("Calling GetHarddiskInformation for drive %d (BlockDeviceIndex=%lu)\n",
876 BlockDeviceIndex + FIRST_BIOS_DISK, BlockDeviceIndex);
877 if (!UefiEnsureDiskReadBufferAligned(BlockIo->Media->IoAlign))
878 {
879 ERR("Failed to align disk read buffer for drive %d\n", BlockDeviceIndex + FIRST_BIOS_DISK);
880 return;
881 }
882
883 GetHarddiskInformation(BlockDeviceIndex + FIRST_BIOS_DISK);
884 BlockDeviceIndex++;
885 }
886
887 /* Step 7: If boot handle was a logical partition, find its parent root device */
889 {
893 (VOID**)&BlockIo);
894
895 if (!EFI_ERROR(Status) && BlockIo != NULL && BlockIo->Media->LogicalPartition)
896 {
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");
901
902 /* Find the root device that matches the boot partition's characteristics */
903 /* For CD-ROMs: match BlockSize=2048 and RemovableMedia=TRUE */
904 /* For hard disks: match BlockSize and find the root device before this partition */
905 BOOLEAN FoundBootDevice = FALSE;
906 for (i = 0; i < BlockDeviceIndex; i++)
907 {
908 EFI_BLOCK_IO* RootBlockIo;
912 (VOID**)&RootBlockIo);
913
914 if (EFI_ERROR(Status) || RootBlockIo == NULL)
915 continue;
916
917 /* For CD-ROM: match BlockSize=2048 and RemovableMedia */
918 if (BlockIo->Media->BlockSize == 2048 && BlockIo->Media->RemovableMedia)
919 {
920 if (RootBlockIo->Media->BlockSize == 2048 &&
921 RootBlockIo->Media->RemovableMedia &&
922 !RootBlockIo->Media->LogicalPartition)
923 {
926 FoundBootDevice = TRUE;
927 TRACE("Found CD-ROM boot device at ARC drive index %lu\n", i);
928 break;
929 }
930 }
931 /* For hard disk partitions: the root device should be before the partition handle */
932 else if (InternalUefiDisk[i].UefiHandleIndex < UefiBootRootIndex)
933 {
934 /* Check if this root device is likely the parent */
935 if (RootBlockIo->Media->BlockSize == BlockIo->Media->BlockSize &&
936 !RootBlockIo->Media->LogicalPartition)
937 {
938 /* This might be the parent, but we need to be more certain */
939 /* For now, use the last root device before the boot handle */
942 FoundBootDevice = TRUE;
943 TRACE("Found potential hard disk boot device at ARC drive index %lu\n", i);
944 }
945 }
946 }
947
948 if (!FoundBootDevice && PcBiosDiskCount > 0)
949 {
952 TRACE("Could not determine boot device, assuming first drive\n");
953 }
954 }
955 }
956
957 TRACE("Found %lu root block devices\n", PcBiosDiskCount);
958}
VOID * EFI_HANDLE
Definition: UefiBaseType.h:35
@ ByProtocol
Definition: UefiSpec.h:1428
EFI_LOCATE_HANDLE LocateHandle
Definition: UefiSpec.h:1835
BOOLEAN IsThisTheBootDrive
Definition: uefidisk.c:39
ULONG UefiHandleIndex
Definition: uefidisk.c:37
UCHAR ArcDriveNumber
Definition: uefidisk.c:38
EFI_HANDLE Handle
Definition: uefidisk.c:36
EFI_HANDLE PublicBootHandle
Definition: uefimem.c:37
#define MAX_SUPPORTED_BLOCK_SIZE
Definition: uefidisk.c:21
static VOID GetHarddiskInformation(_In_ UCHAR DriveNumber)
Definition: uefidisk.c:644

Referenced by UefiInitializeBootDevices().

Variable Documentation

◆ BlockIoGuid

◆ DiskReadBuffer

◆ DiskReadBufferAlignment

ULONG DiskReadBufferAlignment
static

Definition at line 52 of file uefidisk.c.

Referenced by UefiEnsureDiskReadBufferAligned(), and UefiInitializeBootDevices().

◆ DiskReadBufferFallbackPool

BOOLEAN DiskReadBufferFallbackPool = FALSE
static

Definition at line 54 of file uefidisk.c.

Referenced by UefiEnsureDiskReadBufferAligned().

◆ DiskReadBufferFromPool

BOOLEAN DiskReadBufferFromPool
static

Definition at line 53 of file uefidisk.c.

Referenced by UefiEnsureDiskReadBufferAligned(), and UefiInitializeBootDevices().

◆ DiskReadBufferRaw

PVOID DiskReadBufferRaw
static

Definition at line 51 of file uefidisk.c.

Referenced by UefiEnsureDiskReadBufferAligned(), and UefiInitializeBootDevices().

◆ DiskReadBufferSize

◆ FrldrBootDrive

◆ FrldrBootPartition

◆ GlobalImageHandle

EFI_HANDLE GlobalImageHandle
extern

Definition at line 15 of file uefildr.c.

◆ GlobalSystemTable

◆ HandleCount

◆ handles

◆ InternalUefiDisk

◆ PcBiosDiskCount

◆ PublicBootArcDisk

ULONG PublicBootArcDisk = 0
static

Definition at line 63 of file uefidisk.c.

Referenced by UefiInitializeBootDevices(), UefiSetBootpath(), and UefiSetupBlockDevices().

◆ PublicBootHandle

EFI_HANDLE PublicBootHandle
extern

Definition at line 37 of file uefimem.c.

Referenced by UefiMemGetMemoryMap(), and UefiSetupBlockDevices().

◆ UefiBootRootIndex

ULONG UefiBootRootIndex = 0
static

Definition at line 62 of file uefidisk.c.

Referenced by UefiGetBootPartitionEntry(), UefiSetBootpath(), and UefiSetupBlockDevices().

◆ UefiDiskVtbl

const DEVVTBL UefiDiskVtbl
static
Initial value:
=
{
}
static ARC_STATUS UefiDiskGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: uefidisk.c:397
static ARC_STATUS UefiDiskOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: uefidisk.c:419
static ARC_STATUS UefiDiskSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: uefidisk.c:603
static ARC_STATUS UefiDiskClose(ULONG FileId)
Definition: uefidisk.c:388
static ARC_STATUS UefiDiskRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: uefidisk.c:508

Definition at line 634 of file uefidisk.c.

Referenced by GetHarddiskInformation(), and UefiInitializeBootDevices().