]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.c
ShellPkg: Clean up source files
[mirror_edk2.git] / ShellPkg / Library / UefiShellBcfgCommandLib / UefiShellBcfgCommandLib.c
CommitLineData
7b01f0f3
JC
1/** @file\r
2 Main file for BCFG command.\r
3\r
c011b6c9 4 (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>\r
ba0014b9 5 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
7b01f0f3
JC
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16\r
17#include <Uefi.h>\r
7b01f0f3
JC
18\r
19#include <Guid/GlobalVariable.h>\r
20#include <Guid/ShellLibHiiGuid.h>\r
21\r
28165f24
RN
22#include <Protocol/Shell.h>\r
23#include <Protocol/ShellParameters.h>\r
7b01f0f3
JC
24#include <Protocol/DevicePath.h>\r
25#include <Protocol/LoadedImage.h>\r
26#include <Protocol/UnicodeCollation.h>\r
27\r
28#include <Library/BaseLib.h>\r
29#include <Library/BaseMemoryLib.h>\r
30#include <Library/DebugLib.h>\r
31#include <Library/MemoryAllocationLib.h>\r
32#include <Library/PcdLib.h>\r
33#include <Library/ShellCommandLib.h>\r
34#include <Library/ShellLib.h>\r
35#include <Library/SortLib.h>\r
36#include <Library/UefiLib.h>\r
37#include <Library/UefiRuntimeServicesTableLib.h>\r
38#include <Library/UefiBootServicesTableLib.h>\r
39#include <Library/HiiLib.h>\r
40#include <Library/FileHandleLib.h>\r
41#include <Library/PrintLib.h>\r
42#include <Library/HandleParsingLib.h>\r
43#include <Library/DevicePathLib.h>\r
5ab97a64 44#include <Library/UefiBootManagerLib.h>\r
7b01f0f3
JC
45\r
46STATIC CONST CHAR16 mFileName[] = L"ShellCommands";\r
47STATIC EFI_HANDLE gShellBcfgHiiHandle = NULL;\r
48\r
49typedef enum {\r
50 BcfgTargetBootOrder = 0,\r
51 BcfgTargetDriverOrder = 1,\r
52 BcfgTargetMax = 2\r
53} BCFG_OPERATION_TARGET;\r
54\r
55typedef enum {\r
56 BcfgTypeDump = 0,\r
57 BcfgTypeAdd = 1,\r
58 BcfgTypeAddp = 2,\r
59 BcfgTypeAddh = 3,\r
60 BcfgTypeRm = 4,\r
61 BcfgTypeMv = 5,\r
62 BcfgTypeOpt = 6,\r
5ab97a64
CC
63 BcfgTypeMod = 7,\r
64 BcfgTypeModf = 8,\r
65 BcfgTypeModp = 9,\r
66 BcfgTypeModh = 10,\r
67 BcfgTypeMax = 11\r
7b01f0f3
JC
68} BCFG_OPERATION_TYPE;\r
69\r
70typedef struct {\r
71 BCFG_OPERATION_TARGET Target;\r
72 BCFG_OPERATION_TYPE Type;\r
73 UINT16 Number1;\r
74 UINT16 Number2;\r
75 UINTN HandleIndex;\r
76 CHAR16 *FileName;\r
77 CHAR16 *Description;\r
78 UINT16 *Order;\r
79 CONST CHAR16 *OptData;\r
80} BGFG_OPERATION;\r
81\r
82/**\r
83 Update the optional data for a boot or driver option.\r
84\r
85 If optional data exists it will be changed.\r
86\r
87 @param[in] Index The boot or driver option index update.\r
88 @param[in] DataSize The size in bytes of Data.\r
89 @param[in] Data The buffer for the optioanl data.\r
90 @param[in] Target The target of the operation.\r
91\r
92 @retval EFI_SUCCESS The data was sucessfully updated.\r
93 @retval other A error occured.\r
94**/\r
95EFI_STATUS\r
7b01f0f3 96UpdateOptionalData(\r
ba0014b9
LG
97 UINT16 Index,\r
98 UINTN DataSize,\r
7b01f0f3
JC
99 UINT8 *Data,\r
100 IN CONST BCFG_OPERATION_TARGET Target\r
101 )\r
102{\r
103 EFI_STATUS Status;\r
104 CHAR16 VariableName[12];\r
105 UINTN OriginalSize;\r
106 UINT8 *OriginalData;\r
107 UINTN NewSize;\r
108 UINT8 *NewData;\r
109 UINTN OriginalOptionDataSize;\r
110\r
111 UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Target == BcfgTargetBootOrder?L"Boot":L"Driver", Index);\r
ba0014b9 112\r
7b01f0f3
JC
113 OriginalSize = 0;\r
114 OriginalData = NULL;\r
115 NewData = NULL;\r
116 NewSize = 0;\r
117\r
118 Status = gRT->GetVariable(\r
119 VariableName,\r
120 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
121 NULL,\r
122 &OriginalSize,\r
123 OriginalData);\r
124 if (Status == EFI_BUFFER_TOO_SMALL) {\r
125 OriginalData = AllocateZeroPool(OriginalSize);\r
126 if (OriginalData == NULL) {\r
127 return (EFI_OUT_OF_RESOURCES);\r
128 }\r
129 Status = gRT->GetVariable(\r
130 VariableName,\r
131 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
132 NULL,\r
133 &OriginalSize,\r
134 OriginalData);\r
135 }\r
136\r
137 if (!EFI_ERROR(Status)) {\r
138 //\r
139 // Allocate new struct and discard old optional data.\r
140 //\r
141 ASSERT (OriginalData != NULL);\r
142 OriginalOptionDataSize = sizeof(UINT32) + sizeof(UINT16) + StrSize(((CHAR16*)(OriginalData + sizeof(UINT32) + sizeof(UINT16))));\r
143 OriginalOptionDataSize += (*(UINT16*)(OriginalData + sizeof(UINT32)));\r
144 OriginalOptionDataSize -= OriginalSize;\r
145 NewSize = OriginalSize - OriginalOptionDataSize + DataSize;\r
2a6ede28 146 NewData = AllocatePool(NewSize);\r
7b01f0f3
JC
147 if (NewData == NULL) {\r
148 Status = EFI_OUT_OF_RESOURCES;\r
149 } else {\r
2a6ede28 150 CopyMem (NewData, OriginalData, OriginalSize - OriginalOptionDataSize);\r
7b01f0f3
JC
151 CopyMem(NewData + OriginalSize - OriginalOptionDataSize, Data, DataSize);\r
152 }\r
153 }\r
154\r
155 if (!EFI_ERROR(Status)) {\r
156 //\r
157 // put the data back under the variable\r
158 //\r
159 Status = gRT->SetVariable(\r
ba0014b9 160 VariableName,\r
7b01f0f3
JC
161 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
162 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
163 NewSize,\r
164 NewData);\r
165 }\r
166\r
167 SHELL_FREE_NON_NULL(OriginalData);\r
168 SHELL_FREE_NON_NULL(NewData);\r
169 return (Status);\r
170}\r
171\r
172/**\r
173 This function will get a CRC for a boot option.\r
174\r
175 @param[in, out] Crc The CRC value to return.\r
176 @param[in] BootIndex The boot option index to CRC.\r
177\r
178 @retval EFI_SUCCESS The CRC was sucessfully returned.\r
179 @retval other A error occured.\r
180**/\r
181EFI_STATUS\r
7b01f0f3 182GetBootOptionCrc(\r
ba0014b9 183 UINT32 *Crc,\r
7b01f0f3
JC
184 UINT16 BootIndex\r
185 )\r
186{\r
187 CHAR16 VariableName[12];\r
188 EFI_STATUS Status;\r
189 UINT8 *Buffer;\r
190 UINTN BufferSize;\r
191\r
192 Buffer = NULL;\r
193 BufferSize = 0;\r
194\r
195 //\r
196 // Get the data Buffer\r
197 //\r
198 UnicodeSPrint(VariableName, sizeof(VariableName), L"%Boot%04x", BootIndex);\r
199 Status = gRT->GetVariable(\r
200 VariableName,\r
201 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
202 NULL,\r
203 &BufferSize,\r
204 NULL);\r
205 if (Status == EFI_BUFFER_TOO_SMALL) {\r
206 Buffer = AllocateZeroPool(BufferSize);\r
207 Status = gRT->GetVariable(\r
208 VariableName,\r
209 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
210 NULL,\r
211 &BufferSize,\r
212 Buffer);\r
213 }\r
214\r
215 //\r
216 // Get the CRC computed\r
217 //\r
218 if (!EFI_ERROR(Status)) {\r
219 Status = gBS->CalculateCrc32 (Buffer, BufferSize, Crc);\r
220 }\r
221\r
222 SHELL_FREE_NON_NULL(Buffer);\r
223 return EFI_SUCCESS;\r
224}\r
225\r
226/**\r
227 This function will populate the device path protocol parameter based on TheHandle.\r
228\r
229 @param[in] TheHandle Driver handle.\r
230 @param[in, out] FilePath On a sucessful return the device path to the handle.\r
231\r
232 @retval EFI_SUCCESS The device path was sucessfully returned.\r
233 @retval other A error from gBS->HandleProtocol.\r
234\r
235 @sa HandleProtocol\r
236**/\r
237EFI_STATUS\r
7b01f0f3
JC
238GetDevicePathForDriverHandle (\r
239 IN EFI_HANDLE TheHandle,\r
240 IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath\r
241 )\r
242{\r
243 EFI_STATUS Status;\r
244 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
245 EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;\r
246\r
247 Status = gBS->OpenProtocol (\r
248 TheHandle,\r
249 &gEfiLoadedImageProtocolGuid,\r
250 (VOID**)&LoadedImage,\r
251 gImageHandle,\r
252 NULL,\r
253 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
254 );\r
255 if (!EFI_ERROR (Status)) {\r
256 Status = gBS->OpenProtocol (\r
257 LoadedImage->DeviceHandle,\r
258 &gEfiDevicePathProtocolGuid,\r
259 (VOID**)&ImageDevicePath,\r
260 gImageHandle,\r
261 NULL,\r
262 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
263 );\r
264 if (!EFI_ERROR (Status)) {\r
265// *DevPath = DuplicateDevicePath (ImageDevicePath);\r
266// *FilePath = DuplicateDevicePath (LoadedImage->FilePath);\r
267 *FilePath = AppendDevicePath(ImageDevicePath,LoadedImage->FilePath);\r
268 gBS->CloseProtocol(\r
269 LoadedImage->DeviceHandle,\r
270 &gEfiDevicePathProtocolGuid,\r
271 gImageHandle,\r
272 NULL);\r
273 }\r
274 gBS->CloseProtocol(\r
275 TheHandle,\r
276 &gEfiLoadedImageProtocolGuid,\r
277 gImageHandle,\r
278 NULL);\r
279 }\r
280 return (Status);\r
281}\r
282\r
5ab97a64
CC
283/**\r
284 Functino to get Device Path by a handle.\r
285\r
286 @param[in] TheHandle Use it to get DevicePath.\r
287 @param[in] Target Boot option target.\r
288 @param[in, out] DevicePath On a sucessful return the device path to the handle.\r
289\r
290 @retval SHELL_INVALID_PARAMETER The handle was NULL.\r
291 @retval SHELL_NOT_FOUND Not found device path by handle.\r
292 @retval SHELL_SUCCESS Get device path successfully.\r
293**/\r
294SHELL_STATUS\r
295GetDevicePathByHandle(\r
296 IN EFI_HANDLE TheHandle,\r
297 IN BCFG_OPERATION_TARGET Target,\r
298 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
299 )\r
300{\r
301 EFI_STATUS Status;\r
302 SHELL_STATUS ShellStatus;\r
303\r
304 UINTN DriverBindingHandleCount;\r
305 UINTN ParentControllerHandleCount;\r
306 UINTN ChildControllerHandleCount;\r
307\r
308 ShellStatus = SHELL_SUCCESS;\r
309\r
310 if (TheHandle == NULL) {\r
311 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");\r
312 return SHELL_INVALID_PARAMETER;\r
313 }\r
314\r
315 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (TheHandle, &DriverBindingHandleCount, NULL);\r
316 if (EFI_ERROR(Status)) {\r
317 DriverBindingHandleCount = 0;\r
318 }\r
319\r
320 Status = PARSE_HANDLE_DATABASE_PARENTS (TheHandle, &ParentControllerHandleCount, NULL);\r
321 if (EFI_ERROR (Status)) {\r
322 ParentControllerHandleCount = 0;\r
323 }\r
324\r
325 Status = ParseHandleDatabaseForChildControllers (TheHandle, &ChildControllerHandleCount, NULL);\r
326 if (EFI_ERROR (Status)) {\r
327 ChildControllerHandleCount = 0;\r
328 }\r
329\r
330 Status = gBS->HandleProtocol (TheHandle, &gEfiDevicePathProtocolGuid, (VOID**)DevicePath);\r
331\r
332 if ( DriverBindingHandleCount > 0 ||\r
333 ParentControllerHandleCount > 0 ||\r
334 ChildControllerHandleCount > 0 ||\r
335 !EFI_ERROR(Status)\r
336 ) {\r
337 //\r
338 // The handle points to a real controller which has a device path.\r
339 //\r
340 if (Target == BcfgTargetDriverOrder) {\r
341 ShellPrintHiiEx (\r
342 -1,\r
343 -1,\r
344 NULL,STRING_TOKEN (STR_GEN_PARAM_INV),\r
345 gShellBcfgHiiHandle,\r
346 L"bcfg",\r
347 L"Handle should point to driver image."\r
348 );\r
349 ShellStatus = SHELL_NOT_FOUND;\r
350 }\r
351 } else {\r
352 //\r
353 // The handle points to a driver image.\r
354 //\r
355 if (Target == BcfgTargetBootOrder) {\r
356 ShellPrintHiiEx (\r
357 -1,\r
358 -1,\r
359 NULL,\r
360 STRING_TOKEN (STR_GEN_PARAM_INV),\r
361 gShellBcfgHiiHandle,\r
362 L"bcfg",\r
363 L"Handle should point to controller."\r
364 );\r
365 ShellStatus = SHELL_NOT_FOUND;\r
366 } else {\r
367 if (EFI_ERROR (GetDevicePathForDriverHandle (TheHandle, DevicePath))) {\r
368 ShellStatus = SHELL_NOT_FOUND;\r
369 }\r
370 }\r
371 }\r
372\r
373 return (ShellStatus);\r
374}\r
375\r
376/**\r
377 Function to modify an option.\r
378\r
379 @param[in] BcfgOperation Pointer to BCFG operation.\r
380 @param[in] OrderCount The number if items in CurrentOrder.\r
381\r
382 @retval SHELL_SUCCESS The operation was successful.\r
383 @retval SHELL_INVALID_PARAMETER A parameter was invalid.\r
384 @retval SHELL_OUT_OF_RESOUCES A memory allocation failed.\r
385**/\r
386SHELL_STATUS\r
387BcfgMod (\r
388 IN CONST BGFG_OPERATION *BcfgOperation,\r
389 IN CONST UINTN OrderCount\r
390 )\r
391{\r
392 EFI_STATUS Status;\r
393 EFI_HANDLE CurHandle;\r
394 SHELL_STATUS ShellStatus;\r
395 CHAR16 OptionStr[40];\r
396 EFI_SHELL_FILE_INFO *FileList;\r
397 EFI_SHELL_FILE_INFO *Arg;\r
398 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
399 EFI_DEVICE_PATH_PROTOCOL *DevicePathBuffer;\r
400 EFI_DEVICE_PATH_PROTOCOL *DevicePathWalker;\r
401 EFI_BOOT_MANAGER_LOAD_OPTION LoadOption;\r
402\r
403 ShellStatus = SHELL_SUCCESS;\r
404 FileList = NULL;\r
405 DevicePath = NULL;\r
f4fc7d53 406 DevicePathBuffer = NULL;\r
5ab97a64
CC
407\r
408 ZeroMem (&LoadOption, sizeof(EFI_BOOT_MANAGER_LOAD_OPTION));\r
409\r
410 if ( (BcfgOperation->Type == BcfgTypeMod && BcfgOperation->Description == NULL) ||\r
411 (BcfgOperation->Type == BcfgTypeModf && BcfgOperation->FileName == NULL) ||\r
412 (BcfgOperation->Type == BcfgTypeModp && BcfgOperation->FileName == NULL) ||\r
413 (BcfgOperation->Type == BcfgTypeModh && BcfgOperation->HandleIndex == 0) ||\r
414 (BcfgOperation->Number1 > OrderCount)\r
415 ) {\r
416 return (SHELL_INVALID_PARAMETER);\r
417 }\r
418\r
419 if (BcfgOperation->Type == BcfgTypeModh) {\r
420 CurHandle = ConvertHandleIndexToHandle (BcfgOperation->HandleIndex);\r
421 ShellStatus = GetDevicePathByHandle (CurHandle, BcfgOperation->Target, &DevicePathBuffer);\r
422 if (ShellStatus == SHELL_SUCCESS) {\r
423 DevicePath = DuplicateDevicePath (DevicePathBuffer);\r
424 }\r
425 } else if (BcfgOperation->Type == BcfgTypeModf || BcfgOperation->Type == BcfgTypeModp) {\r
426 //\r
427 // Get Device Path by FileName.\r
428 //\r
429 ShellOpenFileMetaArg ((CHAR16 *)BcfgOperation->FileName, EFI_FILE_MODE_READ, &FileList);\r
430 if (FileList == NULL) {\r
431 //\r
432 // The name of file matched nothing.\r
433 //\r
434 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);\r
435 ShellStatus = SHELL_INVALID_PARAMETER;\r
436 }\r
437 else if (FileList->Link.ForwardLink != FileList->Link.BackLink) {\r
438 //\r
439 // If the name of file expanded to multiple names, it's fail.\r
440 //\r
441 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);\r
442 ShellStatus = SHELL_INVALID_PARAMETER;\r
443 } else {\r
444 Arg = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link);\r
445 if (EFI_ERROR (Arg->Status)) {\r
446 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);\r
447 ShellStatus = SHELL_INVALID_PARAMETER;\r
448 } else {\r
449 DevicePathBuffer = gEfiShellProtocol->GetDevicePathFromFilePath (Arg->FullName);\r
450 if (DevicePathBuffer == NULL) {\r
451 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellBcfgHiiHandle, L"bcfg", Arg->FullName);\r
452 ShellStatus = SHELL_UNSUPPORTED;\r
453 }\r
454 }\r
455 }\r
456\r
457 if (ShellStatus == SHELL_SUCCESS) {\r
458 if (BcfgOperation->Type == BcfgTypeModp) {\r
459 ShellStatus = SHELL_INVALID_PARAMETER;\r
460 DevicePathWalker = DevicePathBuffer;\r
461 while (!IsDevicePathEnd (DevicePathWalker)) {\r
462 if ( DevicePathType (DevicePathWalker) == MEDIA_DEVICE_PATH &&\r
463 DevicePathSubType (DevicePathWalker) == MEDIA_HARDDRIVE_DP\r
464 ) {\r
465 //\r
466 // We found the portion of device path starting with the hard driver partition.\r
467 //\r
468 ShellStatus = SHELL_SUCCESS;\r
469 DevicePath = DuplicateDevicePath (DevicePathWalker);\r
470 break;\r
471 } else {\r
472 DevicePathWalker = NextDevicePathNode (DevicePathWalker);\r
473 }\r
474 }\r
475 } else {\r
476 DevicePath = DuplicateDevicePath (DevicePathBuffer);\r
477 }\r
478\r
479 FreePool (DevicePathBuffer);\r
480 }\r
481 }\r
482\r
483 if (ShellStatus == SHELL_SUCCESS) {\r
484 if (BcfgOperation->Target == BcfgTargetBootOrder) {\r
485 UnicodeSPrint (OptionStr, sizeof (OptionStr), L"Boot%04x", BcfgOperation->Order[BcfgOperation->Number1]);\r
486 } else {\r
487 UnicodeSPrint (OptionStr, sizeof (OptionStr), L"Driver%04x", BcfgOperation->Order[BcfgOperation->Number1]);\r
488 }\r
489 Status = EfiBootManagerVariableToLoadOption (OptionStr, &LoadOption);\r
490 if (EFI_ERROR(Status)) {\r
491 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NONE), gShellBcfgHiiHandle);\r
492 ShellStatus = SHELL_NOT_FOUND;\r
493 }\r
494 }\r
495\r
496 if (ShellStatus == SHELL_SUCCESS) {\r
497 if (BcfgOperation->Type == BcfgTypeMod) {\r
498 SHELL_FREE_NON_NULL (LoadOption.Description);\r
499 LoadOption.Description = AllocateCopyPool (StrSize (BcfgOperation->Description), BcfgOperation->Description);\r
500 } else {\r
501 SHELL_FREE_NON_NULL (LoadOption.FilePath);\r
502 LoadOption.FilePath = DuplicateDevicePath (DevicePath);\r
503 }\r
504\r
505 Status = EfiBootManagerLoadOptionToVariable (&LoadOption);\r
506 if (EFI_ERROR(Status)) {\r
507 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", OptionStr);\r
508 ShellStatus = SHELL_INVALID_PARAMETER;\r
509 }\r
510 }\r
511\r
512 EfiBootManagerFreeLoadOption (&LoadOption);\r
513\r
514 if (DevicePath != NULL) {\r
515 FreePool (DevicePath);\r
516 }\r
517\r
518 if (FileList != NULL) {\r
519 ShellCloseFileMetaArg (&FileList);\r
520 }\r
521\r
522 return (ShellStatus);\r
523}\r
524\r
7b01f0f3
JC
525/**\r
526 Function to add a option.\r
527\r
528 @param[in] Position The position to add Target at.\r
529 @param[in] File The file to make the target.\r
530 @param[in] Desc The description text.\r
531 @param[in] CurrentOrder The pointer to the current order of items.\r
532 @param[in] OrderCount The number if items in CurrentOrder.\r
533 @param[in] Target The info on the option to add.\r
534 @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.\r
535 @param[in] UsePath TRUE to convert to devicepath.\r
536 @param[in] HandleNumber The handle number to add.\r
537\r
538 @retval SHELL_SUCCESS The operation was successful.\r
539 @retval SHELL_INVALID_PARAMETER A parameter was invalid.\r
540**/\r
541SHELL_STATUS\r
7b01f0f3
JC
542BcfgAdd(\r
543 IN UINTN Position,\r
544 IN CONST CHAR16 *File,\r
545 IN CONST CHAR16 *Desc,\r
546 IN CONST UINT16 *CurrentOrder,\r
547 IN CONST UINTN OrderCount,\r
548 IN CONST BCFG_OPERATION_TARGET Target,\r
549 IN CONST BOOLEAN UseHandle,\r
550 IN CONST BOOLEAN UsePath,\r
551 IN CONST UINTN HandleNumber\r
552 )\r
553{\r
554 EFI_STATUS Status;\r
555 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
f86a5c34 556 EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
7b01f0f3
JC
557 EFI_DEVICE_PATH_PROTOCOL *FilePath;\r
558 CHAR16 *Str;\r
559 UINT8 *TempByteBuffer;\r
560 UINT8 *TempByteStart;\r
561 EFI_SHELL_FILE_INFO *Arg;\r
562 EFI_SHELL_FILE_INFO *FileList;\r
563 CHAR16 OptionStr[40];\r
564 UINTN DescSize, FilePathSize;\r
565 BOOLEAN Found;\r
566 UINTN TargetLocation;\r
567 UINTN Index;\r
568 EFI_HANDLE *Handles;\r
569 EFI_HANDLE CurHandle;\r
570 UINTN DriverBindingHandleCount;\r
571 UINTN ParentControllerHandleCount;\r
572 UINTN ChildControllerHandleCount;\r
573 SHELL_STATUS ShellStatus;\r
574 UINT16 *NewOrder;\r
575\r
576 if (!UseHandle) {\r
577 if (File == NULL || Desc == NULL) {\r
578 return (SHELL_INVALID_PARAMETER);\r
579 }\r
580 } else {\r
581 if (HandleNumber == 0) {\r
582 return (SHELL_INVALID_PARAMETER);\r
583 }\r
584 }\r
585\r
586 if (Position > OrderCount) {\r
587 Position = OrderCount;\r
588 }\r
589\r
590 Str = NULL;\r
591 FilePath = NULL;\r
592 FileList = NULL;\r
593 Handles = NULL;\r
594 ShellStatus = SHELL_SUCCESS;\r
595 TargetLocation = 0xFFFF;\r
596\r
597 if (UseHandle) {\r
598 CurHandle = ConvertHandleIndexToHandle(HandleNumber);\r
599 if (CurHandle == NULL) {\r
3eb46cfc 600 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");\r
7b01f0f3
JC
601 ShellStatus = SHELL_INVALID_PARAMETER;\r
602 } else {\r
603 if (Target == BcfgTargetBootOrder) {\r
604 //\r
605 //Make sure that the handle should point to a real controller\r
606 //\r
607 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (\r
608 CurHandle,\r
609 &DriverBindingHandleCount,\r
610 NULL);\r
611\r
612 Status = PARSE_HANDLE_DATABASE_PARENTS (\r
613 CurHandle,\r
614 &ParentControllerHandleCount,\r
615 NULL);\r
616\r
617 Status = ParseHandleDatabaseForChildControllers (\r
618 CurHandle,\r
619 &ChildControllerHandleCount,\r
620 NULL);\r
621\r
622 if (DriverBindingHandleCount > 0\r
623 || ParentControllerHandleCount > 0\r
624 || ChildControllerHandleCount > 0) {\r
625 FilePath = NULL;\r
626 Status = gBS->HandleProtocol (\r
627 CurHandle,\r
628 &gEfiDevicePathProtocolGuid,\r
629 (VOID**)&FilePath);\r
630 }\r
631 if (EFI_ERROR (Status)) {\r
ba0014b9 632 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_HANDLE), gShellBcfgHiiHandle, L"bcfg", HandleNumber);\r
7b01f0f3
JC
633 ShellStatus = SHELL_INVALID_PARAMETER;\r
634 }\r
635 } else {\r
636 //\r
637 //Make sure that the handle should point to driver, not a controller.\r
638 //\r
639 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (\r
640 CurHandle,\r
641 &DriverBindingHandleCount,\r
642 NULL);\r
643\r
644 Status = PARSE_HANDLE_DATABASE_PARENTS (\r
645 CurHandle,\r
646 &ParentControllerHandleCount,\r
647 NULL);\r
648\r
649 Status = ParseHandleDatabaseForChildControllers (\r
650 CurHandle,\r
651 &ChildControllerHandleCount,\r
652 NULL);\r
653\r
654 Status = gBS->HandleProtocol (\r
655 CurHandle,\r
656 &gEfiDevicePathProtocolGuid,\r
657 (VOID**)&FilePath);\r
658\r
659 if (DriverBindingHandleCount > 0\r
660 || ParentControllerHandleCount > 0\r
661 || ChildControllerHandleCount > 0\r
662 || !EFI_ERROR(Status) ) {\r
ba0014b9 663 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");\r
7b01f0f3
JC
664 ShellStatus = SHELL_INVALID_PARAMETER;\r
665 } else {\r
666 //\r
667 // Get the DevicePath from the loaded image information.\r
668 //\r
669 Status = GetDevicePathForDriverHandle(CurHandle, &FilePath);\r
670 }\r
671 }\r
672 }\r
673 } else {\r
674 //\r
675 // Get file info\r
676 //\r
677 ShellOpenFileMetaArg ((CHAR16*)File, EFI_FILE_MODE_READ, &FileList);\r
678\r
679 if (FileList == NULL) {\r
680 //\r
681 // If filename matched nothing fail\r
682 //\r
ba0014b9 683 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellBcfgHiiHandle, L"bcfg", File);\r
7b01f0f3
JC
684 ShellStatus = SHELL_INVALID_PARAMETER;\r
685 } else if (FileList->Link.ForwardLink != FileList->Link.BackLink) {\r
686 //\r
687 // If filename expanded to multiple names, fail\r
688 //\r
ba0014b9 689 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellBcfgHiiHandle, L"bcfg", File);\r
7b01f0f3
JC
690 ShellStatus = SHELL_INVALID_PARAMETER;\r
691 } else {\r
692 Arg = (EFI_SHELL_FILE_INFO*)GetFirstNode(&FileList->Link);\r
693 if (EFI_ERROR(Arg->Status)) {\r
ba0014b9 694 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellBcfgHiiHandle, L"bcfg", File);\r
7b01f0f3
JC
695 ShellStatus = SHELL_INVALID_PARAMETER;\r
696 } else {\r
697 //\r
698 // Build FilePath to the filename\r
699 //\r
700\r
701 //\r
702 // get the device path\r
703 //\r
704 DevicePath = gEfiShellProtocol->GetDevicePathFromFilePath(Arg->FullName);\r
705 if (DevicePath == NULL) {\r
ba0014b9 706 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellBcfgHiiHandle, L"bcfg", Arg->FullName);\r
7b01f0f3
JC
707 ShellStatus = SHELL_UNSUPPORTED;\r
708 } else {\r
7b01f0f3 709 if (UsePath) {\r
f86a5c34
QS
710 DevPath = DevicePath;\r
711 ShellStatus = SHELL_INVALID_PARAMETER;\r
7b01f0f3
JC
712 while (!IsDevicePathEnd(DevPath)) {\r
713 if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&\r
714 (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {\r
715\r
716 //\r
717 // If we find it use it instead\r
718 //\r
f86a5c34
QS
719 ShellStatus = SHELL_SUCCESS;\r
720 FilePath = DuplicateDevicePath (DevPath);\r
7b01f0f3
JC
721 break;\r
722 }\r
723 DevPath = NextDevicePathNode(DevPath);\r
724 }\r
7b01f0f3 725 } else {\r
7b01f0f3 726 FilePath = DuplicateDevicePath(DevicePath);\r
7b01f0f3 727 }\r
7b01f0f3
JC
728 FreePool(DevicePath);\r
729 }\r
730 }\r
731 }\r
732 }\r
733\r
734\r
735 if (ShellStatus == SHELL_SUCCESS) {\r
736 //\r
737 // Find a free target ,a brute force implementation\r
738 //\r
739 Found = FALSE;\r
740 for (TargetLocation=0; TargetLocation < 0xFFFF; TargetLocation++) {\r
741 Found = TRUE;\r
742 for (Index=0; Index < OrderCount; Index++) {\r
743 if (CurrentOrder[Index] == TargetLocation) {\r
744 Found = FALSE;\r
745 break;\r
746 }\r
747 }\r
748\r
749 if (Found) {\r
750 break;\r
751 }\r
752 }\r
753\r
754 if (TargetLocation == 0xFFFF) {\r
ba0014b9 755 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET_NF), gShellBcfgHiiHandle, L"bcfg");\r
7b01f0f3
JC
756 } else {\r
757 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET), gShellBcfgHiiHandle, TargetLocation);\r
758 }\r
759 }\r
760\r
761 if (ShellStatus == SHELL_SUCCESS) {\r
762 //\r
763 // Add the option\r
764 //\r
765 DescSize = StrSize(Desc);\r
766 FilePathSize = GetDevicePathSize (FilePath);\r
767\r
768 TempByteBuffer = AllocateZeroPool(sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize);\r
769 if (TempByteBuffer != NULL) {\r
770 TempByteStart = TempByteBuffer;\r
771 *((UINT32 *) TempByteBuffer) = LOAD_OPTION_ACTIVE; // Attributes\r
772 TempByteBuffer += sizeof (UINT32);\r
773\r
774 *((UINT16 *) TempByteBuffer) = (UINT16)FilePathSize; // FilePathListLength\r
775 TempByteBuffer += sizeof (UINT16);\r
776\r
777 CopyMem (TempByteBuffer, Desc, DescSize);\r
778 TempByteBuffer += DescSize;\r
779 ASSERT (FilePath != NULL);\r
780 CopyMem (TempByteBuffer, FilePath, FilePathSize);\r
781\r
782 UnicodeSPrint (OptionStr, sizeof(OptionStr), L"%s%04x", Target == BcfgTargetBootOrder?L"Boot":L"Driver", TargetLocation);\r
783 Status = gRT->SetVariable (\r
784 OptionStr,\r
785 &gEfiGlobalVariableGuid,\r
786 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
787 sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize,\r
788 TempByteStart\r
789 );\r
790\r
791 FreePool(TempByteStart);\r
792 } else {\r
793 Status = EFI_OUT_OF_RESOURCES;\r
794 }\r
795\r
796 if (EFI_ERROR(Status)) {\r
ba0014b9 797 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", OptionStr);\r
7b01f0f3 798 } else {\r
5945813f
RN
799 NewOrder = AllocateZeroPool ((OrderCount + 1) * sizeof (NewOrder[0]));\r
800 if (NewOrder != NULL) {\r
801 CopyMem (NewOrder, CurrentOrder, (OrderCount) * sizeof (NewOrder[0]));\r
7b01f0f3 802\r
5945813f
RN
803 //\r
804 // Insert target into order list\r
805 //\r
806 for (Index = OrderCount; Index > Position; Index--) {\r
807 NewOrder[Index] = NewOrder[Index - 1];\r
808 }\r
7b01f0f3 809\r
5945813f
RN
810 NewOrder[Position] = (UINT16) TargetLocation;\r
811 Status = gRT->SetVariable (\r
812 Target == BcfgTargetBootOrder ? L"BootOrder" : L"DriverOrder",\r
813 &gEfiGlobalVariableGuid,\r
814 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
815 (OrderCount + 1) * sizeof (UINT16),\r
816 NewOrder\r
817 );\r
7b01f0f3 818\r
5945813f 819 FreePool (NewOrder);\r
7b01f0f3 820\r
5945813f
RN
821 if (EFI_ERROR (Status)) {\r
822 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder ? L"BootOrder" : L"DriverOrder");\r
823 ShellStatus = SHELL_INVALID_PARAMETER;\r
824 } else {\r
825 Print (L"bcfg: Add %s as %x\n", OptionStr, Position);\r
826 }\r
7b01f0f3
JC
827 }\r
828 }\r
829 }\r
830\r
831//\r
832//If always Free FilePath, will free devicepath in system when use "addh"\r
833//\r
834 if (FilePath!=NULL && !UseHandle) {\r
835 FreePool (FilePath);\r
836 }\r
837\r
838 if (Str != NULL) {\r
839 FreePool(Str);\r
840 }\r
841\r
842 if (Handles != NULL) {\r
843 FreePool (Handles);\r
844 }\r
845\r
846 if (FileList != NULL) {\r
847 ShellCloseFileMetaArg (&FileList);\r
848 }\r
849\r
850 return (ShellStatus);\r
851}\r
852\r
853/**\r
854 Funciton to remove an item.\r
855\r
856 @param[in] Target The target item to move.\r
857 @param[in] CurrentOrder The pointer to the current order of items.\r
858 @param[in] OrderCount The number if items in CurrentOrder.\r
859 @param[in] Location The current location of the Target.\r
860\r
861 @retval SHELL_SUCCESS The operation was successful.\r
862 @retval SHELL_INVALID_PARAMETER A parameter was invalid.\r
863**/\r
864SHELL_STATUS\r
7b01f0f3
JC
865BcfgRemove(\r
866 IN CONST BCFG_OPERATION_TARGET Target,\r
867 IN CONST UINT16 *CurrentOrder,\r
868 IN CONST UINTN OrderCount,\r
869 IN CONST UINT16 Location\r
870 )\r
871{\r
872 CHAR16 VariableName[12];\r
873 UINT16 *NewOrder;\r
874 EFI_STATUS Status;\r
875 UINTN NewCount;\r
876\r
877 UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Target == BcfgTargetBootOrder?L"Boot":L"Driver", CurrentOrder[Location]);\r
878 Status = gRT->SetVariable(\r
879 VariableName,\r
880 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
881 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
882 0,\r
883 NULL);\r
884 if (EFI_ERROR(Status)) {\r
ba0014b9 885 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);\r
7b01f0f3
JC
886 return (SHELL_INVALID_PARAMETER);\r
887 }\r
888 NewOrder = AllocateZeroPool(OrderCount*sizeof(CurrentOrder[0]));\r
889 if (NewOrder != NULL) {\r
890 NewCount = OrderCount;\r
891 CopyMem(NewOrder, CurrentOrder, OrderCount*sizeof(CurrentOrder[0]));\r
892 CopyMem(NewOrder+Location, NewOrder+Location+1, (OrderCount - Location - 1)*sizeof(CurrentOrder[0]));\r
893 NewCount--;\r
894\r
895 Status = gRT->SetVariable(\r
896 Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
897 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
898 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
899 NewCount*sizeof(NewOrder[0]),\r
900 NewOrder);\r
901 FreePool(NewOrder);\r
902 } else {\r
903 Status = EFI_OUT_OF_RESOURCES;\r
904 }\r
905 if (EFI_ERROR(Status)) {\r
ba0014b9 906 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder");\r
7b01f0f3
JC
907 return (SHELL_INVALID_PARAMETER);\r
908 }\r
909 return (SHELL_SUCCESS);\r
910}\r
911\r
912/**\r
913 Funciton to move a item to another location.\r
914\r
915 @param[in] Target The target item to move.\r
916 @param[in] CurrentOrder The pointer to the current order of items.\r
917 @param[in] OrderCount The number if items in CurrentOrder.\r
918 @param[in] OldLocation The current location of the Target.\r
919 @param[in] NewLocation The desired location of the Target.\r
920\r
921 @retval SHELL_SUCCESS The operation was successful.\r
922 @retval SHELL_INVALID_PARAMETER A parameter was invalid.\r
923**/\r
924SHELL_STATUS\r
7b01f0f3
JC
925BcfgMove(\r
926 IN CONST BCFG_OPERATION_TARGET Target,\r
927 IN CONST UINT16 *CurrentOrder,\r
928 IN CONST UINTN OrderCount,\r
929 IN CONST UINT16 OldLocation,\r
930 IN UINT16 NewLocation\r
931 )\r
932{\r
933 UINT16 *NewOrder;\r
934 EFI_STATUS Status;\r
935 UINT16 Temp;\r
936\r
937 NewOrder = AllocateCopyPool(OrderCount*sizeof(CurrentOrder[0]), CurrentOrder);\r
938 if (NewOrder == NULL) {\r
939 return (SHELL_OUT_OF_RESOURCES);\r
940 }\r
941\r
942 //\r
943 // correct the new location\r
944 //\r
945 if (NewLocation >= OrderCount) {\r
946 if (OrderCount > 0) {\r
947 NewLocation = (UINT16)OrderCount - 1;\r
948 } else {\r
949 NewLocation = 0;\r
950 }\r
951 }\r
952\r
953 Temp = CurrentOrder[OldLocation];\r
954 CopyMem(NewOrder+OldLocation, NewOrder+OldLocation+1, (OrderCount - OldLocation - 1)*sizeof(CurrentOrder[0]));\r
955 CopyMem(NewOrder+NewLocation+1, NewOrder+NewLocation, (OrderCount - NewLocation - 1)*sizeof(CurrentOrder[0]));\r
956 NewOrder[NewLocation] = Temp;\r
957\r
958 Status = gRT->SetVariable(\r
959 Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
960 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
961 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
962 OrderCount*sizeof(CurrentOrder[0]),\r
963 NewOrder);\r
964\r
965 FreePool(NewOrder);\r
966\r
967 if (EFI_ERROR(Status)) {\r
ba0014b9 968 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder");\r
7b01f0f3
JC
969 return (SHELL_INVALID_PARAMETER);\r
970 }\r
971 return (SHELL_SUCCESS);\r
972}\r
973\r
974/**\r
975 Function to add optional data to an option.\r
976\r
977 @param[in] OptData The optional data to add.\r
978 @param[in] CurrentOrder The pointer to the current order of items.\r
979 @param[in] OrderCount The number if items in CurrentOrder.\r
980 @param[in] Target The target of the operation.\r
981\r
982 @retval SHELL_SUCCESS The operation was succesful.\r
983**/\r
984SHELL_STATUS\r
7b01f0f3
JC
985BcfgAddOpt(\r
986 IN CONST CHAR16 *OptData,\r
987 IN CONST UINT16 *CurrentOrder,\r
988 IN CONST UINTN OrderCount,\r
989 IN CONST BCFG_OPERATION_TARGET Target\r
990 )\r
991{\r
992 EFI_KEY_OPTION NewKeyOption;\r
993 EFI_KEY_OPTION *KeyOptionBuffer;\r
994 SHELL_STATUS ShellStatus;\r
995 EFI_STATUS Status;\r
996 UINT16 OptionIndex;\r
997 UINT16 LoopCounter;\r
998 UINT64 Intermediate;\r
999 CONST CHAR16 *Temp;\r
1000 CONST CHAR16 *Walker;\r
1001 CHAR16 *FileName;\r
1002 CHAR16 *Temp2;\r
1003 CHAR16 *Data;\r
77eef0d5 1004 UINT32 KeyIndex;\r
7b01f0f3 1005 CHAR16 VariableName[12];\r
1fd8de32 1006 VOID *VariableData;\r
7b01f0f3
JC
1007\r
1008 SHELL_FILE_HANDLE FileHandle;\r
1009\r
1010 Status = EFI_SUCCESS;\r
1011 ShellStatus = SHELL_SUCCESS;\r
1012 Walker = OptData;\r
1013 FileName = NULL;\r
1014 Data = NULL;\r
1015 KeyOptionBuffer = NULL;\r
77eef0d5 1016 VariableData = NULL;\r
7b01f0f3
JC
1017\r
1018 ZeroMem(&NewKeyOption, sizeof(EFI_KEY_OPTION));\r
77eef0d5 1019 ZeroMem(VariableName, sizeof(VariableName));\r
7b01f0f3
JC
1020\r
1021 while(Walker[0] == L' ') {\r
1022 Walker++;\r
1023 }\r
1024\r
1025 //\r
1026 // Get the index of the variable we are changing.\r
1027 //\r
1028 Status = ShellConvertStringToUint64(Walker, &Intermediate, FALSE, TRUE);\r
1029 if (EFI_ERROR(Status) || (((UINT16)Intermediate) != Intermediate) || StrStr(Walker, L" ") == NULL || ((UINT16)Intermediate) > ((UINT16)OrderCount)) {\r
ba0014b9 1030 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Option Index");\r
7b01f0f3
JC
1031 ShellStatus = SHELL_INVALID_PARAMETER;\r
1032 return (ShellStatus);\r
1033 }\r
1034 OptionIndex = (UINT16)Intermediate;\r
1035\r
1036 Temp = StrStr(Walker, L" ");\r
1037 if (Temp != NULL) {\r
1038 Walker = Temp;\r
1039 }\r
1040 while(Walker[0] == L' ') {\r
1041 Walker++;\r
1042 }\r
1043\r
1044 //\r
ba0014b9 1045 // determine whether we have file with data, quote delimited information, or a hot-key\r
7b01f0f3
JC
1046 //\r
1047 if (Walker[0] == L'\"') {\r
1048 //\r
1049 // quoted filename or quoted information.\r
1050 //\r
1051 Temp = StrStr(Walker+1, L"\"");\r
1052 if (Temp == NULL || StrLen(Temp) != 1) {\r
ba0014b9 1053 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);\r
7b01f0f3
JC
1054 ShellStatus = SHELL_INVALID_PARAMETER;\r
1055 } else {\r
1056 FileName = StrnCatGrow(&FileName, NULL, Walker+1, 0);\r
1057 if (FileName == NULL) {\r
ba0014b9 1058 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellBcfgHiiHandle, L"bcfg");\r
7b01f0f3
JC
1059 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
1060 return (ShellStatus);\r
1061 }\r
1062 Temp2 = StrStr(FileName, L"\"");\r
1063 ASSERT(Temp2 != NULL);\r
1064 Temp2[0] = CHAR_NULL;\r
1065 Temp2++;\r
1066 if (StrLen(Temp2)>0) {\r
ba0014b9 1067 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);\r
7b01f0f3
JC
1068 ShellStatus = SHELL_INVALID_PARAMETER;\r
1069 }\r
1070 if (EFI_ERROR(ShellFileExists(Walker))) {\r
1071 //\r
1072 // Not a file. must be misc information.\r
1073 //\r
1074 Data = FileName;\r
1075 FileName = NULL;\r
1076 } else {\r
1077 FileName = StrnCatGrow(&FileName, NULL, Walker, 0);\r
1078 }\r
1079 }\r
1080 } else {\r
1081 //\r
1082 // filename or hot key information.\r
1083 //\r
1084 if (StrStr(Walker, L" ") == NULL) {\r
1085 //\r
1086 // filename\r
1087 //\r
1088 if (EFI_ERROR(ShellFileExists(Walker))) {\r
ba0014b9 1089 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FIND_FAIL), gShellBcfgHiiHandle, L"bcfg", Walker);\r
7b01f0f3
JC
1090 ShellStatus = SHELL_INVALID_PARAMETER;\r
1091 } else {\r
1092 FileName = StrnCatGrow(&FileName, NULL, Walker, 0);\r
1093 }\r
1094 } else {\r
1095 if (Target != BcfgTargetBootOrder) {\r
ba0014b9 1096 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_BOOT_ONLY), gShellBcfgHiiHandle, L"bcfg");\r
7b01f0f3
JC
1097 ShellStatus = SHELL_INVALID_PARAMETER;\r
1098 }\r
1099\r
1100 if (ShellStatus == SHELL_SUCCESS) {\r
1101 //\r
1102 // Get hot key information\r
1103 //\r
1104 Status = ShellConvertStringToUint64(Walker, &Intermediate, FALSE, TRUE);\r
1105 if (EFI_ERROR(Status) || (((UINT32)Intermediate) != Intermediate) || StrStr(Walker, L" ") == NULL) {\r
ba0014b9 1106 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);\r
7b01f0f3
JC
1107 ShellStatus = SHELL_INVALID_PARAMETER;\r
1108 }\r
1109 NewKeyOption.KeyData.PackedValue = (UINT32)Intermediate;\r
1110 Temp = StrStr(Walker, L" ");\r
1111 if (Temp != NULL) {\r
1112 Walker = Temp;\r
1113 }\r
1114 while(Walker[0] == L' ') {\r
1115 Walker++;\r
1116 }\r
1117 }\r
1118\r
1119 if (ShellStatus == SHELL_SUCCESS) {\r
1120 //\r
ba0014b9 1121 // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.\r
7b01f0f3
JC
1122 // Re-allocate with the added information.\r
1123 //\r
2a6ede28 1124 KeyOptionBuffer = AllocatePool (sizeof(EFI_KEY_OPTION) + (sizeof(EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount));\r
7b01f0f3 1125 if (KeyOptionBuffer == NULL) {\r
ba0014b9 1126 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");\r
7b01f0f3 1127 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
2a6ede28 1128 return ShellStatus;\r
7b01f0f3 1129 }\r
2a6ede28 1130 CopyMem (KeyOptionBuffer, &NewKeyOption, sizeof(EFI_KEY_OPTION));\r
7b01f0f3
JC
1131 }\r
1132 for (LoopCounter = 0 ; ShellStatus == SHELL_SUCCESS && LoopCounter < NewKeyOption.KeyData.Options.InputKeyCount; LoopCounter++) {\r
1133 //\r
1134 // ScanCode\r
1135 //\r
1136 Status = ShellConvertStringToUint64(Walker, &Intermediate, FALSE, TRUE);\r
1137 if (EFI_ERROR(Status) || (((UINT16)Intermediate) != Intermediate) || StrStr(Walker, L" ") == NULL) {\r
ba0014b9 1138 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);\r
7b01f0f3
JC
1139 ShellStatus = SHELL_INVALID_PARAMETER;\r
1140 }\r
1141 ((EFI_INPUT_KEY*)(((UINT8*)KeyOptionBuffer) + sizeof(EFI_KEY_OPTION)))[LoopCounter].ScanCode = (UINT16)Intermediate;\r
1142 Temp = StrStr(Walker, L" ");\r
1143 if (Temp != NULL) {\r
1144 Walker = Temp;\r
1145 }\r
1146 while(Walker[0] == L' ') {\r
1147 Walker++;\r
1148 }\r
1149\r
1150 //\r
1151 // UnicodeChar\r
1152 //\r
1153 Status = ShellConvertStringToUint64(Walker, &Intermediate, FALSE, TRUE);\r
1154 if (EFI_ERROR(Status) || (((UINT16)Intermediate) != Intermediate)) {\r
ba0014b9 1155 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);\r
7b01f0f3
JC
1156 ShellStatus = SHELL_INVALID_PARAMETER;\r
1157 }\r
1158 ((EFI_INPUT_KEY*)(((UINT8*)KeyOptionBuffer) + sizeof(EFI_KEY_OPTION)))[LoopCounter].UnicodeChar = (UINT16)Intermediate;\r
1159 Temp = StrStr(Walker, L" ");\r
1160 if (Temp != NULL) {\r
1161 Walker = Temp;\r
1162 }\r
1163 while(Walker[0] == L' ') {\r
1164 Walker++;\r
1165 }\r
1166 }\r
1167\r
1168 if (ShellStatus == SHELL_SUCCESS) {\r
1169 //\r
1170 // Now do the BootOption / BootOptionCrc\r
1171 //\r
1172 ASSERT (OptionIndex <= OrderCount);\r
1173 KeyOptionBuffer->BootOption = CurrentOrder[OptionIndex];\r
1174 Status = GetBootOptionCrc(&(KeyOptionBuffer->BootOptionCrc), KeyOptionBuffer->BootOption);\r
1175 if (EFI_ERROR(Status)) {\r
ba0014b9 1176 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Option Index");\r
7b01f0f3 1177 ShellStatus = SHELL_INVALID_PARAMETER;\r
ba0014b9 1178 }\r
7b01f0f3
JC
1179 }\r
1180\r
1181 if (ShellStatus == SHELL_SUCCESS) {\r
77eef0d5 1182 for (Temp2 = NULL, KeyIndex = 0 ; KeyIndex <= 0xFFFF ; KeyIndex++) {\r
7b01f0f3 1183 UnicodeSPrint(VariableName, sizeof(VariableName), L"Key%04x", KeyIndex);\r
77eef0d5 1184 Status = GetEfiGlobalVariable2 (VariableName, &VariableData, NULL);\r
7b01f0f3
JC
1185 if (Status == EFI_NOT_FOUND) {\r
1186 break;\r
1187 }\r
77eef0d5
QS
1188 if (!EFI_ERROR(Status)) {\r
1189 SHELL_FREE_NON_NULL(VariableData);\r
1190 }\r
7b01f0f3 1191 }\r
77eef0d5
QS
1192 if (KeyIndex <= 0xFFFF) {\r
1193 Status = gRT->SetVariable(\r
1194 VariableName,\r
1195 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
1196 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
1197 sizeof(EFI_KEY_OPTION) + (sizeof(EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount),\r
1198 KeyOptionBuffer);\r
1199 if (EFI_ERROR(Status)) {\r
ba0014b9 1200 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);\r
77eef0d5 1201 ShellStatus = SHELL_INVALID_PARAMETER;\r
ba0014b9 1202 }\r
77eef0d5 1203 } else {\r
ba0014b9 1204 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_VAR_NO_NUM), gShellBcfgHiiHandle, L"bcfg");\r
7b01f0f3 1205 ShellStatus = SHELL_INVALID_PARAMETER;\r
77eef0d5 1206 }\r
7b01f0f3
JC
1207 ASSERT(FileName == NULL && Data == NULL);\r
1208 }\r
1209 }\r
1210 }\r
1211\r
1212 //\r
1213 // Shouldn't be possible to have have both. Neither is ok though.\r
1214 //\r
1215 ASSERT(FileName == NULL || Data == NULL);\r
1216\r
1217 if (ShellStatus == SHELL_SUCCESS && (FileName != NULL || Data != NULL)) {\r
1218 if (FileName != NULL) {\r
1219 //\r
1220 // Open the file and populate the data buffer.\r
1221 //\r
1222 Status = ShellOpenFileByName(\r
1223 FileName,\r
1224 &FileHandle,\r
1225 EFI_FILE_MODE_READ,\r
1226 0);\r
1227 if (!EFI_ERROR(Status)) {\r
1228 Status = ShellGetFileSize(FileHandle, &Intermediate);\r
1229 }\r
1230 Data = AllocateZeroPool((UINTN)Intermediate);\r
1231 if (Data == NULL) {\r
ba0014b9 1232 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");\r
7b01f0f3
JC
1233 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
1234 }\r
1235 if (!EFI_ERROR(Status)) {\r
1236 Status = ShellReadFile(FileHandle, (UINTN *)&Intermediate, Data);\r
1237 }\r
1238 } else {\r
1239 Intermediate = StrSize(Data);\r
1240 }\r
1241\r
1242 if (!EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS && Data != NULL) {\r
1243 Status = UpdateOptionalData(CurrentOrder[OptionIndex], (UINTN)Intermediate, (UINT8*)Data, Target);\r
1244 if (EFI_ERROR(Status)) {\r
ba0014b9 1245 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);\r
7b01f0f3 1246 ShellStatus = SHELL_INVALID_PARAMETER;\r
ba0014b9 1247 }\r
7b01f0f3
JC
1248 }\r
1249 if (EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS) {\r
ba0014b9 1250 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);\r
7b01f0f3 1251 ShellStatus = SHELL_INVALID_PARAMETER;\r
ba0014b9 1252 }\r
7b01f0f3
JC
1253 }\r
1254\r
1255 SHELL_FREE_NON_NULL(Data);\r
1256 SHELL_FREE_NON_NULL(KeyOptionBuffer);\r
1257 SHELL_FREE_NON_NULL(FileName);\r
1258 return ShellStatus;\r
1259}\r
1260\r
1261/**\r
1262 Function to dump the Bcfg information.\r
1263\r
1264 @param[in] Op The operation.\r
1265 @param[in] OrderCount How many to dump.\r
1266 @param[in] CurrentOrder The pointer to the current order of items.\r
1267 @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.\r
1268\r
1269 @retval SHELL_SUCCESS The dump was successful.\r
1270 @retval SHELL_INVALID_PARAMETER A parameter was invalid.\r
1271**/\r
1272SHELL_STATUS\r
7b01f0f3
JC
1273BcfgDisplayDump(\r
1274 IN CONST CHAR16 *Op,\r
1275 IN CONST UINTN OrderCount,\r
1276 IN CONST UINT16 *CurrentOrder,\r
1277 IN CONST BOOLEAN VerboseOutput\r
1278 )\r
1279{\r
15f8a738
LE
1280 EFI_STATUS Status;\r
1281 UINT8 *Buffer;\r
1282 UINTN BufferSize;\r
1283 CHAR16 VariableName[12];\r
1284 UINTN LoopVar;\r
15f8a738 1285 CHAR16 *DevPathString;\r
40de6483 1286 VOID *FilePathList;\r
8f2c09f8 1287 UINTN Errors;\r
e5945ef7 1288 EFI_LOAD_OPTION *LoadOption;\r
5dc03ade
LE
1289 CHAR16 *Description;\r
1290 UINTN DescriptionSize;\r
5a5a6590 1291 UINTN OptionalDataOffset;\r
7b01f0f3
JC
1292\r
1293 if (OrderCount == 0) {\r
ba0014b9 1294 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_BCFG_NONE), gShellBcfgHiiHandle, L"bcfg");\r
7b01f0f3
JC
1295 return (SHELL_SUCCESS);\r
1296 }\r
1297\r
8f2c09f8
LE
1298 Errors = 0;\r
1299\r
7b01f0f3 1300 for (LoopVar = 0 ; LoopVar < OrderCount ; LoopVar++) {\r
15f8a738
LE
1301 Buffer = NULL;\r
1302 BufferSize = 0;\r
43da602c
LE
1303 DevPathString = NULL;\r
1304\r
7b01f0f3
JC
1305 UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Op, CurrentOrder[LoopVar]);\r
1306\r
1307 Status = gRT->GetVariable(\r
1308 VariableName,\r
1309 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
1310 NULL,\r
1311 &BufferSize,\r
1312 Buffer);\r
1313 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1314 Buffer = AllocateZeroPool(BufferSize);\r
1315 Status = gRT->GetVariable(\r
1316 VariableName,\r
1317 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
1318 NULL,\r
1319 &BufferSize,\r
1320 Buffer);\r
1321 }\r
1322\r
1323 if (EFI_ERROR(Status) || Buffer == NULL) {\r
ba0014b9 1324 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_READ_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);\r
8f2c09f8
LE
1325 ++Errors;\r
1326 goto Cleanup;\r
7b01f0f3
JC
1327 }\r
1328\r
e5945ef7
LE
1329 //\r
1330 // We expect the Attributes, FilePathListLength, and L'\0'-terminated\r
1331 // Description fields to be present.\r
1332 //\r
1333 if (BufferSize < sizeof *LoadOption + sizeof (CHAR16)) {\r
1334 ShellPrintHiiEx (\r
1335 -1,\r
1336 -1,\r
1337 NULL,\r
1338 STRING_TOKEN (STR_BCFG_VAR_CORRUPT),\r
1339 gShellBcfgHiiHandle,\r
1340 L"bcfg",\r
1341 VariableName\r
1342 );\r
1343 ++Errors;\r
1344 goto Cleanup;\r
1345 }\r
5dc03ade
LE
1346\r
1347 LoadOption = (EFI_LOAD_OPTION *)Buffer;\r
aed8c66d 1348 Description = (CHAR16*)(Buffer + sizeof (EFI_LOAD_OPTION));\r
5dc03ade 1349 DescriptionSize = StrSize (Description);\r
e5945ef7 1350\r
3b6b1105 1351 if (LoadOption->FilePathListLength != 0) {\r
40de6483
LE
1352 FilePathList = (UINT8 *)Description + DescriptionSize;\r
1353 DevPathString = ConvertDevicePathToText(FilePathList, TRUE, FALSE);\r
7b01f0f3 1354 }\r
5a5a6590
LE
1355\r
1356 OptionalDataOffset = sizeof *LoadOption + DescriptionSize +\r
1357 LoadOption->FilePathListLength;\r
1358\r
7b01f0f3
JC
1359 ShellPrintHiiEx(\r
1360 -1,\r
1361 -1,\r
1362 NULL,\r
1363 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS),\r
1364 gShellBcfgHiiHandle,\r
1365 LoopVar,\r
1366 VariableName,\r
5dc03ade 1367 Description,\r
7b01f0f3 1368 DevPathString,\r
89896253 1369 OptionalDataOffset >= BufferSize ? L'N' : L'Y'\r
5a5a6590 1370 );\r
2de293cd
LE
1371 if (VerboseOutput && (OptionalDataOffset < BufferSize)) {\r
1372 DumpHex (\r
1373 2, // Indent\r
1374 0, // Offset (displayed)\r
1375 BufferSize - OptionalDataOffset, // DataSize\r
1376 Buffer + OptionalDataOffset // UserData\r
1377 );\r
7b01f0f3
JC
1378 }\r
1379\r
8f2c09f8 1380Cleanup:\r
7b01f0f3
JC
1381 if (Buffer != NULL) {\r
1382 FreePool(Buffer);\r
1383 }\r
7b01f0f3
JC
1384 if (DevPathString != NULL) {\r
1385 FreePool(DevPathString);\r
1386 }\r
1387 }\r
8f2c09f8 1388 return (Errors > 0) ? SHELL_INVALID_PARAMETER : SHELL_SUCCESS;\r
7b01f0f3
JC
1389}\r
1390\r
1391/**\r
1392 Function to initialize the BCFG operation structure.\r
1393\r
1394 @param[in] Struct The stuct to initialize.\r
1395**/\r
1396VOID\r
7b01f0f3
JC
1397InitBcfgStruct(\r
1398 IN BGFG_OPERATION *Struct\r
1399 )\r
1400{\r
1401 ASSERT(Struct != NULL);\r
1402 Struct->Target = BcfgTargetMax;\r
1403 Struct->Type = BcfgTypeMax;\r
1404 Struct->Number1 = 0;\r
1405 Struct->Number2 = 0;\r
1406 Struct->HandleIndex = 0;\r
1407 Struct->FileName = NULL;\r
1408 Struct->Description = NULL;\r
1409 Struct->Order = NULL;\r
1410 Struct->OptData = NULL;\r
1411}\r
1412\r
1413\r
1414STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
1415 {L"-v", TypeFlag},\r
1416 {L"-opt", TypeMaxValue},\r
1417 {NULL, TypeMax}\r
1418 };\r
1419\r
1420/**\r
1421 Function for 'bcfg' command.\r
1422\r
1423 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
1424 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
1425**/\r
1426SHELL_STATUS\r
1427EFIAPI\r
1428ShellCommandRunBcfg (\r
1429 IN EFI_HANDLE ImageHandle,\r
1430 IN EFI_SYSTEM_TABLE *SystemTable\r
1431 )\r
1432{\r
1433 EFI_STATUS Status;\r
1434 LIST_ENTRY *Package;\r
1435 CHAR16 *ProblemParam;\r
1436 SHELL_STATUS ShellStatus;\r
1437 UINTN ParamNumber;\r
1438 CONST CHAR16 *CurrentParam;\r
1439 BGFG_OPERATION CurrentOperation;\r
1440 UINTN Length;\r
1441 UINT64 Intermediate;\r
1442 UINT16 Count;\r
1443\r
1444 Length = 0;\r
1445 ProblemParam = NULL;\r
1446 Package = NULL;\r
1447 ShellStatus = SHELL_SUCCESS;\r
1448\r
1449 InitBcfgStruct(&CurrentOperation);\r
1450\r
1451 //\r
1452 // initialize the shell lib (we must be in non-auto-init...)\r
1453 //\r
1454 Status = ShellInitialize();\r
1455 ASSERT_EFI_ERROR(Status);\r
1456\r
1457 Status = CommandInit();\r
1458 ASSERT_EFI_ERROR(Status);\r
1459\r
1460 //\r
1461 // parse the command line\r
1462 //\r
1463 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
1464 if (EFI_ERROR(Status)) {\r
1465 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
ba0014b9 1466 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellBcfgHiiHandle, L"bcfg", ProblemParam);\r
7b01f0f3
JC
1467 FreePool(ProblemParam);\r
1468 ShellStatus = SHELL_INVALID_PARAMETER;\r
1469 } else {\r
1470 ASSERT(FALSE);\r
1471 }\r
1472 } else {\r
1473 //\r
1474 // Read in if we are doing -OPT\r
1475 //\r
1476 if (ShellCommandLineGetFlag(Package, L"-opt")) {\r
1477 CurrentOperation.OptData = ShellCommandLineGetValue(Package, L"-opt");\r
1478 if (CurrentOperation.OptData == NULL) {\r
ba0014b9 1479 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellBcfgHiiHandle, L"bcfg", L"-opt");\r
7b01f0f3
JC
1480 ShellStatus = SHELL_INVALID_PARAMETER;\r
1481 }\r
1482 CurrentOperation.Type = BcfgTypeOpt;\r
1483 }\r
1484\r
1485 //\r
1486 // small block to read the target of the operation\r
1487 //\r
1488 if ((ShellCommandLineGetCount(Package) < 3 && CurrentOperation.Type != BcfgTypeOpt) ||\r
1489 (ShellCommandLineGetCount(Package) < 2 && CurrentOperation.Type == BcfgTypeOpt)\r
1490 ){\r
ba0014b9 1491 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
7b01f0f3
JC
1492 ShellStatus = SHELL_INVALID_PARAMETER;\r
1493 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"driver") == 0) {\r
1494 CurrentOperation.Target = BcfgTargetDriverOrder;\r
1495 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"boot") == 0) {\r
1496 CurrentOperation.Target = BcfgTargetBootOrder;\r
1497 } else {\r
ba0014b9 1498 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT), gShellBcfgHiiHandle, L"bcfg");\r
7b01f0f3
JC
1499 ShellStatus = SHELL_INVALID_PARAMETER;\r
1500 }\r
1501\r
1502\r
1503 //\r
1504 // Read in the boot or driver order environment variable (not needed for opt)\r
1505 //\r
1506 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BcfgTargetMax) {\r
1507 Length = 0;\r
1508 Status = gRT->GetVariable(\r
1509 CurrentOperation.Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
1510 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
1511 NULL,\r
1512 &Length,\r
1513 CurrentOperation.Order);\r
1514 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1515 CurrentOperation.Order = AllocateZeroPool(Length+(4*sizeof(CurrentOperation.Order[0])));\r
1516 if (CurrentOperation.Order == NULL) {\r
1517 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
1518 } else {\r
1519 Status = gRT->GetVariable(\r
1520 CurrentOperation.Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
1521 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
1522 NULL,\r
1523 &Length,\r
1524 CurrentOperation.Order);\r
1525 }\r
1526 }\r
1527 }\r
1528\r
1529 Count = (UINT16) (Length / sizeof(CurrentOperation.Order[0]));\r
1530\r
1531 //\r
1532 // large block to read the type of operation and verify parameter types for the info.\r
1533 //\r
1534 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BcfgTargetMax) {\r
1535 for (ParamNumber = 2 ; ParamNumber < ShellCommandLineGetCount(Package) && ShellStatus == SHELL_SUCCESS; ParamNumber++) {\r
1536 CurrentParam = ShellCommandLineGetRawValue(Package, ParamNumber);\r
1537 if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"dump") == 0) {\r
1538 CurrentOperation.Type = BcfgTypeDump;\r
d653d806
DB
1539 if (ShellCommandLineGetCount(Package) > 3) {\r
1540 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellBcfgHiiHandle, L"bcfg");\r
1541 ShellStatus = SHELL_INVALID_PARAMETER;\r
1542 }\r
7b01f0f3 1543 } else if (ShellCommandLineGetFlag(Package, L"-v")) {\r
ba0014b9 1544 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"-v (without dump)");\r
7b01f0f3
JC
1545 ShellStatus = SHELL_INVALID_PARAMETER;\r
1546 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"add") == 0) {\r
1547 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {\r
ba0014b9 1548 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
7b01f0f3
JC
1549 ShellStatus = SHELL_INVALID_PARAMETER;\r
1550 }\r
1551 CurrentOperation.Type = BcfgTypeAdd;\r
1552 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
1553 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
ba0014b9 1554 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
7b01f0f3
JC
1555 ShellStatus = SHELL_INVALID_PARAMETER;\r
1556 } else {\r
1557 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);\r
1558 CurrentOperation.Number1 = (UINT16)Intermediate;\r
1559 ASSERT(CurrentOperation.FileName == NULL);\r
1560 CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
1561 ASSERT(CurrentOperation.Description == NULL);\r
1562 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
1563 }\r
1564 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addp") == 0) {\r
1565 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {\r
ba0014b9 1566 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
7b01f0f3
JC
1567 ShellStatus = SHELL_INVALID_PARAMETER;\r
1568 }\r
1569 CurrentOperation.Type = BcfgTypeAddp;\r
1570 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
1571 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
ba0014b9 1572 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
7b01f0f3
JC
1573 ShellStatus = SHELL_INVALID_PARAMETER;\r
1574 } else {\r
1575 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);\r
1576 CurrentOperation.Number1 = (UINT16)Intermediate;\r
1577 ASSERT(CurrentOperation.FileName == NULL);\r
1578 CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
1579 ASSERT(CurrentOperation.Description == NULL);\r
1580 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
1581 }\r
1582 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addh") == 0) {\r
1583 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {\r
ba0014b9 1584 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
7b01f0f3
JC
1585 ShellStatus = SHELL_INVALID_PARAMETER;\r
1586 }\r
1587 CurrentOperation.Type = BcfgTypeAddh;\r
1588 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
1589 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
ba0014b9 1590 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
7b01f0f3
JC
1591 ShellStatus = SHELL_INVALID_PARAMETER;\r
1592 } else {\r
1593 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);\r
1594 CurrentOperation.Number1 = (UINT16)Intermediate;\r
1595 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
1596 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
ba0014b9 1597 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
7b01f0f3
JC
1598 ShellStatus = SHELL_INVALID_PARAMETER;\r
1599 } else {\r
1600 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);\r
1601 CurrentOperation.HandleIndex = (UINT16)Intermediate;\r
1602 ASSERT(CurrentOperation.Description == NULL);\r
1603 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
1604 }\r
1605 }\r
1606 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"rm") == 0) {\r
1607 if ((ParamNumber + 1) >= ShellCommandLineGetCount(Package)) {\r
ba0014b9 1608 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
7b01f0f3
JC
1609 ShellStatus = SHELL_INVALID_PARAMETER;\r
1610 }\r
1611 CurrentOperation.Type = BcfgTypeRm;\r
1612 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
1613 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
ba0014b9 1614 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
7b01f0f3
JC
1615 ShellStatus = SHELL_INVALID_PARAMETER;\r
1616 } else {\r
1617 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);\r
1618 CurrentOperation.Number1 = (UINT16)Intermediate;\r
cfffccd9 1619 if (CurrentOperation.Number1 >= Count){\r
ba0014b9 1620 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);\r
7b01f0f3
JC
1621 ShellStatus = SHELL_INVALID_PARAMETER;\r
1622 }\r
1623 }\r
1624 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"mv") == 0) {\r
1625 if ((ParamNumber + 2) >= ShellCommandLineGetCount(Package)) {\r
ba0014b9 1626 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
7b01f0f3
JC
1627 ShellStatus = SHELL_INVALID_PARAMETER;\r
1628 }\r
1629 CurrentOperation.Type = BcfgTypeMv;\r
1630 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
1631 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
ba0014b9 1632 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
7b01f0f3
JC
1633 ShellStatus = SHELL_INVALID_PARAMETER;\r
1634 } else {\r
1635 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);\r
1636 CurrentOperation.Number1 = (UINT16)Intermediate;\r
cfffccd9 1637 if (CurrentOperation.Number1 >= Count){\r
ba0014b9 1638 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);\r
7b01f0f3
JC
1639 ShellStatus = SHELL_INVALID_PARAMETER;\r
1640 } else {\r
1641 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
1642 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
ba0014b9 1643 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
7b01f0f3
JC
1644 ShellStatus = SHELL_INVALID_PARAMETER;\r
1645 } else {\r
1646 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);\r
1647 CurrentOperation.Number2 = (UINT16)Intermediate;\r
1648 }\r
1649 if (CurrentOperation.Number2 == CurrentOperation.Number1\r
1650 ||CurrentOperation.Number2 >= Count\r
1651 ){\r
ba0014b9 1652 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);\r
7b01f0f3
JC
1653 ShellStatus = SHELL_INVALID_PARAMETER;\r
1654 }\r
1655 }\r
1656 }\r
5ab97a64
CC
1657 }\r
1658 else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16*)CurrentParam, L"mod") == 0) {\r
1659 if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {\r
1660 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
1661 ShellStatus = SHELL_INVALID_PARAMETER;\r
1662 } else {\r
1663 CurrentOperation.Type = BcfgTypeMod;\r
1664 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);\r
1665 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {\r
1666 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
1667 ShellStatus = SHELL_INVALID_PARAMETER;\r
1668 } else {\r
1669 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);\r
1670 CurrentOperation.Number1 = (UINT16)Intermediate;\r
1671 if (CurrentOperation.Number1 >= Count) {\r
1672 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);\r
1673 ShellStatus = SHELL_INVALID_PARAMETER;\r
1674 } else {\r
1675 ASSERT (CurrentOperation.Description == NULL);\r
1676 CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);\r
1677 }\r
1678 }\r
1679 }\r
1680 } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16*)CurrentParam, L"modf") == 0) {\r
1681 if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {\r
1682 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
1683 ShellStatus = SHELL_INVALID_PARAMETER;\r
1684 } else {\r
1685 CurrentOperation.Type = BcfgTypeModf;\r
1686 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);\r
1687 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {\r
1688 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
1689 ShellStatus = SHELL_INVALID_PARAMETER;\r
1690 } else {\r
1691 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);\r
1692 CurrentOperation.Number1 = (UINT16)Intermediate;\r
1693 if (CurrentOperation.Number1 >= Count) {\r
1694 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);\r
1695 ShellStatus = SHELL_INVALID_PARAMETER;\r
1696 } else {\r
1697 ASSERT (CurrentOperation.FileName == NULL);\r
1698 CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);\r
1699 }\r
1700 }\r
1701 }\r
1702 } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16*)CurrentParam, L"modp") == 0) {\r
1703 if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {\r
1704 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
1705 ShellStatus = SHELL_INVALID_PARAMETER;\r
1706 } else {\r
1707 CurrentOperation.Type = BcfgTypeModp;\r
1708 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);\r
1709 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {\r
1710 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
1711 ShellStatus = SHELL_INVALID_PARAMETER;\r
1712 } else {\r
1713 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);\r
1714 CurrentOperation.Number1 = (UINT16)Intermediate;\r
1715 if (CurrentOperation.Number1 >= Count) {\r
1716 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);\r
1717 ShellStatus = SHELL_INVALID_PARAMETER;\r
1718 } else {\r
1719 ASSERT (CurrentOperation.FileName == NULL);\r
1720 CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);\r
1721 }\r
1722 }\r
1723 }\r
1724 } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16*)CurrentParam, L"modh") == 0) {\r
1725 if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {\r
1726 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
1727 ShellStatus = SHELL_INVALID_PARAMETER;\r
1728 } else {\r
1729 CurrentOperation.Type = BcfgTypeModh;\r
1730 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);\r
1731 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {\r
1732 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
1733 ShellStatus = SHELL_INVALID_PARAMETER;\r
1734 }\r
1735 else {\r
1736 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);\r
1737 CurrentOperation.Number1 = (UINT16)Intermediate;\r
1738 if (CurrentOperation.Number1 >= Count) {\r
1739 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);\r
1740 ShellStatus = SHELL_INVALID_PARAMETER;\r
1741 } else {\r
1742 CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);\r
1743 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {\r
1744 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
1745 ShellStatus = SHELL_INVALID_PARAMETER;\r
1746 } else {\r
1747 Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);\r
1748 CurrentOperation.HandleIndex = (UINT16)Intermediate;\r
1749 }\r
1750 }\r
1751 }\r
1752 }\r
7b01f0f3 1753 } else {\r
ba0014b9 1754 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
7b01f0f3
JC
1755 ShellStatus = SHELL_INVALID_PARAMETER;\r
1756 }\r
1757 }\r
1758 }\r
1759 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BcfgTargetMax && CurrentOperation.Type < BcfgTypeMax) {\r
1760 //\r
1761 // we have all the info. Do the work\r
1762 //\r
1763 switch (CurrentOperation.Type) {\r
1764 case BcfgTypeDump:\r
1765 ShellStatus = BcfgDisplayDump(\r
1766 CurrentOperation.Target == BcfgTargetBootOrder?L"Boot":L"Driver",\r
1767 Count,\r
1768 CurrentOperation.Order,\r
1769 ShellCommandLineGetFlag(Package, L"-v"));\r
1770 break;\r
1771 case BcfgTypeMv:\r
1772 ShellStatus = BcfgMove(\r
1773 CurrentOperation.Target,\r
1774 CurrentOperation.Order,\r
1775 Count,\r
1776 CurrentOperation.Number1,\r
1777 CurrentOperation.Number2);\r
1778 break;\r
1779 case BcfgTypeRm:\r
1780 ShellStatus = BcfgRemove(\r
1781 CurrentOperation.Target,\r
1782 CurrentOperation.Order,\r
1783 Count,\r
1784 CurrentOperation.Number1);\r
1785 break;\r
1786 case BcfgTypeAdd:\r
1787 case BcfgTypeAddp:\r
1788 case BcfgTypeAddh:\r
1789 ShellStatus = BcfgAdd(\r
1790 CurrentOperation.Number1,\r
1791 CurrentOperation.FileName,\r
1792 CurrentOperation.Description==NULL?L"":CurrentOperation.Description,\r
1793 CurrentOperation.Order,\r
1794 Count,\r
1795 CurrentOperation.Target,\r
1796 (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddh),\r
1797 (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddp),\r
1798 CurrentOperation.HandleIndex);\r
1799 break;\r
5ab97a64
CC
1800 case BcfgTypeMod:\r
1801 case BcfgTypeModf:\r
1802 case BcfgTypeModp:\r
1803 case BcfgTypeModh:\r
1804 ShellStatus = BcfgMod (&CurrentOperation, Count);\r
1805 break;\r
7b01f0f3
JC
1806 case BcfgTypeOpt:\r
1807 ShellStatus = BcfgAddOpt(\r
1808 CurrentOperation.OptData,\r
1809 CurrentOperation.Order,\r
1810 Count,\r
1811 CurrentOperation.Target);\r
1812 break;\r
1813 default:\r
1814 ASSERT(FALSE);\r
1815 }\r
1816 }\r
1817 }\r
1818\r
1819 if (Package != NULL) {\r
1820 ShellCommandLineFreeVarList (Package);\r
1821 }\r
1822 if (CurrentOperation.FileName != NULL) {\r
1823 FreePool(CurrentOperation.FileName);\r
1824 }\r
1825 if (CurrentOperation.Description != NULL) {\r
1826 FreePool(CurrentOperation.Description);\r
1827 }\r
1828 if (CurrentOperation.Order != NULL) {\r
1829 FreePool(CurrentOperation.Order);\r
1830 }\r
1831\r
1832 return (ShellStatus);\r
1833}\r
1834\r
1835\r
1836/**\r
1837 Function to get the filename with help context if HII will not be used.\r
1838\r
1839 @return The filename with help text in it.\r
1840**/\r
1841CONST CHAR16*\r
1842EFIAPI\r
1843ShellCommandGetManFileNameBcfg (\r
1844 VOID\r
1845 )\r
1846{\r
1847 return (mFileName);\r
1848}\r
1849\r
1850/**\r
1851 "Constructor" for the library.\r
1852\r
1853 This will register the handler for the bcfg command.\r
1854\r
1855 @param[in] ImageHandle the image handle of the process\r
1856 @param[in] SystemTable the EFI System Table pointer\r
1857 @param[in] Name the profile name to use\r
1858\r
1859 @retval EFI_SUCCESS the shell command handlers were installed sucessfully\r
1860 @retval EFI_UNSUPPORTED the shell level required was not found.\r
1861**/\r
1862EFI_STATUS\r
1863EFIAPI\r
1864BcfgLibraryRegisterBcfgCommand (\r
1865 IN EFI_HANDLE ImageHandle,\r
1866 IN EFI_SYSTEM_TABLE *SystemTable,\r
1867 IN CONST CHAR16 *Name\r
1868 )\r
1869{\r
926be9d1 1870 if (gShellBcfgHiiHandle != NULL) {\r
7b01f0f3
JC
1871 return (EFI_SUCCESS);\r
1872 }\r
1873\r
1874 gShellBcfgHiiHandle = HiiAddPackages (&gShellBcfgHiiGuid, gImageHandle, UefiShellBcfgCommandLibStrings, NULL);\r
1875 if (gShellBcfgHiiHandle == NULL) {\r
1876 return (EFI_DEVICE_ERROR);\r
1877 }\r
1878\r
1879 //\r
1880 // install our shell command handler\r
1881 //\r
1882 ShellCommandRegisterCommandName(L"bcfg", ShellCommandRunBcfg , ShellCommandGetManFileNameBcfg, 0, Name, FALSE, gShellBcfgHiiHandle, STRING_TOKEN(STR_GET_HELP_BCFG));\r
1883\r
1884 return (EFI_SUCCESS);\r
1885}\r
1886\r
1887/**\r
1888 Destructor for the library. free any resources.\r
1889\r
1890 @param ImageHandle The image handle of the process.\r
1891 @param SystemTable The EFI System Table pointer.\r
1892**/\r
1893EFI_STATUS\r
1894EFIAPI\r
1895BcfgLibraryUnregisterBcfgCommand (\r
1896 IN EFI_HANDLE ImageHandle,\r
1897 IN EFI_SYSTEM_TABLE *SystemTable\r
1898 )\r
1899{\r
1900 if (gShellBcfgHiiHandle != NULL) {\r
1901 HiiRemovePackages(gShellBcfgHiiHandle);\r
1902 }\r
1903 gShellBcfgHiiHandle = NULL;\r
1904 return (EFI_SUCCESS);\r
1905}\r
1906\r