internal AutoWebProxyScriptEngine(WebProxy proxy, bool useRegistry)
        {
            GlobalLog.Assert(proxy != null, "'proxy' must be assigned.");
            webProxy      = proxy;
            m_UseRegistry = useRegistry;

#if !FEATURE_PAL
            m_AutoDetector        = AutoDetector.CurrentAutoDetector;
            m_NetworkChangeStatus = m_AutoDetector.NetworkChangeStatus;

            SafeRegistryHandle.RegOpenCurrentUser(UnsafeNclNativeMethods.RegistryHelper.KEY_READ, out hkcu);
            if (m_UseRegistry)
            {
                ListenForRegistry();

                // Keep track of the identity we used to read the registry, in case we need to read it again later.
                m_Identity = WindowsIdentity.GetCurrent();
            }
#endif // !FEATURE_PAL

            // In Win2003 winhttp added a Windows Service handling the auto-proxy discovery. In XP using winhttp
            // APIs will load, compile and execute the wpad file in-process. This will also load COM, since
            // WinHttp requires COM to compile the file. For these reasons, we don't use WinHttp on XP, but
            // only on newer OS versions where the "WinHTTP Web Proxy Auto-Discovery Service" exists.
            webProxyFinder = new HybridWebProxyFinder(this);
        }
        internal AutoWebProxyScriptEngine(WebProxy proxy, bool useRegistry)
        {
            GlobalLog.Assert(proxy != null, "'proxy' must be assigned.");
            webProxy = proxy;
            m_UseRegistry = useRegistry;

#if !FEATURE_PAL
            m_AutoDetector = AutoDetector.CurrentAutoDetector;
            m_NetworkChangeStatus = m_AutoDetector.NetworkChangeStatus;

            SafeRegistryHandle.RegOpenCurrentUser(UnsafeNclNativeMethods.RegistryHelper.KEY_READ, out hkcu);
            if (m_UseRegistry)
            {
                ListenForRegistry();

                // Keep track of the identity we used to read the registry, in case we need to read it again later.
                m_Identity = WindowsIdentity.GetCurrent();
            }

#endif // !FEATURE_PAL

            // In Win2003 winhttp added a Windows Service handling the auto-proxy discovery. In XP using winhttp
            // APIs will load, compile and execute the wpad file in-process. This will also load COM, since
            // WinHttp requires COM to compile the file. For these reasons, we don't use WinHttp on XP, but
            // only on newer OS versions where the "WinHTTP Web Proxy Auto-Discovery Service" exists.
            webProxyFinder = new HybridWebProxyFinder(this);
        }
        private void ConnectoidChanged()
        {
            GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::ConnectoidChanged()");
            if (Logging.On)
            {
                Logging.PrintWarning(Logging.Web, SR.GetString(SR.net_log_proxy_update_due_to_ip_config_change));
            }

            // Get the new connectoid/detector.  Only do this after detecting a change, to avoid ----s with other people detecting changes.
            // (We don't want to end up using a detector/connectoid that doesn't match what we read from the registry.)
            m_AutoDetector = AutoDetector.CurrentAutoDetector;

            if (m_UseRegistry)
            {
                // update the engine and proxy
                WebProxyData webProxyData;
                using (m_Identity.Impersonate())
                {
                    webProxyData = GetWebProxyData();
                }
                webProxy.Update(webProxyData);
            }

            // Always uninitialized if the connectoid/address changed and we are autodetecting.
            if (automaticallyDetectSettings)
            {
                webProxyFinder.Reset();
            }
        }
 internal void Close()
 {
     if (this.m_AutoDetector != null)
     {
         int syncStatus = 0;
         try
         {
             this.EnterLock(ref syncStatus);
             if (this.m_AutoDetector != null)
             {
                 this.registrySuppress = true;
                 if (this.registryChangeEventPolicy != null)
                 {
                     this.registryChangeEventPolicy.Close();
                     this.registryChangeEventPolicy = null;
                 }
                 if (this.registryChangeEventLM != null)
                 {
                     this.registryChangeEventLM.Close();
                     this.registryChangeEventLM = null;
                 }
                 if (this.registryChangeEvent != null)
                 {
                     this.registryChangeEvent.Close();
                     this.registryChangeEvent = null;
                 }
                 if ((this.regKeyPolicy != null) && !this.regKeyPolicy.IsInvalid)
                 {
                     this.regKeyPolicy.Close();
                 }
                 if ((this.regKeyLM != null) && !this.regKeyLM.IsInvalid)
                 {
                     this.regKeyLM.Close();
                 }
                 if ((this.regKey != null) && !this.regKey.IsInvalid)
                 {
                     this.regKey.Close();
                 }
                 if (this.hkcu != null)
                 {
                     this.hkcu.RegCloseKey();
                     this.hkcu = null;
                 }
                 if (this.m_Identity != null)
                 {
                     this.m_Identity.Dispose();
                     this.m_Identity = null;
                 }
                 this.webProxyFinder.Dispose();
                 this.m_AutoDetector = null;
             }
         }
         finally
         {
             this.ExitLock(ref syncStatus);
         }
     }
 }
 internal AutoWebProxyScriptEngine(WebProxy proxy, bool useRegistry)
 {
     this.webProxy              = proxy;
     this.m_UseRegistry         = useRegistry;
     this.m_AutoDetector        = AutoDetector.CurrentAutoDetector;
     this.m_NetworkChangeStatus = this.m_AutoDetector.NetworkChangeStatus;
     SafeRegistryHandle.RegOpenCurrentUser(0x20019, out this.hkcu);
     if (this.m_UseRegistry)
     {
         this.ListenForRegistry();
         this.m_Identity = WindowsIdentity.GetCurrent();
     }
     this.webProxyFinder = new HybridWebProxyFinder(this);
 }
            private static void CheckForChanges()
            {
                bool changed = false;

                if (s_RasHelper != null && s_RasHelper.HasChanged)
                {
                    s_RasHelper.Reset();
                    changed = true;
                }
                if (s_AddressChange != null && s_AddressChange.CheckAndReset())
                {
                    changed = true;
                }
                if (changed)
                {
                    int currentVersion = Interlocked.Increment(ref s_CurrentVersion);
                    s_CurrentAutoDetector = new AutoDetector(UnsafeNclNativeMethods.RasHelper.GetCurrentConnectoid(), currentVersion);
                }
            }
 private void ConnectoidChanged()
 {
     if (Logging.On)
     {
         Logging.PrintWarning(Logging.Web, SR.GetString("net_log_proxy_update_due_to_ip_config_change"));
     }
     this.m_AutoDetector = AutoDetector.CurrentAutoDetector;
     if (this.m_UseRegistry)
     {
         WebProxyData webProxyData;
         using (this.m_Identity.Impersonate())
         {
             webProxyData = this.GetWebProxyData();
         }
         this.webProxy.Update(webProxyData);
     }
     if (this.automaticallyDetectSettings)
     {
         this.webProxyFinder.Reset();
     }
 }
 private static void Initialize()
 {
     if (!s_Initialized)
     {
         lock (s_LockObject)
         {
             if (!s_Initialized)
             {
                 s_CurrentAutoDetector = new AutoDetector(UnsafeNclNativeMethods.RasHelper.GetCurrentConnectoid(), 1);
                 if (NetworkChange.CanListenForNetworkChanges)
                 {
                     s_AddressChange = new NetworkAddressChangePolled();
                 }
                 if (UnsafeNclNativeMethods.RasHelper.RasSupported)
                 {
                     s_RasHelper = new UnsafeNclNativeMethods.RasHelper();
                 }
                 s_CurrentVersion = 1;
                 s_Initialized    = true;
             }
         }
     }
 }
 private static void CheckForChanges()
 {
     bool changed = false;
     if (s_RasHelper != null && s_RasHelper.HasChanged)
     {
         s_RasHelper.Reset();
         changed = true;
     }
     if (s_AddressChange != null && s_AddressChange.CheckAndReset())
     {
         changed = true;
     }
     if (changed)
     {
         int currentVersion = Interlocked.Increment(ref s_CurrentVersion);
         s_CurrentAutoDetector = new AutoDetector(UnsafeNclNativeMethods.RasHelper.GetCurrentConnectoid(), currentVersion);
     }
 }
 private static void Initialize()
 {
     if (!s_Initialized)
     {
         lock (s_LockObject)
         {
             if (!s_Initialized)
             {
                 s_CurrentAutoDetector = new AutoDetector(UnsafeNclNativeMethods.RasHelper.GetCurrentConnectoid(), 1);
                 if (NetworkChange.CanListenForNetworkChanges)
                 {
                     s_AddressChange = new NetworkAddressChangePolled();
                 }
                 if (UnsafeNclNativeMethods.RasHelper.RasSupported)
                 {
                     s_RasHelper = new UnsafeNclNativeMethods.RasHelper();
                 }
                 s_CurrentVersion = 1;
                 s_Initialized = true;
             }
         }
     }
 }
        private void ConnectoidChanged()
        {
            GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::ConnectoidChanged()");
            if (Logging.On) Logging.PrintWarning(Logging.Web, SR.GetString(SR.net_log_proxy_update_due_to_ip_config_change));

            // Get the new connectoid/detector.  Only do this after detecting a change, to avoid ----s with other people detecting changes.
            // (We don't want to end up using a detector/connectoid that doesn't match what we read from the registry.)
            m_AutoDetector = AutoDetector.CurrentAutoDetector;

            if (m_UseRegistry)
            {
                // update the engine and proxy
                WebProxyData webProxyData;
                using (m_Identity.Impersonate())
                {
                    webProxyData = GetWebProxyData();
                }
                webProxy.Update(webProxyData);
            }

            // Always uninitialized if the connectoid/address changed and we are autodetecting.
            if (automaticallyDetectSettings)
                webProxyFinder.Reset();
        }
        internal void Close()
        {
#if !FEATURE_PAL
            // m_AutoDetector is always set up in the constructor, use it to lock
            if (m_AutoDetector != null)
            {
                int syncStatus = SyncStatus.Unlocked;
                try
                {
                    EnterLock(ref syncStatus);
                    GlobalLog.Assert(syncStatus == SyncStatus.LockOwner, "AutoWebProxyScriptEngine#{0}::Close()|Failed to acquire lock.", ValidationHelper.HashString(this));

                    if (m_AutoDetector != null)
                    {
                        registrySuppress = true;
                        if (registryChangeEventPolicy != null)
                        {
                            registryChangeEventPolicy.Close();
                            registryChangeEventPolicy = null;
                        }
                        if (registryChangeEventLM != null)
                        {
                            registryChangeEventLM.Close();
                            registryChangeEventLM = null;
                        }
                        if (registryChangeEvent != null)
                        {
                            registryChangeEvent.Close();
                            registryChangeEvent = null;
                        }

                        if (regKeyPolicy != null && !regKeyPolicy.IsInvalid)
                        {
                            regKeyPolicy.Close();
                        }
                        if (regKeyLM != null && !regKeyLM.IsInvalid)
                        {
                            regKeyLM.Close();
                        }
                        if (regKey != null && !regKey.IsInvalid)
                        {
                            regKey.Close();
                        }

                        if (hkcu != null)
                        {
                            hkcu.RegCloseKey();
                            hkcu = null;
                        }

                        if (m_Identity != null)
                        {
                            m_Identity.Dispose();
                            m_Identity = null;
                        }

                        webProxyFinder.Dispose();

                        m_AutoDetector = null;
                    }
                }
                finally
                {
                    ExitLock(ref syncStatus);
                }
            }
#endif // !FEATURE_PAL
        }
 private void CheckForChanges(ref int syncStatus)
 {
     try
     {
         bool flag  = AutoDetector.CheckForNetworkChanges(ref this.m_NetworkChangeStatus);
         bool flag2 = false;
         if (flag || this.needConnectoidUpdate)
         {
             try
             {
                 this.EnterLock(ref syncStatus);
                 if (flag || this.needConnectoidUpdate)
                 {
                     this.needConnectoidUpdate = syncStatus != 2;
                     if (!this.needConnectoidUpdate)
                     {
                         this.ConnectoidChanged();
                         flag2 = true;
                     }
                 }
             }
             finally
             {
                 this.ExitLock(ref syncStatus);
             }
         }
         if (this.m_UseRegistry)
         {
             bool           flag3 = false;
             AutoResetEvent registryChangeEvent = this.registryChangeEvent;
             if (this.registryChangeDeferred || (flag3 = (registryChangeEvent != null) && registryChangeEvent.WaitOne(0, false)))
             {
                 try
                 {
                     this.EnterLock(ref syncStatus);
                     if (flag3 || this.registryChangeDeferred)
                     {
                         this.registryChangeDeferred = syncStatus != 2;
                         if (!this.registryChangeDeferred && (this.registryChangeEvent != null))
                         {
                             try
                             {
                                 using (this.m_Identity.Impersonate())
                                 {
                                     this.ListenForRegistryHelper(ref this.regKey, ref this.registryChangeEvent, IntPtr.Zero, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Connections");
                                 }
                             }
                             catch
                             {
                                 throw;
                             }
                             this.needRegistryUpdate = true;
                         }
                     }
                 }
                 finally
                 {
                     this.ExitLock(ref syncStatus);
                 }
             }
             flag3 = false;
             registryChangeEvent = this.registryChangeEventLM;
             if (this.registryChangeLMDeferred || (flag3 = (registryChangeEvent != null) && registryChangeEvent.WaitOne(0, false)))
             {
                 try
                 {
                     this.EnterLock(ref syncStatus);
                     if (flag3 || this.registryChangeLMDeferred)
                     {
                         this.registryChangeLMDeferred = syncStatus != 2;
                         if (!this.registryChangeLMDeferred && (this.registryChangeEventLM != null))
                         {
                             try
                             {
                                 using (this.m_Identity.Impersonate())
                                 {
                                     this.ListenForRegistryHelper(ref this.regKeyLM, ref this.registryChangeEventLM, UnsafeNclNativeMethods.RegistryHelper.HKEY_LOCAL_MACHINE, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Connections");
                                 }
                             }
                             catch
                             {
                                 throw;
                             }
                             this.needRegistryUpdate = true;
                         }
                     }
                 }
                 finally
                 {
                     this.ExitLock(ref syncStatus);
                 }
             }
             flag3 = false;
             registryChangeEvent = this.registryChangeEventPolicy;
             if (this.registryChangePolicyDeferred || (flag3 = (registryChangeEvent != null) && registryChangeEvent.WaitOne(0, false)))
             {
                 try
                 {
                     this.EnterLock(ref syncStatus);
                     if (flag3 || this.registryChangePolicyDeferred)
                     {
                         this.registryChangePolicyDeferred = syncStatus != 2;
                         if (!this.registryChangePolicyDeferred && (this.registryChangeEventPolicy != null))
                         {
                             try
                             {
                                 using (this.m_Identity.Impersonate())
                                 {
                                     this.ListenForRegistryHelper(ref this.regKeyPolicy, ref this.registryChangeEventPolicy, UnsafeNclNativeMethods.RegistryHelper.HKEY_LOCAL_MACHINE, @"SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings");
                                 }
                             }
                             catch
                             {
                                 throw;
                             }
                             this.needRegistryUpdate = true;
                         }
                     }
                 }
                 finally
                 {
                     this.ExitLock(ref syncStatus);
                 }
             }
             if (this.needRegistryUpdate)
             {
                 try
                 {
                     this.EnterLock(ref syncStatus);
                     if (this.needRegistryUpdate && (syncStatus == 2))
                     {
                         this.needRegistryUpdate = false;
                         if (!flag2)
                         {
                             this.RegistryChanged();
                         }
                     }
                 }
                 finally
                 {
                     this.ExitLock(ref syncStatus);
                 }
             }
         }
     }
     catch (ObjectDisposedException)
     {
     }
 }
        private void CheckForChanges(ref int syncStatus)
        {
            // Catch ObjectDisposedException instead of synchronizing with Close().
            try
            {
                bool changed = AutoDetector.CheckForNetworkChanges(ref m_NetworkChangeStatus);
                bool ignoreRegistryChange = false;
                if (changed || needConnectoidUpdate)
                {
                    try
                    {
                        EnterLock(ref syncStatus);
                        if (changed || needConnectoidUpdate)   // Make sure no one else took care of it before we got the lock.
                        {
                            needConnectoidUpdate = syncStatus != SyncStatus.LockOwner;
                            if (!needConnectoidUpdate)
                            {
                                ConnectoidChanged();

                                // We usually get a registry change at the same time.  Since the connectoid change does more,
                                // we can skip reading the registry info twice.
                                ignoreRegistryChange = true;
                            }
                        }
                    }
                    finally
                    {
                        ExitLock(ref syncStatus);
                    }
                }

                if (!m_UseRegistry)
                {
                    return;
                }

                bool           forReal   = false;
                AutoResetEvent tempEvent = registryChangeEvent;
                if (registryChangeDeferred || (forReal = (tempEvent != null && tempEvent.WaitOne(0, false))))
                {
                    try
                    {
                        EnterLock(ref syncStatus);
                        if (forReal || registryChangeDeferred)  // Check if someone else handled it before I got the lock.
                        {
                            registryChangeDeferred = syncStatus != SyncStatus.LockOwner;
                            if (!registryChangeDeferred && registryChangeEvent != null)
                            {
                                try
                                {
                                    using (m_Identity.Impersonate())
                                    {
                                        ListenForRegistryHelper(ref regKey, ref registryChangeEvent, IntPtr.Zero,
                                                                RegBlobWebProxyDataBuilder.ProxyKey);
                                    }
                                }
                                catch
                                {
                                    throw;
                                }
                                needRegistryUpdate = true;
                            }
                        }
                    }
                    finally
                    {
                        ExitLock(ref syncStatus);
                    }
                }

                forReal   = false;
                tempEvent = registryChangeEventLM;
                if (registryChangeLMDeferred || (forReal = (tempEvent != null && tempEvent.WaitOne(0, false))))
                {
                    try
                    {
                        EnterLock(ref syncStatus);
                        if (forReal || registryChangeLMDeferred)  // Check if someone else handled it before I got the lock.
                        {
                            registryChangeLMDeferred = syncStatus != SyncStatus.LockOwner;
                            if (!registryChangeLMDeferred && registryChangeEventLM != null)
                            {
                                try
                                {
                                    using (m_Identity.Impersonate())
                                    {
                                        ListenForRegistryHelper(ref regKeyLM, ref registryChangeEventLM,
                                                                UnsafeNclNativeMethods.RegistryHelper.HKEY_LOCAL_MACHINE,
                                                                RegBlobWebProxyDataBuilder.ProxyKey);
                                    }
                                }
                                catch
                                {
                                    throw;
                                }
                                needRegistryUpdate = true;
                            }
                        }
                    }
                    finally
                    {
                        ExitLock(ref syncStatus);
                    }
                }

                forReal   = false;
                tempEvent = registryChangeEventPolicy;
                if (registryChangePolicyDeferred || (forReal = (tempEvent != null && tempEvent.WaitOne(0, false))))
                {
                    try
                    {
                        EnterLock(ref syncStatus);
                        if (forReal || registryChangePolicyDeferred)  // Check if someone else handled it before I got the lock.
                        {
                            registryChangePolicyDeferred = syncStatus != SyncStatus.LockOwner;
                            if (!registryChangePolicyDeferred && registryChangeEventPolicy != null)
                            {
                                try
                                {
                                    using (m_Identity.Impersonate())
                                    {
                                        ListenForRegistryHelper(ref regKeyPolicy, ref registryChangeEventPolicy,
                                                                UnsafeNclNativeMethods.RegistryHelper.HKEY_LOCAL_MACHINE,
                                                                RegBlobWebProxyDataBuilder.PolicyKey);
                                    }
                                }
                                catch
                                {
                                    throw;
                                }
                                needRegistryUpdate = true;
                            }
                        }
                    }
                    finally
                    {
                        ExitLock(ref syncStatus);
                    }
                }

                if (needRegistryUpdate)
                {
                    try
                    {
                        EnterLock(ref syncStatus);
                        if (needRegistryUpdate && syncStatus == SyncStatus.LockOwner)
                        {
                            needRegistryUpdate = false;

                            // We don't need to process this now if we just did it for the connectoid.
                            if (!ignoreRegistryChange)
                            {
                                RegistryChanged();
                            }
                        }
                    }
                    finally
                    {
                        ExitLock(ref syncStatus);
                    }
                }
            }
            catch (ObjectDisposedException) { }
        }
        internal void Close()
        {
#if !FEATURE_PAL
            // m_AutoDetector is always set up in the constructor, use it to lock
            if (m_AutoDetector != null)
            {
                int syncStatus = SyncStatus.Unlocked;
                try
                {
                    EnterLock(ref syncStatus);
                    GlobalLog.Assert(syncStatus == SyncStatus.LockOwner, "AutoWebProxyScriptEngine#{0}::Close()|Failed to acquire lock.", ValidationHelper.HashString(this));

                    if (m_AutoDetector != null)
                    {
                        registrySuppress = true;
                        if (registryChangeEventPolicy != null)
                        {
                            registryChangeEventPolicy.Close();
                            registryChangeEventPolicy = null;
                        }
                        if (registryChangeEventLM != null)
                        {
                            registryChangeEventLM.Close();
                            registryChangeEventLM = null;
                        }
                        if (registryChangeEvent != null)
                        {
                            registryChangeEvent.Close();
                            registryChangeEvent = null;
                        }

                        if (regKeyPolicy != null && !regKeyPolicy.IsInvalid)
                        {
                            regKeyPolicy.Close();
                        }
                        if (regKeyLM != null && !regKeyLM.IsInvalid)
                        {
                            regKeyLM.Close();
                        }
                        if (regKey != null && !regKey.IsInvalid)
                        {
                            regKey.Close();
                        }

                        if (hkcu != null)
                        {
                            hkcu.RegCloseKey();
                            hkcu = null;
                        }

                        if (m_Identity != null)
                        {
                            m_Identity.Dispose();
                            m_Identity = null;
                        }

                        webProxyFinder.Dispose();

                        m_AutoDetector = null;
                    }
                }
                finally
                {
                    ExitLock(ref syncStatus);
                }
            }
#endif // !FEATURE_PAL
        }