+++ /dev/null
-/** @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
+++ /dev/null
-## @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
--- /dev/null
+/** @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
--- /dev/null
+## @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