Introduce a new property INCLUDE_PATHS. This property can used by customized build...
[mirror_edk2.git] / EdkNt32Pkg / Library / EdkGenericBdsLib / DevicePath.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 DevicePath.c\r
15\r
16Abstract:\r
17\r
18 BDS internal function define the default device path string, it can be\r
19 replaced by platform device path.\r
20\r
21--*/\r
22\r
23\r
24#ifdef TIANO_EXTENSION_FLAG\r
25EFI_GUID UnknownDeviceGuid = UNKNOWN_DEVICE_GUID;\r
26#endif \r
27\r
28EFI_GUID mEfiWinNtThunkProtocolGuid = EFI_WIN_NT_THUNK_PROTOCOL_GUID;\r
29EFI_GUID mEfiWinNtUgaGuid = EFI_WIN_NT_UGA_GUID;\r
30EFI_GUID mEfiWinNtSerialPortGuid = EFI_WIN_NT_SERIAL_PORT_GUID;\r
31EFI_GUID mEfiMsgPcAnsiGuid = DEVICE_PATH_MESSAGING_PC_ANSI;\r
32EFI_GUID mEfiMsgVt100Guid = DEVICE_PATH_MESSAGING_VT_100;\r
33EFI_GUID mEfiMsgVt100PlusGuid = DEVICE_PATH_MESSAGING_VT_100_PLUS;\r
34EFI_GUID mEfiMsgVt100Utf8Guid = DEVICE_PATH_MESSAGING_VT_UTF8;\r
35\r
36VOID *\r
37ReallocatePool (\r
38 IN VOID *OldPool,\r
39 IN UINTN OldSize,\r
40 IN UINTN NewSize\r
41 )\r
42/*++\r
43\r
44Routine Description:\r
45\r
46 Adjusts the size of a previously allocated buffer.\r
47\r
48Arguments:\r
49\r
50 OldPool - A pointer to the buffer whose size is being adjusted.\r
51\r
52 OldSize - The size of the current buffer.\r
53\r
54 NewSize - The size of the new buffer.\r
55\r
56Returns:\r
57\r
58 EFI_SUCEESS - The requested number of bytes were allocated.\r
59\r
60 EFI_OUT_OF_RESOURCES - The pool requested could not be allocated.\r
61\r
62 EFI_INVALID_PARAMETER - The buffer was invalid.\r
63\r
64--*/\r
65{\r
66 VOID *NewPool;\r
67\r
68 NewPool = NULL;\r
69 if (NewSize) {\r
70 NewPool = AllocateZeroPool (NewSize);\r
71 }\r
72\r
73 if (OldPool) {\r
74 if (NewPool) {\r
75 CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);\r
76 }\r
77\r
78 gBS->FreePool (OldPool);\r
79 }\r
80\r
81 return NewPool;\r
82}\r
83\r
84CHAR16 *\r
85CatPrint (\r
86 IN OUT POOL_PRINT *Str,\r
87 IN CHAR16 *fmt,\r
88 ...\r
89 )\r
90/*++\r
91\r
92Routine Description:\r
93\r
94 Concatenates a formatted unicode string to allocated pool. \r
95 The caller must free the resulting buffer.\r
96\r
97Arguments:\r
98\r
99 Str - Tracks the allocated pool, size in use, and \r
100 amount of pool allocated.\r
101\r
102 fmt - The format string\r
103\r
104Returns:\r
105\r
106 Allocated buffer with the formatted string printed in it. \r
107 The caller must free the allocated buffer. The buffer\r
108 allocation is not packed.\r
109\r
110--*/\r
111{\r
112 UINT16 *AppendStr;\r
113 VA_LIST args;\r
114 UINTN strsize;\r
115\r
116 AppendStr = AllocateZeroPool (0x1000);\r
117 if (AppendStr == NULL) {\r
118 return Str->str;\r
119 }\r
120\r
121 VA_START (args, fmt);\r
122 UnicodeVSPrint (AppendStr, 0x1000, fmt, args);\r
123 VA_END (args);\r
124 if (NULL == Str->str) {\r
125 strsize = StrSize (AppendStr);\r
126 Str->str = AllocateZeroPool (strsize);\r
127 ASSERT (Str->str != NULL);\r
128 } else {\r
129 strsize = StrSize (AppendStr) + StrSize (Str->str) - sizeof (UINT16);\r
130 Str->str = ReallocatePool (\r
131 Str->str,\r
132 StrSize (Str->str),\r
133 strsize\r
134 );\r
135 ASSERT (Str->str != NULL);\r
136 }\r
137\r
138 Str->maxlen = MAX_CHAR * sizeof (UINT16);\r
139 if (strsize < Str->maxlen) {\r
140 StrCat (Str->str, AppendStr);\r
141 Str->len = strsize - sizeof (UINT16);\r
142 }\r
143\r
144 gBS->FreePool (AppendStr);\r
145 return Str->str;\r
146}\r
147\r
148EFI_DEVICE_PATH_PROTOCOL *\r
149BdsLibUnpackDevicePath (\r
150 IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
151 )\r
152/*++\r
153\r
154Routine Description:\r
155\r
156 Function unpacks a device path data structure so that all the nodes\r
157 of a device path are naturally aligned.\r
158\r
159Arguments:\r
160\r
161 DevPath - A pointer to a device path data structure\r
162\r
163Returns:\r
164\r
165 If the memory for the device path is successfully allocated, then a \r
166 pointer to the new device path is returned. Otherwise, NULL is returned.\r
167\r
168--*/\r
169{\r
170 EFI_DEVICE_PATH_PROTOCOL *Src;\r
171 EFI_DEVICE_PATH_PROTOCOL *Dest;\r
172 EFI_DEVICE_PATH_PROTOCOL *NewPath;\r
173 UINTN Size;\r
174\r
175 //\r
176 // Walk device path and round sizes to valid boundries\r
177 //\r
178 Src = DevPath;\r
179 Size = 0;\r
180 for (;;) {\r
181 Size += DevicePathNodeLength (Src);\r
182 Size += ALIGN_SIZE (Size);\r
183\r
184 if (IsDevicePathEnd (Src)) {\r
185 break;\r
186 }\r
187\r
188 Src = NextDevicePathNode (Src);\r
189 }\r
190 //\r
191 // Allocate space for the unpacked path\r
192 //\r
193 NewPath = AllocateZeroPool (Size);\r
194 if (NewPath) {\r
195\r
196 ASSERT (((UINTN) NewPath) % MIN_ALIGNMENT_SIZE == 0);\r
197\r
198 //\r
199 // Copy each node\r
200 //\r
201 Src = DevPath;\r
202 Dest = NewPath;\r
203 for (;;) {\r
204 Size = DevicePathNodeLength (Src);\r
205 CopyMem (Dest, Src, Size);\r
206 Size += ALIGN_SIZE (Size);\r
207 SetDevicePathNodeLength (Dest, Size);\r
208 Dest->Type |= EFI_DP_TYPE_UNPACKED;\r
209 Dest = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) Dest) + Size);\r
210\r
211 if (IsDevicePathEnd (Src)) {\r
212 break;\r
213 }\r
214\r
215 Src = NextDevicePathNode (Src);\r
216 }\r
217 }\r
218\r
219 return NewPath;\r
220}\r
221\r
222VOID\r
223DevPathPci (\r
224 IN OUT POOL_PRINT *Str,\r
225 IN VOID *DevPath\r
226 )\r
227{\r
228 PCI_DEVICE_PATH *Pci;\r
229\r
230 Pci = DevPath;\r
231 CatPrint (Str, L"Pci(%x|%x)", Pci->Device, Pci->Function);\r
232}\r
233\r
234VOID\r
235DevPathPccard (\r
236 IN OUT POOL_PRINT *Str,\r
237 IN VOID *DevPath\r
238 )\r
239{\r
240 PCCARD_DEVICE_PATH *Pccard;\r
241\r
242 Pccard = DevPath;\r
243 CatPrint (Str, L"Pcmcia(Function%x)", Pccard->FunctionNumber);\r
244}\r
245\r
246VOID\r
247DevPathMemMap (\r
248 IN OUT POOL_PRINT *Str,\r
249 IN VOID *DevPath\r
250 )\r
251{\r
252 MEMMAP_DEVICE_PATH *MemMap;\r
253\r
254 MemMap = DevPath;\r
255 CatPrint (\r
256 Str,\r
257 L"MemMap(%d:%.lx-%.lx)",\r
258 MemMap->MemoryType,\r
259 MemMap->StartingAddress,\r
260 MemMap->EndingAddress\r
261 );\r
262}\r
263\r
264VOID\r
265DevPathController (\r
266 IN OUT POOL_PRINT *Str,\r
267 IN VOID *DevPath\r
268 )\r
269{\r
270 CONTROLLER_DEVICE_PATH *Controller;\r
271\r
272 Controller = DevPath;\r
273 CatPrint (Str, L"Ctrl(%d)", Controller->ControllerNumber);\r
274}\r
275\r
276VOID\r
277DevPathVendor (\r
278 IN OUT POOL_PRINT *Str,\r
279 IN VOID *DevPath\r
280 )\r
281/*++\r
282\r
283Routine Description:\r
284\r
285 Convert Vendor device path to device name\r
286\r
287Arguments:\r
288\r
289 Str - The buffer store device name\r
290 DevPath - Pointer to vendor device path\r
291\r
292Returns:\r
293\r
294 When it return, the device name have been stored in *Str.\r
295\r
296--*/\r
297{\r
298 VENDOR_DEVICE_PATH *Vendor;\r
299 CHAR16 *Type;\r
300 INT32 *Temp;\r
301\r
302 Vendor = DevPath;\r
303 Temp = (INT32 *) (&Vendor->Guid);\r
304\r
305 switch (DevicePathType (&Vendor->Header)) {\r
306 case HARDWARE_DEVICE_PATH:\r
307 //\r
308 // If the device is a winntbus device, we will give it a readable device name.\r
309 //\r
310 if (CompareGuid (&Vendor->Guid, &mEfiWinNtThunkProtocolGuid)) {\r
311 CatPrint (Str, L"%s", L"WinNtBus");\r
312 return ;\r
313 } else if (CompareGuid (&Vendor->Guid, &mEfiWinNtUgaGuid)) {\r
314 CatPrint (Str, L"%s", L"UGA");\r
315 return ;\r
316 } else if (CompareGuid (&Vendor->Guid, &mEfiWinNtSerialPortGuid)) {\r
317 CatPrint (Str, L"%s", L"Serial");\r
318 return ;\r
319 } else {\r
320 Type = L"Hw";\r
321 break;\r
322 }\r
323\r
324 case MESSAGING_DEVICE_PATH:\r
325 //\r
326 // If the device is a winntbus device, we will give it a readable device name.\r
327 //\r
328 if (CompareGuid (&Vendor->Guid, &mEfiMsgPcAnsiGuid)) {\r
329 CatPrint (Str, L"%s", L"PC-ANSI");\r
330 return ;\r
331 } else if (CompareGuid (&Vendor->Guid, &mEfiMsgVt100Guid)) {\r
332 CatPrint (Str, L"%s", L"VT100");\r
333 return ;\r
334 } else if (CompareGuid (&Vendor->Guid, &mEfiMsgVt100PlusGuid)) {\r
335 CatPrint (Str, L"%s", L"VT100+");\r
336 return ;\r
337 } else if (CompareGuid (&Vendor->Guid, &mEfiMsgVt100Utf8Guid)) {\r
338 CatPrint (Str, L"%s", L"VT100-UTF8");\r
339 return ;\r
340 } else {\r
341 Type = L"Msg";\r
342 break;\r
343 }\r
344\r
345 case MEDIA_DEVICE_PATH:\r
346 Type = L"Media";\r
347 break;\r
348\r
349 default:\r
350 Type = L"?";\r
351 break;\r
352 }\r
353\r
354 CatPrint (Str, L"Ven%s(%g)", Type, &Vendor->Guid);\r
355}\r
356\r
357VOID\r
358DevPathAcpi (\r
359 IN OUT POOL_PRINT *Str,\r
360 IN VOID *DevPath\r
361 )\r
362{\r
363 ACPI_HID_DEVICE_PATH *Acpi;\r
364\r
365 Acpi = DevPath;\r
366 if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {\r
367 CatPrint (Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);\r
368 } else {\r
369 CatPrint (Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID);\r
370 }\r
371}\r
372\r
373VOID\r
374DevPathAtapi (\r
375 IN OUT POOL_PRINT *Str,\r
376 IN VOID *DevPath\r
377 )\r
378{\r
379 ATAPI_DEVICE_PATH *Atapi;\r
380\r
381 Atapi = DevPath;\r
382 CatPrint (\r
383 Str,\r
384 L"Ata(%s,%s)",\r
385 Atapi->PrimarySecondary ? L"Secondary" : L"Primary",\r
386 Atapi->SlaveMaster ? L"Slave" : L"Master"\r
387 );\r
388}\r
389\r
390VOID\r
391DevPathScsi (\r
392 IN OUT POOL_PRINT *Str,\r
393 IN VOID *DevPath\r
394 )\r
395{\r
396 SCSI_DEVICE_PATH *Scsi;\r
397\r
398 Scsi = DevPath;\r
399 CatPrint (Str, L"Scsi(Pun%x,Lun%x)", Scsi->Pun, Scsi->Lun);\r
400}\r
401\r
402VOID\r
403DevPathFibre (\r
404 IN OUT POOL_PRINT *Str,\r
405 IN VOID *DevPath\r
406 )\r
407{\r
408 FIBRECHANNEL_DEVICE_PATH *Fibre;\r
409\r
410 Fibre = DevPath;\r
411 CatPrint (Str, L"Fibre(Wwn%lx,Lun%x)", Fibre->WWN, Fibre->Lun);\r
412}\r
413\r
414VOID\r
415DevPath1394 (\r
416 IN OUT POOL_PRINT *Str,\r
417 IN VOID *DevPath\r
418 )\r
419{\r
420 F1394_DEVICE_PATH *F1394;\r
421\r
422 F1394 = DevPath;\r
423 CatPrint (Str, L"1394(%g)", &F1394->Guid);\r
424}\r
425\r
426VOID\r
427DevPathUsb (\r
428 IN OUT POOL_PRINT *Str,\r
429 IN VOID *DevPath\r
430 )\r
431{\r
432 USB_DEVICE_PATH *Usb;\r
433\r
434 Usb = DevPath;\r
435 CatPrint (Str, L"Usb(%x, %x)", Usb->ParentPortNumber, Usb->InterfaceNumber);\r
436}\r
437\r
438VOID\r
439DevPathUsbClass (\r
440 IN OUT POOL_PRINT *Str,\r
441 IN VOID *DevPath\r
442 )\r
443{\r
444 USB_CLASS_DEVICE_PATH *UsbClass;\r
445\r
446 UsbClass = DevPath;\r
447 CatPrint (\r
448 Str,\r
449 L"Usb Class(%x, %x, %x, %x, %x)",\r
450 UsbClass->VendorId,\r
451 UsbClass->ProductId,\r
452 UsbClass->DeviceClass,\r
453 UsbClass->DeviceSubClass,\r
454 UsbClass->DeviceProtocol\r
455 );\r
456}\r
457\r
458VOID\r
459DevPathI2O (\r
460 IN OUT POOL_PRINT *Str,\r
461 IN VOID *DevPath\r
462 )\r
463{\r
464 I2O_DEVICE_PATH *I2O;\r
465\r
466 I2O = DevPath;\r
467 CatPrint (Str, L"I2O(%x)", I2O->Tid);\r
468}\r
469\r
470VOID\r
471DevPathMacAddr (\r
472 IN OUT POOL_PRINT *Str,\r
473 IN VOID *DevPath\r
474 )\r
475{\r
476 MAC_ADDR_DEVICE_PATH *MAC;\r
477 UINTN HwAddressSize;\r
478 UINTN Index;\r
479\r
480 MAC = DevPath;\r
481\r
482 HwAddressSize = sizeof (EFI_MAC_ADDRESS);\r
483 if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {\r
484 HwAddressSize = 6;\r
485 }\r
486\r
487 CatPrint (Str, L"Mac(");\r
488\r
489 for (Index = 0; Index < HwAddressSize; Index++) {\r
490 CatPrint (Str, L"%02x", MAC->MacAddress.Addr[Index]);\r
491 }\r
492\r
493 CatPrint (Str, L")");\r
494}\r
495\r
496VOID\r
497DevPathIPv4 (\r
498 IN OUT POOL_PRINT *Str,\r
499 IN VOID *DevPath\r
500 )\r
501{\r
502 IPv4_DEVICE_PATH *IP;\r
503\r
504 IP = DevPath;\r
505 CatPrint (\r
506 Str,\r
507 L"IPv4(%d.%d.%d.%d:%d)",\r
508 IP->RemoteIpAddress.Addr[0],\r
509 IP->RemoteIpAddress.Addr[1],\r
510 IP->RemoteIpAddress.Addr[2],\r
511 IP->RemoteIpAddress.Addr[3],\r
512 IP->RemotePort\r
513 );\r
514}\r
515\r
516VOID\r
517DevPathIPv6 (\r
518 IN OUT POOL_PRINT *Str,\r
519 IN VOID *DevPath\r
520 )\r
521{\r
522 IPv6_DEVICE_PATH *IP;\r
523\r
524 IP = DevPath;\r
525 CatPrint (Str, L"IP-v6(not-done)");\r
526}\r
527\r
528VOID\r
529DevPathInfiniBand (\r
530 IN OUT POOL_PRINT *Str,\r
531 IN VOID *DevPath\r
532 )\r
533{\r
534 INFINIBAND_DEVICE_PATH *InfiniBand;\r
535\r
536 InfiniBand = DevPath;\r
537 CatPrint (Str, L"InfiniBand(not-done)");\r
538}\r
539\r
540VOID\r
541DevPathUart (\r
542 IN OUT POOL_PRINT *Str,\r
543 IN VOID *DevPath\r
544 )\r
545{\r
546 UART_DEVICE_PATH *Uart;\r
547 CHAR8 Parity;\r
548\r
549 Uart = DevPath;\r
550 switch (Uart->Parity) {\r
551 case 0:\r
552 Parity = 'D';\r
553 break;\r
554\r
555 case 1:\r
556 Parity = 'N';\r
557 break;\r
558\r
559 case 2:\r
560 Parity = 'E';\r
561 break;\r
562\r
563 case 3:\r
564 Parity = 'O';\r
565 break;\r
566\r
567 case 4:\r
568 Parity = 'M';\r
569 break;\r
570\r
571 case 5:\r
572 Parity = 'S';\r
573 break;\r
574\r
575 default:\r
576 Parity = 'x';\r
577 break;\r
578 }\r
579\r
580 if (Uart->BaudRate == 0) {\r
581 CatPrint (Str, L"Uart(DEFAULT %c", Parity);\r
582 } else {\r
583 CatPrint (Str, L"Uart(%d %c", Uart->BaudRate, Parity);\r
584 }\r
585\r
586 if (Uart->DataBits == 0) {\r
587 CatPrint (Str, L"D");\r
588 } else {\r
589 CatPrint (Str, L"%d", Uart->DataBits);\r
590 }\r
591\r
592 switch (Uart->StopBits) {\r
593 case 0:\r
594 CatPrint (Str, L"D)");\r
595 break;\r
596\r
597 case 1:\r
598 CatPrint (Str, L"1)");\r
599 break;\r
600\r
601 case 2:\r
602 CatPrint (Str, L"1.5)");\r
603 break;\r
604\r
605 case 3:\r
606 CatPrint (Str, L"2)");\r
607 break;\r
608\r
609 default:\r
610 CatPrint (Str, L"x)");\r
611 break;\r
612 }\r
613}\r
614\r
615VOID\r
616DevPathHardDrive (\r
617 IN OUT POOL_PRINT *Str,\r
618 IN VOID *DevPath\r
619 )\r
620{\r
621 HARDDRIVE_DEVICE_PATH *Hd;\r
622\r
623 Hd = DevPath;\r
624 switch (Hd->SignatureType) {\r
625 case SIGNATURE_TYPE_MBR:\r
626 CatPrint (\r
627 Str,\r
628 L"HD(Part%d,Sig%08x)",\r
629 Hd->PartitionNumber,\r
630 *((UINT32 *) (&(Hd->Signature[0])))\r
631 );\r
632 break;\r
633\r
634 case SIGNATURE_TYPE_GUID:\r
635 CatPrint (\r
636 Str,\r
637 L"HD(Part%d,Sig%g)",\r
638 Hd->PartitionNumber,\r
639 (EFI_GUID *) &(Hd->Signature[0])\r
640 );\r
641 break;\r
642\r
643 default:\r
644 CatPrint (\r
645 Str,\r
646 L"HD(Part%d,MBRType=%02x,SigType=%02x)",\r
647 Hd->PartitionNumber,\r
648 Hd->MBRType,\r
649 Hd->SignatureType\r
650 );\r
651 break;\r
652 }\r
653}\r
654\r
655VOID\r
656DevPathCDROM (\r
657 IN OUT POOL_PRINT *Str,\r
658 IN VOID *DevPath\r
659 )\r
660{\r
661 CDROM_DEVICE_PATH *Cd;\r
662\r
663 Cd = DevPath;\r
664 CatPrint (Str, L"CDROM(Entry%x)", Cd->BootEntry);\r
665}\r
666\r
667VOID\r
668DevPathFilePath (\r
669 IN OUT POOL_PRINT *Str,\r
670 IN VOID *DevPath\r
671 )\r
672{\r
673 FILEPATH_DEVICE_PATH *Fp;\r
674\r
675 Fp = DevPath;\r
676 CatPrint (Str, L"%s", Fp->PathName);\r
677}\r
678\r
679VOID\r
680DevPathMediaProtocol (\r
681 IN OUT POOL_PRINT *Str,\r
682 IN VOID *DevPath\r
683 )\r
684{\r
685 MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;\r
686\r
687 MediaProt = DevPath;\r
688 CatPrint (Str, L"%g", &MediaProt->Protocol);\r
689}\r
690\r
691VOID\r
692DevPathFvFilePath (\r
693 IN OUT POOL_PRINT *Str,\r
694 IN VOID *DevPath\r
695 )\r
696{\r
697 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;\r
698\r
699 FvFilePath = DevPath;\r
700 CatPrint (Str, L"%g", &FvFilePath->NameGuid);\r
701}\r
702\r
703VOID\r
704DevPathBssBss (\r
705 IN OUT POOL_PRINT *Str,\r
706 IN VOID *DevPath\r
707 )\r
708{\r
709 BBS_BBS_DEVICE_PATH *Bbs;\r
710 CHAR16 *Type;\r
711\r
712 Bbs = DevPath;\r
713 switch (Bbs->DeviceType) {\r
714 case BBS_TYPE_FLOPPY:\r
715 Type = L"Floppy";\r
716 break;\r
717\r
718 case BBS_TYPE_HARDDRIVE:\r
719 Type = L"Harddrive";\r
720 break;\r
721\r
722 case BBS_TYPE_CDROM:\r
723 Type = L"CDROM";\r
724 break;\r
725\r
726 case BBS_TYPE_PCMCIA:\r
727 Type = L"PCMCIA";\r
728 break;\r
729\r
730 case BBS_TYPE_USB:\r
731 Type = L"Usb";\r
732 break;\r
733\r
734 case BBS_TYPE_EMBEDDED_NETWORK:\r
735 Type = L"Net";\r
736 break;\r
737\r
738 default:\r
739 Type = L"?";\r
740 break;\r
741 }\r
742 //\r
743 // Since current Print function hasn't implemented %a (for ansi string)\r
744 // we will only print Unicode strings.\r
745 //\r
746 CatPrint (Str, L"Legacy-%s", Type);\r
747}\r
748\r
749VOID\r
750DevPathEndInstance (\r
751 IN OUT POOL_PRINT *Str,\r
752 IN VOID *DevPath\r
753 )\r
754{\r
755 CatPrint (Str, L",");\r
756}\r
757\r
758VOID\r
759DevPathNodeUnknown (\r
760 IN OUT POOL_PRINT *Str,\r
761 IN VOID *DevPath\r
762 )\r
763{\r
764 CatPrint (Str, L"?");\r
765}\r
766\r
767DEVICE_PATH_STRING_TABLE DevPathTable[] = {\r
768 HARDWARE_DEVICE_PATH,\r
769 HW_PCI_DP,\r
770 DevPathPci,\r
771 HARDWARE_DEVICE_PATH,\r
772 HW_PCCARD_DP,\r
773 DevPathPccard,\r
774 HARDWARE_DEVICE_PATH,\r
775 HW_MEMMAP_DP,\r
776 DevPathMemMap,\r
777 HARDWARE_DEVICE_PATH,\r
778 HW_VENDOR_DP,\r
779 DevPathVendor,\r
780 HARDWARE_DEVICE_PATH,\r
781 HW_CONTROLLER_DP,\r
782 DevPathController,\r
783 ACPI_DEVICE_PATH,\r
784 ACPI_DP,\r
785 DevPathAcpi,\r
786 MESSAGING_DEVICE_PATH,\r
787 MSG_ATAPI_DP,\r
788 DevPathAtapi,\r
789 MESSAGING_DEVICE_PATH,\r
790 MSG_SCSI_DP,\r
791 DevPathScsi,\r
792 MESSAGING_DEVICE_PATH,\r
793 MSG_FIBRECHANNEL_DP,\r
794 DevPathFibre,\r
795 MESSAGING_DEVICE_PATH,\r
796 MSG_1394_DP,\r
797 DevPath1394,\r
798 MESSAGING_DEVICE_PATH,\r
799 MSG_USB_DP,\r
800 DevPathUsb,\r
801 MESSAGING_DEVICE_PATH,\r
802 MSG_USB_CLASS_DP,\r
803 DevPathUsbClass,\r
804 MESSAGING_DEVICE_PATH,\r
805 MSG_I2O_DP,\r
806 DevPathI2O,\r
807 MESSAGING_DEVICE_PATH,\r
808 MSG_MAC_ADDR_DP,\r
809 DevPathMacAddr,\r
810 MESSAGING_DEVICE_PATH,\r
811 MSG_IPv4_DP,\r
812 DevPathIPv4,\r
813 MESSAGING_DEVICE_PATH,\r
814 MSG_IPv6_DP,\r
815 DevPathIPv6,\r
816 MESSAGING_DEVICE_PATH,\r
817 MSG_INFINIBAND_DP,\r
818 DevPathInfiniBand,\r
819 MESSAGING_DEVICE_PATH,\r
820 MSG_UART_DP,\r
821 DevPathUart,\r
822 MESSAGING_DEVICE_PATH,\r
823 MSG_VENDOR_DP,\r
824 DevPathVendor,\r
825 MEDIA_DEVICE_PATH,\r
826 MEDIA_HARDDRIVE_DP,\r
827 DevPathHardDrive,\r
828 MEDIA_DEVICE_PATH,\r
829 MEDIA_CDROM_DP,\r
830 DevPathCDROM,\r
831 MEDIA_DEVICE_PATH,\r
832 MEDIA_VENDOR_DP,\r
833 DevPathVendor,\r
834 MEDIA_DEVICE_PATH,\r
835 MEDIA_FILEPATH_DP,\r
836 DevPathFilePath,\r
837 MEDIA_DEVICE_PATH,\r
838 MEDIA_PROTOCOL_DP,\r
839 DevPathMediaProtocol,\r
840\r
841#if (EFI_SPECIFICATION_VERSION < 0x00020000)\r
842 MEDIA_DEVICE_PATH,\r
843 MEDIA_FV_FILEPATH_DP,\r
844 DevPathFvFilePath,\r
845#endif\r
846\r
847 BBS_DEVICE_PATH,\r
848 BBS_BBS_DP,\r
849 DevPathBssBss,\r
850 END_DEVICE_PATH_TYPE,\r
851 END_INSTANCE_DEVICE_PATH_SUBTYPE,\r
852 DevPathEndInstance,\r
853 0,\r
854 0,\r
855 NULL\r
856};\r
857\r
858CHAR16 *\r
859DevicePathToStr (\r
860 IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
861 )\r
862/*++\r
863\r
864 Turns the Device Path into a printable string. Allcoates\r
865 the string from pool. The caller must SafeFreePool the returned\r
866 string.\r
867\r
868--*/\r
869{\r
870 POOL_PRINT Str;\r
871 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;\r
872 VOID (*DumpNode) (POOL_PRINT *, VOID *);\r
873\r
874 UINTN Index;\r
875 UINTN NewSize;\r
876\r
877 ZeroMem (&Str, sizeof (Str));\r
878\r
879 if (DevPath == NULL) {\r
880 goto Done;\r
881 }\r
882 //\r
883 // Unpacked the device path\r
884 //\r
885 DevPath = BdsLibUnpackDevicePath (DevPath);\r
886 ASSERT (DevPath);\r
887\r
888 //\r
889 // Process each device path node\r
890 //\r
891 DevPathNode = DevPath;\r
892 while (!IsDevicePathEnd (DevPathNode)) {\r
893 //\r
894 // Find the handler to dump this device path node\r
895 //\r
896 DumpNode = NULL;\r
897 for (Index = 0; DevPathTable[Index].Function; Index += 1) {\r
898\r
899 if (DevicePathType (DevPathNode) == DevPathTable[Index].Type &&\r
900 DevicePathSubType (DevPathNode) == DevPathTable[Index].SubType\r
901 ) {\r
902 DumpNode = DevPathTable[Index].Function;\r
903 break;\r
904 }\r
905 }\r
906 //\r
907 // If not found, use a generic function\r
908 //\r
909 if (!DumpNode) {\r
910 DumpNode = DevPathNodeUnknown;\r
911 }\r
912 //\r
913 // Put a path seperator in if needed\r
914 //\r
915 if (Str.len && DumpNode != DevPathEndInstance) {\r
916 CatPrint (&Str, L"/");\r
917 }\r
918 //\r
919 // Print this node of the device path\r
920 //\r
921 DumpNode (&Str, DevPathNode);\r
922\r
923 //\r
924 // Next device path node\r
925 //\r
926 DevPathNode = NextDevicePathNode (DevPathNode);\r
927 }\r
928 //\r
929 // Shrink pool used for string allocation\r
930 //\r
931 gBS->FreePool (DevPath);\r
932\r
933Done:\r
934 NewSize = (Str.len + 1) * sizeof (CHAR16);\r
935 Str.str = ReallocatePool (Str.str, NewSize, NewSize);\r
936 ASSERT (Str.str != NULL);\r
937 Str.str[Str.len] = 0;\r
938 return Str.str;\r
939}\r
940\r
941EFI_DEVICE_PATH_PROTOCOL *\r
942LibDuplicateDevicePathInstance (\r
943 IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
944 )\r
945/*++\r
946\r
947Routine Description:\r
948\r
949 Function creates a device path data structure that identically matches the \r
950 device path passed in.\r
951\r
952Arguments:\r
953\r
954 DevPath - A pointer to a device path data structure.\r
955\r
956Returns:\r
957\r
958 The new copy of DevPath is created to identically match the input. \r
959 Otherwise, NULL is returned.\r
960\r
961--*/\r
962{\r
963 EFI_DEVICE_PATH_PROTOCOL *NewDevPath;\r
964 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;\r
965 EFI_DEVICE_PATH_PROTOCOL *Temp;\r
966 UINTN Size;\r
967\r
968 //\r
969 // get the size of an instance from the input\r
970 //\r
971 Temp = DevPath;\r
972 DevicePathInst = GetNextDevicePathInstance (&Temp, &Size);\r
973\r
974 //\r
975 // Make a copy\r
976 //\r
977 NewDevPath = NULL;\r
978 if (Size) {\r
979 NewDevPath = AllocateZeroPool (Size);\r
980 ASSERT (NewDevPath != NULL);\r
981 }\r
982\r
983 if (NewDevPath) {\r
984 CopyMem (NewDevPath, DevicePathInst, Size);\r
985 }\r
986\r
987 return NewDevPath;\r
988}\r