ReactOS 0.4.17-dev-1321-g5c122a9
lockctrl.cpp
Go to the documentation of this file.
1
2// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3// All rights reserved
4// This file was released under the GPLv2 on June 2015.
6/*************************************************************************
7*
8* File: LockCtrl.cpp.cpp
9*
10* Module: UDF File System Driver (Kernel mode execution only)
11*
12* Description:
13* Contains code to handle the "byte-range locking" dispatch entry point.
14*
15*************************************************************************/
16
17#include "udffs.h"
18
19// define the file specific bug-check id
20#define UDF_BUG_CHECK_ID UDF_FILE_SHUTDOWN
21
22
23/*************************************************************************
24*
25* Function: UDFLockControl()
26*
27* Description:
28*
29* Expected Interrupt Level (for execution) :
30*
31* IRQL_PASSIVE_LEVEL
32*
33* Return Value: Irrelevant.
34*
35*************************************************************************/
39 IN PDEVICE_OBJECT DeviceObject, // the logical volume device object
40 IN PIRP Irp) // I/O Request Packet
41{
43 PtrUDFIrpContext PtrIrpContext = NULL;
44 BOOLEAN AreWeTopLevel = FALSE;
45
46 UDFPrint(("UDFLockControl\n"));
47// BrutePoint();
48
51 ASSERT(Irp);
52
53 // set the top level context
54 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
55 // Call the common Lock Control routine, with blocking allowed if
56 // synchronous
57 _SEH2_TRY {
58
59 // get an IRP context structure and issue the request
60 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
61 if(PtrIrpContext) {
62 RC = UDFCommonLockControl(PtrIrpContext, Irp);
63 } else {
65 Irp->IoStatus.Status = RC;
66 Irp->IoStatus.Information = 0;
67 // complete the IRP
69 }
70
72
73 RC = UDFExceptionHandler(PtrIrpContext, Irp);
74
76 } _SEH2_END;
77
78 if (AreWeTopLevel) {
80 }
81
83
84 return(RC);
85} // end UDFLockControl()
86
87
88/*************************************************************************
89*
90* Function: UDFCommonLockControl()
91*
92* Description:
93* This is the common routine for doing Lock control operations called
94* by both the fsd and fsp threads
95*
96* Expected Interrupt Level (for execution) :
97*
98* IRQL_PASSIVE_LEVEL
99*
100* Return Value: Irrelevant
101*
102*************************************************************************/
104NTAPI
106 IN PtrUDFIrpContext PtrIrpContext,
107 IN PIRP Irp)
108{
111 //IO_STATUS_BLOCK LocalIoStatus;
112// BOOLEAN CompleteRequest = FALSE;
113 BOOLEAN PostRequest = FALSE;
114 BOOLEAN CanWait = FALSE;
116 BOOLEAN AcquiredFCB = FALSE;
120
121 UDFPrint(("UDFCommonLockControl\n"));
122
123 _SEH2_TRY {
124 // First, get a pointer to the current I/O stack location.
126 ASSERT(IrpSp);
127
130
131 // Get the FCB and CCB pointers.
132 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
133 ASSERT(Ccb);
134 Fcb = Ccb->Fcb;
135 ASSERT(Fcb);
136 // Validate the sent-in FCB
137 if ( (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) ||
138 (Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
139
140// CompleteRequest = TRUE;
142 }
143
144 NtReqFcb = Fcb->NTRequiredFCB;
145 CanWait = ((PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE);
146
147 // Acquire the FCB resource shared
149 if (!UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), CanWait)) {
150 PostRequest = TRUE;
152 }
153 AcquiredFCB = TRUE;
154
155 RC = FsRtlProcessFileLock(&(NtReqFcb->FileLock), Irp, NULL);
156// CompleteRequest = TRUE;
157
158try_exit: NOTHING;
159
160 } _SEH2_FINALLY {
161
162 // Release the FCB resources if acquired.
163 if (AcquiredFCB) {
165 UDFReleaseResource(&(NtReqFcb->MainResource));
166 AcquiredFCB = FALSE;
167 }
168 if (PostRequest) {
169 // Perform appropriate post related processing here
170 RC = UDFPostRequest(PtrIrpContext, Irp);
171 } else
173 // Simply free up the IrpContext since the IRP has been queued or
174 // Completed by FsRtlProcessFileLock
175 UDFReleaseIrpContext(PtrIrpContext);
176 }
177 } _SEH2_END; // end of "__finally" processing
178
179 return(RC);
180} // end UDFCommonLockControl()
181
182
183/*
184Routine Description:
185 This is a call back routine for doing the fast lock call.
186Arguments:
187 FileObject - Supplies the file object used in this operation
188 FileOffset - Supplies the file offset used in this operation
189 Length - Supplies the length used in this operation
190 ProcessId - Supplies the process ID used in this operation
191 Key - Supplies the key used in this operation
192 FailImmediately - Indicates if the request should fail immediately
193 if the lock cannot be granted.
194 ExclusiveLock - Indicates if this is a request for an exclusive or
195 shared lock
196 IoStatus - Receives the Status if this operation is successful
197
198Return Value:
199 BOOLEAN - TRUE if this operation completed and FALSE if caller
200 needs to take the long route.
201*/
202
204NTAPI
210 ULONG Key,
215 )
216{
218
219// BOOLEAN AcquiredFCB = FALSE;
222
223 UDFPrint(("UDFFastLock\n"));
224 // Decode the type of file object we're being asked to process and make
225 // sure it is only a user file open.
226
227
228 // Get the FCB and CCB pointers.
229 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
230 ASSERT(Ccb);
231 Fcb = Ccb->Fcb;
232 ASSERT(Fcb);
233 // Validate the sent-in FCB
234 if ( (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) ||
235 (Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
236
238 IoStatus->Information = 0;
239 return TRUE;
240 }
241
242 // Acquire exclusive access to the Fcb this operation can always wait
243
245
246 // BUGBUG: kenr
247 // (VOID) ExAcquireResourceShared( Fcb->Header.Resource, TRUE );
248
249 _SEH2_TRY {
250
251 // We check whether we can proceed
252 // based on the state of the file oplocks.
253
254 // Now call the FsRtl routine to do the actual processing of the
255 // Lock request
256 if ((Results = FsRtlFastLock( &(Fcb->NTRequiredFCB->FileLock),
259 Length,
260 ProcessId,
261 Key,
264 IoStatus,
265 NULL,
266 FALSE ))) {
267
268 // Set the flag indicating if Fast I/O is possible
269 Fcb->NTRequiredFCB->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible(Fcb);
270 }
271
272//try_exit: NOTHING;
273 } _SEH2_FINALLY {
274
275 // Release the Fcb, and return to our caller
276
277 // BUGBUG: kenr
278 // UDFReleaseResource( (Fcb)->Header.Resource );
279
281
282 } _SEH2_END;
283
284 return Results;
285} // end UDFFastLock()
286
287
288/*
289Routine Description:
290
291 This is a call back routine for doing the fast unlock single call.
292
293Arguments:
294
295 FileObject - Supplies the file object used in this operation
296 FileOffset - Supplies the file offset used in this operation
297 Length - Supplies the length used in this operation
298 ProcessId - Supplies the process ID used in this operation
299 Key - Supplies the key used in this operation
300 Status - Receives the Status if this operation is successful
301
302Return Value:
303
304 BOOLEAN - TRUE if this operation completed and FALSE if caller
305 needs to take the long route.
306*/
308NTAPI
314 ULONG Key,
317 )
318
319{
321
322// BOOLEAN AcquiredFCB = FALSE;
325
326 UDFPrint(("UDFFastUnlockSingle\n"));
327 // Decode the type of file object we're being asked to process and make
328 // sure it is only a user file open.
329
330 IoStatus->Information = 0;
331
332 // Get the FCB and CCB pointers.
333 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
334 ASSERT(Ccb);
335 Fcb = Ccb->Fcb;
336 ASSERT(Fcb);
337 // Validate the sent-in FCB
338 if ( (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) ||
339 (Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
340
342 return TRUE;
343 }
344
345 // Acquire exclusive access to the Fcb this operation can always wait
346
348
349 // BUGBUG: kenr
350 // (VOID) ExAcquireResourceShared( Fcb->Header.Resource, TRUE );
351
352 _SEH2_TRY {
353
354 // We check whether we can proceed
355 // based on the state of the file oplocks.
356
357 // Now call the FsRtl routine to do the actual processing of the
358 // Lock request
359 Results = TRUE;
360 IoStatus->Status = FsRtlFastUnlockSingle( &(Fcb->NTRequiredFCB->FileLock),
363 Length,
364 ProcessId,
365 Key,
366 NULL,
367 FALSE );
368 // Set the flag indicating if Fast I/O is possible
369 Fcb->NTRequiredFCB->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible(Fcb);
370
371//try_exit: NOTHING;
372 } _SEH2_FINALLY {
373
374 // Release the Fcb, and return to our caller
375
376 // BUGBUG: kenr
377 // UDFReleaseResource( (Fcb)->Header.Resource );
378
380
381 } _SEH2_END;
382
383 return Results;
384} // end UDFFastUnlockSingle()
385
386
387/*
388Routine Description:
389
390 This is a call back routine for doing the fast unlock all call.
391
392Arguments:
393 FileObject - Supplies the file object used in this operation
394 ProcessId - Supplies the process ID used in this operation
395 Status - Receives the Status if this operation is successful
396
397Return Value:
398
399 BOOLEAN - TRUE if this operation completed and FALSE if caller
400 needs to take the long route.
401*/
403NTAPI
409 )
410
411{
413
414// BOOLEAN AcquiredFCB = FALSE;
417
418 UDFPrint(("UDFFastUnlockAll\n"));
419
420 IoStatus->Information = 0;
421 // Decode the type of file object we're being asked to process and make
422 // sure it is only a user file open.
423
424 // Get the FCB and CCB pointers.
425 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
426 ASSERT(Ccb);
427 Fcb = Ccb->Fcb;
428 ASSERT(Fcb);
429 // Validate the sent-in FCB
430 if ( (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) ||
431 (Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
432
434 return TRUE;
435 }
436
437 // Acquire shared access to the Fcb this operation can always wait
438
440
441 UDF_CHECK_PAGING_IO_RESOURCE(Fcb->NTRequiredFCB);
442 UDFAcquireResourceShared( &(Fcb->NTRequiredFCB->MainResource),TRUE );
443
444 _SEH2_TRY {
445
446 // We check whether we can proceed
447 // based on the state of the file oplocks.
448
449 // Now call the FsRtl routine to do the actual processing of the
450 // Lock request
451 Results = TRUE;
452 IoStatus->Status = FsRtlFastUnlockAll( &(Fcb->NTRequiredFCB->FileLock),
454 ProcessId,
455 NULL );
456
457 // Set the flag indicating if Fast I/O is questionable
458
459 Fcb->NTRequiredFCB->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible( Fcb );
460
461//try_exit: NOTHING;
462 } _SEH2_FINALLY {
463
464 // Release the Fcb, and return to our caller
465
466 UDF_CHECK_PAGING_IO_RESOURCE(Fcb->NTRequiredFCB);
467 UDFReleaseResource(&(Fcb->NTRequiredFCB->MainResource));
469
470 } _SEH2_END;
471
472 return Results;
473} // end UDFFastUnlockAll()
474
475
476/*
477Routine Description:
478
479 This is a call back routine for doing the fast unlock all call.
480
481Arguments:
482 FileObject - Supplies the file object used in this operation
483 ProcessId - Supplies the process ID used in this operation
484 Status - Receives the Status if this operation is successful
485
486Return Value:
487
488 BOOLEAN - TRUE if this operation completed and FALSE if caller
489 needs to take the long route.
490*/
491
493NTAPI
497 ULONG Key,
500 )
501
502{
504
505// BOOLEAN AcquiredFCB = FALSE;
508
509 UDFPrint(("UDFFastUnlockAllByKey\n"));
510
511 IoStatus->Information = 0;
512 // Decode the type of file object we're being asked to process and make
513 // sure it is only a user file open.
514
515 // Get the FCB and CCB pointers.
516 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
517 ASSERT(Ccb);
518 Fcb = Ccb->Fcb;
519 ASSERT(Fcb);
520 // Validate the sent-in FCB
521 if ( (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) ||
522 (Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
523
525 return TRUE;
526 }
527
528 // Acquire shared access to the Fcb this operation can always wait
529
531
532 UDF_CHECK_PAGING_IO_RESOURCE(Fcb->NTRequiredFCB);
533 UDFAcquireResourceShared( &(Fcb->NTRequiredFCB->MainResource),TRUE );
534
535 _SEH2_TRY {
536
537 // We check whether we can proceed
538 // based on the state of the file oplocks.
539
540 // Now call the FsRtl routine to do the actual processing of the
541 // Lock request
542 Results = TRUE;
543 IoStatus->Status = FsRtlFastUnlockAllByKey( &(Fcb->NTRequiredFCB->FileLock),
545 ProcessId,
546 Key,
547 NULL );
548
549 // Set the flag indicating if Fast I/O is possible
550
551 Fcb->NTRequiredFCB->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible( Fcb );
552
553//try_exit: NOTHING;
554 } _SEH2_FINALLY {
555
556 // Release the Fcb, and return to our caller
557
558 UDF_CHECK_PAGING_IO_RESOURCE(Fcb->NTRequiredFCB);
559 UDFReleaseResource(&(Fcb->NTRequiredFCB->MainResource));
561
562 } _SEH2_END;
563
564 return Results;
565} // end UDFFastUnlockAllByKey()
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
#define try_return(S)
Definition: cdprocs.h:2179
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4138
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
BOOLEAN __fastcall UDFIsIrpTopLevel(PIRP Irp)
Definition: misc.cpp:228
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
NTSTATUS UDFPostRequest(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: misc.cpp:1128
PtrUDFIrpContext UDFAllocateIrpContext(PIRP Irp, PDEVICE_OBJECT PtrTargetDeviceObject)
Definition: misc.cpp:985
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
#define UDFAcquireResourceShared(Resource, CanWait)
Definition: env_spec_w32.h:658
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
FAST_IO_POSSIBLE NTAPI UDFIsFastIoPossible(IN PtrUDFFCB Fcb)
Definition: fastio.cpp:118
#define NtReqFcb
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG BOOLEAN BOOLEAN ExclusiveLock
Definition: fatprocs.h:2715
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG BOOLEAN FailImmediately
Definition: fatprocs.h:2714
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2712
NTSTATUS NTAPI FsRtlFastUnlockSingle(IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN PEPROCESS Process, IN ULONG Key, IN PVOID Context OPTIONAL, IN BOOLEAN AlreadySynchronized)
Definition: filelock.c:827
NTSTATUS NTAPI FsRtlProcessFileLock(IN PFILE_LOCK FileLock, IN PIRP Irp, IN PVOID Context OPTIONAL)
Definition: filelock.c:1156
NTSTATUS NTAPI FsRtlFastUnlockAll(IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS Process, IN PVOID Context OPTIONAL)
Definition: filelock.c:1027
NTSTATUS NTAPI FsRtlFastUnlockAllByKey(IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS Process, IN ULONG Key, IN PVOID Context OPTIONAL)
Definition: filelock.c:1090
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
#define FsRtlFastLock(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)
Definition: fsrtlfuncs.h:1581
#define NOTHING
Definition: input_list.c:10
_In_ PIRP Irp
Definition: kse.h:79
macro TEXTAREA section xr p2align endm macro DATAAREA section dw endm macro RODATAAREA section dr endm macro EXPORT Attribute global Name endm macro IMPORT Target ifc WEAK weak Name set Target endif endm set macro SET_COMDAT_ALIGNMENT Alignment set Alignment endm macro NESTED_ENTRY Name global Name p2align xr p2align __ComdatAlignment NESTED_ENTRY Name endm macro ALTERNATE_ENTRY Name global Name Results
Definition: kxarm64.h:154
BOOLEAN NTAPI UDFFastUnlockSingle(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: lockctrl.cpp:309
NTSTATUS NTAPI UDFLockControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: lockctrl.cpp:38
NTSTATUS NTAPI UDFCommonLockControl(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: lockctrl.cpp:105
BOOLEAN NTAPI UDFFastLock(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, BOOLEAN FailImmediately, BOOLEAN ExclusiveLock, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: lockctrl.cpp:205
BOOLEAN NTAPI UDFFastUnlockAllByKey(IN PFILE_OBJECT FileObject, PEPROCESS ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: lockctrl.cpp:494
BOOLEAN NTAPI UDFFastUnlockAll(IN PFILE_OBJECT FileObject, PEPROCESS ProcessId, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: lockctrl.cpp:404
#define ASSERT(a)
Definition: mode.c:44
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define IoCompleteRequest
Definition: irp.c:1272
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2032
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:205
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_FINALLY
Definition: pseh2_64.h:153
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:203
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define STATUS_SUCCESS
Definition: shellext.h:65
#define UDF_IRP_CONTEXT_CAN_BLOCK
Definition: struct.h:385
struct _UDFContextControlBlock * PtrUDFCCB
#define UDF_NODE_TYPE_VCB
Definition: struct.h:61
#define UDF_FCB_DIRECTORY
Definition: struct.h:303
FILE_LOCK FileLock
Definition: fatstruc.h:1071
struct _FCB::@927::@930 Fcb
ERESOURCE MainResource
Definition: ntfs.h:607
PFILE_OBJECT FileObject
Definition: iotypes.h:3184
#define STATUS_PENDING
Definition: telnetd.h:14
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define UDF_CHECK_PAGING_IO_RESOURCE(NTReqFCB)
Definition: udffs.h:260
#define UDFPrint(Args)
Definition: udffs.h:223
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IO_DISK_INCREMENT
Definition: iotypes.h:600