[SHELL32] SHChangeNotify: Use tree for CDirectoryList (#6784)
[reactos.git] / drivers / filesystems / cdfs / resrcsup.c
1 /*++
2
3 Copyright (c) 1989-2000 Microsoft Corporation
4
5 Module Name:
6
7 ResrcSup.c
8
9 Abstract:
10
11 This module implements the Cdfs Resource acquisition routines
12
13
14 --*/
15
16 #include "cdprocs.h"
17
18 //
19 // The Bug check file id for this module
20 //
21
22 #define BugCheckFileId (CDFS_BUG_CHECK_RESRCSUP)
23
24 #ifdef ALLOC_PRAGMA
25 #pragma alloc_text(PAGE, CdAcquireForCache)
26 #pragma alloc_text(PAGE, CdFilterCallbackAcquireForCreateSection)
27 #pragma alloc_text(PAGE, CdAcquireResource)
28 #pragma alloc_text(PAGE, CdNoopAcquire)
29 #pragma alloc_text(PAGE, CdNoopRelease)
30 #pragma alloc_text(PAGE, CdReleaseForCreateSection)
31 #pragma alloc_text(PAGE, CdReleaseFromCache)
32 #endif
33
34 \f
35
36 _Requires_lock_held_(_Global_critical_region_)
37 _When_(Type == AcquireExclusive && return != FALSE, _Acquires_exclusive_lock_(*Resource))
38 _When_(Type == AcquireShared && return != FALSE, _Acquires_shared_lock_(*Resource))
39 _When_(Type == AcquireSharedStarveExclusive && return != FALSE, _Acquires_shared_lock_(*Resource))
40 _When_(IgnoreWait == FALSE, _Post_satisfies_(return == TRUE))
41 BOOLEAN
42 CdAcquireResource (
43 _In_ PIRP_CONTEXT IrpContext,
44 _Inout_ PERESOURCE Resource,
45 _In_ BOOLEAN IgnoreWait,
46 _In_ TYPE_OF_ACQUIRE Type
47 )
48
49 /*++
50
51 Routine Description:
52
53 This is the single routine used to acquire file system resources. It
54 looks at the IgnoreWait flag to determine whether to try to acquire the
55 resource without waiting. Returning TRUE/FALSE to indicate success or
56 failure. Otherwise it is driven by the WAIT flag in the IrpContext and
57 will raise CANT_WAIT on a failure.
58
59 Arguments:
60
61 Resource - This is the resource to try and acquire.
62
63 IgnoreWait - If TRUE then this routine will not wait to acquire the
64 resource and will return a boolean indicating whether the resource was
65 acquired. Otherwise we use the flag in the IrpContext and raise
66 if the resource is not acquired.
67
68 Type - Indicates how we should try to get the resource.
69
70 Return Value:
71
72 BOOLEAN - TRUE if the resource is acquired. FALSE if not acquired and
73 IgnoreWait is specified. Otherwise we raise CANT_WAIT.
74
75 --*/
76
77 {
78 BOOLEAN Wait = FALSE;
79 BOOLEAN Acquired;
80 PAGED_CODE();
81
82 //
83 // We look first at the IgnoreWait flag, next at the flag in the Irp
84 // Context to decide how to acquire this resource.
85 //
86
87 if (!IgnoreWait && FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) {
88
89 Wait = TRUE;
90 }
91
92 //
93 // Attempt to acquire the resource either shared or exclusively.
94 //
95
96 switch (Type) {
97 case AcquireExclusive:
98
99 #ifdef _MSC_VER
100 #pragma prefast( suppress:28137, "prefast believes Wait should be a constant, but this is ok for CDFS" )
101 #endif
102 Acquired = ExAcquireResourceExclusiveLite( Resource, Wait );
103 break;
104
105 case AcquireShared:
106
107 Acquired = ExAcquireResourceSharedLite( Resource, Wait );
108 break;
109
110 case AcquireSharedStarveExclusive:
111
112 Acquired = ExAcquireSharedStarveExclusive( Resource, Wait );
113 break;
114
115 default:
116 Acquired = FALSE;
117 NT_ASSERT( FALSE );
118 }
119
120 //
121 // If not acquired and the user didn't specifiy IgnoreWait then
122 // raise CANT_WAIT.
123 //
124
125 if (!Acquired && !IgnoreWait) {
126
127 CdRaiseStatus( IrpContext, STATUS_CANT_WAIT );
128 }
129
130 return Acquired;
131 }
132
133 \f
134
135 _Requires_lock_held_(_Global_critical_region_)
136 _When_(return!=0, _Acquires_shared_lock_(*Fcb->Resource))
137 BOOLEAN
138 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
139 CdAcquireForCache (
140 _Inout_ PFCB Fcb,
141 _In_ BOOLEAN Wait
142 )
143
144 /*++
145
146 Routine Description:
147
148 The address of this routine is specified when creating a CacheMap for
149 a file. It is subsequently called by the Lazy Writer for synchronization.
150
151 Arguments:
152
153 Fcb - The pointer supplied as context to the cache initialization
154 routine.
155
156 Wait - TRUE if the caller is willing to block.
157
158 Return Value:
159
160 None
161
162 --*/
163
164 {
165 PAGED_CODE();
166
167 if (!ExAcquireResourceSharedLite( Fcb->Resource, Wait )) {
168
169 return FALSE;
170 }
171
172 NT_ASSERT(IoGetTopLevelIrp() == NULL);
173 IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
174
175 return TRUE;
176 }
177
178 \f
179 _Requires_lock_held_(_Global_critical_region_)
180 _Releases_lock_(*Fcb->Resource)
181 VOID
182 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
183 CdReleaseFromCache (
184 _Inout_ PFCB Fcb
185 )
186
187 /*++
188
189 Routine Description:
190
191 The address of this routine is specified when creating a CacheMap for
192 a virtual file. It is subsequently called by the Lazy Writer to release
193 a resource acquired above.
194
195 Arguments:
196
197 Fcb - The pointer supplied as context to the cache initialization
198 routine.
199
200 Return Value:
201
202 None
203
204 --*/
205
206 {
207 PAGED_CODE();
208
209 NT_ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
210 IoSetTopLevelIrp( NULL );
211
212 ExReleaseResourceLite( Fcb->Resource );
213 }
214
215 \f
216 BOOLEAN
217 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
218 CdNoopAcquire (
219 _In_ PVOID Fcb,
220 _In_ BOOLEAN Wait
221 )
222
223 /*++
224
225 Routine Description:
226
227 This routine does nothing.
228
229 Arguments:
230
231 Fcb - The Fcb/Vcb which was specified as a context parameter for this
232 routine.
233
234 Wait - TRUE if the caller is willing to block.
235
236 Return Value:
237
238 TRUE
239
240 --*/
241
242 {
243 PAGED_CODE();
244
245 UNREFERENCED_PARAMETER( Fcb );
246 UNREFERENCED_PARAMETER( Wait );
247
248 return TRUE;
249 }
250
251 \f
252 VOID
253 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
254 CdNoopRelease (
255 _In_ PVOID Fcb
256 )
257
258 /*++
259
260 Routine Description:
261
262 This routine does nothing.
263
264 Arguments:
265
266 Fcb - The Fcb/Vcb which was specified as a context parameter for this
267 routine.
268
269 Return Value:
270
271 None
272
273 --*/
274
275 {
276 PAGED_CODE();
277
278 UNREFERENCED_PARAMETER( Fcb );
279 }
280
281
282 _Requires_lock_held_(_Global_critical_region_)
283 NTSTATUS
284 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
285 CdFilterCallbackAcquireForCreateSection (
286 _In_ PFS_FILTER_CALLBACK_DATA CallbackData,
287 _Unreferenced_parameter_ PVOID *CompletionContext
288 )
289
290 /*++
291
292 Routine Description:
293
294 This is the callback routine for MM to use to acquire the file exclusively.
295
296 Arguments:
297
298 FS_FILTER_CALLBACK_DATA - Filter based callback data that provides the file object we
299 want to acquire.
300
301 CompletionContext - Ignored.
302
303 Return Value:
304
305 On success we return STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY.
306
307 If SyncType is SyncTypeCreateSection, we return a status that indicates there are no
308 writers to this file.
309
310 --*/
311
312 {
313 PFILE_OBJECT FileObject;
314
315
316 PAGED_CODE();
317
318 NT_ASSERT( CallbackData->Operation == FS_FILTER_ACQUIRE_FOR_SECTION_SYNCHRONIZATION );
319 NT_ASSERT( CallbackData->SizeOfFsFilterCallbackData == sizeof(FS_FILTER_CALLBACK_DATA) );
320
321 //
322 // Get the file object from the callback data.
323 //
324
325 FileObject = CallbackData->FileObject;
326
327 //
328 // Get the Fcb resource exclusively.
329 //
330
331 ExAcquireResourceExclusiveLite( &((PFCB) FileObject->FsContext)->FcbNonpaged->FcbResource,
332 TRUE );
333
334 //
335 // Take the File resource shared. We need this later on when MM calls
336 // QueryStandardInfo to get the file size.
337 //
338 // If we don't use StarveExclusive, then we can get wedged behind an
339 // exclusive waiter who is waiting on someone else holding it shared in the
340 // read->initializecachemap path (which calls createsection) who is in turn
341 // waiting on us to finish the create section.
342 //
343
344 ExAcquireSharedStarveExclusive( ((PFCB) FileObject->FsContext)->Resource,
345 TRUE );
346
347 //
348 // CDFS is a read-only file system, so we can always indicate no writers.
349 // We only do this for create section synchronization. For others we
350 // return the generic success STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY.
351 //
352
353 if (CallbackData->Parameters.AcquireForSectionSynchronization.SyncType == SyncTypeCreateSection) {
354
355 return STATUS_FILE_LOCKED_WITH_ONLY_READERS;
356
357 } else {
358
359 return STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY;
360 }
361
362 UNREFERENCED_PARAMETER( CompletionContext );
363 }
364
365 \f
366 _Function_class_(FAST_IO_RELEASE_FILE)
367 _Requires_lock_held_(_Global_critical_region_)
368 VOID
369 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
370 CdReleaseForCreateSection (
371 _In_ PFILE_OBJECT FileObject
372 )
373
374 /*++
375
376 Routine Description:
377
378 This is the callback routine for MM to use to release a file acquired with
379 the AcquireForCreateSection call above.
380
381 Arguments:
382
383 FileObject - File object for a Cdfs stream.
384
385 Return Value:
386
387 None
388
389 --*/
390
391 {
392 PAGED_CODE();
393
394 //
395 // Release the resources.
396 //
397
398 ExReleaseResourceLite( &((PFCB) FileObject->FsContext)->FcbNonpaged->FcbResource );
399 ExReleaseResourceLite( ((PFCB) FileObject->FsContext)->Resource);
400 }
401