1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * FILE: drivers/fs/vfat/cleanup.c 5 * PURPOSE: VFAT Filesystem 6 * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com) 7 */ 8 9 /* INCLUDES *****************************************************************/ 10 11 #include "vfat.h" 12 13 #define NDEBUG 14 #include <debug.h> 15 16 /* FUNCTIONS ****************************************************************/ 17 18 /* 19 * FUNCTION: Cleans up after a file has been closed. 20 */ 21 static 22 NTSTATUS 23 VfatCleanupFile( 24 PVFAT_IRP_CONTEXT IrpContext) 25 { 26 PVFATFCB pFcb; 27 PVFATCCB pCcb; 28 BOOLEAN IsVolume; 29 PDEVICE_EXTENSION DeviceExt = IrpContext->DeviceExt; 30 PFILE_OBJECT FileObject = IrpContext->FileObject; 31 32 DPRINT("VfatCleanupFile(DeviceExt %p, FileObject %p)\n", 33 IrpContext->DeviceExt, FileObject); 34 35 /* FIXME: handle file/directory deletion here */ 36 pFcb = (PVFATFCB)FileObject->FsContext; 37 if (!pFcb) 38 return STATUS_SUCCESS; 39 40 IsVolume = BooleanFlagOn(pFcb->Flags, FCB_IS_VOLUME); 41 if (IsVolume) 42 { 43 pFcb->OpenHandleCount--; 44 DeviceExt->OpenHandleCount--; 45 46 if (pFcb->OpenHandleCount != 0) 47 { 48 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess); 49 } 50 } 51 else 52 { 53 if(!ExAcquireResourceExclusiveLite(&pFcb->MainResource, 54 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))) 55 { 56 return STATUS_PENDING; 57 } 58 if(!ExAcquireResourceExclusiveLite(&pFcb->PagingIoResource, 59 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))) 60 { 61 ExReleaseResourceLite(&pFcb->MainResource); 62 return STATUS_PENDING; 63 } 64 65 pCcb = FileObject->FsContext2; 66 if (BooleanFlagOn(pCcb->Flags, CCB_DELETE_ON_CLOSE)) 67 { 68 pFcb->Flags |= FCB_DELETE_PENDING; 69 } 70 71 /* Notify about the cleanup */ 72 FsRtlNotifyCleanup(IrpContext->DeviceExt->NotifySync, 73 &(IrpContext->DeviceExt->NotifyList), 74 FileObject->FsContext2); 75 76 pFcb->OpenHandleCount--; 77 DeviceExt->OpenHandleCount--; 78 79 if (!vfatFCBIsDirectory(pFcb) && 80 FsRtlAreThereCurrentFileLocks(&pFcb->FileLock)) 81 { 82 /* remove all locks this process have on this file */ 83 FsRtlFastUnlockAll(&pFcb->FileLock, 84 FileObject, 85 IoGetRequestorProcess(IrpContext->Irp), 86 NULL); 87 } 88 89 if (BooleanFlagOn(pFcb->Flags, FCB_IS_DIRTY)) 90 { 91 VfatUpdateEntry (pFcb, vfatVolumeIsFatX(DeviceExt)); 92 } 93 94 if (BooleanFlagOn(pFcb->Flags, FCB_DELETE_PENDING) && 95 pFcb->OpenHandleCount == 0) 96 { 97 if (vfatFCBIsDirectory(pFcb) && 98 !VfatIsDirectoryEmpty(DeviceExt, pFcb)) 99 { 100 pFcb->Flags &= ~FCB_DELETE_PENDING; 101 } 102 else 103 { 104 PFILE_OBJECT tmpFileObject; 105 tmpFileObject = pFcb->FileObject; 106 if (tmpFileObject != NULL) 107 { 108 pFcb->FileObject = NULL; 109 CcUninitializeCacheMap(tmpFileObject, NULL, NULL); 110 ObDereferenceObject(tmpFileObject); 111 } 112 113 pFcb->RFCB.ValidDataLength.QuadPart = 0; 114 pFcb->RFCB.FileSize.QuadPart = 0; 115 pFcb->RFCB.AllocationSize.QuadPart = 0; 116 } 117 } 118 119 /* Uninitialize the cache (should be done even if caching was never initialized) */ 120 CcUninitializeCacheMap(FileObject, &pFcb->RFCB.FileSize, NULL); 121 122 if (BooleanFlagOn(pFcb->Flags, FCB_DELETE_PENDING) && 123 pFcb->OpenHandleCount == 0) 124 { 125 VfatDelEntry(DeviceExt, pFcb, NULL); 126 127 vfatReportChange(DeviceExt, 128 pFcb, 129 (vfatFCBIsDirectory(pFcb) ? 130 FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME), 131 FILE_ACTION_REMOVED); 132 } 133 134 if (pFcb->OpenHandleCount != 0) 135 { 136 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess); 137 } 138 139 FileObject->Flags |= FO_CLEANUP_COMPLETE; 140 141 ExReleaseResourceLite(&pFcb->PagingIoResource); 142 ExReleaseResourceLite(&pFcb->MainResource); 143 } 144 145 #ifdef ENABLE_SWAPOUT 146 if (IsVolume && BooleanFlagOn(DeviceExt->Flags, VCB_DISMOUNT_PENDING)) 147 { 148 VfatCheckForDismount(DeviceExt, FALSE); 149 } 150 #endif 151 152 return STATUS_SUCCESS; 153 } 154 155 /* 156 * FUNCTION: Cleans up after a file has been closed. 157 */ 158 NTSTATUS 159 VfatCleanup( 160 PVFAT_IRP_CONTEXT IrpContext) 161 { 162 NTSTATUS Status; 163 164 DPRINT("VfatCleanup(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp); 165 166 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject) 167 { 168 IrpContext->Irp->IoStatus.Information = 0; 169 return STATUS_SUCCESS; 170 } 171 172 if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, 173 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))) 174 { 175 return VfatMarkIrpContextForQueue(IrpContext); 176 } 177 178 Status = VfatCleanupFile(IrpContext); 179 180 ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource); 181 182 if (Status == STATUS_PENDING) 183 { 184 return VfatMarkIrpContextForQueue(IrpContext); 185 } 186 187 IrpContext->Irp->IoStatus.Information = 0; 188 return Status; 189 } 190 191 /* EOF */ 192