ReactOS 0.4.15-dev-7907-g95bf896
device.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING.ARM in the top level directory
3 * PROJECT: ReactOS UEFI Boot Library
4 * FILE: boot/environ/lib/io/device.c
5 * PURPOSE: Boot Library Device Management Routines
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include "bl.h"
12
13/* DATA VARIABLES ************************************************************/
14
16{
20
25
27
28/* FUNCTIONS *****************************************************************/
29
31{
35
38
42
45
48
50
53
55
57
61 _In_ PBL_DEVICE_ENTRY DeviceEntry
62 );
63
66 _In_ PBL_DEVICE_ENTRY DeviceEntry,
67 _Out_ PBL_DEVICE_INFORMATION DeviceInformation
68 );
69
72 _In_ PBL_DEVICE_ENTRY DeviceEntry,
73 _Out_ PBL_DEVICE_INFORMATION DeviceInformation
74 );
75
78 _In_ PBL_DEVICE_ENTRY DeviceEntry,
82 );
83
85{
86 NULL,
88 NULL,
90 NULL,
93};
94
99 _In_ ULONGLONG Block,
100 _In_ ULONGLONG BlockCount
101 )
102{
104}
105
110 _In_ ULONGLONG Block,
111 _In_ ULONGLONG BlockCount
112 )
113{
115 EFI_BLOCK_IO *BlockProtocol;
116 BL_ARCH_MODE OldMode;
117 EFI_STATUS EfiStatus;
118 ULONG FailureCount;
119
120 for (FailureCount = 0, Status = STATUS_SUCCESS;
121 FailureCount < 2 && NT_SUCCESS(Status);
122 FailureCount++)
123 {
124 BlockProtocol = BlockDevice->Protocol;
125
126 OldMode = CurrentExecutionContext->Mode;
128 {
130 break;
131 }
132
133 //EfiPrintf(L"EFI Reading BLOCK %d off media %lx (%d blocks)\r\n",
134 //Block, BlockProtocol->Media->MediaId, BlockCount);
135 EfiStatus = BlockProtocol->ReadBlocks(BlockProtocol,
136 BlockProtocol->Media->MediaId,
137 Block,
138 BlockProtocol->Media->BlockSize * BlockCount,
139 Buffer);
140 if (EfiStatus == EFI_SUCCESS)
141 {
142 //EfiPrintf(L"EFI Read complete into buffer\r\n");
143 //EfiPrintf(L"Buffer data: %lx %lx %lx %lx\r\n", *(PULONG)Buffer, *((PULONG)Buffer + 1), *((PULONG)Buffer + 2), *((PULONG)Buffer + 3));
144 }
145
146 if (OldMode != 1)
147 {
148 BlpArchSwitchContext(OldMode);
149 }
150
151 Status = EfiGetNtStatusCode(EfiStatus);
153 {
154 break;
155 }
156
158
161 (PVOID*)BlockDevice->Protocol);
162 }
163
164 return Status;
165}
166
169 PBL_DEVICE_ENTRY DeviceEntry,
171 _In_ ULONGLONG Block,
172 _In_ ULONGLONG BlockCount,
173 _In_ ULONG OperationType
174 )
175{
176 ULONG FailureCount;
179
180 BlockDevice = DeviceEntry->DeviceSpecificData;
181
182 if (OperationType == 1)
183 {
184 for (FailureCount = 0; FailureCount < 3; FailureCount++)
185 {
186 Status = BlockIoFirmwareWrite(BlockDevice, Buffer, Block, BlockCount);
187 if (Status >= 0)
188 {
189 break;
190 }
191 }
192 }
193 else
194 {
195 for (FailureCount = 0; FailureCount < 3; FailureCount++)
196 {
197 Status = BlockIoFirmwareRead(BlockDevice, Buffer, Block, BlockCount);
198 if (Status >= 0)
199 {
200 break;
201 }
202 }
203 }
204 return Status;
205}
206
211 )
212{
214
215 if (*BufferSize)
216 {
218
219 *Buffer = NULL;
220 *BufferSize = 0;
221 }
222 else
223 {
225 }
226
227 return Status;
228}
229
236 )
237{
239
240 if (!Alignment)
241 {
242 ++Alignment;
243 }
244
246 if ((Size > *BufferSize) || ((Alignment - 1) & (ULONG_PTR)*Buffer))
247 {
249
251
255 0,
257 NULL,
258 0);
259 if (!NT_SUCCESS(Status))
260 {
261 *BufferSize = 0;
262 }
263 }
264
265 return Status;
266}
267
270 _In_ PBL_DEVICE_ENTRY DeviceEntry,
272 _In_ ULONG BlockCount
273 )
274{
275 EfiPrintf(L"No prefetch support\r\n");
277}
278
281 _In_ PBL_DEVICE_ENTRY DeviceEntry,
283 _In_ ULONG BlockCount,
284 _In_ ULONG OperationType
285 )
286{
291
292 BlockDevice = DeviceEntry->DeviceSpecificData;
293 BufferSize = BlockDevice->BlockSize * BlockCount;
294 Offset = BlockDevice->Block + BlockDevice->StartOffset;
295 if ((BlockDevice->LastBlock + 1) < (BlockDevice->Block + BlockCount))
296 {
297 EfiPrintf(L"Read past end of device\r\n");
299 }
300
301 Alignment = BlockDevice->Alignment;
302 if (!(Alignment) || !((Alignment - 1) & (ULONG_PTR)Buffer))
303 {
304 Status = BlockIopFirmwareOperation(DeviceEntry,
305 Buffer,
306 Offset,
307 BlockCount,
308 OperationType);
309 if (!NT_SUCCESS(Status))
310 {
311 EfiPrintf(L"EFI op failed: %lx\r\n", Status);
312 return Status;
313 }
314
315 return STATUS_SUCCESS;
316 }
317
321 BlockDevice->Alignment);
322 if (!NT_SUCCESS(Status))
323 {
324 EfiPrintf(L"No memory for align\r\n");
325 return STATUS_NO_MEMORY;
326 }
327
328 if (OperationType == 1)
329 {
331 }
332
333 Status = BlockIopFirmwareOperation(DeviceEntry,
335 Offset,
336 BlockCount,
337 OperationType);
338 if (!NT_SUCCESS(Status))
339 {
340 return Status;
341 }
342
343 if (!OperationType)
344 {
346 }
347
348 return STATUS_SUCCESS;
349}
350
353 _In_ PBL_DEVICE_ENTRY DeviceEntry,
358 )
359{
361}
362
365 _In_ PBL_DEVICE_ENTRY DeviceEntry,
369 )
370{
373 ULONGLONG OffsetEnd, AlignedOffsetEnd, Offset;
375
376 BlockDevice = DeviceEntry->DeviceSpecificData;
378 OffsetEnd = Size + BlockDevice->Offset;
379 if (OffsetEnd < Size)
380 {
381 OffsetEnd = -1;
383 }
384
385 AlignedOffsetEnd = ~(BlockDevice->BlockSize - 1) & (OffsetEnd + BlockDevice->BlockSize - 1);
386 if (AlignedOffsetEnd < OffsetEnd)
387 {
389 }
390
391 if ((BlockDevice->Offset) || (Size != AlignedOffsetEnd))
392 {
395 AlignedOffsetEnd,
396 BlockDevice->Alignment);
397 if (!NT_SUCCESS(Status))
398 {
399 EfiPrintf(L"Failed to allocate buffer: %lx\r\n", Status);
400 return Status;
401 }
402
404 }
405
406 Offset = AlignedOffsetEnd / BlockDevice->BlockSize;
407
408 if (BlockDevice->Unknown & 2)
409 {
410 Status = BlockIopReadUsingPrefetch(DeviceEntry,
412 AlignedOffsetEnd / BlockDevice->BlockSize);
413 if (NT_SUCCESS(Status))
414 {
415 goto ReadComplete;
416 }
417 }
418
419 Status = BlockIopOperation(DeviceEntry, ReadBuffer, Offset, 0);
420 if (!NT_SUCCESS(Status))
421 {
422 EfiPrintf(L"Block I/O failed: %lx\r\n", Status);
423 return Status;
424 }
425
426 BlockDevice->Block += Offset;
427
428ReadComplete:
429 if (ReadBuffer != Buffer)
430 {
433 (ULONG_PTR)BlockDevice->Offset),
434 Size);
435 }
436
437 if (BytesRead)
438 {
439 *BytesRead = Size;
440 }
441
442 return STATUS_SUCCESS;
443}
444
448 _In_opt_ PULONG DesiredSize,
450 _Out_opt_ PULONG OutputAdjustedSize
451 )
452{
453 ULONG RealSize;
454 ULONGLONG Offset, LastOffset, RemainingOffset, MaxOffset;
456
457 RealSize = 0;
458
459 Offset = (BlockDevice->Offset * BlockDevice->BlockSize) + BlockDevice->Block;
460
461 if (Offset > ((BlockDevice->LastBlock + 1) * BlockDevice->BlockSize))
462 {
464 goto Quickie;
465 }
466
467 LastOffset = (BlockDevice->LastBlock * BlockDevice->BlockSize) + BlockDevice->BlockSize - 1;
468
469 MaxOffset = BlockDevice->LastBlock;
470 if (MaxOffset < BlockDevice->BlockSize)
471 {
472 MaxOffset = BlockDevice->BlockSize;
473 }
474
475 if (LastOffset < MaxOffset)
476 {
477
479 goto Quickie;
480 }
481
482 if (Offset > LastOffset)
483 {
485 goto Quickie;
486 }
487
488 RemainingOffset = LastOffset - Offset + 1;
489
490 if (DesiredSize != FALSE)
491 {
492 RealSize = *DesiredSize;
493 }
494 else
495 {
496 RealSize = ULONG_MAX;
497 }
498
499 if (RemainingOffset < RealSize)
500 {
501 if (Size == FALSE)
502 {
503 RealSize = 0;
505 goto Quickie;
506 }
507
508 RealSize = RemainingOffset;
509 }
510
512
513Quickie:
514 if (Size)
515 {
516 *Size = RealSize;
517 }
518
519 return Status;
520}
521
524 _In_ PBL_DEVICE_ENTRY DeviceEntry,
528 )
529{
532
533 /* Get the device-specific data, which is our block device descriptor */
534 BlockDevice = DeviceEntry->DeviceSpecificData;
535
536 /* Make sure that the buffer and size is valid */
538 if (NT_SUCCESS(Status))
539 {
540 /* Check if this is a virtual device or a physical device */
541 if (BlockDevice->DeviceFlags & BL_BLOCK_DEVICE_VIRTUAL_FLAG)
542 {
543 /* Do a virtual read or write */
545 }
546 else
547 {
548 /* Do a physical read or write */
550 }
551 }
552 else if (BytesRead)
553 {
554 /* We failed, if the caller wanted bytes read, return 0 */
555 *BytesRead = 0;
556 }
557
558 /* Return back to the caller */
559 return Status;
560}
561
564 _In_ PBL_DEVICE_ENTRY DeviceEntry,
565 _Out_ PBL_DEVICE_INFORMATION DeviceInformation
566 )
567{
570
571 BlockDevice = DeviceEntry->DeviceSpecificData;
572
573 /* Take the current block number and block-offset and conver to full offset */
574 Offset = DeviceInformation->BlockDeviceInfo.Block * BlockDevice->BlockSize +
575 DeviceInformation->BlockDeviceInfo.Offset;
576
577 /* Make sure that the full offset is still within the bounds of the device */
578 if (Offset > ((BlockDevice->LastBlock + 1) * BlockDevice->BlockSize - 1))
579 {
580 EfiPrintf(L"Offset out of bounds\r\n");
582 }
583
584 /* Convery the full raw offset into a block number and block-offset */
585 BlockDevice->Block = Offset / BlockDevice->BlockSize;
586 BlockDevice->Offset = Offset % BlockDevice->BlockSize;
587
588 /* Return the unknown */
589 BlockDevice->Unknown = DeviceInformation->BlockDeviceInfo.Unknown;
590
591 /* All done */
592 return STATUS_SUCCESS;
593}
594
597 _In_ PBL_DEVICE_ENTRY DeviceEntry,
598 _Out_ PBL_DEVICE_INFORMATION DeviceInformation
599 )
600{
601 /* Copy the device specific data into the block device information */
602 RtlCopyMemory(&DeviceInformation->BlockDeviceInfo,
603 DeviceEntry->DeviceSpecificData,
604 sizeof(DeviceInformation->BlockDeviceInfo));
605
606 /* Hardcode the device type */
607 DeviceInformation->DeviceType = DiskDevice;
608 return STATUS_SUCCESS;
609}
610
613 _In_ PBL_DEVICE_DESCRIPTOR InputDevice,
614 _Outptr_ PBL_DEVICE_DESCRIPTOR* VirtualDevice
615 )
616{
617 BOOLEAN IsVirtual;
618 PBL_LOCAL_DEVICE ParentDisk;
619
620 /* Assume it isn't */
621 IsVirtual = FALSE;
622
623 /* Check if this is a partition device */
624 if ((InputDevice->DeviceType == LegacyPartitionDevice) ||
625 (InputDevice->DeviceType == PartitionDevice))
626 {
627 /* Check if the parent disk is a VHD */
628 ParentDisk = &InputDevice->Partition.Disk;
629 if (ParentDisk->Type == VirtualDiskDevice)
630 {
631 /* This is a virtual partition device -- does the caller want it? */
632 IsVirtual = TRUE;
633 if (VirtualDevice)
634 {
635 *VirtualDevice = (PBL_DEVICE_DESCRIPTOR)(&ParentDisk->VirtualHardDisk + 1);
636 }
637 }
638 }
639
640 /* Return */
641 return IsVirtual;
642}
643
646 _In_ ULONG DeviceId,
647 _Out_ PBL_DEVICE_INFORMATION DeviceInformation
648 )
649{
650 PBL_DEVICE_ENTRY DeviceEntry;
651
652 /* This parameter is not optional */
653 if (!DeviceInformation)
654 {
656 }
657
658 /* Make sure the device ID is valid */
659 if (DmTableEntries <= DeviceId)
660 {
662 }
663
664 /* Get the device entry */
665 DeviceEntry = DmDeviceTable[DeviceId];
666 if (!DeviceEntry)
667 {
669 }
670
671 /* Make sure the device is open */
672 if (!(DeviceEntry->Flags & BL_DEVICE_ENTRY_OPENED))
673 {
675 }
676
677 /* Set the device information */
678 return DeviceEntry->Callbacks.SetInformation(DeviceEntry, DeviceInformation);
679}
680
683 _In_ ULONG DeviceId,
684 _Out_ PBL_DEVICE_INFORMATION DeviceInformation
685 )
686{
687 PBL_DEVICE_ENTRY DeviceEntry;
688
689 /* This parameter is not optional */
690 if (!DeviceInformation)
691 {
693 }
694
695 /* Make sure the device ID is valid */
696 if (DmTableEntries <= DeviceId)
697 {
699 }
700
701 /* Get the device entry */
702 DeviceEntry = DmDeviceTable[DeviceId];
703 if (!DeviceEntry)
704 {
706 }
707
708 /* Make sure the device is open */
709 if (!(DeviceEntry->Flags & BL_DEVICE_ENTRY_OPENED))
710 {
712 }
713
714 /* Return the device information */
715 DeviceInformation->DeviceType = DeviceEntry->DeviceDescriptor->DeviceType;
716 return DeviceEntry->Callbacks.GetInformation(DeviceEntry, DeviceInformation);
717}
718
721 _In_ ULONG DeviceId,
725 )
726{
727 PBL_DEVICE_ENTRY DeviceEntry;
730
731 /* Make sure we have a buffer, and the device ID is valid */
732 if (!(Buffer) || (DmTableEntries <= DeviceId))
733 {
735 }
736
737 /* Get the device entry for it */
738 DeviceEntry = DmDeviceTable[DeviceId];
739 if (!DeviceEntry)
740 {
742 }
743
744 /* Make sure this is a device opened for read access */
745 if (!(DeviceEntry->Flags & BL_DEVICE_ENTRY_OPENED) ||
746 !(DeviceEntry->Flags & BL_DEVICE_ENTRY_READ_ACCESS))
747 {
749 }
750
751 /* Issue the read */
752 Status = DeviceEntry->Callbacks.Read(DeviceEntry,
753 Buffer,
754 Size,
756 if (!DeviceEntry->Unknown)
757 {
758 /* Update performance counters */
760 }
761
762 /* Return back how many bytes were read, if caller wants to know */
763 if (BytesRead)
764 {
766 }
767
768 /* Return read result */
769 return Status;
770}
771
774 _In_ ULONG DeviceId,
779 )
780{
783
784 /* Get the current block and offset */
786 if (!NT_SUCCESS(Status))
787 {
788 return Status;
789 }
790
791 /* Get the block and block-offset based on the new raw offset */
792 DeviceInfo.BlockDeviceInfo.Block = Offset / DeviceInfo.BlockDeviceInfo.BlockSize;
793 DeviceInfo.BlockDeviceInfo.Offset = Offset % DeviceInfo.BlockDeviceInfo.BlockSize;
794
795 /* Update the block and offset */
797 if (NT_SUCCESS(Status))
798 {
799 /* Now issue a read, with this block and offset configured */
800 Status = BlDeviceRead(DeviceId, Buffer, Size, BytesRead);
801 }
802
803 /* All good, return the caller */
804 return Status;
805}
806
811 )
812{
813 BOOLEAN DeviceMatch;
814 ULONG DeviceSize;
815
816 /* Assume failure */
817 DeviceMatch = FALSE;
818
819 /* Check if the two devices exist and are identical in type */
820 if ((Device1) && (Device2) && (Device1->DeviceType == Device2->DeviceType))
821 {
822 /* Take the bigger of the two sizes */
823 DeviceSize = max(Device1->Size, Device2->Size);
824 if (DeviceSize >= (ULONG)FIELD_OFFSET(BL_DEVICE_DESCRIPTOR, Local))
825 {
826 /* Compare the two devices up to their size */
827 if (RtlEqualMemory(&Device1->Local,
828 &Device2->Local,
829 DeviceSize - FIELD_OFFSET(BL_DEVICE_DESCRIPTOR, Local)))
830 {
831 /* They match! */
832 DeviceMatch = TRUE;
833 }
834 }
835 }
836
837 /* Return matching state */
838 return DeviceMatch;
839}
840
844 )
845{
846 /* If a block device was passed in, free it */
847 if (BlockDevice)
848 {
850 }
851
852 /* Nothing else to do */
853 return STATUS_SUCCESS;
854}
855
859 )
860{
862 EFI_BLOCK_IO_MEDIA *Media;
863
864 /* Open the Block I/O protocol on this device */
867 (PVOID*)&BlockDevice->Protocol);
868 if (!NT_SUCCESS(Status))
869 {
870 return Status;
871 }
872
873 /* Get information on the block media */
874 Media = BlockDevice->Protocol->Media;
875
876 /* Set the appropriate device flags */
877 BlockDevice->DeviceFlags = 0;
878 if (Media->RemovableMedia)
879 {
881 }
882 if (Media->MediaPresent)
883 {
885 }
886
887 /* No clue */
888 BlockDevice->Unknown = 0;
889
890 /* Set the block size */
891 BlockDevice->BlockSize = Media->BlockSize;
892
893 /* Make sure there's a last block value */
894 if (!Media->LastBlock)
895 {
897 }
898
899 /* Don't let it be too high */
900 if (Media->LastBlock > 0xFFFFFFFFFFE)
901 {
902 BlockDevice->LastBlock = 0xFFFFFFFFFFE;
903 }
904 else
905 {
906 BlockDevice->LastBlock = Media->LastBlock;
907 }
908
909 /* Make the alignment the smaller of the I/O alignment or the block size */
910 if (Media->IoAlign >= Media->BlockSize)
911 {
912 BlockDevice->Alignment = Media->IoAlign;
913 }
914 else
915 {
916 BlockDevice->Alignment = Media->BlockSize;
917 }
918
919 /* All good */
920 return STATUS_SUCCESS;
921}
922
925 _In_ PBL_PROTOCOL_HANDLE ProtocolInterface,
926 _In_ PBL_PROTOCOL_HANDLE ChildProtocolInterface)
927{
930 EFI_DEVICE_PATH *DevicePath, *ParentDevicePath;
931 EFI_HANDLE *DeviceHandles;
933
934 /* Find all the Block I/O device handles on the system */
935 DeviceCount = 0;
936 DeviceHandles = 0;
940 &DeviceHandles);
941 if (!NT_SUCCESS(Status))
942 {
943 /* Failed to enumerate, bail out */
944 return Status;
945 }
946
947 /* Loop all the handles */
948 for (i = 0; i < DeviceCount; i++)
949 {
950 /* Check if this is the device itself */
951 Handle = DeviceHandles[i];
952 if (Handle == ProtocolInterface->Handle)
953 {
954 /* Skip it */
955 continue;
956 }
957
958 /* Get the device path of this device */
961 (PVOID*)&DevicePath);
962 if (!NT_SUCCESS(Status))
963 {
964 /* We failed, skip it */
965 continue;
966 }
967
968 /* See if we are its parent */
969 ParentDevicePath = EfiIsDevicePathParent(ProtocolInterface->Interface,
970 DevicePath);
971 if (ParentDevicePath == ProtocolInterface->Interface)
972 {
973 /* Yup, return back to caller */
974 ChildProtocolInterface->Handle = Handle;
975 ChildProtocolInterface->Interface = DevicePath;
977 goto Quickie;
978 }
979
980 /* Close the device path */
982 }
983
984 /* If we got here, nothing was found */
986
987Quickie:
988 /* Free the handle array buffer */
989 BlMmFreeHeap(DeviceHandles);
990 return Status;
991}
992
995 _In_ PBL_DEVICE_ENTRY DeviceEntry,
996 _Out_ PGUID DiskSignature
997 )
998{
999 EfiPrintf(L"GPT not supported\r\n");
1001}
1002
1005 _In_ PBL_DEVICE_ENTRY DeviceEntry
1006 )
1007{
1011 EFI_DEVICE_PATH *LeafNode;
1013 ACPI_HID_DEVICE_PATH *AcpiPath;
1014 HARDDRIVE_DEVICE_PATH *DiskPath;
1015 BOOLEAN Found;
1016 ULONG i;
1017
1018 /* Extract the identifier, and the block device object */
1019 Device = DeviceEntry->DeviceDescriptor;
1020 BlockDevice = (PBL_BLOCK_DEVICE)DeviceEntry->DeviceSpecificData;
1021
1022 /* Initialize protocol handles */
1023 Protocol[0].Handle = BlockDevice->Handle;
1024 Protocol[1].Handle = 0;
1025
1026 /* Open this device */
1029 &Protocol[0].Interface);
1030 if (!NT_SUCCESS(Status))
1031 {
1032 /* Fail */
1033 return Status;
1034 }
1035
1036 /* Iterate twice -- once for the top level, once for the bottom */
1037 for (i = 0, Found = FALSE; Found == FALSE && Protocol[i].Handle; i++)
1038 {
1039 /* Check what kind of leaf node device this is */
1040 LeafNode = EfiGetLeafNode(Protocol[i].Interface);
1041 EfiPrintf(L"Pass %d, Leaf node: %p Type: %d\r\n", i, LeafNode, LeafNode->Type);
1042 if (LeafNode->Type == ACPI_DEVICE_PATH)
1043 {
1044 /* We only support floppy drives */
1045 AcpiPath = (ACPI_HID_DEVICE_PATH*)LeafNode;
1046 if ((AcpiPath->HID == EISA_PNP_ID(0x604)) ||
1047 (AcpiPath->HID == EISA_PNP_ID(0x700)))
1048 {
1049 /* Set the boot library specific device types */
1050 Device->DeviceType = LocalDevice;
1051 Device->Local.Type = FloppyDevice;
1052
1053 /* The ACPI UID is the drive number */
1054 Device->Local.FloppyDisk.DriveNumber = AcpiPath->UID;
1055
1056 /* We found a match */
1057 Found = TRUE;
1058 }
1059 }
1060 else if ((LeafNode->Type == MEDIA_DEVICE_PATH) && (i == 1))
1061 {
1062 /* Extract the disk path and check if it's a physical disk */
1063 DiskPath = (HARDDRIVE_DEVICE_PATH*)LeafNode;
1064 EfiPrintf(L"Disk path: %p Type: %lx\r\n", DiskPath, LeafNode->SubType);
1065 if (LeafNode->SubType == MEDIA_HARDDRIVE_DP)
1066 {
1067 /* Set this as a local device */
1068 Device->Local.Type = LocalDevice;
1069
1070 /* Check if this is an MBR partition */
1071 if (DiskPath->SignatureType == SIGNATURE_TYPE_MBR)
1072 {
1073 /* Set that this is a local partition */
1074 Device->DeviceType = LegacyPartitionDevice;
1075 Device->Partition.Disk.Type = LocalDevice;
1076
1077 /* Write the MBR partition signature */
1078 BlockDevice->PartitionType = MbrPartition;
1079 BlockDevice->Disk.Mbr.Signature = *(PULONG)&DiskPath->Signature[0];
1080 Found = TRUE;
1081 }
1082 else if (DiskPath->SignatureType == SIGNATURE_TYPE_GUID)
1083 {
1084 /* Set this as a GPT partition */
1085 BlockDevice->PartitionType = GptPartition;
1086 Device->Local.HardDisk.PartitionType = GptPartition;
1087
1088 /* Get the GPT signature */
1089 Status = BlockIoGetGPTDiskSignature(DeviceEntry,
1090 &Device->Local.HardDisk.Gpt.PartitionSignature);
1091 if (NT_SUCCESS(Status))
1092 {
1093 /* Copy it */
1094 RtlCopyMemory(&BlockDevice->Disk.Gpt.Signature,
1095 &Device->Local.HardDisk.Gpt.PartitionSignature,
1096 sizeof(BlockDevice->Disk.Gpt.Signature));
1097 Found = TRUE;
1098 }
1099 }
1100
1101 /* Otherwise, this is a raw disk */
1102 BlockDevice->PartitionType = RawPartition;
1103 Device->Local.HardDisk.PartitionType = RawPartition;
1104 Device->Local.HardDisk.Raw.DiskNumber = BlockIoFirmwareRawDiskCount++;
1105 }
1106 else if (LeafNode->SubType == MEDIA_CDROM_DP)
1107 {
1108 /* Set block device information */
1109 EfiPrintf(L"Found CD-ROM\r\n");
1110 BlockDevice->PartitionType = RawPartition;
1111 BlockDevice->Type = CdRomDevice;
1112
1113 /* Set CDROM data */
1114 Device->Local.Type = CdRomDevice;
1115 Device->Local.FloppyDisk.DriveNumber = 0;
1116 Found = TRUE;
1117 }
1118 }
1119 else if ((LeafNode->Type != MEDIA_DEVICE_PATH) &&
1120 (LeafNode->Type != ACPI_DEVICE_PATH) &&
1121 (i == 0))
1122 {
1123 /* This is probably a messaging device node. Are we under it? */
1125 EfiPrintf(L"Pass 0, non DP/ACPI path. Child handle obtained: %lx\r\n", Protocol[1].Handle);
1126 if (!NT_SUCCESS(Status))
1127 {
1128 /* We're not. So this must be a raw device */
1129 Device->DeviceType = LocalDevice;
1130 Found = TRUE;
1131
1132 /* Is it a removable raw device? */
1134 {
1135 /* This is a removable (CD or Floppy or USB) device */
1136 BlockDevice->Type = FloppyDevice;
1137 Device->Local.Type = FloppyDevice;
1138 Device->Local.FloppyDisk.DriveNumber = BlockIoFirmwareRemovableDiskCount++;
1139 EfiPrintf(L"Found Floppy\r\n");
1140 }
1141 else
1142 {
1143 /* It's a fixed device */
1144 BlockDevice->Type = DiskDevice;
1145 Device->Local.Type = DiskDevice;
1146
1147 /* Set it as a raw partition */
1148 Device->Local.HardDisk.PartitionType = RawPartition;
1149 Device->Local.HardDisk.Mbr.PartitionSignature = BlockIoFirmwareRawDiskCount++;
1150 EfiPrintf(L"Found raw disk\r\n");
1151 }
1152 }
1153 }
1154 }
1155
1156 /* Close any protocols that we opened for each handle */
1157 while (i)
1158 {
1160 }
1161
1162 /* Return appropriate status */
1164}
1165
1168 VOID
1169 )
1170{
1171 EfiPrintf(L"not implemented\r\n");
1173}
1174
1177 VOID
1178 )
1179{
1180 EfiPrintf(L"not implemented\r\n");
1182}
1183
1186 _In_ PBL_DEVICE_ENTRY *DeviceEntry,
1188 )
1189{
1190 PBL_DEVICE_ENTRY IoDeviceEntry;
1194
1195 /* Allocate the entry for this device and zero it out */
1196 IoDeviceEntry = BlMmAllocateHeap(sizeof(*IoDeviceEntry));
1197 if (!IoDeviceEntry)
1198 {
1199 return STATUS_NO_MEMORY;
1200 }
1201 RtlZeroMemory(IoDeviceEntry, sizeof(*IoDeviceEntry));
1202
1203 /* Allocate the device descriptor for this device and zero it out */
1204 Device = BlMmAllocateHeap(sizeof(*Device));
1205 if (!Device)
1206 {
1207 return STATUS_NO_MEMORY;
1208 }
1209 RtlZeroMemory(Device, sizeof(*Device));
1210
1211 /* Allocate the block device specific data, and zero it out */
1213 if (!BlockDevice)
1214 {
1215 return STATUS_NO_MEMORY;
1216 }
1218
1219 /* Save the descriptor and block device specific data */
1220 IoDeviceEntry->DeviceSpecificData = BlockDevice;
1221 IoDeviceEntry->DeviceDescriptor = Device;
1222
1223 /* Set the size of the descriptor */
1224 Device->Size = sizeof(*Device);
1225
1226 /* Copy the standard I/O callbacks */
1227 RtlCopyMemory(&IoDeviceEntry->Callbacks,
1229 sizeof(IoDeviceEntry->Callbacks));
1230
1231 /* Add the two that are firmware specific */
1232 IoDeviceEntry->Callbacks.Reset = BlockIoEfiReset;
1233 IoDeviceEntry->Callbacks.Flush = BlockIoEfiFlush;
1234
1235 /* Save the EFI handle */
1236 BlockDevice->Handle = Handle;
1237
1238 /* Get information on this device from EFI, caching it in the device */
1240 if (NT_SUCCESS(Status))
1241 {
1242 /* Build the descriptor structure for this device */
1243 Status = BlockIoEfiGetDeviceInformation(IoDeviceEntry);
1244 if (NT_SUCCESS(Status))
1245 {
1246 /* We have a fully constructed device, return it */
1247 *DeviceEntry = IoDeviceEntry;
1248 return STATUS_SUCCESS;
1249 }
1250 }
1251
1252 /* Failure path, free the descriptor if we allocated one */
1253 if (IoDeviceEntry->DeviceDescriptor)
1254 {
1255 BlMmFreeHeap(IoDeviceEntry->DeviceDescriptor);
1256 }
1257
1258 /* Free any other specific allocations */
1260
1261 /* Free the device entry itself and return the failure code */
1262 BlMmFreeHeap(IoDeviceEntry);
1263 EfiPrintf(L"Failed: %lx\r\n", Status);
1264 return Status;
1265}
1266
1271 )
1272{
1273 PBL_LOCAL_DEVICE LocalDeviceInfo, EfiLocalDeviceInfo;
1274 PBL_DEVICE_ENTRY DeviceEntry;
1275 PBL_DEVICE_DESCRIPTOR EfiDevice;
1277
1278 DeviceEntry = NULL;
1279
1280 /* Check if no device was given */
1281 if (!Device)
1282 {
1283 /* Fail the comparison */
1285 goto Quickie;
1286 }
1287
1288 /* Check if this is a local disk device */
1289 if (Device->DeviceType != DiskDevice)
1290 {
1291 /* Nope -- is it a partition device? */
1292 if ((Device->DeviceType != LegacyPartitionDevice) &&
1293 (Device->DeviceType != PartitionDevice))
1294 {
1295 /* Nope, so we can't compare */
1297 goto Quickie;
1298 }
1299
1300 /* If so, return the device information for the parent disk */
1301 LocalDeviceInfo = &Device->Partition.Disk;
1302 }
1303 else
1304 {
1305 /* Just return the disk information itself */
1306 LocalDeviceInfo = &Device->Local;
1307 }
1308
1309 /* Create an EFI device entry for the EFI device handle */
1310 Status = BlockIoEfiCreateDeviceEntry(&DeviceEntry, Handle);
1311 if (!NT_SUCCESS(Status))
1312 {
1313 goto Quickie;
1314 }
1315
1316 /* Read the descriptor and assume failure for now */
1317 EfiDevice = DeviceEntry->DeviceDescriptor;
1319
1320 /* Check if the EFI device is a disk */
1321 if (EfiDevice->DeviceType != DiskDevice)
1322 {
1323 /* Nope, is it a partition? */
1324 if ((EfiDevice->DeviceType != LegacyPartitionDevice) &&
1325 (EfiDevice->DeviceType != PartitionDevice))
1326 {
1327 /* Neither, invalid handle so bail out */
1329 goto Quickie;
1330 }
1331
1332 /* Yes, so get the information of the parent disk */
1333 EfiLocalDeviceInfo = &EfiDevice->Partition.Disk;
1334 }
1335 else
1336 {
1337 /* It's a disk, so get the disk information itself */
1338 EfiLocalDeviceInfo = &EfiDevice->Local;
1339 }
1340
1341 /* Are the two devices the same type? */
1342 if (EfiLocalDeviceInfo->Type != LocalDeviceInfo->Type)
1343 {
1344 /* Nope, that was easy */
1345 goto Quickie;
1346 }
1347
1348 /* Yes, what kind of device is the EFI side? */
1349 switch (EfiLocalDeviceInfo->Type)
1350 {
1351 case LocalDevice:
1352
1353 /* Local hard drive, compare the signature */
1354 if (RtlCompareMemory(&EfiLocalDeviceInfo->HardDisk,
1355 &LocalDeviceInfo->HardDisk,
1356 sizeof(LocalDeviceInfo->HardDisk)) ==
1357 sizeof(LocalDeviceInfo->HardDisk))
1358 {
1360 }
1361 break;
1362
1363 case FloppyDevice:
1364 case CdRomDevice:
1365
1366 /* Removable floppy or CD, compare the disk number */
1367 if (RtlCompareMemory(&EfiLocalDeviceInfo->FloppyDisk,
1368 &LocalDeviceInfo->FloppyDisk,
1369 sizeof(LocalDeviceInfo->FloppyDisk)) ==
1370 sizeof(LocalDeviceInfo->FloppyDisk))
1371 {
1373 }
1374 break;
1375
1376 case RamDiskDevice:
1377
1378 /* RAM disk, compare the size and base information */
1379 if (RtlCompareMemory(&EfiLocalDeviceInfo->RamDisk,
1380 &LocalDeviceInfo->RamDisk,
1381 sizeof(LocalDeviceInfo->RamDisk)) ==
1382 sizeof(LocalDeviceInfo->RamDisk))
1383 {
1385 }
1386 break;
1387
1388 case FileDevice:
1389
1390 /* File, compare the file identifier */
1391 if (RtlCompareMemory(&EfiLocalDeviceInfo->File,
1392 &LocalDeviceInfo->File,
1393 sizeof(LocalDeviceInfo->File)) ==
1394 sizeof(LocalDeviceInfo->File))
1395 {
1397 }
1398 break;
1399
1400 /* Something else we don't support */
1401 default:
1402 break;
1403 }
1404
1405Quickie:
1406 /* All done, did we have an EFI device entry? */
1407 if (DeviceEntry)
1408 {
1409 /* Free it, since we only needed it locally for comparison */
1410 BlMmFreeHeap(DeviceEntry->DeviceDescriptor);
1412 BlMmFreeHeap(DeviceEntry);
1413 }
1414
1415 /* Return back to the caller */
1416 return Status;
1417}
1418
1422 _In_ PBL_BLOCK_DEVICE BlockIoDevice
1423 )
1424{
1426 BOOLEAN DeviceMatch;
1429 PBL_DEVICE_ENTRY DeviceEntry;
1430 EFI_HANDLE* DeviceHandles;
1431
1432 /* Initialize everything */
1433 DeviceEntry = NULL;
1434 DeviceCount = 0;
1435 DeviceHandles = 0;
1436 DeviceEntry = NULL;
1437
1438 /* Ask EFI for handles to all block devices */
1441 &DeviceCount,
1442 &DeviceHandles);
1443 if (!NT_SUCCESS(Status))
1444 {
1445 return STATUS_NO_SUCH_DEVICE;
1446 }
1447
1448 /* Build a hash entry, with the value inline */
1450 HashEntry.Size = sizeof(EFI_HANDLE);
1451
1452 /* Loop each device we got */
1453 DeviceMatch = FALSE;
1455 for (i = 0; i < DeviceCount; i++)
1456 {
1457 /* Check if we have a match in the device hash table */
1458 HashEntry.Value = DeviceHandles[i];
1460 if (NT_SUCCESS(Status))
1461 {
1462 /* We already know about this device */
1463 EfiPrintf(L"Device is known\r\n");
1464 continue;
1465 }
1466
1467 /* New device, store it in the hash table */
1469 &HashEntry,
1470 DeviceHandles[i],
1471 sizeof(DeviceHandles[i]));
1472 if (!NT_SUCCESS(Status))
1473 {
1474 /* Free the array and fail */
1475 BlMmFreeHeap(DeviceHandles);
1476 break;
1477 }
1478
1479 /* Create an entry for this device*/
1480 Status = BlockIoEfiCreateDeviceEntry(&DeviceEntry, DeviceHandles[i]);
1481 if (!NT_SUCCESS(Status))
1482 {
1483 EfiPrintf(L"EFI create failed: %lx\r\n", Status);
1484 continue;
1485 }
1486
1487 /* Add the device entry to the device table */
1490 DeviceEntry,
1491 &Id,
1493 if (!NT_SUCCESS(Status))
1494 {
1495 /* Remove it from teh hash table */
1497
1498 /* Free the block I/O device data */
1500
1501 /* Free the descriptor */
1502 BlMmFreeHeap(DeviceEntry->DeviceDescriptor);
1503
1504 /* Free the entry */
1505 BlMmFreeHeap(DeviceEntry);
1506 break;
1507 }
1508
1509 /* Does this device match what we're looking for? */
1510 DeviceMatch = BlpDeviceCompare(DeviceEntry->DeviceDescriptor, Device);
1511 if (DeviceMatch)
1512 {
1513 /* Yep, return the data back */
1514 RtlCopyMemory(BlockIoDevice,
1515 DeviceEntry->DeviceSpecificData,
1516 sizeof(*BlockIoDevice));
1518 break;
1519 }
1520 }
1521
1522 /* Free the device handle buffer array */
1523 BlMmFreeHeap(DeviceHandles);
1524
1525 /* Return status */
1526 return Status;
1527}
1528
1532 _In_ PBL_DEVICE_ENTRY DeviceEntry
1533 )
1534{
1535 EfiPrintf(L"Not implemented!\r\n");
1537}
1538
1542 _In_ PBL_DEVICE_ENTRY DeviceEntry
1543 )
1544{
1545 EfiPrintf(L"Not implemented!\r\n");
1547}
1548
1551 _In_ PBL_DEVICE_ENTRY DeviceEntry
1552 )
1553{
1554 NTSTATUS Status, LocalStatus;
1556
1557 /* Assume success */
1559 BlockDevice = DeviceEntry->DeviceSpecificData;
1560
1561 /* Close the protocol */
1562 LocalStatus = EfiCloseProtocol(BlockDevice->Handle, &EfiBlockIoProtocol);
1563 if (!NT_SUCCESS(LocalStatus))
1564 {
1565 /* Only inherit failures */
1566 Status = LocalStatus;
1567 }
1568
1569 /* Free the block device allocations */
1570 LocalStatus = BlockIopFreeAllocations(BlockDevice);
1571 if (!NT_SUCCESS(LocalStatus))
1572 {
1573 /* Only inherit failures */
1574 Status = LocalStatus;
1575 }
1576
1577 /* Return back to caller */
1578 return Status;
1579}
1580
1584 _In_ PBL_DEVICE_ENTRY DeviceEntry
1585 )
1586{
1588
1589 /* Use firmware-specific functions to open the disk */
1590 Status = BlockIoFirmwareOpen(Device, DeviceEntry->DeviceSpecificData);
1591 if (NT_SUCCESS(Status))
1592 {
1593 /* Overwrite with our own close routine */
1594 DeviceEntry->Callbacks.Close = DiskClose;
1595 }
1596
1597 /* Return back to caller */
1598 return Status;
1599}
1600
1604 _In_ PBL_DEVICE_ENTRY DeviceEntry
1605 )
1606{
1607 EfiPrintf(L"Not implemented!\r\n");
1609}
1610
1614 _In_ PBL_DEVICE_ENTRY DeviceEntry
1615 )
1616{
1617 EfiPrintf(L"Not implemented!\r\n");
1619}
1620
1624 _In_ PBL_DEVICE_ENTRY DeviceEntry
1625 )
1626{
1627 EfiPrintf(L"Not implemented!\r\n");
1629}
1630
1634 _In_ PBL_DEVICE_ENTRY DeviceEntry
1635 )
1636{
1637 EfiPrintf(L"Not implemented!\r\n");
1639}
1640
1642{
1643 NULL,
1645 NULL,
1646};
1647
1649{
1650 NULL,
1652 NULL,
1653};
1654
1656{
1657 NULL,
1659 NULL,
1660};
1661
1663{
1664 NULL,
1665 DiskOpen,
1666 NULL,
1667};
1668
1670{
1671 NULL,
1673 NULL,
1674};
1675
1677{
1678 NULL,
1679 UdpOpen,
1680 NULL,
1681};
1682
1684{
1685 NULL,
1686 SpOpen,
1687 NULL,
1688};
1689
1690BOOLEAN
1695 _Inout_ PVOID Argument3,
1697 )
1698{
1699 BOOLEAN Found;
1703 ULONG Unknown = *(PULONG)Argument3;
1704
1705 /* Assume failure */
1706 Found = FALSE;
1707
1708 /* Compare the device descriptor */
1709 if (BlpDeviceCompare(DeviceEntry->DeviceDescriptor, Device))
1710 {
1711 /* Compare something */
1712 if (DeviceEntry->Unknown == Unknown)
1713 {
1714 /* Compare flags */
1715 if ((!(Flags & BL_DEVICE_READ_ACCESS) || (DeviceEntry->Flags & BL_DEVICE_ENTRY_READ_ACCESS)) &&
1717 {
1718 /* And more flags */
1719 if (((Flags & 8) || !(DeviceEntry->Flags & 8)) &&
1720 (!(Flags & 8) || (DeviceEntry->Flags & 8)))
1721 {
1722 /* Found a match! */
1723 Found = TRUE;
1724 }
1725 }
1726 }
1727 }
1728
1729 /* Return matching state */
1730 return Found;
1731}
1732
1736 _In_ ULONG DeviceId
1737 )
1738{
1741
1742 /* Call the close routine for this entry */
1743 Status = DeviceEntry->Callbacks.Close(DmDeviceTable[DeviceId]);
1744
1745 /* Free the descriptor, and the device itself */
1746 BlMmFreeHeap(DeviceEntry->DeviceDescriptor);
1747 BlMmFreeHeap(DeviceEntry);
1748
1749 /* Clear out the netry, and return */
1750 DmDeviceTable[DeviceId] = NULL;
1751 return Status;
1752}
1753
1757 )
1758{
1761
1762 /* Check if the device is opened */
1763 if (DeviceEntry->Flags & BL_DEVICE_ENTRY_OPENED)
1764 {
1765 /* It is, so can't purge it */
1767 }
1768 else
1769 {
1770 /* It isn't, so destroy the entry */
1771 Status = DeviceTableDestroyEntry(DeviceEntry, DeviceEntry->DeviceId);
1772 }
1773
1774 /* Return back to caller */
1775 return Status;
1776}
1777
1781 _In_ ULONG DeviceId
1782 )
1783{
1786
1787 /* Call the close routine for this entry */
1788 Status = DeviceEntry->Callbacks.Close(DeviceEntry);
1789
1790 /* Free the descriptor, and the device itself */
1791 BlMmFreeHeap(DeviceEntry->DeviceDescriptor);
1792 BlMmFreeHeap(DeviceEntry);
1793
1794 /* Clear out the netry, and return */
1795 BlockIoDeviceTable[DeviceId] = NULL;
1796 return Status;
1797}
1798
1801 VOID
1802 )
1803{
1805
1806 /* Call the entry destructor on each entry in the table */
1810
1811 /* Free the table and return */
1813 return Status;
1814}
1815
1818 VOID
1819 )
1820{
1821 /* Free the prefetch buffer */
1823
1824 /* Set state to non initialized */
1826
1827 /* Return back */
1828 return STATUS_SUCCESS;
1829}
1830
1831ULONG
1835 )
1836{
1837 /* Get rid of the alignment bits to have a more unique number */
1838 return ((ULONG_PTR)Entry->Value >> 3) % TableSize;
1839}
1840
1843 VOID
1844 )
1845{
1847
1848 /* Allocate the block device table and zero it out */
1853 {
1854 return STATUS_NO_MEMORY;
1855 }
1857
1858 /* Register our destructor */
1860 if (!NT_SUCCESS(Status))
1861 {
1862 return Status;
1863 }
1864
1865 /* Initialize all counters */
1869
1870 /* Initialize the buffers and their sizes */
1878
1879 /* Allocate the prefetch buffer */
1882 0x100,
1883 0,
1884 0,
1885 NULL,
1886 0);
1887 if (NT_SUCCESS(Status))
1888 {
1889 /* Initialize the block cache */
1890 Status = BcInitialize();
1891 if (NT_SUCCESS(Status))
1892 {
1893 /* Initialize the block device hash table */
1895 if (NT_SUCCESS(Status))
1896 {
1897 /* Register our destructor */
1899 if (NT_SUCCESS(Status))
1900 {
1901 /* We're good */
1903 }
1904 }
1905 }
1906 }
1907
1908 /* Check if this is the failure path */
1909 if (!NT_SUCCESS(Status))
1910 {
1911 /* Free the prefetch buffer is one was allocated */
1913 {
1915 }
1916 }
1917
1918 /* Return back to the caller */
1919 return Status;
1920}
1921
1922BOOLEAN
1927 _In_ PVOID Argument3,
1929 )
1930{
1933
1934 /* Compare the two devices */
1935 return BlpDeviceCompare(DeviceEntry->DeviceDescriptor, Device);
1936}
1937
1941 _In_ PBL_DEVICE_ENTRY DeviceEntry
1942 )
1943{
1946 PBL_DEVICE_ENTRY FoundDeviceEntry;
1947 ULONG Dummy;
1948
1949 /* Check if the block I/O manager is initialized */
1950 if (!BlockIoInitialized)
1951 {
1952 /* First call, initialize it now */
1954 if (!NT_SUCCESS(Status))
1955 {
1956 /* Failed to initialize block I/O */
1957 return Status;
1958 }
1959 }
1960
1961 /* Copy a function table for block I/O devices */
1962 RtlCopyMemory(&DeviceEntry->Callbacks,
1964 sizeof(DeviceEntry->Callbacks));
1965
1966 /* Allocate a block I/O device */
1968 if (!BlockDevice)
1969 {
1970 return STATUS_NO_MEMORY;
1971 }
1972
1973 /* Set this as the device-specific data for this device entry */
1975 DeviceEntry->DeviceSpecificData = BlockDevice;
1976
1977 /* Check if we already have this device in our device table */
1978 FoundDeviceEntry = BlTblFindEntry(BlockIoDeviceTable,
1980 &Dummy,
1982 Device,
1983 NULL,
1984 NULL,
1985 NULL);
1986 if (FoundDeviceEntry)
1987 {
1988 /* We already found a device, so copy its device data and callbacks */
1989 //EfiPrintf(L"Block I/O Device entry found: %p\r\n", FoundDeviceEntry);
1990 RtlCopyMemory(BlockDevice, FoundDeviceEntry->DeviceSpecificData, sizeof(*BlockDevice));
1991 RtlCopyMemory(&DeviceEntry->Callbacks,
1992 &FoundDeviceEntry->Callbacks,
1993 sizeof(DeviceEntry->Callbacks));
1994 return Status;
1995 }
1996
1997 /* Zero out the device for now */
1999
2000 /* Is this a disk? */
2001 if (Device->DeviceType == DiskDevice)
2002 {
2003 /* What type of disk is it? */
2004 switch (Device->Local.Type)
2005 {
2006 /* Is it a raw physical disk? */
2007 case LocalDevice:
2008 case FloppyDevice:
2009 case CdRomDevice:
2010 /* Open a disk device */
2011 Status = DiskDeviceFunctionTable.Open(Device, DeviceEntry);
2012 break;
2013
2014 /* Is it a RAM disk? */
2015 case RamDiskDevice:
2016 /* Open a RAM disk */
2018 break;
2019
2020 /* Is it a file? */
2021 case FileDevice:
2022 /* Open a file */
2023 Status = FileDeviceFunctionTable.Open(Device, DeviceEntry);
2024 break;
2025
2026 /* Is it a VHD? */
2027 case VirtualDiskDevice:
2028 /* Open a virtual disk */
2030 break;
2031
2032 /* Is it something else? */
2033 default:
2034 /* Not supported */
2036 break;
2037 }
2038 }
2039 else if ((Device->DeviceType == LegacyPartitionDevice) ||
2040 (Device->DeviceType == PartitionDevice))
2041 {
2042 /* This is a partition on a disk, open it as such */
2044 }
2045 else
2046 {
2047 /* Other devices are not supported */
2049 }
2050
2051 /* Check for failure */
2052 if (!NT_SUCCESS(Status))
2053 {
2054 /* Free any allocations for this device */
2056 }
2057
2058 /* Return back to the caller */
2059 return Status;
2060}
2061
2064 _In_ PBL_DEVICE_DESCRIPTOR InputDevice,
2066 )
2067{
2068 EfiPrintf(L"Not implemented!\r\n");
2070}
2071
2074 _In_ ULONG DeviceId
2075 )
2076{
2077 PBL_DEVICE_ENTRY DeviceEntry;
2078
2079 /* Validate the device ID */
2080 if (DmTableEntries <= DeviceId)
2081 {
2083 }
2084
2085 /* Make sure there's a device there */
2086 DeviceEntry = DmDeviceTable[DeviceId];
2087 if (DeviceEntry == NULL)
2088 {
2090 }
2091
2092 /* Make sure the device is active */
2093 if (!(DeviceEntry->Flags & BL_DEVICE_ENTRY_OPENED))
2094 {
2096 }
2097
2098 /* Drop a reference and check if it's the last one */
2099 DeviceEntry->ReferenceCount--;
2100 if (!DeviceEntry->ReferenceCount)
2101 {
2102 /* Mark the device as inactive */
2103 DeviceEntry->Flags = ~BL_DEVICE_ENTRY_OPENED;
2104 }
2105
2106 /* We're good */
2107 return STATUS_SUCCESS;
2108}
2109
2115 _Out_ PULONG DeviceId
2116 )
2117{
2119 PBL_DEVICE_ENTRY DeviceEntry;
2120 PBL_DEVICE_DESCRIPTOR LocateDeviceDescriptor;
2121 PBL_REGISTERED_DEVICE RegisteredDevice;
2122 PLIST_ENTRY NextEntry, ListHead;
2123
2124 DeviceEntry = NULL;
2125
2126 /* Check for missing parameters */
2127 if (!(Device) || !(DeviceId) || !(Device->Size))
2128 {
2129 /* Bail out */
2131 goto Quickie;
2132 }
2133
2134 /* Make sure both read and write access are set */
2136 {
2137 /* Bail out */
2139 goto Quickie;
2140 }
2141
2142 /* Check if the boot device is being opened */
2143 if (Device->DeviceType == BootDevice)
2144 {
2145 /* Select it */
2147 }
2148
2149 /* Check if the 'locate' device is being opened */
2150 if (Device->DeviceType == LocateDevice)
2151 {
2152 /* Go find it */
2153 Status = BlpDeviceResolveLocate(Device, &LocateDeviceDescriptor);
2154 if (!NT_SUCCESS(Status))
2155 {
2156 /* Not found, bail out */
2157 goto Quickie;
2158 }
2159
2160 /* Select it */
2161 Device = LocateDeviceDescriptor;
2162 }
2163
2164 /* Check if the device isn't ready yet */
2165 if (Device->Flags & 1)
2166 {
2167 /* Return a failure */
2169 goto Quickie;
2170 }
2171
2172 /* Check if we already have an entry for the device */
2173 DeviceEntry = BlTblFindEntry(DmDeviceTable,
2175 DeviceId,
2177 Device,
2178 &Flags,
2179 &Unknown,
2180 NULL);
2181 if (DeviceEntry)
2182 {
2183 /* Return it, taking a reference on it */
2184 *DeviceId = DeviceEntry->DeviceId;
2185 ++DeviceEntry->ReferenceCount;
2186 DeviceEntry->Flags |= BL_DEVICE_ENTRY_OPENED;
2187 return STATUS_SUCCESS;
2188 }
2189
2190 /* We don't, allocate one */
2191 DeviceEntry = BlMmAllocateHeap(sizeof(*DeviceEntry));
2192 if (!DeviceEntry)
2193 {
2195 goto Quickie;
2196 }
2197
2198 /* Fill it out */
2199 RtlZeroMemory(DeviceEntry, sizeof(*DeviceEntry));
2200 DeviceEntry->ReferenceCount = 1;
2201 DeviceEntry->Flags |= (BL_DEVICE_ENTRY_OPENED |
2204 DeviceEntry->Unknown = Unknown;
2205
2206 /* Save flag 8 if needed */
2207 if (Flags & 8)
2208 {
2209 DeviceEntry->Flags |= 8;
2210 }
2211
2212 /* Allocate a device descriptor for the device */
2213 DeviceEntry->DeviceDescriptor = BlMmAllocateHeap(Device->Size);
2214 if (!DeviceEntry->DeviceDescriptor)
2215 {
2217 goto Quickie;
2218 }
2219
2220 /* Copy the descriptor that was passed in */
2222
2223 /* Now loop the list of dynamically registered devices */
2224 ListHead = &DmRegisteredDevices;
2225 NextEntry = ListHead->Flink;
2226 while (NextEntry != ListHead)
2227 {
2228 /* Get the device */
2229 RegisteredDevice = CONTAINING_RECORD(NextEntry,
2231 ListEntry);
2232
2233 /* Open the device */
2234 Status = RegisteredDevice->Callbacks.Open(Device, DeviceEntry);
2235 if (NT_SUCCESS(Status))
2236 {
2237 /* The device was opened, so we have the right one */
2238 goto DeviceOpened;
2239 }
2240
2241 /* Nope, keep trying */
2242 NextEntry = NextEntry->Flink;
2243 }
2244
2245 /* Well, it wasn't a dynamic device. Is it a block device? */
2246 if ((Device->DeviceType == PartitionDevice) ||
2247 (Device->DeviceType == DiskDevice) ||
2248 (Device->DeviceType == LegacyPartitionDevice))
2249 {
2250 /* Call the Block I/O handler */
2252 }
2253 else if (Device->DeviceType == SerialDevice)
2254 {
2255 /* It's a serial device, call the serial device handler */
2256 Status = SerialPortFunctionTable.Open(Device, DeviceEntry);
2257 }
2258 else if (Device->DeviceType == UdpDevice)
2259 {
2260 /* It's a network device, call the UDP device handler */
2261 Status = UdpFunctionTable.Open(Device, DeviceEntry);
2262 }
2263 else
2264 {
2265 /* Unsupported type of device */
2267 }
2268
2269 /* Check if the device was opened successfully */
2270 if (NT_SUCCESS(Status))
2271 {
2272DeviceOpened:
2273 /* Save the entry in the device table */
2276 DeviceEntry,
2277 DeviceId,
2279 if (NT_SUCCESS(Status))
2280 {
2281 /* It worked -- return the ID in the table to the caller */
2282 EfiPrintf(L"Device ID: %lx\r\n", *DeviceId);
2283 DeviceEntry->DeviceId = *DeviceId;
2284 return STATUS_SUCCESS;
2285 }
2286 }
2287
2288Quickie:
2289 /* Failure path -- did we allocate a device entry? */
2290 EfiPrintf(L"Block failure: %lx\r\n", Status);
2291 if (DeviceEntry)
2292 {
2293 /* Yep -- did it have a descriptor? */
2294 if (DeviceEntry->DeviceDescriptor)
2295 {
2296 /* Free it */
2297 BlMmFreeHeap(DeviceEntry->DeviceDescriptor);
2298 }
2299
2300 /* Free the entry */
2301 BlMmFreeHeap(DeviceEntry);
2302 }
2303
2304 /* Return the failure */
2305 return Status;
2306}
2307
2310 VOID
2311 )
2312{
2314
2315 /* Initialize the table count and list of devices */
2316 DmTableEntries = 8;
2318
2319 /* Initialize device information */
2322
2323 /* Allocate the device table */
2325 if (DmDeviceTable)
2326 {
2327 /* Clear it */
2329#if BL_BITLOCKER_SUPPORT
2330 /* Initialize BitLocker support */
2331 Status = FvebInitialize();
2332#else
2334#endif
2335 }
2336 else
2337 {
2338 /* No memory, we'll fail */
2340 }
2341
2342 /* Return initialization state */
2343 return Status;
2344}
2345
DWORD Id
#define MEDIA_DEVICE_PATH
Definition: DevicePath.h:842
#define MEDIA_CDROM_DP
Definition: DevicePath.h:902
#define ACPI_DEVICE_PATH
Definition: DevicePath.h:175
#define SIGNATURE_TYPE_GUID
Definition: DevicePath.h:897
#define MEDIA_HARDDRIVE_DP
Definition: DevicePath.h:847
#define SIGNATURE_TYPE_MBR
Definition: DevicePath.h:896
#define EISA_PNP_ID(_PNPId)
Definition: DevicePath.h:240
unsigned char BOOLEAN
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:31
VOID * EFI_HANDLE
Definition: UefiBaseType.h:35
#define EFI_SUCCESS
Definition: UefiBaseType.h:120
@ ByProtocol
Definition: UefiSpec.h:1428
#define ReadBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:339
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS EfiGetNtStatusCode(_In_ EFI_STATUS EfiStatus)
Definition: firmware.c:2539
EFI_DEVICE_PATH * EfiIsDevicePathParent(_In_ EFI_DEVICE_PATH *DevicePath1, _In_ EFI_DEVICE_PATH *DevicePath2)
Definition: firmware.c:47
#define BL_BLOCK_DEVICE_VIRTUAL_FLAG
Definition: bl.h:143
#define BL_DEVICE_READ_ACCESS
Definition: bl.h:152
NTSTATUS EfiCloseProtocol(_In_ EFI_HANDLE Handle, _In_ EFI_GUID *Protocol)
Definition: firmware.c:581
struct _BL_DEVICE_DESCRIPTOR * PBL_DEVICE_DESCRIPTOR
@ BlLoaderDeviceMemory
Definition: bl.h:307
#define BL_DEVICE_ENTRY_WRITE_ACCESS
Definition: bl.h:157
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
NTSTATUS BlHtStore(_In_ ULONG TableId, _In_ PBL_HASH_ENTRY Entry, _In_ PVOID Data, _In_ ULONG DataSize)
Definition: util.c:668
@ MbrPartition
Definition: bl.h:275
@ RawPartition
Definition: bl.h:276
@ GptPartition
Definition: bl.h:274
#define BL_DEVICE_WRITE_ACCESS
Definition: bl.h:153
EFI_GUID EfiDevicePathProtocol
Definition: firmware.c:31
EFI_GUID EfiBlockIoProtocol
Definition: firmware.c:33
#define BL_MM_INCLUDE_MAPPED_ALLOCATED
Definition: bl.h:96
NTSTATUS EfiOpenProtocol(_In_ EFI_HANDLE Handle, _In_ EFI_GUID *Protocol, _Out_ PVOID *Interface)
NTSTATUS MmPapAllocatePagesInRange(_Inout_ PVOID *PhysicalAddress, _In_ BL_MEMORY_TYPE MemoryType, _In_ ULONGLONG Pages, _In_ ULONG Attributes, _In_ ULONG Alignment, _In_opt_ PBL_ADDRESS_RANGE Range, _In_ ULONG Type)
Definition: pagealloc.c:707
PVOID BlMmAllocateHeap(_In_ SIZE_T Size)
Definition: heapalloc.c:569
NTSTATUS BlHtCreate(_In_ ULONG Size, _In_ PBL_HASH_TABLE_HASH_FUNCTION HashFunction, _In_ PBL_HASH_TABLE_COMPARE_FUNCTION CompareFunction, _Out_ PULONG Id)
Definition: util.c:504
PVOID BlTblFindEntry(_In_ PVOID *Table, _In_ ULONG Count, _Out_ PULONG EntryIndex, _In_ PBL_TBL_LOOKUP_ROUTINE Callback, _In_ PVOID Argument1, _In_ PVOID Argument2, _In_ PVOID Argument3, _In_ PVOID Argument4)
Definition: util.c:273
struct _BL_BLOCK_DEVICE * PBL_BLOCK_DEVICE
NTSTATUS MmPapFreePages(_In_ PVOID Address, _In_ ULONG WhichList)
Definition: pagealloc.c:1196
PBL_DEVICE_DESCRIPTOR BlpBootDevice
Definition: bootlib.c:16
#define BL_DEVICE_ENTRY_OPENED
Definition: bl.h:155
@ LegacyPartitionDevice
Definition: bl.h:248
@ LocateDevice
Definition: bl.h:253
@ SerialDevice
Definition: bl.h:249
@ DiskDevice
Definition: bl.h:247
@ PartitionDevice
Definition: bl.h:252
@ UdpDevice
Definition: bl.h:250
@ BootDevice
Definition: bl.h:251
VOID BlpArchSwitchContext(_In_ BL_ARCH_MODE NewMode)
Definition: arch.c:166
struct _BL_DEVICE_ENTRY * PBL_DEVICE_ENTRY
NTSTATUS TblDoNotPurgeEntry(_In_ PVOID Entry)
Definition: util.c:495
PBL_ARCH_CONTEXT CurrentExecutionContext
Definition: arch.c:17
#define BL_BLOCK_DEVICE_PRESENT_FLAG
Definition: bl.h:142
NTSTATUS BlHtDelete(_In_ ULONG TableId, _In_ PBL_HASH_ENTRY Entry)
Definition: util.c:722
@ FloppyDevice
Definition: bl.h:262
@ RamDiskDevice
Definition: bl.h:264
@ FileDevice
Definition: bl.h:265
@ LocalDevice
Definition: bl.h:261
@ VirtualDiskDevice
Definition: bl.h:266
@ CdRomDevice
Definition: bl.h:263
NTSTATUS BcInitialize(VOID)
Definition: blkcache.c:73
NTSTATUS BlTblSetEntry(_Inout_ PVOID **Table, _Inout_ PULONG Count, _In_ PVOID Entry, _Out_ PULONG EntryIndex, _In_ PBL_TBL_SET_ROUTINE Callback)
Definition: util.c:321
#define BL_BLOCK_DEVICE_REMOVABLE_FLAG
Definition: bl.h:141
NTSTATUS BlTblMap(_In_ PVOID *Table, _In_ ULONG Count, _In_ PBL_TBL_MAP_ROUTINE MapCallback)
Definition: util.c:399
EFI_DEVICE_PATH * EfiGetLeafNode(_In_ EFI_DEVICE_PATH *DevicePath)
Definition: firmware.c:102
#define BL_HT_VALUE_IS_INLINE
Definition: bl.h:137
#define BL_DEVICE_ENTRY_READ_ACCESS
Definition: bl.h:156
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
NTSTATUS BlpIoRegisterDestroyRoutine(_In_ PBL_IO_DESTROY_ROUTINE DestroyRoutine)
Definition: io.c:21
NTSTATUS EfiLocateHandleBuffer(_In_ EFI_LOCATE_SEARCH_TYPE SearchType, _In_ EFI_GUID *Protocol, _Inout_ PULONG HandleCount, _Inout_ EFI_HANDLE **Buffer)
Definition: firmware.c:1399
NTSTATUS BlHtLookup(_In_ ULONG TableId, _In_ PBL_HASH_ENTRY Entry, _Out_ PBL_HASH_VALUE *Value)
enum _BL_ARCH_MODE BL_ARCH_MODE
NTSTATUS BlockIoEfiCompareDevice(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ EFI_HANDLE Handle)
Definition: device.c:1268
struct _BL_DEVICE_IO_INFORMATION BL_DEVICE_IO_INFORMATION
NTSTATUS BlockIoGetGPTDiskSignature(_In_ PBL_DEVICE_ENTRY DeviceEntry, _Out_ PGUID DiskSignature)
Definition: device.c:994
BL_DEVICE_IO_INFORMATION DmDeviceIoInformation
Definition: device.c:26
NTSTATUS BlockIoEfiGetChildHandle(_In_ PBL_PROTOCOL_HANDLE ProtocolInterface, _In_ PBL_PROTOCOL_HANDLE ChildProtocolInterface)
Definition: device.c:924
BOOLEAN BlDeviceIsVirtualPartitionDevice(_In_ PBL_DEVICE_DESCRIPTOR InputDevice, _Outptr_ PBL_DEVICE_DESCRIPTOR *VirtualDevice)
Definition: device.c:612
NTSTATUS BlDeviceGetInformation(_In_ ULONG DeviceId, _Out_ PBL_DEVICE_INFORMATION DeviceInformation)
Definition: device.c:682
NTSTATUS BlDeviceReadAtOffset(_In_ ULONG DeviceId, _In_ ULONG Size, _In_ ULONGLONG Offset, _In_ PVOID Buffer, _Out_ PULONG BytesRead)
Definition: device.c:773
PVOID * DmDeviceTable
Definition: device.c:24
BL_DEVICE_CALLBACKS PartitionDeviceFunctionTable
Definition: device.c:1648
NTSTATUS SpOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1622
NTSTATUS BlockIopReadPhysicalDevice(_In_ PBL_DEVICE_ENTRY DeviceEntry, _In_ PVOID Buffer, _In_ ULONG Size, _Out_ PULONG BytesRead)
Definition: device.c:364
NTSTATUS BlockIoDeviceTableDestroy(VOID)
Definition: device.c:1800
BL_DEVICE_CALLBACKS VirtualDiskDeviceFunctionTable
Definition: device.c:1669
ULONG HashTableId
Definition: device.c:54
NTSTATUS BlockIoEfiFlush(VOID)
Definition: device.c:1176
NTSTATUS UdpOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1632
BOOLEAN DeviceTableCompare(_In_ PVOID Entry, _In_ PVOID Argument1, _In_ PVOID Argument2, _Inout_ PVOID Argument3, _Inout_ PVOID Argument4)
Definition: device.c:1691
ULONG BlockIoDeviceTableEntries
Definition: device.c:37
NTSTATUS PartitionOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1530
NTSTATUS BlockIoDeviceTableDestroyEntry(_In_ PVOID Entry, _In_ ULONG DeviceId)
Definition: device.c:1779
struct _BL_REGISTERED_DEVICE BL_REGISTERED_DEVICE
BL_DEVICE_CALLBACKS FileDeviceFunctionTable
Definition: device.c:1641
NTSTATUS BlockIopReadWriteVirtualDevice(_In_ PBL_DEVICE_ENTRY DeviceEntry, _In_ PVOID Buffer, _In_ ULONG Size, _In_ ULONG Operation, _Out_ PULONG BytesRead)
Definition: device.c:352
NTSTATUS BlockIoEfiCreateDeviceEntry(_In_ PBL_DEVICE_ENTRY *DeviceEntry, _Out_ PVOID Handle)
Definition: device.c:1185
BOOLEAN BlpDeviceCompare(_In_ PBL_DEVICE_DESCRIPTOR Device1, _In_ PBL_DEVICE_DESCRIPTOR Device2)
Definition: device.c:808
struct _BL_REGISTERED_DEVICE * PBL_REGISTERED_DEVICE
NTSTATUS BlpDeviceOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ ULONG Flags, _In_ ULONG Unknown, _Out_ PULONG DeviceId)
Definition: device.c:2111
NTSTATUS BlDeviceClose(_In_ ULONG DeviceId)
Definition: device.c:2073
NTSTATUS BlockIoSetInformation(_In_ PBL_DEVICE_ENTRY DeviceEntry, _Out_ PBL_DEVICE_INFORMATION DeviceInformation)
Definition: device.c:563
NTSTATUS BlockIopOperation(_In_ PBL_DEVICE_ENTRY DeviceEntry, _In_ PVOID Buffer, _In_ ULONG BlockCount, _In_ ULONG OperationType)
Definition: device.c:280
ULONG BlockIoFirmwareCdromCount
Definition: device.c:41
BL_DEVICE_CALLBACKS SerialPortFunctionTable
Definition: device.c:1683
ULONG BlockIopPartialBlockBufferSize
Definition: device.c:47
BL_DEVICE_CALLBACKS DiskDeviceFunctionTable
Definition: device.c:1662
NTSTATUS DeviceTablePurge(_In_ PVOID Entry)
Definition: device.c:1755
struct _BL_DEVICE_IO_INFORMATION * PBL_DEVICE_IO_INFORMATION
ULONG BlockIopAlignedBufferSize
Definition: device.c:44
ULONG BlockIoEfiHashFunction(_In_ PBL_HASH_ENTRY Entry, _In_ ULONG TableSize)
Definition: device.c:1832
NTSTATUS BlockIoFirmwareRead(_In_ PBL_BLOCK_DEVICE BlockDevice, _In_ PVOID Buffer, _In_ ULONGLONG Block, _In_ ULONGLONG BlockCount)
Definition: device.c:107
ULONG BlockIopReadBlockBufferSize
Definition: device.c:52
PVOID BlockIopPartialBlockBuffer
Definition: device.c:46
PVOID BlockIopReadBlockBuffer
Definition: device.c:51
ULONG DmTableEntries
Definition: device.c:22
NTSTATUS FileDeviceOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1612
BL_DEVICE_CALLBACKS BlockIoDeviceFunctionTable
Definition: device.c:84
NTSTATUS BlockIopFreeAllocations(_In_ PBL_BLOCK_DEVICE BlockDevice)
Definition: device.c:842
NTSTATUS BlDeviceRead(_In_ ULONG DeviceId, _In_ PVOID Buffer, _In_ ULONG Size, _Out_opt_ PULONG BytesRead)
Definition: device.c:720
LIST_ENTRY DmRegisteredDevices
Definition: device.c:21
NTSTATUS DeviceTableDestroyEntry(_In_ PVOID Entry, _In_ ULONG DeviceId)
Definition: device.c:1734
NTSTATUS BlockIopReadUsingPrefetch(_In_ PBL_DEVICE_ENTRY DeviceEntry, _In_ PVOID Buffer, _In_ ULONG BlockCount)
Definition: device.c:269
NTSTATUS BlockIoEfiGetDeviceInformation(_In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1004
NTSTATUS BlockIoEfiReset(VOID)
Definition: device.c:1167
NTSTATUS BlockIoEfiGetBlockIoInformation(_In_ PBL_BLOCK_DEVICE BlockDevice)
Definition: device.c:857
NTSTATUS BlockIopDestroy(VOID)
Definition: device.c:1817
BL_DEVICE_CALLBACKS UdpFunctionTable
Definition: device.c:1676
PVOID BlockIopPrefetchBuffer
Definition: device.c:49
NTSTATUS BlockIopBlockInformationCheck(_In_ PBL_BLOCK_DEVICE BlockDevice, _In_opt_ PULONG DesiredSize, _Out_opt_ PULONG Size, _Out_opt_ PULONG OutputAdjustedSize)
Definition: device.c:446
BOOLEAN BlockIoInitialized
Definition: device.c:56
NTSTATUS BlockIoFirmwareWrite(_In_ PBL_BLOCK_DEVICE BlockDevice, _In_ PVOID Buffer, _In_ ULONGLONG Block, _In_ ULONGLONG BlockCount)
Definition: device.c:96
PVOID * BlockIoDeviceTable
Definition: device.c:36
PVOID BlockIopAlignedBuffer
Definition: device.c:43
NTSTATUS BlDeviceSetInformation(_In_ ULONG DeviceId, _Out_ PBL_DEVICE_INFORMATION DeviceInformation)
Definition: device.c:645
ULONG BlockIoFirmwareRemovableDiskCount
Definition: device.c:39
NTSTATUS DiskClose(_In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1550
NTSTATUS BlockIopFirmwareOperation(PBL_DEVICE_ENTRY DeviceEntry, _In_ PVOID Buffer, _In_ ULONGLONG Block, _In_ ULONGLONG BlockCount, _In_ ULONG OperationType)
Definition: device.c:168
NTSTATUS RdDeviceOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1602
NTSTATUS BlockIoGetInformation(_In_ PBL_DEVICE_ENTRY DeviceEntry, _Out_ PBL_DEVICE_INFORMATION DeviceInformation)
Definition: device.c:596
NTSTATUS BlpDeviceInitialize(VOID)
Definition: device.c:2309
ULONG BlockIoFirmwareRawDiskCount
Definition: device.c:40
NTSTATUS BlockIopAllocateAlignedBuffer(_Inout_ PVOID *Buffer, _Inout_ PULONG BufferSize, _In_ ULONG Size, _In_ ULONG Alignment)
Definition: device.c:231
NTSTATUS BlpDeviceResolveLocate(_In_ PBL_DEVICE_DESCRIPTOR InputDevice, _Out_ PBL_DEVICE_DESCRIPTOR *LocateDevice)
Definition: device.c:2063
NTSTATUS BlockIopInitialize(VOID)
Definition: device.c:1842
NTSTATUS VhdFileDeviceOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1540
BOOLEAN BlockIoDeviceTableCompare(_In_ PVOID Entry, _In_ PVOID Argument1, _In_ PVOID Argument2, _In_ PVOID Argument3, _In_ PVOID Argument4)
Definition: device.c:1923
NTSTATUS DiskOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1582
NTSTATUS BlockIoOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1939
BL_DEVICE_CALLBACKS RamDiskDeviceFunctionTable
Definition: device.c:1655
NTSTATUS BlockIopFreeAlignedBuffer(_Inout_ PVOID *Buffer, _Inout_ PULONG BufferSize)
Definition: device.c:208
NTSTATUS BlockIoRead(_In_ PBL_DEVICE_ENTRY DeviceEntry, _In_ PVOID Buffer, _In_ ULONG Size, _Out_ PULONG BytesRead)
Definition: device.c:523
NTSTATUS BlockIoFirmwareOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_BLOCK_DEVICE BlockIoDevice)
Definition: device.c:1420
return Found
Definition: dirsup.c:1270
Definition: bufpool.h:45
_In_ PVOID Argument2
Definition: classpnp.h:721
#define BufferSize
Definition: mmc.h:75
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
char BlockDevice[260]
Definition: finstext2.c:21
FP_OP Operation
Definition: fpcontrol.c:150
union Alignment_ Alignment
InternalIoctlParams Argument4
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
@ Unknown
Definition: i8042prt.h:114
#define ULONG_MAX
Definition: limits.h:44
#define RtlEqualMemory(a, b, c)
Definition: kdvm.h:18
if(dx< 0)
Definition: linetemp.h:194
ULONG DeviceCount
Definition: mpu401.c:26
#define _Out_opt_
Definition: ms_sal.h:346
#define _Inout_
Definition: ms_sal.h:378
#define _Outptr_
Definition: ms_sal.h:427
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define STATUS_MEDIA_CHANGED
Definition: ntstatus.h:207
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_INTEGER_OVERFLOW
Definition: ntstatus.h:385
#define L(x)
Definition: ntvdm.h:50
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
#define STATUS_SUCCESS
Definition: shellext.h:65
BOOLEAN RemovableMedia
Definition: BlockIo.h:143
UINT32 BlockSize
Definition: BlockIo.h:173
EFI_LBA LastBlock
Definition: BlockIo.h:184
BOOLEAN MediaPresent
Definition: BlockIo.h:150
base of all file and directory entries
Definition: entries.h:83
Definition: hash.c:61
BL_ARCH_MODE Mode
Definition: bl.h:999
PBL_DEVICE_FLUSH Flush
Definition: bl.h:1256
PBL_DEVICE_RESET Reset
Definition: bl.h:1255
PBL_DEVICE_READ Read
Definition: bl.h:1251
PBL_DEVICE_GET_INFORMATION GetInformation
Definition: bl.h:1253
PBL_DEVICE_OPEN Open
Definition: bl.h:1249
PBL_DEVICE_SET_INFORMATION SetInformation
Definition: bl.h:1254
PBL_DEVICE_CLOSE Close
Definition: bl.h:1250
DEVICE_TYPE DeviceType
Definition: bl.h:950
struct _BL_DEVICE_DESCRIPTOR::@138::@141 Partition
BL_LOCAL_DEVICE Local
Definition: bl.h:956
Definition: bl.h:1261
ULONG Unknown
Definition: bl.h:1264
ULONG Flags
Definition: bl.h:1263
ULONG DeviceId
Definition: bl.h:1262
PBL_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: bl.h:1268
BL_DEVICE_CALLBACKS Callbacks
Definition: bl.h:1266
PVOID DeviceSpecificData
Definition: bl.h:1267
ULONG ReferenceCount
Definition: bl.h:1265
ULONGLONG WriteCount
Definition: device.c:18
Definition: bl.h:1177
BL_HARDDISK_DEVICE VirtualHardDisk
Definition: bl.h:935
BL_HARDDISK_DEVICE HardDisk
Definition: bl.h:933
BL_LOCAL_DEVICE_TYPE Type
Definition: bl.h:925
struct _BL_LOCAL_DEVICE::@134::@137 RamDisk
ULONG File
Definition: bl.h:944
struct _BL_LOCAL_DEVICE::@134::@136 FloppyDisk
BL_DEVICE_CALLBACKS Callbacks
Definition: device.c:33
LIST_ENTRY ListEntry
Definition: device.c:32
EFI_BLOCK_IO_MEDIA * Media
Definition: BlockIo.h:230
EFI_BLOCK_READ ReadBlocks
Definition: BlockIo.h:233
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define max(a, b)
Definition: svc.c:63
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#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 CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE Interface
Definition: wdffdo.h:465
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _In_ PWDF_USB_CONTROL_SETUP_PACKET _In_opt_ PWDF_MEMORY_DESCRIPTOR _Out_opt_ PULONG BytesTransferred
Definition: wdfusb.h:1342
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_IRQL_requires_same_ _In_opt_ PVOID Argument1
Definition: cmtypes.h:696
_Must_inspect_result_ typedef _Out_ PULONG TableSize
Definition: iotypes.h:4327
#define ROUND_TO_PAGES(Size)