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