ReactOS 0.4.17-dev-684-ga6524ef
uefidisk.c
Go to the documentation of this file.
1/*
2 * PROJECT: FreeLoader UEFI Support
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Disk Access Functions
5 * COPYRIGHT: Copyright 2022-2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8/* INCLUDES ******************************************************************/
9
10#include <uefildr.h>
11
12#include <debug.h>
14
15#define TAG_HW_RESOURCE_LIST 'lRwH'
16#define TAG_HW_DISK_CONTEXT 'cDwH'
17#define FIRST_BIOS_DISK 0x80
18#define FIRST_PARTITION 1
19
20/* Maximum block size we support (8KB) - filters out flash devices */
21#define MAX_SUPPORTED_BLOCK_SIZE 8192
22
23#include "disk/part_gpt.h"
24
25typedef struct tagDISKCONTEXT
26{
33
34typedef struct _INTERNAL_UEFI_DISK
35{
42
43/* GLOBALS *******************************************************************/
44
47extern EFI_HANDLE PublicBootHandle; /* Freeldr itself */
48
49/* Made to match BIOS */
56
60
61/* UEFI-specific */
67static ULONG HandleCount = 0;
68
69/* FUNCTIONS *****************************************************************/
70
71/* For disk.c!DiskError() */
75{
76 return NULL;
77}
78
79static
82 IN PVOID Pointer,
84{
86
87 if (Alignment <= 1)
88 return TRUE;
89
90 Value = (ULONG_PTR)Pointer;
91 return ((Value & (Alignment - 1)) == 0);
92}
93
94static
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}
159
160/* GPT Support Functions *****************************************************/
161
162// Defined in part_gpt.c
163extern BOOLEAN
165 _In_ UCHAR DriveNumber,
166 _Out_ PGPT_TABLE_HEADER GptHeader);
167
168static
171 _In_ UCHAR DriveNumber,
172 _Out_opt_ PPARTITION_INFORMATION PartitionEntry,
173 _Out_ PULONG BootPartition)
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}
385
386static
389{
392 return ESUCCESS;
393}
394
395static
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}
416
417static
419UefiDiskOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
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}
505
506static
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
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}
600
601static
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}
633
634static const DEVVTBL UefiDiskVtbl =
635{
641};
642
643static VOID
645 _In_ UCHAR DriveNumber)
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}
703
704static
705VOID
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}
959
960static
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}
1065
1066BOOLEAN
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}
1134
1135UCHAR
1137{
1138 /* No floppy support in UEFI */
1139 return 0;
1140}
1141
1142BOOLEAN
1144 IN UCHAR DriveNumber,
1145 IN ULONGLONG SectorNumber,
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}
1276
1277BOOLEAN
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}
1326
1327ULONG
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 N
Definition: crc32.c:57
#define BLOCK_IO_PROTOCOL
Definition: BlockIo.h:31
#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
UINT32 UINTN
PRTL_UNICODE_STRING_BUFFER Path
#define EFI_PAGE_SIZE
Definition: UefiBaseType.h:189
#define EFI_ERROR(A)
Definition: UefiBaseType.h:165
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:31
VOID * EFI_HANDLE
Definition: UefiBaseType.h:35
@ EfiLoaderData
@ ByProtocol
Definition: UefiSpec.h:1428
unsigned char BOOLEAN
Definition: actypes.h:127
@ Identifier
Definition: asmpp.cpp:95
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
BOOLEAN DissectArcPath(IN PCSTR ArcPath, OUT PCSTR *Path OPTIONAL, OUT PUCHAR DriveNumber, OUT PULONG PartitionNumber)
Definition: arcname.c:25
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
BOOLEAN DiskGetPartitionEntry(_In_ UCHAR DriveNumber, _In_opt_ ULONG SectorSize, _In_ ULONG PartitionNumber, _Out_ PPARTITION_INFORMATION PartitionEntry)
Definition: partition.c:178
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
PVOID FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:711
VOID FsSetDeviceSpecific(ULONG FileId, PVOID Specific)
Definition: fs.c:704
#define MachDiskGetDriveGeometry(Drive, Geom)
Definition: machine.h:122
VOID MmFreeMemory(PVOID MemoryPointer)
Definition: mm.c:215
VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: heap.c:553
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: heap.c:545
#define SectorOffset(L)
Definition: cdprocs.h:1622
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
union node Node
Definition: types.h:1255
#define ENXIO
Definition: errno.h:29
#define EINVAL
Definition: errno.h:44
#define ENOMEM
Definition: errno.h:35
#define EIO
Definition: errno.h:28
static const WCHAR Signature[]
Definition: parser.c:141
return ret
Definition: mutex.c:147
#define ULONG_PTR
Definition: config.h:101
CCHAR FrLdrBootPath[MAX_PATH]
Definition: freeldr.c:29
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:24
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 RtlEqualMemory(dst, src, len)
Definition: kdvm.h:18
#define ASSERT(a)
Definition: mode.c:44
#define ULL(a, b)
Definition: format_msg.c:27
#define min(a, b)
Definition: monoChain.cc:55
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
_In_ PIOMMU_DEVICE_PATH DevicePath
Definition: haltypes.h:1823
#define _Out_opt_
Definition: no_sal2.h:214
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
int Count
Definition: noreturn.cpp:7
#define ANSI_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
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
ULONG SectorCount
Definition: part_brfr.c:22
#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
char CHAR
Definition: pedump.c:57
static char Hex[]
Definition: pnpdump.c:50
@ ESUCCESS
Definition: arc.h:32
@ LoaderFirmwareTemporary
Definition: arc.h:298
ULONG ARC_STATUS
Definition: arc.h:4
@ DiskPeripheral
Definition: arc.h:138
@ CdromController
Definition: arc.h:128
@ SeekRelative
Definition: arc.h:60
@ SeekAbsolute
Definition: arc.h:59
enum _OPENMODE OPENMODE
enum _SEEKMODE SEEKMODE
#define TRACE(s)
Definition: solgame.cpp:4
_In_ PVOID Context
Definition: storport.h:2269
BOOLEAN RemovableMedia
Definition: BlockIo.h:143
BOOLEAN LogicalPartition
Definition: BlockIo.h:156
UINT32 BlockSize
Definition: BlockIo.h:173
EFI_LBA LastBlock
Definition: BlockIo.h:184
BOOLEAN MediaPresent
Definition: BlockIo.h:150
EFI_FREE_POOL FreePool
Definition: UefiSpec.h:1814
EFI_LOCATE_HANDLE LocateHandle
Definition: UefiSpec.h:1835
EFI_HANDLE_PROTOCOL HandleProtocol
Definition: UefiSpec.h:1832
EFI_ALLOCATE_POOL AllocatePool
Definition: UefiSpec.h:1813
EFI_BOOT_SERVICES * BootServices
Definition: UefiSpec.h:1959
EFI_BLOCK_IO_MEDIA * Media
Definition: BlockIo.h:230
EFI_BLOCK_READ ReadBlocks
Definition: BlockIo.h:233
Definition: disk.h:24
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
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 IsThisTheBootDrive
Definition: uefidisk.c:39
ULONG UefiHandleIndex
Definition: uefidisk.c:37
CHAR DiskIdentifier[20]
Definition: uefidisk.c:40
UCHAR ArcDriveNumber
Definition: uefidisk.c:38
EFI_HANDLE Handle
Definition: uefidisk.c:36
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:408
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:409
Definition: fs.h:25
ULONGLONG SectorOffset
Definition: hwdisk.c:38
UCHAR DriveNumber
Definition: hwdisk.c:35
ULONGLONG SectorCount
Definition: hwdisk.c:39
ULONGLONG SectorNumber
Definition: hwdisk.c:40
ULONG SectorSize
Definition: hwdisk.c:37
static COORD Position
Definition: mouse.c:34
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char UCHAR
Definition: typedefs.h:53
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint64_t ULONGLONG
Definition: typedefs.h:67
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
static ULONG PublicBootArcDisk
Definition: uefidisk.c:63
PCSTR DiskGetErrorCodeString(_In_ ULONG ErrorCode)
Definition: uefidisk.c:73
BOOLEAN UefiDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
Definition: uefidisk.c:1278
#define TAG_HW_DISK_CONTEXT
Definition: uefidisk.c:16
BOOLEAN DiskReadGptHeader(_In_ UCHAR DriveNumber, _Out_ PGPT_TABLE_HEADER GptHeader)
Definition: part_gpt.c:22
PVOID DiskReadBuffer
Definition: uefidisk.c:50
BOOLEAN UefiDiskReadLogicalSectors(IN UCHAR DriveNumber, IN ULONGLONG SectorNumber, IN ULONG SectorCount, OUT PVOID Buffer)
Definition: uefidisk.c:1143
struct tagDISKCONTEXT DISKCONTEXT
static BOOLEAN DiskReadBufferFromPool
Definition: uefidisk.c:53
static EFI_GUID BlockIoGuid
Definition: uefidisk.c:65
BOOLEAN UefiInitializeBootDevices(VOID)
Definition: uefidisk.c:1067
static ARC_STATUS UefiDiskGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: uefidisk.c:397
static BOOLEAN DiskReadBufferFallbackPool
Definition: uefidisk.c:54
EFI_HANDLE PublicBootHandle
Definition: uefimem.c:37
static ULONG DiskReadBufferAlignment
Definition: uefidisk.c:52
EFI_SYSTEM_TABLE * GlobalSystemTable
Definition: uefildr.c:16
static BOOLEAN UefiGetBootPartitionEntry(_In_ UCHAR DriveNumber, _Out_opt_ PPARTITION_INFORMATION PartitionEntry, _Out_ PULONG BootPartition)
Definition: uefidisk.c:170
static const DEVVTBL UefiDiskVtbl
Definition: uefidisk.c:634
static BOOLEAN UefiEnsureDiskReadBufferAligned(IN ULONG Alignment)
Definition: uefidisk.c:96
static VOID UefiSetupBlockDevices(VOID)
Definition: uefidisk.c:706
static ULONG UefiBootRootIndex
Definition: uefidisk.c:62
static PVOID DiskReadBufferRaw
Definition: uefidisk.c:51
#define FIRST_BIOS_DISK
Definition: uefidisk.c:17
#define MAX_SUPPORTED_BLOCK_SIZE
Definition: uefidisk.c:21
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 VOID GetHarddiskInformation(_In_ UCHAR DriveNumber)
Definition: uefidisk.c:644
static INTERNAL_UEFI_DISK * InternalUefiDisk
Definition: uefidisk.c:64
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
static ULONG HandleCount
Definition: uefidisk.c:67
EFI_HANDLE GlobalImageHandle
Definition: uefildr.c:15
struct _INTERNAL_UEFI_DISK INTERNAL_UEFI_DISK
static UCHAR PcBiosDiskCount
Definition: uefidisk.c:55
static EFI_HANDLE * handles
Definition: uefidisk.c:66
UCHAR UefiGetFloppyCount(VOID)
Definition: uefidisk.c:1136
SIZE_T DiskReadBufferSize
Definition: uefidisk.c:59
static BOOLEAN UefiIsAlignedPointer(IN PVOID Pointer, IN ULONG Alignment)
Definition: uefidisk.c:81
ULONG UefiDiskGetCacheableBlockCount(UCHAR DriveNumber)
Definition: uefidisk.c:1328
UCHAR FrldrBootDrive
Definition: uefidisk.c:57
static BOOLEAN UefiSetBootpath(VOID)
Definition: uefidisk.c:962
ULONG FrldrBootPartition
Definition: uefidisk.c:58
struct _INTERNAL_UEFI_DISK * PINTERNAL_UEFI_DISK
#define FIRST_PARTITION
Definition: uefidisk.c:18
#define ALIGN_UP_POINTER_BY(ptr, align)
Definition: umtypes.h:85
LONGLONG QuadPart
Definition: typedefs.h:114
Definition: dlist.c:348
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
_In_ ULONG SectorSize
Definition: halfuncs.h:291