Establishing a RAS Connection

Now that you know how to create new entries in the RAS phonebook, as well as enumerate RAS devices, let's examine how you can actually establish a connection to a remote server.

RAS currently supports two different feedback mechanisms when dialing and connecting to a server. Dialing a host in synchronous mode will cause the dial function not to return until it has completed its connection (or an error occurs) with the server. Asynchronous mode will return immediately to your control, and enable you to get connection status information while the dialing operation is occurring, via a system notification message.

To dial and connect with a remote server, you use the RasDial() function, which has been defined as follows:

 DWORD RasDial(LPRASDIALEXTENSIONS dialExtensions, LPTSTR   phoneBookPath, LPRASDIALPARAMS rasDialParam, DWORD NotifierType, LPVOID notifier, LPHRASCONN pRasConn); 

The first two parameters should be set to NULL, followed by the rasDialParam parameter, which should point to a RASDIALPARAMS structure. This is used to identify any user authentication parameters for the connection. Remember that in order to properly use RasDial(), you must set the dwSize member of RASDIALPARAMS to the size of the RASDIALPARAMS structure, and the szPhoneNumber and szCallbackNumber members should be set to NULL.

If you want to use RasDial() in synchronous mode, then the next two parameters, NotifierType and notifier, should both be set to NULL.

Using RasDial() in asynchronous mode requires you to set the parameters a bit differently. The NotifierType parameter should be set to 0xFFFFFFFF, which specifies that the notification message WM_RASDIALEVENT should be sent to a specific window for each RasDial() event. The notifier parameter in this instance should be set to a pointer to the window handle that you want to receive the notification message.

In either case, the last parameter, pRasConn, is a pointer to an HRASCONN connection handle. The variable should be set to NULL prior to calling RasDial(), and will contain the handle to the RAS connection once RasDial() has completed.

If the function is successful, you will be returned a 0 value; otherwise, a RAS error code will be returned to you. Remember that if the function returns a non-null value in pRasConn, you must call RasHangUp() (discussed in the section "Closing a Connection") to correctly terminate the connection and free the resources that RAS is using.

One final note: RasDial() does not display any type of logon dialog box to the user. If you need a user to enter any logon information, then you must manually create the dialog box and get the appropriate information yourself.

Synchronous Mode

As you might have already guessed, using the RasDial() function in synchronous mode is the easiest way to establish a remote connection. However, because the function does not return until a connection has been completed (or an error has occurred), you will not receive any notification messages about the connection operations while it is in progress. In order to get further information about the connection once it has been established, you can use the RasGetConnectStatus() function, which is described in the section "Connection Management."

Because most applications typically want to inform the user of the pending connection's progress, using RasDial() in asynchronous mode is more common.

The following example shows what is required to make a synchronous connection using RasDial():

 // Dial a RAS entry in synchronous mode HRASCONN hRasConn = NULL; RASDIALPARAMS rasDialParams; // Setup the RASDIALPARAMS structure for the entry we want // to dial memset(&rasDialParams, 0, sizeof(RASDIALPARAMS)); rasDialParams.dwSize = sizeof(RASDIALPARAMS); wsprintf(rasDialParams.szEntryName, TEXT("Work")); wsprintf(rasDialParams.szUserName, TEXT("BobbieZ")); wsprintf(rasDialParams.szPassword, TEXT("SomePassword")); wsprintf(rasDialParams.szDomain, TEXT("SomeDomain")); if(RasDial(NULL, NULL, &rasDialParams, 0, NULL, &hRasConn)    != 0) {    MessageBox(NULL, TEXT("Could not connect w/ server"),    TEXT("RAS Dial Error"), MB_ICONERROR|MB_OK);    return FALSE; } // Do our communications here ... // Remember to hang up the connection and free the RAS // device if(hRasConn != NULL)    RasHangUp(hRasConn); 

Asynchronous Mode

More often than not, you will want to use the asynchronous mode of the RasDial() function when establishing a connection with a server. This enables you to obtain dynamic feedback on the connection status, which you can display in your application to the user.

To connect with a server in asynchronous mode, you need to call the RasDial() function with the NotifierType parameter set to 0xFFFFFFFF. The notifier parameter should specify a pointer to a window handle that will receive a notification message when any state changes in the connection operation. Once called, RasDial() will return to you immediately, and messages will start being sent to the window that you have specified.

Notification messages are sent to you in the WM_RASDIALEVENT message (which is defined as 0xCCCD in ras.h). When you receive the window's message, the wParam parameter will indicate the current connection state that the RAS dialer is about to enter, and the lParam parameter will contain any errors that have occurred. If you are returned an error state, then you should call RasHangUp() to terminate the call and notify the user.

Table 6.3 describes the possible notification constants that you can receive during a RAS dialing event.

Table 6.3. RAS Dialing Notification States

Value

Description

RASCS_OpenPort

Port is about to be opened.

RASCS_PortOpened

Port has been opened successfully.

RASCS_ConnectDevice

A device is about to be connected. Use the RasGetConnectStatus() function to find out more information about the device.

RASCS_DeviceConnected

The device has successfully connected. Use the RasGetConnectStatus() function to find out more information about the device.

RASCS_AllDevicesConnected

The physical link has been established.

RASCS_Authenticate

The authentication process is starting.

RASCS_AuthNotify

An authentication event has occurred. If the lParam value is nonzero, authentication has failed.

RASCS_AuthRetry

The client has requested another attempt at authentication.

RASCS_AuthChangePassword

The client has requested to change the password.

RASCS_AuthProject

The projection phase is starting.

RASCS_AuthLinkSpeed

The link speed is being calculated.

RASCS_AuthAck

The authentication request is being acknowledged.

RASCS_Authenticated

The client has completed authentication successfully.

RASCS_Projected

RAS projection information is available. Use the RasGetProjectionInfo() function to find out more information about the current RAS projection.

RASCS_RetryAuthentication

RasDial() is requesting new user authentication credentials.

RASCS_PasswordExpired

The password has expired.

RASCS_Connected

The connection has been established and is active.

RASCS_Disconnected

The connection has failed or is inactive.

You will stop receiving notification messages once the connection is established (RASCS_Connected), if the connection fails, or if RasHangUp() has been called on the active connection.

The following example makes a call using RasDial() in asynchronous mode:

 // Function to dial a RAS entry in asynchronous mode void Dial(HWND hWnd) {    HRASCONN hRasConn = NULL;    RASDIALPARAMS rasDialParams;    // Set up the RASDIALPARAMS structure for the entry we    // want to dial    memset(&rasDialParams, 0, sizeof(RASDIALPARAMS));    rasDialParams.dwSize = sizeof(RASDIALPARAMS);    wsprintf(rasDialParams.szEntryName, TEXT("Work"));    wsprintf(rasDialParams.szUserName, TEXT("RandyZ"));    wsprintf(rasDialParams.szPassword, TEXT("SomePassword"));    wsprintf(rasDialParams.szDomain, TEXT("SomeDomain"));    if(RasDial(NULL, NULL, &rasDialParams, 0xFFFFFFFF, &hWnd,          &hRasConn)!= 0) {       MessageBox(NULL, TEXT("Could not connect w/ server"),          TEXT("RAS Dial Error"), MB_ICONERROR|MB_OK);       return FALSE;    }    // Continue to process user messages here, since RasDial    // will return immediately } // Inside the window's message loop (specified by hWnd), // process RAS notification messages LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM    wParam, LPARAM lParam) {    switch(iMessage) {       case WM_RASDIALEVENT: {          DWORD dwRasNotificationEvent = (DWORD)wParam;          DWORD dwRasError = (DWORD)lParam;          // First, let's check to see if any errors have          // occurred          if(dwRasError) {            TCHAR tchRasError[128] = TEXT("\0");            wsprintf(tchRasError, TEXT("An error has               occurred! Error #%d"), dwRasError);            MessageBox(hWnd, tchRasError, TEXT("RAS Dial               Error"), MB_ICONERROR|MB_OK);            return 0;         }        // Check the notification state that we were sent        TCHAR tchRasNotificationMsg[128] = TEXT("\0");        switch(dwRasNotificationEvent) {           case RASCS_OpenPort:              wsprintf(tchRasNotificationMsg, TEXT("Opening                 RAS Port"));           break;           case RASCS_Authenticate:              wsprintf(tchRasNotificationMsg,                 TEXT("Starting RAS Authentication"));           break;           case RASCS_Projected:              wsprintf(tchRasNotificationMsg, TEXT("Remote                 network projection established"));           break;           case RASCS_Connected:              wsprintf(tchRasNotificationMsg,                 TEXT("Connection Established"));           break;           case RASCS_Disconnected:              wsprintf(tchRasNotificationMsg,                 TEXT("Connection Terminated"));           break;         }         MessageBox(hWnd, tchRasNotificationMsg, TEXT("RAS            Event"), MB_ICONINFORMATION|MB_OK);     }     break;     default:        return (DefWindowProc(hWnd, iMessage, wParam,           lParam));   }   return (0L); } 

Closing a Connection

Once you have established a connection using RasDial(), you can use the RasHangUp() function to disconnect and close an active connection handle. The function is defined as follows:

 DWORD RasHangUp(HRASCONN hSession); 

The only parameter that RasHangUp() needs is hSession, which should point to the RAS connection handle that was returned from the earlier call to RasDial(). If successful, you will be returned a zero; otherwise, you will get a standard RAS error code. Remember that once you have terminated a connection, the hSession handle is no longer valid and cannot be used for further RAS function calls.

TIP:

Although you can call RasHangUp() at any point, you should ensure that your connection has completely disconnected before attempting to use the same dial-up device again. To do so, you can use the RasGetConnectStatus() function to verify that you have received the RASCD_Disconnected status from the device.




Pocket PC Network Programming
Pocket PC Network Programming
ISBN: 0321133528
EAN: 2147483647
Year: 2005
Pages: 90

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