Example #1
0
// You must wait Completion Event If not, It can be crashed !!!
NTSTATUS
LpxTdiListen_LSTrans(
	IN	PFILE_OBJECT		ConnectionFileObject,
	IN  PTDI_LISTEN_CONTEXT	TdiListenContext,
	IN  PULONG				Flags,
	IN	PLARGE_INTEGER		TimeOut
	) {

	UNREFERENCED_PARAMETER(TimeOut);

	return	LpxTdiListenWithCompletionEvent(ConnectionFileObject, TdiListenContext, Flags);
}
Example #2
0
NTSTATUS 
DraidListenConnection(
	PDRAID_LISTEN_CONTEXT ListenContext
) {
	NTSTATUS status;
//	KIRQL	oldIrql;
	
	KeClearEvent(&ListenContext->TdiListenContext.CompletionEvent);
	
	status = LpxTdiOpenConnection(
			&ListenContext->ListenFileHandle,
			&ListenContext->ListenFileObject,
			NULL);

	if(!NT_SUCCESS(status)) 
	{
		ASSERT(FALSE);// This should not happen
		return status;
	}

	// 3. Associate address
	status = LpxTdiAssociateAddress(
			ListenContext->ListenFileObject,
			ListenContext->AddressFileHandle
			);

	if(!NT_SUCCESS(status)) 
	{
		ASSERT(FALSE);
		LpxTdiCloseConnection(ListenContext->ListenFileHandle, ListenContext->ListenFileObject);
		return status;
	}

	// 4. Start listening

	ListenContext->Flags = TDI_QUERY_ACCEPT; //???

	status = LpxTdiListenWithCompletionEvent(
					ListenContext->ListenFileObject,
					&ListenContext->TdiListenContext,
					&ListenContext->Flags
				);
	if(!NT_SUCCESS(status)) {
		ASSERT(FALSE); // May be this can be happen if multiple instances of this function is called with same address
		LpxTdiDisassociateAddress(ListenContext->ListenFileObject);
		LpxTdiCloseConnection(ListenContext->ListenFileHandle, ListenContext->ListenFileObject);
		return status;
	}
	return status;
}
Example #3
0
static
NTSTATUS
PrimaryOpenOneListenSocket(
		PPRIMARY_LISTEN_SOCKET	listenSock,
		PLPX_ADDRESS			NICAddr
	) {
	NTSTATUS	ntStatus;
	HANDLE					addressFileHandle = NULL;
	PFILE_OBJECT			addressFileObject = NULL;
	HANDLE					listenFileHandle = NULL;
	PFILE_OBJECT			listenFileObject = NULL;
	

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

	listenSock->Active = FALSE;
	RtlCopyMemory(
			listenSock->NICAddress.Node,
			NICAddr->Node,
			ETHER_ADDR_LENGTH
		);

	//
	//	open a address.
	//
	ntStatus = LpxTdiOpenAddress(
						&addressFileHandle,
						&addressFileObject,
						NICAddr
					);

	if(!NT_SUCCESS(ntStatus)) 
	{
		ASSERT(LPX_BUG);
		return ntStatus;
	}

	listenSock->Active = TRUE;

	KeClearEvent(
			&listenSock->TdiListenContext.CompletionEvent
		);

	listenSock->AddressFileHandle = addressFileHandle;
	listenSock->AddressFileObject = addressFileObject;
		
	ntStatus = MakeConnectionObject(addressFileHandle, addressFileObject, &listenFileHandle, &listenFileObject);
	
	if(!NT_SUCCESS(ntStatus)) 
		{
			ASSERT(LPX_BUG);
			LpxTdiCloseAddress (addressFileHandle, addressFileObject);

			listenSock->Active = FALSE;
	
			return STATUS_UNSUCCESSFUL;
		}

	listenSock->ListenFileHandle = listenFileHandle;
	listenSock->ListenFileObject = listenFileObject;
		
	SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
				( "PrimaryOpenOneListenSocket: opened a address:'%02X:%02X:%02X:%02X:%02X:%02X 0x%04X'\n",
					NICAddr->Node[0],NICAddr->Node[1],NICAddr->Node[2],
					NICAddr->Node[3],NICAddr->Node[4],NICAddr->Node[5],
					NTOHS(NICAddr->Port)
			) );

	listenSock->Flags	= TDI_QUERY_ACCEPT;

	ntStatus = LpxTdiListenWithCompletionEvent(
					listenSock->ListenFileObject,
					&listenSock->TdiListenContext,
					&listenSock->Flags
				);

	if(!NT_SUCCESS(ntStatus)) 
	{
		ASSERT(LPX_BUG);
		LpxTdiDisassociateAddress(listenFileObject);
		LpxTdiCloseConnection(listenFileHandle, listenFileObject);
		LpxTdiCloseAddress (addressFileHandle, addressFileObject);

		listenSock->Active = FALSE;
		ntStatus = STATUS_UNSUCCESSFUL;
	}

	return ntStatus;
}
Example #4
0
NTSTATUS
BindListenSockets(
	IN 	PPRIMARY	Primary
	)
{
	NTSTATUS				ntStatus;
	PSOCKETLPX_ADDRESS_LIST	socketLpxAddressList;
	LONG					idx_addr;


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

	Primary->Agent.ActiveListenSocketCount = 0;
	socketLpxAddressList = &Primary->Agent.SocketLpxAddressList;
	ntStatus = LpxTdiGetAddressList(
		socketLpxAddressList
        );

	if(!NT_SUCCESS(ntStatus)) 
	{
		//ASSERT(LPX_BUG);
		return	ntStatus;
	}
	
	if(socketLpxAddressList->iAddressCount <= 0) 
	{
		SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
					( "BindListenSockets: No NICs in the host.\n") );

		return STATUS_UNSUCCESSFUL;
	}
	
	if(socketLpxAddressList->iAddressCount > MAX_SOCKETLPX_INTERFACE)
		socketLpxAddressList->iAddressCount = MAX_SOCKETLPX_INTERFACE;

	for(idx_addr = 0; idx_addr < socketLpxAddressList->iAddressCount; idx_addr ++) 
	{
		LPX_ADDRESS		NICAddr;
	
		HANDLE			addressFileHandle = NULL;
		PFILE_OBJECT	addressFileObject = NULL;

		HANDLE			listenFileHandle = NULL;
		PFILE_OBJECT	listenFileObject = NULL;
		
		
		Primary->Agent.ListenSocket[idx_addr].Active = FALSE;

		if( (0 == socketLpxAddressList->SocketLpx[idx_addr].LpxAddress.Node[0]) &&
			(0 == socketLpxAddressList->SocketLpx[idx_addr].LpxAddress.Node[1]) &&
			(0 == socketLpxAddressList->SocketLpx[idx_addr].LpxAddress.Node[2]) &&
			(0 == socketLpxAddressList->SocketLpx[idx_addr].LpxAddress.Node[3]) &&
			(0 == socketLpxAddressList->SocketLpx[idx_addr].LpxAddress.Node[4]) &&
			(0 == socketLpxAddressList->SocketLpx[idx_addr].LpxAddress.Node[5]) ) 
		{
			SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
						( "BindListenSockets: We don't use SocketLpx device.\n"));
			continue;
		}

		RtlCopyMemory(
				&Primary->Agent.ListenSocket[idx_addr].NICAddress,
				&socketLpxAddressList->SocketLpx[idx_addr].LpxAddress, 
				sizeof(LPX_ADDRESS)
			);

		RtlCopyMemory(
				&NICAddr, 
				&socketLpxAddressList->SocketLpx[idx_addr].LpxAddress, 
				sizeof(LPX_ADDRESS)
			);

		NICAddr.Port = HTONS(Primary->Agent.ListenPort);
	
		//
		//	open a address.
		//
		ntStatus = LpxTdiOpenAddress(
						&addressFileHandle,
						&addressFileObject,
						&NICAddr
						);

		if(!NT_SUCCESS(ntStatus)) 
		{
			ASSERT(LPX_BUG);
			continue;
		}

		Primary->Agent.ListenSocket[idx_addr].Active = TRUE;

		KeInitializeEvent(&Primary->Agent.ListenSocket[idx_addr].TdiListenContext.CompletionEvent, NotificationEvent, FALSE);

		Primary->Agent.ListenSocket[idx_addr].AddressFileHandle = addressFileHandle;
		Primary->Agent.ListenSocket[idx_addr].AddressFileObject = addressFileObject;
		
		Primary->Agent.ActiveListenSocketCount ++;

		ntStatus = MakeConnectionObject(addressFileHandle, addressFileObject, &listenFileHandle, &listenFileObject);
	
		if(!NT_SUCCESS(ntStatus)) 
		{
			ASSERT(LPX_BUG);
			LpxTdiCloseAddress (addressFileHandle, addressFileObject);

			Primary->Agent.ListenSocket[idx_addr].Active = FALSE;
			Primary->Agent.ActiveListenSocketCount --;
	
			continue;
		}

		Primary->Agent.ListenSocket[idx_addr].ListenFileHandle = listenFileHandle;
		Primary->Agent.ListenSocket[idx_addr].ListenFileObject = listenFileObject;

		
		SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
					( "BindListenSockets: opened a address:'%02X:%02X:%02X:%02X:%02X:%02X 0x%04X'\n",
						NICAddr.Node[0],NICAddr.Node[1],NICAddr.Node[2],
						NICAddr.Node[3],NICAddr.Node[4],NICAddr.Node[5],
						NTOHS(NICAddr.Port)
						) );

		Primary->Agent.ListenSocket[idx_addr].Flags	= TDI_QUERY_ACCEPT;

		ntStatus = LpxTdiListenWithCompletionEvent(
						Primary->Agent.ListenSocket[idx_addr].ListenFileObject,
						&Primary->Agent.ListenSocket[idx_addr].TdiListenContext,
						&Primary->Agent.ListenSocket[idx_addr].Flags
						);

		if(!NT_SUCCESS(ntStatus)) 
		{
			ASSERT(LPX_BUG);
			LpxTdiDisassociateAddress(listenFileObject);
			LpxTdiCloseConnection(listenFileHandle, listenFileObject);
			LpxTdiCloseAddress (addressFileHandle, addressFileObject);

			Primary->Agent.ListenSocket[idx_addr].Active = FALSE;
			Primary->Agent.ActiveListenSocketCount --;
	
			continue;
		}
	}

	return STATUS_SUCCESS;
}
Example #5
0
VOID
PrimaryAgentThreadProc(
	IN 	PPRIMARY	Primary
	)
{
	BOOLEAN			primaryAgentThreadExit = FALSE;
	ULONG			listenSocketIndex;
	PKWAIT_BLOCK	waitBlocks;

	SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
				("PrimaryAgentThreadProc: Start\n"));

	Primary->Agent.Flags |= PRIMARY_AGENT_INITIALIZING;
	
	//
	// Allocate wait block
	//
	 waitBlocks = ExAllocatePool(NonPagedPool, sizeof(KWAIT_BLOCK) * MAXIMUM_WAIT_OBJECTS);
	 if(waitBlocks == NULL) {
		 ASSERT(LFS_REQUIRED);
		 PsTerminateSystemThread(STATUS_INSUFFICIENT_RESOURCES);
	 }

	for(listenSocketIndex=0; listenSocketIndex<MAX_SOCKETLPX_INTERFACE; listenSocketIndex++)
		KeInitializeEvent(
					&Primary->Agent.ListenSocket[listenSocketIndex].TdiListenContext.CompletionEvent, 
					NotificationEvent, 
					FALSE
					);

	BindListenSockets(
		Primary
		);

	Primary->Agent.Flags |= PRIMARY_AGENT_START;
				
	KeSetEvent(&Primary->Agent.ReadyEvent, IO_DISK_INCREMENT, FALSE);


	while(primaryAgentThreadExit == FALSE)
	{
		PKEVENT				events[MAXIMUM_WAIT_OBJECTS];
		LONG				eventCnt;

		ULONG				i;

		LARGE_INTEGER		timeOut;
		NTSTATUS			ntStatus;
		PLIST_ENTRY			primaryAgentRequestEntry;


		ASSERT(MAX_SOCKETLPX_INTERFACE + 1 <= MAXIMUM_WAIT_OBJECTS);

		eventCnt = 0;
		events[eventCnt++] = &Primary->Agent.RequestEvent;

		if(!BooleanFlagOn(Primary->Agent.Flags, PRIMARY_AGENT_SHUTDOWN))
		{
			for(i=0; i<MAX_SOCKETLPX_INTERFACE; i++)
			{
				if(Primary->Agent.ListenSocket[i].TdiListenContext.Irp &&
					Primary->Agent.ListenSocket[i].Active)
				{
					events[eventCnt++] = &Primary->Agent.ListenSocket[i].TdiListenContext.CompletionEvent;
				}
				else
				{
					// events[eventCnt++] = NULL; // I wanna set NULL, But It's not Work
					events[eventCnt++] = &Primary->Agent.ListenSocket[i].TdiListenContext.CompletionEvent;
				}
			}

			ASSERT(eventCnt == MAX_SOCKETLPX_INTERFACE + 1);
		}

		timeOut.QuadPart = - 5 * HZ;
		ntStatus = KeWaitForMultipleObjects(
					eventCnt,
					events,
					WaitAny,
					Executive,
					KernelMode,
					TRUE,
					&timeOut,
					waitBlocks
				);

		if(ntStatus == STATUS_TIMEOUT) 
		{
			continue;
		}

		SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE,
			("PrimaryAgentThreadProc: NTSTATUS:%lu\n", ntStatus));
		

		if(!NT_SUCCESS(ntStatus) || ntStatus >= eventCnt)
		{
			ASSERT(LFS_UNEXPECTED);
			SetFlag(Primary->Agent.Flags, PRIMARY_AGENT_ERROR);

			primaryAgentThreadExit = TRUE;

			continue;
		}

		KeClearEvent(events[ntStatus]);

		if(0 == ntStatus)
		{
			SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE,
					("PrimaryAgentThreadProc: RequestEvent received\n"));

			while(primaryAgentRequestEntry = 
					ExInterlockedRemoveHeadList(
							&Primary->Agent.RequestQueue,
							&Primary->Agent.RequestQSpinLock
							)
				) 
			{
				PPRIMARY_AGENT_REQUEST		primaryAgentRequest;

				primaryAgentRequest = CONTAINING_RECORD(
										primaryAgentRequestEntry,
										PRIMARY_AGENT_REQUEST,
										ListEntry
										);
	
				switch(primaryAgentRequest->RequestType) 
				{

				case PRIMARY_AGENT_REQ_DISCONNECT:
				{
					CloseListenSockets(
						Primary,
						FALSE
						);
				
					break;
				}

				case PRIMARY_AGENT_REQ_SHUTDOWN:
				{
					CloseListenSockets(
						Primary,
						TRUE
						);				
					SetFlag(Primary->Agent.Flags, PRIMARY_AGENT_SHUTDOWN);
					break;
				}

				case PRIMARY_AGENT_REQ_DOWN:

					primaryAgentThreadExit = TRUE;
					break;

				//
				//	added to adapt network card changes.
				//
				case PRIMARY_AGENT_REQ_NIC_DISABLED:
				
					SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
						("PrimaryAgentThreadProc: PRIMARY_AGENT_REQ_NIC_DISABLED\n"));
					PrimaryAgentNICDisabled(Primary, &primaryAgentRequest->AddressList);
				
					break;

				case PRIMARY_AGENT_REQ_NIC_ENABLED:
				
					SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE,
						("PrimaryAgentThreadProc: PRIMARY_AGENT_REQ_NIC_ENABLED\n"));
					PrimaryAgentNICEnabled(Primary, &primaryAgentRequest->AddressList);
				
					break;

				default:
		
					ASSERT(LFS_BUG);
					SetFlag(Primary->Agent.Flags, PRIMARY_AGENT_ERROR);

					break;
				}

				if(primaryAgentRequest->Synchronous == TRUE)
						KeSetEvent(&primaryAgentRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE);
				else
					DereferencePrimaryAgentRequest(
						primaryAgentRequest
						);
			}

			continue;	
		}

		ASSERT(1 <= ntStatus && ntStatus < eventCnt); // LpxEvent 
		
		if(	1 <= ntStatus &&
			ntStatus <= MAX_SOCKETLPX_INTERFACE
			) // Connected 
		{
			NTSTATUS		tdiStatus;
			HANDLE			listenFileHandle;
			PFILE_OBJECT	listenFileObject;
			HANDLE			connFileHandle;
			PFILE_OBJECT	connFileObject;
			PPRIMARY_LISTEN_SOCKET	listenSocket;
			LPX_ADDRESS		remoteAddress;

			listenSocket = &Primary->Agent.ListenSocket[ntStatus-1];

			//
			//	retreive a connection file and remote address.
			//
			connFileHandle = listenSocket->ListenFileHandle;
			connFileObject = listenSocket->ListenFileObject;
			RtlCopyMemory(&remoteAddress, &listenSocket->TdiListenContext.RemoteAddress, sizeof(LPX_ADDRESS));

			listenSocket->TdiListenContext.Irp = NULL;
			listenSocket->ListenFileHandle = NULL;
			listenSocket->ListenFileObject = NULL;
			KeClearEvent(&listenSocket->TdiListenContext.CompletionEvent);

			if(!listenSocket->Active) 
			{
				SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
						("ListenSocket is not active. Maybe a NIC disabled.\n"));
				continue;

			} 
			else if(listenSocket->TdiListenContext.Status != STATUS_SUCCESS) 
			{
				LpxTdiCloseAddress (
					listenSocket->AddressFileHandle, 
					listenSocket->AddressFileObject
					);

				listenSocket->Active = FALSE;
				Primary->Agent.ActiveListenSocketCount --;

				SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
						("Listen IRP #%d failed.\n", ntStatus));
				continue;
			}

			SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
					("PrimaryAgentThreadProc: Connect from %02X:%02X:%02X:%02X:%02X:%02X 0x%4X\n",
						listenSocket->TdiListenContext.RemoteAddress.Node[0], listenSocket->TdiListenContext.RemoteAddress.Node[1],
						listenSocket->TdiListenContext.RemoteAddress.Node[2], listenSocket->TdiListenContext.RemoteAddress.Node[3],
						listenSocket->TdiListenContext.RemoteAddress.Node[4], listenSocket->TdiListenContext.RemoteAddress.Node[5],
						NTOHS(listenSocket->TdiListenContext.RemoteAddress.Port)
						));

			//
			//	Make a new listen connection first of all to get another connection.
			//	It must be earlier than start a session that takes long time.
			//	Primary cannot accept a connection before it creates a new listen object.
			//
			tdiStatus = MakeConnectionObject(
							listenSocket->AddressFileHandle,
							listenSocket->AddressFileObject,
							&listenFileHandle,
							&listenFileObject
							);

			if(!NT_SUCCESS(tdiStatus)) 
			{
				ASSERT(LPX_BUG);
				LpxTdiCloseAddress (
					listenSocket->AddressFileHandle, 
					listenSocket->AddressFileObject
					);

				listenSocket->Active = FALSE;
				Primary->Agent.ActiveListenSocketCount --;
	
				goto start_session;
			}

			listenSocket->ListenFileHandle = listenFileHandle;
			listenSocket->ListenFileObject = listenFileObject;

			listenSocket->Flags	= TDI_QUERY_ACCEPT;
			tdiStatus = LpxTdiListenWithCompletionEvent(
							listenSocket->ListenFileObject,
							&listenSocket->TdiListenContext,
							&listenSocket->Flags
							);

			if(!NT_SUCCESS(tdiStatus)) 
			{
				ASSERT(LPX_BUG);
				LpxTdiDisassociateAddress(listenFileObject);
				LpxTdiCloseConnection(listenFileHandle, listenFileObject);
				LpxTdiCloseAddress (
					listenSocket->AddressFileHandle, 
					listenSocket->AddressFileObject
					);
				listenSocket->Active = FALSE;
				Primary->Agent.ActiveListenSocketCount --;
	
			}

start_session:
			//
			//	start a session.
			//
			Primary_AcceptConnection(Primary, connFileHandle, connFileObject, ntStatus-1, &remoteAddress);
			
			continue;
		}
	}

	for(listenSocketIndex=0; listenSocketIndex<MAX_SOCKETLPX_INTERFACE; listenSocketIndex++)
		KeClearEvent(&Primary->Agent.ListenSocket[listenSocketIndex].TdiListenContext.CompletionEvent);

	//
	// Free wait blocks
	//

	ExFreePool(waitBlocks);

	SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
				("PrimaryAgentThreadProc: PsTerminateSystemThread\n"));
	
	Primary->Agent.Flags |= PRIMARY_AGENT_TERMINATED;

	PsTerminateSystemThread(STATUS_SUCCESS);
}