1 /*
2 * PROJECT: FreeLoader UEFI Support
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Disk Access Functions
5 * COPYRIGHT: Copyright 2022 Justin Miller <justinmiller100@gmail.com>
6 */
7
8 /* INCLUDES ******************************************************************/
9
10 #include <uefildr.h>
11
12 #include <debug.h>
13 DBG_DEFAULT_CHANNEL(WARNING);
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 typedef struct tagDISKCONTEXT
21 {
22 UCHAR DriveNumber;
23 ULONG SectorSize;
24 ULONGLONG SectorOffset;
25 ULONGLONG SectorCount;
26 ULONGLONG SectorNumber;
27 } DISKCONTEXT;
28
29 typedef struct _INTERNAL_UEFI_DISK
30 {
31 UCHAR ArcDriveNumber;
32 UCHAR NumOfPartitions;
33 UCHAR UefiRootNumber;
34 BOOLEAN IsThisTheBootDrive;
35 } INTERNAL_UEFI_DISK, *PINTERNAL_UEFI_DISK;
36
37 /* GLOBALS *******************************************************************/
38
39 extern EFI_SYSTEM_TABLE* GlobalSystemTable;
40 extern EFI_HANDLE GlobalImageHandle;
41 extern EFI_HANDLE PublicBootHandle; /* Freeldr itself */
42
43 /* Made to match BIOS */
44 PVOID DiskReadBuffer;
45 UCHAR PcBiosDiskCount;
46
47 UCHAR FrldrBootDrive;
48 ULONG FrldrBootPartition;
49 SIZE_T DiskReadBufferSize;
50 PVOID Buffer;
51
52 static const CHAR Hex[] = "0123456789abcdef";
53 static CHAR PcDiskIdentifier[32][20];
54
55 /* UEFI-specific */
56 static ULONG UefiBootRootIdentifier;
57 static ULONG OffsetToBoot;
58 static ULONG PublicBootArcDisk;
59 static INTERNAL_UEFI_DISK* InternalUefiDisk = NULL;
60 static EFI_GUID bioGuid = BLOCK_IO_PROTOCOL;
61 static EFI_BLOCK_IO* bio;
62 static EFI_HANDLE* handles = NULL;
63
64 /* FUNCTIONS *****************************************************************/
65
66 PCHAR
GetHarddiskIdentifier(UCHAR DriveNumber)67 GetHarddiskIdentifier(UCHAR DriveNumber)
68 {
69 TRACE("GetHarddiskIdentifier: DriveNumber: %d\n", DriveNumber);
70 return PcDiskIdentifier[DriveNumber - FIRST_BIOS_DISK];
71 }
72
73 static LONG lReportError = 0; // >= 0: display errors; < 0: hide errors.
74
75 LONG
DiskReportError(BOOLEAN bShowError)76 DiskReportError(BOOLEAN bShowError)
77 {
78 /* Set the reference count */
79 if (bShowError) ++lReportError;
80 else --lReportError;
81 return lReportError;
82 }
83
84 static
85 BOOLEAN
UefiGetBootPartitionEntry(IN UCHAR DriveNumber,OUT PPARTITION_TABLE_ENTRY PartitionTableEntry,OUT PULONG BootPartition)86 UefiGetBootPartitionEntry(
87 IN UCHAR DriveNumber,
88 OUT PPARTITION_TABLE_ENTRY PartitionTableEntry,
89 OUT PULONG BootPartition)
90 {
91 ULONG PartitionNum;
92
93 TRACE("UefiGetBootPartitionEntry: DriveNumber: %d\n", DriveNumber - FIRST_BIOS_DISK);
94 /* UefiBootRoot is the offset into the array of handles where the raw disk of the boot drive is.
95 * Partitions start with 1 in ARC, but UEFI root drive identitfier is also first partition. */
96 PartitionNum = (OffsetToBoot - UefiBootRootIdentifier);
97 if (PartitionNum == 0)
98 {
99 TRACE("Boot PartitionNumber is 0\n");
100 /* The OffsetToBoot is equal to the RootIdentifier */
101 PartitionNum = FIRST_PARTITION;
102 }
103
104 *BootPartition = PartitionNum;
105 TRACE("UefiGetBootPartitionEntry: Boot Partition is: %d\n", PartitionNum);
106 return TRUE;
107 }
108
109 static
110 ARC_STATUS
UefiDiskClose(ULONG FileId)111 UefiDiskClose(ULONG FileId)
112 {
113 DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
114 FrLdrTempFree(Context, TAG_HW_DISK_CONTEXT);
115 return ESUCCESS;
116 }
117
118 static
119 ARC_STATUS
UefiDiskGetFileInformation(ULONG FileId,FILEINFORMATION * Information)120 UefiDiskGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
121 {
122 DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
123 RtlZeroMemory(Information, sizeof(*Information));
124
125 /*
126 * The ARC specification mentions that for partitions, StartingAddress and
127 * EndingAddress are the start and end positions of the partition in terms
128 * of byte offsets from the start of the disk.
129 * CurrentAddress is the current offset into (i.e. relative to) the partition.
130 */
131 Information->StartingAddress.QuadPart = Context->SectorOffset * Context->SectorSize;
132 Information->EndingAddress.QuadPart = (Context->SectorOffset + Context->SectorCount) * Context->SectorSize;
133 Information->CurrentAddress.QuadPart = Context->SectorNumber * Context->SectorSize;
134
135 return ESUCCESS;
136 }
137
138 static
139 ARC_STATUS
UefiDiskOpen(CHAR * Path,OPENMODE OpenMode,ULONG * FileId)140 UefiDiskOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
141 {
142 DISKCONTEXT* Context;
143 UCHAR DriveNumber;
144 ULONG DrivePartition, SectorSize;
145 ULONGLONG SectorOffset = 0;
146 ULONGLONG SectorCount = 0;
147 ULONG UefiDriveNumber = 0;
148 PARTITION_TABLE_ENTRY PartitionTableEntry;
149
150 TRACE("UefiDiskOpen: File ID: %d, Path: %s\n", FileId, Path);
151
152 if (DiskReadBufferSize == 0)
153 {
154 ERR("DiskOpen(): DiskReadBufferSize is 0, something is wrong.\n");
155 ASSERT(FALSE);
156 return ENOMEM;
157 }
158
159 if (!DissectArcPath(Path, NULL, &DriveNumber, &DrivePartition))
160 return EINVAL;
161
162 TRACE("Opening disk: DriveNumber: %d, DrivePartition: %d\n", DriveNumber, DrivePartition);
163 UefiDriveNumber = DriveNumber - FIRST_BIOS_DISK;
164 GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber], &bioGuid, (void**)&bio);
165 SectorSize = bio->Media->BlockSize;
166
167 if (DrivePartition != 0xff && DrivePartition != 0)
168 {
169 if (!DiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry))
170 return EINVAL;
171
172 SectorOffset = PartitionTableEntry.SectorCountBeforePartition;
173 SectorCount = PartitionTableEntry.PartitionSectorCount;
174 }
175 else
176 {
177 GEOMETRY Geometry;
178 if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
179 return EINVAL;
180
181 if (SectorSize != Geometry.BytesPerSector)
182 {
183 ERR("SectorSize (%lu) != Geometry.BytesPerSector (%lu), expect problems!\n",
184 SectorSize, Geometry.BytesPerSector);
185 }
186
187 SectorOffset = 0;
188 SectorCount = Geometry.Sectors;
189 }
190
191 Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
192 if (!Context)
193 return ENOMEM;
194
195 Context->DriveNumber = DriveNumber;
196 Context->SectorSize = SectorSize;
197 Context->SectorOffset = SectorOffset;
198 Context->SectorCount = SectorCount;
199 Context->SectorNumber = 0;
200 FsSetDeviceSpecific(*FileId, Context);
201 return ESUCCESS;
202 }
203
204 static
205 ARC_STATUS
UefiDiskRead(ULONG FileId,VOID * Buffer,ULONG N,ULONG * Count)206 UefiDiskRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
207 {
208 DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
209 UCHAR* Ptr = (UCHAR*)Buffer;
210 ULONG Length, TotalSectors, MaxSectors, ReadSectors;
211 ULONGLONG SectorOffset;
212 BOOLEAN ret;
213
214 ASSERT(DiskReadBufferSize > 0);
215
216 TotalSectors = (N + Context->SectorSize - 1) / Context->SectorSize;
217 MaxSectors = DiskReadBufferSize / Context->SectorSize;
218 SectorOffset = Context->SectorOffset + Context->SectorNumber;
219
220 // If MaxSectors is 0, this will lead to infinite loop.
221 // In release builds assertions are disabled, however we also have sanity checks in DiskOpen()
222 ASSERT(MaxSectors > 0);
223
224 ret = TRUE;
225
226 while (TotalSectors)
227 {
228 ReadSectors = min(TotalSectors, MaxSectors);
229
230 ret = MachDiskReadLogicalSectors(Context->DriveNumber,
231 SectorOffset,
232 ReadSectors,
233 DiskReadBuffer);
234 if (!ret)
235 break;
236
237 Length = ReadSectors * Context->SectorSize;
238 Length = min(Length, N);
239
240 RtlCopyMemory(Ptr, DiskReadBuffer, Length);
241
242 Ptr += Length;
243 N -= Length;
244 SectorOffset += ReadSectors;
245 TotalSectors -= ReadSectors;
246 }
247
248 *Count = (ULONG)((ULONG_PTR)Ptr - (ULONG_PTR)Buffer);
249 Context->SectorNumber = SectorOffset - Context->SectorOffset;
250
251 return (ret ? ESUCCESS : EIO);
252 }
253
254 static
255 ARC_STATUS
UefiDiskSeek(ULONG FileId,LARGE_INTEGER * Position,SEEKMODE SeekMode)256 UefiDiskSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
257 {
258 DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
259 LARGE_INTEGER NewPosition = *Position;
260
261 switch (SeekMode)
262 {
263 case SeekAbsolute:
264 break;
265 case SeekRelative:
266 NewPosition.QuadPart += (Context->SectorNumber * Context->SectorSize);
267 break;
268 default:
269 ASSERT(FALSE);
270 return EINVAL;
271 }
272
273 if (NewPosition.QuadPart & (Context->SectorSize - 1))
274 return EINVAL;
275
276 /* Convert in number of sectors */
277 NewPosition.QuadPart /= Context->SectorSize;
278
279 /* HACK: CDROMs may have a SectorCount of 0 */
280 if (Context->SectorCount != 0 && NewPosition.QuadPart >= Context->SectorCount)
281 return EINVAL;
282
283 Context->SectorNumber = NewPosition.QuadPart;
284 return ESUCCESS;
285 }
286
287 static const DEVVTBL UefiDiskVtbl =
288 {
289 UefiDiskClose,
290 UefiDiskGetFileInformation,
291 UefiDiskOpen,
292 UefiDiskRead,
293 UefiDiskSeek,
294 };
295
296 static
297 VOID
GetHarddiskInformation(UCHAR DriveNumber)298 GetHarddiskInformation(UCHAR DriveNumber)
299 {
300 PMASTER_BOOT_RECORD Mbr;
301 PULONG Buffer;
302 ULONG i;
303 ULONG Checksum;
304 ULONG Signature;
305 BOOLEAN ValidPartitionTable;
306 CHAR ArcName[MAX_PATH];
307 PARTITION_TABLE_ENTRY PartitionTableEntry;
308 PCHAR Identifier = PcDiskIdentifier[DriveNumber - FIRST_BIOS_DISK];
309
310 /* Detect disk partition type */
311 DiskDetectPartitionType(DriveNumber);
312
313 /* Read the MBR */
314 if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
315 {
316 ERR("Reading MBR failed\n");
317 /* We failed, use a default identifier */
318 sprintf(Identifier, "BIOSDISK%d", DriveNumber - FIRST_BIOS_DISK);
319 return;
320 }
321
322 Buffer = (ULONG*)DiskReadBuffer;
323 Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
324
325 Signature = Mbr->Signature;
326 TRACE("Signature: %x\n", Signature);
327
328 /* Calculate the MBR checksum */
329 Checksum = 0;
330 for (i = 0; i < 512 / sizeof(ULONG); i++)
331 {
332 Checksum += Buffer[i];
333 }
334 Checksum = ~Checksum + 1;
335 TRACE("Checksum: %x\n", Checksum);
336
337 ValidPartitionTable = (Mbr->MasterBootRecordMagic == 0xAA55);
338
339 /* Fill out the ARC disk block */
340 sprintf(ArcName, "multi(0)disk(0)rdisk(%u)", DriveNumber - FIRST_BIOS_DISK);
341 AddReactOSArcDiskInfo(ArcName, Signature, Checksum, ValidPartitionTable);
342
343 sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(0)", DriveNumber - FIRST_BIOS_DISK);
344 FsRegisterDevice(ArcName, &UefiDiskVtbl);
345
346 /* Add partitions */
347 i = FIRST_PARTITION;
348 DiskReportError(FALSE);
349 while (DiskGetPartitionEntry(DriveNumber, i, &PartitionTableEntry))
350 {
351 if (PartitionTableEntry.SystemIndicator != PARTITION_ENTRY_UNUSED)
352 {
353 sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(%lu)", DriveNumber - FIRST_BIOS_DISK, i);
354 FsRegisterDevice(ArcName, &UefiDiskVtbl);
355 }
356 i++;
357 }
358 DiskReportError(TRUE);
359
360 InternalUefiDisk[DriveNumber].NumOfPartitions = i;
361 /* Convert checksum and signature to identifier string */
362 Identifier[0] = Hex[(Checksum >> 28) & 0x0F];
363 Identifier[1] = Hex[(Checksum >> 24) & 0x0F];
364 Identifier[2] = Hex[(Checksum >> 20) & 0x0F];
365 Identifier[3] = Hex[(Checksum >> 16) & 0x0F];
366 Identifier[4] = Hex[(Checksum >> 12) & 0x0F];
367 Identifier[5] = Hex[(Checksum >> 8) & 0x0F];
368 Identifier[6] = Hex[(Checksum >> 4) & 0x0F];
369 Identifier[7] = Hex[Checksum & 0x0F];
370 Identifier[8] = '-';
371 Identifier[9] = Hex[(Signature >> 28) & 0x0F];
372 Identifier[10] = Hex[(Signature >> 24) & 0x0F];
373 Identifier[11] = Hex[(Signature >> 20) & 0x0F];
374 Identifier[12] = Hex[(Signature >> 16) & 0x0F];
375 Identifier[13] = Hex[(Signature >> 12) & 0x0F];
376 Identifier[14] = Hex[(Signature >> 8) & 0x0F];
377 Identifier[15] = Hex[(Signature >> 4) & 0x0F];
378 Identifier[16] = Hex[Signature & 0x0F];
379 Identifier[17] = '-';
380 Identifier[18] = (ValidPartitionTable ? 'A' : 'X');
381 Identifier[19] = 0;
382 TRACE("Identifier: %s\n", Identifier);
383 }
384
385 static
386 VOID
UefiSetupBlockDevices(VOID)387 UefiSetupBlockDevices(VOID)
388 {
389 ULONG BlockDeviceIndex;
390 ULONG SystemHandleCount;
391 EFI_STATUS Status;
392 ULONG i;
393
394 UINTN handle_size = 0;
395 PcBiosDiskCount = 0;
396 UefiBootRootIdentifier = 0;
397
398 /* 1) Setup a list of boot handles by using the LocateHandle protocol */
399 Status = GlobalSystemTable->BootServices->LocateHandle(ByProtocol, &bioGuid, NULL, &handle_size, handles);
400 handles = MmAllocateMemoryWithType(handle_size, LoaderFirmwareTemporary);
401 Status = GlobalSystemTable->BootServices->LocateHandle(ByProtocol, &bioGuid, NULL, &handle_size, handles);
402 SystemHandleCount = handle_size / sizeof(EFI_HANDLE);
403 InternalUefiDisk = MmAllocateMemoryWithType(sizeof(INTERNAL_UEFI_DISK) * SystemHandleCount, LoaderFirmwareTemporary);
404
405 BlockDeviceIndex = 0;
406 /* 2) Parse the handle list */
407 for (i = 0; i < SystemHandleCount; ++i)
408 {
409 Status = GlobalSystemTable->BootServices->HandleProtocol(handles[i], &bioGuid, (void**)&bio);
410 if (handles[i] == PublicBootHandle)
411 {
412 OffsetToBoot = i; /* Drive offset in the handles list */
413 }
414
415 if (EFI_ERROR(Status) ||
416 bio == NULL ||
417 bio->Media->BlockSize == 0 ||
418 bio->Media->BlockSize > 4096)
419 {
420 TRACE("UefiSetupBlockDevices: UEFI has found a block device that failed, skipping\n");
421 continue;
422 }
423 if (bio->Media->LogicalPartition == FALSE)
424 {
425 TRACE("Found root of a HDD\n");
426 PcBiosDiskCount++;
427 InternalUefiDisk[BlockDeviceIndex].ArcDriveNumber = BlockDeviceIndex;
428 InternalUefiDisk[BlockDeviceIndex].UefiRootNumber = i;
429 GetHarddiskInformation(BlockDeviceIndex + FIRST_BIOS_DISK);
430 BlockDeviceIndex++;
431 }
432 else if (handles[i] == PublicBootHandle)
433 {
434 ULONG increment = 0;
435 ULONG i;
436
437 /* 3) Grab the offset into the array of handles and decrement per volume (valid partition) */
438 for (increment = OffsetToBoot; increment > 0; increment--)
439 {
440 GlobalSystemTable->BootServices->HandleProtocol(handles[increment], &bioGuid, (void**)&bio);
441 if (bio->Media->LogicalPartition == FALSE)
442 {
443 TRACE("Found root at increment %u\n", increment);
444 UefiBootRootIdentifier = increment;
445
446 for (i = 0; i <= PcBiosDiskCount; ++i)
447 {
448 /* Now only of the root drive number is equal to this drive we found above */
449 if (InternalUefiDisk[i].UefiRootNumber == UefiBootRootIdentifier)
450 {
451 InternalUefiDisk[i].IsThisTheBootDrive = TRUE;
452 PublicBootArcDisk = i;
453 TRACE("Found Boot drive\n");
454 }
455 }
456
457 break;
458 }
459 }
460 }
461 }
462 }
463
464 static
465 BOOLEAN
UefiSetBootpath(VOID)466 UefiSetBootpath(VOID)
467 {
468 TRACE("UefiSetBootpath: Setting up boot path\n");
469 GlobalSystemTable->BootServices->HandleProtocol(handles[UefiBootRootIdentifier], &bioGuid, (void**)&bio);
470 FrldrBootDrive = (FIRST_BIOS_DISK + PublicBootArcDisk);
471 if (bio->Media->RemovableMedia == TRUE && bio->Media->BlockSize == 2048)
472 {
473 /* Boot Partition 0xFF is the magic value that indicates booting from CD-ROM (see isoboot.S) */
474 FrldrBootPartition = 0xFF;
475 RtlStringCbPrintfA(FrLdrBootPath, sizeof(FrLdrBootPath),
476 "multi(0)disk(0)cdrom(%u)", PublicBootArcDisk);
477 }
478 else
479 {
480 ULONG BootPartition;
481 PARTITION_TABLE_ENTRY PartitionEntry;
482
483 /* This is a hard disk */
484 if (!UefiGetBootPartitionEntry(FrldrBootDrive, &PartitionEntry, &BootPartition))
485 {
486 ERR("Failed to get boot partition entry\n");
487 return FALSE;
488 }
489
490 RtlStringCbPrintfA(FrLdrBootPath, sizeof(FrLdrBootPath),
491 "multi(0)disk(0)rdisk(%u)partition(%lu)",
492 PublicBootArcDisk, BootPartition);
493 }
494
495 return TRUE;
496 }
497
498 BOOLEAN
UefiInitializeBootDevices(VOID)499 UefiInitializeBootDevices(VOID)
500 {
501 ULONG i = 0;
502
503 DiskReadBufferSize = EFI_PAGE_SIZE;
504 DiskReadBuffer = MmAllocateMemoryWithType(DiskReadBufferSize, LoaderFirmwareTemporary);
505 UefiSetupBlockDevices();
506 UefiSetBootpath();
507
508 /* Add it, if it's a cdrom */
509 GlobalSystemTable->BootServices->HandleProtocol(handles[UefiBootRootIdentifier], &bioGuid, (void**)&bio);
510 if (bio->Media->RemovableMedia == TRUE && bio->Media->BlockSize == 2048)
511 {
512 PMASTER_BOOT_RECORD Mbr;
513 PULONG Buffer;
514 ULONG Checksum = 0;
515 ULONG Signature;
516
517 /* Read the MBR */
518 if (!MachDiskReadLogicalSectors(FrldrBootDrive, 16ULL, 1, DiskReadBuffer))
519 {
520 ERR("Reading MBR failed\n");
521 return FALSE;
522 }
523
524 Buffer = (ULONG*)DiskReadBuffer;
525 Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
526
527 Signature = Mbr->Signature;
528 TRACE("Signature: %x\n", Signature);
529
530 /* Calculate the MBR checksum */
531 for (i = 0; i < 2048 / sizeof(ULONG); i++)
532 {
533 Checksum += Buffer[i];
534 }
535 Checksum = ~Checksum + 1;
536 TRACE("Checksum: %x\n", Checksum);
537
538 /* Fill out the ARC disk block */
539 AddReactOSArcDiskInfo(FrLdrBootPath, Signature, Checksum, TRUE);
540
541 FsRegisterDevice(FrLdrBootPath, &UefiDiskVtbl);
542 PcBiosDiskCount++; // This is not accounted for in the number of pre-enumerated BIOS drives!
543 TRACE("Additional boot drive detected: 0x%02X\n", (int)FrldrBootDrive);
544 }
545 return TRUE;
546 }
547
548 UCHAR
UefiGetFloppyCount(VOID)549 UefiGetFloppyCount(VOID)
550 {
551 /* No floppy for you for now... */
552 return 0;
553 }
554
555 BOOLEAN
UefiDiskReadLogicalSectors(IN UCHAR DriveNumber,IN ULONGLONG SectorNumber,IN ULONG SectorCount,OUT PVOID Buffer)556 UefiDiskReadLogicalSectors(
557 IN UCHAR DriveNumber,
558 IN ULONGLONG SectorNumber,
559 IN ULONG SectorCount,
560 OUT PVOID Buffer)
561 {
562 ULONG UefiDriveNumber;
563
564 UefiDriveNumber = InternalUefiDisk[DriveNumber - FIRST_BIOS_DISK].UefiRootNumber;
565 TRACE("UefiDiskReadLogicalSectors: DriveNumber: %d\n", UefiDriveNumber);
566 GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber], &bioGuid, (void**)&bio);
567
568 /* Devices setup */
569 bio->ReadBlocks(bio, bio->Media->MediaId, SectorNumber, SectorCount * bio->Media->BlockSize, Buffer);
570 return TRUE;
571 }
572
573 BOOLEAN
UefiDiskGetDriveGeometry(UCHAR DriveNumber,PGEOMETRY Geometry)574 UefiDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
575 {
576 ULONG UefiDriveNumber;
577
578 UefiDriveNumber = InternalUefiDisk[DriveNumber - FIRST_BIOS_DISK].UefiRootNumber;
579 GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber], &bioGuid, (void**)&bio);
580 Geometry->Cylinders = 1; // Not relevant for the UEFI BIO protocol
581 Geometry->Heads = 1; // Not relevant for the UEFI BIO protocol
582 Geometry->SectorsPerTrack = (bio->Media->LastBlock + 1);
583 Geometry->BytesPerSector = bio->Media->BlockSize;
584 Geometry->Sectors = (bio->Media->LastBlock + 1);
585
586 return TRUE;
587 }
588
589 ULONG
UefiDiskGetCacheableBlockCount(UCHAR DriveNumber)590 UefiDiskGetCacheableBlockCount(UCHAR DriveNumber)
591 {
592 ULONG UefiDriveNumber = InternalUefiDisk[DriveNumber - FIRST_BIOS_DISK].UefiRootNumber;
593 TRACE("UefiDiskGetCacheableBlockCount: DriveNumber: %d\n", UefiDriveNumber);
594
595 GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber], &bioGuid, (void**)&bio);
596 return (bio->Media->LastBlock + 1);
597 }
598