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