https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9f3c80193e5f5d9c04970…
commit 9f3c80193e5f5d9c0497033322c515cdb3690e8c
Author: Pierre Schweitzer <pierre(a)reactos.org>
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;