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