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