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,
58 NTSTATUS ntStatus = STATUS_SUCCESS;
59 IO_STACK_LOCATION *pIrpSp;
60 ULONG ulIoControlCode;
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( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSLibraryInitCB))
80 ntStatus = STATUS_INVALID_PARAMETER;
85 ntStatus = AFSInitializeLibrary( pLibInitCB);
87 if( !NT_SUCCESS( ntStatus))
90 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
91 AFS_TRACE_LEVEL_ERROR,
92 "AFSDevControl AFSInitializeLibrary failure %08lX\n",
99 // Initialize our global entries
102 ntStatus = AFSInitializeGlobalDirectoryEntries();
104 if( !NT_SUCCESS( ntStatus))
107 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
108 AFS_TRACE_LEVEL_ERROR,
109 "AFSDevControl AFSInitializeGlobalDirectoryEntries failure %08lX\n",
115 ntStatus = AFSInitializeSpecialShareNameList();
117 if( !NT_SUCCESS( ntStatus))
120 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
121 AFS_TRACE_LEVEL_ERROR,
122 "AFSDevControl AFSInitializeSpecialShareNameList failure %08lX\n",
131 case IOCTL_AFS_ADD_CONNECTION:
134 AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;
136 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB) ||
137 pIrpSp->Parameters.DeviceIoControl.InputBufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
138 pConnectCB->RemoteNameLength ||
139 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( ULONG))
142 ntStatus = STATUS_INVALID_PARAMETER;
147 ntStatus = AFSAddConnection( pConnectCB,
148 (PULONG)Irp->AssociatedIrp.SystemBuffer,
149 &Irp->IoStatus.Information);
154 case IOCTL_AFS_CANCEL_CONNECTION:
157 AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;
159 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB))
162 ntStatus = STATUS_INVALID_PARAMETER;
167 ntStatus = AFSCancelConnection( pConnectCB,
168 (AFSCancelConnectionResultCB *)Irp->AssociatedIrp.SystemBuffer,
169 &Irp->IoStatus.Information);
174 case IOCTL_AFS_GET_CONNECTION:
177 AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;
179 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB) ||
180 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0)
183 ntStatus = STATUS_INVALID_PARAMETER;
188 ntStatus = AFSGetConnection( pConnectCB,
189 (WCHAR *)Irp->AssociatedIrp.SystemBuffer,
190 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
191 &Irp->IoStatus.Information);
196 case IOCTL_AFS_LIST_CONNECTIONS:
199 if( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0)
202 ntStatus = STATUS_INVALID_PARAMETER;
207 ntStatus = AFSListConnections( (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer,
208 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
209 &Irp->IoStatus.Information);
214 case IOCTL_AFS_GET_CONNECTION_INFORMATION:
217 AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;
219 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB) ||
220 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0)
223 ntStatus = STATUS_INVALID_PARAMETER;
228 ntStatus = AFSGetConnectionInfo( pConnectCB,
229 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
230 &Irp->IoStatus.Information);
235 case IOCTL_AFS_SET_FILE_EXTENTS:
238 AFSSetFileExtentsCB *pExtents = (AFSSetFileExtentsCB*) Irp->AssociatedIrp.SystemBuffer;
241 // Check lengths twice so that if the buffer makes the
242 // count invalid we will not Accvio
245 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength <
246 ( FIELD_OFFSET( AFSSetFileExtentsCB, ExtentCount) + sizeof(ULONG)) ||
247 pIrpSp->Parameters.DeviceIoControl.InputBufferLength <
248 ( FIELD_OFFSET( AFSSetFileExtentsCB, ExtentCount) + sizeof(ULONG) +
249 sizeof (AFSFileExtentCB) * pExtents->ExtentCount))
252 ntStatus = STATUS_INVALID_PARAMETER;
257 ntStatus = AFSProcessSetFileExtents( pExtents );
259 Irp->IoStatus.Information = 0;
260 Irp->IoStatus.Status = ntStatus;
265 case IOCTL_AFS_RELEASE_FILE_EXTENTS:
267 ntStatus = AFSProcessReleaseFileExtents( Irp);
271 case IOCTL_AFS_SET_FILE_EXTENT_FAILURE:
274 ntStatus = AFSProcessExtentFailure( Irp);
279 case IOCTL_AFS_INVALIDATE_CACHE:
282 AFSInvalidateCacheCB *pInvalidate = (AFSInvalidateCacheCB*)Irp->AssociatedIrp.SystemBuffer;
284 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSInvalidateCacheCB))
287 ntStatus = STATUS_INVALID_PARAMETER;
292 ntStatus = AFSInvalidateCache( pInvalidate);
294 Irp->IoStatus.Information = 0;
295 Irp->IoStatus.Status = ntStatus;
300 case IOCTL_AFS_NETWORK_STATUS:
303 AFSNetworkStatusCB *pNetworkStatus = (AFSNetworkStatusCB *)Irp->AssociatedIrp.SystemBuffer;
305 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkStatusCB))
308 ntStatus = STATUS_INVALID_PARAMETER;
314 // Set the network status
317 ntStatus = AFSSetNetworkState( pNetworkStatus);
319 Irp->IoStatus.Information = 0;
320 Irp->IoStatus.Status = ntStatus;
325 case IOCTL_AFS_VOLUME_STATUS:
328 AFSVolumeStatusCB *pVolumeStatus = (AFSVolumeStatusCB *)Irp->AssociatedIrp.SystemBuffer;
330 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSVolumeStatusCB))
333 ntStatus = STATUS_INVALID_PARAMETER;
338 ntStatus = AFSSetVolumeState( pVolumeStatus);
340 Irp->IoStatus.Information = 0;
341 Irp->IoStatus.Status = ntStatus;
346 case IOCTL_AFS_STATUS_REQUEST:
349 if( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( AFSDriverStatusRespCB))
352 ntStatus = STATUS_INVALID_PARAMETER;
357 ntStatus = AFSGetDriverStatus( (AFSDriverStatusRespCB *)Irp->AssociatedIrp.SystemBuffer);
359 Irp->IoStatus.Information = sizeof( AFSDriverStatusRespCB);
364 case IOCTL_AFS_GET_OBJECT_INFORMATION:
368 if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSGetStatusInfoCB) ||
369 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( AFSStatusInfoCB))
373 ntStatus = STATUS_INVALID_PARAMETER;
378 ntStatus = AFSGetObjectStatus( (AFSGetStatusInfoCB *)Irp->AssociatedIrp.SystemBuffer,
379 pIrpSp->Parameters.DeviceIoControl.InputBufferLength,
380 (AFSStatusInfoCB *)Irp->AssociatedIrp.SystemBuffer,
381 (ULONG *)&Irp->IoStatus.Information);
386 case 0x140390: // IOCTL_LMR_DISABLE_LOCAL_BUFFERING
389 // See http://msdn.microsoft.com/en-us/library/ee210753%28v=vs.85%29.aspx
391 // The IOCTL_LMR_DISABLE_LOCAL_BUFFERING control code is defined internally by
392 // the system as 0x140390 and not in a public header file. It is used by
393 // special-purpose applications to disable local client-side in-memory
394 // caching of data when reading data from or writing data to a remote file.
395 // After local buffering is disabled, the setting remains in effect until all
396 // open handles to the file are closed and the redirector cleans up its internal
399 // General-purpose applications should not use IOCTL_LMR_DISABLE_LOCAL_BUFFERING,
400 // because it can result in excessive network traffic and associated loss of
401 // performance. The IOCTL_LMR_DISABLE_LOCAL_BUFFERING control code should be used
402 // only in specialized applications moving large amounts of data over the network
403 // while attempting to maximize use of network bandwidth. For example, the CopyFile
404 // and CopyFileEx functions use IOCTL_LMR_DISABLE_LOCAL_BUFFERING to improve large
405 // file copy performance.
407 // IOCTL_LMR_DISABLE_LOCAL_BUFFERING is not implemented by local file systems and
408 // will fail with the error ERROR_INVALID_FUNCTION. Issuing the
409 // IOCTL_LMR_DISABLE_LOCAL_BUFFERING control code on remote directory handles will
410 // fail with the error ERROR_NOT_SUPPORTED.
413 ntStatus = STATUS_NOT_SUPPORTED;
421 ntStatus = STATUS_NOT_IMPLEMENTED;
430 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
433 ntStatus = STATUS_UNSUCCESSFUL;
435 AFSDumpTraceFilesFnc();
438 Irp->IoStatus.Status = ntStatus;
440 AFSCompleteRequest( Irp,