]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellInstall1CommandsLib/Bcfg.c
remove duplicate memory de-allocation.
[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 if (TempByteBuffer != NULL) {
269 TempByteStart = TempByteBuffer;
270 *((UINT32 *) TempByteBuffer) = LOAD_OPTION_ACTIVE; // Attributes
271 TempByteBuffer += sizeof (UINT32);
272
273 *((UINT16 *) TempByteBuffer) = (UINT16)FilePathSize; // FilePathListLength
274 TempByteBuffer += sizeof (UINT16);
275
276 CopyMem (TempByteBuffer, Desc, DescSize);
277 TempByteBuffer += DescSize;
278 CopyMem (TempByteBuffer, FilePath, FilePathSize);
279
280 UnicodeSPrint (OptionStr, sizeof(OptionStr), L"%s%04x", Target == BcfgTargetBootOrder?L"Boot":L"Driver", TargetLocation);
281 Status = gRT->SetVariable (
282 OptionStr,
283 &gEfiGlobalVariableGuid,
284 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
285 sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize,
286 TempByteStart
287 );
288
289 FreePool(TempByteStart);
290 } else {
291 Status = EFI_OUT_OF_RESOURCES;
292 }
293
294 if (EFI_ERROR(Status)) {
295 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellInstall1HiiHandle, OptionStr, Status);
296 } else {
297 NewOrder = AllocateZeroPool((OrderCount+1)*sizeof(NewOrder[0]));
298 ASSERT(NewOrder != NULL);
299 CopyMem(NewOrder, CurrentOrder, (OrderCount)*sizeof(NewOrder[0]));
300
301 //
302 // Insert target into order list
303 //
304 for (Index=OrderCount; Index > Position; Index--) {
305 NewOrder[Index] = NewOrder[Index-1];
306 }
307
308 NewOrder[Position] = (UINT16) TargetLocation;
309 Status = gRT->SetVariable (
310 Target == BcfgTargetBootOrder?L"BootOrder":L"DriverOrder",
311 &gEfiGlobalVariableGuid,
312 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
313 (OrderCount+1) * sizeof(UINT16),
314 NewOrder
315 );
316
317 FreePool(NewOrder);
318
319 if (EFI_ERROR(Status)) {
320 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, Target == BcfgTargetBootOrder?L"BootOrder":L"DriverOrder", Status);
321 ShellStatus = SHELL_INVALID_PARAMETER;
322 } else {
323 Print (L"bcfg: Add %s as %x\n", OptionStr, Position);
324 }
325 }
326 }
327
328 //
329 //If always Free FilePath, will free devicepath in system when use "addh"
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 if (NewOrder != NULL) {
389 NewCount = OrderCount;
390 CopyMem(NewOrder, CurrentOrder, OrderCount*sizeof(CurrentOrder[0]));
391 for (LoopVar = 0 ; LoopVar < OrderCount ; LoopVar++){
392 if (NewOrder[LoopVar] == Location) {
393 CopyMem(NewOrder+LoopVar, NewOrder+LoopVar+1, (OrderCount - LoopVar - 1)*sizeof(CurrentOrder[0]));
394 NewCount--;
395 }
396 }
397 Status = gRT->SetVariable(
398 Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",
399 (EFI_GUID*)&gEfiGlobalVariableGuid,
400 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
401 NewCount*sizeof(NewOrder[0]),
402 NewOrder);
403 FreePool(NewOrder);
404 } else {
405 Status = EFI_OUT_OF_RESOURCES;
406 }
407 if (EFI_ERROR(Status)) {
408 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder", Status);
409 return (SHELL_INVALID_PARAMETER);
410 }
411 return (SHELL_SUCCESS);
412 }
413
414 /**
415 Funciton to move a item to another location.
416
417 @param[in] Target The target item to move.
418 @param[in] CurrentOrder The pointer to the current order of items.
419 @param[in] OrderCount The number if items in CurrentOrder.
420 @param[in] OldLocation The current location of the Target.
421 @param[in] NewLocation The desired location of the Target.
422
423 @retval SHELL_SUCCESS The operation was successful.
424 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
425 **/
426 SHELL_STATUS
427 EFIAPI
428 BcfgMoveInstall1(
429 IN CONST BCFG_OPERATION_TARGET Target,
430 IN CONST UINT16 *CurrentOrder,
431 IN CONST UINTN OrderCount,
432 IN CONST UINT16 OldLocation,
433 IN CONST UINT16 NewLocation
434 )
435 {
436 UINT16 *NewOrder;
437 EFI_STATUS Status;
438 UINT16 Temp;
439
440 NewOrder = AllocateZeroPool(OrderCount*sizeof(CurrentOrder[0]));
441 ASSERT(NewOrder != NULL);
442
443 Temp = CurrentOrder[OldLocation];
444 CopyMem(NewOrder, CurrentOrder, OrderCount*sizeof(CurrentOrder[0]));
445 CopyMem(NewOrder+OldLocation, NewOrder+OldLocation+1, (OrderCount - OldLocation - 1)*sizeof(CurrentOrder[0]));
446 CopyMem(NewOrder+NewLocation+1, NewOrder+NewLocation, (OrderCount - NewLocation - 1)*sizeof(CurrentOrder[0]));
447 NewOrder[NewLocation] = Temp;
448
449
450 Status = gRT->SetVariable(
451 Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",
452 (EFI_GUID*)&gEfiGlobalVariableGuid,
453 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
454 OrderCount*sizeof(CurrentOrder[0]),
455 NewOrder);
456
457 FreePool(NewOrder);
458
459 if (EFI_ERROR(Status)) {
460 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder", Status);
461 return (SHELL_INVALID_PARAMETER);
462 }
463 return (SHELL_SUCCESS);
464 }
465
466 /**
467 Function to add optional data to an option.
468
469 @param[in] OptData The optional data to add.
470 @param[in] Target The target of the operation.
471
472 @retval SHELL_SUCCESS The operation was succesful.
473 **/
474 SHELL_STATUS
475 EFIAPI
476 BcfgAddOptInstall1(
477 IN CONST CHAR16 *OptData,
478 IN CONST BCFG_OPERATION_TARGET Target
479 )
480 {
481 ASSERT(OptData != NULL);
482 return SHELL_SUCCESS;
483 }
484
485 /**
486 Function to dump the Bcfg information.
487
488 @param[in] Op The operation.
489 @param[in] OrderCount How many to dump.
490 @param[in] CurrentOrder The pointer to the current order of items.
491 @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.
492
493 @retval SHELL_SUCCESS The dump was successful.
494 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
495 **/
496 SHELL_STATUS
497 EFIAPI
498 BcfgDisplayDumpInstall1(
499 IN CONST CHAR16 *Op,
500 IN CONST UINTN OrderCount,
501 IN CONST UINT16 *CurrentOrder,
502 IN CONST BOOLEAN VerboseOutput
503 )
504 {
505 EFI_STATUS Status;
506 UINT8 *Buffer;
507 UINTN BufferSize;
508 CHAR16 VariableName[12];
509 UINTN LoopVar;
510 UINTN LoopVar2;
511 CHAR16 *DevPathString;
512 VOID *DevPath;
513
514 if (OrderCount == 0) {
515 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_BCFG_NONE), gShellInstall1HiiHandle);
516 return (SHELL_SUCCESS);
517 }
518
519 for (LoopVar = 0 ; LoopVar < OrderCount ; LoopVar++) {
520 Buffer = NULL;
521 BufferSize = 0;
522 UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Op, CurrentOrder[LoopVar]);
523
524 Status = gRT->GetVariable(
525 VariableName,
526 (EFI_GUID*)&gEfiGlobalVariableGuid,
527 NULL,
528 &BufferSize,
529 Buffer);
530 if (Status == EFI_BUFFER_TOO_SMALL) {
531 Buffer = AllocateZeroPool(BufferSize);
532 Status = gRT->GetVariable(
533 VariableName,
534 (EFI_GUID*)&gEfiGlobalVariableGuid,
535 NULL,
536 &BufferSize,
537 Buffer);
538 }
539
540 if (EFI_ERROR(Status) || Buffer == NULL) {
541 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_READ_FAIL), gShellInstall1HiiHandle, VariableName, Status);
542 return (SHELL_INVALID_PARAMETER);
543 }
544
545 DevPath = AllocateZeroPool(*(UINT16*)(Buffer+4));
546 CopyMem(DevPath, Buffer+6+StrSize((CHAR16*)(Buffer+6)), *(UINT16*)(Buffer+4));
547 DevPathString = gDevPathToText->ConvertDevicePathToText(DevPath, TRUE, FALSE);
548 ShellPrintHiiEx(
549 -1,
550 -1,
551 NULL,
552 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS),
553 gShellInstall1HiiHandle,
554 LoopVar,
555 VariableName,
556 (CHAR16*)(Buffer+6),
557 DevPathString,
558 (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6) <= BufferSize?L'N':L'Y');
559 if (VerboseOutput) {
560 for (LoopVar2 = (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6);LoopVar2<BufferSize;LoopVar2++){
561 ShellPrintEx(
562 -1,
563 -1,
564 NULL,
565 L"%02x",
566 Buffer[LoopVar2]);
567 }
568 ShellPrintEx(
569 -1,
570 -1,
571 NULL,
572 L"\r\n");
573 }
574
575 if (Buffer != NULL) {
576 FreePool(Buffer);
577 }
578 if (DevPath != NULL) {
579 FreePool(DevPath);
580 }
581 if (DevPathString != NULL) {
582 FreePool(DevPathString);
583 }
584 }
585 return (SHELL_SUCCESS);
586 }
587
588 /**
589 Function to initialize the BCFG operation structure.
590
591 @param[in] Struct The stuct to initialize.
592 **/
593 VOID
594 EFIAPI
595 InitBcfgStructInstall1(
596 IN BGFG_OPERATION *Struct
597 )
598 {
599 ASSERT(Struct != NULL);
600 Struct->Target = BcfgTargetMax;
601 Struct->Type = BcfgTypeMax;
602 Struct->Number1 = 0;
603 Struct->Number2 = 0;
604 Struct->HandleIndex = 0;
605 Struct->FileName = NULL;
606 Struct->Description = NULL;
607 Struct->Order = NULL;
608 Struct->OptData = NULL;
609 }
610
611
612 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
613 {L"-v", TypeFlag},
614 {L"-opt", TypeMaxValue},
615 {NULL, TypeMax}
616 };
617
618 /**
619 Function for 'bcfg' command.
620
621 @param[in] ImageHandle Handle to the Image (NULL if Internal).
622 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
623 **/
624 SHELL_STATUS
625 EFIAPI
626 ShellCommandRunBcfgInstall (
627 IN EFI_HANDLE ImageHandle,
628 IN EFI_SYSTEM_TABLE *SystemTable
629 )
630 {
631 EFI_STATUS Status;
632 LIST_ENTRY *Package;
633 CHAR16 *ProblemParam;
634 SHELL_STATUS ShellStatus;
635 UINTN ParamNumber;
636 CONST CHAR16 *CurrentParam;
637 BGFG_OPERATION CurrentOperation;
638 UINTN Length;
639 UINT64 Intermediate;
640
641 Length = 0;
642 ProblemParam = NULL;
643 Package = NULL;
644 ShellStatus = SHELL_SUCCESS;
645
646 InitBcfgStructInstall1(&CurrentOperation);
647
648 //
649 // initialize the shell lib (we must be in non-auto-init...)
650 //
651 Status = ShellInitialize();
652 ASSERT_EFI_ERROR(Status);
653
654 Status = CommandInit();
655 ASSERT_EFI_ERROR(Status);
656
657 //
658 // parse the command line
659 //
660 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
661 if (EFI_ERROR(Status)) {
662 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
663 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, ProblemParam);
664 FreePool(ProblemParam);
665 ShellStatus = SHELL_INVALID_PARAMETER;
666 } else {
667 ASSERT(FALSE);
668 }
669 } else {
670 //
671 // Read in if we are doing -OPT
672 //
673 if (ShellCommandLineGetFlag(Package, L"-opt")) {
674 CurrentOperation.OptData = ShellCommandLineGetValue(Package, L"-opt");
675 if (CurrentOperation.OptData == NULL) {
676 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellInstall1HiiHandle, L"-opt");
677 ShellStatus = SHELL_INVALID_PARAMETER;
678 }
679 CurrentOperation.Type = BcfgTypeOpt;
680 }
681
682 //
683 // small block to read the target of the operation
684 //
685 if ((ShellCommandLineGetCount(Package) < 3 && CurrentOperation.Type != BcfgTypeOpt) ||
686 (ShellCommandLineGetCount(Package) < 2 && CurrentOperation.Type == BcfgTypeOpt)
687 ){
688 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
689 ShellStatus = SHELL_INVALID_PARAMETER;
690 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"driver") == 0) {
691 CurrentOperation.Target = BcfgTargetDriverOrder;
692 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"boot") == 0) {
693 CurrentOperation.Target = BcfgTargetBootOrder;
694 } else {
695 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT), gShellInstall1HiiHandle);
696 ShellStatus = SHELL_INVALID_PARAMETER;
697 }
698
699
700 //
701 // Read in the boot or driver order environment variable (not needed for opt)
702 //
703 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BcfgTargetMax && CurrentOperation.Type != BcfgTypeOpt) {
704 Length = 0;
705 Status = gRT->GetVariable(
706 CurrentOperation.Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",
707 (EFI_GUID*)&gEfiGlobalVariableGuid,
708 NULL,
709 &Length,
710 CurrentOperation.Order);
711 if (Status == EFI_BUFFER_TOO_SMALL) {
712 CurrentOperation.Order = AllocateZeroPool(Length+(4*sizeof(CurrentOperation.Order[0])));
713 Status = gRT->GetVariable(
714 CurrentOperation.Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",
715 (EFI_GUID*)&gEfiGlobalVariableGuid,
716 NULL,
717 &Length,
718 CurrentOperation.Order);
719 }
720 }
721
722 //
723 // large block to read the type of operation and verify parameter types for the info.
724 //
725 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BcfgTargetMax) {
726 for (ParamNumber = 2 ; ParamNumber < ShellCommandLineGetCount(Package) && ShellStatus == SHELL_SUCCESS; ParamNumber++) {
727 CurrentParam = ShellCommandLineGetRawValue(Package, ParamNumber);
728 if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"dump") == 0) {
729 CurrentOperation.Type = BcfgTypeDump;
730 } else if (ShellCommandLineGetFlag(Package, L"-v")) {
731 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, L"-v (without dump)");
732 ShellStatus = SHELL_INVALID_PARAMETER;
733 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"add") == 0) {
734 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {
735 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
736 ShellStatus = SHELL_INVALID_PARAMETER;
737 }
738 CurrentOperation.Type = BcfgTypeAdd;
739 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
740 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
741 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
742 ShellStatus = SHELL_INVALID_PARAMETER;
743 } else {
744 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
745 CurrentOperation.Number1 = (UINT16)Intermediate;
746 ASSERT(CurrentOperation.FileName == NULL);
747 CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
748 ASSERT(CurrentOperation.Description == NULL);
749 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
750 }
751 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addp") == 0) {
752 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {
753 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
754 ShellStatus = SHELL_INVALID_PARAMETER;
755 }
756 CurrentOperation.Type = BcfgTypeAddp;
757 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
758 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
759 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
760 ShellStatus = SHELL_INVALID_PARAMETER;
761 } else {
762 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
763 CurrentOperation.Number1 = (UINT16)Intermediate;
764 ASSERT(CurrentOperation.FileName == NULL);
765 CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
766 ASSERT(CurrentOperation.Description == NULL);
767 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
768 }
769 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addh") == 0) {
770 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {
771 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
772 ShellStatus = SHELL_INVALID_PARAMETER;
773 }
774 CurrentOperation.Type = BcfgTypeAddh;
775 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
776 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
777 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
778 ShellStatus = SHELL_INVALID_PARAMETER;
779 } else {
780 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
781 CurrentOperation.Number1 = (UINT16)Intermediate;
782 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
783 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
784 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
785 ShellStatus = SHELL_INVALID_PARAMETER;
786 } else {
787 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
788 CurrentOperation.HandleIndex = (UINT16)Intermediate;
789 ASSERT(CurrentOperation.Description == NULL);
790 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);
791 }
792 }
793 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"rm") == 0) {
794 if ((ParamNumber + 1) >= ShellCommandLineGetCount(Package)) {
795 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
796 ShellStatus = SHELL_INVALID_PARAMETER;
797 }
798 CurrentOperation.Type = BcfgTypeRm;
799 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
800 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
801 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
802 ShellStatus = SHELL_INVALID_PARAMETER;
803 } else {
804 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
805 CurrentOperation.Number1 = (UINT16)Intermediate;
806 if (CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))){
807 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));
808 ShellStatus = SHELL_INVALID_PARAMETER;
809 }
810 }
811 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"mv") == 0) {
812 if ((ParamNumber + 2) >= ShellCommandLineGetCount(Package)) {
813 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);
814 ShellStatus = SHELL_INVALID_PARAMETER;
815 }
816 CurrentOperation.Type = BcfgTypeMv;
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.Number1 = (UINT16)Intermediate;
824 if (CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))){
825 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));
826 ShellStatus = SHELL_INVALID_PARAMETER;
827 }
828 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);
829 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {
830 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
831 ShellStatus = SHELL_INVALID_PARAMETER;
832 } else {
833 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);
834 CurrentOperation.Number2 = (UINT16)Intermediate;
835 }
836 if (CurrentOperation.Number2 == CurrentOperation.Number1
837 ||CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))
838 ||CurrentOperation.Number2 > (Length / sizeof(CurrentOperation.Order[0]))
839 ){
840 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));
841 ShellStatus = SHELL_INVALID_PARAMETER;
842 }
843 }
844 } else {
845 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);
846 ShellStatus = SHELL_INVALID_PARAMETER;
847 }
848 }
849 }
850 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BcfgTargetMax && CurrentOperation.Type < BcfgTypeMax) {
851 //
852 // we have all the info. Do the work
853 //
854 switch (CurrentOperation.Type) {
855 case BcfgTypeDump:
856 ShellStatus = BcfgDisplayDumpInstall1(
857 CurrentOperation.Target == BcfgTargetBootOrder?L"Boot":L"Driver",
858 Length / sizeof(CurrentOperation.Order[0]),
859 CurrentOperation.Order,
860 ShellCommandLineGetFlag(Package, L"-v"));
861 break;
862 case BcfgTypeMv:
863 ShellStatus = BcfgMoveInstall1(
864 CurrentOperation.Target,
865 CurrentOperation.Order,
866 Length / sizeof(CurrentOperation.Order[0]),
867 CurrentOperation.Number1,
868 CurrentOperation.Number2);
869 break;
870 case BcfgTypeRm:
871 ShellStatus = BcfgRemoveInstall1(
872 CurrentOperation.Target,
873 CurrentOperation.Order,
874 Length / sizeof(CurrentOperation.Order[0]),
875 CurrentOperation.Number1);
876 break;
877 case BcfgTypeAdd:
878 case BcfgTypeAddp:
879 case BcfgTypeAddh:
880 ShellStatus = BcfgAddInstall1(
881 CurrentOperation.Number1,
882 CurrentOperation.FileName,
883 CurrentOperation.Description,
884 CurrentOperation.Order,
885 Length / sizeof(CurrentOperation.Order[0]),
886 CurrentOperation.Target,
887 (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddh),
888 (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddp),
889 CurrentOperation.HandleIndex);
890 break;
891 case BcfgTypeOpt:
892 ShellStatus = BcfgAddOptInstall1(
893 CurrentOperation.OptData,
894 CurrentOperation.Target);
895 break;
896 default:
897 ASSERT(FALSE);
898 }
899 }
900 }
901
902 if (Package != NULL) {
903 ShellCommandLineFreeVarList (Package);
904 }
905 if (CurrentOperation.FileName != NULL) {
906 FreePool(CurrentOperation.FileName);
907 }
908 if (CurrentOperation.Description != NULL) {
909 FreePool(CurrentOperation.Description);
910 }
911 if (CurrentOperation.Order != NULL) {
912 FreePool(CurrentOperation.Order);
913 }
914
915 return (ShellStatus);
916 }