]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c
ShellPkg: Fixed build error 'variable set but not used'
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / UefiShellDebug1CommandsLib.c
CommitLineData
5d73d92f 1/** @file\r
2 Main file for NULL named library for debug1 profile shell command functions.\r
3\r
3737ac2b 4 Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
5d73d92f 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 "UefiShellDebug1CommandsLib.h"\r
16\r
17STATIC CONST CHAR16 mFileName[] = L"Debug1Commands";\r
18EFI_HANDLE gShellDebug1HiiHandle = NULL;\r
5d73d92f 19\r
3737ac2b 20/**\r
21 Gets the debug file name. This will be used if HII is not working.\r
22\r
23 @retval NULL No file is available.\r
24 @return The NULL-terminated filename to get help from.\r
25**/\r
5d73d92f 26CONST CHAR16*\r
27EFIAPI\r
28ShellCommandGetManFileNameDebug1 (\r
29 VOID\r
30 )\r
31{\r
32 return (mFileName);\r
33}\r
34\r
35/**\r
36 Constructor for the Shell Debug1 Commands library.\r
37\r
38 @param ImageHandle the image handle of the process\r
39 @param SystemTable the EFI System Table pointer\r
40\r
41 @retval EFI_SUCCESS the shell command handlers were installed sucessfully\r
42 @retval EFI_UNSUPPORTED the shell level required was not found.\r
43**/\r
44EFI_STATUS\r
45EFIAPI\r
46UefiShellDebug1CommandsLibConstructor (\r
47 IN EFI_HANDLE ImageHandle,\r
48 IN EFI_SYSTEM_TABLE *SystemTable\r
49 )\r
50{\r
51 //\r
52 // check our bit of the profiles mask\r
53 //\r
54 if ((PcdGet8(PcdShellProfileMask) & BIT1) == 0) {\r
82571fb5 55 return (EFI_SUCCESS);\r
5d73d92f 56 }\r
57\r
58 //\r
59 // install the HII stuff.\r
60 //\r
61 gShellDebug1HiiHandle = HiiAddPackages (&gShellDebug1HiiGuid, gImageHandle, UefiShellDebug1CommandsLibStrings, NULL);\r
62 if (gShellDebug1HiiHandle == NULL) {\r
63 return (EFI_DEVICE_ERROR);\r
64 }\r
65\r
66 //\r
67 // install our shell command handlers that are always installed\r
68 //\r
3737ac2b 69 ShellCommandRegisterCommandName(L"setsize", ShellCommandRunSetSize , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_SETSIZE) );\r
5d73d92f 70 ShellCommandRegisterCommandName(L"comp", ShellCommandRunComp , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_COMP) );\r
71 ShellCommandRegisterCommandName(L"mode", ShellCommandRunMode , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_MODE) );\r
72 ShellCommandRegisterCommandName(L"memmap", ShellCommandRunMemMap , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_MEMMAP) );\r
73 ShellCommandRegisterCommandName(L"eficompress", ShellCommandRunEfiCompress , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_EFICOMPRESS) );\r
74 ShellCommandRegisterCommandName(L"efidecompress", ShellCommandRunEfiDecompress , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_EFIDCOMPRESS) );\r
75 ShellCommandRegisterCommandName(L"dmem", ShellCommandRunDmem , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_DMEM) );\r
3737ac2b 76 ShellCommandRegisterCommandName(L"loadpcirom", ShellCommandRunLoadPciRom , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_LOAD_PCI_ROM) );\r
5d73d92f 77 ShellCommandRegisterCommandName(L"mm", ShellCommandRunMm , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_MM) );\r
3737ac2b 78 ShellCommandRegisterCommandName(L"setvar", ShellCommandRunSetVar , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_SETVAR) );\r
79 ShellCommandRegisterCommandName(L"sermode", ShellCommandRunSerMode , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_SERMODE) );\r
80 ShellCommandRegisterCommandName(L"pci", ShellCommandRunPci , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_PCI) );\r
5d73d92f 81 ShellCommandRegisterCommandName(L"smbiosview", ShellCommandRunSmbiosView , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_SMBIOSVIEW) );\r
82 ShellCommandRegisterCommandName(L"dmpstore", ShellCommandRunDmpStore , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_DMPSTORE) );\r
83 ShellCommandRegisterCommandName(L"dblk", ShellCommandRunDblk , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_DBLK) );\r
3737ac2b 84 ShellCommandRegisterCommandName(L"edit", ShellCommandRunEdit , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_EDIT) );\r
85 ShellCommandRegisterCommandName(L"hexedit", ShellCommandRunHexEdit , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_HEXEDIT) );\r
5d73d92f 86\r
87 //\r
88 // check install profile bit of the profiles mask is set\r
89 //\r
90 if ((PcdGet8(PcdShellProfileMask) & BIT2) == 0) {\r
91 ShellCommandRegisterCommandName(L"bcfg", ShellCommandRunBcfg , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_BCFG) );\r
92 }\r
93\r
3737ac2b 94\r
95\r
5d73d92f 96\r
97 ShellCommandRegisterAlias(L"dmem", L"mem");\r
98\r
99 return (EFI_SUCCESS);\r
100}\r
101\r
102/**\r
103 Destructor for the library. free any resources.\r
3737ac2b 104\r
105 @param ImageHandle The image handle of the process.\r
106 @param SystemTable The EFI System Table pointer.\r
5d73d92f 107**/\r
108EFI_STATUS\r
109EFIAPI\r
110UefiShellDebug1CommandsLibDestructor (\r
111 IN EFI_HANDLE ImageHandle,\r
112 IN EFI_SYSTEM_TABLE *SystemTable\r
113 )\r
114{\r
115 if (gShellDebug1HiiHandle != NULL) {\r
116 HiiRemovePackages(gShellDebug1HiiHandle);\r
117 }\r
118 return (EFI_SUCCESS);\r
119}\r
120\r
121STATIC CONST CHAR8 Hex[] = {\r
122 '0',\r
123 '1',\r
124 '2',\r
125 '3',\r
126 '4',\r
127 '5',\r
128 '6',\r
129 '7',\r
130 '8',\r
131 '9',\r
132 'A',\r
133 'B',\r
134 'C',\r
135 'D',\r
136 'E',\r
137 'F'\r
138};\r
139\r
3737ac2b 140/**\r
141 Dump some hexadecimal data to the screen.\r
142\r
143 @param[in] Indent How many spaces to indent the output.\r
144 @param[in] Offset The offset of the printing.\r
145 @param[in] DataSize The size in bytes of UserData.\r
146 @param[in] UserData The data to print out.\r
147**/\r
5d73d92f 148VOID\r
5d73d92f 149DumpHex (\r
150 IN UINTN Indent,\r
151 IN UINTN Offset,\r
152 IN UINTN DataSize,\r
153 IN VOID *UserData\r
154 )\r
155{\r
156 UINT8 *Data;\r
157\r
158 CHAR8 Val[50];\r
159\r
160 CHAR8 Str[20];\r
161\r
3737ac2b 162 UINT8 TempByte;\r
5d73d92f 163 UINTN Size;\r
164 UINTN Index;\r
165\r
5d73d92f 166 Data = UserData;\r
167 while (DataSize != 0) {\r
168 Size = 16;\r
169 if (Size > DataSize) {\r
170 Size = DataSize;\r
171 }\r
172\r
173 for (Index = 0; Index < Size; Index += 1) {\r
3737ac2b 174 TempByte = Data[Index];\r
175 Val[Index * 3 + 0] = Hex[TempByte >> 4];\r
176 Val[Index * 3 + 1] = Hex[TempByte & 0xF];\r
5d73d92f 177 Val[Index * 3 + 2] = (CHAR8) ((Index == 7) ? '-' : ' ');\r
3737ac2b 178 Str[Index] = (CHAR8) ((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);\r
5d73d92f 179 }\r
180\r
181 Val[Index * 3] = 0;\r
182 Str[Index] = 0;\r
5904052a 183 ShellPrintEx(-1, -1, L"%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str);\r
5d73d92f 184\r
185 Data += Size;\r
186 Offset += Size;\r
187 DataSize -= Size;\r
188 }\r
189}\r
190\r
191/**\r
192 Convert a Unicode character to upper case only if\r
193 it maps to a valid small-case ASCII character.\r
194\r
195 This internal function only deal with Unicode character\r
196 which maps to a valid small-case ASCII character, i.e.\r
197 L'a' to L'z'. For other Unicode character, the input character\r
198 is returned directly.\r
199\r
200 @param Char The character to convert.\r
201\r
202 @retval LowerCharacter If the Char is with range L'a' to L'z'.\r
203 @retval Unchanged Otherwise.\r
204\r
205\r
206 //Stolen from MdePkg Baselib\r
207**/\r
208CHAR16\r
209EFIAPI\r
210CharToUpper (\r
211 IN CHAR16 Char\r
212 )\r
213{\r
214 if (Char >= L'a' && Char <= L'z') {\r
215 return (CHAR16) (Char - (L'a' - L'A'));\r
216 }\r
217\r
218 return Char;\r
219}\r
220\r
221/**\r
222 Function returns a system configuration table that is stored in the\r
223 EFI System Table based on the provided GUID.\r
224\r
4ff7e37b
ED
225 @param[in] TableGuid A pointer to the table's GUID type.\r
226 @param[in, out] Table On exit, a pointer to a system configuration table.\r
5d73d92f 227\r
228 @retval EFI_SUCCESS A configuration table matching TableGuid was found.\r
229 @retval EFI_NOT_FOUND A configuration table matching TableGuid was not found.\r
230**/\r
231EFI_STATUS\r
232EFIAPI\r
233GetSystemConfigurationTable (\r
234 IN EFI_GUID *TableGuid,\r
235 IN OUT VOID **Table\r
236 )\r
237{\r
238 UINTN Index;\r
239 ASSERT (Table != NULL);\r
240\r
241 for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {\r
3737ac2b 242 if (CompareGuid (TableGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {\r
5d73d92f 243 *Table = gST->ConfigurationTable[Index].VendorTable;\r
244 return EFI_SUCCESS;\r
245 }\r
246 }\r
247\r
248 return EFI_NOT_FOUND;\r
249}\r
250\r
251/**\r
252 Convert a Unicode character to numerical value.\r
253\r
254 This internal function only deal with Unicode character\r
255 which maps to a valid hexadecimal ASII character, i.e.\r
256 L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other\r
257 Unicode character, the value returned does not make sense.\r
258\r
259 @param Char The character to convert.\r
260\r
261 @return The numerical value converted.\r
262\r
263**/\r
264UINTN\r
265EFIAPI\r
266HexCharToUintn (\r
267 IN CHAR16 Char\r
268 )\r
269{\r
270 if (Char >= L'0' && Char <= L'9') {\r
271 return Char - L'0';\r
272 }\r
273\r
274 return (UINTN) (10 + CharToUpper (Char) - L'A');\r
275}\r
276\r
3737ac2b 277/**\r
278 Convert a string representation of a guid to a Guid value.\r
279\r
4ff7e37b
ED
280 @param[in] StringGuid The pointer to the string of a guid.\r
281 @param[in, out] Guid The pointer to the GUID structure to populate.\r
3737ac2b 282\r
283 @retval EFI_INVALID_PARAMETER A parameter was invalid.\r
284 @retval EFI_SUCCESS The conversion was successful.\r
285**/\r
5d73d92f 286EFI_STATUS\r
287EFIAPI\r
288ConvertStringToGuid (\r
289 IN CONST CHAR16 *StringGuid,\r
290 IN OUT EFI_GUID *Guid\r
291 )\r
292{\r
3737ac2b 293 CHAR16 *TempCopy;\r
294 CHAR16 *TempSpot;\r
295 CHAR16 *Walker;\r
296 UINT64 TempVal;\r
297 EFI_STATUS Status;\r
298\r
299 if (StringGuid == NULL) {\r
300 return (EFI_INVALID_PARAMETER);\r
301 } else if (StrLen(StringGuid) != 36) {\r
5d73d92f 302 return (EFI_INVALID_PARAMETER);\r
3737ac2b 303 } \r
304 TempCopy = NULL;\r
305 TempCopy = StrnCatGrow(&TempCopy, NULL, StringGuid, 0);\r
532691c8 306 if (TempCopy == NULL) {\r
307 return (EFI_OUT_OF_RESOURCES);\r
308 }\r
3737ac2b 309 Walker = TempCopy;\r
310 TempSpot = StrStr(Walker, L"-");\r
33c031ee 311 if (TempSpot != NULL) {\r
312 *TempSpot = CHAR_NULL;\r
313 }\r
3737ac2b 314 Status = ShellConvertStringToUint64(Walker, &TempVal, TRUE, FALSE);\r
315 if (EFI_ERROR(Status)) {\r
316 FreePool(TempCopy);\r
317 return (Status);\r
318 }\r
319 Guid->Data1 = (UINT32)TempVal;\r
320 Walker += 9;\r
321 TempSpot = StrStr(Walker, L"-");\r
33c031ee 322 if (TempSpot != NULL) {\r
323 *TempSpot = CHAR_NULL;\r
324 }\r
3737ac2b 325 Status = ShellConvertStringToUint64(Walker, &TempVal, TRUE, FALSE);\r
326 if (EFI_ERROR(Status)) {\r
327 FreePool(TempCopy);\r
328 return (Status);\r
329 }\r
330 Guid->Data2 = (UINT16)TempVal;\r
331 Walker += 5;\r
332 TempSpot = StrStr(Walker, L"-");\r
33c031ee 333 if (TempSpot != NULL) {\r
334 *TempSpot = CHAR_NULL;\r
335 }\r
3737ac2b 336 Status = ShellConvertStringToUint64(Walker, &TempVal, TRUE, FALSE);\r
337 if (EFI_ERROR(Status)) {\r
338 FreePool(TempCopy);\r
339 return (Status);\r
340 }\r
341 Guid->Data3 = (UINT16)TempVal;\r
342 Walker += 5;\r
343 Guid->Data4[0] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
344 Guid->Data4[0] = (UINT8)(Guid->Data4[0]+ (UINT8)HexCharToUintn(Walker[1]));\r
345 Walker += 2;\r
346 Guid->Data4[1] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
347 Guid->Data4[1] = (UINT8)(Guid->Data4[1] + (UINT8)HexCharToUintn(Walker[1]));\r
348 Walker += 3;\r
349 Guid->Data4[2] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
350 Guid->Data4[2] = (UINT8)(Guid->Data4[2] + (UINT8)HexCharToUintn(Walker[1]));\r
351 Walker += 2;\r
352 Guid->Data4[3] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
353 Guid->Data4[3] = (UINT8)(Guid->Data4[3] + (UINT8)HexCharToUintn(Walker[1]));\r
354 Walker += 2;\r
355 Guid->Data4[4] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
356 Guid->Data4[4] = (UINT8)(Guid->Data4[4] + (UINT8)HexCharToUintn(Walker[1]));\r
357 Walker += 2;\r
358 Guid->Data4[5] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
359 Guid->Data4[5] = (UINT8)(Guid->Data4[5] + (UINT8)HexCharToUintn(Walker[1]));\r
360 Walker += 2;\r
361 Guid->Data4[6] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
362 Guid->Data4[6] = (UINT8)(Guid->Data4[6] + (UINT8)HexCharToUintn(Walker[1]));\r
363 Walker += 2;\r
364 Guid->Data4[7] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
365 Guid->Data4[7] = (UINT8)(Guid->Data4[7] + (UINT8)HexCharToUintn(Walker[1]));\r
366 FreePool(TempCopy);\r
367 return (EFI_SUCCESS);\r
368}\r
369\r
3737ac2b 370/**\r
371 Clear the line at the specified Row.\r
372 \r
373 @param[in] Row The row number to be cleared ( start from 1 )\r
374 @param[in] LastCol The last printable column.\r
375 @param[in] LastRow The last printable row.\r
376**/\r
377VOID\r
378EFIAPI\r
379EditorClearLine (\r
380 IN UINTN Row,\r
381 IN UINTN LastCol,\r
382 IN UINTN LastRow\r
383 )\r
384{\r
385 CHAR16 Line[200];\r
386\r
387 if (Row == 0) {\r
388 Row = 1;\r
389 }\r
390\r
391 //\r
392 // prepare a blank line\r
393 //\r
394 SetMem16(Line, LastCol*sizeof(CHAR16), L' ');\r
395\r
396 if (Row == LastRow) {\r
397 //\r
398 // if CHAR_NULL is still at position 80, it will cause first line error\r
399 //\r
400 Line[LastCol - 1] = CHAR_NULL;\r
5d73d92f 401 } else {\r
3737ac2b 402 Line[LastCol] = CHAR_NULL;\r
403 }\r
404\r
405 //\r
406 // print out the blank line\r
407 //\r
408 ShellPrintEx (0, ((INT32)Row) - 1, Line);\r
409}\r
410\r
411/**\r
412 Determine if the character is valid for a filename.\r
413\r
414 @param[in] Ch The character to test.\r
415\r
416 @retval TRUE The character is valid.\r
417 @retval FALSE The character is not valid.\r
418**/\r
419BOOLEAN\r
420EFIAPI\r
421IsValidFileNameChar (\r
422 IN CONST CHAR16 Ch\r
423 )\r
424{\r
425 //\r
426 // See if there are any illegal characters within the name\r
427 //\r
d16efcae 428 if (Ch < 0x20 || Ch == L'\"' || Ch == L'*' || Ch == L'/' || Ch == L'<' || Ch == L'>' || Ch == L'?' || Ch == L'|') {\r
3737ac2b 429 return FALSE;\r
430 }\r
431\r
432 return TRUE;\r
433}\r
434\r
435/**\r
436 Check if file name has illegal characters.\r
437 \r
438 @param Name The filename to check.\r
439\r
440 @retval TRUE The filename is ok.\r
441 @retval FALSE The filename is not ok.\r
442**/\r
443BOOLEAN\r
444EFIAPI\r
445IsValidFileName (\r
446 IN CONST CHAR16 *Name\r
447 )\r
448{\r
449\r
450 UINTN Index;\r
451 UINTN Len;\r
452\r
453 //\r
454 // check the length of Name\r
455 //\r
456 for (Len = 0, Index = StrLen (Name) - 1; Index + 1 != 0; Index--, Len++) {\r
457 if (Name[Index] == '\\' || Name[Index] == ':') {\r
458 break;\r
459 }\r
460 }\r
461\r
462 if (Len == 0 || Len > 255) {\r
463 return FALSE;\r
464 }\r
465 //\r
466 // check whether any char in Name not appears in valid file name char\r
467 //\r
468 for (Index = 0; Index < StrLen (Name); Index++) {\r
469 if (!IsValidFileNameChar (Name[Index])) {\r
470 return FALSE;\r
471 }\r
5d73d92f 472 }\r
3737ac2b 473\r
474 return TRUE;\r
475}\r
476\r
477/**\r
478 Find a filename that is valid (not taken) with the given extension.\r
479\r
480 @param[in] Extension The file extension.\r
481\r
482 @retval NULL Something went wrong.\r
483 @return the valid filename.\r
484**/\r
485CHAR16 *\r
486EFIAPI\r
487EditGetDefaultFileName (\r
488 IN CONST CHAR16 *Extension\r
489 )\r
490{\r
491 EFI_STATUS Status;\r
492 UINTN Suffix;\r
3737ac2b 493 CHAR16 *FileNameTmp;\r
494\r
495 Suffix = 0;\r
3737ac2b 496\r
497 do {\r
498 FileNameTmp = CatSPrint (NULL, L"NewFile%d.%s", Suffix, Extension);\r
499\r
500 //\r
501 // after that filename changed to path\r
502 //\r
503 Status = ShellFileExists (FileNameTmp);\r
504\r
505 if (Status == EFI_NOT_FOUND) {\r
506 return FileNameTmp;\r
507 }\r
508\r
509 FreePool (FileNameTmp);\r
510 FileNameTmp = NULL;\r
511 Suffix++;\r
512 } while (Suffix != 0);\r
513\r
514 FreePool (FileNameTmp);\r
515 return NULL;\r
5d73d92f 516}\r
517\r
3737ac2b 518/**\r
519 Read a file into an allocated buffer. The buffer is the responsibility \r
520 of the caller to free.\r
521\r
522 @param[in] FileName The filename of the file to open.\r
523 @param[out] Buffer Upon successful return, the pointer to the \r
524 address of the allocated buffer. \r
525 @param[out] BufferSize If not NULL, then the pointer to the size\r
526 of the allocated buffer.\r
527 @param[out] ReadOnly Upon successful return TRUE if the file is\r
528 read only. FALSE otherwise.\r
529\r
530 @retval EFI_NOT_FOUND The filename did not represent a file in the \r
531 file system.\r
532 @retval EFI_SUCCESS The file was read into the buffer.\r
533 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
534 @retval EFI_LOAD_ERROR The file read operation failed.\r
535 @retval EFI_INVALID_PARAMETER A parameter was invalid.\r
536 @retval EFI_INVALID_PARAMETER FileName was NULL.\r
537 @retval EFI_INVALID_PARAMETER FileName was a directory.\r
538**/\r
539EFI_STATUS\r
540EFIAPI\r
541ReadFileIntoBuffer (\r
542 IN CONST CHAR16 *FileName,\r
543 OUT VOID **Buffer,\r
544 OUT UINTN *BufferSize OPTIONAL,\r
545 OUT BOOLEAN *ReadOnly\r
546 )\r
547{\r
548 VOID *InternalBuffer;\r
549 UINTN FileSize;\r
550 SHELL_FILE_HANDLE FileHandle;\r
551 BOOLEAN CreateFile;\r
552 EFI_STATUS Status;\r
553 EFI_FILE_INFO *Info;\r
554\r
555 InternalBuffer = NULL;\r
556 FileSize = 0;\r
557 FileHandle = NULL;\r
558 CreateFile = FALSE;\r
559 Status = EFI_SUCCESS;\r
560 Info = NULL;\r
561\r
562 if (FileName == NULL || Buffer == NULL || ReadOnly == NULL) {\r
563 return (EFI_INVALID_PARAMETER);\r
564 }\r
565\r
566 //\r
567 // try to open the file\r
568 //\r
569 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);\r
570\r
571 if (!EFI_ERROR(Status)) {\r
572 ASSERT(CreateFile == FALSE);\r
573 if (FileHandle == NULL) {\r
574 return EFI_LOAD_ERROR;\r
575 }\r
576\r
577 Info = ShellGetFileInfo(FileHandle);\r
578 \r
579 if (Info->Attribute & EFI_FILE_DIRECTORY) {\r
580 FreePool (Info);\r
581 return EFI_INVALID_PARAMETER;\r
582 }\r
583\r
584 if (Info->Attribute & EFI_FILE_READ_ONLY) {\r
585 *ReadOnly = TRUE;\r
586 } else {\r
587 *ReadOnly = FALSE;\r
588 }\r
589 //\r
590 // get file size\r
591 //\r
592 FileSize = (UINTN) Info->FileSize;\r
593\r
594 FreePool (Info);\r
595 } else if (Status == EFI_NOT_FOUND) {\r
596 //\r
597 // file not exists. add create and try again\r
598 //\r
599 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);\r
600 if (EFI_ERROR (Status)) {\r
601 return Status;\r
602 } else {\r
603 //\r
604 // it worked. now delete it and move on with the name (now validated)\r
605 //\r
606 Status = ShellDeleteFile (&FileHandle);\r
607 if (Status == EFI_WARN_DELETE_FAILURE) {\r
608 Status = EFI_ACCESS_DENIED;\r
609 }\r
610 if (EFI_ERROR (Status)) {\r
611 return Status;\r
612 }\r
613 }\r
614 //\r
615 // file doesn't exist, so set CreateFile to TRUE and can't be read-only\r
616 //\r
617 CreateFile = TRUE;\r
618 *ReadOnly = FALSE;\r
619 }\r
620\r
621 //\r
622 // the file exists\r
623 //\r
624 if (!CreateFile) {\r
625 //\r
626 // allocate buffer to read file\r
627 //\r
628 InternalBuffer = AllocateZeroPool (FileSize);\r
629 if (InternalBuffer == NULL) {\r
630 return EFI_OUT_OF_RESOURCES;\r
631 }\r
632 //\r
633 // read file into InternalBuffer\r
634 //\r
635 Status = ShellReadFile (FileHandle, &FileSize, InternalBuffer);\r
636 ShellCloseFile(&FileHandle);\r
637 FileHandle = NULL;\r
638 if (EFI_ERROR (Status)) {\r
639 SHELL_FREE_NON_NULL (InternalBuffer);\r
640 return EFI_LOAD_ERROR;\r
641 }\r
642 }\r
643 *Buffer = InternalBuffer;\r
644 if (BufferSize != NULL) {\r
645 *BufferSize = FileSize;\r
646 }\r
647 return (EFI_SUCCESS);\r
648\r
649}\r