ReactOS  0.4.14-dev-49-gfb4591c
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 
30 typedef struct _BL_REGISTERED_DEVICE
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,
80  _In_ ULONG Size,
82  );
83 
85 {
86  NULL,
88  NULL,
90  NULL,
93 };
94 
99  _In_ ULONGLONG Block,
100  _In_ ULONGLONG BlockCount
101  )
102 {
103  return STATUS_NOT_IMPLEMENTED;
104 }
105 
106 NTSTATUS
109  _In_ PVOID Buffer,
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;
127  if (CurrentExecutionContext->Mode != 1)
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 
167 NTSTATUS
169  PBL_DEVICE_ENTRY DeviceEntry,
170  _In_ PVOID Buffer,
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 
207 NTSTATUS
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 
230 NTSTATUS
234  _In_ ULONG Size,
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 
268 NTSTATUS
270  _In_ PBL_DEVICE_ENTRY DeviceEntry,
271  _In_ PVOID Buffer,
272  _In_ ULONG BlockCount
273  )
274 {
275  EfiPrintf(L"No prefetch support\r\n");
276  return STATUS_NOT_IMPLEMENTED;
277 }
278 
279 NTSTATUS
281  _In_ PBL_DEVICE_ENTRY DeviceEntry,
282  _In_ PVOID Buffer,
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 
320  BufferSize,
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 
351 NTSTATUS
353  _In_ PBL_DEVICE_ENTRY DeviceEntry,
354  _In_ PVOID Buffer,
355  _In_ ULONG Size,
358  )
359 {
360  return STATUS_NOT_IMPLEMENTED;
361 }
362 
363 NTSTATUS
365  _In_ PBL_DEVICE_ENTRY DeviceEntry,
366  _In_ PVOID Buffer,
367  _In_ ULONG Size,
369  )
370 {
373  ULONGLONG OffsetEnd, AlignedOffsetEnd, Offset;
375 
376  BlockDevice = DeviceEntry->DeviceSpecificData;
377  ReadBuffer = Buffer;
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,
411  ReadBuffer,
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 
428 ReadComplete:
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 
445 NTSTATUS
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 
513 Quickie:
514  if (Size)
515  {
516  *Size = RealSize;
517  }
518 
519  return Status;
520 }
521 
522 NTSTATUS
524  _In_ PBL_DEVICE_ENTRY DeviceEntry,
525  _In_ PVOID Buffer,
526  _In_ ULONG Size,
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 
562 NTSTATUS
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 
595 NTSTATUS
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 
611 BOOLEAN
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 
644 NTSTATUS
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 
681 NTSTATUS
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 
719 NTSTATUS
721  _In_ ULONG DeviceId,
722  _In_ PVOID Buffer,
723  _In_ ULONG Size,
725  )
726 {
727  PBL_DEVICE_ENTRY DeviceEntry;
729  ULONG BytesTransferred;
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,
755  &BytesTransferred);
756  if (!DeviceEntry->Unknown)
757  {
758  /* Update performance counters */
759  DmDeviceIoInformation.ReadCount += BytesTransferred;
760  }
761 
762  /* Return back how many bytes were read, if caller wants to know */
763  if (BytesRead)
764  {
765  *BytesRead = BytesTransferred;
766  }
767 
768  /* Return read result */
769  return Status;
770 }
771 
772 NTSTATUS
774  _In_ ULONG DeviceId,
775  _In_ ULONG Size,
777  _In_ PVOID Buffer,
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 
807 BOOLEAN
809  _In_ PBL_DEVICE_DESCRIPTOR Device1,
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 
841 NTSTATUS
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 
856 NTSTATUS
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 
923 NTSTATUS
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;
939  &DeviceCount,
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 
987 Quickie:
988  /* Free the handle array buffer */
989  BlMmFreeHeap(DeviceHandles);
990  return Status;
991 }
992 
993 NTSTATUS
995  _In_ PBL_DEVICE_ENTRY DeviceEntry,
996  _Out_ PGUID DiskSignature
997  )
998 {
999  EfiPrintf(L"GPT not supported\r\n");
1000  return STATUS_NOT_IMPLEMENTED;
1001 }
1002 
1003 NTSTATUS
1005  _In_ PBL_DEVICE_ENTRY DeviceEntry
1006  )
1007 {
1008  NTSTATUS Status;
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? */
1133  if (BlockDevice->DeviceFlags & BL_BLOCK_DEVICE_REMOVABLE_FLAG)
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 
1166 NTSTATUS
1168  VOID
1169  )
1170 {
1171  EfiPrintf(L"not implemented\r\n");
1172  return STATUS_NOT_IMPLEMENTED;
1173 }
1174 
1175 NTSTATUS
1177  VOID
1178  )
1179 {
1180  EfiPrintf(L"not implemented\r\n");
1181  return STATUS_NOT_IMPLEMENTED;
1182 }
1183 
1184 NTSTATUS
1186  _In_ PBL_DEVICE_ENTRY *DeviceEntry,
1188  )
1189 {
1190  PBL_DEVICE_ENTRY IoDeviceEntry;
1192  NTSTATUS Status;
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 
1267 NTSTATUS
1271  )
1272 {
1273  PBL_LOCAL_DEVICE LocalDeviceInfo, EfiLocalDeviceInfo;
1274  PBL_DEVICE_ENTRY DeviceEntry;
1275  PBL_DEVICE_DESCRIPTOR EfiDevice;
1276  NTSTATUS Status;
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 
1405 Quickie:
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 
1419 NTSTATUS
1422  _In_ PBL_BLOCK_DEVICE BlockIoDevice
1423  )
1424 {
1425  NTSTATUS Status;
1426  BOOLEAN DeviceMatch;
1428  ULONG i, Id, DeviceCount;
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 
1529 NTSTATUS
1532  _In_ PBL_DEVICE_ENTRY DeviceEntry
1533  )
1534 {
1535  EfiPrintf(L"Not implemented!\r\n");
1536  return STATUS_NOT_IMPLEMENTED;
1537 }
1538 
1539 NTSTATUS
1542  _In_ PBL_DEVICE_ENTRY DeviceEntry
1543  )
1544 {
1545  EfiPrintf(L"Not implemented!\r\n");
1546  return STATUS_NOT_IMPLEMENTED;
1547 }
1548 
1549 NTSTATUS
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 
1581 NTSTATUS
1584  _In_ PBL_DEVICE_ENTRY DeviceEntry
1585  )
1586 {
1587  NTSTATUS Status;
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 
1601 NTSTATUS
1604  _In_ PBL_DEVICE_ENTRY DeviceEntry
1605  )
1606 {
1607  EfiPrintf(L"Not implemented!\r\n");
1608  return STATUS_NOT_IMPLEMENTED;
1609 }
1610 
1611 NTSTATUS
1614  _In_ PBL_DEVICE_ENTRY DeviceEntry
1615  )
1616 {
1617  EfiPrintf(L"Not implemented!\r\n");
1618  return STATUS_NOT_IMPLEMENTED;
1619 }
1620 
1621 NTSTATUS
1624  _In_ PBL_DEVICE_ENTRY DeviceEntry
1625  )
1626 {
1627  EfiPrintf(L"Not implemented!\r\n");
1628  return STATUS_NOT_IMPLEMENTED;
1629 }
1630 
1631 NTSTATUS
1634  _In_ PBL_DEVICE_ENTRY DeviceEntry
1635  )
1636 {
1637  EfiPrintf(L"Not implemented!\r\n");
1638  return STATUS_NOT_IMPLEMENTED;
1639 }
1640 
1642 {
1643  NULL,
1645  NULL,
1646 };
1647 
1649 {
1650  NULL,
1651  PartitionOpen,
1652  NULL,
1653 };
1654 
1656 {
1657  NULL,
1658  RdDeviceOpen,
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 
1690 BOOLEAN
1692  _In_ PVOID Entry,
1695  _Inout_ PVOID Argument3,
1696  _Inout_ PVOID Argument4
1697  )
1698 {
1699  BOOLEAN Found;
1701  PBL_DEVICE_ENTRY DeviceEntry = (PBL_DEVICE_ENTRY)Entry;
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 
1733 NTSTATUS
1735  _In_ PVOID Entry,
1736  _In_ ULONG DeviceId
1737  )
1738 {
1739  PBL_DEVICE_ENTRY DeviceEntry = (PBL_DEVICE_ENTRY)Entry;
1740  NTSTATUS Status;
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 
1754 NTSTATUS
1756  _In_ PVOID Entry
1757  )
1758 {
1759  PBL_DEVICE_ENTRY DeviceEntry = (PBL_DEVICE_ENTRY)Entry;
1760  NTSTATUS Status;
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 
1778 NTSTATUS
1780  _In_ PVOID Entry,
1781  _In_ ULONG DeviceId
1782  )
1783 {
1784  PBL_DEVICE_ENTRY DeviceEntry = (PBL_DEVICE_ENTRY)Entry;
1785  NTSTATUS Status;
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 
1799 NTSTATUS
1801  VOID
1802  )
1803 {
1804  NTSTATUS Status;
1805 
1806  /* Call the entry destructor on each entry in the table */
1810 
1811  /* Free the table and return */
1813  return Status;
1814 }
1815 
1816 NTSTATUS
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 
1831 ULONG
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 
1841 NTSTATUS
1843  VOID
1844  )
1845 {
1846  NTSTATUS Status;
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 
1922 BOOLEAN
1924  _In_ PVOID Entry,
1927  _In_ PVOID Argument3,
1928  _In_ PVOID Argument4
1929  )
1930 {
1931  PBL_DEVICE_ENTRY DeviceEntry = (PBL_DEVICE_ENTRY)Entry;
1933 
1934  /* Compare the two devices */
1935  return BlpDeviceCompare(DeviceEntry->DeviceDescriptor, Device);
1936 }
1937 
1938 NTSTATUS
1941  _In_ PBL_DEVICE_ENTRY DeviceEntry
1942  )
1943 {
1944  NTSTATUS Status;
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 */
2017  Status = RamDiskDeviceFunctionTable.Open(Device, DeviceEntry);
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 
2062 NTSTATUS
2064  _In_ PBL_DEVICE_DESCRIPTOR InputDevice,
2066  )
2067 {
2068  EfiPrintf(L"Not implemented!\r\n");
2069  return STATUS_NOT_IMPLEMENTED;
2070 }
2071 
2072 NTSTATUS
2074  _In_ ULONG DeviceId
2075  )
2076 {
2077  PBL_DEVICE_ENTRY DeviceEntry;
2078 
2079  /* Validate the device ID */
2080  if (DmTableEntries <= DeviceId)
2081  {
2082  return STATUS_INVALID_PARAMETER;
2083  }
2084 
2085  /* Make sure there's a device there */
2086  DeviceEntry = DmDeviceTable[DeviceId];
2087  if (DeviceEntry == NULL)
2088  {
2089  return STATUS_INVALID_PARAMETER;
2090  }
2091 
2092  /* Make sure the device is active */
2093  if (!(DeviceEntry->Flags & BL_DEVICE_ENTRY_OPENED))
2094  {
2095  return STATUS_INVALID_PARAMETER;
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 
2110 NTSTATUS
2113  _In_ ULONG Flags,
2114  _In_ ULONG Unknown,
2115  _Out_ PULONG DeviceId
2116  )
2117 {
2118  NTSTATUS Status;
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 */
2221  RtlCopyMemory(DeviceEntry->DeviceDescriptor, Device, Device->Size);
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 */
2251  Status = BlockIoDeviceFunctionTable.Open(Device, DeviceEntry);
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  {
2272 DeviceOpened:
2273  /* Save the entry in the device table */
2275  &DmTableEntries,
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 
2288 Quickie:
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 
2308 NTSTATUS
2310  VOID
2311  )
2312 {
2313  NTSTATUS Status;
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 
ULONG DmTableEntries
Definition: device.c:22
NTSTATUS UdpOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1632
ULONG File
Definition: bl.h:945
EFI_GUID EfiBlockIoProtocol
Definition: firmware.c:33
struct _BL_REGISTERED_DEVICE * PBL_REGISTERED_DEVICE
PBL_DEVICE_DESCRIPTOR BlpBootDevice
Definition: bootlib.c:16
#define ACPI_DEVICE_PATH
Definition: DevicePath.h:175
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
BL_DEVICE_CALLBACKS UdpFunctionTable
Definition: device.c:1676
BL_DEVICE_CALLBACKS PartitionDeviceFunctionTable
Definition: device.c:1648
Definition: bl.h:248
ULONGLONG WriteCount
Definition: device.c:18
NTSTATUS EfiLocateHandleBuffer(_In_ EFI_LOCATE_SEARCH_TYPE SearchType, _In_ EFI_GUID *Protocol, _Inout_ PULONG HandleCount, _Inout_ EFI_HANDLE **Buffer)
Definition: firmware.c:1399
_IRQL_requires_same_ _In_opt_ PVOID Argument1
Definition: cmtypes.h:694
BOOLEAN BlockIoDeviceTableCompare(_In_ PVOID Entry, _In_ PVOID Argument1, _In_ PVOID Argument2, _In_ PVOID Argument3, _In_ PVOID Argument4)
Definition: device.c:1923
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2020
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
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
NTSTATUS BlockIoEfiGetDeviceInformation(_In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1004
char BlockDevice[260]
Definition: finstext2.c:21
#define BL_DEVICE_WRITE_ACCESS
Definition: bl.h:154
NTSTATUS RdDeviceOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1602
VOID BlpArchSwitchContext(_In_ BL_ARCH_MODE NewMode)
Definition: arch.c:166
BL_DEVICE_CALLBACKS RamDiskDeviceFunctionTable
Definition: device.c:1655
NTSTATUS BlockIoEfiGetBlockIoInformation(_In_ PBL_BLOCK_DEVICE BlockDevice)
Definition: device.c:857
NTSTATUS BlHtLookup(_In_ ULONG TableId, _In_ PBL_HASH_ENTRY Entry, _Out_ PBL_HASH_VALUE *Value)
NTSTATUS BlpDeviceInitialize(VOID)
Definition: device.c:2309
#define EISA_PNP_ID(_PNPId)
Definition: DevicePath.h:240
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
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 * DmDeviceTable
Definition: device.c:24
NTSTATUS BlockIoGetInformation(_In_ PBL_DEVICE_ENTRY DeviceEntry, _Out_ PBL_DEVICE_INFORMATION DeviceInformation)
Definition: device.c:596
PVOID BlockIopPartialBlockBuffer
Definition: device.c:46
BOOLEAN BlpDeviceCompare(_In_ PBL_DEVICE_DESCRIPTOR Device1, _In_ PBL_DEVICE_DESCRIPTOR Device2)
Definition: device.c:808
NTSTATUS TblDoNotPurgeEntry(_In_ PVOID Entry)
Definition: util.c:495
Definition: bl.h:252
LONG NTSTATUS
Definition: precomp.h:26
struct _BL_LOCAL_DEVICE::@124::@127 RamDisk
struct _BL_DEVICE_IO_INFORMATION BL_DEVICE_IO_INFORMATION
#define ReadBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:339
#define _Outptr_
Definition: no_sal2.h:396
NTSTATUS BlockIopReadWriteVirtualDevice(_In_ PBL_DEVICE_ENTRY DeviceEntry, _In_ PVOID Buffer, _In_ ULONG Size, _In_ ULONG Operation, _Out_ PULONG BytesRead)
Definition: device.c:352
BL_DEVICE_CALLBACKS VirtualDiskDeviceFunctionTable
Definition: device.c:1669
#define BL_DEVICE_ENTRY_WRITE_ACCESS
Definition: bl.h:158
PBL_DEVICE_GET_INFORMATION GetInformation
Definition: bl.h:1254
NTSTATUS BlockIoSetInformation(_In_ PBL_DEVICE_ENTRY DeviceEntry, _Out_ PBL_DEVICE_INFORMATION DeviceInformation)
Definition: device.c:563
struct _BL_DEVICE_ENTRY * PBL_DEVICE_ENTRY
ULONG DeviceId
Definition: bl.h:1263
ULONG ReferenceCount
Definition: bl.h:1266
EFI_BLOCK_READ ReadBlocks
Definition: BlockIo.h:233
ULONG BlockIoEfiHashFunction(_In_ PBL_HASH_ENTRY Entry, _In_ ULONG TableSize)
Definition: device.c:1832
BL_HARDDISK_DEVICE HardDisk
Definition: bl.h:934
PBL_DEVICE_READ Read
Definition: bl.h:1252
NTSTATUS BlHtDelete(_In_ ULONG TableId, _In_ PBL_HASH_ENTRY Entry)
Definition: util.c:722
#define BL_BLOCK_DEVICE_PRESENT_FLAG
Definition: bl.h:143
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
NTSTATUS BlockIoEfiGetChildHandle(_In_ PBL_PROTOCOL_HANDLE ProtocolInterface, _In_ PBL_PROTOCOL_HANDLE ChildProtocolInterface)
Definition: device.c:924
ULONG BlockIopReadBlockBufferSize
Definition: device.c:52
#define _In_opt_
Definition: no_sal2.h:213
Definition: bl.h:1261
DWORD Id
NTSTATUS BlockIoRead(_In_ PBL_DEVICE_ENTRY DeviceEntry, _In_ PVOID Buffer, _In_ ULONG Size, _Out_ PULONG BytesRead)
Definition: device.c:523
NTSTATUS BlTblMap(_In_ PVOID *Table, _In_ ULONG Count, _In_ PBL_TBL_MAP_ROUTINE MapCallback)
Definition: util.c:399
uint32_t ULONG_PTR
Definition: typedefs.h:63
LIST_ENTRY ListEntry
Definition: device.c:32
NTSTATUS BlockIoFirmwareWrite(_In_ PBL_BLOCK_DEVICE BlockDevice, _In_ PVOID Buffer, _In_ ULONGLONG Block, _In_ ULONGLONG BlockCount)
Definition: device.c:96
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define STATUS_MEDIA_CHANGED
Definition: ntstatus.h:195
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
BL_LOCAL_DEVICE Local
Definition: bl.h:957
ULONG HashTableId
Definition: device.c:54
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
BL_DEVICE_CALLBACKS DiskDeviceFunctionTable
Definition: device.c:1662
NTSTATUS EfiOpenProtocol(_In_ EFI_HANDLE Handle, _In_ EFI_GUID *Protocol, _Out_ PVOID *Interface)
#define STATUS_INTEGER_OVERFLOW
Definition: ntstatus.h:371
NTSTATUS BlHtStore(_In_ ULONG TableId, _In_ PBL_HASH_ENTRY Entry, _In_ PVOID Data, _In_ ULONG DataSize)
Definition: util.c:668
NTSTATUS BlockIopFirmwareOperation(PBL_DEVICE_ENTRY DeviceEntry, _In_ PVOID Buffer, _In_ ULONGLONG Block, _In_ ULONGLONG BlockCount, _In_ ULONG OperationType)
Definition: device.c:168
struct _BL_LOCAL_DEVICE::@124::@126 FloppyDisk
ULONG DeviceCount
Definition: mpu401.c:26
NTSTATUS BlockIopAllocateAlignedBuffer(_Inout_ PVOID *Buffer, _Inout_ PULONG BufferSize, _In_ ULONG Size, _In_ ULONG Alignment)
Definition: device.c:231
union Alignment_ Alignment
PBL_DEVICE_OPEN Open
Definition: bl.h:1250
unsigned char BOOLEAN
DEVICE_TYPE DeviceType
Definition: bl.h:951
smooth NULL
Definition: ftsmooth.c:416
BL_HARDDISK_DEVICE VirtualHardDisk
Definition: bl.h:936
PVOID BlMmAllocateHeap(_In_ SIZE_T Size)
Definition: heapalloc.c:569
NTSTATUS BlockIoFirmwareOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_BLOCK_DEVICE BlockIoDevice)
Definition: device.c:1420
#define _Out_
Definition: no_sal2.h:323
NTSTATUS BlockIoEfiCreateDeviceEntry(_In_ PBL_DEVICE_ENTRY *DeviceEntry, _Out_ PVOID Handle)
Definition: device.c:1185
BL_DEVICE_CALLBACKS Callbacks
Definition: device.c:33
NTSTATUS BlpIoRegisterDestroyRoutine(_In_ PBL_IO_DESTROY_ROUTINE DestroyRoutine)
Definition: io.c:21
#define MEDIA_HARDDRIVE_DP
Definition: DevicePath.h:847
BL_DEVICE_CALLBACKS FileDeviceFunctionTable
Definition: device.c:1641
NTSTATUS EfiCloseProtocol(_In_ EFI_HANDLE Handle, _In_ EFI_GUID *Protocol)
Definition: firmware.c:581
Definition: bufpool.h:45
PVOID BlockIopAlignedBuffer
Definition: device.c:43
return Found
Definition: dirsup.c:1270
#define BL_BLOCK_DEVICE_VIRTUAL_FLAG
Definition: bl.h:144
NTSTATUS FileDeviceOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1612
PBL_ARCH_CONTEXT CurrentExecutionContext
Definition: arch.c:17
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_In_ PVOID Argument2
Definition: classpnp.h:680
BL_DEVICE_CALLBACKS BlockIoDeviceFunctionTable
Definition: device.c:84
#define BL_MM_INCLUDE_MAPPED_ALLOCATED
Definition: bl.h:97
Definition: bl.h:251
struct _BL_DEVICE_DESCRIPTOR::@128::@131 Partition
#define _Out_opt_
Definition: no_sal2.h:339
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
_In_ HANDLE Handle
Definition: extypes.h:390
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
BOOLEAN RemovableMedia
Definition: BlockIo.h:143
struct _BL_DEVICE_IO_INFORMATION * PBL_DEVICE_IO_INFORMATION
PVOID DeviceSpecificData
Definition: bl.h:1268
NTSYSAPI ULONG NTAPI RtlEqualMemory(CONST VOID *Source1, CONST VOID *Source2, ULONG Length)
NTSTATUS BlpDeviceResolveLocate(_In_ PBL_DEVICE_DESCRIPTOR InputDevice, _Out_ PBL_DEVICE_DESCRIPTOR *LocateDevice)
Definition: device.c:2063
if(!(yy_init))
Definition: macro.lex.yy.c:714
NTSTATUS BlDeviceRead(_In_ ULONG DeviceId, _In_ PVOID Buffer, _In_ ULONG Size, _Out_opt_ PULONG BytesRead)
Definition: device.c:720
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
NTSTATUS BlDeviceSetInformation(_In_ ULONG DeviceId, _Out_ PBL_DEVICE_INFORMATION DeviceInformation)
Definition: device.c:645
NTSTATUS VhdFileDeviceOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1540
uint64_t ULONGLONG
Definition: typedefs.h:65
NTSTATUS BlockIopFreeAllocations(_In_ PBL_BLOCK_DEVICE BlockDevice)
Definition: device.c:842
NTSTATUS DiskOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1582
struct _DeviceInfo DeviceInfo
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
#define BufferSize
Definition: classpnp.h:419
ULONG BlockIoFirmwareCdromCount
Definition: device.c:41
ULONG Flags
Definition: bl.h:1264
NTSTATUS BlockIoDeviceTableDestroy(VOID)
Definition: device.c:1800
#define MEDIA_CDROM_DP
Definition: DevicePath.h:902
#define _Inout_
Definition: no_sal2.h:244
PVOID BlockIopReadBlockBuffer
Definition: device.c:51
BL_LOCAL_DEVICE_TYPE Type
Definition: bl.h:926
NTSTATUS BlockIoEfiCompareDevice(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ EFI_HANDLE Handle)
Definition: device.c:1268
enum _BL_ARCH_MODE BL_ARCH_MODE
#define SIGNATURE_TYPE_MBR
Definition: DevicePath.h:896
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
PBL_DEVICE_FLUSH Flush
Definition: bl.h:1257
#define MEDIA_DEVICE_PATH
Definition: DevicePath.h:842
NTSTATUS DiskClose(_In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1550
BOOLEAN MediaPresent
Definition: BlockIo.h:150
ULONG BlockIoDeviceTableEntries
Definition: device.c:37
static const WCHAR L[]
Definition: oid.c:1250
NTSTATUS BlockIopReadPhysicalDevice(_In_ PBL_DEVICE_ENTRY DeviceEntry, _In_ PVOID Buffer, _In_ ULONG Size, _Out_ PULONG BytesRead)
Definition: device.c:364
LIST_ENTRY DmRegisteredDevices
Definition: device.c:21
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:31
ULONG Unknown
Definition: bl.h:1265
NTSTATUS DeviceTableDestroyEntry(_In_ PVOID Entry, _In_ ULONG DeviceId)
Definition: device.c:1734
Definition: typedefs.h:117
NTSTATUS PartitionOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1530
NTSTATUS BlockIopReadUsingPrefetch(_In_ PBL_DEVICE_ENTRY DeviceEntry, _In_ PVOID Buffer, _In_ ULONG BlockCount)
Definition: device.c:269
NTSTATUS MmPapFreePages(_In_ PVOID Address, _In_ ULONG WhichList)
Definition: pagealloc.c:1196
#define BL_DEVICE_ENTRY_OPENED
Definition: bl.h:156
PVOID BlockIopPrefetchBuffer
Definition: device.c:49
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
EFI_GUID EfiDevicePathProtocol
Definition: firmware.c:31
Definition: bl.h:1177
EFI_BLOCK_IO_MEDIA * Media
Definition: BlockIo.h:230
PBL_DEVICE_RESET Reset
Definition: bl.h:1256
EFI_LBA LastBlock
Definition: BlockIo.h:184
PVOID * BlockIoDeviceTable
Definition: device.c:36
Status
Definition: gdiplustypes.h:24
VOID * EFI_HANDLE
Definition: UefiBaseType.h:35
Definition: hash.c:61
NTSTATUS BlockIoEfiReset(VOID)
Definition: device.c:1167
struct _BL_DEVICE_DESCRIPTOR * PBL_DEVICE_DESCRIPTOR
NTSTATUS BlockIopDestroy(VOID)
Definition: device.c:1817
#define _In_
Definition: no_sal2.h:204
#define BL_DEVICE_READ_ACCESS
Definition: bl.h:153
EFI_DEVICE_PATH * EfiIsDevicePathParent(_In_ EFI_DEVICE_PATH *DevicePath1, _In_ EFI_DEVICE_PATH *DevicePath2)
Definition: firmware.c:47
BOOLEAN BlockIoInitialized
Definition: device.c:56
NTSTATUS BlDeviceClose(_In_ ULONG DeviceId)
Definition: device.c:2073
struct _BL_BLOCK_DEVICE * PBL_BLOCK_DEVICE
ULONG BlockIopAlignedBufferSize
Definition: device.c:44
#define ROUND_TO_PAGES(Size)
Definition: bl.h:266
#define EFI_SUCCESS
Definition: UefiBaseType.h:120
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS BlockIoOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1939
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
NTSTATUS BlockIopBlockInformationCheck(_In_ PBL_BLOCK_DEVICE BlockDevice, _In_opt_ PULONG DesiredSize, _Out_opt_ PULONG Size, _Out_opt_ PULONG OutputAdjustedSize)
Definition: device.c:446
NTSTATUS BlockIoEfiFlush(VOID)
Definition: device.c:1176
EFI_DEVICE_PATH * EfiGetLeafNode(_In_ EFI_DEVICE_PATH *DevicePath)
Definition: firmware.c:102
NTSTATUS BlTblSetEntry(_Inout_ PVOID **Table, _Inout_ PULONG Count, _In_ PVOID Entry, _Out_ PULONG EntryIndex, _In_ PBL_TBL_SET_ROUTINE Callback)
Definition: util.c:321
NTSTATUS BcInitialize(VOID)
Definition: blkcache.c:73
PBL_DEVICE_CLOSE Close
Definition: bl.h:1251
NTSTATUS BlockIopInitialize(VOID)
Definition: device.c:1842
NTSTATUS BlockIoDeviceTableDestroyEntry(_In_ PVOID Entry, _In_ ULONG DeviceId)
Definition: device.c:1779
_Must_inspect_result_ typedef _Out_ PULONG TableSize
Definition: iotypes.h:3971
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
struct _BL_REGISTERED_DEVICE BL_REGISTERED_DEVICE
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ FLT_SET_CONTEXT_OPERATION Operation
Definition: fltkernel.h:1468
ULONG BlockIopPartialBlockBufferSize
Definition: device.c:47
#define SIGNATURE_TYPE_GUID
Definition: DevicePath.h:897
PBL_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: bl.h:1269
NTSTATUS BlpDeviceOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ ULONG Flags, _In_ ULONG Unknown, _Out_ PULONG DeviceId)
Definition: device.c:2111
ULONG BlockIoFirmwareRawDiskCount
Definition: device.c:40
BL_DEVICE_IO_INFORMATION DmDeviceIoInformation
Definition: device.c:26
NTSTATUS DeviceTablePurge(_In_ PVOID Entry)
Definition: device.c:1755
UINT32 BlockSize
Definition: BlockIo.h:173
NTSTATUS SpOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ PBL_DEVICE_ENTRY DeviceEntry)
Definition: device.c:1622
BL_ARCH_MODE Mode
Definition: bl.h:1000
NTSTATUS BlockIopOperation(_In_ PBL_DEVICE_ENTRY DeviceEntry, _In_ PVOID Buffer, _In_ ULONG BlockCount, _In_ ULONG OperationType)
Definition: device.c:280
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
BL_DEVICE_CALLBACKS SerialPortFunctionTable
Definition: device.c:1683
return STATUS_SUCCESS
Definition: btrfs.c:2966
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
BL_DEVICE_CALLBACKS Callbacks
Definition: bl.h:1267
NTSTATUS EfiGetNtStatusCode(_In_ EFI_STATUS EfiStatus)
Definition: firmware.c:2539
#define BL_HT_VALUE_IS_INLINE
Definition: bl.h:138
ULONG BlockIoFirmwareRemovableDiskCount
Definition: device.c:39
#define BL_DEVICE_ENTRY_READ_ACCESS
Definition: bl.h:157
base of all file and directory entries
Definition: entries.h:82
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255
NTSTATUS BlockIoGetGPTDiskSignature(_In_ PBL_DEVICE_ENTRY DeviceEntry, _Out_ PGUID DiskSignature)
Definition: device.c:994
PBL_DEVICE_SET_INFORMATION SetInformation
Definition: bl.h:1255
NTSTATUS BlockIopFreeAlignedBuffer(_Inout_ PVOID *Buffer, _Inout_ PULONG BufferSize)
Definition: device.c:208
BOOLEAN BlDeviceIsVirtualPartitionDevice(_In_ PBL_DEVICE_DESCRIPTOR InputDevice, _Outptr_ PBL_DEVICE_DESCRIPTOR *VirtualDevice)
Definition: device.c:612
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define ULONG_MAX
Definition: limits.h:44
BOOLEAN DeviceTableCompare(_In_ PVOID Entry, _In_ PVOID Argument1, _In_ PVOID Argument2, _Inout_ PVOID Argument3, _Inout_ PVOID Argument4)
Definition: device.c:1691
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:65
#define BL_BLOCK_DEVICE_REMOVABLE_FLAG
Definition: bl.h:142
NTSTATUS BlockIoFirmwareRead(_In_ PBL_BLOCK_DEVICE BlockDevice, _In_ PVOID Buffer, _In_ ULONGLONG Block, _In_ ULONGLONG BlockCount)
Definition: device.c:107