Exemplo n.º 1
0
//
// To clean up terminated PrimarySession is performed here
//
VOID
Primary_AcceptConnection(
	IN PPRIMARY			Primary,
	IN HANDLE			ListenFileHandle,
	IN PFILE_OBJECT		ListenFileObject,
	IN  ULONG			ListenSocketIndex,
	IN PLPX_ADDRESS		RemoteAddress
	)
{
    PLIST_ENTRY				listEntry;
	PPRIMARY_SESSION		newPrimarySession;
	KIRQL					oldIrql;



	newPrimarySession = PrimarySession_Create(
							Primary, 
							ListenFileHandle, 
							ListenFileObject,
							ListenSocketIndex,
							RemoteAddress
					);

	if(newPrimarySession == NULL)
	{	
		LpxTdiDisconnect(ListenFileObject, 0);
		LpxTdiDisassociateAddress(ListenFileObject);
		LpxTdiCloseConnection(
					ListenFileHandle, 
					ListenFileObject
					);
	}

		
	KeAcquireSpinLock(&Primary->SpinLock, &oldIrql);

	listEntry = Primary->PrimarySessionQueue[ListenSocketIndex].Flink;
	while(listEntry != &Primary->PrimarySessionQueue[ListenSocketIndex])
	{
		PPRIMARY_SESSION primarySession;
	

		primarySession = CONTAINING_RECORD (listEntry, PRIMARY_SESSION, ListEntry);			
		listEntry = listEntry->Flink;

		if(primarySession->ThreadFlags & PRIMARY_SESSION_THREAD_TERMINATED
			|| primarySession->State == SESSION_CLOSED)
	{
			KeReleaseSpinLock(&Primary->SpinLock, oldIrql);
			PrimarySession_Close(primarySession);
			KeAcquireSpinLock(&Primary->SpinLock, &oldIrql);
		}
	}

	KeReleaseSpinLock(&Primary->SpinLock, oldIrql);

	return;
}
Exemplo n.º 2
0
PPRIMARY_SESSION
PrimarySession_Create (
	IN  PPRIMARY					Primary,
	IN	HANDLE						ListenFileHandle,
	IN  PFILE_OBJECT				ListenFileObject,
	IN  PLPXTDI_OVERLAPPED_CONTEXT	ListenOverlapped,
	IN  ULONG						ListenSocketIndex,
	IN  PLPX_ADDRESS				RemoteAddress
	)
{
	PPRIMARY_SESSION	primarySession;
 	OBJECT_ATTRIBUTES	objectAttributes;
	NTSTATUS			status;
	LARGE_INTEGER		timeOut;

		
	NDAS_ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

	Primary_Reference( Primary );

	primarySession = FsRtlAllocatePoolWithTag( NonPagedPool, sizeof(PRIMARY_SESSION), LFS_ALLOC_TAG );
	
	if (primarySession == NULL) {

		NDAS_ASSERT( NDAS_ASSERT_INSUFFICIENT_RESOURCES );

		Primary_Dereference( Primary );
		return NULL;
	}

	try {
	
		RtlZeroMemory( primarySession, sizeof(PRIMARY_SESSION) );

		primarySession->Flags = PRIMARY_SESSION_FLAG_INITIALIZING;

		primarySession->ReferenceCount = 1;
		primarySession->Primary = Primary;
		
		ExInitializeFastMutex( &primarySession->FastMutex );
		
		InitializeListHead( &primarySession->ListEntry );

		KeInitializeEvent( &primarySession->ReadyEvent, NotificationEvent, FALSE );
	
		InitializeListHead( &primarySession->RequestQueue );
		KeInitializeSpinLock( &primarySession->RequestQSpinLock );
		KeInitializeEvent( &primarySession->RequestEvent, NotificationEvent, FALSE );

		InitializeListHead( &primarySession->NetdiskPartitionListEntry );

		primarySession->ThreadHandle = 0;
		primarySession->ThreadObject = NULL;

		NdasFcInitialize( &primarySession->SendNdasFcStatistics );
		NdasFcInitialize( &primarySession->RecvNdasFcStatistics );

		primarySession->ConnectionFileHandle	= ListenFileHandle;
		primarySession->ConnectionFileObject	= ListenFileObject;
		
		LpxTdiV2MoveOverlappedContext( &primarySession->ReceiveOverlapped, ListenOverlapped );

		RtlCopyMemory( &primarySession->RemoteAddress, RemoteAddress, sizeof(LPX_ADDRESS) );
		primarySession->IsLocalAddress			= Lfs_IsLocalAddress(RemoteAddress);

		SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE, ("primarySession->ConnectionFileHandle = %p\n", primarySession->ConnectionFileHandle) );

		primarySession->Thread.SessionState = SESSION_CLOSE;
		primarySession->SessionContext.SessionKey = (UINT32)PtrToUlong(primarySession);

		primarySession->SessionContext.PrimaryMaxDataSize = (LfsRegistry.MaxDataTransferPri < DEFAULT_MAX_DATA_SIZE)
													? LfsRegistry.MaxDataTransferPri:DEFAULT_MAX_DATA_SIZE;

		primarySession->SessionContext.SecondaryMaxDataSize = (LfsRegistry.MaxDataTransferSec < DEFAULT_MAX_DATA_SIZE)
													? LfsRegistry.MaxDataTransferSec:DEFAULT_MAX_DATA_SIZE;

		//
		//	Initialize transport context for traffic control
		//

		InitTransCtx( &primarySession->Thread.TransportCtx, primarySession->SessionContext.SecondaryMaxDataSize );

		SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE, ("PrimarySession_Create: PriMaxData:%08u SecMaxData:%08u\n",
												  primarySession->SessionContext.PrimaryMaxDataSize,
												  primarySession->SessionContext.SecondaryMaxDataSize) );

		ExAcquireFastMutex( &GlobalLfs.FastMutex );
		primarySession->SessionContext.Uid = GlobalLfs.Uid++;
		ExReleaseFastMutex( &GlobalLfs.FastMutex );

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

		status = PsCreateSystemThread( &primarySession->ThreadHandle,
									   THREAD_ALL_ACCESS,
									   &objectAttributes,
									   NULL,
									   NULL,
									   PrimarySessionThreadProc,
									   primarySession );
	
		if (!NT_SUCCESS(status)) {

			leave;
		}

		status = ObReferenceObjectByHandle( primarySession->ThreadHandle,
											FILE_READ_DATA,
											NULL,
											KernelMode,
											&primarySession->ThreadObject,
											NULL );

		if (!NT_SUCCESS(status)) {

			leave;
		}

		timeOut.QuadPart = -LFS_TIME_OUT;
		status = KeWaitForSingleObject( &primarySession->ReadyEvent,
										Executive,
										KernelMode,
										FALSE,
										&timeOut );


		if (!NT_SUCCESS(status)) {

			leave;
		}

		KeClearEvent( &primarySession->ReadyEvent );

		ExInterlockedInsertTailList( &Primary->PrimarySessionQueue[ListenSocketIndex],
									 &primarySession->ListEntry,
									 &Primary->PrimarySessionQSpinLock[ListenSocketIndex] );

		SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE, ("PrimarySession_Create: The primary thread are ready\n") );
		SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE, ("Fat PrimarySession_Create: primarySession = %p\n", primarySession) );
	
	} finally {

		if (AbnormalTermination()) {

			status = STATUS_UNSUCCESSFUL;
		}

		if (!NT_SUCCESS(status)) {

			ASSERT( LFS_UNEXPECTED );
			PrimarySession_Close( primarySession );
			primarySession = NULL;
		}
	}

	return primarySession;
}
Exemplo n.º 3
0
VOID
Primary_Close (
	IN PPRIMARY	Primary
	)
{
	ULONG		listenSocketIndex;
	

	SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
		("Primary_Close: Entered primary = %p\n", Primary));

	for(listenSocketIndex=0; listenSocketIndex<MAX_SOCKETLPX_INTERFACE; listenSocketIndex++)
	{
	    PLIST_ENTRY	primarySessionListEntry;
		BOOLEAN		found   = FALSE;


		if(Primary->Agent.ListenSocket[listenSocketIndex].Active != TRUE)
			continue;
		
		while(primarySessionListEntry = 
				ExInterlockedRemoveHeadList(
						&Primary->PrimarySessionQueue[listenSocketIndex],
						&Primary->PrimarySessionQSpinLock[listenSocketIndex]
						)
			) 
		{
			PPRIMARY_SESSION primarySession;
		 
			primarySession = CONTAINING_RECORD (primarySessionListEntry, PRIMARY_SESSION, ListEntry);
			InitializeListHead(primarySessionListEntry);
			PrimarySession_Close(primarySession);
		}
	}

	if(Primary->Agent.ThreadHandle == NULL)
	{
		ASSERT(LFS_BUG);
		Primary_Dereference(Primary);

		return;
	}

	ASSERT(Primary->Agent.ThreadObject != NULL);

	if(Primary->Agent.Flags & PRIMARY_AGENT_TERMINATED)
	{
		ObDereferenceObject(Primary->Agent.ThreadObject);

		Primary->Agent.ThreadHandle = NULL;
		Primary->Agent.ThreadObject = NULL;

	} else
	{
		PPRIMARY_AGENT_REQUEST		primaryAgentRequest;
		NTSTATUS					ntStatus;
		LARGE_INTEGER				timeOut;
	
		
		primaryAgentRequest = AllocPrimaryAgentRequest(FALSE);
		primaryAgentRequest->RequestType = PRIMARY_AGENT_REQ_DISCONNECT;

		QueueingPrimaryAgentRequest(
			Primary,
			primaryAgentRequest
			);

		primaryAgentRequest = AllocPrimaryAgentRequest (FALSE);
		primaryAgentRequest->RequestType = PRIMARY_AGENT_REQ_DOWN;

		QueueingPrimaryAgentRequest(
			Primary,
			primaryAgentRequest
			);

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

		ASSERT(ntStatus == STATUS_SUCCESS);

		if(ntStatus == STATUS_SUCCESS) 
		{
		    SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
							("Primary_Close: thread stoped\n"));

			ObDereferenceObject(Primary->Agent.ThreadObject);

			Primary->Agent.ThreadHandle = NULL;
			Primary->Agent.ThreadObject = NULL;
		
		} else
		{
			ASSERT(LFS_BUG);
			return;
		}
	}

	Primary_Dereference(Primary);

	return;
}
Exemplo n.º 4
0
PPRIMARY_SESSION
PrimarySession_Create (
	IN  PIRP_CONTEXT			IrpContext,  
	IN	PVOLUME_DEVICE_OBJECT	VolDo,		 
	IN  PSESSION_INFORMATION	SessionInformation,
	IN  PIRP					Irp
	)
{
	PPRIMARY_SESSION	primarySession;
 	OBJECT_ATTRIBUTES	objectAttributes;
	NTSTATUS			status;
	LARGE_INTEGER		timeOut;

		
	ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

	VolDo_Reference( VolDo );

	primarySession = FsRtlAllocatePoolWithTag( NonPagedPool, sizeof(PRIMARY_SESSION), NDFAT_ALLOC_TAG );
	
	if (primarySession == NULL) {

		ASSERT( NDASFAT_INSUFFICIENT_RESOURCES );
		VolDo_Dereference( VolDo );
		return NULL;
	}

	try {
	
		RtlZeroMemory( primarySession, sizeof(PRIMARY_SESSION) );

		primarySession->Flags = PRIMARY_SESSION_FLAG_INITIALIZING;

		primarySession->ReferenceCount = 1;
		primarySession->VolDo = VolDo;
		
		ExInitializeFastMutex( &primarySession->FastMutex )
		
		InitializeListHead( &primarySession->ListEntry );

		primarySession->NetdiskPartitionInformation = SessionInformation->NetdiskPartitionInformation;
	
		RtlInitEmptyUnicodeString( &primarySession->NetdiskPartitionInformation.VolumeName,
								   primarySession->NetdiskPartitionInformation.VolumeNameBuffer,
								   sizeof(primarySession->NetdiskPartitionInformation.VolumeNameBuffer) );

		if (RtlAppendUnicodeStringToString( &primarySession->NetdiskPartitionInformation.VolumeName,
											&SessionInformation->NetdiskPartitionInformation.VolumeName) != STATUS_SUCCESS) {

			ASSERT( NDASFAT_UNEXPECTED );
		}

		ASSERT( primarySession->NetdiskPartitionInformation.VolumeName.Buffer == primarySession->NetdiskPartitionInformation.VolumeNameBuffer );

		primarySession->ConnectionFileHandle		= SessionInformation->ConnectionFileHandle;
		primarySession->ConnectionFileObject		= SessionInformation->ConnectionFileObject;

		primarySession->RemoteAddress				= SessionInformation->RemoteAddress;
		primarySession->IsLocalAddress				= SessionInformation->IsLocalAddress;

		primarySession->Irp									= Irp;

		primarySession->SessionContext = SessionInformation->SessionContext;

		primarySession->SessionContext.PrimaryMaxDataSize	= DEFAULT_NDAS_MAX_DATA_SIZE; //SessionInformation->PrimaryMaxDataSize;
		primarySession->SessionContext.SecondaryMaxDataSize	= DEFAULT_NDAS_MAX_DATA_SIZE; // SessionInformation->SecondaryMaxDataSize;

		DebugTrace2( 0, Dbg2, ("primarySession->ConnectionFileHandle = %x " 
							   "primarySession->SessionContext.PrimaryMaxDataSize = %x primarySession->SessionContext.SecondaryMaxDataSize = %x\n", 
							    primarySession->ConnectionFileHandle, primarySession->SessionContext.PrimaryMaxDataSize, primarySession->SessionContext.SecondaryMaxDataSize) );

		KeInitializeEvent( &primarySession->ReadyEvent, NotificationEvent, FALSE );
	
		InitializeListHead( &primarySession->RequestQueue );
		KeInitializeSpinLock( &primarySession->RequestQSpinLock );
		KeInitializeEvent( &primarySession->RequestEvent, NotificationEvent, FALSE );

		primarySession->ThreadHandle = 0;
		primarySession->ThreadObject = NULL;

		primarySession->Thread.TdiReceiveContext.Irp = NULL;
		KeInitializeEvent( &primarySession->Thread.TdiReceiveContext.CompletionEvent, NotificationEvent, FALSE );

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

		primarySession->Thread.SessionState = SESSION_TREE_CONNECT;
	
		ExInterlockedInsertTailList( &VolDo->PrimarySessionQueue,
									 &primarySession->ListEntry,
									 &VolDo->PrimarySessionQSpinLock );

		status = PsCreateSystemThread( &primarySession->ThreadHandle,
									   THREAD_ALL_ACCESS,
									   &objectAttributes,
									   NULL,
									   NULL,
									   PrimarySessionThreadProc,
									   primarySession );
	
		if (!NT_SUCCESS(status)) {

			leave;
		}

		status = ObReferenceObjectByHandle( primarySession->ThreadHandle,
											FILE_READ_DATA,
											NULL,
											KernelMode,
											&primarySession->ThreadObject,
											NULL );

		if (!NT_SUCCESS(status)) {

			leave;
		}

		timeOut.QuadPart = -NDASFAT_TIME_OUT;
		status = KeWaitForSingleObject( &primarySession->ReadyEvent,
										Executive,
										KernelMode,
										FALSE,
										&timeOut );


		if (!NT_SUCCESS(status)) {

			leave;
		}

		KeClearEvent( &primarySession->ReadyEvent );

		DebugTrace2( 0, Dbg, ("PrimarySession_Create: The primary thread are ready\n") );
	
		DebugTrace2( 0, Dbg2, ("Fat PrimarySession_Create: primarySession = %p\n", primarySession) );
	
	} finally {

		if (AbnormalTermination()) {

			status = IrpContext->ExceptionStatus;
		}

		if (!NT_SUCCESS(status)) {

			ASSERT( NDASFAT_UNEXPECTED );
			PrimarySession_Close( primarySession );
			primarySession = NULL;
		}
	}

	return primarySession;
}