]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.c
MdePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdePkg / Library / UefiFileHandleLib / UefiFileHandleLib.c
index be66c57bb8f50e67826e4ced1eef4354188de0cd..96913c5c02b8deddbc80bdc0fa08f58febb110e5 100644 (file)
@@ -1,14 +1,8 @@
 /** @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
@@ -231,7 +225,7 @@ FileHandleWrite(
 \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
@@ -261,7 +255,7 @@ FileHandleClose (
 \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
@@ -297,9 +291,9 @@ FileHandleDelete (
   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
@@ -330,9 +324,9 @@ FileHandleSetPosition (
   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
@@ -383,18 +377,17 @@ FileHandleFlush (
 }\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
@@ -490,7 +483,7 @@ FileHandleFindFirstFile (
   }\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
@@ -576,17 +569,16 @@ FileHandleFindNextFile(
 /**\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
@@ -625,16 +617,15 @@ FileHandleGetSize (
 /**\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
@@ -772,7 +763,9 @@ StrnCatGrowLeft (
 \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
@@ -822,7 +815,7 @@ FileHandleGetFileName (
         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
@@ -859,6 +852,14 @@ FileHandleGetFileName (
     *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
@@ -912,25 +913,31 @@ FileHandleReturnLine(
 }\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
@@ -945,20 +952,31 @@ FileHandleReadLine(
 {\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
@@ -972,6 +990,7 @@ FileHandleReadLine(
     }\r
   }\r
 \r
+  CrCount = 0;\r
   for (CountSoFar = 0;;CountSoFar++){\r
     CharBuffer = 0;\r
     if (*Ascii) {\r
@@ -986,47 +1005,61 @@ FileHandleReadLine(
        || (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
@@ -1037,8 +1070,15 @@ FileHandleWriteLine(
   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
@@ -1048,13 +1088,84 @@ FileHandleWriteLine(
     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
@@ -1064,7 +1175,7 @@ FileHandleWriteLine(
   @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