//
// Copyright (c) 2002
// Ronald Kevin Burton
//
// Z poniższym kodem nie jest związana żadna gwarancja poprawności działania.
// Program został dołączony do książki ".NET CLR. Księga eksperta" w celu
// ilustracji koncepcji i zasad przedstawionych w tej książce. Program może być 
// używany na własne ryzyko.
//
// Przyznaje się prawo do użycia lub kopiowania tego oprogramowania do dowolnego celu
// bez konieczności ponoszenia żadnych opłat pod warunkiem, że powyższe uwagi zostaną 
// zachowane we wszystkich kopiach. Przyznaje się także prawo do modyfikacji kodu
// i dystrybucji zmodyfikowanego kodu pod warunkiem zachowania powyższych uwag
// oraz dołączenia informacji mówiącej o modyfikacji kodu.
//
// 
// UnmanagedNetworking.cpp : Definiuje punkt wejścia dla aplikacji DLL.
//
#include "stdafx.h"

NetworkTest *pNetworkTest = NULL;

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		{
			WSADATA WSAData;
			DWORD dwRet;
			// Inicjalizacja gniazd 2 DLL
			dwRet = WSAStartup(0x0002, &WSAData);
		}
		break;
	case DLL_PROCESS_DETACH:
		WSACleanup();
		break;
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
		break;
	}
    return TRUE;
}

HRESULT ReportSocketError(const std::string& comment, std::string& strMessage)
{
	DWORD dwLastError = WSAGetLastError();
	std::ostringstream errmsg;
	errmsg << comment.c_str();
	errmsg << " ";
	errmsg << dwLastError;
	errmsg << " ";
	errmsg << dwLastError - WSABASEERR;
	errmsg << " ";
	errmsg << ((dwLastError == WSAEINTR) ? "WSAEINTR" :
		       (dwLastError == WSAEBADF) ? "WSAEBADF" :
		       (dwLastError == WSAEACCES) ? "WSAEACCES" :
		       (dwLastError == WSAEFAULT) ? "WSAEFAULT" :
		       (dwLastError == WSAEINVAL) ? "WSAEINVAL" :
		       (dwLastError == WSAEMFILE) ? "WSAEMFILE" :
		       (dwLastError == WSAEWOULDBLOCK) ? "WSAEWOULDBLOCK" :
		       (dwLastError == WSAEINPROGRESS) ? "WSAEINPROGRESS" :
		       (dwLastError == WSAEALREADY) ? "WSAEALREADY" :
		       (dwLastError == WSAENOTSOCK) ? "WSAENOTSOCK" :
		       (dwLastError == WSAEDESTADDRREQ) ? "WSAEDESTADDRREQ" :
		       (dwLastError == WSAEMSGSIZE) ? "WSAEMSGSIZE" :
		       (dwLastError == WSAEPROTOTYPE) ? "WSAEPROTOTYPE" :
		       (dwLastError == WSAENOPROTOOPT) ? "WSAENOPROTOOPT" :
		       (dwLastError == WSAEPROTONOSUPPORT) ? "WSAEPROTONOSUPPORT" :
		       (dwLastError == WSAESOCKTNOSUPPORT) ? "WSAESOCKTNOSUPPORT" :
		       (dwLastError == WSAEOPNOTSUPP) ? "WSAEOPNOTSUPP" :
		       (dwLastError == WSAEPFNOSUPPORT) ? "WSAEPFNOSUPPORT" :
		       (dwLastError == WSAEAFNOSUPPORT) ? "WSAEAFNOSUPPORT" :
		       (dwLastError == WSAEADDRINUSE) ? "WSAEADDRINUSE" :
		       (dwLastError == WSAEADDRNOTAVAIL) ? "WSAEADDRNOTAVAIL" :
		       (dwLastError == WSAENETDOWN) ? "WSAENETDOWN" :
		       (dwLastError == WSAENETUNREACH) ? "WSAENETUNREACH" :
		       (dwLastError == WSAENETRESET) ? "WSAENETRESET" :
		       (dwLastError == WSAECONNABORTED) ? "WSAECONNABORTED" :
		       (dwLastError == WSAECONNRESET) ? "WSAECONNRESET" :
		       (dwLastError == WSAENOBUFS) ? "WSAENOBUFS" :
		       (dwLastError == WSAEISCONN) ? "WSAEISCONN" :
		       (dwLastError == WSAENOTCONN) ? "WSAENOTCONN" :
		       (dwLastError == WSAESHUTDOWN) ? "WSAESHUTDOWN" :
		       (dwLastError == WSAETOOMANYREFS) ? "WSAETOOMANYREFS" :
		       (dwLastError == WSAETIMEDOUT) ? "WSAETIMEDOUT" :
		       (dwLastError == WSAECONNREFUSED) ? "WSAECONNREFUSED" :
		       (dwLastError == WSAELOOP) ? "WSAELOOP" :
		       (dwLastError == WSAENAMETOOLONG) ? "WSAENAMETOOLONG" :
		       (dwLastError == WSAEHOSTDOWN) ? "WSAEHOSTDOWN" :
		       (dwLastError == WSAEHOSTUNREACH) ? "WSAEHOSTUNREACH" :
		       (dwLastError == WSAENOTEMPTY) ? "WSAENOTEMPTY" :
		       (dwLastError == WSAEPROCLIM) ? "WSAEPROCLIM" :
		       (dwLastError == WSAEUSERS) ? "WSAEUSERS" :
		       (dwLastError == WSAEDQUOT) ? "WSAEDQUOT" :
		       (dwLastError == WSAESTALE) ? "WSAESTALE" :
		       (dwLastError == WSAEREMOTE) ? "WSAEREMOTE" :
		       (dwLastError == WSASYSNOTREADY) ? "WSASYSNOTREADY" :
		       (dwLastError == WSAVERNOTSUPPORTED) ? "WSAVERNOTSUPPORTED" :
		       (dwLastError == WSANOTINITIALISED) ? "WSANOTINITIALISED" :
		       (dwLastError == WSAEDISCON) ? "WSAEDISCON" :
		       (dwLastError == WSAENOMORE) ? "WSAENOMORE" :
		       (dwLastError == WSAECANCELLED) ? "WSAECANCELLED" :
		       (dwLastError == WSAEINVALIDPROCTABLE) ? "WSAEINVALIDPROCTABLE" :
		       (dwLastError == WSAEINVALIDPROVIDER) ? "WSAEINVALIDPROVIDER" :
		       (dwLastError == WSAEPROVIDERFAILEDINIT) ? "WSAEPROVIDERFAILEDINIT" :
		       (dwLastError == WSASYSCALLFAILURE) ? "WSASYSCALLFAILURE" :
		       (dwLastError == WSASERVICE_NOT_FOUND) ? "WSASERVICE_NOT_FOUND" :
		       (dwLastError == WSATYPE_NOT_FOUND) ? "WSATYPE_NOT_FOUND" :
		       (dwLastError == WSA_E_NO_MORE) ? "WSA_E_NO_MORE" :
		       (dwLastError == WSA_E_CANCELLED) ? "WSA_E_CANCELLED" :
		       (dwLastError == WSAEREFUSED) ? "WSAEREFUSED" : "Nieznany");

	strMessage = errmsg.str();

	return HRESULT_FROM_WIN32(dwLastError);
}

UNMANAGEDNETWORKING_API int Start()
{
	if(pNetworkTest)
		return pNetworkTest->Start();
	else
		return 0;
}
UNMANAGEDNETWORKING_API int TransmitByteCount()
{
	if(pNetworkTest)
		return pNetworkTest->GetTransmitByteCount();
	else
		return 0;
}
UNMANAGEDNETWORKING_API int ReceivedByteCount()
{
	if(pNetworkTest)
		return pNetworkTest->GetReceivedByteCount();
	else
		return 0;
}
UNMANAGEDNETWORKING_API double Elapsed()
{
	if(pNetworkTest)
		return pNetworkTest->GetElapsed();
	else
		return 0;
}
UNMANAGEDNETWORKING_API void Stop()
{
	if(pNetworkTest)
	{
		delete pNetworkTest;
		pNetworkTest = NULL;
	}
}
