NTSTATUS AFSSetVolumeInfo( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; IO_STACK_LOCATION *pIrpSp; pIrpSp = IoGetCurrentIrpStackLocation( Irp); __try { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_WARNING, "AFSSetVolumeInfo Entry for FO %08lX\n", pIrpSp->FileObject); AFSCompleteRequest( Irp, ntStatus); } __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) ) { AFSDbgLogMsg( 0, 0, "EXCEPTION - AFSSetVolumeInfo\n"); AFSDumpTraceFilesFnc(); } return ntStatus; }
NTSTATUS AFSFSControl( IN PDEVICE_OBJECT LibDeviceObject, IN PIRP Irp) { UNREFERENCED_PARAMETER(LibDeviceObject); NTSTATUS ntStatus = STATUS_SUCCESS; IO_STACK_LOCATION *pIrpSp; pIrpSp = IoGetCurrentIrpStackLocation( Irp); __try { switch( pIrpSp->MinorFunction) { case IRP_MN_USER_FS_REQUEST: ntStatus = AFSProcessUserFsRequest( Irp); break; case IRP_MN_MOUNT_VOLUME: break; case IRP_MN_VERIFY_VOLUME: break; default: break; } AFSCompleteRequest( Irp, ntStatus); } __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) ) { AFSDbgTrace(( 0, 0, "EXCEPTION - AFSFSControl\n")); AFSDumpTraceFilesFnc(); } return ntStatus; }
NTSTATUS AFSClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; __try { if( DeviceObject == AFSDeviceObject) { AFSCompleteRequest( Irp, ntStatus); try_return( ntStatus); } ntStatus = AFSCommonClose( DeviceObject, Irp); try_exit: NOTHING; } __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) ) { AFSDbgTrace(( 0, 0, "EXCEPTION - AFSClose\n")); AFSDumpTraceFilesFnc(); } return ntStatus; }
NTSTATUS AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; IO_STACK_LOCATION *pIrpSp; FS_INFORMATION_CLASS FsInformationClass; void *pBuffer = NULL; ULONG ulLength = 0; BOOLEAN bReleaseResource = FALSE; PFILE_OBJECT pFileObject = NULL; AFSFcb *pFcb = NULL; AFSObjectInfoCB *pObjectInfo = NULL; AFSVolumeCB *pVolumeCB = NULL; pIrpSp = IoGetCurrentIrpStackLocation( Irp); __try { pFileObject = pIrpSp->FileObject; if( pFileObject == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSQueryVolumeInfo Failing request with NULL FileObject\n"); try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST); } pFcb = (AFSFcb *)pFileObject->FsContext; if( pFcb == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSQueryVolumeInfo Failing request with NULL Fcb\n"); try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST); } pObjectInfo = pFcb->ObjectInformation; if( pObjectInfo == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSQueryVolumeInfo Failing request with NULL ObjectInformation\n"); try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST); } pVolumeCB = pObjectInfo->VolumeCB; ulLength = pIrpSp->Parameters.QueryVolume.Length; FsInformationClass = pIrpSp->Parameters.QueryVolume.FsInformationClass; pBuffer = Irp->AssociatedIrp.SystemBuffer; AFSAcquireShared( pVolumeCB->VolumeLock, TRUE); bReleaseResource = TRUE; // // Don't allow requests against IOCtl nodes // if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSQueryVolumeInfo Failing request against PIOCtl Fcb\n"); try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST); } else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSQueryVolumeInfo Failing request against SpecialShare Fcb\n"); try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST); } else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSQueryVolumeInfo Failing request against SpecialShare Fcb\n"); try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST); } // // Process the request // switch( FsInformationClass) { case FileFsVolumeInformation: { ntStatus = AFSQueryFsVolumeInfo( &pVolumeCB->VolumeInformation, (PFILE_FS_VOLUME_INFORMATION)pBuffer, &ulLength); break; } case FileFsSizeInformation: { ntStatus = AFSQueryFsSizeInfo( &pVolumeCB->VolumeInformation, (PFILE_FS_SIZE_INFORMATION)pBuffer, &ulLength); break; } case FileFsDeviceInformation: { ntStatus = AFSQueryFsDeviceInfo( &pVolumeCB->VolumeInformation, (PFILE_FS_DEVICE_INFORMATION)pBuffer, &ulLength); break; } case FileFsAttributeInformation: { ntStatus = AFSQueryFsAttributeInfo( &pVolumeCB->VolumeInformation, (PFILE_FS_ATTRIBUTE_INFORMATION)pBuffer, &ulLength); break; } case FileFsFullSizeInformation: { ntStatus = AFSQueryFsFullSizeInfo( &pVolumeCB->VolumeInformation, (PFILE_FS_FULL_SIZE_INFORMATION)pBuffer, &ulLength); break; } default: AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_WARNING, "AFSQueryVolumeInfo Invalid class %d\n", FsInformationClass); ntStatus = STATUS_INVALID_PARAMETER; break; } try_exit: // // Setup the Irp's information field to what we actually copied in. // Irp->IoStatus.Information = pIrpSp->Parameters.QueryVolume.Length - ulLength; if( bReleaseResource) { AFSReleaseResource( pVolumeCB->VolumeLock); } AFSCompleteRequest( Irp, ntStatus); } __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) ) { AFSDbgLogMsg( 0, 0, "EXCEPTION - AFSQueryVolumeInfo FO %08lX InfoClass %d FCB %08lX ObjectInfo %08lX VolCB %08lX\n", pFileObject, FsInformationClass, pFcb, pObjectInfo, pVolumeCB); AFSDumpTraceFilesFnc(); } return ntStatus; }
NTSTATUS AFSQueryEA( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_EAS_NOT_SUPPORTED; AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; __try { if( DeviceObject == AFSDeviceObject) { AFSCompleteRequest( Irp, ntStatus); try_return( ntStatus); } // // Check the state of the library // ntStatus = AFSCheckLibraryState( Irp); if( !NT_SUCCESS( ntStatus) || ntStatus == STATUS_PENDING) { if( ntStatus != STATUS_PENDING) { AFSCompleteRequest( Irp, ntStatus); } try_return( ntStatus); } IoSkipCurrentIrpStackLocation( Irp); ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, Irp); // // Indicate the library is done with the request // AFSClearLibraryRequest(); try_exit: NOTHING; } __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) ) { AFSDbgLogMsg( 0, 0, "EXCEPTION - AFSQueryEA\n"); AFSDumpTraceFilesFnc(); } return ntStatus; }
NTSTATUS AFSWrite( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; __try { if( DeviceObject == AFSDeviceObject) { ntStatus = STATUS_INVALID_DEVICE_REQUEST; AFSCompleteRequest( Irp, ntStatus); try_return( ntStatus); } // // Check the state of the library // ntStatus = AFSCheckLibraryState( Irp); if( !NT_SUCCESS( ntStatus) || ntStatus == STATUS_PENDING) { if( ntStatus != STATUS_PENDING) { AFSCompleteRequest( Irp, ntStatus); } try_return( ntStatus); } // // Increment the outstanding IO count again - this time for the // completion routine. // ntStatus = AFSCheckLibraryState( Irp); if( !NT_SUCCESS( ntStatus) || ntStatus == STATUS_PENDING) { AFSClearLibraryRequest(); if( ntStatus != STATUS_PENDING) { AFSCompleteRequest( Irp, ntStatus); } try_return( ntStatus); } // // And send it down, but arrange to capture the comletion // so we can free our lock against unloading. // IoCopyCurrentIrpStackLocationToNext( Irp); AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "Setting AFSWriteComplete as IoCompletion Routine Irp %p\n", Irp)); IoSetCompletionRoutine( Irp, AFSWriteComplete, NULL, TRUE, TRUE, TRUE); ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, Irp); // // Indicate the library/thread pair is done with the request // AFSClearLibraryRequest(); try_exit: NOTHING; } __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) ) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; AFSDumpTraceFilesFnc(); } return ntStatus; }
NTSTATUS AFSInitializeRedirector( IN AFSRedirectorInitInfo *RedirInitInfo) { NTSTATUS ntStatus = STATUS_SUCCESS; LARGE_INTEGER cacheSizeBytes; AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; OBJECT_ATTRIBUTES stObjectAttribs; IO_STATUS_BLOCK stIoStatus; UNICODE_STRING uniServiceName; __Enter { // // First this is to load the library // RtlInitUnicodeString( &uniServiceName, AFS_REDIR_LIBRARY_SERVICE_ENTRY); ntStatus = AFSLoadLibrary( 0, &uniServiceName); if( !NT_SUCCESS( ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitializeRedirector AFSLoadLibrary failure %08lX\n", ntStatus)); try_return( ntStatus); } // // Save off the cache file information // pDevExt->Specific.RDR.CacheBlockSize = RedirInitInfo->CacheBlockSize; pDevExt->Specific.RDR.CacheBlockCount = RedirInitInfo->ExtentCount; pDevExt->Specific.RDR.MaximumRPCLength = RedirInitInfo->MaximumChunkLength; cacheSizeBytes = RedirInitInfo->ExtentCount; cacheSizeBytes.QuadPart *= RedirInitInfo->CacheBlockSize; AFSDumpFileLocation.Length = 0; AFSDumpFileLocation.MaximumLength = (USHORT)RedirInitInfo->DumpFileLocationLength + (4 * sizeof( WCHAR)); AFSDumpFileLocation.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool, AFSDumpFileLocation.MaximumLength, AFS_GENERIC_MEMORY_23_TAG); if( AFSDumpFileLocation.Buffer == NULL) { AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitializeRedirector AFS_GENERIC_MEMORY_23_TAG allocation error\n")); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlCopyMemory( AFSDumpFileLocation.Buffer, L"\\??\\", 4 * sizeof( WCHAR)); AFSDumpFileLocation.Length = 4 * sizeof( WCHAR); RtlCopyMemory( &AFSDumpFileLocation.Buffer[ AFSDumpFileLocation.Length/sizeof( WCHAR)], (void *)((char *)RedirInitInfo + RedirInitInfo->DumpFileLocationOffset), RedirInitInfo->DumpFileLocationLength); AFSDumpFileLocation.Length += (USHORT)RedirInitInfo->DumpFileLocationLength; // // Be sure the shutdown flag is not set // ClearFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN); // // Set up the Throttles. // // Max IO is 10% of the cache, or the value in the registry, // with a minimum of 5Mb (and a maximum of 50% cache size) // if( AFSMaxDirectIo) { // // collect what the user // pDevExt->Specific.RDR.MaxIo.QuadPart = AFSMaxDirectIo; pDevExt->Specific.RDR.MaxIo.QuadPart *= (1024 * 1024); } else { pDevExt->Specific.RDR.MaxIo.QuadPart = cacheSizeBytes.QuadPart / 2; } if (pDevExt->Specific.RDR.MaxIo.QuadPart < (5 * 1024 * 1204)) { pDevExt->Specific.RDR.MaxIo.QuadPart = 5 * 1024 * 1204; } // // For small cache configurations ... // if (pDevExt->Specific.RDR.MaxIo.QuadPart > cacheSizeBytes.QuadPart / 2) { pDevExt->Specific.RDR.MaxIo.QuadPart = cacheSizeBytes.QuadPart / 2; } // // Maximum Dirty is 50% of the cache, or the value in the // registry. No minimum, maximum of 90% of cache size. // if (AFSMaxDirtyFile) { pDevExt->Specific.RDR.MaxDirty.QuadPart = AFSMaxDirtyFile; pDevExt->Specific.RDR.MaxDirty.QuadPart *= (1024 * 1024); } else { pDevExt->Specific.RDR.MaxDirty.QuadPart = cacheSizeBytes.QuadPart/2; } cacheSizeBytes.QuadPart *= 9; cacheSizeBytes.QuadPart = cacheSizeBytes.QuadPart / 10; if (pDevExt->Specific.RDR.MaxDirty.QuadPart > cacheSizeBytes.QuadPart) { pDevExt->Specific.RDR.MaxDirty.QuadPart = cacheSizeBytes.QuadPart; } // // Store off any flags for the file system // if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_FLAG_HIDE_DOT_FILES)) { // // Hide files which begin with . // SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES); } if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_FLAG_DISABLE_SHORTNAMES)) { // // Hide files which begin with . // SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES); } // // Global Reparse Point Policy // pDevExt->Specific.RDR.ReparsePointPolicy = RedirInitInfo->GlobalReparsePointPolicy; // // Are we performing direct to service IO? // if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_PERFORM_SERVICE_IO)) { // // Send IO requests directly to service // SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO); } else { if( RedirInitInfo->MemoryCacheOffset.QuadPart != 0 && RedirInitInfo->MemoryCacheLength.QuadPart != 0) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; #ifdef AMD64 pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL, (void *)RedirInitInfo->MemoryCacheOffset.QuadPart, RedirInitInfo->MemoryCacheLength.QuadPart); #else pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL, (void *)RedirInitInfo->MemoryCacheOffset.LowPart, RedirInitInfo->MemoryCacheLength.LowPart); #endif if( pDevExt->Specific.RDR.CacheMdl != NULL) { __try { MmProbeAndLockPages( pDevExt->Specific.RDR.CacheMdl, KernelMode, IoModifyAccess); pDevExt->Specific.RDR.CacheBaseAddress = MmGetSystemAddressForMdlSafe( pDevExt->Specific.RDR.CacheMdl, NormalPagePriority); } __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) ) { AFSDumpTraceFilesFnc(); IoFreeMdl( pDevExt->Specific.RDR.CacheMdl); pDevExt->Specific.RDR.CacheMdl = NULL; } if( pDevExt->Specific.RDR.CacheMdl != NULL) { pDevExt->Specific.RDR.CacheLength = RedirInitInfo->MemoryCacheLength; ntStatus = STATUS_SUCCESS; } } } if( !NT_SUCCESS( ntStatus) && RedirInitInfo->CacheFileNameLength == 0) { AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitializeRedirector Unable to initialize cache file %08lX\n", ntStatus)); try_return( ntStatus); } if( pDevExt->Specific.RDR.CacheMdl == NULL) { if( RedirInitInfo->CacheFileNameLength == 0) { AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitializeRedirector CacheMdl == NULL\n")); try_return( ntStatus = STATUS_INVALID_PARAMETER); } // // Go open the cache file // pDevExt->Specific.RDR.CacheFile.Length = 0; pDevExt->Specific.RDR.CacheFile.MaximumLength = (USHORT)RedirInitInfo->CacheFileNameLength + (4 * sizeof( WCHAR)); pDevExt->Specific.RDR.CacheFile.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool, pDevExt->Specific.RDR.CacheFile.MaximumLength, AFS_GENERIC_MEMORY_24_TAG); if( pDevExt->Specific.RDR.CacheFile.Buffer == NULL) { AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitializeRedirector AFS_GENERIC_MEMORY_24_TAG allocation failure\n")); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlCopyMemory( pDevExt->Specific.RDR.CacheFile.Buffer, L"\\??\\", 4 * sizeof( WCHAR)); pDevExt->Specific.RDR.CacheFile.Length = 4 * sizeof( WCHAR); RtlCopyMemory( &pDevExt->Specific.RDR.CacheFile.Buffer[ pDevExt->Specific.RDR.CacheFile.Length/sizeof( WCHAR)], RedirInitInfo->CacheFileName, RedirInitInfo->CacheFileNameLength); pDevExt->Specific.RDR.CacheFile.Length += (USHORT)RedirInitInfo->CacheFileNameLength; InitializeObjectAttributes( &stObjectAttribs, &pDevExt->Specific.RDR.CacheFile, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); ntStatus = ZwOpenFile( &pDevExt->Specific.RDR.CacheFileHandle, GENERIC_READ | GENERIC_WRITE, &stObjectAttribs, &stIoStatus, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_WRITE_THROUGH | FILE_RANDOM_ACCESS); if( !NT_SUCCESS( ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitializeRedirector ZwOpenFile failure %08lX\n", ntStatus)); try_return( ntStatus); } // // Map to the fileobject // ntStatus = ObReferenceObjectByHandle( pDevExt->Specific.RDR.CacheFileHandle, SYNCHRONIZE, NULL, KernelMode, (void **)&pDevExt->Specific.RDR.CacheFileObject, NULL); if( !NT_SUCCESS( ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSInitializeRedirector ObReferenceObjectByHandle failure %08lX\n", ntStatus)); try_return( ntStatus); } } }
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 AFSProcessRequest( IN ULONG RequestType, IN ULONG RequestFlags, IN GUID *AuthGroup, IN PUNICODE_STRING FileName, IN AFSFileID *FileId, IN void *Data, IN ULONG DataLength, IN OUT void *ResultBuffer, IN OUT PULONG ResultBufferLength) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSPoolEntry stPoolEntry, *pPoolEntry = NULL; AFSCommSrvcCB *pCommSrvc = NULL; BOOLEAN bReleasePool = FALSE; AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; BOOLEAN bWait = BooleanFlagOn( RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS); ULONG ulPoolEntryLength = 0; BOOLEAN bDecrementCount = FALSE; __try { if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN)) { try_return( ntStatus = STATUS_DEVICE_NOT_READY); } if( InterlockedIncrement( &pControlDevExt->Specific.Control.OutstandingServiceRequestCount) == 1) { KeClearEvent( &pControlDevExt->Specific.Control.OutstandingServiceRequestEvent); } bDecrementCount = TRUE; pCommSrvc = &pControlDevExt->Specific.Control.CommServiceCB; // // Grab the pool resource and check the state // AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSProcessRequest Acquiring IrpPoolLock lock %08lX EXCL %08lX\n", &pCommSrvc->IrpPoolLock, PsGetCurrentThread()); AFSAcquireExcl( &pCommSrvc->IrpPoolLock, TRUE); bReleasePool = TRUE; if( pCommSrvc->IrpPoolControlFlag != POOL_ACTIVE) { // // Pool not running so bail. // try_return( ntStatus = STATUS_DEVICE_NOT_READY); } // // If this is an async request we need to allocate a pool entry for the request // pPoolEntry = &stPoolEntry; if( !bWait) { ASSERT( ResultBuffer == NULL); ulPoolEntryLength = sizeof( AFSPoolEntry) + QuadAlign( DataLength); if( FileName != NULL) { ulPoolEntryLength += FileName->Length; } pPoolEntry = (AFSPoolEntry *)AFSExAllocatePoolWithTag( NonPagedPool, ulPoolEntryLength, AFS_POOL_ENTRY_TAG); if( pPoolEntry == NULL) { try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlZeroMemory( pPoolEntry, ulPoolEntryLength); pPoolEntry->Data = (void *)((char *)pPoolEntry + sizeof( AFSPoolEntry)); pPoolEntry->FileName.Buffer = (WCHAR *)((char *)pPoolEntry->Data + DataLength); } else { RtlZeroMemory( pPoolEntry, sizeof( AFSPoolEntry)); KeInitializeEvent( &pPoolEntry->Event, NotificationEvent, FALSE); } pPoolEntry->RequestType = RequestType; pPoolEntry->RequestIndex = pCommSrvc->IrpPoolRequestIndex++; pPoolEntry->RequestFlags = RequestFlags; pPoolEntry->ResultBufferLength = 0; if( FileId != NULL) { pPoolEntry->FileId = *FileId; } pPoolEntry->FileName.Length = 0; if( FileName != NULL) { if( bWait) { pPoolEntry->FileName = *FileName; } else { pPoolEntry->FileName.Length = FileName->Length; pPoolEntry->FileName.MaximumLength = pPoolEntry->FileName.Length; RtlCopyMemory( pPoolEntry->FileName.Buffer, FileName->Buffer, pPoolEntry->FileName.Length); } } // // Move in the data if there is some // pPoolEntry->DataLength = DataLength; if( Data != NULL && DataLength > 0) { if( bWait) { pPoolEntry->Data = Data; } else { RtlCopyMemory( pPoolEntry->Data, Data, DataLength); } } pPoolEntry->ResultBuffer = ResultBuffer; pPoolEntry->ResultBufferLength = ResultBufferLength; // // Store off the auth group // if( AuthGroup == NULL) { AFSRetrieveAuthGroup( (ULONGLONG)PsGetCurrentProcessId(), (ULONGLONG)PsGetCurrentThreadId(), &pPoolEntry->AuthGroup); } else { RtlCopyMemory( &pPoolEntry->AuthGroup, AuthGroup, sizeof( GUID)); } if( AFSIsLocalSystemAuthGroup( &pPoolEntry->AuthGroup)) { SetFlag( pPoolEntry->RequestFlags, AFS_REQUEST_LOCAL_SYSTEM_PAG); } if( AFSIsNoPAGAuthGroup( &pPoolEntry->AuthGroup)) { AFSDbgLogMsg( 0, 0, "AFSProcessRequest NoPAG Auth Group %08lX\n", PsGetCurrentThread()); } // // Indicate the type of process // #ifdef AMD64 if( !AFSIs64BitProcess( (ULONGLONG)PsGetCurrentProcessId())) { SetFlag( pPoolEntry->RequestFlags, AFS_REQUEST_FLAG_WOW64); } #endif // // Insert the entry into the request pool // ntStatus = AFSInsertRequest( pCommSrvc, pPoolEntry); if( !NT_SUCCESS( ntStatus)) { if( !bWait) { ExFreePool( pPoolEntry); } try_return( ntStatus); } // // Drop the lock on the pool prior to waiting // AFSReleaseResource( &pCommSrvc->IrpPoolLock); bReleasePool = FALSE; // // Wait for the result if this is NOT an asynchronous request // if( bWait) { // // Wait for the result of the request. We specify no timeout ... // ntStatus = KeWaitForSingleObject( &pPoolEntry->Event, Executive, KernelMode, FALSE, NULL); // // Process the result of the request // if( ntStatus == STATUS_SUCCESS) { ntStatus = pPoolEntry->ResultStatus; } else { ntStatus = STATUS_DEVICE_NOT_READY; } } try_exit: if( bReleasePool) { AFSReleaseResource( &pCommSrvc->IrpPoolLock); } if( bDecrementCount && InterlockedDecrement( &pControlDevExt->Specific.Control.OutstandingServiceRequestCount) == 0) { KeSetEvent( &pControlDevExt->Specific.Control.OutstandingServiceRequestEvent, 0, FALSE); } } __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation())) { AFSDumpTraceFilesFnc(); if( bReleasePool) { AFSReleaseResource( &pCommSrvc->IrpPoolLock); } if( bDecrementCount && InterlockedDecrement( &pControlDevExt->Specific.Control.OutstandingServiceRequestCount) == 0) { KeSetEvent( &pControlDevExt->Specific.Control.OutstandingServiceRequestEvent, 0, FALSE); } if ( ntStatus == STATUS_SUCCESS) { ntStatus = STATUS_UNSUCCESSFUL; } } return ntStatus; }
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; }
NTSTATUS AFSClose( IN PDEVICE_OBJECT LibDeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; ULONG ulRequestType = 0; IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); AFSFcb *pFcb = NULL; AFSDeviceExt *pDeviceExt = NULL; AFSCcb *pCcb = NULL; AFSObjectInfoCB *pObjectInfo = NULL; AFSDirectoryCB *pDirCB = NULL; __try { if( AFSRDRDeviceObject == NULL) { // // Let this through, it's an close on the library control device // try_return( ntStatus); } pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; pIrpSp = IoGetCurrentIrpStackLocation( Irp); pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext; if( pFcb == NULL) { try_return( ntStatus); } pObjectInfo = pFcb->ObjectInformation; // // Perform the close functionality depending on the type of node it is // switch( pFcb->Header.NodeTypeCode) { case AFS_IOCTL_FCB: { AFSPIOCtlOpenCloseRequestCB stPIOCtlClose; AFSFileID stParentFileId; AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose Acquiring GlobalRoot lock %08lX EXCL %08lX\n", &pFcb->NPFcb->Resource, PsGetCurrentThread()); AFSAcquireExcl( &pFcb->NPFcb->Resource, TRUE); pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2; // // Send the close to the CM // RtlZeroMemory( &stPIOCtlClose, sizeof( AFSPIOCtlOpenCloseRequestCB)); stPIOCtlClose.RequestId = pCcb->RequestID; stPIOCtlClose.RootId = pObjectInfo->VolumeCB->ObjectInformation.FileId; RtlZeroMemory( &stParentFileId, sizeof( AFSFileID)); stParentFileId = pObjectInfo->ParentObjectInformation->FileId; // // Issue the close request to the service // AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_CLOSE, AFS_REQUEST_FLAG_SYNCHRONOUS, &pCcb->AuthGroup, NULL, &stParentFileId, (void *)&stPIOCtlClose, sizeof( AFSPIOCtlOpenCloseRequestCB), NULL, NULL); pDirCB = pCcb->DirectoryCB; // // Remove the Ccb and de-allocate it // ntStatus = AFSRemoveCcb( pFcb, pCcb); if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_WARNING, "AFSClose Failed to remove Ccb from Fcb Status %08lX\n", ntStatus); // // We can't actually fail a close operation so reset the status // ntStatus = STATUS_SUCCESS; } ASSERT( pDirCB->OpenReferenceCount > 0); InterlockedDecrement( &pDirCB->OpenReferenceCount); AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose (IOCtl) Decrement count on %wZ DE %p Ccb %p Cnt %d\n", &pDirCB->NameInformation.FileName, pDirCB, pCcb, pDirCB->OpenReferenceCount); // // If this is not the root then decrement the open child reference count // if( pObjectInfo->ParentObjectInformation != NULL && pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0) { InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose (IOCtl) Decrement child open ref count on Parent object %08lX Cnt %d\n", pObjectInfo->ParentObjectInformation, pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount); } AFSReleaseResource( &pFcb->NPFcb->Resource); ASSERT( pFcb->OpenReferenceCount != 0); InterlockedDecrement( &pFcb->OpenReferenceCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose (IOCtl) Decrement count on Fcb %08lX Cnt %d\n", pFcb, pFcb->OpenReferenceCount); break; } case AFS_ROOT_ALL: { AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose Acquiring Special Root ALL lock %08lX EXCL %08lX\n", &pFcb->NPFcb->Resource, PsGetCurrentThread()); AFSAcquireExcl( &pFcb->NPFcb->Resource, TRUE); pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2; pDirCB = pCcb->DirectoryCB; // // Remove the Ccb and de-allocate it // ntStatus = AFSRemoveCcb( pFcb, pCcb); if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_WARNING, "AFSClose Failed to remove Ccb from Fcb Status %08lX\n", ntStatus); // // We can't actually fail a close operation so reset the status // ntStatus = STATUS_SUCCESS; } ASSERT( pDirCB->OpenReferenceCount > 0); InterlockedDecrement( &pDirCB->OpenReferenceCount); AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose Decrement (Root ALL) count on %wZ DE %p Ccb %p Cnt %d\n", &pDirCB->NameInformation.FileName, pDirCB, pCcb, pDirCB->OpenReferenceCount); AFSReleaseResource( &pFcb->NPFcb->Resource); ASSERT( pFcb->OpenReferenceCount > 0); InterlockedDecrement( &pFcb->OpenReferenceCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose (RootAll) Decrement count on Fcb %08lX Cnt %d\n", pFcb, pFcb->OpenReferenceCount); break; } // // Root, file or directory node // case AFS_FILE_FCB: case AFS_ROOT_FCB: case AFS_DIRECTORY_FCB: case AFS_SYMBOLIC_LINK_FCB: case AFS_MOUNT_POINT_FCB: case AFS_DFS_LINK_FCB: case AFS_INVALID_FCB: { pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2; // // We may be performing some cleanup on the Fcb so grab it exclusive to ensure no collisions // AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose Acquiring Dcb lock %08lX EXCL %08lX\n", &pFcb->NPFcb->Resource, PsGetCurrentThread()); AFSAcquireExcl( &pFcb->NPFcb->Resource, TRUE); KeQueryTickCount( &pFcb->ObjectInformation->LastAccessCount); pDirCB = pCcb->DirectoryCB; // // If this entry is deleted then remove the object from the volume tree // if( BooleanFlagOn( pDirCB->Flags, AFS_DIR_ENTRY_DELETED)) { if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB) { // // Stop anything possibly in process // AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose Acquiring Fcb extents lock %08lX EXCL %08lX\n", &pFcb->NPFcb->Specific.File.ExtentsResource, PsGetCurrentThread()); AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource, TRUE); pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED; KeSetEvent( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete, 0, FALSE); AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose Releasing Fcb extents lock %08lX EXCL %08lX\n", &pFcb->NPFcb->Specific.File.ExtentsResource, PsGetCurrentThread()); AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource); } AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock, TRUE); AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock, TRUE); if ( pDirCB->OpenReferenceCount == 0) { AFSDbgLogMsg( 0, 0, "AFSClose (Other) OpenReferenceCount is Zero on DE %08lX Ccb %08lX FileName %wZ\n", pDirCB, pCcb, &pDirCB->NameInformation.FileName); } ASSERT( pDirCB->OpenReferenceCount > 0); InterlockedDecrement( &pDirCB->OpenReferenceCount); AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose (Other) Decrement count on %wZ DE %p Ccb %p Cnt %d\n", &pDirCB->NameInformation.FileName, pDirCB, pCcb, pDirCB->OpenReferenceCount); if( pDirCB->OpenReferenceCount == 0) { AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose Deleting dir entry %08lX (%08lX) for %wZ FID %08lX-%08lX-%08lX-%08lX\n", pDirCB, pObjectInfo, &pDirCB->NameInformation.FileName, pObjectInfo->FileId.Cell, pObjectInfo->FileId.Volume, pObjectInfo->FileId.Vnode, pObjectInfo->FileId.Unique); // // Remove and delete the directory entry from the parent list // AFSDeleteDirEntry( pObjectInfo->ParentObjectInformation, pDirCB); if( pObjectInfo->ObjectReferenceCount <= 0) { if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE)) { AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose Removing object %08lX from volume tree\n", pObjectInfo); AFSRemoveHashEntry( &pObjectInfo->VolumeCB->ObjectInfoTree.TreeHead, &pObjectInfo->TreeEntry); ClearFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE); } SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DELETED); } } AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock); AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock); } else { ASSERT( pDirCB->OpenReferenceCount > 0); InterlockedDecrement( &pDirCB->OpenReferenceCount); AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose (Other2) Decrement count on %wZ DE %p Ccb %p Cnt %d\n", &pDirCB->NameInformation.FileName, pDirCB, pCcb, pDirCB->OpenReferenceCount); } // // If this is not the root then decrement the open child reference count // if( pObjectInfo != NULL && pObjectInfo->ParentObjectInformation != NULL && pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0) { InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose Decrement child open ref count on Parent object %08lX Cnt %d\n", pObjectInfo->ParentObjectInformation, pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount); } if( pFcb->OpenReferenceCount == 1 && pFcb->Header.NodeTypeCode == AFS_FILE_FCB) { SetFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED); // // Attempt to tear down our extent list for the file // If there are remaining dirty extents then attempt to // flush them as well // if( pFcb->Specific.File.ExtentsDirtyCount) { AFSFlushExtents( pFcb, &pCcb->AuthGroup); } // // Wait for any outstanding queued flushes to complete // AFSWaitOnQueuedFlushes( pFcb); ASSERT( pFcb->Specific.File.ExtentsDirtyCount == 0 && pFcb->Specific.File.QueuedFlushCount == 0); AFSReleaseResource( &pFcb->NPFcb->Resource); // // Tear 'em down, we'll not be needing them again // AFSTearDownFcbExtents( pFcb, &pCcb->AuthGroup); } else { if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB && pFcb->Specific.File.ExtentsDirtyCount && (pCcb->GrantedAccess & FILE_WRITE_DATA)) { AFSFlushExtents( pFcb, &pCcb->AuthGroup); } AFSReleaseResource( &pFcb->NPFcb->Resource); } // // Remove the Ccb and de-allocate it // ntStatus = AFSRemoveCcb( pFcb, pCcb); if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_WARNING, "AFSClose Failed to remove Ccb from Fcb Status %08lX\n", ntStatus); // // We can't actually fail a close operation so reset the status // ntStatus = STATUS_SUCCESS; } // // Decrement the reference count on the Fcb. this is protecting it from teardown. // ASSERT( pFcb->OpenReferenceCount != 0); InterlockedDecrement( &pFcb->OpenReferenceCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose Decrement count on Fcb %08lX Cnt %d\n", pFcb, pFcb->OpenReferenceCount); break; } case AFS_SPECIAL_SHARE_FCB: { AFSPipeOpenCloseRequestCB stPipeClose; AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose Acquiring Special Share lock %08lX EXCL %08lX\n", &pFcb->NPFcb->Resource, PsGetCurrentThread()); AFSAcquireExcl( &pFcb->NPFcb->Resource, TRUE); pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2; pDirCB = pCcb->DirectoryCB; RtlZeroMemory( &stPipeClose, sizeof( AFSPipeOpenCloseRequestCB)); stPipeClose.RequestId = pCcb->RequestID; stPipeClose.RootId = pObjectInfo->VolumeCB->ObjectInformation.FileId; // // Issue the open request to the service // /* AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_CLOSE, AFS_REQUEST_FLAG_SYNCHRONOUS, &pFcb->AuthGroup, &pDirCB->NameInformation.FileName, NULL, (void *)&stPipeClose, sizeof( AFSPipeOpenCloseRequestCB), NULL, NULL); */ // // Remove the Ccb and de-allocate it // ntStatus = AFSRemoveCcb( pFcb, pCcb); if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_WARNING, "AFSClose Failed to remove Ccb from Fcb Status %08lX\n", ntStatus); // // We can't actually fail a close operation so reset the status // ntStatus = STATUS_SUCCESS; } ASSERT( pDirCB->OpenReferenceCount > 0); InterlockedDecrement( &pDirCB->OpenReferenceCount); AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose (Share) Decrement count on %wZ DE %p Ccb %p Cnt %d\n", &pDirCB->NameInformation.FileName, pDirCB, pCcb, pDirCB->OpenReferenceCount); // // If this is not the root then decrement the open child reference count // if( pObjectInfo->ParentObjectInformation != NULL && pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0) { InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose (Share) Decrement child open ref count on Parent object %08lX Cnt %d\n", pObjectInfo->ParentObjectInformation, pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount); } AFSReleaseResource( &pFcb->NPFcb->Resource); ASSERT( pFcb->OpenReferenceCount != 0); InterlockedDecrement( &pFcb->OpenReferenceCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSClose (Share) Decrement count on Fcb %08lX Cnt %d\n", pFcb, pFcb->OpenReferenceCount); break; } default: AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSClose Processing unknown node type %d\n", pFcb->Header.NodeTypeCode); break; } try_exit: // // Complete the request // AFSCompleteRequest( Irp, ntStatus); } __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) ) { AFSDbgLogMsg( 0, 0, "EXCEPTION - AFSClose\n"); AFSDumpTraceFilesFnc(); } return ntStatus; }
NTSTATUS AFSSetSecurity( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_NOT_SUPPORTED; IO_STACK_LOCATION *pIrpSp; AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; AFSFcb* pFcb = NULL; pIrpSp = IoGetCurrentIrpStackLocation( Irp); __try { AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSSetSecurity Entry for FO %p\n", pIrpSp->FileObject)); if( DeviceObject == AFSDeviceObject) { ntStatus = STATUS_INVALID_DEVICE_REQUEST; AFSCompleteRequest( Irp, ntStatus); try_return( ntStatus); } pFcb = (AFSFcb*) pIrpSp->FileObject->FsContext; if( pFcb == NULL || pFcb->Header.NodeTypeCode == AFS_REDIRECTOR_FCB) { // // Root open // ntStatus = STATUS_INVALID_DEVICE_REQUEST; AFSCompleteRequest( Irp, ntStatus); try_return( ntStatus); } // // Check the state of the library // ntStatus = AFSCheckLibraryState( Irp); if( !NT_SUCCESS( ntStatus) || ntStatus == STATUS_PENDING) { if( ntStatus != STATUS_PENDING) { AFSCompleteRequest( Irp, ntStatus); } try_return( ntStatus); } IoSkipCurrentIrpStackLocation( Irp); ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, Irp); // // Indicate the library is done with the request // AFSClearLibraryRequest(); try_exit: NOTHING; } __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) ) { AFSDbgTrace(( 0, 0, "EXCEPTION - AFSSetSecurity\n")); AFSDumpTraceFilesFnc(); } return ntStatus; }
NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSDeviceExt *pDeviceExt; ULONG ulTimeIncrement = 0; UNICODE_STRING uniSymLinkName; UNICODE_STRING uniDeviceName; ULONG ulIndex = 0; ULONG ulValue = 0; UNICODE_STRING uniValueName; BOOLEAN bExit = FALSE; UNICODE_STRING uniRoutine; RTL_OSVERSIONINFOW sysVersion; UNICODE_STRING uniPsSetCreateProcessNotifyRoutineEx; PsSetCreateProcessNotifyRoutineEx_t pPsSetCreateProcessNotifyRoutineEx = NULL; __try { DbgPrint("AFSRedirFs DriverEntry Initialization build %s:%s\n", __DATE__, __TIME__); // // Initialize some local variables for easier processing // uniSymLinkName.Buffer = NULL; AFSDumpFileLocation.Length = 0; AFSDumpFileLocation.MaximumLength = 0; AFSDumpFileLocation.Buffer = NULL; AFSDumpFileName.Length = 0; AFSDumpFileName.Buffer = NULL; AFSDumpFileName.MaximumLength = 0; ExInitializeResourceLite( &AFSDbgLogLock); // // Initialize the server name // AFSReadServerName(); RtlZeroMemory( &sysVersion, sizeof( RTL_OSVERSIONINFOW)); sysVersion.dwOSVersionInfoSize = sizeof( RTL_OSVERSIONINFOW); RtlGetVersion( &sysVersion); RtlInitUnicodeString( &uniRoutine, L"ZwSetInformationToken"); AFSSetInformationToken = (PAFSSetInformationToken)MmGetSystemRoutineAddress( &uniRoutine); if( AFSSetInformationToken == NULL) { #ifndef AMD64 AFSSrvcTableEntry *pServiceTable = NULL; pServiceTable = (AFSSrvcTableEntry *)KeServiceDescriptorTable; // // Only perform this lookup for Windows XP. // if( pServiceTable != NULL && sysVersion.dwMajorVersion == 5 && sysVersion.dwMinorVersion == 1) { AFSSetInformationToken = (PAFSSetInformationToken)pServiceTable->ServiceTable[ 0xE6]; } #endif } // // And the global root share name // RtlInitUnicodeString( &AFSGlobalRootName, AFS_GLOBAL_ROOT_SHARE_NAME); RtlZeroMemory( &AFSNoPAGAuthGroup, sizeof( GUID)); // // Our backdoor to not let the driver load // if( bExit) { try_return( ntStatus); } // // Perform some initialization // AFSDriverObject = DriverObject; ntStatus = AFSReadRegistry( RegistryPath); if( !NT_SUCCESS( ntStatus)) { DbgPrint("AFS DriverEntry: Failed to read registry Status %08lX\n", ntStatus); ntStatus = STATUS_SUCCESS; } // // Initialize the debug log and dump file interface // AFSInitializeDbgLog(); AFSInitializeDumpFile(); #if DBG if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_FLAG_BREAK_ON_ENTRY)) { DbgPrint("AFSRedirFs DriverEntry - Break on entry\n"); AFSBreakPoint(); if ( bExit) { // // Just as above // try_return( ntStatus = STATUS_UNSUCCESSFUL); } } #endif if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN) && !BooleanFlagOn( AFSDebugFlags, AFS_DBG_CLEAN_SHUTDOWN)) { AFSPrint("AFS DriverEntry: Failed to shutdown clean, exiting\n"); try_return( ntStatus = STATUS_UNSUCCESSFUL); } // // Setup the registry string // AFSRegistryPath.MaximumLength = RegistryPath->MaximumLength; AFSRegistryPath.Length = RegistryPath->Length; AFSRegistryPath.Buffer = (PWSTR)ExAllocatePoolWithTag( PagedPool, AFSRegistryPath.Length, AFS_GENERIC_MEMORY_18_TAG); if( AFSRegistryPath.Buffer == NULL) { DbgPrint("AFSRedirFs DriverEntry Failed to allocate registry path buffer\n"); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlCopyMemory( AFSRegistryPath.Buffer, RegistryPath->Buffer, RegistryPath->Length); if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN)) { // // Update the shutdown flag // ulValue = (ULONG)-1; RtlInitUnicodeString( &uniValueName, AFS_REG_SHUTDOWN_STATUS); AFSUpdateRegistryParameter( &uniValueName, REG_DWORD, &ulValue, sizeof( ULONG)); } RtlInitUnicodeString( &uniDeviceName, AFS_CONTROL_DEVICE_NAME); ntStatus = IoCreateDeviceSecure( DriverObject, sizeof( AFSDeviceExt), &uniDeviceName, FILE_DEVICE_NETWORK_FILE_SYSTEM, 0, FALSE, &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX, (LPCGUID)&GUID_SD_AFS_REDIRECTOR_CONTROL_OBJECT, &AFSDeviceObject); if( !NT_SUCCESS( ntStatus)) { DbgPrint("AFS DriverEntry - Failed to allocate device control object Status %08lX\n", ntStatus); try_return( ntStatus); } // // Setup the device extension // pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; InitializeListHead( &pDeviceExt->Specific.Control.DirNotifyList); FsRtlNotifyInitializeSync( &pDeviceExt->Specific.Control.NotifySync); // // Now initialize the control device // ntStatus = AFSInitializeControlDevice(); if( !NT_SUCCESS( ntStatus)) { try_return( ntStatus); } // // Allocate our symbolic link for service communication // RtlInitUnicodeString( &uniSymLinkName, AFS_SYMLINK_NAME); ntStatus = IoCreateSymbolicLink( &uniSymLinkName, &uniDeviceName); if( !NT_SUCCESS( ntStatus)) { DbgPrint("AFS DriverEntry - Failed to create symbolic link Status %08lX\n", ntStatus); // // OK, no one can communicate with us so fail // try_return( ntStatus); } // // Fill in the dispatch table // for( ulIndex = 0; ulIndex <= IRP_MJ_MAXIMUM_FUNCTION; ulIndex++) { DriverObject->MajorFunction[ ulIndex] = AFSDefaultDispatch; } DriverObject->MajorFunction[IRP_MJ_CREATE] = AFSCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = AFSClose; DriverObject->MajorFunction[IRP_MJ_READ] = AFSRead; DriverObject->MajorFunction[IRP_MJ_WRITE] = AFSWrite; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = AFSQueryFileInfo; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = AFSSetFileInfo; DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = AFSQueryEA; DriverObject->MajorFunction[IRP_MJ_SET_EA] = AFSSetEA; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = AFSFlushBuffers; DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = AFSQueryVolumeInfo; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = AFSSetVolumeInfo; DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = AFSDirControl; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = AFSFSControl; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AFSDevControl; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = AFSInternalDevControl; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = AFSShutdown; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = AFSLockControl; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = AFSCleanup; DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = AFSQuerySecurity; DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = AFSSetSecurity; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = AFSSystemControl; //DriverObject->MajorFunction[IRP_MJ_QUERY_QUOTA] = AFSQueryQuota; //DriverObject->MajorFunction[IRP_MJ_SET_QUOTA] = AFSSetQuota; // // Since we are not a true FSD then we are not controlling a device and hence these will not be needed // #ifdef FSD_NOT_USED DriverObject->MajorFunction[IRP_MJ_POWER] = AFSPower; DriverObject->MajorFunction[IRP_MJ_PNP] = AFSPnP; #endif // // Fast IO Dispatch table // DriverObject->FastIoDispatch = &AFSFastIoDispatch; RtlZeroMemory( &AFSFastIoDispatch, sizeof( AFSFastIoDispatch)); // // Again, since we are not a registered FSD many of these are not going to be called. They are here // for completeness. // AFSFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); AFSFastIoDispatch.FastIoCheckIfPossible = AFSFastIoCheckIfPossible; // CheckForFastIo AFSFastIoDispatch.FastIoRead = AFSFastIoRead; // Read AFSFastIoDispatch.FastIoWrite = AFSFastIoWrite; // Write AFSFastIoDispatch.FastIoQueryBasicInfo = AFSFastIoQueryBasicInfo; // QueryBasicInfo AFSFastIoDispatch.FastIoQueryStandardInfo = AFSFastIoQueryStandardInfo; // QueryStandardInfo AFSFastIoDispatch.FastIoLock = AFSFastIoLock; // Lock AFSFastIoDispatch.FastIoUnlockSingle = AFSFastIoUnlockSingle; // UnlockSingle AFSFastIoDispatch.FastIoUnlockAll = AFSFastIoUnlockAll; // UnlockAll AFSFastIoDispatch.FastIoUnlockAllByKey = AFSFastIoUnlockAllByKey; // UnlockAllByKey AFSFastIoDispatch.FastIoQueryNetworkOpenInfo = AFSFastIoQueryNetworkOpenInfo; AFSFastIoDispatch.AcquireForCcFlush = AFSFastIoAcquireForCCFlush; AFSFastIoDispatch.ReleaseForCcFlush = AFSFastIoReleaseForCCFlush; AFSFastIoDispatch.FastIoDeviceControl = AFSFastIoDevCtrl; AFSFastIoDispatch.AcquireFileForNtCreateSection = AFSFastIoAcquireFile; AFSFastIoDispatch.ReleaseFileForNtCreateSection = AFSFastIoReleaseFile; AFSFastIoDispatch.FastIoDetachDevice = AFSFastIoDetachDevice; //AFSFastIoDispatch.AcquireForModWrite = AFSFastIoAcquireForModWrite; //AFSFastIoDispatch.ReleaseForModWrite = AFSFastIoReleaseForModWrite; AFSFastIoDispatch.MdlRead = AFSFastIoMdlRead; AFSFastIoDispatch.MdlReadComplete = AFSFastIoMdlReadComplete; AFSFastIoDispatch.PrepareMdlWrite = AFSFastIoPrepareMdlWrite; AFSFastIoDispatch.MdlWriteComplete = AFSFastIoMdlWriteComplete; AFSFastIoDispatch.FastIoReadCompressed = AFSFastIoReadCompressed; AFSFastIoDispatch.FastIoWriteCompressed = AFSFastIoWriteCompressed; AFSFastIoDispatch.MdlReadCompleteCompressed = AFSFastIoMdlReadCompleteCompressed; AFSFastIoDispatch.MdlWriteCompleteCompressed = AFSFastIoMdlWriteCompleteCompressed; AFSFastIoDispatch.FastIoQueryOpen = AFSFastIoQueryOpen; // // Cache manager callback routines. // AFSCacheManagerCallbacks.AcquireForLazyWrite = &AFSAcquireFcbForLazyWrite; AFSCacheManagerCallbacks.ReleaseFromLazyWrite = &AFSReleaseFcbFromLazyWrite; AFSCacheManagerCallbacks.AcquireForReadAhead = &AFSAcquireFcbForReadAhead; AFSCacheManagerCallbacks.ReleaseFromReadAhead = &AFSReleaseFcbFromReadAhead; // // System process. // AFSSysProcess = PsGetCurrentProcessId(); // // Register for shutdown notification // IoRegisterShutdownNotification( AFSDeviceObject); // // Initialize the system process cb // AFSInitializeProcessCB( 0, (ULONGLONG)AFSSysProcess); // // Initialize the redirector device // ntStatus = AFSInitRDRDevice(); if( !NT_SUCCESS( ntStatus)) { DbgPrint("AFS DriverEntry Failed to initialize redirector device Status %08lX\n"); try_return( ntStatus); } // // Initialize some server name based strings // AFSInitServerStrings(); // // Register the call back for process creation and tear down. // On Vista SP1 and above, PsSetCreateProcessNotifyRoutineEx // will be used. This function returns STATUS_ACCESS_DENIED // if there is a signing error. In that case, the AFSProcessNotifyEx // routine has not been registered and we can fallback to the // Windows 2000 interface and AFSProcessNotify. // RtlInitUnicodeString( &uniPsSetCreateProcessNotifyRoutineEx, L"PsSetCreateProcessNotifyRoutineEx"); pPsSetCreateProcessNotifyRoutineEx = (PsSetCreateProcessNotifyRoutineEx_t)MmGetSystemRoutineAddress(&uniPsSetCreateProcessNotifyRoutineEx); ntStatus = STATUS_ACCESS_DENIED; if ( pPsSetCreateProcessNotifyRoutineEx) { ntStatus = pPsSetCreateProcessNotifyRoutineEx( AFSProcessNotifyEx, FALSE); } if ( ntStatus == STATUS_ACCESS_DENIED) { ntStatus = PsSetCreateProcessNotifyRoutine( AFSProcessNotify, FALSE); } ntStatus = STATUS_SUCCESS; try_exit: if( !NT_SUCCESS( ntStatus)) { DbgPrint("AFSRedirFs DriverEntry failed to initialize %08lX\n", ntStatus); if( AFSRegistryPath.Buffer != NULL) { ExFreePool( AFSRegistryPath.Buffer); } if( uniSymLinkName.Buffer != NULL) { IoDeleteSymbolicLink( &uniSymLinkName); } if( AFSDeviceObject != NULL) { AFSRemoveControlDevice(); FsRtlNotifyUninitializeSync( &pDeviceExt->Specific.Control.NotifySync); IoUnregisterShutdownNotification( AFSDeviceObject); IoDeleteDevice( AFSDeviceObject); } AFSTearDownDbgLog(); ExDeleteResourceLite( &AFSDbgLogLock); } } __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) ) { AFSDbgLogMsg( 0, 0, "EXCEPTION - AFSRedirFs DriverEntry\n"); AFSDumpTraceFilesFnc(); } return ntStatus; }