xref: /freebsd/lib/libefivar/efivar-dp-parse.c (revision 965f85271c11e6c5901c09984472fa74d2266e1c)
1 /*-
2  * Copyright (c) 2017 Netflix, Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25 
26 /*
27  * Routines to format EFI_DEVICE_PATHs from the UEFI standard. Much of
28  * this file is taken from EDK2 and rototilled.
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 #include <ctype.h>
35 #include <efivar.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <wchar.h>
39 
40 #include "efichar.h"
41 
42 #include "efi-osdep.h"
43 #include "efivar-dp.h"
44 
45 #include "uefi-dplib.h"
46 
47 /* XXX STUBS -- this stuff doesn't work yet */
48 #define StrToIpv4Address(str, unk, ipv4ptr, unk2)
49 #define StrToIpv6Address(str, unk, ipv6ptr, unk2)
50 
51 /*
52  * OK. Now this is evil. Can't typedef it again. Sure beats changing them all.
53  * Since we're doing it all as narrow characters since wchar_t can't be used on
54  * FreeBSD and CHAR16 strings generally aren't a good fit. Since this parsing
55  * doesn't need Unicode for anything, this works out well.
56  */
57 #define CHAR16 char
58 
59 /*
60  * Taken from MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
61  */
62 
63 /** @file
64   DevicePathFromText protocol as defined in the UEFI 2.0 specification.
65 
66 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
67 This program and the accompanying materials
68 are licensed and made available under the terms and conditions of the BSD License
69 which accompanies this distribution.  The full text of the license may be found at
70 http://opensource.org/licenses/bsd-license.php
71 
72 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
73 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
74 
75 **/
76 
77 // #include "UefiDevicePathLib.h"
78 
79 /**
80 
81   Duplicates a string.
82 
83   @param  Src  Source string.
84 
85   @return The duplicated string.
86 
87 **/
88 static
89 CHAR16 *
90 UefiDevicePathLibStrDuplicate (
91   IN CONST CHAR16  *Src
92   )
93 {
94   return AllocateCopyPool (StrSize (Src), Src);
95 }
96 
97 /**
98 
99   Get parameter in a pair of parentheses follow the given node name.
100   For example, given the "Pci(0,1)" and NodeName "Pci", it returns "0,1".
101 
102   @param  Str      Device Path Text.
103   @param  NodeName Name of the node.
104 
105   @return Parameter text for the node.
106 
107 **/
108 static
109 CHAR16 *
110 GetParamByNodeName (
111   IN CHAR16 *Str,
112   IN const CHAR16 *NodeName
113   )
114 {
115   CHAR16  *ParamStr;
116   CHAR16  *StrPointer;
117   UINTN   NodeNameLength;
118   UINTN   ParameterLength;
119 
120   //
121   // Check whether the node name matchs
122   //
123   NodeNameLength = StrLen (NodeName);
124   if (StrnCmp (Str, NodeName, NodeNameLength) != 0) {
125     return NULL;
126   }
127 
128   ParamStr = Str + NodeNameLength;
129   if (!IS_LEFT_PARENTH (*ParamStr)) {
130     return NULL;
131   }
132 
133   //
134   // Skip the found '(' and find first occurrence of ')'
135   //
136   ParamStr++;
137   ParameterLength = 0;
138   StrPointer = ParamStr;
139   while (!IS_NULL (*StrPointer)) {
140     if (IS_RIGHT_PARENTH (*StrPointer)) {
141       break;
142     }
143     StrPointer++;
144     ParameterLength++;
145   }
146   if (IS_NULL (*StrPointer)) {
147     //
148     // ')' not found
149     //
150     return NULL;
151   }
152 
153   ParamStr = AllocateCopyPool ((ParameterLength + 1) * sizeof (CHAR16), ParamStr);
154   if (ParamStr == NULL) {
155     return NULL;
156   }
157   //
158   // Terminate the parameter string
159   //
160   ParamStr[ParameterLength] = '\0';
161 
162   return ParamStr;
163 }
164 
165 /**
166   Gets current sub-string from a string list, before return
167   the list header is moved to next sub-string. The sub-string is separated
168   by the specified character. For example, the separator is ',', the string
169   list is "2,0,3", it returns "2", the remain list move to "0,3"
170 
171   @param  List        A string list separated by the specified separator
172   @param  Separator   The separator character
173 
174   @return A pointer to the current sub-string
175 
176 **/
177 static
178 CHAR16 *
179 SplitStr (
180   IN OUT CHAR16 **List,
181   IN     CHAR16 Separator
182   )
183 {
184   CHAR16  *Str;
185   CHAR16  *ReturnStr;
186 
187   Str = *List;
188   ReturnStr = Str;
189 
190   if (IS_NULL (*Str)) {
191     return ReturnStr;
192   }
193 
194   //
195   // Find first occurrence of the separator
196   //
197   while (!IS_NULL (*Str)) {
198     if (*Str == Separator) {
199       break;
200     }
201     Str++;
202   }
203 
204   if (*Str == Separator) {
205     //
206     // Find a sub-string, terminate it
207     //
208     *Str = '\0';
209     Str++;
210   }
211 
212   //
213   // Move to next sub-string
214   //
215   *List = Str;
216 
217   return ReturnStr;
218 }
219 
220 /**
221   Gets the next parameter string from the list.
222 
223   @param List            A string list separated by the specified separator
224 
225   @return A pointer to the current sub-string
226 
227 **/
228 static
229 CHAR16 *
230 GetNextParamStr (
231   IN OUT CHAR16 **List
232   )
233 {
234   //
235   // The separator is comma
236   //
237   return SplitStr (List, ',');
238 }
239 
240 /**
241   Get one device node from entire device path text.
242 
243   @param DevicePath      On input, the current Device Path node; on output, the next device path node
244   @param IsInstanceEnd   This node is the end of a device path instance
245 
246   @return A device node text or NULL if no more device node available
247 
248 **/
249 static
250 CHAR16 *
251 GetNextDeviceNodeStr (
252   IN OUT CHAR16   **DevicePath,
253   OUT    BOOLEAN  *IsInstanceEnd
254   )
255 {
256   CHAR16  *Str;
257   CHAR16  *ReturnStr;
258   UINTN   ParenthesesStack;
259 
260   Str = *DevicePath;
261   if (IS_NULL (*Str)) {
262     return NULL;
263   }
264 
265   //
266   // Skip the leading '/', '(', ')' and ','
267   //
268   while (!IS_NULL (*Str)) {
269     if (!IS_SLASH (*Str) &&
270         !IS_COMMA (*Str) &&
271         !IS_LEFT_PARENTH (*Str) &&
272         !IS_RIGHT_PARENTH (*Str)) {
273       break;
274     }
275     Str++;
276   }
277 
278   ReturnStr = Str;
279 
280   //
281   // Scan for the separator of this device node, '/' or ','
282   //
283   ParenthesesStack = 0;
284   while (!IS_NULL (*Str)) {
285     if ((IS_COMMA (*Str) || IS_SLASH (*Str)) && (ParenthesesStack == 0)) {
286       break;
287     }
288 
289     if (IS_LEFT_PARENTH (*Str)) {
290       ParenthesesStack++;
291     } else if (IS_RIGHT_PARENTH (*Str)) {
292       ParenthesesStack--;
293     }
294 
295     Str++;
296   }
297 
298   if (ParenthesesStack != 0) {
299     //
300     // The '(' doesn't pair with ')', invalid device path text
301     //
302     return NULL;
303   }
304 
305   if (IS_COMMA (*Str)) {
306     *IsInstanceEnd = TRUE;
307     *Str = '\0';
308     Str++;
309   } else {
310     *IsInstanceEnd = FALSE;
311     if (!IS_NULL (*Str)) {
312       *Str = '\0';
313       Str++;
314     }
315   }
316 
317   *DevicePath = Str;
318 
319   return ReturnStr;
320 }
321 
322 
323 #ifndef __FreeBSD__
324 /**
325   Return whether the integer string is a hex string.
326 
327   @param Str             The integer string
328 
329   @retval TRUE   Hex string
330   @retval FALSE  Decimal string
331 
332 **/
333 static
334 BOOLEAN
335 IsHexStr (
336   IN CHAR16   *Str
337   )
338 {
339   //
340   // skip preceeding white space
341   //
342   while ((*Str != 0) && *Str == ' ') {
343     Str ++;
344   }
345   //
346   // skip preceeding zeros
347   //
348   while ((*Str != 0) && *Str == '0') {
349     Str ++;
350   }
351 
352   return (BOOLEAN) (*Str == 'x' || *Str == 'X');
353 }
354 
355 /**
356 
357   Convert integer string to uint.
358 
359   @param Str             The integer string. If leading with "0x" or "0X", it's hexadecimal.
360 
361   @return A UINTN value represented by Str
362 
363 **/
364 static
365 UINTN
366 Strtoi (
367   IN CHAR16  *Str
368   )
369 {
370   if (IsHexStr (Str)) {
371     return StrHexToUintn (Str);
372   } else {
373     return StrDecimalToUintn (Str);
374   }
375 }
376 
377 /**
378 
379   Convert integer string to 64 bit data.
380 
381   @param Str             The integer string. If leading with "0x" or "0X", it's hexadecimal.
382   @param Data            A pointer to the UINT64 value represented by Str
383 
384 **/
385 static
386 VOID
387 Strtoi64 (
388   IN  CHAR16  *Str,
389   OUT UINT64  *Data
390   )
391 {
392   if (IsHexStr (Str)) {
393     *Data = StrHexToUint64 (Str);
394   } else {
395     *Data = StrDecimalToUint64 (Str);
396   }
397 }
398 #endif
399 
400 /**
401   Converts a Unicode string to ASCII string.
402 
403   @param Str             The equivalent Unicode string
404   @param AsciiStr        On input, it points to destination ASCII string buffer; on output, it points
405                          to the next ASCII string next to it
406 
407 **/
408 static
409 VOID
410 StrToAscii (
411   IN     CHAR16 *Str,
412   IN OUT CHAR8  **AsciiStr
413   )
414 {
415   CHAR8 *Dest;
416 
417   Dest = *AsciiStr;
418   while (!IS_NULL (*Str)) {
419     *(Dest++) = (CHAR8) *(Str++);
420   }
421   *Dest = 0;
422 
423   //
424   // Return the string next to it
425   //
426   *AsciiStr = Dest + 1;
427 }
428 
429 /**
430   Converts a generic text device path node to device path structure.
431 
432   @param Type            The type of the device path node.
433   @param TextDeviceNode  The input text device path node.
434 
435   @return A pointer to device path structure.
436 **/
437 static
438 EFI_DEVICE_PATH_PROTOCOL *
439 DevPathFromTextGenericPath (
440   IN UINT8  Type,
441   IN CHAR16 *TextDeviceNode
442   )
443 {
444   EFI_DEVICE_PATH_PROTOCOL *Node;
445   CHAR16                   *SubtypeStr;
446   CHAR16                   *DataStr;
447   UINTN                    DataLength;
448 
449   SubtypeStr = GetNextParamStr (&TextDeviceNode);
450   DataStr    = GetNextParamStr (&TextDeviceNode);
451 
452   if (DataStr == NULL) {
453     DataLength = 0;
454   } else {
455     DataLength = StrLen (DataStr) / 2;
456   }
457   Node = CreateDeviceNode (
458            Type,
459            (UINT8) Strtoi (SubtypeStr),
460            (UINT16) (sizeof (EFI_DEVICE_PATH_PROTOCOL) + DataLength)
461            );
462 
463   StrHexToBytes (DataStr, DataLength * 2, (UINT8 *) (Node + 1), DataLength);
464   return Node;
465 }
466 
467 /**
468   Converts a generic text device path node to device path structure.
469 
470   @param TextDeviceNode  The input Text device path node.
471 
472   @return A pointer to device path structure.
473 
474 **/
475 static
476 EFI_DEVICE_PATH_PROTOCOL *
477 DevPathFromTextPath (
478   IN CHAR16 *TextDeviceNode
479   )
480 {
481   CHAR16                   *TypeStr;
482 
483   TypeStr    = GetNextParamStr (&TextDeviceNode);
484 
485   return DevPathFromTextGenericPath ((UINT8) Strtoi (TypeStr), TextDeviceNode);
486 }
487 
488 /**
489   Converts a generic hardware text device path node to Hardware device path structure.
490 
491   @param TextDeviceNode  The input Text device path node.
492 
493   @return A pointer to Hardware device path structure.
494 
495 **/
496 static
497 EFI_DEVICE_PATH_PROTOCOL *
498 DevPathFromTextHardwarePath (
499   IN CHAR16 *TextDeviceNode
500   )
501 {
502   return DevPathFromTextGenericPath (HARDWARE_DEVICE_PATH, TextDeviceNode);
503 }
504 
505 /**
506   Converts a text device path node to Hardware PCI device path structure.
507 
508   @param TextDeviceNode  The input Text device path node.
509 
510   @return A pointer to Hardware PCI device path structure.
511 
512 **/
513 static
514 EFI_DEVICE_PATH_PROTOCOL *
515 DevPathFromTextPci (
516   IN CHAR16 *TextDeviceNode
517   )
518 {
519   CHAR16          *FunctionStr;
520   CHAR16          *DeviceStr;
521   PCI_DEVICE_PATH *Pci;
522 
523   DeviceStr   = GetNextParamStr (&TextDeviceNode);
524   FunctionStr = GetNextParamStr (&TextDeviceNode);
525   Pci         = (PCI_DEVICE_PATH *) CreateDeviceNode (
526                                       HARDWARE_DEVICE_PATH,
527                                       HW_PCI_DP,
528                                       (UINT16) sizeof (PCI_DEVICE_PATH)
529                                       );
530 
531   Pci->Function = (UINT8) Strtoi (FunctionStr);
532   Pci->Device   = (UINT8) Strtoi (DeviceStr);
533 
534   return (EFI_DEVICE_PATH_PROTOCOL *) Pci;
535 }
536 
537 /**
538   Converts a text device path node to Hardware PC card device path structure.
539 
540   @param TextDeviceNode  The input Text device path node.
541 
542   @return A pointer to Hardware PC card device path structure.
543 
544 **/
545 static
546 EFI_DEVICE_PATH_PROTOCOL *
547 DevPathFromTextPcCard (
548   IN CHAR16 *TextDeviceNode
549   )
550 {
551   CHAR16              *FunctionNumberStr;
552   PCCARD_DEVICE_PATH  *Pccard;
553 
554   FunctionNumberStr = GetNextParamStr (&TextDeviceNode);
555   Pccard            = (PCCARD_DEVICE_PATH *) CreateDeviceNode (
556                                                HARDWARE_DEVICE_PATH,
557                                                HW_PCCARD_DP,
558                                                (UINT16) sizeof (PCCARD_DEVICE_PATH)
559                                                );
560 
561   Pccard->FunctionNumber  = (UINT8) Strtoi (FunctionNumberStr);
562 
563   return (EFI_DEVICE_PATH_PROTOCOL *) Pccard;
564 }
565 
566 /**
567   Converts a text device path node to Hardware memory map device path structure.
568 
569   @param TextDeviceNode  The input Text device path node.
570 
571   @return A pointer to Hardware memory map device path structure.
572 
573 **/
574 static
575 EFI_DEVICE_PATH_PROTOCOL *
576 DevPathFromTextMemoryMapped (
577   IN CHAR16 *TextDeviceNode
578   )
579 {
580   CHAR16              *MemoryTypeStr;
581   CHAR16              *StartingAddressStr;
582   CHAR16              *EndingAddressStr;
583   MEMMAP_DEVICE_PATH  *MemMap;
584 
585   MemoryTypeStr      = GetNextParamStr (&TextDeviceNode);
586   StartingAddressStr = GetNextParamStr (&TextDeviceNode);
587   EndingAddressStr   = GetNextParamStr (&TextDeviceNode);
588   MemMap             = (MEMMAP_DEVICE_PATH *) CreateDeviceNode (
589                                                HARDWARE_DEVICE_PATH,
590                                                HW_MEMMAP_DP,
591                                                (UINT16) sizeof (MEMMAP_DEVICE_PATH)
592                                                );
593 
594   MemMap->MemoryType = (UINT32) Strtoi (MemoryTypeStr);
595   Strtoi64 (StartingAddressStr, &MemMap->StartingAddress);
596   Strtoi64 (EndingAddressStr, &MemMap->EndingAddress);
597 
598   return (EFI_DEVICE_PATH_PROTOCOL *) MemMap;
599 }
600 
601 /**
602   Converts a text device path node to Vendor device path structure based on the input Type
603   and SubType.
604 
605   @param TextDeviceNode  The input Text device path node.
606   @param Type            The type of device path node.
607   @param SubType         The subtype of device path node.
608 
609   @return A pointer to the newly-created Vendor device path structure.
610 
611 **/
612 static
613 EFI_DEVICE_PATH_PROTOCOL *
614 ConvertFromTextVendor (
615   IN CHAR16 *TextDeviceNode,
616   IN UINT8  Type,
617   IN UINT8  SubType
618   )
619 {
620   CHAR16              *GuidStr;
621   CHAR16              *DataStr;
622   UINTN               Length;
623   VENDOR_DEVICE_PATH  *Vendor;
624 
625   GuidStr = GetNextParamStr (&TextDeviceNode);
626 
627   DataStr = GetNextParamStr (&TextDeviceNode);
628   Length  = StrLen (DataStr);
629   //
630   // Two hex characters make up 1 buffer byte
631   //
632   Length  = (Length + 1) / 2;
633 
634   Vendor  = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
635                                      Type,
636                                      SubType,
637                                      (UINT16) (sizeof (VENDOR_DEVICE_PATH) + Length)
638                                      );
639 
640   StrToGuid (GuidStr, &Vendor->Guid);
641   StrHexToBytes (DataStr, Length * 2, (UINT8 *) (Vendor + 1), Length);
642 
643   return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
644 }
645 
646 /**
647   Converts a text device path node to Vendor Hardware device path structure.
648 
649   @param TextDeviceNode  The input Text device path node.
650 
651   @return A pointer to the newly-created Vendor Hardware device path structure.
652 
653 **/
654 static
655 EFI_DEVICE_PATH_PROTOCOL *
656 DevPathFromTextVenHw (
657   IN CHAR16 *TextDeviceNode
658   )
659 {
660   return ConvertFromTextVendor (
661            TextDeviceNode,
662            HARDWARE_DEVICE_PATH,
663            HW_VENDOR_DP
664            );
665 }
666 
667 /**
668   Converts a text device path node to Hardware Controller device path structure.
669 
670   @param TextDeviceNode  The input Text device path node.
671 
672   @return A pointer to the newly-created Hardware Controller device path structure.
673 
674 **/
675 static
676 EFI_DEVICE_PATH_PROTOCOL *
677 DevPathFromTextCtrl (
678   IN CHAR16 *TextDeviceNode
679   )
680 {
681   CHAR16                  *ControllerStr;
682   CONTROLLER_DEVICE_PATH  *Controller;
683 
684   ControllerStr = GetNextParamStr (&TextDeviceNode);
685   Controller    = (CONTROLLER_DEVICE_PATH *) CreateDeviceNode (
686                                                HARDWARE_DEVICE_PATH,
687                                                HW_CONTROLLER_DP,
688                                                (UINT16) sizeof (CONTROLLER_DEVICE_PATH)
689                                                );
690   Controller->ControllerNumber = (UINT32) Strtoi (ControllerStr);
691 
692   return (EFI_DEVICE_PATH_PROTOCOL *) Controller;
693 }
694 
695 /**
696   Converts a text device path node to BMC device path structure.
697 
698   @param TextDeviceNode  The input Text device path node.
699 
700   @return A pointer to the newly-created BMC device path structure.
701 
702 **/
703 static
704 EFI_DEVICE_PATH_PROTOCOL *
705 DevPathFromTextBmc (
706   IN CHAR16 *TextDeviceNode
707   )
708 {
709   CHAR16                *InterfaceTypeStr;
710   CHAR16                *BaseAddressStr;
711   BMC_DEVICE_PATH       *BmcDp;
712 
713   InterfaceTypeStr = GetNextParamStr (&TextDeviceNode);
714   BaseAddressStr   = GetNextParamStr (&TextDeviceNode);
715   BmcDp            = (BMC_DEVICE_PATH *) CreateDeviceNode (
716                                            HARDWARE_DEVICE_PATH,
717                                            HW_BMC_DP,
718                                            (UINT16) sizeof (BMC_DEVICE_PATH)
719                                            );
720 
721   BmcDp->InterfaceType = (UINT8) Strtoi (InterfaceTypeStr);
722   WriteUnaligned64 (
723     (UINT64 *) (&BmcDp->BaseAddress),
724     StrHexToUint64 (BaseAddressStr)
725     );
726 
727   return (EFI_DEVICE_PATH_PROTOCOL *) BmcDp;
728 }
729 
730 /**
731   Converts a generic ACPI text device path node to ACPI device path structure.
732 
733   @param TextDeviceNode  The input Text device path node.
734 
735   @return A pointer to ACPI device path structure.
736 
737 **/
738 static
739 EFI_DEVICE_PATH_PROTOCOL *
740 DevPathFromTextAcpiPath (
741   IN CHAR16 *TextDeviceNode
742   )
743 {
744   return DevPathFromTextGenericPath (ACPI_DEVICE_PATH, TextDeviceNode);
745 }
746 
747 /**
748   Converts a string to EisaId.
749 
750   @param Text   The input string.
751 
752   @return UINT32 EISA ID.
753 **/
754 static
755 UINT32
756 EisaIdFromText (
757   IN CHAR16 *Text
758   )
759 {
760   return (((Text[0] - 'A' + 1) & 0x1f) << 10)
761        + (((Text[1] - 'A' + 1) & 0x1f) <<  5)
762        + (((Text[2] - 'A' + 1) & 0x1f) <<  0)
763        + (UINT32) (StrHexToUintn (&Text[3]) << 16)
764        ;
765 }
766 
767 /**
768   Converts a text device path node to ACPI HID device path structure.
769 
770   @param TextDeviceNode  The input Text device path node.
771 
772   @return A pointer to the newly-created ACPI HID device path structure.
773 
774 **/
775 static
776 EFI_DEVICE_PATH_PROTOCOL *
777 DevPathFromTextAcpi (
778   IN CHAR16 *TextDeviceNode
779   )
780 {
781   CHAR16                *HIDStr;
782   CHAR16                *UIDStr;
783   ACPI_HID_DEVICE_PATH  *Acpi;
784 
785   HIDStr = GetNextParamStr (&TextDeviceNode);
786   UIDStr = GetNextParamStr (&TextDeviceNode);
787   Acpi   = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
788                                       ACPI_DEVICE_PATH,
789                                       ACPI_DP,
790                                       (UINT16) sizeof (ACPI_HID_DEVICE_PATH)
791                                       );
792 
793   Acpi->HID = EisaIdFromText (HIDStr);
794   Acpi->UID = (UINT32) Strtoi (UIDStr);
795 
796   return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
797 }
798 
799 /**
800   Converts a text device path node to ACPI HID device path structure.
801 
802   @param TextDeviceNode  The input Text device path node.
803   @param PnPId           The input plug and play identification.
804 
805   @return A pointer to the newly-created ACPI HID device path structure.
806 
807 **/
808 static
809 EFI_DEVICE_PATH_PROTOCOL *
810 ConvertFromTextAcpi (
811   IN CHAR16 *TextDeviceNode,
812   IN UINT32  PnPId
813   )
814 {
815   CHAR16                *UIDStr;
816   ACPI_HID_DEVICE_PATH  *Acpi;
817 
818   UIDStr = GetNextParamStr (&TextDeviceNode);
819   Acpi   = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
820                                       ACPI_DEVICE_PATH,
821                                       ACPI_DP,
822                                       (UINT16) sizeof (ACPI_HID_DEVICE_PATH)
823                                       );
824 
825   Acpi->HID = EFI_PNP_ID (PnPId);
826   Acpi->UID = (UINT32) Strtoi (UIDStr);
827 
828   return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
829 }
830 
831 /**
832   Converts a text device path node to PCI root device path structure.
833 
834   @param TextDeviceNode  The input Text device path node.
835 
836   @return A pointer to the newly-created PCI root device path structure.
837 
838 **/
839 static
840 EFI_DEVICE_PATH_PROTOCOL *
841 DevPathFromTextPciRoot (
842   IN CHAR16 *TextDeviceNode
843   )
844 {
845   return ConvertFromTextAcpi (TextDeviceNode, 0x0a03);
846 }
847 
848 /**
849   Converts a text device path node to PCIE root device path structure.
850 
851   @param TextDeviceNode  The input Text device path node.
852 
853   @return A pointer to the newly-created PCIE root device path structure.
854 
855 **/
856 static
857 EFI_DEVICE_PATH_PROTOCOL *
858 DevPathFromTextPcieRoot (
859   IN CHAR16 *TextDeviceNode
860   )
861 {
862   return ConvertFromTextAcpi (TextDeviceNode, 0x0a08);
863 }
864 
865 /**
866   Converts a text device path node to Floppy device path structure.
867 
868   @param TextDeviceNode  The input Text device path node.
869 
870   @return A pointer to the newly-created Floppy device path structure.
871 
872 **/
873 static
874 EFI_DEVICE_PATH_PROTOCOL *
875 DevPathFromTextFloppy (
876   IN CHAR16 *TextDeviceNode
877   )
878 {
879   return ConvertFromTextAcpi (TextDeviceNode, 0x0604);
880 }
881 
882 /**
883   Converts a text device path node to Keyboard device path structure.
884 
885   @param TextDeviceNode  The input Text device path node.
886 
887   @return A pointer to the newly-created  Keyboard device path structure.
888 
889 **/
890 static
891 EFI_DEVICE_PATH_PROTOCOL *
892 DevPathFromTextKeyboard (
893   IN CHAR16 *TextDeviceNode
894   )
895 {
896   return ConvertFromTextAcpi (TextDeviceNode, 0x0301);
897 }
898 
899 /**
900   Converts a text device path node to Serial device path structure.
901 
902   @param TextDeviceNode  The input Text device path node.
903 
904   @return A pointer to the newly-created Serial device path structure.
905 
906 **/
907 static
908 EFI_DEVICE_PATH_PROTOCOL *
909 DevPathFromTextSerial (
910   IN CHAR16 *TextDeviceNode
911   )
912 {
913   return ConvertFromTextAcpi (TextDeviceNode, 0x0501);
914 }
915 
916 /**
917   Converts a text device path node to Parallel Port device path structure.
918 
919   @param TextDeviceNode  The input Text device path node.
920 
921   @return A pointer to the newly-created Parallel Port device path structure.
922 
923 **/
924 static
925 EFI_DEVICE_PATH_PROTOCOL *
926 DevPathFromTextParallelPort (
927   IN CHAR16 *TextDeviceNode
928   )
929 {
930   return ConvertFromTextAcpi (TextDeviceNode, 0x0401);
931 }
932 
933 /**
934   Converts a text device path node to ACPI extension device path structure.
935 
936   @param TextDeviceNode  The input Text device path node.
937 
938   @return A pointer to the newly-created ACPI extension device path structure.
939 
940 **/
941 static
942 EFI_DEVICE_PATH_PROTOCOL *
943 DevPathFromTextAcpiEx (
944   IN CHAR16 *TextDeviceNode
945   )
946 {
947   CHAR16                         *HIDStr;
948   CHAR16                         *CIDStr;
949   CHAR16                         *UIDStr;
950   CHAR16                         *HIDSTRStr;
951   CHAR16                         *CIDSTRStr;
952   CHAR16                         *UIDSTRStr;
953   CHAR8                          *AsciiStr;
954   UINT16                         Length;
955   ACPI_EXTENDED_HID_DEVICE_PATH  *AcpiEx;
956 
957   HIDStr    = GetNextParamStr (&TextDeviceNode);
958   CIDStr    = GetNextParamStr (&TextDeviceNode);
959   UIDStr    = GetNextParamStr (&TextDeviceNode);
960   HIDSTRStr = GetNextParamStr (&TextDeviceNode);
961   CIDSTRStr = GetNextParamStr (&TextDeviceNode);
962   UIDSTRStr = GetNextParamStr (&TextDeviceNode);
963 
964   Length    = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (HIDSTRStr) + 1);
965   Length    = (UINT16) (Length + StrLen (UIDSTRStr) + 1);
966   Length    = (UINT16) (Length + StrLen (CIDSTRStr) + 1);
967   AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode (
968                                                ACPI_DEVICE_PATH,
969                                                ACPI_EXTENDED_DP,
970                                                Length
971                                                );
972 
973   AcpiEx->HID = EisaIdFromText (HIDStr);
974   AcpiEx->CID = EisaIdFromText (CIDStr);
975   AcpiEx->UID = (UINT32) Strtoi (UIDStr);
976 
977   AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
978   StrToAscii (HIDSTRStr, &AsciiStr);
979   StrToAscii (UIDSTRStr, &AsciiStr);
980   StrToAscii (CIDSTRStr, &AsciiStr);
981 
982   return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx;
983 }
984 
985 /**
986   Converts a text device path node to ACPI extension device path structure.
987 
988   @param TextDeviceNode  The input Text device path node.
989 
990   @return A pointer to the newly-created ACPI extension device path structure.
991 
992 **/
993 static
994 EFI_DEVICE_PATH_PROTOCOL *
995 DevPathFromTextAcpiExp (
996   IN CHAR16 *TextDeviceNode
997   )
998 {
999   CHAR16                         *HIDStr;
1000   CHAR16                         *CIDStr;
1001   CHAR16                         *UIDSTRStr;
1002   CHAR8                          *AsciiStr;
1003   UINT16                         Length;
1004   ACPI_EXTENDED_HID_DEVICE_PATH  *AcpiEx;
1005 
1006   HIDStr    = GetNextParamStr (&TextDeviceNode);
1007   CIDStr    = GetNextParamStr (&TextDeviceNode);
1008   UIDSTRStr = GetNextParamStr (&TextDeviceNode);
1009   Length    = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (UIDSTRStr) + 3);
1010   AcpiEx    = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode (
1011                                                   ACPI_DEVICE_PATH,
1012                                                   ACPI_EXTENDED_DP,
1013                                                   Length
1014                                                   );
1015 
1016   AcpiEx->HID = EisaIdFromText (HIDStr);
1017   AcpiEx->CID = EisaIdFromText (CIDStr);
1018   AcpiEx->UID = 0;
1019 
1020   AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
1021   //
1022   // HID string is NULL
1023   //
1024   *AsciiStr = '\0';
1025   //
1026   // Convert UID string
1027   //
1028   AsciiStr++;
1029   StrToAscii (UIDSTRStr, &AsciiStr);
1030   //
1031   // CID string is NULL
1032   //
1033   *AsciiStr = '\0';
1034 
1035   return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx;
1036 }
1037 
1038 /**
1039   Converts a text device path node to ACPI _ADR device path structure.
1040 
1041   @param TextDeviceNode  The input Text device path node.
1042 
1043   @return A pointer to the newly-created ACPI _ADR device path structure.
1044 
1045 **/
1046 static
1047 EFI_DEVICE_PATH_PROTOCOL *
1048 DevPathFromTextAcpiAdr (
1049   IN CHAR16 *TextDeviceNode
1050   )
1051 {
1052   CHAR16                *DisplayDeviceStr;
1053   ACPI_ADR_DEVICE_PATH  *AcpiAdr;
1054   UINTN                 Index;
1055   UINTN                 Length;
1056 
1057   AcpiAdr = (ACPI_ADR_DEVICE_PATH *) CreateDeviceNode (
1058                                        ACPI_DEVICE_PATH,
1059                                        ACPI_ADR_DP,
1060                                        (UINT16) sizeof (ACPI_ADR_DEVICE_PATH)
1061                                        );
1062   ASSERT (AcpiAdr != NULL);
1063 
1064   for (Index = 0; ; Index++) {
1065     DisplayDeviceStr = GetNextParamStr (&TextDeviceNode);
1066     if (IS_NULL (*DisplayDeviceStr)) {
1067       break;
1068     }
1069     if (Index > 0) {
1070       Length  = DevicePathNodeLength (AcpiAdr);
1071       AcpiAdr = ReallocatePool (
1072                   Length,
1073                   Length + sizeof (UINT32),
1074                   AcpiAdr
1075                   );
1076       ASSERT (AcpiAdr != NULL);
1077       SetDevicePathNodeLength (AcpiAdr, Length + sizeof (UINT32));
1078     }
1079 
1080     (&AcpiAdr->ADR)[Index] = (UINT32) Strtoi (DisplayDeviceStr);
1081   }
1082 
1083   return (EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr;
1084 }
1085 
1086 /**
1087   Converts a generic messaging text device path node to messaging device path structure.
1088 
1089   @param TextDeviceNode  The input Text device path node.
1090 
1091   @return A pointer to messaging device path structure.
1092 
1093 **/
1094 static
1095 EFI_DEVICE_PATH_PROTOCOL *
1096 DevPathFromTextMsg (
1097   IN CHAR16 *TextDeviceNode
1098   )
1099 {
1100   return DevPathFromTextGenericPath (MESSAGING_DEVICE_PATH, TextDeviceNode);
1101 }
1102 
1103 /**
1104   Converts a text device path node to Parallel Port device path structure.
1105 
1106   @param TextDeviceNode  The input Text device path node.
1107 
1108   @return A pointer to the newly-created Parallel Port device path structure.
1109 
1110 **/
1111 static
1112 EFI_DEVICE_PATH_PROTOCOL *
1113 DevPathFromTextAta (
1114 IN CHAR16 *TextDeviceNode
1115 )
1116 {
1117   CHAR16            *PrimarySecondaryStr;
1118   CHAR16            *SlaveMasterStr;
1119   CHAR16            *LunStr;
1120   ATAPI_DEVICE_PATH *Atapi;
1121 
1122   Atapi = (ATAPI_DEVICE_PATH *) CreateDeviceNode (
1123     MESSAGING_DEVICE_PATH,
1124     MSG_ATAPI_DP,
1125     (UINT16) sizeof (ATAPI_DEVICE_PATH)
1126     );
1127 
1128   PrimarySecondaryStr = GetNextParamStr (&TextDeviceNode);
1129   SlaveMasterStr      = GetNextParamStr (&TextDeviceNode);
1130   LunStr              = GetNextParamStr (&TextDeviceNode);
1131 
1132   if (StrCmp (PrimarySecondaryStr, "Primary") == 0) {
1133     Atapi->PrimarySecondary = 0;
1134   } else if (StrCmp (PrimarySecondaryStr, "Secondary") == 0) {
1135     Atapi->PrimarySecondary = 1;
1136   } else {
1137     Atapi->PrimarySecondary = (UINT8) Strtoi (PrimarySecondaryStr);
1138   }
1139   if (StrCmp (SlaveMasterStr, "Master") == 0) {
1140     Atapi->SlaveMaster      = 0;
1141   } else if (StrCmp (SlaveMasterStr, "Slave") == 0) {
1142     Atapi->SlaveMaster      = 1;
1143   } else {
1144     Atapi->SlaveMaster      = (UINT8) Strtoi (SlaveMasterStr);
1145   }
1146 
1147   Atapi->Lun                = (UINT16) Strtoi (LunStr);
1148 
1149   return (EFI_DEVICE_PATH_PROTOCOL *) Atapi;
1150 }
1151 
1152 /**
1153   Converts a text device path node to SCSI device path structure.
1154 
1155   @param TextDeviceNode  The input Text device path node.
1156 
1157   @return A pointer to the newly-created SCSI device path structure.
1158 
1159 **/
1160 static
1161 EFI_DEVICE_PATH_PROTOCOL *
1162 DevPathFromTextScsi (
1163   IN CHAR16 *TextDeviceNode
1164   )
1165 {
1166   CHAR16            *PunStr;
1167   CHAR16            *LunStr;
1168   SCSI_DEVICE_PATH  *Scsi;
1169 
1170   PunStr = GetNextParamStr (&TextDeviceNode);
1171   LunStr = GetNextParamStr (&TextDeviceNode);
1172   Scsi   = (SCSI_DEVICE_PATH *) CreateDeviceNode (
1173                                    MESSAGING_DEVICE_PATH,
1174                                    MSG_SCSI_DP,
1175                                    (UINT16) sizeof (SCSI_DEVICE_PATH)
1176                                    );
1177 
1178   Scsi->Pun = (UINT16) Strtoi (PunStr);
1179   Scsi->Lun = (UINT16) Strtoi (LunStr);
1180 
1181   return (EFI_DEVICE_PATH_PROTOCOL *) Scsi;
1182 }
1183 
1184 /**
1185   Converts a text device path node to Fibre device path structure.
1186 
1187   @param TextDeviceNode  The input Text device path node.
1188 
1189   @return A pointer to the newly-created Fibre device path structure.
1190 
1191 **/
1192 static
1193 EFI_DEVICE_PATH_PROTOCOL *
1194 DevPathFromTextFibre (
1195   IN CHAR16 *TextDeviceNode
1196   )
1197 {
1198   CHAR16                    *WWNStr;
1199   CHAR16                    *LunStr;
1200   FIBRECHANNEL_DEVICE_PATH  *Fibre;
1201 
1202   WWNStr = GetNextParamStr (&TextDeviceNode);
1203   LunStr = GetNextParamStr (&TextDeviceNode);
1204   Fibre  = (FIBRECHANNEL_DEVICE_PATH *) CreateDeviceNode (
1205                                           MESSAGING_DEVICE_PATH,
1206                                           MSG_FIBRECHANNEL_DP,
1207                                           (UINT16) sizeof (FIBRECHANNEL_DEVICE_PATH)
1208                                           );
1209 
1210   Fibre->Reserved = 0;
1211   Strtoi64 (WWNStr, &Fibre->WWN);
1212   Strtoi64 (LunStr, &Fibre->Lun);
1213 
1214   return (EFI_DEVICE_PATH_PROTOCOL *) Fibre;
1215 }
1216 
1217 /**
1218   Converts a text device path node to FibreEx device path structure.
1219 
1220   @param TextDeviceNode  The input Text device path node.
1221 
1222   @return A pointer to the newly-created FibreEx device path structure.
1223 
1224 **/
1225 static
1226 EFI_DEVICE_PATH_PROTOCOL *
1227 DevPathFromTextFibreEx (
1228   IN CHAR16 *TextDeviceNode
1229   )
1230 {
1231   CHAR16                      *WWNStr;
1232   CHAR16                      *LunStr;
1233   FIBRECHANNELEX_DEVICE_PATH  *FibreEx;
1234 
1235   WWNStr  = GetNextParamStr (&TextDeviceNode);
1236   LunStr  = GetNextParamStr (&TextDeviceNode);
1237   FibreEx = (FIBRECHANNELEX_DEVICE_PATH *) CreateDeviceNode (
1238                                              MESSAGING_DEVICE_PATH,
1239                                              MSG_FIBRECHANNELEX_DP,
1240                                              (UINT16) sizeof (FIBRECHANNELEX_DEVICE_PATH)
1241                                              );
1242 
1243   FibreEx->Reserved = 0;
1244   Strtoi64 (WWNStr, (UINT64 *) (&FibreEx->WWN));
1245   Strtoi64 (LunStr, (UINT64 *) (&FibreEx->Lun));
1246 
1247   *(UINT64 *) (&FibreEx->WWN) = SwapBytes64 (*(UINT64 *) (&FibreEx->WWN));
1248   *(UINT64 *) (&FibreEx->Lun) = SwapBytes64 (*(UINT64 *) (&FibreEx->Lun));
1249 
1250   return (EFI_DEVICE_PATH_PROTOCOL *) FibreEx;
1251 }
1252 
1253 /**
1254   Converts a text device path node to 1394 device path structure.
1255 
1256   @param TextDeviceNode  The input Text device path node.
1257 
1258   @return A pointer to the newly-created 1394 device path structure.
1259 
1260 **/
1261 static
1262 EFI_DEVICE_PATH_PROTOCOL *
1263 DevPathFromText1394 (
1264   IN CHAR16 *TextDeviceNode
1265   )
1266 {
1267   CHAR16            *GuidStr;
1268   F1394_DEVICE_PATH *F1394DevPath;
1269 
1270   GuidStr = GetNextParamStr (&TextDeviceNode);
1271   F1394DevPath  = (F1394_DEVICE_PATH *) CreateDeviceNode (
1272                                           MESSAGING_DEVICE_PATH,
1273                                           MSG_1394_DP,
1274                                           (UINT16) sizeof (F1394_DEVICE_PATH)
1275                                           );
1276 
1277   F1394DevPath->Reserved = 0;
1278   F1394DevPath->Guid     = StrHexToUint64 (GuidStr);
1279 
1280   return (EFI_DEVICE_PATH_PROTOCOL *) F1394DevPath;
1281 }
1282 
1283 /**
1284   Converts a text device path node to USB device path structure.
1285 
1286   @param TextDeviceNode  The input Text device path node.
1287 
1288   @return A pointer to the newly-created USB device path structure.
1289 
1290 **/
1291 static
1292 EFI_DEVICE_PATH_PROTOCOL *
1293 DevPathFromTextUsb (
1294   IN CHAR16 *TextDeviceNode
1295   )
1296 {
1297   CHAR16          *PortStr;
1298   CHAR16          *InterfaceStr;
1299   USB_DEVICE_PATH *Usb;
1300 
1301   PortStr               = GetNextParamStr (&TextDeviceNode);
1302   InterfaceStr          = GetNextParamStr (&TextDeviceNode);
1303   Usb                   = (USB_DEVICE_PATH *) CreateDeviceNode (
1304                                                 MESSAGING_DEVICE_PATH,
1305                                                 MSG_USB_DP,
1306                                                 (UINT16) sizeof (USB_DEVICE_PATH)
1307                                                 );
1308 
1309   Usb->ParentPortNumber = (UINT8) Strtoi (PortStr);
1310   Usb->InterfaceNumber  = (UINT8) Strtoi (InterfaceStr);
1311 
1312   return (EFI_DEVICE_PATH_PROTOCOL *) Usb;
1313 }
1314 
1315 /**
1316   Converts a text device path node to I20 device path structure.
1317 
1318   @param TextDeviceNode  The input Text device path node.
1319 
1320   @return A pointer to the newly-created I20 device path structure.
1321 
1322 **/
1323 static
1324 EFI_DEVICE_PATH_PROTOCOL *
1325 DevPathFromTextI2O (
1326   IN CHAR16 *TextDeviceNode
1327   )
1328 {
1329   CHAR16          *TIDStr;
1330   I2O_DEVICE_PATH *I2ODevPath;
1331 
1332   TIDStr     = GetNextParamStr (&TextDeviceNode);
1333   I2ODevPath = (I2O_DEVICE_PATH *) CreateDeviceNode (
1334                                     MESSAGING_DEVICE_PATH,
1335                                     MSG_I2O_DP,
1336                                     (UINT16) sizeof (I2O_DEVICE_PATH)
1337                                     );
1338 
1339   I2ODevPath->Tid  = (UINT32) Strtoi (TIDStr);
1340 
1341   return (EFI_DEVICE_PATH_PROTOCOL *) I2ODevPath;
1342 }
1343 
1344 /**
1345   Converts a text device path node to Infini Band device path structure.
1346 
1347   @param TextDeviceNode  The input Text device path node.
1348 
1349   @return A pointer to the newly-created Infini Band device path structure.
1350 
1351 **/
1352 static
1353 EFI_DEVICE_PATH_PROTOCOL *
1354 DevPathFromTextInfiniband (
1355   IN CHAR16 *TextDeviceNode
1356   )
1357 {
1358   CHAR16                  *FlagsStr;
1359   CHAR16                  *GuidStr;
1360   CHAR16                  *SidStr;
1361   CHAR16                  *TidStr;
1362   CHAR16                  *DidStr;
1363   INFINIBAND_DEVICE_PATH  *InfiniBand;
1364 
1365   FlagsStr   = GetNextParamStr (&TextDeviceNode);
1366   GuidStr    = GetNextParamStr (&TextDeviceNode);
1367   SidStr     = GetNextParamStr (&TextDeviceNode);
1368   TidStr     = GetNextParamStr (&TextDeviceNode);
1369   DidStr     = GetNextParamStr (&TextDeviceNode);
1370   InfiniBand = (INFINIBAND_DEVICE_PATH *) CreateDeviceNode (
1371                                             MESSAGING_DEVICE_PATH,
1372                                             MSG_INFINIBAND_DP,
1373                                             (UINT16) sizeof (INFINIBAND_DEVICE_PATH)
1374                                             );
1375 
1376   InfiniBand->ResourceFlags = (UINT32) Strtoi (FlagsStr);
1377   StrToGuid (GuidStr, (EFI_GUID *) InfiniBand->PortGid);
1378   Strtoi64 (SidStr, &InfiniBand->ServiceId);
1379   Strtoi64 (TidStr, &InfiniBand->TargetPortId);
1380   Strtoi64 (DidStr, &InfiniBand->DeviceId);
1381 
1382   return (EFI_DEVICE_PATH_PROTOCOL *) InfiniBand;
1383 }
1384 
1385 /**
1386   Converts a text device path node to Vendor-Defined Messaging device path structure.
1387 
1388   @param TextDeviceNode  The input Text device path node.
1389 
1390   @return A pointer to the newly-created Vendor-Defined Messaging device path structure.
1391 
1392 **/
1393 static
1394 EFI_DEVICE_PATH_PROTOCOL *
1395 DevPathFromTextVenMsg (
1396   IN CHAR16 *TextDeviceNode
1397   )
1398 {
1399   return ConvertFromTextVendor (
1400             TextDeviceNode,
1401             MESSAGING_DEVICE_PATH,
1402             MSG_VENDOR_DP
1403             );
1404 }
1405 
1406 /**
1407   Converts a text device path node to Vendor defined PC-ANSI device path structure.
1408 
1409   @param TextDeviceNode  The input Text device path node.
1410 
1411   @return A pointer to the newly-created Vendor defined PC-ANSI device path structure.
1412 
1413 **/
1414 static
1415 EFI_DEVICE_PATH_PROTOCOL *
1416 DevPathFromTextVenPcAnsi (
1417   IN CHAR16 *TextDeviceNode
1418   )
1419 {
1420   VENDOR_DEVICE_PATH  *Vendor;
1421 
1422   Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
1423                                     MESSAGING_DEVICE_PATH,
1424                                     MSG_VENDOR_DP,
1425                                     (UINT16) sizeof (VENDOR_DEVICE_PATH));
1426   CopyGuid (&Vendor->Guid, &gEfiPcAnsiGuid);
1427 
1428   return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
1429 }
1430 
1431 /**
1432   Converts a text device path node to Vendor defined VT100 device path structure.
1433 
1434   @param TextDeviceNode  The input Text device path node.
1435 
1436   @return A pointer to the newly-created Vendor defined VT100 device path structure.
1437 
1438 **/
1439 static
1440 EFI_DEVICE_PATH_PROTOCOL *
1441 DevPathFromTextVenVt100 (
1442   IN CHAR16 *TextDeviceNode
1443   )
1444 {
1445   VENDOR_DEVICE_PATH  *Vendor;
1446 
1447   Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
1448                                     MESSAGING_DEVICE_PATH,
1449                                     MSG_VENDOR_DP,
1450                                     (UINT16) sizeof (VENDOR_DEVICE_PATH));
1451   CopyGuid (&Vendor->Guid, &gEfiVT100Guid);
1452 
1453   return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
1454 }
1455 
1456 /**
1457   Converts a text device path node to Vendor defined VT100 Plus device path structure.
1458 
1459   @param TextDeviceNode  The input Text device path node.
1460 
1461   @return A pointer to the newly-created Vendor defined VT100 Plus device path structure.
1462 
1463 **/
1464 static
1465 EFI_DEVICE_PATH_PROTOCOL *
1466 DevPathFromTextVenVt100Plus (
1467   IN CHAR16 *TextDeviceNode
1468   )
1469 {
1470   VENDOR_DEVICE_PATH  *Vendor;
1471 
1472   Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
1473                                     MESSAGING_DEVICE_PATH,
1474                                     MSG_VENDOR_DP,
1475                                     (UINT16) sizeof (VENDOR_DEVICE_PATH));
1476   CopyGuid (&Vendor->Guid, &gEfiVT100PlusGuid);
1477 
1478   return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
1479 }
1480 
1481 /**
1482   Converts a text device path node to Vendor defined UTF8 device path structure.
1483 
1484   @param TextDeviceNode  The input Text device path node.
1485 
1486   @return A pointer to the newly-created Vendor defined UTF8 device path structure.
1487 
1488 **/
1489 static
1490 EFI_DEVICE_PATH_PROTOCOL *
1491 DevPathFromTextVenUtf8 (
1492   IN CHAR16 *TextDeviceNode
1493   )
1494 {
1495   VENDOR_DEVICE_PATH  *Vendor;
1496 
1497   Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
1498                                     MESSAGING_DEVICE_PATH,
1499                                     MSG_VENDOR_DP,
1500                                     (UINT16) sizeof (VENDOR_DEVICE_PATH));
1501   CopyGuid (&Vendor->Guid, &gEfiVTUTF8Guid);
1502 
1503   return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
1504 }
1505 
1506 /**
1507   Converts a text device path node to UART Flow Control device path structure.
1508 
1509   @param TextDeviceNode  The input Text device path node.
1510 
1511   @return A pointer to the newly-created UART Flow Control device path structure.
1512 
1513 **/
1514 static
1515 EFI_DEVICE_PATH_PROTOCOL *
1516 DevPathFromTextUartFlowCtrl (
1517   IN CHAR16 *TextDeviceNode
1518   )
1519 {
1520   CHAR16                        *ValueStr;
1521   UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl;
1522 
1523   ValueStr        = GetNextParamStr (&TextDeviceNode);
1524   UartFlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) CreateDeviceNode (
1525                                                         MESSAGING_DEVICE_PATH,
1526                                                         MSG_VENDOR_DP,
1527                                                         (UINT16) sizeof (UART_FLOW_CONTROL_DEVICE_PATH)
1528                                                         );
1529 
1530   CopyGuid (&UartFlowControl->Guid, &gEfiUartDevicePathGuid);
1531   if (StrCmp (ValueStr, "XonXoff") == 0) {
1532     UartFlowControl->FlowControlMap = 2;
1533   } else if (StrCmp (ValueStr, "Hardware") == 0) {
1534     UartFlowControl->FlowControlMap = 1;
1535   } else {
1536     UartFlowControl->FlowControlMap = 0;
1537   }
1538 
1539   return (EFI_DEVICE_PATH_PROTOCOL *) UartFlowControl;
1540 }
1541 
1542 /**
1543   Converts a text device path node to Serial Attached SCSI device path structure.
1544 
1545   @param TextDeviceNode  The input Text device path node.
1546 
1547   @return A pointer to the newly-created Serial Attached SCSI device path structure.
1548 
1549 **/
1550 static
1551 EFI_DEVICE_PATH_PROTOCOL *
1552 DevPathFromTextSAS (
1553   IN CHAR16 *TextDeviceNode
1554   )
1555 {
1556   CHAR16          *AddressStr;
1557   CHAR16          *LunStr;
1558   CHAR16          *RTPStr;
1559   CHAR16          *SASSATAStr;
1560   CHAR16          *LocationStr;
1561   CHAR16          *ConnectStr;
1562   CHAR16          *DriveBayStr;
1563   CHAR16          *ReservedStr;
1564   UINT16          Info;
1565   UINT16          Uint16;
1566   SAS_DEVICE_PATH *Sas;
1567 
1568   AddressStr  = GetNextParamStr (&TextDeviceNode);
1569   LunStr      = GetNextParamStr (&TextDeviceNode);
1570   RTPStr      = GetNextParamStr (&TextDeviceNode);
1571   SASSATAStr  = GetNextParamStr (&TextDeviceNode);
1572   LocationStr = GetNextParamStr (&TextDeviceNode);
1573   ConnectStr  = GetNextParamStr (&TextDeviceNode);
1574   DriveBayStr = GetNextParamStr (&TextDeviceNode);
1575   ReservedStr = GetNextParamStr (&TextDeviceNode);
1576   Sas         = (SAS_DEVICE_PATH *) CreateDeviceNode (
1577                                        MESSAGING_DEVICE_PATH,
1578                                        MSG_VENDOR_DP,
1579                                        (UINT16) sizeof (SAS_DEVICE_PATH)
1580                                        );
1581 
1582   CopyGuid (&Sas->Guid, &gEfiSasDevicePathGuid);
1583   Strtoi64 (AddressStr, &Sas->SasAddress);
1584   Strtoi64 (LunStr, &Sas->Lun);
1585   Sas->RelativeTargetPort = (UINT16) Strtoi (RTPStr);
1586 
1587   if (StrCmp (SASSATAStr, "NoTopology") == 0) {
1588     Info = 0x0;
1589 
1590   } else if ((StrCmp (SASSATAStr, "SATA") == 0) || (StrCmp (SASSATAStr, "SAS") == 0)) {
1591 
1592     Uint16 = (UINT16) Strtoi (DriveBayStr);
1593     if (Uint16 == 0) {
1594       Info = 0x1;
1595     } else {
1596       Info = (UINT16) (0x2 | ((Uint16 - 1) << 8));
1597     }
1598 
1599     if (StrCmp (SASSATAStr, "SATA") == 0) {
1600       Info |= BIT4;
1601     }
1602 
1603     //
1604     // Location is an integer between 0 and 1 or else
1605     // the keyword Internal (0) or External (1).
1606     //
1607     if (StrCmp (LocationStr, "External") == 0) {
1608       Uint16 = 1;
1609     } else if (StrCmp (LocationStr, "Internal") == 0) {
1610       Uint16 = 0;
1611     } else {
1612       Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0);
1613     }
1614     Info |= (Uint16 << 5);
1615 
1616     //
1617     // Connect is an integer between 0 and 3 or else
1618     // the keyword Direct (0) or Expanded (1).
1619     //
1620     if (StrCmp (ConnectStr, "Expanded") == 0) {
1621       Uint16 = 1;
1622     } else if (StrCmp (ConnectStr, "Direct") == 0) {
1623       Uint16 = 0;
1624     } else {
1625       Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1));
1626     }
1627     Info |= (Uint16 << 6);
1628 
1629   } else {
1630     Info = (UINT16) Strtoi (SASSATAStr);
1631   }
1632 
1633   Sas->DeviceTopology = Info;
1634   Sas->Reserved       = (UINT32) Strtoi (ReservedStr);
1635 
1636   return (EFI_DEVICE_PATH_PROTOCOL *) Sas;
1637 }
1638 
1639 /**
1640   Converts a text device path node to Serial Attached SCSI Ex device path structure.
1641 
1642   @param TextDeviceNode  The input Text device path node.
1643 
1644   @return A pointer to the newly-created Serial Attached SCSI Ex device path structure.
1645 
1646 **/
1647 static
1648 EFI_DEVICE_PATH_PROTOCOL *
1649 DevPathFromTextSasEx (
1650   IN CHAR16 *TextDeviceNode
1651   )
1652 {
1653   CHAR16            *AddressStr;
1654   CHAR16            *LunStr;
1655   CHAR16            *RTPStr;
1656   CHAR16            *SASSATAStr;
1657   CHAR16            *LocationStr;
1658   CHAR16            *ConnectStr;
1659   CHAR16            *DriveBayStr;
1660   UINT16            Info;
1661   UINT16            Uint16;
1662   UINT64            SasAddress;
1663   UINT64            Lun;
1664   SASEX_DEVICE_PATH *SasEx;
1665 
1666   AddressStr  = GetNextParamStr (&TextDeviceNode);
1667   LunStr      = GetNextParamStr (&TextDeviceNode);
1668   RTPStr      = GetNextParamStr (&TextDeviceNode);
1669   SASSATAStr  = GetNextParamStr (&TextDeviceNode);
1670   LocationStr = GetNextParamStr (&TextDeviceNode);
1671   ConnectStr  = GetNextParamStr (&TextDeviceNode);
1672   DriveBayStr = GetNextParamStr (&TextDeviceNode);
1673   SasEx       = (SASEX_DEVICE_PATH *) CreateDeviceNode (
1674                                         MESSAGING_DEVICE_PATH,
1675                                         MSG_SASEX_DP,
1676                                         (UINT16) sizeof (SASEX_DEVICE_PATH)
1677                                         );
1678 
1679   Strtoi64 (AddressStr, &SasAddress);
1680   Strtoi64 (LunStr,     &Lun);
1681   WriteUnaligned64 ((UINT64 *) &SasEx->SasAddress, SwapBytes64 (SasAddress));
1682   WriteUnaligned64 ((UINT64 *) &SasEx->Lun,        SwapBytes64 (Lun));
1683   SasEx->RelativeTargetPort      = (UINT16) Strtoi (RTPStr);
1684 
1685   if (StrCmp (SASSATAStr, "NoTopology") == 0) {
1686     Info = 0x0;
1687 
1688   } else if ((StrCmp (SASSATAStr, "SATA") == 0) || (StrCmp (SASSATAStr, "SAS") == 0)) {
1689 
1690     Uint16 = (UINT16) Strtoi (DriveBayStr);
1691     if (Uint16 == 0) {
1692       Info = 0x1;
1693     } else {
1694       Info = (UINT16) (0x2 | ((Uint16 - 1) << 8));
1695     }
1696 
1697     if (StrCmp (SASSATAStr, "SATA") == 0) {
1698       Info |= BIT4;
1699     }
1700 
1701     //
1702     // Location is an integer between 0 and 1 or else
1703     // the keyword Internal (0) or External (1).
1704     //
1705     if (StrCmp (LocationStr, "External") == 0) {
1706       Uint16 = 1;
1707     } else if (StrCmp (LocationStr, "Internal") == 0) {
1708       Uint16 = 0;
1709     } else {
1710       Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0);
1711     }
1712     Info |= (Uint16 << 5);
1713 
1714     //
1715     // Connect is an integer between 0 and 3 or else
1716     // the keyword Direct (0) or Expanded (1).
1717     //
1718     if (StrCmp (ConnectStr, "Expanded") == 0) {
1719       Uint16 = 1;
1720     } else if (StrCmp (ConnectStr, "Direct") == 0) {
1721       Uint16 = 0;
1722     } else {
1723       Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1));
1724     }
1725     Info |= (Uint16 << 6);
1726 
1727   } else {
1728     Info = (UINT16) Strtoi (SASSATAStr);
1729   }
1730 
1731   SasEx->DeviceTopology = Info;
1732 
1733   return (EFI_DEVICE_PATH_PROTOCOL *) SasEx;
1734 }
1735 
1736 /**
1737   Converts a text device path node to NVM Express Namespace device path structure.
1738 
1739   @param TextDeviceNode  The input Text device path node.
1740 
1741   @return A pointer to the newly-created NVM Express Namespace device path structure.
1742 
1743 **/
1744 static
1745 EFI_DEVICE_PATH_PROTOCOL *
1746 DevPathFromTextNVMe (
1747   IN CHAR16 *TextDeviceNode
1748   )
1749 {
1750   CHAR16                     *NamespaceIdStr;
1751   CHAR16                     *NamespaceUuidStr;
1752   NVME_NAMESPACE_DEVICE_PATH *Nvme;
1753   UINT8                      *Uuid;
1754   UINTN                      Index;
1755 
1756   NamespaceIdStr   = GetNextParamStr (&TextDeviceNode);
1757   NamespaceUuidStr = GetNextParamStr (&TextDeviceNode);
1758   Nvme = (NVME_NAMESPACE_DEVICE_PATH *) CreateDeviceNode (
1759     MESSAGING_DEVICE_PATH,
1760     MSG_NVME_NAMESPACE_DP,
1761     (UINT16) sizeof (NVME_NAMESPACE_DEVICE_PATH)
1762     );
1763 
1764   Nvme->NamespaceId = (UINT32) Strtoi (NamespaceIdStr);
1765   Uuid = (UINT8 *) &Nvme->NamespaceUuid;
1766 
1767   Index = sizeof (Nvme->NamespaceUuid) / sizeof (UINT8);
1768   while (Index-- != 0) {
1769     Uuid[Index] = (UINT8) StrHexToUintn (SplitStr (&NamespaceUuidStr, '-'));
1770   }
1771 
1772   return (EFI_DEVICE_PATH_PROTOCOL *) Nvme;
1773 }
1774 
1775 /**
1776   Converts a text device path node to UFS device path structure.
1777 
1778   @param TextDeviceNode  The input Text device path node.
1779 
1780   @return A pointer to the newly-created UFS device path structure.
1781 
1782 **/
1783 static
1784 EFI_DEVICE_PATH_PROTOCOL *
1785 DevPathFromTextUfs (
1786   IN CHAR16 *TextDeviceNode
1787   )
1788 {
1789   CHAR16            *PunStr;
1790   CHAR16            *LunStr;
1791   UFS_DEVICE_PATH   *Ufs;
1792 
1793   PunStr = GetNextParamStr (&TextDeviceNode);
1794   LunStr = GetNextParamStr (&TextDeviceNode);
1795   Ufs    = (UFS_DEVICE_PATH *) CreateDeviceNode (
1796                                  MESSAGING_DEVICE_PATH,
1797                                  MSG_UFS_DP,
1798                                  (UINT16) sizeof (UFS_DEVICE_PATH)
1799                                  );
1800 
1801   Ufs->Pun = (UINT8) Strtoi (PunStr);
1802   Ufs->Lun = (UINT8) Strtoi (LunStr);
1803 
1804   return (EFI_DEVICE_PATH_PROTOCOL *) Ufs;
1805 }
1806 
1807 /**
1808   Converts a text device path node to SD (Secure Digital) device path structure.
1809 
1810   @param TextDeviceNode  The input Text device path node.
1811 
1812   @return A pointer to the newly-created SD device path structure.
1813 
1814 **/
1815 static
1816 EFI_DEVICE_PATH_PROTOCOL *
1817 DevPathFromTextSd (
1818   IN CHAR16 *TextDeviceNode
1819   )
1820 {
1821   CHAR16            *SlotNumberStr;
1822   SD_DEVICE_PATH    *Sd;
1823 
1824   SlotNumberStr = GetNextParamStr (&TextDeviceNode);
1825   Sd            = (SD_DEVICE_PATH *) CreateDeviceNode (
1826                                        MESSAGING_DEVICE_PATH,
1827                                        MSG_SD_DP,
1828                                        (UINT16) sizeof (SD_DEVICE_PATH)
1829                                        );
1830 
1831   Sd->SlotNumber = (UINT8) Strtoi (SlotNumberStr);
1832 
1833   return (EFI_DEVICE_PATH_PROTOCOL *) Sd;
1834 }
1835 
1836 /**
1837   Converts a text device path node to EMMC (Embedded MMC) device path structure.
1838 
1839   @param TextDeviceNode  The input Text device path node.
1840 
1841   @return A pointer to the newly-created EMMC device path structure.
1842 
1843 **/
1844 static
1845 EFI_DEVICE_PATH_PROTOCOL *
1846 DevPathFromTextEmmc (
1847   IN CHAR16 *TextDeviceNode
1848   )
1849 {
1850   CHAR16            *SlotNumberStr;
1851   EMMC_DEVICE_PATH  *Emmc;
1852 
1853   SlotNumberStr = GetNextParamStr (&TextDeviceNode);
1854   Emmc          = (EMMC_DEVICE_PATH *) CreateDeviceNode (
1855                                        MESSAGING_DEVICE_PATH,
1856                                        MSG_EMMC_DP,
1857                                        (UINT16) sizeof (EMMC_DEVICE_PATH)
1858                                        );
1859 
1860   Emmc->SlotNumber = (UINT8) Strtoi (SlotNumberStr);
1861 
1862   return (EFI_DEVICE_PATH_PROTOCOL *) Emmc;
1863 }
1864 
1865 /**
1866   Converts a text device path node to Debug Port device path structure.
1867 
1868   @param TextDeviceNode  The input Text device path node.
1869 
1870   @return A pointer to the newly-created Debug Port device path structure.
1871 
1872 **/
1873 static
1874 EFI_DEVICE_PATH_PROTOCOL *
1875 DevPathFromTextDebugPort (
1876   IN CHAR16 *TextDeviceNode
1877   )
1878 {
1879   VENDOR_DEVICE_PATH  *Vend;
1880 
1881   Vend = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
1882                                                     MESSAGING_DEVICE_PATH,
1883                                                     MSG_VENDOR_DP,
1884                                                     (UINT16) sizeof (VENDOR_DEVICE_PATH)
1885                                                     );
1886 
1887   CopyGuid (&Vend->Guid, &gEfiDebugPortProtocolGuid);
1888 
1889   return (EFI_DEVICE_PATH_PROTOCOL *) Vend;
1890 }
1891 
1892 /**
1893   Converts a text device path node to MAC device path structure.
1894 
1895   @param TextDeviceNode  The input Text device path node.
1896 
1897   @return A pointer to the newly-created MAC device path structure.
1898 
1899 **/
1900 static
1901 EFI_DEVICE_PATH_PROTOCOL *
1902 DevPathFromTextMAC (
1903   IN CHAR16 *TextDeviceNode
1904   )
1905 {
1906   CHAR16                *AddressStr;
1907   CHAR16                *IfTypeStr;
1908   UINTN                 Length;
1909   MAC_ADDR_DEVICE_PATH  *MACDevPath;
1910 
1911   AddressStr    = GetNextParamStr (&TextDeviceNode);
1912   IfTypeStr     = GetNextParamStr (&TextDeviceNode);
1913   MACDevPath    = (MAC_ADDR_DEVICE_PATH *) CreateDeviceNode (
1914                                               MESSAGING_DEVICE_PATH,
1915                                               MSG_MAC_ADDR_DP,
1916                                               (UINT16) sizeof (MAC_ADDR_DEVICE_PATH)
1917                                               );
1918 
1919   MACDevPath->IfType   = (UINT8) Strtoi (IfTypeStr);
1920 
1921   Length = sizeof (EFI_MAC_ADDRESS);
1922   if (MACDevPath->IfType == 0x01 || MACDevPath->IfType == 0x00) {
1923     Length = 6;
1924   }
1925 
1926   StrHexToBytes (AddressStr, Length * 2, MACDevPath->MacAddress.Addr, Length);
1927 
1928   return (EFI_DEVICE_PATH_PROTOCOL *) MACDevPath;
1929 }
1930 
1931 
1932 /**
1933   Converts a text format to the network protocol ID.
1934 
1935   @param Text  String of protocol field.
1936 
1937   @return Network protocol ID .
1938 
1939 **/
1940 static
1941 UINTN
1942 NetworkProtocolFromText (
1943   IN CHAR16 *Text
1944   )
1945 {
1946   if (StrCmp (Text, "UDP") == 0) {
1947     return RFC_1700_UDP_PROTOCOL;
1948   }
1949 
1950   if (StrCmp (Text, "TCP") == 0) {
1951     return RFC_1700_TCP_PROTOCOL;
1952   }
1953 
1954   return Strtoi (Text);
1955 }
1956 
1957 
1958 /**
1959   Converts a text device path node to IPV4 device path structure.
1960 
1961   @param TextDeviceNode  The input Text device path node.
1962 
1963   @return A pointer to the newly-created IPV4 device path structure.
1964 
1965 **/
1966 static
1967 EFI_DEVICE_PATH_PROTOCOL *
1968 DevPathFromTextIPv4 (
1969   IN CHAR16 *TextDeviceNode
1970   )
1971 {
1972   CHAR16            *RemoteIPStr;
1973   CHAR16            *ProtocolStr;
1974   CHAR16            *TypeStr;
1975   CHAR16            *LocalIPStr;
1976   CHAR16            *GatewayIPStr;
1977   CHAR16            *SubnetMaskStr;
1978   IPv4_DEVICE_PATH  *IPv4;
1979 
1980   RemoteIPStr           = GetNextParamStr (&TextDeviceNode);
1981   ProtocolStr           = GetNextParamStr (&TextDeviceNode);
1982   TypeStr               = GetNextParamStr (&TextDeviceNode);
1983   LocalIPStr            = GetNextParamStr (&TextDeviceNode);
1984   GatewayIPStr          = GetNextParamStr (&TextDeviceNode);
1985   SubnetMaskStr         = GetNextParamStr (&TextDeviceNode);
1986   IPv4                  = (IPv4_DEVICE_PATH *) CreateDeviceNode (
1987                                                  MESSAGING_DEVICE_PATH,
1988                                                  MSG_IPv4_DP,
1989                                                  (UINT16) sizeof (IPv4_DEVICE_PATH)
1990                                                  );
1991 
1992   StrToIpv4Address (RemoteIPStr, NULL, &IPv4->RemoteIpAddress, NULL);
1993   IPv4->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr);
1994   if (StrCmp (TypeStr, "Static") == 0) {
1995     IPv4->StaticIpAddress = TRUE;
1996   } else {
1997     IPv4->StaticIpAddress = FALSE;
1998   }
1999 
2000   StrToIpv4Address (LocalIPStr, NULL, &IPv4->LocalIpAddress, NULL);
2001   if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*SubnetMaskStr)) {
2002     StrToIpv4Address (GatewayIPStr,  NULL, &IPv4->GatewayIpAddress, NULL);
2003     StrToIpv4Address (SubnetMaskStr, NULL, &IPv4->SubnetMask,       NULL);
2004   } else {
2005     ZeroMem (&IPv4->GatewayIpAddress, sizeof (IPv4->GatewayIpAddress));
2006     ZeroMem (&IPv4->SubnetMask,    sizeof (IPv4->SubnetMask));
2007   }
2008 
2009   IPv4->LocalPort       = 0;
2010   IPv4->RemotePort      = 0;
2011 
2012   return (EFI_DEVICE_PATH_PROTOCOL *) IPv4;
2013 }
2014 
2015 /**
2016   Converts a text device path node to IPV6 device path structure.
2017 
2018   @param TextDeviceNode  The input Text device path node.
2019 
2020   @return A pointer to the newly-created IPV6 device path structure.
2021 
2022 **/
2023 static
2024 EFI_DEVICE_PATH_PROTOCOL *
2025 DevPathFromTextIPv6 (
2026   IN CHAR16 *TextDeviceNode
2027   )
2028 {
2029   CHAR16            *RemoteIPStr;
2030   CHAR16            *ProtocolStr;
2031   CHAR16            *TypeStr;
2032   CHAR16            *LocalIPStr;
2033   CHAR16            *GatewayIPStr;
2034   CHAR16            *PrefixLengthStr;
2035   IPv6_DEVICE_PATH  *IPv6;
2036 
2037   RemoteIPStr           = GetNextParamStr (&TextDeviceNode);
2038   ProtocolStr           = GetNextParamStr (&TextDeviceNode);
2039   TypeStr               = GetNextParamStr (&TextDeviceNode);
2040   LocalIPStr            = GetNextParamStr (&TextDeviceNode);
2041   PrefixLengthStr       = GetNextParamStr (&TextDeviceNode);
2042   GatewayIPStr          = GetNextParamStr (&TextDeviceNode);
2043   IPv6                  = (IPv6_DEVICE_PATH *) CreateDeviceNode (
2044                                                  MESSAGING_DEVICE_PATH,
2045                                                  MSG_IPv6_DP,
2046                                                  (UINT16) sizeof (IPv6_DEVICE_PATH)
2047                                                  );
2048 
2049   StrToIpv6Address (RemoteIPStr, NULL, &IPv6->RemoteIpAddress, NULL);
2050   IPv6->Protocol        = (UINT16) NetworkProtocolFromText (ProtocolStr);
2051   if (StrCmp (TypeStr, "Static") == 0) {
2052     IPv6->IpAddressOrigin = 0;
2053   } else if (StrCmp (TypeStr, "StatelessAutoConfigure") == 0) {
2054     IPv6->IpAddressOrigin = 1;
2055   } else {
2056     IPv6->IpAddressOrigin = 2;
2057   }
2058 
2059   StrToIpv6Address (LocalIPStr, NULL, &IPv6->LocalIpAddress, NULL);
2060   if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*PrefixLengthStr)) {
2061     StrToIpv6Address (GatewayIPStr, NULL, &IPv6->GatewayIpAddress, NULL);
2062     IPv6->PrefixLength = (UINT8) Strtoi (PrefixLengthStr);
2063   } else {
2064     ZeroMem (&IPv6->GatewayIpAddress, sizeof (IPv6->GatewayIpAddress));
2065     IPv6->PrefixLength = 0;
2066   }
2067 
2068   IPv6->LocalPort       = 0;
2069   IPv6->RemotePort      = 0;
2070 
2071   return (EFI_DEVICE_PATH_PROTOCOL *) IPv6;
2072 }
2073 
2074 /**
2075   Converts a text device path node to UART device path structure.
2076 
2077   @param TextDeviceNode  The input Text device path node.
2078 
2079   @return A pointer to the newly-created UART device path structure.
2080 
2081 **/
2082 static
2083 EFI_DEVICE_PATH_PROTOCOL *
2084 DevPathFromTextUart (
2085   IN CHAR16 *TextDeviceNode
2086   )
2087 {
2088   CHAR16            *BaudStr;
2089   CHAR16            *DataBitsStr;
2090   CHAR16            *ParityStr;
2091   CHAR16            *StopBitsStr;
2092   UART_DEVICE_PATH  *Uart;
2093 
2094   BaudStr         = GetNextParamStr (&TextDeviceNode);
2095   DataBitsStr     = GetNextParamStr (&TextDeviceNode);
2096   ParityStr       = GetNextParamStr (&TextDeviceNode);
2097   StopBitsStr     = GetNextParamStr (&TextDeviceNode);
2098   Uart            = (UART_DEVICE_PATH *) CreateDeviceNode (
2099                                            MESSAGING_DEVICE_PATH,
2100                                            MSG_UART_DP,
2101                                            (UINT16) sizeof (UART_DEVICE_PATH)
2102                                            );
2103 
2104   if (StrCmp (BaudStr, "DEFAULT") == 0) {
2105     Uart->BaudRate = 115200;
2106   } else {
2107     Strtoi64 (BaudStr, &Uart->BaudRate);
2108   }
2109   Uart->DataBits  = (UINT8) ((StrCmp (DataBitsStr, "DEFAULT") == 0) ? 8 : Strtoi (DataBitsStr));
2110   switch (*ParityStr) {
2111   case 'D':
2112     Uart->Parity = 0;
2113     break;
2114 
2115   case 'N':
2116     Uart->Parity = 1;
2117     break;
2118 
2119   case 'E':
2120     Uart->Parity = 2;
2121     break;
2122 
2123   case 'O':
2124     Uart->Parity = 3;
2125     break;
2126 
2127   case 'M':
2128     Uart->Parity = 4;
2129     break;
2130 
2131   case 'S':
2132     Uart->Parity = 5;
2133     break;
2134 
2135   default:
2136     Uart->Parity = (UINT8) Strtoi (ParityStr);
2137     break;
2138   }
2139 
2140   if (StrCmp (StopBitsStr, "D") == 0) {
2141     Uart->StopBits = (UINT8) 0;
2142   } else if (StrCmp (StopBitsStr, "1") == 0) {
2143     Uart->StopBits = (UINT8) 1;
2144   } else if (StrCmp (StopBitsStr, "1.5") == 0) {
2145     Uart->StopBits = (UINT8) 2;
2146   } else if (StrCmp (StopBitsStr, "2") == 0) {
2147     Uart->StopBits = (UINT8) 3;
2148   } else {
2149     Uart->StopBits = (UINT8) Strtoi (StopBitsStr);
2150   }
2151 
2152   return (EFI_DEVICE_PATH_PROTOCOL *) Uart;
2153 }
2154 
2155 /**
2156   Converts a text device path node to USB class device path structure.
2157 
2158   @param TextDeviceNode  The input Text device path node.
2159   @param UsbClassText    A pointer to USB_CLASS_TEXT structure to be integrated to USB Class Text.
2160 
2161   @return A pointer to the newly-created USB class device path structure.
2162 
2163 **/
2164 static
2165 EFI_DEVICE_PATH_PROTOCOL *
2166 ConvertFromTextUsbClass (
2167   IN CHAR16         *TextDeviceNode,
2168   IN USB_CLASS_TEXT *UsbClassText
2169   )
2170 {
2171   CHAR16                *VIDStr;
2172   CHAR16                *PIDStr;
2173   CHAR16                *ClassStr;
2174   CHAR16                *SubClassStr;
2175   CHAR16                *ProtocolStr;
2176   USB_CLASS_DEVICE_PATH *UsbClass;
2177 
2178   UsbClass    = (USB_CLASS_DEVICE_PATH *) CreateDeviceNode (
2179                                             MESSAGING_DEVICE_PATH,
2180                                             MSG_USB_CLASS_DP,
2181                                             (UINT16) sizeof (USB_CLASS_DEVICE_PATH)
2182                                             );
2183 
2184   VIDStr      = GetNextParamStr (&TextDeviceNode);
2185   PIDStr      = GetNextParamStr (&TextDeviceNode);
2186   if (UsbClassText->ClassExist) {
2187     ClassStr = GetNextParamStr (&TextDeviceNode);
2188     if (*ClassStr == '\0') {
2189       UsbClass->DeviceClass = 0xFF;
2190     } else {
2191       UsbClass->DeviceClass = (UINT8) Strtoi (ClassStr);
2192     }
2193   } else {
2194     UsbClass->DeviceClass = UsbClassText->Class;
2195   }
2196   if (UsbClassText->SubClassExist) {
2197     SubClassStr = GetNextParamStr (&TextDeviceNode);
2198     if (*SubClassStr == '\0') {
2199       UsbClass->DeviceSubClass = 0xFF;
2200     } else {
2201       UsbClass->DeviceSubClass = (UINT8) Strtoi (SubClassStr);
2202     }
2203   } else {
2204     UsbClass->DeviceSubClass = UsbClassText->SubClass;
2205   }
2206 
2207   ProtocolStr = GetNextParamStr (&TextDeviceNode);
2208 
2209   if (*VIDStr == '\0') {
2210     UsbClass->VendorId        = 0xFFFF;
2211   } else {
2212     UsbClass->VendorId        = (UINT16) Strtoi (VIDStr);
2213   }
2214   if (*PIDStr == '\0') {
2215     UsbClass->ProductId       = 0xFFFF;
2216   } else {
2217     UsbClass->ProductId       = (UINT16) Strtoi (PIDStr);
2218   }
2219   if (*ProtocolStr == '\0') {
2220     UsbClass->DeviceProtocol  = 0xFF;
2221   } else {
2222     UsbClass->DeviceProtocol  = (UINT8) Strtoi (ProtocolStr);
2223   }
2224 
2225   return (EFI_DEVICE_PATH_PROTOCOL *) UsbClass;
2226 }
2227 
2228 
2229 /**
2230   Converts a text device path node to USB class device path structure.
2231 
2232   @param TextDeviceNode  The input Text device path node.
2233 
2234   @return A pointer to the newly-created USB class device path structure.
2235 
2236 **/
2237 static
2238 EFI_DEVICE_PATH_PROTOCOL *
2239 DevPathFromTextUsbClass (
2240   IN CHAR16 *TextDeviceNode
2241   )
2242 {
2243   USB_CLASS_TEXT  UsbClassText;
2244 
2245   UsbClassText.ClassExist    = TRUE;
2246   UsbClassText.SubClassExist = TRUE;
2247 
2248   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2249 }
2250 
2251 /**
2252   Converts a text device path node to USB audio device path structure.
2253 
2254   @param TextDeviceNode  The input Text device path node.
2255 
2256   @return A pointer to the newly-created USB audio device path structure.
2257 
2258 **/
2259 static
2260 EFI_DEVICE_PATH_PROTOCOL *
2261 DevPathFromTextUsbAudio (
2262   IN CHAR16 *TextDeviceNode
2263   )
2264 {
2265   USB_CLASS_TEXT  UsbClassText;
2266 
2267   UsbClassText.ClassExist    = FALSE;
2268   UsbClassText.Class         = USB_CLASS_AUDIO;
2269   UsbClassText.SubClassExist = TRUE;
2270 
2271   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2272 }
2273 
2274 /**
2275   Converts a text device path node to USB CDC Control device path structure.
2276 
2277   @param TextDeviceNode  The input Text device path node.
2278 
2279   @return A pointer to the newly-created USB CDC Control device path structure.
2280 
2281 **/
2282 static
2283 EFI_DEVICE_PATH_PROTOCOL *
2284 DevPathFromTextUsbCDCControl (
2285   IN CHAR16 *TextDeviceNode
2286   )
2287 {
2288   USB_CLASS_TEXT  UsbClassText;
2289 
2290   UsbClassText.ClassExist    = FALSE;
2291   UsbClassText.Class         = USB_CLASS_CDCCONTROL;
2292   UsbClassText.SubClassExist = TRUE;
2293 
2294   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2295 }
2296 
2297 /**
2298   Converts a text device path node to USB HID device path structure.
2299 
2300   @param TextDeviceNode  The input Text device path node.
2301 
2302   @return A pointer to the newly-created USB HID device path structure.
2303 
2304 **/
2305 static
2306 EFI_DEVICE_PATH_PROTOCOL *
2307 DevPathFromTextUsbHID (
2308   IN CHAR16 *TextDeviceNode
2309   )
2310 {
2311   USB_CLASS_TEXT  UsbClassText;
2312 
2313   UsbClassText.ClassExist    = FALSE;
2314   UsbClassText.Class         = USB_CLASS_HID;
2315   UsbClassText.SubClassExist = TRUE;
2316 
2317   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2318 }
2319 
2320 /**
2321   Converts a text device path node to USB Image device path structure.
2322 
2323   @param TextDeviceNode  The input Text device path node.
2324 
2325   @return A pointer to the newly-created USB Image device path structure.
2326 
2327 **/
2328 static
2329 EFI_DEVICE_PATH_PROTOCOL *
2330 DevPathFromTextUsbImage (
2331   IN CHAR16 *TextDeviceNode
2332   )
2333 {
2334   USB_CLASS_TEXT  UsbClassText;
2335 
2336   UsbClassText.ClassExist    = FALSE;
2337   UsbClassText.Class         = USB_CLASS_IMAGE;
2338   UsbClassText.SubClassExist = TRUE;
2339 
2340   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2341 }
2342 
2343 /**
2344   Converts a text device path node to USB Print device path structure.
2345 
2346   @param TextDeviceNode  The input Text device path node.
2347 
2348   @return A pointer to the newly-created USB Print device path structure.
2349 
2350 **/
2351 static
2352 EFI_DEVICE_PATH_PROTOCOL *
2353 DevPathFromTextUsbPrinter (
2354   IN CHAR16 *TextDeviceNode
2355   )
2356 {
2357   USB_CLASS_TEXT  UsbClassText;
2358 
2359   UsbClassText.ClassExist    = FALSE;
2360   UsbClassText.Class         = USB_CLASS_PRINTER;
2361   UsbClassText.SubClassExist = TRUE;
2362 
2363   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2364 }
2365 
2366 /**
2367   Converts a text device path node to USB mass storage device path structure.
2368 
2369   @param TextDeviceNode  The input Text device path node.
2370 
2371   @return A pointer to the newly-created USB mass storage device path structure.
2372 
2373 **/
2374 static
2375 EFI_DEVICE_PATH_PROTOCOL *
2376 DevPathFromTextUsbMassStorage (
2377   IN CHAR16 *TextDeviceNode
2378   )
2379 {
2380   USB_CLASS_TEXT  UsbClassText;
2381 
2382   UsbClassText.ClassExist    = FALSE;
2383   UsbClassText.Class         = USB_CLASS_MASS_STORAGE;
2384   UsbClassText.SubClassExist = TRUE;
2385 
2386   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2387 }
2388 
2389 /**
2390   Converts a text device path node to USB HUB device path structure.
2391 
2392   @param TextDeviceNode  The input Text device path node.
2393 
2394   @return A pointer to the newly-created USB HUB device path structure.
2395 
2396 **/
2397 static
2398 EFI_DEVICE_PATH_PROTOCOL *
2399 DevPathFromTextUsbHub (
2400   IN CHAR16 *TextDeviceNode
2401   )
2402 {
2403   USB_CLASS_TEXT  UsbClassText;
2404 
2405   UsbClassText.ClassExist    = FALSE;
2406   UsbClassText.Class         = USB_CLASS_HUB;
2407   UsbClassText.SubClassExist = TRUE;
2408 
2409   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2410 }
2411 
2412 /**
2413   Converts a text device path node to USB CDC data device path structure.
2414 
2415   @param TextDeviceNode  The input Text device path node.
2416 
2417   @return A pointer to the newly-created USB CDC data device path structure.
2418 
2419 **/
2420 static
2421 EFI_DEVICE_PATH_PROTOCOL *
2422 DevPathFromTextUsbCDCData (
2423   IN CHAR16 *TextDeviceNode
2424   )
2425 {
2426   USB_CLASS_TEXT  UsbClassText;
2427 
2428   UsbClassText.ClassExist    = FALSE;
2429   UsbClassText.Class         = USB_CLASS_CDCDATA;
2430   UsbClassText.SubClassExist = TRUE;
2431 
2432   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2433 }
2434 
2435 /**
2436   Converts a text device path node to USB smart card device path structure.
2437 
2438   @param TextDeviceNode  The input Text device path node.
2439 
2440   @return A pointer to the newly-created USB smart card device path structure.
2441 
2442 **/
2443 static
2444 EFI_DEVICE_PATH_PROTOCOL *
2445 DevPathFromTextUsbSmartCard (
2446   IN CHAR16 *TextDeviceNode
2447   )
2448 {
2449   USB_CLASS_TEXT  UsbClassText;
2450 
2451   UsbClassText.ClassExist    = FALSE;
2452   UsbClassText.Class         = USB_CLASS_SMART_CARD;
2453   UsbClassText.SubClassExist = TRUE;
2454 
2455   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2456 }
2457 
2458 /**
2459   Converts a text device path node to USB video device path structure.
2460 
2461   @param TextDeviceNode  The input Text device path node.
2462 
2463   @return A pointer to the newly-created USB video device path structure.
2464 
2465 **/
2466 static
2467 EFI_DEVICE_PATH_PROTOCOL *
2468 DevPathFromTextUsbVideo (
2469   IN CHAR16 *TextDeviceNode
2470   )
2471 {
2472   USB_CLASS_TEXT  UsbClassText;
2473 
2474   UsbClassText.ClassExist    = FALSE;
2475   UsbClassText.Class         = USB_CLASS_VIDEO;
2476   UsbClassText.SubClassExist = TRUE;
2477 
2478   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2479 }
2480 
2481 /**
2482   Converts a text device path node to USB diagnostic device path structure.
2483 
2484   @param TextDeviceNode  The input Text device path node.
2485 
2486   @return A pointer to the newly-created USB diagnostic device path structure.
2487 
2488 **/
2489 static
2490 EFI_DEVICE_PATH_PROTOCOL *
2491 DevPathFromTextUsbDiagnostic (
2492   IN CHAR16 *TextDeviceNode
2493   )
2494 {
2495   USB_CLASS_TEXT  UsbClassText;
2496 
2497   UsbClassText.ClassExist    = FALSE;
2498   UsbClassText.Class         = USB_CLASS_DIAGNOSTIC;
2499   UsbClassText.SubClassExist = TRUE;
2500 
2501   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2502 }
2503 
2504 /**
2505   Converts a text device path node to USB wireless device path structure.
2506 
2507   @param TextDeviceNode  The input Text device path node.
2508 
2509   @return A pointer to the newly-created USB wireless device path structure.
2510 
2511 **/
2512 static
2513 EFI_DEVICE_PATH_PROTOCOL *
2514 DevPathFromTextUsbWireless (
2515   IN CHAR16 *TextDeviceNode
2516   )
2517 {
2518   USB_CLASS_TEXT  UsbClassText;
2519 
2520   UsbClassText.ClassExist    = FALSE;
2521   UsbClassText.Class         = USB_CLASS_WIRELESS;
2522   UsbClassText.SubClassExist = TRUE;
2523 
2524   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2525 }
2526 
2527 /**
2528   Converts a text device path node to USB device firmware update device path structure.
2529 
2530   @param TextDeviceNode  The input Text device path node.
2531 
2532   @return A pointer to the newly-created USB device firmware update device path structure.
2533 
2534 **/
2535 static
2536 EFI_DEVICE_PATH_PROTOCOL *
2537 DevPathFromTextUsbDeviceFirmwareUpdate (
2538   IN CHAR16 *TextDeviceNode
2539   )
2540 {
2541   USB_CLASS_TEXT  UsbClassText;
2542 
2543   UsbClassText.ClassExist    = FALSE;
2544   UsbClassText.Class         = USB_CLASS_RESERVE;
2545   UsbClassText.SubClassExist = FALSE;
2546   UsbClassText.SubClass      = USB_SUBCLASS_FW_UPDATE;
2547 
2548   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2549 }
2550 
2551 /**
2552   Converts a text device path node to USB IRDA bridge device path structure.
2553 
2554   @param TextDeviceNode  The input Text device path node.
2555 
2556   @return A pointer to the newly-created USB IRDA bridge device path structure.
2557 
2558 **/
2559 static
2560 EFI_DEVICE_PATH_PROTOCOL *
2561 DevPathFromTextUsbIrdaBridge (
2562   IN CHAR16 *TextDeviceNode
2563   )
2564 {
2565   USB_CLASS_TEXT  UsbClassText;
2566 
2567   UsbClassText.ClassExist    = FALSE;
2568   UsbClassText.Class         = USB_CLASS_RESERVE;
2569   UsbClassText.SubClassExist = FALSE;
2570   UsbClassText.SubClass      = USB_SUBCLASS_IRDA_BRIDGE;
2571 
2572   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2573 }
2574 
2575 /**
2576   Converts a text device path node to USB text and measurement device path structure.
2577 
2578   @param TextDeviceNode  The input Text device path node.
2579 
2580   @return A pointer to the newly-created USB text and measurement device path structure.
2581 
2582 **/
2583 static
2584 EFI_DEVICE_PATH_PROTOCOL *
2585 DevPathFromTextUsbTestAndMeasurement (
2586   IN CHAR16 *TextDeviceNode
2587   )
2588 {
2589   USB_CLASS_TEXT  UsbClassText;
2590 
2591   UsbClassText.ClassExist    = FALSE;
2592   UsbClassText.Class         = USB_CLASS_RESERVE;
2593   UsbClassText.SubClassExist = FALSE;
2594   UsbClassText.SubClass      = USB_SUBCLASS_TEST;
2595 
2596   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2597 }
2598 
2599 /**
2600   Converts a text device path node to USB WWID device path structure.
2601 
2602   @param TextDeviceNode  The input Text device path node.
2603 
2604   @return A pointer to the newly-created USB WWID device path structure.
2605 
2606 **/
2607 static
2608 EFI_DEVICE_PATH_PROTOCOL *
2609 DevPathFromTextUsbWwid (
2610   IN CHAR16 *TextDeviceNode
2611   )
2612 {
2613   CHAR16                *VIDStr;
2614   CHAR16                *PIDStr;
2615   CHAR16                *InterfaceNumStr;
2616   CHAR16                *SerialNumberStr;
2617   USB_WWID_DEVICE_PATH  *UsbWwid;
2618   UINTN                 SerialNumberStrLen;
2619 
2620   VIDStr                   = GetNextParamStr (&TextDeviceNode);
2621   PIDStr                   = GetNextParamStr (&TextDeviceNode);
2622   InterfaceNumStr          = GetNextParamStr (&TextDeviceNode);
2623   SerialNumberStr          = GetNextParamStr (&TextDeviceNode);
2624   SerialNumberStrLen       = StrLen (SerialNumberStr);
2625   if (SerialNumberStrLen >= 2 &&
2626       SerialNumberStr[0] == '\"' &&
2627       SerialNumberStr[SerialNumberStrLen - 1] == '\"'
2628     ) {
2629     SerialNumberStr[SerialNumberStrLen - 1] = '\0';
2630     SerialNumberStr++;
2631     SerialNumberStrLen -= 2;
2632   }
2633   UsbWwid                  = (USB_WWID_DEVICE_PATH *) CreateDeviceNode (
2634                                                          MESSAGING_DEVICE_PATH,
2635                                                          MSG_USB_WWID_DP,
2636                                                          (UINT16) (sizeof (USB_WWID_DEVICE_PATH) + SerialNumberStrLen * sizeof (CHAR16))
2637                                                          );
2638   UsbWwid->VendorId        = (UINT16) Strtoi (VIDStr);
2639   UsbWwid->ProductId       = (UINT16) Strtoi (PIDStr);
2640   UsbWwid->InterfaceNumber = (UINT16) Strtoi (InterfaceNumStr);
2641 
2642   //
2643   // There is no memory allocated in UsbWwid for the '\0' in SerialNumberStr.
2644   // Therefore, the '\0' will not be copied.
2645   //
2646   CopyMem (
2647     (UINT8 *) UsbWwid + sizeof (USB_WWID_DEVICE_PATH),
2648     SerialNumberStr,
2649     SerialNumberStrLen * sizeof (CHAR16)
2650     );
2651 
2652   return (EFI_DEVICE_PATH_PROTOCOL *) UsbWwid;
2653 }
2654 
2655 /**
2656   Converts a text device path node to Logic Unit device path structure.
2657 
2658   @param TextDeviceNode  The input Text device path node.
2659 
2660   @return A pointer to the newly-created Logic Unit device path structure.
2661 
2662 **/
2663 static
2664 EFI_DEVICE_PATH_PROTOCOL *
2665 DevPathFromTextUnit (
2666   IN CHAR16 *TextDeviceNode
2667   )
2668 {
2669   CHAR16                          *LunStr;
2670   DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
2671 
2672   LunStr      = GetNextParamStr (&TextDeviceNode);
2673   LogicalUnit = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *) CreateDeviceNode (
2674                                                       MESSAGING_DEVICE_PATH,
2675                                                       MSG_DEVICE_LOGICAL_UNIT_DP,
2676                                                       (UINT16) sizeof (DEVICE_LOGICAL_UNIT_DEVICE_PATH)
2677                                                       );
2678 
2679   LogicalUnit->Lun  = (UINT8) Strtoi (LunStr);
2680 
2681   return (EFI_DEVICE_PATH_PROTOCOL *) LogicalUnit;
2682 }
2683 
2684 /**
2685   Converts a text device path node to iSCSI device path structure.
2686 
2687   @param TextDeviceNode  The input Text device path node.
2688 
2689   @return A pointer to the newly-created iSCSI device path structure.
2690 
2691 **/
2692 static
2693 EFI_DEVICE_PATH_PROTOCOL *
2694 DevPathFromTextiSCSI (
2695   IN CHAR16 *TextDeviceNode
2696   )
2697 {
2698   UINT16                      Options;
2699   CHAR16                      *NameStr;
2700   CHAR16                      *PortalGroupStr;
2701   CHAR16                      *LunStr;
2702   CHAR16                      *HeaderDigestStr;
2703   CHAR16                      *DataDigestStr;
2704   CHAR16                      *AuthenticationStr;
2705   CHAR16                      *ProtocolStr;
2706   CHAR8                       *AsciiStr;
2707   ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath;
2708   UINT64                      Lun;
2709 
2710   NameStr           = GetNextParamStr (&TextDeviceNode);
2711   PortalGroupStr    = GetNextParamStr (&TextDeviceNode);
2712   LunStr            = GetNextParamStr (&TextDeviceNode);
2713   HeaderDigestStr   = GetNextParamStr (&TextDeviceNode);
2714   DataDigestStr     = GetNextParamStr (&TextDeviceNode);
2715   AuthenticationStr = GetNextParamStr (&TextDeviceNode);
2716   ProtocolStr       = GetNextParamStr (&TextDeviceNode);
2717   ISCSIDevPath      = (ISCSI_DEVICE_PATH_WITH_NAME *) CreateDeviceNode (
2718                                                         MESSAGING_DEVICE_PATH,
2719                                                         MSG_ISCSI_DP,
2720                                                         (UINT16) (sizeof (ISCSI_DEVICE_PATH_WITH_NAME) + StrLen (NameStr))
2721                                                         );
2722 
2723   AsciiStr = ISCSIDevPath->TargetName;
2724   StrToAscii (NameStr, &AsciiStr);
2725 
2726   ISCSIDevPath->TargetPortalGroupTag = (UINT16) Strtoi (PortalGroupStr);
2727   Strtoi64 (LunStr, &Lun);
2728   WriteUnaligned64 ((UINT64 *) &ISCSIDevPath->Lun, SwapBytes64 (Lun));
2729 
2730   Options = 0x0000;
2731   if (StrCmp (HeaderDigestStr, "CRC32C") == 0) {
2732     Options |= 0x0002;
2733   }
2734 
2735   if (StrCmp (DataDigestStr, "CRC32C") == 0) {
2736     Options |= 0x0008;
2737   }
2738 
2739   if (StrCmp (AuthenticationStr, "None") == 0) {
2740     Options |= 0x0800;
2741   }
2742 
2743   if (StrCmp (AuthenticationStr, "CHAP_UNI") == 0) {
2744     Options |= 0x1000;
2745   }
2746 
2747   ISCSIDevPath->LoginOption      = (UINT16) Options;
2748 
2749   if (IS_NULL (*ProtocolStr) || (StrCmp (ProtocolStr, "TCP") == 0)) {
2750     ISCSIDevPath->NetworkProtocol = 0;
2751   } else {
2752     //
2753     // Undefined and reserved.
2754     //
2755     ISCSIDevPath->NetworkProtocol = 1;
2756   }
2757 
2758   return (EFI_DEVICE_PATH_PROTOCOL *) ISCSIDevPath;
2759 }
2760 
2761 /**
2762   Converts a text device path node to VLAN device path structure.
2763 
2764   @param TextDeviceNode  The input Text device path node.
2765 
2766   @return A pointer to the newly-created VLAN device path structure.
2767 
2768 **/
2769 static
2770 EFI_DEVICE_PATH_PROTOCOL *
2771 DevPathFromTextVlan (
2772   IN CHAR16 *TextDeviceNode
2773   )
2774 {
2775   CHAR16            *VlanStr;
2776   VLAN_DEVICE_PATH  *Vlan;
2777 
2778   VlanStr = GetNextParamStr (&TextDeviceNode);
2779   Vlan    = (VLAN_DEVICE_PATH *) CreateDeviceNode (
2780                                    MESSAGING_DEVICE_PATH,
2781                                    MSG_VLAN_DP,
2782                                    (UINT16) sizeof (VLAN_DEVICE_PATH)
2783                                    );
2784 
2785   Vlan->VlanId = (UINT16) Strtoi (VlanStr);
2786 
2787   return (EFI_DEVICE_PATH_PROTOCOL *) Vlan;
2788 }
2789 
2790 /**
2791   Converts a text device path node to Bluetooth device path structure.
2792 
2793   @param TextDeviceNode  The input Text device path node.
2794 
2795   @return A pointer to the newly-created Bluetooth device path structure.
2796 
2797 **/
2798 static
2799 EFI_DEVICE_PATH_PROTOCOL *
2800 DevPathFromTextBluetooth (
2801   IN CHAR16 *TextDeviceNode
2802   )
2803 {
2804   CHAR16                  *BluetoothStr;
2805   BLUETOOTH_DEVICE_PATH   *BluetoothDp;
2806 
2807   BluetoothStr = GetNextParamStr (&TextDeviceNode);
2808   BluetoothDp  = (BLUETOOTH_DEVICE_PATH *) CreateDeviceNode (
2809                                              MESSAGING_DEVICE_PATH,
2810                                              MSG_BLUETOOTH_DP,
2811                                              (UINT16) sizeof (BLUETOOTH_DEVICE_PATH)
2812                                              );
2813   StrHexToBytes (
2814     BluetoothStr,
2815     sizeof (BLUETOOTH_ADDRESS) * 2,
2816     BluetoothDp->BD_ADDR.Address,
2817     sizeof (BLUETOOTH_ADDRESS)
2818     );
2819   return (EFI_DEVICE_PATH_PROTOCOL *) BluetoothDp;
2820 }
2821 
2822 /**
2823   Converts a text device path node to Wi-Fi device path structure.
2824 
2825   @param TextDeviceNode  The input Text device path node.
2826 
2827   @return A pointer to the newly-created Wi-Fi device path structure.
2828 
2829 **/
2830 static
2831 EFI_DEVICE_PATH_PROTOCOL *
2832 DevPathFromTextWiFi (
2833   IN CHAR16 *TextDeviceNode
2834   )
2835 {
2836   CHAR16                *SSIdStr;
2837   CHAR8                 AsciiStr[33];
2838   UINTN                 DataLen;
2839   WIFI_DEVICE_PATH      *WiFiDp;
2840 
2841   SSIdStr = GetNextParamStr (&TextDeviceNode);
2842   WiFiDp  = (WIFI_DEVICE_PATH *) CreateDeviceNode (
2843                                    MESSAGING_DEVICE_PATH,
2844                                    MSG_WIFI_DP,
2845                                    (UINT16) sizeof (WIFI_DEVICE_PATH)
2846                                    );
2847 
2848   if (NULL != SSIdStr) {
2849     DataLen = StrLen (SSIdStr);
2850     if (StrLen (SSIdStr) > 32) {
2851       SSIdStr[32] = '\0';
2852       DataLen     = 32;
2853     }
2854 
2855     UnicodeStrToAsciiStrS (SSIdStr, AsciiStr, sizeof (AsciiStr));
2856     CopyMem (WiFiDp->SSId, AsciiStr, DataLen);
2857   }
2858 
2859   return (EFI_DEVICE_PATH_PROTOCOL *) WiFiDp;
2860 }
2861 
2862 /**
2863   Converts a text device path node to Bluetooth LE device path structure.
2864 
2865   @param TextDeviceNode  The input Text device path node.
2866 
2867   @return A pointer to the newly-created Bluetooth LE device path structure.
2868 
2869 **/
2870 static
2871 EFI_DEVICE_PATH_PROTOCOL *
2872 DevPathFromTextBluetoothLE (
2873   IN CHAR16 *TextDeviceNode
2874   )
2875 {
2876   CHAR16                     *BluetoothLeAddrStr;
2877   CHAR16                     *BluetoothLeAddrTypeStr;
2878   BLUETOOTH_LE_DEVICE_PATH   *BluetoothLeDp;
2879 
2880   BluetoothLeAddrStr     = GetNextParamStr (&TextDeviceNode);
2881   BluetoothLeAddrTypeStr = GetNextParamStr (&TextDeviceNode);
2882   BluetoothLeDp = (BLUETOOTH_LE_DEVICE_PATH *) CreateDeviceNode (
2883                                                  MESSAGING_DEVICE_PATH,
2884                                                  MSG_BLUETOOTH_LE_DP,
2885                                                  (UINT16) sizeof (BLUETOOTH_LE_DEVICE_PATH)
2886                                                  );
2887 
2888   BluetoothLeDp->Address.Type = (UINT8) Strtoi (BluetoothLeAddrTypeStr);
2889   StrHexToBytes (
2890     BluetoothLeAddrStr, sizeof (BluetoothLeDp->Address.Address) * 2,
2891     BluetoothLeDp->Address.Address, sizeof (BluetoothLeDp->Address.Address)
2892     );
2893   return (EFI_DEVICE_PATH_PROTOCOL *) BluetoothLeDp;
2894 }
2895 
2896 /**
2897   Converts a text device path node to DNS device path structure.
2898 
2899   @param TextDeviceNode  The input Text device path node.
2900 
2901   @return A pointer to the newly-created DNS device path structure.
2902 
2903 **/
2904 static
2905 EFI_DEVICE_PATH_PROTOCOL *
2906 DevPathFromTextDns (
2907   IN CHAR16 *TextDeviceNode
2908   )
2909 {
2910   CHAR16            *DeviceNodeStr;
2911   CHAR16            *DeviceNodeStrPtr;
2912   UINT32            DnsServerIpCount;
2913   UINT16            DnsDeviceNodeLength;
2914   DNS_DEVICE_PATH   *DnsDeviceNode;
2915   UINT32            DnsServerIpIndex;
2916   CHAR16            *DnsServerIp;
2917 
2918 
2919   //
2920   // Count the DNS server address number.
2921   //
2922   DeviceNodeStr = UefiDevicePathLibStrDuplicate (TextDeviceNode);
2923   if (DeviceNodeStr == NULL) {
2924     return NULL;
2925   }
2926 
2927   DeviceNodeStrPtr = DeviceNodeStr;
2928 
2929   DnsServerIpCount = 0;
2930   while (DeviceNodeStrPtr != NULL && *DeviceNodeStrPtr != '\0') {
2931     GetNextParamStr (&DeviceNodeStrPtr);
2932     DnsServerIpCount ++;
2933   }
2934 
2935   FreePool (DeviceNodeStr);
2936   DeviceNodeStr = NULL;
2937 
2938   //
2939   // One or more instances of the DNS server address in EFI_IP_ADDRESS,
2940   // otherwise, NULL will be returned.
2941   //
2942   if (DnsServerIpCount == 0) {
2943     return NULL;
2944   }
2945 
2946   //
2947   // Create the DNS DeviceNode.
2948   //
2949   DnsDeviceNodeLength = (UINT16) (sizeof (EFI_DEVICE_PATH_PROTOCOL) + sizeof (UINT8) + DnsServerIpCount * sizeof (EFI_IP_ADDRESS));
2950   DnsDeviceNode       = (DNS_DEVICE_PATH *) CreateDeviceNode (
2951                                               MESSAGING_DEVICE_PATH,
2952                                               MSG_DNS_DP,
2953                                               DnsDeviceNodeLength
2954                                               );
2955   if (DnsDeviceNode == NULL) {
2956     return NULL;
2957   }
2958 
2959   //
2960   // Confirm the DNS server address is IPv4 or IPv6 type.
2961   //
2962   DeviceNodeStrPtr = TextDeviceNode;
2963   while (!IS_NULL (*DeviceNodeStrPtr)) {
2964     if (*DeviceNodeStrPtr == '.') {
2965       DnsDeviceNode->IsIPv6 = 0x00;
2966       break;
2967     }
2968 
2969     if (*DeviceNodeStrPtr == ':') {
2970       DnsDeviceNode->IsIPv6 = 0x01;
2971       break;
2972     }
2973 
2974     DeviceNodeStrPtr++;
2975   }
2976 
2977   for (DnsServerIpIndex = 0; DnsServerIpIndex < DnsServerIpCount; DnsServerIpIndex++) {
2978     DnsServerIp = GetNextParamStr (&TextDeviceNode);
2979     if (DnsDeviceNode->IsIPv6 == 0x00) {
2980       StrToIpv4Address (DnsServerIp,  NULL, &(DnsDeviceNode->DnsServerIp[DnsServerIpIndex].v4), NULL);
2981     } else {
2982       StrToIpv6Address (DnsServerIp, NULL, &(DnsDeviceNode->DnsServerIp[DnsServerIpIndex].v6), NULL);
2983     }
2984   }
2985 
2986   return (EFI_DEVICE_PATH_PROTOCOL *) DnsDeviceNode;
2987 }
2988 
2989 /**
2990   Converts a text device path node to URI device path structure.
2991 
2992   @param TextDeviceNode  The input Text device path node.
2993 
2994   @return A pointer to the newly-created URI device path structure.
2995 
2996 **/
2997 static
2998 EFI_DEVICE_PATH_PROTOCOL *
2999 DevPathFromTextUri (
3000   IN CHAR16 *TextDeviceNode
3001   )
3002 {
3003   CHAR16           *UriStr;
3004   UINTN            UriLength;
3005   URI_DEVICE_PATH  *Uri;
3006 
3007   UriStr = GetNextParamStr (&TextDeviceNode);
3008   UriLength = StrnLenS (UriStr, MAX_UINT16 - sizeof (URI_DEVICE_PATH));
3009   Uri    = (URI_DEVICE_PATH *) CreateDeviceNode (
3010                                  MESSAGING_DEVICE_PATH,
3011                                  MSG_URI_DP,
3012                                  (UINT16) (sizeof (URI_DEVICE_PATH) + UriLength)
3013                                  );
3014 
3015   while (UriLength-- != 0) {
3016     Uri->Uri[UriLength] = (CHAR8) UriStr[UriLength];
3017   }
3018 
3019   return (EFI_DEVICE_PATH_PROTOCOL *) Uri;
3020 }
3021 
3022 /**
3023   Converts a media text device path node to media device path structure.
3024 
3025   @param TextDeviceNode  The input Text device path node.
3026 
3027   @return A pointer to media device path structure.
3028 
3029 **/
3030 static
3031 EFI_DEVICE_PATH_PROTOCOL *
3032 DevPathFromTextMediaPath (
3033   IN CHAR16 *TextDeviceNode
3034   )
3035 {
3036   return DevPathFromTextGenericPath (MEDIA_DEVICE_PATH, TextDeviceNode);
3037 }
3038 
3039 /**
3040   Converts a text device path node to HD device path structure.
3041 
3042   @param TextDeviceNode  The input Text device path node.
3043 
3044   @return A pointer to the newly-created HD device path structure.
3045 
3046 **/
3047 static
3048 EFI_DEVICE_PATH_PROTOCOL *
3049 DevPathFromTextHD (
3050   IN CHAR16 *TextDeviceNode
3051   )
3052 {
3053   CHAR16                *PartitionStr;
3054   CHAR16                *TypeStr;
3055   CHAR16                *SignatureStr;
3056   CHAR16                *StartStr;
3057   CHAR16                *SizeStr;
3058   UINT32                Signature32;
3059   HARDDRIVE_DEVICE_PATH *Hd;
3060 
3061   PartitionStr        = GetNextParamStr (&TextDeviceNode);
3062   TypeStr             = GetNextParamStr (&TextDeviceNode);
3063   SignatureStr        = GetNextParamStr (&TextDeviceNode);
3064   StartStr            = GetNextParamStr (&TextDeviceNode);
3065   SizeStr             = GetNextParamStr (&TextDeviceNode);
3066   Hd                  = (HARDDRIVE_DEVICE_PATH *) CreateDeviceNode (
3067                                                     MEDIA_DEVICE_PATH,
3068                                                     MEDIA_HARDDRIVE_DP,
3069                                                     (UINT16) sizeof (HARDDRIVE_DEVICE_PATH)
3070                                                     );
3071 
3072   Hd->PartitionNumber = (UINT32) Strtoi (PartitionStr);
3073 
3074   ZeroMem (Hd->Signature, 16);
3075   Hd->MBRType = (UINT8) 0;
3076 
3077   if (StrCmp (TypeStr, "MBR") == 0) {
3078     Hd->SignatureType = SIGNATURE_TYPE_MBR;
3079     Hd->MBRType       = 0x01;
3080 
3081     Signature32       = (UINT32) Strtoi (SignatureStr);
3082     CopyMem (Hd->Signature, &Signature32, sizeof (UINT32));
3083   } else if (StrCmp (TypeStr, "GPT") == 0) {
3084     Hd->SignatureType = SIGNATURE_TYPE_GUID;
3085     Hd->MBRType       = 0x02;
3086 
3087     StrToGuid (SignatureStr, (EFI_GUID *) Hd->Signature);
3088   } else {
3089     Hd->SignatureType = (UINT8) Strtoi (TypeStr);
3090   }
3091 
3092   Strtoi64 (StartStr, &Hd->PartitionStart);
3093   Strtoi64 (SizeStr, &Hd->PartitionSize);
3094 
3095   return (EFI_DEVICE_PATH_PROTOCOL *) Hd;
3096 }
3097 
3098 /**
3099   Converts a text device path node to CDROM device path structure.
3100 
3101   @param TextDeviceNode  The input Text device path node.
3102 
3103   @return A pointer to the newly-created CDROM device path structure.
3104 
3105 **/
3106 static
3107 EFI_DEVICE_PATH_PROTOCOL *
3108 DevPathFromTextCDROM (
3109   IN CHAR16 *TextDeviceNode
3110   )
3111 {
3112   CHAR16            *EntryStr;
3113   CHAR16            *StartStr;
3114   CHAR16            *SizeStr;
3115   CDROM_DEVICE_PATH *CDROMDevPath;
3116 
3117   EntryStr              = GetNextParamStr (&TextDeviceNode);
3118   StartStr              = GetNextParamStr (&TextDeviceNode);
3119   SizeStr               = GetNextParamStr (&TextDeviceNode);
3120   CDROMDevPath          = (CDROM_DEVICE_PATH *) CreateDeviceNode (
3121                                                   MEDIA_DEVICE_PATH,
3122                                                   MEDIA_CDROM_DP,
3123                                                   (UINT16) sizeof (CDROM_DEVICE_PATH)
3124                                                   );
3125 
3126   CDROMDevPath->BootEntry = (UINT32) Strtoi (EntryStr);
3127   Strtoi64 (StartStr, &CDROMDevPath->PartitionStart);
3128   Strtoi64 (SizeStr, &CDROMDevPath->PartitionSize);
3129 
3130   return (EFI_DEVICE_PATH_PROTOCOL *) CDROMDevPath;
3131 }
3132 
3133 /**
3134   Converts a text device path node to Vendor-defined media device path structure.
3135 
3136   @param TextDeviceNode  The input Text device path node.
3137 
3138   @return A pointer to the newly-created Vendor-defined media device path structure.
3139 
3140 **/
3141 static
3142 EFI_DEVICE_PATH_PROTOCOL *
3143 DevPathFromTextVenMedia (
3144   IN CHAR16 *TextDeviceNode
3145   )
3146 {
3147   return ConvertFromTextVendor (
3148            TextDeviceNode,
3149            MEDIA_DEVICE_PATH,
3150            MEDIA_VENDOR_DP
3151            );
3152 }
3153 
3154 /**
3155   Converts a text device path node to File device path structure.
3156 
3157   @param TextDeviceNode  The input Text device path node.
3158 
3159   @return A pointer to the newly-created File device path structure.
3160 
3161 **/
3162 static
3163 EFI_DEVICE_PATH_PROTOCOL *
3164 DevPathFromTextFilePath (
3165   IN CHAR16 *TextDeviceNode
3166   )
3167 {
3168   FILEPATH_DEVICE_PATH  *File;
3169 
3170 #ifndef __FreeBSD__
3171   File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode (
3172                                     MEDIA_DEVICE_PATH,
3173                                     MEDIA_FILEPATH_DP,
3174                                     (UINT16) (sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) * 2)
3175                                     );
3176 
3177   StrCpyS (File->PathName, StrLen (TextDeviceNode) + 1, TextDeviceNode);
3178 #else
3179   size_t len = (sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) * 2);
3180   efi_char * v;
3181   File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode (
3182                                     MEDIA_DEVICE_PATH,
3183                                     MEDIA_FILEPATH_DP,
3184 				    (UINT16)len
3185                                     );
3186   v = File->PathName;
3187   utf8_to_ucs2(TextDeviceNode, &v, &len);
3188 #endif
3189 
3190   return (EFI_DEVICE_PATH_PROTOCOL *) File;
3191 }
3192 
3193 /**
3194   Converts a text device path node to Media protocol device path structure.
3195 
3196   @param TextDeviceNode  The input Text device path node.
3197 
3198   @return A pointer to the newly-created Media protocol device path structure.
3199 
3200 **/
3201 static
3202 EFI_DEVICE_PATH_PROTOCOL *
3203 DevPathFromTextMedia (
3204   IN CHAR16 *TextDeviceNode
3205   )
3206 {
3207   CHAR16                      *GuidStr;
3208   MEDIA_PROTOCOL_DEVICE_PATH  *Media;
3209 
3210   GuidStr = GetNextParamStr (&TextDeviceNode);
3211   Media   = (MEDIA_PROTOCOL_DEVICE_PATH *) CreateDeviceNode (
3212                                              MEDIA_DEVICE_PATH,
3213                                              MEDIA_PROTOCOL_DP,
3214                                              (UINT16) sizeof (MEDIA_PROTOCOL_DEVICE_PATH)
3215                                              );
3216 
3217   StrToGuid (GuidStr, &Media->Protocol);
3218 
3219   return (EFI_DEVICE_PATH_PROTOCOL *) Media;
3220 }
3221 
3222 /**
3223   Converts a text device path node to firmware volume device path structure.
3224 
3225   @param TextDeviceNode  The input Text device path node.
3226 
3227   @return A pointer to the newly-created firmware volume device path structure.
3228 
3229 **/
3230 static
3231 EFI_DEVICE_PATH_PROTOCOL *
3232 DevPathFromTextFv (
3233   IN CHAR16 *TextDeviceNode
3234   )
3235 {
3236   CHAR16                    *GuidStr;
3237   MEDIA_FW_VOL_DEVICE_PATH  *Fv;
3238 
3239   GuidStr = GetNextParamStr (&TextDeviceNode);
3240   Fv      = (MEDIA_FW_VOL_DEVICE_PATH *) CreateDeviceNode (
3241                                            MEDIA_DEVICE_PATH,
3242                                            MEDIA_PIWG_FW_VOL_DP,
3243                                            (UINT16) sizeof (MEDIA_FW_VOL_DEVICE_PATH)
3244                                            );
3245 
3246   StrToGuid (GuidStr, &Fv->FvName);
3247 
3248   return (EFI_DEVICE_PATH_PROTOCOL *) Fv;
3249 }
3250 
3251 /**
3252   Converts a text device path node to firmware file device path structure.
3253 
3254   @param TextDeviceNode  The input Text device path node.
3255 
3256   @return A pointer to the newly-created firmware file device path structure.
3257 
3258 **/
3259 static
3260 EFI_DEVICE_PATH_PROTOCOL *
3261 DevPathFromTextFvFile (
3262   IN CHAR16 *TextDeviceNode
3263   )
3264 {
3265   CHAR16                             *GuidStr;
3266   MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvFile;
3267 
3268   GuidStr = GetNextParamStr (&TextDeviceNode);
3269   FvFile  = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) CreateDeviceNode (
3270                                                     MEDIA_DEVICE_PATH,
3271                                                     MEDIA_PIWG_FW_FILE_DP,
3272                                                     (UINT16) sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH)
3273                                                     );
3274 
3275   StrToGuid (GuidStr, &FvFile->FvFileName);
3276 
3277   return (EFI_DEVICE_PATH_PROTOCOL *) FvFile;
3278 }
3279 
3280 /**
3281   Converts a text device path node to text relative offset device path structure.
3282 
3283   @param TextDeviceNode  The input Text device path node.
3284 
3285   @return A pointer to the newly-created Text device path structure.
3286 
3287 **/
3288 static
3289 EFI_DEVICE_PATH_PROTOCOL *
3290 DevPathFromTextRelativeOffsetRange (
3291   IN CHAR16 *TextDeviceNode
3292   )
3293 {
3294   CHAR16                                  *StartingOffsetStr;
3295   CHAR16                                  *EndingOffsetStr;
3296   MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
3297 
3298   StartingOffsetStr = GetNextParamStr (&TextDeviceNode);
3299   EndingOffsetStr   = GetNextParamStr (&TextDeviceNode);
3300   Offset            = (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *) CreateDeviceNode (
3301                                                                     MEDIA_DEVICE_PATH,
3302                                                                     MEDIA_RELATIVE_OFFSET_RANGE_DP,
3303                                                                     (UINT16) sizeof (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH)
3304                                                                     );
3305 
3306   Strtoi64 (StartingOffsetStr, &Offset->StartingOffset);
3307   Strtoi64 (EndingOffsetStr, &Offset->EndingOffset);
3308 
3309   return (EFI_DEVICE_PATH_PROTOCOL *) Offset;
3310 }
3311 
3312 /**
3313   Converts a text device path node to text ram disk device path structure.
3314 
3315   @param TextDeviceNode  The input Text device path node.
3316 
3317   @return A pointer to the newly-created Text device path structure.
3318 
3319 **/
3320 static
3321 EFI_DEVICE_PATH_PROTOCOL *
3322 DevPathFromTextRamDisk (
3323   IN CHAR16 *TextDeviceNode
3324   )
3325 {
3326   CHAR16                                  *StartingAddrStr;
3327   CHAR16                                  *EndingAddrStr;
3328   CHAR16                                  *TypeGuidStr;
3329   CHAR16                                  *InstanceStr;
3330   MEDIA_RAM_DISK_DEVICE_PATH              *RamDisk;
3331   UINT64                                  StartingAddr;
3332   UINT64                                  EndingAddr;
3333 
3334   StartingAddrStr = GetNextParamStr (&TextDeviceNode);
3335   EndingAddrStr   = GetNextParamStr (&TextDeviceNode);
3336   InstanceStr     = GetNextParamStr (&TextDeviceNode);
3337   TypeGuidStr     = GetNextParamStr (&TextDeviceNode);
3338   RamDisk         = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
3339                                                      MEDIA_DEVICE_PATH,
3340                                                      MEDIA_RAM_DISK_DP,
3341                                                      (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
3342                                                      );
3343 
3344   Strtoi64 (StartingAddrStr, &StartingAddr);
3345   WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
3346   Strtoi64 (EndingAddrStr, &EndingAddr);
3347   WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
3348   RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
3349   StrToGuid (TypeGuidStr, &RamDisk->TypeGuid);
3350 
3351   return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
3352 }
3353 
3354 /**
3355   Converts a text device path node to text virtual disk device path structure.
3356 
3357   @param TextDeviceNode  The input Text device path node.
3358 
3359   @return A pointer to the newly-created Text device path structure.
3360 
3361 **/
3362 static
3363 EFI_DEVICE_PATH_PROTOCOL *
3364 DevPathFromTextVirtualDisk (
3365   IN CHAR16 *TextDeviceNode
3366   )
3367 {
3368   CHAR16                                  *StartingAddrStr;
3369   CHAR16                                  *EndingAddrStr;
3370   CHAR16                                  *InstanceStr;
3371   MEDIA_RAM_DISK_DEVICE_PATH              *RamDisk;
3372   UINT64                                  StartingAddr;
3373   UINT64                                  EndingAddr;
3374 
3375   StartingAddrStr = GetNextParamStr (&TextDeviceNode);
3376   EndingAddrStr   = GetNextParamStr (&TextDeviceNode);
3377   InstanceStr     = GetNextParamStr (&TextDeviceNode);
3378 
3379   RamDisk         = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
3380                                                      MEDIA_DEVICE_PATH,
3381                                                      MEDIA_RAM_DISK_DP,
3382                                                      (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
3383                                                      );
3384 
3385   Strtoi64 (StartingAddrStr, &StartingAddr);
3386   WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
3387   Strtoi64 (EndingAddrStr, &EndingAddr);
3388   WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
3389   RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
3390   CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualDiskGuid);
3391 
3392   return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
3393 }
3394 
3395 /**
3396   Converts a text device path node to text virtual cd device path structure.
3397 
3398   @param TextDeviceNode  The input Text device path node.
3399 
3400   @return A pointer to the newly-created Text device path structure.
3401 
3402 **/
3403 static
3404 EFI_DEVICE_PATH_PROTOCOL *
3405 DevPathFromTextVirtualCd (
3406   IN CHAR16 *TextDeviceNode
3407   )
3408 {
3409   CHAR16                                  *StartingAddrStr;
3410   CHAR16                                  *EndingAddrStr;
3411   CHAR16                                  *InstanceStr;
3412   MEDIA_RAM_DISK_DEVICE_PATH              *RamDisk;
3413   UINT64                                  StartingAddr;
3414   UINT64                                  EndingAddr;
3415 
3416   StartingAddrStr = GetNextParamStr (&TextDeviceNode);
3417   EndingAddrStr   = GetNextParamStr (&TextDeviceNode);
3418   InstanceStr     = GetNextParamStr (&TextDeviceNode);
3419 
3420   RamDisk         = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
3421                                                      MEDIA_DEVICE_PATH,
3422                                                      MEDIA_RAM_DISK_DP,
3423                                                      (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
3424                                                      );
3425 
3426   Strtoi64 (StartingAddrStr, &StartingAddr);
3427   WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
3428   Strtoi64 (EndingAddrStr, &EndingAddr);
3429   WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
3430   RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
3431   CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualCdGuid);
3432 
3433   return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
3434 }
3435 
3436 /**
3437   Converts a text device path node to text persistent virtual disk device path structure.
3438 
3439   @param TextDeviceNode  The input Text device path node.
3440 
3441   @return A pointer to the newly-created Text device path structure.
3442 
3443 **/
3444 static
3445 EFI_DEVICE_PATH_PROTOCOL *
3446 DevPathFromTextPersistentVirtualDisk (
3447   IN CHAR16 *TextDeviceNode
3448   )
3449 {
3450   CHAR16                                  *StartingAddrStr;
3451   CHAR16                                  *EndingAddrStr;
3452   CHAR16                                  *InstanceStr;
3453   MEDIA_RAM_DISK_DEVICE_PATH              *RamDisk;
3454   UINT64                                  StartingAddr;
3455   UINT64                                  EndingAddr;
3456 
3457   StartingAddrStr = GetNextParamStr (&TextDeviceNode);
3458   EndingAddrStr   = GetNextParamStr (&TextDeviceNode);
3459   InstanceStr     = GetNextParamStr (&TextDeviceNode);
3460 
3461   RamDisk         = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
3462                                                      MEDIA_DEVICE_PATH,
3463                                                      MEDIA_RAM_DISK_DP,
3464                                                      (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
3465                                                      );
3466 
3467   Strtoi64 (StartingAddrStr, &StartingAddr);
3468   WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
3469   Strtoi64 (EndingAddrStr, &EndingAddr);
3470   WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
3471   RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
3472   CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualDiskGuid);
3473 
3474   return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
3475 }
3476 
3477 /**
3478   Converts a text device path node to text persistent virtual cd device path structure.
3479 
3480   @param TextDeviceNode  The input Text device path node.
3481 
3482   @return A pointer to the newly-created Text device path structure.
3483 
3484 **/
3485 static
3486 EFI_DEVICE_PATH_PROTOCOL *
3487 DevPathFromTextPersistentVirtualCd (
3488   IN CHAR16 *TextDeviceNode
3489   )
3490 {
3491   CHAR16                                  *StartingAddrStr;
3492   CHAR16                                  *EndingAddrStr;
3493   CHAR16                                  *InstanceStr;
3494   MEDIA_RAM_DISK_DEVICE_PATH              *RamDisk;
3495   UINT64                                  StartingAddr;
3496   UINT64                                  EndingAddr;
3497 
3498   StartingAddrStr = GetNextParamStr (&TextDeviceNode);
3499   EndingAddrStr   = GetNextParamStr (&TextDeviceNode);
3500   InstanceStr     = GetNextParamStr (&TextDeviceNode);
3501 
3502   RamDisk         = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
3503                                                      MEDIA_DEVICE_PATH,
3504                                                      MEDIA_RAM_DISK_DP,
3505                                                      (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
3506                                                      );
3507 
3508   Strtoi64 (StartingAddrStr, &StartingAddr);
3509   WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
3510   Strtoi64 (EndingAddrStr, &EndingAddr);
3511   WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
3512   RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
3513   CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualCdGuid);
3514 
3515   return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
3516 }
3517 
3518 /**
3519   Converts a BBS text device path node to BBS device path structure.
3520 
3521   @param TextDeviceNode  The input Text device path node.
3522 
3523   @return A pointer to BBS device path structure.
3524 
3525 **/
3526 static
3527 EFI_DEVICE_PATH_PROTOCOL *
3528 DevPathFromTextBbsPath (
3529   IN CHAR16 *TextDeviceNode
3530   )
3531 {
3532   return DevPathFromTextGenericPath (BBS_DEVICE_PATH, TextDeviceNode);
3533 }
3534 
3535 /**
3536   Converts a text device path node to BIOS Boot Specification device path structure.
3537 
3538   @param TextDeviceNode  The input Text device path node.
3539 
3540   @return A pointer to the newly-created BIOS Boot Specification device path structure.
3541 
3542 **/
3543 static
3544 EFI_DEVICE_PATH_PROTOCOL *
3545 DevPathFromTextBBS (
3546   IN CHAR16 *TextDeviceNode
3547   )
3548 {
3549   CHAR16              *TypeStr;
3550   CHAR16              *IdStr;
3551   CHAR16              *FlagsStr;
3552   CHAR8               *AsciiStr;
3553   BBS_BBS_DEVICE_PATH *Bbs;
3554 
3555   TypeStr   = GetNextParamStr (&TextDeviceNode);
3556   IdStr     = GetNextParamStr (&TextDeviceNode);
3557   FlagsStr  = GetNextParamStr (&TextDeviceNode);
3558   Bbs       = (BBS_BBS_DEVICE_PATH *) CreateDeviceNode (
3559                                         BBS_DEVICE_PATH,
3560                                         BBS_BBS_DP,
3561                                         (UINT16) (sizeof (BBS_BBS_DEVICE_PATH) + StrLen (IdStr))
3562                                         );
3563 
3564   if (StrCmp (TypeStr, "Floppy") == 0) {
3565     Bbs->DeviceType = BBS_TYPE_FLOPPY;
3566   } else if (StrCmp (TypeStr, "HD") == 0) {
3567     Bbs->DeviceType = BBS_TYPE_HARDDRIVE;
3568   } else if (StrCmp (TypeStr, "CDROM") == 0) {
3569     Bbs->DeviceType = BBS_TYPE_CDROM;
3570   } else if (StrCmp (TypeStr, "PCMCIA") == 0) {
3571     Bbs->DeviceType = BBS_TYPE_PCMCIA;
3572   } else if (StrCmp (TypeStr, "USB") == 0) {
3573     Bbs->DeviceType = BBS_TYPE_USB;
3574   } else if (StrCmp (TypeStr, "Network") == 0) {
3575     Bbs->DeviceType = BBS_TYPE_EMBEDDED_NETWORK;
3576   } else {
3577     Bbs->DeviceType = (UINT16) Strtoi (TypeStr);
3578   }
3579 
3580   AsciiStr = Bbs->String;
3581   StrToAscii (IdStr, &AsciiStr);
3582 
3583   Bbs->StatusFlag = (UINT16) Strtoi (FlagsStr);
3584 
3585   return (EFI_DEVICE_PATH_PROTOCOL *) Bbs;
3586 }
3587 
3588 /**
3589   Converts a text device path node to SATA device path structure.
3590 
3591   @param TextDeviceNode  The input Text device path node.
3592 
3593   @return A pointer to the newly-created SATA device path structure.
3594 
3595 **/
3596 static
3597 EFI_DEVICE_PATH_PROTOCOL *
3598 DevPathFromTextSata (
3599   IN CHAR16 *TextDeviceNode
3600   )
3601 {
3602   SATA_DEVICE_PATH *Sata;
3603   CHAR16           *Param1;
3604   CHAR16           *Param2;
3605   CHAR16           *Param3;
3606 
3607   Param1 = GetNextParamStr (&TextDeviceNode);
3608   Param2 = GetNextParamStr (&TextDeviceNode);
3609   Param3 = GetNextParamStr (&TextDeviceNode);
3610 
3611   Sata = (SATA_DEVICE_PATH *) CreateDeviceNode (
3612                                 MESSAGING_DEVICE_PATH,
3613                                 MSG_SATA_DP,
3614                                 (UINT16) sizeof (SATA_DEVICE_PATH)
3615                                 );
3616   Sata->HBAPortNumber            = (UINT16) Strtoi (Param1);
3617 
3618   //
3619   // According to UEFI spec, if PMPN is not provided, the default is 0xFFFF
3620   //
3621   if (*Param2 == '\0' ) {
3622     Sata->PortMultiplierPortNumber = 0xFFFF;
3623   } else {
3624     Sata->PortMultiplierPortNumber = (UINT16) Strtoi (Param2);
3625   }
3626   Sata->Lun                      = (UINT16) Strtoi (Param3);
3627 
3628   return (EFI_DEVICE_PATH_PROTOCOL *) Sata;
3629 }
3630 
3631 GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_FROM_TEXT_TABLE mUefiDevicePathLibDevPathFromTextTable[] = {
3632   {"Path",                    DevPathFromTextPath                    },
3633 
3634   {"HardwarePath",            DevPathFromTextHardwarePath            },
3635   {"Pci",                     DevPathFromTextPci                     },
3636   {"PcCard",                  DevPathFromTextPcCard                  },
3637   {"MemoryMapped",            DevPathFromTextMemoryMapped            },
3638   {"VenHw",                   DevPathFromTextVenHw                   },
3639   {"Ctrl",                    DevPathFromTextCtrl                    },
3640   {"BMC",                     DevPathFromTextBmc                     },
3641 
3642   {"AcpiPath",                DevPathFromTextAcpiPath                },
3643   {"Acpi",                    DevPathFromTextAcpi                    },
3644   {"PciRoot",                 DevPathFromTextPciRoot                 },
3645   {"PcieRoot",                DevPathFromTextPcieRoot                },
3646   {"Floppy",                  DevPathFromTextFloppy                  },
3647   {"Keyboard",                DevPathFromTextKeyboard                },
3648   {"Serial",                  DevPathFromTextSerial                  },
3649   {"ParallelPort",            DevPathFromTextParallelPort            },
3650   {"AcpiEx",                  DevPathFromTextAcpiEx                  },
3651   {"AcpiExp",                 DevPathFromTextAcpiExp                 },
3652   {"AcpiAdr",                 DevPathFromTextAcpiAdr                 },
3653 
3654   {"Msg",                     DevPathFromTextMsg                     },
3655   {"Ata",                     DevPathFromTextAta                     },
3656   {"Scsi",                    DevPathFromTextScsi                    },
3657   {"Fibre",                   DevPathFromTextFibre                   },
3658   {"FibreEx",                 DevPathFromTextFibreEx                 },
3659   {"I1394",                   DevPathFromText1394                    },
3660   {"USB",                     DevPathFromTextUsb                     },
3661   {"I2O",                     DevPathFromTextI2O                     },
3662   {"Infiniband",              DevPathFromTextInfiniband              },
3663   {"VenMsg",                  DevPathFromTextVenMsg                  },
3664   {"VenPcAnsi",               DevPathFromTextVenPcAnsi               },
3665   {"VenVt100",                DevPathFromTextVenVt100                },
3666   {"VenVt100Plus",            DevPathFromTextVenVt100Plus            },
3667   {"VenUtf8",                 DevPathFromTextVenUtf8                 },
3668   {"UartFlowCtrl",            DevPathFromTextUartFlowCtrl            },
3669   {"SAS",                     DevPathFromTextSAS                     },
3670   {"SasEx",                   DevPathFromTextSasEx                   },
3671   {"NVMe",                    DevPathFromTextNVMe                    },
3672   {"UFS",                     DevPathFromTextUfs                     },
3673   {"SD",                      DevPathFromTextSd                      },
3674   {"eMMC",                    DevPathFromTextEmmc                    },
3675   {"DebugPort",               DevPathFromTextDebugPort               },
3676   {"MAC",                     DevPathFromTextMAC                     },
3677   {"IPv4",                    DevPathFromTextIPv4                    },
3678   {"IPv6",                    DevPathFromTextIPv6                    },
3679   {"Uart",                    DevPathFromTextUart                    },
3680   {"UsbClass",                DevPathFromTextUsbClass                },
3681   {"UsbAudio",                DevPathFromTextUsbAudio                },
3682   {"UsbCDCControl",           DevPathFromTextUsbCDCControl           },
3683   {"UsbHID",                  DevPathFromTextUsbHID                  },
3684   {"UsbImage",                DevPathFromTextUsbImage                },
3685   {"UsbPrinter",              DevPathFromTextUsbPrinter              },
3686   {"UsbMassStorage",          DevPathFromTextUsbMassStorage          },
3687   {"UsbHub",                  DevPathFromTextUsbHub                  },
3688   {"UsbCDCData",              DevPathFromTextUsbCDCData              },
3689   {"UsbSmartCard",            DevPathFromTextUsbSmartCard            },
3690   {"UsbVideo",                DevPathFromTextUsbVideo                },
3691   {"UsbDiagnostic",           DevPathFromTextUsbDiagnostic           },
3692   {"UsbWireless",             DevPathFromTextUsbWireless             },
3693   {"UsbDeviceFirmwareUpdate", DevPathFromTextUsbDeviceFirmwareUpdate },
3694   {"UsbIrdaBridge",           DevPathFromTextUsbIrdaBridge           },
3695   {"UsbTestAndMeasurement",   DevPathFromTextUsbTestAndMeasurement   },
3696   {"UsbWwid",                 DevPathFromTextUsbWwid                 },
3697   {"Unit",                    DevPathFromTextUnit                    },
3698   {"iSCSI",                   DevPathFromTextiSCSI                   },
3699   {"Vlan",                    DevPathFromTextVlan                    },
3700   {"Dns",                     DevPathFromTextDns                     },
3701   {"Uri",                     DevPathFromTextUri                     },
3702   {"Bluetooth",               DevPathFromTextBluetooth               },
3703   {"Wi-Fi",                   DevPathFromTextWiFi                    },
3704   {"BluetoothLE",             DevPathFromTextBluetoothLE             },
3705   {"MediaPath",               DevPathFromTextMediaPath               },
3706   {"HD",                      DevPathFromTextHD                      },
3707   {"CDROM",                   DevPathFromTextCDROM                   },
3708   {"VenMedia",                DevPathFromTextVenMedia                },
3709   {"Media",                   DevPathFromTextMedia                   },
3710   {"Fv",                      DevPathFromTextFv                      },
3711   {"FvFile",                  DevPathFromTextFvFile                  },
3712   {"File",                    DevPathFromTextFilePath                },
3713   {"Offset",                  DevPathFromTextRelativeOffsetRange     },
3714   {"RamDisk",                 DevPathFromTextRamDisk                 },
3715   {"VirtualDisk",             DevPathFromTextVirtualDisk             },
3716   {"VirtualCD",               DevPathFromTextVirtualCd               },
3717   {"PersistentVirtualDisk",   DevPathFromTextPersistentVirtualDisk   },
3718   {"PersistentVirtualCD",     DevPathFromTextPersistentVirtualCd     },
3719 
3720   {"BbsPath",                 DevPathFromTextBbsPath                 },
3721   {"BBS",                     DevPathFromTextBBS                     },
3722   {"Sata",                    DevPathFromTextSata                    },
3723   {NULL, NULL}
3724 };
3725 
3726 /**
3727   Convert text to the binary representation of a device node.
3728 
3729   @param TextDeviceNode  TextDeviceNode points to the text representation of a device
3730                          node. Conversion starts with the first character and continues
3731                          until the first non-device node character.
3732 
3733   @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
3734           insufficient memory or text unsupported.
3735 
3736 **/
3737 static
3738 EFI_DEVICE_PATH_PROTOCOL *
3739 EFIAPI
3740 UefiDevicePathLibConvertTextToDeviceNode (
3741   IN CONST CHAR16 *TextDeviceNode
3742   )
3743 {
3744   DEVICE_PATH_FROM_TEXT    FromText;
3745   CHAR16                   *ParamStr;
3746   EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
3747   CHAR16                   *DeviceNodeStr;
3748   UINTN                    Index;
3749 
3750   if ((TextDeviceNode == NULL) || (IS_NULL (*TextDeviceNode))) {
3751     return NULL;
3752   }
3753 
3754   ParamStr      = NULL;
3755   FromText      = NULL;
3756   DeviceNodeStr = UefiDevicePathLibStrDuplicate (TextDeviceNode);
3757   ASSERT (DeviceNodeStr != NULL);
3758 
3759   for (Index = 0; mUefiDevicePathLibDevPathFromTextTable[Index].Function != NULL; Index++) {
3760     ParamStr = GetParamByNodeName (DeviceNodeStr, mUefiDevicePathLibDevPathFromTextTable[Index].DevicePathNodeText);
3761     if (ParamStr != NULL) {
3762       FromText = mUefiDevicePathLibDevPathFromTextTable[Index].Function;
3763       break;
3764     }
3765   }
3766 
3767   if (FromText == NULL) {
3768     //
3769     // A file path
3770     //
3771     FromText = DevPathFromTextFilePath;
3772     DeviceNode = FromText (DeviceNodeStr);
3773   } else {
3774     DeviceNode = FromText (ParamStr);
3775     FreePool (ParamStr);
3776   }
3777 
3778   FreePool (DeviceNodeStr);
3779 
3780   return DeviceNode;
3781 }
3782 
3783 /**
3784   Convert text to the binary representation of a device path.
3785 
3786 
3787   @param TextDevicePath  TextDevicePath points to the text representation of a device
3788                          path. Conversion starts with the first character and continues
3789                          until the first non-device node character.
3790 
3791   @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
3792           there was insufficient memory.
3793 
3794 **/
3795 static
3796 EFI_DEVICE_PATH_PROTOCOL *
3797 EFIAPI
3798 UefiDevicePathLibConvertTextToDevicePath (
3799   IN CONST CHAR16 *TextDevicePath
3800   )
3801 {
3802   EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
3803   EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
3804   CHAR16                   *DevicePathStr;
3805   CHAR16                   *Str;
3806   CHAR16                   *DeviceNodeStr;
3807   BOOLEAN                  IsInstanceEnd;
3808   EFI_DEVICE_PATH_PROTOCOL *DevicePath;
3809 
3810   if ((TextDevicePath == NULL) || (IS_NULL (*TextDevicePath))) {
3811     return NULL;
3812   }
3813 
3814   DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
3815   ASSERT (DevicePath != NULL);
3816   SetDevicePathEndNode (DevicePath);
3817 
3818   DevicePathStr = UefiDevicePathLibStrDuplicate (TextDevicePath);
3819 
3820   Str           = DevicePathStr;
3821   while ((DeviceNodeStr = GetNextDeviceNodeStr (&Str, &IsInstanceEnd)) != NULL) {
3822     DeviceNode = UefiDevicePathLibConvertTextToDeviceNode (DeviceNodeStr);
3823 
3824     NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);
3825     FreePool (DevicePath);
3826     FreePool (DeviceNode);
3827     DevicePath = NewDevicePath;
3828 
3829     if (IsInstanceEnd) {
3830       DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
3831       ASSERT (DeviceNode != NULL);
3832       SetDevicePathEndNode (DeviceNode);
3833       DeviceNode->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
3834 
3835       NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);
3836       FreePool (DevicePath);
3837       FreePool (DeviceNode);
3838       DevicePath = NewDevicePath;
3839     }
3840   }
3841 
3842   FreePool (DevicePathStr);
3843   return DevicePath;
3844 }
3845 
3846 ssize_t
3847 efidp_parse_device_path(char *path, efidp out, size_t max)
3848 {
3849 	EFI_DEVICE_PATH_PROTOCOL *dp;
3850 	UINTN len;
3851 
3852 	dp = UefiDevicePathLibConvertTextToDevicePath (path);
3853 	if (dp == NULL)
3854 		return -1;
3855 	len = GetDevicePathSize(dp);
3856 	if (len > max) {
3857 		free(dp);
3858 		return -1;
3859 	}
3860 	memcpy(out, dp, len);
3861 	free(dp);
3862 
3863 	return len;
3864 }
3865