Introduction
There was a time I needed to detect an internet connection using the modem. I've checked the RAS library and found 2 useful functions: RasEnumConnections
and RasGetConnectStatus
.
The first function (RasEnumConnections
) retrieve a specified amount of connections:
DWORD RasEnumConnections (
LPRASCONN lprasconn,
LPDWORD lpcb,
LPDWORD lpcConnections
);
lprasconn -
Points to a buffer that receives an array of RASCONN
structures, one for each RAS connection. Before calling the function, an application must set the dwSize
member of the first RASCONN
structure in the buffer to sizeof(RASCONN)
in order to identify the version of the structure being passed.
lpcb -
Points to a variable that contains the size, in bytes, of the buffer specified by lprasconn
. On return, the function sets this variable to the number of bytes required to enumerate the RAS connections.
lpcConnections -
Points to a variable that the function sets to the number of RASCONN
structures written to the buffer specified by lprasconn
.
Return Value: 0 - Succeed; Other - Error code
The RASCONN
is a structure which hold the information on a single connection:
typedef struct _RASCONN {
DWORD dwSize;
HRASCONN hrasconn;
TCHAR szEntryName[RAS_MaxEntryName + 1];
#if (WINVER >= 0x400)
CHAR szDeviceType[RAS_MaxDeviceType + 1];
CHAR szDeviceName[RAS_MaxDeviceName + 1];
#endif
} RASCONN ;
dwSize
- Specifies the size, in bytes, of the RASCONN
structure.
hrasconn
- Specifies the remote access connection. This handle is used in other remote access API calls.
szEntryName
- A string that specifies the phone-book entry used to establish the remote access connection. If the connection was established using an empty entry name, this string consists of a "." followed by the connection phone number.
szDeviceType
- A null-terminated string that contains the device type through which the connection is made.
szDeviceName
- A null-terminated string that contains the device name through which the connection is made.
The second function (RasGetConnectStatus
) retrieves information on the current status of the specified connection
DWORD RasGetConnectStatus (
HRASCONN hrasconn,
LPRASCONNSTATUS lprasconnstatus
);
hrasconn
- Identifies the remote access connection for which to retrieve the status. This handle must have been obtained from RasDial
or RasEnumConnections
.
lprasconnstatus
- Points to a RASCONNSTATUS
structure that the function fills with status information. Before calling the function, an application must set the dwSize
member of the structure to sizeof(RASCONNSTATUS)
in order to identify the version of the structure being passed.
Return Value: 0 - Succeed; Other - Error code
The RASCONNSTATUS
structure describes the current status of a connection.
typedef struct _RASCONNSTATUS {
DWORD dwSize;
RASCONNSTATE rasconnstate;
DWORD dwError;
TCHAR szDeviceType[RAS_MaxDeviceType + 1];
TCHAR szDeviceName[RAS_MaxDeviceName + 1];
} RASCONNSTATUS;
To use the RAS library, you need to include <ras.h> in your source files and add rasapi32.lib to link with your application.
I've distributed my application and then I had a problem. One day, I got a mail which describes an error. It turns out that my client's computer missing rasapi32.dll. Only when you install the "Dial-out networking" you get rasapi32.dll. So instead linking rasapi32.lib to my application, I've decided to load it at runtime so I can detect if it is installed instead of getting an error message. What I had to remember is that rasapi32.dll contains 2 kinds of functions: ANSI and UNICODE
, so the code need to know which one to use. I check the _UNICODE
constant definition. Then, I load the library, look for the functions address and call them to get my connection status.
All you need to do to use the code, is to include "rasstatus.h" in your project. I also made a demo project but it is very simple and it only used to check that the code really works.
The code is not so hard to understand and I added some comments so you can understand easily.
#ifndef _RASSTATUS
#define _RASSTATUS
#include <ras.h>
typedef DWORD (WINAPI *RasEnumConnectionsType)(LPRASCONN lprasconn,
LPDWORD lpcb,LPDWORD lpcConnections);
typedef DWORD (WINAPI *RasGetConnectStatusType)(HRASCONN hrasconn,
LPRASCONNSTATUS lprasconnstatus);
#ifdef _UNICODE
#define RasFileName L"RASAPI32.DLL"
#define RasEnumConnectionsName L"RasEnumConnectionsW"
#define RasGetConnectStatusName L"RasGetConnectStatusW"
#else
#define RasFileName "RASAPI32.DLL"
#define RasEnumConnectionsName "RasEnumConnectionsA"
#define RasGetConnectStatusName "RasGetConnectStatusA"
#endif
BOOL IsRasConnected()
{
HINSTANCE hLib = LoadLibrary(RasFileName);
if (hLib == NULL)
return FALSE;
RasEnumConnectionsType _RasEnumConnections =
(RasEnumConnectionsType)GetProcAddress(hLib,RasEnumConnectionsName);
RasGetConnectStatusType _RasGetConnectStatus =
(RasGetConnectStatusType)GetProcAddress(hLib,RasGetConnectStatusName);
BOOL bResult = FALSE;
if (_RasEnumConnections && _RasGetConnectStatus)
{
RASCONN RasConn;
RASCONNSTATUS RasConnStatus;
RasConnStatus.dwSize = sizeof(RASCONNSTATUS);
DWORD dwConnSize = sizeof(RASCONN);
DWORD dwRasCount = 1;
RasConn.dwSize = dwConnSize;
bResult =
(((*_RasEnumConnections)(&RasConn,&dwConnSize,&dwRasCount)) == 0)
&& (((*_RasGetConnectStatus)(RasConn.hrasconn,&RasConnStatus)) == 0)
&& (RasConnStatus.rasconnstate == RASCS_Connected);
}
FreeLibrary(hLib);
return bResult;
}
#endif
All you need to do is to call IsRasConnected
which returns TRUE
is your are connected to the internet or FALSE
otherwise. Hope it could help :) If you have any questions or comments, you can contact me: Gilad Novik - gilad@bmidas.com