00049                    :
00050 
00051     This 
is the common routine 
for cleanup of a 
file/directory called by both
00052     
the fsd and fsp threads.
00053 
00054     Cleanup 
is invoked whenever 
the last handle to a 
file object 
is closed.
00055     This 
is different than 
the Close operation which 
is invoked when 
the last
00056     reference to a 
file object 
is deleted.
00057 
00058     The function of cleanup 
is to essentially 
"cleanup" the file/directory
00059     after a user 
is done with 
it.  The Fcb/Dcb remains around (because MM
00060     still has the file object referenced) but 
is now available 
for another
00061     user to open (i.e., as far as the user is concerned the is now closed).
00062 
00063     See close 
for a more complete description of what close does.
00064 
00065     We 
do no synchronization in 
this routine until we get to 
the point
00066     where we modify 
the counts, share access and volume lock field.
00067 
00068     We need to update 
the Fcb and Vcb to show that a user handle has been closed.
00069     The following structures and fields are affected.
00070 
00071     Vcb:
00072 
00073         VolumeLockFileObject - Did 
the user lock 
the volume with 
this file object.
00074         VcbState - Check 
if we are unlocking 
the volume here.
00075         VcbCleanup - 
Count of outstanding handles on 
the volume.
00076         DirNotifyQueue - If 
this file object has pending DirNotify Irps.
00077 
00078     Fcb:
00079 
00080         ShareAccess - If 
this is a user handle.
00081         FcbCleanup - 
Count of outstanding handles on 
this Fcb.
00082         Oplock - Any outstanding oplocks on 
this file object.
00083         FileLock - Any outstanding filelocks on 
this file object.
00084 
00085 Arguments:
00086 
00087     
Irp - Supplies 
the Irp to process
00088 
00089 Return Value:
00090 
00091     
NTSTATUS - The 
return status 
for the operation.
00092 
00093 --*/
00094 
00095 {
00096     
PFILE_OBJECT FileObject;
00097     
TYPE_OF_OPEN TypeOfOpen;
00098 
00099     BOOLEAN SendUnlockNotification = 
FALSE;
00100     BOOLEAN AttemptTeardown;
00101 
00102     
PVCB Vcb;
00103     
PFCB Fcb;
00104     
PCCB Ccb;
00105 
00106     
PAGED_CODE();
00107 
00108     
ASSERT_IRP_CONTEXT( IrpContext );
00109     
ASSERT_IRP( Irp );
00110 
00111     
00112     
00113     
00114     
00115 
00116     
if (IrpContext->Vcb == 
NULL) {
00117 
00118         
UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
00119         
return STATUS_SUCCESS;
00120     }
00121 
00122     
00123     
00124     
00125 
00126     FileObject = 
IoGetCurrentIrpStackLocation( Irp )->FileObject;
00127 
00128     TypeOfOpen = 
UdfDecodeFileObject( FileObject,
00129                                       &Fcb,
00130                                       &Ccb );
00131 
00132     
00133     
00134     
00135 
00136     
if (TypeOfOpen <= 
StreamFileOpen) {
00137 
00138         
UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
00139 
00140         
return STATUS_SUCCESS;
00141     }
00142 
00143     
00144     
00145     
00146 
00147     Vcb = Fcb->
Vcb;
00148 
00149     
00150     
00151     
00152 
00153     
UdfAcquireFcbExclusive( IrpContext, Fcb, FALSE );
00154 
00155     
00156     
00157     
00158 
00159     
try {
00160 
00161         
00162         
00163         
00164 
00165         
SetFlag( FileObject->
Flags, FO_CLEANUP_COMPLETE );
00166 
00167         
00168         
00169         
00170 
00171         
switch (TypeOfOpen) {
00172 
00173         
case UserDirectoryOpen:
00174 
00175             
DebugTrace(( +1, Dbg,
00176                          
"UdfCommonCleanup, Fcb %08x FO %08x DIR\n",
00177                          Fcb,
00178                          FileObject ));
00179             
00180             
00181             
00182             
00183 
00184             
FsRtlNotifyCleanup( Vcb->
NotifySync,
00185                                 &Vcb->
DirNotifyList,
00186                                 Ccb );
00187 
00188             
break;
00189 
00190         
case UserFileOpen:
00191 
00192             
DebugTrace(( +1, Dbg,
00193                          
"UdfCommonCleanup, Fcb %08x FO %08x FILE\n",
00194                          Fcb,
00195                          FileObject ));
00196             
00197             
00198             
00199             
00200             
00201             
00202 
00203             
FsRtlCheckOplock( &Fcb->Oplock,
00204                               Irp,
00205                               IrpContext,
00206                               NULL,
00207                               NULL );
00208 
00209             
00210             
00211             
00212 
00213             
if (Fcb->FileLock != 
NULL) {
00214 
00215                 
FsRtlFastUnlockAll( Fcb->FileLock,
00216                                     FileObject,
00217                                     
IoGetRequestorProcess( Irp ),
00218                                     NULL );
00219             }
00220 
00221             
00222             
00223             
00224 
00225             
CcUninitializeCacheMap( FileObject, NULL, NULL );
00226 
00227             
00228             
00229             
00230 
00231             
UdfLockFcb( IrpContext, Fcb );
00232             Fcb->IsFastIoPossible = 
UdfIsFastIoPossible( Fcb );
00233             
UdfUnlockFcb( IrpContext, Fcb );
00234 
00235             
break;
00236 
00237         
case UserVolumeOpen :
00238 
00239             
DebugTrace(( +1, Dbg,
00240                          
"UdfCommonCleanup, Fcb %08x FO %08x VOL\n",
00241                          Fcb,
00242                          FileObject ));
00243 
00244             
break;
00245 
00246         
default :
00247 
00248             
UdfBugCheck( TypeOfOpen, 0, 0 );
00249         }
00250 
00251         
00252         
00253         
00254         
00255 
00256         
UdfLockVcb( IrpContext, Vcb );
00257 
00258         
00259         
00260         
00261 
00262         
UdfDecrementCleanupCounts( IrpContext, Fcb );
00263 
00264         
00265         
00266         
00267         
00268 
00269         AttemptTeardown = (Vcb->
VcbCleanup == 0 && Vcb->
VcbCondition == 
VcbNotMounted);
00270         
00271         
00272         
00273         
00274 
00275         
if (FileObject == Vcb->
VolumeLockFileObject) {
00276 
00277             
ClearFlag( Vcb->
VcbState, VCB_STATE_LOCKED );
00278             Vcb->
VolumeLockFileObject = 
NULL;
00279             SendUnlockNotification = 
TRUE;
00280         }
00281 
00282         
UdfUnlockVcb( IrpContext, Vcb );
00283 
00284         
00285         
00286         
00287         
00288         
00289 
00290         
IoRemoveShareAccess( FileObject, &Fcb->
ShareAccess );
00291 
00292     } finally {
00293 
00294         
UdfReleaseFcb( IrpContext, Fcb );
00295 
00296         
if (SendUnlockNotification) {
00297 
00298             
FsRtlNotifyVolumeEvent( FileObject, FSRTL_VOLUME_UNLOCK );
00299         }
00300     }
00301 
00302     
DebugTrace(( -1, Dbg,
00303                  
"UdfCommonCleanup, Fcb %08x FO %08x -> SUCCESS\n",
00304                  Fcb,
00305                  FileObject ));
00306     
00307     
00308     
00309     
00310     
00311     
00312     
00313     
if (AttemptTeardown) {
00314 
00315         
UdfAcquireVcbExclusive( IrpContext, Vcb, FALSE );
00316 
00317         
try {
00318             
00319             
UdfPurgeVolume( IrpContext, Vcb, FALSE );
00320 
00321         } finally {
00322 
00323             
UdfReleaseVcb( IrpContext, Vcb );
00324         }
00325     }
00326 
00327     
00328     
00329     
00330 
00331     
UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
00332 
00333     
return STATUS_SUCCESS;
00334 }