ReactOS  0.4.13-dev-73-gcfe54aa
shutdown.c
Go to the documentation of this file.
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 
33 NTAPI
34 FatFsdShutdown (
35  _In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
37  )
38 
39 /*++
40 
41 Routine 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 
51 Arguments:
52 
53  VolumeDeviceObject - Supplies the volume device object where the
54  file exists
55 
56  Irp - Supplies the Irp being processed
57 
58 Return 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_)
117 NTSTATUS
118 FatCommonShutdown (
119  IN PIRP_CONTEXT IrpContext,
120  IN PIRP Irp
121  )
122 
123 /*++
124 
125 Routine Description:
126 
127  This is the common routine for shutdown called by both the fsd and
128  fsp threads.
129 
130 Arguments:
131 
132  Irp - Supplies the Irp being processed
133 
134 Return Value:
135 
136  NTSTATUS - The return status for the operation
137 
138 --*/
139 
140 {
141  KEVENT Event;
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,
264  KernelMode,
265  FALSE,
266  NULL );
267 
268  KeClearEvent( &Event );
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 Dbg
Definition: shutdown.c:22
#define FatReleaseVolume(IRPCONTEXT, VCB)
Definition: fatprocs.h:1409
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:384
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define FatReleaseGlobal(IRPCONTEXT)
Definition: fatprocs.h:1627
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define FsRtlEnterFileSystem
BOOLEAN FatIsIrpTopLevel(IN PIRP Irp)
Definition: fatdata.c:817
#define VCB_STATE_FLAG_MOUNTED_DIRTY
Definition: fatstruc.h:558
#define FsRtlExitFileSystem
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2621
PDEVICE_OBJECT FatCdromFileSystemDeviceObject
Definition: fatdata.c:59
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 IRP_MJ_SHUTDOWN
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define IRP_CONTEXT_FLAG_WRITE_THROUGH
Definition: ext2fs.h:1079
VOID NTAPI IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:1053
LONG NTSTATUS
Definition: precomp.h:26
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
Definition: cdstruc.h:504
#define IRP_CONTEXT_FLAG_DISABLE_POPUPS
Definition: cdstruc.h:1228
BOOLEAN ShutdownStarted
Definition: fatstruc.h:104
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2401
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FatAcquireExclusiveVolume(IRPCONTEXT, VCB)
Definition: fatprocs.h:1400
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:434
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2300
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
FAT_DATA FatData
Definition: fatdata.c:56
PDEVICE_OBJECT FatDiskFileSystemDeviceObject
Definition: fatdata.c:58
#define FatResetExceptionState(IRPCONTEXT)
Definition: fatprocs.h:2971
return Iosb
Definition: create.c:4426
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1425
#define _Inout_
Definition: no_sal2.h:244
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define VOID
Definition: acefi.h:82
Definition: typedefs.h:117
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
DRIVER_DISPATCH(nfs41_FsdDispatch)
Status
Definition: gdiplustypes.h:24
LIST_ENTRY VcbQueue
Definition: fatstruc.h:45
#define _In_
Definition: no_sal2.h:204
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1250
#define VCB_STATE_FLAG_SHUTDOWN
Definition: fatstruc.h:559
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4424
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
_SEH2_FINALLY
Definition: create.c:4395
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
_Requires_lock_held_(_Global_critical_region_)
Definition: shutdown.c:29
_Function_class_(IRP_MJ_SHUTDOWN)
Definition: shutdown.c:30
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
return STATUS_SUCCESS
Definition: btrfs.c:2725
#define FatAcquireExclusiveGlobal(IRPCONTEXT)
Definition: fatprocs.h:1378
#define NT_ASSERT
Definition: rtlfuncs.h:3312