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