ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

cleanup.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.