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