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