示例#1
0
 public unsafe static extern NTSTATUS NtEnumerateValueKey(
     RegistryKeyHandle KeyHandle,
     uint Index,
     KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
     void *KeyValueInformation,
     uint Length,
     out uint ResultLength);
示例#2
0
 public unsafe static extern WindowsError RegQueryValueExW(
     RegistryKeyHandle hKey,
     string lpValueName,
     void *lpReserved,
     RegistryValueType *lpType,
     void *lpData,
     uint *lpcbData);
示例#3
0
 public unsafe static extern WindowsError RegEnumValueW(
     RegistryKeyHandle hKey,
     uint dwIndex,
     void *lpValueName,
     ref uint lpcchValueName,
     void *lpReserved,
     RegistryValueType *lpType,
     void *lpData,
     uint *lpcbData);
示例#4
0
        /// <summary>
        ///  Open the specified subkey.
        /// </summary>
        public static RegistryKeyHandle OpenKey(
            RegistryKeyHandle key,
            string subKeyName,
            RegistryAccessRights rights = RegistryAccessRights.Read)
        {
            Imports.RegOpenKeyExW(key, subKeyName, 0, rights, out RegistryKeyHandle subKey).ThrowIfFailed();

            return(subKey);
        }
示例#5
0
        /// <summary>
        ///  Returns true if the given value exists.
        /// </summary>
        public static unsafe bool QueryValueExists(RegistryKeyHandle key, string valueName)
        {
            WindowsError result = Imports.RegQueryValueExW(key, valueName, null, null, null, null);

            return(result switch
            {
                WindowsError.ERROR_SUCCESS => true,
                WindowsError.ERROR_FILE_NOT_FOUND => false,
                _ => throw result.GetException(),
            });
示例#6
0
 public static extern WindowsError RegQueryInfoKeyW(
     RegistryKeyHandle hKey,
     SafeHandle lpClass,
     ref uint lpcClass,
     IntPtr lpReserved,
     out uint lpcSubKeys,
     out uint lpcMaxSubKeyLen,
     out uint lpcMaxClassLen,
     out uint lpcValues,
     out uint lpcMaxValueNameLen,
     out uint lpcMaxValueLen,
     out uint lpcbSecurityDescriptor,
     out FILETIME lpftLastWriteTime);
示例#7
0
        /// <summary>
        /// Open the specified subkey.
        /// </summary>
        public static RegistryKeyHandle OpenKey(
            RegistryKeyHandle key,
            string subKeyName,
            RegistryAccessRights rights = RegistryAccessRights.KEY_READ)
        {
            WindowsError result = Imports.RegOpenKeyExW(key, subKeyName, 0, rights, out RegistryKeyHandle subKey);

            if (result != WindowsError.ERROR_SUCCESS)
            {
                throw Errors.GetIoExceptionForError(result);
            }

            return(subKey);
        }
示例#8
0
        public static unsafe string QueryKeyName(RegistryKeyHandle key)
        {
            return(BufferHelper.BufferInvoke((HeapBuffer buffer) =>
            {
                NTStatus status;
                while ((status = Imports.NtQueryKey(key, KeyInformationClass.NameInformation, buffer.VoidPointer, (uint)buffer.ByteCapacity, out uint resultLength))
                       == NTStatus.STATUS_BUFFER_TOO_SMALL || status == NTStatus.STATUS_BUFFER_OVERFLOW)
                {
                    buffer.EnsureByteCapacity(resultLength);
                }

                status.ThrowIfFailed();

                return ((KEY_NAME_INFORMATION *)buffer.VoidPointer)->Name.CreateString();
            }));
        }
示例#9
0
        /// <summary>
        /// Returns true if the given value exists.
        /// </summary>
        public unsafe static bool QueryValueExists(RegistryKeyHandle key, string valueName)
        {
            WindowsError result = Imports.RegQueryValueExW(key, valueName, null, null, null, null);

            switch (result)
            {
            case WindowsError.ERROR_SUCCESS:
                return(true);

            case WindowsError.ERROR_FILE_NOT_FOUND:
                return(false);

            default:
                throw Errors.GetIoExceptionForError(result);
            }
        }
示例#10
0
        /// <summary>
        /// Gets all value names for the given registry key.
        /// </summary>
        public unsafe static IEnumerable <string> GetValueNames(RegistryKeyHandle key)
        {
            List <string> names = new List <string>();

            BufferHelper.BufferInvoke((StringBuffer buffer) =>
            {
                // Ensure we have enough space to hold the perf key values
                buffer.EnsureCharCapacity(10);
                uint bufferSize = buffer.CharCapacity;

                WindowsError result;
                while ((result = Imports.RegEnumValueW(key, (uint)names.Count, buffer.VoidPointer, ref bufferSize, null, null, null, null))
                       != WindowsError.ERROR_NO_MORE_ITEMS)
                {
                    switch (result)
                    {
                    case WindowsError.ERROR_SUCCESS:
                        buffer.Length = bufferSize;
                        names.Add(buffer.ToString());
                        break;

                    case WindowsError.ERROR_MORE_DATA:
                        if (key.IsPerfKey)
                        {
                            // Perf keys always report back ERROR_MORE_DATA,
                            // and also does not report the size of the string.
                            buffer.SetLengthToFirstNull();
                            names.Add(buffer.ToString());
                            bufferSize = buffer.CharCapacity;
                        }
                        else
                        {
                            // For some reason the name size isn't reported back,
                            // even though it is known. Why would they not do this?
                            buffer.EnsureCharCapacity(bufferSize + 100);
                            bufferSize = buffer.CharCapacity;
                        }
                        break;

                    default:
                        throw Errors.GetIoExceptionForError(result);
                    }
                }
            });

            return(names);
        }
示例#11
0
        /// <summary>
        /// Returns the type of the given value, or REG_NONE if it doesn't exist.
        /// </summary>
        public unsafe static RegistryValueType QueryValueType(RegistryKeyHandle key, string valueName)
        {
            RegistryValueType valueType = new RegistryValueType();
            WindowsError      result    = Imports.RegQueryValueExW(key, valueName, null, &valueType, null, null);

            switch (result)
            {
            case WindowsError.ERROR_SUCCESS:
                return(valueType);

            case WindowsError.ERROR_FILE_NOT_FOUND:
                return(RegistryValueType.REG_NONE);

            default:
                throw Errors.GetIoExceptionForError(result);
            }
        }
示例#12
0
        public unsafe static string QueryKeyName(RegistryKeyHandle key)
        {
            return(BufferHelper.BufferInvoke((HeapBuffer buffer) =>
            {
                NTSTATUS status;
                uint resultLength;
                while ((status = Imports.NtQueryKey(key, KEY_INFORMATION_CLASS.KeyNameInformation, buffer.VoidPointer, (uint)buffer.ByteCapacity, out resultLength))
                       == NTSTATUS.STATUS_BUFFER_TOO_SMALL || status == NTSTATUS.STATUS_BUFFER_OVERFLOW)
                {
                    buffer.EnsureByteCapacity(resultLength);
                }

                if (status != NTSTATUS.STATUS_SUCCESS)
                {
                    ErrorMethods.GetIoExceptionForNTStatus(status);
                }

                return ((KEY_NAME_INFORMATION *)buffer.VoidPointer)->Name.CreateString();
            }));
        }
示例#13
0
        /// <summary>
        /// Gets the key's value names directly from NtEnumerateValueKey. This is slightly faster
        /// and uses less memory, but only works for keys in the local machine registry and does
        /// not work with performance keys (such as HKEY_PERFORMANCE_DATA).
        ///
        /// This also doesn't give the same results for "special" (HKCR) keys that are normally
        /// redirected to user specific settings by RegEnumValue.
        /// </summary>
        /// <param name="filterTo">
        /// Only return names that have the given type, or REG_NONE for all types.
        /// </param>
        /// <remarks>
        /// RegEnumValue doesn't map directly to NtEnumerateValueKey and requires allocating a
        /// temporary buffer for *each* invocation- making the direct call here avoids this extra
        /// buffer.
        /// </remarks>
        public unsafe static IEnumerable <string> GetValueNamesDirect(RegistryKeyHandle key, RegistryValueType filterTo = RegistryValueType.REG_NONE)
        {
            List <string> names = new List <string>();

            BufferHelper.BufferInvoke((HeapBuffer buffer) =>
            {
                NTSTATUS status;
                while ((status = Imports.NtEnumerateValueKey(
                            key,
                            (uint)names.Count,
                            KEY_VALUE_INFORMATION_CLASS.KeyValueBasicInformation,
                            buffer.VoidPointer,
                            checked ((uint)buffer.ByteCapacity),
                            out uint resultLength)) != NTSTATUS.STATUS_NO_MORE_ENTRIES)
                {
                    switch (status)
                    {
                    case NTSTATUS.STATUS_SUCCESS:
                        KEY_VALUE_BASIC_INFORMATION *info = (KEY_VALUE_BASIC_INFORMATION *)buffer.VoidPointer;
                        if (filterTo == RegistryValueType.REG_NONE || info->Type == filterTo)
                        {
                            names.Add(info->Name.CreateString());
                        }
                        break;

                    case NTSTATUS.STATUS_BUFFER_OVERFLOW:
                    case NTSTATUS.STATUS_BUFFER_TOO_SMALL:
                        buffer.EnsureByteCapacity(resultLength);
                        break;

                    default:
                        throw ErrorMethods.GetIoExceptionForNTStatus(status);
                    }
                }
            });

            return(names);
        }
示例#14
0
        /// <summary>
        /// Gets the key's value data directly from NtEnumerateValueKey. This is slightly faster
        /// and uses less memory, but only works for keys in the local machine registry and does
        /// not work with performance keys (such as HKEY_PERFORMANCE_DATA).
        ///
        /// This also doesn't give the same results for "special" (HKCR) keys that are normally
        /// redirected to user specific settings by RegEnumValue.
        /// </summary>
        /// <param name="filterTo">
        /// Only return data of the given type, or REG_NONE for all types.
        /// </param>
        /// <remarks>
        /// RegEnumValue doesn't map directly to NtEnumerateValueKey and requires allocating a
        /// temporary buffer for *each* invocation- making the direct call here avoids this extra
        /// buffer.
        /// </remarks>
        public unsafe static IEnumerable <object> GetValueDataDirect(RegistryKeyHandle key, RegistryValueType filterTo = RegistryValueType.REG_NONE)
        {
            List <object> data = new List <object>();

            BufferHelper.BufferInvoke((HeapBuffer buffer) =>
            {
                NTSTATUS status;
                while ((status = Imports.NtEnumerateValueKey(
                            key,
                            (uint)data.Count,
                            KEY_VALUE_INFORMATION_CLASS.KeyValuePartialInformation,
                            buffer.VoidPointer,
                            checked ((uint)buffer.ByteCapacity),
                            out uint resultLength)) != NTSTATUS.STATUS_NO_MORE_ENTRIES)
                {
                    switch (status)
                    {
                    case NTSTATUS.STATUS_SUCCESS:
                        KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer.VoidPointer;
                        if (filterTo == RegistryValueType.REG_NONE || (*info).Type == filterTo)
                        {
                            data.Add(ReadValue(&(*info).Data, (*info).DataLength, (*info).Type));
                        }
                        break;

                    case NTSTATUS.STATUS_BUFFER_OVERFLOW:
                    case NTSTATUS.STATUS_BUFFER_TOO_SMALL:
                        buffer.EnsureByteCapacity(resultLength);
                        break;

                    default:
                        throw ErrorMethods.GetIoExceptionForNTStatus(status);
                    }
                }
            });

            return(data);
        }
示例#15
0
        public unsafe static object QueryValue(RegistryKeyHandle key, string valueName)
        {
            return(BufferHelper.BufferInvoke((HeapBuffer buffer) =>
            {
                RegistryValueType valueType = new RegistryValueType();

                WindowsError result;
                uint byteCapacity = (uint)buffer.ByteCapacity;
                while ((result = Imports.RegQueryValueExW(
                            key,
                            valueName,
                            null,
                            &valueType,
                            buffer.VoidPointer,
                            &byteCapacity)) != WindowsError.ERROR_SUCCESS)
                {
                    switch (result)
                    {
                    case WindowsError.ERROR_MORE_DATA:
                        // According to the docs, the byteCapacity given back will
                        // not be correct for HKEY_PERFORMANCE_DATA
                        byteCapacity = byteCapacity > buffer.ByteCapacity ? byteCapacity : checked (byteCapacity + 256);
                        buffer.EnsureByteCapacity(byteCapacity);
                        break;

                    case WindowsError.ERROR_FILE_NOT_FOUND:
                        return null;

                    default:
                        throw Errors.GetIoExceptionForError(result);
                    }
                }

                return ReadValue(buffer.VoidPointer, byteCapacity, valueType);
            }));
        }
示例#16
0
 public unsafe static extern NTSTATUS NtQueryKey(
     RegistryKeyHandle KeyHandle,
     KEY_INFORMATION_CLASS KeyInformationClass,
     void *KeyInformation,
     uint Length,
     out uint ResultLength);
示例#17
0
 public static extern WindowsError RegOpenKeyExW(
     RegistryKeyHandle hKey,
     string lpSubKey,
     uint ulOptions,
     RegistryAccessRights samDesired,
     out RegistryKeyHandle phkResult);