//	Album List for Winamp
//	Copyright (C) 1999-2001 Safai Ma
//
//	This program is free software; you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation; either version 2 of the License, or
//	(at your option) any later version.
//
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with this program; if not, write to the Free Software
//	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
/*
 * RASAPI32.C
 *
 * Interface glue code to Dail-up Networking
 */
#include "stdafx.h"
#include <ras.h>

static HINSTANCE hDllRAS = 0L;
static DWORD	 nRef = 0L;

static DWORD (APIENTRY *pRasEnumEntriesA)(LPSTR, LPSTR, LPRASENTRYNAMEA, LPDWORD, LPDWORD)					= NULL;
static DWORD (APIENTRY *pRasEnumEntriesW)(LPWSTR, LPWSTR, LPRASENTRYNAMEW, LPDWORD, LPDWORD)				= NULL;
static DWORD (APIENTRY *pRasEnumConnectionsA)(LPRASCONNA, LPDWORD, LPDWORD)									= NULL;
static DWORD (APIENTRY *pRasEnumConnectionsW)(LPRASCONNW, LPDWORD, LPDWORD)									= NULL;
static DWORD (APIENTRY *pRasDialA)(LPRASDIALEXTENSIONS, LPSTR, LPRASDIALPARAMSA, DWORD, LPVOID, LPHRASCONN)	= NULL;
static DWORD (APIENTRY *pRasDialW)(LPRASDIALEXTENSIONS, LPWSTR, LPRASDIALPARAMSW, DWORD, LPVOID, LPHRASCONN)= NULL;
static DWORD (APIENTRY *pRasHangUpA)(HRASCONN)																= NULL;
static DWORD (APIENTRY *pRasHangUpW)(HRASCONN)																= NULL;
static DWORD (APIENTRY *pRasGetConnectStatusA)(HRASCONN, LPRASCONNSTATUSA)									= NULL;
static DWORD (APIENTRY *pRasGetConnectStatusW)(HRASCONN, LPRASCONNSTATUSW)									= NULL;
static DWORD (APIENTRY *pRasGetErrorStringA)(UINT, LPSTR, DWORD)											= NULL;
static DWORD (APIENTRY *pRasGetErrorStringW)(UINT, LPWSTR, DWORD)											= NULL;
static DWORD (APIENTRY *pRasGetEntryDialParamsA)(LPSTR, LPRASDIALPARAMSA, LPBOOL)							= NULL;
static DWORD (APIENTRY *pRasGetEntryDialParamsW)(LPWSTR, LPRASDIALPARAMSW, LPBOOL)							= NULL;
static DWORD (APIENTRY *pRasSetEntryDialParamsA)(LPSTR, LPRASDIALPARAMSA, BOOL)								= NULL;
static DWORD (APIENTRY *pRasSetEntryDialParamsW)(LPWSTR, LPRASDIALPARAMSW, BOOL)							= NULL;

void RASFree();
BOOL RASLoad()
{
	// check for multiple instances and increment reference counts.
	if (nRef != 0)
	{
		nRef++;
		return TRUE;
	}

	hDllRAS = LoadLibrary("RASAPI32.DLL");
	if (!hDllRAS)
	{
		RASFree();
		return FALSE;
	}

	pRasEnumEntriesA		= (DWORD (APIENTRY *)(LPSTR, LPSTR, LPRASENTRYNAMEA, LPDWORD, LPDWORD))							GetProcAddress(hDllRAS, "RasEnumEntriesA");
	pRasEnumEntriesW		= (DWORD (APIENTRY *)(LPWSTR, LPWSTR, LPRASENTRYNAMEW, LPDWORD, LPDWORD))						GetProcAddress(hDllRAS, "RasEnumEntriesW");
	pRasEnumConnectionsA	= (DWORD (APIENTRY *)(LPRASCONNA, LPDWORD, LPDWORD))											GetProcAddress(hDllRAS, "RasEnumConnectionsA");
	pRasEnumConnectionsW	= (DWORD (APIENTRY *)(LPRASCONNW, LPDWORD, LPDWORD))											GetProcAddress(hDllRAS, "RasEnumConnectionsW");
	pRasDialA				= (DWORD (APIENTRY *)(LPRASDIALEXTENSIONS, LPSTR, LPRASDIALPARAMSA, DWORD, LPVOID, LPHRASCONN))	GetProcAddress(hDllRAS, "RasDialA");
	pRasDialW				= (DWORD (APIENTRY *)(LPRASDIALEXTENSIONS, LPWSTR, LPRASDIALPARAMSW, DWORD, LPVOID, LPHRASCONN))GetProcAddress(hDllRAS, "RasDialW");
	pRasHangUpA				= (DWORD (APIENTRY *)(HRASCONN))																GetProcAddress(hDllRAS, "RasHangUpA");
	pRasHangUpW				= (DWORD (APIENTRY *)(HRASCONN))																GetProcAddress(hDllRAS, "RasHangUpW");
	pRasGetConnectStatusA	= (DWORD (APIENTRY *)(HRASCONN, LPRASCONNSTATUSA))												GetProcAddress(hDllRAS, "RasGetConnectStatusA");
	pRasGetConnectStatusW	= (DWORD (APIENTRY *)(HRASCONN, LPRASCONNSTATUSW))												GetProcAddress(hDllRAS, "RasGetConnectStatusW");
	pRasGetErrorStringA		= (DWORD (APIENTRY *)(UINT, LPSTR, DWORD))														GetProcAddress(hDllRAS, "RasGetErrorStringA");
	pRasGetErrorStringW		= (DWORD (APIENTRY *)(UINT, LPWSTR, DWORD))														GetProcAddress(hDllRAS, "RasGetErrorStringW");
	pRasGetEntryDialParamsA	= (DWORD (APIENTRY *)(LPSTR, LPRASDIALPARAMSA, LPBOOL))											GetProcAddress(hDllRAS, "RasGetEntryDialParamsA");
	pRasGetEntryDialParamsW	= (DWORD (APIENTRY *)(LPWSTR, LPRASDIALPARAMSW, LPBOOL))										GetProcAddress(hDllRAS, "RasGetEntryDialParamsW");
	pRasSetEntryDialParamsA	= (DWORD (APIENTRY *)(LPSTR, LPRASDIALPARAMSA, BOOL))											GetProcAddress(hDllRAS, "RasSetEntryDialParamsA");
	pRasSetEntryDialParamsW	= (DWORD (APIENTRY *)(LPWSTR, LPRASDIALPARAMSW, BOOL))											GetProcAddress(hDllRAS, "RasSetEntryDialParamsW");

	// increment reference counts
	nRef++;

	return TRUE;
}

void RASFree()
{
	// check reference count first
	if (nRef == 0) return;
	if (--nRef != 0) return;

	pRasEnumEntriesA		= NULL;
	pRasEnumEntriesW		= NULL;
	pRasEnumConnectionsA	= NULL;
	pRasEnumConnectionsW	= NULL;
	pRasDialA				= NULL;
	pRasDialW				= NULL;
	pRasHangUpA				= NULL;
	pRasHangUpW				= NULL;
	pRasGetConnectStatusA	= NULL;
	pRasGetConnectStatusW	= NULL;
	pRasGetErrorStringA		= NULL;
	pRasGetErrorStringW		= NULL;
	pRasGetEntryDialParamsA	= NULL;
	pRasGetEntryDialParamsW	= NULL;
	pRasSetEntryDialParamsA	= NULL;
	pRasSetEntryDialParamsW	= NULL;

	FreeLibrary(hDllRAS);
	hDllRAS = NULL;
}

DWORD APIENTRY RasEnumEntriesA(LPSTR reserved, LPSTR lpszPhonebook, LPRASENTRYNAMEA lprasentryname, LPDWORD lpcb, LPDWORD lpcEntries)
{
	return pRasEnumEntriesA ? pRasEnumEntriesA(reserved, lpszPhonebook, lprasentryname, lpcb, lpcEntries) : 1;
}

DWORD APIENTRY RasEnumEntriesW(LPWSTR reserved, LPWSTR lpszPhonebook, LPRASENTRYNAMEW lprasentryname, LPDWORD lpcb, LPDWORD lpcEntries)
{
	return pRasEnumEntriesW ? pRasEnumEntriesW(reserved, lpszPhonebook, lprasentryname, lpcb, lpcEntries) : 1;
}

DWORD APIENTRY RasEnumConnectionsA(LPRASCONNA lprasconn, LPDWORD lpcb, LPDWORD lpcConnections)
{
	return pRasEnumConnectionsA ? pRasEnumConnectionsA(lprasconn, lpcb, lpcConnections) : 1;
}

DWORD APIENTRY RasEnumConnectionsW(LPRASCONNW lprasconn, LPDWORD lpcb, LPDWORD lpcConnections)
{
	return pRasEnumConnectionsW ? pRasEnumConnectionsW(lprasconn, lpcb, lpcConnections) : 1;
}

DWORD APIENTRY RasDialA(LPRASDIALEXTENSIONS lpRasDialExtensions, LPSTR lpszPhonebook, LPRASDIALPARAMSA lpRasDialParams, DWORD dwNotifierType, LPVOID lpvNotifier, LPHRASCONN lphRasConn)
{
	return pRasDialA ? pRasDialA(lpRasDialExtensions, lpszPhonebook, lpRasDialParams, dwNotifierType, lpvNotifier, lphRasConn) : 1;
}

DWORD APIENTRY RasDialW(LPRASDIALEXTENSIONS lpRasDialExtensions, LPWSTR lpszPhonebook, LPRASDIALPARAMSW lpRasDialParams, DWORD dwNotifierType, LPVOID lpvNotifier, LPHRASCONN lphRasConn)
{
	return pRasDialW ? pRasDialW(lpRasDialExtensions, lpszPhonebook, lpRasDialParams, dwNotifierType, lpvNotifier, lphRasConn) : 1;
}

DWORD APIENTRY RasHangUpA(HRASCONN hrasconn)
{
	return pRasHangUpA ? pRasHangUpA(hrasconn) : 1;
}

DWORD APIENTRY RasHangUpW(HRASCONN hrasconn)
{
	return pRasHangUpW ? pRasHangUpW(hrasconn) : 1;
}

DWORD APIENTRY RasGetConnectStatusA(HRASCONN hrasconn, LPRASCONNSTATUSA lprasconnstatus)
{
	return pRasGetConnectStatusA ? pRasGetConnectStatusA(hrasconn, lprasconnstatus) : 1;
}

DWORD APIENTRY RasGetConnectStatusW(HRASCONN hrasconn, LPRASCONNSTATUSW lprasconnstatus)
{
	return pRasGetConnectStatusW ? pRasGetConnectStatusW(hrasconn, lprasconnstatus) : 1;
}

DWORD APIENTRY RasGetErrorStringA(UINT uErrorValue, LPSTR lpszErrorString, DWORD cBufSize)
{
	return pRasGetErrorStringA ? pRasGetErrorStringA(uErrorValue, lpszErrorString, cBufSize) : 1;
}

DWORD APIENTRY RasGetErrorStringW(UINT uErrorValue, LPWSTR lpszErrorString, DWORD cBufSize)
{
	return pRasGetErrorStringW ? pRasGetErrorStringW(uErrorValue, lpszErrorString, cBufSize) : 1;
}

DWORD APIENTRY RasGetEntryDialParamsA(LPSTR lpszPhonebook, LPRASDIALPARAMSA lprasdialparams, LPBOOL lpfPassword)
{
	return pRasGetEntryDialParamsA ? pRasGetEntryDialParamsA(lpszPhonebook, lprasdialparams, lpfPassword) : 1;
}

DWORD APIENTRY RasGetEntryDialParamsW(LPWSTR lpszPhonebook, LPRASDIALPARAMSW lprasdialparams, LPBOOL lpfPassword)
{
	return pRasGetEntryDialParamsW ? pRasGetEntryDialParamsW(lpszPhonebook, lprasdialparams, lpfPassword) : 1;
}

DWORD APIENTRY RasSetEntryDialParamsA(LPSTR lpszPhonebook, LPRASDIALPARAMSA lprasdialparams, BOOL fRemovePassword)
{
	return pRasSetEntryDialParamsA ? pRasSetEntryDialParamsA(lpszPhonebook, lprasdialparams, fRemovePassword) : 1;
}

DWORD APIENTRY RasSetEntryDialParamsW(LPWSTR lpszPhonebook, LPRASDIALPARAMSW lprasdialparams, BOOL fRemovePassword)
{
	return pRasSetEntryDialParamsW ? pRasSetEntryDialParamsW(lpszPhonebook, lprasdialparams, fRemovePassword) : 1;
}
