static
NTSTATUS
-VfatGetFileNameInformation(
+VfatGetFileNamesInformation(
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;
- return STATUS_SUCCESS;
+ if (BytesToCopy == DirContext->LongNameU.Length)
+ {
+ pInfo->NextEntryOffset = ULONG_ROUND_UP(sizeof(FILE_NAMES_INFORMATION) +
+ BytesToCopy);
+ Status = STATUS_SUCCESS;
+ }
+ }
+ }
+
+ return Status;
}
static
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 (DeviceExt->Flags & VCB_IS_FATX)
+ 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 (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 (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
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 (DeviceExt->Flags & VCB_IS_FATX)
- {
- 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;
- }
+ NTSTATUS Status;
+ ULONG BytesToCopy = 0;
- return STATUS_SUCCESS;
-}
-
-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 (DeviceExt->Flags & VCB_IS_FATX)
+ 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 (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;
+}
- pInfo->ShortNameLength = (CCHAR)DirContext->ShortNameU.Length;
+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;
- RtlCopyMemory(pInfo->FileName,
- DirContext->LongNameU.Buffer,
- DirContext->LongNameU.Length);
+ *Written = 0;
+ Status = STATUS_BUFFER_OVERFLOW;
- /* pInfo->FileIndex = ; */
+ if (FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName) > BufferLength)
+ return Status;
- 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 (DirContext->DirEntry.Fat.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ if (First || (BufferLength >= FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName) + DirContext->LongNameU.Length))
+ {
+ pInfo->FileNameLength = DirContext->LongNameU.Length;
+ pInfo->EaSize = 0;
+
+ *Written = FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName);
+ pInfo->NextEntryOffset = 0;
+ if (BufferLength > FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName))
{
- pInfo->EndOfFile.QuadPart = 0;
- pInfo->AllocationSize.QuadPart = 0;
+ 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;
+ }
}
- else
+
+ if (vfatVolumeIsFatX(DeviceExt))
{
- 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->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->ShortNameLength = (CCHAR)DirContext->ShortNameU.Length;
+
+ ASSERT(pInfo->ShortNameLength / sizeof(WCHAR) <= 12);
+ RtlCopyMemory(pInfo->ShortName,
+ DirContext->ShortNameU.Buffer,
+ DirContext->ShortNameU.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
VFAT_DIRENTRY_CONTEXT DirContext;
WCHAR LongNameBuffer[LONGNAME_MAX_LENGTH + 1];
WCHAR ShortNameBuffer[13];
+ ULONG Written;
PIO_STACK_LOCATION Stack = IrpContext->Stack;
ProbeForWrite(IrpContext->Irp->UserBuffer, BufferLength, 1);
}
#endif
- Buffer = VfatGetUserBuffer(IrpContext->Irp);
+ Buffer = VfatGetUserBuffer(IrpContext->Irp, FALSE);
+
+ if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource,
+ BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
+ {
+ Status = VfatLockUserBuffer(IrpContext->Irp, BufferLength, IoWriteAccess);
+ if (NT_SUCCESS(Status))
+ Status = STATUS_PENDING;
+
+ return Status;
+ }
if (!ExAcquireResourceSharedLite(&pFcb->MainResource,
- (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
+ BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
{
+ ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
Status = VfatLockUserBuffer(IrpContext->Irp, BufferLength, IoWriteAccess);
if (NT_SUCCESS(Status))
Status = STATUS_PENDING;
* -> The pattern length is not null
* -> The pattern buffer is not null
* Otherwise, we'll fall later and allocate a match all (*) pattern
- */
+ */
if (pSearchPattern &&
pSearchPattern->Length != 0 && pSearchPattern->Buffer != NULL)
{
if (!pCcb->SearchPattern.Buffer)
{
ExReleaseResourceLite(&pFcb->MainResource);
+ ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyUnicodeString(&pCcb->SearchPattern, pSearchPattern);
if (!pCcb->SearchPattern.Buffer)
{
ExReleaseResourceLite(&pFcb->MainResource);
+ ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
return STATUS_INSUFFICIENT_RESOURCES;
}
pCcb->SearchPattern.Buffer[0] = L'*';
pCcb->SearchPattern.Length = sizeof(WCHAR);
}
- if (IrpContext->Stack->Flags & SL_INDEX_SPECIFIED)
+ if (BooleanFlagOn(IrpContext->Stack->Flags, SL_INDEX_SPECIFIED))
{
DirContext.DirIndex = pCcb->Entry = Stack->Parameters.QueryDirectory.FileIndex;
}
- else if (FirstQuery || (IrpContext->Stack->Flags & SL_RESTART_SCAN))
+ else if (FirstQuery || BooleanFlagOn(IrpContext->Stack->Flags, SL_RESTART_SCAN))
{
DirContext.DirIndex = pCcb->Entry = 0;
}
DPRINT("Buffer=%p tofind=%wZ\n", Buffer, &pCcb->SearchPattern);
+ DirContext.DeviceExt = IrpContext->DeviceExt;
DirContext.LongNameU.Buffer = LongNameBuffer;
DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
DirContext.ShortNameU.Buffer = ShortNameBuffer;
DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
+ Written = 0;
while ((Status == STATUS_SUCCESS) && (BufferLength > 0))
{
Status = FindFile(IrpContext->DeviceExt,
{
switch (FileInformationClass)
{
- case FileNameInformation:
- Status = VfatGetFileNameInformation(&DirContext,
- (PFILE_NAMES_INFORMATION)Buffer,
- BufferLength);
- 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;
+ case FileNamesInformation:
+ Status = VfatGetFileNamesInformation(&DirContext,
+ (PFILE_NAMES_INFORMATION)Buffer,
+ BufferLength,
+ &Written,
+ Buffer0 == NULL);
+ break;
+
default:
Status = STATUS_INVALID_INFO_CLASS;
break;
pCcb->Entry = ++DirContext.DirIndex;
BufferLength -= Buffer0->NextEntryOffset;
- if (IrpContext->Stack->Flags & SL_RETURN_SINGLE_ENTRY)
+ if (BooleanFlagOn(IrpContext->Stack->Flags, SL_RETURN_SINGLE_ENTRY))
break;
Buffer += Buffer0->NextEntryOffset;
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);
return Status;
}
-NTSTATUS VfatNotifyChangeDirectory(PVFAT_IRP_CONTEXT * IrpContext)
+NTSTATUS VfatNotifyChangeDirectory(PVFAT_IRP_CONTEXT IrpContext)
{
PVCB pVcb;
PVFATFCB pFcb;
PIO_STACK_LOCATION Stack;
- Stack = (*IrpContext)->Stack;
- pVcb = (*IrpContext)->DeviceExt;
- pFcb = (PVFATFCB) (*IrpContext)->FileObject->FsContext;
-
+ Stack = IrpContext->Stack;
+ pVcb = IrpContext->DeviceExt;
+ pFcb = (PVFATFCB) IrpContext->FileObject->FsContext;
+
FsRtlNotifyFullChangeDirectory(pVcb->NotifySync,
&(pVcb->NotifyList),
- (*IrpContext)->FileObject->FsContext2,
+ IrpContext->FileObject->FsContext2,
(PSTRING)&(pFcb->PathNameU),
BooleanFlagOn(Stack->Flags, SL_WATCH_TREE),
FALSE,
Stack->Parameters.NotifyDirectory.CompletionFilter,
- (*IrpContext)->Irp,
+ IrpContext->Irp,
NULL,
NULL);
- /* We don't need the IRP context as we won't handle IRP completion */
- VfatFreeIrpContext(*IrpContext);
- *IrpContext = NULL;
+ /* We won't handle IRP completion */
+ IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
return STATUS_PENDING;
}
break;
case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
- Status = VfatNotifyChangeDirectory(&IrpContext);
+ Status = VfatNotifyChangeDirectory(IrpContext);
break;
default:
break;
}
- if (Status == STATUS_PENDING)
- {
- /* Only queue if there's IRP context */
- if (IrpContext)
- {
- Status = VfatQueueRequest(IrpContext);
- }
- }
- else
+ if (Status == STATUS_PENDING && BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_COMPLETE))
{
- IrpContext->Irp->IoStatus.Status = Status;
- IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
- VfatFreeIrpContext(IrpContext);
+ return VfatMarkIrpContextForQueue(IrpContext);
}
return Status;