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