blob: 617a5a844ff0cdb428c2f76f94117fb4fca94cdc [file] [log] [blame]
/*++
Copyright (c) 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
EdbSupportFile.c
Abstract:
--*/
#include "Edb.h"
EFI_STATUS
EFIAPI
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 = 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;
}
EFI_STATUS
EFIAPI
ReadFileToBuffer (
IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
IN CHAR16 *FileName,
OUT UINTN *BufferSize,
OUT VOID **Buffer,
IN BOOLEAN ScanFs
)
/*++
Routine Description:
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.
Arguments:
DebuggerPrivate - EBC Debugger private data structure
FileName - The file to be read.
BufferSize - The file buffer size
Buffer - The file buffer
ScanFs - Need Scan all FS
Returns:
EFI_SUCCESS - read file successfully
EFI_NOT_FOUND - file not found
EFI_NO_MAPPING - there is duplicated files found
--*/
{
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;
}
CHAR16 *
EFIAPI
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,
(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;
}