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