ReactOS 0.4.15-dev-7918-g2a2556c
shutdown.c
Go to the documentation of this file.
1/*++
2
3Copyright (c) 1989-2000 Microsoft Corporation
4
5Module Name:
6
7 Shutdown.c
8
9Abstract:
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
34FatFsdShutdown (
35 _In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
37 )
38
39/*++
40
41Routine Description:
42
43 This routine implements the FSD part of shutdown. Note that Shutdown will
44 never be done asynchronously so we will never need the Fsp counterpart
45 to shutdown.
46
47 This is the shutdown routine for the Fat file system device driver.
48 This routine locks the global file system lock and then syncs all the
49 mounted volumes.
50
51Arguments:
52
53 VolumeDeviceObject - Supplies the volume device object where the
54 file exists
55
56 Irp - Supplies the Irp being processed
57
58Return Value:
59
60 NTSTATUS - Always STATUS_SUCCESS
61
62--*/
63
64{
66 PIRP_CONTEXT IrpContext = NULL;
67
69
70 PAGED_CODE();
71
72 DebugTrace(+1, Dbg, "FatFsdShutdown\n", 0);
73
74 //
75 // Call the common shutdown routine.
76 //
77
79
81
82 _SEH2_TRY {
83
84 IrpContext = FatCreateIrpContext( Irp, TRUE );
85
86 Status = FatCommonShutdown( IrpContext, Irp );
87
89
90 //
91 // We had some trouble trying to perform the requested
92 // operation, so we'll abort the I/O request with
93 // the error status that we get back from the
94 // execption code
95 //
96
97 Status = FatProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
98 } _SEH2_END;
99
100 if (TopLevel) { IoSetTopLevelIrp( NULL ); }
101
103
104 //
105 // And return to our caller
106 //
107
108 DebugTrace(-1, Dbg, "FatFsdShutdown -> %08lx\n", Status);
109
110 UNREFERENCED_PARAMETER( VolumeDeviceObject );
111
112 return Status;
113}
114
115
116_Requires_lock_held_(_Global_critical_region_)
118FatCommonShutdown (
119 IN PIRP_CONTEXT IrpContext,
120 IN PIRP Irp
121 )
122
123/*++
124
125Routine Description:
126
127 This is the common routine for shutdown called by both the fsd and
128 fsp threads.
129
130Arguments:
131
132 Irp - Supplies the Irp being processed
133
134Return Value:
135
136 NTSTATUS - The return status for the operation
137
138--*/
139
140{
142 PLIST_ENTRY Links;
143 PVCB Vcb;
144 PIRP NewIrp;
146 BOOLEAN VcbDeleted;
147
148 PAGED_CODE();
149
150 //
151 // Make sure we don't get any pop-ups, and write everything through.
152 //
153
154 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS |
156
157 //
158 // Initialize an event for doing calls down to
159 // our target device objects.
160 //
161
163
164 //
165 // Indicate that shutdown has started. This is used in FatFspClose.
166 //
167
169
170 //
171 // Get everyone else out of the way
172 //
173
174 NT_ASSERT( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
175
176#ifdef _MSC_VER
177#pragma prefast( push )
178#pragma prefast( disable: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" )
179#pragma prefast( disable: 28193, "this will always wait" )
180#endif
181
182 (VOID) FatAcquireExclusiveGlobal( IrpContext );
183
184#ifdef _MSC_VER
185#pragma prefast( pop )
186#endif
187
188 _SEH2_TRY {
189
190 //
191 // For every volume that is mounted we will flush the
192 // volume and then shutdown the target device objects.
193 //
194
195 Links = FatData.VcbQueue.Flink;
196 while (Links != &FatData.VcbQueue) {
197
198 Vcb = CONTAINING_RECORD(Links, VCB, VcbLinks);
199
200 Links = Links->Flink;
201
202 //
203 // If we have already been called before for this volume
204 // (and yes this does happen), skip this volume as no writes
205 // have been allowed since the first shutdown.
206 //
207
208 if ( FlagOn( Vcb->VcbState, VCB_STATE_FLAG_SHUTDOWN) ||
209 (Vcb->VcbCondition != VcbGood) ) {
210
211 continue;
212 }
213
214 FatAcquireExclusiveVolume( IrpContext, Vcb );
215
216 _SEH2_TRY {
217
218 (VOID)FatFlushVolume( IrpContext, Vcb, Flush );
219
220 //
221 // The volume is now clean, note it. We purge the
222 // volume file cache map before marking the volume
223 // clean incase there is a stale Bpb in the cache.
224 //
225
226 if (!FlagOn(Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY)) {
227
228 CcPurgeCacheSection( &Vcb->SectionObjectPointers,
229 NULL,
230 0,
231 FALSE );
232
233 FatMarkVolume( IrpContext, Vcb, VolumeClean );
234 }
235
237
238 FatResetExceptionState( IrpContext );
239 } _SEH2_END;
240
241 //
242 // Sometimes we take an excepion while flushing the volume, such
243 // as when autoconv has converted the volume and is rebooting.
244 // Even in that case we want to send the shutdown irp to the
245 // target device so it can know to flush its cache, if it has one.
246 //
247
248 _SEH2_TRY {
249
251 Vcb->TargetDeviceObject,
252 NULL,
253 0,
254 NULL,
255 &Event,
256 &Iosb );
257
258 if (NewIrp != NULL) {
259
260 if (NT_SUCCESS(IoCallDriver( Vcb->TargetDeviceObject, NewIrp ))) {
261
263 Executive,
265 FALSE,
266 NULL );
267
269 }
270 }
271
273
274 FatResetExceptionState( IrpContext );
275 } _SEH2_END;
276
277 SetFlag( Vcb->VcbState, VCB_STATE_FLAG_SHUTDOWN );
278
279 //
280 // Attempt to punch the volume down.
281 //
282
283 VcbDeleted = FatCheckForDismount( IrpContext,
284 Vcb,
285 FALSE );
286
287 if (!VcbDeleted) {
288
289 FatReleaseVolume( IrpContext, Vcb );
290 }
291 }
292
293 } _SEH2_FINALLY {
294
295
296 FatReleaseGlobal( IrpContext );
297
298 //
299 // Unregister the file system.
300 //
301
306
307 FatCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
308 } _SEH2_END;
309
310 //
311 // And return to our caller
312 //
313
314 DebugTrace(-1, Dbg, "FatFsdShutdown -> STATUS_SUCCESS\n", 0);
315
316 return STATUS_SUCCESS;
317}
318
#define PAGED_CODE()
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
LONG NTSTATUS
Definition: precomp.h:26
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
#define IRP_CONTEXT_FLAG_DISABLE_POPUPS
Definition: cdstruc.h:1222
#define _Requires_lock_held_(lock)
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
return Iosb
Definition: create.c:4402
#define Dbg
Definition: shutdown.c:22
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define IRP_CONTEXT_FLAG_WRITE_THROUGH
Definition: ext2fs.h:1088
PDEVICE_OBJECT FatDiskFileSystemDeviceObject
Definition: fatdata.c:58
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
BOOLEAN FatIsIrpTopLevel(IN PIRP Irp)
Definition: fatdata.c:817
FAT_DATA FatData
Definition: fatdata.c:56
PDEVICE_OBJECT FatCdromFileSystemDeviceObject
Definition: fatdata.c:59
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
@ VolumeClean
Definition: fatprocs.h:1954
#define FatAcquireExclusiveGlobal(IRPCONTEXT)
Definition: fatprocs.h:1387
#define FatAcquireExclusiveVolume(IRPCONTEXT, VCB)
Definition: fatprocs.h:1409
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2417
#define FatReleaseVolume(IRPCONTEXT, VCB)
Definition: fatprocs.h:1418
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2633
#define FatReleaseGlobal(IRPCONTEXT)
Definition: fatprocs.h:1636
#define FatResetExceptionState(IRPCONTEXT)
Definition: fatprocs.h:2983
@ Flush
Definition: fatprocs.h:1054
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2301
#define VCB_STATE_FLAG_SHUTDOWN
Definition: fatstruc.h:563
#define VCB_STATE_FLAG_MOUNTED_DIRTY
Definition: fatstruc.h:562
@ VcbGood
Definition: fatstruc.h:223
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
Status
Definition: gdiplustypes.h:25
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define _Function_class_(x)
Definition: ms_sal.h:2946
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
#define KernelMode
Definition: asm.h:34
DRIVER_DISPATCH(nfs41_FsdDispatch)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
@ NotificationEvent
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
VOID NTAPI IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:1056
#define Vcb
Definition: cdprocs.h:1415
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
#define STATUS_SUCCESS
Definition: shellext.h:65
BOOLEAN ShutdownStarted
Definition: fatstruc.h:108
LIST_ENTRY VcbQueue
Definition: fatstruc.h:49
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: cdstruc.h:498
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define IRP_MJ_SHUTDOWN
@ Executive
Definition: ketypes.h:415
#define NT_ASSERT
Definition: rtlfuncs.h:3310