branch update for HEAD-2003021201
[reactos.git] / drivers / fs / vfat / dirwr.c
index e78d8d0..2f5e54d 100644 (file)
@@ -39,22 +39,16 @@ VfatUpdateEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
 {
   PVOID Context;
   PVOID Buffer;
-  NTSTATUS status;
-  PVFATFCB pDirFcb = NULL, pFcb = NULL;
+  PVFATFCB pDirFcb, pFcb;
   LARGE_INTEGER Offset;
 
   DPRINT ("updEntry PathFileName \'%S\'\n", 
           ((PVFATCCB)(pFileObject->FsContext2))->pFcb->PathName);
-  status = vfatGetFCBForFile(DeviceExt, &pDirFcb, &pFcb, 
-             ((PVFATCCB)(pFileObject->FsContext2))->pFcb->PathName);
-  if (!NT_SUCCESS(status))
-  {
-    if (pDirFcb != NULL)
-    {
-      vfatReleaseFCB(DeviceExt, pDirFcb);
-    }
-    return status;
-  }
+
+  pFcb = ((PVFATCCB)(pFileObject->FsContext2))->pFcb;
+  assert (pFcb);
+  pDirFcb = pFcb->parentFcb;
+  assert (pDirFcb);
 
   Offset.u.HighPart = 0;
   Offset.u.LowPart = pFcb->dirIndex * sizeof(FATDirEntry);
@@ -67,8 +61,7 @@ VfatUpdateEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
   }
   else
      DPRINT1 ("Failed write to \'%S\'.\n", pDirFcb->PathName);
-  vfatReleaseFCB(DeviceExt, pDirFcb);
-  vfatReleaseFCB(DeviceExt, pFcb);
+
   return STATUS_SUCCESS;
 }
 
@@ -192,6 +185,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
   short nbSlots = 0, nbFree = 0, j, posCar, NameLen;
   PUCHAR Buffer;
   BOOLEAN needTilde = FALSE, needLong = FALSE;
+  BOOLEAN lCaseBase, uCaseBase, lCaseExt, uCaseExt;
   PVFATFCB newFCB;
   ULONG CurrentCluster;
   LARGE_INTEGER SystemTime, LocalTime, FileOffset;
@@ -334,7 +328,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
     }
     pEntry->Filename[posCar - 2] = '~';
     pEntry->Filename[posCar - 1] = '1';
-    vfat8Dot3ToString (pEntry->Filename, pEntry->Ext, DirName);
+    vfat8Dot3ToString (pEntry, DirName);
     //try first with xxxxxx~y.zzz
     for (i = 1; i < 10; i++)
     {
@@ -356,7 +350,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
       pEntry->Filename[posCar - 3] = '~';
       pEntry->Filename[posCar - 2] = '1';
       pEntry->Filename[posCar - 1] = '0';
-      vfat8Dot3ToString (pEntry->Filename, pEntry->Ext, DirName);
+      vfat8Dot3ToString (pEntry, DirName);
       //try second with xxxxx~yy.zzz
       for (i = 10; i < 100; i++)
       {
@@ -381,9 +375,20 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
   else
   {
     DPRINT ("check if long name entry needed, needlong=%d\n", needLong);
+    lCaseBase = uCaseBase = lCaseExt = uCaseExt = FALSE;
     for (i = 0; i < posCar; i++)
     {
-      if ((USHORT) pEntry->Filename[i] != FileName[i])
+      if ((USHORT) tolower(pEntry->Filename[i]) == FileName[i])
+      {
+         DPRINT ("i=%d,%d,%d\n", i, pEntry->Filename[i], FileName[i]);
+        lCaseBase = TRUE;
+      }
+      else if ((USHORT) pEntry->Filename[i] == FileName[i])
+      {
+         DPRINT ("i=%d,%d,%d\n", i, pEntry->Filename[i], FileName[i]);
+        uCaseBase = TRUE;
+      }
+      else
       {
         DPRINT ("i=%d,%d,%d\n", i, pEntry->Filename[i], FileName[i]);
         needLong = TRUE;
@@ -392,16 +397,30 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
     if (FileName[i])
     {
       i++;                     //jump on point char
-      for (j = 0, i = posCar + 1; FileName[i] && i < posCar + 4; i++)
+      for (j = 0, i = posCar + 1; FileName[i] && i < posCar + 4; i++, j++)
       {
-        if ((USHORT) pEntry->Ext[j++] != FileName[i])
+       if ((USHORT) tolower(pEntry->Ext[j]) == FileName[i])
+       {
+           DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Ext[j], FileName[i]);
+          lCaseExt = TRUE;
+       }
+       else if ((USHORT) pEntry->Ext[j] == FileName[i])
+       {
+           DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Ext[j], FileName[i]);
+          uCaseExt = TRUE;
+       }
+        else
         {
-          DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Filename[i],
-          FileName[i]);
+          DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Ext[j], FileName[i]);
           needLong = TRUE;
         }
       }
     }
+    if ((lCaseBase && uCaseBase) || (lCaseExt && uCaseExt))
+    {
+       CHECKPOINT;
+       needLong = TRUE;
+    }
   }
   if (needLong == FALSE)
   {
@@ -409,6 +428,14 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
     memcpy (Buffer, pEntry, sizeof (FATDirEntry));
     memset (pEntry, 0, sizeof (FATDirEntry));
     pEntry = (FATDirEntry *) Buffer;
+    if (lCaseBase)
+    {
+       pEntry->lCase |= VFAT_CASE_LOWER_BASE;
+    }
+    if (lCaseExt)
+    {
+       pEntry->lCase |= VFAT_CASE_LOWER_EXT;
+    }
   }
   else
   {
@@ -427,39 +454,51 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
   /* set dates and times */
   KeQuerySystemTime (&SystemTime);
   ExSystemTimeToLocalTime (&SystemTime, &LocalTime);
+#if 0
+  {
+    TIME_FIELDS tf;
+    RtlTimeToTimeFields (&LocalTime, &tf);
+    DPRINT1("%d.%d.%d %02d:%02d:%02d.%03d '%S'\n", 
+           tf.Day, tf.Month, tf.Year, tf.Hour, 
+           tf.Minute, tf.Second, tf.Milliseconds,
+           pFileObject->FileName.Buffer);
+  }
+#endif
   FsdFileTimeToDosDateTime ((TIME *) & LocalTime, &pEntry->CreationDate,
                             &pEntry->CreationTime);
   pEntry->UpdateDate = pEntry->CreationDate;
   pEntry->UpdateTime = pEntry->CreationTime;
   pEntry->AccessDate = pEntry->CreationDate;
 
-  // calculate checksum for 8.3 name
-  for (pSlots[0].alias_checksum = i = 0; i < 11; i++)
-  {
-    pSlots[0].alias_checksum = (((pSlots[0].alias_checksum & 1) << 7
-                                | ((pSlots[0].alias_checksum & 0xfe) >> 1))
-                                + pEntry->Filename[i]);
-  }
-  //construct slots and entry
-  for (i = nbSlots - 2; i >= 0; i--)
+  if (needLong)
   {
-    DPRINT ("construct slot %d\n", i);
-    pSlots[i].attr = 0xf;
-    if (i)
+    // calculate checksum for 8.3 name
+    for (pSlots[0].alias_checksum = i = 0; i < 11; i++)
     {
-      pSlots[i].id = nbSlots - i - 1;
+       pSlots[0].alias_checksum = (((pSlots[0].alias_checksum & 1) << 7
+                                  | ((pSlots[0].alias_checksum & 0xfe) >> 1))
+                                  + pEntry->Filename[i]);
     }
-    else
+    //construct slots and entry
+    for (i = nbSlots - 2; i >= 0; i--)
     {
-      pSlots[i].id = nbSlots - i - 1 + 0x40;
-    }
-    pSlots[i].alias_checksum = pSlots[0].alias_checksum;
+       DPRINT ("construct slot %d\n", i);
+       pSlots[i].attr = 0xf;
+       if (i)
+       {
+          pSlots[i].id = nbSlots - i - 1;
+       }
+       else
+       {
+          pSlots[i].id = nbSlots - i - 1 + 0x40;
+       }
+       pSlots[i].alias_checksum = pSlots[0].alias_checksum;
 //FIXME      pSlots[i].start=;
-    memcpy (pSlots[i].name0_4, DirName + (nbSlots - i - 2) * 13, 10);
-    memcpy (pSlots[i].name5_10, DirName + (nbSlots - i - 2) * 13 + 5, 12);
-    memcpy (pSlots[i].name11_12, DirName + (nbSlots - i - 2) * 13 + 11, 4);
+       memcpy (pSlots[i].name0_4, DirName + (nbSlots - i - 2) * 13, 10);
+       memcpy (pSlots[i].name5_10, DirName + (nbSlots - i - 2) * 13 + 5, 12);
+       memcpy (pSlots[i].name11_12, DirName + (nbSlots - i - 2) * 13 + 11, 4);
+    }
   }
-
   //try to find nbSlots contiguous entries frees in directory
   if (!findDirSpace(DeviceExt, pDirFcb, nbSlots, &start))
   {
@@ -522,7 +561,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
 
   // FEXME: check status
   vfatMakeFCBFromDirEntry (DeviceExt, pDirFcb, FileName, pEntry,
-                           start + nbSlots - 1, &newFCB);
+                           start, start + nbSlots - 1, &newFCB);
   vfatAttachFCBToFileObject (DeviceExt, newFCB, pFileObject);
 
   DPRINT ("new : entry=%11.11s\n", newFCB->entry.Filename);