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