ReactOS 0.4.17-dev-116-ga4b6fe9
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 /* For logical partitions, we need to find the partition number.
1015 * This is tricky - we'll use partition 1 as default for now. */
1016 // TODO: Properly determine partition number from boot handle.
1017 BootPartition = FIRST_PARTITION;
1018 TRACE("Boot handle is logical partition, using partition %lu\n", BootPartition);
1019 }
1020 else
1021 {
1022 /* Boot handle is the root device itself */
1023 if (!UefiGetBootPartitionEntry(FrldrBootDrive, NULL, &BootPartition))
1024 {
1025 ERR("Failed to get boot partition entry\n");
1026 return FALSE;
1027 }
1028 }
1029
1031 "multi(0)disk(0)rdisk(%u)partition(%lu)",
1032 ArcDriveIndex, BootPartition);
1033 TRACE("Boot path set to hard disk: %s\n", FrLdrBootPath);
1034 }
1035
1036 return TRUE;
1037}
1038
1039BOOLEAN
1041{
1042 EFI_BLOCK_IO* BlockIo;
1044 ULONG ArcDriveIndex;
1045
1052 {
1053 ERR("Failed to allocate disk read buffer\n");
1054 return FALSE;
1055 }
1056
1058
1059 if (PcBiosDiskCount == 0)
1060 {
1061 ERR("No block devices found\n");
1062 return FALSE;
1063 }
1064
1065 if (!UefiSetBootpath())
1066 {
1067 ERR("Failed to set boot path\n");
1068 return FALSE;
1069 }
1070
1071 /* Handle CD-ROM boot device registration */
1072 ArcDriveIndex = PublicBootArcDisk;
1073 if (ArcDriveIndex >= PcBiosDiskCount || InternalUefiDisk == NULL)
1074 {
1075 ERR("Invalid boot arc disk index\n");
1076 return FALSE;
1077 }
1078
1080 InternalUefiDisk[ArcDriveIndex].Handle,
1081 &BlockIoGuid,
1082 (VOID**)&BlockIo);
1083
1084 if (EFI_ERROR(Status) || BlockIo == NULL)
1085 {
1086 ERR("Failed to get Block I/O protocol\n");
1087 return FALSE;
1088 }
1089
1090 if (BlockIo->Media->RemovableMedia == TRUE && BlockIo->Media->BlockSize == 2048)
1091 {
1093
1098
1099 if (Status == ESUCCESS)
1100 TRACE("Registered CD-ROM boot device: 0x%02X\n", FrldrBootDrive);
1101 else
1102 ERR("CD-ROM boot device 0x%02X failed\n", FrldrBootDrive);
1103 }
1104
1105 return TRUE;
1106}
1107
1108UCHAR
1110{
1111 /* No floppy support in UEFI */
1112 return 0;
1113}
1114
1115BOOLEAN
1117 IN UCHAR DriveNumber,
1118 IN ULONGLONG SectorNumber,
1121{
1122 ULONG ArcDriveIndex;
1123 EFI_BLOCK_IO* BlockIo;
1125 ULONG BlockSize;
1126 ULONG IoAlign;
1127
1128 if (DriveNumber < FIRST_BIOS_DISK)
1129 return FALSE;
1130
1131 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
1132
1133 if (InternalUefiDisk == NULL)
1134 {
1135 ERR("InternalUefiDisk not initialized\n");
1136 return FALSE;
1137 }
1138
1139 if (ArcDriveIndex >= 32)
1140 {
1141 ERR("Drive index out of bounds: %d (ArcDriveIndex=%lu)\n", DriveNumber, ArcDriveIndex);
1142 return FALSE;
1143 }
1144
1145 /* Allow access during initialization: check if handle is set up.
1146 * During initialization, Handle is set before GetHarddiskInformation is called. */
1147 if (InternalUefiDisk[ArcDriveIndex].Handle == NULL)
1148 {
1149 ERR("Invalid drive number: %d (ArcDriveIndex=%lu, PcBiosDiskCount=%lu, Handle=NULL)\n",
1150 DriveNumber, ArcDriveIndex, PcBiosDiskCount);
1151 return FALSE;
1152 }
1153
1155 InternalUefiDisk[ArcDriveIndex].Handle,
1156 &BlockIoGuid,
1157 (VOID**)&BlockIo);
1158
1159 if (EFI_ERROR(Status) || BlockIo == NULL)
1160 {
1161 ERR("Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1162 return FALSE;
1163 }
1164
1165 if (!BlockIo->Media->MediaPresent)
1166 {
1167 ERR("Media not present for drive %d\n", DriveNumber);
1168 return FALSE;
1169 }
1170
1171 BlockSize = BlockIo->Media->BlockSize;
1172 IoAlign = BlockIo->Media->IoAlign;
1173
1174 if (!UefiEnsureDiskReadBufferAligned(IoAlign))
1175 {
1176 ERR("Failed to align disk read buffer for drive %d\n", DriveNumber);
1177 return FALSE;
1178 }
1179
1180 if (!UefiIsAlignedPointer(Buffer, (IoAlign == 0) ? 1 : IoAlign))
1181 {
1182 ULONG TotalSectors = SectorCount;
1183 ULONG MaxSectors = DiskReadBufferSize / BlockSize;
1184 ULONGLONG CurrentSector = SectorNumber;
1185 PUCHAR OutPtr = (PUCHAR)Buffer;
1186
1187 if (MaxSectors == 0)
1188 {
1189 ERR("DiskReadBufferSize too small for block size %lu\n", BlockSize);
1190 return FALSE;
1191 }
1192
1193 while (TotalSectors)
1194 {
1195 ULONG ReadSectors = min(TotalSectors, MaxSectors);
1196 UINTN ReadSize = ReadSectors * BlockSize;
1197
1198 Status = BlockIo->ReadBlocks(
1199 BlockIo,
1200 BlockIo->Media->MediaId,
1201 CurrentSector,
1202 ReadSize,
1204
1205 if (EFI_ERROR(Status))
1206 {
1207 ERR("ReadBlocks failed: DriveNumber=%d, SectorNumber=%llu, SectorCount=%lu, Status=0x%lx\n",
1208 DriveNumber, CurrentSector, ReadSectors, (ULONG)Status);
1209 ERR("ReadBlocks details: BlockSize=%lu, IoAlign=%lu, Buffer=%p, DiskReadBuffer=%p, MediaId=0x%lx\n",
1210 BlockSize, IoAlign, Buffer, DiskReadBuffer, (ULONG)BlockIo->Media->MediaId);
1211 ERR("ReadBlocks media: LastBlock=%llu, LogicalPartition=%s, RemovableMedia=%s\n",
1212 BlockIo->Media->LastBlock,
1213 BlockIo->Media->LogicalPartition ? "TRUE" : "FALSE",
1214 BlockIo->Media->RemovableMedia ? "TRUE" : "FALSE");
1215 return FALSE;
1216 }
1217
1218 RtlCopyMemory(OutPtr, DiskReadBuffer, ReadSize);
1219 OutPtr += ReadSize;
1220 CurrentSector += ReadSectors;
1221 TotalSectors -= ReadSectors;
1222 }
1223
1224 return TRUE;
1225 }
1226
1227 Status = BlockIo->ReadBlocks(
1228 BlockIo,
1229 BlockIo->Media->MediaId,
1230 SectorNumber,
1231 SectorCount * BlockSize,
1232 Buffer);
1233
1234 if (EFI_ERROR(Status))
1235 {
1236 ERR("ReadBlocks failed: DriveNumber=%d, SectorNumber=%llu, SectorCount=%lu, Status=0x%lx\n",
1237 DriveNumber, SectorNumber, SectorCount, (ULONG)Status);
1238 ERR("ReadBlocks details: BlockSize=%lu, IoAlign=%lu, Buffer=%p, DiskReadBuffer=%p, MediaId=0x%lx\n",
1239 BlockSize, IoAlign, Buffer, DiskReadBuffer, (ULONG)BlockIo->Media->MediaId);
1240 ERR("ReadBlocks media: LastBlock=%llu, LogicalPartition=%s, RemovableMedia=%s\n",
1241 BlockIo->Media->LastBlock,
1242 BlockIo->Media->LogicalPartition ? "TRUE" : "FALSE",
1243 BlockIo->Media->RemovableMedia ? "TRUE" : "FALSE");
1244 return FALSE;
1245 }
1246
1247 return TRUE;
1248}
1249
1250BOOLEAN
1252{
1253 ULONG ArcDriveIndex;
1254 EFI_BLOCK_IO* BlockIo;
1256
1257 if (DriveNumber < FIRST_BIOS_DISK)
1258 return FALSE;
1259
1260 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
1261
1262 if (InternalUefiDisk == NULL)
1263 {
1264 ERR("InternalUefiDisk not initialized\n");
1265 return FALSE;
1266 }
1267
1268 if (ArcDriveIndex >= 32 || InternalUefiDisk[ArcDriveIndex].Handle == NULL)
1269 {
1270 ERR("Invalid drive number: %d\n", DriveNumber);
1271 return FALSE;
1272 }
1273
1275 InternalUefiDisk[ArcDriveIndex].Handle,
1276 &BlockIoGuid,
1277 (VOID**)&BlockIo);
1278
1279 if (EFI_ERROR(Status) || BlockIo == NULL)
1280 {
1281 ERR("Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1282 return FALSE;
1283 }
1284
1285 if (!BlockIo->Media->MediaPresent)
1286 {
1287 ERR("Media not present for drive %d\n", DriveNumber);
1288 return FALSE;
1289 }
1290
1291 Geometry->Cylinders = 1; /* Not relevant for UEFI Block I/O protocol */
1292 Geometry->Heads = 1; /* Not relevant for UEFI Block I/O protocol */
1293 Geometry->SectorsPerTrack = (ULONG)(BlockIo->Media->LastBlock + 1);
1294 Geometry->BytesPerSector = BlockIo->Media->BlockSize;
1295 Geometry->Sectors = BlockIo->Media->LastBlock + 1;
1296
1297 return TRUE;
1298}
1299
1300ULONG
1302{
1303 ULONG ArcDriveIndex;
1304 EFI_BLOCK_IO* BlockIo;
1306
1307 if (DriveNumber < FIRST_BIOS_DISK)
1308 return 0;
1309
1310 ArcDriveIndex = DriveNumber - FIRST_BIOS_DISK;
1311
1312 if (InternalUefiDisk == NULL)
1313 {
1314 ERR("InternalUefiDisk not initialized\n");
1315 return 0;
1316 }
1317
1318 if (ArcDriveIndex >= 32 || InternalUefiDisk[ArcDriveIndex].Handle == NULL)
1319 {
1320 ERR("Invalid drive number: %d\n", DriveNumber);
1321 return 0;
1322 }
1323
1325 InternalUefiDisk[ArcDriveIndex].Handle,
1326 &BlockIoGuid,
1327 (VOID**)&BlockIo);
1328
1329 if (EFI_ERROR(Status) || BlockIo == NULL)
1330 {
1331 ERR("Failed to get Block I/O protocol for drive %d\n", DriveNumber);
1332 return 0;
1333 }
1334
1335 if (!BlockIo->Media->MediaPresent)
1336 {
1337 ERR("Media not present for drive %d\n", DriveNumber);
1338 return 0;
1339 }
1340
1341 return (ULONG)(BlockIo->Media->LastBlock + 1);
1342}
#define 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
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:1251
#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:1116
struct tagDISKCONTEXT DISKCONTEXT
static BOOLEAN DiskReadBufferFromPool
Definition: uefidisk.c:53
static EFI_GUID BlockIoGuid
Definition: uefidisk.c:65
BOOLEAN UefiInitializeBootDevices(VOID)
Definition: uefidisk.c:1040
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:1109
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:1301
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
_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