< RAS Client, Functions & Modes | RAS Main | VPN & RAS Example >
What do we have in this chapter 12 part 2?
Deleting Phonebook Entries
|
Phonebook
A RAS phonebook is nothing more than a collection of RASENTRY structures (or phonebook entries) that contain phone numbers, data rates, user authentication information, VPN strategies, and other connection information. On Windows 95, Windows 98, Windows Me, and Windows CE systems, the phonebook is stored in the system Registry. On Windows NT systems, the phonebook is stored in files that typically have the file extension .PBK. A RASENTRY structure is defined as:
typedef struct tagRASENTRY { DWORD dwSize; DWORD dwfOptions; DWORD dwCountryID; DWORD dwCountryCode; TCHAR szAreaCode[RAS_MaxAreaCode + 1]; TCHAR szLocalPhoneNumber[RAS_MaxPhoneNumber + 1]; DWORD dwAlternateOffset; RASIPADDR ipaddr; RASIPADDR ipaddrDns; RASIPADDR ipaddrDnsAlt; RASIPADDR ipaddrWins; RASIPADDR ipaddrWinsAlt; DWORD dwFrameSize; DWORD dwfNetProtocols; DWORD dwFramingProtocol; TCHAR szScript[MAX_PATH]; TCHAR szAutodialDll[MAX_PATH]; TCHAR szAutodialFunc[MAX_PATH]; TCHAR szDeviceType[RAS_MaxDeviceType + 1]; TCHAR szDeviceName[RAS_MaxDeviceName + 1]; TCHAR szX25PadType[RAS_MaxPadType + 1]; TCHAR szX25Address[RAS_MaxX25Address + 1]; TCHAR szX25Facilities[RAS_MaxFacilities + 1]; TCHAR szX25UserData[RAS_MaxUserData + 1]; DWORD dwChannels; DWORD dwReserved1; DWORD dwReserved2; |
#if (WINVER >= 0x401)
DWORD dwSubEntries;
DWORD dwDialMode;
DWORD dwDialExtraPercent;
DWORD dwDialExtraSampleSeconds;
DWORD dwHangUpExtraPercent;
DWORD dwHangUpExtraSampleSeconds;
DWORD dwIdleDisconnectSeconds;
#endif
#if (WINVER >= 0x500)
DWORD dwType;
DWORD dwEncryptionType;
DWORD dwCustomAuthKey;
GUID guidId;
TCHAR szCustomDialDll[MAX_PATH];
DWORD dwVpnStrategy;
#endif
#if (WINVER >= 0x501)
DWORD dwfOptions2;
DWORD dwfOptions3;
WCHAR szDnsSuffix[RAS_MaxDnsSuffix];
DWORD dwTcpWindowSize;
WCHAR szPrerequisitePbk[MAX_PATH];
WCHAR szPrerequisiteEntry[RAS_MaxEntryName + 1];
DWORD dwRedialCount;
DWORD dwRedialPause;
#endif
} RASENTRY;
As you can see, many fields make up this structure and we will not describe them here. For a complete description of all the fields, consult the Platform SDK.
When you call any RAS API that takes a phonebook file as a parameter (lpszPhonebook), you can identify the path to a phonebook file. As we mentioned earlier, this parameter must be NULL on Windows 95, Windows 98, Windows Me, and Windows CE systems because phonebook entries are stored in the system Registry. On Windows NT systems, this can be a path to a phonebook file. Typically, this phonebook file will have the extension .PBK. Also, the system default phonebook on Windows NT systems is located under %SystemRoot%\System32\Ras\Rasphone.pbk. If you specify NULL as the phonebook, you will use the system default phonebook file. For Windows XP Pro you can find it in the C:\Documents and Settings\All Users\Application Data\Microsoft\Network\Connections\Pbk folder.
RAS provides four functions that allow you to programmatically manage phonebook RASENTRY structures: RasSetEntryProperties(), RasGetEntryProperties(), RasRenameEntry(), and RasDeleteEntry(). You can use the RasSetEntryProperties() function to create a new entry or modify an existing entry. This function is defined as:
DWORD RasSetEntryProperties(
LPCTSTR lpszPhonebook,
LPCTSTR lpszEntry,
LPRASENTRY lpRasEntry,
DWORD dwEntryInfoSize,
LPBYTE lpbDeviceInfo,
DWORD dwDeviceInfoSize
);
The lpszPhonebook parameter is a pointer to a phonebook file name. The lpszEntry parameter is a pointer to a string used to identify an existing or new entry. If a RASENTRY structure exists with this name, the properties are modified; otherwise, a new entry is created in the phonebook. The lpRasEntry parameter is a pointer to a RASENTRY structure. You can place a list of null-terminated strings after the RASENTRY structure defining alternate phone numbers. The last string is terminated by two consecutive null characters. The dwEntryInfoSize parameter is the size (in bytes) of the structure in the lpRasEntry parameter. The lpbDeviceInfo parameter is a pointer to a buffer that contains TAPI device configuration information. On Windows 2000 and Windows NT, this parameter is not used and should be set to NULL. The final parameter, dwDeviceInfoSize, represents the size (in bytes) of the lpbDeviceInfo buffer.
The RasGetEntryProperties() function, defined below, can be used to retrieve the properties of an existing phonebook entry or the default values for a new phonebook entry.
DWORD RasGetEntryProperties(
LPCTSTR lpszPhonebook,
LPCTSTR lpszEntry,
LPRASENTRY lpRasEntry,
LPDWORD lpdwEntryInfoSize,
LPBYTE lpbDeviceInfo,
LPDWORD lpdwDeviceInfoSize
);
The lpszPhonebook parameter is a pointer to the name of a phonebook file. The lpszEntry parameter is a pointer to a string identifying an existing phonebook entry. If you set this parameter to NULL, the lpRasEntry and lpbDeviceInfo parameters will receive default values of a phonebook entry. Retrieving the default values is quite useful: when you need to create a new RAS phonebook entry, you can populate the lpRasEntry and lpbDeviceInfo fields with correct information about your system before you call the RasSetEntryProperties() function.
The lpRasEntry parameter is a pointer to a buffer that your application supplies to receive a RASENTRY structure. As we described in our discussion of the RasSetEntryProperties() function, this structure can be followed by an array of null-terminated strings identifying alternate phone numbers for the requested phonebook entry. Therefore, the size of your receiving buffer should be larger than a RASENTRY structure. If you pass a NULL pointer, the lpdwEntryInfoSize parameter will receive the total number of bytes needed to store all the elements of a RASENTRY structure plus any alternate phone numbers. The lpdwEntryInfoSize parameter is a pointer to a DWORD containing the number of bytes that are in the receiving buffer your application supplies to the lpRasEntry parameter. When this function completes, it will update lpdwEntryInfoSize to the number of bytes actually received in lpRasEntry. We highly recommend calling this function with lpRasEntry set to NULL and lpdwEntryInfoSize set to 0 to obtain buffer sizing information. Once you have the appropriate size, you can call this function again and retrieve all the information without error.
The lpbDeviceInfo parameter is a pointer to an application-supplied buffer that receives TAPI device specific information for this phonebook entry. If this parameter is set to NULL, the lpdwDeviceInfoSize parameter will receive the number of bytes needed to retrieve this information. If you are using Windows 2000, Windows NT, or Windows XP, lpbDeviceInfo should be set to NULL. The final parameter, lpdwDeviceInfoSize, is a pointer to a DWORD that should be set to the number of bytes contained in the buffer supplied to lpbDeviceInfo. When RasGetEntryProperties() returns, lpdwDeviceInfoSize will return the number of bytes that are returned in the lpbDeviceInfo buffer.
The following code sample demonstrates how an application should use RasGetEntryProperties() and RasSetEntryProperties() to create a new phonebook entry:
#include <windows.h>
// Link to rasapi32.lib
#include <ras.h>
#include <raserror.h>
#include <stdio.h>
void main(void)
{
DWORD EntryInfoSize = 0;
DWORD DeviceInfoSize = 0;
DWORD Ret;
LPRASENTRY lpRasEntry;
LPBYTE lpDeviceInfo;
// Get buffer sizing information for a default phonebook entry
if ((Ret = RasGetEntryProperties(NULL, "", NULL, &EntryInfoSize, NULL, &DeviceInfoSize)) != 0)
{
if (Ret != ERROR_BUFFER_TOO_SMALL)
{
printf("RasGetEntryProperties sizing failed with error %d\n", Ret);
return;
}
}
lpRasEntry = (LPRASENTRY) GlobalAlloc(GPTR, EntryInfoSize);
if (DeviceInfoSize == 0)
lpDeviceInfo = NULL;
else
lpDeviceInfo = (LPBYTE) GlobalAlloc(GPTR, DeviceInfoSize);
// Get default phonebook entry
lpRasEntry->dwSize = sizeof(RASENTRY);
if ((Ret = RasGetEntryProperties(NULL, "", lpRasEntry, &EntryInfoSize, lpDeviceInfo, &DeviceInfoSize)) != 0)
{
printf("RasGetEntryProperties failed with error %d\n", Ret);
return;
}
// Validate new phonebook name "Testentry"
if ((Ret = RasValidateEntryName(NULL, "Testentry")) != ERROR_SUCCESS)
{
printf("RasValidateEntryName failed with error %d\n", Ret);
return;
}
// Install a new phonebook entry, "Testentry", using default properties
if ((Ret = RasSetEntryProperties(NULL, "Testentry", lpRasEntry, EntryInfoSize, lpDeviceInfo, DeviceInfoSize)) != 0)
{
printf("RasSetEntryProperties failed with error %d\n", Ret);
return;
}
}
Deleting Phonebook Entries
Deleting phonebook entries is easy. To do so, you simply call the RasDeleteEntry() function, which is defined as:
DWORD RasDeleteEntry(LPCTSTR lpszPhonebook, LPCTSTR lpszEntry);
The lpszPhonebook parameter is a pointer to a phonebook file name. The lpszEntry parameter is a string representing an existing phonebook entry. If this function succeeds, it returns ERROR_SUCCESS; otherwise, it returns ERROR_ INVALID_NAME.
When a RAS client makes a connection using a phonebook entry through RasDial(), it can save the user's security credentials and associates them with the phonebook entry. The functions RasGetCredentials(), RasSetCredentials(), RasGetEntryDialParams(), and RasSetEntryDialParams() allow you to man- age user security credentials associated with a phonebook entry. The RasGetCredentials() and RasSetCredentials() functions were introduced in Windows NT 4. (They are also available on all Windows NT systems.) These two functions supersede RasGetEntryDialParams() and RasSetEntryDialParams(). Because RasGetCredentials() and RasSetCredentials() are not available on Windows 95, Windows 98, Windows Me, and Windows CE systems, you can use RasGetEntryDialParams() and RasSetEntryDialParams() for this purpose on all platforms. The RasGetCredentials() function retrieves user credentials associated with a phonebook entry and is defined as:
DWORD RasGetCredentials(
LPCTSTR lpszPhonebook,
LPCTSTR lpszEntry,
LPRASCREDENTIALS lpCredentials
);
The lpszPhonebook parameter is a pointer to a phonebook filename. The lpszEntry parameter is a string representing an existing phonebook entry. The lpCredentials parameter, defined below, is a pointer to a RASCREDENTIALS structure that can receive the user name, password, and domain associated with the phonebook entry:
typedef struct {
DWORD dwSize;
DWORD dwMask;
TCHAR szUserName[UNLEN + 1];
TCHAR szPassword[PWLEN + 1];
TCHAR szDomain[DNLEN + 1];
} RASCREDENTIALS, *LPRASCREDENTIALS;
The fields of this structure are defined as:
If RasGetCredentials() succeeds, it returns 0. Your application can determine which security credentials are set based on the flags set in the dwMask field of the lpCredentials structure.
The RasSetCredentials() function is similar to RasGetCredentials() except that it lets you change security credentials associated with a phonebook entry. The parameters are the same except that RasSetCredentials() features an additional parameter: fClearCredentials. RasSetCredentials is defined as:
DWORD RasSetCredentials(
LPCTSTR lpszPhonebook,
LPCTSTR lpszEntry,
LPRASCREDENTIALS lpCredentials,
BOOL fClearCredentials
);
The fClearCredentials parameter is a Boolean operator that, if set to TRUE, causes RasSetCredentials() to change credentials identified in the dwMask field of the lpCredentials structure to an empty string (“”) value. For example, if dwMask contains the RASCM_Password flag, the password stored is replaced with an empty string. If the RasSetCredentials() function succeeds, it returns 0.
You can also use RasGetEntryDialParams() and RasSetEntryDialParams() to manage user security credentials associated with phonebook entries. RasGetEntryDialParams() is defined as:
DWORD RasGetEntryDialParams(
LPCTSTR lpszPhonebook,
LPRASDIALPARAMS lprasdialparams,
LPBOOL lpfPassword
);
The lpszPhonebook parameter is a pointer to a phonebook file name. The lprasdialparams parameter is a pointer to a RASDIALPARAMS structure. The lpfPassword parameter is a Boolean flag that returns TRUE if the user's password was retrieved in the lprasdialparams structure.
The RasSetEntryDialParams() function changes the connection information that was last set by the RasDial() call on a particular phonebook entry. RasSetEntryDialParams() is defined as:
DWORD RasSetEntryDialParams(
LPCTSTR lpszPhonebook,
LPRASDIALPARAMS lprasdialparams,
BOOL fRemovePassword
);
The lpszPhonebook and lprasdialparams parameters are exactly the same as the first two parameters in RasGetEntryDialParams(). The fRemovePassword parameter is a Boolean flag that, if set to TRUE, tells RasSetEntryDialParams() to remove the password associated with the phonebook entry identified in the lprasdialparams structure.
RAS has two useful functions that allow you to retrieve the properties of connections established on your system: RasEnumConnections() and RasGetProjectionInfo(). RasEnumConnections() can retrieve all the available active RAS connections on your system. This is useful when you need to obtain connection specific information about a RAS connection on your system using RasGetProjectionInfo(), as you will see later in this chapter. The RasEnumConnections() is defined as:
DWORD RasEnumConnections(
LPRASCONN lprasconn,
LPDWORD lpcb,
LPDWORD lpcConnections
);
The lprasconn parameter is an application buffer that will receive an array of RASCONN structures. A RASCONN structure is defined as:
typedef struct _RASCONN
{
DWORD dwSize;
HRASCONN hrasconn;
TCHAR szEntryName[RAS_MaxEntryName + 1];
#if (WINVER >= 0x400)
TCHAR szDeviceType[RAS_MaxDeviceType + 1];
TCHAR szDeviceName[RAS_MaxDeviceName + 1];
#endif
#if (WINVER >= 0x401)
TCHAR szPhonebook[MAX_PATH];
DWORD dwSubEntry;
#endif
#if (WINVER >= 0x500)
GUID guidEntry;
#endif
#if (WINVER >= 0x501)
DWORD dwSessionId;
DWORD dwFlags;
LUID luid;
#endif
} RASCONN;
The most useful field in the RASCONN structure is the hrasconn, which receives the connection handle that RasDial() originally created. You can use this handle to retrieve more connection information from RasGetProjectionInfo(), which is described later. You need to pass to RasEnumConnections() a large enough buffer to hold several RASCONN structures; otherwise, this function will fail with the error ERROR_BUFFER_TOO_SMALL. Also, the first RASCONN structure in your buffer must have the dwSize field set to the byte size of a RASCONN structure. The next parameter, lpcb, is a pointer to a variable that you must set to the size (in bytes) of your lprasconn array. When this function returns, lpcb will contain the number of bytes required to enumerate all connections. If you don't supply a large enough buffer, you can always try again with the correct buffer size returned in lpcb. The lpcConnections parameter is a pointer to a variable that receives a count of the number of RASCONN structures written to lprasconn.
With the RAS connection handles you receive from RasEnumConnections(), you can obtain network protocol–specific information that is used over an established RAS connection. This is known as projection information. A remote access server uses projection information to represent a remote client on the network. For example, when you make a RAS connection that uses IP over a framing protocol, IP configuration information (such as an assigned IP address) is established from the RAS to your client. You can retrieve projection information for the protocols that travel over the PPP framing protocol by calling the RasGetProjectionInfo() function, which is defined as:
DWORD RasGetProjectionInfo(
HRASCONN hrasconn,
RASPROJECTION rasprojection,
LPVOID lpprojection,
LPDWORD lpcb
);
The hrasconn parameter is a RAS connection handle. The rasprojection parameter is a RASPROJECTION enumeration type that allows you to specify a protocol to receive connection information for. The lpprojection parameter receives a data structure that is associated with the enumeration type specified in rasprojection. The final parameter, lpcb, is a pointer to a variable that you must set to the size of your lpprojection structure. When this function completes, this variable will contain the size of the buffer needed to obtain the projection information.
The following RASPROJECTION enumeration types allow you to receive connection information:
To retrieve IP address information for a PPP framing protocol connection, you must specify the RASP_PppIp enumeration type. When you specify a RASP_PppIp, you will receive a RASPPPIP structure that is defined as:
typedef struct _RASPPPIP {
DWORD dwSize;
DWORD dwError;
TCHAR szIpAddress[ RAS_MaxIpAddress + 1 ];
#ifndef WINNT35COMPATIBLE
TCHAR szServerIpAddress[ RAS_MaxIpAddress + 1 ];
#endif
#if (WINVER >= 0x500)
DWORD dwOptions;
DWORD dwServerOptions;
#endif
} RASPPPIP;
The fields are defined as:
The following code demonstrates how to call RasGetProjectionInfo() to retrieve the IP addresses assigned to a client when a PPP connection is made over RAS:
lpProjection = (RASPPPIP *) GlobalAlloc(GPTR, cb);
lpProjection->dwSize = sizeof(RASPPPIP);
cb = sizeof(RASPPPIP);
Ret = RasGetProjectionInfo(hRasConn, RASP_PppIp, lpProjection, &cb);
if (Ret != ERROR_SUCCESS)
{
printf("RasGetProjectionInfo failed with error %d", Ret);
return;
}
else
{
printf("\nRas Client IP address: %s\n", lpProjection->szIpAddress);
printf("Ras Server IP address: %s\n", lpProjection->szServerIpAddress);
}
Useful References
< RAS Client, Functions & Modes | RAS Main | VPN & RAS Example >