]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellInstall1CommandsLib/Bcfg.c
adding "Install1" profile.
[mirror_edk2.git] / ShellPkg / Library / UefiShellInstall1CommandsLib / Bcfg.c
CommitLineData
75aadf59 1/** @file\r
2 Main file for bcfg shell install1 function.\r
3\r
4 Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "UefiShellInstall1CommandsLib.h"\r
16#include <Guid/GlobalVariable.h>\r
17#include <Library/PrintLib.h>\r
18#include <Library/HandleParsingLib.h>\r
19#include <Library/DevicePathLib.h>\r
20\r
21typedef enum {\r
22 BCFG_TARGET_BOOT_ORDER = 0,\r
23 BCFG_TARGET_DRIVER_ORDER = 1,\r
24 BCFG_TARGET_MAX = 2\r
25} BCFG_OPERATION_TARGET;\r
26\r
27typedef enum {\r
28 BCFG_TYPE_DUMP = 0,\r
29 BCFG_TYPE_ADD = 1,\r
30 BCFG_TYPE_ADDP = 2,\r
31 BCFG_TYPE_ADDH = 3,\r
32 BCFG_TYPE_RM = 4,\r
33 BCFG_TYPE_MV = 5,\r
34 BCFG_TYPE_OPT = 6,\r
35 BCFG_TYPE_MAX = 7\r
36} BCFG_OPERATION_TYPE;\r
37\r
38typedef struct {\r
39 BCFG_OPERATION_TARGET Target;\r
40 BCFG_OPERATION_TYPE Type;\r
41 UINT16 Number1;\r
42 UINT16 Number2;\r
43 UINTN HandleIndex;\r
44 CHAR16 *FileName;\r
45 CHAR16 *Description;\r
46 UINT16 *Order;\r
47 CONST CHAR16 *OptData;\r
48} BGFG_OPERATION;\r
49\r
50/**\r
51 Function to update the optional data associated with an option.\r
52\r
53 @param[in] Target The type being modified. BOOT or DRIVER\r
54 @param[in] OptData The pointer to the data to modify with.\r
55\r
56 @retval SHELL_SUCCESS The optional data was updated sucessfully.\r
57**/\r
58SHELL_STATUS\r
59EFIAPI\r
60BcfgAddOptInstall(\r
61 IN CONST BCFG_OPERATION_TARGET Target,\r
62 IN CONST CHAR16 *OptData\r
63 )\r
64{\r
65 ShellPrintEx(-1, -1, L"use of -opt is not currently supported.");\r
66 return (SHELL_UNSUPPORTED);\r
67}\r
68\r
69/**\r
70 Function to add an option.\r
71\r
72 @param[in] Position The position to add this in at.\r
73 @param[in] File The file to add as the option.\r
74 @param[in] Desc The description.\r
75 @param[in] CurrentOrder The current order of that type.\r
76 @param[in] OrderCount The number of items in the current order.\r
77 @param[in] Target The type being modified. BOOT or DRIVER\r
78 @param[in] UseHandle Add something by a handle. Uses HandleNumber if TRUE and File if FALSE.\r
79 @param[in] UsePath Add something by local path. Only used of UseHandle is FALSE.\r
80 @param[in] HandleNumber The HandleIndex to use.\r
81\r
82 @retval SHELL_SUCCESS The option was added sucessfully.\r
83**/\r
84SHELL_STATUS\r
85EFIAPI\r
86BcfgAddInstall (\r
87 IN UINTN Position,\r
88 IN CONST CHAR16 *File,\r
89 IN CONST CHAR16 *Desc,\r
90 IN CONST UINT16 *CurrentOrder,\r
91 IN CONST UINTN OrderCount,\r
92 IN CONST BCFG_OPERATION_TARGET Target,\r
93 IN CONST BOOLEAN UseHandle,\r
94 IN CONST BOOLEAN UseFullPath,\r
95 IN CONST UINTN HandleNumber\r
96 )\r
97{\r
98 EFI_STATUS Status;\r
99 EFI_DEVICE_PATH_PROTOCOL *DevicePath, *FilePath, *FileNode;\r
100 CHAR16 *Str;\r
101 CONST CHAR16 *p;\r
102 UINT8 *p8;\r
103 UINT8 *p8Copy;\r
104 EFI_SHELL_FILE_INFO *Arg;\r
105 EFI_SHELL_FILE_INFO *FileList;\r
106 CHAR16 OptionStr[40];\r
107 UINTN DescSize, FilePathSize;\r
108 BOOLEAN Found;\r
109 UINTN TargetLocation;\r
110 UINTN Index;\r
111 EFI_HANDLE *Handles;\r
112 EFI_HANDLE CurHandle;\r
113 SHELL_STATUS ShellStatus;\r
114 UINT16 *NewOrder;\r
115 EFI_LOADED_IMAGE_PROTOCOL *Image;\r
116\r
117 if (!UseHandle) {\r
118 ASSERT(File != NULL);\r
119 ASSERT(Desc != NULL);\r
120 } else {\r
121 ASSERT(HandleNumber != 0);\r
122 }\r
123\r
124 Str = NULL;\r
125 FilePath = NULL;\r
126 FileNode = NULL;\r
127 FileList = NULL;\r
128 Handles = NULL;\r
129 ShellStatus = SHELL_SUCCESS;\r
130 TargetLocation = 0xFFFF;\r
131\r
132 if (UseHandle) {\r
133 CurHandle = ConvertHandleIndexToHandle(HandleNumber);\r
134 if (CurHandle == NULL) {\r
135 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, L"<HandleNumber>");\r
136 ShellStatus = SHELL_INVALID_PARAMETER;\r
137 } else {\r
138 FilePath = NULL;\r
139 Status = gBS->HandleProtocol (CurHandle, &gEfiLoadedImageDevicePathProtocolGuid, (VOID**)&FilePath);\r
140 if (EFI_ERROR (Status)) {\r
141 Status = EFI_SUCCESS;\r
142 //\r
143 // Try to construct the DevicePath\r
144 //\r
145 Status = gBS->OpenProtocol(CurHandle, &gEfiLoadedImageProtocolGuid, (VOID**)&Image, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
146 if (EFI_ERROR(Status)) {\r
147 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_HANDLE), gShellInstall1HiiHandle, HandleNumber);\r
148 ShellStatus = SHELL_INVALID_PARAMETER;\r
149 } else {\r
150 Status = gBS->HandleProtocol (Image->DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID**)&DevicePath);\r
151 if (EFI_ERROR(Status)) {\r
152 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_HANDLE), gShellInstall1HiiHandle, HandleNumber);\r
153 ShellStatus = SHELL_INVALID_PARAMETER;\r
154 } else {\r
155 FilePath = AppendDevicePath(DevicePath, Image->FilePath);\r
156 }\r
157 }\r
158 }\r
159 }\r
160 } else {\r
161 //\r
162 // Get file info\r
163 //\r
164 Status = ShellOpenFileMetaArg ((CHAR16*)File, EFI_FILE_MODE_READ, &FileList);\r
165 if (EFI_ERROR(Status)) {\r
166 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellInstall1HiiHandle, File);\r
167 ShellStatus = SHELL_NOT_FOUND;\r
168 } else if (FileList == NULL || FileList->Link.ForwardLink != FileList->Link.BackLink) {\r
169 //\r
170 // If filename expanded to multiple names, fail\r
171 //\r
172 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellInstall1HiiHandle, File);\r
173 ShellStatus = SHELL_INVALID_PARAMETER;\r
174 } else {\r
175 Arg = (EFI_SHELL_FILE_INFO*)GetFirstNode(&FileList->Link);\r
176 if (EFI_ERROR(Arg->Status)) {\r
177 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellInstall1HiiHandle, File, Arg->Status);\r
178 ShellStatus = SHELL_INVALID_PARAMETER;\r
179 } else {\r
180 //\r
181 // Build FilePath to the filename\r
182 //\r
183\r
184 //\r
185 // get the device path\r
186 //\r
187 DevicePath = mEfiShellProtocol->GetDevicePathFromFilePath(Arg->FullName);\r
188 if (DevicePath == NULL) {\r
189 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellInstall1HiiHandle, Arg->FullName);\r
190 ShellStatus = SHELL_UNSUPPORTED;\r
191 } else {\r
192 if (UseFullPath) {\r
193 FilePath = DuplicateDevicePath(DevicePath);\r
194 } else {\r
195 for(p=Arg->FullName; *p != CHAR_NULL && *p != ':'; p++);\r
196 FilePath = FileDevicePath(NULL, p+1);\r
197 }\r
198\r
199 FreePool(DevicePath);\r
200 }\r
201 }\r
202 }\r
203 }\r
204\r
205\r
206 if (ShellStatus == SHELL_SUCCESS) {\r
207 //\r
208 // Find a free target ,a brute force implementation\r
209 //\r
210 Found = FALSE;\r
211 for (TargetLocation=0; TargetLocation < 0xFFFF; TargetLocation++) {\r
212 Found = TRUE;\r
213 for (Index=0; Index < OrderCount; Index++) {\r
214 if (CurrentOrder[Index] == TargetLocation) {\r
215 Found = FALSE;\r
216 break;\r
217 }\r
218 }\r
219\r
220 if (Found) {\r
221 break;\r
222 }\r
223 }\r
224\r
225 if (TargetLocation == 0xFFFF) {\r
226 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET_NF), gShellInstall1HiiHandle);\r
227 } else {\r
228 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET), gShellInstall1HiiHandle, TargetLocation);\r
229 }\r
230 }\r
231\r
232 if (ShellStatus == SHELL_SUCCESS) {\r
233 //\r
234 // Add the option\r
235 //\r
236 DescSize = StrSize(Desc);\r
237 FilePathSize = GetDevicePathSize (FilePath);\r
238\r
239 p8 = AllocateZeroPool(sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize);\r
240 if (p8 != NULL) {\r
241 p8Copy = p8;\r
242 *((UINT32 *) p8) = LOAD_OPTION_ACTIVE; // Attributes\r
243 p8 += sizeof (UINT32);\r
244\r
245 *((UINT16 *) p8) = (UINT16)FilePathSize; // FilePathListLength\r
246 p8 += sizeof (UINT16);\r
247\r
248 CopyMem (p8, Desc, DescSize);\r
249 p8 += DescSize;\r
250 CopyMem (p8, FilePath, FilePathSize);\r
251\r
252 UnicodeSPrint (OptionStr, sizeof(OptionStr), L"%s%04x", Target == BCFG_TARGET_BOOT_ORDER?L"Boot":L"Driver", TargetLocation);\r
253 Status = gRT->SetVariable (\r
254 OptionStr,\r
255 &gEfiGlobalVariableGuid,\r
256 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
257 sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize,\r
258 p8Copy\r
259 );\r
260\r
261 FreePool(p8Copy);\r
262\r
263 if (EFI_ERROR(Status)) {\r
264 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellInstall1HiiHandle, OptionStr, Status);\r
265 } else {\r
266 NewOrder = AllocateZeroPool((OrderCount+1)*sizeof(UINT16));\r
267 ASSERT(NewOrder != NULL);\r
268 CopyMem(NewOrder, CurrentOrder, (OrderCount)*sizeof(UINT16));\r
269\r
270 //\r
271 // Insert target into order list\r
272 //\r
273 for (Index=OrderCount; Index > Position; Index--) {\r
274 NewOrder[Index] = NewOrder[Index-1];\r
275 }\r
276\r
277 NewOrder[Index] = (UINT16)TargetLocation;\r
278 Status = gRT->SetVariable (\r
279 Target == BCFG_TARGET_BOOT_ORDER?L"BootOrder":L"DriverOrder",\r
280 &gEfiGlobalVariableGuid,\r
281 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
282 (OrderCount+1) * sizeof(UINT16),\r
283 NewOrder\r
284 );\r
285\r
286 FreePool(NewOrder);\r
287\r
288 if (EFI_ERROR(Status)) {\r
289 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, Target == BCFG_TARGET_BOOT_ORDER?L"BootOrder":L"DriverOrder", Status);\r
290 ShellStatus = SHELL_INVALID_PARAMETER;\r
291 } else {\r
292 ShellPrintEx (-1, -1, L"bcfg: Add %s as %x\n", OptionStr, Index);\r
293 }\r
294 }\r
295 } else {\r
296 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellInstall1HiiHandle);\r
297 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
298 }\r
299 }\r
300\r
301//\r
302//If always Free FilePath, will free devicepath in system when use "addh"\r
303//\r
304\r
305 if (FilePath!=NULL && !UseHandle) {\r
306 FreePool (FilePath);\r
307 }\r
308\r
309 if (Str != NULL) {\r
310 FreePool(Str);\r
311 }\r
312\r
313 if (Handles != NULL) {\r
314 FreePool (Handles);\r
315 }\r
316\r
317 if (FileList != NULL) {\r
318 ShellCloseFileMetaArg (&FileList);\r
319 }\r
320\r
321 return (ShellStatus);\r
322}\r
323\r
324SHELL_STATUS\r
325EFIAPI\r
326BcfgRemoveInstall(\r
327 IN CONST BCFG_OPERATION_TARGET Target,\r
328 IN CONST UINT16 *CurrentOrder,\r
329 IN CONST UINTN OrderCount,\r
330 IN CONST UINT16 Location\r
331 )\r
332{\r
333 CHAR16 VariableName[12];\r
334 UINT16 *NewOrder;\r
335 EFI_STATUS Status;\r
336\r
337 NewOrder = AllocatePool(OrderCount*sizeof(CurrentOrder[0]));\r
338 if (NewOrder == NULL) {\r
339 return (SHELL_OUT_OF_RESOURCES);\r
340 }\r
341\r
342 CopyMem(NewOrder, CurrentOrder, OrderCount*sizeof(CurrentOrder[0]));\r
343 CopyMem(NewOrder+Location, NewOrder+Location+1, (OrderCount - Location - 1)*sizeof(CurrentOrder[0]));\r
344\r
345 Status = gRT->SetVariable(\r
346 Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
347 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
348 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
349 (OrderCount-1)*sizeof(CurrentOrder[0]), // drop 1 off since the list is 1 shorter\r
350 NewOrder);\r
351\r
352 FreePool(NewOrder);\r
353\r
354 if (EFI_ERROR(Status)) {\r
355 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder", Status);\r
356 return (SHELL_INVALID_PARAMETER);\r
357 }\r
358\r
359 UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Target == BCFG_TARGET_BOOT_ORDER?L"Boot":L"Driver", CurrentOrder[Location]);\r
360 Status = gRT->SetVariable(\r
361 VariableName,\r
362 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
363 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
364 0,\r
365 NULL);\r
366 if (EFI_ERROR(Status)) {\r
367 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, VariableName, Status);\r
368 return (SHELL_INVALID_PARAMETER);\r
369 }\r
370\r
371 return (SHELL_SUCCESS);\r
372}\r
373\r
374SHELL_STATUS\r
375EFIAPI\r
376BcfgMoveInstall(\r
377 IN CONST BCFG_OPERATION_TARGET Target,\r
378 IN CONST UINT16 *CurrentOrder,\r
379 IN CONST UINTN OrderCount,\r
380 IN CONST UINT16 OldLocation,\r
381 IN CONST UINT16 NewLocation\r
382 )\r
383{\r
384 UINT16 *NewOrder;\r
385 EFI_STATUS Status;\r
386 UINT16 Temp;\r
387\r
388 NewOrder = AllocatePool(OrderCount*sizeof(CurrentOrder[0]));\r
389 ASSERT(NewOrder != NULL);\r
390\r
391 Temp = CurrentOrder[OldLocation];\r
392 CopyMem(NewOrder, CurrentOrder, OrderCount*sizeof(CurrentOrder[0]));\r
393 CopyMem(NewOrder+OldLocation, NewOrder+OldLocation+1, (OrderCount - OldLocation - 1)*sizeof(CurrentOrder[0]));\r
394 if (NewLocation == OrderCount) {\r
395 NewOrder[OrderCount-1] = Temp;\r
396 } else {\r
397 CopyMem(NewOrder+NewLocation+1, NewOrder+NewLocation, (OrderCount - NewLocation - 1)*sizeof(CurrentOrder[0]));\r
398 NewOrder[NewLocation] = Temp;\r
399 }\r
400\r
401\r
402 Status = gRT->SetVariable(\r
403 Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
404 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
405 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
406 OrderCount*sizeof(CurrentOrder[0]),\r
407 NewOrder);\r
408\r
409 FreePool(NewOrder);\r
410\r
411 if (EFI_ERROR(Status)) {\r
412 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder", Status);\r
413 return (SHELL_INVALID_PARAMETER);\r
414 }\r
415 return (SHELL_SUCCESS);\r
416}\r
417\r
418SHELL_STATUS\r
419EFIAPI\r
420BcfgDisplayDumpInstall(\r
421 IN CONST CHAR16 *Op,\r
422 IN CONST UINT16 *CurrentOrder,\r
423 IN CONST UINTN OrderCount,\r
424 IN CONST BOOLEAN VerboseOutput\r
425 )\r
426{\r
427 EFI_STATUS Status;\r
428 UINT8 *Buffer;\r
429 UINTN BufferSize;\r
430 CHAR16 VariableName[12];\r
431 UINTN LoopVar;\r
432 UINTN LoopVar2;\r
433 CHAR16 *DevPathString;\r
434 VOID *DevPath;\r
435\r
436 for (LoopVar = 0 ; LoopVar < OrderCount ; LoopVar++) {\r
437 Buffer = NULL;\r
438 BufferSize = 0;\r
439 UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Op, CurrentOrder[LoopVar]);\r
440\r
441 Status = gRT->GetVariable(\r
442 VariableName,\r
443 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
444 NULL,\r
445 &BufferSize,\r
446 Buffer);\r
447 if (Status == EFI_BUFFER_TOO_SMALL) {\r
448 Buffer = AllocatePool(BufferSize);\r
449 Status = gRT->GetVariable(\r
450 VariableName,\r
451 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
452 NULL,\r
453 &BufferSize,\r
454 Buffer);\r
455 }\r
456\r
457 if (EFI_ERROR(Status) || Buffer == NULL) {\r
458 SHELL_FREE_NON_NULL(Buffer);\r
459 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_READ_FAIL), gShellInstall1HiiHandle, VariableName, Status);\r
460 return (SHELL_INVALID_PARAMETER);\r
461 }\r
462\r
463 DevPath = AllocatePool(*(UINT16*)(Buffer+4));\r
464 CopyMem(DevPath, Buffer+6+StrSize((CHAR16*)(Buffer+6)), *(UINT16*)(Buffer+4));\r
465 DevPathString = gDevPathToText->ConvertDevicePathToText(DevPath, TRUE, FALSE);\r
466 ShellPrintHiiEx(\r
467 -1,\r
468 -1,\r
469 NULL,\r
470 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS),\r
471 gShellInstall1HiiHandle,\r
472 Op,\r
473 LoopVar,\r
474 (CHAR16*)(Buffer+6),\r
475 DevPathString,\r
476 (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6) <= BufferSize?L'N':L'Y');\r
477 if (VerboseOutput) {\r
478 for (LoopVar2 = (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6);LoopVar2<BufferSize;LoopVar2++){\r
479 ShellPrintEx(-1, -1, L"%02x", Buffer[LoopVar2]);\r
480 }\r
481 ShellPrintEx(-1, -1, L"\r\n");\r
482 }\r
483\r
484 if (Buffer != NULL) {\r
485 FreePool(Buffer);\r
486 }\r
487 if (DevPath != NULL) {\r
488 FreePool(DevPath);\r
489 }\r
490 if (DevPathString != NULL) {\r
491 FreePool(DevPathString);\r
492 }\r
493 }\r
494 return (SHELL_SUCCESS);\r
495}\r
496\r
497VOID\r
498EFIAPI\r
499InitBcfgStructInstall(\r
500 IN BGFG_OPERATION *Struct\r
501 )\r
502{\r
503 ASSERT(Struct != NULL);\r
504 Struct->Target = BCFG_TARGET_MAX;\r
505 Struct->Type = BCFG_TYPE_MAX;\r
506 Struct->Number1 = 0;\r
507 Struct->Number2 = 0;\r
508 Struct->HandleIndex = 0;\r
509 Struct->FileName = NULL;\r
510 Struct->Description = NULL;\r
511 Struct->Order = NULL;\r
512 Struct->OptData = NULL;\r
513}\r
514\r
515\r
516STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
517 {L"-v", TypeFlag},\r
518 {L"-opt", TypeMaxValue},\r
519 {NULL, TypeMax}\r
520 };\r
521\r
522/**\r
523 Function for 'bcfg' command.\r
524\r
525 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
526 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
527**/\r
528SHELL_STATUS\r
529EFIAPI\r
530ShellCommandRunBcfgInstall (\r
531 IN EFI_HANDLE ImageHandle,\r
532 IN EFI_SYSTEM_TABLE *SystemTable\r
533 )\r
534{\r
535 EFI_STATUS Status;\r
536 LIST_ENTRY *Package;\r
537 CHAR16 *ProblemParam;\r
538 SHELL_STATUS ShellStatus;\r
539 UINTN ParamNumber;\r
540 CONST CHAR16 *CurrentParam;\r
541 BGFG_OPERATION CurrentOperation;\r
542 UINTN Length;\r
543\r
544 Length = 0;\r
545 ProblemParam = NULL;\r
546 Package = NULL;\r
547 ShellStatus = SHELL_SUCCESS;\r
548\r
549 InitBcfgStructInstall(&CurrentOperation);\r
550\r
551 //\r
552 // initialize the shell lib (we must be in non-auto-init...)\r
553 //\r
554 Status = ShellInitialize();\r
555 ASSERT_EFI_ERROR(Status);\r
556\r
557 Status = CommandInit();\r
558 ASSERT_EFI_ERROR(Status);\r
559\r
560 //\r
561 // parse the command line\r
562 //\r
563 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
564 if (EFI_ERROR(Status)) {\r
565 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
566 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, ProblemParam);\r
567 FreePool(ProblemParam);\r
568 ShellStatus = SHELL_INVALID_PARAMETER;\r
569 } else {\r
570 ASSERT(FALSE);\r
571 }\r
572 } else {\r
573 //\r
574 // small block to read the target of the operation\r
575 //\r
576 if (ShellCommandLineGetFlag(Package, L"-opt") && ShellCommandLineGetCount(Package) < 2) {\r
577 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);\r
578 ShellStatus = SHELL_INVALID_PARAMETER;\r
579 } else if (!ShellCommandLineGetFlag(Package, L"-opt") && ShellCommandLineGetCount(Package) < 3) {\r
580 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);\r
581 ShellStatus = SHELL_INVALID_PARAMETER;\r
582 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"driver") == 0) {\r
583 CurrentOperation.Target = BCFG_TARGET_DRIVER_ORDER;\r
584 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"boot") == 0) {\r
585 CurrentOperation.Target = BCFG_TARGET_BOOT_ORDER;\r
586 } else {\r
587 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT), gShellInstall1HiiHandle);\r
588 ShellStatus = SHELL_INVALID_PARAMETER;\r
589 }\r
590\r
591 //\r
592 // Read in if we are doing -OPT\r
593 //\r
594 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BCFG_TARGET_MAX && ShellCommandLineGetFlag(Package, L"-opt")) {\r
595 CurrentOperation.OptData = ShellCommandLineGetValue(Package, L"-opt");\r
596 CurrentOperation.Type = BCFG_TYPE_OPT;\r
597 }\r
598\r
599 //\r
600 // Read in the boot or driver order environment variable (not needed for opt)\r
601 //\r
602 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BCFG_TARGET_MAX && CurrentOperation.Type != BCFG_TYPE_OPT) {\r
603 Length = 0;\r
604 Status = gRT->GetVariable(\r
605 CurrentOperation.Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
606 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
607 NULL,\r
608 &Length,\r
609 CurrentOperation.Order);\r
610 if (Status == EFI_BUFFER_TOO_SMALL) {\r
611 CurrentOperation.Order = AllocatePool(Length+(4*sizeof(CurrentOperation.Order[0])));\r
612 Status = gRT->GetVariable(\r
613 CurrentOperation.Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
614 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
615 NULL,\r
616 &Length,\r
617 CurrentOperation.Order);\r
618 }\r
619 }\r
620\r
621 //\r
622 // large block to read the type of operation and verify parameter types for the info.\r
623 //\r
624 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BCFG_TARGET_MAX) {\r
625 for (ParamNumber = 2 ; ParamNumber < ShellCommandLineGetCount(Package) && ShellStatus == SHELL_SUCCESS; ParamNumber++) {\r
626 CurrentParam = ShellCommandLineGetRawValue(Package, ParamNumber);\r
627 if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"dump") == 0) {\r
628 if (ShellCommandLineGetCount(Package) > 3) {\r
629 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellInstall1HiiHandle);\r
630 ShellStatus = SHELL_INVALID_PARAMETER;\r
631 }\r
632 CurrentOperation.Type = BCFG_TYPE_DUMP;\r
633 } else if (ShellCommandLineGetFlag(Package, L"-v")) {\r
634 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, L"-v (without dump)");\r
635 ShellStatus = SHELL_INVALID_PARAMETER;\r
636 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"add") == 0) {\r
637 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {\r
638 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);\r
639 ShellStatus = SHELL_INVALID_PARAMETER;\r
640 }\r
641 CurrentOperation.Type = BCFG_TYPE_ADD;\r
642 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
643 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
644 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
645 ShellStatus = SHELL_INVALID_PARAMETER;\r
646 } else {\r
647 CurrentOperation.Number1 = (UINT16)StrHexToUintn(CurrentParam);\r
648 ASSERT(CurrentOperation.FileName == NULL);\r
649 CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
650 ASSERT(CurrentOperation.Description == NULL);\r
651 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
652 }\r
653 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addp") == 0) {\r
654 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {\r
655 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);\r
656 ShellStatus = SHELL_INVALID_PARAMETER;\r
657 } else {\r
658 CurrentOperation.Type = BCFG_TYPE_ADDP;\r
659 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
660 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
661 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
662 ShellStatus = SHELL_INVALID_PARAMETER;\r
663 } else {\r
664 CurrentOperation.Number1 = (UINT16)StrHexToUintn(CurrentParam);\r
665 ASSERT(CurrentOperation.FileName == NULL);\r
666 CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
667 ASSERT(CurrentOperation.Description == NULL);\r
668 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
669 }\r
670 }\r
671 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addh") == 0) {\r
672 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {\r
673 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);\r
674 ShellStatus = SHELL_INVALID_PARAMETER;\r
675 }\r
676 CurrentOperation.Type = BCFG_TYPE_ADDH;\r
677 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
678 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
679 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
680 ShellStatus = SHELL_INVALID_PARAMETER;\r
681 } else {\r
682 CurrentOperation.Number1 = (UINT16)StrHexToUintn(CurrentParam);\r
683 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
684 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
685 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
686 ShellStatus = SHELL_INVALID_PARAMETER;\r
687 } else {\r
688 CurrentOperation.HandleIndex = (UINT16)StrHexToUintn(CurrentParam);\r
689 ASSERT(CurrentOperation.Description == NULL);\r
690 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
691 }\r
692 }\r
693 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"rm") == 0) {\r
694 if ((ParamNumber + 1) >= ShellCommandLineGetCount(Package)) {\r
695 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);\r
696 ShellStatus = SHELL_INVALID_PARAMETER;\r
697 }\r
698 CurrentOperation.Type = BCFG_TYPE_RM;\r
699 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
700 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
701 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
702 ShellStatus = SHELL_INVALID_PARAMETER;\r
703 } else {\r
704 CurrentOperation.Number1 = (UINT16)StrHexToUintn(CurrentParam);\r
705 if (CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))){\r
706 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_LOCATION_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));\r
707 ShellStatus = SHELL_INVALID_PARAMETER;\r
708 }\r
709 }\r
710 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"mv") == 0) {\r
711 if ((ParamNumber + 2) >= ShellCommandLineGetCount(Package)) {\r
712 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);\r
713 ShellStatus = SHELL_INVALID_PARAMETER;\r
714 }\r
715 CurrentOperation.Type = BCFG_TYPE_MV;\r
716 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
717 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
718 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
719 ShellStatus = SHELL_INVALID_PARAMETER;\r
720 } else {\r
721 CurrentOperation.Number1 = (UINT16)StrHexToUintn(CurrentParam);\r
722 if (CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))){\r
723 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_LOCATION_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));\r
724 ShellStatus = SHELL_INVALID_PARAMETER;\r
725 }\r
726 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
727 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
728 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
729 ShellStatus = SHELL_INVALID_PARAMETER;\r
730 } else {\r
731 CurrentOperation.Number2 = (UINT16)StrHexToUintn(CurrentParam);\r
732 }\r
733 if (CurrentOperation.Number2 == CurrentOperation.Number1\r
734 ||CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))\r
735 ||CurrentOperation.Number2 > (Length / sizeof(CurrentOperation.Order[0]))\r
736 ){\r
737 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_LOCATION_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));\r
738 ShellStatus = SHELL_INVALID_PARAMETER;\r
739 }\r
740 }\r
741 } else {\r
742 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
743 ShellStatus = SHELL_INVALID_PARAMETER;\r
744 }\r
745 }\r
746 }\r
747 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BCFG_TARGET_MAX && CurrentOperation.Type < BCFG_TYPE_MAX) {\r
748 //\r
749 // we have all the info. Do the work\r
750 //\r
751 switch (CurrentOperation.Type) {\r
752 case BCFG_TYPE_DUMP:\r
753 ShellStatus = BcfgDisplayDumpInstall(\r
754 CurrentOperation.Target == BCFG_TARGET_BOOT_ORDER?L"Boot":L"Driver",\r
755 CurrentOperation.Order,\r
756 Length / sizeof(CurrentOperation.Order[0]),\r
757 ShellCommandLineGetFlag(Package, L"-v"));\r
758 break;\r
759 case BCFG_TYPE_MV:\r
760 ShellStatus = BcfgMoveInstall(\r
761 CurrentOperation.Target,\r
762 CurrentOperation.Order,\r
763 Length / sizeof(CurrentOperation.Order[0]),\r
764 CurrentOperation.Number1,\r
765 CurrentOperation.Number2);\r
766 break;\r
767 case BCFG_TYPE_RM:\r
768 ShellStatus = BcfgRemoveInstall(\r
769 CurrentOperation.Target,\r
770 CurrentOperation.Order,\r
771 (Length / sizeof(CurrentOperation.Order[0])),\r
772 CurrentOperation.Number1);\r
773 break;\r
774 case BCFG_TYPE_ADD:\r
775 case BCFG_TYPE_ADDP:\r
776 case BCFG_TYPE_ADDH:\r
777 ShellStatus = BcfgAddInstall(\r
778 CurrentOperation.Number1,\r
779 CurrentOperation.FileName,\r
780 CurrentOperation.Description,\r
781 CurrentOperation.Order,\r
782 Length / sizeof(CurrentOperation.Order[0]),\r
783 CurrentOperation.Target,\r
784 (BOOLEAN)(CurrentOperation.Type == BCFG_TYPE_ADDH),\r
785 (BOOLEAN)(CurrentOperation.Type == BCFG_TYPE_ADD ),\r
786 CurrentOperation.HandleIndex);\r
787 break;\r
788 case BCFG_TYPE_OPT:\r
789 ShellStatus = BcfgAddOptInstall(\r
790 CurrentOperation.Target,\r
791 CurrentOperation.OptData);\r
792 break;\r
793 default:\r
794 ASSERT(FALSE);\r
795 }\r
796 }\r
797 }\r
798\r
799 if (Package != NULL) {\r
800 ShellCommandLineFreeVarList (Package);\r
801 }\r
802 if (CurrentOperation.FileName != NULL) {\r
803 FreePool(CurrentOperation.FileName);\r
804 }\r
805 if (CurrentOperation.Description != NULL) {\r
806 FreePool(CurrentOperation.Description);\r
807 }\r
808 if (CurrentOperation.Order != NULL) {\r
809 FreePool(CurrentOperation.Order);\r
810 }\r
811\r
812 return (ShellStatus);\r
813}\r