예제 #1
0
        public unsafe void SetStringValue(string name, string value)
        {
            if (value == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
            }

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

            EnsureWriteable();

            int result = Win32Native.RegSetValueEx(hkey,
                                                   name,
                                                   0,
                                                   RegistryValueKind.String,
                                                   value,
                                                   checked (value.Length * 2 + 2));

            if (result != 0)
            {
                Win32Error(result, null);
            }
        }
예제 #2
0
파일: RegistryKey.cs 프로젝트: relaxar/.net
        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);
            }
        }