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