summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportFile.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportFile.c')
-rw-r--r--src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportFile.c384
1 files changed, 384 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportFile.c b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportFile.c
new file mode 100644
index 00000000..768c43fb
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportFile.c
@@ -0,0 +1,384 @@
+/** @file
+
+Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "Edb.h"
+
+/**
+ Read a file.
+
+ @param Vol - File System Volume
+ @param FileName - The file to be read.
+ @param BufferSize - The file buffer size
+ @param Buffer - The file buffer
+
+ @retval EFI_SUCCESS - read file successfully
+ @retval EFI_NOT_FOUND - file not found
+
+**/
+EFI_STATUS
+EFIAPI
+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;
+}
+
+/**
+
+ Read a file.
+ If ScanFs is FLASE, it will use DebuggerPrivate->Vol as default Fs.
+ If ScanFs is TRUE, it will scan all FS and check the file.
+ If there is only one file match the name, it will be read.
+ If there is more than one file match the name, it will return Error.
+
+ @param DebuggerPrivate - EBC Debugger private data structure
+ @param FileName - The file to be read.
+ @param BufferSize - The file buffer size
+ @param Buffer - The file buffer
+ @param ScanFs - Need Scan all FS
+
+ @retval EFI_SUCCESS - read file successfully
+ @retval EFI_NOT_FOUND - file not found
+ @retval EFI_NO_MAPPING - there is duplicated files found
+
+**/
+EFI_STATUS
+EFIAPI
+ReadFileToBuffer (
+ IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
+ IN CHAR16 *FileName,
+ OUT UINTN *BufferSize,
+ OUT VOID **Buffer,
+ IN BOOLEAN ScanFs
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol;
+ UINTN TempBufferSize;
+ VOID *TempBuffer;
+ UINTN NoHandles;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+
+ //
+ // Check parameters
+ //
+ if ((FileName == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // not scan fs
+ //
+ if (!ScanFs) {
+ if (DebuggerPrivate->Vol == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Read file directly from Vol
+ //
+ return ReadFileFromVol (DebuggerPrivate->Vol, FileName, BufferSize, Buffer);
+ }
+
+ //
+ // need scan fs
+ //
+
+ //
+ // Get all Vol handle
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiSimpleFileSystemProtocolGuid,
+ NULL,
+ &NoHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status) && (NoHandles == 0)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Walk through each Vol
+ //
+ DebuggerPrivate->Vol = NULL;
+ *BufferSize = 0;
+ *Buffer = NULL;
+ for (Index = 0; Index < NoHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiSimpleFileSystemProtocolGuid,
+ (VOID**) &Vol
+ );
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ Status = ReadFileFromVol (Vol, FileName, &TempBufferSize, &TempBuffer);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Read file OK, check duplication
+ //
+ if (DebuggerPrivate->Vol != NULL) {
+ //
+ // Find the duplicated file
+ //
+ gBS->FreePool (TempBuffer);
+ gBS->FreePool (*Buffer);
+ EDBPrint (L"Duplicated FileName found!\n");
+ return EFI_NO_MAPPING;
+ } else {
+ //
+ // Record value
+ //
+ DebuggerPrivate->Vol = Vol;
+ *BufferSize = TempBufferSize;
+ *Buffer = TempBuffer;
+ }
+ }
+ }
+
+ //
+ // Scan Fs done
+ //
+ if (DebuggerPrivate->Vol == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Done
+ //
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Get file name under this dir with index
+
+ @param DebuggerPrivate - EBC Debugger private data structure
+ @param DirName - The dir to be read.
+ @param FileName - The file name pattern under this dir
+ @param Index - The file index under this dir
+
+ @return File Name which match the pattern and index.
+
+**/
+CHAR16 *
+EFIAPI
+GetFileNameUnderDir (
+ IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
+ IN CHAR16 *DirName,
+ IN CHAR16 *FileName,
+ IN OUT UINTN *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,
+ (VOID**) &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 = AllocateZeroPool (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;
+}