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