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: AFSDevControl.cpp
39 #include "AFSCommon.h"
42 // Function: AFSDevControl
46 // This is the dipatch handler for the IRP_MJ_DEVICE_CONTROL requests.
50 // A status is returned for the function
54 AFSDevControl( IN PDEVICE_OBJECT LibDeviceObject,
57 UNREFERENCED_PARAMETER(LibDeviceObject);
58 NTSTATUS ntStatus = STATUS_SUCCESS;
59 IO_STACK_LOCATION *pIrpSp;
60 ULONG ulIoControlCode = 0;
65 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
67 ulIoControlCode = pIrpSp->Parameters.DeviceIoControl.IoControlCode;
69 switch( ulIoControlCode)
72 case IOCTL_AFS_INITIALIZE_LIBRARY_DEVICE:
75 AFSLibraryInitCB *pLibInitCB = (AFSLibraryInitCB *)Irp->AssociatedIrp.SystemBuffer;
77 if ( Irp->RequestorMode != KernelMode)
80 ntStatus = STATUS_ACCESS_DENIED;
85 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSLibraryInitCB))
88 ntStatus = STATUS_INVALID_PARAMETER;
93 ntStatus = AFSInitializeLibrary( pLibInitCB);
95 if( !NT_SUCCESS( ntStatus))
98 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
99 AFS_TRACE_LEVEL_ERROR,
100 "AFSDevControl AFSInitializeLibrary failure %08lX\n",
107 // Initialize the worker pool.
110 ntStatus = AFSInitializeWorkerPool();
112 if( !NT_SUCCESS( ntStatus))
115 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
116 AFS_TRACE_LEVEL_ERROR,
117 "AFSDevControl AFSInitializeWorkerPool failure %08lX\n",
124 // Initialize our global entries
127 ntStatus = AFSInitializeGlobalDirectoryEntries();
129 if( !NT_SUCCESS( ntStatus))
132 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
133 AFS_TRACE_LEVEL_ERROR,
134 "AFSDevControl AFSInitializeGlobalDirectoryEntries failure %08lX\n",
140 ntStatus = AFSInitializeSpecialShareNameList();
142 if( !NT_SUCCESS( ntStatus))
145 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
146 AFS_TRACE_LEVEL_ERROR,
147 "AFSDevControl AFSInitializeSpecialShareNameList failure %08lX\n",
156 case IOCTL_AFS_ADD_CONNECTION:
159 AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;
161 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB) ||
162 pIrpSp->Parameters.DeviceIoControl.InputBufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
163 pConnectCB->RemoteNameLength ||
164 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( ULONG))
167 ntStatus = STATUS_INVALID_PARAMETER;
172 ntStatus = AFSAddConnection( pConnectCB,
173 (PULONG)Irp->AssociatedIrp.SystemBuffer,
174 &Irp->IoStatus.Information);
179 case IOCTL_AFS_CANCEL_CONNECTION:
182 AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;
184 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB))
187 ntStatus = STATUS_INVALID_PARAMETER;
192 ntStatus = AFSCancelConnection( pConnectCB,
193 (AFSCancelConnectionResultCB *)Irp->AssociatedIrp.SystemBuffer,
194 &Irp->IoStatus.Information);
199 case IOCTL_AFS_GET_CONNECTION:
202 AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;
204 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB) ||
205 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0)
208 ntStatus = STATUS_INVALID_PARAMETER;
213 ntStatus = AFSGetConnection( pConnectCB,
214 (WCHAR *)Irp->AssociatedIrp.SystemBuffer,
215 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
216 &Irp->IoStatus.Information);
221 case IOCTL_AFS_LIST_CONNECTIONS:
224 if( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0)
227 ntStatus = STATUS_INVALID_PARAMETER;
232 ntStatus = AFSListConnections( (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer,
233 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
234 &Irp->IoStatus.Information);
239 case IOCTL_AFS_GET_CONNECTION_INFORMATION:
242 AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;
244 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB) ||
245 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0)
248 ntStatus = STATUS_INVALID_PARAMETER;
253 ntStatus = AFSGetConnectionInfo( pConnectCB,
254 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
255 &Irp->IoStatus.Information);
260 case IOCTL_AFS_SET_FILE_EXTENTS:
263 AFSSetFileExtentsCB *pExtents = (AFSSetFileExtentsCB*) Irp->AssociatedIrp.SystemBuffer;
266 // Check lengths twice so that if the buffer makes the
267 // count invalid we will not Accvio
270 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength <
271 ( FIELD_OFFSET( AFSSetFileExtentsCB, ExtentCount) + sizeof(ULONG)) ||
272 pIrpSp->Parameters.DeviceIoControl.InputBufferLength <
273 ( FIELD_OFFSET( AFSSetFileExtentsCB, ExtentCount) + sizeof(ULONG) +
274 sizeof (AFSFileExtentCB) * pExtents->ExtentCount))
277 ntStatus = STATUS_INVALID_PARAMETER;
282 ntStatus = AFSProcessSetFileExtents( pExtents );
284 Irp->IoStatus.Information = 0;
285 Irp->IoStatus.Status = ntStatus;
290 case IOCTL_AFS_RELEASE_FILE_EXTENTS:
292 ntStatus = AFSProcessReleaseFileExtents( Irp);
296 case IOCTL_AFS_SET_FILE_EXTENT_FAILURE:
299 ntStatus = AFSProcessExtentFailure( Irp);
304 case IOCTL_AFS_INVALIDATE_CACHE:
307 AFSInvalidateCacheCB *pInvalidate = (AFSInvalidateCacheCB*)Irp->AssociatedIrp.SystemBuffer;
309 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSInvalidateCacheCB))
312 ntStatus = STATUS_INVALID_PARAMETER;
317 ntStatus = AFSInvalidateCache( pInvalidate);
319 Irp->IoStatus.Information = 0;
320 Irp->IoStatus.Status = ntStatus;
325 case IOCTL_AFS_NETWORK_STATUS:
328 AFSNetworkStatusCB *pNetworkStatus = (AFSNetworkStatusCB *)Irp->AssociatedIrp.SystemBuffer;
330 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkStatusCB))
333 ntStatus = STATUS_INVALID_PARAMETER;
339 // Set the network status
342 ntStatus = AFSSetNetworkState( pNetworkStatus);
344 Irp->IoStatus.Information = 0;
345 Irp->IoStatus.Status = ntStatus;
350 case IOCTL_AFS_VOLUME_STATUS:
353 AFSVolumeStatusCB *pVolumeStatus = (AFSVolumeStatusCB *)Irp->AssociatedIrp.SystemBuffer;
355 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSVolumeStatusCB))
358 ntStatus = STATUS_INVALID_PARAMETER;
363 ntStatus = AFSSetVolumeState( pVolumeStatus);
365 Irp->IoStatus.Information = 0;
366 Irp->IoStatus.Status = ntStatus;
371 case IOCTL_AFS_STATUS_REQUEST:
374 if( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( AFSDriverStatusRespCB))
377 ntStatus = STATUS_INVALID_PARAMETER;
382 ntStatus = AFSGetDriverStatus( (AFSDriverStatusRespCB *)Irp->AssociatedIrp.SystemBuffer);
384 Irp->IoStatus.Information = sizeof( AFSDriverStatusRespCB);
389 case IOCTL_AFS_GET_OBJECT_INFORMATION:
393 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSGetStatusInfoCB) ||
394 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( AFSStatusInfoCB))
398 ntStatus = STATUS_INVALID_PARAMETER;
403 ntStatus = AFSGetObjectStatus( (AFSGetStatusInfoCB *)Irp->AssociatedIrp.SystemBuffer,
404 pIrpSp->Parameters.DeviceIoControl.InputBufferLength,
405 (AFSStatusInfoCB *)Irp->AssociatedIrp.SystemBuffer,
406 (ULONG *)&Irp->IoStatus.Information);
411 case 0x140390: // IOCTL_LMR_DISABLE_LOCAL_BUFFERING
414 // See http://msdn.microsoft.com/en-us/library/ee210753%28v=vs.85%29.aspx
416 // The IOCTL_LMR_DISABLE_LOCAL_BUFFERING control code is defined internally by
417 // the system as 0x140390 and not in a public header file. It is used by
418 // special-purpose applications to disable local client-side in-memory
419 // caching of data when reading data from or writing data to a remote file.
420 // After local buffering is disabled, the setting remains in effect until all
421 // open handles to the file are closed and the redirector cleans up its internal
424 // General-purpose applications should not use IOCTL_LMR_DISABLE_LOCAL_BUFFERING,
425 // because it can result in excessive network traffic and associated loss of
426 // performance. The IOCTL_LMR_DISABLE_LOCAL_BUFFERING control code should be used
427 // only in specialized applications moving large amounts of data over the network
428 // while attempting to maximize use of network bandwidth. For example, the CopyFile
429 // and CopyFileEx functions use IOCTL_LMR_DISABLE_LOCAL_BUFFERING to improve large
430 // file copy performance.
432 // IOCTL_LMR_DISABLE_LOCAL_BUFFERING is not implemented by local file systems and
433 // will fail with the error ERROR_INVALID_FUNCTION. Issuing the
434 // IOCTL_LMR_DISABLE_LOCAL_BUFFERING control code on remote directory handles will
435 // fail with the error ERROR_NOT_SUPPORTED.
438 ntStatus = STATUS_NOT_SUPPORTED;
443 case IOCTL_AFS_CONFIG_LIBRARY_TRACE:
445 AFSDebugTraceConfigCB *pConfigLib;
447 if ( pIrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof( AFSDebugTraceConfigCB))
450 ntStatus = STATUS_INVALID_PARAMETER;
455 pConfigLib = (AFSDebugTraceConfigCB *)Irp->AssociatedIrp.SystemBuffer;
457 InterlockedCompareExchangePointer( (PVOID *)&AFSDebugTraceFnc,
458 pConfigLib->AFSDbgLogMsg,
459 (void *)pConfigLib->AFSDbgLogMsg);
467 // Note that this code path is never executed - default behavior is caught in the
468 // security checks in lib. New Ioctl functions therefore have to be added here and
469 // in ..\fs\AFSCommSupport.cpp
472 ntStatus = STATUS_NOT_IMPLEMENTED;
481 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
484 ntStatus = STATUS_UNSUCCESSFUL;
488 "EXCEPTION - AFSDevControl %08lX\n",
491 AFSDumpTraceFilesFnc();
494 Irp->IoStatus.Status = ntStatus;
496 AFSCompleteRequest( Irp,