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