git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			517 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			517 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*++
 | 
						|
 | 
						|
Copyright (c) 2006, 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:
 | 
						|
 | 
						|
  FwVolRead.c
 | 
						|
 | 
						|
Abstract:
 | 
						|
 | 
						|
  Implements read firmware file
 | 
						|
 | 
						|
--*/
 | 
						|
 | 
						|
#include <DxeMain.h>
 | 
						|
 | 
						|
/*++
 | 
						|
 | 
						|
Required Alignment    Alignment Value in FFS       Alignment Value in
 | 
						|
(bytes)                        Attributes Field               Firmware Volume Interfaces
 | 
						|
1                                    0                                     0
 | 
						|
2                                    0                                     1
 | 
						|
4                                    0                                     2
 | 
						|
8                                    0                                     3
 | 
						|
16                                   1                                     4
 | 
						|
128                                  2                                     7
 | 
						|
512                                  3                                     9
 | 
						|
1 KB                                 4                                     10
 | 
						|
4 KB                                 5                                     12
 | 
						|
32 KB                                6                                     15
 | 
						|
64 KB                                7                                     16
 | 
						|
 | 
						|
--*/
 | 
						|
 | 
						|
UINT8 mFvAttributes[] = {0, 4, 7, 9, 10, 12, 15, 16}; 
 | 
						|
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_FV_FILE_ATTRIBUTES
 | 
						|
FfsAttributes2FvFileAttributes (
 | 
						|
  IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
  Routine Description:
 | 
						|
    Convert the FFS File Attributes to FV File Attributes
 | 
						|
    
 | 
						|
  Arguments:
 | 
						|
    FfsAttributes   -   The attributes of UINT8 type.
 | 
						|
    
 | 
						|
  Returns:
 | 
						|
    The attributes of EFI_FV_FILE_ATTRIBUTES
 | 
						|
    
 | 
						|
--*/
 | 
						|
{
 | 
						|
  FfsAttributes = (EFI_FFS_FILE_ATTRIBUTES)((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3);
 | 
						|
  ASSERT (FfsAttributes < 8);
 | 
						|
 | 
						|
  return (EFI_FV_FILE_ATTRIBUTES) mFvAttributes[FfsAttributes];
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
FvGetNextFile (
 | 
						|
  IN         EFI_FIRMWARE_VOLUME_PROTOCOL   *This,
 | 
						|
  IN OUT     VOID                            *Key,
 | 
						|
  IN OUT     EFI_FV_FILETYPE                *FileType,
 | 
						|
  OUT        EFI_GUID                      *NameGuid,
 | 
						|
  OUT        EFI_FV_FILE_ATTRIBUTES        *Attributes,
 | 
						|
  OUT        UINTN                           *Size
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
    Given the input key, search for the next matching file in the volume.
 | 
						|
 | 
						|
Arguments:
 | 
						|
    This          -   Indicates the calling context.
 | 
						|
    FileType      -   FileType is a pointer to a caller allocated
 | 
						|
                      EFI_FV_FILETYPE. The GetNextFile() API can filter it's
 | 
						|
                      search for files based on the value of *FileType input.
 | 
						|
                      A *FileType input of 0 causes GetNextFile() to search for
 | 
						|
                      files of all types.  If a file is found, the file's type
 | 
						|
                      is returned in *FileType.  *FileType is not modified if
 | 
						|
                      no file is found.
 | 
						|
    Key           -   Key is a pointer to a caller allocated buffer that
 | 
						|
                      contains implementation specific data that is used to
 | 
						|
                      track where to begin the search for the next file.
 | 
						|
                      The size of the buffer must be at least This->KeySize
 | 
						|
                      bytes long. To reinitialize the search and begin from
 | 
						|
                      the beginning of the firmware volume, the entire buffer
 | 
						|
                      must be cleared to zero. Other than clearing the buffer
 | 
						|
                      to initiate a new search, the caller must not modify the
 | 
						|
                      data in the buffer between calls to GetNextFile().
 | 
						|
    NameGuid      -   NameGuid is a pointer to a caller allocated EFI_GUID.
 | 
						|
                      If a file is found, the file's name is returned in
 | 
						|
                      *NameGuid.  *NameGuid is not modified if no file is
 | 
						|
                      found.
 | 
						|
    Attributes    -   Attributes is a pointer to a caller allocated
 | 
						|
                      EFI_FV_FILE_ATTRIBUTES.  If a file is found, the file's
 | 
						|
                      attributes are returned in *Attributes. *Attributes is
 | 
						|
                      not modified if no file is found.
 | 
						|
    Size          -   Size is a pointer to a caller allocated UINTN.
 | 
						|
                      If a file is found, the file's size is returned in *Size.
 | 
						|
                      *Size is not modified if no file is found.
 | 
						|
 | 
						|
Returns:
 | 
						|
    EFI_SUCCESS                 - Successfully find the file.
 | 
						|
    EFI_DEVICE_ERROR            - Device error.
 | 
						|
    EFI_ACCESS_DENIED           - Fv could not read.
 | 
						|
    EFI_NOT_FOUND               - No matching file found.
 | 
						|
    EFI_INVALID_PARAMETER       - Invalid parameter
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS                                  Status;
 | 
						|
  FV_DEVICE                                   *FvDevice;
 | 
						|
  EFI_FV_ATTRIBUTES                           FvAttributes;
 | 
						|
  EFI_FFS_FILE_HEADER                         *FfsFileHeader;
 | 
						|
  UINTN                                       *KeyValue;
 | 
						|
  LIST_ENTRY                                  *Link;
 | 
						|
  FFS_FILE_LIST_ENTRY                         *FfsFileEntry;
 | 
						|
  UINTN                                       FileLength;
 | 
						|
 | 
						|
  FvDevice = FV_DEVICE_FROM_THIS (This);
 | 
						|
 | 
						|
  Status = FvGetVolumeAttributes (This, &FvAttributes);
 | 
						|
  if (EFI_ERROR (Status)){
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Check if read operation is enabled
 | 
						|
  //
 | 
						|
  if ((FvAttributes & EFI_FV_READ_STATUS) == 0) {
 | 
						|
    return EFI_ACCESS_DENIED;
 | 
						|
  }
 | 
						|
 | 
						|
  if (*FileType > EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
 | 
						|
    //
 | 
						|
    // File type needs to be in 0 - 0x0B
 | 
						|
    //
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  KeyValue = (UINTN *)Key;
 | 
						|
  for (;;) {
 | 
						|
    if (*KeyValue == 0) {
 | 
						|
      //
 | 
						|
      // Search for 1st matching file
 | 
						|
      //
 | 
						|
      Link = &FvDevice->FfsFileListHeader;
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // Key is pointer to FFsFileEntry, so get next one
 | 
						|
      //
 | 
						|
      Link = (LIST_ENTRY *)(*KeyValue);
 | 
						|
    }
 | 
						|
 | 
						|
    if (Link->ForwardLink == &FvDevice->FfsFileListHeader) {
 | 
						|
      //
 | 
						|
      // Next is end of list so we did not find data
 | 
						|
      //
 | 
						|
      return EFI_NOT_FOUND;
 | 
						|
    }
 | 
						|
 | 
						|
    FfsFileEntry = (FFS_FILE_LIST_ENTRY *)Link->ForwardLink;
 | 
						|
    FfsFileHeader = (EFI_FFS_FILE_HEADER *)FfsFileEntry->FfsHeader;
 | 
						|
 | 
						|
    //
 | 
						|
    // remember the key
 | 
						|
    //
 | 
						|
    *KeyValue = (UINTN)FfsFileEntry;
 | 
						|
 | 
						|
    if (FfsFileHeader->Type == EFI_FV_FILETYPE_FFS_PAD) {
 | 
						|
      //
 | 
						|
      // we ignore pad files
 | 
						|
      //
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if (*FileType == 0) {
 | 
						|
      //
 | 
						|
      // Process all file types so we have a match
 | 
						|
      //
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    if (*FileType == FfsFileHeader->Type) {
 | 
						|
      //
 | 
						|
      // Found a matching file type
 | 
						|
      //
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
  } 
 | 
						|
 | 
						|
  //
 | 
						|
  // Return FileType, NameGuid, and Attributes
 | 
						|
  //
 | 
						|
  *FileType = FfsFileHeader->Type;
 | 
						|
  CopyMem (NameGuid, &FfsFileHeader->Name, sizeof (EFI_GUID));
 | 
						|
  *Attributes = FfsAttributes2FvFileAttributes (FfsFileHeader->Attributes);
 | 
						|
 | 
						|
  //
 | 
						|
  // Read four bytes out of the 3 byte array and throw out extra data
 | 
						|
  //
 | 
						|
  FileLength = *(UINT32 *)&FfsFileHeader->Size[0] & 0x00FFFFFF;
 | 
						|
 | 
						|
  //
 | 
						|
  // we need to substract the header size
 | 
						|
  //
 | 
						|
  *Size = FileLength - sizeof(EFI_FFS_FILE_HEADER);
 | 
						|
 | 
						|
  if (FfsFileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
 | 
						|
    //
 | 
						|
    // If tail is present substract it's size;
 | 
						|
    //
 | 
						|
    *Size -= sizeof(EFI_FFS_FILE_TAIL);
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
FvReadFile (
 | 
						|
  IN     EFI_FIRMWARE_VOLUME_PROTOCOL   *This,
 | 
						|
  IN     EFI_GUID                       *NameGuid,
 | 
						|
  IN OUT VOID                           **Buffer,
 | 
						|
  IN OUT UINTN                          *BufferSize,
 | 
						|
  OUT    EFI_FV_FILETYPE               *FoundType,
 | 
						|
  OUT    EFI_FV_FILE_ATTRIBUTES        *FileAttributes,
 | 
						|
  OUT    UINT32                        *AuthenticationStatus
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
    Locates a file in the firmware volume and
 | 
						|
    copies it to the supplied buffer.
 | 
						|
 | 
						|
Arguments:
 | 
						|
    This              -   Indicates the calling context.
 | 
						|
    NameGuid          -   Pointer to an EFI_GUID, which is the filename.
 | 
						|
    Buffer            -   Buffer is a pointer to pointer to a buffer in
 | 
						|
                          which the file or section contents or are returned.
 | 
						|
    BufferSize        -   BufferSize is a pointer to caller allocated
 | 
						|
                          UINTN. On input *BufferSize indicates the size
 | 
						|
                          in bytes of the memory region pointed to by
 | 
						|
                          Buffer. On output, *BufferSize contains the number
 | 
						|
                          of bytes required to read the file.
 | 
						|
    FoundType         -   FoundType is a pointer to a caller allocated
 | 
						|
                          EFI_FV_FILETYPE that on successful return from Read()
 | 
						|
                          contains the type of file read.  This output reflects
 | 
						|
                          the file type irrespective of the value of the
 | 
						|
                          SectionType input.
 | 
						|
    FileAttributes    -   FileAttributes is a pointer to a caller allocated
 | 
						|
                          EFI_FV_FILE_ATTRIBUTES.  On successful return from
 | 
						|
                          Read(), *FileAttributes contains the attributes of
 | 
						|
                          the file read.
 | 
						|
    AuthenticationStatus -  AuthenticationStatus is a pointer to a caller
 | 
						|
                          allocated UINTN in which the authentication status
 | 
						|
                          is returned.
 | 
						|
Returns:
 | 
						|
    EFI_SUCCESS                   - Successfully read to memory buffer.
 | 
						|
    EFI_WARN_BUFFER_TOO_SMALL     - Buffer too small.
 | 
						|
    EFI_NOT_FOUND                 - Not found.
 | 
						|
    EFI_DEVICE_ERROR              - Device error.
 | 
						|
    EFI_ACCESS_DENIED             - Could not read.
 | 
						|
    EFI_INVALID_PARAMETER         - Invalid parameter.
 | 
						|
    EFI_OUT_OF_RESOURCES          - Not enough buffer to be allocated.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS                        Status;
 | 
						|
  FV_DEVICE                         *FvDevice;
 | 
						|
  EFI_GUID                          SearchNameGuid;
 | 
						|
  EFI_FV_FILETYPE                   LocalFoundType;
 | 
						|
  EFI_FV_FILE_ATTRIBUTES            LocalAttributes;
 | 
						|
  UINTN                             FileSize;
 | 
						|
  UINT8                             *SrcPtr;
 | 
						|
  EFI_FFS_FILE_HEADER               *FfsHeader;
 | 
						|
  UINTN                             InputBufferSize;
 | 
						|
  
 | 
						|
  if (NULL == NameGuid) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  FvDevice = FV_DEVICE_FROM_THIS (This);
 | 
						|
  
 | 
						|
 | 
						|
  //
 | 
						|
  // Keep looking until we find the matching NameGuid.
 | 
						|
  // The Key is really an FfsFileEntry
 | 
						|
  //
 | 
						|
  FvDevice->LastKey = 0;
 | 
						|
  do {
 | 
						|
    LocalFoundType = 0;
 | 
						|
    Status = FvGetNextFile (
 | 
						|
              This,
 | 
						|
              &FvDevice->LastKey,
 | 
						|
              &LocalFoundType,
 | 
						|
              &SearchNameGuid,
 | 
						|
              &LocalAttributes,
 | 
						|
              &FileSize
 | 
						|
              );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return EFI_NOT_FOUND;
 | 
						|
    }
 | 
						|
  } while (!CompareGuid (&SearchNameGuid, NameGuid));
 | 
						|
 | 
						|
  //
 | 
						|
  // Get a pointer to the header
 | 
						|
  //
 | 
						|
  FfsHeader = FvDevice->LastKey->FfsHeader;
 | 
						|
 | 
						|
  //
 | 
						|
  // Remember callers buffer size
 | 
						|
  //
 | 
						|
  InputBufferSize = *BufferSize;
 | 
						|
 | 
						|
  //
 | 
						|
  // Calculate return values
 | 
						|
  //
 | 
						|
  *FoundType = FfsHeader->Type;
 | 
						|
  *FileAttributes = FfsAttributes2FvFileAttributes (FfsHeader->Attributes);
 | 
						|
  *AuthenticationStatus = 0;
 | 
						|
  *BufferSize = FileSize;
 | 
						|
 | 
						|
  if (Buffer == NULL) {
 | 
						|
    //
 | 
						|
    // If Buffer is NULL, we only want to get the information colected so far
 | 
						|
    //
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Skip over file header
 | 
						|
  //
 | 
						|
  SrcPtr = ((UINT8 *)FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);
 | 
						|
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
  if (*Buffer == NULL) {
 | 
						|
    //
 | 
						|
    // Caller passed in a pointer so allocate buffer for them
 | 
						|
    //
 | 
						|
    *Buffer = CoreAllocateBootServicesPool (FileSize);
 | 
						|
    if (*Buffer == NULL) {
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
  } else if (FileSize > InputBufferSize) {
 | 
						|
    //
 | 
						|
    // Callers buffer was not big enough
 | 
						|
    // 
 | 
						|
    Status = EFI_WARN_BUFFER_TOO_SMALL;
 | 
						|
    FileSize = InputBufferSize;
 | 
						|
  }
 | 
						|
  
 | 
						|
  //
 | 
						|
  // Copy data into callers buffer 
 | 
						|
  //
 | 
						|
  CopyMem (*Buffer, SrcPtr, FileSize);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
FvReadFileSection (
 | 
						|
  IN     EFI_FIRMWARE_VOLUME_PROTOCOL   *This,
 | 
						|
  IN     EFI_GUID                       *NameGuid,
 | 
						|
  IN     EFI_SECTION_TYPE               SectionType,
 | 
						|
  IN     UINTN                          SectionInstance,
 | 
						|
  IN OUT VOID                           **Buffer,
 | 
						|
  IN OUT UINTN                          *BufferSize,
 | 
						|
  OUT    UINT32                         *AuthenticationStatus
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
  Routine Description:
 | 
						|
    Locates a section in a given FFS File and
 | 
						|
    copies it to the supplied buffer (not including section header).
 | 
						|
 | 
						|
  Arguments:
 | 
						|
    This              -   Indicates the calling context.
 | 
						|
    NameGuid          -   Pointer to an EFI_GUID, which is the filename.
 | 
						|
    SectionType       -   Indicates the section type to return.
 | 
						|
    SectionInstance   -   Indicates which instance of sections with a type of
 | 
						|
                          SectionType to return.
 | 
						|
    Buffer            -   Buffer is a pointer to pointer to a buffer in which
 | 
						|
                          the file or section contents or are returned.
 | 
						|
    BufferSize        -   BufferSize is a pointer to caller allocated UINTN.
 | 
						|
    AuthenticationStatus -AuthenticationStatus is a pointer to a caller
 | 
						|
                          allocated UINT32 in which the authentication status
 | 
						|
                          is returned.
 | 
						|
 | 
						|
  Returns:
 | 
						|
    EFI_SUCCESS                     - Successfully read the file section into buffer.
 | 
						|
    EFI_WARN_BUFFER_TOO_SMALL       - Buffer too small.
 | 
						|
    EFI_NOT_FOUND                   - Section not found.
 | 
						|
    EFI_DEVICE_ERROR                - Device error.
 | 
						|
    EFI_ACCESS_DENIED               - Could not read.
 | 
						|
    EFI_INVALID_PARAMETER           - Invalid parameter.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS                        Status;
 | 
						|
  FV_DEVICE                         *FvDevice;
 | 
						|
  EFI_FV_FILETYPE                   FileType;
 | 
						|
  EFI_FV_FILE_ATTRIBUTES            FileAttributes;
 | 
						|
  UINTN                             FileSize;
 | 
						|
  UINT8                             *FileBuffer;
 | 
						|
  EFI_SECTION_EXTRACTION_PROTOCOL   *Sep;
 | 
						|
  FFS_FILE_LIST_ENTRY               *FfsEntry;
 | 
						|
 
 | 
						|
  if (NULL == NameGuid || Buffer == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  FvDevice = FV_DEVICE_FROM_THIS (This);
 | 
						|
 | 
						|
  //
 | 
						|
  // Read the whole file into buffer
 | 
						|
  //
 | 
						|
  FileBuffer = NULL;
 | 
						|
  Status = FvReadFile (
 | 
						|
            This,
 | 
						|
            NameGuid,
 | 
						|
            (VOID **)&FileBuffer,
 | 
						|
            &FileSize,
 | 
						|
            &FileType,
 | 
						|
            &FileAttributes,
 | 
						|
            AuthenticationStatus
 | 
						|
            );             
 | 
						|
  //
 | 
						|
  // Get the last key used by our call to FvReadFile as it is the FfsEntry for this file.
 | 
						|
  //  
 | 
						|
  FfsEntry = (FFS_FILE_LIST_ENTRY *)FvDevice->LastKey;
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
  
 | 
						|
  //
 | 
						|
  // Check to see that the file actually HAS sections before we go any further.
 | 
						|
  //
 | 
						|
  if (FileType == EFI_FV_FILETYPE_RAW) {
 | 
						|
    Status = EFI_NOT_FOUND;
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Use FfsEntry to cache Section Extraction Protocol Inforomation
 | 
						|
  //
 | 
						|
  if (FfsEntry->StreamHandle == 0) {
 | 
						|
    //
 | 
						|
    // Located the protocol
 | 
						|
    //
 | 
						|
    Status = CoreLocateProtocol (&gEfiSectionExtractionProtocolGuid, NULL, (VOID **)&Sep);
 | 
						|
    //
 | 
						|
    // Section Extraction Protocol is part of Dxe Core so this should never fail
 | 
						|
    //
 | 
						|
    ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
    Status = Sep->OpenSectionStream (
 | 
						|
                    Sep,
 | 
						|
                    FileSize,
 | 
						|
                    FileBuffer,
 | 
						|
                    &FfsEntry->StreamHandle
 | 
						|
                    );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      goto Done;
 | 
						|
    }
 | 
						|
 | 
						|
    FfsEntry->Sep = Sep;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // Get cached copy of Sep
 | 
						|
    //
 | 
						|
    Sep = FfsEntry->Sep;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // If SectionType == 0 We need the whole section stream
 | 
						|
  //
 | 
						|
  Status = Sep->GetSection (
 | 
						|
                  Sep,
 | 
						|
                            FfsEntry->StreamHandle,
 | 
						|
                            (SectionType == 0) ? NULL : &SectionType,
 | 
						|
                            NULL,
 | 
						|
                            (SectionType == 0) ? 0 : SectionInstance,
 | 
						|
                            Buffer,
 | 
						|
                            BufferSize,
 | 
						|
                            AuthenticationStatus
 | 
						|
                            );
 | 
						|
 | 
						|
  //
 | 
						|
  // Close of stream defered to close of FfsHeader list to allow SEP to cache data
 | 
						|
  //
 | 
						|
 | 
						|
Done:
 | 
						|
  CoreFreePool (FileBuffer);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 |