https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Hao Wu <hao.a.wu@intel.com> Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
		
			
				
	
	
		
			385 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			385 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @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;
 | |
| }
 |