You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6251 lines
169 KiB
6251 lines
169 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
autodial.cxx
|
|
|
|
Abstract:
|
|
|
|
Contains the implementation of autodial
|
|
|
|
Contents:
|
|
|
|
Author:
|
|
|
|
Darren Mitchell (darrenmi) 22-Apr-1997
|
|
|
|
Environment:
|
|
|
|
Win32(s) user-mode DLL
|
|
|
|
Revision History:
|
|
|
|
22-Apr-1997 darrenmi
|
|
Created
|
|
|
|
|
|
--*/
|
|
|
|
#include "wininetp.h"
|
|
#include "autodial.h"
|
|
#include "rashelp.h"
|
|
#include <sensapi.h>
|
|
#include <winsvc.h>
|
|
#include <commctrl.h>
|
|
#include "millenras.h"
|
|
#include <iphlpapi.h>
|
|
|
|
// Globals.
|
|
// In IE4 - there are several situations when these globals are
|
|
// accessed simultaneously by different threads and so we need to protect them
|
|
// with a mutex
|
|
|
|
//
|
|
// fDontProcessHook - set to TRUE in the following circumstances:
|
|
//
|
|
// - autodial is not enabled
|
|
// - loading the ras dll failed
|
|
// - no modem is installed
|
|
//
|
|
// this flag is only relevant on Win95.
|
|
//
|
|
BOOL fDontProcessHook = FALSE;
|
|
|
|
DWORD g_dwLastTickCount = 0;
|
|
|
|
// g_hwndWebCheck is currently not protected with a mutex
|
|
HWND g_hwndWebCheck = NULL; // instead of findwindow every time
|
|
|
|
// have we already checked out the current connection for proxy change?
|
|
BOOL g_fConnChecked = FALSE;
|
|
|
|
// serialize GetConnectedState
|
|
HANDLE g_hConnectionMutex = INVALID_HANDLE_VALUE;
|
|
|
|
// serialize access to RAS
|
|
HANDLE g_hRasMutex = INVALID_HANDLE_VALUE;
|
|
|
|
// serialize access to proxy reg settings
|
|
HANDLE g_hProxyRegMutex = INVALID_HANDLE_VALUE;
|
|
|
|
|
|
// Have we upgraded settings?
|
|
BOOL g_fCheckedUpgrade = FALSE;
|
|
|
|
// should we ask user to go offline if no connect?
|
|
BOOL g_fAskOffline = TRUE;
|
|
|
|
// Don't do any callbacks in rnaapp.exe process
|
|
BOOL g_fRNAAppProcess = FALSE;
|
|
|
|
// We use native font control from comctl so we need to call initcommoncontrols
|
|
HMODULE hCommctrl = NULL;
|
|
typedef BOOL (WINAPI *PFNINITCOMMONCONTROLS)(LPINITCOMMONCONTROLSEX);
|
|
|
|
// base key for settings, lives in proxreg.cxx
|
|
extern CRefdKey* g_prkBase;
|
|
|
|
//
|
|
// Enable sens network checking
|
|
//
|
|
#ifndef UNIX
|
|
/* On Unix we assume we are on a LAN all the time */
|
|
#define CHECK_SENS 1
|
|
#endif /* UNIX */
|
|
|
|
#ifdef CHECK_SENS
|
|
|
|
// prototype for IsNetworkAlive()
|
|
typedef BOOL (WINAPI *ISNETWORKALIVE)(LPDWORD);
|
|
|
|
// handle to sens dll and entry point
|
|
BOOL g_fSensInstalled = TRUE;
|
|
HINSTANCE g_hSens = NULL;
|
|
ISNETWORKALIVE g_pfnIsNetworkAlive = NULL;
|
|
|
|
// how often to call sens to check state? Every 15 seconds seems reasonable
|
|
#define MIN_SENS_CHECK_INTERVAL 15000
|
|
DWORD g_dwLastSensCheck = 0;
|
|
|
|
// message we send to dialmon to find out if sens is loaded
|
|
#define WM_IS_SENSLCE_LOADED (WM_USER+201)
|
|
#endif
|
|
|
|
// registry strings
|
|
const CHAR szRegPathRemoteAccess[] = REGSTR_PATH_REMOTEACCESS;
|
|
const CHAR szRegPathInternetSettings[] = REGSTR_PATH_INTERNET_SETTINGS;
|
|
const CHAR szRegValEnableAutodial[] = REGSTR_VAL_ENABLEAUTODIAL;
|
|
const CHAR szRegValInternetEntry[] = REGSTR_VAL_INTERNETPROFILE;
|
|
const CHAR szRegValUnattended[] = REGSTR_VAL_ENABLEUNATTENDED;
|
|
static const CHAR szRegPathRNAProfile[] = REGSTR_PATH_REMOTEACCESS "\\Profile";
|
|
static const CHAR szRegValAutodialDllName[] = REGSTR_VAL_AUTODIALDLLNAME;
|
|
static const CHAR szRegValAutodialFcnName[] = REGSTR_VAL_AUTODIALFCNNAME;
|
|
static const CHAR szRegValAutodialFlags[] = "HandlerFlags";
|
|
static const CHAR szRegPathRNAService[] = REGSTR_PATH_SERVICES "\\RemoteAccess";
|
|
static const CHAR szRegAddresses[] = "RemoteAccess\\Addresses";
|
|
static const CHAR szRegPathTCP[] = REGSTR_PATH_VXD "\\MSTCP";
|
|
static const CHAR szRegValRemoteConnection[] = "Remote Connection";
|
|
static const CHAR szRegValHostName[] = "HostName";
|
|
static const CHAR szInetPerformSecurityCheck[] = "InetPerformSecurityCheck";
|
|
static const CHAR szRegValEnableSecurityCheck[] = REGSTR_VAL_ENABLESECURITYCHECK;
|
|
static const CHAR szAutodialMonitorClass[] = REGSTR_VAL_AUTODIAL_MONITORCLASSNAME;
|
|
static const CHAR szWebCheckMonitorClass[] = "MS_WebCheckMonitor";
|
|
static const CHAR szRegPathComputerName[] = REGSTR_PATH_COMPUTRNAME;
|
|
static const CHAR szRegValComputerName[] = REGSTR_VAL_COMPUTRNAME;
|
|
static const CHAR szMigrateProxy[] = "MigrateProxy";
|
|
static const CHAR szProxySuspect[] = "ProxySuspect";
|
|
static const CHAR szCMDllName[] = "cmdial32.dll";
|
|
|
|
// wide version of various registry strings
|
|
#define TSZMICROSOFTPATHW L"Software\\Microsoft"
|
|
#define TSZIEPATHW TSZMICROSOFTPATHW L"\\Internet Explorer"
|
|
#define TSZWINCURVERPATHW TSZMICROSOFTPATHW L"\\windows\\CurrentVersion"
|
|
#define TSZWININETPATHW TSZWINCURVERPATHW L"\\Internet Settings"
|
|
|
|
#define REGSTR_PATH_INTERNETSETTINGSW TSZWININETPATHW
|
|
#define REGSTR_PATH_INTERNET_LAN_SETTINGSW REGSTR_PATH_INTERNETSETTINGSW L"\\LAN"
|
|
#define REGSTR_DIAL_AUTOCONNECTW L"AutoConnect"
|
|
#define REGSTR_VAL_COVEREXCLUDEW L"CoverExclude"
|
|
#define REGSTR_VAL_REDIALATTEMPTSW L"RedialAttempts"
|
|
#define REGSTR_VAL_REDIALINTERVALW L"RedialWait"
|
|
#define REGSTR_VAL_INTERNETENTRYW L"InternetProfile"
|
|
#define REGSTR_VAL_INTERNETPROFILEW REGSTR_VAL_INTERNETENTRYW
|
|
#define REGSTR_PATH_REMOTEACCESSW L"RemoteAccess"
|
|
#define REGSTR_VAL_AUTODIALDLLNAMEW L"AutodialDllName"
|
|
#define REGSTR_VAL_AUTODIALFCNNAMEW L"AutodialFcnName"
|
|
|
|
const WCHAR szRegValInternetEntryW[] = REGSTR_VAL_INTERNETPROFILEW;
|
|
const WCHAR szRegPathRemoteAccessW[] = REGSTR_PATH_REMOTEACCESSW;
|
|
const WCHAR szRegPathRNAProfileW[] = REGSTR_PATH_REMOTEACCESSW L"\\Profile";
|
|
const WCHAR szRegValAutodialDllNameW[] = REGSTR_VAL_AUTODIALDLLNAMEW;
|
|
const WCHAR szRegValAutodialFcnNameW[] = REGSTR_VAL_AUTODIALFCNNAMEW;
|
|
const WCHAR szRegValAutodialFlagsW[] = L"HandlerFlags";
|
|
const WCHAR szCMDllNameW[] = L"cmdial32.dll";
|
|
|
|
// NT reg keys for finding ras phonebook file
|
|
static const CHAR szNTRasPhonebookKey[] = "Software\\Microsoft\\RAS Phonebook";
|
|
static const CHAR szPhonebookMode[] = "PhonebookMode";
|
|
|
|
// don't check RNA state more than once every 3 seconds
|
|
#define MIN_RNA_BUSY_CHECK_INTERVAL 3000
|
|
|
|
// Name or reg value we save legacy settings for comparison later
|
|
#define LEGACY_MIGRATE_FLAGS (PROXY_TYPE_PROXY | PROXY_TYPE_AUTO_PROXY_URL)
|
|
|
|
//
|
|
// Current ras connections - used so we don't poll ras every time we're
|
|
// interested - only poll every 3 seconds (const. above)
|
|
//
|
|
RasEnumConnHelp g_RasCon;
|
|
DWORD g_dwConnections = 0;
|
|
BOOL g_fRasInstalled = FALSE;
|
|
DWORD g_dwLastDialupTicks = 0;
|
|
|
|
//
|
|
// API setting for autodial. Allow individual processes to disable autodial
|
|
// using InternetSetOption.
|
|
//
|
|
// This can override an enabled setting but not a disabled setting.
|
|
//
|
|
BOOL g_fAutodialEnableAPISetting = TRUE;
|
|
|
|
//
|
|
// Control of autodial initialization
|
|
//
|
|
BOOL g_fAutodialInitialized = FALSE;
|
|
|
|
//
|
|
// Do we know for sure that winsock is loaded?
|
|
//
|
|
BOOL g_fWinsockLoaded = FALSE;
|
|
|
|
|
|
HANDLE g_hDialEvent = NULL;
|
|
//
|
|
// Structure used to mess about with proxy settings
|
|
//
|
|
typedef struct _proxy {
|
|
DWORD dwEnable;
|
|
TCHAR szServer[INTERNET_MAX_URL_LENGTH];
|
|
TCHAR szOverride[INTERNET_MAX_URL_LENGTH];
|
|
DWORD dwSuspect;
|
|
} PROXY, *PPROXY;
|
|
|
|
//
|
|
// Need GetBestRoute from iphlpapi -- dynaload it, free on ExitAutodialModule
|
|
//
|
|
typedef DWORD (WINAPI *GETBESTROUTE)(DWORD, DWORD, PMIB_IPFORWARDROW);
|
|
|
|
static HINSTANCE g_hIphlpapi = NULL;
|
|
static GETBESTROUTE g_pfnGetBestRoute = NULL;
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RAS dynaload code
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
static HINSTANCE g_hRasLib = NULL;
|
|
static long g_lRasRefCnt = 0;
|
|
|
|
static _RASHANGUP pfnRasHangUp = NULL;
|
|
|
|
static _RASDIALA pfnRasDialA = NULL;
|
|
static _RASENUMENTRIESA pfnRasEnumEntriesA = NULL;
|
|
static _RASGETENTRYDIALPARAMSA pfnRasGetEntryDialParamsA = NULL;
|
|
static _RASSETENTRYDIALPARAMSA pfnRasSetEntryDialParamsA = NULL;
|
|
static _RASEDITPHONEBOOKENTRYA pfnRasEditPhonebookEntryA = NULL;
|
|
static _RASCREATEPHONEBOOKENTRYA pfnRasCreatePhonebookEntryA = NULL;
|
|
static _RASGETERRORSTRINGA pfnRasGetErrorStringA = NULL;
|
|
static _RASGETCONNECTSTATUSA pfnRasGetConnectStatusA = NULL;
|
|
static _RASENUMCONNECTIONSA pfnRasEnumConnectionsA = NULL;
|
|
static _RASGETENTRYPROPERTIESA pfnRasGetEntryPropertiesA = NULL;
|
|
|
|
static _RASDIALW pfnRasDialW = NULL;
|
|
static _RASENUMENTRIESW pfnRasEnumEntriesW = NULL;
|
|
static _RASGETENTRYDIALPARAMSW pfnRasGetEntryDialParamsW = NULL;
|
|
static _RASSETENTRYDIALPARAMSW pfnRasSetEntryDialParamsW = NULL;
|
|
static _RASEDITPHONEBOOKENTRYW pfnRasEditPhonebookEntryW = NULL;
|
|
static _RASCREATEPHONEBOOKENTRYW pfnRasCreatePhonebookEntryW = NULL;
|
|
static _RASGETERRORSTRINGW pfnRasGetErrorStringW = NULL;
|
|
static _RASGETCONNECTSTATUSW pfnRasGetConnectStatusW = NULL;
|
|
static _RASENUMCONNECTIONSW pfnRasEnumConnectionsW = NULL;
|
|
static _RASGETENTRYPROPERTIESW pfnRasGetEntryPropertiesW = NULL;
|
|
|
|
// Millennium (DUN 1.4?) RAS exports
|
|
static _RASINTERNETDIAL pfnRasInternetDialA = NULL;
|
|
static _RASINTERNETHANGUP pfnRasInternetHangUpA = NULL;
|
|
static _RASINTERNETAUTODIAL pfnRasInternetAutodialA = NULL;
|
|
static _RASINTERNETAUTODIALHANG pfnRasInternetAutodialHangUpA = NULL;
|
|
static _RASINTERNETCONNSTATE pfnRasInternetGetConnectedStateExA = NULL;
|
|
static _RNAGETDEFAULTAUTODIAL pfnRnaGetDefaultAutodialConnection = NULL;
|
|
static _RNASETDEFAULTAUTODIAL pfnRnaSetDefaultAutodialConnection = NULL;
|
|
|
|
// RAS entry points to sync up autodial connectoid... used on whistler only
|
|
static _RASGETAUTODIALADDRESSA pfnRasGetAutodialAddressA = NULL;
|
|
static _RASSETAUTODIALADDRESSA pfnRasSetAutodialAddressA = NULL;
|
|
|
|
static _RASGETCREDENTIALSW pfnRasGetCredentialsW = NULL;
|
|
static _RASSETCREDENTIALSW pfnRasSetCredentialsW = NULL;
|
|
|
|
typedef struct _tagAPIMAPENTRY {
|
|
FARPROC* pfn;
|
|
LPSTR pszProc;
|
|
} APIMAPENTRY;
|
|
|
|
APIMAPENTRY rgRasApiMapA[] = {
|
|
{ (FARPROC*) &pfnRasDialA, "RasDialA" },
|
|
{ (FARPROC*) &pfnRasHangUp, "RasHangUpA" },
|
|
{ (FARPROC*) &pfnRasEnumEntriesA, "RasEnumEntriesA" },
|
|
{ (FARPROC*) &pfnRasGetEntryDialParamsA, "RasGetEntryDialParamsA" },
|
|
{ (FARPROC*) &pfnRasSetEntryDialParamsA, "RasSetEntryDialParamsA" },
|
|
{ (FARPROC*) &pfnRasEditPhonebookEntryA, "RasEditPhonebookEntryA" },
|
|
{ (FARPROC*) &pfnRasCreatePhonebookEntryA, "RasCreatePhonebookEntryA" },
|
|
{ (FARPROC*) &pfnRasGetErrorStringA, "RasGetErrorStringA" },
|
|
{ (FARPROC*) &pfnRasGetConnectStatusA, "RasGetConnectStatusA" },
|
|
{ (FARPROC*) &pfnRasEnumConnectionsA, "RasEnumConnectionsA" },
|
|
{ (FARPROC*) &pfnRasGetEntryPropertiesA, "RasGetEntryPropertiesA"},
|
|
{ (FARPROC*) &pfnRasInternetDialA, "RasInternetDialA"},
|
|
{ (FARPROC*) &pfnRasInternetHangUpA, "RasInternetHangUpA"},
|
|
{ (FARPROC*) &pfnRasInternetAutodialA, "RasInternetAutodialA"},
|
|
{ (FARPROC*) &pfnRasInternetAutodialHangUpA, "RasInternetAutodialHangUpA"},
|
|
{ (FARPROC*) &pfnRasInternetGetConnectedStateExA, "RasInternetGetConnectedStateExA"},
|
|
{ (FARPROC*) &pfnRnaGetDefaultAutodialConnection, "RnaGetDefaultAutodialConnection"},
|
|
{ (FARPROC*) &pfnRnaSetDefaultAutodialConnection, "RnaSetDefaultAutodialConnection"},
|
|
{ NULL, NULL },
|
|
};
|
|
|
|
APIMAPENTRY rgRasApiMapW[] = {
|
|
{ (FARPROC*) &pfnRasDialW, "RasDialW" },
|
|
{ (FARPROC*) &pfnRasHangUp, "RasHangUpW" },
|
|
{ (FARPROC*) &pfnRasEnumEntriesW, "RasEnumEntriesW" },
|
|
{ (FARPROC*) &pfnRasGetEntryDialParamsW, "RasGetEntryDialParamsW" },
|
|
{ (FARPROC*) &pfnRasSetEntryDialParamsW, "RasSetEntryDialParamsW" },
|
|
{ (FARPROC*) &pfnRasEditPhonebookEntryW, "RasEditPhonebookEntryW" },
|
|
{ (FARPROC*) &pfnRasCreatePhonebookEntryW, "RasCreatePhonebookEntryW" },
|
|
{ (FARPROC*) &pfnRasGetErrorStringW, "RasGetErrorStringW" },
|
|
{ (FARPROC*) &pfnRasGetConnectStatusW, "RasGetConnectStatusW" },
|
|
{ (FARPROC*) &pfnRasEnumConnectionsW, "RasEnumConnectionsW" },
|
|
{ (FARPROC*) &pfnRasGetEntryPropertiesW, "RasGetEntryPropertiesW"},
|
|
{ (FARPROC*) &pfnRasGetCredentialsW, "RasGetCredentialsW"},
|
|
{ (FARPROC*) &pfnRasSetCredentialsW, "RasSetCredentialsW"},
|
|
|
|
// following are A in W map on purpose.. used on whistler only, but wininet code has
|
|
// the connectoid in multibyte.. may as well let RAS convert it.
|
|
{ (FARPROC*) &pfnRasGetAutodialAddressA, "RasGetAutodialAddressA"},
|
|
{ (FARPROC*) &pfnRasSetAutodialAddressA, "RasSetAutodialAddressA"},
|
|
{ NULL, NULL },
|
|
};
|
|
|
|
#define RASFCN(_fn, _part, _par, _dbge, _dbgl) \
|
|
DWORD _##_fn _part \
|
|
{ \
|
|
DEBUG_ENTER(_dbge); \
|
|
\
|
|
DWORD dwRet; \
|
|
if(NULL == pfn##_fn) \
|
|
{ \
|
|
_dbgl(ERROR_INVALID_FUNCTION); \
|
|
return ERROR_INVALID_FUNCTION; \
|
|
} \
|
|
\
|
|
dwRet = (* pfn##_fn) _par; \
|
|
\
|
|
_dbgl(dwRet); \
|
|
return dwRet; \
|
|
}
|
|
|
|
RASFCN(RasDialA,
|
|
(LPRASDIALEXTENSIONS lpRasDialExtensions, LPSTR lpszPhonebook, LPRASDIALPARAMS lpRasDialParams, DWORD dwNotifierType, LPVOID lpvNotifier, LPHRASCONN lphRasConn),
|
|
(lpRasDialExtensions, lpszPhonebook, lpRasDialParams, dwNotifierType, lpvNotifier, lphRasConn),
|
|
(DBG_DIALUP, Dword, "RasDialA", "%#x, %#x (%q), %#x, %d, %#x, %#x", lpRasDialExtensions, lpszPhonebook, lpszPhonebook, lpRasDialParams, dwNotifierType, lpvNotifier, lphRasConn),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasHangUp,
|
|
(HRASCONN hRasConn),
|
|
(hRasConn),
|
|
(DBG_DIALUP, Dword, "RasHangUp", "%#x", hRasConn),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasEnumEntriesA,
|
|
(LPSTR lpszReserved, LPSTR lpszPhonebook, LPRASENTRYNAMEA lprasentryname, LPDWORD lpcb, LPDWORD lpcEntries),
|
|
(lpszReserved, lpszPhonebook, lprasentryname, lpcb, lpcEntries),
|
|
(DBG_DIALUP, Dword, "RasEnumEntriesA", "%#x (%q), %#x (%q), %#x, %#x, %#x", lpszReserved, lpszReserved, lpszPhonebook, lpszPhonebook, lprasentryname, lpcb, lpcEntries),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasGetEntryDialParamsA,
|
|
(LPCSTR lpszPhonebook, LPRASDIALPARAMS lprasdialparams, LPBOOL lpfPassword),
|
|
(lpszPhonebook, lprasdialparams, lpfPassword),
|
|
(DBG_DIALUP, Dword, "RasGetEntryDialParamsA", "%#x (%q), %#x, %#x", lpszPhonebook, lpszPhonebook, lprasdialparams, lpfPassword),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasSetEntryDialParamsA,
|
|
(LPCSTR lpszPhonebook,LPRASDIALPARAMS lprasdialparams, BOOL fRemovePassword),
|
|
(lpszPhonebook,lprasdialparams, fRemovePassword),
|
|
(DBG_DIALUP, Dword, "RasSetEntryDialParamsA", "%#x (%q), %#x, %d", lpszPhonebook, lpszPhonebook, lprasdialparams, fRemovePassword),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasGetErrorStringA,
|
|
(UINT uError, LPSTR pszBuf, DWORD cBufSize),
|
|
(uError, pszBuf, cBufSize),
|
|
(DBG_DIALUP, Dword, "RasGetErrorStringA", "%d, %#x (%q), %d", uError, pszBuf, cBufSize),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasEditPhonebookEntryA,
|
|
(HWND hwnd, LPSTR lpszBook, LPSTR lpszEntry),
|
|
(hwnd, lpszBook, lpszEntry),
|
|
(DBG_DIALUP, Dword, "RasEditPhonebookEntryA", "%#x, %#x (%q), %#x (%q)", hwnd, lpszBook, lpszBook, lpszEntry, lpszEntry),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasCreatePhonebookEntryA,
|
|
(HWND hwnd, LPSTR pszBook),
|
|
(hwnd, pszBook),
|
|
(DBG_DIALUP, Dword, "RasCreatePhonebookEntryA", "%#x, %#x (%q)", hwnd, pszBook, pszBook),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasGetConnectStatusA,
|
|
(HRASCONN hrasconn, LPRASCONNSTATUS lprasconnstatus),
|
|
(hrasconn, lprasconnstatus),
|
|
(DBG_DIALUP, Dword, "RasGetConnectStatusA", "%#x, %#x", hrasconn, lprasconnstatus),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasGetEntryPropertiesA,
|
|
(LPSTR lpszPhonebook, LPSTR lpszEntry, LPRASENTRY lpRasEntry, LPDWORD lpdwEntryInfoSize, LPBYTE lpbDeviceInfo, LPDWORD lpdwDeviceInfoSize),
|
|
(lpszPhonebook, lpszEntry, lpRasEntry, lpdwEntryInfoSize, lpbDeviceInfo, lpdwDeviceInfoSize),
|
|
(DBG_DIALUP, Dword, "RasGetEntryPropertiesA", "%#x (%q), %#x (%q), %#x, %#x, %#x %#x", lpszPhonebook, lpszPhonebook, lpszEntry, lpszEntry, lpRasEntry, lpdwEntryInfoSize, lpbDeviceInfo, lpdwDeviceInfoSize),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasEnumConnectionsA,
|
|
(LPRASCONN lpRasConn, LPDWORD lpdwSize, LPDWORD lpdwConn),
|
|
(lpRasConn, lpdwSize, lpdwConn),
|
|
(DBG_DIALUP, Dword, "RasEnumConnectionsA", "%#x, %#x, %#x", lpRasConn, lpdwSize, lpdwConn),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasInternetDialA,
|
|
(HWND hwndParent, LPSTR pszEntryName, DWORD dwFlags, DWORD_PTR *lpdwConnection, DWORD dwReserved),
|
|
(hwndParent, pszEntryName, dwFlags, lpdwConnection, dwReserved),
|
|
(DBG_DIALUP, Dword, "RasInternetDialA", "#x, #x (%q), %x, %x, %x", hwndParent, pszEntryName, pszEntryName, dwFlags, lpdwConnection, dwReserved),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasInternetHangUpA,
|
|
(DWORD_PTR dwConnection, DWORD dwReserved),
|
|
(dwConnection, dwReserved),
|
|
(DBG_DIALUP, Dword, "RasInternetHangUpA", "#x, #x", dwConnection, dwReserved),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasInternetAutodialA,
|
|
(DWORD dwFlags, HWND hwndParent),
|
|
(dwFlags, hwndParent),
|
|
(DBG_DIALUP, Dword, "RasInterenetAutodialA", "#x, #x", dwFlags, hwndParent),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasInternetAutodialHangUpA,
|
|
(DWORD dwReserved),
|
|
(dwReserved),
|
|
(DBG_DIALUP, Dword, "RasInternetAutodialHangUpA", "#x", dwReserved),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasInternetGetConnectedStateExA,
|
|
(LPDWORD lpdwFlags, LPSTR lpszConnectionName, DWORD dwBufLen, DWORD dwReserved),
|
|
(lpdwFlags, lpszConnectionName, dwBufLen, dwReserved),
|
|
(DBG_DIALUP, Bool, "RasInternetGetConnectedStateExA", "%x, %x, %x, %x", lpdwFlags, lpszConnectionName, dwBufLen, dwReserved),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RnaGetDefaultAutodialConnection,
|
|
(LPSTR pszEntry, DWORD dwLen, LPDWORD lpdwFlags),
|
|
(pszEntry, dwLen, lpdwFlags),
|
|
(DBG_DIALUP, Dword, "RnaGetDefaultAutodialConnection", "%#x, %#x, %#x", pszEntry, dwLen, lpdwFlags),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RnaSetDefaultAutodialConnection,
|
|
(LPSTR pszEntry, DWORD dwFlags),
|
|
(pszEntry, dwFlags),
|
|
(DBG_DIALUP, Dword, "RnaSetDefaultAutodialConnection", "%#x (%q), %#x", pszEntry, pszEntry, dwFlags),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
////////////////////////////////////////////////////
|
|
// Wide versions
|
|
RASFCN(RasDialW,
|
|
(LPRASDIALEXTENSIONS lpRasDialExtensions, LPWSTR lpszPhonebook,
|
|
LPRASDIALPARAMSW lpRasDialParams, DWORD dwNotifierType, LPVOID lpvNotifier, LPHRASCONN lphRasConn),
|
|
(lpRasDialExtensions, lpszPhonebook, lpRasDialParams, dwNotifierType, lpvNotifier, lphRasConn),
|
|
(DBG_DIALUP, Dword, "RasDialW", "%#x, %#x (%Q), %#x, %d, %#x, %#x", lpRasDialExtensions, lpszPhonebook, lpszPhonebook, lpRasDialParams, dwNotifierType, lpvNotifier, lphRasConn),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasEnumEntriesW,
|
|
(LPWSTR lpszReserved, LPWSTR lpszPhonebook, LPRASENTRYNAMEW lprasentryname,
|
|
LPDWORD lpcb, LPDWORD lpcEntries),
|
|
(lpszReserved, lpszPhonebook, lprasentryname, lpcb, lpcEntries),
|
|
(DBG_DIALUP, Dword, "RasEnumEntriesW", "%#x (%Q), %#x (%Q), %#x, %#x %#x", lpszReserved, lpszReserved, lpszPhonebook, lpszPhonebook, lprasentryname, lpcb, lpcEntries),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasGetEntryDialParamsW,
|
|
(LPCWSTR lpszPhonebook, LPRASDIALPARAMSW lprasdialparams, LPBOOL lpfPassword),
|
|
(lpszPhonebook, lprasdialparams, lpfPassword),
|
|
(DBG_DIALUP, Dword, "RasGetEntryDialParamsW", "%#x (%Q), %#x, %#x", lpszPhonebook, lpszPhonebook, lprasdialparams, lpfPassword),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasSetEntryDialParamsW,
|
|
(LPCWSTR lpszPhonebook, LPRASDIALPARAMSW lprasdialparams, BOOL fRemovePassword),
|
|
(lpszPhonebook,lprasdialparams, fRemovePassword),
|
|
(DBG_DIALUP, Dword, "RasSetEntryDialParamsW", "%#x (%Q), %#x, %d", lpszPhonebook, lpszPhonebook, lprasdialparams, fRemovePassword),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasGetErrorStringW,
|
|
(UINT uError, LPWSTR pszBuf, DWORD cBufSize),
|
|
(uError, pszBuf, cBufSize),
|
|
(DBG_DIALUP, Dword, "RasGetErrorStringW", "%d, %#x (%Q), %d", uError, pszBuf, cBufSize),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasEditPhonebookEntryW,
|
|
(HWND hwnd, LPWSTR lpszBook, LPWSTR lpszEntry),
|
|
(hwnd, lpszBook, lpszEntry),
|
|
(DBG_DIALUP, Dword, "RasEditPhonebookEntryW", "%#x, %#x (%Q), %#x (%Q)", hwnd, lpszBook, lpszBook, lpszEntry, lpszEntry),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasCreatePhonebookEntryW,
|
|
(HWND hwnd, LPWSTR pszBook),
|
|
(hwnd, pszBook),
|
|
(DBG_DIALUP, Dword, "RasCreatePhonebookEntryW", "%#x, %#x (%Q)", hwnd, pszBook, pszBook),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasGetConnectStatusW,
|
|
(HRASCONN hrasconn, LPRASCONNSTATUSW lprasconnstatus),
|
|
(hrasconn, lprasconnstatus),
|
|
(DBG_DIALUP, Dword, "RasGetConnectStatusW", "%#x, %#x", hrasconn, lprasconnstatus),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasGetEntryPropertiesW,
|
|
(LPWSTR lpszPhonebook, LPWSTR lpszEntry, LPRASENTRYW lpRasEntry, LPDWORD lpdwEntryInfoSize, LPBYTE lpbDeviceInfo, LPDWORD lpdwDeviceInfoSize),
|
|
(lpszPhonebook, lpszEntry, lpRasEntry, lpdwEntryInfoSize, lpbDeviceInfo, lpdwDeviceInfoSize),
|
|
(DBG_DIALUP, Dword, "RasGetEntryPropertiesW", "%#x (%Q), %#x (%Q), %#x, %#x, %#x %#x", lpszPhonebook, lpszPhonebook, lpszEntry, lpszEntry, lpRasEntry, lpdwEntryInfoSize, lpbDeviceInfo, lpdwDeviceInfoSize),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasEnumConnectionsW,
|
|
(LPRASCONNW lpRasConn, LPDWORD lpdwSize, LPDWORD lpdwConn),
|
|
(lpRasConn, lpdwSize, lpdwConn),
|
|
(DBG_DIALUP, Dword, "RasEnumConnectionsW", "%#x, %#x, %#x", lpRasConn, lpdwSize, lpdwConn),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasGetAutodialAddressA,
|
|
(LPCSTR lpszAddress, LPDWORD lpdwReserved, LPRASAUTODIALENTRYA lpEntries, LPDWORD lpdwBytes, LPDWORD lpdwEntries),
|
|
(lpszAddress, lpdwReserved, lpEntries, lpdwBytes, lpdwEntries),
|
|
(DBG_DIALUP, Dword, "RasGetAutodialAddressA", "%#x (%Q), %#x, %#x, %#x, %#x", lpszAddress, lpszAddress, lpdwReserved, lpEntries, lpdwBytes, lpdwEntries),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasSetAutodialAddressA,
|
|
(LPCSTR lpszAddress, DWORD dwReserved, LPRASAUTODIALENTRYA lpEntries, DWORD dwBytes, DWORD dwEntries),
|
|
(lpszAddress, dwReserved, lpEntries, dwBytes, dwEntries),
|
|
(DBG_DIALUP, Dword, "RasSetAutodialAddressA", "%#x (%q), %#x, %#x, %#x, %#x", lpszAddress, lpszAddress, dwReserved, lpEntries, dwBytes, dwEntries),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasGetCredentialsW,
|
|
(LPCWSTR pszPhonebook, LPCWSTR pszEntry, LPRASCREDENTIALSW pCreds),
|
|
(pszPhonebook, pszEntry, pCreds),
|
|
(DBG_DIALUP, Dword, "RasGetCredentialsW", "%#x (%Q), %#x (%Q), %#x", pszPhonebook, pszPhonebook, pszEntry, pszEntry, pCreds),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
RASFCN(RasSetCredentialsW,
|
|
(LPCWSTR pszPhonebook, LPCWSTR pszEntry, LPRASCREDENTIALSW pCreds, BOOL fNuke),
|
|
(pszPhonebook, pszEntry, pCreds, fNuke),
|
|
(DBG_DIALUP, Dword, "RasSetCredentialsW", "%#x (%Q), %#x (%Q), %#x, %#x", pszPhonebook, pszPhonebook, pszEntry, pszEntry, pCreds, fNuke),
|
|
DEBUG_LEAVE
|
|
);
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL
|
|
EnsureRasLoaded(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dynaload ras apis
|
|
|
|
Arguments:
|
|
|
|
pfInstalled - return installed state of ras
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - Ras loaded
|
|
FALSE - Ras not loaded
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"EnsureRasLoaded",
|
|
NULL
|
|
));
|
|
|
|
//
|
|
// Looks like RAS is installed - try and load it up!
|
|
//
|
|
if(NULL == g_hRasLib) {
|
|
g_hRasLib = LoadLibrary("RASAPI32.DLL");
|
|
|
|
if(NULL == g_hRasLib)
|
|
{
|
|
DEBUG_LEAVE(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
APIMAPENTRY *prgRasApiMap;
|
|
if(PLATFORM_TYPE_WIN95 == GlobalPlatformType)
|
|
prgRasApiMap = rgRasApiMapA;
|
|
else
|
|
prgRasApiMap = rgRasApiMapW;
|
|
|
|
int nIndex = 0;
|
|
while ((prgRasApiMap+nIndex)->pszProc != NULL) {
|
|
// Some functions are only present on some platforms. Don't
|
|
// assume this succeeds for all functions.
|
|
*(prgRasApiMap+nIndex)->pfn =
|
|
GetProcAddress(g_hRasLib, (prgRasApiMap+nIndex)->pszProc);
|
|
nIndex++;
|
|
}
|
|
}
|
|
|
|
if(g_hRasLib) {
|
|
g_lRasRefCnt++;
|
|
DEBUG_LEAVE(TRUE);
|
|
return TRUE;
|
|
}
|
|
|
|
DEBUG_LEAVE(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
IsServiceRunning(
|
|
LPSTR pszServiceName,
|
|
DWORD dwRequiredState
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Determines whether a specified service is running on NT
|
|
|
|
Arguments:
|
|
|
|
pszServiceName - service to find
|
|
dwRequiredState - state the service has to be in to consider it found
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - Service is in required state
|
|
|
|
FALSE - not
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"IsServiceRunning",
|
|
"%#x (%q), %#x",
|
|
pszServiceName,
|
|
pszServiceName,
|
|
dwRequiredState
|
|
));
|
|
|
|
SC_HANDLE hscm;
|
|
BOOL fFoundService = FALSE;
|
|
|
|
//
|
|
// Sanity check - can only do this on NT
|
|
//
|
|
if(PLATFORM_TYPE_WIN95 == GlobalPlatformType)
|
|
{
|
|
DEBUG_LEAVE(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Ask service manager to enumerate all running services
|
|
//
|
|
hscm = OpenSCManager(NULL, NULL, GENERIC_READ);
|
|
if(hscm)
|
|
{
|
|
SC_HANDLE hras;
|
|
ENUM_SERVICE_STATUS essServices[16];
|
|
DWORD dwError, dwResume = 0, i;
|
|
DWORD cbNeeded = 1, csReturned;
|
|
|
|
while(FALSE == fFoundService && cbNeeded > 0)
|
|
{
|
|
// Get the next chunk of services
|
|
dwError = 0;
|
|
if(FALSE == EnumServicesStatus(hscm, SERVICE_WIN32, dwRequiredState,
|
|
essServices, sizeof(essServices), &cbNeeded, &csReturned,
|
|
&dwResume))
|
|
{
|
|
dwError = GetLastError();
|
|
}
|
|
|
|
if(dwError && dwError != ERROR_MORE_DATA)
|
|
{
|
|
// unknown error - bail
|
|
break;
|
|
}
|
|
|
|
for(i=0; i<csReturned; i++)
|
|
{
|
|
if(0 == lstrcmpi(essServices[i].lpServiceName, pszServiceName))
|
|
{
|
|
// found it!
|
|
fFoundService = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
CloseServiceHandle(hscm);
|
|
}
|
|
|
|
DEBUG_LEAVE(fFoundService);
|
|
return fFoundService;
|
|
}
|
|
|
|
|
|
BOOL
|
|
IsRasInstalled(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Determines whether ras is installed on this machine
|
|
|
|
Arguments:
|
|
|
|
none
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - Ras is installed
|
|
|
|
FALSE - Ras is not installed
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER_API((DBG_DIALUP,
|
|
Bool,
|
|
"IsRasInstalled",
|
|
NULL
|
|
));
|
|
|
|
static fChecked = FALSE;
|
|
|
|
//
|
|
// If RAS is already loaded, don't bother doing any work.
|
|
//
|
|
if(g_hRasLib)
|
|
{
|
|
DEBUG_LEAVE_API(TRUE);
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// if we've already done the check, don't do it again
|
|
//
|
|
if(fChecked)
|
|
{
|
|
DEBUG_LEAVE_API(g_fRasInstalled);
|
|
return g_fRasInstalled;
|
|
}
|
|
|
|
if(PLATFORM_TYPE_WIN95 == GlobalPlatformType) {
|
|
//
|
|
// Check Win9x key
|
|
//
|
|
char szSmall[3]; // there should be a "1" or a "0" only
|
|
DWORD cb;
|
|
HKEY hkey;
|
|
long lRes;
|
|
|
|
lRes = REGOPENKEYEX(HKEY_LOCAL_MACHINE, REGSTR_PATH_RNACOMPONENT,
|
|
NULL, KEY_READ, &hkey);
|
|
if(ERROR_SUCCESS == lRes) {
|
|
cb = sizeof(szSmall);
|
|
// REGSTR_VAL_RNAINSTALLED is defined with TEXT() macro so
|
|
// if wininet is ever compiled unicode this will be a compile
|
|
// error.
|
|
lRes = RegQueryValueExA(hkey, REGSTR_VAL_RNAINSTALLED, NULL,
|
|
NULL, (LPBYTE)szSmall, &cb);
|
|
if(ERROR_SUCCESS == lRes) {
|
|
if((szSmall[0] == '1') && (szSmall[1] == 0)) {
|
|
// 1 means ras installed
|
|
g_fRasInstalled = TRUE;
|
|
}
|
|
}
|
|
REGCLOSEKEY(hkey);
|
|
}
|
|
} else {
|
|
OSVERSIONINFO osvi;
|
|
|
|
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
GetVersionEx(&osvi);
|
|
|
|
if (osvi.dwMajorVersion < 5)
|
|
{
|
|
// on NT4, make sure ras man service is installed
|
|
g_fRasInstalled = IsServiceRunning("RasMan", SERVICE_STATE_ALL);
|
|
|
|
if(g_fRasInstalled)
|
|
{
|
|
if(EnsureRasLoaded() && FALSE == GlobalDisableNT4RasCheck)
|
|
{
|
|
RasEnumHelp *pRasEnum = NULL;
|
|
__try
|
|
{
|
|
// call rasenumentries - if it faults, we're in that
|
|
// NT4 busted case so return not installed.
|
|
pRasEnum = new RasEnumHelp;
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
// if it faults, don't use ras any more
|
|
g_fRasInstalled = FALSE;
|
|
}
|
|
ENDEXCEPT
|
|
|
|
if (pRasEnum)
|
|
delete pRasEnum;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// NT5 and presumably beyond, ras is always installed
|
|
g_fRasInstalled = TRUE;
|
|
}
|
|
}
|
|
|
|
fChecked = TRUE;
|
|
|
|
DEBUG_LEAVE_API(g_fRasInstalled);
|
|
return g_fRasInstalled;
|
|
}
|
|
|
|
|
|
BOOL
|
|
DoConnectoidsExist(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Determines whether any ras connectoids exist
|
|
|
|
Arguments:
|
|
|
|
none
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - Connectoids exist
|
|
|
|
FALSE - No connectoids exist
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER_API((DBG_DIALUP,
|
|
Bool,
|
|
"DoConnectoidsExist",
|
|
NULL
|
|
));
|
|
|
|
static BOOL fExist = FALSE;
|
|
|
|
//
|
|
// If we found connectoids before, don't bother looking again
|
|
//
|
|
if(fExist)
|
|
{
|
|
DEBUG_LEAVE_API(TRUE);
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// If RAS is already loaded, ask it
|
|
//
|
|
if(g_hRasLib && FALSE == GlobalDisableNT4RasCheck) {
|
|
DWORD dwRet, dwEntries;
|
|
|
|
RasEnumHelp *pRasEnum = new RasEnumHelp;
|
|
|
|
if (pRasEnum)
|
|
{
|
|
dwRet = pRasEnum->GetError();
|
|
dwEntries = pRasEnum->GetEntryCount();
|
|
delete pRasEnum;
|
|
}
|
|
else
|
|
{
|
|
dwRet = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
// If ras tells us there are none, return none
|
|
if(ERROR_SUCCESS == dwRet && 0 == dwEntries)
|
|
{
|
|
DEBUG_LEAVE_API(FALSE);
|
|
return FALSE;
|
|
}
|
|
// couldn't determine that there aren't any so assume there are.
|
|
fExist = TRUE;
|
|
DEBUG_LEAVE_API(TRUE);
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// if ras isn't installed, say no connectoids
|
|
//
|
|
if(FALSE == IsRasInstalled())
|
|
{
|
|
DEBUG_LEAVE_API(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
if(PLATFORM_TYPE_WIN95 == GlobalPlatformType) {
|
|
// On win95, check for any value in RemoteAccess\Addresses reg key
|
|
HKEY hkey;
|
|
TCHAR szName[RAS_MaxEntryName+1];
|
|
DWORD cbName = RAS_MaxEntryName+1;
|
|
long lRes;
|
|
|
|
if(ERROR_SUCCESS == REGOPENKEYEX(HKEY_CURRENT_USER, szRegAddresses,
|
|
0, KEY_READ, &hkey)) {
|
|
|
|
lRes = RegEnumValue(hkey, 0, szName, &cbName, NULL, NULL, NULL, NULL);
|
|
if(ERROR_SUCCESS == lRes) {
|
|
// we managed to get info on a connectoid.
|
|
fExist = TRUE;
|
|
}
|
|
|
|
REGCLOSEKEY(hkey);
|
|
}
|
|
} else {
|
|
OSVERSIONINFO osvi;
|
|
|
|
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
GetVersionEx(&osvi);
|
|
|
|
// assume connectoids exist
|
|
fExist = TRUE;
|
|
|
|
if (osvi.dwMajorVersion < 5) {
|
|
// On NT4, check for rasphone.pbk size > 0
|
|
TCHAR szPhonebook[MAX_PATH + 128];
|
|
ULONG uLen, ulMode, cb;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
DWORD dwSize, dwBigSize;
|
|
HKEY hkey;
|
|
|
|
// Ensure system phonebook is the one in use. If user has switched
|
|
// to another phonebook, don't bother doing anything else and assume
|
|
// connectoids exist. It's not our job to grope the world trying to
|
|
// find custom phonebooks.
|
|
if(ERROR_SUCCESS == REGOPENKEYEX(HKEY_CURRENT_USER, szNTRasPhonebookKey,
|
|
0, KEY_READ, &hkey))
|
|
{
|
|
*szPhonebook = 0;
|
|
cb = sizeof(ULONG);
|
|
if(ERROR_SUCCESS == RegQueryValueEx(hkey, szPhonebookMode, NULL,
|
|
NULL, (LPBYTE)&ulMode, &cb) && 0 == ulMode)
|
|
{
|
|
// system phonebook - rasphone.pbk in ras directory
|
|
uLen = GetSystemDirectory(szPhonebook, MAX_PATH);
|
|
if(uLen)
|
|
{
|
|
// append \ras\rasphone.pbk
|
|
LoadString(GlobalDllHandle, IDS_RASPHONEBOOK, szPhonebook + uLen, 128);
|
|
hFile = CreateFile(szPhonebook, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL, OPEN_EXISTING, 0, NULL);
|
|
if(INVALID_HANDLE_VALUE == hFile) {
|
|
// file doesn't exist - no connectoids
|
|
fExist = FALSE;
|
|
} else {
|
|
dwSize = GetFileSize(hFile, &dwBigSize);
|
|
if(0 == dwSize && 0 == dwBigSize)
|
|
// zero size system phonebook - no connectoids
|
|
fExist = FALSE;
|
|
CloseHandle(hFile);
|
|
}
|
|
}
|
|
}
|
|
REGCLOSEKEY(hkey);
|
|
}
|
|
}
|
|
}
|
|
|
|
DEBUG_LEAVE_API(fExist);
|
|
return fExist;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Helper Functions
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL
|
|
InitCommCtrl(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initializes common controls for native font control
|
|
|
|
Called from InternetDialA which is serialized.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - successly called InitCommonControlsEx
|
|
FALSE - failed
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"InitCommCtrl",
|
|
NULL
|
|
));
|
|
|
|
BOOL fSuccess = FALSE;
|
|
|
|
hCommctrl = LoadLibrary("comctl32.dll");
|
|
if(hCommctrl)
|
|
{
|
|
PFNINITCOMMONCONTROLS pfnInit;
|
|
|
|
pfnInit = (PFNINITCOMMONCONTROLS)GetProcAddress(hCommctrl, "InitCommonControlsEx");
|
|
if(pfnInit)
|
|
{
|
|
INITCOMMONCONTROLSEX ex;
|
|
|
|
ex.dwSize = sizeof(ex);
|
|
ex.dwICC = ICC_NATIVEFNTCTL_CLASS;
|
|
pfnInit(&ex);
|
|
fSuccess = TRUE;
|
|
}
|
|
}
|
|
|
|
DEBUG_LEAVE(fSuccess);
|
|
return fSuccess;
|
|
}
|
|
|
|
|
|
VOID
|
|
ExitCommCtrl(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Unloads commctrl library
|
|
|
|
Called from InternetDialA which is serialized.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
None,
|
|
"ExitCommCtrl",
|
|
NULL
|
|
));
|
|
|
|
if(hCommctrl)
|
|
{
|
|
FreeLibrary(hCommctrl);
|
|
hCommctrl = NULL;
|
|
}
|
|
|
|
DEBUG_LEAVE(0);
|
|
}
|
|
|
|
|
|
BOOL
|
|
IsGlobalOffline(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Determines whether wininet is in global offline mode
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - offline
|
|
FALSE - online
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"IsGlobalOffline",
|
|
NULL
|
|
));
|
|
|
|
DWORD dwState = 0, dwSize = sizeof(DWORD);
|
|
BOOL fRet = FALSE;
|
|
|
|
if(InternetQueryOption(NULL, INTERNET_OPTION_CONNECTED_STATE, &dwState,
|
|
&dwSize))
|
|
{
|
|
if(dwState & INTERNET_STATE_DISCONNECTED_BY_USER)
|
|
fRet = TRUE;
|
|
}
|
|
|
|
DEBUG_LEAVE(fRet);
|
|
return fRet;
|
|
}
|
|
|
|
|
|
VOID
|
|
SetOffline(
|
|
IN BOOL fOffline
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets wininet's offline mode
|
|
|
|
Arguments:
|
|
|
|
fOffline - online or offline
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
None,
|
|
"SetOffline",
|
|
"%B",
|
|
fOffline
|
|
));
|
|
|
|
INTERNET_CONNECTED_INFO ci;
|
|
|
|
memset(&ci, 0, sizeof(ci));
|
|
if(fOffline) {
|
|
ci.dwConnectedState = INTERNET_STATE_DISCONNECTED_BY_USER;
|
|
ci.dwFlags = ISO_FORCE_DISCONNECTED;
|
|
} else {
|
|
ci.dwConnectedState = INTERNET_STATE_CONNECTED;
|
|
}
|
|
|
|
InternetSetOption(NULL, INTERNET_OPTION_CONNECTED_STATE, &ci, sizeof(ci));
|
|
|
|
DEBUG_LEAVE(0);
|
|
}
|
|
|
|
|
|
VOID
|
|
GetConnKeyW(
|
|
IN LPWSTR pszConn,
|
|
IN LPWSTR pszKey,
|
|
IN int iLen
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get registry key for a specific connection
|
|
|
|
Arguments:
|
|
|
|
pszConn - connection for which key is required
|
|
pszKey - buffer to put key
|
|
iLen - buffer size
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
None,
|
|
"GetConnKeyW",
|
|
"%#x (%Q), %#x, %d",
|
|
pszConn,
|
|
pszConn,
|
|
pszKey,
|
|
iLen
|
|
));
|
|
|
|
if(NULL == pszConn || 0 == *pszConn)
|
|
{
|
|
// lan setting
|
|
StrCpyNW(pszKey, REGSTR_PATH_INTERNET_LAN_SETTINGSW, iLen);
|
|
}
|
|
else
|
|
{
|
|
// connectoid settings
|
|
wnsprintfW(pszKey, iLen, L"%ws\\%ws", szRegPathRNAProfileW, pszConn);
|
|
}
|
|
|
|
DEBUG_LEAVE(0);
|
|
}
|
|
|
|
VOID
|
|
GetConnKeyA(
|
|
IN LPSTR pszConn,
|
|
IN LPSTR pszKey,
|
|
IN int iLen
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get registry key for a specific connection
|
|
|
|
Arguments:
|
|
|
|
pszConn - connection for which key is required
|
|
pszKey - buffer to put key
|
|
iLen - buffer size
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
None,
|
|
"GetConnKeyA",
|
|
"%#x (%q), %#x, %d",
|
|
pszConn,
|
|
pszConn,
|
|
pszKey,
|
|
iLen
|
|
));
|
|
|
|
if(NULL == pszConn || 0 == *pszConn)
|
|
{
|
|
// lan setting
|
|
lstrcpynA(pszKey, REGSTR_PATH_INTERNET_LAN_SETTINGS, iLen);
|
|
}
|
|
else
|
|
{
|
|
// connectoid settings
|
|
wnsprintfA(pszKey, iLen, "%s\\%s", szRegPathRNAProfile, pszConn);
|
|
}
|
|
|
|
DEBUG_LEAVE(0);
|
|
}
|
|
|
|
|
|
VOID
|
|
SetAutodialEnable(
|
|
IN BOOL fEnable
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets the API setting for controlling autodial. Called from
|
|
InternetSetOption.
|
|
|
|
Arguments:
|
|
|
|
fEnable - FALSE means don't autodial for this process
|
|
TRUE means autodial if configured by the user
|
|
|
|
Return Value:
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
None,
|
|
"SetAutodialEnable",
|
|
"%B",
|
|
fEnable
|
|
));
|
|
|
|
g_fAutodialEnableAPISetting = fEnable;
|
|
|
|
DEBUG_LEAVE(0);
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetAutodialMode(
|
|
)
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Dword,
|
|
"GetAutodialMode",
|
|
NULL
|
|
));
|
|
|
|
DWORD dwMode = AUTODIAL_MODE_NO_NETWORK_PRESENT, dwError, dwData;
|
|
|
|
// make sure RAS and Wininet flags match up
|
|
INET_ASSERT(RAS_AUTODIAL_OPT_NEVER == AUTODIAL_MODE_NEVER);
|
|
INET_ASSERT(RAS_AUTODIAL_OPT_ALWAYS == AUTODIAL_MODE_ALWAYS);
|
|
INET_ASSERT(RAS_AUTODIAL_OPT_DEMAND == AUTODIAL_MODE_NO_NETWORK_PRESENT);
|
|
|
|
if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRnaGetDefaultAutodialConnection)
|
|
{
|
|
dwError = _RnaGetDefaultAutodialConnection(NULL, 0, &dwMode);
|
|
|
|
if(dwError)
|
|
{
|
|
DEBUG_ERROR(DIALUP, dwError);
|
|
dwMode = AUTODIAL_MODE_NEVER;
|
|
}
|
|
|
|
dwMode &= (RAS_AUTODIAL_OPT_NEVER | RAS_AUTODIAL_OPT_ALWAYS | RAS_AUTODIAL_OPT_DEMAND);
|
|
|
|
DEBUG_LEAVE(dwMode);
|
|
return dwMode;
|
|
}
|
|
|
|
if(InternetReadRegistryDword(REGSTR_VAL_ENABLEAUTODIAL, &dwData) ||
|
|
0 == dwData)
|
|
{
|
|
dwMode = AUTODIAL_MODE_NEVER;
|
|
}
|
|
|
|
if(AUTODIAL_MODE_NO_NETWORK_PRESENT == dwMode)
|
|
{
|
|
if(InternetReadRegistryDword(REGSTR_VAL_NONETAUTODIAL, &dwData) ||
|
|
0 == dwData)
|
|
{
|
|
dwMode = AUTODIAL_MODE_ALWAYS;
|
|
}
|
|
}
|
|
|
|
DEBUG_LEAVE(dwMode);
|
|
return dwMode;
|
|
}
|
|
|
|
DWORD
|
|
SetAutodialMode(
|
|
IN DWORD dwMode
|
|
)
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Dword,
|
|
"SetAutodialMode",
|
|
"%#x",
|
|
dwMode
|
|
));
|
|
|
|
DWORD dwEnable = 0, dwNonet = 0, dwError = 0;
|
|
|
|
// make sure RAS and Wininet flags match up
|
|
INET_ASSERT(RAS_AUTODIAL_OPT_NEVER == AUTODIAL_MODE_NEVER);
|
|
INET_ASSERT(RAS_AUTODIAL_OPT_ALWAYS == AUTODIAL_MODE_ALWAYS);
|
|
INET_ASSERT(RAS_AUTODIAL_OPT_DEMAND == AUTODIAL_MODE_NO_NETWORK_PRESENT);
|
|
|
|
if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRnaSetDefaultAutodialConnection && pfnRnaGetDefaultAutodialConnection)
|
|
{
|
|
CHAR szOldName[RAS_MaxEntryName+1];
|
|
DWORD dwOldMode;
|
|
|
|
// Have to set both name and mode at the same time, so read existing values and change
|
|
// what we need.
|
|
dwError = _RnaGetDefaultAutodialConnection(szOldName, ARRAYSIZE(szOldName), &dwOldMode);
|
|
if(0 == dwError)
|
|
{
|
|
dwError = _RnaSetDefaultAutodialConnection(szOldName, dwMode);
|
|
}
|
|
|
|
DEBUG_LEAVE(dwError);
|
|
return dwError;
|
|
}
|
|
|
|
switch(dwMode)
|
|
{
|
|
case AUTODIAL_MODE_NEVER:
|
|
break;
|
|
case AUTODIAL_MODE_NO_NETWORK_PRESENT:
|
|
dwNonet = 1;
|
|
// fall through to always
|
|
case AUTODIAL_MODE_ALWAYS:
|
|
dwEnable = 1;
|
|
break;
|
|
default:
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if(ERROR_SUCCESS == dwError)
|
|
{
|
|
InternetWriteRegistryDword(REGSTR_VAL_ENABLEAUTODIAL, dwEnable);
|
|
InternetWriteRegistryDword(REGSTR_VAL_NONETAUTODIAL, dwNonet);
|
|
}
|
|
|
|
DEBUG_LEAVE(dwError);
|
|
return dwError;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetAutodialConnection(
|
|
CHAR *pszBuffer,
|
|
DWORD dwBufferLength
|
|
)
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Dword,
|
|
"GetAutodialConnection",
|
|
"%#x, %#x",
|
|
pszBuffer,
|
|
dwBufferLength
|
|
));
|
|
|
|
DWORD dwType, dwHasEntry = FALSE, dwMode, dwError = ERROR_INVALID_NAME;
|
|
|
|
if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRnaGetDefaultAutodialConnection)
|
|
{
|
|
dwError = _RnaGetDefaultAutodialConnection(pszBuffer, dwBufferLength, &dwMode);
|
|
|
|
if(0 == dwError)
|
|
{
|
|
DEBUG_PRINT(DIALUP, INFO, ("Entry=%s, Mode=%x", pszBuffer, dwMode));
|
|
}
|
|
|
|
DEBUG_LEAVE(dwError);
|
|
return dwError;
|
|
}
|
|
|
|
if(GlobalPlatformWhistler && EnsureRasLoaded() && pfnRasGetAutodialAddressA)
|
|
{
|
|
RASAUTODIALENTRYA adEntry;
|
|
DWORD dwBytes, dwEntries;
|
|
|
|
ZeroMemory(&adEntry, sizeof(adEntry));
|
|
adEntry.dwSize = sizeof(adEntry);
|
|
dwBytes = sizeof(adEntry);
|
|
dwEntries = 1;
|
|
|
|
dwError = _RasGetAutodialAddressA(
|
|
NULL,
|
|
NULL,
|
|
&adEntry,
|
|
&dwBytes,
|
|
&dwEntries);
|
|
|
|
if(NO_ERROR == dwError && dwEntries)
|
|
{
|
|
lstrcpyn(pszBuffer, adEntry.szEntry, dwBufferLength);
|
|
}
|
|
else
|
|
{
|
|
*pszBuffer = 0;
|
|
}
|
|
|
|
DEBUG_LEAVE(dwError);
|
|
return dwError;
|
|
}
|
|
|
|
if(ERROR_SUCCESS == SHGetValueA(HKEY_CURRENT_USER, szRegPathRemoteAccess,
|
|
szRegValInternetEntry, &dwType, pszBuffer, &dwBufferLength) &&
|
|
lstrlen(pszBuffer))
|
|
{
|
|
dwError = 0; // success
|
|
}
|
|
|
|
DEBUG_LEAVE(dwError);
|
|
return dwError;
|
|
}
|
|
|
|
|
|
DWORD
|
|
SetAutodialConnection(
|
|
CHAR *pszConnection
|
|
)
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Dword,
|
|
"SetAutodialConnection",
|
|
"%#x (%q)",
|
|
pszConnection,
|
|
pszConnection
|
|
));
|
|
|
|
DWORD dwError;
|
|
|
|
if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRnaSetDefaultAutodialConnection && pfnRnaGetDefaultAutodialConnection)
|
|
{
|
|
CHAR szOldName[RAS_MaxEntryName+1];
|
|
DWORD dwOldMode;
|
|
|
|
// Have to set both name and mode at the same time, so read existing values and change
|
|
// what we need.
|
|
dwError = _RnaGetDefaultAutodialConnection(szOldName, ARRAYSIZE(szOldName), &dwOldMode);
|
|
if(0 == dwError)
|
|
{
|
|
dwError = _RnaSetDefaultAutodialConnection(pszConnection, dwOldMode);
|
|
}
|
|
|
|
DEBUG_LEAVE(dwError);
|
|
return dwError;
|
|
}
|
|
|
|
if(GlobalPlatformWhistler && EnsureRasLoaded() && pfnRasSetAutodialAddressA)
|
|
{
|
|
RASAUTODIALENTRYA adEntry;
|
|
|
|
ZeroMemory(&adEntry, sizeof(adEntry));
|
|
adEntry.dwSize = sizeof(adEntry);
|
|
lstrcpyn(adEntry.szEntry, pszConnection, sizeof(adEntry.szEntry) / sizeof(TCHAR));
|
|
|
|
dwError = _RasSetAutodialAddressA(
|
|
NULL,
|
|
NULL,
|
|
&adEntry,
|
|
sizeof(adEntry),
|
|
1);
|
|
|
|
DEBUG_LEAVE(dwError);
|
|
return dwError;
|
|
}
|
|
|
|
SHSetValue(HKEY_CURRENT_USER, szRegPathRemoteAccess, szRegValInternetEntry,
|
|
REG_SZ, pszConnection, lstrlen(pszConnection));
|
|
|
|
DEBUG_LEAVE(0);
|
|
return 0;
|
|
}
|
|
|
|
|
|
BOOL
|
|
IsAutodialEnabled(
|
|
OUT BOOL *pfForceDial,
|
|
IN AUTODIAL *pConfig
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Read flags used to control autodial. Also honors SetOption setting
|
|
to override and not autodial.
|
|
|
|
Note: if autodial isn't enabled, the rest of the structure isn't read.
|
|
|
|
Arguments:
|
|
|
|
pConfig - AUTODIAL struct to store info. NULL is valid if info
|
|
isn't required.
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - Autodial is enabled
|
|
FALSE - Autodial is not enabled
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"IsAutodialEnabled",
|
|
"%#x, %#x",
|
|
pfForceDial,
|
|
pConfig
|
|
));
|
|
|
|
HKEY hKey;
|
|
DWORD dwRes, dwData = 0, dwSize, dwType;
|
|
BOOL fConfigured, fEnabled;
|
|
|
|
//
|
|
// Init out parameter
|
|
//
|
|
if(pfForceDial)
|
|
{
|
|
*pfForceDial = FALSE;
|
|
}
|
|
|
|
if(pConfig)
|
|
{
|
|
memset(pConfig, 0, sizeof(AUTODIAL));
|
|
}
|
|
|
|
//
|
|
// Get autodial enabled
|
|
//
|
|
fConfigured = fEnabled = TRUE;
|
|
|
|
// check registry setting
|
|
if(InternetReadRegistryDword(REGSTR_VAL_ENABLEAUTODIAL, &dwData) ||
|
|
0 == dwData)
|
|
{
|
|
fEnabled = fConfigured = FALSE;
|
|
}
|
|
|
|
if(fEnabled)
|
|
{
|
|
if(InternetReadRegistryDword(REGSTR_VAL_NONETAUTODIAL, &dwData) ||
|
|
0 == dwData)
|
|
{
|
|
// don't use sens -- imitate IE4 and before behavior
|
|
if(pConfig)
|
|
{
|
|
pConfig->fForceDial = TRUE;
|
|
}
|
|
if(pfForceDial)
|
|
{
|
|
*pfForceDial = TRUE;
|
|
}
|
|
}
|
|
|
|
// update fEnabled based on api setting
|
|
fEnabled = g_fAutodialEnableAPISetting;
|
|
}
|
|
|
|
|
|
if(NULL == pConfig)
|
|
{
|
|
DEBUG_LEAVE(fEnabled);
|
|
return fEnabled;
|
|
}
|
|
|
|
//
|
|
// save enabled to pconfig struct
|
|
//
|
|
pConfig->fEnabled = fEnabled;
|
|
|
|
pConfig->fConfigured = fConfigured;
|
|
|
|
|
|
//
|
|
// read security check
|
|
//
|
|
dwSize = sizeof(dwData);
|
|
if( GlobalPlatformType == PLATFORM_TYPE_WIN95 &&
|
|
InternetReadRegistryDword(szRegValEnableSecurityCheck, &dwData) == ERROR_SUCCESS &&
|
|
dwData)
|
|
{
|
|
pConfig->fSecurity = TRUE;
|
|
}
|
|
|
|
if(FALSE == fEnabled)
|
|
{
|
|
// if autodial isn't enabled, no point in reading the rest of the
|
|
// info because it isn't used
|
|
DEBUG_LEAVE(fEnabled);
|
|
return fEnabled;
|
|
}
|
|
|
|
//
|
|
// read connectoid name
|
|
//
|
|
CHAR szConnectoidName[RAS_MaxEntryName + 1];
|
|
if(ERROR_SUCCESS == GetAutodialConnection(szConnectoidName, RAS_MaxEntryName))
|
|
{
|
|
MultiByteToWideChar(CP_ACP, 0, szConnectoidName, -1, pConfig->pszEntryName, RAS_MaxEntryName);
|
|
}
|
|
else
|
|
{
|
|
pConfig->pszEntryName[0] = 0;
|
|
}
|
|
|
|
if(lstrlenW(pConfig->pszEntryName))
|
|
{
|
|
pConfig->fHasEntry = TRUE;
|
|
|
|
// if possible, verify that autodial entry actually exists
|
|
RasEntryPropHelp *pRasProp = new RasEntryPropHelp;
|
|
|
|
if (pRasProp)
|
|
{
|
|
if(pRasProp->GetError() == 0)
|
|
{
|
|
DWORD dwRet = pRasProp->GetW(pConfig->pszEntryName);
|
|
if((ERROR_SUCCESS != dwRet) && (ERROR_INVALID_FUNCTION != dwRet))
|
|
{
|
|
// ras doesn't know about this - blow it away
|
|
pConfig->fHasEntry = FALSE;
|
|
*pConfig->pszEntryName = 0;
|
|
}
|
|
}
|
|
delete pRasProp;
|
|
}
|
|
}
|
|
|
|
if(FALSE == pConfig->fHasEntry && (FALSE == DoConnectoidsExist()))
|
|
{
|
|
// We expect an entry at this point. If we don't and none exist at
|
|
// this point, autodial isn't, in fact, enabled.
|
|
pConfig->fEnabled = FALSE;
|
|
pConfig->fForceDial = FALSE;
|
|
|
|
if(pfForceDial)
|
|
{
|
|
*pfForceDial = FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// read autoconnect for the specified entry
|
|
//
|
|
if(pConfig->fHasEntry)
|
|
{
|
|
WCHAR szKey[MAX_PATH];
|
|
|
|
GetConnKeyW(pConfig->pszEntryName, szKey, ARRAYSIZE(szKey));
|
|
dwSize = sizeof(DWORD);
|
|
if(ERROR_SUCCESS == SHGetValueW(HKEY_CURRENT_USER, szKey,
|
|
REGSTR_DIAL_AUTOCONNECTW, &dwType, &dwData, &dwSize) &&
|
|
dwData)
|
|
{
|
|
pConfig->fUnattended = TRUE;
|
|
}
|
|
}
|
|
|
|
DEBUG_LEAVE(pConfig->fEnabled);
|
|
return pConfig->fEnabled;
|
|
}
|
|
|
|
|
|
UINT_PTR
|
|
SendDialmonMessage(
|
|
UINT uMessage,
|
|
BOOL fPost
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Send a message to dialmon
|
|
|
|
Arguments:
|
|
|
|
uMessage - message to send
|
|
fPost - post or send
|
|
|
|
Return Value:
|
|
|
|
Return of send or 0 if post
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Dword,
|
|
"SendDialmonMessage",
|
|
"%x, %B",
|
|
uMessage,
|
|
fPost
|
|
));
|
|
|
|
UINT_PTR uRet = 0;
|
|
|
|
// Send a message to dialmon's monitor window to start monitoring this
|
|
// connectoid
|
|
if(NULL == g_hwndWebCheck) {
|
|
g_hwndWebCheck = FindWindow(szWebCheckMonitorClass,NULL);
|
|
}
|
|
if(g_hwndWebCheck) {
|
|
if(fPost)
|
|
{
|
|
PostMessage(g_hwndWebCheck, uMessage, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
uRet = SendMessage(g_hwndWebCheck, uMessage, 0, 0);
|
|
}
|
|
}
|
|
|
|
DEBUG_LEAVE(uRet);
|
|
return uRet;
|
|
}
|
|
|
|
|
|
BOOL
|
|
GetRedialParameters(
|
|
IN LPWSTR pszConn,
|
|
OUT LPDWORD pdwDialAttempts,
|
|
OUT LPDWORD pdwDialInterval
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get redial information for a specific connectoid
|
|
|
|
Arguments:
|
|
|
|
pszConn - connection name
|
|
pdwDialAttempts - location to store dial attempts
|
|
pdwDialInterval - location to store dial interval
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - success
|
|
FALSE - failure
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"GetRedialParameters",
|
|
"%#x (%Q), %x, %x",
|
|
pszConn,
|
|
pszConn,
|
|
pdwDialAttempts,
|
|
pdwDialInterval
|
|
));
|
|
|
|
WCHAR szKey[MAX_PATH];
|
|
DWORD dwValue, dwSize;
|
|
HKEY hkey;
|
|
|
|
//
|
|
// validate and clear out variables
|
|
//
|
|
if(NULL == pdwDialAttempts || NULL == pdwDialInterval)
|
|
{
|
|
DEBUG_LEAVE(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// set to defaults
|
|
//
|
|
*pdwDialAttempts = DEFAULT_DIAL_ATTEMPTS;
|
|
*pdwDialInterval = DEFAULT_DIAL_INTERVAL;
|
|
|
|
//
|
|
// read values from registry
|
|
//
|
|
GetConnKeyW(pszConn, szKey, ARRAYSIZE(szKey));
|
|
dwSize = sizeof(DWORD);
|
|
if(ERROR_SUCCESS == SHGetValueW(HKEY_CURRENT_USER, szKey, REGSTR_VAL_REDIALATTEMPTSW, NULL, &dwValue, &dwSize) && dwValue)
|
|
{
|
|
*pdwDialAttempts = dwValue;
|
|
}
|
|
|
|
dwSize = sizeof(DWORD);
|
|
if(ERROR_SUCCESS == SHGetValueW(HKEY_CURRENT_USER, szKey, REGSTR_VAL_REDIALINTERVALW, NULL, &dwValue, &dwSize) && dwValue)
|
|
{
|
|
*pdwDialInterval = dwValue;
|
|
}
|
|
|
|
DEBUG_LEAVE(TRUE);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Win9x security check
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// stolen from ICW's wizglob.h -- BUGBUG - add to our tree
|
|
#define INSTANCE_PPPDRIVER 0x0002
|
|
typedef DWORD (WINAPI * ICFGISFILESHARINGTURNEDON ) (DWORD dwfDriverType, LPBOOL lpfSharingOn);
|
|
|
|
|
|
BOOL
|
|
IsSharingEnabled(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Silently determine whether sharing is turned on on PPP devices on Win9x
|
|
|
|
Arguments:
|
|
|
|
none
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - sharing on
|
|
FALSE - sharing off (or NT)
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"IsSharingEnabled",
|
|
NULL
|
|
));
|
|
|
|
ICFGISFILESHARINGTURNEDON lpIcfgIsFileSharingTurnedOn=NULL;
|
|
HINSTANCE hICFGInst = NULL;
|
|
BOOL fSharingIsOn = FALSE;
|
|
|
|
//
|
|
// Bail out on NT
|
|
//
|
|
if(PLATFORM_TYPE_WINNT == GlobalPlatformType)
|
|
{
|
|
DEBUG_LEAVE(FALSE);
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
hICFGInst = LoadLibraryA("icfg95.dll");
|
|
}
|
|
|
|
//
|
|
// Try and get entry point in icfg95.dll to check
|
|
//
|
|
if(hICFGInst)
|
|
{
|
|
DWORD dwRet;
|
|
lpIcfgIsFileSharingTurnedOn = (ICFGISFILESHARINGTURNEDON)GetProcAddress( hICFGInst, "IcfgIsFileSharingTurnedOn");
|
|
if(lpIcfgIsFileSharingTurnedOn)
|
|
dwRet = lpIcfgIsFileSharingTurnedOn(INSTANCE_PPPDRIVER, &fSharingIsOn);
|
|
|
|
FreeLibrary(hICFGInst);
|
|
}
|
|
|
|
DEBUG_LEAVE(fSharingIsOn);
|
|
return fSharingIsOn;
|
|
}
|
|
|
|
|
|
DWORD
|
|
PerformSecurityCheck(
|
|
IN HWND hwndParent,
|
|
IN DWORD dwFlags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Prompt user to fix sharing on PPP device on Win9x. Reboot if necessary.
|
|
|
|
Arguments:
|
|
|
|
hwndParent - parent window for any UI
|
|
dwFlags - flags possibly containing INTERNET_AUTODIAL_FAILIFSECURITYCHECK
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - failed test, may be rebooting
|
|
FALSE - passed test
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"PerformSecurityCheck",
|
|
"%#x, %#x",
|
|
hwndParent,
|
|
dwFlags
|
|
));
|
|
|
|
static BOOL fDoneCheckOnce = FALSE;
|
|
BOOL fNeedRestart = FALSE;
|
|
HINSTANCE hinstInetWiz;
|
|
INETPERFORMSECURITYCHECK lpInetPerformSecurityCheck;
|
|
CHAR szFilename[SMALLBUFLEN+1]="";
|
|
|
|
// only do this once per session, never on NT
|
|
if(PLATFORM_TYPE_WINNT == GlobalPlatformType || fDoneCheckOnce)
|
|
{
|
|
DEBUG_LEAVE(FALSE);
|
|
return FALSE;
|
|
}
|
|
fDoneCheckOnce = TRUE;
|
|
|
|
if(dwFlags & (INTERNET_AUTODIAL_FAILIFSECURITYCHECK | INTERNET_DIAL_UNATTENDED | INTERNET_AUTODIAL_FORCE_UNATTENDED))
|
|
{
|
|
if(IsSharingEnabled())
|
|
{
|
|
// silent check failed
|
|
DEBUG_LEAVE(TRUE);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
// get filename out of resource
|
|
LoadString(GlobalDllHandle,IDS_INETCFG_FILENAME,szFilename,
|
|
sizeof(szFilename));
|
|
|
|
// load the inetcfg dll
|
|
hinstInetWiz = LoadLibrary(szFilename);
|
|
INET_ASSERT(hinstInetWiz);
|
|
if (hinstInetWiz) {
|
|
|
|
// get the proc address
|
|
lpInetPerformSecurityCheck = (INETPERFORMSECURITYCHECK)
|
|
GetProcAddress(hinstInetWiz,szInetPerformSecurityCheck);
|
|
INET_ASSERT(lpInetPerformSecurityCheck);
|
|
if (lpInetPerformSecurityCheck)
|
|
{
|
|
// call the function to do system security check
|
|
(lpInetPerformSecurityCheck) (hwndParent, &fNeedRestart);
|
|
}
|
|
|
|
FreeLibrary(hinstInetWiz);
|
|
|
|
if(fNeedRestart)
|
|
{
|
|
// call RestartDialog in shell32
|
|
HINSTANCE hShell = LoadLibrary("shell32.dll");
|
|
_RESTARTDIALOG pfnRestart = NULL;
|
|
|
|
if(hShell)
|
|
{
|
|
pfnRestart = (_RESTARTDIALOG)GetProcAddress(hShell, (LPTSTR)59);
|
|
if(pfnRestart)
|
|
(*pfnRestart)(NULL, NULL, EWX_REBOOT);
|
|
FreeLibrary(hShell);
|
|
}
|
|
}
|
|
}
|
|
|
|
DEBUG_LEAVE(fNeedRestart);
|
|
return fNeedRestart;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Custom Dial Handler code
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
BOOL
|
|
IsCDH(
|
|
IN LPWSTR pszEntryName,
|
|
IN CDHINFO *pcdh
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Determine whether a connection uses a custom dial handler
|
|
|
|
Arguments:
|
|
|
|
pszEntryName - connection name
|
|
pcdh - pointer to structure to hold cdh info
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - connection uses custom dial handler
|
|
FALSE - doesn't
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"IsCDH",
|
|
"%#x (%Q), %#x",
|
|
pszEntryName,
|
|
pszEntryName,
|
|
pcdh
|
|
));
|
|
|
|
//
|
|
// clear out cdhinfo
|
|
//
|
|
memset(pcdh, 0, sizeof(CDHINFO));
|
|
|
|
if(PLATFORM_TYPE_WIN95 == GlobalPlatformType)
|
|
{
|
|
//
|
|
// Check registry settings on Win9x
|
|
//
|
|
|
|
WCHAR szKey[MAX_PATH];
|
|
DWORD dwType;
|
|
DWORD cbDllName = sizeof(pcdh->pszDllName);
|
|
DWORD cbFcnName = sizeof(pcdh->pszFcnName);
|
|
wnsprintfW(szKey, MAX_PATH, L"%ws\\%ws", szRegPathRNAProfileW, pszEntryName);
|
|
|
|
if((ERROR_SUCCESS == SHGetValueW(HKEY_CURRENT_USER, szKey, szRegValAutodialDllNameW, &dwType, (LPBYTE) pcdh->pszDllName, &cbDllName)) &&
|
|
(ERROR_SUCCESS == SHGetValueW(HKEY_CURRENT_USER, szKey, szRegValAutodialFcnNameW, &dwType, (LPBYTE) pcdh->pszFcnName, &cbFcnName)))
|
|
{
|
|
// try to read flags - not critical if can't find it
|
|
DWORD cbFlags = sizeof(DWORD);
|
|
SHGetValueW(HKEY_CURRENT_USER, szKey, szRegValAutodialFlagsW, &dwType, (LPBYTE) &(pcdh->dwHandlerFlags), &cbFlags);
|
|
if(0 == cbFlags)
|
|
pcdh->dwHandlerFlags = 0;
|
|
|
|
// if we got dll / fcn, we have a handler
|
|
pcdh->fHasHandler = TRUE;
|
|
|
|
// ICW's isign32.dll registers itself as a CDH but does no useful work. Ignore it.
|
|
// Note this could distinguish isign32.dll a little better -- right now it will
|
|
// incorectly find "aolisign32.dll" if such a thing were to exist.
|
|
if( StrStrIW(pcdh->pszDllName, L"isign32.dll") &&
|
|
StrStrIW(pcdh->pszFcnName, L"AutodialLogon"))
|
|
{
|
|
// nuke it
|
|
memset(pcdh, 0, sizeof(CDHINFO));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// No such this as a "CDH" on Win2k as defined by this mechanism.
|
|
// On Win2K, there's a new field in the rasentry struct specifically
|
|
// for this. See the function DialIfWin2KCDH.
|
|
//
|
|
// Always return FALSE for CDH on Win2K.
|
|
//
|
|
if(FALSE == GlobalPlatformVersion5)
|
|
{
|
|
//
|
|
// NT4 - this is broken -- we look in the RASENTRY struct for autodial
|
|
// function and dll but these fields are intended for use by NT's
|
|
// autodial code, NOT IE's. Prototypes are different and we only
|
|
// get by by luck - if NT finds these entries, it tries to find an
|
|
// A or W version of the exported function. CM is the only guy that
|
|
// does this and they don't export decorated A or W versions. Since
|
|
// NT can't find the function, it ignores the entries.
|
|
//
|
|
// This problem disappears on NT5 -- CM has thier own connectoid
|
|
// type. (Custom dial handlers in general won't be supported)
|
|
//
|
|
RasEntryPropHelp *pRasProp = new RasEntryPropHelp;
|
|
|
|
if (pRasProp)
|
|
{
|
|
if((0 == pRasProp->GetError()) && (0 == pRasProp->GetW(pszEntryName)))
|
|
{
|
|
// got entry, if there is custom dial fields, copy them to our
|
|
// struct
|
|
if(pRasProp->GetAutodiallDllW() && pRasProp->GetAutodialFuncW())
|
|
{
|
|
StrCpyNW(pcdh->pszDllName, pRasProp->GetAutodiallDllW(), sizeof(pcdh->pszDllName));
|
|
StrCpyNW(pcdh->pszFcnName, pRasProp->GetAutodialFuncW(), sizeof(pcdh->pszFcnName));
|
|
pcdh->fHasHandler = TRUE;
|
|
}
|
|
}
|
|
delete pRasProp;
|
|
}
|
|
}
|
|
}
|
|
|
|
DEBUG_LEAVE(pcdh->fHasHandler);
|
|
return pcdh->fHasHandler;
|
|
}
|
|
|
|
BOOL
|
|
CallCDH(
|
|
IN HWND hwndParent,
|
|
IN LPWSTR pszEntryName,
|
|
IN CDHINFO *pcdh,
|
|
IN DWORD dwOperation,
|
|
OUT LPDWORD lpdwResult
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Call a custom dial handler to perform an operation
|
|
|
|
Arguments:
|
|
|
|
hwndParent - parent window for any ui
|
|
pszEntryName - connection name
|
|
pcdh - pointer to structure to hold cdh info
|
|
dwOperation - a CDH operation to perform, one of the
|
|
INTERNET_CUSTOMDIAL_* operations.
|
|
lpdwResult - result of CDH operation
|
|
|
|
ERROR_SUCCESS - operation completed
|
|
ERROR_ALREADY_EXISTS - connection already exists (CM only)
|
|
ERROR_USER_DISCONNECTION - user cancelled operation
|
|
ERROR_INVALID_PARAMETER - CDH failed to load or service request
|
|
|
|
Returns Value:
|
|
|
|
BOOL
|
|
TRUE - CDH handled operation
|
|
FALSE - didn't
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"CallCDH",
|
|
"%#x, %#x (%Q), %#x, %#x, %#x",
|
|
hwndParent,
|
|
pszEntryName,
|
|
pszEntryName,
|
|
pcdh,
|
|
dwOperation,
|
|
lpdwResult
|
|
));
|
|
|
|
BOOL fRet = FALSE;
|
|
|
|
if(pcdh->fHasHandler)
|
|
{
|
|
// FIXME - verify handler supports requested operation by checking
|
|
// it's flags. Connection Manager has been known to assert if it's
|
|
// called to do something it doesn't understand.
|
|
|
|
HINSTANCE hinstDialerDll = LoadLibraryWrapW(pcdh->pszDllName);
|
|
if (hinstDialerDll)
|
|
{
|
|
PFN_DIAL_HANDLER lpInetDialHandler;
|
|
CHAR szFcnName[MAX_PATH + 1];
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, pcdh->pszFcnName, -1, szFcnName, MAX_PATH, NULL, NULL);
|
|
lpInetDialHandler = (PFN_DIAL_HANDLER)GetProcAddress(hinstDialerDll, szFcnName);
|
|
if (lpInetDialHandler)
|
|
{
|
|
#ifdef _X86_
|
|
// IBM Global Network is busted in that it expects to be called
|
|
// as cdecl when all other CDHs are stdcall. To get around
|
|
// this bustitude somewhat, restore esp after the call to get
|
|
// our stack frame back to a point where we won't fault.
|
|
DWORD dwSavedEsp;
|
|
_asm { mov [dwSavedEsp], esp }
|
|
#endif
|
|
|
|
// Thunk entry name to ansi
|
|
CHAR szEntryName[RAS_MaxEntryName + 1];
|
|
WideCharToMultiByte(CP_ACP, 0, pszEntryName, -1, szEntryName, RAS_MaxEntryName, NULL, NULL);
|
|
fRet = (lpInetDialHandler)(hwndParent, szEntryName, dwOperation, lpdwResult);
|
|
|
|
#ifdef _X86_
|
|
_asm { mov esp, [dwSavedEsp] }
|
|
#endif
|
|
}
|
|
|
|
FreeLibrary(hinstDialerDll);
|
|
}
|
|
}
|
|
|
|
DEBUG_LEAVE(fRet);
|
|
return fRet;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Initialization
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
VOID
|
|
InitAutodialModule(
|
|
BOOL fGlobalDataNeeded
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize autodial code
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
None,
|
|
"InitAutodialModule",
|
|
"%B",
|
|
fGlobalDataNeeded
|
|
));
|
|
|
|
// check for global data first - will only ever happen once
|
|
if(fGlobalDataNeeded && !GlobalDataInitialized)
|
|
{
|
|
GlobalDataInitialize();
|
|
}
|
|
|
|
// only do this once...
|
|
if(g_fAutodialInitialized)
|
|
{
|
|
DEBUG_LEAVE(0);
|
|
return;
|
|
}
|
|
|
|
// make sure internet settings key is open
|
|
EnsureInternetSettingsKeyCached();
|
|
|
|
// There is really no reason to acquire a crosprocess mutex
|
|
// We are going to creat a perprocess mutex when services are running. SPP
|
|
// wininet folks will explore whether this has to be expanded to include all processes
|
|
// (Shishir Pardikar)
|
|
|
|
if (FALSE == GlobalIsProcessNtService)
|
|
{
|
|
// create connection mutex
|
|
g_hConnectionMutex = OpenMutex(SYNCHRONIZE, FALSE, CONNECTION_MUTEX);
|
|
if (g_hConnectionMutex == NULL && (GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_NAME))
|
|
{
|
|
SECURITY_ATTRIBUTES* psa = SHGetAllAccessSA();
|
|
if (psa)
|
|
{
|
|
g_hConnectionMutex = CreateMutex(psa, FALSE, CONNECTION_MUTEX);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_hConnectionMutex = CreateMutex(NULL, FALSE, NULL);
|
|
}
|
|
INET_ASSERT(g_hConnectionMutex != INVALID_HANDLE_VALUE);
|
|
|
|
|
|
|
|
// create dial mutex to serialize access to RAS (per process)
|
|
g_hRasMutex = CreateMutex(NULL, FALSE, NULL);
|
|
INET_ASSERT(g_hRasMutex != INVALID_HANDLE_VALUE);
|
|
|
|
// create proxy registry mutex to serialize access to registry settings across processes
|
|
g_hProxyRegMutex = OpenMutex(SYNCHRONIZE, FALSE, PROXY_REG_MUTEX);
|
|
if (g_hProxyRegMutex == NULL && (GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_NAME))
|
|
{
|
|
SECURITY_ATTRIBUTES* psa = SHGetAllAccessSA();
|
|
if (psa)
|
|
{
|
|
g_hProxyRegMutex = CreateMutex(psa, FALSE, PROXY_REG_MUTEX);
|
|
}
|
|
}
|
|
|
|
INET_ASSERT(g_hProxyRegMutex != INVALID_HANDLE_VALUE);
|
|
|
|
|
|
|
|
|
|
if(FALSE == IsAutodialEnabled(NULL, NULL)) {
|
|
// if autodial not enabled, then set the fDontProcessHook flag so we
|
|
// exit our hook proc very quickly and don't interfere with Winsock
|
|
fDontProcessHook = TRUE;
|
|
}
|
|
|
|
if(GetModuleHandle("rnaapp.exe"))
|
|
{
|
|
// We're in rnaapp! Bail all winsock callbacks
|
|
g_fRNAAppProcess = TRUE;
|
|
}
|
|
DEBUG_PRINT(DIALUP, INFO, ("g_fRNAAppProcess = %B\n", g_fRNAAppProcess));
|
|
|
|
g_fAutodialInitialized = TRUE;
|
|
|
|
DEBUG_LEAVE(0);
|
|
}
|
|
|
|
|
|
VOID
|
|
ExitAutodialModule(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Clean up autodial code
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
None,
|
|
"ExitAutodialModule",
|
|
NULL
|
|
));
|
|
|
|
// don't do anything if not initialized
|
|
if(FALSE == g_fAutodialInitialized)
|
|
{
|
|
DEBUG_LEAVE(0);
|
|
return;
|
|
}
|
|
|
|
#ifdef CHECK_SENS
|
|
if(g_hSens) {
|
|
FreeLibrary(g_hSens);
|
|
g_hSens = NULL;
|
|
g_pfnIsNetworkAlive = NULL;
|
|
}
|
|
#endif
|
|
|
|
// close connection mutex
|
|
if(INVALID_HANDLE_VALUE != g_hConnectionMutex)
|
|
{
|
|
CloseHandle(g_hConnectionMutex);
|
|
g_hConnectionMutex = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
// close RAS mutex
|
|
if(INVALID_HANDLE_VALUE != g_hRasMutex)
|
|
{
|
|
CloseHandle(g_hRasMutex);
|
|
g_hRasMutex = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
// close proxy registry mutex
|
|
if(INVALID_HANDLE_VALUE != g_hProxyRegMutex)
|
|
{
|
|
CloseHandle(g_hProxyRegMutex);
|
|
g_hProxyRegMutex = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
// close user's reg key
|
|
CRefdKey* prk = (CRefdKey*)InterlockedExchangePointer((PVOID*)&g_prkBase, NULL);
|
|
CloseBaseProxyKey(prk);
|
|
|
|
if (g_hRasLib)
|
|
{
|
|
FreeLibrary(g_hRasLib);
|
|
g_hRasLib = NULL;
|
|
}
|
|
|
|
if(g_hIphlpapi)
|
|
{
|
|
FreeLibrary(g_hIphlpapi);
|
|
g_hIphlpapi = NULL;
|
|
g_pfnGetBestRoute = NULL;
|
|
}
|
|
|
|
g_fAutodialInitialized = FALSE;
|
|
|
|
DEBUG_LEAVE(0);
|
|
}
|
|
|
|
|
|
VOID
|
|
ResetAutodialModule(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Reset certain state when a global reset is called. Causes settings
|
|
to be reread and some one-time operations to be redone.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
None,
|
|
"ResetAutodialModule",
|
|
NULL
|
|
));
|
|
|
|
// global settings have changed - reset hook to look again
|
|
fDontProcessHook = FALSE;
|
|
|
|
// refresh proxy info and next connection
|
|
g_fConnChecked = FALSE;
|
|
|
|
#ifdef CHECK_SENS
|
|
// refresh our sens state
|
|
g_fSensInstalled = TRUE;
|
|
#endif
|
|
|
|
// beta 1 hack
|
|
g_fCheckedUpgrade = FALSE;
|
|
|
|
// check security context again for HKCU settings
|
|
CRefdKey* prk = (CRefdKey*)InterlockedExchangePointer((PVOID*)&g_prkBase, NULL);
|
|
CloseBaseProxyKey(prk);
|
|
|
|
DEBUG_LEAVE(0);
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Connection management code
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#ifdef CHECK_SENS
|
|
|
|
|
|
BOOL
|
|
GetSensLanState(
|
|
OUT LPDWORD pdwFlags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Load and query sens to see if any packets have moved on the lan.
|
|
Beware of service not started and/or api dll not present.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - Lan is active
|
|
FALSE - Lan is not active
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"GetSensLanState",
|
|
"%#x",
|
|
pdwFlags
|
|
));
|
|
|
|
BOOL fConnected = TRUE;
|
|
|
|
// initialize out flags parameter to default - lan connectivity
|
|
*pdwFlags = NETWORK_ALIVE_LAN;
|
|
|
|
// If sens isn't around to ask, we have to assume the lan is connected
|
|
|
|
if(FALSE == g_fSensInstalled)
|
|
{
|
|
DEBUG_LEAVE(TRUE);
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// Try to load SENS and get our entry point
|
|
//
|
|
if(NULL == g_hSens) {
|
|
|
|
INT_PTR fSensRunning;
|
|
|
|
if(PLATFORM_TYPE_WINNT == GlobalPlatformType)
|
|
{
|
|
// check for running service on NT
|
|
fSensRunning = IsServiceRunning("Sens", SERVICE_ACTIVE);
|
|
}
|
|
else
|
|
{
|
|
// check for dialmon loaded bits on Win9x
|
|
|
|
//
|
|
// Webcheck creates this named event to track the lifetime of Sens.
|
|
// It's created with CreateEventA so we need to open with with
|
|
// OpenEventA.
|
|
//
|
|
HANDLE hEvent;
|
|
|
|
fSensRunning = FALSE;
|
|
|
|
hEvent = OpenEventA(SYNCHRONIZE, FALSE, "MS_WebcheckExternalsTerminateEvent");
|
|
if(hEvent)
|
|
{
|
|
fSensRunning = TRUE;
|
|
CloseHandle(hEvent);
|
|
}
|
|
}
|
|
|
|
// On win9x check with dialmon to see if sens is running before
|
|
// calling it. If we call it and it isn't loaded, it'll load itself
|
|
// and defeat the purpose of not loading it.
|
|
if(fSensRunning)
|
|
{
|
|
g_hSens = LoadLibrary("sensapi.dll");
|
|
if(g_hSens) {
|
|
g_pfnIsNetworkAlive = (ISNETWORKALIVE)GetProcAddress(g_hSens, "IsNetworkAlive");
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Call sens to get its state
|
|
//
|
|
if(g_pfnIsNetworkAlive) {
|
|
fConnected = g_pfnIsNetworkAlive(pdwFlags);
|
|
g_fSensInstalled = TRUE;
|
|
if(fConnected) {
|
|
if(ERROR_SUCCESS != GetLastError()) {
|
|
// sens service not running - must assume lan is available
|
|
g_fSensInstalled = FALSE;
|
|
}
|
|
if(0 == (*pdwFlags & (NETWORK_ALIVE_LAN | NETWORK_ALIVE_AOL)))
|
|
{
|
|
// no AOL or LAN flag, so return no lan connectivity
|
|
fConnected = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
DEBUG_PRINT(DIALUP, INFO, ("g_fSensInstalled = %B\n", g_fSensInstalled));
|
|
|
|
//
|
|
// If sens isn't alive but we managed to load the dll, unload it
|
|
// now as it's useless. Otherwise, hang on to the dll. No need to
|
|
// load and unload it all the time.
|
|
//
|
|
if(FALSE == g_fSensInstalled && g_hSens) {
|
|
FreeLibrary(g_hSens);
|
|
g_hSens = NULL;
|
|
g_pfnIsNetworkAlive = NULL;
|
|
}
|
|
|
|
DEBUG_LEAVE(fConnected);
|
|
return fConnected;
|
|
}
|
|
|
|
|
|
|
|
#endif // CHECK_SENS
|
|
|
|
|
|
BOOL
|
|
IsDialUpConnection(
|
|
IN BOOL fForceRefresh,
|
|
OUT LPDWORD lpdwConnectionNum
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Determines whether there's a dial-up connection. Refreshes information
|
|
periodically.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - A dial-up connection exists
|
|
FALSE - No dial-up connection
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"IsDialUpConnection",
|
|
"%B, %x",
|
|
fForceRefresh,
|
|
lpdwConnectionNum
|
|
));
|
|
|
|
static BOOL fRasLoaded = FALSE;
|
|
DWORD dwNewTickCount, dwElapsed, dwBytes, dwRes, dwConNum = 0;
|
|
BOOL fProcessedRecently = FALSE, fRet;
|
|
|
|
//
|
|
// Initialize out parameter
|
|
//
|
|
if(lpdwConnectionNum)
|
|
{
|
|
*lpdwConnectionNum = 0;
|
|
}
|
|
|
|
//
|
|
// serialize
|
|
//
|
|
WaitForSingleObject(g_hRasMutex, INFINITE);
|
|
|
|
//
|
|
// Check out how recently we polled ras
|
|
//
|
|
dwNewTickCount = GetTickCountWrap();
|
|
dwElapsed = dwNewTickCount - g_dwLastDialupTicks;
|
|
|
|
//
|
|
// Only refresh if more than MIN... ticks has passed
|
|
//
|
|
if((dwElapsed >= MIN_RNA_BUSY_CHECK_INTERVAL) || fForceRefresh) {
|
|
g_dwLastDialupTicks = dwNewTickCount;
|
|
if(DoConnectoidsExist())
|
|
{
|
|
if(FALSE == fRasLoaded)
|
|
fRasLoaded = EnsureRasLoaded();
|
|
|
|
if(fRasLoaded)
|
|
{
|
|
g_RasCon.Enum();
|
|
if(g_RasCon.GetError() == 0)
|
|
g_dwConnections = g_RasCon.GetConnectionsCount();
|
|
else
|
|
g_dwConnections = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_dwConnections = 0;
|
|
}
|
|
}
|
|
|
|
DEBUG_PRINT(DIALUP, INFO, ("Found %d connections\n", g_dwConnections));
|
|
|
|
if(g_dwConnections > 1 && lpdwConnectionNum)
|
|
{
|
|
//
|
|
// We have more than one connection and caller wants to know which one
|
|
// is the interesting one. Try to find a VPN connectoid.
|
|
//
|
|
// Note: RasGetEntryPropertiesA doesn't exist on Win95 Gold. However,
|
|
// you need RAS 1.2 (which has it) for the VPN device so we're ok
|
|
// using it. If we can't dynaload it for some inexplicable reason,
|
|
// we'll just end up not finding a VPN entry and setting proxy
|
|
// settings to the first connection.
|
|
//
|
|
// Note we use an array of 2 rasentry structures because NT wants to
|
|
// a phone number list after the actual struct and we need space for it.
|
|
// An extra RASENTRY struct is 1700+ bytes so it should be sufficient.
|
|
//
|
|
RasEntryPropHelp *pRasProp = new RasEntryPropHelp;
|
|
|
|
if (pRasProp)
|
|
{
|
|
for(dwConNum = 0; dwConNum < g_dwConnections; dwConNum++)
|
|
{
|
|
if(0 == pRasProp->GetW(g_RasCon.GetEntryW(dwConNum)))
|
|
{
|
|
if(0 == lstrcmpiA(pRasProp->GetDeviceTypeA(), RASDT_Vpn))
|
|
{
|
|
DEBUG_PRINT(DIALUP, INFO, ("Found VPN entry: %ws\n",
|
|
g_RasCon.GetEntryW(dwConNum)));
|
|
*lpdwConnectionNum = dwConNum;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
delete pRasProp;
|
|
}
|
|
}
|
|
|
|
fRet = (BOOL)(g_dwConnections != 0);
|
|
|
|
//
|
|
// verify status of connection we're interested in is RASCS_Connected.
|
|
//
|
|
if(fRet)
|
|
{
|
|
RasGetConnectStatusHelp RasGetConnectStatus(g_RasCon.GetHandle(dwConNum));
|
|
dwRes = RasGetConnectStatus.GetError();
|
|
if(dwRes || (RasGetConnectStatus.ConnState() != RASCS_Connected))
|
|
{
|
|
fRet = FALSE;
|
|
}
|
|
|
|
DEBUG_PRINT(DIALUP, INFO, ("Connect Status: dwRet=%x, connstate=%x\n", dwRes, RasGetConnectStatus.ConnState()));
|
|
}
|
|
|
|
ReleaseMutex(g_hRasMutex);
|
|
|
|
DEBUG_LEAVE(fRet);
|
|
return fRet;
|
|
}
|
|
|
|
|
|
BOOL
|
|
IsLanConnection(
|
|
OUT LPDWORD pdwFlags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Determines whether there's a lan connection. Refreshes information
|
|
periodically.
|
|
|
|
When Sens is present, AOL functionality is retuned as TRUE with
|
|
*pdwFlags = NETWORK_ALIVE_AOL.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - A lan connection exists
|
|
FALSE - No lan connection
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"IsLanConnection",
|
|
"%#x",
|
|
pdwFlags
|
|
));
|
|
|
|
static DWORD dwLastSensTicks = 0;
|
|
static BOOL fSensState = TRUE;
|
|
static DWORD dwSensFlags = 0;
|
|
DWORD dwNewTickCount, dwElapsed;
|
|
BOOL fRet = TRUE;
|
|
|
|
// init out parameter
|
|
INET_ASSERT(pdwFlags);
|
|
*pdwFlags = 0;
|
|
|
|
#ifdef CHECK_SENS
|
|
//
|
|
// Check connectivity apis to see if lan is really present
|
|
//
|
|
if(fRet)
|
|
{
|
|
dwNewTickCount = GetTickCountWrap();
|
|
dwElapsed = dwNewTickCount - dwLastSensTicks;
|
|
if(dwElapsed >= MIN_SENS_CHECK_INTERVAL)
|
|
{
|
|
fSensState = GetSensLanState(&dwSensFlags);
|
|
dwLastSensTicks = dwNewTickCount;
|
|
}
|
|
fRet = fSensState;
|
|
*pdwFlags = dwSensFlags;
|
|
}
|
|
#endif
|
|
|
|
DEBUG_LEAVE(fRet);
|
|
return fRet;
|
|
}
|
|
|
|
|
|
VOID
|
|
CheckForUpgrade(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Performs processing that needs to happen when we upgrade to IE5.
|
|
|
|
- Migrate proxy and dial settings on upgrade
|
|
- Migrate legacy proxy settings when they change
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
None,
|
|
"CheckForUpgrade",
|
|
NULL
|
|
));
|
|
|
|
DWORD dwMigrateState = 1, dwRet, dwEntries = 0;
|
|
char szUserName[10];
|
|
DWORD cbUserNameSize = ARRAYSIZE(szUserName);
|
|
CRefdKey* prkBase = FindBaseProxyKey();
|
|
|
|
//
|
|
// Bail out right away if we've already done this
|
|
// Or if we are running in an NT service such as the usermode portion of webdav redir
|
|
// in order to avoid deadlocks
|
|
|
|
// Also check to make sure we're not running as .default or SYSTEM
|
|
|
|
if(prkBase &&
|
|
(FALSE == g_fCheckedUpgrade) &&
|
|
(FALSE == GlobalIsProcessNtService) &&
|
|
!IsInGUIModeSetup() &&
|
|
!(GlobalPlatformWhistler &&
|
|
GlobalUserName.Get(szUserName,&cbUserNameSize) &&
|
|
(0 == lstrcmpi(szUserName, ".Default") ||
|
|
0 == lstrcmpi(szUserName, "SYSTEM"))))
|
|
{
|
|
LONG lResult;
|
|
DWORD dwType, dwExclude, dwSize = sizeof(DWORD), dwDisp;
|
|
RasEnumHelp *pRasEnum = NULL;
|
|
//
|
|
// Check to see if proxy settings have been migrated
|
|
//
|
|
if(ERROR_SUCCESS != SHGetValue(prkBase->GetKey(),
|
|
REGSTR_PATH_INTERNET_SETTINGS, szMigrateProxy, &dwType, &dwMigrateState, &dwSize))
|
|
{
|
|
dwMigrateState = 0;
|
|
}
|
|
|
|
DEBUG_PRINT(DIALUP, INFO, ("dwMigrateState=%d\n", dwMigrateState));
|
|
|
|
//
|
|
// set up list of connectoids
|
|
//
|
|
if(DoConnectoidsExist() && EnsureRasLoaded() && FALSE == GlobalDisableNT4RasCheck)
|
|
{
|
|
pRasEnum = new RasEnumHelp;
|
|
if(pRasEnum != NULL)
|
|
{
|
|
dwRet = pRasEnum->GetError();
|
|
dwEntries = pRasEnum->GetEntryCount();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Migrate legacy proxy settings to all connections
|
|
//
|
|
if(0 == dwMigrateState)
|
|
{
|
|
INTERNET_PROXY_INFO_EX info;
|
|
|
|
// start off with clean proxy struct
|
|
memset(&info, 0, sizeof(info));
|
|
info.dwStructSize = sizeof(INTERNET_PROXY_INFO_EX);
|
|
|
|
// need to migrate settings
|
|
if(ReadLegacyProxyInfo(szRegPathInternetSettings, &info))
|
|
{
|
|
#ifndef UNIX
|
|
// make sure autodiscovery is on
|
|
info.dwFlags |= PROXY_TYPE_AUTO_DETECT;
|
|
#endif /* !UNIX */
|
|
|
|
// Save proxy settings to for lan
|
|
info.lpszConnectionName = NULL;
|
|
WriteProxySettings(&info, TRUE);
|
|
|
|
// Save legacy settings to special location so we can check
|
|
// for change later
|
|
info.lpszConnectionName = LEGACY_SAVE_NAME;
|
|
WriteProxySettings(&info, TRUE);
|
|
|
|
//
|
|
// If we're not turning on autodiscovery for dialup connections
|
|
// by default, get rid of it at this point
|
|
//
|
|
if(FALSE == EnableAutodiscoverForDialup())
|
|
{
|
|
info.dwFlags &= ~PROXY_TYPE_AUTO_DETECT;
|
|
}
|
|
|
|
// Save settings for each connectoid
|
|
DWORD i;
|
|
for(i=0; i<dwEntries; i++)
|
|
{
|
|
info.lpszConnectionName = pRasEnum->GetEntryA(i);
|
|
WriteProxySettings(&info, TRUE);
|
|
}
|
|
|
|
// clean memory possibly allocated by ReadLegacyProxyInfo
|
|
info.lpszConnectionName = NULL; // not allocated, don't free
|
|
CleanProxyStruct(&info);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check to see if other dial-up settings have been migrated
|
|
//
|
|
|
|
if(0 == dwMigrateState && dwEntries)
|
|
{
|
|
CHAR szKey[MAX_PATH];
|
|
DWORD dwMinutes, dwAttempts, dwInterval, dwWait, i;
|
|
DWORD dwEnable;
|
|
|
|
// read dial attempts and wait
|
|
if(InternetReadRegistryDword(REGSTR_VAL_REDIALATTEMPTS, &dwAttempts))
|
|
dwAttempts = DEFAULT_DIAL_ATTEMPTS;
|
|
if(InternetReadRegistryDword(REGSTR_VAL_REDIALINTERVAL, &dwInterval))
|
|
dwInterval = DEFAULT_DIAL_INTERVAL;
|
|
|
|
// Get idle enable
|
|
if(InternetReadRegistryDword(REGSTR_VAL_ENABLEAUTODISCONNECT, &dwEnable) ||
|
|
0 == dwEnable)
|
|
{
|
|
dwEnable = 0;
|
|
dwMinutes = 20;
|
|
}
|
|
|
|
// if enabled, get minutes
|
|
if(dwEnable &&
|
|
InternetReadRegistryDword(REGSTR_VAL_DISCONNECTIDLETIME, &dwMinutes))
|
|
{
|
|
dwEnable = 0;
|
|
dwMinutes = 20;
|
|
}
|
|
|
|
// enumerate ras entries
|
|
for(i=0; i<dwEntries; i++)
|
|
{
|
|
DWORD dwDisposition;
|
|
HKEY hkey;
|
|
long lRes;
|
|
|
|
// migrate settings for this connectoid
|
|
GetConnKeyA(pRasEnum->GetEntryA(i), szKey, ARRAYSIZE(szKey));
|
|
SHSetValueA(HKEY_CURRENT_USER, szKey, REGSTR_VAL_ENABLEAUTODISCONNECT, REG_DWORD, (BYTE *)&dwEnable, sizeof(DWORD));
|
|
SHSetValueA(HKEY_CURRENT_USER, szKey, REGSTR_VAL_DISCONNECTIDLETIME, REG_DWORD, (BYTE *)&dwMinutes, sizeof(DWORD));
|
|
SHSetValueA(HKEY_CURRENT_USER, szKey, REGSTR_VAL_ENABLEEXITDISCONNECT, REG_DWORD, (BYTE *)&dwEnable, sizeof(DWORD));
|
|
SHSetValueA(HKEY_CURRENT_USER, szKey, REGSTR_VAL_REDIALATTEMPTS, REG_DWORD, (BYTE *)&dwAttempts, sizeof(DWORD));
|
|
SHSetValueA(HKEY_CURRENT_USER, szKey, REGSTR_VAL_REDIALINTERVAL, REG_DWORD, (BYTE *)&dwInterval, sizeof(DWORD));
|
|
}
|
|
}
|
|
|
|
if(pRasEnum)
|
|
delete pRasEnum;
|
|
|
|
//
|
|
// mark setings as migrated so we don't do this again next time
|
|
//
|
|
dwDisp = 1;
|
|
SHSetValueA(prkBase->GetKey(), REGSTR_PATH_INTERNET_SETTINGS,
|
|
szMigrateProxy, REG_DWORD, &dwDisp, sizeof(DWORD));
|
|
|
|
if(dwMigrateState)
|
|
{
|
|
// We have already migrated settings. If legacy settings have
|
|
// changed, update current connection.
|
|
INTERNET_PROXY_INFO_EX saved, current, destination;
|
|
|
|
memset(&saved, 0, sizeof(saved));
|
|
saved.dwStructSize = sizeof(INTERNET_PROXY_INFO_EX);
|
|
saved.lpszConnectionName = LEGACY_SAVE_NAME;
|
|
|
|
memset(¤t, 0, sizeof(current));
|
|
current.dwStructSize = sizeof(INTERNET_PROXY_INFO_EX);
|
|
|
|
memset(&destination, 0, sizeof(destination));
|
|
destination.dwStructSize = sizeof(INTERNET_PROXY_INFO_EX);
|
|
|
|
if( ReadLegacyProxyInfo(szRegPathInternetSettings, ¤t) &&
|
|
ERROR_SUCCESS == ReadProxySettings(&saved))
|
|
{
|
|
BOOL fChanged = FALSE;
|
|
|
|
//
|
|
// see if they've changed
|
|
//
|
|
if((saved.dwFlags & LEGACY_MIGRATE_FLAGS) != (current.dwFlags & LEGACY_MIGRATE_FLAGS))
|
|
{
|
|
fChanged = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// Only check for autoconfig url match if setting is the same and on because
|
|
// legacy saved for no autoconfig url is to delete the url.
|
|
if((saved.dwFlags & PROXY_TYPE_AUTO_PROXY_URL) &&
|
|
(FALSE == IsConnectionMatch(saved.lpszAutoconfigUrl, current.lpszAutoconfigUrl)))
|
|
{
|
|
fChanged = TRUE;
|
|
}
|
|
}
|
|
if(FALSE == IsConnectionMatch(saved.lpszProxy, current.lpszProxy))
|
|
{
|
|
fChanged = TRUE;
|
|
}
|
|
if(FALSE == IsConnectionMatch(saved.lpszProxyBypass, current.lpszProxyBypass))
|
|
{
|
|
fChanged = TRUE;
|
|
}
|
|
|
|
// if they have, save to current connection
|
|
if(fChanged)
|
|
{
|
|
DWORD dwIndex;
|
|
LPCSTR lpszTemp;
|
|
|
|
// save new legacy settings to check again later
|
|
current.lpszConnectionName = LEGACY_SAVE_NAME;
|
|
WriteProxySettings(¤t, TRUE);
|
|
|
|
// read existing lan settings
|
|
destination.lpszConnectionName = NULL;
|
|
ReadProxySettings(&destination);
|
|
|
|
// fix flags
|
|
destination.dwFlags = (destination.dwFlags & ~LEGACY_MIGRATE_FLAGS) | (current.dwFlags & LEGACY_MIGRATE_FLAGS);
|
|
|
|
// fix proxy server / override
|
|
lpszTemp = destination.lpszProxy;
|
|
destination.lpszProxy = current.lpszProxy;
|
|
current.lpszProxy = lpszTemp;
|
|
|
|
lpszTemp = destination.lpszProxyBypass;
|
|
destination.lpszProxyBypass = current.lpszProxyBypass;
|
|
current.lpszProxyBypass = lpszTemp;
|
|
|
|
// fix autoconfig url
|
|
lpszTemp = destination.lpszAutoconfigUrl;
|
|
destination.lpszAutoconfigUrl = current.lpszAutoconfigUrl;
|
|
current.lpszAutoconfigUrl = lpszTemp;
|
|
|
|
// save it
|
|
WriteProxySettings(&destination, TRUE);
|
|
}
|
|
}
|
|
|
|
saved.lpszConnectionName = NULL;
|
|
current.lpszConnectionName = NULL;
|
|
destination.lpszConnectionName = NULL;
|
|
CleanProxyStruct(&saved);
|
|
CleanProxyStruct(¤t);
|
|
CleanProxyStruct(&destination);
|
|
}
|
|
|
|
// don't run this code again
|
|
g_fCheckedUpgrade = TRUE;
|
|
}
|
|
|
|
CloseBaseProxyKey(prkBase);
|
|
|
|
DEBUG_LEAVE(0);
|
|
}
|
|
|
|
|
|
DWORD
|
|
FixProxySettings(
|
|
IN LPWSTR pszConnW,
|
|
IN BOOL fForceUpdate,
|
|
IN DWORD dwLanFlags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Copy lan or dial-up proxy settings to generic key and tell proxy code
|
|
new proxy information
|
|
|
|
Arguments:
|
|
|
|
pszConn - connection name to switch to
|
|
fForceUpdate - set regardless of having set before
|
|
dwLanFlags - distinguish between LAN and AOL connection
|
|
|
|
Return Value:
|
|
|
|
DWORD
|
|
0 - no proxy for this connection
|
|
1 - proxy exists for this connection
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Int,
|
|
"FixProxySettings",
|
|
"%#x (%Q), %B, %#x",
|
|
pszConnW,
|
|
pszConnW,
|
|
fForceUpdate,
|
|
dwLanFlags
|
|
));
|
|
|
|
static TCHAR pszLastConn[RAS_MaxEntryName+1];
|
|
static DWORD dwEnable = 0;
|
|
CHAR szConn[RAS_MaxEntryName + 1];
|
|
LPSTR pszConn = NULL;
|
|
|
|
if(pszConnW != NULL)
|
|
{
|
|
*szConn = '\0';
|
|
pszConn = szConn;
|
|
WideCharToMultiByte(CP_ACP, 0, pszConnW, -1, pszConn, RAS_MaxEntryName, NULL, NULL);
|
|
}
|
|
|
|
//
|
|
// Make sure we've listened to any global settings changed that happened
|
|
// in other processes
|
|
//
|
|
if (InternetSettingsChanged()) {
|
|
ChangeGlobalSettings();
|
|
}
|
|
|
|
//
|
|
// Ensure upgrade stuff is done
|
|
//
|
|
CheckForUpgrade();
|
|
|
|
//
|
|
// Is this connection already fixed?
|
|
//
|
|
if(g_fConnChecked && (FALSE == fForceUpdate)) {
|
|
if((NULL == pszConn && 0 == *pszLastConn) ||
|
|
0 == lstrcmp(pszConn, pszLastConn)) {
|
|
// already fixed this connection
|
|
|
|
DEBUG_LEAVE(dwEnable);
|
|
return dwEnable;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Get proxy struct for proxy object
|
|
//
|
|
INTERNET_PROXY_INFO_EX info;
|
|
memset(&info, 0, sizeof(info));
|
|
info.dwStructSize = sizeof(info);
|
|
info.lpszConnectionName = pszConn;
|
|
|
|
//
|
|
// Read proxy settings for this connection unless it's LAN/AOL
|
|
// in which case we want no proxy
|
|
//
|
|
if(pszConn || 0 == (dwLanFlags & NETWORK_ALIVE_AOL))
|
|
{
|
|
if (ReadProxySettings(&info) != ERROR_SUCCESS)
|
|
{
|
|
DEBUG_LEAVE(dwEnable);
|
|
return dwEnable;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Save connection we fixed
|
|
//
|
|
if(NULL == pszConn) {
|
|
// lan
|
|
*pszLastConn = 0;
|
|
} else {
|
|
// connectoid
|
|
lstrcpyn(pszLastConn, pszConn, RAS_MaxEntryName + 1);
|
|
}
|
|
|
|
// tell caller if proxy is enabled
|
|
if(info.dwFlags & PROXY_TYPE_PROXY)
|
|
{
|
|
dwEnable = 1;
|
|
}
|
|
else
|
|
{
|
|
dwEnable = 0;
|
|
}
|
|
|
|
GlobalProxyInfo.SetProxySettings(&info, FALSE);
|
|
|
|
//GlobalProxyInfo.RefreshProxySettings(FALSE);
|
|
|
|
//
|
|
// Copy current settings to the legacy reg locations so legacy
|
|
// apps can find them.
|
|
//
|
|
info.lpszConnectionName = LEGACY_SAVE_NAME;
|
|
WriteLegacyProxyInfo(szRegPathInternetSettings, &info, TRUE);
|
|
WriteProxySettings(&info, TRUE);
|
|
|
|
// free up memory allocated by ReadProxySettings
|
|
info.lpszConnectionName = NULL; // not allocated, don't free
|
|
CleanProxyStruct(&info);
|
|
|
|
//
|
|
// Flag we've checked this at least once so in future we can bail out early
|
|
//
|
|
g_fConnChecked = TRUE;
|
|
|
|
DEBUG_LEAVE(dwEnable);
|
|
return dwEnable;
|
|
}
|
|
|
|
|
|
BOOL
|
|
FixProxySettingsForCurrentConnection(
|
|
IN BOOL fForceUpdate
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Figure out the current connection and fix proxy settings for it.
|
|
Basically a cheap, return-no-info version of GetConnectedStateEx used
|
|
by the winsock callback.
|
|
|
|
Arguments:
|
|
|
|
none
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - connected
|
|
FALSE - not connected
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"FixProxySettingsForCurrentConnection",
|
|
"%B",
|
|
fForceUpdate
|
|
));
|
|
|
|
|
|
BOOL fRet, fForceDial;
|
|
DWORD dwFixEntry;
|
|
|
|
//
|
|
// Make sure everything's initialized
|
|
//
|
|
InitAutodialModule(TRUE);
|
|
|
|
// serialize connection type stuff
|
|
WaitForSingleObject(g_hConnectionMutex, INFINITE);
|
|
|
|
//
|
|
// Check to see if we have a dialup connection
|
|
//
|
|
fRet = IsDialUpConnection(FALSE, &dwFixEntry);
|
|
if(fRet)
|
|
{
|
|
FixProxySettings(g_RasCon.GetEntryW(dwFixEntry), fForceUpdate, 0);
|
|
}
|
|
|
|
//
|
|
// If dial always isn't set, check lan setting
|
|
//
|
|
IsAutodialEnabled(&fForceDial, NULL);
|
|
|
|
if(FALSE == fRet && FALSE == fForceDial)
|
|
{
|
|
//
|
|
// no ras connections - ensure LAN proxy settings are correct
|
|
//
|
|
DWORD dwFlags;
|
|
fRet = IsLanConnection(&dwFlags);
|
|
|
|
//
|
|
// Whether we have a lan connection or not, prop lan proxy settings.
|
|
// This allows unknown connections to use lan settings.
|
|
//
|
|
FixProxySettings(NULL, fForceUpdate, dwFlags);
|
|
}
|
|
|
|
ReleaseMutex(g_hConnectionMutex);
|
|
|
|
DEBUG_LEAVE(fRet);
|
|
return fRet;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Win2K Helper Functions
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
BOOL
|
|
DialIfWin2KCDH(
|
|
IN LPWSTR pszEntry,
|
|
IN HWND hwndParent,
|
|
IN BOOL fHideParent,
|
|
OUT DWORD *lpdwResult,
|
|
OUT DWORD_PTR *lpdwConnection
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Check a connectoid to see if it has a Win2K custom dial handler and if
|
|
so, do the voodoo magic to dial it
|
|
|
|
Arguments:
|
|
|
|
lpParams - dial params
|
|
hwndParent - parent window
|
|
fHideParent - if true, hide this window if dialing this connectoid
|
|
lpdwResult - result of dial (set if return is TRUE)
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - Attempted to dial Win2K CDH
|
|
FALSE - didn't
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"DialIfWin2KCDH",
|
|
"%x (%Q), %x, %B, %x, %x",
|
|
pszEntry,
|
|
pszEntry,
|
|
hwndParent,
|
|
fHideParent,
|
|
lpdwResult,
|
|
lpdwConnection
|
|
));
|
|
|
|
DWORD dwRet;
|
|
RasEntryPropHelp *pRasProp = new RasEntryPropHelp;
|
|
BOOL fResult = FALSE;
|
|
|
|
if (pRasProp == NULL)
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
if(FALSE == GlobalPlatformVersion5)
|
|
{
|
|
// not on win2k, bag
|
|
goto Cleanup;
|
|
}
|
|
|
|
// get props for this connectoid and see if it has a custom dial dll
|
|
|
|
if(ERROR_SUCCESS != (dwRet = pRasProp->GetW(pszEntry)))
|
|
{
|
|
// error getting rasentry struct
|
|
goto Cleanup;
|
|
}
|
|
|
|
if(NULL == pRasProp->GetCustomDialDllW())
|
|
{
|
|
// no custom dial dll
|
|
goto Cleanup;
|
|
}
|
|
|
|
// hide parent window if necessary
|
|
if(fHideParent)
|
|
{
|
|
ShowWindow(hwndParent, SW_HIDE);
|
|
}
|
|
|
|
// call rasdialdlg to dial the custom dude
|
|
HMODULE hLib;
|
|
RASDIALDLG rdd;
|
|
_RASDIALDLGW pfnRdd;
|
|
|
|
hLib = LoadLibrary("rasdlg.dll");
|
|
if(hLib)
|
|
{
|
|
pfnRdd = (_RASDIALDLGW)GetProcAddress(hLib, "RasDialDlgW");
|
|
if(pfnRdd)
|
|
{
|
|
memset(&rdd, 0, sizeof(rdd));
|
|
rdd.dwSize = sizeof(RASDIALDLG);
|
|
rdd.hwndOwner = hwndParent;
|
|
dwRet = (*pfnRdd)(NULL, pszEntry, NULL, &rdd);
|
|
}
|
|
FreeLibrary(hLib);
|
|
}
|
|
else
|
|
{
|
|
// really bad...
|
|
goto Cleanup;
|
|
}
|
|
|
|
// figure out how we did
|
|
if(dwRet)
|
|
{
|
|
DWORD dwEntry;
|
|
|
|
// success
|
|
*lpdwResult = ERROR_SUCCESS;
|
|
|
|
// find hconn for the thing we just dialed
|
|
if(lpdwConnection)
|
|
{
|
|
if(IsDialUpConnection(TRUE, &dwEntry))
|
|
{
|
|
*lpdwConnection = (DWORD_PTR) g_RasCon.GetHandle(dwEntry);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// error or cancel
|
|
*lpdwResult = ERROR_USER_DISCONNECTION;
|
|
|
|
if(rdd.dwError)
|
|
{
|
|
*lpdwResult = rdd.dwError;
|
|
}
|
|
}
|
|
|
|
fResult = TRUE;
|
|
|
|
Cleanup:
|
|
if (pRasProp)
|
|
{
|
|
delete pRasProp;
|
|
}
|
|
|
|
DEBUG_LEAVE(fResult);
|
|
return fResult;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Winsock callback handler
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
DWORD
|
|
CheckForNoNetOverride(
|
|
LPSTR pszHostName
|
|
)
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"CheckForNoNetOverride",
|
|
"%#x (%q)",
|
|
pszHostName,
|
|
pszHostName
|
|
));
|
|
|
|
DWORD dwAutodialFlags = 0;
|
|
DWORD dwFlags;
|
|
|
|
if(IsOS(OS_WHISTLERORGREATER) && IsLanConnection(&dwFlags) && ERROR_SUCCESS == LoadWinsock())
|
|
{
|
|
DWORD dwIpAddress;
|
|
DWORD dwError;
|
|
|
|
// assume no route and we want to override
|
|
dwAutodialFlags = INTERNET_AUTODIAL_OVERRIDE_NET_PRESENT;
|
|
|
|
// First check to see if we have an ip address.
|
|
ADDRINFO Hints;
|
|
LPADDRINFO lpAddrInfo;
|
|
|
|
memset(&Hints, 0, sizeof(struct addrinfo));
|
|
Hints.ai_flags = AI_NUMERICHOST; // Only check for address literals.
|
|
Hints.ai_family = PF_UNSPEC; // Accept any protocol family.
|
|
Hints.ai_socktype = SOCK_STREAM; // Constrain results to stream socket.
|
|
Hints.ai_protocol = IPPROTO_TCP; // Constrain results to TCP.
|
|
|
|
dwError = _I_getaddrinfo(pszHostName, NULL, &Hints, &lpAddrInfo);
|
|
|
|
if(ERROR_SUCCESS != dwError)
|
|
{
|
|
// not an ip address, try to resolve name
|
|
Hints.ai_flags = AI_CANONNAME;
|
|
dwError = _I_getaddrinfo(pszHostName, NULL, &Hints, &lpAddrInfo);
|
|
}
|
|
|
|
//
|
|
// If we got an IP4 address, check to see if we have a route for it
|
|
//
|
|
if(ERROR_SUCCESS == dwError && (AF_INET == lpAddrInfo->ai_family))
|
|
{
|
|
MIB_IPFORWARDROW bestRoute;
|
|
DWORD dwError = 0;
|
|
|
|
if(NULL == g_hIphlpapi)
|
|
{
|
|
g_hIphlpapi = LoadLibrary("iphlpapi.dll");
|
|
if(g_hIphlpapi)
|
|
{
|
|
g_pfnGetBestRoute = (GETBESTROUTE)GetProcAddress(g_hIphlpapi, "GetBestRoute");
|
|
}
|
|
}
|
|
|
|
// snag ip address from lpaddr
|
|
SOCKADDR_IN *paddr = (SOCKADDR_IN *)(lpAddrInfo->ai_addr);
|
|
dwIpAddress = *((unsigned long *)(&paddr->sin_addr));
|
|
|
|
if(g_pfnGetBestRoute && (ERROR_SUCCESS == g_pfnGetBestRoute(dwIpAddress, 0, &bestRoute)))
|
|
{
|
|
// got a route, no need to override dial semantics
|
|
DEBUG_PRINT(DIALUP, INFO, ("Found a route to %s, no need to override dial\n", pszHostName));
|
|
dwAutodialFlags = 0;
|
|
}
|
|
}
|
|
|
|
UnloadWinsock();
|
|
}
|
|
|
|
DEBUG_LEAVE(dwAutodialFlags);
|
|
return dwAutodialFlags;
|
|
}
|
|
|
|
|
|
BOOL
|
|
InternetAutodialIfNotLocalHost(
|
|
IN LPSTR OPTIONAL pszURL,
|
|
IN LPSTR OPTIONAL pszHostName
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dial so long as we're configured for it and the name passed isn't a
|
|
local host alias.
|
|
|
|
Finds:
|
|
'localhost'
|
|
'127.0.0.1' and its aliases
|
|
local machine name from registry or winsock
|
|
|
|
If a URL is specified, it's cracked to get the host name.
|
|
|
|
Arguments:
|
|
|
|
pszURL - url to check for
|
|
pszHostName - hostname to check for
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Bool,
|
|
"InternetAutodialIfNotLocalHost",
|
|
"%#x (%q), %#x (%q)",
|
|
pszURL,
|
|
pszURL,
|
|
pszHostName,
|
|
pszHostName
|
|
));
|
|
|
|
CHAR *pszURLCopy = NULL, *pszLocalHostname;
|
|
BOOL fLocalHost = FALSE;
|
|
BOOL fAllocatedBuffer = FALSE;
|
|
BOOL fRet = TRUE;
|
|
BOOL fNeedToFix = TRUE;
|
|
DWORD dwAutodialFlags = 0;
|
|
|
|
//
|
|
// Make sure we're all initialized
|
|
//
|
|
InitAutodialModule(TRUE);
|
|
|
|
|
|
// we bypass this activity in an NT service has disabled autodialing. This special cases
|
|
// this behaviour for the webdav redir.
|
|
// In future wininet folks will look to see whether this shouldn't be done for all
|
|
// apps disabling autodialing. For now we just avoid the testing hit for the
|
|
// browser folks (Shishir Pardikar)
|
|
|
|
if((FALSE == fDontProcessHook) && !(GlobalIsProcessNtService && !IsAutodialEnabled(NULL, NULL)))
|
|
|
|
{
|
|
//
|
|
// If we were passed a URL, crack it to get host name
|
|
//
|
|
if(NULL == pszHostName && pszURL)
|
|
{
|
|
DWORD dwHostNameLength;
|
|
long error;
|
|
|
|
// make a copy of url to crack
|
|
pszURLCopy = new (CHAR[INTERNET_MAX_URL_LENGTH+1]);
|
|
if(NULL == pszURLCopy)
|
|
{
|
|
goto quit;
|
|
}
|
|
fAllocatedBuffer = TRUE;
|
|
lstrcpyn(pszURLCopy, pszURL, INTERNET_MAX_URL_LENGTH);
|
|
|
|
// crack it
|
|
error = CrackUrl(pszURLCopy,
|
|
0,
|
|
FALSE, // don't escape URL-path
|
|
NULL, // don't care about scheme
|
|
NULL, // don't care about Scheme Name
|
|
NULL,
|
|
&pszHostName,
|
|
&dwHostNameLength,
|
|
NULL, // don't care about port
|
|
NULL, // don't care about user name
|
|
NULL,
|
|
NULL, // or password
|
|
NULL,
|
|
NULL, // or object
|
|
NULL,
|
|
NULL, // no extra
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if ((error != ERROR_SUCCESS) || (pszHostName == NULL))
|
|
{
|
|
goto quit;
|
|
}
|
|
|
|
// null-terminate host name (stomps pszURLCopy buffer)
|
|
pszHostName[dwHostNameLength] = 0;
|
|
}
|
|
|
|
//
|
|
// We'd better have a host name by now...
|
|
//
|
|
INET_ASSERT(pszHostName);
|
|
if(NULL == pszHostName)
|
|
{
|
|
goto quit;
|
|
}
|
|
|
|
//
|
|
// Check for 'localhost'
|
|
//
|
|
if( 0 == lstrcmpi(pszHostName, "localhost"))
|
|
{
|
|
DEBUG_PRINT(DIALUP, INFO, ("Found localhost\n"));
|
|
fLocalHost = TRUE;
|
|
goto quit;
|
|
}
|
|
|
|
//
|
|
// check for 127.0.0.1 or its variants -- use inet_addr if winsock loaded
|
|
//
|
|
if(g_fWinsockLoaded || _I_inet_addr)
|
|
{
|
|
if(ERROR_SUCCESS == LoadWinsock())
|
|
{
|
|
if(0x0100007f == _I_inet_addr(pszHostName))
|
|
{
|
|
fLocalHost = TRUE;
|
|
}
|
|
UnloadWinsock();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// winsock not loaded, do the best we can
|
|
if(0 == lstrcmpi(pszHostName, "127.0.0.1"))
|
|
{
|
|
fLocalHost = TRUE;
|
|
}
|
|
}
|
|
|
|
if(fLocalHost)
|
|
{
|
|
DEBUG_PRINT(DIALUP, INFO, ("Found 127.0.0.1 alias\n"));
|
|
goto quit;
|
|
}
|
|
|
|
//
|
|
// check local machine name
|
|
//
|
|
pszLocalHostname = new (CHAR[INTERNET_MAX_HOST_NAME_LENGTH+1]);
|
|
INET_ASSERT(pszLocalHostname);
|
|
if(pszLocalHostname)
|
|
{
|
|
DWORD dwSize = INTERNET_MAX_HOST_NAME_LENGTH;
|
|
DWORD dwValType;
|
|
|
|
// check fully qualified name (only if we know winsock is loaded)
|
|
if(g_fWinsockLoaded || _I_gethostname)
|
|
{
|
|
if(ERROR_SUCCESS == LoadWinsock())
|
|
{
|
|
if(0 == _I_gethostname(pszLocalHostname, INTERNET_MAX_HOST_NAME_LENGTH))
|
|
{
|
|
if(0 == lstrcmpi(pszLocalHostname, pszHostName))
|
|
fLocalHost = TRUE;
|
|
}
|
|
UnloadWinsock();
|
|
}
|
|
}
|
|
|
|
if (!fLocalHost &&
|
|
SHGetValue(HKEY_LOCAL_MACHINE,szRegPathTCP,
|
|
szRegValHostName,&dwValType,pszLocalHostname,&dwSize) ==
|
|
ERROR_SUCCESS)
|
|
{
|
|
if(0 == lstrcmpi(pszLocalHostname, pszHostName))
|
|
fLocalHost = TRUE;
|
|
}
|
|
|
|
// also against check computer name in registry, RPC
|
|
// will use this if there's no DNS hostname set
|
|
dwSize = INTERNET_MAX_HOST_NAME_LENGTH;
|
|
if (!fLocalHost &&
|
|
SHGetValue(HKEY_LOCAL_MACHINE, szRegPathComputerName,
|
|
szRegValComputerName,&dwValType,pszLocalHostname,&dwSize) ==
|
|
ERROR_SUCCESS)
|
|
{
|
|
if(0 == lstrcmpi(pszLocalHostname, pszHostName))
|
|
fLocalHost = TRUE;
|
|
}
|
|
|
|
delete pszLocalHostname;
|
|
}
|
|
|
|
if(fLocalHost)
|
|
{
|
|
DEBUG_PRINT(DIALUP, INFO, ("Found local machine name\n"));
|
|
goto quit;
|
|
}
|
|
|
|
// Check for override of "dial if no net" (ICS host is prime example)
|
|
dwAutodialFlags = CheckForNoNetOverride(pszHostName);
|
|
|
|
// not localhost, so need to autodial
|
|
fRet = InternetAutodial(dwAutodialFlags, 0);
|
|
fNeedToFix = FALSE;
|
|
}
|
|
|
|
quit:
|
|
if(fNeedToFix)
|
|
{
|
|
// Since we're not dialing, ensure correct settings
|
|
FixProxySettingsForCurrentConnection(FALSE);
|
|
}
|
|
|
|
if(fAllocatedBuffer)
|
|
{
|
|
delete pszURLCopy;
|
|
}
|
|
|
|
DEBUG_LEAVE(fRet);
|
|
return fRet;
|
|
}
|
|
|
|
|
|
extern "C"
|
|
VOID
|
|
InternetAutodialCallback(
|
|
IN DWORD dwOpCode,
|
|
IN LPCVOID lpParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Possibly establish a connection prior to a winsock operation. Called
|
|
by winsock before each operation.
|
|
|
|
Arguments:
|
|
|
|
dwOpCode - Winsock operation about to be done
|
|
lpParam - Information about operation
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER_API((DBG_DIALUP,
|
|
None,
|
|
"InternetAutodialCallback",
|
|
"%s (%#x), %#x",
|
|
InternetMapWinsockCallbackType(dwOpCode),
|
|
dwOpCode,
|
|
lpParam
|
|
));
|
|
|
|
//
|
|
// Make sure we're initialized and have done the process check!
|
|
//
|
|
InitAutodialModule(FALSE);
|
|
|
|
//
|
|
// If we're in rnaapp.exe process, bail out now!
|
|
//
|
|
if(g_fRNAAppProcess)
|
|
{
|
|
DEBUG_PRINT(DIALUP, INFO, ("Process is rnaapp.exe! Bailing out!\n"));
|
|
DEBUG_LEAVE_API(0);
|
|
return;
|
|
}
|
|
|
|
// return as soon as possible if we know there's nothing for us to do here...
|
|
|
|
// keep track of the last time we sent winsock activity messages or
|
|
// checked for RNA activity. We won't do these things more than once
|
|
// every MIN_RNA_BUSY_CHECK_INTERVAL seconds. Getting the tick count
|
|
// is extremely cheap so this is a worthwhile optimization.
|
|
|
|
|
|
BOOL fProcessedRecently = FALSE;
|
|
DWORD dwNewTickCount = GetTickCountWrap();
|
|
DWORD dwElapsed = dwNewTickCount - g_dwLastTickCount;
|
|
if (dwElapsed < MIN_RNA_BUSY_CHECK_INTERVAL) {
|
|
fProcessedRecently = TRUE;
|
|
} else {
|
|
g_dwLastTickCount = dwNewTickCount;
|
|
}
|
|
|
|
// we're in the winsock callback so it's safe (ie. cheap) to call winsock
|
|
g_fWinsockLoaded = TRUE;
|
|
|
|
if (!fProcessedRecently) {
|
|
// if hidden autodisconnect monitor window is around, send it a message to
|
|
// notify it of winsock activity so it knows we're not idle.
|
|
HWND hwndMonitorApp = FindWindow(szAutodialMonitorClass,NULL);
|
|
if (hwndMonitorApp) {
|
|
PostMessage(hwndMonitorApp,WM_WINSOCK_ACTIVITY,0,0);
|
|
}
|
|
if(NULL == g_hwndWebCheck) {
|
|
g_hwndWebCheck = FindWindow(szWebCheckMonitorClass,NULL);
|
|
}
|
|
if(g_hwndWebCheck) {
|
|
PostMessage(g_hwndWebCheck,WM_WINSOCK_ACTIVITY,0,0);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Only continue if we have a callback type that we actually do something
|
|
// with
|
|
//
|
|
switch(dwOpCode)
|
|
{
|
|
case WINSOCK_CALLBACK_CONNECT:
|
|
case WINSOCK_CALLBACK_RECVFROM:
|
|
// we do stuff with these so continue...
|
|
break;
|
|
case WINSOCK_CALLBACK_GETHOSTBYNAME:
|
|
// bail out now for gethostbyname(NULL) else do normal
|
|
// gethostbyname processing.
|
|
if(NULL == lpParam)
|
|
{
|
|
DEBUG_PRINT(DIALUP, INFO, ("Not dialing for gethostbyname(NULL)\n"));
|
|
DEBUG_LEAVE_API(0);
|
|
return;
|
|
}
|
|
break;
|
|
default:
|
|
DEBUG_LEAVE_API(0);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// if we're EXPLORER or IEXPLORE and in global offline mode, don't dial
|
|
//
|
|
if (GlobalIsProcessExplorer && IsGlobalOffline())
|
|
{
|
|
DEBUG_LEAVE_API(0);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// verify proxy settings are correct for current connection and if
|
|
// we're already connected, bail out!
|
|
//
|
|
if(FixProxySettingsForCurrentConnection(FALSE) || fDontProcessHook)
|
|
{
|
|
DEBUG_LEAVE_API(0);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Look at the specific winsock operation we're doing and bail out if
|
|
// we don't want to dial
|
|
//
|
|
switch (dwOpCode)
|
|
{
|
|
case WINSOCK_CALLBACK_CONNECT:
|
|
case WINSOCK_CALLBACK_RECVFROM:
|
|
// these APIs all have a sockaddr struct as the API-specific
|
|
// parameter, look in struct to find address family. Don't
|
|
// respond if it's non-TCP.
|
|
INET_ASSERT(lpParam);
|
|
|
|
if (lpParam) {
|
|
struct sockaddr_in * psa = (struct sockaddr_in *) lpParam;
|
|
|
|
if (AF_INET != psa->sin_family) {
|
|
// not TCP, don't respond
|
|
DEBUG_PRINT(DIALUP, INFO, ("Not dialing for non TCP connect\n"));
|
|
DEBUG_LEAVE_API(0);
|
|
return;
|
|
}
|
|
|
|
#if defined(UNIX) && defined(ux10)
|
|
DEBUG_PRINT(DIALUP, INFO, ("IP address: %d.%d.%d.%d\n",
|
|
((LPBYTE)&(psa->sin_addr))[0],
|
|
((LPBYTE)&(psa->sin_addr))[1],
|
|
((LPBYTE)&(psa->sin_addr))[2],
|
|
((LPBYTE)&(psa->sin_addr))[3]));
|
|
#else
|
|
DEBUG_PRINT(DIALUP, INFO, ("IP address: %d.%d.%d.%d\n",
|
|
psa->sin_addr.S_un.S_un_b.s_b1,
|
|
psa->sin_addr.S_un.S_un_b.s_b2,
|
|
psa->sin_addr.S_un.S_un_b.s_b3,
|
|
psa->sin_addr.S_un.S_un_b.s_b4));
|
|
#endif
|
|
|
|
if (0x0100007f == psa->sin_addr.s_addr) {
|
|
// loop back address, don't respond
|
|
DEBUG_PRINT(DIALUP, INFO, ("Not dialing for 127.0.0.1\n"));
|
|
DEBUG_LEAVE_API(0);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Check to make sure this isn't our local address if possible
|
|
//
|
|
// This is a very rare code path and won't be hit in normal
|
|
// browsing. Also, winsock is already loaded in this process
|
|
// so LoadWinsock is reasonably cheap.
|
|
//
|
|
// This code is here to fix FrontPage and WinCE. Those are
|
|
// pretty much the only guys that will ever hit it.
|
|
//
|
|
// [darrenmi] don't attempt to do this if we're on the
|
|
// netware client because gethostbyname(NULL) will fault.
|
|
//
|
|
|
|
// how many IPs can the local host have? 16 seems like an
|
|
// excessive amount.
|
|
#define MAX_IP_COUNT 16
|
|
|
|
if (FALSE == GlobalRunningNovellClient32 &&
|
|
FALSE == g_fGetHostByNameNULLFails &&
|
|
ERROR_SUCCESS == LoadWinsock())
|
|
{
|
|
// get real ip addresses for this host
|
|
HOSTENT *ph;
|
|
|
|
__try
|
|
{
|
|
ph = _I_gethostbyname(NULL);
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
g_fGetHostByNameNULLFails = TRUE;
|
|
ph = NULL;
|
|
}
|
|
ENDEXCEPT
|
|
|
|
if(ph)
|
|
{
|
|
int iCount = 0;
|
|
DWORD dwAddress[MAX_IP_COUNT];
|
|
|
|
while((LPDWORD)(ph->h_addr_list[iCount]) && iCount < MAX_IP_COUNT)
|
|
{
|
|
dwAddress[iCount] = *((LPDWORD)(ph->h_addr_list[iCount]));
|
|
|
|
//
|
|
// don't dial if connecting to this host's ip address
|
|
//
|
|
// FrontPage does this.
|
|
//
|
|
if(dwAddress[iCount] == psa->sin_addr.s_addr) {
|
|
DEBUG_PRINT(DIALUP, INFO, ("Not dialing for local host IP address\n"));
|
|
DEBUG_LEAVE_API(0);
|
|
return;
|
|
}
|
|
|
|
iCount++;
|
|
}
|
|
|
|
//
|
|
// RFC1918 lists 192.168.x.x as 256 class C networks
|
|
// for use as non-global addresses. If this address
|
|
// is one of these guys and we already have an ip on the
|
|
// same subnet, don't dial
|
|
//
|
|
// WinCE device does this.
|
|
//
|
|
if((psa->sin_addr.s_addr & 0x0000FFFF) == 0x0000A8C0)
|
|
{
|
|
int i;
|
|
|
|
for(i=0; i<iCount; i++)
|
|
{
|
|
if((psa->sin_addr.s_addr & 0x00FFFFFF) == (dwAddress[i] & 0x00FFFFFF))
|
|
{
|
|
// connect to a local subnet we're alreay on. Don't dial.
|
|
DEBUG_PRINT(DIALUP, INFO, ("Not dialing for local 192.168.x.x subnet\n"));
|
|
DEBUG_LEAVE_API(0);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
UnloadWinsock();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WINSOCK_CALLBACK_GETHOSTBYNAME:
|
|
// a lot of apps do a GetHostByName(<local host name>) first
|
|
// thing to get their hands on a hostent struct, this doesn't
|
|
// constitute wanting to hit the net. If we get a GetHostByName,
|
|
// compare the host name to the local host name in the registry,
|
|
// and if they match then don't respond to this.
|
|
if (lpParam)
|
|
{
|
|
InternetAutodialIfNotLocalHost(NULL, (LPSTR)lpParam);
|
|
DEBUG_LEAVE_API(0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Dial...
|
|
//
|
|
InternetAutodial(0, 0);
|
|
|
|
DEBUG_LEAVE_API(0);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Public APIs
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
VOID
|
|
AUTO_PROXY_DLLS::SaveDetectedProxySettings(
|
|
IN LPINTERNET_PROXY_INFO_EX lpProxySettings,
|
|
IN BOOL fNeedHostIPChk
|
|
)
|
|
{
|
|
BOOL fRet;
|
|
BOOL fDialupRet;
|
|
BOOL fConnectionMatch = FALSE;
|
|
|
|
//
|
|
// Ensure we're initialized
|
|
//
|
|
|
|
InitAutodialModule(TRUE);
|
|
|
|
WaitForSingleObject(g_hConnectionMutex, INFINITE);
|
|
|
|
// remove settting from last time...
|
|
lpProxySettings->dwAutoDiscoveryFlags &= ~(AUTO_PROXY_FLAG_DETECTION_SUSPECT);
|
|
|
|
//
|
|
// Check to see if we have a dialup connection
|
|
//
|
|
|
|
DWORD dwFixEntry;
|
|
fRet = IsDialUpConnection(TRUE, &dwFixEntry);
|
|
|
|
if(fRet)
|
|
{
|
|
// check for match
|
|
if(lpProxySettings->lpszConnectionName &&
|
|
lstrcmpiA(lpProxySettings->lpszConnectionName, g_RasCon.GetEntryA(dwFixEntry)) == 0)
|
|
{
|
|
fConnectionMatch = TRUE;
|
|
}
|
|
}
|
|
|
|
fDialupRet = fRet;
|
|
|
|
DWORD dwFlags;
|
|
|
|
//
|
|
// no ras connections - ensure LAN proxy settings are correct
|
|
//
|
|
|
|
fRet = IsLanConnection(&dwFlags);
|
|
|
|
if(fRet)
|
|
{
|
|
if (lpProxySettings->lpszConnectionName == NULL)
|
|
{
|
|
fConnectionMatch = TRUE;
|
|
}
|
|
else if (fDialupRet &&
|
|
(dwFlags & NETWORK_ALIVE_LAN) &&
|
|
(lpProxySettings->dwDetectedInterfaceIpCount == 1) &&
|
|
g_fSensInstalled )
|
|
{
|
|
//
|
|
// At this point our detection results are suspect,
|
|
// because we are claiming to have a DialUp Adapter,
|
|
// Net Adapter, and only One IP address for the whole
|
|
// system.
|
|
//
|
|
|
|
lpProxySettings->dwAutoDiscoveryFlags |= AUTO_PROXY_FLAG_DETECTION_SUSPECT;
|
|
}
|
|
}
|
|
|
|
if ( fConnectionMatch && !(IsGlobalOffline()))
|
|
{
|
|
LockAutoProxy();
|
|
|
|
fRet = TRUE;
|
|
|
|
//
|
|
// Do Host IP check to confirm we're still ok, ie on the same connection,
|
|
// that we began on.
|
|
//
|
|
|
|
if ( fNeedHostIPChk )
|
|
{
|
|
DWORD error;
|
|
DWORD * pdwDetectedInterfaceIp = NULL;
|
|
DWORD dwDetectedInterfaceIpCount;
|
|
|
|
fRet = FALSE;
|
|
|
|
error = GetHostAddresses(&pdwDetectedInterfaceIp,
|
|
&dwDetectedInterfaceIpCount); // will this cause problems with auto-dial?
|
|
|
|
if ( error == ERROR_SUCCESS &&
|
|
dwDetectedInterfaceIpCount == lpProxySettings->dwDetectedInterfaceIpCount)
|
|
{
|
|
fRet = TRUE;
|
|
for (DWORD i = 0; i < dwDetectedInterfaceIpCount; i++)
|
|
{
|
|
if (pdwDetectedInterfaceIp[i] != lpProxySettings->pdwDetectedInterfaceIp[i] ) {
|
|
fRet = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( pdwDetectedInterfaceIp != NULL) {
|
|
FREE_MEMORY(pdwDetectedInterfaceIp);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now save out all our settings, if we can.
|
|
//
|
|
|
|
if (fRet)
|
|
{
|
|
SetProxySettings(lpProxySettings,
|
|
IsModifiedInProcess(),
|
|
FALSE /*no overwrite*/);
|
|
|
|
if ( ! IsModifiedInProcess() )
|
|
{
|
|
// Need to save results to registry, if we succeed,
|
|
// then make sure to transfer new version stamp
|
|
if ( WriteProxySettings(lpProxySettings, FALSE) == ERROR_SUCCESS )
|
|
{
|
|
_ProxySettings.dwCurrentSettingsVersion =
|
|
lpProxySettings->dwCurrentSettingsVersion;
|
|
}
|
|
}
|
|
|
|
// stamp version, so we know we've been updated.
|
|
_dwUpdatedProxySettingsVersion = lpProxySettings->dwCurrentSettingsVersion;
|
|
}
|
|
|
|
UnlockAutoProxy();
|
|
}
|
|
|
|
ReleaseMutex(g_hConnectionMutex);
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
INTERNETAPI_(BOOL)
|
|
InternetGetConnectedStateExW(
|
|
OUT LPDWORD lpdwFlags,
|
|
OUT LPWSTR lpszConnectionName,
|
|
IN DWORD dwBufLen,
|
|
IN DWORD dwReserved
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Determine whether any useful connections exist
|
|
|
|
On FALSE, will return information about autodial connection if any
|
|
|
|
Arguments:
|
|
|
|
lpdwFlags - Location to store flags about current connection
|
|
INTERNET_CONNECTION_MODEM Modem connection
|
|
INTERNET_CONNECTION_LAN Network connection
|
|
INTERNET_CONNECTION_PROXY Proxy in use
|
|
INTERNET_RAS_INSTALLED Ras is installed on machine
|
|
lpszConnectionName
|
|
- name of current connection
|
|
dwBufLen - length of name buffer
|
|
dwReserved - Must be 0
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - connection exists
|
|
FALSE - no connection exists
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER_API((DBG_DIALUP,
|
|
Bool,
|
|
"InternetGetConnectedStateExW",
|
|
"%#x, %#x, %#x, %#x",
|
|
lpdwFlags,
|
|
lpszConnectionName,
|
|
dwBufLen,
|
|
dwReserved
|
|
));
|
|
|
|
BOOL fRet = FALSE, fProcessedRecently = FALSE, fConfigured = FALSE;
|
|
DWORD dwFlags = 0;
|
|
DWORD dwRes = 0, dwBytes, dwEnable = 0;
|
|
AUTODIAL ad;
|
|
BOOL fAutodialEnabled;
|
|
static BOOL fSensState = TRUE;
|
|
|
|
//
|
|
// Ensure we're initialized
|
|
//
|
|
InitAutodialModule(TRUE);
|
|
|
|
//
|
|
// Verify parameters
|
|
//
|
|
if((lpdwFlags && ERROR_SUCCESS != ProbeWriteBuffer(lpdwFlags, sizeof(DWORD))) ||
|
|
(lpszConnectionName && ERROR_SUCCESS != ProbeWriteBuffer(lpszConnectionName, dwBufLen)) ||
|
|
dwReserved)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
DEBUG_ERROR(DIALUP, ERROR_INVALID_PARAMETER);
|
|
DEBUG_LEAVE_API(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If on Millennium, forward calls to RAS
|
|
//
|
|
if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRasInternetGetConnectedStateExA)
|
|
{
|
|
CHAR szAnsiName[RAS_MaxEntryName + 1];
|
|
DWORD dwConnFlags = 0;
|
|
|
|
//
|
|
// call RAS one first...
|
|
//
|
|
fRet = _RasInternetGetConnectedStateExA(&dwConnFlags, szAnsiName, RAS_MaxEntryName, dwReserved);
|
|
|
|
if(lpszConnectionName)
|
|
{
|
|
MultiByteToWideChar(CP_ACP, 0, szAnsiName, -1, lpszConnectionName, dwBufLen);
|
|
}
|
|
|
|
//
|
|
// RAS one fills in everything except PROXY and OFFLINE flags.
|
|
//
|
|
if(dwConnFlags & INTERNET_CONNECTION_MODEM)
|
|
{
|
|
dwEnable = FixProxySettings(lpszConnectionName, FALSE, 0);
|
|
}
|
|
else if(dwConnFlags & INTERNET_CONNECTION_LAN)
|
|
{
|
|
dwEnable = FixProxySettings(NULL, FALSE, 0);
|
|
}
|
|
|
|
if(dwEnable)
|
|
{
|
|
dwConnFlags |= INTERNET_CONNECTION_PROXY | INTERNET_CONNECTION_CONFIGURED;
|
|
}
|
|
|
|
if(IsGlobalOffline())
|
|
{
|
|
dwConnFlags |= INTERNET_CONNECTION_OFFLINE;
|
|
}
|
|
|
|
if(fRet)
|
|
{
|
|
// we now have a connection - if we get into a state where we don't,
|
|
// ask user to go offline
|
|
g_fAskOffline = TRUE;
|
|
}
|
|
|
|
// set out flags if caller requested it
|
|
if(lpdwFlags)
|
|
{
|
|
*lpdwFlags = dwConnFlags;
|
|
}
|
|
|
|
DEBUG_LEAVE_API(fRet);
|
|
return fRet;
|
|
}
|
|
|
|
//
|
|
// Initialize out variables
|
|
//
|
|
if(lpdwFlags)
|
|
*lpdwFlags = 0;
|
|
|
|
if(lpszConnectionName)
|
|
*lpszConnectionName = 0;
|
|
|
|
|
|
WaitForSingleObject(g_hConnectionMutex, INFINITE);
|
|
|
|
|
|
//
|
|
// Check to see if we have a dialup connection
|
|
//
|
|
DWORD dwFixEntry;
|
|
fRet = IsDialUpConnection(FALSE, &dwFixEntry);
|
|
|
|
//
|
|
// Tell caller if RAS is installed
|
|
//
|
|
if(g_fRasInstalled)
|
|
{
|
|
dwFlags |= INTERNET_RAS_INSTALLED;
|
|
}
|
|
|
|
if(fRet)
|
|
{
|
|
// this connectoid is connected
|
|
dwFlags |= INTERNET_CONNECTION_MODEM;
|
|
fConfigured = TRUE;
|
|
|
|
dwEnable = FixProxySettings(g_RasCon.GetEntryW(dwFixEntry), FALSE, 0);
|
|
|
|
// copy name for caller
|
|
if(lpszConnectionName && dwBufLen) {
|
|
StrCpyNW(lpszConnectionName, g_RasCon.GetEntryW(dwFixEntry), dwBufLen);
|
|
}
|
|
}
|
|
|
|
//
|
|
// autodial configuration is relevant for finding out if lan is present.
|
|
// if autodial.force is set, consider lan NOT present since we're going
|
|
// to dial anyway.
|
|
//
|
|
fAutodialEnabled = IsAutodialEnabled(NULL, &ad);
|
|
|
|
if((FALSE == fRet) && (FALSE == ad.fForceDial))
|
|
{
|
|
//
|
|
// no ras connections - ensure LAN proxy settings are correct
|
|
//
|
|
DWORD dwLanFlags;
|
|
fRet = IsLanConnection(&dwLanFlags);
|
|
|
|
if(fRet)
|
|
{
|
|
// lan connection is configured and present
|
|
dwFlags |= INTERNET_CONNECTION_LAN;
|
|
dwEnable = FixProxySettings(NULL, FALSE, dwLanFlags);
|
|
// if call wants name, fill in "lan connection"
|
|
if(lpszConnectionName && dwBufLen)
|
|
LoadStringWrapW(GlobalDllHandle, IDS_LAN_CONNECTION, lpszConnectionName, dwBufLen);
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// turn on proxy flag if necessary
|
|
//
|
|
if(dwEnable)
|
|
{
|
|
dwFlags |= INTERNET_CONNECTION_PROXY;
|
|
|
|
// we have some kind of configured connection
|
|
fConfigured = TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// If no connection found, tell caller about autodial entry
|
|
//
|
|
if(FALSE == fConfigured ||
|
|
0 == (dwFlags & (INTERNET_CONNECTION_LAN | INTERNET_CONNECTION_MODEM)))
|
|
{
|
|
if(ad.fConfigured)
|
|
{
|
|
// we have an autodial connection
|
|
fConfigured = TRUE;
|
|
|
|
if(0 == (dwFlags & (INTERNET_CONNECTION_LAN | INTERNET_CONNECTION_MODEM)))
|
|
{
|
|
// autodial is enabled
|
|
|
|
// If the caller cares about entry name, find them one
|
|
if(ad.fHasEntry)
|
|
{
|
|
// use specified one
|
|
dwFlags |= INTERNET_CONNECTION_MODEM;
|
|
if(lpszConnectionName && dwBufLen)
|
|
{
|
|
StrCpyNW(lpszConnectionName, ad.pszEntryName, dwBufLen);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// None set as default, pick one and set it
|
|
RasEnumHelp * pre = new RasEnumHelp;
|
|
|
|
if(pre)
|
|
{
|
|
if (pre->GetEntryCount())
|
|
{
|
|
LPWSTR pwzName = pre->GetEntryW(0);
|
|
|
|
// set this entry to the default
|
|
SHSetValueW(HKEY_CURRENT_USER, szRegPathRemoteAccessW, szRegValInternetEntryW,
|
|
REG_SZ, (BYTE *)pwzName, lstrlenW(pwzName));
|
|
|
|
// return to caller
|
|
dwFlags |= INTERNET_CONNECTION_MODEM;
|
|
if(lpszConnectionName && dwBufLen)
|
|
{
|
|
StrCpyNW(lpszConnectionName, pwzName, dwBufLen);
|
|
}
|
|
}
|
|
delete pre;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Tell caller if we have a connection configured
|
|
//
|
|
if(fConfigured)
|
|
{
|
|
dwFlags |= INTERNET_CONNECTION_CONFIGURED;
|
|
}
|
|
|
|
|
|
//
|
|
// Tell caller if we're offline
|
|
//
|
|
if(IsGlobalOffline())
|
|
{
|
|
dwFlags |= INTERNET_CONNECTION_OFFLINE;
|
|
}
|
|
|
|
if(lpdwFlags)
|
|
*lpdwFlags = dwFlags;
|
|
|
|
#if defined(SITARA)
|
|
|
|
//
|
|
// IF we're configured to use a modem,
|
|
// then go ahead an turn on Sitara
|
|
//
|
|
|
|
if (fRet && (dwFlags & INTERNET_CONNECTION_MODEM))
|
|
{
|
|
GlobalHasSitaraModemConn = TRUE;
|
|
}
|
|
else
|
|
{
|
|
GlobalHasSitaraModemConn = FALSE;
|
|
}
|
|
|
|
#endif // SITARA
|
|
|
|
if(fRet)
|
|
// we now have a connection - if we get into a state where we don't,
|
|
// ask user to go offline
|
|
g_fAskOffline = TRUE;
|
|
|
|
ReleaseMutex(g_hConnectionMutex);
|
|
|
|
DEBUG_LEAVE_API(fRet);
|
|
SetLastError(ERROR_SUCCESS);
|
|
return fRet;
|
|
}
|
|
|
|
|
|
INTERNETAPI_(BOOL)
|
|
InternetGetConnectedStateExA(
|
|
OUT LPDWORD lpdwFlags,
|
|
OUT LPSTR lpszConnectionName,
|
|
IN DWORD dwBufLen,
|
|
IN DWORD dwReserved
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Ansi version of InternetGetConnectedStateExW
|
|
|
|
Arguments:
|
|
|
|
Same as InternetGetConnectedStateExW
|
|
|
|
Return Value:
|
|
|
|
Same as InternetGetConnectedStateExW
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER_API((DBG_DIALUP,
|
|
Bool,
|
|
"InternetGetConnectedStateExA",
|
|
"%#x, %#x, %#x, %#x",
|
|
lpdwFlags,
|
|
lpszConnectionName,
|
|
dwBufLen,
|
|
dwReserved
|
|
));
|
|
|
|
WCHAR szWideName[RAS_MaxEntryName + 1];
|
|
BOOL fRet;
|
|
|
|
//
|
|
// call wide version
|
|
//
|
|
*szWideName = 0;
|
|
fRet = InternetGetConnectedStateExW(lpdwFlags, szWideName, RAS_MaxEntryName, dwReserved);
|
|
|
|
//
|
|
// convert wide name to ansi
|
|
//
|
|
if(lpszConnectionName)
|
|
{
|
|
if(ERROR_SUCCESS == ProbeWriteBuffer(lpszConnectionName, dwBufLen))
|
|
{
|
|
int i;
|
|
i = WideCharToMultiByte(CP_ACP, 0, szWideName, -1, lpszConnectionName, dwBufLen, NULL, NULL);
|
|
if(0 == i) {
|
|
// truncated - null terminate
|
|
lpszConnectionName[dwBufLen - 1] = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
DEBUG_ERROR(DIALUP, ERROR_INVALID_PARAMETER);
|
|
fRet = FALSE;
|
|
}
|
|
}
|
|
|
|
DEBUG_LEAVE_API(fRet);
|
|
return fRet;
|
|
}
|
|
|
|
|
|
|
|
INTERNETAPI_(BOOL)
|
|
InternetGetConnectedState(
|
|
OUT LPDWORD lpdwFlags,
|
|
IN DWORD dwReserved
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get simple information about connected state
|
|
|
|
Arguments:
|
|
|
|
lpdwFlags - Location to store connection flags
|
|
|
|
xxx
|
|
|
|
dwReserved - must be 0
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
Connected - TRUE
|
|
|
|
Not - FALSE
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER_API((DBG_DIALUP,
|
|
Bool,
|
|
"InternetGetConnectedState",
|
|
"%#x, %#x",
|
|
lpdwFlags,
|
|
dwReserved
|
|
));
|
|
|
|
BOOL fRet = InternetGetConnectedStateExW(lpdwFlags, NULL, 0, dwReserved);
|
|
|
|
DEBUG_LEAVE_API(fRet);
|
|
return fRet;
|
|
}
|
|
|
|
|
|
BOOL
|
|
HandleFlagsForRas(
|
|
IN HWND hwndParent,
|
|
IN BOOL fAutodialing,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD *pdwRasFlags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert InternetDial flags to RasInternetDial flags. Also directly handle
|
|
any flags that Ras doesn't know about.
|
|
|
|
Only ever called on Millennium
|
|
|
|
Arguments:
|
|
|
|
hwndParent Parent window for any UI
|
|
fAutodialing We're called from InternetAutodial vs. InternetDial
|
|
dwFlags InternetDial flags
|
|
dwRasFlags RasInternetDial flags
|
|
|
|
Return values:
|
|
|
|
TRUE Success
|
|
|
|
FALSE Abort operation
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
Dword,
|
|
"HandleFlagsForRas",
|
|
"%#x, %B, %#x, %#x",
|
|
hwndParent,
|
|
fAutodialing,
|
|
dwFlags,
|
|
pdwRasFlags
|
|
));
|
|
|
|
DWORD dwResult = ERROR_SUCCESS;
|
|
|
|
*pdwRasFlags = 0;
|
|
|
|
//
|
|
// Convert flags for directly supported options
|
|
//
|
|
if((dwFlags & INTERNET_DIAL_SHOW_OFFLINE) ||
|
|
(GlobalIsProcessExplorer)) *pdwRasFlags |= RAS_INTERNET_AUTODIAL_ALLOW_OFFLINE;
|
|
if((dwFlags & INTERNET_DIAL_UNATTENDED) ||
|
|
(dwFlags & INTERNET_AUTODIAL_FORCE_UNATTENDED)) *pdwRasFlags |= RAS_INTERNET_AUTODIAL_UNATTENDED;
|
|
|
|
// if(dwFlags & INTERNET_DIAL_FORCE_PROMPT) not supported
|
|
|
|
//
|
|
// Handle offline mode
|
|
//
|
|
if(dwFlags & INTERNET_AUTODIAL_FORCE_ONLINE)
|
|
{
|
|
SetOffline(FALSE);
|
|
}
|
|
|
|
//
|
|
// Handle security check -- only if not connected and autodial and check is enabled.
|
|
//
|
|
AUTODIAL ad;
|
|
DWORD dwState;
|
|
|
|
if(!IsDialUpConnection(FALSE, NULL))
|
|
{
|
|
//
|
|
// Perform check if:
|
|
//
|
|
// - Autodial is enabled OR we're not autodialing
|
|
// - and Security check is enabled
|
|
//
|
|
IsAutodialEnabled(NULL, &ad);
|
|
|
|
if((ad.fEnabled || !fAutodialing) && ad.fSecurity)
|
|
{
|
|
if(PerformSecurityCheck(hwndParent, dwFlags))
|
|
{
|
|
// non-silent check failed
|
|
dwResult = ERROR_INTERNET_FAILED_DUETOSECURITYCHECK;
|
|
}
|
|
}
|
|
}
|
|
|
|
DEBUG_PRINT(DIALUP, INFO, ("Ras Flags=0x%x\n", *pdwRasFlags));
|
|
|
|
DEBUG_LEAVE(dwResult);
|
|
return dwResult;
|
|
}
|
|
|
|
VOID
|
|
HandleUserCancel(
|
|
IN DWORD dwResult,
|
|
IN DWORD dwFlags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Check to see if user cancelled dial and fix appropriate states
|
|
|
|
Arguments:
|
|
|
|
dwResult - Result of dialing operation -- only care about
|
|
USER_DISCONNECTION
|
|
dwFlags - Dialing flags, only care about SHOW_OFFLINE
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER((DBG_DIALUP,
|
|
None,
|
|
"HandleUserCancel",
|
|
"%#x, %#x",
|
|
dwResult,
|
|
dwFlags
|
|
));
|
|
|
|
if(ERROR_USER_DISCONNECTION == dwResult)
|
|
{
|
|
if(GlobalIsProcessExplorer || (dwFlags & INTERNET_DIAL_SHOW_OFFLINE))
|
|
{
|
|
// offline semantics - set offline mode
|
|
SetOffline(TRUE);
|
|
}
|
|
else
|
|
{
|
|
// Normal cancel. Prevent more dialing attempts.
|
|
fDontProcessHook = TRUE;
|
|
}
|
|
}
|
|
|
|
DEBUG_LEAVE(0);
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
InternetDialW(
|
|
IN HWND hwndParent,
|
|
IN LPWSTR pszEntryName,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD_PTR *lpdwConnection,
|
|
IN DWORD dwReserved
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Connect to a specified connectoid
|
|
|
|
Arguments:
|
|
|
|
hwndParent - parent window for dialing ui
|
|
|
|
pszEntryName - string => connectoid to connect to
|
|
- empty string ("") => let user choose
|
|
- NULL => connect to autodial connectoid
|
|
|
|
dwFlags - flags controlling operation:
|
|
|
|
xxx
|
|
|
|
lpdwConnection - location to store connection handle
|
|
|
|
dwReserved - must be 0
|
|
|
|
Return Value:
|
|
|
|
DWORD
|
|
Success - 0
|
|
|
|
Failure - Ras or windows error code
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER_API((DBG_DIALUP,
|
|
Dword,
|
|
"InternetDialW",
|
|
"%#x, %#x (%Q), %#x, %#x, %#x",
|
|
hwndParent,
|
|
pszEntryName,
|
|
pszEntryName,
|
|
dwFlags,
|
|
lpdwConnection,
|
|
dwReserved
|
|
));
|
|
|
|
DIALSTATE data;
|
|
BOOL fConn = FALSE;
|
|
DWORD dwRet = ERROR_SUCCESS, dwTemp;
|
|
WCHAR szKey[MAX_PATH];
|
|
AUTODIAL ad;
|
|
|
|
//
|
|
// Ensure we're initialized
|
|
//
|
|
InitAutodialModule(TRUE);
|
|
|
|
//
|
|
// ensure reserved field is 0
|
|
//
|
|
if(dwReserved)
|
|
{
|
|
dwRet = ERROR_INVALID_PARAMETER;
|
|
goto quit;
|
|
}
|
|
|
|
//
|
|
// ensure we have a lpdwConnection pointer and initialize it
|
|
//
|
|
if(NULL == lpdwConnection ||
|
|
ERROR_SUCCESS != ProbeWriteBuffer(lpdwConnection, sizeof(DWORD)))
|
|
{
|
|
dwRet = ERROR_INVALID_PARAMETER;
|
|
goto quit;
|
|
}
|
|
*lpdwConnection = 0;
|
|
|
|
//
|
|
// ensure we have a valid pszEntryName (NULL is valid - see below)
|
|
//
|
|
if(pszEntryName && ERROR_SUCCESS != ProbeStringW(pszEntryName, &dwTemp))
|
|
{
|
|
dwRet = ERROR_INVALID_PARAMETER;
|
|
goto quit;
|
|
}
|
|
|
|
//
|
|
// On Millennium, forward calls to RAS
|
|
//
|
|
if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRasInternetDialA)
|
|
{
|
|
DWORD dwRasFlags;
|
|
|
|
dwRet = HandleFlagsForRas(hwndParent, FALSE, dwFlags, &dwRasFlags);
|
|
if(dwRet)
|
|
{
|
|
// error, need to bail out
|
|
DEBUG_LEAVE_API(dwRet);
|
|
return dwRet;
|
|
}
|
|
|
|
CHAR szAnsiName[RAS_MaxEntryName+1];
|
|
CHAR *pszNameToUse = NULL;
|
|
|
|
if(pszEntryName)
|
|
{
|
|
WideCharToMultiByte(CP_ACP, 0, pszEntryName, -1, szAnsiName, RAS_MaxEntryName, NULL, NULL);
|
|
pszNameToUse = szAnsiName;
|
|
}
|
|
|
|
dwRet = _RasInternetDialA(hwndParent, pszNameToUse, dwRasFlags, lpdwConnection, dwReserved);
|
|
|
|
//
|
|
// Switch to offline mode if necessary
|
|
//
|
|
HandleUserCancel(dwRet, dwFlags);
|
|
|
|
//
|
|
// If connected, send message to dialmon
|
|
//
|
|
CDHINFO cdh;
|
|
DWORD dwEntry = 0;
|
|
|
|
if(IsDialUpConnection(TRUE, &dwEntry) && !IsCDH(g_RasCon.GetEntryW(dwEntry), &cdh))
|
|
{
|
|
SendDialmonMessage(WM_SET_CONNECTOID_NAME, TRUE);
|
|
}
|
|
|
|
//
|
|
// fix proxy information for new connection
|
|
//
|
|
FixProxySettingsForCurrentConnection(FALSE);
|
|
|
|
DEBUG_LEAVE_API(dwRet);
|
|
return dwRet;
|
|
}
|
|
|
|
//
|
|
// Check config state
|
|
//
|
|
IsAutodialEnabled(NULL, &ad);
|
|
|
|
if(ad.fSecurity)
|
|
{
|
|
if(PerformSecurityCheck(hwndParent, dwFlags))
|
|
{
|
|
DEBUG_LEAVE_API(ERROR_INTERNET_FAILED_DUETOSECURITYCHECK);
|
|
return ERROR_INTERNET_FAILED_DUETOSECURITYCHECK;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Save connectoid name
|
|
//
|
|
memset(&data, 0, sizeof(DIALSTATE));
|
|
data.params.dwSize = sizeof(RASDIALPARAMSW);
|
|
if(pszEntryName && *pszEntryName)
|
|
{
|
|
// use passed connection name as one to dial
|
|
StrCpyNW(data.params.szEntryName, pszEntryName, RAS_MaxEntryName + 1);
|
|
}
|
|
else
|
|
{
|
|
// NULL name passed, use autodial entry if any. If not, use first
|
|
// one in list (data.params.szEntryName == "")
|
|
|
|
if(ad.fEnabled && ad.fHasEntry)
|
|
{
|
|
StrCpyNW(data.params.szEntryName, ad.pszEntryName, RAS_MaxEntryName + 1);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check to see if already have a ras connection
|
|
//
|
|
fConn = IsDialUpConnection(FALSE, NULL);
|
|
|
|
//
|
|
// Check to see if there's a custom dial handler
|
|
//
|
|
if(FALSE == fConn)
|
|
{
|
|
CDHINFO cdh;
|
|
|
|
memset(&cdh, 0, sizeof(CDHINFO));
|
|
if(IsCDH(data.params.szEntryName, &cdh))
|
|
{
|
|
DWORD dwTmpRetVal;
|
|
|
|
if(CallCDH(hwndParent, data.params.szEntryName, &cdh, INTERNET_CUSTOMDIAL_CONNECT, &dwTmpRetVal))
|
|
{
|
|
dwRet = dwTmpRetVal;
|
|
if(ERROR_SUCCESS == dwRet || ERROR_ALREADY_EXISTS == dwRet)
|
|
{
|
|
// successfully connected
|
|
dwRet = ERROR_SUCCESS;
|
|
|
|
if(lpdwConnection)
|
|
*lpdwConnection = (DWORD)CDH_HCONN;
|
|
|
|
// reset last ras poll time to force a check next time
|
|
g_dwLastDialupTicks = 0;
|
|
|
|
// fix proxy information for new connection
|
|
WaitForSingleObject(g_hConnectionMutex, INFINITE);
|
|
FixProxySettings(data.params.szEntryName, FALSE, 0);
|
|
ReleaseMutex(g_hConnectionMutex);
|
|
}
|
|
else
|
|
{
|
|
// check to see if user cancelled and go to offline if necessary
|
|
HandleUserCancel(dwRet, dwFlags);
|
|
}
|
|
dwRet = ERROR_SUCCESS;
|
|
goto quit;
|
|
}
|
|
|
|
// else CDH didn't actually do anything - fall through
|
|
}
|
|
}
|
|
|
|
if(GlobalPlatformVersion5 && *data.params.szEntryName)
|
|
{
|
|
// check to see if it's a win2k CDH
|
|
if(DialIfWin2KCDH(data.params.szEntryName, hwndParent, FALSE, &dwRet, lpdwConnection))
|
|
{
|
|
// check for cancel and offline mode
|
|
HandleUserCancel(dwRet, dwFlags);
|
|
|
|
goto quit;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// If we still don't have a connection, show our UI to make one
|
|
//
|
|
if(FALSE == fConn)
|
|
{
|
|
DWORD dwType, dwTemp, dwSize;
|
|
BOOL fDialedCDH = FALSE;
|
|
|
|
//
|
|
// serialize access to our UI
|
|
//
|
|
|
|
// If we already are displaying the UI, bring it to the foreground
|
|
|
|
// get mutex and check connection again - may have to wait for it and
|
|
// connection status could change
|
|
INET_ASSERT(g_hAutodialMutex);
|
|
WaitForSingleObject(g_hAutodialMutex, INFINITE);
|
|
|
|
if(IsDialUpConnection(FALSE, NULL))
|
|
{
|
|
// got a connection in the mean time - bail out
|
|
ReleaseMutex(g_hAutodialMutex);
|
|
DEBUG_LEAVE_API(ERROR_SUCCESS);
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
if(IsGlobalOffline())
|
|
{
|
|
// we went offline, then bail out without UI
|
|
ReleaseMutex(g_hAutodialMutex);
|
|
DEBUG_LEAVE_API(ERROR_SUCCESS);
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
//
|
|
// Make sure ras is happy
|
|
//
|
|
if(FALSE == EnsureRasLoaded())
|
|
{
|
|
ReleaseMutex(g_hAutodialMutex);
|
|
DEBUG_LEAVE_API(ERROR_NO_CONNECTION);
|
|
return ERROR_NO_CONNECTION;
|
|
}
|
|
|
|
//
|
|
// Fire up commctrl
|
|
//
|
|
InitCommCtrl();
|
|
|
|
if(!g_hDialEvent)
|
|
{
|
|
g_hDialEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
}
|
|
|
|
if(!g_hDialEvent)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
//
|
|
// Dial it
|
|
//
|
|
CDialUI *pdui = new CDialUI(hwndParent);
|
|
|
|
if(pdui)
|
|
{
|
|
// make sure we have a reference
|
|
pdui->AddRef();
|
|
dwRet = pdui->StartDial(&data, dwFlags);
|
|
fDialedCDH = pdui->DialedCDH();
|
|
pdui->Release();
|
|
}
|
|
|
|
//
|
|
// Shut down commtrl
|
|
//
|
|
ExitCommCtrl();
|
|
|
|
//
|
|
// Switch to offline mode if necessary
|
|
//
|
|
HandleUserCancel(data.dwResult, dwFlags);
|
|
|
|
//
|
|
// reset last ras poll time to force a check next time and release
|
|
// mutex
|
|
//
|
|
g_dwLastDialupTicks = 0;
|
|
ReleaseMutex(g_hAutodialMutex);
|
|
|
|
if(!fDialedCDH)
|
|
{
|
|
//
|
|
// Save connect automatically if it wasn't overridden
|
|
//
|
|
if(0 == (dwFlags & INTERNET_DIAL_FORCE_PROMPT))
|
|
{
|
|
GetConnKeyW(data.params.szEntryName, szKey, ARRAYSIZE(szKey));
|
|
dwTemp = (data.dwFlags & CI_AUTO_CONNECT) ? 1 : 0;
|
|
SHSetValueW(HKEY_CURRENT_USER, szKey, REGSTR_DIAL_AUTOCONNECTW,
|
|
REG_DWORD, &dwTemp, sizeof(DWORD));
|
|
}
|
|
|
|
//
|
|
// check to see if we're really connected or not
|
|
//
|
|
if(data.dwResult || NULL == data.hConn)
|
|
{
|
|
if(data.hConn)
|
|
_RasHangUp(data.hConn);
|
|
dwRet = data.dwResult;
|
|
goto quit;
|
|
}
|
|
|
|
RasGetConnectStatusHelp RasGetConnectStatus(data.hConn);
|
|
dwRet = RasGetConnectStatus.GetError();
|
|
if(dwRet)
|
|
{
|
|
_RasHangUp(data.hConn);
|
|
goto quit;
|
|
}
|
|
|
|
if(RasGetConnectStatus.ConnState() != RASCS_Connected)
|
|
{
|
|
_RasHangUp(data.hConn);
|
|
dwRet = ERROR_NO_CONNECTION;
|
|
goto quit;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// fix proxy information for new connection
|
|
//
|
|
WaitForSingleObject(g_hConnectionMutex, INFINITE);
|
|
FixProxySettings(data.params.szEntryName, FALSE, 0);
|
|
ReleaseMutex(g_hConnectionMutex);
|
|
|
|
//
|
|
// reset last ras poll time to force a check next time
|
|
//
|
|
g_dwLastDialupTicks = 0;
|
|
|
|
//
|
|
// start disconnect monitoring
|
|
//
|
|
SendDialmonMessage(WM_SET_CONNECTOID_NAME, TRUE);
|
|
|
|
|
|
//
|
|
// return handle to caller if required
|
|
//
|
|
if(lpdwConnection)
|
|
*lpdwConnection = (DWORD_PTR) data.hConn;
|
|
|
|
quit:
|
|
SetEvent(g_hDialEvent);
|
|
DEBUG_LEAVE_API(dwRet);
|
|
return dwRet;
|
|
}
|
|
|
|
|
|
DWORD
|
|
InternetDialA(
|
|
IN HWND hwndParent,
|
|
IN LPSTR pszEntryName,
|
|
IN DWORD dwFlags,
|
|
OUT DWORD_PTR *lpdwConnection,
|
|
IN DWORD dwReserved
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Wide version of InternetDialA
|
|
|
|
Arguments:
|
|
|
|
Same as InternetDialA
|
|
|
|
Return Value:
|
|
|
|
Same as InternetDialA
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER_API((DBG_DIALUP,
|
|
Dword,
|
|
"InternetDialA",
|
|
"%#x, %#x (%q), %#x, %#x, %#x",
|
|
hwndParent,
|
|
pszEntryName,
|
|
pszEntryName,
|
|
dwFlags,
|
|
lpdwConnection,
|
|
dwReserved
|
|
));
|
|
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
WCHAR szWideEntryName[RAS_MaxEntryName + 1];
|
|
WCHAR *pwzNameToUse = NULL;
|
|
|
|
if (pszEntryName)
|
|
{
|
|
if (IsBadStringPtr(pszEntryName, RAS_MaxEntryName + 1))
|
|
{
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
goto cleanup;
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
i = MultiByteToWideChar(CP_ACP, 0, pszEntryName, -1, szWideEntryName, RAS_MaxEntryName);
|
|
if(0 == i)
|
|
{
|
|
// truncated - null terminate
|
|
szWideEntryName[RAS_MaxEntryName] = 0;
|
|
}
|
|
pwzNameToUse = szWideEntryName;
|
|
}
|
|
}
|
|
dwErr = InternetDialW(hwndParent, pwzNameToUse, dwFlags, lpdwConnection, dwReserved);
|
|
|
|
cleanup:
|
|
DEBUG_LEAVE_API(dwErr);
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
DWORD
|
|
InternetHangUp(
|
|
IN DWORD_PTR dwConnection,
|
|
IN DWORD dwReserved
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Hangs up a connection established by InternetDial
|
|
|
|
Arguments:
|
|
|
|
dwConnection - connection obtained from InternetDial
|
|
|
|
dwReserved - must be 0
|
|
|
|
Return Value:
|
|
|
|
DWORD
|
|
Success - 0
|
|
|
|
Failure - Ras or windows error code
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER_API((DBG_DIALUP,
|
|
Dword,
|
|
"InternetHangUp",
|
|
"%#x, %#x",
|
|
dwConnection,
|
|
dwReserved
|
|
));
|
|
|
|
DWORD dwRet;
|
|
|
|
//
|
|
// If on Millennium, forward calls to RAS
|
|
//
|
|
if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRasInternetHangUpA)
|
|
{
|
|
dwRet = _RasInternetHangUpA(dwConnection, dwReserved);
|
|
|
|
DEBUG_LEAVE_API(dwRet);
|
|
return dwRet;
|
|
}
|
|
|
|
// ensure reserved is 0
|
|
if(dwReserved)
|
|
{
|
|
DEBUG_LEAVE_API(ERROR_INVALID_PARAMETER);
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Ensure we're initialized
|
|
//
|
|
if(FALSE == g_fAutodialInitialized)
|
|
{
|
|
InitAutodialModule(FALSE);
|
|
}
|
|
|
|
//
|
|
// Best we can do for CDH's is post message to the disconnect monitor.
|
|
// Hopefully it'll do the right thing and disconnect. Works for MSN
|
|
// at least.
|
|
//
|
|
if(CDH_HCONN == dwConnection)
|
|
{
|
|
//
|
|
// Try to find a CM connection to hang up
|
|
//
|
|
if(IsDialUpConnection(FALSE, NULL))
|
|
{
|
|
CDHINFO cdh;
|
|
DWORD i, dwError;
|
|
|
|
for(i=0; i < g_dwConnections; i++)
|
|
{
|
|
if(IsCDH(g_RasCon.GetEntryW(i), &cdh))
|
|
{
|
|
if(StrStrIW(cdh.pszDllName, szCMDllNameW))
|
|
{
|
|
DEBUG_PRINT(DIALUP, INFO, ("Found CM connection to hang up\n"));
|
|
dwError = _RasHangUp(g_RasCon.GetHandle(i));
|
|
DEBUG_LEAVE_API(dwError);
|
|
return dwError;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
HWND hwndMonitorWnd = FindWindow(TEXT("MS_AutodialMonitor"),NULL);
|
|
if (hwndMonitorWnd) {
|
|
PostMessage(hwndMonitorWnd,WM_IEXPLORER_EXITING,0,0);
|
|
}
|
|
|
|
DEBUG_LEAVE_API(0);
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// Load ras
|
|
//
|
|
if(FALSE == EnsureRasLoaded())
|
|
{
|
|
DEBUG_LEAVE_API(ERROR_UNKNOWN);
|
|
return ERROR_UNKNOWN;
|
|
}
|
|
|
|
//
|
|
// hang up the connection
|
|
//
|
|
dwRet = _RasHangUp((HRASCONN)dwConnection);
|
|
|
|
DEBUG_LEAVE_API(dwRet);
|
|
return dwRet;
|
|
}
|
|
|
|
|
|
BOOLAPI InternetSetDialStateA(
|
|
IN LPCSTR lpszEntryName,
|
|
IN DWORD dwState,
|
|
IN DWORD dwReserved
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets current state for a custom dial handler.
|
|
|
|
This was broken in IE4 and didn't actually do anything. Rather than
|
|
leave it in this state, the notion of custom dial state has been
|
|
removed. [darrenmi]
|
|
|
|
Arguments:
|
|
|
|
lpszEntryName - connectiod to set state for
|
|
|
|
dwState - new connection state
|
|
|
|
dwReserved - must be 0
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
Success - TRUE
|
|
|
|
Failure - FALSE, GetLastError for more information
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER_API((DBG_DIALUP,
|
|
Bool,
|
|
"InternetSetDialStateA",
|
|
"%#x (%q), %#x, %#x",
|
|
lpszEntryName,
|
|
lpszEntryName,
|
|
dwState,
|
|
dwReserved
|
|
));
|
|
|
|
// NOTE: When this starts using lpszEntryName, remember to define USES_STRING to activate
|
|
// unicode conversions for InternetSetDialStateW.
|
|
|
|
if(dwReserved)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
DEBUG_ERROR(DIALUP, ERROR_INVALID_PARAMETER);
|
|
|
|
DEBUG_LEAVE_API(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
// [darrenmi] I do not expect any client to ever call this api - I don't
|
|
// think any were ever written. Only possible exception may be CM.
|
|
// If it does call it, I want to know.
|
|
#ifdef DEBUG
|
|
OutputDebugString("Wininet.DLL: Unexpected use of dead api, contact darrenmi [x34231]\n");
|
|
OutputDebugString("Wininet.DLL: It is safe to continue past this DebugBreak()\n");
|
|
DebugBreak();
|
|
#endif
|
|
|
|
DEBUG_LEAVE_API(TRUE);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOLAPI InternetSetDialStateW(
|
|
IN LPCWSTR lpszEntryName,
|
|
IN DWORD dwState,
|
|
IN DWORD dwReserved
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Wide version of InternetSetDialStateA
|
|
|
|
Arguments:
|
|
|
|
Same as InternetSetDialStateA
|
|
|
|
Return Value:
|
|
|
|
Same as InternetSetDialStateA
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER_API((DBG_DIALUP,
|
|
Bool,
|
|
"InternetSetDialStateW",
|
|
"%#x (%Q), %#x, %#x",
|
|
lpszEntryName,
|
|
lpszEntryName,
|
|
dwState,
|
|
dwReserved
|
|
));
|
|
|
|
BOOL fRet;
|
|
|
|
//
|
|
// Convert and call multibyte version
|
|
//
|
|
#ifdef INTERNETSETDIALSTATE_USES_CONNECTOID
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
MEMORYPACKET mpConnectoid;
|
|
|
|
if (lpszEntryName)
|
|
{
|
|
ALLOC_MB(lpszEntryName, 0, mpConnectoid);
|
|
if (!mpConnectoid.psStr)
|
|
{
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
UNICODE_TO_ANSI(lpszEntryName, mpConnectoid);
|
|
}
|
|
fRet = InternetSetDialStateA(mpConnectoid.psStr, dwState, dwReserved);
|
|
|
|
cleanup:
|
|
if (dwErr!=ERROR_SUCCESS)
|
|
{
|
|
SetLastError(dwErr);
|
|
DEBUG_ERROR(DIALUP, dwErr);
|
|
}
|
|
#else
|
|
fRet = InternetSetDialStateA(NULL, dwState, dwReserved);
|
|
#endif
|
|
|
|
DEBUG_LEAVE_API(fRet);
|
|
return fRet;
|
|
}
|
|
|
|
|
|
BOOLAPI InternetGoOnlineW(
|
|
IN LPWSTR lpszURL,
|
|
IN HWND hwndParent,
|
|
IN DWORD dwFlags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Show UI to ask user whether they wish to go back online. This is
|
|
triggered by clicking a link that isn't available offline.
|
|
|
|
Arguments:
|
|
|
|
lpszURL - url that triggered switch (currently not used)
|
|
|
|
hwndParent - parent window for dialog
|
|
|
|
dwFlags - operation control flags (currently not used)
|
|
INTERENT_GOONLINE_REFRESH
|
|
This was caused by a refresh rather than a click
|
|
on an unavailable link
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
Success - TRUE
|
|
|
|
Failure - FALSE, GetLastError for more information
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER_API((DBG_DIALUP,
|
|
Bool,
|
|
"InternetGoOnlineW",
|
|
"%#x (%Q), %#x, %#x",
|
|
lpszURL,
|
|
lpszURL,
|
|
hwndParent,
|
|
dwFlags
|
|
));
|
|
|
|
INT_PTR fRet = TRUE;
|
|
|
|
//
|
|
// validate flags
|
|
//
|
|
if(dwFlags & ~INTERENT_GOONLINE_REFRESH)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
DEBUG_ERROR(DIALUP, ERROR_INVALID_PARAMETER);
|
|
|
|
DEBUG_LEAVE_API(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// if already online, we're done
|
|
//
|
|
if(IsGlobalOffline())
|
|
{
|
|
ULONG_PTR uCookie = 0;
|
|
SHActivateContext(&uCookie);
|
|
//
|
|
// Show ui to ask user to go online
|
|
//
|
|
fRet = DialogBoxParamWrapW(GlobalDllHandle, MAKEINTRESOURCEW(IDD_GOONLINE),
|
|
hwndParent, OnlineDlgProc, 0);
|
|
|
|
if (uCookie)
|
|
{
|
|
SHDeactivateContext(uCookie);
|
|
}
|
|
}
|
|
|
|
if(fRet)
|
|
{
|
|
//
|
|
// Make sure we're connected.
|
|
//
|
|
SetOffline(FALSE);
|
|
|
|
MEMORYPACKET mpUrl;
|
|
if (lpszURL)
|
|
{
|
|
ALLOC_MB(lpszURL, 0, mpUrl);
|
|
if (mpUrl.psStr)
|
|
{
|
|
UNICODE_TO_ANSI(lpszURL, mpUrl);
|
|
fRet = InternetAutodialIfNotLocalHost(mpUrl.psStr, NULL);
|
|
}
|
|
else
|
|
{
|
|
fRet = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
DEBUG_LEAVE_API(fRet != 0);
|
|
return (fRet != 0);
|
|
}
|
|
|
|
|
|
BOOLAPI InternetGoOnlineA(
|
|
IN LPSTR lpszURL,
|
|
IN HWND hwndParent,
|
|
IN DWORD dwFlags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Wide version of InternetGoOnlineA
|
|
|
|
Arguments:
|
|
|
|
Same as InternetGoOnlineA
|
|
|
|
Return Value:
|
|
|
|
Same as InternetGoOnlineA
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER_API((DBG_DIALUP,
|
|
Bool,
|
|
"InternetGoOnlineA",
|
|
"%#x (%q), %#x, %#x",
|
|
lpszURL,
|
|
lpszURL,
|
|
hwndParent,
|
|
dwFlags
|
|
));
|
|
|
|
BOOL fRet = FALSE;
|
|
|
|
//
|
|
// Convert and call multibyte version
|
|
//
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
BOOL fResult = FALSE;
|
|
LPWSTR lpszWideURL = NULL;
|
|
|
|
if (lpszURL)
|
|
{
|
|
int i;
|
|
DWORD dwLen = lstrlenA(lpszURL);
|
|
if((lpszWideURL = (LPWSTR)LocalAlloc(LPTR, (dwLen+1) * sizeof(WCHAR))) != NULL)
|
|
{
|
|
i = MultiByteToWideChar(CP_ACP, 0, lpszURL, -1, lpszWideURL, dwLen);
|
|
if(0 == i)
|
|
lpszWideURL[dwLen] = 0; // truncated - null terminate
|
|
}
|
|
}
|
|
|
|
fRet = InternetGoOnlineW(lpszWideURL, hwndParent, dwFlags);
|
|
|
|
if(lpszWideURL)
|
|
{
|
|
LocalFree(lpszWideURL);
|
|
}
|
|
|
|
DEBUG_LEAVE_API(fRet);
|
|
return fRet;
|
|
}
|
|
|
|
|
|
BOOL
|
|
InternetAutodial(
|
|
IN DWORD dwFlags,
|
|
IN HWND hwndParent
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dials the internet connectoid
|
|
|
|
Arguments:
|
|
|
|
dwFlags - flags to control operation
|
|
|
|
xxx
|
|
|
|
hwndParent - parent window for any ui that's displayed
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
Success - TRUE
|
|
|
|
Failure - FALSE, GetLastError for more info
|
|
|
|
--*/
|
|
|
|
{
|
|
DEBUG_ENTER_API((DBG_DIALUP,
|
|
Bool,
|
|
"InternetAutodial",
|
|
"%#x, %#x",
|
|
dwFlags,
|
|
hwndParent
|
|
));
|
|
|
|
AUTODIAL config;
|
|
DWORD dwErrorCode = ERROR_INTERNET_INTERNAL_ERROR;
|
|
DWORD dwRet = ERROR_SUCCESS, dwLanFlags;
|
|
HWND hwnd = GetDesktopWindow();
|
|
|
|
|
|
//
|
|
// On Millennium, forward calls to RAS
|
|
//
|
|
if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRasInternetAutodialA)
|
|
{
|
|
DWORD dwRasFlags;
|
|
|
|
dwRet = HandleFlagsForRas(hwndParent, TRUE, dwFlags, &dwRasFlags);
|
|
if(dwRet)
|
|
{
|
|
// error, need to bail out
|
|
DEBUG_LEAVE_API(dwRet);
|
|
return dwRet;
|
|
}
|
|
|
|
dwRet = _RasInternetAutodialA(dwRasFlags, hwndParent);
|
|
|
|
//
|
|
// Switch to offline mode if necessary
|
|
//
|
|
HandleUserCancel(dwRet, dwFlags);
|
|
|
|
//
|
|
// If connected, send message to dialmon
|
|
//
|
|
CDHINFO cdh;
|
|
DWORD dwEntry = 0;
|
|
|
|
if(IsDialUpConnection(TRUE, &dwEntry) && !IsCDH(g_RasCon.GetEntryW(dwEntry), &cdh))
|
|
{
|
|
SendDialmonMessage(WM_SET_CONNECTOID_NAME, TRUE);
|
|
}
|
|
|
|
//
|
|
// fix proxy information for new connection
|
|
//
|
|
FixProxySettingsForCurrentConnection(FALSE);
|
|
|
|
//
|
|
// Prop return code
|
|
//
|
|
if(dwRet)
|
|
{
|
|
DEBUG_ERROR(DIALUP, dwRet);
|
|
SetLastError(dwRet);
|
|
}
|
|
|
|
DEBUG_LEAVE_API(0 == dwRet);
|
|
return (0 == dwRet);
|
|
}
|
|
|
|
// dwFlags - only valid flag is INTERNET_AUTODIAL_FORCE_UNATTENDED
|
|
// Keep ISVs honest about this
|
|
if(dwFlags & ~(INTERNET_AUTODIAL_FLAGS_MASK))
|
|
{
|
|
dwErrorCode = ERROR_INVALID_PARAMETER;
|
|
goto quit;
|
|
}
|
|
|
|
if(FALSE == g_fAutodialInitialized)
|
|
{
|
|
InitAutodialModule(TRUE);
|
|
}
|
|
|
|
// if no parent window was passed, use desktop window
|
|
if(NULL == hwndParent)
|
|
{
|
|
hwndParent = GetDesktopWindow();
|
|
}
|
|
|
|
//
|
|
// need connection mutex for FixProxySettings and IsLanConnection
|
|
//
|
|
WaitForSingleObject(g_hConnectionMutex, INFINITE);
|
|
|
|
//
|
|
// check to see if we're already connected
|
|
//
|
|
if(IsDialUpConnection(FALSE, &dwRet))
|
|
{
|
|
// make sure proxy settings are correct
|
|
FixProxySettings(g_RasCon.GetEntryW(dwRet), FALSE, 0);
|
|
ReleaseMutex(g_hConnectionMutex);
|
|
|
|
// If we're connected by modem, ensure online if necessary
|
|
if(dwFlags & INTERNET_AUTODIAL_FORCE_ONLINE)
|
|
{
|
|
SetOffline(FALSE);
|
|
}
|
|
|
|
dwErrorCode = ERROR_SUCCESS;
|
|
goto quit;
|
|
}
|
|
|
|
// Check config and make sure we have connectoids if we're supposed to
|
|
// dial one
|
|
if(IsAutodialEnabled(NULL, &config))
|
|
{
|
|
if(FALSE == EnsureRasLoaded())
|
|
{
|
|
config.fEnabled = config.fForceDial = FALSE;
|
|
}
|
|
else
|
|
{
|
|
RasEnumHelp *pRasEnum = new RasEnumHelp;
|
|
|
|
if (pRasEnum)
|
|
{
|
|
if (pRasEnum->GetEntryCount() == 0)
|
|
{
|
|
config.fEnabled = config.fForceDial = FALSE;
|
|
}
|
|
delete pRasEnum;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(IsLanConnection(&dwLanFlags) && (FALSE == config.fForceDial))
|
|
{
|
|
if(!config.fEnabled || !(dwFlags & INTERNET_AUTODIAL_OVERRIDE_NET_PRESENT))
|
|
{
|
|
// make sure proxy settings are correct
|
|
FixProxySettings(NULL, FALSE, dwLanFlags);
|
|
ReleaseMutex(g_hConnectionMutex);
|
|
|
|
// autodial not necessary
|
|
dwErrorCode = ERROR_SUCCESS;
|
|
goto quit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// check if offline and can't go online...
|
|
//
|
|
if( GlobalIsProcessExplorer && IsGlobalOffline() &&
|
|
0 == (dwFlags & INTERNET_AUTODIAL_FORCE_ONLINE)) {
|
|
|
|
ReleaseMutex(g_hConnectionMutex);
|
|
dwErrorCode = ERROR_INTERNET_OFFLINE;
|
|
goto quit;
|
|
}
|
|
|
|
// make sure we're online
|
|
SetOffline(FALSE);
|
|
|
|
// make sure we're supposed to dial
|
|
if(FALSE == config.fEnabled) {
|
|
fDontProcessHook = TRUE;
|
|
dwErrorCode = ERROR_SUCCESS;
|
|
|
|
DEBUG_PRINT(DIALUP, INFO, ("Unable to find a connection\n"));
|
|
|
|
// no connections and can't dial. Prompt to go offline.
|
|
if(g_fAskOffline)
|
|
{
|
|
// IE5 Beta 1 Hack - Throw up this dialog for explorer or IE
|
|
// Only for now. However, we should introduce an API that
|
|
// allows any app to say that it wants to participate in
|
|
// IE's Offline Mode stuff and all such apps would then
|
|
// get this dialog
|
|
|
|
if(GlobalIsProcessExplorer)
|
|
{
|
|
ULONG_PTR uCookie = 0;
|
|
SHActivateContext(&uCookie);
|
|
// Throw up this dialog for explorer.exe or iexplore.exe only
|
|
if(DialogBoxParamWrapW(GlobalDllHandle, MAKEINTRESOURCEW(IDD_GOOFFLINE),
|
|
hwndParent, GoOfflinePromptDlgProc,(LPARAM) 0))
|
|
{
|
|
SetOffline(TRUE);
|
|
}
|
|
else
|
|
{
|
|
g_fAskOffline = FALSE;
|
|
}
|
|
if (uCookie)
|
|
{
|
|
SHDeactivateContext(uCookie);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// If we try to hit the net at this point, we want to use the lan
|
|
// settings whatever they are.
|
|
//
|
|
// This is the only place settings get propagated when no connection
|
|
// can be found.
|
|
//
|
|
FixProxySettings(NULL, FALSE, 0);
|
|
ReleaseMutex(g_hConnectionMutex);
|
|
|
|
goto quit;
|
|
}
|
|
|
|
// if no entry, fill in a bogus one - dialing UI will pick the first
|
|
// one
|
|
if(FALSE == config.fHasEntry) {
|
|
config.pszEntryName[0] = 0;
|
|
config.fHasEntry = TRUE;
|
|
}
|
|
|
|
ReleaseMutex(g_hConnectionMutex);
|
|
|
|
// Load Ras
|
|
if(FALSE == EnsureRasLoaded()) {
|
|
// Load of ras failed - probably not installed
|
|
fDontProcessHook = TRUE;
|
|
dwErrorCode = ERROR_SERVICE_DOES_NOT_EXIST;
|
|
goto quit;
|
|
}
|
|
|
|
//
|
|
// Fix dial flags
|
|
//
|
|
if((dwFlags & INTERNET_AUTODIAL_FORCE_UNATTENDED) && (config.fUnattended))
|
|
dwFlags |= INTERNET_DIAL_UNATTENDED;
|
|
|
|
//
|
|
// Dial it
|
|
//
|
|
DWORD_PTR dwHandle;
|
|
dwErrorCode = InternetDialW(hwndParent, config.pszEntryName, dwFlags, &dwHandle, 0);
|
|
|
|
quit:
|
|
if(dwErrorCode != ERROR_SUCCESS)
|
|
{
|
|
SetLastError(dwErrorCode);
|
|
DEBUG_ERROR(DIALUP, dwErrorCode);
|
|
}
|
|
DEBUG_LEAVE_API(dwErrorCode == ERROR_SUCCESS);
|
|
|
|
return((dwErrorCode == ERROR_SUCCESS));
|
|
}
|
|
|
|
|
|
BOOLAPI InternetAutodialHangup(
|
|
IN DWORD dwReserved
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Finds and hangs up the autodial connection
|
|
|
|
If the autodial connection is a CDH, call the CDH to hang it up. This
|
|
may or may not work depending on whether the CDH supports hanging up.
|
|
|
|
Arguments:
|
|
|
|
dwReserved - must be 0
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
Success - TRUE
|
|
|
|
Failure - FALSE, GetLastError for more information
|
|
|
|
--*/
|
|
|
|
{
|
|
AUTODIAL config;
|
|
CDHINFO cdh;
|
|
|
|
DEBUG_ENTER_API((DBG_DIALUP,
|
|
Bool,
|
|
"InternetAutodialHangup",
|
|
"%#x",
|
|
dwReserved
|
|
));
|
|
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
int j = 0;
|
|
|
|
// ensure reserved is 0
|
|
if(dwReserved) {
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
DEBUG_ERROR(DIALUP, ERROR_INVALID_PARAMETER);
|
|
DEBUG_LEAVE_API(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// On Millennium, forward calls to RAS
|
|
//
|
|
if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRasInternetAutodialHangUpA)
|
|
{
|
|
dwErr = _RasInternetAutodialHangUpA(dwReserved);
|
|
|
|
DEBUG_LEAVE_API(TRUE);
|
|
return TRUE;
|
|
}
|
|
|
|
if(FALSE == g_fAutodialInitialized)
|
|
{
|
|
InitAutodialModule(FALSE);
|
|
}
|
|
|
|
// read connectoid - if none or autodial not enabled, bail
|
|
if(FALSE == IsAutodialEnabled(NULL, &config) || FALSE == config.fHasEntry)
|
|
goto quit;
|
|
|
|
if(IsCDH(config.pszEntryName, &cdh))
|
|
{
|
|
//
|
|
// If this CDH is CM, bail out here so the RasHangup below happens
|
|
//
|
|
if(NULL == StrStrIW(cdh.pszDllName, szCMDllNameW))
|
|
{
|
|
// ask it to hang up - may or may not do it depending on what it
|
|
// supports
|
|
//
|
|
// This isn't going to work. CM doesn't like getting commands it
|
|
// doesn't understand. For now, CDHs don't hang up. Tough.
|
|
//
|
|
// CallCDH(NULL, config.pszEntryName, &cdh, INTERNET_CUSTOMDIAL_DISCONNECT);
|
|
//
|
|
// Actually, post message to CDH's disconnect monitor. Works for
|
|
// MSN at least.
|
|
HWND hwndMonitorWnd = FindWindow(TEXT("MS_AutodialMonitor"),NULL);
|
|
if (hwndMonitorWnd) {
|
|
PostMessage(hwndMonitorWnd,WM_IEXPLORER_EXITING,0,0);
|
|
}
|
|
|
|
goto quit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// See if a ras connection matches the autodial connectoid
|
|
//
|
|
if(IsDialUpConnection(FALSE, NULL))
|
|
{
|
|
//
|
|
// See if any current connections match autodial connection
|
|
//
|
|
DWORD i;
|
|
|
|
for(i = 0; i < g_dwConnections; i++)
|
|
{
|
|
if(0 == StrCmpIW(g_RasCon.GetEntryW(i), config.pszEntryName))
|
|
{
|
|
_RasHangUp(g_RasCon.GetHandle(i));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
quit:
|
|
DEBUG_LEAVE_API(TRUE);
|
|
return TRUE;
|
|
}
|