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