[BOOTLIB]: Implement MmArchTranslateVirtualAddress for non-paging mode. Stub Mmx86Tra...
[reactos.git] / reactos / boot / environ / lib / firmware / efi / firmware.c
index 56aa889..48cdffb 100644 (file)
@@ -23,6 +23,7 @@ EFI_RUNTIME_SERVICES *EfiRT;
 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *EfiConOut;
 EFI_SIMPLE_TEXT_INPUT_PROTOCOL *EfiConIn;
 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *EfiConInEx;
+PHYSICAL_ADDRESS EfiRsdt;
 
 EFI_GUID EfiGraphicsOutputProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
 EFI_GUID EfiUgaDrawProtocol = EFI_UGA_DRAW_PROTOCOL_GUID;
@@ -30,9 +31,16 @@ EFI_GUID EfiLoadedImageProtocol = EFI_LOADED_IMAGE_PROTOCOL_GUID;
 EFI_GUID EfiDevicePathProtocol = EFI_DEVICE_PATH_PROTOCOL_GUID;
 EFI_GUID EfiSimpleTextInputExProtocol = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
 EFI_GUID EfiBlockIoProtocol = EFI_BLOCK_IO_PROTOCOL_GUID;
+EFI_GUID EfiRootAcpiTableGuid = EFI_ACPI_20_TABLE_GUID;
+EFI_GUID EfiRootAcpiTable10Guid = EFI_ACPI_TABLE_GUID;
+EFI_GUID EfiGlobalVariable = EFI_GLOBAL_VARIABLE;
+EFI_GUID BlpEfiSecureBootPrivateNamespace = { 0x77FA9ABD , 0x0359, 0x4D32, { 0xBD, 0x60, 0x28, 0xF4, 0xE7, 0x8F, 0x78, 0x4B } };
 
 WCHAR BlScratchBuffer[8192];
 
+BOOLEAN BlpFirmwareChecked;
+BOOLEAN BlpFirmwareEnabled;
+
 /* FUNCTIONS *****************************************************************/
 
 EFI_DEVICE_PATH *
@@ -41,14 +49,21 @@ EfiIsDevicePathParent (
     _In_ EFI_DEVICE_PATH *DevicePath2
     )
 {
+    EFI_DEVICE_PATH* CurrentPath1;
+    EFI_DEVICE_PATH* CurrentPath2;
     USHORT Length1, Length2;
 
+    /* Start with the current nodes */
+    CurrentPath1 = DevicePath1;
+    CurrentPath2 = DevicePath2;
+
     /* Loop each element of the device path */
-    while (!IsDevicePathEndType(DevicePath1) && !IsDevicePathEndType(DevicePath2))
+    while (!(IsDevicePathEndType(CurrentPath1)) &&
+           !(IsDevicePathEndType(CurrentPath2)))
     {
         /* Check if the element has a different length */
-        Length1 = DevicePathNodeLength(DevicePath1);
-        Length2 = DevicePathNodeLength(DevicePath2);
+        Length1 = DevicePathNodeLength(CurrentPath1);
+        Length2 = DevicePathNodeLength(CurrentPath2);
         if (Length1 != Length2)
         {
             /* Then they're not related */
@@ -56,25 +71,25 @@ EfiIsDevicePathParent (
         }
 
         /* Check if the rest of the element data matches */
-        if (RtlCompareMemory(DevicePath1, DevicePath2, Length1) != Length1)
+        if (RtlCompareMemory(CurrentPath1, CurrentPath2, Length1) != Length1)
         {
             /* Nope, not related */
             return NULL;
         }
 
         /* Move to the next element */
-        DevicePath1 = NextDevicePathNode(DevicePath1);
-        DevicePath2 = NextDevicePathNode(DevicePath2);
+        CurrentPath1 = NextDevicePathNode(CurrentPath1);
+        CurrentPath2 = NextDevicePathNode(CurrentPath2);
     }
 
     /* If the last element in path 1 is empty, then path 2 is the child (deeper) */
-    if (!IsDevicePathEndType(DevicePath1))
+    if (!IsDevicePathEndType(CurrentPath1))
     {
         return DevicePath2;
     }
 
     /* If the last element in path 2 is empty, then path 1 is the child (deeper) */
-    if (!IsDevicePathEndType(DevicePath2))
+    if (!IsDevicePathEndType(CurrentPath2))
     {
         return DevicePath1;
     }
@@ -103,7 +118,7 @@ EfiGetLeafNode (
         }
     }
 
-    /* This now contains the deepeest (leaf) node */
+    /* This now contains the deepest (leaf) node */
     return DevicePath;
 }
 
@@ -128,7 +143,17 @@ EfiPrintf (
     }
     else
     {
-        /* FIXME: @TODO: Not yet supported */
+        /* Switch to real mode */
+        BlpArchSwitchContext(BlRealMode);
+
+        /* Call EFI directly */
+        if (EfiConOut != NULL)
+        {
+            EfiConOut->OutputString(EfiConOut, BlScratchBuffer);
+        }
+
+        /* Switch back to protected mode */
+        BlpArchSwitchContext(BlProtectedMode);
     }
 
     /* All done */
@@ -258,6 +283,217 @@ EfiCloseProtocol (
     return Status;
 }
 
+NTSTATUS
+EfiGetVariable (
+    _In_ PWCHAR VariableName,
+    _In_ EFI_GUID* VendorGuid,
+    _Out_opt_ PULONG Attributes,
+    _Inout_ PULONG DataSize,
+    _Out_ PVOID Data
+    )
+{
+    EFI_STATUS EfiStatus;
+    NTSTATUS Status;
+    BL_ARCH_MODE OldMode;
+    ULONG LocalAttributes;
+
+    /* Are we in protected mode? */
+    OldMode = CurrentExecutionContext->Mode;
+    if (OldMode != BlRealMode)
+    {
+        /* FIXME: Not yet implemented */
+        return STATUS_NOT_IMPLEMENTED;
+    }
+
+    /* Call the runtime API */
+    EfiStatus = EfiRT->GetVariable(VariableName,
+                                   VendorGuid,
+                                   (UINT32*)&LocalAttributes,
+                                   (UINTN*)DataSize,
+                                   Data);
+
+    /* Switch back to protected mode if we came from there */
+    if (OldMode != BlRealMode)
+    {
+        BlpArchSwitchContext(OldMode);
+    }
+
+    /* Return attributes back to the caller if asked to */
+    if (Attributes)
+    {
+        *Attributes = LocalAttributes;
+    }
+
+    /* Convert the error to an NTSTATUS and return it */
+    Status = EfiGetNtStatusCode(EfiStatus);
+    return Status;
+}
+
+NTSTATUS
+BlpSecureBootEFIIsEnabled (
+    VOID
+    )
+{
+    NTSTATUS Status;
+    BOOLEAN SetupMode, SecureBoot;
+    ULONG DataSize;
+
+    /* Assume setup mode enabled, and no secure boot */
+    SecureBoot = FALSE;
+    SetupMode = TRUE;
+
+    /* Get the SetupMode variable */
+    DataSize = sizeof(SetupMode);
+    Status = EfiGetVariable(L"SetupMode",
+                            &EfiGlobalVariable,
+                            NULL,
+                            &DataSize,
+                            &SetupMode);
+    if (NT_SUCCESS(Status))
+    {
+        /* If it worked, get the SecureBoot variable */
+        DataSize = sizeof(SecureBoot);
+        Status = EfiGetVariable(L"SecureBoot",
+                                &EfiGlobalVariable,
+                                NULL,
+                                &DataSize,
+                                &SecureBoot);
+        if (NT_SUCCESS(Status))
+        {
+            /* In setup mode or without secureboot turned on, return failure */
+            if ((SecureBoot != TRUE) || (SetupMode))
+            {
+                Status = STATUS_INVALID_SIGNATURE;
+            }
+
+            // BlpSbdiStateFlags |= 8u;
+        }
+    }
+
+    /* Return secureboot status */
+    return Status;
+}
+
+NTSTATUS
+BlSecureBootIsEnabled (
+    _Out_ PBOOLEAN SecureBootEnabled
+    )
+{
+    NTSTATUS Status;
+
+    /* Have we checked before ? */
+    if (!BlpFirmwareChecked)
+    {
+        /* First time checking */
+        Status = BlpSecureBootEFIIsEnabled();
+        if NT_SUCCESS(Status)
+        {
+            /* Yep, it's on */
+            BlpFirmwareEnabled = TRUE;
+        }
+
+        /* Don't check again */
+        BlpFirmwareChecked = TRUE;
+    }
+
+    /* Return the firmware result */
+    *SecureBootEnabled = BlpFirmwareEnabled;
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+BlSecureBootCheckForFactoryReset (
+    VOID
+    )
+{
+    BOOLEAN SecureBootEnabled;
+    NTSTATUS Status;
+    ULONG DataSize;
+
+    /* Initialize locals */
+    DataSize = 0;
+    SecureBootEnabled = FALSE;
+
+    /* Check if secureboot is enabled */
+    Status = BlSecureBootIsEnabled(&SecureBootEnabled);
+    if (!(NT_SUCCESS(Status)) || !(SecureBootEnabled))
+    {
+        /* It's not. Check if there's a revocation list */
+        Status = EfiGetVariable(L"RevocationList",
+                                &BlpEfiSecureBootPrivateNamespace,
+                                NULL,
+                                &DataSize,
+                                NULL);
+        if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_TOO_SMALL))
+        {
+            /* We don't support this yet */
+            EfiPrintf(L"Not yet supported\r\n");
+            Status = STATUS_NOT_IMPLEMENTED;
+        }
+    }
+
+    /* Return back to the caller */
+    return Status;
+}
+
+NTSTATUS
+EfiConInReset (
+    VOID
+    )
+{
+    BL_ARCH_MODE OldMode;
+    EFI_STATUS EfiStatus;
+
+    /* Are we in protected mode? */
+    OldMode = CurrentExecutionContext->Mode;
+    if (OldMode != BlRealMode)
+    {
+        /* FIXME: Not yet implemented */
+        return STATUS_NOT_IMPLEMENTED;
+    }
+
+    /* Make the EFI call */
+    EfiStatus = EfiConIn->Reset(EfiConIn, FALSE);
+
+    /* Switch back to protected mode if we came from there */
+    if (OldMode != BlRealMode)
+    {
+        BlpArchSwitchContext(OldMode);
+    }
+
+    /* Convert the error to an NTSTATUS */
+    return EfiGetNtStatusCode(EfiStatus);
+}
+
+NTSTATUS
+EfiConInExReset (
+    VOID
+    )
+{
+    BL_ARCH_MODE OldMode;
+    EFI_STATUS EfiStatus;
+
+    /* Are we in protected mode? */
+    OldMode = CurrentExecutionContext->Mode;
+    if (OldMode != BlRealMode)
+    {
+        /* FIXME: Not yet implemented */
+        return STATUS_NOT_IMPLEMENTED;
+    }
+
+    /* Make the EFI call */
+    EfiStatus = EfiConInEx->Reset(EfiConInEx, FALSE);
+
+    /* Switch back to protected mode if we came from there */
+    if (OldMode != BlRealMode)
+    {
+        BlpArchSwitchContext(OldMode);
+    }
+
+    /* Convert the error to an NTSTATUS */
+    return EfiGetNtStatusCode(EfiStatus);
+}
+
 NTSTATUS
 EfiConInExSetState (
     _In_ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *ConInEx,
@@ -328,13 +564,27 @@ EfiGetMemoryMap (
 {
     BL_ARCH_MODE OldMode;
     EFI_STATUS EfiStatus;
+    PHYSICAL_ADDRESS MemoryMapSizePhysical, MemoryMapPhysical, MapKeyPhysical;
+    PHYSICAL_ADDRESS DescriptorSizePhysical, DescriptorVersionPhysical;
 
     /* Are we in protected mode? */
     OldMode = CurrentExecutionContext->Mode;
     if (OldMode != BlRealMode)
     {
-        /* FIXME: Not yet implemented */
-        return STATUS_NOT_IMPLEMENTED;
+        /* Convert all of the addresses to physical */
+        BlMmTranslateVirtualAddress(MemoryMapSize, &MemoryMapSizePhysical);
+        MemoryMapSize = (UINTN*)MemoryMapSizePhysical.LowPart;
+        BlMmTranslateVirtualAddress(MemoryMap, &MemoryMapPhysical);
+        MemoryMap = (EFI_MEMORY_DESCRIPTOR*)MemoryMapPhysical.LowPart;
+        BlMmTranslateVirtualAddress(MapKey, &MapKeyPhysical);
+        MapKey = (UINTN*)MapKeyPhysical.LowPart;
+        BlMmTranslateVirtualAddress(DescriptorSize, &DescriptorSizePhysical);
+        DescriptorSize = (UINTN*)DescriptorSizePhysical.LowPart;
+        BlMmTranslateVirtualAddress(DescriptorVersion, &DescriptorVersionPhysical);
+        DescriptorVersion = (UINTN*)DescriptorVersionPhysical.LowPart;
+
+        /* Switch to real mode */
+        BlpArchSwitchContext(BlProtectedMode);
     }
 
     /* Make the EFI call */
@@ -566,6 +816,37 @@ EfiConOutEnableCursor (
     return EfiGetNtStatusCode(EfiStatus);
 }
 
+NTSTATUS
+EfiConOutOutputString (
+    _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface,
+    _In_ PWCHAR String
+    )
+{
+    BL_ARCH_MODE OldMode;
+    EFI_STATUS EfiStatus;
+
+    /* Are we in protected mode? */
+    OldMode = CurrentExecutionContext->Mode;
+    if (OldMode != BlRealMode)
+    {
+        /* FIXME: Not yet implemented */
+        return STATUS_NOT_IMPLEMENTED;
+    }
+
+    /* Make the EFI call */
+    EfiStatus = TextInterface->OutputString(TextInterface, String);
+
+    /* Switch back to protected mode if we came from there */
+    if (OldMode != BlRealMode)
+    {
+        BlpArchSwitchContext(OldMode);
+    }
+
+    /* Convert the error to an NTSTATUS */
+    return EfiGetNtStatusCode(EfiStatus);
+}
+
+
 VOID
 EfiConOutReadCurrentMode (
     _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface,
@@ -692,7 +973,7 @@ EfiGopSetMode (
     if ((ModeChanged) && (NT_SUCCESS(Status)))
     {
         /* FIXME @TODO: Should be BlStatusPrint */
-        EfiPrintf(L"Console video mode  set to 0x%x\r\r\n", Mode);
+        EfiPrintf(L"Console video mode set to 0x%x\r\n", Mode);
     }
 
     /* Convert the error to an NTSTATUS */
@@ -792,6 +1073,42 @@ EfiResetSystem (
     EfiRT->ResetSystem(ResetType, EFI_SUCCESS, 0, NULL);
 }
 
+NTSTATUS
+EfiConnectController (
+    _In_ EFI_HANDLE ControllerHandle
+    )
+{
+    BL_ARCH_MODE OldMode;
+    EFI_STATUS EfiStatus;
+
+    /* Is this EFI 1.02? */
+    if (EfiST->Hdr.Revision == EFI_1_02_SYSTEM_TABLE_REVISION)
+    {
+        /* This function didn't exist back then */
+        return STATUS_NOT_SUPPORTED;
+    }
+
+    /* Are we in protected mode? */
+    OldMode = CurrentExecutionContext->Mode;
+    if (OldMode != BlRealMode)
+    {
+        /* FIXME: Not yet implemented */
+        return STATUS_NOT_IMPLEMENTED;
+    }
+
+    /* Make the EFI call */
+    EfiStatus = EfiBS->ConnectController(ControllerHandle, NULL, NULL, TRUE);
+
+    /* Switch back to protected mode if we came from there */
+    if (OldMode != BlRealMode)
+    {
+        BlpArchSwitchContext(OldMode);
+    }
+
+    /* Convert the error to an NTSTATUS */
+    return EfiGetNtStatusCode(EfiStatus);
+}
+
 NTSTATUS
 EfiAllocatePages (
     _In_ ULONG Type,
@@ -823,6 +1140,129 @@ EfiAllocatePages (
     return EfiGetNtStatusCode(EfiStatus);
 }
 
+NTSTATUS
+EfipGetSystemTable (
+    _In_ EFI_GUID *TableGuid,
+    _Out_ PPHYSICAL_ADDRESS TableAddress
+    )
+{
+    ULONG i;
+    NTSTATUS Status;
+
+    /* Assume failure */
+    Status = STATUS_NOT_FOUND;
+
+    /* Loop through the configuration tables */
+    for (i = 0; i < EfiST->NumberOfTableEntries; i++)
+    {
+        /* Check if this one matches the one we want */
+        if (RtlEqualMemory(&EfiST->ConfigurationTable[i].VendorGuid,
+                           TableGuid,
+                           sizeof(*TableGuid)))
+        {
+            /* Return its address */
+            TableAddress->QuadPart = (ULONG_PTR)EfiST->ConfigurationTable[i].VendorTable;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+    }
+
+    /* Return the search result */
+    return Status;
+}
+
+NTSTATUS
+EfipGetRsdt (
+    _Out_ PPHYSICAL_ADDRESS FoundRsdt
+    )
+{
+    NTSTATUS Status;
+    ULONG Length;
+    PHYSICAL_ADDRESS RsdpAddress, Rsdt;
+    PRSDP Rsdp;
+
+    /* Assume failure */
+    Length = 0;
+    Rsdp = NULL;
+
+    /* Check if we already know it */
+    if (EfiRsdt.QuadPart)
+    {
+        /* Return it */
+        *FoundRsdt = EfiRsdt;
+        return STATUS_SUCCESS;
+    }
+
+    /* Otherwise, look for the ACPI 2.0 RSDP (XSDT really) */
+    Status = EfipGetSystemTable(&EfiRootAcpiTableGuid, &RsdpAddress);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Didn't fint it, look for the ACPI 1.0 RSDP (RSDT really) */
+        Status = EfipGetSystemTable(&EfiRootAcpiTable10Guid, &RsdpAddress);
+        if (!NT_SUCCESS(Status))
+        {
+            return Status;
+        }
+    }
+
+    /* Map it */
+    Length = sizeof(*Rsdp);
+    Status = BlMmMapPhysicalAddressEx((PVOID*)&Rsdp,
+                                      0,
+                                      Length,
+                                      RsdpAddress);
+    if (NT_SUCCESS(Status))
+    {
+        /* Check the revision (anything >= 2.0 is XSDT) */
+        if (Rsdp->Revision)
+        {
+            /* Check if the table is bigger than just its header */
+            if (Rsdp->Length > Length)
+            {
+                /* Capture the real length */
+                Length = Rsdp->Length;
+
+                /* Unmap our header mapping */
+                BlMmUnmapVirtualAddressEx(Rsdp, sizeof(*Rsdp));
+
+                /* And map the whole thing now */
+                Status = BlMmMapPhysicalAddressEx((PVOID*)&Rsdp,
+                                                  0,
+                                                  Length,
+                                                  RsdpAddress);
+                if (!NT_SUCCESS(Status))
+                {
+                    return Status;
+                }
+            }
+
+            /* Read the XSDT address from the table*/
+            Rsdt = Rsdp->XsdtAddress;
+        }
+        else
+        {
+            /* ACPI 1.0 so just read the RSDT */
+            Rsdt.QuadPart = Rsdp->RsdtAddress;
+        }
+
+        /* Save it for later */
+        EfiRsdt = Rsdt;
+
+        /* And return it back */
+        *FoundRsdt = Rsdt;
+    }
+
+    /* Check if we had mapped the RSDP */
+    if (Rsdp)
+    {
+        /* Unmap it */
+        BlMmUnmapVirtualAddressEx(Rsdp, Length);
+    }
+
+    /* Return search result back to caller */
+    return Status;
+}
+
 BL_MEMORY_ATTR
 MmFwpGetOsAttributeType (
     _In_ ULONGLONG Attribute
@@ -949,7 +1389,7 @@ MmFwGetMemoryMap (
     NTSTATUS Status;
     ULONGLONG Pages, StartPage, EndPage;
     UINTN EfiMemoryMapSize, MapKey, DescriptorSize, DescriptorVersion;
-    EFI_PHYSICAL_ADDRESS EfiBuffer;
+    EFI_PHYSICAL_ADDRESS EfiBuffer = 0;
     EFI_MEMORY_DESCRIPTOR* EfiMemoryMap;
     EFI_STATUS EfiStatus;
     BL_ARCH_MODE OldMode;
@@ -1105,7 +1545,7 @@ MmFwGetMemoryMap (
 
     /* Loop the EFI memory map */
 #if 0
-    EfiPrintf(L"UEFI MEMORY MAP\n\r\n");
+    EfiPrintf(L"UEFI MEMORY MAP\r\n\r\n");
     EfiPrintf(L"TYPE        START              END                   ATTRIBUTES\r\n");
     EfiPrintf(L"===============================================================\r\n");
 #endif
@@ -1211,7 +1651,8 @@ MmFwGetMemoryMap (
                 if (Descriptor->Type == BlConventionalMemory)
                 {
                     /* Set the reserved flag on the descriptor */
-                    Descriptor->Flags |= BlReservedMemory;
+                    EfiPrintf(L"Adding magic flag\r\n");
+                    Descriptor->Flags |= BlMemoryReserved;
                 }
 
                 /* Add this descriptor into the list */
@@ -1255,15 +1696,16 @@ MmFwGetMemoryMap (
         if ((Descriptor->Type == BlConventionalMemory) && (EndPage <= 0x100))
         {
             /* Set the reserved flag on the descriptor */
-            Descriptor->Flags |= BlReservedMemory;
+            EfiPrintf(L"Adding magic flag\r\n");
+            Descriptor->Flags |= BlMemoryReserved;
         }
 
         /* Add the descriptor to the list, requesting coalescing as asked */
         Status = MmMdAddDescriptorToList(MemoryMap,
                                          Descriptor,
                                          BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG |
-                                         (Flags & BL_MM_FLAG_REQUEST_COALESCING) ?
-                                         BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG : 0);
+                                         ((Flags & BL_MM_FLAG_REQUEST_COALESCING) ?
+                                          BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG : 0));
         if (!NT_SUCCESS(Status))
         {
             EfiPrintf(L"Failed to add full descriptor: %lx\r\n", Status);
@@ -1306,7 +1748,7 @@ BlpFwInitialize (
     NTSTATUS Status = STATUS_SUCCESS;
     EFI_KEY_TOGGLE_STATE KeyToggleState;
 
-    /* Check if we have vaild firmware data */
+    /* Check if we have valid firmware data */
     if (!(FirmwareData) || !(FirmwareData->Version))
     {
         return STATUS_INVALID_PARAMETER;
@@ -1340,7 +1782,7 @@ BlpFwInitialize (
             /* FIXME: Not supported */
             Status = STATUS_NOT_SUPPORTED;
         }
-        else if (FirmwareData->Version >= 2)
+        else if (FirmwareData->Version >= BL_FIRMWARE_DESCRIPTOR_VERSION)
         {
             /* Version 2 -- save the data */
             EfiFirmwareData = *FirmwareData;
@@ -1366,6 +1808,107 @@ BlpFwInitialize (
     return Status;
 }
 
+NTSTATUS
+BlFwGetParameters (
+    _In_ PBL_FIRMWARE_DESCRIPTOR Parameters
+    )
+{
+    /* Make sure we got an argument */
+    if (!Parameters)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Copy the static data */
+    *Parameters = *EfiFirmwareParameters;
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+BlFwEnumerateDevice (
+    _In_ PBL_DEVICE_DESCRIPTOR Device
+    )
+{
+    NTSTATUS Status;
+    ULONG PathProtocols, BlockProtocols;
+    EFI_HANDLE* PathArray;
+    EFI_HANDLE* BlockArray;
+
+    /* Initialize locals */
+    BlockArray = NULL;
+    PathArray = NULL;
+    PathProtocols = 0;
+    BlockProtocols = 0;
+
+    /* Enumeration only makes sense on disks or partitions */
+    if ((Device->DeviceType != DiskDevice) &&
+        (Device->DeviceType != LegacyPartitionDevice) &&
+        (Device->DeviceType != PartitionDevice))
+    {
+        return STATUS_NOT_SUPPORTED;
+    }
+
+    /* Enumerate the list of device paths */
+    Status = EfiLocateHandleBuffer(ByProtocol,
+                                   &EfiDevicePathProtocol,
+                                   &PathProtocols,
+                                   &PathArray);
+    if (NT_SUCCESS(Status))
+    {
+        /* Loop through each one */
+        Status = STATUS_NOT_FOUND;
+        while (PathProtocols)
+        {
+            /* Attempt to connect the driver for this device epath */
+            Status = EfiConnectController(PathArray[--PathProtocols]);
+            if (NT_SUCCESS(Status))
+            {
+                /* Now enumerate any block I/O devices the driver added */
+                Status = EfiLocateHandleBuffer(ByProtocol,
+                                               &EfiBlockIoProtocol,
+                                               &BlockProtocols,
+                                               &BlockArray);
+                if (!NT_SUCCESS(Status))
+                {
+                    break;
+                }
+
+                /* Loop through each one */
+                while (BlockProtocols)
+                {
+                    /* Check if one of the new devices is the one we want */
+                    Status = BlockIoEfiCompareDevice(Device,
+                                                     BlockArray[--BlockProtocols]);
+                    if (NT_SUCCESS(Status))
+                    {
+                        /* Yep, all done */
+                        goto Quickie;
+                    }
+                }
+
+                /* Move on to the next device path */
+                BlMmFreeHeap(BlockArray);
+                BlockArray = NULL;
+            }
+        }
+    }
+
+Quickie:
+    /* We're done -- free the array of device path protocols, if any */
+    if (PathArray)
+    {
+        BlMmFreeHeap(PathArray);
+    }
+
+    /* We're done -- free the array of block I/O protocols, if any */
+    if (BlockArray)
+    {
+        BlMmFreeHeap(BlockArray);
+    }
+
+    /* Return if we found the device or not */
+    return Status;
+}
 
 /*++
  * @name EfiGetEfiStatusCode