https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9f3c80193e5f5d9c0497033322c515cdb3690e8c

commit 9f3c80193e5f5d9c0497033322c515cdb3690e8c
Author: Pierre Schweitzer <[email protected]>
AuthorDate: Sat Dec 9 12:33:29 2017 +0100

    [FASTFAT] Don't mix FileNameInformation and FileNamesInformation (and 
support the later).
    This commit fixes weird behavior in our FastFAT implementation. It was 
mixing two classes:
    FileNameInformation and FileNamesInformation. It was handling 
FileNameInformation like
    FileNamesInformation and was filling buffer with FILE_NAMES_INFORMATION 
structure instead
    of FILE_NAME_INFORMATION structure (how many things did that break?!).
    Also, it wasn't implementing the FileNamesInformation class at all. This is 
required by
    ntdll_winetest:directory which doesn't expect it to fail and thus, attempts 
to read
    never filled in memory.
    
    This commit fixes the winetest crash, and may fix other weird FS behavior.
    
    CORE-13367
---
 drivers/filesystems/fastfat/dir.c | 51 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/drivers/filesystems/fastfat/dir.c 
b/drivers/filesystems/fastfat/dir.c
index db96257281..284c04bca1 100644
--- a/drivers/filesystems/fastfat/dir.c
+++ b/drivers/filesystems/fastfat/dir.c
@@ -89,6 +89,47 @@ FsdSystemTimeToDosDateTime(
 static
 NTSTATUS
 VfatGetFileNameInformation(
+    PVFAT_DIRENTRY_CONTEXT DirContext,
+    PFILE_NAME_INFORMATION pInfo,
+    ULONG BufferLength,
+    PULONG Written,
+    BOOLEAN First)
+{
+    NTSTATUS Status;
+    ULONG BytesToCopy = 0;
+
+    *Written = 0;
+    Status = STATUS_BUFFER_OVERFLOW;
+
+    if (FIELD_OFFSET(FILE_NAMES_INFORMATION, FileName) > BufferLength)
+        return Status;
+
+    if (First || (BufferLength >= FIELD_OFFSET(FILE_NAMES_INFORMATION, 
FileName) + DirContext->LongNameU.Length))
+    {
+        pInfo->FileNameLength = DirContext->LongNameU.Length;
+
+        *Written = FIELD_OFFSET(FILE_NAMES_INFORMATION, FileName);
+        if (BufferLength > FIELD_OFFSET(FILE_NAMES_INFORMATION, FileName))
+        {
+            BytesToCopy = min(DirContext->LongNameU.Length, BufferLength - 
FIELD_OFFSET(FILE_NAMES_INFORMATION, FileName));
+            RtlCopyMemory(pInfo->FileName,
+                         DirContext->LongNameU.Buffer,
+                         BytesToCopy);
+            *Written += BytesToCopy;
+
+            if (BytesToCopy == DirContext->LongNameU.Length)
+            {
+                Status = STATUS_SUCCESS;
+            }
+        }
+    }
+
+    return Status;
+}
+
+static
+NTSTATUS
+VfatGetFileNamesInformation(
     PVFAT_DIRENTRY_CONTEXT DirContext,
     PFILE_NAMES_INFORMATION pInfo,
     ULONG BufferLength,
@@ -622,7 +663,7 @@ DoQuery(
             {
                 case FileNameInformation:
                     Status = VfatGetFileNameInformation(&DirContext,
-                                                        
(PFILE_NAMES_INFORMATION)Buffer,
+                                                        
(PFILE_NAME_INFORMATION)Buffer,
                                                         BufferLength,
                                                         &Written,
                                                         Buffer0 == NULL);
@@ -655,6 +696,14 @@ DoQuery(
                                                         Buffer0 == NULL);
                     break;
 
+                case FileNamesInformation:
+                    Status = VfatGetFileNamesInformation(&DirContext,
+                                                         
(PFILE_NAMES_INFORMATION)Buffer,
+                                                         BufferLength,
+                                                         &Written,
+                                                         Buffer0 == NULL);
+                     break;
+
                 default:
                     Status = STATUS_INVALID_INFO_CLASS;
                     break;

Reply via email to