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