mirror of https://github.com/dahall/Vanara.git
209 lines
8.3 KiB
C#
209 lines
8.3 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using Vanara.Extensions;
|
|
|
|
namespace Vanara.PInvoke
|
|
{
|
|
public static partial class AdvApi32
|
|
{
|
|
/// <summary>
|
|
/// <para>
|
|
/// The <c>LSA_OBJECT_ATTRIBUTES</c> structure is used with the LsaOpenPolicy function to specify the attributes of the connection to
|
|
/// the Policy object.
|
|
/// </para>
|
|
/// <para>
|
|
/// When you call LsaOpenPolicy, initialize the members of this structure to <c>NULL</c> or zero because the function does not use
|
|
/// the information.
|
|
/// </para>
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>The <c>LSA_OBJECT_ATTRIBUTES</c> structure is defined in the LsaLookup.h header file.</para>
|
|
/// <para>
|
|
/// <c>Windows Server 2008 with SP2 and earlier, Windows Vista with SP2 and earlier, Windows Server 2003, Windows XP/2000:</c> The
|
|
/// <c>LSA_OBJECT_ATTRIBUTES</c> structure is defined in the NTSecAPI.h header file.
|
|
/// </para>
|
|
/// </remarks>
|
|
// https://docs.microsoft.com/en-us/windows/desktop/api/lsalookup/ns-lsalookup-_lsa_object_attributes typedef struct
|
|
// _LSA_OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PLSA_UNICODE_STRING ObjectName; ULONG Attributes; PVOID
|
|
// SecurityDescriptor; PVOID SecurityQualityOfService; } LSA_OBJECT_ATTRIBUTES, *PLSA_OBJECT_ATTRIBUTES;
|
|
[PInvokeData("lsalookup.h", MSDNShortId = "ad05cb52-8e58-46a9-b3e8-0c9c2a24a997")]
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct LSA_OBJECT_ATTRIBUTES
|
|
{
|
|
/// <summary>Specifies the size, in bytes, of the LSA_OBJECT_ATTRIBUTES structure.</summary>
|
|
public int Length;
|
|
|
|
/// <summary>Should be <c>NULL</c>.</summary>
|
|
public IntPtr RootDirectory;
|
|
|
|
/// <summary>Should be <c>NULL</c>.</summary>
|
|
public IntPtr ObjectName;
|
|
|
|
/// <summary>Should be zero.</summary>
|
|
public int Attributes;
|
|
|
|
/// <summary>Should be <c>NULL</c>.</summary>
|
|
public IntPtr SecurityDescriptor;
|
|
|
|
/// <summary>Should be <c>NULL</c>.</summary>
|
|
public IntPtr SecurityQualityOfService;
|
|
|
|
/// <summary>Returns a completely empty reference. This value should be used when calling <see cref="LsaOpenPolicy(string, in LSA_OBJECT_ATTRIBUTES, LsaPolicyRights, out SafeLSA_HANDLE)"/>.</summary>
|
|
/// <value>An <see cref="LSA_OBJECT_ATTRIBUTES"/> instance with all members set to <c>NULL</c> or zero.</value>
|
|
public static LSA_OBJECT_ATTRIBUTES Empty { get; } = new LSA_OBJECT_ATTRIBUTES();
|
|
}
|
|
|
|
/// <summary>
|
|
/// The LSA_STRING structure is used by various Local Security Authority (LSA) functions to specify a string. Also an example of
|
|
/// unnecessary over-engineering and re-engineering.
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Size = 8)]
|
|
[PInvokeData("LsaLookup.h", MSDNShortId = "aa378522")]
|
|
public struct LSA_STRING
|
|
{
|
|
/// <summary>
|
|
/// Specifies the length, in bytes, of the string pointed to by the Buffer member, not including the terminating null character,
|
|
/// if any.
|
|
/// </summary>
|
|
public ushort length;
|
|
|
|
/// <summary>
|
|
/// Specifies the total size, in bytes, of the memory allocated for Buffer. Up to MaximumLength bytes can be written into the
|
|
/// buffer without trampling memory.
|
|
/// </summary>
|
|
public ushort MaximumLength;
|
|
|
|
/// <summary>Pointer to a string. Note that the strings returned by the various LSA functions might not be null-terminated.</summary>
|
|
public string Buffer;
|
|
|
|
/// <summary>Initializes a new instance of the <see cref="LSA_STRING"/> struct from a string.</summary>
|
|
/// <param name="s">The string value.</param>
|
|
/// <exception cref="ArgumentException">String exceeds 32Kb of data.</exception>
|
|
public LSA_STRING(string s)
|
|
{
|
|
if (s == null)
|
|
{
|
|
length = MaximumLength = 0;
|
|
Buffer = null;
|
|
}
|
|
else
|
|
{
|
|
var l = s.Length;
|
|
if (l >= ushort.MaxValue)
|
|
throw new ArgumentException("String too long");
|
|
Buffer = s;
|
|
length = (ushort)l;
|
|
MaximumLength = (ushort)(l + 1);
|
|
}
|
|
}
|
|
|
|
/// <summary>Gets the number of characters in the string.</summary>
|
|
public int Length => length;
|
|
|
|
/// <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.Substring(0, Length);
|
|
|
|
/// <summary>Performs an implicit conversion from <see cref="LSA_STRING"/> to <see cref="string"/>.</summary>
|
|
/// <param name="value">The value.</param>
|
|
/// <returns>The result of the conversion.</returns>
|
|
public static implicit operator string(LSA_STRING value) => value.ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>
|
|
/// The <c>LSA_TRANSLATED_NAME</c> structure is used with the LsaLookupSids function to return information about the account
|
|
/// identified by a SID.
|
|
/// </para>
|
|
/// </summary>
|
|
// https://docs.microsoft.com/en-us/windows/desktop/api/lsalookup/ns-lsalookup-_lsa_translated_name typedef struct
|
|
// _LSA_TRANSLATED_NAME { SID_NAME_USE Use; LSA_UNICODE_STRING Name; LONG DomainIndex; } LSA_TRANSLATED_NAME, *PLSA_TRANSLATED_NAME;
|
|
[PInvokeData("lsalookup.h", MSDNShortId = "edea8317-5cdf-4d1e-9e6d-fcf17b91adb7")]
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct LSA_TRANSLATED_NAME
|
|
{
|
|
/// <summary>An SID_NAME_USE enumeration value that identifies the type of SID.</summary>
|
|
public SID_NAME_USE Use;
|
|
|
|
/// <summary>
|
|
/// An LSA_UNICODE_STRING structure that contains the isolated name of the translated SID. An isolated name is a user, group, or
|
|
/// local group account name without the domain name (for example, user_name, rather than Acctg\user_name).
|
|
/// </summary>
|
|
public LSA_UNICODE_STRING Name;
|
|
|
|
/// <summary>
|
|
/// The index of an entry in a related LSA_REFERENCED_DOMAIN_LIST data structure which describes the domain that owns the
|
|
/// account. If there is no corresponding reference domain for an entry, then DomainIndex will contain a negative value.
|
|
/// </summary>
|
|
public int DomainIndex;
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>
|
|
/// The <c>LSA_TRANSLATED_SID2</c> structure contains SIDs that are retrieved based on account names. This structure is used by the
|
|
/// LsaLookupNames2 function.
|
|
/// </para>
|
|
/// </summary>
|
|
// https://docs.microsoft.com/en-us/windows/desktop/api/lsalookup/ns-lsalookup-_lsa_translated_sid2 typedef struct
|
|
// _LSA_TRANSLATED_SID2 { SID_NAME_USE Use; PSID Sid; LONG DomainIndex; ULONG Flags; } LSA_TRANSLATED_SID2, *PLSA_TRANSLATED_SID2;
|
|
[PInvokeData("lsalookup.h", MSDNShortId = "792de958-8e24-46d8-b484-159435bc96e3")]
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct LSA_TRANSLATED_SID2
|
|
{
|
|
/// <summary>
|
|
/// An SID_NAME_USE enumeration value that identifies the use of the SID. If this value is SidTypeUnknown or SidTypeInvalid, the
|
|
/// rest of the information in the structure is not valid and should be ignored.
|
|
/// </summary>
|
|
public SID_NAME_USE Use;
|
|
|
|
/// <summary>The complete SID of the account.</summary>
|
|
public PSID Sid;
|
|
|
|
/// <summary>
|
|
/// The index of an entry in a related LSA_REFERENCED_DOMAIN_LIST data structure which describes the domain that owns the
|
|
/// account. If there is no corresponding reference domain for an entry, then DomainIndex will contain a negative value.
|
|
/// </summary>
|
|
public int DomainIndex;
|
|
|
|
/// <summary>Not used.</summary>
|
|
public uint Flags;
|
|
}
|
|
|
|
/// <summary>A custom marshaler for functions using LSA_STRING so that managed strings can be used.</summary>
|
|
/// <seealso cref="ICustomMarshaler"/>
|
|
internal class LsaStringMarshaler : ICustomMarshaler
|
|
{
|
|
public static ICustomMarshaler GetInstance(string cookie) => new LsaStringMarshaler();
|
|
|
|
public void CleanUpManagedData(object ManagedObj)
|
|
{
|
|
}
|
|
|
|
public void CleanUpNativeData(IntPtr pNativeData)
|
|
{
|
|
if (pNativeData == IntPtr.Zero) return;
|
|
Marshal.FreeCoTaskMem(pNativeData);
|
|
pNativeData = IntPtr.Zero;
|
|
}
|
|
|
|
public int GetNativeDataSize() => Marshal.SizeOf(typeof(LSA_STRING));
|
|
|
|
public IntPtr MarshalManagedToNative(object ManagedObj)
|
|
{
|
|
var s = ManagedObj as string;
|
|
if (s == null) return IntPtr.Zero;
|
|
var str = new LSA_STRING(s);
|
|
return str.MarshalToPtr(Marshal.AllocCoTaskMem, out var _);
|
|
}
|
|
|
|
public object MarshalNativeToManaged(IntPtr pNativeData)
|
|
{
|
|
if (pNativeData == IntPtr.Zero) return null;
|
|
var ret = pNativeData.ToStructure<LSA_STRING>();
|
|
var s = (string)ret.ToString().Clone();
|
|
//LsaFreeMemory(pNativeData);
|
|
return s;
|
|
}
|
|
}
|
|
}
|
|
} |