NTSTATUS AFSFlushBuffers( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; __Enter { 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); } IoSkipCurrentIrpStackLocation( Irp); ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, Irp); // // Indicate the library is done with the request // AFSClearLibraryRequest(); try_exit: NOTHING; } return ntStatus; }
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 AFSSetEA( IN PDEVICE_OBJECT LibDeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_EAS_NOT_SUPPORTED; IO_STACK_LOCATION *pIrpSp; pIrpSp = IoGetCurrentIrpStackLocation( Irp); __try { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSSetEa Entry for FO %08lX\n", pIrpSp->FileObject); AFSCompleteRequest( Irp, ntStatus); } __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) { AFSDbgLogMsg( 0, 0, "EXCEPTION - AFSSetEA\n"); } 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 AFSControlDeviceCreate( IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; __Enter { // // For now, jsut let the open happen // Irp->IoStatus.Information = FILE_OPENED; AFSCompleteRequest( Irp, ntStatus); } 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 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 AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; FILE_OBJECT *pFileObject = NULL; IO_STACK_LOCATION *pIrpSp; AFSDeviceExt *pDeviceExt = NULL; AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; GUID *pAuthGroup = NULL; UNICODE_STRING uniGUIDString; __Enter { pIrpSp = IoGetCurrentIrpStackLocation( Irp); pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension; pFileObject = pIrpSp->FileObject; uniGUIDString.Buffer = NULL; uniGUIDString.Length = 0; uniGUIDString.MaximumLength = 0; // // Validate the process entry // pAuthGroup = AFSValidateProcessEntry(); if( pAuthGroup != NULL) { RtlStringFromGUID( *pAuthGroup, &uniGUIDString); AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s (%08lX) Located AuthGroup %wZ after validation\n", __FUNCTION__, Irp, &uniGUIDString); } else { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s (%08lX) Failed to locate AuthGroup\n", __FUNCTION__, Irp); } // // Root open? // if( pFileObject == NULL || pFileObject->FileName.Buffer == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSCommonCreate (%08lX) Processing volume open request\n", Irp); ntStatus = AFSOpenRedirector( Irp); 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( pControlDevExt->Specific.Control.LibraryDeviceObject, Irp); // // Indicate the library is done with the request // AFSClearLibraryRequest(); try_exit: if ( pFileObject) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s (%08lX) File \"%wZ\" AuthGroup '%wZ' ntStatus %08lX\n", __FUNCTION__, Irp, &pFileObject->FileName, &uniGUIDString, ntStatus); } if( uniGUIDString.Buffer != NULL) { RtlFreeUnicodeString( &uniGUIDString); } } return ntStatus; }
NTSTATUS AFSFlushBuffers( IN PDEVICE_OBJECT LibDeviceObject, IN PIRP Irp) { UNREFERENCED_PARAMETER(LibDeviceObject); AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension; NTSTATUS ntStatus = STATUS_SUCCESS; IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); PFILE_OBJECT pFileObject = pIrpSp->FileObject; AFSFcb *pFcb = (AFSFcb *)pFileObject->FsContext; AFSCcb *pCcb = (AFSCcb *)pFileObject->FsContext2; IO_STATUS_BLOCK iosb = {0}; BOOLEAN bReleaseSectionObject = FALSE; pIrpSp = IoGetCurrentIrpStackLocation( Irp); __Enter { if( pFcb == NULL) { AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSFlushBuffers Attempted access (%p) when pFcb == NULL\n", Irp)); try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST); } if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB || pFcb->Header.NodeTypeCode == AFS_ROOT_ALL ) { // // Once we support ADS's on directories we need to perform a flush ehre // try_return( ntStatus = STATUS_SUCCESS); } else if (pFcb->Header.NodeTypeCode != AFS_FILE_FCB) { // // Nothing to flush Everything but files are write through // try_return( ntStatus = STATUS_INVALID_PARAMETER); } AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT, AFS_TRACE_LEVEL_VERBOSE, "AFSFlushBuffers Acquiring Fcb SectionObject lock %p SHARED %08lX\n", &pFcb->NPFcb->SectionObjectResource, PsGetCurrentThread())); AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource, TRUE); bReleaseSectionObject = TRUE; // // The flush consists of two parts. We firstly flush our // cache (if we have one), then we tell the service to write // to the remote server // __try { CcFlushCache( &pFcb->NPFcb->SectionObjectPointers, NULL, 0, &iosb); if (!NT_SUCCESS( iosb.Status )) { AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSFlushBuffers CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n", pFcb->ObjectInformation->FileId.Cell, pFcb->ObjectInformation->FileId.Volume, pFcb->ObjectInformation->FileId.Vnode, pFcb->ObjectInformation->FileId.Unique, iosb.Status, iosb.Information)); try_return( ntStatus = iosb.Status ); } } __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation())) { try_return( ntStatus = GetExceptionCode()); } if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO)) { AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT, AFS_TRACE_LEVEL_VERBOSE, "AFSFlushBuffers Releasing Fcb SectionObject lock %p SHARED %08lX\n", &pFcb->NPFcb->SectionObjectResource, PsGetCurrentThread())); AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource); bReleaseSectionObject = FALSE; // // Now, flush to the server - if there is stuff to do // ntStatus = AFSFlushExtents( pFcb, &pCcb->AuthGroup); if( !NT_SUCCESS( ntStatus)) { AFSReleaseExtentsWithFlush( pFcb, &pCcb->AuthGroup, TRUE); ntStatus = STATUS_SUCCESS; } } try_exit: if ( bReleaseSectionObject) { AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT, AFS_TRACE_LEVEL_VERBOSE, "AFSFlushBuffers Releasing Fcb SectionObject lock %p SHARED %08lX\n", &pFcb->NPFcb->SectionObjectResource, PsGetCurrentThread())); AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource); } AFSCompleteRequest( Irp, ntStatus); } return ntStatus; }
NTSTATUS AFSRDRDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp); PFILE_OBJECT pFileObject = pIrpSp->FileObject; BOOLEAN bCompleteIrp = TRUE; __Enter { switch( pIrpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_REDIR_QUERY_PATH: { QUERY_PATH_REQUEST *pPathRequest = (QUERY_PATH_REQUEST *)pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; QUERY_PATH_RESPONSE *pPathResponse = (QUERY_PATH_RESPONSE *)Irp->UserBuffer; UNICODE_STRING uniPathName; ntStatus = STATUS_BAD_NETWORK_PATH; uniPathName.Length = (USHORT)pPathRequest->PathNameLength; uniPathName.MaximumLength = uniPathName.Length; uniPathName.Buffer = pPathRequest->FilePathName; if( uniPathName.Length >= AFSServerName.Length + sizeof( WCHAR)) { USHORT usLength = uniPathName.Length; uniPathName.Length = AFSServerName.Length; // // Skip over the first slash in the name // uniPathName.Buffer = &uniPathName.Buffer[ 1]; // // Check to see if the first (or only) component // of the path matches the server name // if( RtlCompareUnicodeString( &AFSServerName, &uniPathName, TRUE) == 0 && ( usLength == AFSServerName.Length + sizeof( WCHAR) || uniPathName.Buffer[ AFSServerName.Length / sizeof( WCHAR)] == '\\')) { ntStatus = STATUS_SUCCESS; pPathResponse->LengthAccepted = AFSServerName.Length + sizeof( WCHAR); } } break; } case IOCTL_REDIR_QUERY_PATH_EX: { QUERY_PATH_REQUEST_EX *pPathRequest = (QUERY_PATH_REQUEST_EX *)pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; QUERY_PATH_RESPONSE *pPathResponse = (QUERY_PATH_RESPONSE *)Irp->UserBuffer; UNICODE_STRING uniPathName; ntStatus = STATUS_BAD_NETWORK_PATH; uniPathName.Length = pPathRequest->PathName.Length; uniPathName.MaximumLength = uniPathName.Length; uniPathName.Buffer = pPathRequest->PathName.Buffer; if( uniPathName.Length >= AFSServerName.Length + sizeof( WCHAR)) { USHORT usLength = uniPathName.Length; uniPathName.Length = AFSServerName.Length; // // Skip over the first slash in the name // uniPathName.Buffer = &uniPathName.Buffer[ 1]; // // Check to see if the first (or only) component // of the path matches the server name // if( RtlCompareUnicodeString( &AFSServerName, &uniPathName, TRUE) == 0 && ( usLength == AFSServerName.Length + sizeof( WCHAR) || uniPathName.Buffer[ AFSServerName.Length / sizeof( WCHAR)] == '\\')) { ntStatus = STATUS_SUCCESS; pPathResponse->LengthAccepted = AFSServerName.Length + sizeof( WCHAR); } } break; } default: ntStatus = STATUS_INVALID_DEVICE_REQUEST; break; } if (bCompleteIrp) { // // Complete the request // AFSCompleteRequest( Irp, ntStatus); } } return ntStatus; }
NTSTATUS AFSCleanup( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension; IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); __try { // // Set some initial variables to make processing easier // if( DeviceObject == AFSDeviceObject) { if( FlagOn( (ULONG_PTR)pIrpSp->FileObject->FsContext, AFS_CONTROL_INSTANCE)) { // // This is the process which was registered for the callback pool so cleanup the pool // AFSCleanupIrpPool(); } if( FlagOn( (ULONG_PTR)pIrpSp->FileObject->FsContext, AFS_REDIRECTOR_INSTANCE)) { // // Close the redirector // AFSCloseRedirector(); } AFSCompleteRequest( Irp, ntStatus); try_return( ntStatus); } ntStatus = AFSCommonCleanup( DeviceObject, Irp); try_exit: NOTHING; } __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) { AFSDbgLogMsg( 0, 0, "EXCEPTION - AFSCleanup\n"); } 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 AFSCommonClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); AFSDeviceExt *pDeviceExt = NULL; AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; AFSFcb* pFcb = NULL; __Enter { pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension; pIrpSp = IoGetCurrentIrpStackLocation( Irp); pFcb = (AFSFcb*) pIrpSp->FileObject->FsContext; if( pFcb == NULL || pFcb->Header.NodeTypeCode == AFS_REDIRECTOR_FCB) { 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; } return ntStatus; }
NTSTATUS AFSCommonCleanup( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension; IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); PFILE_OBJECT pFileObject = NULL; AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; BOOLEAN bCompleteRequest = TRUE; __Enter { // // Set some initial variables to make processing easier // pFileObject = pIrpSp->FileObject; if( pIrpSp->FileObject->FsContext == NULL) { // // Root open // try_return( ntStatus); } // // Check the state of the library // ntStatus = AFSCheckLibraryState( Irp); if( !NT_SUCCESS( ntStatus) || ntStatus == STATUS_PENDING) { if( ntStatus == STATUS_PENDING) { bCompleteRequest = FALSE; } try_return( ntStatus); } bCompleteRequest = FALSE; IoSkipCurrentIrpStackLocation( Irp); ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, Irp); // // Indicate the library is done with the request // AFSClearLibraryRequest(); try_exit: if( bCompleteRequest) { if( pFileObject != NULL) { // // Setup the fileobject flags to indicate cleanup is complete. // SetFlag( pFileObject->Flags, FO_CLEANUP_COMPLETE); } // // Complete the request // AFSCompleteRequest( Irp, ntStatus); } } return ntStatus; }
NTSTATUS AFSFlushBuffers( IN PDEVICE_OBJECT LibDeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); PFILE_OBJECT pFileObject = pIrpSp->FileObject; AFSFcb *pFcb = (AFSFcb *)pFileObject->FsContext; AFSCcb *pCcb = (AFSCcb *)pFileObject->FsContext2; IO_STATUS_BLOCK iosb = {0}; pIrpSp = IoGetCurrentIrpStackLocation( Irp); __Enter { if( pFcb == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSFlushBuffers Attempted access (%08lX) when pFcb == NULL\n", Irp); try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST); } if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB || pFcb->Header.NodeTypeCode == AFS_ROOT_ALL ) { // // Once we support ADS's on directories we need to perform a flush ehre // try_return( ntStatus = STATUS_SUCCESS); } else if (pFcb->Header.NodeTypeCode != AFS_FILE_FCB) { // // Nothing to flush Everything but files are write through // try_return( ntStatus = STATUS_INVALID_PARAMETER); } // // The flush consists of two parts. We firstly flush our // cache (if we have one), then we tell the service to write // to the remote server // __try { CcFlushCache( &pFcb->NPFcb->SectionObjectPointers, NULL, 0, &iosb); if (!NT_SUCCESS( iosb.Status )) { AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSFlushBuffers CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n", pFcb->ObjectInformation->FileId.Cell, pFcb->ObjectInformation->FileId.Volume, pFcb->ObjectInformation->FileId.Vnode, pFcb->ObjectInformation->FileId.Unique, iosb.Status, iosb.Information); try_return( ntStatus = iosb.Status ); } } __except( EXCEPTION_EXECUTE_HANDLER) { try_return( ntStatus = GetExceptionCode()); } // // Now, flush to the server - if there is stuff to do // ntStatus = AFSFlushExtents( pFcb, &pCcb->AuthGroup); if( !NT_SUCCESS( ntStatus)) { AFSReleaseExtentsWithFlush( pFcb, &pCcb->AuthGroup); ntStatus = STATUS_SUCCESS; } try_exit: AFSCompleteRequest( Irp, ntStatus); } return ntStatus; }
NTSTATUS AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSDeviceExt *pDeviceExt = NULL; IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); AFSFcb *pFcb = NULL; AFSCcb *pCcb = NULL; PFILE_OBJECT pFileObject = NULL; AFSFcb *pRootFcb = NULL; AFSDeviceExt *pControlDeviceExt = NULL; IO_STATUS_BLOCK stIoSB; AFSObjectInfoCB *pObjectInfo = NULL; AFSFileCleanupCB stFileCleanup; ULONG ulNotificationFlags = 0; __try { if( AFSRDRDeviceObject == NULL) { // // Let this through, it's a cleanup on the library control device // try_return( ntStatus); } pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension; // // Set some initial variables to make processing easier // pFileObject = pIrpSp->FileObject; pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext; pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2; if( pFcb == NULL) { try_return( ntStatus); } pObjectInfo = pFcb->ObjectInformation; pRootFcb = pObjectInfo->VolumeCB->RootFcb; RtlZeroMemory( &stFileCleanup, sizeof( AFSFileCleanupCB)); stFileCleanup.ProcessId = (ULONGLONG)PsGetCurrentProcessId(); stFileCleanup.Identifier = (ULONGLONG)pFileObject; // // Perform the cleanup functionality depending on the type of node it is // switch( pFcb->Header.NodeTypeCode) { case AFS_ROOT_ALL: { AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup Acquiring GlobalRoot lock %08lX EXCL %08lX\n", &pFcb->NPFcb->Resource, PsGetCurrentThread()); AFSAcquireExcl( &pFcb->NPFcb->Resource, TRUE); ASSERT( pFcb->OpenHandleCount != 0); InterlockedDecrement( &pFcb->OpenHandleCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup (RootAll) Decrement handle count on Fcb %08lX Cnt %d\n", pFcb, pFcb->OpenHandleCount); AFSReleaseResource( &pFcb->NPFcb->Resource); FsRtlNotifyCleanup( pControlDeviceExt->Specific.Control.NotifySync, &pControlDeviceExt->Specific.Control.DirNotifyList, pCcb); break; } case AFS_IOCTL_FCB: { AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup Acquiring PIOCtl lock %08lX EXCL %08lX\n", &pFcb->NPFcb->Resource, PsGetCurrentThread()); AFSAcquireExcl( &pFcb->NPFcb->Resource, TRUE); ASSERT( pFcb->OpenHandleCount != 0); InterlockedDecrement( &pFcb->OpenHandleCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup (IOCtl) Decrement handle count on Fcb %08lX Cnt %d\n", pFcb, pFcb->OpenHandleCount); // // Decrement the open child handle count // if( pObjectInfo->ParentObjectInformation != NULL && pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0) { InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup (IOCtl) Decrement child open handle count on Parent object %08lX Cnt %d\n", pObjectInfo->ParentObjectInformation, pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount); } // // And finally, release the Fcb if we acquired it. // AFSReleaseResource( &pFcb->NPFcb->Resource); break; } // // This Fcb represents a file // case AFS_FILE_FCB: { // // 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, "AFSCleanup Acquiring Fcb lock %08lX EXCL %08lX\n", &pFcb->NPFcb->Resource, PsGetCurrentThread()); AFSAcquireExcl( &pFcb->NPFcb->Resource, TRUE); // // If the handle has write permission ... // if( (pCcb->GrantedAccess & FILE_WRITE_DATA) && CcIsFileCached( pIrpSp->FileObject)) { __try { CcFlushCache( &pFcb->NPFcb->SectionObjectPointers, NULL, 0, &stIoSB); if( !NT_SUCCESS( stIoSB.Status)) { AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSCleanup CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n", &pCcb->FullFileName, pObjectInfo->FileId.Cell, pObjectInfo->FileId.Volume, pObjectInfo->FileId.Vnode, pObjectInfo->FileId.Unique, stIoSB.Status, stIoSB.Information); ntStatus = stIoSB.Status; } } __except( EXCEPTION_EXECUTE_HANDLER) { ntStatus = GetExceptionCode(); } } // // Uninitialize the cache map. This call is unconditional. // AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup Tearing down cache map for Fcb %08lX FileObject %08lX\n", pFcb, pFileObject); CcUninitializeCacheMap( pFileObject, NULL, NULL); // // Unlock all outstanding locks on the file, again, unconditionally // (VOID) FsRtlFastUnlockAll( &pFcb->Specific.File.FileLock, pFileObject, IoGetRequestorProcess( Irp), NULL); // // Tell the service to unlock all on the file // ulNotificationFlags |= AFS_REQUEST_FLAG_BYTE_RANGE_UNLOCK_ALL; // // Perform some final common processing // ASSERT( pFcb->OpenHandleCount != 0); InterlockedDecrement( &pFcb->OpenHandleCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup (File) Decrement handle count on Fcb %08lX Cnt %d\n", pFcb, pFcb->OpenHandleCount); if( pFcb->ObjectInformation->ParentObjectInformation != NULL) { stFileCleanup.ParentId = pFcb->ObjectInformation->ParentObjectInformation->FileId; } stFileCleanup.LastAccessTime = pObjectInfo->LastAccessTime; if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED)) { stFileCleanup.AllocationSize = pObjectInfo->EndOfFile; stFileCleanup.FileAttributes = pObjectInfo->FileAttributes; if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CREATE_TIME)) { stFileCleanup.CreateTime = pObjectInfo->CreationTime; ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CREATE_TIME); } if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CHANGE_TIME)) { stFileCleanup.ChangeTime = pObjectInfo->ChangeTime; ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CHANGE_TIME); } if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_ACCESS_TIME)) { stFileCleanup.LastAccessTime = pObjectInfo->LastAccessTime; ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_ACCESS_TIME); } if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME)) { stFileCleanup.LastWriteTime = pObjectInfo->LastWriteTime; ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME | AFS_FCB_FLAG_UPDATE_WRITE_TIME); } } if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_WRITE_TIME)) { stFileCleanup.LastWriteTime = pObjectInfo->LastWriteTime; } // // If the count has dropped to zero and there is a pending delete // then delete the node // if( pFcb->OpenHandleCount == 0 && BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE)) { // // Stop anything possibly in process // AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup 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, "AFSCleanup Releasing Fcb extents lock %08lX EXCL %08lX\n", &pFcb->NPFcb->Specific.File.ExtentsResource, PsGetCurrentThread()); AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource); // // Before telling the server about the deleted file, tear down all extents for // the file // AFSTearDownFcbExtents( pFcb, &pCcb->AuthGroup); ntStatus = STATUS_SUCCESS; ulNotificationFlags |= AFS_REQUEST_FLAG_FILE_DELETED; // // Indicate the file access mode that is being released // stFileCleanup.FileAccess = pCcb->FileAccess; // // Push the request to the service // ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING, ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS, &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, &pObjectInfo->FileId, &stFileCleanup, sizeof( AFSFileCleanupCB), NULL, NULL); if( !NT_SUCCESS( ntStatus) && ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSCleanup Failed to notify service of deleted file %wZ Status %08lX\n", &pCcb->FullFileName, ntStatus); ntStatus = STATUS_SUCCESS; ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE); } else { ntStatus = STATUS_SUCCESS; AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup Setting DELETE flag in file %wZ Dir Entry %p\n", &pCcb->FullFileName, pCcb->DirectoryCB); SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED); ASSERT( pObjectInfo->ParentObjectInformation != NULL); AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation, pCcb, (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME, (ULONG)FILE_ACTION_REMOVED); // // Now that the service has the entry has deleted we need to remove it from the parent // tree so another lookup on the node will fail // if( !BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE)) { AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock, TRUE); AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup DE %p for %wZ removing entry\n", pCcb->DirectoryCB, &pCcb->DirectoryCB->NameInformation.FileName); AFSRemoveNameEntry( pObjectInfo->ParentObjectInformation, pCcb->DirectoryCB); AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock); } else { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup DE %p for %wZ NOT removing entry due to flag set\n", pCcb->DirectoryCB, &pCcb->DirectoryCB->NameInformation.FileName); } } } else { if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED)) { ULONG ulNotifyFilter = 0; ClearFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED); ulNotifyFilter |= (FILE_NOTIFY_CHANGE_ATTRIBUTES); AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation, pCcb, (ULONG)ulNotifyFilter, (ULONG)FILE_ACTION_MODIFIED); } // // Attempt to flush any dirty extents to the server. This may be a little // aggressive, to flush whenever the handle is closed, but it ensures // coherency. // if( (pCcb->GrantedAccess & FILE_WRITE_DATA) && pFcb->Specific.File.ExtentsDirtyCount != 0) { AFSFlushExtents( pFcb, &pCcb->AuthGroup); } if( pFcb->OpenHandleCount == 0) { // // Wait for any outstanding queued flushes to complete // AFSWaitOnQueuedFlushes( pFcb); ulNotificationFlags |= AFS_REQUEST_FLAG_FLUSH_FILE; } // // Indicate the file access mode that is being released // stFileCleanup.FileAccess = pCcb->FileAccess; // // Push the request to the service // AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING, ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS, &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, &pObjectInfo->FileId, &stFileCleanup, sizeof( AFSFileCleanupCB), NULL, NULL); } // // Remove the share access at this time since we may not get the close for sometime on this FO. // IoRemoveShareAccess( pFileObject, &pFcb->ShareAccess); // // We don't need the name array after the user closes the handle on the file // if( pCcb->NameArray != NULL) { AFSFreeNameArray( pCcb->NameArray); pCcb->NameArray = NULL; } // // Decrement the open child handle count // if( pObjectInfo->ParentObjectInformation != NULL) { ASSERT( pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0); InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup (File) Decrement child open handle count on Parent object %08lX Cnt %d\n", pObjectInfo->ParentObjectInformation, pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount); } // // And finally, release the Fcb if we acquired it. // AFSReleaseResource( &pFcb->NPFcb->Resource); break; } // // Root or directory node // case AFS_ROOT_FCB: { // // Set the root Fcb to this node // pRootFcb = pFcb; // // Fall through to below // } case AFS_DIRECTORY_FCB: { // // 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, "AFSCleanup Acquiring Dcb lock %08lX EXCL %08lX\n", &pFcb->NPFcb->Resource, PsGetCurrentThread()); AFSAcquireExcl( &pFcb->NPFcb->Resource, TRUE); // // Perform some final common processing // ASSERT( pFcb->OpenHandleCount != 0); InterlockedDecrement( &pFcb->OpenHandleCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup (Dir) Decrement handle count on Fcb %08lX Cnt %d\n", pFcb, pFcb->OpenHandleCount); if( pFcb->ObjectInformation->ParentObjectInformation != NULL) { stFileCleanup.ParentId = pFcb->ObjectInformation->ParentObjectInformation->FileId; } stFileCleanup.LastAccessTime = pObjectInfo->LastAccessTime; if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED)) { stFileCleanup.FileAttributes = pObjectInfo->FileAttributes; if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CREATE_TIME)) { stFileCleanup.CreateTime = pObjectInfo->CreationTime; ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CREATE_TIME); } if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CHANGE_TIME)) { stFileCleanup.ChangeTime = pObjectInfo->ChangeTime; ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CHANGE_TIME); } if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_ACCESS_TIME)) { stFileCleanup.LastAccessTime = pObjectInfo->LastAccessTime; ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_ACCESS_TIME); } } // // If the count has dropped to zero and there is a pending delete // then delete the node // if( pFcb->OpenHandleCount == 0 && BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE)) { // // Try to notify the service about the delete // ulNotificationFlags |= AFS_REQUEST_FLAG_FILE_DELETED; // // Indicate the file access mode that is being released // stFileCleanup.FileAccess = pCcb->FileAccess; // // Push the request to the service // ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING, ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS, &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, &pObjectInfo->FileId, &stFileCleanup, sizeof( AFSFileCleanupCB), NULL, NULL); if( !NT_SUCCESS( ntStatus) && ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSCleanup Failed to notify service of deleted directory %wZ Status %08lX\n", &pCcb->FullFileName, ntStatus); ntStatus = STATUS_SUCCESS; ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE); } else { ntStatus = STATUS_SUCCESS; AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup Setting DELETE flag in directory %wZ Dir Entry %p\n", &pCcb->FullFileName, pCcb->DirectoryCB); SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED); ASSERT( pObjectInfo->ParentObjectInformation != NULL); AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation, pCcb, (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME, (ULONG)FILE_ACTION_REMOVED); // // Now that the service has the entry has deleted we need to remove it from the parent // tree so another lookup on the node will fail // if( !BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE)) { AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock, TRUE); AFSRemoveNameEntry( pObjectInfo->ParentObjectInformation, pCcb->DirectoryCB); AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock); } else { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup DE %p for %wZ NOT removing entry due to flag set\n", pCcb->DirectoryCB, &pCcb->DirectoryCB->NameInformation.FileName); } } } // // If there have been any updates to the node then push it to // the service // else { if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED)) { ULONG ulNotifyFilter = 0; ClearFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED); if( pObjectInfo->ParentObjectInformation != NULL) { ulNotifyFilter |= (FILE_NOTIFY_CHANGE_ATTRIBUTES); AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation, pCcb, (ULONG)ulNotifyFilter, (ULONG)FILE_ACTION_MODIFIED); } } // // Indicate the file access mode that is being released // stFileCleanup.FileAccess = pCcb->FileAccess; AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING, ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS, &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, &pObjectInfo->FileId, &stFileCleanup, sizeof( AFSFileCleanupCB), NULL, NULL); } // // Release the notification for this directory if there is one // FsRtlNotifyCleanup( pControlDeviceExt->Specific.Control.NotifySync, &pControlDeviceExt->Specific.Control.DirNotifyList, pCcb); // // Remove the share access at this time since we may not get the close for sometime on this FO. // IoRemoveShareAccess( pFileObject, &pFcb->ShareAccess); // // We don't need the name array after the user closes the handle on the file // if( pCcb->NameArray != NULL) { AFSFreeNameArray( pCcb->NameArray); pCcb->NameArray = NULL; } // // Decrement the open child handle count // if( pObjectInfo->ParentObjectInformation != NULL) { ASSERT( pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0); InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup (Dir) Decrement child open handle count on Parent object %08lX Cnt %d\n", pObjectInfo->ParentObjectInformation, pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount); } // // And finally, release the Fcb if we acquired it. // AFSReleaseResource( &pFcb->NPFcb->Resource); break; } case AFS_SYMBOLIC_LINK_FCB: case AFS_MOUNT_POINT_FCB: case AFS_DFS_LINK_FCB: case AFS_INVALID_FCB: { // // 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, "AFSCleanup (MP/SL) Acquiring Dcb lock %08lX EXCL %08lX\n", &pFcb->NPFcb->Resource, PsGetCurrentThread()); AFSAcquireExcl( &pFcb->NPFcb->Resource, TRUE); // // Perform some final common processing // ASSERT( pFcb->OpenHandleCount != 0); InterlockedDecrement( &pFcb->OpenHandleCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup (MP/SL) Decrement handle count on Fcb %08lX Cnt %d\n", pFcb, pFcb->OpenHandleCount); if( pFcb->ObjectInformation->ParentObjectInformation != NULL) { stFileCleanup.ParentId = pFcb->ObjectInformation->ParentObjectInformation->FileId; } stFileCleanup.LastAccessTime = pObjectInfo->LastAccessTime; if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED)) { stFileCleanup.FileAttributes = pObjectInfo->FileAttributes; if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CREATE_TIME)) { stFileCleanup.CreateTime = pObjectInfo->CreationTime; ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CREATE_TIME); } if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CHANGE_TIME)) { stFileCleanup.ChangeTime = pObjectInfo->ChangeTime; ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CHANGE_TIME); } if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_ACCESS_TIME)) { stFileCleanup.LastAccessTime = pObjectInfo->LastAccessTime; ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_ACCESS_TIME); } } // // If the count has dropped to zero and there is a pending delete // then delete the node // if( pFcb->OpenHandleCount == 0 && BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE)) { // // Try to notify the service about the delete // ulNotificationFlags |= AFS_REQUEST_FLAG_FILE_DELETED; // // Indicate the file access mode that is being released // stFileCleanup.FileAccess = pCcb->FileAccess; // // Push the request to the service // ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING, ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS, &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, &pObjectInfo->FileId, &stFileCleanup, sizeof( AFSFileCleanupCB), NULL, NULL); if( !NT_SUCCESS( ntStatus) && ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSCleanup Failed to notify service of deleted MP/SL %wZ Status %08lX\n", &pCcb->FullFileName, ntStatus); ntStatus = STATUS_SUCCESS; ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE); } else { ntStatus = STATUS_SUCCESS; AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup Setting DELETE flag in MP/SL %wZ Dir Entry %p\n", &pCcb->FullFileName, pCcb->DirectoryCB); SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED); ASSERT( pObjectInfo->ParentObjectInformation != NULL); AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation, pCcb, (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME, (ULONG)FILE_ACTION_REMOVED); // // Now that the service has the entry has deleted we need to remove it from the parent // tree so another lookup on the node will fail // if( !BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE)) { AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock, TRUE); AFSRemoveNameEntry( pObjectInfo->ParentObjectInformation, pCcb->DirectoryCB); AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock); } else { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup DE %p for %wZ NOT removing entry due to flag set\n", pCcb->DirectoryCB, &pCcb->DirectoryCB->NameInformation.FileName); } } } // // If there have been any updates to the node then push it to // the service // else { if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED)) { ULONG ulNotifyFilter = 0; ClearFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED); if( pObjectInfo->ParentObjectInformation != NULL) { ulNotifyFilter |= (FILE_NOTIFY_CHANGE_ATTRIBUTES); AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation, pCcb, (ULONG)ulNotifyFilter, (ULONG)FILE_ACTION_MODIFIED); } } // // Indicate the file access mode that is being released // stFileCleanup.FileAccess = pCcb->FileAccess; AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING, ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS, &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, &pObjectInfo->FileId, &stFileCleanup, sizeof( AFSFileCleanupCB), NULL, NULL); } // // Remove the share access at this time since we may not get the close for sometime on this FO. // IoRemoveShareAccess( pFileObject, &pFcb->ShareAccess); // // We don't need the name array after the user closes the handle on the file // if( pCcb->NameArray != NULL) { AFSFreeNameArray( pCcb->NameArray); pCcb->NameArray = NULL; } // // Decrement the open child handle count // if( pObjectInfo->ParentObjectInformation != NULL) { ASSERT( pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0); InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup (MP/SL) Decrement child open handle count on Parent object %08lX Cnt %d\n", pObjectInfo->ParentObjectInformation, pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount); } // // And finally, release the Fcb if we acquired it. // AFSReleaseResource( &pFcb->NPFcb->Resource); break; } case AFS_SPECIAL_SHARE_FCB: { AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup Acquiring SPECIAL SHARE lock %08lX EXCL %08lX\n", &pFcb->NPFcb->Resource, PsGetCurrentThread()); AFSAcquireExcl( &pFcb->NPFcb->Resource, TRUE); ASSERT( pFcb->OpenHandleCount != 0); InterlockedDecrement( &pFcb->OpenHandleCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup (Share) Decrement handle count on Fcb %08lX Cnt %d\n", pFcb, pFcb->OpenHandleCount); // // Decrement the open child handle count // if( pObjectInfo->ParentObjectInformation != NULL && pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0) { InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount); AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, AFS_TRACE_LEVEL_VERBOSE, "AFSCleanup (Share) Decrement child open handle count on Parent object %08lX Cnt %d\n", pObjectInfo->ParentObjectInformation, pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount); } // // And finally, release the Fcb if we acquired it. // AFSReleaseResource( &pFcb->NPFcb->Resource); break; } default: AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_WARNING, "AFSCleanup Processing unknown node type %d\n", pFcb->Header.NodeTypeCode); break; } try_exit: if( pFileObject != NULL) { // // Setup the fileobject flags to indicate cleanup is complete. // SetFlag( pFileObject->Flags, FO_CLEANUP_COMPLETE); } // // Complete the request // AFSCompleteRequest( Irp, ntStatus); }
NTSTATUS AFSRead( 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); } IoSkipCurrentIrpStackLocation( Irp); ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, Irp); // // Indicate the library is done with the request // AFSClearLibraryRequest(); try_exit: NOTHING; } __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; } 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 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 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 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 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 AFSQuerySecurity( IN PDEVICE_OBJECT LibDeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; PIO_STACK_LOCATION pIrpSp; PMDL pUserBufferMdl = NULL; void *pLockedUserBuffer = NULL; ULONG ulSDLength = 0; __try { pIrpSp = IoGetCurrentIrpStackLocation( Irp); AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSQuerySecurity Entry for FO %08lX\n", pIrpSp->FileObject); if( AFSDefaultSD == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSQuerySecurity No default SD allocated\n"); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } ulSDLength = RtlLengthSecurityDescriptor( AFSDefaultSD); if( pIrpSp->Parameters.QuerySecurity.Length < ulSDLength || Irp->UserBuffer == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSQuerySecurity Buffer too small\n"); Irp->IoStatus.Information = (ULONG_PTR)ulSDLength; try_return( ntStatus = STATUS_BUFFER_OVERFLOW); } pLockedUserBuffer = AFSLockUserBuffer( Irp->UserBuffer, pIrpSp->Parameters.QuerySecurity.Length, &pUserBufferMdl); if( pLockedUserBuffer == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, AFS_TRACE_LEVEL_ERROR, "AFSQuerySecurity Failed to lock user buffer\n"); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlCopyMemory( pLockedUserBuffer, AFSDefaultSD, ulSDLength); Irp->IoStatus.Information = (ULONG_PTR)ulSDLength; try_exit: if( pUserBufferMdl != NULL) { MmUnlockPages( pUserBufferMdl); IoFreeMdl( pUserBufferMdl); } } __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) { AFSDbgLogMsg( 0, 0, "EXCEPTION - AFSQuerySecurity\n"); } AFSCompleteRequest( Irp, ntStatus); return ntStatus; }