NTSTATUS AFSDevControl( IN PDEVICE_OBJECT LibDeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; IO_STACK_LOCATION *pIrpSp; ULONG ulIoControlCode; __try { pIrpSp = IoGetCurrentIrpStackLocation( Irp); ulIoControlCode = pIrpSp->Parameters.DeviceIoControl.IoControlCode; switch( ulIoControlCode) { case IOCTL_AFS_INITIALIZE_LIBRARY_DEVICE: { AFSLibraryInitCB *pLibInitCB = (AFSLibraryInitCB *)Irp->AssociatedIrp.SystemBuffer; if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSLibraryInitCB)) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSInitializeLibrary( pLibInitCB); if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSDevControl AFSInitializeLibrary failure %08lX\n", ntStatus); break; } // // Initialize our global entries // ntStatus = AFSInitializeGlobalDirectoryEntries(); if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSDevControl AFSInitializeGlobalDirectoryEntries failure %08lX\n", ntStatus); break; } ntStatus = AFSInitializeSpecialShareNameList(); if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSDevControl AFSInitializeSpecialShareNameList failure %08lX\n", ntStatus); break; } break; } case IOCTL_AFS_ADD_CONNECTION: { AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer; if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB) || pIrpSp->Parameters.DeviceIoControl.InputBufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) + pConnectCB->RemoteNameLength || pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( ULONG)) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSAddConnection( pConnectCB, (PULONG)Irp->AssociatedIrp.SystemBuffer, &Irp->IoStatus.Information); break; } case IOCTL_AFS_CANCEL_CONNECTION: { AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer; if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB)) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSCancelConnection( pConnectCB, (AFSCancelConnectionResultCB *)Irp->AssociatedIrp.SystemBuffer, &Irp->IoStatus.Information); break; } case IOCTL_AFS_GET_CONNECTION: { AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer; if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB) || pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSGetConnection( pConnectCB, (WCHAR *)Irp->AssociatedIrp.SystemBuffer, pIrpSp->Parameters.DeviceIoControl.OutputBufferLength, &Irp->IoStatus.Information); break; } case IOCTL_AFS_LIST_CONNECTIONS: { if( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSListConnections( (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer, pIrpSp->Parameters.DeviceIoControl.OutputBufferLength, &Irp->IoStatus.Information); break; } case IOCTL_AFS_GET_CONNECTION_INFORMATION: { AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer; if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB) || pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSGetConnectionInfo( pConnectCB, pIrpSp->Parameters.DeviceIoControl.OutputBufferLength, &Irp->IoStatus.Information); break; } case IOCTL_AFS_SET_FILE_EXTENTS: { AFSSetFileExtentsCB *pExtents = (AFSSetFileExtentsCB*) Irp->AssociatedIrp.SystemBuffer; // // Check lengths twice so that if the buffer makes the // count invalid we will not Accvio // if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < ( FIELD_OFFSET( AFSSetFileExtentsCB, ExtentCount) + sizeof(ULONG)) || pIrpSp->Parameters.DeviceIoControl.InputBufferLength < ( FIELD_OFFSET( AFSSetFileExtentsCB, ExtentCount) + sizeof(ULONG) + sizeof (AFSFileExtentCB) * pExtents->ExtentCount)) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSProcessSetFileExtents( pExtents ); Irp->IoStatus.Information = 0; Irp->IoStatus.Status = ntStatus; break; } case IOCTL_AFS_RELEASE_FILE_EXTENTS: { ntStatus = AFSProcessReleaseFileExtents( Irp); break; } case IOCTL_AFS_SET_FILE_EXTENT_FAILURE: { ntStatus = AFSProcessExtentFailure( Irp); break; } case IOCTL_AFS_INVALIDATE_CACHE: { AFSInvalidateCacheCB *pInvalidate = (AFSInvalidateCacheCB*)Irp->AssociatedIrp.SystemBuffer; if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSInvalidateCacheCB)) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSInvalidateCache( pInvalidate); Irp->IoStatus.Information = 0; Irp->IoStatus.Status = ntStatus; break; } case IOCTL_AFS_NETWORK_STATUS: { AFSNetworkStatusCB *pNetworkStatus = (AFSNetworkStatusCB *)Irp->AssociatedIrp.SystemBuffer; if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkStatusCB)) { ntStatus = STATUS_INVALID_PARAMETER; break; } // // Set the network status // ntStatus = AFSSetNetworkState( pNetworkStatus); Irp->IoStatus.Information = 0; Irp->IoStatus.Status = ntStatus; break; } case IOCTL_AFS_VOLUME_STATUS: { AFSVolumeStatusCB *pVolumeStatus = (AFSVolumeStatusCB *)Irp->AssociatedIrp.SystemBuffer; if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSVolumeStatusCB)) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSSetVolumeState( pVolumeStatus); Irp->IoStatus.Information = 0; Irp->IoStatus.Status = ntStatus; break; } case IOCTL_AFS_STATUS_REQUEST: { if( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( AFSDriverStatusRespCB)) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSGetDriverStatus( (AFSDriverStatusRespCB *)Irp->AssociatedIrp.SystemBuffer); Irp->IoStatus.Information = sizeof( AFSDriverStatusRespCB); break; } case IOCTL_AFS_GET_OBJECT_INFORMATION: { if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSGetStatusInfoCB) || pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( AFSStatusInfoCB)) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSGetObjectStatus( (AFSGetStatusInfoCB *)Irp->AssociatedIrp.SystemBuffer, pIrpSp->Parameters.DeviceIoControl.InputBufferLength, (AFSStatusInfoCB *)Irp->AssociatedIrp.SystemBuffer, (ULONG *)&Irp->IoStatus.Information); break; } case 0x140390: // IOCTL_LMR_DISABLE_LOCAL_BUFFERING { // // See http://msdn.microsoft.com/en-us/library/ee210753%28v=vs.85%29.aspx // // The IOCTL_LMR_DISABLE_LOCAL_BUFFERING control code is defined internally by // the system as 0x140390 and not in a public header file. It is used by // special-purpose applications to disable local client-side in-memory // caching of data when reading data from or writing data to a remote file. // After local buffering is disabled, the setting remains in effect until all // open handles to the file are closed and the redirector cleans up its internal // data structures. // // General-purpose applications should not use IOCTL_LMR_DISABLE_LOCAL_BUFFERING, // because it can result in excessive network traffic and associated loss of // performance. The IOCTL_LMR_DISABLE_LOCAL_BUFFERING control code should be used // only in specialized applications moving large amounts of data over the network // while attempting to maximize use of network bandwidth. For example, the CopyFile // and CopyFileEx functions use IOCTL_LMR_DISABLE_LOCAL_BUFFERING to improve large // file copy performance. // // IOCTL_LMR_DISABLE_LOCAL_BUFFERING is not implemented by local file systems and // will fail with the error ERROR_INVALID_FUNCTION. Issuing the // IOCTL_LMR_DISABLE_LOCAL_BUFFERING control code on remote directory handles will // fail with the error ERROR_NOT_SUPPORTED. // ntStatus = STATUS_NOT_SUPPORTED; break; } default: { ntStatus = STATUS_NOT_IMPLEMENTED; break; } } //try_exit: } __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation())) { ntStatus = STATUS_UNSUCCESSFUL; AFSDumpTraceFilesFnc(); } Irp->IoStatus.Status = ntStatus; AFSCompleteRequest( Irp, ntStatus); return ntStatus; }
ntStatus)); try_return( ntStatus); } } } pDevExt->Specific.RDR.MaxLinkCount = RedirInitInfo->MaxPathLinkCount; pDevExt->Specific.RDR.NameArrayLength = RedirInitInfo->NameArrayLength; // // Intialize the library // ntStatus = AFSInitializeLibrary( &RedirInitInfo->GlobalFileId, TRUE); if ( !NT_SUCCESS( ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitializeRedirector AFSInitializeLibrary failure %08lX\n", ntStatus)); } try_exit: if( !NT_SUCCESS( ntStatus)) { if( pDevExt->Specific.RDR.CacheMdl != NULL)
NTSTATUS AFSProcessControlRequest( IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; PIO_STACK_LOCATION pIrpSp; ULONG ulIoControlCode; BOOLEAN bCompleteRequest = TRUE; AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; ULONG ulBytesProcessed = 0; __try { pIrpSp = IoGetCurrentIrpStackLocation( Irp); ulIoControlCode = pIrpSp->Parameters.DeviceIoControl.IoControlCode; switch( ulIoControlCode) { case IOCTL_AFS_INITIALIZE_CONTROL_DEVICE: { // // Go intialize the pool // ntStatus = AFSInitIrpPool(); if( !NT_SUCCESS( ntStatus)) { // // Don't initialize // break; } // // Tag this instance as the one to close the irp pool when it is closed // pIrpSp->FileObject->FsContext = (void *)((ULONG_PTR)pIrpSp->FileObject->FsContext | AFS_CONTROL_INSTANCE); break; } case IOCTL_AFS_INITIALIZE_REDIRECTOR_DEVICE: { AFSRedirectorInitInfo *pRedirInitInfo = (AFSRedirectorInitInfo *)Irp->AssociatedIrp.SystemBuffer; // // Extract off the passed in information which contains the // cache file parameters // if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSRedirectorInitInfo) || pIrpSp->Parameters.DeviceIoControl.InputBufferLength < (ULONG)FIELD_OFFSET( AFSRedirectorInitInfo, CacheFileName) + pRedirInitInfo->CacheFileNameLength) { ntStatus = STATUS_INVALID_PARAMETER; break; } // // Initialize the Redirector device // ntStatus = AFSInitializeRedirector( pRedirInitInfo); if( !NT_SUCCESS( ntStatus)) { break; } // // Stash away context so we know the instance used to initialize the redirector // pIrpSp->FileObject->FsContext = (void *)((ULONG_PTR)pIrpSp->FileObject->FsContext | AFS_REDIRECTOR_INSTANCE); break; } case IOCTL_AFS_PROCESS_IRP_REQUEST: { ntStatus = AFSProcessIrpRequest( Irp); break; } case IOCTL_AFS_PROCESS_IRP_RESULT: { ntStatus = AFSProcessIrpResult( Irp); break; } case IOCTL_AFS_SYSNAME_NOTIFICATION: { AFSSysNameNotificationCB *pSysNameInfo = (AFSSysNameNotificationCB *)Irp->AssociatedIrp.SystemBuffer; if( pSysNameInfo == NULL || pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSSysNameNotificationCB)) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSSetSysNameInformation( pSysNameInfo, pIrpSp->Parameters.DeviceIoControl.InputBufferLength); break; } case IOCTL_AFS_CONFIGURE_DEBUG_TRACE: { AFSTraceConfigCB *pTraceInfo = (AFSTraceConfigCB *)Irp->AssociatedIrp.SystemBuffer; if( pTraceInfo == NULL || pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSTraceConfigCB)) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSConfigureTrace( pTraceInfo); break; } case IOCTL_AFS_GET_TRACE_BUFFER: { if( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSGetTraceBuffer( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength, Irp->AssociatedIrp.SystemBuffer, &Irp->IoStatus.Information); break; } case IOCTL_AFS_FORCE_CRASH: { #if DBG if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_FLAG_ENABLE_FORCE_CRASH)) { KeBugCheck( (ULONG)-1); } #endif break; } #ifdef NOT_IMPLEMENTED case IOCTL_AFS_LOAD_LIBRARY: { AFSLoadLibraryCB *pLoadLib = (AFSLoadLibraryCB *)Irp->AssociatedIrp.SystemBuffer; UNICODE_STRING uniServicePath; if( pLoadLib == NULL || pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSLoadLibraryCB) || pIrpSp->Parameters.DeviceIoControl.InputBufferLength < (ULONG)FIELD_OFFSET( AFSLoadLibraryCB, LibraryServicePath) + pLoadLib->LibraryServicePathLength) { ntStatus = STATUS_INVALID_PARAMETER; break; } uniServicePath.Length = pLoadLib->LibraryServicePathLength; uniServicePath.MaximumLength = uniServicePath.Length; uniServicePath.Buffer = pLoadLib->LibraryServicePath; if( uniServicePath.Length == 0) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSLoadLibrary( pLoadLib->Flags, &uniServicePath); if( NT_SUCCESS( ntStatus)) { // // Intialize the library // ntStatus = AFSInitializeLibrary( NULL, FALSE); } break; } case IOCTL_AFS_UNLOAD_LIBRARY: { // // Try to unload the library we currently have in place // ntStatus = AFSUnloadLibrary( FALSE); break; } #endif case IOCTL_AFS_SHUTDOWN: { ntStatus = AFSShutdownRedirector(); break; } case IOCTL_AFS_AUTHGROUP_CREATE_AND_SET: { AFSAuthGroupRequestCB *pAuthGroupRequestCB = (AFSAuthGroupRequestCB *)Irp->AssociatedIrp.SystemBuffer; if( pAuthGroupRequestCB == NULL || pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSAuthGroupRequestCB)) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSCreateSetProcessAuthGroup( pAuthGroupRequestCB); break; } case IOCTL_AFS_AUTHGROUP_QUERY: { ntStatus = AFSQueryProcessAuthGroupList( ( GUID *)Irp->AssociatedIrp.SystemBuffer, pIrpSp->Parameters.DeviceIoControl.OutputBufferLength, &Irp->IoStatus.Information); break; } case IOCTL_AFS_AUTHGROUP_SET: { AFSAuthGroupRequestCB *pAuthGroupRequestCB = (AFSAuthGroupRequestCB *)Irp->AssociatedIrp.SystemBuffer; if( pAuthGroupRequestCB == NULL || pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSAuthGroupRequestCB)) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSSetActiveProcessAuthGroup( pAuthGroupRequestCB); break; } case IOCTL_AFS_AUTHGROUP_RESET: { AFSAuthGroupRequestCB *pAuthGroupRequestCB = (AFSAuthGroupRequestCB *)Irp->AssociatedIrp.SystemBuffer; if( pAuthGroupRequestCB == NULL || pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSAuthGroupRequestCB)) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSResetActiveProcessAuthGroup( pAuthGroupRequestCB); break; } case IOCTL_AFS_AUTHGROUP_LOGON_CREATE: case IOCTL_AFS_AUTHGROUP_SID_CREATE: { AFSAuthGroupRequestCB *pAuthGroupRequestCB = (AFSAuthGroupRequestCB *)Irp->AssociatedIrp.SystemBuffer; if( pAuthGroupRequestCB != NULL && pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSAuthGroupRequestCB)) { ntStatus = STATUS_INVALID_PARAMETER; break; } ntStatus = AFSCreateAuthGroupForSIDorLogonSession( pAuthGroupRequestCB, ulIoControlCode == IOCTL_AFS_AUTHGROUP_LOGON_CREATE); break; } case IOCTL_AFS_AUTHGROUP_SID_QUERY: { AFSAuthGroupRequestCB *pAuthGroupRequestCB = NULL; if( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( GUID)) { ntStatus = STATUS_INVALID_PARAMETER; break; } if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof( AFSAuthGroupRequestCB)) { pAuthGroupRequestCB = (AFSAuthGroupRequestCB *)Irp->AssociatedIrp.SystemBuffer; } ntStatus = AFSQueryAuthGroup( pAuthGroupRequestCB, (GUID *)Irp->AssociatedIrp.SystemBuffer, &Irp->IoStatus.Information); break; } default: { // // Check the state of the library // ntStatus = AFSCheckLibraryState( Irp); if( !NT_SUCCESS( ntStatus) || ntStatus == STATUS_PENDING) { if( ntStatus == STATUS_PENDING) { bCompleteRequest = FALSE; } break; } bCompleteRequest = FALSE; IoSkipCurrentIrpStackLocation( Irp); ntStatus = IoCallDriver( pDevExt->Specific.Control.LibraryDeviceObject, Irp); // // Indicate the library is done with the request // AFSClearLibraryRequest(); break; } } //try_exit: } __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation())) { ntStatus = STATUS_UNSUCCESSFUL; AFSDumpTraceFilesFnc(); } if( bCompleteRequest) { Irp->IoStatus.Status = ntStatus; AFSCompleteRequest( Irp, ntStatus); } return ntStatus; }