Beispiel #1
0
NTSTATUS
CtxInstanceSetup (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_SETUP_FLAGS Flags,
    __in DEVICE_TYPE VolumeDeviceType,
    __in FLT_FILESYSTEM_TYPE VolumeFilesystemType
    )
/*++

Routine Description:

    This routine is called whenever a new instance is created on a volume. This
    gives us a chance to decide if we need to attach to this volume or not.

Arguments:

    FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
        opaque handles to this filter, instance and its associated volume.

    Flags - Flags describing the reason for this attach request.

Return Value:

    STATUS_SUCCESS - attach
    STATUS_FLT_DO_NOT_ATTACH - do not attach

--*/
{
    PCTX_INSTANCE_CONTEXT instanceContext = NULL;
    NTSTATUS status = STATUS_SUCCESS;
    ULONG volumeNameLength;

#if __NDAS_FS_MINI__

	ULONG					propertyLengthReturned; 

	UNICODE_STRING			ntfs;
	UNICODE_STRING			ndasNtfs;
	UNICODE_STRING			fat;
	UNICODE_STRING			ndasFat;

	PNETDISK_PARTITION		netdiskPartition;
	NETDISK_ENABLE_MODE		netdiskEnableMode;

#endif

#if __LFS__
	ULONG					propertyLengthReturned; 
	BOOLEAN					result;

	UNICODE_STRING			ntfs;
	UNICODE_STRING			ndasNtfs;
	UNICODE_STRING			fat;
	UNICODE_STRING			ndasFat;

	PENABLED_NETDISK		enabledNetdisk;
	NETDISK_ENABLE_MODE		netdiskEnableMode;
#endif

    UNREFERENCED_PARAMETER( Flags );
    UNREFERENCED_PARAMETER( VolumeDeviceType );
    UNREFERENCED_PARAMETER( VolumeFilesystemType );

    PAGED_CODE();

#if __NDAS_FS_MINI__

    DebugTrace( DEBUG_TRACE_INSTANCES,
                ("[Ctx]: Instance setup started FltObjects = %p\n", FltObjects) );

#endif

    DebugTrace( DEBUG_TRACE_INSTANCES,
                ("[Ctx]: Instance setup started (Volume = %p, Instance = %p)\n",
                 FltObjects->Volume,
                 FltObjects->Instance) );

    //
    //  Allocate and initialize the context for this volume
    //


    //
    //  Allocate the instance context
    //

    DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS,
                ("[Ctx]: Allocating instance context (Volume = %p, Instance = %p)\n",
                 FltObjects->Volume,
                 FltObjects->Instance) );

    status = FltAllocateContext( FltObjects->Filter,
                                 FLT_INSTANCE_CONTEXT,
                                 CTX_INSTANCE_CONTEXT_SIZE,
                                 NonPagedPool,
                                 &instanceContext );

    if (!NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR,
                    ("[Ctx]: Failed to allocate instance context (Volume = %p, Instance = %p, Status = 0x%x)\n",
                     FltObjects->Volume,
                     FltObjects->Instance,
                     status) );

        goto CtxInstanceSetupCleanup;
    }

#if __NDAS_FS_MINI__

	RtlZeroMemory( instanceContext, sizeof(CTX_INSTANCE_CONTEXT) );

	status = FltGetVolumeProperties( FltObjects->Volume,
									 NULL,
									 0,
									 &propertyLengthReturned ); 


	DebugTrace( DEBUG_TRACE_INSTANCES,
				("[MiniSpy]: IRP_MJ_VOLUME_MOUNT FltGetVolumeProperties, status = %x, propertyLengthReturned = %d\n",
				 status,
				 propertyLengthReturned) );

	instanceContext->VolumeProperties = ExAllocatePoolWithTag( PagedPool, propertyLengthReturned, CTX_VOLUME_PROPERTY_TAG );

	status = FltGetVolumeProperties( FltObjects->Volume,
									 instanceContext->VolumeProperties,
									 propertyLengthReturned,
									 &propertyLengthReturned ); 

	DebugTrace( DEBUG_TRACE_INSTANCES,
				("[MiniSpy]: FltGetVolumeProperties, status = %x, propertyLengthReturned = %d\n",
				 status,
				 propertyLengthReturned) );

	if( !NT_SUCCESS( status )) {

		status = STATUS_FLT_DO_NOT_ATTACH;
		goto CtxInstanceSetupCleanup;
	}

	DebugTrace( DEBUG_TRACE_INSTANCES,
				("[MiniSpy]: FltGetVolumeProperties, DeviceType = %d "
				 "FileSystemDriverName = %wZ\n"
				 "FileSystemDeviceName = %wZ "
				 "RealDeviceName = %wZ\n",
				 instanceContext->VolumeProperties->DeviceType,
				 &instanceContext->VolumeProperties->FileSystemDriverName,
				 &instanceContext->VolumeProperties->FileSystemDeviceName,
				 &instanceContext->VolumeProperties->RealDeviceName) );

	RtlInitUnicodeString( &ntfs, L"\\Ntfs" );
	RtlInitUnicodeString( &ndasNtfs, NDAS_NTFS_DEVICE_NAME );
	RtlInitUnicodeString( &fat, L"\\Fat" );
	RtlInitUnicodeString( &ndasFat, NDAS_FAT_DEVICE_NAME );

	if (!(RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ntfs, TRUE)		||
		  RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)	||
		  RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &fat, TRUE)		||
		  RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE))) {

		status = STATUS_FLT_DO_NOT_ATTACH;
		goto CtxInstanceSetupCleanup;
	}

	status = FltGetDeviceObject( FltObjects->Volume, &instanceContext->DeviceObject );

	if (!NT_SUCCESS(status)) {

		status = STATUS_FLT_DO_NOT_ATTACH;
		goto CtxInstanceSetupCleanup;
	}
	
	status = FltGetDiskDeviceObject( FltObjects->Volume, &instanceContext->DiskDeviceObject );

	if (!NT_SUCCESS(status)) {

		status = STATUS_FLT_DO_NOT_ATTACH;
		goto CtxInstanceSetupCleanup;
	}

	DebugTrace( DEBUG_TRACE_INSTANCES,
				("DeviceObject = %p, DiskDeviceObject = %p\n", instanceContext->DeviceObject, instanceContext->DiskDeviceObject) );


	if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE) && 
		!GlobalLfs.NdasFatRwSupport && !GlobalLfs.NdasFatRoSupport ||
		RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE) && 
		!GlobalLfs.NdasNtfsRwSupport && !GlobalLfs.NdasNtfsRoSupport) {

		NDASFS_ASSERT( FALSE );
		status = STATUS_FLT_DO_NOT_ATTACH;
		goto CtxInstanceSetupCleanup;
	}

	if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE)) {

		status = NetdiskManager_PreMountVolume( GlobalLfs.NetdiskManager,
												GlobalLfs.NdasFatRwIndirect ? TRUE : FALSE,
												instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.DeviceObject,
												instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.Vpb->RealDevice,
												&netdiskPartition,
												&netdiskEnableMode );
	
	} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)) {

		status = NetdiskManager_PreMountVolume( GlobalLfs.NetdiskManager,
												GlobalLfs.NdasNtfsRwIndirect ? TRUE : FALSE,
												instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.DeviceObject,
												instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.Vpb->RealDevice,
												&netdiskPartition,
												&netdiskEnableMode );
	
	} else {

		status = NetdiskManager_PreMountVolume( GlobalLfs.NetdiskManager,
												FALSE,
												instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.DeviceObject,
												instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.Vpb->RealDevice,
												&netdiskPartition,
												&netdiskEnableMode );
	}


	SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("NetdiskManager_IsNetdiskPartition status = %x\n", status) );

	if (!NT_SUCCESS(status)) {

		if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE) ||
			RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)) {

			NDASFS_ASSERT( FALSE );
			status = STATUS_FLT_DO_NOT_ATTACH;
			goto CtxInstanceSetupCleanup;
		}

		status = STATUS_FLT_DO_NOT_ATTACH;
		goto CtxInstanceSetupCleanup;
	} 
	
	switch (netdiskEnableMode) {

	case NETDISK_READ_ONLY:

		if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &fat, TRUE)) {

			if (GlobalLfs.NdasFatRoSupport) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );
	
				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}			
			
		} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE)) {

			if (!GlobalLfs.NdasFatRoSupport) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );
	
				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}			

		} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ntfs, TRUE)) {

			if (GlobalLfs.NdasNtfsRoSupport) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );

				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}
			
		} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)) {

			if (!GlobalLfs.NdasNtfsRoSupport) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );

				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}
			
		} else {

			NDASFS_ASSERT( FALSE );
		}

		break;

	case NETDISK_SECONDARY:
	case NETDISK_PRIMARY:
	case NETDISK_SECONDARY2PRIMARY:

		if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &fat, TRUE)) {

			if (GlobalLfs.NdasFatRwSupport &&
				FlagOn(netdiskPartition->EnabledNetdisk->NetdiskInformation.EnabledFeatures, NDASFEATURE_SIMULTANEOUS_WRITE)) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );
	
				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}			
			
		} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE)) {

			if (!(GlobalLfs.NdasFatRwSupport &&
				  FlagOn(netdiskPartition->EnabledNetdisk->NetdiskInformation.EnabledFeatures, NDASFEATURE_SIMULTANEOUS_WRITE))) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );
	
				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}			

		} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ntfs, TRUE)) {

			if (GlobalLfs.NdasNtfsRwSupport &&
				FlagOn(netdiskPartition->EnabledNetdisk->NetdiskInformation.EnabledFeatures, NDASFEATURE_SIMULTANEOUS_WRITE)) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );

				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}
			
		} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)) {

			if (!(GlobalLfs.NdasNtfsRwSupport &&
				  FlagOn(netdiskPartition->EnabledNetdisk->NetdiskInformation.EnabledFeatures, NDASFEATURE_SIMULTANEOUS_WRITE))) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );

				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}
			
		} else {

			NDASFS_ASSERT( FALSE );
		}
	
		break;

	default:

		NDASFS_ASSERT( FALSE );
		break;
	}

	LfsReference( &GlobalLfs );

    ExInitializeFastMutex( &instanceContext->LfsDeviceExt.FastMutex );
	instanceContext->LfsDeviceExt.ReferenceCount		= 1;

	InitializeListHead( &instanceContext->LfsDeviceExt.LfsQListEntry );

	instanceContext->LfsDeviceExt.Flags = LFS_DEVICE_FLAG_INITIALIZING;

	instanceContext->LfsDeviceExt.FileSpyDeviceObject	= NULL;
	instanceContext->LfsDeviceExt.InstanceContext		= instanceContext;

	FltReferenceContext( instanceContext->LfsDeviceExt.InstanceContext );

	instanceContext->LfsDeviceExt.NetdiskPartition		= netdiskPartition;
	instanceContext->LfsDeviceExt.NetdiskEnabledMode	= netdiskEnableMode;

	instanceContext->LfsDeviceExt.FilteringMode	= LFS_NO_FILTERING;

	instanceContext->LfsDeviceExt.DiskDeviceObject			= instanceContext->DiskDeviceObject;
	instanceContext->LfsDeviceExt.MountVolumeDeviceObject	= instanceContext->DiskDeviceObject;

    SPY_LOG_PRINT( SPYDEBUG_ERROR,
                   ("FileSpy!CtxInstanceSetup: instanceContext->LfsDeviceExt.DiskDeviceObject = %p\n",
					instanceContext->LfsDeviceExt.DiskDeviceObject) );

	ExInterlockedInsertTailList( &GlobalLfs.LfsDeviceExtQueue,
								 &instanceContext->LfsDeviceExt.LfsQListEntry,
								 &GlobalLfs.LfsDeviceExtQSpinLock );


	if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ntfs, TRUE)) {

		instanceContext->LfsDeviceExt.FileSystemType = LFS_FILE_SYSTEM_NTFS;

	} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)) {

		instanceContext->LfsDeviceExt.FileSystemType = LFS_FILE_SYSTEM_NDAS_NTFS;
	
	} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &fat, TRUE)) {

		instanceContext->LfsDeviceExt.FileSystemType = LFS_FILE_SYSTEM_FAT;

	} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE)) {

		instanceContext->LfsDeviceExt.FileSystemType = LFS_FILE_SYSTEM_NDAS_FAT;
	
	} else {

		NDASFS_ASSERT( FALSE ); 
	}

	NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
									instanceContext->LfsDeviceExt.NetdiskPartition,
									instanceContext->LfsDeviceExt.NetdiskEnabledMode,
									TRUE,
									instanceContext->LfsDeviceExt.FileSystemType,		
									&instanceContext->LfsDeviceExt,
									&instanceContext->LfsDeviceExt.NetdiskPartitionInformation );

	switch (netdiskEnableMode) {

	case NETDISK_READ_ONLY:

		instanceContext->LfsDeviceExt.FilteringMode = LFS_READONLY;

		break;

	case NETDISK_SECONDARY:

		instanceContext->LfsDeviceExt.FilteringMode = LFS_SECONDARY;

		break;

	case NETDISK_PRIMARY:
	case NETDISK_SECONDARY2PRIMARY:

		instanceContext->LfsDeviceExt.FilteringMode = LFS_PRIMARY;

		break;
	
	default:

		ASSERT( LFS_BUG );

		break;
	}

	SetFlag( instanceContext->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_MOUNTING );

	ASSERT( instanceContext->DiskDeviceObject->Vpb->DeviceObject );

	instanceContext->LfsDeviceExt.Vpb						= instanceContext->LfsDeviceExt.DiskDeviceObject->Vpb; // Vpb will be changed in IrpSp Why ?
	instanceContext->LfsDeviceExt.BaseVolumeDeviceObject	= instanceContext->LfsDeviceExt.Vpb->DeviceObject;

	switch (instanceContext->LfsDeviceExt.FilteringMode) {

	case LFS_READONLY: {
		
		//
		//	We don't support cache purging yet.
		//

		SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("LfsFsControlMountVolumeComplete: READONLY newDevExt->LfsDeviceExt = %p "
											"newDevExt->LfsDeviceExt.FileSystemType = %d\n",
											 &instanceContext->LfsDeviceExt, instanceContext->LfsDeviceExt.FileSystemType) );
		
		instanceContext->LfsDeviceExt.AttachedToDeviceObject = instanceContext->DeviceObject; //NULL; //instanceContext->NLExtHeader.AttachedToDeviceObject;

		NetdiskManager_MountVolumeComplete( GlobalLfs.NetdiskManager,
											instanceContext->LfsDeviceExt.NetdiskPartition,
											instanceContext->LfsDeviceExt.NetdiskEnabledMode,
											status,
											instanceContext->LfsDeviceExt.AttachedToDeviceObject );

		status = SpyFsControlReadonlyMountVolumeComplete( &instanceContext->LfsDeviceExt );

		break;
	}

	case LFS_PRIMARY: {

		instanceContext->LfsDeviceExt.AttachedToDeviceObject = instanceContext->DeviceObject; //NULL; //instanceContext->NLExtHeader.AttachedToDeviceObject;

		ASSERT( instanceContext->LfsDeviceExt.AttachedToDeviceObject );

		NetdiskManager_MountVolumeComplete( GlobalLfs.NetdiskManager,
											instanceContext->LfsDeviceExt.NetdiskPartition,
											instanceContext->LfsDeviceExt.NetdiskEnabledMode,
											status,
											instanceContext->LfsDeviceExt.AttachedToDeviceObject );

		SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("LfsFsControlMountVolumeComplete: LFS_PRIMARY newDevExt->LfsDeviceExt = %p "
											"newDevExt->LfsDeviceExt.FileSystemType = %d\n",
											 &instanceContext->LfsDeviceExt, instanceContext->LfsDeviceExt.FileSystemType) );

		status = STATUS_SUCCESS;
		break;
	}

	case LFS_SECONDARY: {

		instanceContext->LfsDeviceExt.AttachedToDeviceObject = instanceContext->DeviceObject; //NULL; //instanceContext->NLExtHeader.AttachedToDeviceObject;
					
		NetdiskManager_MountVolumeComplete( GlobalLfs.NetdiskManager,
											instanceContext->LfsDeviceExt.NetdiskPartition,
											instanceContext->LfsDeviceExt.NetdiskEnabledMode,
											status,
											instanceContext->LfsDeviceExt.AttachedToDeviceObject );

		SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("CtxInstanceSetup: LFS_SECONDARY newDevExt->LfsDeviceExt = %p "
											"newDevExt->LfsDeviceExt.FileSystemType = %d\n",
											 &instanceContext->LfsDeviceExt, instanceContext->LfsDeviceExt.FileSystemType) );

		status = SpyFsControlSecondaryMountVolumeComplete( &instanceContext->LfsDeviceExt );

		if (instanceContext->LfsDeviceExt.FilteringMode == LFS_SECONDARY_TO_PRIMARY) {
		
			NetdiskManager_ChangeMode( GlobalLfs.NetdiskManager,
									   instanceContext->LfsDeviceExt.NetdiskPartition,
									   &instanceContext->LfsDeviceExt.NetdiskEnabledMode );
		}

		break;
	}

	default:

		NDASFS_ASSERT( FALSE );

		NetdiskManager_MountVolumeComplete( GlobalLfs.NetdiskManager,
											instanceContext->LfsDeviceExt.NetdiskPartition,
											instanceContext->LfsDeviceExt.NetdiskEnabledMode,
											status,
											NULL );

		status = STATUS_SUCCESS;

		break;
	}

    //
    //  We completed initialization of this device object, so now
    //  clear the initializing flag.
    //

	if (status == STATUS_SUCCESS) {

		ClearFlag( instanceContext->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_INITIALIZING );
		ClearFlag( instanceContext->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_MOUNTING );

		SetFlag( instanceContext->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_MOUNTED );

	} else {

		NTSTATUS status2;


		NDASFS_ASSERT( FALSE );

		//
		//	Queue an event to notify user applications
		//

		XevtQueueVolumeInvalidOrLocked( -1,
										instanceContext->LfsDeviceExt.NetdiskPartitionInformation.NetdiskInformation.SlotNo,
										instanceContext->LfsDeviceExt.NetdiskPartitionInformation.NetdiskInformation.UnitDiskNo );

		//
		//	Try to unplug
		//

		status2 = NetdiskManager_UnplugNetdisk( GlobalLfs.NetdiskManager,
												instanceContext->LfsDeviceExt.NetdiskPartition,
												instanceContext->LfsDeviceExt.NetdiskEnabledMode );

		ASSERT( NT_SUCCESS(status2) );
	}

#endif

    //
    //  Get the NT volume name length
    //

    status = FltGetVolumeName( FltObjects->Volume, NULL, &volumeNameLength );

    if( !NT_SUCCESS( status ) &&
        (status != STATUS_BUFFER_TOO_SMALL) ) {

        DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR,
                    ("[Ctx]: Unexpected failure in FltGetVolumeName. (Volume = %p, Instance = %p, Status = 0x%x)\n",
                     FltObjects->Volume,
                     FltObjects->Instance,
                     status) );

        goto CtxInstanceSetupCleanup;
    }

    //
    //  Allocate a string big enough to take the volume name
    //

    instanceContext->VolumeName.MaximumLength = (USHORT) volumeNameLength;
    status = CtxAllocateUnicodeString( &instanceContext->VolumeName );

    if( !NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR,
                    ("[Ctx]: Failed to allocate volume name string. (Volume = %p, Instance = %p, Status = 0x%x)\n",
                     FltObjects->Volume,
                     FltObjects->Instance,
                     status) );

        goto CtxInstanceSetupCleanup;
    }

    //
    //  Get the NT volume name
    //

    status = FltGetVolumeName( FltObjects->Volume, &instanceContext->VolumeName, &volumeNameLength );

    if( !NT_SUCCESS( status ) ) {

        DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR,
                    ("[Ctx]: Unexpected failure in FltGetVolumeName. (Volume = %p, Instance = %p, Status = 0x%x)\n",
                     FltObjects->Volume,
                     FltObjects->Instance,
                     status) );

        goto CtxInstanceSetupCleanup;
    }


    instanceContext->Instance = FltObjects->Instance;
    instanceContext->Volume = FltObjects->Volume;

    //
    //  Set the instance context.
    //

    DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS,
                ("[Ctx]: Setting instance context %p for volume %wZ (Volume = %p, Instance = %p)\n",
                 instanceContext,
                 &instanceContext->VolumeName,
                 FltObjects->Volume,
                 FltObjects->Instance) );

    status = FltSetInstanceContext( FltObjects->Instance,
                                    FLT_SET_CONTEXT_KEEP_IF_EXISTS,
                                    instanceContext,
                                    NULL );

    if( !NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_INSTANCES | DEBUG_TRACE_ERROR,
                    ("[Ctx]: Failed to set instance context for volume %wZ (Volume = %p, Instance = %p, Status = 0x%08X)\n",
                     &instanceContext->VolumeName,
                     FltObjects->Volume,
                     FltObjects->Instance,
                     status) );
        goto CtxInstanceSetupCleanup;
    }

CtxInstanceSetupCleanup:

#if __NDAS_FS_MINI__

	if (status != STATUS_SUCCESS) {

		if (instanceContext->DiskDeviceObject) {

			ObDereferenceObject( instanceContext->DiskDeviceObject );
			instanceContext->DiskDeviceObject = NULL;
		}

		if (instanceContext->DeviceObject) {

			ObDereferenceObject( instanceContext->DeviceObject );
			instanceContext->DeviceObject = NULL;
		}

		if (instanceContext->VolumeProperties) {

			ExFreePoolWithTag( instanceContext->VolumeProperties, CTX_VOLUME_PROPERTY_TAG );
			instanceContext->VolumeProperties = NULL;
		}

		if (FlagOn(instanceContext->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_INITIALIZING)) {

			LfsDeviceExt_Dereference( &instanceContext->LfsDeviceExt );
		}
	}

#endif

    //
    //  If FltAllocateContext suceeded then we MUST release the context,
    //  irrespective of whether FltSetInstanceContext suceeded or not.
    //
    //  FltAllocateContext increments the ref count by one.
    //  A successful FltSetInstanceContext increments the ref count by one
    //  and also associates the context with the file system object
    //
    //  FltReleaseContext decrements the ref count by one.
    //
    //  When FltSetInstanceContext succeeds, calling FltReleaseContext will
    //  leave the context with a ref count of 1 corresponding to the internal
    //  reference to the context from the file system structures
    //
    //  When FltSetInstanceContext fails, calling FltReleaseContext will
    //  leave the context with a ref count of 0 which is correct since
    //  there is no reference to the context from the file system structures
    //

    if ( instanceContext != NULL ) {

        DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS,
                    ("[Ctx]: Releasing instance context %p (Volume = %p, Instance = %p)\n",
                     instanceContext,
                     FltObjects->Volume,
                     FltObjects->Instance) );

        FltReleaseContext( instanceContext );
    }


    if (NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_INSTANCES,
                    ("[Ctx]: Instance setup complete (Volume = %p, Instance = %p). Filter will attach to the volume.\n",
                     FltObjects->Volume,
                     FltObjects->Instance) );
    } else {

        DebugTrace( DEBUG_TRACE_INSTANCES,
                    ("[Ctx]: Instance setup complete (Volume = %p, Instance = %p). Filter will not attach to the volume.\n",
                     FltObjects->Volume,
                     FltObjects->Instance) );
    }

    return status;
}
Beispiel #2
0
NTSTATUS
NPInstanceSetup (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_SETUP_FLAGS Flags,
    __in DEVICE_TYPE VolumeDeviceType,
    __in FLT_FILESYSTEM_TYPE VolumeFilesystemType
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PVOLUME_CONTEXT context = NULL;
    ULONG retLen;
    UCHAR volPropBuffer[sizeof(FLT_VOLUME_PROPERTIES)+512];
    PFLT_VOLUME_PROPERTIES volProp = (PFLT_VOLUME_PROPERTIES)volPropBuffer;
    PDEVICE_OBJECT devObj = NULL;

    UNREFERENCED_PARAMETER( Flags );
    UNREFERENCED_PARAMETER( VolumeDeviceType );
    UNREFERENCED_PARAMETER( VolumeFilesystemType );
    PAGED_CODE();

    PT_DBG_PRINT( PTDBG_TRACE_ROUTINES,
                  ("minifilter1!NPInstanceSetup: Entered\n") );
    try
    {
        // Allocate a volume context structure.
        status = FltAllocateContext( FltObjects->Filter,
                                     FLT_VOLUME_CONTEXT,
                                     sizeof(VOLUME_CONTEXT),
                                     NonPagedPool,
                                     &context );
        if( !NT_SUCCESS(status) )
            leave;
        // Get the volume properties, so I can get a sector size
        status = FltGetVolumeProperties( FltObjects->Volume,
                                         volProp,
                                         sizeof(volPropBuffer),
                                         &retLen );
        if( !NT_SUCCESS(status) )
            leave;
        // Get sector size
        ASSERT((volProp->SectorSize == 0) || (volProp->SectorSize >= MIN_SECTOR_SIZE));
        context->SectorSize = max(volProp->SectorSize, MIN_SECTOR_SIZE);

        // Get device object, so I can get disk name
        context->Name.Buffer = NULL;
        status = FltGetDiskDeviceObject( FltObjects->Volume, &devObj );
        if( !NT_SUCCESS(status) )
            leave;

        status = IoVolumeDeviceToDosName( devObj, &context->Name);
        if( !NT_SUCCESS(status) )
            leave;

        // Set the context
        status = FltSetVolumeContext( FltObjects->Volume,
                                      FLT_SET_CONTEXT_KEEP_IF_EXISTS,
                                      context,
                                      NULL );

        DbgPrint("minifilter1!NPInstanceSetup: [%wZ 0x%04x/0x%04x]\n",
                  &context->Name, context->SectorSize, volProp->SectorSize);
        DbgPrint("[%wZ - %wZ - %wZ]\n",
                &volProp->FileSystemDriverName,
                &volProp->FileSystemDeviceName,
                &volProp->RealDeviceName);
        if (status == STATUS_FLT_CONTEXT_ALREADY_DEFINED )
        {
            status = STATUS_SUCCESS;
        }
    }
    finally
    {
        //  Always release the context.  If the set failed, it will free the
        //  context.  If not, it will remove the reference added by the set.
        //  Note that the name buffer in the context will get freed by the
        //  NPCleanupVolumeContext() routine.
        if(context)
            FltReleaseContext( context );
        if(devObj)
            ObDereferenceObject( devObj );
    }

    return status;
}
Beispiel #3
0
/* 
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
 *
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
 */
NTSTATUS
cfsd_InstanceSetup( IN PCFLT_RELATED_OBJECTS FltObjects,
                    IN FLT_INSTANCE_SETUP_FLAGS Flags,
                    IN DEVICE_TYPE VolumeDeviceType,
                    IN FLT_FILESYSTEM_TYPE VolumeFilesystemType )

{

#if DBG
UCHAR                    VPBuffer[sizeof(FLT_VOLUME_PROPERTIES)+512];
PFLT_VOLUME_PROPERTIES   VolumeProperties = (PFLT_VOLUME_PROPERTIES)VPBuffer;
PDEVICE_OBJECT           theDeviceObject = NULL;
ULONG                    ReturnedLength;
NTSTATUS                 Status;
UNICODE_STRING           DosName;


     Status = FltGetVolumeProperties( FltObjects->Volume,
                                      VolumeProperties,
                                      sizeof( VPBuffer ),
                                      &ReturnedLength );

     if ( !NT_SUCCESS( Status ) ) 
     {
     }

     // Zero it so we can show a NULL if no DOS name is found
     RtlZeroMemory( &DosName, sizeof( UNICODE_STRING ) );

     Status = FltGetDiskDeviceObject( FltObjects->Volume, &theDeviceObject );

     if ( NT_SUCCESS( Status ) ) 
     {
      Status = IoVolumeDeviceToDosName( theDeviceObject, &DosName );
     }
     else
     {  
     }

#endif // End #if DBG

 UNREFERENCED_PARAMETER( FltObjects );

// *************************************************************************************


 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "** [ ATTACHMENT REQUEST 0x%X ] **", Flags ) );

    // Handle our instance setup under different situations and decide if we want
    // to attach under those circumstances
     if ( ( FlagOn( FLTFL_INSTANCE_SETUP_AUTOMATIC_ATTACHMENT, Flags ) ) &&
          ( FlagOn( FLTFL_INSTANCE_SETUP_AUTOMATIC_ATTACHMENT, gAttachRequirements->InstanceFlags ) ) )
     {
       // If FLTFL_INSTANCE_SETUP_NEWLY_MOUNTED_VOLUME is set and we are not accepting it, return STATUS_FLT_DO_NOT_ATTACH
       if ( ( FlagOn( FLTFL_INSTANCE_SETUP_NEWLY_MOUNTED_VOLUME, Flags ) ) &&
            ( !FlagOn( FLTFL_INSTANCE_SETUP_NEWLY_MOUNTED_VOLUME, gAttachRequirements->InstanceFlags ) ) )
       {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED attach method - FLTFL_INSTANCE_SETUP_AUTOMATIC_ATTACHMENT -> FLTFL_INSTANCE_SETUP_NEWLY_MOUNTED_VOLUME\n") );
        return STATUS_FLT_DO_NOT_ATTACH;
       } // End if ( ( FlagOn( FLTFL_INSTANCE_SETUP_NEWLY_MOUNTED_VOLUME, Flags ) ) &&
         //          ( !FlagOn( FLTFL_INSTANCE_SETUP_NEWLY_MOUNTED_VOLUME, gAttachRequirements->InstanceFlags ) ) )

#if DBG
  if ( FlagOn( FLTFL_INSTANCE_SETUP_NEWLY_MOUNTED_VOLUME, Flags ) )
  {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ACCEPTED attach method - FLTFL_INSTANCE_SETUP_AUTOMATIC_ATTACHMENT -> FLTFL_INSTANCE_SETUP_NEWLY_MOUNTED_VOLUME\n") );
  }
  else
  {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ACCEPTED attach method - FLTFL_INSTANCE_SETUP_AUTOMATIC_ATTACHMENT\n") );
  } 
#endif // End #if DBG

     } // End if ( ( FlagOn( FLTFL_INSTANCE_SETUP_AUTOMATIC_ATTACHMENT, Flags ) ) &&
       //          ( FlagOn( FLTFL_INSTANCE_SETUP_AUTOMATIC_ATTACHMENT, gAttachRequirements->InstanceFlags ) ) )
     else if ( ( FlagOn( FLTFL_INSTANCE_SETUP_MANUAL_ATTACHMENT, Flags ) ) &&
               ( FlagOn( FLTFL_INSTANCE_SETUP_MANUAL_ATTACHMENT, gAttachRequirements->InstanceFlags ) ) )
     {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ACCEPTED attach method - FLTFL_INSTANCE_SETUP_MANUAL_ATTACHMENT\n") );

     } // End if ( ( FlagOn( FLTFL_INSTANCE_SETUP_MANUAL_ATTACHMENT, Flags ) ) &&
       //          ( FlagOn( FLTFL_INSTANCE_SETUP_MANUAL_ATTACHMENT, gAttachRequirements->InstanceFlags ) ) )
     else
     {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED ATTACHMENT - Unknown FLAGS in fInstanceSetup()\n") );
      return STATUS_FLT_DO_NOT_ATTACH;
     }

// *************************************************************************************


   switch ( VolumeDeviceType )
   {
    case FILE_DEVICE_UNKNOWN:
        {
          if ( FlagOn( gAttachRequirements->InstanceVolumeDeviceTypes, MASK_FILE_DEVICE_UNKNOWN ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
        {
          if ( FlagOn( gAttachRequirements->InstanceVolumeDeviceTypes, MASK_FILE_DEVICE_CD_ROM_FILE_SYSTEM ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume  <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FILE_DEVICE_DFS_FILE_SYSTEM:
        {
          if ( FlagOn( gAttachRequirements->InstanceVolumeDeviceTypes, MASK_FILE_DEVICE_DFS_FILE_SYSTEM ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FILE_DEVICE_DISK_FILE_SYSTEM:
        {
          if ( FlagOn( gAttachRequirements->InstanceVolumeDeviceTypes, MASK_FILE_DEVICE_DISK_FILE_SYSTEM ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FILE_DEVICE_NETWORK_FILE_SYSTEM:
        {
          if ( FlagOn( gAttachRequirements->InstanceVolumeDeviceTypes, MASK_FILE_DEVICE_NETWORK_FILE_SYSTEM ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }

    case FILE_DEVICE_TAPE_FILE_SYSTEM:
        {
          if ( FlagOn( gAttachRequirements->InstanceVolumeDeviceTypes, MASK_FILE_DEVICE_TAPE_FILE_SYSTEM ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }

    case FILE_DEVICE_NULL:
        {
          if ( FlagOn( gAttachRequirements->InstanceVolumeDeviceTypes, MASK_FILE_DEVICE_NULL ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }

    case FILE_DEVICE_VIRTUAL_DISK:
        {
          if ( FlagOn( gAttachRequirements->InstanceVolumeDeviceTypes, MASK_FILE_DEVICE_VIRTUAL_DISK ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume <%wZ> [%wZ] (%wZ)\n", &DosName, &VolumeProperties->RealDeviceName, &VolumeProperties->FileSystemDeviceName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
        default :
               {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACHED to NONSUPPORTED Volume Device type : 0x%x\n",VolumeDeviceType ) );

                return STATUS_FLT_DO_NOT_ATTACH;
               }

   } // End switch ( VolumeDeviceType 

// *************************************************************************************


   switch ( VolumeFilesystemType )
   {
    case FLT_FSTYPE_UNKNOWN:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_UNKNOWN ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to File System type : FLT_FSTYPE_UNKNOWN [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_UNKNOWN [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_RAW:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_RAW ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_RAW [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_RAW [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_NTFS:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_NTFS ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_NTFS [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_NTFS [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_FAT:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_FAT ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_FAT [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_FAT [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_CDFS:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_CDFS ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_CDFS [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_CDFS [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_UDFS:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_UDFS ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_UDFS [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_UDFS [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_LANMAN:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_LANMAN ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_LANMAN [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_LANMAN [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_WEBDAV:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_WEBDAV ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_WEBDAV [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_WEBDAV [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }
         break;
        }
    case FLT_FSTYPE_RDPDR:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_RDPDR ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_RDPDR [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_RDPDR [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_NFS:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_NFS ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_NFS [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_NFS [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_MS_NETWARE:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_MS_NETWARE) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_MS_NETWARE [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_MS_NETWARE [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_NETWARE:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_NETWARE ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_NETWARE [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_NETWARE [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_BSUDF:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_BSUDF ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_BSUDF [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_BSUDF [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_MUP:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_MUP ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_MUP [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_MUP [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_RSFX:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_RSFX) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_RSFX [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_RSFX [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_ROXIO_UDF1:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_ROXIO_UDF1) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_ROXIO_UDF1 [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_ROXIO_UDF1 [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_ROXIO_UDF2:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_ROXIO_UDF2 ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_ROXIO_UDF2 [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_ROXIO_UDF2 [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    case FLT_FSTYPE_ROXIO_UDF3:
        {

          if ( FlagOn( gAttachRequirements->InstancedFileSystemTypes, MASK_FSTYPE_ROXIO_UDF3 ) )
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "ATTACHED to Volume File System type : FLT_FSTYPE_ROXIO_UDF3 [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
          }
          else
          {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to Volume File System type : FLT_FSTYPE_ROXIO_UDF3 [%wZ]\n",&VolumeProperties->FileSystemDriverName ) );
           return STATUS_FLT_DO_NOT_ATTACH;
          }

         break;
        }
    default :
           {
 DBG_PRINT( DbgOutput, DBG_ATTACH_INSTANCE, (PRINT_TAG_ATTACH "REFUSED to ATTACH to NONSUPPORTED Volume File System type : 0x%x\n",VolumeFilesystemType ) );

            return STATUS_FLT_DO_NOT_ATTACH;
           }

   } // End switch ( VolumeFilesystemType )

// *************************************************************************************

 return STATUS_SUCCESS;
}
NTSTATUS
FmmInstanceSetup (
    _In_ PCFLT_RELATED_OBJECTS FltObjects,
    _In_ FLT_INSTANCE_SETUP_FLAGS Flags,
    _In_ DEVICE_TYPE VolumeDeviceType,
    _In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType
    )
/*++

Routine Description:

    This routine is called whenever a new instance is created on a volume. This
    gives us a chance to decide if we need to attach to this volume or not.

Arguments:

    FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
        opaque handles to this filter, instance and its associated volume.

    Flags - Flags describing the reason for this attach request.

Return Value:

    STATUS_SUCCESS - attach
    STATUS_FLT_DO_NOT_ATTACH - do not attach

--*/
{
    PFMM_INSTANCE_CONTEXT instanceContext = NULL;
    PDEVICE_OBJECT diskDeviceObject;
    NTSTATUS status = STATUS_SUCCESS;

    UNREFERENCED_PARAMETER( VolumeDeviceType );

    PAGED_CODE();

    DebugTrace( DEBUG_TRACE_INSTANCES,
                ("[Fmm]: Instance setup started (Volume = %p, Instance = %p)\n",
                 FltObjects->Volume,
                 FltObjects->Instance) );

    //
    //  Check if the file system mounted is ntfs or fat
    //
    //  The sample picks NTFS, FAT and ReFS as examples. The metadata
    //  handling demostrated in the sample can be applied
    //  to any file system
    //

    if (VolumeFilesystemType != FLT_FSTYPE_NTFS && VolumeFilesystemType != FLT_FSTYPE_FAT && VolumeFilesystemType != FLT_FSTYPE_REFS) {

        //
        //  An unknown file system is mounted which we do not care
        //

        DebugTrace( DEBUG_TRACE_INSTANCES,
                    ("[Fmm]: Unsupported file system mounted (Volume = %p, Instance = %p)\n",
                     FltObjects->Volume,
                     FltObjects->Instance) );

        status = STATUS_NOT_SUPPORTED;
        goto FmmInstanceSetupCleanup;
    }

    //
    //  Get the disk device object and make sure it is a disk device type and does not
    //  have any of the device characteristics we do not support.
    //
    //  The sample picks the device characteristics to demonstrate how to access and
    //  check the device characteristics in order to make a decision to attach. The
    //  metadata handling demostrated in the sample is not limited to the
    //  characteristics we have used in the sample.
    //

    status = FltGetDiskDeviceObject( FltObjects->Volume, &diskDeviceObject );

    if (!NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_INSTANCES | DEBUG_TRACE_ERROR,
                    ("[Fmm]: Failed to get device object (Volume = %p, Status = 0x%08X)\n",
                     FltObjects->Volume,
                     status) );
        goto FmmInstanceSetupCleanup;
    }

    if (diskDeviceObject->DeviceType != FILE_DEVICE_DISK ||
        FlagOn( diskDeviceObject->Characteristics, FMM_UNSUPPORTED_DEVICE_CHARACS )) {

        DebugTrace( DEBUG_TRACE_INSTANCES,
                    ("[Fmm]: Unsupported device type or device characteristics (Volume = %p, Instance = %p DiskDeviceObjectDeviceTYpe = 0x%x, DiskDeviceObjectCharacteristics = 0x%x)\n",
                     FltObjects->Volume,
                     FltObjects->Instance,
                     diskDeviceObject->DeviceType,
                     diskDeviceObject->Characteristics) );

        ObDereferenceObject( diskDeviceObject );
        status = STATUS_NOT_SUPPORTED;
        goto FmmInstanceSetupCleanup;
    }

    ObDereferenceObject( diskDeviceObject );

    //
    //  Allocate and initialize the context for this volume
    //

    status = FltAllocateContext( FltObjects->Filter,
                                 FLT_INSTANCE_CONTEXT,
                                 FMM_INSTANCE_CONTEXT_SIZE,
                                 NonPagedPool,
                                 &instanceContext );

    if( !NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_INSTANCES | DEBUG_TRACE_ERROR,
                    ("[Fmm]: Failed to allocate instance context (Volume = %p, Instance = %p, Status = 0x%08X)\n",
                     FltObjects->Volume,
                     FltObjects->Instance,
                     status) );

        goto FmmInstanceSetupCleanup;
    }

    FLT_ASSERT( instanceContext != NULL );

    RtlZeroMemory( instanceContext, FMM_INSTANCE_CONTEXT_SIZE );

    instanceContext->Flags = 0;
    instanceContext->Instance = FltObjects->Instance;
    instanceContext->FilesystemType = VolumeFilesystemType;
    instanceContext->Volume = FltObjects->Volume;
    ExInitializeResourceLite( &instanceContext->MetadataResource );


    //
    //  Set the instance context.
    //

    status = FltSetInstanceContext( FltObjects->Instance,
                                    FLT_SET_CONTEXT_KEEP_IF_EXISTS,
                                    instanceContext,
                                    NULL );

    if( !NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_INSTANCES | DEBUG_TRACE_ERROR,
                    ("[Fmm]: Failed to set instance context (Volume = %p, Instance = %p, Status = 0x%08X)\n",
                     FltObjects->Volume,
                     FltObjects->Instance,
                     status) );
        goto FmmInstanceSetupCleanup;
    }

    //
    //  Acquire exclusive access to the instance context
    //

    FmmAcquireResourceExclusive( &instanceContext->MetadataResource );

    //
    //  Sanity - the instance context cannot be in a transition state during instance setup
    //

    FLT_ASSERT( !FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_TRANSITION) );

    //
    //  Open the filter metadata on disk
    //
    //  The sample will attach to volume if it finds its metadata file on the volume.
    //  If this is a manual attachment then the sample filter will create its metadata
    //  file and attach to the volume.
    //

    status = FmmOpenMetadata( instanceContext,
                              BooleanFlagOn( Flags, FLTFL_INSTANCE_SETUP_MANUAL_ATTACHMENT ) );

    //
    //  Relinquish exclusive access to the instance context
    //

    FmmReleaseResource( &instanceContext->MetadataResource );

    if (!NT_SUCCESS( status )) {

        goto FmmInstanceSetupCleanup;
    }


FmmInstanceSetupCleanup:

    //
    //  If FltAllocateContext suceeded then we MUST release the context,
    //  irrespective of whether FltSetInstanceContext suceeded or not.
    //
    //  FltAllocateContext increments the ref count by one.
    //  A successful FltSetInstanceContext increments the ref count by one
    //  and also associates the context with the file system object
    //
    //  FltReleaseContext decrements the ref count by one.
    //
    //  When FltSetInstanceContext succeeds, calling FltReleaseContext will
    //  leave the context with a ref count of 1 corresponding to the internal
    //  reference to the context from the file system structures
    //
    //  When FltSetInstanceContext fails, calling FltReleaseContext will
    //  leave the context with a ref count of 0 which is correct since
    //  there is no reference to the context from the file system structures
    //

    if ( instanceContext != NULL ) {

        FltReleaseContext( instanceContext );
    }


    if (NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_INSTANCES,
                    ("[Fmm]: Instance setup complete (Volume = %p, Instance = %p). Filter will attach to the volume.\n",
                     FltObjects->Volume,
                     FltObjects->Instance) );
    } else {

        DebugTrace( DEBUG_TRACE_INSTANCES,
                    ("[Fmm]: Instance setup complete (Volume = %p, Instance = %p). Filter will not attach to the volume.\n",
                     FltObjects->Volume,
                     FltObjects->Instance) );
    }

    //
    //  If this is an automatic attachment (mount, load, etc) and we are not 
    //  attaching to this volume because we do not support attaching to this 
    //  volume, then simply return STATUS_FLT_DO_NOT_ATTACH. If we return 
    //  anything else fltmgr logs an event log indicating failure to attach. 
    //  Since this failure to attach is not really an error, we do not want 
    //  this failure to be logged as an error in the event log. For all other
    //  error codes besides the ones we consider "normal", if is ok for fltmgr
    //  to actually log the failure to attach.
    //
    //  If this is a manual attach attempt that we have failed then we want to 
    //  give the user a clear indication of why the attachment failed. Hence in 
    //  this case, we will not override the error status with STATUS_FLT_DO_NOT_ATTACH
    //  irrespective of the cause of the failure to attach
    //

    if (status == STATUS_NOT_SUPPORTED && 
       !FlagOn( Flags, FLTFL_INSTANCE_SETUP_MANUAL_ATTACHMENT )) {

        status = STATUS_FLT_DO_NOT_ATTACH;
    }

    return status;
}