Author: fireball
Date: Sun Aug 8 10:43:28 2010
New Revision: 48487
URL:
http://svn.reactos.org/svn/reactos?rev=48487&view=rev
Log:
[FASTFAT_NEW]
- Implement close and cleanup infrastructure.
- Add necessary FCB and VCB counters.
- Add missing op and file locks initialization.
- A lot of small cleanups, improvements, and other things, bringing fastfat_new much
closer to a minimally working state.
Modified:
trunk/reactos/drivers/filesystems/fastfat_new/cleanup.c
trunk/reactos/drivers/filesystems/fastfat_new/close.c
trunk/reactos/drivers/filesystems/fastfat_new/create.c
trunk/reactos/drivers/filesystems/fastfat_new/dir.c
trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c
trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h
trunk/reactos/drivers/filesystems/fastfat_new/fat.c
trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h
trunk/reactos/drivers/filesystems/fastfat_new/fcb.c
trunk/reactos/drivers/filesystems/fastfat_new/volume.c
Modified: trunk/reactos/drivers/filesystems/fastfat_new/cleanup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/cleanup.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/cleanup.c [iso-8859-1] Sun Aug 8
10:43:28 2010
@@ -13,13 +13,431 @@
/* FUNCTIONS ****************************************************************/
+/* Last handle to a file object is closed */
+NTSTATUS
+NTAPI
+FatiCleanup(PFAT_IRP_CONTEXT IrpContext, PIRP Irp)
+{
+ PIO_STACK_LOCATION IrpSp;
+ PFILE_OBJECT FileObject;
+ TYPE_OF_OPEN TypeOfOpen;
+ PSHARE_ACCESS ShareAccess;
+ BOOLEAN SendUnlockNotification = FALSE;
+ PLARGE_INTEGER TruncateSize = NULL;
+ //LARGE_INTEGER LocalTruncateSize;
+ BOOLEAN AcquiredVcb = FALSE, AcquiredFcb = FALSE;
+ NTSTATUS Status;
+ PVCB Vcb;
+ PFCB Fcb;
+ PCCB Ccb;
+
+ IrpSp = IoGetCurrentIrpStackLocation( Irp );
+
+ DPRINT("FatiCleanup\n");
+ DPRINT("\tIrp = %p\n", Irp);
+ DPRINT("\t->FileObject = %p\n", IrpSp->FileObject);
+
+ FileObject = IrpSp->FileObject;
+ TypeOfOpen = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb);
+
+ if (TypeOfOpen == UnopenedFileObject)
+ {
+ DPRINT1("Unopened File Object\n");
+
+ FatCompleteRequest(IrpContext, Irp, STATUS_SUCCESS);
+ return STATUS_SUCCESS;
+ }
+
+ if (FlagOn( FileObject->Flags, FO_CLEANUP_COMPLETE ))
+ {
+ /* Just flush the file */
+
+ if (FlagOn(Vcb->State, VCB_STATE_FLAG_DEFERRED_FLUSH) &&
+ FlagOn(FileObject->Flags, FO_FILE_MODIFIED) &&
+ !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED) &&
+ (TypeOfOpen == UserFileOpen))
+ {
+ //Status = FatFlushFile(IrpContext, Fcb, Flush);
+ //if (!NT_SUCCESS(Status)) FatNormalizeAndRaiseStatus(IrpContext, Status);
+ UNIMPLEMENTED;
+ }
+
+ FatCompleteRequest(IrpContext, Irp, STATUS_SUCCESS);
+ return STATUS_SUCCESS;
+ }
+
+ if (TypeOfOpen == UserFileOpen ||
+ TypeOfOpen == UserDirectoryOpen)
+ {
+ ASSERT(Fcb != NULL);
+
+ (VOID)FatAcquireExclusiveFcb(IrpContext, Fcb);
+
+ AcquiredFcb = TRUE;
+
+ /* Set FCB flags according to DELETE_ON_CLOSE */
+ if (FlagOn(Ccb->Flags, CCB_DELETE_ON_CLOSE))
+ {
+ ASSERT(FatNodeType(Fcb) != FAT_NTC_ROOT_DCB);
+
+ SetFlag(Fcb->State, FCB_STATE_DELETE_ON_CLOSE);
+
+ /* Issue a notification */
+ if (TypeOfOpen == UserDirectoryOpen)
+ {
+ FsRtlNotifyFullChangeDirectory(Vcb->NotifySync,
+ &Vcb->NotifyList,
+ FileObject->FsContext,
+ NULL,
+ FALSE,
+ FALSE,
+ 0,
+ NULL,
+ NULL,
+ NULL);
+ }
+ }
+
+ /* If file should be deleted, acquire locks */
+ if ((Fcb->UncleanCount == 1) &&
+ FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) &&
+ (Fcb->Condition != FcbBad) &&
+ !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED))
+ {
+ FatReleaseFcb(IrpContext, Fcb);
+ AcquiredFcb = FALSE;
+
+ (VOID)FatAcquireExclusiveVcb(IrpContext, Vcb);
+ AcquiredVcb = TRUE;
+
+ (VOID)FatAcquireExclusiveFcb(IrpContext, Fcb);
+ AcquiredFcb = TRUE;
+ }
+ }
+
+ /* Acquire VCB lock if it was a volume open */
+ if (TypeOfOpen == UserVolumeOpen)
+ {
+ (VOID)FatAcquireExclusiveVcb(IrpContext, Vcb);
+ AcquiredVcb = TRUE;
+ }
+
+ /* Cleanup all notifications */
+ if (TypeOfOpen == UserDirectoryOpen)
+ {
+ FsRtlNotifyCleanup(Vcb->NotifySync,
+ &Vcb->NotifyList,
+ Ccb);
+ }
+
+ if (Fcb)
+ {
+ //TODO: FatVerifyFcb
+ }
+
+ switch (TypeOfOpen)
+ {
+ case DirectoryFile:
+ case VirtualVolumeFile:
+ DPRINT1("Cleanup VirtualVolumeFile/DirectoryFile\n");
+ ShareAccess = NULL;
+ break;
+
+ case UserVolumeOpen:
+ DPRINT("Cleanup UserVolumeOpen\n");
+
+ if (FlagOn(Ccb->Flags, CCB_COMPLETE_DISMOUNT))
+ {
+ FatCheckForDismount( IrpContext, Vcb, TRUE );
+ } else if (FileObject->WriteAccess &&
+ FlagOn(FileObject->Flags, FO_FILE_MODIFIED))
+ {
+ UNIMPLEMENTED;
+ }
+
+ /* Release the volume and send notification */
+ if (FlagOn(Vcb->State, VCB_STATE_FLAG_LOCKED) &&
+ (Vcb->FileObjectWithVcbLocked == FileObject))
+ {
+ UNIMPLEMENTED;
+ SendUnlockNotification = TRUE;
+ }
+
+ ShareAccess = &Vcb->ShareAccess;
+ break;
+
+ case EaFile:
+ DPRINT1("Cleanup EaFileObject\n");
+ ShareAccess = NULL;
+ break;
+
+ case UserDirectoryOpen:
+ DPRINT("Cleanup UserDirectoryOpen\n");
+
+ ShareAccess = &Fcb->ShareAccess;
+
+ /* Should it be a delayed close? */
+ if ((Fcb->UncleanCount == 1) &&
+ (Fcb->OpenCount == 1) &&
+ (Fcb->Dcb.DirectoryFileOpenCount == 0) &&
+ !FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) &&
+ Fcb->Condition == FcbGood)
+ {
+ /* Yes, a delayed one */
+ SetFlag(Fcb->State, FCB_STATE_DELAY_CLOSE);
+ }
+
+ if (VcbGood == Vcb->Condition)
+ {
+ //FatUpdateDirentFromFcb( IrpContext, FileObject, Fcb, Ccb );
+ //TODO: Actually update dirent
+ }
+
+ if ((Fcb->UncleanCount == 1) &&
+ (FatNodeType(Fcb) == FAT_NTC_DCB) &&
+ (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE)) &&
+ (Fcb->Condition != FcbBad) &&
+ !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED))
+ {
+ UNIMPLEMENTED;
+ }
+
+ /* Decrement unclean counter */
+ ASSERT(Fcb->UncleanCount != 0);
+ Fcb->UncleanCount--;
+ break;
+
+ case UserFileOpen:
+ DPRINT("Cleanup UserFileOpen\n");
+
+ ShareAccess = &Fcb->ShareAccess;
+
+ /* Should it be a delayed close? */
+ if ((FileObject->SectionObjectPointer->DataSectionObject == NULL)
&&
+ (FileObject->SectionObjectPointer->ImageSectionObject == NULL)
&&
+ (Fcb->UncleanCount == 1) &&
+ (Fcb->OpenCount == 1) &&
+ !FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) &&
+ Fcb->Condition == FcbGood)
+ {
+ /* Yes, a delayed one */
+ SetFlag(Fcb->State, FCB_STATE_DELAY_CLOSE);
+ }
+
+ /* Unlock all file locks */
+ FsRtlFastUnlockAll(&Fcb->Fcb.Lock,
+ FileObject,
+ IoGetRequestorProcess(Irp),
+ NULL);
+
+ if (Vcb->Condition == VcbGood)
+ {
+ if (Fcb->Condition != FcbBad)
+ {
+ //FatUpdateDirentFromFcb( IrpContext, FileObject, Fcb, Ccb );
+ // TODO: Update on-disk structures
+ }
+
+ if (Fcb->UncleanCount == 1 &&
+ Fcb->Condition != FcbBad)
+ {
+ //DELETE_CONTEXT DeleteContext;
+
+ /* Should this file be deleted on close? */
+ if (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) &&
+ !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED))
+ {
+ UNIMPLEMENTED;
+ }
+ else
+ {
+ if (!FlagOn(Fcb->State, FCB_STATE_PAGEFILE) &&
+ (Fcb->Header.ValidDataLength.LowPart <
Fcb->Header.FileSize.LowPart))
+ {
+#if 0
+ ULONG ValidDataLength;
+
+ ValidDataLength = Fcb->Header.ValidDataLength.LowPart;
+
+ if (ValidDataLength < Fcb->ValidDataToDisk) {
+ ValidDataLength = Fcb->ValidDataToDisk;
+ }
+
+ if (ValidDataLength < Fcb->Header.FileSize.LowPart)
+ {
+ FatZeroData( IrpContext,
+ Vcb,
+ FileObject,
+ ValidDataLength,
+ Fcb->Header.FileSize.LowPart -
+ ValidDataLength );
+
+ Fcb->ValidDataToDisk =
+ Fcb->Header.ValidDataLength.LowPart =
+ Fcb->Header.FileSize.LowPart;
+
+ if (CcIsFileCached(FileObject))
+ {
+ CcSetFileSizes(FileObject,
(PCC_FILE_SIZES)&Fcb->Header.AllocationSize);
+ }
+ }
+#endif
+ DPRINT1("Zeroing out data is not implemented\n");
+ }
+ }
+
+ /* Should the file be truncated on close? */
+ if (FlagOn(Fcb->State, FCB_STATE_TRUNCATE_ON_CLOSE))
+ {
+ if (Vcb->Condition == VcbGood)
+ {
+ // TODO: Actually truncate the file allocation
+ UNIMPLEMENTED;
+ }
+
+ /* Remove truncation flag */
+ Fcb->State &= ~FCB_STATE_TRUNCATE_ON_CLOSE;
+ }
+
+ /* Check again if it should be deleted */
+ if (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) &&
+ Fcb->Header.AllocationSize.LowPart == 0)
+ {
+ UNIMPLEMENTED;
+ /*FatNotifyReportChange(IrpContext,
+ Vcb,
+ Fcb,
+ FILE_NOTIFY_CHANGE_FILE_NAME,
+ FILE_ACTION_REMOVED );*/
+ }
+
+ /* Remove the entry from the splay table if the file was deleted */
+ if (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE))
+ {
+ FatRemoveNames(IrpContext, Fcb);
+ }
+ }
+ }
+
+ ASSERT(Fcb->UncleanCount != 0);
+ Fcb->UncleanCount--;
+ if (!FlagOn(FileObject->Flags, FO_CACHE_SUPPORTED))
+ {
+ ASSERT(Fcb->NonCachedUncleanCount != 0);
+ Fcb->NonCachedUncleanCount--;
+ }
+
+ if (FlagOn(FileObject->Flags, FO_CACHE_SUPPORTED) &&
+ (Fcb->NonCachedUncleanCount != 0) &&
+ (Fcb->NonCachedUncleanCount == Fcb->UncleanCount) &&
+ (Fcb->SectionObjectPointers.DataSectionObject != NULL))
+ {
+ CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, NULL);
+
+ /* Acquire and release PagingIo to get in sync with lazy writer */
+ ExAcquireResourceExclusiveLite(Fcb->Header.PagingIoResource, TRUE);
+ ExReleaseResourceLite(Fcb->Header.PagingIoResource);
+
+ CcPurgeCacheSection(&Fcb->SectionObjectPointers,
+ NULL,
+ 0,
+ FALSE);
+ }
+
+ if (Fcb->Condition == FcbBad)
+ {
+ //TruncateSize = &FatLargeZero;
+ UNIMPLEMENTED;
+ }
+
+ /* Cleanup the cache map */
+ CcUninitializeCacheMap(FileObject, TruncateSize, NULL);
+ break;
+
+ default:
+ KeBugCheckEx(FAT_FILE_SYSTEM, __LINE__, (ULONG_PTR)TypeOfOpen, 0, 0);
+ }
+
+ /* Cleanup the share access */
+
+ if (ShareAccess)
+ {
+ DPRINT("Cleaning up the share access\n");
+ IoRemoveShareAccess(FileObject, ShareAccess);
+ }
+
+ if (TypeOfOpen == UserFileOpen)
+ {
+ /* Update oplocks */
+ FsRtlCheckOplock(&Fcb->Fcb.Oplock,
+ Irp,
+ IrpContext,
+ NULL,
+ NULL);
+
+ Fcb->Header.IsFastIoPossible = FatIsFastIoPossible(Fcb);
+ }
+
+ /* Set the FO_CLEANUP_COMPLETE flag */
+ SetFlag(FileObject->Flags, FO_CLEANUP_COMPLETE);
+
+ Status = STATUS_SUCCESS;
+
+ // TODO: Unpin repinned BCBs
+ //FatUnpinRepinnedBcbs(IrpContext);
+
+ /* Flush the volume if necessary */
+ if (FlagOn(Vcb->State, VCB_STATE_FLAG_DEFERRED_FLUSH) &&
+ !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED))
+ {
+ UNIMPLEMENTED;
+ }
+
+ /* Cleanup */
+ if (AcquiredFcb) FatReleaseFcb(IrpContext, Fcb);
+ if (AcquiredVcb) FatReleaseVcb(IrpContext, Vcb);
+
+ /* Send volume notification */
+ if (SendUnlockNotification)
+ FsRtlNotifyVolumeEvent(FileObject, FSRTL_VOLUME_UNLOCK);
+
+ return Status;
+}
+
NTSTATUS
NTAPI
FatCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
- DPRINT1("FatCleanup(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
-
- return STATUS_NOT_IMPLEMENTED;
+ PFAT_IRP_CONTEXT IrpContext;
+ NTSTATUS Status;
+
+ DPRINT("FatCleanup(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
+
+ /* FatCleanup works only with a volume device object */
+ if (DeviceObject == FatGlobalData.DiskDeviceObject)
+ {
+ /* Complete the request and return success */
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = FILE_OPENED;
+
+ IoCompleteRequest(Irp, IO_DISK_INCREMENT);
+
+ return STATUS_SUCCESS;
+ }
+
+ /* Enter FsRtl critical region */
+ FsRtlEnterFileSystem();
+
+ /* Build an irp context */
+ IrpContext = FatBuildIrpContext(Irp, TRUE);
+
+ /* Call internal function */
+ Status = FatiCleanup(IrpContext, Irp);
+
+ /* Leave FsRtl critical region */
+ FsRtlExitFileSystem();
+
+ return Status;
}
/* EOF */
Modified: trunk/reactos/drivers/filesystems/fastfat_new/close.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/close.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/close.c [iso-8859-1] Sun Aug 8 10:43:28
2010
@@ -15,11 +15,340 @@
NTSTATUS
NTAPI
+FatiCommonClose(IN PVCB Vcb,
+ IN PFCB Fcb,
+ IN PCCB Ccb,
+ IN TYPE_OF_OPEN TypeOfOpen,
+ IN BOOLEAN Wait,
+ OUT PBOOLEAN VcbDeleted)
+{
+ NTSTATUS Status;
+ PFCB ParentDcb;
+ BOOLEAN RecursiveClose, VcbDeletedLv = FALSE;
+ FAT_IRP_CONTEXT IrpContext;
+
+ if (VcbDeleted) *VcbDeleted = FALSE;
+
+ if (TypeOfOpen == UnopenedFileObject)
+ {
+ DPRINT1("Closing unopened file object\n");
+ Status = STATUS_SUCCESS;
+ return Status;
+ }
+
+ RtlZeroMemory(&IrpContext, sizeof(FAT_IRP_CONTEXT));
+
+ IrpContext.NodeTypeCode = FAT_NTC_IRP_CONTEXT;
+ IrpContext.NodeByteSize = sizeof(IrpContext);
+ IrpContext.MajorFunction = IRP_MJ_CLOSE;
+
+ if (Wait) SetFlag(IrpContext.Flags, IRPCONTEXT_CANWAIT);
+
+ if (!ExAcquireResourceExclusiveLite(&Vcb->Resource, Wait)) return
STATUS_PENDING;
+
+ if (Vcb->State & VCB_STATE_FLAG_CLOSE_IN_PROGRESS)
+ {
+ RecursiveClose = TRUE;
+ }
+ else
+ {
+ SetFlag(Vcb->State, VCB_STATE_FLAG_CLOSE_IN_PROGRESS);
+ RecursiveClose = FALSE;
+
+ Vcb->OpenFileCount++;
+ }
+
+ /* Update on-disk structures */
+ switch (TypeOfOpen)
+ {
+ case VirtualVolumeFile:
+ DPRINT1("Close VirtualVolumeFile\n");
+
+ InterlockedDecrement((PLONG)&(Vcb->InternalOpenCount));
+ InterlockedDecrement((PLONG)&(Vcb->ResidualOpenCount));
+
+ Status = STATUS_SUCCESS;
+ goto close_done;
+ break;
+
+ case UserVolumeOpen:
+ DPRINT1("Close UserVolumeOpen\n");
+
+ Vcb->DirectAccessOpenCount--;
+ Vcb->OpenFileCount--;
+ if (FlagOn(Ccb->Flags, CCB_READ_ONLY)) Vcb->ReadOnlyCount--;
+
+ FatDeleteCcb(&IrpContext, Ccb);
+
+ Status = STATUS_SUCCESS;
+ goto close_done;
+ break;
+
+ case EaFile:
+ UNIMPLEMENTED;
+ break;
+
+ case DirectoryFile:
+ DPRINT1("Close DirectoryFile\n");
+
+ InterlockedDecrement((PLONG)&(Fcb->Dcb.DirectoryFileOpenCount));
+ InterlockedDecrement((PLONG)&(Vcb->InternalOpenCount));
+
+ if (FatNodeType(Fcb) == FAT_NTC_ROOT_DCB)
+ {
+ InterlockedDecrement((PLONG)&(Vcb->ResidualOpenCount));
+ }
+
+ if (RecursiveClose)
+ {
+ Status = STATUS_SUCCESS;
+ goto close_done;
+ }
+ else
+ {
+ break;
+ }
+
+ case UserDirectoryOpen:
+ case UserFileOpen:
+ DPRINT("Close UserFileOpen/UserDirectoryOpen\n");
+
+ if ((FatNodeType(Fcb) == FAT_NTC_DCB) &&
+ IsListEmpty(&Fcb->Dcb.ParentDcbList) &&
+ (Fcb->OpenCount == 1) &&
+ (Fcb->Dcb.DirectoryFile != NULL))
+ {
+ PFILE_OBJECT DirectoryFileObject = Fcb->Dcb.DirectoryFile;
+
+ DPRINT1("Uninitialize the stream file object\n");
+
+ CcUninitializeCacheMap(DirectoryFileObject, NULL, NULL);
+
+ Fcb->Dcb.DirectoryFile = NULL;
+ ObDereferenceObject(DirectoryFileObject);
+ }
+
+ Fcb->OpenCount--;
+ Vcb->OpenFileCount--;
+ if (FlagOn(Ccb->Flags, CCB_READ_ONLY)) Vcb->ReadOnlyCount --;
+
+ FatDeleteCcb(&IrpContext, Ccb);
+ break;
+
+ default:
+ KeBugCheckEx(FAT_FILE_SYSTEM, __LINE__, (ULONG_PTR)TypeOfOpen, 0, 0);
+ }
+
+ /* Update in-memory structures */
+ if (((FatNodeType(Fcb) == FAT_NTC_FCB) &&
+ (Fcb->OpenCount == 0))
+ ||
+ ((FatNodeType(Fcb) == FAT_NTC_DCB) &&
+ (IsListEmpty(&Fcb->Dcb.ParentDcbList)) &&
+ (Fcb->OpenCount == 0) &&
+ (Fcb->Dcb.DirectoryFileOpenCount == 0)))
+ {
+ ParentDcb = Fcb->ParentFcb;
+
+ SetFlag(Vcb->State, VCB_STATE_FLAG_DELETED_FCB);
+
+ FatDeleteFcb(&IrpContext, Fcb);
+
+ while ((FatNodeType(ParentDcb) == FAT_NTC_DCB) &&
+ IsListEmpty(&ParentDcb->Dcb.ParentDcbList) &&
+ (ParentDcb->OpenCount == 0) &&
+ (ParentDcb->Dcb.DirectoryFile != NULL))
+ {
+ PFILE_OBJECT DirectoryFileObject;
+
+ DirectoryFileObject = ParentDcb->Dcb.DirectoryFile;
+
+ DPRINT1("Uninitialize parent Stream Cache Map\n");
+
+ CcUninitializeCacheMap(DirectoryFileObject, NULL, NULL);
+
+ ParentDcb->Dcb.DirectoryFile = NULL;
+
+ ObDereferenceObject(DirectoryFileObject);
+
+ if (ParentDcb->Dcb.DirectoryFileOpenCount == 0)
+ {
+ PFCB CurrentDcb;
+
+ CurrentDcb = ParentDcb;
+ ParentDcb = CurrentDcb->ParentFcb;
+
+ SetFlag(Vcb->State, VCB_STATE_FLAG_DELETED_FCB);
+
+ FatDeleteFcb(&IrpContext, CurrentDcb);
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ Status = STATUS_SUCCESS;
+
+close_done:
+ /* Closing is done, check if VCB could be closed too */
+ if (!RecursiveClose)
+ {
+ /* One open left - yes, VCB can go away */
+ if (Vcb->OpenFileCount == 1 &&
+ !FlagOn(Vcb->State, VCB_STATE_FLAG_DISMOUNT_IN_PROGRESS)
+ && VcbDeleted)
+ {
+ FatReleaseVcb(&IrpContext, Vcb );
+
+ SetFlag(IrpContext.Flags, IRPCONTEXT_CANWAIT);
+
+ FatAcquireExclusiveGlobal(&IrpContext);
+
+ FatAcquireExclusiveVcb(&IrpContext, Vcb);
+
+ Vcb->OpenFileCount--;
+
+ VcbDeletedLv = FatCheckForDismount(&IrpContext, Vcb, FALSE);
+
+ FatReleaseGlobal(&IrpContext);
+
+ if (VcbDeleted) *VcbDeleted = VcbDeletedLv;
+ }
+ else
+ {
+ /* Remove extra referenec */
+ Vcb->OpenFileCount --;
+ }
+
+ /* Clear recursion flag if necessary */
+ if (!VcbDeletedLv)
+ {
+ ClearFlag(Vcb->State, VCB_STATE_FLAG_CLOSE_IN_PROGRESS);
+ }
+ }
+
+ /* Release VCB if it wasn't deleted */
+ if (!VcbDeletedLv)
+ FatReleaseVcb(&IrpContext, Vcb);
+
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+FatiClose(IN PFAT_IRP_CONTEXT IrpContext,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IrpSp;
+ TYPE_OF_OPEN TypeOfOpen;
+ PVCB Vcb;
+ PFCB Fcb;
+ PCCB Ccb;
+ BOOLEAN TopLevel, Wait, VcbDeleted = FALSE;
+ NTSTATUS Status;
+ PCLOSE_CONTEXT CloseContext = NULL;
+
+ TopLevel = FatIsTopLevelIrp(Irp);
+
+ /* Get current IRP stack location */
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+ /* Decode incoming file object */
+ TypeOfOpen = FatDecodeFileObject(IrpSp->FileObject, &Vcb, &Fcb,
&Ccb);
+
+ /* Set CCB read only flag */
+ if (Ccb && IsFileObjectReadOnly(IrpSp->FileObject))
+ SetFlag(Ccb->Flags, CCB_READ_ONLY);
+
+ /* It's possible to wait only if we are top level or not a system process */
+ Wait = TopLevel && (PsGetCurrentProcess() != FatGlobalData.SystemProcess);
+
+ /* Call the common handler */
+ Status = FatiCommonClose(Vcb, Fcb, Ccb, TypeOfOpen, Wait, &VcbDeleted);
+
+ if (((TypeOfOpen == UserFileOpen ||
+ TypeOfOpen == UserDirectoryOpen) &&
+ (Fcb->State & FCB_STATE_DELAY_CLOSE) &&
+ !FatGlobalData.ShutdownStarted) ||
+ Status == STATUS_PENDING)
+ {
+ DPRINT1("TODO: Queue a pending close request\n");
+ }
+ else
+ {
+ /* Close finished right away */
+ if (TypeOfOpen == VirtualVolumeFile ||
+ TypeOfOpen == DirectoryFile ||
+ TypeOfOpen == EaFile)
+ {
+ if (TypeOfOpen == VirtualVolumeFile)
+ {
+ /* Free close context for the not deleted VCB */
+ if (!VcbDeleted)
+ {
+ CloseContext = Vcb->CloseContext;
+ Vcb->CloseContext = NULL;
+
+ ASSERT(CloseContext != NULL);
+ }
+ }
+ else
+ {
+ //CloseContext = FatAllocateCloseContext(Vcb);
+ DPRINT1("TODO: Allocate close context!\n");
+ ASSERT(CloseContext != NULL);
+ }
+
+ /* Free close context */
+ if (CloseContext) ExFreePool(CloseContext);
+ }
+ }
+
+ /* Complete the request */
+ FatCompleteRequest(NULL, Irp, Status);
+
+ /* Reset the top level IRP if necessary */
+ if (TopLevel) IoSetTopLevelIrp(NULL);
+
+ return Status;
+}
+
+NTSTATUS
+NTAPI
FatClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
- DPRINT1("FatClose(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
-
- return STATUS_NOT_IMPLEMENTED;
+ PFAT_IRP_CONTEXT IrpContext;
+ NTSTATUS Status;
+
+ DPRINT("FatClose(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
+
+ /* FatClose works only with a volume device object */
+ if (DeviceObject == FatGlobalData.DiskDeviceObject)
+ {
+ /* Complete the request and return success */
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = FILE_OPENED;
+
+ IoCompleteRequest(Irp, IO_DISK_INCREMENT);
+
+ return STATUS_SUCCESS;
+ }
+
+ /* Enter FsRtl critical region */
+ FsRtlEnterFileSystem();
+
+ /* Build an irp context */
+ IrpContext = FatBuildIrpContext(Irp, TRUE);
+
+ /* Call internal function */
+ Status = FatiClose(IrpContext, Irp);
+
+ /* Leave FsRtl critical region */
+ FsRtlExitFileSystem();
+
+ return Status;
}
/* EOF */
Modified: trunk/reactos/drivers/filesystems/fastfat_new/create.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/create.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/create.c [iso-8859-1] Sun Aug 8
10:43:28 2010
@@ -72,7 +72,9 @@
/* Increment counters */
Dcb->OpenCount++;
+ Dcb->UncleanCount++;
Vcb->OpenFileCount++;
+ if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++;
/* Set success statuses */
Iosb.Status = STATUS_SUCCESS;
@@ -186,7 +188,7 @@
CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize);
// TODO: Actually truncate the file
- DPRINT1("TODO: Actually truncate the file with a fullfat handle %x\n",
Fcb->FatHandle);
+ DPRINT1("TODO: Actually truncate file '%wZ' with a fullfat handle
%x\n", &Fcb->FullFileName, Fcb->FatHandle);
/* Release the paging resource */
ExReleaseResourceLite(Fcb->Header.PagingIoResource);
@@ -287,6 +289,12 @@
UserDirectoryOpen,
Fcb,
FatCreateCcb());
+
+ /* Increase counters */
+ Fcb->UncleanCount++;
+ Fcb->OpenCount++;
+ Vcb->OpenFileCount++;
+ if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++;
Iosb.Status = STATUS_SUCCESS;
Iosb.Information = FILE_OPENED;
@@ -319,6 +327,7 @@
PFCB Fcb;
NTSTATUS Status;
FF_FILE *FileHandle;
+ FF_ERROR FfError;
/* Check for create file option and fail */
if (CreateDisposition == FILE_CREATE)
@@ -341,20 +350,22 @@
}
/* Open the file with FullFAT */
- FileHandle = FF_Open(Vcb->Ioman, AnsiName.Buffer, FF_MODE_READ, NULL);
+ FileHandle = FF_Open(Vcb->Ioman, AnsiName.Buffer, FF_MODE_READ, &FfError);
if (!FileHandle)
{
+ DPRINT1("Failed to open file '%s', error %ld\n",
AnsiName.Buffer, FfError);
Iosb.Status = STATUS_OBJECT_NAME_NOT_FOUND; // FIXME: A shortcut for now
return Iosb;
}
+ DPRINT1("Succeeded opening file '%s'\n", AnsiName.Buffer);
/* Create a new FCB for this file */
Fcb = FatCreateFcb(IrpContext, Vcb, ParentDcb, FileHandle);
// TODO: Check if overwrite is needed
- // This is usual file open branch, without overwriting!
+ // TODO: This is usual file open branch, without overwriting!
/* Set context and section object pointers */
FatSetFileObject(FileObject,
UserFileOpen,
@@ -364,6 +375,13 @@
Iosb.Status = STATUS_SUCCESS;
Iosb.Information = FILE_OPENED;
+
+
+ /* Increase counters */
+ Fcb->UncleanCount++;
+ Fcb->OpenCount++;
+ if (FlagOn(FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING))
Fcb->NonCachedUncleanCount++;
+ if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++;
return Iosb;
}
@@ -397,7 +415,7 @@
// and opened handles count is not 0
//if (!FlagOn(ShareAccess, FILE_SHARE_READ)
- DPRINT1("Exclusive voume open\n");
+ DPRINT1("Exclusive volume open\n");
// TODO: Flush the volume
VolumeFlushed = TRUE;
@@ -450,6 +468,7 @@
/* Increase direct open count */
Vcb->DirectOpenCount++;
Vcb->OpenFileCount++;
+ if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++;
/* Set no buffering flag */
FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
@@ -720,7 +739,7 @@
/* Set parent DCB */
ParentDcb = RelatedDcb;
- DPRINT1("Opening file '%wZ' relatively to '%wZ'\n",
&FileName, &ParentDcb->FullFileName);
+ DPRINT("Opening file '%wZ' relatively to '%wZ'\n",
&FileName, &ParentDcb->FullFileName);
}
else
{
@@ -1137,6 +1156,12 @@
DeleteOnClose,
OpenedAsDos);
+ /* In case of success set cache supported flag */
+ if (NT_SUCCESS(Iosb.Status) && !NoIntermediateBuffering)
+ {
+ SetFlag(FileObject->Flags, FO_CACHE_SUPPORTED);
+ }
+
Irp->IoStatus.Information = Iosb.Information;
/* Unlock VCB */
Modified: trunk/reactos/drivers/filesystems/fastfat_new/dir.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/dir.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/dir.c [iso-8859-1] Sun Aug 8 10:43:28
2010
@@ -81,9 +81,6 @@
/* Initialize advanced FCB header fields */
ExInitializeFastMutex(&Dcb->HeaderMutex);
FsRtlSetupAdvancedHeader(&Dcb->Header, &Dcb->HeaderMutex);
-
- /* Initialize MCB */
- FsRtlInitializeLargeMcb(&Dcb->Mcb, NonPagedPool);
/* Set up first cluster field depending on FAT type */
if (TRUE/*FatIsFat32(Vcb)*/)
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c [iso-8859-1] Sun Aug 8
10:43:28 2010
@@ -42,6 +42,7 @@
RtlZeroMemory(&FatGlobalData, sizeof(FAT_GLOBAL_DATA));
FatGlobalData.DriverObject = DriverObject;
FatGlobalData.DiskDeviceObject = DeviceObject;
+ FatGlobalData.SystemProcess = PsGetCurrentProcess();
/* Fill major function handlers */
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FatClose;
@@ -317,7 +318,7 @@
TypeOfOpen = (*Ccb == NULL ? DirectoryFile : UserDirectoryOpen);
- DPRINT1("Referencing a directory: %wZ\n",
&(*FcbOrDcb)->FullFileName);
+ DPRINT("Referencing a directory: %wZ\n",
&(*FcbOrDcb)->FullFileName);
break;
/* File */
@@ -510,4 +511,17 @@
return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
}
+BOOLEAN
+NTAPI
+FatIsTopLevelIrp(IN PIRP Irp)
+{
+ if (!IoGetTopLevelIrp())
+ {
+ IoSetTopLevelIrp(Irp);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
/* EOF */
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h [iso-8859-1] Sun Aug 8
10:43:28 2010
@@ -36,6 +36,22 @@
ExReleaseResourceLite(&(FatGlobalData.Resource)); \
}
+#define FatIsFastIoPossible(FCB) ((BOOLEAN)
\
+ (((FCB)->Condition != FcbGood ||
!FsRtlOplockIsFastIoPossible(&(FCB)->Fcb.Oplock)) ? \
+ FastIoIsNotPossible
\
+ :
\
+ (!FsRtlAreThereCurrentFileLocks(&(FCB)->Fcb.Lock) &&
\
+ ((FCB)->OutstandingAsyncWrites == 0) &&
\
+ !FlagOn((FCB)->Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED) ?
\
+ FastIoIsPossible
\
+ :
\
+ FastIoIsQuestionable
\
+ )
\
+ )
\
+)
+
+#define IsFileObjectReadOnly(FO) (!((FO)->WriteAccess | (FO)->DeleteAccess))
+
NTSYSAPI
NTSTATUS
NTAPI
@@ -66,6 +82,12 @@
ULONG ByteSize,
PBCB *Bcb,
PVOID *Buffer);
+
+BOOLEAN
+NTAPI
+FatCheckForDismount(IN PFAT_IRP_CONTEXT IrpContext,
+ PVCB Vcb,
+ IN BOOLEAN Force);
/* ----------------------------------------------------------- dir.c */
@@ -205,6 +227,9 @@
PVOID FASTCALL
FatMapUserBuffer(PIRP Irp);
+BOOLEAN NTAPI
+FatIsTopLevelIrp(IN PIRP Irp);
+
/* --------------------------------------------------------- fullfat.c */
FF_T_SINT32
@@ -283,6 +308,10 @@
IN PVCB Vcb,
IN PFCB ParentDcb,
IN FF_FILE *FileHandle);
+
+VOID NTAPI
+FatDeleteFcb(IN PFAT_IRP_CONTEXT IrpContext,
+ IN PFCB Fcb);
IO_STATUS_BLOCK NTAPI
FatiOpenExistingFcb(IN PFAT_IRP_CONTEXT IrpContext,
@@ -320,6 +349,10 @@
FatCreateCcb();
VOID NTAPI
+FatDeleteCcb(IN PFAT_IRP_CONTEXT IrpContext,
+ IN PCCB Ccb);
+
+VOID NTAPI
FatSetFullNameInFcb(PFCB Fcb,
PUNICODE_STRING Name);
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fat.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fat.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fat.c [iso-8859-1] Sun Aug 8 10:43:28
2010
@@ -201,6 +201,10 @@
goto FatInitializeVcbCleanup;
}
+ /* Increase internal / residual open counter */
+ InterlockedIncrement((PLONG)&(Vcb->InternalOpenCount));
+ InterlockedIncrement((PLONG)&(Vcb->ResidualOpenCount));
+
/* Set up notifications */
FsRtlNotifyInitializeSync(&Vcb->NotifySync);
InitializeListHead(&Vcb->NotifyList);
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fatstruc.h [iso-8859-1] Sun Aug 8
10:43:28 2010
@@ -14,15 +14,17 @@
#define FatNodeType(Ptr) (*((PFAT_NODE_TYPE)(Ptr)))
/* Node type codes */
-#define FAT_NTC_VCB (CSHORT) '00VF'
-#define FAT_NTC_FCB (CSHORT) 'CF'
-#define FAT_NTC_DCB (CSHORT) 'DF'
-#define FAT_NTC_ROOT_DCB (CSHORT) 'RFD'
-#define FAT_NTC_CCB (CSHORT) 'BCC'
+#define FAT_NTC_VCB (CSHORT) '00VF'
+#define FAT_NTC_FCB (CSHORT) 'CF'
+#define FAT_NTC_DCB (CSHORT) 'DF'
+#define FAT_NTC_ROOT_DCB (CSHORT) 'RFD'
+#define FAT_NTC_CCB (CSHORT) 'BCC'
+#define FAT_NTC_IRP_CONTEXT (CSHORT) 'PRI'
typedef struct _FAT_GLOBAL_DATA
{
ERESOURCE Resource;
+ PEPROCESS SystemProcess;
PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT DiskDeviceObject;
LIST_ENTRY VcbListHead;
@@ -33,6 +35,7 @@
CACHE_MANAGER_CALLBACKS CacheMgrCallbacks;
CACHE_MANAGER_CALLBACKS CacheMgrNoopCallbacks;
BOOLEAN Win31FileSystem;
+ BOOLEAN ShutdownStarted;
/* Jan 1, 1980 System Time */
LARGE_INTEGER DefaultFileTime;
@@ -82,6 +85,10 @@
typedef struct _FAT_IRP_CONTEXT
{
+ /* Type and size of this record (must be FAT_NTC_IRP_CONTEXT) */
+ FAT_NODE_TYPE NodeTypeCode;
+ CSHORT NodeByteSize;
+
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
UCHAR MajorFunction;
@@ -132,10 +139,15 @@
PFAT_SETFAT_VALUE_RUN_ROUTINE SetValueRun;
} FAT_METHODS, *PFAT_METHODS;
-#define VCB_STATE_FLAG_LOCKED 0x01
-#define VCB_STATE_FLAG_DIRTY 0x02
-#define VCB_STATE_MOUNTED_DIRTY 0x04
-#define VCB_STATE_CREATE_IN_PROGRESS 0x08
+#define VCB_STATE_FLAG_LOCKED 0x001
+#define VCB_STATE_FLAG_DIRTY 0x002
+#define VCB_STATE_MOUNTED_DIRTY 0x004
+#define VCB_STATE_CREATE_IN_PROGRESS 0x008
+#define VCB_STATE_FLAG_CLOSE_IN_PROGRESS 0x010
+#define VCB_STATE_FLAG_DELETED_FCB 0x020
+#define VCB_STATE_FLAG_DISMOUNT_IN_PROGRESS 0x040
+#define VCB_STATE_FLAG_DEFERRED_FLUSH 0x080
+#define VCB_STATE_FLAG_WRITE_PROTECTED 0x100
typedef enum _VCB_CONDITION
{
@@ -158,10 +170,11 @@
ULONG State;
VCB_CONDITION Condition;
ERESOURCE Resource;
+ struct _CLOSE_CONTEXT *CloseContext;
/* Direct volume access */
- ULONG DirectOpenCount;
SHARE_ACCESS ShareAccess;
+ PFILE_OBJECT FileObjectWithVcbLocked;
/* Notifications support */
PNOTIFY_SYNC NotifySync;
@@ -186,8 +199,13 @@
struct _FCB *RootDcb;
/* Counters */
+ ULONG DirectOpenCount;
+ ULONG OpenFileCount;
+ ULONG ReadOnlyCount;
+ ULONG InternalOpenCount;
+ ULONG ResidualOpenCount;
+ ULONG DirectAccessOpenCount;
ULONG MediaChangeCount;
- ULONG OpenFileCount;
/* FullFAT integration */
FF_IOMAN *Ioman;
@@ -252,6 +270,7 @@
#define FCB_STATE_PAGEFILE 0x04
#define FCB_STATE_DELAY_CLOSE 0x08
#define FCB_STATE_TRUNCATE_ON_CLOSE 0x10
+#define FCB_STATE_DELETE_ON_CLOSE 0x20
typedef struct _FCB
{
@@ -281,8 +300,6 @@
FCB_CONDITION Condition;
/* Share access */
SHARE_ACCESS ShareAccess;
- /* Mcb mapping Vbo->Lbo */
- LARGE_MCB Mcb;
ULONG FirstCluster;
/* Links into FCB Tree */
FCB_NAME_LINK ShortName;
@@ -307,6 +324,8 @@
PKEVENT OutstandingAsyncEvent;
/* Counters */
ULONG OpenCount;
+ ULONG UncleanCount;
+ ULONG NonCachedUncleanCount;
union
{
struct
@@ -318,10 +337,11 @@
struct
{
- /* A list of all FCBs/DCBs opened under this DCB */
- LIST_ENTRY ParentDcbList;
+ LIST_ENTRY ParentDcbList; /* A list of all FCBs/DCBs opened under this DCB
*/
+ ULONG DirectoryFileOpenCount; /* Sector-based access to the dir */
+ PFILE_OBJECT DirectoryFile;
/* Directory data stream (just handy to have it). */
- PFILE_OBJECT StreamFileObject;
+ //PFILE_OBJECT StreamFileObject;
/* Bitmap to search for free dirents. */
RTL_BITMAP FreeBitmap;
/* Names */
@@ -390,6 +410,17 @@
EaFile
} TYPE_OF_OPEN;
+typedef struct _CLOSE_CONTEXT
+{
+ LIST_ENTRY GlobalLinks;
+ LIST_ENTRY VcbLinks;
+
+ PVCB Vcb;
+ PFCB Fcb;
+ TYPE_OF_OPEN TypeOfOpen;
+ BOOLEAN Free;
+} CLOSE_CONTEXT, *PCLOSE_CONTEXT;
+
typedef enum _FILE_TIME_INDEX
{
FileCreationTime = 0,
@@ -402,4 +433,8 @@
#define CCB_SEARCH_PATTERN_LEGAL_8DOT3 0x02
#define CCB_SEARCH_PATTERN_HAS_WILD_CARD 0x04
#define CCB_DASD_IO 0x10
+#define CCB_READ_ONLY 0x20
+#define CCB_DELETE_ON_CLOSE 0x40
+#define CCB_COMPLETE_DISMOUNT 0x80
+
extern FAT_GLOBAL_DATA FatGlobalData;
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fcb.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/fcb.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/fcb.c [iso-8859-1] Sun Aug 8 10:43:28
2010
@@ -149,10 +149,72 @@
Fcb->Header.ValidDataLength.LowPart = FileHandle->Filesize;
Fcb->FatHandle = FileHandle;
+ /* Initialize locks */
+ FsRtlInitializeFileLock(&Fcb->Fcb.Lock, NULL, NULL);
+ FsRtlInitializeOplock(&Fcb->Fcb.Oplock);
+
/* Set names */
FatSetFcbNames(IrpContext, Fcb);
return Fcb;
+}
+
+VOID
+NTAPI
+FatDeleteFcb(IN PFAT_IRP_CONTEXT IrpContext,
+ IN PFCB Fcb)
+{
+ DPRINT("FatDeleteFcb %p\n", Fcb);
+
+ if (Fcb->OpenCount != 0)
+ {
+ DPRINT1("Trying to delete FCB with OpenCount %d\n",
Fcb->OpenCount);
+ ASSERT(FALSE);
+ }
+
+ if ((Fcb->Header.NodeTypeCode == FAT_NTC_DCB) ||
+ (Fcb->Header.NodeTypeCode == FAT_NTC_ROOT_DCB))
+ {
+ /* Make sure it's a valid deletion */
+ ASSERT(Fcb->Dcb.DirectoryFileOpenCount == 0);
+ ASSERT(IsListEmpty(&Fcb->Dcb.ParentDcbList));
+ ASSERT(Fcb->Dcb.DirectoryFile == NULL);
+ }
+ else
+ {
+ /* Free locks */
+ FsRtlUninitializeFileLock(&Fcb->Fcb.Lock);
+ FsRtlUninitializeOplock(&Fcb->Fcb.Oplock);
+ }
+
+ /* Release any possible filter contexts */
+ FsRtlTeardownPerStreamContexts(&Fcb->Header);
+
+ /* Remove from parents queue */
+ if (Fcb->Header.NodeTypeCode != FAT_NTC_ROOT_DCB)
+ {
+ RemoveEntryList(&(Fcb->ParentDcbLinks));
+ }
+
+ /* Free FullFAT handle */
+ if (Fcb->FatHandle) FF_Close(Fcb->FatHandle);
+
+ /* Remove from the splay table */
+ if (FlagOn(Fcb->State, FCB_STATE_HAS_NAMES))
+ FatRemoveNames(IrpContext, Fcb);
+
+ /* Free file name buffers */
+ if (Fcb->Header.NodeTypeCode != FAT_NTC_ROOT_DCB)
+ {
+ if (Fcb->FullFileName.Buffer)
+ ExFreePool(Fcb->FullFileName.Buffer);
+ }
+
+ if (Fcb->ExactCaseLongName.Buffer)
+ ExFreePool(Fcb->ExactCaseLongName.Buffer);
+
+ /* Free this FCB, finally */
+ ExFreePool(Fcb);
}
PCCB
@@ -170,6 +232,17 @@
Ccb->NodeByteSize = sizeof(CCB);
return Ccb;
+}
+
+VOID
+NTAPI
+FatDeleteCcb(IN PFAT_IRP_CONTEXT IrpContext,
+ IN PCCB Ccb)
+{
+ // TODO: Deallocate CCB strings, if any
+
+ /* Free the CCB */
+ ExFreePool(Ccb);
}
IO_STATUS_BLOCK
@@ -443,8 +516,11 @@
ClearFlag(Fcb->State, FCB_STATE_DELAY_CLOSE);
/* Increase counters */
+ Fcb->UncleanCount++;
Fcb->OpenCount++;
Vcb->OpenFileCount++;
+ if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++;
+ if (FlagOn(FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING))
Fcb->NonCachedUncleanCount++;
// TODO: Handle DeleteOnClose and OpenedAsDos by storing those flags in CCB
}
Modified: trunk/reactos/drivers/filesystems/fastfat_new/volume.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat_new/volume.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat_new/volume.c [iso-8859-1] Sun Aug 8
10:43:28 2010
@@ -8,7 +8,7 @@
/* INCLUDES *****************************************************************/
-//#define NDEBUG
+#define NDEBUG
#include "fastfat.h"
/* FUNCTIONS ****************************************************************/
@@ -77,8 +77,8 @@
Buffer->SectorsPerAllocationUnit = Vcb->Bpb.SectorsPerCluster;
Buffer->BytesPerSector = Vcb->Bpb.BytesPerSector;
- DPRINT1("Total %d, free %d, SPC %d, BPS %d\n",
Partition->FreeClusterCount,
- Partition->NumClusters, Vcb->Bpb.SectorsPerCluster,
Vcb->Bpb.BytesPerSector);
+ DPRINT1("Total %d, free %d, SPC %d, BPS %d\n", Partition->NumClusters,
+ Partition->FreeClusterCount, Vcb->Bpb.SectorsPerCluster,
Vcb->Bpb.BytesPerSector);
return Status;
}
@@ -228,4 +228,14 @@
}
}
+BOOLEAN
+NTAPI
+FatCheckForDismount(IN PFAT_IRP_CONTEXT IrpContext,
+ PVCB Vcb,
+ IN BOOLEAN Force)
+{
+ /* We never allow deletion of a volume for now */
+ return FALSE;
+}
+
/* EOF */