]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c
ShellPkg: Update header file including style
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / UefiShellDebug1CommandsLib.c
1 /** @file
2 Main file for NULL named library for debug1 profile shell command functions.
3
4 Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "UefiShellDebug1CommandsLib.h"
16 #include <Library/BcfgCommandLib.h>
17
18 STATIC CONST CHAR16 mFileName[] = L"Debug1Commands";
19 EFI_HANDLE gShellDebug1HiiHandle = NULL;
20
21 /**
22 Gets the debug file name. This will be used if HII is not working.
23
24 @retval NULL No file is available.
25 @return The NULL-terminated filename to get help from.
26 **/
27 CONST CHAR16*
28 EFIAPI
29 ShellCommandGetManFileNameDebug1 (
30 VOID
31 )
32 {
33 return (mFileName);
34 }
35
36 /**
37 Constructor for the Shell Debug1 Commands library.
38
39 @param ImageHandle the image handle of the process
40 @param SystemTable the EFI System Table pointer
41
42 @retval EFI_SUCCESS the shell command handlers were installed sucessfully
43 @retval EFI_UNSUPPORTED the shell level required was not found.
44 **/
45 EFI_STATUS
46 EFIAPI
47 UefiShellDebug1CommandsLibConstructor (
48 IN EFI_HANDLE ImageHandle,
49 IN EFI_SYSTEM_TABLE *SystemTable
50 )
51 {
52 //
53 // check our bit of the profiles mask
54 //
55 if ((PcdGet8(PcdShellProfileMask) & BIT1) == 0) {
56 return (EFI_SUCCESS);
57 }
58
59 //
60 // install the HII stuff.
61 //
62 gShellDebug1HiiHandle = HiiAddPackages (&gShellDebug1HiiGuid, gImageHandle, UefiShellDebug1CommandsLibStrings, NULL);
63 if (gShellDebug1HiiHandle == NULL) {
64 return (EFI_DEVICE_ERROR);
65 }
66
67 //
68 // install our shell command handlers that are always installed
69 //
70 ShellCommandRegisterCommandName(L"setsize", ShellCommandRunSetSize , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_SETSIZE) );
71 ShellCommandRegisterCommandName(L"comp", ShellCommandRunComp , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_COMP) );
72 ShellCommandRegisterCommandName(L"mode", ShellCommandRunMode , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_MODE) );
73 ShellCommandRegisterCommandName(L"memmap", ShellCommandRunMemMap , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_MEMMAP) );
74 ShellCommandRegisterCommandName(L"eficompress", ShellCommandRunEfiCompress , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_EFICOMPRESS) );
75 ShellCommandRegisterCommandName(L"efidecompress", ShellCommandRunEfiDecompress , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_EFIDCOMPRESS) );
76 ShellCommandRegisterCommandName(L"dmem", ShellCommandRunDmem , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_DMEM) );
77 ShellCommandRegisterCommandName(L"loadpcirom", ShellCommandRunLoadPciRom , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_LOAD_PCI_ROM) );
78 ShellCommandRegisterCommandName(L"mm", ShellCommandRunMm , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_MM) );
79 ShellCommandRegisterCommandName(L"setvar", ShellCommandRunSetVar , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_SETVAR) );
80 ShellCommandRegisterCommandName(L"sermode", ShellCommandRunSerMode , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_SERMODE) );
81 ShellCommandRegisterCommandName(L"pci", ShellCommandRunPci , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_PCI) );
82 ShellCommandRegisterCommandName(L"smbiosview", ShellCommandRunSmbiosView , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_SMBIOSVIEW) );
83 ShellCommandRegisterCommandName(L"dmpstore", ShellCommandRunDmpStore , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_DMPSTORE) );
84 ShellCommandRegisterCommandName(L"dblk", ShellCommandRunDblk , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_DBLK) );
85 ShellCommandRegisterCommandName(L"edit", ShellCommandRunEdit , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_EDIT) );
86 ShellCommandRegisterCommandName(L"hexedit", ShellCommandRunHexEdit , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_HEXEDIT) );
87
88 ShellCommandRegisterAlias(L"dmem", L"mem");
89
90 BcfgLibraryRegisterBcfgCommand(ImageHandle, SystemTable, L"Debug1");
91
92 return (EFI_SUCCESS);
93 }
94
95 /**
96 Destructor for the library. free any resources.
97
98 @param ImageHandle The image handle of the process.
99 @param SystemTable The EFI System Table pointer.
100 **/
101 EFI_STATUS
102 EFIAPI
103 UefiShellDebug1CommandsLibDestructor (
104 IN EFI_HANDLE ImageHandle,
105 IN EFI_SYSTEM_TABLE *SystemTable
106 )
107 {
108 if (gShellDebug1HiiHandle != NULL) {
109 HiiRemovePackages(gShellDebug1HiiHandle);
110 }
111
112 BcfgLibraryUnregisterBcfgCommand(ImageHandle, SystemTable);
113 return (EFI_SUCCESS);
114 }
115
116 /**
117 Convert a Unicode character to upper case only if
118 it maps to a valid small-case ASCII character.
119
120 This internal function only deal with Unicode character
121 which maps to a valid small-case ASCII character, i.e.
122 L'a' to L'z'. For other Unicode character, the input character
123 is returned directly.
124
125 @param Char The character to convert.
126
127 @retval LowerCharacter If the Char is with range L'a' to L'z'.
128 @retval Unchanged Otherwise.
129
130
131 //Stolen from MdePkg Baselib
132 **/
133 CHAR16
134 CharToUpper (
135 IN CHAR16 Char
136 )
137 {
138 if (Char >= L'a' && Char <= L'z') {
139 return (CHAR16) (Char - (L'a' - L'A'));
140 }
141
142 return Char;
143 }
144
145 /**
146 Function returns a system configuration table that is stored in the
147 EFI System Table based on the provided GUID.
148
149 @param[in] TableGuid A pointer to the table's GUID type.
150 @param[in, out] Table On exit, a pointer to a system configuration table.
151
152 @retval EFI_SUCCESS A configuration table matching TableGuid was found.
153 @retval EFI_NOT_FOUND A configuration table matching TableGuid was not found.
154 **/
155 EFI_STATUS
156 GetSystemConfigurationTable (
157 IN EFI_GUID *TableGuid,
158 IN OUT VOID **Table
159 )
160 {
161 UINTN Index;
162 ASSERT (Table != NULL);
163
164 for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
165 if (CompareGuid (TableGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {
166 *Table = gST->ConfigurationTable[Index].VendorTable;
167 return EFI_SUCCESS;
168 }
169 }
170
171 return EFI_NOT_FOUND;
172 }
173
174 /**
175 Clear the line at the specified Row.
176
177 @param[in] Row The row number to be cleared ( start from 1 )
178 @param[in] LastCol The last printable column.
179 @param[in] LastRow The last printable row.
180 **/
181 VOID
182 EditorClearLine (
183 IN UINTN Row,
184 IN UINTN LastCol,
185 IN UINTN LastRow
186 )
187 {
188 CHAR16 Line[200];
189
190 if (Row == 0) {
191 Row = 1;
192 }
193
194 //
195 // prepare a blank line
196 //
197 SetMem16(Line, LastCol*sizeof(CHAR16), L' ');
198
199 if (Row == LastRow) {
200 //
201 // if CHAR_NULL is still at position 80, it will cause first line error
202 //
203 Line[LastCol - 1] = CHAR_NULL;
204 } else {
205 Line[LastCol] = CHAR_NULL;
206 }
207
208 //
209 // print out the blank line
210 //
211 ShellPrintEx (0, ((INT32)Row) - 1, Line);
212 }
213
214 /**
215 Determine if the character is valid for a filename.
216
217 @param[in] Ch The character to test.
218
219 @retval TRUE The character is valid.
220 @retval FALSE The character is not valid.
221 **/
222 BOOLEAN
223 IsValidFileNameChar (
224 IN CONST CHAR16 Ch
225 )
226 {
227 //
228 // See if there are any illegal characters within the name
229 //
230 if (Ch < 0x20 || Ch == L'\"' || Ch == L'*' || Ch == L'/' || Ch == L'<' || Ch == L'>' || Ch == L'?' || Ch == L'|') {
231 return FALSE;
232 }
233
234 return TRUE;
235 }
236
237 /**
238 Check if file name has illegal characters.
239
240 @param Name The filename to check.
241
242 @retval TRUE The filename is ok.
243 @retval FALSE The filename is not ok.
244 **/
245 BOOLEAN
246 IsValidFileName (
247 IN CONST CHAR16 *Name
248 )
249 {
250
251 UINTN Index;
252 UINTN Len;
253
254 //
255 // check the length of Name
256 //
257 for (Len = 0, Index = StrLen (Name) - 1; Index + 1 != 0; Index--, Len++) {
258 if (Name[Index] == '\\' || Name[Index] == ':') {
259 break;
260 }
261 }
262
263 if (Len == 0 || Len > 255) {
264 return FALSE;
265 }
266 //
267 // check whether any char in Name not appears in valid file name char
268 //
269 for (Index = 0; Index < StrLen (Name); Index++) {
270 if (!IsValidFileNameChar (Name[Index])) {
271 return FALSE;
272 }
273 }
274
275 return TRUE;
276 }
277
278 /**
279 Find a filename that is valid (not taken) with the given extension.
280
281 @param[in] Extension The file extension.
282
283 @retval NULL Something went wrong.
284 @return the valid filename.
285 **/
286 CHAR16 *
287 EditGetDefaultFileName (
288 IN CONST CHAR16 *Extension
289 )
290 {
291 EFI_STATUS Status;
292 UINTN Suffix;
293 CHAR16 *FileNameTmp;
294
295 Suffix = 0;
296
297 do {
298 FileNameTmp = CatSPrint (NULL, L"NewFile%d.%s", Suffix, Extension);
299
300 //
301 // after that filename changed to path
302 //
303 Status = ShellFileExists (FileNameTmp);
304
305 if (Status == EFI_NOT_FOUND) {
306 return FileNameTmp;
307 }
308
309 FreePool (FileNameTmp);
310 FileNameTmp = NULL;
311 Suffix++;
312 } while (Suffix != 0);
313
314 FreePool (FileNameTmp);
315 return NULL;
316 }
317
318 /**
319 Read a file into an allocated buffer. The buffer is the responsibility
320 of the caller to free.
321
322 @param[in] FileName The filename of the file to open.
323 @param[out] Buffer Upon successful return, the pointer to the
324 address of the allocated buffer.
325 @param[out] BufferSize If not NULL, then the pointer to the size
326 of the allocated buffer.
327 @param[out] ReadOnly Upon successful return TRUE if the file is
328 read only. FALSE otherwise.
329
330 @retval EFI_NOT_FOUND The filename did not represent a file in the
331 file system.
332 @retval EFI_SUCCESS The file was read into the buffer.
333 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
334 @retval EFI_LOAD_ERROR The file read operation failed.
335 @retval EFI_INVALID_PARAMETER A parameter was invalid.
336 @retval EFI_INVALID_PARAMETER FileName was NULL.
337 @retval EFI_INVALID_PARAMETER FileName was a directory.
338 **/
339 EFI_STATUS
340 ReadFileIntoBuffer (
341 IN CONST CHAR16 *FileName,
342 OUT VOID **Buffer,
343 OUT UINTN *BufferSize OPTIONAL,
344 OUT BOOLEAN *ReadOnly
345 )
346 {
347 VOID *InternalBuffer;
348 UINTN FileSize;
349 SHELL_FILE_HANDLE FileHandle;
350 BOOLEAN CreateFile;
351 EFI_STATUS Status;
352 EFI_FILE_INFO *Info;
353
354 InternalBuffer = NULL;
355 FileSize = 0;
356 FileHandle = NULL;
357 CreateFile = FALSE;
358 Status = EFI_SUCCESS;
359 Info = NULL;
360
361 if (FileName == NULL || Buffer == NULL || ReadOnly == NULL) {
362 return (EFI_INVALID_PARAMETER);
363 }
364
365 //
366 // try to open the file
367 //
368 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
369
370 if (!EFI_ERROR(Status)) {
371 ASSERT(CreateFile == FALSE);
372 if (FileHandle == NULL) {
373 return EFI_LOAD_ERROR;
374 }
375
376 Info = ShellGetFileInfo(FileHandle);
377
378 if (Info->Attribute & EFI_FILE_DIRECTORY) {
379 FreePool (Info);
380 return EFI_INVALID_PARAMETER;
381 }
382
383 if (Info->Attribute & EFI_FILE_READ_ONLY) {
384 *ReadOnly = TRUE;
385 } else {
386 *ReadOnly = FALSE;
387 }
388 //
389 // get file size
390 //
391 FileSize = (UINTN) Info->FileSize;
392
393 FreePool (Info);
394 } else if (Status == EFI_NOT_FOUND) {
395 //
396 // file not exists. add create and try again
397 //
398 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
399 if (EFI_ERROR (Status)) {
400 return Status;
401 } else {
402 //
403 // it worked. now delete it and move on with the name (now validated)
404 //
405 Status = ShellDeleteFile (&FileHandle);
406 if (Status == EFI_WARN_DELETE_FAILURE) {
407 Status = EFI_ACCESS_DENIED;
408 }
409 if (EFI_ERROR (Status)) {
410 return Status;
411 }
412 }
413 //
414 // file doesn't exist, so set CreateFile to TRUE and can't be read-only
415 //
416 CreateFile = TRUE;
417 *ReadOnly = FALSE;
418 }
419
420 //
421 // the file exists
422 //
423 if (!CreateFile) {
424 //
425 // allocate buffer to read file
426 //
427 InternalBuffer = AllocateZeroPool (FileSize);
428 if (InternalBuffer == NULL) {
429 return EFI_OUT_OF_RESOURCES;
430 }
431 //
432 // read file into InternalBuffer
433 //
434 Status = ShellReadFile (FileHandle, &FileSize, InternalBuffer);
435 ShellCloseFile(&FileHandle);
436 FileHandle = NULL;
437 if (EFI_ERROR (Status)) {
438 SHELL_FREE_NON_NULL (InternalBuffer);
439 return EFI_LOAD_ERROR;
440 }
441 }
442 *Buffer = InternalBuffer;
443 if (BufferSize != NULL) {
444 *BufferSize = FileSize;
445 }
446 return (EFI_SUCCESS);
447
448 }