]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellInstall1CommandsLib/Bcfg.c
f5a228665787cefb97999b012c4bd0d692df676a
[mirror_edk2.git] / ShellPkg / Library / UefiShellInstall1CommandsLib / Bcfg.c
1 /** @file
2 Main file for bcfg shell Install1 function.
3
4 Copyright (c) 2010 - 2011, 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 Function to add a option.
52
53 @param[in] Position The position to add Target at.
54 @param[in] File The file to make the target.
55 @param[in] Desc The description text.
56 @param[in] CurrentOrder The pointer to the current order of items.
57 @param[in] OrderCount The number if items in CurrentOrder.
58 @param[in] Target The info on the option to add.
59 @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.
60 @param[in] UsePath TRUE to convert to devicepath.
61 @param[in] HandleNumber The handle number to add.
62
63 @retval SHELL_SUCCESS The operation was successful.
64 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
65 **/
66 SHELL_STATUS
67 EFIAPI
68 BcfgAddInstall1(
69 IN UINTN Position,
70 IN CONST CHAR16 *File,
71 IN CONST CHAR16 *Desc,
72 IN CONST UINT16 *CurrentOrder,
73 IN CONST UINTN OrderCount,
74 IN CONST BCFG_OPERATION_TARGET Target,
75 IN CONST BOOLEAN UseHandle,
76 IN CONST BOOLEAN UsePath,
77 IN CONST UINTN HandleNumber
78 )
79 {
80 EFI_STATUS Status;
81 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
82 EFI_DEVICE_PATH_PROTOCOL *FilePath;
83 EFI_DEVICE_PATH_PROTOCOL *FileNode;
84 EFI_DEVICE_PATH_PROTOCOL *DevPath;
85 CHAR16 *Str;
86 CONST CHAR16 *StringWalker;
87 UINT8 *TempByteBuffer;
88 UINT8 *TempByteStart;
89 EFI_SHELL_FILE_INFO *Arg;
90 EFI_SHELL_FILE_INFO *FileList;
91 CHAR16 OptionStr[40];
92 UINTN DescSize, FilePathSize;
93 BOOLEAN Found;
94 UINTN TargetLocation;
95 UINTN Index;
96 EFI_HANDLE *Handles;
97 EFI_HANDLE CurHandle;
98 UINTN DriverBindingHandleCount;
99 UINTN ParentControllerHandleCount;
100 UINTN ChildControllerHandleCount;
101 SHELL_STATUS ShellStatus;
102 UINT16 *NewOrder;
103 UINT64 Intermediate;
104
105 if (!UseHandle) {
106 if (File == NULL || Desc == NULL) {
107 return (SHELL_INVALID_PARAMETER);
108 }
109 } else {
110 if (HandleNumber == 0) {
111 return (SHELL_INVALID_PARAMETER);
112 }
113 }
114
115 if (Position > OrderCount) {
116 Position = OrderCount;
117 }
118
119 Str = NULL;
120 FilePath = NULL;
121 FileNode = NULL;
122 FileList = NULL;
123 Handles = NULL;
124 ShellStatus = SHELL_SUCCESS;
125 TargetLocation = 0xFFFF;
126
127 if (UseHandle) {
128 Status = ShellConvertStringToUint64(File, &Intermediate, TRUE, FALSE);
129 CurHandle = ConvertHandleIndexToHandle((UINTN)Intermediate);
130 if (CurHandle == NULL || EFI_ERROR(Status)) {
131 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, File);
132 ShellStatus = SHELL_INVALID_PARAMETER;
133 } else {
134 //
135 //Make sure that the handle should point to a real controller
136 //
137 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
138 CurHandle,
139 &DriverBindingHandleCount,
140 NULL);
141
142 Status = PARSE_HANDLE_DATABASE_PARENTS (
143 CurHandle,
144 &ParentControllerHandleCount,
145 NULL);
146
147 Status = ParseHandleDatabaseForChildControllers (
148 CurHandle,
149 &ChildControllerHandleCount,
150 NULL);
151
152 if (DriverBindingHandleCount > 0
153 || ParentControllerHandleCount > 0
154 || ChildControllerHandleCount > 0) {
155 FilePath = NULL;
156 Status = gBS->HandleProtocol (
157 CurHandle,
158 &gEfiDevicePathProtocolGuid,
159 (VOID**)&FilePath);
160 }
161 if (EFI_ERROR (Status)) {
162 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_HANDLE), gShellInstall1HiiHandle, Intermediate);
163 ShellStatus = SHELL_INVALID_PARAMETER;
164 }
165 }
166 } else {
167 //
168 // Get file info
169 //
170 ShellOpenFileMetaArg ((CHAR16*)File, EFI_FILE_MODE_READ, &FileList);
171
172 if (FileList == NULL) {
173 //
174 // If filename matched nothing fail
175 //
176 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellInstall1HiiHandle, File);
177 ShellStatus = SHELL_INVALID_PARAMETER;
178 } else if (FileList->Link.ForwardLink != FileList->Link.BackLink) {
179 //
180 // If filename expanded to multiple names, fail
181 //
182 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellInstall1HiiHandle, File);
183 ShellStatus = SHELL_INVALID_PARAMETER;
184 } else {
185 Arg = (EFI_SHELL_FILE_INFO*)GetFirstNode(&FileList->Link);
186 if (EFI_ERROR(Arg->Status)) {
187 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellInstall1HiiHandle, File, Arg->Status);
188 ShellStatus = SHELL_INVALID_PARAMETER;
189 } else {
190 //
191 // Build FilePath to the filename
192 //
193
194 //
195 // get the device path
196 //
197 DevicePath = mEfiShellProtocol->GetDevicePathFromFilePath(Arg->FullName);
198 if (DevicePath == NULL) {
199 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellInstall1HiiHandle, Arg->FullName);
200 ShellStatus = SHELL_UNSUPPORTED;
201 } else {
202 if (UsePath) {
203 DevPath = DevicePath;
204 while (!IsDevicePathEnd(DevPath)) {
205 if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&
206 (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {
207
208 //
209 // If we find it use it instead
210 //
211 DevicePath = DevPath;
212 break;
213 }
214 DevPath = NextDevicePathNode(DevPath);
215 }
216 //
217 // append the file
218 //
219 for(StringWalker=Arg->FullName; *StringWalker != CHAR_NULL && *StringWalker != ':'; StringWalker++);
220 FileNode = FileDevicePath(NULL, StringWalker+1);
221 FilePath = AppendDevicePath(DevicePath, FileNode);
222 FreePool(FileNode);
223 } else {
224 FilePath = DuplicateDevicePath(DevicePath);
225 }
226
227 FreePool(DevicePath);
228 }
229 }
230 }
231 }
232
233
234 if (ShellStatus == SHELL_SUCCESS) {
235 //
236 // Find a free target ,a brute force implementation
237 //
238 Found = FALSE;
239 for (TargetLocation=0; TargetLocation < 0xFFFF; TargetLocation++) {
240 Found = TRUE;
241 for (Index=0; Index < OrderCount; Index++) {
242 if (CurrentOrder[Index] == TargetLocation) {
243 Found = FALSE;
244 break;
245 }
246 }
247
248 if (Found) {
249 break;
250 }
251 }
252
253 if (TargetLocation == 0xFFFF) {
254 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET_NF), gShellInstall1HiiHandle);
255 } else {
256 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET), gShellInstall1HiiHandle, TargetLocation);
257 }
258 }
259
260 if (ShellStatus == SHELL_SUCCESS) {
261 //
262 // Add the option
263 //
264 DescSize = StrSize(Desc);
265 FilePathSize = GetDevicePathSize (FilePath);
266
267 TempByteBuffer = AllocateZeroPool(sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize);
268 TempByteStart = TempByteBuffer;
269 *((UINT32 *) TempByteBuffer) = LOAD_OPTION_ACTIVE; // Attributes
270 TempByteBuffer += sizeof (UINT32);
271
272 *((UINT16 *) TempByteBuffer) = (UINT16)FilePathSize; // FilePathListLength
273 TempByteBuffer += sizeof (UINT16);
274
275 CopyMem (TempByteBuffer, Desc, DescSize);
276 TempByteBuffer += DescSize;
277 CopyMem (TempByteBuffer, FilePath, FilePathSize);
278
279 UnicodeSPrint (OptionStr, sizeof(OptionStr), L"%s%04x", Target == BcfgTargetBootOrder?L"Boot":L"Driver", TargetLocation);
280 Status = gRT->SetVariable (
281 OptionStr,
282 &gEfiGlobalVariableGuid,
283 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
284 sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize,
285 TempByteStart
286 );
287
288 FreePool(TempByteStart);
289
290 if (EFI_ERROR(Status)) {
291 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellInstall1HiiHandle, OptionStr, Status);
292 } else {
293 NewOrder = AllocateZeroPool((OrderCount+1)*sizeof(NewOrder[0]));
294 ASSERT(NewOrder != NULL);
295 CopyMem(NewOrder, CurrentOrder, (OrderCount)*sizeof(NewOrder[0]));
296
297 //
298 // Insert target into order list
299 //
300 for (Index=OrderCount; Index > Position; Index--) {
301 NewOrder[Index] = NewOrder[Index-1];
302 }
303
304 NewOrder[Position] = (UINT16) TargetLocation;
305 Status = gRT->SetVariable (
306 Target == BcfgTargetBootOrder?L"BootOrder":L"DriverOrder",
307 &gEfiGlobalVariableGuid,
308 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
309 (OrderCount+1) * sizeof(UINT16),
310 NewOrder
311 );
312
313 FreePool(NewOrder);
314
315 if (EFI_ERROR(Status)) {
316 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, Target == BcfgTargetBootOrder?L"BootOrder":L"DriverOrder", Status);
317 ShellStatus = SHELL_INVALID_PARAMETER;
318 } else {
319 Print (L"bcfg: Add %s as %x\n", OptionStr, Position);
320 }
321 }
322 }
323 if (FileNode != NULL) {
324 FreePool (FileNode);
325 }
326
327 //
328 //If always Free FilePath, will free devicepath in system when use "addh"
329 //
330
331 if (FilePath!=NULL && !UseHandle) {
332 FreePool (FilePath);
333 }
334
335 if (Str != NULL) {
336 FreePool(Str);
337 }
338
339 if (Handles != NULL) {
340 FreePool (Handles);
341 }
342
343 if (FileList != NULL) {
344 ShellCloseFileMetaArg (&FileList);
345 }
346
347 return (ShellStatus);
348 }
349
350 /**
351 Funciton to remove an item.
352
353 @param[in] Target The target item to move.
354 @param[in] CurrentOrder The pointer to the current order of items.
355 @param[in] OrderCount The number if items in CurrentOrder.
356 @param[in] Location The current location of the Target.
357
358 @retval SHELL_SUCCESS The operation was successful.
359 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
360 **/
361 SHELL_STATUS
362 EFIAPI
363 BcfgRemoveInstall1(
364 IN CONST BCFG_OPERATION_TARGET Target,
365 IN CONST UINT16 *CurrentOrder,
366 IN CONST UINTN OrderCount,
367 IN CONST UINT16 Location
368 )
369 {
370 CHAR16 VariableName[12];
371 UINT16 *NewOrder;
372 EFI_STATUS Status;
373 UINTN LoopVar;
374 UINTN NewCount;
375
376 UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Target == BcfgTargetBootOrder?L"Boot":L"Driver", Location);
377 Status = gRT->SetVariable(
378 VariableName,
379 (EFI_GUID*)&gEfiGlobalVariableGuid,
380 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
381 0,
382 NULL);
383 if (EFI_ERROR(Status)) {
384 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, VariableName, Status);
385 return (SHELL_INVALID_PARAMETER);
386 }
387 NewOrder = AllocateZeroPool(OrderCount*sizeof(CurrentOrder[0]));
388 NewCount = OrderCount;
389 CopyMem(NewOrder, CurrentOrder, OrderCount*sizeof(CurrentOrder[0]));
390 for (LoopVar = 0 ; LoopVar < OrderCount ; LoopVar++){
391 if (NewOrder[LoopVar] == Location) {
392 CopyMem(NewOrder+LoopVar, NewOrder+LoopVar+1, (OrderCount - LoopVar - 1)*sizeof(CurrentOrder[0]));
393 NewCount--;
394 }
395 }
396 Status = gRT->SetVariable(
397 Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",
398 (EFI_GUID*)&gEfiGlobalVariableGuid,
399 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
400 NewCount*sizeof(NewOrder[0]),
401 NewOrder);
402 FreePool(NewOrder);
403
404 if (EFI_ERROR(Status)) {
405 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder", Status);
406 return (SHELL_INVALID_PARAMETER);
407 }
408 return (SHELL_SUCCESS);
409 }
410
411 /**
412 Funciton to move a item to another location.
413
414 @param[in] Target The target item to move.
415 @param[in] CurrentOrder The pointer to the current order of items.
416 @param[in] OrderCount The number if items in CurrentOrder.
417 @param[in] OldLocation The current location of the Target.
418 @param[in] NewLocation The desired location of the Target.
419
420 @retval SHELL_SUCCESS The operation was successful.
421 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
422 **/
423 SHELL_STATUS
424 EFIAPI
425 BcfgMoveInstall1(
426 IN CONST BCFG_OPERATION_TARGET Target,
427 IN CONST UINT16 *CurrentOrder,
428 IN CONST UINTN OrderCount,
429 IN CONST UINT16 OldLocation,
430 IN CONST UINT16 NewLocation
431 )
432 {
433 UINT16 *NewOrder;
434 EFI_STATUS Status;
435 UINT16 Temp;
436
437 NewOrder = AllocateZeroPool(OrderCount*sizeof(CurrentOrder[0]));
438 ASSERT(NewOrder != NULL);
439
440 Temp = CurrentOrder[OldLocation];
441 CopyMem(NewOrder, CurrentOrder, OrderCount*sizeof(CurrentOrder[0]));
442 CopyMem(NewOrder+OldLocation, NewOrder+OldLocation+1, (OrderCount - OldLocation - 1)*sizeof(CurrentOrder[0]));
443 CopyMem(NewOrder+NewLocation+1, NewOrder+NewLocation, (OrderCount - NewLocation - 1)*sizeof(CurrentOrder[0]));
444 NewOrder[NewLocation] = Temp;
445
446
447 Status = gRT->SetVariable(
448 Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",
449 (EFI_GUID*)&gEfiGlobalVariableGuid,
450 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
451 OrderCount*sizeof(CurrentOrder[0]),
452 NewOrder);
453
454 FreePool(NewOrder);
455
456 if (EFI_ERROR(Status)) {
457 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder", Status);
458 return (SHELL_INVALID_PARAMETER);
459 }
460 return (SHELL_SUCCESS);
461 }
462
463 SHELL_STATUS
464 EFIAPI
465 BcfgAddOptInstall1(
466 IN CONST CHAR16 *OptData,
467 IN CONST BCFG_OPERATION_TARGET Target
468 )
469 {
470 ASSERT(OptData != NULL);
471 return SHELL_SUCCESS;
472 }
473
474 /**
475 Function to dump the Bcfg information.
476
477 @param[in] Op The operation.
478 @param[in] OrderCount How many to dump.
479 @param[in] CurrentOrder The pointer to the current order of items.
480 @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.
481
482 @retval SHELL_SUCCESS The dump was successful.
483 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
484 **/
485 SHELL_STATUS
486 EFIAPI
487 BcfgDisplayDumpInstall1(
488 IN CONST CHAR16 *Op,
489 IN CONST UINTN OrderCount,
490 IN CONST UINT16 *CurrentOrder,
491 IN CONST BOOLEAN VerboseOutput
492 )
493 {
494 EFI_STATUS Status;
495 UINT8 *Buffer;
496 UINTN BufferSize;
497 CHAR16 VariableName[12];
498 UINTN LoopVar;
499 UINTN LoopVar2;
500 CHAR16 *DevPathString;
501 VOID *DevPath;
502
503 if (OrderCount == 0) {
504 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_BCFG_NONE), gShellInstall1HiiHandle);
505 return (SHELL_SUCCESS);
506 }
507
508 for (LoopVar = 0 ; LoopVar < OrderCount ; LoopVar++) {
509 Buffer = NULL;
510 BufferSize = 0;
511 UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Op, CurrentOrder[LoopVar]);
512
513 Status = gRT->GetVariable(
514 VariableName,
515 (EFI_GUID*)&gEfiGlobalVariableGuid,
516 NULL,
517 &BufferSize,
518 Buffer);
519 if (Status == EFI_BUFFER_TOO_SMALL) {
520 Buffer = AllocateZeroPool(BufferSize);
521 Status = gRT->GetVariable(
522 VariableName,
523 (EFI_GUID*)&gEfiGlobalVariableGuid,
524 NULL,
525 &BufferSize,
526 Buffer);
527 }
528
529 if (EFI_ERROR(Status) || Buffer == NULL) {
530 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_READ_FAIL), gShellInstall1HiiHandle, VariableName, Status);
531 return (SHELL_INVALID_PARAMETER);
532 }
533
534 DevPath = AllocateZeroPool(*(UINT16*)(Buffer+4));
535 CopyMem(DevPath, Buffer+6+StrSize((CHAR16*)(Buffer+6)), *(UINT16*)(Buffer+4));
536 DevPathString = gDevPathToText->ConvertDevicePathToText(DevPath, TRUE, FALSE);
537 ShellPrintHiiEx(
538 -1,
539 -1,
540 NULL,
541 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS),
542 gShellInstall1HiiHandle,
543 LoopVar,
544 VariableName,
545 (CHAR16*)(Buffer+6),
546 DevPathString,
547 (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6) <= BufferSize?L'N':L'Y');
548 if (VerboseOutput) {
549 for (LoopVar2 = (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6);LoopVar2<BufferSize;LoopVar2++){
550 ShellPrintEx(
551 -1,
552 -1,
553 NULL,
554 L"%02x",
555 Buffer[LoopVar2]);
556 }
557 ShellPrintEx(
558 -1,
559 -1,
560 NULL,
561 L"\r\n");
562 }
563
564 if (Buffer != NULL) {
565 FreePool(Buffer);
566 }
567 if (DevPath != NULL) {
568 FreePool(DevPath);
569 }
570 if (DevPathString != NULL) {
571 FreePool(DevPathString);
572 }
573 }
574 return (SHELL_SUCCESS);
575 }
576
577 /**
578 Function to initialize the BCFG operation structure.
579
580 @param[in] Struct The stuct to initialize.
581 **/
582 VOID
583 EFIAPI
584 InitBcfgStructInstall1(
585 IN BGFG_OPERATION *Struct
586 )
587 {
588 ASSERT(Struct != NULL);
589 Struct->Target = BcfgTargetMax;
590 Struct->Type = BcfgTypeMax;
591 Struct->Number1 = 0;
592 Struct->Number2 = 0;
593 Struct->HandleIndex = 0;
594 Struct->FileName = NULL;
595 Struct->Description = NULL;
596 Struct->Order = NULL;
597 Struct->OptData = NULL;
598 }
599
600
601 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
602 {L"-v", TypeFlag},
603 {L"-opt", TypeMaxValue},
604 {NULL, TypeMax}
605 };
606
607 /**
608 Function for 'bcfg' command.
609
610 @param[in] ImageHandle Handle to the Image (NULL if Internal).
611 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
612 **/
613 SHELL_STATUS
614 EFIAPI
615 ShellCommandRunBcfgInstall (
616 IN EFI_HANDLE ImageHandle,
617 IN EFI_SYSTEM_TABLE *SystemTable
618 )
619 {
620 EFI_STATUS Status;
621 LIST_ENTRY *Package;
622 CHAR16 *ProblemParam;
623 SHELL_STATUS ShellStatus;
624 UINTN ParamNumber;
625 CONST CHAR16 *CurrentParam;
626 BGFG_OPERATION CurrentOperation;
627 UINTN Length;
628 UINT64 Intermediate;
629
630 Length = 0;
631 ProblemParam = NULL;
632 Package = NULL;
633 ShellStatus = SHELL_SUCCESS;
634
635 InitBcfgStructInstall1(&CurrentOperation);
636
637 //
638 // initialize the shell lib (we must be in non-auto-init...)
639 //
640 Status = ShellInitialize();
641 ASSERT_EFI_ERROR(Status);
642
643 Status = CommandInit();
644 ASSERT_EFI_ERROR(Status);
645
646 //
647 // parse the command line
648 //
649 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
650 if (EFI_ERROR(Status)) {
651 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
652 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, ProblemParam);
653 FreePool(ProblemParam);
654 ShellStatus = SHELL_INVALID_PARAMETER;
655 } else {
656 ASSERT(FALSE);
657 }
658 } else {
659 //
660 // Read in if we are doing -OPT
661 //
662 if (ShellCommandLineGetFlag(Package, L"-opt")) {
663 CurrentOperation.OptData = ShellCommandLineGetValue(Package, L"-opt");
664 if (CurrentOperation.OptData == NULL) {
665 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellInstall1HiiHandle, L"-opt");
666 ShellStatus = SHELL_INVALID_PARAMETER;
667 }
668 CurrentOperation.Type = BcfgTypeOpt;
669 }
670
671 //
672 // small block to read the target of the operation
673 //
674 if ((ShellCommandLineGetCount(Package) < 3 && CurrentOperation.Type != BcfgTypeOpt) ||
675 (ShellCommandLineGetCount(Package) < 2 && CurrentOperation.Type == BcfgTypeOpt)
676 ){
677 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
678 ShellStatus = SHELL_INVALID_PARAMETER;
679 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"driver") == 0) {
680 CurrentOperation.Target = BcfgTargetDriverOrder;
681 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"boot") == 0) {
682 CurrentOperation.Target = BcfgTargetBootOrder;
683 } else {
684 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT), gShellInstall1HiiHandle);
685 ShellStatus = SHELL_INVALID_PARAMETER;
686 }
687
688
689 //
690 // Read in the boot or driver order environment variable (not needed for opt)
691 //
692 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BcfgTargetMax && CurrentOperation.Type != BcfgTypeOpt) {
693 Length = 0;
694 Status = gRT->GetVariable(
695 CurrentOperation.Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",
696 (EFI_GUID*)&gEfiGlobalVariableGuid,
697 NULL,
698 &Length,
699 CurrentOperation.Order);
700 if (Status == EFI_BUFFER_TOO_SMALL) {
701 CurrentOperation.Order = AllocateZeroPool(Length+(4*sizeof(CurrentOperation.Order[0])));
702 Status = gRT->GetVariable(
703 CurrentOperation.Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",
704 (EFI_GUID*)&gEfiGlobalVariableGuid,
705 NULL,
706 &Length,
707 CurrentOperation.Order);
708 }
709 }
710
711 //
712 // large block to read the type of operation and verify parameter types for the info.
713 //
714 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BcfgTargetMax) {
715 for (ParamNumber = 2 ; ParamNumber < ShellCommandLineGetCount(Package) && ShellStatus == SHELL_SUCCESS; ParamNumber++) {
716 CurrentParam = ShellCommandLineGetRawValue(Package, ParamNumber);
717 if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"dump") == 0) {
718 CurrentOperation.Type = BcfgTypeDump;
719 } else if (ShellCommandLineGetFlag(Package, L"-v")) {
720 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, L"-v (without dump)");
721 ShellStatus = SHELL_INVALID_PARAMETER;
722 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"add") == 0) {
723 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {
724 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
725 ShellStatus = SHELL_INVALID_PARAMETER;
726 }
727 CurrentOperation.Type = BcfgTypeAdd;
728 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
729 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
730 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
731 ShellStatus = SHELL_INVALID_PARAMETER;
732 } else {
733 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
734 CurrentOperation.Number1 = (UINT16)Intermediate;
735 ASSERT(CurrentOperation.FileName == NULL);
736 CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
737 ASSERT(CurrentOperation.Description == NULL);
738 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
739 }
740 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addp") == 0) {
741 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {
742 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
743 ShellStatus = SHELL_INVALID_PARAMETER;
744 }
745 CurrentOperation.Type = BcfgTypeAddp;
746 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
747 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
748 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
749 ShellStatus = SHELL_INVALID_PARAMETER;
750 } else {
751 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
752 CurrentOperation.Number1 = (UINT16)Intermediate;
753 ASSERT(CurrentOperation.FileName == NULL);
754 CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
755 ASSERT(CurrentOperation.Description == NULL);
756 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
757 }
758 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addh") == 0) {
759 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {
760 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
761 ShellStatus = SHELL_INVALID_PARAMETER;
762 }
763 CurrentOperation.Type = BcfgTypeAddh;
764 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
765 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
766 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
767 ShellStatus = SHELL_INVALID_PARAMETER;
768 } else {
769 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
770 CurrentOperation.Number1 = (UINT16)Intermediate;
771 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
772 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
773 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
774 ShellStatus = SHELL_INVALID_PARAMETER;
775 } else {
776 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
777 CurrentOperation.HandleIndex = (UINT16)Intermediate;
778 ASSERT(CurrentOperation.Description == NULL);
779 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
780 }
781 }
782 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"rm") == 0) {
783 if ((ParamNumber + 1) >= ShellCommandLineGetCount(Package)) {
784 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
785 ShellStatus = SHELL_INVALID_PARAMETER;
786 }
787 CurrentOperation.Type = BcfgTypeRm;
788 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
789 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
790 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
791 ShellStatus = SHELL_INVALID_PARAMETER;
792 } else {
793 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
794 CurrentOperation.Number1 = (UINT16)Intermediate;
795 if (CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))){
796 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));
797 ShellStatus = SHELL_INVALID_PARAMETER;
798 }
799 }
800 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"mv") == 0) {
801 if ((ParamNumber + 2) >= ShellCommandLineGetCount(Package)) {
802 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
803 ShellStatus = SHELL_INVALID_PARAMETER;
804 }
805 CurrentOperation.Type = BcfgTypeMv;
806 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
807 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
808 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
809 ShellStatus = SHELL_INVALID_PARAMETER;
810 } else {
811 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
812 CurrentOperation.Number1 = (UINT16)Intermediate;
813 if (CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))){
814 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));
815 ShellStatus = SHELL_INVALID_PARAMETER;
816 }
817 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
818 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
819 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
820 ShellStatus = SHELL_INVALID_PARAMETER;
821 } else {
822 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
823 CurrentOperation.Number2 = (UINT16)Intermediate;
824 }
825 if (CurrentOperation.Number2 == CurrentOperation.Number1
826 ||CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))
827 ||CurrentOperation.Number2 > (Length / sizeof(CurrentOperation.Order[0]))
828 ){
829 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));
830 ShellStatus = SHELL_INVALID_PARAMETER;
831 }
832 }
833 } else {
834 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
835 ShellStatus = SHELL_INVALID_PARAMETER;
836 }
837 }
838 }
839 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BcfgTargetMax && CurrentOperation.Type < BcfgTypeMax) {
840 //
841 // we have all the info. Do the work
842 //
843 switch (CurrentOperation.Type) {
844 case BcfgTypeDump:
845 ShellStatus = BcfgDisplayDumpInstall1(
846 CurrentOperation.Target == BcfgTargetBootOrder?L"Boot":L"Driver",
847 Length / sizeof(CurrentOperation.Order[0]),
848 CurrentOperation.Order,
849 ShellCommandLineGetFlag(Package, L"-v"));
850 break;
851 case BcfgTypeMv:
852 ShellStatus = BcfgMoveInstall1(
853 CurrentOperation.Target,
854 CurrentOperation.Order,
855 Length / sizeof(CurrentOperation.Order[0]),
856 CurrentOperation.Number1,
857 CurrentOperation.Number2);
858 break;
859 case BcfgTypeRm:
860 ShellStatus = BcfgRemoveInstall1(
861 CurrentOperation.Target,
862 CurrentOperation.Order,
863 Length / sizeof(CurrentOperation.Order[0]),
864 CurrentOperation.Number1);
865 break;
866 case BcfgTypeAdd:
867 case BcfgTypeAddp:
868 case BcfgTypeAddh:
869 ShellStatus = BcfgAddInstall1(
870 CurrentOperation.Number1,
871 CurrentOperation.FileName,
872 CurrentOperation.Description,
873 CurrentOperation.Order,
874 Length / sizeof(CurrentOperation.Order[0]),
875 CurrentOperation.Target,
876 (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddh),
877 (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddp),
878 CurrentOperation.HandleIndex);
879 break;
880 case BcfgTypeOpt:
881 ShellStatus = BcfgAddOptInstall1(
882 CurrentOperation.OptData,
883 CurrentOperation.Target);
884 break;
885 default:
886 ASSERT(FALSE);
887 }
888 }
889 }
890
891 if (Package != NULL) {
892 ShellCommandLineFreeVarList (Package);
893 }
894 if (CurrentOperation.FileName != NULL) {
895 FreePool(CurrentOperation.FileName);
896 }
897 if (CurrentOperation.Description != NULL) {
898 FreePool(CurrentOperation.Description);
899 }
900 if (CurrentOperation.Order != NULL) {
901 FreePool(CurrentOperation.Order);
902 }
903
904 return (ShellStatus);
905 }