/*++ Copyright (c) 2000-2001 Microsoft Corporation Module Name: close.c Abstract: This module implements routines related to handling IRP_MJ_CLOSE. --*/ #include "fatx.h" NTSTATUS FatxFsdClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: This routine is called by the I/O manager to handle IRP_MJ_CLOSE requests. Arguments: DeviceObject - Specifies the device object that the I/O request is for. Irp - Specifies the packet that describes the I/O request. Return Value: Status of operation. --*/ { PFAT_VOLUME_EXTENSION VolumeExtension; PFILE_OBJECT FileObject; PDIRECTORY_ENUM_CONTEXT DirectoryEnumContext; PFAT_FCB Fcb; VolumeExtension = (PFAT_VOLUME_EXTENSION)DeviceObject->DeviceExtension; // // Always grab the exclusive lock because we could end up writing to the // disk and we also use this lock to guard access to the file control block // and file control block list. // FatxAcquireVolumeMutexExclusive(VolumeExtension); FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject; // // Delete the directory enumeration context if one exists. // DirectoryEnumContext = (PDIRECTORY_ENUM_CONTEXT)FileObject->FsContext2; if (DirectoryEnumContext != NULL) { FileObject->FsContext2 = NULL; ExFreePool(DirectoryEnumContext); } // // Dereference the file control block associated with the file object. // Fcb = (PFAT_FCB)FileObject->FsContext; FileObject->FsContext = NULL; FatxDereferenceFcb(Fcb); // // Decrement the file object count for the volume and check if we're ready // to delete this device object. // VolumeExtension->FileObjectCount--; if ((VolumeExtension->FileObjectCount == 0) && FatxIsFlagSet(VolumeExtension->Flags, FAT_VOLUME_DISMOUNTED)) { FatxReleaseVolumeMutex(VolumeExtension); FatxDeleteVolumeDevice(DeviceObject); } else { FatxReleaseVolumeMutex(VolumeExtension); } Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }