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