Fixed some problems if special parameters are delivered like SL_RESTART_SCAN, SL_INDE...
[reactos.git] / reactos / drivers / fs / vfat / dir.c
index ac5434d..8a87c39 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: dir.c,v 1.33 2003/12/13 14:25:04 ekohl Exp $
+ * $Id$
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
 
 */
 
-#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;
@@ -36,26 +33,28 @@ BOOL FsdDosDateTimeToFileTime (WORD wDosDate, WORD wDosTime, TIME * FileTime)
 
   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)
     {
@@ -68,14 +67,13 @@ FsdFileTimeToDosDateTime (TIME * FileTime, WORD * pwDosDate, WORD * pwDosTime)
     {
       pddate->Day = TimeFields.Day;
       pddate->Month = TimeFields.Month;
-      pddate->Year = TimeFields.Year - 1980;
+      pddate->Year = (USHORT) (TimeFields.Year - DeviceExt->BaseDateYear);
     }
 
   return TRUE;
 }
 
-
-#define DWORD_ROUND_UP(x)   ROUND_UP((x), (sizeof(DWORD)))
+#define ULONG_ROUND_UP(x)   ROUND_UP((x), (sizeof(ULONG)))
 
 NTSTATUS
 VfatGetFileNameInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
@@ -85,8 +83,8 @@ VfatGetFileNameInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
     return STATUS_BUFFER_OVERFLOW;
   pInfo->FileNameLength = DirContext->LongNameU.Length;
   pInfo->NextEntryOffset =
-    DWORD_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
-  memcpy (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
+    ULONG_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
+  RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
   return STATUS_SUCCESS;
 }
 
@@ -100,22 +98,62 @@ VfatGetFileDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
     return STATUS_BUFFER_OVERFLOW;
   pInfo->FileNameLength = DirContext->LongNameU.Length;
   pInfo->NextEntryOffset =
-    DWORD_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
-  memcpy (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
+    ULONG_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
+  RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
 //      pInfo->FileIndex=;
-  FsdDosDateTimeToFileTime (DirContext->FatDirEntry.CreationDate,
-                           DirContext->FatDirEntry.CreationTime, &pInfo->CreationTime);
-  FsdDosDateTimeToFileTime (DirContext->FatDirEntry.AccessDate, 0,
-                           &pInfo->LastAccessTime);
-  FsdDosDateTimeToFileTime (DirContext->FatDirEntry.UpdateDate, 
-                            DirContext->FatDirEntry.UpdateTime, &pInfo->LastWriteTime);
-  pInfo->ChangeTime = pInfo->LastWriteTime;
-  pInfo->EndOfFile.u.HighPart = 0;
-  pInfo->EndOfFile.u.LowPart = DirContext->FatDirEntry.FileSize;
-  /* Make allocsize a rounded up multiple of BytesPerCluster */
-  pInfo->AllocationSize.u.HighPart = 0;
-  pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->FatDirEntry.FileSize, DeviceExt->FatInfo.BytesPerCluster);
-  pInfo->FileAttributes = DirContext->FatDirEntry.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;
 }
@@ -123,29 +161,53 @@ VfatGetFileDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
 NTSTATUS
 VfatGetFileFullDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
                                     PDEVICE_EXTENSION DeviceExt,
-                                    PFILE_FULL_DIRECTORY_INFORMATION pInfo,
+                                    PFILE_FULL_DIR_INFORMATION pInfo,
                                     ULONG BufferLength)
 {
-  if ((sizeof (FILE_FULL_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
+  if ((sizeof (FILE_FULL_DIR_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
     return STATUS_BUFFER_OVERFLOW;
   pInfo->FileNameLength = DirContext->LongNameU.Length;
   pInfo->NextEntryOffset =
-    DWORD_ROUND_UP (sizeof (FILE_FULL_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
-  memcpy (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
+    ULONG_ROUND_UP (sizeof (FILE_FULL_DIR_INFORMATION) + DirContext->LongNameU.Length);
+  RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
 //      pInfo->FileIndex=;
-  FsdDosDateTimeToFileTime (DirContext->FatDirEntry.CreationDate,
-                           DirContext->FatDirEntry.CreationTime, &pInfo->CreationTime);
-  FsdDosDateTimeToFileTime (DirContext->FatDirEntry.AccessDate, 
-                            0, &pInfo->LastAccessTime);
-  FsdDosDateTimeToFileTime (DirContext->FatDirEntry.UpdateDate, 
-                            DirContext->FatDirEntry.UpdateTime, &pInfo->LastWriteTime);
-  pInfo->ChangeTime = pInfo->LastWriteTime;
-  pInfo->EndOfFile.u.HighPart = 0;
-  pInfo->EndOfFile.u.LowPart = DirContext->FatDirEntry.FileSize;
-  /* Make allocsize a rounded up multiple of BytesPerCluster */
-  pInfo->AllocationSize.u.HighPart = 0;
-  pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->FatDirEntry.FileSize, DeviceExt->FatInfo.BytesPerCluster);
-  pInfo->FileAttributes = DirContext->FatDirEntry.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;
 }
@@ -153,32 +215,80 @@ VfatGetFileFullDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
 NTSTATUS
 VfatGetFileBothInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
                            PDEVICE_EXTENSION DeviceExt,
-                           PFILE_BOTH_DIRECTORY_INFORMATION pInfo,
+                           PFILE_BOTH_DIR_INFORMATION pInfo,
                            ULONG BufferLength)
 {
-  if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
+  if ((sizeof (FILE_BOTH_DIR_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
     return STATUS_BUFFER_OVERFLOW;
-  pInfo->FileNameLength = DirContext->LongNameU.Length;
-  pInfo->NextEntryOffset = 
-    DWORD_ROUND_UP (sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
-  memcpy(pInfo->ShortName, DirContext->ShortNameU.Buffer, DirContext->ShortNameU.Length);
-  pInfo->ShortNameLength = DirContext->ShortNameU.Length;
-  memcpy (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
-//      pInfo->FileIndex=;
-  FsdDosDateTimeToFileTime (DirContext->FatDirEntry.CreationDate,
-                           DirContext->FatDirEntry.CreationDate, &pInfo->CreationTime);
-  FsdDosDateTimeToFileTime (DirContext->FatDirEntry.AccessDate, 0,
-                           &pInfo->LastAccessTime);
-  FsdDosDateTimeToFileTime (DirContext->FatDirEntry.UpdateDate, 
-                            DirContext->FatDirEntry.UpdateTime, &pInfo->LastWriteTime);
-  pInfo->ChangeTime = pInfo->LastWriteTime;
-  pInfo->EndOfFile.u.HighPart = 0;
-  pInfo->EndOfFile.u.LowPart = DirContext->FatDirEntry.FileSize;
-  /* Make allocsize a rounded up multiple of BytesPerCluster */
-  pInfo->AllocationSize.u.HighPart = 0;
-  pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->FatDirEntry.FileSize, DeviceExt->FatInfo.BytesPerCluster);
-  pInfo->FileAttributes = DirContext->FatDirEntry.Attrib;
-//      pInfo->EaSize=;
+
+  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;
 }
 
@@ -188,18 +298,17 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
   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;
   PVFATCCB pCcb;
-  BOOLEAN First = FALSE;
-  BOOLEAN FirstCall;
+  BOOLEAN FirstQuery = FALSE;
+  BOOLEAN FirstCall = TRUE;
   VFAT_DIRENTRY_CONTEXT DirContext;
-  WCHAR LongNameBuffer[MAX_PATH];
+  WCHAR LongNameBuffer[LONGNAME_MAX_LENGTH + 1];
   WCHAR ShortNameBuffer[13];
-  
-  PEXTENDED_IO_STACK_LOCATION Stack = (PEXTENDED_IO_STACK_LOCATION) IrpContext->Stack;
+
+  PIO_STACK_LOCATION Stack = IrpContext->Stack;
 
   pCcb = (PVFATCCB) IrpContext->FileObject->FsContext2;
   pFcb = (PVFATFCB) IrpContext->FileObject->FsContext;
@@ -209,7 +318,7 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
 #if 0
   /* Do not probe the user buffer until SEH is available */
   if (IrpContext->Irp->RequestorMode != KernelMode &&
-      IrpContext->Irp->MdlAddress == NULL && 
+      IrpContext->Irp->MdlAddress == NULL &&
       IrpContext->Irp->UserBuffer != NULL)
     {
       ProbeForWrite(IrpContext->Irp->UserBuffer, BufferLength, 1);
@@ -229,15 +338,20 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
     }
 
   /* 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 =
     Stack->Parameters.QueryDirectory.FileInformationClass;
-  FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
   if (pSearchPattern)
     {
       if (!pCcb->SearchPattern.Buffer)
         {
-          First = TRUE;
+          FirstQuery = TRUE;
           pCcb->SearchPattern.MaximumLength = pSearchPattern->Length + sizeof(WCHAR);
           pCcb->SearchPattern.Buffer = ExAllocatePool(NonPagedPool, pCcb->SearchPattern.MaximumLength);
           if (!pCcb->SearchPattern.Buffer)
@@ -251,7 +365,7 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
     }
   else if (!pCcb->SearchPattern.Buffer)
     {
-      First = TRUE;
+      FirstQuery = TRUE;
       pCcb->SearchPattern.MaximumLength = 2 * sizeof(WCHAR);
       pCcb->SearchPattern.Buffer = ExAllocatePool(NonPagedPool, 2 * sizeof(WCHAR));
       if (!pCcb->SearchPattern.Buffer)
@@ -266,18 +380,15 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
 
   if (IrpContext->Stack->Flags & SL_INDEX_SPECIFIED)
     {
-      DirContext.DirIndex = pCcb->Entry = pCcb->CurrentByteOffset.u.LowPart;
-      FirstCall = TRUE;
+      DirContext.DirIndex = pCcb->Entry = Stack->Parameters.QueryDirectory.FileIndex;
     }
-  else if (First || (IrpContext->Stack->Flags & SL_RESTART_SCAN))
+  else if (FirstQuery || (IrpContext->Stack->Flags & SL_RESTART_SCAN))
     {
       DirContext.DirIndex = pCcb->Entry = 0;
-      FirstCall = TRUE;
     }
   else
     {
       DirContext.DirIndex = pCcb->Entry;
-      FirstCall = FALSE;
     }
 
   DPRINT ("Buffer=%x tofind=%wZ\n", Buffer, &pCcb->SearchPattern);
@@ -289,7 +400,7 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
 
   while (RC == STATUS_SUCCESS && BufferLength > 0)
     {
-      RC = FindFile (IrpContext->DeviceExt, pFcb, 
+      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);
@@ -300,25 +411,25 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
             {
               case FileNameInformation:
                 RC = VfatGetFileNameInformation (&DirContext,
-                                                 (PFILE_NAMES_INFORMATION) Buffer, 
+                                                 (PFILE_NAMES_INFORMATION) Buffer,
                                                 BufferLength);
                 break;
               case FileDirectoryInformation:
-                RC = VfatGetFileDirectoryInformation (&DirContext, 
+                RC = VfatGetFileDirectoryInformation (&DirContext,
                                                      IrpContext->DeviceExt,
-                                                     (PFILE_DIRECTORY_INFORMATION) Buffer, 
+                                                     (PFILE_DIRECTORY_INFORMATION) Buffer,
                                                      BufferLength);
                 break;
              case FileFullDirectoryInformation:
-               RC = VfatGetFileFullDirectoryInformation (&DirContext, 
+               RC = VfatGetFileFullDirectoryInformation (&DirContext,
                                                         IrpContext->DeviceExt,
-                                                        (PFILE_FULL_DIRECTORY_INFORMATION) Buffer, 
+                                                        (PFILE_FULL_DIR_INFORMATION) Buffer,
                                                         BufferLength);
                break;
              case FileBothDirectoryInformation:
-               RC = VfatGetFileBothInformation (&DirContext, 
+               RC = VfatGetFileBothInformation (&DirContext,
                                                IrpContext->DeviceExt,
-                                               (PFILE_BOTH_DIRECTORY_INFORMATION) Buffer, 
+                                               (PFILE_BOTH_DIR_INFORMATION) Buffer,
                                                BufferLength);
                break;
              default:
@@ -326,20 +437,12 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
            }
           if (RC == STATUS_BUFFER_OVERFLOW)
             {
-              if (Buffer0)
-                {
-                  Buffer0->NextEntryOffset = 0;
-                }
               break;
             }
        }
       else
         {
-          if (Buffer0)
-            {
-              Buffer0->NextEntryOffset = 0;
-            }
-          if (First)
+          if (FirstQuery)
             {
               RC = STATUS_NO_SUCH_FILE;
             }
@@ -350,22 +453,21 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
           break;
        }
       Buffer0 = (PFILE_NAMES_INFORMATION) Buffer;
-      Buffer0->FileIndex = FileIndex++;
+      Buffer0->FileIndex = DirContext.DirIndex;
       pCcb->Entry = ++DirContext.DirIndex;
+      BufferLength -= Buffer0->NextEntryOffset;
       if (IrpContext->Stack->Flags & SL_RETURN_SINGLE_ENTRY)
         {
           break;
         }
-      BufferLength -= Buffer0->NextEntryOffset;
       Buffer += Buffer0->NextEntryOffset;
     }
   if (Buffer0)
     {
       Buffer0->NextEntryOffset = 0;
-    }
-  if (FileIndex > 0)
-    {
       RC = STATUS_SUCCESS;
+      IrpContext->Irp->IoStatus.Information = Stack->Parameters.QueryDirectory.Length - BufferLength;
+
     }
   ExReleaseResourceLite(&pFcb->MainResource);
   return RC;
@@ -379,6 +481,7 @@ NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT IrpContext)
 {
   NTSTATUS RC = STATUS_SUCCESS;
   CHECKPOINT;
+  IrpContext->Irp->IoStatus.Information = 0;
   switch (IrpContext->MinorFunction)
     {
     case IRP_MN_QUERY_DIRECTORY:
@@ -402,7 +505,6 @@ NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT IrpContext)
   else
   {
     IrpContext->Irp->IoStatus.Status = RC;
-    IrpContext->Irp->IoStatus.Information = 0;
     IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
     VfatFreeIrpContext(IrpContext);
   }