]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c
add more user input verification to connect and vol commands.
[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
59 return (EFI_UNSUPPORTED);\r
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
153EFIAPI\r
154DumpHex (\r
155 IN UINTN Indent,\r
156 IN UINTN Offset,\r
157 IN UINTN DataSize,\r
158 IN VOID *UserData\r
159 )\r
160{\r
161 UINT8 *Data;\r
162\r
163 CHAR8 Val[50];\r
164\r
165 CHAR8 Str[20];\r
166\r
3737ac2b 167 UINT8 TempByte;\r
5d73d92f 168 UINTN Size;\r
169 UINTN Index;\r
170\r
5d73d92f 171 Data = UserData;\r
172 while (DataSize != 0) {\r
173 Size = 16;\r
174 if (Size > DataSize) {\r
175 Size = DataSize;\r
176 }\r
177\r
178 for (Index = 0; Index < Size; Index += 1) {\r
3737ac2b 179 TempByte = Data[Index];\r
180 Val[Index * 3 + 0] = Hex[TempByte >> 4];\r
181 Val[Index * 3 + 1] = Hex[TempByte & 0xF];\r
5d73d92f 182 Val[Index * 3 + 2] = (CHAR8) ((Index == 7) ? '-' : ' ');\r
3737ac2b 183 Str[Index] = (CHAR8) ((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);\r
5d73d92f 184 }\r
185\r
186 Val[Index * 3] = 0;\r
187 Str[Index] = 0;\r
188 ShellPrintEx(-1, -1, L"%*a%02X: %-.48a *%a*\r\n", Indent, "", Offset, Val, Str);\r
189\r
190 Data += Size;\r
191 Offset += Size;\r
192 DataSize -= Size;\r
193 }\r
194}\r
195\r
196/**\r
197 Convert a Unicode character to upper case only if\r
198 it maps to a valid small-case ASCII character.\r
199\r
200 This internal function only deal with Unicode character\r
201 which maps to a valid small-case ASCII character, i.e.\r
202 L'a' to L'z'. For other Unicode character, the input character\r
203 is returned directly.\r
204\r
205 @param Char The character to convert.\r
206\r
207 @retval LowerCharacter If the Char is with range L'a' to L'z'.\r
208 @retval Unchanged Otherwise.\r
209\r
210\r
211 //Stolen from MdePkg Baselib\r
212**/\r
213CHAR16\r
214EFIAPI\r
215CharToUpper (\r
216 IN CHAR16 Char\r
217 )\r
218{\r
219 if (Char >= L'a' && Char <= L'z') {\r
220 return (CHAR16) (Char - (L'a' - L'A'));\r
221 }\r
222\r
223 return Char;\r
224}\r
225\r
226/**\r
227 Function returns a system configuration table that is stored in the\r
228 EFI System Table based on the provided GUID.\r
229\r
230 @param[in] TableGuid A pointer to the table's GUID type.\r
3737ac2b 231 @param[in,out] Table On exit, a pointer to a system configuration table.\r
5d73d92f 232\r
233 @retval EFI_SUCCESS A configuration table matching TableGuid was found.\r
234 @retval EFI_NOT_FOUND A configuration table matching TableGuid was not found.\r
235**/\r
236EFI_STATUS\r
237EFIAPI\r
238GetSystemConfigurationTable (\r
239 IN EFI_GUID *TableGuid,\r
240 IN OUT VOID **Table\r
241 )\r
242{\r
243 UINTN Index;\r
244 ASSERT (Table != NULL);\r
245\r
246 for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {\r
3737ac2b 247 if (CompareGuid (TableGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {\r
5d73d92f 248 *Table = gST->ConfigurationTable[Index].VendorTable;\r
249 return EFI_SUCCESS;\r
250 }\r
251 }\r
252\r
253 return EFI_NOT_FOUND;\r
254}\r
255\r
256/**\r
257 Convert a Unicode character to numerical value.\r
258\r
259 This internal function only deal with Unicode character\r
260 which maps to a valid hexadecimal ASII character, i.e.\r
261 L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other\r
262 Unicode character, the value returned does not make sense.\r
263\r
264 @param Char The character to convert.\r
265\r
266 @return The numerical value converted.\r
267\r
268**/\r
269UINTN\r
270EFIAPI\r
271HexCharToUintn (\r
272 IN CHAR16 Char\r
273 )\r
274{\r
275 if (Char >= L'0' && Char <= L'9') {\r
276 return Char - L'0';\r
277 }\r
278\r
279 return (UINTN) (10 + CharToUpper (Char) - L'A');\r
280}\r
281\r
3737ac2b 282/**\r
283 Convert a string representation of a guid to a Guid value.\r
284\r
285 @param[in] StringGuid The pointer to the string of a guid.\r
286 @param[in,out] Guid The pointer to the GUID structure to populate.\r
287\r
288 @retval EFI_INVALID_PARAMETER A parameter was invalid.\r
289 @retval EFI_SUCCESS The conversion was successful.\r
290**/\r
5d73d92f 291EFI_STATUS\r
292EFIAPI\r
293ConvertStringToGuid (\r
294 IN CONST CHAR16 *StringGuid,\r
295 IN OUT EFI_GUID *Guid\r
296 )\r
297{\r
3737ac2b 298 CHAR16 *TempCopy;\r
299 CHAR16 *TempSpot;\r
300 CHAR16 *Walker;\r
301 UINT64 TempVal;\r
302 EFI_STATUS Status;\r
303\r
304 if (StringGuid == NULL) {\r
305 return (EFI_INVALID_PARAMETER);\r
306 } else if (StrLen(StringGuid) != 36) {\r
5d73d92f 307 return (EFI_INVALID_PARAMETER);\r
3737ac2b 308 } \r
309 TempCopy = NULL;\r
310 TempCopy = StrnCatGrow(&TempCopy, NULL, StringGuid, 0);\r
311 Walker = TempCopy;\r
312 TempSpot = StrStr(Walker, L"-");\r
313 *TempSpot = CHAR_NULL;\r
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
322 *TempSpot = CHAR_NULL;\r
323 Status = ShellConvertStringToUint64(Walker, &TempVal, TRUE, FALSE);\r
324 if (EFI_ERROR(Status)) {\r
325 FreePool(TempCopy);\r
326 return (Status);\r
327 }\r
328 Guid->Data2 = (UINT16)TempVal;\r
329 Walker += 5;\r
330 TempSpot = StrStr(Walker, L"-");\r
331 *TempSpot = CHAR_NULL;\r
332 Status = ShellConvertStringToUint64(Walker, &TempVal, TRUE, FALSE);\r
333 if (EFI_ERROR(Status)) {\r
334 FreePool(TempCopy);\r
335 return (Status);\r
336 }\r
337 Guid->Data3 = (UINT16)TempVal;\r
338 Walker += 5;\r
339 Guid->Data4[0] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
340 Guid->Data4[0] = (UINT8)(Guid->Data4[0]+ (UINT8)HexCharToUintn(Walker[1]));\r
341 Walker += 2;\r
342 Guid->Data4[1] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
343 Guid->Data4[1] = (UINT8)(Guid->Data4[1] + (UINT8)HexCharToUintn(Walker[1]));\r
344 Walker += 3;\r
345 Guid->Data4[2] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
346 Guid->Data4[2] = (UINT8)(Guid->Data4[2] + (UINT8)HexCharToUintn(Walker[1]));\r
347 Walker += 2;\r
348 Guid->Data4[3] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
349 Guid->Data4[3] = (UINT8)(Guid->Data4[3] + (UINT8)HexCharToUintn(Walker[1]));\r
350 Walker += 2;\r
351 Guid->Data4[4] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
352 Guid->Data4[4] = (UINT8)(Guid->Data4[4] + (UINT8)HexCharToUintn(Walker[1]));\r
353 Walker += 2;\r
354 Guid->Data4[5] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
355 Guid->Data4[5] = (UINT8)(Guid->Data4[5] + (UINT8)HexCharToUintn(Walker[1]));\r
356 Walker += 2;\r
357 Guid->Data4[6] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
358 Guid->Data4[6] = (UINT8)(Guid->Data4[6] + (UINT8)HexCharToUintn(Walker[1]));\r
359 Walker += 2;\r
360 Guid->Data4[7] = (UINT8)(HexCharToUintn(Walker[0]) * 16);\r
361 Guid->Data4[7] = (UINT8)(Guid->Data4[7] + (UINT8)HexCharToUintn(Walker[1]));\r
362 FreePool(TempCopy);\r
363 return (EFI_SUCCESS);\r
364}\r
365\r
366CHAR16 TempBufferCatSPrint[1000];\r
367/** \r
368 Appends a formatted Unicode string to a Null-terminated Unicode string\r
369 \r
370 This function appends a formatted Unicode string to the Null-terminated \r
371 Unicode string specified by String. String is optional and may be NULL.\r
372 Storage for the formatted Unicode string returned is allocated using \r
373 AllocateZeroPool(). The pointer to the appended string is returned. The caller\r
374 is responsible for freeing the returned string.\r
375 \r
376 If String is not NULL and not aligned on a 16-bit boundary, then ASSERT().\r
377 If Format is NULL, then ASSERT().\r
378 If Format is not aligned on a 16-bit boundary, then ASSERT().\r
379 \r
380 @param String A null-terminated Unicode string.\r
381 @param FormatString A null-terminated Unicode format string.\r
382 @param ... The variable argument list whose contents are accessed based \r
383 on the format string specified by Format.\r
384\r
385 @retval NULL There was not enough available memory.\r
386 @return Null terminated Unicode string is that is the formatted \r
387 string appended to String.\r
388 @sa CatVSPrint\r
389**/\r
390CHAR16*\r
391EFIAPI\r
392CatSPrint (\r
393 IN CONST CHAR16 *String OPTIONAL,\r
394 IN CONST CHAR16 *FormatString,\r
395 ...\r
396 )\r
397{\r
398 VA_LIST Marker;\r
399 UINTN StringLength;\r
400 if (String != NULL) {\r
401 StrCpy(TempBufferCatSPrint, String);\r
402 } else {\r
403 *TempBufferCatSPrint = CHAR_NULL;\r
404 }\r
405 VA_START (Marker, FormatString);\r
406 StringLength = StrLen(TempBufferCatSPrint);\r
407\r
408 UnicodeVSPrint(TempBufferCatSPrint+StrLen(TempBufferCatSPrint), 1000-StringLength, FormatString, Marker);\r
409 return (AllocateCopyPool(StrSize(TempBufferCatSPrint), TempBufferCatSPrint));\r
410}\r
411\r
412/**\r
413 Clear the line at the specified Row.\r
414 \r
415 @param[in] Row The row number to be cleared ( start from 1 )\r
416 @param[in] LastCol The last printable column.\r
417 @param[in] LastRow The last printable row.\r
418**/\r
419VOID\r
420EFIAPI\r
421EditorClearLine (\r
422 IN UINTN Row,\r
423 IN UINTN LastCol,\r
424 IN UINTN LastRow\r
425 )\r
426{\r
427 CHAR16 Line[200];\r
428\r
429 if (Row == 0) {\r
430 Row = 1;\r
431 }\r
432\r
433 //\r
434 // prepare a blank line\r
435 //\r
436 SetMem16(Line, LastCol*sizeof(CHAR16), L' ');\r
437\r
438 if (Row == LastRow) {\r
439 //\r
440 // if CHAR_NULL is still at position 80, it will cause first line error\r
441 //\r
442 Line[LastCol - 1] = CHAR_NULL;\r
5d73d92f 443 } else {\r
3737ac2b 444 Line[LastCol] = CHAR_NULL;\r
445 }\r
446\r
447 //\r
448 // print out the blank line\r
449 //\r
450 ShellPrintEx (0, ((INT32)Row) - 1, Line);\r
451}\r
452\r
453/**\r
454 Determine if the character is valid for a filename.\r
455\r
456 @param[in] Ch The character to test.\r
457\r
458 @retval TRUE The character is valid.\r
459 @retval FALSE The character is not valid.\r
460**/\r
461BOOLEAN\r
462EFIAPI\r
463IsValidFileNameChar (\r
464 IN CONST CHAR16 Ch\r
465 )\r
466{\r
467 //\r
468 // See if there are any illegal characters within the name\r
469 //\r
470 if (Ch < 0x20 || Ch == L'\"' || Ch == L'*' || Ch == L'/' || Ch == L'<' || Ch == L'>' || Ch == L'?' || Ch == L'|' || Ch == L' ') {\r
471 return FALSE;\r
472 }\r
473\r
474 return TRUE;\r
475}\r
476\r
477/**\r
478 Check if file name has illegal characters.\r
479 \r
480 @param Name The filename to check.\r
481\r
482 @retval TRUE The filename is ok.\r
483 @retval FALSE The filename is not ok.\r
484**/\r
485BOOLEAN\r
486EFIAPI\r
487IsValidFileName (\r
488 IN CONST CHAR16 *Name\r
489 )\r
490{\r
491\r
492 UINTN Index;\r
493 UINTN Len;\r
494\r
495 //\r
496 // check the length of Name\r
497 //\r
498 for (Len = 0, Index = StrLen (Name) - 1; Index + 1 != 0; Index--, Len++) {\r
499 if (Name[Index] == '\\' || Name[Index] == ':') {\r
500 break;\r
501 }\r
502 }\r
503\r
504 if (Len == 0 || Len > 255) {\r
505 return FALSE;\r
506 }\r
507 //\r
508 // check whether any char in Name not appears in valid file name char\r
509 //\r
510 for (Index = 0; Index < StrLen (Name); Index++) {\r
511 if (!IsValidFileNameChar (Name[Index])) {\r
512 return FALSE;\r
513 }\r
5d73d92f 514 }\r
3737ac2b 515\r
516 return TRUE;\r
517}\r
518\r
519/**\r
520 Find a filename that is valid (not taken) with the given extension.\r
521\r
522 @param[in] Extension The file extension.\r
523\r
524 @retval NULL Something went wrong.\r
525 @return the valid filename.\r
526**/\r
527CHAR16 *\r
528EFIAPI\r
529EditGetDefaultFileName (\r
530 IN CONST CHAR16 *Extension\r
531 )\r
532{\r
533 EFI_STATUS Status;\r
534 UINTN Suffix;\r
535 BOOLEAN FoundNewFile;\r
536 CHAR16 *FileNameTmp;\r
537\r
538 Suffix = 0;\r
539 FoundNewFile = FALSE;\r
540\r
541 do {\r
542 FileNameTmp = CatSPrint (NULL, L"NewFile%d.%s", Suffix, Extension);\r
543\r
544 //\r
545 // after that filename changed to path\r
546 //\r
547 Status = ShellFileExists (FileNameTmp);\r
548\r
549 if (Status == EFI_NOT_FOUND) {\r
550 return FileNameTmp;\r
551 }\r
552\r
553 FreePool (FileNameTmp);\r
554 FileNameTmp = NULL;\r
555 Suffix++;\r
556 } while (Suffix != 0);\r
557\r
558 FreePool (FileNameTmp);\r
559 return NULL;\r
5d73d92f 560}\r
561\r
3737ac2b 562/**\r
563 Read a file into an allocated buffer. The buffer is the responsibility \r
564 of the caller to free.\r
565\r
566 @param[in] FileName The filename of the file to open.\r
567 @param[out] Buffer Upon successful return, the pointer to the \r
568 address of the allocated buffer. \r
569 @param[out] BufferSize If not NULL, then the pointer to the size\r
570 of the allocated buffer.\r
571 @param[out] ReadOnly Upon successful return TRUE if the file is\r
572 read only. FALSE otherwise.\r
573\r
574 @retval EFI_NOT_FOUND The filename did not represent a file in the \r
575 file system.\r
576 @retval EFI_SUCCESS The file was read into the buffer.\r
577 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
578 @retval EFI_LOAD_ERROR The file read operation failed.\r
579 @retval EFI_INVALID_PARAMETER A parameter was invalid.\r
580 @retval EFI_INVALID_PARAMETER FileName was NULL.\r
581 @retval EFI_INVALID_PARAMETER FileName was a directory.\r
582**/\r
583EFI_STATUS\r
584EFIAPI\r
585ReadFileIntoBuffer (\r
586 IN CONST CHAR16 *FileName,\r
587 OUT VOID **Buffer,\r
588 OUT UINTN *BufferSize OPTIONAL,\r
589 OUT BOOLEAN *ReadOnly\r
590 )\r
591{\r
592 VOID *InternalBuffer;\r
593 UINTN FileSize;\r
594 SHELL_FILE_HANDLE FileHandle;\r
595 BOOLEAN CreateFile;\r
596 EFI_STATUS Status;\r
597 EFI_FILE_INFO *Info;\r
598\r
599 InternalBuffer = NULL;\r
600 FileSize = 0;\r
601 FileHandle = NULL;\r
602 CreateFile = FALSE;\r
603 Status = EFI_SUCCESS;\r
604 Info = NULL;\r
605\r
606 if (FileName == NULL || Buffer == NULL || ReadOnly == NULL) {\r
607 return (EFI_INVALID_PARAMETER);\r
608 }\r
609\r
610 //\r
611 // try to open the file\r
612 //\r
613 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);\r
614\r
615 if (!EFI_ERROR(Status)) {\r
616 ASSERT(CreateFile == FALSE);\r
617 if (FileHandle == NULL) {\r
618 return EFI_LOAD_ERROR;\r
619 }\r
620\r
621 Info = ShellGetFileInfo(FileHandle);\r
622 \r
623 if (Info->Attribute & EFI_FILE_DIRECTORY) {\r
624 FreePool (Info);\r
625 return EFI_INVALID_PARAMETER;\r
626 }\r
627\r
628 if (Info->Attribute & EFI_FILE_READ_ONLY) {\r
629 *ReadOnly = TRUE;\r
630 } else {\r
631 *ReadOnly = FALSE;\r
632 }\r
633 //\r
634 // get file size\r
635 //\r
636 FileSize = (UINTN) Info->FileSize;\r
637\r
638 FreePool (Info);\r
639 } else if (Status == EFI_NOT_FOUND) {\r
640 //\r
641 // file not exists. add create and try again\r
642 //\r
643 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);\r
644 if (EFI_ERROR (Status)) {\r
645 return Status;\r
646 } else {\r
647 //\r
648 // it worked. now delete it and move on with the name (now validated)\r
649 //\r
650 Status = ShellDeleteFile (&FileHandle);\r
651 if (Status == EFI_WARN_DELETE_FAILURE) {\r
652 Status = EFI_ACCESS_DENIED;\r
653 }\r
654 if (EFI_ERROR (Status)) {\r
655 return Status;\r
656 }\r
657 }\r
658 //\r
659 // file doesn't exist, so set CreateFile to TRUE and can't be read-only\r
660 //\r
661 CreateFile = TRUE;\r
662 *ReadOnly = FALSE;\r
663 }\r
664\r
665 //\r
666 // the file exists\r
667 //\r
668 if (!CreateFile) {\r
669 //\r
670 // allocate buffer to read file\r
671 //\r
672 InternalBuffer = AllocateZeroPool (FileSize);\r
673 if (InternalBuffer == NULL) {\r
674 return EFI_OUT_OF_RESOURCES;\r
675 }\r
676 //\r
677 // read file into InternalBuffer\r
678 //\r
679 Status = ShellReadFile (FileHandle, &FileSize, InternalBuffer);\r
680 ShellCloseFile(&FileHandle);\r
681 FileHandle = NULL;\r
682 if (EFI_ERROR (Status)) {\r
683 SHELL_FREE_NON_NULL (InternalBuffer);\r
684 return EFI_LOAD_ERROR;\r
685 }\r
686 }\r
687 *Buffer = InternalBuffer;\r
688 if (BufferSize != NULL) {\r
689 *BufferSize = FileSize;\r
690 }\r
691 return (EFI_SUCCESS);\r
692\r
693}\r