[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
This commit is contained in:
Pierre Schweitzer 2017-12-09 12:33:29 +01:00
parent d086a431cb
commit 9f3c80193e
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B

View file

@ -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;