ReactOS 0.4.17-dev-683-g0dafdc5
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:24
#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 1328 of file uefidisk.c.

1329{
1330 ULONG ArcDriveIndex;
1331 EFI_BLOCK_IO* BlockIo;
1333
1334 if (DriveNumber < FIRST_BIOS_DISK)
1335 return 0;
1336
1337 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
1338
1339 if (InternalUefiDisk == NULL)
1340 {
1341 ERR("InternalUefiDisk not initialized\n");
1342 return 0;
1343 }
1344
1345 if (ArcDriveIndex >= 32 || InternalUefiDisk[ArcDriveIndex].Handle == NULL)
1346 {
1347 ERR("Invalid drive number: %d\n", DriveNumber);
1348 return 0;
1349 }
1350
1352 InternalUefiDisk[ArcDriveIndex].Handle,
1353 &BlockIoGuid,
1354 (VOID**)&BlockIo);
1355
1356 if (EFI_ERROR(Status) || BlockIo == NULL)
1357 {
1358 ERR("Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1359 return 0;
1360 }
1361
1362 if (!BlockIo->Media->MediaPresent)
1363 {
1364 ERR("Media not present for drive %d\n", DriveNumber);
1365 return 0;
1366 }
1367
1368 return (ULONG)(BlockIo->Media->LastBlock + 1);
1369}
#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 1278 of file uefidisk.c.

1279{
1280 ULONG ArcDriveIndex;
1281 EFI_BLOCK_IO* BlockIo;
1283
1284 if (DriveNumber < FIRST_BIOS_DISK)
1285 return FALSE;
1286
1287 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
1288
1289 if (InternalUefiDisk == NULL)
1290 {
1291 ERR("InternalUefiDisk not initialized\n");
1292 return FALSE;
1293 }
1294
1295 if (ArcDriveIndex >= 32 || InternalUefiDisk[ArcDriveIndex].Handle == NULL)
1296 {
1297 ERR("Invalid drive number: %d\n", DriveNumber);
1298 return FALSE;
1299 }
1300
1302 InternalUefiDisk[ArcDriveIndex].Handle,
1303 &BlockIoGuid,
1304 (VOID**)&BlockIo);
1305
1306 if (EFI_ERROR(Status) || BlockIo == NULL)
1307 {
1308 ERR("Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1309 return FALSE;
1310 }
1311
1312 if (!BlockIo->Media->MediaPresent)
1313 {
1314 ERR("Media not present for drive %d\n", DriveNumber);
1315 return FALSE;
1316 }
1317
1318 Geometry->Cylinders = 1; /* Not relevant for UEFI Block I/O protocol */
1319 Geometry->Heads = 1; /* Not relevant for UEFI Block I/O protocol */
1320 Geometry->SectorsPerTrack = (ULONG)(BlockIo->Media->LastBlock + 1);
1321 Geometry->BytesPerSector = BlockIo->Media->BlockSize;
1322 Geometry->Sectors = BlockIo->Media->LastBlock + 1;
1323
1324 return TRUE;
1325}
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:147
#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 1143 of file uefidisk.c.

1148{
1149 ULONG ArcDriveIndex;
1150 EFI_BLOCK_IO* BlockIo;
1152 ULONG BlockSize;
1153 ULONG IoAlign;
1154
1155 if (DriveNumber < FIRST_BIOS_DISK)
1156 return FALSE;
1157
1158 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
1159
1160 if (InternalUefiDisk == NULL)
1161 {
1162 ERR("InternalUefiDisk not initialized\n");
1163 return FALSE;
1164 }
1165
1166 if (ArcDriveIndex >= 32)
1167 {
1168 ERR("Drive index out of bounds: %d (ArcDriveIndex=%lu)\n", DriveNumber, ArcDriveIndex);
1169 return FALSE;
1170 }
1171
1172 /* Allow access during initialization: check if handle is set up.
1173 * During initialization, Handle is set before GetHarddiskInformation is called. */
1174 if (InternalUefiDisk[ArcDriveIndex].Handle == NULL)
1175 {
1176 ERR("Invalid drive number: %d (ArcDriveIndex=%lu, PcBiosDiskCount=%lu, Handle=NULL)\n",
1177 DriveNumber, ArcDriveIndex, PcBiosDiskCount);
1178 return FALSE;
1179 }
1180
1182 InternalUefiDisk[ArcDriveIndex].Handle,
1183 &BlockIoGuid,
1184 (VOID**)&BlockIo);
1185
1186 if (EFI_ERROR(Status) || BlockIo == NULL)
1187 {
1188 ERR("Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1189 return FALSE;
1190 }
1191
1192 if (!BlockIo->Media->MediaPresent)
1193 {
1194 ERR("Media not present for drive %d\n", DriveNumber);
1195 return FALSE;
1196 }
1197
1198 BlockSize = BlockIo->Media->BlockSize;
1199 IoAlign = BlockIo->Media->IoAlign;
1200
1201 if (!UefiEnsureDiskReadBufferAligned(IoAlign))
1202 {
1203 ERR("Failed to align disk read buffer for drive %d\n", DriveNumber);
1204 return FALSE;
1205 }
1206
1207 if (!UefiIsAlignedPointer(Buffer, (IoAlign == 0) ? 1 : IoAlign))
1208 {
1209 ULONG TotalSectors = SectorCount;
1210 ULONG MaxSectors = DiskReadBufferSize / BlockSize;
1211 ULONGLONG CurrentSector = SectorNumber;
1212 PUCHAR OutPtr = (PUCHAR)Buffer;
1213
1214 if (MaxSectors == 0)
1215 {
1216 ERR("DiskReadBufferSize too small for block size %lu\n", BlockSize);
1217 return FALSE;
1218 }
1219
1220 while (TotalSectors)
1221 {
1222 ULONG ReadSectors = min(TotalSectors, MaxSectors);
1223 UINTN ReadSize = ReadSectors * BlockSize;
1224
1225 Status = BlockIo->ReadBlocks(
1226 BlockIo,
1227 BlockIo->Media->MediaId,
1228 CurrentSector,
1229 ReadSize,
1231
1232 if (EFI_ERROR(Status))
1233 {
1234 ERR("ReadBlocks failed: DriveNumber=%d, SectorNumber=%llu, SectorCount=%lu, Status=0x%lx\n",
1235 DriveNumber, CurrentSector, ReadSectors, (ULONG)Status);
1236 ERR("ReadBlocks details: BlockSize=%lu, IoAlign=%lu, Buffer=%p, DiskReadBuffer=%p, MediaId=0x%lx\n",
1237 BlockSize, IoAlign, Buffer, DiskReadBuffer, (ULONG)BlockIo->Media->MediaId);
1238 ERR("ReadBlocks media: LastBlock=%llu, LogicalPartition=%s, RemovableMedia=%s\n",
1239 BlockIo->Media->LastBlock,
1240 BlockIo->Media->LogicalPartition ? "TRUE" : "FALSE",
1241 BlockIo->Media->RemovableMedia ? "TRUE" : "FALSE");
1242 return FALSE;
1243 }
1244
1245 RtlCopyMemory(OutPtr, DiskReadBuffer, ReadSize);
1246 OutPtr += ReadSize;
1247 CurrentSector += ReadSectors;
1248 TotalSectors -= ReadSectors;
1249 }
1250
1251 return TRUE;
1252 }
1253
1254 Status = BlockIo->ReadBlocks(
1255 BlockIo,
1256 BlockIo->Media->MediaId,
1257 SectorNumber,
1258 SectorCount * BlockSize,
1259 Buffer);
1260
1261 if (EFI_ERROR(Status))
1262 {
1263 ERR("ReadBlocks failed: DriveNumber=%d, SectorNumber=%llu, SectorCount=%lu, Status=0x%lx\n",
1264 DriveNumber, SectorNumber, SectorCount, (ULONG)Status);
1265 ERR("ReadBlocks details: BlockSize=%lu, IoAlign=%lu, Buffer=%p, DiskReadBuffer=%p, MediaId=0x%lx\n",
1266 BlockSize, IoAlign, Buffer, DiskReadBuffer, (ULONG)BlockIo->Media->MediaId);
1267 ERR("ReadBlocks media: LastBlock=%llu, LogicalPartition=%s, RemovableMedia=%s\n",
1268 BlockIo->Media->LastBlock,
1269 BlockIo->Media->LogicalPartition ? "TRUE" : "FALSE",
1270 BlockIo->Media->RemovableMedia ? "TRUE" : "FALSE");
1271 return FALSE;
1272 }
1273
1274 return TRUE;
1275}
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 1136 of file uefidisk.c.

1137{
1138 /* No floppy support in UEFI */
1139 return 0;
1140}

Referenced by MachInit().

◆ UefiInitializeBootDevices()

BOOLEAN UefiInitializeBootDevices ( VOID  )

Definition at line 1067 of file uefidisk.c.

1068{
1069 EFI_BLOCK_IO* BlockIo;
1071 ULONG ArcDriveIndex;
1072
1079 {
1080 ERR("Failed to allocate disk read buffer\n");
1081 return FALSE;
1082 }
1083
1085
1086 if (PcBiosDiskCount == 0)
1087 {
1088 ERR("No block devices found\n");
1089 return FALSE;
1090 }
1091
1092 if (!UefiSetBootpath())
1093 {
1094 ERR("Failed to set boot path\n");
1095 return FALSE;
1096 }
1097
1098 /* Handle CD-ROM boot device registration */
1099 ArcDriveIndex = PublicBootArcDisk;
1100 if (ArcDriveIndex >= PcBiosDiskCount || InternalUefiDisk == NULL)
1101 {
1102 ERR("Invalid boot arc disk index\n");
1103 return FALSE;
1104 }
1105
1107 InternalUefiDisk[ArcDriveIndex].Handle,
1108 &BlockIoGuid,
1109 (VOID**)&BlockIo);
1110
1111 if (EFI_ERROR(Status) || BlockIo == NULL)
1112 {
1113 ERR("Failed to get Block I/O protocol\n");
1114 return FALSE;
1115 }
1116
1117 if (BlockIo->Media->RemovableMedia == TRUE && BlockIo->Media->BlockSize == 2048)
1118 {
1120
1125
1126 if (Status == ESUCCESS)
1127 TRACE("Registered CD-ROM boot device: 0x%02X\n", FrldrBootDrive);
1128 else
1129 ERR("CD-ROM boot device 0x%02X failed\n", FrldrBootDrive);
1130 }
1131
1132 return TRUE;
1133}
#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 EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
1017 HARDDRIVE_DEVICE_PATH *HdNode;
1018
1019 BootPartition = FIRST_PARTITION; /* Fallback if the walk below fails */
1020
1023 &DevicePathGuid,
1024 (VOID**)&DevicePath);
1025
1026 if (!EFI_ERROR(Status) && (DevicePath != NULL))
1027 {
1028 /* Walk the device path looking for the Hard Drive node */
1030 {
1032 break; /* Malformed path */
1033
1036 {
1037 HdNode = (HARDDRIVE_DEVICE_PATH*)Node;
1038 BootPartition = HdNode->PartitionNumber;
1039 TRACE("Found partition number %lu from device path\n", BootPartition);
1040 break;
1041 }
1042 }
1043 }
1044
1045 TRACE("Boot handle is a logical partition, using partition %lu\n", BootPartition);
1046 }
1047 else
1048 {
1049 /* Boot handle is the root device itself */
1050 if (!UefiGetBootPartitionEntry(FrldrBootDrive, NULL, &BootPartition))
1051 {
1052 ERR("Failed to get boot partition entry\n");
1053 return FALSE;
1054 }
1055 }
1056
1058 "multi(0)disk(0)rdisk(%u)partition(%lu)",
1059 ArcDriveIndex, BootPartition);
1060 TRACE("Boot path set to hard disk: %s\n", FrLdrBootPath);
1061 }
1062
1063 return TRUE;
1064}
#define MEDIA_DEVICE_PATH
Definition: DevicePath.h:842
FORCEINLINE EFI_DEVICE_PATH_PROTOCOL * NextDevicePathNode(_In_ PVOID Node)
Definition: DevicePath.h:1189
FORCEINLINE BOOLEAN IsDevicePathEnd(_In_ PVOID Node)
Definition: DevicePath.h:1209
FORCEINLINE UINT8 DevicePathSubType(_In_ PVOID Node)
Definition: DevicePath.h:1169
#define MEDIA_HARDDRIVE_DP
Definition: DevicePath.h:847
#define EFI_DEVICE_PATH_PROTOCOL_GUID
Definition: DevicePath.h:27
FORCEINLINE UINT8 DevicePathType(_In_ PVOID Node)
Definition: DevicePath.h:1159
FORCEINLINE UINTN DevicePathNodeLength(_In_ PVOID Node)
Definition: DevicePath.h:1179
union node Node
Definition: types.h:1255
_In_ PIOMMU_DEVICE_PATH DevicePath
Definition: haltypes.h:1823
static BOOLEAN UefiGetBootPartitionEntry(_In_ UCHAR DriveNumber, _Out_opt_ PPARTITION_INFORMATION PartitionEntry, _Out_ PULONG BootPartition)
Definition: uefidisk.c:170
ULONG FrldrBootPartition
Definition: uefidisk.c:58
Definition: dlist.c:348

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().