Another 2.0 major commit. All tests working.

pull/25/head
David Hall 2018-11-19 21:18:50 -07:00
parent 627c6d2314
commit c5467dfb7e
230 changed files with 25015 additions and 12728 deletions

View File

@ -446,7 +446,7 @@ namespace System.Collections.Generic
actualValue = k;
return true;
}
actualValue = default(T);
actualValue = default;
return false;
}

View File

@ -82,7 +82,7 @@ namespace System.Linq
/// <param name="source">The sequence to return the specified value for if it is empty.</param>
/// <param name="defaultValue">The value to return if the sequence is empty. This value defaults to <c>default(TSource)</c>.</param>
/// <returns>An <see cref="IEnumerable{T}"/> that contains <paramref name="defaultValue"/> if source is empty; otherwise, source.</returns>
public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source, TSource defaultValue = default(TSource))
public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source, TSource defaultValue = default)
{
if (source == null) throw new ArgumentNullException(nameof(source));
using (var e = source.GetEnumerator())
@ -169,7 +169,7 @@ namespace System.Linq
if (e.MoveNext()) return e.Current;
}
}
return default(TSource);
return default;
}
/// <summary>Returns the first element of the sequence that satisfies a condition or a default value if no such element is found.</summary>
@ -183,7 +183,7 @@ namespace System.Linq
if (predicate == null) throw new ArgumentNullException(nameof(predicate));
foreach (var element in source)
if (predicate(element)) return element;
return default(TSource);
return default;
}
/// <summary>Returns the minimum value in a generic sequence.</summary>

View File

@ -610,7 +610,7 @@ namespace Vanara.Collections
{
Array.Copy(internalItems, index + 1, internalItems, index, Count - index);
}
internalItems[Count] = default(T);
internalItems[Count] = default;
version++;
OnItemDeleted(index, oldVal);
}
@ -906,7 +906,7 @@ namespace Vanara.Collections
this.list = list;
index = 0;
version = list.version;
Current = default(T);
Current = default;
}
/// <summary>Gets the current.</summary>
@ -939,7 +939,7 @@ namespace Vanara.Collections
throw new InvalidOperationException();
}
index = 0;
Current = default(T);
Current = default;
}
/// <summary>Advances the enumerator to the next element of the collection.</summary>
@ -958,7 +958,7 @@ namespace Vanara.Collections
return true;
}
index = list.Count + 1;
Current = default(T);
Current = default;
return false;
}
}

View File

@ -74,7 +74,7 @@ namespace Vanara.Collections
/// <value>The element at the specified index.</value>
public T this[int index]
{
get => hashtable.TryGetValue(index, out T ret) ? ret : default(T);
get => hashtable.TryGetValue(index, out T ret) ? ret : default;
set => Insert(index, value);
}

View File

@ -50,7 +50,7 @@ namespace Vanara.Collections
/// <returns></returns>
public virtual TValue this[TKey key]
{
get => TryGetValue(key, out var value) ? value : default(TValue);
get => TryGetValue(key, out var value) ? value : default;
set => SetValue(key, value);
}
@ -141,7 +141,7 @@ namespace Vanara.Collections
Keys.Select(k => new KeyValuePair<TKey, TValue>(k, this[k]));
/// <inheritdoc />
public virtual TValue this[TKey key] => TryGetValue(key, out var value) ? value : default(TValue);
public virtual TValue this[TKey key] => TryGetValue(key, out var value) ? value : default;
/// <inheritdoc />
public abstract bool ContainsKey(TKey key);

View File

@ -99,7 +99,7 @@ namespace Vanara.Extensions
/// <summary>Clears and sets to <c>default(E)</c>.</summary>
public void Clear()
{
flags = default(TEnum);
flags = default;
}
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>

View File

@ -11,6 +11,22 @@ namespace Vanara.Extensions
/// <summary>Extension methods for System.Runtime.InteropServices.</summary>
public static partial class InteropExtensions
{
/// <summary>
/// Gets the length of a null terminated array of pointers. <note type="warning">This is a very dangerous function and can result in
/// memory access errors if the <paramref name="lptr"/> does not point to a null-terminated array of pointers.</note>
/// </summary>
/// <param name="lptr">The <see cref="IntPtr"/> pointing to the native array.</param>
/// <returns>
/// The number of non-null pointers in the array. If <paramref name="lptr"/> is equal to IntPtr.Zero, this result is 0.
/// </returns>
public static int GetNulledPtrArrayLength(this IntPtr lptr)
{
if (lptr == IntPtr.Zero) return 0;
var c = 0;
while (Marshal.ReadIntPtr(lptr, IntPtr.Size * c++) != IntPtr.Zero) ;
return c - 1;
}
/// <summary>Determines whether this type is formatted or blittable.</summary>
/// <param name="T">The type to check.</param>
/// <returns><c>true</c> if the specified type is blittable; otherwise, <c>false</c>.</returns>
@ -47,7 +63,7 @@ namespace Vanara.Extensions
/// <returns>An <see cref="IEnumerable{T}"/> exposing the elements of the linked list.</returns>
public static IEnumerable<T> LinkedListToIEnum<T>(this IntPtr ptr, Func<T, IntPtr> next)
{
for (var pCurrent = ptr; pCurrent != IntPtr.Zero; )
for (var pCurrent = ptr; pCurrent != IntPtr.Zero;)
{
var ret = pCurrent.ToStructure<T>();
yield return ret;
@ -58,12 +74,13 @@ namespace Vanara.Extensions
/// <summary>Marshals data from a managed list of specified type to a pre-allocated unmanaged block of memory.</summary>
/// <typeparam name="T">
/// A type of the enumerated managed object that holds the data to be marshaled. The object must be a structure or an instance of a formatted class.
/// A type of the enumerated managed object that holds the data to be marshaled. The object must be a structure or an instance of a
/// formatted class.
/// </typeparam>
/// <param name="items">The enumerated list of items to marshal.</param>
/// <param name="ptr">
/// A pointer to a pre-allocated block of memory. The allocated memory must be sufficient to hold the size of <typeparamref name="T"/> times the number
/// of items in the enumeration plus the number of bytes specified by <paramref name="prefixBytes"/>.
/// A pointer to a pre-allocated block of memory. The allocated memory must be sufficient to hold the size of <typeparamref
/// name="T"/> times the number of items in the enumeration plus the number of bytes specified by <paramref name="prefixBytes"/>.
/// </param>
/// <param name="prefixBytes">The number of bytes to skip before writing the first element of <paramref name="items"/>.</param>
public static void MarshalToPtr<T>(this IEnumerable<T> items, IntPtr ptr, int prefixBytes = 0)
@ -74,12 +91,17 @@ namespace Vanara.Extensions
Marshal.StructureToPtr(item, ptr.Offset(prefixBytes + i++ * stSize), false);
}
/// <summary>Marshals data from a managed list of specified type to an unmanaged block of memory allocated by the <paramref name="memAlloc"/> method.</summary>
/// <summary>
/// Marshals data from a managed list of specified type to an unmanaged block of memory allocated by the <paramref name="memAlloc"/> method.
/// </summary>
/// <typeparam name="T">
/// A type of the enumerated managed object that holds the data to be marshaled. The object must be a structure or an instance of a formatted class.
/// A type of the enumerated managed object that holds the data to be marshaled. The object must be a structure or an instance of a
/// formatted class.
/// </typeparam>
/// <param name="items">The enumerated list of items to marshal.</param>
/// <param name="memAlloc">The function that allocates the memory for the block of items (typically <see cref="Marshal.AllocCoTaskMem(int)"/> or <see cref="Marshal.AllocHGlobal(int)"/>.</param>
/// <param name="memAlloc">
/// The function that allocates the memory for the block of items (typically <see cref="Marshal.AllocCoTaskMem(int)"/> or <see cref="Marshal.AllocHGlobal(int)"/>.
/// </param>
/// <param name="bytesAllocated">The bytes allocated by the <paramref name="memAlloc"/> method.</param>
/// <param name="prefixBytes">Number of bytes preceding the trailing strings.</param>
/// <returns>Pointer to the allocated native (unmanaged) array of items stored.</returns>
@ -104,7 +126,9 @@ namespace Vanara.Extensions
return result;
}
/// <summary>Marshals data from a managed list of strings to an unmanaged block of memory allocated by the <paramref name="memAlloc"/> method.</summary>
/// <summary>
/// Marshals data from a managed list of strings to an unmanaged block of memory allocated by the <paramref name="memAlloc"/> method.
/// </summary>
/// <param name="values">The enumerated list of strings to marshal.</param>
/// <param name="packing">The packing type for the strings.</param>
/// <param name="memAlloc">
@ -114,7 +138,8 @@ namespace Vanara.Extensions
/// <param name="charSet">The character set to use for the strings.</param>
/// <param name="prefixBytes">Number of bytes preceding the trailing strings.</param>
/// <returns>
/// Pointer to the allocated native (unmanaged) array of strings stored using the <paramref name="packing"/> model and the character set defined by <paramref name="charSet"/>.
/// Pointer to the allocated native (unmanaged) array of strings stored using the <paramref name="packing"/> model and the character
/// set defined by <paramref name="charSet"/>.
/// </returns>
public static IntPtr MarshalToPtr(this IEnumerable<string> values, StringListPackMethod packing, Func<int, IntPtr> memAlloc, out int bytesAllocated, CharSet charSet = CharSet.Auto, int prefixBytes = 0)
{
@ -146,7 +171,7 @@ namespace Vanara.Extensions
if (packing == StringListPackMethod.Packed)
{
ms.Position += (count + 1) * IntPtr.Size;
for (int i = 0; i < list.Count; i++)
for (var i = 0; i < list.Count; i++)
{
ms.Poke(list[i] == null ? IntPtr.Zero : ms.Pointer.Offset(ms.Position), prefixBytes + (i * IntPtr.Size));
ms.Write(list[i]);
@ -172,8 +197,12 @@ namespace Vanara.Extensions
/// <summary>Marshals data from a managed object to an unmanaged block of memory that is allocated using <paramref name="memAlloc"/>.</summary>
/// <typeparam name="T">The type of the managed object.</typeparam>
/// <param name="value">A managed object that holds the data to be marshaled. The object must be a structure or an instance of a formatted class.</param>
/// <param name="memAlloc">The function that allocates the memory for the structure (typically <see cref="Marshal.AllocCoTaskMem(int)"/> or <see cref="Marshal.AllocHGlobal(int)"/>.</param>
/// <param name="value">
/// A managed object that holds the data to be marshaled. The object must be a structure or an instance of a formatted class.
/// </param>
/// <param name="memAlloc">
/// The function that allocates the memory for the structure (typically <see cref="Marshal.AllocCoTaskMem(int)"/> or <see cref="Marshal.AllocHGlobal(int)"/>.
/// </param>
/// <param name="bytesAllocated">The bytes allocated by the <paramref name="memAlloc"/> method.</param>
/// <returns>A pointer to the memory allocated by <paramref name="memAlloc"/>.</returns>
public static IntPtr StructureToPtr<T>(this T value, Func<int, IntPtr> memAlloc, out int bytesAllocated)
@ -214,99 +243,6 @@ namespace Vanara.Extensions
yield return ToStructure<T>(ptr.Offset(prefixBytes + i * stSize));
}
/// <summary>Converts a <see cref="UIntPtr"/> to a <see cref="IntPtr"/>.</summary>
/// <param name="p">The <see cref="UIntPtr"/>.</param>
/// <returns>An equivalent <see cref="IntPtr"/>.</returns>
public static IntPtr ToIntPtr(this UIntPtr p)
{
unsafe { return new IntPtr(p.ToPointer()); }
}
/// <summary>Converts a <see cref="IntPtr"/> to a <see cref="UIntPtr"/>.</summary>
/// <param name="p">The <see cref="IntPtr"/>.</param>
/// <returns>An equivalent <see cref="UIntPtr"/>.</returns>
public static UIntPtr ToUIntPtr(this IntPtr p)
{
unsafe { return new UIntPtr(p.ToPointer()); }
}
/// <summary>Converts an <see cref="IntPtr"/> to a structure. If pointer has no value, <c>null</c> is returned.</summary>
/// <typeparam name="T">Type of the structure.</typeparam>
/// <param name="ptr">The <see cref="IntPtr"/> that points to allocated memory holding a structure or <see cref="IntPtr.Zero"/>.</param>
/// <returns>The converted structure or <c>null</c>.</returns>
public static T? ToNullableStructure<T>(this IntPtr ptr) where T : struct => ptr != IntPtr.Zero ? ptr.ToStructure<T>() : (T?)null;
/// <summary>Marshals data from an unmanaged block of memory to a newly allocated managed object of the type specified by a generic type parameter.</summary>
/// <typeparam name="T">The type of the object to which the data is to be copied. This must be a structure.</typeparam>
/// <param name="ptr">A pointer to an unmanaged block of memory.</param>
/// <returns>A managed object that contains the data that the <paramref name="ptr"/> parameter points to.</returns>
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public static T ToStructure<T>(this IntPtr ptr) => typeof(T) == typeof(IntPtr) ? (T)(object)ptr : ((T)Marshal.PtrToStructure(ptr, typeof(T).IsEnum ? Enum.GetUnderlyingType(typeof(T)) : typeof(T)));
/// <summary>Marshals data from an unmanaged block of memory to a managed object.</summary>
/// <typeparam name="T">The type of the object to which the data is to be copied. This must be a formatted class.</typeparam>
/// <param name="ptr">A pointer to an unmanaged block of memory.</param>
/// <param name="instance">The object to which the data is to be copied. This must be an instance of a formatted class.</param>
/// <returns>A managed object that contains the data that the <paramref name="ptr"/> parameter points to.</returns>
public static T ToStructure<T>(this IntPtr ptr, [In] T instance)
{
Marshal.PtrToStructure(ptr, instance);
return instance;
}
/// <summary>
/// Gets the length of a null terminated array of pointers. <note type="warning">This is a very dangerous function and can result in memory access errors
/// if the <paramref name="lptr"/> does not point to a null-terminated array of pointers.</note>
/// </summary>
/// <param name="lptr">The <see cref="IntPtr"/> pointing to the native array.</param>
/// <returns>The number of non-null pointers in the array. If <paramref name="lptr"/> is equal to IntPtr.Zero, this result is 0.</returns>
public static int GetNulledPtrArrayLength(this IntPtr lptr)
{
if (lptr == IntPtr.Zero) return 0;
var c = 0;
while (Marshal.ReadIntPtr(lptr, IntPtr.Size * c++) != IntPtr.Zero) ;
return c - 1;
}
/// <summary>Returns an enumeration of strings from memory where each string is pointed to by a preceding list of pointers of length <paramref name="count"/>.</summary>
/// <param name="ptr">The <see cref="IntPtr"/> pointing to the native array.</param>
/// <param name="count">The count of expected strings.</param>
/// <param name="charSet">The character set of the strings.</param>
/// <param name="prefixBytes">Number of bytes preceding the array of string pointers.</param>
/// <returns>Enumeration of strings.</returns>
public static IEnumerable<string> ToStringEnum(this IntPtr ptr, int count, CharSet charSet = CharSet.Auto, int prefixBytes = 0)
{
if (ptr == IntPtr.Zero || count == 0) yield break;
var lPtrVal = ptr.ToInt64();
for (var i = 0; i < count; i++)
{
var iptr = new IntPtr(lPtrVal + prefixBytes + i * IntPtr.Size);
var sptr = Marshal.ReadIntPtr(iptr);
yield return StringHelper.GetString(sptr, charSet);
}
}
/// <summary>
/// Gets an enumerated list of strings from a block of unmanaged memory where each string is separated by a single '\0' character and is terminated by
/// two '\0' characters.
/// </summary>
/// <param name="lptr">The <see cref="IntPtr"/> pointing to the native array.</param>
/// <param name="charSet">The character set of the strings.</param>
/// <param name="prefixBytes">Number of bytes preceding the array of string pointers.</param>
/// <returns>An enumerated list of strings.</returns>
public static IEnumerable<string> ToStringEnum(this IntPtr lptr, CharSet charSet = CharSet.Auto, int prefixBytes = 0)
{
if (lptr == IntPtr.Zero) yield break;
var charLength = StringHelper.GetCharSize(charSet);
int GetCh(IntPtr p) => charLength == 1 ? Marshal.ReadByte(p) : Marshal.ReadInt16(p);
for (var ptr = lptr.Offset(prefixBytes); GetCh(ptr) != 0;)
{
var s = StringHelper.GetString(ptr, charSet);
yield return s;
ptr = ptr.Offset(((s?.Length ?? 0) + 1) * charLength);
}
}
/// <summary>Converts a <see cref="SecureString"/> to a string.</summary>
/// <param name="s">The <see cref="SecureString"/> value.</param>
/// <returns>The extracted string.</returns>
@ -326,6 +262,20 @@ namespace Vanara.Extensions
}
}
/// <summary>Converts a <see cref="UIntPtr"/> to a <see cref="IntPtr"/>.</summary>
/// <param name="p">The <see cref="UIntPtr"/>.</param>
/// <returns>An equivalent <see cref="IntPtr"/>.</returns>
public static IntPtr ToIntPtr(this UIntPtr p)
{
unsafe { return new IntPtr(p.ToPointer()); }
}
/// <summary>Converts an <see cref="IntPtr"/> to a structure. If pointer has no value, <c>null</c> is returned.</summary>
/// <typeparam name="T">Type of the structure.</typeparam>
/// <param name="ptr">The <see cref="IntPtr"/> that points to allocated memory holding a structure or <see cref="IntPtr.Zero"/>.</param>
/// <returns>The converted structure or <c>null</c>.</returns>
public static T? ToNullableStructure<T>(this IntPtr ptr) where T : struct => ptr != IntPtr.Zero ? ptr.ToStructure<T>() : (T?)null;
/// <summary>Converts a pointer to an unmanaged Unicode string to a <see cref="SecureString"/>.</summary>
/// <param name="p">A pointer to an unmanaged Unicode string.</param>
/// <returns>A <see cref="SecureString"/> with the contents of the in memory string.</returns>
@ -371,5 +321,74 @@ namespace Vanara.Extensions
ss.MakeReadOnly();
return ss;
}
/// <summary>
/// Returns an enumeration of strings from memory where each string is pointed to by a preceding list of pointers of length <paramref name="count"/>.
/// </summary>
/// <param name="ptr">The <see cref="IntPtr"/> pointing to the native array.</param>
/// <param name="count">The count of expected strings.</param>
/// <param name="charSet">The character set of the strings.</param>
/// <param name="prefixBytes">Number of bytes preceding the array of string pointers.</param>
/// <returns>Enumeration of strings.</returns>
public static IEnumerable<string> ToStringEnum(this IntPtr ptr, int count, CharSet charSet = CharSet.Auto, int prefixBytes = 0)
{
if (ptr == IntPtr.Zero || count == 0) yield break;
var lPtrVal = ptr.ToInt64();
for (var i = 0; i < count; i++)
{
var iptr = new IntPtr(lPtrVal + prefixBytes + i * IntPtr.Size);
var sptr = Marshal.ReadIntPtr(iptr);
yield return StringHelper.GetString(sptr, charSet);
}
}
/// <summary>
/// Gets an enumerated list of strings from a block of unmanaged memory where each string is separated by a single '\0' character and
/// is terminated by two '\0' characters.
/// </summary>
/// <param name="lptr">The <see cref="IntPtr"/> pointing to the native array.</param>
/// <param name="charSet">The character set of the strings.</param>
/// <param name="prefixBytes">Number of bytes preceding the array of string pointers.</param>
/// <returns>An enumerated list of strings.</returns>
public static IEnumerable<string> ToStringEnum(this IntPtr lptr, CharSet charSet = CharSet.Auto, int prefixBytes = 0)
{
if (lptr == IntPtr.Zero) yield break;
var charLength = StringHelper.GetCharSize(charSet);
int GetCh(IntPtr p) => charLength == 1 ? Marshal.ReadByte(p) : Marshal.ReadInt16(p);
for (var ptr = lptr.Offset(prefixBytes); GetCh(ptr) != 0;)
{
var s = StringHelper.GetString(ptr, charSet);
yield return s;
ptr = ptr.Offset(((s?.Length ?? 0) + 1) * charLength);
}
}
/// <summary>
/// Marshals data from an unmanaged block of memory to a newly allocated managed object of the type specified by a generic type parameter.
/// </summary>
/// <typeparam name="T">The type of the object to which the data is to be copied. This must be a structure.</typeparam>
/// <param name="ptr">A pointer to an unmanaged block of memory.</param>
/// <returns>A managed object that contains the data that the <paramref name="ptr"/> parameter points to.</returns>
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public static T ToStructure<T>(this IntPtr ptr) => typeof(T) == typeof(IntPtr) ? (T)(object)ptr : ((T)Marshal.PtrToStructure(ptr, typeof(T).IsEnum ? Enum.GetUnderlyingType(typeof(T)) : typeof(T)));
/// <summary>Marshals data from an unmanaged block of memory to a managed object.</summary>
/// <typeparam name="T">The type of the object to which the data is to be copied. This must be a formatted class.</typeparam>
/// <param name="ptr">A pointer to an unmanaged block of memory.</param>
/// <param name="instance">The object to which the data is to be copied. This must be an instance of a formatted class.</param>
/// <returns>A managed object that contains the data that the <paramref name="ptr"/> parameter points to.</returns>
public static T ToStructure<T>(this IntPtr ptr, [In] T instance)
{
Marshal.PtrToStructure(ptr, instance);
return instance;
}
/// <summary>Converts a <see cref="IntPtr"/> to a <see cref="UIntPtr"/>.</summary>
/// <param name="p">The <see cref="IntPtr"/>.</param>
/// <returns>An equivalent <see cref="UIntPtr"/>.</returns>
public static UIntPtr ToUIntPtr(this IntPtr p)
{
unsafe { return new UIntPtr(p.ToPointer()); }
}
}
}

View File

@ -38,7 +38,7 @@ namespace Vanara.Extensions
/// <param name="propertyName">Name of the property.</param>
/// <param name="defaultValue">The default value to return in the instance that the property is not found.</param>
/// <returns>The property value, if found, or the <paramref name="defaultValue"/> if not.</returns>
public static T GetPropertyValue<T>(this object obj, string propertyName, T defaultValue = default(T))
public static T GetPropertyValue<T>(this object obj, string propertyName, T defaultValue = default)
{
var prop = obj.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, typeof(T), Type.EmptyTypes, null);
if (prop == null) return defaultValue;

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using Vanara.Extensions;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedMember.Global
@ -13,19 +14,23 @@ namespace Vanara.InteropServices
{
/// <summary>No actions may be taken.</summary>
None = 0,
/// <summary>The type can be retrieved.</summary>
Get = 1,
/// <summary>The type can be set.</summary>
Set = 2,
/// <summary>The type can be retrieved and set.</summary>
GetSet = 3,
/// <summary>Throw a <see cref="Exception"/> if this enumeration value is used.</summary>
Exception = 4
}
/// <summary>
/// Attribute for enum values that provides information about corresponding types and related actions. Useful for Get/Set methods that use an enumeration
/// value to determine the type to get or set.
/// Attribute for enum values that provides information about corresponding types and related actions. Useful for Get/Set methods that
/// use an enumeration value to determine the type to get or set.
/// </summary>
/// <seealso cref="System.Attribute"/>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Class, AllowMultiple = true)]
@ -42,10 +47,7 @@ namespace Vanara.InteropServices
/// <summary>Initializes a new instance of the <see cref="CorrespondingTypeAttribute"/> class.</summary>
/// <param name="action">The actions allowed for the type.</param>
public CorrespondingTypeAttribute(CorrepsondingAction action)
{
Action = action;
}
public CorrespondingTypeAttribute(CorrepsondingAction action) => Action = action;
/// <summary>Gets the action allowed for the type.</summary>
/// <value>The action allowed for the type.</value>
@ -59,37 +61,33 @@ namespace Vanara.InteropServices
/// <param name="value">The enumeration value or class instance.</param>
/// <param name="typeRef">The type supplied by the user to validate.</param>
/// <returns><c>true</c> if this instance can get the specified type; otherwise, <c>false</c>.</returns>
public static bool CanGet(object value, Type typeRef)
{
return GetAttrForObj(value).Any(a => a.Action.IsFlagSet(CorrepsondingAction.Get) && a.TypeRef == typeRef);
}
public static bool CanGet(object value, Type typeRef) => GetAttrForObj(value).Any(a => a.Action.IsFlagSet(CorrepsondingAction.Get) && a.TypeRef == typeRef);
public static bool CanGet<TEnum>(TEnum value, Type typeRef) where TEnum : System.Enum => GetAttrForEnum(value).Any(a => a.Action.IsFlagSet(CorrepsondingAction.Get) && a.TypeRef == typeRef);
/// <summary>Determines whether this type can get the specified reference type.</summary>
/// <param name="type">The class type.</param>
/// <param name="typeRef">The type supplied by the user to validate.</param>
/// <returns><c>true</c> if this type can get the specified reference type; otherwise, <c>false</c>.</returns>
public static bool CanGet(Type type, Type typeRef)
{
return GetAttrForType(type).Any(a => a.Action.IsFlagSet(CorrepsondingAction.Get) && a.TypeRef == typeRef);
}
public static bool CanGet(Type type, Type typeRef) => GetAttrForType(type).Any(a => a.Action.IsFlagSet(CorrepsondingAction.Get) && a.TypeRef == typeRef);
/// <summary>Determines whether this instance can set the type for the specified enum value or class.</summary>
/// <param name="value">The enumeration value or class instance.</param>
/// <param name="typeRef">The type supplied by the user to validate.</param>
/// <returns><c>true</c> if this instance can set the specified type; otherwise, <c>false</c>.</returns>
public static bool CanSet(object value, Type typeRef)
{
return GetAttrForObj(value).Any(a => a.Action.IsFlagSet(CorrepsondingAction.Set) && a.TypeRef == typeRef);
}
public static bool CanSet(object value, Type typeRef) => GetAttrForObj(value).Any(a => a.Action.IsFlagSet(CorrepsondingAction.Set) && a.TypeRef == typeRef);
/// <summary>Determines whether this instance can set the type for the specified enum value or class.</summary>
/// <param name="value">The enumeration value or class instance.</param>
/// <param name="typeRef">The type supplied by the user to validate.</param>
/// <returns><c>true</c> if this instance can set the specified type; otherwise, <c>false</c>.</returns>
public static bool CanSet<TEnum>(TEnum value, Type typeRef) where TEnum : System.Enum => GetAttrForEnum(value).Any(a => a.Action.IsFlagSet(CorrepsondingAction.Set) && a.TypeRef == typeRef);
/// <summary>Determines whether this type can set the specified reference type.</summary>
/// <param name="type">The class type.</param>
/// <param name="typeRef">The type supplied by the user to validate.</param>
/// <returns><c>true</c> if this type can set the specified reference type; otherwise, <c>false</c>.</returns>
public static bool CanSet(Type type, Type typeRef)
{
return GetAttrForType(type).Any(a => a.Action.IsFlagSet(CorrepsondingAction.Set) && a.TypeRef == typeRef);
}
public static bool CanSet(Type type, Type typeRef) => GetAttrForType(type).Any(a => a.Action.IsFlagSet(CorrepsondingAction.Set) && a.TypeRef == typeRef);
/// <summary>Gets the corresponding types for the supplied enumeration value.</summary>
/// <param name="enumValue">The enumeration value or class.</param>
@ -101,12 +99,24 @@ namespace Vanara.InteropServices
/// <returns>The types defined by the attribute.</returns>
public static IEnumerable<Type> GetCorrespondingTypes(Type type) => GetAttrForType(type).Select(a => a.TypeRef);
/// <summary>Gets the CorrespondingTypeAttribute instances associated with an enum value.</summary>
/// <param name="value">The enum value.</param>
/// <returns>An enumeration of all associated CorrespondingTypeAttribute instances.</returns>
protected static IEnumerable<CorrespondingTypeAttribute> GetAttrForEnum<TEnum>(TEnum value) where TEnum : System.Enum
{
var valueType = value.GetType();
var attr = valueType.GetField(value.ToString()).GetCustomAttributes<CorrespondingTypeAttribute>();
if (!attr.Any()) return new CorrespondingTypeAttribute[0];
if (attr.Any(a => a.Action == CorrepsondingAction.Exception)) throw new Exception();
return attr;
}
/// <summary>Gets the CorrespondingTypeAttribute instances associated with an enum value.</summary>
/// <param name="value">The enum value.</param>
/// <returns>An enumeration of all associated CorrespondingTypeAttribute instances.</returns>
protected static IEnumerable<CorrespondingTypeAttribute> GetAttrForObj(object value)
{
if (value == null) throw new ArgumentNullException(nameof(value));
if (value is null) throw new ArgumentNullException(nameof(value));
var valueType = value.GetType();
if (!valueType.IsEnum && !valueType.IsClass) throw new ArgumentException("Value must be an enumeration or class value.", nameof(value));
var attr = (valueType.IsEnum ? valueType.GetField(value.ToString()).GetCustomAttributes<CorrespondingTypeAttribute>() : valueType.GetCustomAttributes<CorrespondingTypeAttribute>());

View File

@ -77,7 +77,7 @@ namespace Vanara.InteropServices
/// <typeparam name="T">Native type</typeparam>
/// <param name="value">The value.</param>
/// <returns><see cref="SafeHGlobalHandle"/> object to an native (unmanaged) memory block the size of T.</returns>
public static SafeHGlobalHandle CreateFromStructure<T>(T value = default(T)) => new SafeHGlobalHandle(InteropExtensions.StructureToPtr(value, new HGlobalMemoryMethods().AllocMem, out int s), s);
public static SafeHGlobalHandle CreateFromStructure<T>(T value = default) => new SafeHGlobalHandle(InteropExtensions.StructureToPtr(value, new HGlobalMemoryMethods().AllocMem, out int s), s);
/// <summary>
/// Allocates from unmanaged memory to represent a structure with a variable length array at the end and marshal these structure elements. It is the

View File

@ -64,52 +64,6 @@ namespace Vanara.PInvoke
SECURITY_OBJECT_ID_CENTRAL_ACCESS_RULE = 4
}
/// <summary>Flags that indicate where the access right is displayed or whether other containers or objects can inherit the access right.</summary>
[Flags]
public enum SI_ACCESS_Flags : uint
{
/// <summary>The access right is displayed on the advanced security pages.</summary>
SI_ACCESS_SPECIFIC = 0x00010000,
/// <summary>The access right is displayed on the basic security page.</summary>
SI_ACCESS_GENERAL = 0x00020000,
/// <summary>
/// Indicates an access right that applies only to containers. If this flag is set, the access right is displayed on the basic security page only if
/// the <see cref="ISecurityInformation.GetObjectInformation(ref SI_OBJECT_INFO)"/> specifies the SI_CONTAINER flag.
/// </summary>
SI_ACCESS_CONTAINER = 0x00040000,
/// <summary>Indicates a property-specific access right.</summary>
SI_ACCESS_PROPERTY = 0x00080000,
/// <summary>Other containers that are contained by the primary object inherit the entry.</summary>
CONTAINER_INHERIT_ACE = 2,
/// <summary>
/// The ACE is inherited. Operations that change the security on a tree of objects may modify inherited ACEs without changing ACEs that were directly
/// applied to the object.
/// </summary>
INHERITED_ACE = 0x10,
/// <summary>
/// The ACE does not apply to the primary object to which the ACL is attached, but objects contained by the primary object inherit the entry.
/// </summary>
INHERIT_ONLY_ACE = 8,
/// <summary>The ObjectInheritAce and ContainerInheritAce bits are not propagated to an inherited ACE.</summary>
NO_PROPAGATE_INHERIT_ACE = 4,
/// <summary>Noncontainer objects contained by the primary object inherit the entry.</summary>
OBJECT_INHERIT_ACE = 1,
}
/// <summary>Indicate the types of ACEs that can be inherited in a <see cref="SI_INHERIT_TYPE"/> structure.</summary>
[Flags]
public enum SI_INHERIT_Flags : uint
{
/// <summary>The specified object type can inherit ACEs that have the <c>CONTAINER_INHERIT_ACE</c> flag set.</summary>
CONTAINER_INHERIT_ACE = 2,
/// <summary>The specified object type can inherit ACEs that have the <c>INHERIT_ONLY_ACE</c> flag set.</summary>
INHERIT_ONLY_ACE = 8,
/// <summary>The specified object type can inherit ACEs that have the <c>OBJECT_INHERIT_ACE</c> flag set.</summary>
OBJECT_INHERIT_ACE = 1
}
/// <summary>A set of bit flags that determine the editing options available to the user.</summary>
[Flags]
public enum SI_OBJECT_INFO_Flags : uint
@ -357,7 +311,7 @@ namespace Vanara.PInvoke
/// A pointer to a ULONG variable that receives the count of granted access masks pointed to by the ppGrantedAccessList parameter.
/// </param>
void GetEffectivePermission(in Guid pguidObjectType, [In] PSID pUserSid,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszServerName, [In] IntPtr pSD,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszServerName, [In] PSECURITY_DESCRIPTOR pSD,
[MarshalAs(UnmanagedType.LPArray)] out OBJECT_TYPE_LIST[] ppObjectTypeList,
out uint pcObjectTypeListLength,
[MarshalAs(UnmanagedType.LPArray)] out uint[] ppGrantedAccessList,
@ -501,7 +455,7 @@ namespace Vanara.PInvoke
/// </para>
/// <para>If this flag is FALSE, ppSecurityDescriptor should return the object's current security descriptor.</para>
/// </param>
void GetSecurity([In] SECURITY_INFORMATION RequestInformation, out IntPtr SecurityDescriptor, [In, MarshalAs(UnmanagedType.Bool)] bool fDefault);
void GetSecurity([In] SECURITY_INFORMATION RequestInformation, out PSECURITY_DESCRIPTOR SecurityDescriptor, [In, MarshalAs(UnmanagedType.Bool)] bool fDefault);
/// <summary>
/// The SetSecurity method provides a security descriptor containing the security information the user wants to apply to the securable object. The
@ -512,7 +466,7 @@ namespace Vanara.PInvoke
/// A pointer to a security descriptor containing the new security information. Do not assume the security descriptor is in self-relative form; it
/// can be either absolute or self-relative.
/// </param>
void SetSecurity([In] SECURITY_INFORMATION RequestInformation, [In] IntPtr SecurityDescriptor);
void SetSecurity([In] SECURITY_INFORMATION RequestInformation, [In] PSECURITY_DESCRIPTOR SecurityDescriptor);
/// <summary>
/// The GetAccessRights method requests information about the access rights that can be controlled for a securable object. The access control editor
@ -594,7 +548,7 @@ namespace Vanara.PInvoke
/// client. Returns FALSE if the ACEs are not ordered correctly.
/// </returns>
[return: MarshalAs(UnmanagedType.Bool)]
bool IsDaclCanonical([In] IntPtr pDacl);
bool IsDaclCanonical([In] PACL pDacl);
/// <summary>The LookupSids method returns the common names corresponding to each of the elements in the specified list of SIDs.</summary>
/// <param name="cSids">The number of pointers to SID structures pointed to by rgpSids.</param>
@ -672,7 +626,7 @@ namespace Vanara.PInvoke
/// as the number of ACEs in the ACL referenced by pACL. Each INHERITED_FROM entry in ppInheritArray provides inheritance information for the
/// corresponding ACE entry in pACL.
/// </param>
void GetInheritSource([In] int si, [In] IntPtr pACL, [MarshalAs(UnmanagedType.LPArray)] out INHERITED_FROM[] ppInheritArray);
void GetInheritSource([In] int si, [In] PACL pACL, [MarshalAs(UnmanagedType.LPArray)] out INHERITED_FROM[] ppInheritArray);
}
/// <summary>
@ -812,15 +766,15 @@ namespace Vanara.PInvoke
[MarshalAs(UnmanagedType.LPWStr)]
public string pszName;
/// <summary>A set of <see cref="SI_ACCESS_Flags"/> that indicate where the access right is displayed.</summary>
public SI_ACCESS_Flags dwFlags;
/// <summary>A set of <see cref="INHERIT_FLAGS"/> that indicate where the access right is displayed.</summary>
public INHERIT_FLAGS dwFlags;
/// <summary>Initializes a new instance of the <see cref="SI_ACCESS"/> class.</summary>
/// <param name="mask">The access mask.</param>
/// <param name="name">The display name.</param>
/// <param name="flags">The access flags.</param>
/// <param name="objType">Type of the object.</param>
public SI_ACCESS(uint mask, string name, SI_ACCESS_Flags flags, Guid? objType = null)
public SI_ACCESS(uint mask, string name, INHERIT_FLAGS flags, Guid? objType = null)
{
this.mask = mask;
pszName = name;
@ -868,10 +822,10 @@ namespace Vanara.PInvoke
public IntPtr pguid;
/// <summary>
/// A set of <see cref="SI_INHERIT_Flags"/> that indicate the types of ACEs that can be inherited by the <see cref="ChildObjectTypeId"/>. These flags
/// A set of <see cref="INHERIT_FLAGS"/> that indicate the types of ACEs that can be inherited by the <see cref="ChildObjectTypeId"/>. These flags
/// correspond to the AceFlags member of an ACE_HEADER structure.
/// </summary>
public SI_INHERIT_Flags dwFlags;
public INHERIT_FLAGS dwFlags;
/// <summary>A display string that describes the child object.</summary>
[MarshalAs(UnmanagedType.LPWStr)]
@ -880,7 +834,7 @@ namespace Vanara.PInvoke
/// <summary>Initializes a new instance of the <see cref="SI_INHERIT_TYPE"/> struct.</summary>
/// <param name="flags">The inheritance flags.</param>
/// <param name="name">The display name.</param>
public SI_INHERIT_TYPE(SI_INHERIT_Flags flags, string name)
public SI_INHERIT_TYPE(INHERIT_FLAGS flags, string name)
{
dwFlags = flags;
pszName = name;
@ -890,7 +844,7 @@ namespace Vanara.PInvoke
/// <param name="childObjectType">Type of the child object.</param>
/// <param name="flags">The inheritance flags.</param>
/// <param name="name">The display name.</param>
public SI_INHERIT_TYPE(Guid childObjectType, SI_INHERIT_Flags flags, string name) : this(flags, name)
public SI_INHERIT_TYPE(Guid childObjectType, INHERIT_FLAGS flags, string name) : this(flags, name)
{
ChildObjectTypeId = childObjectType;
}

View File

@ -753,7 +753,7 @@ namespace Vanara.PInvoke
{
if (!dwFlags.IsFlagSet(PropSheetFlags.PSP_DLGINDIRECT)) FreeResource(ref _pszTemplate);
dwFlags = dwFlags.SetFlags(PropSheetFlags.PSP_DLGINDIRECT, false);
_pszTemplate = value.GetClonedHandle();
_pszTemplate = GetClonedHandle(value);
}
}
@ -777,13 +777,13 @@ namespace Vanara.PInvoke
/// A handle to the icon to use as the small icon in the tab for the page. If dwFlags does not include the PSP_USEHICON value,
/// this member is ignored.
/// </summary>
public IntPtr hIcon
public HICON hIcon
{
get => dwFlags.IsFlagSet(PropSheetFlags.PSP_USEHICON) ? _hIcon : IntPtr.Zero;
set
{
if (dwFlags.IsFlagSet(PropSheetFlags.PSP_USEICONID)) FreeResource(ref _pszTemplate);
_hIcon = value;
_hIcon = (IntPtr)value;
dwFlags = dwFlags.SetFlags(PropSheetFlags.PSP_USEICONID, false) | PropSheetFlags.PSP_USEHICON;
}
}
@ -800,7 +800,7 @@ namespace Vanara.PInvoke
{
if (dwFlags.IsFlagSet(PropSheetFlags.PSP_USEICONID)) FreeResource(ref _hIcon);
dwFlags = dwFlags.SetFlags(PropSheetFlags.PSP_USEHICON, false) | PropSheetFlags.PSP_USEICONID;
_hIcon = value.GetClonedHandle();
_hIcon = GetClonedHandle(value);
}
}
@ -816,7 +816,7 @@ namespace Vanara.PInvoke
{
if (dwFlags.IsFlagSet(PropSheetFlags.PSP_USETITLE)) FreeResource(ref _pszTitle);
dwFlags = dwFlags.SetFlags(PropSheetFlags.PSP_USETITLE, !value.IsInvalid);
_pszTitle = value.GetClonedHandle();
_pszTitle = GetClonedHandle(value);
}
}
@ -841,7 +841,7 @@ namespace Vanara.PInvoke
{
if (dwFlags.IsFlagSet(PropSheetFlags.PSP_USEHEADERTITLE)) FreeResource(ref _pszHeaderTitle);
dwFlags = dwFlags.SetFlags(PropSheetFlags.PSP_USEHEADERTITLE, !value.IsInvalid);
_pszHeaderTitle = value.GetClonedHandle();
_pszHeaderTitle = GetClonedHandle(value);
}
}
@ -867,7 +867,7 @@ namespace Vanara.PInvoke
{
if (dwFlags.IsFlagSet(PropSheetFlags.PSP_USEHEADERSUBTITLE)) FreeResource(ref _pszHeaderSubTitle);
dwFlags = dwFlags.SetFlags(PropSheetFlags.PSP_USEHEADERSUBTITLE, !value.IsInvalid);
_pszHeaderSubTitle = value.GetClonedHandle();
_pszHeaderSubTitle = GetClonedHandle(value);
}
}
@ -909,6 +909,8 @@ namespace Vanara.PInvoke
FreeResource(ref _pszHeaderSubTitle);
}
private static IntPtr GetClonedHandle(SafeResourceId rid) => rid == null ? IntPtr.Zero : (rid.IsIntResource ? rid.DangerousGetHandle() : StringHelper.AllocString(rid.ToString()));
private static void FreeResource(ref IntPtr ptr)
{
if (IS_INTRESOURCE(ptr) || ptr == IntPtr.Zero) return;

View File

@ -0,0 +1,189 @@
using System;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
public static partial class Gdi32
{
/// <summary>
/// <para>
/// The <c>CreateEnhMetaFile</c> function creates a device context for an enhanced-format metafile. This device context can be used
/// to store a device-independent picture.
/// </para>
/// </summary>
/// <param name="hdc">
/// <para>
/// A handle to a reference device for the enhanced metafile. This parameter can be <c>NULL</c>; for more information, see Remarks.
/// </para>
/// </param>
/// <param name="lpFilename">
/// <para>
/// A pointer to the file name for the enhanced metafile to be created. If this parameter is <c>NULL</c>, the enhanced metafile is
/// memory based and its contents are lost when it is deleted by using the DeleteEnhMetaFile function.
/// </para>
/// </param>
/// <param name="lprc">
/// <para>
/// A pointer to a RECT structure that specifies the dimensions (in .01-millimeter units) of the picture to be stored in the enhanced metafile.
/// </para>
/// </param>
/// <param name="lpDesc">
/// <para>
/// A pointer to a string that specifies the name of the application that created the picture, as well as the picture's title. This
/// parameter can be <c>NULL</c>; for more information, see Remarks.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is a handle to the device context for the enhanced metafile.</para>
/// <para>If the function fails, the return value is <c>NULL</c>.</para>
/// </returns>
/// <remarks>
/// <para>
/// Where text arguments must use Unicode characters, use the <c>CreateEnhMetaFile</c> function as a wide-character function. Where
/// text arguments must use characters from the Windows character set, use this function as an ANSI function.
/// </para>
/// <para>
/// The system uses the reference device identified by the hdcRef parameter to record the resolution and units of the device on which
/// a picture originally appeared. If the hdcRef parameter is <c>NULL</c>, it uses the current display device for reference.
/// </para>
/// <para>
/// The <c>left</c> and <c>top</c> members of the RECT structure pointed to by the lpRect parameter must be less than the
/// <c>right</c> and <c>bottom</c> members, respectively. Points along the edges of the rectangle are included in the picture. If
/// lpRect is <c>NULL</c>, the graphics device interface (GDI) computes the dimensions of the smallest rectangle that surrounds the
/// picture drawn by the application. The lpRect parameter should be provided where possible.
/// </para>
/// <para>
/// The string pointed to by the lpDescription parameter must contain a null character between the application name and the picture
/// name and must terminate with two null charactersfor example, "XYZ Graphics Editor\0Bald Eagle\0\0", where \0 represents the null
/// character. If lpDescription is <c>NULL</c>, there is no corresponding entry in the enhanced-metafile header.
/// </para>
/// <para>
/// Applications use the device context created by this function to store a graphics picture in an enhanced metafile. The handle
/// identifying this device context can be passed to any GDI function.
/// </para>
/// <para>
/// After an application stores a picture in an enhanced metafile, it can display the picture on any output device by calling the
/// PlayEnhMetaFile function. When displaying the picture, the system uses the rectangle pointed to by the lpRect parameter and the
/// resolution data from the reference device to position and scale the picture.
/// </para>
/// <para>The device context returned by this function contains the same default attributes associated with any new device context.</para>
/// <para>Applications must use the GetWinMetaFileBits function to convert an enhanced metafile to the older Windows metafile format.</para>
/// <para>The file name for the enhanced metafile should use the .emf extension.</para>
/// <para>Examples</para>
/// <para>For an example, see Creating an Enhanced Metafile.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/nf-wingdi-createenhmetafilea HDC CreateEnhMetaFileA( HDC hdc, LPCSTR
// lpFilename, const RECT *lprc, LPCSTR lpDesc );
[DllImport(Lib.Gdi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("wingdi.h", MSDNShortId = "647f83ca-dca3-44af-a594-5f9ba2bd7607")]
public static extern HDC CreateEnhMetaFile(HDC hdc, string lpFilename, ref RECT lprc, string lpDesc);
/// <summary>
/// <para>The <c>DeleteEnhMetaFile</c> function deletes an enhanced-format metafile or an enhanced-format metafile handle.</para>
/// </summary>
/// <param name="hmf">
/// <para>A handle to an enhanced metafile.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero.</para>
/// </returns>
/// <remarks>
/// <para>
/// If the hemf parameter identifies an enhanced metafile stored in memory, the <c>DeleteEnhMetaFile</c> function deletes the
/// metafile. If hemf identifies a metafile stored on a disk, the function deletes the metafile handle but does not destroy the
/// actual metafile. An application can retrieve the file by calling the GetEnhMetaFile function.
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Opening an Enhanced Metafile and Displaying Its Contents.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/nf-wingdi-deleteenhmetafile BOOL DeleteEnhMetaFile( HENHMETAFILE hmf );
[DllImport(Lib.Gdi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wingdi.h", MSDNShortId = "d3b93b3b-fa0b-4480-8348-19919c9e904d")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeleteEnhMetaFile(HENHMETAFILE hmf);
/// <summary>
/// <para>
/// The <c>GetEnhMetaFile</c> function creates a handle that identifies the enhanced-format metafile stored in the specified file.
/// </para>
/// </summary>
/// <param name="lpName">
/// <para>A pointer to a null-terminated string that specifies the name of an enhanced metafile.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is a handle to the enhanced metafile.</para>
/// <para>If the function fails, the return value is <c>NULL</c>.</para>
/// </returns>
/// <remarks>
/// <para>
/// When the application no longer needs an enhanced-metafile handle, it should delete the handle by calling the DeleteEnhMetaFile function.
/// </para>
/// <para>
/// A Windows-format metafile must be converted to the enhanced format before it can be processed by the <c>GetEnhMetaFile</c>
/// function. To convert the file, use the SetWinMetaFileBits function.
/// </para>
/// <para>
/// Where text arguments must use Unicode characters, use this function as a wide-character function. Where text arguments must use
/// characters from the Windows character set, use this function as an ANSI function.
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Opening an Enhanced Metafile and Displaying Its Contents.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/nf-wingdi-getenhmetafilea HENHMETAFILE GetEnhMetaFileA( LPCSTR lpName );
[DllImport(Lib.Gdi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("wingdi.h", MSDNShortId = "bcb9611e-8e4e-4f87-8a1e-dedbe0042821")]
public static extern SafeHENHMETAFILE GetEnhMetaFile(string lpName);
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="HENHMETAFILE"/> that is disposed using <see cref="DeleteEnhMetaFile"/>.</summary>
public class SafeHENHMETAFILE : HANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafeHENHMETAFILE"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeHENHMETAFILE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeHENHMETAFILE"/> class.</summary>
private SafeHENHMETAFILE() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeHENHMETAFILE"/> to <see cref="HENHMETAFILE"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HENHMETAFILE(SafeHENHMETAFILE h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => DeleteEnhMetaFile(this);
}
/*
CloseMetaFile
CopyMetaFile
CreateMetaFile
DeleteMetaFile
EnumMetaFile
GetMetaFile
GetMetaFileBitsEx
PlayMetaFile
PlayMetaFileRecord
SetMetaFileBitsEx
CloseEnhMetaFile
CopyEnhMetaFile
ENHMFENUMPROC
EnumEnhMetaFile
MFENUMPROC
GdiComment
GetEnhMetaFileBits
GetEnhMetaFileDescription
GetEnhMetaFileHeader
GetEnhMetaFilePaletteEntries
GetWinMetaFileBits
PlayEnhMetaFile
PlayEnhMetaFileRecord
SetEnhMetaFileBits
SetWinMetaFileBits
*/
}
}

View File

@ -3797,7 +3797,7 @@ namespace Vanara.PInvoke
/// this parameter.
/// </param>
/// <returns>The physical address that corresponds to the IPv4 address specified by the DestIP parameter.</returns>
public static byte[] SendARP(IN_ADDR DestIP, IN_ADDR SrcIP = default(IN_ADDR))
public static byte[] SendARP(IN_ADDR DestIP, IN_ADDR SrcIP = default)
{
uint len = 6;
var ret = new byte[(int)len];

View File

@ -5286,7 +5286,7 @@ namespace Vanara.PInvoke
// ResolveIpNetEntry2( PMIB_IPNET_ROW2 Row, CONST SOCKADDR_INET *SourceAddress );
[DllImport(Lib.IpHlpApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("netioapi.h", MSDNShortId = "37f9dc58-362d-413e-a593-4dda52fb7d8b")]
public static extern Win32Error ResolveIpNetEntry2(ref MIB_IPNET_ROW2 Row, IntPtr SourceAddress = default(IntPtr));
public static extern Win32Error ResolveIpNetEntry2(ref MIB_IPNET_ROW2 Row, IntPtr SourceAddress = default);
/// <summary>
/// <para>The <c>ResolveIpNetEntry2</c> function resolves the physical address for a neighbor IP address entry on the local computer.</para>

View File

@ -1,4 +1,5 @@
using System;
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
@ -46,7 +47,7 @@ namespace Vanara.PInvoke
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[PInvokeData("Winbase.h", MSDNShortId = "ms724211")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(HANDLE hObject);
public static extern bool CloseHandle(IntPtr hObject);
/// <summary>Compares two object handles to determine if they refer to the same underlying kernel object.</summary>
/// <param name="hFirstObjectHandle">The first object handle to compare.</param>
@ -58,6 +59,51 @@ namespace Vanara.PInvoke
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CompareObjectHandles(IntPtr hFirstObjectHandle, IntPtr hSecondObjectHandle);
/// <summary>Duplicates an object handle.</summary>
/// <param name="hSourceHandle">
/// The handle to be duplicated. This is an open object handle that is valid in the context of the source process. For a list of objects whose handles
/// can be duplicated, see the following Remarks section.
/// </param>
/// <param name="bInheritHandle">
/// A variable that indicates whether the handle is inheritable. If <c>TRUE</c>, the duplicate handle can be inherited by new processes created by the
/// target process. If <c>FALSE</c>, the new handle cannot be inherited.
/// </param>
/// <param name="dwOptions">
/// <para>Optional actions. This parameter can be zero, or any combination of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>DUPLICATE_CLOSE_SOURCE0x00000001</term>
/// <term>Closes the source handle. This occurs regardless of any error status returned.</term>
/// </item>
/// <item>
/// <term>DUPLICATE_SAME_ACCESS0x00000002</term>
/// <term>Ignores the dwDesiredAccess parameter. The duplicate handle has the same access as the source handle.</term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="dwDesiredAccess">
/// <para>The access requested for the new handle. For the flags that can be specified for each object type, see the following Remarks section.</para>
/// <para>
/// This parameter is ignored if the dwOptions parameter specifies the DUPLICATE_SAME_ACCESS flag. Otherwise, the flags that can be specified depend on
/// the type of object whose handle is to be duplicated.
/// </para>
/// </param>
/// <returns>
/// <para>The duplicate handle. This handle value is valid in the context of the target process.</para>
/// <para>
/// If hSourceHandle is a pseudo handle returned by <c>GetCurrentProcess</c> or <c>GetCurrentThread</c>, <c>DuplicateHandle</c> converts it to a real
/// handle to a process or thread, respectively.
/// </para>
/// </returns>
public static IntPtr Duplicate(this IKernelHandle sourceHandle, bool bInheritHandle = true, DUPLICATE_HANDLE_OPTIONS dwOptions = DUPLICATE_HANDLE_OPTIONS.DUPLICATE_SAME_ACCESS, uint dwDesiredAccess = 0) =>
DuplicateHandle(GetCurrentProcess(), sourceHandle.DangerousGetHandle(), GetCurrentProcess(), out var h, dwDesiredAccess, bInheritHandle, dwOptions) ? h : IntPtr.Zero;
/// <summary>Duplicates an object handle.</summary>
/// <param name="hSourceProcessHandle">
/// <para>A handle to the process with the handle to be duplicated.</para>
@ -121,9 +167,8 @@ namespace Vanara.PInvoke
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("Winbase.h", MSDNShortId = "ms724251")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DuplicateHandle(
[In] HPROCESS hSourceProcessHandle, [In] IntPtr hSourceHandle, [In] HPROCESS hTargetProcessHandle, out HANDLE lpTargetHandle, uint dwDesiredAccess,
[MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, DUPLICATE_HANDLE_OPTIONS dwOptions);
public static extern bool DuplicateHandle([In] HPROCESS hSourceProcessHandle, [In] IntPtr hSourceHandle, [In] HPROCESS hTargetProcessHandle,
out IntPtr lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, DUPLICATE_HANDLE_OPTIONS dwOptions);
/// <summary>Retrieves certain properties of an object handle.</summary>
/// <param name="hObject">
@ -212,7 +257,7 @@ namespace Vanara.PInvoke
protected SafeKernelHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => CloseHandle(this);
protected override bool InternalReleaseHandle() => CloseHandle(handle);
}
/// <summary>Provides a <see cref="SafeHandle"/> to a synchronization object that is automatically disposed using CloseHandle.</summary>
@ -228,6 +273,11 @@ namespace Vanara.PInvoke
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
protected SafeSyncHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Performs an implicit conversion from <see cref="SafeSyncHandle"/> to <see cref="SafeWaitHandle"/>.</summary>
/// <param name="h">The SafeSyncHandle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator SafeWaitHandle(SafeSyncHandle h) => new SafeWaitHandle(h.handle, false);
}
}
}

View File

@ -1070,6 +1070,10 @@ namespace Vanara.PInvoke
internal HHEAP HeapHandle { get; set; } = GetProcessHeap();
private int GetSize(IntPtr ptr) => (int)HeapSize(HeapHandle, 0, ptr).Value;
/// <summary>Gets a static instance of this class.</summary>
/// <value>The instance.</value>
public static IMemoryMethods Instance { get; } = new HeapMemoryMethods();
}
/// <summary>Provides a handle to a heap.</summary>

View File

@ -39,6 +39,8 @@ namespace Vanara.InteropServices
/// <summary>Gets the reallocation method.</summary>
public Func<IntPtr, int, IntPtr> ReAllocMem => (p, i) => { var o = LocalReAlloc(p, i, LMEM.LMEM_MOVEABLE); return !o.IsNull ? (IntPtr)o : throw Win32Error.GetLastError().GetException(); };
public static IMemoryMethods Instance { get; } = new LocalMemoryMethods();
}
/// <summary>A <see cref="SafeHandle"/> for memory allocated via LocalAlloc.</summary>
@ -111,7 +113,7 @@ namespace Vanara.InteropServices
/// <typeparam name="T">Native type</typeparam>
/// <param name="value">The value.</param>
/// <returns><see cref="SafeLocalHandle"/> object to an native (unmanaged) memory block the size of T.</returns>
public static SafeLocalHandle CreateFromStructure<T>(T value = default(T)) => new SafeLocalHandle(InteropExtensions.StructureToPtr(value, new LocalMemoryMethods().AllocMem, out var s), s);
public static SafeLocalHandle CreateFromStructure<T>(T value = default) => new SafeLocalHandle(InteropExtensions.StructureToPtr(value, new LocalMemoryMethods().AllocMem, out var s), s);
/// <summary>Converts an <see cref="IntPtr"/> to a <see cref="SafeLocalHandle"/> where it owns the reference.</summary>
/// <param name="ptr">The <see cref="IntPtr"/>.</param>

View File

@ -887,10 +887,11 @@ namespace Vanara.PInvoke
private static unsafe IAsyncResult BeginDeviceIoControl<TIn, TOut>(HFILE hDevice, uint dwIoControlCode, byte[] buffer, AsyncCallback userCallback, object userState) where TIn : struct where TOut : struct
{
var ar = OverlappedAsync.SetupOverlappedFunction(hDevice, userCallback, buffer);
var prefix = Marshal.SizeOf(typeof(int)) * 2;
var inSz = Marshal.SizeOf(typeof(TIn));
fixed (byte* pIn = buffer, pOut = &buffer[inSz])
fixed (byte* pIn = &buffer[prefix], pOut = &buffer[prefix + inSz])
{
var ret = DeviceIoControl(hDevice, dwIoControlCode, pIn, (uint)inSz, pOut, (uint)(buffer.Length - inSz), out var bRet, ar.Overlapped);
var ret = DeviceIoControl(hDevice, dwIoControlCode, pIn, (uint)inSz, pOut, (uint)Marshal.SizeOf(typeof(TOut)), out var bRet, ar.Overlapped);
return OverlappedAsync.EvaluateOverlappedFunction(ar, ret);
}
}

View File

@ -60,7 +60,7 @@ namespace Vanara.PInvoke
[PInvokeData("Winbase.h", MSDNShortId = "ms648033")]
[UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public delegate bool EnumResLangProc([In] HINSTANCE hModule, [In] SafeResourceId lpszType, [In] SafeResourceId lpszName, ushort wIDLanguage, [In] IntPtr lParam);
public delegate bool EnumResLangProc([In] HINSTANCE hModule, [In] ResourceId lpszType, [In] ResourceId lpszName, ushort wIDLanguage, [In] IntPtr lParam);
/// <summary>
/// An application-defined callback function used with the <c>EnumResourceNames</c> and <c>EnumResourceNamesEx</c> functions. It
@ -105,7 +105,7 @@ namespace Vanara.PInvoke
[SuppressUnmanagedCodeSecurity]
[PInvokeData("Winbase.h", MSDNShortId = "ms648034")]
[return: MarshalAs(UnmanagedType.Bool)]
public delegate bool EnumResNameProc(HINSTANCE hModule, SafeResourceId lpszType, SafeResourceId lpszName, IntPtr lParam);
public delegate bool EnumResNameProc(HINSTANCE hModule, ResourceId lpszType, ResourceId lpszName, IntPtr lParam);
/// <summary>
/// An application-defined callback function used with the <c>EnumResourceTypes</c> and <c>EnumResourceTypesEx</c> functions. It
@ -142,7 +142,7 @@ namespace Vanara.PInvoke
[UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
[PInvokeData("Winbase.h", MSDNShortId = "ms648041")]
[return: MarshalAs(UnmanagedType.Bool)]
public delegate bool EnumResTypeProc(HINSTANCE hModule, SafeResourceId lpszType, IntPtr lParam);
public delegate bool EnumResTypeProc(HINSTANCE hModule, ResourceId lpszType, IntPtr lParam);
/// <summary>Flags used by <see cref="GetModuleHandleEx"/>.</summary>
[PInvokeData("Winbase.h", MSDNShortId = "ms683200")]
@ -670,9 +670,9 @@ namespace Vanara.PInvoke
/// ///
/// <returns>A list of strings for each of the resources matching <paramref name="type"/>.</returns>
[PInvokeData("WinBase.h", MSDNShortId = "ms648037")]
public static IList<SafeResourceId> EnumResourceNamesEx(HINSTANCE hModule, SafeResourceId type, RESOURCE_ENUM_FLAGS flags = 0, ushort langFilter = 0)
public static IList<ResourceId> EnumResourceNamesEx(HINSTANCE hModule, SafeResourceId type, RESOURCE_ENUM_FLAGS flags = 0, ushort langFilter = 0)
{
var list = new List<SafeResourceId>();
var list = new List<ResourceId>();
if (!EnumResourceNamesEx(hModule, type, (m, t, name, l) => { list.Add(name); return true; }, IntPtr.Zero, flags, langFilter))
Win32Error.ThrowLastError();
return list;
@ -957,9 +957,9 @@ namespace Vanara.PInvoke
/// </para>
/// </param>
/// <returns>List of resource identifiers.</returns>
public static IList<SafeResourceId> EnumResourceTypesEx([In] HINSTANCE hModule, RESOURCE_ENUM_FLAGS flags = 0, ushort langFilter = 0)
public static IList<ResourceId> EnumResourceTypesEx([In] HINSTANCE hModule, RESOURCE_ENUM_FLAGS flags = 0, ushort langFilter = 0)
{
var list = new List<SafeResourceId>();
var list = new List<ResourceId>();
if (!EnumResourceTypesEx(hModule, (p, t, l) => { list.Add(t); return true; }, IntPtr.Zero, flags, langFilter))
Win32Error.ThrowLastError();
return list;

View File

@ -6722,6 +6722,10 @@ namespace Vanara.PInvoke
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HPROCESS(SafeHPROCESS h) => h.handle;
/// <summary>Gets a handle to the current process that can be used across processes.</summary>
/// <value>The current process handle.</value>
public static SafeHPROCESS Current => new SafeHPROCESS(GetCurrentProcess().Duplicate());
}
/// <summary>Provides a <see cref="SafeHandle"/> to a thread that releases a created HTHREAD instance at disposal using CloseHandle.</summary>
@ -6740,6 +6744,10 @@ namespace Vanara.PInvoke
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HTHREAD(SafeHTHREAD h) => h.handle;
/// <summary>Gets a handle to the current thread that can be used across processes.</summary>
/// <value>The current thread handle.</value>
public static SafeHTHREAD Current => new SafeHTHREAD(GetCurrentThread().Duplicate());
}
}
}

View File

@ -1,4 +1,5 @@
using System;
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using Vanara.InteropServices;
@ -2210,6 +2211,11 @@ namespace Vanara.PInvoke
public SafeEventHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
private SafeEventHandle() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeSyncHandle"/> to <see cref="SafeWaitHandle"/>.</summary>
/// <param name="h">The SafeSyncHandle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator SafeEventHandle(SafeWaitHandle h) => new SafeEventHandle(h.DangerousGetHandle(), false);
}
/// <summary>Provides a <see cref="SafeHandle"/> to a mutex that is automatically disposed using CloseHandle.</summary>
@ -2223,6 +2229,11 @@ namespace Vanara.PInvoke
public SafeMutexHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
private SafeMutexHandle() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeSyncHandle"/> to <see cref="SafeWaitHandle"/>.</summary>
/// <param name="h">The SafeSyncHandle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator SafeMutexHandle(SafeWaitHandle h) => new SafeMutexHandle(h.DangerousGetHandle(), false);
}
/// <summary>
@ -2275,6 +2286,11 @@ namespace Vanara.PInvoke
public SafeSemaphoreHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
private SafeSemaphoreHandle() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeSyncHandle"/> to <see cref="SafeWaitHandle"/>.</summary>
/// <param name="h">The SafeSyncHandle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator SafeSemaphoreHandle(SafeWaitHandle h) => new SafeSemaphoreHandle(h.DangerousGetHandle(), false);
}
/// <summary>Provides a <see cref="SafeHandle"/> to a waitable timer that is automatically disposed using CloseHandle.</summary>
@ -2288,6 +2304,11 @@ namespace Vanara.PInvoke
public SafeWaitableTimerHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
private SafeWaitableTimerHandle() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeSyncHandle"/> to <see cref="SafeWaitHandle"/>.</summary>
/// <param name="h">The SafeSyncHandle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator SafeWaitableTimerHandle(SafeWaitHandle h) => new SafeWaitableTimerHandle(h.DangerousGetHandle(), false);
}
}
}

View File

@ -1251,7 +1251,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("Wincon.h", MSDNShortId = "")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ReadConsole(HFILE hConsoleInput, StringBuilder lpBuffer, uint nNumberOfCharsToRead, out uint lpNumberOfCharsRead, IntPtr pInputControl = default(IntPtr));
public static extern bool ReadConsole(HFILE hConsoleInput, StringBuilder lpBuffer, uint nNumberOfCharsToRead, out uint lpNumberOfCharsRead, IntPtr pInputControl = default);
/// <summary>Reads data from a console input buffer and removes it from the buffer.</summary>
/// <param name="hConsoleInput">
@ -1912,7 +1912,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("Wincon.h", MSDNShortId = "")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WriteConsole(HFILE hConsoleOutput, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] char[] lpBuffer, uint nNumberOfCharsToWrite, out uint lpNumberOfCharsWritten, IntPtr lpReserved = default(IntPtr));
public static extern bool WriteConsole(HFILE hConsoleOutput, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] char[] lpBuffer, uint nNumberOfCharsToWrite, out uint lpNumberOfCharsWritten, IntPtr lpReserved = default);
/// <summary>Writes data directly to the console input buffer.</summary>
/// <param name="hConsoleInput">

View File

@ -2,8 +2,6 @@
using System.Runtime.InteropServices;
using static Vanara.Extensions.BitHelper;
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
public static partial class Kernel32

View File

@ -190,7 +190,7 @@ namespace Vanara.PInvoke
/// </returns>
[DllImport(Lib.NetApi32, ExactSpelling = true), SuppressUnmanagedCodeSecurity]
[PInvokeData("lm.h", MSDNShortId = "aa370304")]
public static extern Win32Error NetApiBufferFree(SafeNetApiBuffer pBuf);
public static extern Win32Error NetApiBufferFree(IntPtr pBuf);
/// <summary>
/// <para>
@ -2349,7 +2349,7 @@ namespace Vanara.PInvoke
public IEnumerable<string> ToStringEnum(int count) => handle.ToStringEnum(count);
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => NetApiBufferFree(this) == 0;
protected override bool InternalReleaseHandle() => NetApiBufferFree(handle) == 0;
}
}
}

View File

@ -73,5 +73,299 @@ namespace Vanara.PInvoke
/// </remarks>
void Write([In, MarshalAs(UnmanagedType.LPWStr)] string pszPropName, in object pVar);
}
/// <summary>
/// Describes the structure of a particular UDT. You can use IRecordInfo any time you need to access the description of UDTs
/// contained in type libraries. IRecordInfo can be reused as needed; there can be many instances of the UDT for a single IRecordInfo pointer.
/// </summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nn-oaidl-irecordinfo
[PInvokeData("OAIdl.h")]
[ComImport, Guid("0000002F-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IRecordInfo
{
/// <summary>
/// <para>Initializes a new instance of a record.</para>
/// </summary>
/// <param name="pvNew">
/// <para>An instance of a record.</para>
/// </param>
/// <remarks>
/// <para>The caller must allocate the memory of the record by its appropriate size using the GetSize method.</para>
/// <para><c>RecordInit</c> sets all contents of the record to 0 and the record should hold no resources.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-recordinit
void RecordInit(IntPtr pvNew);
/// <summary>
/// <para>Releases object references and other values of a record without deallocating the record.</para>
/// </summary>
/// <param name="pvExisting">
/// <para>The record to be cleared.</para>
/// </param>
/// <remarks>
/// <c>RecordClear</c> releases memory blocks held by VT_PTR or VT_SAFEARRAY instance fields. The caller needs to free the
/// instance fields memory, <c>RecordClear</c> will do nothing if there are no resources held.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-recordclear
void RecordClear(IntPtr pvExisting);
/// <summary>
/// <para>Copies an existing record into the passed in buffer.</para>
/// </summary>
/// <param name="pvExisting">
/// <para>The current record instance.</para>
/// </param>
/// <param name="pvNew">
/// <para>The destination where the record will be copied.</para>
/// </param>
/// <remarks>
/// <c>RecordCopy</c> will release the resources in the destination first. The caller is responsible for allocating sufficient
/// memory in the destination by calling GetSize or RecordCreate. If <c>RecordCopy</c> fails to copy any of the fields then all
/// fields will be cleared, as though RecordClear had been called.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-recordcopy
void RecordCopy(IntPtr pvExisting, IntPtr pvNew);
/// <summary>
/// <para>Gets the GUID of the record type.</para>
/// </summary>
/// <returns>
/// <para>The class GUID of the TypeInfo that describes the UDT.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-getguid
Guid GetGuid();
/// <summary>
/// <para>
/// Gets the name of the record type. This is useful if you want to print out the type of the record, because each UDT has it's
/// own IRecordInfo.
/// </para>
/// </summary>
/// <returns>
/// <para>The name.</para>
/// </returns>
/// <remarks>
/// <para>The caller must free the BSTR by calling SysFreeString.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-getname
[return: MarshalAs(UnmanagedType.BStr)]
string GetName();
/// <summary>
/// <para>
/// Gets the number of bytes of memory necessary to hold the record instance. This allows you to allocate memory for a record
/// instance rather than calling RecordCreate.
/// </para>
/// </summary>
/// <returns>
/// <para>The size of a record instance, in bytes.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-getsize
uint GetSize();
/// <summary>Retrieves the type information that describes a UDT or safearray of UDTs.</summary>
/// <param name="ppTypeInfo">The type information.</param>
/// <remarks><c>AddRef</c> is called on the pointer ppTypeInfo.</remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-gettypeinfo
void GetTypeInfo([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "System.Runtime.InteropServices.CustomMarshalers.TypeToTypeInfoMarshaler")] out Type ppTypeInfo);
/// <summary>
/// <para>Returns a pointer to the VARIANT containing the value of a given field name.</para>
/// </summary>
/// <param name="pvData">
/// <para>The instance of a record.</para>
/// </param>
/// <param name="szFieldName">
/// <para>The field name.</para>
/// </param>
/// <returns>
/// The VARIANT that you want to hold the value of the field name, szFieldName. On return, places a copy of the field's value in
/// the variant.
/// </returns>
/// <remarks>
/// <para>
/// The VARIANT that you pass in contains a copy of the field's value upon return. If you modify the VARIANT then the underlying
/// record field does not change.
/// </para>
/// <para>The caller allocates memory of the VARIANT.</para>
/// <para>The method VariantClear is called for pvarField before copying.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-getfield
[return: MarshalAs(UnmanagedType.Struct)]
object GetField(IntPtr pvData, [MarshalAs(UnmanagedType.LPWStr)] string szFieldName);
/// <summary>
/// <para>Returns a pointer to the value of a given field name without copying the value and allocating resources.</para>
/// </summary>
/// <param name="pvData">
/// <para>The instance of a record.</para>
/// </param>
/// <param name="szFieldName">
/// <para>The name of the field.</para>
/// </param>
/// <param name="pvarField">
/// <para>The VARIANT that will contain the UDT upon return.</para>
/// </param>
/// <returns>
/// <para>Receives the value of the field upon return.</para>
/// </returns>
/// <remarks>
/// <para>
/// Upon return, the VARIANT you pass contains a direct pointer to the record's field, ppvDataCArray. If you modify the VARIANT,
/// then the underlying record field will change.
/// </para>
/// <para>
/// The caller allocates memory of the VARIANT, but does not own the memory so cannot free pvarField. This method calls
/// VariantClear for pvarField before filling in the requested field.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-getfieldnocopy
IntPtr GetFieldNoCopy(IntPtr pvData, [MarshalAs(UnmanagedType.LPWStr)] string szFieldName, [MarshalAs(UnmanagedType.Struct)] out object pvarField);
/// <summary>
/// <para>Puts a variant into a field.</para>
/// </summary>
/// <param name="wFlags">
/// <para>The only legal values for the wFlags parameter is INVOKE_PROPERTYPUT or INVOKE_PROPERTYPUTREF.</para>
/// <para>
/// If INVOKE_PROPERTYPUTREF is passed in then <c>PutField</c> just assigns the value of the variant that is passed in to the
/// field using normal coercion rules.
/// </para>
/// <para>
/// If INVOKE_PROPERTYPUT is passed in then specific rules apply. If the field is declared as a class that derives from IDispatch
/// and the field's value is NULL then an error will be returned. If the field's value is not NULL then the variant will be
/// passed to the default property supported by the object referenced by the field. If the field is not declared as a class
/// derived from <c>IDispatch</c> then an error will be returned. If the field is declared as a variant of type VT_Dispatch then
/// the default value of the object is assigned to the field. Otherwise, the variant's value is assigned to the field.
/// </para>
/// </param>
/// <param name="pvData">
/// <para>The pointer to an instance of the record.</para>
/// </param>
/// <param name="szFieldName">
/// <para>The name of the field of the record.</para>
/// </param>
/// <param name="pvarField">
/// <para>The pointer to the variant.</para>
/// </param>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-putfield
void PutField(uint wFlags, IntPtr pvData, [MarshalAs(UnmanagedType.LPWStr)] string szFieldName, [In, MarshalAs(UnmanagedType.Struct)] ref object pvarField);
/// <summary>
/// <para>
/// Passes ownership of the data to the assigned field by placing the actual data into the field. <c>PutFieldNoCopy</c> is useful
/// for saving resources because it allows you to place your data directly into a record field. <c>PutFieldNoCopy</c> differs
/// from PutField because it does not copy the data referenced by the variant.
/// </para>
/// </summary>
/// <param name="wFlags">
/// <para>The only legal values for the wFlags parameter is INVOKE_PROPERTYPUT or INVOKE_PROPERTYPUTREF.</para>
/// </param>
/// <param name="pvData">
/// <para>An instance of the record described by IRecordInfo.</para>
/// </param>
/// <param name="szFieldName">
/// <para>The name of the field of the record.</para>
/// </param>
/// <param name="pvarField">
/// <para>The variant to be put into the field.</para>
/// </param>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-putfieldnocopy
void PutFieldNoCopy(uint wFlags, IntPtr pvData, [MarshalAs(UnmanagedType.LPWStr)] string szFieldName, [In, MarshalAs(UnmanagedType.Struct)] ref object pvarField);
/// <summary>
/// <para>Gets the names of the fields of the record.</para>
/// </summary>
/// <param name="pcNames">
/// <para>The number of names to return.</para>
/// </param>
/// <param name="rgBstrNames">
/// <para>The name of the array of type BSTR.</para>
/// <para>If the rgBstrNames parameter is NULL, then pcNames is returned with the number of field names.</para>
/// <para>
/// It the rgBstrNames parameter is not NULL, then the string names contained in rgBstrNames are returned. If the number of names
/// in pcNames and rgBstrNames are not equal then the lesser number of the two is the number of returned field names. The caller
/// needs to free the BSTRs inside the array returned in rgBstrNames.
/// </para>
/// </param>
/// <remarks>
/// <para>
/// The caller should allocate memory for the array of BSTRs. If the array is larger than needed, set the unused portion to 0.
/// </para>
/// <para>On return, the caller will need to free each contained BSTR using SysFreeString.</para>
/// <para>In case of out of memory, pcNames points to error code.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-getfieldnames
void GetFieldNames(ref uint pcNames, [In, Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.BStr, SizeParamIndex = 0)] string[] rgBstrNames);
/// <summary>
/// <para>Determines whether the record that is passed in matches that of the current record information.</para>
/// </summary>
/// <param name="pRecordInfo">
/// <para>The information of the record.</para>
/// </param>
/// <returns>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>TRUE</term>
/// <term>The record that is passed in matches the current record information.</term>
/// </item>
/// <item>
/// <term>FALSE</term>
/// <term>The record that is passed in does not match the current record information.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-ismatchingtype
[PreserveSig] [return: MarshalAs(UnmanagedType.Bool)] bool IsMatchingType([In] IRecordInfo pRecordInfo);
/// <summary>
/// <para>Allocates memory for a new record, initializes the instance and returns a pointer to the record.</para>
/// </summary>
/// <returns>
/// <para>This method returns a pointer to the created record.</para>
/// </returns>
/// <remarks>
/// <para>The memory is set to zeros before it is returned.</para>
/// <para>The records created must be freed by calling RecordDestroy.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-recordcreate
[PreserveSig] IntPtr RecordCreate();
/// <summary>
/// <para>Creates a copy of an instance of a record to the specified location.</para>
/// </summary>
/// <param name="pvSource">
/// <para>An instance of the record to be copied.</para>
/// </param>
/// <param name="ppvDest">
/// <para>The new record with data copied from pvSource.</para>
/// </param>
/// <remarks>
/// <para>The records created must be freed by calling RecordDestroy.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-recordcreatecopy
void RecordCreateCopy(IntPtr pvSource, out IntPtr ppvDest);
/// <summary>
/// <para>Releases the resources and deallocates the memory of the record.</para>
/// </summary>
/// <param name="pvRecord">
/// <para>An instance of the record to be destroyed.</para>
/// </param>
/// <remarks>
/// <para>RecordClear is called to release the resources held by the instance of a record without deallocating memory.</para>
/// <para>
/// <c>Note</c> This method can only be called on records allocated through RecordCreate and RecordCreateCopy. If you allocate
/// the record yourself, you cannot call this method.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/oaidl/nf-oaidl-irecordinfo-recorddestroy
void RecordDestroy(IntPtr pvRecord);
}
}
}

View File

@ -188,7 +188,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.Ole32, ExactSpelling = true, SetLastError = false)]
[PInvokeData("Objbase.h", MSDNShortId = "aa380328")]
public static extern HRESULT StgCreateStorageEx([MarshalAs(UnmanagedType.LPWStr)] string pwcsName, STGM grfMode,
STGFMT stgfmt, FileFlagsAndAttributes grfAttrs, [In] IntPtr pStgOptions, IntPtr pSecurityDescriptor, in Guid riid,
STGFMT stgfmt, FileFlagsAndAttributes grfAttrs, [In] IntPtr pStgOptions, PSECURITY_DESCRIPTOR pSecurityDescriptor, in Guid riid,
[MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 6)] out object ppObjectOpen);
/// <summary>The StgCreateStorageEx function creates a new storage object using a provided implementation for the IStorage or IPropertySetStorage interfaces. To open an existing file, use the StgOpenStorageEx function instead.
@ -212,7 +212,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.Ole32, ExactSpelling = true, SetLastError = false)]
[PInvokeData("Objbase.h", MSDNShortId = "aa380328")]
public static extern HRESULT StgCreateStorageEx([MarshalAs(UnmanagedType.LPWStr)] string pwcsName, STGM grfMode,
STGFMT stgfmt, FileFlagsAndAttributes grfAttrs, in STGOPTIONS pStgOptions, IntPtr pSecurityDescriptor, in Guid riid,
STGFMT stgfmt, FileFlagsAndAttributes grfAttrs, in STGOPTIONS pStgOptions, PSECURITY_DESCRIPTOR pSecurityDescriptor, in Guid riid,
[MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 6)] out object ppObjectOpen);
/// <summary>The StgIsStorageFile function indicates whether a particular disk file contains a storage object.</summary>

View File

@ -236,8 +236,8 @@ namespace Vanara.PInvoke
[return: MarshalAs(UnmanagedType.Interface)]
IStream CreateStream([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName,
[In] STGM grfMode,
[In] uint reserved1,
[In] uint reserved2);
[In, Optional] uint reserved1,
[In, Optional] uint reserved2);
/// <summary>The OpenStream method opens an existing stream object within this storage object in the specified access mode.</summary>
/// <param name="pwcsName">
@ -254,9 +254,9 @@ namespace Vanara.PInvoke
/// <returns>A IStream interface pointer to the newly opened stream object.</returns>
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
IStream OpenStream([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, [In] IntPtr reserved1,
IStream OpenStream([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, [In, Optional] IntPtr reserved1,
[In] STGM grfMode,
[In] uint reserved2);
[In, Optional] uint reserved2);
/// <summary>
/// The CreateStorage method creates and opens a new storage object nested within this storage object with the specified name in
@ -279,8 +279,8 @@ namespace Vanara.PInvoke
[return: MarshalAs(UnmanagedType.Interface)]
IStorage CreateStorage([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName,
[In] STGM grfMode,
[In] uint reserved1,
[In] uint reserved2);
[In, Optional] uint reserved1,
[In, Optional] uint reserved2);
/// <summary>The OpenStorage method opens an existing storage object with the specified name in the specified access mode.</summary>
/// <param name="pwcsName">
@ -302,7 +302,7 @@ namespace Vanara.PInvoke
[In, MarshalAs(UnmanagedType.Interface)] IStorage pstgPriority,
[In] STGM grfMode,
[In] SNB snbExclude,
[In] uint reserved);
[In, Optional] uint reserved);
/// <summary>The CopyTo method copies the entire contents of an open storage object to another storage object.</summary>
/// <param name="ciidExclude">
@ -374,7 +374,7 @@ namespace Vanara.PInvoke
/// <returns>The interface pointer to the new enumerator object.</returns>
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
IEnumSTATSTG EnumElements([In] uint reserved1, [In] IntPtr reserved2, [In] uint reserved3);
IEnumSTATSTG EnumElements([In] uint reserved1, [In, Optional] IntPtr reserved2, [In, Optional] uint reserved3);
/// <summary>The DestroyElement method removes the specified storage or stream from this storage object.</summary>
/// <param name="pwcsName">A string that contains the name of the storage or stream to be removed.</param>

View File

@ -33,6 +33,6 @@ namespace Vanara.PInvoke
/// </returns>
[DllImport(Lib.Ole32, ExactSpelling = true, SetLastError = false)]
[PInvokeData("Ole2.h", MSDNShortId = "ms690134")]
public static extern HRESULT OleInitialize(IntPtr pvReserved);
public static extern HRESULT OleInitialize([Optional] IntPtr pvReserved);
}
}

View File

@ -1,43 +1,243 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace Vanara.PInvoke
{
public static partial class Ole32
{
/// <summary>
/// The IOleWindow interface provides methods that allow an application to obtain the handle to the various windows that participate in in-place
/// activation, and also to enter and exit context-sensitive help mode.
/// <para>
/// Represents information about the effects of a drag-and-drop operation. The <c>DoDragDrop</c> function and many of the methods in
/// the <c>IDropSource</c> and <c>IDropTarget</c> use the values of this enumeration.
/// </para>
/// </summary>
/// <remarks>
/// <para>
/// Your application should always mask values from the <c>DROPEFFECT</c> enumeration to ensure compatibility with future
/// implementations. Presently, only some of the positions in a <c>DROPEFFECT</c> value have meaning. In the future, more
/// interpretations for the bits will be added. Drag sources and drop targets should carefully mask these values appropriately before
/// comparing. They should never compare a <c>DROPEFFECT</c> against, say, DROPEFFECT_COPY by doing the following:
/// </para>
/// <para>Instead, the application should always mask for the value or values being sought as using one of the following techniques:</para>
/// <para>This allows for the definition of new drop effects, while preserving backward compatibility with existing code.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/com/dropeffect-constants
[PInvokeData("OleIdl.h", MSDNShortId = "d8e46899-3fbf-4012-8dd3-67fa627526d5")]
// public static extern
public enum DROPEFFECT : uint
{
/// <summary>Drop target cannot accept the data.</summary>
DROPEFFECT_NONE = 0,
/// <summary>Drop results in a copy. The original data is untouched by the drag source.</summary>
DROPEFFECT_COPY = 1,
/// <summary>Drag source should remove the data.</summary>
DROPEFFECT_MOVE = 2,
/// <summary>Drag source should create a link to the original data.</summary>
DROPEFFECT_LINK = 4,
/// <summary>
/// Scrolling is about to start or is currently occurring in the target. This value is used in addition to the other values.
/// </summary>
DROPEFFECT_SCROLL = 0x80000000,
}
/// <summary>
/// <para>
/// The <c>IDropSource</c> interface is one of the interfaces you implement to provide drag-and-drop operations in your application.
/// It contains methods used in any application used as a data source in a drag-and-drop operation. The data source application in a
/// drag-and-drop operation is responsible for:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Determining the data being dragged based on the user's selection.</term>
/// </item>
/// <item>
/// <term>Initiating the drag-and-drop operation based on the user's mouse actions.</term>
/// </item>
/// <item>
/// <term>
/// Generating some of the visual feedback during the drag-and-drop operation, such as setting the cursor and highlighting the data
/// selected for the drag-and-drop operation.
/// </term>
/// </item>
/// <item>
/// <term>Canceling or completing the drag-and-drop operation based on the user's mouse actions.</term>
/// </item>
/// <item>
/// <term>Performing any action on the original data caused by the drop operation, such as deleting the data on a drag move.</term>
/// </item>
/// </list>
/// <para>
/// <c>IDropSource</c> contains the methods for generating visual feedback to the end user and for canceling or completing the
/// drag-and-drop operation. You also need to call the DoDragDrop, RegisterDragDrop, and RevokeDragDrop functions in drag-and-drop operations.
/// </para>
/// </summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/oleidl/nn-oleidl-idropsource
[PInvokeData("oleidl.h", MSDNShortId = "963a36bc-4ad7-4591-bffc-a96b4310177d")]
[ComImport, Guid("00000121-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDropSource
{
/// <summary>
/// <para>
/// Determines whether a drag-and-drop operation should be continued, canceled, or completed. You do not call this method
/// directly. The OLE DoDragDrop function calls this method during a drag-and-drop operation.
/// </para>
/// </summary>
/// <param name="fEscapePressed">
/// <para>
/// Indicates whether the Esc key has been pressed since the previous call to <c>QueryContinueDrag</c> or to DoDragDrop if this
/// is the first call to <c>QueryContinueDrag</c>. A <c>TRUE</c> value indicates the end user has pressed the escape key; a
/// <c>FALSE</c> value indicates it has not been pressed.
/// </para>
/// </param>
/// <param name="grfKeyState">
/// <para>
/// The current state of the keyboard modifier keys on the keyboard. Possible values can be a combination of any of the flags
/// MK_CONTROL, MK_SHIFT, MK_ALT, MK_BUTTON, MK_LBUTTON, MK_MBUTTON, and MK_RBUTTON.
/// </para>
/// </param>
/// <returns>
/// <para>This method can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>
/// The drag operation should continue. This result occurs if no errors are detected, the mouse button starting the drag-and-drop
/// operation has not been released, and the Esc key has not been detected.
/// </term>
/// </item>
/// <item>
/// <term>DRAGDROP_S_DROP</term>
/// <term>
/// The drop operation should occur completing the drag operation. This result occurs if grfKeyState indicates that the key that
/// started the drag-and-drop operation has been released.
/// </term>
/// </item>
/// <item>
/// <term>DRAGDROP_S_CANCEL</term>
/// <term>
/// The drag operation should be canceled with no drop operation occurring. This result occurs if fEscapePressed is TRUE,
/// indicating the Esc key has been pressed.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The DoDragDrop function calls <c>QueryContinueDrag</c> whenever it detects a change in the keyboard or mouse button state
/// during a drag-and-drop operation. <c>QueryContinueDrag</c> must determine whether the drag-and-drop operation should be
/// continued, canceled, or completed based on the contents of the parameters grfKeyState and fEscapePressed.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/oleidl/nf-oleidl-idropsource-querycontinuedrag HRESULT QueryContinueDrag(
// BOOL fEscapePressed, DWORD grfKeyState );
[PInvokeData("oleidl.h", MSDNShortId = "96ea44fc-5046-4e31-abfc-659d8ef3ca8f")]
[PreserveSig]
HRESULT QueryContinueDrag([MarshalAs(UnmanagedType.Bool)] bool fEscapePressed, uint grfKeyState);
/// <summary>
/// <para>
/// Enables a source application to give visual feedback to the end user during a drag-and-drop operation by providing the
/// DoDragDrop function with an enumeration value specifying the visual effect.
/// </para>
/// </summary>
/// <param name="dwEffect">
/// <para>The DROPEFFECT value returned by the most recent call to IDropTarget::DragEnter, IDropTarget::DragOver, or IDropTarget::DragLeave.</para>
/// </param>
/// <returns>
/// <para>This method returns S_OK on success. Other possible values include the following.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>DRAGDROP_S_USEDEFAULTCURSORS</term>
/// <term>
/// Indicates successful completion of the method, and requests OLE to update the cursor using the OLE-provided default cursors.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// When your application detects that the user has started a drag-and-drop operation, it should call the DoDragDrop function.
/// <c>DoDragDrop</c> enters a loop, calling IDropTarget::DragEnter when the mouse first enters a drop target window,
/// IDropTarget::DragOver when the mouse changes its position within the target window, and IDropTarget::DragLeave when the mouse
/// leaves the target window.
/// </para>
/// <para>
/// For every call to either IDropTarget::DragEnter or IDropTarget::DragOver, DoDragDrop calls <c>IDropSource::GiveFeedback</c>,
/// passing it the DROPEFFECT value returned from the drop target call.
/// </para>
/// <para>
/// DoDragDrop calls IDropTarget::DragLeave when the mouse has left the target window. Then, <c>DoDragDrop</c> calls
/// <c>IDropSource::GiveFeedback</c> and passes the DROPEFFECT_NONE value in the dwEffect parameter.
/// </para>
/// <para>
/// The dwEffect parameter can include DROPEFFECT_SCROLL, indicating that the source should put up the drag-scrolling variation
/// of the appropriate pointer.
/// </para>
/// <para>Notes to Implementers</para>
/// <para>
/// This function is called frequently during the DoDragDrop loop, so you can gain performance advantages if you optimize your
/// implementation as much as possible.
/// </para>
/// <para>
/// <c>IDropSource::GiveFeedback</c> is responsible for changing the cursor shape or for changing the highlighted source based on
/// the value of the dwEffect parameter. If you are using default cursors, you can return DRAGDROP_S_USEDEFAULTCURSORS, which
/// causes OLE to update the cursor for you, using its defaults.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/oleidl/nf-oleidl-idropsource-givefeedback HRESULT GiveFeedback( DWORD
// dwEffect );
[PInvokeData("oleidl.h", MSDNShortId = "dde37299-ad7c-4f59-af99-e75b72ad9188")]
[PreserveSig]
HRESULT GiveFeedback(DROPEFFECT dwEffect);
}
/// <summary>
/// The IOleWindow interface provides methods that allow an application to obtain the handle to the various windows that participate
/// in in-place activation, and also to enter and exit context-sensitive help mode.
/// </summary>
[PInvokeData("Oleidl.h")]
[ComImport, Guid("00000114-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleWindow
{
/// <summary>Retrieves a handle to one of the windows participating in in-place activation (frame, document, parent, or in-place object window).</summary>
/// <returns>A pointer to a variable that receives the window handle.</returns>
IntPtr GetWindow();
/// <summary>
/// Determines whether context-sensitive help mode should be entered during an in-place activation session.
/// Retrieves a handle to one of the windows participating in in-place activation (frame, document, parent, or in-place object window).
/// </summary>
/// <returns>A pointer to a variable that receives the window handle.</returns>
HWND GetWindow();
/// <summary>Determines whether context-sensitive help mode should be entered during an in-place activation session.</summary>
/// <param name="fEnterMode"><c>true</c> if help mode should be entered; <c>false</c> if it should be exited.</param>
void ContextSensitiveHelp([MarshalAs(UnmanagedType.Bool)] bool fEnterMode);
}
/// <summary>
/// Indicates the number of menu items in each of the six menu groups of a menu shared between a container and an object server during an in-place
/// editing session. This is the mechanism for building a shared menu.
/// Indicates the number of menu items in each of the six menu groups of a menu shared between a container and an object server
/// during an in-place editing session. This is the mechanism for building a shared menu.
/// </summary>
[PInvokeData("Oleidl.h", MSDNShortId = "ms693766")]
[StructLayout(LayoutKind.Sequential)]
public struct OLEMENUGROUPWIDTHS
{
/// <summary>
/// An array whose elements contain the number of menu items in each of the six menu groups of a shared in-place editing menu. Each menu group can
/// have any number of menu items. The container uses elements 0, 2, and 4 to indicate the number of menu items in its File, View, and Window menu
/// groups. The object server uses elements 1, 3, and 5 to indicate the number of menu items in its Edit, Object, and Help menu groups.
/// An array whose elements contain the number of menu items in each of the six menu groups of a shared in-place editing menu.
/// Each menu group can have any number of menu items. The container uses elements 0, 2, and 4 to indicate the number of menu
/// items in its File, View, and Window menu groups. The object server uses elements 1, 3, and 5 to indicate the number of menu
/// items in its Edit, Object, and Help menu groups.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public uint[] width;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public uint[] width;
}
}
}

View File

@ -12,8 +12,6 @@ using static Vanara.PInvoke.OleAut32;
using static Vanara.PInvoke.PropSys;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
// ReSharper disable InconsistentNaming ReSharper disable FieldCanBeMadeReadOnly.Global ReSharper disable BitwiseOperatorOnEnumWithoutFlags
namespace Vanara.PInvoke
{
/// <summary></summary>
@ -221,7 +219,7 @@ namespace Vanara.PInvoke
public IEnumerable<int> cal => GetVector<int>();
/// <summary>Gets the ANSI string array value.</summary>
public IEnumerable<string> calpstr => GetStringVector();
public IEnumerable<string> calpstr => throw new NotSupportedException(); //GetStringVector();
/// <summary>Gets the Unicode string array value.</summary>
public IEnumerable<string> calpwstr => GetStringVector();
@ -904,8 +902,9 @@ namespace Vanara.PInvoke
break;
case VARTYPE.VT_CF:
SetStruct((CLIPDATA?)value, VarType);
break;
//SetStruct((CLIPDATA?)value, VarType);
//break;
throw new NotSupportedException();
case VARTYPE.VT_BLOB:
case VARTYPE.VT_BLOB_OBJECT:
@ -1047,8 +1046,7 @@ namespace Vanara.PInvoke
case VARTYPE.VT_VECTOR | VARTYPE.VT_BSTR:
{
var ep = value as IEnumerable<IntPtr>;
if (ep != null)
if (value is IEnumerable<IntPtr> ep)
SetVector(ep, VarType);
else
SetStringVector(ConvertToEnum<string>(value), VarType);
@ -1056,6 +1054,8 @@ namespace Vanara.PInvoke
break;
case VARTYPE.VT_VECTOR | VARTYPE.VT_LPSTR:
throw new NotSupportedException();
case VARTYPE.VT_VECTOR | VARTYPE.VT_LPWSTR:
SetStringVector(ConvertToEnum<string>(value), VarType);
break;
@ -1167,13 +1167,14 @@ namespace Vanara.PInvoke
private IEnumerable<object> GetSafeArray()
{
if (_ptr == IntPtr.Zero) return null;
var dims = SafeArrayGetDim(_ptr);
var sa = new SafeSAFEARRAY(_ptr, false);
var dims = SafeArrayGetDim(sa);
if (dims != 1) throw new NotSupportedException("Only single-dimensional arrays are supported");
SafeArrayGetLBound(_ptr, 1U, out int lBound);
SafeArrayGetUBound(_ptr, 1U, out int uBound);
var elemSz = SafeArrayGetElemsize(_ptr);
SafeArrayGetLBound(sa, 1U, out int lBound);
SafeArrayGetUBound(sa, 1U, out int uBound);
var elemSz = SafeArrayGetElemsize(sa);
if (elemSz == 0) throw new Win32Exception();
using (var d = new SafeArrayScopedAccessData(_ptr))
using (var d = new SafeArrayScopedAccessData(sa))
return Marshal.GetObjectsForNativeVariants(d.Data, uBound - lBound + 1);
}
@ -1195,7 +1196,10 @@ namespace Vanara.PInvoke
private IEnumerable<string> GetStringVector()
{
var ve = (VarEnum)((int)vt & 0x0FFF);
return _blob.pBlobData.ToIEnum<IntPtr>((int)_blob.cbSize).Select(p => GetString(ve, p));
if (ve == VarEnum.VT_LPSTR)
return _blob.pBlobData.ToIEnum<IntPtr>((int)_blob.cbSize).Select(p => GetString(ve, p));
PropVariantToStringVectorAlloc(this, out var mem, out var cnt).ThrowIfFailed();
return mem.ToStringEnum((int)cnt, CharSet.Unicode);
}
private IEnumerable<T> GetVector<T>()
@ -1217,7 +1221,7 @@ namespace Vanara.PInvoke
vt = VARTYPE.VT_ARRAY | VARTYPE.VT_VARIANT;
if (array == null || array.Count == 0) return;
var psa = SafeArrayCreateVector(VARTYPE.VT_VARIANT, 0, (uint)array.Count);
if (psa == IntPtr.Zero) throw new Win32Exception();
if (psa.IsNull) throw new Win32Exception();
using (var p = new SafeArrayScopedAccessData(psa))
{
var elemSz = SafeArrayGetElemsize(psa);
@ -1225,7 +1229,8 @@ namespace Vanara.PInvoke
for (var i = 0; i < array.Count; ++i)
Marshal.GetNativeVariantForObject(array[i], p.Data.Offset(i * elemSz));
}
_ptr = psa;
_ptr = psa.DangerousGetHandle();
psa.SetHandleAsInvalid();
}
private void SetString(string value, VarEnum ve)
@ -1246,35 +1251,25 @@ namespace Vanara.PInvoke
Clear();
var sc = value.ToArray();
/*using (var tmp = new PROPVARIANT())
{
InitPropVariantFromStringVector(sc, (uint) sc.Length, tmp).ThrowIfFailed();
PropVariantCopy(this, tmp);
}*/
vt = svt | VARTYPE.VT_VECTOR;
if (sc.Length <= 0) return;
var destPtr = IntPtr.Zero;
var index = 0;
try
switch (svt)
{
// TODO: Fix this so that it uses the system call in hopes that PropVarClear will actually release the memory.
destPtr = Marshal.AllocCoTaskMem(IntPtr.Size * sc.Length);
for (index = 0; index < sc.Length; index++)
Marshal.WriteIntPtr(destPtr, index * IntPtr.Size, GetStringPtr(sc[index], (VarEnum)svt));
_blob.cbSize = (uint)sc.Length;
_blob.pBlobData = destPtr;
destPtr = IntPtr.Zero;
}
finally
{
if (destPtr != IntPtr.Zero)
{
for (var i = 0; i < index; i++)
Marshal.FreeCoTaskMem(Marshal.ReadIntPtr(destPtr, i * IntPtr.Size));
Marshal.FreeCoTaskMem(destPtr);
}
case VARTYPE.VT_BSTR:
vt = svt | VARTYPE.VT_VECTOR;
_blob.cbSize = (uint)sc.Length;
_blob.pBlobData = value.Select(Marshal.StringToBSTR).MarshalToPtr(Marshal.AllocCoTaskMem, out var _);
break;
case VARTYPE.VT_LPSTR:
vt = svt | VARTYPE.VT_VECTOR;
_blob.cbSize = (uint)sc.Length;
_blob.pBlobData = value.Select(Marshal.StringToCoTaskMemAnsi).MarshalToPtr(Marshal.AllocCoTaskMem, out var _);
//_blob.pBlobData = value.MarshalToPtr(StringListPackMethod.Packed, Marshal.AllocCoTaskMem, out var _, CharSet.Ansi);
break;
case VARTYPE.VT_LPWSTR:
InitPropVariantFromStringVector(sc, (uint)sc.Length, this).ThrowIfFailed();
break;
default:
break;
}
}
@ -1308,12 +1303,52 @@ namespace Vanara.PInvoke
vt = (VARTYPE)varEnum | VARTYPE.VT_VECTOR;
if (array == null) return;
var enumerable = array as ICollection<T> ?? array.ToList();
_blob.cbSize = (uint)enumerable.Count;
var sz = Marshal.SizeOf(typeof(T));
// TODO: Fix this so that it uses the system call in hopes that PropVarClear will actually release the memory.
_blob.pBlobData = Marshal.AllocCoTaskMem(sz * (int)_blob.cbSize);
enumerable.MarshalToPtr(_blob.pBlobData);
var sz = 0U;
switch (varEnum)
{
case VarEnum.VT_I2:
InitPropVariantFromInt16Vector(GetArray<short>(out sz), sz, this).ThrowIfFailed();
break;
case VarEnum.VT_I4:
InitPropVariantFromInt32Vector(GetArray<int>(out sz), sz, this).ThrowIfFailed();
break;
case VarEnum.VT_R8:
InitPropVariantFromDoubleVector(GetArray<double>(out sz), sz, this).ThrowIfFailed();
break;
case VarEnum.VT_BOOL:
InitPropVariantFromBooleanVector(GetArray<bool>(out sz), sz, this).ThrowIfFailed();
break;
case VarEnum.VT_UI1:
InitPropVariantFromBuffer(GetArray<byte>(out sz), sz, this).ThrowIfFailed();
break;
case VarEnum.VT_UI2:
InitPropVariantFromUInt16Vector(GetArray<ushort>(out sz), sz, this).ThrowIfFailed();
break;
case VarEnum.VT_UI4:
InitPropVariantFromUInt32Vector(GetArray<uint>(out sz), sz, this).ThrowIfFailed();
break;
case VarEnum.VT_I8:
InitPropVariantFromInt64Vector(GetArray<long>(out sz), sz, this).ThrowIfFailed();
break;
case VarEnum.VT_UI8:
InitPropVariantFromUInt64Vector(GetArray<ulong>(out sz), sz, this).ThrowIfFailed();
break;
case VarEnum.VT_FILETIME:
InitPropVariantFromFileTimeVector(GetArray<FILETIME>(out sz), sz, this).ThrowIfFailed();
break;
default:
var enumerable = array as ICollection<T> ?? array.ToList();
_blob.cbSize = (uint)enumerable.Count;
_blob.pBlobData = enumerable.MarshalToPtr(Marshal.AllocCoTaskMem, out var _);
break;
}
TV[] GetArray<TV>(out uint len)
{
var ret = ConvertToEnum<TV>(array).ToArray();
len = (uint)ret.Length;
return ret;
}
}
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>

View File

@ -189,8 +189,7 @@ namespace Vanara.PInvoke
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/propidl/nf-propidl-ienumstatpropsetstg-reset
[PreserveSig]
HRESULT Reset();
void Reset();
/// <summary>
/// <para>
@ -199,12 +198,10 @@ namespace Vanara.PInvoke
/// to that point later. The new enumerator supports the same IEnumSTATPROPSETSTG interface.
/// </para>
/// </summary>
/// <param name="ppenum">
/// <returns>
/// <para>A pointer to the variable that receives the IEnumSTATPROPSETSTG interface pointer.</para>
/// <para>If the method does not succeed, the value of the parameter is undefined.</para>
/// </param>
/// <returns>
/// <para>This method supports return values listed in the following table.</para>
/// <para>This method supports exceptions listed in the following table.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
@ -225,8 +222,7 @@ namespace Vanara.PInvoke
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/propidl/nf-propidl-ienumstatpropsetstg-clone
[PreserveSig]
HRESULT Clone(out IEnumSTATPROPSETSTG ppenum);
IEnumSTATPROPSETSTG Clone();
}
/// <summary>
@ -328,8 +324,7 @@ namespace Vanara.PInvoke
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/propidl/nf-propidl-ienumstatpropstg-reset
[PreserveSig]
HRESULT Reset();
void Reset();
/// <summary>
/// <para>
@ -364,8 +359,7 @@ namespace Vanara.PInvoke
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/propidl/nf-propidl-ienumstatpropstg-clone
[PreserveSig]
HRESULT Clone(out IEnumSTATPROPSTG ppenum);
IEnumSTATPROPSTG Clone();
}
/// <summary>

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,6 @@ using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using Vanara.InteropServices;
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
/// <summary>Platform invokable enumerated types, constants and functions from ole32.h</summary>

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,4 @@
// ReSharper disable InconsistentNaming
using System;
using System;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke

View File

@ -321,12 +321,36 @@ namespace Vanara.PInvoke
STOREID_FALLBACK = 2
}
/// <summary><para>Exposes a method that creates an object of a specified class.</para></summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/propsys/nn-propsys-icreateobject
[PInvokeData("propsys.h", MSDNShortId = "90502b4a-dc0a-4077-83d7-e9f5445ba69b")]
[ComImport, Guid("75121952-e0d0-43e5-9380-1d80483acf72"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICreateObject
{
/// <summary><para>Creates a local object of a specified class and returns a pointer to a specified interface on the object.</para></summary><param name="clsid"><para>Type: <c>REFCLSID</c></para><para>A reference to a CLSID.</para></param><param name="pUnkOuter"><para>Type: <c>IUnknown*</c></para><para>A pointer to the IUnknown interface that aggregates the object created by this function, or <c>NULL</c> if no aggregation is desired.</para></param><param name="riid"><para>Type: <c>REFIID</c></para><para>A reference to the IID of the interface the created object should return.</para></param><param name="ppv"><para>Type: <c>void**</c></para><para>When this method returns, contains the address of the pointer to the interface requested in riid.</para></param><returns><para>Type: <c>HRESULT</c></para><para>If this method succeeds, it returns <c>S_OK</c>. Otherwise, it returns an <c>HRESULT</c> error code.</para></returns><remarks><para>This method can be used with GetPropertyStoreWithCreateObject.</para></remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/propsys/nf-propsys-icreateobject-createobject
// HRESULT CreateObject( REFCLSID clsid, IUnknown *pUnkOuter, REFIID riid, void **ppv );
[PInvokeData("propsys.h", MSDNShortId = "72c56de7-4c04-4bcf-b6bb-6e41d12b68a3")]
void CreateObject(in Guid clsid, [MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, in Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppv);
}
/// <summary><para>Exposes a method to create a specified IPropertyStore object in circumstances where property access is potentially slow.</para></summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/propsys/nn-propsys-idelayedpropertystorefactory
[PInvokeData("propsys.h", MSDNShortId = "855c9f10-9f40-4c60-a669-551fa51133f5")]
[ComImport, Guid("40d4577f-e237-4bdb-bd69-58f089431b6a"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDelayedPropertyStoreFactory : IPropertyStoreFactory
{
/// <summary><para>Gets an IPropertyStore object that corresponds to the supplied flags.</para></summary><param name="flags"><para>Type: <c>GETPROPERTYSTOREFLAGS</c></para><para>GETPROPERTYSTOREFLAGS values that modify the store that is returned.</para></param><param name="pUnkFactory"><para>Type: <c>IUnknown*</c></para><para>Optional. A pointer to the IUnknown of an object that implements ICreateObject. If pUnkFactory is provided, this method can create the handler instance using <c>ICreateObject</c> rather than CoCreateInstance, if implemented. The reason to provide pUnkFactory is usually to create the handler in a different process. However, for most users, passing <c>NULL</c> in this parameter is sufficient.</para></param><param name="riid"><para>Type: <c>REFIID</c></para><para>A reference to IID of the object to create.</para></param><param name="ppv"><para>Type: <c>void**</c></para><para>When this method returns, contains the address of an IPropertyStore interface pointer.</para></param><returns><para>Type: <c>HRESULT</c></para><para>If this method succeeds, it returns <c>S_OK</c>. Otherwise, it returns an <c>HRESULT</c> error code.</para></returns><remarks><para>It is recommended that you use the IID_PPV_ARGS macro, defined in Objbase.h, to package the riid and ppv parameters. This macro provides the correct IID based on the interface pointed to by the value in ppv, which eliminates the possibility of a coding error.</para></remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/propsys/nf-propsys-ipropertystorefactory-getpropertystore
// HRESULT GetPropertyStore( GETPROPERTYSTOREFLAGS flags, IUnknown *pUnkFactory, REFIID riid, void **ppv );
new void GetPropertyStore(GETPROPERTYSTOREFLAGS flags, [Optional, MarshalAs(UnmanagedType.IUnknown)] ICreateObject pUnkFactory, in Guid riid, out IPropertyStore ppv);
/// <summary><para>Gets an IPropertyStore object, given a set of property keys. This provides an alternative, possibly faster, method of getting an <c>IPropertyStore</c> object compared to calling IPropertyStoreFactory::GetPropertyStore.</para></summary><param name="rgKeys"><para>Type: <c>const PROPERTYKEY*</c></para><para>A pointer to an array of PROPERTYKEY structures.</para></param><param name="cKeys"><para>Type: <c>UINT</c></para><para>The number of PROPERTYKEY structures in the array pointed to by rgKeys.</para></param><param name="flags"><para>Type: <c>GETPROPERTYSTOREFLAGS</c></para><para>GETPROPERTYSTOREFLAGS values that modify the store that is returned.</para></param><param name="riid"><para>Type: <c>REFIID</c></para><para>A reference to IID of the object to create.</para></param><param name="ppv"><para>Type: <c>void**</c></para><para>When this method returns, contains the address of an IPropertyStore interface pointer.</para></param><returns><para>Type: <c>HRESULT</c></para><para>If this method succeeds, it returns <c>S_OK</c>. Otherwise, it returns an <c>HRESULT</c> error code.</para></returns><remarks><para>It is recommended that you use the IID_PPV_ARGS macro, defined in Objbase.h, to package the riid and ppv parameters. This macro provides the correct IID based on the interface pointed to by the value in ppv, which eliminates the possibility of a coding error.</para></remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/propsys/nf-propsys-ipropertystorefactory-getpropertystoreforkeys
// HRESULT GetPropertyStoreForKeys( const PROPERTYKEY *rgKeys, UINT cKeys, GETPROPERTYSTOREFLAGS flags, REFIID riid, void **ppv );
new void GetPropertyStoreForKeys([In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] PROPERTYKEY[] rgKeys, uint cKeys, GETPROPERTYSTOREFLAGS flags,
in Guid riid, out IPropertyStore ppv);
/// <summary><para>Gets an IPropertyStore interface object, as specified.</para></summary><param name="flags"><para>Type: <c>GETPROPERTYSTOREFLAGS</c></para><para>The GPS_XXX flags that modify the store that is returned. See GETPROPERTYSTOREFLAGS.</para></param><param name="dwStoreId"><para>Type: <c>DWORD</c></para><para>The property store ID. Valid values are.</para><para>STOREID_INNATE</para><para>Value is 0.</para><para>STOREID_FILE</para><para>Value is 1.</para><para>STOREID_FALLBACK</para><para>Value is 2.</para></param><param name="riid"><para>Type: <c>REFIID</c></para><para>A reference to the desired IID.</para></param><param name="ppv"><para>Type: <c>void**</c></para><para>The address of an IPropertyStore interface pointer.</para></param><returns><para>Type: <c>HRESULT</c></para><para>If this method succeeds, it returns <c>S_OK</c>. Otherwise, it returns an <c>HRESULT</c> error code.</para></returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/propsys/nf-propsys-idelayedpropertystorefactory-getdelayedpropertystore
// HRESULT GetDelayedPropertyStore( GETPROPERTYSTOREFLAGS flags, DWORD dwStoreId, REFIID riid, void **ppv );
@ -621,7 +645,7 @@ namespace Vanara.PInvoke
/// <summary><para>Gets an IPropertyStore object that corresponds to the supplied flags.</para></summary><param name="flags"><para>Type: <c>GETPROPERTYSTOREFLAGS</c></para><para>GETPROPERTYSTOREFLAGS values that modify the store that is returned.</para></param><param name="pUnkFactory"><para>Type: <c>IUnknown*</c></para><para>Optional. A pointer to the IUnknown of an object that implements ICreateObject. If pUnkFactory is provided, this method can create the handler instance using <c>ICreateObject</c> rather than CoCreateInstance, if implemented. The reason to provide pUnkFactory is usually to create the handler in a different process. However, for most users, passing <c>NULL</c> in this parameter is sufficient.</para></param><param name="riid"><para>Type: <c>REFIID</c></para><para>A reference to IID of the object to create.</para></param><param name="ppv"><para>Type: <c>void**</c></para><para>When this method returns, contains the address of an IPropertyStore interface pointer.</para></param><returns><para>Type: <c>HRESULT</c></para><para>If this method succeeds, it returns <c>S_OK</c>. Otherwise, it returns an <c>HRESULT</c> error code.</para></returns><remarks><para>It is recommended that you use the IID_PPV_ARGS macro, defined in Objbase.h, to package the riid and ppv parameters. This macro provides the correct IID based on the interface pointed to by the value in ppv, which eliminates the possibility of a coding error.</para></remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/propsys/nf-propsys-ipropertystorefactory-getpropertystore
// HRESULT GetPropertyStore( GETPROPERTYSTOREFLAGS flags, IUnknown *pUnkFactory, REFIID riid, void **ppv );
void GetPropertyStore(GETPROPERTYSTOREFLAGS flags, [MarshalAs(UnmanagedType.IUnknown)] object pUnkFactory, in Guid riid, out IPropertyStore ppv);
void GetPropertyStore(GETPROPERTYSTOREFLAGS flags, [Optional, MarshalAs(UnmanagedType.IUnknown)] ICreateObject pUnkFactory, in Guid riid, out IPropertyStore ppv);
/// <summary><para>Gets an IPropertyStore object, given a set of property keys. This provides an alternative, possibly faster, method of getting an <c>IPropertyStore</c> object compared to calling IPropertyStoreFactory::GetPropertyStore.</para></summary><param name="rgKeys"><para>Type: <c>const PROPERTYKEY*</c></para><para>A pointer to an array of PROPERTYKEY structures.</para></param><param name="cKeys"><para>Type: <c>UINT</c></para><para>The number of PROPERTYKEY structures in the array pointed to by rgKeys.</para></param><param name="flags"><para>Type: <c>GETPROPERTYSTOREFLAGS</c></para><para>GETPROPERTYSTOREFLAGS values that modify the store that is returned.</para></param><param name="riid"><para>Type: <c>REFIID</c></para><para>A reference to IID of the object to create.</para></param><param name="ppv"><para>Type: <c>void**</c></para><para>When this method returns, contains the address of an IPropertyStore interface pointer.</para></param><returns><para>Type: <c>HRESULT</c></para><para>If this method succeeds, it returns <c>S_OK</c>. Otherwise, it returns an <c>HRESULT</c> error code.</para></returns><remarks><para>It is recommended that you use the IID_PPV_ARGS macro, defined in Objbase.h, to package the riid and ppv parameters. This macro provides the correct IID based on the interface pointed to by the value in ppv, which eliminates the possibility of a coding error.</para></remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/propsys/nf-propsys-ipropertystorefactory-getpropertystoreforkeys

View File

@ -524,7 +524,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.PropSys, SetLastError = false, ExactSpelling = true)]
[PInvokeData("propsys.h", MSDNShortId = "010572d5-0357-4101-803e-0a27fc60ca5e")]
public static extern HRESULT PSCreatePropertyStoreFromObject([MarshalAs(UnmanagedType.IUnknown)] object punk, STGM grfMode, in Guid riid,
[MarshalAs(UnmanagedType.Interface)] out object ppv);
[MarshalAs(UnmanagedType.Interface)] out IPropertyStore ppv);
/// <summary>
/// <para>Wraps an IPropertySetStorage interface in an IPropertyStore interface.</para>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -105,7 +105,7 @@ namespace Vanara.PInvoke
/// <summary>Returns a <see cref="string"/> that represents this instance.</summary>
/// <returns>A <see cref="string"/> that represents this instance.</returns>
public override string ToString() => Buffer;
public override string ToString() => Buffer.Substring(0, Length);
/// <summary>Performs an implicit conversion from <see cref="LSA_STRING"/> to <see cref="string"/>.</summary>
/// <param name="value">The value.</param>

View File

@ -1,8 +1,5 @@
using System;
using System.Runtime.InteropServices;
using static Vanara.PInvoke.Secur32;
// ReSharper disable InconsistentNaming ReSharper disable FieldCanBeMadeReadOnly.Global ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
@ -14,8 +11,8 @@ namespace Vanara.PInvoke
public enum LsaAccountAccessMask : uint
{
/// <summary>
/// This access type is required to read the account information. This includes the privileges assigned to the account, memory quotas assigned, and
/// any special access types granted.
/// This access type is required to read the account information. This includes the privileges assigned to the account, memory
/// quotas assigned, and any special access types granted.
/// </summary>
ACCOUNT_VIEW = 0x00000001,
@ -55,8 +52,8 @@ namespace Vanara.PInvoke
public enum LsaLookupNamesFlags : uint
{
/// <summary>
/// The function searches only on the local systems for names that do not specify a domain. The function does search on remote systems for names that
/// do specify a domain.
/// The function searches only on the local systems for names that do not specify a domain. The function does search on remote
/// systems for names that do specify a domain.
/// </summary>
LSA_LOOKUP_ISOLATED_AS_LOCAL = 0x80000000
}
@ -66,40 +63,210 @@ namespace Vanara.PInvoke
[PInvokeData("ntlsa.h")]
public enum LsaLookupSidsFlags : uint
{
/// <summary>Internet SIDs from identity providers for connected accounts are disallowed. Connected accounts are those accounts which have a corresponding shadow account in the local SAM database connected to an online identity provider. For example, MicrosoftAccount is a connected account.</summary>
/// <summary>
/// Internet SIDs from identity providers for connected accounts are disallowed. Connected accounts are those accounts which have
/// a corresponding shadow account in the local SAM database connected to an online identity provider. For example,
/// MicrosoftAccount is a connected account.
/// </summary>
LSA_LOOKUP_DISALLOW_CONNECTED_ACCOUNT_INTERNET_SID = 0x80000000,
/// <summary>Returns the internet names. Otherwise the NT4 style name (domain\username) is returned. The exception is if the Microsoft Account internet SID is specified, in which case the internet name is returned unless LSA_LOOKUP_DISALLOW_NON_WINDOWS_INTERNET_SID is specified.</summary>
/// <summary>
/// Returns the internet names. Otherwise the NT4 style name (domain\username) is returned. The exception is if the Microsoft
/// Account internet SID is specified, in which case the internet name is returned unless
/// LSA_LOOKUP_DISALLOW_NON_WINDOWS_INTERNET_SID is specified.
/// </summary>
LSA_LOOKUP_PREFER_INTERNET_NAMES = 0x40000000,
/// <summary>Always returns local SAM account names even for Internet provider identities.</summary>
LSA_LOOKUP_RETURN_LOCAL_NAMES = 0
}
/// <summary>
/// The LsaGetAppliedCAPIDs function returns an array of central access policies (CAPs) identifiers (CAPIDs) of all the CAPs applied on a specific computer.
/// The LsaGetAppliedCAPIDs function returns an array of central access policies (CAPs) identifiers (CAPIDs) of all the CAPs applied
/// on a specific computer.
/// </summary>
/// <param name="systemName">
/// The name of the specific computer. The name can have the form of "ComputerName" or "\\ComputerName". If this parameter is NULL, then the function
/// returns the CAPIDs of the local computer.
/// The name of the specific computer. The name can have the form of "ComputerName" or "\\ComputerName". If this parameter is NULL,
/// then the function returns the CAPIDs of the local computer.
/// </param>
/// <param name="CAPIDs">
/// A pointer to a variable that receives an array of pointers to CAPIDs that identify the CAPs available on the specified computer. When you have
/// finished using the CAPIDs, call the LsaFreeMemory function on each element in the array and the entire array.
/// A pointer to a variable that receives an array of pointers to CAPIDs that identify the CAPs available on the specified computer.
/// When you have finished using the CAPIDs, call the LsaFreeMemory function on each element in the array and the entire array.
/// </param>
/// <param name="CAPIDCount">
/// A pointer to a variable that receives the number of CAPs that are available on the specified computer. The array returned in the CAPIDs parameter
/// contains the same number of elements as the CAPIDCount parameter.
/// A pointer to a variable that receives the number of CAPs that are available on the specified computer. The array returned in the
/// CAPIDs parameter contains the same number of elements as the CAPIDCount parameter.
/// </param>
/// <returns>
/// If the function succeeds, the return value is STATUS_SUCCESS.
/// <para>
/// If the function fails, the return value is one of the LSA Policy Function Return Values. You can use the LsaNtStatusToWinError function to convert
/// the NTSTATUS code to a Windows error code.
/// If the function fails, the return value is one of the LSA Policy Function Return Values. You can use the LsaNtStatusToWinError
/// function to convert the NTSTATUS code to a Windows error code.
/// </para>
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true, CharSet = CharSet.Unicode)]
[PInvokeData("ntlsa.h", MSDNShortId = "hh846251")]
public static extern uint LsaGetAppliedCAPIDs(
public static extern NTStatus LsaGetAppliedCAPIDs(
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string systemName,
out SafeLsaMemoryHandle CAPIDs, out uint CAPIDCount);
/// <summary>
/// <para>
/// Retrieves the locally unique identifier (LUID) used by the Local Security Authority (LSA) to represent the specified privilege name.
/// </para>
/// <para>This function is not declared in a public header.</para>
/// <para>Do not use this function. Instead, use LookupPrivilegeValue.</para>
/// </summary>
/// <param name="PolicyHandle">
/// <para>A handle to the LSA Policy object.</para>
/// </param>
/// <param name="Name">
/// <para>A pointer to a null-terminated string that specifies the name of the privilege, as defined in the Winnt.h header file.</para>
/// </param>
/// <param name="Value">
/// <para>A pointer to a variable that receives the LUID by which the privilege is known by the LSA.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, return <c>STATUS_SUCCESS</c>.</para>
/// <para>If the function fails, return an <c>NTSTATUS</c> code that indicates the reason it failed.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/ntlsa/nf-ntlsa-lsalookupprivilegevalue NTSTATUS LsaLookupPrivilegeValue(
// LSA_HANDLE PolicyHandle, PLSA_UNICODE_STRING Name, PLUID Value );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntlsa.h", MSDNShortId = "4926fff9-6e1a-475c-95ab-78c9b67aaa87")]
public static extern NTStatus LsaLookupPrivilegeValue(LSA_HANDLE PolicyHandle, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string Name, out LUID Value);
/// <summary>
/// <para>Returns the Central Access Policies (CAPs) for the specified IDs.</para>
/// </summary>
/// <param name="CAPIDs">
/// <para>A pointer to a variable that contains an array of pointers to CAPIDs that identify the CAPs being queried.</para>
/// </param>
/// <param name="CAPIDCount">
/// <para>The number of IDs in the CAPIDs parameter.</para>
/// </param>
/// <param name="CAPs">
/// <para>Receives a pointer to an array of pointers to CENTRAL_ACCESS_POLICY structures representing the queried CAPs.</para>
/// </param>
/// <param name="CAPCount">
/// <para>The number of CENTRAL_ACCESS_POLICY structure pointers returned in the CAPs parameter.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is STATUS_SUCCESS.</para>
/// <para>If the function fails, the return value is an NTSTATUS code, which can be one of the LSA Policy Function Return Values.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/ntlsa/nf-ntlsa-lsaquerycaps NTSTATUS LsaQueryCAPs( PSID *CAPIDs, ULONG
// CAPIDCount, PCENTRAL_ACCESS_POLICY *CAPs, PULONG CAPCount );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntlsa.h", MSDNShortId = "55D6FD6F-0FD5-41F6-967B-F5600E19C3EF")]
public static extern NTStatus LsaQueryCAPs([In] IntPtr[] CAPIDs, uint CAPIDCount, SafeLsaMemoryHandle CAPs, out uint CAPCount);
/// <summary>
/// <para>Represents a central access policy that contains a set of central access policy entries.</para>
/// </summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/ntlsa/ns-ntlsa-_central_access_policy typedef struct _CENTRAL_ACCESS_POLICY {
// PSID CAPID; LSA_UNICODE_STRING Name; LSA_UNICODE_STRING Description; LSA_UNICODE_STRING ChangeId; ULONG Flags; ULONG CAPECount;
// PCENTRAL_ACCESS_POLICY_ENTRY *CAPEs; } CENTRAL_ACCESS_POLICY, *PCENTRAL_ACCESS_POLICY;
[PInvokeData("ntlsa.h", MSDNShortId = "C1C2E8AE-0B7F-4620-9C27-31DAF683E342")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CENTRAL_ACCESS_POLICY
{
/// <summary>
/// <para>The identifier of the central access policy.</para>
/// </summary>
public IntPtr CAPID;
/// <summary>
/// <para>The name of the central access policy.</para>
/// </summary>
public LSA_UNICODE_STRING Name;
/// <summary>
/// <para>The description of the central access policy.</para>
/// </summary>
public LSA_UNICODE_STRING Description;
/// <summary>
/// <para>An identifier that can be used to version the central access policy.</para>
/// </summary>
public LSA_UNICODE_STRING ChangeId;
/// <summary>
/// <para>Reserved.</para>
/// </summary>
public uint Flags;
/// <summary>
/// <para>The length of the buffer pointed to by the CAPEs field.</para>
/// </summary>
public uint CAPECount;
/// <summary>
/// <para>Pointer to a buffer of CENTRAL_ACCESS_POLICY_ENTRY pointers.</para>
/// </summary>
public IntPtr CAPEs;
}
/// <summary>
/// <para>Represents a central access policy entry containing a list of security descriptors and staged security descriptors.</para>
/// </summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/ntlsa/ns-ntlsa-_central_access_policy_entry typedef struct
// _CENTRAL_ACCESS_POLICY_ENTRY { LSA_UNICODE_STRING Name; LSA_UNICODE_STRING Description; LSA_UNICODE_STRING ChangeId; ULONG
// LengthAppliesTo; PUCHAR AppliesTo; ULONG LengthSD; PSECURITY_DESCRIPTOR SD; ULONG LengthStagedSD; PSECURITY_DESCRIPTOR StagedSD;
// ULONG Flags; } CENTRAL_ACCESS_POLICY_ENTRY, *PCENTRAL_ACCESS_POLICY_ENTRY;
[PInvokeData("ntlsa.h", MSDNShortId = "8667848D-096C-422E-B4A6-38CC406F0F4A")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CENTRAL_ACCESS_POLICY_ENTRY
{
/// <summary>
/// <para>The name of the central access policy entry.</para>
/// </summary>
public LSA_UNICODE_STRING Name;
/// <summary>
/// <para>The description of the central access policy entry.</para>
/// </summary>
public LSA_UNICODE_STRING Description;
/// <summary>
/// <para>An identifier that can be used to version the central access policy entry.</para>
/// </summary>
public LSA_UNICODE_STRING ChangeId;
/// <summary>
/// <para>The length of the buffer pointed to by the AppliesTo field.</para>
/// </summary>
public uint LengthAppliesTo;
/// <summary>
/// <para>A resource condition in binary form.</para>
/// </summary>
public IntPtr AppliesTo;
/// <summary>
/// <para>The length of the buffer pointed to by the SD field.</para>
/// </summary>
public uint LengthSD;
/// <summary>
/// <para>A buffer of security descriptors associated with the entry.</para>
/// </summary>
public IntPtr SD;
/// <summary>
/// <para>The length of the buffer pointed to by the StagedSD field.</para>
/// </summary>
public uint LengthStagedSD;
/// <summary>
/// <para>A buffer of staged security descriptors associated with the entry.</para>
/// </summary>
public IntPtr StagedSD;
/// <summary>
/// <para>This field is reserved.</para>
/// </summary>
public uint Flags;
}
}
}

View File

@ -453,7 +453,7 @@ namespace Vanara.PInvoke
if (ret == NTStatus.STATUS_NO_MORE_ENTRIES) return new PSID[0];
var wret = LsaNtStatusToWinError(ret);
wret.ThrowIfFailed();
return mem.DangerousGetHandle().ToIEnum<LSA_ENUMERATION_INFORMATION>(cnt).Select(u => PSID.CreateFromPtr(u.Sid));
return mem.DangerousGetHandle().ToIEnum<LSA_ENUMERATION_INFORMATION>(cnt).Select(u => u.Sid);
}
/// <summary>Gets system access for an account.</summary>
@ -1269,7 +1269,7 @@ namespace Vanara.PInvoke
public struct LSA_ENUMERATION_INFORMATION
{
/// <summary>Pointer to a SID.</summary>
public IntPtr Sid;
public PSID Sid;
}
/// <summary>
@ -1297,7 +1297,7 @@ namespace Vanara.PInvoke
public struct LSA_FOREST_TRUST_DOMAIN_INFO
{
/// <summary/>
public IntPtr Sid;
public PSID Sid;
/// <summary>
/// <para>LSA_UNICODE_STRING structure that contains the DNS name of the domain.</para>
@ -1531,7 +1531,7 @@ namespace Vanara.PInvoke
/// <summary>Returns a <see cref="string"/> that represents this instance.</summary>
/// <returns>A <see cref="string"/> that represents this instance.</returns>
public override string ToString() => Buffer;
public override string ToString() => Buffer.Substring(0, Length);
/// <summary>Performs an implicit conversion from <see cref="LSA_UNICODE_STRING"/> to <see cref="string"/>.</summary>
/// <param name="value">The value.</param>
@ -1998,5 +1998,60 @@ namespace Vanara.PInvoke
return s;
}
}
/*
AuditComputeEffectivePolicyBySid function
AuditComputeEffectivePolicyByToken function
AuditEnumerateCategories function
AuditEnumeratePerUserPolicy function
AuditEnumerateSubCategories function
AuditFree function
AuditLookupCategoryGuidFromCategoryId function
AuditLookupCategoryIdFromCategoryGuid function
AuditLookupCategoryNameA function
AuditLookupCategoryNameW function
AuditLookupSubCategoryNameA function
AuditLookupSubCategoryNameW function
AuditQueryGlobalSaclA function
AuditQueryGlobalSaclW function
AuditQueryPerUserPolicy function
AuditQuerySecurity function
AuditQuerySystemPolicy function
AuditSetGlobalSaclA function
AuditSetGlobalSaclW function
AuditSetPerUserPolicy function
AuditSetSecurity function
AuditSetSystemPolicy function
KERB_CRYPTO_KEY structure
LsaCallAuthenticationPackage function
LsaCreateTrustedDomainEx function
LsaDeleteTrustedDomain function
LsaEnumerateLogonSessions function
LsaEnumerateTrustedDomains function
LsaEnumerateTrustedDomainsEx function
LsaGetLogonSessionData function
LsaLogonUser function
LsaLookupNames function
LsaLookupSids function
LsaOpenTrustedDomainByName function
LsaQueryDomainInformationPolicy function
LsaQueryForestTrustInformation function
LsaQueryInformationPolicy function
LsaQueryTrustedDomainInfoByName function
LsaRegisterPolicyChangeNotification function
LsaRetrievePrivateData function
LsaSetDomainInformationPolicy function
LsaSetForestTrustInformation function
LsaSetInformationPolicy function
LsaSetTrustedDomainInfoByName function
LsaStorePrivateData function
LsaUnregisterPolicyChangeNotification function
PSAM_INIT_NOTIFICATION_ROUTINE callback function
PSAM_PASSWORD_FILTER_ROUTINE callback function
PSAM_PASSWORD_NOTIFICATION_ROUTINE callback function
RtlDecryptMemory function
RtlEncryptMemory function
RtlGenRandom function
*/
}
}

View File

@ -1,8 +1,7 @@
using System;
using System.Runtime.InteropServices;
using Vanara.InteropServices;
// ReSharper disable InconsistentNaming
using static Vanara.PInvoke.Kernel32;
namespace Vanara.PInvoke
{
@ -10,121 +9,95 @@ namespace Vanara.PInvoke
{
/// <summary>Class representation of the native SID structure.</summary>
/// <seealso cref="SafeHGlobalHandle"/>
public class PSID : SafeHGlobalHandle, IEquatable<PSID>, IEquatable<IntPtr>, ICloneable
public class SafePSID : SafeMemoryHandle<HeapMemoryMethods>, IEquatable<SafePSID>, IEquatable<PSID>, IEquatable<IntPtr>, ICloneable, ISecurityObject
{
/// <summary>Equivalent to a NULL pointer to a SID.</summary>
public new static readonly PSID Null = new PSID();
public static readonly SafePSID Null = new SafePSID(0);
/// <summary>Initializes a new instance of the <see cref="PSID"/> class.</summary>
/// <param name="ptr">A pointer to an existing SID.</param>
/// <param name="own">if set to <c>true</c><see cref="Marshal.FreeHGlobal(IntPtr)"/> will be called on the pointer when disposed.</param>
public PSID(IntPtr ptr, bool own = true) : base(ptr, GetLengthSid(ptr), own)
{
}
/// <summary>Initializes a new instance of the <see cref="SafePSID"/> class.</summary>
/// <param name="psid">The existing <see cref="SafePSID"/> instance to duplicate.</param>
public SafePSID(PSID psid) : base(GetLengthSid(psid)) => CopySid(Size, handle, psid);
/// <summary>Initializes a new instance of the <see cref="PSID"/> class.</summary>
/// <param name="psid">The existing <see cref="PSID"/> instance to duplicate.</param>
public PSID(PSID psid) : base(GetLengthSid(psid.handle))
{
CopySid(Size, handle, psid.handle);
}
/// <summary>Initializes a new instance of the <see cref="PSID"/> class.</summary>
/// <summary>Initializes a new instance of the <see cref="SafePSID"/> class.</summary>
/// <param name="size">The size of memory to allocate, in bytes.</param>
public PSID(int size) : base(size)
public SafePSID(int size) : base(size)
{
}
/// <summary>Initializes a new instance of the <see cref="PSID"/> class.</summary>
/// <summary>Initializes a new instance of the <see cref="SafePSID"/> class.</summary>
/// <param name="sidBytes">An array of bytes that contain a valid Sid.</param>
public PSID(byte[] sidBytes) : base(sidBytes?.Length ?? 0)
{
Marshal.Copy(sidBytes, 0, handle, Size);
}
public SafePSID(byte[] sidBytes) : base(sidBytes?.Length ?? 0) => Marshal.Copy(sidBytes, 0, handle, Size);
/// <summary>Initializes a new instance of the <see cref="PSID"/> class.</summary>
/// <summary>Initializes a new instance of the <see cref="SafePSID"/> class.</summary>
/// <param name="sidValue">The string SID value.</param>
public PSID(string sidValue) : base(IntPtr.Zero, 0, true)
{
if (ConvertStringSidToSid(sidValue, out IntPtr psid))
SetHandle(psid);
}
/// <summary>Initializes a new instance of the <see cref="PSID"/> class.</summary>
public PSID() : base(0)
public SafePSID(string sidValue) : this(ConvertStringSidToSid(sidValue))
{
}
/// <summary>Verifies that the revision number is within a known range, and that the number of subauthorities is less than the maximum.</summary>
/// <summary>
/// Verifies that the revision number is within a known range, and that the number of subauthorities is less than the maximum.
/// </summary>
/// <value><c>true</c> if this instance is a valid SID; otherwise, <c>false</c>.</value>
public bool IsValidSid => IsValidSid(this);
/// <summary>Copies the specified SID from a memory pointer to a <see cref="PSID"/> instance.</summary>
/// <summary>Copies the specified SID from a memory pointer to a <see cref="SafePSID"/> instance.</summary>
/// <param name="psid">The SID pointer. This value remains the responsibility of the caller to release.</param>
/// <returns>A <see cref="PSID"/> instance.</returns>
public static PSID CreateFromPtr(IntPtr psid)
/// <returns>A <see cref="SafePSID"/> instance.</returns>
public static SafePSID CreateFromPtr(IntPtr psid)
{
var newSid = new PSID(GetLengthSid(psid));
var newSid = new SafePSID(GetLengthSid(psid));
CopySid(newSid.Size, newSid.handle, psid);
return newSid;
}
/// <summary>Performs an explicit conversion from <see cref="PSID"/> to <see cref="IntPtr"/>.</summary>
/// <param name="psid">The PSID instance.</param>
/// <summary>Performs an explicit conversion from <see cref="SafePSID"/> to <see cref="IntPtr"/>.</summary>
/// <param name="psid">The SafePSID instance.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(PSID psid) => psid.DangerousGetHandle();
public static explicit operator IntPtr(SafePSID psid) => psid.DangerousGetHandle();
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="PSID"/>.</summary>
/// <param name="psid">The SID pointer.</param>
/// <summary>Performs an explicit conversion from <see cref="SafePSID"/> to <see cref="PSID"/>.</summary>
/// <param name="psid">The SafePSID instance.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator PSID(IntPtr psid) => new PSID(psid, false);
public static implicit operator PSID(SafePSID psid) => psid.DangerousGetHandle();
/// <summary>Initializes a new <see cref="PSID"/> instance from a SID authority and subauthorities.</summary>
/// <summary>Initializes a new <see cref="SafePSID"/> instance from a SID authority and subauthorities.</summary>
/// <param name="sidAuthority">The SID authority.</param>
/// <param name="subAuth0">The first subauthority.</param>
/// <param name="subAuthorities1to7">Up to seven other subauthorities.</param>
/// <returns>A new <see cref="PSID"/> instance.</returns>
/// <returns>A new <see cref="SafePSID"/> instance.</returns>
/// <exception cref="System.ArgumentOutOfRangeException">
/// <paramref name="sidAuthority"/> is null or an invalid length or more than 8 total subauthorities were submitted.
/// </exception>
public static PSID Init(PSID_IDENTIFIER_AUTHORITY sidAuthority, int subAuth0, params int[] subAuthorities1to7)
public static SafePSID Init(PSID_IDENTIFIER_AUTHORITY sidAuthority, int subAuth0, params int[] subAuthorities1to7)
{
if (sidAuthority == null)
throw new ArgumentOutOfRangeException(nameof(sidAuthority));
if (subAuthorities1to7.Length > 7)
throw new ArgumentOutOfRangeException(nameof(subAuthorities1to7));
var res = IntPtr.Zero;
try
{
AllocateAndInitializeSid(sidAuthority, (byte)(subAuthorities1to7.Length + 1),
subAuth0,
subAuthorities1to7.Length > 0 ? subAuthorities1to7[0] : 0,
subAuthorities1to7.Length > 1 ? subAuthorities1to7[1] : 0,
subAuthorities1to7.Length > 2 ? subAuthorities1to7[2] : 0,
subAuthorities1to7.Length > 3 ? subAuthorities1to7[3] : 0,
subAuthorities1to7.Length > 4 ? subAuthorities1to7[4] : 0,
subAuthorities1to7.Length > 5 ? subAuthorities1to7[5] : 0,
subAuthorities1to7.Length > 6 ? subAuthorities1to7[6] : 0,
out res);
return CreateFromPtr(res);
}
finally
{
FreeSid(res);
}
AllocateAndInitializeSid(sidAuthority, (byte)(subAuthorities1to7.Length + 1),
subAuth0,
subAuthorities1to7.Length > 0 ? subAuthorities1to7[0] : 0,
subAuthorities1to7.Length > 1 ? subAuthorities1to7[1] : 0,
subAuthorities1to7.Length > 2 ? subAuthorities1to7[2] : 0,
subAuthorities1to7.Length > 3 ? subAuthorities1to7[3] : 0,
subAuthorities1to7.Length > 4 ? subAuthorities1to7[4] : 0,
subAuthorities1to7.Length > 5 ? subAuthorities1to7[5] : 0,
subAuthorities1to7.Length > 6 ? subAuthorities1to7[6] : 0,
out var res);
return new SafePSID(res);
}
/// <summary>Implements the operator !=.</summary>
/// <param name="psid1">The psid1.</param>
/// <param name="psid2">The psid2.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(PSID psid1, PSID psid2) => !(psid1 == psid2);
public static bool operator !=(SafePSID psid1, SafePSID psid2) => !(psid1 == psid2);
/// <summary>Implements the operator ==.</summary>
/// <param name="psid1">The psid1.</param>
/// <param name="psid2">The psid2.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(PSID psid1, PSID psid2)
public static bool operator ==(SafePSID psid1, SafePSID psid2)
{
if (ReferenceEquals(psid1, psid2)) return true;
if (Equals(null, psid1) || Equals(null, psid2)) return false;
@ -132,13 +105,18 @@ namespace Vanara.PInvoke
}
/// <summary>Clones this instance.</summary>
/// <returns>A copy of the current <see cref="PSID"/>.</returns>
public PSID Clone() => CreateFromPtr(handle);
/// <returns>A copy of the current <see cref="SafePSID"/>.</returns>
public SafePSID Clone() => CreateFromPtr(handle);
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
public bool Equals(PSID other) => EqualSid(this, other);
public bool Equals(SafePSID other) => EqualSid(this, other);
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
public bool Equals(PSID other) => Equals(other.DangerousGetHandle());
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
@ -147,19 +125,23 @@ namespace Vanara.PInvoke
/// <summary>Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.</summary>
/// <param name="obj">The object to compare with the current object.</param>
/// <returns>true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.</returns>
/// <returns>
/// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
/// </returns>
public override bool Equals(object obj)
{
if (obj is PSID psid2)
if (obj is SafePSID psid2)
return Equals(psid2);
if (obj is PSID psidh)
return Equals(psidh);
if (obj is IntPtr ptr)
return Equals(ptr);
return false;
}
/// <summary>Gets the binary form of this PSID.</summary>
/// <summary>Gets the binary form of this SafePSID.</summary>
/// <returns>An array of bytes containing the Sid.</returns>
public byte[] GetBinaryForm() => ToArray<byte>(GetLengthSid(handle));
public byte[] GetBinaryForm() => base.GetBytes(0, Size);
/// <summary>Returns a hash code for this instance.</summary>
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>

View File

@ -0,0 +1,112 @@
using System;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
public static partial class AdvApi32
{
/// <summary>The OpenProcessToken function opens the access token associated with a process.</summary>
/// <param name="ProcessHandle">
/// A handle to the process whose access token is opened. The process must have the PROCESS_QUERY_INFORMATION access permission.
/// </param>
/// <param name="DesiredAccess">
/// Specifies an access mask that specifies the requested types of access to the access token. These requested access types are
/// compared with the discretionary access control list (DACL) of the token to determine which accesses are granted or denied.
/// </param>
/// <param name="TokenHandle">A pointer to a handle that identifies the newly opened access token when the function returns.</param>
/// <returns>
/// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error
/// information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "aa379295")]
public static extern bool OpenProcessToken([In] HPROCESS ProcessHandle, TokenAccess DesiredAccess, out SafeHTOKEN TokenHandle);
/// <summary>The <c>OpenThreadToken</c> function opens the access token associated with a thread.</summary>
/// <param name="ThreadHandle">A handle to the thread whose access token is opened.</param>
/// <param name="DesiredAccess">
/// <para>
/// Specifies an access mask that specifies the requested types of access to the access token. These requested access types are
/// reconciled against the token's discretionary access control list (DACL) to determine which accesses are granted or denied.
/// </para>
/// <para>For a list of access rights for access tokens, see Access Rights for Access-Token Objects.</para>
/// </param>
/// <param name="OpenAsSelf">
/// <para>TRUE if the access check is to be made against the process-level security context.</para>
/// <para>
/// <c>FALSE</c> if the access check is to be made against the current security context of the thread calling the
/// <c>OpenThreadToken</c> function.
/// </para>
/// <para>
/// The OpenAsSelf parameter allows the caller of this function to open the access token of a specified thread when the caller is
/// impersonating a token at <c>SecurityIdentification</c> level. Without this parameter, the calling thread cannot open the access
/// token on the specified thread because it is impossible to open executive-level objects by using the <c>SecurityIdentification</c>
/// impersonation level.
/// </para>
/// </param>
/// <param name="TokenHandle">A pointer to a variable that receives the handle to the newly opened access token.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>
/// If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>. If the token has
/// the anonymous impersonation level, the token will not be opened and <c>OpenThreadToken</c> sets ERROR_CANT_OPEN_ANONYMOUS as the error.
/// </para>
/// </returns>
// BOOL WINAPI OpenThreadToken( _In_ HANDLE ThreadHandle, _In_ DWORD DesiredAccess, _In_ BOOL OpenAsSelf, _Out_ PHANDLE TokenHandle); https://msdn.microsoft.com/en-us/library/windows/desktop/aa379296(v=vs.85).aspx
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "aa379296")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenThreadToken([In] HTHREAD ThreadHandle, TokenAccess DesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool OpenAsSelf, out SafeHTOKEN TokenHandle);
/// <summary>
/// The <c>SetThreadToken</c> function assigns an impersonation token to a thread. The function can also cause a thread to stop using
/// an impersonation token.
/// </summary>
/// <param name="Thread">
/// <para>A pointer to a handle to the thread to which the function assigns the impersonation token.</para>
/// <para>If Thread is <c>NULL</c>, the function assigns the impersonation token to the calling thread.</para>
/// </param>
/// <param name="Token">
/// <para>
/// A handle to the impersonation token to assign to the thread. This handle must have been opened with TOKEN_IMPERSONATE access
/// rights. For more information, see Access Rights for Access-Token Objects.
/// </para>
/// <para>If Token is <c>NULL</c>, the function causes the thread to stop using an impersonation token.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI SetThreadToken( _In_opt_ PHANDLE Thread, _In_opt_ HANDLE Token); https://msdn.microsoft.com/en-us/library/windows/desktop/aa379590(v=vs.85).aspx
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "aa379590")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetThreadToken(in HTHREAD Thread, [Optional] HTOKEN Token);
/// <summary>
/// The <c>SetThreadToken</c> function assigns an impersonation token to a thread. The function can also cause a thread to stop using
/// an impersonation token.
/// </summary>
/// <param name="Thread">
/// <para>A pointer to a handle to the thread to which the function assigns the impersonation token.</para>
/// <para>If Thread is <c>NULL</c>, the function assigns the impersonation token to the calling thread.</para>
/// </param>
/// <param name="Token">
/// <para>
/// A handle to the impersonation token to assign to the thread. This handle must have been opened with TOKEN_IMPERSONATE access
/// rights. For more information, see Access Rights for Access-Token Objects.
/// </para>
/// <para>If Token is <c>NULL</c>, the function causes the thread to stop using an impersonation token.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI SetThreadToken( _In_opt_ PHANDLE Thread, _In_opt_ HANDLE Token); https://msdn.microsoft.com/en-us/library/windows/desktop/aa379590(v=vs.85).aspx
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "aa379590")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetThreadToken([Optional] IntPtr Thread, [Optional] HTOKEN Token);
}
}

View File

@ -1,63 +0,0 @@
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
public static partial class AdvApi32
{
/// <summary>The ConvertSidToStringSid function converts a security identifier (SID) to a string format suitable for display, storage, or transmission.</summary>
/// <param name="Sid">A pointer to the SID structure to be converted.</param>
/// <param name="StringSid">
/// A pointer to a variable that receives a pointer to a null-terminated SID string. To free the returned buffer, call the LocalFree function.
/// </param>
/// <returns>
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero.To get extended error information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("sddl.h", MSDNShortId = "aa376399")]
public static extern bool ConvertSidToStringSid(PSID Sid, out SafeHGlobalHandle StringSid);
/// <summary>Converts a security identifier (SID) to a string format suitable for display, storage, or transmission.</summary>
/// <param name="Sid">The SID structure to be converted.</param>
/// <returns>A null-terminated SID string.</returns>
[PInvokeData("sddl.h", MSDNShortId = "aa376399")]
public static string ConvertSidToStringSid(PSID Sid) => ConvertSidToStringSid(Sid, out SafeHGlobalHandle str) ? str.ToString(-1) : throw new Win32Exception();
/// <summary>
/// The ConvertStringSidToSid function converts a string-format security identifier (SID) into a valid, functional SID. You can use this function to
/// retrieve a SID that the ConvertSidToStringSid function converted to string format.
/// </summary>
/// <param name="pStringSid">
/// A pointer to a null-terminated string containing the string-format SID to convert. The SID string can use either the standard S-R-I-S-S… format for
/// SID strings, or the SID string constant format, such as "BA" for built-in administrators. For more information about SID string notation, see SID Components.
/// </param>
/// <param name="sid">A pointer to a variable that receives a pointer to the converted SID. To free the returned buffer, call the LocalFree function.</param>
/// <returns>
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("sddl.h", MSDNShortId = "aa376402")]
public static extern bool ConvertStringSidToSid(string pStringSid, out PSID sid);
/// <summary>
/// The ConvertStringSidToSid function converts a string-format security identifier (SID) into a valid, functional SID. You can use this function to
/// retrieve a SID that the ConvertSidToStringSid function converted to string format.
/// </summary>
/// <param name="pStringSid">
/// A pointer to a null-terminated string containing the string-format SID to convert. The SID string can use either the standard S-R-I-S-S… format for
/// SID strings, or the SID string constant format, such as "BA" for built-in administrators. For more information about SID string notation, see SID Components.
/// </param>
/// <param name="sid">A pointer to a variable that receives a pointer to the converted SID. To free the returned buffer, call the LocalFree function.</param>
/// <returns>
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("Sddl.h", MSDNShortId = "aa376402")]
public static extern bool ConvertStringSidToSid(string pStringSid, out IntPtr sid);
}
}

View File

@ -1,4 +1,5 @@
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Vanara.InteropServices;
namespace Vanara.PInvoke
@ -89,13 +90,73 @@ namespace Vanara.PInvoke
/// security descriptor string does not have a D: component. For more information, see Security Descriptor String Format.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/sddl/nf-sddl-convertsecuritydescriptortostringsecuritydescriptora
// BOOL ConvertSecurityDescriptorToStringSecurityDescriptorA( PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD RequestedStringSDRevision, SECURITY_INFORMATION SecurityInformation, LPSTR *StringSecurityDescriptor, PULONG StringSecurityDescriptorLen );
// https://docs.microsoft.com/en-us/windows/desktop/api/sddl/nf-sddl-convertsecuritydescriptortostringsecuritydescriptora BOOL
// ConvertSecurityDescriptorToStringSecurityDescriptorA( PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD RequestedStringSDRevision,
// SECURITY_INFORMATION SecurityInformation, LPSTR *StringSecurityDescriptor, PULONG StringSecurityDescriptorLen );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("sddl.h", MSDNShortId = "36140833-8e30-4c32-a88a-c10751b6c223")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ConvertSecurityDescriptorToStringSecurityDescriptor(SafeSecurityDescriptor SecurityDescriptor, SDDL_REVISION RequestedStringSDRevision,
SECURITY_INFORMATION SecurityInformation, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LocalStringMarshaler), MarshalCookie = "Auto")] out string StringSecurityDescriptor, out uint StringSecurityDescriptorLen);
public static extern bool ConvertSecurityDescriptorToStringSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, SDDL_REVISION RequestedStringSDRevision,
SECURITY_INFORMATION SecurityInformation, out SafeLocalHandle StringSecurityDescriptor, out uint StringSecurityDescriptorLen);
/// <summary>
/// <para>
/// The <c>ConvertSecurityDescriptorToStringSecurityDescriptor</c> function converts a security descriptor to a string format. You
/// can use the string format to store or transmit the security descriptor.
/// </para>
/// <para>
/// To convert the string-format security descriptor back to a valid, functional security descriptor, call the
/// ConvertStringSecurityDescriptorToSecurityDescriptor function.
/// </para>
/// </summary>
/// <param name="SecurityDescriptor">
/// <para>A pointer to the security descriptor to convert. The security descriptor can be in absolute or self-relative format.</para>
/// </param>
/// <param name="SecurityInformation">
/// <para>
/// Specifies a combination of the SECURITY_INFORMATION bit flags to indicate the components of the security descriptor to include in
/// the output string.
/// </para>
/// </param>
/// <returns>A security descriptor string. For a description of the string format, see Security Descriptor String Format.</returns>
/// <remarks>
/// <para>
/// If the DACL is <c>NULL</c>, and the SE_DACL_PRESENT control bit is set in the input security descriptor, the function fails.
/// </para>
/// <para>
/// If the DACL is <c>NULL</c>, and the SE_DACL_PRESENT control bit is not set in the input security descriptor, the resulting
/// security descriptor string does not have a D: component. For more information, see Security Descriptor String Format.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/sddl/nf-sddl-convertsecuritydescriptortostringsecuritydescriptora BOOL
// ConvertSecurityDescriptorToStringSecurityDescriptorA( PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD RequestedStringSDRevision,
// SECURITY_INFORMATION SecurityInformation, LPSTR *StringSecurityDescriptor, PULONG StringSecurityDescriptorLen );
[PInvokeData("sddl.h", MSDNShortId = "36140833-8e30-4c32-a88a-c10751b6c223")]
[return: MarshalAs(UnmanagedType.Bool)]
public static string ConvertSecurityDescriptorToStringSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, SECURITY_INFORMATION SecurityInformation) =>
ConvertSecurityDescriptorToStringSecurityDescriptor(SecurityDescriptor, SDDL_REVISION.SDDL_REVISION_1, SecurityInformation, out var sd, out var sz) ? sd.ToString(-1) : throw new Win32Exception();
/// <summary>
/// The ConvertSidToStringSid function converts a security identifier (SID) to a string format suitable for display, storage, or transmission.
/// </summary>
/// <param name="Sid">A pointer to the SID structure to be converted.</param>
/// <param name="StringSid">
/// A pointer to a variable that receives a pointer to a null-terminated SID string. To free the returned buffer, call the LocalFree function.
/// </param>
/// <returns>
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero.To get extended error
/// information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("sddl.h", MSDNShortId = "aa376399")]
public static extern bool ConvertSidToStringSid(PSID Sid, out SafeLocalHandle StringSid);
/// <summary>Converts a security identifier (SID) to a string format suitable for display, storage, or transmission.</summary>
/// <param name="Sid">The SID structure to be converted.</param>
/// <returns>A null-terminated SID string.</returns>
[PInvokeData("sddl.h", MSDNShortId = "aa376399")]
public static string ConvertSidToStringSid(PSID Sid) => ConvertSidToStringSid(Sid, out var str) ? str.ToString(-1) : throw new Win32Exception();
/// <summary>
/// <para>
@ -154,12 +215,80 @@ namespace Vanara.PInvoke
/// For information about the <c>ace_type</c>, <c>object_guid</c>, and <c>inherit_object_guid</c> fields, see Ace Strings.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/sddl/nf-sddl-convertstringsecuritydescriptortosecuritydescriptora
// BOOL ConvertStringSecurityDescriptorToSecurityDescriptorA( LPCSTR StringSecurityDescriptor, DWORD StringSDRevision, PSECURITY_DESCRIPTOR *SecurityDescriptor, PULONG SecurityDescriptorSize );
// https://docs.microsoft.com/en-us/windows/desktop/api/sddl/nf-sddl-convertstringsecuritydescriptortosecuritydescriptora BOOL
// ConvertStringSecurityDescriptorToSecurityDescriptorA( LPCSTR StringSecurityDescriptor, DWORD StringSDRevision,
// PSECURITY_DESCRIPTOR *SecurityDescriptor, PULONG SecurityDescriptorSize );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("sddl.h", MSDNShortId = "c5654148-fb4c-436d-9378-a1168fc82607")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string StringSecurityDescriptor, SDDL_REVISION StringSDRevision,
out SafeSecurityDescriptor SecurityDescriptor, out uint SecurityDescriptorSize);
public static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string StringSecurityDescriptor, SDDL_REVISION StringSDRevision, out SafeLocalHandle SecurityDescriptor, out uint SecurityDescriptorSize);
/// <summary>
/// <para>
/// The <c>ConvertStringSecurityDescriptorToSecurityDescriptor</c> function converts a string-format security descriptor into a
/// valid, functional security descriptor. This function retrieves a security descriptor that the
/// ConvertSecurityDescriptorToStringSecurityDescriptor function converted to string format.
/// </para>
/// </summary>
/// <param name="StringSecurityDescriptor">
/// <para>A pointer to a null-terminated string containing the string-format security descriptor to convert.</para>
/// </param>
/// <returns>
/// A pointer to the converted security descriptor. The returned security descriptor is self-relative. To convert the security
/// descriptor to an absolute security descriptor, use the MakeAbsoluteSD function.
/// </returns>
/// <remarks>
/// <para>
/// If <c>ace_type</c> is ACCESS_ALLOWED_OBJECT_ACE_TYPE and neither <c>object_guid</c> nor <c>inherit_object_guid</c> has a GUID
/// specified, then <c>ConvertStringSecurityDescriptorToSecurityDescriptor</c> converts <c>ace_type</c> to ACCESS_ALLOWED_ACE_TYPE.
/// For information about the <c>ace_type</c>, <c>object_guid</c>, and <c>inherit_object_guid</c> fields, see Ace Strings.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/sddl/nf-sddl-convertstringsecuritydescriptortosecuritydescriptora BOOL
// ConvertStringSecurityDescriptorToSecurityDescriptorA( LPCSTR StringSecurityDescriptor, DWORD StringSDRevision,
// PSECURITY_DESCRIPTOR *SecurityDescriptor, PULONG SecurityDescriptorSize );
[PInvokeData("sddl.h", MSDNShortId = "c5654148-fb4c-436d-9378-a1168fc82607")]
[return: MarshalAs(UnmanagedType.Bool)]
public static SafeSecurityDescriptor ConvertStringSecurityDescriptorToSecurityDescriptor(string StringSecurityDescriptor)
{
if (!ConvertStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor, SDDL_REVISION.SDDL_REVISION_1, out var sd, out var sz))
throw new Win32Exception();
return new SafeSecurityDescriptor(sd.ToArray<byte>((int)sz));
}
/// <summary>
/// The ConvertStringSidToSid function converts a string-format security identifier (SID) into a valid, functional SID. You can use
/// this function to retrieve a SID that the ConvertSidToStringSid function converted to string format.
/// </summary>
/// <param name="pStringSid">
/// A pointer to a null-terminated string containing the string-format SID to convert. The SID string can use either the standard
/// S-R-I-S-S… format for SID strings, or the SID string constant format, such as "BA" for built-in administrators. For more
/// information about SID string notation, see SID Components.
/// </param>
/// <param name="sid">
/// A pointer to a variable that receives a pointer to the converted SID. To free the returned buffer, call the LocalFree function.
/// </param>
/// <returns>
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error
/// information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("sddl.h", MSDNShortId = "aa376402")]
public static extern bool ConvertStringSidToSid(string pStringSid, out SafeLocalHandle sid);
/// <summary>
/// The ConvertStringSidToSid function converts a string-format security identifier (SID) into a valid, functional SID. You can use
/// this function to retrieve a SID that the ConvertSidToStringSid function converted to string format.
/// </summary>
/// <param name="pStringSid">
/// A pointer to a null-terminated string containing the string-format SID to convert. The SID string can use either the standard
/// S-R-I-S-S… format for SID strings, or the SID string constant format, such as "BA" for built-in administrators. For more
/// information about SID string notation, see SID Components.
/// </param>
/// <returns>A pointer to the converted SID.</returns>
[PInvokeData("sddl.h", MSDNShortId = "aa376402")]
[return: MarshalAs(UnmanagedType.Bool)]
public static SafePSID ConvertStringSidToSid(string pStringSid) => ConvertStringSidToSid(pStringSid, out var psid) ? new SafePSID(psid.DangerousGetHandle()) : throw new Win32Exception();
}
}
}

View File

@ -1,9 +1,5 @@
using System;
using System.ComponentModel;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Text;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
@ -14,11 +10,11 @@ namespace Vanara.PInvoke
/// A pointer to a SID_IDENTIFIER_AUTHORITY structure. This structure provides the top-level identifier authority value to set in the SID.
/// </param>
/// <param name="subAuthorityCount">
/// Specifies the number of subauthorities to place in the SID. This parameter also identifies how many of the subauthority parameters have meaningful
/// values. This parameter must contain a value from 1 to 8.
/// Specifies the number of subauthorities to place in the SID. This parameter also identifies how many of the subauthority
/// parameters have meaningful values. This parameter must contain a value from 1 to 8.
/// <para>
/// For example, a value of 3 indicates that the subauthority values specified by the dwSubAuthority0, dwSubAuthority1, and dwSubAuthority2 parameters
/// have meaningful values and to ignore the remainder.
/// For example, a value of 3 indicates that the subauthority values specified by the dwSubAuthority0, dwSubAuthority1, and
/// dwSubAuthority2 parameters have meaningful values and to ignore the remainder.
/// </para>
/// </param>
/// <param name="dwSubAuthority0">Subauthority value to place in the SID.</param>
@ -31,29 +27,35 @@ namespace Vanara.PInvoke
/// <param name="dwSubAuthority7">Subauthority value to place in the SID.</param>
/// <param name="pSid">A pointer to a variable that receives the pointer to the allocated and initialized SID structure.</param>
/// <returns>
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero.To get extended error information, call GetLastError.
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero.To get extended error
/// information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("winbase.h", MSDNShortId = "aa375213")]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa375213")]
public static extern bool AllocateAndInitializeSid([In] PSID_IDENTIFIER_AUTHORITY sia,
byte subAuthorityCount, int dwSubAuthority0, int dwSubAuthority1,
int dwSubAuthority2, int dwSubAuthority3, int dwSubAuthority4,
int dwSubAuthority5, int dwSubAuthority6, int dwSubAuthority7, out IntPtr pSid);
int dwSubAuthority5, int dwSubAuthority6, int dwSubAuthority7, out SafeAllocatedSID pSid);
/// <summary>The CopySid function copies a security identifier (SID) to a buffer.</summary>
/// <param name="cbDestSid">Specifies the length, in bytes, of the buffer receiving the copy of the SID.</param>
/// <param name="destSid">A pointer to a buffer that receives a copy of the source SID structure.</param>
/// <param name="sourceSid">A pointer to a SID structure that the function copies to the buffer pointed to by the pDestinationSid parameter.</param>
/// <param name="sourceSid">
/// A pointer to a SID structure that the function copies to the buffer pointed to by the pDestinationSid parameter.
/// </param>
/// <returns>
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError.
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error
/// information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("Winbase.h", MSDNShortId = "aa376404")]
public static extern bool CopySid(int cbDestSid, IntPtr destSid, IntPtr sourceSid);
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa376404")]
public static extern bool CopySid(int cbDestSid, IntPtr destSid, PSID sourceSid);
/// <summary>The EqualSid function tests two security identifier (SID) values for equality. Two SIDs must match exactly to be considered equal.</summary>
/// <summary>
/// The EqualSid function tests two security identifier (SID) values for equality. Two SIDs must match exactly to be considered equal.
/// </summary>
/// <param name="sid1">A pointer to the first SID structure to compare. This structure is assumed to be valid.</param>
/// <param name="sid2">A pointer to the second SID structure to compare. This structure is assumed to be valid.</param>
/// <returns>
@ -63,76 +65,140 @@ namespace Vanara.PInvoke
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("Winbase.h", MSDNShortId = "aa446622")]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa446622")]
public static extern bool EqualSid(PSID sid1, PSID sid2);
/// <summary>The EqualSid function tests two security identifier (SID) values for equality. Two SIDs must match exactly to be considered equal.</summary>
/// <param name="sid1">A pointer to the first SID structure to compare. This structure is assumed to be valid.</param>
/// <param name="sid2">A pointer to the second SID structure to compare. This structure is assumed to be valid.</param>
/// <returns>
/// If the SID structures are equal, the return value is nonzero.
/// <para>If the SID structures are not equal, the return value is zero. To get extended error information, call GetLastError.</para>
/// <para>If either SID structure is not valid, the return value is undefined.</para>
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("Winbase.h", MSDNShortId = "aa446622")]
public static extern bool EqualSid(IntPtr sid1, IntPtr sid2);
/// <summary>The FreeSid function frees a security identifier (SID) previously allocated by using the AllocateAndInitializeSid function.</summary>
/// <summary>
/// The FreeSid function frees a security identifier (SID) previously allocated by using the AllocateAndInitializeSid function.
/// </summary>
/// <param name="pSid">A pointer to the SID structure to free.</param>
/// <returns>
/// If the function succeeds, the function returns NULL. If the function fails, it returns a pointer to the SID structure represented by the pSid parameter.
/// If the function succeeds, the function returns NULL. If the function fails, it returns a pointer to the SID structure represented
/// by the pSid parameter.
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[PInvokeData("Winbase.h", MSDNShortId = "aa446631")]
public static extern IntPtr FreeSid(IntPtr pSid);
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa446631")]
public static extern PSID FreeSid(SafeAllocatedSID pSid);
/// <summary>The GetLengthSid function returns the length, in bytes, of a valid security identifier (SID).</summary>
/// <param name="pSid">A pointer to the SID structure whose length is returned. The structure is assumed to be valid.</param>
/// <returns>
/// If the SID structure is valid, the return value is the length, in bytes, of the SID structure.
/// <para>
/// If the SID structure is not valid, the return value is undefined. Before calling GetLengthSid, pass the SID to the IsValidSid function to verify that
/// the SID is valid.
/// If the SID structure is not valid, the return value is undefined. Before calling GetLengthSid, pass the SID to the IsValidSid
/// function to verify that the SID is valid.
/// </para>
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[PInvokeData("Winbase.h", MSDNShortId = "aa446642")]
public static extern int GetLengthSid(IntPtr pSid);
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa446642")]
public static extern int GetLengthSid(PSID pSid);
/// <summary>
/// The GetSidSubAuthority function returns a pointer to a specified subauthority in a security identifier (SID). The subauthority value is a relative
/// identifier (RID).
/// <para>
/// The <c>GetSidIdentifierAuthority</c> function returns a pointer to the SID_IDENTIFIER_AUTHORITY structure in a specified security
/// identifier (SID).
/// </para>
/// </summary>
/// <param name="pSid">
/// <para>A pointer to the SID structure for which a pointer to the SID_IDENTIFIER_AUTHORITY structure is returned.</para>
/// <para>
/// This function does not handle SID structures that are not valid. Call the IsValidSid function to verify that the <c>SID</c>
/// structure is valid before you call this function.
/// </para>
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, the return value is a pointer to the SID_IDENTIFIER_AUTHORITY structure for the specified SID structure.
/// </para>
/// <para>
/// If the function fails, the return value is undefined. The function fails if the SID structure pointed to by the pSid parameter is
/// not valid. To get extended error information, call GetLastError.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// This function uses a 32-bit RID value. For applications that require a larger RID value, use CreateWellKnownSid and related functions.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-getsididentifierauthority
// PSID_IDENTIFIER_AUTHORITY GetSidIdentifierAuthority( PSID pSid );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "67a06e7b-775f-424c-ab36-0fc9b93b801a")]
public static extern PSID_IDENTIFIER_AUTHORITY GetSidIdentifierAuthority(PSID pSid);
/// <summary>
/// <para>
/// The <c>GetSidLengthRequired</c> function returns the length, in bytes, of the buffer required to store a SID with a specified
/// number of subauthorities.
/// </para>
/// </summary>
/// <param name="nSubAuthorityCount">
/// <para>Specifies the number of subauthorities to be stored in the SID structure.</para>
/// </param>
/// <returns>
/// <para>The return value is the length, in bytes, of the buffer required to store the SID structure. This function cannot fail.</para>
/// </returns>
/// <remarks>
/// <para>
/// The SID structure specified in nSubAuthorityCount uses a 32-bit RID value. For applications that require longer RID values, use
/// CreateWellKnownSid and related functions.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-getsidlengthrequired DWORD
// GetSidLengthRequired( UCHAR nSubAuthorityCount );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "a481fb4f-20bd-4f44-a3d5-d8b8d6228339")]
public static extern uint GetSidLengthRequired(byte nSubAuthorityCount);
/// <summary>
/// The GetSidSubAuthority function returns a pointer to a specified subauthority in a security identifier (SID). The subauthority
/// value is a relative identifier (RID).
/// </summary>
/// <param name="pSid">A pointer to the SID structure from which a pointer to a subauthority is to be returned.</param>
/// <param name="nSubAuthority">
/// Specifies an index value identifying the subauthority array element whose address the function will return. The function performs no validation tests
/// on this value. An application can call the GetSidSubAuthorityCount function to discover the range of acceptable values.
/// Specifies an index value identifying the subauthority array element whose address the function will return. The function performs
/// no validation tests on this value. An application can call the GetSidSubAuthorityCount function to discover the range of
/// acceptable values.
/// </param>
/// <returns>
/// If the function succeeds, the return value is a pointer to the specified SID subauthority. To get extended error information, call GetLastError.
/// If the function succeeds, the return value is a pointer to the specified SID subauthority. To get extended error information,
/// call GetLastError.
/// <para>
/// If the function fails, the return value is undefined. The function fails if the specified SID structure is not valid or if the index value specified
/// by the nSubAuthority parameter is out of bounds.
/// If the function fails, the return value is undefined. The function fails if the specified SID structure is not valid or if the
/// index value specified by the nSubAuthority parameter is out of bounds.
/// </para>
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[PInvokeData("Winbase.h", MSDNShortId = "aa446657")]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa446657")]
public static extern IntPtr GetSidSubAuthority(PSID pSid, uint nSubAuthority);
/// <summary>
/// The IsValidSid function validates a security identifier (SID) by verifying that the revision number is within a known range, and that the number of
/// subauthorities is less than the maximum.
/// The IsValidSid function validates a security identifier (SID) by verifying that the revision number is within a known range, and
/// that the number of subauthorities is less than the maximum.
/// </summary>
/// <param name="pSid">A pointer to the SID structure to validate. This parameter cannot be NULL.</param>
/// <returns>
/// If the SID structure is valid, the return value is nonzero. If the SID structure is not valid, the return value is zero. There is no extended error
/// information for this function; do not call GetLastError.
/// If the SID structure is valid, the return value is nonzero. If the SID structure is not valid, the return value is zero. There is
/// no extended error information for this function; do not call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("Winbase.h", MSDNShortId = "aa379151")]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa379151")]
public static extern bool IsValidSid(PSID pSid);
/// <summary>Provides a <see cref="SafeHandle"/> to an allocated SID that is released at disposal using FreeSid.</summary>
public class SafeAllocatedSID : HANDLE, ISecurityObject
{
/// <summary>Initializes a new instance of the <see cref="SafeAllocatedSID"/> class.</summary>
private SafeAllocatedSID() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeAllocatedSID"/> to <see cref="AllocatedSID"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PSID(SafeAllocatedSID h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => FreeSid(this).IsNull;
}
}
}
}

View File

@ -1,12 +1,546 @@
using System;
using System.ComponentModel;
using System.Linq;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Text;
using Vanara.InteropServices;
using static Vanara.PInvoke.Kernel32;
namespace Vanara.PInvoke
{
public static partial class AdvApi32
{
/// <summary>Specifies the logon provider.</summary>
public enum LogonUserProvider
{
/// <summary>
/// Use the standard logon provider for the system. The default security provider is negotiate, unless you pass NULL for the
/// domain name and the user name is not in UPN format. In this case, the default provider is NTLM.
/// </summary>
LOGON32_PROVIDER_DEFAULT = 0,
/// <summary>Use the Windows NT 3.5 logon provider.</summary>
LOGON32_PROVIDER_WINNT35 = 1,
/// <summary>Use the NTLM logon provider.</summary>
LOGON32_PROVIDER_WINNT40 = 2,
/// <summary>Use the negotiate logon provider.</summary>
LOGON32_PROVIDER_WINNT50 = 3,
/// <summary>Use the virtual logon provider.</summary>
LOGON32_PROVIDER_VIRTUAL = 4
}
/// <summary>The type of logon operation to perform.</summary>
public enum LogonUserType
{
/// <summary>
/// This logon type is intended for users who will be interactively using the computer, such as a user being logged on by a
/// terminal server, remote shell, or similar process. This logon type has the additional expense of caching logon information
/// for disconnected operations; therefore, it is inappropriate for some client/server applications, such as a mail server.
/// </summary>
LOGON32_LOGON_INTERACTIVE = 2,
/// <summary>
/// This logon type is intended for high performance servers to authenticate plaintext passwords. The LogonUser function does not
/// cache credentials for this logon type.
/// </summary>
LOGON32_LOGON_NETWORK = 3,
/// <summary>
/// This logon type is intended for batch servers, where processes may be executing on behalf of a user without their direct
/// intervention. This type is also for higher performance servers that process many plaintext authentication attempts at a time,
/// such as mail or web servers.
/// </summary>
LOGON32_LOGON_BATCH = 4,
/// <summary>Indicates a service-type logon. The account provided must have the service privilege enabled.</summary>
LOGON32_LOGON_SERVICE = 5,
/// <summary>
/// GINAs are no longer supported.
/// <para>
/// <c>Windows Server 2003 and Windows XP:</c> This logon type is for GINA DLLs that log on users who will be interactively using
/// the computer. This logon type can generate a unique audit record that shows when the workstation was unlocked.
/// </para>
/// </summary>
LOGON32_LOGON_UNLOCK = 7,
/// <summary>
/// This logon type preserves the name and password in the authentication package, which allows the server to make connections to
/// other network servers while impersonating the client. A server can accept plain-text credentials from a client, call
/// LogonUser, verify that the user can access the system across the network, and still communicate with other servers.
/// </summary>
LOGON32_LOGON_NETWORK_CLEARTEXT = 8,
/// <summary>
/// This logon type allows the caller to clone its current token and specify new credentials for outbound connections. The new
/// logon session has the same local identifier but uses different credentials for other network connections. This logon type is
/// supported only by the LOGON32_PROVIDER_WINNT50 logon provider.
/// </summary>
LOGON32_LOGON_NEW_CREDENTIALS = 9
}
/// <summary>
/// The AdjustTokenPrivileges function enables or disables privileges in the specified access token. Enabling or disabling privileges
/// in an access token requires TOKEN_ADJUST_PRIVILEGES access.
/// </summary>
/// <param name="objectHandle">
/// A handle to the access token that contains the privileges to be modified. The handle must have TOKEN_ADJUST_PRIVILEGES access to
/// the token. If the PreviousState parameter is not NULL, the handle must also have TOKEN_QUERY access.
/// </param>
/// <param name="DisableAllPrivileges">
/// Specifies whether the function disables all of the token's privileges. If this value is TRUE, the function disables all
/// privileges and ignores the NewState parameter. If it is FALSE, the function modifies privileges based on the information pointed
/// to by the NewState parameter.
/// </param>
/// <param name="NewState">
/// A pointer to a TOKEN_PRIVILEGES structure that specifies an array of privileges and their attributes. If DisableAllPrivileges is
/// TRUE, the function ignores this parameter. If the DisableAllPrivileges parameter is FALSE, the AdjustTokenPrivileges function
/// enables, disables, or removes these privileges for the token. The following table describes the action taken by the
/// AdjustTokenPrivileges function, based on the privilege attribute.
/// </param>
/// <param name="BufferLength">
/// Specifies the size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be zero if the
/// PreviousState parameter is NULL.
/// </param>
/// <param name="PreviousState">
/// A pointer to a buffer that the function fills with a TOKEN_PRIVILEGES structure that contains the previous state of any
/// privileges that the function modifies. That is, if a privilege has been modified by this function, the privilege and its previous
/// state are contained in the TOKEN_PRIVILEGES structure referenced by PreviousState. If the PrivilegeCount member of
/// TOKEN_PRIVILEGES is zero, then no privileges have been changed by this function. This parameter can be NULL.
/// <para>
/// If you specify a buffer that is too small to receive the complete list of modified privileges, the function fails and does not
/// adjust any privileges. In this case, the function sets the variable pointed to by the ReturnLength parameter to the number of
/// bytes required to hold the complete list of modified privileges.
/// </para>
/// </param>
/// <param name="ReturnLength">
/// A pointer to a variable that receives the required size, in bytes, of the buffer pointed to by the PreviousState parameter. This
/// parameter can be NULL if PreviousState is NULL.
/// </param>
/// <returns>
/// If the function succeeds, the return value is nonzero. To determine whether the function adjusted all of the specified
/// privileges, call GetLastError, which returns either ERROR_SUCCESS, indicating that the function adjusted all specified
/// privileges, or ERROR_NOT_ALL_ASSIGNED, indicating that the token does not have one or more of the privileges specified in the
/// NewState parameter. The function may succeed with this error value even if no privileges were adjusted. The PreviousState
/// parameter indicates the privileges that were adjusted.
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa375202")]
public static extern bool AdjustTokenPrivileges([In] HTOKEN objectHandle,
[In, MarshalAs(UnmanagedType.Bool)] bool DisableAllPrivileges,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PTOKEN_PRIVILEGES.Marshaler))] PTOKEN_PRIVILEGES NewState,
[In] uint BufferLength,
[In, Out] SafeCoTaskMemHandle PreviousState,
//[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PTOKEN_PRIVILEGES.Marshaler), MarshalCookie = "Out")] PTOKEN_PRIVILEGES PreviousState,
[In, Out] ref uint ReturnLength);
/// <summary>
/// The AdjustTokenPrivileges function enables or disables privileges in the specified access token. Enabling or disabling privileges
/// in an access token requires TOKEN_ADJUST_PRIVILEGES access.
/// </summary>
/// <param name="objectHandle">
/// A handle to the access token that contains the privileges to be modified. The handle must have TOKEN_ADJUST_PRIVILEGES access to
/// the token. If the PreviousState parameter is not NULL, the handle must also have TOKEN_QUERY access.
/// </param>
/// <param name="DisableAllPrivileges">
/// Specifies whether the function disables all of the token's privileges. If this value is TRUE, the function disables all
/// privileges and ignores the NewState parameter. If it is FALSE, the function modifies privileges based on the information pointed
/// to by the NewState parameter.
/// </param>
/// <param name="NewState">
/// A pointer to a TOKEN_PRIVILEGES structure that specifies an array of privileges and their attributes. If DisableAllPrivileges is
/// TRUE, the function ignores this parameter. If the DisableAllPrivileges parameter is FALSE, the AdjustTokenPrivileges function
/// enables, disables, or removes these privileges for the token. The following table describes the action taken by the
/// AdjustTokenPrivileges function, based on the privilege attribute.
/// </param>
/// <param name="BufferLength">
/// Specifies the size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be zero if the
/// PreviousState parameter is NULL.
/// </param>
/// <param name="PreviousState">
/// A pointer to a buffer that the function fills with a TOKEN_PRIVILEGES structure that contains the previous state of any
/// privileges that the function modifies. That is, if a privilege has been modified by this function, the privilege and its previous
/// state are contained in the TOKEN_PRIVILEGES structure referenced by PreviousState. If the PrivilegeCount member of
/// TOKEN_PRIVILEGES is zero, then no privileges have been changed by this function. This parameter can be NULL.
/// <para>
/// If you specify a buffer that is too small to receive the complete list of modified privileges, the function fails and does not
/// adjust any privileges. In this case, the function sets the variable pointed to by the ReturnLength parameter to the number of
/// bytes required to hold the complete list of modified privileges.
/// </para>
/// </param>
/// <param name="ReturnLength">
/// A pointer to a variable that receives the required size, in bytes, of the buffer pointed to by the PreviousState parameter. This
/// parameter can be NULL if PreviousState is NULL.
/// </param>
/// <returns>
/// If the function succeeds, the return value is nonzero. To determine whether the function adjusted all of the specified
/// privileges, call GetLastError, which returns either ERROR_SUCCESS, indicating that the function adjusted all specified
/// privileges, or ERROR_NOT_ALL_ASSIGNED, indicating that the token does not have one or more of the privileges specified in the
/// NewState parameter. The function may succeed with this error value even if no privileges were adjusted. The PreviousState
/// parameter indicates the privileges that were adjusted.
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa375202")]
public static extern bool AdjustTokenPrivileges([In] HTOKEN objectHandle,
[In, MarshalAs(UnmanagedType.Bool)] bool DisableAllPrivileges, [In] SafeCoTaskMemHandle NewState,
[In] uint BufferLength, [In, Out] SafeCoTaskMemHandle PreviousState, [In, Out] ref uint ReturnLength);
/// <summary>The <c>AllocateLocallyUniqueId</c> function allocates a locally unique identifier (LUID).</summary>
/// <param name="Luid">A pointer to a <c>LUID</c> structure that receives the allocated LUID.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI AllocateLocallyUniqueId( _Out_ PLUID Luid); https://msdn.microsoft.com/en-us/library/windows/desktop/aa375260(v=vs.85).aspx
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa375260")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AllocateLocallyUniqueId(out LUID Luid);
/// <summary>The <c>DuplicateToken</c> function creates a new access token that duplicates one already in existence.</summary>
/// <param name="ExistingTokenHandle">A handle to an access token opened with TOKEN_DUPLICATE access.</param>
/// <param name="ImpersonationLevel">
/// Specifies a <c>SECURITY_IMPERSONATION_LEVEL</c> enumerated type that supplies the impersonation level of the new token.
/// </param>
/// <param name="DuplicateTokenHandle">
/// <para>
/// A pointer to a variable that receives a handle to the duplicate token. This handle has TOKEN_IMPERSONATE and TOKEN_QUERY access
/// to the new token.
/// </para>
/// <para>When you have finished using the new token, call the <c>CloseHandle</c> function to close the token handle.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI DuplicateToken( _In_ HANDLE ExistingTokenHandle, _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, _Out_ PHANDLE
// DuplicateTokenHandle); https://msdn.microsoft.com/en-us/library/windows/desktop/aa446616(v=vs.85).aspx
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa446616")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DuplicateToken(HTOKEN ExistingTokenHandle,
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, out SafeHTOKEN DuplicateTokenHandle);
/// <summary>
/// The <c>DuplicateTokenEx</c> function creates a new access token that duplicates an existing token. This function can create
/// either a primary token or an impersonation token.
/// </summary>
/// <param name="hExistingToken">A handle to an access token opened with TOKEN_DUPLICATE access.</param>
/// <param name="dwDesiredAccess">
/// <para>
/// Specifies the requested access rights for the new token. The <c>DuplicateTokenEx</c> function compares the requested access
/// rights with the existing token's discretionary access control list (DACL) to determine which rights are granted or denied. To
/// request the same access rights as the existing token, specify zero. To request all access rights that are valid for the caller,
/// specify MAXIMUM_ALLOWED.
/// </para>
/// <para>For a list of access rights for access tokens, see Access Rights for Access-Token Objects.</para>
/// </param>
/// <param name="lpTokenAttributes">
/// <para>
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that specifies a security descriptor for the new token and determines whether
/// child processes can inherit the token. If lpTokenAttributes is <c>NULL</c>, the token gets a default security descriptor and the
/// handle cannot be inherited. If the security descriptor contains a system access control list (SACL), the token gets
/// ACCESS_SYSTEM_SECURITY access right, even if it was not requested in dwDesiredAccess.
/// </para>
/// <para>
/// To set the owner in the security descriptor for the new token, the caller's process token must have the <c>SE_RESTORE_NAME</c>
/// privilege set.
/// </para>
/// </param>
/// <param name="ImpersonationLevel">
/// Specifies a value from the <c>SECURITY_IMPERSONATION_LEVEL</c> enumeration that indicates the impersonation level of the new token.
/// </param>
/// <param name="TokenType">
/// <para>Specifies one of the following values from the <c>TOKEN_TYPE</c> enumeration.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>TokenPrimary</term>
/// <term>The new token is a primary token that you can use in the CreateProcessAsUser function.</term>
/// </item>
/// <item>
/// <term>TokenImpersonation</term>
/// <term>The new token is an impersonation token.</term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="phNewToken">
/// <para>A pointer to a <c>HANDLE</c> variable that receives the new token.</para>
/// <para>When you have finished using the new token, call the <c>CloseHandle</c> function to close the token handle.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns a nonzero value.</para>
/// <para>If the function fails, it returns zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI DuplicateTokenEx( _In_ HANDLE hExistingToken, _In_ DWORD dwDesiredAccess, _In_opt_ LPSECURITY_ATTRIBUTES
// lpTokenAttributes, _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, _In_ TOKEN_TYPE TokenType, _Out_ PHANDLE phNewToken); https://msdn.microsoft.com/en-us/library/windows/desktop/aa446617(v=vs.85).aspx
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa446617")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DuplicateTokenEx(HTOKEN hExistingToken, TokenAccess dwDesiredAccess, SECURITY_ATTRIBUTES lpTokenAttributes,
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, TOKEN_TYPE TokenType, out SafeHTOKEN phNewToken);
/// <summary>The GetAce function obtains a pointer to an access control entry (ACE) in an access control list (ACL).</summary>
/// <param name="pAcl">A pointer to an ACL that contains the ACE to be retrieved.</param>
/// <param name="dwAceIndex">
/// The index of the ACE to be retrieved. A value of zero corresponds to the first ACE in the ACL, a value of one to the second ACE,
/// and so on.
/// </param>
/// <param name="pAce">A pointer to a pointer that the function sets to the address of the ACE.</param>
/// <returns>
/// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error
/// information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa446634")]
public static extern bool GetAce(PACL pAcl, int dwAceIndex, out PACE pAce);
/// <summary>The GetAclInformation function retrieves information about an access control list (ACL).</summary>
/// <param name="pAcl">
/// A pointer to an ACL. The function retrieves information about this ACL. If a null value is passed, the function causes an access violation.
/// </param>
/// <param name="pAclInformation">
/// A pointer to a buffer to receive the requested information. The structure that is placed into the buffer depends on the
/// information class requested in the dwAclInformationClass parameter.
/// </param>
/// <param name="nAclInformationLength">The size, in bytes, of the buffer pointed to by the pAclInformation parameter.</param>
/// <param name="dwAclInformationClass">
/// A value of the ACL_INFORMATION_CLASS enumeration that indicates the class of information requested. This parameter can be one of
/// two values from this enumeration:
/// <list type="bullet">
/// <listItem>
/// <para>
/// If the value is AclRevisionInformation, the function fills the buffer pointed to by the pAclInformation parameter with an
/// ACL_REVISION_INFORMATION structure.
/// </para>
/// </listItem><listItem>
/// <para>
/// If the value is AclSizeInformation, the function fills the buffer pointed to by the pAclInformation parameter with an
/// ACL_SIZE_INFORMATION structure.
/// </para>
/// </listItem>
/// </list>
/// </param>
/// <returns>
/// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error
/// information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa446635")]
public static extern bool GetAclInformation(PACL pAcl, ref ACL_REVISION_INFORMATION pAclInformation, uint nAclInformationLength = 4, ACL_INFORMATION_CLASS dwAclInformationClass = ACL_INFORMATION_CLASS.AclRevisionInformation);
/// <summary>The GetAclInformation function retrieves information about an access control list (ACL).</summary>
/// <param name="pAcl">
/// A pointer to an ACL. The function retrieves information about this ACL. If a null value is passed, the function causes an access violation.
/// </param>
/// <param name="pAclInformation">
/// A pointer to a buffer to receive the requested information. The structure that is placed into the buffer depends on the
/// information class requested in the dwAclInformationClass parameter.
/// </param>
/// <param name="nAclInformationLength">The size, in bytes, of the buffer pointed to by the pAclInformation parameter.</param>
/// <param name="dwAclInformationClass">
/// A value of the ACL_INFORMATION_CLASS enumeration that indicates the class of information requested. This parameter can be one of
/// two values from this enumeration:
/// <list type="bullet">
/// <listItem>
/// <para>
/// If the value is AclRevisionInformation, the function fills the buffer pointed to by the pAclInformation parameter with an
/// ACL_REVISION_INFORMATION structure.
/// </para>
/// </listItem><listItem>
/// <para>
/// If the value is AclSizeInformation, the function fills the buffer pointed to by the pAclInformation parameter with an
/// ACL_SIZE_INFORMATION structure.
/// </para>
/// </listItem>
/// </list>
/// </param>
/// <returns>
/// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error
/// information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa446635")]
public static extern bool GetAclInformation(PACL pAcl, ref ACL_SIZE_INFORMATION pAclInformation, uint nAclInformationLength = 12, ACL_INFORMATION_CLASS dwAclInformationClass = ACL_INFORMATION_CLASS.AclSizeInformation);
/// <summary>The GetPrivateObjectSecurity function retrieves information from a private object's security descriptor.</summary>
/// <param name="ObjectDescriptor">A pointer to a SECURITY_DESCRIPTOR structure. This is the security descriptor to be queried.</param>
/// <param name="SecurityInformation">
/// A set of bit flags that indicate the parts of the security descriptor to retrieve. This parameter can be a combination of the
/// SECURITY_INFORMATION bit flags.
/// </param>
/// <param name="ResultantDescriptor">
/// A pointer to a buffer that receives a copy of the requested information from the specified security descriptor. The
/// SECURITY_DESCRIPTOR structure is returned in self-relative format.
/// </param>
/// <param name="DescriptorLength">Specifies the size, in bytes, of the buffer pointed to by the ResultantDescriptor parameter.</param>
/// <param name="ReturnLength">
/// A pointer to a variable the function sets to zero if the descriptor is copied successfully. If the buffer is too small for the
/// security descriptor, this variable receives the number of bytes required. If this variable's value is greater than the value of
/// the DescriptorLength parameter when the function returns, the function returns FALSE and none of the security descriptor is
/// copied to the buffer.
/// </param>
/// <returns>
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error
/// information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa446646")]
public static extern bool GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor, SECURITY_INFORMATION SecurityInformation,
SafeSecurityDescriptor ResultantDescriptor, uint DescriptorLength, out uint ReturnLength);
/// <summary><para>The <c>GetSecurityDescriptorControl</c> function retrieves a security descriptor control and revision information.</para></summary><param name="pSecurityDescriptor"><para>A pointer to a SECURITY_DESCRIPTOR structure whose control and revision information the function retrieves.</para></param><param name="pControl"><para>A pointer to a SECURITY_DESCRIPTOR_CONTROL structure that receives the security descriptor&#39;s control information.</para></param><param name="lpdwRevision"><para>A pointer to a variable that receives the security descriptor&#39;s revision value. This value is always set, even when <c>GetSecurityDescriptorControl</c> returns an error.</para></param><returns><para>If the function succeeds, the return value is nonzero.</para><para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para></returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-getsecuritydescriptorcontrol
// BOOL GetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor, PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "d66682f2-8017-4245-9d93-5f8332a5b483")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetSecurityDescriptorControl(PSECURITY_DESCRIPTOR pSecurityDescriptor, out SECURITY_DESCRIPTOR_CONTROL pControl, out SDDL_REVISION lpdwRevision);
/// <summary>
/// The GetSecurityDescriptorDacl function retrieves a pointer to the discretionary access control list (DACL) in a specified
/// security descriptor.
/// </summary>
/// <param name="pSecurityDescriptor">
/// A pointer to the SECURITY_DESCRIPTOR structure that contains the DACL. The function retrieves a pointer to it.
/// </param>
/// <param name="lpbDaclPresent">
/// A pointer to a value that indicates the presence of a DACL in the specified security descriptor. If lpbDaclPresent is TRUE, the
/// security descriptor contains a DACL, and the remaining output parameters in this function receive valid values. If lpbDaclPresent
/// is FALSE, the security descriptor does not contain a DACL, and the remaining output parameters do not receive valid values.
/// <para>
/// A value of TRUE for lpbDaclPresent does not mean that pDacl is not NULL. That is, lpbDaclPresent can be TRUE while pDacl is NULL,
/// meaning that a NULL DACL is in effect. A NULL DACL implicitly allows all access to an object and is not the same as an empty
/// DACL. An empty DACL permits no access to an object. For information about creating a proper DACL, see Creating a DACL.
/// </para>
/// </param>
/// <param name="pDacl">
/// A pointer to a pointer to an access control list (ACL). If a DACL exists, the function sets the pointer pointed to by pDacl to
/// the address of the security descriptor's DACL. If a DACL does not exist, no value is stored.
/// <para>
/// If the function stores a NULL value in the pointer pointed to by pDacl, the security descriptor has a NULL DACL. A NULL DACL
/// implicitly allows all access to an object.
/// </para>
/// <para>
/// If an application expects a non-NULL DACL but encounters a NULL DACL, the application should fail securely and not allow access.
/// </para>
/// </param>
/// <param name="lpbDaclDefaulted">
/// A pointer to a flag set to the value of the SE_DACL_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure if a DACL exists
/// for the security descriptor. If this flag is TRUE, the DACL was retrieved by a default mechanism; if FALSE, the DACL was
/// explicitly specified by a user.
/// </param>
/// <returns>
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error
/// information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa446648")]
public static extern bool GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, [MarshalAs(UnmanagedType.Bool)] out bool lpbDaclPresent,
out PACL pDacl, [MarshalAs(UnmanagedType.Bool)] out bool lpbDaclDefaulted);
/// <summary><para>The <c>GetSecurityDescriptorGroup</c> function retrieves the primary group information from a security descriptor.</para></summary><param name="pSecurityDescriptor"><para>A pointer to a SECURITY_DESCRIPTOR structure whose primary group information the function retrieves.</para></param><param name="pGroup"><para>A pointer to a pointer to a security identifier (SID) that identifies the primary group when the function returns. If the security descriptor does not contain a primary group, the function sets the pointer pointed to by pGroup to <c>NULL</c> and ignores the remaining output parameter, lpbGroupDefaulted. If the security descriptor contains a primary group, the function sets the pointer pointed to by pGroup to the address of the security descriptor&#39;s group SID and provides a valid value for the variable pointed to by lpbGroupDefaulted.</para></param><param name="lpbGroupDefaulted"><para>A pointer to a flag that is set to the value of the SE_GROUP_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure when the function returns. If the value stored in the variable pointed to by the pGroup parameter is <c>NULL</c>, no value is set.</para></param><returns><para>If the function succeeds, the function returns nonzero.</para><para>If the function fails, it returns zero. To get extended error information, call GetLastError.</para></returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-getsecuritydescriptorgroup
// BOOL GetSecurityDescriptorGroup( PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID *pGroup, LPBOOL lpbGroupDefaulted );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "a920b49e-a4c2-4e49-b529-88c12205d995")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR pSecurityDescriptor, out PSID pGroup, [MarshalAs(UnmanagedType.Bool)] out bool lpbGroupDefaulted);
/// <summary><para>The <c>GetSecurityDescriptorLength</c> function returns the length, in bytes, of a structurally valid security descriptor. The length includes the length of all associated structures.</para></summary><param name="pSecurityDescriptor"><para>A pointer to the SECURITY_DESCRIPTOR structure whose length the function returns. The pointer is assumed to be valid.</para></param><returns><para>If the function succeeds, the function returns the length, in bytes, of the SECURITY_DESCRIPTOR structure.</para><para>If the SECURITY_DESCRIPTOR structure is not valid, the return value is undefined.</para></returns><remarks><para>The minimum length of a security descriptor is SECURITY_DESCRIPTOR_MIN_LENGTH. A security descriptor of this length has no associated security identifiers (SIDs) or access control lists (ACLs).</para></remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-getsecuritydescriptorlength
// DWORD GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pSecurityDescriptor );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "eb331839-ff3e-4f4b-b93b-18da2ea72697")]
public static extern uint GetSecurityDescriptorLength(PSECURITY_DESCRIPTOR pSecurityDescriptor);
/// <summary>The GetSecurityDescriptorOwner function retrieves the owner information from a security descriptor.</summary>
/// <param name="pSecurityDescriptor">A pointer to a SECURITY_DESCRIPTOR structure whose owner information the function retrieves.</param>
/// <param name="pOwner">
/// A pointer to a pointer to a security identifier (SID) that identifies the owner when the function returns. If the security
/// descriptor does not contain an owner, the function sets the pointer pointed to by pOwner to NULL and ignores the remaining output
/// parameter, lpbOwnerDefaulted. If the security descriptor contains an owner, the function sets the pointer pointed to by pOwner to
/// the address of the security descriptor's owner SID and provides a valid value for the variable pointed to by lpbOwnerDefaulted.
/// </param>
/// <param name="lpbOwnerDefaulted">
/// A pointer to a flag that is set to the value of the SE_OWNER_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure when the
/// function returns. If the value stored in the variable pointed to by the pOwner parameter is NULL, no value is set.
/// </param>
/// <returns>
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error
/// information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa446651")]
public static extern bool GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR pSecurityDescriptor, out PSID pOwner, [MarshalAs(UnmanagedType.Bool)] out bool lpbOwnerDefaulted);
/// <summary><para>The <c>GetSecurityDescriptorSacl</c> function retrieves a pointer to the system access control list (SACL) in a specified security descriptor.</para></summary><param name="pSecurityDescriptor"><para>A pointer to the SECURITY_DESCRIPTOR structure that contains the SACL to which the function retrieves a pointer.</para></param><param name="lpbSaclPresent"><para>A pointer to a flag the function sets to indicate the presence of a SACL in the specified security descriptor. If this parameter is <c>TRUE</c>, the security descriptor contains a SACL, and the remaining output parameters in this function receive valid values. If this parameter is <c>FALSE</c>, the security descriptor does not contain a SACL, and the remaining output parameters do not receive valid values.</para></param><param name="pSacl"><para>A pointer to a pointer to an access control list (ACL). If a SACL exists, the function sets the pointer pointed to by pSacl to the address of the security descriptor&#39;s SACL. If a SACL does not exist, no value is stored.</para><para>If the function stores a <c>NULL</c> value in the pointer pointed to by pSacl, the security descriptor has a <c>NULL</c> SACL.</para></param><param name="lpbSaclDefaulted"><para>A pointer to a flag that is set to the value of the SE_SACL_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure if a SACL exists for the security descriptor.</para></param><returns><para>If the function succeeds, the function returns nonzero.</para><para>If the function fails, it returns zero. To get extended error information, call GetLastError.</para></returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-getsecuritydescriptorsacl
// BOOL GetSecurityDescriptorSacl( PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbSaclPresent, PACL *pSacl, LPBOOL lpbSaclDefaulted );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "6bf59735-aaa3-4751-8c98-00cc197df4e5")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, [MarshalAs(UnmanagedType.Bool)] out bool lpbSaclPresent, out PACL pSacl,
[MarshalAs(UnmanagedType.Bool)] out bool lpbSaclDefaulted);
/// <summary>
/// The GetTokenInformation function retrieves a specified type of information about an access token. The calling process must have
/// appropriate access rights to obtain the information.
/// </summary>
/// <param name="hObject">
/// A handle to an access token from which information is retrieved. If TokenInformationClass specifies TokenSource, the handle must
/// have TOKEN_QUERY_SOURCE access. For all other TokenInformationClass values, the handle must have TOKEN_QUERY access.
/// </param>
/// <param name="tokenInfoClass">
/// Specifies a value from the TOKEN_INFORMATION_CLASS enumerated type to identify the type of information the function retrieves.
/// Any callers who check the TokenIsAppContainer and have it return 0 should also verify that the caller token is not an identify
/// level impersonation token. If the current token is not an application container but is an identity level token, you should return AccessDenied.
/// </param>
/// <param name="pTokenInfo">
/// A pointer to a buffer the function fills with the requested information. The structure put into this buffer depends upon the type
/// of information specified by the TokenInformationClass parameter.
/// </param>
/// <param name="tokenInfoLength">
/// Specifies the size, in bytes, of the buffer pointed to by the TokenInformation parameter. If TokenInformation is NULL, this
/// parameter must be zero.
/// </param>
/// <param name="returnLength">
/// A pointer to a variable that receives the number of bytes needed for the buffer pointed to by the TokenInformation parameter. If
/// this value is larger than the value specified in the TokenInformationLength parameter, the function fails and stores no data in
/// the buffer.
/// <para>
/// If the value of the TokenInformationClass parameter is TokenDefaultDacl and the token has no default DACL, the function sets the
/// variable pointed to by ReturnLength to sizeof(TOKEN_DEFAULT_DACL) and sets the DefaultDacl member of the TOKEN_DEFAULT_DACL
/// structure to NULL.
/// </para>
/// </param>
/// <returns>
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error
/// information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa446671")]
public static extern bool GetTokenInformation(HTOKEN hObject, TOKEN_INFORMATION_CLASS tokenInfoClass, SafeAllocatedMemoryHandle pTokenInfo, int tokenInfoLength, out int returnLength);
/// <summary>
/// <para>
/// The <c>ImpersonateLoggedOnUser</c> function lets the calling thread impersonate the security context of a logged-on user. The
@ -60,11 +594,295 @@ namespace Vanara.PInvoke
/// <para><c>Windows XP with SP1 and earlier:</c> The <c>SeImpersonatePrivilege</c> privilege is not supported.</para>
/// <para>For more information about impersonation, see Client Impersonation.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-impersonateloggedonuser
// BOOL ImpersonateLoggedOnUser( HANDLE hToken );
// https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-impersonateloggedonuser BOOL
// ImpersonateLoggedOnUser( HANDLE hToken );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "cf5c31ae-6749-45c2-888f-697060cc8c75")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ImpersonateLoggedOnUser(SafeHTOKEN hToken);
public static extern bool ImpersonateLoggedOnUser(HTOKEN hToken);
/// <summary>
/// The MapGenericMask function maps the generic access rights in an access mask to specific and standard access rights. The function
/// applies a mapping supplied in a <see cref="GENERIC_MAPPING"/> structure.
/// </summary>
/// <param name="AccessMask">A pointer to an access mask.</param>
/// <param name="GenericMapping">
/// A pointer to a <see cref="GENERIC_MAPPING"/> structure specifying a mapping of generic access types to specific and standard
/// access types.
/// </param>
[DllImport(Lib.AdvApi32, ExactSpelling = true)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa379266")]
public static extern void MapGenericMask(ref uint AccessMask, ref GENERIC_MAPPING GenericMapping);
/// <summary>
/// The PrivilegeCheck function determines whether a specified set of privileges are enabled in an access token. The PrivilegeCheck
/// function is typically called by a server application to check the privileges of a client's access token.
/// </summary>
/// <param name="ClientToken">
/// A handle to an access token representing a client process. This handle must have been obtained by opening the token of a thread
/// impersonating the client. The token must be open for TOKEN_QUERY access.
/// </param>
/// <param name="RequiredPrivileges">
/// A pointer to a PRIVILEGE_SET structure. The Privilege member of this structure is an array of LUID_AND_ATTRIBUTES structures.
/// Before calling PrivilegeCheck, use the Privilege array to indicate the set of privileges to check. Set the Control member to
/// PRIVILEGE_SET_ALL_NECESSARY if all of the privileges must be enabled; or set it to zero if it is sufficient that any one of the
/// privileges be enabled.
/// <para>
/// When PrivilegeCheck returns, the Attributes member of each LUID_AND_ATTRIBUTES structure is set to SE_PRIVILEGE_USED_FOR_ACCESS
/// if the corresponding privilege is enabled.
/// </para>
/// </param>
/// <param name="pfResult">
/// A pointer to a value the function sets to indicate whether any or all of the specified privileges are enabled in the access
/// token. If the Control member of the PRIVILEGE_SET structure specifies PRIVILEGE_SET_ALL_NECESSARY, this value is TRUE only if all
/// the privileges are enabled; otherwise, this value is TRUE if any of the privileges are enabled.
/// </param>
/// <returns>
/// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error
/// information, call GetLastError.
/// </returns>
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa379304")]
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool PrivilegeCheck(HTOKEN ClientToken,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PRIVILEGE_SET.Marshaler))] PRIVILEGE_SET RequiredPrivileges,
[MarshalAs(UnmanagedType.Bool)] out bool pfResult);
/// <summary>The RevertToSelf function terminates the impersonation of a client application.</summary>
/// <returns>
/// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error
/// information, call GetLastError.
/// </returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
[PInvokeData("securitybaseapi.h", MSDNShortId = "aa379317")]
public static extern bool RevertToSelf();
/// <summary>Provides a <see cref="SafeHandle"/> to a that releases a created HTOKEN instance at disposal using CloseHandle.</summary>
public class SafeHTOKEN : SafeKernelHandle
{
/// <summary>
/// Retrieves a pseudo-handle that you can use as a shorthand way to refer to the access token associated with a process.
/// </summary>
/// <remarks>
/// A pseudo-handle is a special constant that can function as the access token for the current process. The calling process can
/// use a pseudo-handle to specify the access token for that process whenever a token handle is required. Child processes do not
/// inherit pseudo-handles.
/// <para>Starting in Windows 8, this pseudo-handle has only TOKEN_QUERY and TOKEN_QUERY_SOURCE access rights.</para>
/// <para>
/// A process can create a standard handle that is valid in the context of other processes and can be inherited by other
/// processes. To create this standard handle, call the DuplicateHandle function and specify the pseudo-handle as the source handle.
/// </para>
/// <para>
/// You do not need to close the pseudo-handle when you no longer need it. If you call the CloseHandle function with a
/// pseudo-handle, the function has no effect. If you call DuplicateHandle to duplicate the pseudo-handle, however, you must
/// close the duplicate handle.
/// </para>
/// </remarks>
public static readonly SafeHTOKEN CurrentProcessToken = new SafeHTOKEN((IntPtr)4, false);
/// <summary>
/// Retrieves a pseudo-handle that you can use as a shorthand way to refer to the token that is currently in effect for the
/// thread, which is the thread token if one exists and the process token otherwise.
/// </summary>
/// <remarks>
/// A pseudo-handle is a special constant that can function as the access token for the current thread. The calling thread can
/// use a pseudo-handle to specify the access token for that thread whenever a token handle is required. Child threads do not
/// inherit pseudo-handles.
/// <para>Starting in Windows 8, this pseudo-handle has only TOKEN_QUERY and TOKEN_QUERY_SOURCE access rights.</para>
/// <para>
/// A thread can create a standard handle that is valid in the context of other threads and can be inherited by other threads. To
/// create this standard handle, call the DuplicateHandle function and specify the pseudo-handle as the source handle.
/// </para>
/// <para>
/// You do not need to close the pseudo-handle when you no longer need it. If you call the CloseHandle function with a
/// pseudo-handle, the function has no effect. If you call DuplicateHandle to duplicate the pseudo-handle, however, you must
/// close the duplicate handle.
/// </para>
/// </remarks>
public static readonly SafeHTOKEN CurrentThreadEffectiveToken = new SafeHTOKEN((IntPtr)6, false);
/// <summary>
/// Retrieves a pseudo-handle that you can use as a shorthand way to refer to the impersonation token that was assigned to the
/// current thread.
/// </summary>
/// <remarks>
/// A pseudo-handle is a special constant that can function as the impersonation token for the current thread. The calling thread
/// can use a pseudo-handle to specify the impersonation token for that thread whenever a token handle is required. Child threads
/// do not inherit pseudo-handles.
/// <para>Starting in Windows 8, this pseudo-handle has only TOKEN_QUERY and TOKEN_QUERY_SOURCE access rights.</para>
/// <para>
/// A thread can create a standard handle that is valid in the context of other threads and can be inherited by other threads. To
/// create this standard handle, call the DuplicateHandle function and specify the pseudo-handle as the source handle.
/// </para>
/// <para>
/// You do not need to close the pseudo-handle when you no longer need it. If you call the CloseHandle function with a
/// pseudo-handle, the function has no effect. If you call DuplicateHandle to duplicate the pseudo-handle, however, you must
/// close the duplicate handle.
/// </para>
/// </remarks>
public static readonly SafeHTOKEN CurrentThreadToken = new SafeHTOKEN((IntPtr)5, false);
/// <summary>Initializes a new instance of the <see cref="HTOKEN"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle"><see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).</param>
public SafeHTOKEN(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
private SafeHTOKEN() : base() { }
/// <summary>Gets a value indicating whether this token is elevated.</summary>
/// <value><c>true</c> if this instance is elevated; otherwise, <c>false</c>.</value>
public bool IsElevated => GetInfo<TOKEN_ELEVATION>(TOKEN_INFORMATION_CLASS.TokenElevation).TokenIsElevated;
/// <summary>Get the token handle instance from a process handle.</summary>
/// <param name="hProcess">The process handle.</param>
/// <param name="desiredAccess">The desired access. TOKEN_DUPLICATE must usually be included.</param>
/// <returns>Resulting token handle.</returns>
public static SafeHTOKEN FromProcess(HPROCESS hProcess, TokenAccess desiredAccess = TokenAccess.TOKEN_DUPLICATE) =>
!OpenProcessToken(hProcess, desiredAccess, out var val) ? throw new Win32Exception() : val;
/// <summary>Get the token handle instance from a process instance.</summary>
/// <param name="process">The process instance. If this value is <see langword="null"/>, the current process will be used.</param>
/// <param name="desiredAccess">The desired access. TOKEN_DUPLICATE must usually be included.</param>
/// <returns>Resulting token handle.</returns>
public static SafeHTOKEN FromProcess(System.Diagnostics.Process process, TokenAccess desiredAccess = TokenAccess.TOKEN_DUPLICATE) =>
FromProcess((process ?? System.Diagnostics.Process.GetCurrentProcess()).Handle, desiredAccess);
/// <summary>Get the token handle instance from a process handle.</summary>
/// <param name="hThread">The thread handle.</param>
/// <param name="desiredAccess">The desired access. TOKEN_DUPLICATE must usually be included.</param>
/// <param name="openAsSelf">if set to <c>true</c> open as self.</param>
/// <returns>Resulting token handle.</returns>
public static SafeHTOKEN FromThread(HTHREAD hThread, TokenAccess desiredAccess = TokenAccess.TOKEN_DUPLICATE, bool openAsSelf = true)
{
if (!OpenThreadToken(hThread, desiredAccess, openAsSelf, out var val))
{
if (Marshal.GetLastWin32Error() == Win32Error.ERROR_NO_TOKEN)
{
var pval = FromProcess(System.Diagnostics.Process.GetCurrentProcess());
if (!DuplicateTokenEx(pval, TokenAccess.TOKEN_IMPERSONATE | desiredAccess, null, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenImpersonation, out val))
Win32Error.ThrowLastError();
if (!SetThreadToken(IntPtr.Zero, val))
Win32Error.ThrowLastError();
}
else
Win32Error.ThrowLastError();
}
return val;
}
/// <summary>
/// Retrieves a specified type of information about an access token cast to supplied <typeparamref name="T"/> type. The calling
/// process must have appropriate access rights to obtain the information. <note type="note">The caller is responsible for
/// ensuring that the type requested by <typeparamref name="T"/> matches the type information requested by <paramref name="tokenInfoClass"/>.</note>
/// </summary>
/// <param name="tokenInfoClass">
/// Specifies a value from the TOKEN_INFORMATION_CLASS enumerated type to identify the type of information the function
/// retrieves. Any callers who check the TokenIsAppContainer and have it return 0 should also verify that the caller token is not
/// an identify level impersonation token. If the current token is not an application container but is an identity level token,
/// you should return AccessDenied.
/// </param>
public T GetInfo<T>(TOKEN_INFORMATION_CLASS tokenInfoClass)
{
if (CorrespondingTypeAttribute.GetCorrespondingTypes(tokenInfoClass).FirstOrDefault() != typeof(T))
throw new InvalidCastException();
using (var pType = GetInfo(tokenInfoClass))
{
// Marshal from native to .NET.
switch (tokenInfoClass)
{
// DWORD
case TOKEN_INFORMATION_CLASS.TokenSessionId:
case TOKEN_INFORMATION_CLASS.TokenAppContainerNumber:
// BOOL
case TOKEN_INFORMATION_CLASS.TokenSandBoxInert:
case TOKEN_INFORMATION_CLASS.TokenHasRestrictions:
case TOKEN_INFORMATION_CLASS.TokenVirtualizationAllowed:
case TOKEN_INFORMATION_CLASS.TokenVirtualizationEnabled:
case TOKEN_INFORMATION_CLASS.TokenIsAppContainer:
return (T)Convert.ChangeType(Marshal.ReadInt32((IntPtr)pType), typeof(T));
// Enum
case TOKEN_INFORMATION_CLASS.TokenType:
case TOKEN_INFORMATION_CLASS.TokenImpersonationLevel:
case TOKEN_INFORMATION_CLASS.TokenOrigin:
case TOKEN_INFORMATION_CLASS.TokenElevationType:
case TOKEN_INFORMATION_CLASS.TokenUIAccess:
var i = Marshal.ReadInt32((IntPtr)pType);
if (typeof(T).IsEnum)
return (T)Enum.ToObject(typeof(T), i);
return (T)Convert.ChangeType(i, typeof(T));
case TOKEN_INFORMATION_CLASS.TokenLinkedToken:
if (typeof(T) == typeof(IntPtr))
return (T)Convert.ChangeType(Marshal.ReadIntPtr((IntPtr)pType), typeof(T));
return default;
// Struct
case TOKEN_INFORMATION_CLASS.TokenUser:
case TOKEN_INFORMATION_CLASS.TokenGroups:
case TOKEN_INFORMATION_CLASS.TokenOwner:
case TOKEN_INFORMATION_CLASS.TokenPrimaryGroup:
case TOKEN_INFORMATION_CLASS.TokenDefaultDacl:
case TOKEN_INFORMATION_CLASS.TokenSource:
case TOKEN_INFORMATION_CLASS.TokenStatistics:
case TOKEN_INFORMATION_CLASS.TokenRestrictedSids:
case TOKEN_INFORMATION_CLASS.TokenGroupsAndPrivileges:
case TOKEN_INFORMATION_CLASS.TokenElevation:
case TOKEN_INFORMATION_CLASS.TokenAccessInformation:
case TOKEN_INFORMATION_CLASS.TokenIntegrityLevel:
case TOKEN_INFORMATION_CLASS.TokenMandatoryPolicy:
case TOKEN_INFORMATION_CLASS.TokenLogonSid:
case TOKEN_INFORMATION_CLASS.TokenCapabilities:
case TOKEN_INFORMATION_CLASS.TokenAppContainerSid:
case TOKEN_INFORMATION_CLASS.TokenUserClaimAttributes:
case TOKEN_INFORMATION_CLASS.TokenDeviceClaimAttributes:
case TOKEN_INFORMATION_CLASS.TokenDeviceGroups:
case TOKEN_INFORMATION_CLASS.TokenRestrictedDeviceGroups:
return pType.ToStructure<T>();
case TOKEN_INFORMATION_CLASS.TokenPrivileges:
return (T)Convert.ChangeType(PTOKEN_PRIVILEGES.FromPtr((IntPtr)pType), typeof(T));
default:
return default;
}
}
}
/// <summary>
/// Retrieves a specified type of information about an access token. The calling process must have appropriate access rights to
/// obtain the information.
/// </summary>
/// <param name="tokenInfoClass">
/// Specifies a value from the TOKEN_INFORMATION_CLASS enumerated type to identify the type of information the function
/// retrieves. Any callers who check the TokenIsAppContainer and have it return 0 should also verify that the caller token is not
/// an identify level impersonation token. If the current token is not an application container but is an identity level token,
/// you should return AccessDenied.
/// </param>
/// <returns>The block of memory containing the requested information.</returns>
public SafeCoTaskMemHandle GetInfo(TOKEN_INFORMATION_CLASS tokenInfoClass)
{
// Get information size
if (!GetTokenInformation(this, tokenInfoClass, SafeCoTaskMemHandle.Null, 0, out int cbSize))
{
var e = Win32Error.GetLastError();
if (e.Failed && e != Win32Error.ERROR_INSUFFICIENT_BUFFER && e != Win32Error.ERROR_BAD_LENGTH)
e.ThrowIfFailed();
}
// Retrieve token information.
var pType = new SafeCoTaskMemHandle(cbSize);
if (!GetTokenInformation(this, tokenInfoClass, pType, cbSize, out cbSize))
Win32Error.ThrowLastError();
return pType;
}
/// <summary>Performs an implicit conversion from <see cref="SafeHTOKEN"/> to <see cref="HTOKEN"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HTOKEN(SafeHTOKEN h) => h.handle;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -832,7 +832,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("wincred.h", MSDNShortId = "b62cb9c9-2a64-4ef4-97f0-e1ea85976d3e")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CredReadDomainCredentials(ref CREDENTIAL_TARGET_INFORMATION TargetInfo, uint Flags, out uint Count, out SafeCredMemoryHandle Credential);
public static extern bool CredReadDomainCredentials(in CREDENTIAL_TARGET_INFORMATION TargetInfo, uint Flags, out uint Count, out SafeCredMemoryHandle Credential);
/// <summary>
/// <para>[ <c>CredRename</c> is no longer supported. Starting with Windows Vista, calls to <c>CredRename</c> always return ERROR_NOT_SUPPORTED.]</para>
@ -910,7 +910,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("wincred.h", MSDNShortId = "65757235-d92c-479f-8e2b-1f8d8564792b")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CredUnmarshalCredential(string MarshaledCredential, ref CRED_MARSHAL_TYPE CredType, out SafeCredMemoryHandle Credential);
public static extern bool CredUnmarshalCredential(string MarshaledCredential, out CRED_MARSHAL_TYPE CredType, out SafeCredMemoryHandle Credential);
/// <summary>
/// <para>
@ -1071,7 +1071,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("wincred.h", MSDNShortId = "9a590347-d610-4916-bf63-60fbec173ac2")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CredWrite(ref CREDENTIAL Credential, CRED_WRITE Flags = CRED_WRITE.CRED_PRESERVE_CREDENTIAL_BLOB);
public static extern bool CredWrite(in CREDENTIAL Credential, CRED_WRITE Flags);
/// <summary>
/// <para>
@ -1184,7 +1184,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("wincred.h", MSDNShortId = "6b54c14f-a736-4fb0-b4e4-97765a792a5e")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CredWriteDomainCredentials(ref CREDENTIAL_TARGET_INFORMATION TargetInfo, ref CREDENTIAL Credential, uint Flags);
public static extern bool CredWriteDomainCredentials(in CREDENTIAL_TARGET_INFORMATION TargetInfo, in CREDENTIAL Credential, CRED_WRITE Flags);
/// <summary>Undocumented.</summary>
[PInvokeData("wincred.h", MSDNShortId = "20a1d54b-04a7-4b0a-88e4-1970d1f71502")]

View File

@ -1,11 +1,4 @@
using System;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Text;
using Vanara.Extensions;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
@ -17,33 +10,58 @@ namespace Vanara.PInvoke
{
/// <summary>Required to query the values of a registry key.</summary>
KEY_QUERY_VALUE = 0x0001,
/// <summary>Required to create, delete, or set a registry value.</summary>
KEY_SET_VALUE = 0x0002,
/// <summary>Required to create a subkey of a registry key.</summary>
KEY_CREATE_SUB_KEY = 0x0004,
/// <summary>Required to enumerate the subkeys of a registry key.</summary>
KEY_ENUMERATE_SUB_KEYS = 0x0008,
/// <summary>Required to request change notifications for a registry key or for subkeys of a registry key.</summary>
KEY_NOTIFY = 0x0010,
/// <summary>Reserved for system use.</summary>
KEY_CREATE_LINK = 0x0020,
/// <summary>Indicates that an application on 64-bit Windows should operate on the 32-bit registry view. This flag is ignored by 32-bit Windows. For more information, see Accessing an Alternate Registry View.
/// <para>This flag must be combined using the OR operator with the other flags in this table that either query or access registry values.</para>
/// <note>Windows 2000: This flag is not supported.</note></summary>
/// <summary>
/// Indicates that an application on 64-bit Windows should operate on the 32-bit registry view. This flag is ignored by 32-bit
/// Windows. For more information, see Accessing an Alternate Registry View.
/// <para>
/// This flag must be combined using the OR operator with the other flags in this table that either query or access registry values.
/// </para>
/// <note>Windows 2000: This flag is not supported.</note>
/// </summary>
KEY_WOW64_32KEY = 0x0200,
/// <summary>Indicates that an application on 64-bit Windows should operate on the 64-bit registry view. This flag is ignored by 32-bit Windows. For more information, see Accessing an Alternate Registry View.
/// <para>This flag must be combined using the OR operator with the other flags in this table that either query or access registry values.</para>
/// <note>Windows 2000: This flag is not supported.</note></summary>
/// <summary>
/// Indicates that an application on 64-bit Windows should operate on the 64-bit registry view. This flag is ignored by 32-bit
/// Windows. For more information, see Accessing an Alternate Registry View.
/// <para>
/// This flag must be combined using the OR operator with the other flags in this table that either query or access registry values.
/// </para>
/// <note>Windows 2000: This flag is not supported.</note>
/// </summary>
KEY_WOW64_64KEY = 0x0100,
/// <summary></summary>
KEY_WOW64_RES = 0x0300,
/// <summary>Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY values.</summary>
KEY_READ = 0x20019,
/// <summary>Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUB_KEY access rights.</summary>
KEY_WRITE = 0x20006,
/// <summary>Equivalent to KEY_READ.</summary>
KEY_EXECUTE = 0x20019,
/// <summary>Combines the STANDARD_RIGHTS_REQUIRED, KEY_QUERY_VALUE, KEY_SET_VALUE, KEY_CREATE_SUB_KEY, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, and KEY_CREATE_LINK access rights.</summary>
/// <summary>
/// Combines the STANDARD_RIGHTS_REQUIRED, KEY_QUERY_VALUE, KEY_SET_VALUE, KEY_CREATE_SUB_KEY, KEY_ENUMERATE_SUB_KEYS,
/// KEY_NOTIFY, and KEY_CREATE_LINK access rights.
/// </summary>
KEY_ALL_ACCESS = 0xF003F,
}
@ -58,135 +76,173 @@ namespace Vanara.PInvoke
/// <summary>Notify the caller of changes to the attributes of the key, such as the security descriptor information.</summary>
REG_NOTIFY_CHANGE_ATTRIBUTES = 2,
/// <summary>Notify the caller of changes to a value of the key. This can include adding or deleting a value, or changing an existing value.</summary>
/// <summary>
/// Notify the caller of changes to a value of the key. This can include adding or deleting a value, or changing an existing value.
/// </summary>
REG_NOTIFY_CHANGE_LAST_SET = 4,
/// <summary>Notify the caller of changes to the security descriptor of the key.</summary>
REG_NOTIFY_CHANGE_SECURITY = 8,
/// <summary>
/// Indicates that the lifetime of the registration must not be tied to the lifetime of the thread issuing the RegNotifyChangeKeyValue call.
/// <note type="note">This flag value is only supported in Windows 8 and later.</note>
/// Indicates that the lifetime of the registration must not be tied to the lifetime of the thread issuing the
/// RegNotifyChangeKeyValue call. <note type="note">This flag value is only supported in Windows 8 and later.</note>
/// </summary>
REG_NOTIFY_THREAD_AGNOSTIC = 0x10000000
}
/// <summary>
/// Options for <see cref="RegOpenKeyEx"/>.
/// </summary>
/// <summary>Options for <see cref="RegOpenKeyEx"/>.</summary>
[Flags]
[PInvokeData("winnt.h")]
public enum RegOpenOptions
{
/// <summary>Reserved.</summary>
REG_OPTION_RESERVED = 0x00000000,
/// <summary>
/// This key is not volatile; this is the default. The information is stored in a file and is preserved when the system is restarted. The RegSaveKey
/// function saves keys that are not volatile.
/// This key is not volatile; this is the default. The information is stored in a file and is preserved when the system is
/// restarted. The RegSaveKey function saves keys that are not volatile.
/// </summary>
REG_OPTION_NON_VOLATILE = 0x00000000,
/// <summary>
/// All keys created by the function are volatile. The information is stored in memory and is not preserved when the corresponding registry hive is unloaded. For HKEY_LOCAL_MACHINE, this occurs only when the system initiates a full shutdown. For registry keys loaded by the RegLoadKey function, this occurs when the corresponding RegUnLoadKey is performed. The RegSaveKey function does not save volatile keys. This flag is ignored for keys that already exist.
/// <note type="note">On a user selected shutdown, a fast startup shutdown is the default behavior for the system.</note>
/// All keys created by the function are volatile. The information is stored in memory and is not preserved when the
/// corresponding registry hive is unloaded. For HKEY_LOCAL_MACHINE, this occurs only when the system initiates a full shutdown.
/// For registry keys loaded by the RegLoadKey function, this occurs when the corresponding RegUnLoadKey is performed. The
/// RegSaveKey function does not save volatile keys. This flag is ignored for keys that already exist. <note type="note">On a
/// user selected shutdown, a fast startup shutdown is the default behavior for the system.</note>
/// </summary>
REG_OPTION_VOLATILE = 0x00000001,
/// <summary>
/// <note type="note">Registry symbolic links should only be used for for application compatibility when absolutely necessary.</note>
/// <para>This key is a symbolic link. The target path is assigned to the L"SymbolicLinkValue" value of the key. The target path must be an absolute registry path.</para>
/// <para>
/// This key is a symbolic link. The target path is assigned to the L"SymbolicLinkValue" value of the key. The target path must
/// be an absolute registry path.
/// </para>
/// </summary>
REG_OPTION_CREATE_LINK = 0x00000002,
/// <summary>
/// If this flag is set, the function ignores the samDesired parameter and attempts to open the key with the access required to backup or restore the
/// key. If the calling thread has the SE_BACKUP_NAME privilege enabled, the key is opened with the ACCESS_SYSTEM_SECURITY and KEY_READ access
/// rights. If the calling thread has the SE_RESTORE_NAME privilege enabled, beginning with Windows Vista, the key is opened with the
/// ACCESS_SYSTEM_SECURITY, DELETE and KEY_WRITE access rights. If both privileges are enabled, the key has the combined access rights for both
/// privileges. For more information, see Running with Special Privileges.
/// If this flag is set, the function ignores the samDesired parameter and attempts to open the key with the access required to
/// backup or restore the key. If the calling thread has the SE_BACKUP_NAME privilege enabled, the key is opened with the
/// ACCESS_SYSTEM_SECURITY and KEY_READ access rights. If the calling thread has the SE_RESTORE_NAME privilege enabled, beginning
/// with Windows Vista, the key is opened with the ACCESS_SYSTEM_SECURITY, DELETE and KEY_WRITE access rights. If both privileges
/// are enabled, the key has the combined access rights for both privileges. For more information, see Running with Special Privileges.
/// </summary>
REG_OPTION_BACKUP_RESTORE = 0x00000004,
/// <summary>The key is a symbolic link. Registry symbolic links should only be used when absolutely necessary.</summary>
REG_OPTION_OPEN_LINK = 0x00000008,
}
/// <summary>
/// Used by the <see cref="ChangeServiceConfig(IntPtr,ServiceTypes,ServiceStartType,ServiceErrorControlType,string,string,IntPtr,char[],string,string,string)"/> function.
/// Used by the <see
/// cref="ChangeServiceConfig(IntPtr,ServiceTypes,ServiceStartType,ServiceErrorControlType,string,string,IntPtr,char[],string,string,string)"/> function.
/// </summary>
public enum ServiceErrorControlType : uint
{
/// <summary>Makes no change for this setting.</summary>
SERVICE_NO_CHANGE = 0xFFFFFFFF,
/// <summary>The startup program ignores the error and continues the startup operation.</summary>
SERVICE_ERROR_IGNORE = 0x00000000,
/// <summary>The startup program logs the error in the event log but continues the startup operation.</summary>
SERVICE_ERROR_NORMAL = 0x00000001,
/// <summary>
/// The startup program logs the error in the event log. If the last-known-good configuration is being started, the startup operation continues.
/// Otherwise, the system is restarted with the last-known-good configuration.
/// The startup program logs the error in the event log. If the last-known-good configuration is being started, the startup
/// operation continues. Otherwise, the system is restarted with the last-known-good configuration.
/// </summary>
SERVICE_ERROR_SEVERE = 0x00000002,
/// <summary>
/// The startup program logs the error in the event log, if possible. If the last-known-good configuration is being started, the startup operation
/// fails. Otherwise, the system is restarted with the last-known good configuration.
/// The startup program logs the error in the event log, if possible. If the last-known-good configuration is being started, the
/// startup operation fails. Otherwise, the system is restarted with the last-known good configuration.
/// </summary>
SERVICE_ERROR_CRITICAL = 0x00000003
}
/// <summary>
/// Used by the <see cref="ChangeServiceConfig(IntPtr,ServiceTypes,ServiceStartType,ServiceErrorControlType,string,string,IntPtr,char[],string,string,string)"/> function.
/// Used by the <see
/// cref="ChangeServiceConfig(IntPtr,ServiceTypes,ServiceStartType,ServiceErrorControlType,string,string,IntPtr,char[],string,string,string)"/> function.
/// </summary>
public enum ServiceStartType : uint
{
/// <summary>Makes no change for this setting.</summary>
SERVICE_NO_CHANGE = 0xFFFFFFFF,
/// <summary>A device driver started by the system loader. This value is valid only for driver services.</summary>
SERVICE_BOOT_START = 0x00000000,
/// <summary>A device driver started by the IoInitSystem function. This value is valid only for driver services.</summary>
SERVICE_SYSTEM_START = 0x00000001,
/// <summary>A service started automatically by the service control manager during system startup.</summary>
SERVICE_AUTO_START = 0x00000002,
/// <summary>A service started by the service control manager when a process calls the StartService function.</summary>
SERVICE_DEMAND_START = 0x00000003,
/// <summary>A service that cannot be started. Attempts to start the service result in the error code ERROR_SERVICE_DISABLED.</summary>
SERVICE_DISABLED = 0x00000004
}
/// <summary>
/// Used by the <see cref="ChangeServiceConfig(IntPtr,ServiceTypes,ServiceStartType,ServiceErrorControlType,string,string,IntPtr,char[],string,string,string)"/> function.
/// Used by the <see
/// cref="ChangeServiceConfig(IntPtr,ServiceTypes,ServiceStartType,ServiceErrorControlType,string,string,IntPtr,char[],string,string,string)"/> function.
/// </summary>
[Flags]
public enum ServiceTypes : uint
{
/// <summary>Makes no change for this setting.</summary>
SERVICE_NO_CHANGE = 0xFFFFFFFF,
/// <summary>Driver service.</summary>
SERVICE_KERNEL_DRIVER = 0x00000001,
/// <summary>File system driver service.</summary>
SERVICE_FILE_SYSTEM_DRIVER = 0x00000002,
/// <summary>Reserved</summary>
SERVICE_ADAPTER = 0x00000004,
/// <summary>Reserved</summary>
SERVICE_RECOGNIZER_DRIVER = 0x00000008,
/// <summary>Combination of SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER</summary>
SERVICE_DRIVER = SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER,
/// <summary>Service that runs in its own process.</summary>
SERVICE_WIN32_OWN_PROCESS = 0x00000010,
/// <summary>Service that shares a process with other services.</summary>
SERVICE_WIN32_SHARE_PROCESS = 0x00000020,
/// <summary>Combination of SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS</summary>
SERVICE_WIN32 = SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS,
/// <summary>The service user service</summary>
SERVICE_USER_SERVICE = 0x00000040,
/// <summary>The service userservice instance</summary>
SERVICE_USERSERVICE_INSTANCE = 0x00000080,
/// <summary>Combination of SERVICE_USER_SERVICE | SERVICE_WIN32_SHARE_PROCESS</summary>
SERVICE_USER_SHARE_PROCESS = SERVICE_USER_SERVICE | SERVICE_WIN32_SHARE_PROCESS,
/// <summary>Combination of SERVICE_USER_SERVICE | SERVICE_WIN32_OWN_PROCESS</summary>
SERVICE_USER_OWN_PROCESS = SERVICE_USER_SERVICE | SERVICE_WIN32_OWN_PROCESS,
/// <summary>The service can interact with the desktop.</summary>
SERVICE_INTERACTIVE_PROCESS = 0x00000100,
/// <summary>The service PKG service</summary>
SERVICE_PKG_SERVICE = 0x00000200,
/// <summary>Combination of all service types</summary>
SERVICE_TYPE_ALL = SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS | SERVICE_USER_SERVICE | SERVICE_USERSERVICE_INSTANCE | SERVICE_PKG_SERVICE
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
using static Vanara.PInvoke.Kernel32;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
namespace Vanara.PInvoke
@ -18,14 +19,14 @@ namespace Vanara.PInvoke
/// Registry entries subordinate to this key define types (or classes) of documents and the properties associated with those types.
/// Shell and COM applications use the information stored under this key.
/// </summary>
public static readonly SafeRegistryHandle HKEY_CLASSES_ROOT = new SafeRegistryHandle(new IntPtr(unchecked((int)0x80000000)), false);
public static readonly HKEY HKEY_CLASSES_ROOT = new HKEY(new IntPtr(unchecked((int)0x80000000)));
/// <summary>
/// Contains information about the current hardware profile of the local computer system. The information under HKEY_CURRENT_CONFIG
/// describes only the differences between the current hardware configuration and the standard configuration. Information about the
/// standard hardware configuration is stored under the Software and System keys of HKEY_LOCAL_MACHINE.
/// </summary>
public static readonly SafeRegistryHandle HKEY_CURRENT_CONFIG = new SafeRegistryHandle(new IntPtr(unchecked((int)0x80000005)), false);
public static readonly HKEY HKEY_CURRENT_CONFIG = new HKEY(new IntPtr(unchecked((int)0x80000005)));
/// <summary>
/// Registry entries subordinate to this key define the preferences of the current user. These preferences include the settings of
@ -35,10 +36,10 @@ namespace Vanara.PInvoke
/// for example, creates the HKEY_CURRENT_USER\Software\Microsoft key for its applications to use, with each application creating its
/// own subkey under the Microsoft key.
/// </summary>
public static readonly SafeRegistryHandle HKEY_CURRENT_USER = new SafeRegistryHandle(new IntPtr(unchecked((int)0x80000001)), false);
public static readonly HKEY HKEY_CURRENT_USER = new HKEY(new IntPtr(unchecked((int)0x80000001)));
/// <summary></summary>
public static readonly SafeRegistryHandle HKEY_DYN_DATA = new SafeRegistryHandle(new IntPtr(unchecked((int)0x80000006)), false);
public static readonly HKEY HKEY_DYN_DATA = new HKEY(new IntPtr(unchecked((int)0x80000006)));
/// <summary>
/// Registry entries subordinate to this key define the physical state of the computer, including data about the bus type, system
@ -47,19 +48,19 @@ namespace Vanara.PInvoke
/// preferences, network security information, software-related information (such as server names and the location of the server),
/// and other system information.
/// </summary>
public static readonly SafeRegistryHandle HKEY_LOCAL_MACHINE = new SafeRegistryHandle(new IntPtr(unchecked((int)0x80000002)), false);
public static readonly HKEY HKEY_LOCAL_MACHINE = new HKEY(new IntPtr(unchecked((int)0x80000002)));
/// <summary>
/// Registry entries subordinate to this key allow you to access performance data. The data is not actually stored in the registry;
/// the registry functions cause the system to collect the data from its source.
/// </summary>
public static readonly SafeRegistryHandle HKEY_PERFORMANCE_DATA = new SafeRegistryHandle(new IntPtr(unchecked((int)0x80000004)), false);
public static readonly HKEY HKEY_PERFORMANCE_DATA = new HKEY(new IntPtr(unchecked((int)0x80000004)));
/// <summary>
/// Registry entries subordinate to this key define the default user configuration for new users on the local computer and the user
/// configuration for the current user.
/// </summary>
public static readonly SafeRegistryHandle HKEY_USERS = new SafeRegistryHandle(new IntPtr(unchecked((int)0x80000003)), false);
public static readonly HKEY HKEY_USERS = new HKEY(new IntPtr(unchecked((int)0x80000003)));
/// <summary>Flags used by RegLoadAppKey.</summary>
[PInvokeData("winreg.h", MSDNShortId = "88eb79c1-9ea0-436e-ad2e-9ce05b8dcb2c")]
@ -694,7 +695,7 @@ namespace Vanara.PInvoke
/// </returns>
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winreg.h", MSDNShortId = "ms724837")]
public static extern Win32Error RegCloseKey(IntPtr hKey);
public static extern Win32Error RegCloseKey(HKEY hKey);
/// <summary>
/// <para>Establishes a connection to a predefined registry key on another computer.</para>
@ -750,7 +751,7 @@ namespace Vanara.PInvoke
// lpMachineName, HKEY hKey, PHKEY phkResult );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "d7fb41cc-4855-4ad7-879c-b1ac85ac5803")]
public static extern Win32Error RegConnectRegistry(string lpMachineName, SafeRegistryHandle hKey, out SafeRegistryHandle phkResult);
public static extern Win32Error RegConnectRegistry(string lpMachineName, HKEY hKey, out SafeRegistryHandle phkResult);
/// <summary>
/// <para>Copies the specified registry key, along with its values and subkeys, to the specified destination key.</para>
@ -789,7 +790,7 @@ namespace Vanara.PInvoke
// lpSubKey, HKEY hKeyDest );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "d16f2b47-e537-42b0-90b3-9f9a00e61e76")]
public static extern Win32Error RegCopyTree(SafeRegistryHandle hKeySrc, string lpSubKey, SafeRegistryHandle hKeyDest);
public static extern Win32Error RegCopyTree(HKEY hKeySrc, string lpSubKey, HKEY hKeyDest);
/// <summary>
/// <para>Creates the specified registry key. If the key already exists in the registry, the function opens it.</para>
@ -859,7 +860,7 @@ namespace Vanara.PInvoke
// lpSubKey, PHKEY phkResult );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "cb4d30f4-e288-41e8-86e0-807c313db53d")]
public static extern Win32Error RegCreateKey(SafeRegistryHandle hKey, string lpSubKey, out SafeRegistryHandle phkResult);
public static extern Win32Error RegCreateKey(HKEY hKey, string lpSubKey, out SafeRegistryHandle phkResult);
/// <summary>
/// <para>
@ -1018,7 +1019,7 @@ namespace Vanara.PInvoke
// PHKEY phkResult, LPDWORD lpdwDisposition );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "e9ffad7f-c0b6-44ce-bf22-fbe45ca98bf4")]
public static extern Win32Error RegCreateKeyEx(SafeRegistryHandle hKey, string lpSubKey, uint Reserved, string lpClass, REG_OPTION dwOptions, REGSAM samDesired, SECURITY_ATTRIBUTES lpSecurityAttributes, out SafeRegistryHandle phkResult, out REG_DISPOSITION lpdwDisposition);
public static extern Win32Error RegCreateKeyEx(HKEY hKey, string lpSubKey, uint Reserved, string lpClass, REG_OPTION dwOptions, REGSAM samDesired, SECURITY_ATTRIBUTES lpSecurityAttributes, out SafeRegistryHandle phkResult, out REG_DISPOSITION lpdwDisposition);
/// <summary>
/// <para>
@ -1179,7 +1180,7 @@ namespace Vanara.PInvoke
// lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition, HANDLE hTransaction, PVOID pExtendedParemeter );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "f18e5ff9-41c3-4c26-8d01-a8ec69bcdef2")]
public static extern Win32Error RegCreateKeyTransacted(SafeRegistryHandle hKey, string lpSubKey, uint Reserved, string lpClass, REG_OPTION dwOptions, REGSAM samDesired, SECURITY_ATTRIBUTES lpSecurityAttributes, out SafeRegistryHandle phkResult, out REG_DISPOSITION lpdwDisposition, IntPtr hTransaction, IntPtr pExtendedParemeter);
public static extern Win32Error RegCreateKeyTransacted(HKEY hKey, string lpSubKey, uint Reserved, string lpClass, REG_OPTION dwOptions, REGSAM samDesired, SECURITY_ATTRIBUTES lpSecurityAttributes, out SafeRegistryHandle phkResult, out REG_DISPOSITION lpdwDisposition, IntPtr hTransaction, IntPtr pExtendedParemeter);
/// <summary>
/// <para>Deletes a subkey and its values. Note that key names are not case sensitive.</para>
@ -1230,7 +1231,7 @@ namespace Vanara.PInvoke
// lpSubKey );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "a2310ca0-1b9f-48d1-a3b5-ea3a528bfaba")]
public static extern Win32Error RegDeleteKey(SafeRegistryHandle hKey, string lpSubKey);
public static extern Win32Error RegDeleteKey(HKEY hKey, string lpSubKey);
/// <summary>
/// <para>
@ -1303,7 +1304,7 @@ namespace Vanara.PInvoke
// lpSubKey, REGSAM samDesired, DWORD Reserved );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "41fde6a5-647c-4293-92b8-74be54fa4136")]
public static extern Win32Error RegDeleteKeyEx(SafeRegistryHandle hKey, string lpSubKey, REGSAM samDesired, uint Reserved = 0);
public static extern Win32Error RegDeleteKeyEx(HKEY hKey, string lpSubKey, REGSAM samDesired, uint Reserved = 0);
/// <summary>
/// <para>
@ -1387,7 +1388,7 @@ namespace Vanara.PInvoke
// HKEY hKey, LPCSTR lpSubKey, REGSAM samDesired, DWORD Reserved, HANDLE hTransaction, PVOID pExtendedParameter );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "4c67e08b-4338-4441-8300-6b6ed31d4b21")]
public static extern Win32Error RegDeleteKeyTransacted(SafeRegistryHandle hKey, string lpSubKey, REGSAM samDesired, uint Reserved, IntPtr hTransaction, IntPtr pExtendedParameter);
public static extern Win32Error RegDeleteKeyTransacted(HKEY hKey, string lpSubKey, REGSAM samDesired, uint Reserved, IntPtr hTransaction, IntPtr pExtendedParameter);
/// <summary>
/// <para>Removes the specified value from the specified registry key and subkey.</para>
@ -1423,7 +1424,7 @@ namespace Vanara.PInvoke
// LPCSTR lpSubKey, LPCSTR lpValueName );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "a4a082c2-8cf3-41eb-87c0-a6c453821f8b")]
public static extern Win32Error RegDeleteKeyValue(SafeRegistryHandle hKey, string lpSubKey, string lpValueName);
public static extern Win32Error RegDeleteKeyValue(HKEY hKey, string lpSubKey, string lpValueName);
/// <summary>
/// <para>Deletes the subkeys and values of the specified key recursively.</para>
@ -1465,7 +1466,7 @@ namespace Vanara.PInvoke
// lpSubKey );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "984813a9-e191-498f-8288-b8a4c567112b")]
public static extern Win32Error RegDeleteTree(SafeRegistryHandle hKey, string lpSubKey);
public static extern Win32Error RegDeleteTree(HKEY hKey, string lpSubKey);
/// <summary>
/// <para>Removes a named value from the specified registry key. Note that value names are not case sensitive.</para>
@ -1499,7 +1500,7 @@ namespace Vanara.PInvoke
// lpValueName );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "4393b4ef-cd10-40d4-bb12-2d84e7cb7d3c")]
public static extern Win32Error RegDeleteValue(SafeRegistryHandle hKey, string lpValueName);
public static extern Win32Error RegDeleteValue(HKEY hKey, string lpValueName);
/// <summary>
/// <para>
@ -1577,7 +1578,7 @@ namespace Vanara.PInvoke
// hBase );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winreg.h", MSDNShortId = "294a1d28-d09f-44a3-8bc0-6fae50c3a8f8")]
public static extern Win32Error RegDisableReflectionKey(SafeRegistryHandle hBase);
public static extern Win32Error RegDisableReflectionKey(HKEY hBase);
/// <summary>
/// <para>
@ -1611,7 +1612,7 @@ namespace Vanara.PInvoke
// hBase );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winreg.h", MSDNShortId = "6dfbc3d8-cd71-4ee9-a10b-955c26a6894c")]
public static extern Win32Error RegEnableReflectionKey(SafeRegistryHandle hBase);
public static extern Win32Error RegEnableReflectionKey(HKEY hBase);
/// <summary>
/// <para>
@ -1688,7 +1689,7 @@ namespace Vanara.PInvoke
// LPSTR lpName, DWORD cchName );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "18a05c60-6c6d-438f-9003-f07d688d86a3")]
public static extern Win32Error RegEnumKey(SafeRegistryHandle hKey, uint dwIndex, StringBuilder lpName, uint cchName);
public static extern Win32Error RegEnumKey(HKEY hKey, uint dwIndex, StringBuilder lpName, uint cchName);
/// <summary>
/// <para>
@ -1791,7 +1792,7 @@ namespace Vanara.PInvoke
// dwIndex, LPSTR lpName, LPDWORD lpcchName, LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcchClass, PFILETIME lpftLastWriteTime );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "647d34cc-01ba-4389-be29-b099ed198e7c")]
public static extern Win32Error RegEnumKeyEx(SafeRegistryHandle hKey, uint dwIndex, StringBuilder lpName, ref uint lpcchName, IntPtr lpReserved, StringBuilder lpClass, ref uint lpcchClass, out FILETIME lpftLastWriteTime);
public static extern Win32Error RegEnumKeyEx(HKEY hKey, uint dwIndex, StringBuilder lpName, ref uint lpcchName, IntPtr lpReserved, StringBuilder lpClass, ref uint lpcchClass, out FILETIME lpftLastWriteTime);
/// <summary>
/// <para>
@ -1908,7 +1909,7 @@ namespace Vanara.PInvoke
// LPDWORD lpcbData );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "7014ff96-c655-486f-af32-180b87281b06")]
public static extern Win32Error RegEnumValue(SafeRegistryHandle hKey, uint dwIndex, StringBuilder lpValueName, ref uint lpcchValueName, IntPtr lpReserved, out REG_VALUE_TYPE lpType, IntPtr lpData, ref uint lpcbData);
public static extern Win32Error RegEnumValue(HKEY hKey, uint dwIndex, StringBuilder lpValueName, ref uint lpcchValueName, IntPtr lpReserved, out REG_VALUE_TYPE lpType, IntPtr lpData, ref uint lpcbData);
/// <summary>
/// <para>Writes all the attributes of the specified open registry key into the registry.</para>
@ -1963,7 +1964,7 @@ namespace Vanara.PInvoke
// https://docs.microsoft.com/en-us/windows/desktop/api/winreg/nf-winreg-regflushkey LSTATUS RegFlushKey( HKEY hKey );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winreg.h", MSDNShortId = "ae1160be-1da7-4621-a0fc-727aa229ec06")]
public static extern Win32Error RegFlushKey(SafeRegistryHandle hKey);
public static extern Win32Error RegFlushKey(HKEY hKey);
/// <summary>
/// <para>
@ -2012,7 +2013,7 @@ namespace Vanara.PInvoke
// SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, LPDWORD lpcbSecurityDescriptor );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winreg.h", MSDNShortId = "26bd8f89-9241-4c13-a214-c2b276d68c92")]
public static extern Win32Error RegGetKeySecurity(SafeRegistryHandle hKey, SECURITY_INFORMATION SecurityInformation, IntPtr pSecurityDescriptor, ref uint lpcbSecurityDescriptor);
public static extern Win32Error RegGetKeySecurity(HKEY hKey, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, ref uint lpcbSecurityDescriptor);
/// <summary>
/// <para>Retrieves the type and data for the specified registry value.</para>
@ -2204,7 +2205,7 @@ namespace Vanara.PInvoke
// lpSubKey, LPCSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "1c06facb-6735-4b3f-b77d-f162e3faaada")]
public static extern Win32Error RegGetValue(SafeRegistryHandle hkey, string lpSubKey, string lpValue, RRF dwFlags, out REG_VALUE_TYPE pdwType, IntPtr pvData, ref uint pcbData);
public static extern Win32Error RegGetValue(HKEY hkey, string lpSubKey, string lpValue, RRF dwFlags, out REG_VALUE_TYPE pdwType, IntPtr pvData, ref uint pcbData);
/// <summary>
/// <para>Loads the specified registry hive as an application hive.</para>
@ -2337,7 +2338,7 @@ namespace Vanara.PInvoke
// LPCSTR lpFile );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "536395aa-03ba-430d-a66d-fcabdc9dfe22")]
public static extern Win32Error RegLoadKey(SafeRegistryHandle hKey, string lpSubKey, string lpFile);
public static extern Win32Error RegLoadKey(HKEY hKey, string lpSubKey, string lpFile);
/// <summary>
/// <para>Loads the specified string from the specified key and subkey.</para>
@ -2416,7 +2417,7 @@ namespace Vanara.PInvoke
// LPCSTR pszValue, LPSTR pszOutBuf, DWORD cbOutBuf, LPDWORD pcbData, DWORD Flags, LPCSTR pszDirectory );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "76ffc77f-a1bc-4e01-858f-4a76563a2bbc")]
public static extern Win32Error RegLoadMUIString(SafeRegistryHandle hKey, string pszValue, StringBuilder pszOutBuf, uint cbOutBuf, IntPtr pcbData, REG_MUI_STRING Flags, string pszDirectory);
public static extern Win32Error RegLoadMUIString(HKEY hKey, string pszValue, StringBuilder pszOutBuf, uint cbOutBuf, IntPtr pcbData, REG_MUI_STRING Flags, string pszDirectory);
/// <summary>Notifies the caller about changes to the attributes or contents of a specified registry key.</summary>
/// <param name="hKey">A handle to an open registry key. This handle is returned by the RegCreateKeyEx or RegOpenKeyEx function.</param>
@ -2443,7 +2444,7 @@ namespace Vanara.PInvoke
/// </returns>
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winreg.h", MSDNShortId = "ms724892")]
public static extern Win32Error RegNotifyChangeKeyValue(SafeRegistryHandle hKey, [MarshalAs(UnmanagedType.Bool)] bool bWatchSubtree, RegNotifyChangeFilter dwFilter, IntPtr hEvent, [MarshalAs(UnmanagedType.Bool)] bool fAsynchronous);
public static extern Win32Error RegNotifyChangeKeyValue(HKEY hKey, [MarshalAs(UnmanagedType.Bool)] bool bWatchSubtree, RegNotifyChangeFilter dwFilter, SafeEventHandle hEvent, [MarshalAs(UnmanagedType.Bool)] bool fAsynchronous);
/// <summary>
/// <para>Retrieves a handle to the <c>HKEY_CURRENT_USER</c> key for the user the current thread is impersonating.</para>
@ -2531,7 +2532,7 @@ namespace Vanara.PInvoke
// PHKEY phkResult );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "bad0a0f8-1889-4eff-98be-084c95d69f3b")]
public static extern Win32Error RegOpenKey(SafeRegistryHandle hKey, string lpSubKey, out SafeRegistryHandle phkResult);
public static extern Win32Error RegOpenKey(HKEY hKey, string lpSubKey, out SafeRegistryHandle phkResult);
/// <summary>Opens the specified registry key. Note that key names are not case sensitive.</summary>
/// <param name="hKey">
@ -2569,7 +2570,7 @@ namespace Vanara.PInvoke
/// </returns>
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "ms724897")]
public static extern Win32Error RegOpenKeyEx(SafeRegistryHandle hKey, string lpSubKey, RegOpenOptions ulOptions, RegAccessTypes samDesired, out SafeRegistryHandle phkResult);
public static extern Win32Error RegOpenKeyEx(HKEY hKey, string lpSubKey, RegOpenOptions ulOptions, RegAccessTypes samDesired, out SafeRegistryHandle phkResult);
/// <summary>
/// <para>Opens the specified registry key and associates it with a transaction. Note that key names are not case sensitive.</para>
@ -2645,7 +2646,7 @@ namespace Vanara.PInvoke
// hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult, HANDLE hTransaction, PVOID pExtendedParemeter );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "11663ed2-d17c-4f08-be7b-9b591271fbcd")]
public static extern Win32Error RegOpenKeyTransacted(SafeRegistryHandle hKey, string lpSubKey, uint ulOptions, REGSAM samDesired, out SafeRegistryHandle phkResult, IntPtr hTransaction, IntPtr pExtendedParemeter);
public static extern Win32Error RegOpenKeyTransacted(HKEY hKey, string lpSubKey, uint ulOptions, REGSAM samDesired, out SafeRegistryHandle phkResult, IntPtr hTransaction, IntPtr pExtendedParemeter);
/// <summary>
/// <para>
@ -2705,7 +2706,7 @@ namespace Vanara.PInvoke
// HANDLE hToken, DWORD dwOptions, REGSAM samDesired, PHKEY phkResult );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winreg.h", MSDNShortId = "bd068826-cf88-4fc7-a7d6-96cc03e923c7")]
public static extern Win32Error RegOpenUserClassesRoot(SafeHTOKEN hToken, uint dwOptions, REGSAM samDesired, out SafeRegistryHandle phkResult);
public static extern Win32Error RegOpenUserClassesRoot(HTOKEN hToken, uint dwOptions, REGSAM samDesired, out SafeRegistryHandle phkResult);
/// <summary>
/// <para>Maps a predefined registry key to the specified registry key.</para>
@ -2753,7 +2754,7 @@ namespace Vanara.PInvoke
// hKey, HKEY hNewHKey );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winreg.h", MSDNShortId = "ad58b7ff-cd61-4719-9028-b470ae7e9bb0")]
public static extern Win32Error RegOverridePredefKey(SafeRegistryHandle hKey, SafeRegistryHandle hNewHKey);
public static extern Win32Error RegOverridePredefKey(HKEY hKey, HKEY hNewHKey);
/// <summary>
/// <para>Retrieves information about the specified registry key.</para>
@ -2839,7 +2840,7 @@ namespace Vanara.PInvoke
// lpcValues, LPDWORD lpcbMaxValueNameLen, LPDWORD lpcbMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "25eb2cd2-9fdd-4d6f-8071-daab56f9aae1")]
public static extern Win32Error RegQueryInfoKey(SafeRegistryHandle hKey, StringBuilder lpClass, ref uint lpcchClass, IntPtr lpReserved, out uint lpcSubKeys, out uint lpcbMaxSubKeyLen, out uint lpcbMaxClassLen, out uint lpcValues, out uint lpcbMaxValueNameLen, out uint lpcbMaxValueLen, out uint lpcbSecurityDescriptor, out FILETIME lpftLastWriteTime);
public static extern Win32Error RegQueryInfoKey(HKEY hKey, StringBuilder lpClass, ref uint lpcchClass, IntPtr lpReserved, out uint lpcSubKeys, out uint lpcbMaxSubKeyLen, out uint lpcbMaxClassLen, out uint lpcValues, out uint lpcbMaxValueNameLen, out uint lpcbMaxValueLen, out uint lpcbSecurityDescriptor, out FILETIME lpftLastWriteTime);
/// <summary>
/// <para>Retrieves the type and data for a list of value names associated with an open registry key.</para>
@ -2927,7 +2928,7 @@ namespace Vanara.PInvoke
// HKEY hKey, PVALENTA val_list, DWORD num_vals, __out_data_source(REGISTRY)LPSTR lpValueBuf, LPDWORD ldwTotsize );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "e718534a-6e68-40f5-9cdd-170ce9b5e6e5")]
public static extern Win32Error RegQueryMultipleValues(SafeRegistryHandle hKey, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] VALENT[] val_list, uint num_vals, IntPtr lpValueBuf, ref uint ldwTotsize);
public static extern Win32Error RegQueryMultipleValues(HKEY hKey, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] VALENT[] val_list, uint num_vals, IntPtr lpValueBuf, ref uint ldwTotsize);
/// <summary>
/// <para>Determines whether reflection has been disabled or enabled for the specified key.</para>
@ -2962,7 +2963,7 @@ namespace Vanara.PInvoke
// hBase, BOOL *bIsReflectionDisabled );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winreg.h", MSDNShortId = "d7516eab-dbcf-4ece-931e-d7bb2a983503")]
public static extern Win32Error RegQueryReflectionKey(SafeRegistryHandle hBase, [MarshalAs(UnmanagedType.Bool)] out bool bIsReflectionDisabled);
public static extern Win32Error RegQueryReflectionKey(HKEY hBase, [MarshalAs(UnmanagedType.Bool)] out bool bIsReflectionDisabled);
/// <summary>
/// <para>
@ -3047,7 +3048,7 @@ namespace Vanara.PInvoke
// lpSubKey, __out_data_source(REGISTRY)LPSTR lpData, PLONG lpcbData );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "18f27717-3bd9-45ac-a1ea-61abc1753a52")]
public static extern Win32Error RegQueryValue(SafeRegistryHandle hKey, string lpSubKey, IntPtr lpData, ref int lpcbData);
public static extern Win32Error RegQueryValue(HKEY hKey, string lpSubKey, IntPtr lpData, ref int lpcbData);
/// <summary>
/// <para>Retrieves the type and data for the specified value name associated with an open registry key.</para>
@ -3171,7 +3172,7 @@ namespace Vanara.PInvoke
// lpValueName, LPDWORD lpReserved, LPDWORD lpType, __out_data_source(REGISTRY)LPBYTE lpData, LPDWORD lpcbData );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "202d253a-10ff-40e7-8eec-a49717443b81")]
public static extern Win32Error RegQueryValueEx(SafeRegistryHandle hKey, string lpValueName, IntPtr lpReserved, out REG_VALUE_TYPE lpType, IntPtr lpData, ref uint lpcbData);
public static extern Win32Error RegQueryValueEx(HKEY hKey, string lpValueName, IntPtr lpReserved, out REG_VALUE_TYPE lpType, IntPtr lpData, ref uint lpcbData);
/// <summary>
/// <para>
@ -3233,7 +3234,7 @@ namespace Vanara.PInvoke
// lpSubKey, LPCSTR lpNewFile, LPCSTR lpOldFile );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "f968fa71-edc8-4f49-b9fa-1e89224df33b")]
public static extern Win32Error RegReplaceKey(SafeRegistryHandle hKey, string lpSubKey, string lpNewFile, string lpOldFile);
public static extern Win32Error RegReplaceKey(HKEY hKey, string lpSubKey, string lpNewFile, string lpOldFile);
/// <summary>
/// <para>
@ -3315,7 +3316,7 @@ namespace Vanara.PInvoke
// lpFile, DWORD dwFlags );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "6267383d-427a-4ae8-b9cc-9c1861d3b7bb")]
public static extern Win32Error RegRestoreKey(SafeRegistryHandle hKey, string lpFile, REG_HIVE dwFlags);
public static extern Win32Error RegRestoreKey(HKEY hKey, string lpFile, REG_HIVE dwFlags);
/// <summary>
/// <para>Saves the specified key and all of its subkeys and values to a new file, in the standard format.</para>
@ -3375,7 +3376,7 @@ namespace Vanara.PInvoke
// CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "da80f40d-0099-4748-94ca-5d3b001e633e")]
public static extern Win32Error RegSaveKey(SafeRegistryHandle hKey, string lpFile, SECURITY_ATTRIBUTES lpSecurityAttributes);
public static extern Win32Error RegSaveKey(HKEY hKey, string lpFile, SECURITY_ATTRIBUTES lpSecurityAttributes);
/// <summary>
/// <para>Saves the specified key and all of its subkeys and values to a registry file, in the specified format.</para>
@ -3467,7 +3468,7 @@ namespace Vanara.PInvoke
// lpFile, CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD Flags );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "f93b4162-cac4-42f7-bfd4-9e23fff80a03")]
public static extern Win32Error RegSaveKeyEx(SafeRegistryHandle hKey, string lpFile, SECURITY_ATTRIBUTES lpSecurityAttributes, REG_SAVE Flags);
public static extern Win32Error RegSaveKeyEx(HKEY hKey, string lpFile, SECURITY_ATTRIBUTES lpSecurityAttributes, REG_SAVE Flags);
/// <summary>
/// <para>The <c>RegSetKeySecurity</c> function sets the security of an open registry key.</para>
@ -3501,7 +3502,7 @@ namespace Vanara.PInvoke
// SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winreg.h", MSDNShortId = "08bf8fc1-6a08-490e-b589-730211774257")]
public static extern Win32Error RegSetKeySecurity(SafeRegistryHandle hKey, SECURITY_INFORMATION SecurityInformation, IntPtr pSecurityDescriptor);
public static extern Win32Error RegSetKeySecurity(HKEY hKey, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor);
/// <summary>
/// <para>Sets the data for the specified value in the specified registry key and subkey.</para>
@ -3559,7 +3560,7 @@ namespace Vanara.PInvoke
// lpSubKey, LPCSTR lpValueName, DWORD dwType, LPCVOID lpData, DWORD cbData );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "e27d2dd6-b139-4ac1-8dd8-527022333364")]
public static extern Win32Error RegSetKeyValue(SafeRegistryHandle hKey, string lpSubKey, string lpValueName, REG_VALUE_TYPE dwType, IntPtr lpData, uint cbData);
public static extern Win32Error RegSetKeyValue(HKEY hKey, string lpSubKey, string lpValueName, REG_VALUE_TYPE dwType, IntPtr lpData, uint cbData);
/// <summary>
/// <para>Sets the data for the default or unnamed value of a specified registry key. The data must be a text string.</para>
@ -3626,7 +3627,7 @@ namespace Vanara.PInvoke
// lpSubKey, DWORD dwType, LPCSTR lpData, DWORD cbData );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "f99774d4-575b-43a3-8887-e15acb0477fd")]
public static extern Win32Error RegSetValue(SafeRegistryHandle hKey, string lpSubKey, REG_VALUE_TYPE dwType, string lpData, uint cbData = 0);
public static extern Win32Error RegSetValue(HKEY hKey, string lpSubKey, REG_VALUE_TYPE dwType, string lpData, uint cbData = 0);
/// <summary>
/// <para>Sets the data and type of a specified value under a registry key.</para>
@ -3714,7 +3715,7 @@ namespace Vanara.PInvoke
// lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "29b0e27c-4999-4e92-bd8b-bba74920bccc")]
public static extern Win32Error RegSetValueEx(SafeRegistryHandle hKey, string lpValueName, uint Reserved, REG_VALUE_TYPE dwType, IntPtr lpData, uint cbData);
public static extern Win32Error RegSetValueEx(HKEY hKey, string lpValueName, uint Reserved, REG_VALUE_TYPE dwType, IntPtr lpData, uint cbData);
/// <summary>
/// <para>Unloads the specified registry key and its subkeys from the registry.</para>
@ -3759,7 +3760,7 @@ namespace Vanara.PInvoke
// lpSubKey );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winreg.h", MSDNShortId = "73b4b6a9-4acb-4247-bd7f-82024ba3e14a")]
public static extern Win32Error RegUnLoadKey(SafeRegistryHandle hKey, string lpSubKey);
public static extern Win32Error RegUnLoadKey(HKEY hKey, string lpSubKey);
/// <summary>Contains information about a registry value. The RegQueryMultipleValues function uses this structure.</summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/winreg/ns-winreg-value_enta typedef struct value_entA { LPSTR ve_valuename;

File diff suppressed because it is too large Load Diff

View File

@ -6,14 +6,6 @@ using System.Security;
using Vanara.Extensions;
using Vanara.InteropServices;
using static Vanara.PInvoke.AdvApi32;
using AUTHZ_ACCESS_CHECK_RESULTS_HANDLE = System.IntPtr;
using AUTHZ_AUDIT_EVENT_HANDLE = System.IntPtr;
using AUTHZ_CLIENT_CONTEXT_HANDLE = System.IntPtr;
using AUTHZ_RESOURCE_MANAGER_HANDLE = System.IntPtr;
// ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
@ -99,24 +91,30 @@ namespace Vanara.PInvoke
public enum AUTHZ_CONTEXT_INFORMATION_CLASS
{
/// <summary>Retrieves a TOKEN_USER structure that contains a user security identifier (SID) and its attribute.</summary>
[CorrespondingType(typeof(TOKEN_USER))]
AuthzContextInfoUserSid = 1,
/// <summary>Retrieves a TOKEN_GROUPS structure that contains the group SIDs to which the user belongs and their attributes.</summary>
[CorrespondingType(typeof(TOKEN_GROUPS))]
AuthzContextInfoGroupsSids,
/// <summary>Retrieves a TOKEN_GROUPS structure that contains the restricted group SIDs in the context and their attributes.</summary>
[CorrespondingType(typeof(TOKEN_GROUPS))]
AuthzContextInfoRestrictedSids,
/// <summary>Retrieves a TOKEN_PRIVILEGES structure that contains the privileges held by the user.</summary>
[CorrespondingType(typeof(PTOKEN_PRIVILEGES))]
AuthzContextInfoPrivileges,
/// <summary>Retrieves the expiration time set on the context.</summary>
[CorrespondingType(typeof(long))]
AuthzContextInfoExpirationTime,
/// <summary>This constant is reserved. Do not use it.</summary>
AuthzContextInfoServerContext,
/// <summary>Retrieves an LUID structures used by the resource manager to identify the context.</summary>
[CorrespondingType(typeof(LUID))]
AuthzContextInfoIdentifier,
/// <summary>This constant is reserved. Do not use it.</summary>
@ -132,6 +130,7 @@ namespace Vanara.PInvoke
/// Retrieves an AUTHZ_SECURITY_ATTRIBUTES_INFORMATION structure that contains security attributes.
/// <para><c>Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:</c> This value is not supported.</para>
/// </summary>
[CorrespondingType(typeof(AUTHZ_SECURITY_ATTRIBUTES_INFORMATION))]
AuthzContextInfoSecurityAttributes,
/// <summary>
@ -141,6 +140,7 @@ namespace Vanara.PInvoke
/// is not supported.
/// </para>
/// </summary>
[CorrespondingType(typeof(TOKEN_GROUPS))]
AuthzContextInfoDeviceSids,
/// <summary>
@ -150,6 +150,7 @@ namespace Vanara.PInvoke
/// is not supported.
/// </para>
/// </summary>
[CorrespondingType(typeof(AUTHZ_SECURITY_ATTRIBUTES_INFORMATION))]
AuthzContextInfoUserClaims,
/// <summary>
@ -159,6 +160,7 @@ namespace Vanara.PInvoke
/// is not supported.
/// </para>
/// </summary>
[CorrespondingType(typeof(AUTHZ_SECURITY_ATTRIBUTES_INFORMATION))]
AuthzContextInfoDeviceClaims,
/// <summary>
@ -168,6 +170,7 @@ namespace Vanara.PInvoke
/// is not supported.
/// </para>
/// </summary>
[CorrespondingType(typeof(TOKEN_APPCONTAINER_INFORMATION))]
AuthzContextInfoAppContainerSid,
/// <summary>
@ -177,6 +180,7 @@ namespace Vanara.PInvoke
/// is not supported.
/// </para>
/// </summary>
[CorrespondingType(typeof(TOKEN_GROUPS))]
AuthzContextInfoCapabilitySids,
}
@ -549,8 +553,8 @@ namespace Vanara.PInvoke
[DllImport(Lib.Authz, SetLastError = true, ExactSpelling = true)]
[PInvokeData("authz.h", MSDNShortId = "633c2a73-169c-4e0c-abb6-96c360bd63cf")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AuthzAccessCheck(AuthzAccessCheckFlags Flags, SafeAUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext, ref AUTHZ_ACCESS_REQUEST pRequest,
[Optional] SafeAUTHZ_AUDIT_EVENT_HANDLE hAuditEvent, SafeSecurityDescriptor pSecurityDescriptor,
public static extern bool AuthzAccessCheck(AuthzAccessCheckFlags Flags, AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext, in AUTHZ_ACCESS_REQUEST pRequest,
[Optional] AUTHZ_AUDIT_EVENT_HANDLE hAuditEvent, PSECURITY_DESCRIPTOR pSecurityDescriptor,
[Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 6)] SECURITY_DESCRIPTOR[] OptionalSecurityDescriptorArray,
uint OptionalSecurityDescriptorCount, [In, Out] AUTHZ_ACCESS_REPLY pReply, out SafeAUTHZ_ACCESS_CHECK_RESULTS_HANDLE phAccessCheckResults);
@ -673,8 +677,8 @@ namespace Vanara.PInvoke
[DllImport(Lib.Authz, SetLastError = true, ExactSpelling = true)]
[PInvokeData("authz.h", MSDNShortId = "633c2a73-169c-4e0c-abb6-96c360bd63cf")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AuthzAccessCheck(AuthzAccessCheckFlags Flags, SafeAUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext, ref AUTHZ_ACCESS_REQUEST pRequest,
[Optional] SafeAUTHZ_AUDIT_EVENT_HANDLE hAuditEvent, SafeSecurityDescriptor pSecurityDescriptor,
public static extern bool AuthzAccessCheck(AuthzAccessCheckFlags Flags, AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext, in AUTHZ_ACCESS_REQUEST pRequest,
[Optional] AUTHZ_AUDIT_EVENT_HANDLE hAuditEvent, PSECURITY_DESCRIPTOR pSecurityDescriptor,
[Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 6)] SECURITY_DESCRIPTOR[] OptionalSecurityDescriptorArray,
uint OptionalSecurityDescriptorCount, [In, Out] AUTHZ_ACCESS_REPLY pReply, [Optional] IntPtr phAccessCheckResults);
@ -787,7 +791,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.Authz, SetLastError = true, ExactSpelling = true)]
[PInvokeData("authz.h", MSDNShortId = "c365029a-3ff3-49c1-9dfc-b52948e466f3")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AuthzGetInformationFromContext(SafeAUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext,
public static extern bool AuthzGetInformationFromContext(AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext,
AUTHZ_CONTEXT_INFORMATION_CLASS InfoClass, uint BufferSize, out uint pSizeRequired, IntPtr Buffer);
/// <summary>
@ -814,7 +818,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.Authz, SetLastError = true, ExactSpelling = true)]
[PInvokeData("authz.h", MSDNShortId = "2EC9EE76-9A92-40DF-9884-547D96FF3E09")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AuthzInitializeCompoundContext(SafeAUTHZ_CLIENT_CONTEXT_HANDLE UserContext, SafeAUTHZ_CLIENT_CONTEXT_HANDLE DeviceContext, out SafeAUTHZ_CLIENT_CONTEXT_HANDLE phCompoundContext);
public static extern bool AuthzInitializeCompoundContext(AUTHZ_CLIENT_CONTEXT_HANDLE UserContext, AUTHZ_CLIENT_CONTEXT_HANDLE DeviceContext, out SafeAUTHZ_CLIENT_CONTEXT_HANDLE phCompoundContext);
/// <summary>
/// <para>
@ -944,7 +948,7 @@ namespace Vanara.PInvoke
public static extern bool AuthzInitializeContextFromSid(
AuthzContextFlags Flags,
PSID UserSid,
[Optional] SafeAUTHZ_RESOURCE_MANAGER_HANDLE hAuthzResourceManager,
[Optional] AUTHZ_RESOURCE_MANAGER_HANDLE hAuthzResourceManager,
[Optional] IntPtr pExpirationTime,
LUID Identifier,
[Optional] IntPtr DynamicGroupArgs,
@ -998,7 +1002,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.Authz, SetLastError = true, ExactSpelling = true)]
[PInvokeData("authz.h", MSDNShortId = "75a7fb3f-6b3a-42ca-b467-f57baf6c60c6")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AuthzInitializeContextFromToken(uint Flags, SafeHTOKEN TokenHandle, SafeAUTHZ_RESOURCE_MANAGER_HANDLE hAuthzResourceManager,
public static extern bool AuthzInitializeContextFromToken(uint Flags, HTOKEN TokenHandle, AUTHZ_RESOURCE_MANAGER_HANDLE hAuthzResourceManager,
[Optional] IntPtr pExpirationTime, LUID Identifier, [Optional] IntPtr DynamicGroupArgs, out SafeAUTHZ_CLIENT_CONTEXT_HANDLE phAuthzClientContext);
/// <summary>
@ -1057,13 +1061,12 @@ namespace Vanara.PInvoke
// AuthzInitializeObjectAccessAuditEvent( DWORD Flags, AUTHZ_AUDIT_EVENT_TYPE_HANDLE hAuditEventType, PWSTR szOperationType, PWSTR
// szObjectType, PWSTR szObjectName, PWSTR szAdditionalInfo, PAUTHZ_AUDIT_EVENT_HANDLE phAuditEvent, DWORD
// dwAdditionalParameterCount, ... );
[DllImport(Lib.Authz, SetLastError = true, ExactSpelling = true)]
[DllImport(Lib.Authz, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("authz.h", MSDNShortId = "cf79a92f-31e0-47cf-8990-4dbd46056a90")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AuthzInitializeObjectAccessAuditEvent(AuthzAuditEventFlags Flags, IntPtr hAuditEventType,
[MarshalAs(UnmanagedType.LPWStr)] string szOperationType, [MarshalAs(UnmanagedType.LPWStr)] string szObjectType,
[MarshalAs(UnmanagedType.LPWStr)] string szObjectName, [MarshalAs(UnmanagedType.LPWStr)] string szAdditionalInfo,
out SafeAUTHZ_AUDIT_EVENT_HANDLE phAuditEvent, uint dwAdditionalParameterCount);
string szOperationType, string szObjectType, string szObjectName, string szAdditionalInfo,
out SafeAUTHZ_AUDIT_EVENT_HANDLE phAuditEvent, uint dwAdditionalParameterCount = 0);
/// <summary>The AuthzInitializeResourceManager function uses Authz to verify that clients have access to various resources.</summary>
/// <param name="flags">
@ -1143,7 +1146,7 @@ namespace Vanara.PInvoke
[PInvokeData("authz.h", MSDNShortId = "A93CD1DD-4E87-4C6A-928A-F90AD7F1085E")]
[DllImport(Lib.Authz, ExactSpelling = true, SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AuthzModifyClaims(SafeAUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext, AUTHZ_CONTEXT_INFORMATION_CLASS ClaimClass,
public static extern bool AuthzModifyClaims(AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext, AUTHZ_CONTEXT_INFORMATION_CLASS ClaimClass,
AUTHZ_SECURITY_ATTRIBUTE_OPERATION[] pClaimOperations,
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(AUTHZ_SECURITY_ATTRIBUTES_INFORMATION_Marshaler))] AUTHZ_SECURITY_ATTRIBUTES_INFORMATION pClaims);
@ -1177,7 +1180,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.Authz, ExactSpelling = true, SetLastError = true, CharSet = CharSet.Unicode)]
[PInvokeData("authz.h", MSDNShortId = "d84873e2-ecfe-45cf-9048-7ed173117efa")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AuthzModifySecurityAttributes(SafeAUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext,
public static extern bool AuthzModifySecurityAttributes(AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext,
AUTHZ_SECURITY_ATTRIBUTE_OPERATION[] pOperations,
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(AUTHZ_SECURITY_ATTRIBUTES_INFORMATION_Marshaler))] AUTHZ_SECURITY_ATTRIBUTES_INFORMATION pAttributes);
@ -1218,9 +1221,59 @@ namespace Vanara.PInvoke
[DllImport(Lib.Authz, ExactSpelling = true, SetLastError = true, CharSet = CharSet.Unicode)]
[PInvokeData("authz.h", MSDNShortId = "740569A5-6159-409B-B8CB-B3A8BAE4F398")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AuthzModifySids(SafeAUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext, AUTHZ_CONTEXT_INFORMATION_CLASS SidClass,
public static extern bool AuthzModifySids(AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext, AUTHZ_CONTEXT_INFORMATION_CLASS SidClass,
AUTHZ_SID_OPERATION[] pSidOperations, in TOKEN_GROUPS pSids);
/// <summary>Provides a handle to an access check results.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct AUTHZ_ACCESS_CHECK_RESULTS_HANDLE : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="AUTHZ_ACCESS_CHECK_RESULTS_HANDLE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public AUTHZ_ACCESS_CHECK_RESULTS_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>
/// Returns an invalid handle by instantiating a <see cref="AUTHZ_ACCESS_CHECK_RESULTS_HANDLE"/> object with <see cref="IntPtr.Zero"/>.
/// </summary>
public static AUTHZ_ACCESS_CHECK_RESULTS_HANDLE NULL => new AUTHZ_ACCESS_CHECK_RESULTS_HANDLE(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="AUTHZ_ACCESS_CHECK_RESULTS_HANDLE"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(AUTHZ_ACCESS_CHECK_RESULTS_HANDLE h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="AUTHZ_ACCESS_CHECK_RESULTS_HANDLE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator AUTHZ_ACCESS_CHECK_RESULTS_HANDLE(IntPtr h) => new AUTHZ_ACCESS_CHECK_RESULTS_HANDLE(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(AUTHZ_ACCESS_CHECK_RESULTS_HANDLE h1, AUTHZ_ACCESS_CHECK_RESULTS_HANDLE h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(AUTHZ_ACCESS_CHECK_RESULTS_HANDLE h1, AUTHZ_ACCESS_CHECK_RESULTS_HANDLE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is AUTHZ_ACCESS_CHECK_RESULTS_HANDLE h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>
/// <para>The <c>AUTHZ_ACCESS_REQUEST</c> structure defines an access check request.</para>
/// </summary>
@ -1254,13 +1307,157 @@ namespace Vanara.PInvoke
/// <summary>Initializes a new instance of the <see cref="AUTHZ_ACCESS_REQUEST"/> struct.</summary>
/// <param name="access">The access.</param>
public AUTHZ_ACCESS_REQUEST(uint access) : this() { DesiredAccess = access; }
public AUTHZ_ACCESS_REQUEST(uint access) : this() => DesiredAccess = access;
/// <summary>Gets or sets the object types.</summary>
/// <value>The object types.</value>
public OBJECT_TYPE_LIST[] ObjectTypes => ObjectTypeList.ToIEnum<IntPtr>((int)ObjectTypeListLength).Select(p => p.ToStructure<OBJECT_TYPE_LIST>()).ToArray();
}
/// <summary>Provides a handle to an Audit event.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct AUTHZ_AUDIT_EVENT_HANDLE : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="AUTHZ_AUDIT_EVENT_HANDLE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public AUTHZ_AUDIT_EVENT_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="AUTHZ_AUDIT_EVENT_HANDLE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static AUTHZ_AUDIT_EVENT_HANDLE NULL => new AUTHZ_AUDIT_EVENT_HANDLE(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="AUTHZ_AUDIT_EVENT_HANDLE"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(AUTHZ_AUDIT_EVENT_HANDLE h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="AUTHZ_AUDIT_EVENT_HANDLE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator AUTHZ_AUDIT_EVENT_HANDLE(IntPtr h) => new AUTHZ_AUDIT_EVENT_HANDLE(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(AUTHZ_AUDIT_EVENT_HANDLE h1, AUTHZ_AUDIT_EVENT_HANDLE h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(AUTHZ_AUDIT_EVENT_HANDLE h1, AUTHZ_AUDIT_EVENT_HANDLE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is AUTHZ_AUDIT_EVENT_HANDLE h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a handle to a client context.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct AUTHZ_CLIENT_CONTEXT_HANDLE : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="AUTHZ_CLIENT_CONTEXT_HANDLE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public AUTHZ_CLIENT_CONTEXT_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="AUTHZ_CLIENT_CONTEXT_HANDLE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static AUTHZ_CLIENT_CONTEXT_HANDLE NULL => new AUTHZ_CLIENT_CONTEXT_HANDLE(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="AUTHZ_CLIENT_CONTEXT_HANDLE"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(AUTHZ_CLIENT_CONTEXT_HANDLE h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="AUTHZ_CLIENT_CONTEXT_HANDLE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator AUTHZ_CLIENT_CONTEXT_HANDLE(IntPtr h) => new AUTHZ_CLIENT_CONTEXT_HANDLE(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(AUTHZ_CLIENT_CONTEXT_HANDLE h1, AUTHZ_CLIENT_CONTEXT_HANDLE h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(AUTHZ_CLIENT_CONTEXT_HANDLE h1, AUTHZ_CLIENT_CONTEXT_HANDLE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is AUTHZ_CLIENT_CONTEXT_HANDLE h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a handle to a resource manager.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct AUTHZ_RESOURCE_MANAGER_HANDLE : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="AUTHZ_RESOURCE_MANAGER_HANDLE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public AUTHZ_RESOURCE_MANAGER_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="AUTHZ_RESOURCE_MANAGER_HANDLE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static AUTHZ_RESOURCE_MANAGER_HANDLE NULL => new AUTHZ_RESOURCE_MANAGER_HANDLE(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="AUTHZ_RESOURCE_MANAGER_HANDLE"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(AUTHZ_RESOURCE_MANAGER_HANDLE h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="AUTHZ_RESOURCE_MANAGER_HANDLE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator AUTHZ_RESOURCE_MANAGER_HANDLE(IntPtr h) => new AUTHZ_RESOURCE_MANAGER_HANDLE(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(AUTHZ_RESOURCE_MANAGER_HANDLE h1, AUTHZ_RESOURCE_MANAGER_HANDLE h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(AUTHZ_RESOURCE_MANAGER_HANDLE h1, AUTHZ_RESOURCE_MANAGER_HANDLE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is AUTHZ_RESOURCE_MANAGER_HANDLE h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>
/// <para>
/// The <c>AUTHZ_SECURITY_ATTRIBUTE_FQBN_VALUE</c> structure specifies a fully qualified binary name value associated with a security attribute.
@ -1331,50 +1528,32 @@ namespace Vanara.PInvoke
/// <summary>Initializes a new instance of the <see cref="AUTHZ_SECURITY_ATTRIBUTE_V1"/> struct.</summary>
/// <param name="name">The name.</param>
/// <param name="values">The value.</param>
public AUTHZ_SECURITY_ATTRIBUTE_V1(string name, params long[] values) : this(name, AUTHZ_SECURITY_ATTRIBUTE_DATATYPE.AUTHZ_SECURITY_ATTRIBUTE_TYPE_INT64, values.Length)
{
Values.pInt64 = values;
}
public AUTHZ_SECURITY_ATTRIBUTE_V1(string name, params long[] values) : this(name, AUTHZ_SECURITY_ATTRIBUTE_DATATYPE.AUTHZ_SECURITY_ATTRIBUTE_TYPE_INT64, values.Length) => Values.pInt64 = values;
/// <summary>Initializes a new instance of the <see cref="AUTHZ_SECURITY_ATTRIBUTE_V1"/> struct.</summary>
/// <param name="name">The name.</param>
/// <param name="values">The value.</param>
public AUTHZ_SECURITY_ATTRIBUTE_V1(string name, params ulong[] values) : this(name, AUTHZ_SECURITY_ATTRIBUTE_DATATYPE.AUTHZ_SECURITY_ATTRIBUTE_TYPE_UINT64, values.Length)
{
Values.pUInt64 = values;
}
public AUTHZ_SECURITY_ATTRIBUTE_V1(string name, params ulong[] values) : this(name, AUTHZ_SECURITY_ATTRIBUTE_DATATYPE.AUTHZ_SECURITY_ATTRIBUTE_TYPE_UINT64, values.Length) => Values.pUInt64 = values;
/// <summary>Initializes a new instance of the <see cref="AUTHZ_SECURITY_ATTRIBUTE_V1"/> struct.</summary>
/// <param name="name">The name.</param>
/// <param name="values">The value.</param>
public AUTHZ_SECURITY_ATTRIBUTE_V1(string name, params bool[] values) : this(name, AUTHZ_SECURITY_ATTRIBUTE_DATATYPE.AUTHZ_SECURITY_ATTRIBUTE_TYPE_BOOLEAN, values.Length)
{
Values.pInt64 = Array.ConvertAll(values, Convert.ToInt64);
}
public AUTHZ_SECURITY_ATTRIBUTE_V1(string name, params bool[] values) : this(name, AUTHZ_SECURITY_ATTRIBUTE_DATATYPE.AUTHZ_SECURITY_ATTRIBUTE_TYPE_BOOLEAN, values.Length) => Values.pInt64 = Array.ConvertAll(values, Convert.ToInt64);
/// <summary>Initializes a new instance of the <see cref="AUTHZ_SECURITY_ATTRIBUTE_V1"/> struct.</summary>
/// <param name="name">The name.</param>
/// <param name="values">The value.</param>
public AUTHZ_SECURITY_ATTRIBUTE_V1(string name, params string[] values) : this(name, AUTHZ_SECURITY_ATTRIBUTE_DATATYPE.AUTHZ_SECURITY_ATTRIBUTE_TYPE_STRING, values.Length)
{
Values.ppString = values;
}
public AUTHZ_SECURITY_ATTRIBUTE_V1(string name, params string[] values) : this(name, AUTHZ_SECURITY_ATTRIBUTE_DATATYPE.AUTHZ_SECURITY_ATTRIBUTE_TYPE_STRING, values.Length) => Values.ppString = values;
/// <summary>Initializes a new instance of the <see cref="AUTHZ_SECURITY_ATTRIBUTE_V1"/> struct.</summary>
/// <param name="name">The name.</param>
/// <param name="values">The value.</param>
public AUTHZ_SECURITY_ATTRIBUTE_V1(string name, params AUTHZ_SECURITY_ATTRIBUTE_FQBN_VALUE[] values) : this(name, AUTHZ_SECURITY_ATTRIBUTE_DATATYPE.AUTHZ_SECURITY_ATTRIBUTE_TYPE_FQBN, values.Length)
{
Values.pFqbn = values;
}
public AUTHZ_SECURITY_ATTRIBUTE_V1(string name, params AUTHZ_SECURITY_ATTRIBUTE_FQBN_VALUE[] values) : this(name, AUTHZ_SECURITY_ATTRIBUTE_DATATYPE.AUTHZ_SECURITY_ATTRIBUTE_TYPE_FQBN, values.Length) => Values.pFqbn = values;
/// <summary>Initializes a new instance of the <see cref="AUTHZ_SECURITY_ATTRIBUTE_V1"/> struct.</summary>
/// <param name="name">The name.</param>
/// <param name="values">The value.</param>
public AUTHZ_SECURITY_ATTRIBUTE_V1(string name, params AUTHZ_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE[] values) : this(name, AUTHZ_SECURITY_ATTRIBUTE_DATATYPE.AUTHZ_SECURITY_ATTRIBUTE_TYPE_OCTET_STRING, values.Length)
{
Values.pOctetString = values;
}
public AUTHZ_SECURITY_ATTRIBUTE_V1(string name, params AUTHZ_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE[] values) : this(name, AUTHZ_SECURITY_ATTRIBUTE_DATATYPE.AUTHZ_SECURITY_ATTRIBUTE_TYPE_OCTET_STRING, values.Length) => Values.pOctetString = values;
private AUTHZ_SECURITY_ATTRIBUTE_V1(string name, AUTHZ_SECURITY_ATTRIBUTE_DATATYPE type, int count) : this()
{
@ -1472,7 +1651,7 @@ namespace Vanara.PInvoke
{
var ms = new MemoryStream();
var bw = new BinaryWriter(ms);
foreach (T item in items)
foreach (var item in items)
bw.Write(item);
Marshal.Copy(ms.ToArray(), 0, ptr, (int)ms.Length);
}
@ -1570,62 +1749,105 @@ namespace Vanara.PInvoke
public static AUTHZ_SECURITY_ATTRIBUTES_INFORMATION FromPtr(IntPtr ptr) => (AUTHZ_SECURITY_ATTRIBUTES_INFORMATION)AUTHZ_SECURITY_ATTRIBUTES_INFORMATION_Marshaler.GetInstance(null).MarshalNativeToManaged(ptr);
}
/// <summary>A safe handle for AUTHZ_ACCESS_CHECK_RESULTS_HANDLE.</summary>
/// <seealso cref="GenericSafeHandle"/>
public class SafeAUTHZ_ACCESS_CHECK_RESULTS_HANDLE : GenericSafeHandle
/// <summary>
/// Provides a <see cref="SafeHandle"/> to a check results value that releases a created AUTHZ_ACCESS_CHECK_RESULTS_HANDLE instance
/// at disposal using AuthzFreeHandle.
/// </summary>
public class SafeAUTHZ_ACCESS_CHECK_RESULTS_HANDLE : HANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafeAUTHZ_ACCESS_CHECK_RESULTS_HANDLE"/> class.</summary>
public SafeAUTHZ_ACCESS_CHECK_RESULTS_HANDLE() : base(AuthzFreeHandle) { }
/// <summary>
/// Initializes a new instance of the <see cref="AUTHZ_ACCESS_CHECK_RESULTS_HANDLE"/> class and assigns an existing handle.
/// </summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeAUTHZ_ACCESS_CHECK_RESULTS_HANDLE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeAUTHZ_ACCESS_CHECK_RESULTS_HANDLE"/> class.</summary>
/// <param name="ptr">An existing handle.</param>
/// <param name="own">if set to <c>true</c> free handle when disposed.</param>
public SafeAUTHZ_ACCESS_CHECK_RESULTS_HANDLE(AUTHZ_ACCESS_CHECK_RESULTS_HANDLE ptr, bool own = true) : base(ptr, AuthzFreeHandle, own) { }
/// <summary>Initializes a new instance of the <see cref="AUTHZ_ACCESS_CHECK_RESULTS_HANDLE"/> class.</summary>
private SafeAUTHZ_ACCESS_CHECK_RESULTS_HANDLE() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeAUTHZ_ACCESS_CHECK_RESULTS_HANDLE"/> to <see cref="AUTHZ_ACCESS_CHECK_RESULTS_HANDLE"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator AUTHZ_ACCESS_CHECK_RESULTS_HANDLE(SafeAUTHZ_ACCESS_CHECK_RESULTS_HANDLE h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => AuthzFreeHandle(this);
}
/// <summary>A safe handle for AUTHZ_AUDIT_EVENT_HANDLE.</summary>
/// <seealso cref="GenericSafeHandle"/>
public class SafeAUTHZ_AUDIT_EVENT_HANDLE : GenericSafeHandle
/// <summary>
/// Provides a <see cref="SafeHandle"/> to an audit event that releases a created AUTHZ_AUDIT_EVENT_HANDLE instance at disposal using AuthzFreeAuditEvent.
/// </summary>
public class SafeAUTHZ_AUDIT_EVENT_HANDLE : HANDLE
{
/// <summary>A <c>null</c> value equivalent.</summary>
public static readonly SafeAUTHZ_AUDIT_EVENT_HANDLE Null = new SafeAUTHZ_AUDIT_EVENT_HANDLE();
/// <summary>Initializes a new instance of the <see cref="AUTHZ_AUDIT_EVENT_HANDLE"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeAUTHZ_AUDIT_EVENT_HANDLE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeAUTHZ_AUDIT_EVENT_HANDLE"/> class.</summary>
public SafeAUTHZ_AUDIT_EVENT_HANDLE() : base(AuthzFreeContext) { }
/// <summary>Initializes a new instance of the <see cref="AUTHZ_AUDIT_EVENT_HANDLE"/> class.</summary>
private SafeAUTHZ_AUDIT_EVENT_HANDLE() : base() { }
/// <summary>Initializes a new instance of the <see cref="SafeAUTHZ_AUDIT_EVENT_HANDLE"/> class.</summary>
/// <param name="ptr">An existing handle.</param>
/// <param name="own">if set to <c>true</c> free handle when disposed.</param>
public SafeAUTHZ_AUDIT_EVENT_HANDLE(AUTHZ_AUDIT_EVENT_HANDLE ptr, bool own = true) : base(ptr, AuthzFreeAuditEvent, own) { }
/// <summary>Performs an implicit conversion from <see cref="SafeAUTHZ_AUDIT_EVENT_HANDLE"/> to <see cref="AUTHZ_AUDIT_EVENT_HANDLE"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator AUTHZ_AUDIT_EVENT_HANDLE(SafeAUTHZ_AUDIT_EVENT_HANDLE h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => AuthzFreeAuditEvent(this);
}
/// <summary>A safe handle for AUTHZ_CLIENT_CONTEXT_HANDLE.</summary>
/// <seealso cref="GenericSafeHandle"/>
public class SafeAUTHZ_CLIENT_CONTEXT_HANDLE : GenericSafeHandle
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="AUTHZ_CLIENT_CONTEXT_HANDLE"/> that is disposed using <see cref="AuthzFreeContext"/>.</summary>
public class SafeAUTHZ_CLIENT_CONTEXT_HANDLE : HANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafeAUTHZ_CLIENT_CONTEXT_HANDLE"/> class.</summary>
public SafeAUTHZ_CLIENT_CONTEXT_HANDLE() : base(AuthzFreeContext) { }
/// <summary>
/// Initializes a new instance of the <see cref="SafeAUTHZ_CLIENT_CONTEXT_HANDLE"/> class and assigns an existing handle.
/// </summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeAUTHZ_CLIENT_CONTEXT_HANDLE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeAUTHZ_CLIENT_CONTEXT_HANDLE"/> class.</summary>
/// <param name="ptr">An existing handle.</param>
/// <param name="own">if set to <c>true</c> free handle when disposed.</param>
public SafeAUTHZ_CLIENT_CONTEXT_HANDLE(AUTHZ_CLIENT_CONTEXT_HANDLE ptr, bool own = true) : base(ptr, AuthzFreeContext, own) { }
private SafeAUTHZ_CLIENT_CONTEXT_HANDLE() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeAUTHZ_CLIENT_CONTEXT_HANDLE"/> to <see cref="AUTHZ_CLIENT_CONTEXT_HANDLE"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator AUTHZ_CLIENT_CONTEXT_HANDLE(SafeAUTHZ_CLIENT_CONTEXT_HANDLE h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => AuthzFreeContext(this);
}
/// <summary>A safe handle for AUTHZ_RESOURCE_MANAGER_HANDLE.</summary>
/// <seealso cref="GenericSafeHandle"/>
public class SafeAUTHZ_RESOURCE_MANAGER_HANDLE : GenericSafeHandle
/// <summary>
/// Provides a <see cref="SafeHandle"/> for <see cref="AUTHZ_RESOURCE_MANAGER_HANDLE"/> that is disposed using <see cref="AuthzFreeResourceManager"/>.
/// </summary>
public class SafeAUTHZ_RESOURCE_MANAGER_HANDLE : HANDLE
{
/// <summary>A <c>null</c> value equivalent.</summary>
public static readonly SafeAUTHZ_RESOURCE_MANAGER_HANDLE Null = new SafeAUTHZ_RESOURCE_MANAGER_HANDLE();
/// <summary>
/// Initializes a new instance of the <see cref="SafeAUTHZ_RESOURCE_MANAGER_HANDLE"/> class and assigns an existing handle.
/// </summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeAUTHZ_RESOURCE_MANAGER_HANDLE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeAUTHZ_RESOURCE_MANAGER_HANDLE"/> class.</summary>
public SafeAUTHZ_RESOURCE_MANAGER_HANDLE() : base(AuthzFreeResourceManager) { }
private SafeAUTHZ_RESOURCE_MANAGER_HANDLE() : base() { }
/// <summary>Initializes a new instance of the <see cref="SafeAUTHZ_RESOURCE_MANAGER_HANDLE"/> class.</summary>
/// <param name="ptr">An existing handle.</param>
/// <param name="own">if set to <c>true</c> free handle when disposed.</param>
public SafeAUTHZ_RESOURCE_MANAGER_HANDLE(AUTHZ_RESOURCE_MANAGER_HANDLE ptr, bool own = true) : base(ptr, AuthzFreeResourceManager, own) { }
/// <summary>Performs an implicit conversion from <see cref="SafeAUTHZ_RESOURCE_MANAGER_HANDLE"/> to <see cref="AUTHZ_RESOURCE_MANAGER_HANDLE"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator AUTHZ_RESOURCE_MANAGER_HANDLE(SafeAUTHZ_RESOURCE_MANAGER_HANDLE h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => AuthzFreeResourceManager(this);
}
internal class AUTHZ_SECURITY_ATTRIBUTES_INFORMATION_Marshaler : ICustomMarshaler
@ -1636,10 +1858,7 @@ namespace Vanara.PInvoke
{
}
public void CleanUpNativeData(IntPtr pNativeData)
{
Marshal.FreeHGlobal(pNativeData);
}
public void CleanUpNativeData(IntPtr pNativeData) => Marshal.FreeHGlobal(pNativeData);
public int GetNativeDataSize() => -1;

View File

@ -1,32 +0,0 @@
#if (NET20 || NET35)
namespace Microsoft.Win32.SafeHandles
{
using System;
using System.Security;
using Vanara.InteropServices;
/// <summary>
/// Represents a safe handle to the Windows registry.
/// </summary>
[SecurityCritical]
public sealed class SafeRegistryHandle : GenericSafeHandle
{
/// <summary>
/// Initializes a new instance of the <see cref="SafeRegistryHandle"/> class.
/// </summary>
[SecurityCritical]
internal SafeRegistryHandle() : this(IntPtr.Zero) { }
/// <summary>
/// Initializes a new instance of the <see cref="SafeRegistryHandle"/> class.
/// </summary>
/// <param name="preexistingHandle">An object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle"><c>true</c> to reliably release the handle during the finalization phase; <c>false</c> to prevent reliable release.</param>
[SecurityCritical]
public SafeRegistryHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, h => Vanara.PInvoke.AdvApi32.RegCloseKey(h) == 0, ownsHandle)
{
SetHandle(preexistingHandle);
}
}
}
#endif

View File

@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using Vanara.Extensions;
using Vanara.InteropServices;
using static Vanara.PInvoke.AdvApi32;
namespace Vanara.PInvoke
@ -11,16 +7,60 @@ namespace Vanara.PInvoke
/// <summary>Functions, enumerations and structures found in Secur32.dll.</summary>
public static partial class Secur32
{
/// <summary>The MSV1_0 authentication package name.</summary>
[PInvokeData("Ntsecapi.h")]
public const string MSV1_0_PACKAGE_NAME = "MICROSOFT_AUTHENTICATION_PACKAGE_V1_0";
/// <summary>The Kerberos authentication package name.</summary>
[PInvokeData("Ntsecapi.h")]
public const string MICROSOFT_KERBEROS_NAME = "Kerberos";
/// <summary>The MSV1_0 authentication package name.</summary>
[PInvokeData("Ntsecapi.h")]
public const string MSV1_0_PACKAGE_NAME = "MICROSOFT_AUTHENTICATION_PACKAGE_V1_0";
/// <summary>The Negotiate authentication package name.</summary>
[PInvokeData("Security.h")]
public const string NEGOSSP_NAME = "Negotiate";
/// <summary>
/// <para>The <c>LsaConnectUntrusted</c> function establishes an untrusted connection to the LSA server.</para>
/// </summary>
/// <param name="LsaHandle">
/// <para>Pointer to a handle that receives the connection handle, which must be provided in future authentication services.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is STATUS_SUCCESS.</para>
/// <para>If the function fails, the return value is an NTSTATUS code. For more information, see LSA Policy Function Return Values.</para>
/// <para>The LsaNtStatusToWinError function converts an NTSTATUS code to a Windows error code.</para>
/// </returns>
/// <remarks>
/// <para>
/// <c>LsaConnectUntrusted</c> returns a handle to an untrusted connection; it does not verify any information about the caller. The
/// handle should be closed using the LsaDeregisterLogonProcess function.
/// </para>
/// <para>
/// If your application simply needs to query information from authentication packages, you can use the handle returned by this
/// function in calls to LsaCallAuthenticationPackage and LsaLookupAuthenticationPackage.
/// </para>
/// <para>Applications with the SeTcbPrivilege privilege may create a trusted connection by calling LsaRegisterLogonProcess.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaconnectuntrusted NTSTATUS LsaConnectUntrusted(
// PHANDLE LsaHandle );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "b54917c8-51cd-4891-9613-f37a4a46448b")]
// public static extern NTStatus LsaConnectUntrusted(ref IntPtr LsaHandle);
public static extern NTStatus LsaConnectUntrusted(out SafeLsaConnectionHandle LsaHandle);
/// <summary>
/// The LsaDeregisterLogonProcess function deletes the caller's logon application context and closes the connection to the LSA server.
/// </summary>
/// <param name="LsaHandle">Handle obtained from a LsaRegisterLogonProcess or LsaConnectUntrusted call.</param>
/// <returns>
/// If the function succeeds, the return value is STATUS_SUCCESS.
/// <para>If the function fails, the return value is an NTSTATUS code. For more information, see LSA Policy Function Return Values.</para>
/// <para>The LsaNtStatusToWinError function converts an NTSTATUS code to a Windows error code.</para>
/// </returns>
[DllImport(Lib.Secur32, ExactSpelling = true)]
[PInvokeData("Ntsecapi.h", MSDNShortId = "aa378269")]
public static extern NTStatus LsaDeregisterLogonProcess(LsaConnectionHandle LsaHandle);
/// <summary>The LsaLookupAuthenticationPackage function obtains the unique identifier of an authentication package.</summary>
/// <param name="LsaHandle">Handle obtained from a previous call to LsaRegisterLogonProcess or LsaConnectUntrusted.</param>
/// <param name="PackageName">A string that specifies the name of the authentication package. The package name must not exceed 127 bytes in length. The following table lists the names of the Microsoft-provided authentication packages.
@ -41,50 +81,150 @@ namespace Vanara.PInvoke
/// </list></returns>
[DllImport(Lib.Secur32, ExactSpelling = true)]
[PInvokeData("Ntsecapi.h", MSDNShortId = "aa378297")]
public static extern uint LsaLookupAuthenticationPackage(SafeLsaConnectionHandle LsaHandle, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaStringMarshaler))] string PackageName, out int AuthenticationPackage);
/// <summary>The LsaConnectUntrusted function establishes an untrusted connection to the LSA server.</summary>
/// <param name="LsaHandle">Pointer to a handle that receives the connection handle, which must be provided in future authentication services.</param>
/// <returns>If the function succeeds, the return value is STATUS_SUCCESS.
/// <para>If the function fails, the return value is an NTSTATUS code. For more information, see LSA Policy Function Return Values.</para>
/// <para>The LsaNtStatusToWinError function converts an NTSTATUS code to a Windows error code.</para></returns>
[DllImport(Lib.Secur32, ExactSpelling = true)]
[PInvokeData("Ntsecapi.h", MSDNShortId = "aa378265")]
public static extern uint LsaConnectUntrusted(out SafeLsaConnectionHandle LsaHandle);
/// <summary>The LsaDeregisterLogonProcess function deletes the caller's logon application context and closes the connection to the LSA server.</summary>
/// <param name="LsaHandle">Handle obtained from a LsaRegisterLogonProcess or LsaConnectUntrusted call.</param>
/// <returns>If the function succeeds, the return value is STATUS_SUCCESS.
/// <para>If the function fails, the return value is an NTSTATUS code. For more information, see LSA Policy Function Return Values.</para>
/// <para>The LsaNtStatusToWinError function converts an NTSTATUS code to a Windows error code.</para></returns>
[DllImport(Lib.Secur32, ExactSpelling = true)]
[PInvokeData("Ntsecapi.h", MSDNShortId = "aa378269")]
public static extern uint LsaDeregisterLogonProcess(IntPtr LsaHandle);
/// <summary>The LsaRegisterLogonProcess function establishes a connection to the LSA server and verifies that the caller is a logon application.</summary>
/// <param name="LogonProcessName">String identifying the logon application. This should be a printable name suitable for display to administrators. For example, the Windows logon application might use the name "User32LogonProcess". This name is used by the LSA during auditing. LsaRegisterLogonProcess does not check whether the name is already in use. This string must not exceed 127 bytes.</param>
/// <param name="LsaHandle">Pointer that receives a handle used in future authentication function calls.</param>
/// <param name="SecurityMode">The value returned is not meaningful and should be ignored.</param>
/// <returns>If the function succeeds, the return value is STATUS_SUCCESS.
/// <para>If the function fails, the return value is an NTSTATUS code. For more information, see LSA Policy Function Return Values.</para>
/// <para>The LsaNtStatusToWinError function converts an NTSTATUS code to a Windows error code.</para></returns>
[DllImport(Lib.Secur32, ExactSpelling = true)]
[PInvokeData("Ntsecapi.h", MSDNShortId = "aa378318")]
public static extern uint LsaRegisterLogonProcess([In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaStringMarshaler))] string LogonProcessName, out SafeLsaConnectionHandle LsaHandle, out uint SecurityMode);
public static extern NTStatus LsaLookupAuthenticationPackage(LsaConnectionHandle LsaHandle, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaStringMarshaler))] string PackageName, out int AuthenticationPackage);
/// <summary>
/// A SafeHandle for security descriptors. If owned, will call LocalFree on the pointer when disposed.
/// The LsaRegisterLogonProcess function establishes a connection to the LSA server and verifies that the caller is a logon application.
/// </summary>
[PInvokeData("Ntsecapi.h")]
public class SafeLsaConnectionHandle : GenericSafeHandle
{
/// <summary>Initializes a new instance of the <see cref="SafeLsaConnectionHandle"/> class.</summary>
public SafeLsaConnectionHandle() : this(IntPtr.Zero) {}
/// <param name="LogonProcessName">
/// String identifying the logon application. This should be a printable name suitable for display to administrators. For example,
/// the Windows logon application might use the name "User32LogonProcess". This name is used by the LSA during auditing.
/// LsaRegisterLogonProcess does not check whether the name is already in use. This string must not exceed 127 bytes.
/// </param>
/// <param name="LsaHandle">Pointer that receives a handle used in future authentication function calls.</param>
/// <param name="SecurityMode">The value returned is not meaningful and should be ignored.</param>
/// <returns>
/// If the function succeeds, the return value is STATUS_SUCCESS.
/// <para>If the function fails, the return value is an NTSTATUS code. For more information, see LSA Policy Function Return Values.</para>
/// <para>The LsaNtStatusToWinError function converts an NTSTATUS code to a Windows error code.</para>
/// </returns>
[DllImport(Lib.Secur32, ExactSpelling = true)]
[PInvokeData("Ntsecapi.h", MSDNShortId = "aa378318")]
public static extern NTStatus LsaRegisterLogonProcess([In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaStringMarshaler))] string LogonProcessName, out SafeLsaConnectionHandle LsaHandle, out uint SecurityMode);
/// <summary>Initializes a new instance of the <see cref="SafeLsaConnectionHandle"/> class from an existing pointer.</summary>
/// <param name="handle">The connection handle.</param>
/// <param name="own">if set to <c>true</c> indicates that this pointer should be freed when disposed.</param>
public SafeLsaConnectionHandle(IntPtr handle, bool own = true) : base(handle, h => LsaDeregisterLogonProcess(h) == 0, own) { }
/// <summary>Provides a handle to an LSA connection.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct LsaConnectionHandle : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="LsaConnectionHandle"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public LsaConnectionHandle(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="LsaConnectionHandle"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static LsaConnectionHandle NULL => new LsaConnectionHandle(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="LsaConnectionHandle"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(LsaConnectionHandle h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="LsaConnectionHandle"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator LsaConnectionHandle(IntPtr h) => new LsaConnectionHandle(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(LsaConnectionHandle h1, LsaConnectionHandle h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(LsaConnectionHandle h1, LsaConnectionHandle h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is LsaConnectionHandle h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="LsaConnectionHandle"/> that is disposed using <see cref="LsaDeregisterLogonProcess"/>.</summary>
public class SafeLsaConnectionHandle : HANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafeLsaConnectionHandle"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeLsaConnectionHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeLsaConnectionHandle"/> class.</summary>
private SafeLsaConnectionHandle() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeLsaConnectionHandle"/> to <see cref="LsaConnectionHandle"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator LsaConnectionHandle(SafeLsaConnectionHandle h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => LsaDeregisterLogonProcess(this).Succeeded;
}
/*
AuditComputeEffectivePolicyBySid function
AuditComputeEffectivePolicyByToken function
AuditEnumerateCategories function
AuditEnumeratePerUserPolicy function
AuditEnumerateSubCategories function
AuditFree function
AuditLookupCategoryGuidFromCategoryId function
AuditLookupCategoryIdFromCategoryGuid function
AuditLookupCategoryNameA function
AuditLookupCategoryNameW function
AuditLookupSubCategoryNameA function
AuditLookupSubCategoryNameW function
AuditQueryGlobalSaclA function
AuditQueryGlobalSaclW function
AuditQueryPerUserPolicy function
AuditQuerySecurity function
AuditQuerySystemPolicy function
AuditSetGlobalSaclA function
AuditSetGlobalSaclW function
AuditSetPerUserPolicy function
AuditSetSecurity function
AuditSetSystemPolicy function
KERB_CRYPTO_KEY structure
LsaCallAuthenticationPackage function
LsaCreateTrustedDomainEx function
LsaDeleteTrustedDomain function
LsaEnumerateLogonSessions function
LsaEnumerateTrustedDomains function
LsaEnumerateTrustedDomainsEx function
LsaGetLogonSessionData function
LsaLogonUser function
LsaLookupNames function
LsaLookupSids function
LsaOpenTrustedDomainByName function
LsaQueryDomainInformationPolicy function
LsaQueryForestTrustInformation function
LsaQueryInformationPolicy function
LsaQueryTrustedDomainInfoByName function
LsaRegisterPolicyChangeNotification function
LsaRetrievePrivateData function
LsaSetDomainInformationPolicy function
LsaSetForestTrustInformation function
LsaSetInformationPolicy function
LsaSetTrustedDomainInfoByName function
LsaStorePrivateData function
LsaUnregisterPolicyChangeNotification function
PSAM_INIT_NOTIFICATION_ROUTINE callback function
PSAM_PASSWORD_FILTER_ROUTINE callback function
PSAM_PASSWORD_NOTIFICATION_ROUTINE callback function
RtlDecryptMemory function
RtlEncryptMemory function
RtlGenRandom function
*/
}
}
}

View File

@ -36,7 +36,8 @@ namespace Vanara.PInvoke
// SameSuppliedUser, PBOOLEAN SameSuppliedIdentity );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "d2c4f363-3d86-48f0-bae1-4f9240d68bab")]
public static extern Win32Error SspiCompareAuthIdentities(PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity1, PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity2, [MarshalAs(UnmanagedType.U1)] out bool SameSuppliedUser, [MarshalAs(UnmanagedType.U1)] out bool SameSuppliedIdentity);
public static extern Win32Error SspiCompareAuthIdentities(PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity1, PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity2,
[MarshalAs(UnmanagedType.U1)] out bool SameSuppliedUser, [MarshalAs(UnmanagedType.U1)] out bool SameSuppliedIdentity);
/// <summary>
/// <para>Creates a copy of the specified opaque credential structure.</para>
@ -146,7 +147,8 @@ namespace Vanara.PInvoke
// PSEC_WINNT_AUTH_IDENTITY_OPAQUE *ppAuthIdentity );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "0aea2f00-fcf1-4c4e-a22f-a669dd4fb294")]
public static extern Win32Error SspiEncodeStringsAsAuthIdentity([MarshalAs(UnmanagedType.LPWStr)] string pszUserName, [MarshalAs(UnmanagedType.LPWStr)] string pszDomainName, [MarshalAs(UnmanagedType.LPWStr)] string pszPackedCredentialsString, out SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE ppAuthIdentity);
public static extern Win32Error SspiEncodeStringsAsAuthIdentity([MarshalAs(UnmanagedType.LPWStr)] string pszUserName, [MarshalAs(UnmanagedType.LPWStr)] string pszDomainName,
[MarshalAs(UnmanagedType.LPWStr)] string pszPackedCredentialsString, out SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE ppAuthIdentity);
/// <summary>
/// <para>Encrypts the specified identity structure.</para>
@ -406,40 +408,63 @@ namespace Vanara.PInvoke
[PInvokeData("sspi.h", MSDNShortId = "50b1f24a-c802-4691-a450-316cb31bf44d")]
public static extern void SspiZeroAuthIdentity(PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData);
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
private static extern void SspiFreeAuthIdentity(IntPtr AuthData);
/// <summary>Provides a handle to an authorization identity.</summary>
public class PSEC_WINNT_AUTH_IDENTITY_OPAQUE : HANDLE
/// <summary>Provides a handle to a auth identity.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct PSEC_WINNT_AUTH_IDENTITY_OPAQUE : IHandle
{
/// <summary>
/// Initializes a new instance of the <see cref="PSEC_WINNT_AUTH_IDENTITY_OPAQUE"/> class and assigns an existing handle.
/// </summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public PSEC_WINNT_AUTH_IDENTITY_OPAQUE(IntPtr preexistingHandle) : base(preexistingHandle, true) { }
private IntPtr handle;
/// <summary>
/// Initializes a new instance of the <see cref="PSEC_WINNT_AUTH_IDENTITY_OPAQUE"/> class and assigns an existing handle.
/// </summary>
/// <summary>Initializes a new instance of the <see cref="PSEC_WINNT_AUTH_IDENTITY_OPAQUE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
protected PSEC_WINNT_AUTH_IDENTITY_OPAQUE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
public PSEC_WINNT_AUTH_IDENTITY_OPAQUE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>
/// Returns an invalid handle by instantiating a <see cref="PSEC_WINNT_AUTH_IDENTITY_OPAQUE"/> object with <see cref="IntPtr.Zero"/>.
/// </summary>
public static PSEC_WINNT_AUTH_IDENTITY_OPAQUE NULL => new PSEC_WINNT_AUTH_IDENTITY_OPAQUE(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="PSEC_WINNT_AUTH_IDENTITY_OPAQUE"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(PSEC_WINNT_AUTH_IDENTITY_OPAQUE h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="PSEC_WINNT_AUTH_IDENTITY_OPAQUE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PSEC_WINNT_AUTH_IDENTITY_OPAQUE(IntPtr h) => new PSEC_WINNT_AUTH_IDENTITY_OPAQUE(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(PSEC_WINNT_AUTH_IDENTITY_OPAQUE h1, PSEC_WINNT_AUTH_IDENTITY_OPAQUE h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(PSEC_WINNT_AUTH_IDENTITY_OPAQUE h1, PSEC_WINNT_AUTH_IDENTITY_OPAQUE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is PSEC_WINNT_AUTH_IDENTITY_OPAQUE h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>
/// Provides a <see cref="SafeHandle"/> to a that releases a created PSEC_WINNT_AUTH_IDENTITY_OPAQUE instance at disposal using SspiFreeAuthIdentity.
/// Provides a <see cref="SafeHandle"/> for <see cref="PSEC_WINNT_AUTH_IDENTITY_OPAQUE"/> that is disposed using <see cref="SspiFreeAuthIdentity"/>.
/// </summary>
public class SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE : PSEC_WINNT_AUTH_IDENTITY_OPAQUE
public class SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE : HANDLE
{
/// <summary>
/// Initializes a new instance of the <see cref="PSEC_WINNT_AUTH_IDENTITY_OPAQUE"/> class and assigns an existing handle.
/// Initializes a new instance of the <see cref="SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE"/> class and assigns an existing handle.
/// </summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
@ -447,6 +472,14 @@ namespace Vanara.PInvoke
/// </param>
public SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE"/> class.</summary>
private SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE"/> to <see cref="PSEC_WINNT_AUTH_IDENTITY_OPAQUE"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PSEC_WINNT_AUTH_IDENTITY_OPAQUE(SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() { SspiFreeAuthIdentity(this); return true; }
}
@ -464,15 +497,111 @@ namespace Vanara.PInvoke
public void CleanUpNativeData(IntPtr pNativeData)
{
if (pNativeData == IntPtr.Zero) return;
SspiFreeAuthIdentity(pNativeData);
SspiFreeAuthIdentity(new PSEC_WINNT_AUTH_IDENTITY_OPAQUE(pNativeData));
pNativeData = IntPtr.Zero;
}
public int GetNativeDataSize() => 0;
public int GetNativeDataSize() => -1;
public IntPtr MarshalManagedToNative(object ManagedObj) => IntPtr.Zero;
public object MarshalNativeToManaged(IntPtr pNativeData) => Marshal.PtrToStringAuto(pNativeData);
}
/*
_CREDUIWIN_MARSHALED_CONTEXT
_SEC_APPLICATION_PROTOCOL_NEGOTIATION_STATUS enumeration
_SEC_CHANNEL_BINDINGS
_SEC_WINNT_AUTH_BYTE_VECTOR
_SEC_WINNT_AUTH_CERTIFICATE_DATA
_SEC_WINNT_AUTH_DATA
_SEC_WINNT_AUTH_DATA_PASSWORD
_SEC_WINNT_AUTH_IDENTITY_EX2
_SEC_WINNT_AUTH_IDENTITY_EX
_SEC_WINNT_AUTH_IDENTITY_
_SEC_WINNT_AUTH_PACKED_CREDENTIALS
_SEC_WINNT_AUTH_PACKED_CREDENTIALS_EX
_SEC_WINNT_AUTH_SHORT_VECTOR
_SEC_WINNT_CREDUI_CONTEXT
_SEC_WINNT_CREDUI_CONTEXT_VECTOR
_SecBuffer
_SecBufferDesc
_SECPKG_ATTR_LCT_STATUS enumeration
_SECPKG_CRED_CLASS enumeration
_SecPkgContext_AccessToken
_SecPkgContext_Authority
_SecPkgContext_Bindings
_SecPkgContext_ClientSpecifiedTarget
_SecPkgContext_CredentialName
_SecPkgContext_CredInfo
_SecPkgContext_DceInfo
_SecPkgContext_Flags
_SecPkgContext_KeyInfo
_SecPkgContext_LastClientTokenStatus
_SecPkgContext_Lifespan
_SecPkgContext_Names
_SecPkgContext_NativeNames
_SecPkgContext_NegoStatus
_SecPkgContext_NegotiationInfo
_SecPkgContext_PackageInfo
_SecPkgContext_PasswordExpiry
_SecPkgContext_ProtoInfo
_SecPkgContext_SessionKey
_SecPkgContext_Sizes
_SecPkgContext_StreamSizes
_SecPkgContext_SubjectAttributes
_SecPkgContext_TargetInformation
_SecPkgCredentials_Cert
_SecPkgCredentials_KdcProxySettings
_SecPkgCredentials_Names
_SecPkgCredentials_SSIProvider
_SecPkgInfo
_SECURITY_FUNCTION_TABLE
_SECURITY_INTEGER
_SECURITY_PACKAGE_OPTIONS
_SECURITY_STRING
AcceptSecurityContext
AcquireCredentialsHandle
AddSecurityPackage
ApplyControlToken
ChangeAccountPassword
CompleteAuthToken
DecryptMessage
DeleteSecurityContext
DeleteSecurityPackage
EncryptMessage
EnumerateSecurityPackages
ExportSecurityContext
FreeContextBuffer
FreeCredentialsHandle
ImpersonateSecurityContext
ImportSecurityContext
InitializeSecurityContext
InitSecurityInterface
MakeSignature
QueryContextAttributesEx
QueryContextAttributes
QueryCredentialsAttributes
QuerySecurityContextToken
QuerySecurityPackageInfo
RevertSecurityContext
SaslAcceptSecurityContext
SaslEnumerateProfiles
SaslGetContextOption
SaslGetProfilePackage
SaslIdentifyPackage
SaslInitializeSecurityContext
SaslSetContextOption
SetContextAttributes
SetCredentialsAttributes
SspiDecryptAuthIdentityEx
SspiEncryptAuthIdentityEx
SspiGetCredUIContext
SspiIsPromptingNeeded
SspiPromptForCredentials
SspiUnmarshalCredUIContext
SspiUpdateCredentials
VerifySignature
*/
}
}

View File

@ -37,6 +37,11 @@ INHERITED_FROM, TRUSTEE, LSA_OBJECT_ATTRIBUTES, LSA_STRING, LSA_TRANSLATED_NAME,
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Core\Vanara.Core.csproj" />
<ProjectReference Include="..\Kernel32\Vanara.PInvoke.Kernel32.csproj" />
<ProjectReference Include="..\Shared\Vanara.PInvoke.Shared.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net20' ">
<Reference Include="System" />
</ItemGroup>
@ -50,12 +55,7 @@ INHERITED_FROM, TRUSTEE, LSA_OBJECT_ATTRIBUTES, LSA_STRING, LSA_TRANSLATED_NAME,
<Reference Include="System" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="System.Security.AccessControl" Version="4.4.0" />
<PackageReference Include="Microsoft.Win32.Registry" Version="4.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Core\Vanara.Core.csproj" />
<ProjectReference Include="..\Kernel32\Vanara.PInvoke.Kernel32.csproj" />
<ProjectReference Include="..\Shared\Vanara.PInvoke.Shared.csproj" />
<PackageReference Include="System.Security.AccessControl" Version="4.5.0" />
<PackageReference Include="Microsoft.Win32.Registry" Version="4.5.0" />
</ItemGroup>
</Project>

View File

@ -14,10 +14,7 @@ namespace Vanara.PInvoke
{
/// <summary>Initializes a new instance of the <see cref="PInvokeDataAttribute"/> class.</summary>
/// <param name="guid">A GUID.</param>
public AssociateAttribute(string guid)
{
Guid = new Guid(guid);
}
public AssociateAttribute(string guid) => Guid = new Guid(guid);
/// <summary>Gets or sets the GUID associated with this element.</summary>
/// <value>A GUID value.</value>
@ -43,7 +40,7 @@ namespace Vanara.PInvoke
value = (T)f.GetRawConstantValue();
return true;
}
value = default(T);
value = default;
return false;
}
}

View File

@ -0,0 +1,33 @@
#if (NET20 || NET35)
namespace Microsoft.Win32.SafeHandles
{
using System;
using System.Runtime.InteropServices;
using System.Security;
/// <summary>Represents a safe handle to the Windows registry.</summary>
[SecurityCritical]
public sealed class SafeRegistryHandle : SafeHandleZeroOrMinusOneIsInvalid
{
/// <summary>Initializes a new instance of the <see cref="SafeRegistryHandle"/> class.</summary>
/// <param name="preexistingHandle">An object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; <see langword="false"/> to prevent reliable release.
/// </param>
[SecurityCritical]
public SafeRegistryHandle(IntPtr preexistingHandle, bool ownsHandle) : base(ownsHandle) => SetHandle(preexistingHandle);
[SecurityCritical]
internal SafeRegistryHandle() : base(true) { }
/// <inheritdoc/>
[SecurityCritical]
protected override bool ReleaseHandle() => RegCloseKey(handle).Succeeded;
[DllImport(Vanara.PInvoke.Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
private static extern Vanara.PInvoke.Win32Error RegCloseKey(IntPtr hKey);
}
}
#endif

View File

@ -6,8 +6,8 @@ using System.Diagnostics.CodeAnalysis;
namespace Vanara.Collections
{
/// <summary>
/// Creates an enumerable class from a counter and an indexer. Useful if a class doesn't support <see cref="IEnumerable"/> or <see cref="IEnumerable{T}"/>
/// like some COM objects.
/// Creates an enumerable class from a counter and an indexer. Useful if a class doesn't support <see cref="IEnumerable"/> or <see
/// cref="IEnumerable{T}"/> like some COM objects.
/// </summary>
/// <typeparam name="TItem">The type of the item.</typeparam>
public class IEnumFromIndexer<TItem> : IReadOnlyList<TItem>
@ -16,7 +16,7 @@ namespace Vanara.Collections
private readonly Func<uint, TItem> indexer;
private readonly uint startIndex;
/// <summary>Initializes a new instance of the <see cref="IEnumFromIndexer{TItem}" /> class.</summary>
/// <summary>Initializes a new instance of the <see cref="IEnumFromIndexer{TItem}"/> class.</summary>
/// <param name="getCount">The method used to get the total count of items.</param>
/// <param name="indexer">The method used to get a single item.</param>
/// <param name="startIndex">The index at which the collection begins (usually 1 or 0).</param>
@ -51,19 +51,31 @@ namespace Vanara.Collections
{
private uint i;
private IEnumFromIndexer<TItem> ienum;
public Enumerator(IEnumFromIndexer<TItem> ienum) { this.ienum = ienum; ((IEnumerator)this).Reset(); }
bool IEnumerator.MoveNext() => ienum != null && ++i < ienum.getCount() + ienum.startIndex;
void IEnumerator.Reset() { if (ienum != null) i = ienum.startIndex - 1; }
TItem IEnumerator<TItem>.Current => ienum == null ? default(TItem) : ienum.indexer(i);
public Enumerator(IEnumFromIndexer<TItem> ienum)
{
this.ienum = ienum; ((IEnumerator)this).Reset();
}
TItem IEnumerator<TItem>.Current => ienum == null ? default : ienum.indexer(i);
[ExcludeFromCodeCoverage]
object IEnumerator.Current => ((IEnumerator<TItem>)this).Current;
void IDisposable.Dispose() { ienum = null; }
void IDisposable.Dispose() => ienum = null;
bool IEnumerator.MoveNext() => ienum != null && ++i < ienum.getCount() + ienum.startIndex;
void IEnumerator.Reset()
{
if (ienum != null) i = ienum.startIndex - 1;
}
}
}
/// <summary>
/// Creates an enumerable class from a get next method and a reset method. Useful if a class doesn't support <see cref="IEnumerable"/> or <see cref="IEnumerable{T}"/>
/// like some COM objects.
/// Creates an enumerable class from a get next method and a reset method. Useful if a class doesn't support <see cref="IEnumerable"/> or
/// <see cref="IEnumerable{T}"/> like some COM objects.
/// </summary>
/// <typeparam name="TItem">The type of the item.</typeparam>
public class IEnumFromNext<TItem> : IEnumerable<TItem>
@ -71,12 +83,7 @@ namespace Vanara.Collections
private readonly TryGetNext next;
private readonly Action reset;
/// <summary>Delegate that gets the next value in an enumeration and returns true or returns false to indicate there are no more items in the enumeration.</summary>
/// <param name="value">The value, on success, of the next item.</param>
/// <returns><c>true</c> if an item is returned, otherwise <c>false</c>.</returns>
public delegate bool TryGetNext(out TItem value);
/// <summary>Initializes a new instance of the <see cref="IEnumFromNext{TItem}" /> class.</summary>
/// <summary>Initializes a new instance of the <see cref="IEnumFromNext{TItem}"/> class.</summary>
/// <param name="next">The method used to try to get the next item in the enumeration.</param>
/// <param name="reset">The method used to reset the enumeration to the first element.</param>
public IEnumFromNext(TryGetNext next, Action reset)
@ -86,6 +93,13 @@ namespace Vanara.Collections
this.reset = reset;
}
/// <summary>
/// Delegate that gets the next value in an enumeration and returns true or returns false to indicate there are no more items in the enumeration.
/// </summary>
/// <param name="value">The value, on success, of the next item.</param>
/// <returns><c>true</c> if an item is returned, otherwise <c>false</c>.</returns>
public delegate bool TryGetNext(out TItem value);
/// <summary>Returns an enumerator that iterates through the collection.</summary>
/// <returns>A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.</returns>
public IEnumerator<TItem> GetEnumerator() => new Enumerator(this);
@ -98,23 +112,32 @@ namespace Vanara.Collections
private class Enumerator : IEnumerator<TItem>
{
private IEnumFromNext<TItem> ienum;
public Enumerator(IEnumFromNext<TItem> ienum) { this.ienum = ienum; ((IEnumerator)this).Reset(); }
public Enumerator(IEnumFromNext<TItem> ienum)
{
this.ienum = ienum; ((IEnumerator)this).Reset();
}
public TItem Current { get; private set; }
[ExcludeFromCodeCoverage]
object IEnumerator.Current => Current;
void IDisposable.Dispose() => ienum = null;
bool IEnumerator.MoveNext()
{
if (ienum == null || !ienum.next(out TItem p)) return false;
if (ienum == null || !ienum.next(out var p)) return false;
Current = p;
return true;
}
void IEnumerator.Reset()
{
if (ienum == null) return;
ienum.reset();
Current = default(TItem);
Current = default;
}
public TItem Current { get; private set; }
[ExcludeFromCodeCoverage]
object IEnumerator.Current => Current;
void IDisposable.Dispose() { ienum = null; }
}
}
}

View File

@ -4,47 +4,78 @@ using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
public class HANDLE : SafeHandleZeroOrMinusOneIsInvalid, IEquatable<HANDLE>, IHandle
/// <summary>Signals that a structure or class holds a handle to a synchronization object.</summary>
public interface IGraphicsObjectHandle : IHandle { }
/// <summary>Signals that a structure or class holds a HANDLE.</summary>
public interface IHandle
{
public HANDLE() : base(true)
{
}
/// <summary>Returns the value of the handle field.</summary>
/// <returns>An IntPtr representing the value of the handle field.</returns>
IntPtr DangerousGetHandle();
}
protected HANDLE(IntPtr ptr, bool ownsHandle = true) : base(ownsHandle) => SetHandle(ptr);
/// <summary>Signals that a structure or class holds a handle to a synchronization object.</summary>
public interface IKernelHandle : IHandle { }
/// <summary>Signals that a structure or class holds a pointer to a security object.</summary>
public interface ISecurityObject : IHandle { }
/// <summary>Signals that a structure or class holds a handle to a synchronization object.</summary>
public interface IShellHandle : IHandle { }
/// <summary>Signals that a structure or class holds a handle to a synchronization object.</summary>
public interface ISyncHandle : IKernelHandle { }
/// <summary>Signals that a structure or class holds a handle to a synchronization object.</summary>
public interface IUserHandle : IHandle { }
/// <summary>Provides a handle to an accelator table.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct HACCEL : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="HACCEL"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public HACCEL(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="HACCEL"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static HACCEL NULL => new HACCEL(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
public static bool operator !=(HANDLE h1, HANDLE h2) => !(h1 == h2);
/// <summary>Performs an explicit conversion from <see cref="HACCEL"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(HACCEL h) => h.handle;
public static bool operator ==(HANDLE h1, HANDLE h2) => h1 is null || h2 is null ? false : h1.Equals(h2);
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="HACCEL"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HACCEL(IntPtr h) => new HACCEL(h);
public bool Equals(HANDLE other)
{
if (other is null)
return false;
if (ReferenceEquals(this, other))
return true;
return handle == other.handle && IsClosed == other.IsClosed;
}
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(HACCEL h1, HACCEL h2) => !(h1 == h2);
public override bool Equals(object obj) => obj is HANDLE h ? Equals(h) : base.Equals(obj);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(HACCEL h1, HACCEL h2) => h1.Equals(h2);
public override int GetHashCode() => base.GetHashCode();
/// <inheritdoc/>
public override bool Equals(object obj) => obj is HACCEL h ? handle == h.handle : false;
/// <summary>
/// Internal method that actually releases the handle. This is called by <see cref="ReleaseHandle"/> for valid handles and afterwards
/// zeros the handle.
/// </summary>
/// <returns><c>true</c> to indicate successful release of the handle; <c>false</c> otherwise.</returns>
protected virtual bool InternalReleaseHandle() => true;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
protected override bool ReleaseHandle()
{
if (IsClosed) return true;
if (!InternalReleaseHandle()) return false;
handle = IntPtr.Zero;
return true;
}
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a handle to a bitmap.</summary>
@ -492,6 +523,54 @@ namespace Vanara.PInvoke
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a handle to an enhanced metafile.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct HENHMETAFILE : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="HENHMETAFILE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public HENHMETAFILE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="HENHMETAFILE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static HENHMETAFILE NULL => new HENHMETAFILE(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="HENHMETAFILE"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(HENHMETAFILE h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="HENHMETAFILE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HENHMETAFILE(IntPtr h) => new HENHMETAFILE(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(HENHMETAFILE h1, HENHMETAFILE h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(HENHMETAFILE h1, HENHMETAFILE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is HENHMETAFILE h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a handle to a file.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct HFILE : IKernelHandle
@ -841,6 +920,11 @@ namespace Vanara.PInvoke
/// <returns>The result of the conversion.</returns>
public static implicit operator HKEY(IntPtr h) => new HKEY(h);
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="HKEY"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HKEY(SafeRegistryHandle h) => new HKEY(h.DangerousGetHandle());
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
@ -911,6 +995,54 @@ namespace Vanara.PInvoke
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a handle to a metafile.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct HMETAFILE : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="HMETAFILE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public HMETAFILE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="HMETAFILE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static HMETAFILE NULL => new HMETAFILE(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="HMETAFILE"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(HMETAFILE h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="HMETAFILE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HMETAFILE(IntPtr h) => new HMETAFILE(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(HMETAFILE h1, HMETAFILE h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(HMETAFILE h1, HMETAFILE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is HMETAFILE h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a handle to a monitor.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct HMONITOR : IKernelHandle
@ -1065,29 +1197,6 @@ namespace Vanara.PInvoke
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Signals that a structure or class holds a HANDLE.</summary>
public interface IHandle
{
/// <summary>Returns the value of the handle field.</summary>
/// <returns>An IntPtr representing the value of the handle field.</returns>
IntPtr DangerousGetHandle();
}
/// <summary>Signals that a structure or class holds a handle to a synchronization object.</summary>
public interface IUserHandle : IHandle { }
/// <summary>Signals that a structure or class holds a handle to a synchronization object.</summary>
public interface IShellHandle : IHandle { }
/// <summary>Signals that a structure or class holds a handle to a synchronization object.</summary>
public interface IGraphicsObjectHandle : IHandle { }
/// <summary>Signals that a structure or class holds a handle to a synchronization object.</summary>
public interface IKernelHandle : IHandle { }
/// <summary>Signals that a structure or class holds a handle to a synchronization object.</summary>
public interface ISyncHandle : IKernelHandle { }
/// <summary>Provides a handle to a process.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct HPROCESS : ISyncHandle
@ -1572,4 +1681,220 @@ namespace Vanara.PInvoke
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a pointer to an access control entry.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct PACE : ISecurityObject
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="PACE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public PACE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="PACE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static PACE NULL => new PACE(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="PACE"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(PACE h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="PACE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PACE(IntPtr h) => new PACE(h);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is PACE h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a pointer to an access control list.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct PACL : ISecurityObject
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="PACL"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public PACL(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="PACL"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static PACL NULL => new PACL(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="PACL"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(PACL h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="PACL"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PACL(IntPtr h) => new PACL(h);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is PACL h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a pointer to a security descriptor.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct PSECURITY_DESCRIPTOR : ISecurityObject
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="PSECURITY_DESCRIPTOR"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public PSECURITY_DESCRIPTOR(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="PSECURITY_DESCRIPTOR"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static PSECURITY_DESCRIPTOR NULL => new PSECURITY_DESCRIPTOR(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="PSECURITY_DESCRIPTOR"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(PSECURITY_DESCRIPTOR h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="PSECURITY_DESCRIPTOR"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PSECURITY_DESCRIPTOR(IntPtr h) => new PSECURITY_DESCRIPTOR(h);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is PSECURITY_DESCRIPTOR h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a pointer to a security identifier.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct PSID : ISecurityObject
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="PSID"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public PSID(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="PSID"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static PSID NULL => new PSID(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="PSID"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(PSID h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="PSID"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PSID(IntPtr h) => new PSID(h);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is PSID h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Base class for all native handles.</summary>
/// <seealso cref="Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid"/>
/// <seealso cref="System.IEquatable{Vanara.PInvoke.HANDLE}"/>
/// <seealso cref="Vanara.PInvoke.IHandle"/>
public class HANDLE : SafeHandleZeroOrMinusOneIsInvalid, IEquatable<HANDLE>, IHandle
{
/// <summary>Initializes a new instance of the <see cref="HANDLE"/> class.</summary>
public HANDLE() : base(true)
{
}
/// <summary>Initializes a new instance of the <see cref="HANDLE"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
protected HANDLE(IntPtr ptr, bool ownsHandle = true) : base(ownsHandle) => SetHandle(ptr);
/// <summary>Gets a value indicating whether this instance is null.</summary>
/// <value><c>true</c> if this instance is null; otherwise, <c>false</c>.</value>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(HANDLE h1, HANDLE h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(HANDLE h1, HANDLE h2) => h1 is null || h2 is null ? false : h1.Equals(h2);
/// <summary>Determines whether the specified <see cref="HANDLE"/>, is equal to this instance.</summary>
/// <param name="other">The <see cref="HANDLE"/> to compare with this instance.</param>
/// <returns><c>true</c> if the specified <see cref="HANDLE"/> is equal to this instance; otherwise, <c>false</c>.</returns>
public bool Equals(HANDLE other)
{
if (other is null)
return false;
if (ReferenceEquals(this, other))
return true;
return handle == other.handle && IsClosed == other.IsClosed;
}
/// <summary>Determines whether the specified <see cref="System.Object"/>, is equal to this instance.</summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj) => obj is HANDLE h ? Equals(h) : base.Equals(obj);
/// <summary>Returns a hash code for this instance.</summary>
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
public override int GetHashCode() => base.GetHashCode();
/// <summary>
/// Internal method that actually releases the handle. This is called by <see cref="ReleaseHandle"/> for valid handles and afterwards
/// zeros the handle.
/// </summary>
/// <returns><c>true</c> to indicate successful release of the handle; <c>false</c> otherwise.</returns>
protected virtual bool InternalReleaseHandle() => true;
/// <inheritdoc/>
protected override bool ReleaseHandle()
{
if (IsInvalid) return true;
if (!InternalReleaseHandle()) return false;
handle = IntPtr.Zero;
return true;
}
}
}

View File

@ -8,7 +8,7 @@ namespace Vanara.InteropServices
/// <seealso cref="System.Runtime.InteropServices.ICustomMarshaler"/>
public class CoTaskMemStringMarshaler : ICustomMarshaler
{
private CharSet charSet = CharSet.Unicode;
private readonly CharSet charSet = CharSet.Unicode;
private CoTaskMemStringMarshaler(string cookie)
{
@ -29,10 +29,7 @@ namespace Vanara.InteropServices
/// <summary>Performs necessary cleanup of the unmanaged data when it is no longer needed.</summary>
/// <param name="pNativeData">A pointer to the unmanaged data to be destroyed.</param>
public void CleanUpNativeData(IntPtr pNativeData)
{
Marshal.FreeCoTaskMem(pNativeData);
}
public void CleanUpNativeData(IntPtr pNativeData) => Marshal.FreeCoTaskMem(pNativeData);
/// <summary>Returns the size of the native data to be marshaled.</summary>
/// <returns>The size in bytes of the native data.</returns>

View File

@ -8,21 +8,27 @@ using Vanara.Extensions;
namespace Vanara.InteropServices
{
/// <summary>
/// A safe unmanaged array of structures allocated on the global heap with a prefix type (usually a uint or int) that determines the count of elements.
/// A safe unmanaged array of structures allocated on the global heap with a prefix type (usually a uint or int) that determines the
/// count of elements.
/// </summary>
public class SafeElementArray<TElem, TPrefix, TMem> : SafeMemoryHandle<TMem>, IEnumerable<TElem> where TMem : IMemoryMethods, new() where TElem : struct where TPrefix : IConvertible
{
private static int ElemSize = Marshal.SizeOf(typeof(TElem));
private static int PrefixSize = Marshal.SizeOf(typeof(TPrefix));
private static readonly int ElemSize = Marshal.SizeOf(typeof(TElem));
private static readonly int PrefixSize = Marshal.SizeOf(typeof(TPrefix));
/// <summary>Initializes a new instance of the <see cref="SafeElementArray{TElem, TPrefix, TMem}"/> class.</summary>
protected SafeElementArray() : this(0) { }
/// <summary>Initializes a new instance of the <see cref="SafeElementArray{TElem, TPrefix, TMem}"/> class and allocates <paramref name="elementCount"/> bytes.</summary>
/// <summary>
/// Initializes a new instance of the <see cref="SafeElementArray{TElem, TPrefix, TMem}"/> class and allocates <paramref
/// name="elementCount"/> bytes.
/// </summary>
/// <param name="elementCount">The TElem count to allocate.</param>
protected SafeElementArray(TPrefix elementCount) : this(Convert.ToInt32(elementCount)) { }
/// <summary>Initializes a new instance of the <see cref="SafeElementArray{TElem, TPrefix, TMem}"/> class from a copy of a managed TElem array.</summary>
/// <summary>
/// Initializes a new instance of the <see cref="SafeElementArray{TElem, TPrefix, TMem}"/> class from a copy of a managed TElem array.
/// </summary>
/// <param name="array">The array of bytes to copy.</param>
/// <param name="getElemSize">Size of the get elem.</param>
protected SafeElementArray(TElem[] array, Func<TElem, int> getElemSize = null) : base(IntPtr.Zero, 0, true) { GetElemSize = getElemSize; Elements = array; }
@ -37,12 +43,14 @@ namespace Vanara.InteropServices
IntCount = elementCount;
}
private SafeElementArray(int elementCount) : base(GetRequiredSize(elementCount)) { }
private SafeElementArray(int elementCount) : base(GetRequiredSize(elementCount))
{
}
/// <summary>Gets the number of elements contained in the <see cref="SafeElementArray{TElem, TPrefix, TMem}"/>.</summary>
protected TPrefix Count
{
get => IsInvalid ? default(TPrefix) : handle.ToStructure<TPrefix>();
get => IsInvalid ? default : handle.ToStructure<TPrefix>();
private set { if (!IsInvalid) Marshal.StructureToPtr(value, handle, false); }
}

View File

@ -29,9 +29,7 @@ namespace Vanara.InteropServices
/// <param name="elementCount">The element count. This value can be 0.</param>
public SafeNativeArray(int elementCount) : base(GetRequiredSize(elementCount)) => Zero();
/// <summary>
/// Initializes a new instance of the <see cref="SafeNativeArray{TElem}"/> class.
/// </summary>
/// <summary>Initializes a new instance of the <see cref="SafeNativeArray{TElem}"/> class.</summary>
/// <param name="ptr">The PTR.</param>
/// <param name="size">The size.</param>
/// <param name="ownsHandle">if set to <c>true</c> [owns handle].</param>

View File

@ -5,58 +5,85 @@
{
/// <summary>The acl UI</summary>
public const string AclUI = "aclui.dll";
/// <summary>The adv api32</summary>
public const string AdvApi32 = "advapi32.dll";
/// <summary>The authz</summary>
public const string Authz = "authz.dll";
/// <summary>The COM CTL32</summary>
public const string ComCtl32 = "comctl32.dll";
/// <summary>The cred UI</summary>
public const string CredUI = "credui.dll";
/// <summary>The crypt32.dll</summary>
public const string Crypt32 = "crypt32.dll";
/// <summary>The DWM API</summary>
public const string DwmApi = "dwmapi.dll";
/// <summary>The gdi32</summary>
public const string Gdi32 = "gdi32.dll";
/// <summary>The gdi32</summary>
public const string IpHlpApi = "Iphlpapi.dll";
/// <summary>The kernel32</summary>
public const string Kernel32 = "kernel32.dll";
/// <summary>The kernel base</summary>
public const string KernelBase = "kernelbase.dll";
/// <summary>The MPR</summary>
public const string Mpr = "mpr.dll";
/// <summary>The mstask</summary>
public const string Mstask = "mstask.dll";
/// <summary>The net api32</summary>
public const string NetApi32 = "netapi32.dll";
/// <summary>The normaliz</summary>
public const string Normaliz = "normaliz.dll";
/// <summary>The nt DLL</summary>
public const string NtDll= "ntdll.dll";
public const string NtDll = "ntdll.dll";
/// <summary>The NTDS API</summary>
public const string NTDSApi = "ntdsapi.dll";
/// <summary>The ole32</summary>
public const string Ole32 = "ole32.dll";
/// <summary>The OLE aut32</summary>
public const string OleAut32 = "oleaut32.dll";
/// <summary>The property system</summary>
public const string PropSys = "propsys.dll";
/// <summary>The secur32</summary>
public const string Secur32 = "secur32.dll";
/// <summary>The shell32</summary>
public const string Shell32 = "shell32.dll";
/// <summary>The shlwapi</summary>
public const string Shlwapi = "Shlwapi.dll";
/// <summary>The user32</summary>
public const string User32 = "user32.dll";
/// <summary>The ux theme</summary>
public const string UxTheme = "uxtheme.dll";
/// <summary>The vertdll</summary>
public const string VertDll = "vertdll.dll";
/// <summary>The virt disk</summary>
public const string VirtDisk = "virtdisk.dll";
/// <summary>The win inet</summary>
public const string WinInet = "wininet.dll";
}

View File

@ -3,36 +3,43 @@
namespace Vanara.PInvoke
{
/// <summary>
/// The STGM constants are flags that indicate conditions for creating and deleting the object and access modes for the object. The STGM constants are included in the IStorage, IStream, and IPropertySetStorage interfaces and in the StgCreateDocfile, StgCreateStorageEx, StgCreateDocfileOnILockBytes, StgOpenStorage, and StgOpenStorageEx functions.
/// <para>These elements are often combined using an OR operator. They are interpreted in groups as listed in the following table. It is not valid to use more than one element from a single group.</para>
/// <para>Use a flag from the creation group when creating an object, such as with StgCreateStorageEx or IStorage::CreateStream.</para></summary>
/// The STGM constants are flags that indicate conditions for creating and deleting the object and access modes for the object. The STGM
/// constants are included in the IStorage, IStream, and IPropertySetStorage interfaces and in the StgCreateDocfile, StgCreateStorageEx,
/// StgCreateDocfileOnILockBytes, StgOpenStorage, and StgOpenStorageEx functions.
/// <para>
/// These elements are often combined using an OR operator. They are interpreted in groups as listed in the following table. It is not
/// valid to use more than one element from a single group.
/// </para>
/// <para>Use a flag from the creation group when creating an object, such as with StgCreateStorageEx or IStorage::CreateStream.</para>
/// </summary>
[Flags]
[PInvokeData("ObjBase.h", MSDNShortId = "aa380337")]
public enum STGM
{
/// <summary>
/// Indicates that the object is read-only, meaning that modifications cannot be made. For example, if a stream object is opened with STGM_READ, the
/// ISequentialStream::Read method may be called, but the ISequentialStream::Write method may not. Similarly, if a storage object opened with
/// STGM_READ, the IStorage::OpenStream and IStorage::OpenStorage methods may be called, but the IStorage::CreateStream and IStorage::CreateStorage
/// methods may not.
/// Indicates that the object is read-only, meaning that modifications cannot be made. For example, if a stream object is opened with
/// STGM_READ, the ISequentialStream::Read method may be called, but the ISequentialStream::Write method may not. Similarly, if a
/// storage object opened with STGM_READ, the IStorage::OpenStream and IStorage::OpenStorage methods may be called, but the
/// IStorage::CreateStream and IStorage::CreateStorage methods may not.
/// </summary>
STGM_READ = 0x00000000,
/// <summary>
/// Enables you to save changes to the object, but does not permit access to its data. The provided implementations of the IPropertyStorage and
/// IPropertySetStorage interfaces do not support this write-only mode.
/// Enables you to save changes to the object, but does not permit access to its data. The provided implementations of the
/// IPropertyStorage and IPropertySetStorage interfaces do not support this write-only mode.
/// </summary>
STGM_WRITE = 0x00000001,
/// <summary>
/// Enables access and modification of object data. For example, if a stream object is created or opened in this mode, it is possible to call both
/// IStream::Read and IStream::Write. Be aware that this constant is not a simple binary OR operation of the STGM_WRITE and STGM_READ elements.
/// Enables access and modification of object data. For example, if a stream object is created or opened in this mode, it is possible
/// to call both IStream::Read and IStream::Write. Be aware that this constant is not a simple binary OR operation of the STGM_WRITE
/// and STGM_READ elements.
/// </summary>
STGM_READWRITE = 0x00000002,
/// <summary>
/// Specifies that subsequent openings of the object are not denied read or write access. If no flag from the sharing group is specified, this flag
/// is assumed.
/// Specifies that subsequent openings of the object are not denied read or write access. If no flag from the sharing group is
/// specified, this flag is assumed.
/// </summary>
STGM_SHARE_DENY_NONE = 0x00000040,
@ -41,30 +48,32 @@ namespace Vanara.PInvoke
/// <summary>
/// Prevents others from subsequently opening the object for STGM_WRITE or STGM_READWRITE access. In transacted mode, sharing of
/// STGM_SHARE_DENY_WRITE or STGM_SHARE_EXCLUSIVE can significantly improve performance because they do not require snapshots. For more information
/// about transactioning, see the Remarks section.
/// STGM_SHARE_DENY_WRITE or STGM_SHARE_EXCLUSIVE can significantly improve performance because they do not require snapshots. For
/// more information about transactioning, see the Remarks section.
/// </summary>
STGM_SHARE_DENY_WRITE = 0x00000020,
/// <summary>
/// Prevents others from subsequently opening the object in any mode. Be aware that this value is not a simple bitwise OR operation of the
/// STGM_SHARE_DENY_READ and STGM_SHARE_DENY_WRITE values. In transacted mode, sharing of STGM_SHARE_DENY_WRITE or STGM_SHARE_EXCLUSIVE can
/// significantly improve performance because they do not require snapshots. For more information about transactioning, see the Remarks section.
/// Prevents others from subsequently opening the object in any mode. Be aware that this value is not a simple bitwise OR operation
/// of the STGM_SHARE_DENY_READ and STGM_SHARE_DENY_WRITE values. In transacted mode, sharing of STGM_SHARE_DENY_WRITE or
/// STGM_SHARE_EXCLUSIVE can significantly improve performance because they do not require snapshots. For more information about
/// transactioning, see the Remarks section.
/// </summary>
STGM_SHARE_EXCLUSIVE = 0x00000010,
/// <summary>
/// Opens the storage object with exclusive access to the most recently committed version. Thus, other users cannot commit changes to the object
/// while you have it open in priority mode. You gain performance benefits for copy operations, but you prevent others from committing changes. Limit
/// the time that objects are open in priority mode. You must specify STGM_DIRECT and STGM_READ with priority mode, and you cannot specify
/// STGM_DELETEONRELEASE. STGM_DELETEONRELEASE is only valid when creating a root object, such as with StgCreateStorageEx. It is not valid when
/// opening an existing root object, such as with StgOpenStorageEx. It is also not valid when creating or opening a subelement, such as with IStorage::OpenStorage.
/// Opens the storage object with exclusive access to the most recently committed version. Thus, other users cannot commit changes to
/// the object while you have it open in priority mode. You gain performance benefits for copy operations, but you prevent others
/// from committing changes. Limit the time that objects are open in priority mode. You must specify STGM_DIRECT and STGM_READ with
/// priority mode, and you cannot specify STGM_DELETEONRELEASE. STGM_DELETEONRELEASE is only valid when creating a root object, such
/// as with StgCreateStorageEx. It is not valid when opening an existing root object, such as with StgOpenStorageEx. It is also not
/// valid when creating or opening a subelement, such as with IStorage::OpenStorage.
/// </summary>
STGM_PRIORITY = 0x00040000,
/// <summary>
/// Indicates that an existing storage object or stream should be removed before the new object replaces it. A new object is created when this flag
/// is specified only if the existing object has been successfully removed.
/// Indicates that an existing storage object or stream should be removed before the new object replaces it. A new object is created
/// when this flag is specified only if the existing object has been successfully removed.
/// <para>This flag is used when attempting to create:</para>
/// <para>* A storage object on a disk, but a file of that name exists.</para>
/// <para>* An object inside a storage object, but an object with the specified name exists.</para>
@ -74,55 +83,58 @@ namespace Vanara.PInvoke
STGM_CREATE = 0x00001000,
/// <summary>
/// Creates the new object while preserving existing data in a stream named "Contents". In the case of a storage object or a byte array, the old data
/// is formatted into a stream regardless of whether the existing file or byte array currently contains a layered storage object. This flag can only
/// be used when creating a root storage object. It cannot be used within a storage object; for example, in IStorage::CreateStream. It is also not
/// valid to use this flag and the STGM_DELETEONRELEASE flag simultaneously.
/// Creates the new object while preserving existing data in a stream named "Contents". In the case of a storage object or a byte
/// array, the old data is formatted into a stream regardless of whether the existing file or byte array currently contains a layered
/// storage object. This flag can only be used when creating a root storage object. It cannot be used within a storage object; for
/// example, in IStorage::CreateStream. It is also not valid to use this flag and the STGM_DELETEONRELEASE flag simultaneously.
/// </summary>
STGM_CONVERT = 0x00020000,
/// <summary>
/// Causes the create operation to fail if an existing object with the specified name exists. In this case, STG_E_FILEALREADYEXISTS is returned. This
/// is the default creation mode; that is, if no other create flag is specified, STGM_FAILIFTHERE is implied.
/// Causes the create operation to fail if an existing object with the specified name exists. In this case, STG_E_FILEALREADYEXISTS
/// is returned. This is the default creation mode; that is, if no other create flag is specified, STGM_FAILIFTHERE is implied.
/// </summary>
STGM_FAILIFTHERE = 0x00000000,
/// <summary>
/// Indicates that, in direct mode, each change to a storage or stream element is written as it occurs. This is the default if neither STGM_DIRECT
/// nor STGM_TRANSACTED is specified.
/// Indicates that, in direct mode, each change to a storage or stream element is written as it occurs. This is the default if
/// neither STGM_DIRECT nor STGM_TRANSACTED is specified.
/// </summary>
STGM_DIRECT = 0x00000000,
/// <summary>
/// Indicates that, in transacted mode, changes are buffered and written only if an explicit commit operation is called. To ignore the changes, call
/// the Revert method in the IStream, IStorage, or IPropertyStorage interface. The COM compound file implementation of IStorage does not support
/// transacted streams, which means that streams can be opened only in direct mode, and you cannot revert changes to them, however transacted
/// storages are supported. The compound file, stand-alone, and NTFS file system implementations of IPropertySetStorage similarly do not support
/// transacted, simple property sets because these property sets are stored in streams. However, transactioning of nonsimple property sets, which can
/// be created by specifying the PROPSETFLAG_NONSIMPLE flag in the grfFlags parameter of IPropertySetStorage::Create, are supported.
/// Indicates that, in transacted mode, changes are buffered and written only if an explicit commit operation is called. To ignore
/// the changes, call the Revert method in the IStream, IStorage, or IPropertyStorage interface. The COM compound file implementation
/// of IStorage does not support transacted streams, which means that streams can be opened only in direct mode, and you cannot
/// revert changes to them, however transacted storages are supported. The compound file, stand-alone, and NTFS file system
/// implementations of IPropertySetStorage similarly do not support transacted, simple property sets because these property sets are
/// stored in streams. However, transactioning of nonsimple property sets, which can be created by specifying the
/// PROPSETFLAG_NONSIMPLE flag in the grfFlags parameter of IPropertySetStorage::Create, are supported.
/// </summary>
STGM_TRANSACTED = 0x00010000,
/// <summary>
/// Indicates that, in transacted mode, a temporary scratch file is usually used to save modifications until the Commit method is called. Specifying
/// STGM_NOSCRATCH permits the unused portion of the original file to be used as work space instead of creating a new file for that purpose. This
/// does not affect the data in the original file, and in certain cases can result in improved performance. It is not valid to specify this flag
/// without also specifying STGM_TRANSACTED, and this flag may only be used in a root open. For more information about NoScratch mode, see the
/// Remarks section.
/// Indicates that, in transacted mode, a temporary scratch file is usually used to save modifications until the Commit method is
/// called. Specifying STGM_NOSCRATCH permits the unused portion of the original file to be used as work space instead of creating a
/// new file for that purpose. This does not affect the data in the original file, and in certain cases can result in improved
/// performance. It is not valid to specify this flag without also specifying STGM_TRANSACTED, and this flag may only be used in a
/// root open. For more information about NoScratch mode, see the Remarks section.
/// </summary>
STGM_NOSCRATCH = 0x00100000,
/// <summary>
/// This flag is used when opening a storage object with STGM_TRANSACTED and without STGM_SHARE_EXCLUSIVE or STGM_SHARE_DENY_WRITE. In this case,
/// specifying STGM_NOSNAPSHOT prevents the system-provided implementation from creating a snapshot copy of the file. Instead, changes to the file
/// are written to the end of the file. Unused space is not reclaimed unless consolidation is performed during the commit, and there is only one
/// current writer on the file. When the file is opened in no snapshot mode, another open operation cannot be performed without specifying
/// STGM_NOSNAPSHOT. This flag may only be used in a root open operation. For more information about NoSnapshot mode, see the Remarks section.
/// This flag is used when opening a storage object with STGM_TRANSACTED and without STGM_SHARE_EXCLUSIVE or STGM_SHARE_DENY_WRITE.
/// In this case, specifying STGM_NOSNAPSHOT prevents the system-provided implementation from creating a snapshot copy of the file.
/// Instead, changes to the file are written to the end of the file. Unused space is not reclaimed unless consolidation is performed
/// during the commit, and there is only one current writer on the file. When the file is opened in no snapshot mode, another open
/// operation cannot be performed without specifying STGM_NOSNAPSHOT. This flag may only be used in a root open operation. For more
/// information about NoSnapshot mode, see the Remarks section.
/// </summary>
STGM_NOSNAPSHOT = 0x00200000,
/// <summary>
/// Provides a faster implementation of a compound file in a limited, but frequently used, case. For more information, see the Remarks section.
/// Provides a faster implementation of a compound file in a limited, but frequently used, case. For more information, see the
/// Remarks section.
/// </summary>
STGM_SIMPLE = 0x08000000,
@ -130,10 +142,10 @@ namespace Vanara.PInvoke
STGM_DIRECT_SWMR = 0x00400000,
/// <summary>
/// Indicates that the underlying file is to be automatically destroyed when the root storage object is released. This feature is most useful for
/// creating temporary files. This flag can only be used when creating a root object, such as with StgCreateStorageEx. It is not valid when opening a
/// root object, such as with StgOpenStorageEx, or when creating or opening a subelement, such as with IStorage::CreateStream. It is also not valid
/// to use this flag and the STGM_CONVERT flag simultaneously.
/// Indicates that the underlying file is to be automatically destroyed when the root storage object is released. This feature is
/// most useful for creating temporary files. This flag can only be used when creating a root object, such as with
/// StgCreateStorageEx. It is not valid when opening a root object, such as with StgOpenStorageEx, or when creating or opening a
/// subelement, such as with IStorage::CreateStream. It is also not valid to use this flag and the STGM_CONVERT flag simultaneously.
/// </summary>
STGM_DELETEONRELEASE = 0x04000000,
}

View File

@ -8,22 +8,31 @@ namespace Vanara.PInvoke
{
/// <summary>No minimum (default).</summary>
None = 0,
/// <summary>Windows 2000</summary>
Windows2000 = 0x1,
/// <summary>Windows XP</summary>
WindowsXP = 0x3,
/// <summary>Windows XP SP2</summary>
WindowsXP_SP2 = 0x7,
/// <summary>Windows Vista</summary>
WindowsVista = 0xF,
/// <summary>Windows Vista SP2</summary>
WindowsVista_SP2 = 0x1F,
/// <summary>Windows 7</summary>
Windows7 = 0x3F,
/// <summary>Windows 8</summary>
Windows8 = 0x7F,
/// <summary>Windows 8.1</summary>
Windows81 = 0xFF,
/// <summary>Windows 10</summary>
Windows10 = 0x1FF
}
@ -37,10 +46,7 @@ namespace Vanara.PInvoke
{
/// <summary>Initializes a new instance of the <see cref="PInvokeDataAttribute"/> class.</summary>
/// <param name="header">The header.</param>
public PInvokeDataAttribute(string header)
{
Header = header;
}
public PInvokeDataAttribute(string header) => Header = header;
/// <summary>Gets or sets the DLL in which this element is defined.</summary>
/// <value>The DLL file name without the path (e.g. "advapi32.dll").</value>

View File

@ -8,111 +8,160 @@ namespace Vanara.PInvoke
{
/// <summary>The SHTDN reason flag comment required</summary>
SHTDN_REASON_FLAG_COMMENT_REQUIRED = 0x01000000,
/// <summary>The SHTDN reason flag dirty problem identifier required</summary>
SHTDN_REASON_FLAG_DIRTY_PROBLEM_ID_REQUIRED = 0x02000000,
/// <summary>The SHTDN reason flag clean UI</summary>
SHTDN_REASON_FLAG_CLEAN_UI = 0x04000000,
/// <summary>The SHTDN reason flag dirty UI</summary>
SHTDN_REASON_FLAG_DIRTY_UI = 0x08000000,
/// <summary>The SHTDN reason flag mobile UI reserved</summary>
SHTDN_REASON_FLAG_MOBILE_UI_RESERVED = 0x10000000,
/// <summary>
/// The reason code is defined by the user. For more information, see Defining a Custom Reason Code. If this flag is not present, the reason code is
/// defined by the system.
/// The reason code is defined by the user. For more information, see Defining a Custom Reason Code. If this flag is not present, the
/// reason code is defined by the system.
/// </summary>
SHTDN_REASON_FLAG_USER_DEFINED = 0x40000000,
/// <summary>
/// The shutdown was planned. The system generates a System State Data (SSD) file. This file contains system state information such as the processes,
/// threads, memory usage, and configuration.
/// The shutdown was planned. The system generates a System State Data (SSD) file. This file contains system state information such
/// as the processes, threads, memory usage, and configuration.
/// <para>
/// If this flag is not present, the shutdown was unplanned. Notification and reporting options are controlled by a set of policies. For example,
/// after logging in, the system displays a dialog box reporting the unplanned shutdown if the policy has been enabled. An SSD file is created only
/// if the SSD policy is enabled on the system. The administrator can use Windows Error Reporting to send the SSD data to a central location, or to Microsoft.
/// If this flag is not present, the shutdown was unplanned. Notification and reporting options are controlled by a set of policies.
/// For example, after logging in, the system displays a dialog box reporting the unplanned shutdown if the policy has been enabled.
/// An SSD file is created only if the SSD policy is enabled on the system. The administrator can use Windows Error Reporting to send
/// the SSD data to a central location, or to Microsoft.
/// </para>
/// </summary>
SHTDN_REASON_FLAG_PLANNED = 0x80000000,
/// <summary>Other issue.</summary>
SHTDN_REASON_MAJOR_OTHER = 0x00000000,
/// <summary>No issue.</summary>
SHTDN_REASON_MAJOR_NONE = 0x00000000,
/// <summary>Hardware issue.</summary>
SHTDN_REASON_MAJOR_HARDWARE = 0x00010000,
/// <summary>Operating system issue.</summary>
SHTDN_REASON_MAJOR_OPERATINGSYSTEM = 0x00020000,
/// <summary>Software issue.</summary>
SHTDN_REASON_MAJOR_SOFTWARE = 0x00030000,
/// <summary>Application issue.</summary>
SHTDN_REASON_MAJOR_APPLICATION = 0x00040000,
/// <summary>System failure.</summary>
SHTDN_REASON_MAJOR_SYSTEM = 0x00050000,
/// <summary>Power failure.</summary>
SHTDN_REASON_MAJOR_POWER = 0x00060000,
/// <summary>The InitiateSystemShutdown function was used instead of InitiateSystemShutdownEx.</summary>
SHTDN_REASON_MAJOR_LEGACY_API = 0x00070000,
/// <summary>Other issue.</summary>
SHTDN_REASON_MINOR_OTHER = 0x00000000,
/// <summary>The SHTDN reason minor none</summary>
SHTDN_REASON_MINOR_NONE = 0x000000ff,
/// <summary>Maintenance.</summary>
SHTDN_REASON_MINOR_MAINTENANCE = 0x00000001,
/// <summary>Installation.</summary>
SHTDN_REASON_MINOR_INSTALLATION = 0x00000002,
/// <summary>Upgrade.</summary>
SHTDN_REASON_MINOR_UPGRADE = 0x00000003,
/// <summary>Reconfigure.</summary>
SHTDN_REASON_MINOR_RECONFIG = 0x00000004,
/// <summary>Unresponsive.</summary>
SHTDN_REASON_MINOR_HUNG = 0x00000005,
/// <summary>Unstable.</summary>
SHTDN_REASON_MINOR_UNSTABLE = 0x00000006,
/// <summary>Disk.</summary>
SHTDN_REASON_MINOR_DISK = 0x00000007,
/// <summary>Processor.</summary>
SHTDN_REASON_MINOR_PROCESSOR = 0x00000008,
/// <summary>Network card.</summary>
SHTDN_REASON_MINOR_NETWORKCARD = 0x00000009,
/// <summary>Power supply.</summary>
SHTDN_REASON_MINOR_POWER_SUPPLY = 0x0000000a,
/// <summary>Unplugged.</summary>
SHTDN_REASON_MINOR_CORDUNPLUGGED = 0x0000000b,
/// <summary>Environment.</summary>
SHTDN_REASON_MINOR_ENVIRONMENT = 0x0000000c,
/// <summary>Driver.</summary>
SHTDN_REASON_MINOR_HARDWARE_DRIVER = 0x0000000d,
/// <summary>Other driver event.</summary>
SHTDN_REASON_MINOR_OTHERDRIVER = 0x0000000e,
/// <summary>Blue screen crash event.</summary>
SHTDN_REASON_MINOR_BLUESCREEN = 0x0000000F,
/// <summary>Service pack.</summary>
SHTDN_REASON_MINOR_SERVICEPACK = 0x00000010,
/// <summary>Hot fix.</summary>
SHTDN_REASON_MINOR_HOTFIX = 0x00000011,
/// <summary>Security patch.</summary>
SHTDN_REASON_MINOR_SECURITYFIX = 0x00000012,
/// <summary>Security issue.</summary>
SHTDN_REASON_MINOR_SECURITY = 0x00000013,
/// <summary>Network connectivity.</summary>
SHTDN_REASON_MINOR_NETWORK_CONNECTIVITY = 0x00000014,
/// <summary>WMI issue.</summary>
SHTDN_REASON_MINOR_WMI = 0x00000015,
/// <summary>Service pack uninstallation.</summary>
SHTDN_REASON_MINOR_SERVICEPACK_UNINSTALL = 0x00000016,
/// <summary>Hot fix uninstallation.</summary>
SHTDN_REASON_MINOR_HOTFIX_UNINSTALL = 0x00000017,
/// <summary>Security patch uninstallation.</summary>
SHTDN_REASON_MINOR_SECURITYFIX_UNINSTALL = 0x00000018,
/// <summary>MMC issue.</summary>
SHTDN_REASON_MINOR_MMC = 0x00000019,
/// <summary>System restore.</summary>
SHTDN_REASON_MINOR_SYSTEMRESTORE = 0x0000001a,
/// <summary>Terminal Services.</summary>
SHTDN_REASON_MINOR_TERMSRV = 0x00000020,
/// <summary>DC promotion.</summary>
SHTDN_REASON_MINOR_DC_PROMOTION = 0x00000021,
/// <summary>DC demotion.</summary>
SHTDN_REASON_MINOR_DC_DEMOTION = 0x00000022,
/// <summary>Unknown.</summary>
SHTDN_REASON_UNKNOWN = SHTDN_REASON_MINOR_NONE,
/// <summary>The InitiateSystemShutdown function was used instead of InitiateSystemShutdownEx.</summary>
SHTDN_REASON_LEGACY_API = SHTDN_REASON_MAJOR_LEGACY_API | SHTDN_REASON_FLAG_PLANNED
}

View File

@ -4,8 +4,6 @@ using Vanara.Extensions;
using Vanara.InteropServices;
using static Vanara.PInvoke.Macros;
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
/// <summary>Predefined resource types.</summary>
@ -30,8 +28,8 @@ namespace Vanara.PInvoke
RT_DIALOG = 5,
/// <summary>
/// Allows a resource editing tool to associate a string with an .rc file. Typically, the string is the name of the header file that provides
/// symbolic names. The resource compiler parses the string but otherwise ignores the value.
/// Allows a resource editing tool to associate a string with an .rc file. Typically, the string is the name of the header file that
/// provides symbolic names. The resource compiler parses the string but otherwise ignores the value.
/// </summary>
RT_DLGINCLUDE = 17,
@ -78,17 +76,11 @@ namespace Vanara.PInvoke
RT_VXD = 20,
}
/* ===================================================================================
* Removing struct based ResourceId as they can cause resource leaks with improper
* use. Opted for using IntPtr in structs and SafeResourceId in functions.
* ===================================================================================
*
/// <summary>Helper structure to use for a pointer that can morph into a string, pointer or integer.</summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct ResourceId : IEquatable<string>, IEquatable<IntPtr>, IEquatable<int>, IEquatable<ResourceId>
public struct ResourceId : IEquatable<string>, IEquatable<IntPtr>, IEquatable<int>, IEquatable<ResourceId>, IHandle
{
/// <summary>The PTR</summary>
public IntPtr ptr;
private IntPtr ptr;
/// <summary>Gets or sets an integer identifier.</summary>
/// <value>The identifier.</value>
@ -103,9 +95,9 @@ namespace Vanara.PInvoke
}
/// <summary>Represent a NULL value.</summary>
public static readonly ResourceId Null = new ResourceId();
public static readonly ResourceId NULL = new ResourceId();
/// <summary>Performs an implicit conversion from <see cref="ResourceId"/> to <see cref="int"/>.</summary>
/// <summary>Performs an implicit conversion from <see cref="SafeResourceId"/> to <see cref="System.Int32"/>.</summary>
/// <param name="r">The r.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator int(ResourceId r) => r.id;
@ -115,11 +107,6 @@ namespace Vanara.PInvoke
/// <returns>The result of the conversion.</returns>
public static implicit operator IntPtr(ResourceId r) => r.ptr;
/// <summary>Performs an implicit conversion from <see cref="string"/> to <see cref="ResourceId"/>.</summary>
/// <param name="resName">Name of the resource.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator ResourceId(string resName) => new ResourceId { ptr = StringHelper.AllocString(resName) };
/// <summary>Performs an implicit conversion from <see cref="int"/> to <see cref="ResourceId"/>.</summary>
/// <param name="resId">The resource identifier.</param>
/// <returns>The result of the conversion.</returns>
@ -138,7 +125,7 @@ namespace Vanara.PInvoke
/// <summary>Performs an implicit conversion from <see cref="ResourceId"/> to <see cref="string"/>.</summary>
/// <param name="r">The r.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator string(ResourceId r) => r.ToString();
public static explicit operator string(ResourceId r) => r.ToString();
/// <summary>Determines whether the specified <see cref="System.Object"/>, is equal to this instance.</summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
@ -197,129 +184,14 @@ namespace Vanara.PInvoke
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
/// <exception cref="NotImplementedException"></exception>
bool IEquatable<ResourceId>.Equals(ResourceId other) => string.Equals(other.ToString(), ToString());
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => ptr;
}
/// <summary>Helper structure to use for a pointer that can morph into a string, pointer or integer.</summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct ResourceIdUni : IEquatable<string>, IEquatable<IntPtr>, IEquatable<int>, IEquatable<ResourceIdUni>
{
/// <summary>The PTR</summary>
public IntPtr ptr;
/// <summary>Gets or sets an integer identifier.</summary>
/// <value>The identifier.</value>
public int id
{
get => IS_INTRESOURCE(ptr) ? (ushort)ptr.ToInt32() : 0;
set
{
if (value > ushort.MaxValue || value <= 0) throw new ArgumentOutOfRangeException(nameof(id));
ptr = (IntPtr)(ushort)value;
}
}
/// <summary>Represent a NULL value.</summary>
public static readonly ResourceIdUni Null = new ResourceIdUni();
/// <summary>Performs an implicit conversion from <see cref="ResourceIdUni"/> to <see cref="int"/>.</summary>
/// <param name="r">The r.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator int(ResourceIdUni r) => r.id;
/// <summary>Performs an implicit conversion from <see cref="ResourceIdUni"/> to <see cref="IntPtr"/>.</summary>
/// <param name="r">The r.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator IntPtr(ResourceIdUni r) => r.ptr;
/// <summary>Performs an implicit conversion from <see cref="string"/> to <see cref="ResourceIdUni"/>.</summary>
/// <param name="resName">Name of the resource.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator ResourceIdUni(string resName) => new ResourceIdUni { ptr = StringHelper.AllocString(resName, CharSet.Unicode) };
/// <summary>Performs an implicit conversion from <see cref="int"/> to <see cref="ResourceIdUni"/>.</summary>
/// <param name="resId">The resource identifier.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator ResourceIdUni(int resId) => new ResourceIdUni { id = resId };
/// <summary>Performs an implicit conversion from <see cref="ResourceType"/> to <see cref="ResourceIdUni"/>.</summary>
/// <param name="resType">Type of the resource.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator ResourceIdUni(ResourceType resType) => new ResourceIdUni { id = (int)resType };
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="ResourceIdUni"/>.</summary>
/// <param name="p">The PTR.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator ResourceIdUni(IntPtr p) => new ResourceIdUni { ptr = p };
/// <summary>Performs an implicit conversion from <see cref="ResourceIdUni"/> to <see cref="string"/>.</summary>
/// <param name="r">The r.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator string(ResourceIdUni r) => r.ToString();
/// <summary>Determines whether the specified <see cref="System.Object"/>, is equal to this instance.</summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
switch (obj)
{
case null:
return false;
case string s:
return Equals(s);
case int i:
return Equals(i);
case IntPtr p:
return Equals(p);
case ResourceIdUni r:
return Equals(r);
default:
if (!obj.GetType().IsPrimitive) return false;
try { return Equals(Convert.ToInt32(obj)); } catch { return false; }
}
}
/// <summary>Returns a hash code for this instance.</summary>
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
public override int GetHashCode() => ptr.GetHashCode();
/// <summary>Returns a <see cref="string"/> that represents this instance.</summary>
/// <returns>A <see cref="string"/> that represents this instance.</returns>
public override string ToString() => IS_INTRESOURCE(ptr) ? $"#{ptr.ToInt32()}" : Marshal.PtrToStringUni(ptr);
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
bool IEquatable<int>.Equals(int other) => ptr.ToInt32().Equals(other);
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
/// <exception cref="NotImplementedException"></exception>
bool IEquatable<string>.Equals(string other) => string.Equals(ToString(), other);
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
bool IEquatable<IntPtr>.Equals(IntPtr other) => ptr.Equals(other);
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
/// <exception cref="NotImplementedException"></exception>
bool IEquatable<ResourceIdUni>.Equals(ResourceIdUni other) => string.Equals(other.ToString(), ToString());
}
*/
/// <summary>Represents a system resource name that can identify as a string, integer, or pointer.</summary>
/// <seealso cref="SafeHandle"/>
public class SafeResourceId : GenericSafeHandle, IEquatable<string>, IEquatable<int>, IEquatable<SafeResourceId>, IEquatable<IntPtr>
public class SafeResourceId : GenericSafeHandle, IEquatable<string>, IEquatable<int>, IEquatable<SafeResourceId>, IEquatable<ResourceId>, IEquatable<IntPtr>, IHandle
{
/// <summary>Represent a NULL value.</summary>
public static readonly SafeResourceId Null = new SafeResourceId();
@ -380,25 +252,31 @@ namespace Vanara.PInvoke
}
}
/// <inheritdoc/>
public override bool IsInvalid => handle == IntPtr.Zero;
/// <summary>Gets a value indicating whether this instance is an integer-based resource.</summary>
/// <value><c>true</c> if this instance is an integer-based resource; otherwise, <c>false</c>.</value>
public bool IsIntResource => IS_INTRESOURCE(handle);
/// <inheritdoc/>
public override bool IsInvalid => handle == IntPtr.Zero;
/// <inheritdoc/>
protected override Func<IntPtr, bool> CloseMethod => h => { if (h != IntPtr.Zero && !IS_INTRESOURCE(h)) StringHelper.FreeString(h); return true; };
/// <summary>Gets the string representation of a resource identifier.</summary>
/// <param name="ptr">The resource identifier.</param>
/// <param name="charSet">The character set.</param>
/// <returns>The string representation.</returns>
public static string GetString(IntPtr ptr, CharSet charSet = CharSet.Auto) => IS_INTRESOURCE(ptr) ? $"#{ptr.ToInt32()}" : StringHelper.GetString(ptr, charSet);
/// <summary>Performs an implicit conversion from <see cref="SafeResourceId"/> to <see cref="System.Int32"/>.</summary>
/// <param name="r">The r.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator int(SafeResourceId r) => r.IsIntResource ? (ushort)r.handle.ToInt32() : 0;
/// <summary>Performs an implicit conversion from <see cref="SafeResourceId"/> to <see cref="IntPtr"/>.</summary>
/// <param name="r">The r.</param>
/// <summary>Performs an implicit conversion from <see cref="SafeResourceId"/> to <see cref="ResourceId"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator IntPtr(SafeResourceId r) => r.handle;
public static implicit operator ResourceId(SafeResourceId h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="string"/> to <see cref="SafeResourceId"/>.</summary>
/// <param name="resName">Name of the resource.</param>
@ -435,6 +313,9 @@ namespace Vanara.PInvoke
case null:
return false;
case ResourceId resId:
return Equals(resId);
case string s:
return Equals(s);
@ -456,12 +337,8 @@ namespace Vanara.PInvoke
/// <summary>
/// Gets a cloned handle that also, if a string resource, copies the string to a new handle which must be released using StringHelper.FreeString.
/// </summary>
/// <returns>A copy of the handle. Warning: This method can cause memory leaks if this is a string resource which is not freed.</returns>
public IntPtr GetClonedHandle()
{
if (IsIntResource || IsIntResource) return handle;
return StringHelper.AllocString(StringHelper.GetString(handle, CharSet), CharSet);
}
/// <returns>A safe copy of this resource id.</returns>
public SafeResourceId Clone() => new SafeResourceId(handle);
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
@ -487,12 +364,11 @@ namespace Vanara.PInvoke
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
bool IEquatable<IntPtr>.Equals(IntPtr other) => new SafeResourceId(other).Equals(this);
bool IEquatable<ResourceId>.Equals(ResourceId other) => other.Equals((ResourceId)this);
/// <summary>Gets the string representation of a resource identifier.</summary>
/// <param name="ptr">The resource identifier.</param>
/// <param name="charSet">The character set.</param>
/// <returns>The string representation.</returns>
public static string GetString(IntPtr ptr, CharSet charSet = CharSet.Auto) => IS_INTRESOURCE(ptr) ? $"#{ptr.ToInt32()}" : StringHelper.GetString(ptr, charSet);
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
bool IEquatable<IntPtr>.Equals(IntPtr other) => new SafeResourceId(other).Equals(this);
}
}

View File

@ -59,7 +59,7 @@ namespace Vanara.PInvoke
/// <summary>Performs an implicit conversion from <see cref="SizeT"/> to <see cref="System.UInt64"/>.</summary>
/// <param name="value">The value.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator ulong(SizeT value) => (ulong)value.Value;
public static implicit operator ulong(SizeT value) => value.Value;
/// <inheritdoc/>
public int CompareTo(SizeT other) => Value.CompareTo(other.Value);

View File

@ -12,7 +12,8 @@
<Copyright>Copyright © 2017-2018</Copyright>
<AssemblyTitle>$(AssemblyName)</AssemblyTitle>
<VersionPrefix>2.0.0</VersionPrefix>
<TargetFrameworks>net20;net35;net40;net45;netstandard20</TargetFrameworks>
<!--<TargetFramework>netstandard20</TargetFramework>-->
<TargetFrameworks>net20;net35;net40;net45;netstandard2.0</TargetFrameworks>
<AssemblyName>Vanara.PInvoke.Shared</AssemblyName>
<PackageId>$(AssemblyName)</PackageId>
<RootNamespace>Vanara.PInvoke</RootNamespace>
@ -39,7 +40,6 @@ COLORREF, HRESULT, LOGFONT, MSG, NTStatus, OBJECT_TYPE_LIST, POINTS, PRECT, RECT
Enumerations
ACCESS_MASK, DrawTextFlags, FacilityCode, FacilityCode, FileFlagsAndAttributes, FontFamily, FontPitch, LogFontCharSet, LogFontClippingPrecision, LogFontOutputPrecision, LogFontOutputQuality, ObjectTypeListLevel, PInvokeClient, ProcessorArchitecture, ResourceType, SECURITY_INFORMATION, SeverityLevel, SeverityLevel, ShowWindowCommand, STGM, SystemShutDownReason
</PackageReleaseNotes>
<LangVersion>latest</LangVersion>
</PropertyGroup>
@ -65,4 +65,9 @@ ACCESS_MASK, DrawTextFlags, FacilityCode, FacilityCode, FileFlagsAndAttributes,
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
<Reference Include="System" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="Microsoft.Win32.Registry">
<Version>4.5.0</Version>
</PackageReference>
</ItemGroup>
</Project>

View File

@ -4,28 +4,27 @@ using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
/// <summary>
/// The SECURITY_ATTRIBUTES structure contains the security descriptor for an object and specifies whether the handle retrieved by specifying this
/// structure is inheritable. This structure provides security settings for objects created by various functions, such as CreateFile, CreatePipe,
/// CreateProcess, RegCreateKeyEx, or RegSaveKeyEx.
/// The SECURITY_ATTRIBUTES structure contains the security descriptor for an object and specifies whether the handle retrieved by
/// specifying this structure is inheritable. This structure provides security settings for objects created by various functions, such as
/// CreateFile, CreatePipe, CreateProcess, RegCreateKeyEx, or RegSaveKeyEx.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
public class SECURITY_ATTRIBUTES
{
/// <summary>The size, in bytes, of this structure. Set this value to the size of the SECURITY_ATTRIBUTES structure.</summary>
public int nLength = Marshal.SizeOf(typeof(SECURITY_ATTRIBUTES));
/// <summary>
/// A pointer to a SECURITY_DESCRIPTOR structure that controls access to the object. If the value of this member is NULL, the object is assigned the
/// default security descriptor associated with the access token of the calling process. This is not the same as granting access to everyone by
/// assigning a NULL discretionary access control list (DACL). By default, the default DACL in the access token of a process allows access only to
/// the user represented by the access token.
/// A pointer to a SECURITY_DESCRIPTOR structure that controls access to the object. If the value of this member is NULL, the object
/// is assigned the default security descriptor associated with the access token of the calling process. This is not the same as
/// granting access to everyone by assigning a NULL discretionary access control list (DACL). By default, the default DACL in the
/// access token of a process allows access only to the user represented by the access token.
/// </summary>
public IntPtr lpSecurityDescriptor;
/// <summary>
/// A Boolean value that specifies whether the returned handle is inherited when a new process is created. If this member is TRUE, the new process
/// inherits the handle.
/// A Boolean value that specifies whether the returned handle is inherited when a new process is created. If this member is TRUE,
/// the new process inherits the handle.
/// </summary>
[MarshalAs(UnmanagedType.Bool)] public bool bInheritHandle;
}

View File

@ -6,11 +6,10 @@ using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
/// <summary>
/// Specifies a date and time, using individual members for the month, day, year, weekday, hour, minute, second, and millisecond. The time is either in
/// coordinated universal time (UTC) or local time, depending on the function that is being called.
/// Specifies a date and time, using individual members for the month, day, year, weekday, hour, minute, second, and millisecond. The
/// time is either in coordinated universal time (UTC) or local time, depending on the function that is being called.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 2)]
// ReSharper disable once InconsistentNaming
public struct SYSTEMTIME : IEquatable<SYSTEMTIME>, IComparable<SYSTEMTIME>
{
/// <summary>The year. The valid values for this member are 1601 through 30827.</summary>
@ -19,19 +18,58 @@ namespace Vanara.PInvoke
/// <summary>
/// The month. This member can be one of the following values.
/// <list type="table">
/// <listheader><term>Value</term><term>Meaning</term></listheader>
/// <item><term>1</term><term>January</term></item>
/// <item><term>2</term><term>February</term></item>
/// <item><term>3</term><term>March</term></item>
/// <item><term>4</term><term>April</term></item>
/// <item><term>5</term><term>May</term></item>
/// <item><term>6</term><term>June</term></item>
/// <item><term>7</term><term>July</term></item>
/// <item><term>8</term><term>August</term></item>
/// <item><term>9</term><term>September</term></item>
/// <item><term>10</term><term>October</term></item>
/// <item><term>11</term><term>November</term></item>
/// <item><term>12</term><term>December</term></item>
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>1</term>
/// <term>January</term>
/// </item>
/// <item>
/// <term>2</term>
/// <term>February</term>
/// </item>
/// <item>
/// <term>3</term>
/// <term>March</term>
/// </item>
/// <item>
/// <term>4</term>
/// <term>April</term>
/// </item>
/// <item>
/// <term>5</term>
/// <term>May</term>
/// </item>
/// <item>
/// <term>6</term>
/// <term>June</term>
/// </item>
/// <item>
/// <term>7</term>
/// <term>July</term>
/// </item>
/// <item>
/// <term>8</term>
/// <term>August</term>
/// </item>
/// <item>
/// <term>9</term>
/// <term>September</term>
/// </item>
/// <item>
/// <term>10</term>
/// <term>October</term>
/// </item>
/// <item>
/// <term>11</term>
/// <term>November</term>
/// </item>
/// <item>
/// <term>12</term>
/// <term>December</term>
/// </item>
/// </list>
/// </summary>
public ushort wMonth;
@ -39,14 +77,38 @@ namespace Vanara.PInvoke
/// <summary>
/// The day of the week. This member can be one of the following values.
/// <list type="table">
/// <listheader><term>Value</term><term>Meaning</term></listheader>
/// <item><term>0</term><term>Sunday</term></item>
/// <item><term>1</term><term>Monday</term></item>
/// <item><term>2</term><term>Tuesday</term></item>
/// <item><term>3</term><term>Wednesday</term></item>
/// <item><term>4</term><term>Thursday</term></item>
/// <item><term>5</term><term>Friday</term></item>
/// <item><term>6</term><term>Saturday</term></item>
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>Sunday</term>
/// </item>
/// <item>
/// <term>1</term>
/// <term>Monday</term>
/// </item>
/// <item>
/// <term>2</term>
/// <term>Tuesday</term>
/// </item>
/// <item>
/// <term>3</term>
/// <term>Wednesday</term>
/// </item>
/// <item>
/// <term>4</term>
/// <term>Thursday</term>
/// </item>
/// <item>
/// <term>5</term>
/// <term>Friday</term>
/// </item>
/// <item>
/// <term>6</term>
/// <term>Saturday</term>
/// </item>
/// </list>
/// </summary>
public ushort wDayOfWeek;
@ -69,8 +131,8 @@ namespace Vanara.PInvoke
private static readonly int[] DaysToMonth365 = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
private static readonly int[] DaysToMonth366 = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 };
/// <summary>Initializes a new instance of the <see cref="SYSTEMTIME" /> struct with a <see cref="DateTime" />.</summary>
/// <param name="dt">The <see cref="DateTime" /> value.</param>
/// <summary>Initializes a new instance of the <see cref="SYSTEMTIME"/> struct with a <see cref="DateTime"/>.</summary>
/// <param name="dt">The <see cref="DateTime"/> value.</param>
/// <param name="toKind">Indicates whether the <see cref="SYSTEMTIME"/> should represent the local, universal or unknown time.</param>
/// <exception cref="ArgumentOutOfRangeException">dt - Year value must be 1601 through 30827</exception>
public SYSTEMTIME(DateTime dt, DateTimeKind toKind = DateTimeKind.Unspecified)
@ -92,19 +154,58 @@ namespace Vanara.PInvoke
/// <param name="month">
/// The month. This member can be one of the following values.
/// <list type="table">
/// <listheader><term>Value</term><term>Meaning</term></listheader>
/// <item><term>1</term><term>January</term></item>
/// <item><term>2</term><term>February</term></item>
/// <item><term>3</term><term>March</term></item>
/// <item><term>4</term><term>April</term></item>
/// <item><term>5</term><term>May</term></item>
/// <item><term>6</term><term>June</term></item>
/// <item><term>7</term><term>July</term></item>
/// <item><term>8</term><term>August</term></item>
/// <item><term>9</term><term>September</term></item>
/// <item><term>10</term><term>October</term></item>
/// <item><term>11</term><term>November</term></item>
/// <item><term>12</term><term>December</term></item>
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>1</term>
/// <term>January</term>
/// </item>
/// <item>
/// <term>2</term>
/// <term>February</term>
/// </item>
/// <item>
/// <term>3</term>
/// <term>March</term>
/// </item>
/// <item>
/// <term>4</term>
/// <term>April</term>
/// </item>
/// <item>
/// <term>5</term>
/// <term>May</term>
/// </item>
/// <item>
/// <term>6</term>
/// <term>June</term>
/// </item>
/// <item>
/// <term>7</term>
/// <term>July</term>
/// </item>
/// <item>
/// <term>8</term>
/// <term>August</term>
/// </item>
/// <item>
/// <term>9</term>
/// <term>September</term>
/// </item>
/// <item>
/// <term>10</term>
/// <term>October</term>
/// </item>
/// <item>
/// <term>11</term>
/// <term>November</term>
/// </item>
/// <item>
/// <term>12</term>
/// <term>December</term>
/// </item>
/// </list>
/// </param>
/// <param name="day">The day of the month. The valid values for this member are 1 through 31.</param>
@ -225,9 +326,9 @@ namespace Vanara.PInvoke
/// <summary>Compares the current object with another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>
/// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value Meaning Less than zero
/// This object is less than the <paramref name="other"/> parameter.Zero This object is equal to <paramref name="other"/>. Greater than zero This object
/// is greater than <paramref name="other"/>.
/// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value
/// Meaning Less than zero This object is less than the <paramref name="other"/> parameter.Zero This object is equal to <paramref
/// name="other"/>. Greater than zero This object is greater than <paramref name="other"/>.
/// </returns>
public int CompareTo(SYSTEMTIME other) => Compare(this, other);

View File

@ -12,8 +12,7 @@ namespace Vanara.PInvoke
/// <summary>
/// The file attributes of a file.
/// <para>
/// For possible values and their descriptions, see <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/gg258117(v=vs.85).aspx">File
/// Attribute Constants</a>.
/// For possible values and their descriptions, see <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/gg258117(v=vs.85).aspx">File Attribute Constants</a>.
/// </para>
/// <para>The FILE_ATTRIBUTE_SPARSE_FILE attribute on the file is set if any of the streams of the file have ever been sparse.</para>
/// </summary>
@ -29,22 +28,24 @@ namespace Vanara.PInvoke
/// A FILETIME structure.
/// <para>For a file, the structure specifies when the file was last read from, written to, or for executable files, run.</para>
/// <para>
/// For a directory, the structure specifies when the directory is created. If the underlying file system does not support last access time, this member
/// is zero.
/// For a directory, the structure specifies when the directory is created. If the underlying file system does not support last
/// access time, this member is zero.
/// </para>
/// <para>
/// On the FAT file system, the specified date for both files and directories is correct, but the time of day is always set to midnight.
/// </para>
/// <para>On the FAT file system, the specified date for both files and directories is correct, but the time of day is always set to midnight.</para>
/// </summary>
public FILETIME ftLastAccessTime;
/// <summary>
/// A FILETIME structure.
/// <para>
/// For a file, the structure specifies when the file was last written to, truncated, or overwritten, for example, when WriteFile or SetEndOfFile are
/// used. The date and time are not updated when file attributes or security descriptors are changed.
/// For a file, the structure specifies when the file was last written to, truncated, or overwritten, for example, when WriteFile or
/// SetEndOfFile are used. The date and time are not updated when file attributes or security descriptors are changed.
/// </para>
/// <para>
/// For a directory, the structure specifies when the directory is created. If the underlying file system does not support last write time, this member
/// is zero.
/// For a directory, the structure specifies when the directory is created. If the underlying file system does not support last write
/// time, this member is zero.
/// </para>
/// </summary>
public FILETIME ftLastWriteTime;

View File

@ -1,12 +1,9 @@
using System.Runtime.InteropServices;
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
/// <summary>The COLORREF value is used to specify an RGB color in the form <c>0x00bbggrr</c>.</summary>
// typedef DWORD COLORREF;typedef DWORD* LPCOLORREF;
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd183449(v=vs.85).aspx
// typedef DWORD COLORREF;typedef DWORD* LPCOLORREF; https://msdn.microsoft.com/en-us/library/windows/desktop/dd183449(v=vs.85).aspx
[PInvokeData("Windef.h", MSDNShortId = "dd183449")]
[StructLayout(LayoutKind.Explicit, Size = 4)]
public struct COLORREF
@ -14,12 +11,15 @@ namespace Vanara.PInvoke
/// <summary>The DWORD value</summary>
[FieldOffset(0)]
private uint Value;
/// <summary>The intensity of the red color.</summary>
[FieldOffset(0)]
public byte R;
/// <summary>The intensity of the green color.</summary>
[FieldOffset(1)]
public byte G;
/// <summary>The intensity of the blue color.</summary>
[FieldOffset(2)]
public byte B;
@ -51,7 +51,7 @@ namespace Vanara.PInvoke
/// <summary>Initializes a new instance of the <see cref="COLORREF"/> struct.</summary>
/// <param name="color">The color.</param>
public COLORREF(System.Drawing.Color color) : this(color == System.Drawing.Color.Transparent ? (uint)CLR_NONE : (uint)color.ToArgb()) { }
public COLORREF(System.Drawing.Color color) : this(color == System.Drawing.Color.Transparent ? CLR_NONE : (uint)color.ToArgb()) { }
/// <summary>Performs an implicit conversion from <see cref="COLORREF"/> to <see cref="System.Drawing.Color"/>.</summary>
/// <param name="cr">The <see cref="COLORREF"/> value.</param>

View File

@ -42,20 +42,22 @@ namespace Vanara.PInvoke
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other" /> parameter; otherwise, false.</returns>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
public bool Equals(POINTS other) => x == other.x || y == other.y;
/// <summary>Determines whether the specified <see cref="object" />, is equal to this instance.</summary>
/// <param name="obj">The <see cref="object" /> to compare with this instance.</param>
/// <returns><c>true</c> if the specified <see cref="object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
/// <summary>Determines whether the specified <see cref="object"/>, is equal to this instance.</summary>
/// <param name="obj">The <see cref="object"/> to compare with this instance.</param>
/// <returns><c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
switch (obj)
{
case POINTS pt:
return Equals(pt);
case Point ptl:
return Equals((POINTS)ptl);
return Equals(ptl);
default:
return false;
}
@ -69,8 +71,8 @@ namespace Vanara.PInvoke
/// <returns>An equivalent <see cref="Point"/> structure.</returns>
public Point ToPoint() => this;
/// <summary>Returns a <see cref="string" /> that represents this instance.</summary>
/// <returns>A <see cref="string" /> that represents this instance.</returns>
/// <summary>Returns a <see cref="string"/> that represents this instance.</summary>
/// <returns>A <see cref="string"/> that represents this instance.</returns>
public override string ToString() => "{x=" + x.ToString(CultureInfo.CurrentCulture) + ", y=" + y.ToString(CultureInfo.CurrentCulture) + "}";
/// <summary>Performs an implicit conversion from <see cref="POINTS"/> to <see cref="Point"/>.</summary>

View File

@ -7,15 +7,14 @@ using System.Drawing;
using System.Globalization;
using System.Runtime.InteropServices;
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
/// <summary>Defines the coordinates of the upper-left and lower-right corners of a rectangle.</summary>
/// <remarks>
/// By convention, the right and bottom edges of the rectangle are normally considered exclusive. In other words, the pixel whose coordinates are ( right,
/// bottom ) lies immediately outside of the rectangle. For example, when RECT is passed to the FillRect function, the rectangle is filled up to, but not
/// including, the right column and bottom row of pixels. This structure is identical to the RECT structure.
/// By convention, the right and bottom edges of the rectangle are normally considered exclusive. In other words, the pixel whose
/// coordinates are ( right, bottom ) lies immediately outside of the rectangle. For example, when RECT is passed to the FillRect
/// function, the rectangle is filled up to, but not including, the right column and bottom row of pixels. This structure is identical to
/// the RECT structure.
/// </remarks>
[StructLayout(LayoutKind.Sequential), TypeConverter(typeof(RECTConverter))]
public struct RECT : IEquatable<PRECT>, IEquatable<RECT>, IEquatable<Rectangle>
@ -165,12 +164,16 @@ namespace Vanara.PInvoke
{
case null:
return false;
case RECT r:
return Equals(r);
case PRECT r:
return Equals(r);
case Rectangle r:
return Equals(r);
default:
return false;
}
@ -187,9 +190,10 @@ namespace Vanara.PInvoke
/// <summary>Defines the coordinates of the upper-left and lower-right corners of a rectangle.</summary>
/// <remarks>
/// By convention, the right and bottom edges of the rectangle are normally considered exclusive. In other words, the pixel whose coordinates are ( right,
/// bottom ) lies immediately outside of the rectangle. For example, when RECT is passed to the FillRect function, the rectangle is filled up to, but not
/// including, the right column and bottom row of pixels. This structure is identical to the RECT structure.
/// By convention, the right and bottom edges of the rectangle are normally considered exclusive. In other words, the pixel whose
/// coordinates are ( right, bottom ) lies immediately outside of the rectangle. For example, when RECT is passed to the FillRect
/// function, the rectangle is filled up to, but not including, the right column and bottom row of pixels. This structure is identical to
/// the RECT structure.
/// </remarks>
[StructLayout(LayoutKind.Sequential), TypeConverter(typeof(PRECTConverter))]
public class PRECT : IEquatable<PRECT>, IEquatable<RECT>, IEquatable<Rectangle>
@ -206,25 +210,16 @@ namespace Vanara.PInvoke
/// <param name="top">The top.</param>
/// <param name="right">The right.</param>
/// <param name="bottom">The bottom.</param>
public PRECT(int left, int top, int right, int bottom)
{
rect = new RECT(left, top, right, bottom);
}
public PRECT(int left, int top, int right, int bottom) => rect = new RECT(left, top, right, bottom);
/// <summary>Initializes a new instance of the <see cref="PRECT"/> class.</summary>
/// <param name="r">The <see cref="Rectangle"/> structure.</param>
public PRECT(Rectangle r)
{
rect = new RECT(r);
}
public PRECT(Rectangle r) => rect = new RECT(r);
/// <summary>Initializes a new instance of the <see cref="PRECT"/> class.</summary>
/// <param name="r">The r.</param>
[ExcludeFromCodeCoverage]
private PRECT(RECT r)
{
rect = r;
}
private PRECT(RECT r) => rect = r;
/// <summary>The x-coordinate of the upper-left corner of the rectangle.</summary>
public int left
@ -374,6 +369,51 @@ namespace Vanara.PInvoke
public override string ToString() => rect.ToString();
}
internal class PRECTConverter : RECTConverter
{
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var b = base.ConvertFrom(context, culture, value);
if (b is RECT r)
return new PRECT(r);
return b;
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
var prect = value as PRECT;
if (destinationType == typeof(InstanceDescriptor) && prect != null)
{
var ctor = typeof(PRECT).GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(int) });
return new InstanceDescriptor(ctor, new object[] { prect.left, prect.top, prect.right, prect.bottom });
}
return base.ConvertTo(context, culture, prect != null ? prect.rect : value, destinationType);
}
public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
{
if (propertyValues == null)
throw new ArgumentNullException(nameof(propertyValues));
var left = propertyValues["left"] ?? 0;
var top = propertyValues["top"] ?? 0;
var right = propertyValues["right"] ?? 0;
var bottom = propertyValues["bottom"] ?? 0;
if (!(left is int) || !(top is int) || !(right is int) || !(bottom is int))
throw new ArgumentException(@"Invalid property value.");
return new PRECT((int)left, (int)top, (int)right, (int)bottom);
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
var props = TypeDescriptor.GetProperties(typeof(PRECT), attributes);
return props.Sort(new[] { "left", "top", "right", "bottom" });
}
}
internal class RECTConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) =>
@ -425,20 +465,6 @@ namespace Vanara.PInvoke
return base.ConvertTo(context, culture, value, destinationType);
}
protected static string IntConvertToString(ITypeDescriptorContext context, CultureInfo culture, RECT rect)
{
var intConverter = TypeDescriptor.GetConverter(typeof(int));
var args = new string[4];
var nArg = 0;
args[nArg++] = intConverter.ConvertToString(context, culture, rect.left);
args[nArg++] = intConverter.ConvertToString(context, culture, rect.top);
args[nArg++] = intConverter.ConvertToString(context, culture, rect.right);
args[nArg++] = intConverter.ConvertToString(context, culture, rect.bottom);
return string.Join(culture.TextInfo.ListSeparator + " ", args);
}
public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
{
if (propertyValues == null)
@ -464,50 +490,19 @@ namespace Vanara.PInvoke
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context) => true;
}
internal class PRECTConverter : RECTConverter
{
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
protected static string IntConvertToString(ITypeDescriptorContext context, CultureInfo culture, RECT rect)
{
var b = base.ConvertFrom(context, culture, value);
if (b is RECT r)
return new PRECT(r);
return b;
}
var intConverter = TypeDescriptor.GetConverter(typeof(int));
var args = new string[4];
var nArg = 0;
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
var prect = value as PRECT;
if (destinationType == typeof(InstanceDescriptor) && prect != null)
{
var ctor = typeof(PRECT).GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(int) });
return new InstanceDescriptor(ctor, new object[] { prect.left, prect.top, prect.right, prect.bottom });
}
args[nArg++] = intConverter.ConvertToString(context, culture, rect.left);
args[nArg++] = intConverter.ConvertToString(context, culture, rect.top);
args[nArg++] = intConverter.ConvertToString(context, culture, rect.right);
args[nArg++] = intConverter.ConvertToString(context, culture, rect.bottom);
return base.ConvertTo(context, culture, prect != null ? prect.rect : value, destinationType);
}
public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
{
if (propertyValues == null)
throw new ArgumentNullException(nameof(propertyValues));
var left = propertyValues["left"] ?? 0;
var top = propertyValues["top"] ?? 0;
var right = propertyValues["right"] ?? 0;
var bottom = propertyValues["bottom"] ?? 0;
if (!(left is int) || !(top is int) || !(right is int) || !(bottom is int))
throw new ArgumentException(@"Invalid property value.");
return new PRECT((int)left, (int)top, (int)right, (int)bottom);
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
var props = TypeDescriptor.GetProperties(typeof(PRECT), attributes);
return props.Sort(new[] { "left", "top", "right", "bottom" });
return string.Join(culture.TextInfo.ListSeparator + " ", args);
}
}
}

View File

@ -6,8 +6,7 @@ using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
/// <summary>The <c>SIZE</c> structure specifies the width and height of a rectangle.</summary>
// typedef struct tagSIZE { LONG cx; LONG cy;} SIZE, *PSIZE;
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd145106(v=vs.85).aspx
// typedef struct tagSIZE { LONG cx; LONG cy;} SIZE, *PSIZE; https://msdn.microsoft.com/en-us/library/windows/desktop/dd145106(v=vs.85).aspx
[PInvokeData("Windef.h", MSDNShortId = "dd145106")]
[StructLayout(LayoutKind.Sequential), Serializable]
public struct SIZE : IEquatable<SIZE>
@ -45,16 +44,16 @@ namespace Vanara.PInvoke
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other" /> parameter; otherwise, false.</returns>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
public bool Equals(SIZE other) => cx == other.cx || cy == other.cy;
/// <summary>Determines whether the specified <see cref="System.Object" />, is equal to this instance.</summary>
/// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
/// <summary>Determines whether the specified <see cref="System.Object"/>, is equal to this instance.</summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
if (obj is SIZE sz) return Equals(sz);
if (obj is Size msz) return Equals((SIZE)msz);
if (obj is Size msz) return Equals(msz);
return false;
}
@ -66,8 +65,8 @@ namespace Vanara.PInvoke
/// <returns>An equivalent <see cref="System.Drawing.Size"/> structure.</returns>
public Size ToSize() => this;
/// <summary>Returns a <see cref="string" /> that represents this instance.</summary>
/// <returns>A <see cref="string" /> that represents this instance.</returns>
/// <summary>Returns a <see cref="string"/> that represents this instance.</summary>
/// <returns>A <see cref="string"/> that represents this instance.</returns>
public override string ToString() => "{cx=" + cx.ToString(CultureInfo.CurrentCulture) + ", cy=" + cy.ToString(CultureInfo.CurrentCulture) + "}";
/// <summary>Performs an implicit conversion from <see cref="SIZE"/> to <see cref="Size"/>.</summary>

View File

@ -5,21 +5,38 @@ using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
/// <summary>
/// Formal replacement for the Windows HRESULT definition. In windows.h, it is a defined UINT value. For .NET, this class strongly types the value.
/// Formal replacement for the Windows HRESULT definition. In windows.h, it is a defined UINT value. For .NET, this class strongly types
/// the value.
/// <para>The 32-bit value is organized as follows:</para>
/// <list type="table">
/// <item><term>Bit</term><description>31</description><description>30</description><description>29</description><description>28</description><description>27</description><description>26 - 16</description><description>15 - 0</description></item>
/// <item><term>Field</term><description>Severity</description><description>Severity</description><description>Customer</description><description>NT status</description><description>MsgID</description><description>Facility</description><description>Code</description></item>
/// <item>
/// <term>Bit</term>
/// <description>31</description>
/// <description>30</description>
/// <description>29</description>
/// <description>28</description>
/// <description>27</description>
/// <description>26 - 16</description>
/// <description>15 - 0</description>
/// </item>
/// <item>
/// <term>Field</term>
/// <description>Severity</description>
/// <description>Severity</description>
/// <description>Customer</description>
/// <description>NT status</description>
/// <description>MsgID</description>
/// <description>Facility</description>
/// <description>Code</description>
/// </item>
/// </list>
/// </summary>
/// <seealso cref="System.IComparable" />
/// <seealso cref="System.IComparable{HRESULT}" />
/// <seealso cref="System.IEquatable{HRESULT}" />
/// <seealso cref="System.IComparable"/>
/// <seealso cref="System.IComparable{HRESULT}"/>
/// <seealso cref="System.IEquatable{HRESULT}"/>
[StructLayout(LayoutKind.Sequential)]
[TypeConverter(typeof(HRESULTTypeConverter))]
public partial struct HRESULT : IComparable, IComparable<HRESULT>, IEquatable<HRESULT>, IConvertible
@ -65,7 +82,7 @@ namespace Vanara.PInvoke
/// <summary>The source of the error code is the control mechanism.</summary>
FACILITY_CONTROL = 10,
/// <summary>The source of the error code is a certificate client or server? </summary>
/// <summary>The source of the error code is a certificate client or server?</summary>
FACILITY_CERT = 11,
/// <summary>The source of the error code is Wininet related.</summary>
@ -170,7 +187,7 @@ namespace Vanara.PInvoke
/// <summary>The source of the error code is the user mode virtualization subsystem.</summary>
FACILITY_USERMODE_VIRTUALIZATION = 55,
/// <summary>The source of the error code is the user mode volume manager</summary>
/// <summary>The source of the error code is the user mode volume manager</summary>
FACILITY_USERMODE_VOLMGR = 56,
/// <summary>The source of the error code is the Boot Configuration Database.</summary>
@ -197,16 +214,14 @@ namespace Vanara.PInvoke
{
/// <summary>Success</summary>
Success = 0,
/// <summary>Failure</summary>
Fail = 1
}
/// <summary>Initializes a new instance of the <see cref="HRESULT"/> structure.</summary>
/// <param name="rawValue">The raw HRESULT value.</param>
public HRESULT(uint rawValue)
{
_value = rawValue;
}
public HRESULT(uint rawValue) => _value = rawValue;
/// <summary>Gets the code portion of the <see cref="HRESULT"/>.</summary>
/// <value>The code value (bits 0-15).</value>
@ -231,21 +246,21 @@ namespace Vanara.PInvoke
/// <summary>Compares the current object with another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>
/// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value Meaning Less than zero
/// This object is less than the <paramref name="other"/> parameter.Zero This object is equal to <paramref name="other"/>. Greater than zero This object
/// is greater than <paramref name="other"/>.
/// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value
/// Meaning Less than zero This object is less than the <paramref name="other"/> parameter.Zero This object is equal to <paramref
/// name="other"/>. Greater than zero This object is greater than <paramref name="other"/>.
/// </returns>
public int CompareTo(HRESULT other) => _value.CompareTo(other._value);
/// <summary>
/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes,
/// follows, or occurs in the same position in the sort order as the other object.
/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current
/// instance precedes, follows, or occurs in the same position in the sort order as the other object.
/// </summary>
/// <param name="obj">An object to compare with this instance.</param>
/// <returns>
/// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This
/// instance precedes <paramref name="obj"/> in the sort order. Zero This instance occurs in the same position in the sort order as <paramref
/// name="obj"/>. Greater than zero This instance follows <paramref name="obj"/> in the sort order.
/// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less
/// than zero This instance precedes <paramref name="obj"/> in the sort order. Zero This instance occurs in the same position in the
/// sort order as <paramref name="obj"/>. Greater than zero This instance follows <paramref name="obj"/> in the sort order.
/// </returns>
public int CompareTo(object obj)
{
@ -328,7 +343,9 @@ namespace Vanara.PInvoke
public static HRESULT Make(bool severe, uint facility, uint code) => new HRESULT(
(severe ? severityMask : 0) | (facility << facilityShift) | code);
/// <summary>If this <see cref="HRESULT"/> represents a failure, throw the associated <see cref="Exception"/> with the optionally supplied message.</summary>
/// <summary>
/// If this <see cref="HRESULT"/> represents a failure, throw the associated <see cref="Exception"/> with the optionally supplied message.
/// </summary>
/// <param name="message">The optional message to assign to the <see cref="Exception"/>.</param>
[SecurityCritical, SecuritySafeCritical]
[System.Diagnostics.DebuggerStepThrough]
@ -345,10 +362,7 @@ namespace Vanara.PInvoke
/// <param name="hresult">The 32-bit raw HRESULT value.</param>
/// <param name="message">The optional message to assign to the <see cref="Exception"/>.</param>
[System.Diagnostics.DebuggerStepThrough]
public static void ThrowIfFailed(int hresult, string message = null)
{
new HRESULT((uint)hresult).ThrowIfFailed(message);
}
public static void ThrowIfFailed(int hresult, string message = null) => new HRESULT((uint)hresult).ThrowIfFailed(message);
/// <summary>Returns a <see cref="string"/> that represents this instance.</summary>
/// <returns>A <see cref="string"/> that represents this instance.</returns>

View File

@ -1,6 +1,4 @@
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
namespace Vanara.PInvoke
{
public partial struct NTStatus
{

View File

@ -5,14 +5,12 @@ using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
/// <summary>
/// Formal replacement for the Windows NTStatus definition. In ntstatus.h, it is a defined UINT value. For .NET, this class strongly types the value.
/// Formal replacement for the Windows NTStatus definition. In ntstatus.h, it is a defined UINT value. For .NET, this class strongly
/// types the value.
/// <para>The 32-bit value is organized as follows:</para>
/// <list type="table">
/// <item>
@ -54,108 +52,160 @@ namespace Vanara.PInvoke
{
/// <summary>The default facility code.</summary>
FACILITY_NULL = 0,
/// <summary>The facility debugger</summary>
FACILITY_DEBUGGER = 0x1,
/// <summary>The facility RPC runtime</summary>
FACILITY_RPC_RUNTIME = 0x2,
/// <summary>The facility RPC stubs</summary>
FACILITY_RPC_STUBS = 0x3,
/// <summary>The facility io error code</summary>
FACILITY_IO_ERROR_CODE = 0x4,
/// <summary>The facility codclass error code</summary>
FACILITY_CODCLASS_ERROR_CODE = 0x6,
/// <summary>The facility ntwi N32</summary>
FACILITY_NTWIN32 = 0x7,
/// <summary>The facility ntcert</summary>
FACILITY_NTCERT = 0x8,
/// <summary>The facility ntsspi</summary>
FACILITY_NTSSPI = 0x9,
/// <summary>The facility terminal server</summary>
FACILITY_TERMINAL_SERVER = 0xA,
/// <summary>The faciltiy MUI error code</summary>
FACILTIY_MUI_ERROR_CODE = 0xB,
/// <summary>The facility usb error code</summary>
FACILITY_USB_ERROR_CODE = 0x10,
/// <summary>The facility hid error code</summary>
FACILITY_HID_ERROR_CODE = 0x11,
/// <summary>The facility firewire error code</summary>
FACILITY_FIREWIRE_ERROR_CODE = 0x12,
/// <summary>The facility cluster error code</summary>
FACILITY_CLUSTER_ERROR_CODE = 0x13,
/// <summary>The facility acpi error code</summary>
FACILITY_ACPI_ERROR_CODE = 0x14,
/// <summary>The facility SXS error code</summary>
FACILITY_SXS_ERROR_CODE = 0x15,
/// <summary>The facility transaction</summary>
FACILITY_TRANSACTION = 0x19,
/// <summary>The facility commonlog</summary>
FACILITY_COMMONLOG = 0x1A,
/// <summary>The facility video</summary>
FACILITY_VIDEO = 0x1B,
/// <summary>The facility filter manager</summary>
FACILITY_FILTER_MANAGER = 0x1C,
/// <summary>The facility monitor</summary>
FACILITY_MONITOR = 0x1D,
/// <summary>The facility graphics kernel</summary>
FACILITY_GRAPHICS_KERNEL = 0x1E,
/// <summary>The facility driver framework</summary>
FACILITY_DRIVER_FRAMEWORK = 0x20,
/// <summary>The facility fve error code</summary>
FACILITY_FVE_ERROR_CODE = 0x21,
/// <summary>The facility FWP error code</summary>
FACILITY_FWP_ERROR_CODE = 0x22,
/// <summary>The facility ndis error code</summary>
FACILITY_NDIS_ERROR_CODE = 0x23,
/// <summary>The facility TPM</summary>
FACILITY_TPM = 0x29,
/// <summary>The facility RTPM</summary>
FACILITY_RTPM = 0x2A,
/// <summary>The facility hypervisor</summary>
FACILITY_HYPERVISOR = 0x35,
/// <summary>The facility ipsec</summary>
FACILITY_IPSEC = 0x36,
/// <summary>The facility virtualization</summary>
FACILITY_VIRTUALIZATION = 0x37,
/// <summary>The facility volmgr</summary>
FACILITY_VOLMGR = 0x38,
/// <summary>The facility BCD error code</summary>
FACILITY_BCD_ERROR_CODE = 0x39,
/// <summary>The facility wi N32 k ntuser</summary>
FACILITY_WIN32K_NTUSER = 0x3E,
/// <summary>The facility wi N32 k ntgdi</summary>
FACILITY_WIN32K_NTGDI = 0x3F,
/// <summary>The facility resume key filter</summary>
FACILITY_RESUME_KEY_FILTER = 0x40,
/// <summary>The facility RDBSS</summary>
FACILITY_RDBSS = 0x41,
/// <summary>The facility BTH att</summary>
FACILITY_BTH_ATT = 0x42,
/// <summary>The facility secureboot</summary>
FACILITY_SECUREBOOT = 0x43,
/// <summary>The facility audio kernel</summary>
FACILITY_AUDIO_KERNEL = 0x44,
/// <summary>The facility VSM</summary>
FACILITY_VSM = 0x45,
/// <summary>The facility volsnap</summary>
FACILITY_VOLSNAP = 0x50,
/// <summary>The facility sdbus</summary>
FACILITY_SDBUS = 0x51,
/// <summary>The facility shared VHDX</summary>
FACILITY_SHARED_VHDX = 0x5C,
/// <summary>The facility SMB</summary>
FACILITY_SMB = 0x5D,
/// <summary>The facility interix</summary>
FACILITY_INTERIX = 0x99,
/// <summary>The facility spaces</summary>
FACILITY_SPACES = 0xE7,
/// <summary>The facility security core</summary>
FACILITY_SECURITY_CORE = 0xE8,
/// <summary>The facility system integrity</summary>
FACILITY_SYSTEM_INTEGRITY = 0xE9,
/// <summary>The facility licensing</summary>
FACILITY_LICENSING = 0xEA,
/// <summary>The facility platform manifest</summary>
FACILITY_PLATFORM_MANIFEST = 0xEB,
/// <summary>The facility maximum value</summary>
FACILITY_MAXIMUM_VALUE = 0xEC
}
@ -163,7 +213,9 @@ namespace Vanara.PInvoke
/// <summary>A value indicating the severity of an <see cref="NTStatus"/> value (bits 30-31).</summary>
public enum SeverityLevel : byte
{
/// <summary>Indicates a successful NTSTATUS value, such as STATUS_SUCCESS, or the value IO_ERR_RETRY_SUCCEEDED in error log packets.</summary>
/// <summary>
/// Indicates a successful NTSTATUS value, such as STATUS_SUCCESS, or the value IO_ERR_RETRY_SUCCEEDED in error log packets.
/// </summary>
STATUS_SEVERITY_SUCCESS = 0x0,
/// <summary>Indicates an informational NTSTATUS value, such as STATUS_SERIAL_MORE_WRITES.</summary>
@ -173,18 +225,15 @@ namespace Vanara.PInvoke
STATUS_SEVERITY_WARNING = 0x2,
/// <summary>
/// Indicates an error NTSTATUS value, such as STATUS_INSUFFICIENT_RESOURCES for a FinalStatus value or IO_ERR_CONFIGURATION_ERROR for an ErrorCode
/// value in error log packets.
/// Indicates an error NTSTATUS value, such as STATUS_INSUFFICIENT_RESOURCES for a FinalStatus value or
/// IO_ERR_CONFIGURATION_ERROR for an ErrorCode value in error log packets.
/// </summary>
STATUS_SEVERITY_ERROR = 0x3
}
/// <summary>Initializes a new instance of the <see cref="NTStatus"/> structure.</summary>
/// <param name="rawValue">The raw NTStatus value.</param>
public NTStatus(uint rawValue)
{
_value = rawValue;
}
public NTStatus(uint rawValue) => _value = rawValue;
/// <summary>Gets the code portion of the <see cref="NTStatus"/>.</summary>
/// <value>The code value (bits 0-15).</value>
@ -214,20 +263,20 @@ namespace Vanara.PInvoke
/// <param name="other">An object to compare with this object.</param>
/// <returns>
/// A value that indicates the relative order of the objects being compared. The return value has the following
/// meanings: Value Meaning Less than zero This object is less than the <paramref name="other"/> parameter.Zero This object is equal to
/// <paramref name="other"/>. Greater than zero This object is greater than <paramref name="other"/>.
/// meanings: Value Meaning Less than zero This object is less than the <paramref name="other"/> parameter.Zero This object is equal
/// to <paramref name="other"/>. Greater than zero This object is greater than <paramref name="other"/>.
/// </returns>
public int CompareTo(NTStatus other) => _value.CompareTo(other._value);
/// <summary>
/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes,
/// follows, or occurs in the same position in the sort order as the other object.
/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current
/// instance precedes, follows, or occurs in the same position in the sort order as the other object.
/// </summary>
/// <param name="obj">An object to compare with this instance.</param>
/// <returns>
/// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This
/// instance precedes <paramref name="obj"/> in the sort order. Zero This instance occurs in the same position in the sort order as
/// <paramref name="obj"/> . Greater than zero This instance follows <paramref name="obj"/> in the sort order.
/// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less
/// than zero This instance precedes <paramref name="obj"/> in the sort order. Zero This instance occurs in the same position in the
/// sort order as <paramref name="obj"/> . Greater than zero This instance follows <paramref name="obj"/> in the sort order.
/// </returns>
public int CompareTo(object obj)
{
@ -305,10 +354,12 @@ namespace Vanara.PInvoke
/// <param name="facility">The facility.</param>
/// <param name="code">The code.</param>
/// <returns>The resulting <see cref="NTStatus"/>.</returns>
public static NTStatus Make(SeverityLevel severity, bool customerDefined, ushort facility, ushort code) =>
public static NTStatus Make(SeverityLevel severity, bool customerDefined, ushort facility, ushort code) =>
new NTStatus(((uint)severity << severityShift) | (customerDefined ? customerMask : 0) | ((uint)facility << facilityShift) | code);
/// <summary>If this <see cref="NTStatus"/> represents a failure, throw the associated <see cref="Exception"/> with the optionally supplied message.</summary>
/// <summary>
/// If this <see cref="NTStatus"/> represents a failure, throw the associated <see cref="Exception"/> with the optionally supplied message.
/// </summary>
/// <param name="message">The optional message to assign to the <see cref="Exception"/>.</param>
[SecurityCritical]
[SecuritySafeCritical]
@ -320,14 +371,12 @@ namespace Vanara.PInvoke
}
/// <summary>
/// If the supplied raw NTStatus value represents a failure, throw the associated <see cref="Exception"/> with the optionally supplied message.
/// If the supplied raw NTStatus value represents a failure, throw the associated <see cref="Exception"/> with the optionally
/// supplied message.
/// </summary>
/// <param name="ntstatus">The 32-bit raw NTStatus value.</param>
/// <param name="message">The optional message to assign to the <see cref="Exception"/>.</param>
public static void ThrowIfFailed(uint ntstatus, string message = null)
{
new NTStatus(ntstatus).ThrowIfFailed(message);
}
public static void ThrowIfFailed(uint ntstatus, string message = null) => new NTStatus(ntstatus).ThrowIfFailed(message);
/// <summary>Returns a <see cref="string"/> that represents this instance.</summary>
/// <returns>A <see cref="string"/> that represents this instance.</returns>
@ -418,8 +467,8 @@ namespace Vanara.PInvoke
/// <summary>Converts the specified NTSTATUS code to its equivalent system error code.</summary>
/// <param name="status">The NTSTATUS code to be converted.</param>
/// <returns>
/// The function returns the corresponding system error code. ERROR_MR_MID_NOT_FOUND is returned when the specified NTSTATUS code does not have a
/// corresponding system error code.
/// The function returns the corresponding system error code. ERROR_MR_MID_NOT_FOUND is returned when the specified NTSTATUS code
/// does not have a corresponding system error code.
/// </returns>
[DllImport(Lib.NtDll, ExactSpelling = true)]
[PInvokeData("Winternl.h", MSDNShortId = "ms680600")]

View File

@ -1,5 +1,3 @@
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
public partial struct Win32Error

View File

@ -5,8 +5,6 @@ using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
/// <summary>Represents a Win32 Error Code. This can be used in place of a return value.</summary>
@ -18,10 +16,7 @@ namespace Vanara.PInvoke
/// <summary>Initializes a new instance of the <see cref="Win32Error"/> struct with an error value.</summary>
/// <param name="i">The i.</param>
public Win32Error(int i)
{
value = i;
}
public Win32Error(int i) => value = i;
/// <summary>Gets a value indicating whether this <see cref="Win32Error"/> is a failure.</summary>
/// <value><c>true</c> if failed; otherwise, <c>false</c>.</value>
@ -34,21 +29,21 @@ namespace Vanara.PInvoke
/// <summary>Compares the current object with another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>
/// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value Meaning Less than zero
/// This object is less than the <paramref name="other"/> parameter.Zero This object is equal to <paramref name="other"/>. Greater than zero This object
/// is greater than <paramref name="other"/>.
/// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value
/// Meaning Less than zero This object is less than the <paramref name="other"/> parameter.Zero This object is equal to <paramref
/// name="other"/>. Greater than zero This object is greater than <paramref name="other"/>.
/// </returns>
public int CompareTo(Win32Error other) => value.CompareTo(other.value);
/// <summary>
/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes,
/// follows, or occurs in the same position in the sort order as the other object.
/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current
/// instance precedes, follows, or occurs in the same position in the sort order as the other object.
/// </summary>
/// <param name="obj">An object to compare with this instance.</param>
/// <returns>
/// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This
/// instance precedes <paramref name="obj"/> in the sort order. Zero This instance occurs in the same position in the sort order as <paramref
/// name="obj"/>. Greater than zero This instance follows <paramref name="obj"/> in the sort order.
/// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less
/// than zero This instance precedes <paramref name="obj"/> in the sort order. Zero This instance occurs in the same position in the
/// sort order as <paramref name="obj"/>. Greater than zero This instance follows <paramref name="obj"/> in the sort order.
/// </returns>
public int CompareTo(object obj)
{
@ -125,10 +120,7 @@ namespace Vanara.PInvoke
/// <param name="err">The error.</param>
/// <param name="message">The message.</param>
[System.Diagnostics.DebuggerStepThrough]
public static void ThrowIfFailed(Win32Error err, string message = null)
{
err.ThrowIfFailed(message);
}
public static void ThrowIfFailed(Win32Error err, string message = null) => err.ThrowIfFailed(message);
/// <summary>Performs an explicit conversion from <see cref="System.Int32"/> to <see cref="Win32Error"/>.</summary>
/// <param name="value">The value.</param>

View File

@ -1,10 +1,37 @@
using System;
using System.Runtime.InteropServices;
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
/// <summary>
/// Font families describe the look of a font in a general way. They are intended for specifying fonts when the exact typeface desired is
/// not available.
/// </summary>
[PInvokeData("Wingdi.h", MSDNShortId = "dd145037")]
public enum FontFamily : byte
{
/// <summary>Use default font.</summary>
FF_DONTCARE = 0 << 4,
/// <summary>Fonts with variable stroke width (proportional) and with serifs. MS Serif is an example.</summary>
FF_ROMAN = 1 << 4,
/// <summary>Fonts with variable stroke width (proportional) and without serifs. MS Sans Serif is an example.</summary>
FF_SWISS = 2 << 4,
/// <summary>
/// Fonts with constant stroke width (monospace), with or without serifs. Monospace fonts are usually modern. Pica, Elite, and
/// CourierNew are examples.
/// </summary>
FF_MODERN = 3 << 4,
/// <summary>Fonts designed to look like handwriting. Script and Cursive are examples.</summary>
FF_SCRIPT = 4 << 4,
/// <summary>Novelty fonts. Old English is an example.</summary>
FF_DECORATIVE = 5 << 4,
}
/// <summary>Specifies information about the pitch, the technology, and the family of a physical font.</summary>
[PInvokeData("Wingdi.h", MSDNShortId = "dd145037")]
[Flags]
@ -12,18 +39,31 @@ namespace Vanara.PInvoke
{
/// <summary>The default pitch, which is implementation-dependent.</summary>
DEFAULT_PITCH = 0,
/// <summary>A fixed pitch, which means that all the characters in the font occupy the same width when output in a string.</summary>
FIXED_PITCH = 1,
/// <summary>A variable pitch, which means that the characters in the font occupy widths that are proportional to the actual widths of the glyphs when output in a string. For example, the "i" and space characters usually have much smaller widths than a "W" or "O" character.</summary>
/// <summary>
/// A variable pitch, which means that the characters in the font occupy widths that are proportional to the actual widths of the
/// glyphs when output in a string. For example, the "i" and space characters usually have much smaller widths than a "W" or "O" character.
/// </summary>
VARIABLE_PITCH = 2,
/// <summary>The mono font/</summary>
MONO_FONT = 8,
/// <summary>If this bit is set the font is a variable pitch font. If this bit is clear the font is a fixed pitch font. Note very carefully that those meanings are the opposite of what the constant name implies.</summary>
/// <summary>
/// If this bit is set the font is a variable pitch font. If this bit is clear the font is a fixed pitch font. Note very carefully
/// that those meanings are the opposite of what the constant name implies.
/// </summary>
TMPF_FIXED_PITCH = 0x01,
/// <summary>If this bit is set the font is a vector font.</summary>
TMPF_VECTOR = 0x02,
/// <summary>If this bit is set the font is a TrueType font.</summary>
TMPF_TRUETYPE = 0x04,
/// <summary>If this bit is set the font is a device font.</summary>
TMPF_DEVICE = 0x08,
}
@ -36,8 +76,8 @@ namespace Vanara.PInvoke
ANSI_CHARSET = 0,
/// <summary>
/// Specifies a character set based on the current system locale; for example, when the system locale is United States English, the default character
/// set is ANSI_CHARSET.
/// Specifies a character set based on the current system locale; for example, when the system locale is United States English, the
/// default character set is ANSI_CHARSET.
/// </summary>
DEFAULT_CHARSET = 1,
@ -56,7 +96,9 @@ namespace Vanara.PInvoke
/// <summary>Specifies the "simplified" Chinese character set for People's Republic of China.</summary>
GB2312_CHARSET = 134,
/// <summary>Specifies the "traditional" Chinese character set, used mostly in Taiwan and in the Hong Kong and Macao Special Administrative Regions.</summary>
/// <summary>
/// Specifies the "traditional" Chinese character set, used mostly in Taiwan and in the Hong Kong and Macao Special Administrative Regions.
/// </summary>
CHINESEBIG5_CHARSET = 136,
/// <summary>Specifies a mapping to one of the OEM code pages, according to the current system locale setting.</summary>
@ -107,14 +149,14 @@ namespace Vanara.PInvoke
CLIP_DEFAULT_PRECIS = 0,
/// <summary>
/// Windows XP SP1: Turns off font association for the font. Note that this flag is not guaranteed to have any effect on any platform after Windows
/// Server 2003.
/// Windows XP SP1: Turns off font association for the font. Note that this flag is not guaranteed to have any effect on any platform
/// after Windows Server 2003.
/// </summary>
CLIP_DFA_DISABLE = 4 << 4,
/// <summary>
/// Turns off font association for the font. This is identical to CLIP_DFA_DISABLE, but it can have problems in some situations; the recommended flag
/// to use is CLIP_DFA_DISABLE.
/// Turns off font association for the font. This is identical to CLIP_DFA_DISABLE, but it can have problems in some situations; the
/// recommended flag to use is CLIP_DFA_DISABLE.
/// </summary>
CLIP_DFA_OVERRIDE = 64,
@ -122,8 +164,9 @@ namespace Vanara.PInvoke
CLIP_EMBEDDED = 8 << 4,
/// <summary>
/// When this value is used, the rotation for all fonts depends on whether the orientation of the coordinate system is left-handed or right-handed.
/// If not used, device fonts always rotate counterclockwise, but the rotation of other fonts is dependent on the orientation of the coordinate system.
/// When this value is used, the rotation for all fonts depends on whether the orientation of the coordinate system is left-handed or
/// right-handed. If not used, device fonts always rotate counterclockwise, but the rotation of other fonts is dependent on the
/// orientation of the coordinate system.
/// </summary>
CLIP_LH_ANGLES = 1 << 4,
@ -131,8 +174,8 @@ namespace Vanara.PInvoke
CLIP_MASK = 0xf,
/// <summary>
/// Not used by the font mapper, but is returned when raster, vector, or TrueType fonts are enumerated. For compatibility, this value is always
/// returned when enumerating fonts.
/// Not used by the font mapper, but is returned when raster, vector, or TrueType fonts are enumerated. For compatibility, this value
/// is always returned when enumerating fonts.
/// </summary>
CLIP_STROKE_PRECIS = 2,
@ -141,35 +184,8 @@ namespace Vanara.PInvoke
}
/// <summary>
/// Font families describe the look of a font in a general way. They are intended for specifying fonts when the exact typeface desired is not available.
/// </summary>
[PInvokeData("Wingdi.h", MSDNShortId = "dd145037")]
public enum FontFamily : byte
{
/// <summary>Use default font.</summary>
FF_DONTCARE = 0 << 4,
/// <summary>Fonts with variable stroke width (proportional) and with serifs. MS Serif is an example.</summary>
FF_ROMAN = 1 << 4,
/// <summary>Fonts with variable stroke width (proportional) and without serifs. MS Sans Serif is an example.</summary>
FF_SWISS = 2 << 4,
/// <summary>
/// Fonts with constant stroke width (monospace), with or without serifs. Monospace fonts are usually modern. Pica, Elite, and CourierNew are examples.
/// </summary>
FF_MODERN = 3 << 4,
/// <summary>Fonts designed to look like handwriting. Script and Cursive are examples.</summary>
FF_SCRIPT = 4 << 4,
/// <summary>Novelty fonts. Old English is an example.</summary>
FF_DECORATIVE = 5 << 4,
}
/// <summary>
/// The output precision. The output precision defines how closely the output must match the requested font's height, width, character orientation,
/// escapement, pitch, and font type.
/// The output precision. The output precision defines how closely the output must match the requested font's height, width, character
/// orientation, escapement, pitch, and font type.
/// </summary>
[PInvokeData("Wingdi.h", MSDNShortId = "dd145037")]
public enum LogFontOutputPrecision : byte
@ -187,8 +203,8 @@ namespace Vanara.PInvoke
OUT_OUTLINE_PRECIS = 8,
/// <summary>
/// Instructs the font mapper to choose from only PostScript fonts. If there are no PostScript fonts installed in the system, the font mapper returns
/// to default behavior.
/// Instructs the font mapper to choose from only PostScript fonts. If there are no PostScript fonts installed in the system, the
/// font mapper returns to default behavior.
/// </summary>
OUT_PS_ONLY_PRECIS = 10,
@ -201,12 +217,14 @@ namespace Vanara.PInvoke
/// <summary>This value is not used by the font mapper, but it is returned when raster fonts are enumerated.</summary>
OUT_STRING_PRECIS = 1,
/// <summary>This value is not used by the font mapper, but it is returned when TrueType, other outline-based fonts, and vector fonts are enumerated.</summary>
/// <summary>
/// This value is not used by the font mapper, but it is returned when TrueType, other outline-based fonts, and vector fonts are enumerated.
/// </summary>
OUT_STROKE_PRECIS = 3,
/// <summary>
/// Instructs the font mapper to choose from only TrueType fonts. If there are no TrueType fonts installed in the system, the font mapper returns to
/// default behavior.
/// Instructs the font mapper to choose from only TrueType fonts. If there are no TrueType fonts installed in the system, the font
/// mapper returns to default behavior.
/// </summary>
OUT_TT_ONLY_PRECIS = 7,
@ -215,8 +233,8 @@ namespace Vanara.PInvoke
}
/// <summary>
/// The output quality defines how carefully the graphics device interface (GDI) must attempt to match the logical-font attributes to those of an actual
/// physical font.
/// The output quality defines how carefully the graphics device interface (GDI) must attempt to match the logical-font attributes to
/// those of an actual physical font.
/// </summary>
[PInvokeData("Wingdi.h", MSDNShortId = "dd145037")]
public enum LogFontOutputQuality : byte
@ -225,15 +243,16 @@ namespace Vanara.PInvoke
DEFAULT_QUALITY = 0,
/// <summary>
/// Appearance of the font is less important than when PROOF_QUALITY is used. For GDI raster fonts, scaling is enabled, which means that more font
/// sizes are available, but the quality may be lower. Bold, italic, underline, and strikeout fonts are synthesized if necessary.
/// Appearance of the font is less important than when PROOF_QUALITY is used. For GDI raster fonts, scaling is enabled, which means
/// that more font sizes are available, but the quality may be lower. Bold, italic, underline, and strikeout fonts are synthesized if necessary.
/// </summary>
DRAFT_QUALITY = 1,
/// <summary>
/// Character quality of the font is more important than exact matching of the logical-font attributes. For GDI raster fonts, scaling is disabled and
/// the font closest in size is chosen. Although the chosen font size may not be mapped exactly when PROOF_QUALITY is used, the quality of the font
/// is high and there is no distortion of appearance. Bold, italic, underline, and strikeout fonts are synthesized if necessary.
/// Character quality of the font is more important than exact matching of the logical-font attributes. For GDI raster fonts, scaling
/// is disabled and the font closest in size is chosen. Although the chosen font size may not be mapped exactly when PROOF_QUALITY is
/// used, the quality of the font is high and there is no distortion of appearance. Bold, italic, underline, and strikeout fonts are
/// synthesized if necessary.
/// </summary>
PROOF_QUALITY = 2,
@ -244,12 +263,14 @@ namespace Vanara.PInvoke
ANTIALIASED_QUALITY = 4,
/// <summary>
/// If set, text is rendered (when possible) using ClearType antialiasing method. The font quality is given less importance than maintaining the text size.
/// If set, text is rendered (when possible) using ClearType antialiasing method. The font quality is given less importance than
/// maintaining the text size.
/// </summary>
CLEARTYPE_QUALITY = 5,
/// <summary>
/// If set, text is rendered (when possible) using ClearType antialiasing method. The font quality is given more importance than maintaining the text size.
/// If set, text is rendered (when possible) using ClearType antialiasing method. The font quality is given more importance than
/// maintaining the text size.
/// </summary>
CLEARTYPE_NATURAL_QUALITY = 6
}
@ -260,36 +281,52 @@ namespace Vanara.PInvoke
public struct LOGFONT
{
/// <summary>
/// The height, in logical units, of the font's character cell or character. The character height value (also known as the em height) is the
/// character cell height value minus the internal-leading value. The font mapper interprets the value specified in lfHeight in the following manner.
/// The height, in logical units, of the font's character cell or character. The character height value (also known as the em height)
/// is the character cell height value minus the internal-leading value. The font mapper interprets the value specified in lfHeight
/// in the following manner.
/// <list type="table">
/// <listheader><term>Value</term><definition>Meaning</definition></listheader>
/// <item><term>&gt; 0</term><definition>The font mapper transforms this value into device units and matches it against the cell height of the available fonts.</definition></item>
/// <item><term>0</term><definition>The font mapper uses a default height value when it searches for a match.</definition></item>
/// <item><term>&lt; 0</term><definition>The font mapper transforms this value into device units and matches its absolute value against the character height of the available fonts.</definition></item>
/// <listheader>
/// <term>Value</term>
/// <definition>Meaning</definition>
/// </listheader>
/// <item>
/// <term>&gt; 0</term>
/// <definition>The font mapper transforms this value into device units and matches it against the cell height of the available fonts.</definition>
/// </item>
/// <item>
/// <term>0</term>
/// <definition>The font mapper uses a default height value when it searches for a match.</definition>
/// </item>
/// <item>
/// <term>&lt; 0</term>
/// <definition>The font mapper transforms this value into device units and matches its absolute value against the character height
/// of the available fonts.</definition>
/// </item>
/// </list>
/// <para>For all height comparisons, the font mapper looks for the largest font that does not exceed the requested size.</para>
/// <para>This mapping occurs when the font is used for the first time.</para>
/// <para>For the MM_TEXT mapping mode, you can use the following formula to specify a height for a font with a specified point size:</para>
/// <para>
/// For the MM_TEXT mapping mode, you can use the following formula to specify a height for a font with a specified point size:
/// </para>
/// </summary>
public int lfHeight;
/// <summary>
/// The average width, in logical units, of characters in the font. If lfWidth is zero, the aspect ratio of the device is matched against the
/// digitization aspect ratio of the available fonts to find the closest match, determined by the absolute value of the difference.
/// The average width, in logical units, of characters in the font. If lfWidth is zero, the aspect ratio of the device is matched
/// against the digitization aspect ratio of the available fonts to find the closest match, determined by the absolute value of the difference.
/// </summary>
public int lfWidth;
/// <summary>
/// The angle, in tenths of degrees, between the escapement vector and the x-axis of the device. The escapement vector is parallel to the base line
/// of a row of text.
/// The angle, in tenths of degrees, between the escapement vector and the x-axis of the device. The escapement vector is parallel to
/// the base line of a row of text.
/// <para>
/// When the graphics mode is set to GM_ADVANCED, you can specify the escapement angle of the string independently of the orientation angle of the
/// string's characters.
/// When the graphics mode is set to GM_ADVANCED, you can specify the escapement angle of the string independently of the orientation
/// angle of the string's characters.
/// </para>
/// <para>
/// When the graphics mode is set to GM_COMPATIBLE, lfEscapement specifies both the escapement and orientation. You should set lfEscapement and
/// lfOrientation to the same value.
/// When the graphics mode is set to GM_COMPATIBLE, lfEscapement specifies both the escapement and orientation. You should set
/// lfEscapement and lfOrientation to the same value.
/// </para>
/// </summary>
public int lfEscapement;
@ -298,7 +335,8 @@ namespace Vanara.PInvoke
public int lfOrientation;
/// <summary>
/// The weight of the font in the range 0 through 1000. For example, 400 is normal and 700 is bold. If this value is zero, a default weight is used.
/// The weight of the font in the range 0 through 1000. For example, 400 is normal and 700 is bold. If this value is zero, a default
/// weight is used.
/// </summary>
private int _lfWeight;
@ -315,17 +353,19 @@ namespace Vanara.PInvoke
public LogFontCharSet lfCharSet;
/// <summary>
/// The output precision. The output precision defines how closely the output must match the requested font's height, width, character orientation,
/// escapement, pitch, and font type.
/// The output precision. The output precision defines how closely the output must match the requested font's height, width,
/// character orientation, escapement, pitch, and font type.
/// </summary>
public LogFontOutputPrecision lfOutPrecision;
/// <summary>The clipping precision. The clipping precision defines how to clip characters that are partially outside the clipping region.</summary>
/// <summary>
/// The clipping precision. The clipping precision defines how to clip characters that are partially outside the clipping region.
/// </summary>
public LogFontClippingPrecision lfClipPrecision;
/// <summary>
/// The output quality. The output quality defines how carefully the graphics device interface (GDI) must attempt to match the logical-font
/// attributes to those of an actual physical font.
/// The output quality. The output quality defines how carefully the graphics device interface (GDI) must attempt to match the
/// logical-font attributes to those of an actual physical font.
/// </summary>
public LogFontOutputQuality lfQuality;
@ -333,9 +373,9 @@ namespace Vanara.PInvoke
private byte lfPitchAndFamily;
/// <summary>
/// A null-terminated string that specifies the typeface name of the font. The length of this string must not exceed 32 TCHAR values, including the
/// terminating NULL. The EnumFontFamiliesEx function can be used to enumerate the typeface names of all currently available fonts. If lfFaceName is
/// an empty string, GDI uses the first font that matches the other specified attributes.
/// A null-terminated string that specifies the typeface name of the font. The length of this string must not exceed 32 TCHAR values,
/// including the terminating NULL. The EnumFontFamiliesEx function can be used to enumerate the typeface names of all currently
/// available fonts. If lfFaceName is an empty string, GDI uses the first font that matches the other specified attributes.
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
private string _lfFaceName;
@ -348,9 +388,9 @@ namespace Vanara.PInvoke
}
/// <summary>
/// A string that specifies the typeface name of the font. The length of this string must not exceed 31 characters. The EnumFontFamiliesEx function
/// can be used to enumerate the typeface names of all currently available fonts. If lfFaceName is an empty string, GDI uses the first font that
/// matches the other specified attributes.
/// A string that specifies the typeface name of the font. The length of this string must not exceed 31 characters. The
/// EnumFontFamiliesEx function can be used to enumerate the typeface names of all currently available fonts. If lfFaceName is an
/// empty string, GDI uses the first font that matches the other specified attributes.
/// </summary>
/// <value>The face name of the font.</value>
public string lfFaceName
@ -385,7 +425,8 @@ namespace Vanara.PInvoke
}
/// <summary>
/// The weight of the font in the range 0 through 1000. For example, 400 is normal and 700 is bold. If this value is zero, a default weight is used.
/// The weight of the font in the range 0 through 1000. For example, 400 is normal and 700 is bold. If this value is zero, a default
/// weight is used.
/// </summary>
public short lfWeight
{

View File

@ -1,7 +1,5 @@
using System;
// ReSharper disable InconsistentNaming ReSharper disable FieldCanBeMadeReadOnly.Global ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
/// <summary>Access flags.</summary>
@ -12,7 +10,8 @@ namespace Vanara.PInvoke
DELETE = 0x00010000,
/// <summary>
/// The right to read the information in the object's security descriptor, not including the information in the system access control list (SACL).
/// The right to read the information in the object's security descriptor, not including the information in the system access control
/// list (SACL).
/// </summary>
READ_CONTROL = 0x00020000,
@ -23,8 +22,8 @@ namespace Vanara.PInvoke
WRITE_OWNER = 0x00080000,
/// <summary>
/// The right to use the object for synchronization. This enables a thread to wait until the object is in the signaled state. Some object types do not
/// support this access right.
/// The right to use the object for synchronization. This enables a thread to wait until the object is in the signaled state. Some
/// object types do not support this access right.
/// </summary>
SYNCHRONIZE = 0x00100000,
@ -47,8 +46,8 @@ namespace Vanara.PInvoke
SPECIFIC_RIGHTS_ALL = 0x0000FFFF,
/// <summary>
/// Controls the ability to get or set the SACL in an object's security descriptor. The system grants this access right only if the SE_SECURITY_NAME
/// privilege is enabled in the access token of the requesting thread.
/// Controls the ability to get or set the SACL in an object's security descriptor. The system grants this access right only if the
/// SE_SECURITY_NAME privilege is enabled in the access token of the requesting thread.
/// </summary>
ACCESS_SYSTEM_SECURITY = 0x01000000,

View File

@ -3,116 +3,144 @@
namespace Vanara.PInvoke
{
/// <summary>
/// File attributes are metadata values stored by the file system on disk and are used by the system and are available to developers via various file I/O APIs.
/// File attributes are metadata values stored by the file system on disk and are used by the system and are available to developers via
/// various file I/O APIs.
/// </summary>
[Flags]
[PInvokeData("winnt.h")]
public enum FileFlagsAndAttributes : uint
{
/// <summary>
/// A file that is read-only. Applications can read the file, but cannot write to it or delete it. This attribute is not honored on directories. For
/// more information, see You cannot view or change the Read-only or the System attributes of folders in Windows Server 2003, in Windows XP, in
/// Windows Vista or in Windows 7.
/// A file that is read-only. Applications can read the file, but cannot write to it or delete it. This attribute is not honored on
/// directories. For more information, see You cannot view or change the Read-only or the System attributes of folders in Windows
/// Server 2003, in Windows XP, in Windows Vista or in Windows 7.
/// </summary>
FILE_ATTRIBUTE_READONLY = 0x00000001,
/// <summary>The file or directory is hidden. It is not included in an ordinary directory listing.</summary>
FILE_ATTRIBUTE_HIDDEN = 0x00000002,
/// <summary>A file or directory that the operating system uses a part of, or uses exclusively.</summary>
FILE_ATTRIBUTE_SYSTEM = 0x00000004,
/// <summary>The handle that identifies a directory.</summary>
FILE_ATTRIBUTE_DIRECTORY = 0x00000010,
/// <summary>
/// A file or directory that is an archive file or directory. Applications typically use this attribute to mark files for backup or removal .
/// A file or directory that is an archive file or directory. Applications typically use this attribute to mark files for backup or
/// removal .
/// </summary>
FILE_ATTRIBUTE_ARCHIVE = 0x00000020,
/// <summary>This value is reserved for system use.</summary>
FILE_ATTRIBUTE_DEVICE = 0x00000040,
/// <summary>A file that does not have other attributes set. This attribute is valid only when used alone.</summary>
FILE_ATTRIBUTE_NORMAL = 0x00000080,
/// <summary>
/// A file that is being used for temporary storage. File systems avoid writing data back to mass storage if sufficient cache memory is available,
/// because typically, an application deletes a temporary file after the handle is closed. In that scenario, the system can entirely avoid writing
/// the data. Otherwise, the data is written after the handle is closed.
/// A file that is being used for temporary storage. File systems avoid writing data back to mass storage if sufficient cache memory
/// is available, because typically, an application deletes a temporary file after the handle is closed. In that scenario, the system
/// can entirely avoid writing the data. Otherwise, the data is written after the handle is closed.
/// </summary>
FILE_ATTRIBUTE_TEMPORARY = 0x00000100,
/// <summary>A file that is a sparse file.</summary>
FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200,
/// <summary>A file or directory that has an associated reparse point, or a file that is a symbolic link.</summary>
FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400,
/// <summary>
/// A file or directory that is compressed. For a file, all of the data in the file is compressed. For a directory, compression is the default for
/// newly created files and subdirectories.
/// A file or directory that is compressed. For a file, all of the data in the file is compressed. For a directory, compression is
/// the default for newly created files and subdirectories.
/// </summary>
FILE_ATTRIBUTE_COMPRESSED = 0x00000800,
/// <summary>
/// The data of a file is not available immediately. This attribute indicates that the file data is physically moved to offline storage. This
/// attribute is used by Remote Storage, which is the hierarchical storage management software. Applications should not arbitrarily change this attribute.
/// The data of a file is not available immediately. This attribute indicates that the file data is physically moved to offline
/// storage. This attribute is used by Remote Storage, which is the hierarchical storage management software. Applications should not
/// arbitrarily change this attribute.
/// </summary>
FILE_ATTRIBUTE_OFFLINE = 0x00001000,
/// <summary>The file or directory is not to be indexed by the content indexing service.</summary>
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000,
/// <summary>
/// A file or directory that is encrypted. For a file, all data streams in the file are encrypted. For a directory, encryption is the default for
/// newly created files and subdirectories.
/// A file or directory that is encrypted. For a file, all data streams in the file are encrypted. For a directory, encryption is the
/// default for newly created files and subdirectories.
/// </summary>
FILE_ATTRIBUTE_ENCRYPTED = 0x00004000,
/// <summary>
/// The directory or user data stream is configured with integrity (only supported on ReFS volumes). It is not included in an ordinary directory
/// listing. The integrity setting persists with the file if it's renamed. If a file is copied the destination file will have integrity set if either
/// the source file or destination directory have integrity set.
/// The directory or user data stream is configured with integrity (only supported on ReFS volumes). It is not included in an
/// ordinary directory listing. The integrity setting persists with the file if it's renamed. If a file is copied the destination
/// file will have integrity set if either the source file or destination directory have integrity set.
/// <para>
/// <c>Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:</c> This flag is not supported
/// until Windows Server 2012.
/// <c>Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:</c> This flag is
/// not supported until Windows Server 2012.
/// </para>
/// </summary>
FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x00008000,
/// <summary>This value is reserved for system use.</summary>
FILE_ATTRIBUTE_VIRTUAL = 0x00010000,
/// <summary>
/// The user data stream not to be read by the background data integrity scanner (AKA scrubber). When set on a directory it only provides
/// inheritance. This flag is only supported on Storage Spaces and ReFS volumes. It is not included in an ordinary directory listing.
/// The user data stream not to be read by the background data integrity scanner (AKA scrubber). When set on a directory it only
/// provides inheritance. This flag is only supported on Storage Spaces and ReFS volumes. It is not included in an ordinary directory listing.
/// <para>
/// <c>Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:</c> This flag is not supported
/// until Windows 8 and Windows Server 2012.
/// <c>Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:</c> This flag is
/// not supported until Windows 8 and Windows Server 2012.
/// </para>
/// </summary>
FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x00020000,
/// <summary>The file attribute ea</summary>
FILE_ATTRIBUTE_EA = 0x00040000,
/// <summary>
/// Write operations will not go through any intermediate cache, they will go directly to disk.
/// <para>For additional information, see the Caching Behavior section of this topic.</para>
/// </summary>
FILE_FLAG_WRITE_THROUGH = 0x80000000,
/// <summary>
/// The file or device is being opened or created for asynchronous I/O.
/// <para>
/// When subsequent I/O operations are completed on this handle, the event specified in the OVERLAPPED structure will be set to the signaled state.
/// When subsequent I/O operations are completed on this handle, the event specified in the OVERLAPPED structure will be set to the
/// signaled state.
/// </para>
/// <para>If this flag is specified, the file can be used for simultaneous read and write operations.</para>
/// <para>
/// If this flag is not specified, then I/O operations are serialized, even if the calls to the read and write functions specify an OVERLAPPED structure.
/// If this flag is not specified, then I/O operations are serialized, even if the calls to the read and write functions specify an
/// OVERLAPPED structure.
/// </para>
/// <para>
/// For information about considerations when using a file handle created with this flag, see the Synchronous and Asynchronous I/O Handles section of
/// this topic.
/// For information about considerations when using a file handle created with this flag, see the Synchronous and Asynchronous I/O
/// Handles section of this topic.
/// </para>
/// </summary>
FILE_FLAG_OVERLAPPED = 0x40000000,
/// <summary>
/// The file or device is being opened with no system caching for data reads and writes. This flag does not affect hard disk caching or memory mapped files.
/// The file or device is being opened with no system caching for data reads and writes. This flag does not affect hard disk caching
/// or memory mapped files.
/// <para>
/// There are strict requirements for successfully working with files opened with CreateFile using the FILE_FLAG_NO_BUFFERING flag, for details see
/// File Buffering.
/// There are strict requirements for successfully working with files opened with CreateFile using the FILE_FLAG_NO_BUFFERING flag,
/// for details see File Buffering.
/// </para>
/// </summary>
FILE_FLAG_NO_BUFFERING = 0x20000000,
/// <summary>
/// Access is intended to be random. The system can use this as a hint to optimize file caching.
/// <para>This flag has no effect if the file system does not support cached I/O and FILE_FLAG_NO_BUFFERING.</para>
/// <para>For more information, see the Caching Behavior section of this topic.</para>
/// </summary>
FILE_FLAG_RANDOM_ACCESS = 0x10000000,
/// <summary>
/// Access is intended to be sequential from beginning to end. The system can use this as a hint to optimize file caching.
/// <para>This flag should not be used if read-behind (that is, reverse scans) will be used.</para>
@ -120,70 +148,88 @@ namespace Vanara.PInvoke
/// <para>For more information, see the Caching Behavior section of this topic.</para>
/// </summary>
FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000,
/// <summary>
/// The file is to be deleted immediately after all of its handles are closed, which includes the specified handle and any other open or duplicated handles.
/// <para>If there are existing open handles to a file, the call fails unless they were all opened with the FILE_SHARE_DELETE share mode.</para>
/// The file is to be deleted immediately after all of its handles are closed, which includes the specified handle and any other open
/// or duplicated handles.
/// <para>
/// If there are existing open handles to a file, the call fails unless they were all opened with the FILE_SHARE_DELETE share mode.
/// </para>
/// <para>Subsequent open requests for the file fail, unless the FILE_SHARE_DELETE share mode is specified.</para>
/// </summary>
FILE_FLAG_DELETE_ON_CLOSE = 0x04000000,
/// <summary>
/// The file is being opened or created for a backup or restore operation. The system ensures that the calling process overrides file security checks
/// when the process has SE_BACKUP_NAME and SE_RESTORE_NAME privileges. For more information, see Changing Privileges in a Token.
/// The file is being opened or created for a backup or restore operation. The system ensures that the calling process overrides file
/// security checks when the process has SE_BACKUP_NAME and SE_RESTORE_NAME privileges. For more information, see Changing Privileges
/// in a Token.
/// <para>
/// You must set this flag to obtain a handle to a directory. A directory handle can be passed to some functions instead of a file handle. For more
/// information, see the Remarks section.
/// You must set this flag to obtain a handle to a directory. A directory handle can be passed to some functions instead of a file
/// handle. For more information, see the Remarks section.
/// </para>
/// </summary>
FILE_FLAG_BACKUP_SEMANTICS = 0x02000000,
/// <summary>
/// Access will occur according to POSIX rules. This includes allowing multiple files with names, differing only in case, for file systems that
/// support that naming. Use care when using this option, because files created with this flag may not be accessible by applications that are written
/// for MS-DOS or 16-bit Windows.
/// Access will occur according to POSIX rules. This includes allowing multiple files with names, differing only in case, for file
/// systems that support that naming. Use care when using this option, because files created with this flag may not be accessible by
/// applications that are written for MS-DOS or 16-bit Windows.
/// </summary>
FILE_FLAG_POSIX_SEMANTICS = 0x01000000,
/// <summary>
/// The file or device is being opened with session awareness. If this flag is not specified, then per-session devices (such as a device using
/// RemoteFX USB Redirection) cannot be opened by processes running in session 0. This flag has no effect for callers not in session 0. This flag is
/// supported only on server editions of Windows.
/// The file or device is being opened with session awareness. If this flag is not specified, then per-session devices (such as a
/// device using RemoteFX USB Redirection) cannot be opened by processes running in session 0. This flag has no effect for callers
/// not in session 0. This flag is supported only on server editions of Windows.
/// <para><c>Windows Server 2008 R2 and Windows Server 2008:</c> This flag is not supported before Windows Server 2012.</para>
/// </summary>
FILE_FLAG_SESSION_AWARE = 0x00800000,
/// <summary>
/// Normal reparse point processing will not occur; CreateFile will attempt to open the reparse point. When a file is opened, a file handle is
/// returned, whether or not the filter that controls the reparse point is operational.
/// Normal reparse point processing will not occur; CreateFile will attempt to open the reparse point. When a file is opened, a file
/// handle is returned, whether or not the filter that controls the reparse point is operational.
/// <para>This flag cannot be used with the CREATE_ALWAYS flag.</para>
/// <para>If the file is not a reparse point, then this flag is ignored.</para>
/// </summary>
FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000,
/// <summary>
/// The file data is requested, but it should continue to be located in remote storage. It should not be transported back to local storage. This flag
/// is for use by remote storage systems.
/// The file data is requested, but it should continue to be located in remote storage. It should not be transported back to local
/// storage. This flag is for use by remote storage systems.
/// </summary>
FILE_FLAG_OPEN_NO_RECALL = 0x00100000,
/// <summary>
/// If you attempt to create multiple instances of a pipe with this flag, creation of the first instance succeeds, but creation of the next instance
/// fails with ERROR_ACCESS_DENIED.
/// If you attempt to create multiple instances of a pipe with this flag, creation of the first instance succeeds, but creation of
/// the next instance fails with ERROR_ACCESS_DENIED.
/// </summary>
FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000,
/// <summary>Impersonates a client at the Anonymous impersonation level.</summary>
SECURITY_ANONYMOUS = 0x00000000,
/// <summary>Impersonates a client at the Identification impersonation level.</summary>
SECURITY_IDENTIFICATION = 0x00010000,
/// <summary>
/// Impersonate a client at the impersonation level. This is the default behavior if no other flags are specified along with the
/// SECURITY_SQOS_PRESENT flag.
/// </summary>
SECURITY_IMPERSONATION = 0x00020000,
/// <summary>Impersonates a client at the Delegation impersonation level.</summary>
SECURITY_DELEGATION = 0x00030000,
/// <summary>The security tracking mode is dynamic. If this flag is not specified, the security tracking mode is static.</summary>
SECURITY_CONTEXT_TRACKING = 0x00040000,
/// <summary>
/// Only the enabled aspects of the client's security context are available to the server. If you do not specify this flag, all aspects of the
/// client's security context are available.
/// Only the enabled aspects of the client's security context are available to the server. If you do not specify this flag, all
/// aspects of the client's security context are available.
/// <para>This allows the client to limit the groups and privileges that a server can use while impersonating the client.</para>
/// </summary>
SECURITY_EFFECTIVE_ONLY = 0x00080000,
/// <summary>Include to enable the other SECURITY_ flags.</summary>
SECURITY_SQOS_PRESENT = 0x00100000,
}

View File

@ -1,8 +1,6 @@
using System;
using System.Runtime.InteropServices;
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
/// <summary>Valid values for the <see cref="OBJECT_TYPE_LIST.level"/> field.</summary>
@ -22,16 +20,20 @@ namespace Vanara.PInvoke
}
/// <summary>
/// Identifies an object type element in a hierarchy of object types. An array of OBJECT_TYPE_LIST structures to define a hierarchy of an object and its
/// subobjects, such as property sets and properties.
/// The <c>OBJECT_TYPE_LIST</c> structure identifies an object type element in a hierarchy of object types. The AccessCheckByType
/// functions use an array of <c>OBJECT_TYPE_LIST</c> structures to define a hierarchy of an object and its subobjects, such as property
/// sets and properties.
/// </summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_object_type_list
// typedef struct _OBJECT_TYPE_LIST { WORD Level; WORD Sbz; GUID *ObjectType; } OBJECT_TYPE_LIST, *POBJECT_TYPE_LIST;
[PInvokeData("winnt.h", MSDNShortId = "c729ff1a-65f3-4f6f-84dd-5700aead75ce")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 2)]
public partial class OBJECT_TYPE_LIST : IDisposable
{
/// <summary>
/// Specifies the level of the object type in the hierarchy of an object and its subobjects. Level zero indicates the object itself. Level one
/// indicates a subobject of the object, such as a property set. Level two indicates a subobject of the level one subobject, such as a property.
/// There can be a maximum of five levels numbered zero through four.
/// Specifies the level of the object type in the hierarchy of an object and its subobjects. Level zero indicates the object itself.
/// Level one indicates a subobject of the object, such as a property set. Level two indicates a subobject of the level one
/// subobject, such as a property. There can be a maximum of five levels numbered zero through four.
/// </summary>
public ObjectTypeListLevel level;

View File

@ -1,7 +1,7 @@
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
/// <summary>Processor architecture</summary>
[PInvokeData("winnt.h")]
public enum ProcessorArchitecture : ushort
{
/// <summary>x86</summary>

View File

@ -5,47 +5,68 @@ namespace Vanara.PInvoke
/// <summary>
/// The SECURITY_INFORMATION data type identifies the object-related security information being set or queried. This security information includes:
/// <list type="bullet">
/// <item><term>The owner of an object</term></item>
/// <item><term>The primary group of an object</term></item>
/// <item><term>The discretionary access control list (DACL) of an object</term></item>
/// <item><term>The system access control list (SACL) of an object</term></item>
/// <item>
/// <term>The owner of an object</term>
/// </item>
/// <item>
/// <term>The primary group of an object</term>
/// </item>
/// <item>
/// <term>The discretionary access control list (DACL) of an object</term>
/// </item>
/// <item>
/// <term>The system access control list (SACL) of an object</term>
/// </item>
/// </list>
/// </summary>
[PInvokeData("winnt.h")]
[Flags]
public enum SECURITY_INFORMATION : uint
{
/// <summary>The owner identifier of the object is being referenced.</summary>
OWNER_SECURITY_INFORMATION = 0x00000001,
/// <summary>The primary group identifier of the object is being referenced.</summary>
GROUP_SECURITY_INFORMATION = 0x00000002,
/// <summary>The DACL of the object is being referenced.</summary>
DACL_SECURITY_INFORMATION = 0x00000004,
/// <summary>The SACL of the object is being referenced.</summary>
SACL_SECURITY_INFORMATION = 0x00000008,
/// <summary>The mandatory integrity label is being referenced. The mandatory integrity label is an ACE in the SACL of the object.</summary>
LABEL_SECURITY_INFORMATION = 0x00000010,
/// <summary>
/// The resource properties of the object being referenced. The resource properties are stored in SYSTEM_RESOURCE_ATTRIBUTE_ACE types in the SACL of
/// the security descriptor.
/// The resource properties of the object being referenced. The resource properties are stored in SYSTEM_RESOURCE_ATTRIBUTE_ACE types
/// in the SACL of the security descriptor.
/// </summary>
ATTRIBUTE_SECURITY_INFORMATION = 0x00000020,
/// <summary>
/// The Central Access Policy (CAP) identifier applicable on the object that is being referenced. Each CAP identifier is stored in a
/// SYSTEM_SCOPED_POLICY_ID_ACE type in the SACL of the SD.
/// </summary>
SCOPE_SECURITY_INFORMATION = 0x00000040,
/// <summary>Reserved.</summary>
PROCESS_TRUST_LABEL_SECURITY_INFORMATION = 0x00000080,
/// <summary>
/// All parts of the security descriptor. This is useful for backup and restore software that needs to preserve the entire security descriptor.
/// </summary>
BACKUP_SECURITY_INFORMATION = 0x00010000,
/// <summary>The DACL cannot inherit access control entries (ACEs).</summary>
PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000,
/// <summary>The SACL cannot inherit ACEs.</summary>
PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000,
/// <summary>The DACL inherits ACEs from the parent object.</summary>
UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000,
/// <summary>The SACL inherits ACEs from the parent object.</summary>
UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000
}

View File

@ -1,6 +1,4 @@
using System;
// ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
@ -11,51 +9,116 @@ namespace Vanara.PInvoke
{
/// <summary>Justifies the text to the top of the rectangle.</summary>
DT_TOP = 0x00000000,
/// <summary>Aligns text to the left.</summary>
DT_LEFT = 0x00000000,
/// <summary>Centers text horizontally in the rectangle.</summary>
DT_CENTER = 0x00000001,
/// <summary>Aligns text to the right.</summary>
DT_RIGHT = 0x00000002,
/// <summary>Centers text vertically. This value is used only with the DT_SINGLELINE value.</summary>
DT_VCENTER = 0x00000004,
/// <summary>Justifies the text to the bottom of the rectangle. This value is used only with the DT_SINGLELINE value.</summary>
DT_BOTTOM = 0x00000008,
/// <summary>Breaks words. Lines are automatically broken between words if a word extends past the edge of the rectangle specified by the lprc parameter. A carriage return-line feed sequence also breaks the line.</summary>
/// <summary>
/// Breaks words. Lines are automatically broken between words if a word extends past the edge of the rectangle specified by the lprc
/// parameter. A carriage return-line feed sequence also breaks the line.
/// </summary>
DT_WORDBREAK = 0x00000010,
/// <summary>Displays text on a single line only. Carriage returns and line feeds do not break the line.</summary>
DT_SINGLELINE = 0x00000020,
/// <summary>Expands tab characters. The default number of characters per tab is eight.</summary>
DT_EXPANDTABS = 0x00000040,
/// <summary>Sets tab stops. The DRAWTEXTPARAMS structure pointed to by the lpDTParams parameter specifies the number of average character widths per tab stop.</summary>
/// <summary>
/// Sets tab stops. The DRAWTEXTPARAMS structure pointed to by the lpDTParams parameter specifies the number of average character
/// widths per tab stop.
/// </summary>
DT_TABSTOP = 0x00000080,
/// <summary>Draws without clipping. DrawTextEx is somewhat faster when DT_NOCLIP is used.</summary>
DT_NOCLIP = 0x00000100,
/// <summary>Includes the font external leading in line height. Normally, external leading is not included in the height of a line of text.</summary>
/// <summary>
/// Includes the font external leading in line height. Normally, external leading is not included in the height of a line of text.
/// </summary>
DT_EXTERNALLEADING = 0x00000200,
/// <summary>Determines the width and height of the rectangle. If there are multiple lines of text, DrawTextEx uses the width of the rectangle pointed to by the lprc parameter and extends the base of the rectangle to bound the last line of text. If there is only one line of text, DrawTextEx modifies the right side of the rectangle so that it bounds the last character in the line. In either case, DrawTextEx returns the height of the formatted text, but does not draw the text.</summary>
/// <summary>
/// Determines the width and height of the rectangle. If there are multiple lines of text, DrawTextEx uses the width of the rectangle
/// pointed to by the lprc parameter and extends the base of the rectangle to bound the last line of text. If there is only one line
/// of text, DrawTextEx modifies the right side of the rectangle so that it bounds the last character in the line. In either case,
/// DrawTextEx returns the height of the formatted text, but does not draw the text.
/// </summary>
DT_CALCRECT = 0x00000400,
/// <summary>Turns off processing of prefix characters. Normally, DrawTextEx interprets the ampersand (&amp;) mnemonic-prefix character as a directive to underscore the character that follows, and the double-ampersand (&amp;&amp;) mnemonic-prefix characters as a directive to print a single ampersand. By specifying DT_NOPREFIX, this processing is turned off. Compare with DT_HIDEPREFIX and DT_PREFIXONLY</summary>
/// <summary>
/// Turns off processing of prefix characters. Normally, DrawTextEx interprets the ampersand (&amp;) mnemonic-prefix character as a
/// directive to underscore the character that follows, and the double-ampersand (&amp;&amp;) mnemonic-prefix characters as a
/// directive to print a single ampersand. By specifying DT_NOPREFIX, this processing is turned off. Compare with DT_HIDEPREFIX and DT_PREFIXONLY
/// </summary>
DT_NOPREFIX = 0x00000800,
/// <summary>Uses the system font to calculate text metrics.</summary>
DT_INTERNAL = 0x00001000,
/// <summary>Duplicates the text-displaying characteristics of a multiline edit control. Specifically, the average character width is calculated in the same manner as for an edit control, and the function does not display a partially visible last line.</summary>
/// <summary>
/// Duplicates the text-displaying characteristics of a multiline edit control. Specifically, the average character width is
/// calculated in the same manner as for an edit control, and the function does not display a partially visible last line.
/// </summary>
DT_EDITCONTROL = 0x00002000,
/// <summary>For displayed text, replaces characters in the middle of the string with ellipses so that the result fits in the specified rectangle. If the string contains backslash (\) characters, DT_PATH_ELLIPSIS preserves as much as possible of the text after the last backslash. The string is not modified unless the DT_MODIFYSTRING flag is specified.</summary>
/// <summary>
/// For displayed text, replaces characters in the middle of the string with ellipses so that the result fits in the specified
/// rectangle. If the string contains backslash (\) characters, DT_PATH_ELLIPSIS preserves as much as possible of the text after the
/// last backslash. The string is not modified unless the DT_MODIFYSTRING flag is specified.
/// </summary>
DT_PATH_ELLIPSIS = 0x00004000,
/// <summary>For displayed text, replaces the end of a string with ellipses so that the result fits in the specified rectangle. Any word (not at the end of the string) that goes beyond the limits of the rectangle is truncated without ellipses. The string is not modified unless the DT_MODIFYSTRING flag is specified.</summary>
/// <summary>
/// For displayed text, replaces the end of a string with ellipses so that the result fits in the specified rectangle. Any word (not
/// at the end of the string) that goes beyond the limits of the rectangle is truncated without ellipses. The string is not modified
/// unless the DT_MODIFYSTRING flag is specified.
/// </summary>
DT_END_ELLIPSIS = 0x00008000,
/// <summary>Modifies the specified string to match the displayed text. This value has no effect unless DT_END_ELLIPSIS or DT_PATH_ELLIPSIS is specified.</summary>
/// <summary>
/// Modifies the specified string to match the displayed text. This value has no effect unless DT_END_ELLIPSIS or DT_PATH_ELLIPSIS is specified.
/// </summary>
DT_MODIFYSTRING = 0x00010000,
/// <summary>Layout in right-to-left reading order for bidirectional text when the font selected into the hdc is a Hebrew or Arabic font. The default reading order for all text is left-to-right.</summary>
/// <summary>
/// Layout in right-to-left reading order for bidirectional text when the font selected into the hdc is a Hebrew or Arabic font. The
/// default reading order for all text is left-to-right.
/// </summary>
DT_RTLREADING = 0x00020000,
/// <summary>Truncates any word that does not fit in the rectangle and adds ellipses.</summary>
DT_WORD_ELLIPSIS = 0x00040000,
/// <summary>Prevents a line break at a DBCS (double-wide character string), so that the line-breaking rule is equivalent to SBCS strings. For example, this can be used in Korean windows, for more readability of icon labels. This value has no effect unless DT_WORDBREAK is specified.</summary>
/// <summary>
/// Prevents a line break at a DBCS (double-wide character string), so that the line-breaking rule is equivalent to SBCS strings. For
/// example, this can be used in Korean windows, for more readability of icon labels. This value has no effect unless DT_WORDBREAK is specified.
/// </summary>
DT_NOFULLWIDTHCHARBREAK = 0x00080000,
/// <summary>Ignores the ampersand (&amp;) prefix character in the text. The letter that follows will not be underlined, but other mnemonic-prefix characters are still processed.</summary>
/// <summary>
/// Ignores the ampersand (&amp;) prefix character in the text. The letter that follows will not be underlined, but other
/// mnemonic-prefix characters are still processed.
/// </summary>
DT_HIDEPREFIX = 0x00100000,
/// <summary>Draws only an underline at the position of the character following the ampersand (&amp;) prefix character. Does not draw any character in the string.</summary>
/// <summary>
/// Draws only an underline at the position of the character following the ampersand (&amp;) prefix character. Does not draw any
/// character in the string.
/// </summary>
DT_PREFIXONLY = 0x00200000,
}
}

View File

@ -1,26 +1,32 @@
using System;
using System.Runtime.InteropServices;
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
/// <summary>Contains message information from a thread's message queue.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct MSG
{
/// <summary>A handle to the window whose window procedure receives the message. This member is NULL when the message is a thread message.</summary>
/// <summary>
/// A handle to the window whose window procedure receives the message. This member is NULL when the message is a thread message.
/// </summary>
public HWND hwnd;
/// <summary>The message identifier. Applications can only use the low word; the high word is reserved by the system.</summary>
public uint message;
/// <summary>Additional information about the message. The exact meaning depends on the value of the message member.</summary>
public IntPtr wParam;
/// <summary>Additional information about the message. The exact meaning depends on the value of the message member.</summary>
public IntPtr lParam;
/// <summary>The time at which the message was posted.</summary>
public uint time;
/// <summary>The horizontal cursor position, in screen coordinates, when the message was posted.</summary>
public int pt_x;
/// <summary>The vertical cursor position, in screen coordinates, when the message was posted.</summary>
public int pt_y;
}

View File

@ -25,6 +25,12 @@ namespace Vanara.PInvoke
/// <returns>The return value is the high-order word of the specified value.</returns>
public static ushort HIWORD(UIntPtr dwValue) => HIWORD((uint)dwValue.ToUInt64());
/// <summary>Determines whether a value is an integer identifier for a resource.</summary>
/// <param name="ptr">The pointer to be tested whether it contains an integer resource identifier.</param>
/// <returns>If the value is a resource identifier, the return value is TRUE. Otherwise, the return value is FALSE.</returns>
[PInvokeData("WinBase.h", MSDNShortId = "ms648028")]
public static bool IS_INTRESOURCE(IntPtr ptr) => ptr.ToInt64() >> 16 == 0;
/// <summary>Retrieves the low-order byte from the given 16-bit value.</summary>
/// <param name="wValue">The value to be converted.</param>
/// <returns>The return value is the low-order byte of the specified value.</returns>
@ -45,6 +51,15 @@ namespace Vanara.PInvoke
/// <returns>The return value is the low-order word of the specified value.</returns>
public static ushort LOWORD(UIntPtr dwValue) => LOWORD((uint)dwValue.ToUInt64());
/// <summary>
/// Converts an integer value to a resource type compatible with the resource-management functions. This macro is used in place of a
/// string containing the name of the resource.
/// </summary>
/// <param name="id">The integer value to be converted.</param>
/// <returns>The return value is string representation of the integer value.</returns>
[PInvokeData("WinUser.h", MSDNShortId = "ms648029")]
public static ResourceId MAKEINTRESOURCE(int id) => id;
/// <summary>Creates a LONG value by concatenating the specified values.</summary>
/// <param name="wLow">The low-order word of the new value.</param>
/// <param name="wHigh">The high-order word of the new value.</param>
@ -88,21 +103,6 @@ namespace Vanara.PInvoke
/// <param name="iValue">The value to be converted.</param>
/// <returns>The return value is the low-order 16-bit value of the specified value.</returns>
public static short SignedLOWORD(IntPtr iValue) => SignedLOWORD(unchecked((int)iValue.ToInt64()));
/// <summary>Determines whether a value is an integer identifier for a resource.</summary>
/// <param name="ptr">The pointer to be tested whether it contains an integer resource identifier.</param>
/// <returns>If the value is a resource identifier, the return value is TRUE. Otherwise, the return value is FALSE.</returns>
[PInvokeData("WinBase.h", MSDNShortId = "ms648028")]
public static bool IS_INTRESOURCE(IntPtr ptr) => ptr.ToInt64() >> 16 == 0;
/// <summary>
/// Converts an integer value to a resource type compatible with the resource-management functions. This macro is used in place of a string containing
/// the name of the resource.
/// </summary>
/// <param name="id">The integer value to be converted.</param>
/// <returns>The return value is string representation of the integer value.</returns>
[PInvokeData("WinUser.h", MSDNShortId = "ms648029")]
public static SafeResourceId MAKEINTRESOURCE(int id) => new SafeResourceId(id);
}
//public static T GetLParam<T>(this System.Windows.Forms.Message msg) => (T)msg.GetLParam(typeof(T));

View File

@ -1,7 +1,4 @@
// ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
namespace Vanara.PInvoke
{
/// <summary>The flags that specify how an application is to be displayed when it is opened.</summary>
[PInvokeData("WinUser.h", MSDNShortId = "bb759784")]
@ -11,14 +8,14 @@ namespace Vanara.PInvoke
SW_HIDE = 0,
/// <summary>
/// Activates and displays a window. If the window is minimized or maximized, Windows restores it to its original size and position. An application
/// should specify this flag when displaying the window for the first time.
/// Activates and displays a window. If the window is minimized or maximized, Windows restores it to its original size and position.
/// An application should specify this flag when displaying the window for the first time.
/// </summary>
SW_SHOWNORMAL = 1,
/// <summary>
/// Activates and displays a window. If the window is minimized or maximized, Windows restores it to its original size and position. An application
/// should specify this flag when displaying the window for the first time.
/// Activates and displays a window. If the window is minimized or maximized, Windows restores it to its original size and position.
/// An application should specify this flag when displaying the window for the first time.
/// </summary>
SW_NORMAL = 1,
@ -47,20 +44,21 @@ namespace Vanara.PInvoke
SW_SHOWNA = 8,
/// <summary>
/// Activates and displays the window. If the window is minimized or maximized, Windows restores it to its original size and position. An application
/// should specify this flag when restoring a minimized window.
/// Activates and displays the window. If the window is minimized or maximized, Windows restores it to its original size and
/// position. An application should specify this flag when restoring a minimized window.
/// </summary>
SW_RESTORE = 9,
/// <summary>
/// Sets the show state based on the SW_ flag specified in the STARTUPINFO structure passed to the CreateProcess function by the program that started
/// the application. An application should call ShowWindow with this flag to set the initial show state of its main window.
/// Sets the show state based on the SW_ flag specified in the STARTUPINFO structure passed to the CreateProcess function by the
/// program that started the application. An application should call ShowWindow with this flag to set the initial show state of its
/// main window.
/// </summary>
SW_SHOWDEFAULT = 10,
/// <summary>
/// Minimizes a window, even if the thread that owns the window is not responding. This flag should only be used when minimizing windows from a
/// different thread.
/// Minimizes a window, even if the thread that owns the window is not responding. This flag should only be used when minimizing
/// windows from a different thread.
/// </summary>
SW_FORCEMINIMIZE = 11,
}

View File

@ -17,8 +17,8 @@
COLOR_ACTIVECAPTION = 2,
/// <summary>
/// Inactive window caption. The associated foreground color is COLOR_INACTIVECAPTIONTEXT. Specifies the left side color in the
/// color gradient of an inactive window's title bar if the gradient effect is enabled.
/// Inactive window caption. The associated foreground color is COLOR_INACTIVECAPTIONTEXT. Specifies the left side color in the color
/// gradient of an inactive window's title bar if the gradient effect is enabled.
/// </summary>
COLOR_INACTIVECAPTION = 3,
@ -70,8 +70,8 @@
COLOR_BTNTEXT = 18,
/// <summary>
/// Inactive window caption. The associated foreground color is COLOR_INACTIVECAPTIONTEXT. Specifies the left side color in the
/// color gradient of an inactive window's title bar if the gradient effect is enabled.
/// Inactive window caption. The associated foreground color is COLOR_INACTIVECAPTIONTEXT. Specifies the left side color in the color
/// gradient of an inactive window's title bar if the gradient effect is enabled.
/// </summary>
COLOR_INACTIVECAPTIONTEXT = 19,
@ -94,8 +94,8 @@
COLOR_HOTLIGHT = 26,
/// <summary>
/// Right side color in the color gradient of an active window's title bar. COLOR_ACTIVECAPTION specifies the left side color.
/// Use SPI_GETGRADIENTCAPTIONS with the SystemParametersInfo function to determine whether the gradient effect is enabled.
/// Right side color in the color gradient of an active window's title bar. COLOR_ACTIVECAPTION specifies the left side color. Use
/// SPI_GETGRADIENTCAPTIONS with the SystemParametersInfo function to determine whether the gradient effect is enabled.
/// </summary>
COLOR_GRADIENTACTIVECAPTION = 27,
@ -105,14 +105,14 @@
COLOR_GRADIENTINACTIVECAPTION = 28,
/// <summary>
/// The color used to highlight menu items when the menu appears as a flat menu (see SystemParametersInfo). The highlighted menu
/// item is outlined with COLOR_HIGHLIGHT. Windows 2000: This value is not supported.
/// The color used to highlight menu items when the menu appears as a flat menu (see SystemParametersInfo). The highlighted menu item
/// is outlined with COLOR_HIGHLIGHT. Windows 2000: This value is not supported.
/// </summary>
COLOR_MENUHILIGHT = 29,
/// <summary>
/// The background color for the menu bar when menus appear as flat menus (see SystemParametersInfo). However, COLOR_MENU
/// continues to specify the background color of the menu popup. Windows 2000: This value is not supported.
/// The background color for the menu bar when menus appear as flat menus (see SystemParametersInfo). However, COLOR_MENU continues
/// to specify the background color of the menu popup. Windows 2000: This value is not supported.
/// </summary>
COLOR_MENUBAR = 30,

View File

@ -11,13 +11,16 @@ namespace Vanara.PInvoke
{
/// <summary>Prompt the user for input or not, whichever is the default behavior.</summary>
OLECMDEXECOPT_DODEFAULT = 0,
/// <summary>Execute the command after obtaining user input.</summary>
OLECMDEXECOPT_PROMPTUSER = 1,
/// <summary>
/// Execute the command without prompting the user. For example, clicking the Print toolbar button causes a document to be
/// immediately printed without user input.
/// </summary>
OLECMDEXECOPT_DONTPROMPTUSER = 2,
/// <summary>Show help for the corresponding command, but do not execute.</summary>
OLECMDEXECOPT_SHOWHELP = 3
}
@ -28,14 +31,19 @@ namespace Vanara.PInvoke
{
/// <summary>The command is supported by this object.</summary>
OLECMDF_SUPPORTED = 0x00000001,
/// <summary>The command is available and enabled.</summary>
OLECMDF_ENABLED = 0x00000002,
/// <summary>The command is an on-off toggle and is currently on.</summary>
OLECMDF_LATCHED = 0x00000004,
/// <summary>Reserved for future use.</summary>
OLECMDF_NINCHED = 0x00000008,
/// <summary>The command is hidden.</summary>
OLECMDF_INVISIBLE = 0x00000010,
/// <summary>The command is hidden on the context menu.</summary>
OLECMDF_DEFHIDEONCTXTMENU = 0x00000020,
}
@ -134,10 +142,13 @@ namespace Vanara.PInvoke
{
/// <summary>The window is visible.</summary>
OLECMDIDF_WINDOWSTATE_USERVISIBLE = 0x01,
/// <summary>The window has focus.</summary>
OLECMDIDF_WINDOWSTATE_ENABLED = 0x02,
/// <summary>The window is visible and valid.</summary>
OLECMDIDF_WINDOWSTATE_USERVISIBLE_VALID = 0x00010000,
/// <summary>The window has focus and is valid.</summary>
OLECMDIDF_WINDOWSTATE_ENABLED_VALID = 0x00020000
}
@ -152,29 +163,35 @@ namespace Vanara.PInvoke
{
/// <summary>No extra information is requested.</summary>
OLECMDTEXTF_NONE = 0,
/// <summary>The object should provide the localized name of the command.</summary>
OLECMDTEXTF_NAME = 1,
/// <summary>The object should provide a localized status string for the command.</summary>
OLECMDTEXTF_STATUS = 2,
}
/// <summary>
/// <para>
/// Enables objects and their containers to dispatch commands to each other. For example, an object's toolbars may contain buttons
/// for commands such as Print, Print Preview, Save, New, and Zoom.
/// for commands such as <c>Print</c>, <c>Print Preview</c>, <c>Save</c>, <c>New</c>, and <c>Zoom</c>.
/// </para>
/// <para>
/// Normal in-place activation guidelines recommend that you remove or disable such buttons because no efficient, standard mechanism
/// has been available to dispatch them to the container.Similarly, a container has heretofore had no efficient means to send
/// commands such as Print, Page Setup, and Properties to an in-place active object. Such simple command routing could have been
/// handled through existing OLE Automation standards and the IDispatch interface, but the overhead with IDispatch is more than is
/// required in the case of document objects.The IOleCommandTarget interface provides a simpler means to achieve the same ends.
/// has been available to dispatch them to the container. Similarly, a container has heretofore had no efficient means to send
/// commands such as <c>Print</c>, <c>Page Setup</c>, and <c>Properties</c> to an in-place active object. Such simple command routing
/// could have been handled through existing OLE Automation standards and the <c>IDispatch</c> interface, but the overhead with
/// IDispatch is more than is required in the case of document objects. The <c>IOleCommandTarget</c> interface provides a simpler
/// means to achieve the same ends.
/// </para>
/// <para>
/// Available commands are defined by integer identifiers in a group. The group itself is identified with a GUID. The interface
/// allows a caller both to query for support of one or more commands within a group and to issue a supported command to the object.
/// </para>
/// </summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/docobj/nn-docobj-iolecommandtarget
[PInvokeData("docobj.h", MSDNShortId = "5c8b455e-7740-4f71-aef6-27390a11a1a3")]
[ComImport, Guid("B722BCCB-4E68-101B-A2BC-00AA00404770"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[PInvokeData("docobj.h")]
public interface IOleCommandTarget
{
/// <summary>Queries the object for the status of one or more commands generated by user interface events.</summary>
@ -206,7 +223,7 @@ namespace Vanara.PInvoke
/// <param name="pvaOut">Pointer to a VARIANTARG structure to receive command output. This parameter can be NULL.</param>
/// <returns>This method returns S_OK on success.</returns>
[PreserveSig]
HRESULT Exec(in Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, [In, MarshalAs(UnmanagedType.LPArray)] object[] pvaIn, IntPtr pvaOut);
HRESULT Exec(in Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, in object pvaIn, ref object pvaOut);
}
/// <summary>Associates command flags from the OLECMDF enumeration with a command identifier through a call to IOleCommandTarget::QueryStatus.</summary>
@ -222,7 +239,7 @@ namespace Vanara.PInvoke
}
/// <summary>Specifies a text name or status string for a single command identifier.</summary>
[StructLayout(LayoutKind.Sequential)]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class OLECMDTEXT : IDisposable
{
/// <summary>
@ -256,10 +273,7 @@ namespace Vanara.PInvoke
/// <returns>A <see cref="string"/> that represents this instance.</returns>
public override string ToString() => rgwz;
void IDisposable.Dispose()
{
_rgwz.Free();
}
void IDisposable.Dispose() => _rgwz.Free();
}
}
}

View File

@ -1,9 +1,7 @@
using System;
using System.Linq;
using Vanara.Extensions;
using static Vanara.PInvoke.AdvApi32;
using static Vanara.PInvoke.Shell32;
// ReSharper disable InconsistentNaming
namespace Vanara.PInvoke
{
@ -23,7 +21,16 @@ namespace Vanara.PInvoke
public static string FullPath(this KNOWNFOLDERID id)
{
SHGetKnownFolderPath(id.Guid(), stdGetFlags, HTOKEN.NULL, out var path);
return path.ToString(-1);
return path;
}
/// <summary>Retrieves the IShellItem associated with a <see cref="KNOWNFOLDERID"/>.</summary>
/// <param name="id">The known folder.</param>
/// <returns>The <see cref="IShellItem"/> instance.</returns>
public static IShellItem GetIShellItem(this KNOWNFOLDERID id)
{
SHGetKnownFolderItem(id.Guid(), KNOWN_FOLDER_FLAG.KF_FLAG_DEFAULT, HTOKEN.NULL, typeof(IShellItem).GUID, out var ppv).ThrowIfFailed();
return (IShellItem)ppv;
}
/// <summary>Gets a registry property associated with this known folder.</summary>
@ -39,15 +46,6 @@ namespace Vanara.PInvoke
/// <returns>The GUID associated with the <paramref name="id"/> or <see cref="Guid.Empty"/> if no association exists.</returns>
public static Guid Guid(this KNOWNFOLDERID id) => AssociateAttribute.GetGuidFromEnum(id);
/// <summary>Retrieves the IShellItem associated with a <see cref="KNOWNFOLDERID"/>.</summary>
/// <param name="id">The known folder.</param>
/// <returns>The <see cref="IShellItem"/> instance.</returns>
public static IShellItem GetIShellItem(this KNOWNFOLDERID id)
{
SHGetKnownFolderItem(id.Guid(), KNOWN_FOLDER_FLAG.KF_FLAG_DEFAULT, HTOKEN.NULL, typeof(IShellItem).GUID, out var ppv).ThrowIfFailed();
return (IShellItem) ppv;
}
/// <summary>Retrieves the <see cref="KNOWNFOLDERID"/> associated with the <see cref="Environment.SpecialFolder"/>.</summary>
/// <param name="spFolder">The <see cref="Environment.SpecialFolder"/>.</param>
/// <returns>Matching <see cref="KNOWNFOLDERID"/>.</returns>

View File

@ -2,14 +2,6 @@
using System.Runtime.InteropServices;
using System.Security;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedParameter.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable InconsistentNaming
// ReSharper disable MemberHidesStaticFromOuterClass
// ReSharper disable UnusedMethodReturnValue.Global
namespace Vanara.PInvoke
{
public static partial class Shell32

Some files were not shown because too many files have changed in this diff Show More