summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal/DevicePathDxe/DevicePathToText.c
diff options
context:
space:
mode:
authorxgu3 <xgu3@6f19259b-4bc3-4df7-8a09-765794883524>2007-07-05 07:05:28 +0000
committerxgu3 <xgu3@6f19259b-4bc3-4df7-8a09-765794883524>2007-07-05 07:05:28 +0000
commit95276127e373f2e2fb2a208ff77267422a197d9f (patch)
tree44e70c799deb743571f752bf72b0b69078e27457 /MdeModulePkg/Universal/DevicePathDxe/DevicePathToText.c
parent8a7f0c4c6b814fe50a18ed0c96e3d871e98bd224 (diff)
downloadedk2-95276127e373f2e2fb2a208ff77267422a197d9f.zip
edk2-95276127e373f2e2fb2a208ff77267422a197d9f.tar.gz
edk2-95276127e373f2e2fb2a208ff77267422a197d9f.tar.bz2
Check in following modules,
DxeIpl ConPlatform ConSplitter GraphicsConsole Terminal DevicePath git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3069 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Universal/DevicePathDxe/DevicePathToText.c')
-rw-r--r--MdeModulePkg/Universal/DevicePathDxe/DevicePathToText.c1503
1 files changed, 1503 insertions, 0 deletions
diff --git a/MdeModulePkg/Universal/DevicePathDxe/DevicePathToText.c b/MdeModulePkg/Universal/DevicePathDxe/DevicePathToText.c
new file mode 100644
index 0000000..c024ccf
--- /dev/null
+++ b/MdeModulePkg/Universal/DevicePathDxe/DevicePathToText.c
@@ -0,0 +1,1503 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ DevicePathToText.c
+
+Abstract:
+
+ DevicePathToText protocol as defined in the UEFI 2.0 specification.
+
+--*/
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+#include "DevicePath.h"
+
+STATIC
+EFI_DEVICE_PATH_PROTOCOL *
+UnpackDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevPath
+ )
+/*++
+
+ Routine Description:
+ Function unpacks a device path data structure so that all the nodes of a device path
+ are naturally aligned.
+
+ Arguments:
+ DevPath - A pointer to a device path data structure
+
+ Returns:
+ If the memory for the device path is successfully allocated, then a pointer to the
+ new device path is returned. Otherwise, NULL is returned.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *Src;
+ EFI_DEVICE_PATH_PROTOCOL *Dest;
+ EFI_DEVICE_PATH_PROTOCOL *NewPath;
+ UINTN Size;
+
+ if (DevPath == NULL) {
+ return NULL;
+ }
+ //
+ // Walk device path and round sizes to valid boundries
+ //
+ Src = DevPath;
+ Size = 0;
+ for (;;) {
+ Size += DevicePathNodeLength (Src);
+ Size += ALIGN_SIZE (Size);
+
+ if (IsDevicePathEnd (Src)) {
+ break;
+ }
+
+ Src = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (Src);
+ }
+ //
+ // Allocate space for the unpacked path
+ //
+ NewPath = AllocateZeroPool (Size);
+ if (NewPath != NULL) {
+
+ ASSERT (((UINTN) NewPath) % MIN_ALIGNMENT_SIZE == 0);
+
+ //
+ // Copy each node
+ //
+ Src = DevPath;
+ Dest = NewPath;
+ for (;;) {
+ Size = DevicePathNodeLength (Src);
+ CopyMem (Dest, Src, Size);
+ Size += ALIGN_SIZE (Size);
+ SetDevicePathNodeLength (Dest, Size);
+ Dest->Type |= EFI_DP_TYPE_UNPACKED;
+ Dest = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) Dest) + Size);
+
+ if (IsDevicePathEnd (Src)) {
+ break;
+ }
+
+ Src = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (Src);
+ }
+ }
+
+ return NewPath;
+}
+
+STATIC
+VOID *
+ReallocatePool (
+ IN VOID *OldPool,
+ IN UINTN OldSize,
+ IN UINTN NewSize
+ )
+/*++
+
+ Routine Description:
+ Adjusts the size of a previously allocated buffer.
+
+ Arguments:
+ OldPool - A pointer to the buffer whose size is being adjusted.
+ OldSize - The size of the current buffer.
+ NewSize - The size of the new buffer.
+
+ Returns:
+ EFI_SUCEESS - The requested number of bytes were allocated.
+ EFI_OUT_OF_RESOURCES - The pool requested could not be allocated.
+ EFI_INVALID_PARAMETER - The buffer was invalid.
+
+--*/
+{
+ VOID *NewPool;
+
+ NewPool = NULL;
+ if (NewSize) {
+ NewPool = AllocateZeroPool (NewSize);
+ }
+
+ if (OldPool) {
+ if (NewPool) {
+ CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
+ }
+
+ FreePool (OldPool);
+ }
+
+ return NewPool;
+}
+
+STATIC
+CHAR16 *
+CatPrint (
+ IN OUT POOL_PRINT *Str,
+ IN CHAR16 *Fmt,
+ ...
+ )
+/*++
+
+ Routine Description:
+ Concatenates a formatted unicode string to allocated pool.
+ The caller must free the resulting buffer.
+
+ Arguments:
+ Str - Tracks the allocated pool, size in use, and
+ amount of pool allocated.
+ Fmt - The format string
+
+ Returns:
+ Allocated buffer with the formatted string printed in it.
+ The caller must free the allocated buffer. The buffer
+ allocation is not packed.
+
+--*/
+{
+ UINT16 *AppendStr;
+ VA_LIST Args;
+ UINTN Size;
+
+ AppendStr = AllocateZeroPool (0x1000);
+ if (AppendStr == NULL) {
+ return Str->Str;
+ }
+
+ VA_START (Args, Fmt);
+ UnicodeVSPrint (AppendStr, 0x1000, Fmt, Args);
+ VA_END (Args);
+ if (NULL == Str->Str) {
+ Size = StrSize (AppendStr);
+ Str->Str = AllocateZeroPool (Size);
+ ASSERT (Str->Str != NULL);
+ } else {
+ Size = StrSize (AppendStr) - sizeof (UINT16);
+ Size = Size + StrSize (Str->Str);
+ Str->Str = ReallocatePool (
+ Str->Str,
+ StrSize (Str->Str),
+ Size
+ );
+ ASSERT (Str->Str != NULL);
+ }
+
+ Str->MaxLen = MAX_CHAR * sizeof (UINT16);
+ if (Size < Str->MaxLen) {
+ StrCat (Str->Str, AppendStr);
+ Str->Len = Size - sizeof (UINT16);
+ }
+
+ FreePool (AppendStr);
+ return Str->Str;
+}
+
+STATIC
+VOID
+DevPathToTextPci (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ PCI_DEVICE_PATH *Pci;
+
+ Pci = DevPath;
+ CatPrint (Str, L"Pci(%x,%x)", Pci->Function, Pci->Device);
+}
+
+STATIC
+VOID
+DevPathToTextPccard (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ PCCARD_DEVICE_PATH *Pccard;
+
+ Pccard = DevPath;
+ CatPrint (Str, L"PcCard(%x)", Pccard->FunctionNumber);
+}
+
+STATIC
+VOID
+DevPathToTextMemMap (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MEMMAP_DEVICE_PATH *MemMap;
+
+ MemMap = DevPath;
+ CatPrint (
+ Str,
+ L"MemoryMapped(%lx,%lx)",
+ MemMap->StartingAddress,
+ MemMap->EndingAddress
+ );
+}
+
+STATIC
+VOID
+DevPathToTextVendor (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+ CHAR16 *Type;
+ UINTN Index;
+ UINT32 FlowControlMap;
+ UINT16 Info;
+
+ Vendor = (VENDOR_DEVICE_PATH *) DevPath;
+ switch (DevicePathType (&Vendor->Header)) {
+ case HARDWARE_DEVICE_PATH:
+ Type = L"Hw";
+ break;
+
+ case MESSAGING_DEVICE_PATH:
+ Type = L"Msg";
+ if (AllowShortcuts) {
+ if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {
+ CatPrint (Str, L"VenPcAnsi()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {
+ CatPrint (Str, L"VenVt100()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {
+ CatPrint (Str, L"VenVt100Plus()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {
+ CatPrint (Str, L"VenUft8()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingUartFlowControlGuid)) {
+ FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);
+ switch (FlowControlMap & 0x00000003) {
+ case 0:
+ CatPrint (Str, L"UartFlowCtrl(%s)", L"None");
+ break;
+
+ case 1:
+ CatPrint (Str, L"UartFlowCtrl(%s)", L"Hardware");
+ break;
+
+ case 2:
+ CatPrint (Str, L"UartFlowCtrl(%s)", L"XonXoff");
+ break;
+
+ default:
+ break;
+ }
+
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingSASGuid)) {
+ CatPrint (
+ Str,
+ L"SAS(%lx,%lx,%x,",
+ ((SAS_DEVICE_PATH *) Vendor)->SasAddress,
+ ((SAS_DEVICE_PATH *) Vendor)->Lun,
+ ((SAS_DEVICE_PATH *) Vendor)->RelativeTargetPort
+ );
+ Info = (((SAS_DEVICE_PATH *) Vendor)->DeviceTopology);
+ if ((Info & 0x0f) == 0) {
+ CatPrint (Str, L"NoTopology,0,0,0,");
+ } else if (((Info & 0x0f) == 1) || ((Info & 0x0f) == 2)) {
+ CatPrint (
+ Str,
+ L"%s,%s,%s,",
+ (Info & (0x1 << 4)) ? L"SATA" : L"SAS",
+ (Info & (0x1 << 5)) ? L"External" : L"Internal",
+ (Info & (0x1 << 6)) ? L"Expanded" : L"Direct"
+ );
+ if ((Info & 0x0f) == 1) {
+ CatPrint (Str, L"0,");
+ } else {
+ CatPrint (Str, L"%x,", (Info >> 8) & 0xff);
+ }
+ } else {
+ CatPrint (Str, L"0,0,0,0,");
+ }
+
+ CatPrint (Str, L"%x)", ((SAS_DEVICE_PATH *) Vendor)->Reserved);
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {
+ CatPrint (Str, L"DebugPort()");
+ return ;
+ } else {
+ return ;
+ //
+ // reserved
+ //
+ }
+ }
+ break;
+
+ case MEDIA_DEVICE_PATH:
+ Type = L"Media";
+ break;
+
+ default:
+ Type = L"?";
+ break;
+ }
+
+ CatPrint (Str, L"Ven%s(%g,", Type, &Vendor->Guid);
+ for (Index = 0; Index < DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH); Index++) {
+ CatPrint (Str, L"%02x", ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);
+ }
+
+ CatPrint (Str, L")");
+}
+
+STATIC
+VOID
+DevPathToTextController (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CONTROLLER_DEVICE_PATH *Controller;
+
+ Controller = DevPath;
+ CatPrint (
+ Str,
+ L"Ctrl(%x)",
+ Controller->ControllerNumber
+ );
+}
+
+STATIC
+VOID
+DevPathToTextAcpi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ Acpi = DevPath;
+ if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+ if (AllowShortcuts) {
+ switch (EISA_ID_TO_NUM (Acpi->HID)) {
+ case 0x0a03:
+ CatPrint (Str, L"PciRoot(%x)", Acpi->UID);
+ break;
+
+ case 0x0604:
+ CatPrint (Str, L"Floppy(%x)", Acpi->UID);
+ break;
+
+ case 0x0301:
+ CatPrint (Str, L"Keyboard(%x)", Acpi->UID);
+ break;
+
+ case 0x0501:
+ CatPrint (Str, L"Serial(%x)", Acpi->UID);
+ break;
+
+ case 0x0401:
+ CatPrint (Str, L"ParallelPort(%x)", Acpi->UID);
+ break;
+
+ default:
+ break;
+ }
+
+ return ;
+ }
+
+ CatPrint (Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
+ } else {
+ CatPrint (Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID);
+ }
+}
+
+#define NextStrA(a) ((UINT8 *) (((UINT8 *) (a)) + AsciiStrLen ((CHAR8 *) (a)) + 1))
+
+STATIC
+VOID
+DevPathToTextExtAcpi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR *AcpiExt;
+ UINT8 *NextString;
+
+ AcpiExt = DevPath;
+
+ if (AllowShortcuts) {
+ NextString = NextStrA (AcpiExt->HidUidCidStr);
+ if ((*(AcpiExt->HidUidCidStr) == '\0') &&
+ (*(NextStrA (NextString)) == '\0') &&
+ (AcpiExt->UID == 0)
+ ) {
+ if ((AcpiExt->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+ CatPrint (
+ Str,
+ L"AcpiExp(PNP%04x,%x,%a)",
+ EISA_ID_TO_NUM (AcpiExt->HID),
+ AcpiExt->CID,
+ NextStrA (AcpiExt->HidUidCidStr)
+ );
+ } else {
+ CatPrint (
+ Str,
+ L"AcpiExp(%08x,%x,%a)",
+ AcpiExt->HID,
+ AcpiExt->CID,
+ NextStrA (AcpiExt->HidUidCidStr)
+ );
+ }
+ }
+ return ;
+ }
+
+ NextString = NextStrA (AcpiExt->HidUidCidStr);
+ NextString = NextStrA (NextString);
+ if ((AcpiExt->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+ CatPrint (
+ Str,
+ L"AcpiEx(PNP%04x,%x,%x,%a,%a,%a)",
+ EISA_ID_TO_NUM (AcpiExt->HID),
+ AcpiExt->CID,
+ AcpiExt->UID,
+ AcpiExt->HidUidCidStr,
+ NextString,
+ NextStrA (AcpiExt->HidUidCidStr)
+ );
+ } else {
+ CatPrint (
+ Str,
+ L"AcpiEx(%08x,%x,%x,%a,%a,%a)",
+ AcpiExt->HID,
+ AcpiExt->CID,
+ AcpiExt->UID,
+ AcpiExt->HidUidCidStr,
+ NextString,
+ NextStrA (AcpiExt->HidUidCidStr)
+ );
+ }
+}
+
+STATIC
+VOID
+DevPathToTextAtapi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ATAPI_DEVICE_PATH *Atapi;
+
+ Atapi = DevPath;
+
+ if (DisplayOnly) {
+ CatPrint (Str, L"Ata(%x)", Atapi->Lun);
+ } else {
+ CatPrint (
+ Str,
+ L"Ata(%s,%s,%x)",
+ Atapi->PrimarySecondary ? L"Secondary" : L"Primary",
+ Atapi->SlaveMaster ? L"Slave" : L"Master",
+ Atapi->Lun
+ );
+ }
+}
+
+STATIC
+VOID
+DevPathToTextScsi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ SCSI_DEVICE_PATH *Scsi;
+
+ Scsi = DevPath;
+ CatPrint (Str, L"Scsi(%x,%x)", Scsi->Pun, Scsi->Lun);
+}
+
+STATIC
+VOID
+DevPathToTextFibre (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ FIBRECHANNEL_DEVICE_PATH *Fibre;
+
+ Fibre = DevPath;
+ CatPrint (Str, L"Fibre(%lx,%lx)", Fibre->WWN, Fibre->Lun);
+}
+
+STATIC
+VOID
+DevPathToText1394 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ F1394_DEVICE_PATH *F1394;
+
+ F1394 = DevPath;
+ CatPrint (Str, L"I1394(%lx)", F1394->Guid);
+}
+
+STATIC
+VOID
+DevPathToTextUsb (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ USB_DEVICE_PATH *Usb;
+
+ Usb = DevPath;
+ CatPrint (Str, L"USB(%x,%x)", Usb->ParentPortNumber, Usb->InterfaceNumber);
+}
+
+STATIC
+VOID
+DevPathToTextUsbWWID (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ USB_WWID_DEVICE_PATH *UsbWWId;
+
+ UsbWWId = DevPath;
+ CatPrint (
+ Str,
+ L"UsbWwid(%x,%x,%x,\"WWID\")",
+ UsbWWId->VendorId,
+ UsbWWId->ProductId,
+ UsbWWId->InterfaceNumber
+ );
+}
+
+STATIC
+VOID
+DevPathToTextLogicalUnit (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
+
+ LogicalUnit = DevPath;
+ CatPrint (Str, L"Unit(%x)", LogicalUnit->Lun);
+}
+
+STATIC
+VOID
+DevPathToTextUsbClass (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ USB_CLASS_DEVICE_PATH *UsbClass;
+
+ UsbClass = DevPath;
+
+ if (AllowShortcuts == TRUE) {
+ switch (UsbClass->DeviceClass) {
+ case 1:
+ CatPrint (
+ Str,
+ L"UsbAudio(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 2:
+ CatPrint (
+ Str,
+ L"UsbCDCControl(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 3:
+ CatPrint (
+ Str,
+ L"UsbHID(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 6:
+ CatPrint (
+ Str,
+ L"UsbImage(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 7:
+ CatPrint (
+ Str,
+ L"UsbPrinter(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 8:
+ CatPrint (
+ Str,
+ L"UsbMassStorage(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 9:
+ CatPrint (
+ Str,
+ L"UsbHub(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 10:
+ CatPrint (
+ Str,
+ L"UsbCDCData(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 11:
+ CatPrint (
+ Str,
+ L"UsbSmartCard(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 14:
+ CatPrint (
+ Str,
+ L"UsbVideo(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 220:
+ CatPrint (
+ Str,
+ L"UsbDiagnostic(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 224:
+ CatPrint (
+ Str,
+ L"UsbWireless(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 254:
+ if (UsbClass->DeviceSubClass == 1) {
+ CatPrint (
+ Str,
+ L"UsbDeviceFirmwareUpdate(%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceProtocol
+ );
+ } else if (UsbClass->DeviceSubClass == 2) {
+ CatPrint (
+ Str,
+ L"UsbIrdaBridge(%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceProtocol
+ );
+ } else if (UsbClass->DeviceSubClass == 3) {
+ CatPrint (
+ Str,
+ L"UsbTestAndMeasurement(%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceProtocol
+ );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return ;
+ }
+
+ CatPrint (
+ Str,
+ L"UsbClass(%x,%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceClass,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+}
+
+STATIC
+VOID
+DevPathToTextI2O (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ I2O_DEVICE_PATH *I2O;
+
+ I2O = DevPath;
+ CatPrint (Str, L"I2O(%x)", I2O->Tid);
+}
+
+STATIC
+VOID
+DevPathToTextMacAddr (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MAC_ADDR_DEVICE_PATH *MAC;
+ UINTN HwAddressSize;
+ UINTN Index;
+
+ MAC = DevPath;
+
+ HwAddressSize = sizeof (EFI_MAC_ADDRESS);
+ if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
+ HwAddressSize = 6;
+ }
+
+ CatPrint (Str, L"MAC(");
+
+ for (Index = 0; Index < HwAddressSize; Index++) {
+ CatPrint (Str, L"%02x", MAC->MacAddress.Addr[Index]);
+ }
+
+ CatPrint (Str, L",%x)", MAC->IfType);
+}
+
+STATIC
+VOID
+DevPathToTextIPv4 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ IPv4_DEVICE_PATH *IP;
+
+ IP = DevPath;
+ if (DisplayOnly == TRUE) {
+ CatPrint (
+ Str,
+ L"IPv4(%d.%d.%d.%d)",
+ IP->RemoteIpAddress.Addr[0],
+ IP->RemoteIpAddress.Addr[1],
+ IP->RemoteIpAddress.Addr[2],
+ IP->RemoteIpAddress.Addr[3]
+ );
+ return ;
+ }
+
+ CatPrint (
+ Str,
+ L"IPv4(%d.%d.%d.%d,%s,%s,%d.%d.%d.%d)",
+ IP->RemoteIpAddress.Addr[0],
+ IP->RemoteIpAddress.Addr[1],
+ IP->RemoteIpAddress.Addr[2],
+ IP->RemoteIpAddress.Addr[3],
+ IP->Protocol ? L"TCP" : L"UDP",
+ (IP->StaticIpAddress == TRUE) ? L"Static" : L"DHCP",
+ IP->LocalIpAddress.Addr[0],
+ IP->LocalIpAddress.Addr[1],
+ IP->LocalIpAddress.Addr[2],
+ IP->LocalIpAddress.Addr[3]
+ );
+}
+
+STATIC
+VOID
+DevPathToTextIPv6 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ IPv6_DEVICE_PATH *IP;
+
+ IP = DevPath;
+ if (DisplayOnly == TRUE) {
+ CatPrint (
+ Str,
+ L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",
+ IP->RemoteIpAddress.Addr[0],
+ IP->RemoteIpAddress.Addr[1],
+ IP->RemoteIpAddress.Addr[2],
+ IP->RemoteIpAddress.Addr[3],
+ IP->RemoteIpAddress.Addr[4],
+ IP->RemoteIpAddress.Addr[5],
+ IP->RemoteIpAddress.Addr[6],
+ IP->RemoteIpAddress.Addr[7],
+ IP->RemoteIpAddress.Addr[8],
+ IP->RemoteIpAddress.Addr[9],
+ IP->RemoteIpAddress.Addr[10],
+ IP->RemoteIpAddress.Addr[11],
+ IP->RemoteIpAddress.Addr[12],
+ IP->RemoteIpAddress.Addr[13],
+ IP->RemoteIpAddress.Addr[14],
+ IP->RemoteIpAddress.Addr[15]
+ );
+ return ;
+ }
+
+ CatPrint (
+ Str,
+ L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x,%s,%s,%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",
+ IP->RemoteIpAddress.Addr[0],
+ IP->RemoteIpAddress.Addr[1],
+ IP->RemoteIpAddress.Addr[2],
+ IP->RemoteIpAddress.Addr[3],
+ IP->RemoteIpAddress.Addr[4],
+ IP->RemoteIpAddress.Addr[5],
+ IP->RemoteIpAddress.Addr[6],
+ IP->RemoteIpAddress.Addr[7],
+ IP->RemoteIpAddress.Addr[8],
+ IP->RemoteIpAddress.Addr[9],
+ IP->RemoteIpAddress.Addr[10],
+ IP->RemoteIpAddress.Addr[11],
+ IP->RemoteIpAddress.Addr[12],
+ IP->RemoteIpAddress.Addr[13],
+ IP->RemoteIpAddress.Addr[14],
+ IP->RemoteIpAddress.Addr[15],
+ IP->Protocol ? L"TCP" : L"UDP",
+ (IP->StaticIpAddress == TRUE) ? L"Static" : L"DHCP",
+ IP->LocalIpAddress.Addr[0],
+ IP->LocalIpAddress.Addr[1],
+ IP->LocalIpAddress.Addr[2],
+ IP->LocalIpAddress.Addr[3],
+ IP->LocalIpAddress.Addr[4],
+ IP->LocalIpAddress.Addr[5],
+ IP->LocalIpAddress.Addr[6],
+ IP->LocalIpAddress.Addr[7],
+ IP->LocalIpAddress.Addr[8],
+ IP->LocalIpAddress.Addr[9],
+ IP->LocalIpAddress.Addr[10],
+ IP->LocalIpAddress.Addr[11],
+ IP->LocalIpAddress.Addr[12],
+ IP->LocalIpAddress.Addr[13],
+ IP->LocalIpAddress.Addr[14],
+ IP->LocalIpAddress.Addr[15]
+ );
+}
+
+STATIC
+VOID
+DevPathToTextInfiniBand (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+
+ InfiniBand = DevPath;
+ CatPrint (
+ Str,
+ L"Infiniband(%x,%g,%lx,%lx,%lx)",
+ InfiniBand->ResourceFlags,
+ InfiniBand->PortGid,
+ InfiniBand->ServiceId,
+ InfiniBand->TargetPortId,
+ InfiniBand->DeviceId
+ );
+}
+
+STATIC
+VOID
+DevPathToTextUart (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ UART_DEVICE_PATH *Uart;
+ CHAR8 Parity;
+
+ Uart = DevPath;
+ switch (Uart->Parity) {
+ case 0:
+ Parity = 'D';
+ break;
+
+ case 1:
+ Parity = 'N';
+ break;
+
+ case 2:
+ Parity = 'E';
+ break;
+
+ case 3:
+ Parity = 'O';
+ break;
+
+ case 4:
+ Parity = 'M';
+ break;
+
+ case 5:
+ Parity = 'S';
+ break;
+
+ default:
+ Parity = 'x';
+ break;
+ }
+
+ if (Uart->BaudRate == 0) {
+ CatPrint (Str, L"Uart(DEFAULT,");
+ } else {
+ CatPrint (Str, L"Uart(%ld,", Uart->BaudRate);
+ }
+
+ if (Uart->DataBits == 0) {
+ CatPrint (Str, L"DEFAULT,");
+ } else {
+ CatPrint (Str, L"%d,", Uart->DataBits);
+ }
+
+ CatPrint (Str, L"%c,", Parity);
+
+ switch (Uart->StopBits) {
+ case 0:
+ CatPrint (Str, L"D)");
+ break;
+
+ case 1:
+ CatPrint (Str, L"1)");
+ break;
+
+ case 2:
+ CatPrint (Str, L"1.5)");
+ break;
+
+ case 3:
+ CatPrint (Str, L"2)");
+ break;
+
+ default:
+ CatPrint (Str, L"x)");
+ break;
+ }
+}
+
+STATIC
+VOID
+DevPathToTextiSCSI (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ISCSI_DEVICE_PATH_WITH_NAME *iSCSI;
+ UINT16 Options;
+
+ iSCSI = DevPath;
+ CatPrint (
+ Str,
+ L"iSCSI(%s,%x,%lx,",
+ iSCSI->iSCSITargetName,
+ iSCSI->TargetPortalGroupTag,
+ iSCSI->Lun
+ );
+
+ Options = iSCSI->LoginOption;
+ CatPrint (Str, L"%s,", ((Options >> 1) & 0x0001) ? L"CRC32C" : L"None");
+ CatPrint (Str, L"%s,", ((Options >> 3) & 0x0001) ? L"CRC32C" : L"None");
+ if ((Options >> 11) & 0x0001) {
+ CatPrint (Str, L"%s,", L"None");
+ } else if ((Options >> 12) & 0x0001) {
+ CatPrint (Str, L"%s,", L"CHAP_UNI");
+ } else {
+ CatPrint (Str, L"%s,", L"CHAP_BI");
+
+ }
+
+ CatPrint (Str, L"%s)", (iSCSI->NetworkProtocol == 0) ? L"TCP" : L"reserved");
+}
+
+STATIC
+VOID
+DevPathToTextHardDrive (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ HARDDRIVE_DEVICE_PATH *Hd;
+
+ Hd = DevPath;
+ switch (Hd->SignatureType) {
+ case 0:
+ CatPrint (
+ Str,
+ L"HD(%d,%s,0,",
+ Hd->PartitionNumber,
+ L"None"
+ );
+ break;
+
+ case SIGNATURE_TYPE_MBR:
+ CatPrint (
+ Str,
+ L"HD(%d,%s,%08x,",
+ Hd->PartitionNumber,
+ L"MBR",
+ *((UINT32 *) (&(Hd->Signature[0])))
+ );
+ break;
+
+ case SIGNATURE_TYPE_GUID:
+ CatPrint (
+ Str,
+ L"HD(%d,%s,%g,",
+ Hd->PartitionNumber,
+ L"GUID",
+ (EFI_GUID *) &(Hd->Signature[0])
+ );
+ break;
+
+ default:
+ break;
+ }
+
+ CatPrint (Str, L"%lx,%lx)", Hd->PartitionStart, Hd->PartitionSize);
+}
+
+STATIC
+VOID
+DevPathToTextCDROM (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CDROM_DEVICE_PATH *Cd;
+
+ Cd = DevPath;
+ if (DisplayOnly == TRUE) {
+ CatPrint (Str, L"CDROM(%x)", Cd->BootEntry);
+ return ;
+ }
+
+ CatPrint (Str, L"CDROM(%x,%lx,%lx)", Cd->BootEntry, Cd->PartitionStart, Cd->PartitionSize);
+}
+
+STATIC
+VOID
+DevPathToTextFilePath (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ FILEPATH_DEVICE_PATH *Fp;
+
+ Fp = DevPath;
+ CatPrint (Str, L"%s", Fp->PathName);
+}
+
+STATIC
+VOID
+DevPathToTextMediaProtocol (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;
+
+ MediaProt = DevPath;
+ CatPrint (Str, L"Media(%g)", &MediaProt->Protocol);
+}
+
+STATIC
+VOID
+DevPathToTextBBS (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ BBS_BBS_DEVICE_PATH *Bbs;
+ CHAR16 *Type;
+
+ Bbs = DevPath;
+ switch (Bbs->DeviceType) {
+ case BBS_TYPE_FLOPPY:
+ Type = L"Floppy";
+ break;
+
+ case BBS_TYPE_HARDDRIVE:
+ Type = L"HD";
+ break;
+
+ case BBS_TYPE_CDROM:
+ Type = L"CDROM";
+ break;
+
+ case BBS_TYPE_PCMCIA:
+ Type = L"PCMCIA";
+ break;
+
+ case BBS_TYPE_USB:
+ Type = L"USB";
+ break;
+
+ case BBS_TYPE_EMBEDDED_NETWORK:
+ Type = L"Network";
+ break;
+
+ default:
+ Type = L"?";
+ break;
+ }
+
+ CatPrint (Str, L"BBS(%s,%a", Type, Bbs->String);
+
+ if (DisplayOnly == TRUE) {
+ CatPrint (Str, L")");
+ return ;
+ }
+
+ CatPrint (Str, L",%x)", Bbs->StatusFlag);
+}
+
+STATIC
+VOID
+DevPathToTextEndInstance (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CatPrint (Str, L",");
+}
+
+STATIC
+VOID
+DevPathToTextNodeUnknown (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CatPrint (Str, L"?");
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED const DEVICE_PATH_TO_TEXT_TABLE DevPathToTextTable[] = {
+ {HARDWARE_DEVICE_PATH, HW_PCI_DP, DevPathToTextPci},
+ {HARDWARE_DEVICE_PATH, HW_PCCARD_DP, DevPathToTextPccard},
+ {HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, DevPathToTextMemMap},
+ {HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DevPathToTextVendor},
+ {HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, DevPathToTextController},
+ {ACPI_DEVICE_PATH, ACPI_DP, DevPathToTextAcpi},
+ {ACPI_DEVICE_PATH, ACPI_EXTENDED_DP, DevPathToTextExtAcpi},
+ {MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, DevPathToTextAtapi},
+ {MESSAGING_DEVICE_PATH, MSG_SCSI_DP, DevPathToTextScsi},
+ {MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, DevPathToTextFibre},
+ {MESSAGING_DEVICE_PATH, MSG_1394_DP, DevPathToText1394},
+ {MESSAGING_DEVICE_PATH, MSG_USB_DP, DevPathToTextUsb},
+ {MESSAGING_DEVICE_PATH, MSG_USB_WWID_DP, DevPathToTextUsbWWID},
+ {MESSAGING_DEVICE_PATH, MSG_DEVICE_LOGICAL_UNIT_DP, DevPathToTextLogicalUnit},
+ {MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP, DevPathToTextUsbClass},
+ {MESSAGING_DEVICE_PATH, MSG_I2O_DP, DevPathToTextI2O},
+ {MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, DevPathToTextMacAddr},
+ {MESSAGING_DEVICE_PATH, MSG_IPv4_DP, DevPathToTextIPv4},
+ {MESSAGING_DEVICE_PATH, MSG_IPv6_DP, DevPathToTextIPv6},
+ {MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, DevPathToTextInfiniBand},
+ {MESSAGING_DEVICE_PATH, MSG_UART_DP, DevPathToTextUart},
+ {MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, DevPathToTextVendor},
+ {MESSAGING_DEVICE_PATH, MSG_ISCSI_DP, DevPathToTextiSCSI},
+ {MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, DevPathToTextHardDrive},
+ {MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, DevPathToTextCDROM},
+ {MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, DevPathToTextVendor},
+ {MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, DevPathToTextFilePath},
+ {MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, DevPathToTextMediaProtocol},
+ {MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, DevPathToTextFilePath},
+ {BBS_DEVICE_PATH, BBS_BBS_DP, DevPathToTextBBS},
+ {END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, DevPathToTextEndInstance},
+ {0, 0, NULL}
+};
+
+CHAR16 *
+ConvertDeviceNodeToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+/*++
+
+ Routine Description:
+ Convert a device node to its text representation.
+
+ Arguments:
+ DeviceNode - Points to the device node to be converted.
+ DisplayOnly - If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ AllowShortcuts - If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ Returns:
+ A pointer - a pointer to the allocated text representation of the device node.
+ NULL - if DeviceNode is NULL or there was insufficient memory.
+
+--*/
+{
+ POOL_PRINT Str;
+ UINTN Index;
+ UINTN NewSize;
+ VOID (*DumpNode)(POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);
+
+ if (DeviceNode == NULL) {
+ return NULL;
+ }
+
+ ZeroMem (&Str, sizeof (Str));
+
+ //
+ // Process the device path node
+ //
+ DumpNode = NULL;
+ for (Index = 0; DevPathToTextTable[Index].Function != NULL; Index++) {
+ if (DevicePathType (DeviceNode) == DevPathToTextTable[Index].Type &&
+ DevicePathSubType (DeviceNode) == DevPathToTextTable[Index].SubType
+ ) {
+ DumpNode = DevPathToTextTable[Index].Function;
+ break;
+ }
+ }
+ //
+ // If not found, use a generic function
+ //
+ if (DumpNode == NULL) {
+ DumpNode = DevPathToTextNodeUnknown;
+ }
+
+ //
+ // Print this node
+ //
+ DumpNode (&Str, (VOID *) DeviceNode, DisplayOnly, AllowShortcuts);
+
+ //
+ // Shrink pool used for string allocation
+ //
+ NewSize = (Str.Len + 1) * sizeof (CHAR16);
+ Str.Str = ReallocatePool (Str.Str, NewSize, NewSize);
+ ASSERT (Str.Str != NULL);
+ Str.Str[Str.Len] = 0;
+ return Str.Str;
+}
+
+CHAR16 *
+ConvertDevicePathToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+/*++
+
+ Routine Description:
+ Convert a device path to its text representation.
+
+ Arguments:
+ DeviceNode - Points to the device path to be converted.
+ DisplayOnly - If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ AllowShortcuts - If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ Returns:
+ A pointer - a pointer to the allocated text representation of the device path.
+ NULL - if DeviceNode is NULL or there was insufficient memory.
+
+--*/
+{
+ POOL_PRINT Str;
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
+ EFI_DEVICE_PATH_PROTOCOL *UnpackDevPath;
+ UINTN Index;
+ UINTN NewSize;
+ VOID (*DumpNode) (POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);
+
+ if (DevicePath == NULL) {
+ return NULL;
+ }
+
+ ZeroMem (&Str, sizeof (Str));
+
+ //
+ // Unpacked the device path
+ //
+ UnpackDevPath = UnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) DevicePath);
+ ASSERT (UnpackDevPath != NULL);
+
+ //
+ // Process each device path node
+ //
+ DevPathNode = UnpackDevPath;
+ while (!IsDevicePathEnd (DevPathNode)) {
+ //
+ // Find the handler to dump this device path node
+ //
+ DumpNode = NULL;
+ for (Index = 0; DevPathToTextTable[Index].Function; Index += 1) {
+
+ if (DevicePathType (DevPathNode) == DevPathToTextTable[Index].Type &&
+ DevicePathSubType (DevPathNode) == DevPathToTextTable[Index].SubType
+ ) {
+ DumpNode = DevPathToTextTable[Index].Function;
+ break;
+ }
+ }
+ //
+ // If not found, use a generic function
+ //
+ if (!DumpNode) {
+ DumpNode = DevPathToTextNodeUnknown;
+ }
+ //
+ // Put a path seperator in if needed
+ //
+ if (Str.Len && DumpNode != DevPathToTextEndInstance) {
+ if (*(Str.Str + Str.Len / sizeof (CHAR16) - 1) != L',') {
+ CatPrint (&Str, L"/");
+ }
+ }
+ //
+ // Print this node of the device path
+ //
+ DumpNode (&Str, DevPathNode, DisplayOnly, AllowShortcuts);
+
+ //
+ // Next device path node
+ //
+ DevPathNode = NextDevicePathNode (DevPathNode);
+ }
+ //
+ // Shrink pool used for string allocation
+ //
+ FreePool (UnpackDevPath);
+
+ NewSize = (Str.Len + 1) * sizeof (CHAR16);
+ Str.Str = ReallocatePool (Str.Str, NewSize, NewSize);
+ ASSERT (Str.Str != NULL);
+ Str.Str[Str.Len] = 0;
+ return Str.Str;
+}