[FASTFAT_NEW] Fix build with FASTFATDBG set
[reactos.git] / drivers / filesystems / fastfat_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 Fat called
12 by the dispatch driver.
13
14
15 --*/
16
17 #include "fatprocs.h"
18
19 //
20 // The local debug trace level
21 //
22
23 #define Dbg (DEBUG_TRACE_LOCKCTRL)
24
25 #ifdef ALLOC_PRAGMA
26 #pragma alloc_text(PAGE, FatCommonLockControl)
27 #pragma alloc_text(PAGE, FatFastLock)
28 #pragma alloc_text(PAGE, FatFastUnlockAll)
29 #pragma alloc_text(PAGE, FatFastUnlockAllByKey)
30 #pragma alloc_text(PAGE, FatFastUnlockSingle)
31 #pragma alloc_text(PAGE, FatFsdLockControl)
32 #endif
33
34 \f
35 NTSTATUS
36 NTAPI
37 FatFsdLockControl (
38 IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
39 IN PIRP Irp
40 )
41
42 /*++
43
44 Routine Description:
45
46 This routine implements the FSD part of Lock control operations
47
48 Arguments:
49
50 VolumeDeviceObject - Supplies the volume device object where the
51 file exists
52
53 Irp - Supplies the Irp being processed
54
55 Return Value:
56
57 NTSTATUS - The FSD status for the IRP
58
59 --*/
60
61 {
62 NTSTATUS Status;
63 PIRP_CONTEXT IrpContext = NULL;
64
65 BOOLEAN TopLevel;
66
67 DebugTrace(+1, Dbg, "FatFsdLockControl\n", 0);
68
69 //
70 // Call the common Lock Control routine, with blocking allowed if
71 // synchronous
72 //
73
74 FsRtlEnterFileSystem();
75
76 TopLevel = FatIsIrpTopLevel( Irp );
77
78 _SEH2_TRY {
79
80 IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ) );
81
82 Status = FatCommonLockControl( 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, "FatFsdLockControl -> %08lx\n", Status);
105
106 UNREFERENCED_PARAMETER( VolumeDeviceObject );
107
108 return Status;
109 }
110
111 \f
112 BOOLEAN
113 NTAPI
114 FatFastLock (
115 IN PFILE_OBJECT FileObject,
116 IN PLARGE_INTEGER FileOffset,
117 IN PLARGE_INTEGER Length,
118 PEPROCESS ProcessId,
119 ULONG Key,
120 BOOLEAN FailImmediately,
121 BOOLEAN ExclusiveLock,
122 OUT PIO_STATUS_BLOCK IoStatus,
123 IN PDEVICE_OBJECT DeviceObject
124 )
125
126 /*++
127
128 Routine Description:
129
130 This is a call back routine for doing the fast lock call.
131
132 Arguments:
133
134 FileObject - Supplies the file object used in this operation
135
136 FileOffset - Supplies the file offset used in this operation
137
138 Length - Supplies the length used in this operation
139
140 ProcessId - Supplies the process ID used in this operation
141
142 Key - Supplies the key used in this operation
143
144 FailImmediately - Indicates if the request should fail immediately
145 if the lock cannot be granted.
146
147 ExclusiveLock - Indicates if this is a request for an exclusive or
148 shared lock
149
150 IoStatus - Receives the Status if this operation is successful
151
152 Return Value:
153
154 BOOLEAN - TRUE if this operation completed and FALSE if caller
155 needs to take the long route.
156
157 --*/
158
159 {
160 BOOLEAN Results;
161 PVCB Vcb;
162 PFCB Fcb;
163 PCCB Ccb;
164
165 DebugTrace(+1, Dbg, "FatFastLock\n", 0);
166
167 //
168 // Decode the type of file object we're being asked to process and make
169 // sure it is only a user file open.
170 //
171
172 if (FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb ) != UserFileOpen) {
173
174 IoStatus->Status = STATUS_INVALID_PARAMETER;
175 IoStatus->Information = 0;
176
177 DebugTrace(-1, Dbg, "FatFastLock -> TRUE (STATUS_INVALID_PARAMETER)\n", 0);
178 return TRUE;
179 }
180
181 //
182 // Acquire exclusive access to the Fcb this operation can always wait
183 //
184
185 FsRtlEnterFileSystem();
186
187 _SEH2_TRY {
188
189 //
190 // We check whether we can proceed
191 // based on the state of the file oplocks.
192 //
193
194 if (!FsRtlOplockIsFastIoPossible( &(Fcb)->Specific.Fcb.Oplock )) {
195
196 try_return( Results = FALSE );
197 }
198
199 //
200 // Now call the FsRtl routine to do the actual processing of the
201 // Lock request
202 //
203
204 #ifndef __REACTOS__
205 if (Results = FsRtlFastLock( &Fcb->Specific.Fcb.FileLock,
206 #else
207 Results = FsRtlFastLock( &Fcb->Specific.Fcb.FileLock,
208 #endif
209 FileObject,
210 FileOffset,
211 Length,
212 ProcessId,
213 Key,
214 FailImmediately,
215 ExclusiveLock,
216 IoStatus,
217 NULL,
218 #ifndef __REACTOS__
219 FALSE )) {
220 #else
221 FALSE );
222
223 if (Results) {
224 #endif
225
226 //
227 // Set the flag indicating if Fast I/O is possible
228 //
229
230 Fcb->Header.IsFastIoPossible = FatIsFastIoPossible( Fcb );
231 }
232
233 try_exit: NOTHING;
234 } _SEH2_FINALLY {
235
236 DebugUnwind( FatFastLock );
237
238 //
239 // Release the Fcb, and return to our caller
240 //
241
242 FsRtlExitFileSystem();
243
244 DebugTrace(-1, Dbg, "FatFastLock -> %08lx\n", Results);
245 } _SEH2_END;
246
247 return Results;
248 }
249
250 \f
251 BOOLEAN
252 NTAPI
253 FatFastUnlockSingle (
254 IN PFILE_OBJECT FileObject,
255 IN PLARGE_INTEGER FileOffset,
256 IN PLARGE_INTEGER Length,
257 PEPROCESS ProcessId,
258 ULONG Key,
259 OUT PIO_STATUS_BLOCK IoStatus,
260 IN PDEVICE_OBJECT DeviceObject
261 )
262
263 /*++
264
265 Routine Description:
266
267 This is a call back routine for doing the fast unlock single call.
268
269 Arguments:
270
271 FileObject - Supplies the file object used in this operation
272
273 FileOffset - Supplies the file offset used in this operation
274
275 Length - Supplies the length used in this operation
276
277 ProcessId - Supplies the process ID used in this operation
278
279 Key - Supplies the key used in this operation
280
281 Status - Receives the Status if this operation is successful
282
283 Return Value:
284
285 BOOLEAN - TRUE if this operation completed and FALSE if caller
286 needs to take the long route.
287
288 --*/
289
290 {
291 BOOLEAN Results;
292 PVCB Vcb;
293 PFCB Fcb;
294 PCCB Ccb;
295
296 DebugTrace(+1, Dbg, "FatFastUnlockSingle\n", 0);
297
298 IoStatus->Information = 0;
299
300 //
301 // Decode the type of file object we're being asked to process and make sure
302 // it is only a user file open
303 //
304
305 if (FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb ) != UserFileOpen) {
306
307 IoStatus->Status = STATUS_INVALID_PARAMETER;
308
309 DebugTrace(-1, Dbg, "FatFastUnlockSingle -> TRUE (STATUS_INVALID_PARAMETER)\n", 0);
310 return TRUE;
311 }
312
313 //
314 // Acquire exclusive access to the Fcb this operation can always wait
315 //
316
317 FsRtlEnterFileSystem();
318
319 _SEH2_TRY {
320
321 //
322 // We check whether we can proceed based on the state of the file oplocks.
323 //
324
325 if (!FsRtlOplockIsFastIoPossible( &(Fcb)->Specific.Fcb.Oplock )) {
326
327 try_return( Results = FALSE );
328 }
329
330 //
331 // Now call the FsRtl routine to do the actual processing of the
332 // Lock request. The call will always succeed.
333 //
334
335 Results = TRUE;
336 IoStatus->Status = FsRtlFastUnlockSingle( &Fcb->Specific.Fcb.FileLock,
337 FileObject,
338 FileOffset,
339 Length,
340 ProcessId,
341 Key,
342 NULL,
343 FALSE );
344
345 //
346 // Set the flag indicating if Fast I/O is possible
347 //
348
349 Fcb->Header.IsFastIoPossible = FatIsFastIoPossible( Fcb );
350
351 try_exit: NOTHING;
352 } _SEH2_FINALLY {
353
354 DebugUnwind( FatFastUnlockSingle );
355
356 //
357 // Release the Fcb, and return to our caller
358 //
359
360 FsRtlExitFileSystem();
361
362 DebugTrace(-1, Dbg, "FatFastUnlockSingle -> %08lx\n", Results);
363 } _SEH2_END;
364
365 return Results;
366 }
367
368 \f
369 BOOLEAN
370 NTAPI
371 FatFastUnlockAll (
372 IN PFILE_OBJECT FileObject,
373 PEPROCESS ProcessId,
374 OUT PIO_STATUS_BLOCK IoStatus,
375 IN PDEVICE_OBJECT DeviceObject
376 )
377
378 /*++
379
380 Routine Description:
381
382 This is a call back routine for doing the fast unlock all call.
383
384 Arguments:
385
386 FileObject - Supplies the file object used in this operation
387
388 ProcessId - Supplies the process ID used in this operation
389
390 Status - Receives the Status if this operation is successful
391
392 Return Value:
393
394 BOOLEAN - TRUE if this operation completed and FALSE if caller
395 needs to take the long route.
396
397 --*/
398
399 {
400 BOOLEAN Results;
401 PVCB Vcb;
402 PFCB Fcb;
403 PCCB Ccb;
404
405 DebugTrace(+1, Dbg, "FatFastUnlockAll\n", 0);
406
407 IoStatus->Information = 0;
408
409 //
410 // Decode the type of file object we're being asked to process and make sure
411 // it is only a user file open.
412 //
413
414 if (FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb ) != UserFileOpen) {
415
416 IoStatus->Status = STATUS_INVALID_PARAMETER;
417
418 DebugTrace(-1, Dbg, "FatFastUnlockAll -> TRUE (STATUS_INVALID_PARAMETER)\n", 0);
419 return TRUE;
420 }
421
422 //
423 // Acquire exclusive access to the Fcb this operation can always wait
424 //
425
426 FsRtlEnterFileSystem();
427
428 (VOID) ExAcquireResourceSharedLite( Fcb->Header.Resource, TRUE );
429
430 _SEH2_TRY {
431
432 //
433 // We check whether we can proceed based on the state of the file oplocks.
434 //
435
436 if (!FsRtlOplockIsFastIoPossible( &(Fcb)->Specific.Fcb.Oplock )) {
437
438 try_return( Results = FALSE );
439 }
440
441 //
442 // Now call the FsRtl routine to do the actual processing of the
443 // Lock request. The call will always succeed.
444 //
445
446 Results = TRUE;
447 IoStatus->Status = FsRtlFastUnlockAll( &Fcb->Specific.Fcb.FileLock,
448 FileObject,
449 ProcessId,
450 NULL );
451
452 //
453 // Set the flag indicating if Fast I/O is possible
454 //
455
456 Fcb->Header.IsFastIoPossible = FatIsFastIoPossible( Fcb );
457
458 try_exit: NOTHING;
459 } _SEH2_FINALLY {
460
461 DebugUnwind( FatFastUnlockAll );
462
463 //
464 // Release the Fcb, and return to our caller
465 //
466
467 ExReleaseResourceLite( (Fcb)->Header.Resource );
468
469 FsRtlExitFileSystem();
470
471 DebugTrace(-1, Dbg, "FatFastUnlockAll -> %08lx\n", Results);
472 } _SEH2_END;
473
474 return Results;
475 }
476
477 \f
478 BOOLEAN
479 NTAPI
480 FatFastUnlockAllByKey (
481 IN PFILE_OBJECT FileObject,
482 PVOID ProcessId,
483 ULONG Key,
484 OUT PIO_STATUS_BLOCK IoStatus,
485 IN PDEVICE_OBJECT DeviceObject
486 )
487
488 /*++
489
490 Routine Description:
491
492 This is a call back routine for doing the fast unlock all by key call.
493
494 Arguments:
495
496 FileObject - Supplies the file object used in this operation
497
498 ProcessId - Supplies the process ID used in this operation
499
500 Key - Supplies the key used in this operation
501
502 Status - Receives the Status if this operation is successful
503
504 Return Value:
505
506 BOOLEAN - TRUE if this operation completed and FALSE if caller
507 needs to take the long route.
508
509 --*/
510
511 {
512 BOOLEAN Results;
513 PVCB Vcb;
514 PFCB Fcb;
515 PCCB Ccb;
516
517 DebugTrace(+1, Dbg, "FatFastUnlockAllByKey\n", 0);
518
519 IoStatus->Information = 0;
520
521 //
522 // Decode the type of file object we're being asked to process and make sure
523 // it is only a user file open.
524 //
525
526 if (FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb ) != UserFileOpen) {
527
528 IoStatus->Status = STATUS_INVALID_PARAMETER;
529
530 DebugTrace(-1, Dbg, "FatFastUnlockAll -> TRUE (STATUS_INVALID_PARAMETER)\n", 0);
531 return TRUE;
532 }
533
534 //
535 // Acquire exclusive access to the Fcb this operation can always wait
536 //
537
538 FsRtlEnterFileSystem();
539
540 (VOID) ExAcquireResourceSharedLite( Fcb->Header.Resource, TRUE );
541
542 _SEH2_TRY {
543
544 //
545 // We check whether we can proceed based on the state of the file oplocks.
546 //
547
548 if (!FsRtlOplockIsFastIoPossible( &(Fcb)->Specific.Fcb.Oplock )) {
549
550 try_return( Results = FALSE );
551 }
552
553 //
554 // Now call the FsRtl routine to do the actual processing of the
555 // Lock request. The call will always succeed.
556 //
557
558 Results = TRUE;
559 IoStatus->Status = FsRtlFastUnlockAllByKey( &Fcb->Specific.Fcb.FileLock,
560 FileObject,
561 ProcessId,
562 Key,
563 NULL );
564
565 //
566 // Set the flag indicating if Fast I/O is possible
567 //
568
569 Fcb->Header.IsFastIoPossible = FatIsFastIoPossible( Fcb );
570
571 try_exit: NOTHING;
572 } _SEH2_FINALLY {
573
574 DebugUnwind( FatFastUnlockAllByKey );
575
576 //
577 // Release the Fcb, and return to our caller
578 //
579
580 ExReleaseResourceLite( (Fcb)->Header.Resource );
581
582 FsRtlExitFileSystem();
583
584 DebugTrace(-1, Dbg, "FatFastUnlockAllByKey -> %08lx\n", Results);
585 } _SEH2_END;
586
587 return Results;
588 }
589
590 \f
591 NTSTATUS
592 FatCommonLockControl (
593 IN PIRP_CONTEXT IrpContext,
594 IN PIRP Irp
595 )
596
597 /*++
598
599 Routine Description:
600
601 This is the common routine for doing Lock control operations called
602 by both the fsd and fsp threads
603
604 Arguments:
605
606 Irp - Supplies the Irp to process
607
608 Return Value:
609
610 NTSTATUS - The return status for the operation
611
612 --*/
613
614 {
615 NTSTATUS Status;
616 PIO_STACK_LOCATION IrpSp;
617
618 TYPE_OF_OPEN TypeOfOpen;
619
620 PVCB Vcb;
621 PFCB Fcb;
622 PCCB Ccb;
623
624 BOOLEAN OplockPostIrp = FALSE;
625
626 //
627 // Get a pointer to the current Irp stack location
628 //
629
630 IrpSp = IoGetCurrentIrpStackLocation( Irp );
631
632 DebugTrace(+1, Dbg, "FatCommonLockControl\n", 0);
633 DebugTrace( 0, Dbg, "Irp = %08lx\n", Irp);
634 DebugTrace( 0, Dbg, "MinorFunction = %08lx\n", IrpSp->MinorFunction);
635
636 //
637 // Decode the type of file object we're being asked to process
638 //
639
640 TypeOfOpen = FatDecodeFileObject( IrpSp->FileObject, &Vcb, &Fcb, &Ccb );
641
642 //
643 // If the file is not a user file open then we reject the request
644 // as an invalid parameter
645 //
646
647 if (TypeOfOpen != UserFileOpen) {
648
649 FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );
650
651 DebugTrace(-1, Dbg, "FatCommonLockControl -> STATUS_INVALID_PARAMETER\n", 0);
652 return STATUS_INVALID_PARAMETER;
653 }
654
655 //
656 // Acquire exclusive access to the Fcb and enqueue the Irp if we didn't
657 // get access
658 //
659
660 if (!FatAcquireSharedFcb( IrpContext, Fcb )) {
661
662 Status = FatFsdPostRequest( IrpContext, Irp );
663
664 DebugTrace(-1, Dbg, "FatCommonLockControl -> %08lx\n", Status);
665 return Status;
666 }
667
668 _SEH2_TRY {
669
670 //
671 // We check whether we can proceed
672 // based on the state of the file oplocks.
673 //
674
675 Status = FsRtlCheckOplock( &Fcb->Specific.Fcb.Oplock,
676 Irp,
677 IrpContext,
678 FatOplockComplete,
679 NULL );
680
681 if (Status != STATUS_SUCCESS) {
682
683 OplockPostIrp = TRUE;
684 try_return( NOTHING );
685 }
686
687 //
688 // Now call the FsRtl routine to do the actual processing of the
689 // Lock request
690 //
691
692 Status = FsRtlProcessFileLock( &Fcb->Specific.Fcb.FileLock, Irp, NULL );
693
694 //
695 // Set the flag indicating if Fast I/O is possible
696 //
697
698 Fcb->Header.IsFastIoPossible = FatIsFastIoPossible( Fcb );
699
700 try_exit: NOTHING;
701 } _SEH2_FINALLY {
702
703 DebugUnwind( FatCommonLockControl );
704
705 //
706 // Only if this is not an abnormal termination do we delete the
707 // irp context
708 //
709
710 if (!_SEH2_AbnormalTermination() && !OplockPostIrp) {
711
712 FatCompleteRequest( IrpContext, FatNull, 0 );
713 }
714
715 //
716 // Release the Fcb, and return to our caller
717 //
718
719 FatReleaseFcb( IrpContext, Fcb );
720
721 DebugTrace(-1, Dbg, "FatCommonLockControl -> %08lx\n", Status);
722 } _SEH2_END;
723
724 return Status;
725 }
726