/** @file\r
Provides interface to EFI_FILE_HANDLE functionality.\r
\r
- Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved. <BR>\r
+ Copyright (c) 2006 - 2017, 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
\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
- // 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
+ \r
+ if (Buffer != NULL && *Size != 0) {\r
*Buffer = CHAR_NULL;\r
- }\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
-\r
- if Handle is NULL, return error.\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
+ Function to write a line of text to a file.\r
+ \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, if NULL the function will\r
+ take no action and return EFI_SUCCESS.\r
+\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
if (Handle == NULL) {\r
return (EFI_INVALID_PARAMETER);\r
}\r
-\r
- Size = StrSize(Buffer) - sizeof(Buffer[0]);\r
- Status = FileHandleWrite(Handle, &Size, Buffer);\r
+ \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
- Size = StrSize(L"\r\n") - sizeof(CHAR16);\r
- return FileHandleWrite(Handle, &Size, L"\r\n");\r
+ \r
+ Status = FileHandleSetPosition(Handle, 0);\r
+ if (EFI_ERROR(Status)) {\r
+ return Status;\r
+ }\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