]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c
ShellPkg/UefiShellDebug1CommandsLib: Remove unnecessary EFIAPI
[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 - 2011, 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 Convert a Unicode character to numerical value.
176
177 This internal function only deal with Unicode character
178 which maps to a valid hexadecimal ASII character, i.e.
179 L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
180 Unicode character, the value returned does not make sense.
181
182 @param Char The character to convert.
183
184 @return The numerical value converted.
185
186 **/
187 UINTN
188 HexCharToUintn (
189 IN CHAR16 Char
190 )
191 {
192 if (Char >= L'0' && Char <= L'9') {
193 return Char - L'0';
194 }
195
196 return (UINTN) (10 + CharToUpper (Char) - L'A');
197 }
198
199 /**
200 Convert a string representation of a guid to a Guid value.
201
202 @param[in] StringGuid The pointer to the string of a guid.
203 @param[in, out] Guid The pointer to the GUID structure to populate.
204
205 @retval EFI_INVALID_PARAMETER A parameter was invalid.
206 @retval EFI_SUCCESS The conversion was successful.
207 **/
208 EFI_STATUS
209 ConvertStringToGuid (
210 IN CONST CHAR16 *StringGuid,
211 IN OUT EFI_GUID *Guid
212 )
213 {
214 CHAR16 *TempCopy;
215 CHAR16 *TempSpot;
216 CHAR16 *Walker;
217 UINT64 TempVal;
218 EFI_STATUS Status;
219
220 if (StringGuid == NULL) {
221 return (EFI_INVALID_PARAMETER);
222 } else if (StrLen(StringGuid) != 36) {
223 return (EFI_INVALID_PARAMETER);
224 }
225 TempCopy = NULL;
226 TempCopy = StrnCatGrow(&TempCopy, NULL, StringGuid, 0);
227 if (TempCopy == NULL) {
228 return (EFI_OUT_OF_RESOURCES);
229 }
230 Walker = TempCopy;
231 TempSpot = StrStr(Walker, L"-");
232 if (TempSpot != NULL) {
233 *TempSpot = CHAR_NULL;
234 }
235 Status = ShellConvertStringToUint64(Walker, &TempVal, TRUE, FALSE);
236 if (EFI_ERROR(Status)) {
237 FreePool(TempCopy);
238 return (Status);
239 }
240 Guid->Data1 = (UINT32)TempVal;
241 Walker += 9;
242 TempSpot = StrStr(Walker, L"-");
243 if (TempSpot != NULL) {
244 *TempSpot = CHAR_NULL;
245 }
246 Status = ShellConvertStringToUint64(Walker, &TempVal, TRUE, FALSE);
247 if (EFI_ERROR(Status)) {
248 FreePool(TempCopy);
249 return (Status);
250 }
251 Guid->Data2 = (UINT16)TempVal;
252 Walker += 5;
253 TempSpot = StrStr(Walker, L"-");
254 if (TempSpot != NULL) {
255 *TempSpot = CHAR_NULL;
256 }
257 Status = ShellConvertStringToUint64(Walker, &TempVal, TRUE, FALSE);
258 if (EFI_ERROR(Status)) {
259 FreePool(TempCopy);
260 return (Status);
261 }
262 Guid->Data3 = (UINT16)TempVal;
263 Walker += 5;
264 Guid->Data4[0] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
265 Guid->Data4[0] = (UINT8)(Guid->Data4[0]+ (UINT8)HexCharToUintn(Walker[1]));
266 Walker += 2;
267 Guid->Data4[1] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
268 Guid->Data4[1] = (UINT8)(Guid->Data4[1] + (UINT8)HexCharToUintn(Walker[1]));
269 Walker += 3;
270 Guid->Data4[2] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
271 Guid->Data4[2] = (UINT8)(Guid->Data4[2] + (UINT8)HexCharToUintn(Walker[1]));
272 Walker += 2;
273 Guid->Data4[3] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
274 Guid->Data4[3] = (UINT8)(Guid->Data4[3] + (UINT8)HexCharToUintn(Walker[1]));
275 Walker += 2;
276 Guid->Data4[4] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
277 Guid->Data4[4] = (UINT8)(Guid->Data4[4] + (UINT8)HexCharToUintn(Walker[1]));
278 Walker += 2;
279 Guid->Data4[5] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
280 Guid->Data4[5] = (UINT8)(Guid->Data4[5] + (UINT8)HexCharToUintn(Walker[1]));
281 Walker += 2;
282 Guid->Data4[6] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
283 Guid->Data4[6] = (UINT8)(Guid->Data4[6] + (UINT8)HexCharToUintn(Walker[1]));
284 Walker += 2;
285 Guid->Data4[7] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
286 Guid->Data4[7] = (UINT8)(Guid->Data4[7] + (UINT8)HexCharToUintn(Walker[1]));
287 FreePool(TempCopy);
288 return (EFI_SUCCESS);
289 }
290
291 /**
292 Clear the line at the specified Row.
293
294 @param[in] Row The row number to be cleared ( start from 1 )
295 @param[in] LastCol The last printable column.
296 @param[in] LastRow The last printable row.
297 **/
298 VOID
299 EditorClearLine (
300 IN UINTN Row,
301 IN UINTN LastCol,
302 IN UINTN LastRow
303 )
304 {
305 CHAR16 Line[200];
306
307 if (Row == 0) {
308 Row = 1;
309 }
310
311 //
312 // prepare a blank line
313 //
314 SetMem16(Line, LastCol*sizeof(CHAR16), L' ');
315
316 if (Row == LastRow) {
317 //
318 // if CHAR_NULL is still at position 80, it will cause first line error
319 //
320 Line[LastCol - 1] = CHAR_NULL;
321 } else {
322 Line[LastCol] = CHAR_NULL;
323 }
324
325 //
326 // print out the blank line
327 //
328 ShellPrintEx (0, ((INT32)Row) - 1, Line);
329 }
330
331 /**
332 Determine if the character is valid for a filename.
333
334 @param[in] Ch The character to test.
335
336 @retval TRUE The character is valid.
337 @retval FALSE The character is not valid.
338 **/
339 BOOLEAN
340 IsValidFileNameChar (
341 IN CONST CHAR16 Ch
342 )
343 {
344 //
345 // See if there are any illegal characters within the name
346 //
347 if (Ch < 0x20 || Ch == L'\"' || Ch == L'*' || Ch == L'/' || Ch == L'<' || Ch == L'>' || Ch == L'?' || Ch == L'|') {
348 return FALSE;
349 }
350
351 return TRUE;
352 }
353
354 /**
355 Check if file name has illegal characters.
356
357 @param Name The filename to check.
358
359 @retval TRUE The filename is ok.
360 @retval FALSE The filename is not ok.
361 **/
362 BOOLEAN
363 IsValidFileName (
364 IN CONST CHAR16 *Name
365 )
366 {
367
368 UINTN Index;
369 UINTN Len;
370
371 //
372 // check the length of Name
373 //
374 for (Len = 0, Index = StrLen (Name) - 1; Index + 1 != 0; Index--, Len++) {
375 if (Name[Index] == '\\' || Name[Index] == ':') {
376 break;
377 }
378 }
379
380 if (Len == 0 || Len > 255) {
381 return FALSE;
382 }
383 //
384 // check whether any char in Name not appears in valid file name char
385 //
386 for (Index = 0; Index < StrLen (Name); Index++) {
387 if (!IsValidFileNameChar (Name[Index])) {
388 return FALSE;
389 }
390 }
391
392 return TRUE;
393 }
394
395 /**
396 Find a filename that is valid (not taken) with the given extension.
397
398 @param[in] Extension The file extension.
399
400 @retval NULL Something went wrong.
401 @return the valid filename.
402 **/
403 CHAR16 *
404 EditGetDefaultFileName (
405 IN CONST CHAR16 *Extension
406 )
407 {
408 EFI_STATUS Status;
409 UINTN Suffix;
410 CHAR16 *FileNameTmp;
411
412 Suffix = 0;
413
414 do {
415 FileNameTmp = CatSPrint (NULL, L"NewFile%d.%s", Suffix, Extension);
416
417 //
418 // after that filename changed to path
419 //
420 Status = ShellFileExists (FileNameTmp);
421
422 if (Status == EFI_NOT_FOUND) {
423 return FileNameTmp;
424 }
425
426 FreePool (FileNameTmp);
427 FileNameTmp = NULL;
428 Suffix++;
429 } while (Suffix != 0);
430
431 FreePool (FileNameTmp);
432 return NULL;
433 }
434
435 /**
436 Read a file into an allocated buffer. The buffer is the responsibility
437 of the caller to free.
438
439 @param[in] FileName The filename of the file to open.
440 @param[out] Buffer Upon successful return, the pointer to the
441 address of the allocated buffer.
442 @param[out] BufferSize If not NULL, then the pointer to the size
443 of the allocated buffer.
444 @param[out] ReadOnly Upon successful return TRUE if the file is
445 read only. FALSE otherwise.
446
447 @retval EFI_NOT_FOUND The filename did not represent a file in the
448 file system.
449 @retval EFI_SUCCESS The file was read into the buffer.
450 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
451 @retval EFI_LOAD_ERROR The file read operation failed.
452 @retval EFI_INVALID_PARAMETER A parameter was invalid.
453 @retval EFI_INVALID_PARAMETER FileName was NULL.
454 @retval EFI_INVALID_PARAMETER FileName was a directory.
455 **/
456 EFI_STATUS
457 ReadFileIntoBuffer (
458 IN CONST CHAR16 *FileName,
459 OUT VOID **Buffer,
460 OUT UINTN *BufferSize OPTIONAL,
461 OUT BOOLEAN *ReadOnly
462 )
463 {
464 VOID *InternalBuffer;
465 UINTN FileSize;
466 SHELL_FILE_HANDLE FileHandle;
467 BOOLEAN CreateFile;
468 EFI_STATUS Status;
469 EFI_FILE_INFO *Info;
470
471 InternalBuffer = NULL;
472 FileSize = 0;
473 FileHandle = NULL;
474 CreateFile = FALSE;
475 Status = EFI_SUCCESS;
476 Info = NULL;
477
478 if (FileName == NULL || Buffer == NULL || ReadOnly == NULL) {
479 return (EFI_INVALID_PARAMETER);
480 }
481
482 //
483 // try to open the file
484 //
485 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
486
487 if (!EFI_ERROR(Status)) {
488 ASSERT(CreateFile == FALSE);
489 if (FileHandle == NULL) {
490 return EFI_LOAD_ERROR;
491 }
492
493 Info = ShellGetFileInfo(FileHandle);
494
495 if (Info->Attribute & EFI_FILE_DIRECTORY) {
496 FreePool (Info);
497 return EFI_INVALID_PARAMETER;
498 }
499
500 if (Info->Attribute & EFI_FILE_READ_ONLY) {
501 *ReadOnly = TRUE;
502 } else {
503 *ReadOnly = FALSE;
504 }
505 //
506 // get file size
507 //
508 FileSize = (UINTN) Info->FileSize;
509
510 FreePool (Info);
511 } else if (Status == EFI_NOT_FOUND) {
512 //
513 // file not exists. add create and try again
514 //
515 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
516 if (EFI_ERROR (Status)) {
517 return Status;
518 } else {
519 //
520 // it worked. now delete it and move on with the name (now validated)
521 //
522 Status = ShellDeleteFile (&FileHandle);
523 if (Status == EFI_WARN_DELETE_FAILURE) {
524 Status = EFI_ACCESS_DENIED;
525 }
526 if (EFI_ERROR (Status)) {
527 return Status;
528 }
529 }
530 //
531 // file doesn't exist, so set CreateFile to TRUE and can't be read-only
532 //
533 CreateFile = TRUE;
534 *ReadOnly = FALSE;
535 }
536
537 //
538 // the file exists
539 //
540 if (!CreateFile) {
541 //
542 // allocate buffer to read file
543 //
544 InternalBuffer = AllocateZeroPool (FileSize);
545 if (InternalBuffer == NULL) {
546 return EFI_OUT_OF_RESOURCES;
547 }
548 //
549 // read file into InternalBuffer
550 //
551 Status = ShellReadFile (FileHandle, &FileSize, InternalBuffer);
552 ShellCloseFile(&FileHandle);
553 FileHandle = NULL;
554 if (EFI_ERROR (Status)) {
555 SHELL_FREE_NON_NULL (InternalBuffer);
556 return EFI_LOAD_ERROR;
557 }
558 }
559 *Buffer = InternalBuffer;
560 if (BufferSize != NULL) {
561 *BufferSize = FileSize;
562 }
563 return (EFI_SUCCESS);
564
565 }