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 FsRtlNotifyFullReportChange(DeviceExt->NotifySync, 128 &(DeviceExt->NotifyList), 129 (PSTRING)&pFcb->PathNameU, 130 pFcb->PathNameU.Length - pFcb->LongNameU.Length, 131 NULL, 132 NULL, 133 vfatFCBIsDirectory(pFcb) ? 134 FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME, 135 FILE_ACTION_REMOVED, 136 NULL); 137 } 138 139 if (pFcb->OpenHandleCount != 0) 140 { 141 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess); 142 } 143 144 FileObject->Flags |= FO_CLEANUP_COMPLETE; 145 146 ExReleaseResourceLite(&pFcb->PagingIoResource); 147 ExReleaseResourceLite(&pFcb->MainResource); 148 } 149 150 #ifdef ENABLE_SWAPOUT 151 if (IsVolume && BooleanFlagOn(DeviceExt->Flags, VCB_DISMOUNT_PENDING)) 152 { 153 VfatCheckForDismount(DeviceExt, FALSE); 154 } 155 #endif 156 157 return STATUS_SUCCESS; 158 } 159 160 /* 161 * FUNCTION: Cleans up after a file has been closed. 162 */ 163 NTSTATUS 164 VfatCleanup( 165 PVFAT_IRP_CONTEXT IrpContext) 166 { 167 NTSTATUS Status; 168 169 DPRINT("VfatCleanup(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp); 170 171 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject) 172 { 173 IrpContext->Irp->IoStatus.Information = 0; 174 return STATUS_SUCCESS; 175 } 176 177 if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, 178 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))) 179 { 180 return VfatMarkIrpContextForQueue(IrpContext); 181 } 182 183 Status = VfatCleanupFile(IrpContext); 184 185 ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource); 186 187 if (Status == STATUS_PENDING) 188 { 189 return VfatMarkIrpContextForQueue(IrpContext); 190 } 191 192 IrpContext->Irp->IoStatus.Information = 0; 193 return Status; 194 } 195 196 /* EOF */ 197