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