/** @file\r
Provides interface to EFI_FILE_HANDLE functionality.\r
\r
- Copyright (c) 2006 - 2014, 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
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved. <BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
\r
@param FileHandle the file handle to close.\r
\r
-@retval EFI_SUCCESS the file handle was closed sucessfully.\r
+@retval EFI_SUCCESS the file handle was closed successfully.\r
**/\r
EFI_STATUS\r
EFIAPI\r
\r
@param FileHandle the file handle to delete\r
\r
- @retval EFI_SUCCESS the file was closed sucessfully\r
+ @retval EFI_SUCCESS the file was closed successfully\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
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
+ @param Position Byte position from beginning of file\r
\r
- @retval EFI_SUCCESS Operation completed sucessfully.\r
+ @retval EFI_SUCCESS Operation completed successfully.\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
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
+ @param Position Byte position from beginning of file.\r
\r
- @retval EFI_SUCCESS the operation completed sucessfully.\r
+ @retval EFI_SUCCESS the operation completed successfully.\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
}\r
\r
/**\r
- function to determine if a given handle is a directory handle\r
-\r
- if DirHandle is NULL then return error\r
+ Function to determine if a given handle is a directory handle.\r
\r
- open the file information on the DirHandle and verify that the Attribute\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
+ @param[in] 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
+ @retval EFI_SUCCESS DirHandle is a directory.\r
+ @retval EFI_INVALID_PARAMETER DirHandle is NULL.\r
+ The file information returns from FileHandleGetInfo is NULL.\r
+ @retval EFI_NOT_FOUND DirHandle is not a directory.\r
**/\r
EFI_STATUS\r
EFIAPI\r
}\r
\r
//\r
- // reset to the begining of the directory\r
+ // reset to the beginning of the directory\r
//\r
Status = FileHandleSetPosition(DirHandle, 0);\r
if (EFI_ERROR(Status)) {\r
/**\r
Retrieve the size of a file.\r
\r
- if FileHandle is NULL then return error\r
- if Size is NULL then return error\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
+ @param[in] FileHandle The file handle from which size is retrieved.\r
+ @param[out] Size The pointer to size.\r
\r
- @retval EFI_SUCCESS operation was completed sucessfully\r
- @retval EFI_DEVICE_ERROR cannot access the file\r
+ @retval EFI_SUCCESS Operation was completed successfully.\r
+ @retval EFI_DEVICE_ERROR Cannot access the file.\r
+ @retval EFI_INVALID_PARAMETER FileHandle is NULL.\r
+ Size is NULL.\r
**/\r
EFI_STATUS\r
EFIAPI\r
/**\r
Set the size of a file.\r
\r
- If FileHandle is NULL then return error.\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
+ @param[in] FileHandle The file handle whose size is to be changed.\r
+ @param[in] Size The new size.\r
\r
- @retval EFI_SUCCESS operation was completed sucessfully.\r
- @retval EFI_DEVICE_ERROR cannot access the file.\r
+ @retval EFI_SUCCESS The operation completed successfully.\r
+ @retval EFI_DEVICE_ERROR Cannot access the file.\r
+ @retval EFI_INVALID_PARAMETER FileHandle is NULL.\r
**/\r
EFI_STATUS\r
EFIAPI\r
\r
/**\r
Function to get a full filename given a EFI_FILE_HANDLE somewhere lower on the\r
- directory 'stack'.\r
+ directory 'stack'. If the file is a directory, then append the '\' char at the\r
+ end of name string. If it's not a directory, then the last '\' should not be\r
+ added.\r
\r
if Handle is NULL, return EFI_INVALID_PARAMETER\r
\r
break;\r
} else {\r
//\r
- // We got info... do we have a name? if yes preceed the current path with it...\r
+ // We got info... do we have a name? if yes precede the current path with it...\r
//\r
if (StrLen (FileInfo->FileName) == 0) {\r
if (*FullFileName == NULL) {\r
*FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);\r
}\r
\r
+ if (*FullFileName != NULL &&\r
+ (*FullFileName)[StrLen(*FullFileName) - 1] == L'\\' &&\r
+ StrLen(*FullFileName) > 1 &&\r
+ FileHandleIsDirectory(Handle) == EFI_NOT_FOUND\r
+ ) {\r
+ (*FullFileName)[StrLen(*FullFileName) - 1] = CHAR_NULL;\r
+ }\r
+\r
if (CurrentHandle != NULL) {\r
CurrentHandle->Close (CurrentHandle);\r
}\r
}\r
\r
/**\r
- Function to read a single line (up to but not including the \n) from a EFI_FILE_HANDLE.\r
+ Function to read a single line (up to but not including the \n) from a file.\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
+ The function will not return the \r and \n character in buffer. When an empty line is\r
+ read a CHAR_NULL character will be returned in buffer.\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
+ @param[in] Handle FileHandle to read from.\r
+ @param[in, out] Buffer The pointer to buffer to read into.\r
+ @param[in, out] Size The pointer to number of bytes in Buffer.\r
+ @param[in] Truncate If the buffer is large enough, this has no effect.\r
+ If the buffer is is too small and Truncate is TRUE,\r
+ the line will be truncated.\r
+ If the buffer is is too small and Truncate is FALSE,\r
+ then no read will occur.\r
+\r
+ @param[in, out] Ascii Boolean value for indicating whether the file is\r
+ Ascii (TRUE) or UCS2 (FALSE).\r
+\r
+ @retval EFI_SUCCESS The operation was successful. 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
+ @retval EFI_BUFFER_TOO_SMALL Size was not large enough to store the line.\r
+ Size was updated to the minimum space required.\r
@sa FileHandleRead\r
**/\r
EFI_STATUS\r
{\r
EFI_STATUS Status;\r
CHAR16 CharBuffer;\r
+ UINT64 FileSize;\r
UINTN CharSize;\r
UINTN CountSoFar;\r
+ UINTN CrCount;\r
UINT64 OriginalFilePosition;\r
\r
-\r
if (Handle == NULL\r
||Size == NULL\r
||(Buffer==NULL&&*Size!=0)\r
){\r
return (EFI_INVALID_PARAMETER);\r
}\r
- if (Buffer != NULL) {\r
+\r
+ if (Buffer != NULL && *Size != 0) {\r
*Buffer = CHAR_NULL;\r
}\r
+\r
+ Status = FileHandleGetSize (Handle, &FileSize);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ } else if (FileSize == 0) {\r
+ *Ascii = TRUE;\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
FileHandleGetPosition(Handle, &OriginalFilePosition);\r
if (OriginalFilePosition == 0) {\r
CharSize = sizeof(CHAR16);\r
}\r
}\r
\r
+ CrCount = 0;\r
for (CountSoFar = 0;;CountSoFar++){\r
CharBuffer = 0;\r
if (*Ascii) {\r
|| (CharBuffer == '\n' && *Ascii)\r
){\r
break;\r
+ } else if (\r
+ (CharBuffer == L'\r' && !(*Ascii)) ||\r
+ (CharBuffer == '\r' && *Ascii)\r
+ ) {\r
+ CrCount++;\r
+ continue;\r
}\r
//\r
// if we have space save it...\r
//\r
- if ((CountSoFar+1)*sizeof(CHAR16) < *Size){\r
+ if ((CountSoFar+1-CrCount)*sizeof(CHAR16) < *Size){\r
ASSERT(Buffer != NULL);\r
- ((CHAR16*)Buffer)[CountSoFar] = CharBuffer;\r
- ((CHAR16*)Buffer)[CountSoFar+1] = CHAR_NULL;\r
+ ((CHAR16*)Buffer)[CountSoFar-CrCount] = CharBuffer;\r
+ ((CHAR16*)Buffer)[CountSoFar+1-CrCount] = 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 ((CountSoFar+1-CrCount)*sizeof(CHAR16) > *Size){\r
+ *Size = (CountSoFar+1-CrCount)*sizeof(CHAR16);\r
if (!Truncate) {\r
+ if (Buffer != NULL && *Size != 0) {\r
+ ZeroMem(Buffer, *Size);\r
+ }\r
FileHandleSetPosition(Handle, OriginalFilePosition);\r
+ return (EFI_BUFFER_TOO_SMALL);\r
} else {\r
DEBUG((DEBUG_WARN, "The line was truncated in FileHandleReadLine"));\r
+ return (EFI_SUCCESS);\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
+ Function to write a line of text to a file.\r
\r
- if Handle is NULL, return error.\r
- if Buffer is NULL, do nothing. (return SUCCESS)\r
+ If the file is a Unicode file (with UNICODE file tag) then write the unicode\r
+ text.\r
+ If the file is an ASCII file then write the ASCII text.\r
+ If the size of file is zero (without file tag at the beginning) then write\r
+ ASCII text as default.\r
\r
- @param[in] Handle FileHandle to write to\r
- @param[in] Buffer Buffer to write\r
+ @param[in] Handle FileHandle to write to.\r
+ @param[in] Buffer Buffer to write, if NULL the function will\r
+ take no action and return EFI_SUCCESS.\r
\r
- @retval EFI_SUCCESS the data was written.\r
- @retval other failure.\r
+ @retval EFI_SUCCESS The data was written.\r
+ Buffer is NULL.\r
+ @retval EFI_INVALID_PARAMETER Handle is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate temporary space for ASCII\r
+ string due to out of resources.\r
\r
@sa FileHandleWrite\r
**/\r
IN CHAR16 *Buffer\r
)\r
{\r
- EFI_STATUS Status;\r
- UINTN Size;\r
+ EFI_STATUS Status;\r
+ CHAR16 CharBuffer;\r
+ UINTN Size;\r
+ UINTN Index;\r
+ UINTN CharSize;\r
+ UINT64 FileSize;\r
+ UINT64 OriginalFilePosition;\r
+ BOOLEAN Ascii;\r
+ CHAR8 *AsciiBuffer;\r
\r
if (Buffer == NULL) {\r
return (EFI_SUCCESS);\r
return (EFI_INVALID_PARAMETER);\r
}\r
\r
- Size = StrSize(Buffer) - sizeof(Buffer[0]);\r
- Status = FileHandleWrite(Handle, &Size, Buffer);\r
+ Ascii = FALSE;\r
+ AsciiBuffer = NULL;\r
+\r
+ Status = FileHandleGetPosition(Handle, &OriginalFilePosition);\r
if (EFI_ERROR(Status)) {\r
- return (Status);\r
+ return Status;\r
+ }\r
+\r
+ Status = FileHandleSetPosition(Handle, 0);\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
+ Status = FileHandleGetSize(Handle, &FileSize);\r
+ if (EFI_ERROR(Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (FileSize == 0) {\r
+ Ascii = TRUE;\r
+ } else {\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
+ }\r
+ }\r
+\r
+ Status = FileHandleSetPosition(Handle, OriginalFilePosition);\r
+ if (EFI_ERROR(Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (Ascii) {\r
+ Size = ( StrSize(Buffer) / sizeof(CHAR16) ) * sizeof(CHAR8);\r
+ AsciiBuffer = (CHAR8 *)AllocateZeroPool(Size);\r
+ if (AsciiBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ UnicodeStrToAsciiStrS (Buffer, AsciiBuffer, Size);\r
+ for (Index = 0; Index < Size; Index++) {\r
+ if ((AsciiBuffer[Index] & BIT7) != 0) {\r
+ FreePool(AsciiBuffer);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+\r
+ Size = AsciiStrSize(AsciiBuffer) - sizeof(CHAR8);\r
+ Status = FileHandleWrite(Handle, &Size, AsciiBuffer);\r
+ if (EFI_ERROR(Status)) {\r
+ FreePool (AsciiBuffer);\r
+ return (Status);\r
+ }\r
+ Size = AsciiStrSize("\r\n") - sizeof(CHAR8);\r
+ Status = FileHandleWrite(Handle, &Size, "\r\n");\r
+ } else {\r
+ if (OriginalFilePosition == 0) {\r
+ Status = FileHandleSetPosition (Handle, sizeof(CHAR16));\r
+ if (EFI_ERROR(Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+ Size = StrSize(Buffer) - sizeof(CHAR16);\r
+ Status = FileHandleWrite(Handle, &Size, Buffer);\r
+ if (EFI_ERROR(Status)) {\r
+ return (Status);\r
+ }\r
+ Size = StrSize(L"\r\n") - sizeof(CHAR16);\r
+ Status = FileHandleWrite(Handle, &Size, L"\r\n");\r
+ }\r
+\r
+ if (AsciiBuffer != NULL) {\r
+ FreePool (AsciiBuffer);\r
+ }\r
+ return Status;\r
}\r
\r
/**\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
+ @retval EFI_SUCCESS the operation was successful\r
@return other a return value from FileHandleWriteLine\r
\r
@sa FileHandleWriteLine\r