Beispiel #1
1
/**
  Create a new file or folder in current directory.

  @param FileName              Point to the fileNmae or folder name.
  @param CreateFile            CreateFile== TRUE  means create a new file.
                               CreateFile== FALSE means create a new Folder.

**/
EFI_STATUS
LibCreateNewFile (
  IN CHAR16     *FileName,
  IN BOOLEAN    CreateFile
  )
{
  EFI_FILE_HANDLE      FileHandle;
  EFI_FILE_HANDLE      NewHandle;
  EFI_HANDLE           DeviceHandle;
  EFI_STATUS           Status;
  CHAR16               *ParentName;
  CHAR16               *FullFileName;

  NewHandle = NULL;
  FullFileName = NULL;

  LibGetFileHandleFromDevicePath(gFileExplorerPrivate.RetDevicePath, &FileHandle, &ParentName, &DeviceHandle);
  FullFileName = LibAppendFileName (ParentName, FileName);
  if (FullFileName == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  if (CreateFile) {
    Status = FileHandle->Open(
                          FileHandle,
                          &NewHandle,
                          FullFileName,
                          EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE,
                          0
                          );
    if (EFI_ERROR (Status)) {
      FileHandle->Close (FileHandle);
      return Status;
    }
  } else {
    Status = FileHandle->Open(
                          FileHandle,
                          &NewHandle,
                          FullFileName,
                          EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE,
                          EFI_FILE_DIRECTORY
                          );
    if (EFI_ERROR (Status)) {
      FileHandle->Close (FileHandle);
      return Status;
    }
  }

  FileHandle->Close (FileHandle);

  //
  // Return the DevicePath of the new created file or folder.
  //
  gFileExplorerPrivate.RetDevicePath = FileDevicePath (DeviceHandle, FullFileName);

  return EFI_SUCCESS;

}
Beispiel #2
0
/**
  Open the NvVars file for reading or writing

  @param[in]  FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
  @param[in]  ReadingFile - TRUE: open the file for reading.  FALSE: writing
  @param[out] NvVarsFile - If EFI_SUCCESS is returned, then this is updated
                           with the opened NvVars file.

  @return     EFI_SUCCESS if the file was opened

**/
EFI_STATUS
GetNvVarsFile (
  IN  EFI_HANDLE            FsHandle,
  IN  BOOLEAN               ReadingFile,
  OUT EFI_FILE_HANDLE       *NvVarsFile
  )
{
  EFI_STATUS                            Status;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL       *Fs;
  EFI_FILE_HANDLE                       Root;

  //
  // Get the FileSystem protocol on that handle
  //
  Status = gBS->HandleProtocol (
                  FsHandle,
                  &gEfiSimpleFileSystemProtocolGuid,
                  (VOID **)&Fs
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get the volume (the root directory)
  //
  Status = Fs->OpenVolume (Fs, &Root);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Attempt to open the NvVars file in the root directory
  //
  Status = Root->Open (
                   Root,
                   NvVarsFile,
                   L"NvVars",
                   ReadingFile ?
                     EFI_FILE_MODE_READ :
                     (
                       EFI_FILE_MODE_CREATE |
                       EFI_FILE_MODE_READ |
                       EFI_FILE_MODE_WRITE
                     ),
                   0
                   );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return Status;
}
Beispiel #3
0
/**
  Find the file handle from the input menu info.
  
  @param  MenuEntry        Input Menu info.
  @param  RetFileHandle    Return the file handle for the input device path.
  
  @retval EFI_SUCESS       Find the file handle success.
  @retval Other            Find the file handle failure.
**/
EFI_STATUS
LibGetFileHandleFromMenu (
  IN  MENU_ENTRY                *MenuEntry,  
  OUT EFI_FILE_HANDLE           *RetFileHandle
  )
{
  EFI_FILE_HANDLE Dir;
  EFI_FILE_HANDLE NewDir;
  FILE_CONTEXT    *FileContext;
  EFI_STATUS      Status;

  FileContext   = (FILE_CONTEXT *) MenuEntry->VariableContext;
  Dir           = FileContext->FileHandle;

  //
  // Open current directory to get files from it
  //
  Status = Dir->Open (
                  Dir,
                  &NewDir,
                  FileContext->FileName,
                  EFI_FILE_READ_ONLY,
                  0
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (!FileContext->IsRoot) {
    Dir->Close (Dir);
  }

  *RetFileHandle = NewDir;

  return EFI_SUCCESS;
}
Beispiel #4
0
/**
  Write a file.

  @param[in] FileName        The file to be written.
  @param[in] BufferSize      The file buffer size
  @param[in] Buffer          The file buffer

  @retval EFI_SUCCESS    Write file successfully
**/
EFI_STATUS
WriteFileFromBuffer (
  IN  CHAR16                               *FileName,
  IN  UINTN                                BufferSize,
  IN  VOID                                 *Buffer
  )
{
  EFI_STATUS                        Status;
  EFI_FILE_HANDLE                   RootDir;
  EFI_FILE_HANDLE                   Handle;
  UINTN                             TempBufferSize;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;

  Vol = GetMyVol();
  if (Vol == NULL) {
    return EFI_NOT_FOUND;
  }

  //
  // Open the root directory
  //
  Status = Vol->OpenVolume (Vol, &RootDir);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open the file
  //
  Status = RootDir->Open (
                      RootDir,
                      &Handle,
                      FileName,
                      EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE,
                      0
                      );
  if (EFI_ERROR (Status)) {
    RootDir->Close (RootDir);
    return Status;
  }

  //
  // Delete file
  //
  Status = Handle->Delete(Handle);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Open the file again
  //
  Status = RootDir->Open (
                      RootDir,
                      &Handle,
                      FileName,
                      EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE,
                      0
                      );
  if (EFI_ERROR (Status)) {
    RootDir->Close (RootDir);
    return Status;
  }

  RootDir->Close (RootDir);

  //
  // Write the file data from the buffer
  //
  TempBufferSize = BufferSize;
  Status = Handle->Write (
                     Handle,
                     &TempBufferSize,
                     Buffer
                     );
  if (EFI_ERROR (Status)) {
    Handle->Close (Handle);
    return Status;
  }

  Handle->Close (Handle);

  return EFI_SUCCESS;
}
Beispiel #5
0
EFI_STATUS
GetProtocolAssertion (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath,
  IN CHAR16                       *FilePath,
  OUT UINT32                      *PassNumber,
  OUT UINT32                      *WarnNumber,
  OUT UINT32                      *FailNumber
  )
/*++

Routine Description:

  Get the assertion number of a protocol or service.

Arguments:

  DevicePath    - Device path of the key files.
  FilePath      - Path of the key files.
  PassNumber    - The number of passed assertions.
  WarnNumber    - The number of warning assertions.
  FailNumber    - The number of failed assertions.

Returns:

  EFI_SUCCESS   - Get instance assertion number successfully.

--*/
{
  EFI_STATUS                        Status;
  EFI_HANDLE                        DeviceHandle;
  EFI_FILE_HANDLE                   RootDir;
  EFI_FILE_HANDLE                   LogDir;
  UINTN                             FileInfoSize;
  EFI_FILE_INFO                     *FileInfo;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;
  EFI_DEVICE_PATH_PROTOCOL          *RemainingDevicePath;
  UINTN                             BufferSize;
  CHAR16                            *Buffer;
  CHAR16                            *FileName;
  CHAR16                            *LogName;
  CHAR16                            *TempName;
  CHAR16                            *CaseIndexStr;
  CHAR16                            *CaseIterationStr;

  //
  // Check parameters
  //
  if ((DevicePath == NULL) || (FilePath   == NULL) ||
      (PassNumber == NULL) || (WarnNumber == NULL) ||
      (FailNumber == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Locate the device handle
  //
  RemainingDevicePath = DevicePath;
  Status = BS->LocateDevicePath (
                 &gEfiSimpleFileSystemProtocolGuid,
                 &RemainingDevicePath,
                 &DeviceHandle
                 );
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Locate device path - %r", Status));
    return Status;
  }

  //
  // Locate the simple file system
  //
  Status = BS->HandleProtocol (
                 DeviceHandle,
                 &gEfiSimpleFileSystemProtocolGuid,
                 &Vol
                 );
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Handle protocol - %r", Status));
    return Status;
  }

  //
  // Open the root directory
  //
  Status = Vol->OpenVolume (Vol, &RootDir);
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Open volume - %r", Status));
    return Status;
  }

  //
  // Open the log directory
  //
  Status = RootDir->Open (
                      RootDir,
                      &LogDir,
                      FilePath,
                      EFI_FILE_MODE_READ,
                      EFI_FILE_DIRECTORY
                      );
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Open directory - %r", Status));
    RootDir->Close (RootDir);
    return Status;
  }

  RootDir->Close (RootDir);

  //
  // Allocate memory for the entries in the directory
  //
  FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;

  Status = BS->AllocatePool (
                 EfiBootServicesData,
                 FileInfoSize,
                 &FileInfo
                 );
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Allocate pool - %r", Status));
    LogDir->Close (LogDir);
    return Status;
  }

  //
  // Walk through each file in the directory
  //
  while (TRUE) {
    //
    // Read a file entry
    //
    FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;

    Status = LogDir->Read (
                       LogDir,
                       &FileInfoSize,
                       FileInfo
                       );
    if (EFI_ERROR (Status) || (FileInfoSize == 0)) {
      break;
    }

    if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {
      //
      // This is a file
      //

      //
      // Only deal with the EFI key file
      //
      if (!SctStrEndWith (FileInfo->FileName, L".ekl")) {
        continue;
      }

      //
      // Read the file to a buffer
      //
      FileName = PoolPrint (L"%s\\%s", FilePath, FileInfo->FileName);
      if (FileName == NULL) {
        EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"PoolPrint: Out of resources"));
        return EFI_OUT_OF_RESOURCES;
      }

      Status = ReadFileToBuffer (
                 DevicePath,
                 FileName,
                 &BufferSize,
                 &Buffer
                 );
      if (EFI_ERROR (Status)) {
        EFI_SCT_DEBUG ((EFI_SCT_D_DEBUG, L"Read file to buffer - %r", Status));
        BS->FreePool (FileName);
        continue;
      }

      BS->FreePool (FileName);

      //
      // Get the index and iteration from the file name
      //
      TempName = StrDuplicate (FileInfo->FileName);

      //
      // The following function didn't allocate memory for CaseIndexStr and
      // CaseIterationStr. So DON'T free the TempName before these two strings
      // are still used.
      //
      Status = GetIndexFromFileName (
                 TempName,
                 &CaseIndexStr,
                 &CaseIterationStr
                 );
      if (EFI_ERROR (Status)) {
        EFI_SCT_DEBUG ((EFI_SCT_D_DEBUG, L"Get index from file name - %r", Status));
        BS->FreePool (TempName);
        continue;
      }

      //
      // Load the buffer to the report information structure
      //
      LogName = SctStrEndReplace (FileInfo->FileName, L"log");

      Status = LoadReportInfor (
                 CaseIndexStr,
                 CaseIterationStr,
                 Buffer,
                 LogName
                 );
      if (EFI_ERROR (Status)) {
        EFI_SCT_DEBUG ((EFI_SCT_D_DEBUG, L"Load report infor - %r", Status));
        BS->FreePool (TempName);
        BS->FreePool (LogName);
        BS->FreePool (Buffer);
        continue;
      }

      BS->FreePool (TempName);
      BS->FreePool (LogName);
      BS->FreePool (Buffer);

      //
      // Get the assertion number (free the GUID assertion table)
      //
      Status = GetAssertionNumber (PassNumber, WarnNumber, FailNumber);
      if (EFI_ERROR (Status)) {
        EFI_SCT_DEBUG ((EFI_SCT_D_DEBUG, L"Get assertion number - %r", Status));
        continue;
      }

    } else {
      //
      // This is a directory
      //

      //
      // Skip the '.' and '..' dir
      //
      if ((StrCmp (FileInfo->FileName, L".")  == 0) ||
          (StrCmp (FileInfo->FileName, L"..") == 0)) {
        continue;
      }

      //
      // Get the report information from the sub directories
      //
      FileName = PoolPrint (L"%s\\%s", FilePath, FileInfo->FileName);
      if (FileName == NULL) {
        EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"PoolPrint: Out of resources"));
        return EFI_OUT_OF_RESOURCES;
      }

      Status = GetProtocolAssertion (
                 DevicePath,
                 FileName,
                 PassNumber,
                 WarnNumber,
                 FailNumber
                 );
      if (EFI_ERROR (Status)) {
        EFI_SCT_DEBUG ((EFI_SCT_D_DEBUG, L"Get protocol assertion - %r", Status));
        BS->FreePool (FileName);
        continue;
      }

      BS->FreePool (FileName);
    }
  }

  //
  // Free resources
  //
  BS->FreePool (FileInfo);
  LogDir->Close (LogDir);

  //
  // Done
  //
  return EFI_SUCCESS;
}
Beispiel #6
0
EFI_STATUS
ReadFileFromVol (
  IN  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol,
  IN  CHAR16                      *FileName,
  OUT UINTN                       *BufferSize,
  OUT VOID                        **Buffer
  )
/*++

Routine Description:

  Read a file.
  
Arguments:

  Vol             - File System Volume
  FileName        - The file to be read.
  BufferSize      - The file buffer size
  Buffer          - The file buffer

Returns:

  EFI_SUCCESS    - read file successfully
  EFI_NOT_FOUND  - file not found

--*/
{
  EFI_STATUS                        Status;
  EFI_FILE_HANDLE                   RootDir;
  EFI_FILE_HANDLE                   Handle;
  UINTN                             FileInfoSize;
  EFI_FILE_INFO                     *FileInfo;
  UINTN                             TempBufferSize;
  VOID                              *TempBuffer;

  //
  // Open the root directory
  //
  Status = Vol->OpenVolume (Vol, &RootDir);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open the file
  //
  Status = RootDir->Open (
                      RootDir,
                      &Handle,
                      FileName,
                      EFI_FILE_MODE_READ,
                      0
                      );
  if (EFI_ERROR (Status)) {
    RootDir->Close (RootDir);
    return Status;
  }

  RootDir->Close (RootDir);

  //
  // Get the file information
  //
  FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;

  FileInfo = EfiLibAllocateZeroPool (FileInfoSize);
  if (FileInfo == NULL) {
    Handle->Close (Handle);
    return Status;
  }

  Status = Handle->GetInfo (
                     Handle,
                     &gEfiFileInfoGuid,
                     &FileInfoSize,
                     FileInfo
                     );
  if (EFI_ERROR (Status)) {
    Handle->Close (Handle);
    gBS->FreePool (FileInfo);
    return Status;
  }

  //
  // Allocate buffer for the file data. The last CHAR16 is for L'\0'
  //
  TempBufferSize = (UINTN) FileInfo->FileSize + sizeof(CHAR16);
  TempBuffer = EfiLibAllocateZeroPool (TempBufferSize);
  if (TempBuffer == NULL) {
    Handle->Close (Handle);
    gBS->FreePool (FileInfo);
    return Status;
  }

  gBS->FreePool (FileInfo);

  //
  // Read the file data to the buffer
  //
  Status = Handle->Read (
                     Handle,
                     &TempBufferSize,
                     TempBuffer
                     );
  if (EFI_ERROR (Status)) {
    Handle->Close (Handle);
    gBS->FreePool (TempBuffer);
    return Status;
  }

  Handle->Close (Handle);

  *BufferSize = TempBufferSize;
  *Buffer     = TempBuffer;
  return EFI_SUCCESS;
}
Beispiel #7
0
VOID
EFIAPI
PlatformBdsPolicyBehavior (
  IN OUT LIST_ENTRY                  *DriverOptionList,
  IN OUT LIST_ENTRY                  *BootOptionList,
  IN PROCESS_CAPSULES                ProcessCapsules,
  IN BASEM_MEMORY_TEST               BaseMemoryTest
  )
/*++

Routine Description:

  The function will excute with as the platform policy, current policy
  is driven by boot mode. IBV/OEM can customize this code for their specific
  policy action.

Arguments:

  DriverOptionList - The header of the driver option link list

  BootOptionList   - The header of the boot option link list

  ProcessCapsules  - A pointer to ProcessCapsules()

  BaseMemoryTest   - A pointer to BaseMemoryTest()

Returns:

  None.

--*/
{
  EFI_STATUS                         Status;
  UINT16                             Timeout;
  EFI_EVENT                          UserInputDurationTime;
  LIST_ENTRY                     *Link;
  BDS_COMMON_OPTION                  *BootOption;
  UINTN                              Index;
  EFI_INPUT_KEY                      Key;
  EFI_TPL                            OldTpl;
  EFI_BOOT_MODE                      BootMode;

  VBoxLogFlowFuncEnter();

  ConnectRootBridge ();

  if (PcdGetBool (PcdOvmfFlashVariablesEnable)) {
    DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars "
      "from disk since flash variables appear to be supported.\n"));
  } else {
    //
    // Try to restore variables from the hard disk early so
    // they can be used for the other BDS connect operations.
    //
    PlatformBdsRestoreNvVarsFromHardDisk ();
  }

  //
  // Init the time out value
  //
  Timeout = PcdGet16 (PcdPlatformBootTimeOut);

  //
  // Load the driver option as the driver option list
  //
  PlatformBdsGetDriverOption (DriverOptionList);

  //
  // Get current Boot Mode
  //
  Status = BdsLibGetBootMode (&BootMode);
  DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));

  //
  // Go the different platform policy with different boot mode
  // Notes: this part code can be change with the table policy
  //
  ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);
  //
  // Connect platform console
  //
  Status = PlatformBdsConnectConsole (gPlatformConsole);
  if (EFI_ERROR (Status)) {
    //
    // Here OEM/IBV can customize with defined action
    //
    PlatformBdsNoConsoleAction ();
  }
  //
  // Create a 300ms duration event to ensure user has enough input time to enter Setup
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER,
                  0,
                  NULL,
                  NULL,
                  &UserInputDurationTime
                  );
  ASSERT (Status == EFI_SUCCESS);
  Status = gBS->SetTimer (UserInputDurationTime, TimerRelative, 3000000);
  ASSERT (Status == EFI_SUCCESS);
  //
  // Memory test and Logo show
  //
  PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);

  //
  // Perform some platform specific connect sequence
  //
  PlatformBdsConnectSequence ();

  //
  // Process QEMU's -kernel command line option
  //
  TryRunningQemuKernel ();

  //
  // Give one chance to enter the setup if we
  // have the time out
  //
  if (Timeout != 0) {
    //PlatformBdsEnterFrontPage (Timeout, FALSE);
  }

  DEBUG ((EFI_D_INFO, "BdsLibConnectAll\n"));
  BdsLibConnectAll ();
#ifdef VBOX
    {
        UINTN cFileSystem = 0;
        EFI_HANDLE *phFileSystem = NULL;
        BDS_COMMON_OPTION *BootOption0080 = NULL;
        EFI_STATUS rc = EFI_SUCCESS;
        DEBUG ((EFI_D_INFO, "------------------ VBox Platform Specific Initialization Start -----------------------\n"));
        BootOption0080 = BdsLibVariableToOption(BootOptionList, L"Boot0080");
        if (!BootOption0080)
        {
            rc = gBS->LocateHandleBuffer (ByProtocol,
                                          &gEfiSimpleFileSystemProtocolGuid,
                                          NULL,
                                          &cFileSystem,
                                          &phFileSystem);
            VBoxLogFlowFuncMarkRC(rc);
            VBoxLogFlowFuncMarkVar(cFileSystem, "%d");
            if (   rc == EFI_SUCCESS
                && cFileSystem > 0)
            {
                EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFSVolume;
                EFI_FILE_HANDLE                  hFSRoot;
                EFI_FILE_HANDLE                  hBootEfiFile;
                UINTN iFileSystem = 0;
                /* Ok, we've found several simple file system handles
                 * 1. we should find if '\\System\\Library\\CoreServices\\boot.efi' present
                 * 2. Alter 'BootOrder' to include this file in boot sequence.
                 */
                for (iFileSystem = 0; iFileSystem < cFileSystem; ++iFileSystem)
                {
                    EFI_DEVICE_PATH_PROTOCOL *pDevicePath = NULL;
                    /* mount and look up the boot.efi */
                    rc = gBS->HandleProtocol (phFileSystem[iFileSystem],
                                              &gEfiSimpleFileSystemProtocolGuid,
                                              (VOID *) &pFSVolume);
                    VBoxLogFlowFuncMarkVar(iFileSystem, "%d");
                    VBoxLogFlowFuncMarkRC(rc);
                    if (EFI_ERROR(rc))
                        continue;

                    rc = pFSVolume->OpenVolume(pFSVolume, &hFSRoot);
                    VBoxLogFlowFuncMarkRC(rc);
                    if (EFI_ERROR(rc))
                        continue;

                    rc = hFSRoot->Open(hFSRoot, &hBootEfiFile, L"\\System\\Library\\CoreServices\\boot.efi", EFI_FILE_MODE_READ, 0);
                    VBoxLogFlowFuncMarkRC(rc);
                    if (EFI_ERROR(rc))
                        continue;
                    /* nice file is found and we have to register it */
                    pDevicePath = FileDevicePath(phFileSystem[iFileSystem], L"\\System\\Library\\CoreServices\\boot.efi");
                    VBoxLogFlowFuncMarkVar(pDevicePath,"%p");
                    if (!pDevicePath)
                        continue;
                    rc = BdsLibRegisterNewOption (BootOptionList, pDevicePath, L"Mac Boot", L"BootOrder");
                    VBoxLogFlowFuncMarkRC(rc);
                }
            }
        }
        else
        {
            VBoxLogFlowFuncMarkVar(BootOption0080->LoadOptionsSize, "%d");
            if (BootOption0080->LoadOptionsSize)
                VBoxLogFlowFuncMarkVar(BootOption0080->LoadOptions, "%s");
#if 0
            /* Boot0080 option is found */
            UINT16                    *BootOrder;
            UINTN                     BootOrderSize;
            UINTN                     Index = 0;
            CHAR16                    *BootOptionName;
            ASSERT(BootOption0080->Signature == BDS_LOAD_OPTION_SIGNATURE);
            BootOrder = BdsLibGetVariableAndSize (
                          L"BootOrder",
                          &gEfiGlobalVariableGuid,
                          &BootOrderSize);
            ASSERT(BootOrder);
            BootOptionName = AllocateRuntimePool(256 * sizeof(UINT16));
            UnicodeSPrint(BootOptionName, 256 * sizeof(UINT16), L"Boot%04x", BootOrder[Index]);
            BootOption0080->OptionName = BootOptionName;
            rc = gRT->SetVariable(BootOptionName,
                                  &gEfiGlobalVariableGuid,
                                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                                  sizeof(BDS_COMMON_OPTION),
                                  BootOption0080);
            LogFlowFuncMarkRC(rc);
#if 0
            rc = BdsLibRegisterNewOption (BootOptionList, BootOption0080->DevicePath, L"Mac Boot Temp", L"BootOrder");
#endif
            LogFlowFuncMarkRC(rc);
#endif
        }
        DEBUG ((EFI_D_INFO, "------------------ VBox Platform Specific Initialization End -----------------------\n"));
    }
#endif
  BdsLibEnumerateAllBootOption (BootOptionList);

  SetBootOrderFromQemu (BootOptionList);
  //
  // The BootOrder variable may have changed, reload the in-memory list with
  // it.
  //
  BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");

  //
  // To give the User a chance to enter Setup here, if user set TimeOut is 0.
  // BDS should still give user a chance to enter Setup
  //
  // Connect first boot option, and then check user input before exit
  //
  for (Link = BootOptionList->ForwardLink; Link != BootOptionList;Link = Link->ForwardLink) {
    BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
    if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {
      //
      // skip the header of the link list, becuase it has no boot option
      //
      continue;
    } else {
      //
      // Make sure the boot option device path connected, but ignore the BBS device path
      //
      if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {
        BdsLibConnectDevicePath (BootOption->DevicePath);
      }
      break;
    }
  }

  //
  // Check whether the user input after the duration time has expired
  //
  OldTpl = EfiGetCurrentTpl();
  gBS->RestoreTPL (TPL_APPLICATION);
  gBS->WaitForEvent (1, &UserInputDurationTime, &Index);
  gBS->CloseEvent (UserInputDurationTime);
  Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
  gBS->RaiseTPL (OldTpl);

  if (!EFI_ERROR (Status)) {
    //
    // Enter Setup if user input
    //
    Timeout = 0xffff;
    PlatformBdsEnterFrontPage (Timeout, FALSE);
  }

  VBoxLogFlowFuncLeave();
  return ;
}
Beispiel #8
0
EFI_STATUS
ReadFileToBuffer (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath,
  IN CHAR16                       *FileName,
  OUT UINTN                       *BufferSize,
  OUT VOID                        **Buffer
  )
/*++

Routine Description:

  Read a file.

--*/
{
  EFI_STATUS                        Status;
  EFI_HANDLE                        DeviceHandle;
  EFI_FILE_HANDLE                   RootDir;
  EFI_FILE_HANDLE                   Handle;
  UINTN                             FileInfoSize;
  EFI_FILE_INFO                     *FileInfo;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;
  EFI_DEVICE_PATH_PROTOCOL          *RemainingDevicePath;
  UINTN                             TempBufferSize;
  VOID                              *TempBuffer;

  //
  // Check parameters
  //
  if ((DevicePath == NULL) || (FileName == NULL) || (Buffer == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Locate the device handle
  //
  RemainingDevicePath = DevicePath;
  Status = BS->LocateDevicePath (
                 &gEfiSimpleFileSystemProtocolGuid,
                 &RemainingDevicePath,
                 &DeviceHandle
                 );
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Locate device path - %r", Status));
    return Status;
  }

  //
  // Locate the simple file system
  //
  Status = BS->HandleProtocol (
                 DeviceHandle,
                 &gEfiSimpleFileSystemProtocolGuid,
                 &Vol
                 );
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Handle protocol - %r", Status));
    return Status;
  }

  //
  // Open the root directory
  //
  Status = Vol->OpenVolume (Vol, &RootDir);
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Open volume - %r", Status));
    return Status;
  }

  //
  // Open the file
  //
  Status = RootDir->Open (
                      RootDir,
                      &Handle,
                      FileName,
                      EFI_FILE_MODE_READ,
                      0
                      );
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Open file - %r", Status));
    RootDir->Close (RootDir);
    return Status;
  }

  RootDir->Close (RootDir);

  //
  // Get the file information
  //
  FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;

  Status = BS->AllocatePool (
                 EfiBootServicesData,
                 FileInfoSize,
                 &FileInfo
                 );
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Allocate pool - %r", Status));
    Handle->Close (Handle);
    return Status;
  }

  ZeroMem (FileInfo, FileInfoSize);

  Status = Handle->GetInfo (
                     Handle,
                     &gEfiFileInfoGuid,
                     &FileInfoSize,
                     FileInfo
                     );
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Get file info - %r", Status));
    Handle->Close (Handle);
    BS->FreePool (FileInfo);
    return Status;
  }

  //
  // Allocate buffer for the file data. The last CHAR16 is for L'\0'
  //
  TempBufferSize = (UINTN) FileInfo->FileSize + sizeof(CHAR16);

  Status = BS->AllocatePool (
                 EfiBootServicesData,
                 TempBufferSize,
                 &TempBuffer
                 );
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Allocate pool - %r", Status));
    Handle->Close (Handle);
    BS->FreePool (FileInfo);
    return Status;
  }

  ZeroMem (TempBuffer, TempBufferSize);

  BS->FreePool (FileInfo);

  //
  // Read the file data to the buffer
  //
  Status = Handle->Read (
                     Handle,
                     &TempBufferSize,
                     TempBuffer
                     );
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Read file - %r", Status));
    Handle->Close (Handle);
    BS->FreePool (TempBuffer);
    return Status;
  }

  Handle->Close (Handle);

  *BufferSize = TempBufferSize;
  *Buffer     = TempBuffer;
  return EFI_SUCCESS;
}
Beispiel #9
0
EFIAPI
GetFileBufferByFilePath (
  IN BOOLEAN                           BootPolicy,
  IN CONST EFI_DEVICE_PATH_PROTOCOL    *FilePath,
  OUT      UINTN                       *FileSize,
  OUT UINT32                           *AuthenticationStatus
  )
{
  EFI_DEVICE_PATH_PROTOCOL          *DevicePathNode;
  EFI_DEVICE_PATH_PROTOCOL          *OrigDevicePathNode;
  EFI_DEVICE_PATH_PROTOCOL          *TempDevicePathNode;
  EFI_HANDLE                        Handle;
  EFI_GUID                          *FvNameGuid;
  EFI_FIRMWARE_VOLUME2_PROTOCOL     *FwVol;
  EFI_SECTION_TYPE                  SectionType;
  UINT8                             *ImageBuffer;
  UINTN                             ImageBufferSize;
  EFI_FV_FILETYPE                   Type;
  EFI_FV_FILE_ATTRIBUTES            Attrib;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Volume;
  EFI_FILE_HANDLE                   FileHandle;
  EFI_FILE_HANDLE                   LastHandle;
  EFI_FILE_INFO                     *FileInfo;
  UINTN                             FileInfoSize;
  EFI_LOAD_FILE_PROTOCOL            *LoadFile;
  EFI_LOAD_FILE2_PROTOCOL           *LoadFile2;
  EFI_STATUS                        Status;

  //
  // Check input File device path.
  //
  if (FilePath == NULL || FileSize == NULL || AuthenticationStatus == NULL) {
    return NULL;
  }

  //
  // Init local variable
  //
  TempDevicePathNode  = NULL;
  FvNameGuid          = NULL;
  FileInfo            = NULL;
  FileHandle          = NULL;
  ImageBuffer         = NULL;
  ImageBufferSize     = 0;
  *AuthenticationStatus = 0;
  
  //
  // Copy File Device Path
  //
  OrigDevicePathNode = DuplicateDevicePath (FilePath);
  if (OrigDevicePathNode == NULL) {
    return NULL;
  }

  //
  // Check whether this device path support FV2 protocol.
  // Is so, this device path may contain a Image.
  //
  DevicePathNode = OrigDevicePathNode;
  Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePathNode, &Handle);
  if (!EFI_ERROR (Status)) {
    //
    // For FwVol File system there is only a single file name that is a GUID.
    //
    FvNameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevicePathNode);
    if (FvNameGuid == NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      //
      // Read image from the firmware file
      //
      Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol);
      if (!EFI_ERROR (Status)) {
        SectionType = EFI_SECTION_PE32;
        ImageBuffer = NULL;
        Status = FwVol->ReadSection (
                          FwVol,
                          FvNameGuid,
                          SectionType,
                          0,
                          (VOID **)&ImageBuffer,
                          &ImageBufferSize,
                          AuthenticationStatus
                          );
        if (EFI_ERROR (Status)) {
          //
          // Try a raw file, since a PE32 SECTION does not exist
          //
          if (ImageBuffer != NULL) {
            FreePool (ImageBuffer);
            *AuthenticationStatus = 0;
          }
          ImageBuffer = NULL;
          Status = FwVol->ReadFile (
                            FwVol,
                            FvNameGuid,
                            (VOID **)&ImageBuffer,
                            &ImageBufferSize,
                            &Type,
                            &Attrib,
                            AuthenticationStatus
                            );
        }
      }
    }
    if (!EFI_ERROR (Status)) {
      goto Finish;
    }
  }

  //
  // Attempt to access the file via a file system interface
  //
  DevicePathNode = OrigDevicePathNode;
  Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathNode, &Handle);
  if (!EFI_ERROR (Status)) {
    Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&Volume);
    if (!EFI_ERROR (Status)) {
      //
      // Open the Volume to get the File System handle
      //
      Status = Volume->OpenVolume (Volume, &FileHandle);
      if (!EFI_ERROR (Status)) {
        //
        // Duplicate the device path to avoid the access to unaligned device path node.
        // Because the device path consists of one or more FILE PATH MEDIA DEVICE PATH
        // nodes, It assures the fields in device path nodes are 2 byte aligned.
        //
        TempDevicePathNode = DuplicateDevicePath (DevicePathNode);
        if (TempDevicePathNode == NULL) {
          FileHandle->Close (FileHandle);
          //
          // Setting Status to an EFI_ERROR value will cause the rest of
          // the file system support below to be skipped.
          //
          Status = EFI_OUT_OF_RESOURCES;
        }
        //
        // Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the
        // directory information and filename can be seperate. The goal is to inch
        // our way down each device path node and close the previous node
        //
        DevicePathNode = TempDevicePathNode;
        while (!EFI_ERROR (Status) && !IsDevicePathEnd (DevicePathNode)) {
          if (DevicePathType (DevicePathNode) != MEDIA_DEVICE_PATH ||
              DevicePathSubType (DevicePathNode) != MEDIA_FILEPATH_DP) {
            Status = EFI_UNSUPPORTED;
            break;
          }
  
          LastHandle = FileHandle;
          FileHandle = NULL;
  
          Status = LastHandle->Open (
                                LastHandle,
                                &FileHandle,
                                ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName,
                                EFI_FILE_MODE_READ,
                                0
                                );
  
          //
          // Close the previous node
          //
          LastHandle->Close (LastHandle);
  
          DevicePathNode = NextDevicePathNode (DevicePathNode);
        }
  
        if (!EFI_ERROR (Status)) {
          //
          // We have found the file. Now we need to read it. Before we can read the file we need to
          // figure out how big the file is.
          //
          FileInfo = NULL;
          FileInfoSize = 0;
          Status = FileHandle->GetInfo (
                                FileHandle,
                                &gEfiFileInfoGuid,
                                &FileInfoSize,
                                FileInfo
                                );
  
          if (Status == EFI_BUFFER_TOO_SMALL) {
            FileInfo = AllocatePool (FileInfoSize);
            if (FileInfo == NULL) {
              Status = EFI_OUT_OF_RESOURCES;
            } else {
              Status = FileHandle->GetInfo (
                                    FileHandle,
                                    &gEfiFileInfoGuid,
                                    &FileInfoSize,
                                    FileInfo
                                    );
            }
          }
          
          if (!EFI_ERROR (Status) && (FileInfo != NULL)) {
            //
            // Allocate space for the file
            //
            ImageBuffer = AllocatePool ((UINTN)FileInfo->FileSize);
            if (ImageBuffer == NULL) {
              Status = EFI_OUT_OF_RESOURCES;
            } else {
              //
              // Read the file into the buffer we allocated
              //
              ImageBufferSize = (UINTN)FileInfo->FileSize;
              Status          = FileHandle->Read (FileHandle, &ImageBufferSize, ImageBuffer);
            }
          }
        }
        //
        // Close the file and Free FileInfo and TempDevicePathNode since we are done
        // 
        if (FileInfo != NULL) {
          FreePool (FileInfo);
        }
        if (FileHandle != NULL) {
          FileHandle->Close (FileHandle);
        }
        if (TempDevicePathNode != NULL) {
          FreePool (TempDevicePathNode);
        }
      }
    }
    if (!EFI_ERROR (Status)) {
      goto Finish;
    }
  }

  //
  // Attempt to access the file via LoadFile2 interface
  //
  if (!BootPolicy) {
    DevicePathNode = OrigDevicePathNode;
    Status = gBS->LocateDevicePath (&gEfiLoadFile2ProtocolGuid, &DevicePathNode, &Handle);
    if (!EFI_ERROR (Status)) {
      Status = gBS->HandleProtocol (Handle, &gEfiLoadFile2ProtocolGuid, (VOID**)&LoadFile2);
      if (!EFI_ERROR (Status)) {
        //
        // Call LoadFile2 with the correct buffer size
        //
        ImageBufferSize = 0;
        ImageBuffer     = NULL;
        Status = LoadFile2->LoadFile (
                             LoadFile2,
                             DevicePathNode,
                             FALSE,
                             &ImageBufferSize,
                             ImageBuffer
                             );
        if (Status == EFI_BUFFER_TOO_SMALL) {
          ImageBuffer = AllocatePool (ImageBufferSize);
          if (ImageBuffer == NULL) {
            Status = EFI_OUT_OF_RESOURCES;
          } else {
            Status = LoadFile2->LoadFile (
                                 LoadFile2,
                                 DevicePathNode,
                                 FALSE,
                                 &ImageBufferSize,
                                 ImageBuffer
                                 );
          }
        }
      }
      if (!EFI_ERROR (Status)) {
        goto Finish;
      }
    }
  }

  //
  // Attempt to access the file via LoadFile interface
  //
  DevicePathNode = OrigDevicePathNode;
  Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &DevicePathNode, &Handle);
  if (!EFI_ERROR (Status)) {
    Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID**)&LoadFile);
    if (!EFI_ERROR (Status)) {
      //
      // Call LoadFile with the correct buffer size
      //
      ImageBufferSize = 0;
      ImageBuffer     = NULL;
      Status = LoadFile->LoadFile (
                           LoadFile,
                           DevicePathNode,
                           BootPolicy,
                           &ImageBufferSize,
                           ImageBuffer
                           );
      if (Status == EFI_BUFFER_TOO_SMALL) {
        ImageBuffer = AllocatePool (ImageBufferSize);
        if (ImageBuffer == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
        } else {
          Status = LoadFile->LoadFile (
                               LoadFile,
                               DevicePathNode,
                               BootPolicy,
                               &ImageBufferSize,
                               ImageBuffer
                               );
        }
      }
    }
  }

Finish:

  if (EFI_ERROR (Status)) {
    if (ImageBuffer != NULL) {
      FreePool (ImageBuffer);
      ImageBuffer = NULL;
    }
    *FileSize = 0;
  } else {
    *FileSize = ImageBufferSize;
  }

  FreePool (OrigDevicePathNode);

  return ImageBuffer;
}
Beispiel #10
0
EFI_STATUS
LoadSupportFiles (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath,
  IN CHAR16                       *FilePath,
  IN BOOLEAN                      Recursive,
  OUT EFI_LIST_ENTRY              *SupportFileList
  )
/*++

Routine Description:

  Load all test support files.

Arguments:

  DevicePath      - Device path of the files.
  FilePath        - Path of the files.
  Recursive       - Recursively.
  SupportFileList - Pointer to the support file list.

Returns:

  EFI_SUCCESS     - Successfully.
  Other value     - Something failed.

--*/
{
  EFI_STATUS                        Status;
  EFI_HANDLE                        DeviceHandle;
  EFI_FILE_HANDLE                   RootDir;
  EFI_FILE_HANDLE                   SupportDir;
  CHAR16                            *SubDir;
  CHAR16                            *FileName;
  UINTN                             FileInfoSize;
  EFI_FILE_INFO                     *FileInfo;
  EFI_SCT_TEST_FILE                 *SupportFile;
  EFI_DEVICE_PATH_PROTOCOL          *RemainderPath;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;

  //
  // Check parameters
  //
  if ((DevicePath == NULL) || (FilePath == NULL) || (SupportFileList == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Debug information
  //
  EFI_SCT_DEBUG ((EFI_SCT_D_TRACE, L"Load support files from <%s>", FilePath));

  //
  // Locate the device handle from the device path
  //
  RemainderPath = DevicePath;

  Status = BS->LocateDevicePath (
                 &gEfiSimpleFileSystemProtocolGuid,
                 &RemainderPath,
                 &DeviceHandle
                 );
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Locate device handle - %r", Status));
    return Status;
  }

  //
  // Locate the volume of the file system
  //
  Status = BS->HandleProtocol (
                 DeviceHandle,
                 &gEfiSimpleFileSystemProtocolGuid,
                 &Vol
                 );
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Locate file system - %r", Status));
    return Status;
  }

  //
  // Open the root volume
  //
  Status = Vol->OpenVolume (Vol, &RootDir);
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Open root volume - %r", Status));
    return Status;
  }

  //
  // Open the support directory
  //
  Status = RootDir->Open (
                      RootDir,
                      &SupportDir,
                      FilePath,
                      EFI_FILE_MODE_READ,
                      EFI_FILE_DIRECTORY
                      );
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Open support directory - %r", Status));
    RootDir->Close (RootDir);
    return Status;
  }

  RootDir->Close (RootDir);

  //
  // Allocate memory for the entries in the directory
  //
  FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;

  Status = BS->AllocatePool (
                 EfiBootServicesData,
                 FileInfoSize,
                 &FileInfo
                 );
  if (EFI_ERROR (Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Allocate pool - %r", Status));
    SupportDir->Close (SupportDir);
    return Status;
  }

  //
  // Walk through each file in the directory
  //
  while (TRUE) {
    //
    // Read a file entry
    //
    FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;

    Status = SupportDir->Read (
                           SupportDir,
                           &FileInfoSize,
                           FileInfo
                           );
    if (EFI_ERROR (Status) || (FileInfoSize == 0)) {
      break;
    }

    if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {
      //
      // This is a file
      //
      if (SctStrEndWith (FileInfo->FileName, L".efi")) {
        //
        // Load the support file
        //
        FileName = PoolPrint (L"%s\\%s", FilePath, FileInfo->FileName);
        if (FileName == NULL) {
          EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"PoolPrint: Out of resources"));
          break;
        }

        Status = LoadSingleSupportFile (
                   DevicePath,
                   FileName,
                   &SupportFile
                   );
        if (EFI_ERROR (Status)) {
          EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Load a support file - %r", Status));
          BS->FreePool (FileName);
          continue;
        }

        BS->FreePool (FileName);

        //
        // Add the support file to the support file list
        //
        InsertTailList (SupportFileList, &SupportFile->Link);
      }
    } else {
      //
      // This is a directory
      //
      if (Recursive) {
        //
        // Skip the '.' and '..' dir
        //
        if ((StrCmp (FileInfo->FileName, L".")  == 0) ||
            (StrCmp (FileInfo->FileName, L"..") == 0)) {
          continue;
        }

        //
        // Load the support files under the sub directory
        //
        SubDir = PoolPrint (L"%s\\%s", FilePath, FileInfo->FileName);
        if (SubDir == NULL) {
          EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"PoolPrint: Out of resources"));
          break;
        }

        Status = LoadSupportFiles (
                   DevicePath,
                   SubDir,
                   Recursive,
                   SupportFileList
                   );
        if (EFI_ERROR (Status)) {
          EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Load support files - %r", Status));
          BS->FreePool (SubDir);
          continue;
        }

        BS->FreePool (SubDir);
      }
    }
  }

  //
  // Free resources
  //
  BS->FreePool (FileInfo);
  SupportDir->Close (SupportDir);

  //
  // Done
  //
  return EFI_SUCCESS;
}
Beispiel #11
0
EFI_STATUS
BOpt_FindFiles (
  IN BMM_CALLBACK_DATA          *CallbackData,
  IN BM_MENU_ENTRY              *MenuEntry
  )
/*++

Routine Description
  Find files under current directory
  All files and sub-directories in current directory
  will be stored in DirectoryMenu for future use.

Arguments:
  FileOption   -- Pointer for Dir to explore

Returns:
  TRUE         -- Get files from current dir successfully
  FALSE        -- Can't get files from current dir

--*/
{
  EFI_FILE_HANDLE NewDir;
  EFI_FILE_HANDLE Dir;
  EFI_FILE_INFO   *DirInfo;
  UINTN           BufferSize;
  UINTN           DirBufferSize;
  BM_MENU_ENTRY   *NewMenuEntry;
  BM_FILE_CONTEXT *FileContext;
  BM_FILE_CONTEXT *NewFileContext;
  UINTN           Pass;
  EFI_STATUS      Status;
  UINTN           OptionNumber;

  FileContext   = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;
  Dir           = FileContext->FHandle;
  OptionNumber  = 0;
  //
  // Open current directory to get files from it
  //
  Status = Dir->Open (
                  Dir,
                  &NewDir,
                  FileContext->FileName,
                  EFI_FILE_READ_ONLY,
                  0
                  );
  if (!FileContext->IsRoot) {
    Dir->Close (Dir);
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  DirInfo = EfiLibFileInfo (NewDir);
  if (!DirInfo) {
    return EFI_NOT_FOUND;
  }

  if (!(DirInfo->Attribute & EFI_FILE_DIRECTORY)) {
    return EFI_INVALID_PARAMETER;
  }

  FileContext->DevicePath = EfiFileDevicePath (
                              FileContext->Handle,
                              FileContext->FileName
                              );

  DirBufferSize = sizeof (EFI_FILE_INFO) + 1024;
  DirInfo       = EfiAllocateZeroPool (DirBufferSize);
  if (!DirInfo) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Get all files in current directory
  // Pass 1 to get Directories
  // Pass 2 to get files that are EFI images
  //
  for (Pass = 1; Pass <= 2; Pass++) {
    NewDir->SetPosition (NewDir, 0);
    for (;;) {
      BufferSize  = DirBufferSize;
      Status      = NewDir->Read (NewDir, &BufferSize, DirInfo);
      if (EFI_ERROR (Status) || BufferSize == 0) {
        break;
      }

      if ((DirInfo->Attribute & EFI_FILE_DIRECTORY && Pass == 2) ||
          (!(DirInfo->Attribute & EFI_FILE_DIRECTORY) && Pass == 1)
          ) {
        //
        // Pass 1 is for Directories
        // Pass 2 is for file names
        //
        continue;
      }

      if (!(BOpt_IsEfiImageName (DirInfo->FileName) || DirInfo->Attribute & EFI_FILE_DIRECTORY)) {
        //
        // Slip file unless it is a directory entry or a .EFI file
        //
        continue;
      }

      NewMenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);
      if (NULL == NewMenuEntry) {
        return EFI_OUT_OF_RESOURCES;
      }

      NewFileContext          = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;
      NewFileContext->Handle  = FileContext->Handle;
      NewFileContext->FileName = BOpt_AppendFileName (
                                  FileContext->FileName,
                                  DirInfo->FileName
                                  );
      NewFileContext->FHandle = NewDir;
      NewFileContext->DevicePath = EfiFileDevicePath (
                                    NewFileContext->Handle,
                                    NewFileContext->FileName
                                    );
      NewMenuEntry->HelpString = NULL;

      MenuEntry->DisplayStringToken = GetStringTokenFromDepository (
                                        CallbackData,
                                        FileOptionStrDepository
                                        );

      NewFileContext->IsDir = (BOOLEAN) ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY);

      if (NewFileContext->IsDir) {
        BufferSize                  = EfiStrLen (DirInfo->FileName) * 2 + 6;
        NewMenuEntry->DisplayString = EfiAllocateZeroPool (BufferSize);

        SPrint (
          NewMenuEntry->DisplayString,
          BufferSize,
          L"<%s>",
          DirInfo->FileName
          );

      } else {
        NewMenuEntry->DisplayString = EfiStrDuplicate (DirInfo->FileName);
      }

      NewFileContext->IsRoot            = FALSE;
      NewFileContext->IsLoadFile        = FALSE;
      NewFileContext->IsRemovableMedia  = FALSE;

      NewMenuEntry->OptionNumber        = OptionNumber;
      OptionNumber++;
      InsertTailList (&DirectoryMenu.Head, &NewMenuEntry->Link);
    }
  }

  DirectoryMenu.MenuNumber = OptionNumber;
  SafeFreePool (DirInfo);
  return EFI_SUCCESS;
}
/**
  Find files under the current directory. All files and sub-directories
  in current directory will be stored in DirectoryMenu for future use.

  @param[in] MenuEntry     The Menu Entry.

  @retval EFI_SUCCESS      Get files from current dir successfully.
  @return Other            Can't get files from current dir.

**/
EFI_STATUS
FindFiles (
  IN SECUREBOOT_MENU_ENTRY              *MenuEntry
  )
{
  EFI_FILE_HANDLE           NewDir;
  EFI_FILE_HANDLE           Dir;
  EFI_FILE_INFO             *DirInfo;
  UINTN                     BufferSize;
  UINTN                     DirBufferSize;
  SECUREBOOT_MENU_ENTRY     *NewMenuEntry;
  SECUREBOOT_FILE_CONTEXT   *FileContext;
  SECUREBOOT_FILE_CONTEXT   *NewFileContext;
  UINTN                     Pass;
  EFI_STATUS                Status;
  UINTN                     OptionNumber;

  FileContext   = (SECUREBOOT_FILE_CONTEXT *) MenuEntry->FileContext;
  Dir           = FileContext->FHandle;
  OptionNumber  = 0;
  //
  // Open current directory to get files from it
  //
  Status = Dir->Open (
                  Dir,
                  &NewDir,
                  FileContext->FileName,
                  EFI_FILE_READ_ONLY,
                  0
                  );
  if (!FileContext->IsRoot) {
    Dir->Close (Dir);
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  DirInfo = FileInfo (NewDir);
  if (DirInfo == NULL) {
    return EFI_NOT_FOUND;
  }

  if ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {
    return EFI_INVALID_PARAMETER;
  }

  FileContext->DevicePath = FileDevicePath (
                              FileContext->Handle,
                              FileContext->FileName
                              );

  DirBufferSize = sizeof (EFI_FILE_INFO) + 1024;
  DirInfo       = AllocateZeroPool (DirBufferSize);
  if (DirInfo == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Get all files in current directory
  // Pass 1 to get Directories
  // Pass 2 to get files that are EFI images
  //
  for (Pass = 1; Pass <= 2; Pass++) {
    NewDir->SetPosition (NewDir, 0);
    for (;;) {
      BufferSize  = DirBufferSize;
      Status      = NewDir->Read (NewDir, &BufferSize, DirInfo);
      if (EFI_ERROR (Status) || BufferSize == 0) {
        break;
      }

      if (((DirInfo->Attribute & EFI_FILE_DIRECTORY) != 0 && Pass == 2) ||
          ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == 0 && Pass == 1)
          ) {
        //
        // Pass 1 is for Directories
        // Pass 2 is for file names
        //
        continue;
      }

      NewMenuEntry = CreateMenuEntry ();
      if (NULL == NewMenuEntry) {
        return EFI_OUT_OF_RESOURCES;
      }

      NewFileContext          = (SECUREBOOT_FILE_CONTEXT *) NewMenuEntry->FileContext;
      NewFileContext->Handle  = FileContext->Handle;
      NewFileContext->FileName = AppendFileName (
                                  FileContext->FileName,
                                  DirInfo->FileName
                                  );
      NewFileContext->FHandle = NewDir;
      NewFileContext->DevicePath = FileDevicePath (
                                    NewFileContext->Handle,
                                    NewFileContext->FileName
                                    );
      NewMenuEntry->HelpString = NULL;

      NewFileContext->IsDir = (BOOLEAN) ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY);
      if (NewFileContext->IsDir) {
        BufferSize = StrLen (DirInfo->FileName) * 2 + 6;
        NewMenuEntry->DisplayString = AllocateZeroPool (BufferSize);

        UnicodeSPrint (
          NewMenuEntry->DisplayString,
          BufferSize,
          L"<%s>",
          DirInfo->FileName
          );

      } else {
        NewMenuEntry->DisplayString = StrDuplicate (DirInfo->FileName);
      }

      NewFileContext->IsRoot            = FALSE;
      NewFileContext->IsLoadFile        = FALSE;
      NewFileContext->IsRemovableMedia  = FALSE;

      NewMenuEntry->OptionNumber        = OptionNumber;
      OptionNumber++;
      InsertTailList (&DirectoryMenu.Head, &NewMenuEntry->Link);
    }
  }

  DirectoryMenu.MenuNumber = OptionNumber;
  FreePool (DirInfo);
  return EFI_SUCCESS;
}
Beispiel #13
0
/**
 *  Write a file to floppy disk.
 */
EFI_STATUS
WriteFloppyFile (
  IN CHAR16      *FileName,
  IN OUT UINT32  Length,
  IN VOID        *Buffer
  )
{
  EFI_STATUS                          Status;
  EFI_HANDLE                          DeviceHandle;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL     *Vol;
  EFI_FILE_HANDLE                     RootDir;
  EFI_FILE_HANDLE                     Handle;
  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;
  UINTN                               BufLen;

  //
  // Get floppy device path
  //
  Status = GetFloppyDevicePath (&DevicePath);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  //  Determine device handle for fs protocol on floppy device path
  //
  Status = gtBS->LocateDevicePath (
                   &gEfiSimpleFileSystemProtocolGuid,
                   &DevicePath,
                   &DeviceHandle
                   );
  if (EFI_ERROR(Status) ) {
    return Status;
  }

  //
  //  Determine volume for file system on device handle
  //
  Status = gtBS->HandleProtocol (
                   DeviceHandle,
                   &gEfiSimpleFileSystemProtocolGuid,
                   (VOID*)&Vol
                   );
  if (EFI_ERROR(Status) ) {
    return Status;
  }

  //
  // Open volume for file system on device path
  //
  Status = Vol->OpenVolume (Vol, &RootDir);
  if (Status == EFI_MEDIA_CHANGED) {
    //
    // Reopen the volume
    //
    Status = gtBS->HandleProtocol (
                     DeviceHandle,
                     &gEfiSimpleFileSystemProtocolGuid,
                     (VOID*)&Vol
                     );
    if (EFI_ERROR(Status) ) {
      return Status;
    }
    Status = Vol->OpenVolume (Vol, &RootDir);
  }
  if (EFI_ERROR(Status) ) {
    return Status;
  }

  //
  // Determine the existence of the file
  //
  Status = RootDir->Open (
                      RootDir,
                      &Handle,
                      FileName,
                      EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE,
                      0
                      );
  if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_FOUND)) {
    RootDir->Close (RootDir);
    return Status;
  }

  if (Status == EFI_SUCCESS) {
    //
    // Delete the existent file
    //
    Status = Handle->Delete (Handle);
    if (Status != EFI_SUCCESS) {
      Handle->Close (Handle);
      RootDir->Close (RootDir);
      return Status;
    }
  }

  //
  // Create the file
  //
  Status = RootDir->Open (
                      RootDir,
                      &Handle,
                      FileName,
                      EFI_FILE_MODE_CREATE|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ,
                      0
                      );
  if (EFI_ERROR(Status)) {
    RootDir->Close (RootDir);
    return Status;
  }

  //
  // Write the file
  //
  BufLen = Length;
  Status = Handle->Write (Handle, &BufLen, Buffer);

  Handle->Close (Handle);
  RootDir->Close (RootDir);
  return Status;
}
Beispiel #14
0
/**
 *  Read a file from floppy disk.
 */
EFI_STATUS
ReadFloppyFile (
  IN CHAR16       *FileName,
  OUT UINT32      *Length,
  OUT VOID        **Buffer
  )
{
  EFI_STATUS                          Status;
  EFI_HANDLE                          DeviceHandle;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL     *Vol;
  EFI_FILE_HANDLE                     RootDir;
  EFI_FILE_HANDLE                     Handle;
  EFI_FILE_INFO                       *FileInfo;
  UINTN                               FileInfoSize;
  VOID*                               FileBuffer;
  UINTN                               FileSize;
  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;

  //
  // Get floppy device path
  //
  Status = GetFloppyDevicePath (&DevicePath);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  //  Determine device handle for fs protocol on floppy device path
  //
  Status = gtBS->LocateDevicePath (
                   &gEfiSimpleFileSystemProtocolGuid,
                   &DevicePath,
                   &DeviceHandle
                   );
  if (EFI_ERROR(Status) ) {
    return Status;
  }

  //
  //  Determine volume for file system on device handle
  //
  Status = gtBS->HandleProtocol (
                   DeviceHandle,
                   &gEfiSimpleFileSystemProtocolGuid,
                   (VOID*)&Vol
                   );
  if (EFI_ERROR(Status) ) {
    return Status;
  }

  //
  // Open volume for file system on device path
  //
  Status = Vol->OpenVolume (Vol, &RootDir);
  if (Status == EFI_MEDIA_CHANGED) {
    //
    // Reopen the volume
    //
    Status = gtBS->HandleProtocol (
                     DeviceHandle,
                     &gEfiSimpleFileSystemProtocolGuid,
                     (VOID*)&Vol
                     );
    if (EFI_ERROR(Status) ) {
      return Status;
    }
    Status = Vol->OpenVolume (Vol, &RootDir);
  }
  if (EFI_ERROR(Status) ) {
    return Status;
  }

  //
  // Open file for read
  //
  Status = RootDir->Open (
                      RootDir,
                      &Handle,
                      FileName,
                      EFI_FILE_MODE_READ,
                      0
                      );
  if (EFI_ERROR(Status) ) {
    RootDir->Close (RootDir);
    return Status;
  }


  //
  // Get file size
  //
  FileInfoSize = 1;
  Status = gtBS->AllocatePool (
                   EfiBootServicesData,
                   FileInfoSize,
                   &FileInfo
                   );
  if (EFI_ERROR(Status) ) {
    Handle->Close (Handle);
    RootDir->Close (RootDir);
    return Status;
  }
  //
  // the return code should be EFI_BUFFER_TOO_SMALL
  //
  Status = Handle->GetInfo (
                     Handle,
                     &gEfiFileInfoGuid,
                     &FileInfoSize,
                     FileInfo
                     );

  gtBS->FreePool (FileInfo);
  Status = gtBS->AllocatePool (
                   EfiBootServicesData,
                   FileInfoSize,
                   &FileInfo
                   );
  if (EFI_ERROR(Status) ) {
    Handle->Close (Handle);
    RootDir->Close (RootDir);
    return Status;
  }
  Status = Handle->GetInfo (
                     Handle,
                     &gEfiFileInfoGuid,
                     &FileInfoSize,
                     FileInfo
                     );
  FileSize = (UINTN)FileInfo->FileSize;
  gtBS->FreePool (FileInfo);

  //
  // Read the file
  //
  Status = gtBS->AllocatePool (
                   EfiBootServicesData,
                   FileSize,
                   &FileBuffer
                   );
  if (EFI_ERROR(Status) ) {
    Handle->Close (Handle);
    RootDir->Close (RootDir);
    return Status;
  }
  Status = Handle->Read (
                     Handle,
                     &FileSize,
                     FileBuffer
                     );
  if (EFI_ERROR(Status) ) {
    gtBS->FreePool (FileBuffer);
  } else {
    *Buffer = FileBuffer;
    *Length = (UINT32)FileSize;
  }
  Handle->Close (Handle);
  RootDir->Close (RootDir);
  return Status;
}
Beispiel #15
0
/**
  Get the headers (dos, image, optional header) from an image

  @param  Device                SimpleFileSystem device handle
  @param  FileName              File name for the image
  @param  DosHeader             Pointer to dos header
  @param  Hdr                   The buffer in which to return the PE32, PE32+, or TE header.

  @retval EFI_SUCCESS           Successfully get the machine type.
  @retval EFI_NOT_FOUND         The file is not found.
  @retval EFI_LOAD_ERROR        File is not a valid image file.

**/
EFI_STATUS
EFIAPI
BdsLibGetImageHeader (
  IN  EFI_HANDLE                  Device,
  IN  CHAR16                      *FileName,
  OUT EFI_IMAGE_DOS_HEADER        *DosHeader,
  OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr,
  IN OUT  CHAR16                      **NewFileName
  )
{
  EFI_STATUS                       Status;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Volume;
  EFI_FILE_HANDLE                  Root;
  EFI_FILE_HANDLE                  ThisFile;
  UINTN                            BufferSize;
  UINT64                           FileSize;
  EFI_FILE_INFO                    *Info;
  CHAR16                           *FileName0 = NULL; /*application's file*/

  Root     = NULL;
  ThisFile = NULL;
  //
  // Handle the file system interface to the device
  //
  Status = gBS->HandleProtocol (
                  Device,
                  &gEfiSimpleFileSystemProtocolGuid,
                  (VOID *) &Volume
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Status = Volume->OpenVolume (
                     Volume,
                     &Root
                     );
  if (EFI_ERROR (Status)) {
    Root = NULL;
    goto Done;
  }

  Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0);
  DEBUG((DEBUG_INFO, "%a:%d Open FileName:'%s' - %r \n", __FILE__, __LINE__, FileName, Status));
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // Get file size
  //
  do {
    BufferSize  = 0;
    Info   = NULL;
    /* Get right size we need to allocate */
    Status = ThisFile->GetInfo (
                         ThisFile,
                         &gEfiFileInfoGuid,
                         &BufferSize,
                         Info
                         );
    if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL)
    {
        goto Done;
    }
    Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info);
    if (EFI_ERROR (Status)) {
      goto Done;
    }
    Status = ThisFile->GetInfo (
                         ThisFile,
                         &gEfiFileInfoGuid,
                         &BufferSize,
                         Info
                         );
    if (!EFI_ERROR (Status)) {
      DEBUG((DEBUG_INFO, "%a:%d Open FileName:%s from Info %r \n", __FILE__, __LINE__, Info->FileName, Status));
      Status = gBS->AllocatePool (EfiBootServicesData, StrLen(Info->FileName), (VOID **) &FileName0);
      StrCpy(FileName0, Info->FileName);
      if (EFI_ERROR (Status)) {
        goto Done;
      }
      break;
    }
    if (Status != EFI_BUFFER_TOO_SMALL) {
      FreePool (Info);
      goto Done;
    }
    FreePool (Info);
  } while (TRUE);

  FileSize = Info->FileSize;
  FreePool (Info);

  //
  // Read dos header
  //
#ifndef VBOX
  BufferSize = sizeof (EFI_IMAGE_DOS_HEADER);
  Status = ThisFile->Read (ThisFile, &BufferSize, DosHeader);
  if (EFI_ERROR (Status) ||
      BufferSize < sizeof (EFI_IMAGE_DOS_HEADER) ||
      FileSize <= DosHeader->e_lfanew ||
      DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
    Status = EFI_LOAD_ERROR;
    goto Done;
  }

  //
  // Move to PE signature
  //
  Status = ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew);
  if (EFI_ERROR (Status)) {
    Status = EFI_LOAD_ERROR;
    goto Done;
  }

  //
  // Read and check PE signature
  //
  BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
  Status = ThisFile->Read (ThisFile, &BufferSize, Hdr.Pe32);
  if (EFI_ERROR (Status) ||
      BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) ||
      Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
    Status = EFI_LOAD_ERROR;
    goto Done;
  }

  //
  // Check PE32 or PE32+ magic
  //
  if (Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
      Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
    Status = EFI_LOAD_ERROR;
    goto Done;
  }
#endif
 Done:
  if (!EFI_ERROR(Status))
  {
    EFI_STATUS Status0;
    /* We need prepare the correct file path for case sensitive loaders ... Sigh.*/
    CHAR16 *dup;
    CHAR16 *p, *pp;
    dup = AllocateZeroPool(StrSize(FileName));
    StrCpy(dup, FileName);
    pp = p = dup;
    while (*p != L'\0')
    {
        BufferSize  = 0;
        Info   = NULL;
        if (*p == L'\\' && p != dup)
        {
            *p = L'\0';
            Status0 = Root->Open (Root, &ThisFile, dup, EFI_FILE_MODE_READ, 1);
            DEBUG((DEBUG_INFO, "%a:%d Open FileName:%s - %r \n", __FILE__, __LINE__, dup, Status));
            if (EFI_ERROR (Status)) {
              goto Done;
            }
            /* Get right size we need to allocate */
            Status0 = ThisFile->GetInfo (
                                 ThisFile,
                                 &gEfiFileInfoGuid,
                                 &BufferSize,
                                 Info
                                 );
            if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL)
            {
                DEBUG((DEBUG_INFO, "%a:%d GetInfo(1) FileName:%s %r \n", __FILE__, __LINE__, FileName, Status));
                goto Done;
            }
            Status0 = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info);
            if (EFI_ERROR (Status)) {
              goto Done;
            }
            Status0 = ThisFile->GetInfo (
                                 ThisFile,
                                 &gEfiFileInfoGuid,
                                 &BufferSize,
                                 Info
                                 );
            if (!EFI_ERROR (Status0)) {
              DEBUG((DEBUG_INFO, "%a:%d Open FileName:%s from Info %r \n", __FILE__, __LINE__, Info->FileName, Status));
              StrCpy(pp + 1, Info->FileName);
            }
            * p = L'\\';
            pp = p;
        }
        p++;
    }
    StrCpy(pp + 1, FileName0);
    DEBUG((DEBUG_INFO, "%a:%d NewFileName:'%s'\n", __FILE__, __LINE__, dup));
    *NewFileName = dup;
  }
  DEBUG((DEBUG_INFO, "%a:%d %s - %r\n", __FILE__, __LINE__, FileName, Status));
  if (ThisFile != NULL) {
    ThisFile->Close (ThisFile);
  }
  if (Root != NULL) {
    Root->Close (Root);
  }
  return Status;
}
Beispiel #16
0
/**
Internal work function to fill in EFI_OPEN_FILE information for the Fs and BlkIo

@param  File        Open file handle
@param  FileName    Name of file after device stripped off


**/
EFI_STATUS
EblFileDevicePath (
  IN OUT EFI_OPEN_FILE  *File,
  IN  CHAR8             *FileName,
  IN  CONST UINT64      OpenMode
  )
{
  EFI_STATUS                        Status;
  UINTN                             Size;
  FILEPATH_DEVICE_PATH              *FilePath;
  EFI_DEVICE_PATH_PROTOCOL          *FileDevicePath;
  CHAR16                            UnicodeFileName[MAX_PATHNAME];
  EFI_BLOCK_IO_PROTOCOL             *BlkIo;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Fs;
  EFI_FILE_HANDLE                   Root;


  if ( *FileName != 0 ) {
    AsciiStrToUnicodeStr (FileName, UnicodeFileName);
  } else {
    AsciiStrToUnicodeStr ("\\", UnicodeFileName);
  }

  Size = StrSize (UnicodeFileName);
  FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof (EFI_DEVICE_PATH_PROTOCOL));
  if (FileDevicePath != NULL) {
    FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath;
    FilePath->Header.Type    = MEDIA_DEVICE_PATH;
    FilePath->Header.SubType = MEDIA_FILEPATH_DP;
    CopyMem (&FilePath->PathName, UnicodeFileName, Size);
    SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
    SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));

    if (File->EfiHandle != NULL) {
      File->DevicePath = DevicePathFromHandle (File->EfiHandle);
    }

    File->DevicePath = AppendDevicePath (File->DevicePath, FileDevicePath);
    FreePool (FileDevicePath);
  }

  Status = gBS->HandleProtocol (File->EfiHandle, &gEfiBlockIoProtocolGuid, (VOID **)&BlkIo);
  if (!EFI_ERROR (Status)) {
    File->FsBlockIoMedia = BlkIo->Media;
    File->FsBlockIo = BlkIo;

    // If we are not opening the device this will get over written with file info
    File->MaxPosition = MultU64x32 (BlkIo->Media->LastBlock + 1, BlkIo->Media->BlockSize);
  }

  if (File->Type == EfiOpenFileSystem) {
    Status = gBS->HandleProtocol (File->EfiHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs);
    if (!EFI_ERROR (Status)) {
      Status = Fs->OpenVolume (Fs, &Root);
      if (!EFI_ERROR (Status)) {
        // Get information about the volume
        Size = 0;
        Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo);
        if (Status == EFI_BUFFER_TOO_SMALL) {
          File->FsInfo = AllocatePool (Size);
          Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo);
        }

        // Get information about the file
        Status = Root->Open (Root, &File->FsFileHandle, UnicodeFileName, OpenMode, 0);
        if (!EFI_ERROR (Status)) {
          Size = 0;
          Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, NULL);
          if (Status == EFI_BUFFER_TOO_SMALL) {
            File->FsFileInfo = AllocatePool (Size);
            Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, File->FsFileInfo);
            if (!EFI_ERROR (Status)) {
              File->Size = (UINTN)File->FsFileInfo->FileSize;
              File->MaxPosition = (UINT64)File->Size;
            }
          }
        }

        Root->Close (Root);
      }
    }
  } else if (File->Type == EfiOpenBlockIo) {
    File->Size = (UINTN)File->MaxPosition;
  }

  return Status;
}
Beispiel #17
0
EFI_STATUS
EFIAPI
TOLOpen (
    IN EFI_TEST_OUTPUT_LIBRARY_PROTOCOL       *This,
    IN EFI_DEVICE_PATH_PROTOCOL               *DevicePath,
    IN CHAR16                                 *FileName,
    IN BOOLEAN                                OverwriteFile,
    OUT EFI_FILE                              **FileHandle
)
/*++

Routine Description:

  One interface function of the TestOutputLibrary to open a file.

Arguments:

  This                  - the protocol instance structure.
  DevicePath            - the file's root device path.
  FileName              - the file's name relative to the root.
  OverwriteFile         - whether to overwrite the file.
  FileHandle            - return the file's handle.

Returns:

  EFI_SUCCESS           - open the file successfully.
  EFI_NOT_READY         - to overwrite an opened file is not allowed.
  EFI_OUT_OF_RESOURCES  - not enough memory.

--*/
{
    EFI_STATUS                        Status;
    TEST_OUTPUT_FILE                  *OutputFile;
    TEST_OUTPUT_PRIVATE_DATA          *Private;
    EFI_HANDLE                        DeviceHandle;
    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;
    EFI_FILE_HANDLE                   RootDir;
    EFI_FILE_HANDLE                   Handle;
    UINTN                             BufSize;
    CHAR8                             Buffer[2];
    EFI_DEVICE_PATH_PROTOCOL          *PreDevicePath;

    Private = TEST_OUTPUT_PRIVATE_DATA_FROM_THIS (This);

    //
    // Search the file in OutputFileList to see whether the file has been opened
    //
    OutputFile = Private->OutputFileList;
    while (OutputFile != NULL) {
        if ((SctDevicePathCompare (DevicePath, OutputFile->DevicePath) == 0) &&
                (StrCmp (FileName, OutputFile->FileName)                   == 0)) {
            break;
        }
        OutputFile = OutputFile->Next;
    }

    if (OutputFile == NULL) {
        //
        // Not found, open the file and add to the list
        //

        PreDevicePath = DevicePath;
        //
        //  Determine device handle for fs protocol on specified device path
        //
        Status = BS->LocateDevicePath (
                     &gEfiSimpleFileSystemProtocolGuid,
                     &PreDevicePath,
                     &DeviceHandle
                 );
        if (EFI_ERROR (Status)) {
            return Status;
        }

        //
        //  Determine volume for file system on device handle
        //
        Status = BS->HandleProtocol (
                     DeviceHandle,
                     &gEfiSimpleFileSystemProtocolGuid,
                     (VOID*)&Vol
                 );
        if (EFI_ERROR (Status)) {
            return Status;
        }

        //
        // Open volume for file system on device path
        //
        Status = Vol->OpenVolume (Vol, &RootDir);
        if (EFI_ERROR (Status)) {
            return Status;
        }

        //
        // Determine the existence of the file
        //
        Status = RootDir->Open (
                     RootDir,
                     &Handle,
                     FileName,
                     EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ,
                     0
                 );
        if (Status == EFI_NOT_FOUND) {
            //
            // The file not exist, create it
            //
            Status = SctCreateFile (RootDir, FileName, &Handle);
            if (EFI_ERROR (Status)) {
                RootDir->Close (RootDir);
                return Status;
            }

            //
            // Write the head of Unicode text file
            //
            Buffer[0] = 0xff;
            Buffer[1] = 0xfe;
            BufSize = 2;
            Status = Handle->Write (Handle, &BufSize, Buffer);
            if (EFI_ERROR (Status)) {
                Handle->Close (Handle);
                return Status;
            }
        } else if (EFI_ERROR (Status)) {
            RootDir->Close(RootDir);
            return Status;
        }

        if (OverwriteFile) {
            //
            // Overwrite the file
            //

            //
            // Delete the file
            //
            Status = Handle->Delete (Handle);

            //
            // EFI_FILE.Delete() return a warning status
            //
            if (Status != EFI_SUCCESS) {
                RootDir->Close (RootDir);
                return EFI_UNSUPPORTED;
            }

            //
            // Recreate the file
            //
            Status = RootDir->Open (
                         RootDir,
                         &Handle,
                         FileName,
                         EFI_FILE_MODE_CREATE|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ,
                         0
                     );
            if (EFI_ERROR (Status)) {
                RootDir->Close (RootDir);
                return Status;
            }

            //
            // Write the head of Unicode text file
            //
            Buffer[0] = 0xff;
            Buffer[1] = 0xfe;
            BufSize = 2;
            Status = Handle->Write (Handle, &BufSize, Buffer);
            if (EFI_ERROR (Status)) {
                Handle->Close (Handle);
                return Status;
            }
        } else {
            //
            // Append the file
            //

            //
            // Set position to the end of file
            //
            Status = Handle->SetPosition (Handle, (UINT64)-1);
            if (EFI_ERROR (Status)) {
                RootDir->Close (RootDir);
                return Status;
            }
        }
        RootDir->Close (RootDir);

        //
        // Add the opened file to the OutputFileList
        //
        Status = BS->AllocatePool (
                     EfiBootServicesData,
                     sizeof(TEST_OUTPUT_FILE),
                     (VOID **)&OutputFile
                 );
        if (EFI_ERROR (Status)) {
            Handle->Close (Handle);
            return Status;
        }
        ZeroMem (OutputFile, sizeof(TEST_OUTPUT_FILE));

        OutputFile->DevicePath = DuplicateDevicePath (DevicePath);
        if (OutputFile->DevicePath == NULL) {
            Handle->Close (Handle);
            BS->FreePool (OutputFile);
            return EFI_OUT_OF_RESOURCES;
        }
        OutputFile->FileName = StrDuplicate (FileName);
        if (OutputFile->FileName == NULL) {
            Handle->Close (Handle);
            BS->FreePool (OutputFile->DevicePath);
            BS->FreePool (OutputFile);
            return EFI_OUT_OF_RESOURCES;
        }

        OutputFile->FileHandle = Handle;
        OutputFile->Next = Private->OutputFileList;
        Private->OutputFileList = OutputFile;
    }

    //
    // Add the open count and return the file handle
    //
    OutputFile->OpenCount ++;
    *FileHandle = OutputFile->FileHandle;

    return EFI_SUCCESS;
}
Beispiel #18
0
EFI_STATUS
	EntryPoint (
	EFI_HANDLE ImageHandle,
	EFI_SYSTEM_TABLE* SystemTable
	)
{
	EFI_STATUS Status = 0;
	UINTN i = 0;
	EFI_FILE_IO_INTERFACE *Vol = 0;
	EFI_FILE_HANDLE RootFs = 0;
	EFI_FILE_HANDLE FileHandle = 0;
	EFI_HANDLE* Search = 0;
	EFI_HANDLE DeviceHandle = 0;
	UINTN Size = 0;
	VOID* BootmgrBuffer = 0;
	EFI_FILE_INFO* FileInfoBuffer = 0;
	EFI_HANDLE BootmgrHandle = NULL;
	EFI_LOADED_IMAGE *BootmgrLoadedImage = 0;
	EFI_LOADED_IMAGE *LoadedImage = 0;
	CHAR16 *BOOTMGFW = L"\\EFI\\Microsoft\\BOOT\\BOOTMGFW.EFI";
	CHAR16 *BOOTMGFW_BAK = L"\\EFI\\Microsoft\\BOOT\\BOOTMGFW.BAK";
	EFI_DEVICE_PATH_PROTOCOL* DevPath = 0;

	ST = SystemTable;
	BS = ST->BootServices;
	RS = ST->RuntimeServices;

	Status = Main();

	//=========================================================================//
	// get device handle for the loaded (this) image                           //
	//=========================================================================//

	Status = BS->HandleProtocol(ImageHandle, &gLoadedImageProtocol, (VOID **) &LoadedImage);
	if (EFI_ERROR (Status)) {
		return Status;
	}
	DeviceHandle = LoadedImage->DeviceHandle;

	//=========================================================================//
	// get file io interface for device image was loaded from                  //
	//=========================================================================//

	Status = BS->HandleProtocol(DeviceHandle, &gFileSystemProtocol, (VOID **) &Vol);
	if (EFI_ERROR (Status)) {
		return Status;
	}

	//=========================================================================//
	// open file system root for the device image was loaded from              //
	//=========================================================================//

	Status = Vol->OpenVolume(Vol, &RootFs);
	if (EFI_ERROR (Status)) {
		return Status;
	}

	//=========================================================================//
	// try to open bootmgfw on file system that image was loaded from          //
	//=========================================================================//

	//=========================================================================//
	// look for BOOTMGFW.BAK first to support BOOTMGFW.EFI replacement         //
	// install method.                                                         //
	//=========================================================================//

	Status = RootFs->Open(RootFs, &FileHandle, BOOTMGFW_BAK, EFI_FILE_MODE_READ, 0);
	if (Status == EFI_SUCCESS) {
		BOOTMGFW = BOOTMGFW_BAK;
	}
	else if (Status == EFI_NOT_FOUND) {
		/* if BOOTMGFW.BAK not found search for BOOTMGFW.EFI */
		Status = RootFs->Open(RootFs, &FileHandle, BOOTMGFW, EFI_FILE_MODE_READ, 0);
		if (EFI_ERROR (Status)) {
			RootFs->Close(RootFs);
			switch(Status) {
			case EFI_NOT_FOUND:

				//=========================================================================//
				// failed to find bootmgfw on same device, look for it on other devices.   //
				// get array of device handle's that bootmgfw might be installed on        //
				// first get size of array                                                 //
				//=========================================================================//

				Size = 0;
				Status = BS->LocateHandle(ByProtocol, &gFileSystemProtocol, NULL, &Size, 0);
				if(Status == EFI_BUFFER_TOO_SMALL) {
					/* allocate memory for array */
					Search = (EFI_HANDLE *) AllocatePool(Size);
				}
				if(Search) {
					/* get the array */
					Status = BS->LocateHandle(ByProtocol, &gFileSystemProtocol, NULL, &Size, Search);
					/* loop through handle's open each file system & try to open bootmgfw */
					if(Status == EFI_SUCCESS) {
						for(i = 0; i < Size / sizeof(EFI_HANDLE); i++) {
							/* we already know bootmgfw is not in the same device as the loaded image, skip */
							if(Search[i] == DeviceHandle) {
								continue;
							}
							/* get file io interface */
							Status = BS->HandleProtocol(Search[i], &gFileSystemProtocol, (VOID **) &Vol);
							if(EFI_ERROR (Status)) {
								continue;
							}
							/* open file system root on the device */
							Status = Vol->OpenVolume(Vol, &RootFs);
							if(EFI_ERROR (Status)) {
								continue;
							}
							/* try to open bootmgfw on the file system */
							Status = RootFs->Open(RootFs, &FileHandle, BOOTMGFW, EFI_FILE_MODE_READ, 0);
							if(Status == EFI_SUCCESS) {
								/* found it, set DeviceHandle & break the loop */
								DeviceHandle = Search[i];
								break;
							}
							/* clean up for next pass */
							RootFs->Close(RootFs);
						}
						/* free array of device handles, if EFI_SUCCESS break */
						/* the switch/case else fall through to the error */
						BS->FreePool(Search);
						if(Status == EFI_SUCCESS) {
							break;
						}
					}
				}
			default:
				return Status;
			}
		}
	}
	else {
		return Status;
	}

	//============================================================================//
	// RootFs is open, FileHandle is open, DeviceHandle is set                    //
	// get size of bootmgfw.efi by retriving an EFI_FILE_INFO                     //
	// first get the size of the STRUCT and allocate memory                       //
	//============================================================================//

	Size = 0;
	Status = FileHandle->GetInfo(FileHandle, &gFileInfo, &Size, NULL);
	if(Status == EFI_BUFFER_TOO_SMALL) {
		/* allocate memory for EFI_FILE_INFO */
		FileInfoBuffer = (EFI_FILE_INFO *) AllocatePool(Size);
	} 
	else {
		FileHandle->Close(FileHandle);
		RootFs->Close(RootFs);
		return Status;
	}

	//=========================================================================//
	// get EFI_FILE_INFO for bootmgfw.efi                                      //
	//=========================================================================//

	Status = FileHandle->GetInfo(FileHandle, &gFileInfo, &Size, FileInfoBuffer);
	if(EFI_ERROR(Status)) {
		FileHandle->Close(FileHandle);
		RootFs->Close(RootFs);
		return Status;
	}

	//=========================================================================//
	// get size of bootmgfw.efi                                                //
	//=========================================================================//

	Size = FileInfoBuffer->FileSize;

	//=========================================================================//
	// free EFI_FILE_INFO buffer                                               //
	//=========================================================================//

	BS->FreePool(FileInfoBuffer);

	//=========================================================================//
	// allocate memory for bootmgfw.efi                                        //
	//=========================================================================//

	BootmgrBuffer = AllocatePool(Size);
	if (!BootmgrBuffer) {
		BS->FreePool(BootmgrBuffer);
		FileHandle->Close(FileHandle);
		RootFs->Close(RootFs);
		return Status;
	}

	//=========================================================================//
	// read bootmgfw.efi into buffer                                           //
	//=========================================================================//

	Status = FileHandle->Read(FileHandle, &Size, BootmgrBuffer);
	if (EFI_ERROR (Status)) {
		BS->FreePool(BootmgrBuffer);
		FileHandle->Close(FileHandle);
		RootFs->Close(RootFs);
		return Status;
	}

	//=========================================================================//
	// close handle for bootmgfw.efi                                           //
	//=========================================================================//

	Status = FileHandle->Close(FileHandle);
	if (EFI_ERROR (Status)) {
	}

	//=========================================================================//
	// close handle for file system root                                       //
	//=========================================================================//

	Status = RootFs->Close(RootFs);
	if (EFI_ERROR (Status)) {
	}

	//=========================================================================//
	// load bootmgfw.efi from buffer to execution space                        //
	//=========================================================================//

	Status = BS->LoadImage(FALSE, ImageHandle, 0, BootmgrBuffer, Size, &BootmgrHandle);
	if (EFI_ERROR (Status)) {
		BS->FreePool(BootmgrBuffer);
		return Status;
	}
	BS->FreePool(BootmgrBuffer);

	//=========================================================================//
	// set bootmgfw.efi start variables                                        //
	//=========================================================================//

	Status = BS->HandleProtocol(BootmgrHandle, &gLoadedImageProtocol, (VOID **) &BootmgrLoadedImage);
	if (EFI_ERROR (Status)) {
		return Status;
	}
	BootmgrLoadedImage->DeviceHandle = DeviceHandle;
	BootmgrLoadedImage->ParentHandle = NULL;
	BootmgrLoadedImage->FilePath = FileDevicePath(DeviceHandle, BOOTMGFW);

	//=========================================================================//
	// start bootmgfw.efi execution                                            //
	//=========================================================================//

	Status = BS->StartImage(BootmgrHandle, 0, 0);

	//============================================================================//
	// should never get here show error                                           //
	//============================================================================//

	if (BootmgrHandle != NULL) {
		Status = BS->UnloadImage(BootmgrHandle);
	}
	return Status;
}
Beispiel #19
0
BOOLEAN
FileExist (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath,
  IN CHAR16                       *FileName
  )
/*++

Routine Description:

  Check whether a file exists.

--*/
{
  EFI_STATUS                        Status;
  EFI_HANDLE                        DeviceHandle;
  EFI_FILE_HANDLE                   RootDir;
  EFI_FILE_HANDLE                   Handle;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;
  EFI_DEVICE_PATH_PROTOCOL          *RemainingDevicePath;

  //
  // Check parameters
  //
  if ((DevicePath == NULL) || (FileName == NULL)) {
    return FALSE;
  }

  //
  // Locate the device handle
  //
  RemainingDevicePath = DevicePath;
  Status = BS->LocateDevicePath (
                 &gEfiSimpleFileSystemProtocolGuid,
                 &RemainingDevicePath,
                 &DeviceHandle
                 );
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  //
  // Locate the simple file system
  //
  Status = BS->HandleProtocol (
                 DeviceHandle,
                 &gEfiSimpleFileSystemProtocolGuid,
                 &Vol
                 );
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  //
  // Open the root directory
  //
  Status = Vol->OpenVolume (Vol, &RootDir);
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  //
  // Open the file
  //
  Status = RootDir->Open (
                      RootDir,
                      &Handle,
                      FileName,
                      EFI_FILE_MODE_READ,
                      0
                      );
  if (EFI_ERROR (Status)) {
    RootDir->Close (RootDir);
    return FALSE;
  }

  RootDir->Close (RootDir);
  Handle->Close (Handle);
  return TRUE;
}
Beispiel #20
0
EFI_STATUS
FileOpen (
  IN  EFI_DEVICE_PATH_PROTOCOL   *Device,
  IN  CHAR16                     *MappedFile,
  OUT EFI_FILE_PROTOCOL          **File,
  IN  UINT64                     OpenMode
  )
{  
  EFI_HANDLE                        Handle;
  EFI_FILE_HANDLE                   Root;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Volume;
  EFI_STATUS                        Status;

  *File = NULL;

  Status = gBS->LocateDevicePath (
                  &gEfiSimpleFileSystemProtocolGuid,
                  &Device, 
                  &Handle
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->HandleProtocol (
                  Handle,
                  &gEfiSimpleFileSystemProtocolGuid,
                  &Volume
                  );
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  //
  // Open the root directory of the volume
  //
  Root = NULL;
  Status = Volume->OpenVolume (
                     Volume,
                     &Root
                     );
  ASSERT_EFI_ERROR (Status);
  ASSERT (Root != NULL);

  //
  // Open file
  //
  Status = Root->Open (
                   Root,
                   File,
                   MappedFile,
                   OpenMode,
                   0
                   );
  if (EFI_ERROR (Status)) {
    *File = NULL;
  }

  //
  // Close the Root directory
  //
  Root->Close (Root);
  return Status;
}
Beispiel #21
0
/**
  Get the headers (dos, image, optional header) from an image

  @param  Device                SimpleFileSystem device handle
  @param  FileName              File name for the image
  @param  DosHeader             Pointer to dos header
  @param  Hdr                   The buffer in which to return the PE32, PE32+, or TE header.

  @retval EFI_SUCCESS           Successfully get the machine type.
  @retval EFI_NOT_FOUND         The file is not found.
  @retval EFI_LOAD_ERROR        File is not a valid image file.

**/
EFI_STATUS
EFIAPI
BdsLibGetImageHeader (
  IN  EFI_HANDLE                  Device,
  IN  CHAR16                      *FileName,
  OUT EFI_IMAGE_DOS_HEADER        *DosHeader,
  OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr
  )
{
  EFI_STATUS                       Status;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Volume;
  EFI_FILE_HANDLE                  Root;
  EFI_FILE_HANDLE                  ThisFile;
  UINTN                            BufferSize;
  UINT64                           FileSize;
  EFI_FILE_INFO                    *Info;

  Root     = NULL;
  ThisFile = NULL;
  //
  // Handle the file system interface to the device
  //
  Status = gBS->HandleProtocol (
                  Device,
                  &gEfiSimpleFileSystemProtocolGuid,
                  (VOID *) &Volume
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Status = Volume->OpenVolume (
                     Volume,
                     &Root
                     );
  if (EFI_ERROR (Status)) {
    Root = NULL;
    goto Done;
  }
//  ASSERT (Root != NULL);
  Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0);
  if (EFI_ERROR (Status)) {
    goto Done;
  }
 // ASSERT (ThisFile != NULL);

  //
  // Get file size
  //
  BufferSize  = SIZE_OF_EFI_FILE_INFO + 200;
  do {
    Info   = NULL;
    Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info);
    if (EFI_ERROR (Status)) {
      goto Done;
    }
    Status = ThisFile->GetInfo (
                         ThisFile,
                         &gEfiFileInfoGuid,
                         &BufferSize,
                         Info
                         );
    if (!EFI_ERROR (Status)) {
      break;
    }
    if (Status != EFI_BUFFER_TOO_SMALL) {
      FreePool (Info);
      goto Done;
    }
    FreePool (Info);
  } while (TRUE);

  FileSize = Info->FileSize;
  FreePool (Info);

  //
  // Read dos header
  //
  BufferSize = sizeof (EFI_IMAGE_DOS_HEADER);
  Status = ThisFile->Read (ThisFile, &BufferSize, DosHeader);
  if (EFI_ERROR (Status) ||
      BufferSize < sizeof (EFI_IMAGE_DOS_HEADER) ||
      FileSize <= DosHeader->e_lfanew ||
      DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
    Status = EFI_LOAD_ERROR;
    goto Done;
  }

  //
  // Move to PE signature
  //
  Status = ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew);
  if (EFI_ERROR (Status)) {
    Status = EFI_LOAD_ERROR;
    goto Done;
  }

  //
  // Read and check PE signature
  //
  BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
  Status = ThisFile->Read (ThisFile, &BufferSize, Hdr.Pe32);
  if (EFI_ERROR (Status) ||
      BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) ||
      Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
    Status = EFI_LOAD_ERROR;
    goto Done;
  }

  //
  // Check PE32 or PE32+ magic
  //
  if (Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
      Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
    Status = EFI_LOAD_ERROR;
    goto Done;
  }

 Done:
  if (ThisFile != NULL) {
    ThisFile->Close (ThisFile);
  }
  if (Root != NULL) {
    Root->Close (Root);
  }
  return Status;
}
Beispiel #22
0
EFI_STATUS
EFIAPI
TrlReadResetRecord (
  IN EFI_TEST_RECOVERY_LIBRARY_PROTOCOL     *This,
  OUT UINTN                                 *Size,
  OUT VOID                                  *Buffer
  )
/*++

Routine Description:

  One interface function of the TestRecoveryLibrary to read reset record.

Arguments:

  This        - the protocol instance structure.
  Size        - return the bytes been read.
  Buffer      - buffer to store the record, it can't less than 1024Bytes.

Returns:

  EFI_SUCCESS           - read the record successfully.
  EFI_INVALID_PARAMETER - invalid parameters.

--*/
{
  EFI_STATUS                          Status;
  EFI_HANDLE                          DeviceHandle;
  EFI_FILE_HANDLE                     RootDir;
  EFI_FILE_HANDLE                     Handle;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL     *Vol;
  TEST_RECOVERY_PRIVATE_DATA          *Private;
  EFI_DEVICE_PATH_PROTOCOL            *PreDevicePath;

  Private = TEST_RECOVERY_PRIVATE_DATA_FROM_TRL (This);

  //
  //  Determine device handle for fs protocol on specified device path
  //
  PreDevicePath = Private->DevicePath;
  Status = gBS->LocateDevicePath (
                  &gEfiSimpleFileSystemProtocolGuid,
                  &PreDevicePath,
                  &DeviceHandle
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  //  Determine volume for file system on device handle
  //
  Status = gBS->HandleProtocol (
                  DeviceHandle,
                  &gEfiSimpleFileSystemProtocolGuid,
                  (VOID*)&Vol
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open volume for file system on device path
  //
  Status = Vol->OpenVolume (Vol, &RootDir);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open file for read
  //
  Status = RootDir->Open (
                      RootDir,
                      &Handle,
                      Private->FileName,
                      EFI_FILE_MODE_READ,
                      0
                      );
  if (EFI_ERROR (Status)) {
    RootDir->Close (RootDir);
    return Status;
  }

  *Size = MAX_BUFFER_SIZE;
  Status = Handle->Read (Handle, Size, Buffer);
  Handle->Close (Handle);
  RootDir->Close (RootDir);
  return Status;
}
Beispiel #23
0
CHAR16 *
GetFileNameUnderDir (
  IN  EFI_DEBUGGER_PRIVATE_DATA   *DebuggerPrivate,
  IN  CHAR16                      *DirName,
  IN  CHAR16                      *FileName,
  IN OUT UINTN                    *Index
  )
/*++

Routine Description:

  Get file name under this dir with index
  
Arguments:

  DebuggerPrivate - EBC Debugger private data structure
  DirName         - The dir to be read.
  FileName        - The file name pattern under this dir
  Index           - The file index under this dir

Returns:

  File Name which match the pattern and index.

--*/
{
  EFI_STATUS                        Status;
  EFI_FILE_HANDLE                   RootDir;
  EFI_FILE_HANDLE                   Handle;
  UINTN                             FileInfoSize;
  EFI_FILE_INFO                     *FileInfo;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;
  VOID                              *TempName;
  UINTN                             FileIndex;

  if (DebuggerPrivate->Vol == NULL) {
    Status = gBS->LocateProtocol (
                    &gEfiSimpleFileSystemProtocolGuid,
                    NULL,
                    &DebuggerPrivate->Vol
                    );
    if (EFI_ERROR(Status)) {
      return NULL;
    }
  }
  Vol = DebuggerPrivate->Vol;

  //
  // Open the root directory
  //
  Status = Vol->OpenVolume (Vol, &RootDir);
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  //
  // Open the file
  //
  Status = RootDir->Open (
                      RootDir,
                      &Handle,
                      DirName,
                      EFI_FILE_MODE_READ,
                      EFI_FILE_DIRECTORY
                      );
  if (EFI_ERROR (Status)) {
    RootDir->Close (RootDir);
    return NULL;
  }
  RootDir->Close (RootDir);

  //
  // Set Dir Position
  //
  Status = Handle->SetPosition (Handle, 0);
  if (EFI_ERROR (Status)) {
    Handle->Close (Handle);
    return NULL;
  }

  //
  // Get the file information
  //
  FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;

  FileInfo = EfiLibAllocateZeroPool (FileInfoSize);
  if (FileInfo == NULL) {
    Handle->Close (Handle);
    return NULL;
  }

  //
  // Walk through each file in the directory
  //
  FileIndex = 0;
  TempName = NULL;
  while (TRUE) {
    //
    // Read a file entry
    //
    FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;

    Status = Handle->Read (
                       Handle,
                       &FileInfoSize,
                       FileInfo
                       );
    if (EFI_ERROR (Status) || (FileInfoSize == 0)) {
      break;
    }

    if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {
      //
      // This is a file
      //

      //
      // Only deal with the EFI key file
      //
      if (!StrEndWith (FileInfo->FileName, FileName)) {
        continue;
      }

      if (FileIndex == *Index) {
        TempName = StrDuplicate (FileInfo->FileName);
        *Index = *Index + 1;
        break;
      }
      FileIndex ++;
    }
  }

  //
  // Free resources
  //
  gBS->FreePool (FileInfo);
  Handle->Close (Handle);

  return TempName;
}
Beispiel #24
0
EFI_STATUS
EFIAPI
TrlWriteResetRecord (
  IN EFI_TEST_RECOVERY_LIBRARY_PROTOCOL     *This,
  IN UINTN                                  Size,
  IN VOID                                   *Buffer
  )
/*++

Routine Description:

  One interface function of the TestRecoveryLibrary to write reset record.

Arguments:

  This        - the protocol instance structure.
  Size        - the bytes to be write, it can't bigger than 1024Bytes.
  Buffer      - buffer contain the record to be written.

Returns:

  EFI_SUCCESS           - write the record successfully.
  EFI_INVALID_PARAMETER - invalid parameters.

--*/
{
  EFI_STATUS                          Status;
  EFI_HANDLE                          DeviceHandle;
  EFI_FILE_HANDLE                     RootDir;
  EFI_FILE_HANDLE                     Handle;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL     *Vol;
  TEST_RECOVERY_PRIVATE_DATA          *Private;
  EFI_DEVICE_PATH_PROTOCOL            *PreDevicePath;

  Private = TEST_RECOVERY_PRIVATE_DATA_FROM_TRL (This);

  //
  //  Determine device handle for fs protocol on specified device path
  //
  PreDevicePath = Private->DevicePath;
  Status = gBS->LocateDevicePath (
                  &gEfiSimpleFileSystemProtocolGuid,
                  &PreDevicePath,
                  &DeviceHandle
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  //  Determine volume for file system on device handle
  //
  Status = gBS->HandleProtocol (
                  DeviceHandle,
                  &gEfiSimpleFileSystemProtocolGuid,
                  (VOID*)&Vol
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open volume for file system on device path
  //
  Status = Vol->OpenVolume (Vol, &RootDir);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open file for read
  //
  Status = RootDir->Open (
                      RootDir,
                      &Handle,
                      Private->FileName,
                      EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE,
                      0
                      );
  if (Status == EFI_NOT_FOUND) {
    //
    // The file not exist, create it
    //
    Status = RootDir->Open (
                        RootDir,
                        &Handle,
                        Private->FileName,
                        EFI_FILE_MODE_CREATE|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ,
                        0
                        );
    if (EFI_ERROR (Status)) {
      RootDir->Close (RootDir);
      return Status;
    }
  } else if (Status == EFI_SUCCESS) {
    //
    // The file exist, delete it
    //
    Status = Handle->Delete (Handle);
    //
    // EFI_FILE.Delete() return a warning status
    //
    if (Status != EFI_SUCCESS) {
      Handle->Close (Handle);
      RootDir->Close (RootDir);
      return EFI_UNSUPPORTED;
    }

    //
    // Recreate the file
    //
    Status = RootDir->Open (
                        RootDir,
                        &Handle,
                        Private->FileName,
                        EFI_FILE_MODE_CREATE|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ,
                        0
                        );
    if (EFI_ERROR (Status)) {
      RootDir->Close (RootDir);
      return Status;
    }
  } else {
    RootDir->Close (RootDir);
    return Status;
  }

  //
  // Write buffer
  //
  Status = Handle->Write (Handle, &Size, Buffer);
  Handle->Close (Handle);
  RootDir->Close (RootDir);
  return Status;
}
Beispiel #25
0
/**
  Function to get a full filename given a EFI_FILE_HANDLE somewhere lower on the
  directory 'stack'. If the file is a directory, then append the '\' char at the 
  end of name string. If it's not a directory, then the last '\' should not be 
  added.

  if Handle is NULL, return EFI_INVALID_PARAMETER

  @param[in] Handle             Handle to the Directory or File to create path to.
  @param[out] FullFileName      pointer to pointer to generated full file name.  It
                                is the responsibility of the caller to free this memory
                                with a call to FreePool().
  @retval EFI_SUCCESS           the operation was sucessful and the FullFileName is valid.
  @retval EFI_INVALID_PARAMETER Handle was NULL.
  @retval EFI_INVALID_PARAMETER FullFileName was NULL.
  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.
**/
EFI_STATUS
EFIAPI
FileHandleGetFileName (
  IN CONST EFI_FILE_HANDLE      Handle,
  OUT CHAR16                    **FullFileName
  )
{
  EFI_STATUS      Status;
  UINTN           Size;
  EFI_FILE_HANDLE CurrentHandle;
  EFI_FILE_HANDLE NextHigherHandle;
  EFI_FILE_INFO   *FileInfo;

  Size = 0;

  //
  // Check our parameters
  //
  if (FullFileName == NULL || Handle == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  *FullFileName = NULL;
  CurrentHandle = NULL;

  Status = Handle->Open(Handle, &CurrentHandle, L".", EFI_FILE_MODE_READ, 0);
  if (!EFI_ERROR(Status)) {
    //
    // Reverse out the current directory on the device
    //
    for (;;) {
      FileInfo = FileHandleGetInfo(CurrentHandle);
      if (FileInfo == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        break;
      } else {
        //
        // We got info... do we have a name? if yes precede the current path with it...
        //
        if (StrLen (FileInfo->FileName) == 0) {
          if (*FullFileName == NULL) {
            ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));
            *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);
          }
          FreePool(FileInfo);
          break;
        } else {
          if (*FullFileName == NULL) {
            ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));
            *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);
          }
          ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));
          *FullFileName = StrnCatGrowLeft(FullFileName, &Size, FileInfo->FileName, 0);
          *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);
          FreePool(FileInfo);
        }
      }
      //
      // Move to the parent directory
      //
      Status = CurrentHandle->Open (CurrentHandle, &NextHigherHandle, L"..", EFI_FILE_MODE_READ, 0);
      if (EFI_ERROR (Status)) {
        break;
      }

      FileHandleClose(CurrentHandle);
      CurrentHandle = NextHigherHandle;
    }
  } else if (Status == EFI_NOT_FOUND) {
    Status = EFI_SUCCESS;
    ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));
    *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);
  }

  if (*FullFileName != NULL && 
      (*FullFileName)[StrLen(*FullFileName) - 1] == L'\\' && 
      StrLen(*FullFileName) > 1 &&
      FileHandleIsDirectory(Handle) == EFI_NOT_FOUND
     ) {
    (*FullFileName)[StrLen(*FullFileName) - 1] = CHAR_NULL;
  }

  if (CurrentHandle != NULL) {
    CurrentHandle->Close (CurrentHandle);
  }

  if (EFI_ERROR(Status) && *FullFileName != NULL) {
    FreePool(*FullFileName);
  }

  return (Status);
}
Beispiel #26
0
/**
  Read a file from this volume.

  @param[in]  Vol             File System Volume
  @param[in]  FileName        The file to be read.
  @param[out] BufferSize      The file buffer size
  @param[out] Buffer          The file buffer

  @retval EFI_SUCCESS    Read file successfully
  @retval EFI_NOT_FOUND  File not found
**/
EFI_STATUS
ReadFileFromVol (
  IN  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol,
  IN  CHAR16                            *FileName,
  OUT UINTN                             *BufferSize,
  OUT VOID                              **Buffer
  )
{
  EFI_STATUS                        Status;
  EFI_FILE_HANDLE                   RootDir;
  EFI_FILE_HANDLE                   Handle;
  UINTN                             FileInfoSize;
  EFI_FILE_INFO                     *FileInfo;
  UINTN                             TempBufferSize;
  VOID                              *TempBuffer;

  //
  // Open the root directory
  //
  Status = Vol->OpenVolume (Vol, &RootDir);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open the file
  //
  Status = RootDir->Open (
                      RootDir,
                      &Handle,
                      FileName,
                      EFI_FILE_MODE_READ,
                      0
                      );
  if (EFI_ERROR (Status)) {
    RootDir->Close (RootDir);
    return Status;
  }

  RootDir->Close (RootDir);

  //
  // Get the file information
  //
  FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;

  FileInfo = AllocateZeroPool (FileInfoSize);
  if (FileInfo == NULL) {
    Handle->Close (Handle);
    return Status;
  }

  Status = Handle->GetInfo (
                     Handle,
                     &gEfiFileInfoGuid,
                     &FileInfoSize,
                     FileInfo
                     );
  if (EFI_ERROR (Status)) {
    Handle->Close (Handle);
    gBS->FreePool (FileInfo);
    return Status;
  }

  //
  // Allocate buffer for the file data. The last CHAR16 is for L'\0'
  //
  TempBufferSize = (UINTN) FileInfo->FileSize + sizeof(CHAR16);
  TempBuffer = AllocateZeroPool (TempBufferSize);
  if (TempBuffer == NULL) {
    Handle->Close (Handle);
    gBS->FreePool (FileInfo);
    return Status;
  }

  gBS->FreePool (FileInfo);

  //
  // Read the file data to the buffer
  //
  Status = Handle->Read (
                     Handle,
                     &TempBufferSize,
                     TempBuffer
                     );
  if (EFI_ERROR (Status)) {
    Handle->Close (Handle);
    gBS->FreePool (TempBuffer);
    return Status;
  }

  Handle->Close (Handle);

  *BufferSize = TempBufferSize;
  *Buffer     = TempBuffer;
  return EFI_SUCCESS;
}
Beispiel #27
0
/**
  Find the file handle from the input device path info.
  
  @param  RootDirectory    Device path info.
  @param  RetFileHandle    Return the file handle for the input device path.
  @param  ParentFileName   Parent file name.
  @param  DeviceHandle     Driver handle for this partition.
  
  @retval EFI_SUCESS       Find the file handle success.
  @retval Other            Find the file handle failure.
**/
EFI_STATUS
LibGetFileHandleFromDevicePath (
  IN  EFI_DEVICE_PATH_PROTOCOL  *RootDirectory,  
  OUT EFI_FILE_HANDLE           *RetFileHandle,
  OUT UINT16                    **ParentFileName,
  OUT EFI_HANDLE                *DeviceHandle
  )
{
  EFI_DEVICE_PATH_PROTOCOL          *DevicePathNode;
  EFI_DEVICE_PATH_PROTOCOL          *TempDevicePathNode;
  EFI_STATUS                        Status;
  EFI_HANDLE                        Handle;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Volume;
  EFI_FILE_HANDLE                   FileHandle;
  EFI_FILE_HANDLE                   LastHandle;
  CHAR16                            *TempPath;

  *ParentFileName = NULL;

  //
  // Attempt to access the file via a file system interface
  //
  DevicePathNode = RootDirectory;
  Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathNode, &Handle);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&Volume);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  //
  // Open the Volume to get the File System handle
  //
  Status = Volume->OpenVolume (Volume, &FileHandle);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  *DeviceHandle = Handle;

  if (IsDevicePathEnd(DevicePathNode)) {
    *ParentFileName = AllocateCopyPool (StrSize (L"\\"), L"\\");
    *RetFileHandle = FileHandle;
    return EFI_SUCCESS;
  }
  
  //
  // Duplicate the device path to avoid the access to unaligned device path node.
  // Because the device path consists of one or more FILE PATH MEDIA DEVICE PATH
  // nodes, It assures the fields in device path nodes are 2 byte aligned.
  //
  TempDevicePathNode = DuplicateDevicePath (DevicePathNode);
  if (TempDevicePathNode == NULL) {

    //
    // Setting Status to an EFI_ERROR value will cause the rest of
    // the file system support below to be skipped.
    //
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }
        
  //
  // Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the
  // directory information and filename can be seperate. The goal is to inch
  // our way down each device path node and close the previous node
  //
  DevicePathNode = TempDevicePathNode;
  while (!EFI_ERROR (Status) && !IsDevicePathEnd (DevicePathNode)) {
    if (DevicePathType (DevicePathNode) != MEDIA_DEVICE_PATH ||
        DevicePathSubType (DevicePathNode) != MEDIA_FILEPATH_DP) {
      Status = EFI_UNSUPPORTED;
      goto Done;
    }

    LastHandle = FileHandle;
    FileHandle = NULL;

    Status = LastHandle->Open (
                          LastHandle,
                          &FileHandle,
                          ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName,
                          EFI_FILE_MODE_READ,
                          0
                          );
    if (*ParentFileName == NULL) {
      *ParentFileName = AllocateCopyPool (StrSize (((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName), ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName);
    } else {
      TempPath = LibAppendFileName (*ParentFileName, ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName);
      if (TempPath == NULL) {
        LastHandle->Close (LastHandle);
        Status = EFI_OUT_OF_RESOURCES;
        goto Done;
      }
      FreePool (*ParentFileName);
      *ParentFileName = TempPath;
    }

    //
    // Close the previous node
    //
    LastHandle->Close (LastHandle);

    DevicePathNode = NextDevicePathNode (DevicePathNode);
  }

  if (EFI_ERROR (Status)) {
    goto Done;
  }

  *RetFileHandle = FileHandle;

  Status = EFI_SUCCESS;

Done:
  if (TempDevicePathNode != NULL) {
    FreePool (TempDevicePathNode);
  }

  if ((FileHandle != NULL) && (EFI_ERROR (Status))) {
    FileHandle->Close (FileHandle);
  }

  return Status;
}
Beispiel #28
0
/**
  Entrypoint of Acpi Platform driver.

  @param  ImageHandle
  @param  SystemTable

  @return EFI_SUCCESS
  @return EFI_LOAD_ERROR
  @return EFI_OUT_OF_RESOURCES

**/
EFI_STATUS
EFIAPI
AcpiPlatformEntryPoint (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
	EFI_STATUS                      Status;
	EFI_ACPI_TABLE_PROTOCOL         *AcpiTable;
//	INTN                            Instance;
//	EFI_ACPI_COMMON_HEADER          *CurrentTable;
	EFI_ACPI_COMMON_HEADER			*oldDSDT;
	UINTN                           TableHandle;
	UINTN                           TableSize;
//	UINTN                           Size;
#if READTABLES	
	UINTN							Index;
	CHAR16*							FileName;
#if LIP	
	EFI_LOADED_IMAGE_PROTOCOL		*LoadedImage;
#endif	
	VOID							*FileBuffer;
//	VOID**							TmpHandler;
	UINT64							FileSize;
	UINTN							BufferSize;
//	UINTN							Key;
	EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
	EFI_FILE_INFO                   *Info;
	EFI_FILE_HANDLE                 Root = NULL;
	EFI_FILE_HANDLE                 ThisFile = NULL;
#endif	
	EFI_PHYSICAL_ADDRESS			*Acpi20;
	EFI_PEI_HOB_POINTERS			GuidHob;
	EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;
//	EFI_ACPI_DESCRIPTION_HEADER *Rsdt, *Xsdt;
//	EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;
	EFI_ACPI_DESCRIPTION_HEADER		*Table;
	SIGNAT							Signature;
//	EFI_ACPI_TABLE_INSTANCE			*AcpiInstance;

  Msg = NULL;
  Status = gBS->LocateProtocol(&gMsgLogProtocolGuid, NULL, (VOID **) &Msg);
  if (!EFI_ERROR(Status) && (Msg != NULL)) {
    msgCursor = Msg->Cursor;
    BootLog("MsgLog Protocol installed in AcpiPlatform\n");
 }

	//
	// Find the AcpiTable protocol
	//
	Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable);
	if (EFI_ERROR (Status)) {
		return EFI_ABORTED;
	}
#if DEBUG_ACPI
	AcpiInstance = EFI_ACPI_TABLE_INSTANCE_FROM_THIS(AcpiTable);
	DBG(L"Rsdp1 %x\n", AcpiInstance->Rsdp1);
	DBG(L"Rsdp3 %x\n", AcpiInstance->Rsdp3);
	DBG(L"Rsdt1 %x\n", AcpiInstance->Rsdt1);
	DBG(L"Rsdt3 %x\n", AcpiInstance->Rsdt3);
	DBG(L"Xsdt  %x\n", AcpiInstance->Xsdt);
	DBG(L"Fadt1 %x\n", AcpiInstance->Fadt1);
	DBG(L"Fadt3 %x\n", AcpiInstance->Fadt3);
#endif	
//	Instance     = 0;
//	CurrentTable = NULL;
	TableHandle  = 0;
	
	GuidHob.Raw = GetFirstGuidHob (&gEfiAcpiTableGuid);
	if (GuidHob.Raw == NULL) {
		GuidHob.Raw = GetFirstGuidHob (&gEfiAcpi10TableGuid);
		if (GuidHob.Raw == NULL) {
			return EFI_ABORTED;
		}
		//Slice: TODO if we found only Acpi1.0 we need to convert it to Acpi2.0
		// like I did in Chameleon
	}
	Acpi20 = GET_GUID_HOB_DATA (GuidHob.Guid);
	if (Acpi20 == NULL) {
		return EFI_ABORTED;
	}
	Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)*Acpi20;	
	DBG(L"Rsdp @ %x\n", (UINTN)Rsdp);
	DBG(L"Rsdt @ %x\n", (UINTN)(Rsdp->RsdtAddress));
	DBG(L"Xsdt @ %x\n", (UINTN)(Rsdp->XsdtAddress));
	
	InstallLegacyTables(AcpiTable, Rsdp);
//	DBG(L"LegacyTables installed\n");
	oldDSDT = (EFI_ACPI_COMMON_HEADER*)(UINTN)Fadt->Dsdt;
	DBG(L"Fadt @ %x\n", (UINTN)Fadt);
	DBG(L"oldDSDT @ %x\n", (UINTN)oldDSDT);
	
#if READTABLES
#if LIP	
//  Looking for a volume from what we boot
	
/*	TODO - look for a volume we want to boot System
	it is possible if we fix in BdsBoot.c 
	gRT->SetVariable (
		L"BootCurrent",
		&gEfiGlobalVariableGuid,
		EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
			sizeof (UINT16),
		&Option->BootCurrent
	);
 gRT->GetVariable (
		L"BootNext",
		&gEfiGlobalVariableGuid,
		EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
		0,
		&BootNext
		);
 and extract DevicePath from BootNext - first available :(
 In Gui.efi we can repeat this patch with DSDT.aml loaded from another place
 */
	
	Status = gBS->HandleProtocol (
								  ImageHandle,
								  &gEfiLoadedImageProtocolGuid,
								  (VOID*)&LoadedImage
								  );
	if (EFI_ERROR (Status)) {
		return EFI_ABORTED;
	}
	Status = gBS->HandleProtocol (
								  LoadedImage->DeviceHandle,
								  &gEfiSimpleFileSystemProtocolGuid,
								  (VOID *) &Volume
								  );
	if (EFI_ERROR (Status)) {
		return EFI_ABORTED;
	}

	//		DBG(L"Volume found\n");
	//
	// Open the root directory of the volume
	//
	if (!EFI_ERROR (Status)) {
		Status = Volume->OpenVolume (Volume, &Root);
	}
#else //Multiple FS protocols
	EFI_HANDLE            *mFs = NULL;
	UINTN                 mFsCount = 0;
	// mFsInfo[] array entries must match mFs[] handles
	EFI_FILE_SYSTEM_INFO  **mFsInfo = NULL;
	
	gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &mFsCount, &mFs);
	mFsInfo = AllocateZeroPool (mFsCount * sizeof (EFI_FILE_SYSTEM_INFO *));
	if (mFsInfo == NULL) {
		// If we can't do this then we can't support file system entries
		mFsCount = 0;
	} else {
		// Loop through all the file system structures and cache the file system info data
		for (Index =0; Index < mFsCount; Index++) {
			Status = gBS->HandleProtocol (mFs[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Volume);
			if (!EFI_ERROR (Status)) {
				Status = Volume->OpenVolume (Volume, &Root);
				if (!EFI_ERROR (Status)) {
					// Get information about the volume
/*					Size = 0;
					Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]);
					if (Status == EFI_BUFFER_TOO_SMALL) {
						mFsInfo[Index] = AllocatePool (Size);
						Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]);
					}
*/					
//					Root->Close (Root);
					break; //I will stop at first volume
					//TODO try to find DSDT in all volumes
				}
			}
		}
  }
#endif	
	FileName = AllocateZeroPool(32); //Should be enough
	//
	// Read tables from the first volume.
	//
	for (Index=0; Index<NUM_TABLES; Index++) {
		StrCpyS(FileName, 32, ACPInames[Index]);
//		DBG(L"File probe %s\n", FileName);
		Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0);
		if (EFI_ERROR (Status)) {
			continue;
		}
		/* Get right size we need to allocate */
		Status = ThisFile->GetInfo (
									ThisFile,
									&gEfiFileInfoGuid,
									&BufferSize,
									Info
									);
		if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) {
			continue;
		}
		DBG(L"Buffer size %d\n", BufferSize);
		//		DBG(L"GetInfo success!\n");
		Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info);
		if (EFI_ERROR (Status)) {
			//			DBG(L"No pool!\n");
			continue;
		}
		Status = ThisFile->GetInfo (
									ThisFile,
									&gEfiFileInfoGuid,
									&BufferSize,
									Info
									);
		FileSize = Info->FileSize;
//				DBG(L"FileSize = %d!\n", FileSize);
		gBS->FreePool (Info);
//Slice - this is the problem. 		
//		FileBuffer = AllocatePool(FileSize);
		Status = gBS->AllocatePool (EfiBootServicesData, FileSize, (VOID **) &FileBuffer);
		if (EFI_ERROR (Status)) {
			//			DBG(L"No pool for FileBuffer size %d!\n", FileSize);
			continue;
		}
/*		Status = gBS->AllocatePages (
									 AllocateMaxAddress,
									 EfiACPIMemoryNVS,
									 EFI_SIZE_TO_PAGES(FileSize),
									 FileBuffer
									 );
		if (EFI_ERROR (Status)) {
			//			DBG(L"No pool for FileBuffer size %d!\n", FileSize);
			continue;
		}
*/		
		
//should use ACPI memory
//		Status=gBS->AllocatePages(AllocateMaxAddress,
//					EfiACPIReclaimMemory,RoundPage(FileSize)/EFI_PAGE_SIZE, FileBuffer);
		DBG(L"FileBuffer @ %x\n", (UINTN)FileBuffer);
		
		Status = ThisFile->Read (ThisFile, &FileSize, FileBuffer); //(VOID**)&
//		DBG(L"FileRead status=%x\n", 	Status);	
		if (!EFI_ERROR(Status)) {
			//
			// Add the table
			//
//			TableHandle = 0;
			if (ThisFile != NULL) {
				ThisFile->Close (ThisFile); //close file before use buffer?! Flush?!
			}
			
//			DBG(L"FileRead success: %c%c%c%c\n",
//				  ((CHAR8*)FileBuffer)[0], ((CHAR8*)FileBuffer)[1], ((CHAR8*)FileBuffer)[2], ((CHAR8*)FileBuffer)[3]);
			TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) FileBuffer)->Length;
			//ASSERT (BufferSize >= TableSize);
			DBG(L"Table size=%d\n", TableSize);
			if (FileSize < TableSize) {
				//Data incorrect. What TODO? Quick fix
//				((EFI_ACPI_DESCRIPTION_HEADER *) FileBuffer)->Length = FileSize;
//				TableSize = FileSize;
				DBG(L"Table size > file size :(\n");
				continue; //do nothing with broken table
			}			
			//
			// Checksum ACPI table
			//
			AcpiPlatformChecksum ((UINT8*)FileBuffer, TableSize);			
			if ((Index==0) && oldDSDT) {  //DSDT always at index 0
				if (((EFI_ACPI_DESCRIPTION_HEADER *) oldDSDT)->Length > TableSize) {
					CopyMem(oldDSDT, FileBuffer, TableSize);
					DBG(L"New DSDT copied to old place\n");
				}
			}		
			//
			// Install ACPI table
			//
			//TmpHandler = &FileBuffer;
				Status = AcpiTable->InstallAcpiTable (
													  AcpiTable,
													  FileBuffer,
													  TableSize,
													  &TableHandle
													  );

			DBG(L"Table install status=%x\n", 	Status);
			if (EFI_ERROR(Status)) {
				continue;
			}
//			DBG(L"Table installed #%d\n", Index);
			//
			// Increment the instance
			//
//			Instance++;   //for a what?
			FileBuffer = NULL;
			
		} else if (oldDSDT && (Index==0)) {
			//if new DSDT not found then install legacy one
			Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(Fadt->Dsdt));
			TableSize = Table->Length;
			Signature.Sign = Table->Signature;
			DBG(L"Install legacy table: %c%c%c%c\n", 
				  Signature.ASign[0], Signature.ASign[1], Signature.ASign[2], Signature.ASign[3]);
			
			Status = AcpiTable->InstallAcpiTable (
												  AcpiTable,
												  Table,
												  TableSize,
												  &TableHandle
												  );
		}
	}
	if (Root != NULL) {
		Root->Close (Root);
	}
#else
//just install legacy tables
	if (oldDSDT) {
		//if new DSDT not found then install legacy one
		Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(Fadt->Dsdt));
		TableSize = Table->Length;
		Signature.Sign = Table->Signature;
		DBG(L"Install legacy table: %c%c%c%c\n", 
			Signature.ASign[0], Signature.ASign[1], Signature.ASign[2], Signature.ASign[3]);
		
		/*Status = */AcpiTable->InstallAcpiTable (
											  AcpiTable,
											  Table,
											  TableSize,
											  &TableHandle
											  );
	}	
	
#endif	
#if DEBUG_ACPI==2
  gBS->Stall(5000000);
#endif

	return EFI_SUCCESS;
}