https://git.reactos.org/?p=reactos.git;a=commitdiff;h=52f0726817fc40917f1ce…
commit 52f0726817fc40917f1ce956029b38985f32d9fa
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Sat Dec 9 10:58:19 2017 +0100
[FASTFAT] Allow partial returns on directory info query for first entry.
This mimics what MS FastFAT does and fixes (a bit) ntdll_winetest:directory.
It still crashes, but go farther.
CORE-13367
---
drivers/filesystems/fastfat/dir.c | 559 ++++++++++++++++++++++----------------
1 file changed, 330 insertions(+), 229 deletions(-)
diff --git a/drivers/filesystems/fastfat/dir.c b/drivers/filesystems/fastfat/dir.c
index 165d8c9bdf..db96257281 100644
--- a/drivers/filesystems/fastfat/dir.c
+++ b/drivers/filesystems/fastfat/dir.c
@@ -91,20 +91,43 @@ NTSTATUS
VfatGetFileNameInformation(
PVFAT_DIRENTRY_CONTEXT DirContext,
PFILE_NAMES_INFORMATION pInfo,
- ULONG BufferLength)
+ ULONG BufferLength,
+ PULONG Written,
+ BOOLEAN First)
{
- if ((sizeof(FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) >
BufferLength)
- return STATUS_BUFFER_OVERFLOW;
+ NTSTATUS Status;
+ ULONG BytesToCopy = 0;
- pInfo->FileNameLength = DirContext->LongNameU.Length;
- pInfo->NextEntryOffset = ULONG_ROUND_UP(sizeof(FILE_DIRECTORY_INFORMATION) +
- DirContext->LongNameU.Length);
+ *Written = 0;
+ Status = STATUS_BUFFER_OVERFLOW;
- RtlCopyMemory(pInfo->FileName,
- DirContext->LongNameU.Buffer,
- DirContext->LongNameU.Length);
+ 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);
+ pInfo->NextEntryOffset = 0;
+ 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)
+ {
+ pInfo->NextEntryOffset = ULONG_ROUND_UP(sizeof(FILE_NAMES_INFORMATION)
+
+ BytesToCopy);
+ Status = STATUS_SUCCESS;
+ }
+ }
+ }
- return STATUS_SUCCESS;
+ return Status;
}
static
@@ -113,90 +136,115 @@ VfatGetFileDirectoryInformation(
PVFAT_DIRENTRY_CONTEXT DirContext,
PDEVICE_EXTENSION DeviceExt,
PFILE_DIRECTORY_INFORMATION pInfo,
- ULONG BufferLength)
+ ULONG BufferLength,
+ PULONG Written,
+ BOOLEAN First)
{
- if ((sizeof(FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) >
BufferLength)
- return STATUS_BUFFER_OVERFLOW;
+ NTSTATUS Status;
+ ULONG BytesToCopy = 0;
- pInfo->FileNameLength = DirContext->LongNameU.Length;
- pInfo->NextEntryOffset = ULONG_ROUND_UP(sizeof(FILE_DIRECTORY_INFORMATION) +
- DirContext->LongNameU.Length);
- /* pInfo->FileIndex = ; */
+ *Written = 0;
+ Status = STATUS_BUFFER_OVERFLOW;
- RtlCopyMemory(pInfo->FileName,
- DirContext->LongNameU.Buffer,
- DirContext->LongNameU.Length);
+ if (FIELD_OFFSET(FILE_DIRECTORY_INFORMATION, FileName) > BufferLength)
+ return Status;
- if (vfatVolumeIsFatX(DeviceExt))
+ if (First || (BufferLength >= FIELD_OFFSET(FILE_DIRECTORY_INFORMATION, FileName) +
DirContext->LongNameU.Length))
{
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.FatX.CreationDate,
- DirContext->DirEntry.FatX.CreationTime,
- &pInfo->CreationTime);
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.FatX.AccessDate,
- DirContext->DirEntry.FatX.AccessTime,
- &pInfo->LastAccessTime);
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.FatX.UpdateDate,
- DirContext->DirEntry.FatX.UpdateTime,
- &pInfo->LastWriteTime);
-
- pInfo->ChangeTime = pInfo->LastWriteTime;
-
- if (BooleanFlagOn(DirContext->DirEntry.FatX.Attrib,
FILE_ATTRIBUTE_DIRECTORY))
- {
- pInfo->EndOfFile.QuadPart = 0;
- pInfo->AllocationSize.QuadPart = 0;
- }
- else
+ pInfo->FileNameLength = DirContext->LongNameU.Length;
+ /* pInfo->FileIndex = ; */
+
+ *Written = FIELD_OFFSET(FILE_DIRECTORY_INFORMATION, FileName);
+ pInfo->NextEntryOffset = 0;
+ if (BufferLength > FIELD_OFFSET(FILE_DIRECTORY_INFORMATION, FileName))
{
- pInfo->EndOfFile.u.HighPart = 0;
- pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize;
- /* Make allocsize a rounded up multiple of BytesPerCluster */
- pInfo->AllocationSize.u.HighPart = 0;
- pInfo->AllocationSize.u.LowPart =
ROUND_UP(DirContext->DirEntry.FatX.FileSize,
-
DeviceExt->FatInfo.BytesPerCluster);
+ BytesToCopy = min(DirContext->LongNameU.Length, BufferLength -
FIELD_OFFSET(FILE_DIRECTORY_INFORMATION, FileName));
+ RtlCopyMemory(pInfo->FileName,
+ DirContext->LongNameU.Buffer,
+ BytesToCopy);
+ *Written += BytesToCopy;
+
+ if (BytesToCopy == DirContext->LongNameU.Length)
+ {
+ pInfo->NextEntryOffset =
ULONG_ROUND_UP(sizeof(FILE_DIRECTORY_INFORMATION) +
+ BytesToCopy);
+ Status = STATUS_SUCCESS;
+ }
}
- pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f;
- }
- else
- {
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.Fat.CreationDate,
- DirContext->DirEntry.Fat.CreationTime,
- &pInfo->CreationTime);
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.Fat.AccessDate,
- 0,
- &pInfo->LastAccessTime);
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.Fat.UpdateDate,
- DirContext->DirEntry.Fat.UpdateTime,
- &pInfo->LastWriteTime);
-
- pInfo->ChangeTime = pInfo->LastWriteTime;
-
- if (BooleanFlagOn(DirContext->DirEntry.Fat.Attrib, FILE_ATTRIBUTE_DIRECTORY))
+
+
+ if (vfatVolumeIsFatX(DeviceExt))
{
- pInfo->EndOfFile.QuadPart = 0;
- pInfo->AllocationSize.QuadPart = 0;
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.FatX.CreationDate,
+ DirContext->DirEntry.FatX.CreationTime,
+ &pInfo->CreationTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.FatX.AccessDate,
+ DirContext->DirEntry.FatX.AccessTime,
+ &pInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.FatX.UpdateDate,
+ DirContext->DirEntry.FatX.UpdateTime,
+ &pInfo->LastWriteTime);
+
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+
+ if (BooleanFlagOn(DirContext->DirEntry.FatX.Attrib,
FILE_ATTRIBUTE_DIRECTORY))
+ {
+ pInfo->EndOfFile.QuadPart = 0;
+ pInfo->AllocationSize.QuadPart = 0;
+ }
+ else
+ {
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart =
ROUND_UP(DirContext->DirEntry.FatX.FileSize,
+
DeviceExt->FatInfo.BytesPerCluster);
+ }
+
+ pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f;
}
else
{
- pInfo->EndOfFile.u.HighPart = 0;
- pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize;
- /* Make allocsize a rounded up multiple of BytesPerCluster */
- pInfo->AllocationSize.u.HighPart = 0;
- pInfo->AllocationSize.u.LowPart =
ROUND_UP(DirContext->DirEntry.Fat.FileSize,
-
DeviceExt->FatInfo.BytesPerCluster);
- }
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.Fat.CreationDate,
+ DirContext->DirEntry.Fat.CreationTime,
+ &pInfo->CreationTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.Fat.AccessDate,
+ 0,
+ &pInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.Fat.UpdateDate,
+ DirContext->DirEntry.Fat.UpdateTime,
+ &pInfo->LastWriteTime);
+
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+
+ if (BooleanFlagOn(DirContext->DirEntry.Fat.Attrib,
FILE_ATTRIBUTE_DIRECTORY))
+ {
+ pInfo->EndOfFile.QuadPart = 0;
+ pInfo->AllocationSize.QuadPart = 0;
+ }
+ else
+ {
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart =
ROUND_UP(DirContext->DirEntry.Fat.FileSize,
+
DeviceExt->FatInfo.BytesPerCluster);
+ }
- pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f;
+ pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f;
+ }
}
- return STATUS_SUCCESS;
+ return Status;
}
static
@@ -205,183 +253,220 @@ VfatGetFileFullDirectoryInformation(
PVFAT_DIRENTRY_CONTEXT DirContext,
PDEVICE_EXTENSION DeviceExt,
PFILE_FULL_DIR_INFORMATION pInfo,
- ULONG BufferLength)
+ ULONG BufferLength,
+ PULONG Written,
+ BOOLEAN First)
{
- if ((sizeof(FILE_FULL_DIR_INFORMATION) + DirContext->LongNameU.Length) >
BufferLength)
- return STATUS_BUFFER_OVERFLOW;
-
- pInfo->FileNameLength = DirContext->LongNameU.Length;
- pInfo->NextEntryOffset = ULONG_ROUND_UP(sizeof(FILE_FULL_DIR_INFORMATION) +
- DirContext->LongNameU.Length);
- /* pInfo->FileIndex = ; */
- /* pInfo->EaSize = ; */
-
- RtlCopyMemory(pInfo->FileName,
- DirContext->LongNameU.Buffer,
- DirContext->LongNameU.Length);
-
- if (vfatVolumeIsFatX(DeviceExt))
- {
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.FatX.CreationDate,
- DirContext->DirEntry.FatX.CreationTime,
- &pInfo->CreationTime);
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.FatX.AccessDate,
- DirContext->DirEntry.FatX.AccessTime,
- &pInfo->LastAccessTime);
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.FatX.UpdateDate,
- DirContext->DirEntry.FatX.UpdateTime,
- &pInfo->LastWriteTime);
-
- pInfo->ChangeTime = pInfo->LastWriteTime;
- pInfo->EndOfFile.u.HighPart = 0;
- pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize;
- /* Make allocsize a rounded up multiple of BytesPerCluster */
- pInfo->AllocationSize.u.HighPart = 0;
- pInfo->AllocationSize.u.LowPart =
ROUND_UP(DirContext->DirEntry.FatX.FileSize,
-
DeviceExt->FatInfo.BytesPerCluster);
- pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f;
- }
- else
- {
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.Fat.CreationDate,
- DirContext->DirEntry.Fat.CreationTime,
- &pInfo->CreationTime);
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.Fat.AccessDate,
- 0,
- &pInfo->LastAccessTime);
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.Fat.UpdateDate,
- DirContext->DirEntry.Fat.UpdateTime,
- &pInfo->LastWriteTime);
-
- pInfo->ChangeTime = pInfo->LastWriteTime;
- pInfo->EndOfFile.u.HighPart = 0;
- pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize;
- /* Make allocsize a rounded up multiple of BytesPerCluster */
- pInfo->AllocationSize.u.HighPart = 0;
- pInfo->AllocationSize.u.LowPart =
ROUND_UP(DirContext->DirEntry.Fat.FileSize,
-
DeviceExt->FatInfo.BytesPerCluster);
- pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f;
- }
-
- return STATUS_SUCCESS;
-}
+ NTSTATUS Status;
+ ULONG BytesToCopy = 0;
-static
-NTSTATUS
-VfatGetFileBothInformation(
- PVFAT_DIRENTRY_CONTEXT DirContext,
- PDEVICE_EXTENSION DeviceExt,
- PFILE_BOTH_DIR_INFORMATION pInfo,
- ULONG BufferLength)
-{
- if ((sizeof(FILE_BOTH_DIR_INFORMATION) + DirContext->LongNameU.Length) >
BufferLength)
- return STATUS_BUFFER_OVERFLOW;
+ *Written = 0;
+ Status = STATUS_BUFFER_OVERFLOW;
- pInfo->EaSize = 0;
+ if (FIELD_OFFSET(FILE_FULL_DIR_INFORMATION, FileName) > BufferLength)
+ return Status;
- if (vfatVolumeIsFatX(DeviceExt))
+ if (First || (BufferLength >= FIELD_OFFSET(FILE_FULL_DIR_INFORMATION, FileName) +
DirContext->LongNameU.Length))
{
pInfo->FileNameLength = DirContext->LongNameU.Length;
-
- RtlCopyMemory(pInfo->FileName,
- DirContext->LongNameU.Buffer,
- DirContext->LongNameU.Length);
-
- pInfo->NextEntryOffset = ULONG_ROUND_UP(sizeof(FILE_BOTH_DIR_INFORMATION) +
- DirContext->LongNameU.Length);
- pInfo->ShortName[0] = 0;
- pInfo->ShortNameLength = 0;
/* pInfo->FileIndex = ; */
+ pInfo->EaSize = 0;
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.FatX.CreationDate,
- DirContext->DirEntry.FatX.CreationTime,
- &pInfo->CreationTime);
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.FatX.AccessDate,
- DirContext->DirEntry.FatX.AccessTime,
- &pInfo->LastAccessTime);
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.FatX.UpdateDate,
- DirContext->DirEntry.FatX.UpdateTime,
- &pInfo->LastWriteTime);
-
- pInfo->ChangeTime = pInfo->LastWriteTime;
-
- if (BooleanFlagOn(DirContext->DirEntry.FatX.Attrib,
FILE_ATTRIBUTE_DIRECTORY))
+ *Written = FIELD_OFFSET(FILE_FULL_DIR_INFORMATION, FileName);
+ pInfo->NextEntryOffset = 0;
+ if (BufferLength > FIELD_OFFSET(FILE_FULL_DIR_INFORMATION, FileName))
{
- pInfo->EndOfFile.QuadPart = 0;
- pInfo->AllocationSize.QuadPart = 0;
+ BytesToCopy = min(DirContext->LongNameU.Length, BufferLength -
FIELD_OFFSET(FILE_FULL_DIR_INFORMATION, FileName));
+ RtlCopyMemory(pInfo->FileName,
+ DirContext->LongNameU.Buffer,
+ BytesToCopy);
+ *Written += BytesToCopy;
+
+ if (BytesToCopy == DirContext->LongNameU.Length)
+ {
+ pInfo->NextEntryOffset =
ULONG_ROUND_UP(sizeof(FILE_FULL_DIR_INFORMATION) +
+ BytesToCopy);
+ Status = STATUS_SUCCESS;
+ }
}
- else
+
+ if (vfatVolumeIsFatX(DeviceExt))
{
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.FatX.CreationDate,
+ DirContext->DirEntry.FatX.CreationTime,
+ &pInfo->CreationTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.FatX.AccessDate,
+ DirContext->DirEntry.FatX.AccessTime,
+ &pInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.FatX.UpdateDate,
+ DirContext->DirEntry.FatX.UpdateTime,
+ &pInfo->LastWriteTime);
+
+ pInfo->ChangeTime = pInfo->LastWriteTime;
pInfo->EndOfFile.u.HighPart = 0;
pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize;
/* Make allocsize a rounded up multiple of BytesPerCluster */
pInfo->AllocationSize.u.HighPart = 0;
pInfo->AllocationSize.u.LowPart =
ROUND_UP(DirContext->DirEntry.FatX.FileSize,
DeviceExt->FatInfo.BytesPerCluster);
+ pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f;
+ }
+ else
+ {
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.Fat.CreationDate,
+ DirContext->DirEntry.Fat.CreationTime,
+ &pInfo->CreationTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.Fat.AccessDate,
+ 0,
+ &pInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.Fat.UpdateDate,
+ DirContext->DirEntry.Fat.UpdateTime,
+ &pInfo->LastWriteTime);
+
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart =
ROUND_UP(DirContext->DirEntry.Fat.FileSize,
+
DeviceExt->FatInfo.BytesPerCluster);
+ pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f;
}
-
- pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f;
}
- else
- {
- pInfo->FileNameLength = DirContext->LongNameU.Length;
- pInfo->NextEntryOffset = ULONG_ROUND_UP(sizeof(FILE_BOTH_DIR_INFORMATION) +
- DirContext->LongNameU.Length);
- RtlCopyMemory(pInfo->ShortName,
- DirContext->ShortNameU.Buffer,
- DirContext->ShortNameU.Length);
+ return Status;
+}
+
+static
+NTSTATUS
+VfatGetFileBothInformation(
+ PVFAT_DIRENTRY_CONTEXT DirContext,
+ PDEVICE_EXTENSION DeviceExt,
+ PFILE_BOTH_DIR_INFORMATION pInfo,
+ ULONG BufferLength,
+ PULONG Written,
+ BOOLEAN First)
+{
+ NTSTATUS Status;
+ ULONG BytesToCopy = 0;
+
+ *Written = 0;
+ Status = STATUS_BUFFER_OVERFLOW;
- pInfo->ShortNameLength = (CCHAR)DirContext->ShortNameU.Length;
+ if (FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName) > BufferLength)
+ return Status;
- RtlCopyMemory(pInfo->FileName,
- DirContext->LongNameU.Buffer,
- DirContext->LongNameU.Length);
+ if (First || (BufferLength >= FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName) +
DirContext->LongNameU.Length))
+ {
+ pInfo->FileNameLength = DirContext->LongNameU.Length;
+ pInfo->EaSize = 0;
- /* pInfo->FileIndex = ; */
+ *Written = FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName);
+ pInfo->NextEntryOffset = 0;
+ if (BufferLength > FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName))
+ {
+ BytesToCopy = min(DirContext->LongNameU.Length, BufferLength -
FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName));
+ RtlCopyMemory(pInfo->FileName,
+ DirContext->LongNameU.Buffer,
+ BytesToCopy);
+ *Written += BytesToCopy;
+
+ if (BytesToCopy == DirContext->LongNameU.Length)
+ {
+ pInfo->NextEntryOffset =
ULONG_ROUND_UP(sizeof(FILE_BOTH_DIR_INFORMATION) +
+ BytesToCopy);
+ Status = STATUS_SUCCESS;
+ }
+ }
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.Fat.CreationDate,
- DirContext->DirEntry.Fat.CreationTime,
- &pInfo->CreationTime);
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.Fat.AccessDate,
- 0,
- &pInfo->LastAccessTime);
- FsdDosDateTimeToSystemTime(DeviceExt,
- DirContext->DirEntry.Fat.UpdateDate,
- DirContext->DirEntry.Fat.UpdateTime,
- &pInfo->LastWriteTime);
-
- pInfo->ChangeTime = pInfo->LastWriteTime;
-
- if (BooleanFlagOn(DirContext->DirEntry.Fat.Attrib, FILE_ATTRIBUTE_DIRECTORY))
+ if (vfatVolumeIsFatX(DeviceExt))
{
- pInfo->EndOfFile.QuadPart = 0;
- pInfo->AllocationSize.QuadPart = 0;
+ pInfo->ShortName[0] = 0;
+ pInfo->ShortNameLength = 0;
+ /* pInfo->FileIndex = ; */
+
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.FatX.CreationDate,
+ DirContext->DirEntry.FatX.CreationTime,
+ &pInfo->CreationTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.FatX.AccessDate,
+ DirContext->DirEntry.FatX.AccessTime,
+ &pInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.FatX.UpdateDate,
+ DirContext->DirEntry.FatX.UpdateTime,
+ &pInfo->LastWriteTime);
+
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+
+ if (BooleanFlagOn(DirContext->DirEntry.FatX.Attrib,
FILE_ATTRIBUTE_DIRECTORY))
+ {
+ pInfo->EndOfFile.QuadPart = 0;
+ pInfo->AllocationSize.QuadPart = 0;
+ }
+ else
+ {
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart =
ROUND_UP(DirContext->DirEntry.FatX.FileSize,
+
DeviceExt->FatInfo.BytesPerCluster);
+ }
+
+ pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f;
}
else
{
- pInfo->EndOfFile.u.HighPart = 0;
- pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize;
- /* Make allocsize a rounded up multiple of BytesPerCluster */
- pInfo->AllocationSize.u.HighPart = 0;
- pInfo->AllocationSize.u.LowPart =
ROUND_UP(DirContext->DirEntry.Fat.FileSize, DeviceExt->FatInfo.BytesPerCluster);
- }
+ pInfo->ShortNameLength = (CCHAR)DirContext->ShortNameU.Length;
+
+ RtlCopyMemory(pInfo->FileName,
+ DirContext->LongNameU.Buffer,
+ DirContext->LongNameU.Length);
+
+ /* pInfo->FileIndex = ; */
+
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.Fat.CreationDate,
+ DirContext->DirEntry.Fat.CreationTime,
+ &pInfo->CreationTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.Fat.AccessDate,
+ 0,
+ &pInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ DirContext->DirEntry.Fat.UpdateDate,
+ DirContext->DirEntry.Fat.UpdateTime,
+ &pInfo->LastWriteTime);
+
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+
+ if (BooleanFlagOn(DirContext->DirEntry.Fat.Attrib,
FILE_ATTRIBUTE_DIRECTORY))
+ {
+ pInfo->EndOfFile.QuadPart = 0;
+ pInfo->AllocationSize.QuadPart = 0;
+ }
+ else
+ {
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart =
ROUND_UP(DirContext->DirEntry.Fat.FileSize, DeviceExt->FatInfo.BytesPerCluster);
+ }
- pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f;
+ pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f;
+ }
}
- return STATUS_SUCCESS;
+ return Status;
}
static
@@ -402,6 +487,7 @@ DoQuery(
VFAT_DIRENTRY_CONTEXT DirContext;
WCHAR LongNameBuffer[LONGNAME_MAX_LENGTH + 1];
WCHAR ShortNameBuffer[13];
+ ULONG Written;
PIO_STACK_LOCATION Stack = IrpContext->Stack;
@@ -517,6 +603,7 @@ DoQuery(
DirContext.ShortNameU.Buffer = ShortNameBuffer;
DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
+ Written = 0;
while ((Status == STATUS_SUCCESS) && (BufferLength > 0))
{
Status = FindFile(IrpContext->DeviceExt,
@@ -536,28 +623,36 @@ DoQuery(
case FileNameInformation:
Status = VfatGetFileNameInformation(&DirContext,
(PFILE_NAMES_INFORMATION)Buffer,
- BufferLength);
+ BufferLength,
+ &Written,
+ Buffer0 == NULL);
break;
case FileDirectoryInformation:
Status = VfatGetFileDirectoryInformation(&DirContext,
IrpContext->DeviceExt,
(PFILE_DIRECTORY_INFORMATION)Buffer,
- BufferLength);
+ BufferLength,
+ &Written,
+ Buffer0 == NULL);
break;
case FileFullDirectoryInformation:
Status = VfatGetFileFullDirectoryInformation(&DirContext,
IrpContext->DeviceExt,
(PFILE_FULL_DIR_INFORMATION)Buffer,
- BufferLength);
+ BufferLength,
+ &Written,
+ Buffer0 == NULL);
break;
case FileBothDirectoryInformation:
Status = VfatGetFileBothInformation(&DirContext,
IrpContext->DeviceExt,
(PFILE_BOTH_DIR_INFORMATION)Buffer,
- BufferLength);
+ BufferLength,
+ &Written,
+ Buffer0 == NULL);
break;
default:
@@ -591,6 +686,12 @@ DoQuery(
Status = STATUS_SUCCESS;
IrpContext->Irp->IoStatus.Information =
Stack->Parameters.QueryDirectory.Length - BufferLength;
}
+ else
+ {
+ ASSERT(Status != STATUS_SUCCESS || BufferLength == 0);
+ ASSERT(Written <= Stack->Parameters.QueryDirectory.Length);
+ IrpContext->Irp->IoStatus.Information = Written;
+ }
ExReleaseResourceLite(&pFcb->MainResource);
ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);