示例#1
0
        public void DeleteValue(String name, bool throwOnMissingValue)
        {
            EnsureWriteable();
            int errorCode = Win32Native.RegDeleteValue(hkey, name);

            //
            // From windows 2003 server, if the name is too long we will get error code ERROR_FILENAME_EXCED_RANGE
            // This still means the name doesn't exist. We need to be consistent with previous OS.
            //
            if (errorCode == Win32Native.ERROR_FILE_NOT_FOUND || errorCode == Win32Native.ERROR_FILENAME_EXCED_RANGE)
            {
                if (throwOnMissingValue)
                {
                    ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSubKeyValueAbsent);
                }
                // Otherwise, just return giving no indication to the user.
                // (For compatibility)
            }
            // We really should throw an exception here if errorCode was bad,
            // but we can't for compatibility reasons.
            BCLDebug.Correctness(errorCode == 0, "RegDeleteValue failed.  Here's your error code: " + errorCode);
        }
示例#2
0
        public void DeleteSubKeyTree(string subkey, bool throwOnMissingSubKey)
        {
            ValidateKeyName(subkey);

            // Security concern: Deleting a hive's "" subkey would delete all
            // of that hive's contents.  Don't allow "".
            if (subkey.Length == 0 && IsSystemKey())
            {
                ThrowHelper.ThrowArgumentException(SR.Arg_RegKeyDelHive);
            }

            EnsureWriteable();

            subkey = FixupName(subkey); // Fixup multiple slashes to a single slash

            RegistryKey key = InternalOpenSubKeyWithoutSecurityChecks(subkey, true);
            if (key != null)
            {
                using (key)
                {
                    if (key.InternalSubKeyCount() > 0)
                    {
                        string[] keys = key.InternalGetSubKeyNames();

                        for (int i = 0; i < keys.Length; i++)
                        {
                            key.DeleteSubKeyTreeInternal(keys[i]);
                        }
                    }
                }

                DeleteSubKeyTreeCore(subkey);
            }
            else if (throwOnMissingSubKey)
            {
                ThrowHelper.ThrowArgumentException(SR.Arg_RegSubKeyAbsent);
            }
        }
示例#3
0
        private RegistryKey InternalOpenSubKeyCore(string name, RegistryRights rights, bool throwOnPermissionFailure)
        {
            SafeRegistryHandle result = null;
            int ret = Interop.mincore.RegOpenKeyEx(_hkey, name, 0, ((int)rights | (int)_regView), out result);
            if (ret == 0 && !result.IsInvalid)
            {
                RegistryKey key = new RegistryKey(result, IsWritable((int)rights), false, _remoteKey, false, _regView);
                key._keyName = _keyName + "\\" + name;
                return key;
            }

            if (throwOnPermissionFailure)
            {
                if (ret == Interop.mincore.Errors.ERROR_ACCESS_DENIED || ret == Interop.mincore.Errors.ERROR_BAD_IMPERSONATION_LEVEL)
                {
                    // We need to throw SecurityException here for compatibility reason,
                    // although UnauthorizedAccessException will make more sense.
                    ThrowHelper.ThrowSecurityException(SR.Security_RegistryPermission);
                }
            }

            // Return null if we didn't find the key.
            return null;
        }
示例#4
0
        private static void ValidateKeyName(string name)
        {
            if (name == null)
            {
                ThrowHelper.ThrowArgumentNullException(nameof(name));
            }

            int nextSlash = name.IndexOf("\\", StringComparison.OrdinalIgnoreCase);
            int current = 0;
            while (nextSlash != -1)
            {
                if ((nextSlash - current) > MaxKeyLength)
                {
                    ThrowHelper.ThrowArgumentException(SR.Arg_RegKeyStrLenBug, nameof(name));
                }
                current = nextSlash + 1;
                nextSlash = name.IndexOf("\\", current, StringComparison.OrdinalIgnoreCase);
            }

            if ((name.Length - current) > MaxKeyLength)
            {
                ThrowHelper.ThrowArgumentException(SR.Arg_RegKeyStrLenBug, nameof(name));
            }
        }
示例#5
0
        /// <summary>
        /// An internal version which does no security checks or argument checking.  Skipping the
        /// security checks should give us a slight perf gain on large trees.
        /// </summary>
        private void DeleteSubKeyTreeInternal(string subkey)
        {
            RegistryKey key = InternalOpenSubKeyWithoutSecurityChecks(subkey, true);
            if (key != null)
            {
                using (key)
                {
                    if (key.InternalSubKeyCount() > 0)
                    {
                        string[] keys = key.InternalGetSubKeyNames();
                        for (int i = 0; i < keys.Length; i++)
                        {
                            key.DeleteSubKeyTreeInternal(keys[i]);
                        }
                    }
                }

                DeleteSubKeyTreeCore(subkey);
            }
            else
            {
                ThrowHelper.ThrowArgumentException(SR.Arg_RegSubKeyAbsent);
            }
        }
示例#6
0
        public unsafe void SetValue(String name, Object value, RegistryValueKind valueKind)
        {
            if (value == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
            }

            if (name != null && name.Length > MaxValueLength)
            {
                throw new ArgumentException(SR.Arg_RegValStrLenBug);
            }

            if (!Enum.IsDefined(typeof(RegistryValueKind), valueKind))
            {
                throw new ArgumentException(SR.Arg_RegBadKeyKind, nameof(valueKind));
            }

            EnsureWriteable();

            if (valueKind == RegistryValueKind.Unknown)
            {
                // this is to maintain compatibility with the old way of autodetecting the type.
                // SetValue(string, object) will come through this codepath.
                valueKind = CalculateValueKind(value);
            }

            int ret = 0;

            try
            {
                switch (valueKind)
                {
                case RegistryValueKind.ExpandString:
                case RegistryValueKind.String:
                {
                    String data = value.ToString();
                    ret = Win32Native.RegSetValueEx(hkey,
                                                    name,
                                                    0,
                                                    valueKind,
                                                    data,
                                                    checked (data.Length * 2 + 2));
                    break;
                }

                case RegistryValueKind.MultiString:
                {
                    // Other thread might modify the input array after we calculate the buffer length.
                    // Make a copy of the input array to be safe.
                    string[] dataStrings = (string[])(((string[])value).Clone());
                    int      sizeInBytes = 0;

                    // First determine the size of the array
                    //
                    for (int i = 0; i < dataStrings.Length; i++)
                    {
                        if (dataStrings[i] == null)
                        {
                            ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetStrArrNull);
                        }
                        sizeInBytes = checked (sizeInBytes + (dataStrings[i].Length + 1) * 2);
                    }
                    sizeInBytes = checked (sizeInBytes + 2);

                    byte[] basePtr = new byte[sizeInBytes];
                    fixed(byte *b = basePtr)
                    {
                        IntPtr currentPtr = new IntPtr((void *)b);

                        // Write out the strings...
                        //
                        for (int i = 0; i < dataStrings.Length; i++)
                        {
                            // Assumes that the Strings are always null terminated.
                            String.InternalCopy(dataStrings[i], currentPtr, (checked (dataStrings[i].Length * 2)));
                            currentPtr = new IntPtr((long)currentPtr + (checked (dataStrings[i].Length * 2)));
                            *(char *)(currentPtr.ToPointer()) = '\0';
                            currentPtr = new IntPtr((long)currentPtr + 2);
                        }

                        *(char *)(currentPtr.ToPointer()) = '\0';
                        currentPtr = new IntPtr((long)currentPtr + 2);

                        ret = Win32Native.RegSetValueEx(hkey,
                                                        name,
                                                        0,
                                                        RegistryValueKind.MultiString,
                                                        basePtr,
                                                        sizeInBytes);
                    }
                    break;
                }

                case RegistryValueKind.None:
                case RegistryValueKind.Binary:
                    byte[] dataBytes = (byte[])value;
                    ret = Win32Native.RegSetValueEx(hkey,
                                                    name,
                                                    0,
                                                    (valueKind == RegistryValueKind.None ? Win32Native.REG_NONE : RegistryValueKind.Binary),
                                                    dataBytes,
                                                    dataBytes.Length);
                    break;

                case RegistryValueKind.DWord:
                {
                    // We need to use Convert here because we could have a boxed type cannot be
                    // unboxed and cast at the same time.  I.e. ((int)(object)(short) 5) will fail.
                    int data = Convert.ToInt32(value, System.Globalization.CultureInfo.InvariantCulture);

                    ret = Win32Native.RegSetValueEx(hkey,
                                                    name,
                                                    0,
                                                    RegistryValueKind.DWord,
                                                    ref data,
                                                    4);
                    break;
                }

                case RegistryValueKind.QWord:
                {
                    long data = Convert.ToInt64(value, System.Globalization.CultureInfo.InvariantCulture);

                    ret = Win32Native.RegSetValueEx(hkey,
                                                    name,
                                                    0,
                                                    RegistryValueKind.QWord,
                                                    ref data,
                                                    8);
                    break;
                }
                }
            }
            catch (OverflowException)
            {
                ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind);
            }
            catch (InvalidOperationException)
            {
                ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind);
            }
            catch (FormatException)
            {
                ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind);
            }
            catch (InvalidCastException)
            {
                ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind);
            }

            if (ret == 0)
            {
                SetDirty();
            }
            else
            {
                Win32Error(ret, null);
            }
        }
示例#7
0
        private unsafe void SetValueCore(string name, object value, RegistryValueKind valueKind)
        {
            int ret = 0;

            try
            {
                switch (valueKind)
                {
                case RegistryValueKind.ExpandString:
                case RegistryValueKind.String:
                {
                    string data = value.ToString();
                    ret = Interop.Advapi32.RegSetValueEx(_hkey,
                                                         name,
                                                         0,
                                                         valueKind,
                                                         data,
                                                         checked (data.Length * 2 + 2));
                    break;
                }

                case RegistryValueKind.MultiString:
                {
                    // Other thread might modify the input array after we calculate the buffer length.
                    // Make a copy of the input array to be safe.
                    string[] dataStrings = (string[])(((string[])value).Clone());

                    // First determine the size of the array
                    //
                    // Format is null terminator between strings and final null terminator at the end.
                    //    e.g. str1\0str2\0str3\0\0
                    //
                    int sizeInChars = 1;         // no matter what, we have the final null terminator.
                    for (int i = 0; i < dataStrings.Length; i++)
                    {
                        if (dataStrings[i] == null)
                        {
                            ThrowHelper.ThrowArgumentException(SR.Arg_RegSetStrArrNull);
                        }
                        sizeInChars = checked (sizeInChars + (dataStrings[i].Length + 1));
                    }
                    int sizeInBytes = checked (sizeInChars * sizeof(char));

                    // Write out the strings...
                    //
                    char[] dataChars        = new char[sizeInChars];
                    int    destinationIndex = 0;
                    for (int i = 0; i < dataStrings.Length; i++)
                    {
                        int length = dataStrings[i].Length;
                        dataStrings[i].CopyTo(0, dataChars, destinationIndex, length);
                        destinationIndex += (length + 1);         // +1 for null terminator, which is already zero-initialized in new array.
                    }

                    ret = Interop.Advapi32.RegSetValueEx(_hkey,
                                                         name,
                                                         0,
                                                         RegistryValueKind.MultiString,
                                                         dataChars,
                                                         sizeInBytes);

                    break;
                }

                case RegistryValueKind.None:
                case RegistryValueKind.Binary:
                    byte[] dataBytes = (byte[])value;
                    ret = Interop.Advapi32.RegSetValueEx(_hkey,
                                                         name,
                                                         0,
                                                         (valueKind == RegistryValueKind.None ? Interop.Advapi32.RegistryValues.REG_NONE : RegistryValueKind.Binary),
                                                         dataBytes,
                                                         dataBytes.Length);
                    break;

                case RegistryValueKind.DWord:
                {
                    // We need to use Convert here because we could have a boxed type cannot be
                    // unboxed and cast at the same time.  I.e. ((int)(object)(short) 5) will fail.
                    int data = Convert.ToInt32(value, System.Globalization.CultureInfo.InvariantCulture);

                    ret = Interop.Advapi32.RegSetValueEx(_hkey,
                                                         name,
                                                         0,
                                                         RegistryValueKind.DWord,
                                                         ref data,
                                                         4);
                    break;
                }

                case RegistryValueKind.QWord:
                {
                    long data = Convert.ToInt64(value, System.Globalization.CultureInfo.InvariantCulture);

                    ret = Interop.Advapi32.RegSetValueEx(_hkey,
                                                         name,
                                                         0,
                                                         RegistryValueKind.QWord,
                                                         ref data,
                                                         8);
                    break;
                }
                }
            }
            catch (Exception exc) when(exc is OverflowException || exc is InvalidOperationException || exc is FormatException || exc is InvalidCastException)
            {
                ThrowHelper.ThrowArgumentException(SR.Arg_RegSetMismatchedKind);
            }

            if (ret == 0)
            {
                SetDirty();
            }
            else
            {
                Win32Error(ret, null);
            }
        }