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