Remote Access Services (RAS)

< BACK  NEXT >
[oR]

The Remote Access Service (RAS) functions can be used to make a connection using a pre-defined RAS phone book entry. RAS will make the call, logon to the remote computer, handle authentication, and then negotiate network connections. You can use RAS connections to do the following:

Dial into a Windows NT or 2000 RAS-enabled server, and then use TCP/IP using Point to Point Protocol (PPP) to connect to file shares, printers, intranet, email server, or other resources. The Windows NTLM (NT LAN Manager) authentication will be handled by RAS.

Dial into an Internet Service Provider (ISP), and then use TCP/IP using Point to Point Protocol (PPP) to connect to the Internet or email. RAS will usually handle the logon and authentication required by the ISP.

RAS maintains a phone book with entries for each available connection. Users can manage this phone book using the Connections folder on the desktop. Each phone book entry has an associated name and information on how the connection should be made (such as the phone number, login credentials, and protocols to use). Standard RAS phone book entries are preinstalled to support the connection to desktop PCs, such as "Serial Port @ 19200."

Unlike TAPI, an application does not directly use the connection itself. Instead, it uses the TCP/IP network protocol through the connection managed by RAS. You can use RAS in your own applications to make a connection to aserver, and then use network techniques such as HTTP and sockets to communicate with the server (see Chapter 8). Alternatively, you can check whether a RAS connection is already made, and then use the existing connection if it is the server to which you require access. Note that RAS in Windows CE only supports a single connection at any one time, and does not support incoming connections. This means that, if a Windows CE device is currently connected to a desktop PC, RAS cannot be used to dial out through, for example, a modem.

In Windows CE the phone book is stored in the registry and not in files as is the case with Windows NT/98/2000. The key HKEY_CURRENT_USER\Comm\RasBook has a sub-key for each of the entries, such as "115200 Default." These sub-keys have values specifying the connection parameters, such as "User,""Domain," and "Password" (which is encrypted).

Listing RAS Phone Book Entries

The names of all the RAS phone book entries can be obtained through a call to the function RasEnumEntries (Table 11.9). To call this and any other RAS function, you should include ras.h for function prototypes and constants, and raserror.h for error codes.

Table 11.9. RasEnumEntries Retrieves all RAS phone book entries
RasEnumEntries
LPWSTR Reserved Pass as NULL.
LPWSTR lpszPhoneBookPath In Windows CE the Phone Book is stored in the registry, so pass as NULL.
LPRASENTRYNAME lprasentryname Pointer to an array of RASENTRYNAME structures that will receive information on the RAS phone book entries.
LPDWORD lpcb Size of the array pointed to by LPRASENTRYNAME in bytes.
LPDWORD lpcEntries Pointer to a DWORD that contains the number of returned phone book entries.
DWORD Return Value 0 for success, or an error code defined in the header file raserror.h.

An application calling RasEnumEntries should first allocate an array of RASENTRYNAME structures with enough elements to hold the expected number of phone book entries. The RASENTRYNAME structure has only two members:

  • dwSize The size of the structure in bytes

  • szEntryName A buffer in which the phone book entry name (e. g. "115200 Default") is placed

Before calling RasEnumEntries, the first element in the RASENTRYNAME array should have the dwSize member set to the size of a single RASENTRYNAME structure. In Listing 11.6, an array of 20 RASENTRYNAME structures is allocated, the first member is set to the size of the structure, and the dwSize variable is set to the overall size of the array in bytes. A call to RasEnumEntries is then made. A "for" loop is used to display the entry name for all the returned phone book entries

Listing 11.6 Listing RAS phone book entries
 #include <ras.h> #include <raserror.h> void Listing11_6() {   LPRASENTRYNAME lpRasEntry = NULL;   DWORD dwRes, dwSize, dwEntries, dw;   lpRasEntry = new RASENTRYNAME[20];   if(lpRasEntry == NULL)   {     cout   _T("Out of memory")   endl;     return;   }   lpRasEntry[0].dwSize = sizeof(RASENTRYNAME);   dwSize = sizeof(RASENTRYNAME) * 20;   dwRes = RasEnumEntries(NULL, NULL, lpRasEntry,           &dwSize, &dwEntries);   if (dwRes != 0)     cout   _T("Error getting RAS entries")            dwRes  endl;   else   {     for(dw = 0; dw < dwEntries; dw++)     {       cout   lpRasEntry[dw].szEntryName   endl;     }   }   delete[] lpRasEntry; } 

It is possible that more RAS phone book entries exist than will fit in the supplied array. RasEnumEntries is meant to return an ERROR_BUFFER_TOO_SMALL error, and only return the number of entries that fit in the array. However, in Windows CE RasEnumEntries returns a "0" value for success even if all the entries cannot be returned. So, if your array is completely full on a return from RasEnumEntries, you should reallocate the array to make it larger and call RasEnumEntries again to ensure that all the entries are returned.

Making a RAS Connection

  • Setting the connection parameters, such as the login name, telephone number, and domain name

  • Making the call using the RasDial function

The easiest way of setting the connection parameters is to call the RasGetEntryDialParams (Table 11.10) function to retrieve settings from the registry for the given phone book entry. You can then either use the default values or change them appropriately. The RASDIALPARAMS structure can be passed to RasDial to actually make the connection.

Table 11.10. RasGetEntryDialParams Retrieves default connection settings for a phone book entry
RasGetEntryDialParams
LPWSTR lpszPhoneBook Name of the phone book entry, such as "115200 Default"
LPRASDIALPARAMS lpRasDialParams Pointer to a RASDIALPARAMS structure to receive the connection settings
LPBOOL lpfPassword TRUE if the password was returned, FALSE if it needs to be supplied
DWORD Return Value 0 for success, or an error code defined in the header file raserror.h

The RASDIALPARAMS structure contains members for the essential parameters for making a connection. The most important ones are the following:

  • dwSize Size of the array in bytes. This should be initialized before calling RasGetEntryDialParams.

  • szEntryName The phone book entry name, e.g. "115200 Default."

  • szUserName Name used for logon.

  • szPassword Password used for logon. This will need to be set if lpfPassword is FALSE on return from RasGetEntryDialParams.

  • szDomain Domain used for authentication.

The RAS connection is made by calling the RasDial function ( Table 11.11). This function is passed a RASDIALPARAMS structure and returns a HRASCONN connection handle. The function makes the call asynchronously it returns before the connection has been made. Usually, an application will request that notifications through a WM_RASDIALEVENT message be sent to a designated window, as described in the next section.

Table 11.11. RasDial Makes a RAS connection
RasDial
LPRASDIALEXTENSIONS dialExtensions NULL for Windows CE.
LPTSTR phoneBookPath NULL for Windows CE. The Phone Book is in the registry.
LPRASDIALPARAMS rasDialParam RASDIALPARAMS structure returned through calling RasGetEntryDialParams.
DWORD NotifierType How to notify application of dialing progress. 0 for no notification, or 0xFFFFFFFF to indicate that the "notifier" parameter contains a window handle to receive a WM_RASDIALEVENT message.
LPVOID notifier Pointer to a hWnd to receive WM_RASDIALEVENT messages, or NULL for no notification.
LPHRASCONN pRasConn Pointer to a HRASCONN variable to receive a RAS connection handle.
DWORD Return Value 0 for success, or an error code defined in the header file raserror.h.

In Listing 11.7a, the RasGetEntryDialParams and RasDial functions are used to make a connection. Note that RasDial will fail with an error 602 if there is already a RAS connection. The function Listing11_7 is passed the window handle of the main application window, and this is used for notification.

Listing 11.7a Making a connection using RAS
 HRASCONN g_hRasConn = NULL; // NB: Assumes that a RAS connection (such as ActiveSync) // is not already open. If this is the case, RasDial // returns an error 602. void Listing11_7(HWND hWnd) {   RASDIALPARAMS rasDialParams;   DWORD dwRes;   BOOL bPassword;   rasDialParams.dwSize = sizeof(RASDIALPARAMS);   // change "SPL" to your RAS entry name   wcscpy(rasDialParams.szEntryName, _T("SPL"));   dwRes = RasGetEntryDialParams(NULL,       &rasDialParams, &bPassword);   if(dwRes != 0)   {     cout   _T("Error getting Dial Params:")            dwRes endl;   return;   }   if(!bPassword)     cout   _T("Password not returned") < endl;   dwRes = RasDial(NULL, NULL, &rasDialParams,       0 FFFFFFFF, hWnd, &g_hRasConn);   if(dwRes != 0)     cout   _T("Error dialing RAS: ")          dwRes   endl; } 

Monitoring a RAS Connection

An application can specify a window handle that will receive WM_RASDIALEVENT messages so that the progress of a connection can be monitored. The code in Listing 11.7b lists the function RasDialEvent that is called from the main window message procedure when a WM_RASDIALEVENT is called. The wParam value contains a value defined in the RASCONNSTATE enumeration. The code in Listing 11.7b shows some of the more important event numbers, such as connection and disconnection. An application should wait until a RASCS_Authenticated event has been received this indicates that the connection has been made, the user has been authenticated, and a network connection is present.

Listing 11.7b Responding to WM_RASDIALEVENT
 // This function is called from the message-processing // function for the windows with the hWnd handle passed // to RasDial. See code in Examples.cpp relating to the // WM_RASDIALEVENT message void RasDialEvent(HWND hWnd, WPARAM wParam, LPARAM lParam) {   if(wParam == RASCS_OpenPort)     cout   _T("Opening Port")   endl;   else if(wParam == RASCS_PortOpened)     cout   _T("Port Opened")   endl;   else if(wParam == RASCS_ConnectDevice)     cout   _T("Connecting to device")  endl;   else if(wParam == RASCS_DeviceConnected)     cout   _T("Connected")   endl;   else if(wParam == RASCS_Authenticated)     cout   _T("Authenticated")   endl;   else if(wParam == RASCS_DeviceConnected)     cout   _T("Connected")   endl;   else if(wParam == RASCS_AllDevicesConnected)     cout    _T("All devices connected")   endl;   else if(wParam == RASCS_Authenticate)     cout   _T("Waiting for authentication")   endl;   else if(wParam == RASCS_AuthAck)     cout   _T("Authentication acknowledged")   endl;   else if(wParam == RASCS_Disconnected)     cout   _T("Disconnected")   endl; } 

Dropping a RAS Connection

An application can drop a RAS connection through calling the RasHangUp function, and passing the HRASCONN returned from calling RasDial. A RAS connection is not owned by any one particular application, so the RAS connection is not automatically dropped when the application that made the connection terminates. Also, as described in the next section, an application can use a connection already made by another application.

Listing 11.8 Dropping a RAS connection
 void Listing11_8() {   if(g_hRasConn != NULL)   {     RasHangUp(g_hRasConn);     g_hRasConn = NULL;   }   else     cout   _T("Not connected")   endl; } 

Testing for an Existing RAS Connection

An application should test for an existing RAS connection before attempting tomake a new connection since Windows CE only supports a single connection at any one time. If a connection already exists, the application should test whether the connection is to the correct server for its requirements.

The RasEnumConnections (Table 11.12) function returns information about a RAS connection, if one exists. On the desktop, this function can return information about more than one connection, but on Windows CE it can only ever return information about a single connection, as this is the maximum number of supported connections.

In Listing 11.9 an array of RASCONN structures is passed into the function RasEnumConnections. The dwSize member of the first RASCONN structure must be initialized with the size of the array prior to calling the function. On return, the dwConnections variable contains the number of active RAS connections. The RASCONN structure contains the following members:

  • dwSize The size in bytes of the structure

  • hrasconn The RAS connection handle, as returned from RasDial

  • szEntryName The RAS phone book entry name

Table 11.12. RasEnumConnections
RasEnumConnections
LPRASCONN lprasconn Array of RASCONN structures into which information about the connections is returned.
LPDWORD lpcb Pointer to a DWORD that contains, on calling the function, the size of the array pointed to be lpcConnections. On return, it contains the number of bytes returned in lpcConnections.
LPDWORD lpcConnections Pointer to a DWORD that returns the number of RASCONN structures returned in lprasconn.
DWORD Return Value 0 for success, or an error code defined in the header file raserror.h.

If a connection exists, the RasGetConnectStatus function is used to return a RASCONNSTATUS structure for the hrasconn handle. The rasconnstate member contains the value from the RASCONNSTATE enumeration, which is the same enumeration used with the WM_RASDIALEVENT message in Listing 11.7b.

Listing 11.9 Testing for existing RAS connection
 void Listing11_9() {   RASCONN rsconn[10];   DWORD dwcb, dwConnections;   RASCONNSTATUS rasStatus;   dwcb = sizeof(rsconn);   rsconn[0].dwSize = sizeof(RASCONN);   if(RasEnumConnections(rsconn, &dwcb, &dwConnections)       == 0)   {     if(dwConnections == 0 ||         rsconn[0].hrasconn == NULL)     {       cout   _T("No current connections")              endl;       return;     }     // Find the current status of the RAS connection     // Note there will only ever be one connection     rasStatus.dwSize = sizeof(rasStatus);     if(RasGetConnectStatus(rsconn[0].hrasconn,         &rasStatus) != 0)     {       cout   _T("Could not get status")           endl;       return;     }     if(rasStatus.rasconnstate != RASCS_Connected)     {       cout   _T("Not connected")   endl;       return;     }     cout   _T("Current connection to: ")            rsconn[0].szEntryName;   }   else     cout   _T("Could not enumerate RAS connections")             endl; } 

< BACK  NEXT >


Windows CE 3. 0 Application Programming
Windows CE 3.0: Application Programming (Prentice Hall Series on Microsoft Technologies)
ISBN: 0130255920
EAN: 2147483647
Year: 2002
Pages: 181

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net