Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencleanup.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS FAT file system driver 00003 * LICENSE: GNU GPLv3 as published by the Free Software Foundation 00004 * FILE: drivers/filesystems/fastfat/cleanup.c 00005 * PURPOSE: Cleanup routines 00006 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) 00007 */ 00008 00009 /* INCLUDES *****************************************************************/ 00010 00011 #define NDEBUG 00012 #include "fastfat.h" 00013 00014 /* FUNCTIONS ****************************************************************/ 00015 00016 /* Last handle to a file object is closed */ 00017 NTSTATUS 00018 NTAPI 00019 FatiCleanup(PFAT_IRP_CONTEXT IrpContext, PIRP Irp) 00020 { 00021 PIO_STACK_LOCATION IrpSp; 00022 PFILE_OBJECT FileObject; 00023 TYPE_OF_OPEN TypeOfOpen; 00024 PSHARE_ACCESS ShareAccess; 00025 BOOLEAN SendUnlockNotification = FALSE; 00026 PLARGE_INTEGER TruncateSize = NULL; 00027 //LARGE_INTEGER LocalTruncateSize; 00028 BOOLEAN AcquiredVcb = FALSE, AcquiredFcb = FALSE; 00029 NTSTATUS Status; 00030 PVCB Vcb; 00031 PFCB Fcb; 00032 PCCB Ccb; 00033 00034 IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00035 00036 DPRINT("FatiCleanup\n"); 00037 DPRINT("\tIrp = %p\n", Irp); 00038 DPRINT("\t->FileObject = %p\n", IrpSp->FileObject); 00039 00040 FileObject = IrpSp->FileObject; 00041 TypeOfOpen = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb); 00042 00043 if (TypeOfOpen == UnopenedFileObject) 00044 { 00045 DPRINT1("Unopened File Object\n"); 00046 00047 FatCompleteRequest(IrpContext, Irp, STATUS_SUCCESS); 00048 return STATUS_SUCCESS; 00049 } 00050 00051 if (FlagOn( FileObject->Flags, FO_CLEANUP_COMPLETE )) 00052 { 00053 /* Just flush the file */ 00054 00055 if (FlagOn(Vcb->State, VCB_STATE_FLAG_DEFERRED_FLUSH) && 00056 FlagOn(FileObject->Flags, FO_FILE_MODIFIED) && 00057 !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED) && 00058 (TypeOfOpen == UserFileOpen)) 00059 { 00060 //Status = FatFlushFile(IrpContext, Fcb, Flush); 00061 //if (!NT_SUCCESS(Status)) FatNormalizeAndRaiseStatus(IrpContext, Status); 00062 UNIMPLEMENTED; 00063 } 00064 00065 FatCompleteRequest(IrpContext, Irp, STATUS_SUCCESS); 00066 return STATUS_SUCCESS; 00067 } 00068 00069 if (TypeOfOpen == UserFileOpen || 00070 TypeOfOpen == UserDirectoryOpen) 00071 { 00072 ASSERT(Fcb != NULL); 00073 00074 (VOID)FatAcquireExclusiveFcb(IrpContext, Fcb); 00075 00076 AcquiredFcb = TRUE; 00077 00078 /* Set FCB flags according to DELETE_ON_CLOSE */ 00079 if (FlagOn(Ccb->Flags, CCB_DELETE_ON_CLOSE)) 00080 { 00081 ASSERT(FatNodeType(Fcb) != FAT_NTC_ROOT_DCB); 00082 00083 SetFlag(Fcb->State, FCB_STATE_DELETE_ON_CLOSE); 00084 00085 /* Issue a notification */ 00086 if (TypeOfOpen == UserDirectoryOpen) 00087 { 00088 FsRtlNotifyFullChangeDirectory(Vcb->NotifySync, 00089 &Vcb->NotifyList, 00090 FileObject->FsContext, 00091 NULL, 00092 FALSE, 00093 FALSE, 00094 0, 00095 NULL, 00096 NULL, 00097 NULL); 00098 } 00099 } 00100 00101 /* If file should be deleted, acquire locks */ 00102 if ((Fcb->UncleanCount == 1) && 00103 FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) && 00104 (Fcb->Condition != FcbBad) && 00105 !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED)) 00106 { 00107 FatReleaseFcb(IrpContext, Fcb); 00108 AcquiredFcb = FALSE; 00109 00110 (VOID)FatAcquireExclusiveVcb(IrpContext, Vcb); 00111 AcquiredVcb = TRUE; 00112 00113 (VOID)FatAcquireExclusiveFcb(IrpContext, Fcb); 00114 AcquiredFcb = TRUE; 00115 } 00116 } 00117 00118 /* Acquire VCB lock if it was a volume open */ 00119 if (TypeOfOpen == UserVolumeOpen) 00120 { 00121 (VOID)FatAcquireExclusiveVcb(IrpContext, Vcb); 00122 AcquiredVcb = TRUE; 00123 } 00124 00125 /* Cleanup all notifications */ 00126 if (TypeOfOpen == UserDirectoryOpen) 00127 { 00128 FsRtlNotifyCleanup(Vcb->NotifySync, 00129 &Vcb->NotifyList, 00130 Ccb); 00131 } 00132 00133 if (Fcb) 00134 { 00135 //TODO: FatVerifyFcb 00136 } 00137 00138 switch (TypeOfOpen) 00139 { 00140 case DirectoryFile: 00141 case VirtualVolumeFile: 00142 DPRINT1("Cleanup VirtualVolumeFile/DirectoryFile\n"); 00143 ShareAccess = NULL; 00144 break; 00145 00146 case UserVolumeOpen: 00147 DPRINT("Cleanup UserVolumeOpen\n"); 00148 00149 if (FlagOn(Ccb->Flags, CCB_COMPLETE_DISMOUNT)) 00150 { 00151 FatCheckForDismount( IrpContext, Vcb, TRUE ); 00152 } else if (FileObject->WriteAccess && 00153 FlagOn(FileObject->Flags, FO_FILE_MODIFIED)) 00154 { 00155 UNIMPLEMENTED; 00156 } 00157 00158 /* Release the volume and send notification */ 00159 if (FlagOn(Vcb->State, VCB_STATE_FLAG_LOCKED) && 00160 (Vcb->FileObjectWithVcbLocked == FileObject)) 00161 { 00162 UNIMPLEMENTED; 00163 SendUnlockNotification = TRUE; 00164 } 00165 00166 ShareAccess = &Vcb->ShareAccess; 00167 break; 00168 00169 case EaFile: 00170 DPRINT1("Cleanup EaFileObject\n"); 00171 ShareAccess = NULL; 00172 break; 00173 00174 case UserDirectoryOpen: 00175 DPRINT("Cleanup UserDirectoryOpen\n"); 00176 00177 ShareAccess = &Fcb->ShareAccess; 00178 00179 /* Should it be a delayed close? */ 00180 if ((Fcb->UncleanCount == 1) && 00181 (Fcb->OpenCount == 1) && 00182 (Fcb->Dcb.DirectoryFileOpenCount == 0) && 00183 !FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) && 00184 Fcb->Condition == FcbGood) 00185 { 00186 /* Yes, a delayed one */ 00187 SetFlag(Fcb->State, FCB_STATE_DELAY_CLOSE); 00188 } 00189 00190 if (VcbGood == Vcb->Condition) 00191 { 00192 //FatUpdateDirentFromFcb( IrpContext, FileObject, Fcb, Ccb ); 00193 //TODO: Actually update dirent 00194 } 00195 00196 if ((Fcb->UncleanCount == 1) && 00197 (FatNodeType(Fcb) == FAT_NTC_DCB) && 00198 (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE)) && 00199 (Fcb->Condition != FcbBad) && 00200 !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED)) 00201 { 00202 UNIMPLEMENTED; 00203 } 00204 00205 /* Decrement unclean counter */ 00206 ASSERT(Fcb->UncleanCount != 0); 00207 Fcb->UncleanCount--; 00208 break; 00209 00210 case UserFileOpen: 00211 DPRINT("Cleanup UserFileOpen\n"); 00212 00213 ShareAccess = &Fcb->ShareAccess; 00214 00215 /* Should it be a delayed close? */ 00216 if ((FileObject->SectionObjectPointer->DataSectionObject == NULL) && 00217 (FileObject->SectionObjectPointer->ImageSectionObject == NULL) && 00218 (Fcb->UncleanCount == 1) && 00219 (Fcb->OpenCount == 1) && 00220 !FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) && 00221 Fcb->Condition == FcbGood) 00222 { 00223 /* Yes, a delayed one */ 00224 //SetFlag(Fcb->State, FCB_STATE_DELAY_CLOSE); 00225 DPRINT1("Setting a delay on close for some reason for FCB %p, FF handle %p, file name '%wZ'\n", Fcb, Fcb->FatHandle, &Fcb->FullFileName); 00226 } 00227 00228 /* Unlock all file locks */ 00229 FsRtlFastUnlockAll(&Fcb->Fcb.Lock, 00230 FileObject, 00231 IoGetRequestorProcess(Irp), 00232 NULL); 00233 00234 if (Vcb->Condition == VcbGood) 00235 { 00236 if (Fcb->Condition != FcbBad) 00237 { 00238 //FatUpdateDirentFromFcb( IrpContext, FileObject, Fcb, Ccb ); 00239 // TODO: Update on-disk structures 00240 } 00241 00242 if (Fcb->UncleanCount == 1 && 00243 Fcb->Condition != FcbBad) 00244 { 00245 //DELETE_CONTEXT DeleteContext; 00246 00247 /* Should this file be deleted on close? */ 00248 if (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) && 00249 !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED)) 00250 { 00251 UNIMPLEMENTED; 00252 } 00253 else 00254 { 00255 if (!FlagOn(Fcb->State, FCB_STATE_PAGEFILE) && 00256 (Fcb->Header.ValidDataLength.LowPart < Fcb->Header.FileSize.LowPart)) 00257 { 00258 #if 0 00259 ULONG ValidDataLength; 00260 00261 ValidDataLength = Fcb->Header.ValidDataLength.LowPart; 00262 00263 if (ValidDataLength < Fcb->ValidDataToDisk) { 00264 ValidDataLength = Fcb->ValidDataToDisk; 00265 } 00266 00267 if (ValidDataLength < Fcb->Header.FileSize.LowPart) 00268 { 00269 FatZeroData( IrpContext, 00270 Vcb, 00271 FileObject, 00272 ValidDataLength, 00273 Fcb->Header.FileSize.LowPart - 00274 ValidDataLength ); 00275 00276 Fcb->ValidDataToDisk = 00277 Fcb->Header.ValidDataLength.LowPart = 00278 Fcb->Header.FileSize.LowPart; 00279 00280 if (CcIsFileCached(FileObject)) 00281 { 00282 CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize); 00283 } 00284 } 00285 #endif 00286 DPRINT1("Zeroing out data is not implemented\n"); 00287 } 00288 } 00289 00290 /* Should the file be truncated on close? */ 00291 if (FlagOn(Fcb->State, FCB_STATE_TRUNCATE_ON_CLOSE)) 00292 { 00293 if (Vcb->Condition == VcbGood) 00294 { 00295 // TODO: Actually truncate the file allocation 00296 UNIMPLEMENTED; 00297 } 00298 00299 /* Remove truncation flag */ 00300 Fcb->State &= ~FCB_STATE_TRUNCATE_ON_CLOSE; 00301 } 00302 00303 /* Check again if it should be deleted */ 00304 if (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE) && 00305 Fcb->Header.AllocationSize.LowPart == 0) 00306 { 00307 FatNotifyReportChange(IrpContext, 00308 Vcb, 00309 Fcb, 00310 FILE_NOTIFY_CHANGE_FILE_NAME, 00311 FILE_ACTION_REMOVED); 00312 } 00313 00314 /* Remove the entry from the splay table if the file was deleted */ 00315 if (FlagOn(Fcb->State, FCB_STATE_DELETE_ON_CLOSE)) 00316 { 00317 FatRemoveNames(IrpContext, Fcb); 00318 } 00319 } 00320 } 00321 00322 ASSERT(Fcb->UncleanCount != 0); 00323 Fcb->UncleanCount--; 00324 if (!FlagOn(FileObject->Flags, FO_CACHE_SUPPORTED)) 00325 { 00326 ASSERT(Fcb->NonCachedUncleanCount != 0); 00327 Fcb->NonCachedUncleanCount--; 00328 } 00329 00330 if (FlagOn(FileObject->Flags, FO_CACHE_SUPPORTED) && 00331 (Fcb->NonCachedUncleanCount != 0) && 00332 (Fcb->NonCachedUncleanCount == Fcb->UncleanCount) && 00333 (Fcb->SectionObjectPointers.DataSectionObject != NULL)) 00334 { 00335 CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, NULL); 00336 00337 /* Acquire and release PagingIo to get in sync with lazy writer */ 00338 ExAcquireResourceExclusiveLite(Fcb->Header.PagingIoResource, TRUE); 00339 ExReleaseResourceLite(Fcb->Header.PagingIoResource); 00340 00341 CcPurgeCacheSection(&Fcb->SectionObjectPointers, 00342 NULL, 00343 0, 00344 FALSE); 00345 } 00346 00347 if (Fcb->Condition == FcbBad) 00348 { 00349 //TruncateSize = &FatLargeZero; 00350 UNIMPLEMENTED; 00351 } 00352 00353 /* Cleanup the cache map */ 00354 CcUninitializeCacheMap(FileObject, TruncateSize, NULL); 00355 break; 00356 00357 default: 00358 KeBugCheckEx(FAT_FILE_SYSTEM, __LINE__, (ULONG_PTR)TypeOfOpen, 0, 0); 00359 } 00360 00361 /* Cleanup the share access */ 00362 00363 if (ShareAccess) 00364 { 00365 DPRINT("Cleaning up the share access\n"); 00366 IoRemoveShareAccess(FileObject, ShareAccess); 00367 } 00368 00369 if (TypeOfOpen == UserFileOpen) 00370 { 00371 /* Update oplocks */ 00372 FsRtlCheckOplock(&Fcb->Fcb.Oplock, 00373 Irp, 00374 IrpContext, 00375 NULL, 00376 NULL); 00377 00378 Fcb->Header.IsFastIoPossible = FatIsFastIoPossible(Fcb); 00379 } 00380 00381 /* Set the FO_CLEANUP_COMPLETE flag */ 00382 SetFlag(FileObject->Flags, FO_CLEANUP_COMPLETE); 00383 00384 Status = STATUS_SUCCESS; 00385 00386 // TODO: Unpin repinned BCBs 00387 //FatUnpinRepinnedBcbs(IrpContext); 00388 00389 /* Flush the volume if necessary */ 00390 if (FlagOn(Vcb->State, VCB_STATE_FLAG_DEFERRED_FLUSH) && 00391 !FlagOn(Vcb->State, VCB_STATE_FLAG_WRITE_PROTECTED)) 00392 { 00393 UNIMPLEMENTED; 00394 } 00395 00396 /* Cleanup */ 00397 if (AcquiredFcb) FatReleaseFcb(IrpContext, Fcb); 00398 if (AcquiredVcb) FatReleaseVcb(IrpContext, Vcb); 00399 00400 /* Send volume notification */ 00401 if (SendUnlockNotification) 00402 FsRtlNotifyVolumeEvent(FileObject, FSRTL_VOLUME_UNLOCK); 00403 00404 return Status; 00405 } 00406 00407 NTSTATUS 00408 NTAPI 00409 FatCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp) 00410 { 00411 PFAT_IRP_CONTEXT IrpContext; 00412 NTSTATUS Status; 00413 00414 DPRINT("FatCleanup(DeviceObject %p, Irp %p)\n", DeviceObject, Irp); 00415 00416 /* FatCleanup works only with a volume device object */ 00417 if (DeviceObject == FatGlobalData.DiskDeviceObject) 00418 { 00419 /* Complete the request and return success */ 00420 Irp->IoStatus.Status = STATUS_SUCCESS; 00421 Irp->IoStatus.Information = FILE_OPENED; 00422 00423 IoCompleteRequest(Irp, IO_DISK_INCREMENT); 00424 00425 return STATUS_SUCCESS; 00426 } 00427 00428 /* Enter FsRtl critical region */ 00429 FsRtlEnterFileSystem(); 00430 00431 /* Build an irp context */ 00432 IrpContext = FatBuildIrpContext(Irp, TRUE); 00433 00434 /* Call internal function */ 00435 Status = FatiCleanup(IrpContext, Irp); 00436 00437 /* Leave FsRtl critical region */ 00438 FsRtlExitFileSystem(); 00439 00440 return Status; 00441 } 00442 00443 /* EOF */ Generated on Fri May 25 2012 04:19:21 for ReactOS by
1.7.6.1
|