summaryrefslogtreecommitdiff
path: root/ShellPkg/Library/BaseFileHandleLib
diff options
context:
space:
mode:
authorjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>2009-06-16 00:23:19 +0000
committerjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>2009-06-16 00:23:19 +0000
commitb1f95a06ca1a66ad15b3d8843fb4c7563c5350d2 (patch)
treecf88e0c20fe3952951914456198608b58c471aa1 /ShellPkg/Library/BaseFileHandleLib
parent14e96c2996a138b22f544da4d7921782ef85e51e (diff)
downloadedk2-platforms-b1f95a06ca1a66ad15b3d8843fb4c7563c5350d2.tar.xz
Updating with new functions and adding "C" style entrypoint library with example application.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8564 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ShellPkg/Library/BaseFileHandleLib')
-rw-r--r--ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.c304
1 files changed, 300 insertions, 4 deletions
diff --git a/ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.c b/ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.c
index 87b5772488..023210e8e0 100644
--- a/ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.c
+++ b/ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.c
@@ -14,11 +14,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Uefi.h>
-#include <Library/ShellLib.h>
+#include <Protocol/SimpleFileSystem.h>
+
+#include <Guid/FileInfo.h>
+
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
-
-#include <Protocol/SimpleFileSystem.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
#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)
@@ -620,4 +623,297 @@ FileHandleGetSize (
FreePool(FileInfo);
return (EFI_SUCCESS);
-} \ No newline at end of file
+}
+
+
+/**
+ 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;
+
+ //
+ // 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 = StrLen(Source);
+ }
+
+ //
+ // Test and grow if required
+ //
+ if (CurrentSize != NULL) {
+ NewSize = *CurrentSize;
+ while (NewSize < (DestinationStartSize + (Count*sizeof(CHAR16)))) {
+ NewSize += 2 * Count * sizeof(CHAR16);
+ }
+ *Destination = ReallocatePool(*CurrentSize, NewSize, *Destination);
+ *CurrentSize = NewSize;
+ } else {
+ *Destination = AllocateZeroPool((Count+1)*sizeof(CHAR16));
+ }
+
+ *Destination = CopyMem(*Destination+StrLen(Source), *Destination, StrSize(*Destination));
+ *Destination = CopyMem(*Destination, Source, StrLen(Source));
+ 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;
+ *FullFileName = NULL;
+
+ //
+ // Check our parameters
+ //
+ if (FullFileName == NULL || Handle == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ 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) {
+ *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);
+ FreePool(FileInfo);
+ break;
+ } else {
+ *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;
+ }
+ }
+
+ if (CurrentHandle != NULL) {
+ CurrentHandle->Close (CurrentHandle);
+ }
+
+ if (EFI_ERROR(Status) && *FullFileName != NULL) {
+ FreePool(FullFileName);
+ }
+
+ return (Status);
+}
+
+/**
+ Function to read a single line (up to but not including the \n) from a 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.
+
+ @retval EFI_SUCCESS the operation was sucessful. the line is stored in
+ Buffer.
+ @retval EFI_INVALID_PARAMETER Handle was NULL.
+ @retval EFI_INVALID_PARAMETER Buffer 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 VOID *Buffer,
+ IN OUT UINTN *Size,
+ IN BOOLEAN Truncate
+ ){
+ EFI_STATUS Status;
+ CHAR16 CharBuffer;
+ UINTN CharSize;
+ UINTN CountSoFar;
+ UINT64 Position;
+
+
+ if (Handle == NULL
+ ||Buffer == NULL
+ ||Size == NULL
+ ){
+ return (EFI_INVALID_PARAMETER);
+ }
+ FileHandleGetPosition(Handle, &Position);
+
+ for (CountSoFar = 0;;CountSoFar++){
+ CharSize = sizeof(CharBuffer);
+ Status = FileHandleRead(Handle, &CharSize, &CharBuffer);
+ if ( EFI_ERROR(Status)
+ || CharSize == 0
+ || CharBuffer == '\n'
+ ){
+ break;
+ }
+ //
+ // if we have space save it...
+ //
+ if ((CountSoFar+1)*sizeof(CHAR16) < *Size){
+ ((CHAR16*)Buffer)[CountSoFar] = CharBuffer;
+ ((CHAR16*)Buffer)[CountSoFar+1] = '\0';
+ }
+ }
+
+ //
+ // if we ran out of space tell when...
+ //
+ if ((CountSoFar+1)*sizeof(CHAR16) > *Size){
+ *Size = (CountSoFar+1)*sizeof(CHAR16);
+ if (Truncate == FALSE) {
+ FileHandleSetPosition(Handle, Position);
+ } else {
+ DEBUG((DEBUG_WARN, "The line was truncated in ReadLine"));
+ }
+ return (EFI_BUFFER_TOO_SMALL);
+ }
+ *Size = (CountSoFar+1)*sizeof(CHAR16);
+ 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 = StrLen(Buffer);
+ Status = FileHandleWrite(Handle, &Size, Buffer);
+ if (EFI_ERROR(Status)) {
+ return (Status);
+ }
+ Size = StrLen(L"\r\n");
+ return FileHandleWrite(Handle, &Size, L"\r\n");
+}