]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellInstall1CommandsLib/Bcfg.c
Refine code to make it more safely.
[mirror_edk2.git] / ShellPkg / Library / UefiShellInstall1CommandsLib / Bcfg.c
1 /** @file
2 Main file for bcfg shell Install1 function.
3
4 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "UefiShellInstall1CommandsLib.h"
16 #include <Guid/GlobalVariable.h>
17 #include <Library/PrintLib.h>
18 #include <Library/HandleParsingLib.h>
19 #include <Library/DevicePathLib.h>
20
21 typedef enum {
22 BcfgTargetBootOrder = 0,
23 BcfgTargetDriverOrder = 1,
24 BcfgTargetMax = 2
25 } BCFG_OPERATION_TARGET;
26
27 typedef enum {
28 BcfgTypeDump = 0,
29 BcfgTypeAdd = 1,
30 BcfgTypeAddp = 2,
31 BcfgTypeAddh = 3,
32 BcfgTypeRm = 4,
33 BcfgTypeMv = 5,
34 BcfgTypeOpt = 6,
35 BcfgTypeMax = 7
36 } BCFG_OPERATION_TYPE;
37
38 typedef struct {
39 BCFG_OPERATION_TARGET Target;
40 BCFG_OPERATION_TYPE Type;
41 UINT16 Number1;
42 UINT16 Number2;
43 UINTN HandleIndex;
44 CHAR16 *FileName;
45 CHAR16 *Description;
46 UINT16 *Order;
47 CONST CHAR16 *OptData;
48 } BGFG_OPERATION;
49
50 /**
51 Update the optional data for a boot or driver option.
52
53 If optional data exists it will be changed.
54
55 @param[in] Index The boot or driver option index update.
56 @param[in] DataSize The size in bytes of Data.
57 @param[in] Data The buffer for the optioanl data.
58 @param[in] Target The target of the operation.
59
60 @retval EFI_SUCCESS The data was sucessfully updated.
61 @retval other A error occured.
62 **/
63 EFI_STATUS
64 EFIAPI
65 UpdateOptionalData(
66 UINT16 Index,
67 UINTN DataSize,
68 UINT8 *Data,
69 IN CONST BCFG_OPERATION_TARGET Target
70 )
71 {
72 EFI_STATUS Status;
73 CHAR16 VariableName[12];
74 UINTN OriginalSize;
75 UINT8 *OriginalData;
76 UINTN NewSize;
77 UINT8 *NewData;
78 UINTN OriginalOptionDataSize;
79
80 UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Target == BcfgTargetBootOrder?L"Boot":L"Driver", Index);
81
82 OriginalSize = 0;
83 OriginalData = NULL;
84 NewData = NULL;
85 NewSize = 0;
86
87 Status = gRT->GetVariable(
88 VariableName,
89 (EFI_GUID*)&gEfiGlobalVariableGuid,
90 NULL,
91 &OriginalSize,
92 OriginalData);
93 if (Status == EFI_BUFFER_TOO_SMALL) {
94 OriginalData = AllocateZeroPool(OriginalSize);
95 if (OriginalData == NULL) {
96 return (EFI_OUT_OF_RESOURCES);
97 }
98 Status = gRT->GetVariable(
99 VariableName,
100 (EFI_GUID*)&gEfiGlobalVariableGuid,
101 NULL,
102 &OriginalSize,
103 OriginalData);
104 }
105
106 if (!EFI_ERROR(Status)) {
107 //
108 // Allocate new struct and discard old optional data.
109 //
110 ASSERT (OriginalData != NULL);
111 OriginalOptionDataSize = sizeof(UINT32) + sizeof(UINT16) + StrSize(((CHAR16*)(OriginalData + sizeof(UINT32) + sizeof(UINT16))));
112 OriginalOptionDataSize += (*(UINT16*)(OriginalData + sizeof(UINT32)));
113 OriginalOptionDataSize -= OriginalSize;
114 NewSize = OriginalSize - OriginalOptionDataSize + DataSize;
115 NewData = AllocateCopyPool(NewSize, OriginalData);
116 if (NewData == NULL) {
117 Status = EFI_OUT_OF_RESOURCES;
118 } else {
119 CopyMem(NewData + OriginalSize - OriginalOptionDataSize, Data, DataSize);
120 }
121 }
122
123 if (!EFI_ERROR(Status)) {
124 //
125 // put the data back under the variable
126 //
127 Status = gRT->SetVariable(
128 VariableName,
129 (EFI_GUID*)&gEfiGlobalVariableGuid,
130 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
131 NewSize,
132 NewData);
133 }
134
135 SHELL_FREE_NON_NULL(OriginalData);
136 SHELL_FREE_NON_NULL(NewData);
137 return (Status);
138 }
139
140 /**
141 This function will get a CRC for a boot option.
142
143 @param[in, out] Crc The CRC value to return.
144 @param[in] BootIndex The boot option index to CRC.
145
146 @retval EFI_SUCCESS The CRC was sucessfully returned.
147 @retval other A error occured.
148 **/
149 EFI_STATUS
150 EFIAPI
151 GetBootOptionCrc(
152 UINT32 *Crc,
153 UINT16 BootIndex
154 )
155 {
156 CHAR16 VariableName[12];
157 EFI_STATUS Status;
158 UINT8 *Buffer;
159 UINTN BufferSize;
160
161 Buffer = NULL;
162 BufferSize = 0;
163
164 //
165 // Get the data Buffer
166 //
167 UnicodeSPrint(VariableName, sizeof(VariableName), L"%Boot%04x", BootIndex);
168 Status = gRT->GetVariable(
169 VariableName,
170 (EFI_GUID*)&gEfiGlobalVariableGuid,
171 NULL,
172 &BufferSize,
173 NULL);
174 if (Status == EFI_BUFFER_TOO_SMALL) {
175 Buffer = AllocateZeroPool(BufferSize);
176 Status = gRT->GetVariable(
177 VariableName,
178 (EFI_GUID*)&gEfiGlobalVariableGuid,
179 NULL,
180 &BufferSize,
181 Buffer);
182 }
183
184 //
185 // Get the CRC computed
186 //
187 if (!EFI_ERROR(Status)) {
188 Status = gBS->CalculateCrc32 (Buffer, BufferSize, Crc);
189 }
190
191 SHELL_FREE_NON_NULL(Buffer);
192 return EFI_SUCCESS;
193 }
194
195 /**
196 This function will populate the device path protocol parameter based on TheHandle.
197
198 @param[in] TheHandle Driver handle.
199 @param[in, out] FilePath On a sucessful return the device path to the handle.
200
201 @retval EFI_SUCCESS The device path was sucessfully returned.
202 @retval other A error from gBS->HandleProtocol.
203
204 @sa HandleProtocol
205 **/
206 EFI_STATUS
207 EFIAPI
208 GetDevicePathForDriverHandleInstall1 (
209 IN EFI_HANDLE TheHandle,
210 IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath
211 )
212 {
213 EFI_STATUS Status;
214 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
215 EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
216
217 Status = gBS->OpenProtocol (
218 TheHandle,
219 &gEfiLoadedImageProtocolGuid,
220 (VOID**)&LoadedImage,
221 gImageHandle,
222 NULL,
223 EFI_OPEN_PROTOCOL_GET_PROTOCOL
224 );
225 if (!EFI_ERROR (Status)) {
226 Status = gBS->OpenProtocol (
227 LoadedImage->DeviceHandle,
228 &gEfiDevicePathProtocolGuid,
229 (VOID**)&ImageDevicePath,
230 gImageHandle,
231 NULL,
232 EFI_OPEN_PROTOCOL_GET_PROTOCOL
233 );
234 if (!EFI_ERROR (Status)) {
235 // *DevPath = DuplicateDevicePath (ImageDevicePath);
236 // *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
237 *FilePath = AppendDevicePath(ImageDevicePath,LoadedImage->FilePath);
238 gBS->CloseProtocol(
239 LoadedImage->DeviceHandle,
240 &gEfiDevicePathProtocolGuid,
241 gImageHandle,
242 NULL);
243 }
244 gBS->CloseProtocol(
245 TheHandle,
246 &gEfiLoadedImageProtocolGuid,
247 gImageHandle,
248 NULL);
249 }
250 return (Status);
251 }
252
253 /**
254 Function to add a option.
255
256 @param[in] Position The position to add Target at.
257 @param[in] File The file to make the target.
258 @param[in] Desc The description text.
259 @param[in] CurrentOrder The pointer to the current order of items.
260 @param[in] OrderCount The number if items in CurrentOrder.
261 @param[in] Target The info on the option to add.
262 @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.
263 @param[in] UsePath TRUE to convert to devicepath.
264 @param[in] HandleNumber The handle number to add.
265
266 @retval SHELL_SUCCESS The operation was successful.
267 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
268 **/
269 SHELL_STATUS
270 EFIAPI
271 BcfgAddInstall1(
272 IN UINTN Position,
273 IN CONST CHAR16 *File,
274 IN CONST CHAR16 *Desc,
275 IN CONST UINT16 *CurrentOrder,
276 IN CONST UINTN OrderCount,
277 IN CONST BCFG_OPERATION_TARGET Target,
278 IN CONST BOOLEAN UseHandle,
279 IN CONST BOOLEAN UsePath,
280 IN CONST UINTN HandleNumber
281 )
282 {
283 EFI_STATUS Status;
284 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
285 EFI_DEVICE_PATH_PROTOCOL *FilePath;
286 CHAR16 *Str;
287 UINT8 *TempByteBuffer;
288 UINT8 *TempByteStart;
289 EFI_SHELL_FILE_INFO *Arg;
290 EFI_SHELL_FILE_INFO *FileList;
291 CHAR16 OptionStr[40];
292 UINTN DescSize, FilePathSize;
293 BOOLEAN Found;
294 UINTN TargetLocation;
295 UINTN Index;
296 EFI_HANDLE *Handles;
297 EFI_HANDLE CurHandle;
298 UINTN DriverBindingHandleCount;
299 UINTN ParentControllerHandleCount;
300 UINTN ChildControllerHandleCount;
301 SHELL_STATUS ShellStatus;
302 UINT16 *NewOrder;
303
304 if (!UseHandle) {
305 if (File == NULL || Desc == NULL) {
306 return (SHELL_INVALID_PARAMETER);
307 }
308 } else {
309 if (HandleNumber == 0) {
310 return (SHELL_INVALID_PARAMETER);
311 }
312 }
313
314 if (Position > OrderCount) {
315 Position = OrderCount;
316 }
317
318 Str = NULL;
319 FilePath = NULL;
320 FileList = NULL;
321 Handles = NULL;
322 ShellStatus = SHELL_SUCCESS;
323 TargetLocation = 0xFFFF;
324
325 if (UseHandle) {
326 CurHandle = ConvertHandleIndexToHandle(HandleNumber);
327 if (CurHandle == NULL) {
328 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, L"Handle Number");
329 ShellStatus = SHELL_INVALID_PARAMETER;
330 } else {
331 if (Target == BcfgTargetBootOrder) {
332 //
333 //Make sure that the handle should point to a real controller
334 //
335 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
336 CurHandle,
337 &DriverBindingHandleCount,
338 NULL);
339
340 Status = PARSE_HANDLE_DATABASE_PARENTS (
341 CurHandle,
342 &ParentControllerHandleCount,
343 NULL);
344
345 Status = ParseHandleDatabaseForChildControllers (
346 CurHandle,
347 &ChildControllerHandleCount,
348 NULL);
349
350 if (DriverBindingHandleCount > 0
351 || ParentControllerHandleCount > 0
352 || ChildControllerHandleCount > 0) {
353 FilePath = NULL;
354 Status = gBS->HandleProtocol (
355 CurHandle,
356 &gEfiDevicePathProtocolGuid,
357 (VOID**)&FilePath);
358 }
359 if (EFI_ERROR (Status)) {
360 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_HANDLE), gShellInstall1HiiHandle, HandleNumber);
361 ShellStatus = SHELL_INVALID_PARAMETER;
362 }
363 } else {
364 //
365 //Make sure that the handle should point to driver, not a controller.
366 //
367 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
368 CurHandle,
369 &DriverBindingHandleCount,
370 NULL);
371
372 Status = PARSE_HANDLE_DATABASE_PARENTS (
373 CurHandle,
374 &ParentControllerHandleCount,
375 NULL);
376
377 Status = ParseHandleDatabaseForChildControllers (
378 CurHandle,
379 &ChildControllerHandleCount,
380 NULL);
381
382 Status = gBS->HandleProtocol (
383 CurHandle,
384 &gEfiDevicePathProtocolGuid,
385 (VOID**)&FilePath);
386
387 if (DriverBindingHandleCount > 0
388 || ParentControllerHandleCount > 0
389 || ChildControllerHandleCount > 0
390 || !EFI_ERROR(Status) ) {
391 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, L"Handle Number");
392 ShellStatus = SHELL_INVALID_PARAMETER;
393 } else {
394 //
395 // Get the DevicePath from the loaded image information.
396 //
397 Status = GetDevicePathForDriverHandleInstall1(CurHandle, &FilePath);
398 }
399 }
400 }
401 } else {
402 //
403 // Get file info
404 //
405 ShellOpenFileMetaArg ((CHAR16*)File, EFI_FILE_MODE_READ, &FileList);
406
407 if (FileList == NULL) {
408 //
409 // If filename matched nothing fail
410 //
411 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellInstall1HiiHandle, File);
412 ShellStatus = SHELL_INVALID_PARAMETER;
413 } else if (FileList->Link.ForwardLink != FileList->Link.BackLink) {
414 //
415 // If filename expanded to multiple names, fail
416 //
417 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellInstall1HiiHandle, File);
418 ShellStatus = SHELL_INVALID_PARAMETER;
419 } else {
420 Arg = (EFI_SHELL_FILE_INFO*)GetFirstNode(&FileList->Link);
421 if (EFI_ERROR(Arg->Status)) {
422 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellInstall1HiiHandle, File, Arg->Status);
423 ShellStatus = SHELL_INVALID_PARAMETER;
424 } else {
425 //
426 // Build FilePath to the filename
427 //
428
429 //
430 // get the device path
431 //
432 DevicePath = gEfiShellProtocol->GetDevicePathFromFilePath(Arg->FullName);
433 if (DevicePath == NULL) {
434 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellInstall1HiiHandle, Arg->FullName);
435 ShellStatus = SHELL_UNSUPPORTED;
436 } else {
437 /*
438 if (UsePath) {
439 DevPath = DevicePath;
440 while (!IsDevicePathEnd(DevPath)) {
441 if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&
442 (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {
443
444 //
445 // If we find it use it instead
446 //
447 DevicePath = DevPath;
448 break;
449 }
450 DevPath = NextDevicePathNode(DevPath);
451 }
452 //
453 // append the file
454 //
455 for(StringWalker=Arg->FullName; *StringWalker != CHAR_NULL && *StringWalker != ':'; StringWalker++);
456 FileNode = FileDevicePath(NULL, StringWalker+1);
457 FilePath = AppendDevicePath(DevicePath, FileNode);
458 FreePool(FileNode);
459 } else {
460 */
461 FilePath = DuplicateDevicePath(DevicePath);
462 /*
463 }
464 */
465 FreePool(DevicePath);
466 }
467 }
468 }
469 }
470
471
472 if (ShellStatus == SHELL_SUCCESS) {
473 //
474 // Find a free target ,a brute force implementation
475 //
476 Found = FALSE;
477 for (TargetLocation=0; TargetLocation < 0xFFFF; TargetLocation++) {
478 Found = TRUE;
479 for (Index=0; Index < OrderCount; Index++) {
480 if (CurrentOrder[Index] == TargetLocation) {
481 Found = FALSE;
482 break;
483 }
484 }
485
486 if (Found) {
487 break;
488 }
489 }
490
491 if (TargetLocation == 0xFFFF) {
492 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET_NF), gShellInstall1HiiHandle);
493 } else {
494 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET), gShellInstall1HiiHandle, TargetLocation);
495 }
496 }
497
498 if (ShellStatus == SHELL_SUCCESS) {
499 //
500 // Add the option
501 //
502 DescSize = StrSize(Desc);
503 FilePathSize = GetDevicePathSize (FilePath);
504
505 TempByteBuffer = AllocateZeroPool(sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize);
506 if (TempByteBuffer != NULL) {
507 TempByteStart = TempByteBuffer;
508 *((UINT32 *) TempByteBuffer) = LOAD_OPTION_ACTIVE; // Attributes
509 TempByteBuffer += sizeof (UINT32);
510
511 *((UINT16 *) TempByteBuffer) = (UINT16)FilePathSize; // FilePathListLength
512 TempByteBuffer += sizeof (UINT16);
513
514 CopyMem (TempByteBuffer, Desc, DescSize);
515 TempByteBuffer += DescSize;
516 ASSERT (FilePath != NULL);
517 CopyMem (TempByteBuffer, FilePath, FilePathSize);
518
519 UnicodeSPrint (OptionStr, sizeof(OptionStr), L"%s%04x", Target == BcfgTargetBootOrder?L"Boot":L"Driver", TargetLocation);
520 Status = gRT->SetVariable (
521 OptionStr,
522 &gEfiGlobalVariableGuid,
523 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
524 sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize,
525 TempByteStart
526 );
527
528 FreePool(TempByteStart);
529 } else {
530 Status = EFI_OUT_OF_RESOURCES;
531 }
532
533 if (EFI_ERROR(Status)) {
534 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellInstall1HiiHandle, OptionStr, Status);
535 } else {
536 NewOrder = AllocateZeroPool((OrderCount+1)*sizeof(NewOrder[0]));
537 ASSERT(NewOrder != NULL);
538 CopyMem(NewOrder, CurrentOrder, (OrderCount)*sizeof(NewOrder[0]));
539
540 //
541 // Insert target into order list
542 //
543 for (Index=OrderCount; Index > Position; Index--) {
544 NewOrder[Index] = NewOrder[Index-1];
545 }
546
547 NewOrder[Position] = (UINT16) TargetLocation;
548 Status = gRT->SetVariable (
549 Target == BcfgTargetBootOrder?L"BootOrder":L"DriverOrder",
550 &gEfiGlobalVariableGuid,
551 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
552 (OrderCount+1) * sizeof(UINT16),
553 NewOrder
554 );
555
556 FreePool(NewOrder);
557
558 if (EFI_ERROR(Status)) {
559 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, Target == BcfgTargetBootOrder?L"BootOrder":L"DriverOrder", Status);
560 ShellStatus = SHELL_INVALID_PARAMETER;
561 } else {
562 Print (L"bcfg: Add %s as %x\n", OptionStr, Position);
563 }
564 }
565 }
566
567 //
568 //If always Free FilePath, will free devicepath in system when use "addh"
569 //
570 if (FilePath!=NULL && !UseHandle) {
571 FreePool (FilePath);
572 }
573
574 if (Str != NULL) {
575 FreePool(Str);
576 }
577
578 if (Handles != NULL) {
579 FreePool (Handles);
580 }
581
582 if (FileList != NULL) {
583 ShellCloseFileMetaArg (&FileList);
584 }
585
586 return (ShellStatus);
587 }
588
589 /**
590 Funciton to remove an item.
591
592 @param[in] Target The target item to move.
593 @param[in] CurrentOrder The pointer to the current order of items.
594 @param[in] OrderCount The number if items in CurrentOrder.
595 @param[in] Location The current location of the Target.
596
597 @retval SHELL_SUCCESS The operation was successful.
598 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
599 **/
600 SHELL_STATUS
601 EFIAPI
602 BcfgRemoveInstall1(
603 IN CONST BCFG_OPERATION_TARGET Target,
604 IN CONST UINT16 *CurrentOrder,
605 IN CONST UINTN OrderCount,
606 IN CONST UINT16 Location
607 )
608 {
609 CHAR16 VariableName[12];
610 UINT16 *NewOrder;
611 EFI_STATUS Status;
612 UINTN NewCount;
613
614 UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Target == BcfgTargetBootOrder?L"Boot":L"Driver", CurrentOrder[Location]);
615 Status = gRT->SetVariable(
616 VariableName,
617 (EFI_GUID*)&gEfiGlobalVariableGuid,
618 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
619 0,
620 NULL);
621 if (EFI_ERROR(Status)) {
622 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, VariableName, Status);
623 return (SHELL_INVALID_PARAMETER);
624 }
625 NewOrder = AllocateZeroPool(OrderCount*sizeof(CurrentOrder[0]));
626 if (NewOrder != NULL) {
627 NewCount = OrderCount;
628 CopyMem(NewOrder, CurrentOrder, OrderCount*sizeof(CurrentOrder[0]));
629 CopyMem(NewOrder+Location, NewOrder+Location+1, (OrderCount - Location - 1)*sizeof(CurrentOrder[0]));
630 NewCount--;
631
632 Status = gRT->SetVariable(
633 Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",
634 (EFI_GUID*)&gEfiGlobalVariableGuid,
635 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
636 NewCount*sizeof(NewOrder[0]),
637 NewOrder);
638 FreePool(NewOrder);
639 } else {
640 Status = EFI_OUT_OF_RESOURCES;
641 }
642 if (EFI_ERROR(Status)) {
643 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder", Status);
644 return (SHELL_INVALID_PARAMETER);
645 }
646 return (SHELL_SUCCESS);
647 }
648
649 /**
650 Funciton to move a item to another location.
651
652 @param[in] Target The target item to move.
653 @param[in] CurrentOrder The pointer to the current order of items.
654 @param[in] OrderCount The number if items in CurrentOrder.
655 @param[in] OldLocation The current location of the Target.
656 @param[in] NewLocation The desired location of the Target.
657
658 @retval SHELL_SUCCESS The operation was successful.
659 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
660 **/
661 SHELL_STATUS
662 EFIAPI
663 BcfgMoveInstall1(
664 IN CONST BCFG_OPERATION_TARGET Target,
665 IN CONST UINT16 *CurrentOrder,
666 IN CONST UINTN OrderCount,
667 IN CONST UINT16 OldLocation,
668 IN CONST UINT16 NewLocation
669 )
670 {
671 UINT16 *NewOrder;
672 EFI_STATUS Status;
673 UINT16 Temp;
674
675 NewOrder = AllocateZeroPool(OrderCount*sizeof(CurrentOrder[0]));
676 ASSERT(NewOrder != NULL);
677
678 Temp = CurrentOrder[OldLocation];
679 CopyMem(NewOrder, CurrentOrder, OrderCount*sizeof(CurrentOrder[0]));
680 CopyMem(NewOrder+OldLocation, NewOrder+OldLocation+1, (OrderCount - OldLocation - 1)*sizeof(CurrentOrder[0]));
681 CopyMem(NewOrder+NewLocation+1, NewOrder+NewLocation, (OrderCount - NewLocation - 1)*sizeof(CurrentOrder[0]));
682 NewOrder[NewLocation] = Temp;
683
684
685 Status = gRT->SetVariable(
686 Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",
687 (EFI_GUID*)&gEfiGlobalVariableGuid,
688 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
689 OrderCount*sizeof(CurrentOrder[0]),
690 NewOrder);
691
692 FreePool(NewOrder);
693
694 if (EFI_ERROR(Status)) {
695 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder", Status);
696 return (SHELL_INVALID_PARAMETER);
697 }
698 return (SHELL_SUCCESS);
699 }
700
701 /**
702 Function to add optional data to an option.
703
704 @param[in] OptData The optional data to add.
705 @param[in] CurrentOrder The pointer to the current order of items.
706 @param[in] OrderCount The number if items in CurrentOrder.
707 @param[in] Target The target of the operation.
708
709 @retval SHELL_SUCCESS The operation was succesful.
710 **/
711 SHELL_STATUS
712 EFIAPI
713 BcfgAddOptInstall1(
714 IN CONST CHAR16 *OptData,
715 IN CONST UINT16 *CurrentOrder,
716 IN CONST UINTN OrderCount,
717 IN CONST BCFG_OPERATION_TARGET Target
718 )
719 {
720 EFI_KEY_OPTION NewKeyOption;
721 EFI_KEY_OPTION *KeyOptionBuffer;
722 SHELL_STATUS ShellStatus;
723 EFI_STATUS Status;
724 UINT16 OptionIndex;
725 UINT16 LoopCounter;
726 UINT64 Intermediate;
727 CONST CHAR16 *Temp;
728 CONST CHAR16 *Walker;
729 CHAR16 *FileName;
730 CHAR16 *Temp2;
731 CHAR16 *Data;
732 UINT16 KeyIndex;
733 CHAR16 VariableName[12];
734
735 SHELL_FILE_HANDLE FileHandle;
736
737 Status = EFI_SUCCESS;
738 ShellStatus = SHELL_SUCCESS;
739 Walker = OptData;
740 FileName = NULL;
741 Data = NULL;
742 KeyOptionBuffer = NULL;
743
744 ZeroMem(&NewKeyOption, sizeof(EFI_KEY_OPTION));
745
746 while(Walker[0] == L' ') {
747 Walker++;
748 }
749
750 //
751 // Get the index of the variable we are changing.
752 //
753 Status = ShellConvertStringToUint64(Walker, &Intermediate, FALSE, TRUE);
754 if (EFI_ERROR(Status) || (((UINT16)Intermediate) != Intermediate) || StrStr(Walker, L" ") == NULL || ((UINT16)Intermediate) > ((UINT16)OrderCount)) {
755 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, L"Option Index");
756 ShellStatus = SHELL_INVALID_PARAMETER;
757 return (ShellStatus);
758 }
759 OptionIndex = (UINT16)Intermediate;
760
761 Temp = StrStr(Walker, L" ");
762 if (Temp != NULL) {
763 Walker = Temp;
764 }
765 while(Walker[0] == L' ') {
766 Walker++;
767 }
768
769 //
770 // determine whether we have file with data, quote delimited information, or a hot-key
771 //
772 if (Walker[0] == L'\"') {
773 //
774 // quoted filename or quoted information.
775 //
776 Temp = StrStr(Walker+1, L"\"");
777 if (Temp == NULL || StrLen(Temp) != 1) {
778 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, Walker);
779 ShellStatus = SHELL_INVALID_PARAMETER;
780 } else {
781 FileName = StrnCatGrow(&FileName, NULL, Walker+1, 0);
782 if (FileName == NULL) {
783 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellInstall1HiiHandle);
784 ShellStatus = SHELL_OUT_OF_RESOURCES;
785 return (ShellStatus);
786 }
787 Temp2 = StrStr(FileName, L"\"");
788 ASSERT(Temp2 != NULL);
789 Temp2[0] = CHAR_NULL;
790 Temp2++;
791 if (StrLen(Temp2)>0) {
792 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, Walker);
793 ShellStatus = SHELL_INVALID_PARAMETER;
794 }
795 if (EFI_ERROR(ShellFileExists(Walker))) {
796 //
797 // Not a file. must be misc information.
798 //
799 Data = FileName;
800 FileName = NULL;
801 } else {
802 FileName = StrnCatGrow(&FileName, NULL, Walker, 0);
803 }
804 }
805 } else {
806 //
807 // filename or hot key information.
808 //
809 if (StrStr(Walker, L" ") == NULL) {
810 //
811 // filename
812 //
813 if (EFI_ERROR(ShellFileExists(Walker))) {
814 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FIND_FAIL), gShellInstall1HiiHandle, Walker);
815 ShellStatus = SHELL_INVALID_PARAMETER;
816 } else {
817 FileName = StrnCatGrow(&FileName, NULL, Walker, 0);
818 }
819 } else {
820 if (Target != BcfgTargetBootOrder) {
821 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_BOOT_ONLY), gShellInstall1HiiHandle);
822 ShellStatus = SHELL_INVALID_PARAMETER;
823 }
824
825 if (ShellStatus == SHELL_SUCCESS) {
826 //
827 // Get hot key information
828 //
829 Status = ShellConvertStringToUint64(Walker, &Intermediate, FALSE, TRUE);
830 if (EFI_ERROR(Status) || (((UINT32)Intermediate) != Intermediate) || StrStr(Walker, L" ") == NULL) {
831 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, Walker);
832 ShellStatus = SHELL_INVALID_PARAMETER;
833 }
834 NewKeyOption.KeyData.PackedValue = (UINT32)Intermediate;
835 Temp = StrStr(Walker, L" ");
836 if (Temp != NULL) {
837 Walker = Temp;
838 }
839 while(Walker[0] == L' ') {
840 Walker++;
841 }
842 }
843
844 if (ShellStatus == SHELL_SUCCESS) {
845 //
846 // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
847 // Re-allocate with the added information.
848 //
849 KeyOptionBuffer = AllocateCopyPool(sizeof(EFI_KEY_OPTION) + (sizeof(EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount), &NewKeyOption);
850 if (KeyOptionBuffer == NULL) {
851 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellInstall1HiiHandle);
852 ShellStatus = SHELL_OUT_OF_RESOURCES;
853 }
854 }
855 for (LoopCounter = 0 ; ShellStatus == SHELL_SUCCESS && LoopCounter < NewKeyOption.KeyData.Options.InputKeyCount; LoopCounter++) {
856 //
857 // ScanCode
858 //
859 Status = ShellConvertStringToUint64(Walker, &Intermediate, FALSE, TRUE);
860 if (EFI_ERROR(Status) || (((UINT16)Intermediate) != Intermediate) || StrStr(Walker, L" ") == NULL) {
861 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, Walker);
862 ShellStatus = SHELL_INVALID_PARAMETER;
863 }
864 ((EFI_INPUT_KEY*)(((UINT8*)KeyOptionBuffer) + sizeof(EFI_KEY_OPTION)))[LoopCounter].ScanCode = (UINT16)Intermediate;
865 Temp = StrStr(Walker, L" ");
866 if (Temp != NULL) {
867 Walker = Temp;
868 }
869 while(Walker[0] == L' ') {
870 Walker++;
871 }
872
873 //
874 // UnicodeChar
875 //
876 Status = ShellConvertStringToUint64(Walker, &Intermediate, FALSE, TRUE);
877 if (EFI_ERROR(Status) || (((UINT16)Intermediate) != Intermediate)) {
878 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, Walker);
879 ShellStatus = SHELL_INVALID_PARAMETER;
880 }
881 ((EFI_INPUT_KEY*)(((UINT8*)KeyOptionBuffer) + sizeof(EFI_KEY_OPTION)))[LoopCounter].UnicodeChar = (UINT16)Intermediate;
882 Temp = StrStr(Walker, L" ");
883 if (Temp != NULL) {
884 Walker = Temp;
885 }
886 while(Walker[0] == L' ') {
887 Walker++;
888 }
889 }
890
891 if (ShellStatus == SHELL_SUCCESS) {
892 //
893 // Now do the BootOption / BootOptionCrc
894 //
895 ASSERT (OptionIndex <= OrderCount);
896 KeyOptionBuffer->BootOption = CurrentOrder[OptionIndex];
897 Status = GetBootOptionCrc(&(KeyOptionBuffer->BootOptionCrc), KeyOptionBuffer->BootOption);
898 if (EFI_ERROR(Status)) {
899 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, L"Option Index");
900 ShellStatus = SHELL_INVALID_PARAMETER;
901 }
902 }
903
904 if (ShellStatus == SHELL_SUCCESS) {
905 for (Temp2 = NULL, KeyIndex = 0 ; KeyIndex < 0xFFFF ; KeyIndex++) {
906 UnicodeSPrint(VariableName, sizeof(VariableName), L"Key%04x", KeyIndex);
907 Status = gRT->GetVariable(
908 VariableName,
909 (EFI_GUID*)&gEfiGlobalVariableGuid,
910 NULL,
911 (UINTN*)&Intermediate,
912 NULL);
913 if (Status == EFI_NOT_FOUND) {
914 break;
915 }
916 }
917 Status = gRT->SetVariable(
918 VariableName,
919 (EFI_GUID*)&gEfiGlobalVariableGuid,
920 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
921 sizeof(EFI_KEY_OPTION) + (sizeof(EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount),
922 KeyOptionBuffer);
923 if (EFI_ERROR(Status)) {
924 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellInstall1HiiHandle, VariableName, Status);
925 ShellStatus = SHELL_INVALID_PARAMETER;
926 }
927 ASSERT(FileName == NULL && Data == NULL);
928 }
929 }
930 }
931
932 //
933 // Shouldn't be possible to have have both. Neither is ok though.
934 //
935 ASSERT(FileName == NULL || Data == NULL);
936
937 if (ShellStatus == SHELL_SUCCESS && (FileName != NULL || Data != NULL)) {
938 if (FileName != NULL) {
939 //
940 // Open the file and populate the data buffer.
941 //
942 Status = ShellOpenFileByName(
943 FileName,
944 &FileHandle,
945 EFI_FILE_MODE_READ,
946 0);
947 if (!EFI_ERROR(Status)) {
948 Status = ShellGetFileSize(FileHandle, &Intermediate);
949 }
950 Data = AllocateZeroPool((UINTN)Intermediate);
951 if (Data == NULL) {
952 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellInstall1HiiHandle);
953 ShellStatus = SHELL_OUT_OF_RESOURCES;
954 }
955 if (!EFI_ERROR(Status)) {
956 Status = ShellReadFile(FileHandle, (UINTN *)&Intermediate, Data);
957 }
958 } else {
959 Intermediate = StrSize(Data);
960 }
961
962 if (!EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS && Data != NULL) {
963 Status = UpdateOptionalData(CurrentOrder[OptionIndex], (UINTN)Intermediate, (UINT8*)Data, Target);
964 if (EFI_ERROR(Status)) {
965 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellInstall1HiiHandle, VariableName, Status);
966 ShellStatus = SHELL_INVALID_PARAMETER;
967 }
968 }
969 if (EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS) {
970 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellInstall1HiiHandle, VariableName, Status);
971 ShellStatus = SHELL_INVALID_PARAMETER;
972 }
973 }
974
975 SHELL_FREE_NON_NULL(Data);
976 SHELL_FREE_NON_NULL(KeyOptionBuffer);
977 SHELL_FREE_NON_NULL(FileName);
978 return ShellStatus;
979 }
980
981 /**
982 Function to dump the Bcfg information.
983
984 @param[in] Op The operation.
985 @param[in] OrderCount How many to dump.
986 @param[in] CurrentOrder The pointer to the current order of items.
987 @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.
988
989 @retval SHELL_SUCCESS The dump was successful.
990 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
991 **/
992 SHELL_STATUS
993 EFIAPI
994 BcfgDisplayDumpInstall1(
995 IN CONST CHAR16 *Op,
996 IN CONST UINTN OrderCount,
997 IN CONST UINT16 *CurrentOrder,
998 IN CONST BOOLEAN VerboseOutput
999 )
1000 {
1001 EFI_STATUS Status;
1002 UINT8 *Buffer;
1003 UINTN BufferSize;
1004 CHAR16 VariableName[12];
1005 UINTN LoopVar;
1006 UINTN LoopVar2;
1007 CHAR16 *DevPathString;
1008 VOID *DevPath;
1009
1010 if (OrderCount == 0) {
1011 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_BCFG_NONE), gShellInstall1HiiHandle);
1012 return (SHELL_SUCCESS);
1013 }
1014
1015 for (LoopVar = 0 ; LoopVar < OrderCount ; LoopVar++) {
1016 Buffer = NULL;
1017 BufferSize = 0;
1018 UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Op, CurrentOrder[LoopVar]);
1019
1020 Status = gRT->GetVariable(
1021 VariableName,
1022 (EFI_GUID*)&gEfiGlobalVariableGuid,
1023 NULL,
1024 &BufferSize,
1025 Buffer);
1026 if (Status == EFI_BUFFER_TOO_SMALL) {
1027 Buffer = AllocateZeroPool(BufferSize);
1028 Status = gRT->GetVariable(
1029 VariableName,
1030 (EFI_GUID*)&gEfiGlobalVariableGuid,
1031 NULL,
1032 &BufferSize,
1033 Buffer);
1034 }
1035
1036 if (EFI_ERROR(Status) || Buffer == NULL) {
1037 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_READ_FAIL), gShellInstall1HiiHandle, VariableName, Status);
1038 return (SHELL_INVALID_PARAMETER);
1039 }
1040
1041 if ((*(UINT16*)(Buffer+4)) != 0) {
1042 DevPath = AllocateZeroPool(*(UINT16*)(Buffer+4));
1043 if (DevPath == NULL) {
1044 DevPathString = NULL;
1045 } else {
1046 CopyMem(DevPath, Buffer+6+StrSize((CHAR16*)(Buffer+6)), *(UINT16*)(Buffer+4));
1047 DevPathString = ConvertDevicePathToText(DevPath, TRUE, FALSE);
1048 }
1049 } else {
1050 DevPath = NULL;
1051 DevPathString = NULL;
1052 }
1053 ShellPrintHiiEx(
1054 -1,
1055 -1,
1056 NULL,
1057 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS),
1058 gShellInstall1HiiHandle,
1059 LoopVar,
1060 VariableName,
1061 (CHAR16*)(Buffer+6),
1062 DevPathString,
1063 (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6) <= BufferSize?L'N':L'Y');
1064 if (VerboseOutput) {
1065 for (LoopVar2 = (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6);LoopVar2<BufferSize;LoopVar2++){
1066 ShellPrintEx(
1067 -1,
1068 -1,
1069 NULL,
1070 L"%02x",
1071 Buffer[LoopVar2]);
1072 }
1073 ShellPrintEx(
1074 -1,
1075 -1,
1076 NULL,
1077 L"\r\n");
1078 }
1079
1080 if (Buffer != NULL) {
1081 FreePool(Buffer);
1082 }
1083 if (DevPath != NULL) {
1084 FreePool(DevPath);
1085 }
1086 if (DevPathString != NULL) {
1087 FreePool(DevPathString);
1088 }
1089 }
1090 return (SHELL_SUCCESS);
1091 }
1092
1093 /**
1094 Function to initialize the BCFG operation structure.
1095
1096 @param[in] Struct The stuct to initialize.
1097 **/
1098 VOID
1099 EFIAPI
1100 InitBcfgStructInstall1(
1101 IN BGFG_OPERATION *Struct
1102 )
1103 {
1104 ASSERT(Struct != NULL);
1105 Struct->Target = BcfgTargetMax;
1106 Struct->Type = BcfgTypeMax;
1107 Struct->Number1 = 0;
1108 Struct->Number2 = 0;
1109 Struct->HandleIndex = 0;
1110 Struct->FileName = NULL;
1111 Struct->Description = NULL;
1112 Struct->Order = NULL;
1113 Struct->OptData = NULL;
1114 }
1115
1116
1117 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
1118 {L"-v", TypeFlag},
1119 {L"-opt", TypeMaxValue},
1120 {NULL, TypeMax}
1121 };
1122
1123 /**
1124 Function for 'bcfg' command.
1125
1126 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1127 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1128 **/
1129 SHELL_STATUS
1130 EFIAPI
1131 ShellCommandRunBcfgInstall (
1132 IN EFI_HANDLE ImageHandle,
1133 IN EFI_SYSTEM_TABLE *SystemTable
1134 )
1135 {
1136 EFI_STATUS Status;
1137 LIST_ENTRY *Package;
1138 CHAR16 *ProblemParam;
1139 SHELL_STATUS ShellStatus;
1140 UINTN ParamNumber;
1141 CONST CHAR16 *CurrentParam;
1142 BGFG_OPERATION CurrentOperation;
1143 UINTN Length;
1144 UINT64 Intermediate;
1145
1146 Length = 0;
1147 ProblemParam = NULL;
1148 Package = NULL;
1149 ShellStatus = SHELL_SUCCESS;
1150
1151 InitBcfgStructInstall1(&CurrentOperation);
1152
1153 //
1154 // initialize the shell lib (we must be in non-auto-init...)
1155 //
1156 Status = ShellInitialize();
1157 ASSERT_EFI_ERROR(Status);
1158
1159 Status = CommandInit();
1160 ASSERT_EFI_ERROR(Status);
1161
1162 //
1163 // parse the command line
1164 //
1165 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
1166 if (EFI_ERROR(Status)) {
1167 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
1168 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, ProblemParam);
1169 FreePool(ProblemParam);
1170 ShellStatus = SHELL_INVALID_PARAMETER;
1171 } else {
1172 ASSERT(FALSE);
1173 }
1174 } else {
1175 //
1176 // Read in if we are doing -OPT
1177 //
1178 if (ShellCommandLineGetFlag(Package, L"-opt")) {
1179 CurrentOperation.OptData = ShellCommandLineGetValue(Package, L"-opt");
1180 if (CurrentOperation.OptData == NULL) {
1181 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellInstall1HiiHandle, L"-opt");
1182 ShellStatus = SHELL_INVALID_PARAMETER;
1183 }
1184 CurrentOperation.Type = BcfgTypeOpt;
1185 }
1186
1187 //
1188 // small block to read the target of the operation
1189 //
1190 if ((ShellCommandLineGetCount(Package) < 3 && CurrentOperation.Type != BcfgTypeOpt) ||
1191 (ShellCommandLineGetCount(Package) < 2 && CurrentOperation.Type == BcfgTypeOpt)
1192 ){
1193 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
1194 ShellStatus = SHELL_INVALID_PARAMETER;
1195 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"driver") == 0) {
1196 CurrentOperation.Target = BcfgTargetDriverOrder;
1197 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"boot") == 0) {
1198 CurrentOperation.Target = BcfgTargetBootOrder;
1199 } else {
1200 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT), gShellInstall1HiiHandle);
1201 ShellStatus = SHELL_INVALID_PARAMETER;
1202 }
1203
1204
1205 //
1206 // Read in the boot or driver order environment variable (not needed for opt)
1207 //
1208 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BcfgTargetMax) {
1209 Length = 0;
1210 Status = gRT->GetVariable(
1211 CurrentOperation.Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",
1212 (EFI_GUID*)&gEfiGlobalVariableGuid,
1213 NULL,
1214 &Length,
1215 CurrentOperation.Order);
1216 if (Status == EFI_BUFFER_TOO_SMALL) {
1217 CurrentOperation.Order = AllocateZeroPool(Length+(4*sizeof(CurrentOperation.Order[0])));
1218 if (CurrentOperation.Order == NULL) {
1219 ShellStatus = SHELL_OUT_OF_RESOURCES;
1220 } else {
1221 Status = gRT->GetVariable(
1222 CurrentOperation.Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",
1223 (EFI_GUID*)&gEfiGlobalVariableGuid,
1224 NULL,
1225 &Length,
1226 CurrentOperation.Order);
1227 }
1228 }
1229 }
1230
1231 //
1232 // large block to read the type of operation and verify parameter types for the info.
1233 //
1234 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BcfgTargetMax) {
1235 for (ParamNumber = 2 ; ParamNumber < ShellCommandLineGetCount(Package) && ShellStatus == SHELL_SUCCESS; ParamNumber++) {
1236 CurrentParam = ShellCommandLineGetRawValue(Package, ParamNumber);
1237 if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"dump") == 0) {
1238 CurrentOperation.Type = BcfgTypeDump;
1239 } else if (ShellCommandLineGetFlag(Package, L"-v")) {
1240 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, L"-v (without dump)");
1241 ShellStatus = SHELL_INVALID_PARAMETER;
1242 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"add") == 0) {
1243 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {
1244 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
1245 ShellStatus = SHELL_INVALID_PARAMETER;
1246 }
1247 CurrentOperation.Type = BcfgTypeAdd;
1248 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
1249 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
1250 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1251 ShellStatus = SHELL_INVALID_PARAMETER;
1252 } else {
1253 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
1254 CurrentOperation.Number1 = (UINT16)Intermediate;
1255 ASSERT(CurrentOperation.FileName == NULL);
1256 CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
1257 ASSERT(CurrentOperation.Description == NULL);
1258 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
1259 }
1260 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addp") == 0) {
1261 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {
1262 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
1263 ShellStatus = SHELL_INVALID_PARAMETER;
1264 }
1265 CurrentOperation.Type = BcfgTypeAddp;
1266 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
1267 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
1268 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1269 ShellStatus = SHELL_INVALID_PARAMETER;
1270 } else {
1271 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
1272 CurrentOperation.Number1 = (UINT16)Intermediate;
1273 ASSERT(CurrentOperation.FileName == NULL);
1274 CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
1275 ASSERT(CurrentOperation.Description == NULL);
1276 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
1277 }
1278 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addh") == 0) {
1279 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {
1280 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
1281 ShellStatus = SHELL_INVALID_PARAMETER;
1282 }
1283 CurrentOperation.Type = BcfgTypeAddh;
1284 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
1285 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
1286 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1287 ShellStatus = SHELL_INVALID_PARAMETER;
1288 } else {
1289 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
1290 CurrentOperation.Number1 = (UINT16)Intermediate;
1291 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
1292 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
1293 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1294 ShellStatus = SHELL_INVALID_PARAMETER;
1295 } else {
1296 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
1297 CurrentOperation.HandleIndex = (UINT16)Intermediate;
1298 ASSERT(CurrentOperation.Description == NULL);
1299 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
1300 }
1301 }
1302 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"rm") == 0) {
1303 if ((ParamNumber + 1) >= ShellCommandLineGetCount(Package)) {
1304 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
1305 ShellStatus = SHELL_INVALID_PARAMETER;
1306 }
1307 CurrentOperation.Type = BcfgTypeRm;
1308 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
1309 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
1310 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1311 ShellStatus = SHELL_INVALID_PARAMETER;
1312 } else {
1313 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
1314 CurrentOperation.Number1 = (UINT16)Intermediate;
1315 if (CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))){
1316 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));
1317 ShellStatus = SHELL_INVALID_PARAMETER;
1318 }
1319 }
1320 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"mv") == 0) {
1321 if ((ParamNumber + 2) >= ShellCommandLineGetCount(Package)) {
1322 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
1323 ShellStatus = SHELL_INVALID_PARAMETER;
1324 }
1325 CurrentOperation.Type = BcfgTypeMv;
1326 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
1327 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
1328 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1329 ShellStatus = SHELL_INVALID_PARAMETER;
1330 } else {
1331 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
1332 CurrentOperation.Number1 = (UINT16)Intermediate;
1333 if (CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))){
1334 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));
1335 ShellStatus = SHELL_INVALID_PARAMETER;
1336 }
1337 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
1338 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
1339 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1340 ShellStatus = SHELL_INVALID_PARAMETER;
1341 } else {
1342 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
1343 CurrentOperation.Number2 = (UINT16)Intermediate;
1344 }
1345 if (CurrentOperation.Number2 == CurrentOperation.Number1
1346 ||CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))
1347 ||CurrentOperation.Number2 > (Length / sizeof(CurrentOperation.Order[0]))
1348 ){
1349 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));
1350 ShellStatus = SHELL_INVALID_PARAMETER;
1351 }
1352 }
1353 } else {
1354 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1355 ShellStatus = SHELL_INVALID_PARAMETER;
1356 }
1357 }
1358 }
1359 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BcfgTargetMax && CurrentOperation.Type < BcfgTypeMax) {
1360 //
1361 // we have all the info. Do the work
1362 //
1363 switch (CurrentOperation.Type) {
1364 case BcfgTypeDump:
1365 ShellStatus = BcfgDisplayDumpInstall1(
1366 CurrentOperation.Target == BcfgTargetBootOrder?L"Boot":L"Driver",
1367 Length / sizeof(CurrentOperation.Order[0]),
1368 CurrentOperation.Order,
1369 ShellCommandLineGetFlag(Package, L"-v"));
1370 break;
1371 case BcfgTypeMv:
1372 ShellStatus = BcfgMoveInstall1(
1373 CurrentOperation.Target,
1374 CurrentOperation.Order,
1375 Length / sizeof(CurrentOperation.Order[0]),
1376 CurrentOperation.Number1,
1377 CurrentOperation.Number2);
1378 break;
1379 case BcfgTypeRm:
1380 ShellStatus = BcfgRemoveInstall1(
1381 CurrentOperation.Target,
1382 CurrentOperation.Order,
1383 Length / sizeof(CurrentOperation.Order[0]),
1384 CurrentOperation.Number1);
1385 break;
1386 case BcfgTypeAdd:
1387 case BcfgTypeAddp:
1388 case BcfgTypeAddh:
1389 ShellStatus = BcfgAddInstall1(
1390 CurrentOperation.Number1,
1391 CurrentOperation.FileName,
1392 CurrentOperation.Description==NULL?L"":CurrentOperation.Description,
1393 CurrentOperation.Order,
1394 Length / sizeof(CurrentOperation.Order[0]),
1395 CurrentOperation.Target,
1396 (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddh),
1397 (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddp),
1398 CurrentOperation.HandleIndex);
1399 break;
1400 case BcfgTypeOpt:
1401 ShellStatus = BcfgAddOptInstall1(
1402 CurrentOperation.OptData,
1403 CurrentOperation.Order,
1404 Length / sizeof(CurrentOperation.Order[0]),
1405 CurrentOperation.Target);
1406 break;
1407 default:
1408 ASSERT(FALSE);
1409 }
1410 }
1411 }
1412
1413 if (Package != NULL) {
1414 ShellCommandLineFreeVarList (Package);
1415 }
1416 if (CurrentOperation.FileName != NULL) {
1417 FreePool(CurrentOperation.FileName);
1418 }
1419 if (CurrentOperation.Description != NULL) {
1420 FreePool(CurrentOperation.Description);
1421 }
1422 if (CurrentOperation.Order != NULL) {
1423 FreePool(CurrentOperation.Order);
1424 }
1425
1426 return (ShellStatus);
1427 }