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