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.

2147 lines
52 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. globals.cxx
  5. Abstract:
  6. Contains global data items for WININET.DLL and initialization function
  7. Contents:
  8. GlobalDllInitialize
  9. GlobalDllTerminate
  10. GlobalDataInitialize
  11. GlobalTruncateFileName;
  12. GlobalDataTerminate
  13. IsHttp1_1
  14. IsOffline
  15. SetOfflineUserState
  16. FetchLocalStrings
  17. GetWininetUserName
  18. ChangeGlobalSettings
  19. RefreshOfflineFromRegistry
  20. PerformStartupProcessing
  21. Author:
  22. Richard L Firth (rfirth) 15-Jul-1995
  23. Revision History:
  24. 15-Jul-1995 rfirth
  25. Created
  26. 07-Oct-1998 joshco
  27. updated minor version number 1->2
  28. --*/
  29. #include <wininetp.h>
  30. #include <ntverp.h>
  31. #include <autodial.h> // InitAutodialModule, ExitAutodialModule
  32. #include <schnlsp.h>
  33. #include <persist.h>
  34. //
  35. // WinInet major & minor versions - allow to be defined externally
  36. //
  37. // JOSHCO
  38. #if !defined(WININET_MAJOR_VERSION)
  39. #define WININET_MAJOR_VERSION 1
  40. #endif
  41. #if !defined(WININET_MINOR_VERSION)
  42. #define WININET_MINOR_VERSION 2
  43. #endif
  44. //
  45. // external functions
  46. //
  47. void RefreshP3PSettings();
  48. STDAPI_(void) UrlZonesDetach (void);
  49. #if INET_DEBUG
  50. VOID
  51. InitDebugSock(
  52. VOID
  53. );
  54. #endif
  55. //
  56. // private prototypes
  57. //
  58. #if defined(SITARA)
  59. PRIVATE
  60. VOID
  61. OpenIeMainKey(
  62. VOID
  63. );
  64. PRIVATE
  65. VOID
  66. CloseIeMainKey(
  67. VOID
  68. );
  69. PRIVATE
  70. BOOL
  71. CheckABS(
  72. VOID
  73. );
  74. PRIVATE
  75. BOOL
  76. ReadIeMainDwordValue(
  77. IN LPSTR pszValueName,
  78. OUT LPDWORD pdwValue
  79. );
  80. #endif // SITARA
  81. //
  82. // global DLL state data
  83. //
  84. GLOBAL HINSTANCE GlobalDllHandle = NULL;
  85. GLOBAL DWORD GlobalPlatformType;
  86. GLOBAL DWORD GlobalPlatformVersion5;
  87. GLOBAL DWORD GlobalPlatformMillennium = FALSE;
  88. GLOBAL DWORD GlobalPlatformWhistler = FALSE;
  89. GLOBAL DWORD GlobalDllState = INTERNET_STATE_ONLINE | INTERNET_STATE_IDLE;
  90. GLOBAL BOOL GlobalDataInitialized = FALSE;
  91. GLOBAL BOOL GlobalTruncateFileName = FALSE;
  92. //
  93. // WinInet DLL version information (mainly for diagnostics)
  94. //
  95. #if INET_DEBUG
  96. GLOBAL DWORD InternetMajorVersion = 1;
  97. GLOBAL DWORD InternetMinorVersion = 0;
  98. #endif // INET_DEBUG
  99. #if !defined(VER_PRODUCTBUILD)
  100. #define VER_PRODUCTBUILD 0
  101. #endif
  102. GLOBAL DWORD InternetBuildNumber = VER_PRODUCTBUILD;
  103. //
  104. // transport-based time-outs, etc.
  105. //
  106. //GLOBAL DWORD GlobalConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
  107. #ifndef unix
  108. GLOBAL DWORD GlobalConnectTimeout = 5 * 60 * 1000;
  109. #else
  110. GLOBAL DWORD GlobalConnectTimeout = 1 * 60 * 1000;
  111. #endif /* unix */
  112. GLOBAL DWORD GlobalConnectRetries = DEFAULT_CONNECT_RETRIES;
  113. GLOBAL DWORD GlobalSendTimeout = DEFAULT_SEND_TIMEOUT;
  114. GLOBAL DWORD GlobalReceiveTimeout = DEFAULT_RECEIVE_TIMEOUT;
  115. GLOBAL DWORD GlobalDataSendTimeout = DEFAULT_SEND_TIMEOUT;
  116. GLOBAL DWORD GlobalDataReceiveTimeout = DEFAULT_RECEIVE_TIMEOUT;
  117. GLOBAL DWORD GlobalFromCacheTimeout = (DWORD)-1;
  118. GLOBAL DWORD GlobalFtpAcceptTimeout = DEFAULT_FTP_ACCEPT_TIMEOUT;
  119. GLOBAL DWORD GlobalTransportPacketLength = DEFAULT_TRANSPORT_PACKET_LENGTH;
  120. GLOBAL DWORD GlobalKeepAliveSocketTimeout = DEFAULT_KEEP_ALIVE_TIMEOUT;
  121. GLOBAL DWORD GlobalSocketSendBufferLength = DEFAULT_SOCKET_SEND_BUFFER_LENGTH;
  122. GLOBAL DWORD GlobalSocketReceiveBufferLength = DEFAULT_SOCKET_RECEIVE_BUFFER_LENGTH;
  123. GLOBAL DWORD GlobalMaxHttpRedirects = DEFAULT_MAX_HTTP_REDIRECTS;
  124. GLOBAL DWORD GlobalMaxConnectionsPerServer = DEFAULT_MAX_CONNECTIONS_PER_SERVER;
  125. GLOBAL DWORD GlobalMaxConnectionsPer1_0Server = DEFAULT_MAX_CONS_PER_1_0_SERVER;
  126. GLOBAL DWORD GlobalConnectionInactiveTimeout = DEFAULT_CONNECTION_INACTIVE_TIMEOUT;
  127. GLOBAL DWORD GlobalServerInfoTimeout = DEFAULT_SERVER_INFO_TIMEOUT;
  128. GLOBAL const DWORD GlobalMaxSizeStatusLineResultText = 1024;
  129. GLOBAL BOOL GlobalHaveInternetOpened = FALSE;
  130. GLOBAL BOOL GlobalBypassEditedEntry = FALSE;
  131. GLOBAL DWORD GlobalCacheMode = 0;
  132. //GLOBAL DWORD GlobalServerInfoAllocCount = 0;
  133. //GLOBAL DWORD GlobalServerInfoDeAllocCount = 0;
  134. //
  135. // async worker thread variables
  136. //
  137. //GLOBAL DWORD GlobalMinimumWorkerThreads = DEFAULT_MINIMUM_THREADS;
  138. //GLOBAL DWORD GlobalMaximumWorkerThreads = DEFAULT_MAXIMUM_THREADS;
  139. //GLOBAL DWORD GlobalInitialWorkerThreads = DEFAULT_INITIAL_THREADS;
  140. //GLOBAL DWORD GlobalWorkerThreadIdleTimeout = DEFAULT_THREAD_IDLE_TIMEOUT;
  141. //GLOBAL DWORD GlobalWorkQueueLimit = DEFAULT_WORK_QUEUE_LIMIT;
  142. GLOBAL DWORD GlobalWorkerThreadTimeout = DEFAULT_WORKER_THREAD_TIMEOUT;
  143. GLOBAL BOOL g_bHibernating = FALSE;
  144. GLOBAL BOOL g_bDisableHibernation = FALSE;
  145. //
  146. // switches
  147. //
  148. GLOBAL BOOL InDllCleanup = FALSE;
  149. GLOBAL BOOL GlobalPleaseQuitWhatYouAreDoing = FALSE;
  150. GLOBAL BOOL GlobalDynaUnload = FALSE;
  151. GLOBAL BOOL GlobalDisableKeepAlive = FALSE;
  152. GLOBAL BOOL GlobalDisablePassport = FALSE;
  153. GLOBAL BOOL GlobalEnableHttp1_1 = FALSE;
  154. GLOBAL BOOL GlobalEnableProxyHttp1_1 = FALSE;
  155. GLOBAL BOOL GlobalDisableReadRange = FALSE;
  156. GLOBAL BOOL GlobalEnableGopher = FALSE;
  157. //GLOBAL BOOL GlobalAutoProxyInDeInit = FALSE;
  158. GLOBAL BOOL GlobalIsProcessExplorer = FALSE;
  159. #ifndef UNIX
  160. GLOBAL BOOL GlobalEnableFortezza = TRUE;
  161. #else /* for UNIX */
  162. GLOBAL BOOL GlobalEnableFortezza = FALSE;
  163. #endif /* UNIX */
  164. #if defined(SITARA)
  165. GLOBAL BOOL GlobalEnableSitara = FALSE;
  166. GLOBAL BOOL GlobalHasSitaraModemConn = FALSE;
  167. #endif // SITARA
  168. GLOBAL BOOL GlobalEnableUtf8Encoding = FALSE;
  169. GLOBAL BOOL GlobalEnableRevocation = FALSE;
  170. // SSL Switches (petesk 7/24/97)
  171. GLOBAL DWORD GlobalSecureProtocols = DEFAULT_SECURE_PROTOCOLS;
  172. GLOBAL DWORD GlobalSslStateCount = 0;
  173. //
  174. // AutoDetect Proxy Globals
  175. //
  176. GLOBAL LONG GlobalInternetOpenHandleCount = -1;
  177. GLOBAL DWORD GlobalProxyVersionCount = 0;
  178. GLOBAL BOOL GlobalAutoProxyNeedsInit = FALSE;
  179. GLOBAL BOOL GlobalAutoProxyInInit = FALSE;
  180. GLOBAL BOOL GlobalAutoProxyCacheEnable = TRUE;
  181. GLOBAL BOOL GlobalDisplayScriptDownloadFailureUI = FALSE;
  182. GLOBAL BOOL GlobalSendUTF8ServerToProxy = TRUE;
  183. GLOBAL BOOL GlobalMBCSAPIforCrack = TRUE;
  184. GLOBAL BOOL GlobalUseUTF8ServerForNameRes = FALSE;
  185. //
  186. // Workaround for Novell's Client32
  187. //
  188. GLOBAL BOOL fDontUseDNSLoadBalancing = FALSE;
  189. //
  190. // Workaround for slow RAS enumeration
  191. //
  192. GLOBAL BOOL GlobalDisableNT4RasCheck = FALSE;
  193. GLOBAL BOOL GlobalUseLanSettings = FALSE;
  194. GLOBAL BOOL GlobalSendExtraCRLF = TRUE;
  195. //Ftp time checking
  196. GLOBAL BOOL GlobalBypassFtpTimeCheck = FALSE;
  197. //
  198. // lists
  199. //
  200. GLOBAL SERIALIZED_LIST GlobalObjectList = {0};
  201. GLOBAL SERIALIZED_LIST GlobalServerInfoList = {0};
  202. //
  203. // cache timeouts
  204. //
  205. GLOBAL LONGLONG dwdwHttpDefaultExpiryDelta = 12 * 60 * 60 * (LONGLONG)10000000; // 12 hours in 100ns units
  206. GLOBAL LONGLONG dwdwFtpDefaultExpiryDelta = 24 * 60 * 60 * (LONGLONG)10000000; // 24 hours in 100ns units
  207. GLOBAL LONGLONG dwdwGopherDefaultExpiryDelta = 24 * 60 * 60 * (LONGLONG)10000000; // 24 hours in 100ns units
  208. GLOBAL LONGLONG dwdwSessionStartTime;
  209. GLOBAL LONGLONG dwdwSessionStartTimeDefaultDelta = 0;
  210. GLOBAL DWORD GlobalUrlCacheSyncMode = WININET_SYNC_MODE_DEFAULT;
  211. GLOBAL DWORD GlobalDiskUsageLowerBound = (4*1024*1024);
  212. GLOBAL DWORD GlobalScavengeFileLifeTime = (10*60);
  213. GLOBAL LPSTR vszMimeExclusionList=NULL, vszHeaderExclusionList=NULL;
  214. GLOBAL LPSTR *lpvrgszMimeExclusionTable=NULL, *lpvrgszHeaderExclusionTable=NULL;
  215. GLOBAL DWORD *lpvrgdwMimeExclusionTableOfSizes=NULL;
  216. GLOBAL DWORD vdwMimeExclusionTableCount=0, vdwHeaderExclusionTableCount=0;
  217. //
  218. // SSL globals, for UI. We need to know
  219. // whether its ok for us to pop up UI.
  220. //
  221. //
  222. GLOBAL BOOL GlobalWarnOnPost = FALSE;
  223. GLOBAL BOOL GlobalWarnAlways = FALSE;
  224. GLOBAL BOOL GlobalWarnOnZoneCrossing = TRUE;
  225. GLOBAL BOOL GlobalWarnOnBadCertSending = FALSE;
  226. GLOBAL BOOL GlobalWarnOnBadCertRecving = TRUE;
  227. GLOBAL BOOL GlobalDisableSslCaching = FALSE;
  228. GLOBAL BOOL GlobalWarnOnPostRedirect = TRUE;
  229. GLOBAL BOOL GlobalAlwaysDrainOnRedirect = FALSE;
  230. GLOBAL BOOL GlobalBypassSSLNoCacheCheck = FALSE;
  231. GLOBAL BOOL GlobalWarnOnHTTPSToHTTPRedirect = TRUE;
  232. GLOBAL SECURITY_CACHE_LIST GlobalCertCache;
  233. GLOBAL DWORD GlobalSettingsVersion=0; // crossprocess settings versionstamp
  234. GLOBAL BOOL GlobalSettingsLoaded = FALSE;
  235. GLOBAL const char vszSyncMode[] = "SyncMode5";
  236. GLOBAL const char vszDisableSslCaching[] = "DisableCachingOfSSLPages";
  237. GLOBAL BOOL GlobalDisableNTLMPreAuth = FALSE;
  238. GLOBAL char vszCurrentUser[MAX_PATH];
  239. GLOBAL DWORD vdwCurrentUserLen = 0;
  240. //
  241. // critical sections
  242. //
  243. GLOBAL CRITICAL_SECTION AutoProxyDllCritSec = {0};
  244. GLOBAL CRITICAL_SECTION LockRequestFileCritSec = {0};
  245. GLOBAL CRITICAL_SECTION ZoneMgrCritSec = {0};
  246. GLOBAL CRITICAL_SECTION MlangCritSec = {0};
  247. // cookies info
  248. GLOBAL BOOL vfPerUserCookies = TRUE;
  249. const char vszAnyUserName[]="anyuser";
  250. const char vszPerUserCookies[] = "PerUserCookies";
  251. const char vszInvalidFilenameChars[] = "<>\\\"/:|?*";
  252. GLOBAL BOOL GlobalLeashLegacyCookies = TRUE;
  253. const char vszLeashLegacyCookies[] = REGSTR_LEASH_LEGACY_COOKIES;
  254. // Hard-coded user agent string
  255. // Update for each different version of IE
  256. #if defined(UNIX)
  257. const char gszDefaultUserAgent[] = "Mozilla/4.0 (compatible; MSIE 6.0; X11)";
  258. #elif defined(_WIN64)
  259. const char gszDefaultUserAgent[] = "Mozilla/4.0 (compatible; MSIE 6.0; Win64)";
  260. #else
  261. const char gszDefaultUserAgent[] = "Mozilla/4.0 (compatible; MSIE 6.0; Win32)";
  262. #endif
  263. // Mlang related data and functions.
  264. PRIVATE HINSTANCE hInstMlang;
  265. PRIVATE PFNINETMULTIBYTETOUNICODE pfnInetMultiByteToUnicode;
  266. PRIVATE BOOL bFailedMlangLoad; // So we don't try repeatedly if we fail once.
  267. BOOL LoadMlang( );
  268. BOOL UnloadMlang( );
  269. #define MLANGDLLNAME "mlang.dll"
  270. // shfolder.dll hmod handle
  271. HMODULE g_HMODSHFolder = NULL;
  272. // Shell32.dll hmod handle
  273. HMODULE g_HMODShell32 = NULL;
  274. GLOBAL CUserName GlobalUserName;
  275. //
  276. // novell client32 (hack) "support"
  277. //
  278. GLOBAL BOOL GlobalRunningNovellClient32 = FALSE;
  279. GLOBAL BOOL GlobalNonBlockingClient32 = FALSE;
  280. //
  281. // private data
  282. //
  283. HANDLE g_hAutodialMutex = NULL;
  284. //
  285. // proxy info
  286. //
  287. GLOBAL PROXY_INFO_GLOBAL GlobalProxyInfo;
  288. //
  289. // DLL version info
  290. //
  291. GLOBAL INTERNET_VERSION_INFO InternetVersionInfo = {
  292. WININET_MAJOR_VERSION,
  293. WININET_MINOR_VERSION
  294. };
  295. //
  296. // HTTP version info - default 1.0
  297. //
  298. GLOBAL HTTP_VERSION_INFO HttpVersionInfo = {1, 0};
  299. GLOBAL BOOL fCdromDialogActive = FALSE;
  300. GLOBAL DWORD g_dwCredPersistAvail = CRED_PERSIST_UNKNOWN;
  301. //
  302. // The following globals are literal strings passed to winsock.
  303. // Do NOT make them const, otherwise they end up in .text section,
  304. // and web release of winsock2 has a bug where it locks and dirties
  305. // send buffers, confusing the win95 vmm and resulting in code
  306. // getting corrupted when it is paged back in. -RajeevD
  307. //
  308. GLOBAL char gszAt[] = "@";
  309. GLOBAL char gszBang[] = "!";
  310. GLOBAL char gszCRLF[] = "\r\n";
  311. extern GLOBAL SERIALIZED_LIST BlockedRequestQueue;
  312. // Identity-related globals
  313. GLOBAL DWORD GlobalIdentity = 0;
  314. GLOBAL GUID GlobalIdentityGuid = { 0x00000000L, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  315. GLOBAL BOOL GlobalSuppressCookiesPolicy = FALSE;
  316. #ifdef WININET6
  317. GLOBAL HKEY GlobalCacheHKey = HKEY_CURRENT_USER;
  318. #endif
  319. GLOBAL PTSTR GlobalSpecialDomains = NULL;
  320. GLOBAL PTSTR *GlobalSDOffsets = NULL;
  321. // auth globals
  322. DWORD GlobalEnableNegotiate = FALSE;
  323. // Nt service loading wininet. This triggers special semantics for webdav redir to avoid deadlocks
  324. // due to crossprocessmutexes being taken (ConnectionMutex is a good example of that)
  325. // (Shishir Pardikar)
  326. GLOBAL BOOL GlobalIsProcessNtService = FALSE;
  327. // Global Cred hack for Mars V2
  328. PWC * g_pwcUserAndPassword;
  329. // Begin (a-thkesa)
  330. // The following global added to read expire time value from registry:Default is 30 Min
  331. // See Windows Bug:557284/WinSE:23879
  332. // Declared in proxysup.hxx
  333. GLOBAL DWORD GlobalBadProxyExpiresTime = 30*60; // this will be multiplied
  334. // End(a-thkesa)
  335. BOOL g_fHasCredsTimestamp;
  336. SYSTEMTIME g_TimeCredsEntered;
  337. void SetUserOrPass (LPSTR lpszIn, BOOL fUser)
  338. {
  339. if (NULL == g_pwcUserAndPassword)
  340. {
  341. g_pwcUserAndPassword = PWC_Create(NULL, 0, NULL, NULL, NULL);
  342. }
  343. if (g_pwcUserAndPassword)
  344. {
  345. AuthLock();
  346. if (fUser)
  347. {
  348. g_pwcUserAndPassword->SetUser(lpszIn);
  349. }
  350. else
  351. {
  352. g_pwcUserAndPassword->SetPass(lpszIn);
  353. }
  354. AuthUnlock();
  355. }
  356. }
  357. void TimeStampCreds(void)
  358. {
  359. ::GetSystemTime(&g_TimeCredsEntered); // time-stamp the creds
  360. g_fHasCredsTimestamp = TRUE;
  361. }
  362. PSYSTEMTIME GetCredTimeStamp (void)
  363. {
  364. if (g_fHasCredsTimestamp)
  365. {
  366. return &g_TimeCredsEntered;
  367. }
  368. else
  369. {
  370. return NULL;
  371. }
  372. }
  373. BOOL GetUserAndPass (LPSTR *pszUser, LPSTR *pszPass)
  374. {
  375. if (g_pwcUserAndPassword)
  376. {
  377. if (g_pwcUserAndPassword->lpszUser && g_pwcUserAndPassword->lpszPass)
  378. {
  379. *pszUser = g_pwcUserAndPassword->GetUser();
  380. *pszPass = g_pwcUserAndPassword->GetPass();
  381. return TRUE;
  382. }
  383. }
  384. *pszUser = *pszPass = NULL;
  385. return FALSE;
  386. }
  387. //
  388. // functions
  389. //
  390. #ifdef UNIX
  391. extern "C"
  392. #endif /* UNIX */
  393. VOID
  394. GlobalDllInitialize(
  395. VOID
  396. )
  397. /*++
  398. Routine Description:
  399. The set of initializations - critical sections, etc. - that must be done at
  400. DLL_PROCESS_ATTACH
  401. Arguments:
  402. None.
  403. Return Value:
  404. None.
  405. --*/
  406. {
  407. DEBUG_ENTER((DBG_GLOBAL,
  408. None,
  409. "GlobalDllInitialize",
  410. NULL
  411. ));
  412. CLEAR_DEBUG_CRIT(szDebugBlankBuffer);
  413. GetCurrentGmtTime((LPFILETIME)&dwdwSessionStartTime);
  414. InitializeCriticalSection(&AutoProxyDllCritSec);
  415. InitializeCriticalSection(&LockRequestFileCritSec);
  416. InitializeCriticalSection(&ZoneMgrCritSec);
  417. InitializeCriticalSection(&MlangCritSec);
  418. InitializeSerializedList(&GlobalObjectList);
  419. InitializeSerializedList(&GlobalServerInfoList);
  420. InitializeSerializedList(&BlockedRequestQueue);
  421. AuthOpen();
  422. IwinsockInitialize();
  423. SecurityInitialize();
  424. FtpInitialize();
  425. GopherInitialize();
  426. //
  427. // initialize cache critical sections etc.
  428. //
  429. DLLUrlCacheEntry(DLL_PROCESS_ATTACH);
  430. EnsureInternetSettingsKeyCached();
  431. DEBUG_LEAVE(0);
  432. }
  433. #ifdef UNIX
  434. extern "C"
  435. #endif /* UNIX */
  436. VOID
  437. GlobalDllTerminate(
  438. VOID
  439. )
  440. /*++
  441. Routine Description:
  442. Undoes the initializations of GlobalDllInitialize
  443. Arguments:
  444. None.
  445. Return Value:
  446. None.
  447. --*/
  448. {
  449. DEBUG_ENTER((DBG_GLOBAL,
  450. None,
  451. "GlobalDllTerminate",
  452. NULL
  453. ));
  454. //
  455. // only perform resource clean-up if this DLL is being unloaded due to a
  456. // FreeLibrary() call. Otherwise, we take the lazy way out and let the
  457. // system clean up after us
  458. //
  459. if (GlobalDynaUnload) {
  460. TerminateAsyncSupport();
  461. GopherTerminate();
  462. FtpTerminate();
  463. IwinsockTerminate();
  464. HandleTerminate();
  465. }
  466. CHECK_SOCKETS();
  467. AuthClose();
  468. TerminateSerializedList(&BlockedRequestQueue);
  469. TerminateSerializedList(&GlobalServerInfoList);
  470. //
  471. //BUGBUG: we can't Terminate the list here because
  472. // of a race condition from IE3
  473. // (someone still holds the handle)
  474. // but we don't want to leak the CritSec
  475. // TerminateSerlizedList == DeleteCritSec + some Asserts
  476. //
  477. //TerminateSerializedList(&GlobalObjectList);
  478. DeleteCriticalSection(&(GlobalObjectList.Lock));
  479. DeleteCriticalSection(&MlangCritSec);
  480. DeleteCriticalSection(&ZoneMgrCritSec);
  481. DeleteCriticalSection(&LockRequestFileCritSec);
  482. DeleteCriticalSection(&AutoProxyDllCritSec);
  483. DLLUrlCacheEntry(DLL_PROCESS_DETACH);
  484. SecurityTerminate();
  485. if (g_HMODSHFolder)
  486. {
  487. FreeLibrary(g_HMODSHFolder);
  488. g_HMODSHFolder = NULL;
  489. }
  490. if (g_HMODShell32)
  491. {
  492. FreeLibrary(g_HMODShell32);
  493. g_HMODShell32 = NULL;
  494. }
  495. CloseInternetSettingsKey();
  496. DEBUG_LEAVE(0);
  497. }
  498. DWORD
  499. GlobalDataInitialize(
  500. VOID
  501. )
  502. /*++
  503. Routine Description:
  504. Loads any global data items from the registry
  505. Arguments:
  506. None.
  507. Return Value:
  508. DWORD
  509. Success - ERROR_SUCCESS
  510. Failure - ERROR_NOT_ENOUGH_MEMORY
  511. --*/
  512. {
  513. DEBUG_ENTER((DBG_GLOBAL,
  514. Dword,
  515. "GlobalDataInitialize",
  516. NULL
  517. ));
  518. static BOOL Initializing = FALSE;
  519. static BOOL Initialized = FALSE;
  520. static DWORD error = ERROR_SUCCESS;
  521. //
  522. // only one thread initializes
  523. //
  524. if (InterlockedExchange((LPLONG)&Initializing, TRUE)) {
  525. while (!Initialized) {
  526. SleepEx(0, TRUE);
  527. }
  528. goto done;
  529. }
  530. //
  531. // we ignore any failure return codes from reading the registry. All the
  532. // global variables are initialized to default values
  533. //
  534. //
  535. // UseSchannelDirectly - TRUE if we are to bypass SSPI "Secur32/Security"
  536. // and directly call into SCHANNEL. This should give us a perf
  537. // improvement since we don't have to load an extra DLL.
  538. //
  539. g_fHasCredsTimestamp = FALSE;
  540. //
  541. // BUGBUG - all these need to be per-process. They are intended for IE
  542. //
  543. memset(&GlobalIdentityGuid, 0, sizeof(GlobalIdentityGuid));
  544. InternetReadRegistryDword("FromCacheTimeout",
  545. (LPDWORD)&GlobalFromCacheTimeout
  546. );
  547. //InternetReadRegistryDword("UseSchannelDirectly",
  548. // (LPDWORD)&GlobalUseSchannelDirectly
  549. // );
  550. // also in ChangeGlobalSettings()
  551. InternetReadRegistryDword("SecureProtocols",
  552. (LPDWORD)&GlobalSecureProtocols
  553. );
  554. // also in ChangeGlobalSettings()
  555. if (!GlobalPlatformWhistler)
  556. {
  557. // Fortezza support has been removed from XP
  558. InternetReadRegistryDword("Fortezza",
  559. (LPDWORD)&GlobalEnableFortezza
  560. );
  561. }
  562. else
  563. {
  564. GlobalEnableFortezza = FALSE;
  565. }
  566. // also in ChangeGlobalSettings()
  567. InternetReadRegistryDword("CertificateRevocation",
  568. (LPDWORD)&GlobalEnableRevocation
  569. );
  570. InternetReadRegistryDword("DisableKeepAlive",
  571. (LPDWORD)&GlobalDisableKeepAlive
  572. );
  573. InternetReadRegistryDword("DisablePassport",
  574. (LPDWORD)&GlobalDisablePassport
  575. );
  576. InternetReadRegistryDword("CacheMode", (LPDWORD) &GlobalCacheMode);
  577. // also in ChangeGlobalSettings()
  578. InternetReadRegistryDword("EnableHttp1_1",
  579. (LPDWORD)&GlobalEnableHttp1_1
  580. );
  581. // also in ChangeGlobalSettings()
  582. InternetReadRegistryDword("ProxyHttp1.1",
  583. (LPDWORD)&GlobalEnableProxyHttp1_1
  584. );
  585. DWORD dwEnableNegotiate = -1;
  586. InternetReadRegistryDword("EnableNegotiate",
  587. (LPDWORD)&dwEnableNegotiate
  588. );
  589. if (dwEnableNegotiate != -1)
  590. {
  591. // the value is present in the registy, so we honor it.
  592. GlobalEnableNegotiate = dwEnableNegotiate;
  593. }
  594. else
  595. {
  596. if (GlobalPlatformWhistler && !IsInGUIModeSetup())
  597. {
  598. // the value is abscent in Whistler, we'll need to turn set the value to 1
  599. InternetWriteRegistryDword("EnableNegotiate", 1);
  600. GlobalEnableNegotiate = TRUE;
  601. }
  602. }
  603. GetUrlCacheHeaderData(CACHE_HEADER_DATA_DOWNLOAD_PARTIAL, &GlobalSslStateCount);
  604. DWORD dwType, dwSize;
  605. dwSize = sizeof(DWORD);
  606. SHGetValue(HKEY_CURRENT_USER, INTERNET_POLICY_KEY,
  607. "EnableAutoProxyResultCache", &dwType, &GlobalAutoProxyCacheEnable, &dwSize);
  608. dwSize = sizeof(DWORD);
  609. SHGetValue(HKEY_CURRENT_USER, INTERNET_POLICY_KEY,
  610. "DisplayScriptDownloadFailureUI", &dwType, &GlobalDisplayScriptDownloadFailureUI, &dwSize);
  611. dwSize = sizeof(DWORD);
  612. SHGetValue(HKEY_CURRENT_USER, INTERNET_POLICY_KEY,
  613. "MBCSServername", &dwType, &GlobalSendUTF8ServerToProxy, &dwSize);
  614. dwSize = sizeof(DWORD);
  615. SHGetValue(HKEY_CURRENT_USER, INTERNET_POLICY_KEY,
  616. "MBCSAPIforCrack", &dwType, &GlobalMBCSAPIforCrack, &dwSize);
  617. dwSize = sizeof(DWORD);
  618. SHGetValue(HKEY_CURRENT_USER, INTERNET_POLICY_KEY,
  619. "UTF8ServerNameRes", &dwType, &GlobalUseUTF8ServerForNameRes, &dwSize);
  620. //Read DisableWorkerThreadHibernation from HKLM first and allow HKCU override.
  621. InternetReadRegistryDwordKey(HKEY_LOCAL_MACHINE,
  622. "DisableWorkerThreadHibernation",
  623. (LPDWORD)&g_bDisableHibernation
  624. );
  625. InternetReadRegistryDword("DisableWorkerThreadHibernation",
  626. (LPDWORD)&g_bDisableHibernation
  627. );
  628. GlobalUseUTF8ServerForNameRes = GlobalUseUTF8ServerForNameRes
  629. && GlobalSendUTF8ServerToProxy;
  630. InternetReadRegistryDword("DisableReadRange",
  631. (LPDWORD)&GlobalDisableReadRange
  632. );
  633. InternetReadRegistryDword("SocketSendBufferLength",
  634. &GlobalSocketSendBufferLength
  635. );
  636. InternetReadRegistryDword("SocketReceiveBufferLength",
  637. &GlobalSocketReceiveBufferLength
  638. );
  639. InternetReadRegistryDword("KeepAliveTimeout",
  640. &GlobalKeepAliveSocketTimeout
  641. );
  642. InternetReadRegistryDword("MaxHttpRedirects",
  643. &GlobalMaxHttpRedirects
  644. );
  645. InternetReadRegistryDword("MaxConnectionsPerServer",
  646. &GlobalMaxConnectionsPerServer
  647. );
  648. InternetReadRegistryDword("MaxConnectionsPer1_0Server",
  649. &GlobalMaxConnectionsPer1_0Server
  650. );
  651. InternetReadRegistryDword("ServerInfoTimeout",
  652. &GlobalServerInfoTimeout
  653. );
  654. InternetReadRegistryDword("ReceiveTimeOut",
  655. (LPDWORD)&GlobalReceiveTimeout
  656. );
  657. InternetReadRegistryDword("DisableNTLMPreAuth",
  658. (LPDWORD)&GlobalDisableNTLMPreAuth
  659. );
  660. InternetReadRegistryDword("ScavengeCacheLowerBound",
  661. (LPDWORD)&GlobalDiskUsageLowerBound
  662. );
  663. InternetCacheReadRegistryDword("ScavengeCacheFileLifeTime",
  664. (LPDWORD)&GlobalScavengeFileLifeTime
  665. );
  666. DWORD dwDefTime;
  667. if (InternetReadRegistryDword("HttpDefaultExpiryTimeSecs", &dwDefTime) ==
  668. ERROR_SUCCESS) {
  669. dwdwHttpDefaultExpiryDelta = dwDefTime * (LONGLONG)10000000;
  670. }
  671. if (InternetReadRegistryDword("FtpDefaultExpiryTimeSecs", &dwDefTime) ==
  672. ERROR_SUCCESS) {
  673. dwdwFtpDefaultExpiryDelta = dwDefTime * (LONGLONG)10000000;
  674. }
  675. if (InternetReadRegistryDword("GopherDefaultExpiryTimeSecs", &dwDefTime) ==
  676. ERROR_SUCCESS) {
  677. dwdwGopherDefaultExpiryDelta = dwDefTime * (LONGLONG)10000000;
  678. }
  679. InternetReadRegistryDword(vszDisableSslCaching, (LPDWORD)&GlobalDisableSslCaching);
  680. InternetReadRegistryDword(vszPerUserCookies, (LPDWORD)&vfPerUserCookies);
  681. InternetReadRegistryDword(vszLeashLegacyCookies, (LPDWORD)&GlobalLeashLegacyCookies);
  682. InternetReadRegistryDword("DisableNT4RasCheck", (LPDWORD)&GlobalDisableNT4RasCheck);
  683. InternetReadRegistryDword("DialupUseLanSettings", (LPDWORD)&GlobalUseLanSettings);
  684. InternetReadRegistryDword("SendExtraCRLF", (LPDWORD)&GlobalSendExtraCRLF);
  685. InternetReadRegistryDword("BypassFtpTimeCheck", (LPDWORD)&GlobalBypassFtpTimeCheck);
  686. InternetReadRegistryDword("EnableGopher", (LPDWORD)&GlobalEnableGopher);
  687. dwSize = sizeof(DWORD);
  688. SHRegGetUSValue( INTERNET_SETTINGS_KEY, "BypassSSLNoCacheCheck", &dwType,
  689. (LPVOID)&GlobalBypassSSLNoCacheCheck, &dwSize, FALSE, NULL, 0 );
  690. //
  691. // fix for Novell's Client32 - zekel 23-jul-96
  692. // first check HKLM then HKCU, HKCU takes precdence
  693. //
  694. InternetReadRegistryDwordKey(HKEY_LOCAL_MACHINE,
  695. "DontUseDNSLoadBalancing",
  696. (LPDWORD)&fDontUseDNSLoadBalancing
  697. );
  698. InternetReadRegistryDword("DontUseDNSLoadBalancing",
  699. (LPDWORD) &fDontUseDNSLoadBalancing
  700. );
  701. InternetReadRegistryDword("NonBlockingClient32",
  702. (LPDWORD)&GlobalNonBlockingClient32
  703. );
  704. //
  705. // Get the list of MIME types for which caching needs to be disabled
  706. //
  707. CreateMimeExclusionTableForCache();
  708. //
  709. // Get the list of headers that should be excluded from the cache
  710. //
  711. CreateHeaderExclusionTableForCache();
  712. DEBUG_PRINT(HTTP,
  713. INFO,
  714. ("Current wininet user is %s length %d\n",
  715. vszCurrentUser,
  716. vdwCurrentUserLen
  717. ));
  718. //
  719. // initialize databases
  720. //
  721. InitializeResolverCache();
  722. GlobalDataReadWarningUIFlags();
  723. PerformStartupProcessing();
  724. //
  725. // create the global keep-alive, cert-cache and proxy lists
  726. //
  727. GlobalCertCache.Initialize();
  728. GlobalProxyInfo.InitializeProxySettings();
  729. //LoadServerInfoDatabase();
  730. //
  731. // initialize offline mode from registry
  732. //
  733. RefreshOfflineFromRegistry();
  734. //
  735. // read the global (cache) settings version to avoid an unnecessary reload
  736. // N.B. we rely on the side effect of calling urlcache InitGlobals
  737. //
  738. InternetSettingsChanged();
  739. char buf[MAX_PATH + 1];
  740. if (GetModuleFileName(NULL, buf, sizeof(buf))) {
  741. LPSTR p = strrchr(buf, DIR_SEPARATOR_CHAR);
  742. p = p ? ++p : buf;
  743. DEBUG_PRINT(INET, INFO, ("process is %q\n", p));
  744. if (lstrcmpi(p, "EXPLORER.EXE") && lstrcmpi(p, "IEXPLORE.EXE")) {
  745. //
  746. // yet another app-hack: AOL's current browser can't understand
  747. // HTTP 1.1. When they do, they have to call InternetSetOption()
  748. // with INTERNET_OPTION_HTTP_VERSION
  749. //
  750. if (!lstrcmpi(p, "WAOL.EXE")) {
  751. GlobalEnableHttp1_1 = FALSE;
  752. }
  753. if (!lstrcmpi(p, "SVCHOST.EXE") ||
  754. !lstrcmpi(p, "SERVICES.EXE")) {
  755. GlobalIsProcessNtService = TRUE;
  756. }
  757. //
  758. // non-IE app must supply this through option
  759. //
  760. GlobalFromCacheTimeout = (DWORD)-1;
  761. } else {
  762. GlobalIsProcessExplorer = TRUE;
  763. }
  764. } else {
  765. DEBUG_PRINT(INET,
  766. INFO,
  767. ("GetModuleFileName() returns %d\n",
  768. GetLastError()
  769. ));
  770. }
  771. //
  772. // initialize the autodial code
  773. //
  774. // NB!!! this has been moved AFTER the above app hack because it uses the GlobalIsProcessNtService
  775. // variable to decide whether to create a perprocess connection mutex or cross-process
  776. // (Shishir Pardikar)
  777. InitAutodialModule(FALSE);
  778. #if defined(SITARA)
  779. //
  780. // check if Sitara is loaded (IE5B1). Existence of key means Sitara
  781. // installed
  782. //
  783. HKEY key;
  784. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  785. "Software\\Microsoft\\InternetExpressLane",
  786. 0,
  787. KEY_QUERY_VALUE,
  788. &key) == ERROR_SUCCESS) {
  789. REGCLOSEKEY(key);
  790. OpenIeMainKey();
  791. GlobalEnableSitara = CheckABS();
  792. }
  793. #endif // SITARA
  794. DWORD urlEncoding;
  795. urlEncoding = 0;
  796. InternetReadRegistryDwordKey(HKEY_LOCAL_MACHINE,
  797. "UrlEncoding",
  798. &urlEncoding
  799. );
  800. if (urlEncoding == 0) {
  801. GlobalEnableUtf8Encoding = TRUE;
  802. }
  803. // File name truncate ?
  804. DWORD dwTruncateFileName;
  805. dwTruncateFileName = 0;
  806. InternetReadRegistryDword("TruncateFileName", &dwTruncateFileName);
  807. if (dwTruncateFileName != 0)
  808. GlobalTruncateFileName = TRUE;
  809. //
  810. // perform module/package-specific initialization
  811. //
  812. error = HandleInitialize();
  813. if (error != ERROR_SUCCESS) {
  814. goto quit;
  815. }
  816. //
  817. // initalize the cookie system
  818. //
  819. if (!OpenTheCookieJar()) {
  820. error = ERROR_NOT_ENOUGH_MEMORY;
  821. goto quit;
  822. }
  823. //
  824. // initialize the background task manager
  825. //
  826. if( !LoadBackgroundTaskMgr() ) {
  827. error = ERROR_NOT_ENOUGH_MEMORY;
  828. //goto quit;
  829. }
  830. // Begin (a-thkesa)
  831. // Read GlobalBadProxyExpiresTime value from the registry.
  832. InternetReadRegistryDword("BadProxyExpiresTime", (LPDWORD)&GlobalBadProxyExpiresTime);
  833. // End (a-thkesa)
  834. quit:
  835. //
  836. // finally, if EnableHttp1_1 was set to non-zero in the registry, enable
  837. // HTTP 1.1
  838. //
  839. if (GlobalEnableHttp1_1) {
  840. HttpVersionInfo.dwMajorVersion = 1;
  841. HttpVersionInfo.dwMinorVersion = 1;
  842. }
  843. if (error == ERROR_SUCCESS) {
  844. GlobalDataInitialized = TRUE;
  845. }
  846. //
  847. // irrespective of success or failure, we have attempted global data
  848. // initialization. If we failed then we assume its something fundamental
  849. // and fatal: we don't try again
  850. //
  851. Initialized = TRUE;
  852. done:
  853. DEBUG_LEAVE(error);
  854. return error;
  855. }
  856. VOID
  857. GlobalDataReadWarningUIFlags(
  858. VOID
  859. )
  860. /*++
  861. Routine Description:
  862. Reads Registry values into global data.
  863. Used to read read the registry on connects.
  864. Arguments:
  865. None.
  866. Return Value:
  867. DWORD
  868. Success - ERROR_SUCCESS
  869. Failure - ERROR_NOT_ENOUGH_MEMORY
  870. --*/
  871. {
  872. DEBUG_ENTER((DBG_GLOBAL,
  873. None,
  874. "GlobalDataReadWarningUIFlags",
  875. NULL
  876. ));
  877. #ifndef WININET6
  878. //
  879. // Load SSL Values from the Registry on whether to pop up UI on error.
  880. //
  881. InternetReadRegistryDword("WarnOnPost", (LPDWORD)&GlobalWarnOnPost);
  882. GlobalWarnAlways = FALSE;
  883. InternetReadRegistryDword("WarnAlwaysOnPost", (LPDWORD)&GlobalWarnAlways);
  884. //
  885. // If Global Warn On Post is set to "2" we reset the "WarnAlways" to TRUE,
  886. // since this is the new way INETCPL reads/writes the registry.
  887. //
  888. if ( GlobalWarnOnPost == 2 )
  889. {
  890. GlobalWarnAlways = TRUE;
  891. }
  892. InternetReadRegistryDword("WarnOnZoneCrossing", (LPDWORD)&GlobalWarnOnZoneCrossing);
  893. InternetReadRegistryDword("WarnOnBadCertSending", (LPDWORD)&GlobalWarnOnBadCertSending);
  894. InternetReadRegistryDword("WarnOnBadCertRecving", (LPDWORD)&GlobalWarnOnBadCertRecving);
  895. InternetReadRegistryDword("WarnOnPostRedirect", (LPDWORD)&GlobalWarnOnPostRedirect);
  896. InternetReadRegistryDword("AlwaysDrainOnRedirect", (LPDWORD)&GlobalAlwaysDrainOnRedirect);
  897. InternetReadRegistryDword("WarnOnHTTPSToHTTPRedirect", (LPDWORD)&GlobalWarnOnHTTPSToHTTPRedirect);
  898. #else
  899. //
  900. // Load SSL Values from the Registry on whether to pop up UI on error.
  901. //
  902. InternetIDEReadRegistryDword("WarnOnPost", (LPDWORD)&GlobalWarnOnPost);
  903. GlobalWarnAlways = FALSE;
  904. InternetIDEReadRegistryDword("WarnAlwaysOnPost", (LPDWORD)&GlobalWarnAlways);
  905. //
  906. // If Global Warn On Post is set to "2" we reset the "WarnAlways" to TRUE,
  907. // since this is the new way INETCPL reads/writes the registry.
  908. //
  909. if ( GlobalWarnOnPost == 2 )
  910. {
  911. GlobalWarnAlways = TRUE;
  912. }
  913. InternetIDEReadRegistryDword("WarnOnZoneCrossing", (LPDWORD)&GlobalWarnOnZoneCrossing);
  914. InternetIDEReadRegistryDword("WarnOnBadCertSending", (LPDWORD)&GlobalWarnOnBadCertSending);
  915. InternetIDEReadRegistryDword("WarnOnBadCertRecving", (LPDWORD)&GlobalWarnOnBadCertRecving);
  916. InternetIDEReadRegistryDword("WarnOnPostRedirect", (LPDWORD)&GlobalWarnOnPostRedirect);
  917. InternetIDEReadRegistryDword("WarnOnHTTPSToHTTPRedirect", (LPDWORD)&GlobalWarnOnHTTPSToHTTPRedirect);
  918. #endif
  919. DEBUG_LEAVE(0);
  920. }
  921. VOID
  922. GlobalDataTerminate(
  923. VOID
  924. )
  925. /*++
  926. Routine Description:
  927. Undoes work of GlobalDataInitialize()
  928. Arguments:
  929. None.
  930. Return Value:
  931. None.
  932. --*/
  933. {
  934. DEBUG_ENTER((DBG_GLOBAL,
  935. None,
  936. "GlobalDataTerminate",
  937. NULL
  938. ));
  939. //
  940. // Release background task manager
  941. //
  942. UnloadBackgroundTaskMgr();
  943. PWC_Free(g_pwcUserAndPassword);
  944. AuthUnload();
  945. UrlZonesDetach();
  946. TerminateResolverCache();
  947. CloseTheCookieJar();
  948. if (GlobalSpecialDomains)
  949. {
  950. delete [] GlobalSpecialDomains;
  951. delete [] GlobalSDOffsets;
  952. }
  953. //
  954. // destroy lists created from registry
  955. //
  956. DestroyMimeExclusionTableForCache();
  957. DestroyHeaderExclusionTableForCache();
  958. //
  959. // terminate the global cert-cache and proxy lists
  960. //
  961. GlobalCertCache.Terminate();
  962. GlobalProxyInfo.TerminateProxySettings();
  963. //SaveServerInfoDatabase();
  964. PurgeServerInfoList(TRUE);
  965. //TerminateAsyncSupport();
  966. //
  967. // free up the handle to the startup mutex
  968. //
  969. if (g_hAutodialMutex) {
  970. CloseHandle(g_hAutodialMutex);
  971. }
  972. #if defined(SITARA)
  973. CloseIeMainKey();
  974. #endif // SITARA
  975. UnloadMlang();
  976. UnloadSecurity();
  977. GlobalDataInitialized = FALSE;
  978. DEBUG_LEAVE(0);
  979. }
  980. BOOL
  981. IsHttp1_1(
  982. VOID
  983. )
  984. /*++
  985. Routine Description:
  986. Determine if we are using HTTP 1.1 or greater
  987. Arguments:
  988. None.
  989. Return Value:
  990. BOOL
  991. --*/
  992. {
  993. return (HttpVersionInfo.dwMajorVersion > 1)
  994. ? TRUE
  995. : (((HttpVersionInfo.dwMajorVersion == 1)
  996. && (HttpVersionInfo.dwMajorVersion >= 1))
  997. ? TRUE
  998. : FALSE);
  999. }
  1000. BOOL
  1001. IsOffline(
  1002. VOID
  1003. )
  1004. /*++
  1005. Routine Description:
  1006. Returns whether we are in (global) offline mode or not. We are offline if
  1007. we went offline because of network failure, or we were put into offline
  1008. mode by the user
  1009. Arguments:
  1010. None.
  1011. Return Value:
  1012. BOOL
  1013. TRUE - we are currently offline
  1014. FALSE - not offline
  1015. --*/
  1016. {
  1017. DEBUG_ENTER((DBG_SESSION,
  1018. Bool,
  1019. "IsOffline",
  1020. NULL
  1021. ));
  1022. INET_ASSERT(((GlobalDllState & INTERNET_LINE_STATE_MASK) == INTERNET_STATE_ONLINE)
  1023. || ((GlobalDllState & INTERNET_LINE_STATE_MASK) == INTERNET_STATE_OFFLINE));
  1024. INET_ASSERT((GlobalDllState & INTERNET_STATE_OFFLINE_USER)
  1025. ? ((GlobalDllState & INTERNET_LINE_STATE_MASK) == INTERNET_STATE_OFFLINE)
  1026. : TRUE);
  1027. BOOL offline = (GlobalDllState & (INTERNET_STATE_OFFLINE | INTERNET_STATE_OFFLINE_USER))
  1028. ? TRUE
  1029. : FALSE;
  1030. DEBUG_LEAVE(offline);
  1031. return offline;
  1032. }
  1033. DWORD
  1034. SetOfflineUserState(
  1035. IN DWORD dwState,
  1036. IN BOOL bForce
  1037. )
  1038. /*++
  1039. Routine Description:
  1040. If we are in online state, puts Wininet into user-induced offline mode. Stop
  1041. all outstanding requests, if required and set the global scope. If we are in
  1042. offline mode, then change state to online
  1043. Arguments:
  1044. dwState - INTERNET_STATE_ONLINE or INTERNET_STATE_OFFLINE
  1045. bForce - TRUE if we are to forcibly complete all outstanding requests
  1046. (including synchronous requests)
  1047. Return Value:
  1048. DWORD
  1049. Success - ERROR_SUCCESS
  1050. Failure -
  1051. --*/
  1052. {
  1053. DEBUG_ENTER((DBG_GLOBAL,
  1054. Dword,
  1055. "SetOfflineUserState",
  1056. "%s (%d), %B",
  1057. (dwState == INTERNET_STATE_ONLINE) ? "INTERNET_STATE_ONLINE"
  1058. : (dwState == INTERNET_STATE_OFFLINE) ? "INTERNET_STATE_OFFLINE"
  1059. : "???",
  1060. dwState,
  1061. bForce
  1062. ));
  1063. INET_ASSERT((dwState == INTERNET_STATE_ONLINE)
  1064. || (dwState == INTERNET_STATE_OFFLINE));
  1065. INET_ASSERT(((GlobalDllState & INTERNET_LINE_STATE_MASK) == INTERNET_STATE_ONLINE)
  1066. || ((GlobalDllState & INTERNET_LINE_STATE_MASK) == INTERNET_STATE_OFFLINE));
  1067. DWORD error = ERROR_SUCCESS;
  1068. if (dwState == INTERNET_STATE_OFFLINE) {
  1069. GlobalDllState = (GlobalDllState & ~INTERNET_LINE_STATE_MASK)
  1070. | (INTERNET_STATE_OFFLINE | INTERNET_STATE_OFFLINE_USER);
  1071. if (bForce) {
  1072. //CancelActiveAsyncRequests(ERROR_INTERNET_OFFLINE);
  1073. CancelActiveSyncRequests(ERROR_INTERNET_OFFLINE);
  1074. GlobalProxyInfo.AbortAutoProxy();
  1075. }
  1076. } else {
  1077. GlobalDllState = GlobalDllState
  1078. & ~(INTERNET_LINE_STATE_MASK | INTERNET_STATE_OFFLINE_USER)
  1079. | INTERNET_STATE_ONLINE;
  1080. }
  1081. DEBUG_PRINT(GLOBAL,
  1082. INFO,
  1083. ("GlobalDllState = %#x\n",
  1084. GlobalDllState
  1085. ));
  1086. DEBUG_LEAVE(error);
  1087. return error;
  1088. }
  1089. /*++
  1090. FetchLocalStrings:
  1091. This routine fetches the strings necessary to display information in the
  1092. language of the local user.
  1093. Arguments:
  1094. None
  1095. Return Value:
  1096. The address of a LOCAL_STRINGS structure containing the addresses of the
  1097. localized strings to display.
  1098. Author:
  1099. Doug Barlow (dbarlow) 4/25/1996
  1100. --*/
  1101. //
  1102. // WARNING! The order of elements in the following array must match the
  1103. // order of elements in the LOCAL_STRINGS structure.
  1104. //
  1105. static const UINT
  1106. uStringId[]
  1107. = { IDS_LW95_ENTERAUTHINFO,
  1108. IDS_SECERT_CERTINFO,
  1109. IDS_SECERT_STRENGTH_HIGH,
  1110. IDS_SECERT_STRENGTH_MEDIUM,
  1111. IDS_SECERT_STRENGTH_LOW,
  1112. IDS_CERT_SUBJECT,
  1113. IDS_CERT_ISSUER,
  1114. IDS_CERT_EFFECTIVE_DATE,
  1115. IDS_CERT_EXPIRATION_DATE,
  1116. IDS_CERT_PROTOCOL,
  1117. IDS_CERT_USAGE,
  1118. IDS_CERT_ENCRYPT_ALG,
  1119. IDS_CERT_HASH_ALG,
  1120. IDS_CERT_EXCH_ALG,
  1121. IDS_CERT_COMMENT,
  1122. IDS_COMMENT_EXPIRES,
  1123. IDS_COMMENT_NOT_VALID,
  1124. IDS_COMMENT_BAD_CN,
  1125. IDS_COMMENT_BAD_CA,
  1126. IDS_COMMENT_BAD_SIGNATURE,
  1127. IDS_COMMENT_REVOKED,
  1128. IDS_STRING_CIPHMSG,
  1129. IDS_STRING_HASHMSG,
  1130. IDS_STRING_EXCHMSG,
  1131. IDS_CERT_FINGERPRINT,
  1132. IDS_DOMAIN,
  1133. IDS_REALM,
  1134. IDS_SITE,
  1135. IDS_FIREWALL
  1136. };
  1137. PLOCAL_STRINGS
  1138. FetchLocalStrings(
  1139. void)
  1140. {
  1141. static LOCAL_STRINGS
  1142. lszStrings;
  1143. static BOOL fInitialized = FALSE;
  1144. INET_ASSERT(sizeof(uStringId) == offsetof(LOCAL_STRINGS, rgchBuffer));
  1145. EnterCriticalSection(&GeneralInitCritSec);
  1146. __try
  1147. {
  1148. if (!fInitialized)
  1149. {
  1150. LPWSTR szBufEntry;
  1151. LPWSTR *pszName;
  1152. DWORD dwOffset;
  1153. DWORD index, len;
  1154. //
  1155. // It needs to be initialized.
  1156. //
  1157. pszName = (LPWSTR *)&lszStrings;
  1158. dwOffset = 0;
  1159. for (index = 0;
  1160. index < sizeof(uStringId) / sizeof(UINT);
  1161. index += 1)
  1162. {
  1163. szBufEntry = &lszStrings.rgchBuffer[dwOffset];
  1164. len = LoadStringWrapW(
  1165. GlobalDllHandle,
  1166. uStringId[index],
  1167. szBufEntry,
  1168. LOCAL_STRINGS_MAX_BUFFER - dwOffset);
  1169. INET_ASSERT(0 != len); // Resource missing!
  1170. dwOffset += len;
  1171. lszStrings.rgchBuffer[dwOffset++] = 0;
  1172. *pszName++ = szBufEntry;
  1173. }
  1174. INET_ASSERT(LOCAL_STRINGS_MAX_BUFFER > dwOffset);
  1175. //
  1176. // Make it available to this and future callers.
  1177. //
  1178. fInitialized = TRUE;
  1179. }
  1180. }
  1181. __finally
  1182. {
  1183. LeaveCriticalSection(&GeneralInitCritSec);
  1184. }
  1185. ENDFINALLY
  1186. return &lszStrings;
  1187. }
  1188. PLOCAL_STRINGSA
  1189. FetchLocalStringsA(
  1190. void)
  1191. {
  1192. static LOCAL_STRINGSA
  1193. lszStrings;
  1194. static BOOL fInitialized = FALSE;
  1195. INET_ASSERT(sizeof(uStringId) == offsetof(LOCAL_STRINGSA, rgchBuffer));
  1196. EnterCriticalSection(&GeneralInitCritSec);
  1197. __try
  1198. {
  1199. if (!fInitialized)
  1200. {
  1201. LPSTR szBufEntry;
  1202. LPSTR *pszName;
  1203. DWORD dwOffset;
  1204. DWORD index, len;
  1205. //
  1206. // It needs to be initialized.
  1207. //
  1208. pszName = (LPSTR *)&lszStrings;
  1209. dwOffset = 0;
  1210. for (index = 0;
  1211. index < sizeof(uStringId) / sizeof(UINT);
  1212. index += 1)
  1213. {
  1214. szBufEntry = &lszStrings.rgchBuffer[dwOffset];
  1215. len = LoadStringA(
  1216. GlobalDllHandle,
  1217. uStringId[index],
  1218. szBufEntry,
  1219. LOCAL_STRINGS_MAX_BUFFER - dwOffset);
  1220. INET_ASSERT(0 != len); // Resource missing!
  1221. dwOffset += len;
  1222. lszStrings.rgchBuffer[dwOffset++] = 0;
  1223. *pszName++ = szBufEntry;
  1224. }
  1225. INET_ASSERT(LOCAL_STRINGS_MAX_BUFFER > dwOffset);
  1226. //
  1227. // Make it available to this and future callers.
  1228. //
  1229. fInitialized = TRUE;
  1230. }
  1231. }
  1232. __finally
  1233. {
  1234. LeaveCriticalSection(&GeneralInitCritSec);
  1235. }
  1236. ENDFINALLY
  1237. return &lszStrings;
  1238. }
  1239. BOOL
  1240. GetWininetUserName(
  1241. VOID
  1242. )
  1243. {
  1244. BOOL fRet = FALSE;
  1245. DWORD dwT;
  1246. CHAR *ptr;
  1247. // Note this critsect could be blocked for a while if RPC gets involved...
  1248. EnterCriticalSection(&GeneralInitCritSec);
  1249. if (vdwCurrentUserLen) {
  1250. fRet = TRUE;
  1251. goto Done;
  1252. }
  1253. dwT = sizeof(vszCurrentUser);
  1254. if (vfPerUserCookies) {
  1255. fRet = GetUserName(vszCurrentUser, &dwT);
  1256. if (!fRet) {
  1257. DEBUG_PRINT(HTTP,
  1258. ERROR,
  1259. ("GetUsername returns %d\n",
  1260. GetLastError()
  1261. ));
  1262. }
  1263. }
  1264. if (fRet == FALSE){
  1265. strcpy(vszCurrentUser, vszAnyUserName);
  1266. fRet = TRUE;
  1267. }
  1268. // Downcase the username.
  1269. ptr = vszCurrentUser;
  1270. while (*ptr)
  1271. {
  1272. /* BUGBUG: This logic mangles the user name when
  1273. there are multi-byte characters.
  1274. Unfortunately fixing it would lose legacy cookies so the
  1275. fix had to be backed out.
  1276. The correct code is commented out below. */
  1277. *ptr = tolower(*ptr);
  1278. ptr++;
  1279. // if (!IsDBCSLeadByte(*ptr))
  1280. // *ptr = tolower(*ptr);
  1281. // ptr = CharNextExA(CP_ACP, ptr, 0);
  1282. }
  1283. INET_ASSERT(fRet == TRUE);
  1284. vdwCurrentUserLen = (DWORD) (ptr - vszCurrentUser);
  1285. Done:
  1286. LeaveCriticalSection(&GeneralInitCritSec);
  1287. return (fRet);
  1288. }
  1289. VOID
  1290. ChangeGlobalSettings(
  1291. VOID
  1292. )
  1293. /*++
  1294. Routine Description:
  1295. Changes global settings
  1296. Arguments:
  1297. None.
  1298. Return Value:
  1299. None.
  1300. --*/
  1301. {
  1302. DEBUG_ENTER((DBG_GLOBAL,
  1303. None,
  1304. "ChangeGlobalSettings",
  1305. NULL
  1306. ));
  1307. InternetReadRegistryDword(vszSyncMode,
  1308. &GlobalUrlCacheSyncMode
  1309. );
  1310. InternetReadRegistryDword(vszDisableSslCaching,
  1311. (LPDWORD)&GlobalDisableSslCaching
  1312. );
  1313. InternetReadRegistryDword("EnableHttp1_1",
  1314. (LPDWORD)&GlobalEnableHttp1_1
  1315. );
  1316. InternetReadRegistryDword("ProxyHttp1.1",
  1317. (LPDWORD)&GlobalEnableProxyHttp1_1
  1318. );
  1319. InternetReadRegistryDword(vszPerUserCookies,
  1320. (LPDWORD)&vfPerUserCookies
  1321. );
  1322. InternetReadRegistryDword(vszLeashLegacyCookies, (LPDWORD)&GlobalLeashLegacyCookies);
  1323. if (!GlobalProxyInfo.IsModifiedInProcess())
  1324. {
  1325. FixProxySettingsForCurrentConnection(
  1326. FALSE
  1327. );
  1328. }
  1329. //
  1330. // update security protocol changes.
  1331. //
  1332. InternetReadRegistryDword("SecureProtocols",
  1333. (LPDWORD)&GlobalSecureProtocols
  1334. );
  1335. if (!GlobalPlatformWhistler)
  1336. {
  1337. // Fortezza support has been removed from XP
  1338. InternetReadRegistryDword("Fortezza",
  1339. (LPDWORD)&GlobalEnableFortezza
  1340. );
  1341. }
  1342. else
  1343. {
  1344. GlobalEnableFortezza = FALSE;
  1345. }
  1346. InternetReadRegistryDword("CertificateRevocation",
  1347. (LPDWORD)&GlobalEnableRevocation
  1348. );
  1349. //
  1350. // Check autodial settings and hang up if autodial was turned off
  1351. //
  1352. // have autodial module reset itself
  1353. ResetAutodialModule();
  1354. RefreshOfflineFromRegistry();
  1355. // force reload of cookie-settings from registry by flushing memory cache
  1356. RefreshP3PSettings();
  1357. DEBUG_LEAVE(0);
  1358. }
  1359. VOID
  1360. RefreshOfflineFromRegistry(
  1361. VOID
  1362. )
  1363. /*++
  1364. Routine Description:
  1365. Reads offline setting in the registry and sets wininet's offline mode
  1366. accordingly.
  1367. Arguments:
  1368. None.
  1369. Return Value:
  1370. None.
  1371. --*/
  1372. {
  1373. DEBUG_ENTER((DBG_GLOBAL,
  1374. None,
  1375. "RefreshOfflineFromRegistry",
  1376. NULL
  1377. ));
  1378. DWORD dwTemp = 0;
  1379. // note: this won't alter dwTemp if not found and so will default to
  1380. // online
  1381. InternetReadRegistryDword("GlobalUserOffline", &dwTemp);
  1382. // convert to appropriate flags
  1383. if(0 == dwTemp) {
  1384. // online
  1385. dwTemp = INTERNET_STATE_ONLINE;
  1386. } else {
  1387. // offline
  1388. dwTemp = INTERNET_STATE_OFFLINE;
  1389. }
  1390. SetOfflineUserState(dwTemp, FALSE);
  1391. DEBUG_LEAVE(0);
  1392. }
  1393. VOID
  1394. PerformStartupProcessing(
  1395. VOID
  1396. )
  1397. /*++
  1398. Routine Description:
  1399. Performs actions exactly once on system startup. Resets offline mode.
  1400. Arguments:
  1401. None.
  1402. Return Value:
  1403. None.
  1404. --*/
  1405. {
  1406. DEBUG_ENTER((DBG_GLOBAL,
  1407. None,
  1408. "PerformStartupProcessing",
  1409. NULL
  1410. ));
  1411. INET_ASSERT(NULL == g_hAutodialMutex);
  1412. g_hAutodialMutex = OpenMutex(SYNCHRONIZE, FALSE, WININET_STARTUP_MUTEX);
  1413. if (g_hAutodialMutex == NULL && (GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_NAME))
  1414. {
  1415. SECURITY_ATTRIBUTES* psa = SHGetAllAccessSA();
  1416. if (psa)
  1417. {
  1418. g_hAutodialMutex = CreateMutex(psa, FALSE, WININET_STARTUP_MUTEX);
  1419. }
  1420. }
  1421. if(g_hAutodialMutex) {
  1422. DWORD dwLastError = GetLastError();
  1423. if(ERROR_SUCCESS == dwLastError) {
  1424. // GetLastError returns ERROR_ALREADY_EXISTS if the mutex existed
  1425. // before we created it. If we don't get this error, we're the
  1426. // first so proceed with out startup processing
  1427. if(!GlobalPlatformVersion5)
  1428. {
  1429. // Reset global offline mode on non-Win2K platforms
  1430. InternetWriteRegistryDword("GlobalUserOffline", 0);
  1431. }
  1432. }
  1433. }
  1434. DEBUG_LEAVE(0);
  1435. }
  1436. #if defined(SITARA)
  1437. PRIVATE HKEY IeMainKey = NULL;
  1438. PRIVATE
  1439. VOID
  1440. OpenIeMainKey(
  1441. VOID
  1442. )
  1443. {
  1444. if (RegOpenKeyEx(HKEY_CURRENT_USER,
  1445. "Software\\Microsoft\\Internet Explorer\\Main",
  1446. 0,
  1447. KEY_QUERY_VALUE,
  1448. &IeMainKey
  1449. ) != ERROR_SUCCESS) {
  1450. IeMainKey = NULL;
  1451. }
  1452. }
  1453. PRIVATE
  1454. VOID
  1455. CloseIeMainKey(
  1456. VOID
  1457. )
  1458. {
  1459. if (IeMainKey != NULL) {
  1460. REGCLOSEKEY(IeMainKey);
  1461. IeMainKey = NULL;
  1462. }
  1463. }
  1464. DWORD
  1465. GetSitaraProtocol(
  1466. VOID
  1467. )
  1468. {
  1469. DEBUG_ENTER((DBG_SOCKETS,
  1470. Int,
  1471. "GetSitaraProtocol",
  1472. NULL
  1473. ));
  1474. DWORD dwProtocol = IPPROTO_TCP;
  1475. DWORD dwEnabled = 0;
  1476. if (ReadIeMainDwordValue("Use_Express_Lane", &dwEnabled) && (dwEnabled != 0)) {
  1477. dwProtocol = 901;
  1478. }
  1479. DEBUG_LEAVE(dwProtocol);
  1480. return dwProtocol;
  1481. }
  1482. PRIVATE
  1483. BOOL
  1484. CheckABS(
  1485. VOID
  1486. )
  1487. {
  1488. DEBUG_ENTER((DBG_SOCKETS,
  1489. Bool,
  1490. "CheckABS",
  1491. NULL
  1492. ));
  1493. BOOL on = 0;
  1494. ReadIeMainDwordValue("ABS", (LPDWORD)&on);
  1495. DEBUG_LEAVE(!on);
  1496. return !on;
  1497. }
  1498. PRIVATE
  1499. BOOL
  1500. ReadIeMainDwordValue(
  1501. IN LPSTR pszValueName,
  1502. OUT LPDWORD pdwValue
  1503. )
  1504. {
  1505. if (IeMainKey != NULL) {
  1506. DWORD value;
  1507. DWORD valueType;
  1508. DWORD valueLength = sizeof(value);
  1509. DWORD err = RegQueryValueEx(IeMainKey,
  1510. pszValueName,
  1511. NULL,
  1512. &valueType,
  1513. (LPBYTE)&value,
  1514. &valueLength
  1515. );
  1516. if ((err == ERROR_SUCCESS)
  1517. && ((valueType == REG_DWORD) || (valueType == REG_BINARY))
  1518. && (valueLength == sizeof(DWORD))) {
  1519. *pdwValue = value;
  1520. return TRUE;
  1521. }
  1522. }
  1523. return FALSE;
  1524. }
  1525. #endif // SITARA
  1526. // Loads Mlang.dll and get the entry point we are interested in.
  1527. BOOL LoadMlang( )
  1528. {
  1529. EnterCriticalSection(&MlangCritSec);
  1530. if (hInstMlang == NULL && !bFailedMlangLoad)
  1531. {
  1532. INET_ASSERT(pfnInetMultiByteToUnicode == NULL);
  1533. hInstMlang = LoadLibrary(MLANGDLLNAME);
  1534. if (hInstMlang != NULL)
  1535. {
  1536. pfnInetMultiByteToUnicode = (PFNINETMULTIBYTETOUNICODE)GetProcAddress
  1537. (hInstMlang,"ConvertINetMultiByteToUnicode");
  1538. if (pfnInetMultiByteToUnicode == NULL)
  1539. {
  1540. INET_ASSERT(FALSE);
  1541. FreeLibrary(hInstMlang);
  1542. hInstMlang = NULL;
  1543. }
  1544. }
  1545. else
  1546. {
  1547. INET_ASSERT(FALSE); // bad news if we can't load mlang.dll
  1548. }
  1549. if (pfnInetMultiByteToUnicode == NULL)
  1550. bFailedMlangLoad = TRUE;
  1551. }
  1552. LeaveCriticalSection(&MlangCritSec);
  1553. return (pfnInetMultiByteToUnicode != NULL);
  1554. }
  1555. BOOL UnloadMlang( )
  1556. {
  1557. EnterCriticalSection(&MlangCritSec);
  1558. if (hInstMlang)
  1559. FreeLibrary(hInstMlang);
  1560. hInstMlang = NULL;
  1561. pfnInetMultiByteToUnicode = NULL;
  1562. bFailedMlangLoad = FALSE;
  1563. LeaveCriticalSection(&MlangCritSec);
  1564. return TRUE;
  1565. }
  1566. PFNINETMULTIBYTETOUNICODE GetInetMultiByteToUnicode( )
  1567. {
  1568. // We are checking for pfnInetMultiByteToUnicode without getting a crit section.
  1569. // This works only because UnloadMlang is called at the Dll unload time.
  1570. if (pfnInetMultiByteToUnicode == NULL)
  1571. {
  1572. LoadMlang( );
  1573. }
  1574. return pfnInetMultiByteToUnicode;
  1575. }