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