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