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