|
|
/*
File: rpbk.c
Implementation of api's that populate the router phonebook portions of MPR intformation structures.
Paul Mayfield, 11/2/98
The following describes the mapping from ras entry to router entry.
// The following RAS options are not supported. They will always
// be cleared if set.
//
RASEO_UseCountryAndAreaCodes RASEO_TerminalBeforeDial RASEO_TerminalAfterDial RASEO_ModemLights RASEO_UseLogonCredentials RASEO_Custom RASEO_PreviewPhoneNumber RASEO_PreviewUserPw RASEO_PreviewDomain RASEO_ShowDialingProgress
// The following ras types are not supported.
//
RASET_Internet // Reset to MPRET_Phone if set
// The following protocol setting is not supported
//
RASNP_NetBEUI // Always exclude
//
// RASENTRY Conversion
//
Items deleted: DWORD dwSize; // version is MPR_INTERFACE_2
WCHAR szScript[ MAX_PATH ]; // Set to ""
DWORD dwReserved1; // Set to 0
DWORD dwReserved2; // Set to 0
WCHAR szAutodialDll[...]; // Set to ""
WCHAR szAutodialFunc[...]; // Set to ""
WCHAR szCustomDialDll[MAX_PATH]; // Set to ""
DWORD dwFramingProtocol; // Set to PPP
DWORD dwCountryID; // Set to 0
DWORD dwCountryCode; // Set to 0
WCHAR szAreaCode[ RAS_MaxAreaCode + 1 ]; // Set to ""
DWORD dwFrameSize
Items modified: DWORD dwAlternateOffset to PWCHAR pszAlternates RASIPADDR ipaddr to DWORD RASIPADDR ipaddrDns to DWORD RASIPADDR ipaddrDnsAlt to DWORD RASIPADDR ipaddrWins to DWORD RASIPADDR ipaddrWinsAlt to DWORD
//
// RASSUBENTRY Conversion
//
Items deleted: DWORD dwSize; // version is MPR_INTERFACE_DEVICE_0
DWORD dwfFlags; // unused anyway
Items modified: DWORD dwAlternateOffset to PWCHAR pszAlternates
*/
#include "dimsvcp.h"
#include <ras.h>
#include <dimsvc.h> // Generated by MIDL
#include <mprapi.h>
#include <mprapip.h>
#include "rpbk.h"
//
// Definitions
//
#define MPRIO_UnsupportedOptions \
( \ RASEO_UseCountryAndAreaCodes | \ RASEO_TerminalBeforeDial | \ RASEO_TerminalAfterDial | \ RASEO_ModemLights | \ RASEO_UseLogonCredentials | \ RASEO_Custom | \ RASEO_PreviewPhoneNumber | \ RASEO_PreviewUserPw | \ RASEO_PreviewDomain | \ RASEO_ShowDialingProgress \ )
//
// Strings
//
static const WCHAR pszRouterPbkFmt[] = L"\\ras\\Router.pbk";
//
// Structure tracks router entry information
//
typedef struct _RPBK_ENTRY_INFO { PWCHAR pszPhonebookPath;
DWORD dwEntrySize; LPRASENTRY pRasEntry; DWORD dwCustAuthDataSize; LPBYTE lpbCustAuthData; } RPBK_ENTRY_INFO;
//
// Structure tracks sub entry information
//
typedef struct _RPBK_SUBENTRY_INFO { PWCHAR pszPhonebookPath; LPRASSUBENTRY pRasSubEntry; DWORD dwSize; } RPBK_SUBENTRY_INFO;
//
// Common allocation
//
PVOID RpbkAlloc( IN DWORD dwBytes, IN BOOL bZero) { return LOCAL_ALLOC( (bZero) ? HEAP_ZERO_MEMORY : 0, dwBytes ); }
//
// Common free
//
VOID RpbkFree( IN PVOID pvData) { LOCAL_FREE( pvData ); }
//
// Cleans up the entry info blob
//
VOID RpbkFreeEntryInfo( IN RPBK_ENTRY_INFO * pInfo) { if (pInfo) { if (pInfo->pszPhonebookPath) { RpbkFreePhonebookPath(pInfo->pszPhonebookPath); } if (pInfo->pRasEntry) { RpbkFree(pInfo->pRasEntry); } if (pInfo->lpbCustAuthData) { RpbkFree(pInfo->lpbCustAuthData); } RpbkFree(pInfo); } }
//
// Cleans up the sub entry info blob
//
VOID RpbkFreeSubEntryInfo( IN RPBK_SUBENTRY_INFO * pInfo) { if (pInfo) { if (pInfo->pszPhonebookPath) { RpbkFree(pInfo->pszPhonebookPath); } if (pInfo->pRasSubEntry) { RpbkFree(pInfo->pRasSubEntry); } RpbkFree(pInfo); } }
//
// Returns a heap-allocated copy of the path to the router
// phonebook
//
DWORD RpbkGetPhonebookPath( OUT PWCHAR* ppszPath) { WCHAR pszSystemPath[MAX_PATH]; UINT uiLength = sizeof(pszSystemPath) / sizeof(WCHAR); DWORD dwRetSize = 0; PWCHAR pszRet = NULL;
// Find the system directory
//
uiLength = GetSystemDirectoryW(pszSystemPath, uiLength); if (uiLength == 0) { return ERROR_NOT_ENOUGH_MEMORY; }
// Allocate the return buffer
//
dwRetSize = ((uiLength + 1) * sizeof(WCHAR)) + sizeof(pszRouterPbkFmt); pszRet = (PWCHAR) RpbkAlloc(dwRetSize, FALSE); if (pszRet == NULL) { return ERROR_NOT_ENOUGH_MEMORY; }
// Format the string
//
wcscpy(pszRet, pszSystemPath); wcscpy(pszRet + uiLength, pszRouterPbkFmt);
*ppszPath = pszRet; return NO_ERROR; }
//
// Cleans up after RpbkGetPhonebookPath
//
DWORD RpbkFreePhonebookPath( IN PWCHAR pszPath) { if ( pszPath ) { RpbkFree(pszPath); }
return NO_ERROR; }
//
// Returns size in bytes of a multisz.
//
DWORD RpbkGetMultiSzSize( IN LPWSTR lpwsMultSz ) { LPWSTR lpwsPtr = lpwsMultSz; DWORD dwcbAlternates = 0; DWORD dwCurCount;
if ( lpwsMultSz == NULL ) { return( 0 ); }
while( *lpwsPtr != L'\0' ) { dwCurCount = ( wcslen( lpwsPtr ) + 1 ); dwcbAlternates += dwCurCount; lpwsPtr += dwCurCount; }
//
// One more for the last NULL terminator
//
dwcbAlternates++;
dwcbAlternates *= sizeof( WCHAR );
return( dwcbAlternates ); }
//
// Copies a multi sz
//
DWORD RpbkCopyMultiSz( IN LPWSTR lpwsDst, IN LPWSTR lpwsSrc) { if (!lpwsDst || !lpwsSrc) { return ERROR_INVALID_PARAMETER; }
while (lpwsSrc[0] || lpwsSrc[1]) { *lpwsDst = *lpwsSrc; lpwsDst++; lpwsSrc++; } lpwsDst[0] = (WCHAR)0; lpwsDst[1] = (WCHAR)0; return NO_ERROR; }
//
// Removes any unsupported options from the interface data
// provided.
//
DWORD RpbkConformIfData( IN DWORD dwLevel, IN LPBYTE pInterfaceData) { MPR_INTERFACE_2* pIf2 = (MPR_INTERFACE_2*)pInterfaceData;
// Clear the unsupported options
//
pIf2->dwfOptions &= ~MPRIO_UnsupportedOptions;
// Make sure that netbios doesn't get reported
//
pIf2->dwfNetProtocols &= ~RASNP_NetBEUI;
// Make sure that the type is not internet
//
if (pIf2->dwType == RASET_Internet) { pIf2->dwType = RASET_Phone; }
return NO_ERROR; }
//
// Removes any unsupported options from the router entry
// provided.
//
DWORD RpbkConformEntry( IN LPRASENTRY pEntry) { // Clear the unsupported options
//
pEntry->dwfOptions &= ~MPRIO_UnsupportedOptions;
// Make sure that netbios is not enabled
//
pEntry->dwfNetProtocols &= ~RASNP_NetBEUI;
// Make sure that the type is not internet
//
if (pEntry->dwType == RASET_Internet) { pEntry->dwType = RASET_Phone; }
// Default all other values of the entry that
// can't be supplied through MPR_INTERFACE_*
// structures.
pEntry->dwSize = sizeof(RASENTRY); pEntry->dwReserved1 = 0; pEntry->dwReserved2 = 0; pEntry->dwFramingProtocol = RASFP_Ppp; pEntry->dwFrameSize = 0; pEntry->dwCountryID = 0; pEntry->dwCountryCode = 0; pEntry->szScript[0] = L'\0'; pEntry->szAutodialDll[0] = L'\0'; pEntry->szAutodialFunc[0] = L'\0'; pEntry->szCustomDialDll[0] = L'\0'; pEntry->szAreaCode[0] = L'\0';
return NO_ERROR; }
//
// Reads in the router phonebook entry associated with
// the given interface
//
DWORD RpbkOpenEntry( IN ROUTER_INTERFACE_OBJECT* pIfObject, OUT PHANDLE phEntry ) { RPBK_ENTRY_INFO * pInfo = NULL; DWORD dwErr = NO_ERROR, dwSize;
do { // Initialize
*phEntry = NULL; // Allocate the control structure
//
pInfo = (RPBK_ENTRY_INFO*) RpbkAlloc(sizeof(RPBK_ENTRY_INFO), TRUE); if (pInfo == NULL) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; }
// Get the phonebook path
//
dwErr = RpbkGetPhonebookPath(&(pInfo->pszPhonebookPath)); if (dwErr != NO_ERROR) { break; }
// Find out how big the ras entry needs to be
//
dwErr = RasGetEntryProperties( pInfo->pszPhonebookPath, pIfObject->lpwsInterfaceName, NULL, &(pInfo->dwEntrySize), NULL, NULL); if (dwErr != ERROR_BUFFER_TOO_SMALL) { break; }
// Allocate the ras entry structure
//
pInfo->pRasEntry = (LPRASENTRY) RpbkAlloc(pInfo->dwEntrySize, TRUE); if (pInfo->pRasEntry == NULL) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; }
// Read in the ras entry
//
pInfo->pRasEntry->dwSize = sizeof(RASENTRY); dwErr = RasGetEntryProperties( pInfo->pszPhonebookPath, pIfObject->lpwsInterfaceName, pInfo->pRasEntry, &(pInfo->dwEntrySize), NULL, NULL); if (dwErr != NO_ERROR) { break; }
// Find out how big the custom auth data needs
// to be
dwErr = RasGetCustomAuthDataW ( pInfo->pszPhonebookPath, pIfObject->lpwsInterfaceName, NULL, &(pInfo->dwCustAuthDataSize)); if ( (dwErr != NO_ERROR) && (dwErr != ERROR_BUFFER_TOO_SMALL) ) { break; }
dwErr = NO_ERROR; if ( pInfo->dwCustAuthDataSize ) { // Allocate the custom auth data
//
pInfo->lpbCustAuthData = RpbkAlloc(pInfo->dwCustAuthDataSize, TRUE); if (pInfo->lpbCustAuthData == NULL) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; }
// Read in the ras entry
//
dwErr = RasGetCustomAuthDataW( pInfo->pszPhonebookPath, pIfObject->lpwsInterfaceName, pInfo->lpbCustAuthData, &(pInfo->dwCustAuthDataSize)); if (dwErr != NO_ERROR) { break; } }
// Assign the return value
*phEntry = (HANDLE)pInfo; } while (FALSE);
// Cleanup
{ if (dwErr != NO_ERROR) { RpbkFreeEntryInfo(pInfo); } } return dwErr; }
//
// Cleans up the data returned by RpbkOpen* functions
//
DWORD RpbkCloseEntry( IN HANDLE hEntry ) { RpbkFreeEntryInfo((RPBK_ENTRY_INFO*)hEntry); return NO_ERROR; }
//
// Writes out the router phonebook entry based on the
// the given interface
//
DWORD RpbkSetEntry( IN DWORD dwLevel, IN LPBYTE pInterfaceData ) { MPRI_INTERFACE_2* pIf2 = (MPRI_INTERFACE_2*)pInterfaceData; LPRASENTRY pEntry = NULL; PWCHAR pszAlternates = NULL, pszPath = NULL; DWORD dwErr = NO_ERROR, dwSize; LPWSTR pszAltSrc = NULL; // Validate parameters
if (!pIf2) { return ERROR_INVALID_PARAMETER; }
// Allocate the ras entry structure
//
dwSize = sizeof(RASENTRY); if (pIf2->dwAlternatesOffset) { pszAltSrc = (LPWSTR) ((ULONG_PTR)(pIf2) + (ULONG_PTR)(pIf2->dwAlternatesOffset)); dwSize += RpbkGetMultiSzSize(pszAltSrc); } pEntry = RpbkAlloc(dwSize, TRUE); if (pEntry == NULL) { return ERROR_NOT_ENOUGH_MEMORY; }
// Assign all assignable fields
//
pEntry->dwfOptions = pIf2->dwfOptions; *((DWORD*)&(pEntry->ipaddr)) = pIf2->ipaddr; *((DWORD*)&(pEntry->ipaddrDns)) = pIf2->ipaddrDns; *((DWORD*)&(pEntry->ipaddrDnsAlt)) = pIf2->ipaddrDnsAlt; *((DWORD*)&(pEntry->ipaddrWins)) = pIf2->ipaddrWins; *((DWORD*)&(pEntry->ipaddrWinsAlt)) = pIf2->ipaddrWinsAlt; pEntry->dwfNetProtocols = pIf2->dwfNetProtocols; pEntry->dwChannels = pIf2->dwChannels; pEntry->dwSubEntries = pIf2->dwSubEntries; pEntry->dwDialMode = pIf2->dwDialMode; pEntry->dwDialExtraPercent = pIf2->dwDialExtraPercent; pEntry->dwDialExtraSampleSeconds = pIf2->dwDialExtraSampleSeconds; pEntry->dwHangUpExtraPercent = pIf2->dwHangUpExtraPercent; pEntry->dwHangUpExtraSampleSeconds = pIf2->dwHangUpExtraSampleSeconds; pEntry->dwIdleDisconnectSeconds = pIf2->dwIdleDisconnectSeconds; pEntry->dwType = pIf2->dwType; pEntry->dwEncryptionType = pIf2->dwEncryptionType; pEntry->dwCustomAuthKey = pIf2->dwCustomAuthKey; pEntry->dwVpnStrategy = pIf2->dwVpnStrategy; pEntry->guidId = pIf2->guidId;
// Copy all copyable fields
//
wcscpy(pEntry->szLocalPhoneNumber, pIf2->szLocalPhoneNumber); wcscpy(pEntry->szDeviceType, pIf2->szDeviceType); wcscpy(pEntry->szDeviceName, pIf2->szDeviceName); wcscpy(pEntry->szX25PadType, pIf2->szX25PadType); wcscpy(pEntry->szX25Address, pIf2->szX25Address); wcscpy(pEntry->szX25Facilities, pIf2->szX25Facilities); wcscpy(pEntry->szX25UserData, pIf2->szX25UserData);
do { // Copy the alternates list
//
if (pIf2->dwAlternatesOffset) { pEntry->dwAlternateOffset = sizeof(RASENTRY); pszAlternates = (PWCHAR) ((ULONG_PTR)(pEntry) + (ULONG_PTR)(pEntry->dwAlternateOffset)); dwErr = RpbkCopyMultiSz(pszAlternates, pszAltSrc); if (dwErr != NO_ERROR) { break; } } else { pEntry->dwAlternateOffset = 0; }
// Remove any unsupported options that may have made
// it in. (shouldn't be any)
//
dwErr = RpbkConformEntry(pEntry); if (dwErr != NO_ERROR) { break; }
// Map MPRIO_IpSecPreSharedKey to RASEO_PreSharedKey
//
//
if(pIf2->dwfOptions & MPRIO_IpSecPreSharedKey) { pEntry->dwfOptions &= ~(MPRIO_IpSecPreSharedKey); pEntry->dwfOptions2 |= RASEO2_UsePreSharedKey; }
// Discover the phonebook path
dwErr = RpbkGetPhonebookPath(&pszPath); if (dwErr != NO_ERROR) { break; }
// Save the entry
dwErr = RasSetEntryPropertiesW( pszPath, pIf2->wszInterfaceName, pEntry, dwSize, NULL, 0); if (dwErr != NO_ERROR) { break; }
// Save the custom auth options
//
dwErr = RasSetCustomAuthDataW( pszPath, pIf2->wszInterfaceName, (LPBYTE)(pIf2 + 1), pIf2->dwCustomAuthDataSize); if ( dwErr != NO_ERROR ) { break; } } while (FALSE);
// Cleanup
{ if (pEntry) { RpbkFree(pEntry); } if (pszPath) { RpbkFree(pszPath); } }
return dwErr; } //
// Deletes the given entry from the phonebook
//
DWORD RpbkDeleteEntry( IN PWCHAR pszInterfaceName ) { PWCHAR pszPath = NULL; DWORD dwErr = NO_ERROR; do { // Get the phonebook path
//
dwErr = RpbkGetPhonebookPath(&pszPath); if (dwErr != NO_ERROR) { break; }
// Delete the entry
//
dwErr = RasDeleteEntry(pszPath, pszInterfaceName); if (dwErr != NO_ERROR) { break; } } while (FALSE); // Cleanup
{ if ( pszPath ) { RpbkFree(pszPath); } } return dwErr; }
//
// Calculates the required size of a buffer to hold interface information
// at the given level based on the given entry or sub entry.
//
DWORD RpbkEntryToIfDataSize( IN HANDLE hEntry, IN DWORD dwLevel, OUT LPDWORD lpdwcbSizeOfData ) { RPBK_ENTRY_INFO* pInfo = (RPBK_ENTRY_INFO*)hEntry; DWORD dwSize; PWCHAR pszAlternates = NULL;
// Validate parameters
if (!pInfo) { return ERROR_INVALID_PARAMETER; }
// Initialize
*lpdwcbSizeOfData = 0;
// For level 2, the size is the size of the level 2
// structure plus the size of the alternate phone list
if (dwLevel != 2) { return ERROR_INVALID_LEVEL; }
// Initailize the size to the base size
//
dwSize = sizeof(MPR_INTERFACE_2);
// Add on the size of the custom auth data
//
dwSize += pInfo->dwCustAuthDataSize; // Add on the size of the alternates list
//
if (pInfo->pRasEntry->dwAlternateOffset) { pszAlternates = (PWCHAR) ((ULONG_PTR)(pInfo->pRasEntry) + (ULONG_PTR)(pInfo->pRasEntry->dwAlternateOffset)); dwSize += RpbkGetMultiSzSize(pszAlternates); }
// Assign the return value
//
*lpdwcbSizeOfData = dwSize; return NO_ERROR; }
//
// Populates the ras portion of the given interface info blob based on the
// level and entry or subentry.
//
DWORD RpbkEntryToIfData( IN HANDLE hEntry, IN DWORD dwLevel, OUT LPBYTE pInterfaceData ) { RPBK_ENTRY_INFO* pInfo = (RPBK_ENTRY_INFO*)hEntry; MPRI_INTERFACE_2* pIf2 = (MPRI_INTERFACE_2*)pInterfaceData; LPRASENTRY pEntry = NULL; PWCHAR pszSrc, pszDst; DWORD dwErr = NO_ERROR, dwOffset = 0; // Validate parameters
if (!pInfo || !pIf2) { return ERROR_INVALID_PARAMETER; }
// Alias the ras entry
//
pEntry = pInfo->pRasEntry;
// Assign all assignable fields
//
pIf2->dwfOptions = pEntry->dwfOptions; pIf2->ipaddr = *((DWORD*)&(pEntry->ipaddr)); pIf2->ipaddrDns = *((DWORD*)&(pEntry->ipaddrDns)); pIf2->ipaddrDnsAlt = *((DWORD*)&(pEntry->ipaddrDnsAlt)); pIf2->ipaddrWins = *((DWORD*)&(pEntry->ipaddrWins)); pIf2->ipaddrWinsAlt = *((DWORD*)&(pEntry->ipaddrWinsAlt)); pIf2->dwfNetProtocols = pEntry->dwfNetProtocols; pIf2->dwChannels = pEntry->dwChannels; pIf2->dwSubEntries = pEntry->dwSubEntries; pIf2->dwDialMode = pEntry->dwDialMode; pIf2->dwDialExtraPercent = pEntry->dwDialExtraPercent; pIf2->dwDialExtraSampleSeconds = pEntry->dwDialExtraSampleSeconds; pIf2->dwHangUpExtraPercent = pEntry->dwHangUpExtraPercent; pIf2->dwHangUpExtraSampleSeconds= pEntry->dwHangUpExtraSampleSeconds; pIf2->dwIdleDisconnectSeconds = pEntry->dwIdleDisconnectSeconds; pIf2->dwType = pEntry->dwType; pIf2->dwEncryptionType = pEntry->dwEncryptionType; pIf2->dwCustomAuthKey = pEntry->dwCustomAuthKey; pIf2->dwVpnStrategy = pEntry->dwVpnStrategy; pIf2->guidId = pEntry->guidId;
// Copy all copyable fields
//
wcscpy(pIf2->szLocalPhoneNumber, pEntry->szLocalPhoneNumber); wcscpy(pIf2->szDeviceType, pEntry->szDeviceType); wcscpy(pIf2->szDeviceName, pEntry->szDeviceName); wcscpy(pIf2->szX25PadType, pEntry->szX25PadType); wcscpy(pIf2->szX25Address, pEntry->szX25Address); wcscpy(pIf2->szX25Facilities, pEntry->szX25Facilities); wcscpy(pIf2->szX25UserData, pEntry->szX25UserData);
// Append the custom auth data to the end of the
// structure.
//
dwOffset = sizeof(MPRI_INTERFACE_2); if ( pInfo->dwCustAuthDataSize ) { pIf2->dwCustomAuthDataSize = pInfo->dwCustAuthDataSize; pIf2->dwCustomAuthDataOffset = TRUE; CopyMemory( pIf2 + 1, pInfo->lpbCustAuthData, pInfo->dwCustAuthDataSize); }
// Append the alternates list
//
dwOffset += pInfo->dwCustAuthDataSize; if (pEntry->dwAlternateOffset) { pIf2->dwAlternatesOffset = TRUE; pszSrc = (PWCHAR)((ULONG_PTR)(pEntry) + (ULONG_PTR)(pEntry->dwAlternateOffset));
pszDst = (PWCHAR)((ULONG_PTR)(pIf2) + (ULONG_PTR)dwOffset); dwErr = RpbkCopyMultiSz(pszDst, pszSrc); if (dwErr != NO_ERROR) { return dwErr; } } else { pIf2->dwAlternatesOffset = 0; }
// Remove any unsupported options that may have made
// it in. (shouldn't be any)
//
dwErr = RpbkConformIfData(dwLevel, pInterfaceData); if (dwErr != NO_ERROR) { return dwErr; }
if(pEntry->dwfOptions2 & RASEO2_UsePreSharedKey) { pIf2->dwfOptions |= MPRIO_IpSecPreSharedKey; }
return NO_ERROR; }
//
// Reads in the router phonebook sub entry associated with
// the given interface
//
DWORD RpbkOpenSubEntry( IN ROUTER_INTERFACE_OBJECT* pIfObject, IN DWORD dwIndex, OUT PHANDLE phSubEntry ) { RPBK_SUBENTRY_INFO * pInfo = NULL; DWORD dwErr = NO_ERROR, dwSize;
do { // Initialize
*phSubEntry = NULL; // Allocate the control structure
//
pInfo = (RPBK_SUBENTRY_INFO*) RpbkAlloc(sizeof(RPBK_SUBENTRY_INFO), TRUE); if (pInfo == NULL) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; }
// Get the phonebook path
//
dwErr = RpbkGetPhonebookPath(&(pInfo->pszPhonebookPath)); if (dwErr != NO_ERROR) { break; }
// Find out how big the ras entry needs to be
//
dwErr = RasGetSubEntryPropertiesW( pInfo->pszPhonebookPath, pIfObject->lpwsInterfaceName, dwIndex, NULL, &(pInfo->dwSize), NULL, NULL); if (dwErr != ERROR_BUFFER_TOO_SMALL) { break; }
// Allocate the ras entry structure
//
pInfo->pRasSubEntry = (LPRASSUBENTRY) RpbkAlloc(pInfo->dwSize, TRUE); if (pInfo->pRasSubEntry == NULL) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; }
// Read in the ras entry
//
pInfo->pRasSubEntry->dwSize = sizeof(RASSUBENTRY); dwErr = RasGetSubEntryProperties( pInfo->pszPhonebookPath, pIfObject->lpwsInterfaceName, dwIndex, pInfo->pRasSubEntry, &(pInfo->dwSize), NULL, NULL); if (dwErr != NO_ERROR) { break; }
// Assign the return value
*phSubEntry = (HANDLE)pInfo; } while (FALSE);
// Cleanup
{ if (dwErr != NO_ERROR) { RpbkFreeSubEntryInfo(pInfo); } } return dwErr; }
//
// Cleans up the data returned by RpbkOpen* functions
//
DWORD RpbkCloseSubEntry( IN HANDLE hSubEntry ) { RpbkFreeSubEntryInfo((RPBK_SUBENTRY_INFO*)hSubEntry); return NO_ERROR; }
DWORD RpbkSetSubEntry( IN PWCHAR pszInterface, IN DWORD dwIndex, IN DWORD dwLevel, OUT LPBYTE pDevData ) { MPR_DEVICE_0* pDev0 = (MPR_DEVICE_0*)pDevData; MPR_DEVICE_1* pDev1 = (MPR_DEVICE_1*)pDevData; LPRASSUBENTRY pSubEntry = NULL; PWCHAR pszAlternates = NULL, pszPath = NULL; DWORD dwErr = NO_ERROR, dwSize; // Validate parameters
if (! pDev0) { return ERROR_INVALID_PARAMETER; }
// Allocate the ras entry structure
//
dwSize = sizeof(RASSUBENTRY); if ((dwLevel == 1) && (pDev1->szAlternates)) { dwSize += RpbkGetMultiSzSize(pDev1->szAlternates); } pSubEntry = RpbkAlloc(dwSize, TRUE); if (pSubEntry == NULL) { return ERROR_NOT_ENOUGH_MEMORY; } pSubEntry->dwSize = sizeof(RASSUBENTRY);
do { // Copy all copyable fields
//
if ( dwLevel == 0 ) { wcscpy(pSubEntry->szDeviceType, pDev0->szDeviceType); wcscpy(pSubEntry->szDeviceName, pDev0->szDeviceName); } if ( dwLevel == 1 ) { wcscpy(pSubEntry->szDeviceType, pDev1->szDeviceType); wcscpy(pSubEntry->szDeviceName, pDev1->szDeviceName); wcscpy(pSubEntry->szLocalPhoneNumber, pDev1->szLocalPhoneNumber);
if (pDev1->szAlternates) { pSubEntry->dwAlternateOffset = sizeof(RASSUBENTRY); pszAlternates = (PWCHAR) ((ULONG_PTR)(pSubEntry) + (ULONG_PTR)(pSubEntry->dwAlternateOffset)); dwErr = RpbkCopyMultiSz(pszAlternates, pDev1->szAlternates); if (dwErr != NO_ERROR) { break; } } else { pSubEntry->dwAlternateOffset = 0; } }
// Discover the phonebook path
dwErr = RpbkGetPhonebookPath(&pszPath); if (dwErr != NO_ERROR) { break; }
// Save the entry
dwErr = RasSetSubEntryPropertiesW( pszPath, pszInterface, dwIndex, pSubEntry, dwSize, NULL, 0); if (dwErr != NO_ERROR) { break; }
} while (FALSE);
// Cleanup
{ if (pSubEntry) { RpbkFree(pSubEntry); } if (pszPath) { RpbkFree(pszPath); } }
return dwErr; } DWORD RpbkSubEntryToDevDataSize( IN HANDLE hSubEntry, IN DWORD dwLevel, OUT LPDWORD lpdwcbSizeOfData ) { RPBK_SUBENTRY_INFO* pInfo = (RPBK_SUBENTRY_INFO*)hSubEntry; DWORD dwSize = 0; PWCHAR pszAlternates = NULL;
// Validate parameters
if (pInfo == NULL) { return ERROR_INVALID_PARAMETER; }
// Initialize
*lpdwcbSizeOfData = 0;
// Initailize the size
//
if ( dwLevel == 0 ) { dwSize = sizeof(MPR_DEVICE_0); } else { dwSize = sizeof(MPR_DEVICE_1); // Add on the size of the alternates list
//
if (pInfo->pRasSubEntry->dwAlternateOffset) { pszAlternates = (PWCHAR) ((ULONG_PTR)(pInfo->pRasSubEntry) + (ULONG_PTR)(pInfo->pRasSubEntry->dwAlternateOffset)); dwSize += RpbkGetMultiSzSize(pszAlternates); } }
// Assign the return value
//
*lpdwcbSizeOfData = dwSize; return NO_ERROR; } DWORD RpbkSubEntryToDevData( IN HANDLE hSubEntry, IN DWORD dwLevel, OUT LPBYTE pDeviceData ) { RPBK_SUBENTRY_INFO* pInfo = (RPBK_SUBENTRY_INFO*)hSubEntry; MPR_DEVICE_0* pDev0 = (MPR_DEVICE_0*)pDeviceData; MPR_DEVICE_1* pDev1 = (MPR_DEVICE_1*)pDeviceData; LPRASSUBENTRY pSubEntry = NULL; PWCHAR pszAlternates = NULL; DWORD dwErr = NO_ERROR, dwOffset = 0; // Validate parameters
if (!pInfo || !pDev0) { return ERROR_INVALID_PARAMETER; }
// Alias the ras entry
//
pSubEntry = pInfo->pRasSubEntry;
// Copy all copyable fields
//
if ( dwLevel == 0 ) { wcscpy(pDev0->szDeviceType, pSubEntry->szDeviceType); wcscpy(pDev0->szDeviceName, pSubEntry->szDeviceName); } else if ( dwLevel == 1 ) { wcscpy(pDev1->szDeviceType, pSubEntry->szDeviceType); wcscpy(pDev1->szDeviceName, pSubEntry->szDeviceName); wcscpy(pDev1->szLocalPhoneNumber, pSubEntry->szLocalPhoneNumber); // Append the custom auth data to the end of the
// structure.
//
dwOffset += sizeof(MPR_DEVICE_1); if (pSubEntry->dwAlternateOffset) { pDev1->szAlternates = (PWCHAR) ((ULONG_PTR)(pDev1) + dwOffset); pszAlternates = (PWCHAR) ((ULONG_PTR)(pSubEntry) + (ULONG_PTR)(pSubEntry->dwAlternateOffset)); dwErr = RpbkCopyMultiSz(pDev1->szAlternates, pszAlternates); if (dwErr != NO_ERROR) { return dwErr; } } else { pDev1->szAlternates = NULL; } } return NO_ERROR; }
|