]> git.proxmox.com Git - mirror_edk2.git/commitdiff
renaming the BaseFileHandleLib to UefiFileHandleLib.
authorjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 25 Mar 2011 20:43:54 +0000 (20:43 +0000)
committerjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 25 Mar 2011 20:43:54 +0000 (20:43 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11421 6f19259b-4bc3-4df7-8a09-765794883524

ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.c [deleted file]
ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.inf [deleted file]
ShellPkg/Library/UefiFileHandleLib/UefiFileHandleLib.c [new file with mode: 0644]
ShellPkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf [new file with mode: 0644]

diff --git a/ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.c b/ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.c
deleted file mode 100644 (file)
index bd3a4a7..0000000
+++ /dev/null
@@ -1,1151 +0,0 @@
-/** @file\r
-  Provides interface to EFI_FILE_HANDLE functionality.\r
-\r
-  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved. <BR>\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include <Uefi.h>\r
-\r
-#include <Protocol/SimpleFileSystem.h>\r
-\r
-#include <Guid/FileInfo.h>\r
-\r
-#include <Library/DebugLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/FileHandleLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/PrintLib.h>\r
-\r
-#define MAX_FILE_NAME_LEN 522 // (20 * (6+5+2))+1) unicode characters from EFI FAT spec (doubled for bytes)\r
-#define FIND_XXXXX_FILE_BUFFER_SIZE (SIZE_OF_EFI_FILE_INFO + MAX_FILE_NAME_LEN)\r
-\r
-/**\r
-  This function will retrieve the information about the file for the handle\r
-  specified and store it in allocated pool memory.\r
-\r
-  This function allocates a buffer to store the file's information. It is the\r
-  caller's responsibility to free the buffer\r
-\r
-  @param  FileHandle  The file handle of the file for which information is\r
-  being requested.\r
-\r
-  @retval NULL information could not be retrieved.\r
-\r
-  @return the information about the file\r
-**/\r
-EFI_FILE_INFO*\r
-EFIAPI\r
-FileHandleGetInfo (\r
-  IN EFI_FILE_HANDLE            FileHandle\r
-  )\r
-{\r
-  EFI_FILE_INFO   *FileInfo;\r
-  UINTN           FileInfoSize;\r
-  EFI_STATUS      Status;\r
-\r
-  //\r
-  // ASSERT if FileHandle is NULL\r
-  //\r
-  ASSERT (FileHandle != NULL);\r
-\r
-  //\r
-  // Get the required size to allocate\r
-  //\r
-  FileInfoSize = 0;\r
-  FileInfo = NULL;\r
-  Status = FileHandle->GetInfo(FileHandle,\r
-                               &gEfiFileInfoGuid,\r
-                               &FileInfoSize,\r
-                               FileInfo);\r
-  //\r
-  // error is expected.  getting size to allocate\r
-  //\r
-  ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
-  FileInfo = AllocateZeroPool(FileInfoSize);\r
-  ASSERT (FileInfo != NULL);\r
-  //\r
-  // now get the information\r
-  //\r
-  Status = FileHandle->GetInfo(FileHandle,\r
-                               &gEfiFileInfoGuid,\r
-                               &FileInfoSize,\r
-                               FileInfo);\r
-  //\r
-  // if we got an error free the memory and return NULL\r
-  //\r
-  if (EFI_ERROR(Status)) {\r
-    FreePool(FileInfo);\r
-    return NULL;\r
-  }\r
-  return (FileInfo);\r
-}\r
-\r
-/**\r
-  This function sets the information about the file for the opened handle\r
-  specified.\r
-\r
-  @param[in]  FileHandle        The file handle of the file for which information\r
-                                is being set.\r
-\r
-  @param[in]  FileInfo          The information to set.\r
-\r
-  @retval EFI_SUCCESS                  The information was set.\r
-  @retval EFI_INVALID_PARAMETER A parameter was out of range or invalid.\r
-  @retval EFI_UNSUPPORTED       The FileHandle does not support FileInfo.\r
-  @retval EFI_NO_MEDIA               The device has no medium.\r
-  @retval EFI_DEVICE_ERROR         The device reported an error.\r
-  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
-  @retval EFI_WRITE_PROTECTED    The file or medium is write protected.\r
-  @retval EFI_ACCESS_DENIED     The file was opened read only.\r
-  @retval EFI_VOLUME_FULL       The volume is full.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleSetInfo (\r
-  IN EFI_FILE_HANDLE           FileHandle,\r
-  IN CONST EFI_FILE_INFO        *FileInfo\r
-  )\r
-{\r
-\r
-  //\r
-  // ASSERT if the FileHandle or FileInfo is NULL\r
-  //\r
-  ASSERT (FileHandle != NULL);\r
-  ASSERT (FileInfo   != NULL);\r
-\r
-  //\r
-  // Set the info\r
-  //\r
-  return (FileHandle->SetInfo(FileHandle,\r
-                              &gEfiFileInfoGuid,\r
-                              (UINTN)FileInfo->Size,\r
-                              (EFI_FILE_INFO*)FileInfo));\r
-}\r
-\r
-/**\r
-  This function reads information from an opened file.\r
-\r
-  If FileHandle is not a directory, the function reads the requested number of\r
-  bytes from the file at the file's current position and returns them in Buffer.\r
-  If the read goes beyond the end of the file, the read length is truncated to the\r
-  end of the file. The file's current position is increased by the number of bytes\r
-  returned.  If FileHandle is a directory, the function reads the directory entry\r
-  at the file's current position and returns the entry in Buffer. If the Buffer\r
-  is not large enough to hold the current directory entry, then\r
-  EFI_BUFFER_TOO_SMALL is returned and the current file position is not updated.\r
-  BufferSize is set to be the size of the buffer needed to read the entry. On\r
-  success, the current position is updated to the next directory entry. If there\r
-  are no more directory entries, the read returns a zero-length buffer.\r
-  EFI_FILE_INFO is the structure returned as the directory entry.\r
-\r
-  @param FileHandle             the opened file handle\r
-  @param BufferSize             on input the size of buffer in bytes.  on return\r
-                                the number of bytes written.\r
-  @param Buffer                 the buffer to put read data into.\r
-\r
-  @retval EFI_SUCCESS           Data was read.\r
-  @retval EFI_NO_MEDIA          The device has no media.\r
-  @retval EFI_DEVICE_ERROR      The device reported an error.\r
-  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
-  @retval EFI_BUFFER_TO_SMALL   Buffer is too small. ReadSize contains required\r
-                                size.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleRead(\r
-  IN EFI_FILE_HANDLE            FileHandle,\r
-  IN OUT UINTN                  *BufferSize,\r
-  OUT VOID                      *Buffer\r
-  )\r
-{\r
-  //\r
-  // ASSERT if FileHandle is NULL\r
-  //\r
-  ASSERT (FileHandle != NULL);\r
-\r
-  //\r
-  // Perform the read based on EFI_FILE_PROTOCOL\r
-  //\r
-  return (FileHandle->Read(FileHandle, BufferSize, Buffer));\r
-}\r
-\r
-\r
-/**\r
-  Write data to a file.\r
-\r
-  This function writes the specified number of bytes to the file at the current\r
-  file position. The current file position is advanced the actual number of bytes\r
-  written, which is returned in BufferSize. Partial writes only occur when there\r
-  has been a data error during the write attempt (such as "volume space full").\r
-  The file is automatically grown to hold the data if required. Direct writes to\r
-  opened directories are not supported.\r
-\r
-  @param FileHandle           The opened file for writing\r
-  @param BufferSize           on input the number of bytes in Buffer.  On output\r
-                              the number of bytes written.\r
-  @param Buffer               the buffer containing data to write is stored.\r
-\r
- @retval EFI_SUCCESS           Data was written.\r
- @retval EFI_UNSUPPORTED           Writes to an open directory are not supported.\r
- @retval EFI_NO_MEDIA          The device has no media.\r
- @retval EFI_DEVICE_ERROR          The device reported an error.\r
- @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
- @retval EFI_WRITE_PROTECTED   The device is write-protected.\r
- @retval EFI_ACCESS_DENIED       The file was open for read only.\r
- @retval EFI_VOLUME_FULL           The volume is full.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleWrite(\r
-  IN EFI_FILE_HANDLE            FileHandle,\r
-  IN OUT UINTN                  *BufferSize,\r
-  IN VOID                       *Buffer\r
-  )\r
-{\r
-  //\r
-  // ASSERT if FileHandle is NULL\r
-  //\r
-  ASSERT (FileHandle != NULL);\r
-  //\r
-  // Perform the write based on EFI_FILE_PROTOCOL\r
-  //\r
-  return (FileHandle->Write(FileHandle, BufferSize, Buffer));\r
-}\r
-\r
-/**\r
-  Close an open file handle.\r
-\r
-  This function closes a specified file handle. All "dirty" cached file data is\r
-  flushed to the device, and the file is closed. In all cases the handle is\r
-  closed.\r
-\r
-@param FileHandle               the file handle to close.\r
-\r
-@retval EFI_SUCCESS             the file handle was closed sucessfully.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleClose (\r
-  IN EFI_FILE_HANDLE            FileHandle\r
-  )\r
-{\r
-  EFI_STATUS Status;\r
-  //\r
-  // ASSERT if FileHandle is NULL\r
-  //\r
-  ASSERT (FileHandle != NULL);\r
-  //\r
-  // Perform the Close based on EFI_FILE_PROTOCOL\r
-  //\r
-  Status = FileHandle->Close(FileHandle);\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Delete a file and close the handle\r
-\r
-  This function closes and deletes a file. In all cases the file handle is closed.\r
-  If the file cannot be deleted, the warning code EFI_WARN_DELETE_FAILURE is\r
-  returned, but the handle is still closed.\r
-\r
-  @param FileHandle             the file handle to delete\r
-\r
-  @retval EFI_SUCCESS           the file was closed sucessfully\r
-  @retval EFI_WARN_DELETE_FAILURE the handle was closed, but the file was not\r
-                                deleted\r
-  @retval INVALID_PARAMETER            One of the parameters has an invalid value.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleDelete (\r
-  IN EFI_FILE_HANDLE           FileHandle\r
-  )\r
-{\r
-  EFI_STATUS Status;\r
-  //\r
-  // ASSERT if FileHandle is NULL\r
-  //\r
-  ASSERT (FileHandle != NULL);\r
-  //\r
-  // Perform the Delete based on EFI_FILE_PROTOCOL\r
-  //\r
-  Status = FileHandle->Delete(FileHandle);\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Set the current position in a file.\r
-\r
-  This function sets the current file position for the handle to the position\r
-  supplied. With the exception of seeking to position 0xFFFFFFFFFFFFFFFF, only\r
-  absolute positioning is supported, and seeking past the end of the file is\r
-  allowed (a subsequent write would grow the file). Seeking to position\r
-  0xFFFFFFFFFFFFFFFF causes the current position to be set to the end of the file.\r
-  If FileHandle is a directory, the only position that may be set is zero. This\r
-  has the effect of starting the read process of the directory entries over.\r
-\r
-  @param FileHandle             The file handle on which the position is being set\r
-  @param Position               Byte position from begining of file\r
-\r
-  @retval EFI_SUCCESS           Operation completed sucessfully.\r
-  @retval EFI_UNSUPPORTED       the seek request for non-zero is not valid on\r
-                                directories.\r
-  @retval INVALID_PARAMETER     One of the parameters has an invalid value.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleSetPosition (\r
-  IN EFI_FILE_HANDLE           FileHandle,\r
-  IN UINT64            Position\r
-  )\r
-{\r
-  //\r
-  // ASSERT if FileHandle is NULL\r
-  //\r
-  ASSERT (FileHandle != NULL);\r
-  //\r
-  // Perform the SetPosition based on EFI_FILE_PROTOCOL\r
-  //\r
-  return (FileHandle->SetPosition(FileHandle, Position));\r
-}\r
-\r
-/**\r
-  Gets a file's current position\r
-\r
-  This function retrieves the current file position for the file handle. For\r
-  directories, the current file position has no meaning outside of the file\r
-  system driver and as such the operation is not supported. An error is returned\r
-  if FileHandle is a directory.\r
-\r
-  @param FileHandle             The open file handle on which to get the position.\r
-  @param Position               Byte position from begining of file.\r
-\r
-  @retval EFI_SUCCESS           the operation completed sucessfully.\r
-  @retval INVALID_PARAMETER     One of the parameters has an invalid value.\r
-  @retval EFI_UNSUPPORTED       the request is not valid on directories.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleGetPosition (\r
-  IN EFI_FILE_HANDLE            FileHandle,\r
-  OUT UINT64                    *Position\r
-  )\r
-{\r
-  if (Position == NULL) {\r
-    return (EFI_INVALID_PARAMETER);\r
-  }\r
-  //\r
-  // ASSERT if FileHandle is NULL\r
-  //\r
-  ASSERT (FileHandle != NULL);\r
-  //\r
-  // Perform the GetPosition based on EFI_FILE_PROTOCOL\r
-  //\r
-  return (FileHandle->GetPosition(FileHandle, Position));\r
-}\r
-/**\r
-  Flushes data on a file\r
-\r
-  This function flushes all modified data associated with a file to a device.\r
-\r
-  @param FileHandle             The file handle on which to flush data\r
-\r
-  @retval EFI_SUCCESS           The data was flushed.\r
-  @retval EFI_NO_MEDIA          The device has no media.\r
-  @retval EFI_DEVICE_ERROR      The device reported an error.\r
-  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
-  @retval EFI_WRITE_PROTECTED   The file or medium is write protected.\r
-  @retval EFI_ACCESS_DENIED     The file was opened for read only.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleFlush (\r
-  IN EFI_FILE_HANDLE            FileHandle\r
-  )\r
-{\r
-  //\r
-  // ASSERT if FileHandle is NULL\r
-  //\r
-  ASSERT (FileHandle != NULL);\r
-  //\r
-  // Perform the Flush based on EFI_FILE_PROTOCOL\r
-  //\r
-  return (FileHandle->Flush(FileHandle));\r
-}\r
-\r
-/**\r
-  function to determine if a given handle is a directory handle\r
-\r
-  if DirHandle is NULL then ASSERT()\r
-\r
-  open the file information on the DirHandle and verify that the Attribute\r
-  includes EFI_FILE_DIRECTORY bit set.\r
-\r
-  @param DirHandle              Handle to open file\r
-\r
-  @retval EFI_SUCCESS           DirHandle is a directory\r
-  @retval EFI_INVALID_PARAMETER DirHandle did not have EFI_FILE_INFO available\r
-  @retval EFI_NOT_FOUND         DirHandle is not a directory\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleIsDirectory (\r
-  IN EFI_FILE_HANDLE            DirHandle\r
-  )\r
-{\r
-  EFI_FILE_INFO *DirInfo;\r
-\r
-  //\r
-  // ASSERT if DirHandle is NULL\r
-  //\r
-  ASSERT(DirHandle != NULL);\r
-\r
-  //\r
-  // get the file information for DirHandle\r
-  //\r
-  DirInfo = FileHandleGetInfo (DirHandle);\r
-\r
-  //\r
-  // Parse DirInfo\r
-  //\r
-  if (DirInfo == NULL) {\r
-    //\r
-    // We got nothing...\r
-    //\r
-    return (EFI_INVALID_PARAMETER);\r
-  }\r
-  if ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {\r
-    //\r
-    // Attributes say this is not a directory\r
-    //\r
-    FreePool (DirInfo);\r
-    return (EFI_NOT_FOUND);\r
-  }\r
-  //\r
-  // all good...\r
-  //\r
-  FreePool (DirInfo);\r
-  return (EFI_SUCCESS);\r
-}\r
-\r
-/**\r
-  Retrieves the first file from a directory\r
-\r
-  This function opens a directory and gets the first file's info in the\r
-  directory. Caller can use FileHandleFindNextFile() to get other files.  When\r
-  complete the caller is responsible for calling FreePool() on Buffer.\r
-\r
-  @param DirHandle              The file handle of the directory to search\r
-  @param Buffer                 Pointer to buffer for file's information\r
-\r
-  @retval EFI_SUCCESS           Found the first file.\r
-  @retval EFI_NOT_FOUND         Cannot find the directory.\r
-  @retval EFI_NO_MEDIA          The device has no media.\r
-  @retval EFI_DEVICE_ERROR      The device reported an error.\r
-  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
-  @return Others                status of FileHandleGetInfo, FileHandleSetPosition,\r
-                                or FileHandleRead\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleFindFirstFile (\r
-  IN EFI_FILE_HANDLE            DirHandle,\r
-  OUT EFI_FILE_INFO             **Buffer\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-  UINTN         BufferSize;\r
-\r
-  //\r
-  // ASSERTs\r
-  //\r
-  ASSERT (DirHandle != NULL);\r
-  ASSERT (Buffer != NULL);\r
-\r
-  //\r
-  // verify that DirHandle is a directory\r
-  //\r
-  Status = FileHandleIsDirectory(DirHandle);\r
-  if (EFI_ERROR(Status)) {\r
-    return (Status);\r
-  }\r
-\r
-  //\r
-  // reset to the begining of the directory\r
-  //\r
-  Status = FileHandleSetPosition(DirHandle, 0);\r
-  if (EFI_ERROR(Status)) {\r
-    return (Status);\r
-  }\r
-\r
-  //\r
-  // Allocate a buffer sized to struct size + enough for the string at the end\r
-  //\r
-  BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE;\r
-  *Buffer = AllocateZeroPool(BufferSize);\r
-  ASSERT (*Buffer != NULL);\r
-\r
-  //\r
-  // read in the info about the first file\r
-  //\r
-  Status = FileHandleRead (DirHandle, &BufferSize, *Buffer);\r
-  ASSERT(Status != EFI_BUFFER_TOO_SMALL);\r
-  if (EFI_ERROR(Status)) {\r
-    FreePool(*Buffer);\r
-    *Buffer = NULL;\r
-    return (Status);\r
-  }\r
-  return (EFI_SUCCESS);\r
-}\r
-/**\r
-  Retrieves the next file in a directory.\r
-\r
-  To use this function, caller must call the FileHandleFindFirstFile() to get the\r
-  first file, and then use this function get other files. This function can be\r
-  called for several times to get each file's information in the directory. If\r
-  the call of FileHandleFindNextFile() got the last file in the directory, the next\r
-  call of this function has no file to get. *NoFile will be set to TRUE and the\r
-  Buffer memory will be automatically freed.\r
-\r
-  @param DirHandle              the file handle of the directory\r
-  @param Buffer                                    pointer to buffer for file's information\r
-  @param NoFile                                    pointer to boolean when last file is found\r
-\r
-  @retval EFI_SUCCESS           Found the next file, or reached last file\r
-  @retval EFI_NO_MEDIA          The device has no media.\r
-  @retval EFI_DEVICE_ERROR      The device reported an error.\r
-  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleFindNextFile(\r
-  IN EFI_FILE_HANDLE             DirHandle,\r
-  OUT EFI_FILE_INFO              *Buffer,\r
-  OUT BOOLEAN                    *NoFile\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-  UINTN         BufferSize;\r
-\r
-  //\r
-  // ASSERTs for DirHandle or Buffer or NoFile poitners being NULL\r
-  //\r
-  ASSERT (DirHandle != NULL);\r
-  ASSERT (Buffer    != NULL);\r
-  ASSERT (NoFile    != NULL);\r
-\r
-  //\r
-  // This BufferSize MUST stay equal to the originally allocated one in GetFirstFile\r
-  //\r
-  BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE;\r
-\r
-  //\r
-  // read in the info about the next file\r
-  //\r
-  Status = FileHandleRead (DirHandle, &BufferSize, Buffer);\r
-  ASSERT(Status != EFI_BUFFER_TOO_SMALL);\r
-  if (EFI_ERROR(Status)) {\r
-    return (Status);\r
-  }\r
-\r
-  //\r
-  // If we read 0 bytes (but did not have erros) we already read in the last file.\r
-  //\r
-  if (BufferSize == 0) {\r
-    FreePool(Buffer);\r
-    *NoFile = TRUE;\r
-  }\r
-\r
-  return (EFI_SUCCESS);\r
-}\r
-\r
-/**\r
-  Retrieve the size of a file.\r
-\r
-  if FileHandle is NULL then ASSERT()\r
-  if Size is NULL then ASSERT()\r
-\r
-  This function extracts the file size info from the FileHandle's EFI_FILE_INFO\r
-  data.\r
-\r
-  @param FileHandle             file handle from which size is retrieved\r
-  @param Size                   pointer to size\r
-\r
-  @retval EFI_SUCCESS           operation was completed sucessfully\r
-  @retval EFI_DEVICE_ERROR      cannot access the file\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleGetSize (\r
-  IN EFI_FILE_HANDLE            FileHandle,\r
-  OUT UINT64                    *Size\r
-  )\r
-{\r
-  EFI_FILE_INFO                 *FileInfo;\r
-\r
-  //\r
-  // ASSERT for FileHandle or Size being NULL\r
-  //\r
-  ASSERT (FileHandle != NULL);\r
-  ASSERT (Size != NULL);\r
-\r
-  //\r
-  // get the FileInfo structure\r
-  //\r
-  FileInfo = FileHandleGetInfo(FileHandle);\r
-  if (FileInfo == NULL) {\r
-    return (EFI_DEVICE_ERROR);\r
-  }\r
-\r
-  //\r
-  // Assign the Size pointer to the correct value\r
-  //\r
-  *Size = FileInfo->FileSize;\r
-\r
-  //\r
-  // free the FileInfo memory\r
-  //\r
-  FreePool(FileInfo);\r
-\r
-  return (EFI_SUCCESS);\r
-}\r
-\r
-/**\r
-  Set the size of a file.\r
-\r
-  If FileHandle is NULL then ASSERT().\r
-\r
-  This function changes the file size info from the FileHandle's EFI_FILE_INFO\r
-  data.\r
-\r
-  @param FileHandle             File handle whose size is to be changed.\r
-  @param Size                   New size.\r
-\r
-  @retval EFI_SUCCESS           operation was completed sucessfully.\r
-  @retval EFI_DEVICE_ERROR      cannot access the file.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleSetSize (\r
-  IN EFI_FILE_HANDLE            FileHandle,\r
-  IN UINT64                     Size\r
-  )\r
-{\r
-  EFI_FILE_INFO                 *FileInfo;\r
-  EFI_STATUS                    Status;\r
-\r
-  //\r
-  // ASSERT for FileHandle or Size being NULL\r
-  //\r
-  ASSERT (FileHandle != NULL);\r
-\r
-  //\r
-  // get the FileInfo structure\r
-  //\r
-  FileInfo = FileHandleGetInfo(FileHandle);\r
-  if (FileInfo == NULL) {\r
-    return (EFI_DEVICE_ERROR);\r
-  }\r
-\r
-  //\r
-  // Assign the FileSize pointer to the new value\r
-  //\r
-  FileInfo->FileSize = Size;\r
-\r
-  Status = FileHandleSetInfo(FileHandle, FileInfo);\r
-  //\r
-  // free the FileInfo memory\r
-  //\r
-  FreePool(FileInfo);\r
-\r
-  return (Status);\r
-}\r
-\r
-/**\r
-  Safely append (on the left) with automatic string resizing given length of Destination and\r
-  desired length of copy from Source.\r
-\r
-  append the first D characters of Source to the end of Destination, where D is\r
-  the lesser of Count and the StrLen() of Source. If appending those D characters\r
-  will fit within Destination (whose Size is given as CurrentSize) and\r
-  still leave room for a NULL terminator, then those characters are appended,\r
-  starting at the original terminating NULL of Destination, and a new terminating\r
-  NULL is appended.\r
-\r
-  If appending D characters onto Destination will result in a overflow of the size\r
-  given in CurrentSize the string will be grown such that the copy can be performed\r
-  and CurrentSize will be updated to the new size.\r
-\r
-  If Source is NULL, there is nothing to append, just return the current buffer in\r
-  Destination.\r
-\r
-  if Destination is NULL, then ASSERT()\r
-  if Destination's current length (including NULL terminator) is already more then\r
-  CurrentSize, then ASSERT()\r
-\r
-  @param[in,out] Destination   The String to append onto\r
-  @param[in,out] CurrentSize   on call the number of bytes in Destination.  On\r
-                                return possibly the new size (still in bytes).  if NULL\r
-                                then allocate whatever is needed.\r
-  @param[in]      Source        The String to append from\r
-  @param[in]      Count         Maximum number of characters to append.  if 0 then\r
-                                all are appended.\r
-\r
-  @return Destination           return the resultant string.\r
-**/\r
-CHAR16*\r
-EFIAPI\r
-StrnCatGrowLeft (\r
-  IN OUT CHAR16           **Destination,\r
-  IN OUT UINTN            *CurrentSize,\r
-  IN     CONST CHAR16     *Source,\r
-  IN     UINTN            Count\r
-  )\r
-{\r
-  UINTN DestinationStartSize;\r
-  UINTN NewSize;\r
-  UINTN CopySize;\r
-\r
-  //\r
-  // ASSERTs\r
-  //\r
-  ASSERT(Destination != NULL);\r
-\r
-  //\r
-  // If there's nothing to do then just return Destination\r
-  //\r
-  if (Source == NULL) {\r
-    return (*Destination);\r
-  }\r
-\r
-  //\r
-  // allow for NULL pointers address as Destination\r
-  //\r
-  if (*Destination != NULL) {\r
-    ASSERT(CurrentSize != 0);\r
-    DestinationStartSize = StrSize(*Destination);\r
-    ASSERT(DestinationStartSize <= *CurrentSize);\r
-  } else {\r
-    DestinationStartSize = 0;\r
-//    ASSERT(*CurrentSize == 0);\r
-  }\r
-\r
-  //\r
-  // Append all of Source?\r
-  //\r
-  if (Count == 0) {\r
-    Count = StrSize(Source);\r
-  }\r
-\r
-  //\r
-  // Test and grow if required\r
-  //\r
-  if (CurrentSize != NULL) {\r
-    NewSize = *CurrentSize;\r
-    while (NewSize < (DestinationStartSize + Count)) {\r
-      NewSize += 2 * Count;\r
-    }\r
-    *Destination = ReallocatePool(*CurrentSize, NewSize, *Destination);\r
-    *CurrentSize = NewSize;\r
-  } else {\r
-    *Destination = AllocateZeroPool(Count+sizeof(CHAR16));\r
-  }\r
-\r
-  CopySize = StrSize(*Destination);\r
-  CopyMem((*Destination)+((Count-2)/sizeof(CHAR16)), *Destination, CopySize);\r
-  CopyMem(*Destination, Source, Count-2);\r
-  return (*Destination);\r
-}\r
-\r
-/**\r
-  Function to get a full filename given a EFI_FILE_HANDLE somewhere lower on the\r
-  directory 'stack'.\r
-\r
-  if Handle is NULL, return EFI_INVALID_PARAMETER\r
-\r
-  @param[in] Handle             Handle to the Directory or File to create path to.\r
-  @param[out] FullFileName      pointer to pointer to generated full file name.  It\r
-                                is the responsibility of the caller to free this memory\r
-                                with a call to FreePool().\r
-  @retval EFI_SUCCESS           the operation was sucessful and the FullFileName is valid.\r
-  @retval EFI_INVALID_PARAMETER Handle was NULL.\r
-  @retval EFI_INVALID_PARAMETER FullFileName was NULL.\r
-  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleGetFileName (\r
-  IN CONST EFI_FILE_HANDLE      Handle,\r
-  OUT CHAR16                    **FullFileName\r
-  )\r
-{\r
-  EFI_STATUS      Status;\r
-  UINTN           Size;\r
-  EFI_FILE_HANDLE CurrentHandle;\r
-  EFI_FILE_HANDLE NextHigherHandle;\r
-  EFI_FILE_INFO   *FileInfo;\r
-\r
-  Size = 0;\r
-\r
-  //\r
-  // Check our parameters\r
-  //\r
-  if (FullFileName == NULL || Handle == NULL) {\r
-    return (EFI_INVALID_PARAMETER);\r
-  }\r
-\r
-  *FullFileName = NULL;\r
-  CurrentHandle = NULL;\r
-\r
-  Status = Handle->Open(Handle, &CurrentHandle, L".", EFI_FILE_MODE_READ, 0);\r
-  if (!EFI_ERROR(Status)) {\r
-    //\r
-    // Reverse out the current directory on the device\r
-    //\r
-    for (;;) {\r
-      FileInfo = FileHandleGetInfo(CurrentHandle);\r
-      if (FileInfo == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        break;\r
-      } else {\r
-        //\r
-        // We got info... do we have a name? if yes preceed the current path with it...\r
-        //\r
-        if (StrLen (FileInfo->FileName) == 0) {\r
-          if (*FullFileName == NULL) {\r
-            ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));\r
-            *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);\r
-          }\r
-          FreePool(FileInfo);\r
-          break;\r
-        } else {\r
-          if (*FullFileName == NULL) {\r
-            ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));\r
-            *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);\r
-          }\r
-          ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));\r
-          *FullFileName = StrnCatGrowLeft(FullFileName, &Size, FileInfo->FileName, 0);\r
-          *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);\r
-          FreePool(FileInfo);\r
-        }\r
-      }\r
-      //\r
-      // Move to the parent directory\r
-      //\r
-      Status = CurrentHandle->Open (CurrentHandle, &NextHigherHandle, L"..", EFI_FILE_MODE_READ, 0);\r
-      if (EFI_ERROR (Status)) {\r
-        break;\r
-      }\r
-\r
-      FileHandleClose(CurrentHandle);\r
-      CurrentHandle = NextHigherHandle;\r
-    }\r
-  } else if (Status == EFI_NOT_FOUND) {\r
-    Status = EFI_SUCCESS;\r
-    ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));\r
-    *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);\r
-  }\r
-\r
-  if (CurrentHandle != NULL) {\r
-    CurrentHandle->Close (CurrentHandle);\r
-  }\r
-\r
-  if (EFI_ERROR(Status) && *FullFileName != NULL) {\r
-    FreePool(*FullFileName);\r
-  }\r
-\r
-  return (Status);\r
-}\r
-\r
-/**\r
-  Function to read a single line from a file. The \n is not included in the returned\r
-  buffer.  The returned buffer must be callee freed.\r
-\r
-  If the position upon start is 0, then the Ascii Boolean will be set.  This should be\r
-  maintained and not changed for all operations with the same file.\r
-\r
-  @param[in]      Handle        FileHandle to read from.\r
-  @param[in,out]  Ascii         Boolean value for indicating whether the file is Ascii (TRUE) or UCS2 (FALSE);\r
-\r
-  @return                       The line of text from the file.\r
-\r
-  @sa FileHandleReadLine\r
-**/\r
-CHAR16*\r
-EFIAPI\r
-FileHandleReturnLine(\r
-  IN EFI_FILE_HANDLE            Handle,\r
-  IN OUT BOOLEAN                *Ascii\r
-  )\r
-{\r
-  CHAR16          *RetVal;\r
-  UINTN           Size;\r
-  EFI_STATUS      Status;\r
-\r
-  Size = 0;\r
-  RetVal = NULL;\r
-\r
-  Status = FileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii);\r
-  if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    RetVal = AllocatePool(Size);\r
-    Status = FileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii);\r
-  }\r
-  ASSERT_EFI_ERROR(Status);\r
-  if (EFI_ERROR(Status) && (RetVal != NULL)) {\r
-    FreePool(RetVal);\r
-    RetVal = NULL;\r
-  }\r
-  return (RetVal);\r
-}\r
-\r
-/**\r
-  Function to read a single line (up to but not including the \n) from a EFI_FILE_HANDLE.\r
-\r
-  If the position upon start is 0, then the Ascii Boolean will be set.  This should be\r
-  maintained and not changed for all operations with the same file.\r
-\r
-  @param[in]      Handle        FileHandle to read from\r
-  @param[in,out]  Buffer        pointer to buffer to read into\r
-  @param[in,out]  Size          pointer to number of bytes in buffer\r
-  @param[in]      Truncate      if TRUE then allows for truncation of the line to fit.\r
-                                if FALSE will reset the position to the begining of the\r
-                                line if the buffer is not large enough.\r
-  @param[in,out]  Ascii         Boolean value for indicating whether the file is Ascii (TRUE) or UCS2 (FALSE);\r
-\r
-  @retval EFI_SUCCESS           the operation was sucessful.  the line is stored in\r
-                                Buffer.\r
-  @retval EFI_INVALID_PARAMETER Handle was NULL.\r
-  @retval EFI_INVALID_PARAMETER Size was NULL.\r
-  @retval EFI_BUFFER_TOO_SMALL  Size was not enough space to store the line.\r
-                                Size was updated to minimum space required.\r
-  @sa FileHandleRead\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleReadLine(\r
-  IN EFI_FILE_HANDLE            Handle,\r
-  IN OUT CHAR16                 *Buffer,\r
-  IN OUT UINTN                  *Size,\r
-  IN BOOLEAN                    Truncate,\r
-  IN OUT BOOLEAN                *Ascii\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  CHAR16      CharBuffer;\r
-  UINTN       CharSize;\r
-  UINTN       CountSoFar;\r
-  UINT64      OriginalFilePosition;\r
-\r
-\r
-  if (Handle == NULL\r
-    ||Size   == NULL\r
-   ){\r
-    return (EFI_INVALID_PARAMETER);\r
-  }\r
-  if (Buffer == NULL) {\r
-    ASSERT(*Size == 0);\r
-  } else {\r
-    *Buffer = CHAR_NULL;\r
-  }\r
-  FileHandleGetPosition(Handle, &OriginalFilePosition);\r
-  if (OriginalFilePosition == 0) {\r
-    CharSize = sizeof(CHAR16);\r
-    Status = FileHandleRead(Handle, &CharSize, &CharBuffer);\r
-    ASSERT_EFI_ERROR(Status);\r
-    if (CharBuffer == UnicodeFileTag) {\r
-      *Ascii = FALSE;\r
-    } else {\r
-      *Ascii = TRUE;\r
-      FileHandleSetPosition(Handle, OriginalFilePosition);\r
-    }\r
-  }\r
-\r
-  for (CountSoFar = 0;;CountSoFar++){\r
-    CharBuffer = 0;\r
-    if (*Ascii) {\r
-      CharSize = sizeof(CHAR8);\r
-    } else {\r
-      CharSize = sizeof(CHAR16);\r
-    }\r
-    Status = FileHandleRead(Handle, &CharSize, &CharBuffer);\r
-    if (  EFI_ERROR(Status)\r
-       || CharSize == 0\r
-       || (CharBuffer == L'\n' && !(*Ascii))\r
-       || (CharBuffer ==  '\n' && *Ascii)\r
-     ){\r
-      break;\r
-    }\r
-    //\r
-    // if we have space save it...\r
-    //\r
-    if ((CountSoFar+1)*sizeof(CHAR16) < *Size){\r
-      ASSERT(Buffer != NULL);\r
-      ((CHAR16*)Buffer)[CountSoFar] = CharBuffer;\r
-      ((CHAR16*)Buffer)[CountSoFar+1] = CHAR_NULL;\r
-    }\r
-  }\r
-\r
-  //\r
-  // if we ran out of space tell when...\r
-  //\r
-  if ((CountSoFar+1)*sizeof(CHAR16) > *Size){\r
-    *Size = (CountSoFar+1)*sizeof(CHAR16);\r
-    if (!Truncate) {\r
-      FileHandleSetPosition(Handle, OriginalFilePosition);\r
-    } else {\r
-      DEBUG((DEBUG_WARN, "The line was truncated in FileHandleReadLine"));\r
-    }\r
-    return (EFI_BUFFER_TOO_SMALL);\r
-  }\r
-  while(Buffer[StrLen(Buffer)-1] == L'\r') {\r
-    Buffer[StrLen(Buffer)-1] = CHAR_NULL;\r
-  }\r
-\r
-  return (Status);\r
-}\r
-\r
-/**\r
-  function to write a line of unicode text to a file.\r
-\r
-  if Handle is NULL, ASSERT.\r
-  if Buffer is NULL, do nothing.  (return SUCCESS)\r
-\r
-  @param[in]     Handle         FileHandle to write to\r
-  @param[in]     Buffer         Buffer to write\r
-\r
-  @retval  EFI_SUCCESS          the data was written.\r
-  @retval  other                failure.\r
-\r
-  @sa FileHandleWrite\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandleWriteLine(\r
-  IN EFI_FILE_HANDLE Handle,\r
-  IN CHAR16          *Buffer\r
-  )\r
-{\r
-  EFI_STATUS Status;\r
-  UINTN      Size;\r
-\r
-  ASSERT(Handle != NULL);\r
-\r
-  if (Buffer == NULL) {\r
-    return (EFI_SUCCESS);\r
-  }\r
-\r
-  Size = StrSize(Buffer) - sizeof(Buffer[0]);\r
-  Status = FileHandleWrite(Handle, &Size, Buffer);\r
-  if (EFI_ERROR(Status)) {\r
-    return (Status);\r
-  }\r
-  Size = StrSize(L"\r\n") - sizeof(CHAR16);\r
-  return FileHandleWrite(Handle, &Size, L"\r\n");\r
-}\r
-\r
-/**\r
-  function to take a formatted argument and print it to a file.\r
-\r
-  @param[in] Handle   the file handle for the file to write to\r
-  @param[in] Format   the format argument (see printlib for format specifier)\r
-  @param[in] ...      the variable arguments for the format\r
-\r
-  @retval EFI_SUCCESS the operation was sucessful\r
-  @return other       a return value from FileHandleWriteLine\r
-\r
-  @sa FileHandleWriteLine\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileHandlePrintLine(\r
-  IN EFI_FILE_HANDLE  Handle,\r
-  IN CONST CHAR16     *Format,\r
-  ...\r
-  )\r
-{\r
-  VA_LIST           Marker;\r
-  CHAR16            *Buffer;\r
-  EFI_STATUS        Status;\r
-\r
-  VA_START (Marker, Format);\r
-\r
-  //\r
-  // Get a buffer to print into\r
-  //\r
-  Buffer = AllocateZeroPool (PcdGet16 (PcdShellPrintBufferSize));\r
-  ASSERT (Buffer != NULL);\r
-\r
-  //\r
-  // Print into our buffer\r
-  //\r
-  UnicodeVSPrint (Buffer, PcdGet16 (PcdShellPrintBufferSize), Format, Marker);\r
-\r
-  //\r
-  // Print buffer into file\r
-  //\r
-  Status = FileHandleWriteLine(Handle, Buffer);\r
-\r
-  //\r
-  // Cleanup and return\r
-  //\r
-  FreePool(Buffer);\r
-  return (Status);\r
-}\r
-\r
-/**\r
-  Function to determine if a FILE_HANDLE is at the end of the file.\r
-\r
-  This will NOT work on directories.\r
-\r
-  If Handle is NULL, then ASSERT.\r
-\r
-  @param[in] Handle     the file handle\r
-\r
-  @retval TRUE          the position is at the end of the file\r
-  @retval FALSE         the position is not at the end of the file\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-FileHandleEof(\r
-  IN EFI_FILE_HANDLE Handle\r
-  )\r
-{\r
-  EFI_FILE_INFO *Info;\r
-  UINT64        Pos;\r
-  BOOLEAN       RetVal;\r
-\r
-  //\r
-  // ASSERT if Handle is NULL\r
-  //\r
-  ASSERT(Handle != NULL);\r
-\r
-  FileHandleGetPosition(Handle, &Pos);\r
-  Info = FileHandleGetInfo (Handle);\r
-  ASSERT(Info != NULL);\r
-  FileHandleSetPosition(Handle, Pos);\r
-\r
-  if (Info == NULL) {\r
-    return (FALSE);\r
-  }\r
-\r
-  if (Pos == Info->FileSize) {\r
-    RetVal = TRUE;\r
-  } else {\r
-    RetVal = FALSE;\r
-  }\r
-\r
-  FreePool (Info);\r
-\r
-  return (RetVal);\r
-}\r
diff --git a/ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.inf b/ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.inf
deleted file mode 100644 (file)
index 05b61d3..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-##  @file\r
-# Provides interface to shell functionality for shell commands and applications.\r
-#\r
-# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved. <BR>\r
-#\r
-#  This program and the accompanying materials\r
-#  are licensed and made available under the terms and conditions of the BSD License\r
-#  which accompanies this distribution. The full text of the license may be found at\r
-#  http://opensource.org/licenses/bsd-license.php\r
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-#\r
-##\r
-\r
-[Defines]\r
-  INF_VERSION                    = 0x00010006\r
-  BASE_NAME                      = BaseFileHandleLib\r
-  FILE_GUID                      = 9495D344-9D8A-41f3-8D17-E2FD238C4E71\r
-  MODULE_TYPE                    = DXE_DRIVER\r
-  VERSION_STRING                 = 1.0\r
-  LIBRARY_CLASS                  = FileHandleLib|DXE_DRIVER UEFI_APPLICATION UEFI_DRIVER\r
-\r
-#\r
-#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
-#\r
-\r
-[Sources.common]\r
-  BaseFileHandleLib.c\r
-\r
-[Packages]\r
-  MdePkg/MdePkg.dec\r
-  ShellPkg/ShellPkg.dec\r
-\r
-[LibraryClasses]\r
-  MemoryAllocationLib\r
-  BaseLib\r
-  BaseMemoryLib\r
-  DebugLib\r
-  PrintLib\r
-  PcdLib\r
-\r
-[Protocols]\r
-  gEfiSimpleFileSystemProtocolGuid             # ALWAYS_USED\r
-\r
-[Guids]\r
-  gEfiFileInfoGuid                              # ALWAYS_CONSUMED\r
-\r
-[Pcd.common]\r
-  gEfiShellPkgTokenSpaceGuid.PcdShellPrintBufferSize # ALWAYS_CONSUMED\r
diff --git a/ShellPkg/Library/UefiFileHandleLib/UefiFileHandleLib.c b/ShellPkg/Library/UefiFileHandleLib/UefiFileHandleLib.c
new file mode 100644 (file)
index 0000000..fd8b7bb
--- /dev/null
@@ -0,0 +1,1155 @@
+/** @file\r
+  Provides interface to EFI_FILE_HANDLE functionality.\r
+\r
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved. <BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+\r
+#include <Protocol/SimpleFileSystem.h>\r
+#include <Protocol/UnicodeCollation.h>\r
+\r
+#include <Guid/FileInfo.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/FileHandleLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PrintLib.h>\r
+\r
+CONST UINT16 gUnicodeFileTag = EFI_UNICODE_BYTE_ORDER_MARK;\r
+\r
+#define MAX_FILE_NAME_LEN 522 // (20 * (6+5+2))+1) unicode characters from EFI FAT spec (doubled for bytes)\r
+#define FIND_XXXXX_FILE_BUFFER_SIZE (SIZE_OF_EFI_FILE_INFO + MAX_FILE_NAME_LEN)\r
+\r
+/**\r
+  This function will retrieve the information about the file for the handle\r
+  specified and store it in allocated pool memory.\r
+\r
+  This function allocates a buffer to store the file's information. It is the\r
+  caller's responsibility to free the buffer\r
+\r
+  @param  FileHandle  The file handle of the file for which information is\r
+  being requested.\r
+\r
+  @retval NULL information could not be retrieved.\r
+\r
+  @return the information about the file\r
+**/\r
+EFI_FILE_INFO*\r
+EFIAPI\r
+FileHandleGetInfo (\r
+  IN EFI_FILE_HANDLE            FileHandle\r
+  )\r
+{\r
+  EFI_FILE_INFO   *FileInfo;\r
+  UINTN           FileInfoSize;\r
+  EFI_STATUS      Status;\r
+\r
+  if (FileHandle == NULL) {\r
+    return (NULL);\r
+  }\r
+\r
+  //\r
+  // Get the required size to allocate\r
+  //\r
+  FileInfoSize = 0;\r
+  FileInfo = NULL;\r
+  Status = FileHandle->GetInfo(FileHandle,\r
+                               &gEfiFileInfoGuid,\r
+                               &FileInfoSize,\r
+                               NULL);\r
+  if (Status == EFI_BUFFER_TOO_SMALL){\r
+    //\r
+    // error is expected.  getting size to allocate\r
+    //\r
+    FileInfo = AllocateZeroPool(FileInfoSize);\r
+    //\r
+    // now get the information\r
+    //\r
+    Status = FileHandle->GetInfo(FileHandle,\r
+                                 &gEfiFileInfoGuid,\r
+                                 &FileInfoSize,\r
+                                 FileInfo);\r
+    //\r
+    // if we got an error free the memory and return NULL\r
+    //\r
+    if (EFI_ERROR(Status)) {\r
+      FreePool(FileInfo);\r
+      return NULL;\r
+    }\r
+  }\r
+  return (FileInfo);\r
+}\r
+\r
+/**\r
+  This function sets the information about the file for the opened handle\r
+  specified.\r
+\r
+  @param[in]  FileHandle        The file handle of the file for which information\r
+                                is being set.\r
+\r
+  @param[in]  FileInfo          The information to set.\r
+\r
+  @retval EFI_SUCCESS                  The information was set.\r
+  @retval EFI_INVALID_PARAMETER A parameter was out of range or invalid.\r
+  @retval EFI_UNSUPPORTED       The FileHandle does not support FileInfo.\r
+  @retval EFI_NO_MEDIA               The device has no medium.\r
+  @retval EFI_DEVICE_ERROR         The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_WRITE_PROTECTED    The file or medium is write protected.\r
+  @retval EFI_ACCESS_DENIED     The file was opened read only.\r
+  @retval EFI_VOLUME_FULL       The volume is full.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleSetInfo (\r
+  IN EFI_FILE_HANDLE           FileHandle,\r
+  IN CONST EFI_FILE_INFO        *FileInfo\r
+  )\r
+{\r
+\r
+  //\r
+  // ASSERT if the FileHandle or FileInfo is NULL\r
+  //\r
+  ASSERT (FileHandle != NULL);\r
+  ASSERT (FileInfo   != NULL);\r
+\r
+  //\r
+  // Set the info\r
+  //\r
+  return (FileHandle->SetInfo(FileHandle,\r
+                              &gEfiFileInfoGuid,\r
+                              (UINTN)FileInfo->Size,\r
+                              (EFI_FILE_INFO*)FileInfo));\r
+}\r
+\r
+/**\r
+  This function reads information from an opened file.\r
+\r
+  If FileHandle is not a directory, the function reads the requested number of\r
+  bytes from the file at the file's current position and returns them in Buffer.\r
+  If the read goes beyond the end of the file, the read length is truncated to the\r
+  end of the file. The file's current position is increased by the number of bytes\r
+  returned.  If FileHandle is a directory, the function reads the directory entry\r
+  at the file's current position and returns the entry in Buffer. If the Buffer\r
+  is not large enough to hold the current directory entry, then\r
+  EFI_BUFFER_TOO_SMALL is returned and the current file position is not updated.\r
+  BufferSize is set to be the size of the buffer needed to read the entry. On\r
+  success, the current position is updated to the next directory entry. If there\r
+  are no more directory entries, the read returns a zero-length buffer.\r
+  EFI_FILE_INFO is the structure returned as the directory entry.\r
+\r
+  @param FileHandle             the opened file handle\r
+  @param BufferSize             on input the size of buffer in bytes.  on return\r
+                                the number of bytes written.\r
+  @param Buffer                 the buffer to put read data into.\r
+\r
+  @retval EFI_SUCCESS           Data was read.\r
+  @retval EFI_NO_MEDIA          The device has no media.\r
+  @retval EFI_DEVICE_ERROR      The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
+  @retval EFI_BUFFER_TO_SMALL   Buffer is too small. ReadSize contains required\r
+                                size.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleRead(\r
+  IN EFI_FILE_HANDLE            FileHandle,\r
+  IN OUT UINTN                  *BufferSize,\r
+  OUT VOID                      *Buffer\r
+  )\r
+{\r
+  //\r
+  // ASSERT if FileHandle is NULL\r
+  //\r
+  ASSERT (FileHandle != NULL);\r
+\r
+  //\r
+  // Perform the read based on EFI_FILE_PROTOCOL\r
+  //\r
+  return (FileHandle->Read(FileHandle, BufferSize, Buffer));\r
+}\r
+\r
+\r
+/**\r
+  Write data to a file.\r
+\r
+  This function writes the specified number of bytes to the file at the current\r
+  file position. The current file position is advanced the actual number of bytes\r
+  written, which is returned in BufferSize. Partial writes only occur when there\r
+  has been a data error during the write attempt (such as "volume space full").\r
+  The file is automatically grown to hold the data if required. Direct writes to\r
+  opened directories are not supported.\r
+\r
+  @param FileHandle           The opened file for writing\r
+  @param BufferSize           on input the number of bytes in Buffer.  On output\r
+                              the number of bytes written.\r
+  @param Buffer               the buffer containing data to write is stored.\r
+\r
+ @retval EFI_SUCCESS           Data was written.\r
+ @retval EFI_UNSUPPORTED           Writes to an open directory are not supported.\r
+ @retval EFI_NO_MEDIA          The device has no media.\r
+ @retval EFI_DEVICE_ERROR          The device reported an error.\r
+ @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
+ @retval EFI_WRITE_PROTECTED   The device is write-protected.\r
+ @retval EFI_ACCESS_DENIED       The file was open for read only.\r
+ @retval EFI_VOLUME_FULL           The volume is full.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleWrite(\r
+  IN EFI_FILE_HANDLE            FileHandle,\r
+  IN OUT UINTN                  *BufferSize,\r
+  IN VOID                       *Buffer\r
+  )\r
+{\r
+  //\r
+  // ASSERT if FileHandle is NULL\r
+  //\r
+  ASSERT (FileHandle != NULL);\r
+  //\r
+  // Perform the write based on EFI_FILE_PROTOCOL\r
+  //\r
+  return (FileHandle->Write(FileHandle, BufferSize, Buffer));\r
+}\r
+\r
+/**\r
+  Close an open file handle.\r
+\r
+  This function closes a specified file handle. All "dirty" cached file data is\r
+  flushed to the device, and the file is closed. In all cases the handle is\r
+  closed.\r
+\r
+@param FileHandle               the file handle to close.\r
+\r
+@retval EFI_SUCCESS             the file handle was closed sucessfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleClose (\r
+  IN EFI_FILE_HANDLE            FileHandle\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  //\r
+  // ASSERT if FileHandle is NULL\r
+  //\r
+  ASSERT (FileHandle != NULL);\r
+  //\r
+  // Perform the Close based on EFI_FILE_PROTOCOL\r
+  //\r
+  Status = FileHandle->Close(FileHandle);\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Delete a file and close the handle\r
+\r
+  This function closes and deletes a file. In all cases the file handle is closed.\r
+  If the file cannot be deleted, the warning code EFI_WARN_DELETE_FAILURE is\r
+  returned, but the handle is still closed.\r
+\r
+  @param FileHandle             the file handle to delete\r
+\r
+  @retval EFI_SUCCESS           the file was closed sucessfully\r
+  @retval EFI_WARN_DELETE_FAILURE the handle was closed, but the file was not\r
+                                deleted\r
+  @retval INVALID_PARAMETER            One of the parameters has an invalid value.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleDelete (\r
+  IN EFI_FILE_HANDLE           FileHandle\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  //\r
+  // ASSERT if FileHandle is NULL\r
+  //\r
+  ASSERT (FileHandle != NULL);\r
+  //\r
+  // Perform the Delete based on EFI_FILE_PROTOCOL\r
+  //\r
+  Status = FileHandle->Delete(FileHandle);\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Set the current position in a file.\r
+\r
+  This function sets the current file position for the handle to the position\r
+  supplied. With the exception of seeking to position 0xFFFFFFFFFFFFFFFF, only\r
+  absolute positioning is supported, and seeking past the end of the file is\r
+  allowed (a subsequent write would grow the file). Seeking to position\r
+  0xFFFFFFFFFFFFFFFF causes the current position to be set to the end of the file.\r
+  If FileHandle is a directory, the only position that may be set is zero. This\r
+  has the effect of starting the read process of the directory entries over.\r
+\r
+  @param FileHandle             The file handle on which the position is being set\r
+  @param Position               Byte position from begining of file\r
+\r
+  @retval EFI_SUCCESS           Operation completed sucessfully.\r
+  @retval EFI_UNSUPPORTED       the seek request for non-zero is not valid on\r
+                                directories.\r
+  @retval INVALID_PARAMETER     One of the parameters has an invalid value.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleSetPosition (\r
+  IN EFI_FILE_HANDLE           FileHandle,\r
+  IN UINT64            Position\r
+  )\r
+{\r
+  //\r
+  // ASSERT if FileHandle is NULL\r
+  //\r
+  ASSERT (FileHandle != NULL);\r
+  //\r
+  // Perform the SetPosition based on EFI_FILE_PROTOCOL\r
+  //\r
+  return (FileHandle->SetPosition(FileHandle, Position));\r
+}\r
+\r
+/**\r
+  Gets a file's current position\r
+\r
+  This function retrieves the current file position for the file handle. For\r
+  directories, the current file position has no meaning outside of the file\r
+  system driver and as such the operation is not supported. An error is returned\r
+  if FileHandle is a directory.\r
+\r
+  @param FileHandle             The open file handle on which to get the position.\r
+  @param Position               Byte position from begining of file.\r
+\r
+  @retval EFI_SUCCESS           the operation completed sucessfully.\r
+  @retval INVALID_PARAMETER     One of the parameters has an invalid value.\r
+  @retval EFI_UNSUPPORTED       the request is not valid on directories.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleGetPosition (\r
+  IN EFI_FILE_HANDLE            FileHandle,\r
+  OUT UINT64                    *Position\r
+  )\r
+{\r
+  if (Position == NULL) {\r
+    return (EFI_INVALID_PARAMETER);\r
+  }\r
+  //\r
+  // ASSERT if FileHandle is NULL\r
+  //\r
+  ASSERT (FileHandle != NULL);\r
+  //\r
+  // Perform the GetPosition based on EFI_FILE_PROTOCOL\r
+  //\r
+  return (FileHandle->GetPosition(FileHandle, Position));\r
+}\r
+/**\r
+  Flushes data on a file\r
+\r
+  This function flushes all modified data associated with a file to a device.\r
+\r
+  @param FileHandle             The file handle on which to flush data\r
+\r
+  @retval EFI_SUCCESS           The data was flushed.\r
+  @retval EFI_NO_MEDIA          The device has no media.\r
+  @retval EFI_DEVICE_ERROR      The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
+  @retval EFI_WRITE_PROTECTED   The file or medium is write protected.\r
+  @retval EFI_ACCESS_DENIED     The file was opened for read only.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleFlush (\r
+  IN EFI_FILE_HANDLE            FileHandle\r
+  )\r
+{\r
+  //\r
+  // ASSERT if FileHandle is NULL\r
+  //\r
+  ASSERT (FileHandle != NULL);\r
+  //\r
+  // Perform the Flush based on EFI_FILE_PROTOCOL\r
+  //\r
+  return (FileHandle->Flush(FileHandle));\r
+}\r
+\r
+/**\r
+  function to determine if a given handle is a directory handle\r
+\r
+  if DirHandle is NULL then ASSERT()\r
+\r
+  open the file information on the DirHandle and verify that the Attribute\r
+  includes EFI_FILE_DIRECTORY bit set.\r
+\r
+  @param DirHandle              Handle to open file\r
+\r
+  @retval EFI_SUCCESS           DirHandle is a directory\r
+  @retval EFI_INVALID_PARAMETER DirHandle did not have EFI_FILE_INFO available\r
+  @retval EFI_NOT_FOUND         DirHandle is not a directory\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleIsDirectory (\r
+  IN EFI_FILE_HANDLE            DirHandle\r
+  )\r
+{\r
+  EFI_FILE_INFO *DirInfo;\r
+\r
+  //\r
+  // ASSERT if DirHandle is NULL\r
+  //\r
+  ASSERT(DirHandle != NULL);\r
+\r
+  //\r
+  // get the file information for DirHandle\r
+  //\r
+  DirInfo = FileHandleGetInfo (DirHandle);\r
+\r
+  //\r
+  // Parse DirInfo\r
+  //\r
+  if (DirInfo == NULL) {\r
+    //\r
+    // We got nothing...\r
+    //\r
+    return (EFI_INVALID_PARAMETER);\r
+  }\r
+  if ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {\r
+    //\r
+    // Attributes say this is not a directory\r
+    //\r
+    FreePool (DirInfo);\r
+    return (EFI_NOT_FOUND);\r
+  }\r
+  //\r
+  // all good...\r
+  //\r
+  FreePool (DirInfo);\r
+  return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+  Retrieves the first file from a directory\r
+\r
+  This function opens a directory and gets the first file's info in the\r
+  directory. Caller can use FileHandleFindNextFile() to get other files.  When\r
+  complete the caller is responsible for calling FreePool() on Buffer.\r
+\r
+  @param DirHandle              The file handle of the directory to search\r
+  @param Buffer                 Pointer to buffer for file's information\r
+\r
+  @retval EFI_SUCCESS           Found the first file.\r
+  @retval EFI_NOT_FOUND         Cannot find the directory.\r
+  @retval EFI_NO_MEDIA          The device has no media.\r
+  @retval EFI_DEVICE_ERROR      The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
+  @return Others                status of FileHandleGetInfo, FileHandleSetPosition,\r
+                                or FileHandleRead\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleFindFirstFile (\r
+  IN EFI_FILE_HANDLE            DirHandle,\r
+  OUT EFI_FILE_INFO             **Buffer\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  UINTN         BufferSize;\r
+\r
+  if (Buffer == NULL || DirHandle == NULL) {\r
+    return (EFI_INVALID_PARAMETER);\r
+  }\r
+\r
+  //\r
+  // verify that DirHandle is a directory\r
+  //\r
+  Status = FileHandleIsDirectory(DirHandle);\r
+  if (EFI_ERROR(Status)) {\r
+    return (Status);\r
+  }\r
+\r
+  //\r
+  // Allocate a buffer sized to struct size + enough for the string at the end\r
+  //\r
+  BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE;\r
+  *Buffer = AllocateZeroPool(BufferSize);\r
+  if (*Buffer == NULL){\r
+    return (EFI_OUT_OF_RESOURCES);\r
+  }\r
+\r
+  //\r
+  // reset to the begining of the directory\r
+  //\r
+  Status = FileHandleSetPosition(DirHandle, 0);\r
+  if (EFI_ERROR(Status)) {\r
+    FreePool(*Buffer);\r
+    *Buffer = NULL;\r
+    return (Status);\r
+  }\r
+\r
+  //\r
+  // read in the info about the first file\r
+  //\r
+  Status = FileHandleRead (DirHandle, &BufferSize, *Buffer);\r
+  ASSERT(Status != EFI_BUFFER_TOO_SMALL);\r
+  if (EFI_ERROR(Status)) {\r
+    FreePool(*Buffer);\r
+    *Buffer = NULL;\r
+    return (Status);\r
+  }\r
+  return (EFI_SUCCESS);\r
+}\r
+/**\r
+  Retrieves the next file in a directory.\r
+\r
+  To use this function, caller must call the FileHandleFindFirstFile() to get the\r
+  first file, and then use this function get other files. This function can be\r
+  called for several times to get each file's information in the directory. If\r
+  the call of FileHandleFindNextFile() got the last file in the directory, the next\r
+  call of this function has no file to get. *NoFile will be set to TRUE and the\r
+  Buffer memory will be automatically freed.\r
+\r
+  @param DirHandle              the file handle of the directory\r
+  @param Buffer                                    pointer to buffer for file's information\r
+  @param NoFile                                    pointer to boolean when last file is found\r
+\r
+  @retval EFI_SUCCESS           Found the next file, or reached last file\r
+  @retval EFI_NO_MEDIA          The device has no media.\r
+  @retval EFI_DEVICE_ERROR      The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleFindNextFile(\r
+  IN EFI_FILE_HANDLE             DirHandle,\r
+  OUT EFI_FILE_INFO              *Buffer,\r
+  OUT BOOLEAN                    *NoFile\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  UINTN         BufferSize;\r
+\r
+  //\r
+  // ASSERTs for DirHandle or Buffer or NoFile poitners being NULL\r
+  //\r
+  ASSERT (DirHandle != NULL);\r
+  ASSERT (Buffer    != NULL);\r
+  ASSERT (NoFile    != NULL);\r
+\r
+  //\r
+  // This BufferSize MUST stay equal to the originally allocated one in GetFirstFile\r
+  //\r
+  BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE;\r
+\r
+  //\r
+  // read in the info about the next file\r
+  //\r
+  Status = FileHandleRead (DirHandle, &BufferSize, Buffer);\r
+  ASSERT(Status != EFI_BUFFER_TOO_SMALL);\r
+  if (EFI_ERROR(Status)) {\r
+    return (Status);\r
+  }\r
+\r
+  //\r
+  // If we read 0 bytes (but did not have erros) we already read in the last file.\r
+  //\r
+  if (BufferSize == 0) {\r
+    FreePool(Buffer);\r
+    *NoFile = TRUE;\r
+  }\r
+\r
+  return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+  Retrieve the size of a file.\r
+\r
+  if FileHandle is NULL then ASSERT()\r
+  if Size is NULL then ASSERT()\r
+\r
+  This function extracts the file size info from the FileHandle's EFI_FILE_INFO\r
+  data.\r
+\r
+  @param FileHandle             file handle from which size is retrieved\r
+  @param Size                   pointer to size\r
+\r
+  @retval EFI_SUCCESS           operation was completed sucessfully\r
+  @retval EFI_DEVICE_ERROR      cannot access the file\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleGetSize (\r
+  IN EFI_FILE_HANDLE            FileHandle,\r
+  OUT UINT64                    *Size\r
+  )\r
+{\r
+  EFI_FILE_INFO                 *FileInfo;\r
+\r
+  //\r
+  // ASSERT for FileHandle or Size being NULL\r
+  //\r
+  ASSERT (FileHandle != NULL);\r
+  ASSERT (Size != NULL);\r
+\r
+  //\r
+  // get the FileInfo structure\r
+  //\r
+  FileInfo = FileHandleGetInfo(FileHandle);\r
+  if (FileInfo == NULL) {\r
+    return (EFI_DEVICE_ERROR);\r
+  }\r
+\r
+  //\r
+  // Assign the Size pointer to the correct value\r
+  //\r
+  *Size = FileInfo->FileSize;\r
+\r
+  //\r
+  // free the FileInfo memory\r
+  //\r
+  FreePool(FileInfo);\r
+\r
+  return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+  Set the size of a file.\r
+\r
+  If FileHandle is NULL then ASSERT().\r
+\r
+  This function changes the file size info from the FileHandle's EFI_FILE_INFO\r
+  data.\r
+\r
+  @param FileHandle             File handle whose size is to be changed.\r
+  @param Size                   New size.\r
+\r
+  @retval EFI_SUCCESS           operation was completed sucessfully.\r
+  @retval EFI_DEVICE_ERROR      cannot access the file.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleSetSize (\r
+  IN EFI_FILE_HANDLE            FileHandle,\r
+  IN UINT64                     Size\r
+  )\r
+{\r
+  EFI_FILE_INFO                 *FileInfo;\r
+  EFI_STATUS                    Status;\r
+\r
+  //\r
+  // ASSERT for FileHandle or Size being NULL\r
+  //\r
+  ASSERT (FileHandle != NULL);\r
+\r
+  //\r
+  // get the FileInfo structure\r
+  //\r
+  FileInfo = FileHandleGetInfo(FileHandle);\r
+  if (FileInfo == NULL) {\r
+    return (EFI_DEVICE_ERROR);\r
+  }\r
+\r
+  //\r
+  // Assign the FileSize pointer to the new value\r
+  //\r
+  FileInfo->FileSize = Size;\r
+\r
+  Status = FileHandleSetInfo(FileHandle, FileInfo);\r
+  //\r
+  // free the FileInfo memory\r
+  //\r
+  FreePool(FileInfo);\r
+\r
+  return (Status);\r
+}\r
+\r
+/**\r
+  Safely append (on the left) with automatic string resizing given length of Destination and\r
+  desired length of copy from Source.\r
+\r
+  append the first D characters of Source to the end of Destination, where D is\r
+  the lesser of Count and the StrLen() of Source. If appending those D characters\r
+  will fit within Destination (whose Size is given as CurrentSize) and\r
+  still leave room for a NULL terminator, then those characters are appended,\r
+  starting at the original terminating NULL of Destination, and a new terminating\r
+  NULL is appended.\r
+\r
+  If appending D characters onto Destination will result in a overflow of the size\r
+  given in CurrentSize the string will be grown such that the copy can be performed\r
+  and CurrentSize will be updated to the new size.\r
+\r
+  If Source is NULL, there is nothing to append, just return the current buffer in\r
+  Destination.\r
+\r
+  if Destination is NULL, then ASSERT()\r
+  if Destination's current length (including NULL terminator) is already more then\r
+  CurrentSize, then ASSERT()\r
+\r
+  @param[in,out] Destination   The String to append onto\r
+  @param[in,out] CurrentSize   on call the number of bytes in Destination.  On\r
+                                return possibly the new size (still in bytes).  if NULL\r
+                                then allocate whatever is needed.\r
+  @param[in]      Source        The String to append from\r
+  @param[in]      Count         Maximum number of characters to append.  if 0 then\r
+                                all are appended.\r
+\r
+  @return Destination           return the resultant string.\r
+**/\r
+CHAR16*\r
+EFIAPI\r
+StrnCatGrowLeft (\r
+  IN OUT CHAR16           **Destination,\r
+  IN OUT UINTN            *CurrentSize,\r
+  IN     CONST CHAR16     *Source,\r
+  IN     UINTN            Count\r
+  )\r
+{\r
+  UINTN DestinationStartSize;\r
+  UINTN NewSize;\r
+  UINTN CopySize;\r
+\r
+  //\r
+  // ASSERTs\r
+  //\r
+  ASSERT(Destination != NULL);\r
+\r
+  //\r
+  // If there's nothing to do then just return Destination\r
+  //\r
+  if (Source == NULL) {\r
+    return (*Destination);\r
+  }\r
+\r
+  //\r
+  // allow for NULL pointers address as Destination\r
+  //\r
+  if (*Destination != NULL) {\r
+    ASSERT(CurrentSize != 0);\r
+    DestinationStartSize = StrSize(*Destination);\r
+    ASSERT(DestinationStartSize <= *CurrentSize);\r
+  } else {\r
+    DestinationStartSize = 0;\r
+//    ASSERT(*CurrentSize == 0);\r
+  }\r
+\r
+  //\r
+  // Append all of Source?\r
+  //\r
+  if (Count == 0) {\r
+    Count = StrSize(Source);\r
+  }\r
+\r
+  //\r
+  // Test and grow if required\r
+  //\r
+  if (CurrentSize != NULL) {\r
+    NewSize = *CurrentSize;\r
+    while (NewSize < (DestinationStartSize + Count)) {\r
+      NewSize += 2 * Count;\r
+    }\r
+    *Destination = ReallocatePool(*CurrentSize, NewSize, *Destination);\r
+    *CurrentSize = NewSize;\r
+  } else {\r
+    *Destination = AllocateZeroPool(Count+sizeof(CHAR16));\r
+  }\r
+\r
+  CopySize = StrSize(*Destination);\r
+  CopyMem((*Destination)+((Count-2)/sizeof(CHAR16)), *Destination, CopySize);\r
+  CopyMem(*Destination, Source, Count-2);\r
+  return (*Destination);\r
+}\r
+\r
+/**\r
+  Function to get a full filename given a EFI_FILE_HANDLE somewhere lower on the\r
+  directory 'stack'.\r
+\r
+  if Handle is NULL, return EFI_INVALID_PARAMETER\r
+\r
+  @param[in] Handle             Handle to the Directory or File to create path to.\r
+  @param[out] FullFileName      pointer to pointer to generated full file name.  It\r
+                                is the responsibility of the caller to free this memory\r
+                                with a call to FreePool().\r
+  @retval EFI_SUCCESS           the operation was sucessful and the FullFileName is valid.\r
+  @retval EFI_INVALID_PARAMETER Handle was NULL.\r
+  @retval EFI_INVALID_PARAMETER FullFileName was NULL.\r
+  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleGetFileName (\r
+  IN CONST EFI_FILE_HANDLE      Handle,\r
+  OUT CHAR16                    **FullFileName\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  UINTN           Size;\r
+  EFI_FILE_HANDLE CurrentHandle;\r
+  EFI_FILE_HANDLE NextHigherHandle;\r
+  EFI_FILE_INFO   *FileInfo;\r
+\r
+  Size = 0;\r
+\r
+  //\r
+  // Check our parameters\r
+  //\r
+  if (FullFileName == NULL || Handle == NULL) {\r
+    return (EFI_INVALID_PARAMETER);\r
+  }\r
+\r
+  *FullFileName = NULL;\r
+  CurrentHandle = NULL;\r
+\r
+  Status = Handle->Open(Handle, &CurrentHandle, L".", EFI_FILE_MODE_READ, 0);\r
+  if (!EFI_ERROR(Status)) {\r
+    //\r
+    // Reverse out the current directory on the device\r
+    //\r
+    for (;;) {\r
+      FileInfo = FileHandleGetInfo(CurrentHandle);\r
+      if (FileInfo == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        break;\r
+      } else {\r
+        //\r
+        // We got info... do we have a name? if yes preceed the current path with it...\r
+        //\r
+        if (StrLen (FileInfo->FileName) == 0) {\r
+          if (*FullFileName == NULL) {\r
+            ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));\r
+            *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);\r
+          }\r
+          FreePool(FileInfo);\r
+          break;\r
+        } else {\r
+          if (*FullFileName == NULL) {\r
+            ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));\r
+            *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);\r
+          }\r
+          ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));\r
+          *FullFileName = StrnCatGrowLeft(FullFileName, &Size, FileInfo->FileName, 0);\r
+          *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);\r
+          FreePool(FileInfo);\r
+        }\r
+      }\r
+      //\r
+      // Move to the parent directory\r
+      //\r
+      Status = CurrentHandle->Open (CurrentHandle, &NextHigherHandle, L"..", EFI_FILE_MODE_READ, 0);\r
+      if (EFI_ERROR (Status)) {\r
+        break;\r
+      }\r
+\r
+      FileHandleClose(CurrentHandle);\r
+      CurrentHandle = NextHigherHandle;\r
+    }\r
+  } else if (Status == EFI_NOT_FOUND) {\r
+    Status = EFI_SUCCESS;\r
+    ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));\r
+    *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);\r
+  }\r
+\r
+  if (CurrentHandle != NULL) {\r
+    CurrentHandle->Close (CurrentHandle);\r
+  }\r
+\r
+  if (EFI_ERROR(Status) && *FullFileName != NULL) {\r
+    FreePool(*FullFileName);\r
+  }\r
+\r
+  return (Status);\r
+}\r
+\r
+/**\r
+  Function to read a single line from a file. The \n is not included in the returned\r
+  buffer.  The returned buffer must be callee freed.\r
+\r
+  If the position upon start is 0, then the Ascii Boolean will be set.  This should be\r
+  maintained and not changed for all operations with the same file.\r
+\r
+  @param[in]      Handle        FileHandle to read from.\r
+  @param[in,out]  Ascii         Boolean value for indicating whether the file is Ascii (TRUE) or UCS2 (FALSE);\r
+\r
+  @return                       The line of text from the file.\r
+\r
+  @sa FileHandleReadLine\r
+**/\r
+CHAR16*\r
+EFIAPI\r
+FileHandleReturnLine(\r
+  IN EFI_FILE_HANDLE            Handle,\r
+  IN OUT BOOLEAN                *Ascii\r
+  )\r
+{\r
+  CHAR16          *RetVal;\r
+  UINTN           Size;\r
+  EFI_STATUS      Status;\r
+\r
+  Size = 0;\r
+  RetVal = NULL;\r
+\r
+  Status = FileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii);\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    RetVal = AllocateZeroPool(Size);\r
+    Status = FileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii);\r
+  }\r
+  ASSERT_EFI_ERROR(Status);\r
+  if (EFI_ERROR(Status) && (RetVal != NULL)) {\r
+    FreePool(RetVal);\r
+    RetVal = NULL;\r
+  }\r
+  return (RetVal);\r
+}\r
+\r
+/**\r
+  Function to read a single line (up to but not including the \n) from a EFI_FILE_HANDLE.\r
+\r
+  If the position upon start is 0, then the Ascii Boolean will be set.  This should be\r
+  maintained and not changed for all operations with the same file.\r
+\r
+  @param[in]      Handle        FileHandle to read from\r
+  @param[in,out]  Buffer        pointer to buffer to read into\r
+  @param[in,out]  Size          pointer to number of bytes in buffer\r
+  @param[in]      Truncate      if TRUE then allows for truncation of the line to fit.\r
+                                if FALSE will reset the position to the begining of the\r
+                                line if the buffer is not large enough.\r
+  @param[in,out]  Ascii         Boolean value for indicating whether the file is Ascii (TRUE) or UCS2 (FALSE);\r
+\r
+  @retval EFI_SUCCESS           the operation was sucessful.  the line is stored in\r
+                                Buffer.\r
+  @retval EFI_INVALID_PARAMETER Handle was NULL.\r
+  @retval EFI_INVALID_PARAMETER Size was NULL.\r
+  @retval EFI_BUFFER_TOO_SMALL  Size was not enough space to store the line.\r
+                                Size was updated to minimum space required.\r
+  @sa FileHandleRead\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleReadLine(\r
+  IN EFI_FILE_HANDLE            Handle,\r
+  IN OUT CHAR16                 *Buffer,\r
+  IN OUT UINTN                  *Size,\r
+  IN BOOLEAN                    Truncate,\r
+  IN OUT BOOLEAN                *Ascii\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  CHAR16      CharBuffer;\r
+  UINTN       CharSize;\r
+  UINTN       CountSoFar;\r
+  UINT64      OriginalFilePosition;\r
+\r
+\r
+  if (Handle == NULL\r
+    ||Size   == NULL\r
+   ){\r
+    return (EFI_INVALID_PARAMETER);\r
+  }\r
+  if (Buffer == NULL) {\r
+    ASSERT(*Size == 0);\r
+  } else {\r
+    *Buffer = CHAR_NULL;\r
+  }\r
+  FileHandleGetPosition(Handle, &OriginalFilePosition);\r
+  if (OriginalFilePosition == 0) {\r
+    CharSize = sizeof(CHAR16);\r
+    Status = FileHandleRead(Handle, &CharSize, &CharBuffer);\r
+    ASSERT_EFI_ERROR(Status);\r
+    if (CharBuffer == gUnicodeFileTag) {\r
+      *Ascii = FALSE;\r
+    } else {\r
+      *Ascii = TRUE;\r
+      FileHandleSetPosition(Handle, OriginalFilePosition);\r
+    }\r
+  }\r
+\r
+  for (CountSoFar = 0;;CountSoFar++){\r
+    CharBuffer = 0;\r
+    if (*Ascii) {\r
+      CharSize = sizeof(CHAR8);\r
+    } else {\r
+      CharSize = sizeof(CHAR16);\r
+    }\r
+    Status = FileHandleRead(Handle, &CharSize, &CharBuffer);\r
+    if (  EFI_ERROR(Status)\r
+       || CharSize == 0\r
+       || (CharBuffer == L'\n' && !(*Ascii))\r
+       || (CharBuffer ==  '\n' && *Ascii)\r
+     ){\r
+      break;\r
+    }\r
+    //\r
+    // if we have space save it...\r
+    //\r
+    if ((CountSoFar+1)*sizeof(CHAR16) < *Size){\r
+      ASSERT(Buffer != NULL);\r
+      ((CHAR16*)Buffer)[CountSoFar] = CharBuffer;\r
+      ((CHAR16*)Buffer)[CountSoFar+1] = CHAR_NULL;\r
+    }\r
+  }\r
+\r
+  //\r
+  // if we ran out of space tell when...\r
+  //\r
+  if ((CountSoFar+1)*sizeof(CHAR16) > *Size){\r
+    *Size = (CountSoFar+1)*sizeof(CHAR16);\r
+    if (!Truncate) {\r
+      FileHandleSetPosition(Handle, OriginalFilePosition);\r
+    } else {\r
+      DEBUG((DEBUG_WARN, "The line was truncated in FileHandleReadLine"));\r
+    }\r
+    return (EFI_BUFFER_TOO_SMALL);\r
+  }\r
+  while(Buffer[StrLen(Buffer)-1] == L'\r') {\r
+    Buffer[StrLen(Buffer)-1] = CHAR_NULL;\r
+  }\r
+\r
+  return (Status);\r
+}\r
+\r
+/**\r
+  function to write a line of unicode text to a file.\r
+\r
+  if Handle is NULL, ASSERT.\r
+  if Buffer is NULL, do nothing.  (return SUCCESS)\r
+\r
+  @param[in]     Handle         FileHandle to write to\r
+  @param[in]     Buffer         Buffer to write\r
+\r
+  @retval  EFI_SUCCESS          the data was written.\r
+  @retval  other                failure.\r
+\r
+  @sa FileHandleWrite\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandleWriteLine(\r
+  IN EFI_FILE_HANDLE Handle,\r
+  IN CHAR16          *Buffer\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  UINTN      Size;\r
+\r
+  ASSERT(Handle != NULL);\r
+\r
+  if (Buffer == NULL) {\r
+    return (EFI_SUCCESS);\r
+  }\r
+\r
+  Size = StrSize(Buffer) - sizeof(Buffer[0]);\r
+  Status = FileHandleWrite(Handle, &Size, Buffer);\r
+  if (EFI_ERROR(Status)) {\r
+    return (Status);\r
+  }\r
+  Size = StrSize(L"\r\n") - sizeof(CHAR16);\r
+  return FileHandleWrite(Handle, &Size, L"\r\n");\r
+}\r
+\r
+/**\r
+  function to take a formatted argument and print it to a file.\r
+\r
+  @param[in] Handle   the file handle for the file to write to\r
+  @param[in] Format   the format argument (see printlib for format specifier)\r
+  @param[in] ...      the variable arguments for the format\r
+\r
+  @retval EFI_SUCCESS the operation was sucessful\r
+  @return other       a return value from FileHandleWriteLine\r
+\r
+  @sa FileHandleWriteLine\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileHandlePrintLine(\r
+  IN EFI_FILE_HANDLE  Handle,\r
+  IN CONST CHAR16     *Format,\r
+  ...\r
+  )\r
+{\r
+  VA_LIST           Marker;\r
+  CHAR16            *Buffer;\r
+  EFI_STATUS        Status;\r
+\r
+  VA_START (Marker, Format);\r
+\r
+  //\r
+  // Get a buffer to print into\r
+  //\r
+  Buffer = AllocateZeroPool (PcdGet16 (PcdShellPrintBufferSize));\r
+  ASSERT (Buffer != NULL);\r
+\r
+  //\r
+  // Print into our buffer\r
+  //\r
+  UnicodeVSPrint (Buffer, PcdGet16 (PcdShellPrintBufferSize), Format, Marker);\r
+\r
+  //\r
+  // Print buffer into file\r
+  //\r
+  Status = FileHandleWriteLine(Handle, Buffer);\r
+\r
+  //\r
+  // Cleanup and return\r
+  //\r
+  FreePool(Buffer);\r
+  return (Status);\r
+}\r
+\r
+/**\r
+  Function to determine if a FILE_HANDLE is at the end of the file.\r
+\r
+  This will NOT work on directories.\r
+\r
+  If Handle is NULL, then ASSERT.\r
+\r
+  @param[in] Handle     the file handle\r
+\r
+  @retval TRUE          the position is at the end of the file\r
+  @retval FALSE         the position is not at the end of the file\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+FileHandleEof(\r
+  IN EFI_FILE_HANDLE Handle\r
+  )\r
+{\r
+  EFI_FILE_INFO *Info;\r
+  UINT64        Pos;\r
+  BOOLEAN       RetVal;\r
+\r
+  //\r
+  // ASSERT if Handle is NULL\r
+  //\r
+  ASSERT(Handle != NULL);\r
+\r
+  FileHandleGetPosition(Handle, &Pos);\r
+  Info = FileHandleGetInfo (Handle);\r
+  ASSERT(Info != NULL);\r
+  FileHandleSetPosition(Handle, Pos);\r
+\r
+  if (Info == NULL) {\r
+    return (FALSE);\r
+  }\r
+\r
+  if (Pos == Info->FileSize) {\r
+    RetVal = TRUE;\r
+  } else {\r
+    RetVal = FALSE;\r
+  }\r
+\r
+  FreePool (Info);\r
+\r
+  return (RetVal);\r
+}\r
diff --git a/ShellPkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf b/ShellPkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
new file mode 100644 (file)
index 0000000..dbeb6ba
--- /dev/null
@@ -0,0 +1,50 @@
+##  @file\r
+# Provides interface to shell functionality for shell commands and applications.\r
+#\r
+# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved. <BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010006\r
+  BASE_NAME                      = BaseFileHandleLib\r
+  FILE_GUID                      = 9495D344-9D8A-41f3-8D17-E2FD238C4E71\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = FileHandleLib|DXE_DRIVER UEFI_APPLICATION UEFI_DRIVER\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  UefiFileHandleLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+\r
+[LibraryClasses]\r
+  MemoryAllocationLib\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  PrintLib\r
+  PcdLib\r
+\r
+[Protocols]\r
+  gEfiSimpleFileSystemProtocolGuid             # ALWAYS_USED\r
+\r
+[Guids]\r
+  gEfiFileInfoGuid                              # ALWAYS_CONSUMED\r
+\r
+[Pcd.common]\r
+  gEfiShellPkgTokenSpaceGuid.PcdShellPrintBufferSize # ALWAYS_CONSUMED\r