windows-nt/Source/XPSP1/NT/base/ntsetup/oobe/msobcomm/rnaapi.cpp
2020-09-26 16:20:57 +08:00

1966 lines
64 KiB
C++

/*-----------------------------------------------------------------------------
rnaapi.cpp
Wrapper to softlink to RNAPH and RASAPI32.DLL
Copyright (C) 1999 Microsoft Corporation
All rights reserved.
Authors:
vyung
History:
2/7/99 Vyung created
-----------------------------------------------------------------------------*/
#include <util.h>
#include "obcomglb.h"
#include "rnaapi.h"
#include "enumodem.h"
#include "mapicall.h"
#include "wininet.h"
#include "wancfg.h"
#include "assert.h"
extern DWORD SetIEClientInfo(LPINETCLIENTINFO lpClientInfo);
static const WCHAR cszRASAPI32_DLL[] = L"RASAPI32.DLL";
static const WCHAR cszRNAPH_DLL[] = L"RNAPH.DLL";
static const CHAR cszRasEnumDevices[] = "RasEnumDevicesW";
static const CHAR cszRasValidateEntryName[] = "RasValidateEntryName";
static const CHAR cszRasValidateEntryNameA[] = "RasValidateEntryNameW";
static const CHAR cszRasSetCredentials[] = "RasSetCredentialsW";
static const CHAR cszRasSetEntryProperties[] = "RasSetEntryPropertiesW";
static const CHAR cszRasGetEntryProperties[] = "RasGetEntryPropertiesW";
static const CHAR cszRasDeleteEntry[] = "RasDeleteEntryW";
static const CHAR cszRasHangUp[] = "RasHangUpW";
static const CHAR cszRasGetConnectStatus[] = "RasGetConnectStatusW";
static const CHAR cszRasDial[] = "RasDialW";
static const CHAR cszRasEnumConnections[] = "RasEnumConnectionsW";
static const CHAR cszRasGetEntryDialParams[] = "RasGetEntryDialParamsW";
static const CHAR cszRasGetCountryInfo[] = "RasGetCountryInfoW";
static const CHAR cszRasSetEntryDialParams[] = "RasSetEntryDialParamsW";
static const WCHAR cszWininet[] = L"WININET.DLL";
static const CHAR cszInternetSetOption[] = "InternetSetOptionW";
static const CHAR cszInternetQueryOption[] = "InternetQueryOptionW";
#define INTERNET_OPTION_PER_CONNECTION_OPTION 75
//
// Options used in INTERNET_PER_CONN_OPTON struct
//
#define INTERNET_PER_CONN_FLAGS 1
#define INTERNET_PER_CONN_PROXY_SERVER 2
#define INTERNET_PER_CONN_PROXY_BYPASS 3
#define INTERNET_PER_CONN_AUTOCONFIG_URL 4
#define INTERNET_PER_CONN_AUTODISCOVERY_FLAGS 5
//
// PER_CONN_FLAGS
//
#define PROXY_TYPE_DIRECT 0x00000001 // direct to net
#define PROXY_TYPE_PROXY 0x00000002 // via named proxy
#define PROXY_TYPE_AUTO_PROXY_URL 0x00000004 // autoproxy URL
#define PROXY_TYPE_AUTO_DETECT 0x00000008 // use autoproxy detection
//
// PER_CONN_AUTODISCOVERY_FLAGS
//
#define AUTO_PROXY_FLAG_USER_SET 0x00000001 // user changed this setting
#define AUTO_PROXY_FLAG_ALWAYS_DETECT 0x00000002 // force detection even when its not needed
#define AUTO_PROXY_FLAG_DETECTION_RUN 0x00000004 // detection has been run
#define AUTO_PROXY_FLAG_MIGRATED 0x00000008 // migration has just been done
#define AUTO_PROXY_FLAG_DONT_CACHE_PROXY_RESULT 0x00000010 // don't cache result of host=proxy name
#define AUTO_PROXY_FLAG_CACHE_INIT_RUN 0x00000020 // don't initalize and run unless URL expired
#define AUTO_PROXY_FLAG_DETECTION_SUSPECT 0x00000040 // if we're on a LAN & Modem, with only one IP, bad?!?
typedef DWORD (WINAPI* RASSETCREDENTIALS)(
LPCTSTR lpszPhonebook,
LPCTSTR lpszEntry,
LPRASCREDENTIALS lpCredentials,
BOOL fClearCredentials
);
typedef HRESULT (WINAPI * INTERNETSETOPTION) (IN HINTERNET hInternet OPTIONAL, IN DWORD dwOption,IN LPVOID lpBuffer,IN DWORD dwBufferLength);
typedef INTERNET_PER_CONN_OPTION_LISTW INTERNET_PER_CONN_OPTION_LIST;
typedef LPINTERNET_PER_CONN_OPTION_LISTW LPINTERNET_PER_CONN_OPTION_LIST;
// on NT we have to call RasGetEntryProperties with a larger buffer than RASENTRY.
// This is a bug in WinNT4.0 RAS, that didn't get fixed.
//
#define RASENTRY_SIZE_PATCH (7 * sizeof(DWORD))
HRESULT UpdateMailSettings(
HWND hwndParent,
LPINETCLIENTINFO lpINetClientInfo,
LPWSTR lpszEntryName);
DWORD EntryTypeFromDeviceType(
LPCWSTR szDeviceType
);
//+----------------------------------------------------------------------------LPRASDEVINFO
//
// Function: RNAAPI::RNAAPI
//
// Synopsis: Initialize class members and load DLLs
//
// Arguments: None
//
// Returns: None
//
// History: ChrisK Created 1/15/96
//
//-----------------------------------------------------------------------------
RNAAPI::RNAAPI()
{
m_hInst = LoadLibrary(cszRASAPI32_DLL);
m_bUseAutoProxyforConnectoid = 0;
if (FALSE == IsNT ())
{
//
// we only load RNAPH.DLL if it is not NT
// MKarki (5/4/97) - Fix for Bug #3378
//
m_hInst2 = LoadLibrary(cszRNAPH_DLL);
}
else
{
m_hInst2 = NULL;
}
m_fnRasEnumDeviecs = NULL;
m_fnRasValidateEntryName = NULL;
m_fnRasSetEntryProperties = NULL;
m_fnRasGetEntryProperties = NULL;
m_fnRasDeleteEntry = NULL;
m_fnRasHangUp = NULL;
m_fnRasGetConnectStatus = NULL;
m_fnRasEnumConnections = NULL;
m_fnRasDial = NULL;
m_fnRasGetEntryDialParams = NULL;
m_fnRasGetCountryInfo = NULL;
m_fnRasSetEntryDialParams = NULL;
m_pEnumModem = NULL;
}
//+----------------------------------------------------------------------------
//
// Function: RNAAPI::~RNAAPI
//
// Synopsis: release DLLs
//
// Arguments: None
//
// Returns: None
//
// History: ChrisK Created 1/15/96
//
//-----------------------------------------------------------------------------
RNAAPI::~RNAAPI()
{
//
// Clean up
//
if (m_hInst) FreeLibrary(m_hInst);
if (m_hInst2) FreeLibrary(m_hInst2);
}
//+----------------------------------------------------------------------------
//
// Function: RNAAPI::RasEnumDevices
//
// Synopsis: Softlink to RAS function
//
// Arguments: see RAS documentation
//
// Returns: see RAS documentation
//
// History: ChrisK Created 1/15/96
//
//-----------------------------------------------------------------------------
DWORD RNAAPI::RasEnumDevices(LPRASDEVINFO lpRasDevInfo, LPDWORD lpcb,
LPDWORD lpcDevices)
{
DWORD dwRet = ERROR_DLL_NOT_FOUND;
// Look for the API if we haven't already found it
LoadApi(cszRasEnumDevices, (FARPROC*)&m_fnRasEnumDeviecs);
if (m_fnRasEnumDeviecs)
dwRet = (*m_fnRasEnumDeviecs) (lpRasDevInfo, lpcb, lpcDevices);
return dwRet;
}
//+----------------------------------------------------------------------------
//
// Function: RNAAPI::LoadApi
//
// Synopsis: If the given function pointer is NULL, then try to load the API
// from the first DLL, if that fails, try to load from the second
// DLL
//
// Arguments: pszFName - the name of the exported function
// pfnProc - point to where the proc address will be returned
//
// Returns: TRUE - success
//
// History: ChrisK Created 1/15/96
//
//-----------------------------------------------------------------------------
BOOL RNAAPI::LoadApi(LPCSTR pszFName, FARPROC* pfnProc)
{
USES_CONVERSION;
if (*pfnProc == NULL)
{
// Look for the entry point in the first DLL
if (m_hInst)
*pfnProc = GetProcAddress(m_hInst, pszFName);
// if that fails, look for the entry point in the second DLL
if (m_hInst2 && !(*pfnProc))
*pfnProc = GetProcAddress(m_hInst2, pszFName);
}
return (pfnProc != NULL);
}
//+----------------------------------------------------------------------------
//
// Function: RNAAPI::RasGetConnectStatus
//
// Synopsis: Softlink to RAS function
//
// Arguments: see RAS documentation
//
// Returns: see RAS documentation
//
// History: ChrisK Created 7/16/96
//
//-----------------------------------------------------------------------------
DWORD RNAAPI::RasGetConnectStatus(HRASCONN hrasconn, LPRASCONNSTATUS lprasconnstatus)
{
DWORD dwRet = ERROR_DLL_NOT_FOUND;
// Look for the API if we haven't already found it
LoadApi(cszRasGetConnectStatus, (FARPROC*)&m_fnRasGetConnectStatus);
if (m_fnRasGetConnectStatus)
dwRet = (*m_fnRasGetConnectStatus) (hrasconn, lprasconnstatus);
return dwRet;
}
//+----------------------------------------------------------------------------
//
// Function: RNAAPI::RasValidateEntryName
//
// Synopsis: Softlink to RAS function
//
// Arguments: see RAS documentation
//
// Returns: see RAS documentation
//
// History: ChrisK Created 1/15/96
//
//-----------------------------------------------------------------------------
DWORD RNAAPI::RasValidateEntryName(LPCWSTR lpszPhonebook, LPCWSTR lpszEntry)
{
DWORD dwRet = ERROR_DLL_NOT_FOUND;
// Look for the API if we haven't already found it
LoadApi(cszRasValidateEntryName, (FARPROC*)&m_fnRasValidateEntryName);
LoadApi(cszRasValidateEntryNameA, (FARPROC*)&m_fnRasValidateEntryName);
if (m_fnRasValidateEntryName)
dwRet = (*m_fnRasValidateEntryName) (lpszPhonebook, lpszEntry);
return dwRet;
}
//+----------------------------------------------------------------------------
//
// Function: RNAAPI::RasSetEntryProperties
//
// Synopsis: Softlink to RAS function
//
// Arguments: see RAS documentation
//
// Returns: see RAS documentation
//
// History: ChrisK Created 1/15/96
//
//-----------------------------------------------------------------------------
DWORD RNAAPI::RasSetEntryProperties(LPCWSTR lpszPhonebook, LPCWSTR lpszEntry,
LPBYTE lpbEntryInfo, DWORD dwEntryInfoSize,
LPBYTE lpbDeviceInfo, DWORD dwDeviceInfoSize)
{
DWORD dwRet = ERROR_DLL_NOT_FOUND;
RASENTRY FAR *lpRE = NULL;
// Look for the API if we haven't already found it
LoadApi(cszRasSetEntryProperties, (FARPROC*)&m_fnRasSetEntryProperties);
/*//////Assert(
(NULL != lpbDeviceInfo) && (NULL != dwDeviceInfoSize)
||
(NULL == lpbDeviceInfo) && (NULL == dwDeviceInfoSize)
);*/
#define RASGETCOUNTRYINFO_BUFFER_SIZE 256
if (0 == ((LPRASENTRY)lpbEntryInfo)->dwCountryCode)
{
BYTE rasCI[RASGETCOUNTRYINFO_BUFFER_SIZE];
LPRASCTRYINFO prasCI;
DWORD dwSize;
DWORD dw;
prasCI = (LPRASCTRYINFO)rasCI;
ZeroMemory(prasCI, sizeof(rasCI));
prasCI->dwSize = sizeof(RASCTRYINFO);
dwSize = sizeof(rasCI);
////////Assert(((LPRASENTRY)lpbEntryInfo)->dwCountryID);
prasCI->dwCountryID = ((LPRASENTRY)lpbEntryInfo)->dwCountryID;
dw = RNAAPI::RasGetCountryInfo(prasCI, &dwSize);
if (ERROR_SUCCESS == dw)
{
////////Assert(prasCI->dwCountryCode);
((LPRASENTRY)lpbEntryInfo)->dwCountryCode = prasCI->dwCountryCode;
}
else
{
////////AssertMsg(0, L"Unexpected error from RasGetCountryInfo.\r\n");
}
}
if (m_fnRasSetEntryProperties)
dwRet = (*m_fnRasSetEntryProperties) (lpszPhonebook, lpszEntry,
lpbEntryInfo, dwEntryInfoSize,
lpbDeviceInfo, dwDeviceInfoSize);
lpRE = (RASENTRY FAR*)lpbEntryInfo;
LclSetEntryScriptPatch(lpRE->szScript, lpszEntry);
return dwRet;
}
//+----------------------------------------------------------------------------
//
// Function: RNAAPI::RasGetEntryProperties
//
// Synopsis: Softlink to RAS function
//
// Arguments: see RAS documentation
//
// Returns: see RAS documentation
//
// History: ChrisK Created 1/15/96
// jmazner 9/17/96 Modified to allow calls with buffers = NULL and
// InfoSizes = 0. (Based on earlier modification
// to the same procedure in icwdial) See
// RasGetEntryProperties docs to learn why this is
// needed.
//
//-----------------------------------------------------------------------------
DWORD RNAAPI::RasGetEntryProperties(LPCWSTR lpszPhonebook, LPCWSTR lpszEntry,
LPBYTE lpbEntryInfo, LPDWORD lpdwEntryInfoSize,
LPBYTE lpbDeviceInfo, LPDWORD lpdwDeviceInfoSize)
{
DWORD dwRet = ERROR_DLL_NOT_FOUND;
LPBYTE lpbEntryInfoPatch = NULL;
LPDWORD lpdwEntryInfoPatchSize = 0;
// BUGBUG: 990203 (dane) Changed WINVER != 0x400 to WINVER < 0x400 so code
// would compile for Whistler. This has the potential for causing many
// problems. Per ChrisK this code was hand tuned for WINVER == 0x400 and
// is very fragile. If something is failing in regard to modems, RAS,
// ISPs, etc. LOOK HERE FIRST.
//
#if defined(_REMOVE_) // What is the significance of this? Can it be changed to (WINVER < 0x400)?
#if (WINVER != 0x400)
#error This was built with WINVER not equal to 0x400. The size of RASENTRY may not be valid.
#endif
#endif // _REMOVE_
#if (WINVER < 0x400)
#error This was built with WINVER less than 0x400. The size of RASENTRY may not be valid.
#endif
if( (NULL == lpbEntryInfo) && (NULL == lpbDeviceInfo) )
{
////////Assert( NULL != lpdwEntryInfoSize );
//////Assert( NULL != lpdwDeviceInfoSize );
//////Assert( 0 == *lpdwEntryInfoSize );
//////Assert( 0 == *lpdwDeviceInfoSize );
// we're here to ask RAS what size these buffers need to be, don't use the patch stuff
// (see RasGetEntryProperties docs)
lpbEntryInfoPatch = lpbEntryInfo;
lpdwEntryInfoPatchSize = lpdwEntryInfoSize;
}
else
{
//////Assert((*lpdwEntryInfoSize) >= sizeof(RASENTRY));
//////Assert(lpbEntryInfo && lpdwEntryInfoSize);
//
// We are going to fake out RasGetEntryProperties by creating a slightly larger
// temporary buffer and copying the data in and out.
//
lpdwEntryInfoPatchSize = (LPDWORD) GlobalAlloc(GPTR, sizeof(DWORD));
if (NULL == lpdwEntryInfoPatchSize)
return ERROR_NOT_ENOUGH_MEMORY;
*lpdwEntryInfoPatchSize = (*lpdwEntryInfoSize) + RASENTRY_SIZE_PATCH;
lpbEntryInfoPatch = (LPBYTE)GlobalAlloc(GPTR, *lpdwEntryInfoPatchSize);
if (NULL == lpbEntryInfoPatch)
return ERROR_NOT_ENOUGH_MEMORY;
// RAS expects the dwSize field to contain the size of the LPRASENTRY struct
// (used to check which version of the struct we're using) rather than the amount
// of memory actually allocated to the pointer.
//((LPRASENTRY)lpbEntryInfoPatch)->dwSize = dwEntryInfoPatch;
((LPRASENTRY)lpbEntryInfoPatch)->dwSize = sizeof(RASENTRY);
}
// Look for the API if we haven't already found it
LoadApi(cszRasGetEntryProperties, (FARPROC*)&m_fnRasGetEntryProperties);
if (m_fnRasGetEntryProperties)
dwRet = (*m_fnRasGetEntryProperties) (lpszPhonebook, lpszEntry,
lpbEntryInfoPatch, lpdwEntryInfoPatchSize,
lpbDeviceInfo, lpdwDeviceInfoSize);
//TraceMsg(TF_RNAAPI, L"ICWHELP: RasGetEntryProperties returned %lu\r\n", dwRet);
if( NULL != lpbEntryInfo )
{
//
// Copy out the contents of the temporary buffer UP TO the size of the original buffer
//
//////Assert(lpbEntryInfoPatch);
memcpy(lpbEntryInfo, lpbEntryInfoPatch,*lpdwEntryInfoSize);
GlobalFree(lpbEntryInfoPatch);
lpbEntryInfoPatch = NULL;
if( lpdwEntryInfoPatchSize )
{
GlobalFree( lpdwEntryInfoPatchSize );
lpdwEntryInfoPatchSize = NULL;
}
//
// We are again faking Ras functionality here by over writing the size value;
// This is neccesary due to a bug in the NT implementation of RasSetEntryProperties
*lpdwEntryInfoSize = sizeof(RASENTRY);
}
return dwRet;
}
//+----------------------------------------------------------------------------
//
// Function: RNAAPI::RasDeleteEntry
//
// Synopsis: Softlink to RAS function
//
// Arguments: see RAS documentation
//
// Returns: see RAS documentation
//
// History: ChrisK Created 1/15/96
//
//-----------------------------------------------------------------------------
DWORD RNAAPI::RasDeleteEntry(LPWSTR lpszPhonebook, LPWSTR lpszEntry)
{
DWORD dwRet = ERROR_DLL_NOT_FOUND;
// Look for the API if we haven't already found it
LoadApi(cszRasDeleteEntry, (FARPROC*)&m_fnRasDeleteEntry);
if (m_fnRasDeleteEntry)
dwRet = (*m_fnRasDeleteEntry) (lpszPhonebook, lpszEntry);
return dwRet;
}
//+----------------------------------------------------------------------------
//
// Function: RNAAPI::RasHangUp
//
// Synopsis: Softlink to RAS function
//
// Arguments: see RAS documentation
//
// Returns: see RAS documentation
//
// History: ChrisK Created 1/15/96
//
//-----------------------------------------------------------------------------
DWORD RNAAPI::RasHangUp(HRASCONN hrasconn)
{
DWORD dwRet = ERROR_DLL_NOT_FOUND;
// Look for the API if we haven't already found it
LoadApi(cszRasHangUp, (FARPROC*)&m_fnRasHangUp);
if (m_fnRasHangUp)
{
dwRet = (*m_fnRasHangUp) (hrasconn);
Sleep(3000);
}
return dwRet;
}
// ############################################################################
DWORD RNAAPI::RasDial(LPRASDIALEXTENSIONS lpRasDialExtensions, LPWSTR lpszPhonebook,
LPRASDIALPARAMS lpRasDialParams, DWORD dwNotifierType,
LPVOID lpvNotifier, LPHRASCONN lphRasConn)
{
DWORD dwRet = ERROR_DLL_NOT_FOUND;
// Look for the API if we haven't already found it
LoadApi(cszRasDial, (FARPROC*)&m_fnRasDial);
if (m_fnRasDial)
{
dwRet = (*m_fnRasDial) (lpRasDialExtensions, lpszPhonebook,lpRasDialParams,
dwNotifierType, lpvNotifier,lphRasConn);
}
return dwRet;
}
// ############################################################################
DWORD RNAAPI::RasEnumConnections(LPRASCONN lprasconn, LPDWORD lpcb,LPDWORD lpcConnections)
{
DWORD dwRet = ERROR_DLL_NOT_FOUND;
// Look for the API if we haven't already found it
LoadApi(cszRasEnumConnections, (FARPROC*)&m_fnRasEnumConnections);
if (m_fnRasEnumConnections)
{
dwRet = (*m_fnRasEnumConnections) (lprasconn, lpcb,lpcConnections);
}
return dwRet;
}
// ############################################################################
DWORD RNAAPI::RasGetEntryDialParams(LPCWSTR lpszPhonebook, LPRASDIALPARAMS lprasdialparams,
LPBOOL lpfPassword)
{
DWORD dwRet = ERROR_DLL_NOT_FOUND;
// Look for the API if we haven't already found it
LoadApi(cszRasGetEntryDialParams, (FARPROC*)&m_fnRasGetEntryDialParams);
if (m_fnRasGetEntryDialParams)
{
dwRet = (*m_fnRasGetEntryDialParams) (lpszPhonebook, lprasdialparams,lpfPassword);
}
return dwRet;
}
//+----------------------------------------------------------------------------
//
// Function: RNAAPI::RasGetCountryInfo
//
// Synopsis: Softlink to RAS function
//
// Arguments: see RAS documentation
//
// Returns: see RAS documentation
//
// History: ChrisK Created 8/16/96
//
//-----------------------------------------------------------------------------
DWORD RNAAPI::RasGetCountryInfo(LPRASCTRYINFO lprci, LPDWORD lpdwSize)
{
DWORD dwRet = ERROR_DLL_NOT_FOUND;
// Look for the API if we haven't already found it
LoadApi(cszRasGetCountryInfo, (FARPROC*)&m_fnRasGetCountryInfo);
if (m_fnRasGetCountryInfo)
{
dwRet = (*m_fnRasGetCountryInfo) (lprci, lpdwSize);
}
return dwRet;
}
//+----------------------------------------------------------------------------
//
// Function: RNAAPI::RasSetEntryDialParams
//
// Synopsis: Softlink to RAS function
//
// Arguments: see RAS documentation
//
// Returns: see RAS documentation
//
// History: ChrisK Created 8/20/96
//
//-----------------------------------------------------------------------------
DWORD RNAAPI::RasSetEntryDialParams(LPCWSTR lpszPhonebook, LPRASDIALPARAMS lprasdialparams,
BOOL fRemovePassword)
{
DWORD dwRet = ERROR_DLL_NOT_FOUND;
// Look for the API if we haven't already found it
LoadApi(cszRasSetEntryDialParams, (FARPROC*)&m_fnRasSetEntryDialParams);
if (m_fnRasSetEntryDialParams)
{
dwRet = (*m_fnRasSetEntryDialParams) (lpszPhonebook, lprasdialparams,
fRemovePassword);
}
return dwRet;
}
/*******************************************************************
NAME: CreateConnectoid
SYNOPSIS: Creates a connectoid (phone book entry) with specified
name and phone number
ENTRY: pszConnectionName - name for the new connectoid
pszUserName - optional. If non-NULL, this will be set for the
user name in new connectoid
pszPassword - optional. If non-NULL, this will be set for the
password in new connectoid
EXIT: returns ERROR_SUCCESS if successful, or an RNA error code
HISTORY:
96/02/26 markdu Moved ClearConnectoidIPParams functionality
into CreateConnectoid
********************************************************************/
DWORD RNAAPI::CreateConnectoid(LPCWSTR pszPhonebook, LPCWSTR pszConnectionName,
LPRASENTRY lpRasEntry, LPCWSTR pszUserName, LPCWSTR pszPassword, LPBYTE lpDeviceInfo, LPDWORD lpdwDeviceInfoSize)
{
//DEBUGMSG(L"rnacall.c::CreateConnectoid()");
DWORD dwRet;
////Assert(pszConnectionName);
// if we don't have a valid RasEntry, bail
if ((NULL == lpRasEntry) || (sizeof(RASENTRY) != lpRasEntry->dwSize))
{
return ERROR_INVALID_PARAMETER;
}
// Enumerate the modems.
if (m_pEnumModem)
{
// Re-enumerate the modems to be sure we have the most recent changes
dwRet = m_pEnumModem->ReInit();
}
else
{
// The object does not exist, so create it.
m_pEnumModem = new CEnumModem;
if (m_pEnumModem)
{
dwRet = m_pEnumModem->GetError();
}
else
{
dwRet = ERROR_NOT_ENOUGH_MEMORY;
}
}
if (ERROR_SUCCESS != dwRet)
{
return dwRet;
}
// Make sure there is at least one device
if (0 == m_pEnumModem->GetNumDevices())
{
return ERROR_DEVICE_DOES_NOT_EXIST;
}
// Validate the device if possible
if (lstrlen(lpRasEntry->szDeviceName) && lstrlen(lpRasEntry->szDeviceType))
{
// Verify that there is a device with the given name and type
if (!m_pEnumModem->VerifyDeviceNameAndType(lpRasEntry->szDeviceName,
lpRasEntry->szDeviceType))
{
// There was no device that matched both name and type,
// so try to get the first device with matching name.
LPWSTR szDeviceType =
m_pEnumModem->GetDeviceTypeFromName(lpRasEntry->szDeviceName);
if (szDeviceType)
{
lstrcpy (lpRasEntry->szDeviceType, szDeviceType);
}
else
{
// There was no device that matched the given name,
// so try to get the first device with matching type.
// If this fails, fall through to recovery case below.
LPWSTR szDeviceName =
m_pEnumModem->GetDeviceNameFromType(lpRasEntry->szDeviceType);
if (szDeviceName)
{
lstrcpy (lpRasEntry->szDeviceName, szDeviceName);
}
else
{
// There was no device that matched the given name OR
// the given type. Reset the values so they will be
// replaced with the first device.
lpRasEntry->szDeviceName[0] = L'\0';
lpRasEntry->szDeviceType[0] = L'\0';
}
}
}
}
else if (lstrlen(lpRasEntry->szDeviceName))
{
// Only the name was given. Try to find a matching type.
// If this fails, fall through to recovery case below.
LPWSTR szDeviceType =
m_pEnumModem->GetDeviceTypeFromName(lpRasEntry->szDeviceName);
if (szDeviceType)
{
lstrcpy (lpRasEntry->szDeviceType, szDeviceType);
}
}
else if (lstrlen(lpRasEntry->szDeviceType))
{
// Only the type was given. Try to find a matching name.
// If this fails, fall through to recovery case below.
LPWSTR szDeviceName =
m_pEnumModem->GetDeviceNameFromType(lpRasEntry->szDeviceType);
if (szDeviceName)
{
lstrcpy (lpRasEntry->szDeviceName, szDeviceName);
}
}
// If either name or type is missing, just get first device.
// Since we already verified that there was at least one device,
// we can assume that this will succeed.
if(!lstrlen(lpRasEntry->szDeviceName) ||
!lstrlen(lpRasEntry->szDeviceType))
{
LPWSTR szDeviceName = m_pEnumModem->GetDeviceNameFromType(RASDT_Modem);
if (NULL != szDeviceName)
{
lstrcpyn(lpRasEntry->szDeviceType, RASDT_Modem, RAS_MaxDeviceType);
lstrcpyn(lpRasEntry->szDeviceName, szDeviceName, RAS_MaxDeviceName);
}
else
{
return ERROR_INETCFG_UNKNOWN;
}
}
lpRasEntry->dwType = EntryTypeFromDeviceType(lpRasEntry->szDeviceType);
// Verify the connectoid name
dwRet = RasValidateEntryName(pszPhonebook, pszConnectionName);
if ((ERROR_SUCCESS != dwRet) &&
(ERROR_ALREADY_EXISTS != dwRet))
{
//DEBUGMSG(L"RasValidateEntryName returned %lu", dwRet);
return dwRet;
}
// 96/04/07 markdu NASH BUG 15645
// If there is no area code string, and RASEO_UseCountryAndAreaCodes is not
// set, then the area code will be ignored so put in a default otherwise the
// call to RasSetEntryProperties will fail due to an RNA bug.
// if RASEO_UseCountryAndAreaCodes is set, then area code is required, so not
// having one is an error. Let RNA report the error.
if (!lstrlen(lpRasEntry->szAreaCode) &&
!(lpRasEntry->dwfOptions & RASEO_UseCountryAndAreaCodes))
{
lstrcpy (lpRasEntry->szAreaCode, szDefaultAreaCode);
}
lpRasEntry->dwfOptions |= RASEO_ModemLights;
// 96/05/14 markdu NASH BUG 22730 Work around RNA bug. Flags for terminal
// settings are swapped by RasSetEntryproperties, so we swap them before
// the call.
/*if (IsWin95())
SwapDWBits(&lpRasEntry->dwfOptions, RASEO_TerminalBeforeDial,
RASEO_TerminalAfterDial);*/
// call RNA to create the connectoid
////Assert(lpRasSetEntryProperties);
dwRet = RasSetEntryProperties(pszPhonebook, pszConnectionName,
(LPBYTE)lpRasEntry, sizeof(RASENTRY), NULL, 0);
// 96/05/14 markdu NASH BUG 22730 Work around RNA bug. Put the bits back
// to the way they were originally,
/*if (IsWin95())
SwapDWBits(&lpRasEntry->dwfOptions, RASEO_TerminalBeforeDial,
RASEO_TerminalAfterDial);*/
// populate the connectoid with user's account name and password.
if (dwRet == ERROR_SUCCESS)
{
if (pszUserName || pszPassword)
{
dwRet = SetConnectoidUsername(pszPhonebook, pszConnectionName,
pszUserName, pszPassword);
}
}
// RAS ATM (PPPOA) Integration: We have to set auxillary device properties!
if ( !lstrcmpi(lpRasEntry->szDeviceType, RASDT_Atm) ) {
if ( (lpDeviceInfo != 0) && (lpdwDeviceInfoSize != 0) && (*lpdwDeviceInfoSize > 0) )
{
LPATMPBCONFIG lpAtmConfig = (LPATMPBCONFIG) lpDeviceInfo;
LPBYTE lpBuffer = 0;
DWORD dwBufSize = 0;
DWORD dwRasEntrySize = sizeof(RASENTRY);
if (!m_fnRasSetEntryProperties)
LoadApi(cszRasSetEntryProperties, (FARPROC*)&m_fnRasSetEntryProperties);
if (!m_fnRasGetEntryProperties)
LoadApi(cszRasGetEntryProperties, (FARPROC*)&m_fnRasGetEntryProperties);
if (m_fnRasGetEntryProperties)
{
if (!(*m_fnRasGetEntryProperties)(pszPhonebook, pszConnectionName, (LPBYTE)lpRasEntry, &dwRasEntrySize, 0, &dwBufSize))
{
if ( dwBufSize )
{
if ( !(lpBuffer = (LPBYTE) malloc ( dwBufSize ) ))
{
return ERROR_NOT_ENOUGH_MEMORY;
}
else
{
memset ( lpBuffer, 0, dwBufSize );
}
if (!( (*m_fnRasGetEntryProperties) (pszPhonebook, pszConnectionName, (LPBYTE)lpRasEntry, &dwRasEntrySize, lpBuffer, &dwBufSize) ))
{
// buffer is now available. we now update its content.
LPWANPBCONFIG lpw = (LPWANPBCONFIG) lpBuffer;
assert ( lpw->cbDeviceSize == sizeof (ATMPBCONFIG) );
assert ( lpw->cbVendorSize == sizeof (ATMPBCONFIG) );
assert ( lpw->cbTotalSize <= dwBufSize );
memcpy ( lpBuffer+(lpw->dwDeviceOffset), lpDeviceInfo, sizeof(ATMPBCONFIG) );
memcpy ( lpBuffer+(lpw->dwVendorOffset), lpDeviceInfo, sizeof(ATMPBCONFIG) );
if ( m_fnRasSetEntryProperties )
{
(*m_fnRasSetEntryProperties)(pszPhonebook, pszConnectionName, (LPBYTE)lpRasEntry, sizeof(RASENTRY), lpBuffer, dwBufSize);
}
else
{
// free (lpBuffer);
// report error?
}
}
free (lpBuffer);
lpBuffer = NULL;
}
}
}
}
}
#ifndef _NT_ // BUGBUG: Should this be in Whistler?
if (dwRet == ERROR_SUCCESS)
{
// We don't use auto discovery for referral and signup connectoid
if (!m_bUseAutoProxyforConnectoid)
{
// VYUNG 12/16/1998
// REMOVE AUTO DISCOVERY FROM THE DIALUP CONNECTOID
INTERNET_PER_CONN_OPTION_LIST list;
DWORD dwBufSize = sizeof(list);
// fill out list struct
list.dwSize = sizeof(list);
WCHAR szConnectoid [RAS_MaxEntryName];
lstrcpyn(szConnectoid, pszConnectionName, lstrlen(pszConnectionName)+1);
list.pszConnection = szConnectoid;
list.dwOptionCount = 1; // one option
list.pOptions = new INTERNET_PER_CONN_OPTION[1];
if(list.pOptions)
{
// set flags
list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
list.pOptions[0].Value.dwValue = PROXY_TYPE_DIRECT; // no proxy, autoconfig url, or autodiscovery
// tell wininet
HINSTANCE hInst = NULL;
FARPROC fpInternetSetOption = NULL;
dwRet = ERROR_SUCCESS;
hInst = LoadLibrary(cszWininet);
if (hInst)
{
fpInternetSetOption = GetProcAddress(hInst, cszInternetSetOption);
if (fpInternetSetOption)
{
if( !((INTERNETSETOPTION)fpInternetSetOption) (NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize) )
{
dwRet = GetLastError();
//DEBUGMSG("INETCFG export.c::InetSetAutodial() InternetSetOption failed");
}
}
else
dwRet = GetLastError();
FreeLibrary(hInst);
}
delete [] list.pOptions;
}
}
}
#endif //_NT_
return dwRet;
}
/*******************************************************************
NAME: SetConnectoidUsername
SYNOPSIS: Set the username and password strings for the phonebook
entry name specified.
The RASCM_DefaultCreds bit makes this entry available to all users.
ENTRY: pszConnectoidName - phonebook entry name
pszUserName - string with user name
pszPassword - string with password
EXIT: Return value of GetEntryDialParams or SetEntryDialParams
********************************************************************/
DWORD RNAAPI::SetConnectoidUsername(
LPCWSTR pszPhonebook,
LPCWSTR pszConnectoidName,
LPCWSTR pszUserName,
LPCWSTR pszPassword
)
{
DWORD dwRet = ERROR_SUCCESS;
TRACE(L"rnacall.c::SetConnectoidUsername()");
MYASSERT(pszConnectoidName);
FARPROC fp = GetProcAddress(m_hInst, cszRasSetCredentials);
if (fp)
{
// fill in credential structure
RASCREDENTIALS rascred;
ZeroMemory(&rascred, sizeof(rascred));
rascred.dwSize = sizeof(rascred);
rascred.dwMask = RASCM_UserName
| RASCM_Password
| RASCM_Domain
| RASCM_DefaultCreds;
lstrcpyn(rascred.szUserName, pszUserName,UNLEN);
lstrcpyn(rascred.szPassword, pszPassword,PWLEN);
lstrcpyn(rascred.szDomain, L"",DNLEN);
dwRet = ((RASSETCREDENTIALS)fp)(NULL,
(LPWSTR)pszConnectoidName,
&rascred,
FALSE
);
TRACE1(L"RasSetCredentials returned, %lu", dwRet);
}
else
{
TRACE(L"RasSetCredentials api not found.");
}
return dwRet;
}
//*******************************************************************
//
// FUNCTION: InetConfigClientEx
//
// PURPOSE: This function requires a valid phone book entry name
// (unless it is being used just to set the client info).
// If lpRasEntry points to a valid RASENTRY struct, the phone
// book entry will be created (or updated if it already exists)
// with the data in the struct.
// If username and password are given, these
// will be set as the dial params for the phone book entry.
// If a client info struct is given, that data will be set.
// Any files (ie TCP and RNA) that are needed will be
// installed by calling InetConfigSystem().
// This function will also perform verification on the device
// specified in the RASENTRY struct. If no device is specified,
// the user will be prompted to install one if there are none
// installed, or they will be prompted to choose one if there
// is more than one installed.
//
// PARAMETERS: hwndParent - window handle of calling application. This
// handle will be used as the parent for any dialogs that
// are required for error messages or the "installing files"
// dialog.
// lpszPhonebook - name of phone book to store the entry in
// lpszEntryName - name of phone book entry to be
// created or modified
// lpRasEntry - specifies a RASENTRY struct that contains
// the phone book entry data for the entry lpszEntryName
// lpszUsername - username to associate with the phone book entry
// lpszPassword - password to associate with the phone book entry
// lpszProfileName - Name of client info profile to
// retrieve. If this is NULL, the default profile is used.
// lpINetClientInfo - client information
// dwfOptions - a combination of INETCFG_ flags that controls
// the installation and configuration as follows:
//
// INETCFG_INSTALLMAIL - install exchange and internet mail
// INETCFG_INSTALLMODEM - Invoke InstallModem wizard if NO
// MODEM IS INSTALLED. Note that if
// no modem is installed and this flag
// is not set, the function will fail
// INETCFG_INSTALLRNA - install RNA (if needed)
// INETCFG_INSTALLTCP - install TCP/IP (if needed)
// INETCFG_CONNECTOVERLAN - connecting with LAN (vs modem)
// INETCFG_SETASAUTODIAL - Set the phone book entry for autodial
// INETCFG_OVERWRITEENTRY - Overwrite the phone book entry if it
// exists. Note: if this flag is not
// set, and the entry exists, a unique
// name will be created for the entry.
// INETCFG_WARNIFSHARINGBOUND - Check if TCP/IP file sharing is
// turned on, and warn user to turn
// it off. Reboot is required if
// the user turns it off.
// INETCFG_REMOVEIFSHARINGBOUND - Check if TCP/IP file sharing is
// turned on, and force user to turn
// it off. If user does not want to
// turn it off, return will be
// ERROR_CANCELLED. Reboot is
// required if the user turns it off.
//
// lpfNeedsRestart - if non-NULL, then on return, this will be
// TRUE if windows must be restarted to complete the installation.
//
// RETURNS: HRESULT code, ERROR_SUCCESS if no errors occurred
//
// HISTORY:
// 96/03/11 markdu Created.
//
//*******************************************************************
HRESULT RNAAPI::InetConfigClientEx(
HWND hwndParent,
LPCWSTR lpszPhonebook,
LPCWSTR lpszEntryName,
LPRASENTRY lpRasEntry,
LPCWSTR lpszUsername,
LPCWSTR lpszPassword,
LPCWSTR lpszProfileName,
LPINETCLIENTINFO lpINetClientInfo,
DWORD dwfOptions,
LPBOOL lpfNeedsRestart,
LPWSTR szConnectoidName,
DWORD dwSizeOfCreatedEntryName,
LPBYTE lpDeviceInfo,
LPDWORD lpdwDeviceInfoSize)
{
BOOL fNeedsRestart = FALSE; // Default to no reboot needed
HWND hwndWaitDlg = NULL;
DWORD dwRet = ERROR_SUCCESS;
//DEBUGMSG(L"export.c::InetConfigClient()");
// Install files if needed.
// Note: the parent hwnd is validated in InetConfigSystem
// We must also mask out the InstallModem flag since we want to
// do that here, not in InetConfigSystem
/*
DWORD dwRet = InetConfigSystem(hwndParent,
dwfOptions & ~INETCFG_INSTALLMODEM, &fNeedsRestart);
if (ERROR_SUCCESS != dwRet)
{
return dwRet;
}*/
if (dwSizeOfCreatedEntryName < MAX_ISP_NAME + 1)
{
return E_FAIL;
}
// Make sure we have a connectoid name
if (lpszEntryName && lstrlen(lpszEntryName))
{
// Copy the name into a private buffer in case we have
// to muck around with it
lstrcpyn(szConnectoidName, lpszEntryName, dwSizeOfCreatedEntryName);
// Make sure the name is valid.
dwRet = RasValidateEntryName(lpszPhonebook, szConnectoidName);
if ((ERROR_SUCCESS == dwRet) ||
(ERROR_ALREADY_EXISTS == dwRet))
{
// Find out if we can overwrite an existing connectoid
if (!(dwfOptions & INETCFG_OVERWRITEENTRY) && (ERROR_ALREADY_EXISTS == dwRet))
{
WCHAR szConnectoidNameBase[MAX_ISP_NAME + 1];
// Create a base string that is truncated to leave room for a space
// and a 3-digit number to be appended. So, the buffer size will be
// MAX_ISP_NAME + 1 - (LEN_APPEND_INT + 1)
lstrcpyn(szConnectoidNameBase, szConnectoidName,
MAX_ISP_NAME - LEN_APPEND_INT);
// If the entry exists, we have to create a unique name
int nSuffix = 2;
while ((ERROR_ALREADY_EXISTS == dwRet) && (nSuffix < MAX_APPEND_INT))
{
// Add the integer to the end of the base string and then bump it
wsprintf(szConnectoidName, szFmtAppendIntToString,
szConnectoidNameBase, nSuffix++);
// Validate this new name
dwRet = RasValidateEntryName(lpszPhonebook, szConnectoidName);
}
// If we could not create a unique name, bail
// Note that dwRet should still be ERROR_ALREADY_EXISTS in this case
if (nSuffix >= MAX_APPEND_INT)
{
return dwRet;
}
}
if (lpRasEntry && lpRasEntry->dwSize == sizeof(RASENTRY))
{
// For NT 5 and greater, File sharing is disabled per connectoid by setting this RAS option.
//if (TRUE == IsNT5())
//{
// lpRasEntry->dwfOptions |= RASEO_SecureLocalFiles;
//}
// Create a connectoid with given properties
dwRet = MakeConnectoid(hwndParent, dwfOptions, lpszPhonebook,
szConnectoidName, lpRasEntry, lpszUsername, lpszPassword, &fNeedsRestart, lpDeviceInfo, lpdwDeviceInfoSize);
}
else if ((lpszUsername && lstrlen(lpszUsername)) ||
(lpszPassword && lstrlen(lpszPassword)))
{
// If we created a connectoid, we already updated the dial params
// with the user name and password. However, if we didn't create a
// connectoid we still may need to update dial params of an existing one
// Update the dial params for the given connectoid.
dwRet = SetConnectoidUsername(lpszPhonebook, szConnectoidName,
lpszUsername, lpszPassword);
}
// If the connectoid was created/updated successfully, see
// if it is supposed to be set as the autodial connectoid.
if ((ERROR_SUCCESS == dwRet) && (dwfOptions & INETCFG_SETASAUTODIAL))
{
// dwRet = InetSetAutodial((DWORD)TRUE, szConnectoidName);
}
}
}
// Now set the client info if provided and no errors have occurred yet.
if (ERROR_SUCCESS == dwRet)
{
if (NULL != lpINetClientInfo)
{
dwRet = InetSetClientInfo(lpszProfileName, lpINetClientInfo);
if (ERROR_SUCCESS != dwRet)
{
if (NULL != hwndWaitDlg)
DestroyWindow(hwndWaitDlg);
hwndWaitDlg = NULL;
return dwRet;
}
// update IE news settings
dwRet = SetIEClientInfo(lpINetClientInfo);
if (ERROR_SUCCESS != dwRet)
{
if (NULL != hwndWaitDlg)
DestroyWindow(hwndWaitDlg);
hwndWaitDlg = NULL;
return dwRet;
}
}
// Now update the mail client if we were asked to do so.
// Note: if we got here without errors, and INETCFG_INSTALLMAIL is set,
// then mail has been installed by now.
if (dwfOptions & INETCFG_INSTALLMAIL)
{
INETCLIENTINFO INetClientInfo;
ZeroMemory(&INetClientInfo, sizeof(INETCLIENTINFO));
INetClientInfo.dwSize = sizeof(INETCLIENTINFO);
// Use a temp pointer that we can modify.
LPINETCLIENTINFO lpTmpINetClientInfo = lpINetClientInfo;
// If no client info struct was given, try to get the profile by name
if ((NULL == lpTmpINetClientInfo) && (NULL != lpszProfileName) &&
lstrlen(lpszProfileName))
{
lpTmpINetClientInfo = &INetClientInfo;
dwRet = InetGetClientInfo(lpszProfileName, lpTmpINetClientInfo);
if (ERROR_SUCCESS != dwRet)
{
if (NULL != hwndWaitDlg)
DestroyWindow(hwndWaitDlg);
hwndWaitDlg = NULL;
return dwRet;
}
}
// If we still don't have client info, we should enumerate the profiles
// If there is one profile, get it. If multiple, show UI to allow user
// to choose. If none, there is nothing to do at this point.
// For now, we don't support enumeration, so just try to get the default.
if (NULL == lpTmpINetClientInfo)
{
lpTmpINetClientInfo = &INetClientInfo;
dwRet = InetGetClientInfo(NULL, lpTmpINetClientInfo);
if (ERROR_SUCCESS != dwRet)
{
if (NULL != hwndWaitDlg)
DestroyWindow(hwndWaitDlg);
hwndWaitDlg = NULL;
return dwRet;
}
}
// If we have client info, update mail settings.
if (NULL != lpTmpINetClientInfo)
{
dwRet = UpdateMailSettings(hwndParent, lpTmpINetClientInfo, szConnectoidName);
}
}
}
// tell caller whether we need to reboot or not
if ((ERROR_SUCCESS == dwRet) && (lpfNeedsRestart))
{
*lpfNeedsRestart = fNeedsRestart;
}
if (NULL != hwndWaitDlg)
DestroyWindow(hwndWaitDlg);
hwndWaitDlg = NULL;
return dwRet;
}
//*******************************************************************
//
// FUNCTION: MakeConnectoid
//
// PURPOSE: This function will create a connectoid with the
// supplied name if lpRasEntry points to a valid RASENTRY
// struct. If username and password are given, these
// will be set as the dial params for the connectoid.
//
// PARAMETERS:
// hwndParent - window handle of calling application. This
// handle will be used as the parent for any dialogs that
// are required for error messages or the "choose modem"
// dialog.
// dwfOptions - a combination of INETCFG_ flags that controls
// the installation and configuration.
// lpszPhonebook - name of phone book to store the entry in
// lpszEntryName - name of connectoid to create/modify
// lpRasEntry - connectoid data
// lpszUsername - username to associate with connectoid
// lpszPassword - password to associate with connectoid
// lpfNeedsRestart - set to true if we need a restart. Note that
// since this is an internal helper function, we
// assume that the pointer is valid, and we don't
// initialize it (we only touch it if we are setting
// it to TRUE).
//
// RETURNS: HRESULT code, ERROR_SUCCESS if no errors occurred
//
// HISTORY:
// 96/03/12 markdu Created.
//
//*******************************************************************
DWORD RNAAPI::MakeConnectoid(
HWND hwndParent,
DWORD dwfOptions,
LPCWSTR lpszPhonebook,
LPCWSTR lpszEntryName,
LPRASENTRY lpRasEntry,
LPCWSTR lpszUsername,
LPCWSTR lpszPassword,
LPBOOL lpfNeedsRestart,
LPBYTE lpDeviceInfo,
LPDWORD lpdwDeviceInfoSize)
{
DWORD dwRet;
//ASSERT(lpfNeedsRestart);
if (dwfOptions & RASEO_UseCountryAndAreaCodes)
{
if ((0 == lpRasEntry->dwCountryCode) || (0 == lpRasEntry->dwCountryID))
return ERROR_INVALID_PARAMETER;
}
if (0 == lstrlen(lpRasEntry->szLocalPhoneNumber))
{
return ERROR_INVALID_PARAMETER;
}
// Load RNA if not already loaded since ENUM_MODEM needs it.
/*dwRet = EnsureRNALoaded();
if (ERROR_SUCCESS != dwRet)
{
return dwRet;
}*/
//
// Enumerate the modems
//
CEnumModem EnumModem;
dwRet = EnumModem.GetError();
if (ERROR_SUCCESS != dwRet)
{
return dwRet;
}
// If there are no modems, install one if requested.
if (0 == EnumModem.GetNumDevices())
{
// We have not been asked to install a modem, so there
// is nothing further we can do.
return ERROR_INVALID_PARAMETER;
/*
if (FALSE == IsNT())
{
//
// 5/22/97 jmazner Olympus #4698
// On Win95, calling RasEnumDevices launches RNAAP.EXE
// If RNAAP.EXE is running, any modems you install won't be usable
// So, nuke RNAAP.EXE before installing the modem.
//
WCHAR szWindowTitle[255] = L"\0nogood";
//
// Unload the RAS dll's before killing RNAAP, just to be safe
//
DeInitRNA();
LoadSz(IDS_RNAAP_TITLE, szWindowTitle,255);
HWND hwnd = FindWindow(szWindowTitle, NULL);
if (NULL != hwnd)
{
if (!PostMessage(hwnd, WM_CLOSE, 0, 0))
{
DEBUGMSG(L"Trying to kill RNAAP window returned getError %d", GetLastError());
}
}
}*/
}
// Validate the device if possible
if (lstrlen(lpRasEntry->szDeviceName) && lstrlen(lpRasEntry->szDeviceType))
{
// Verify that there is a device with the given name and type
if (!EnumModem.VerifyDeviceNameAndType(lpRasEntry->szDeviceName,
lpRasEntry->szDeviceType))
{
// There was no device that matched both name and type,
// so reset the strings and bring up the choose modem UI.
lpRasEntry->szDeviceName[0] = L'\0';
lpRasEntry->szDeviceType[0] = L'\0';
}
}
else if (lstrlen(lpRasEntry->szDeviceName))
{
// Only the name was given. Try to find a matching type.
// If this fails, fall through to recovery case below.
LPWSTR szDeviceType =
EnumModem.GetDeviceTypeFromName(lpRasEntry->szDeviceName);
if (szDeviceType)
{
lstrcpy (lpRasEntry->szDeviceType, szDeviceType);
}
}
else if (lstrlen(lpRasEntry->szDeviceType))
{
// Only the type was given. Try to find a matching name.
// If this fails, fall through to recovery case below.
LPWSTR szDeviceName =
EnumModem.GetDeviceNameFromType(lpRasEntry->szDeviceType);
if (szDeviceName)
{
lstrcpy (lpRasEntry->szDeviceName, szDeviceName);
}
}
// If either name or type is missing, bring up choose modem UI if there
// are multiple devices, else just get first device.
// Since we already verified that there was at least one device,
// we can assume that this will succeed.
// If either name or type is missing at this point, fall back to the modem
// that is enumerated first. If no modem is enumerated, return an error.
//
if(!lstrlen(lpRasEntry->szDeviceName) ||
!lstrlen(lpRasEntry->szDeviceType))
{
LPWSTR szDeviceName = EnumModem.GetDeviceNameFromType(RASDT_Modem);
if (NULL != szDeviceName)
{
lstrcpyn(lpRasEntry->szDeviceType, RASDT_Modem, RAS_MaxDeviceType);
lstrcpyn(lpRasEntry->szDeviceName, szDeviceName, RAS_MaxDeviceName);
}
else
{
return ERROR_INETCFG_UNKNOWN;
}
}
// Create a connectoid with given properties
dwRet = CreateConnectoid(lpszPhonebook, lpszEntryName, lpRasEntry,
lpszUsername, lpszPassword, lpDeviceInfo, lpdwDeviceInfoSize);
return dwRet;
}
//+----------------------------------------------------------------------------
//
// Function LclSetEntryScriptPatch
//
// Synopsis Softlink to RasSetEntryPropertiesScriptPatch
//
// Arguments see RasSetEntryPropertiesScriptPatch
//
// Returns see RasSetEntryPropertiesScriptPatch
//
// Histroy 10/3/96 ChrisK Created
//
//-----------------------------------------------------------------------------
//typedef BOOL (WINAPI* LCLSETENTRYSCRIPTPATCH)(LPWSTR, LPWSTR);
/*
BOOL RNAAPI::LclSetEntryScriptPatch(LPCWSTR lpszScript, LPCWSTR lpszEntry)
{
HINSTANCE hinst = NULL;
LCLSETENTRYSCRIPTPATCH fp = NULL;
BOOL bRC = FALSE;
hinst = LoadLibrary(L"ICWDIAL.DLL");
if (hinst)
{
fp = (LCLSETENTRYSCRIPTPATCH)GetProcAddress(hinst, L"RasSetEntryPropertiesScriptPatch");
if (fp)
bRC = (fp)(lpszScript, lpszEntry);
FreeLibrary(hinst);
hinst = NULL;
fp = NULL;
}
return bRC;
}
*/
//+----------------------------------------------------------------------------
//
// Function RemoveOldScriptFilenames
//
// Synopsis Given the data returned from a call to GetPrivateProfileSection
// remove any information about existing script file so that
// we can replace it with the new script information.
//
// Arguments lpszData - pointer to input data
//
// Returns TRUE - success
// lpdwSize - size of resulting data
//
// History 10/2/96 ChrisK Created
//
//-----------------------------------------------------------------------------
static BOOL RemoveOldScriptFilenames(LPWSTR lpszData, LPDWORD lpdwSize)
{
BOOL bRC = FALSE;
LPWSTR lpszTemp = lpszData;
LPWSTR lpszCopyTo = lpszData;
INT iLen = 0;
//
// Walk through list of name value pairs
//
if (!lpszData || L'\0' == lpszData[0])
goto RemoveOldScriptFilenamesExit;
while (*lpszTemp) {
if (0 != lstrcmpi(lpszTemp, cszDeviceSwitch))
{
//
// Keep pairs that don't match criteria
//
iLen = BYTES_REQUIRED_BY_SZ(lpszTemp);
if (lpszCopyTo != lpszTemp)
{
memmove(lpszCopyTo, lpszTemp, iLen+1);
}
lpszCopyTo += iLen + 1;
lpszTemp += iLen + 1;
}
else
{
//
// Skip the pair that matches and the one after that
//
lpszTemp += lstrlen(lpszTemp) + 1;
if (*lpszTemp)
lpszTemp += lstrlen(lpszTemp) + 1;
}
}
//
// Add second trailing NULL
//
*lpszCopyTo = L'\0';
//
// Return new size
// Note the size does not include the final \0
//
*lpdwSize = (DWORD)(lpszCopyTo - lpszData);
bRC = TRUE;
RemoveOldScriptFilenamesExit:
return bRC;
}
//+----------------------------------------------------------------------------
//
// Function GleanRealScriptFileName
//
// Synopsis Given a string figure out the real filename
// Due to another NT4.0 Ras bug, script filenames returned by
// RasGetEntryProperties may contain a leading garbage character
//
// Arguments lppszOut - pointer that will point to real filename
// lpszIn - points to current filename
//
// Returns TRUE - success
// *lppszOut - points to real file name, remember to free the memory
// in this variable when you are done. And don't talk with
// your mouth full - mom.
//
// History 10/2/96 ChrisK Created
//
//-----------------------------------------------------------------------------
static BOOL GleanRealScriptFileName(LPWSTR *lppszOut, LPWSTR lpszIn)
{
BOOL bRC = FALSE;
LPWSTR lpsz = NULL;
DWORD dwRet = 0;
//
// Validate parameters
//
//Assert(lppszOut && lpszIn);
if (!(lppszOut && lpszIn))
goto GleanFilenameExit;
//
// first determine if the filename is OK as is
//
dwRet = GetFileAttributes(lpszIn);
if (L'\0' != lpszIn[0] && 0xFFFFFFFF == dwRet) // Empty filename is OK
{
//
// Check for the same filename without the first character
//
lpsz = lpszIn+1;
dwRet = GetFileAttributes(lpsz);
if (0xFFFFFFFF == dwRet)
goto GleanFilenameExit;
}
else
{
lpsz = lpszIn;
}
//
// Return filename
//
*lppszOut = (LPWSTR)GlobalAlloc(GPTR, BYTES_REQUIRED_BY_SZ(lpsz));
lstrcpy(*lppszOut, lpsz);
bRC = TRUE;
GleanFilenameExit:
return bRC;
}
//+----------------------------------------------------------------------------
//
// Function IsScriptPatchNeeded
//
// Synopsis Check version to see if patch is needed
//
// Arguments lpszData - contents of section in rasphone.pbk
// lpszScript - name of script file
//
// Returns TRUE - patch is needed
//
// Histroy 10/1/96
//
//-----------------------------------------------------------------------------
static BOOL IsScriptPatchNeeded(LPWSTR lpszData, LPWSTR lpszScript)
{
BOOL bRC = FALSE;
LPWSTR lpsz = lpszData;
WCHAR szType[MAX_PATH + MAX_CHARS_IN_BUFFER(cszType) + 1];
lstrcpy(szType, cszType);
lstrcat(szType, lpszScript);
//Assert(MAX_PATH + MAX_CHARS_IN_BUFFER(cszType) +1 > lstrlen(szType));
lpsz = lpszData;
while(*lpsz)
{
if (0 == lstrcmp(lpsz, cszDeviceSwitch))
{
lpsz += lstrlen(lpsz)+1;
// if we find a DEVICE=switch statement and the script is empty
// then we'll have to patch the entry
if (0 == lpszScript[0])
bRC = TRUE;
// if we find a DEVICE=switch statement and the script is different
// then we'll have to patch the entry
else if (0 != lstrcmp(lpsz, szType))
bRC = TRUE;
// if we find a DEVICE=switch statement and the script is the same
// then we DON'T have to patch it
else
bRC = FALSE;
break; // get out of while statement
}
lpsz += lstrlen(lpsz)+1;
}
if (L'\0' == *lpsz)
{
// if we didn't find DEVICE=switch statement and the script is empty
// then we DON'T have to patch it
if (L'\0' == lpszScript[0])
bRC = FALSE;
// if we didn't find DEVICE=switch statement and the script is not
// empty the we'll have to patch it.
else
bRC = TRUE;
}
return bRC;
}
//+----------------------------------------------------------------------------
//
// Function GetRasPBKFilename
//
// Synopsis Find the Ras phone book and return the fully qualified path
// in the buffer
//
// Arguments lpBuffer - pointer to buffer
// dwSize - size of buffer (must be at least MAX_PATH)
//
// Returns TRUE - success
//
// History 10/1/96 ChrisK Created
//
//-----------------------------------------------------------------------------
static BOOL GetRasPBKFilename(LPWSTR lpBuffer, DWORD dwSize)
{
BOOL bRC = FALSE;
UINT urc = 0;
LPWSTR lpsz = NULL;
//
// Validate parameters
//
//Assert(lpBuffer && (dwSize >= MAX_PATH));
//
// Get path to system directory
//
urc = GetSystemDirectory(lpBuffer, dwSize);
if (0 == urc || urc > dwSize)
goto GetRasPBKExit;
//
// Check for trailing '\' and add \ras\rasphone.pbk to path
//
lpsz = &lpBuffer[lstrlen(lpBuffer)-1];
if (L'\\' != *lpsz)
lpsz++;
lstrcpy(lpsz, cszRasPBKFilename);
bRC = TRUE;
GetRasPBKExit:
return bRC;
}
//+----------------------------------------------------------------------------
//
// Function RasSetEntryPropertiesScriptPatch
//
// Synopsis Work around bug in NT4.0 that does not save script file names
// to RAS phone book entries
//
// Arguments lpszScript - name of script file
// lpszEntry - name of phone book entry
//
// Returns TRUE - success
//
// Histroy 10/1/96 ChrisK Created
//
//-----------------------------------------------------------------------------
BOOL WINAPI RasSetEntryPropertiesScriptPatch(LPWSTR lpszScript, LPCWSTR lpszEntry)
{
BOOL bRC = FALSE;
WCHAR szRasPBK[MAX_PATH+1];
WCHAR szData[SCRIPT_PATCH_BUFFER_SIZE];
DWORD dwrc = 0;
LPWSTR lpszTo;
LPWSTR lpszFixedFilename = NULL;
//
// Validate parameters
//
//Assert(lpszScript && lpszEntry);
//TraceMsg(TF_GENERAL, L"ICWDIAL: ScriptPatch script %s, entry %s.\r\n", lpszScript, lpszEntry);
//
// Verify and fix filename
//
if (!GleanRealScriptFileName(&lpszFixedFilename, lpszScript))
goto ScriptPatchExit;
//
// Get the path to the RAS phone book
//
if (!GetRasPBKFilename(szRasPBK, MAX_PATH+1))
goto ScriptPatchExit;
//
// Get data
//
ZeroMemory(szData, SCRIPT_PATCH_BUFFER_SIZE);
dwrc = GetPrivateProfileSection(lpszEntry, szData,SCRIPT_PATCH_BUFFER_SIZE,szRasPBK);
if (SCRIPT_PATCH_BUFFER_SIZE == (dwrc + 2))
goto ScriptPatchExit;
//
// Verify version
//
if (!IsScriptPatchNeeded(szData, lpszFixedFilename))
{
bRC = TRUE;
goto ScriptPatchExit;
}
//
// Clean up data
//
RemoveOldScriptFilenames(szData, &dwrc);
//
// Make sure there is enough space left to add new data
//
if (SCRIPT_PATCH_BUFFER_SIZE <=
(dwrc + sizeof(cszDeviceSwitch) + SIZEOF_NULL + MAX_CHARS_IN_BUFFER(cszType) + MAX_PATH))
goto ScriptPatchExit;
//
// Add data
//
if (L'\0' != lpszFixedFilename[0])
{
lpszTo = &szData[dwrc];
lstrcpy(lpszTo, cszDeviceSwitch);
lpszTo += MAX_CHARS_IN_BUFFER(cszDeviceSwitch);
lstrcpy(lpszTo, cszType);
lpszTo += MAX_CHARS_IN_BUFFER(cszType) - 1;
lstrcpy(lpszTo, lpszFixedFilename);
lpszTo += lstrlen(lpszFixedFilename) + SIZEOF_NULL;
*lpszTo = L'\0'; // extra terminating NULL
//Assert(&lpszTo[SIZEOF_NULL]<&szData[SCRIPT_PATCH_BUFFER_SIZE]);
}
//
// Write data
//
bRC = WritePrivateProfileSection(lpszEntry, szData,szRasPBK);
ScriptPatchExit:
if (lpszFixedFilename)
GlobalFree(lpszFixedFilename);
lpszFixedFilename = NULL;
//if (!bRC)
// TraceMsg(TF_GENERAL, L"ICWDIAL: ScriptPatch failed.\r\n");
return bRC;
}
//+----------------------------------------------------------------------------
//
// Function LclSetEntryScriptPatch
//
// Synopsis Softlink to RasSetEntryPropertiesScriptPatch
//
// Arguments see RasSetEntryPropertiesScriptPatch
//
// Returns see RasSetEntryPropertiesScriptPatch
//
// Histroy 10/3/96 ChrisK Created
//
//-----------------------------------------------------------------------------
typedef BOOL (WINAPI* LCLSETENTRYSCRIPTPATCH)(LPCWSTR, LPCWSTR);
BOOL LclSetEntryScriptPatch(LPWSTR lpszScript, LPCWSTR lpszEntry)
{
return RasSetEntryPropertiesScriptPatch(lpszScript, lpszEntry);
}
//*******************************************************************
//
// FUNCTION: UpdateMailSettings
//
// PURPOSE: This function will update the settings for mail in
// the profile of the user's choice.
//
// PARAMETERS: hwndParent - window handle of calling application. This
// handle will be used as the parent for any dialogs that
// are required for error messages or the "choose profile"
// dialog.
// lpINetClientInfo - client information
// lpszEntryName - name of phone book entry to be
// set for connection.
//
// RETURNS: HRESULT code, ERROR_SUCCESS if no errors occurred
//
// HISTORY:
// 96/03/26 markdu Created.
//
//*******************************************************************
HRESULT UpdateMailSettings(
HWND hwndParent,
LPINETCLIENTINFO lpINetClientInfo,
LPWSTR lpszEntryName)
{
DWORD dwRet = ERROR_SUCCESS;
MAILCONFIGINFO MailConfigInfo;
ZeroMemory(&MailConfigInfo, sizeof(MAILCONFIGINFO)); // zero out structure
// 96/04/06 markdu NASH BUG 16404
// Funcionts in mapicall.c expect us to allocate global structure
// call MAPI to set up profile and store this information in it
if (InitMAPI(NULL))
{
// structure to pass to dialog to fill out
CHOOSEPROFILEDLGINFO ChooseProfileDlgInfo;
ZeroMemory(&ChooseProfileDlgInfo, sizeof(CHOOSEPROFILEDLGINFO));
ChooseProfileDlgInfo.fSetProfileAsDefault = TRUE;
// 96/04/25 markdu NASH BUG 19572 Only show choose profile dialog
// if there are any existing profiles,
// 99/2/18 Remove multi profile dialog for OOBE
// set up a structure with mail config information
MailConfigInfo.pszEmailAddress = lpINetClientInfo->szEMailAddress;
MailConfigInfo.pszEmailServer = lpINetClientInfo->szPOPServer;
MailConfigInfo.pszEmailDisplayName = lpINetClientInfo->szEMailName;
MailConfigInfo.pszEmailAccountName = lpINetClientInfo->szPOPLogonName;
MailConfigInfo.pszEmailAccountPwd = lpINetClientInfo->szPOPLogonPassword;
MailConfigInfo.pszConnectoidName = lpszEntryName;
MailConfigInfo.fRememberPassword = TRUE;
MailConfigInfo.pszProfileName = ChooseProfileDlgInfo.szProfileName;
MailConfigInfo.fSetProfileAsDefault = ChooseProfileDlgInfo.fSetProfileAsDefault;
// BUGBUG SMTP
// set up the profile through MAPI
dwRet = SetMailProfileInformation(&MailConfigInfo);
// Hide error messages for OOBE
/*
if (ERROR_SUCCESS != dwRet)
{
DisplayErrorMessage(hwndParent, IDS_ERRConfigureMail,
(DWORD) dwRet, ERRCLS_MAPI,MB_ICONEXCLAMATION);
}*/
DeInitMAPI();
}
else
{
// an error occurred.
dwRet = GetLastError();
if (ERROR_SUCCESS == dwRet)
{
// Error occurred, but the error code was not set.
dwRet = ERROR_INETCFG_UNKNOWN;
}
}
return dwRet;
}
DWORD EntryTypeFromDeviceType(
LPCWSTR szDeviceType
)
{
DWORD dwType;
MYASSERT(
!lstrcmpi(RASDT_PPPoE, szDeviceType) ||
!lstrcmpi(RASDT_Atm, szDeviceType) ||
!lstrcmpi(RASDT_Isdn, szDeviceType) ||
!lstrcmpi(RASDT_Modem, szDeviceType)
);
if (lstrcmpi(RASDT_PPPoE, szDeviceType) == 0)
{
dwType = RASET_Broadband;
}
else
{
dwType = RASET_Phone;
}
return dwType;
}