]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Nt32Pkg/WinNtSimpleFileSystemDxe/WinNtSimpleFileSystem.c
UefiCpuPkg: Remove double \r
[mirror_edk2.git] / Nt32Pkg / WinNtSimpleFileSystemDxe / WinNtSimpleFileSystem.c
index 92fb38415fa1be91fc04284a48ffccb7a0d7f7c7..f13f82eee22be537d17d5007b64d3fe51fc492bd 100644 (file)
@@ -1,13 +1,7 @@
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. 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
+/**@file\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 - 2017, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 Module Name:\r
 \r
@@ -22,7 +16,7 @@ Abstract:
 \r
   * Other names and brands may be claimed as the property of others.\r
 \r
---*/\r
+**/\r
 \r
 //\r
 // The package level header files this module uses\r
@@ -255,7 +249,7 @@ Returns:
   Status = gBS->OpenProtocol (\r
                   ControllerHandle,\r
                   &gEfiWinNtIoProtocolGuid,\r
-                  &WinNtIo,\r
+                  (VOID **) &WinNtIo,\r
                   This->DriverBindingHandle,\r
                   ControllerHandle,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
@@ -328,7 +322,7 @@ Returns:
   Status = gBS->OpenProtocol (\r
                   ControllerHandle,\r
                   &gEfiWinNtIoProtocolGuid,\r
-                  &WinNtIo,\r
+                  (VOID **) &WinNtIo,\r
                   This->DriverBindingHandle,\r
                   ControllerHandle,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
@@ -459,7 +453,7 @@ Returns:
   Status = gBS->OpenProtocol (\r
                   ControllerHandle,\r
                   &gEfiSimpleFileSystemProtocolGuid,\r
-                  &SimpleFileSystem,\r
+                  (VOID **) &SimpleFileSystem,\r
                   This->DriverBindingHandle,\r
                   ControllerHandle,\r
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
@@ -504,7 +498,7 @@ EFI_STATUS
 EFIAPI\r
 WinNtSimpleFileSystemOpenVolume (\r
   IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *This,\r
-  OUT EFI_FILE                        **Root\r
+  OUT EFI_FILE_PROTOCOL               **Root\r
   )\r
 /*++\r
 \r
@@ -543,6 +537,8 @@ Returns:
   WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private;\r
   WIN_NT_EFI_FILE_PRIVATE           *PrivateFile;\r
   EFI_TPL                           OldTpl;\r
+  CHAR16                            *TempFileName;\r
+  UINTN                             Size;\r
 \r
   if (This == NULL || Root == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -589,10 +585,50 @@ Returns:
   PrivateFile->EfiFile.GetInfo      = WinNtSimpleFileSystemGetInfo;\r
   PrivateFile->EfiFile.SetInfo      = WinNtSimpleFileSystemSetInfo;\r
   PrivateFile->EfiFile.Flush        = WinNtSimpleFileSystemFlush;\r
-  PrivateFile->LHandle              = INVALID_HANDLE_VALUE;\r
-  PrivateFile->DirHandle            = INVALID_HANDLE_VALUE;\r
   PrivateFile->IsValidFindBuf       = FALSE;\r
 \r
+  //\r
+  // Set DirHandle\r
+  //\r
+  PrivateFile->DirHandle = PrivateFile->WinNtThunk->CreateFile (\r
+                                                      PrivateFile->FilePath,\r
+                                                      GENERIC_READ,\r
+                                                      FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+                                                      NULL,\r
+                                                      OPEN_EXISTING,\r
+                                                      FILE_FLAG_BACKUP_SEMANTICS,\r
+                                                      NULL\r
+                                                      );\r
+\r
+  if (PrivateFile->DirHandle == INVALID_HANDLE_VALUE) {\r
+    Status = EFI_NOT_FOUND;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Find the first file under it\r
+  //\r
+  Size  = StrSize (PrivateFile->FilePath);\r
+  Size += StrSize (L"\\*");\r
+  Status = gBS->AllocatePool (\r
+                  EfiBootServicesData,\r
+                  Size,\r
+                  (VOID **)&TempFileName\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+  StrCpy (TempFileName, PrivateFile->FilePath);\r
+  StrCat (TempFileName, L"\\*");\r
+\r
+  PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (TempFileName, &PrivateFile->FindBuf);\r
+  FreePool (TempFileName);\r
+\r
+  if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
+    PrivateFile->IsValidFindBuf = FALSE;\r
+  } else {\r
+    PrivateFile->IsValidFindBuf = TRUE;\r
+  }\r
   *Root = &PrivateFile->EfiFile;\r
 \r
   Status = EFI_SUCCESS;\r
@@ -617,14 +653,170 @@ Done:
   return Status;\r
 }\r
 \r
+/**\r
+  Count the number of Leading Dot in FileNameToken.\r
+\r
+  @param FileNameToken  A string representing a token in the path name.\r
+\r
+  @return  UINTN             The number of leading dot in the name.\r
+\r
+**/\r
+UINTN\r
+CountLeadingDots (\r
+  IN CONST CHAR16 * FileNameToken\r
+  )\r
+{\r
+  UINTN          Num;\r
+\r
+  Num = 0;\r
+  while (*FileNameToken == L'.') {\r
+    Num++;\r
+    FileNameToken++;\r
+  }\r
+  \r
+  return Num;\r
+}\r
+\r
+BOOLEAN \r
+IsFileNameTokenValid (\r
+  IN CONST CHAR16 * FileNameToken\r
+  )\r
+{\r
+  UINTN Num;\r
+  if (StrStr (FileNameToken, L"/") != NULL) {\r
+    //\r
+    // No L'/' in file name.\r
+    //\r
+    return FALSE;\r
+  } else {\r
+    //\r
+    // If Token has all dot, the number should not exceed 2\r
+    //\r
+    Num = CountLeadingDots (FileNameToken);\r
+\r
+    if (Num == StrLen (FileNameToken)) {\r
+      //\r
+      // If the FileNameToken only contains a number of L'.'.\r
+      //\r
+      if (Num > 2) {\r
+        return FALSE;\r
+      }\r
+    }\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Return the first string token found in the indirect pointer a String named by FileName.\r
+\r
+  On input, FileName is a indirect pointer pointing to a String.\r
+  On output, FileName is a updated to point to the next character after the first\r
+  found L"\" or NULL if there is no L"\" found.\r
+\r
+  @param FileName  A indirect pointer pointing to a FileName.\r
+\r
+  @return  Token      The first string token found before a L"\".\r
+\r
+**/\r
+CHAR16 *\r
+GetNextFileNameToken (\r
+  IN OUT CONST CHAR16 ** FileName \r
+  )\r
+{\r
+  CHAR16 *SlashPos;\r
+  CHAR16 *Token;\r
+  UINTN  Offset;\r
+  ASSERT (**FileName != L'\\');\r
+  ASSERT (**FileName != L'\0');\r
+\r
+  SlashPos = StrStr (*FileName, L"\\");\r
+  if (SlashPos == NULL) {\r
+    Token = AllocateCopyPool (StrSize(*FileName), *FileName);\r
+    *FileName = NULL;\r
+  } else {\r
+    Offset = SlashPos - *FileName;\r
+    Token = AllocateZeroPool ((Offset + 1) * sizeof (CHAR16));\r
+    StrnCpy (Token, *FileName, Offset);\r
+    //\r
+    // Point *FileName to the next character after L'\'.\r
+    //\r
+    *FileName = *FileName + Offset + 1;\r
+    //\r
+    // If *FileName is an empty string, then set *FileName to NULL\r
+    //\r
+    if (**FileName == L'\0') {\r
+      *FileName = NULL;\r
+    }\r
+  }\r
+\r
+  return Token;\r
+}\r
+\r
+/**\r
+  Check if a FileName contains only Valid Characters.\r
+\r
+  If FileName contains only a single L'\', return TRUE.\r
+  If FileName contains two adjacent L'\', return FALSE.\r
+  If FileName conatins L'/' , return FALSE.\r
+  If FielName contains more than two dots seperated with other FileName characters\r
+  by L'\', return FALSE. For example, L'.\...\filename.txt' is invalid path name. But L'..TwoDots\filename.txt' is valid path name.\r
+\r
+  @param FileName  The File Name String to check.\r
+\r
+  @return  TRUE        FileName only contains valid characters.\r
+  @return  FALSE       FileName contains at least one invalid character.\r
+\r
+**/\r
+\r
+BOOLEAN\r
+IsFileNameValid (\r
+  IN CONST CHAR16 *FileName \r
+  )\r
+{\r
+  CHAR16       *Token;\r
+  BOOLEAN      Valid;\r
+\r
+  //\r
+  // If FileName is just L'\', then it is a valid pathname. \r
+  //\r
+  if (StrCmp (FileName, L"\\") == 0) {\r
+    return TRUE;\r
+  }\r
+  //\r
+  // We don't support two or more adjacent L'\'.\r
+  //\r
+  if (StrStr (FileName, L"\\\\") != NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Is FileName has a leading L"\", skip to next character.\r
+  //\r
+  if (FileName [0] == L'\\') {\r
+    FileName++;\r
+  }\r
+\r
+  do {\r
+    Token = GetNextFileNameToken (&FileName);\r
+    Valid = IsFileNameTokenValid (Token);\r
+    FreePool (Token);\r
+    \r
+    if (!Valid)\r
+      return FALSE;\r
+  } while (FileName != NULL);\r
+\r
+  return TRUE;\r
+}\r
+\r
 EFI_STATUS\r
 EFIAPI\r
 WinNtSimpleFileSystemOpen (\r
-  IN  EFI_FILE  *This,\r
-  OUT EFI_FILE  **NewHandle,\r
-  IN  CHAR16    *FileName,\r
-  IN  UINT64    OpenMode,\r
-  IN  UINT64    Attributes\r
+  IN  EFI_FILE_PROTOCOL  *This,\r
+  OUT EFI_FILE_PROTOCOL  **NewHandle,\r
+  IN  CHAR16             *FileName,\r
+  IN  UINT64             OpenMode,\r
+  IN  UINT64             Attributes\r
   )\r
 /*++\r
 \r
@@ -672,7 +864,6 @@ Returns:
 // TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
 // TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
 {\r
-  EFI_FILE                          *Root;\r
   WIN_NT_EFI_FILE_PRIVATE           *PrivateFile;\r
   WIN_NT_EFI_FILE_PRIVATE           *NewPrivateFile;\r
   WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;\r
@@ -687,6 +878,7 @@ Returns:
   BOOLEAN                           LoopFinish;\r
   UINTN                             InfoSize;\r
   EFI_FILE_INFO                     *Info;\r
+  UINTN                             Size;\r
 \r
   //\r
   // Check for obvious invalid parameters.\r
@@ -733,29 +925,16 @@ Returns:
   StrCpy (TempFileName, FileName);\r
   FileName = TempFileName;\r
 \r
-  //\r
-  // BUGBUG: assume an open of root\r
-  // if current location, return current data\r
-  //\r
-  if (StrCmp (FileName, L"\\") == 0 || (StrCmp (FileName, L".") == 0 && PrivateFile->IsRootDirectory)) {\r
-    //\r
-    // BUGBUG: assume an open root\r
-    //\r
-OpenRoot:\r
-    Status          = WinNtSimpleFileSystemOpenVolume (PrivateFile->SimpleFileSystem, &Root);\r
-    NewPrivateFile  = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root);\r
-    goto Done;\r
-  }\r
-\r
   if (FileName[StrLen (FileName) - 1] == L'\\') {\r
     FileName[StrLen (FileName) - 1]  = 0;\r
   }\r
 \r
   //\r
-  // If file name does not equal to "." or "..",\r
+  // If file name does not equal to "." or ".." and not trailed with "\..",\r
   // then we trim the leading/trailing blanks and trailing dots\r
   //\r
-  if (StrCmp (FileName, L".") != 0 && StrCmp (FileName, L"..") != 0) {\r
+  if (StrCmp (FileName, L".") != 0 && StrCmp (FileName, L"..") != 0 && \r
+    ((StrLen (FileName) >= 3) ? (StrCmp (&FileName[StrLen (FileName) - 3], L"\\..") != 0) : TRUE)) {\r
     //\r
     // Trim leading blanks\r
     //\r
@@ -767,10 +946,10 @@ OpenRoot:
     }\r
     CutPrefix (FileName, Count);\r
     //\r
-    // Trim trailing dots and blanks\r
+    // Trim trailing blanks\r
     //\r
     for (TempFileName = FileName + StrLen (FileName) - 1;\r
-      TempFileName >= FileName && (*TempFileName == L' ' || *TempFileName == L'.');\r
+      TempFileName >= FileName && (*TempFileName == L' ');\r
       TempFileName--) {\r
       ;\r
     }\r
@@ -800,7 +979,10 @@ OpenRoot:
     StrCpy (NewPrivateFile->FilePath, PrivateFile->FilePath);\r
   }\r
 \r
-  NewPrivateFile->FileName = AllocatePool (StrSize (NewPrivateFile->FilePath) + StrSize (L"\\") + StrSize (FileName));\r
+  Size = StrSize (NewPrivateFile->FilePath);\r
+  Size += StrSize (L"\\");\r
+  Size += StrSize (FileName);\r
+  NewPrivateFile->FileName = AllocatePool (Size);\r
   if (NewPrivateFile->FileName == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Done;\r
@@ -821,6 +1003,11 @@ OpenRoot:
     }\r
   }\r
 \r
+  if (!IsFileNameValid (NewPrivateFile->FileName)) {\r
+    Status = EFI_NOT_FOUND;\r
+    goto Done;\r
+  }\r
+\r
   //\r
   // Get rid of . and .., except leading . or ..\r
   //\r
@@ -877,22 +1064,17 @@ OpenRoot:
     }\r
   }\r
 \r
-  if (StrCmp (NewPrivateFile->FileName, PrivateRoot->FilePath) == 0) {\r
-    NewPrivateFile->IsRootDirectory = TRUE;\r
-    FreePool (NewPrivateFile->FilePath);\r
-    FreePool (NewPrivateFile->FileName);\r
-    FreePool (NewPrivateFile);\r
-    goto OpenRoot;\r
-  }\r
-\r
   RealFileName = NewPrivateFile->FileName;\r
   while (EfiStrChr (RealFileName, L'\\') != NULL) {\r
     RealFileName = EfiStrChr (RealFileName, L'\\') + 1;\r
   }\r
 \r
-  TempChar            = *(RealFileName - 1);\r
-  *(RealFileName - 1) = 0;\r
-\r
+  TempChar = 0;\r
+  if (RealFileName != NewPrivateFile->FileName) {\r
+    TempChar            = *(RealFileName - 1);\r
+    *(RealFileName - 1) = 0;\r
+    }\r
+  \r
   FreePool (NewPrivateFile->FilePath);\r
   NewPrivateFile->FilePath = NULL;\r
   NewPrivateFile->FilePath = AllocatePool (StrSize (NewPrivateFile->FileName));\r
@@ -902,8 +1084,9 @@ OpenRoot:
   }\r
 \r
   StrCpy (NewPrivateFile->FilePath, NewPrivateFile->FileName);\r
-\r
-  *(RealFileName - 1)             = TempChar;\r
+  if (TempChar != 0) {\r
+    *(RealFileName - 1)             = TempChar;\r
+  }\r
 \r
   NewPrivateFile->IsRootDirectory = FALSE;\r
 \r
@@ -951,7 +1134,9 @@ OpenRoot:
   //\r
   if (NewPrivateFile->IsDirectoryPath) {\r
 \r
-    TempFileName = AllocatePool (StrSize (NewPrivateFile->FileName) + StrSize (L"\\*"));\r
+    Size  = StrSize (NewPrivateFile->FileName);\r
+    Size += StrSize (L"\\*");\r
+    TempFileName = AllocatePool (Size);\r
     if (TempFileName == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto Done;\r
@@ -1004,6 +1189,7 @@ OpenRoot:
         Status = EFI_NOT_FOUND;\r
       }\r
 \r
+      FreePool (TempFileName);\r
       goto Done;\r
     }\r
 \r
@@ -1012,6 +1198,7 @@ OpenRoot:
     //\r
     StrCat (TempFileName, L"\\*");\r
     NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->FindFirstFile (TempFileName, &NewPrivateFile->FindBuf);\r
+    FreePool (TempFileName);\r
 \r
     if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
       NewPrivateFile->IsValidFindBuf = FALSE;\r
@@ -1092,15 +1279,17 @@ OpenRoot:
     Status = WinNtSimpleFileSystemGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);\r
 \r
     if (EFI_ERROR (Status)) {\r
+      FreePool (Info);\r
       goto Done;\r
     }\r
 \r
     Info->Attribute = Attributes;\r
 \r
     WinNtSimpleFileSystemSetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, InfoSize, Info);\r
+    FreePool (Info);\r
   }\r
 \r
-Done: ;\r
+Done:\r
   FreePool (FileName);\r
 \r
   if (EFI_ERROR (Status)) {\r
@@ -1117,6 +1306,9 @@ Done: ;
     }\r
   } else {\r
     *NewHandle = &NewPrivateFile->EfiFile;\r
+    if (StrCmp (NewPrivateFile->FileName, PrivateRoot->FilePath) == 0) {\r
+     NewPrivateFile->IsRootDirectory = TRUE;\r
+    }   \r
   }\r
 \r
   return Status;\r
@@ -1125,7 +1317,7 @@ Done: ;
 EFI_STATUS\r
 EFIAPI\r
 WinNtSimpleFileSystemClose (\r
-  IN EFI_FILE  *This\r
+  IN EFI_FILE_PROTOCOL  *This\r
   )\r
 /*++\r
 \r
@@ -1174,6 +1366,10 @@ Returns:
     FreePool (PrivateFile->FileName);\r
   }\r
 \r
+  if (PrivateFile->FilePath) {\r
+    FreePool (PrivateFile->FilePath);\r
+  }\r
+\r
   FreePool (PrivateFile);\r
 \r
   gBS->RestoreTPL (OldTpl);\r
@@ -1184,7 +1380,7 @@ Returns:
 EFI_STATUS\r
 EFIAPI\r
 WinNtSimpleFileSystemDelete (\r
-  IN EFI_FILE  *This\r
+  IN EFI_FILE_PROTOCOL  *This\r
   )\r
 /*++\r
 \r
@@ -1244,6 +1440,7 @@ Returns:
   }\r
 \r
   FreePool (PrivateFile->FileName);\r
+  FreePool (PrivateFile->FilePath);\r
   FreePool (PrivateFile);\r
 \r
   gBS->RestoreTPL (OldTpl);\r
@@ -1251,7 +1448,6 @@ Returns:
   return Status;\r
 }\r
 \r
-STATIC\r
 VOID\r
 WinNtSystemTimeToEfiTime (\r
   IN SYSTEMTIME             *SystemTime,\r
@@ -1290,12 +1486,36 @@ Returns:
   }\r
 }\r
 \r
+/**\r
+  Convert the FileTime to EfiTime.\r
+\r
+  @param PrivateFile  Pointer to WIN_NT_EFI_FILE_PRIVATE.\r
+  @param TimeZone     Pointer to the current time zone.\r
+  @param FileTime     Pointer to file time.\r
+  @param EfiTime      Pointer to EFI time.\r
+**/\r
+VOID\r
+WinNtFileTimeToEfiTime (  \r
+  IN CONST WIN_NT_EFI_FILE_PRIVATE *PrivateFile,\r
+  IN       TIME_ZONE_INFORMATION   *TimeZone,\r
+  IN CONST FILETIME                *FileTime,\r
+  OUT      EFI_TIME                *EfiTime\r
+  )\r
+{\r
+  FILETIME                         TempFileTime;\r
+  SYSTEMTIME                       SystemTime;\r
+\r
+  PrivateFile->WinNtThunk->FileTimeToLocalFileTime (FileTime, &TempFileTime);\r
+  PrivateFile->WinNtThunk->FileTimeToSystemTime (&TempFileTime, &SystemTime);\r
+  WinNtSystemTimeToEfiTime (&SystemTime, TimeZone, EfiTime);\r
+}\r
+\r
 EFI_STATUS\r
 EFIAPI\r
 WinNtSimpleFileSystemRead (\r
-  IN     EFI_FILE  *This,\r
-  IN OUT UINTN     *BufferSize,\r
-  OUT    VOID      *Buffer\r
+  IN     EFI_FILE_PROTOCOL  *This,\r
+  IN OUT UINTN              *BufferSize,\r
+  OUT    VOID               *Buffer\r
   )\r
 /*++\r
 \r
@@ -1333,7 +1553,6 @@ Returns:
   UINTN                   NameSize;\r
   UINTN                   ResultSize;\r
   UINTN                   Index;\r
-  SYSTEMTIME              SystemTime;\r
   EFI_FILE_INFO           *Info;\r
   WCHAR                   *pw;\r
   TIME_ZONE_INFORMATION   TimeZone;\r
@@ -1405,12 +1624,12 @@ Returns:
     }\r
 \r
     Status = PrivateFile->WinNtThunk->ReadFile (\r
-                                      PrivateFile->LHandle,\r
-                                      Buffer,\r
-                                      *BufferSize,\r
-                                      BufferSize,\r
-                                      NULL\r
-                                      ) ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
+                                        PrivateFile->LHandle,\r
+                                        Buffer,\r
+                                        (DWORD)*BufferSize,\r
+                                        (LPDWORD)BufferSize,\r
+                                        NULL\r
+                                        ) ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
     goto Done;\r
   }\r
 \r
@@ -1440,24 +1659,9 @@ Returns:
     Info->Size = ResultSize;\r
 \r
     PrivateFile->WinNtThunk->GetTimeZoneInformation (&TimeZone);\r
-\r
-    PrivateFile->WinNtThunk->FileTimeToLocalFileTime (\r
-                              &PrivateFile->FindBuf.ftCreationTime,\r
-                              &PrivateFile->FindBuf.ftCreationTime\r
-                              );\r
-\r
-    PrivateFile->WinNtThunk->FileTimeToSystemTime (&PrivateFile->FindBuf.ftCreationTime, &SystemTime);\r
-\r
-    WinNtSystemTimeToEfiTime (&SystemTime, &TimeZone, &Info->CreateTime);\r
-\r
-    PrivateFile->WinNtThunk->FileTimeToLocalFileTime (\r
-                              &PrivateFile->FindBuf.ftLastWriteTime,\r
-                              &PrivateFile->FindBuf.ftLastWriteTime\r
-                              );\r
-\r
-    PrivateFile->WinNtThunk->FileTimeToSystemTime (&PrivateFile->FindBuf.ftLastWriteTime, &SystemTime);\r
-\r
-    WinNtSystemTimeToEfiTime (&SystemTime, &TimeZone, &Info->ModificationTime);\r
+    WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &PrivateFile->FindBuf.ftCreationTime, &Info->CreateTime);\r
+    WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &PrivateFile->FindBuf.ftLastAccessTime, &Info->LastAccessTime);\r
+    WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &PrivateFile->FindBuf.ftLastWriteTime, &Info->ModificationTime);\r
 \r
     Info->FileSize      = PrivateFile->FindBuf.nFileSizeLow;\r
 \r
@@ -1508,9 +1712,9 @@ Done:
 EFI_STATUS\r
 EFIAPI\r
 WinNtSimpleFileSystemWrite (\r
-  IN     EFI_FILE  *This,\r
-  IN OUT UINTN     *BufferSize,\r
-  IN     VOID      *Buffer\r
+  IN     EFI_FILE_PROTOCOL  *This,\r
+  IN OUT UINTN              *BufferSize,\r
+  IN     VOID               *Buffer\r
   )\r
 /*++\r
 \r
@@ -1576,12 +1780,12 @@ Returns:
   }\r
 \r
   Status = PrivateFile->WinNtThunk->WriteFile (\r
-                                    PrivateFile->LHandle,\r
-                                    Buffer,\r
-                                    *BufferSize,\r
-                                    BufferSize,\r
-                                    NULL\r
-                                    ) ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
+                                      PrivateFile->LHandle,\r
+                                      Buffer,\r
+                                      (DWORD)*BufferSize,\r
+                                      (LPDWORD)BufferSize,\r
+                                      NULL\r
+                                      ) ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
 \r
 Done:\r
   gBS->RestoreTPL (OldTpl);\r
@@ -1595,8 +1799,8 @@ Done:
 EFI_STATUS\r
 EFIAPI\r
 WinNtSimpleFileSystemSetPosition (\r
-  IN EFI_FILE  *This,\r
-  IN UINT64    Position\r
+  IN EFI_FILE_PROTOCOL  *This,\r
+  IN UINT64             Position\r
   )\r
 /*++\r
 \r
@@ -1625,6 +1829,7 @@ Returns:
   UINT32                  PosHigh;\r
   CHAR16                  *FileName;\r
   EFI_TPL                 OldTpl;\r
+  UINTN                   Size;\r
 \r
   if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1640,7 +1845,9 @@ Returns:
       goto Done;\r
     }\r
 \r
-    FileName = AllocatePool (StrSize (PrivateFile->FileName) + StrSize (L"\\*"));\r
+    Size  = StrSize (PrivateFile->FileName);\r
+    Size += StrSize (L"\\*");\r
+    FileName = AllocatePool (Size);\r
     if (FileName == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto Done;\r
@@ -1670,7 +1877,7 @@ Returns:
     } else {\r
       PosHigh = (UINT32) RShiftU64 (Position, 32);\r
 \r
-      PosLow  = PrivateFile->WinNtThunk->SetFilePointer (PrivateFile->LHandle, (ULONG) Position, &PosHigh, FILE_BEGIN);\r
+      PosLow  = PrivateFile->WinNtThunk->SetFilePointer (PrivateFile->LHandle, (ULONG) Position, (PLONG)&PosHigh, FILE_BEGIN);\r
     }\r
 \r
     Status = (PosLow == 0xFFFFFFFF) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
@@ -1684,8 +1891,8 @@ Done:
 EFI_STATUS\r
 EFIAPI\r
 WinNtSimpleFileSystemGetPosition (\r
-  IN  EFI_FILE  *This,\r
-  OUT UINT64    *Position\r
+  IN  EFI_FILE_PROTOCOL   *This,\r
+  OUT UINT64              *Position\r
   )\r
 /*++\r
 \r
@@ -1733,11 +1940,11 @@ Returns:
 \r
     PositionHigh = 0;\r
     *Position = PrivateFile->WinNtThunk->SetFilePointer (\r
-                                          PrivateFile->LHandle,\r
-                                          0,\r
-                                          &PositionHigh,\r
-                                          FILE_CURRENT\r
-                                          );\r
+                                           PrivateFile->LHandle,\r
+                                           0,\r
+                                           (PLONG)&PositionHigh,\r
+                                           FILE_CURRENT\r
+                                           );\r
 \r
     Status = *Position == 0xffffffff ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
     if (EFI_ERROR (Status)) {\r
@@ -1753,7 +1960,6 @@ Done:
   return Status;\r
 }\r
 \r
-STATIC\r
 EFI_STATUS\r
 WinNtSimpleFileSystemFileInfo (\r
   IN     WIN_NT_EFI_FILE_PRIVATE  *PrivateFile,\r
@@ -1784,18 +1990,24 @@ Returns:
   UINTN                       ResultSize;\r
   EFI_FILE_INFO               *Info;\r
   BY_HANDLE_FILE_INFORMATION  FileInfo;\r
-  SYSTEMTIME                  SystemTime;\r
   CHAR16                      *RealFileName;\r
   CHAR16                      *TempPointer;\r
-  EFI_FILE_INFO               *DirInfo;\r
-  UINTN                       ReadSize;\r
-  UINT64                      Location;\r
-  EFI_STATUS                  DirStatus;\r
-\r
+  TIME_ZONE_INFORMATION       TimeZone;\r
 \r
   Size        = SIZE_OF_EFI_FILE_INFO;\r
-  NameSize    = StrSize (PrivateFile->FileName);\r
-  ResultSize  = Size + NameSize;\r
+\r
+  RealFileName  = PrivateFile->FileName;\r
+  TempPointer   = RealFileName;\r
+  while (*TempPointer) {\r
+    if (*TempPointer == '\\') {\r
+      RealFileName = TempPointer + 1;\r
+    }\r
+\r
+    TempPointer++;\r
+  }\r
+  NameSize = StrSize (RealFileName);\r
+\r
+  ResultSize = Size + NameSize; \r
 \r
   Status      = EFI_BUFFER_TOO_SMALL;\r
   if (*BufferSize >= ResultSize) {\r
@@ -1812,29 +2024,10 @@ Returns:
     Info->FileSize      = FileInfo.nFileSizeLow;\r
     Info->PhysicalSize  = Info->FileSize;\r
 \r
-    PrivateFile->WinNtThunk->FileTimeToSystemTime (&FileInfo.ftCreationTime, &SystemTime);\r
-    Info->CreateTime.Year   = SystemTime.wYear;\r
-    Info->CreateTime.Month  = (UINT8) SystemTime.wMonth;\r
-    Info->CreateTime.Day    = (UINT8) SystemTime.wDay;\r
-    Info->CreateTime.Hour   = (UINT8) SystemTime.wHour;\r
-    Info->CreateTime.Minute = (UINT8) SystemTime.wMinute;\r
-    Info->CreateTime.Second = (UINT8) SystemTime.wSecond;\r
-\r
-    PrivateFile->WinNtThunk->FileTimeToSystemTime (&FileInfo.ftLastAccessTime, &SystemTime);\r
-    Info->LastAccessTime.Year   = SystemTime.wYear;\r
-    Info->LastAccessTime.Month  = (UINT8) SystemTime.wMonth;\r
-    Info->LastAccessTime.Day    = (UINT8) SystemTime.wDay;\r
-    Info->LastAccessTime.Hour   = (UINT8) SystemTime.wHour;\r
-    Info->LastAccessTime.Minute = (UINT8) SystemTime.wMinute;\r
-    Info->LastAccessTime.Second = (UINT8) SystemTime.wSecond;\r
-\r
-    PrivateFile->WinNtThunk->FileTimeToSystemTime (&FileInfo.ftLastWriteTime, &SystemTime);\r
-    Info->ModificationTime.Year   = SystemTime.wYear;\r
-    Info->ModificationTime.Month  = (UINT8) SystemTime.wMonth;\r
-    Info->ModificationTime.Day    = (UINT8) SystemTime.wDay;\r
-    Info->ModificationTime.Hour   = (UINT8) SystemTime.wHour;\r
-    Info->ModificationTime.Minute = (UINT8) SystemTime.wMinute;\r
-    Info->ModificationTime.Second = (UINT8) SystemTime.wSecond;\r
+    PrivateFile->WinNtThunk->GetTimeZoneInformation (&TimeZone);\r
+    WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &FileInfo.ftCreationTime, &Info->CreateTime);\r
+    WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &FileInfo.ftLastAccessTime, &Info->LastAccessTime);\r
+    WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &FileInfo.ftLastWriteTime, &Info->ModificationTime);\r
 \r
     if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {\r
       Info->Attribute |= EFI_FILE_ARCHIVE;\r
@@ -1860,61 +2053,11 @@ Returns:
       Info->Attribute |= EFI_FILE_DIRECTORY;\r
     }\r
 \r
-    RealFileName  = PrivateFile->FileName;\r
-    TempPointer   = RealFileName;\r
-\r
-    while (*TempPointer) {\r
-      if (*TempPointer == '\\') {\r
-        RealFileName = TempPointer + 1;\r
-      }\r
-\r
-      TempPointer++;\r
-    }\r
-\r
     if (PrivateFile->IsRootDirectory) {\r
       *((CHAR8 *) Buffer + Size) = 0;\r
     } else {\r
       CopyMem ((CHAR8 *) Buffer + Size, RealFileName, NameSize);\r
     }\r
-\r
-    if (Info->Attribute & EFI_FILE_DIRECTORY) {\r
-      //\r
-      // The GetFileInformationByHandle.nFileSizeLow is bogus for dir so we \r
-      // need to do the same thing the caller would do to get the right value\r
-      //\r
-      ASSERT (PrivateFile->EfiFile.Read != NULL);\r
-      DirStatus = PrivateFile->EfiFile.GetPosition (&PrivateFile->EfiFile, &Location);\r
-      if (EFI_ERROR (DirStatus)) {\r
-        Location = 0;\r
-      }\r
-\r
-      PrivateFile->EfiFile.SetPosition (&PrivateFile->EfiFile, 0);\r
-      Info->FileSize = 0; \r
-      do {\r
-        ReadSize = 0;\r
-        DirInfo = NULL;\r
-        DirStatus = PrivateFile->EfiFile.Read (&PrivateFile->EfiFile, &ReadSize, DirInfo);\r
-        if (DirStatus == EFI_BUFFER_TOO_SMALL) {\r
-          DirInfo = AllocatePool (ReadSize);\r
-          if (DirInfo != NULL) {\r
-            //\r
-            // Read each dir entry to figure out how big the directory is\r
-            //\r
-            DirStatus = PrivateFile->EfiFile.Read (&PrivateFile->EfiFile, &ReadSize, DirInfo);\r
-            if (!EFI_ERROR (DirStatus) && (ReadSize != 0)) {\r
-              Info->FileSize += ReadSize;\r
-            }\r
-            FreePool (DirInfo);\r
-          }\r
-        }\r
-        \r
-      } while (!EFI_ERROR (DirStatus) && (ReadSize != 0));\r
-\r
-      //\r
-      // reset the file possition back to the previous location\r
-      //\r
-      PrivateFile->EfiFile.SetPosition (&PrivateFile->EfiFile, Location);\r
-    }\r
   }\r
 \r
   *BufferSize = ResultSize;\r
@@ -1924,10 +2067,10 @@ Returns:
 EFI_STATUS\r
 EFIAPI\r
 WinNtSimpleFileSystemGetInfo (\r
-  IN     EFI_FILE  *This,\r
-  IN     EFI_GUID  *InformationType,\r
-  IN OUT UINTN     *BufferSize,\r
-  OUT    VOID      *Buffer\r
+  IN     EFI_FILE_PROTOCOL  *This,\r
+  IN     EFI_GUID           *InformationType,\r
+  IN OUT UINTN              *BufferSize,\r
+  OUT    VOID               *Buffer\r
   )\r
 /*++\r
 \r
@@ -2045,10 +2188,10 @@ Returns:
     //\r
     NtStatus = PrivateFile->WinNtThunk->GetDiskFreeSpace (\r
                                           DriveNameFound ? DriveName : NULL,\r
-                                          &SectorsPerCluster,\r
-                                          &BytesPerSector,\r
-                                          &FreeClusters,\r
-                                          &TotalClusters\r
+                                          (LPDWORD)&SectorsPerCluster,\r
+                                          (LPDWORD)&BytesPerSector,\r
+                                          (LPDWORD)&FreeClusters,\r
+                                          (LPDWORD)&TotalClusters\r
                                           );\r
     if (DriveName) {\r
       FreePool (DriveName);\r
@@ -2105,7 +2248,7 @@ Done:
 EFI_STATUS\r
 EFIAPI\r
 WinNtSimpleFileSystemSetInfo (\r
-  IN EFI_FILE         *This,\r
+  IN EFI_FILE_PROTOCOL*This,\r
   IN EFI_GUID         *InformationType,\r
   IN UINTN            BufferSize,\r
   IN VOID             *Buffer\r
@@ -2177,6 +2320,7 @@ Returns:
   WIN32_FIND_DATA                   FindBuf;\r
   EFI_FILE_SYSTEM_INFO              *NewFileSystemInfo;\r
   EFI_TPL                           OldTpl;\r
+  UINTN                             Size;\r
 \r
   //\r
   // Check for invalid parameters.\r
@@ -2202,12 +2346,12 @@ Returns:
   // Set file system information.\r
   //\r
   if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {\r
-    if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) {\r
+    NewFileSystemInfo = (EFI_FILE_SYSTEM_INFO *) Buffer;\r
+    if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (NewFileSystemInfo->VolumeLabel)) {\r
       Status = EFI_BAD_BUFFER_SIZE;\r
       goto Done;\r
     }\r
 \r
-    NewFileSystemInfo = (EFI_FILE_SYSTEM_INFO *) Buffer;\r
 \r
     FreePool (PrivateRoot->VolumeLabel);\r
     PrivateRoot->VolumeLabel = AllocatePool (StrSize (NewFileSystemInfo->VolumeLabel));\r
@@ -2256,7 +2400,7 @@ Returns:
   //\r
   NewFileInfo = (EFI_FILE_INFO *) Buffer;\r
 \r
-  if (NewFileInfo->Size <= sizeof (EFI_FILE_INFO) ||\r
+  if ((NewFileInfo->Size <= SIZE_OF_EFI_FILE_INFO) ||\r
       (NewFileInfo->Attribute &~(EFI_FILE_VALID_ATTR)) ||\r
       (sizeof (UINTN) == 4 && NewFileInfo->Size > 0xFFFFFFFF)\r
       ) {\r
@@ -2306,7 +2450,10 @@ Returns:
   // Make full pathname from new filename and rootpath.\r
   //\r
   if (NewFileInfo->FileName[0] == '\\') {\r
-    NewFileName = AllocatePool (StrSize (PrivateRoot->FilePath) + StrSize (L"\\") + StrSize (NewFileInfo->FileName));\r
+    Size  = StrSize (PrivateRoot->FilePath);\r
+    Size += StrSize (L"\\");\r
+    Size += StrSize (NewFileInfo->FileName);\r
+    NewFileName = AllocatePool (Size);\r
     if (NewFileName == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto Done;\r
@@ -2316,7 +2463,10 @@ Returns:
     StrCat (NewFileName, L"\\");\r
     StrCat (NewFileName, NewFileInfo->FileName + 1);\r
   } else {\r
-    NewFileName = AllocatePool (StrSize (PrivateFile->FilePath) + StrSize (L"\\") + StrSize (NewFileInfo->FileName));\r
+    Size  = StrSize (PrivateFile->FilePath);\r
+    Size += StrSize (L"\\");\r
+    Size += StrSize (NewFileInfo->FileName);\r
+    NewFileName = AllocatePool (Size);\r
     if (NewFileName == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto Done;\r
@@ -2434,7 +2584,9 @@ Returns:
 \r
       StrCpy (PrivateFile->FileName, NewFileName);\r
 \r
-      TempFileName = AllocatePool (StrSize (NewFileName) + StrSize (L"\\*"));\r
+      Size  =  StrSize (NewFileName);\r
+      Size += StrSize (L"\\*");\r
+      TempFileName = AllocatePool (Size);\r
 \r
       StrCpy (TempFileName, NewFileName);\r
 \r
@@ -2475,8 +2627,8 @@ Returns:
         FreePool (TempFileName);\r
       }\r
     } else {\r
+      Status    = EFI_ACCESS_DENIED;\r
 Reopen: ;\r
-      Status    = EFI_DEVICE_ERROR;\r
 \r
       NtStatus  = PrivateFile->WinNtThunk->SetFileAttributes (OldFileName, OldAttr);\r
 \r
@@ -2484,7 +2636,9 @@ Reopen: ;
         goto Done;\r
       }\r
 \r
-      TempFileName = AllocatePool (StrSize (OldFileName) + StrSize (L"\\*"));\r
+      Size =  StrSize (OldFileName);\r
+      Size += StrSize (L"\\*");\r
+      TempFileName = AllocatePool (Size);\r
 \r
       StrCpy (TempFileName, OldFileName);\r
 \r
@@ -2575,6 +2729,13 @@ Reopen: ;
       goto Done;\r
     }\r
 \r
+    if (!PrivateFile->WinNtThunk->LocalFileTimeToFileTime (\r
+                                    &NewCreationFileTime,\r
+                                    &NewCreationFileTime\r
+                                    )) {\r
+      goto Done;\r
+    }\r
+\r
     NewLastAccessSystemTime.wYear         = NewFileInfo->LastAccessTime.Year;\r
     NewLastAccessSystemTime.wMonth        = NewFileInfo->LastAccessTime.Month;\r
     NewLastAccessSystemTime.wDay          = NewFileInfo->LastAccessTime.Day;\r
@@ -2590,6 +2751,13 @@ Reopen: ;
       goto Done;\r
     }\r
 \r
+    if (!PrivateFile->WinNtThunk->LocalFileTimeToFileTime (\r
+                                    &NewLastAccessFileTime,\r
+                                    &NewLastAccessFileTime\r
+                                    )) {\r
+      goto Done;\r
+    }\r
+\r
     NewLastWriteSystemTime.wYear          = NewFileInfo->ModificationTime.Year;\r
     NewLastWriteSystemTime.wMonth         = NewFileInfo->ModificationTime.Month;\r
     NewLastWriteSystemTime.wDay           = NewFileInfo->ModificationTime.Day;\r
@@ -2605,6 +2773,13 @@ Reopen: ;
       goto Done;\r
     }\r
 \r
+    if (!PrivateFile->WinNtThunk->LocalFileTimeToFileTime (\r
+                                    &NewLastWriteFileTime,\r
+                                    &NewLastWriteFileTime\r
+                                    )) {\r
+      goto Done;\r
+    }\r
+\r
     if (!PrivateFile->WinNtThunk->SetFileTime (\r
                                     PrivateFile->IsDirectoryPath ? PrivateFile->DirHandle : PrivateFile->LHandle,\r
                                     &NewCreationFileTime,\r
@@ -2650,6 +2825,7 @@ Reopen: ;
   NtStatus = PrivateFile->WinNtThunk->SetFileAttributes (NewFileName, NewAttr);\r
 \r
   if (!NtStatus) {\r
+    Status    = EFI_DEVICE_ERROR;\r
     goto Reopen;\r
   }\r
 \r
@@ -2673,7 +2849,7 @@ Done:
 EFI_STATUS\r
 EFIAPI\r
 WinNtSimpleFileSystemFlush (\r
-  IN EFI_FILE  *This\r
+  IN EFI_FILE_PROTOCOL  *This\r
   )\r
 /*++\r
 \r