2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/fsrtl/filelock.c
5 * PURPOSE: File Locking implementation for File System Drivers
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
15 /* GLOBALS *******************************************************************/
17 PAGED_LOOKASIDE_LIST FsRtlFileLockLookasideList
;
19 /* PRIVATE FUNCTIONS *********************************************************/
23 FsRtlCompleteLockIrpReal(IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteRoutine
,
27 OUT PNTSTATUS NewStatus
,
28 IN PFILE_OBJECT FileObject OPTIONAL
)
30 /* Check if we have a complete routine */
33 /* Check if we have a file object */
34 if (FileObject
) FileObject
->LastLock
= NULL
;
36 /* Set the I/O Status and do completion */
37 Irp
->IoStatus
.Status
= Status
;
38 *NewStatus
= CompleteRoutine(Context
, Irp
);
42 /* Otherwise do a normal I/O complete request */
43 FsRtlCompleteRequest(Irp
, Status
);
48 /* PUBLIC FUNCTIONS **********************************************************/
55 FsRtlGetNextFileLock(IN PFILE_LOCK FileLock
,
58 KeBugCheck(FILE_SYSTEM
);
67 FsRtlPrivateLock(IN PFILE_LOCK FileLock
,
68 IN PFILE_OBJECT FileObject
,
69 IN PLARGE_INTEGER FileOffset
,
70 IN PLARGE_INTEGER Length
,
73 IN BOOLEAN FailImmediately
,
74 IN BOOLEAN ExclusiveLock
,
75 OUT PIO_STATUS_BLOCK IoStatus
,
77 IN PVOID Context OPTIONAL
,
78 IN BOOLEAN AlreadySynchronized
)
83 if (!Warn
++) DPRINT1("FsRtlPrivateLock() is stubplemented!\n");
85 /* Initialize the lock, if necessary */
86 if (!FileLock
->LockInformation
)
88 DPRINT("LockInformation is uninitialized!\n");
91 /* Assume all is cool, and lock is set */
92 IoStatus
->Status
= STATUS_SUCCESS
;
96 /* Complete the request */
97 FsRtlCompleteLockIrpReal(FileLock
->CompleteLockIrpRoutine
,
104 /* Update the status */
105 IoStatus
->Status
= Status
;
116 FsRtlCheckLockForReadAccess(IN PFILE_LOCK FileLock
,
119 KeBugCheck(FILE_SYSTEM
);
128 FsRtlCheckLockForWriteAccess(IN PFILE_LOCK FileLock
,
131 KeBugCheck(FILE_SYSTEM
);
140 FsRtlFastCheckLockForRead(IN PFILE_LOCK FileLock
,
141 IN PLARGE_INTEGER FileOffset
,
142 IN PLARGE_INTEGER Length
,
144 IN PFILE_OBJECT FileObject
,
147 KeBugCheck(FILE_SYSTEM
);
156 FsRtlFastCheckLockForWrite(IN PFILE_LOCK FileLock
,
157 IN PLARGE_INTEGER FileOffset
,
158 IN PLARGE_INTEGER Length
,
160 IN PFILE_OBJECT FileObject
,
163 KeBugCheck(FILE_SYSTEM
);
172 FsRtlFastUnlockSingle(IN PFILE_LOCK FileLock
,
173 IN PFILE_OBJECT FileObject
,
174 IN PLARGE_INTEGER FileOffset
,
175 IN PLARGE_INTEGER Length
,
176 IN PEPROCESS Process
,
178 IN PVOID Context OPTIONAL
,
179 IN BOOLEAN AlreadySynchronized
)
182 if (!Warn
++) DPRINT1("FsRtlFastUnlockSingle() is stubplemented!\n");
184 return STATUS_SUCCESS
;
192 FsRtlFastUnlockAll(IN PFILE_LOCK FileLock
,
193 IN PFILE_OBJECT FileObject
,
194 IN PEPROCESS Process
,
195 IN PVOID Context OPTIONAL
)
197 KeBugCheck(FILE_SYSTEM
);
198 return STATUS_UNSUCCESSFUL
;
206 FsRtlFastUnlockAllByKey(IN PFILE_LOCK FileLock
,
207 IN PFILE_OBJECT FileObject
,
208 IN PEPROCESS Process
,
210 IN PVOID Context OPTIONAL
)
212 KeBugCheck(FILE_SYSTEM
);
213 return STATUS_UNSUCCESSFUL
;
221 FsRtlProcessFileLock(IN PFILE_LOCK FileLock
,
223 IN PVOID Context OPTIONAL
)
225 PIO_STACK_LOCATION IoStackLocation
;
227 IO_STATUS_BLOCK IoStatusBlock
;
229 /* Get the I/O Stack location */
230 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
231 ASSERT(IoStackLocation
->MajorFunction
== IRP_MJ_LOCK_CONTROL
);
233 /* Clear the I/O status block and check what function this is */
234 IoStatusBlock
.Information
= 0;
235 switch(IoStackLocation
->MinorFunction
)
240 /* Call the private lock routine */
241 FsRtlPrivateLock(FileLock
,
242 IoStackLocation
->FileObject
,
244 Parameters
.LockControl
.ByteOffset
,
245 IoStackLocation
->Parameters
.LockControl
.Length
,
246 IoGetRequestorProcess(Irp
),
247 IoStackLocation
->Parameters
.LockControl
.Key
,
248 IoStackLocation
->Flags
& SL_FAIL_IMMEDIATELY
,
249 IoStackLocation
->Flags
& SL_EXCLUSIVE_LOCK
,
256 /* A single unlock */
257 case IRP_MN_UNLOCK_SINGLE
:
259 /* Call fast unlock */
260 IoStatusBlock
.Status
=
261 FsRtlFastUnlockSingle(FileLock
,
262 IoStackLocation
->FileObject
,
263 &IoStackLocation
->Parameters
.LockControl
.
265 IoStackLocation
->Parameters
.LockControl
.
267 IoGetRequestorProcess(Irp
),
268 IoStackLocation
->Parameters
.LockControl
.
273 /* Complete the IRP */
274 FsRtlCompleteLockIrpReal(FileLock
->CompleteLockIrpRoutine
,
277 IoStatusBlock
.Status
,
283 case IRP_MN_UNLOCK_ALL
:
285 /* Do a fast unlock */
286 IoStatusBlock
.Status
= FsRtlFastUnlockAll(FileLock
,
289 IoGetRequestorProcess(Irp
),
292 /* Complete the IRP */
293 FsRtlCompleteLockIrpReal(FileLock
->CompleteLockIrpRoutine
,
296 IoStatusBlock
.Status
,
302 case IRP_MN_UNLOCK_ALL_BY_KEY
:
305 IoStatusBlock
.Status
=
306 FsRtlFastUnlockAllByKey(FileLock
,
307 IoStackLocation
->FileObject
,
308 IoGetRequestorProcess(Irp
),
309 IoStackLocation
->Parameters
.
313 /* Complete the IRP */
314 FsRtlCompleteLockIrpReal(FileLock
->CompleteLockIrpRoutine
,
317 IoStatusBlock
.Status
,
322 /* Invalid request */
326 FsRtlCompleteRequest(Irp
, STATUS_INVALID_DEVICE_REQUEST
);
327 IoStatusBlock
.Status
= STATUS_INVALID_DEVICE_REQUEST
;
331 /* Return the status */
332 return IoStatusBlock
.Status
;
340 FsRtlInitializeFileLock (IN PFILE_LOCK FileLock
,
341 IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL
,
342 IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL
)
345 FileLock
->FastIoIsQuestionable
= FALSE
;
346 FileLock
->CompleteLockIrpRoutine
= CompleteLockIrpRoutine
;
347 FileLock
->UnlockRoutine
= UnlockRoutine
;
348 FileLock
->LockInformation
= NULL
;
356 FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock
)
366 FsRtlAllocateFileLock(IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL
,
367 IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL
)
371 /* Try to allocate it */
372 FileLock
= ExAllocateFromPagedLookasideList(&FsRtlFileLockLookasideList
);
376 FsRtlInitializeFileLock(FileLock
,
377 CompleteLockIrpRoutine
,
381 /* Return the lock */
390 FsRtlFreeFileLock(IN PFILE_LOCK FileLock
)
392 /* Uninitialize and free the lock */
393 FsRtlUninitializeFileLock(FileLock
);
394 ExFreeToPagedLookasideList(&FsRtlFileLockLookasideList
, FileLock
);