mirror of https://github.com/dahall/Vanara.git
Extended and improved object GetValue(this REG_VALUE_TYPE value) method
parent
583a0a9f93
commit
9609ce7eee
|
@ -1,19 +1,105 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Serialization;
|
|
||||||
using Vanara.InteropServices;
|
using Vanara.InteropServices;
|
||||||
using Vanara.PInvoke;
|
using Vanara.PInvoke;
|
||||||
|
|
||||||
|
namespace Vanara.Extensions
|
||||||
|
{
|
||||||
|
/// <summary>Extension methods for registry types.</summary>
|
||||||
|
public static class RegistryTypeExt
|
||||||
|
{
|
||||||
|
/// <summary>Gets a <see cref="REG_VALUE_TYPE"/> given a system type.</summary>
|
||||||
|
/// <param name="type">The type.</param>
|
||||||
|
/// <returns>A compatible <see cref="REG_VALUE_TYPE"/>. If no good match is found, <see cref="REG_VALUE_TYPE.REG_SZ"/> is returned.</returns>
|
||||||
|
public static REG_VALUE_TYPE GetFromType(Type type)
|
||||||
|
{
|
||||||
|
if (typeof(IEnumerable<string>).IsAssignableFrom(type))
|
||||||
|
return REG_VALUE_TYPE.REG_MULTI_SZ;
|
||||||
|
switch (Type.GetTypeCode(type))
|
||||||
|
{
|
||||||
|
case TypeCode.SByte:
|
||||||
|
case TypeCode.Byte:
|
||||||
|
case TypeCode.Int16:
|
||||||
|
case TypeCode.UInt16:
|
||||||
|
case TypeCode.Int32:
|
||||||
|
case TypeCode.UInt32:
|
||||||
|
return REG_VALUE_TYPE.REG_DWORD;
|
||||||
|
|
||||||
|
case TypeCode.Int64:
|
||||||
|
case TypeCode.UInt64:
|
||||||
|
return REG_VALUE_TYPE.REG_QWORD;
|
||||||
|
|
||||||
|
case TypeCode.Char:
|
||||||
|
case TypeCode.String:
|
||||||
|
return REG_VALUE_TYPE.REG_SZ;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (typeof(IEnumerable<byte>).IsAssignableFrom(type) || type.IsMarshalable())
|
||||||
|
return REG_VALUE_TYPE.REG_BINARY;
|
||||||
|
return REG_VALUE_TYPE.REG_SZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Gets a <see cref="REG_VALUE_TYPE"/> given a system type.</summary>
|
||||||
|
/// <typeparam name="T">The type.</typeparam>
|
||||||
|
/// <returns>A compatible <see cref="REG_VALUE_TYPE"/>. If no good match is found, <see cref="REG_VALUE_TYPE.REG_SZ"/> is returned.</returns>
|
||||||
|
public static REG_VALUE_TYPE GetFromType<T>() => GetFromType(typeof(T));
|
||||||
|
|
||||||
|
/// <summary>Extract the value of this registry type from a pointer.</summary>
|
||||||
|
/// <param name="value">The registry type value.</param>
|
||||||
|
/// <param name="ptr">The allocated memory pointer.</param>
|
||||||
|
/// <param name="size">The size of the allocated memory.</param>
|
||||||
|
/// <param name="charSet">The character set to use in conversion if applicable.</param>
|
||||||
|
/// <returns>The extracted value.</returns>
|
||||||
|
/// <exception cref="InvalidOperationException">Registry links cannot be retrived from a pointer. Please use RegOpenKeyEx.</exception>
|
||||||
|
public static object GetValue(this REG_VALUE_TYPE value, IntPtr ptr, uint size, CharSet charSet = CharSet.Auto)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case REG_VALUE_TYPE.REG_DWORD:
|
||||||
|
case REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN:
|
||||||
|
var data = ptr.Convert<byte[]>(4);
|
||||||
|
if (BitConverter.IsLittleEndian && value == REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN || !BitConverter.IsLittleEndian && value == REG_VALUE_TYPE.REG_DWORD)
|
||||||
|
Array.Reverse(data);
|
||||||
|
return BitConverter.ToUInt32(data, 0);
|
||||||
|
|
||||||
|
case REG_VALUE_TYPE.REG_EXPAND_SZ:
|
||||||
|
return Environment.ExpandEnvironmentVariables(StringHelper.GetString(ptr, charSet, size));
|
||||||
|
|
||||||
|
case REG_VALUE_TYPE.REG_MULTI_SZ:
|
||||||
|
return ptr.ToStringEnum(charSet, 0, size).ToArray();
|
||||||
|
|
||||||
|
case REG_VALUE_TYPE.REG_QWORD:
|
||||||
|
return ptr.Convert<ulong>(size);
|
||||||
|
|
||||||
|
case REG_VALUE_TYPE.REG_SZ:
|
||||||
|
return StringHelper.GetString(ptr, charSet, size);
|
||||||
|
|
||||||
|
case REG_VALUE_TYPE.REG_RESOURCE_LIST:
|
||||||
|
case REG_VALUE_TYPE.REG_FULL_RESOURCE_DESCRIPTOR:
|
||||||
|
case REG_VALUE_TYPE.REG_RESOURCE_REQUIREMENTS_LIST:
|
||||||
|
case REG_VALUE_TYPE.REG_BINARY:
|
||||||
|
return ptr.Convert<byte[]>(size);
|
||||||
|
|
||||||
|
case REG_VALUE_TYPE.REG_LINK:
|
||||||
|
throw new InvalidOperationException("Registry links cannot be retrived from a pointer. Please use RegOpenKeyEx.");
|
||||||
|
default:
|
||||||
|
case REG_VALUE_TYPE.REG_NONE:
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace Vanara.PInvoke
|
namespace Vanara.PInvoke
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A registry value can store data in various formats. When you store data under a registry value, for instance by calling the
|
/// A registry value can store data in various formats. When you store data under a registry value, for instance by calling the
|
||||||
/// RegSetValueEx function, you can specify one of the following values to indicate the type of data being stored. When you retrieve
|
/// RegSetValueEx function, you can specify one of the following values to indicate the type of data being stored. When you retrieve a
|
||||||
/// a registry value, functions such as RegQueryValueEx use these values to indicate the type of data retrieved.
|
/// registry value, functions such as RegQueryValueEx use these values to indicate the type of data retrieved.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PInvokeData("winnt.h")]
|
[PInvokeData("winnt.h")]
|
||||||
public enum REG_VALUE_TYPE : uint
|
public enum REG_VALUE_TYPE : uint
|
||||||
|
@ -52,8 +138,8 @@ namespace Vanara.PInvoke
|
||||||
REG_EXPAND_SZ = 2,
|
REG_EXPAND_SZ = 2,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A null-terminated Unicode string that contains the target path of a symbolic link that was created by calling the
|
/// A null-terminated Unicode string that contains the target path of a symbolic link that was created by calling the RegCreateKeyEx
|
||||||
/// RegCreateKeyEx function with REG_OPTION_CREATE_LINK.
|
/// function with REG_OPTION_CREATE_LINK.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
REG_LINK = 6,
|
REG_LINK = 6,
|
||||||
|
|
||||||
|
@ -62,8 +148,8 @@ namespace Vanara.PInvoke
|
||||||
/// <para>The following is an example:</para>
|
/// <para>The following is an example:</para>
|
||||||
/// <para>String1\0String2\0String3\0LastString\0\0</para>
|
/// <para>String1\0String2\0String3\0LastString\0\0</para>
|
||||||
/// <para>
|
/// <para>
|
||||||
/// The first \0 terminates the first string, the second to the last \0 terminates the last string, and the final \0 terminates
|
/// The first \0 terminates the first string, the second to the last \0 terminates the last string, and the final \0 terminates the
|
||||||
/// the sequence.Note that the final terminator must be factored into the length of the string.
|
/// sequence.Note that the final terminator must be factored into the length of the string.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[CorrespondingType(typeof(IEnumerable<string>))]
|
[CorrespondingType(typeof(IEnumerable<string>))]
|
||||||
|
@ -76,8 +162,8 @@ namespace Vanara.PInvoke
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A 64-bit number in little-endian format.
|
/// A 64-bit number in little-endian format.
|
||||||
/// <para>
|
/// <para>
|
||||||
/// Windows is designed to run on little-endian computer architectures. Therefore, this value is defined as REG_QWORD in the
|
/// Windows is designed to run on little-endian computer architectures. Therefore, this value is defined as REG_QWORD in the Windows
|
||||||
/// Windows header files.
|
/// header files.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[CorrespondingType(typeof(ulong))]
|
[CorrespondingType(typeof(ulong))]
|
||||||
|
@ -99,81 +185,3 @@ namespace Vanara.PInvoke
|
||||||
REG_RESOURCE_REQUIREMENTS_LIST = 10,
|
REG_RESOURCE_REQUIREMENTS_LIST = 10,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Vanara.Extensions
|
|
||||||
{
|
|
||||||
/// <summary>Extension methods for registry types.</summary>
|
|
||||||
public static class RegistryTypeExt
|
|
||||||
{
|
|
||||||
/// <summary>Extract the value of this registry type from a pointer.</summary>
|
|
||||||
/// <param name="value">The registry type value.</param>
|
|
||||||
/// <param name="ptr">The allocated memory pointer.</param>
|
|
||||||
/// <param name="size">The size of the allocated memory.</param>
|
|
||||||
/// <returns>The extracted value.</returns>
|
|
||||||
public static object GetValue(this Vanara.PInvoke.REG_VALUE_TYPE value, IntPtr ptr, uint size)
|
|
||||||
{
|
|
||||||
switch (value)
|
|
||||||
{
|
|
||||||
case PInvoke.REG_VALUE_TYPE.REG_DWORD:
|
|
||||||
case PInvoke.REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN:
|
|
||||||
var data = IntPtrConverter.Convert<byte[]>(ptr, 4);
|
|
||||||
if (BitConverter.IsLittleEndian && value == REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN || !BitConverter.IsLittleEndian && value == REG_VALUE_TYPE.REG_DWORD)
|
|
||||||
Array.Reverse(data);
|
|
||||||
return BitConverter.ToUInt32(data, 0);
|
|
||||||
case PInvoke.REG_VALUE_TYPE.REG_EXPAND_SZ:
|
|
||||||
return Environment.ExpandEnvironmentVariables(StringHelper.GetString(ptr, System.Runtime.InteropServices.CharSet.Auto, size));
|
|
||||||
case PInvoke.REG_VALUE_TYPE.REG_MULTI_SZ:
|
|
||||||
return ptr.ToStringEnum(System.Runtime.InteropServices.CharSet.Auto, 0, size).ToArray();
|
|
||||||
case PInvoke.REG_VALUE_TYPE.REG_QWORD:
|
|
||||||
return IntPtrConverter.Convert<ulong>(ptr, size);
|
|
||||||
case PInvoke.REG_VALUE_TYPE.REG_SZ:
|
|
||||||
return StringHelper.GetString(ptr, System.Runtime.InteropServices.CharSet.Auto, size);
|
|
||||||
case PInvoke.REG_VALUE_TYPE.REG_RESOURCE_LIST:
|
|
||||||
case PInvoke.REG_VALUE_TYPE.REG_FULL_RESOURCE_DESCRIPTOR:
|
|
||||||
case PInvoke.REG_VALUE_TYPE.REG_RESOURCE_REQUIREMENTS_LIST:
|
|
||||||
case PInvoke.REG_VALUE_TYPE.REG_BINARY:
|
|
||||||
return IntPtrConverter.Convert<byte[]>(ptr, size);
|
|
||||||
case PInvoke.REG_VALUE_TYPE.REG_LINK:
|
|
||||||
throw new InvalidOperationException("Registry links cannot be retrived from a pointer. Please use RegOpenKeyEx.");
|
|
||||||
default:
|
|
||||||
case PInvoke.REG_VALUE_TYPE.REG_NONE:
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Gets a <see cref="REG_VALUE_TYPE"/> given a system type.</summary>
|
|
||||||
/// <param name="type">The type.</param>
|
|
||||||
/// <returns>A compatible <see cref="REG_VALUE_TYPE"/>. If no good match is found, <see cref="REG_VALUE_TYPE.REG_SZ"/> is returned.</returns>
|
|
||||||
public static REG_VALUE_TYPE GetFromType(Type type)
|
|
||||||
{
|
|
||||||
if (typeof(IEnumerable<string>).IsAssignableFrom(type))
|
|
||||||
return REG_VALUE_TYPE.REG_MULTI_SZ;
|
|
||||||
switch (Type.GetTypeCode(type))
|
|
||||||
{
|
|
||||||
case TypeCode.SByte:
|
|
||||||
case TypeCode.Byte:
|
|
||||||
case TypeCode.Int16:
|
|
||||||
case TypeCode.UInt16:
|
|
||||||
case TypeCode.Int32:
|
|
||||||
case TypeCode.UInt32:
|
|
||||||
return REG_VALUE_TYPE.REG_DWORD;
|
|
||||||
case TypeCode.Int64:
|
|
||||||
case TypeCode.UInt64:
|
|
||||||
return REG_VALUE_TYPE.REG_QWORD;
|
|
||||||
case TypeCode.Char:
|
|
||||||
case TypeCode.String:
|
|
||||||
return REG_VALUE_TYPE.REG_SZ;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (typeof(IEnumerable<byte>).IsAssignableFrom(type) || type.IsMarshalable())
|
|
||||||
return REG_VALUE_TYPE.REG_BINARY;
|
|
||||||
return REG_VALUE_TYPE.REG_SZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Gets a <see cref="REG_VALUE_TYPE"/> given a system type.</summary>
|
|
||||||
/// <typeparam name="T">The type.</typeparam>
|
|
||||||
/// <returns>A compatible <see cref="REG_VALUE_TYPE"/>. If no good match is found, <see cref="REG_VALUE_TYPE.REG_SZ"/> is returned.</returns>
|
|
||||||
public static REG_VALUE_TYPE GetFromType<T>() => GetFromType(typeof(T));
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue