2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSLockControl.cpp
39 #include "AFSCommon.h"
42 AFSLockControl( IN PDEVICE_OBJECT LibDeviceObject,
46 UNREFERENCED_PARAMETER(LibDeviceObject);
47 NTSTATUS ntStatus = STATUS_SUCCESS;
48 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
51 BOOLEAN bCompleteRequest = TRUE;
52 AFSByteRangeLockRequestCB stLockRequestCB;
53 AFSByteRangeLockResultCB stLockResultCB;
54 AFSByteRangeUnlockRequestCB stUnlockRequestCB;
55 AFSByteRangeUnlockResultCB stUnlockResultCB;
56 ULONG ulResultLen = 0;
57 BOOLEAN bReleaseResource = FALSE;
58 IO_STATUS_BLOCK stIoStatus;
63 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
65 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
70 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
71 AFS_TRACE_LEVEL_ERROR,
72 "AFSLockControl Attempted access (%p) when pFcb == NULL\n",
75 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
79 // Acquire the main shared for adding the lock control to the list
82 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
83 AFS_TRACE_LEVEL_VERBOSE,
84 "AFSLockControl Acquiring Fcb lock %p SHARED %08lX\n",
85 &pFcb->NPFcb->Resource,
86 PsGetCurrentThread()));
88 AFSAcquireShared( &pFcb->NPFcb->Resource,
91 bReleaseResource = TRUE;
93 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
96 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
97 AFS_TRACE_LEVEL_ERROR,
98 "AFSLockControl Failing request against PIOCtl Fcb\n"));
100 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
102 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
105 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
106 AFS_TRACE_LEVEL_ERROR,
107 "AFSLockControl Failing request against SpecialShare Fcb\n"));
109 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
111 else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
114 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
115 AFS_TRACE_LEVEL_ERROR,
116 "AFSLockControl Failing request against Invalid Fcb\n"));
118 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
122 // Post the request to the service for checks
125 switch( pIrpSp->MinorFunction)
131 stLockRequestCB.Count = 1;
133 stLockRequestCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
135 stLockRequestCB.Request[ 0].LockType = AFS_BYTE_RANGE_LOCK_TYPE_EXCL;
137 stLockRequestCB.Request[ 0].Offset = pIrpSp->Parameters.LockControl.ByteOffset;
139 stLockRequestCB.Request[ 0].Length.QuadPart = pIrpSp->Parameters.LockControl.Length->QuadPart;
141 ulResultLen = sizeof( AFSByteRangeLockResultCB);
143 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_BYTE_RANGE_LOCK,
144 AFS_REQUEST_FLAG_SYNCHRONOUS,
146 &pCcb->DirectoryCB->NameInformation.FileName,
147 &pFcb->ObjectInformation->FileId,
148 pFcb->ObjectInformation->VolumeCB->VolumeInformation.Cell,
149 pFcb->ObjectInformation->VolumeCB->VolumeInformation.CellLength,
151 sizeof( AFSByteRangeLockRequestCB),
155 if( !NT_SUCCESS( ntStatus))
158 try_return( ntStatus);
164 case IRP_MN_UNLOCK_ALL:
165 case IRP_MN_UNLOCK_ALL_BY_KEY:
168 // Flush data and then release the locks on the file server
171 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
172 AFS_TRACE_LEVEL_VERBOSE,
173 "AFSLockControl Acquiring Fcb SectionObject lock %p SHARED %08lX\n",
174 &pFcb->NPFcb->SectionObjectResource,
175 PsGetCurrentThread()));
177 AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
183 CcFlushCache( &pFcb->NPFcb->SectionObjectPointers,
188 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
191 ntStatus = GetExceptionCode();
195 "EXCEPTION - AFSLockControl CcFlushCache failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
196 pFcb->ObjectInformation->FileId.Cell,
197 pFcb->ObjectInformation->FileId.Volume,
198 pFcb->ObjectInformation->FileId.Vnode,
199 pFcb->ObjectInformation->FileId.Unique,
203 if( !NT_SUCCESS( stIoStatus.Status))
206 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
207 AFS_TRACE_LEVEL_ERROR,
208 "AFSLockControl CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
209 pFcb->ObjectInformation->FileId.Cell,
210 pFcb->ObjectInformation->FileId.Volume,
211 pFcb->ObjectInformation->FileId.Vnode,
212 pFcb->ObjectInformation->FileId.Unique,
214 stIoStatus.Information));
216 ntStatus = stIoStatus.Status;
219 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
220 AFS_TRACE_LEVEL_VERBOSE,
221 "AFSLockControl Releasing Fcb SectionObject lock %p SHARED %08lX\n",
222 &pFcb->NPFcb->SectionObjectResource,
223 PsGetCurrentThread()));
225 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
227 RtlZeroMemory( &stUnlockRequestCB,
228 sizeof( AFSByteRangeUnlockRequestCB));
230 stUnlockRequestCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
232 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK_ALL,
233 AFS_REQUEST_FLAG_SYNCHRONOUS,
235 &pCcb->DirectoryCB->NameInformation.FileName,
236 &pFcb->ObjectInformation->FileId,
237 pFcb->ObjectInformation->VolumeCB->VolumeInformation.Cell,
238 pFcb->ObjectInformation->VolumeCB->VolumeInformation.CellLength,
239 (void *)&stUnlockRequestCB,
240 sizeof( AFSByteRangeUnlockRequestCB),
245 // Even on a failure we need to notify the rtl package of the unlock
251 case IRP_MN_UNLOCK_SINGLE:
254 // Flush the data and then release the file server locks
257 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
258 AFS_TRACE_LEVEL_VERBOSE,
259 "AFSLockControl Acquiring Fcb SectionObject lock %p SHARED %08lX\n",
260 &pFcb->NPFcb->SectionObjectResource,
261 PsGetCurrentThread()));
263 AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
269 CcFlushCache( &pFcb->NPFcb->SectionObjectPointers,
270 &pIrpSp->Parameters.LockControl.ByteOffset,
271 pIrpSp->Parameters.LockControl.Length->LowPart,
274 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
277 ntStatus = GetExceptionCode();
281 "EXCEPTION - AFSLockControl CcFlushCache failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
282 pFcb->ObjectInformation->FileId.Cell,
283 pFcb->ObjectInformation->FileId.Volume,
284 pFcb->ObjectInformation->FileId.Vnode,
285 pFcb->ObjectInformation->FileId.Unique,
289 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
290 AFS_TRACE_LEVEL_VERBOSE,
291 "AFSLockControl Releasing Fcb SectionObject lock %p SHARED %08lX\n",
292 &pFcb->NPFcb->SectionObjectResource,
293 PsGetCurrentThread()));
295 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
297 if( !NT_SUCCESS( stIoStatus.Status))
300 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
301 AFS_TRACE_LEVEL_ERROR,
302 "AFSLockControl CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
303 pFcb->ObjectInformation->FileId.Cell,
304 pFcb->ObjectInformation->FileId.Volume,
305 pFcb->ObjectInformation->FileId.Vnode,
306 pFcb->ObjectInformation->FileId.Unique,
308 stIoStatus.Information));
310 ntStatus = stIoStatus.Status;
313 stUnlockRequestCB.Count = 1;
315 stUnlockRequestCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
317 stUnlockRequestCB.Request[ 0].LockType = AFS_BYTE_RANGE_LOCK_TYPE_EXCL;
319 stUnlockRequestCB.Request[ 0].Offset = pIrpSp->Parameters.LockControl.ByteOffset;
321 stUnlockRequestCB.Request[ 0].Length.QuadPart = pIrpSp->Parameters.LockControl.Length->QuadPart;
323 ulResultLen = sizeof( AFSByteRangeUnlockResultCB);
325 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK,
326 AFS_REQUEST_FLAG_SYNCHRONOUS,
328 &pCcb->DirectoryCB->NameInformation.FileName,
329 &pFcb->ObjectInformation->FileId,
330 pFcb->ObjectInformation->VolumeCB->VolumeInformation.Cell,
331 pFcb->ObjectInformation->VolumeCB->VolumeInformation.CellLength,
332 (void *)&stUnlockRequestCB,
333 sizeof( AFSByteRangeUnlockRequestCB),
334 (void *)&stUnlockResultCB,
346 // Below here we won't complete the request, it is handled by the lock package
349 bCompleteRequest = FALSE;
352 // Now call the system package for actually processing the lock request
355 ntStatus = FsRtlProcessFileLock( &pFcb->Specific.File.FileLock,
361 if( bReleaseResource)
368 AFSReleaseResource( &pFcb->NPFcb->Resource);
371 if( bCompleteRequest)
374 AFSCompleteRequest( Irp,
378 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
383 "EXCEPTION - AFSLockControl\n"));
385 AFSDumpTraceFilesFnc();
388 // Again, there is little point in failing this request but pass back some type of failure status
391 ntStatus = STATUS_UNSUCCESSFUL;
393 AFSCompleteRequest( Irp,