コード例 #1
0
        /// <summary>
        /// Query a variable buffer from the object.
        /// </summary>
        /// <param name="info_class">The information class to query.</param>
        /// <param name="init_buffer">A buffer to initialize the initial query. Can be null.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The result of the query.</returns>
        /// <exception cref="NtException">Thrown on error.</exception>
        public virtual NtResult <SafeHGlobalBuffer> QueryRawBuffer(Q info_class, byte[] init_buffer, bool throw_on_error)
        {
            NtStatus status;
            int      return_length;

            // First try base size before trying to reallocate.
            using (var buffer = init_buffer.ToBuffer())
            {
                status = QueryInformation(info_class, buffer, out return_length);
                if (status.IsSuccess())
                {
                    return(status.CreateResult(false, () => buffer.Detach(return_length)));
                }
            }

            if (!IsInvalidBufferStatus(status))
            {
                return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
            }

            // If the function returned a length then trust it.
            if (return_length > 0 && GetTrustReturnLength(info_class))
            {
                using (var buffer = new SafeHGlobalBuffer(return_length))
                {
                    return(QueryInformation(info_class, buffer, out return_length).CreateResult(throw_on_error, () => buffer.Detach(return_length)));
                }
            }

            // Function length can't be trusted, we'll need to brute force it.
            return_length = 256;
            int max_length = GetMaximumBruteForceLength(info_class);

            while (return_length <= max_length)
            {
                using (var buffer = new SafeHGlobalBuffer(return_length))
                {
                    status = QueryInformation(info_class, buffer, out int dummy_length);
                    if (status.IsSuccess())
                    {
                        if (dummy_length > 0 && dummy_length < return_length)
                        {
                            return_length = dummy_length;
                        }
                        return(status.CreateResult(throw_on_error, () => buffer.Detach(return_length)));
                    }
                    else if (!IsInvalidBufferStatus(status))
                    {
                        return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
                    }

                    return_length *= 2;
                }
            }

            return(NtStatus.STATUS_BUFFER_TOO_SMALL.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
        }
コード例 #2
0
        private NtResult <SafeHGlobalBuffer> CreateRelativeSecurityDescriptor(bool throw_on_error)
        {
            using (var sd_buffer = CreateAbsoluteSecurityDescriptor(throw_on_error))
            {
                if (!sd_buffer.IsSuccess)
                {
                    return(sd_buffer);
                }

                int      total_length = 0;
                NtStatus status       = NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer.Result, SafeHGlobalBuffer.Null, ref total_length);
                if (status != NtStatus.STATUS_BUFFER_TOO_SMALL)
                {
                    return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
                }

                using (var relative_sd = new SafeHGlobalBuffer(total_length))
                {
                    return(NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer.Result, relative_sd, ref total_length)
                           .CreateResult(throw_on_error, () => relative_sd.Detach()));
                }
            }
        }