Example #1
0
BOOL
CLpxStreamListener::GetAcceptResult(
	OUT SOCKADDR_LPX* lpLocalAddr,
	OUT SOCKADDR_LPX* lpRemoteAddr, 
	OUT LPDWORD lpcbReceived, 
	OUT CONST BYTE** ppbData, 
	OUT LPDWORD lpdwFlags /* = NULL */)
{
	BOOL fSuccess = ::WSAGetOverlappedResult(
		m_sock,
		&m_ovReceive,
		lpcbReceived,
		TRUE,
		lpdwFlags);

	if (!fSuccess) {
		XTLTRACE("CLpxStreamListener.WSAGetOverlappedResult failed, error=0x%X\n", 
			GetLastError());
		return FALSE;
	}

	*ppbData = (CONST BYTE*) m_wsaReceiveBuffer.buf;

	SOCKADDR_LPX *pLocalAddr, *pRemoteAddr;
	INT iLocalAddrLen, iRemoteAddrLen;

	LPFN_GETACCEPTEXSOCKADDRS lpfnAcceptExSockaddrs = NULL;
	GUID GuidAcceptExSockaddrs = WSAID_GETACCEPTEXSOCKADDRS;
	DWORD cbRead;
	INT iResult = ::WSAIoctl(m_sock, 
		SIO_GET_EXTENSION_FUNCTION_POINTER, 
		&GuidAcceptExSockaddrs, 
		sizeof(GuidAcceptExSockaddrs),
		&lpfnAcceptExSockaddrs, 
		sizeof(lpfnAcceptExSockaddrs), 
		&cbRead,
		NULL, 
		NULL);

	if (NULL == lpfnAcceptExSockaddrs) {
		XTLTRACE("Cannot load AcceptEx function, error=0x%X\n", GetLastError());
		return FALSE;
	}

	lpfnAcceptExSockaddrs(
		m_wsaReceiveBuffer.buf, 
		m_wsaReceiveBuffer.len,
		sizeof(SOCKADDR_LPX) + 16,
		sizeof(SOCKADDR_LPX) + 16,
		(sockaddr**) &pLocalAddr,
		&iLocalAddrLen,
		(sockaddr**) &pRemoteAddr,
		&iRemoteAddrLen);

	*lpLocalAddr = *pLocalAddr;
	*lpRemoteAddr = *pRemoteAddr;

	return TRUE;
}
Example #2
0
BOOL 
CLpxStreamConnection::Connect(
	CONST SOCKADDR_LPX* pRemoteAddr, 
	CONST BYTE* lpSendBuffer, 
	DWORD dwSendDataLen, 
	LPDWORD lpcbSent)
{
	_ASSERTE(INVALID_SOCKET != m_sock);

	ResetSendOverlapped();

	LPFN_CONNECTEX lpfnConnectEx = NULL;
	GUID GuidConnectEx = WSAID_CONNECTEX;
	DWORD cbRead;
	INT iResult = ::WSAIoctl(m_sock, 
		SIO_GET_EXTENSION_FUNCTION_POINTER, 
		&GuidConnectEx, 
		sizeof(GuidConnectEx),
		&lpfnConnectEx, 
		sizeof(lpfnConnectEx), 
		&cbRead,
		NULL, 
		NULL);

	if (NULL == lpfnConnectEx) {
		XTLTRACE("Cannot load ConnectEx function, error=0x%X\n", GetLastError());
		return FALSE;
	}

	BOOL fSuccess = lpfnConnectEx(
		m_sock,
		(const sockaddr*) pRemoteAddr,
		sizeof(SOCKADDR_LPX),
		(PVOID) lpSendBuffer,
		dwSendDataLen,
		lpcbSent,
		&m_ovSend);

	if (fSuccess) {
		fSuccess = ::SetEvent(m_hSentEvent);
		_ASSERTE(fSuccess);
		return TRUE;
	}

	if (ERROR_IO_PENDING != ::WSAGetLastError()) {
		XTLTRACE("CLpxStreamConnection.ConnectEx failed, socket=%p, error=0x%X\n", 
			reinterpret_cast<PVOID>(m_sock), WSAGetLastError());
		return FALSE;
	}

	return TRUE;
}
Example #3
0
BOOL
CLpxDatagramBroadcastSocket::Create()
{
	BOOL fSuccess = CLpxDatagramSocket::Create();
	if (!fSuccess) {
		return FALSE;
	}
	
	BOOL bBroadcast = TRUE;

	fSuccess = CLpxAsyncSocket::SetSockOpt(
		SO_BROADCAST, 
		(CONST BYTE*) &bBroadcast, 
		sizeof(bBroadcast));

	if (!fSuccess) 
	{
		DWORD error = GetLastError();

		(void) CLpxAsyncSocket::Close();

		XTLTRACE("Setting opt to SO_BROADCAST failed, socket=%p, error=0x%X\n",
			reinterpret_cast<PVOID>(m_sock), error);
		return FALSE;
	}

	return TRUE;
}
Example #4
0
BOOL
CLpxAsyncSocket::_GetRecvResult( 
	OUT LPDWORD lpcbReceived, 
	OUT BYTE** ppbData, 
	OUT LPDWORD lpdwFlags /* = NULL */)
{
	DWORD cbReceived = 0;
	DWORD dwFlags = 0;

	BOOL fSuccess = ::WSAGetOverlappedResult(
		m_sock,
		&m_ovReceive,
		&cbReceived,
		TRUE,
		&dwFlags);
	
	if (!fSuccess)
	{
		XTLTRACE("GetRecvResult.WSAGetOverlappedResult failed, socket=%p, error=0x%X\n", 
			reinterpret_cast<PVOID>(m_sock), GetLastError());
		return FALSE;
	}

	*ppbData = (BYTE*)m_wsaReceiveBuffer.buf;
	if (lpcbReceived) *lpcbReceived = cbReceived;
	if (lpdwFlags) *lpdwFlags = dwFlags;

	return TRUE;
}
Example #5
0
BOOL 
CLpxAsyncSocket::AllocRecvBuf(DWORD cbSize)
{
	if (cbSize > m_wsaReceiveBuffer.len) {

		if (NULL != m_wsaReceiveBuffer.buf) {
			m_wsaReceiveBuffer.buf = (char*) ::HeapReAlloc(
				::GetProcessHeap(),
				HEAP_ZERO_MEMORY,
				m_wsaReceiveBuffer.buf,
				cbSize);
		} else {
			m_wsaReceiveBuffer.buf = (char*) ::HeapAlloc(
				::GetProcessHeap(),
				HEAP_ZERO_MEMORY,
				cbSize);
		}

		if (NULL == m_wsaReceiveBuffer.buf) {
			XTLTRACE("Allocating RecvBuf %d bytes failed, error=0x%X\n", 
				cbSize, ERROR_OUTOFMEMORY);
			m_wsaReceiveBuffer.len = 0;
			SetLastError(ERROR_OUTOFMEMORY);
			return FALSE;
		}

		m_wsaReceiveBuffer.len = cbSize;
	}

	return TRUE;
}
Example #6
0
DWORD
CNdasService::Impl::OnServiceShutdown()
{
	XTLTRACE("System is shutting down...\n");

	m_cLogDeviceManager.OnShutdown();
	m_cDeviceEventHandler.OnShutdown();
	
	XTLVERIFY( ::LfsFiltCtlShutdown() );
	
	return NO_ERROR;
}
Example #7
0
BOOL
CLpxSockAddrListChangeNotifier::Reset()
{
	BOOL fSuccess = ::ResetEvent(m_hEvent);
	_ASSERT(fSuccess);

	if (INVALID_SOCKET != m_sock) {
		::closesocket(m_sock);
	}

	// ::ZeroMemory(&m_overlapped, sizeof(WSAOVERLAPPED));
	m_overlapped.Internal =
	m_overlapped.InternalHigh =
	m_overlapped.Offset =
	m_overlapped.OffsetHigh = 0;
	m_overlapped.hEvent = m_hEvent;

	XTL::AutoSocket sock = ::WSASocket(
		AF_LPX, 
		SOCK_DGRAM, 
		LPXPROTO_DGRAM, 
		NULL, 
		0, 
		WSA_FLAG_OVERLAPPED);

	if (INVALID_SOCKET == (SOCKET) sock) {
		return FALSE;
	}

	int iError;
	DWORD cbBytesReturned;

	iError = ::WSAIoctl(
		sock,
		SIO_ADDRESS_LIST_CHANGE,
		NULL, 0,
		NULL, 0,
		&cbBytesReturned,
		&m_overlapped,
		NULL);

	if (0 != iError && WSA_IO_PENDING != ::WSAGetLastError()) { 
		// SOCKET_ERROR
		// TODO: Error Event Log from WSAGetLastError
		XTLTRACE("WSAIoctl SIO_ADDRESS_LIST_CHANGE failed, error=0x%X\n", GetLastError());
		return FALSE;
	}

	m_sock = sock.Detach();

	return TRUE;
}
Example #8
0
BOOL 
CLpxStreamListener::Listen(INT nBacklog /* = SOMAXCONN */)
{
	_ASSERTE(INVALID_SOCKET != m_sock);

	INT iResult = ::listen(m_sock, nBacklog);
	if (0 != iResult) {
		XTLTRACE("CLpxStreamListener.listen failed, socket=%p, error=0x%X\n", 
			reinterpret_cast<PVOID>(m_sock), WSAGetLastError());
		return FALSE;
	}
	return TRUE;
}
Example #9
0
BOOL
CLpxAsyncSocket::ShutDown(INT nHow)
{
	_ASSERTE(INVALID_SOCKET != m_sock);

	INT iResult = ::shutdown(m_sock, nHow);
	if (0 != iResult) {
		XTLTRACE("shutdown failed, socket=%p, error=0x%X\n", 
			reinterpret_cast<PVOID>(m_sock), GetLastError());
		return FALSE;
	}
	return TRUE;
}
Example #10
0
BOOL
CLpxSockAddrListChangeNotifier::Initialize()
{
	if (NULL == m_hEvent) {
		m_hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
		if (NULL == m_hEvent) {
			XTLTRACE("Creating a event failed, error=0x%X\n", GetLastError());
			return FALSE;
		}
	}
	return TRUE;

}
Example #11
0
// #if WINVER >= 0x0501
BOOL
CLpxStreamConnection::Disconnect(DWORD dwFlags)
{
	_ASSERTE(INVALID_SOCKET != m_sock);

	LPFN_DISCONNECTEX lpfnDisconnectEx = NULL;
	GUID GuidDisconnectEx = WSAID_CONNECTEX;
	DWORD cbRead;
	INT iResult = ::WSAIoctl(m_sock, 
		SIO_GET_EXTENSION_FUNCTION_POINTER, 
		&GuidDisconnectEx, 
		sizeof(GuidDisconnectEx),
		&lpfnDisconnectEx, 
		sizeof(lpfnDisconnectEx), 
		&cbRead,
		NULL, 
		NULL);

	if (NULL == lpfnDisconnectEx) {
		XTLTRACE("Cannot load DisconnectEx function, error=0x%X\n",
			WSAGetLastError());
		return FALSE;
	}

	BOOL fSuccess = lpfnDisconnectEx(
		m_sock,
		NULL,
		dwFlags,
		0);

	if (!fSuccess) {
		XTLTRACE("DisconnectEx failed, socket=%p, error=0x%X\n",
			reinterpret_cast<PVOID>(m_sock), WSAGetLastError());
		return FALSE;
	}

	return TRUE;
}
Example #12
0
BOOL
CLpxDatagramSocket::GetSendToResult(LPDWORD lpcbSent)
{
	BOOL fSuccess = CLpxAsyncSocket::_GetSendResult(lpcbSent);
	if (!fSuccess) 
	{
		XTLTRACE("CLpxDatagramSocket._GetSendResult failed, socket=%p, error=0x%X\n", 
			reinterpret_cast<PVOID>(m_sock), GetLastError());
		return FALSE;
	}

	UnlockSendQueue();
	return TRUE;
}
Example #13
0
BOOL
CLpxDatagramSocket::SendToSync(
	CONST SOCKADDR_LPX* pRemoteAddr,
	DWORD cbToSend, 
	CONST BYTE* lpbData, 
	DWORD dwSendFlags,
	LPDWORD lpcbSent)
{
	BOOL fSuccess = SendTo(pRemoteAddr, cbToSend, lpbData, dwSendFlags);
	if (!fSuccess) 
	{
		XTLTRACE("CLpxDatagramSocket.SendTo failed, socket=%p, error=0x%X\n", 
			reinterpret_cast<PVOID>(m_sock), GetLastError());
		return FALSE;
	}
	fSuccess = GetSendToResult(lpcbSent);
	if (!fSuccess) 
	{
		XTLTRACE("CLpxDatagramSocket.GetSendToResult failed, socket=%p, error=0x%X\n", 
			reinterpret_cast<PVOID>(m_sock), GetLastError());
		return FALSE;
	}
	return TRUE;
}
Example #14
0
BOOL 
CLpxStreamConnection::Recv(DWORD cbBufferMax, LPDWORD lpdwFlags)
{
	_ASSERTE(INVALID_SOCKET != m_sock);

	BOOL fSuccess = FALSE;
	DWORD cbReceived = 0;

	fSuccess = AllocRecvBuf(cbBufferMax);
	if (!fSuccess) {
		XTLTRACE("AllocRecvBuf failed, error=0x%X\n", GetLastError());
		return FALSE;
	}

	ResetRecvOverlapped();

	INT iResult = ::WSARecv(
		m_sock,
		&m_wsaReceiveBuffer, 1,
		&cbReceived, lpdwFlags,
		&m_ovReceive, NULL);

	if (0 != iResult && WSA_IO_PENDING != ::WSAGetLastError()) {
		XTLTRACE("CLpxStreamConnection.Recv failed, max bytes=%d, socket=%p, error=0x%X\n", 
			cbBufferMax, reinterpret_cast<PVOID>(m_sock), WSAGetLastError());
		return FALSE;
	}

	if (0 == iResult) {
		fSuccess = ::SetEvent(m_hReceivedEvent);
		_ASSERTE(fSuccess);
		return TRUE;
	}

	return TRUE;
}
Example #15
0
BOOL
CLpxAsyncSocket::Bind(CONST SOCKADDR_LPX* pBindAddr)
{
	_ASSERTE(INVALID_SOCKET != m_sock);

	INT iResult = ::bind(
		m_sock,
		(const sockaddr*) pBindAddr,
		sizeof(SOCKADDR_LPX));

	if (0 != iResult) {
		XTLTRACE("CLpxAsyncSocket.bind failed, socket=%p, error=0x%X\n", 
			reinterpret_cast<PVOID>(m_sock), GetLastError());
		return FALSE;
	}

	m_localAddr = *pBindAddr;

	return TRUE;
}
Example #16
0
BOOL
CLpxAsyncSocket::Close()
{
	_ASSERTE(INVALID_SOCKET != m_sock);

	//
	// We need to reset recv and send event
	// If there is a previous data is not fetched, 
	// Data Received/Sent event will be fetched on a closed socket.
	//
	BOOL fSuccess = ::ResetEvent(m_hReceivedEvent);
	_ASSERTE(fSuccess);

	fSuccess = ::ResetEvent(m_hSentEvent);
	_ASSERTE(fSuccess);

	if (m_lSendQueueLocks > 0) {
		UnlockSendQueue();
		_ASSERTE(0 == m_lSendQueueLocks);
	}
	if (m_lRecvQueueLocks > 0) {
		UnlockRecvQueue();
		_ASSERTE(0 == m_lRecvQueueLocks);
	}

	//
	// Reset Queue Locks
	//
	m_lSendQueueLocks = 0;
	m_lRecvQueueLocks = 0;

	INT iResult = ::closesocket(m_sock);
	if (0 != iResult) {
		XTLTRACE("Closing a sock %p failed, error=0x%X\n", 
			reinterpret_cast<PVOID>(m_sock), GetLastError());
		return FALSE;
	}

	m_sock = INVALID_SOCKET;
	return TRUE;
}
Example #17
0
BOOL
CLpxAsyncSocket::CreateEx(INT nSocketType /* = SOCK_STREAM */)
{
	_ASSERTE(INVALID_SOCKET == m_sock);
	_ASSERTE(SOCK_STREAM == nSocketType || SOCK_DGRAM == nSocketType);

	m_sock = ::WSASocket(
		AF_LPX,
		nSocketType,
		(nSocketType == SOCK_STREAM) ? LPXPROTO_STREAM : LPXPROTO_DGRAM,
		NULL,
		0,
		WSA_FLAG_OVERLAPPED);

	if (INVALID_SOCKET == m_sock) {
		XTLTRACE("CLpxAsyncSocket.Creating a sock failed, error=0x%X\n", GetLastError());
		return FALSE;
	}

	return TRUE;
}
Example #18
0
BOOL
CLpxAsyncSocket::SetSockOpt(
	INT nOptName, 
	CONST BYTE* lpOptVal, 
	INT nOptLen, 
	INT nLevel /* = SOL_SOCKET */)
{
	_ASSERTE(INVALID_SOCKET != m_sock);

	INT iResult = ::setsockopt(
		m_sock,
		nLevel,
		nOptName,
		(const char*) lpOptVal,
		nOptLen);

	if (0 != iResult) {
		XTLTRACE("CLpxAsyncSocket.SetSockOpt failed, socket=%p, error=0x%X\n", 
			reinterpret_cast<PVOID>(m_sock), GetLastError());
		return FALSE;
	}
	return TRUE;
}
Example #19
0
BOOL
CLpxDatagramSocket::GetRecvFromResult(
	OUT SOCKADDR_LPX* pRemoteAddr, 
	OUT LPDWORD lpcbReceived, 
	OUT BYTE** ppbData, 
	OUT LPDWORD lpdwFlags)
{
	BOOL fSuccess = CLpxAsyncSocket::_GetRecvResult(
		lpcbReceived, 
		ppbData, 
		lpdwFlags);

	if (!fSuccess)
	{
		XTLTRACE("CLpxDatagramSocket._GetRecvResult failed, socket=%p, error=0x%X\n", 
			reinterpret_cast<PVOID>(m_sock), GetLastError());
		return FALSE;
	}

	if (pRemoteAddr) *pRemoteAddr = m_remoteAddr;
	UnlockRecvQueue();
	return TRUE;
}
Example #20
0
BOOL
CLpxStreamConnection::Send(
	DWORD cbToSend, 
	CONST BYTE* lpbData,
	DWORD dwFlags /* = 0 */)
{
	_ASSERTE(INVALID_SOCKET != m_sock);

	BOOL fSuccess = FALSE;

	ResetSendOverlapped();

	m_wsaSendBuffer.len = cbToSend;
	m_wsaSendBuffer.buf = (char*) lpbData;

	DWORD cbSent = 0;
	INT iResult = ::WSASend(
		m_sock,
		&m_wsaSendBuffer, 1,
		&cbSent, dwFlags,
		&m_ovSend, NULL);

	if (0 != iResult && WSA_IO_PENDING != ::WSAGetLastError()) {
		XTLTRACE("CLpxStreamConnection.Send failed, bytes=%d, socket=%p, error=0x%X\n", 
			cbToSend, reinterpret_cast<PVOID>(m_sock), WSAGetLastError());
		return FALSE;
	}

	if (0 == iResult) {
		fSuccess = ::SetEvent(m_hSentEvent);
		_ASSERTE(fSuccess);
		return TRUE;
	}

	return TRUE;
}
Example #21
0
BOOL 
CLpxAsyncSocket::_GetSendResult(LPDWORD lpcbSent)
{
	DWORD dwFlags = 0;
	DWORD cbSent = 0;

	BOOL fSuccess = ::WSAGetOverlappedResult(
		m_sock,
		&m_ovSend,
		&cbSent,
		TRUE,
		&dwFlags);

	if (!fSuccess)
	{
		XTLTRACE("GetSendResult.WSAGetOverlappedResult failed, socket=%p, error=0x%X\n", 
			reinterpret_cast<PVOID>(m_sock), GetLastError());
		return FALSE;
	}

	if (lpcbSent) *lpcbSent = cbSent;

	return fSuccess;
}
Example #22
0
BOOL 
CLpxStreamConnection::GetConnectResult(
	OUT LPDWORD lpcbSent)
{
	_ASSERTE(INVALID_SOCKET != m_sock);

	BOOL fSuccess = _GetSendResult(lpcbSent);

	if (!fSuccess) {
		return FALSE;
	}

	fSuccess = CLpxAsyncSocket::SetSockOpt(
		SO_UPDATE_CONNECT_CONTEXT,
		NULL, 
		0);

	if (!fSuccess) {
		XTLTRACE("Setsockopt SO_UPDATE_ACCEPT_CONTEXT failed, socket=%p, error=0x%X\n",
			reinterpret_cast<PVOID>(m_sock), WSAGetLastError());
	}

	return TRUE;
}
Example #23
0
DWORD 
CNdasCommandServer::
ThreadStart(LPVOID lpParam)
{
	HANDLE hStopEvent = static_cast<HANDLE>(lpParam);

	CmdWorkItemVector workItems;
	workItems.reserve(MaxPipeInstances);

	size_t size = workItems.size();
	XTLASSERT(0 == size);
	std::generate_n(
		std::back_inserter(workItems), 
		MaxPipeInstances, 
		pWorkItemPtrGenerator);
	size = workItems.size();
	XTLASSERT(MaxPipeInstances == size);

	DWORD nWorkItems = 0;

	for (DWORD i = 0; i < MaxPipeInstances; ++i)
	{
		CmdWorkItemPtr p = workItems[i];
		BOOL fSuccess = p->QueueUserWorkItemEx(
			this, 
			&CNdasCommandServer::CommandProcessStart, 
			hStopEvent, 
			WT_EXECUTELONGFUNCTION);
		if (fSuccess)
		{
			++nWorkItems;
		}
		else
		{
			XTLTRACE_ERR("Starting work item (%d/%d) failed.\n", i + 1, MaxPipeInstances);
		}
	}

	// Release semaphore to start workers (semaphore increment)
	LONG prev;
	XTLVERIFY( ::ReleaseSemaphore(m_hProcSemaphore, nWorkItems, &prev) );
	XTLASSERT( 0 == prev );

	// Wait for stop event
	XTLVERIFY(WAIT_OBJECT_0 == ::WaitForSingleObject(hStopEvent, INFINITE));

	// Stopped and waits for user work items
	DWORD finished = 0;
	while (finished < nWorkItems)
	{
		::Sleep(0);
		DWORD waitResult = ::WaitForSingleObject(m_hProcSemaphore, 0);
		if (waitResult == WAIT_OBJECT_0)
		{
			XTLTRACE("Command Process work item finished (%d/%d).\n", finished + 1, nWorkItems);
			++finished;
		}
		XTLVERIFY(WAIT_OBJECT_0 == waitResult || WAIT_TIMEOUT == waitResult);
	}

	// Now Finally this thread can stop
	return 0;
}
Example #24
0
DWORD
CNdasService::Impl::OnServiceStop()
{
	//////////////////////////////////////////////////////////////////////////
	// We should report the SCM that the service is stopping
	// Otherwise, the service will terminate the thread.
	// And we'll get ACCESS VIOLATION ERROR!
	//////////////////////////////////////////////////////////////////////////

	XTLTRACE("Service is stopping...\n");

	ReportServiceStopPending(1000);
	XTLVERIFY( ::SetEvent(m_hStopServiceEvent) );

	// Yield to other threads to finish themselves.
	::Sleep(0);

	//////////////////////////////////////////////////////////////////////////
	// Wait for the command processor thread to stop
	//////////////////////////////////////////////////////////////////////////

	XTLTRACE("Waiting for worker threads to stop....\n");

	DWORD waitResult = WAIT_TIMEOUT;
	while (WAIT_OBJECT_0 != waitResult)
	{
		ReportServiceStopPending(3000);
		// yield to work threads for them to handle their terminations
		::Sleep(0);
		waitResult = ::WaitForSingleObject(m_wiCmdServer.GetThreadHandle(), 3000);
		XTLVERIFY(WAIT_OBJECT_0 == waitResult || WAIT_TIMEOUT == waitResult);
		XTLTRACE("Waiting for command processors to stop in 3 seconds....\n");
	}
	
	XTLTRACE("Command processors stopped....\n");

	//////////////////////////////////////////////////////////////////////////
	// Wait for the work items to stop
	//////////////////////////////////////////////////////////////////////////

	DWORD finished = 0;
	while (finished < m_nWorkItems)
	{
		ReportServiceStopPending(1500);
		// yield to work threads for them to handle their terminations
		::Sleep(0);
		DWORD waitResult = ::WaitForSingleObject(m_hWorkItemSemaphore, 1000);
		if (waitResult == WAIT_OBJECT_0)
		{
			++finished;
			XTLTRACE("(%d/%d) WorkItems stopped...\n", finished, m_nWorkItems);
		}
		XTLVERIFY(WAIT_OBJECT_0 == waitResult || WAIT_TIMEOUT == waitResult);
	}

	//////////////////////////////////////////////////////////////////////////
	// All threads and work items are done
	//////////////////////////////////////////////////////////////////////////

	XTLTRACE("All work items stopped....\n");
	XTLTRACE("Reporting to the SCM that the service is stopped....\n");

	m_cDeviceEventHandler.Uninitialize();

	m_cDeviceRegistrar.Cleanup();
	m_cLogDeviceManager.Cleanup();

	ReportServiceStopped();

	return NO_ERROR;
}
Example #25
0
BOOL 
CLpxStreamListener::Accept(SOCKET sockAccept, DWORD cbDataBuffer)
{
	_ASSERTE(INVALID_SOCKET != m_sock);
	_ASSERTE(INVALID_SOCKET != sockAccept);

	BOOL fSuccess = FALSE;

	DWORD cbBufReq = (sizeof(SOCKADDR_LPX) + 16) * 2 + cbDataBuffer;
	fSuccess = AllocRecvBuf(cbBufReq);
	if (!fSuccess) {
		XTLTRACE("AllocRecvBuf failed.\n");
		return FALSE;
	}

	DWORD cbAcceptBuffer = m_wsaReceiveBuffer.len;
	PVOID pbAcceptBuffer = m_wsaReceiveBuffer.buf;

	ResetRecvOverlapped();

	//----------------------------------------
	// Load the AcceptEx function into memory using WSAIoctl.
	// The WSAIoctl function is an extension of the ioctlsocket()
	// function that can use overlapped I/O. The function's 3rd
	// through 6th parameters are input and output buffers where
	// we pass the pointer to our AcceptEx function. This is used
	// so that we can call the AcceptEx function directly, rather
	// than refer to the Mswsock.lib library.
	LPFN_ACCEPTEX lpfnAcceptEx = NULL;
	GUID GuidAcceptEx = WSAID_ACCEPTEX;
	DWORD cbRead;
	INT iResult = ::WSAIoctl(m_sock, 
		SIO_GET_EXTENSION_FUNCTION_POINTER, 
		&GuidAcceptEx, 
		sizeof(GuidAcceptEx),
		&lpfnAcceptEx, 
		sizeof(lpfnAcceptEx), 
		&cbRead,
		NULL, 
		NULL);

	if (NULL == lpfnAcceptEx) {
		XTLTRACE("Cannot load AcceptEx function, error=0x%X\n", GetLastError());
		return FALSE;
	}

	DWORD cbReceived = 0;
	fSuccess = lpfnAcceptEx(
		m_sock, 
		sockAccept, 
		pbAcceptBuffer, 
		cbDataBuffer,
		sizeof(SOCKADDR_LPX) + 16,
		sizeof(SOCKADDR_LPX) + 16,
		&cbReceived,
		&m_ovReceive);

	if (!fSuccess && ERROR_IO_PENDING != ::GetLastError()) {
		return FALSE;
	}

	iResult = ::setsockopt(
		sockAccept, 
		SOL_SOCKET, 
		SO_UPDATE_ACCEPT_CONTEXT, 
		(char *)&m_sock, 
		sizeof(m_sock));

	if (0 != iResult) {
		XTLTRACE("Setting SO_UPDATE_ACCEPT_CONTEXT failed, error=0x%X\n", 
			GetLastError());
	}

	if (fSuccess) {
		::SetEvent(m_hReceivedEvent);
		return TRUE;
	}

	return TRUE;
}