/*++ Copyright (c) 1995 Microsoft Corporation Module Name: globals.cxx Abstract: Contains global data items for WININET.DLL and initialization function Contents: GlobalDllInitialize GlobalDllTerminate GlobalDataInitialize GlobalTruncateFileName; GlobalDataTerminate IsHttp1_1 IsOffline SetOfflineUserState FetchLocalStrings GetWininetUserName ChangeGlobalSettings RefreshOfflineFromRegistry PerformStartupProcessing Author: Richard L Firth (rfirth) 15-Jul-1995 Revision History: 15-Jul-1995 rfirth Created 07-Oct-1998 joshco updated minor version number 1->2 --*/ #include #include #include // InitAutodialModule, ExitAutodialModule #include #include // // WinInet major & minor versions - allow to be defined externally // // JOSHCO #if !defined(WININET_MAJOR_VERSION) #define WININET_MAJOR_VERSION 1 #endif #if !defined(WININET_MINOR_VERSION) #define WININET_MINOR_VERSION 2 #endif // // external functions // void RefreshP3PSettings(); STDAPI_(void) UrlZonesDetach (void); #if INET_DEBUG VOID InitDebugSock( VOID ); #endif // // private prototypes // #if defined(SITARA) PRIVATE VOID OpenIeMainKey( VOID ); PRIVATE VOID CloseIeMainKey( VOID ); PRIVATE BOOL CheckABS( VOID ); PRIVATE BOOL ReadIeMainDwordValue( IN LPSTR pszValueName, OUT LPDWORD pdwValue ); #endif // SITARA // // global DLL state data // GLOBAL HINSTANCE GlobalDllHandle = NULL; GLOBAL DWORD GlobalPlatformType; GLOBAL DWORD GlobalPlatformVersion5; GLOBAL DWORD GlobalPlatformMillennium = FALSE; GLOBAL DWORD GlobalPlatformWhistler = FALSE; GLOBAL DWORD GlobalDllState = INTERNET_STATE_ONLINE | INTERNET_STATE_IDLE; GLOBAL BOOL GlobalDataInitialized = FALSE; GLOBAL BOOL GlobalTruncateFileName = FALSE; // // WinInet DLL version information (mainly for diagnostics) // #if INET_DEBUG GLOBAL DWORD InternetMajorVersion = 1; GLOBAL DWORD InternetMinorVersion = 0; #endif // INET_DEBUG #if !defined(VER_PRODUCTBUILD) #define VER_PRODUCTBUILD 0 #endif GLOBAL DWORD InternetBuildNumber = VER_PRODUCTBUILD; // // transport-based time-outs, etc. // //GLOBAL DWORD GlobalConnectTimeout = DEFAULT_CONNECT_TIMEOUT; #ifndef unix GLOBAL DWORD GlobalConnectTimeout = 5 * 60 * 1000; #else GLOBAL DWORD GlobalConnectTimeout = 1 * 60 * 1000; #endif /* unix */ GLOBAL DWORD GlobalConnectRetries = DEFAULT_CONNECT_RETRIES; GLOBAL DWORD GlobalSendTimeout = DEFAULT_SEND_TIMEOUT; GLOBAL DWORD GlobalReceiveTimeout = DEFAULT_RECEIVE_TIMEOUT; GLOBAL DWORD GlobalDataSendTimeout = DEFAULT_SEND_TIMEOUT; GLOBAL DWORD GlobalDataReceiveTimeout = DEFAULT_RECEIVE_TIMEOUT; GLOBAL DWORD GlobalFromCacheTimeout = (DWORD)-1; GLOBAL DWORD GlobalFtpAcceptTimeout = DEFAULT_FTP_ACCEPT_TIMEOUT; GLOBAL DWORD GlobalTransportPacketLength = DEFAULT_TRANSPORT_PACKET_LENGTH; GLOBAL DWORD GlobalKeepAliveSocketTimeout = DEFAULT_KEEP_ALIVE_TIMEOUT; GLOBAL DWORD GlobalSocketSendBufferLength = DEFAULT_SOCKET_SEND_BUFFER_LENGTH; GLOBAL DWORD GlobalSocketReceiveBufferLength = DEFAULT_SOCKET_RECEIVE_BUFFER_LENGTH; GLOBAL DWORD GlobalMaxHttpRedirects = DEFAULT_MAX_HTTP_REDIRECTS; GLOBAL DWORD GlobalMaxConnectionsPerServer = DEFAULT_MAX_CONNECTIONS_PER_SERVER; GLOBAL DWORD GlobalMaxConnectionsPer1_0Server = DEFAULT_MAX_CONS_PER_1_0_SERVER; GLOBAL DWORD GlobalConnectionInactiveTimeout = DEFAULT_CONNECTION_INACTIVE_TIMEOUT; GLOBAL DWORD GlobalServerInfoTimeout = DEFAULT_SERVER_INFO_TIMEOUT; GLOBAL const DWORD GlobalMaxSizeStatusLineResultText = 1024; GLOBAL BOOL GlobalHaveInternetOpened = FALSE; GLOBAL BOOL GlobalBypassEditedEntry = FALSE; GLOBAL DWORD GlobalCacheMode = 0; //GLOBAL DWORD GlobalServerInfoAllocCount = 0; //GLOBAL DWORD GlobalServerInfoDeAllocCount = 0; // // async worker thread variables // //GLOBAL DWORD GlobalMinimumWorkerThreads = DEFAULT_MINIMUM_THREADS; //GLOBAL DWORD GlobalMaximumWorkerThreads = DEFAULT_MAXIMUM_THREADS; //GLOBAL DWORD GlobalInitialWorkerThreads = DEFAULT_INITIAL_THREADS; //GLOBAL DWORD GlobalWorkerThreadIdleTimeout = DEFAULT_THREAD_IDLE_TIMEOUT; //GLOBAL DWORD GlobalWorkQueueLimit = DEFAULT_WORK_QUEUE_LIMIT; GLOBAL DWORD GlobalWorkerThreadTimeout = DEFAULT_WORKER_THREAD_TIMEOUT; GLOBAL BOOL g_bHibernating = FALSE; GLOBAL BOOL g_bDisableHibernation = FALSE; // // switches // GLOBAL BOOL InDllCleanup = FALSE; GLOBAL BOOL GlobalPleaseQuitWhatYouAreDoing = FALSE; GLOBAL BOOL GlobalDynaUnload = FALSE; GLOBAL BOOL GlobalDisableKeepAlive = FALSE; GLOBAL BOOL GlobalDisablePassport = FALSE; GLOBAL BOOL GlobalEnableHttp1_1 = FALSE; GLOBAL BOOL GlobalEnableProxyHttp1_1 = FALSE; GLOBAL BOOL GlobalDisableReadRange = FALSE; GLOBAL BOOL GlobalEnableGopher = FALSE; //GLOBAL BOOL GlobalAutoProxyInDeInit = FALSE; GLOBAL BOOL GlobalIsProcessExplorer = FALSE; #ifndef UNIX GLOBAL BOOL GlobalEnableFortezza = TRUE; #else /* for UNIX */ GLOBAL BOOL GlobalEnableFortezza = FALSE; #endif /* UNIX */ #if defined(SITARA) GLOBAL BOOL GlobalEnableSitara = FALSE; GLOBAL BOOL GlobalHasSitaraModemConn = FALSE; #endif // SITARA GLOBAL BOOL GlobalEnableUtf8Encoding = FALSE; GLOBAL BOOL GlobalEnableRevocation = FALSE; // SSL Switches (petesk 7/24/97) GLOBAL DWORD GlobalSecureProtocols = DEFAULT_SECURE_PROTOCOLS; GLOBAL DWORD GlobalSslStateCount = 0; // // AutoDetect Proxy Globals // GLOBAL LONG GlobalInternetOpenHandleCount = -1; GLOBAL DWORD GlobalProxyVersionCount = 0; GLOBAL BOOL GlobalAutoProxyNeedsInit = FALSE; GLOBAL BOOL GlobalAutoProxyInInit = FALSE; GLOBAL BOOL GlobalAutoProxyCacheEnable = TRUE; GLOBAL BOOL GlobalDisplayScriptDownloadFailureUI = FALSE; GLOBAL BOOL GlobalSendUTF8ServerToProxy = TRUE; GLOBAL BOOL GlobalMBCSAPIforCrack = TRUE; GLOBAL BOOL GlobalUseUTF8ServerForNameRes = FALSE; // // Workaround for Novell's Client32 // GLOBAL BOOL fDontUseDNSLoadBalancing = FALSE; // // Workaround for slow RAS enumeration // GLOBAL BOOL GlobalDisableNT4RasCheck = FALSE; GLOBAL BOOL GlobalUseLanSettings = FALSE; GLOBAL BOOL GlobalSendExtraCRLF = TRUE; //Ftp time checking GLOBAL BOOL GlobalBypassFtpTimeCheck = FALSE; // // lists // GLOBAL SERIALIZED_LIST GlobalObjectList = {0}; GLOBAL SERIALIZED_LIST GlobalServerInfoList = {0}; // // cache timeouts // GLOBAL LONGLONG dwdwHttpDefaultExpiryDelta = 12 * 60 * 60 * (LONGLONG)10000000; // 12 hours in 100ns units GLOBAL LONGLONG dwdwFtpDefaultExpiryDelta = 24 * 60 * 60 * (LONGLONG)10000000; // 24 hours in 100ns units GLOBAL LONGLONG dwdwGopherDefaultExpiryDelta = 24 * 60 * 60 * (LONGLONG)10000000; // 24 hours in 100ns units GLOBAL LONGLONG dwdwSessionStartTime; GLOBAL LONGLONG dwdwSessionStartTimeDefaultDelta = 0; GLOBAL DWORD GlobalUrlCacheSyncMode = WININET_SYNC_MODE_DEFAULT; GLOBAL DWORD GlobalDiskUsageLowerBound = (4*1024*1024); GLOBAL DWORD GlobalScavengeFileLifeTime = (10*60); GLOBAL LPSTR vszMimeExclusionList=NULL, vszHeaderExclusionList=NULL; GLOBAL LPSTR *lpvrgszMimeExclusionTable=NULL, *lpvrgszHeaderExclusionTable=NULL; GLOBAL DWORD *lpvrgdwMimeExclusionTableOfSizes=NULL; GLOBAL DWORD vdwMimeExclusionTableCount=0, vdwHeaderExclusionTableCount=0; // // SSL globals, for UI. We need to know // whether its ok for us to pop up UI. // // GLOBAL BOOL GlobalWarnOnPost = FALSE; GLOBAL BOOL GlobalWarnAlways = FALSE; GLOBAL BOOL GlobalWarnOnZoneCrossing = TRUE; GLOBAL BOOL GlobalWarnOnBadCertSending = FALSE; GLOBAL BOOL GlobalWarnOnBadCertRecving = TRUE; GLOBAL BOOL GlobalDisableSslCaching = FALSE; GLOBAL BOOL GlobalWarnOnPostRedirect = TRUE; GLOBAL BOOL GlobalAlwaysDrainOnRedirect = FALSE; GLOBAL BOOL GlobalBypassSSLNoCacheCheck = FALSE; GLOBAL BOOL GlobalWarnOnHTTPSToHTTPRedirect = TRUE; GLOBAL SECURITY_CACHE_LIST GlobalCertCache; GLOBAL DWORD GlobalSettingsVersion=0; // crossprocess settings versionstamp GLOBAL BOOL GlobalSettingsLoaded = FALSE; GLOBAL const char vszSyncMode[] = "SyncMode5"; GLOBAL const char vszDisableSslCaching[] = "DisableCachingOfSSLPages"; GLOBAL BOOL GlobalDisableNTLMPreAuth = FALSE; GLOBAL char vszCurrentUser[MAX_PATH]; GLOBAL DWORD vdwCurrentUserLen = 0; // // critical sections // GLOBAL CRITICAL_SECTION AutoProxyDllCritSec = {0}; GLOBAL CRITICAL_SECTION LockRequestFileCritSec = {0}; GLOBAL CRITICAL_SECTION ZoneMgrCritSec = {0}; GLOBAL CRITICAL_SECTION MlangCritSec = {0}; // cookies info GLOBAL BOOL vfPerUserCookies = TRUE; const char vszAnyUserName[]="anyuser"; const char vszPerUserCookies[] = "PerUserCookies"; const char vszInvalidFilenameChars[] = "<>\\\"/:|?*"; GLOBAL BOOL GlobalLeashLegacyCookies = TRUE; const char vszLeashLegacyCookies[] = REGSTR_LEASH_LEGACY_COOKIES; // Hard-coded user agent string // Update for each different version of IE #if defined(UNIX) const char gszDefaultUserAgent[] = "Mozilla/4.0 (compatible; MSIE 6.0; X11)"; #elif defined(_WIN64) const char gszDefaultUserAgent[] = "Mozilla/4.0 (compatible; MSIE 6.0; Win64)"; #else const char gszDefaultUserAgent[] = "Mozilla/4.0 (compatible; MSIE 6.0; Win32)"; #endif // Mlang related data and functions. PRIVATE HINSTANCE hInstMlang; PRIVATE PFNINETMULTIBYTETOUNICODE pfnInetMultiByteToUnicode; PRIVATE BOOL bFailedMlangLoad; // So we don't try repeatedly if we fail once. BOOL LoadMlang( ); BOOL UnloadMlang( ); #define MLANGDLLNAME "mlang.dll" // shfolder.dll hmod handle HMODULE g_HMODSHFolder = NULL; // Shell32.dll hmod handle HMODULE g_HMODShell32 = NULL; GLOBAL CUserName GlobalUserName; // // novell client32 (hack) "support" // GLOBAL BOOL GlobalRunningNovellClient32 = FALSE; GLOBAL BOOL GlobalNonBlockingClient32 = FALSE; // // private data // HANDLE g_hAutodialMutex = NULL; // // proxy info // GLOBAL PROXY_INFO_GLOBAL GlobalProxyInfo; // // DLL version info // GLOBAL INTERNET_VERSION_INFO InternetVersionInfo = { WININET_MAJOR_VERSION, WININET_MINOR_VERSION }; // // HTTP version info - default 1.0 // GLOBAL HTTP_VERSION_INFO HttpVersionInfo = {1, 0}; GLOBAL BOOL fCdromDialogActive = FALSE; GLOBAL DWORD g_dwCredPersistAvail = CRED_PERSIST_UNKNOWN; // // The following globals are literal strings passed to winsock. // Do NOT make them const, otherwise they end up in .text section, // and web release of winsock2 has a bug where it locks and dirties // send buffers, confusing the win95 vmm and resulting in code // getting corrupted when it is paged back in. -RajeevD // GLOBAL char gszAt[] = "@"; GLOBAL char gszBang[] = "!"; GLOBAL char gszCRLF[] = "\r\n"; extern GLOBAL SERIALIZED_LIST BlockedRequestQueue; // Identity-related globals GLOBAL DWORD GlobalIdentity = 0; GLOBAL GUID GlobalIdentityGuid = { 0x00000000L, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; GLOBAL BOOL GlobalSuppressCookiesPolicy = FALSE; #ifdef WININET6 GLOBAL HKEY GlobalCacheHKey = HKEY_CURRENT_USER; #endif GLOBAL PTSTR GlobalSpecialDomains = NULL; GLOBAL PTSTR *GlobalSDOffsets = NULL; // auth globals DWORD GlobalEnableNegotiate = FALSE; // Nt service loading wininet. This triggers special semantics for webdav redir to avoid deadlocks // due to crossprocessmutexes being taken (ConnectionMutex is a good example of that) // (Shishir Pardikar) GLOBAL BOOL GlobalIsProcessNtService = FALSE; // Global Cred hack for Mars V2 PWC * g_pwcUserAndPassword; // Begin (a-thkesa) // The following global added to read expire time value from registry:Default is 30 Min // See Windows Bug:557284/WinSE:23879 // Declared in proxysup.hxx GLOBAL DWORD GlobalBadProxyExpiresTime = 30*60; // this will be multiplied // End(a-thkesa) BOOL g_fHasCredsTimestamp; SYSTEMTIME g_TimeCredsEntered; void SetUserOrPass (LPSTR lpszIn, BOOL fUser) { if (NULL == g_pwcUserAndPassword) { g_pwcUserAndPassword = PWC_Create(NULL, 0, NULL, NULL, NULL); } if (g_pwcUserAndPassword) { AuthLock(); if (fUser) { g_pwcUserAndPassword->SetUser(lpszIn); } else { g_pwcUserAndPassword->SetPass(lpszIn); } AuthUnlock(); } } void TimeStampCreds(void) { ::GetSystemTime(&g_TimeCredsEntered); // time-stamp the creds g_fHasCredsTimestamp = TRUE; } PSYSTEMTIME GetCredTimeStamp (void) { if (g_fHasCredsTimestamp) { return &g_TimeCredsEntered; } else { return NULL; } } BOOL GetUserAndPass (LPSTR *pszUser, LPSTR *pszPass) { if (g_pwcUserAndPassword) { if (g_pwcUserAndPassword->lpszUser && g_pwcUserAndPassword->lpszPass) { *pszUser = g_pwcUserAndPassword->GetUser(); *pszPass = g_pwcUserAndPassword->GetPass(); return TRUE; } } *pszUser = *pszPass = NULL; return FALSE; } // // functions // #ifdef UNIX extern "C" #endif /* UNIX */ VOID GlobalDllInitialize( VOID ) /*++ Routine Description: The set of initializations - critical sections, etc. - that must be done at DLL_PROCESS_ATTACH Arguments: None. Return Value: None. --*/ { DEBUG_ENTER((DBG_GLOBAL, None, "GlobalDllInitialize", NULL )); CLEAR_DEBUG_CRIT(szDebugBlankBuffer); GetCurrentGmtTime((LPFILETIME)&dwdwSessionStartTime); InitializeCriticalSection(&AutoProxyDllCritSec); InitializeCriticalSection(&LockRequestFileCritSec); InitializeCriticalSection(&ZoneMgrCritSec); InitializeCriticalSection(&MlangCritSec); InitializeSerializedList(&GlobalObjectList); InitializeSerializedList(&GlobalServerInfoList); InitializeSerializedList(&BlockedRequestQueue); AuthOpen(); IwinsockInitialize(); SecurityInitialize(); FtpInitialize(); GopherInitialize(); // // initialize cache critical sections etc. // DLLUrlCacheEntry(DLL_PROCESS_ATTACH); EnsureInternetSettingsKeyCached(); DEBUG_LEAVE(0); } #ifdef UNIX extern "C" #endif /* UNIX */ VOID GlobalDllTerminate( VOID ) /*++ Routine Description: Undoes the initializations of GlobalDllInitialize Arguments: None. Return Value: None. --*/ { DEBUG_ENTER((DBG_GLOBAL, None, "GlobalDllTerminate", NULL )); // // only perform resource clean-up if this DLL is being unloaded due to a // FreeLibrary() call. Otherwise, we take the lazy way out and let the // system clean up after us // if (GlobalDynaUnload) { TerminateAsyncSupport(); GopherTerminate(); FtpTerminate(); IwinsockTerminate(); HandleTerminate(); } CHECK_SOCKETS(); AuthClose(); TerminateSerializedList(&BlockedRequestQueue); TerminateSerializedList(&GlobalServerInfoList); // //BUGBUG: we can't Terminate the list here because // of a race condition from IE3 // (someone still holds the handle) // but we don't want to leak the CritSec // TerminateSerlizedList == DeleteCritSec + some Asserts // //TerminateSerializedList(&GlobalObjectList); DeleteCriticalSection(&(GlobalObjectList.Lock)); DeleteCriticalSection(&MlangCritSec); DeleteCriticalSection(&ZoneMgrCritSec); DeleteCriticalSection(&LockRequestFileCritSec); DeleteCriticalSection(&AutoProxyDllCritSec); DLLUrlCacheEntry(DLL_PROCESS_DETACH); SecurityTerminate(); if (g_HMODSHFolder) { FreeLibrary(g_HMODSHFolder); g_HMODSHFolder = NULL; } if (g_HMODShell32) { FreeLibrary(g_HMODShell32); g_HMODShell32 = NULL; } CloseInternetSettingsKey(); DEBUG_LEAVE(0); } DWORD GlobalDataInitialize( VOID ) /*++ Routine Description: Loads any global data items from the registry Arguments: None. Return Value: DWORD Success - ERROR_SUCCESS Failure - ERROR_NOT_ENOUGH_MEMORY --*/ { DEBUG_ENTER((DBG_GLOBAL, Dword, "GlobalDataInitialize", NULL )); static BOOL Initializing = FALSE; static BOOL Initialized = FALSE; static DWORD error = ERROR_SUCCESS; // // only one thread initializes // if (InterlockedExchange((LPLONG)&Initializing, TRUE)) { while (!Initialized) { SleepEx(0, TRUE); } goto done; } // // we ignore any failure return codes from reading the registry. All the // global variables are initialized to default values // // // UseSchannelDirectly - TRUE if we are to bypass SSPI "Secur32/Security" // and directly call into SCHANNEL. This should give us a perf // improvement since we don't have to load an extra DLL. // g_fHasCredsTimestamp = FALSE; // // BUGBUG - all these need to be per-process. They are intended for IE // memset(&GlobalIdentityGuid, 0, sizeof(GlobalIdentityGuid)); InternetReadRegistryDword("FromCacheTimeout", (LPDWORD)&GlobalFromCacheTimeout ); //InternetReadRegistryDword("UseSchannelDirectly", // (LPDWORD)&GlobalUseSchannelDirectly // ); // also in ChangeGlobalSettings() InternetReadRegistryDword("SecureProtocols", (LPDWORD)&GlobalSecureProtocols ); // also in ChangeGlobalSettings() if (!GlobalPlatformWhistler) { // Fortezza support has been removed from XP InternetReadRegistryDword("Fortezza", (LPDWORD)&GlobalEnableFortezza ); } else { GlobalEnableFortezza = FALSE; } // also in ChangeGlobalSettings() InternetReadRegistryDword("CertificateRevocation", (LPDWORD)&GlobalEnableRevocation ); InternetReadRegistryDword("DisableKeepAlive", (LPDWORD)&GlobalDisableKeepAlive ); InternetReadRegistryDword("DisablePassport", (LPDWORD)&GlobalDisablePassport ); InternetReadRegistryDword("CacheMode", (LPDWORD) &GlobalCacheMode); // also in ChangeGlobalSettings() InternetReadRegistryDword("EnableHttp1_1", (LPDWORD)&GlobalEnableHttp1_1 ); // also in ChangeGlobalSettings() InternetReadRegistryDword("ProxyHttp1.1", (LPDWORD)&GlobalEnableProxyHttp1_1 ); DWORD dwEnableNegotiate = -1; InternetReadRegistryDword("EnableNegotiate", (LPDWORD)&dwEnableNegotiate ); if (dwEnableNegotiate != -1) { // the value is present in the registy, so we honor it. GlobalEnableNegotiate = dwEnableNegotiate; } else { if (GlobalPlatformWhistler && !IsInGUIModeSetup()) { // the value is abscent in Whistler, we'll need to turn set the value to 1 InternetWriteRegistryDword("EnableNegotiate", 1); GlobalEnableNegotiate = TRUE; } } GetUrlCacheHeaderData(CACHE_HEADER_DATA_DOWNLOAD_PARTIAL, &GlobalSslStateCount); DWORD dwType, dwSize; dwSize = sizeof(DWORD); SHGetValue(HKEY_CURRENT_USER, INTERNET_POLICY_KEY, "EnableAutoProxyResultCache", &dwType, &GlobalAutoProxyCacheEnable, &dwSize); dwSize = sizeof(DWORD); SHGetValue(HKEY_CURRENT_USER, INTERNET_POLICY_KEY, "DisplayScriptDownloadFailureUI", &dwType, &GlobalDisplayScriptDownloadFailureUI, &dwSize); dwSize = sizeof(DWORD); SHGetValue(HKEY_CURRENT_USER, INTERNET_POLICY_KEY, "MBCSServername", &dwType, &GlobalSendUTF8ServerToProxy, &dwSize); dwSize = sizeof(DWORD); SHGetValue(HKEY_CURRENT_USER, INTERNET_POLICY_KEY, "MBCSAPIforCrack", &dwType, &GlobalMBCSAPIforCrack, &dwSize); dwSize = sizeof(DWORD); SHGetValue(HKEY_CURRENT_USER, INTERNET_POLICY_KEY, "UTF8ServerNameRes", &dwType, &GlobalUseUTF8ServerForNameRes, &dwSize); //Read DisableWorkerThreadHibernation from HKLM first and allow HKCU override. InternetReadRegistryDwordKey(HKEY_LOCAL_MACHINE, "DisableWorkerThreadHibernation", (LPDWORD)&g_bDisableHibernation ); InternetReadRegistryDword("DisableWorkerThreadHibernation", (LPDWORD)&g_bDisableHibernation ); GlobalUseUTF8ServerForNameRes = GlobalUseUTF8ServerForNameRes && GlobalSendUTF8ServerToProxy; InternetReadRegistryDword("DisableReadRange", (LPDWORD)&GlobalDisableReadRange ); InternetReadRegistryDword("SocketSendBufferLength", &GlobalSocketSendBufferLength ); InternetReadRegistryDword("SocketReceiveBufferLength", &GlobalSocketReceiveBufferLength ); InternetReadRegistryDword("KeepAliveTimeout", &GlobalKeepAliveSocketTimeout ); InternetReadRegistryDword("MaxHttpRedirects", &GlobalMaxHttpRedirects ); InternetReadRegistryDword("MaxConnectionsPerServer", &GlobalMaxConnectionsPerServer ); InternetReadRegistryDword("MaxConnectionsPer1_0Server", &GlobalMaxConnectionsPer1_0Server ); InternetReadRegistryDword("ServerInfoTimeout", &GlobalServerInfoTimeout ); InternetReadRegistryDword("ReceiveTimeOut", (LPDWORD)&GlobalReceiveTimeout ); InternetReadRegistryDword("DisableNTLMPreAuth", (LPDWORD)&GlobalDisableNTLMPreAuth ); InternetReadRegistryDword("ScavengeCacheLowerBound", (LPDWORD)&GlobalDiskUsageLowerBound ); InternetCacheReadRegistryDword("ScavengeCacheFileLifeTime", (LPDWORD)&GlobalScavengeFileLifeTime ); DWORD dwDefTime; if (InternetReadRegistryDword("HttpDefaultExpiryTimeSecs", &dwDefTime) == ERROR_SUCCESS) { dwdwHttpDefaultExpiryDelta = dwDefTime * (LONGLONG)10000000; } if (InternetReadRegistryDword("FtpDefaultExpiryTimeSecs", &dwDefTime) == ERROR_SUCCESS) { dwdwFtpDefaultExpiryDelta = dwDefTime * (LONGLONG)10000000; } if (InternetReadRegistryDword("GopherDefaultExpiryTimeSecs", &dwDefTime) == ERROR_SUCCESS) { dwdwGopherDefaultExpiryDelta = dwDefTime * (LONGLONG)10000000; } InternetReadRegistryDword(vszDisableSslCaching, (LPDWORD)&GlobalDisableSslCaching); InternetReadRegistryDword(vszPerUserCookies, (LPDWORD)&vfPerUserCookies); InternetReadRegistryDword(vszLeashLegacyCookies, (LPDWORD)&GlobalLeashLegacyCookies); InternetReadRegistryDword("DisableNT4RasCheck", (LPDWORD)&GlobalDisableNT4RasCheck); InternetReadRegistryDword("DialupUseLanSettings", (LPDWORD)&GlobalUseLanSettings); InternetReadRegistryDword("SendExtraCRLF", (LPDWORD)&GlobalSendExtraCRLF); InternetReadRegistryDword("BypassFtpTimeCheck", (LPDWORD)&GlobalBypassFtpTimeCheck); InternetReadRegistryDword("EnableGopher", (LPDWORD)&GlobalEnableGopher); dwSize = sizeof(DWORD); SHRegGetUSValue( INTERNET_SETTINGS_KEY, "BypassSSLNoCacheCheck", &dwType, (LPVOID)&GlobalBypassSSLNoCacheCheck, &dwSize, FALSE, NULL, 0 ); // // fix for Novell's Client32 - zekel 23-jul-96 // first check HKLM then HKCU, HKCU takes precdence // InternetReadRegistryDwordKey(HKEY_LOCAL_MACHINE, "DontUseDNSLoadBalancing", (LPDWORD)&fDontUseDNSLoadBalancing ); InternetReadRegistryDword("DontUseDNSLoadBalancing", (LPDWORD) &fDontUseDNSLoadBalancing ); InternetReadRegistryDword("NonBlockingClient32", (LPDWORD)&GlobalNonBlockingClient32 ); // // Get the list of MIME types for which caching needs to be disabled // CreateMimeExclusionTableForCache(); // // Get the list of headers that should be excluded from the cache // CreateHeaderExclusionTableForCache(); DEBUG_PRINT(HTTP, INFO, ("Current wininet user is %s length %d\n", vszCurrentUser, vdwCurrentUserLen )); // // initialize databases // InitializeResolverCache(); GlobalDataReadWarningUIFlags(); PerformStartupProcessing(); // // create the global keep-alive, cert-cache and proxy lists // GlobalCertCache.Initialize(); GlobalProxyInfo.InitializeProxySettings(); //LoadServerInfoDatabase(); // // initialize offline mode from registry // RefreshOfflineFromRegistry(); // // read the global (cache) settings version to avoid an unnecessary reload // N.B. we rely on the side effect of calling urlcache InitGlobals // InternetSettingsChanged(); char buf[MAX_PATH + 1]; if (GetModuleFileName(NULL, buf, sizeof(buf))) { LPSTR p = strrchr(buf, DIR_SEPARATOR_CHAR); p = p ? ++p : buf; DEBUG_PRINT(INET, INFO, ("process is %q\n", p)); if (lstrcmpi(p, "EXPLORER.EXE") && lstrcmpi(p, "IEXPLORE.EXE")) { // // yet another app-hack: AOL's current browser can't understand // HTTP 1.1. When they do, they have to call InternetSetOption() // with INTERNET_OPTION_HTTP_VERSION // if (!lstrcmpi(p, "WAOL.EXE")) { GlobalEnableHttp1_1 = FALSE; } if (!lstrcmpi(p, "SVCHOST.EXE") || !lstrcmpi(p, "SERVICES.EXE")) { GlobalIsProcessNtService = TRUE; } // // non-IE app must supply this through option // GlobalFromCacheTimeout = (DWORD)-1; } else { GlobalIsProcessExplorer = TRUE; } } else { DEBUG_PRINT(INET, INFO, ("GetModuleFileName() returns %d\n", GetLastError() )); } // // initialize the autodial code // // NB!!! this has been moved AFTER the above app hack because it uses the GlobalIsProcessNtService // variable to decide whether to create a perprocess connection mutex or cross-process // (Shishir Pardikar) InitAutodialModule(FALSE); #if defined(SITARA) // // check if Sitara is loaded (IE5B1). Existence of key means Sitara // installed // HKEY key; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\InternetExpressLane", 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) { REGCLOSEKEY(key); OpenIeMainKey(); GlobalEnableSitara = CheckABS(); } #endif // SITARA DWORD urlEncoding; urlEncoding = 0; InternetReadRegistryDwordKey(HKEY_LOCAL_MACHINE, "UrlEncoding", &urlEncoding ); if (urlEncoding == 0) { GlobalEnableUtf8Encoding = TRUE; } // File name truncate ? DWORD dwTruncateFileName; dwTruncateFileName = 0; InternetReadRegistryDword("TruncateFileName", &dwTruncateFileName); if (dwTruncateFileName != 0) GlobalTruncateFileName = TRUE; // // perform module/package-specific initialization // error = HandleInitialize(); if (error != ERROR_SUCCESS) { goto quit; } // // initalize the cookie system // if (!OpenTheCookieJar()) { error = ERROR_NOT_ENOUGH_MEMORY; goto quit; } // // initialize the background task manager // if( !LoadBackgroundTaskMgr() ) { error = ERROR_NOT_ENOUGH_MEMORY; //goto quit; } // Begin (a-thkesa) // Read GlobalBadProxyExpiresTime value from the registry. InternetReadRegistryDword("BadProxyExpiresTime", (LPDWORD)&GlobalBadProxyExpiresTime); // End (a-thkesa) quit: // // finally, if EnableHttp1_1 was set to non-zero in the registry, enable // HTTP 1.1 // if (GlobalEnableHttp1_1) { HttpVersionInfo.dwMajorVersion = 1; HttpVersionInfo.dwMinorVersion = 1; } if (error == ERROR_SUCCESS) { GlobalDataInitialized = TRUE; } // // irrespective of success or failure, we have attempted global data // initialization. If we failed then we assume its something fundamental // and fatal: we don't try again // Initialized = TRUE; done: DEBUG_LEAVE(error); return error; } VOID GlobalDataReadWarningUIFlags( VOID ) /*++ Routine Description: Reads Registry values into global data. Used to read read the registry on connects. Arguments: None. Return Value: DWORD Success - ERROR_SUCCESS Failure - ERROR_NOT_ENOUGH_MEMORY --*/ { DEBUG_ENTER((DBG_GLOBAL, None, "GlobalDataReadWarningUIFlags", NULL )); #ifndef WININET6 // // Load SSL Values from the Registry on whether to pop up UI on error. // InternetReadRegistryDword("WarnOnPost", (LPDWORD)&GlobalWarnOnPost); GlobalWarnAlways = FALSE; InternetReadRegistryDword("WarnAlwaysOnPost", (LPDWORD)&GlobalWarnAlways); // // If Global Warn On Post is set to "2" we reset the "WarnAlways" to TRUE, // since this is the new way INETCPL reads/writes the registry. // if ( GlobalWarnOnPost == 2 ) { GlobalWarnAlways = TRUE; } InternetReadRegistryDword("WarnOnZoneCrossing", (LPDWORD)&GlobalWarnOnZoneCrossing); InternetReadRegistryDword("WarnOnBadCertSending", (LPDWORD)&GlobalWarnOnBadCertSending); InternetReadRegistryDword("WarnOnBadCertRecving", (LPDWORD)&GlobalWarnOnBadCertRecving); InternetReadRegistryDword("WarnOnPostRedirect", (LPDWORD)&GlobalWarnOnPostRedirect); InternetReadRegistryDword("AlwaysDrainOnRedirect", (LPDWORD)&GlobalAlwaysDrainOnRedirect); InternetReadRegistryDword("WarnOnHTTPSToHTTPRedirect", (LPDWORD)&GlobalWarnOnHTTPSToHTTPRedirect); #else // // Load SSL Values from the Registry on whether to pop up UI on error. // InternetIDEReadRegistryDword("WarnOnPost", (LPDWORD)&GlobalWarnOnPost); GlobalWarnAlways = FALSE; InternetIDEReadRegistryDword("WarnAlwaysOnPost", (LPDWORD)&GlobalWarnAlways); // // If Global Warn On Post is set to "2" we reset the "WarnAlways" to TRUE, // since this is the new way INETCPL reads/writes the registry. // if ( GlobalWarnOnPost == 2 ) { GlobalWarnAlways = TRUE; } InternetIDEReadRegistryDword("WarnOnZoneCrossing", (LPDWORD)&GlobalWarnOnZoneCrossing); InternetIDEReadRegistryDword("WarnOnBadCertSending", (LPDWORD)&GlobalWarnOnBadCertSending); InternetIDEReadRegistryDword("WarnOnBadCertRecving", (LPDWORD)&GlobalWarnOnBadCertRecving); InternetIDEReadRegistryDword("WarnOnPostRedirect", (LPDWORD)&GlobalWarnOnPostRedirect); InternetIDEReadRegistryDword("WarnOnHTTPSToHTTPRedirect", (LPDWORD)&GlobalWarnOnHTTPSToHTTPRedirect); #endif DEBUG_LEAVE(0); } VOID GlobalDataTerminate( VOID ) /*++ Routine Description: Undoes work of GlobalDataInitialize() Arguments: None. Return Value: None. --*/ { DEBUG_ENTER((DBG_GLOBAL, None, "GlobalDataTerminate", NULL )); // // Release background task manager // UnloadBackgroundTaskMgr(); PWC_Free(g_pwcUserAndPassword); AuthUnload(); UrlZonesDetach(); TerminateResolverCache(); CloseTheCookieJar(); if (GlobalSpecialDomains) { delete [] GlobalSpecialDomains; delete [] GlobalSDOffsets; } // // destroy lists created from registry // DestroyMimeExclusionTableForCache(); DestroyHeaderExclusionTableForCache(); // // terminate the global cert-cache and proxy lists // GlobalCertCache.Terminate(); GlobalProxyInfo.TerminateProxySettings(); //SaveServerInfoDatabase(); PurgeServerInfoList(TRUE); //TerminateAsyncSupport(); // // free up the handle to the startup mutex // if (g_hAutodialMutex) { CloseHandle(g_hAutodialMutex); } #if defined(SITARA) CloseIeMainKey(); #endif // SITARA UnloadMlang(); UnloadSecurity(); GlobalDataInitialized = FALSE; DEBUG_LEAVE(0); } BOOL IsHttp1_1( VOID ) /*++ Routine Description: Determine if we are using HTTP 1.1 or greater Arguments: None. Return Value: BOOL --*/ { return (HttpVersionInfo.dwMajorVersion > 1) ? TRUE : (((HttpVersionInfo.dwMajorVersion == 1) && (HttpVersionInfo.dwMajorVersion >= 1)) ? TRUE : FALSE); } BOOL IsOffline( VOID ) /*++ Routine Description: Returns whether we are in (global) offline mode or not. We are offline if we went offline because of network failure, or we were put into offline mode by the user Arguments: None. Return Value: BOOL TRUE - we are currently offline FALSE - not offline --*/ { DEBUG_ENTER((DBG_SESSION, Bool, "IsOffline", NULL )); INET_ASSERT(((GlobalDllState & INTERNET_LINE_STATE_MASK) == INTERNET_STATE_ONLINE) || ((GlobalDllState & INTERNET_LINE_STATE_MASK) == INTERNET_STATE_OFFLINE)); INET_ASSERT((GlobalDllState & INTERNET_STATE_OFFLINE_USER) ? ((GlobalDllState & INTERNET_LINE_STATE_MASK) == INTERNET_STATE_OFFLINE) : TRUE); BOOL offline = (GlobalDllState & (INTERNET_STATE_OFFLINE | INTERNET_STATE_OFFLINE_USER)) ? TRUE : FALSE; DEBUG_LEAVE(offline); return offline; } DWORD SetOfflineUserState( IN DWORD dwState, IN BOOL bForce ) /*++ Routine Description: If we are in online state, puts Wininet into user-induced offline mode. Stop all outstanding requests, if required and set the global scope. If we are in offline mode, then change state to online Arguments: dwState - INTERNET_STATE_ONLINE or INTERNET_STATE_OFFLINE bForce - TRUE if we are to forcibly complete all outstanding requests (including synchronous requests) Return Value: DWORD Success - ERROR_SUCCESS Failure - --*/ { DEBUG_ENTER((DBG_GLOBAL, Dword, "SetOfflineUserState", "%s (%d), %B", (dwState == INTERNET_STATE_ONLINE) ? "INTERNET_STATE_ONLINE" : (dwState == INTERNET_STATE_OFFLINE) ? "INTERNET_STATE_OFFLINE" : "???", dwState, bForce )); INET_ASSERT((dwState == INTERNET_STATE_ONLINE) || (dwState == INTERNET_STATE_OFFLINE)); INET_ASSERT(((GlobalDllState & INTERNET_LINE_STATE_MASK) == INTERNET_STATE_ONLINE) || ((GlobalDllState & INTERNET_LINE_STATE_MASK) == INTERNET_STATE_OFFLINE)); DWORD error = ERROR_SUCCESS; if (dwState == INTERNET_STATE_OFFLINE) { GlobalDllState = (GlobalDllState & ~INTERNET_LINE_STATE_MASK) | (INTERNET_STATE_OFFLINE | INTERNET_STATE_OFFLINE_USER); if (bForce) { //CancelActiveAsyncRequests(ERROR_INTERNET_OFFLINE); CancelActiveSyncRequests(ERROR_INTERNET_OFFLINE); GlobalProxyInfo.AbortAutoProxy(); } } else { GlobalDllState = GlobalDllState & ~(INTERNET_LINE_STATE_MASK | INTERNET_STATE_OFFLINE_USER) | INTERNET_STATE_ONLINE; } DEBUG_PRINT(GLOBAL, INFO, ("GlobalDllState = %#x\n", GlobalDllState )); DEBUG_LEAVE(error); return error; } /*++ FetchLocalStrings: This routine fetches the strings necessary to display information in the language of the local user. Arguments: None Return Value: The address of a LOCAL_STRINGS structure containing the addresses of the localized strings to display. Author: Doug Barlow (dbarlow) 4/25/1996 --*/ // // WARNING! The order of elements in the following array must match the // order of elements in the LOCAL_STRINGS structure. // static const UINT uStringId[] = { IDS_LW95_ENTERAUTHINFO, IDS_SECERT_CERTINFO, IDS_SECERT_STRENGTH_HIGH, IDS_SECERT_STRENGTH_MEDIUM, IDS_SECERT_STRENGTH_LOW, IDS_CERT_SUBJECT, IDS_CERT_ISSUER, IDS_CERT_EFFECTIVE_DATE, IDS_CERT_EXPIRATION_DATE, IDS_CERT_PROTOCOL, IDS_CERT_USAGE, IDS_CERT_ENCRYPT_ALG, IDS_CERT_HASH_ALG, IDS_CERT_EXCH_ALG, IDS_CERT_COMMENT, IDS_COMMENT_EXPIRES, IDS_COMMENT_NOT_VALID, IDS_COMMENT_BAD_CN, IDS_COMMENT_BAD_CA, IDS_COMMENT_BAD_SIGNATURE, IDS_COMMENT_REVOKED, IDS_STRING_CIPHMSG, IDS_STRING_HASHMSG, IDS_STRING_EXCHMSG, IDS_CERT_FINGERPRINT, IDS_DOMAIN, IDS_REALM, IDS_SITE, IDS_FIREWALL }; PLOCAL_STRINGS FetchLocalStrings( void) { static LOCAL_STRINGS lszStrings; static BOOL fInitialized = FALSE; INET_ASSERT(sizeof(uStringId) == offsetof(LOCAL_STRINGS, rgchBuffer)); EnterCriticalSection(&GeneralInitCritSec); __try { if (!fInitialized) { LPWSTR szBufEntry; LPWSTR *pszName; DWORD dwOffset; DWORD index, len; // // It needs to be initialized. // pszName = (LPWSTR *)&lszStrings; dwOffset = 0; for (index = 0; index < sizeof(uStringId) / sizeof(UINT); index += 1) { szBufEntry = &lszStrings.rgchBuffer[dwOffset]; len = LoadStringWrapW( GlobalDllHandle, uStringId[index], szBufEntry, LOCAL_STRINGS_MAX_BUFFER - dwOffset); INET_ASSERT(0 != len); // Resource missing! dwOffset += len; lszStrings.rgchBuffer[dwOffset++] = 0; *pszName++ = szBufEntry; } INET_ASSERT(LOCAL_STRINGS_MAX_BUFFER > dwOffset); // // Make it available to this and future callers. // fInitialized = TRUE; } } __finally { LeaveCriticalSection(&GeneralInitCritSec); } ENDFINALLY return &lszStrings; } PLOCAL_STRINGSA FetchLocalStringsA( void) { static LOCAL_STRINGSA lszStrings; static BOOL fInitialized = FALSE; INET_ASSERT(sizeof(uStringId) == offsetof(LOCAL_STRINGSA, rgchBuffer)); EnterCriticalSection(&GeneralInitCritSec); __try { if (!fInitialized) { LPSTR szBufEntry; LPSTR *pszName; DWORD dwOffset; DWORD index, len; // // It needs to be initialized. // pszName = (LPSTR *)&lszStrings; dwOffset = 0; for (index = 0; index < sizeof(uStringId) / sizeof(UINT); index += 1) { szBufEntry = &lszStrings.rgchBuffer[dwOffset]; len = LoadStringA( GlobalDllHandle, uStringId[index], szBufEntry, LOCAL_STRINGS_MAX_BUFFER - dwOffset); INET_ASSERT(0 != len); // Resource missing! dwOffset += len; lszStrings.rgchBuffer[dwOffset++] = 0; *pszName++ = szBufEntry; } INET_ASSERT(LOCAL_STRINGS_MAX_BUFFER > dwOffset); // // Make it available to this and future callers. // fInitialized = TRUE; } } __finally { LeaveCriticalSection(&GeneralInitCritSec); } ENDFINALLY return &lszStrings; } BOOL GetWininetUserName( VOID ) { BOOL fRet = FALSE; DWORD dwT; CHAR *ptr; // Note this critsect could be blocked for a while if RPC gets involved... EnterCriticalSection(&GeneralInitCritSec); if (vdwCurrentUserLen) { fRet = TRUE; goto Done; } dwT = sizeof(vszCurrentUser); if (vfPerUserCookies) { fRet = GetUserName(vszCurrentUser, &dwT); if (!fRet) { DEBUG_PRINT(HTTP, ERROR, ("GetUsername returns %d\n", GetLastError() )); } } if (fRet == FALSE){ strcpy(vszCurrentUser, vszAnyUserName); fRet = TRUE; } // Downcase the username. ptr = vszCurrentUser; while (*ptr) { /* BUGBUG: This logic mangles the user name when there are multi-byte characters. Unfortunately fixing it would lose legacy cookies so the fix had to be backed out. The correct code is commented out below. */ *ptr = tolower(*ptr); ptr++; // if (!IsDBCSLeadByte(*ptr)) // *ptr = tolower(*ptr); // ptr = CharNextExA(CP_ACP, ptr, 0); } INET_ASSERT(fRet == TRUE); vdwCurrentUserLen = (DWORD) (ptr - vszCurrentUser); Done: LeaveCriticalSection(&GeneralInitCritSec); return (fRet); } VOID ChangeGlobalSettings( VOID ) /*++ Routine Description: Changes global settings Arguments: None. Return Value: None. --*/ { DEBUG_ENTER((DBG_GLOBAL, None, "ChangeGlobalSettings", NULL )); InternetReadRegistryDword(vszSyncMode, &GlobalUrlCacheSyncMode ); InternetReadRegistryDword(vszDisableSslCaching, (LPDWORD)&GlobalDisableSslCaching ); InternetReadRegistryDword("EnableHttp1_1", (LPDWORD)&GlobalEnableHttp1_1 ); InternetReadRegistryDword("ProxyHttp1.1", (LPDWORD)&GlobalEnableProxyHttp1_1 ); InternetReadRegistryDword(vszPerUserCookies, (LPDWORD)&vfPerUserCookies ); InternetReadRegistryDword(vszLeashLegacyCookies, (LPDWORD)&GlobalLeashLegacyCookies); if (!GlobalProxyInfo.IsModifiedInProcess()) { FixProxySettingsForCurrentConnection( FALSE ); } // // update security protocol changes. // InternetReadRegistryDword("SecureProtocols", (LPDWORD)&GlobalSecureProtocols ); if (!GlobalPlatformWhistler) { // Fortezza support has been removed from XP InternetReadRegistryDword("Fortezza", (LPDWORD)&GlobalEnableFortezza ); } else { GlobalEnableFortezza = FALSE; } InternetReadRegistryDword("CertificateRevocation", (LPDWORD)&GlobalEnableRevocation ); // // Check autodial settings and hang up if autodial was turned off // // have autodial module reset itself ResetAutodialModule(); RefreshOfflineFromRegistry(); // force reload of cookie-settings from registry by flushing memory cache RefreshP3PSettings(); DEBUG_LEAVE(0); } VOID RefreshOfflineFromRegistry( VOID ) /*++ Routine Description: Reads offline setting in the registry and sets wininet's offline mode accordingly. Arguments: None. Return Value: None. --*/ { DEBUG_ENTER((DBG_GLOBAL, None, "RefreshOfflineFromRegistry", NULL )); DWORD dwTemp = 0; // note: this won't alter dwTemp if not found and so will default to // online InternetReadRegistryDword("GlobalUserOffline", &dwTemp); // convert to appropriate flags if(0 == dwTemp) { // online dwTemp = INTERNET_STATE_ONLINE; } else { // offline dwTemp = INTERNET_STATE_OFFLINE; } SetOfflineUserState(dwTemp, FALSE); DEBUG_LEAVE(0); } VOID PerformStartupProcessing( VOID ) /*++ Routine Description: Performs actions exactly once on system startup. Resets offline mode. Arguments: None. Return Value: None. --*/ { DEBUG_ENTER((DBG_GLOBAL, None, "PerformStartupProcessing", NULL )); INET_ASSERT(NULL == g_hAutodialMutex); g_hAutodialMutex = OpenMutex(SYNCHRONIZE, FALSE, WININET_STARTUP_MUTEX); if (g_hAutodialMutex == NULL && (GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_NAME)) { SECURITY_ATTRIBUTES* psa = SHGetAllAccessSA(); if (psa) { g_hAutodialMutex = CreateMutex(psa, FALSE, WININET_STARTUP_MUTEX); } } if(g_hAutodialMutex) { DWORD dwLastError = GetLastError(); if(ERROR_SUCCESS == dwLastError) { // GetLastError returns ERROR_ALREADY_EXISTS if the mutex existed // before we created it. If we don't get this error, we're the // first so proceed with out startup processing if(!GlobalPlatformVersion5) { // Reset global offline mode on non-Win2K platforms InternetWriteRegistryDword("GlobalUserOffline", 0); } } } DEBUG_LEAVE(0); } #if defined(SITARA) PRIVATE HKEY IeMainKey = NULL; PRIVATE VOID OpenIeMainKey( VOID ) { if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\Main", 0, KEY_QUERY_VALUE, &IeMainKey ) != ERROR_SUCCESS) { IeMainKey = NULL; } } PRIVATE VOID CloseIeMainKey( VOID ) { if (IeMainKey != NULL) { REGCLOSEKEY(IeMainKey); IeMainKey = NULL; } } DWORD GetSitaraProtocol( VOID ) { DEBUG_ENTER((DBG_SOCKETS, Int, "GetSitaraProtocol", NULL )); DWORD dwProtocol = IPPROTO_TCP; DWORD dwEnabled = 0; if (ReadIeMainDwordValue("Use_Express_Lane", &dwEnabled) && (dwEnabled != 0)) { dwProtocol = 901; } DEBUG_LEAVE(dwProtocol); return dwProtocol; } PRIVATE BOOL CheckABS( VOID ) { DEBUG_ENTER((DBG_SOCKETS, Bool, "CheckABS", NULL )); BOOL on = 0; ReadIeMainDwordValue("ABS", (LPDWORD)&on); DEBUG_LEAVE(!on); return !on; } PRIVATE BOOL ReadIeMainDwordValue( IN LPSTR pszValueName, OUT LPDWORD pdwValue ) { if (IeMainKey != NULL) { DWORD value; DWORD valueType; DWORD valueLength = sizeof(value); DWORD err = RegQueryValueEx(IeMainKey, pszValueName, NULL, &valueType, (LPBYTE)&value, &valueLength ); if ((err == ERROR_SUCCESS) && ((valueType == REG_DWORD) || (valueType == REG_BINARY)) && (valueLength == sizeof(DWORD))) { *pdwValue = value; return TRUE; } } return FALSE; } #endif // SITARA // Loads Mlang.dll and get the entry point we are interested in. BOOL LoadMlang( ) { EnterCriticalSection(&MlangCritSec); if (hInstMlang == NULL && !bFailedMlangLoad) { INET_ASSERT(pfnInetMultiByteToUnicode == NULL); hInstMlang = LoadLibrary(MLANGDLLNAME); if (hInstMlang != NULL) { pfnInetMultiByteToUnicode = (PFNINETMULTIBYTETOUNICODE)GetProcAddress (hInstMlang,"ConvertINetMultiByteToUnicode"); if (pfnInetMultiByteToUnicode == NULL) { INET_ASSERT(FALSE); FreeLibrary(hInstMlang); hInstMlang = NULL; } } else { INET_ASSERT(FALSE); // bad news if we can't load mlang.dll } if (pfnInetMultiByteToUnicode == NULL) bFailedMlangLoad = TRUE; } LeaveCriticalSection(&MlangCritSec); return (pfnInetMultiByteToUnicode != NULL); } BOOL UnloadMlang( ) { EnterCriticalSection(&MlangCritSec); if (hInstMlang) FreeLibrary(hInstMlang); hInstMlang = NULL; pfnInetMultiByteToUnicode = NULL; bFailedMlangLoad = FALSE; LeaveCriticalSection(&MlangCritSec); return TRUE; } PFNINETMULTIBYTETOUNICODE GetInetMultiByteToUnicode( ) { // We are checking for pfnInetMultiByteToUnicode without getting a crit section. // This works only because UnloadMlang is called at the Dll unload time. if (pfnInetMultiByteToUnicode == NULL) { LoadMlang( ); } return pfnInetMultiByteToUnicode; }