]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellInstall1CommandsLib/Bcfg.c
b91b34ffaeb1cc544509044629fdb8f3b1ebd270
[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 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 CopyMem(DevPath, Buffer+6+StrSize((CHAR16*)(Buffer+6)), *(UINT16*)(Buffer+4));
1044 DevPathString = ConvertDevicePathToText(DevPath, TRUE, FALSE);
1045 } else {
1046 DevPath = NULL;
1047 DevPathString = NULL;
1048 }
1049 ShellPrintHiiEx(
1050 -1,
1051 -1,
1052 NULL,
1053 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS),
1054 gShellInstall1HiiHandle,
1055 LoopVar,
1056 VariableName,
1057 (CHAR16*)(Buffer+6),
1058 DevPathString,
1059 (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6) <= BufferSize?L'N':L'Y');
1060 if (VerboseOutput) {
1061 for (LoopVar2 = (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6);LoopVar2<BufferSize;LoopVar2++){
1062 ShellPrintEx(
1063 -1,
1064 -1,
1065 NULL,
1066 L"%02x",
1067 Buffer[LoopVar2]);
1068 }
1069 ShellPrintEx(
1070 -1,
1071 -1,
1072 NULL,
1073 L"\r\n");
1074 }
1075
1076 if (Buffer != NULL) {
1077 FreePool(Buffer);
1078 }
1079 if (DevPath != NULL) {
1080 FreePool(DevPath);
1081 }
1082 if (DevPathString != NULL) {
1083 FreePool(DevPathString);
1084 }
1085 }
1086 return (SHELL_SUCCESS);
1087 }
1088
1089 /**
1090 Function to initialize the BCFG operation structure.
1091
1092 @param[in] Struct The stuct to initialize.
1093 **/
1094 VOID
1095 EFIAPI
1096 InitBcfgStructInstall1(
1097 IN BGFG_OPERATION *Struct
1098 )
1099 {
1100 ASSERT(Struct != NULL);
1101 Struct->Target = BcfgTargetMax;
1102 Struct->Type = BcfgTypeMax;
1103 Struct->Number1 = 0;
1104 Struct->Number2 = 0;
1105 Struct->HandleIndex = 0;
1106 Struct->FileName = NULL;
1107 Struct->Description = NULL;
1108 Struct->Order = NULL;
1109 Struct->OptData = NULL;
1110 }
1111
1112
1113 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
1114 {L"-v", TypeFlag},
1115 {L"-opt", TypeMaxValue},
1116 {NULL, TypeMax}
1117 };
1118
1119 /**
1120 Function for 'bcfg' command.
1121
1122 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1123 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1124 **/
1125 SHELL_STATUS
1126 EFIAPI
1127 ShellCommandRunBcfgInstall (
1128 IN EFI_HANDLE ImageHandle,
1129 IN EFI_SYSTEM_TABLE *SystemTable
1130 )
1131 {
1132 EFI_STATUS Status;
1133 LIST_ENTRY *Package;
1134 CHAR16 *ProblemParam;
1135 SHELL_STATUS ShellStatus;
1136 UINTN ParamNumber;
1137 CONST CHAR16 *CurrentParam;
1138 BGFG_OPERATION CurrentOperation;
1139 UINTN Length;
1140 UINT64 Intermediate;
1141
1142 Length = 0;
1143 ProblemParam = NULL;
1144 Package = NULL;
1145 ShellStatus = SHELL_SUCCESS;
1146
1147 InitBcfgStructInstall1(&CurrentOperation);
1148
1149 //
1150 // initialize the shell lib (we must be in non-auto-init...)
1151 //
1152 Status = ShellInitialize();
1153 ASSERT_EFI_ERROR(Status);
1154
1155 Status = CommandInit();
1156 ASSERT_EFI_ERROR(Status);
1157
1158 //
1159 // parse the command line
1160 //
1161 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
1162 if (EFI_ERROR(Status)) {
1163 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
1164 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, ProblemParam);
1165 FreePool(ProblemParam);
1166 ShellStatus = SHELL_INVALID_PARAMETER;
1167 } else {
1168 ASSERT(FALSE);
1169 }
1170 } else {
1171 //
1172 // Read in if we are doing -OPT
1173 //
1174 if (ShellCommandLineGetFlag(Package, L"-opt")) {
1175 CurrentOperation.OptData = ShellCommandLineGetValue(Package, L"-opt");
1176 if (CurrentOperation.OptData == NULL) {
1177 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellInstall1HiiHandle, L"-opt");
1178 ShellStatus = SHELL_INVALID_PARAMETER;
1179 }
1180 CurrentOperation.Type = BcfgTypeOpt;
1181 }
1182
1183 //
1184 // small block to read the target of the operation
1185 //
1186 if ((ShellCommandLineGetCount(Package) < 3 && CurrentOperation.Type != BcfgTypeOpt) ||
1187 (ShellCommandLineGetCount(Package) < 2 && CurrentOperation.Type == BcfgTypeOpt)
1188 ){
1189 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
1190 ShellStatus = SHELL_INVALID_PARAMETER;
1191 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"driver") == 0) {
1192 CurrentOperation.Target = BcfgTargetDriverOrder;
1193 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"boot") == 0) {
1194 CurrentOperation.Target = BcfgTargetBootOrder;
1195 } else {
1196 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT), gShellInstall1HiiHandle);
1197 ShellStatus = SHELL_INVALID_PARAMETER;
1198 }
1199
1200
1201 //
1202 // Read in the boot or driver order environment variable (not needed for opt)
1203 //
1204 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BcfgTargetMax) {
1205 Length = 0;
1206 Status = gRT->GetVariable(
1207 CurrentOperation.Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",
1208 (EFI_GUID*)&gEfiGlobalVariableGuid,
1209 NULL,
1210 &Length,
1211 CurrentOperation.Order);
1212 if (Status == EFI_BUFFER_TOO_SMALL) {
1213 CurrentOperation.Order = AllocateZeroPool(Length+(4*sizeof(CurrentOperation.Order[0])));
1214 Status = gRT->GetVariable(
1215 CurrentOperation.Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",
1216 (EFI_GUID*)&gEfiGlobalVariableGuid,
1217 NULL,
1218 &Length,
1219 CurrentOperation.Order);
1220 }
1221 }
1222
1223 //
1224 // large block to read the type of operation and verify parameter types for the info.
1225 //
1226 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BcfgTargetMax) {
1227 for (ParamNumber = 2 ; ParamNumber < ShellCommandLineGetCount(Package) && ShellStatus == SHELL_SUCCESS; ParamNumber++) {
1228 CurrentParam = ShellCommandLineGetRawValue(Package, ParamNumber);
1229 if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"dump") == 0) {
1230 CurrentOperation.Type = BcfgTypeDump;
1231 } else if (ShellCommandLineGetFlag(Package, L"-v")) {
1232 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, L"-v (without dump)");
1233 ShellStatus = SHELL_INVALID_PARAMETER;
1234 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"add") == 0) {
1235 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {
1236 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
1237 ShellStatus = SHELL_INVALID_PARAMETER;
1238 }
1239 CurrentOperation.Type = BcfgTypeAdd;
1240 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
1241 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
1242 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1243 ShellStatus = SHELL_INVALID_PARAMETER;
1244 } else {
1245 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
1246 CurrentOperation.Number1 = (UINT16)Intermediate;
1247 ASSERT(CurrentOperation.FileName == NULL);
1248 CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
1249 ASSERT(CurrentOperation.Description == NULL);
1250 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
1251 }
1252 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addp") == 0) {
1253 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {
1254 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
1255 ShellStatus = SHELL_INVALID_PARAMETER;
1256 }
1257 CurrentOperation.Type = BcfgTypeAddp;
1258 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
1259 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
1260 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1261 ShellStatus = SHELL_INVALID_PARAMETER;
1262 } else {
1263 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
1264 CurrentOperation.Number1 = (UINT16)Intermediate;
1265 ASSERT(CurrentOperation.FileName == NULL);
1266 CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
1267 ASSERT(CurrentOperation.Description == NULL);
1268 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
1269 }
1270 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addh") == 0) {
1271 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {
1272 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
1273 ShellStatus = SHELL_INVALID_PARAMETER;
1274 }
1275 CurrentOperation.Type = BcfgTypeAddh;
1276 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
1277 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
1278 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1279 ShellStatus = SHELL_INVALID_PARAMETER;
1280 } else {
1281 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
1282 CurrentOperation.Number1 = (UINT16)Intermediate;
1283 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
1284 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
1285 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1286 ShellStatus = SHELL_INVALID_PARAMETER;
1287 } else {
1288 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
1289 CurrentOperation.HandleIndex = (UINT16)Intermediate;
1290 ASSERT(CurrentOperation.Description == NULL);
1291 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
1292 }
1293 }
1294 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"rm") == 0) {
1295 if ((ParamNumber + 1) >= ShellCommandLineGetCount(Package)) {
1296 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
1297 ShellStatus = SHELL_INVALID_PARAMETER;
1298 }
1299 CurrentOperation.Type = BcfgTypeRm;
1300 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
1301 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
1302 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1303 ShellStatus = SHELL_INVALID_PARAMETER;
1304 } else {
1305 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
1306 CurrentOperation.Number1 = (UINT16)Intermediate;
1307 if (CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))){
1308 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));
1309 ShellStatus = SHELL_INVALID_PARAMETER;
1310 }
1311 }
1312 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"mv") == 0) {
1313 if ((ParamNumber + 2) >= ShellCommandLineGetCount(Package)) {
1314 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
1315 ShellStatus = SHELL_INVALID_PARAMETER;
1316 }
1317 CurrentOperation.Type = BcfgTypeMv;
1318 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
1319 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
1320 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1321 ShellStatus = SHELL_INVALID_PARAMETER;
1322 } else {
1323 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
1324 CurrentOperation.Number1 = (UINT16)Intermediate;
1325 if (CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))){
1326 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));
1327 ShellStatus = SHELL_INVALID_PARAMETER;
1328 }
1329 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
1330 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
1331 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1332 ShellStatus = SHELL_INVALID_PARAMETER;
1333 } else {
1334 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
1335 CurrentOperation.Number2 = (UINT16)Intermediate;
1336 }
1337 if (CurrentOperation.Number2 == CurrentOperation.Number1
1338 ||CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))
1339 ||CurrentOperation.Number2 > (Length / sizeof(CurrentOperation.Order[0]))
1340 ){
1341 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));
1342 ShellStatus = SHELL_INVALID_PARAMETER;
1343 }
1344 }
1345 } else {
1346 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
1347 ShellStatus = SHELL_INVALID_PARAMETER;
1348 }
1349 }
1350 }
1351 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BcfgTargetMax && CurrentOperation.Type < BcfgTypeMax) {
1352 //
1353 // we have all the info. Do the work
1354 //
1355 switch (CurrentOperation.Type) {
1356 case BcfgTypeDump:
1357 ShellStatus = BcfgDisplayDumpInstall1(
1358 CurrentOperation.Target == BcfgTargetBootOrder?L"Boot":L"Driver",
1359 Length / sizeof(CurrentOperation.Order[0]),
1360 CurrentOperation.Order,
1361 ShellCommandLineGetFlag(Package, L"-v"));
1362 break;
1363 case BcfgTypeMv:
1364 ShellStatus = BcfgMoveInstall1(
1365 CurrentOperation.Target,
1366 CurrentOperation.Order,
1367 Length / sizeof(CurrentOperation.Order[0]),
1368 CurrentOperation.Number1,
1369 CurrentOperation.Number2);
1370 break;
1371 case BcfgTypeRm:
1372 ShellStatus = BcfgRemoveInstall1(
1373 CurrentOperation.Target,
1374 CurrentOperation.Order,
1375 Length / sizeof(CurrentOperation.Order[0]),
1376 CurrentOperation.Number1);
1377 break;
1378 case BcfgTypeAdd:
1379 case BcfgTypeAddp:
1380 case BcfgTypeAddh:
1381 ShellStatus = BcfgAddInstall1(
1382 CurrentOperation.Number1,
1383 CurrentOperation.FileName,
1384 CurrentOperation.Description==NULL?L"":CurrentOperation.Description,
1385 CurrentOperation.Order,
1386 Length / sizeof(CurrentOperation.Order[0]),
1387 CurrentOperation.Target,
1388 (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddh),
1389 (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddp),
1390 CurrentOperation.HandleIndex);
1391 break;
1392 case BcfgTypeOpt:
1393 ShellStatus = BcfgAddOptInstall1(
1394 CurrentOperation.OptData,
1395 CurrentOperation.Order,
1396 Length / sizeof(CurrentOperation.Order[0]),
1397 CurrentOperation.Target);
1398 break;
1399 default:
1400 ASSERT(FALSE);
1401 }
1402 }
1403 }
1404
1405 if (Package != NULL) {
1406 ShellCommandLineFreeVarList (Package);
1407 }
1408 if (CurrentOperation.FileName != NULL) {
1409 FreePool(CurrentOperation.FileName);
1410 }
1411 if (CurrentOperation.Description != NULL) {
1412 FreePool(CurrentOperation.Description);
1413 }
1414 if (CurrentOperation.Order != NULL) {
1415 FreePool(CurrentOperation.Order);
1416 }
1417
1418 return (ShellStatus);
1419 }