ReactOS 0.4.16-dev-2613-g9533ad7
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
61
62/* UEFI-specific */
68static ULONG HandleCount = 0;
69
70/* FUNCTIONS *****************************************************************/
71
72/* For disk.c!DiskError() */
76{
77 return NULL;
78}
79
80static
83 IN PVOID Pointer,
85{
87
88 if (Alignment <= 1)
89 return TRUE;
90
91 Value = (ULONG_PTR)Pointer;
92 return ((Value & (Alignment - 1)) == 0);
93}
94
95static
99{
100 ULONG RequiredAlignment = (Alignment == 0) ? 1 : Alignment;
102
103 if (DiskReadBuffer != NULL && DiskReadBufferAlignment >= RequiredAlignment &&
104 UefiIsAlignedPointer(DiskReadBuffer, RequiredAlignment))
105 {
106 return TRUE;
107 }
108
109 DiskReadBufferAlignment = RequiredAlignment;
110
112 {
114 {
116 }
117 else
118 {
120 }
121
126 }
127
129 DiskReadBufferSize + RequiredAlignment,
130 (void**)&DiskReadBufferRaw);
132 {
133 /* This can sometimes happen on Mac firmware and probably happens on other EFI 1.x devices as well. */
134 WARN("Failed to allocate aligned disk read buffer using AllocatePool, trying MmAllocateMemoryWithType (buffer size = 0x%X, alignment %lu)\n",
135 DiskReadBufferSize, RequiredAlignment);
138 if (DiskReadBufferRaw == NULL)
139 {
140 /* That failed too */
141 ERR("Failed to allocate aligned disk read buffer (buffer size = 0x%X, alignment %lu)\n",
142 DiskReadBufferSize, RequiredAlignment);
143 return FALSE;
144 }
145
147 }
148
150
152 if (!UefiIsAlignedPointer(DiskReadBuffer, RequiredAlignment))
153 {
154 ERR("Aligned disk read buffer is not properly aligned (align %lu)\n", RequiredAlignment);
155 return FALSE;
156 }
157
158 return TRUE;
159}
160
161/* GPT Support Functions *****************************************************/
162
163// Defined in part_gpt.c
164extern BOOLEAN
166 _In_ UCHAR DriveNumber,
167 _Out_ PGPT_TABLE_HEADER GptHeader);
168
169static
172 _In_ UCHAR DriveNumber,
173 _Out_opt_ PPARTITION_INFORMATION PartitionEntry,
174 _Out_ PULONG BootPartition)
175{
176 ULONG PartitionNum;
177 ULONG ArcDriveIndex;
178 EFI_BLOCK_IO* BootBlockIo;
180 ULONG BlockSize;
181 ULONGLONG BootPartitionSize;
182 PARTITION_INFORMATION TempPartitionEntry;
183
184 TRACE("UefiGetBootPartitionEntry: DriveNumber: %d\n", DriveNumber - FIRST_BIOS_DISK);
185
186 if (DriveNumber < FIRST_BIOS_DISK)
187 return FALSE;
188
189 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
190 if (ArcDriveIndex >= PcBiosDiskCount || handles == NULL || UefiBootRootIndex >= HandleCount)
191 return FALSE;
192
193 /* Get the boot handle's Block I/O protocol to determine partition offset/size */
197 (VOID**)&BootBlockIo);
198
199 if (EFI_ERROR(Status) || BootBlockIo == NULL)
200 {
201 ERR("Failed to get Block I/O protocol for boot handle\n");
202 return FALSE;
203 }
204
205 /* For logical partitions, UEFI Block I/O protocol starts at block 0.
206 * We need to find which partition it corresponds to by comparing sizes. */
207 BootPartitionSize = BootBlockIo->Media->LastBlock + 1;
208
209 TRACE("Boot partition: Size=%llu blocks, BlockSize=%lu\n",
210 BootPartitionSize, BootBlockIo->Media->BlockSize);
211
212 /* If boot handle is the root device itself (not a logical partition) */
213 if (!BootBlockIo->Media->LogicalPartition)
214 {
215 TRACE("Boot handle is root device, using partition 0\n");
216 *BootPartition = 0;
217 if (PartitionEntry)
218 {
219 // RtlZeroMemory(PartitionEntry, sizeof(*PartitionEntry));
220 /* Represent the whole disk */
221 PartitionEntry->StartingOffset.QuadPart = 0ULL;
222 PartitionEntry->PartitionLength.QuadPart = (BootPartitionSize * BootBlockIo->Media->BlockSize);
223 PartitionEntry->HiddenSectors = 0;
224 PartitionEntry->PartitionNumber = *BootPartition;
225 PartitionEntry->PartitionType = PARTITION_GPT; /* Mark as GPT partition */
226 PartitionEntry->BootIndicator = TRUE;
227 PartitionEntry->RecognizedPartition = TRUE;
228 PartitionEntry->RewritePartition = FALSE;
229 }
230 return TRUE;
231 }
232
233 /* Boot handle is a logical partition - find matching partition entry.
234 * Try to detect GPT first by reading the GPT header. */
235 GPT_TABLE_HEADER GptHeader;
236 BOOLEAN IsGpt = DiskReadGptHeader(DriveNumber, &GptHeader);
237 if (IsGpt)
238 {
239 /* For GPT, iterate through GPT partition entries */
240 GPT_PARTITION_ENTRY GptEntry;
241 EFI_BLOCK_IO* RootBlockIo;
242 ULONG EntriesPerBlock;
246
248 InternalUefiDisk[ArcDriveIndex].Handle,
250 (VOID**)&RootBlockIo);
251
252 if (EFI_ERROR(Status) || RootBlockIo == NULL)
253 return FALSE;
254
255 BlockSize = RootBlockIo->Media->BlockSize;
256 EntriesPerBlock = BlockSize / GptHeader.SizeOfPartitionEntry;
257
258 /* Iterate through GPT partition entries */
259 for (ULONG i = 0; i < GptHeader.NumberOfPartitionEntries; i++)
260 {
261 ULONGLONG EntryLba = GptHeader.PartitionEntryLba + (i / EntriesPerBlock);
262 ULONG EntryOffset = (i % EntriesPerBlock) * GptHeader.SizeOfPartitionEntry;
263
264 /* Read the block containing the partition entry */
265 Status = RootBlockIo->ReadBlocks(
266 RootBlockIo,
267 RootBlockIo->Media->MediaId,
268 EntryLba,
269 BlockSize,
271
272 if (EFI_ERROR(Status))
273 continue;
274
275 /* Extract partition entry */
276 RtlCopyMemory(&GptEntry, (PUCHAR)DiskReadBuffer + EntryOffset, sizeof(GptEntry));
277
278 /* Skip unused partitions */
279 if (RtlEqualMemory(&GptEntry.PartitionTypeGuid, &UnusedGuid, sizeof(UnusedGuid)))
280 continue;
281
282 /* Calculate partition size in blocks */
283 ULONGLONG PartitionSizeBlocks = GptEntry.EndingLba - GptEntry.StartingLba + 1;
284
285 TRACE("GPT Partition %lu: StartLba=%llu, EndLba=%llu, SizeBlocks=%llu\n",
286 i + 1, GptEntry.StartingLba, GptEntry.EndingLba, PartitionSizeBlocks);
287
288 /* Match partition by size (within 1 block tolerance for rounding) */
289 if (PartitionSizeBlocks == BootPartitionSize ||
290 (PartitionSizeBlocks > 0 &&
291 (PartitionSizeBlocks - 1 <= BootPartitionSize &&
292 BootPartitionSize <= PartitionSizeBlocks + 1)))
293 {
294 TRACE("Found matching GPT partition %lu: Size matches (%llu blocks)\n",
295 i + 1, BootPartitionSize);
296
297 *BootPartition = i + 1; /* GPT partitions are 1-indexed */
298
299 /* Convert GPT entry to standard-style entry */
300 if (PartitionEntry)
301 {
302 PartitionEntry->StartingOffset.QuadPart = (GptEntry.StartingLba * BlockSize);
303 PartitionEntry->PartitionLength.QuadPart = ((ULONGLONG)PartitionSizeBlocks * BlockSize);
304 PartitionEntry->HiddenSectors = 0;
305 PartitionEntry->PartitionNumber = *BootPartition;
306 PartitionEntry->PartitionType = PARTITION_GPT; /* Mark as GPT partition */
307 PartitionEntry->BootIndicator = RtlEqualMemory(&GptEntry.PartitionTypeGuid, &SystemGuid, sizeof(SystemGuid));
308 PartitionEntry->RecognizedPartition = TRUE;
309 PartitionEntry->RewritePartition = FALSE;
310 }
311 return TRUE;
312 }
313 }
314 }
315 else
316 {
317 /* MBR partition matching */
318
319 BlockSize = BootBlockIo->Media->BlockSize;
320
321 PartitionNum = FIRST_PARTITION;
322 while (DiskGetPartitionEntry(DriveNumber, BlockSize, PartitionNum, &TempPartitionEntry))
323 {
324 /* Convert partition size to UEFI blocks */
325 ULONGLONG PartitionSizeBlocks = TempPartitionEntry.PartitionLength.QuadPart / BlockSize;
326 ULONGLONG StartingLba = TempPartitionEntry.StartingOffset.QuadPart / BlockSize;
327 ULONGLONG EndingLba = StartingLba + PartitionSizeBlocks - 1;
328
329 TRACE("Partition %lu: StartLba=%llu, EndLba=%llu, SizeBlocks=%llu\n",
330 PartitionNum, StartingLba, EndingLba, PartitionSizeBlocks);
331
332 /* Match partition by size (within 1 block tolerance for rounding) */
333 if (PartitionSizeBlocks == BootPartitionSize ||
334 (PartitionSizeBlocks > 0 &&
335 (PartitionSizeBlocks - 1 <= BootPartitionSize &&
336 BootPartitionSize <= PartitionSizeBlocks + 1)))
337 {
338 TRACE("Found matching partition %lu: Size matches (%llu blocks)\n",
339 PartitionNum, BootPartitionSize);
340
341 *BootPartition = PartitionNum;
342 if (PartitionEntry)
343 RtlCopyMemory(PartitionEntry, &TempPartitionEntry, sizeof(*PartitionEntry));
344 return TRUE;
345 }
346
347 PartitionNum++;
348 }
349 }
350
351 /* If we couldn't find a match, check if it's a CD-ROM (special case) */
352 if (BootBlockIo->Media->RemovableMedia && BootBlockIo->Media->BlockSize == 2048)
353 {
354 TRACE("Boot device is CD-ROM, using partition 0xFF\n");
355 *BootPartition = 0xFF;
356 if (PartitionEntry)
357 {
358 // RtlZeroMemory(PartitionEntry, sizeof(*PartitionEntry));
359 /* Represent the whole disk */
360 PartitionEntry->StartingOffset.QuadPart = 0ULL;
361 PartitionEntry->PartitionLength.QuadPart = (BootPartitionSize * BootBlockIo->Media->BlockSize);
362 PartitionEntry->HiddenSectors = 0;
363 PartitionEntry->PartitionNumber = *BootPartition;
364 PartitionEntry->PartitionType = PARTITION_GPT; /* Mark as GPT partition */
365 PartitionEntry->BootIndicator = TRUE;
366 PartitionEntry->RecognizedPartition = TRUE;
367 PartitionEntry->RewritePartition = FALSE;
368 }
369 return TRUE;
370 }
371
372 /* Fallback: if we can't determine, use partition 1 */
373 ERR("Could not determine boot partition, using partition 1 as fallback\n");
374 PartitionNum = FIRST_PARTITION;
375 if (DiskGetPartitionEntry(DriveNumber, BootBlockIo->Media->BlockSize,
376 PartitionNum, &TempPartitionEntry))
377 {
378 *BootPartition = PartitionNum;
379 if (PartitionEntry)
380 RtlCopyMemory(PartitionEntry, &TempPartitionEntry, sizeof(*PartitionEntry));
381 return TRUE;
382 }
383
384 return FALSE;
385}
386
387static
390{
393 return ESUCCESS;
394}
395
396static
399{
402
403 /*
404 * The ARC specification mentions that for partitions, StartingAddress and
405 * EndingAddress are the start and end positions of the partition in terms
406 * of byte offsets from the start of the disk.
407 * CurrentAddress is the current offset into (i.e. relative to) the partition.
408 */
409 Information->StartingAddress.QuadPart = Context->SectorOffset * Context->SectorSize;
410 Information->EndingAddress.QuadPart = (Context->SectorOffset + Context->SectorCount) * Context->SectorSize;
411 Information->CurrentAddress.QuadPart = Context->SectorNumber * Context->SectorSize;
412
413 Information->Type = DiskPeripheral; /* No floppy for you for now... */
414
415 return ESUCCESS;
416}
417
418static
420UefiDiskOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
421{
423 UCHAR DriveNumber;
424 ULONG DrivePartition, SectorSize;
427 ULONG ArcDriveIndex;
428 EFI_BLOCK_IO* BlockIo;
430
431 TRACE("UefiDiskOpen: File ID: %p, Path: %s\n", FileId, Path);
432
433 if (DiskReadBufferSize == 0)
434 {
435 ERR("DiskOpen(): DiskReadBufferSize is 0, something is wrong.\n");
436 ASSERT(FALSE);
437 return ENOMEM;
438 }
439
440 if (!DissectArcPath(Path, NULL, &DriveNumber, &DrivePartition))
441 return EINVAL;
442
443 TRACE("Opening disk: DriveNumber: %d, DrivePartition: %d\n", DriveNumber, DrivePartition);
444
445 if (DriveNumber < FIRST_BIOS_DISK)
446 return EINVAL;
447
448 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
449 if (ArcDriveIndex >= PcBiosDiskCount || InternalUefiDisk == NULL)
450 return EINVAL;
451
452 /* Get Block I/O protocol for this drive */
454 InternalUefiDisk[ArcDriveIndex].Handle,
456 (VOID**)&BlockIo);
457
458 if (EFI_ERROR(Status) || BlockIo == NULL)
459 {
460 ERR("Failed to get Block I/O protocol for drive %d\n", DriveNumber);
461 return EINVAL;
462 }
463
464 /* Check media is present */
465 if (!BlockIo->Media->MediaPresent)
466 {
467 ERR("Media not present for drive %d\n", DriveNumber);
468 return ENXIO;
469 }
470
471#if 0
472 GEOMETRY Geometry;
473 if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
474 return EIO;
475#endif
476 SectorSize = BlockIo->Media->BlockSize;
477
478 if (DrivePartition != 0xff && DrivePartition != 0)
479 {
480 PARTITION_INFORMATION PartitionEntry;
481 if (!DiskGetPartitionEntry(DriveNumber, SectorSize, DrivePartition, &PartitionEntry))
482 return EIO;
483
486 }
487 else
488 {
489 SectorOffset = 0;
490 SectorCount = BlockIo->Media->LastBlock + 1; // Geometry.Sectors;
491 }
492
494 if (!Context)
495 return ENOMEM;
496
497 Context->DriveNumber = DriveNumber;
498 Context->SectorSize = SectorSize;
499 Context->SectorOffset = SectorOffset;
500 Context->SectorCount = SectorCount;
501 Context->SectorNumber = 0;
503
504 return ESUCCESS;
505}
506
507static
510{
512 UCHAR* Ptr = (UCHAR*)Buffer;
513 ULONG Length, TotalSectors, MaxSectors, ReadSectors;
515 BOOLEAN ret;
516 EFI_BLOCK_IO* BlockIo;
518 ULONG ArcDriveIndex;
519
521
522 TotalSectors = (N + Context->SectorSize - 1) / Context->SectorSize;
523 MaxSectors = DiskReadBufferSize / Context->SectorSize;
524 SectorOffset = Context->SectorOffset + Context->SectorNumber;
525
526 // If MaxSectors is 0, this will lead to infinite loop.
527 // In release builds assertions are disabled, however we also have sanity checks in DiskOpen()
528 ASSERT(MaxSectors > 0);
529
530 if (MaxSectors == 0)
531 {
532 ERR("MaxSectors is 0, cannot read\n");
533 *Count = 0;
534 return EIO;
535 }
536
537 ArcDriveIndex = Context->DriveNumber - FIRST_BIOS_DISK;
538 if (ArcDriveIndex >= PcBiosDiskCount || InternalUefiDisk == NULL)
539 {
540 ERR("Invalid drive number %d\n", Context->DriveNumber);
541 *Count = 0;
542 return EINVAL;
543 }
544
545 /* Get Block I/O protocol */
547 InternalUefiDisk[ArcDriveIndex].Handle,
549 (VOID**)&BlockIo);
550
551 if (EFI_ERROR(Status) || BlockIo == NULL)
552 {
553 ERR("Failed to get Block I/O protocol\n");
554 *Count = 0;
555 return EIO;
556 }
557
559 {
560 ERR("Failed to align disk read buffer\n");
561 *Count = 0;
562 return EIO;
563 }
564
565 ret = TRUE;
566
567 while (TotalSectors)
568 {
569 ReadSectors = min(TotalSectors, MaxSectors);
570
571 Status = BlockIo->ReadBlocks(
572 BlockIo,
573 BlockIo->Media->MediaId,
575 ReadSectors * Context->SectorSize,
577
578 if (EFI_ERROR(Status))
579 {
580 ERR("ReadBlocks failed: Status = 0x%lx\n", (ULONG)Status);
581 ret = FALSE;
582 break;
583 }
584
585 Length = ReadSectors * Context->SectorSize;
586 Length = min(Length, N);
587
589
590 Ptr += Length;
591 N -= Length;
592 SectorOffset += ReadSectors;
593 TotalSectors -= ReadSectors;
594 }
595
597 Context->SectorNumber = SectorOffset - Context->SectorOffset;
598
599 return (ret ? ESUCCESS : EIO);
600}
601
602static
605{
607 LARGE_INTEGER NewPosition = *Position;
608
609 switch (SeekMode)
610 {
611 case SeekAbsolute:
612 break;
613 case SeekRelative:
614 NewPosition.QuadPart += (Context->SectorNumber * Context->SectorSize);
615 break;
616 default:
617 ASSERT(FALSE);
618 return EINVAL;
619 }
620
621 if (NewPosition.QuadPart & (Context->SectorSize - 1))
622 return EINVAL;
623
624 /* Convert in number of sectors */
625 NewPosition.QuadPart /= Context->SectorSize;
626
627 /* HACK: CDROMs may have a SectorCount of 0 */
628 if (Context->SectorCount != 0 && NewPosition.QuadPart >= Context->SectorCount)
629 return EINVAL;
630
631 Context->SectorNumber = NewPosition.QuadPart;
632 return ESUCCESS;
633}
634
635static const DEVVTBL UefiDiskVtbl =
636{
642};
643
644static VOID
646 _In_ UCHAR DriveNumber)
647{
648 static const CHAR Hex[] = "0123456789abcdef";
649
651 ULONG Checksum, Signature;
652 BOOLEAN ValidPartitionTable;
653 ULONG ArcDriveIndex;
655 CHAR DiskName[64];
656
658
659 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
660 if (ArcDriveIndex >= 32)
661 return;
662
664
665 RtlStringCbPrintfA(DiskName, sizeof(DiskName),
666 "multi(0)disk(0)rdisk(%u)",
667 ArcDriveIndex);
668
670 Status = DiskInitialize(DriveNumber, DiskName, DiskPeripheral, &UefiDiskVtbl,
671 &Checksum, &Signature, &ValidPartitionTable);
673
674 if (Status != ESUCCESS)
675 {
676 /* The disk failed to be initialized, use a default identifier */
677 RtlStringCbPrintfA(Identifier, 20, "BIOSDISK%u", ArcDriveIndex + 1);
678 return;
679 }
680
681 /* Convert checksum and signature to identifier string */
682 Identifier[0] = Hex[(Checksum >> 28) & 0x0F];
683 Identifier[1] = Hex[(Checksum >> 24) & 0x0F];
684 Identifier[2] = Hex[(Checksum >> 20) & 0x0F];
685 Identifier[3] = Hex[(Checksum >> 16) & 0x0F];
686 Identifier[4] = Hex[(Checksum >> 12) & 0x0F];
687 Identifier[5] = Hex[(Checksum >> 8) & 0x0F];
688 Identifier[6] = Hex[(Checksum >> 4) & 0x0F];
689 Identifier[7] = Hex[Checksum & 0x0F];
690 Identifier[8] = '-';
691 Identifier[9] = Hex[(Signature >> 28) & 0x0F];
692 Identifier[10] = Hex[(Signature >> 24) & 0x0F];
693 Identifier[11] = Hex[(Signature >> 20) & 0x0F];
694 Identifier[12] = Hex[(Signature >> 16) & 0x0F];
695 Identifier[13] = Hex[(Signature >> 12) & 0x0F];
696 Identifier[14] = Hex[(Signature >> 8) & 0x0F];
697 Identifier[15] = Hex[(Signature >> 4) & 0x0F];
698 Identifier[16] = Hex[Signature & 0x0F];
699 Identifier[17] = '-';
700 Identifier[18] = (ValidPartitionTable ? 'A' : 'X');
701 Identifier[19] = ANSI_NULL;
702 TRACE("Identifier: %s\n", Identifier);
703}
704
705static
706VOID
708{
709 ULONG BlockDeviceIndex;
710 ULONG SystemHandleCount;
712 ULONG i;
713 UINTN HandleSize = 0;
714 EFI_BLOCK_IO* BlockIo;
715
716 PcBiosDiskCount = 0;
718
719 /* Step 1: Get the size needed for handles buffer - no matter how it fails we're good */
723 NULL,
724 &HandleSize,
725 NULL);
726
727 if (HandleSize == 0)
728 {
729 ERR("Failed to get handle buffer size: Status = 0x%lx\n", (ULONG)Status);
730 return;
731 }
732
733 SystemHandleCount = HandleSize / sizeof(EFI_HANDLE);
734 if (SystemHandleCount == 0)
735 {
736 ERR("No block devices found\n");
737 return;
738 }
739
740 /* Step 2: Allocate buffer for handles */
742 if (handles == NULL)
743 {
744 ERR("Failed to allocate memory for handles\n");
745 return;
746 }
747
748 /* Step 3: Get actual handles */
752 NULL,
753 &HandleSize,
754 handles);
755
756 if (EFI_ERROR(Status))
757 {
758 ERR("Failed to locate block device handles: Status = 0x%lx\n", (ULONG)Status);
759 return;
760 }
761
762 HandleCount = SystemHandleCount;
763
764 /* Step 4: Allocate internal disk structure */
766 sizeof(INTERNAL_UEFI_DISK) * SystemHandleCount,
768
769 if (InternalUefiDisk == NULL)
770 {
771 ERR("Failed to allocate memory for internal disk structure\n");
772 return;
773 }
774
775 RtlZeroMemory(InternalUefiDisk, sizeof(INTERNAL_UEFI_DISK) * SystemHandleCount);
776
777 /* Step 5: Find boot handle and determine if it's a root device or partition */
779 for (i = 0; i < SystemHandleCount; i++)
780 {
781 if (handles[i] == PublicBootHandle)
782 {
784 TRACE("Found boot handle at index %lu\n", i);
785
786 /* Check if boot handle is a root device or partition */
788 handles[i],
790 (VOID**)&BlockIo);
791
792 if (!EFI_ERROR(Status) && BlockIo != NULL)
793 {
794 TRACE("Boot handle: LogicalPartition=%s, RemovableMedia=%s, BlockSize=%lu\n",
795 BlockIo->Media->LogicalPartition ? "TRUE" : "FALSE",
796 BlockIo->Media->RemovableMedia ? "TRUE" : "FALSE",
797 BlockIo->Media->BlockSize);
798 }
799 break;
800 }
801 }
802
803 /* Step 6: Enumerate root block devices (skip logical partitions) */
804 BlockDeviceIndex = 0;
805 for (i = 0; i < SystemHandleCount; i++)
806 {
808 handles[i],
810 (VOID**)&BlockIo);
811
812 if (EFI_ERROR(Status))
813 {
814 TRACE("HandleProtocol failed for handle %lu: Status = 0x%lx\n", i, (ULONG)Status);
815 continue;
816 }
817
818 if (BlockIo == NULL)
819 {
820 TRACE("BlockIo is NULL for handle %lu\n", i);
821 continue;
822 }
823
824 if (!BlockIo->Media->MediaPresent)
825 {
826 TRACE("Media not present for handle %lu\n", i);
827 continue;
828 }
829
830 if (BlockIo->Media->BlockSize == 0)
831 {
832 TRACE("Invalid block size (0) for handle %lu\n", i);
833 continue;
834 }
835
836 /* Filter out devices with unusually large block sizes (flash devices) */
837 if (BlockIo->Media->BlockSize > MAX_SUPPORTED_BLOCK_SIZE)
838 {
839 TRACE("Block size too large (%lu) for handle %lu, skipping\n",
840 BlockIo->Media->BlockSize, i);
841 continue;
842 }
843
844 /* Logical partitions are handled separately by partition scanning */
845 if (BlockIo->Media->LogicalPartition)
846 {
847 /* If boot handle is a logical partition, we need to find its parent root device */
848 /* For now, we'll handle this after enumeration by matching handles */
849 TRACE("Skipping logical partition handle %lu\n", i);
850 continue;
851 }
852
853 /* This is a root block device */
854 TRACE("Found root block device at index %lu: BlockSize=%lu, LastBlock=%llu\n",
855 i, BlockIo->Media->BlockSize, BlockIo->Media->LastBlock);
856
857 InternalUefiDisk[BlockDeviceIndex].ArcDriveNumber = BlockDeviceIndex;
858 InternalUefiDisk[BlockDeviceIndex].UefiHandleIndex = i;
859 InternalUefiDisk[BlockDeviceIndex].Handle = handles[i];
860 InternalUefiDisk[BlockDeviceIndex].IsThisTheBootDrive = FALSE;
861
862 /* Check if this root device contains the boot partition */
863 /* If boot handle is a logical partition, we need to find which root device it belongs to */
864 /* For now, if boot handle index matches, mark it as boot device */
865 if (i == UefiBootRootIndex)
866 {
867 InternalUefiDisk[BlockDeviceIndex].IsThisTheBootDrive = TRUE;
868 PublicBootArcDisk = BlockDeviceIndex;
869 TRACE("Boot device is at ARC drive index %lu (root device)\n", BlockDeviceIndex);
870 }
871
872 /* Increment PcBiosDiskCount BEFORE calling GetHarddiskInformation
873 * so that UefiDiskReadLogicalSectors can validate the drive number */
874 PcBiosDiskCount = BlockDeviceIndex + 1;
875
876 TRACE("Calling GetHarddiskInformation for drive %d (BlockDeviceIndex=%lu)\n",
877 BlockDeviceIndex + FIRST_BIOS_DISK, BlockDeviceIndex);
878 if (!UefiEnsureDiskReadBufferAligned(BlockIo->Media->IoAlign))
879 {
880 ERR("Failed to align disk read buffer for drive %d\n", BlockDeviceIndex + FIRST_BIOS_DISK);
881 return;
882 }
883
884 GetHarddiskInformation(BlockDeviceIndex + FIRST_BIOS_DISK);
885 BlockDeviceIndex++;
886 }
887
888 /* Step 7: If boot handle was a logical partition, find its parent root device */
890 {
894 (VOID**)&BlockIo);
895
896 if (!EFI_ERROR(Status) && BlockIo != NULL && BlockIo->Media->LogicalPartition)
897 {
898 TRACE("Boot handle is a logical partition, searching for parent root device\n");
899 TRACE("Boot partition: BlockSize=%lu, RemovableMedia=%s\n",
900 BlockIo->Media->BlockSize,
901 BlockIo->Media->RemovableMedia ? "TRUE" : "FALSE");
902
903 /* Find the root device that matches the boot partition's characteristics */
904 /* For CD-ROMs: match BlockSize=2048 and RemovableMedia=TRUE */
905 /* For hard disks: match BlockSize and find the root device before this partition */
906 BOOLEAN FoundBootDevice = FALSE;
907 for (i = 0; i < BlockDeviceIndex; i++)
908 {
909 EFI_BLOCK_IO* RootBlockIo;
913 (VOID**)&RootBlockIo);
914
915 if (EFI_ERROR(Status) || RootBlockIo == NULL)
916 continue;
917
918 /* For CD-ROM: match BlockSize=2048 and RemovableMedia */
919 if (BlockIo->Media->BlockSize == 2048 && BlockIo->Media->RemovableMedia)
920 {
921 if (RootBlockIo->Media->BlockSize == 2048 &&
922 RootBlockIo->Media->RemovableMedia &&
923 !RootBlockIo->Media->LogicalPartition)
924 {
927 FoundBootDevice = TRUE;
928 TRACE("Found CD-ROM boot device at ARC drive index %lu\n", i);
929 break;
930 }
931 }
932 /* For hard disk partitions: the root device should be before the partition handle */
933 else if (InternalUefiDisk[i].UefiHandleIndex < UefiBootRootIndex)
934 {
935 /* Check if this root device is likely the parent */
936 if (RootBlockIo->Media->BlockSize == BlockIo->Media->BlockSize &&
937 !RootBlockIo->Media->LogicalPartition)
938 {
939 /* This might be the parent, but we need to be more certain */
940 /* For now, use the last root device before the boot handle */
943 FoundBootDevice = TRUE;
944 TRACE("Found potential hard disk boot device at ARC drive index %lu\n", i);
945 }
946 }
947 }
948
949 if (!FoundBootDevice && PcBiosDiskCount > 0)
950 {
953 TRACE("Could not determine boot device, assuming first drive\n");
954 }
955 }
956 }
957
958 TRACE("Found %lu root block devices\n", PcBiosDiskCount);
959}
960
961static
964{
965 EFI_BLOCK_IO* BootBlockIo = NULL;
967 ULONG ArcDriveIndex;
968
969 TRACE("UefiSetBootpath: Setting up boot path\n");
970
972 {
973 ERR("Invalid boot root index\n");
974 return FALSE;
975 }
976
977 ArcDriveIndex = PublicBootArcDisk;
978 if (ArcDriveIndex >= PcBiosDiskCount || InternalUefiDisk == NULL)
979 {
980 ERR("Invalid boot arc disk index\n");
981 return FALSE;
982 }
983
987 (VOID**)&BootBlockIo);
988
989 if (EFI_ERROR(Status) || BootBlockIo == NULL)
990 {
991 ERR("Failed to get Block I/O protocol for boot handle\n");
992 return FALSE;
993 }
994
995 FrldrBootDrive = (FIRST_BIOS_DISK + ArcDriveIndex);
996
997 /* Check if booting from CD-ROM by checking the boot handle properties.
998 * CD-ROMs have BlockSize=2048 and RemovableMedia=TRUE. */
999 if (BootBlockIo->Media->RemovableMedia == TRUE && BootBlockIo->Media->BlockSize == 2048)
1000 {
1001 /* Boot Partition 0xFF is the magic value that indicates booting from CD-ROM */
1002 FrldrBootPartition = 0xFF;
1004 "multi(0)disk(0)cdrom(%u)", ArcDriveIndex);
1005 TRACE("Boot path set to CD-ROM: %s\n", FrLdrBootPath);
1006 }
1007 else
1008 {
1009 ULONG BootPartition;
1010
1011 /* This is a hard disk */
1012 /* If boot handle is a logical partition, we need to determine which partition number */
1013 if (BootBlockIo->Media->LogicalPartition)
1014 {
1015 /* For logical partitions, we need to find the partition number.
1016 * This is tricky - we'll use partition 1 as default for now. */
1017 // TODO: Properly determine partition number from boot handle.
1018 BootPartition = FIRST_PARTITION;
1019 TRACE("Boot handle is logical partition, using partition %lu\n", BootPartition);
1020 }
1021 else
1022 {
1023 /* Boot handle is the root device itself */
1024 if (!UefiGetBootPartitionEntry(FrldrBootDrive, NULL, &BootPartition))
1025 {
1026 ERR("Failed to get boot partition entry\n");
1027 return FALSE;
1028 }
1029 }
1030
1032 "multi(0)disk(0)rdisk(%u)partition(%lu)",
1033 ArcDriveIndex, BootPartition);
1034 TRACE("Boot path set to hard disk: %s\n", FrLdrBootPath);
1035 }
1036
1037 return TRUE;
1038}
1039
1040BOOLEAN
1042{
1043 EFI_BLOCK_IO* BlockIo;
1045 ULONG ArcDriveIndex;
1046
1053 {
1054 ERR("Failed to allocate disk read buffer\n");
1055 return FALSE;
1056 }
1057
1059
1060 if (PcBiosDiskCount == 0)
1061 {
1062 ERR("No block devices found\n");
1063 return FALSE;
1064 }
1065
1066 if (!UefiSetBootpath())
1067 {
1068 ERR("Failed to set boot path\n");
1069 return FALSE;
1070 }
1071
1072 /* Handle CD-ROM boot device registration */
1073 ArcDriveIndex = PublicBootArcDisk;
1074 if (ArcDriveIndex >= PcBiosDiskCount || InternalUefiDisk == NULL)
1075 {
1076 ERR("Invalid boot arc disk index\n");
1077 return FALSE;
1078 }
1079
1081 InternalUefiDisk[ArcDriveIndex].Handle,
1082 &BlockIoGuid,
1083 (VOID**)&BlockIo);
1084
1085 if (EFI_ERROR(Status) || BlockIo == NULL)
1086 {
1087 ERR("Failed to get Block I/O protocol\n");
1088 return FALSE;
1089 }
1090
1091 if (BlockIo->Media->RemovableMedia == TRUE && BlockIo->Media->BlockSize == 2048)
1092 {
1094
1099
1100 if (Status == ESUCCESS)
1101 TRACE("Registered CD-ROM boot device: 0x%02X\n", FrldrBootDrive);
1102 else
1103 ERR("CD-ROM boot device 0x%02X failed\n", FrldrBootDrive);
1104 }
1105
1106 return TRUE;
1107}
1108
1109UCHAR
1111{
1112 /* No floppy support in UEFI */
1113 return 0;
1114}
1115
1116BOOLEAN
1118 IN UCHAR DriveNumber,
1119 IN ULONGLONG SectorNumber,
1122{
1123 ULONG ArcDriveIndex;
1124 EFI_BLOCK_IO* BlockIo;
1126 ULONG BlockSize;
1127 ULONG IoAlign;
1128
1129 if (DriveNumber < FIRST_BIOS_DISK)
1130 return FALSE;
1131
1132 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
1133
1134 if (InternalUefiDisk == NULL)
1135 {
1136 ERR("InternalUefiDisk not initialized\n");
1137 return FALSE;
1138 }
1139
1140 if (ArcDriveIndex >= 32)
1141 {
1142 ERR("Drive index out of bounds: %d (ArcDriveIndex=%lu)\n", DriveNumber, ArcDriveIndex);
1143 return FALSE;
1144 }
1145
1146 /* Allow access during initialization: check if handle is set up.
1147 * During initialization, Handle is set before GetHarddiskInformation is called. */
1148 if (InternalUefiDisk[ArcDriveIndex].Handle == NULL)
1149 {
1150 ERR("Invalid drive number: %d (ArcDriveIndex=%lu, PcBiosDiskCount=%lu, Handle=NULL)\n",
1151 DriveNumber, ArcDriveIndex, PcBiosDiskCount);
1152 return FALSE;
1153 }
1154
1156 InternalUefiDisk[ArcDriveIndex].Handle,
1157 &BlockIoGuid,
1158 (VOID**)&BlockIo);
1159
1160 if (EFI_ERROR(Status) || BlockIo == NULL)
1161 {
1162 ERR("Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1163 return FALSE;
1164 }
1165
1166 if (!BlockIo->Media->MediaPresent)
1167 {
1168 ERR("Media not present for drive %d\n", DriveNumber);
1169 return FALSE;
1170 }
1171
1172 BlockSize = BlockIo->Media->BlockSize;
1173 IoAlign = BlockIo->Media->IoAlign;
1174
1175 if (!UefiEnsureDiskReadBufferAligned(IoAlign))
1176 {
1177 ERR("Failed to align disk read buffer for drive %d\n", DriveNumber);
1178 return FALSE;
1179 }
1180
1181 if (!UefiIsAlignedPointer(Buffer, (IoAlign == 0) ? 1 : IoAlign))
1182 {
1183 ULONG TotalSectors = SectorCount;
1184 ULONG MaxSectors = DiskReadBufferSize / BlockSize;
1185 ULONGLONG CurrentSector = SectorNumber;
1186 PUCHAR OutPtr = (PUCHAR)Buffer;
1187
1188 if (MaxSectors == 0)
1189 {
1190 ERR("DiskReadBufferSize too small for block size %lu\n", BlockSize);
1191 return FALSE;
1192 }
1193
1194 while (TotalSectors)
1195 {
1196 ULONG ReadSectors = min(TotalSectors, MaxSectors);
1197 UINTN ReadSize = ReadSectors * BlockSize;
1198
1199 Status = BlockIo->ReadBlocks(
1200 BlockIo,
1201 BlockIo->Media->MediaId,
1202 CurrentSector,
1203 ReadSize,
1205
1206 if (EFI_ERROR(Status))
1207 {
1208 ERR("ReadBlocks failed: DriveNumber=%d, SectorNumber=%llu, SectorCount=%lu, Status=0x%lx\n",
1209 DriveNumber, CurrentSector, ReadSectors, (ULONG)Status);
1210 ERR("ReadBlocks details: BlockSize=%lu, IoAlign=%lu, Buffer=%p, DiskReadBuffer=%p, MediaId=0x%lx\n",
1211 BlockSize, IoAlign, Buffer, DiskReadBuffer, (ULONG)BlockIo->Media->MediaId);
1212 ERR("ReadBlocks media: LastBlock=%llu, LogicalPartition=%s, RemovableMedia=%s\n",
1213 BlockIo->Media->LastBlock,
1214 BlockIo->Media->LogicalPartition ? "TRUE" : "FALSE",
1215 BlockIo->Media->RemovableMedia ? "TRUE" : "FALSE");
1216 return FALSE;
1217 }
1218
1219 RtlCopyMemory(OutPtr, DiskReadBuffer, ReadSize);
1220 OutPtr += ReadSize;
1221 CurrentSector += ReadSectors;
1222 TotalSectors -= ReadSectors;
1223 }
1224
1225 return TRUE;
1226 }
1227
1228 Status = BlockIo->ReadBlocks(
1229 BlockIo,
1230 BlockIo->Media->MediaId,
1231 SectorNumber,
1232 SectorCount * BlockSize,
1233 Buffer);
1234
1235 if (EFI_ERROR(Status))
1236 {
1237 ERR("ReadBlocks failed: DriveNumber=%d, SectorNumber=%llu, SectorCount=%lu, Status=0x%lx\n",
1238 DriveNumber, SectorNumber, SectorCount, (ULONG)Status);
1239 ERR("ReadBlocks details: BlockSize=%lu, IoAlign=%lu, Buffer=%p, DiskReadBuffer=%p, MediaId=0x%lx\n",
1240 BlockSize, IoAlign, Buffer, DiskReadBuffer, (ULONG)BlockIo->Media->MediaId);
1241 ERR("ReadBlocks media: LastBlock=%llu, LogicalPartition=%s, RemovableMedia=%s\n",
1242 BlockIo->Media->LastBlock,
1243 BlockIo->Media->LogicalPartition ? "TRUE" : "FALSE",
1244 BlockIo->Media->RemovableMedia ? "TRUE" : "FALSE");
1245 return FALSE;
1246 }
1247
1248 return TRUE;
1249}
1250
1251BOOLEAN
1253{
1254 ULONG ArcDriveIndex;
1255 EFI_BLOCK_IO* BlockIo;
1257
1258 if (DriveNumber < FIRST_BIOS_DISK)
1259 return FALSE;
1260
1261 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
1262
1263 if (InternalUefiDisk == NULL)
1264 {
1265 ERR("InternalUefiDisk not initialized\n");
1266 return FALSE;
1267 }
1268
1269 if (ArcDriveIndex >= 32 || InternalUefiDisk[ArcDriveIndex].Handle == NULL)
1270 {
1271 ERR("Invalid drive number: %d\n", DriveNumber);
1272 return FALSE;
1273 }
1274
1276 InternalUefiDisk[ArcDriveIndex].Handle,
1277 &BlockIoGuid,
1278 (VOID**)&BlockIo);
1279
1280 if (EFI_ERROR(Status) || BlockIo == NULL)
1281 {
1282 ERR("Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1283 return FALSE;
1284 }
1285
1286 if (!BlockIo->Media->MediaPresent)
1287 {
1288 ERR("Media not present for drive %d\n", DriveNumber);
1289 return FALSE;
1290 }
1291
1292 Geometry->Cylinders = 1; /* Not relevant for UEFI Block I/O protocol */
1293 Geometry->Heads = 1; /* Not relevant for UEFI Block I/O protocol */
1294 Geometry->SectorsPerTrack = (ULONG)(BlockIo->Media->LastBlock + 1);
1295 Geometry->BytesPerSector = BlockIo->Media->BlockSize;
1296 Geometry->Sectors = BlockIo->Media->LastBlock + 1;
1297
1298 return TRUE;
1299}
1300
1301ULONG
1303{
1304 ULONG ArcDriveIndex;
1305 EFI_BLOCK_IO* BlockIo;
1307
1308 if (DriveNumber < FIRST_BIOS_DISK)
1309 return 0;
1310
1311 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
1312
1313 if (InternalUefiDisk == NULL)
1314 {
1315 ERR("InternalUefiDisk not initialized\n");
1316 return 0;
1317 }
1318
1319 if (ArcDriveIndex >= 32 || InternalUefiDisk[ArcDriveIndex].Handle == NULL)
1320 {
1321 ERR("Invalid drive number: %d\n", DriveNumber);
1322 return 0;
1323 }
1324
1326 InternalUefiDisk[ArcDriveIndex].Handle,
1327 &BlockIoGuid,
1328 (VOID**)&BlockIo);
1329
1330 if (EFI_ERROR(Status) || BlockIo == NULL)
1331 {
1332 ERR("Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1333 return 0;
1334 }
1335
1336 if (!BlockIo->Media->MediaPresent)
1337 {
1338 ERR("Media not present for drive %d\n", DriveNumber);
1339 return 0;
1340 }
1341
1342 return (ULONG)(BlockIo->Media->LastBlock + 1);
1343}
#define N
Definition: crc32.c:57
#define BLOCK_IO_PROTOCOL
Definition: BlockIo.h:31
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
#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:146
#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:25
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
#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
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
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
static ULONG PublicBootArcDisk
Definition: uefidisk.c:64
PCSTR DiskGetErrorCodeString(_In_ ULONG ErrorCode)
Definition: uefidisk.c:74
BOOLEAN UefiDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
Definition: uefidisk.c:1252
PVOID Buffer
Definition: uefidisk.c:60
#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:1117
struct tagDISKCONTEXT DISKCONTEXT
static BOOLEAN DiskReadBufferFromPool
Definition: uefidisk.c:53
static EFI_GUID BlockIoGuid
Definition: uefidisk.c:66
BOOLEAN UefiInitializeBootDevices(VOID)
Definition: uefidisk.c:1041
static ARC_STATUS UefiDiskGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: uefidisk.c:398
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:171
static const DEVVTBL UefiDiskVtbl
Definition: uefidisk.c:635
static BOOLEAN UefiEnsureDiskReadBufferAligned(IN ULONG Alignment)
Definition: uefidisk.c:97
static VOID UefiSetupBlockDevices(VOID)
Definition: uefidisk.c:707
static ULONG UefiBootRootIndex
Definition: uefidisk.c:63
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:420
static ARC_STATUS UefiDiskSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: uefidisk.c:604
static VOID GetHarddiskInformation(_In_ UCHAR DriveNumber)
Definition: uefidisk.c:645
static INTERNAL_UEFI_DISK * InternalUefiDisk
Definition: uefidisk.c:65
static ARC_STATUS UefiDiskClose(ULONG FileId)
Definition: uefidisk.c:389
static ARC_STATUS UefiDiskRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: uefidisk.c:509
static ULONG HandleCount
Definition: uefidisk.c:68
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:67
UCHAR UefiGetFloppyCount(VOID)
Definition: uefidisk.c:1110
SIZE_T DiskReadBufferSize
Definition: uefidisk.c:59
static BOOLEAN UefiIsAlignedPointer(IN PVOID Pointer, IN ULONG Alignment)
Definition: uefidisk.c:82
ULONG UefiDiskGetCacheableBlockCount(UCHAR DriveNumber)
Definition: uefidisk.c:1302
UCHAR FrldrBootDrive
Definition: uefidisk.c:57
static BOOLEAN UefiSetBootpath(VOID)
Definition: uefidisk.c:963
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
_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