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