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 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
99 AFS_TRACE_LEVEL_ERROR,
100 "AFSDevControl AFSInitializeLibrary failure %08lX\n",
107 // Initialize our global entries
110 ntStatus = AFSInitializeGlobalDirectoryEntries();
112 if( !NT_SUCCESS( ntStatus))
115 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
116 AFS_TRACE_LEVEL_ERROR,
117 "AFSDevControl AFSInitializeGlobalDirectoryEntries failure %08lX\n",
123 ntStatus = AFSInitializeSpecialShareNameList();
125 if( !NT_SUCCESS( ntStatus))
128 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
129 AFS_TRACE_LEVEL_ERROR,
130 "AFSDevControl AFSInitializeSpecialShareNameList failure %08lX\n",
139 case IOCTL_AFS_ADD_CONNECTION:
142 AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;
144 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB) ||
145 pIrpSp->Parameters.DeviceIoControl.InputBufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
146 pConnectCB->RemoteNameLength ||
147 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( ULONG))
150 ntStatus = STATUS_INVALID_PARAMETER;
155 ntStatus = AFSAddConnection( pConnectCB,
156 (PULONG)Irp->AssociatedIrp.SystemBuffer,
157 &Irp->IoStatus.Information);
162 case IOCTL_AFS_CANCEL_CONNECTION:
165 AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;
167 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB))
170 ntStatus = STATUS_INVALID_PARAMETER;
175 ntStatus = AFSCancelConnection( pConnectCB,
176 (AFSCancelConnectionResultCB *)Irp->AssociatedIrp.SystemBuffer,
177 &Irp->IoStatus.Information);
182 case IOCTL_AFS_GET_CONNECTION:
185 AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;
187 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB) ||
188 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0)
191 ntStatus = STATUS_INVALID_PARAMETER;
196 ntStatus = AFSGetConnection( pConnectCB,
197 (WCHAR *)Irp->AssociatedIrp.SystemBuffer,
198 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
199 &Irp->IoStatus.Information);
204 case IOCTL_AFS_LIST_CONNECTIONS:
207 if( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0)
210 ntStatus = STATUS_INVALID_PARAMETER;
215 ntStatus = AFSListConnections( (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer,
216 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
217 &Irp->IoStatus.Information);
222 case IOCTL_AFS_GET_CONNECTION_INFORMATION:
225 AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;
227 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB) ||
228 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0)
231 ntStatus = STATUS_INVALID_PARAMETER;
236 ntStatus = AFSGetConnectionInfo( pConnectCB,
237 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
238 &Irp->IoStatus.Information);
243 case IOCTL_AFS_SET_FILE_EXTENTS:
246 AFSSetFileExtentsCB *pExtents = (AFSSetFileExtentsCB*) Irp->AssociatedIrp.SystemBuffer;
249 // Check lengths twice so that if the buffer makes the
250 // count invalid we will not Accvio
253 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength <
254 ( FIELD_OFFSET( AFSSetFileExtentsCB, ExtentCount) + sizeof(ULONG)) ||
255 pIrpSp->Parameters.DeviceIoControl.InputBufferLength <
256 ( FIELD_OFFSET( AFSSetFileExtentsCB, ExtentCount) + sizeof(ULONG) +
257 sizeof (AFSFileExtentCB) * pExtents->ExtentCount))
260 ntStatus = STATUS_INVALID_PARAMETER;
265 ntStatus = AFSProcessSetFileExtents( pExtents );
267 Irp->IoStatus.Information = 0;
268 Irp->IoStatus.Status = ntStatus;
273 case IOCTL_AFS_RELEASE_FILE_EXTENTS:
275 ntStatus = AFSProcessReleaseFileExtents( Irp);
279 case IOCTL_AFS_SET_FILE_EXTENT_FAILURE:
282 ntStatus = AFSProcessExtentFailure( Irp);
287 case IOCTL_AFS_INVALIDATE_CACHE:
290 AFSInvalidateCacheCB *pInvalidate = (AFSInvalidateCacheCB*)Irp->AssociatedIrp.SystemBuffer;
292 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSInvalidateCacheCB))
295 ntStatus = STATUS_INVALID_PARAMETER;
300 ntStatus = AFSInvalidateCache( pInvalidate);
302 Irp->IoStatus.Information = 0;
303 Irp->IoStatus.Status = ntStatus;
308 case IOCTL_AFS_NETWORK_STATUS:
311 AFSNetworkStatusCB *pNetworkStatus = (AFSNetworkStatusCB *)Irp->AssociatedIrp.SystemBuffer;
313 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkStatusCB))
316 ntStatus = STATUS_INVALID_PARAMETER;
322 // Set the network status
325 ntStatus = AFSSetNetworkState( pNetworkStatus);
327 Irp->IoStatus.Information = 0;
328 Irp->IoStatus.Status = ntStatus;
333 case IOCTL_AFS_VOLUME_STATUS:
336 AFSVolumeStatusCB *pVolumeStatus = (AFSVolumeStatusCB *)Irp->AssociatedIrp.SystemBuffer;
338 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSVolumeStatusCB))
341 ntStatus = STATUS_INVALID_PARAMETER;
346 ntStatus = AFSSetVolumeState( pVolumeStatus);
348 Irp->IoStatus.Information = 0;
349 Irp->IoStatus.Status = ntStatus;
354 case IOCTL_AFS_STATUS_REQUEST:
357 if( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( AFSDriverStatusRespCB))
360 ntStatus = STATUS_INVALID_PARAMETER;
365 ntStatus = AFSGetDriverStatus( (AFSDriverStatusRespCB *)Irp->AssociatedIrp.SystemBuffer);
367 Irp->IoStatus.Information = sizeof( AFSDriverStatusRespCB);
372 case IOCTL_AFS_GET_OBJECT_INFORMATION:
376 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSGetStatusInfoCB) ||
377 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( AFSStatusInfoCB))
381 ntStatus = STATUS_INVALID_PARAMETER;
386 ntStatus = AFSGetObjectStatus( (AFSGetStatusInfoCB *)Irp->AssociatedIrp.SystemBuffer,
387 pIrpSp->Parameters.DeviceIoControl.InputBufferLength,
388 (AFSStatusInfoCB *)Irp->AssociatedIrp.SystemBuffer,
389 (ULONG *)&Irp->IoStatus.Information);
394 case 0x140390: // IOCTL_LMR_DISABLE_LOCAL_BUFFERING
397 // See http://msdn.microsoft.com/en-us/library/ee210753%28v=vs.85%29.aspx
399 // The IOCTL_LMR_DISABLE_LOCAL_BUFFERING control code is defined internally by
400 // the system as 0x140390 and not in a public header file. It is used by
401 // special-purpose applications to disable local client-side in-memory
402 // caching of data when reading data from or writing data to a remote file.
403 // After local buffering is disabled, the setting remains in effect until all
404 // open handles to the file are closed and the redirector cleans up its internal
407 // General-purpose applications should not use IOCTL_LMR_DISABLE_LOCAL_BUFFERING,
408 // because it can result in excessive network traffic and associated loss of
409 // performance. The IOCTL_LMR_DISABLE_LOCAL_BUFFERING control code should be used
410 // only in specialized applications moving large amounts of data over the network
411 // while attempting to maximize use of network bandwidth. For example, the CopyFile
412 // and CopyFileEx functions use IOCTL_LMR_DISABLE_LOCAL_BUFFERING to improve large
413 // file copy performance.
415 // IOCTL_LMR_DISABLE_LOCAL_BUFFERING is not implemented by local file systems and
416 // will fail with the error ERROR_INVALID_FUNCTION. Issuing the
417 // IOCTL_LMR_DISABLE_LOCAL_BUFFERING control code on remote directory handles will
418 // fail with the error ERROR_NOT_SUPPORTED.
421 ntStatus = STATUS_NOT_SUPPORTED;
429 // Note that this code path is never executed - default behavior is caught in the
430 // security checks in lib. New Ioctl functions therefore have to be added here and
431 // in ..\fs\AFSCommSupport.cpp
434 ntStatus = STATUS_NOT_IMPLEMENTED;
443 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
446 ntStatus = STATUS_UNSUCCESSFUL;
450 "EXCEPTION - AFSDevControl %08lX\n",
453 AFSDumpTraceFilesFnc();
456 Irp->IoStatus.Status = ntStatus;
458 AFSCompleteRequest( Irp,