3 Copyright (c) 1989-2000 Microsoft Corporation
11 This module implements the file system shutdown routine for Fat
19 // Local debug trace level
22 #define Dbg (DEBUG_TRACE_SHUTDOWN)
25 #pragma alloc_text(PAGE, FatCommonShutdown)
26 #pragma alloc_text(PAGE, FatFsdShutdown)
33 IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject
,
41 This routine implements the FSD part of shutdown. Note that Shutdown will
42 never be done asynchronously so we will never need the Fsp counterpart
45 This is the shutdown routine for the Fat file system device driver.
46 This routine locks the global file system lock and then syncs all the
51 VolumeDeviceObject - Supplies the volume device object where the
54 Irp - Supplies the Irp being processed
58 NTSTATUS - Always STATUS_SUCCESS
64 PIRP_CONTEXT IrpContext
= NULL
;
68 DebugTrace(+1, Dbg
, "FatFsdShutdown\n", 0);
71 // Call the common shutdown routine.
74 FsRtlEnterFileSystem();
76 TopLevel
= FatIsIrpTopLevel( Irp
);
80 IrpContext
= FatCreateIrpContext( Irp
, TRUE
);
82 Status
= FatCommonShutdown( IrpContext
, Irp
);
84 } _SEH2_EXCEPT(FatExceptionFilter( IrpContext
, _SEH2_GetExceptionInformation() )) {
87 // We had some trouble trying to perform the requested
88 // operation, so we'll abort the I/O request with
89 // the error status that we get back from the
93 Status
= FatProcessException( IrpContext
, Irp
, _SEH2_GetExceptionCode() );
96 if (TopLevel
) { IoSetTopLevelIrp( NULL
); }
98 FsRtlExitFileSystem();
101 // And return to our caller
104 DebugTrace(-1, Dbg
, "FatFsdShutdown -> %08lx\n", Status
);
106 UNREFERENCED_PARAMETER( VolumeDeviceObject
);
114 IN PIRP_CONTEXT IrpContext
,
122 This is the common routine for shutdown called by both the fsd and
127 Irp - Supplies the Irp being processed
131 NTSTATUS - The return status for the operation
141 IO_STATUS_BLOCK Iosb
;
145 // Make sure we don't get any pop-ups, and write everything through.
148 SetFlag(IrpContext
->Flags
, IRP_CONTEXT_FLAG_DISABLE_POPUPS
|
149 IRP_CONTEXT_FLAG_WRITE_THROUGH
);
152 // Allocate an initialize an event for doing calls down to
153 // our target deivce objects
156 Event
= FsRtlAllocatePoolWithTag( NonPagedPool
,
159 KeInitializeEvent( Event
, NotificationEvent
, FALSE
);
162 // Indicate that shutdown has started. This is used in FatFspClose.
165 FatData
.ShutdownStarted
= TRUE
;
168 // Get everyone else out of the way
171 (VOID
) FatAcquireExclusiveGlobal( IrpContext
);
176 // For every volume that is mounted we will flush the
177 // volume and then shutdown the target device objects.
180 Links
= FatData
.VcbQueue
.Flink
;
181 while (Links
!= &FatData
.VcbQueue
) {
183 Vcb
= CONTAINING_RECORD(Links
, VCB
, VcbLinks
);
185 Links
= Links
->Flink
;
188 // If we have already been called before for this volume
189 // (and yes this does happen), skip this volume as no writes
190 // have been allowed since the first shutdown.
193 if ( FlagOn( Vcb
->VcbState
, VCB_STATE_FLAG_SHUTDOWN
) ||
194 (Vcb
->VcbCondition
!= VcbGood
) ) {
199 FatAcquireExclusiveVolume( IrpContext
, Vcb
);
203 (VOID
)FatFlushVolume( IrpContext
, Vcb
, Flush
);
206 // The volume is now clean, note it. We purge the
207 // volume file cache map before marking the volume
208 // clean incase there is a stale Bpb in the cache.
211 if (!FlagOn(Vcb
->VcbState
, VCB_STATE_FLAG_MOUNTED_DIRTY
)) {
213 CcPurgeCacheSection( &Vcb
->SectionObjectPointers
,
218 FatMarkVolume( IrpContext
, Vcb
, VolumeClean
);
221 } _SEH2_EXCEPT( EXCEPTION_EXECUTE_HANDLER
) {
223 FatResetExceptionState( IrpContext
);
227 // Sometimes we take an excepion while flushing the volume, such
228 // as when autoconv has converted the volume and is rebooting.
229 // Even in that case we want to send the shutdown irp to the
230 // target device so it can know to flush its cache, if it has one.
235 NewIrp
= IoBuildSynchronousFsdRequest( IRP_MJ_SHUTDOWN
,
236 Vcb
->TargetDeviceObject
,
243 if (NewIrp
!= NULL
) {
245 if (NT_SUCCESS(IoCallDriver( Vcb
->TargetDeviceObject
, NewIrp
))) {
247 (VOID
) KeWaitForSingleObject( Event
,
253 KeClearEvent( Event
);
257 } _SEH2_EXCEPT( EXCEPTION_EXECUTE_HANDLER
) {
259 FatResetExceptionState( IrpContext
);
262 SetFlag( Vcb
->VcbState
, VCB_STATE_FLAG_SHUTDOWN
);
266 // Attempt to punch the volume down.
269 VcbDeleted
= FatCheckForDismount( IrpContext
,
274 FatReleaseVolume( IrpContext
, Vcb
);
282 FatReleaseGlobal( IrpContext
);
285 // Unregister the file system.
288 IoUnregisterFileSystem( FatDiskFileSystemDeviceObject
);
289 IoUnregisterFileSystem( FatCdromFileSystemDeviceObject
);
290 IoDeleteDevice( FatDiskFileSystemDeviceObject
);
291 IoDeleteDevice( FatCdromFileSystemDeviceObject
);
293 FatCompleteRequest( IrpContext
, Irp
, STATUS_SUCCESS
);
297 // And return to our caller
300 DebugTrace(-1, Dbg
, "FatFsdShutdown -> STATUS_SUCCESS\n", 0);
302 return STATUS_SUCCESS
;