[FASTFAT_NEW] Fix build with FASTFATDBG set
[reactos.git] / drivers / filesystems / fastfat_new / shutdown.c
1 /*++
2
3 Copyright (c) 1989-2000 Microsoft Corporation
4
5 Module Name:
6
7 Shutdown.c
8
9 Abstract:
10
11 This module implements the file system shutdown routine for Fat
12
13
14 --*/
15
16 #include "fatprocs.h"
17
18 //
19 // Local debug trace level
20 //
21
22 #define Dbg (DEBUG_TRACE_SHUTDOWN)
23
24 #ifdef ALLOC_PRAGMA
25 #pragma alloc_text(PAGE, FatCommonShutdown)
26 #pragma alloc_text(PAGE, FatFsdShutdown)
27 #endif
28
29 \f
30 NTSTATUS
31 NTAPI
32 FatFsdShutdown (
33 IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
34 IN PIRP Irp
35 )
36
37 /*++
38
39 Routine Description:
40
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
43 to shutdown.
44
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
47 mounted volumes.
48
49 Arguments:
50
51 VolumeDeviceObject - Supplies the volume device object where the
52 file exists
53
54 Irp - Supplies the Irp being processed
55
56 Return Value:
57
58 NTSTATUS - Always STATUS_SUCCESS
59
60 --*/
61
62 {
63 NTSTATUS Status;
64 PIRP_CONTEXT IrpContext = NULL;
65
66 BOOLEAN TopLevel;
67
68 DebugTrace(+1, Dbg, "FatFsdShutdown\n", 0);
69
70 //
71 // Call the common shutdown routine.
72 //
73
74 FsRtlEnterFileSystem();
75
76 TopLevel = FatIsIrpTopLevel( Irp );
77
78 _SEH2_TRY {
79
80 IrpContext = FatCreateIrpContext( Irp, TRUE );
81
82 Status = FatCommonShutdown( IrpContext, Irp );
83
84 } _SEH2_EXCEPT(FatExceptionFilter( IrpContext, _SEH2_GetExceptionInformation() )) {
85
86 //
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
90 // execption code
91 //
92
93 Status = FatProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
94 } _SEH2_END;
95
96 if (TopLevel) { IoSetTopLevelIrp( NULL ); }
97
98 FsRtlExitFileSystem();
99
100 //
101 // And return to our caller
102 //
103
104 DebugTrace(-1, Dbg, "FatFsdShutdown -> %08lx\n", Status);
105
106 UNREFERENCED_PARAMETER( VolumeDeviceObject );
107
108 return Status;
109 }
110
111 \f
112 NTSTATUS
113 FatCommonShutdown (
114 IN PIRP_CONTEXT IrpContext,
115 IN PIRP Irp
116 )
117
118 /*++
119
120 Routine Description:
121
122 This is the common routine for shutdown called by both the fsd and
123 fsp threads.
124
125 Arguments:
126
127 Irp - Supplies the Irp being processed
128
129 Return Value:
130
131 NTSTATUS - The return status for the operation
132
133 --*/
134
135 {
136 PKEVENT Event;
137
138 PLIST_ENTRY Links;
139 PVCB Vcb;
140 PIRP NewIrp;
141 IO_STATUS_BLOCK Iosb;
142 BOOLEAN VcbDeleted;
143
144 //
145 // Make sure we don't get any pop-ups, and write everything through.
146 //
147
148 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS |
149 IRP_CONTEXT_FLAG_WRITE_THROUGH);
150
151 //
152 // Allocate an initialize an event for doing calls down to
153 // our target deivce objects
154 //
155
156 Event = FsRtlAllocatePoolWithTag( NonPagedPool,
157 sizeof(KEVENT),
158 TAG_EVENT );
159 KeInitializeEvent( Event, NotificationEvent, FALSE );
160
161 //
162 // Indicate that shutdown has started. This is used in FatFspClose.
163 //
164
165 FatData.ShutdownStarted = TRUE;
166
167 //
168 // Get everyone else out of the way
169 //
170
171 (VOID) FatAcquireExclusiveGlobal( IrpContext );
172
173 _SEH2_TRY {
174
175 //
176 // For every volume that is mounted we will flush the
177 // volume and then shutdown the target device objects.
178 //
179
180 Links = FatData.VcbQueue.Flink;
181 while (Links != &FatData.VcbQueue) {
182
183 Vcb = CONTAINING_RECORD(Links, VCB, VcbLinks);
184
185 Links = Links->Flink;
186
187 //
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.
191 //
192
193 if ( FlagOn( Vcb->VcbState, VCB_STATE_FLAG_SHUTDOWN) ||
194 (Vcb->VcbCondition != VcbGood) ) {
195
196 continue;
197 }
198
199 FatAcquireExclusiveVolume( IrpContext, Vcb );
200
201 _SEH2_TRY {
202
203 (VOID)FatFlushVolume( IrpContext, Vcb, Flush );
204
205 //
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.
209 //
210
211 if (!FlagOn(Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY)) {
212
213 CcPurgeCacheSection( &Vcb->SectionObjectPointers,
214 NULL,
215 0,
216 FALSE );
217
218 FatMarkVolume( IrpContext, Vcb, VolumeClean );
219 }
220
221 } _SEH2_EXCEPT( EXCEPTION_EXECUTE_HANDLER ) {
222
223 FatResetExceptionState( IrpContext );
224 } _SEH2_END;
225
226 //
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.
231 //
232
233 _SEH2_TRY {
234
235 NewIrp = IoBuildSynchronousFsdRequest( IRP_MJ_SHUTDOWN,
236 Vcb->TargetDeviceObject,
237 NULL,
238 0,
239 NULL,
240 Event,
241 &Iosb );
242
243 if (NewIrp != NULL) {
244
245 if (NT_SUCCESS(IoCallDriver( Vcb->TargetDeviceObject, NewIrp ))) {
246
247 (VOID) KeWaitForSingleObject( Event,
248 Executive,
249 KernelMode,
250 FALSE,
251 NULL );
252
253 KeClearEvent( Event );
254 }
255 }
256
257 } _SEH2_EXCEPT( EXCEPTION_EXECUTE_HANDLER ) {
258
259 FatResetExceptionState( IrpContext );
260 } _SEH2_END;
261
262 SetFlag( Vcb->VcbState, VCB_STATE_FLAG_SHUTDOWN );
263
264
265 //
266 // Attempt to punch the volume down.
267 //
268
269 VcbDeleted = FatCheckForDismount( IrpContext,
270 Vcb,
271 FALSE );
272 if (!VcbDeleted) {
273
274 FatReleaseVolume( IrpContext, Vcb );
275 }
276 }
277
278 } _SEH2_FINALLY {
279
280 ExFreePool( Event );
281
282 FatReleaseGlobal( IrpContext );
283
284 //
285 // Unregister the file system.
286 //
287
288 IoUnregisterFileSystem( FatDiskFileSystemDeviceObject);
289 IoUnregisterFileSystem( FatCdromFileSystemDeviceObject);
290 IoDeleteDevice( FatDiskFileSystemDeviceObject);
291 IoDeleteDevice( FatCdromFileSystemDeviceObject);
292
293 FatCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
294 } _SEH2_END;
295
296 //
297 // And return to our caller
298 //
299
300 DebugTrace(-1, Dbg, "FatFsdShutdown -> STATUS_SUCCESS\n", 0);
301
302 return STATUS_SUCCESS;
303 }
304