Пример #1
0
VOID
PrimarySession_Dereference (
	IN 	PPRIMARY_SESSION	PrimarySession
	)
{
    LONG result;


    result = InterlockedDecrement( &PrimarySession->ReferenceCount );
    ASSERT( result >= 0 );

    if (result == 0) {

		KIRQL		oldIrql;
		PPRIMARY    primary = PrimarySession->Primary;

		
		KeAcquireSpinLock(&PrimarySession->Primary->PrimarySessionQSpinLock[PrimarySession->ListenSocketIndex], &oldIrql);
		RemoveEntryList(&PrimarySession->ListEntry);
		KeReleaseSpinLock(&PrimarySession->Primary->PrimarySessionQSpinLock[PrimarySession->ListenSocketIndex], oldIrql);
		
		ExFreePoolWithTag( PrimarySession, LFS_ALLOC_TAG );

		SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE,
					("PrimarySession_Dereference: PrimarySession = %p is Freed\n", PrimarySession) );

		Primary_Dereference( primary );
	}
}
Пример #2
0
VOID
Primary_FileSystemShutdown (
	IN PPRIMARY	Primary
	)
{
	ULONG		listenSocketIndex;


	Primary_Reference(Primary);

	SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_ERROR,
		("Primary_FileSystemShutdown: Entered primary = %p\n", Primary));

	do 
	{
		if(Primary->Agent.ThreadHandle == NULL)
		{
			ASSERT(LFS_BUG);
			break;
		}

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

		if(Primary->Agent.Flags & PRIMARY_AGENT_TERMINATED)
		{
			break;
		} 
		else
		{
			PPRIMARY_AGENT_REQUEST	primaryAgentRequest;
			NTSTATUS				ntStatus;
			LARGE_INTEGER			timeOut;
	
		
			primaryAgentRequest = AllocPrimaryAgentRequest(TRUE);
			primaryAgentRequest->RequestType = PRIMARY_AGENT_REQ_SHUTDOWN;

			QueueingPrimaryAgentRequest(
				Primary,
				primaryAgentRequest
				);

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

			ASSERT(ntStatus == STATUS_SUCCESS);

			KeClearEvent(&primaryAgentRequest->CompleteEvent);

			if(ntStatus == STATUS_SUCCESS) 
			{
			    SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
								("Primary_FileSystemShutdown: thread shutdown\n"));
			} 
			else
			{
				ASSERT(LFS_BUG);
				break;
			}
		}
	}while(0);
	
	for(listenSocketIndex=0; listenSocketIndex<MAX_SOCKETLPX_INTERFACE; listenSocketIndex++)
	{
		if(Primary->Agent.ListenSocket[listenSocketIndex].Active != TRUE)
			continue;
		

		while(1) 
		{	
			KIRQL		oldIrql;
			BOOLEAN		found;
		    PLIST_ENTRY	primarySessionListEntry;

	
			KeAcquireSpinLock(&Primary->PrimarySessionQSpinLock[listenSocketIndex], &oldIrql);
			found = FALSE;

			for (primarySessionListEntry = Primary->PrimarySessionQueue[listenSocketIndex].Flink;
				 primarySessionListEntry != &Primary->PrimarySessionQueue[listenSocketIndex];
				 primarySessionListEntry = primarySessionListEntry->Flink)
			{		
				PPRIMARY_SESSION primarySession;
		 
				primarySession = CONTAINING_RECORD (primarySessionListEntry, PRIMARY_SESSION, ListEntry);
		 
				//if(primarySession->LfsDeviceExt && primarySession->LfsDeviceExt->FileSystemType == FileSystemType)
				//{
					RemoveEntryList(primarySessionListEntry);
				    KeReleaseSpinLock(&Primary->PrimarySessionQSpinLock[listenSocketIndex], oldIrql);
					
					InitializeListHead(primarySessionListEntry);
					PrimarySession_FileSystemShutdown(primarySession);

					found = TRUE;
					break;			
				//}
			}
			
			if(found == FALSE)
			{
				KeReleaseSpinLock(&Primary->PrimarySessionQSpinLock[listenSocketIndex], oldIrql);
				break;
			}
		} 
	}

	Primary_Dereference(Primary);

	return;
}
Пример #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;
}
Пример #4
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;
}