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