/*
- * $Id: dir.c,v 1.22 2002/02/02 14:04:55 hbirr Exp $
+ * $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
- * FILE: services/fs/vfat/dir.c
+ * FILE: drivers/fs/vfat/dir.c
* PURPOSE: VFAT Filesystem : directory control
* UPDATE HISTORY:
19-12-1998 : created
*/
-#include <ddk/ntddk.h>
-#include <wchar.h>
-
#define NDEBUG
-#include <debug.h>
-
#include "vfat.h"
// function like DosDateTimeToFileTime
-BOOL FsdDosDateTimeToFileTime (WORD wDosDate, WORD wDosTime, TIME * FileTime)
+BOOLEAN
+FsdDosDateTimeToSystemTime (PDEVICE_EXTENSION DeviceExt, USHORT DosDate, USHORT DosTime, PLARGE_INTEGER SystemTime)
{
- PDOSTIME pdtime = (PDOSTIME) & wDosTime;
- PDOSDATE pddate = (PDOSDATE) & wDosDate;
+ PDOSTIME pdtime = (PDOSTIME) &DosTime;
+ PDOSDATE pddate = (PDOSDATE) &DosDate;
TIME_FIELDS TimeFields;
+ LARGE_INTEGER LocalTime;
- if (FileTime == NULL)
+ if (SystemTime == NULL)
return FALSE;
TimeFields.Milliseconds = 0;
TimeFields.Day = pddate->Day;
TimeFields.Month = pddate->Month;
- TimeFields.Year = 1980 + pddate->Year;
+ TimeFields.Year = (CSHORT)(DeviceExt->BaseDateYear + pddate->Year);
- RtlTimeFieldsToTime (&TimeFields, (PLARGE_INTEGER) FileTime);
+ RtlTimeFieldsToTime (&TimeFields, &LocalTime);
+ ExLocalTimeToSystemTime(&LocalTime, SystemTime);
return TRUE;
}
-
// function like FileTimeToDosDateTime
-BOOL
-FsdFileTimeToDosDateTime (TIME * FileTime, WORD * pwDosDate, WORD * pwDosTime)
+BOOLEAN
+FsdSystemTimeToDosDateTime (PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, USHORT *pDosDate, USHORT *pDosTime)
{
- PDOSTIME pdtime = (PDOSTIME) pwDosTime;
- PDOSDATE pddate = (PDOSDATE) pwDosDate;
+ PDOSTIME pdtime = (PDOSTIME) pDosTime;
+ PDOSDATE pddate = (PDOSDATE) pDosDate;
TIME_FIELDS TimeFields;
+ LARGE_INTEGER LocalTime;
- if (FileTime == NULL)
+ if (SystemTime == NULL)
return FALSE;
- RtlTimeToTimeFields ((PLARGE_INTEGER) FileTime, &TimeFields);
+ ExSystemTimeToLocalTime (SystemTime, &LocalTime);
+ RtlTimeToTimeFields (&LocalTime, &TimeFields);
if (pdtime)
{
{
pddate->Day = TimeFields.Day;
pddate->Month = TimeFields.Month;
- pddate->Year = TimeFields.Year - 1980;
+ pddate->Year = (USHORT) (TimeFields.Year - DeviceExt->BaseDateYear);
}
return TRUE;
}
-
-
-unsigned long
-vfat_wstrlen (PWSTR s)
-{
- WCHAR c = ' ';
- unsigned int len = 0;
-
- while (c != 0)
- {
- c = *s;
- s++;
- len++;
- };
- s -= len;
-
- return len - 1;
-}
-
-#define DWORD_ROUND_UP(x) ( (((ULONG)(x))%32) ? ((((ULONG)x)&(~0x1f))+0x20) : ((ULONG)x) )
+#define ULONG_ROUND_UP(x) ROUND_UP((x), (sizeof(ULONG)))
NTSTATUS
-VfatGetFileNameInformation (PVFATFCB pFcb,
- PFILE_NAMES_INFORMATION pInfo, ULONG BufferLength)
+VfatGetFileNameInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
+ PFILE_NAMES_INFORMATION pInfo, ULONG BufferLength)
{
- ULONG Length;
- Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR);
- if ((sizeof (FILE_DIRECTORY_INFORMATION) + Length) > BufferLength)
+ if ((sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
return STATUS_BUFFER_OVERFLOW;
- pInfo->FileNameLength = Length;
+ pInfo->FileNameLength = DirContext->LongNameU.Length;
pInfo->NextEntryOffset =
- DWORD_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + Length);
- memcpy (pInfo->FileName, pFcb->ObjectName, Length);
+ ULONG_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
+ RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
return STATUS_SUCCESS;
}
NTSTATUS
-VfatGetFileDirectoryInformation (PVFATFCB pFcb,
- PDEVICE_EXTENSION DeviceExt,
- PFILE_DIRECTORY_INFORMATION pInfo,
- ULONG BufferLength)
+VfatGetFileDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
+ PDEVICE_EXTENSION DeviceExt,
+ PFILE_DIRECTORY_INFORMATION pInfo,
+ ULONG BufferLength)
{
- unsigned long long AllocSize;
- ULONG Length;
- Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR);
- if ((sizeof (FILE_DIRECTORY_INFORMATION) + Length) > BufferLength)
+ if ((sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
return STATUS_BUFFER_OVERFLOW;
- pInfo->FileNameLength = Length;
+ pInfo->FileNameLength = DirContext->LongNameU.Length;
pInfo->NextEntryOffset =
- DWORD_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + Length);
- memcpy (pInfo->FileName, pFcb->ObjectName, Length);
+ ULONG_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
+ RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
// pInfo->FileIndex=;
- FsdDosDateTimeToFileTime (pFcb->entry.CreationDate,
- pFcb->entry.CreationTime, &pInfo->CreationTime);
- FsdDosDateTimeToFileTime (pFcb->entry.AccessDate, 0,
- &pInfo->LastAccessTime);
- FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
- &pInfo->LastWriteTime);
- FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
- &pInfo->ChangeTime);
- pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize);
- /* Make allocsize a rounded up multiple of BytesPerCluster */
- AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
- DeviceExt->BytesPerCluster) * DeviceExt->BytesPerCluster;
- pInfo->AllocationSize.QuadPart = AllocSize;
- pInfo->FileAttributes = pFcb->entry.Attrib;
+ 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;
+ if (DirContext->DirEntry.FatX.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ pInfo->EndOfFile.QuadPart = 0LL;
+ pInfo->AllocationSize.QuadPart = 0LL;
+ }
+ 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
+ {
+ 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)
+ {
+ pInfo->EndOfFile.QuadPart = 0LL;
+ pInfo->AllocationSize.QuadPart = 0LL;
+ }
+ 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;
+ }
return STATUS_SUCCESS;
}
NTSTATUS
-VfatGetFileFullDirectoryInformation (PVFATFCB pFcb,
- PDEVICE_EXTENSION DeviceExt,
- PFILE_FULL_DIRECTORY_INFORMATION pInfo,
- ULONG BufferLength)
+VfatGetFileFullDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
+ PDEVICE_EXTENSION DeviceExt,
+ PFILE_FULL_DIR_INFORMATION pInfo,
+ ULONG BufferLength)
{
- unsigned long long AllocSize;
- ULONG Length;
- Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR);
- if ((sizeof (FILE_FULL_DIRECTORY_INFORMATION) + Length) > BufferLength)
+ if ((sizeof (FILE_FULL_DIR_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
return STATUS_BUFFER_OVERFLOW;
- pInfo->FileNameLength = Length;
+ pInfo->FileNameLength = DirContext->LongNameU.Length;
pInfo->NextEntryOffset =
- DWORD_ROUND_UP (sizeof (FILE_FULL_DIRECTORY_INFORMATION) + Length);
- memcpy (pInfo->FileName, pFcb->ObjectName, Length);
+ ULONG_ROUND_UP (sizeof (FILE_FULL_DIR_INFORMATION) + DirContext->LongNameU.Length);
+ RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
// pInfo->FileIndex=;
- FsdDosDateTimeToFileTime (pFcb->entry.CreationDate,
- pFcb->entry.CreationTime, &pInfo->CreationTime);
- FsdDosDateTimeToFileTime (pFcb->entry.AccessDate, 0,
- &pInfo->LastAccessTime);
- FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
- &pInfo->LastWriteTime);
- FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
- &pInfo->ChangeTime);
- pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize);
- /* Make allocsize a rounded up multiple of BytesPerCluster */
- AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
- DeviceExt->BytesPerCluster) * DeviceExt->BytesPerCluster;
- pInfo->AllocationSize.QuadPart = AllocSize;
- pInfo->FileAttributes = pFcb->entry.Attrib;
+ 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;
+ }
// pInfo->EaSize=;
return STATUS_SUCCESS;
}
NTSTATUS
-VfatGetFileBothInformation (PVFATFCB pFcb,
- PDEVICE_EXTENSION DeviceExt,
- PFILE_BOTH_DIRECTORY_INFORMATION pInfo,
- ULONG BufferLength)
+VfatGetFileBothInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
+ PDEVICE_EXTENSION DeviceExt,
+ PFILE_BOTH_DIR_INFORMATION pInfo,
+ ULONG BufferLength)
{
- short i;
- unsigned long long AllocSize;
- ULONG Length;
- Length = vfat_wstrlen (pFcb->ObjectName) * sizeof(WCHAR);
- if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
+ if ((sizeof (FILE_BOTH_DIR_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
return STATUS_BUFFER_OVERFLOW;
- pInfo->FileNameLength = Length;
- pInfo->NextEntryOffset =
- DWORD_ROUND_UP (sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length);
- memcpy (pInfo->FileName, pFcb->ObjectName, Length);
-// pInfo->FileIndex=;
- FsdDosDateTimeToFileTime (pFcb->entry.CreationDate,
- pFcb->entry.CreationTime, &pInfo->CreationTime);
- FsdDosDateTimeToFileTime (pFcb->entry.AccessDate, 0,
- &pInfo->LastAccessTime);
- FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
- &pInfo->LastWriteTime);
- FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
- &pInfo->ChangeTime);
- pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize);
- /* Make allocsize a rounded up multiple of BytesPerCluster */
- AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
- DeviceExt->BytesPerCluster) * DeviceExt->BytesPerCluster;
- pInfo->AllocationSize.QuadPart = AllocSize;
- pInfo->FileAttributes = pFcb->entry.Attrib;
-// pInfo->EaSize=;
- for (i = 0; i < 8 && (pFcb->entry.Filename[i] != ' '); i++)
- pInfo->ShortName[i] = pFcb->entry.Filename[i];
- pInfo->ShortNameLength = i;
- pInfo->ShortName[i] = '.';
- for (i = 0; i < 3 && (pFcb->entry.Ext[i] != ' '); i++)
- pInfo->ShortName[i + 1 + pInfo->ShortNameLength] = pFcb->entry.Ext[i];
- if (i)
- pInfo->ShortNameLength += (i + 1);
- pInfo->ShortNameLength *= sizeof(WCHAR);
+
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ {
+ 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=;
+ 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 = 0LL;
+ pInfo->AllocationSize.QuadPart = 0LL;
+ }
+ 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->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);
+ 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 (DirContext->DirEntry.Fat.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ pInfo->EndOfFile.QuadPart = 0LL;
+ pInfo->AllocationSize.QuadPart = 0LL;
+ }
+ 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->EaSize=0;
return STATUS_SUCCESS;
}
long BufferLength = 0;
PUNICODE_STRING pSearchPattern = NULL;
FILE_INFORMATION_CLASS FileInformationClass;
- unsigned long FileIndex = 0;
unsigned char *Buffer = NULL;
PFILE_NAMES_INFORMATION Buffer0 = NULL;
PVFATFCB pFcb;
- VFATFCB tmpFcb;
PVFATCCB pCcb;
- WCHAR pCharPattern[MAX_PATH];
- unsigned long OldEntry, OldSector;
+ BOOLEAN FirstQuery = FALSE;
+ BOOLEAN FirstCall = TRUE;
+ VFAT_DIRENTRY_CONTEXT DirContext;
+ WCHAR LongNameBuffer[LONGNAME_MAX_LENGTH + 1];
+ WCHAR ShortNameBuffer[13];
+
+ PIO_STACK_LOCATION Stack = IrpContext->Stack;
pCcb = (PVFATCCB) IrpContext->FileObject->FsContext2;
- pFcb = pCcb->pFcb;
+ pFcb = (PVFATFCB) IrpContext->FileObject->FsContext;
- if (!ExAcquireResourceSharedLite(&pFcb->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
- {
- return STATUS_PENDING;
- }
+ // determine Buffer for result :
+ BufferLength = Stack->Parameters.QueryDirectory.Length;
+#if 0
+ /* Do not probe the user buffer until SEH is available */
+ if (IrpContext->Irp->RequestorMode != KernelMode &&
+ IrpContext->Irp->MdlAddress == NULL &&
+ IrpContext->Irp->UserBuffer != NULL)
+ {
+ ProbeForWrite(IrpContext->Irp->UserBuffer, BufferLength, 1);
+ }
+#endif
+ Buffer = VfatGetUserBuffer(IrpContext->Irp);
- // Obtain the callers parameters
- BufferLength = IrpContext->Stack->Parameters.QueryDirectory.Length;
- pSearchPattern = IrpContext->Stack->Parameters.QueryDirectory.FileName;
+ if (!ExAcquireResourceSharedLite(&pFcb->MainResource,
+ (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
+ {
+ RC = VfatLockUserBuffer(IrpContext->Irp, BufferLength, IoWriteAccess);
+ if (NT_SUCCESS(RC))
+ {
+ RC = STATUS_PENDING;
+ }
+ return RC;
+ }
+
+ /* Obtain the callers parameters */
+#ifdef _MSC_VER
+ /* HACKHACK: Bug in the MS ntifs.h header:
+ * FileName is really a PUNICODE_STRING, not a PSTRING */
+ pSearchPattern = (PUNICODE_STRING)Stack->Parameters.QueryDirectory.FileName;
+#else
+ pSearchPattern = Stack->Parameters.QueryDirectory.FileName;
+#endif
FileInformationClass =
- IrpContext->Stack->Parameters.QueryDirectory.FileInformationClass;
- FileIndex = IrpContext->Stack->Parameters.QueryDirectory.FileIndex;
- if (IrpContext->Stack->Flags & SL_RESTART_SCAN)
- { //FIXME : what is really use of RestartScan ?
- pCcb->StartEntry = pCcb->StartSector = 0;
+ Stack->Parameters.QueryDirectory.FileInformationClass;
+ if (pSearchPattern)
+ {
+ if (!pCcb->SearchPattern.Buffer)
+ {
+ FirstQuery = TRUE;
+ pCcb->SearchPattern.MaximumLength = pSearchPattern->Length + sizeof(WCHAR);
+ pCcb->SearchPattern.Buffer = ExAllocatePool(NonPagedPool, pCcb->SearchPattern.MaximumLength);
+ if (!pCcb->SearchPattern.Buffer)
+ {
+ ExReleaseResourceLite(&pFcb->MainResource);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ RtlCopyUnicodeString(&pCcb->SearchPattern, pSearchPattern);
+ pCcb->SearchPattern.Buffer[pCcb->SearchPattern.Length / sizeof(WCHAR)] = 0;
+ }
}
- // determine Buffer for result :
- if (IrpContext->Irp->MdlAddress)
- Buffer = MmGetSystemAddressForMdl (IrpContext->Irp->MdlAddress);
- else
- Buffer = IrpContext->Irp->UserBuffer;
- DPRINT ("Buffer=%x tofind=%S\n", Buffer, pSearchPattern->Buffer);
- if (pSearchPattern == NULL)
+ else if (!pCcb->SearchPattern.Buffer)
{
- pCharPattern[0] = L'*';
- pCharPattern[1] = 0;
+ FirstQuery = TRUE;
+ pCcb->SearchPattern.MaximumLength = 2 * sizeof(WCHAR);
+ pCcb->SearchPattern.Buffer = ExAllocatePool(NonPagedPool, 2 * sizeof(WCHAR));
+ if (!pCcb->SearchPattern.Buffer)
+ {
+ ExReleaseResourceLite(&pFcb->MainResource);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ pCcb->SearchPattern.Buffer[0] = L'*';
+ pCcb->SearchPattern.Buffer[1] = 0;
+ pCcb->SearchPattern.Length = sizeof(WCHAR);
+ }
+
+ if (IrpContext->Stack->Flags & SL_INDEX_SPECIFIED)
+ {
+ DirContext.DirIndex = pCcb->Entry = Stack->Parameters.QueryDirectory.FileIndex;
+ }
+ else if (FirstQuery || (IrpContext->Stack->Flags & SL_RESTART_SCAN))
+ {
+ DirContext.DirIndex = pCcb->Entry = 0;
}
else
{
- memcpy (pCharPattern, pSearchPattern->Buffer, pSearchPattern->Length);
- pCharPattern[pSearchPattern->Length / sizeof(WCHAR)] = 0;
+ DirContext.DirIndex = pCcb->Entry;
}
- tmpFcb.ObjectName = tmpFcb.PathName;
+
+ DPRINT ("Buffer=%x tofind=%wZ\n", Buffer, &pCcb->SearchPattern);
+
+ DirContext.LongNameU.Buffer = LongNameBuffer;
+ DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
+ DirContext.ShortNameU.Buffer = ShortNameBuffer;
+ DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
+
while (RC == STATUS_SUCCESS && BufferLength > 0)
{
- OldSector = pCcb->StartSector;
- OldEntry = pCcb->StartEntry;
- if (OldSector)
- pCcb->StartEntry++;
- RC =
- FindFile (IrpContext->DeviceExt, &tmpFcb, pFcb, pCharPattern, &pCcb->StartEntry, NULL);
- pCcb->StartSector = 1;
- DPRINT ("Found %S,RC=%x, sector %x entry %x\n", tmpFcb.ObjectName, RC,
- pCcb->StartSector, pCcb->StartEntry);
+ RC = FindFile (IrpContext->DeviceExt, pFcb,
+ &pCcb->SearchPattern, &DirContext, FirstCall);
+ pCcb->Entry = DirContext.DirIndex;
+ DPRINT ("Found %wZ, RC=%x, entry %x\n", &DirContext.LongNameU, RC, pCcb->Entry);
+ FirstCall = FALSE;
if (NT_SUCCESS (RC))
- {
- switch (FileInformationClass)
- {
- case FileNameInformation:
- RC =
- VfatGetFileNameInformation (&tmpFcb,
- (PFILE_NAMES_INFORMATION) Buffer,
- BufferLength);
- break;
- case FileDirectoryInformation:
- RC =
- VfatGetFileDirectoryInformation (&tmpFcb, IrpContext->DeviceExt,
- (PFILE_DIRECTORY_INFORMATION)
- Buffer, BufferLength);
- break;
- case FileFullDirectoryInformation:
- RC =
- VfatGetFileFullDirectoryInformation (&tmpFcb, IrpContext->DeviceExt,
- (PFILE_FULL_DIRECTORY_INFORMATION)
- Buffer, BufferLength);
- break;
- case FileBothDirectoryInformation:
- RC =
- VfatGetFileBothInformation (&tmpFcb, IrpContext->DeviceExt,
- (PFILE_BOTH_DIRECTORY_INFORMATION)
- Buffer, BufferLength);
- break;
- default:
- RC = STATUS_INVALID_INFO_CLASS;
+ {
+ switch (FileInformationClass)
+ {
+ case FileNameInformation:
+ RC = VfatGetFileNameInformation (&DirContext,
+ (PFILE_NAMES_INFORMATION) Buffer,
+ BufferLength);
+ break;
+ case FileDirectoryInformation:
+ RC = VfatGetFileDirectoryInformation (&DirContext,
+ IrpContext->DeviceExt,
+ (PFILE_DIRECTORY_INFORMATION) Buffer,
+ BufferLength);
+ break;
+ case FileFullDirectoryInformation:
+ RC = VfatGetFileFullDirectoryInformation (&DirContext,
+ IrpContext->DeviceExt,
+ (PFILE_FULL_DIR_INFORMATION) Buffer,
+ BufferLength);
+ break;
+ case FileBothDirectoryInformation:
+ RC = VfatGetFileBothInformation (&DirContext,
+ IrpContext->DeviceExt,
+ (PFILE_BOTH_DIR_INFORMATION) Buffer,
+ BufferLength);
+ break;
+ default:
+ RC = STATUS_INVALID_INFO_CLASS;
}
+ if (RC == STATUS_BUFFER_OVERFLOW)
+ {
+ break;
+ }
}
else
- {
- if (Buffer0)
- Buffer0->NextEntryOffset = 0;
- if (OldSector)
- RC = STATUS_NO_MORE_FILES;
+ {
+ if (FirstQuery)
+ {
+ RC = STATUS_NO_SUCH_FILE;
+ }
else
- RC = STATUS_NO_SUCH_FILE;
- break;
- }
- if (RC == STATUS_BUFFER_OVERFLOW)
- {
- if (Buffer0)
- Buffer0->NextEntryOffset = 0;
- pCcb->StartSector = OldSector;
- pCcb->StartEntry = OldEntry;
- break;
+ {
+ RC = STATUS_NO_MORE_FILES;
+ }
+ break;
}
Buffer0 = (PFILE_NAMES_INFORMATION) Buffer;
- Buffer0->FileIndex = FileIndex++;
- if (IrpContext->Stack->Flags & SL_RETURN_SINGLE_ENTRY)
- break;
+ Buffer0->FileIndex = DirContext.DirIndex;
+ pCcb->Entry = ++DirContext.DirIndex;
BufferLength -= Buffer0->NextEntryOffset;
+ if (IrpContext->Stack->Flags & SL_RETURN_SINGLE_ENTRY)
+ {
+ break;
+ }
Buffer += Buffer0->NextEntryOffset;
}
if (Buffer0)
- Buffer0->NextEntryOffset = 0;
- if (FileIndex > 0)
- RC = STATUS_SUCCESS;
-
- if (IrpContext->Flags & IRPCONTEXT_CANWAIT)
- {
- ExReleaseResourceLite(&pFcb->MainResource);
- }
+ {
+ Buffer0->NextEntryOffset = 0;
+ RC = STATUS_SUCCESS;
+ IrpContext->Irp->IoStatus.Information = Stack->Parameters.QueryDirectory.Length - BufferLength;
+ }
+ ExReleaseResourceLite(&pFcb->MainResource);
return RC;
}
{
NTSTATUS RC = STATUS_SUCCESS;
CHECKPOINT;
+ IrpContext->Irp->IoStatus.Information = 0;
switch (IrpContext->MinorFunction)
{
case IRP_MN_QUERY_DIRECTORY:
else
{
IrpContext->Irp->IoStatus.Status = RC;
- IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
}