/* In case of moving, don't delete data */
if (MoveContext == NULL)
{
+ ULONG ClusterCount = 0;
+
while (CurrentCluster && CurrentCluster != 0xffffffff)
{
GetNextCluster(DeviceExt, CurrentCluster, &NextCluster);
/* FIXME: check status */
WriteCluster(DeviceExt, CurrentCluster, 0);
CurrentCluster = NextCluster;
+ ClusterCount++;
+ }
+
+ if (ClusterCount != 0 && DeviceExt->FatInfo.FatType == FAT32)
+ {
+ FAT32UpdateFreeClustersCount(DeviceExt, ClusterCount, TRUE);
}
}
#endif
}
+NTSTATUS
+FAT32UpdateFreeClustersCount(
+ PDEVICE_EXTENSION DeviceExt,
+ ULONG Count,
+ BOOLEAN Freed)
+{
+ LARGE_INTEGER Offset;
+ ULONG Length;
+#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
+ NTSTATUS Status;
+#else
+ PVOID Context;
+#endif
+ struct _FsInfoSector * Sector;
+
+ /* We'll read (and then write) the fsinfo sector */
+ Offset.QuadPart = DeviceExt->FatInfo.FSInfoSector * DeviceExt->FatInfo.BytesPerSector;
+ Length = DeviceExt->FatInfo.BytesPerSector;
+#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
+ /* Go through Cc for this */
+ _SEH2_TRY
+ {
+ CcPinRead(DeviceExt->VolumeFcb->FileObject, &Offset, Length, PIN_WAIT, &Context, (PVOID *)&Sector);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+#else
+ /* No Cc, do it the old way:
+ * - Allocate a big enough buffer
+ * - And read the disk
+ */
+ Sector = ExAllocatePoolWithTag(NonPagedPool, Length, TAG_VFAT);
+ if (Sector == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Status = VfatReadDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(Sector, TAG_VFAT);
+ return Status;
+ }
+#endif
+
+ /* Make sure we have a FSINFO sector */
+ if (Sector->ExtBootSignature2 != 0x41615252 ||
+ Sector->FSINFOSignature != 0x61417272 ||
+ Sector->Signatur2 != 0xaa550000)
+ {
+ ASSERT(FALSE);
+#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
+ CcUnpinData(Context);
+#else
+ ExFreePoolWithTag(Sector, TAG_VFAT);
+#endif
+ return STATUS_DISK_CORRUPT_ERROR;
+ }
+
+ /* Update the free clusters count */
+ if (Freed)
+ {
+ Sector->FreeCluster += Count;
+ }
+ else
+ {
+ Sector->FreeCluster -= Count;
+ }
+
+#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
+ /* Mark FSINFO sector dirty so that it gets written to the disk */
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
+ return STATUS_SUCCESS;
+#else
+ /* Write back the FSINFO sector to the disk */
+ Status = VfatWriteDisk(DeviceExt->StorageDevice, &Offset, Length, (PUCHAR)Sector, FALSE);
+ ExFreePoolWithTag(Sector, TAG_VFAT);
+ return Status;
+#endif
+}
+
/* EOF */
}
else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart)
{
+ ULONG ClusterCount;
+
DPRINT("Check for the ability to set file size\n");
if (!MmCanFileBeTruncated(FileObject->SectionObjectPointer,
(PLARGE_INTEGER)AllocationSize))
Status = STATUS_SUCCESS;
}
+ ClusterCount = 0;
while (NT_SUCCESS(Status) && 0xffffffff != Cluster && Cluster > 1)
{
Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
WriteCluster(DeviceExt, Cluster, 0);
Cluster = NCluster;
+ ClusterCount++;
+ }
+
+ if (ClusterCount != 0 && DeviceExt->FatInfo.FatType == FAT32)
+ {
+ FAT32UpdateFreeClustersCount(DeviceExt, ClusterCount, TRUE);
}
}
else