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 } 645