public static unsafe ReadOnlyCollection<UrlReservation> GetAll()
        {
            List<UrlReservation> revs = new List<UrlReservation>();

            uint retVal = ErrorCodes.NOERROR;

            retVal = HttpApiNative.HttpInitialize(HttpApiConstants.HTTPAPI_VERSION_2, HttpApiConstants.HTTP_INITIALIZE_CONFIG, IntPtr.Zero);
            if (ErrorCodes.NOERROR == retVal)
            {
                try
                {
                    HTTP_SERVICE_CONFIG_URLACL_QUERY inputConfigInfoSet = new HTTP_SERVICE_CONFIG_URLACL_QUERY();
                    inputConfigInfoSet.QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryNext;
                    inputConfigInfoSet.dwToken = 0;

                    byte[] buf = new byte[128];

                    while (retVal == ErrorCodes.NOERROR)
                    {
                        int returnLength = 0;
                        retVal = HttpApiNative.HttpQueryServiceConfiguration(
                            IntPtr.Zero,
                            HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo,
                            ref inputConfigInfoSet,
                            Marshal.SizeOf(inputConfigInfoSet),
                            null,
                            0,
                            out returnLength,
                            IntPtr.Zero);

                        if (retVal == ErrorCodes.ERROR_INSUFFICIENT_BUFFER && returnLength > buf.Length)
                        {
                            buf = new byte[returnLength];
                        }

                        fixed (byte* pBuf = buf)
                        {
                            retVal = HttpApiNative.HttpQueryServiceConfiguration(
                                IntPtr.Zero,
                                HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo,
                                ref inputConfigInfoSet,
                                Marshal.SizeOf(inputConfigInfoSet),
                                pBuf,
                                buf.Length,
                                out returnLength,
                                IntPtr.Zero);

                            if (retVal == ErrorCodes.NOERROR)
                            {
                                var outputConfigInfo = (HTTP_SERVICE_CONFIG_URLACL_SET)Marshal.PtrToStructure(
                                    new IntPtr(pBuf), typeof(HTTP_SERVICE_CONFIG_URLACL_SET));
                                var rev = new UrlReservation(outputConfigInfo.KeyDesc.pUrlPrefix,
                                    SecurityIdentifiersFromSDDL(outputConfigInfo.ParamDesc.pStringSecurityDescriptor));
                                revs.Add(rev);
                            }
                        }

                        inputConfigInfoSet.dwToken++;
                    }

                    if (retVal != ErrorCodes.ERROR_NO_MORE_ITEMS)
                    {
                        throw new Win32Exception((int)retVal);
                    }
                }
                finally
                {
                    retVal = HttpApiNative.HttpTerminate(HttpApiConstants.HTTP_INITIALIZE_CONFIG, IntPtr.Zero);
                }
            }

            if (ErrorCodes.NOERROR != retVal)
            {
                throw new Win32Exception(Convert.ToInt32(retVal));
            }

            return new ReadOnlyCollection<UrlReservation>(revs);
        }
 internal static void Create(UrlReservation urlReservation)
 {
     string sddl = GenerateSddl(urlReservation.SIDs);
     ReserveURL(urlReservation.Url, sddl);
 }
 internal static void Delete(UrlReservation urlReservation)
 {
     string sddl = GenerateSddl(urlReservation.SIDs);
     FreeURL(urlReservation.Url, sddl);
 }
        private void CreateAcl()
        {
            var thisUser = string.Format(@"{0}\{1}", Environment.UserDomainName, Environment.UserName);
            try
            {
                var acct = new NTAccount(thisUser);
                SecurityIdentifier sid = (SecurityIdentifier)acct.Translate(typeof(SecurityIdentifier));

                var url = new UrlReservation("http://+:31076/", new List<SecurityIdentifier>() { sid });
                url.Create();
            }
            catch (Win32Exception ex)
            {
                if ((uint)ex.HResult==(uint)0x80004005)
                {
                    var result = MessageBox.Show("The Scratch Gateway program needs to reserve an http address on your machine. Scratch connects to this address to talk to your board. Adding this reservation requires administrator priveleges. You will now be asked to allow admin access.", "Elevation Required", MessageBoxButton.OKCancel);
                    if (result == MessageBoxResult.Cancel)
                        throw;

                    // Requires elevation, and apparently, we're not so we will shell out to netsh
                    AddAddress("http://+:31076/", Environment.UserDomainName, Environment.UserName);
                }
                else
                    throw;
            }
        }