Leaked source code of windows server 2003
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

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. autodial.cxx
  5. Abstract:
  6. Contains the implementation of autodial
  7. Contents:
  8. Author:
  9. Darren Mitchell (darrenmi) 22-Apr-1997
  10. Environment:
  11. Win32(s) user-mode DLL
  12. Revision History:
  13. 22-Apr-1997 darrenmi
  14. Created
  15. --*/
  16. #include "wininetp.h"
  17. #include "autodial.h"
  18. #include "rashelp.h"
  19. #include <sensapi.h>
  20. #include <winsvc.h>
  21. #include <commctrl.h>
  22. #include "millenras.h"
  23. #include <iphlpapi.h>
  24. // Globals.
  25. // In IE4 - there are several situations when these globals are
  26. // accessed simultaneously by different threads and so we need to protect them
  27. // with a mutex
  28. //
  29. // fDontProcessHook - set to TRUE in the following circumstances:
  30. //
  31. // - autodial is not enabled
  32. // - loading the ras dll failed
  33. // - no modem is installed
  34. //
  35. // this flag is only relevant on Win95.
  36. //
  37. BOOL fDontProcessHook = FALSE;
  38. DWORD g_dwLastTickCount = 0;
  39. // g_hwndWebCheck is currently not protected with a mutex
  40. HWND g_hwndWebCheck = NULL; // instead of findwindow every time
  41. // have we already checked out the current connection for proxy change?
  42. BOOL g_fConnChecked = FALSE;
  43. // serialize GetConnectedState
  44. HANDLE g_hConnectionMutex = INVALID_HANDLE_VALUE;
  45. // serialize access to RAS
  46. HANDLE g_hRasMutex = INVALID_HANDLE_VALUE;
  47. // serialize access to proxy reg settings
  48. HANDLE g_hProxyRegMutex = INVALID_HANDLE_VALUE;
  49. // Have we upgraded settings?
  50. BOOL g_fCheckedUpgrade = FALSE;
  51. // should we ask user to go offline if no connect?
  52. BOOL g_fAskOffline = TRUE;
  53. // Don't do any callbacks in rnaapp.exe process
  54. BOOL g_fRNAAppProcess = FALSE;
  55. // We use native font control from comctl so we need to call initcommoncontrols
  56. HMODULE hCommctrl = NULL;
  57. typedef BOOL (WINAPI *PFNINITCOMMONCONTROLS)(LPINITCOMMONCONTROLSEX);
  58. // base key for settings, lives in proxreg.cxx
  59. extern CRefdKey* g_prkBase;
  60. //
  61. // Enable sens network checking
  62. //
  63. #ifndef UNIX
  64. /* On Unix we assume we are on a LAN all the time */
  65. #define CHECK_SENS 1
  66. #endif /* UNIX */
  67. #ifdef CHECK_SENS
  68. // prototype for IsNetworkAlive()
  69. typedef BOOL (WINAPI *ISNETWORKALIVE)(LPDWORD);
  70. // handle to sens dll and entry point
  71. BOOL g_fSensInstalled = TRUE;
  72. HINSTANCE g_hSens = NULL;
  73. ISNETWORKALIVE g_pfnIsNetworkAlive = NULL;
  74. // how often to call sens to check state? Every 15 seconds seems reasonable
  75. #define MIN_SENS_CHECK_INTERVAL 15000
  76. DWORD g_dwLastSensCheck = 0;
  77. // message we send to dialmon to find out if sens is loaded
  78. #define WM_IS_SENSLCE_LOADED (WM_USER+201)
  79. #endif
  80. // registry strings
  81. const CHAR szRegPathRemoteAccess[] = REGSTR_PATH_REMOTEACCESS;
  82. const CHAR szRegPathInternetSettings[] = REGSTR_PATH_INTERNET_SETTINGS;
  83. const CHAR szRegValEnableAutodial[] = REGSTR_VAL_ENABLEAUTODIAL;
  84. const CHAR szRegValInternetEntry[] = REGSTR_VAL_INTERNETPROFILE;
  85. const CHAR szRegValUnattended[] = REGSTR_VAL_ENABLEUNATTENDED;
  86. static const CHAR szRegPathRNAProfile[] = REGSTR_PATH_REMOTEACCESS "\\Profile";
  87. static const CHAR szRegValAutodialDllName[] = REGSTR_VAL_AUTODIALDLLNAME;
  88. static const CHAR szRegValAutodialFcnName[] = REGSTR_VAL_AUTODIALFCNNAME;
  89. static const CHAR szRegValAutodialFlags[] = "HandlerFlags";
  90. static const CHAR szRegPathRNAService[] = REGSTR_PATH_SERVICES "\\RemoteAccess";
  91. static const CHAR szRegAddresses[] = "RemoteAccess\\Addresses";
  92. static const CHAR szRegPathTCP[] = REGSTR_PATH_VXD "\\MSTCP";
  93. static const CHAR szRegValRemoteConnection[] = "Remote Connection";
  94. static const CHAR szRegValHostName[] = "HostName";
  95. static const CHAR szInetPerformSecurityCheck[] = "InetPerformSecurityCheck";
  96. static const CHAR szRegValEnableSecurityCheck[] = REGSTR_VAL_ENABLESECURITYCHECK;
  97. static const CHAR szAutodialMonitorClass[] = REGSTR_VAL_AUTODIAL_MONITORCLASSNAME;
  98. static const CHAR szWebCheckMonitorClass[] = "MS_WebCheckMonitor";
  99. static const CHAR szRegPathComputerName[] = REGSTR_PATH_COMPUTRNAME;
  100. static const CHAR szRegValComputerName[] = REGSTR_VAL_COMPUTRNAME;
  101. static const CHAR szMigrateProxy[] = "MigrateProxy";
  102. static const CHAR szProxySuspect[] = "ProxySuspect";
  103. static const CHAR szCMDllName[] = "cmdial32.dll";
  104. // wide version of various registry strings
  105. #define TSZMICROSOFTPATHW L"Software\\Microsoft"
  106. #define TSZIEPATHW TSZMICROSOFTPATHW L"\\Internet Explorer"
  107. #define TSZWINCURVERPATHW TSZMICROSOFTPATHW L"\\windows\\CurrentVersion"
  108. #define TSZWININETPATHW TSZWINCURVERPATHW L"\\Internet Settings"
  109. #define REGSTR_PATH_INTERNETSETTINGSW TSZWININETPATHW
  110. #define REGSTR_PATH_INTERNET_LAN_SETTINGSW REGSTR_PATH_INTERNETSETTINGSW L"\\LAN"
  111. #define REGSTR_DIAL_AUTOCONNECTW L"AutoConnect"
  112. #define REGSTR_VAL_COVEREXCLUDEW L"CoverExclude"
  113. #define REGSTR_VAL_REDIALATTEMPTSW L"RedialAttempts"
  114. #define REGSTR_VAL_REDIALINTERVALW L"RedialWait"
  115. #define REGSTR_VAL_INTERNETENTRYW L"InternetProfile"
  116. #define REGSTR_VAL_INTERNETPROFILEW REGSTR_VAL_INTERNETENTRYW
  117. #define REGSTR_PATH_REMOTEACCESSW L"RemoteAccess"
  118. #define REGSTR_VAL_AUTODIALDLLNAMEW L"AutodialDllName"
  119. #define REGSTR_VAL_AUTODIALFCNNAMEW L"AutodialFcnName"
  120. const WCHAR szRegValInternetEntryW[] = REGSTR_VAL_INTERNETPROFILEW;
  121. const WCHAR szRegPathRemoteAccessW[] = REGSTR_PATH_REMOTEACCESSW;
  122. const WCHAR szRegPathRNAProfileW[] = REGSTR_PATH_REMOTEACCESSW L"\\Profile";
  123. const WCHAR szRegValAutodialDllNameW[] = REGSTR_VAL_AUTODIALDLLNAMEW;
  124. const WCHAR szRegValAutodialFcnNameW[] = REGSTR_VAL_AUTODIALFCNNAMEW;
  125. const WCHAR szRegValAutodialFlagsW[] = L"HandlerFlags";
  126. const WCHAR szCMDllNameW[] = L"cmdial32.dll";
  127. // NT reg keys for finding ras phonebook file
  128. static const CHAR szNTRasPhonebookKey[] = "Software\\Microsoft\\RAS Phonebook";
  129. static const CHAR szPhonebookMode[] = "PhonebookMode";
  130. // don't check RNA state more than once every 3 seconds
  131. #define MIN_RNA_BUSY_CHECK_INTERVAL 3000
  132. // Name or reg value we save legacy settings for comparison later
  133. #define LEGACY_MIGRATE_FLAGS (PROXY_TYPE_PROXY | PROXY_TYPE_AUTO_PROXY_URL)
  134. //
  135. // Current ras connections - used so we don't poll ras every time we're
  136. // interested - only poll every 3 seconds (const. above)
  137. //
  138. RasEnumConnHelp g_RasCon;
  139. DWORD g_dwConnections = 0;
  140. BOOL g_fRasInstalled = FALSE;
  141. DWORD g_dwLastDialupTicks = 0;
  142. //
  143. // API setting for autodial. Allow individual processes to disable autodial
  144. // using InternetSetOption.
  145. //
  146. // This can override an enabled setting but not a disabled setting.
  147. //
  148. BOOL g_fAutodialEnableAPISetting = TRUE;
  149. //
  150. // Control of autodial initialization
  151. //
  152. BOOL g_fAutodialInitialized = FALSE;
  153. //
  154. // Do we know for sure that winsock is loaded?
  155. //
  156. BOOL g_fWinsockLoaded = FALSE;
  157. HANDLE g_hDialEvent = NULL;
  158. //
  159. // Structure used to mess about with proxy settings
  160. //
  161. typedef struct _proxy {
  162. DWORD dwEnable;
  163. TCHAR szServer[INTERNET_MAX_URL_LENGTH];
  164. TCHAR szOverride[INTERNET_MAX_URL_LENGTH];
  165. DWORD dwSuspect;
  166. } PROXY, *PPROXY;
  167. //
  168. // Need GetBestRoute from iphlpapi -- dynaload it, free on ExitAutodialModule
  169. //
  170. typedef DWORD (WINAPI *GETBESTROUTE)(DWORD, DWORD, PMIB_IPFORWARDROW);
  171. static HINSTANCE g_hIphlpapi = NULL;
  172. static GETBESTROUTE g_pfnGetBestRoute = NULL;
  173. ///////////////////////////////////////////////////////////////////////////
  174. ///////////////////////////////////////////////////////////////////////////
  175. //
  176. // RAS dynaload code
  177. //
  178. ///////////////////////////////////////////////////////////////////////////
  179. ///////////////////////////////////////////////////////////////////////////
  180. static HINSTANCE g_hRasLib = NULL;
  181. static long g_lRasRefCnt = 0;
  182. static _RASHANGUP pfnRasHangUp = NULL;
  183. static _RASDIALA pfnRasDialA = NULL;
  184. static _RASENUMENTRIESA pfnRasEnumEntriesA = NULL;
  185. static _RASGETENTRYDIALPARAMSA pfnRasGetEntryDialParamsA = NULL;
  186. static _RASSETENTRYDIALPARAMSA pfnRasSetEntryDialParamsA = NULL;
  187. static _RASEDITPHONEBOOKENTRYA pfnRasEditPhonebookEntryA = NULL;
  188. static _RASCREATEPHONEBOOKENTRYA pfnRasCreatePhonebookEntryA = NULL;
  189. static _RASGETERRORSTRINGA pfnRasGetErrorStringA = NULL;
  190. static _RASGETCONNECTSTATUSA pfnRasGetConnectStatusA = NULL;
  191. static _RASENUMCONNECTIONSA pfnRasEnumConnectionsA = NULL;
  192. static _RASGETENTRYPROPERTIESA pfnRasGetEntryPropertiesA = NULL;
  193. static _RASDIALW pfnRasDialW = NULL;
  194. static _RASENUMENTRIESW pfnRasEnumEntriesW = NULL;
  195. static _RASGETENTRYDIALPARAMSW pfnRasGetEntryDialParamsW = NULL;
  196. static _RASSETENTRYDIALPARAMSW pfnRasSetEntryDialParamsW = NULL;
  197. static _RASEDITPHONEBOOKENTRYW pfnRasEditPhonebookEntryW = NULL;
  198. static _RASCREATEPHONEBOOKENTRYW pfnRasCreatePhonebookEntryW = NULL;
  199. static _RASGETERRORSTRINGW pfnRasGetErrorStringW = NULL;
  200. static _RASGETCONNECTSTATUSW pfnRasGetConnectStatusW = NULL;
  201. static _RASENUMCONNECTIONSW pfnRasEnumConnectionsW = NULL;
  202. static _RASGETENTRYPROPERTIESW pfnRasGetEntryPropertiesW = NULL;
  203. // Millennium (DUN 1.4?) RAS exports
  204. static _RASINTERNETDIAL pfnRasInternetDialA = NULL;
  205. static _RASINTERNETHANGUP pfnRasInternetHangUpA = NULL;
  206. static _RASINTERNETAUTODIAL pfnRasInternetAutodialA = NULL;
  207. static _RASINTERNETAUTODIALHANG pfnRasInternetAutodialHangUpA = NULL;
  208. static _RASINTERNETCONNSTATE pfnRasInternetGetConnectedStateExA = NULL;
  209. static _RNAGETDEFAULTAUTODIAL pfnRnaGetDefaultAutodialConnection = NULL;
  210. static _RNASETDEFAULTAUTODIAL pfnRnaSetDefaultAutodialConnection = NULL;
  211. // RAS entry points to sync up autodial connectoid... used on whistler only
  212. static _RASGETAUTODIALADDRESSA pfnRasGetAutodialAddressA = NULL;
  213. static _RASSETAUTODIALADDRESSA pfnRasSetAutodialAddressA = NULL;
  214. static _RASGETCREDENTIALSW pfnRasGetCredentialsW = NULL;
  215. static _RASSETCREDENTIALSW pfnRasSetCredentialsW = NULL;
  216. typedef struct _tagAPIMAPENTRY {
  217. FARPROC* pfn;
  218. LPSTR pszProc;
  219. } APIMAPENTRY;
  220. APIMAPENTRY rgRasApiMapA[] = {
  221. { (FARPROC*) &pfnRasDialA, "RasDialA" },
  222. { (FARPROC*) &pfnRasHangUp, "RasHangUpA" },
  223. { (FARPROC*) &pfnRasEnumEntriesA, "RasEnumEntriesA" },
  224. { (FARPROC*) &pfnRasGetEntryDialParamsA, "RasGetEntryDialParamsA" },
  225. { (FARPROC*) &pfnRasSetEntryDialParamsA, "RasSetEntryDialParamsA" },
  226. { (FARPROC*) &pfnRasEditPhonebookEntryA, "RasEditPhonebookEntryA" },
  227. { (FARPROC*) &pfnRasCreatePhonebookEntryA, "RasCreatePhonebookEntryA" },
  228. { (FARPROC*) &pfnRasGetErrorStringA, "RasGetErrorStringA" },
  229. { (FARPROC*) &pfnRasGetConnectStatusA, "RasGetConnectStatusA" },
  230. { (FARPROC*) &pfnRasEnumConnectionsA, "RasEnumConnectionsA" },
  231. { (FARPROC*) &pfnRasGetEntryPropertiesA, "RasGetEntryPropertiesA"},
  232. { (FARPROC*) &pfnRasInternetDialA, "RasInternetDialA"},
  233. { (FARPROC*) &pfnRasInternetHangUpA, "RasInternetHangUpA"},
  234. { (FARPROC*) &pfnRasInternetAutodialA, "RasInternetAutodialA"},
  235. { (FARPROC*) &pfnRasInternetAutodialHangUpA, "RasInternetAutodialHangUpA"},
  236. { (FARPROC*) &pfnRasInternetGetConnectedStateExA, "RasInternetGetConnectedStateExA"},
  237. { (FARPROC*) &pfnRnaGetDefaultAutodialConnection, "RnaGetDefaultAutodialConnection"},
  238. { (FARPROC*) &pfnRnaSetDefaultAutodialConnection, "RnaSetDefaultAutodialConnection"},
  239. { NULL, NULL },
  240. };
  241. APIMAPENTRY rgRasApiMapW[] = {
  242. { (FARPROC*) &pfnRasDialW, "RasDialW" },
  243. { (FARPROC*) &pfnRasHangUp, "RasHangUpW" },
  244. { (FARPROC*) &pfnRasEnumEntriesW, "RasEnumEntriesW" },
  245. { (FARPROC*) &pfnRasGetEntryDialParamsW, "RasGetEntryDialParamsW" },
  246. { (FARPROC*) &pfnRasSetEntryDialParamsW, "RasSetEntryDialParamsW" },
  247. { (FARPROC*) &pfnRasEditPhonebookEntryW, "RasEditPhonebookEntryW" },
  248. { (FARPROC*) &pfnRasCreatePhonebookEntryW, "RasCreatePhonebookEntryW" },
  249. { (FARPROC*) &pfnRasGetErrorStringW, "RasGetErrorStringW" },
  250. { (FARPROC*) &pfnRasGetConnectStatusW, "RasGetConnectStatusW" },
  251. { (FARPROC*) &pfnRasEnumConnectionsW, "RasEnumConnectionsW" },
  252. { (FARPROC*) &pfnRasGetEntryPropertiesW, "RasGetEntryPropertiesW"},
  253. { (FARPROC*) &pfnRasGetCredentialsW, "RasGetCredentialsW"},
  254. { (FARPROC*) &pfnRasSetCredentialsW, "RasSetCredentialsW"},
  255. // following are A in W map on purpose.. used on whistler only, but wininet code has
  256. // the connectoid in multibyte.. may as well let RAS convert it.
  257. { (FARPROC*) &pfnRasGetAutodialAddressA, "RasGetAutodialAddressA"},
  258. { (FARPROC*) &pfnRasSetAutodialAddressA, "RasSetAutodialAddressA"},
  259. { NULL, NULL },
  260. };
  261. #define RASFCN(_fn, _part, _par, _dbge, _dbgl) \
  262. DWORD _##_fn _part \
  263. { \
  264. DEBUG_ENTER(_dbge); \
  265. \
  266. DWORD dwRet; \
  267. if(NULL == pfn##_fn) \
  268. { \
  269. _dbgl(ERROR_INVALID_FUNCTION); \
  270. return ERROR_INVALID_FUNCTION; \
  271. } \
  272. \
  273. dwRet = (* pfn##_fn) _par; \
  274. \
  275. _dbgl(dwRet); \
  276. return dwRet; \
  277. }
  278. RASFCN(RasDialA,
  279. (LPRASDIALEXTENSIONS lpRasDialExtensions, LPSTR lpszPhonebook, LPRASDIALPARAMS lpRasDialParams, DWORD dwNotifierType, LPVOID lpvNotifier, LPHRASCONN lphRasConn),
  280. (lpRasDialExtensions, lpszPhonebook, lpRasDialParams, dwNotifierType, lpvNotifier, lphRasConn),
  281. (DBG_DIALUP, Dword, "RasDialA", "%#x, %#x (%q), %#x, %d, %#x, %#x", lpRasDialExtensions, lpszPhonebook, lpszPhonebook, lpRasDialParams, dwNotifierType, lpvNotifier, lphRasConn),
  282. DEBUG_LEAVE
  283. );
  284. RASFCN(RasHangUp,
  285. (HRASCONN hRasConn),
  286. (hRasConn),
  287. (DBG_DIALUP, Dword, "RasHangUp", "%#x", hRasConn),
  288. DEBUG_LEAVE
  289. );
  290. RASFCN(RasEnumEntriesA,
  291. (LPSTR lpszReserved, LPSTR lpszPhonebook, LPRASENTRYNAMEA lprasentryname, LPDWORD lpcb, LPDWORD lpcEntries),
  292. (lpszReserved, lpszPhonebook, lprasentryname, lpcb, lpcEntries),
  293. (DBG_DIALUP, Dword, "RasEnumEntriesA", "%#x (%q), %#x (%q), %#x, %#x, %#x", lpszReserved, lpszReserved, lpszPhonebook, lpszPhonebook, lprasentryname, lpcb, lpcEntries),
  294. DEBUG_LEAVE
  295. );
  296. RASFCN(RasGetEntryDialParamsA,
  297. (LPCSTR lpszPhonebook, LPRASDIALPARAMS lprasdialparams, LPBOOL lpfPassword),
  298. (lpszPhonebook, lprasdialparams, lpfPassword),
  299. (DBG_DIALUP, Dword, "RasGetEntryDialParamsA", "%#x (%q), %#x, %#x", lpszPhonebook, lpszPhonebook, lprasdialparams, lpfPassword),
  300. DEBUG_LEAVE
  301. );
  302. RASFCN(RasSetEntryDialParamsA,
  303. (LPCSTR lpszPhonebook,LPRASDIALPARAMS lprasdialparams, BOOL fRemovePassword),
  304. (lpszPhonebook,lprasdialparams, fRemovePassword),
  305. (DBG_DIALUP, Dword, "RasSetEntryDialParamsA", "%#x (%q), %#x, %d", lpszPhonebook, lpszPhonebook, lprasdialparams, fRemovePassword),
  306. DEBUG_LEAVE
  307. );
  308. RASFCN(RasGetErrorStringA,
  309. (UINT uError, LPSTR pszBuf, DWORD cBufSize),
  310. (uError, pszBuf, cBufSize),
  311. (DBG_DIALUP, Dword, "RasGetErrorStringA", "%d, %#x (%q), %d", uError, pszBuf, cBufSize),
  312. DEBUG_LEAVE
  313. );
  314. RASFCN(RasEditPhonebookEntryA,
  315. (HWND hwnd, LPSTR lpszBook, LPSTR lpszEntry),
  316. (hwnd, lpszBook, lpszEntry),
  317. (DBG_DIALUP, Dword, "RasEditPhonebookEntryA", "%#x, %#x (%q), %#x (%q)", hwnd, lpszBook, lpszBook, lpszEntry, lpszEntry),
  318. DEBUG_LEAVE
  319. );
  320. RASFCN(RasCreatePhonebookEntryA,
  321. (HWND hwnd, LPSTR pszBook),
  322. (hwnd, pszBook),
  323. (DBG_DIALUP, Dword, "RasCreatePhonebookEntryA", "%#x, %#x (%q)", hwnd, pszBook, pszBook),
  324. DEBUG_LEAVE
  325. );
  326. RASFCN(RasGetConnectStatusA,
  327. (HRASCONN hrasconn, LPRASCONNSTATUS lprasconnstatus),
  328. (hrasconn, lprasconnstatus),
  329. (DBG_DIALUP, Dword, "RasGetConnectStatusA", "%#x, %#x", hrasconn, lprasconnstatus),
  330. DEBUG_LEAVE
  331. );
  332. RASFCN(RasGetEntryPropertiesA,
  333. (LPSTR lpszPhonebook, LPSTR lpszEntry, LPRASENTRY lpRasEntry, LPDWORD lpdwEntryInfoSize, LPBYTE lpbDeviceInfo, LPDWORD lpdwDeviceInfoSize),
  334. (lpszPhonebook, lpszEntry, lpRasEntry, lpdwEntryInfoSize, lpbDeviceInfo, lpdwDeviceInfoSize),
  335. (DBG_DIALUP, Dword, "RasGetEntryPropertiesA", "%#x (%q), %#x (%q), %#x, %#x, %#x %#x", lpszPhonebook, lpszPhonebook, lpszEntry, lpszEntry, lpRasEntry, lpdwEntryInfoSize, lpbDeviceInfo, lpdwDeviceInfoSize),
  336. DEBUG_LEAVE
  337. );
  338. RASFCN(RasEnumConnectionsA,
  339. (LPRASCONN lpRasConn, LPDWORD lpdwSize, LPDWORD lpdwConn),
  340. (lpRasConn, lpdwSize, lpdwConn),
  341. (DBG_DIALUP, Dword, "RasEnumConnectionsA", "%#x, %#x, %#x", lpRasConn, lpdwSize, lpdwConn),
  342. DEBUG_LEAVE
  343. );
  344. RASFCN(RasInternetDialA,
  345. (HWND hwndParent, LPSTR pszEntryName, DWORD dwFlags, DWORD_PTR *lpdwConnection, DWORD dwReserved),
  346. (hwndParent, pszEntryName, dwFlags, lpdwConnection, dwReserved),
  347. (DBG_DIALUP, Dword, "RasInternetDialA", "#x, #x (%q), %x, %x, %x", hwndParent, pszEntryName, pszEntryName, dwFlags, lpdwConnection, dwReserved),
  348. DEBUG_LEAVE
  349. );
  350. RASFCN(RasInternetHangUpA,
  351. (DWORD_PTR dwConnection, DWORD dwReserved),
  352. (dwConnection, dwReserved),
  353. (DBG_DIALUP, Dword, "RasInternetHangUpA", "#x, #x", dwConnection, dwReserved),
  354. DEBUG_LEAVE
  355. );
  356. RASFCN(RasInternetAutodialA,
  357. (DWORD dwFlags, HWND hwndParent),
  358. (dwFlags, hwndParent),
  359. (DBG_DIALUP, Dword, "RasInterenetAutodialA", "#x, #x", dwFlags, hwndParent),
  360. DEBUG_LEAVE
  361. );
  362. RASFCN(RasInternetAutodialHangUpA,
  363. (DWORD dwReserved),
  364. (dwReserved),
  365. (DBG_DIALUP, Dword, "RasInternetAutodialHangUpA", "#x", dwReserved),
  366. DEBUG_LEAVE
  367. );
  368. RASFCN(RasInternetGetConnectedStateExA,
  369. (LPDWORD lpdwFlags, LPSTR lpszConnectionName, DWORD dwBufLen, DWORD dwReserved),
  370. (lpdwFlags, lpszConnectionName, dwBufLen, dwReserved),
  371. (DBG_DIALUP, Bool, "RasInternetGetConnectedStateExA", "%x, %x, %x, %x", lpdwFlags, lpszConnectionName, dwBufLen, dwReserved),
  372. DEBUG_LEAVE
  373. );
  374. RASFCN(RnaGetDefaultAutodialConnection,
  375. (LPSTR pszEntry, DWORD dwLen, LPDWORD lpdwFlags),
  376. (pszEntry, dwLen, lpdwFlags),
  377. (DBG_DIALUP, Dword, "RnaGetDefaultAutodialConnection", "%#x, %#x, %#x", pszEntry, dwLen, lpdwFlags),
  378. DEBUG_LEAVE
  379. );
  380. RASFCN(RnaSetDefaultAutodialConnection,
  381. (LPSTR pszEntry, DWORD dwFlags),
  382. (pszEntry, dwFlags),
  383. (DBG_DIALUP, Dword, "RnaSetDefaultAutodialConnection", "%#x (%q), %#x", pszEntry, pszEntry, dwFlags),
  384. DEBUG_LEAVE
  385. );
  386. ////////////////////////////////////////////////////
  387. // Wide versions
  388. RASFCN(RasDialW,
  389. (LPRASDIALEXTENSIONS lpRasDialExtensions, LPWSTR lpszPhonebook,
  390. LPRASDIALPARAMSW lpRasDialParams, DWORD dwNotifierType, LPVOID lpvNotifier, LPHRASCONN lphRasConn),
  391. (lpRasDialExtensions, lpszPhonebook, lpRasDialParams, dwNotifierType, lpvNotifier, lphRasConn),
  392. (DBG_DIALUP, Dword, "RasDialW", "%#x, %#x (%Q), %#x, %d, %#x, %#x", lpRasDialExtensions, lpszPhonebook, lpszPhonebook, lpRasDialParams, dwNotifierType, lpvNotifier, lphRasConn),
  393. DEBUG_LEAVE
  394. );
  395. RASFCN(RasEnumEntriesW,
  396. (LPWSTR lpszReserved, LPWSTR lpszPhonebook, LPRASENTRYNAMEW lprasentryname,
  397. LPDWORD lpcb, LPDWORD lpcEntries),
  398. (lpszReserved, lpszPhonebook, lprasentryname, lpcb, lpcEntries),
  399. (DBG_DIALUP, Dword, "RasEnumEntriesW", "%#x (%Q), %#x (%Q), %#x, %#x %#x", lpszReserved, lpszReserved, lpszPhonebook, lpszPhonebook, lprasentryname, lpcb, lpcEntries),
  400. DEBUG_LEAVE
  401. );
  402. RASFCN(RasGetEntryDialParamsW,
  403. (LPCWSTR lpszPhonebook, LPRASDIALPARAMSW lprasdialparams, LPBOOL lpfPassword),
  404. (lpszPhonebook, lprasdialparams, lpfPassword),
  405. (DBG_DIALUP, Dword, "RasGetEntryDialParamsW", "%#x (%Q), %#x, %#x", lpszPhonebook, lpszPhonebook, lprasdialparams, lpfPassword),
  406. DEBUG_LEAVE
  407. );
  408. RASFCN(RasSetEntryDialParamsW,
  409. (LPCWSTR lpszPhonebook, LPRASDIALPARAMSW lprasdialparams, BOOL fRemovePassword),
  410. (lpszPhonebook,lprasdialparams, fRemovePassword),
  411. (DBG_DIALUP, Dword, "RasSetEntryDialParamsW", "%#x (%Q), %#x, %d", lpszPhonebook, lpszPhonebook, lprasdialparams, fRemovePassword),
  412. DEBUG_LEAVE
  413. );
  414. RASFCN(RasGetErrorStringW,
  415. (UINT uError, LPWSTR pszBuf, DWORD cBufSize),
  416. (uError, pszBuf, cBufSize),
  417. (DBG_DIALUP, Dword, "RasGetErrorStringW", "%d, %#x (%Q), %d", uError, pszBuf, cBufSize),
  418. DEBUG_LEAVE
  419. );
  420. RASFCN(RasEditPhonebookEntryW,
  421. (HWND hwnd, LPWSTR lpszBook, LPWSTR lpszEntry),
  422. (hwnd, lpszBook, lpszEntry),
  423. (DBG_DIALUP, Dword, "RasEditPhonebookEntryW", "%#x, %#x (%Q), %#x (%Q)", hwnd, lpszBook, lpszBook, lpszEntry, lpszEntry),
  424. DEBUG_LEAVE
  425. );
  426. RASFCN(RasCreatePhonebookEntryW,
  427. (HWND hwnd, LPWSTR pszBook),
  428. (hwnd, pszBook),
  429. (DBG_DIALUP, Dword, "RasCreatePhonebookEntryW", "%#x, %#x (%Q)", hwnd, pszBook, pszBook),
  430. DEBUG_LEAVE
  431. );
  432. RASFCN(RasGetConnectStatusW,
  433. (HRASCONN hrasconn, LPRASCONNSTATUSW lprasconnstatus),
  434. (hrasconn, lprasconnstatus),
  435. (DBG_DIALUP, Dword, "RasGetConnectStatusW", "%#x, %#x", hrasconn, lprasconnstatus),
  436. DEBUG_LEAVE
  437. );
  438. RASFCN(RasGetEntryPropertiesW,
  439. (LPWSTR lpszPhonebook, LPWSTR lpszEntry, LPRASENTRYW lpRasEntry, LPDWORD lpdwEntryInfoSize, LPBYTE lpbDeviceInfo, LPDWORD lpdwDeviceInfoSize),
  440. (lpszPhonebook, lpszEntry, lpRasEntry, lpdwEntryInfoSize, lpbDeviceInfo, lpdwDeviceInfoSize),
  441. (DBG_DIALUP, Dword, "RasGetEntryPropertiesW", "%#x (%Q), %#x (%Q), %#x, %#x, %#x %#x", lpszPhonebook, lpszPhonebook, lpszEntry, lpszEntry, lpRasEntry, lpdwEntryInfoSize, lpbDeviceInfo, lpdwDeviceInfoSize),
  442. DEBUG_LEAVE
  443. );
  444. RASFCN(RasEnumConnectionsW,
  445. (LPRASCONNW lpRasConn, LPDWORD lpdwSize, LPDWORD lpdwConn),
  446. (lpRasConn, lpdwSize, lpdwConn),
  447. (DBG_DIALUP, Dword, "RasEnumConnectionsW", "%#x, %#x, %#x", lpRasConn, lpdwSize, lpdwConn),
  448. DEBUG_LEAVE
  449. );
  450. RASFCN(RasGetAutodialAddressA,
  451. (LPCSTR lpszAddress, LPDWORD lpdwReserved, LPRASAUTODIALENTRYA lpEntries, LPDWORD lpdwBytes, LPDWORD lpdwEntries),
  452. (lpszAddress, lpdwReserved, lpEntries, lpdwBytes, lpdwEntries),
  453. (DBG_DIALUP, Dword, "RasGetAutodialAddressA", "%#x (%Q), %#x, %#x, %#x, %#x", lpszAddress, lpszAddress, lpdwReserved, lpEntries, lpdwBytes, lpdwEntries),
  454. DEBUG_LEAVE
  455. );
  456. RASFCN(RasSetAutodialAddressA,
  457. (LPCSTR lpszAddress, DWORD dwReserved, LPRASAUTODIALENTRYA lpEntries, DWORD dwBytes, DWORD dwEntries),
  458. (lpszAddress, dwReserved, lpEntries, dwBytes, dwEntries),
  459. (DBG_DIALUP, Dword, "RasSetAutodialAddressA", "%#x (%q), %#x, %#x, %#x, %#x", lpszAddress, lpszAddress, dwReserved, lpEntries, dwBytes, dwEntries),
  460. DEBUG_LEAVE
  461. );
  462. RASFCN(RasGetCredentialsW,
  463. (LPCWSTR pszPhonebook, LPCWSTR pszEntry, LPRASCREDENTIALSW pCreds),
  464. (pszPhonebook, pszEntry, pCreds),
  465. (DBG_DIALUP, Dword, "RasGetCredentialsW", "%#x (%Q), %#x (%Q), %#x", pszPhonebook, pszPhonebook, pszEntry, pszEntry, pCreds),
  466. DEBUG_LEAVE
  467. );
  468. RASFCN(RasSetCredentialsW,
  469. (LPCWSTR pszPhonebook, LPCWSTR pszEntry, LPRASCREDENTIALSW pCreds, BOOL fNuke),
  470. (pszPhonebook, pszEntry, pCreds, fNuke),
  471. (DBG_DIALUP, Dword, "RasSetCredentialsW", "%#x (%Q), %#x (%Q), %#x, %#x", pszPhonebook, pszPhonebook, pszEntry, pszEntry, pCreds, fNuke),
  472. DEBUG_LEAVE
  473. );
  474. ///////////////////////////////////////////////////////////////////////////
  475. ///////////////////////////////////////////////////////////////////////////
  476. BOOL
  477. EnsureRasLoaded(
  478. VOID
  479. )
  480. /*++
  481. Routine Description:
  482. Dynaload ras apis
  483. Arguments:
  484. pfInstalled - return installed state of ras
  485. Return Value:
  486. BOOL
  487. TRUE - Ras loaded
  488. FALSE - Ras not loaded
  489. --*/
  490. {
  491. DEBUG_ENTER((DBG_DIALUP,
  492. Bool,
  493. "EnsureRasLoaded",
  494. NULL
  495. ));
  496. //
  497. // Looks like RAS is installed - try and load it up!
  498. //
  499. if(NULL == g_hRasLib) {
  500. g_hRasLib = LoadLibrary("RASAPI32.DLL");
  501. if(NULL == g_hRasLib)
  502. {
  503. DEBUG_LEAVE(FALSE);
  504. return FALSE;
  505. }
  506. APIMAPENTRY *prgRasApiMap;
  507. if(PLATFORM_TYPE_WIN95 == GlobalPlatformType)
  508. prgRasApiMap = rgRasApiMapA;
  509. else
  510. prgRasApiMap = rgRasApiMapW;
  511. int nIndex = 0;
  512. while ((prgRasApiMap+nIndex)->pszProc != NULL) {
  513. // Some functions are only present on some platforms. Don't
  514. // assume this succeeds for all functions.
  515. *(prgRasApiMap+nIndex)->pfn =
  516. GetProcAddress(g_hRasLib, (prgRasApiMap+nIndex)->pszProc);
  517. nIndex++;
  518. }
  519. }
  520. if(g_hRasLib) {
  521. g_lRasRefCnt++;
  522. DEBUG_LEAVE(TRUE);
  523. return TRUE;
  524. }
  525. DEBUG_LEAVE(FALSE);
  526. return FALSE;
  527. }
  528. BOOL
  529. IsServiceRunning(
  530. LPSTR pszServiceName,
  531. DWORD dwRequiredState
  532. )
  533. /*++
  534. Routine Description:
  535. Determines whether a specified service is running on NT
  536. Arguments:
  537. pszServiceName - service to find
  538. dwRequiredState - state the service has to be in to consider it found
  539. Return Value:
  540. BOOL
  541. TRUE - Service is in required state
  542. FALSE - not
  543. --*/
  544. {
  545. DEBUG_ENTER((DBG_DIALUP,
  546. Bool,
  547. "IsServiceRunning",
  548. "%#x (%q), %#x",
  549. pszServiceName,
  550. pszServiceName,
  551. dwRequiredState
  552. ));
  553. SC_HANDLE hscm;
  554. BOOL fFoundService = FALSE;
  555. //
  556. // Sanity check - can only do this on NT
  557. //
  558. if(PLATFORM_TYPE_WIN95 == GlobalPlatformType)
  559. {
  560. DEBUG_LEAVE(FALSE);
  561. return FALSE;
  562. }
  563. //
  564. // Ask service manager to enumerate all running services
  565. //
  566. hscm = OpenSCManager(NULL, NULL, GENERIC_READ);
  567. if(hscm)
  568. {
  569. SC_HANDLE hras;
  570. ENUM_SERVICE_STATUS essServices[16];
  571. DWORD dwError, dwResume = 0, i;
  572. DWORD cbNeeded = 1, csReturned;
  573. while(FALSE == fFoundService && cbNeeded > 0)
  574. {
  575. // Get the next chunk of services
  576. dwError = 0;
  577. if(FALSE == EnumServicesStatus(hscm, SERVICE_WIN32, dwRequiredState,
  578. essServices, sizeof(essServices), &cbNeeded, &csReturned,
  579. &dwResume))
  580. {
  581. dwError = GetLastError();
  582. }
  583. if(dwError && dwError != ERROR_MORE_DATA)
  584. {
  585. // unknown error - bail
  586. break;
  587. }
  588. for(i=0; i<csReturned; i++)
  589. {
  590. if(0 == lstrcmpi(essServices[i].lpServiceName, pszServiceName))
  591. {
  592. // found it!
  593. fFoundService = TRUE;
  594. break;
  595. }
  596. }
  597. }
  598. CloseServiceHandle(hscm);
  599. }
  600. DEBUG_LEAVE(fFoundService);
  601. return fFoundService;
  602. }
  603. BOOL
  604. IsRasInstalled(
  605. VOID
  606. )
  607. /*++
  608. Routine Description:
  609. Determines whether ras is installed on this machine
  610. Arguments:
  611. none
  612. Return Value:
  613. BOOL
  614. TRUE - Ras is installed
  615. FALSE - Ras is not installed
  616. --*/
  617. {
  618. DEBUG_ENTER_API((DBG_DIALUP,
  619. Bool,
  620. "IsRasInstalled",
  621. NULL
  622. ));
  623. static fChecked = FALSE;
  624. //
  625. // If RAS is already loaded, don't bother doing any work.
  626. //
  627. if(g_hRasLib)
  628. {
  629. DEBUG_LEAVE_API(TRUE);
  630. return TRUE;
  631. }
  632. //
  633. // if we've already done the check, don't do it again
  634. //
  635. if(fChecked)
  636. {
  637. DEBUG_LEAVE_API(g_fRasInstalled);
  638. return g_fRasInstalled;
  639. }
  640. if(PLATFORM_TYPE_WIN95 == GlobalPlatformType) {
  641. //
  642. // Check Win9x key
  643. //
  644. char szSmall[3]; // there should be a "1" or a "0" only
  645. DWORD cb;
  646. HKEY hkey;
  647. long lRes;
  648. lRes = REGOPENKEYEX(HKEY_LOCAL_MACHINE, REGSTR_PATH_RNACOMPONENT,
  649. NULL, KEY_READ, &hkey);
  650. if(ERROR_SUCCESS == lRes) {
  651. cb = sizeof(szSmall);
  652. // REGSTR_VAL_RNAINSTALLED is defined with TEXT() macro so
  653. // if wininet is ever compiled unicode this will be a compile
  654. // error.
  655. lRes = RegQueryValueExA(hkey, REGSTR_VAL_RNAINSTALLED, NULL,
  656. NULL, (LPBYTE)szSmall, &cb);
  657. if(ERROR_SUCCESS == lRes) {
  658. if((szSmall[0] == '1') && (szSmall[1] == 0)) {
  659. // 1 means ras installed
  660. g_fRasInstalled = TRUE;
  661. }
  662. }
  663. REGCLOSEKEY(hkey);
  664. }
  665. } else {
  666. OSVERSIONINFO osvi;
  667. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  668. GetVersionEx(&osvi);
  669. if (osvi.dwMajorVersion < 5)
  670. {
  671. // on NT4, make sure ras man service is installed
  672. g_fRasInstalled = IsServiceRunning("RasMan", SERVICE_STATE_ALL);
  673. if(g_fRasInstalled)
  674. {
  675. if(EnsureRasLoaded() && FALSE == GlobalDisableNT4RasCheck)
  676. {
  677. RasEnumHelp *pRasEnum = NULL;
  678. __try
  679. {
  680. // call rasenumentries - if it faults, we're in that
  681. // NT4 busted case so return not installed.
  682. pRasEnum = new RasEnumHelp;
  683. }
  684. __except(EXCEPTION_EXECUTE_HANDLER)
  685. {
  686. // if it faults, don't use ras any more
  687. g_fRasInstalled = FALSE;
  688. }
  689. ENDEXCEPT
  690. if (pRasEnum)
  691. delete pRasEnum;
  692. }
  693. }
  694. }
  695. else
  696. {
  697. // NT5 and presumably beyond, ras is always installed
  698. g_fRasInstalled = TRUE;
  699. }
  700. }
  701. fChecked = TRUE;
  702. DEBUG_LEAVE_API(g_fRasInstalled);
  703. return g_fRasInstalled;
  704. }
  705. BOOL
  706. DoConnectoidsExist(
  707. VOID
  708. )
  709. /*++
  710. Routine Description:
  711. Determines whether any ras connectoids exist
  712. Arguments:
  713. none
  714. Return Value:
  715. BOOL
  716. TRUE - Connectoids exist
  717. FALSE - No connectoids exist
  718. --*/
  719. {
  720. DEBUG_ENTER_API((DBG_DIALUP,
  721. Bool,
  722. "DoConnectoidsExist",
  723. NULL
  724. ));
  725. static BOOL fExist = FALSE;
  726. //
  727. // If we found connectoids before, don't bother looking again
  728. //
  729. if(fExist)
  730. {
  731. DEBUG_LEAVE_API(TRUE);
  732. return TRUE;
  733. }
  734. //
  735. // If RAS is already loaded, ask it
  736. //
  737. if(g_hRasLib && FALSE == GlobalDisableNT4RasCheck) {
  738. DWORD dwRet, dwEntries;
  739. RasEnumHelp *pRasEnum = new RasEnumHelp;
  740. if (pRasEnum)
  741. {
  742. dwRet = pRasEnum->GetError();
  743. dwEntries = pRasEnum->GetEntryCount();
  744. delete pRasEnum;
  745. }
  746. else
  747. {
  748. dwRet = ERROR_NOT_ENOUGH_MEMORY;
  749. }
  750. // If ras tells us there are none, return none
  751. if(ERROR_SUCCESS == dwRet && 0 == dwEntries)
  752. {
  753. DEBUG_LEAVE_API(FALSE);
  754. return FALSE;
  755. }
  756. // couldn't determine that there aren't any so assume there are.
  757. fExist = TRUE;
  758. DEBUG_LEAVE_API(TRUE);
  759. return TRUE;
  760. }
  761. //
  762. // if ras isn't installed, say no connectoids
  763. //
  764. if(FALSE == IsRasInstalled())
  765. {
  766. DEBUG_LEAVE_API(FALSE);
  767. return FALSE;
  768. }
  769. if(PLATFORM_TYPE_WIN95 == GlobalPlatformType) {
  770. // On win95, check for any value in RemoteAccess\Addresses reg key
  771. HKEY hkey;
  772. TCHAR szName[RAS_MaxEntryName+1];
  773. DWORD cbName = RAS_MaxEntryName+1;
  774. long lRes;
  775. if(ERROR_SUCCESS == REGOPENKEYEX(HKEY_CURRENT_USER, szRegAddresses,
  776. 0, KEY_READ, &hkey)) {
  777. lRes = RegEnumValue(hkey, 0, szName, &cbName, NULL, NULL, NULL, NULL);
  778. if(ERROR_SUCCESS == lRes) {
  779. // we managed to get info on a connectoid.
  780. fExist = TRUE;
  781. }
  782. REGCLOSEKEY(hkey);
  783. }
  784. } else {
  785. OSVERSIONINFO osvi;
  786. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  787. GetVersionEx(&osvi);
  788. // assume connectoids exist
  789. fExist = TRUE;
  790. if (osvi.dwMajorVersion < 5) {
  791. // On NT4, check for rasphone.pbk size > 0
  792. TCHAR szPhonebook[MAX_PATH + 128];
  793. ULONG uLen, ulMode, cb;
  794. HANDLE hFile = INVALID_HANDLE_VALUE;
  795. DWORD dwSize, dwBigSize;
  796. HKEY hkey;
  797. // Ensure system phonebook is the one in use. If user has switched
  798. // to another phonebook, don't bother doing anything else and assume
  799. // connectoids exist. It's not our job to grope the world trying to
  800. // find custom phonebooks.
  801. if(ERROR_SUCCESS == REGOPENKEYEX(HKEY_CURRENT_USER, szNTRasPhonebookKey,
  802. 0, KEY_READ, &hkey))
  803. {
  804. *szPhonebook = 0;
  805. cb = sizeof(ULONG);
  806. if(ERROR_SUCCESS == RegQueryValueEx(hkey, szPhonebookMode, NULL,
  807. NULL, (LPBYTE)&ulMode, &cb) && 0 == ulMode)
  808. {
  809. // system phonebook - rasphone.pbk in ras directory
  810. uLen = GetSystemDirectory(szPhonebook, MAX_PATH);
  811. if(uLen)
  812. {
  813. // append \ras\rasphone.pbk
  814. LoadString(GlobalDllHandle, IDS_RASPHONEBOOK, szPhonebook + uLen, 128);
  815. hFile = CreateFile(szPhonebook, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
  816. NULL, OPEN_EXISTING, 0, NULL);
  817. if(INVALID_HANDLE_VALUE == hFile) {
  818. // file doesn't exist - no connectoids
  819. fExist = FALSE;
  820. } else {
  821. dwSize = GetFileSize(hFile, &dwBigSize);
  822. if(0 == dwSize && 0 == dwBigSize)
  823. // zero size system phonebook - no connectoids
  824. fExist = FALSE;
  825. CloseHandle(hFile);
  826. }
  827. }
  828. }
  829. REGCLOSEKEY(hkey);
  830. }
  831. }
  832. }
  833. DEBUG_LEAVE_API(fExist);
  834. return fExist;
  835. }
  836. ///////////////////////////////////////////////////////////////////////////
  837. ///////////////////////////////////////////////////////////////////////////
  838. //
  839. // Helper Functions
  840. //
  841. ///////////////////////////////////////////////////////////////////////////
  842. ///////////////////////////////////////////////////////////////////////////
  843. BOOL
  844. InitCommCtrl(
  845. VOID
  846. )
  847. /*++
  848. Routine Description:
  849. Initializes common controls for native font control
  850. Called from InternetDialA which is serialized.
  851. Arguments:
  852. None
  853. Return Value:
  854. BOOL
  855. TRUE - successly called InitCommonControlsEx
  856. FALSE - failed
  857. --*/
  858. {
  859. DEBUG_ENTER((DBG_DIALUP,
  860. Bool,
  861. "InitCommCtrl",
  862. NULL
  863. ));
  864. BOOL fSuccess = FALSE;
  865. hCommctrl = LoadLibrary("comctl32.dll");
  866. if(hCommctrl)
  867. {
  868. PFNINITCOMMONCONTROLS pfnInit;
  869. pfnInit = (PFNINITCOMMONCONTROLS)GetProcAddress(hCommctrl, "InitCommonControlsEx");
  870. if(pfnInit)
  871. {
  872. INITCOMMONCONTROLSEX ex;
  873. ex.dwSize = sizeof(ex);
  874. ex.dwICC = ICC_NATIVEFNTCTL_CLASS;
  875. pfnInit(&ex);
  876. fSuccess = TRUE;
  877. }
  878. }
  879. DEBUG_LEAVE(fSuccess);
  880. return fSuccess;
  881. }
  882. VOID
  883. ExitCommCtrl(
  884. VOID
  885. )
  886. /*++
  887. Routine Description:
  888. Unloads commctrl library
  889. Called from InternetDialA which is serialized.
  890. Arguments:
  891. None
  892. Return Value:
  893. None
  894. --*/
  895. {
  896. DEBUG_ENTER((DBG_DIALUP,
  897. None,
  898. "ExitCommCtrl",
  899. NULL
  900. ));
  901. if(hCommctrl)
  902. {
  903. FreeLibrary(hCommctrl);
  904. hCommctrl = NULL;
  905. }
  906. DEBUG_LEAVE(0);
  907. }
  908. BOOL
  909. IsGlobalOffline(
  910. VOID
  911. )
  912. /*++
  913. Routine Description:
  914. Determines whether wininet is in global offline mode
  915. Arguments:
  916. None
  917. Return Value:
  918. BOOL
  919. TRUE - offline
  920. FALSE - online
  921. --*/
  922. {
  923. DEBUG_ENTER((DBG_DIALUP,
  924. Bool,
  925. "IsGlobalOffline",
  926. NULL
  927. ));
  928. DWORD dwState = 0, dwSize = sizeof(DWORD);
  929. BOOL fRet = FALSE;
  930. if(InternetQueryOption(NULL, INTERNET_OPTION_CONNECTED_STATE, &dwState,
  931. &dwSize))
  932. {
  933. if(dwState & INTERNET_STATE_DISCONNECTED_BY_USER)
  934. fRet = TRUE;
  935. }
  936. DEBUG_LEAVE(fRet);
  937. return fRet;
  938. }
  939. VOID
  940. SetOffline(
  941. IN BOOL fOffline
  942. )
  943. /*++
  944. Routine Description:
  945. Sets wininet's offline mode
  946. Arguments:
  947. fOffline - online or offline
  948. Return Value:
  949. None.
  950. --*/
  951. {
  952. DEBUG_ENTER((DBG_DIALUP,
  953. None,
  954. "SetOffline",
  955. "%B",
  956. fOffline
  957. ));
  958. INTERNET_CONNECTED_INFO ci;
  959. memset(&ci, 0, sizeof(ci));
  960. if(fOffline) {
  961. ci.dwConnectedState = INTERNET_STATE_DISCONNECTED_BY_USER;
  962. ci.dwFlags = ISO_FORCE_DISCONNECTED;
  963. } else {
  964. ci.dwConnectedState = INTERNET_STATE_CONNECTED;
  965. }
  966. InternetSetOption(NULL, INTERNET_OPTION_CONNECTED_STATE, &ci, sizeof(ci));
  967. DEBUG_LEAVE(0);
  968. }
  969. VOID
  970. GetConnKeyW(
  971. IN LPWSTR pszConn,
  972. IN LPWSTR pszKey,
  973. IN int iLen
  974. )
  975. /*++
  976. Routine Description:
  977. Get registry key for a specific connection
  978. Arguments:
  979. pszConn - connection for which key is required
  980. pszKey - buffer to put key
  981. iLen - buffer size
  982. Return Value:
  983. None.
  984. --*/
  985. {
  986. DEBUG_ENTER((DBG_DIALUP,
  987. None,
  988. "GetConnKeyW",
  989. "%#x (%Q), %#x, %d",
  990. pszConn,
  991. pszConn,
  992. pszKey,
  993. iLen
  994. ));
  995. if(NULL == pszConn || 0 == *pszConn)
  996. {
  997. // lan setting
  998. StrCpyNW(pszKey, REGSTR_PATH_INTERNET_LAN_SETTINGSW, iLen);
  999. }
  1000. else
  1001. {
  1002. // connectoid settings
  1003. wnsprintfW(pszKey, iLen, L"%ws\\%ws", szRegPathRNAProfileW, pszConn);
  1004. }
  1005. DEBUG_LEAVE(0);
  1006. }
  1007. VOID
  1008. GetConnKeyA(
  1009. IN LPSTR pszConn,
  1010. IN LPSTR pszKey,
  1011. IN int iLen
  1012. )
  1013. /*++
  1014. Routine Description:
  1015. Get registry key for a specific connection
  1016. Arguments:
  1017. pszConn - connection for which key is required
  1018. pszKey - buffer to put key
  1019. iLen - buffer size
  1020. Return Value:
  1021. None.
  1022. --*/
  1023. {
  1024. DEBUG_ENTER((DBG_DIALUP,
  1025. None,
  1026. "GetConnKeyA",
  1027. "%#x (%q), %#x, %d",
  1028. pszConn,
  1029. pszConn,
  1030. pszKey,
  1031. iLen
  1032. ));
  1033. if(NULL == pszConn || 0 == *pszConn)
  1034. {
  1035. // lan setting
  1036. lstrcpynA(pszKey, REGSTR_PATH_INTERNET_LAN_SETTINGS, iLen);
  1037. }
  1038. else
  1039. {
  1040. // connectoid settings
  1041. wnsprintfA(pszKey, iLen, "%s\\%s", szRegPathRNAProfile, pszConn);
  1042. }
  1043. DEBUG_LEAVE(0);
  1044. }
  1045. VOID
  1046. SetAutodialEnable(
  1047. IN BOOL fEnable
  1048. )
  1049. /*++
  1050. Routine Description:
  1051. Sets the API setting for controlling autodial. Called from
  1052. InternetSetOption.
  1053. Arguments:
  1054. fEnable - FALSE means don't autodial for this process
  1055. TRUE means autodial if configured by the user
  1056. Return Value:
  1057. none.
  1058. --*/
  1059. {
  1060. DEBUG_ENTER((DBG_DIALUP,
  1061. None,
  1062. "SetAutodialEnable",
  1063. "%B",
  1064. fEnable
  1065. ));
  1066. g_fAutodialEnableAPISetting = fEnable;
  1067. DEBUG_LEAVE(0);
  1068. }
  1069. DWORD
  1070. GetAutodialMode(
  1071. )
  1072. {
  1073. DEBUG_ENTER((DBG_DIALUP,
  1074. Dword,
  1075. "GetAutodialMode",
  1076. NULL
  1077. ));
  1078. DWORD dwMode = AUTODIAL_MODE_NO_NETWORK_PRESENT, dwError, dwData;
  1079. // make sure RAS and Wininet flags match up
  1080. INET_ASSERT(RAS_AUTODIAL_OPT_NEVER == AUTODIAL_MODE_NEVER);
  1081. INET_ASSERT(RAS_AUTODIAL_OPT_ALWAYS == AUTODIAL_MODE_ALWAYS);
  1082. INET_ASSERT(RAS_AUTODIAL_OPT_DEMAND == AUTODIAL_MODE_NO_NETWORK_PRESENT);
  1083. if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRnaGetDefaultAutodialConnection)
  1084. {
  1085. dwError = _RnaGetDefaultAutodialConnection(NULL, 0, &dwMode);
  1086. if(dwError)
  1087. {
  1088. DEBUG_ERROR(DIALUP, dwError);
  1089. dwMode = AUTODIAL_MODE_NEVER;
  1090. }
  1091. dwMode &= (RAS_AUTODIAL_OPT_NEVER | RAS_AUTODIAL_OPT_ALWAYS | RAS_AUTODIAL_OPT_DEMAND);
  1092. DEBUG_LEAVE(dwMode);
  1093. return dwMode;
  1094. }
  1095. if(InternetReadRegistryDword(REGSTR_VAL_ENABLEAUTODIAL, &dwData) ||
  1096. 0 == dwData)
  1097. {
  1098. dwMode = AUTODIAL_MODE_NEVER;
  1099. }
  1100. if(AUTODIAL_MODE_NO_NETWORK_PRESENT == dwMode)
  1101. {
  1102. if(InternetReadRegistryDword(REGSTR_VAL_NONETAUTODIAL, &dwData) ||
  1103. 0 == dwData)
  1104. {
  1105. dwMode = AUTODIAL_MODE_ALWAYS;
  1106. }
  1107. }
  1108. DEBUG_LEAVE(dwMode);
  1109. return dwMode;
  1110. }
  1111. DWORD
  1112. SetAutodialMode(
  1113. IN DWORD dwMode
  1114. )
  1115. {
  1116. DEBUG_ENTER((DBG_DIALUP,
  1117. Dword,
  1118. "SetAutodialMode",
  1119. "%#x",
  1120. dwMode
  1121. ));
  1122. DWORD dwEnable = 0, dwNonet = 0, dwError = 0;
  1123. // make sure RAS and Wininet flags match up
  1124. INET_ASSERT(RAS_AUTODIAL_OPT_NEVER == AUTODIAL_MODE_NEVER);
  1125. INET_ASSERT(RAS_AUTODIAL_OPT_ALWAYS == AUTODIAL_MODE_ALWAYS);
  1126. INET_ASSERT(RAS_AUTODIAL_OPT_DEMAND == AUTODIAL_MODE_NO_NETWORK_PRESENT);
  1127. if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRnaSetDefaultAutodialConnection && pfnRnaGetDefaultAutodialConnection)
  1128. {
  1129. CHAR szOldName[RAS_MaxEntryName+1];
  1130. DWORD dwOldMode;
  1131. // Have to set both name and mode at the same time, so read existing values and change
  1132. // what we need.
  1133. dwError = _RnaGetDefaultAutodialConnection(szOldName, ARRAYSIZE(szOldName), &dwOldMode);
  1134. if(0 == dwError)
  1135. {
  1136. dwError = _RnaSetDefaultAutodialConnection(szOldName, dwMode);
  1137. }
  1138. DEBUG_LEAVE(dwError);
  1139. return dwError;
  1140. }
  1141. switch(dwMode)
  1142. {
  1143. case AUTODIAL_MODE_NEVER:
  1144. break;
  1145. case AUTODIAL_MODE_NO_NETWORK_PRESENT:
  1146. dwNonet = 1;
  1147. // fall through to always
  1148. case AUTODIAL_MODE_ALWAYS:
  1149. dwEnable = 1;
  1150. break;
  1151. default:
  1152. dwError = ERROR_INVALID_PARAMETER;
  1153. }
  1154. if(ERROR_SUCCESS == dwError)
  1155. {
  1156. InternetWriteRegistryDword(REGSTR_VAL_ENABLEAUTODIAL, dwEnable);
  1157. InternetWriteRegistryDword(REGSTR_VAL_NONETAUTODIAL, dwNonet);
  1158. }
  1159. DEBUG_LEAVE(dwError);
  1160. return dwError;
  1161. }
  1162. DWORD
  1163. GetAutodialConnection(
  1164. CHAR *pszBuffer,
  1165. DWORD dwBufferLength
  1166. )
  1167. {
  1168. DEBUG_ENTER((DBG_DIALUP,
  1169. Dword,
  1170. "GetAutodialConnection",
  1171. "%#x, %#x",
  1172. pszBuffer,
  1173. dwBufferLength
  1174. ));
  1175. DWORD dwType, dwHasEntry = FALSE, dwMode, dwError = ERROR_INVALID_NAME;
  1176. if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRnaGetDefaultAutodialConnection)
  1177. {
  1178. dwError = _RnaGetDefaultAutodialConnection(pszBuffer, dwBufferLength, &dwMode);
  1179. if(0 == dwError)
  1180. {
  1181. DEBUG_PRINT(DIALUP, INFO, ("Entry=%s, Mode=%x", pszBuffer, dwMode));
  1182. }
  1183. DEBUG_LEAVE(dwError);
  1184. return dwError;
  1185. }
  1186. if(GlobalPlatformWhistler && EnsureRasLoaded() && pfnRasGetAutodialAddressA)
  1187. {
  1188. RASAUTODIALENTRYA adEntry;
  1189. DWORD dwBytes, dwEntries;
  1190. ZeroMemory(&adEntry, sizeof(adEntry));
  1191. adEntry.dwSize = sizeof(adEntry);
  1192. dwBytes = sizeof(adEntry);
  1193. dwEntries = 1;
  1194. dwError = _RasGetAutodialAddressA(
  1195. NULL,
  1196. NULL,
  1197. &adEntry,
  1198. &dwBytes,
  1199. &dwEntries);
  1200. if(NO_ERROR == dwError && dwEntries)
  1201. {
  1202. lstrcpyn(pszBuffer, adEntry.szEntry, dwBufferLength);
  1203. }
  1204. else
  1205. {
  1206. *pszBuffer = 0;
  1207. }
  1208. DEBUG_LEAVE(dwError);
  1209. return dwError;
  1210. }
  1211. if(ERROR_SUCCESS == SHGetValueA(HKEY_CURRENT_USER, szRegPathRemoteAccess,
  1212. szRegValInternetEntry, &dwType, pszBuffer, &dwBufferLength) &&
  1213. lstrlen(pszBuffer))
  1214. {
  1215. dwError = 0; // success
  1216. }
  1217. DEBUG_LEAVE(dwError);
  1218. return dwError;
  1219. }
  1220. DWORD
  1221. SetAutodialConnection(
  1222. CHAR *pszConnection
  1223. )
  1224. {
  1225. DEBUG_ENTER((DBG_DIALUP,
  1226. Dword,
  1227. "SetAutodialConnection",
  1228. "%#x (%q)",
  1229. pszConnection,
  1230. pszConnection
  1231. ));
  1232. DWORD dwError;
  1233. if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRnaSetDefaultAutodialConnection && pfnRnaGetDefaultAutodialConnection)
  1234. {
  1235. CHAR szOldName[RAS_MaxEntryName+1];
  1236. DWORD dwOldMode;
  1237. // Have to set both name and mode at the same time, so read existing values and change
  1238. // what we need.
  1239. dwError = _RnaGetDefaultAutodialConnection(szOldName, ARRAYSIZE(szOldName), &dwOldMode);
  1240. if(0 == dwError)
  1241. {
  1242. dwError = _RnaSetDefaultAutodialConnection(pszConnection, dwOldMode);
  1243. }
  1244. DEBUG_LEAVE(dwError);
  1245. return dwError;
  1246. }
  1247. if(GlobalPlatformWhistler && EnsureRasLoaded() && pfnRasSetAutodialAddressA)
  1248. {
  1249. RASAUTODIALENTRYA adEntry;
  1250. ZeroMemory(&adEntry, sizeof(adEntry));
  1251. adEntry.dwSize = sizeof(adEntry);
  1252. lstrcpyn(adEntry.szEntry, pszConnection, sizeof(adEntry.szEntry) / sizeof(TCHAR));
  1253. dwError = _RasSetAutodialAddressA(
  1254. NULL,
  1255. NULL,
  1256. &adEntry,
  1257. sizeof(adEntry),
  1258. 1);
  1259. DEBUG_LEAVE(dwError);
  1260. return dwError;
  1261. }
  1262. SHSetValue(HKEY_CURRENT_USER, szRegPathRemoteAccess, szRegValInternetEntry,
  1263. REG_SZ, pszConnection, lstrlen(pszConnection));
  1264. DEBUG_LEAVE(0);
  1265. return 0;
  1266. }
  1267. BOOL
  1268. IsAutodialEnabled(
  1269. OUT BOOL *pfForceDial,
  1270. IN AUTODIAL *pConfig
  1271. )
  1272. /*++
  1273. Routine Description:
  1274. Read flags used to control autodial. Also honors SetOption setting
  1275. to override and not autodial.
  1276. Note: if autodial isn't enabled, the rest of the structure isn't read.
  1277. Arguments:
  1278. pConfig - AUTODIAL struct to store info. NULL is valid if info
  1279. isn't required.
  1280. Return Value:
  1281. BOOL
  1282. TRUE - Autodial is enabled
  1283. FALSE - Autodial is not enabled
  1284. --*/
  1285. {
  1286. DEBUG_ENTER((DBG_DIALUP,
  1287. Bool,
  1288. "IsAutodialEnabled",
  1289. "%#x, %#x",
  1290. pfForceDial,
  1291. pConfig
  1292. ));
  1293. HKEY hKey;
  1294. DWORD dwRes, dwData = 0, dwSize, dwType;
  1295. BOOL fConfigured, fEnabled;
  1296. //
  1297. // Init out parameter
  1298. //
  1299. if(pfForceDial)
  1300. {
  1301. *pfForceDial = FALSE;
  1302. }
  1303. if(pConfig)
  1304. {
  1305. memset(pConfig, 0, sizeof(AUTODIAL));
  1306. }
  1307. //
  1308. // Get autodial enabled
  1309. //
  1310. fConfigured = fEnabled = TRUE;
  1311. // check registry setting
  1312. if(InternetReadRegistryDword(REGSTR_VAL_ENABLEAUTODIAL, &dwData) ||
  1313. 0 == dwData)
  1314. {
  1315. fEnabled = fConfigured = FALSE;
  1316. }
  1317. if(fEnabled)
  1318. {
  1319. if(InternetReadRegistryDword(REGSTR_VAL_NONETAUTODIAL, &dwData) ||
  1320. 0 == dwData)
  1321. {
  1322. // don't use sens -- imitate IE4 and before behavior
  1323. if(pConfig)
  1324. {
  1325. pConfig->fForceDial = TRUE;
  1326. }
  1327. if(pfForceDial)
  1328. {
  1329. *pfForceDial = TRUE;
  1330. }
  1331. }
  1332. // update fEnabled based on api setting
  1333. fEnabled = g_fAutodialEnableAPISetting;
  1334. }
  1335. if(NULL == pConfig)
  1336. {
  1337. DEBUG_LEAVE(fEnabled);
  1338. return fEnabled;
  1339. }
  1340. //
  1341. // save enabled to pconfig struct
  1342. //
  1343. pConfig->fEnabled = fEnabled;
  1344. pConfig->fConfigured = fConfigured;
  1345. //
  1346. // read security check
  1347. //
  1348. dwSize = sizeof(dwData);
  1349. if( GlobalPlatformType == PLATFORM_TYPE_WIN95 &&
  1350. InternetReadRegistryDword(szRegValEnableSecurityCheck, &dwData) == ERROR_SUCCESS &&
  1351. dwData)
  1352. {
  1353. pConfig->fSecurity = TRUE;
  1354. }
  1355. if(FALSE == fEnabled)
  1356. {
  1357. // if autodial isn't enabled, no point in reading the rest of the
  1358. // info because it isn't used
  1359. DEBUG_LEAVE(fEnabled);
  1360. return fEnabled;
  1361. }
  1362. //
  1363. // read connectoid name
  1364. //
  1365. CHAR szConnectoidName[RAS_MaxEntryName + 1];
  1366. if(ERROR_SUCCESS == GetAutodialConnection(szConnectoidName, RAS_MaxEntryName))
  1367. {
  1368. MultiByteToWideChar(CP_ACP, 0, szConnectoidName, -1, pConfig->pszEntryName, RAS_MaxEntryName);
  1369. }
  1370. else
  1371. {
  1372. pConfig->pszEntryName[0] = 0;
  1373. }
  1374. if(lstrlenW(pConfig->pszEntryName))
  1375. {
  1376. pConfig->fHasEntry = TRUE;
  1377. // if possible, verify that autodial entry actually exists
  1378. RasEntryPropHelp *pRasProp = new RasEntryPropHelp;
  1379. if (pRasProp)
  1380. {
  1381. if(pRasProp->GetError() == 0)
  1382. {
  1383. DWORD dwRet = pRasProp->GetW(pConfig->pszEntryName);
  1384. if((ERROR_SUCCESS != dwRet) && (ERROR_INVALID_FUNCTION != dwRet))
  1385. {
  1386. // ras doesn't know about this - blow it away
  1387. pConfig->fHasEntry = FALSE;
  1388. *pConfig->pszEntryName = 0;
  1389. }
  1390. }
  1391. delete pRasProp;
  1392. }
  1393. }
  1394. if(FALSE == pConfig->fHasEntry && (FALSE == DoConnectoidsExist()))
  1395. {
  1396. // We expect an entry at this point. If we don't and none exist at
  1397. // this point, autodial isn't, in fact, enabled.
  1398. pConfig->fEnabled = FALSE;
  1399. pConfig->fForceDial = FALSE;
  1400. if(pfForceDial)
  1401. {
  1402. *pfForceDial = FALSE;
  1403. }
  1404. }
  1405. //
  1406. // read autoconnect for the specified entry
  1407. //
  1408. if(pConfig->fHasEntry)
  1409. {
  1410. WCHAR szKey[MAX_PATH];
  1411. GetConnKeyW(pConfig->pszEntryName, szKey, ARRAYSIZE(szKey));
  1412. dwSize = sizeof(DWORD);
  1413. if(ERROR_SUCCESS == SHGetValueW(HKEY_CURRENT_USER, szKey,
  1414. REGSTR_DIAL_AUTOCONNECTW, &dwType, &dwData, &dwSize) &&
  1415. dwData)
  1416. {
  1417. pConfig->fUnattended = TRUE;
  1418. }
  1419. }
  1420. DEBUG_LEAVE(pConfig->fEnabled);
  1421. return pConfig->fEnabled;
  1422. }
  1423. UINT_PTR
  1424. SendDialmonMessage(
  1425. UINT uMessage,
  1426. BOOL fPost
  1427. )
  1428. /*++
  1429. Routine Description:
  1430. Send a message to dialmon
  1431. Arguments:
  1432. uMessage - message to send
  1433. fPost - post or send
  1434. Return Value:
  1435. Return of send or 0 if post
  1436. --*/
  1437. {
  1438. DEBUG_ENTER((DBG_DIALUP,
  1439. Dword,
  1440. "SendDialmonMessage",
  1441. "%x, %B",
  1442. uMessage,
  1443. fPost
  1444. ));
  1445. UINT_PTR uRet = 0;
  1446. // Send a message to dialmon's monitor window to start monitoring this
  1447. // connectoid
  1448. if(NULL == g_hwndWebCheck) {
  1449. g_hwndWebCheck = FindWindow(szWebCheckMonitorClass,NULL);
  1450. }
  1451. if(g_hwndWebCheck) {
  1452. if(fPost)
  1453. {
  1454. PostMessage(g_hwndWebCheck, uMessage, 0, 0);
  1455. }
  1456. else
  1457. {
  1458. uRet = SendMessage(g_hwndWebCheck, uMessage, 0, 0);
  1459. }
  1460. }
  1461. DEBUG_LEAVE(uRet);
  1462. return uRet;
  1463. }
  1464. BOOL
  1465. GetRedialParameters(
  1466. IN LPWSTR pszConn,
  1467. OUT LPDWORD pdwDialAttempts,
  1468. OUT LPDWORD pdwDialInterval
  1469. )
  1470. /*++
  1471. Routine Description:
  1472. Get redial information for a specific connectoid
  1473. Arguments:
  1474. pszConn - connection name
  1475. pdwDialAttempts - location to store dial attempts
  1476. pdwDialInterval - location to store dial interval
  1477. Return Value:
  1478. BOOL
  1479. TRUE - success
  1480. FALSE - failure
  1481. --*/
  1482. {
  1483. DEBUG_ENTER((DBG_DIALUP,
  1484. Bool,
  1485. "GetRedialParameters",
  1486. "%#x (%Q), %x, %x",
  1487. pszConn,
  1488. pszConn,
  1489. pdwDialAttempts,
  1490. pdwDialInterval
  1491. ));
  1492. WCHAR szKey[MAX_PATH];
  1493. DWORD dwValue, dwSize;
  1494. HKEY hkey;
  1495. //
  1496. // validate and clear out variables
  1497. //
  1498. if(NULL == pdwDialAttempts || NULL == pdwDialInterval)
  1499. {
  1500. DEBUG_LEAVE(FALSE);
  1501. return FALSE;
  1502. }
  1503. //
  1504. // set to defaults
  1505. //
  1506. *pdwDialAttempts = DEFAULT_DIAL_ATTEMPTS;
  1507. *pdwDialInterval = DEFAULT_DIAL_INTERVAL;
  1508. //
  1509. // read values from registry
  1510. //
  1511. GetConnKeyW(pszConn, szKey, ARRAYSIZE(szKey));
  1512. dwSize = sizeof(DWORD);
  1513. if(ERROR_SUCCESS == SHGetValueW(HKEY_CURRENT_USER, szKey, REGSTR_VAL_REDIALATTEMPTSW, NULL, &dwValue, &dwSize) && dwValue)
  1514. {
  1515. *pdwDialAttempts = dwValue;
  1516. }
  1517. dwSize = sizeof(DWORD);
  1518. if(ERROR_SUCCESS == SHGetValueW(HKEY_CURRENT_USER, szKey, REGSTR_VAL_REDIALINTERVALW, NULL, &dwValue, &dwSize) && dwValue)
  1519. {
  1520. *pdwDialInterval = dwValue;
  1521. }
  1522. DEBUG_LEAVE(TRUE);
  1523. return TRUE;
  1524. }
  1525. ///////////////////////////////////////////////////////////////////////////
  1526. ///////////////////////////////////////////////////////////////////////////
  1527. //
  1528. // Win9x security check
  1529. //
  1530. ///////////////////////////////////////////////////////////////////////////
  1531. ///////////////////////////////////////////////////////////////////////////
  1532. // stolen from ICW's wizglob.h -- BUGBUG - add to our tree
  1533. #define INSTANCE_PPPDRIVER 0x0002
  1534. typedef DWORD (WINAPI * ICFGISFILESHARINGTURNEDON ) (DWORD dwfDriverType, LPBOOL lpfSharingOn);
  1535. BOOL
  1536. IsSharingEnabled(
  1537. VOID
  1538. )
  1539. /*++
  1540. Routine Description:
  1541. Silently determine whether sharing is turned on on PPP devices on Win9x
  1542. Arguments:
  1543. none
  1544. Return Value:
  1545. BOOL
  1546. TRUE - sharing on
  1547. FALSE - sharing off (or NT)
  1548. --*/
  1549. {
  1550. DEBUG_ENTER((DBG_DIALUP,
  1551. Bool,
  1552. "IsSharingEnabled",
  1553. NULL
  1554. ));
  1555. ICFGISFILESHARINGTURNEDON lpIcfgIsFileSharingTurnedOn=NULL;
  1556. HINSTANCE hICFGInst = NULL;
  1557. BOOL fSharingIsOn = FALSE;
  1558. //
  1559. // Bail out on NT
  1560. //
  1561. if(PLATFORM_TYPE_WINNT == GlobalPlatformType)
  1562. {
  1563. DEBUG_LEAVE(FALSE);
  1564. return FALSE;
  1565. }
  1566. else
  1567. {
  1568. hICFGInst = LoadLibraryA("icfg95.dll");
  1569. }
  1570. //
  1571. // Try and get entry point in icfg95.dll to check
  1572. //
  1573. if(hICFGInst)
  1574. {
  1575. DWORD dwRet;
  1576. lpIcfgIsFileSharingTurnedOn = (ICFGISFILESHARINGTURNEDON)GetProcAddress( hICFGInst, "IcfgIsFileSharingTurnedOn");
  1577. if(lpIcfgIsFileSharingTurnedOn)
  1578. dwRet = lpIcfgIsFileSharingTurnedOn(INSTANCE_PPPDRIVER, &fSharingIsOn);
  1579. FreeLibrary(hICFGInst);
  1580. }
  1581. DEBUG_LEAVE(fSharingIsOn);
  1582. return fSharingIsOn;
  1583. }
  1584. DWORD
  1585. PerformSecurityCheck(
  1586. IN HWND hwndParent,
  1587. IN DWORD dwFlags
  1588. )
  1589. /*++
  1590. Routine Description:
  1591. Prompt user to fix sharing on PPP device on Win9x. Reboot if necessary.
  1592. Arguments:
  1593. hwndParent - parent window for any UI
  1594. dwFlags - flags possibly containing INTERNET_AUTODIAL_FAILIFSECURITYCHECK
  1595. Return Value:
  1596. BOOL
  1597. TRUE - failed test, may be rebooting
  1598. FALSE - passed test
  1599. --*/
  1600. {
  1601. DEBUG_ENTER((DBG_DIALUP,
  1602. Bool,
  1603. "PerformSecurityCheck",
  1604. "%#x, %#x",
  1605. hwndParent,
  1606. dwFlags
  1607. ));
  1608. static BOOL fDoneCheckOnce = FALSE;
  1609. BOOL fNeedRestart = FALSE;
  1610. HINSTANCE hinstInetWiz;
  1611. INETPERFORMSECURITYCHECK lpInetPerformSecurityCheck;
  1612. CHAR szFilename[SMALLBUFLEN+1]="";
  1613. // only do this once per session, never on NT
  1614. if(PLATFORM_TYPE_WINNT == GlobalPlatformType || fDoneCheckOnce)
  1615. {
  1616. DEBUG_LEAVE(FALSE);
  1617. return FALSE;
  1618. }
  1619. fDoneCheckOnce = TRUE;
  1620. if(dwFlags & (INTERNET_AUTODIAL_FAILIFSECURITYCHECK | INTERNET_DIAL_UNATTENDED | INTERNET_AUTODIAL_FORCE_UNATTENDED))
  1621. {
  1622. if(IsSharingEnabled())
  1623. {
  1624. // silent check failed
  1625. DEBUG_LEAVE(TRUE);
  1626. return TRUE;
  1627. }
  1628. }
  1629. // get filename out of resource
  1630. LoadString(GlobalDllHandle,IDS_INETCFG_FILENAME,szFilename,
  1631. sizeof(szFilename));
  1632. // load the inetcfg dll
  1633. hinstInetWiz = LoadLibrary(szFilename);
  1634. INET_ASSERT(hinstInetWiz);
  1635. if (hinstInetWiz) {
  1636. // get the proc address
  1637. lpInetPerformSecurityCheck = (INETPERFORMSECURITYCHECK)
  1638. GetProcAddress(hinstInetWiz,szInetPerformSecurityCheck);
  1639. INET_ASSERT(lpInetPerformSecurityCheck);
  1640. if (lpInetPerformSecurityCheck)
  1641. {
  1642. // call the function to do system security check
  1643. (lpInetPerformSecurityCheck) (hwndParent, &fNeedRestart);
  1644. }
  1645. FreeLibrary(hinstInetWiz);
  1646. if(fNeedRestart)
  1647. {
  1648. // call RestartDialog in shell32
  1649. HINSTANCE hShell = LoadLibrary("shell32.dll");
  1650. _RESTARTDIALOG pfnRestart = NULL;
  1651. if(hShell)
  1652. {
  1653. pfnRestart = (_RESTARTDIALOG)GetProcAddress(hShell, (LPTSTR)59);
  1654. if(pfnRestart)
  1655. (*pfnRestart)(NULL, NULL, EWX_REBOOT);
  1656. FreeLibrary(hShell);
  1657. }
  1658. }
  1659. }
  1660. DEBUG_LEAVE(fNeedRestart);
  1661. return fNeedRestart;
  1662. }
  1663. ///////////////////////////////////////////////////////////////////////////
  1664. ///////////////////////////////////////////////////////////////////////////
  1665. //
  1666. // Custom Dial Handler code
  1667. //
  1668. ///////////////////////////////////////////////////////////////////////////
  1669. ///////////////////////////////////////////////////////////////////////////
  1670. BOOL
  1671. IsCDH(
  1672. IN LPWSTR pszEntryName,
  1673. IN CDHINFO *pcdh
  1674. )
  1675. /*++
  1676. Routine Description:
  1677. Determine whether a connection uses a custom dial handler
  1678. Arguments:
  1679. pszEntryName - connection name
  1680. pcdh - pointer to structure to hold cdh info
  1681. Return Value:
  1682. BOOL
  1683. TRUE - connection uses custom dial handler
  1684. FALSE - doesn't
  1685. --*/
  1686. {
  1687. DEBUG_ENTER((DBG_DIALUP,
  1688. Bool,
  1689. "IsCDH",
  1690. "%#x (%Q), %#x",
  1691. pszEntryName,
  1692. pszEntryName,
  1693. pcdh
  1694. ));
  1695. //
  1696. // clear out cdhinfo
  1697. //
  1698. memset(pcdh, 0, sizeof(CDHINFO));
  1699. if(PLATFORM_TYPE_WIN95 == GlobalPlatformType)
  1700. {
  1701. //
  1702. // Check registry settings on Win9x
  1703. //
  1704. WCHAR szKey[MAX_PATH];
  1705. DWORD dwType;
  1706. DWORD cbDllName = sizeof(pcdh->pszDllName);
  1707. DWORD cbFcnName = sizeof(pcdh->pszFcnName);
  1708. wnsprintfW(szKey, MAX_PATH, L"%ws\\%ws", szRegPathRNAProfileW, pszEntryName);
  1709. if((ERROR_SUCCESS == SHGetValueW(HKEY_CURRENT_USER, szKey, szRegValAutodialDllNameW, &dwType, (LPBYTE) pcdh->pszDllName, &cbDllName)) &&
  1710. (ERROR_SUCCESS == SHGetValueW(HKEY_CURRENT_USER, szKey, szRegValAutodialFcnNameW, &dwType, (LPBYTE) pcdh->pszFcnName, &cbFcnName)))
  1711. {
  1712. // try to read flags - not critical if can't find it
  1713. DWORD cbFlags = sizeof(DWORD);
  1714. SHGetValueW(HKEY_CURRENT_USER, szKey, szRegValAutodialFlagsW, &dwType, (LPBYTE) &(pcdh->dwHandlerFlags), &cbFlags);
  1715. if(0 == cbFlags)
  1716. pcdh->dwHandlerFlags = 0;
  1717. // if we got dll / fcn, we have a handler
  1718. pcdh->fHasHandler = TRUE;
  1719. // ICW's isign32.dll registers itself as a CDH but does no useful work. Ignore it.
  1720. // Note this could distinguish isign32.dll a little better -- right now it will
  1721. // incorectly find "aolisign32.dll" if such a thing were to exist.
  1722. if( StrStrIW(pcdh->pszDllName, L"isign32.dll") &&
  1723. StrStrIW(pcdh->pszFcnName, L"AutodialLogon"))
  1724. {
  1725. // nuke it
  1726. memset(pcdh, 0, sizeof(CDHINFO));
  1727. }
  1728. }
  1729. }
  1730. else
  1731. {
  1732. //
  1733. // No such this as a "CDH" on Win2k as defined by this mechanism.
  1734. // On Win2K, there's a new field in the rasentry struct specifically
  1735. // for this. See the function DialIfWin2KCDH.
  1736. //
  1737. // Always return FALSE for CDH on Win2K.
  1738. //
  1739. if(FALSE == GlobalPlatformVersion5)
  1740. {
  1741. //
  1742. // NT4 - this is broken -- we look in the RASENTRY struct for autodial
  1743. // function and dll but these fields are intended for use by NT's
  1744. // autodial code, NOT IE's. Prototypes are different and we only
  1745. // get by by luck - if NT finds these entries, it tries to find an
  1746. // A or W version of the exported function. CM is the only guy that
  1747. // does this and they don't export decorated A or W versions. Since
  1748. // NT can't find the function, it ignores the entries.
  1749. //
  1750. // This problem disappears on NT5 -- CM has thier own connectoid
  1751. // type. (Custom dial handlers in general won't be supported)
  1752. //
  1753. RasEntryPropHelp *pRasProp = new RasEntryPropHelp;
  1754. if (pRasProp)
  1755. {
  1756. if((0 == pRasProp->GetError()) && (0 == pRasProp->GetW(pszEntryName)))
  1757. {
  1758. // got entry, if there is custom dial fields, copy them to our
  1759. // struct
  1760. if(pRasProp->GetAutodiallDllW() && pRasProp->GetAutodialFuncW())
  1761. {
  1762. StrCpyNW(pcdh->pszDllName, pRasProp->GetAutodiallDllW(), sizeof(pcdh->pszDllName));
  1763. StrCpyNW(pcdh->pszFcnName, pRasProp->GetAutodialFuncW(), sizeof(pcdh->pszFcnName));
  1764. pcdh->fHasHandler = TRUE;
  1765. }
  1766. }
  1767. delete pRasProp;
  1768. }
  1769. }
  1770. }
  1771. DEBUG_LEAVE(pcdh->fHasHandler);
  1772. return pcdh->fHasHandler;
  1773. }
  1774. BOOL
  1775. CallCDH(
  1776. IN HWND hwndParent,
  1777. IN LPWSTR pszEntryName,
  1778. IN CDHINFO *pcdh,
  1779. IN DWORD dwOperation,
  1780. OUT LPDWORD lpdwResult
  1781. )
  1782. /*++
  1783. Routine Description:
  1784. Call a custom dial handler to perform an operation
  1785. Arguments:
  1786. hwndParent - parent window for any ui
  1787. pszEntryName - connection name
  1788. pcdh - pointer to structure to hold cdh info
  1789. dwOperation - a CDH operation to perform, one of the
  1790. INTERNET_CUSTOMDIAL_* operations.
  1791. lpdwResult - result of CDH operation
  1792. ERROR_SUCCESS - operation completed
  1793. ERROR_ALREADY_EXISTS - connection already exists (CM only)
  1794. ERROR_USER_DISCONNECTION - user cancelled operation
  1795. ERROR_INVALID_PARAMETER - CDH failed to load or service request
  1796. Returns Value:
  1797. BOOL
  1798. TRUE - CDH handled operation
  1799. FALSE - didn't
  1800. --*/
  1801. {
  1802. DEBUG_ENTER((DBG_DIALUP,
  1803. Bool,
  1804. "CallCDH",
  1805. "%#x, %#x (%Q), %#x, %#x, %#x",
  1806. hwndParent,
  1807. pszEntryName,
  1808. pszEntryName,
  1809. pcdh,
  1810. dwOperation,
  1811. lpdwResult
  1812. ));
  1813. BOOL fRet = FALSE;
  1814. if(pcdh->fHasHandler)
  1815. {
  1816. // FIXME - verify handler supports requested operation by checking
  1817. // it's flags. Connection Manager has been known to assert if it's
  1818. // called to do something it doesn't understand.
  1819. HINSTANCE hinstDialerDll = LoadLibraryWrapW(pcdh->pszDllName);
  1820. if (hinstDialerDll)
  1821. {
  1822. PFN_DIAL_HANDLER lpInetDialHandler;
  1823. CHAR szFcnName[MAX_PATH + 1];
  1824. WideCharToMultiByte(CP_ACP, 0, pcdh->pszFcnName, -1, szFcnName, MAX_PATH, NULL, NULL);
  1825. lpInetDialHandler = (PFN_DIAL_HANDLER)GetProcAddress(hinstDialerDll, szFcnName);
  1826. if (lpInetDialHandler)
  1827. {
  1828. #ifdef _X86_
  1829. // IBM Global Network is busted in that it expects to be called
  1830. // as cdecl when all other CDHs are stdcall. To get around
  1831. // this bustitude somewhat, restore esp after the call to get
  1832. // our stack frame back to a point where we won't fault.
  1833. DWORD dwSavedEsp;
  1834. _asm { mov [dwSavedEsp], esp }
  1835. #endif
  1836. // Thunk entry name to ansi
  1837. CHAR szEntryName[RAS_MaxEntryName + 1];
  1838. WideCharToMultiByte(CP_ACP, 0, pszEntryName, -1, szEntryName, RAS_MaxEntryName, NULL, NULL);
  1839. fRet = (lpInetDialHandler)(hwndParent, szEntryName, dwOperation, lpdwResult);
  1840. #ifdef _X86_
  1841. _asm { mov esp, [dwSavedEsp] }
  1842. #endif
  1843. }
  1844. FreeLibrary(hinstDialerDll);
  1845. }
  1846. }
  1847. DEBUG_LEAVE(fRet);
  1848. return fRet;
  1849. }
  1850. ///////////////////////////////////////////////////////////////////////////
  1851. ///////////////////////////////////////////////////////////////////////////
  1852. //
  1853. // Initialization
  1854. //
  1855. ///////////////////////////////////////////////////////////////////////////
  1856. ///////////////////////////////////////////////////////////////////////////
  1857. VOID
  1858. InitAutodialModule(
  1859. BOOL fGlobalDataNeeded
  1860. )
  1861. /*++
  1862. Routine Description:
  1863. Initialize autodial code
  1864. Arguments:
  1865. None.
  1866. Return Value:
  1867. None.
  1868. --*/
  1869. {
  1870. DEBUG_ENTER((DBG_DIALUP,
  1871. None,
  1872. "InitAutodialModule",
  1873. "%B",
  1874. fGlobalDataNeeded
  1875. ));
  1876. // check for global data first - will only ever happen once
  1877. if(fGlobalDataNeeded && !GlobalDataInitialized)
  1878. {
  1879. GlobalDataInitialize();
  1880. }
  1881. // only do this once...
  1882. if(g_fAutodialInitialized)
  1883. {
  1884. DEBUG_LEAVE(0);
  1885. return;
  1886. }
  1887. // make sure internet settings key is open
  1888. EnsureInternetSettingsKeyCached();
  1889. // There is really no reason to acquire a crosprocess mutex
  1890. // We are going to creat a perprocess mutex when services are running. SPP
  1891. // wininet folks will explore whether this has to be expanded to include all processes
  1892. // (Shishir Pardikar)
  1893. if (FALSE == GlobalIsProcessNtService)
  1894. {
  1895. // create connection mutex
  1896. g_hConnectionMutex = OpenMutex(SYNCHRONIZE, FALSE, CONNECTION_MUTEX);
  1897. if (g_hConnectionMutex == NULL && (GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_NAME))
  1898. {
  1899. SECURITY_ATTRIBUTES* psa = SHGetAllAccessSA();
  1900. if (psa)
  1901. {
  1902. g_hConnectionMutex = CreateMutex(psa, FALSE, CONNECTION_MUTEX);
  1903. }
  1904. }
  1905. }
  1906. else
  1907. {
  1908. g_hConnectionMutex = CreateMutex(NULL, FALSE, NULL);
  1909. }
  1910. INET_ASSERT(g_hConnectionMutex != INVALID_HANDLE_VALUE);
  1911. // create dial mutex to serialize access to RAS (per process)
  1912. g_hRasMutex = CreateMutex(NULL, FALSE, NULL);
  1913. INET_ASSERT(g_hRasMutex != INVALID_HANDLE_VALUE);
  1914. // create proxy registry mutex to serialize access to registry settings across processes
  1915. g_hProxyRegMutex = OpenMutex(SYNCHRONIZE, FALSE, PROXY_REG_MUTEX);
  1916. if (g_hProxyRegMutex == NULL && (GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_NAME))
  1917. {
  1918. SECURITY_ATTRIBUTES* psa = SHGetAllAccessSA();
  1919. if (psa)
  1920. {
  1921. g_hProxyRegMutex = CreateMutex(psa, FALSE, PROXY_REG_MUTEX);
  1922. }
  1923. }
  1924. INET_ASSERT(g_hProxyRegMutex != INVALID_HANDLE_VALUE);
  1925. if(FALSE == IsAutodialEnabled(NULL, NULL)) {
  1926. // if autodial not enabled, then set the fDontProcessHook flag so we
  1927. // exit our hook proc very quickly and don't interfere with Winsock
  1928. fDontProcessHook = TRUE;
  1929. }
  1930. if(GetModuleHandle("rnaapp.exe"))
  1931. {
  1932. // We're in rnaapp! Bail all winsock callbacks
  1933. g_fRNAAppProcess = TRUE;
  1934. }
  1935. DEBUG_PRINT(DIALUP, INFO, ("g_fRNAAppProcess = %B\n", g_fRNAAppProcess));
  1936. g_fAutodialInitialized = TRUE;
  1937. DEBUG_LEAVE(0);
  1938. }
  1939. VOID
  1940. ExitAutodialModule(
  1941. VOID
  1942. )
  1943. /*++
  1944. Routine Description:
  1945. Clean up autodial code
  1946. Arguments:
  1947. None.
  1948. Return Value:
  1949. None.
  1950. --*/
  1951. {
  1952. DEBUG_ENTER((DBG_DIALUP,
  1953. None,
  1954. "ExitAutodialModule",
  1955. NULL
  1956. ));
  1957. // don't do anything if not initialized
  1958. if(FALSE == g_fAutodialInitialized)
  1959. {
  1960. DEBUG_LEAVE(0);
  1961. return;
  1962. }
  1963. #ifdef CHECK_SENS
  1964. if(g_hSens) {
  1965. FreeLibrary(g_hSens);
  1966. g_hSens = NULL;
  1967. g_pfnIsNetworkAlive = NULL;
  1968. }
  1969. #endif
  1970. // close connection mutex
  1971. if(INVALID_HANDLE_VALUE != g_hConnectionMutex)
  1972. {
  1973. CloseHandle(g_hConnectionMutex);
  1974. g_hConnectionMutex = INVALID_HANDLE_VALUE;
  1975. }
  1976. // close RAS mutex
  1977. if(INVALID_HANDLE_VALUE != g_hRasMutex)
  1978. {
  1979. CloseHandle(g_hRasMutex);
  1980. g_hRasMutex = INVALID_HANDLE_VALUE;
  1981. }
  1982. // close proxy registry mutex
  1983. if(INVALID_HANDLE_VALUE != g_hProxyRegMutex)
  1984. {
  1985. CloseHandle(g_hProxyRegMutex);
  1986. g_hProxyRegMutex = INVALID_HANDLE_VALUE;
  1987. }
  1988. // close user's reg key
  1989. CRefdKey* prk = (CRefdKey*)InterlockedExchangePointer((PVOID*)&g_prkBase, NULL);
  1990. CloseBaseProxyKey(prk);
  1991. if (g_hRasLib)
  1992. {
  1993. FreeLibrary(g_hRasLib);
  1994. g_hRasLib = NULL;
  1995. }
  1996. if(g_hIphlpapi)
  1997. {
  1998. FreeLibrary(g_hIphlpapi);
  1999. g_hIphlpapi = NULL;
  2000. g_pfnGetBestRoute = NULL;
  2001. }
  2002. g_fAutodialInitialized = FALSE;
  2003. DEBUG_LEAVE(0);
  2004. }
  2005. VOID
  2006. ResetAutodialModule(
  2007. VOID
  2008. )
  2009. /*++
  2010. Routine Description:
  2011. Reset certain state when a global reset is called. Causes settings
  2012. to be reread and some one-time operations to be redone.
  2013. Arguments:
  2014. None.
  2015. Return Value:
  2016. None.
  2017. --*/
  2018. {
  2019. DEBUG_ENTER((DBG_DIALUP,
  2020. None,
  2021. "ResetAutodialModule",
  2022. NULL
  2023. ));
  2024. // global settings have changed - reset hook to look again
  2025. fDontProcessHook = FALSE;
  2026. // refresh proxy info and next connection
  2027. g_fConnChecked = FALSE;
  2028. #ifdef CHECK_SENS
  2029. // refresh our sens state
  2030. g_fSensInstalled = TRUE;
  2031. #endif
  2032. // beta 1 hack
  2033. g_fCheckedUpgrade = FALSE;
  2034. // check security context again for HKCU settings
  2035. CRefdKey* prk = (CRefdKey*)InterlockedExchangePointer((PVOID*)&g_prkBase, NULL);
  2036. CloseBaseProxyKey(prk);
  2037. DEBUG_LEAVE(0);
  2038. }
  2039. ///////////////////////////////////////////////////////////////////////////
  2040. ///////////////////////////////////////////////////////////////////////////
  2041. //
  2042. // Connection management code
  2043. //
  2044. ///////////////////////////////////////////////////////////////////////////
  2045. ///////////////////////////////////////////////////////////////////////////
  2046. #ifdef CHECK_SENS
  2047. BOOL
  2048. GetSensLanState(
  2049. OUT LPDWORD pdwFlags
  2050. )
  2051. /*++
  2052. Routine Description:
  2053. Load and query sens to see if any packets have moved on the lan.
  2054. Beware of service not started and/or api dll not present.
  2055. Arguments:
  2056. None
  2057. Return Value:
  2058. BOOL
  2059. TRUE - Lan is active
  2060. FALSE - Lan is not active
  2061. --*/
  2062. {
  2063. DEBUG_ENTER((DBG_DIALUP,
  2064. Bool,
  2065. "GetSensLanState",
  2066. "%#x",
  2067. pdwFlags
  2068. ));
  2069. BOOL fConnected = TRUE;
  2070. // initialize out flags parameter to default - lan connectivity
  2071. *pdwFlags = NETWORK_ALIVE_LAN;
  2072. // If sens isn't around to ask, we have to assume the lan is connected
  2073. if(FALSE == g_fSensInstalled)
  2074. {
  2075. DEBUG_LEAVE(TRUE);
  2076. return TRUE;
  2077. }
  2078. //
  2079. // Try to load SENS and get our entry point
  2080. //
  2081. if(NULL == g_hSens) {
  2082. INT_PTR fSensRunning;
  2083. if(PLATFORM_TYPE_WINNT == GlobalPlatformType)
  2084. {
  2085. // check for running service on NT
  2086. fSensRunning = IsServiceRunning("Sens", SERVICE_ACTIVE);
  2087. }
  2088. else
  2089. {
  2090. // check for dialmon loaded bits on Win9x
  2091. //
  2092. // Webcheck creates this named event to track the lifetime of Sens.
  2093. // It's created with CreateEventA so we need to open with with
  2094. // OpenEventA.
  2095. //
  2096. HANDLE hEvent;
  2097. fSensRunning = FALSE;
  2098. hEvent = OpenEventA(SYNCHRONIZE, FALSE, "MS_WebcheckExternalsTerminateEvent");
  2099. if(hEvent)
  2100. {
  2101. fSensRunning = TRUE;
  2102. CloseHandle(hEvent);
  2103. }
  2104. }
  2105. // On win9x check with dialmon to see if sens is running before
  2106. // calling it. If we call it and it isn't loaded, it'll load itself
  2107. // and defeat the purpose of not loading it.
  2108. if(fSensRunning)
  2109. {
  2110. g_hSens = LoadLibrary("sensapi.dll");
  2111. if(g_hSens) {
  2112. g_pfnIsNetworkAlive = (ISNETWORKALIVE)GetProcAddress(g_hSens, "IsNetworkAlive");
  2113. }
  2114. }
  2115. }
  2116. //
  2117. // Call sens to get its state
  2118. //
  2119. if(g_pfnIsNetworkAlive) {
  2120. fConnected = g_pfnIsNetworkAlive(pdwFlags);
  2121. g_fSensInstalled = TRUE;
  2122. if(fConnected) {
  2123. if(ERROR_SUCCESS != GetLastError()) {
  2124. // sens service not running - must assume lan is available
  2125. g_fSensInstalled = FALSE;
  2126. }
  2127. if(0 == (*pdwFlags & (NETWORK_ALIVE_LAN | NETWORK_ALIVE_AOL)))
  2128. {
  2129. // no AOL or LAN flag, so return no lan connectivity
  2130. fConnected = FALSE;
  2131. }
  2132. }
  2133. }
  2134. DEBUG_PRINT(DIALUP, INFO, ("g_fSensInstalled = %B\n", g_fSensInstalled));
  2135. //
  2136. // If sens isn't alive but we managed to load the dll, unload it
  2137. // now as it's useless. Otherwise, hang on to the dll. No need to
  2138. // load and unload it all the time.
  2139. //
  2140. if(FALSE == g_fSensInstalled && g_hSens) {
  2141. FreeLibrary(g_hSens);
  2142. g_hSens = NULL;
  2143. g_pfnIsNetworkAlive = NULL;
  2144. }
  2145. DEBUG_LEAVE(fConnected);
  2146. return fConnected;
  2147. }
  2148. #endif // CHECK_SENS
  2149. BOOL
  2150. IsDialUpConnection(
  2151. IN BOOL fForceRefresh,
  2152. OUT LPDWORD lpdwConnectionNum
  2153. )
  2154. /*++
  2155. Routine Description:
  2156. Determines whether there's a dial-up connection. Refreshes information
  2157. periodically.
  2158. Arguments:
  2159. None
  2160. Return Value:
  2161. BOOL
  2162. TRUE - A dial-up connection exists
  2163. FALSE - No dial-up connection
  2164. --*/
  2165. {
  2166. DEBUG_ENTER((DBG_DIALUP,
  2167. Bool,
  2168. "IsDialUpConnection",
  2169. "%B, %x",
  2170. fForceRefresh,
  2171. lpdwConnectionNum
  2172. ));
  2173. static BOOL fRasLoaded = FALSE;
  2174. DWORD dwNewTickCount, dwElapsed, dwBytes, dwRes, dwConNum = 0;
  2175. BOOL fProcessedRecently = FALSE, fRet;
  2176. //
  2177. // Initialize out parameter
  2178. //
  2179. if(lpdwConnectionNum)
  2180. {
  2181. *lpdwConnectionNum = 0;
  2182. }
  2183. //
  2184. // serialize
  2185. //
  2186. WaitForSingleObject(g_hRasMutex, INFINITE);
  2187. //
  2188. // Check out how recently we polled ras
  2189. //
  2190. dwNewTickCount = GetTickCountWrap();
  2191. dwElapsed = dwNewTickCount - g_dwLastDialupTicks;
  2192. //
  2193. // Only refresh if more than MIN... ticks has passed
  2194. //
  2195. if((dwElapsed >= MIN_RNA_BUSY_CHECK_INTERVAL) || fForceRefresh) {
  2196. g_dwLastDialupTicks = dwNewTickCount;
  2197. if(DoConnectoidsExist())
  2198. {
  2199. if(FALSE == fRasLoaded)
  2200. fRasLoaded = EnsureRasLoaded();
  2201. if(fRasLoaded)
  2202. {
  2203. g_RasCon.Enum();
  2204. if(g_RasCon.GetError() == 0)
  2205. g_dwConnections = g_RasCon.GetConnectionsCount();
  2206. else
  2207. g_dwConnections = 0;
  2208. }
  2209. }
  2210. else
  2211. {
  2212. g_dwConnections = 0;
  2213. }
  2214. }
  2215. DEBUG_PRINT(DIALUP, INFO, ("Found %d connections\n", g_dwConnections));
  2216. if(g_dwConnections > 1 && lpdwConnectionNum)
  2217. {
  2218. //
  2219. // We have more than one connection and caller wants to know which one
  2220. // is the interesting one. Try to find a VPN connectoid.
  2221. //
  2222. // Note: RasGetEntryPropertiesA doesn't exist on Win95 Gold. However,
  2223. // you need RAS 1.2 (which has it) for the VPN device so we're ok
  2224. // using it. If we can't dynaload it for some inexplicable reason,
  2225. // we'll just end up not finding a VPN entry and setting proxy
  2226. // settings to the first connection.
  2227. //
  2228. // Note we use an array of 2 rasentry structures because NT wants to
  2229. // a phone number list after the actual struct and we need space for it.
  2230. // An extra RASENTRY struct is 1700+ bytes so it should be sufficient.
  2231. //
  2232. RasEntryPropHelp *pRasProp = new RasEntryPropHelp;
  2233. if (pRasProp)
  2234. {
  2235. for(dwConNum = 0; dwConNum < g_dwConnections; dwConNum++)
  2236. {
  2237. if(0 == pRasProp->GetW(g_RasCon.GetEntryW(dwConNum)))
  2238. {
  2239. if(0 == lstrcmpiA(pRasProp->GetDeviceTypeA(), RASDT_Vpn))
  2240. {
  2241. DEBUG_PRINT(DIALUP, INFO, ("Found VPN entry: %ws\n",
  2242. g_RasCon.GetEntryW(dwConNum)));
  2243. *lpdwConnectionNum = dwConNum;
  2244. break;
  2245. }
  2246. }
  2247. }
  2248. delete pRasProp;
  2249. }
  2250. }
  2251. fRet = (BOOL)(g_dwConnections != 0);
  2252. //
  2253. // verify status of connection we're interested in is RASCS_Connected.
  2254. //
  2255. if(fRet)
  2256. {
  2257. RasGetConnectStatusHelp RasGetConnectStatus(g_RasCon.GetHandle(dwConNum));
  2258. dwRes = RasGetConnectStatus.GetError();
  2259. if(dwRes || (RasGetConnectStatus.ConnState() != RASCS_Connected))
  2260. {
  2261. fRet = FALSE;
  2262. }
  2263. DEBUG_PRINT(DIALUP, INFO, ("Connect Status: dwRet=%x, connstate=%x\n", dwRes, RasGetConnectStatus.ConnState()));
  2264. }
  2265. ReleaseMutex(g_hRasMutex);
  2266. DEBUG_LEAVE(fRet);
  2267. return fRet;
  2268. }
  2269. BOOL
  2270. IsLanConnection(
  2271. OUT LPDWORD pdwFlags
  2272. )
  2273. /*++
  2274. Routine Description:
  2275. Determines whether there's a lan connection. Refreshes information
  2276. periodically.
  2277. When Sens is present, AOL functionality is retuned as TRUE with
  2278. *pdwFlags = NETWORK_ALIVE_AOL.
  2279. Arguments:
  2280. None
  2281. Return Value:
  2282. BOOL
  2283. TRUE - A lan connection exists
  2284. FALSE - No lan connection
  2285. --*/
  2286. {
  2287. DEBUG_ENTER((DBG_DIALUP,
  2288. Bool,
  2289. "IsLanConnection",
  2290. "%#x",
  2291. pdwFlags
  2292. ));
  2293. static DWORD dwLastSensTicks = 0;
  2294. static BOOL fSensState = TRUE;
  2295. static DWORD dwSensFlags = 0;
  2296. DWORD dwNewTickCount, dwElapsed;
  2297. BOOL fRet = TRUE;
  2298. // init out parameter
  2299. INET_ASSERT(pdwFlags);
  2300. *pdwFlags = 0;
  2301. #ifdef CHECK_SENS
  2302. //
  2303. // Check connectivity apis to see if lan is really present
  2304. //
  2305. if(fRet)
  2306. {
  2307. dwNewTickCount = GetTickCountWrap();
  2308. dwElapsed = dwNewTickCount - dwLastSensTicks;
  2309. if(dwElapsed >= MIN_SENS_CHECK_INTERVAL)
  2310. {
  2311. fSensState = GetSensLanState(&dwSensFlags);
  2312. dwLastSensTicks = dwNewTickCount;
  2313. }
  2314. fRet = fSensState;
  2315. *pdwFlags = dwSensFlags;
  2316. }
  2317. #endif
  2318. DEBUG_LEAVE(fRet);
  2319. return fRet;
  2320. }
  2321. VOID
  2322. CheckForUpgrade(
  2323. VOID
  2324. )
  2325. /*++
  2326. Routine Description:
  2327. Performs processing that needs to happen when we upgrade to IE5.
  2328. - Migrate proxy and dial settings on upgrade
  2329. - Migrate legacy proxy settings when they change
  2330. Arguments:
  2331. None
  2332. Return Value:
  2333. --*/
  2334. {
  2335. DEBUG_ENTER((DBG_DIALUP,
  2336. None,
  2337. "CheckForUpgrade",
  2338. NULL
  2339. ));
  2340. DWORD dwMigrateState = 1, dwRet, dwEntries = 0;
  2341. char szUserName[10];
  2342. DWORD cbUserNameSize = ARRAYSIZE(szUserName);
  2343. CRefdKey* prkBase = FindBaseProxyKey();
  2344. //
  2345. // Bail out right away if we've already done this
  2346. // Or if we are running in an NT service such as the usermode portion of webdav redir
  2347. // in order to avoid deadlocks
  2348. // Also check to make sure we're not running as .default or SYSTEM
  2349. if(prkBase &&
  2350. (FALSE == g_fCheckedUpgrade) &&
  2351. (FALSE == GlobalIsProcessNtService) &&
  2352. !IsInGUIModeSetup() &&
  2353. !(GlobalPlatformWhistler &&
  2354. GlobalUserName.Get(szUserName,&cbUserNameSize) &&
  2355. (0 == lstrcmpi(szUserName, ".Default") ||
  2356. 0 == lstrcmpi(szUserName, "SYSTEM"))))
  2357. {
  2358. LONG lResult;
  2359. DWORD dwType, dwExclude, dwSize = sizeof(DWORD), dwDisp;
  2360. RasEnumHelp *pRasEnum = NULL;
  2361. //
  2362. // Check to see if proxy settings have been migrated
  2363. //
  2364. if(ERROR_SUCCESS != SHGetValue(prkBase->GetKey(),
  2365. REGSTR_PATH_INTERNET_SETTINGS, szMigrateProxy, &dwType, &dwMigrateState, &dwSize))
  2366. {
  2367. dwMigrateState = 0;
  2368. }
  2369. DEBUG_PRINT(DIALUP, INFO, ("dwMigrateState=%d\n", dwMigrateState));
  2370. //
  2371. // set up list of connectoids
  2372. //
  2373. if(DoConnectoidsExist() && EnsureRasLoaded() && FALSE == GlobalDisableNT4RasCheck)
  2374. {
  2375. pRasEnum = new RasEnumHelp;
  2376. if(pRasEnum != NULL)
  2377. {
  2378. dwRet = pRasEnum->GetError();
  2379. dwEntries = pRasEnum->GetEntryCount();
  2380. }
  2381. }
  2382. //
  2383. // Migrate legacy proxy settings to all connections
  2384. //
  2385. if(0 == dwMigrateState)
  2386. {
  2387. INTERNET_PROXY_INFO_EX info;
  2388. // start off with clean proxy struct
  2389. memset(&info, 0, sizeof(info));
  2390. info.dwStructSize = sizeof(INTERNET_PROXY_INFO_EX);
  2391. // need to migrate settings
  2392. if(ReadLegacyProxyInfo(szRegPathInternetSettings, &info))
  2393. {
  2394. #ifndef UNIX
  2395. // make sure autodiscovery is on
  2396. info.dwFlags |= PROXY_TYPE_AUTO_DETECT;
  2397. #endif /* !UNIX */
  2398. // Save proxy settings to for lan
  2399. info.lpszConnectionName = NULL;
  2400. WriteProxySettings(&info, TRUE);
  2401. // Save legacy settings to special location so we can check
  2402. // for change later
  2403. info.lpszConnectionName = LEGACY_SAVE_NAME;
  2404. WriteProxySettings(&info, TRUE);
  2405. //
  2406. // If we're not turning on autodiscovery for dialup connections
  2407. // by default, get rid of it at this point
  2408. //
  2409. if(FALSE == EnableAutodiscoverForDialup())
  2410. {
  2411. info.dwFlags &= ~PROXY_TYPE_AUTO_DETECT;
  2412. }
  2413. // Save settings for each connectoid
  2414. DWORD i;
  2415. for(i=0; i<dwEntries; i++)
  2416. {
  2417. info.lpszConnectionName = pRasEnum->GetEntryA(i);
  2418. WriteProxySettings(&info, TRUE);
  2419. }
  2420. // clean memory possibly allocated by ReadLegacyProxyInfo
  2421. info.lpszConnectionName = NULL; // not allocated, don't free
  2422. CleanProxyStruct(&info);
  2423. }
  2424. }
  2425. //
  2426. // Check to see if other dial-up settings have been migrated
  2427. //
  2428. if(0 == dwMigrateState && dwEntries)
  2429. {
  2430. CHAR szKey[MAX_PATH];
  2431. DWORD dwMinutes, dwAttempts, dwInterval, dwWait, i;
  2432. DWORD dwEnable;
  2433. // read dial attempts and wait
  2434. if(InternetReadRegistryDword(REGSTR_VAL_REDIALATTEMPTS, &dwAttempts))
  2435. dwAttempts = DEFAULT_DIAL_ATTEMPTS;
  2436. if(InternetReadRegistryDword(REGSTR_VAL_REDIALINTERVAL, &dwInterval))
  2437. dwInterval = DEFAULT_DIAL_INTERVAL;
  2438. // Get idle enable
  2439. if(InternetReadRegistryDword(REGSTR_VAL_ENABLEAUTODISCONNECT, &dwEnable) ||
  2440. 0 == dwEnable)
  2441. {
  2442. dwEnable = 0;
  2443. dwMinutes = 20;
  2444. }
  2445. // if enabled, get minutes
  2446. if(dwEnable &&
  2447. InternetReadRegistryDword(REGSTR_VAL_DISCONNECTIDLETIME, &dwMinutes))
  2448. {
  2449. dwEnable = 0;
  2450. dwMinutes = 20;
  2451. }
  2452. // enumerate ras entries
  2453. for(i=0; i<dwEntries; i++)
  2454. {
  2455. DWORD dwDisposition;
  2456. HKEY hkey;
  2457. long lRes;
  2458. // migrate settings for this connectoid
  2459. GetConnKeyA(pRasEnum->GetEntryA(i), szKey, ARRAYSIZE(szKey));
  2460. SHSetValueA(HKEY_CURRENT_USER, szKey, REGSTR_VAL_ENABLEAUTODISCONNECT, REG_DWORD, (BYTE *)&dwEnable, sizeof(DWORD));
  2461. SHSetValueA(HKEY_CURRENT_USER, szKey, REGSTR_VAL_DISCONNECTIDLETIME, REG_DWORD, (BYTE *)&dwMinutes, sizeof(DWORD));
  2462. SHSetValueA(HKEY_CURRENT_USER, szKey, REGSTR_VAL_ENABLEEXITDISCONNECT, REG_DWORD, (BYTE *)&dwEnable, sizeof(DWORD));
  2463. SHSetValueA(HKEY_CURRENT_USER, szKey, REGSTR_VAL_REDIALATTEMPTS, REG_DWORD, (BYTE *)&dwAttempts, sizeof(DWORD));
  2464. SHSetValueA(HKEY_CURRENT_USER, szKey, REGSTR_VAL_REDIALINTERVAL, REG_DWORD, (BYTE *)&dwInterval, sizeof(DWORD));
  2465. }
  2466. }
  2467. if(pRasEnum)
  2468. delete pRasEnum;
  2469. //
  2470. // mark setings as migrated so we don't do this again next time
  2471. //
  2472. dwDisp = 1;
  2473. SHSetValueA(prkBase->GetKey(), REGSTR_PATH_INTERNET_SETTINGS,
  2474. szMigrateProxy, REG_DWORD, &dwDisp, sizeof(DWORD));
  2475. if(dwMigrateState)
  2476. {
  2477. // We have already migrated settings. If legacy settings have
  2478. // changed, update current connection.
  2479. INTERNET_PROXY_INFO_EX saved, current, destination;
  2480. memset(&saved, 0, sizeof(saved));
  2481. saved.dwStructSize = sizeof(INTERNET_PROXY_INFO_EX);
  2482. saved.lpszConnectionName = LEGACY_SAVE_NAME;
  2483. memset(&current, 0, sizeof(current));
  2484. current.dwStructSize = sizeof(INTERNET_PROXY_INFO_EX);
  2485. memset(&destination, 0, sizeof(destination));
  2486. destination.dwStructSize = sizeof(INTERNET_PROXY_INFO_EX);
  2487. if( ReadLegacyProxyInfo(szRegPathInternetSettings, &current) &&
  2488. ERROR_SUCCESS == ReadProxySettings(&saved))
  2489. {
  2490. BOOL fChanged = FALSE;
  2491. //
  2492. // see if they've changed
  2493. //
  2494. if((saved.dwFlags & LEGACY_MIGRATE_FLAGS) != (current.dwFlags & LEGACY_MIGRATE_FLAGS))
  2495. {
  2496. fChanged = TRUE;
  2497. }
  2498. else
  2499. {
  2500. // Only check for autoconfig url match if setting is the same and on because
  2501. // legacy saved for no autoconfig url is to delete the url.
  2502. if((saved.dwFlags & PROXY_TYPE_AUTO_PROXY_URL) &&
  2503. (FALSE == IsConnectionMatch(saved.lpszAutoconfigUrl, current.lpszAutoconfigUrl)))
  2504. {
  2505. fChanged = TRUE;
  2506. }
  2507. }
  2508. if(FALSE == IsConnectionMatch(saved.lpszProxy, current.lpszProxy))
  2509. {
  2510. fChanged = TRUE;
  2511. }
  2512. if(FALSE == IsConnectionMatch(saved.lpszProxyBypass, current.lpszProxyBypass))
  2513. {
  2514. fChanged = TRUE;
  2515. }
  2516. // if they have, save to current connection
  2517. if(fChanged)
  2518. {
  2519. DWORD dwIndex;
  2520. LPCSTR lpszTemp;
  2521. // save new legacy settings to check again later
  2522. current.lpszConnectionName = LEGACY_SAVE_NAME;
  2523. WriteProxySettings(&current, TRUE);
  2524. // read existing lan settings
  2525. destination.lpszConnectionName = NULL;
  2526. ReadProxySettings(&destination);
  2527. // fix flags
  2528. destination.dwFlags = (destination.dwFlags & ~LEGACY_MIGRATE_FLAGS) | (current.dwFlags & LEGACY_MIGRATE_FLAGS);
  2529. // fix proxy server / override
  2530. lpszTemp = destination.lpszProxy;
  2531. destination.lpszProxy = current.lpszProxy;
  2532. current.lpszProxy = lpszTemp;
  2533. lpszTemp = destination.lpszProxyBypass;
  2534. destination.lpszProxyBypass = current.lpszProxyBypass;
  2535. current.lpszProxyBypass = lpszTemp;
  2536. // fix autoconfig url
  2537. lpszTemp = destination.lpszAutoconfigUrl;
  2538. destination.lpszAutoconfigUrl = current.lpszAutoconfigUrl;
  2539. current.lpszAutoconfigUrl = lpszTemp;
  2540. // save it
  2541. WriteProxySettings(&destination, TRUE);
  2542. }
  2543. }
  2544. saved.lpszConnectionName = NULL;
  2545. current.lpszConnectionName = NULL;
  2546. destination.lpszConnectionName = NULL;
  2547. CleanProxyStruct(&saved);
  2548. CleanProxyStruct(&current);
  2549. CleanProxyStruct(&destination);
  2550. }
  2551. // don't run this code again
  2552. g_fCheckedUpgrade = TRUE;
  2553. }
  2554. CloseBaseProxyKey(prkBase);
  2555. DEBUG_LEAVE(0);
  2556. }
  2557. DWORD
  2558. FixProxySettings(
  2559. IN LPWSTR pszConnW,
  2560. IN BOOL fForceUpdate,
  2561. IN DWORD dwLanFlags
  2562. )
  2563. /*++
  2564. Routine Description:
  2565. Copy lan or dial-up proxy settings to generic key and tell proxy code
  2566. new proxy information
  2567. Arguments:
  2568. pszConn - connection name to switch to
  2569. fForceUpdate - set regardless of having set before
  2570. dwLanFlags - distinguish between LAN and AOL connection
  2571. Return Value:
  2572. DWORD
  2573. 0 - no proxy for this connection
  2574. 1 - proxy exists for this connection
  2575. --*/
  2576. {
  2577. DEBUG_ENTER((DBG_DIALUP,
  2578. Int,
  2579. "FixProxySettings",
  2580. "%#x (%Q), %B, %#x",
  2581. pszConnW,
  2582. pszConnW,
  2583. fForceUpdate,
  2584. dwLanFlags
  2585. ));
  2586. static TCHAR pszLastConn[RAS_MaxEntryName+1];
  2587. static DWORD dwEnable = 0;
  2588. CHAR szConn[RAS_MaxEntryName + 1];
  2589. LPSTR pszConn = NULL;
  2590. if(pszConnW != NULL)
  2591. {
  2592. *szConn = '\0';
  2593. pszConn = szConn;
  2594. WideCharToMultiByte(CP_ACP, 0, pszConnW, -1, pszConn, RAS_MaxEntryName, NULL, NULL);
  2595. }
  2596. //
  2597. // Make sure we've listened to any global settings changed that happened
  2598. // in other processes
  2599. //
  2600. if (InternetSettingsChanged()) {
  2601. ChangeGlobalSettings();
  2602. }
  2603. //
  2604. // Ensure upgrade stuff is done
  2605. //
  2606. CheckForUpgrade();
  2607. //
  2608. // Is this connection already fixed?
  2609. //
  2610. if(g_fConnChecked && (FALSE == fForceUpdate)) {
  2611. if((NULL == pszConn && 0 == *pszLastConn) ||
  2612. 0 == lstrcmp(pszConn, pszLastConn)) {
  2613. // already fixed this connection
  2614. DEBUG_LEAVE(dwEnable);
  2615. return dwEnable;
  2616. }
  2617. }
  2618. //
  2619. // Get proxy struct for proxy object
  2620. //
  2621. INTERNET_PROXY_INFO_EX info;
  2622. memset(&info, 0, sizeof(info));
  2623. info.dwStructSize = sizeof(info);
  2624. info.lpszConnectionName = pszConn;
  2625. //
  2626. // Read proxy settings for this connection unless it's LAN/AOL
  2627. // in which case we want no proxy
  2628. //
  2629. if(pszConn || 0 == (dwLanFlags & NETWORK_ALIVE_AOL))
  2630. {
  2631. if (ReadProxySettings(&info) != ERROR_SUCCESS)
  2632. {
  2633. DEBUG_LEAVE(dwEnable);
  2634. return dwEnable;
  2635. }
  2636. }
  2637. //
  2638. // Save connection we fixed
  2639. //
  2640. if(NULL == pszConn) {
  2641. // lan
  2642. *pszLastConn = 0;
  2643. } else {
  2644. // connectoid
  2645. lstrcpyn(pszLastConn, pszConn, RAS_MaxEntryName + 1);
  2646. }
  2647. // tell caller if proxy is enabled
  2648. if(info.dwFlags & PROXY_TYPE_PROXY)
  2649. {
  2650. dwEnable = 1;
  2651. }
  2652. else
  2653. {
  2654. dwEnable = 0;
  2655. }
  2656. GlobalProxyInfo.SetProxySettings(&info, FALSE);
  2657. //GlobalProxyInfo.RefreshProxySettings(FALSE);
  2658. //
  2659. // Copy current settings to the legacy reg locations so legacy
  2660. // apps can find them.
  2661. //
  2662. info.lpszConnectionName = LEGACY_SAVE_NAME;
  2663. WriteLegacyProxyInfo(szRegPathInternetSettings, &info, TRUE);
  2664. WriteProxySettings(&info, TRUE);
  2665. // free up memory allocated by ReadProxySettings
  2666. info.lpszConnectionName = NULL; // not allocated, don't free
  2667. CleanProxyStruct(&info);
  2668. //
  2669. // Flag we've checked this at least once so in future we can bail out early
  2670. //
  2671. g_fConnChecked = TRUE;
  2672. DEBUG_LEAVE(dwEnable);
  2673. return dwEnable;
  2674. }
  2675. BOOL
  2676. FixProxySettingsForCurrentConnection(
  2677. IN BOOL fForceUpdate
  2678. )
  2679. /*++
  2680. Routine Description:
  2681. Figure out the current connection and fix proxy settings for it.
  2682. Basically a cheap, return-no-info version of GetConnectedStateEx used
  2683. by the winsock callback.
  2684. Arguments:
  2685. none
  2686. Return Value:
  2687. BOOL
  2688. TRUE - connected
  2689. FALSE - not connected
  2690. --*/
  2691. {
  2692. DEBUG_ENTER((DBG_DIALUP,
  2693. Bool,
  2694. "FixProxySettingsForCurrentConnection",
  2695. "%B",
  2696. fForceUpdate
  2697. ));
  2698. BOOL fRet, fForceDial;
  2699. DWORD dwFixEntry;
  2700. //
  2701. // Make sure everything's initialized
  2702. //
  2703. InitAutodialModule(TRUE);
  2704. // serialize connection type stuff
  2705. WaitForSingleObject(g_hConnectionMutex, INFINITE);
  2706. //
  2707. // Check to see if we have a dialup connection
  2708. //
  2709. fRet = IsDialUpConnection(FALSE, &dwFixEntry);
  2710. if(fRet)
  2711. {
  2712. FixProxySettings(g_RasCon.GetEntryW(dwFixEntry), fForceUpdate, 0);
  2713. }
  2714. //
  2715. // If dial always isn't set, check lan setting
  2716. //
  2717. IsAutodialEnabled(&fForceDial, NULL);
  2718. if(FALSE == fRet && FALSE == fForceDial)
  2719. {
  2720. //
  2721. // no ras connections - ensure LAN proxy settings are correct
  2722. //
  2723. DWORD dwFlags;
  2724. fRet = IsLanConnection(&dwFlags);
  2725. //
  2726. // Whether we have a lan connection or not, prop lan proxy settings.
  2727. // This allows unknown connections to use lan settings.
  2728. //
  2729. FixProxySettings(NULL, fForceUpdate, dwFlags);
  2730. }
  2731. ReleaseMutex(g_hConnectionMutex);
  2732. DEBUG_LEAVE(fRet);
  2733. return fRet;
  2734. }
  2735. ///////////////////////////////////////////////////////////////////////////
  2736. ///////////////////////////////////////////////////////////////////////////
  2737. //
  2738. // Win2K Helper Functions
  2739. //
  2740. ///////////////////////////////////////////////////////////////////////////
  2741. ///////////////////////////////////////////////////////////////////////////
  2742. BOOL
  2743. DialIfWin2KCDH(
  2744. IN LPWSTR pszEntry,
  2745. IN HWND hwndParent,
  2746. IN BOOL fHideParent,
  2747. OUT DWORD *lpdwResult,
  2748. OUT DWORD_PTR *lpdwConnection
  2749. )
  2750. /*++
  2751. Routine Description:
  2752. Check a connectoid to see if it has a Win2K custom dial handler and if
  2753. so, do the voodoo magic to dial it
  2754. Arguments:
  2755. lpParams - dial params
  2756. hwndParent - parent window
  2757. fHideParent - if true, hide this window if dialing this connectoid
  2758. lpdwResult - result of dial (set if return is TRUE)
  2759. Return Value:
  2760. BOOL
  2761. TRUE - Attempted to dial Win2K CDH
  2762. FALSE - didn't
  2763. --*/
  2764. {
  2765. DEBUG_ENTER((DBG_DIALUP,
  2766. Bool,
  2767. "DialIfWin2KCDH",
  2768. "%x (%Q), %x, %B, %x, %x",
  2769. pszEntry,
  2770. pszEntry,
  2771. hwndParent,
  2772. fHideParent,
  2773. lpdwResult,
  2774. lpdwConnection
  2775. ));
  2776. DWORD dwRet;
  2777. RasEntryPropHelp *pRasProp = new RasEntryPropHelp;
  2778. BOOL fResult = FALSE;
  2779. if (pRasProp == NULL)
  2780. {
  2781. goto Cleanup;
  2782. }
  2783. if(FALSE == GlobalPlatformVersion5)
  2784. {
  2785. // not on win2k, bag
  2786. goto Cleanup;
  2787. }
  2788. // get props for this connectoid and see if it has a custom dial dll
  2789. if(ERROR_SUCCESS != (dwRet = pRasProp->GetW(pszEntry)))
  2790. {
  2791. // error getting rasentry struct
  2792. goto Cleanup;
  2793. }
  2794. if(NULL == pRasProp->GetCustomDialDllW())
  2795. {
  2796. // no custom dial dll
  2797. goto Cleanup;
  2798. }
  2799. // hide parent window if necessary
  2800. if(fHideParent)
  2801. {
  2802. ShowWindow(hwndParent, SW_HIDE);
  2803. }
  2804. // call rasdialdlg to dial the custom dude
  2805. HMODULE hLib;
  2806. RASDIALDLG rdd;
  2807. _RASDIALDLGW pfnRdd;
  2808. hLib = LoadLibrary("rasdlg.dll");
  2809. if(hLib)
  2810. {
  2811. pfnRdd = (_RASDIALDLGW)GetProcAddress(hLib, "RasDialDlgW");
  2812. if(pfnRdd)
  2813. {
  2814. memset(&rdd, 0, sizeof(rdd));
  2815. rdd.dwSize = sizeof(RASDIALDLG);
  2816. rdd.hwndOwner = hwndParent;
  2817. dwRet = (*pfnRdd)(NULL, pszEntry, NULL, &rdd);
  2818. }
  2819. FreeLibrary(hLib);
  2820. }
  2821. else
  2822. {
  2823. // really bad...
  2824. goto Cleanup;
  2825. }
  2826. // figure out how we did
  2827. if(dwRet)
  2828. {
  2829. DWORD dwEntry;
  2830. // success
  2831. *lpdwResult = ERROR_SUCCESS;
  2832. // find hconn for the thing we just dialed
  2833. if(lpdwConnection)
  2834. {
  2835. if(IsDialUpConnection(TRUE, &dwEntry))
  2836. {
  2837. *lpdwConnection = (DWORD_PTR) g_RasCon.GetHandle(dwEntry);
  2838. }
  2839. }
  2840. }
  2841. else
  2842. {
  2843. // error or cancel
  2844. *lpdwResult = ERROR_USER_DISCONNECTION;
  2845. if(rdd.dwError)
  2846. {
  2847. *lpdwResult = rdd.dwError;
  2848. }
  2849. }
  2850. fResult = TRUE;
  2851. Cleanup:
  2852. if (pRasProp)
  2853. {
  2854. delete pRasProp;
  2855. }
  2856. DEBUG_LEAVE(fResult);
  2857. return fResult;
  2858. }
  2859. ///////////////////////////////////////////////////////////////////////////
  2860. ///////////////////////////////////////////////////////////////////////////
  2861. //
  2862. // Winsock callback handler
  2863. //
  2864. ///////////////////////////////////////////////////////////////////////////
  2865. ///////////////////////////////////////////////////////////////////////////
  2866. DWORD
  2867. CheckForNoNetOverride(
  2868. LPSTR pszHostName
  2869. )
  2870. {
  2871. DEBUG_ENTER((DBG_DIALUP,
  2872. Bool,
  2873. "CheckForNoNetOverride",
  2874. "%#x (%q)",
  2875. pszHostName,
  2876. pszHostName
  2877. ));
  2878. DWORD dwAutodialFlags = 0;
  2879. DWORD dwFlags;
  2880. if(IsOS(OS_WHISTLERORGREATER) && IsLanConnection(&dwFlags) && ERROR_SUCCESS == LoadWinsock())
  2881. {
  2882. DWORD dwIpAddress;
  2883. DWORD dwError;
  2884. // assume no route and we want to override
  2885. dwAutodialFlags = INTERNET_AUTODIAL_OVERRIDE_NET_PRESENT;
  2886. // First check to see if we have an ip address.
  2887. ADDRINFO Hints;
  2888. LPADDRINFO lpAddrInfo;
  2889. memset(&Hints, 0, sizeof(struct addrinfo));
  2890. Hints.ai_flags = AI_NUMERICHOST; // Only check for address literals.
  2891. Hints.ai_family = PF_UNSPEC; // Accept any protocol family.
  2892. Hints.ai_socktype = SOCK_STREAM; // Constrain results to stream socket.
  2893. Hints.ai_protocol = IPPROTO_TCP; // Constrain results to TCP.
  2894. dwError = _I_getaddrinfo(pszHostName, NULL, &Hints, &lpAddrInfo);
  2895. if(ERROR_SUCCESS != dwError)
  2896. {
  2897. // not an ip address, try to resolve name
  2898. Hints.ai_flags = AI_CANONNAME;
  2899. dwError = _I_getaddrinfo(pszHostName, NULL, &Hints, &lpAddrInfo);
  2900. }
  2901. //
  2902. // If we got an IP4 address, check to see if we have a route for it
  2903. //
  2904. if(ERROR_SUCCESS == dwError && (AF_INET == lpAddrInfo->ai_family))
  2905. {
  2906. MIB_IPFORWARDROW bestRoute;
  2907. DWORD dwError = 0;
  2908. if(NULL == g_hIphlpapi)
  2909. {
  2910. g_hIphlpapi = LoadLibrary("iphlpapi.dll");
  2911. if(g_hIphlpapi)
  2912. {
  2913. g_pfnGetBestRoute = (GETBESTROUTE)GetProcAddress(g_hIphlpapi, "GetBestRoute");
  2914. }
  2915. }
  2916. // snag ip address from lpaddr
  2917. SOCKADDR_IN *paddr = (SOCKADDR_IN *)(lpAddrInfo->ai_addr);
  2918. dwIpAddress = *((unsigned long *)(&paddr->sin_addr));
  2919. if(g_pfnGetBestRoute && (ERROR_SUCCESS == g_pfnGetBestRoute(dwIpAddress, 0, &bestRoute)))
  2920. {
  2921. // got a route, no need to override dial semantics
  2922. DEBUG_PRINT(DIALUP, INFO, ("Found a route to %s, no need to override dial\n", pszHostName));
  2923. dwAutodialFlags = 0;
  2924. }
  2925. }
  2926. UnloadWinsock();
  2927. }
  2928. DEBUG_LEAVE(dwAutodialFlags);
  2929. return dwAutodialFlags;
  2930. }
  2931. BOOL
  2932. InternetAutodialIfNotLocalHost(
  2933. IN LPSTR OPTIONAL pszURL,
  2934. IN LPSTR OPTIONAL pszHostName
  2935. )
  2936. /*++
  2937. Routine Description:
  2938. Dial so long as we're configured for it and the name passed isn't a
  2939. local host alias.
  2940. Finds:
  2941. 'localhost'
  2942. '127.0.0.1' and its aliases
  2943. local machine name from registry or winsock
  2944. If a URL is specified, it's cracked to get the host name.
  2945. Arguments:
  2946. pszURL - url to check for
  2947. pszHostName - hostname to check for
  2948. Return Value:
  2949. None.
  2950. --*/
  2951. {
  2952. DEBUG_ENTER((DBG_DIALUP,
  2953. Bool,
  2954. "InternetAutodialIfNotLocalHost",
  2955. "%#x (%q), %#x (%q)",
  2956. pszURL,
  2957. pszURL,
  2958. pszHostName,
  2959. pszHostName
  2960. ));
  2961. CHAR *pszURLCopy = NULL, *pszLocalHostname;
  2962. BOOL fLocalHost = FALSE;
  2963. BOOL fAllocatedBuffer = FALSE;
  2964. BOOL fRet = TRUE;
  2965. BOOL fNeedToFix = TRUE;
  2966. DWORD dwAutodialFlags = 0;
  2967. //
  2968. // Make sure we're all initialized
  2969. //
  2970. InitAutodialModule(TRUE);
  2971. // we bypass this activity in an NT service has disabled autodialing. This special cases
  2972. // this behaviour for the webdav redir.
  2973. // In future wininet folks will look to see whether this shouldn't be done for all
  2974. // apps disabling autodialing. For now we just avoid the testing hit for the
  2975. // browser folks (Shishir Pardikar)
  2976. if((FALSE == fDontProcessHook) && !(GlobalIsProcessNtService && !IsAutodialEnabled(NULL, NULL)))
  2977. {
  2978. //
  2979. // If we were passed a URL, crack it to get host name
  2980. //
  2981. if(NULL == pszHostName && pszURL)
  2982. {
  2983. DWORD dwHostNameLength;
  2984. long error;
  2985. // make a copy of url to crack
  2986. pszURLCopy = new (CHAR[INTERNET_MAX_URL_LENGTH+1]);
  2987. if(NULL == pszURLCopy)
  2988. {
  2989. goto quit;
  2990. }
  2991. fAllocatedBuffer = TRUE;
  2992. lstrcpyn(pszURLCopy, pszURL, INTERNET_MAX_URL_LENGTH);
  2993. // crack it
  2994. error = CrackUrl(pszURLCopy,
  2995. 0,
  2996. FALSE, // don't escape URL-path
  2997. NULL, // don't care about scheme
  2998. NULL, // don't care about Scheme Name
  2999. NULL,
  3000. &pszHostName,
  3001. &dwHostNameLength,
  3002. NULL, // don't care about port
  3003. NULL, // don't care about user name
  3004. NULL,
  3005. NULL, // or password
  3006. NULL,
  3007. NULL, // or object
  3008. NULL,
  3009. NULL, // no extra
  3010. NULL,
  3011. NULL
  3012. );
  3013. if ((error != ERROR_SUCCESS) || (pszHostName == NULL))
  3014. {
  3015. goto quit;
  3016. }
  3017. // null-terminate host name (stomps pszURLCopy buffer)
  3018. pszHostName[dwHostNameLength] = 0;
  3019. }
  3020. //
  3021. // We'd better have a host name by now...
  3022. //
  3023. INET_ASSERT(pszHostName);
  3024. if(NULL == pszHostName)
  3025. {
  3026. goto quit;
  3027. }
  3028. //
  3029. // Check for 'localhost'
  3030. //
  3031. if( 0 == lstrcmpi(pszHostName, "localhost"))
  3032. {
  3033. DEBUG_PRINT(DIALUP, INFO, ("Found localhost\n"));
  3034. fLocalHost = TRUE;
  3035. goto quit;
  3036. }
  3037. //
  3038. // check for 127.0.0.1 or its variants -- use inet_addr if winsock loaded
  3039. //
  3040. if(g_fWinsockLoaded || _I_inet_addr)
  3041. {
  3042. if(ERROR_SUCCESS == LoadWinsock())
  3043. {
  3044. if(0x0100007f == _I_inet_addr(pszHostName))
  3045. {
  3046. fLocalHost = TRUE;
  3047. }
  3048. UnloadWinsock();
  3049. }
  3050. }
  3051. else
  3052. {
  3053. // winsock not loaded, do the best we can
  3054. if(0 == lstrcmpi(pszHostName, "127.0.0.1"))
  3055. {
  3056. fLocalHost = TRUE;
  3057. }
  3058. }
  3059. if(fLocalHost)
  3060. {
  3061. DEBUG_PRINT(DIALUP, INFO, ("Found 127.0.0.1 alias\n"));
  3062. goto quit;
  3063. }
  3064. //
  3065. // check local machine name
  3066. //
  3067. pszLocalHostname = new (CHAR[INTERNET_MAX_HOST_NAME_LENGTH+1]);
  3068. INET_ASSERT(pszLocalHostname);
  3069. if(pszLocalHostname)
  3070. {
  3071. DWORD dwSize = INTERNET_MAX_HOST_NAME_LENGTH;
  3072. DWORD dwValType;
  3073. // check fully qualified name (only if we know winsock is loaded)
  3074. if(g_fWinsockLoaded || _I_gethostname)
  3075. {
  3076. if(ERROR_SUCCESS == LoadWinsock())
  3077. {
  3078. if(0 == _I_gethostname(pszLocalHostname, INTERNET_MAX_HOST_NAME_LENGTH))
  3079. {
  3080. if(0 == lstrcmpi(pszLocalHostname, pszHostName))
  3081. fLocalHost = TRUE;
  3082. }
  3083. UnloadWinsock();
  3084. }
  3085. }
  3086. if (!fLocalHost &&
  3087. SHGetValue(HKEY_LOCAL_MACHINE,szRegPathTCP,
  3088. szRegValHostName,&dwValType,pszLocalHostname,&dwSize) ==
  3089. ERROR_SUCCESS)
  3090. {
  3091. if(0 == lstrcmpi(pszLocalHostname, pszHostName))
  3092. fLocalHost = TRUE;
  3093. }
  3094. // also against check computer name in registry, RPC
  3095. // will use this if there's no DNS hostname set
  3096. dwSize = INTERNET_MAX_HOST_NAME_LENGTH;
  3097. if (!fLocalHost &&
  3098. SHGetValue(HKEY_LOCAL_MACHINE, szRegPathComputerName,
  3099. szRegValComputerName,&dwValType,pszLocalHostname,&dwSize) ==
  3100. ERROR_SUCCESS)
  3101. {
  3102. if(0 == lstrcmpi(pszLocalHostname, pszHostName))
  3103. fLocalHost = TRUE;
  3104. }
  3105. delete pszLocalHostname;
  3106. }
  3107. if(fLocalHost)
  3108. {
  3109. DEBUG_PRINT(DIALUP, INFO, ("Found local machine name\n"));
  3110. goto quit;
  3111. }
  3112. // Check for override of "dial if no net" (ICS host is prime example)
  3113. dwAutodialFlags = CheckForNoNetOverride(pszHostName);
  3114. // not localhost, so need to autodial
  3115. fRet = InternetAutodial(dwAutodialFlags, 0);
  3116. fNeedToFix = FALSE;
  3117. }
  3118. quit:
  3119. if(fNeedToFix)
  3120. {
  3121. // Since we're not dialing, ensure correct settings
  3122. FixProxySettingsForCurrentConnection(FALSE);
  3123. }
  3124. if(fAllocatedBuffer)
  3125. {
  3126. delete pszURLCopy;
  3127. }
  3128. DEBUG_LEAVE(fRet);
  3129. return fRet;
  3130. }
  3131. extern "C"
  3132. VOID
  3133. InternetAutodialCallback(
  3134. IN DWORD dwOpCode,
  3135. IN LPCVOID lpParam
  3136. )
  3137. /*++
  3138. Routine Description:
  3139. Possibly establish a connection prior to a winsock operation. Called
  3140. by winsock before each operation.
  3141. Arguments:
  3142. dwOpCode - Winsock operation about to be done
  3143. lpParam - Information about operation
  3144. Return Value:
  3145. None.
  3146. --*/
  3147. {
  3148. DEBUG_ENTER_API((DBG_DIALUP,
  3149. None,
  3150. "InternetAutodialCallback",
  3151. "%s (%#x), %#x",
  3152. InternetMapWinsockCallbackType(dwOpCode),
  3153. dwOpCode,
  3154. lpParam
  3155. ));
  3156. //
  3157. // Make sure we're initialized and have done the process check!
  3158. //
  3159. InitAutodialModule(FALSE);
  3160. //
  3161. // If we're in rnaapp.exe process, bail out now!
  3162. //
  3163. if(g_fRNAAppProcess)
  3164. {
  3165. DEBUG_PRINT(DIALUP, INFO, ("Process is rnaapp.exe! Bailing out!\n"));
  3166. DEBUG_LEAVE_API(0);
  3167. return;
  3168. }
  3169. // return as soon as possible if we know there's nothing for us to do here...
  3170. // keep track of the last time we sent winsock activity messages or
  3171. // checked for RNA activity. We won't do these things more than once
  3172. // every MIN_RNA_BUSY_CHECK_INTERVAL seconds. Getting the tick count
  3173. // is extremely cheap so this is a worthwhile optimization.
  3174. BOOL fProcessedRecently = FALSE;
  3175. DWORD dwNewTickCount = GetTickCountWrap();
  3176. DWORD dwElapsed = dwNewTickCount - g_dwLastTickCount;
  3177. if (dwElapsed < MIN_RNA_BUSY_CHECK_INTERVAL) {
  3178. fProcessedRecently = TRUE;
  3179. } else {
  3180. g_dwLastTickCount = dwNewTickCount;
  3181. }
  3182. // we're in the winsock callback so it's safe (ie. cheap) to call winsock
  3183. g_fWinsockLoaded = TRUE;
  3184. if (!fProcessedRecently) {
  3185. // if hidden autodisconnect monitor window is around, send it a message to
  3186. // notify it of winsock activity so it knows we're not idle.
  3187. HWND hwndMonitorApp = FindWindow(szAutodialMonitorClass,NULL);
  3188. if (hwndMonitorApp) {
  3189. PostMessage(hwndMonitorApp,WM_WINSOCK_ACTIVITY,0,0);
  3190. }
  3191. if(NULL == g_hwndWebCheck) {
  3192. g_hwndWebCheck = FindWindow(szWebCheckMonitorClass,NULL);
  3193. }
  3194. if(g_hwndWebCheck) {
  3195. PostMessage(g_hwndWebCheck,WM_WINSOCK_ACTIVITY,0,0);
  3196. }
  3197. }
  3198. //
  3199. // Only continue if we have a callback type that we actually do something
  3200. // with
  3201. //
  3202. switch(dwOpCode)
  3203. {
  3204. case WINSOCK_CALLBACK_CONNECT:
  3205. case WINSOCK_CALLBACK_RECVFROM:
  3206. // we do stuff with these so continue...
  3207. break;
  3208. case WINSOCK_CALLBACK_GETHOSTBYNAME:
  3209. // bail out now for gethostbyname(NULL) else do normal
  3210. // gethostbyname processing.
  3211. if(NULL == lpParam)
  3212. {
  3213. DEBUG_PRINT(DIALUP, INFO, ("Not dialing for gethostbyname(NULL)\n"));
  3214. DEBUG_LEAVE_API(0);
  3215. return;
  3216. }
  3217. break;
  3218. default:
  3219. DEBUG_LEAVE_API(0);
  3220. return;
  3221. }
  3222. //
  3223. // if we're EXPLORER or IEXPLORE and in global offline mode, don't dial
  3224. //
  3225. if (GlobalIsProcessExplorer && IsGlobalOffline())
  3226. {
  3227. DEBUG_LEAVE_API(0);
  3228. return;
  3229. }
  3230. //
  3231. // verify proxy settings are correct for current connection and if
  3232. // we're already connected, bail out!
  3233. //
  3234. if(FixProxySettingsForCurrentConnection(FALSE) || fDontProcessHook)
  3235. {
  3236. DEBUG_LEAVE_API(0);
  3237. return;
  3238. }
  3239. //
  3240. // Look at the specific winsock operation we're doing and bail out if
  3241. // we don't want to dial
  3242. //
  3243. switch (dwOpCode)
  3244. {
  3245. case WINSOCK_CALLBACK_CONNECT:
  3246. case WINSOCK_CALLBACK_RECVFROM:
  3247. // these APIs all have a sockaddr struct as the API-specific
  3248. // parameter, look in struct to find address family. Don't
  3249. // respond if it's non-TCP.
  3250. INET_ASSERT(lpParam);
  3251. if (lpParam) {
  3252. struct sockaddr_in * psa = (struct sockaddr_in *) lpParam;
  3253. if (AF_INET != psa->sin_family) {
  3254. // not TCP, don't respond
  3255. DEBUG_PRINT(DIALUP, INFO, ("Not dialing for non TCP connect\n"));
  3256. DEBUG_LEAVE_API(0);
  3257. return;
  3258. }
  3259. #if defined(UNIX) && defined(ux10)
  3260. DEBUG_PRINT(DIALUP, INFO, ("IP address: %d.%d.%d.%d\n",
  3261. ((LPBYTE)&(psa->sin_addr))[0],
  3262. ((LPBYTE)&(psa->sin_addr))[1],
  3263. ((LPBYTE)&(psa->sin_addr))[2],
  3264. ((LPBYTE)&(psa->sin_addr))[3]));
  3265. #else
  3266. DEBUG_PRINT(DIALUP, INFO, ("IP address: %d.%d.%d.%d\n",
  3267. psa->sin_addr.S_un.S_un_b.s_b1,
  3268. psa->sin_addr.S_un.S_un_b.s_b2,
  3269. psa->sin_addr.S_un.S_un_b.s_b3,
  3270. psa->sin_addr.S_un.S_un_b.s_b4));
  3271. #endif
  3272. if (0x0100007f == psa->sin_addr.s_addr) {
  3273. // loop back address, don't respond
  3274. DEBUG_PRINT(DIALUP, INFO, ("Not dialing for 127.0.0.1\n"));
  3275. DEBUG_LEAVE_API(0);
  3276. return;
  3277. }
  3278. //
  3279. // Check to make sure this isn't our local address if possible
  3280. //
  3281. // This is a very rare code path and won't be hit in normal
  3282. // browsing. Also, winsock is already loaded in this process
  3283. // so LoadWinsock is reasonably cheap.
  3284. //
  3285. // This code is here to fix FrontPage and WinCE. Those are
  3286. // pretty much the only guys that will ever hit it.
  3287. //
  3288. // [darrenmi] don't attempt to do this if we're on the
  3289. // netware client because gethostbyname(NULL) will fault.
  3290. //
  3291. // how many IPs can the local host have? 16 seems like an
  3292. // excessive amount.
  3293. #define MAX_IP_COUNT 16
  3294. if (FALSE == GlobalRunningNovellClient32 &&
  3295. FALSE == g_fGetHostByNameNULLFails &&
  3296. ERROR_SUCCESS == LoadWinsock())
  3297. {
  3298. // get real ip addresses for this host
  3299. HOSTENT *ph;
  3300. __try
  3301. {
  3302. ph = _I_gethostbyname(NULL);
  3303. }
  3304. __except(EXCEPTION_EXECUTE_HANDLER)
  3305. {
  3306. g_fGetHostByNameNULLFails = TRUE;
  3307. ph = NULL;
  3308. }
  3309. ENDEXCEPT
  3310. if(ph)
  3311. {
  3312. int iCount = 0;
  3313. DWORD dwAddress[MAX_IP_COUNT];
  3314. while((LPDWORD)(ph->h_addr_list[iCount]) && iCount < MAX_IP_COUNT)
  3315. {
  3316. dwAddress[iCount] = *((LPDWORD)(ph->h_addr_list[iCount]));
  3317. //
  3318. // don't dial if connecting to this host's ip address
  3319. //
  3320. // FrontPage does this.
  3321. //
  3322. if(dwAddress[iCount] == psa->sin_addr.s_addr) {
  3323. DEBUG_PRINT(DIALUP, INFO, ("Not dialing for local host IP address\n"));
  3324. DEBUG_LEAVE_API(0);
  3325. return;
  3326. }
  3327. iCount++;
  3328. }
  3329. //
  3330. // RFC1918 lists 192.168.x.x as 256 class C networks
  3331. // for use as non-global addresses. If this address
  3332. // is one of these guys and we already have an ip on the
  3333. // same subnet, don't dial
  3334. //
  3335. // WinCE device does this.
  3336. //
  3337. if((psa->sin_addr.s_addr & 0x0000FFFF) == 0x0000A8C0)
  3338. {
  3339. int i;
  3340. for(i=0; i<iCount; i++)
  3341. {
  3342. if((psa->sin_addr.s_addr & 0x00FFFFFF) == (dwAddress[i] & 0x00FFFFFF))
  3343. {
  3344. // connect to a local subnet we're alreay on. Don't dial.
  3345. DEBUG_PRINT(DIALUP, INFO, ("Not dialing for local 192.168.x.x subnet\n"));
  3346. DEBUG_LEAVE_API(0);
  3347. return;
  3348. }
  3349. }
  3350. }
  3351. }
  3352. UnloadWinsock();
  3353. }
  3354. }
  3355. break;
  3356. case WINSOCK_CALLBACK_GETHOSTBYNAME:
  3357. // a lot of apps do a GetHostByName(<local host name>) first
  3358. // thing to get their hands on a hostent struct, this doesn't
  3359. // constitute wanting to hit the net. If we get a GetHostByName,
  3360. // compare the host name to the local host name in the registry,
  3361. // and if they match then don't respond to this.
  3362. if (lpParam)
  3363. {
  3364. InternetAutodialIfNotLocalHost(NULL, (LPSTR)lpParam);
  3365. DEBUG_LEAVE_API(0);
  3366. return;
  3367. }
  3368. }
  3369. //
  3370. // Dial...
  3371. //
  3372. InternetAutodial(0, 0);
  3373. DEBUG_LEAVE_API(0);
  3374. }
  3375. ///////////////////////////////////////////////////////////////////////////
  3376. ///////////////////////////////////////////////////////////////////////////
  3377. //
  3378. // Public APIs
  3379. //
  3380. ///////////////////////////////////////////////////////////////////////////
  3381. ///////////////////////////////////////////////////////////////////////////
  3382. VOID
  3383. AUTO_PROXY_DLLS::SaveDetectedProxySettings(
  3384. IN LPINTERNET_PROXY_INFO_EX lpProxySettings,
  3385. IN BOOL fNeedHostIPChk
  3386. )
  3387. {
  3388. BOOL fRet;
  3389. BOOL fDialupRet;
  3390. BOOL fConnectionMatch = FALSE;
  3391. //
  3392. // Ensure we're initialized
  3393. //
  3394. InitAutodialModule(TRUE);
  3395. WaitForSingleObject(g_hConnectionMutex, INFINITE);
  3396. // remove settting from last time...
  3397. lpProxySettings->dwAutoDiscoveryFlags &= ~(AUTO_PROXY_FLAG_DETECTION_SUSPECT);
  3398. //
  3399. // Check to see if we have a dialup connection
  3400. //
  3401. DWORD dwFixEntry;
  3402. fRet = IsDialUpConnection(TRUE, &dwFixEntry);
  3403. if(fRet)
  3404. {
  3405. // check for match
  3406. if(lpProxySettings->lpszConnectionName &&
  3407. lstrcmpiA(lpProxySettings->lpszConnectionName, g_RasCon.GetEntryA(dwFixEntry)) == 0)
  3408. {
  3409. fConnectionMatch = TRUE;
  3410. }
  3411. }
  3412. fDialupRet = fRet;
  3413. DWORD dwFlags;
  3414. //
  3415. // no ras connections - ensure LAN proxy settings are correct
  3416. //
  3417. fRet = IsLanConnection(&dwFlags);
  3418. if(fRet)
  3419. {
  3420. if (lpProxySettings->lpszConnectionName == NULL)
  3421. {
  3422. fConnectionMatch = TRUE;
  3423. }
  3424. else if (fDialupRet &&
  3425. (dwFlags & NETWORK_ALIVE_LAN) &&
  3426. (lpProxySettings->dwDetectedInterfaceIpCount == 1) &&
  3427. g_fSensInstalled )
  3428. {
  3429. //
  3430. // At this point our detection results are suspect,
  3431. // because we are claiming to have a DialUp Adapter,
  3432. // Net Adapter, and only One IP address for the whole
  3433. // system.
  3434. //
  3435. lpProxySettings->dwAutoDiscoveryFlags |= AUTO_PROXY_FLAG_DETECTION_SUSPECT;
  3436. }
  3437. }
  3438. if ( fConnectionMatch && !(IsGlobalOffline()))
  3439. {
  3440. LockAutoProxy();
  3441. fRet = TRUE;
  3442. //
  3443. // Do Host IP check to confirm we're still ok, ie on the same connection,
  3444. // that we began on.
  3445. //
  3446. if ( fNeedHostIPChk )
  3447. {
  3448. DWORD error;
  3449. DWORD * pdwDetectedInterfaceIp = NULL;
  3450. DWORD dwDetectedInterfaceIpCount;
  3451. fRet = FALSE;
  3452. error = GetHostAddresses(&pdwDetectedInterfaceIp,
  3453. &dwDetectedInterfaceIpCount); // will this cause problems with auto-dial?
  3454. if ( error == ERROR_SUCCESS &&
  3455. dwDetectedInterfaceIpCount == lpProxySettings->dwDetectedInterfaceIpCount)
  3456. {
  3457. fRet = TRUE;
  3458. for (DWORD i = 0; i < dwDetectedInterfaceIpCount; i++)
  3459. {
  3460. if (pdwDetectedInterfaceIp[i] != lpProxySettings->pdwDetectedInterfaceIp[i] ) {
  3461. fRet = FALSE;
  3462. break;
  3463. }
  3464. }
  3465. }
  3466. if ( pdwDetectedInterfaceIp != NULL) {
  3467. FREE_MEMORY(pdwDetectedInterfaceIp);
  3468. }
  3469. }
  3470. //
  3471. // Now save out all our settings, if we can.
  3472. //
  3473. if (fRet)
  3474. {
  3475. SetProxySettings(lpProxySettings,
  3476. IsModifiedInProcess(),
  3477. FALSE /*no overwrite*/);
  3478. if ( ! IsModifiedInProcess() )
  3479. {
  3480. // Need to save results to registry, if we succeed,
  3481. // then make sure to transfer new version stamp
  3482. if ( WriteProxySettings(lpProxySettings, FALSE) == ERROR_SUCCESS )
  3483. {
  3484. _ProxySettings.dwCurrentSettingsVersion =
  3485. lpProxySettings->dwCurrentSettingsVersion;
  3486. }
  3487. }
  3488. // stamp version, so we know we've been updated.
  3489. _dwUpdatedProxySettingsVersion = lpProxySettings->dwCurrentSettingsVersion;
  3490. }
  3491. UnlockAutoProxy();
  3492. }
  3493. ReleaseMutex(g_hConnectionMutex);
  3494. return;
  3495. }
  3496. INTERNETAPI_(BOOL)
  3497. InternetGetConnectedStateExW(
  3498. OUT LPDWORD lpdwFlags,
  3499. OUT LPWSTR lpszConnectionName,
  3500. IN DWORD dwBufLen,
  3501. IN DWORD dwReserved
  3502. )
  3503. /*++
  3504. Routine Description:
  3505. Determine whether any useful connections exist
  3506. On FALSE, will return information about autodial connection if any
  3507. Arguments:
  3508. lpdwFlags - Location to store flags about current connection
  3509. INTERNET_CONNECTION_MODEM Modem connection
  3510. INTERNET_CONNECTION_LAN Network connection
  3511. INTERNET_CONNECTION_PROXY Proxy in use
  3512. INTERNET_RAS_INSTALLED Ras is installed on machine
  3513. lpszConnectionName
  3514. - name of current connection
  3515. dwBufLen - length of name buffer
  3516. dwReserved - Must be 0
  3517. Return Value:
  3518. BOOL
  3519. TRUE - connection exists
  3520. FALSE - no connection exists
  3521. --*/
  3522. {
  3523. DEBUG_ENTER_API((DBG_DIALUP,
  3524. Bool,
  3525. "InternetGetConnectedStateExW",
  3526. "%#x, %#x, %#x, %#x",
  3527. lpdwFlags,
  3528. lpszConnectionName,
  3529. dwBufLen,
  3530. dwReserved
  3531. ));
  3532. BOOL fRet = FALSE, fProcessedRecently = FALSE, fConfigured = FALSE;
  3533. DWORD dwFlags = 0;
  3534. DWORD dwRes = 0, dwBytes, dwEnable = 0;
  3535. AUTODIAL ad;
  3536. BOOL fAutodialEnabled;
  3537. static BOOL fSensState = TRUE;
  3538. //
  3539. // Ensure we're initialized
  3540. //
  3541. InitAutodialModule(TRUE);
  3542. //
  3543. // Verify parameters
  3544. //
  3545. if((lpdwFlags && ERROR_SUCCESS != ProbeWriteBuffer(lpdwFlags, sizeof(DWORD))) ||
  3546. (lpszConnectionName && ERROR_SUCCESS != ProbeWriteBuffer(lpszConnectionName, dwBufLen)) ||
  3547. dwReserved)
  3548. {
  3549. SetLastError(ERROR_INVALID_PARAMETER);
  3550. DEBUG_ERROR(DIALUP, ERROR_INVALID_PARAMETER);
  3551. DEBUG_LEAVE_API(FALSE);
  3552. return FALSE;
  3553. }
  3554. //
  3555. // If on Millennium, forward calls to RAS
  3556. //
  3557. if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRasInternetGetConnectedStateExA)
  3558. {
  3559. CHAR szAnsiName[RAS_MaxEntryName + 1];
  3560. DWORD dwConnFlags = 0;
  3561. //
  3562. // call RAS one first...
  3563. //
  3564. fRet = _RasInternetGetConnectedStateExA(&dwConnFlags, szAnsiName, RAS_MaxEntryName, dwReserved);
  3565. if(lpszConnectionName)
  3566. {
  3567. MultiByteToWideChar(CP_ACP, 0, szAnsiName, -1, lpszConnectionName, dwBufLen);
  3568. }
  3569. //
  3570. // RAS one fills in everything except PROXY and OFFLINE flags.
  3571. //
  3572. if(dwConnFlags & INTERNET_CONNECTION_MODEM)
  3573. {
  3574. dwEnable = FixProxySettings(lpszConnectionName, FALSE, 0);
  3575. }
  3576. else if(dwConnFlags & INTERNET_CONNECTION_LAN)
  3577. {
  3578. dwEnable = FixProxySettings(NULL, FALSE, 0);
  3579. }
  3580. if(dwEnable)
  3581. {
  3582. dwConnFlags |= INTERNET_CONNECTION_PROXY | INTERNET_CONNECTION_CONFIGURED;
  3583. }
  3584. if(IsGlobalOffline())
  3585. {
  3586. dwConnFlags |= INTERNET_CONNECTION_OFFLINE;
  3587. }
  3588. if(fRet)
  3589. {
  3590. // we now have a connection - if we get into a state where we don't,
  3591. // ask user to go offline
  3592. g_fAskOffline = TRUE;
  3593. }
  3594. // set out flags if caller requested it
  3595. if(lpdwFlags)
  3596. {
  3597. *lpdwFlags = dwConnFlags;
  3598. }
  3599. DEBUG_LEAVE_API(fRet);
  3600. return fRet;
  3601. }
  3602. //
  3603. // Initialize out variables
  3604. //
  3605. if(lpdwFlags)
  3606. *lpdwFlags = 0;
  3607. if(lpszConnectionName)
  3608. *lpszConnectionName = 0;
  3609. WaitForSingleObject(g_hConnectionMutex, INFINITE);
  3610. //
  3611. // Check to see if we have a dialup connection
  3612. //
  3613. DWORD dwFixEntry;
  3614. fRet = IsDialUpConnection(FALSE, &dwFixEntry);
  3615. //
  3616. // Tell caller if RAS is installed
  3617. //
  3618. if(g_fRasInstalled)
  3619. {
  3620. dwFlags |= INTERNET_RAS_INSTALLED;
  3621. }
  3622. if(fRet)
  3623. {
  3624. // this connectoid is connected
  3625. dwFlags |= INTERNET_CONNECTION_MODEM;
  3626. fConfigured = TRUE;
  3627. dwEnable = FixProxySettings(g_RasCon.GetEntryW(dwFixEntry), FALSE, 0);
  3628. // copy name for caller
  3629. if(lpszConnectionName && dwBufLen) {
  3630. StrCpyNW(lpszConnectionName, g_RasCon.GetEntryW(dwFixEntry), dwBufLen);
  3631. }
  3632. }
  3633. //
  3634. // autodial configuration is relevant for finding out if lan is present.
  3635. // if autodial.force is set, consider lan NOT present since we're going
  3636. // to dial anyway.
  3637. //
  3638. fAutodialEnabled = IsAutodialEnabled(NULL, &ad);
  3639. if((FALSE == fRet) && (FALSE == ad.fForceDial))
  3640. {
  3641. //
  3642. // no ras connections - ensure LAN proxy settings are correct
  3643. //
  3644. DWORD dwLanFlags;
  3645. fRet = IsLanConnection(&dwLanFlags);
  3646. if(fRet)
  3647. {
  3648. // lan connection is configured and present
  3649. dwFlags |= INTERNET_CONNECTION_LAN;
  3650. dwEnable = FixProxySettings(NULL, FALSE, dwLanFlags);
  3651. // if call wants name, fill in "lan connection"
  3652. if(lpszConnectionName && dwBufLen)
  3653. LoadStringWrapW(GlobalDllHandle, IDS_LAN_CONNECTION, lpszConnectionName, dwBufLen);
  3654. }
  3655. }
  3656. //
  3657. // turn on proxy flag if necessary
  3658. //
  3659. if(dwEnable)
  3660. {
  3661. dwFlags |= INTERNET_CONNECTION_PROXY;
  3662. // we have some kind of configured connection
  3663. fConfigured = TRUE;
  3664. }
  3665. //
  3666. // If no connection found, tell caller about autodial entry
  3667. //
  3668. if(FALSE == fConfigured ||
  3669. 0 == (dwFlags & (INTERNET_CONNECTION_LAN | INTERNET_CONNECTION_MODEM)))
  3670. {
  3671. if(ad.fConfigured)
  3672. {
  3673. // we have an autodial connection
  3674. fConfigured = TRUE;
  3675. if(0 == (dwFlags & (INTERNET_CONNECTION_LAN | INTERNET_CONNECTION_MODEM)))
  3676. {
  3677. // autodial is enabled
  3678. // If the caller cares about entry name, find them one
  3679. if(ad.fHasEntry)
  3680. {
  3681. // use specified one
  3682. dwFlags |= INTERNET_CONNECTION_MODEM;
  3683. if(lpszConnectionName && dwBufLen)
  3684. {
  3685. StrCpyNW(lpszConnectionName, ad.pszEntryName, dwBufLen);
  3686. }
  3687. }
  3688. else
  3689. {
  3690. // None set as default, pick one and set it
  3691. RasEnumHelp * pre = new RasEnumHelp;
  3692. if(pre)
  3693. {
  3694. if (pre->GetEntryCount())
  3695. {
  3696. LPWSTR pwzName = pre->GetEntryW(0);
  3697. // set this entry to the default
  3698. SHSetValueW(HKEY_CURRENT_USER, szRegPathRemoteAccessW, szRegValInternetEntryW,
  3699. REG_SZ, (BYTE *)pwzName, lstrlenW(pwzName));
  3700. // return to caller
  3701. dwFlags |= INTERNET_CONNECTION_MODEM;
  3702. if(lpszConnectionName && dwBufLen)
  3703. {
  3704. StrCpyNW(lpszConnectionName, pwzName, dwBufLen);
  3705. }
  3706. }
  3707. delete pre;
  3708. }
  3709. }
  3710. }
  3711. }
  3712. }
  3713. //
  3714. // Tell caller if we have a connection configured
  3715. //
  3716. if(fConfigured)
  3717. {
  3718. dwFlags |= INTERNET_CONNECTION_CONFIGURED;
  3719. }
  3720. //
  3721. // Tell caller if we're offline
  3722. //
  3723. if(IsGlobalOffline())
  3724. {
  3725. dwFlags |= INTERNET_CONNECTION_OFFLINE;
  3726. }
  3727. if(lpdwFlags)
  3728. *lpdwFlags = dwFlags;
  3729. #if defined(SITARA)
  3730. //
  3731. // IF we're configured to use a modem,
  3732. // then go ahead an turn on Sitara
  3733. //
  3734. if (fRet && (dwFlags & INTERNET_CONNECTION_MODEM))
  3735. {
  3736. GlobalHasSitaraModemConn = TRUE;
  3737. }
  3738. else
  3739. {
  3740. GlobalHasSitaraModemConn = FALSE;
  3741. }
  3742. #endif // SITARA
  3743. if(fRet)
  3744. // we now have a connection - if we get into a state where we don't,
  3745. // ask user to go offline
  3746. g_fAskOffline = TRUE;
  3747. ReleaseMutex(g_hConnectionMutex);
  3748. DEBUG_LEAVE_API(fRet);
  3749. SetLastError(ERROR_SUCCESS);
  3750. return fRet;
  3751. }
  3752. INTERNETAPI_(BOOL)
  3753. InternetGetConnectedStateExA(
  3754. OUT LPDWORD lpdwFlags,
  3755. OUT LPSTR lpszConnectionName,
  3756. IN DWORD dwBufLen,
  3757. IN DWORD dwReserved
  3758. )
  3759. /*++
  3760. Routine Description:
  3761. Ansi version of InternetGetConnectedStateExW
  3762. Arguments:
  3763. Same as InternetGetConnectedStateExW
  3764. Return Value:
  3765. Same as InternetGetConnectedStateExW
  3766. --*/
  3767. {
  3768. DEBUG_ENTER_API((DBG_DIALUP,
  3769. Bool,
  3770. "InternetGetConnectedStateExA",
  3771. "%#x, %#x, %#x, %#x",
  3772. lpdwFlags,
  3773. lpszConnectionName,
  3774. dwBufLen,
  3775. dwReserved
  3776. ));
  3777. WCHAR szWideName[RAS_MaxEntryName + 1];
  3778. BOOL fRet;
  3779. //
  3780. // call wide version
  3781. //
  3782. *szWideName = 0;
  3783. fRet = InternetGetConnectedStateExW(lpdwFlags, szWideName, RAS_MaxEntryName, dwReserved);
  3784. //
  3785. // convert wide name to ansi
  3786. //
  3787. if(lpszConnectionName)
  3788. {
  3789. if(ERROR_SUCCESS == ProbeWriteBuffer(lpszConnectionName, dwBufLen))
  3790. {
  3791. int i;
  3792. i = WideCharToMultiByte(CP_ACP, 0, szWideName, -1, lpszConnectionName, dwBufLen, NULL, NULL);
  3793. if(0 == i) {
  3794. // truncated - null terminate
  3795. lpszConnectionName[dwBufLen - 1] = 0;
  3796. }
  3797. }
  3798. else
  3799. {
  3800. SetLastError(ERROR_INVALID_PARAMETER);
  3801. DEBUG_ERROR(DIALUP, ERROR_INVALID_PARAMETER);
  3802. fRet = FALSE;
  3803. }
  3804. }
  3805. DEBUG_LEAVE_API(fRet);
  3806. return fRet;
  3807. }
  3808. INTERNETAPI_(BOOL)
  3809. InternetGetConnectedState(
  3810. OUT LPDWORD lpdwFlags,
  3811. IN DWORD dwReserved
  3812. )
  3813. /*++
  3814. Routine Description:
  3815. Get simple information about connected state
  3816. Arguments:
  3817. lpdwFlags - Location to store connection flags
  3818. xxx
  3819. dwReserved - must be 0
  3820. Return Value:
  3821. BOOL
  3822. Connected - TRUE
  3823. Not - FALSE
  3824. --*/
  3825. {
  3826. DEBUG_ENTER_API((DBG_DIALUP,
  3827. Bool,
  3828. "InternetGetConnectedState",
  3829. "%#x, %#x",
  3830. lpdwFlags,
  3831. dwReserved
  3832. ));
  3833. BOOL fRet = InternetGetConnectedStateExW(lpdwFlags, NULL, 0, dwReserved);
  3834. DEBUG_LEAVE_API(fRet);
  3835. return fRet;
  3836. }
  3837. BOOL
  3838. HandleFlagsForRas(
  3839. IN HWND hwndParent,
  3840. IN BOOL fAutodialing,
  3841. IN DWORD dwFlags,
  3842. OUT DWORD *pdwRasFlags
  3843. )
  3844. /*++
  3845. Routine Description:
  3846. Convert InternetDial flags to RasInternetDial flags. Also directly handle
  3847. any flags that Ras doesn't know about.
  3848. Only ever called on Millennium
  3849. Arguments:
  3850. hwndParent Parent window for any UI
  3851. fAutodialing We're called from InternetAutodial vs. InternetDial
  3852. dwFlags InternetDial flags
  3853. dwRasFlags RasInternetDial flags
  3854. Return values:
  3855. TRUE Success
  3856. FALSE Abort operation
  3857. --*/
  3858. {
  3859. DEBUG_ENTER((DBG_DIALUP,
  3860. Dword,
  3861. "HandleFlagsForRas",
  3862. "%#x, %B, %#x, %#x",
  3863. hwndParent,
  3864. fAutodialing,
  3865. dwFlags,
  3866. pdwRasFlags
  3867. ));
  3868. DWORD dwResult = ERROR_SUCCESS;
  3869. *pdwRasFlags = 0;
  3870. //
  3871. // Convert flags for directly supported options
  3872. //
  3873. if((dwFlags & INTERNET_DIAL_SHOW_OFFLINE) ||
  3874. (GlobalIsProcessExplorer)) *pdwRasFlags |= RAS_INTERNET_AUTODIAL_ALLOW_OFFLINE;
  3875. if((dwFlags & INTERNET_DIAL_UNATTENDED) ||
  3876. (dwFlags & INTERNET_AUTODIAL_FORCE_UNATTENDED)) *pdwRasFlags |= RAS_INTERNET_AUTODIAL_UNATTENDED;
  3877. // if(dwFlags & INTERNET_DIAL_FORCE_PROMPT) not supported
  3878. //
  3879. // Handle offline mode
  3880. //
  3881. if(dwFlags & INTERNET_AUTODIAL_FORCE_ONLINE)
  3882. {
  3883. SetOffline(FALSE);
  3884. }
  3885. //
  3886. // Handle security check -- only if not connected and autodial and check is enabled.
  3887. //
  3888. AUTODIAL ad;
  3889. DWORD dwState;
  3890. if(!IsDialUpConnection(FALSE, NULL))
  3891. {
  3892. //
  3893. // Perform check if:
  3894. //
  3895. // - Autodial is enabled OR we're not autodialing
  3896. // - and Security check is enabled
  3897. //
  3898. IsAutodialEnabled(NULL, &ad);
  3899. if((ad.fEnabled || !fAutodialing) && ad.fSecurity)
  3900. {
  3901. if(PerformSecurityCheck(hwndParent, dwFlags))
  3902. {
  3903. // non-silent check failed
  3904. dwResult = ERROR_INTERNET_FAILED_DUETOSECURITYCHECK;
  3905. }
  3906. }
  3907. }
  3908. DEBUG_PRINT(DIALUP, INFO, ("Ras Flags=0x%x\n", *pdwRasFlags));
  3909. DEBUG_LEAVE(dwResult);
  3910. return dwResult;
  3911. }
  3912. VOID
  3913. HandleUserCancel(
  3914. IN DWORD dwResult,
  3915. IN DWORD dwFlags
  3916. )
  3917. /*++
  3918. Routine Description:
  3919. Check to see if user cancelled dial and fix appropriate states
  3920. Arguments:
  3921. dwResult - Result of dialing operation -- only care about
  3922. USER_DISCONNECTION
  3923. dwFlags - Dialing flags, only care about SHOW_OFFLINE
  3924. Return Value:
  3925. None
  3926. --*/
  3927. {
  3928. DEBUG_ENTER((DBG_DIALUP,
  3929. None,
  3930. "HandleUserCancel",
  3931. "%#x, %#x",
  3932. dwResult,
  3933. dwFlags
  3934. ));
  3935. if(ERROR_USER_DISCONNECTION == dwResult)
  3936. {
  3937. if(GlobalIsProcessExplorer || (dwFlags & INTERNET_DIAL_SHOW_OFFLINE))
  3938. {
  3939. // offline semantics - set offline mode
  3940. SetOffline(TRUE);
  3941. }
  3942. else
  3943. {
  3944. // Normal cancel. Prevent more dialing attempts.
  3945. fDontProcessHook = TRUE;
  3946. }
  3947. }
  3948. DEBUG_LEAVE(0);
  3949. }
  3950. DWORD
  3951. InternetDialW(
  3952. IN HWND hwndParent,
  3953. IN LPWSTR pszEntryName,
  3954. IN DWORD dwFlags,
  3955. OUT DWORD_PTR *lpdwConnection,
  3956. IN DWORD dwReserved
  3957. )
  3958. /*++
  3959. Routine Description:
  3960. Connect to a specified connectoid
  3961. Arguments:
  3962. hwndParent - parent window for dialing ui
  3963. pszEntryName - string => connectoid to connect to
  3964. - empty string ("") => let user choose
  3965. - NULL => connect to autodial connectoid
  3966. dwFlags - flags controlling operation:
  3967. xxx
  3968. lpdwConnection - location to store connection handle
  3969. dwReserved - must be 0
  3970. Return Value:
  3971. DWORD
  3972. Success - 0
  3973. Failure - Ras or windows error code
  3974. --*/
  3975. {
  3976. DEBUG_ENTER_API((DBG_DIALUP,
  3977. Dword,
  3978. "InternetDialW",
  3979. "%#x, %#x (%Q), %#x, %#x, %#x",
  3980. hwndParent,
  3981. pszEntryName,
  3982. pszEntryName,
  3983. dwFlags,
  3984. lpdwConnection,
  3985. dwReserved
  3986. ));
  3987. DIALSTATE data;
  3988. BOOL fConn = FALSE;
  3989. DWORD dwRet = ERROR_SUCCESS, dwTemp;
  3990. WCHAR szKey[MAX_PATH];
  3991. AUTODIAL ad;
  3992. //
  3993. // Ensure we're initialized
  3994. //
  3995. InitAutodialModule(TRUE);
  3996. //
  3997. // ensure reserved field is 0
  3998. //
  3999. if(dwReserved)
  4000. {
  4001. dwRet = ERROR_INVALID_PARAMETER;
  4002. goto quit;
  4003. }
  4004. //
  4005. // ensure we have a lpdwConnection pointer and initialize it
  4006. //
  4007. if(NULL == lpdwConnection ||
  4008. ERROR_SUCCESS != ProbeWriteBuffer(lpdwConnection, sizeof(DWORD)))
  4009. {
  4010. dwRet = ERROR_INVALID_PARAMETER;
  4011. goto quit;
  4012. }
  4013. *lpdwConnection = 0;
  4014. //
  4015. // ensure we have a valid pszEntryName (NULL is valid - see below)
  4016. //
  4017. if(pszEntryName && ERROR_SUCCESS != ProbeStringW(pszEntryName, &dwTemp))
  4018. {
  4019. dwRet = ERROR_INVALID_PARAMETER;
  4020. goto quit;
  4021. }
  4022. //
  4023. // On Millennium, forward calls to RAS
  4024. //
  4025. if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRasInternetDialA)
  4026. {
  4027. DWORD dwRasFlags;
  4028. dwRet = HandleFlagsForRas(hwndParent, FALSE, dwFlags, &dwRasFlags);
  4029. if(dwRet)
  4030. {
  4031. // error, need to bail out
  4032. DEBUG_LEAVE_API(dwRet);
  4033. return dwRet;
  4034. }
  4035. CHAR szAnsiName[RAS_MaxEntryName+1];
  4036. CHAR *pszNameToUse = NULL;
  4037. if(pszEntryName)
  4038. {
  4039. WideCharToMultiByte(CP_ACP, 0, pszEntryName, -1, szAnsiName, RAS_MaxEntryName, NULL, NULL);
  4040. pszNameToUse = szAnsiName;
  4041. }
  4042. dwRet = _RasInternetDialA(hwndParent, pszNameToUse, dwRasFlags, lpdwConnection, dwReserved);
  4043. //
  4044. // Switch to offline mode if necessary
  4045. //
  4046. HandleUserCancel(dwRet, dwFlags);
  4047. //
  4048. // If connected, send message to dialmon
  4049. //
  4050. CDHINFO cdh;
  4051. DWORD dwEntry = 0;
  4052. if(IsDialUpConnection(TRUE, &dwEntry) && !IsCDH(g_RasCon.GetEntryW(dwEntry), &cdh))
  4053. {
  4054. SendDialmonMessage(WM_SET_CONNECTOID_NAME, TRUE);
  4055. }
  4056. //
  4057. // fix proxy information for new connection
  4058. //
  4059. FixProxySettingsForCurrentConnection(FALSE);
  4060. DEBUG_LEAVE_API(dwRet);
  4061. return dwRet;
  4062. }
  4063. //
  4064. // Check config state
  4065. //
  4066. IsAutodialEnabled(NULL, &ad);
  4067. if(ad.fSecurity)
  4068. {
  4069. if(PerformSecurityCheck(hwndParent, dwFlags))
  4070. {
  4071. DEBUG_LEAVE_API(ERROR_INTERNET_FAILED_DUETOSECURITYCHECK);
  4072. return ERROR_INTERNET_FAILED_DUETOSECURITYCHECK;
  4073. }
  4074. }
  4075. //
  4076. // Save connectoid name
  4077. //
  4078. memset(&data, 0, sizeof(DIALSTATE));
  4079. data.params.dwSize = sizeof(RASDIALPARAMSW);
  4080. if(pszEntryName && *pszEntryName)
  4081. {
  4082. // use passed connection name as one to dial
  4083. StrCpyNW(data.params.szEntryName, pszEntryName, RAS_MaxEntryName + 1);
  4084. }
  4085. else
  4086. {
  4087. // NULL name passed, use autodial entry if any. If not, use first
  4088. // one in list (data.params.szEntryName == "")
  4089. if(ad.fEnabled && ad.fHasEntry)
  4090. {
  4091. StrCpyNW(data.params.szEntryName, ad.pszEntryName, RAS_MaxEntryName + 1);
  4092. }
  4093. }
  4094. //
  4095. // Check to see if already have a ras connection
  4096. //
  4097. fConn = IsDialUpConnection(FALSE, NULL);
  4098. //
  4099. // Check to see if there's a custom dial handler
  4100. //
  4101. if(FALSE == fConn)
  4102. {
  4103. CDHINFO cdh;
  4104. memset(&cdh, 0, sizeof(CDHINFO));
  4105. if(IsCDH(data.params.szEntryName, &cdh))
  4106. {
  4107. DWORD dwTmpRetVal;
  4108. if(CallCDH(hwndParent, data.params.szEntryName, &cdh, INTERNET_CUSTOMDIAL_CONNECT, &dwTmpRetVal))
  4109. {
  4110. dwRet = dwTmpRetVal;
  4111. if(ERROR_SUCCESS == dwRet || ERROR_ALREADY_EXISTS == dwRet)
  4112. {
  4113. // successfully connected
  4114. dwRet = ERROR_SUCCESS;
  4115. if(lpdwConnection)
  4116. *lpdwConnection = (DWORD)CDH_HCONN;
  4117. // reset last ras poll time to force a check next time
  4118. g_dwLastDialupTicks = 0;
  4119. // fix proxy information for new connection
  4120. WaitForSingleObject(g_hConnectionMutex, INFINITE);
  4121. FixProxySettings(data.params.szEntryName, FALSE, 0);
  4122. ReleaseMutex(g_hConnectionMutex);
  4123. }
  4124. else
  4125. {
  4126. // check to see if user cancelled and go to offline if necessary
  4127. HandleUserCancel(dwRet, dwFlags);
  4128. }
  4129. dwRet = ERROR_SUCCESS;
  4130. goto quit;
  4131. }
  4132. // else CDH didn't actually do anything - fall through
  4133. }
  4134. }
  4135. if(GlobalPlatformVersion5 && *data.params.szEntryName)
  4136. {
  4137. // check to see if it's a win2k CDH
  4138. if(DialIfWin2KCDH(data.params.szEntryName, hwndParent, FALSE, &dwRet, lpdwConnection))
  4139. {
  4140. // check for cancel and offline mode
  4141. HandleUserCancel(dwRet, dwFlags);
  4142. goto quit;
  4143. }
  4144. }
  4145. //
  4146. // If we still don't have a connection, show our UI to make one
  4147. //
  4148. if(FALSE == fConn)
  4149. {
  4150. DWORD dwType, dwTemp, dwSize;
  4151. BOOL fDialedCDH = FALSE;
  4152. //
  4153. // serialize access to our UI
  4154. //
  4155. // If we already are displaying the UI, bring it to the foreground
  4156. // get mutex and check connection again - may have to wait for it and
  4157. // connection status could change
  4158. INET_ASSERT(g_hAutodialMutex);
  4159. WaitForSingleObject(g_hAutodialMutex, INFINITE);
  4160. if(IsDialUpConnection(FALSE, NULL))
  4161. {
  4162. // got a connection in the mean time - bail out
  4163. ReleaseMutex(g_hAutodialMutex);
  4164. DEBUG_LEAVE_API(ERROR_SUCCESS);
  4165. return ERROR_SUCCESS;
  4166. }
  4167. if(IsGlobalOffline())
  4168. {
  4169. // we went offline, then bail out without UI
  4170. ReleaseMutex(g_hAutodialMutex);
  4171. DEBUG_LEAVE_API(ERROR_SUCCESS);
  4172. return ERROR_SUCCESS;
  4173. }
  4174. //
  4175. // Make sure ras is happy
  4176. //
  4177. if(FALSE == EnsureRasLoaded())
  4178. {
  4179. ReleaseMutex(g_hAutodialMutex);
  4180. DEBUG_LEAVE_API(ERROR_NO_CONNECTION);
  4181. return ERROR_NO_CONNECTION;
  4182. }
  4183. //
  4184. // Fire up commctrl
  4185. //
  4186. InitCommCtrl();
  4187. if(!g_hDialEvent)
  4188. {
  4189. g_hDialEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  4190. }
  4191. if(!g_hDialEvent)
  4192. {
  4193. return E_FAIL;
  4194. }
  4195. //
  4196. // Dial it
  4197. //
  4198. CDialUI *pdui = new CDialUI(hwndParent);
  4199. if(pdui)
  4200. {
  4201. // make sure we have a reference
  4202. pdui->AddRef();
  4203. dwRet = pdui->StartDial(&data, dwFlags);
  4204. fDialedCDH = pdui->DialedCDH();
  4205. pdui->Release();
  4206. }
  4207. //
  4208. // Shut down commtrl
  4209. //
  4210. ExitCommCtrl();
  4211. //
  4212. // Switch to offline mode if necessary
  4213. //
  4214. HandleUserCancel(data.dwResult, dwFlags);
  4215. //
  4216. // reset last ras poll time to force a check next time and release
  4217. // mutex
  4218. //
  4219. g_dwLastDialupTicks = 0;
  4220. ReleaseMutex(g_hAutodialMutex);
  4221. if(!fDialedCDH)
  4222. {
  4223. //
  4224. // Save connect automatically if it wasn't overridden
  4225. //
  4226. if(0 == (dwFlags & INTERNET_DIAL_FORCE_PROMPT))
  4227. {
  4228. GetConnKeyW(data.params.szEntryName, szKey, ARRAYSIZE(szKey));
  4229. dwTemp = (data.dwFlags & CI_AUTO_CONNECT) ? 1 : 0;
  4230. SHSetValueW(HKEY_CURRENT_USER, szKey, REGSTR_DIAL_AUTOCONNECTW,
  4231. REG_DWORD, &dwTemp, sizeof(DWORD));
  4232. }
  4233. //
  4234. // check to see if we're really connected or not
  4235. //
  4236. if(data.dwResult || NULL == data.hConn)
  4237. {
  4238. if(data.hConn)
  4239. _RasHangUp(data.hConn);
  4240. dwRet = data.dwResult;
  4241. goto quit;
  4242. }
  4243. RasGetConnectStatusHelp RasGetConnectStatus(data.hConn);
  4244. dwRet = RasGetConnectStatus.GetError();
  4245. if(dwRet)
  4246. {
  4247. _RasHangUp(data.hConn);
  4248. goto quit;
  4249. }
  4250. if(RasGetConnectStatus.ConnState() != RASCS_Connected)
  4251. {
  4252. _RasHangUp(data.hConn);
  4253. dwRet = ERROR_NO_CONNECTION;
  4254. goto quit;
  4255. }
  4256. }
  4257. }
  4258. //
  4259. // fix proxy information for new connection
  4260. //
  4261. WaitForSingleObject(g_hConnectionMutex, INFINITE);
  4262. FixProxySettings(data.params.szEntryName, FALSE, 0);
  4263. ReleaseMutex(g_hConnectionMutex);
  4264. //
  4265. // reset last ras poll time to force a check next time
  4266. //
  4267. g_dwLastDialupTicks = 0;
  4268. //
  4269. // start disconnect monitoring
  4270. //
  4271. SendDialmonMessage(WM_SET_CONNECTOID_NAME, TRUE);
  4272. //
  4273. // return handle to caller if required
  4274. //
  4275. if(lpdwConnection)
  4276. *lpdwConnection = (DWORD_PTR) data.hConn;
  4277. quit:
  4278. SetEvent(g_hDialEvent);
  4279. DEBUG_LEAVE_API(dwRet);
  4280. return dwRet;
  4281. }
  4282. DWORD
  4283. InternetDialA(
  4284. IN HWND hwndParent,
  4285. IN LPSTR pszEntryName,
  4286. IN DWORD dwFlags,
  4287. OUT DWORD_PTR *lpdwConnection,
  4288. IN DWORD dwReserved
  4289. )
  4290. /*++
  4291. Routine Description:
  4292. Wide version of InternetDialA
  4293. Arguments:
  4294. Same as InternetDialA
  4295. Return Value:
  4296. Same as InternetDialA
  4297. --*/
  4298. {
  4299. DEBUG_ENTER_API((DBG_DIALUP,
  4300. Dword,
  4301. "InternetDialA",
  4302. "%#x, %#x (%q), %#x, %#x, %#x",
  4303. hwndParent,
  4304. pszEntryName,
  4305. pszEntryName,
  4306. dwFlags,
  4307. lpdwConnection,
  4308. dwReserved
  4309. ));
  4310. DWORD dwErr = ERROR_SUCCESS;
  4311. WCHAR szWideEntryName[RAS_MaxEntryName + 1];
  4312. WCHAR *pwzNameToUse = NULL;
  4313. if (pszEntryName)
  4314. {
  4315. if (IsBadStringPtr(pszEntryName, RAS_MaxEntryName + 1))
  4316. {
  4317. dwErr = ERROR_INVALID_PARAMETER;
  4318. goto cleanup;
  4319. }
  4320. else
  4321. {
  4322. int i;
  4323. i = MultiByteToWideChar(CP_ACP, 0, pszEntryName, -1, szWideEntryName, RAS_MaxEntryName);
  4324. if(0 == i)
  4325. {
  4326. // truncated - null terminate
  4327. szWideEntryName[RAS_MaxEntryName] = 0;
  4328. }
  4329. pwzNameToUse = szWideEntryName;
  4330. }
  4331. }
  4332. dwErr = InternetDialW(hwndParent, pwzNameToUse, dwFlags, lpdwConnection, dwReserved);
  4333. cleanup:
  4334. DEBUG_LEAVE_API(dwErr);
  4335. return dwErr;
  4336. }
  4337. DWORD
  4338. InternetHangUp(
  4339. IN DWORD_PTR dwConnection,
  4340. IN DWORD dwReserved
  4341. )
  4342. /*++
  4343. Routine Description:
  4344. Hangs up a connection established by InternetDial
  4345. Arguments:
  4346. dwConnection - connection obtained from InternetDial
  4347. dwReserved - must be 0
  4348. Return Value:
  4349. DWORD
  4350. Success - 0
  4351. Failure - Ras or windows error code
  4352. --*/
  4353. {
  4354. DEBUG_ENTER_API((DBG_DIALUP,
  4355. Dword,
  4356. "InternetHangUp",
  4357. "%#x, %#x",
  4358. dwConnection,
  4359. dwReserved
  4360. ));
  4361. DWORD dwRet;
  4362. //
  4363. // If on Millennium, forward calls to RAS
  4364. //
  4365. if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRasInternetHangUpA)
  4366. {
  4367. dwRet = _RasInternetHangUpA(dwConnection, dwReserved);
  4368. DEBUG_LEAVE_API(dwRet);
  4369. return dwRet;
  4370. }
  4371. // ensure reserved is 0
  4372. if(dwReserved)
  4373. {
  4374. DEBUG_LEAVE_API(ERROR_INVALID_PARAMETER);
  4375. return ERROR_INVALID_PARAMETER;
  4376. }
  4377. //
  4378. // Ensure we're initialized
  4379. //
  4380. if(FALSE == g_fAutodialInitialized)
  4381. {
  4382. InitAutodialModule(FALSE);
  4383. }
  4384. //
  4385. // Best we can do for CDH's is post message to the disconnect monitor.
  4386. // Hopefully it'll do the right thing and disconnect. Works for MSN
  4387. // at least.
  4388. //
  4389. if(CDH_HCONN == dwConnection)
  4390. {
  4391. //
  4392. // Try to find a CM connection to hang up
  4393. //
  4394. if(IsDialUpConnection(FALSE, NULL))
  4395. {
  4396. CDHINFO cdh;
  4397. DWORD i, dwError;
  4398. for(i=0; i < g_dwConnections; i++)
  4399. {
  4400. if(IsCDH(g_RasCon.GetEntryW(i), &cdh))
  4401. {
  4402. if(StrStrIW(cdh.pszDllName, szCMDllNameW))
  4403. {
  4404. DEBUG_PRINT(DIALUP, INFO, ("Found CM connection to hang up\n"));
  4405. dwError = _RasHangUp(g_RasCon.GetHandle(i));
  4406. DEBUG_LEAVE_API(dwError);
  4407. return dwError;
  4408. }
  4409. }
  4410. }
  4411. }
  4412. HWND hwndMonitorWnd = FindWindow(TEXT("MS_AutodialMonitor"),NULL);
  4413. if (hwndMonitorWnd) {
  4414. PostMessage(hwndMonitorWnd,WM_IEXPLORER_EXITING,0,0);
  4415. }
  4416. DEBUG_LEAVE_API(0);
  4417. return 0;
  4418. }
  4419. //
  4420. // Load ras
  4421. //
  4422. if(FALSE == EnsureRasLoaded())
  4423. {
  4424. DEBUG_LEAVE_API(ERROR_UNKNOWN);
  4425. return ERROR_UNKNOWN;
  4426. }
  4427. //
  4428. // hang up the connection
  4429. //
  4430. dwRet = _RasHangUp((HRASCONN)dwConnection);
  4431. DEBUG_LEAVE_API(dwRet);
  4432. return dwRet;
  4433. }
  4434. BOOLAPI InternetSetDialStateA(
  4435. IN LPCSTR lpszEntryName,
  4436. IN DWORD dwState,
  4437. IN DWORD dwReserved
  4438. )
  4439. /*++
  4440. Routine Description:
  4441. Sets current state for a custom dial handler.
  4442. This was broken in IE4 and didn't actually do anything. Rather than
  4443. leave it in this state, the notion of custom dial state has been
  4444. removed. [darrenmi]
  4445. Arguments:
  4446. lpszEntryName - connectiod to set state for
  4447. dwState - new connection state
  4448. dwReserved - must be 0
  4449. Return Value:
  4450. BOOL
  4451. Success - TRUE
  4452. Failure - FALSE, GetLastError for more information
  4453. --*/
  4454. {
  4455. DEBUG_ENTER_API((DBG_DIALUP,
  4456. Bool,
  4457. "InternetSetDialStateA",
  4458. "%#x (%q), %#x, %#x",
  4459. lpszEntryName,
  4460. lpszEntryName,
  4461. dwState,
  4462. dwReserved
  4463. ));
  4464. // NOTE: When this starts using lpszEntryName, remember to define USES_STRING to activate
  4465. // unicode conversions for InternetSetDialStateW.
  4466. if(dwReserved)
  4467. {
  4468. SetLastError(ERROR_INVALID_PARAMETER);
  4469. DEBUG_ERROR(DIALUP, ERROR_INVALID_PARAMETER);
  4470. DEBUG_LEAVE_API(FALSE);
  4471. return FALSE;
  4472. }
  4473. // [darrenmi] I do not expect any client to ever call this api - I don't
  4474. // think any were ever written. Only possible exception may be CM.
  4475. // If it does call it, I want to know.
  4476. #ifdef DEBUG
  4477. OutputDebugString("Wininet.DLL: Unexpected use of dead api, contact darrenmi [x34231]\n");
  4478. OutputDebugString("Wininet.DLL: It is safe to continue past this DebugBreak()\n");
  4479. DebugBreak();
  4480. #endif
  4481. DEBUG_LEAVE_API(TRUE);
  4482. return TRUE;
  4483. }
  4484. BOOLAPI InternetSetDialStateW(
  4485. IN LPCWSTR lpszEntryName,
  4486. IN DWORD dwState,
  4487. IN DWORD dwReserved
  4488. )
  4489. /*++
  4490. Routine Description:
  4491. Wide version of InternetSetDialStateA
  4492. Arguments:
  4493. Same as InternetSetDialStateA
  4494. Return Value:
  4495. Same as InternetSetDialStateA
  4496. --*/
  4497. {
  4498. DEBUG_ENTER_API((DBG_DIALUP,
  4499. Bool,
  4500. "InternetSetDialStateW",
  4501. "%#x (%Q), %#x, %#x",
  4502. lpszEntryName,
  4503. lpszEntryName,
  4504. dwState,
  4505. dwReserved
  4506. ));
  4507. BOOL fRet;
  4508. //
  4509. // Convert and call multibyte version
  4510. //
  4511. #ifdef INTERNETSETDIALSTATE_USES_CONNECTOID
  4512. DWORD dwErr = ERROR_SUCCESS;
  4513. MEMORYPACKET mpConnectoid;
  4514. if (lpszEntryName)
  4515. {
  4516. ALLOC_MB(lpszEntryName, 0, mpConnectoid);
  4517. if (!mpConnectoid.psStr)
  4518. {
  4519. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  4520. goto cleanup;
  4521. }
  4522. UNICODE_TO_ANSI(lpszEntryName, mpConnectoid);
  4523. }
  4524. fRet = InternetSetDialStateA(mpConnectoid.psStr, dwState, dwReserved);
  4525. cleanup:
  4526. if (dwErr!=ERROR_SUCCESS)
  4527. {
  4528. SetLastError(dwErr);
  4529. DEBUG_ERROR(DIALUP, dwErr);
  4530. }
  4531. #else
  4532. fRet = InternetSetDialStateA(NULL, dwState, dwReserved);
  4533. #endif
  4534. DEBUG_LEAVE_API(fRet);
  4535. return fRet;
  4536. }
  4537. BOOLAPI InternetGoOnlineW(
  4538. IN LPWSTR lpszURL,
  4539. IN HWND hwndParent,
  4540. IN DWORD dwFlags
  4541. )
  4542. /*++
  4543. Routine Description:
  4544. Show UI to ask user whether they wish to go back online. This is
  4545. triggered by clicking a link that isn't available offline.
  4546. Arguments:
  4547. lpszURL - url that triggered switch (currently not used)
  4548. hwndParent - parent window for dialog
  4549. dwFlags - operation control flags (currently not used)
  4550. INTERENT_GOONLINE_REFRESH
  4551. This was caused by a refresh rather than a click
  4552. on an unavailable link
  4553. Return Value:
  4554. BOOL
  4555. Success - TRUE
  4556. Failure - FALSE, GetLastError for more information
  4557. --*/
  4558. {
  4559. DEBUG_ENTER_API((DBG_DIALUP,
  4560. Bool,
  4561. "InternetGoOnlineW",
  4562. "%#x (%Q), %#x, %#x",
  4563. lpszURL,
  4564. lpszURL,
  4565. hwndParent,
  4566. dwFlags
  4567. ));
  4568. INT_PTR fRet = TRUE;
  4569. //
  4570. // validate flags
  4571. //
  4572. if(dwFlags & ~INTERENT_GOONLINE_REFRESH)
  4573. {
  4574. SetLastError(ERROR_INVALID_PARAMETER);
  4575. DEBUG_ERROR(DIALUP, ERROR_INVALID_PARAMETER);
  4576. DEBUG_LEAVE_API(FALSE);
  4577. return FALSE;
  4578. }
  4579. //
  4580. // if already online, we're done
  4581. //
  4582. if(IsGlobalOffline())
  4583. {
  4584. ULONG_PTR uCookie = 0;
  4585. SHActivateContext(&uCookie);
  4586. //
  4587. // Show ui to ask user to go online
  4588. //
  4589. fRet = DialogBoxParamWrapW(GlobalDllHandle, MAKEINTRESOURCEW(IDD_GOONLINE),
  4590. hwndParent, OnlineDlgProc, 0);
  4591. if (uCookie)
  4592. {
  4593. SHDeactivateContext(uCookie);
  4594. }
  4595. }
  4596. if(fRet)
  4597. {
  4598. //
  4599. // Make sure we're connected.
  4600. //
  4601. SetOffline(FALSE);
  4602. MEMORYPACKET mpUrl;
  4603. if (lpszURL)
  4604. {
  4605. ALLOC_MB(lpszURL, 0, mpUrl);
  4606. if (mpUrl.psStr)
  4607. {
  4608. UNICODE_TO_ANSI(lpszURL, mpUrl);
  4609. fRet = InternetAutodialIfNotLocalHost(mpUrl.psStr, NULL);
  4610. }
  4611. else
  4612. {
  4613. fRet = FALSE;
  4614. }
  4615. }
  4616. }
  4617. DEBUG_LEAVE_API(fRet != 0);
  4618. return (fRet != 0);
  4619. }
  4620. BOOLAPI InternetGoOnlineA(
  4621. IN LPSTR lpszURL,
  4622. IN HWND hwndParent,
  4623. IN DWORD dwFlags
  4624. )
  4625. /*++
  4626. Routine Description:
  4627. Wide version of InternetGoOnlineA
  4628. Arguments:
  4629. Same as InternetGoOnlineA
  4630. Return Value:
  4631. Same as InternetGoOnlineA
  4632. --*/
  4633. {
  4634. DEBUG_ENTER_API((DBG_DIALUP,
  4635. Bool,
  4636. "InternetGoOnlineA",
  4637. "%#x (%q), %#x, %#x",
  4638. lpszURL,
  4639. lpszURL,
  4640. hwndParent,
  4641. dwFlags
  4642. ));
  4643. BOOL fRet = FALSE;
  4644. //
  4645. // Convert and call multibyte version
  4646. //
  4647. DWORD dwErr = ERROR_SUCCESS;
  4648. BOOL fResult = FALSE;
  4649. LPWSTR lpszWideURL = NULL;
  4650. if (lpszURL)
  4651. {
  4652. int i;
  4653. DWORD dwLen = lstrlenA(lpszURL);
  4654. if((lpszWideURL = (LPWSTR)LocalAlloc(LPTR, (dwLen+1) * sizeof(WCHAR))) != NULL)
  4655. {
  4656. i = MultiByteToWideChar(CP_ACP, 0, lpszURL, -1, lpszWideURL, dwLen);
  4657. if(0 == i)
  4658. lpszWideURL[dwLen] = 0; // truncated - null terminate
  4659. }
  4660. }
  4661. fRet = InternetGoOnlineW(lpszWideURL, hwndParent, dwFlags);
  4662. if(lpszWideURL)
  4663. {
  4664. LocalFree(lpszWideURL);
  4665. }
  4666. DEBUG_LEAVE_API(fRet);
  4667. return fRet;
  4668. }
  4669. BOOL
  4670. InternetAutodial(
  4671. IN DWORD dwFlags,
  4672. IN HWND hwndParent
  4673. )
  4674. /*++
  4675. Routine Description:
  4676. Dials the internet connectoid
  4677. Arguments:
  4678. dwFlags - flags to control operation
  4679. xxx
  4680. hwndParent - parent window for any ui that's displayed
  4681. Return Value:
  4682. BOOL
  4683. Success - TRUE
  4684. Failure - FALSE, GetLastError for more info
  4685. --*/
  4686. {
  4687. DEBUG_ENTER_API((DBG_DIALUP,
  4688. Bool,
  4689. "InternetAutodial",
  4690. "%#x, %#x",
  4691. dwFlags,
  4692. hwndParent
  4693. ));
  4694. AUTODIAL config;
  4695. DWORD dwErrorCode = ERROR_INTERNET_INTERNAL_ERROR;
  4696. DWORD dwRet = ERROR_SUCCESS, dwLanFlags;
  4697. HWND hwnd = GetDesktopWindow();
  4698. //
  4699. // On Millennium, forward calls to RAS
  4700. //
  4701. if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRasInternetAutodialA)
  4702. {
  4703. DWORD dwRasFlags;
  4704. dwRet = HandleFlagsForRas(hwndParent, TRUE, dwFlags, &dwRasFlags);
  4705. if(dwRet)
  4706. {
  4707. // error, need to bail out
  4708. DEBUG_LEAVE_API(dwRet);
  4709. return dwRet;
  4710. }
  4711. dwRet = _RasInternetAutodialA(dwRasFlags, hwndParent);
  4712. //
  4713. // Switch to offline mode if necessary
  4714. //
  4715. HandleUserCancel(dwRet, dwFlags);
  4716. //
  4717. // If connected, send message to dialmon
  4718. //
  4719. CDHINFO cdh;
  4720. DWORD dwEntry = 0;
  4721. if(IsDialUpConnection(TRUE, &dwEntry) && !IsCDH(g_RasCon.GetEntryW(dwEntry), &cdh))
  4722. {
  4723. SendDialmonMessage(WM_SET_CONNECTOID_NAME, TRUE);
  4724. }
  4725. //
  4726. // fix proxy information for new connection
  4727. //
  4728. FixProxySettingsForCurrentConnection(FALSE);
  4729. //
  4730. // Prop return code
  4731. //
  4732. if(dwRet)
  4733. {
  4734. DEBUG_ERROR(DIALUP, dwRet);
  4735. SetLastError(dwRet);
  4736. }
  4737. DEBUG_LEAVE_API(0 == dwRet);
  4738. return (0 == dwRet);
  4739. }
  4740. // dwFlags - only valid flag is INTERNET_AUTODIAL_FORCE_UNATTENDED
  4741. // Keep ISVs honest about this
  4742. if(dwFlags & ~(INTERNET_AUTODIAL_FLAGS_MASK))
  4743. {
  4744. dwErrorCode = ERROR_INVALID_PARAMETER;
  4745. goto quit;
  4746. }
  4747. if(FALSE == g_fAutodialInitialized)
  4748. {
  4749. InitAutodialModule(TRUE);
  4750. }
  4751. // if no parent window was passed, use desktop window
  4752. if(NULL == hwndParent)
  4753. {
  4754. hwndParent = GetDesktopWindow();
  4755. }
  4756. //
  4757. // need connection mutex for FixProxySettings and IsLanConnection
  4758. //
  4759. WaitForSingleObject(g_hConnectionMutex, INFINITE);
  4760. //
  4761. // check to see if we're already connected
  4762. //
  4763. if(IsDialUpConnection(FALSE, &dwRet))
  4764. {
  4765. // make sure proxy settings are correct
  4766. FixProxySettings(g_RasCon.GetEntryW(dwRet), FALSE, 0);
  4767. ReleaseMutex(g_hConnectionMutex);
  4768. // If we're connected by modem, ensure online if necessary
  4769. if(dwFlags & INTERNET_AUTODIAL_FORCE_ONLINE)
  4770. {
  4771. SetOffline(FALSE);
  4772. }
  4773. dwErrorCode = ERROR_SUCCESS;
  4774. goto quit;
  4775. }
  4776. // Check config and make sure we have connectoids if we're supposed to
  4777. // dial one
  4778. if(IsAutodialEnabled(NULL, &config))
  4779. {
  4780. if(FALSE == EnsureRasLoaded())
  4781. {
  4782. config.fEnabled = config.fForceDial = FALSE;
  4783. }
  4784. else
  4785. {
  4786. RasEnumHelp *pRasEnum = new RasEnumHelp;
  4787. if (pRasEnum)
  4788. {
  4789. if (pRasEnum->GetEntryCount() == 0)
  4790. {
  4791. config.fEnabled = config.fForceDial = FALSE;
  4792. }
  4793. delete pRasEnum;
  4794. }
  4795. }
  4796. }
  4797. if(IsLanConnection(&dwLanFlags) && (FALSE == config.fForceDial))
  4798. {
  4799. if(!config.fEnabled || !(dwFlags & INTERNET_AUTODIAL_OVERRIDE_NET_PRESENT))
  4800. {
  4801. // make sure proxy settings are correct
  4802. FixProxySettings(NULL, FALSE, dwLanFlags);
  4803. ReleaseMutex(g_hConnectionMutex);
  4804. // autodial not necessary
  4805. dwErrorCode = ERROR_SUCCESS;
  4806. goto quit;
  4807. }
  4808. }
  4809. //
  4810. // check if offline and can't go online...
  4811. //
  4812. if( GlobalIsProcessExplorer && IsGlobalOffline() &&
  4813. 0 == (dwFlags & INTERNET_AUTODIAL_FORCE_ONLINE)) {
  4814. ReleaseMutex(g_hConnectionMutex);
  4815. dwErrorCode = ERROR_INTERNET_OFFLINE;
  4816. goto quit;
  4817. }
  4818. // make sure we're online
  4819. SetOffline(FALSE);
  4820. // make sure we're supposed to dial
  4821. if(FALSE == config.fEnabled) {
  4822. fDontProcessHook = TRUE;
  4823. dwErrorCode = ERROR_SUCCESS;
  4824. DEBUG_PRINT(DIALUP, INFO, ("Unable to find a connection\n"));
  4825. // no connections and can't dial. Prompt to go offline.
  4826. if(g_fAskOffline)
  4827. {
  4828. // IE5 Beta 1 Hack - Throw up this dialog for explorer or IE
  4829. // Only for now. However, we should introduce an API that
  4830. // allows any app to say that it wants to participate in
  4831. // IE's Offline Mode stuff and all such apps would then
  4832. // get this dialog
  4833. if(GlobalIsProcessExplorer)
  4834. {
  4835. ULONG_PTR uCookie = 0;
  4836. SHActivateContext(&uCookie);
  4837. // Throw up this dialog for explorer.exe or iexplore.exe only
  4838. if(DialogBoxParamWrapW(GlobalDllHandle, MAKEINTRESOURCEW(IDD_GOOFFLINE),
  4839. hwndParent, GoOfflinePromptDlgProc,(LPARAM) 0))
  4840. {
  4841. SetOffline(TRUE);
  4842. }
  4843. else
  4844. {
  4845. g_fAskOffline = FALSE;
  4846. }
  4847. if (uCookie)
  4848. {
  4849. SHDeactivateContext(uCookie);
  4850. }
  4851. }
  4852. }
  4853. //
  4854. // If we try to hit the net at this point, we want to use the lan
  4855. // settings whatever they are.
  4856. //
  4857. // This is the only place settings get propagated when no connection
  4858. // can be found.
  4859. //
  4860. FixProxySettings(NULL, FALSE, 0);
  4861. ReleaseMutex(g_hConnectionMutex);
  4862. goto quit;
  4863. }
  4864. // if no entry, fill in a bogus one - dialing UI will pick the first
  4865. // one
  4866. if(FALSE == config.fHasEntry) {
  4867. config.pszEntryName[0] = 0;
  4868. config.fHasEntry = TRUE;
  4869. }
  4870. ReleaseMutex(g_hConnectionMutex);
  4871. // Load Ras
  4872. if(FALSE == EnsureRasLoaded()) {
  4873. // Load of ras failed - probably not installed
  4874. fDontProcessHook = TRUE;
  4875. dwErrorCode = ERROR_SERVICE_DOES_NOT_EXIST;
  4876. goto quit;
  4877. }
  4878. //
  4879. // Fix dial flags
  4880. //
  4881. if((dwFlags & INTERNET_AUTODIAL_FORCE_UNATTENDED) && (config.fUnattended))
  4882. dwFlags |= INTERNET_DIAL_UNATTENDED;
  4883. //
  4884. // Dial it
  4885. //
  4886. DWORD_PTR dwHandle;
  4887. dwErrorCode = InternetDialW(hwndParent, config.pszEntryName, dwFlags, &dwHandle, 0);
  4888. quit:
  4889. if(dwErrorCode != ERROR_SUCCESS)
  4890. {
  4891. SetLastError(dwErrorCode);
  4892. DEBUG_ERROR(DIALUP, dwErrorCode);
  4893. }
  4894. DEBUG_LEAVE_API(dwErrorCode == ERROR_SUCCESS);
  4895. return((dwErrorCode == ERROR_SUCCESS));
  4896. }
  4897. BOOLAPI InternetAutodialHangup(
  4898. IN DWORD dwReserved
  4899. )
  4900. /*++
  4901. Routine Description:
  4902. Finds and hangs up the autodial connection
  4903. If the autodial connection is a CDH, call the CDH to hang it up. This
  4904. may or may not work depending on whether the CDH supports hanging up.
  4905. Arguments:
  4906. dwReserved - must be 0
  4907. Return Value:
  4908. BOOL
  4909. Success - TRUE
  4910. Failure - FALSE, GetLastError for more information
  4911. --*/
  4912. {
  4913. AUTODIAL config;
  4914. CDHINFO cdh;
  4915. DEBUG_ENTER_API((DBG_DIALUP,
  4916. Bool,
  4917. "InternetAutodialHangup",
  4918. "%#x",
  4919. dwReserved
  4920. ));
  4921. DWORD dwErr = ERROR_SUCCESS;
  4922. int j = 0;
  4923. // ensure reserved is 0
  4924. if(dwReserved) {
  4925. SetLastError(ERROR_INVALID_PARAMETER);
  4926. DEBUG_ERROR(DIALUP, ERROR_INVALID_PARAMETER);
  4927. DEBUG_LEAVE_API(FALSE);
  4928. return FALSE;
  4929. }
  4930. //
  4931. // On Millennium, forward calls to RAS
  4932. //
  4933. if(GlobalPlatformMillennium && EnsureRasLoaded() && pfnRasInternetAutodialHangUpA)
  4934. {
  4935. dwErr = _RasInternetAutodialHangUpA(dwReserved);
  4936. DEBUG_LEAVE_API(TRUE);
  4937. return TRUE;
  4938. }
  4939. if(FALSE == g_fAutodialInitialized)
  4940. {
  4941. InitAutodialModule(FALSE);
  4942. }
  4943. // read connectoid - if none or autodial not enabled, bail
  4944. if(FALSE == IsAutodialEnabled(NULL, &config) || FALSE == config.fHasEntry)
  4945. goto quit;
  4946. if(IsCDH(config.pszEntryName, &cdh))
  4947. {
  4948. //
  4949. // If this CDH is CM, bail out here so the RasHangup below happens
  4950. //
  4951. if(NULL == StrStrIW(cdh.pszDllName, szCMDllNameW))
  4952. {
  4953. // ask it to hang up - may or may not do it depending on what it
  4954. // supports
  4955. //
  4956. // This isn't going to work. CM doesn't like getting commands it
  4957. // doesn't understand. For now, CDHs don't hang up. Tough.
  4958. //
  4959. // CallCDH(NULL, config.pszEntryName, &cdh, INTERNET_CUSTOMDIAL_DISCONNECT);
  4960. //
  4961. // Actually, post message to CDH's disconnect monitor. Works for
  4962. // MSN at least.
  4963. HWND hwndMonitorWnd = FindWindow(TEXT("MS_AutodialMonitor"),NULL);
  4964. if (hwndMonitorWnd) {
  4965. PostMessage(hwndMonitorWnd,WM_IEXPLORER_EXITING,0,0);
  4966. }
  4967. goto quit;
  4968. }
  4969. }
  4970. //
  4971. // See if a ras connection matches the autodial connectoid
  4972. //
  4973. if(IsDialUpConnection(FALSE, NULL))
  4974. {
  4975. //
  4976. // See if any current connections match autodial connection
  4977. //
  4978. DWORD i;
  4979. for(i = 0; i < g_dwConnections; i++)
  4980. {
  4981. if(0 == StrCmpIW(g_RasCon.GetEntryW(i), config.pszEntryName))
  4982. {
  4983. _RasHangUp(g_RasCon.GetHandle(i));
  4984. break;
  4985. }
  4986. }
  4987. }
  4988. quit:
  4989. DEBUG_LEAVE_API(TRUE);
  4990. return TRUE;
  4991. }