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