RasDial

When a RAS client application is ready to make a connection to a remote computer, it must call the RasDial function. RasDial is quite complex, offering many call parameters that are used for dialing, authenticating, and establishing a remote connection to a RAS server. RasDial is defined as

 DWORD RasDial( LPRASDIALEXTENSIONS lpRasDialExtensions, LPCTSTR lpszPhonebook, LPRASDIALPARAMS lpRasDialParams, DWORD dwNotifierType, LPVOID lpvNotifier, LPHRASCONN lphRasConn ); 

The lpRasDialExtensions parameter is an optional pointer to a RASDIALEXTENSIONS structure that causes your application to enable extended features for RasDial. On Windows 95, Windows 98, and Windows CE, this parameter is ignored and should be set to NULL. The RASDIALEXTENSIONS structure is defined as

 typedef struct tagRASDIALEXTENSIONS { DWORD dwSize; DWORD dwfOptions; HWND hwndParent; ULONG_PTR reserved; #if (WINVER >= 0x500) ULONG_PTR reserved1; RASEAPINFO RasEapInfo; #endif } RASDIALEXTENSIONS; 

Notice that this structure is sized differently during compilation based on the value of WINVER, as described earlier. The above fields are described as follows:

  • dwSize Should be set to the size (in bytes) of the RASDIALEXTENSIONS structure.
  • dwfOptions Allows you to set bit flags for using RasDial extensions. Table 16-1 describes these flags.

Table 16-1. RasDial bit flags of the extension features

Flag Description
RDEOPT_UsePrefixSuffix Makes RasDial use the prefix and suffix associated with the specified dialing device.
RDEOPT_PausedStates Allows RasDial to enter a paused operating state so that users can retry logons, change passwords, and set callback numbers.
RDEOPT_IgnoreModemSpeaker Makes RasDial ignore the modem speaker settings in the RAS phonebook.
RDEOPT_SetModemSpeaker Turns on the modem speaker if RDEOPT_IgnoreModemSpeaker is set.
RDEOPT_IgnoreSoftwareCompression Makes RasDial ignore software compression settings.
RDEOPT_SetSoftwareCompression Turns on software compression if RDEOPT_IgnoreSoftwareCompression is set.
RDEOPT_PauseOnScript Used internally by RasDialDlg. You should not set this flag.

  • hwndParent Is not used and should be set to NULL.
  • reserved Is not used and should be set to 0.
  • reserved1 Is reserved for future use on Windows 2000 and should be set to 0.
  • RasEapInfo On Windows 2000, allows you to specify Extensible Authentication Protocol (EAP) information. The details of EAP are beyond the scope of this book.

The lpszPhonebook parameter of RasDial identifies the path to a phonebook file on Windows 2000 and Windows NT. This parameter must be NULL on Windows 95, Windows 98, and Windows CE because the phonebook is stored in the system Registry. A phonebook is a collection of RAS dialing properties that define how to set up a RAS connection. However, you are not required to use a phonebook to make a RAS connection. RasDial features enough dialing parameters to allow you to set up a basic connection. We will discuss the details of a RAS phonebook later in this chapter.

The RASDIALPARAMS structure pointer lpRasDialParams defines dialing and user authentication parameters that the RasDial function uses to establish a remote connection. It's defined as

 typedef struct _RASDIALPARAMS { DWORD dwSize; TCHAR szEntryName[RAS_MaxEntryName + 1]; TCHAR szPhoneNumber[RAS_MaxPhoneNumber + 1]; TCHAR szCallbackNumber[RAS_MaxCallbackNumber + 1]; TCHAR szUserName[UNLEN + 1]; TCHAR szPassword[PWLEN + 1]; TCHAR szDomain[DNLEN + 1] ; #if (WINVER >= 0x401) DWORD dwSubEntry; DWORD dwCallbackId; #endif } RASDIALPARAMS; 

The fields of RASDIALPARAMS are described as follows:

  • dwSize Should be set to the size (in bytes) of a RASDIALPARAMS structure. This allows RAS to internally determine what WINVER version you compiled with.
  • szEntryName A string that allows you to identify a phonebook entry contained in the phonebook file listed in the lpszPhonebook parameter of RasDial. This is an important parameter because phonebook entries enable you to fine-tune RAS connection properties such as selecting a modem or selecting a framing protocol. However, specifying a phonebook entry to use RasDial is optional. If this field is an empty string (""), RasDial will select the first available modem installed on your system and will rely on the next parameter, szPhoneNumber, to dial a connection.
  • szPhoneNumber A string representing a phone number that overrides the number contained in the phonebook entry specified in the szEntryName field.
  • szCallbackNumber Allows you to specify a phone number the RAS server can call you back on. If the RAS server permits you to have a callback number, the server will terminate your original connection and call back your client using the callback number you specified. This is a nice feature because it lets your server know where a user is connecting from.
  • szUserName A string that identifies a logon name used to authenticate a user on a RAS server.
  • szPassword A string that identifies the password used to authenticate a user on a RAS server.
  • szDomain Identifies the Windows 2000 or Windows NT domain where the user account is located.
  • dwSubEntry Optionally allows you to specify the initial phonebook subentry to dial for a RAS multilink connection. (We'll describe RAS phonebook subentries and multilink connections in "Multilink Phonebook Subentries.")
  • dwCallbackId Allows you to pass an application-defined value to a RasDialFunc2 callback function (which we'll also describe later). If you're not using a RasDialFunc2 callback function, this field is not used.

The next RasDial parameters, dwNotifierType and lpvNotifier, determine the operating mode of RasDial (whether it can be called synchronously or asynchronously). The final RasDial parameter, lphRasConn, is a pointer to a RAS connection handle of type HRASCONN. Before you call RasDial, you must set this parameter to NULL. If RasDial completes successfully, a reference handle to the RAS connection is returned.

Let's begin by demonstrating how to call RasDial. As we mentioned, RasDial can execute in two operating modes: synchronous and asynchronous. In synchronous mode, RasDial blocks until it either completes a connection or fails to do so. In asynchronous mode, RasDial completes a connection immediately, allowing your application to perform other actions while connecting.

Synchronous Mode

If the lpvNotifier parameter of RasDial is set to NULL, RasDial will operate synchronously. When the lpvNotifier parameter is NULL, the dwNotifierType parameter is ignored. Calling RasDial synchronously is the easiest way to use this function; however, you won't be able to monitor the connection as you can in asynchronous mode, which we will describe in a moment. Figure 16-1 demonstrates how to call RasDial synchronously. Notice that this code listing does not specify a phonebook or a phonebook entry. Instead, it demonstrates how simple forming a RAS connection is.

Figure 16-1. Calling RasDial synchronously

 RASDIALPARAMS RasDialParams; HRASCONN hRasConn; DWORD Ret; // Always set the size of the RASDIALPARAMS structure RasDialParams.dwSize = sizeof(RASDIALPARAMS); hRasConn = NULL; // Setting this field to an empty string will allow // RasDial to use default dialing properties lstrcpy(RasDialParams.szEntryName, ""); lstrcpy(RasDialParams.szPhoneNumber, "867-5309"); lstrcpy(RasDialParams.szUserName, "jenny"); lstrcpy(RasDialParams.szPassword, "mypassword"); lstrcpy(RasDialParams.szDomain, "mydomain"); // Call RasDial synchronously (the fifth parameter // is set to NULL) Ret = RasDial(NULL, NULL, &RasDialParams, 0, NULL, &hRasConn); if (Ret != 0) { printf("RasDial failed: Error = %d\n", Ret); } 

Asynchronous Mode

Calling RasDial asynchronously is a lot more complicated than calling this function in synchronous mode. If the lpvNotifier parameter of RasDial is not set to NULL, RasDial will operate asynchronously—meaning the call returns immediately but the connection proceeds. Calling RasDial asynchronously is the preferred method for making a RAS connection because you can monitor the connection's progress. The lpvNotifier parameter can be either a pointer to a function that is called when a connection activity occurs in RasDial or a window handle that receives progress notification via Windows messages. The dwNotifierType parameter of RasDial determines the type of function or window handle that is passed into lpvNotifier. Table 16-2 describes the values that you can specify in dwNotifierType.

Table 16-2. RasDial asynchronous notification methods

Notifier Type Meaning
0 The lpvNotifier parameter causes RasDial to use the RasDialFunc function pointer to manage connection events.
1 The lpvNotifier parameter causes RasDial to use the RasDialFunc1 function pointer to manage connection events.
2 The lpvNotifier parameter causes RasDial to use the RasDialFunc2 function pointer to manage connection events.
0xFFFFFFFF The lpvNotifier parameter makes RasDial send a window message during connection events.

Table 16-2 shows the three function prototypes that you can supply to RasDial in the lpvNotifier parameter for receiving callback notification of connection events: RasDialFunc, RasDialFunc1, and RasDialFunc2. The first one, RasDialFunc, is prototyped as

 VOID WINAPI RasDialFunc( UINT unMsg, RASCONNSTATE rasconnstate, DWORD dwError ); 

The unMsg parameter receives the type of event that has occurred. Currently this event can be only WM_RASDIALEVENT, which means that this parameter is not useful. The rasconnstate parameter receives the connection activity that the RasDial function is about to start. Table 16-3 defines the possible connection activities. The dwError parameter receives a RAS error code if one of the connection activities experiences failure.

Table 16-3 shows three operating states associated with connection activities in an asynchronous RasDial call: running, paused, and terminal. The running state indicates that the RasDial call is still in progress, and each running-state activity offers progress status information.

The paused state indicates that RasDial needs more information to establish the connection. By default, the paused state is disabled. You can enable this notification process by setting the RDEOPT_PausedStates flag in the RASDIALEXTENSIONS structure that we mentioned earlier. When a paused state activity occurs, it indicates one of the conditions listed below.

  • The user needs to supply new logon credentials because the authentication failed.
  • The user needs to provide a new password because his or her password has expired.
  • The user needs to provide a callback number.

Table 16-3. RAS connection activities

Activity State Description
RASCS_OpenPort Running A communication port is about to be opened.
RASCS_PortOpened Running The communication port is open.
RASCS_ConnectDevice Running A device is about to be connected.
RASCS_ DeviceConnected Running The device has successfully connected.
RASCS_ AllDevicesConnected Running A physical link has been established.
RASCS_ Authenticate Running The RAS authentication process has started.
RASCS_ AuthNotify Running An authentication event has occurred.
RASCS_ AuthRetry Running The client has requested another authentication attempt.
RASCS_ AuthCallback Running The server has requested a callback number.
RASCS_ AuthChangePassword Running The client has requested to change the password on the RAS account.
RASCS_ AuthProject Running The protocol projection is starting.
RASCS_ AuthLinkSpeed Running The link speed is being calculated.
RASCS_ AuthAck Running An authentication request is being acknowledged.
RASCS_ ReAuthenticate Running The authentication process after a callback is starting.
RASCS_ Authenticated Running The client has successfully completed the authentication.
RASCS_ PrepareForCallback Running The line is about to disconnect to prepare for a callback.
RASCS_ WaitForModemReset Running The client is waiting for the modem to reset before preparing for a callback.
RASCS_ WaitForCallback Running The client is waiting for an incoming call from the server.
RASCS_ Projected Running The protocol projection is complete.
RASCS_ StartAuthentication Running User authentication is being started or retried. (This applies to Windows 95 and Windows 98 only.)
RASCS_ CallbackComplete Running The client has been called back. (This applies to Windows 95 and Windows 98 only.)
RASCS_ LogonNetwork Running The client is logging on to a remote network. (This applies to Windows 95 and Windows 98 only.)
RASCS_ SubEntryConnected Running A subentry of a multilink phonebook entry has connected. The dwSubEntry parameter of RasDialFunc2 will contain an index of the subentry connected.
RASCS_ SubEntryDisconnected Running A subentry of a multilink phonebook entry has disconnected. The dwSubEntry parameter of RasDialFunc2 will contain an index of the subentry disconnected.
RASCS_ RetryAuthentication Paused RasDial is awaiting new user credentials.
RASCS_ CallbackSetByCaller Paused RasDial is awaiting a callback number from the client.
RASCS_ PasswordExpired Paused RasDial expects the user to supply a new password.
RASCS_InvokeEapUI Paused On Windows 2000, RasDial is awaiting a custom user interface to obtain EAP information.
RASCS_ Connected Terminal The RAS connection succeeded and is active.
RASCS_ Disconnected Terminal The RAS connection failed or is inactive.

These activities pertain to information in the RASDIALPARAMS structure described earlier in this chapter. When a paused state activity occurs, RasDial will notify your callback function (or window procedure). If the paused state is disabled, RAS will send an error to your notification function and RasDial will fail. If enabled, the RasDial function will be in a paused state that allows your application to supply the necessary information through a RASDIALPARAMS structure. When RasDial is paused, you can resume by calling it again with the original call's connection handle (lphRasConn) and notification function (lpvNotifier), or you can simply end the paused operation by calling RasHangUp (described later in this chapter). If you resume the paused connection, you will have to supply the necessary user input via the RASDIALPARAMS structure passed to the resumed RasDial call.

NOTE
Do not resume the paused state by calling RasDial directly from a notification handler function such as RasDialFunc. RasDial is not designed to handle this situation, so you should resume RasDial directly from your application thread.

The final state—terminal—indicates that the RasDial connection has either succeeded or failed. It can also indicate that the RasHangUp function closed the connection.

Now that you have a basic understanding of how you can monitor the connection of an asynchronous RasDial call, we'll demonstrate how to set up a simple program that calls RasDial asynchronously. Figure 16-2 shows this procedure. You'll also find an asynchronous RasDial example on the companion CD.

Figure 16-2 Calling RasDial asynchronously

 void main(void) { DWORD Ret; RASDIALPARAMS RasDialParams; HRASCONN hRasConn; // Fill in the RASDIALPARAMS structure with call parameters // as was done in the synchronous example ... if ((Ret = RasDial(NULL, NULL, &RasDialParams, 0, &RasDialFunc, &hRasConn)) != 0) { printf("RasDial failed with error %d\n", Ret); return; } // Perform other tasks while RasDial is processing ... } // Callback function RasDialFunc() void WINAPI RasDialFunc(UINT unMsg, RASCONNSTATE rasconnstate, DWORD dwError) { char szRasString[256]; // Buffer for error string if (dwError) { RasGetErrorString((UINT)dwError, szRasString, 256); printf("Error: %d - %s\n",dwError, szRasString); return; } // Map each of the states of RasDial, and display on the // screen the next state that RasDial is entering switch (rasconnstate) { case RASCS_ConnectDevice: printf ("Connecting device...\n"); break; case RASCS_DeviceConnected: printf ("Device connected.\n"); break; // Add other connection activities here ... default: printf ("Unmonitored RAS activity.\n"); break; } } 

Table 16-2 also mentioned two other callback notification functions: RasDialFunc1 and RasDialFunc2. These functions are prototyped as

 VOID WINAPI RasDialFunc1( HRASCONN hrasconn, UINT unMsg, RASCONNSTATE rascs, DWORD dwError, DWORD dwExtendedError ); DWORD WINAPI RasDialFunc2( DWORD dwCallbackId, DWORD dwSubEntry, HRASCONN hrasconn, UINT unMsg, RASCONNSTATE rascs, DWORD dwError, DWORD dwExtendedError ); 

The RasDialFunc1 function is just like the RasDialFunc function discussed earlier except that it features two additional parameters: hrasconn and dwExtendedError. The hrasconn parameter is the handle to the connection that RasDial returned. The dwExtendedError parameter allows you to retrieve extended error information when the following types of errors occur in the dwError parameter during the connection.

  • ERROR_SERVER_NOT_RESPONDING dwExtendedError receives a NetBIOS-specific error code that occurred.
  • ERROR_NETBIOS_ERROR dwExtendedError receives a NetBIOS-specific error code that occurred.
  • ERROR_AUTH_INTERNAL dwExtendedError receives an internal diagnostic error code. These error codes are not documented.
  • ERROR_CANNOT_GET_LANA dwExtendedError receives a routing RAS-specific error code.

The RasDialFunc2 function is just like RasDialFunc1 except that it features two additional parameters: dwCallbackId and dwSubEntry. The dwCallbackId parameter contains an application-defined value that was originally set in the dwCallbackId field of a RASDIALPARAMS structure passed to the RasDial call we described earlier. The dwSubEntry parameter receives the subentry phonebook index that caused the callback to the RasDialFunc2 function.

Status Notification

RAS features a stand-alone function named RasConnectionNotification that allows your application to determine when an asynchronous RAS connection has been created or terminated. RasConnectionNotification is defined as

 DWORD RasConnectionNotification( HRASCONN hrasconn, HANDLE hEvent, DWORD dwFlags ); 

The hrasconn parameter is a connection handle returned from RasDial. The hEvent parameter is an event handle that your application creates using the CreateEvent function. The dwFlags parameter can be set to a combination of the following connection activity flags:

  • RASCN_Connection Notifies you that a RAS connection has been created. If the hrasconn parameter is set to INVALID_HANDLE_VALUE, the event is signaled when any RAS connection occurs.
  • RASCN_Disconnection Notifies you that a RAS connection has been terminated. If the hrasconn parameter is set to INVALID_HANDLE_VALUE, the event is signaled when any connection ends.
  • RASCN_BandwidthAdded On a multilink connection, the event is signaled when a subentry connects.
  • RASCN_BandwidthRemoved On a multilink connection, the event is signaled when a subentry disconnects.

Note that these flags function in the same way as the connection activity flags described in Table 16-3. If any of these activities occur during your connection, your event will become signaled. Your application should use Win32 wait functions, such as WaitForSingleObject, to determine when the object becomes signaled.

Closing a Connection

Closing a connection established by RasDial is simple. All you have to do is call RasHangUp, which is defined as

 DWORD RasHangUp( HRASCONN hrasconn ); 

The hrasconn parameter is a handle returned from RasDial. Although this function is easy to use, you have to consider how connections are managed internally in RAS. A connection uses a modem port, and it takes time for the port to reset internally when a connection shuts down. Therefore, you should wait until the port connection closes completely. To do this, you can call RasGetConnectionStatus to determine when your connection is reset. RasGetConnectionStatus is defined as

 DWORD RasGetConnectStatus( HRASCONN hrasconn, LPRASCONNSTATUS lprasconnstatus ); 

The hrasconn parameter is a handle returned from RasDial. The lprasconnstatus parameter is a RASCONNSTATUS structure that receives the current connection status. A RASCONNSTATUS structure is defined as

 typedef struct _RASCONNSTATUS { DWORD dwSize; RASCONNSTATE rasconnstate; DWORD dwError; TCHAR szDeviceType[RAS_MaxDeviceType + 1]; TCHAR szDeviceName[RAS_MaxDeviceName + 1]; } RASCONNSTATUS; 

These fields are defined as follows:

  • dwSize Should be set to the size (in bytes) of RASCONNSTATUS
  • rasconnstate Receives one of the connection activities defined in Table 16-3
  • dwError Receives a specific RAS error code if RasGetConnectStatus does not return 0
  • szDeviceType Receives a string representing the type of device used on the connection
  • szDeviceName Receives the name of the current device

We recommend that you check the state of your connection until you receive the RASCS_ Disconnected activity status. Obviously, you might have to call RasGetConnectionStatus several times until the connection is reset. Once the connection is reset, you can exit your application or make another connection.



Network Programming for Microsoft Windows
Linux Server Hacks, Volume Two: Tips & Tools for Connecting, Monitoring, and Troubleshooting
ISBN: 735615799
EAN: 2147483647
Year: 1998
Pages: 159

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