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