Ejemplo n.º 1
0
PLFS_TABLE
LfsTable_Create(
	IN PLFS	Lfs
	)
{
	PLFS_TABLE	lfsTable;


	LfsReference (Lfs);

	lfsTable = ExAllocatePoolWithTag( 
						NonPagedPool, 
                        sizeof(LFS_TABLE),
						LFS_ALLOC_TAG
						);
	
	if (lfsTable == NULL)
	{
		ASSERT(LFS_INSUFFICIENT_RESOURCES);
		LfsDereference (Lfs);
		return NULL;
	}

	RtlZeroMemory(
		lfsTable,
		sizeof(LFS_TABLE)
		);

	KeInitializeSpinLock(&lfsTable->SpinLock);
	InitializeListHead(&lfsTable->LfsTabPartitionList) ;
	lfsTable->ReferenceCount = 1;
	lfsTable->Lfs = Lfs;
	

	
	return lfsTable;
}
Ejemplo n.º 2
0
PPRIMARY
Primary_Create (
	IN PLFS	Lfs
	)
{
	PPRIMARY			primary;
 	OBJECT_ATTRIBUTES	objectAttributes;
	LONG				i;
	NTSTATUS			ntStatus;
	LARGE_INTEGER		timeOut;


	SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
		("Primary_Create: Entered\n"));

	LfsReference (Lfs);

	primary = ExAllocatePoolWithTag( 
						NonPagedPool, 
                        sizeof(PRIMARY),
						LFS_ALLOC_TAG
						);
	
	if (primary == NULL)
	{
		ASSERT(LFS_INSUFFICIENT_RESOURCES);
		LfsDereference (Lfs);

		return NULL;
	}

	RtlZeroMemory(
		primary,
		sizeof(PRIMARY)
		);

	KeInitializeSpinLock(&primary->SpinLock);	
	primary->ReferenceCount	= 1;

	primary->Lfs = Lfs;

//	InitializeListHead(&primary->LfsDeviceExtQueue);
//	KeInitializeSpinLock(&primary->LfsDeviceExtQSpinLock);

	for(i=0; i<MAX_SOCKETLPX_INTERFACE; i++)
	{
		InitializeListHead(&primary->PrimarySessionQueue[i]);
		KeInitializeSpinLock(&primary->PrimarySessionQSpinLock[i]);
	}

	primary->Agent.ThreadHandle = 0;
	primary->Agent.ThreadObject = NULL;

	primary->Agent.Flags = 0;

	KeInitializeEvent(&primary->Agent.ReadyEvent, NotificationEvent, FALSE);

	InitializeListHead(&primary->Agent.RequestQueue);
	KeInitializeSpinLock(&primary->Agent.RequestQSpinLock);
	KeInitializeEvent(&primary->Agent.RequestEvent, NotificationEvent, FALSE);

	
	primary->Agent.ListenPort = DEFAULT_PRIMARY_PORT;
	primary->Agent.ActiveListenSocketCount = 0;

	
	InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

	ntStatus = PsCreateSystemThread(
					&primary->Agent.ThreadHandle,
					THREAD_ALL_ACCESS,
					&objectAttributes,
					NULL,
					NULL,
					PrimaryAgentThreadProc,
					primary
					);
	
	if(!NT_SUCCESS(ntStatus)) 
	{
		ASSERT(LFS_UNEXPECTED);
		Primary_Close(primary);
		
		return NULL;
	}

	ntStatus = ObReferenceObjectByHandle(
					primary->Agent.ThreadHandle,
					FILE_READ_DATA,
					NULL,
					KernelMode,
					&primary->Agent.ThreadObject,
					NULL
					);

	if(!NT_SUCCESS(ntStatus)) 
	{
		ASSERT(LFS_INSUFFICIENT_RESOURCES);
		Primary_Close(primary);
		
		return NULL;
	}

	timeOut.QuadPart = - LFS_TIME_OUT;		// 10 sec
	ntStatus = KeWaitForSingleObject(
					&primary->Agent.ReadyEvent,
					Executive,
					KernelMode,
					FALSE,
					&timeOut
					);

	ASSERT(ntStatus == STATUS_SUCCESS);

	KeClearEvent(&primary->Agent.ReadyEvent);

	if(ntStatus != STATUS_SUCCESS) 
	{
		ASSERT(LFS_BUG);
		Primary_Close(primary);
		
		return NULL;
	}
	
	SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
		("Primary_Create: primary = %p\n", primary));

	return primary;
}
Ejemplo n.º 3
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;
}