#include "AdeptHeaders.hpp"
#include "rasfuncs.h"
#include "application.hpp"
#include "missionLang\resource.h"
#include <stdio.h>
#include <windows.h>
#include <ras.h>
#include <raserror.h>
#include <assert.h>
#include <ddraw.h>
#include <d3d.h>
#pragma comment(lib, "rasapi32.lib")

//========================================================================
//========================================================================
namespace RAS
{
	HINSTANCE	hInstance		= NULL;
	bool		bInitialized	= false;

	DWORD (APIENTRY *pRasCreatePhonebookEntry)( HWND, LPCSTR )												= NULL;
	DWORD (APIENTRY *pRasDial)(LPRASDIALEXTENSIONS, LPCSTR, LPRASDIALPARAMSA, DWORD, LPVOID, LPHRASCONN )	= NULL;
	DWORD (APIENTRY *pRasEnumConnections)( LPRASCONNA, LPDWORD, LPDWORD )									= NULL;
	DWORD (APIENTRY *pRasEnumDevices)(LPRASDEVINFOA, LPDWORD, LPDWORD )										= NULL;
	DWORD (APIENTRY *pRasEnumEntries)(LPCSTR, LPCSTR, LPRASENTRYNAMEA, LPDWORD, LPDWORD )					= NULL;
	DWORD (APIENTRY *pRasGetConnectStatus)( HRASCONN, LPRASCONNSTATUSA )									= NULL;
	DWORD (APIENTRY *pRasGetEntryDialParams)( LPCSTR, LPRASDIALPARAMSA, LPBOOL )							= NULL;
	DWORD (APIENTRY *pRasGetEntryProperties)( LPCSTR, LPCSTR, LPRASENTRYA, LPDWORD, LPBYTE, LPDWORD )		= NULL;
	DWORD (APIENTRY *pRasHangUp)( HRASCONN )																= NULL;

	VOID WINAPI RasDialNotifierFunction(HRASCONN hrasconn, UINT unMsg, RASCONNSTATE rascs, DWORD dwError, DWORD dwExtendedError);

	const int NotificationType_RasDialFunc = 0;
	const int NotificationType_RasDialFunc1 = 1;
	const int NotificationType_RasDialFunc2 = 2;
	const int NotificationType_Window = 0xFFFFFFFF;

	char szStatus[256];
	int iStatus = 0; // 0=connecting, 1=connected
	HRASCONN	hRasCon=NULL;

}

//========================================================================
//========================================================================
extern HWND				hWindow;
extern IDirectDraw7*	CurrentDDobject;
bool RAS::CreateNewEntry(void)
{
    gosASSERT(FALSE); // no RAS
	if (!bInitialized)
		return 0;

	if (true)
	{
		if (CurrentDDobject)
		{
			CurrentDDobject->FlipToGDISurface();
		}
	}

	//
	// try to determine if we have any "locations" yet
	//
	HKEY hKey;
	if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Telephony\\Locations", &hKey) == ERROR_SUCCESS)
	{
		char szSubKeyName[1024];
		DWORD dwSize=sizeof(szSubKeyName);
		FILETIME ft;

		if (RegEnumKeyEx(hKey, 0, szSubKeyName, &dwSize, NULL, NULL, NULL, &ft) == ERROR_SUCCESS)
		{
			RegCloseKey(hKey);
			if (pRasCreatePhonebookEntry(hWindow, NULL))
				return false;
			else
				return false;
		}
		RegCloseKey(hKey);
	}

	gos_EnableSetting(gos_Set_MinMaxApp, 0);
	if (pRasCreatePhonebookEntry(NULL, NULL))
		return false;

	return true;
}

//========================================================================
//========================================================================
int RAS::GetStatus(char * &s)
{
    gosASSERT(FALSE); // no RAS
	s=szStatus;

	return iStatus;
}

//========================================================================
//========================================================================
int RAS::GetListOfEntries(char **pList)
{
    gosASSERT(FALSE); // no RAS
	if (!bInitialized)
		return 0;

	DWORD dwSize=0;
	DWORD dwNum=0;
	DWORD dwBufferSize=0;

	iStatus = 0;

	if (true)
	{
		RASENTRYNAME *pRen = (RASENTRYNAME *)&dwBufferSize;
		dwSize = 0;
		dwNum = 0;
		dwBufferSize = sizeof(pRen[0]);

		RAS::pRasEnumEntries(NULL, NULL, pRen, &dwSize, &dwNum);
		if (dwNum)
		{
			pRen = (RASENTRYNAME *)malloc(dwSize);
			if (pRen)
			{
				pRen[0].dwSize = sizeof(pRen[0]);
				RAS::pRasEnumEntries(NULL, NULL, pRen, &dwSize, &dwNum);

				for (DWORD i=0 ; i<dwNum ; i++)
				{
					strcpy(pList[i], pRen[i].szEntryName);
				}

				for (i=0 ; i<dwNum ; i++)
				{
					if (true)
					{
						RASENTRY *re;
						DWORD dwRESize = 0;

						RAS::pRasGetEntryProperties(NULL, pRen[i].szEntryName, NULL, &dwRESize, NULL, NULL);
						if (dwRESize)
						{
							re = (RASENTRY *)malloc(dwRESize);
							if (re)
							{
								re->dwSize = sizeof(RASENTRY);
								RAS::pRasGetEntryProperties(NULL, pRen[i].szEntryName, re, &dwRESize, NULL, NULL);
								free(re);
							}
						}

						RASDIALPARAMS rdp;
						rdp.dwSize		= sizeof(rdp);
						strcpy(rdp.szEntryName, pRen[i].szEntryName);
						BOOL bPassword = TRUE;

						RAS::pRasGetEntryDialParams(NULL, &rdp, &bPassword);
					}

					//printf("Entry %d: \"%s\"\n", i, pRen[i].szEntryName);
				}

				free(pRen);
			}
		}
	}

	return dwNum;
}

//========================================================================
//========================================================================
bool RAS::GetUserNameAndPassword(char *szEntry, char *szUserName, char *szPassword)
{
    gosASSERT(FALSE); // no RAS
	if (!bInitialized)
		return false;

	RASDIALPARAMS rdp;
	rdp.dwSize		= sizeof(rdp);
	strcpy(rdp.szEntryName, szEntry);
	BOOL bPassword = TRUE;

	RAS::pRasGetEntryDialParams(NULL, &rdp, &bPassword);

	strcpy(szUserName, rdp.szUserName);
	strcpy(szPassword, rdp.szPassword);

	return true;
}

//========================================================================
//========================================================================
bool RAS::Dial(char *pszEntry, char *pszUser, char *pszPassword)
{
    gosASSERT(FALSE); // no RAS
	if (!bInitialized)
		return false;

	//
	// check to see if we're already connected to a DUN thingy
	//
	if (true)
	{
		DWORD dwSize;
		DWORD dwNum;
		DWORD dwBufferSize;

		RASCONN *pRasCon = (RASCONN *)&dwBufferSize;
		dwSize = 0;
		dwNum = 0;
		dwBufferSize = sizeof(pRasCon[0]);


		RAS::pRasEnumConnections(pRasCon, &dwSize, &dwNum);
		if (dwNum)
		{
			//
			// we're connected to a RAS/DUN entry, so let's just not dial,
			// and just go on
			//
			strcpy(szStatus, "Already connected");
			iStatus = 1;
			return true;

#ifdef _DEBUG123
			pRasCon = (RASCONN *)gos_Malloc(dwSize);
			if (pRasCon)
			{
				pRasCon[0].dwSize = sizeof(pRasCon[0]);
				RAS::pRasEnumConnections(pRasCon, &dwSize, &dwNum);

				if (dwNum >
				for (DWORD i=0 ; i<dwNum ; i++)
				{
				}

				gos_Free(pRasCon);
			}
#endif
		}
	}




	RASDIALPARAMS	rdp;

	rdp.dwSize				= sizeof(rdp);

	strcpy(rdp.szPhoneNumber,		"");
	strcpy(rdp.szCallbackNumber,	"");
	strcpy(rdp.szUserName,			pszUser);
	strcpy(rdp.szPassword,			pszPassword);
	strcpy(rdp.szDomain,			"*");
	strcpy(rdp.szEntryName,			pszEntry);

	DWORD dwErr;
	hRasCon = 0;
	if ((dwErr=RAS::pRasDial(NULL, NULL, &rdp, RAS::NotificationType_RasDialFunc1, (LPVOID)RasDialNotifierFunction, &hRasCon)) != 0)
	{
		printf("Error: %d\n", dwErr);
		strcpy(szStatus, "Error trying to dial modem.");
	}

	return true;
}

//========================================================================
//========================================================================
bool RAS::HangUp(void)
{
    gosASSERT(FALSE); // no RAS
	if (!bInitialized)
		return false;

	if (hRasCon)
	{
		RAS::pRasHangUp(hRasCon);
		hRasCon = NULL;
		iStatus = 0;
	}

	return true;
}

//========================================================================
//========================================================================
int RAS::GetStatus(char * &status)
{
    gosASSERT(FALSE); // no RAS
	if (!bInitialized)
		return -1;

	return 0;
}

//========================================================================
//========================================================================
VOID WINAPI RAS::RasDialNotifierFunction(HRASCONN hrasconn, UINT unMsg, RASCONNSTATE rascs, DWORD dwError, DWORD dwExtendedError)
{
    gosASSERT(FALSE); // no RAS
	assert(unMsg == WM_RASDIALEVENT);

	if (dwError == 0)
	{
		switch (rascs)
		{
		case RASCS_OpenPort:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_OpenPort));
			break;

		case RASCS_PortOpened:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_PortOpened));
			break;

		case RASCS_ConnectDevice:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_ConnectDevice));
			break;

		case RASCS_DeviceConnected:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_DeviceConnected));
			break;

		case RASCS_AllDevicesConnected:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_AllDevicesConnected));
			break;

		case RASCS_Authenticate:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_Authenticate));
			break;

		case RASCS_AuthNotify:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_AuthNotify));
			break;

		case RASCS_AuthRetry:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_AuthRetry));
			break;

		case RASCS_AuthCallback:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_AuthCallback));
			break;

		case RASCS_AuthChangePassword:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_AuthChangePassword));
			break;

		case RASCS_AuthProject:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_AuthProject));
			break;

		case RASCS_AuthLinkSpeed:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_AuthLinkSpeed));
			break;

		case RASCS_AuthAck:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_AuthAck));
			break;

		case RASCS_ReAuthenticate:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_ReAuthenticate));
			break;

		case RASCS_Authenticated:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_Authenticated));
			break;

		case RASCS_PrepareForCallback:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_PrepareForCallback));
			break;

		case RASCS_WaitForModemReset:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_WaitForModemReset));
			break;

		case RASCS_WaitForCallback:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_WaitForCallback));
			break;

		case RASCS_Projected:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_Projected));
			break;

		case RASCS_SubEntryConnected:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_SubEntryConnected));
			break;

		case RASCS_SubEntryDisconnected:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_SubEntryDisconnected));
			break;

		case RASCS_Interactive:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_Interactive));
			break;

		case RASCS_RetryAuthentication:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_RetryAuthentication));
			break;

		case RASCS_CallbackSetByCaller:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_CallbackSetByCaller));
			break;

		case RASCS_PasswordExpired:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_PasswordExpired));
			break;

		case RASCS_Connected:
			// we must now set the status to 1, so that the script knows we're connected, and that it's okay to
			// shut down the dial up networking status window and continue on.
			iStatus = 1;
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_Connected));
			break;

		case RASCS_Disconnected:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_Disconnected));
			break;

		case RASCS_StartAuthentication:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_StartAuthentication));
			break;

		case RASCS_CallbackComplete:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_CallbackComplete));
			break;

		case RASCS_LogonNetwork:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_LogonNetwork));
			break;

		default:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_RASCS_Unknown));
			break;
		}
	}
	else
	{
		switch (dwError)
		{
		case PENDING:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_PENDING));
			break;

		case ERROR_INVALID_PORT_HANDLE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_INVALID_PORT_HANDLE));
			break;

		case ERROR_PORT_ALREADY_OPEN:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PORT_ALREADY_OPEN));
			break;

		case ERROR_BUFFER_TOO_SMALL:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_BUFFER_TOO_SMALL));
			break;

		case ERROR_WRONG_INFO_SPECIFIED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_WRONG_INFO_SPECIFIED));
			break;

		case ERROR_CANNOT_SET_PORT_INFO:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_CANNOT_SET_PORT_INFO));
			break;

		case ERROR_PORT_NOT_CONNECTED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PORT_NOT_CONNECTED));
			break;

		case ERROR_EVENT_INVALID:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_EVENT_INVALID));
			break;

		case ERROR_DEVICE_DOES_NOT_EXIST:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_DEVICE_DOES_NOT_EXIST));
			break;

		case ERROR_DEVICETYPE_DOES_NOT_EXIST:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_DEVICETYPE_DOES_NOT_EXIST));
			break;

		case ERROR_BUFFER_INVALID:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_BUFFER_INVALID));
			break;

		case ERROR_ROUTE_NOT_AVAILABLE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_ROUTE_NOT_AVAILABLE));
			break;

		case ERROR_ROUTE_NOT_ALLOCATED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_ROUTE_NOT_ALLOCATED));
			break;

		case ERROR_INVALID_COMPRESSION_SPECIFIED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_INVALID_COMPRESSION_SPECIFIED));
			break;

		case ERROR_OUT_OF_BUFFERS:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_OUT_OF_BUFFERS));
			break;

		case ERROR_PORT_NOT_FOUND:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PORT_NOT_FOUND));
			break;

		case ERROR_ASYNC_REQUEST_PENDING:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_ASYNC_REQUEST_PENDING));
			break;

		case ERROR_ALREADY_DISCONNECTING:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_ALREADY_DISCONNECTING));
			break;

		case ERROR_PORT_NOT_OPEN:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PORT_NOT_OPEN));
			break;

		case ERROR_PORT_DISCONNECTED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PORT_DISCONNECTED));
			break;

		case ERROR_NO_ENDPOINTS:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NO_ENDPOINTS));
			break;

		case ERROR_CANNOT_OPEN_PHONEBOOK:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_CANNOT_OPEN_PHONEBOOK));
			break;

		case ERROR_CANNOT_LOAD_PHONEBOOK:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_CANNOT_LOAD_PHONEBOOK));
			break;

		case ERROR_CANNOT_FIND_PHONEBOOK_ENTRY:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_CANNOT_FIND_PHONEBOOK_ENTRY));
			break;

		case ERROR_CANNOT_WRITE_PHONEBOOK:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_CANNOT_WRITE_PHONEBOOK));
			break;

		case ERROR_CORRUPT_PHONEBOOK:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_CORRUPT_PHONEBOOK));
			break;

		case ERROR_CANNOT_LOAD_STRING:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_CANNOT_LOAD_STRING));
			break;

		case ERROR_KEY_NOT_FOUND:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_KEY_NOT_FOUND));
			break;

		case ERROR_DISCONNECTION:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_DISCONNECTION));
			break;

		case ERROR_REMOTE_DISCONNECTION:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_REMOTE_DISCONNECTION));
			break;

		case ERROR_HARDWARE_FAILURE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_HARDWARE_FAILURE));
			break;

		case ERROR_USER_DISCONNECTION:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_USER_DISCONNECTION));
			break;

		case ERROR_INVALID_SIZE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_INVALID_SIZE));
			break;

		case ERROR_PORT_NOT_AVAILABLE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PORT_NOT_AVAILABLE));
			break;

		case ERROR_CANNOT_PROJECT_CLIENT:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_CANNOT_PROJECT_CLIENT));
			break;

		case ERROR_UNKNOWN:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_UNKNOWN));
			break;

		case ERROR_WRONG_DEVICE_ATTACHED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_WRONG_DEVICE_ATTACHED));
			break;

		case ERROR_BAD_STRING:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_BAD_STRING));
			break;

		case ERROR_REQUEST_TIMEOUT:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_REQUEST_TIMEOUT));
			break;

		case ERROR_CANNOT_GET_LANA:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_CANNOT_GET_LANA));
			break;

		case ERROR_NETBIOS_ERROR:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NETBIOS_ERROR));
			break;

		case ERROR_SERVER_OUT_OF_RESOURCES:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_SERVER_OUT_OF_RESOURCES));
			break;

		case ERROR_NAME_EXISTS_ON_NET:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NAME_EXISTS_ON_NET));
			break;

		case ERROR_SERVER_GENERAL_NET_FAILURE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_SERVER_GENERAL_NET_FAILURE));
			break;

		case WARNING_MSG_ALIAS_NOT_ADDED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_WARNING_MSG_ALIAS_NOT_ADDED));
			break;

		case ERROR_AUTH_INTERNAL:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_AUTH_INTERNAL));
			break;

		case ERROR_RESTRICTED_LOGON_HOURS:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_RESTRICTED_LOGON_HOURS));
			break;

		case ERROR_ACCT_DISABLED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_ACCT_DISABLED));
			break;

		case ERROR_PASSWD_EXPIRED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PASSWD_EXPIRED));
			break;

		case ERROR_NO_DIALIN_PERMISSION:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NO_DIALIN_PERMISSION));
			break;

		case ERROR_SERVER_NOT_RESPONDING:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_SERVER_NOT_RESPONDING));
			break;

		case ERROR_FROM_DEVICE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_FROM_DEVICE));
			break;

		case ERROR_UNRECOGNIZED_RESPONSE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_UNRECOGNIZED_RESPONSE));
			break;

		case ERROR_MACRO_NOT_FOUND:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_MACRO_NOT_FOUND));
			break;

		case ERROR_MACRO_NOT_DEFINED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_MACRO_NOT_DEFINED));
			break;

		case ERROR_MESSAGE_MACRO_NOT_FOUND:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_MESSAGE_MACRO_NOT_FOUND));
			break;

		case ERROR_DEFAULTOFF_MACRO_NOT_FOUND:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_DEFAULTOFF_MACRO_NOT_FOUND));
			break;

		case ERROR_FILE_COULD_NOT_BE_OPENED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_FILE_COULD_NOT_BE_OPENED));
			break;

		case ERROR_DEVICENAME_TOO_LONG:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_DEVICENAME_TOO_LONG));
			break;

		case ERROR_DEVICENAME_NOT_FOUND:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_DEVICENAME_NOT_FOUND));
			break;

		case ERROR_NO_RESPONSES:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NO_RESPONSES));
			break;

		case ERROR_NO_COMMAND_FOUND:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NO_COMMAND_FOUND));
			break;

		case ERROR_WRONG_KEY_SPECIFIED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_WRONG_KEY_SPECIFIED));
			break;

		case ERROR_UNKNOWN_DEVICE_TYPE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_UNKNOWN_DEVICE_TYPE));
			break;

		case ERROR_ALLOCATING_MEMORY:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_ALLOCATING_MEMORY));
			break;

		case ERROR_PORT_NOT_CONFIGURED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PORT_NOT_CONFIGURED));
			break;

		case ERROR_DEVICE_NOT_READY:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_DEVICE_NOT_READY));
			break;

		case ERROR_READING_INI_FILE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_READING_INI_FILE));
			break;

		case ERROR_NO_CONNECTION:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NO_CONNECTION));
			break;

		case ERROR_BAD_USAGE_IN_INI_FILE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_BAD_USAGE_IN_INI_FILE));
			break;

		case ERROR_READING_SECTIONNAME:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_READING_SECTIONNAME));
			break;

		case ERROR_READING_DEVICETYPE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_READING_DEVICETYPE));
			break;

		case ERROR_READING_DEVICENAME:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_READING_DEVICENAME));
			break;

		case ERROR_READING_USAGE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_READING_USAGE));
			break;

		case ERROR_READING_MAXCONNECTBPS:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_READING_MAXCONNECTBPS));
			break;

		case ERROR_READING_MAXCARRIERBPS:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_READING_MAXCARRIERBPS));
			break;

		case ERROR_LINE_BUSY:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_LINE_BUSY));
			break;

		case ERROR_VOICE_ANSWER:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_VOICE_ANSWER));
			break;

		case ERROR_NO_ANSWER:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NO_ANSWER));
			break;

		case ERROR_NO_CARRIER:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NO_CARRIER));
			break;

		case ERROR_NO_DIALTONE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NO_DIALTONE));
			break;

		case ERROR_IN_COMMAND:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_IN_COMMAND));
			break;

		case ERROR_WRITING_SECTIONNAME:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_WRITING_SECTIONNAME));
			break;

		case ERROR_WRITING_DEVICETYPE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_WRITING_DEVICETYPE));
			break;

		case ERROR_WRITING_DEVICENAME:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_WRITING_DEVICENAME));
			break;

		case ERROR_WRITING_MAXCONNECTBPS:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_WRITING_MAXCONNECTBPS));
			break;

		case ERROR_WRITING_MAXCARRIERBPS:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_WRITING_MAXCARRIERBPS));
			break;

		case ERROR_WRITING_USAGE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_WRITING_USAGE));
			break;

		case ERROR_WRITING_DEFAULTOFF:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_WRITING_DEFAULTOFF));
			break;

		case ERROR_READING_DEFAULTOFF:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_READING_DEFAULTOFF));
			break;

		case ERROR_EMPTY_INI_FILE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_EMPTY_INI_FILE));
			break;

		case ERROR_AUTHENTICATION_FAILURE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_AUTHENTICATION_FAILURE));
			break;

		case ERROR_PORT_OR_DEVICE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PORT_OR_DEVICE));
			break;

		case ERROR_NOT_BINARY_MACRO:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NOT_BINARY_MACRO));
			break;

		case ERROR_DCB_NOT_FOUND:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_DCB_NOT_FOUND));
			break;

		case ERROR_STATE_MACHINES_NOT_STARTED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_STATE_MACHINES_NOT_STARTED));
			break;

		case ERROR_STATE_MACHINES_ALREADY_STARTED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_STATE_MACHINES_ALREADY_STARTED));
			break;

		case ERROR_PARTIAL_RESPONSE_LOOPING:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PARTIAL_RESPONSE_LOOPING));
			break;

		case ERROR_UNKNOWN_RESPONSE_KEY:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_UNKNOWN_RESPONSE_KEY));
			break;

		case ERROR_RECV_BUF_FULL:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_RECV_BUF_FULL));
			break;

		case ERROR_CMD_TOO_LONG:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_CMD_TOO_LONG));
			break;

		case ERROR_UNSUPPORTED_BPS:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_UNSUPPORTED_BPS));
			break;

		case ERROR_UNEXPECTED_RESPONSE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_UNEXPECTED_RESPONSE));
			break;

		case ERROR_INTERACTIVE_MODE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_INTERACTIVE_MODE));
			break;

		case ERROR_BAD_CALLBACK_NUMBER:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_BAD_CALLBACK_NUMBER));
			break;

		case ERROR_INVALID_AUTH_STATE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_INVALID_AUTH_STATE));
			break;

		case ERROR_WRITING_INITBPS:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_WRITING_INITBPS));
			break;

		case ERROR_X25_DIAGNOSTIC:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_X25_DIAGNOSTIC));
			break;

		case ERROR_ACCT_EXPIRED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_ACCT_EXPIRED));
			break;

		case ERROR_CHANGING_PASSWORD:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_CHANGING_PASSWORD));
			break;

		case ERROR_OVERRUN:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_OVERRUN));
			break;

		case ERROR_RASMAN_CANNOT_INITIALIZE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_RASMAN_CANNOT_INITIALIZE));
			break;

		case ERROR_BIPLEX_PORT_NOT_AVAILABLE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_BIPLEX_PORT_NOT_AVAILABLE));
			break;

		case ERROR_NO_ACTIVE_ISDN_LINES:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NO_ACTIVE_ISDN_LINES));
			break;

		case ERROR_NO_ISDN_CHANNELS_AVAILABLE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NO_ISDN_CHANNELS_AVAILABLE));
			break;

		case ERROR_TOO_MANY_LINE_ERRORS:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_TOO_MANY_LINE_ERRORS));
			break;

		case ERROR_IP_CONFIGURATION:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_IP_CONFIGURATION));
			break;

		case ERROR_NO_IP_ADDRESSES:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NO_IP_ADDRESSES));
			break;

		case ERROR_PPP_TIMEOUT:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PPP_TIMEOUT));
			break;

		case ERROR_PPP_REMOTE_TERMINATED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PPP_REMOTE_TERMINATED));
			break;

		case ERROR_PPP_NO_PROTOCOLS_CONFIGURED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PPP_NO_PROTOCOLS_CONFIGURED));
			break;

		case ERROR_PPP_NO_RESPONSE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PPP_NO_RESPONSE));
			break;

		case ERROR_PPP_INVALID_PACKET:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PPP_INVALID_PACKET));
			break;

		case ERROR_PHONE_NUMBER_TOO_LONG:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PHONE_NUMBER_TOO_LONG));
			break;

		case ERROR_IPXCP_NO_DIALOUT_CONFIGURED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_IPXCP_NO_DIALOUT_CONFIGURED));
			break;

		case ERROR_IPXCP_NO_DIALIN_CONFIGURED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_IPXCP_NO_DIALIN_CONFIGURED));
			break;

		case ERROR_IPXCP_DIALOUT_ALREADY_ACTIVE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_IPXCP_DIALOUT_ALREADY_ACTIVE));
			break;

		case ERROR_ACCESSING_TCPCFGDLL:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_ACCESSING_TCPCFGDLL));
			break;

		case ERROR_NO_IP_RAS_ADAPTER:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NO_IP_RAS_ADAPTER));
			break;

		case ERROR_SLIP_REQUIRES_IP:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_SLIP_REQUIRES_IP));
			break;

		case ERROR_PROJECTION_NOT_COMPLETE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PROJECTION_NOT_COMPLETE));
			break;

		case ERROR_PROTOCOL_NOT_CONFIGURED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PROTOCOL_NOT_CONFIGURED));
			break;

		case ERROR_PPP_NOT_CONVERGING:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PPP_NOT_CONVERGING));
			break;

		case ERROR_PPP_CP_REJECTED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PPP_CP_REJECTED));
			break;

		case ERROR_PPP_LCP_TERMINATED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PPP_LCP_TERMINATED));
			break;

		case ERROR_PPP_REQUIRED_ADDRESS_REJECTED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PPP_REQUIRED_ADDRESS_REJECTED));
			break;

		case ERROR_PPP_NCP_TERMINATED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PPP_NCP_TERMINATED));
			break;

		case ERROR_PPP_LOOPBACK_DETECTED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PPP_LOOPBACK_DETECTED));
			break;

		case ERROR_PPP_NO_ADDRESS_ASSIGNED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_PPP_NO_ADDRESS_ASSIGNED));
			break;

		case ERROR_CANNOT_USE_LOGON_CREDENTIALS:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_CANNOT_USE_LOGON_CREDENTIALS));
			break;

		case ERROR_TAPI_CONFIGURATION:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_TAPI_CONFIGURATION));
			break;

		case ERROR_NO_LOCAL_ENCRYPTION:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NO_LOCAL_ENCRYPTION));
			break;

		case ERROR_NO_REMOTE_ENCRYPTION:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NO_REMOTE_ENCRYPTION));
			break;

		case ERROR_REMOTE_REQUIRES_ENCRYPTION:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_REMOTE_REQUIRES_ENCRYPTION));
			break;

		case ERROR_IPXCP_NET_NUMBER_CONFLICT:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_IPXCP_NET_NUMBER_CONFLICT));
			break;

		case ERROR_INVALID_SMM:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_INVALID_SMM));
			break;

		case ERROR_SMM_UNINITIALIZED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_SMM_UNINITIALIZED));
			break;

		case ERROR_NO_MAC_FOR_PORT:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_NO_MAC_FOR_PORT));
			break;

		case ERROR_SMM_TIMEOUT:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_SMM_TIMEOUT));
			break;

		case ERROR_BAD_PHONE_NUMBER:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_BAD_PHONE_NUMBER));
			break;

		case ERROR_WRONG_MODULE:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_WRONG_MODULE));
			break;

		case ERROR_INVALID_CALLBACK_NUMBER:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_INVALID_CALLBACK_NUMBER));
			break;

		case ERROR_SCRIPT_SYNTAX:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_SCRIPT_SYNTAX));
			break;

		case ERROR_HANGUP_FAILED:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_HANGUP_FAILED));
			break;

		default:
			strcpy(szStatus, Application::GetInstance()->GetLocString(IDS_RAS_ERROR_GENERIC));
			break;



		}
	}
	return;
}














//========================================================================
//========================================================================
bool RAS::InitializeLibrary(void)
{
    gosASSERT(FALSE); // no RAS
	if (bInitialized)
		return true;

	hInstance = LoadLibrary("rasapi32.dll");
	if (hInstance)
		bInitialized = true;

	*(FARPROC *)&pRasCreatePhonebookEntry	= GetProcAddress(hInstance, "RasCreatePhonebookEntryA");
	*(FARPROC *)&pRasDial					= GetProcAddress(hInstance, "RasDialA");
	*(FARPROC *)&pRasEnumConnections		= GetProcAddress(hInstance, "RasEnumConnectionsA");
	*(FARPROC *)&pRasEnumDevices			= GetProcAddress(hInstance, "RasEnumDevicesA");
	*(FARPROC *)&pRasEnumEntries			= GetProcAddress(hInstance, "RasEnumEntriesA");
	*(FARPROC *)&pRasGetConnectStatus		= GetProcAddress(hInstance, "RasGetConnectStatusA");
	*(FARPROC *)&pRasGetEntryDialParams		= GetProcAddress(hInstance, "RasGetEntryDialParamsA");
	*(FARPROC *)&pRasGetEntryProperties		= GetProcAddress(hInstance, "RasGetEntryPropertiesA");
	*(FARPROC *)&pRasHangUp					= GetProcAddress(hInstance, "RasHangUpA");

	if (!pRasCreatePhonebookEntry) goto fail;
	if (!pRasDial) goto fail;
	if (!pRasEnumConnections) goto fail;
	if (!pRasEnumDevices) goto fail;
	if (!pRasEnumEntries) goto fail;
	if (!pRasGetConnectStatus) goto fail;
	if (!pRasGetEntryDialParams) goto fail;
	if (!pRasGetEntryProperties) goto fail;
	if (!pRasHangUp) goto fail;

	return bInitialized;

fail:
	TerminateLibrary();
	return false;
}

//========================================================================
//========================================================================
bool RAS::TerminateLibrary(void)
{
    gosASSERT(FALSE); // no RAS
	HangUp();

	if (bInitialized)
	{

		pRasCreatePhonebookEntry	= NULL;
		pRasDial					= NULL;
		pRasEnumConnections			= NULL;
		pRasEnumDevices				= NULL;
		pRasEnumEntries				= NULL;
		pRasGetConnectStatus		= NULL;
		pRasGetEntryDialParams		= NULL;
		pRasGetEntryProperties		= NULL;
		pRasHangUp					= NULL;

		FreeLibrary(hInstance);
		bInitialized = false;
	}

	return true;
}



