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