Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / drivers / filesystems / cdfs_new / lockctrl.c
1 /*++
2
3 Copyright (c) 1989-2000 Microsoft Corporation
4
5 Module Name:
6
7 LockCtrl.c
8
9 Abstract:
10
11 This module implements the Lock Control routines for Cdfs called
12 by the Fsd/Fsp dispatch driver.
13
14
15 --*/
16
17 #include "CdProcs.h"
18
19 //
20 // The Bug check file id for this module
21 //
22
23 #define BugCheckFileId (CDFS_BUG_CHECK_LOCKCTRL)
24
25 #ifdef ALLOC_PRAGMA
26 #pragma alloc_text(PAGE, CdCommonLockControl)
27 #pragma alloc_text(PAGE, CdFastLock)
28 #pragma alloc_text(PAGE, CdFastUnlockAll)
29 #pragma alloc_text(PAGE, CdFastUnlockAllByKey)
30 #pragma alloc_text(PAGE, CdFastUnlockSingle)
31 #endif
32
33 \f
34 NTSTATUS
35 CdCommonLockControl (
36 IN PIRP_CONTEXT IrpContext,
37 IN PIRP Irp
38 )
39
40 /*++
41
42 Routine Description:
43
44 This is the common routine for Lock Control called by both the fsd and fsp
45 threads.
46
47 Arguments:
48
49 Irp - Supplies the Irp to process
50
51 Return Value:
52
53 NTSTATUS - The return status for the operation
54
55 --*/
56
57 {
58 NTSTATUS Status;
59 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
60
61 TYPE_OF_OPEN TypeOfOpen;
62 PFCB Fcb;
63 PCCB Ccb;
64
65 PAGED_CODE();
66
67 //
68 // Extract and decode the type of file object we're being asked to process
69 //
70
71 TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
72
73 //
74 // If the file is not a user file open then we reject the request
75 // as an invalid parameter
76 //
77
78 if (TypeOfOpen != UserFileOpen) {
79
80 CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );
81 return STATUS_INVALID_PARAMETER;
82 }
83
84 //
85 // We check whether we can proceed based on the state of the file oplocks.
86 // This call might post the irp for us.
87 //
88
89 Status = FsRtlCheckOplock( &Fcb->Oplock,
90 Irp,
91 IrpContext,
92 (PVOID)CdOplockComplete,/* ReactOS Change: GCC "assignment from incompatible pointer type" */
93 NULL );
94
95 //
96 // If we don't get success then the oplock package completed the request.
97 //
98
99 if (Status != STATUS_SUCCESS) {
100
101 return Status;
102 }
103
104 //
105 // Verify the Fcb.
106 //
107
108 CdVerifyFcbOperation( IrpContext, Fcb );
109
110 //
111 // If we don't have a file lock, then get one now.
112 //
113
114 if (Fcb->FileLock == NULL) { CdCreateFileLock( IrpContext, Fcb, TRUE ); }
115
116 //
117 // Now call the FsRtl routine to do the actual processing of the
118 // Lock request
119 //
120
121 Status = FsRtlProcessFileLock( Fcb->FileLock, Irp, NULL );
122
123 //
124 // Set the flag indicating if Fast I/O is possible
125 //
126
127 CdLockFcb( IrpContext, Fcb );
128 Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb );
129 CdUnlockFcb( IrpContext, Fcb );
130
131 //
132 // Complete the request.
133 //
134
135 CdCompleteRequest( IrpContext, NULL, Status );
136 return Status;
137 }
138
139 \f
140 BOOLEAN
141 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
142 CdFastLock (
143 IN PFILE_OBJECT FileObject,
144 IN PLARGE_INTEGER FileOffset,
145 IN PLARGE_INTEGER Length,
146 PEPROCESS ProcessId,
147 ULONG Key,
148 BOOLEAN FailImmediately,
149 BOOLEAN ExclusiveLock,
150 OUT PIO_STATUS_BLOCK IoStatus,
151 IN PDEVICE_OBJECT DeviceObject
152 )
153
154 /*++
155
156 Routine Description:
157
158 This is a call back routine for doing the fast lock call.
159
160 Arguments:
161
162 FileObject - Supplies the file object used in this operation
163
164 FileOffset - Supplies the file offset used in this operation
165
166 Length - Supplies the length used in this operation
167
168 ProcessId - Supplies the process ID used in this operation
169
170 Key - Supplies the key used in this operation
171
172 FailImmediately - Indicates if the request should fail immediately
173 if the lock cannot be granted.
174
175 ExclusiveLock - Indicates if this is a request for an exclusive or
176 shared lock
177
178 IoStatus - Receives the Status if this operation is successful
179
180 Return Value:
181
182 BOOLEAN - TRUE if this operation completed and FALSE if caller
183 needs to take the long route.
184
185 --*/
186
187 {
188 BOOLEAN Results = FALSE;
189
190 PFCB Fcb;
191 TYPE_OF_OPEN TypeOfOpen;
192
193 PAGED_CODE();
194
195 ASSERT_FILE_OBJECT( FileObject );
196
197 IoStatus->Information = 0;
198
199 //
200 // Decode the type of file object we're being asked to process and
201 // make sure that is is only a user file open.
202 //
203
204 TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb );
205
206 if (TypeOfOpen != UserFileOpen) {
207
208 IoStatus->Status = STATUS_INVALID_PARAMETER;
209 return TRUE;
210 }
211
212 //
213 // Only deal with 'good' Fcb's.
214 //
215
216 if (!CdVerifyFcbOperation( NULL, Fcb )) {
217
218 return FALSE;
219 }
220
221 FsRtlEnterFileSystem();
222
223 //
224 // Use a try-finally to facilitate cleanup.
225 //
226
227 try {
228
229 //
230 // We check whether we can proceed based on the state of the file oplocks.
231 //
232
233 if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) {
234
235 try_return( NOTHING );
236 }
237
238 //
239 // If we don't have a file lock, then get one now.
240 //
241
242 if ((Fcb->FileLock == NULL) && !CdCreateFileLock( NULL, Fcb, FALSE )) {
243
244 try_return( NOTHING );
245 }
246
247 //
248 // Now call the FsRtl routine to perform the lock request.
249 //
250 /* ReactOS Change: GCC "suggest parentheses around assignment used as truth value" */
251 if ((Results = FsRtlFastLock( Fcb->FileLock,
252 FileObject,
253 FileOffset,
254 Length,
255 ProcessId,
256 Key,
257 FailImmediately,
258 ExclusiveLock,
259 IoStatus,
260 NULL,
261 FALSE ))) {
262
263 //
264 // Set the flag indicating if Fast I/O is questionable. We
265 // only change this flag if the current state is possible.
266 // Retest again after synchronizing on the header.
267 //
268
269 if (Fcb->IsFastIoPossible == FastIoIsPossible) {
270
271 CdLockFcb( NULL, Fcb );
272 Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb );
273 CdUnlockFcb( NULL, Fcb );
274 }
275 }
276
277 try_exit: NOTHING;
278 } finally {
279
280 FsRtlExitFileSystem();
281 }
282
283 return Results;
284 }
285
286 \f
287 BOOLEAN
288 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
289 CdFastUnlockSingle (
290 IN PFILE_OBJECT FileObject,
291 IN PLARGE_INTEGER FileOffset,
292 IN PLARGE_INTEGER Length,
293 PEPROCESS ProcessId,
294 ULONG Key,
295 OUT PIO_STATUS_BLOCK IoStatus,
296 IN PDEVICE_OBJECT DeviceObject
297 )
298
299 /*++
300
301 Routine Description:
302
303 This is a call back routine for doing the fast unlock single call.
304
305 Arguments:
306
307 FileObject - Supplies the file object used in this operation
308
309 FileOffset - Supplies the file offset used in this operation
310
311 Length - Supplies the length used in this operation
312
313 ProcessId - Supplies the process ID used in this operation
314
315 Key - Supplies the key used in this operation
316
317 Status - Receives the Status if this operation is successful
318
319 Return Value:
320
321 BOOLEAN - TRUE if this operation completed and FALSE if caller
322 needs to take the long route.
323
324 --*/
325
326 {
327 BOOLEAN Results = FALSE;
328 TYPE_OF_OPEN TypeOfOpen;
329 PFCB Fcb;
330
331 PAGED_CODE();
332
333 IoStatus->Information = 0;
334
335 //
336 // Decode the type of file object we're being asked to process and
337 // make sure that is is only a user file open.
338 //
339
340 TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb );
341
342 if (TypeOfOpen != UserFileOpen) {
343
344 IoStatus->Status = STATUS_INVALID_PARAMETER;
345 return TRUE;
346 }
347
348 //
349 // Only deal with 'good' Fcb's.
350 //
351
352 if (!CdVerifyFcbOperation( NULL, Fcb )) {
353
354 return FALSE;
355 }
356
357 //
358 // If there is no lock then return immediately.
359 //
360
361 if (Fcb->FileLock == NULL) {
362
363 IoStatus->Status = STATUS_RANGE_NOT_LOCKED;
364 return TRUE;
365 }
366
367 FsRtlEnterFileSystem();
368
369 try {
370
371 //
372 // We check whether we can proceed based on the state of the file oplocks.
373 //
374
375 if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) {
376
377 try_return( NOTHING );
378 }
379
380 //
381 // If we don't have a file lock, then get one now.
382 //
383
384 if ((Fcb->FileLock == NULL) && !CdCreateFileLock( NULL, Fcb, FALSE )) {
385
386 try_return( NOTHING );
387 }
388
389 //
390 // Now call the FsRtl routine to do the actual processing of the
391 // Lock request. The call will always succeed.
392 //
393
394 Results = TRUE;
395 IoStatus->Status = FsRtlFastUnlockSingle( Fcb->FileLock,
396 FileObject,
397 FileOffset,
398 Length,
399 ProcessId,
400 Key,
401 NULL,
402 FALSE );
403
404 //
405 // Set the flag indicating if Fast I/O is possible. We are
406 // only concerned if there are no longer any filelocks on this
407 // file.
408 //
409
410 if (!FsRtlAreThereCurrentFileLocks( Fcb->FileLock ) &&
411 (Fcb->IsFastIoPossible != FastIoIsPossible)) {
412
413 CdLockFcb( IrpContext, Fcb );
414 Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb );
415 CdUnlockFcb( IrpContext, Fcb );
416 }
417
418 try_exit: NOTHING;
419 } finally {
420
421 FsRtlExitFileSystem();
422 }
423
424 return Results;
425 }
426
427 \f
428 BOOLEAN
429 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
430 CdFastUnlockAll (
431 IN PFILE_OBJECT FileObject,
432 PEPROCESS ProcessId,
433 OUT PIO_STATUS_BLOCK IoStatus,
434 IN PDEVICE_OBJECT DeviceObject
435 )
436
437 /*++
438
439 Routine Description:
440
441 This is a call back routine for doing the fast unlock all call.
442
443 Arguments:
444
445 FileObject - Supplies the file object used in this operation
446
447 ProcessId - Supplies the process ID used in this operation
448
449 Status - Receives the Status if this operation is successful
450
451 Return Value:
452
453 BOOLEAN - TRUE if this operation completed and FALSE if caller
454 needs to take the long route.
455
456 --*/
457
458 {
459 BOOLEAN Results = FALSE;
460 TYPE_OF_OPEN TypeOfOpen;
461 PFCB Fcb;
462
463 PAGED_CODE();
464
465 IoStatus->Information = 0;
466
467 //
468 // Decode the type of file object we're being asked to process and
469 // make sure that is is only a user file open.
470 //
471
472 TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb );
473
474 if (TypeOfOpen != UserFileOpen) {
475
476 IoStatus->Status = STATUS_INVALID_PARAMETER;
477 return TRUE;
478 }
479
480 //
481 // Only deal with 'good' Fcb's.
482 //
483
484 if (!CdVerifyFcbOperation( NULL, Fcb )) {
485
486 return FALSE;
487 }
488
489 //
490 // If there is no lock then return immediately.
491 //
492
493 if (Fcb->FileLock == NULL) {
494
495 IoStatus->Status = STATUS_RANGE_NOT_LOCKED;
496 return TRUE;
497 }
498
499 FsRtlEnterFileSystem();
500
501 try {
502
503 //
504 // We check whether we can proceed based on the state of the file oplocks.
505 //
506
507 if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) {
508
509 try_return( NOTHING );
510 }
511
512 //
513 // If we don't have a file lock, then get one now.
514 //
515
516 if ((Fcb->FileLock == NULL) && !CdCreateFileLock( NULL, Fcb, FALSE )) {
517
518 try_return( NOTHING );
519 }
520
521 //
522 // Now call the FsRtl routine to do the actual processing of the
523 // Lock request. The call will always succeed.
524 //
525
526 Results = TRUE;
527 IoStatus->Status = FsRtlFastUnlockAll( Fcb->FileLock,
528 FileObject,
529 ProcessId,
530 NULL );
531
532
533 //
534 // Set the flag indicating if Fast I/O is possible
535 //
536
537 CdLockFcb( IrpContext, Fcb );
538 Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb );
539 CdUnlockFcb( IrpContext, Fcb );
540
541 try_exit: NOTHING;
542 } finally {
543
544 FsRtlExitFileSystem();
545 }
546
547 return Results;
548 }
549
550 \f
551 BOOLEAN
552 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
553 CdFastUnlockAllByKey (
554 IN PFILE_OBJECT FileObject,
555 PVOID ProcessId,
556 ULONG Key,
557 OUT PIO_STATUS_BLOCK IoStatus,
558 IN PDEVICE_OBJECT DeviceObject
559 )
560
561 /*++
562
563 Routine Description:
564
565 This is a call back routine for doing the fast unlock all by key call.
566
567 Arguments:
568
569 FileObject - Supplies the file object used in this operation
570
571 ProcessId - Supplies the process ID used in this operation
572
573 Key - Supplies the key used in this operation
574
575 Status - Receives the Status if this operation is successful
576
577 Return Value:
578
579 BOOLEAN - TRUE if this operation completed and FALSE if caller
580 needs to take the long route.
581
582 --*/
583
584 {
585 BOOLEAN Results = FALSE;
586 TYPE_OF_OPEN TypeOfOpen;
587 PFCB Fcb;
588
589 PAGED_CODE();
590
591 IoStatus->Information = 0;
592
593 //
594 // Decode the type of file object we're being asked to process and
595 // make sure that is is only a user file open.
596 //
597
598 TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb );
599
600 if (TypeOfOpen != UserFileOpen) {
601
602 IoStatus->Status = STATUS_INVALID_PARAMETER;
603 return TRUE;
604 }
605
606 //
607 // Only deal with 'good' Fcb's.
608 //
609
610 if (!CdVerifyFcbOperation( NULL, Fcb )) {
611
612 return FALSE;
613 }
614
615 //
616 // If there is no lock then return immediately.
617 //
618
619 if (Fcb->FileLock == NULL) {
620
621 IoStatus->Status = STATUS_RANGE_NOT_LOCKED;
622 return TRUE;
623 }
624
625 FsRtlEnterFileSystem();
626
627 try {
628
629 //
630 // We check whether we can proceed based on the state of the file oplocks.
631 //
632
633 if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) {
634
635 try_return( NOTHING );
636 }
637
638 //
639 // If we don't have a file lock, then get one now.
640 //
641
642 if ((Fcb->FileLock == NULL) && !CdCreateFileLock( NULL, Fcb, FALSE )) {
643
644 try_return( NOTHING );
645 }
646
647 //
648 // Now call the FsRtl routine to do the actual processing of the
649 // Lock request. The call will always succeed.
650 //
651
652 Results = TRUE;
653 IoStatus->Status = FsRtlFastUnlockAllByKey( Fcb->FileLock,
654 FileObject,
655 ProcessId,
656 Key,
657 NULL );
658
659
660 //
661 // Set the flag indicating if Fast I/O is possible
662 //
663
664 CdLockFcb( IrpContext, Fcb );
665 Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb );
666 CdUnlockFcb( IrpContext, Fcb );
667
668 try_exit: NOTHING;
669 } finally {
670
671 FsRtlExitFileSystem();
672 }
673
674 return Results;
675 }
676
677
678