public void Initialize()
        {
            if (_disposed)
            {
                throw new InvalidOperationException(Resources.HttpInitializeDispose);
            }

            if (!_initialized)
            {
                var version =
                    new HttpServerVersion {
                    Major = 1, Minor = 0
                };

                var returnCode =
                    NativeHttpServer.HttpInitialize(version, HttpInitialize.Configuration, IntPtr.Zero);

                if (returnCode != 0)
                {
                    throw new Win32Exception((int)returnCode, Resources.HttpInitializeException);
                }

                _initialized = true;
            }
        }
        public void UnbindCertificate(int port)
        {
            if (_disposed)
            {
                throw new InvalidOperationException(Resources.HttpUnBindDispose);
            }

            if (!_initialized)
            {
                throw new InvalidOperationException(Resources.HttpUnBindInitialize);
            }

            var endPoint =
                new IPEndPoint(IPAddress.Any, port);

            var endPointData =
                endPoint.GetBytes();

            var endPointPtr = IntPtr.Zero;

            try
            {
                endPointPtr =
                    Marshal.AllocHGlobal(endPointData.Length);

                Marshal.Copy(endPointData, 0, endPointPtr, endPointData.Length);

                var config =
                    new HttpCertificateConfigurationSet
                {
                    IpPort = endPointPtr,
                };

                var returnCode =
                    NativeHttpServer.HttpDeleteServiceConfiguration(IntPtr.Zero, HttpConfigurationType.Certificate, ref config, (uint)Marshal.SizeOf(config), IntPtr.Zero);

                if (returnCode != 0)
                {
                    throw new Win32Exception((int)returnCode, Resources.HttpUnBindException);
                }
            }
            finally
            {
                if (endPointPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(endPointPtr);
                }
            }
        }
        public void Terminate()
        {
            if (_disposed)
            {
                throw new InvalidOperationException(Resources.HttpTerminateDispose);
            }

            if (_initialized)
            {
                var returnCode =
                    NativeHttpServer.HttpTerminate(HttpInitialize.Configuration, IntPtr.Zero);

                if (returnCode != 0)
                {
                }

                _initialized = false;
            }
        }
        public void BindCertificate(int port, X509Certificate2 certificate, StoreName storeName)
        {
            if (_disposed)
            {
                throw new InvalidOperationException(Resources.HttpBindDispose);
            }

            if (!_initialized)
            {
                throw new InvalidOperationException(Resources.HttpBindInitialize);
            }

            if (certificate == null)
            {
                throw new ArgumentNullException(Resources.HttpBindCertificate);
            }

            using (var store = new CertificateStore(new X509Store(storeName, StoreLocation.LocalMachine)))
            {
                store.Open(OpenFlags.ReadOnly);

                if (!store.Certificates.Contains(certificate))
                {
                    throw new ArgumentException();
                }
            }

            var hash =
                certificate.GetCertHash();

            var endPoint =
                new IPEndPoint(IPAddress.Any, port);

            var endPointData =
                endPoint.GetBytes();

            var hashPtr = IntPtr.Zero;

            var endPointPtr = IntPtr.Zero;

            try
            {
                endPointPtr =
                    Marshal.AllocHGlobal(endPointData.Length);

                Marshal.Copy(endPointData, 0, endPointPtr, endPointData.Length);

                hashPtr =
                    Marshal.AllocHGlobal(hash.Length);

                Marshal.Copy(hash, 0, hashPtr, hash.Length);

                var config =
                    new HttpCertificateConfigurationSet
                {
                    IpPort = endPointPtr,

                    Hash       = hashPtr,
                    HashLength = (uint)hash.Length,

                    StoreName = storeName.ToString(),

                    AppId = Guid.NewGuid()
                };

                var returnCode =
                    NativeHttpServer.HttpSetServiceConfiguration(IntPtr.Zero, HttpConfigurationType.Certificate, ref config, (uint)Marshal.SizeOf(config), IntPtr.Zero);

                if (returnCode != 0)
                {
                    throw new Win32Exception((int)returnCode, Resources.HttpBindException);
                }
            }
            finally
            {
                if (hashPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(hashPtr);
                }

                if (endPointPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(endPointPtr);
                }
            }
        }
        public X509Certificate2 GetBindedCertificate(int port, out StoreName storeName)
        {
            if (_disposed)
            {
                throw new InvalidOperationException(Resources.HttpBindedDispose);
            }

            if (!_initialized)
            {
                throw new InvalidOperationException(Resources.HttpBindedInitialize);
            }

            X509Certificate2 certificate = null;

            var endPoint =
                new IPEndPoint(IPAddress.Any, port);

            var endPointData =
                endPoint.GetBytes();

            var endPointPtr = IntPtr.Zero;

            var outConfigPtr = IntPtr.Zero;

            try
            {
                endPointPtr =
                    Marshal.AllocHGlobal(endPointData.Length);

                Marshal.Copy(endPointData, 0, endPointPtr, endPointData.Length);

                var config =
                    new HttpCertificateConfigurationQuery
                {
                    IpPort = endPointPtr,

                    QueryType = HttpConfigurationQueryType.Exact
                };

                uint returnLength;

                var returnCode =
                    NativeHttpServer.HttpQueryServiceConfiguration(IntPtr.Zero, HttpConfigurationType.Certificate, ref config, (uint)Marshal.SizeOf(config), IntPtr.Zero, 0, out returnLength, IntPtr.Zero);

                if (returnCode == 122) //ERROR_INSUFFICIENT_BUFFER
                {
                    outConfigPtr =
                        Marshal.AllocHGlobal((int)returnLength);

                    returnCode =
                        NativeHttpServer.HttpQueryServiceConfiguration(IntPtr.Zero, HttpConfigurationType.Certificate, ref config, (uint)Marshal.SizeOf(config), outConfigPtr, returnLength, out returnLength, IntPtr.Zero);
                }

                if (returnCode == 2) //ERROR_FILE_NOT_FOUND
                {
                    storeName = 0;

                    return(null);
                }

                if (returnCode != 0)
                {
                    throw new Win32Exception((int)returnCode, Resources.HttpBindedException);
                }

                var outConfig =
                    (HttpCertificateConfigurationSet)
                    Marshal.PtrToStructure(outConfigPtr, typeof(HttpCertificateConfigurationSet));

                var hash =
                    new byte[outConfig.HashLength];

                Marshal.Copy(outConfig.Hash, hash, 0, hash.Length);

                storeName =
                    (StoreName)Enum.Parse(typeof(StoreName), outConfig.StoreName, true);

                var store =
                    new X509Store(storeName, StoreLocation.LocalMachine);

                try
                {
                    store.Open(OpenFlags.ReadOnly);

                    foreach (var c in store.Certificates)
                    {
                        if (c.GetCertHash().SequenceEqual(hash))
                        {
                            certificate = c;

                            break;
                        }
                    }
                }
                finally
                {
                    store.Close();
                }
            }
            finally
            {
                if (endPointPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(endPointPtr);
                }

                if (outConfigPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(outConfigPtr);
                }
            }

            return(certificate);
        }