xref: /freebsd/lib/libefivar/efivar-dp-parse.c (revision b782b7884c8aa19cb2dcb6ece6909e9f05173d72)
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   if (MACDevPath->IfType == 0x01 || MACDevPath->IfType == 0x00) {
1924     Length = 6;
1925   }
1926 
1927   StrHexToBytes (AddressStr, Length * 2, MACDevPath->MacAddress.Addr, Length);
1928 
1929   return (EFI_DEVICE_PATH_PROTOCOL *) MACDevPath;
1930 }
1931 
1932 
1933 /**
1934   Converts a text format to the network protocol ID.
1935 
1936   @param Text  String of protocol field.
1937 
1938   @return Network protocol ID .
1939 
1940 **/
1941 static
1942 UINTN
1943 NetworkProtocolFromText (
1944   IN CHAR16 *Text
1945   )
1946 {
1947   if (StrCmp (Text, "UDP") == 0) {
1948     return RFC_1700_UDP_PROTOCOL;
1949   }
1950 
1951   if (StrCmp (Text, "TCP") == 0) {
1952     return RFC_1700_TCP_PROTOCOL;
1953   }
1954 
1955   return Strtoi (Text);
1956 }
1957 
1958 
1959 /**
1960   Converts a text device path node to IPV4 device path structure.
1961 
1962   @param TextDeviceNode  The input Text device path node.
1963 
1964   @return A pointer to the newly-created IPV4 device path structure.
1965 
1966 **/
1967 static
1968 EFI_DEVICE_PATH_PROTOCOL *
1969 DevPathFromTextIPv4 (
1970   IN CHAR16 *TextDeviceNode
1971   )
1972 {
1973   CHAR16            *RemoteIPStr;
1974   CHAR16            *ProtocolStr;
1975   CHAR16            *TypeStr;
1976   CHAR16            *LocalIPStr;
1977   CHAR16            *GatewayIPStr;
1978   CHAR16            *SubnetMaskStr;
1979   IPv4_DEVICE_PATH  *IPv4;
1980 
1981   RemoteIPStr           = GetNextParamStr (&TextDeviceNode);
1982   ProtocolStr           = GetNextParamStr (&TextDeviceNode);
1983   TypeStr               = GetNextParamStr (&TextDeviceNode);
1984   LocalIPStr            = GetNextParamStr (&TextDeviceNode);
1985   GatewayIPStr          = GetNextParamStr (&TextDeviceNode);
1986   SubnetMaskStr         = GetNextParamStr (&TextDeviceNode);
1987   IPv4                  = (IPv4_DEVICE_PATH *) CreateDeviceNode (
1988                                                  MESSAGING_DEVICE_PATH,
1989                                                  MSG_IPv4_DP,
1990                                                  (UINT16) sizeof (IPv4_DEVICE_PATH)
1991                                                  );
1992 
1993   StrToIpv4Address (RemoteIPStr, NULL, &IPv4->RemoteIpAddress, NULL);
1994   IPv4->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr);
1995   if (StrCmp (TypeStr, "Static") == 0) {
1996     IPv4->StaticIpAddress = TRUE;
1997   } else {
1998     IPv4->StaticIpAddress = FALSE;
1999   }
2000 
2001   StrToIpv4Address (LocalIPStr, NULL, &IPv4->LocalIpAddress, NULL);
2002   if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*SubnetMaskStr)) {
2003     StrToIpv4Address (GatewayIPStr,  NULL, &IPv4->GatewayIpAddress, NULL);
2004     StrToIpv4Address (SubnetMaskStr, NULL, &IPv4->SubnetMask,       NULL);
2005   } else {
2006     ZeroMem (&IPv4->GatewayIpAddress, sizeof (IPv4->GatewayIpAddress));
2007     ZeroMem (&IPv4->SubnetMask,    sizeof (IPv4->SubnetMask));
2008   }
2009 
2010   IPv4->LocalPort       = 0;
2011   IPv4->RemotePort      = 0;
2012 
2013   return (EFI_DEVICE_PATH_PROTOCOL *) IPv4;
2014 }
2015 
2016 /**
2017   Converts a text device path node to IPV6 device path structure.
2018 
2019   @param TextDeviceNode  The input Text device path node.
2020 
2021   @return A pointer to the newly-created IPV6 device path structure.
2022 
2023 **/
2024 static
2025 EFI_DEVICE_PATH_PROTOCOL *
2026 DevPathFromTextIPv6 (
2027   IN CHAR16 *TextDeviceNode
2028   )
2029 {
2030   CHAR16            *RemoteIPStr;
2031   CHAR16            *ProtocolStr;
2032   CHAR16            *TypeStr;
2033   CHAR16            *LocalIPStr;
2034   CHAR16            *GatewayIPStr;
2035   CHAR16            *PrefixLengthStr;
2036   IPv6_DEVICE_PATH  *IPv6;
2037 
2038   RemoteIPStr           = GetNextParamStr (&TextDeviceNode);
2039   ProtocolStr           = GetNextParamStr (&TextDeviceNode);
2040   TypeStr               = GetNextParamStr (&TextDeviceNode);
2041   LocalIPStr            = GetNextParamStr (&TextDeviceNode);
2042   PrefixLengthStr       = GetNextParamStr (&TextDeviceNode);
2043   GatewayIPStr          = GetNextParamStr (&TextDeviceNode);
2044   IPv6                  = (IPv6_DEVICE_PATH *) CreateDeviceNode (
2045                                                  MESSAGING_DEVICE_PATH,
2046                                                  MSG_IPv6_DP,
2047                                                  (UINT16) sizeof (IPv6_DEVICE_PATH)
2048                                                  );
2049 
2050   StrToIpv6Address (RemoteIPStr, NULL, &IPv6->RemoteIpAddress, NULL);
2051   IPv6->Protocol        = (UINT16) NetworkProtocolFromText (ProtocolStr);
2052   if (StrCmp (TypeStr, "Static") == 0) {
2053     IPv6->IpAddressOrigin = 0;
2054   } else if (StrCmp (TypeStr, "StatelessAutoConfigure") == 0) {
2055     IPv6->IpAddressOrigin = 1;
2056   } else {
2057     IPv6->IpAddressOrigin = 2;
2058   }
2059 
2060   StrToIpv6Address (LocalIPStr, NULL, &IPv6->LocalIpAddress, NULL);
2061   if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*PrefixLengthStr)) {
2062     StrToIpv6Address (GatewayIPStr, NULL, &IPv6->GatewayIpAddress, NULL);
2063     IPv6->PrefixLength = (UINT8) Strtoi (PrefixLengthStr);
2064   } else {
2065     ZeroMem (&IPv6->GatewayIpAddress, sizeof (IPv6->GatewayIpAddress));
2066     IPv6->PrefixLength = 0;
2067   }
2068 
2069   IPv6->LocalPort       = 0;
2070   IPv6->RemotePort      = 0;
2071 
2072   return (EFI_DEVICE_PATH_PROTOCOL *) IPv6;
2073 }
2074 
2075 /**
2076   Converts a text device path node to UART device path structure.
2077 
2078   @param TextDeviceNode  The input Text device path node.
2079 
2080   @return A pointer to the newly-created UART device path structure.
2081 
2082 **/
2083 static
2084 EFI_DEVICE_PATH_PROTOCOL *
2085 DevPathFromTextUart (
2086   IN CHAR16 *TextDeviceNode
2087   )
2088 {
2089   CHAR16            *BaudStr;
2090   CHAR16            *DataBitsStr;
2091   CHAR16            *ParityStr;
2092   CHAR16            *StopBitsStr;
2093   UART_DEVICE_PATH  *Uart;
2094 
2095   BaudStr         = GetNextParamStr (&TextDeviceNode);
2096   DataBitsStr     = GetNextParamStr (&TextDeviceNode);
2097   ParityStr       = GetNextParamStr (&TextDeviceNode);
2098   StopBitsStr     = GetNextParamStr (&TextDeviceNode);
2099   Uart            = (UART_DEVICE_PATH *) CreateDeviceNode (
2100                                            MESSAGING_DEVICE_PATH,
2101                                            MSG_UART_DP,
2102                                            (UINT16) sizeof (UART_DEVICE_PATH)
2103                                            );
2104 
2105   if (StrCmp (BaudStr, "DEFAULT") == 0) {
2106     Uart->BaudRate = 115200;
2107   } else {
2108     Strtoi64 (BaudStr, &Uart->BaudRate);
2109   }
2110   Uart->DataBits  = (UINT8) ((StrCmp (DataBitsStr, "DEFAULT") == 0) ? 8 : Strtoi (DataBitsStr));
2111   switch (*ParityStr) {
2112   case 'D':
2113     Uart->Parity = 0;
2114     break;
2115 
2116   case 'N':
2117     Uart->Parity = 1;
2118     break;
2119 
2120   case 'E':
2121     Uart->Parity = 2;
2122     break;
2123 
2124   case 'O':
2125     Uart->Parity = 3;
2126     break;
2127 
2128   case 'M':
2129     Uart->Parity = 4;
2130     break;
2131 
2132   case 'S':
2133     Uart->Parity = 5;
2134     break;
2135 
2136   default:
2137     Uart->Parity = (UINT8) Strtoi (ParityStr);
2138     break;
2139   }
2140 
2141   if (StrCmp (StopBitsStr, "D") == 0) {
2142     Uart->StopBits = (UINT8) 0;
2143   } else if (StrCmp (StopBitsStr, "1") == 0) {
2144     Uart->StopBits = (UINT8) 1;
2145   } else if (StrCmp (StopBitsStr, "1.5") == 0) {
2146     Uart->StopBits = (UINT8) 2;
2147   } else if (StrCmp (StopBitsStr, "2") == 0) {
2148     Uart->StopBits = (UINT8) 3;
2149   } else {
2150     Uart->StopBits = (UINT8) Strtoi (StopBitsStr);
2151   }
2152 
2153   return (EFI_DEVICE_PATH_PROTOCOL *) Uart;
2154 }
2155 
2156 /**
2157   Converts a text device path node to USB class device path structure.
2158 
2159   @param TextDeviceNode  The input Text device path node.
2160   @param UsbClassText    A pointer to USB_CLASS_TEXT structure to be integrated to USB Class Text.
2161 
2162   @return A pointer to the newly-created USB class device path structure.
2163 
2164 **/
2165 static
2166 EFI_DEVICE_PATH_PROTOCOL *
2167 ConvertFromTextUsbClass (
2168   IN CHAR16         *TextDeviceNode,
2169   IN USB_CLASS_TEXT *UsbClassText
2170   )
2171 {
2172   CHAR16                *VIDStr;
2173   CHAR16                *PIDStr;
2174   CHAR16                *ClassStr;
2175   CHAR16                *SubClassStr;
2176   CHAR16                *ProtocolStr;
2177   USB_CLASS_DEVICE_PATH *UsbClass;
2178 
2179   UsbClass    = (USB_CLASS_DEVICE_PATH *) CreateDeviceNode (
2180                                             MESSAGING_DEVICE_PATH,
2181                                             MSG_USB_CLASS_DP,
2182                                             (UINT16) sizeof (USB_CLASS_DEVICE_PATH)
2183                                             );
2184 
2185   VIDStr      = GetNextParamStr (&TextDeviceNode);
2186   PIDStr      = GetNextParamStr (&TextDeviceNode);
2187   if (UsbClassText->ClassExist) {
2188     ClassStr = GetNextParamStr (&TextDeviceNode);
2189     UsbClass->DeviceClass = (UINT8) Strtoi (ClassStr);
2190   } else {
2191     UsbClass->DeviceClass = UsbClassText->Class;
2192   }
2193   if (UsbClassText->SubClassExist) {
2194     SubClassStr = GetNextParamStr (&TextDeviceNode);
2195     UsbClass->DeviceSubClass = (UINT8) Strtoi (SubClassStr);
2196   } else {
2197     UsbClass->DeviceSubClass = UsbClassText->SubClass;
2198   }
2199 
2200   ProtocolStr = GetNextParamStr (&TextDeviceNode);
2201 
2202   UsbClass->VendorId        = (UINT16) Strtoi (VIDStr);
2203   UsbClass->ProductId       = (UINT16) Strtoi (PIDStr);
2204   UsbClass->DeviceProtocol  = (UINT8) Strtoi (ProtocolStr);
2205 
2206   return (EFI_DEVICE_PATH_PROTOCOL *) UsbClass;
2207 }
2208 
2209 
2210 /**
2211   Converts a text device path node to USB class device path structure.
2212 
2213   @param TextDeviceNode  The input Text device path node.
2214 
2215   @return A pointer to the newly-created USB class device path structure.
2216 
2217 **/
2218 static
2219 EFI_DEVICE_PATH_PROTOCOL *
2220 DevPathFromTextUsbClass (
2221   IN CHAR16 *TextDeviceNode
2222   )
2223 {
2224   USB_CLASS_TEXT  UsbClassText;
2225 
2226   UsbClassText.ClassExist    = TRUE;
2227   UsbClassText.SubClassExist = TRUE;
2228 
2229   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2230 }
2231 
2232 /**
2233   Converts a text device path node to USB audio device path structure.
2234 
2235   @param TextDeviceNode  The input Text device path node.
2236 
2237   @return A pointer to the newly-created USB audio device path structure.
2238 
2239 **/
2240 static
2241 EFI_DEVICE_PATH_PROTOCOL *
2242 DevPathFromTextUsbAudio (
2243   IN CHAR16 *TextDeviceNode
2244   )
2245 {
2246   USB_CLASS_TEXT  UsbClassText;
2247 
2248   UsbClassText.ClassExist    = FALSE;
2249   UsbClassText.Class         = USB_CLASS_AUDIO;
2250   UsbClassText.SubClassExist = TRUE;
2251 
2252   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2253 }
2254 
2255 /**
2256   Converts a text device path node to USB CDC Control device path structure.
2257 
2258   @param TextDeviceNode  The input Text device path node.
2259 
2260   @return A pointer to the newly-created USB CDC Control device path structure.
2261 
2262 **/
2263 static
2264 EFI_DEVICE_PATH_PROTOCOL *
2265 DevPathFromTextUsbCDCControl (
2266   IN CHAR16 *TextDeviceNode
2267   )
2268 {
2269   USB_CLASS_TEXT  UsbClassText;
2270 
2271   UsbClassText.ClassExist    = FALSE;
2272   UsbClassText.Class         = USB_CLASS_CDCCONTROL;
2273   UsbClassText.SubClassExist = TRUE;
2274 
2275   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2276 }
2277 
2278 /**
2279   Converts a text device path node to USB HID device path structure.
2280 
2281   @param TextDeviceNode  The input Text device path node.
2282 
2283   @return A pointer to the newly-created USB HID device path structure.
2284 
2285 **/
2286 static
2287 EFI_DEVICE_PATH_PROTOCOL *
2288 DevPathFromTextUsbHID (
2289   IN CHAR16 *TextDeviceNode
2290   )
2291 {
2292   USB_CLASS_TEXT  UsbClassText;
2293 
2294   UsbClassText.ClassExist    = FALSE;
2295   UsbClassText.Class         = USB_CLASS_HID;
2296   UsbClassText.SubClassExist = TRUE;
2297 
2298   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2299 }
2300 
2301 /**
2302   Converts a text device path node to USB Image device path structure.
2303 
2304   @param TextDeviceNode  The input Text device path node.
2305 
2306   @return A pointer to the newly-created USB Image device path structure.
2307 
2308 **/
2309 static
2310 EFI_DEVICE_PATH_PROTOCOL *
2311 DevPathFromTextUsbImage (
2312   IN CHAR16 *TextDeviceNode
2313   )
2314 {
2315   USB_CLASS_TEXT  UsbClassText;
2316 
2317   UsbClassText.ClassExist    = FALSE;
2318   UsbClassText.Class         = USB_CLASS_IMAGE;
2319   UsbClassText.SubClassExist = TRUE;
2320 
2321   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2322 }
2323 
2324 /**
2325   Converts a text device path node to USB Print device path structure.
2326 
2327   @param TextDeviceNode  The input Text device path node.
2328 
2329   @return A pointer to the newly-created USB Print device path structure.
2330 
2331 **/
2332 static
2333 EFI_DEVICE_PATH_PROTOCOL *
2334 DevPathFromTextUsbPrinter (
2335   IN CHAR16 *TextDeviceNode
2336   )
2337 {
2338   USB_CLASS_TEXT  UsbClassText;
2339 
2340   UsbClassText.ClassExist    = FALSE;
2341   UsbClassText.Class         = USB_CLASS_PRINTER;
2342   UsbClassText.SubClassExist = TRUE;
2343 
2344   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2345 }
2346 
2347 /**
2348   Converts a text device path node to USB mass storage device path structure.
2349 
2350   @param TextDeviceNode  The input Text device path node.
2351 
2352   @return A pointer to the newly-created USB mass storage device path structure.
2353 
2354 **/
2355 static
2356 EFI_DEVICE_PATH_PROTOCOL *
2357 DevPathFromTextUsbMassStorage (
2358   IN CHAR16 *TextDeviceNode
2359   )
2360 {
2361   USB_CLASS_TEXT  UsbClassText;
2362 
2363   UsbClassText.ClassExist    = FALSE;
2364   UsbClassText.Class         = USB_CLASS_MASS_STORAGE;
2365   UsbClassText.SubClassExist = TRUE;
2366 
2367   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2368 }
2369 
2370 /**
2371   Converts a text device path node to USB HUB device path structure.
2372 
2373   @param TextDeviceNode  The input Text device path node.
2374 
2375   @return A pointer to the newly-created USB HUB device path structure.
2376 
2377 **/
2378 static
2379 EFI_DEVICE_PATH_PROTOCOL *
2380 DevPathFromTextUsbHub (
2381   IN CHAR16 *TextDeviceNode
2382   )
2383 {
2384   USB_CLASS_TEXT  UsbClassText;
2385 
2386   UsbClassText.ClassExist    = FALSE;
2387   UsbClassText.Class         = USB_CLASS_HUB;
2388   UsbClassText.SubClassExist = TRUE;
2389 
2390   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2391 }
2392 
2393 /**
2394   Converts a text device path node to USB CDC data device path structure.
2395 
2396   @param TextDeviceNode  The input Text device path node.
2397 
2398   @return A pointer to the newly-created USB CDC data device path structure.
2399 
2400 **/
2401 static
2402 EFI_DEVICE_PATH_PROTOCOL *
2403 DevPathFromTextUsbCDCData (
2404   IN CHAR16 *TextDeviceNode
2405   )
2406 {
2407   USB_CLASS_TEXT  UsbClassText;
2408 
2409   UsbClassText.ClassExist    = FALSE;
2410   UsbClassText.Class         = USB_CLASS_CDCDATA;
2411   UsbClassText.SubClassExist = TRUE;
2412 
2413   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2414 }
2415 
2416 /**
2417   Converts a text device path node to USB smart card device path structure.
2418 
2419   @param TextDeviceNode  The input Text device path node.
2420 
2421   @return A pointer to the newly-created USB smart card device path structure.
2422 
2423 **/
2424 static
2425 EFI_DEVICE_PATH_PROTOCOL *
2426 DevPathFromTextUsbSmartCard (
2427   IN CHAR16 *TextDeviceNode
2428   )
2429 {
2430   USB_CLASS_TEXT  UsbClassText;
2431 
2432   UsbClassText.ClassExist    = FALSE;
2433   UsbClassText.Class         = USB_CLASS_SMART_CARD;
2434   UsbClassText.SubClassExist = TRUE;
2435 
2436   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2437 }
2438 
2439 /**
2440   Converts a text device path node to USB video device path structure.
2441 
2442   @param TextDeviceNode  The input Text device path node.
2443 
2444   @return A pointer to the newly-created USB video device path structure.
2445 
2446 **/
2447 static
2448 EFI_DEVICE_PATH_PROTOCOL *
2449 DevPathFromTextUsbVideo (
2450   IN CHAR16 *TextDeviceNode
2451   )
2452 {
2453   USB_CLASS_TEXT  UsbClassText;
2454 
2455   UsbClassText.ClassExist    = FALSE;
2456   UsbClassText.Class         = USB_CLASS_VIDEO;
2457   UsbClassText.SubClassExist = TRUE;
2458 
2459   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2460 }
2461 
2462 /**
2463   Converts a text device path node to USB diagnostic device path structure.
2464 
2465   @param TextDeviceNode  The input Text device path node.
2466 
2467   @return A pointer to the newly-created USB diagnostic device path structure.
2468 
2469 **/
2470 static
2471 EFI_DEVICE_PATH_PROTOCOL *
2472 DevPathFromTextUsbDiagnostic (
2473   IN CHAR16 *TextDeviceNode
2474   )
2475 {
2476   USB_CLASS_TEXT  UsbClassText;
2477 
2478   UsbClassText.ClassExist    = FALSE;
2479   UsbClassText.Class         = USB_CLASS_DIAGNOSTIC;
2480   UsbClassText.SubClassExist = TRUE;
2481 
2482   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2483 }
2484 
2485 /**
2486   Converts a text device path node to USB wireless device path structure.
2487 
2488   @param TextDeviceNode  The input Text device path node.
2489 
2490   @return A pointer to the newly-created USB wireless device path structure.
2491 
2492 **/
2493 static
2494 EFI_DEVICE_PATH_PROTOCOL *
2495 DevPathFromTextUsbWireless (
2496   IN CHAR16 *TextDeviceNode
2497   )
2498 {
2499   USB_CLASS_TEXT  UsbClassText;
2500 
2501   UsbClassText.ClassExist    = FALSE;
2502   UsbClassText.Class         = USB_CLASS_WIRELESS;
2503   UsbClassText.SubClassExist = TRUE;
2504 
2505   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2506 }
2507 
2508 /**
2509   Converts a text device path node to USB device firmware update device path structure.
2510 
2511   @param TextDeviceNode  The input Text device path node.
2512 
2513   @return A pointer to the newly-created USB device firmware update device path structure.
2514 
2515 **/
2516 static
2517 EFI_DEVICE_PATH_PROTOCOL *
2518 DevPathFromTextUsbDeviceFirmwareUpdate (
2519   IN CHAR16 *TextDeviceNode
2520   )
2521 {
2522   USB_CLASS_TEXT  UsbClassText;
2523 
2524   UsbClassText.ClassExist    = FALSE;
2525   UsbClassText.Class         = USB_CLASS_RESERVE;
2526   UsbClassText.SubClassExist = FALSE;
2527   UsbClassText.SubClass      = USB_SUBCLASS_FW_UPDATE;
2528 
2529   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2530 }
2531 
2532 /**
2533   Converts a text device path node to USB IRDA bridge device path structure.
2534 
2535   @param TextDeviceNode  The input Text device path node.
2536 
2537   @return A pointer to the newly-created USB IRDA bridge device path structure.
2538 
2539 **/
2540 static
2541 EFI_DEVICE_PATH_PROTOCOL *
2542 DevPathFromTextUsbIrdaBridge (
2543   IN CHAR16 *TextDeviceNode
2544   )
2545 {
2546   USB_CLASS_TEXT  UsbClassText;
2547 
2548   UsbClassText.ClassExist    = FALSE;
2549   UsbClassText.Class         = USB_CLASS_RESERVE;
2550   UsbClassText.SubClassExist = FALSE;
2551   UsbClassText.SubClass      = USB_SUBCLASS_IRDA_BRIDGE;
2552 
2553   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2554 }
2555 
2556 /**
2557   Converts a text device path node to USB text and measurement device path structure.
2558 
2559   @param TextDeviceNode  The input Text device path node.
2560 
2561   @return A pointer to the newly-created USB text and measurement device path structure.
2562 
2563 **/
2564 static
2565 EFI_DEVICE_PATH_PROTOCOL *
2566 DevPathFromTextUsbTestAndMeasurement (
2567   IN CHAR16 *TextDeviceNode
2568   )
2569 {
2570   USB_CLASS_TEXT  UsbClassText;
2571 
2572   UsbClassText.ClassExist    = FALSE;
2573   UsbClassText.Class         = USB_CLASS_RESERVE;
2574   UsbClassText.SubClassExist = FALSE;
2575   UsbClassText.SubClass      = USB_SUBCLASS_TEST;
2576 
2577   return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
2578 }
2579 
2580 /**
2581   Converts a text device path node to USB WWID device path structure.
2582 
2583   @param TextDeviceNode  The input Text device path node.
2584 
2585   @return A pointer to the newly-created USB WWID device path structure.
2586 
2587 **/
2588 static
2589 EFI_DEVICE_PATH_PROTOCOL *
2590 DevPathFromTextUsbWwid (
2591   IN CHAR16 *TextDeviceNode
2592   )
2593 {
2594   CHAR16                *VIDStr;
2595   CHAR16                *PIDStr;
2596   CHAR16                *InterfaceNumStr;
2597   CHAR16                *SerialNumberStr;
2598   USB_WWID_DEVICE_PATH  *UsbWwid;
2599   UINTN                 SerialNumberStrLen;
2600 
2601   VIDStr                   = GetNextParamStr (&TextDeviceNode);
2602   PIDStr                   = GetNextParamStr (&TextDeviceNode);
2603   InterfaceNumStr          = GetNextParamStr (&TextDeviceNode);
2604   SerialNumberStr          = GetNextParamStr (&TextDeviceNode);
2605   SerialNumberStrLen       = StrLen (SerialNumberStr);
2606   if (SerialNumberStrLen >= 2 &&
2607       SerialNumberStr[0] == '\"' &&
2608       SerialNumberStr[SerialNumberStrLen - 1] == '\"'
2609     ) {
2610     SerialNumberStr[SerialNumberStrLen - 1] = '\0';
2611     SerialNumberStr++;
2612     SerialNumberStrLen -= 2;
2613   }
2614   UsbWwid                  = (USB_WWID_DEVICE_PATH *) CreateDeviceNode (
2615                                                          MESSAGING_DEVICE_PATH,
2616                                                          MSG_USB_WWID_DP,
2617                                                          (UINT16) (sizeof (USB_WWID_DEVICE_PATH) + SerialNumberStrLen * sizeof (CHAR16))
2618                                                          );
2619   UsbWwid->VendorId        = (UINT16) Strtoi (VIDStr);
2620   UsbWwid->ProductId       = (UINT16) Strtoi (PIDStr);
2621   UsbWwid->InterfaceNumber = (UINT16) Strtoi (InterfaceNumStr);
2622 
2623   //
2624   // There is no memory allocated in UsbWwid for the '\0' in SerialNumberStr.
2625   // Therefore, the '\0' will not be copied.
2626   //
2627   CopyMem (
2628     (UINT8 *) UsbWwid + sizeof (USB_WWID_DEVICE_PATH),
2629     SerialNumberStr,
2630     SerialNumberStrLen * sizeof (CHAR16)
2631     );
2632 
2633   return (EFI_DEVICE_PATH_PROTOCOL *) UsbWwid;
2634 }
2635 
2636 /**
2637   Converts a text device path node to Logic Unit device path structure.
2638 
2639   @param TextDeviceNode  The input Text device path node.
2640 
2641   @return A pointer to the newly-created Logic Unit device path structure.
2642 
2643 **/
2644 static
2645 EFI_DEVICE_PATH_PROTOCOL *
2646 DevPathFromTextUnit (
2647   IN CHAR16 *TextDeviceNode
2648   )
2649 {
2650   CHAR16                          *LunStr;
2651   DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
2652 
2653   LunStr      = GetNextParamStr (&TextDeviceNode);
2654   LogicalUnit = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *) CreateDeviceNode (
2655                                                       MESSAGING_DEVICE_PATH,
2656                                                       MSG_DEVICE_LOGICAL_UNIT_DP,
2657                                                       (UINT16) sizeof (DEVICE_LOGICAL_UNIT_DEVICE_PATH)
2658                                                       );
2659 
2660   LogicalUnit->Lun  = (UINT8) Strtoi (LunStr);
2661 
2662   return (EFI_DEVICE_PATH_PROTOCOL *) LogicalUnit;
2663 }
2664 
2665 /**
2666   Converts a text device path node to iSCSI device path structure.
2667 
2668   @param TextDeviceNode  The input Text device path node.
2669 
2670   @return A pointer to the newly-created iSCSI device path structure.
2671 
2672 **/
2673 static
2674 EFI_DEVICE_PATH_PROTOCOL *
2675 DevPathFromTextiSCSI (
2676   IN CHAR16 *TextDeviceNode
2677   )
2678 {
2679   UINT16                      Options;
2680   CHAR16                      *NameStr;
2681   CHAR16                      *PortalGroupStr;
2682   CHAR16                      *LunStr;
2683   CHAR16                      *HeaderDigestStr;
2684   CHAR16                      *DataDigestStr;
2685   CHAR16                      *AuthenticationStr;
2686   CHAR16                      *ProtocolStr;
2687   CHAR8                       *AsciiStr;
2688   ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath;
2689 
2690   NameStr           = GetNextParamStr (&TextDeviceNode);
2691   PortalGroupStr    = GetNextParamStr (&TextDeviceNode);
2692   LunStr            = GetNextParamStr (&TextDeviceNode);
2693   HeaderDigestStr   = GetNextParamStr (&TextDeviceNode);
2694   DataDigestStr     = GetNextParamStr (&TextDeviceNode);
2695   AuthenticationStr = GetNextParamStr (&TextDeviceNode);
2696   ProtocolStr       = GetNextParamStr (&TextDeviceNode);
2697   ISCSIDevPath      = (ISCSI_DEVICE_PATH_WITH_NAME *) CreateDeviceNode (
2698                                                         MESSAGING_DEVICE_PATH,
2699                                                         MSG_ISCSI_DP,
2700                                                         (UINT16) (sizeof (ISCSI_DEVICE_PATH_WITH_NAME) + StrLen (NameStr))
2701                                                         );
2702 
2703   AsciiStr = ISCSIDevPath->TargetName;
2704   StrToAscii (NameStr, &AsciiStr);
2705 
2706   ISCSIDevPath->TargetPortalGroupTag = (UINT16) Strtoi (PortalGroupStr);
2707   Strtoi64 (LunStr, &ISCSIDevPath->Lun);
2708 
2709   Options = 0x0000;
2710   if (StrCmp (HeaderDigestStr, "CRC32C") == 0) {
2711     Options |= 0x0002;
2712   }
2713 
2714   if (StrCmp (DataDigestStr, "CRC32C") == 0) {
2715     Options |= 0x0008;
2716   }
2717 
2718   if (StrCmp (AuthenticationStr, "None") == 0) {
2719     Options |= 0x0800;
2720   }
2721 
2722   if (StrCmp (AuthenticationStr, "CHAP_UNI") == 0) {
2723     Options |= 0x1000;
2724   }
2725 
2726   ISCSIDevPath->LoginOption      = (UINT16) Options;
2727 
2728   ISCSIDevPath->NetworkProtocol  = (UINT16) StrCmp (ProtocolStr, "TCP");
2729 
2730   return (EFI_DEVICE_PATH_PROTOCOL *) ISCSIDevPath;
2731 }
2732 
2733 /**
2734   Converts a text device path node to VLAN device path structure.
2735 
2736   @param TextDeviceNode  The input Text device path node.
2737 
2738   @return A pointer to the newly-created VLAN device path structure.
2739 
2740 **/
2741 static
2742 EFI_DEVICE_PATH_PROTOCOL *
2743 DevPathFromTextVlan (
2744   IN CHAR16 *TextDeviceNode
2745   )
2746 {
2747   CHAR16            *VlanStr;
2748   VLAN_DEVICE_PATH  *Vlan;
2749 
2750   VlanStr = GetNextParamStr (&TextDeviceNode);
2751   Vlan    = (VLAN_DEVICE_PATH *) CreateDeviceNode (
2752                                    MESSAGING_DEVICE_PATH,
2753                                    MSG_VLAN_DP,
2754                                    (UINT16) sizeof (VLAN_DEVICE_PATH)
2755                                    );
2756 
2757   Vlan->VlanId = (UINT16) Strtoi (VlanStr);
2758 
2759   return (EFI_DEVICE_PATH_PROTOCOL *) Vlan;
2760 }
2761 
2762 /**
2763   Converts a text device path node to Bluetooth device path structure.
2764 
2765   @param TextDeviceNode  The input Text device path node.
2766 
2767   @return A pointer to the newly-created Bluetooth device path structure.
2768 
2769 **/
2770 static
2771 EFI_DEVICE_PATH_PROTOCOL *
2772 DevPathFromTextBluetooth (
2773   IN CHAR16 *TextDeviceNode
2774   )
2775 {
2776   CHAR16                  *BluetoothStr;
2777   CHAR16                  *Walker;
2778   CHAR16                  *TempNumBuffer;
2779   UINTN                   TempBufferSize;
2780   INT32                   Index;
2781   BLUETOOTH_DEVICE_PATH   *BluetoothDp;
2782 
2783   BluetoothStr = GetNextParamStr (&TextDeviceNode);
2784   BluetoothDp = (BLUETOOTH_DEVICE_PATH *) CreateDeviceNode (
2785                                    MESSAGING_DEVICE_PATH,
2786                                    MSG_BLUETOOTH_DP,
2787                                    (UINT16) sizeof (BLUETOOTH_DEVICE_PATH)
2788                                    );
2789 
2790   Index = sizeof (BLUETOOTH_ADDRESS) - 1;
2791   Walker = BluetoothStr;
2792   while (!IS_NULL(*Walker) && Index >= 0) {
2793     TempBufferSize = 2 * sizeof(CHAR16) + StrSize("0x");
2794     TempNumBuffer = AllocateZeroPool (TempBufferSize);
2795     if (TempNumBuffer == NULL) {
2796       break;
2797     }
2798     StrCpyS (TempNumBuffer, TempBufferSize / sizeof (CHAR16), "0x");
2799     StrnCatS (TempNumBuffer, TempBufferSize / sizeof (CHAR16), Walker, 2);
2800     BluetoothDp->BD_ADDR.Address[Index] = (UINT8)Strtoi (TempNumBuffer);
2801     FreePool (TempNumBuffer);
2802     Walker += 2;
2803     Index--;
2804   }
2805 
2806   return (EFI_DEVICE_PATH_PROTOCOL *) BluetoothDp;
2807 }
2808 
2809 /**
2810   Converts a text device path node to Wi-Fi device path structure.
2811 
2812   @param TextDeviceNode  The input Text device path node.
2813 
2814   @return A pointer to the newly-created Wi-Fi device path structure.
2815 
2816 **/
2817 static
2818 EFI_DEVICE_PATH_PROTOCOL *
2819 DevPathFromTextWiFi (
2820   IN CHAR16 *TextDeviceNode
2821   )
2822 {
2823   CHAR16                *SSIdStr;
2824   CHAR8                 AsciiStr[33];
2825   UINTN                 DataLen;
2826   WIFI_DEVICE_PATH      *WiFiDp;
2827 
2828   SSIdStr = GetNextParamStr (&TextDeviceNode);
2829   WiFiDp  = (WIFI_DEVICE_PATH *) CreateDeviceNode (
2830                                    MESSAGING_DEVICE_PATH,
2831                                    MSG_WIFI_DP,
2832                                    (UINT16) sizeof (WIFI_DEVICE_PATH)
2833                                    );
2834 
2835   if (NULL != SSIdStr) {
2836     DataLen = StrLen (SSIdStr);
2837     if (StrLen (SSIdStr) > 32) {
2838       SSIdStr[32] = '\0';
2839       DataLen     = 32;
2840     }
2841 
2842     UnicodeStrToAsciiStrS (SSIdStr, AsciiStr, sizeof (AsciiStr));
2843     CopyMem (WiFiDp->SSId, AsciiStr, DataLen);
2844   }
2845 
2846   return (EFI_DEVICE_PATH_PROTOCOL *) WiFiDp;
2847 }
2848 
2849 /**
2850   Converts a text device path node to URI device path structure.
2851 
2852   @param TextDeviceNode  The input Text device path node.
2853 
2854   @return A pointer to the newly-created URI device path structure.
2855 
2856 **/
2857 static
2858 EFI_DEVICE_PATH_PROTOCOL *
2859 DevPathFromTextUri (
2860   IN CHAR16 *TextDeviceNode
2861   )
2862 {
2863   CHAR16           *UriStr;
2864   UINTN            UriLength;
2865   URI_DEVICE_PATH  *Uri;
2866 
2867   UriStr = GetNextParamStr (&TextDeviceNode);
2868   UriLength = StrnLenS (UriStr, MAX_UINT16 - sizeof (URI_DEVICE_PATH));
2869   Uri    = (URI_DEVICE_PATH *) CreateDeviceNode (
2870                                  MESSAGING_DEVICE_PATH,
2871                                  MSG_URI_DP,
2872                                  (UINT16) (sizeof (URI_DEVICE_PATH) + UriLength)
2873                                  );
2874 
2875   while (UriLength-- != 0) {
2876     Uri->Uri[UriLength] = (CHAR8) UriStr[UriLength];
2877   }
2878 
2879   return (EFI_DEVICE_PATH_PROTOCOL *) Uri;
2880 }
2881 
2882 /**
2883   Converts a media text device path node to media device path structure.
2884 
2885   @param TextDeviceNode  The input Text device path node.
2886 
2887   @return A pointer to media device path structure.
2888 
2889 **/
2890 static
2891 EFI_DEVICE_PATH_PROTOCOL *
2892 DevPathFromTextMediaPath (
2893   IN CHAR16 *TextDeviceNode
2894   )
2895 {
2896   return DevPathFromTextGenericPath (MEDIA_DEVICE_PATH, TextDeviceNode);
2897 }
2898 
2899 /**
2900   Converts a text device path node to HD device path structure.
2901 
2902   @param TextDeviceNode  The input Text device path node.
2903 
2904   @return A pointer to the newly-created HD device path structure.
2905 
2906 **/
2907 static
2908 EFI_DEVICE_PATH_PROTOCOL *
2909 DevPathFromTextHD (
2910   IN CHAR16 *TextDeviceNode
2911   )
2912 {
2913   CHAR16                *PartitionStr;
2914   CHAR16                *TypeStr;
2915   CHAR16                *SignatureStr;
2916   CHAR16                *StartStr;
2917   CHAR16                *SizeStr;
2918   UINT32                Signature32;
2919   HARDDRIVE_DEVICE_PATH *Hd;
2920 
2921   PartitionStr        = GetNextParamStr (&TextDeviceNode);
2922   TypeStr             = GetNextParamStr (&TextDeviceNode);
2923   SignatureStr        = GetNextParamStr (&TextDeviceNode);
2924   StartStr            = GetNextParamStr (&TextDeviceNode);
2925   SizeStr             = GetNextParamStr (&TextDeviceNode);
2926   Hd                  = (HARDDRIVE_DEVICE_PATH *) CreateDeviceNode (
2927                                                     MEDIA_DEVICE_PATH,
2928                                                     MEDIA_HARDDRIVE_DP,
2929                                                     (UINT16) sizeof (HARDDRIVE_DEVICE_PATH)
2930                                                     );
2931 
2932   Hd->PartitionNumber = (UINT32) Strtoi (PartitionStr);
2933 
2934   ZeroMem (Hd->Signature, 16);
2935   Hd->MBRType = (UINT8) 0;
2936 
2937   if (StrCmp (TypeStr, "MBR") == 0) {
2938     Hd->SignatureType = SIGNATURE_TYPE_MBR;
2939     Hd->MBRType       = 0x01;
2940 
2941     Signature32       = (UINT32) Strtoi (SignatureStr);
2942     CopyMem (Hd->Signature, &Signature32, sizeof (UINT32));
2943   } else if (StrCmp (TypeStr, "GPT") == 0) {
2944     Hd->SignatureType = SIGNATURE_TYPE_GUID;
2945     Hd->MBRType       = 0x02;
2946 
2947     StrToGuid (SignatureStr, (EFI_GUID *) Hd->Signature);
2948   } else {
2949     Hd->SignatureType = (UINT8) Strtoi (TypeStr);
2950   }
2951 
2952   Strtoi64 (StartStr, &Hd->PartitionStart);
2953   Strtoi64 (SizeStr, &Hd->PartitionSize);
2954 
2955   return (EFI_DEVICE_PATH_PROTOCOL *) Hd;
2956 }
2957 
2958 /**
2959   Converts a text device path node to CDROM device path structure.
2960 
2961   @param TextDeviceNode  The input Text device path node.
2962 
2963   @return A pointer to the newly-created CDROM device path structure.
2964 
2965 **/
2966 static
2967 EFI_DEVICE_PATH_PROTOCOL *
2968 DevPathFromTextCDROM (
2969   IN CHAR16 *TextDeviceNode
2970   )
2971 {
2972   CHAR16            *EntryStr;
2973   CHAR16            *StartStr;
2974   CHAR16            *SizeStr;
2975   CDROM_DEVICE_PATH *CDROMDevPath;
2976 
2977   EntryStr              = GetNextParamStr (&TextDeviceNode);
2978   StartStr              = GetNextParamStr (&TextDeviceNode);
2979   SizeStr               = GetNextParamStr (&TextDeviceNode);
2980   CDROMDevPath          = (CDROM_DEVICE_PATH *) CreateDeviceNode (
2981                                                   MEDIA_DEVICE_PATH,
2982                                                   MEDIA_CDROM_DP,
2983                                                   (UINT16) sizeof (CDROM_DEVICE_PATH)
2984                                                   );
2985 
2986   CDROMDevPath->BootEntry = (UINT32) Strtoi (EntryStr);
2987   Strtoi64 (StartStr, &CDROMDevPath->PartitionStart);
2988   Strtoi64 (SizeStr, &CDROMDevPath->PartitionSize);
2989 
2990   return (EFI_DEVICE_PATH_PROTOCOL *) CDROMDevPath;
2991 }
2992 
2993 /**
2994   Converts a text device path node to Vendor-defined media device path structure.
2995 
2996   @param TextDeviceNode  The input Text device path node.
2997 
2998   @return A pointer to the newly-created Vendor-defined media device path structure.
2999 
3000 **/
3001 static
3002 EFI_DEVICE_PATH_PROTOCOL *
3003 DevPathFromTextVenMedia (
3004   IN CHAR16 *TextDeviceNode
3005   )
3006 {
3007   return ConvertFromTextVendor (
3008            TextDeviceNode,
3009            MEDIA_DEVICE_PATH,
3010            MEDIA_VENDOR_DP
3011            );
3012 }
3013 
3014 /**
3015   Converts a text device path node to File device path structure.
3016 
3017   @param TextDeviceNode  The input Text device path node.
3018 
3019   @return A pointer to the newly-created File device path structure.
3020 
3021 **/
3022 static
3023 EFI_DEVICE_PATH_PROTOCOL *
3024 DevPathFromTextFilePath (
3025   IN CHAR16 *TextDeviceNode
3026   )
3027 {
3028   FILEPATH_DEVICE_PATH  *File;
3029 
3030 #ifndef __FreeBSD__
3031   File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode (
3032                                     MEDIA_DEVICE_PATH,
3033                                     MEDIA_FILEPATH_DP,
3034                                     (UINT16) (sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) * 2)
3035                                     );
3036 
3037   StrCpyS (File->PathName, StrLen (TextDeviceNode) + 1, TextDeviceNode);
3038 #else
3039   size_t len = (sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) * 2);
3040   efi_char * v;
3041   File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode (
3042                                     MEDIA_DEVICE_PATH,
3043                                     MEDIA_FILEPATH_DP,
3044 				    (UINT16)len
3045                                     );
3046   v = File->PathName;
3047   utf8_to_ucs2(TextDeviceNode, &v, &len);
3048 #endif
3049 
3050   return (EFI_DEVICE_PATH_PROTOCOL *) File;
3051 }
3052 
3053 /**
3054   Converts a text device path node to Media protocol device path structure.
3055 
3056   @param TextDeviceNode  The input Text device path node.
3057 
3058   @return A pointer to the newly-created Media protocol device path structure.
3059 
3060 **/
3061 static
3062 EFI_DEVICE_PATH_PROTOCOL *
3063 DevPathFromTextMedia (
3064   IN CHAR16 *TextDeviceNode
3065   )
3066 {
3067   CHAR16                      *GuidStr;
3068   MEDIA_PROTOCOL_DEVICE_PATH  *Media;
3069 
3070   GuidStr = GetNextParamStr (&TextDeviceNode);
3071   Media   = (MEDIA_PROTOCOL_DEVICE_PATH *) CreateDeviceNode (
3072                                              MEDIA_DEVICE_PATH,
3073                                              MEDIA_PROTOCOL_DP,
3074                                              (UINT16) sizeof (MEDIA_PROTOCOL_DEVICE_PATH)
3075                                              );
3076 
3077   StrToGuid (GuidStr, &Media->Protocol);
3078 
3079   return (EFI_DEVICE_PATH_PROTOCOL *) Media;
3080 }
3081 
3082 /**
3083   Converts a text device path node to firmware volume device path structure.
3084 
3085   @param TextDeviceNode  The input Text device path node.
3086 
3087   @return A pointer to the newly-created firmware volume device path structure.
3088 
3089 **/
3090 static
3091 EFI_DEVICE_PATH_PROTOCOL *
3092 DevPathFromTextFv (
3093   IN CHAR16 *TextDeviceNode
3094   )
3095 {
3096   CHAR16                    *GuidStr;
3097   MEDIA_FW_VOL_DEVICE_PATH  *Fv;
3098 
3099   GuidStr = GetNextParamStr (&TextDeviceNode);
3100   Fv      = (MEDIA_FW_VOL_DEVICE_PATH *) CreateDeviceNode (
3101                                            MEDIA_DEVICE_PATH,
3102                                            MEDIA_PIWG_FW_VOL_DP,
3103                                            (UINT16) sizeof (MEDIA_FW_VOL_DEVICE_PATH)
3104                                            );
3105 
3106   StrToGuid (GuidStr, &Fv->FvName);
3107 
3108   return (EFI_DEVICE_PATH_PROTOCOL *) Fv;
3109 }
3110 
3111 /**
3112   Converts a text device path node to firmware file device path structure.
3113 
3114   @param TextDeviceNode  The input Text device path node.
3115 
3116   @return A pointer to the newly-created firmware file device path structure.
3117 
3118 **/
3119 static
3120 EFI_DEVICE_PATH_PROTOCOL *
3121 DevPathFromTextFvFile (
3122   IN CHAR16 *TextDeviceNode
3123   )
3124 {
3125   CHAR16                             *GuidStr;
3126   MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvFile;
3127 
3128   GuidStr = GetNextParamStr (&TextDeviceNode);
3129   FvFile  = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) CreateDeviceNode (
3130                                                     MEDIA_DEVICE_PATH,
3131                                                     MEDIA_PIWG_FW_FILE_DP,
3132                                                     (UINT16) sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH)
3133                                                     );
3134 
3135   StrToGuid (GuidStr, &FvFile->FvFileName);
3136 
3137   return (EFI_DEVICE_PATH_PROTOCOL *) FvFile;
3138 }
3139 
3140 /**
3141   Converts a text device path node to text relative offset device path structure.
3142 
3143   @param TextDeviceNode  The input Text device path node.
3144 
3145   @return A pointer to the newly-created Text device path structure.
3146 
3147 **/
3148 static
3149 EFI_DEVICE_PATH_PROTOCOL *
3150 DevPathFromTextRelativeOffsetRange (
3151   IN CHAR16 *TextDeviceNode
3152   )
3153 {
3154   CHAR16                                  *StartingOffsetStr;
3155   CHAR16                                  *EndingOffsetStr;
3156   MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
3157 
3158   StartingOffsetStr = GetNextParamStr (&TextDeviceNode);
3159   EndingOffsetStr   = GetNextParamStr (&TextDeviceNode);
3160   Offset            = (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *) CreateDeviceNode (
3161                                                                     MEDIA_DEVICE_PATH,
3162                                                                     MEDIA_RELATIVE_OFFSET_RANGE_DP,
3163                                                                     (UINT16) sizeof (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH)
3164                                                                     );
3165 
3166   Strtoi64 (StartingOffsetStr, &Offset->StartingOffset);
3167   Strtoi64 (EndingOffsetStr, &Offset->EndingOffset);
3168 
3169   return (EFI_DEVICE_PATH_PROTOCOL *) Offset;
3170 }
3171 
3172 /**
3173   Converts a text device path node to text ram disk device path structure.
3174 
3175   @param TextDeviceNode  The input Text device path node.
3176 
3177   @return A pointer to the newly-created Text device path structure.
3178 
3179 **/
3180 static
3181 EFI_DEVICE_PATH_PROTOCOL *
3182 DevPathFromTextRamDisk (
3183   IN CHAR16 *TextDeviceNode
3184   )
3185 {
3186   CHAR16                                  *StartingAddrStr;
3187   CHAR16                                  *EndingAddrStr;
3188   CHAR16                                  *TypeGuidStr;
3189   CHAR16                                  *InstanceStr;
3190   MEDIA_RAM_DISK_DEVICE_PATH              *RamDisk;
3191   UINT64                                  StartingAddr;
3192   UINT64                                  EndingAddr;
3193 
3194   StartingAddrStr = GetNextParamStr (&TextDeviceNode);
3195   EndingAddrStr   = GetNextParamStr (&TextDeviceNode);
3196   InstanceStr     = GetNextParamStr (&TextDeviceNode);
3197   TypeGuidStr     = GetNextParamStr (&TextDeviceNode);
3198   RamDisk         = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
3199                                                      MEDIA_DEVICE_PATH,
3200                                                      MEDIA_RAM_DISK_DP,
3201                                                      (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
3202                                                      );
3203 
3204   Strtoi64 (StartingAddrStr, &StartingAddr);
3205   WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
3206   Strtoi64 (EndingAddrStr, &EndingAddr);
3207   WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
3208   RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
3209   StrToGuid (TypeGuidStr, &RamDisk->TypeGuid);
3210 
3211   return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
3212 }
3213 
3214 /**
3215   Converts a text device path node to text virtual disk device path structure.
3216 
3217   @param TextDeviceNode  The input Text device path node.
3218 
3219   @return A pointer to the newly-created Text device path structure.
3220 
3221 **/
3222 static
3223 EFI_DEVICE_PATH_PROTOCOL *
3224 DevPathFromTextVirtualDisk (
3225   IN CHAR16 *TextDeviceNode
3226   )
3227 {
3228   CHAR16                                  *StartingAddrStr;
3229   CHAR16                                  *EndingAddrStr;
3230   CHAR16                                  *InstanceStr;
3231   MEDIA_RAM_DISK_DEVICE_PATH              *RamDisk;
3232   UINT64                                  StartingAddr;
3233   UINT64                                  EndingAddr;
3234 
3235   StartingAddrStr = GetNextParamStr (&TextDeviceNode);
3236   EndingAddrStr   = GetNextParamStr (&TextDeviceNode);
3237   InstanceStr     = GetNextParamStr (&TextDeviceNode);
3238 
3239   RamDisk         = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
3240                                                      MEDIA_DEVICE_PATH,
3241                                                      MEDIA_RAM_DISK_DP,
3242                                                      (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
3243                                                      );
3244 
3245   Strtoi64 (StartingAddrStr, &StartingAddr);
3246   WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
3247   Strtoi64 (EndingAddrStr, &EndingAddr);
3248   WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
3249   RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
3250   CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualDiskGuid);
3251 
3252   return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
3253 }
3254 
3255 /**
3256   Converts a text device path node to text virtual cd device path structure.
3257 
3258   @param TextDeviceNode  The input Text device path node.
3259 
3260   @return A pointer to the newly-created Text device path structure.
3261 
3262 **/
3263 static
3264 EFI_DEVICE_PATH_PROTOCOL *
3265 DevPathFromTextVirtualCd (
3266   IN CHAR16 *TextDeviceNode
3267   )
3268 {
3269   CHAR16                                  *StartingAddrStr;
3270   CHAR16                                  *EndingAddrStr;
3271   CHAR16                                  *InstanceStr;
3272   MEDIA_RAM_DISK_DEVICE_PATH              *RamDisk;
3273   UINT64                                  StartingAddr;
3274   UINT64                                  EndingAddr;
3275 
3276   StartingAddrStr = GetNextParamStr (&TextDeviceNode);
3277   EndingAddrStr   = GetNextParamStr (&TextDeviceNode);
3278   InstanceStr     = GetNextParamStr (&TextDeviceNode);
3279 
3280   RamDisk         = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
3281                                                      MEDIA_DEVICE_PATH,
3282                                                      MEDIA_RAM_DISK_DP,
3283                                                      (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
3284                                                      );
3285 
3286   Strtoi64 (StartingAddrStr, &StartingAddr);
3287   WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
3288   Strtoi64 (EndingAddrStr, &EndingAddr);
3289   WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
3290   RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
3291   CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualCdGuid);
3292 
3293   return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
3294 }
3295 
3296 /**
3297   Converts a text device path node to text persistent virtual disk device path structure.
3298 
3299   @param TextDeviceNode  The input Text device path node.
3300 
3301   @return A pointer to the newly-created Text device path structure.
3302 
3303 **/
3304 static
3305 EFI_DEVICE_PATH_PROTOCOL *
3306 DevPathFromTextPersistentVirtualDisk (
3307   IN CHAR16 *TextDeviceNode
3308   )
3309 {
3310   CHAR16                                  *StartingAddrStr;
3311   CHAR16                                  *EndingAddrStr;
3312   CHAR16                                  *InstanceStr;
3313   MEDIA_RAM_DISK_DEVICE_PATH              *RamDisk;
3314   UINT64                                  StartingAddr;
3315   UINT64                                  EndingAddr;
3316 
3317   StartingAddrStr = GetNextParamStr (&TextDeviceNode);
3318   EndingAddrStr   = GetNextParamStr (&TextDeviceNode);
3319   InstanceStr     = GetNextParamStr (&TextDeviceNode);
3320 
3321   RamDisk         = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
3322                                                      MEDIA_DEVICE_PATH,
3323                                                      MEDIA_RAM_DISK_DP,
3324                                                      (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
3325                                                      );
3326 
3327   Strtoi64 (StartingAddrStr, &StartingAddr);
3328   WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
3329   Strtoi64 (EndingAddrStr, &EndingAddr);
3330   WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
3331   RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
3332   CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualDiskGuid);
3333 
3334   return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
3335 }
3336 
3337 /**
3338   Converts a text device path node to text persistent virtual cd device path structure.
3339 
3340   @param TextDeviceNode  The input Text device path node.
3341 
3342   @return A pointer to the newly-created Text device path structure.
3343 
3344 **/
3345 static
3346 EFI_DEVICE_PATH_PROTOCOL *
3347 DevPathFromTextPersistentVirtualCd (
3348   IN CHAR16 *TextDeviceNode
3349   )
3350 {
3351   CHAR16                                  *StartingAddrStr;
3352   CHAR16                                  *EndingAddrStr;
3353   CHAR16                                  *InstanceStr;
3354   MEDIA_RAM_DISK_DEVICE_PATH              *RamDisk;
3355   UINT64                                  StartingAddr;
3356   UINT64                                  EndingAddr;
3357 
3358   StartingAddrStr = GetNextParamStr (&TextDeviceNode);
3359   EndingAddrStr   = GetNextParamStr (&TextDeviceNode);
3360   InstanceStr     = GetNextParamStr (&TextDeviceNode);
3361 
3362   RamDisk         = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
3363                                                      MEDIA_DEVICE_PATH,
3364                                                      MEDIA_RAM_DISK_DP,
3365                                                      (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
3366                                                      );
3367 
3368   Strtoi64 (StartingAddrStr, &StartingAddr);
3369   WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
3370   Strtoi64 (EndingAddrStr, &EndingAddr);
3371   WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
3372   RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
3373   CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualCdGuid);
3374 
3375   return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
3376 }
3377 
3378 /**
3379   Converts a BBS text device path node to BBS device path structure.
3380 
3381   @param TextDeviceNode  The input Text device path node.
3382 
3383   @return A pointer to BBS device path structure.
3384 
3385 **/
3386 static
3387 EFI_DEVICE_PATH_PROTOCOL *
3388 DevPathFromTextBbsPath (
3389   IN CHAR16 *TextDeviceNode
3390   )
3391 {
3392   return DevPathFromTextGenericPath (BBS_DEVICE_PATH, TextDeviceNode);
3393 }
3394 
3395 /**
3396   Converts a text device path node to BIOS Boot Specification device path structure.
3397 
3398   @param TextDeviceNode  The input Text device path node.
3399 
3400   @return A pointer to the newly-created BIOS Boot Specification device path structure.
3401 
3402 **/
3403 static
3404 EFI_DEVICE_PATH_PROTOCOL *
3405 DevPathFromTextBBS (
3406   IN CHAR16 *TextDeviceNode
3407   )
3408 {
3409   CHAR16              *TypeStr;
3410   CHAR16              *IdStr;
3411   CHAR16              *FlagsStr;
3412   CHAR8               *AsciiStr;
3413   BBS_BBS_DEVICE_PATH *Bbs;
3414 
3415   TypeStr   = GetNextParamStr (&TextDeviceNode);
3416   IdStr     = GetNextParamStr (&TextDeviceNode);
3417   FlagsStr  = GetNextParamStr (&TextDeviceNode);
3418   Bbs       = (BBS_BBS_DEVICE_PATH *) CreateDeviceNode (
3419                                         BBS_DEVICE_PATH,
3420                                         BBS_BBS_DP,
3421                                         (UINT16) (sizeof (BBS_BBS_DEVICE_PATH) + StrLen (IdStr))
3422                                         );
3423 
3424   if (StrCmp (TypeStr, "Floppy") == 0) {
3425     Bbs->DeviceType = BBS_TYPE_FLOPPY;
3426   } else if (StrCmp (TypeStr, "HD") == 0) {
3427     Bbs->DeviceType = BBS_TYPE_HARDDRIVE;
3428   } else if (StrCmp (TypeStr, "CDROM") == 0) {
3429     Bbs->DeviceType = BBS_TYPE_CDROM;
3430   } else if (StrCmp (TypeStr, "PCMCIA") == 0) {
3431     Bbs->DeviceType = BBS_TYPE_PCMCIA;
3432   } else if (StrCmp (TypeStr, "USB") == 0) {
3433     Bbs->DeviceType = BBS_TYPE_USB;
3434   } else if (StrCmp (TypeStr, "Network") == 0) {
3435     Bbs->DeviceType = BBS_TYPE_EMBEDDED_NETWORK;
3436   } else {
3437     Bbs->DeviceType = (UINT16) Strtoi (TypeStr);
3438   }
3439 
3440   AsciiStr = Bbs->String;
3441   StrToAscii (IdStr, &AsciiStr);
3442 
3443   Bbs->StatusFlag = (UINT16) Strtoi (FlagsStr);
3444 
3445   return (EFI_DEVICE_PATH_PROTOCOL *) Bbs;
3446 }
3447 
3448 /**
3449   Converts a text device path node to SATA device path structure.
3450 
3451   @param TextDeviceNode  The input Text device path node.
3452 
3453   @return A pointer to the newly-created SATA device path structure.
3454 
3455 **/
3456 static
3457 EFI_DEVICE_PATH_PROTOCOL *
3458 DevPathFromTextSata (
3459   IN CHAR16 *TextDeviceNode
3460   )
3461 {
3462   SATA_DEVICE_PATH *Sata;
3463   CHAR16           *Param1;
3464   CHAR16           *Param2;
3465   CHAR16           *Param3;
3466 
3467   Param1 = GetNextParamStr (&TextDeviceNode);
3468   Param2 = GetNextParamStr (&TextDeviceNode);
3469   Param3 = GetNextParamStr (&TextDeviceNode);
3470 
3471   Sata = (SATA_DEVICE_PATH *) CreateDeviceNode (
3472                                 MESSAGING_DEVICE_PATH,
3473                                 MSG_SATA_DP,
3474                                 (UINT16) sizeof (SATA_DEVICE_PATH)
3475                                 );
3476   Sata->HBAPortNumber            = (UINT16) Strtoi (Param1);
3477   Sata->PortMultiplierPortNumber = (UINT16) Strtoi (Param2);
3478   Sata->Lun                      = (UINT16) Strtoi (Param3);
3479 
3480   return (EFI_DEVICE_PATH_PROTOCOL *) Sata;
3481 }
3482 
3483 GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_FROM_TEXT_TABLE mUefiDevicePathLibDevPathFromTextTable[] = {
3484   {"Path",                    DevPathFromTextPath                    },
3485 
3486   {"HardwarePath",            DevPathFromTextHardwarePath            },
3487   {"Pci",                     DevPathFromTextPci                     },
3488   {"PcCard",                  DevPathFromTextPcCard                  },
3489   {"MemoryMapped",            DevPathFromTextMemoryMapped            },
3490   {"VenHw",                   DevPathFromTextVenHw                   },
3491   {"Ctrl",                    DevPathFromTextCtrl                    },
3492   {"BMC",                     DevPathFromTextBmc                     },
3493 
3494   {"AcpiPath",                DevPathFromTextAcpiPath                },
3495   {"Acpi",                    DevPathFromTextAcpi                    },
3496   {"PciRoot",                 DevPathFromTextPciRoot                 },
3497   {"PcieRoot",                DevPathFromTextPcieRoot                },
3498   {"Floppy",                  DevPathFromTextFloppy                  },
3499   {"Keyboard",                DevPathFromTextKeyboard                },
3500   {"Serial",                  DevPathFromTextSerial                  },
3501   {"ParallelPort",            DevPathFromTextParallelPort            },
3502   {"AcpiEx",                  DevPathFromTextAcpiEx                  },
3503   {"AcpiExp",                 DevPathFromTextAcpiExp                 },
3504   {"AcpiAdr",                 DevPathFromTextAcpiAdr                 },
3505 
3506   {"Msg",                     DevPathFromTextMsg                     },
3507   {"Ata",                     DevPathFromTextAta                     },
3508   {"Scsi",                    DevPathFromTextScsi                    },
3509   {"Fibre",                   DevPathFromTextFibre                   },
3510   {"FibreEx",                 DevPathFromTextFibreEx                 },
3511   {"I1394",                   DevPathFromText1394                    },
3512   {"USB",                     DevPathFromTextUsb                     },
3513   {"I2O",                     DevPathFromTextI2O                     },
3514   {"Infiniband",              DevPathFromTextInfiniband              },
3515   {"VenMsg",                  DevPathFromTextVenMsg                  },
3516   {"VenPcAnsi",               DevPathFromTextVenPcAnsi               },
3517   {"VenVt100",                DevPathFromTextVenVt100                },
3518   {"VenVt100Plus",            DevPathFromTextVenVt100Plus            },
3519   {"VenUtf8",                 DevPathFromTextVenUtf8                 },
3520   {"UartFlowCtrl",            DevPathFromTextUartFlowCtrl            },
3521   {"SAS",                     DevPathFromTextSAS                     },
3522   {"SasEx",                   DevPathFromTextSasEx                   },
3523   {"NVMe",                    DevPathFromTextNVMe                    },
3524   {"UFS",                     DevPathFromTextUfs                     },
3525   {"SD",                      DevPathFromTextSd                      },
3526   {"eMMC",                    DevPathFromTextEmmc                    },
3527   {"DebugPort",               DevPathFromTextDebugPort               },
3528   {"MAC",                     DevPathFromTextMAC                     },
3529   {"IPv4",                    DevPathFromTextIPv4                    },
3530   {"IPv6",                    DevPathFromTextIPv6                    },
3531   {"Uart",                    DevPathFromTextUart                    },
3532   {"UsbClass",                DevPathFromTextUsbClass                },
3533   {"UsbAudio",                DevPathFromTextUsbAudio                },
3534   {"UsbCDCControl",           DevPathFromTextUsbCDCControl           },
3535   {"UsbHID",                  DevPathFromTextUsbHID                  },
3536   {"UsbImage",                DevPathFromTextUsbImage                },
3537   {"UsbPrinter",              DevPathFromTextUsbPrinter              },
3538   {"UsbMassStorage",          DevPathFromTextUsbMassStorage          },
3539   {"UsbHub",                  DevPathFromTextUsbHub                  },
3540   {"UsbCDCData",              DevPathFromTextUsbCDCData              },
3541   {"UsbSmartCard",            DevPathFromTextUsbSmartCard            },
3542   {"UsbVideo",                DevPathFromTextUsbVideo                },
3543   {"UsbDiagnostic",           DevPathFromTextUsbDiagnostic           },
3544   {"UsbWireless",             DevPathFromTextUsbWireless             },
3545   {"UsbDeviceFirmwareUpdate", DevPathFromTextUsbDeviceFirmwareUpdate },
3546   {"UsbIrdaBridge",           DevPathFromTextUsbIrdaBridge           },
3547   {"UsbTestAndMeasurement",   DevPathFromTextUsbTestAndMeasurement   },
3548   {"UsbWwid",                 DevPathFromTextUsbWwid                 },
3549   {"Unit",                    DevPathFromTextUnit                    },
3550   {"iSCSI",                   DevPathFromTextiSCSI                   },
3551   {"Vlan",                    DevPathFromTextVlan                    },
3552   {"Uri",                     DevPathFromTextUri                     },
3553   {"Bluetooth",               DevPathFromTextBluetooth               },
3554   {"Wi-Fi",                   DevPathFromTextWiFi                    },
3555   {"MediaPath",               DevPathFromTextMediaPath               },
3556   {"HD",                      DevPathFromTextHD                      },
3557   {"CDROM",                   DevPathFromTextCDROM                   },
3558   {"VenMedia",                DevPathFromTextVenMedia                },
3559   {"Media",                   DevPathFromTextMedia                   },
3560   {"Fv",                      DevPathFromTextFv                      },
3561   {"FvFile",                  DevPathFromTextFvFile                  },
3562   {"File",                    DevPathFromTextFilePath                },
3563   {"Offset",                  DevPathFromTextRelativeOffsetRange     },
3564   {"RamDisk",                 DevPathFromTextRamDisk                 },
3565   {"VirtualDisk",             DevPathFromTextVirtualDisk             },
3566   {"VirtualCD",               DevPathFromTextVirtualCd               },
3567   {"PersistentVirtualDisk",   DevPathFromTextPersistentVirtualDisk   },
3568   {"PersistentVirtualCD",     DevPathFromTextPersistentVirtualCd     },
3569 
3570   {"BbsPath",                 DevPathFromTextBbsPath                 },
3571   {"BBS",                     DevPathFromTextBBS                     },
3572   {"Sata",                    DevPathFromTextSata                    },
3573   {NULL, NULL}
3574 };
3575 
3576 /**
3577   Convert text to the binary representation of a device node.
3578 
3579   @param TextDeviceNode  TextDeviceNode points to the text representation of a device
3580                          node. Conversion starts with the first character and continues
3581                          until the first non-device node character.
3582 
3583   @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
3584           insufficient memory or text unsupported.
3585 
3586 **/
3587 static
3588 EFI_DEVICE_PATH_PROTOCOL *
3589 EFIAPI
3590 UefiDevicePathLibConvertTextToDeviceNode (
3591   IN CONST CHAR16 *TextDeviceNode
3592   )
3593 {
3594   DEVICE_PATH_FROM_TEXT    FromText;
3595   CHAR16                   *ParamStr;
3596   EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
3597   CHAR16                   *DeviceNodeStr;
3598   UINTN                    Index;
3599 
3600   if ((TextDeviceNode == NULL) || (IS_NULL (*TextDeviceNode))) {
3601     return NULL;
3602   }
3603 
3604   ParamStr      = NULL;
3605   FromText      = NULL;
3606   DeviceNodeStr = UefiDevicePathLibStrDuplicate (TextDeviceNode);
3607   ASSERT (DeviceNodeStr != NULL);
3608 
3609   for (Index = 0; mUefiDevicePathLibDevPathFromTextTable[Index].Function != NULL; Index++) {
3610     ParamStr = GetParamByNodeName (DeviceNodeStr, mUefiDevicePathLibDevPathFromTextTable[Index].DevicePathNodeText);
3611     if (ParamStr != NULL) {
3612       FromText = mUefiDevicePathLibDevPathFromTextTable[Index].Function;
3613       break;
3614     }
3615   }
3616 
3617   if (FromText == NULL) {
3618     //
3619     // A file path
3620     //
3621     FromText = DevPathFromTextFilePath;
3622     DeviceNode = FromText (DeviceNodeStr);
3623   } else {
3624     DeviceNode = FromText (ParamStr);
3625     FreePool (ParamStr);
3626   }
3627 
3628   FreePool (DeviceNodeStr);
3629 
3630   return DeviceNode;
3631 }
3632 
3633 /**
3634   Convert text to the binary representation of a device path.
3635 
3636 
3637   @param TextDevicePath  TextDevicePath points to the text representation of a device
3638                          path. Conversion starts with the first character and continues
3639                          until the first non-device node character.
3640 
3641   @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
3642           there was insufficient memory.
3643 
3644 **/
3645 static
3646 EFI_DEVICE_PATH_PROTOCOL *
3647 EFIAPI
3648 UefiDevicePathLibConvertTextToDevicePath (
3649   IN CONST CHAR16 *TextDevicePath
3650   )
3651 {
3652   EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
3653   EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
3654   CHAR16                   *DevicePathStr;
3655   CHAR16                   *Str;
3656   CHAR16                   *DeviceNodeStr;
3657   BOOLEAN                  IsInstanceEnd;
3658   EFI_DEVICE_PATH_PROTOCOL *DevicePath;
3659 
3660   if ((TextDevicePath == NULL) || (IS_NULL (*TextDevicePath))) {
3661     return NULL;
3662   }
3663 
3664   DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
3665   ASSERT (DevicePath != NULL);
3666   SetDevicePathEndNode (DevicePath);
3667 
3668   DevicePathStr = UefiDevicePathLibStrDuplicate (TextDevicePath);
3669 
3670   Str           = DevicePathStr;
3671   while ((DeviceNodeStr = GetNextDeviceNodeStr (&Str, &IsInstanceEnd)) != NULL) {
3672     DeviceNode = UefiDevicePathLibConvertTextToDeviceNode (DeviceNodeStr);
3673 
3674     NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);
3675     FreePool (DevicePath);
3676     FreePool (DeviceNode);
3677     DevicePath = NewDevicePath;
3678 
3679     if (IsInstanceEnd) {
3680       DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
3681       ASSERT (DeviceNode != NULL);
3682       SetDevicePathEndNode (DeviceNode);
3683       DeviceNode->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
3684 
3685       NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);
3686       FreePool (DevicePath);
3687       FreePool (DeviceNode);
3688       DevicePath = NewDevicePath;
3689     }
3690   }
3691 
3692   FreePool (DevicePathStr);
3693   return DevicePath;
3694 }
3695 
3696 ssize_t
3697 efidp_parse_device_path(char *path, efidp out, size_t max)
3698 {
3699 	EFI_DEVICE_PATH_PROTOCOL *dp;
3700 	UINTN len;
3701 
3702 	dp = UefiDevicePathLibConvertTextToDevicePath (path);
3703 	if (dp == NULL)
3704 		return -1;
3705 	len = GetDevicePathSize(dp);
3706 	if (len > max) {
3707 		free(dp);
3708 		return -1;
3709 	}
3710 	memcpy(out, dp, len);
3711 	free(dp);
3712 
3713 	return len;
3714 }
3715