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