- Used the parent fcb instead to determine it from parent fileobject.
Modified: trunk/reactos/drivers/fs/vfat/create.c
Modified: trunk/reactos/drivers/fs/vfat/dirwr.c
Modified: trunk/reactos/drivers/fs/vfat/fcb.c
Modified: trunk/reactos/drivers/fs/vfat/rw.c
Modified: trunk/reactos/drivers/fs/vfat/vfat.h

Modified: trunk/reactos/drivers/fs/vfat/create.c
--- trunk/reactos/drivers/fs/vfat/create.c	2005-01-01 11:02:35 UTC (rev 12686)
+++ trunk/reactos/drivers/fs/vfat/create.c	2005-01-01 11:11:52 UTC (rev 12687)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: create.c,v 1.78 2004/12/25 11:18:38 navaraf Exp $
+/* $Id$
  *
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/fs/vfat/create.c
@@ -314,46 +314,30 @@
 }
 
 NTSTATUS
-VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
-	      PUNICODE_STRING FileNameU)
+VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PVFATFCB* ParentFcb)
 /*
  * FUNCTION: Opens a file
  */
 {
-  PVFATFCB ParentFcb;
   PVFATFCB Fcb;
   NTSTATUS Status;
+  UNICODE_STRING PathNameU;
+  WCHAR Buffer[260];
 
-
-//  PDEVICE_OBJECT DeviceObject = DeviceExt->StorageDevice->Vpb->DeviceObject;
-  
   DPRINT ("VfatOpenFile(%08lx, %08lx, '%wZ')\n", DeviceExt, FileObject, &FileObject->FileName);
 
   if (FileObject->RelatedFileObject)
     {
-      DPRINT ("Converting relative filename to absolute filename\n");
+      DPRINT ("'%wZ'\n", &FileObject->RelatedFileObject->FileName);
 
-      Fcb = FileObject->RelatedFileObject->FsContext;
-      RtlCopyUnicodeString(FileNameU, &Fcb->PathNameU);
-      if (!vfatFCBIsRoot(Fcb))
-        {
-	  RtlAppendUnicodeToString(FileNameU, L"\\");
-	}
-      RtlAppendUnicodeStringToString(FileNameU, &FileObject->FileName);
+      *ParentFcb = FileObject->RelatedFileObject->FsContext;
+      (*ParentFcb)->RefCount++;
     }
   else
     {
-      RtlCopyUnicodeString(FileNameU, &FileObject->FileName);
+      *ParentFcb = NULL;
     }
-  if (FileNameU->Length > sizeof(WCHAR) &&
-      FileNameU->Buffer[FileNameU->Length / sizeof(WCHAR) - 1] == L'\\')
-    {
-      FileNameU->Length -= sizeof(WCHAR);
-    }
-  FileNameU->Buffer[FileNameU->Length / sizeof(WCHAR)] = 0;
 
-  DPRINT ("PathName to open: '%wZ'\n", FileNameU);
-
   if (!DeviceExt->FatInfo.FixedMedia)
     {
       Status = VfatBlockDeviceIoControl (DeviceExt->StorageDevice,
@@ -382,40 +366,47 @@
       if (!NT_SUCCESS(Status))
 	{
 	  DPRINT ("Status %lx\n", Status);
+	  *ParentFcb = NULL;
 	  return Status;
 	}
     }
 
+  if (*ParentFcb)
+  {
+     (*ParentFcb)->RefCount++;
+  }
 
-  /*  try first to find an existing FCB in memory  */
-  DPRINT ("Checking for existing FCB in memory\n");
-  Fcb = vfatGrabFCBFromTable (DeviceExt, FileNameU);
-  if (Fcb == NULL)
+  PathNameU.Buffer = Buffer;
+  PathNameU.Length = 0;
+  PathNameU.MaximumLength = sizeof(Buffer);
+  RtlCopyUnicodeString(&PathNameU, &FileObject->FileName);
+  if (PathNameU.Length > sizeof(WCHAR) &&
+      PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR) - 1] == L'\\')
     {
-      DPRINT ("No existing FCB found, making a new one if file exists.\n");
-      Status = vfatGetFCBForFile (DeviceExt, &ParentFcb, &Fcb, FileNameU);
-      if (ParentFcb != NULL)
-        {
-          vfatReleaseFCB (DeviceExt, ParentFcb);
-        }
-      if (!NT_SUCCESS (Status))
-        {
-          DPRINT ("Could not make a new FCB, status: %x\n", Status);
-          return  Status;
-	}
+      PathNameU.Length -= sizeof(WCHAR);
     }
-  else
-    {
-      RtlCopyUnicodeString(FileNameU, &Fcb->PathNameU);
-    }
+  PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = 0;
+
+  /*  try first to find an existing FCB in memory  */
+  DPRINT ("Checking for existing FCB in memory\n");
+
+  Status = vfatGetFCBForFile (DeviceExt, ParentFcb, &Fcb, &PathNameU);
+  if (!NT_SUCCESS (Status))
+  {
+     DPRINT ("Could not make a new FCB, status: %x\n", Status);
+     return  Status;
+  }
   if (Fcb->Flags & FCB_DELETE_PENDING)
-    {
-      vfatReleaseFCB (DeviceExt, Fcb);
-      return STATUS_DELETE_PENDING;
-    }
+  {
+     vfatReleaseFCB (DeviceExt, Fcb);
+     return STATUS_DELETE_PENDING;
+  }
   DPRINT ("Attaching FCB to fileObject\n");
   Status = vfatAttachFCBToFileObject (DeviceExt, Fcb, FileObject);
-
+  if (!NT_SUCCESS(Status))
+  {
+     vfatReleaseFCB (DeviceExt, Fcb);
+  }
   return  Status;
 }
 
@@ -481,12 +472,12 @@
   ULONG RequestedDisposition, RequestedOptions;
   PVFATCCB pCcb;
   PVFATFCB pFcb;
+  PVFATFCB ParentFcb;
   PWCHAR c, last;
   BOOLEAN PagingFileCreate = FALSE;
   LARGE_INTEGER AllocationSize;
   BOOLEAN Dots;
-  UNICODE_STRING NameU;
-  WCHAR NameW[MAX_PATH];
+  UNICODE_STRING FileNameU;
   
   /* Unpack the various parameters. */
   Stack = IoGetCurrentIrpStackLocation (Irp);
@@ -563,12 +554,8 @@
 	}
     }
 
-  NameU.Buffer = NameW;
-  NameU.Length = 0;
-  NameU.MaximumLength = sizeof(NameW);
-
   /* Try opening the file. */
-  Status = VfatOpenFile (DeviceExt, FileObject, &NameU);
+  Status = VfatOpenFile (DeviceExt, FileObject, &ParentFcb);
 
   /*
    * If the directory containing the file to open doesn't exist then
@@ -578,6 +565,10 @@
       Status == STATUS_INVALID_PARAMETER ||
       Status == STATUS_DELETE_PENDING)
     {
+      if (ParentFcb)
+      {
+         vfatReleaseFCB (DeviceExt, ParentFcb);
+      }
       return(Status);
     }
 
@@ -593,12 +584,15 @@
 	{
 	  ULONG Attributes;
 	  Attributes = Stack->Parameters.Create.FileAttributes;
-	  Status = VfatAddEntry (DeviceExt, &NameU, FileObject, RequestedOptions, 
+          
+          vfatSplitPathName(&FileObject->FileName, NULL, &FileNameU);
+	  Status = VfatAddEntry (DeviceExt, &FileNameU, &pFcb, ParentFcb, RequestedOptions, 
 				 (UCHAR)(Attributes & FILE_ATTRIBUTE_VALID_FLAGS));
+          vfatReleaseFCB (DeviceExt, ParentFcb);
 	  if (NT_SUCCESS (Status))
 	    {
-	      pFcb = FileObject->FsContext;
-        
+              vfatAttachFCBToFileObject (DeviceExt, pFcb, FileObject);
+      
 	      Irp->IoStatus.Information = FILE_CREATED;
         
 	      VfatSetAllocationSizeInformation(FileObject, 
@@ -621,11 +615,16 @@
 	}
       else
 	{
+          vfatReleaseFCB (DeviceExt, ParentFcb);
 	  return(Status);
 	}
     }
   else
     {
+      if (ParentFcb)
+      {
+         vfatReleaseFCB (DeviceExt, ParentFcb);
+      }
       /* Otherwise fail if the caller wanted to create a new file  */
       if (RequestedDisposition == FILE_CREATE)
 	{

Modified: trunk/reactos/drivers/fs/vfat/dirwr.c
--- trunk/reactos/drivers/fs/vfat/dirwr.c	2005-01-01 11:02:35 UTC (rev 12686)
+++ trunk/reactos/drivers/fs/vfat/dirwr.c	2005-01-01 11:11:52 UTC (rev 12687)
@@ -1,4 +1,4 @@
-/* $Id: dirwr.c,v 1.44 2004/12/25 11:18:38 navaraf Exp $
+/* $Id$
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -183,10 +183,11 @@
 
 NTSTATUS
 FATAddEntry (PDEVICE_EXTENSION DeviceExt,
-	      PUNICODE_STRING PathNameU,
-	      PFILE_OBJECT pFileObject,
-	      ULONG RequestedOptions,
-	      UCHAR ReqAttr)
+	     PUNICODE_STRING NameU,
+	     PVFATFCB* Fcb,
+	     PVFATFCB ParentFcb, 
+	     ULONG RequestedOptions,
+	     UCHAR ReqAttr)
 /*
   create a new FAT entry
 */
@@ -198,11 +199,9 @@
   PUCHAR Buffer;
   BOOLEAN needTilde = FALSE, needLong = FALSE;
   BOOLEAN lCaseBase = FALSE, uCaseBase, lCaseExt = FALSE, uCaseExt;
-  PVFATFCB newFCB;
   ULONG CurrentCluster;
   LARGE_INTEGER SystemTime, FileOffset;
   NTSTATUS Status = STATUS_SUCCESS;
-  PVFATFCB pDirFcb;
   ULONG size;
   long i;
   
@@ -212,33 +211,20 @@
   BOOLEAN SpacesFound;
 
   VFAT_DIRENTRY_CONTEXT DirContext;
-  UNICODE_STRING DirNameU;
   WCHAR LongNameBuffer[MAX_PATH];
   WCHAR ShortNameBuffer[13];
 
-  DPRINT ("addEntry: Pathname='%wZ'\n", PathNameU);
+  DPRINT ("addEntry: Name='%wZ', Dir='%wZ'\n", NameU, &ParentFcb->PathNameU);
 
-  vfatSplitPathName(PathNameU, &DirNameU, &DirContext.LongNameU);
-  if (DirNameU.Length > sizeof(WCHAR))
-    {
-      DirNameU.Length -= sizeof(WCHAR);
-    }
-
-  pDirFcb = vfatGrabFCBFromTable(DeviceExt, &DirNameU);
-  if (pDirFcb == NULL)
-    {
-      return STATUS_UNSUCCESSFUL;
-    }
-
-  if (!ExAcquireResourceExclusiveLite(&pDirFcb->MainResource, TRUE))
-    {
-      DPRINT("Failed acquiring lock\n");
-      return STATUS_UNSUCCESSFUL;
-    }
+  DirContext.LongNameU = *NameU;
   
   nbSlots = (DirContext.LongNameU.Length / sizeof(WCHAR) + 12) / 13 + 1;	//nb of entry needed for long name+normal entry
   DPRINT ("NameLen= %d, nbSlots =%d\n", DirContext.LongNameU.Length / sizeof(WCHAR), nbSlots);
   Buffer = ExAllocatePool (NonPagedPool, (nbSlots - 1) * sizeof (FAT_DIR_ENTRY));
+  if (Buffer == NULL)
+  {
+    return STATUS_INSUFFICIENT_RESOURCES;
+  }		
   RtlZeroMemory (Buffer, (nbSlots - 1) * sizeof (FAT_DIR_ENTRY));
   pSlots = (slot *) Buffer;
 
@@ -254,7 +240,7 @@
 
   IsNameLegal = RtlIsNameLegalDOS8Dot3(&DirContext.LongNameU, &NameA, &SpacesFound);
 
-  if (IsNameLegal == FALSE || SpacesFound != FALSE)
+  if (!IsNameLegal || SpacesFound)
     {
       GENERATE_NAME_CONTEXT NameContext;
       VFAT_DIRENTRY_CONTEXT SearchContext;
@@ -272,7 +258,7 @@
           RtlGenerate8dot3Name(&DirContext.LongNameU, FALSE, &NameContext, &DirContext.ShortNameU);
           DirContext.ShortNameU.Buffer[DirContext.ShortNameU.Length / sizeof(WCHAR)] = 0;
 	  SearchContext.DirIndex = 0;
-          Status = FindFile (DeviceExt, pDirFcb, &DirContext.ShortNameU, &SearchContext, TRUE);
+          Status = FindFile (DeviceExt, ParentFcb, &DirContext.ShortNameU, &SearchContext, TRUE);
           if (!NT_SUCCESS(Status))
             {
 	      break;
@@ -280,8 +266,6 @@
         }
       if (i == 100) /* FIXME : what to do after this ? */
         {
-          ExReleaseResourceLite(&pDirFcb->MainResource);
-          vfatReleaseFCB(DeviceExt, pDirFcb);
           ExFreePool (Buffer);
           CHECKPOINT;
           return STATUS_UNSUCCESSFUL;
@@ -386,6 +370,16 @@
     }
   /* set dates and times */
   KeQuerySystemTime (&SystemTime);
+#if 0
+  {
+    TIME_FIELDS tf;
+    RtlTimeToTimeFields (&SystemTime, &tf);
+    DPRINT1("%d.%d.%d %02d:%02d:%02d.%03d '%wZ'\n", 
+	    tf.Day, tf.Month, tf.Year, tf.Hour, 
+	    tf.Minute, tf.Second, tf.Milliseconds,
+	    NameU);
+  }
+#endif
   FsdSystemTimeToDosDateTime (DeviceExt, &SystemTime, &DirContext.DirEntry.Fat.CreationDate,
                               &DirContext.DirEntry.Fat.CreationTime);
   DirContext.DirEntry.Fat.UpdateDate = DirContext.DirEntry.Fat.CreationDate;
@@ -421,10 +415,8 @@
 	}
     }
   /* try to find nbSlots contiguous entries frees in directory */
-  if (!vfatFindDirSpace(DeviceExt, pDirFcb, nbSlots, &DirContext.StartIndex))
+  if (!vfatFindDirSpace(DeviceExt, ParentFcb, nbSlots, &DirContext.StartIndex))
     {
-      ExReleaseResourceLite(&pDirFcb->MainResource);
-      vfatReleaseFCB(DeviceExt, pDirFcb);
       ExFreePool (Buffer);
       return STATUS_DISK_FULL;
     }
@@ -435,8 +427,6 @@
       Status = NextCluster (DeviceExt, 0, &CurrentCluster, TRUE);
       if (CurrentCluster == 0xffffffff || !NT_SUCCESS(Status))
         {
-          ExReleaseResourceLite(&pDirFcb->MainResource);
-          vfatReleaseFCB(DeviceExt, pDirFcb);
           ExFreePool (Buffer);
           if (!NT_SUCCESS(Status))
             {
@@ -458,7 +448,7 @@
     {
       /* one cluster */
       CHECKPOINT;
-      CcMapData (pDirFcb->FileObject, &FileOffset, nbSlots * sizeof(FAT_DIR_ENTRY),
+      CcMapData (ParentFcb->FileObject, &FileOffset, nbSlots * sizeof(FAT_DIR_ENTRY),
                  TRUE, &Context, (PVOID*)&pFatEntry);
       if (nbSlots > 1)
         {
@@ -473,13 +463,13 @@
       size = DeviceExt->FatInfo.BytesPerCluster -
              (DirContext.StartIndex * sizeof(FAT_DIR_ENTRY)) % DeviceExt->FatInfo.BytesPerCluster;
       i = size / sizeof(FAT_DIR_ENTRY);
-      CcMapData (pDirFcb->FileObject, &FileOffset, size, TRUE,
+      CcMapData (ParentFcb->FileObject, &FileOffset, size, TRUE,
                  &Context, (PVOID*)&pFatEntry);
       RtlCopyMemory(pFatEntry, Buffer, size);
       CcSetDirtyPinnedData(Context, NULL);
       CcUnpinData(Context);
       FileOffset.u.LowPart += size;
-      CcMapData (pDirFcb->FileObject, &FileOffset,
+      CcMapData (ParentFcb->FileObject, &FileOffset,
                  nbSlots * sizeof(FAT_DIR_ENTRY) - size,
                  TRUE, &Context, (PVOID*)&pFatEntry);
       if (nbSlots - 1 > i)
@@ -492,16 +482,15 @@
   CcUnpinData(Context);
 
   /* FIXME: check status */
-  vfatMakeFCBFromDirEntry (DeviceExt, pDirFcb, &DirContext, &newFCB);
-  vfatAttachFCBToFileObject (DeviceExt, newFCB, pFileObject);
+  vfatMakeFCBFromDirEntry (DeviceExt, ParentFcb, &DirContext, Fcb);
 
-  DPRINT ("new : entry=%11.11s\n", newFCB->entry.Fat.Filename);
+  DPRINT ("new : entry=%11.11s\n", (*Fcb)->entry.Fat.Filename);
   DPRINT ("new : entry=%11.11s\n", DirContext.DirEntry.Fat.Filename);
 
   if (RequestedOptions & FILE_DIRECTORY_FILE)
     {
       FileOffset.QuadPart = 0;
-      CcMapData (pFileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster, TRUE,
+      CcMapData ((*Fcb)->FileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster, TRUE,
                  &Context, (PVOID*)&pFatEntry);
       /* clear the new directory cluster */
       RtlZeroMemory (pFatEntry, DeviceExt->FatInfo.BytesPerCluster);
@@ -510,9 +499,9 @@
       RtlCopyMemory (pFatEntry[0].Filename, ".          ", 11);
       RtlCopyMemory (&pFatEntry[1].Attrib, &DirContext.DirEntry.Fat.Attrib, sizeof(FAT_DIR_ENTRY) - 11);
       RtlCopyMemory (pFatEntry[1].Filename, "..         ", 11);
-      pFatEntry[1].FirstCluster = pDirFcb->entry.Fat.FirstCluster;
-      pFatEntry[1].FirstClusterHigh = pDirFcb->entry.Fat.FirstClusterHigh;
-      if (vfatFCBIsRoot(pDirFcb))
+      pFatEntry[1].FirstCluster = ParentFcb->entry.Fat.FirstCluster;
+      pFatEntry[1].FirstClusterHigh = ParentFcb->entry.Fat.FirstClusterHigh;
+      if (vfatFCBIsRoot(ParentFcb))
         {
           pFatEntry[1].FirstCluster = 0;
           pFatEntry[1].FirstClusterHigh = 0;
@@ -520,8 +509,6 @@
       CcSetDirtyPinnedData(Context, NULL);
       CcUnpinData(Context);
     }
-  ExReleaseResourceLite(&pDirFcb->MainResource);
-  vfatReleaseFCB (DeviceExt, pDirFcb);
   ExFreePool (Buffer);
   DPRINT ("addentry ok\n");
   return STATUS_SUCCESS;
@@ -529,8 +516,9 @@
 
 NTSTATUS
 FATXAddEntry (PDEVICE_EXTENSION DeviceExt,
-	      PUNICODE_STRING PathNameU,
-	      PFILE_OBJECT pFileObject,
+	      PUNICODE_STRING NameU,
+	      PVFATFCB* Fcb,
+	      PVFATFCB ParentFcb,
 	      ULONG RequestedOptions,
 	      UCHAR ReqAttr)
 /*
@@ -538,21 +526,14 @@
 */
 {
    PVOID Context = NULL;
-   PVFATFCB newFCB;
    LARGE_INTEGER SystemTime, FileOffset;
-   PVFATFCB pDirFcb;
    OEM_STRING NameA;
    VFAT_DIRENTRY_CONTEXT DirContext;
    PFATX_DIR_ENTRY pFatXDirEntry;
-   UNICODE_STRING DirNameU;
    
-   DPRINT ("addEntry: Pathname='%wZ'\n", PathNameU);
+   DPRINT ("addEntry: Name='%wZ', Dir='%wZ'\n", NameU, &ParentFcb->PathNameU);
    
-   vfatSplitPathName(PathNameU, &DirNameU, &DirContext.LongNameU);
-   if (DirNameU.Length > sizeof(WCHAR))
-   {
-      DirNameU.Length -= sizeof(WCHAR);
-   }
+   DirContext.LongNameU = *NameU;
    
    if (DirContext.LongNameU.Length / sizeof(WCHAR) > 42)
    {
@@ -561,27 +542,13 @@
       return STATUS_NAME_TOO_LONG;
    }
    
-   pDirFcb = vfatGrabFCBFromTable(DeviceExt, &DirNameU);
-   if (pDirFcb == NULL)
-   {
-      return STATUS_UNSUCCESSFUL;
-   }
-   
-   if (!ExAcquireResourceExclusiveLite(&pDirFcb->MainResource, TRUE))
-   {
-      DPRINT("Failed acquiring lock\n");
-      return STATUS_UNSUCCESSFUL;
-   }
-   
    /* try to find 1 entry free in directory */
-   if (!vfatFindDirSpace(DeviceExt, pDirFcb, 1, &DirContext.StartIndex))
+   if (!vfatFindDirSpace(DeviceExt, ParentFcb, 1, &DirContext.StartIndex))
    {
-      ExReleaseResourceLite(&pDirFcb->MainResource);
-      vfatReleaseFCB(DeviceExt, pDirFcb);
       return STATUS_DISK_FULL;
    }
    DirContext.DirIndex = DirContext.StartIndex;
-   if (!vfatFCBIsRoot(pDirFcb))
+   if (!vfatFCBIsRoot(ParentFcb))
    {
       DirContext.DirIndex += 2;
    }
@@ -620,33 +587,31 @@
    /* add entry into parent directory */
    FileOffset.u.HighPart = 0;
    FileOffset.u.LowPart = DirContext.StartIndex * sizeof(FATX_DIR_ENTRY);
-   CcMapData(pDirFcb->FileObject, &FileOffset, sizeof(FATX_DIR_ENTRY),
-                 TRUE, &Context, (PVOID*)&pFatXDirEntry);
+   CcMapData(ParentFcb->FileObject, &FileOffset, sizeof(FATX_DIR_ENTRY),
+             TRUE, &Context, (PVOID*)&pFatXDirEntry);
    RtlCopyMemory(pFatXDirEntry, &DirContext.DirEntry.FatX, sizeof(FATX_DIR_ENTRY));
    CcSetDirtyPinnedData(Context, NULL);
    CcUnpinData(Context);
    
    /* FIXME: check status */
-   vfatMakeFCBFromDirEntry(DeviceExt, pDirFcb, &DirContext, &newFCB);
-   vfatAttachFCBToFileObject(DeviceExt, newFCB, pFileObject);
+   vfatMakeFCBFromDirEntry(DeviceExt, ParentFcb, &DirContext, Fcb);
    
-   ExReleaseResourceLite(&pDirFcb->MainResource);
-   vfatReleaseFCB(DeviceExt, pDirFcb);
    DPRINT("addentry ok\n");
    return STATUS_SUCCESS;
 }
 
 NTSTATUS
 VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
-	      PUNICODE_STRING PathNameU,
-	      PFILE_OBJECT pFileObject,
+	      PUNICODE_STRING NameU,
+	      PVFATFCB *Fcb,
+	      PVFATFCB ParentFcb,
 	      ULONG RequestedOptions,
 	      UCHAR ReqAttr)
 {
    if (DeviceExt->Flags & VCB_IS_FATX)
-      return FATXAddEntry(DeviceExt, PathNameU, pFileObject, RequestedOptions, ReqAttr);
+      return FATXAddEntry(DeviceExt, NameU, Fcb, ParentFcb, RequestedOptions, ReqAttr);
    else
-      return FATAddEntry(DeviceExt, PathNameU, pFileObject, RequestedOptions, ReqAttr);
+      return FATAddEntry(DeviceExt, NameU, Fcb, ParentFcb, RequestedOptions, ReqAttr);
 }
 
 NTSTATUS

Modified: trunk/reactos/drivers/fs/vfat/fcb.c
--- trunk/reactos/drivers/fs/vfat/fcb.c	2005-01-01 11:02:35 UTC (rev 12686)
+++ trunk/reactos/drivers/fs/vfat/fcb.c	2005-01-01 11:11:52 UTC (rev 12687)
@@ -1,4 +1,4 @@
-/* $Id: fcb.c,v 1.43 2004/12/05 16:31:51 gvg Exp $
+/* $Id$
  *
  *
  * FILE:             drivers/fs/vfat/fcb.c
@@ -55,18 +55,25 @@
 vfatSplitPathName(PUNICODE_STRING PathNameU, PUNICODE_STRING DirNameU, PUNICODE_STRING FileNameU)
 {
   PWCHAR pName;
-  DirNameU->Buffer = PathNameU->Buffer;
+  ULONG Length = 0;
   pName = PathNameU->Buffer + PathNameU->Length / sizeof(WCHAR) - 1;
-  while (*pName != L'\\' && pName > PathNameU->Buffer)
+  while (*pName != L'\\' && pName >= PathNameU->Buffer)
     {
       pName--;
+      Length++;
     }
-  ASSERT(*pName == L'\\');
-  FileNameU->Buffer = pName + 1;
-  DirNameU->Length = (FileNameU->Buffer - PathNameU->Buffer) * sizeof(WCHAR);
-  DirNameU->MaximumLength = DirNameU->Length;
-  FileNameU->Length = PathNameU->Length - DirNameU->Length;
-  FileNameU->MaximumLength = FileNameU->Length; 
+  ASSERT(*pName == L'\\' || pName < PathNameU->Buffer);
+  if (FileNameU)
+    {
+      FileNameU->Buffer = pName + 1;
+      FileNameU->Length = FileNameU->MaximumLength = Length * sizeof(WCHAR);
+    }
+  if (DirNameU)
+    {
+      DirNameU->Buffer = PathNameU->Buffer;
+      DirNameU->Length = (pName + 1 - PathNameU->Buffer) * sizeof(WCHAR);
+      DirNameU->MaximumLength = DirNameU->Length;
+    }
 }
 
 VOID
@@ -637,63 +644,85 @@
           pFCB,
           pFileNameU);
 
-  RtlRosInitUnicodeStringFromLiteral(&RootNameU, L"\\");
+  parentFCB = *pParentFCB;
 
-  //  Trivial case, open of the root directory on volume
-  if (RtlEqualUnicodeString(pFileNameU, &RootNameU, FALSE))
-    {
-      DPRINT ("returning root FCB\n");
+  if (parentFCB == NULL)
+  {
+     RtlRosInitUnicodeStringFromLiteral(&RootNameU, L"\\");
 
-      FCB = vfatOpenRootFCB (pVCB);
-      *pFCB = FCB;
-      *pParentFCB = NULL;
+     //  Trivial case, open of the root directory on volume
+     if (RtlEqualUnicodeString(pFileNameU, &RootNameU, FALSE))
+     {
+        DPRINT ("returning root FCB\n");
 
-      return  (FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND;
-    }
+        FCB = vfatOpenRootFCB (pVCB);
+        *pFCB = FCB;
+        *pParentFCB = NULL;
 
-  last = curr = pFileNameU->Buffer + pFileNameU->Length / sizeof(WCHAR) - 1;
-  while (*curr != L'\\' && curr > pFileNameU->Buffer)
-    {
-      curr--;
-    }
+        return  (FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND;
+     }
+
+     /* Check for an existing FCB */
+     FCB = vfatGrabFCBFromTable (pVCB, pFileNameU);
+     if (FCB)
+     {
+        *pFCB = FCB;
+        *pParentFCB = FCB->parentFcb;
+        (*pParentFCB)->RefCount++;
+        return STATUS_SUCCESS;
+     }
+
+     last = curr = pFileNameU->Buffer + pFileNameU->Length / sizeof(WCHAR) - 1;
+     while (*curr != L'\\' && curr > pFileNameU->Buffer)
+     {
+        curr--;
+     }
  
-  if (curr > pFileNameU->Buffer)
-    {
-      NameU.Buffer = pFileNameU->Buffer;
-      NameU.MaximumLength = NameU.Length = (curr - pFileNameU->Buffer) * sizeof(WCHAR);
-      FCB = vfatGrabFCBFromTable(pVCB, &NameU);
-      if (FCB)
+     if (curr > pFileNameU->Buffer)
+     {
+        NameU.Buffer = pFileNameU->Buffer;
+        NameU.MaximumLength = NameU.Length = (curr - pFileNameU->Buffer) * sizeof(WCHAR);
+        FCB = vfatGrabFCBFromTable(pVCB, &NameU);
+        if (FCB)
         {
-	  Length = (curr - pFileNameU->Buffer) * sizeof(WCHAR);
-          if (Length != FCB->PathNameU.Length)
-	    {
+	   Length = (curr - pFileNameU->Buffer) * sizeof(WCHAR);
+           if (Length != FCB->PathNameU.Length)
+	   {
 	      if (pFileNameU->Length + FCB->PathNameU.Length - Length > pFileNameU->MaximumLength)
-	        {
-		  vfatReleaseFCB (pVCB, FCB);
-		  return STATUS_OBJECT_NAME_INVALID;
-		}
+	      {
+		 vfatReleaseFCB (pVCB, FCB);
+		 return STATUS_OBJECT_NAME_INVALID;
+              }
 	      memmove(pFileNameU->Buffer + FCB->PathNameU.Length / sizeof(WCHAR), 
 		      curr, pFileNameU->Length - Length);
 	      pFileNameU->Length += FCB->PathNameU.Length - Length;
 	      curr = pFileNameU->Buffer + FCB->PathNameU.Length / sizeof(WCHAR);
               last = pFileNameU->Buffer + pFileNameU->Length / sizeof(WCHAR) - 1;
-	    }
+	  }
 	  RtlCopyMemory(pFileNameU->Buffer, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
-	}
-    }
-  else
-    {
-      FCB = NULL;
-    }
+        }
+     }
+     else
+     {
+       FCB = NULL;
+     }
 
-  if (FCB == NULL)
-    {
-      FCB = vfatOpenRootFCB(pVCB);
-      curr = pFileNameU->Buffer;
-    }
+     if (FCB == NULL)
+     {
+       FCB = vfatOpenRootFCB(pVCB);
+       curr = pFileNameU->Buffer;
+     }
   
-  parentFCB = NULL;
-  prev = curr;
+     parentFCB = NULL;
+     prev = curr;
+  }
+  else
+  {
+     FCB = parentFCB;
+     parentFCB = NULL;
+     prev = curr = pFileNameU->Buffer - 1;
+     last = pFileNameU->Buffer + pFileNameU->Length / sizeof(WCHAR) - 1;
+  }
 
   while (curr <= last)
     {
@@ -751,14 +780,16 @@
 	  status = vfatDirFindFile(pVCB, parentFCB, &NameU, &FCB);
           if (status == STATUS_OBJECT_NAME_NOT_FOUND)
             {
-              *pParentFCB = parentFCB;
               *pFCB = NULL;
 	      if (curr > last)
 	        {
+                  *pParentFCB = parentFCB;
                   return  STATUS_OBJECT_NAME_NOT_FOUND;
 		}
               else
                 {
+                  vfatReleaseFCB (pVCB, parentFCB);
+		  *pParentFCB = NULL;
                   return  STATUS_OBJECT_PATH_NOT_FOUND;
                 }
 	    }
@@ -778,3 +809,4 @@
 
   return  STATUS_SUCCESS;
 }
+

Modified: trunk/reactos/drivers/fs/vfat/rw.c
--- trunk/reactos/drivers/fs/vfat/rw.c	2005-01-01 11:02:35 UTC (rev 12686)
+++ trunk/reactos/drivers/fs/vfat/rw.c	2005-01-01 11:11:52 UTC (rev 12687)
@@ -1,5 +1,5 @@
 
-/* $Id: rw.c,v 1.72 2004/12/05 16:31:51 gvg Exp $
+/* $Id$
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -642,7 +642,7 @@
       Resource = &Fcb->MainResource;
    }
    if (!ExAcquireResourceSharedLite(Resource,
-                                    (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
+                                    IrpContext->Flags & IRPCONTEXT_CANWAIT ? TRUE : FALSE))
    {
       Resource = NULL;
       Status = STATUS_PENDING;

Modified: trunk/reactos/drivers/fs/vfat/vfat.h
--- trunk/reactos/drivers/fs/vfat/vfat.h	2005-01-01 11:02:35 UTC (rev 12686)
+++ trunk/reactos/drivers/fs/vfat/vfat.h	2005-01-01 11:11:52 UTC (rev 12687)
@@ -1,4 +1,4 @@
-/* $Id: vfat.h,v 1.70 2004/12/05 16:31:51 gvg Exp $ */
+/* $Id$ */
 
 #include <ddk/ntifs.h>
 
@@ -457,7 +457,7 @@
 
 NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt,
                        PFILE_OBJECT FileObject,
-                       PUNICODE_STRING FileNameU);
+		       PVFATFCB* parentFcb);
 
 NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt,
                    PVFATFCB Parent,
@@ -507,7 +507,8 @@
 
 NTSTATUS VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
 		       PUNICODE_STRING PathNameU,
-		       PFILE_OBJECT pFileObject,
+		       PVFATFCB* Fcb,
+		       PVFATFCB ParentFcb,
 		       ULONG RequestedOptions,
 		       UCHAR ReqAttr);