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); } }
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); } }