Fixed bug in NT32 file system driver. The FileInfo->FileSize returned for a directory...
authorajfish <ajfish@6f19259b-4bc3-4df7-8a09-765794883524>
Sat, 5 May 2007 02:05:48 +0000 (02:05 +0000)
committerajfish <ajfish@6f19259b-4bc3-4df7-8a09-765794883524>
Sat, 5 May 2007 02:05:48 +0000 (02:05 +0000)
It looks like the BDS and Shell use a bad algorithm of guessing how big a file name can be. This is bad as it's not defined by the protocol.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2583 6f19259b-4bc3-4df7-8a09-765794883524

EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/WinNtSimpleFileSystem.c

index 28fd819..eb7b434 100644 (file)
@@ -1273,7 +1273,7 @@ Returns:
   UINTN                   FileInfoSize;\r
   EFI_TPL                 OldTpl;\r
 \r
   UINTN                   FileInfoSize;\r
   EFI_TPL                 OldTpl;\r
 \r
-  if (This == NULL || BufferSize == NULL || Buffer == NULL) {\r
+  if (This == NULL || BufferSize == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -1717,6 +1717,11 @@ Returns:
   SYSTEMTIME                  SystemTime;\r
   CHAR16                      *RealFileName;\r
   CHAR16                      *TempPointer;\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
 \r
   Size        = SIZE_OF_EFI_FILE_INFO;\r
   NameSize    = StrSize (PrivateFile->FileName);\r
 \r
   Size        = SIZE_OF_EFI_FILE_INFO;\r
   NameSize    = StrSize (PrivateFile->FileName);\r
@@ -1801,6 +1806,45 @@ Returns:
     } else {\r
       CopyMem ((CHAR8 *) Buffer + Size, RealFileName, NameSize);\r
     }\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
   }\r
 \r
   *BufferSize = ResultSize;\r