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