TianoCore EDK2 master
Loading...
Searching...
No Matches
UefiShellBcfgCommandLib.c
Go to the documentation of this file.
1
10#include <Uefi.h>
11
12#include <Guid/GlobalVariable.h>
14
15#include <Protocol/Shell.h>
17#include <Protocol/DevicePath.h>
20
21#include <Library/BaseLib.h>
23#include <Library/DebugLib.h>
25#include <Library/PcdLib.h>
27#include <Library/ShellLib.h>
28#include <Library/SortLib.h>
29#include <Library/UefiLib.h>
32#include <Library/HiiLib.h>
34#include <Library/PrintLib.h>
38
39STATIC CONST CHAR16 mFileName[] = L"ShellCommands";
40STATIC EFI_HII_HANDLE gShellBcfgHiiHandle = NULL;
41
42typedef enum {
43 BcfgTargetBootOrder = 0,
44 BcfgTargetDriverOrder = 1,
45 BcfgTargetMax = 2
46} BCFG_OPERATION_TARGET;
47
48typedef enum {
49 BcfgTypeDump = 0,
50 BcfgTypeAdd = 1,
51 BcfgTypeAddp = 2,
52 BcfgTypeAddh = 3,
53 BcfgTypeRm = 4,
54 BcfgTypeMv = 5,
55 BcfgTypeOpt = 6,
56 BcfgTypeMod = 7,
57 BcfgTypeModf = 8,
58 BcfgTypeModp = 9,
59 BcfgTypeModh = 10,
60 BcfgTypeMax = 11
61} BCFG_OPERATION_TYPE;
62
63typedef struct {
64 BCFG_OPERATION_TARGET Target;
65 BCFG_OPERATION_TYPE Type;
66 UINT16 Number1;
67 UINT16 Number2;
68 UINTN HandleIndex;
69 CHAR16 *FileName;
70 CHAR16 *Description;
71 UINT16 *Order;
72 CONST CHAR16 *OptData;
74
90 UINT16 Index,
91 UINTN DataSize,
92 UINT8 *Data,
93 IN CONST BCFG_OPERATION_TARGET Target
94 )
95{
96 EFI_STATUS Status;
97 CHAR16 VariableName[12];
98 UINTN OriginalSize;
99 UINT8 *OriginalData;
100 UINTN NewSize;
101 UINT8 *NewData;
102 UINTN TmpSize;
103 UINTN OriginalOptionDataSize;
104
105 UnicodeSPrint (VariableName, sizeof (VariableName), L"%s%04x", Target == BcfgTargetBootOrder ? L"Boot" : L"Driver", Index);
106
107 OriginalSize = 0;
108 OriginalData = NULL;
109 NewData = NULL;
110 NewSize = 0;
111
112 Status = gRT->GetVariable (
113 VariableName,
114 (EFI_GUID *)&gEfiGlobalVariableGuid,
115 NULL,
116 &OriginalSize,
117 OriginalData
118 );
119 if (Status == EFI_BUFFER_TOO_SMALL) {
120 OriginalData = AllocateZeroPool (OriginalSize);
121 if (OriginalData == NULL) {
122 return (EFI_OUT_OF_RESOURCES);
123 }
124
125 Status = gRT->GetVariable (
126 VariableName,
127 (EFI_GUID *)&gEfiGlobalVariableGuid,
128 NULL,
129 &OriginalSize,
130 OriginalData
131 );
132 }
133
134 if (!EFI_ERROR (Status)) {
135 //
136 // Allocate new struct and discard old optional data.
137 //
138 ASSERT (OriginalData != NULL);
139 // Length of Attributes, FilePathListLength, Description fields
140 TmpSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (((CHAR16 *)(OriginalData + sizeof (UINT32) + sizeof (UINT16))));
141 // Length of FilePathList field
142 TmpSize += (*(UINT16 *)(OriginalData + sizeof (UINT32)));
143 // What remains is the original OptionalData field
144 OriginalOptionDataSize = OriginalSize - TmpSize;
145 NewSize = OriginalSize - OriginalOptionDataSize + DataSize;
146 NewData = AllocatePool (NewSize);
147 if (NewData == NULL) {
148 Status = EFI_OUT_OF_RESOURCES;
149 } else {
150 CopyMem (NewData, OriginalData, OriginalSize - OriginalOptionDataSize);
151 CopyMem (NewData + OriginalSize - OriginalOptionDataSize, Data, DataSize);
152 }
153 }
154
155 if (!EFI_ERROR (Status)) {
156 //
157 // put the data back under the variable
158 //
159 Status = gRT->SetVariable (
160 VariableName,
161 (EFI_GUID *)&gEfiGlobalVariableGuid,
162 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
163 NewSize,
164 NewData
165 );
166 }
167
168 SHELL_FREE_NON_NULL (OriginalData);
169 SHELL_FREE_NON_NULL (NewData);
170 return (Status);
171}
172
184 UINT32 *Crc,
185 UINT16 BootIndex
186 )
187{
188 CHAR16 VariableName[12];
189 EFI_STATUS Status;
190 UINT8 *Buffer;
191 UINTN BufferSize;
192
193 Buffer = NULL;
194 BufferSize = 0;
195
196 //
197 // Get the data Buffer
198 //
199 UnicodeSPrint (VariableName, sizeof (VariableName), L"%Boot%04x", BootIndex);
200 Status = gRT->GetVariable (
201 VariableName,
202 (EFI_GUID *)&gEfiGlobalVariableGuid,
203 NULL,
204 &BufferSize,
205 NULL
206 );
207 if (Status == EFI_BUFFER_TOO_SMALL) {
208 Buffer = AllocateZeroPool (BufferSize);
209 if (Buffer == NULL) {
210 return EFI_OUT_OF_RESOURCES;
211 }
212
213 Status = gRT->GetVariable (
214 VariableName,
215 (EFI_GUID *)&gEfiGlobalVariableGuid,
216 NULL,
217 &BufferSize,
218 Buffer
219 );
220 }
221
222 //
223 // Get the CRC computed
224 //
225 if (!EFI_ERROR (Status)) {
226 Status = gBS->CalculateCrc32 (Buffer, BufferSize, Crc);
227 }
228
229 SHELL_FREE_NON_NULL (Buffer);
230 return EFI_SUCCESS;
231}
232
246 IN EFI_HANDLE TheHandle,
248 )
249{
250 EFI_STATUS Status;
251 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
252 EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
253
254 Status = gBS->OpenProtocol (
255 TheHandle,
256 &gEfiLoadedImageProtocolGuid,
257 (VOID **)&LoadedImage,
259 NULL,
260 EFI_OPEN_PROTOCOL_GET_PROTOCOL
261 );
262 if (!EFI_ERROR (Status)) {
263 Status = gBS->OpenProtocol (
264 LoadedImage->DeviceHandle,
265 &gEfiDevicePathProtocolGuid,
266 (VOID **)&ImageDevicePath,
268 NULL,
269 EFI_OPEN_PROTOCOL_GET_PROTOCOL
270 );
271 if (!EFI_ERROR (Status)) {
272 // *DevPath = DuplicateDevicePath (ImageDevicePath);
273 // *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
274 *FilePath = AppendDevicePath (ImageDevicePath, LoadedImage->FilePath);
275 gBS->CloseProtocol (
276 LoadedImage->DeviceHandle,
277 &gEfiDevicePathProtocolGuid,
279 NULL
280 );
281 }
282
283 gBS->CloseProtocol (
284 TheHandle,
285 &gEfiLoadedImageProtocolGuid,
287 NULL
288 );
289 }
290
291 return (Status);
292}
293
307 IN EFI_HANDLE TheHandle,
308 IN BCFG_OPERATION_TARGET Target,
309 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
310 )
311{
312 EFI_STATUS Status;
313 SHELL_STATUS ShellStatus;
314
315 UINTN DriverBindingHandleCount;
316 UINTN ParentControllerHandleCount;
317 UINTN ChildControllerHandleCount;
318
319 ShellStatus = SHELL_SUCCESS;
320
321 if (TheHandle == NULL) {
322 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");
324 }
325
326 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (TheHandle, &DriverBindingHandleCount, NULL);
327 if (EFI_ERROR (Status)) {
328 DriverBindingHandleCount = 0;
329 }
330
331 Status = PARSE_HANDLE_DATABASE_PARENTS (TheHandle, &ParentControllerHandleCount, NULL);
332 if (EFI_ERROR (Status)) {
333 ParentControllerHandleCount = 0;
334 }
335
336 Status = ParseHandleDatabaseForChildControllers (TheHandle, &ChildControllerHandleCount, NULL);
337 if (EFI_ERROR (Status)) {
338 ChildControllerHandleCount = 0;
339 }
340
341 Status = gBS->HandleProtocol (TheHandle, &gEfiDevicePathProtocolGuid, (VOID **)DevicePath);
342
343 if ((DriverBindingHandleCount > 0) ||
344 (ParentControllerHandleCount > 0) ||
345 (ChildControllerHandleCount > 0) ||
346 !EFI_ERROR (Status)
347 )
348 {
349 //
350 // The handle points to a real controller which has a device path.
351 //
352 if (Target == BcfgTargetDriverOrder) {
354 -1,
355 -1,
356 NULL,
357 STRING_TOKEN (STR_GEN_PARAM_INV),
358 gShellBcfgHiiHandle,
359 L"bcfg",
360 L"Handle should point to driver image."
361 );
362 ShellStatus = SHELL_NOT_FOUND;
363 }
364 } else {
365 //
366 // The handle points to a driver image.
367 //
368 if (Target == BcfgTargetBootOrder) {
370 -1,
371 -1,
372 NULL,
373 STRING_TOKEN (STR_GEN_PARAM_INV),
374 gShellBcfgHiiHandle,
375 L"bcfg",
376 L"Handle should point to controller."
377 );
378 ShellStatus = SHELL_NOT_FOUND;
379 } else {
380 if (EFI_ERROR (GetDevicePathForDriverHandle (TheHandle, DevicePath))) {
381 ShellStatus = SHELL_NOT_FOUND;
382 }
383 }
384 }
385
386 return (ShellStatus);
387}
388
401 IN CONST BGFG_OPERATION *BcfgOperation,
402 IN CONST UINTN OrderCount
403 )
404{
405 EFI_STATUS Status;
406 EFI_HANDLE CurHandle;
407 SHELL_STATUS ShellStatus;
408 CHAR16 OptionStr[40];
409 EFI_SHELL_FILE_INFO *FileList;
411 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
412 EFI_DEVICE_PATH_PROTOCOL *DevicePathBuffer;
413 EFI_DEVICE_PATH_PROTOCOL *DevicePathWalker;
415
416 ShellStatus = SHELL_SUCCESS;
417 FileList = NULL;
418 DevicePath = NULL;
419 DevicePathBuffer = NULL;
420
421 ZeroMem (&LoadOption, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION));
422
423 if (((BcfgOperation->Type == BcfgTypeMod) && (BcfgOperation->Description == NULL)) ||
424 ((BcfgOperation->Type == BcfgTypeModf) && (BcfgOperation->FileName == NULL)) ||
425 ((BcfgOperation->Type == BcfgTypeModp) && (BcfgOperation->FileName == NULL)) ||
426 ((BcfgOperation->Type == BcfgTypeModh) && (BcfgOperation->HandleIndex == 0)) ||
427 (BcfgOperation->Number1 > OrderCount)
428 )
429 {
431 }
432
433 if (BcfgOperation->Type == BcfgTypeModh) {
434 CurHandle = ConvertHandleIndexToHandle (BcfgOperation->HandleIndex);
435 if (CurHandle == NULL) {
436 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");
438 }
439
440 ShellStatus = GetDevicePathByHandle (CurHandle, BcfgOperation->Target, &DevicePathBuffer);
441 if (ShellStatus == SHELL_SUCCESS) {
442 DevicePath = DuplicateDevicePath (DevicePathBuffer);
443 }
444 } else if ((BcfgOperation->Type == BcfgTypeModf) || (BcfgOperation->Type == BcfgTypeModp)) {
445 //
446 // Get Device Path by FileName.
447 //
448 ShellOpenFileMetaArg ((CHAR16 *)BcfgOperation->FileName, EFI_FILE_MODE_READ, &FileList);
449 if (FileList == NULL) {
450 //
451 // The name of file matched nothing.
452 //
453 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);
454 ShellStatus = SHELL_INVALID_PARAMETER;
455 } else if (FileList->Link.ForwardLink != FileList->Link.BackLink) {
456 //
457 // If the name of file expanded to multiple names, it's fail.
458 //
459 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);
460 ShellStatus = SHELL_INVALID_PARAMETER;
461 } else {
462 Arg = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link);
463 if (EFI_ERROR (Arg->Status)) {
464 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);
465 ShellStatus = SHELL_INVALID_PARAMETER;
466 } else {
467 DevicePathBuffer = gEfiShellProtocol->GetDevicePathFromFilePath (Arg->FullName);
468 if (DevicePathBuffer == NULL) {
469 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellBcfgHiiHandle, L"bcfg", Arg->FullName);
470 ShellStatus = SHELL_UNSUPPORTED;
471 }
472 }
473 }
474
475 if (ShellStatus == SHELL_SUCCESS) {
476 if (BcfgOperation->Type == BcfgTypeModp) {
477 ShellStatus = SHELL_INVALID_PARAMETER;
478 DevicePathWalker = DevicePathBuffer;
479 while (!IsDevicePathEnd (DevicePathWalker)) {
480 if ((DevicePathType (DevicePathWalker) == MEDIA_DEVICE_PATH) &&
481 (DevicePathSubType (DevicePathWalker) == MEDIA_HARDDRIVE_DP)
482 )
483 {
484 //
485 // We found the portion of device path starting with the hard driver partition.
486 //
487 ShellStatus = SHELL_SUCCESS;
488 DevicePath = DuplicateDevicePath (DevicePathWalker);
489 break;
490 } else {
491 DevicePathWalker = NextDevicePathNode (DevicePathWalker);
492 }
493 }
494 } else {
495 DevicePath = DuplicateDevicePath (DevicePathBuffer);
496 }
497
498 FreePool (DevicePathBuffer);
499 }
500 }
501
502 if (ShellStatus == SHELL_SUCCESS) {
503 if (BcfgOperation->Target == BcfgTargetBootOrder) {
504 UnicodeSPrint (OptionStr, sizeof (OptionStr), L"Boot%04x", BcfgOperation->Order[BcfgOperation->Number1]);
505 } else {
506 UnicodeSPrint (OptionStr, sizeof (OptionStr), L"Driver%04x", BcfgOperation->Order[BcfgOperation->Number1]);
507 }
508
509 Status = EfiBootManagerVariableToLoadOption (OptionStr, &LoadOption);
510 if (EFI_ERROR (Status)) {
511 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NONE), gShellBcfgHiiHandle);
512 ShellStatus = SHELL_NOT_FOUND;
513 }
514 }
515
516 if (ShellStatus == SHELL_SUCCESS) {
517 if (BcfgOperation->Type == BcfgTypeMod) {
518 SHELL_FREE_NON_NULL (LoadOption.Description);
519 LoadOption.Description = AllocateCopyPool (StrSize (BcfgOperation->Description), BcfgOperation->Description);
520 } else {
521 SHELL_FREE_NON_NULL (LoadOption.FilePath);
522 if (DevicePath != NULL) {
523 LoadOption.FilePath = DuplicateDevicePath (DevicePath);
524 } else {
525 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (SHELL_OUT_OF_RESOURCES), gShellBcfgHiiHandle, L"bcfg", OptionStr);
526 goto Done;
527 }
528 }
529
530 Status = EfiBootManagerLoadOptionToVariable (&LoadOption);
531 if (EFI_ERROR (Status)) {
532 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", OptionStr);
533 ShellStatus = SHELL_INVALID_PARAMETER;
534 }
535 }
536
537 EfiBootManagerFreeLoadOption (&LoadOption);
538
539Done:
540
541 if (DevicePath != NULL) {
542 FreePool (DevicePath);
543 }
544
545 if (FileList != NULL) {
546 ShellCloseFileMetaArg (&FileList);
547 }
548
549 return (ShellStatus);
550}
551
570 IN UINTN Position,
571 IN CONST CHAR16 *File,
572 IN CONST CHAR16 *Desc,
573 IN CONST UINT16 *CurrentOrder,
574 IN CONST UINTN OrderCount,
575 IN CONST BCFG_OPERATION_TARGET Target,
576 IN CONST BOOLEAN UseHandle,
577 IN CONST BOOLEAN UsePath,
578 IN CONST UINTN HandleNumber
579 )
580{
581 EFI_STATUS Status;
582 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
584 EFI_DEVICE_PATH_PROTOCOL *FilePath;
585 CHAR16 *Str;
586 UINT8 *TempByteBuffer;
587 UINT8 *TempByteStart;
589 EFI_SHELL_FILE_INFO *FileList;
590 CHAR16 OptionStr[40];
591 UINTN DescSize, FilePathSize;
592 BOOLEAN Found;
593 UINTN TargetLocation;
594 UINTN Index;
595 EFI_HANDLE *Handles;
596 EFI_HANDLE CurHandle;
597 UINTN DriverBindingHandleCount;
598 UINTN ParentControllerHandleCount;
599 UINTN ChildControllerHandleCount;
600 SHELL_STATUS ShellStatus;
601 UINT16 *NewOrder;
602
603 if (!UseHandle) {
604 if ((File == NULL) || (Desc == NULL)) {
606 }
607 } else {
608 if (HandleNumber == 0) {
610 }
611 }
612
613 if (Position > OrderCount) {
614 Position = OrderCount;
615 }
616
617 Str = NULL;
618 FilePath = NULL;
619 FileList = NULL;
620 Handles = NULL;
621 ShellStatus = SHELL_SUCCESS;
622 TargetLocation = 0xFFFF;
623
624 if (UseHandle) {
625 CurHandle = ConvertHandleIndexToHandle (HandleNumber);
626 if (CurHandle == NULL) {
627 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");
628 ShellStatus = SHELL_INVALID_PARAMETER;
629 } else {
630 if (Target == BcfgTargetBootOrder) {
631 //
632 // Make sure that the handle should point to a real controller
633 //
635 CurHandle,
636 &DriverBindingHandleCount,
637 NULL
638 );
639
641 CurHandle,
642 &ParentControllerHandleCount,
643 NULL
644 );
645
647 CurHandle,
648 &ChildControllerHandleCount,
649 NULL
650 );
651
652 if ( (DriverBindingHandleCount > 0)
653 || (ParentControllerHandleCount > 0)
654 || (ChildControllerHandleCount > 0))
655 {
656 FilePath = NULL;
657 Status = gBS->HandleProtocol (
658 CurHandle,
659 &gEfiDevicePathProtocolGuid,
660 (VOID **)&FilePath
661 );
662 }
663
664 if (EFI_ERROR (Status)) {
665 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_HANDLE), gShellBcfgHiiHandle, L"bcfg", HandleNumber);
666 ShellStatus = SHELL_INVALID_PARAMETER;
667 }
668 } else {
669 //
670 // Make sure that the handle should point to driver, not a controller.
671 //
673 CurHandle,
674 &DriverBindingHandleCount,
675 NULL
676 );
677
679 CurHandle,
680 &ParentControllerHandleCount,
681 NULL
682 );
683
685 CurHandle,
686 &ChildControllerHandleCount,
687 NULL
688 );
689
690 Status = gBS->HandleProtocol (
691 CurHandle,
692 &gEfiDevicePathProtocolGuid,
693 (VOID **)&FilePath
694 );
695
696 if ( (DriverBindingHandleCount > 0)
697 || (ParentControllerHandleCount > 0)
698 || (ChildControllerHandleCount > 0)
699 || !EFI_ERROR (Status))
700 {
701 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");
702 ShellStatus = SHELL_INVALID_PARAMETER;
703 } else {
704 //
705 // Get the DevicePath from the loaded image information.
706 //
707 Status = GetDevicePathForDriverHandle (CurHandle, &FilePath);
708 }
709 }
710 }
711 } else {
712 //
713 // Get file info
714 //
715 ShellOpenFileMetaArg ((CHAR16 *)File, EFI_FILE_MODE_READ, &FileList);
716
717 if (FileList == NULL) {
718 //
719 // If filename matched nothing fail
720 //
721 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellBcfgHiiHandle, L"bcfg", File);
722 ShellStatus = SHELL_INVALID_PARAMETER;
723 } else if (FileList->Link.ForwardLink != FileList->Link.BackLink) {
724 //
725 // If filename expanded to multiple names, fail
726 //
727 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellBcfgHiiHandle, L"bcfg", File);
728 ShellStatus = SHELL_INVALID_PARAMETER;
729 } else {
730 Arg = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link);
731 if (EFI_ERROR (Arg->Status)) {
732 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellBcfgHiiHandle, L"bcfg", File);
733 ShellStatus = SHELL_INVALID_PARAMETER;
734 } else {
735 //
736 // Build FilePath to the filename
737 //
738
739 //
740 // get the device path
741 //
742 DevicePath = gEfiShellProtocol->GetDevicePathFromFilePath (Arg->FullName);
743 if (DevicePath == NULL) {
744 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellBcfgHiiHandle, L"bcfg", Arg->FullName);
745 ShellStatus = SHELL_UNSUPPORTED;
746 } else {
747 if (UsePath) {
748 DevPath = DevicePath;
749 ShellStatus = SHELL_INVALID_PARAMETER;
750 while (!IsDevicePathEnd (DevPath)) {
751 if ((DevicePathType (DevPath) == MEDIA_DEVICE_PATH) &&
753 {
754 //
755 // If we find it use it instead
756 //
757 ShellStatus = SHELL_SUCCESS;
758 FilePath = DuplicateDevicePath (DevPath);
759 break;
760 }
761
762 DevPath = NextDevicePathNode (DevPath);
763 }
764 } else {
765 FilePath = DuplicateDevicePath (DevicePath);
766 }
767
768 FreePool (DevicePath);
769 }
770 }
771 }
772 }
773
774 if (ShellStatus == SHELL_SUCCESS) {
775 //
776 // Find a free target ,a brute force implementation
777 //
778 Found = FALSE;
779 for (TargetLocation = 0; TargetLocation < 0xFFFF; TargetLocation++) {
780 Found = TRUE;
781 for (Index = 0; Index < OrderCount; Index++) {
782 if (CurrentOrder[Index] == TargetLocation) {
783 Found = FALSE;
784 break;
785 }
786 }
787
788 if (Found) {
789 break;
790 }
791 }
792
793 if (TargetLocation == 0xFFFF) {
794 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET_NF), gShellBcfgHiiHandle, L"bcfg");
795 } else {
796 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET), gShellBcfgHiiHandle, TargetLocation);
797 }
798 }
799
800 if (ShellStatus == SHELL_SUCCESS) {
801 //
802 // Add the option
803 //
804 DescSize = StrSize (Desc);
805 if (FilePath == NULL) {
806 ASSERT (FilePath != NULL);
807 ShellStatus = SHELL_UNSUPPORTED;
808 TempByteBuffer = NULL;
809 } else {
810 FilePathSize = GetDevicePathSize (FilePath);
811
812 TempByteBuffer = AllocateZeroPool (sizeof (UINT32) + sizeof (UINT16) + DescSize + FilePathSize);
813 }
814
815 if (TempByteBuffer != NULL) {
816 TempByteStart = TempByteBuffer;
817 *((UINT32 *)TempByteBuffer) = LOAD_OPTION_ACTIVE; // Attributes
818 TempByteBuffer += sizeof (UINT32);
819
820 *((UINT16 *)TempByteBuffer) = (UINT16)FilePathSize; // FilePathListLength
821 TempByteBuffer += sizeof (UINT16);
822
823 CopyMem (TempByteBuffer, Desc, DescSize);
824 TempByteBuffer += DescSize;
825 ASSERT (FilePath != NULL);
826 CopyMem (TempByteBuffer, FilePath, FilePathSize);
827
828 UnicodeSPrint (OptionStr, sizeof (OptionStr), L"%s%04x", Target == BcfgTargetBootOrder ? L"Boot" : L"Driver", TargetLocation);
829 Status = gRT->SetVariable (
830 OptionStr,
831 &gEfiGlobalVariableGuid,
832 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
833 sizeof (UINT32) + sizeof (UINT16) + DescSize + FilePathSize,
834 TempByteStart
835 );
836
837 FreePool (TempByteStart);
838 } else {
839 Status = EFI_OUT_OF_RESOURCES;
840 }
841
842 if (EFI_ERROR (Status)) {
843 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", OptionStr);
844 } else {
845 NewOrder = AllocateZeroPool ((OrderCount + 1) * sizeof (NewOrder[0]));
846 if (NewOrder != NULL) {
847 CopyMem (NewOrder, CurrentOrder, (OrderCount) * sizeof (NewOrder[0]));
848
849 //
850 // Insert target into order list
851 //
852 for (Index = OrderCount; Index > Position; Index--) {
853 NewOrder[Index] = NewOrder[Index - 1];
854 }
855
856 NewOrder[Position] = (UINT16)TargetLocation;
857 Status = gRT->SetVariable (
858 Target == BcfgTargetBootOrder ? L"BootOrder" : L"DriverOrder",
859 &gEfiGlobalVariableGuid,
860 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
861 (OrderCount + 1) * sizeof (UINT16),
862 NewOrder
863 );
864
865 FreePool (NewOrder);
866
867 if (EFI_ERROR (Status)) {
868 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder ? L"BootOrder" : L"DriverOrder");
869 ShellStatus = SHELL_INVALID_PARAMETER;
870 } else {
871 Print (L"bcfg: Add %s as %x\n", OptionStr, Position);
872 }
873 }
874 }
875 }
876
877 //
878 // If always Free FilePath, will free devicepath in system when use "addh"
879 //
880 if ((FilePath != NULL) && !UseHandle) {
881 FreePool (FilePath);
882 }
883
884 if (Str != NULL) {
885 FreePool (Str);
886 }
887
888 if (Handles != NULL) {
889 FreePool (Handles);
890 }
891
892 if (FileList != NULL) {
893 ShellCloseFileMetaArg (&FileList);
894 }
895
896 return (ShellStatus);
897}
898
912 IN CONST BCFG_OPERATION_TARGET Target,
913 IN CONST UINT16 *CurrentOrder,
914 IN CONST UINTN OrderCount,
915 IN CONST UINT16 Location
916 )
917{
918 CHAR16 VariableName[12];
919 UINT16 *NewOrder;
920 EFI_STATUS Status;
921 UINTN NewCount;
922
923 UnicodeSPrint (VariableName, sizeof (VariableName), L"%s%04x", Target == BcfgTargetBootOrder ? L"Boot" : L"Driver", CurrentOrder[Location]);
924 Status = gRT->SetVariable (
925 VariableName,
926 (EFI_GUID *)&gEfiGlobalVariableGuid,
927 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
928 0,
929 NULL
930 );
931 if (EFI_ERROR (Status)) {
932 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
934 }
935
936 NewOrder = AllocateZeroPool (OrderCount*sizeof (CurrentOrder[0]));
937 if (NewOrder != NULL) {
938 NewCount = OrderCount;
939 CopyMem (NewOrder, CurrentOrder, OrderCount*sizeof (CurrentOrder[0]));
940 CopyMem (NewOrder+Location, NewOrder+Location+1, (OrderCount - Location - 1)*sizeof (CurrentOrder[0]));
941 NewCount--;
942
943 Status = gRT->SetVariable (
944 Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
945 (EFI_GUID *)&gEfiGlobalVariableGuid,
946 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
947 NewCount*sizeof (NewOrder[0]),
948 NewOrder
949 );
950 FreePool (NewOrder);
951 } else {
952 Status = EFI_OUT_OF_RESOURCES;
953 }
954
955 if (EFI_ERROR (Status)) {
956 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder");
958 }
959
960 return (SHELL_SUCCESS);
961}
962
977 IN CONST BCFG_OPERATION_TARGET Target,
978 IN CONST UINT16 *CurrentOrder,
979 IN CONST UINTN OrderCount,
980 IN CONST UINT16 OldLocation,
981 IN UINT16 NewLocation
982 )
983{
984 UINT16 *NewOrder;
985 EFI_STATUS Status;
986 UINT16 Temp;
987
988 NewOrder = AllocateCopyPool (OrderCount*sizeof (CurrentOrder[0]), CurrentOrder);
989 if (NewOrder == NULL) {
990 return (SHELL_OUT_OF_RESOURCES);
991 }
992
993 //
994 // correct the new location
995 //
996 if (NewLocation >= OrderCount) {
997 if (OrderCount > 0) {
998 NewLocation = (UINT16)OrderCount - 1;
999 } else {
1000 NewLocation = 0;
1001 }
1002 }
1003
1004 Temp = CurrentOrder[OldLocation];
1005 CopyMem (NewOrder+OldLocation, NewOrder+OldLocation+1, (OrderCount - OldLocation - 1)*sizeof (CurrentOrder[0]));
1006 CopyMem (NewOrder+NewLocation+1, NewOrder+NewLocation, (OrderCount - NewLocation - 1)*sizeof (CurrentOrder[0]));
1007 NewOrder[NewLocation] = Temp;
1008
1009 Status = gRT->SetVariable (
1010 Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
1011 (EFI_GUID *)&gEfiGlobalVariableGuid,
1012 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
1013 OrderCount*sizeof (CurrentOrder[0]),
1014 NewOrder
1015 );
1016
1017 FreePool (NewOrder);
1018
1019 if (EFI_ERROR (Status)) {
1020 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder");
1021 return (SHELL_INVALID_PARAMETER);
1022 }
1023
1024 return (SHELL_SUCCESS);
1025}
1026
1039 IN CONST CHAR16 *OptData,
1040 IN CONST UINT16 *CurrentOrder,
1041 IN CONST UINTN OrderCount,
1042 IN CONST BCFG_OPERATION_TARGET Target
1043 )
1044{
1045 EFI_KEY_OPTION NewKeyOption;
1046 EFI_KEY_OPTION *KeyOptionBuffer;
1047 SHELL_STATUS ShellStatus;
1048 EFI_STATUS Status;
1049 UINT16 OptionIndex;
1050 UINT32 LoopCounter;
1051 UINT64 Intermediate;
1052 CONST CHAR16 *Temp;
1053 CONST CHAR16 *Walker;
1054 CHAR16 *FileName;
1055 CHAR16 *Temp2;
1056 CHAR16 *Data;
1057 UINT32 KeyIndex;
1058 CHAR16 VariableName[12];
1059 VOID *VariableData;
1060
1061 SHELL_FILE_HANDLE FileHandle;
1062
1063 Status = EFI_SUCCESS;
1064 ShellStatus = SHELL_SUCCESS;
1065 Walker = OptData;
1066 FileName = NULL;
1067 Data = NULL;
1068 KeyOptionBuffer = NULL;
1069 VariableData = NULL;
1070
1071 ZeroMem (&NewKeyOption, sizeof (EFI_KEY_OPTION));
1072 ZeroMem (VariableName, sizeof (VariableName));
1073
1074 while (Walker[0] == L' ') {
1075 Walker++;
1076 }
1077
1078 //
1079 // Get the index of the variable we are changing.
1080 //
1081 Status = ShellConvertStringToUint64 (Walker, &Intermediate, TRUE, TRUE);
1082 if (EFI_ERROR (Status) || (((UINT16)Intermediate) != Intermediate) || (StrStr (Walker, L" ") == NULL) || (((UINT16)Intermediate) > ((UINT16)OrderCount))) {
1083 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Option Index");
1084 ShellStatus = SHELL_INVALID_PARAMETER;
1085 return (ShellStatus);
1086 }
1087
1088 OptionIndex = (UINT16)Intermediate;
1089
1090 Temp = StrStr (Walker, L" ");
1091 if (Temp != NULL) {
1092 Walker = Temp;
1093 }
1094
1095 while (Walker[0] == L' ') {
1096 Walker++;
1097 }
1098
1099 //
1100 // determine whether we have file with data, quote delimited information, or a hot-key
1101 //
1102 if (Walker[0] == L'\"') {
1103 //
1104 // quoted filename or quoted information.
1105 //
1106 Temp = StrStr (Walker+1, L"\"");
1107 if ((Temp == NULL) || (StrLen (Temp) != 1)) {
1108 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
1109 ShellStatus = SHELL_INVALID_PARAMETER;
1110 } else {
1111 FileName = StrnCatGrow (&FileName, NULL, Walker+1, 0);
1112 if (FileName == NULL) {
1113 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellBcfgHiiHandle, L"bcfg");
1114 ShellStatus = SHELL_OUT_OF_RESOURCES;
1115 return (ShellStatus);
1116 }
1117
1118 Temp2 = StrStr (FileName, L"\"");
1119 if (Temp2 == NULL) {
1120 ASSERT (Temp2 != NULL);
1121 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
1122 ShellStatus = SHELL_INVALID_PARAMETER;
1123 return (ShellStatus);
1124 }
1125
1126 Temp2[0] = CHAR_NULL;
1127 Temp2++;
1128 if (StrLen (Temp2) > 0) {
1129 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
1130 ShellStatus = SHELL_INVALID_PARAMETER;
1131 }
1132
1133 if (EFI_ERROR (ShellFileExists (Walker))) {
1134 //
1135 // Not a file. must be misc information.
1136 //
1137 Data = FileName;
1138 FileName = NULL;
1139 } else {
1140 FileName = StrnCatGrow (&FileName, NULL, Walker, 0);
1141 }
1142 }
1143 } else {
1144 //
1145 // filename or hot key information.
1146 //
1147 if (StrStr (Walker, L" ") == NULL) {
1148 //
1149 // filename
1150 //
1151 if (EFI_ERROR (ShellFileExists (Walker))) {
1152 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FIND_FAIL), gShellBcfgHiiHandle, L"bcfg", Walker);
1153 ShellStatus = SHELL_INVALID_PARAMETER;
1154 } else {
1155 FileName = StrnCatGrow (&FileName, NULL, Walker, 0);
1156 }
1157 } else {
1158 if (Target != BcfgTargetBootOrder) {
1159 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_BOOT_ONLY), gShellBcfgHiiHandle, L"bcfg");
1160 ShellStatus = SHELL_INVALID_PARAMETER;
1161 }
1162
1163 if (ShellStatus == SHELL_SUCCESS) {
1164 //
1165 // Get hot key information
1166 //
1167 Status = ShellConvertStringToUint64 (Walker, &Intermediate, FALSE, TRUE);
1168 if (EFI_ERROR (Status) || (((UINT32)Intermediate) != Intermediate) || (StrStr (Walker, L" ") == NULL)) {
1169 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
1170 ShellStatus = SHELL_INVALID_PARAMETER;
1171 }
1172
1173 NewKeyOption.KeyData.PackedValue = (UINT32)Intermediate;
1174 Temp = StrStr (Walker, L" ");
1175 if (Temp != NULL) {
1176 Walker = Temp;
1177 }
1178
1179 while (Walker[0] == L' ') {
1180 Walker++;
1181 }
1182 }
1183
1184 if (ShellStatus == SHELL_SUCCESS) {
1185 //
1186 // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
1187 // Re-allocate with the added information.
1188 //
1189 KeyOptionBuffer = AllocatePool (sizeof (EFI_KEY_OPTION) + (sizeof (EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount));
1190 if (KeyOptionBuffer == NULL) {
1191 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");
1192 ShellStatus = SHELL_OUT_OF_RESOURCES;
1193 return ShellStatus;
1194 }
1195
1196 CopyMem (KeyOptionBuffer, &NewKeyOption, sizeof (EFI_KEY_OPTION));
1197 }
1198
1199 for (LoopCounter = 0; ShellStatus == SHELL_SUCCESS && LoopCounter < NewKeyOption.KeyData.Options.InputKeyCount; LoopCounter++) {
1200 //
1201 // ScanCode
1202 //
1203 Status = ShellConvertStringToUint64 (Walker, &Intermediate, FALSE, TRUE);
1204 if (EFI_ERROR (Status) || (((UINT16)Intermediate) != Intermediate) || (StrStr (Walker, L" ") == NULL)) {
1205 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
1206 ShellStatus = SHELL_INVALID_PARAMETER;
1207 }
1208
1209 ((EFI_INPUT_KEY *)(((UINT8 *)KeyOptionBuffer) + sizeof (EFI_KEY_OPTION)))[LoopCounter].ScanCode = (UINT16)Intermediate;
1210 Temp = StrStr (Walker, L" ");
1211 if (Temp != NULL) {
1212 Walker = Temp;
1213 }
1214
1215 while (Walker[0] == L' ') {
1216 Walker++;
1217 }
1218
1219 //
1220 // UnicodeChar
1221 //
1222 Status = ShellConvertStringToUint64 (Walker, &Intermediate, FALSE, TRUE);
1223 if (EFI_ERROR (Status) || (((UINT16)Intermediate) != Intermediate)) {
1224 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
1225 ShellStatus = SHELL_INVALID_PARAMETER;
1226 }
1227
1228 ((EFI_INPUT_KEY *)(((UINT8 *)KeyOptionBuffer) + sizeof (EFI_KEY_OPTION)))[LoopCounter].UnicodeChar = (UINT16)Intermediate;
1229 Temp = StrStr (Walker, L" ");
1230 if (Temp != NULL) {
1231 Walker = Temp;
1232 }
1233
1234 while (Walker[0] == L' ') {
1235 Walker++;
1236 }
1237 }
1238
1239 if (ShellStatus == SHELL_SUCCESS) {
1240 //
1241 // Now do the BootOption / BootOptionCrc
1242 //
1243 ASSERT (OptionIndex <= OrderCount);
1244 KeyOptionBuffer->BootOption = CurrentOrder[OptionIndex];
1245 Status = GetBootOptionCrc (&(KeyOptionBuffer->BootOptionCrc), KeyOptionBuffer->BootOption);
1246 if (EFI_ERROR (Status)) {
1247 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Option Index");
1248 ShellStatus = SHELL_INVALID_PARAMETER;
1249 }
1250 }
1251
1252 if (ShellStatus == SHELL_SUCCESS) {
1253 for (Temp2 = NULL, KeyIndex = 0; KeyIndex <= 0xFFFF; KeyIndex++) {
1254 UnicodeSPrint (VariableName, sizeof (VariableName), L"Key%04x", KeyIndex);
1255 Status = GetEfiGlobalVariable2 (VariableName, &VariableData, NULL);
1256 if (Status == EFI_NOT_FOUND) {
1257 break;
1258 }
1259
1260 if (!EFI_ERROR (Status)) {
1261 SHELL_FREE_NON_NULL (VariableData);
1262 }
1263 }
1264
1265 if (KeyIndex <= 0xFFFF) {
1266 Status = gRT->SetVariable (
1267 VariableName,
1268 (EFI_GUID *)&gEfiGlobalVariableGuid,
1269 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
1270 sizeof (EFI_KEY_OPTION) + (sizeof (EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount),
1271 KeyOptionBuffer
1272 );
1273 if (EFI_ERROR (Status)) {
1274 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
1275 ShellStatus = SHELL_INVALID_PARAMETER;
1276 }
1277 } else {
1278 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_VAR_NO_NUM), gShellBcfgHiiHandle, L"bcfg");
1279 ShellStatus = SHELL_INVALID_PARAMETER;
1280 }
1281
1282 ASSERT (FileName == NULL && Data == NULL);
1283 }
1284 }
1285 }
1286
1287 //
1288 // Shouldn't be possible to have have both. Neither is ok though.
1289 //
1290 ASSERT (FileName == NULL || Data == NULL);
1291
1292 if ((ShellStatus == SHELL_SUCCESS) && ((FileName != NULL) || (Data != NULL))) {
1293 if (FileName != NULL) {
1294 //
1295 // Open the file and populate the data buffer.
1296 //
1297 Status = ShellOpenFileByName (
1298 FileName,
1299 &FileHandle,
1300 EFI_FILE_MODE_READ,
1301 0
1302 );
1303 if (!EFI_ERROR (Status)) {
1304 Status = ShellGetFileSize (FileHandle, &Intermediate);
1305 }
1306
1307 Data = AllocateZeroPool ((UINTN)Intermediate);
1308 if (Data == NULL) {
1309 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");
1310 ShellStatus = SHELL_OUT_OF_RESOURCES;
1311 }
1312
1313 if (!EFI_ERROR (Status)) {
1314 Status = ShellReadFile (FileHandle, (UINTN *)&Intermediate, Data);
1315 }
1316 } else {
1317 Intermediate = StrSize (Data);
1318 }
1319
1320 if (!EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS) && (Data != NULL)) {
1321 Status = UpdateOptionalData (CurrentOrder[OptionIndex], (UINTN)Intermediate, (UINT8 *)Data, Target);
1322 if (EFI_ERROR (Status)) {
1323 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
1324 ShellStatus = SHELL_INVALID_PARAMETER;
1325 }
1326 }
1327
1328 if (EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS)) {
1329 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
1330 ShellStatus = SHELL_INVALID_PARAMETER;
1331 }
1332 }
1333
1334 SHELL_FREE_NON_NULL (Data);
1335 SHELL_FREE_NON_NULL (KeyOptionBuffer);
1336 SHELL_FREE_NON_NULL (FileName);
1337 return ShellStatus;
1338}
1339
1353 IN CONST CHAR16 *Op,
1354 IN CONST UINTN OrderCount,
1355 IN CONST UINT16 *CurrentOrder,
1356 IN CONST BOOLEAN VerboseOutput
1357 )
1358{
1359 EFI_STATUS Status;
1360 UINT8 *Buffer;
1361 UINTN BufferSize;
1362 CHAR16 VariableName[12];
1363 UINTN LoopVar;
1364 CHAR16 *DevPathString;
1365 VOID *FilePathList;
1366 UINTN Errors;
1367 EFI_LOAD_OPTION *LoadOption;
1368 CHAR16 *Description;
1369 UINTN DescriptionSize;
1370 UINTN OptionalDataOffset;
1371
1372 if (OrderCount == 0) {
1373 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NONE), gShellBcfgHiiHandle, L"bcfg");
1374 return (SHELL_SUCCESS);
1375 }
1376
1377 Errors = 0;
1378
1379 for (LoopVar = 0; LoopVar < OrderCount; LoopVar++) {
1380 Buffer = NULL;
1381 BufferSize = 0;
1382 DevPathString = NULL;
1383
1384 UnicodeSPrint (VariableName, sizeof (VariableName), L"%s%04x", Op, CurrentOrder[LoopVar]);
1385
1386 Status = gRT->GetVariable (
1387 VariableName,
1388 (EFI_GUID *)&gEfiGlobalVariableGuid,
1389 NULL,
1390 &BufferSize,
1391 Buffer
1392 );
1393 if (Status == EFI_BUFFER_TOO_SMALL) {
1394 Buffer = AllocateZeroPool (BufferSize);
1395 if (Buffer == NULL) {
1396 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");
1397 ++Errors;
1398 goto Cleanup;
1399 }
1400
1401 Status = gRT->GetVariable (
1402 VariableName,
1403 (EFI_GUID *)&gEfiGlobalVariableGuid,
1404 NULL,
1405 &BufferSize,
1406 Buffer
1407 );
1408 }
1409
1410 if (EFI_ERROR (Status) || (Buffer == NULL)) {
1411 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_READ_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
1412 ++Errors;
1413 goto Cleanup;
1414 }
1415
1416 //
1417 // We expect the Attributes, FilePathListLength, and L'\0'-terminated
1418 // Description fields to be present.
1419 //
1420 if (BufferSize < sizeof *LoadOption + sizeof (CHAR16)) {
1422 -1,
1423 -1,
1424 NULL,
1425 STRING_TOKEN (STR_BCFG_VAR_CORRUPT),
1426 gShellBcfgHiiHandle,
1427 L"bcfg",
1428 VariableName
1429 );
1430 ++Errors;
1431 goto Cleanup;
1432 }
1433
1434 LoadOption = (EFI_LOAD_OPTION *)Buffer;
1435 Description = (CHAR16 *)(Buffer + sizeof (EFI_LOAD_OPTION));
1436 DescriptionSize = StrSize (Description);
1437
1438 if (LoadOption->FilePathListLength != 0) {
1439 FilePathList = (UINT8 *)Description + DescriptionSize;
1440 DevPathString = ConvertDevicePathToText (FilePathList, TRUE, FALSE);
1441 if (DevPathString == NULL) {
1442 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");
1443 ++Errors;
1444 goto Cleanup;
1445 }
1446 }
1447
1448 OptionalDataOffset = sizeof *LoadOption + DescriptionSize +
1449 LoadOption->FilePathListLength;
1450
1452 -1,
1453 -1,
1454 NULL,
1455 STRING_TOKEN (STR_BCFG_LOAD_OPTIONS),
1456 gShellBcfgHiiHandle,
1457 LoopVar,
1458 VariableName,
1459 Description,
1460 DevPathString,
1461 OptionalDataOffset >= BufferSize ? L'N' : L'Y'
1462 );
1463 if (VerboseOutput && (OptionalDataOffset < BufferSize)) {
1464 DumpHex (
1465 2, // Indent
1466 0, // Offset (displayed)
1467 BufferSize - OptionalDataOffset, // DataSize
1468 Buffer + OptionalDataOffset // UserData
1469 );
1470 }
1471
1472Cleanup:
1473 if (Buffer != NULL) {
1474 FreePool (Buffer);
1475 }
1476
1477 if (DevPathString != NULL) {
1478 FreePool (DevPathString);
1479 }
1480 }
1481
1482 return (Errors > 0) ? SHELL_INVALID_PARAMETER : SHELL_SUCCESS;
1483}
1484
1490VOID
1492 IN BGFG_OPERATION *Struct
1493 )
1494{
1495 ASSERT (Struct != NULL);
1496 Struct->Target = BcfgTargetMax;
1497 Struct->Type = BcfgTypeMax;
1498 Struct->Number1 = 0;
1499 Struct->Number2 = 0;
1500 Struct->HandleIndex = 0;
1501 Struct->FileName = NULL;
1502 Struct->Description = NULL;
1503 Struct->Order = NULL;
1504 Struct->OptData = NULL;
1505}
1506
1507STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
1508 { L"-v", TypeFlag },
1509 { L"-opt", TypeMaxValue },
1510 { NULL, TypeMax }
1511};
1512
1520EFIAPI
1522 IN EFI_HANDLE ImageHandle,
1523 IN EFI_SYSTEM_TABLE *SystemTable
1524 )
1525{
1526 EFI_STATUS Status;
1527 LIST_ENTRY *Package;
1528 CHAR16 *ProblemParam;
1529 SHELL_STATUS ShellStatus;
1530 UINTN ParamNumber;
1531 CONST CHAR16 *CurrentParam;
1532 BGFG_OPERATION CurrentOperation;
1533 UINTN Length;
1534 UINT64 Intermediate;
1535 UINT16 Count;
1536
1537 Length = 0;
1538 ProblemParam = NULL;
1539 Package = NULL;
1540 ShellStatus = SHELL_SUCCESS;
1541
1542 InitBcfgStruct (&CurrentOperation);
1543
1544 //
1545 // initialize the shell lib (we must be in non-auto-init...)
1546 //
1547 Status = ShellInitialize ();
1548 ASSERT_EFI_ERROR (Status);
1549
1550 Status = CommandInit ();
1551 ASSERT_EFI_ERROR (Status);
1552
1553 //
1554 // parse the command line
1555 //
1556 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
1557 if (EFI_ERROR (Status)) {
1558 if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
1559 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellBcfgHiiHandle, L"bcfg", ProblemParam);
1560 FreePool (ProblemParam);
1561 ShellStatus = SHELL_INVALID_PARAMETER;
1562 } else {
1563 ASSERT (FALSE);
1564 }
1565 } else {
1566 //
1567 // Read in if we are doing -OPT
1568 //
1569 if (ShellCommandLineGetFlag (Package, L"-opt")) {
1570 CurrentOperation.OptData = ShellCommandLineGetValue (Package, L"-opt");
1571 if (CurrentOperation.OptData == NULL) {
1572 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellBcfgHiiHandle, L"bcfg", L"-opt");
1573 ShellStatus = SHELL_INVALID_PARAMETER;
1574 }
1575
1576 CurrentOperation.Type = BcfgTypeOpt;
1577 }
1578
1579 //
1580 // small block to read the target of the operation
1581 //
1582 if (((ShellCommandLineGetCount (Package) < 3) && (CurrentOperation.Type != BcfgTypeOpt)) ||
1583 ((ShellCommandLineGetCount (Package) < 2) && (CurrentOperation.Type == BcfgTypeOpt))
1584 )
1585 {
1586 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
1587 ShellStatus = SHELL_INVALID_PARAMETER;
1588 } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)ShellCommandLineGetRawValue (Package, 1), L"driver") == 0) {
1589 CurrentOperation.Target = BcfgTargetDriverOrder;
1590 } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)ShellCommandLineGetRawValue (Package, 1), L"boot") == 0) {
1591 CurrentOperation.Target = BcfgTargetBootOrder;
1592 } else {
1593 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT), gShellBcfgHiiHandle, L"bcfg");
1594 ShellStatus = SHELL_INVALID_PARAMETER;
1595 }
1596
1597 //
1598 // Read in the boot or driver order environment variable (not needed for opt)
1599 //
1600 if ((ShellStatus == SHELL_SUCCESS) && (CurrentOperation.Target < BcfgTargetMax)) {
1601 Length = 0;
1602 Status = gRT->GetVariable (
1603 CurrentOperation.Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
1604 (EFI_GUID *)&gEfiGlobalVariableGuid,
1605 NULL,
1606 &Length,
1607 CurrentOperation.Order
1608 );
1609 if (Status == EFI_BUFFER_TOO_SMALL) {
1610 CurrentOperation.Order = AllocateZeroPool (Length+(4*sizeof (CurrentOperation.Order[0])));
1611 if (CurrentOperation.Order == NULL) {
1612 ShellStatus = SHELL_OUT_OF_RESOURCES;
1613 } else {
1614 Status = gRT->GetVariable (
1615 CurrentOperation.Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
1616 (EFI_GUID *)&gEfiGlobalVariableGuid,
1617 NULL,
1618 &Length,
1619 CurrentOperation.Order
1620 );
1621 }
1622 }
1623 }
1624
1625 Count = (UINT16)(Length / sizeof (CurrentOperation.Order[0]));
1626
1627 //
1628 // large block to read the type of operation and verify parameter types for the info.
1629 //
1630 if ((ShellStatus == SHELL_SUCCESS) && (CurrentOperation.Target < BcfgTargetMax)) {
1631 for (ParamNumber = 2; ParamNumber < ShellCommandLineGetCount (Package) && ShellStatus == SHELL_SUCCESS; ParamNumber++) {
1632 CurrentParam = ShellCommandLineGetRawValue (Package, ParamNumber);
1633 if (CurrentParam == NULL) {
1634 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"NULL");
1635 ShellStatus = SHELL_INVALID_PARAMETER;
1636 goto Done;
1637 }
1638
1639 if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"dump") == 0) {
1640 CurrentOperation.Type = BcfgTypeDump;
1641 if (ShellCommandLineGetCount (Package) > 3) {
1642 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellBcfgHiiHandle, L"bcfg");
1643 ShellStatus = SHELL_INVALID_PARAMETER;
1644 }
1645 } else if (ShellCommandLineGetFlag (Package, L"-v")) {
1646 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"-v (without dump)");
1647 ShellStatus = SHELL_INVALID_PARAMETER;
1648 } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"add") == 0) {
1649 if ((ParamNumber + 3) >= ShellCommandLineGetCount (Package)) {
1650 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
1651 ShellStatus = SHELL_INVALID_PARAMETER;
1652 }
1653
1654 CurrentOperation.Type = BcfgTypeAdd;
1655 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
1656 if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
1657 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
1658 ShellStatus = SHELL_INVALID_PARAMETER;
1659 } else {
1660 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
1661 CurrentOperation.Number1 = (UINT16)Intermediate;
1662 ASSERT (CurrentOperation.FileName == NULL);
1663 CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
1664 ASSERT (CurrentOperation.Description == NULL);
1665 CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
1666 }
1667 } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"addp") == 0) {
1668 if ((ParamNumber + 3) >= ShellCommandLineGetCount (Package)) {
1669 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
1670 ShellStatus = SHELL_INVALID_PARAMETER;
1671 }
1672
1673 CurrentOperation.Type = BcfgTypeAddp;
1674 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
1675 if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
1676 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
1677 ShellStatus = SHELL_INVALID_PARAMETER;
1678 } else {
1679 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
1680 CurrentOperation.Number1 = (UINT16)Intermediate;
1681 ASSERT (CurrentOperation.FileName == NULL);
1682 CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
1683 ASSERT (CurrentOperation.Description == NULL);
1684 CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
1685 }
1686 } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"addh") == 0) {
1687 if ((ParamNumber + 3) >= ShellCommandLineGetCount (Package)) {
1688 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
1689 ShellStatus = SHELL_INVALID_PARAMETER;
1690 }
1691
1692 CurrentOperation.Type = BcfgTypeAddh;
1693 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
1694 if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
1695 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
1696 ShellStatus = SHELL_INVALID_PARAMETER;
1697 } else {
1698 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
1699 CurrentOperation.Number1 = (UINT16)Intermediate;
1700 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
1701 if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
1702 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
1703 ShellStatus = SHELL_INVALID_PARAMETER;
1704 } else {
1705 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
1706 CurrentOperation.HandleIndex = (UINT16)Intermediate;
1707 ASSERT (CurrentOperation.Description == NULL);
1708 CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
1709 }
1710 }
1711 } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"rm") == 0) {
1712 if ((ParamNumber + 1) >= ShellCommandLineGetCount (Package)) {
1713 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
1714 ShellStatus = SHELL_INVALID_PARAMETER;
1715 }
1716
1717 CurrentOperation.Type = BcfgTypeRm;
1718 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
1719 if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
1720 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
1721 ShellStatus = SHELL_INVALID_PARAMETER;
1722 } else {
1723 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
1724 CurrentOperation.Number1 = (UINT16)Intermediate;
1725 if (CurrentOperation.Number1 >= Count) {
1726 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
1727 ShellStatus = SHELL_INVALID_PARAMETER;
1728 }
1729 }
1730 } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"mv") == 0) {
1731 if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
1732 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
1733 ShellStatus = SHELL_INVALID_PARAMETER;
1734 }
1735
1736 CurrentOperation.Type = BcfgTypeMv;
1737 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
1738 if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
1739 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
1740 ShellStatus = SHELL_INVALID_PARAMETER;
1741 } else {
1742 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
1743 CurrentOperation.Number1 = (UINT16)Intermediate;
1744 if (CurrentOperation.Number1 >= Count) {
1745 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
1746 ShellStatus = SHELL_INVALID_PARAMETER;
1747 } else {
1748 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
1749 if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
1750 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
1751 ShellStatus = SHELL_INVALID_PARAMETER;
1752 } else {
1753 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
1754 CurrentOperation.Number2 = (UINT16)Intermediate;
1755 }
1756
1757 if ( (CurrentOperation.Number2 == CurrentOperation.Number1)
1758 || (CurrentOperation.Number2 >= Count)
1759 )
1760 {
1761 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
1762 ShellStatus = SHELL_INVALID_PARAMETER;
1763 }
1764 }
1765 }
1766 } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"mod") == 0) {
1767 if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
1768 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
1769 ShellStatus = SHELL_INVALID_PARAMETER;
1770 } else {
1771 CurrentOperation.Type = BcfgTypeMod;
1772 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
1773 if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
1774 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
1775 ShellStatus = SHELL_INVALID_PARAMETER;
1776 } else {
1777 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
1778 CurrentOperation.Number1 = (UINT16)Intermediate;
1779 if (CurrentOperation.Number1 >= Count) {
1780 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
1781 ShellStatus = SHELL_INVALID_PARAMETER;
1782 } else {
1783 ASSERT (CurrentOperation.Description == NULL);
1784 CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
1785 }
1786 }
1787 }
1788 } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"modf") == 0) {
1789 if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
1790 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
1791 ShellStatus = SHELL_INVALID_PARAMETER;
1792 } else {
1793 CurrentOperation.Type = BcfgTypeModf;
1794 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
1795 if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
1796 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
1797 ShellStatus = SHELL_INVALID_PARAMETER;
1798 } else {
1799 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
1800 CurrentOperation.Number1 = (UINT16)Intermediate;
1801 if (CurrentOperation.Number1 >= Count) {
1802 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
1803 ShellStatus = SHELL_INVALID_PARAMETER;
1804 } else {
1805 ASSERT (CurrentOperation.FileName == NULL);
1806 CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
1807 }
1808 }
1809 }
1810 } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"modp") == 0) {
1811 if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
1812 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
1813 ShellStatus = SHELL_INVALID_PARAMETER;
1814 } else {
1815 CurrentOperation.Type = BcfgTypeModp;
1816 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
1817 if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
1818 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
1819 ShellStatus = SHELL_INVALID_PARAMETER;
1820 } else {
1821 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
1822 CurrentOperation.Number1 = (UINT16)Intermediate;
1823 if (CurrentOperation.Number1 >= Count) {
1824 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
1825 ShellStatus = SHELL_INVALID_PARAMETER;
1826 } else {
1827 ASSERT (CurrentOperation.FileName == NULL);
1828 CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
1829 }
1830 }
1831 }
1832 } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"modh") == 0) {
1833 if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
1834 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
1835 ShellStatus = SHELL_INVALID_PARAMETER;
1836 } else {
1837 CurrentOperation.Type = BcfgTypeModh;
1838 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
1839 if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
1840 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
1841 ShellStatus = SHELL_INVALID_PARAMETER;
1842 } else {
1843 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
1844 CurrentOperation.Number1 = (UINT16)Intermediate;
1845 if (CurrentOperation.Number1 >= Count) {
1846 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
1847 ShellStatus = SHELL_INVALID_PARAMETER;
1848 } else {
1849 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
1850 if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
1851 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
1852 ShellStatus = SHELL_INVALID_PARAMETER;
1853 } else {
1854 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
1855 CurrentOperation.HandleIndex = (UINT16)Intermediate;
1856 }
1857 }
1858 }
1859 }
1860 } else {
1861 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
1862 ShellStatus = SHELL_INVALID_PARAMETER;
1863 }
1864 }
1865 }
1866
1867 if ((ShellStatus == SHELL_SUCCESS) && (CurrentOperation.Target < BcfgTargetMax) && (CurrentOperation.Type < BcfgTypeMax)) {
1868 //
1869 // we have all the info. Do the work
1870 //
1871 switch (CurrentOperation.Type) {
1872 case BcfgTypeDump:
1873 ShellStatus = BcfgDisplayDump (
1874 CurrentOperation.Target == BcfgTargetBootOrder ? L"Boot" : L"Driver",
1875 Count,
1876 CurrentOperation.Order,
1877 ShellCommandLineGetFlag (Package, L"-v")
1878 );
1879 break;
1880 case BcfgTypeMv:
1881 ShellStatus = BcfgMove (
1882 CurrentOperation.Target,
1883 CurrentOperation.Order,
1884 Count,
1885 CurrentOperation.Number1,
1886 CurrentOperation.Number2
1887 );
1888 break;
1889 case BcfgTypeRm:
1890 ShellStatus = BcfgRemove (
1891 CurrentOperation.Target,
1892 CurrentOperation.Order,
1893 Count,
1894 CurrentOperation.Number1
1895 );
1896 break;
1897 case BcfgTypeAdd:
1898 case BcfgTypeAddp:
1899 case BcfgTypeAddh:
1900 ShellStatus = BcfgAdd (
1901 CurrentOperation.Number1,
1902 CurrentOperation.FileName,
1903 CurrentOperation.Description == NULL ? L"" : CurrentOperation.Description,
1904 CurrentOperation.Order,
1905 Count,
1906 CurrentOperation.Target,
1907 (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddh),
1908 (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddp),
1909 CurrentOperation.HandleIndex
1910 );
1911 break;
1912 case BcfgTypeMod:
1913 case BcfgTypeModf:
1914 case BcfgTypeModp:
1915 case BcfgTypeModh:
1916 ShellStatus = BcfgMod (&CurrentOperation, Count);
1917 break;
1918 case BcfgTypeOpt:
1919 ShellStatus = BcfgAddOpt (
1920 CurrentOperation.OptData,
1921 CurrentOperation.Order,
1922 Count,
1923 CurrentOperation.Target
1924 );
1925 break;
1926 default:
1927 ASSERT (FALSE);
1928 }
1929 }
1930 }
1931
1932Done:
1933
1934 if (Package != NULL) {
1936 }
1937
1938 if (CurrentOperation.FileName != NULL) {
1939 FreePool (CurrentOperation.FileName);
1940 }
1941
1942 if (CurrentOperation.Description != NULL) {
1943 FreePool (CurrentOperation.Description);
1944 }
1945
1946 if (CurrentOperation.Order != NULL) {
1947 FreePool (CurrentOperation.Order);
1948 }
1949
1950 return (ShellStatus);
1951}
1952
1958CONST CHAR16 *
1959EFIAPI
1961 VOID
1962 )
1963{
1964 return (mFileName);
1965}
1966
1980EFIAPI
1982 IN EFI_HANDLE ImageHandle,
1983 IN EFI_SYSTEM_TABLE *SystemTable,
1984 IN CONST CHAR16 *Name
1985 )
1986{
1987 if (gShellBcfgHiiHandle != NULL) {
1988 return (EFI_SUCCESS);
1989 }
1990
1991 gShellBcfgHiiHandle = HiiAddPackages (&gShellBcfgHiiGuid, gImageHandle, UefiShellBcfgCommandLibStrings, NULL);
1992 if (gShellBcfgHiiHandle == NULL) {
1993 return (EFI_DEVICE_ERROR);
1994 }
1995
1996 //
1997 // install our shell command handler
1998 //
1999 ShellCommandRegisterCommandName (L"bcfg", ShellCommandRunBcfg, ShellCommandGetManFileNameBcfg, 0, Name, FALSE, gShellBcfgHiiHandle, STRING_TOKEN (STR_GET_HELP_BCFG));
2000
2001 return (EFI_SUCCESS);
2002}
2003
2011EFIAPI
2013 IN EFI_HANDLE ImageHandle,
2014 IN EFI_SYSTEM_TABLE *SystemTable
2015 )
2016{
2017 if (gShellBcfgHiiHandle != NULL) {
2018 HiiRemovePackages (gShellBcfgHiiHandle);
2019 }
2020
2021 gShellBcfgHiiHandle = NULL;
2022 return (EFI_SUCCESS);
2023}
UINT64 UINTN
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
CHAR16 *EFIAPI StrStr(IN CONST CHAR16 *String, IN CONST CHAR16 *SearchString)
Definition: String.c:224
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define MEDIA_HARDDRIVE_DP
Definition: DevicePath.h:1014
UINT8 EFIAPI DevicePathType(IN CONST VOID *Node)
UINT8 EFIAPI DevicePathSubType(IN CONST VOID *Node)
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL)
CHAR16 *EFIAPI ConvertDevicePathToText(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN BOOLEAN DisplayOnly, IN BOOLEAN AllowShortcuts)
UINTN EFIAPI GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DuplicateDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
EFI_HANDLE EFIAPI ConvertHandleIndexToHandle(IN CONST UINTN TheIndex)
#define PARSE_HANDLE_DATABASE_PARENTS(ControllerHandle, Count, Buffer)
#define PARSE_HANDLE_DATABASE_UEFI_DRIVERS(ControllerHandle, Count, Buffer)
EFI_STATUS EFIAPI ParseHandleDatabaseForChildControllers(IN CONST EFI_HANDLE ControllerHandle, OUT UINTN *MatchingHandleCount, OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL)
EFI_HII_HANDLE EFIAPI HiiAddPackages(IN CONST EFI_GUID *PackageListGuid, IN EFI_HANDLE DeviceHandle OPTIONAL,...)
Definition: HiiLib.c:141
VOID EFIAPI HiiRemovePackages(IN EFI_HII_HANDLE HiiHandle)
Definition: HiiLib.c:253
UINTN EFIAPI UnicodeSPrint(OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString,...)
Definition: PrintLib.c:408
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
SHELL_STATUS
Definition: Shell.h:21
@ SHELL_OUT_OF_RESOURCES
Definition: Shell.h:73
@ SHELL_SUCCESS
Definition: Shell.h:25
@ SHELL_NOT_FOUND
Definition: Shell.h:101
@ SHELL_UNSUPPORTED
Definition: Shell.h:40
@ SHELL_INVALID_PARAMETER
Definition: Shell.h:35
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
UINT8 ScanCode
follows value defined in Scan Code Set1
Definition: Ps2KbdCtrller.c:12
EFI_STATUS EFIAPI CommandInit(VOID)
RETURN_STATUS EFIAPI ShellCommandRegisterCommandName(IN CONST CHAR16 *CommandString, IN SHELL_RUN_COMMAND CommandHandler, IN SHELL_GET_MAN_FILENAME GetManFileName, IN UINT32 ShellMinSupportLevel, IN CONST CHAR16 *ProfileName, IN CONST BOOLEAN CanAffectLE, IN CONST EFI_HII_HANDLE HiiHandle, IN CONST EFI_STRING_ID ManFormatHelp)
VOID EFIAPI DumpHex(IN UINTN Indent, IN UINTN Offset, IN UINTN DataSize, IN VOID *UserData)
EFI_STATUS EFIAPI ShellGetFileSize(IN SHELL_FILE_HANDLE FileHandle, OUT UINT64 *Size)
CONST CHAR16 *EFIAPI ShellCommandLineGetValue(IN CONST LIST_ENTRY *CheckPackage, IN CHAR16 *KeyString)
EFI_STATUS EFIAPI ShellCloseFileMetaArg(IN OUT EFI_SHELL_FILE_INFO **ListHead)
#define ShellCommandLineParse(CheckList, CheckPackage, ProblemParam, AutoPageBreak)
Make it easy to upgrade from older versions of the shell library.
Definition: ShellLib.h:755
EFI_STATUS EFIAPI ShellPrintHiiEx(IN INT32 Col OPTIONAL, IN INT32 Row OPTIONAL, IN CONST CHAR8 *Language OPTIONAL, IN CONST EFI_STRING_ID HiiFormatStringId, IN CONST EFI_HII_HANDLE HiiFormatHandle,...)
BOOLEAN EFIAPI ShellCommandLineGetFlag(IN CONST LIST_ENTRY *CONST CheckPackage, IN CONST CHAR16 *CONST KeyString)
BOOLEAN EFIAPI ShellIsHexOrDecimalNumber(IN CONST CHAR16 *String, IN CONST BOOLEAN ForceHex, IN CONST BOOLEAN StopAtSpace)
@ TypeMaxValue
A flag followed by all the command line data before the next flag.
Definition: ShellLib.h:704
@ TypeFlag
A flag that is present or not present only (IE "-a").
Definition: ShellLib.h:699
EFI_STATUS EFIAPI ShellOpenFileByName(IN CONST CHAR16 *FileName, OUT SHELL_FILE_HANDLE *FileHandle, IN UINT64 OpenMode, IN UINT64 Attributes)
Definition: UefiShellLib.c:720
CHAR16 *EFIAPI StrnCatGrow(IN OUT CHAR16 **Destination, IN OUT UINTN *CurrentSize, IN CONST CHAR16 *Source, IN UINTN Count)
EFI_STATUS EFIAPI ShellFileExists(IN CONST CHAR16 *Name)
EFI_STATUS EFIAPI ShellOpenFileMetaArg(IN CHAR16 *Arg, IN UINT64 OpenMode, IN OUT EFI_SHELL_FILE_INFO **ListHead)
VOID EFIAPI ShellCommandLineFreeVarList(IN LIST_ENTRY *CheckPackage)
EFI_STATUS EFIAPI ShellInitialize(VOID)
Definition: UefiShellLib.c:532
CONST CHAR16 *EFIAPI ShellCommandLineGetRawValue(IN CONST LIST_ENTRY *CONST CheckPackage, IN UINTN Position)
UINTN EFIAPI ShellCommandLineGetCount(IN CONST LIST_ENTRY *CheckPackage)
EFI_STATUS EFIAPI ShellConvertStringToUint64(IN CONST CHAR16 *String, OUT UINT64 *Value, IN CONST BOOLEAN ForceHex, IN CONST BOOLEAN StopAtSpace)
EFI_STATUS EFIAPI ShellReadFile(IN SHELL_FILE_HANDLE FileHandle, IN OUT UINTN *ReadSize, OUT VOID *Buffer)
Definition: UefiShellLib.c:912
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_STATUS EFIAPI EfiBootManagerLoadOptionToVariable(IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *LoadOption)
Definition: BmLoadOption.c:170
EFI_STATUS EFIAPI EfiBootManagerFreeLoadOption(IN EFI_BOOT_MANAGER_LOAD_OPTION *LoadOption)
EFI_STATUS EFIAPI EfiBootManagerVariableToLoadOption(IN CHAR16 *VariableName, IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *LoadOption)
Definition: BmLoadOption.c:998
EFI_HANDLE gImageHandle
EFI_BOOT_SERVICES * gBS
#define STRING_TOKEN(t)
VOID * EFI_HII_HANDLE
EFI_STATUS EFIAPI GetEfiGlobalVariable2(IN CONST CHAR16 *Name, OUT VOID **Value, OUT UINTN *Size OPTIONAL)
Definition: UefiLib.c:1470
UINTN EFIAPI Print(IN CONST CHAR16 *Format,...)
Definition: UefiLibPrint.c:113
#define EFI_VARIABLE_NON_VOLATILE
EFI_STATUS EFIAPI BcfgLibraryUnregisterBcfgCommand(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS UpdateOptionalData(UINT16 Index, UINTN DataSize, UINT8 *Data, IN CONST BCFG_OPERATION_TARGET Target)
EFI_STATUS GetDevicePathForDriverHandle(IN EFI_HANDLE TheHandle, IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath)
CONST CHAR16 *EFIAPI ShellCommandGetManFileNameBcfg(VOID)
EFI_STATUS EFIAPI BcfgLibraryRegisterBcfgCommand(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable, IN CONST CHAR16 *Name)
EFI_STATUS GetBootOptionCrc(UINT32 *Crc, UINT16 BootIndex)
SHELL_STATUS GetDevicePathByHandle(IN EFI_HANDLE TheHandle, IN BCFG_OPERATION_TARGET Target, IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath)
SHELL_STATUS BcfgAdd(IN UINTN Position, IN CONST CHAR16 *File, IN CONST CHAR16 *Desc, IN CONST UINT16 *CurrentOrder, IN CONST UINTN OrderCount, IN CONST BCFG_OPERATION_TARGET Target, IN CONST BOOLEAN UseHandle, IN CONST BOOLEAN UsePath, IN CONST UINTN HandleNumber)
SHELL_STATUS BcfgDisplayDump(IN CONST CHAR16 *Op, IN CONST UINTN OrderCount, IN CONST UINT16 *CurrentOrder, IN CONST BOOLEAN VerboseOutput)
SHELL_STATUS BcfgAddOpt(IN CONST CHAR16 *OptData, IN CONST UINT16 *CurrentOrder, IN CONST UINTN OrderCount, IN CONST BCFG_OPERATION_TARGET Target)
VOID InitBcfgStruct(IN BGFG_OPERATION *Struct)
SHELL_STATUS BcfgRemove(IN CONST BCFG_OPERATION_TARGET Target, IN CONST UINT16 *CurrentOrder, IN CONST UINTN OrderCount, IN CONST UINT16 Location)
SHELL_STATUS BcfgMove(IN CONST BCFG_OPERATION_TARGET Target, IN CONST UINT16 *CurrentOrder, IN CONST UINTN OrderCount, IN CONST UINT16 OldLocation, IN UINT16 NewLocation)
SHELL_STATUS EFIAPI ShellCommandRunBcfg(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
SHELL_STATUS BcfgMod(IN CONST BGFG_OPERATION *BcfgOperation, IN CONST UINTN OrderCount)
UINT16 FilePathListLength
Definition: UefiSpec.h:2133
UINT32 BootOptionCrc
Definition: UefiSpec.h:2236
UINT16 BootOption
Definition: UefiSpec.h:2241
EFI_BOOT_KEY_DATA KeyData
Definition: UefiSpec.h:2230
EFI_DEVICE_PATH_PROTOCOL * FilePath
Definition: LoadedImage.h:54
EFI_HANDLE DeviceHandle
The device handle that the EFI Image was loaded from.
Definition: LoadedImage.h:53
LIST_ENTRY Link
Linked list members.
Definition: Shell.h:153
EFI_STATUS Status
Status of opening the file. Valid only if Handle != NULL.
Definition: Shell.h:154
CONST CHAR16 * FullName
Fully qualified filename.
Definition: Shell.h:155
Definition: Base.h:213
UINT32 InputKeyCount
Definition: UefiSpec.h:2217