• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Main file for SetVar shell Debug1 function.
3 
4   (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5   Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
6   This program and the accompanying materials
7   are licensed and made available under the terms and conditions of the BSD License
8   which accompanies this distribution.  The full text of the license may be found at
9   http://opensource.org/licenses/bsd-license.php
10 
11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 
14 **/
15 
16 #include "UefiShellDebug1CommandsLib.h"
17 
18 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
19   {L"-guid", TypeValue},
20   {L"-bs", TypeFlag},
21   {L"-rt", TypeFlag},
22   {L"-nv", TypeFlag},
23   {NULL, TypeMax}
24   };
25 
26 
27 /**
28   Check if the input is a (potentially empty) string of hexadecimal nibbles.
29 
30   @param[in] String  The CHAR16 string to check.
31 
32   @retval FALSE  A character has been found in String for which
33                  ShellIsHexaDecimalDigitCharacter() returned FALSE.
34 
35   @retval TRUE   Otherwise. (Note that this covers the case when String is
36                  empty.)
37 **/
38 BOOLEAN
39 EFIAPI
IsStringOfHexNibbles(IN CONST CHAR16 * String)40 IsStringOfHexNibbles (
41   IN CONST CHAR16  *String
42   )
43 {
44   CONST CHAR16 *Pos;
45 
46   for (Pos = String; *Pos != L'\0'; ++Pos) {
47     if (!ShellIsHexaDecimalDigitCharacter (*Pos)) {
48       return FALSE;
49     }
50   }
51   return TRUE;
52 }
53 
54 
55 /**
56   Function for 'setvar' command.
57 
58   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
59   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
60 **/
61 SHELL_STATUS
62 EFIAPI
ShellCommandRunSetVar(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)63 ShellCommandRunSetVar (
64   IN EFI_HANDLE        ImageHandle,
65   IN EFI_SYSTEM_TABLE  *SystemTable
66   )
67 {
68   EFI_STATUS          Status;
69   LIST_ENTRY          *Package;
70   CHAR16              *ProblemParam;
71   SHELL_STATUS        ShellStatus;
72   CONST CHAR16        *VariableName;
73   CONST CHAR16        *Data;
74   EFI_GUID            Guid;
75   CONST CHAR16        *StringGuid;
76   UINT32              Attributes;
77   VOID                *Buffer;
78   UINTN               Size;
79   UINTN               LoopVar;
80   EFI_DEVICE_PATH_PROTOCOL           *DevPath;
81 
82   ShellStatus         = SHELL_SUCCESS;
83   Status              = EFI_SUCCESS;
84   Buffer              = NULL;
85   Size                = 0;
86   Attributes          = 0;
87   DevPath             = NULL;
88 
89   //
90   // initialize the shell lib (we must be in non-auto-init...)
91   //
92   Status = ShellInitialize();
93   ASSERT_EFI_ERROR(Status);
94 
95   Status = CommandInit();
96   ASSERT_EFI_ERROR(Status);
97 
98   //
99   // parse the command line
100   //
101   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
102   if (EFI_ERROR(Status)) {
103     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
104       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"setvar", ProblemParam);
105       FreePool(ProblemParam);
106       ShellStatus = SHELL_INVALID_PARAMETER;
107     } else {
108       ASSERT(FALSE);
109     }
110   } else {
111     if (ShellCommandLineGetCount(Package) < 2) {
112       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"setvar");
113       ShellStatus = SHELL_INVALID_PARAMETER;
114     } else if (ShellCommandLineGetCount(Package) > 3) {
115       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"setvar");
116       ShellStatus = SHELL_INVALID_PARAMETER;
117     } else {
118       VariableName  = ShellCommandLineGetRawValue(Package, 1);
119       Data          = ShellCommandLineGetRawValue(Package, 2);
120       if (!ShellCommandLineGetFlag(Package, L"-guid")){
121         CopyGuid(&Guid, &gEfiGlobalVariableGuid);
122       } else {
123         StringGuid = ShellCommandLineGetValue(Package, L"-guid");
124         Status = ConvertStringToGuid(StringGuid, &Guid);
125         if (EFI_ERROR(Status)) {
126           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", StringGuid);
127           ShellStatus = SHELL_INVALID_PARAMETER;
128         }
129       }
130       if (Data == NULL || Data[0] !=  L'=') {
131         //
132         // Display what's there
133         //
134         Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
135         if (Status == EFI_BUFFER_TOO_SMALL) {
136           Buffer = AllocateZeroPool(Size);
137           Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
138         }
139         if (!EFI_ERROR(Status)&& Buffer != NULL) {
140           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_PRINT), gShellDebug1HiiHandle, &Guid, VariableName, Size);
141           for (LoopVar = 0 ; LoopVar < Size ; LoopVar++) {
142             ShellPrintEx(-1, -1, L"%02x ", ((UINT8*)Buffer)[LoopVar]);
143           }
144           ShellPrintEx(-1, -1, L"\r\n");
145         } else {
146           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_GET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
147           ShellStatus = SHELL_ACCESS_DENIED;
148         }
149       } else if (StrCmp(Data, L"=") == 0) {
150         //
151         // Delete what's there!
152         //
153         Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, 0, NULL);
154         if (EFI_ERROR(Status)) {
155           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
156           ShellStatus = SHELL_ACCESS_DENIED;
157         } else {
158           ASSERT(ShellStatus == SHELL_SUCCESS);
159         }
160       } else {
161         //
162         // Change what's there or create a new one.
163         //
164 
165         ASSERT(Data[0] == L'=');
166         Data++;
167         ASSERT(Data[0] != L'\0');
168 
169         //
170         // Determine if the variable exists and get the attributes
171         //
172         Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
173         if (Status == EFI_BUFFER_TOO_SMALL) {
174           Buffer = AllocateZeroPool(Size);
175           Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
176         }
177 
178         if (EFI_ERROR(Status) || Buffer == NULL) {
179           //
180           // Creating a new variable.  determine attributes from command line.
181           //
182           Attributes = 0;
183           if (ShellCommandLineGetFlag(Package, L"-bs")) {
184             Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
185           }
186           if (ShellCommandLineGetFlag(Package, L"-rt")) {
187             Attributes |= EFI_VARIABLE_RUNTIME_ACCESS |
188                           EFI_VARIABLE_BOOTSERVICE_ACCESS;
189           }
190           if (ShellCommandLineGetFlag(Package, L"-nv")) {
191             Attributes |= EFI_VARIABLE_NON_VOLATILE;
192           }
193         }
194         SHELL_FREE_NON_NULL(Buffer);
195 
196         //
197         // What type is the new data.
198         //
199         if (IsStringOfHexNibbles(Data)) {
200           if (StrLen(Data) % 2 != 0) {
201             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", Data);
202             ShellStatus = SHELL_INVALID_PARAMETER;
203           } else {
204             //
205             // arbitrary buffer
206             //
207             Buffer = AllocateZeroPool((StrLen(Data) / 2));
208             if (Buffer == NULL) {
209               Status = EFI_OUT_OF_RESOURCES;
210             } else {
211               for (LoopVar = 0 ; LoopVar < (StrLen(Data) / 2) ; LoopVar++) {
212                 ((UINT8*)Buffer)[LoopVar] = (UINT8)(HexCharToUintn(Data[LoopVar*2]) * 16);
213                 ((UINT8*)Buffer)[LoopVar] = (UINT8)(((UINT8*)Buffer)[LoopVar] + HexCharToUintn(Data[LoopVar*2+1]));
214               }
215               Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, StrLen(Data) / 2, Buffer);
216             }
217             if (EFI_ERROR(Status)) {
218               ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
219               ShellStatus = SHELL_ACCESS_DENIED;
220             } else {
221               ASSERT(ShellStatus == SHELL_SUCCESS);
222             }
223           }
224         } else if (StrnCmp(Data, L"\"", 1) == 0) {
225           //
226           // ascii text
227           //
228           Data++;
229           Buffer = AllocateZeroPool(StrSize(Data) / 2);
230           if (Buffer == NULL) {
231             Status = EFI_OUT_OF_RESOURCES;
232           } else {
233             AsciiSPrint(Buffer, StrSize(Data) / 2, "%s", Data);
234             ((CHAR8*)Buffer)[AsciiStrLen(Buffer)-1] = CHAR_NULL;
235             Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, AsciiStrSize(Buffer)-sizeof(CHAR8), Buffer);
236           }
237           if (EFI_ERROR(Status)) {
238             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
239             ShellStatus = SHELL_ACCESS_DENIED;
240           } else {
241             ASSERT(ShellStatus == SHELL_SUCCESS);
242           }
243         } else if (StrnCmp(Data, L"L\"", 2) == 0) {
244           //
245           // ucs2 text
246           //
247           Data++;
248           Data++;
249           Buffer = AllocateZeroPool(StrSize(Data));
250           if (Buffer == NULL) {
251             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"setvar");
252             ShellStatus = SHELL_OUT_OF_RESOURCES;
253           } else {
254             UnicodeSPrint(Buffer, StrSize(Data), L"%s", Data);
255             ((CHAR16*)Buffer)[StrLen(Buffer)-1] = CHAR_NULL;
256 
257             Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, StrSize(Buffer)-sizeof(CHAR16), Buffer);
258             if (EFI_ERROR(Status)) {
259               ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
260               ShellStatus = SHELL_ACCESS_DENIED;
261             } else {
262               ASSERT(ShellStatus == SHELL_SUCCESS);
263             }
264           }
265         } else if (StrnCmp(Data, L"--", 2) == 0) {
266           //
267           // device path in text format
268           //
269           Data++;
270           Data++;
271           DevPath = ConvertTextToDevicePath(Data);
272           if (DevPath == NULL) {
273             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, L"setvar");
274             ShellStatus = SHELL_INVALID_PARAMETER;
275           } else {
276             Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, GetDevicePathSize(DevPath), DevPath);
277             if (EFI_ERROR(Status)) {
278               ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
279               ShellStatus = SHELL_ACCESS_DENIED;
280             } else {
281               ASSERT(ShellStatus == SHELL_SUCCESS);
282             }
283           }
284         } else {
285           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", Data);
286           ShellStatus = SHELL_INVALID_PARAMETER;
287         }
288       }
289     }
290     ShellCommandLineFreeVarList (Package);
291   }
292 
293   if (Buffer != NULL) {
294     FreePool(Buffer);
295   }
296 
297   if (DevPath != NULL) {
298     FreePool(DevPath);
299   }
300 
301   return (ShellStatus);
302 }
303