/*----------------------------------------------------------------------------- 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 #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; }