789 lines
22 KiB
C
789 lines
22 KiB
C
/*
|
|
|
|
RASLaunch.c : module to manage RAS connections
|
|
|
|
|
|
17/06/97
|
|
|
|
Author: Christophe Roguet
|
|
*/
|
|
|
|
|
|
#include <NET\RASLaunch.h>
|
|
#include <winbase.h>
|
|
#include <ras.h>
|
|
#include <raserror.h>
|
|
#include <winsock.h>
|
|
|
|
|
|
|
|
|
|
/* two macros to obtain a string that is the name of a DLL entry */
|
|
|
|
#define MakeFunctionName(n) (MakeFunctionName2(n))
|
|
#define MakeFunctionName2(n) (#n)
|
|
|
|
int RASLoadRAS(), RASUnloadRAS(), RASLoadIP(), RASUnloadIP();
|
|
|
|
|
|
|
|
/****************************************************************/
|
|
/****************************************************************/
|
|
/****************************************************************/
|
|
/****************************************************************/
|
|
/****************************************************************/
|
|
|
|
/* global variables */
|
|
|
|
/* flag: has the module be initialized ? */
|
|
|
|
static char gs_bIsInitialized = 0;
|
|
|
|
/* handle to the RAS DLL */
|
|
|
|
static HINSTANCE gs_hRASAPI_DLL = NULL;
|
|
|
|
/* pointers to the RAS DLL functions that we use */
|
|
|
|
static DWORD (APIENTRY *gs_pfndwRasEnumEntries)(LPTSTR, LPTSTR, LPRASENTRYNAME, LPDWORD, LPDWORD) = NULL;
|
|
static DWORD (APIENTRY *gs_pfndwRasEnumConnections)(LPRASCONN, LPDWORD, LPDWORD) = NULL;
|
|
static DWORD (APIENTRY *gs_pfndwRasGetConnectStatus)(HRASCONN, LPRASCONNSTATUS) = NULL;
|
|
static DWORD (APIENTRY *gs_pfndwRasGetEntryDialParams)(LPTSTR, LPRASDIALPARAMS, LPBOOL) = NULL;
|
|
static DWORD (APIENTRY *gs_pfndwRasDial)(LPRASDIALEXTENSIONS, LPTSTR, LPRASDIALPARAMS, DWORD, LPVOID, LPHRASCONN) = NULL;
|
|
static DWORD (APIENTRY *gs_pfndwRasHangUp)(HRASCONN) = NULL;
|
|
static DWORD (APIENTRY *gs_pfndwRasGetErrorString)(UINT, LPTSTR, DWORD) = NULL;
|
|
|
|
/****************************************************************/
|
|
/* RAS_Init() */
|
|
/****************************************************************/
|
|
|
|
int RAS_Init()
|
|
|
|
{
|
|
if( !(gs_bIsInitialized & RASInitialized) && RASLoadRAS()==0)
|
|
gs_bIsInitialized|=RASInitialized;
|
|
|
|
if( !(gs_bIsInitialized & IPInitialized) && RASLoadIP()==0)
|
|
gs_bIsInitialized|=IPInitialized;
|
|
|
|
return gs_bIsInitialized;
|
|
}
|
|
|
|
/****************************************************************/
|
|
/* RAS_Exit() */
|
|
/* 0: success */
|
|
/****************************************************************/
|
|
|
|
int RAS_Exit()
|
|
|
|
{
|
|
int RASUnloadOK, IPUnloadOK;
|
|
if(gs_bIsInitialized & RASInitialized) {
|
|
RASUnloadOK=RASUnloadRAS();
|
|
if(RASUnloadOK==0)
|
|
gs_bIsInitialized&=~RASInitialized;
|
|
}
|
|
|
|
if(gs_bIsInitialized & IPInitialized) {
|
|
IPUnloadOK=RASUnloadIP();
|
|
if(IPUnloadOK==0)
|
|
gs_bIsInitialized&=~IPInitialized;
|
|
}
|
|
|
|
return RASUnloadOK | IPUnloadOK;
|
|
}
|
|
|
|
/****************************************************************/
|
|
|
|
/****************************************************************/
|
|
/* RASLoadRAS */
|
|
/* Attach the process to the RAS DLL */
|
|
/* return value: */
|
|
/* 0: success */
|
|
/* -1: failure */
|
|
/****************************************************************/
|
|
|
|
int RASLoadRAS(void)
|
|
|
|
{
|
|
long lErrorCode;
|
|
gs_hRASAPI_DLL=LoadLibrary("RASAPI32.DLL");
|
|
|
|
if(gs_hRASAPI_DLL==NULL) {
|
|
lErrorCode=GetLastError();
|
|
return -1;
|
|
}
|
|
|
|
gs_pfndwRasEnumEntries=(DWORD (APIENTRY*)(LPTSTR, LPTSTR, LPRASENTRYNAME, LPDWORD, LPDWORD))
|
|
GetProcAddress(gs_hRASAPI_DLL, MakeFunctionName(RasEnumEntries));
|
|
if(gs_pfndwRasEnumEntries==NULL) {
|
|
lErrorCode=GetLastError();
|
|
return -1;
|
|
}
|
|
|
|
gs_pfndwRasEnumConnections=(DWORD (APIENTRY*)(LPRASCONN, LPDWORD, LPDWORD))
|
|
GetProcAddress(gs_hRASAPI_DLL, MakeFunctionName(RasEnumConnections));
|
|
if(gs_pfndwRasEnumConnections==NULL) {
|
|
lErrorCode=GetLastError();
|
|
return -1;
|
|
}
|
|
|
|
gs_pfndwRasGetConnectStatus=(DWORD (APIENTRY*)(HRASCONN, LPRASCONNSTATUS))
|
|
GetProcAddress(gs_hRASAPI_DLL, MakeFunctionName(RasGetConnectStatus));
|
|
if(gs_pfndwRasGetConnectStatus==NULL) {
|
|
lErrorCode=GetLastError();
|
|
return -1;
|
|
}
|
|
|
|
gs_pfndwRasGetEntryDialParams=(DWORD (APIENTRY*)(LPTSTR, LPRASDIALPARAMS, LPBOOL))
|
|
GetProcAddress(gs_hRASAPI_DLL, MakeFunctionName(RasGetEntryDialParams));
|
|
if(gs_pfndwRasGetEntryDialParams==NULL) {
|
|
lErrorCode=GetLastError();
|
|
return -1;
|
|
}
|
|
|
|
gs_pfndwRasDial=(DWORD (APIENTRY*)(LPRASDIALEXTENSIONS, LPTSTR, LPRASDIALPARAMS, DWORD, LPVOID, LPHRASCONN))
|
|
GetProcAddress(gs_hRASAPI_DLL, MakeFunctionName(RasDial));
|
|
if(gs_pfndwRasDial==NULL) {
|
|
lErrorCode=GetLastError();
|
|
return -1;
|
|
}
|
|
|
|
gs_pfndwRasHangUp=(DWORD (APIENTRY*)(HRASCONN))
|
|
GetProcAddress(gs_hRASAPI_DLL, MakeFunctionName(RasHangUp));
|
|
if(gs_pfndwRasHangUp==NULL) {
|
|
lErrorCode=GetLastError();
|
|
return -1;
|
|
}
|
|
|
|
gs_pfndwRasGetErrorString=(DWORD (APIENTRY*)(UINT, LPTSTR, DWORD))
|
|
GetProcAddress(gs_hRASAPI_DLL, MakeFunctionName(RasGetErrorString));
|
|
if(gs_pfndwRasGetErrorString==NULL) {
|
|
lErrorCode=GetLastError();
|
|
return -1;
|
|
}
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************/
|
|
/* RASUnloadRAS() */
|
|
/* Detach from the RAS DLL */
|
|
/* return value: */
|
|
/* 0: success */
|
|
/* -1: failure */
|
|
/****************************************************************/
|
|
|
|
int RASUnloadRAS(void)
|
|
|
|
{
|
|
long lErrorCode;
|
|
|
|
if(FreeLibrary(gs_hRASAPI_DLL)==FALSE) {
|
|
lErrorCode=GetLastError();
|
|
return -1;
|
|
}
|
|
|
|
gs_hRASAPI_DLL=NULL;
|
|
|
|
gs_pfndwRasEnumEntries=(DWORD (APIENTRY*)(LPTSTR, LPTSTR, LPRASENTRYNAME, LPDWORD, LPDWORD))
|
|
0L;
|
|
gs_pfndwRasEnumConnections=(DWORD (APIENTRY*)(LPRASCONN, LPDWORD, LPDWORD))
|
|
0L;
|
|
gs_pfndwRasGetConnectStatus=(DWORD (APIENTRY*)(HRASCONN, LPRASCONNSTATUS))
|
|
0L;
|
|
gs_pfndwRasGetEntryDialParams=(DWORD (APIENTRY*)(LPTSTR, LPRASDIALPARAMS, LPBOOL))
|
|
0L;
|
|
gs_pfndwRasDial=(DWORD (APIENTRY*)(LPRASDIALEXTENSIONS, LPTSTR, LPRASDIALPARAMS, DWORD, LPVOID, LPHRASCONN))
|
|
0L;
|
|
gs_pfndwRasHangUp=(DWORD (APIENTRY*)(HRASCONN))
|
|
0L;
|
|
gs_pfndwRasGetErrorString=(DWORD (APIENTRY*)(UINT, LPTSTR, DWORD))
|
|
0L;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************/
|
|
/****************************************************************/
|
|
/****************************************************************/
|
|
/****************************************************************/
|
|
/****************************************************************/
|
|
/****************************************************************/
|
|
|
|
/* RAS callback function declaration */
|
|
|
|
VOID APIENTRY RASNotifier(UINT , RASCONNSTATE , DWORD );
|
|
|
|
/* handle to the RAS connection */
|
|
|
|
static HRASCONN gs_hConnection=INVALID_HANDLE_VALUE;
|
|
|
|
|
|
/****************************************************************/
|
|
/* RASScanEntries */
|
|
/* to list the available RAS connections */
|
|
/* return value: */
|
|
/* -1: no more available entry */
|
|
/* 0: an entry has been found */
|
|
/****************************************************************/
|
|
|
|
int RASScanEntries(char bStart, char *pcName, int iSize)
|
|
|
|
{
|
|
static DWORD s_dwBufferSize=0;
|
|
static DWORD s_dwNumberOfWrittenEntries=0;
|
|
static LPRASENTRYNAME s_pBuffer=0;
|
|
DWORD dwReturnValue;
|
|
static DWORD s_dwCurrentEntry=0;
|
|
|
|
if( !(gs_bIsInitialized & RASInitialized) )
|
|
return -1;
|
|
|
|
if(bStart) {
|
|
s_dwCurrentEntry=0;
|
|
|
|
if(s_pBuffer!=0)
|
|
free(s_pBuffer);
|
|
|
|
s_dwBufferSize=sizeof(RASENTRYNAME);
|
|
|
|
s_pBuffer=(LPRASENTRYNAME)malloc(s_dwBufferSize);
|
|
|
|
s_pBuffer->dwSize=sizeof(RASENTRYNAME);
|
|
|
|
dwReturnValue=gs_pfndwRasEnumEntries(NULL, NULL, s_pBuffer, &s_dwBufferSize, &s_dwNumberOfWrittenEntries);
|
|
|
|
while(dwReturnValue==ERROR_BUFFER_TOO_SMALL || dwReturnValue==ERROR_NOT_ENOUGH_MEMORY) {
|
|
free(s_pBuffer);
|
|
s_pBuffer=(LPRASENTRYNAME)malloc(s_dwBufferSize);
|
|
s_pBuffer->dwSize=sizeof(RASENTRYNAME);
|
|
dwReturnValue=gs_pfndwRasEnumEntries(NULL, NULL, s_pBuffer, &s_dwBufferSize, &s_dwNumberOfWrittenEntries);
|
|
}
|
|
|
|
if(dwReturnValue!=0) {
|
|
free(s_pBuffer);
|
|
s_pBuffer=0;
|
|
return -1;
|
|
}
|
|
|
|
}
|
|
|
|
if(s_dwCurrentEntry<s_dwNumberOfWrittenEntries) {
|
|
strncpy(pcName, s_pBuffer[s_dwCurrentEntry].szEntryName, iSize-1);
|
|
s_dwCurrentEntry++;
|
|
return 0;
|
|
} else {
|
|
if(s_pBuffer!=0) {
|
|
free(s_pBuffer);
|
|
s_pBuffer=0;
|
|
}
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/****************************************************************/
|
|
/* RASScanConnections */
|
|
/* to list the active RAS connections */
|
|
/* return value: */
|
|
/* -1: no more active connection */
|
|
/* 0: an active connection has been found */
|
|
/****************************************************************/
|
|
|
|
int RASScanConnections(char bStart, char *pcName, int iSize, int *iState)
|
|
|
|
{
|
|
static DWORD s_dwBufferSize=0;
|
|
static DWORD s_dwNumberOfWrittenConnections=0;
|
|
static LPRASCONN s_pBuffer=0;
|
|
DWORD dwReturnValue;
|
|
static DWORD s_dwCurrentConnection=0;
|
|
RASCONNSTATUS stRasConnStatus;
|
|
|
|
if( !(gs_bIsInitialized & RASInitialized) )
|
|
return -1;
|
|
|
|
if(bStart) {
|
|
s_dwCurrentConnection=0;
|
|
|
|
if(s_pBuffer!=0)
|
|
free(s_pBuffer);
|
|
|
|
s_dwBufferSize=sizeof(RASCONN);
|
|
|
|
s_pBuffer=(LPRASCONN)malloc(s_dwBufferSize);
|
|
|
|
s_pBuffer->dwSize=sizeof(RASCONN);
|
|
|
|
dwReturnValue=gs_pfndwRasEnumConnections(s_pBuffer, &s_dwBufferSize, &s_dwNumberOfWrittenConnections);
|
|
|
|
while(dwReturnValue==ERROR_BUFFER_TOO_SMALL || dwReturnValue==ERROR_NOT_ENOUGH_MEMORY) {
|
|
free(s_pBuffer);
|
|
s_pBuffer=(LPRASCONN)malloc(s_dwBufferSize);
|
|
s_pBuffer->dwSize=sizeof(RASCONN);
|
|
dwReturnValue=gs_pfndwRasEnumConnections(s_pBuffer, &s_dwBufferSize, &s_dwNumberOfWrittenConnections);
|
|
}
|
|
|
|
if(dwReturnValue!=0) {
|
|
free(s_pBuffer);
|
|
s_pBuffer=0;
|
|
return -1;
|
|
}
|
|
|
|
}
|
|
|
|
if(s_dwCurrentConnection<s_dwNumberOfWrittenConnections) {
|
|
strncpy(pcName, s_pBuffer[s_dwCurrentConnection].szEntryName, iSize-1);
|
|
stRasConnStatus.dwSize=sizeof(RASCONNSTATUS);
|
|
dwReturnValue=gs_pfndwRasGetConnectStatus( s_pBuffer[s_dwCurrentConnection].hrasconn,
|
|
&stRasConnStatus);
|
|
if(dwReturnValue==0) {
|
|
/* *iState=stRasConnStatus.rasconnstate;*/
|
|
switch(stRasConnStatus.rasconnstate) {
|
|
case RASCS_Connected:
|
|
*iState=myRAS_CONNECTED;
|
|
break;
|
|
case RASCS_Disconnected:
|
|
*iState=myRAS_DISCONNECTED;
|
|
break;
|
|
default:
|
|
*iState=myRAS_UNKNOWN;
|
|
break;
|
|
}
|
|
} else {
|
|
if(dwReturnValue==ERROR_INVALID_HANDLE)
|
|
*iState=myRAS_IDLE;
|
|
else
|
|
*iState=myRAS_ERROR;
|
|
}
|
|
s_dwCurrentConnection++;
|
|
return 0;
|
|
} else {
|
|
if(s_pBuffer!=0) {
|
|
free(s_pBuffer);
|
|
s_pBuffer=0;
|
|
}
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/****************************************************************/
|
|
/* RASStartConnection */
|
|
/* launches the module RAS connection */
|
|
/****************************************************************/
|
|
|
|
int RASGetConnectionAccount(const char *pcEntryName, char *pcAccountName, char *pcPassword)
|
|
|
|
{
|
|
RASDIALPARAMS stDialParams;
|
|
BOOL bPasswordRetrieved;
|
|
DWORD dwErrorCode;
|
|
|
|
if( !(gs_bIsInitialized & RASInitialized) )
|
|
return -1;
|
|
|
|
memset(&stDialParams, 0, sizeof(RASDIALPARAMS));
|
|
|
|
stDialParams.dwSize=sizeof(RASDIALPARAMS);
|
|
strncpy(stDialParams.szEntryName, pcEntryName, RAS_MaxEntryName);
|
|
|
|
dwErrorCode=gs_pfndwRasGetEntryDialParams(NULL, &stDialParams, &bPasswordRetrieved);
|
|
|
|
if(bPasswordRetrieved) {
|
|
strcpy(pcAccountName, stDialParams.szUserName);
|
|
strcpy(pcPassword, stDialParams.szPassword);
|
|
return 0;
|
|
} else {
|
|
*pcAccountName='\0';
|
|
*pcPassword='\0';
|
|
return -1;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/****************************************************************/
|
|
/* RASStartConnection */
|
|
/* launches the module RAS connection */
|
|
/****************************************************************/
|
|
|
|
int RASStartConnection(const char *pcEntryName, const char *pcAccountName, const char *pcPassword)
|
|
|
|
{
|
|
RASDIALPARAMS stDialParams;
|
|
BOOL bPasswordRetrieved;
|
|
DWORD dwErrorCode;
|
|
|
|
if( !(gs_bIsInitialized & RASInitialized) )
|
|
return -1;
|
|
|
|
memset(&stDialParams, 0, sizeof(RASDIALPARAMS));
|
|
|
|
stDialParams.dwSize=sizeof(RASDIALPARAMS);
|
|
strncpy(stDialParams.szEntryName, pcEntryName, RAS_MaxEntryName);
|
|
|
|
dwErrorCode=gs_pfndwRasGetEntryDialParams(NULL, &stDialParams, &bPasswordRetrieved);
|
|
|
|
if(dwErrorCode!=0)
|
|
return -1;
|
|
|
|
/* if an account name is provided, use this one instead of the retrieved one */
|
|
|
|
if(pcAccountName!=NULL) {
|
|
strncpy(stDialParams.szUserName, pcAccountName, UNLEN);
|
|
strncpy(stDialParams.szPassword, pcPassword, PWLEN);
|
|
}
|
|
|
|
dwErrorCode=gs_pfndwRasDial(NULL, NULL, &stDialParams, 0, RASNotifier, &gs_hConnection);
|
|
|
|
if(dwErrorCode!=0)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************/
|
|
/* RASGetConnectionState */
|
|
/* get the status of the module connection */
|
|
/* return value: */
|
|
/****************************************************************/
|
|
int RASGetConnectionState()
|
|
|
|
{
|
|
RASCONNSTATUS stRasConnStatus;
|
|
DWORD dwReturnValue;
|
|
|
|
if( !(gs_bIsInitialized & RASInitialized) )
|
|
return -1;
|
|
|
|
dwReturnValue=gs_pfndwRasGetConnectStatus( gs_hConnection, &stRasConnStatus);
|
|
|
|
if(dwReturnValue==0) {
|
|
/* return stRasConnStatus.rasconnstate;*/
|
|
switch(stRasConnStatus.rasconnstate) {
|
|
case RASCS_Connected:
|
|
return myRAS_CONNECTED;
|
|
break;
|
|
case RASCS_Disconnected:
|
|
return myRAS_DISCONNECTED;
|
|
break;
|
|
default:
|
|
return myRAS_UNKNOWN;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(dwReturnValue==ERROR_INVALID_HANDLE)
|
|
return myRAS_IDLE;
|
|
|
|
return myRAS_ERROR;
|
|
}
|
|
|
|
/****************************************************************/
|
|
/* RASCloseConnection */
|
|
/* initiate the closing of the module RAS connection */
|
|
/* return value: */
|
|
/* 0: success */
|
|
/* -1: failure */
|
|
/****************************************************************/
|
|
|
|
int RASCloseConnection()
|
|
|
|
{
|
|
DWORD dwErrorCode;
|
|
|
|
if( !(gs_bIsInitialized & RASInitialized) )
|
|
return -1;
|
|
|
|
dwErrorCode=gs_pfndwRasHangUp(gs_hConnection);
|
|
|
|
if(dwErrorCode==0)
|
|
return 0;
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
/****************************************************************/
|
|
/* RASNotifier */
|
|
/* RAS Callback Function */
|
|
/* only useful for debug purpose */
|
|
/****************************************************************/
|
|
|
|
static VOID APIENTRY RASNotifier(UINT unMsg, RASCONNSTATE rasconnstate, DWORD dwError)
|
|
|
|
{
|
|
static char acErrorMsg[256];
|
|
if(dwError) {
|
|
gs_pfndwRasGetErrorString(dwError, acErrorMsg, sizeof(acErrorMsg));
|
|
}
|
|
}
|
|
|
|
/****************************************************************/
|
|
/****************************************************************/
|
|
/****************************************************************/
|
|
/****************************************************************/
|
|
/****************************************************************/
|
|
/****************************************************************/
|
|
|
|
|
|
/* set of functions to test the IP connectivity */
|
|
|
|
|
|
static HANDLE gs_hWinsockDll = NULL;
|
|
static char gs_bWinsockStarted = 0;
|
|
|
|
static int (PASCAL *gs_pfniWSAStartup)(WORD, LPWSADATA) = NULL;
|
|
static int (PASCAL *gs_pfniWSACleanup)(void) = NULL;
|
|
static int (PASCAL *gs_pfniWSAGetLastError)(void) = NULL;
|
|
static SOCKET (PASCAL *gs_pfnisocket)(int, int, int) = NULL;
|
|
static int (PASCAL *gs_pfniclosesocket)(SOCKET) = NULL;
|
|
static int (PASCAL *gs_pfniconnect)(SOCKET, const struct sockaddr FAR *, int) = NULL;
|
|
static unsigned short (PASCAL *gs_pfnushtons)(unsigned short) = NULL;
|
|
static unsigned long (PASCAL *gs_pfnulinet_addr)(const char FAR *) = NULL;
|
|
static struct hostent FAR *(PASCAL *gs_pfnpstgethostbyname)(const char FAR *) = NULL;
|
|
static int (PASCAL *gs_pfniioctlsocket)(SOCKET, long, u_long FAR *);
|
|
static int (PASCAL *gs_pfniselect)(int, fd_set FAR *, fd_set FAR *, fd_set FAR *, const struct timeval FAR *);
|
|
static int FAR (PASCAL *gs_pfni__WSAFDIsSet)(SOCKET, fd_set FAR *);
|
|
|
|
|
|
static int gs_iConnectivityState = -1;
|
|
static SOCKET gs_sd = INVALID_SOCKET;
|
|
static struct sockaddr_in gs_stTargetAddr;
|
|
|
|
/****************************************************************/
|
|
/* RASLoadIP() */
|
|
/* Attach to the winsock DLL */
|
|
/* return value: */
|
|
/* 0 : success */
|
|
/* -1: failure */
|
|
/****************************************************************/
|
|
|
|
int RASLoadIP()
|
|
|
|
{
|
|
WSADATA stWSAData;
|
|
|
|
gs_hWinsockDll=LoadLibrary("WSOCK32.DLL");
|
|
|
|
if(gs_hWinsockDll==NULL)
|
|
return -1; /* the winsock DLL is not present on this computer */
|
|
|
|
gs_pfniWSAStartup=(int (PASCAL *)(WORD, LPWSADATA))GetProcAddress(gs_hWinsockDll, MakeFunctionName(WSAStartup));
|
|
gs_pfniWSACleanup=(int (PASCAL *)(void))GetProcAddress(gs_hWinsockDll, MakeFunctionName(WSACleanup));
|
|
gs_pfniWSAGetLastError=(int (PASCAL *)(void))GetProcAddress(gs_hWinsockDll, MakeFunctionName(WSAGetLastError));
|
|
gs_pfnisocket=(SOCKET (PASCAL *)(int, int, int))GetProcAddress(gs_hWinsockDll, MakeFunctionName(socket));
|
|
gs_pfniclosesocket=(int (PASCAL *)(SOCKET))GetProcAddress(gs_hWinsockDll, MakeFunctionName(closesocket));
|
|
gs_pfniconnect=(int (PASCAL *)(SOCKET, const struct sockaddr FAR *, int))GetProcAddress(gs_hWinsockDll, MakeFunctionName(connect));
|
|
gs_pfnushtons=(unsigned short (PASCAL *)(unsigned short))GetProcAddress(gs_hWinsockDll, MakeFunctionName(htons));
|
|
gs_pfnulinet_addr=(unsigned long (PASCAL *)(const char FAR *))GetProcAddress(gs_hWinsockDll, MakeFunctionName(inet_addr));
|
|
gs_pfnpstgethostbyname=(struct hostent FAR * (PASCAL *)(const char FAR *))GetProcAddress(gs_hWinsockDll, MakeFunctionName(gethostbyname));
|
|
gs_pfniioctlsocket=(int (PASCAL *)(SOCKET, long, u_long FAR *))GetProcAddress(gs_hWinsockDll, MakeFunctionName(ioctlsocket));
|
|
gs_pfniselect=(int (PASCAL *)(int, fd_set FAR *, fd_set FAR *, fd_set FAR *, const struct timeval FAR *))GetProcAddress(gs_hWinsockDll, MakeFunctionName(select));
|
|
|
|
gs_pfni__WSAFDIsSet=(int FAR (PASCAL *)(SOCKET, fd_set FAR *))GetProcAddress(gs_hWinsockDll, MakeFunctionName(__WSAFDIsSet));
|
|
|
|
if(gs_pfniWSAStartup(MAKEWORD(1,1), &stWSAData)) {
|
|
RASUnloadIP();
|
|
return -2; /* can't negotiate DLL version */
|
|
}
|
|
|
|
gs_bWinsockStarted=~0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************/
|
|
/* RASUnloadIP() */
|
|
/* Detach from the winsock DLL */
|
|
/* return value: */
|
|
/* 0 : success */
|
|
/* -1: failure */
|
|
/****************************************************************/
|
|
|
|
int RASUnloadIP()
|
|
|
|
{
|
|
/* long lErrorCode; */
|
|
|
|
/* delete the connect thread */
|
|
|
|
if(gs_sd!=INVALID_SOCKET) {
|
|
gs_pfniclosesocket(gs_sd);
|
|
gs_sd=INVALID_SOCKET;
|
|
}
|
|
|
|
/* deregister from the winsock DLL and unload it */
|
|
|
|
if(gs_bWinsockStarted)
|
|
if(gs_pfniWSACleanup())
|
|
return -1;
|
|
else
|
|
gs_bWinsockStarted=0;
|
|
|
|
if(FreeLibrary(gs_hWinsockDll)==FALSE)
|
|
return -1;
|
|
|
|
gs_hWinsockDll=NULL;
|
|
|
|
gs_pfniWSAStartup=(int (PASCAL *)(WORD, LPWSADATA))NULL;
|
|
gs_pfniWSACleanup=(int (PASCAL *)(void))NULL;
|
|
gs_pfniWSAGetLastError=(int (PASCAL *)(void))NULL;
|
|
gs_pfnisocket=(SOCKET (PASCAL *)(int, int, int))NULL;
|
|
gs_pfniclosesocket=(int (PASCAL *)(SOCKET))NULL;
|
|
gs_pfniconnect=(int (PASCAL *)(SOCKET, const struct sockaddr FAR *, int))NULL;
|
|
gs_pfnushtons=(unsigned short (PASCAL *)(unsigned short))NULL;
|
|
gs_pfnulinet_addr=(unsigned long (PASCAL *)(const char FAR *))NULL;
|
|
gs_pfnpstgethostbyname=(struct hostent FAR * (PASCAL *)(const char FAR *))NULL;
|
|
gs_pfniioctlsocket=(int (PASCAL *)(SOCKET, long, u_long FAR *))GetProcAddress(gs_hWinsockDll, MakeFunctionName(ioctlsocket));
|
|
gs_pfniselect=(int (PASCAL *)(int, fd_set FAR *, fd_set FAR *, fd_set FAR *, const struct timeval FAR *))NULL;
|
|
|
|
gs_pfni__WSAFDIsSet=(int FAR (PASCAL *)(SOCKET, fd_set FAR *))NULL;
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************/
|
|
/* TouchTarget */
|
|
/****************************************************************/
|
|
|
|
int RASTouchTarget(const char *acTargetAddr)
|
|
|
|
{
|
|
|
|
struct hostent *entry;
|
|
|
|
long lErrorCode;
|
|
|
|
int iReturnValue;
|
|
|
|
unsigned long ulMode;
|
|
|
|
if( !(gs_bIsInitialized & IPInitialized) )
|
|
return myRAS_NotInitialized;
|
|
|
|
if(gs_sd!=INVALID_SOCKET)
|
|
return myRAS_Busy; /* a search is in progress */
|
|
|
|
iReturnValue=myRAS_IPUnavailable; /* TCP/IP is not installed on the computer */
|
|
|
|
/* create a TCP socket and try to connect it to the target address */
|
|
|
|
gs_sd=gs_pfnisocket(PF_INET, SOCK_STREAM, 0);
|
|
|
|
if(gs_sd>0) {
|
|
|
|
iReturnValue=0; /* the target address can be reached */
|
|
|
|
gs_stTargetAddr.sin_family = AF_INET;
|
|
gs_stTargetAddr.sin_port = gs_pfnushtons (80); /* www port, but any socket number should do */
|
|
gs_stTargetAddr.sin_addr.s_addr = gs_pfnulinet_addr(acTargetAddr);
|
|
|
|
if(gs_stTargetAddr.sin_addr.s_addr==INADDR_NONE) {
|
|
/* if the address is not a correct numeric address, ask a DNS to translate it */
|
|
|
|
entry=gs_pfnpstgethostbyname(acTargetAddr);
|
|
|
|
if(entry==NULL) { /* the supplied address is not correct */
|
|
gs_pfniclosesocket(gs_sd);
|
|
gs_sd=INVALID_SOCKET;
|
|
iReturnValue=myRAS_InvalidAddress;
|
|
} else
|
|
gs_stTargetAddr.sin_addr = *(struct in_addr *)(entry->h_addr_list[0]);
|
|
}
|
|
|
|
if(iReturnValue==0) {
|
|
|
|
iReturnValue=myRAS_InternalError; /* unable to start connecting */
|
|
|
|
/* set non blocking mode on the socket */
|
|
ulMode=~0;
|
|
|
|
if(gs_pfniioctlsocket(gs_sd, FIONBIO, &ulMode)==SOCKET_ERROR) {
|
|
lErrorCode=gs_pfniWSAGetLastError();
|
|
} else {
|
|
iReturnValue=0; /* the test operation is proceeding */
|
|
|
|
if(gs_pfniconnect(gs_sd, (struct sockaddr *)&gs_stTargetAddr, sizeof(gs_stTargetAddr))==SOCKET_ERROR) {
|
|
lErrorCode=gs_pfniWSAGetLastError();
|
|
/* should be WSAEWOULDBLOCK */
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if(iReturnValue!=0)
|
|
gs_iConnectivityState=-1;
|
|
else
|
|
gs_iConnectivityState=myRAS_Testing;
|
|
|
|
return iReturnValue;
|
|
}
|
|
|
|
/****************************************************************/
|
|
|
|
int RASCancelTouch()
|
|
|
|
{
|
|
if(gs_sd==INVALID_SOCKET)
|
|
return -1;
|
|
|
|
gs_pfniclosesocket(gs_sd);
|
|
gs_sd=INVALID_SOCKET;
|
|
|
|
gs_iConnectivityState=myRAS_Canceled;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************/
|
|
|
|
int RASGetConnectivity()
|
|
|
|
{
|
|
long lErrorCode;
|
|
|
|
fd_set WriteFD, ExceptionFD;
|
|
static struct timeval timeout = {0, 0};
|
|
|
|
int iNumberOfEvents;
|
|
|
|
/* is a connect operation in progress ? */
|
|
|
|
if(gs_sd==INVALID_SOCKET)
|
|
return gs_iConnectivityState;
|
|
|
|
/* has the connect operation finished ? */
|
|
|
|
FD_ZERO(&WriteFD);
|
|
FD_ZERO(&ExceptionFD);
|
|
FD_SET(gs_sd, &WriteFD);
|
|
FD_SET(gs_sd, &ExceptionFD);
|
|
|
|
iNumberOfEvents=gs_pfniselect(0, NULL, &WriteFD, &ExceptionFD, &timeout);
|
|
|
|
if(iNumberOfEvents==SOCKET_ERROR) {
|
|
lErrorCode=gs_pfniWSAGetLastError();
|
|
return -1;
|
|
}
|
|
|
|
if(iNumberOfEvents>0) {
|
|
if(gs_pfni__WSAFDIsSet(gs_sd, &WriteFD))
|
|
gs_iConnectivityState=myRAS_Connectable;
|
|
else if(gs_pfni__WSAFDIsSet(gs_sd, &ExceptionFD))
|
|
gs_iConnectivityState=myRAS_NotConnectable;
|
|
else
|
|
gs_iConnectivityState=-1;
|
|
|
|
gs_pfniclosesocket(gs_sd);
|
|
gs_sd=INVALID_SOCKET;
|
|
}
|
|
|
|
return gs_iConnectivityState;
|
|
}
|
|
|
|
/****************************************************************/
|