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