Vanara/PInvoke/Security/AdvApi32/AclApi.cs

1593 lines
89 KiB
C#

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
public static partial class AdvApi32
{
/// <summary>A function used to track the progress of the TreeResetNamedSecurityInfo and TreeSetNamedSecurityInfo functions.</summary>
/// <param name="pObjectName">Name of object just processed.</param>
/// <param name="Status">Status of operation on object.</param>
/// <param name="pInvokeSetting">When to set.</param>
/// <param name="Args">Caller specific data.</param>
/// <param name="SecuritySet">Whether security was set.</param>
[PInvokeData("aclapi.h", MSDNShortId = "caa711c3-301b-4ed7-b1f4-dc6a48563905")]
[UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
public delegate void FN_PROGRESS(string pObjectName, uint Status, ref PROG_INVOKE_SETTING pInvokeSetting, IntPtr Args, [MarshalAs(UnmanagedType.Bool)] bool SecuritySet);
/// <summary>Flags to control the behavior of <see cref="TreeSetNamedSecurityInfo"/>.</summary>
[PInvokeData("aclapi.h", MSDNShortId = "caa711c3-301b-4ed7-b1f4-dc6a48563905")]
public enum TREE_SEC_INFO
{
/// <summary>
/// The security information is set on the object specified by the pObjectName parameter and the tree of child objects of that
/// object. If ACLs are specified in either the pDacl or pSacl parameters, the security descriptors are associated with the
/// object. The security descriptors are propagated to the tree of child objects based on their inheritance properties.
/// </summary>
TREE_SEC_INFO_SET = 0x00000001,
/// <summary>
/// The security information is reset on the object specified by the pObjectName parameter and the tree of child objects of that
/// object. Any existing security information is removed from all objects on the tree.
/// <para>
/// If any object in the tree does not grant appropriate permissions to the caller to modify the security descriptor on the
/// object, then the propagation of security information on that particular node of the tree and its objects is skipped. The
/// operation continues on the rest of the tree under the object specified by the pObjectName parameter.
/// </para>
/// </summary>
TREE_SEC_INFO_RESET = 0x00000002,
/// <summary>
/// The security information is reset on the object specified by the pObjectName parameter and the tree of child objects of that
/// object. Any existing inherited security information is removed from all objects on the tree. Security information that was
/// explicitly set on objects in the tree is unchanged.
/// <para>
/// If any object in the tree does not grant appropriate permissions to the caller to modify the security descriptor on the
/// object, then the propagation of security information on that particular node of the tree and its objects is skipped. The
/// operation continues on the rest of the tree under the object specified by the pObjectName parameter.
/// </para>
/// </summary>
TREE_SEC_INFO_RESET_KEEP_EXPLICIT = 0x00000003,
}
/// <summary>
/// <para>
/// The <c>BuildExplicitAccessWithName</c> function initializes an EXPLICIT_ACCESS structure with data specified by the caller. The
/// trustee is identified by a name string.
/// </para>
/// </summary>
/// <param name="pExplicitAccess">
/// <para>
/// A pointer to an EXPLICIT_ACCESS structure to initialize. The <c>BuildExplicitAccessWithName</c> function does not allocate any
/// memory. This parameter cannot be <c>NULL</c>.
/// </para>
/// </param>
/// <param name="pTrusteeName">
/// <para>
/// A pointer to a <c>null</c>-terminated string that contains the name of the trustee for the <c>ptstrName</c> member of the TRUSTEE
/// structure. The <c>BuildExplicitAccessWithName</c> function sets the other members of the <c>TRUSTEE</c> structure as follows.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>pMultipleTrustee</term>
/// <term>NULL</term>
/// </item>
/// <item>
/// <term>MultipleTrusteeOperation</term>
/// <term>NO_MULTIPLE_TRUSTEE</term>
/// </item>
/// <item>
/// <term>TrusteeForm</term>
/// <term>TRUSTEE_IS_NAME</term>
/// </item>
/// <item>
/// <term>TrusteeType</term>
/// <term>TRUSTEE_IS_UNKNOWN</term>
/// </item>
/// </list>
/// </param>
/// <param name="AccessPermissions">
/// <para>
/// Specifies an access mask for the <c>grfAccessPermissions</c> member of the EXPLICIT_ACCESS structure. The mask is a set of bit
/// flags that use the ACCESS_MASK format to specify the access rights that an ACE allows, denies, or audits for the trustee. The
/// functions that use the <c>EXPLICIT_ACCESS</c> structure do not convert, interpret, or validate the bits in this mask.
/// </para>
/// </param>
/// <param name="AccessMode">
/// <para>
/// Specifies an access mode for the <c>grfAccessMode</c> member of the EXPLICIT_ACCESS structure. The access mode indicates whether
/// the access control entry (ACE) allows, denies, or audits the specified rights. For a discretionary access control list (DACL),
/// this parameter can be one of the values from the ACCESS_MODE enumeration. For a system access control list (SACL), this parameter
/// can be a combination of <c>ACCESS_MODE</c> values.
/// </para>
/// </param>
/// <param name="Inheritance">
/// <para>
/// Specifies an inheritance type for the <c>grfInheritance</c> member of the EXPLICIT_ACCESS structure. This value is a set of bit
/// flags that determine whether other containers or objects can inherit the ACE from the primary object to which the ACL is
/// attached. The value of this member corresponds to the inheritance portion (low-order byte) of the <c>AceFlags</c> member of the
/// ACE_HEADER structure. This parameter can be NO_INHERITANCE to indicate that the ACE is not inheritable, or it can be a
/// combination of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CONTAINER_INHERIT_ACE</term>
/// <term>Other containers that are contained by the primary object inherit the ACE.</term>
/// </item>
/// <item>
/// <term>INHERIT_ONLY_ACE</term>
/// <term>
/// The ACE does not apply to the primary object to which the ACL is attached, but objects contained by the primary object inherit
/// the ACE.
/// </term>
/// </item>
/// <item>
/// <term>NO_PROPAGATE_INHERIT_ACE</term>
/// <term>The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE flags are not propagated to an inherited ACE.</term>
/// </item>
/// <item>
/// <term>OBJECT_INHERIT_ACE</term>
/// <term>Noncontainer objects contained by the primary object inherit the ACE.</term>
/// </item>
/// <item>
/// <term>SUB_CONTAINERS_AND_OBJECTS_INHERIT</term>
/// <term>
/// Both containers and noncontainer objects that are contained by the primary object inherit the ACE. This flag corresponds to the
/// combination of the CONTAINER_INHERIT_ACE and OBJECT_INHERIT_ACE flags.
/// </term>
/// </item>
/// <item>
/// <term>SUB_CONTAINERS_ONLY_INHERIT</term>
/// <term>
/// Other containers that are contained by the primary object inherit the ACE. This flag corresponds to the combination of the
/// CONTAINER_INHERIT_ACE and INHERIT_ONLY_ACE flags.
/// </term>
/// </item>
/// <item>
/// <term>SUB_OBJECTS_ONLY_INHERIT</term>
/// <term>
/// Noncontainer objects contained by the primary object inherit the ACE. This flag corresponds to the combination of the
/// OBJECT_INHERIT_ACE and INHERIT_ONLY_ACE flags.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>This function does not return a value.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-buildexplicitaccesswithnamea void
// BuildExplicitAccessWithNameA( PEXPLICIT_ACCESS_A pExplicitAccess, LPSTR pTrusteeName, DWORD AccessPermissions, ACCESS_MODE
// AccessMode, DWORD Inheritance );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "5f12db19-63cf-4be6-9450-3c36e425967b")]
public static extern void BuildExplicitAccessWithName(out EXPLICIT_ACCESS pExplicitAccess, string pTrusteeName, uint AccessPermissions, ACCESS_MODE AccessMode, INHERIT_FLAGS Inheritance);
/// <summary>
/// <para>
/// The <c>BuildSecurityDescriptor</c> function allocates and initializes a new security descriptor. This function can initialize the
/// new security descriptor by merging specified security information with the information in an existing security descriptor. If you
/// do not specify an existing security descriptor, the function initializes a new security descriptor based on the specified
/// security information.
/// </para>
/// <para>
/// The <c>BuildSecurityDescriptor</c> function creates a self-relative security descriptor. The self-relative format makes the
/// security descriptor suitable for storing in a stream.
/// </para>
/// </summary>
/// <param name="pOwner">
/// <para>
/// A pointer to a TRUSTEE structure that identifies the owner for the new security descriptor. If the structure uses the
/// TRUSTEE_IS_NAME form, <c>BuildSecurityDescriptor</c> looks up the security identifier (SID) associated with the specified trustee name.
/// </para>
/// <para>
/// If this parameter is <c>NULL</c>, the function uses the owner SID from the original security descriptor pointed to by pOldSD. If
/// pOldSD is <c>NULL</c>, or if the owner SID in pOldSD is <c>NULL</c>, the owner SID is <c>NULL</c> in the new security descriptor.
/// </para>
/// </param>
/// <param name="pGroup">
/// <para>
/// A pointer to a TRUSTEE structure that identifies the primary group SID for the new security descriptor. If the structure uses the
/// TRUSTEE_IS_NAME form, <c>BuildSecurityDescriptor</c> looks up the SID associated with the specified trustee name.
/// </para>
/// <para>
/// If this parameter is <c>NULL</c>, the function uses the group SID from the original security descriptor pointed to by pOldSD. If
/// pOldSD is <c>NULL</c>, or if the group SID in pOldSD is <c>NULL</c>, the group SID is <c>NULL</c> in the new security descriptor.
/// </para>
/// </param>
/// <param name="cCountOfAccessEntries">
/// <para>The number of EXPLICIT_ACCESS structures in the pListOfAccessEntries array.</para>
/// </param>
/// <param name="pListOfAccessEntries">
/// <para>
/// A pointer to an array of EXPLICIT_ACCESS structures that describe access control information for the discretionary access control
/// list (DACL) of the new security descriptor. The function creates the new DACL by merging the information in the array with the
/// DACL in pOldSD, if any. If pOldSD is <c>NULL</c>, or if the DACL in pOldSD is <c>NULL</c>, the function creates a new DACL based
/// solely on the information in the array. For a description of the rules for creating an ACL from an array of
/// <c>EXPLICIT_ACCESS</c> structures, see the SetEntriesInAcl function.
/// </para>
/// <para>
/// If pListOfAccessEntries is <c>NULL</c>, the new security descriptor gets the DACL from pOldSD. In this case, if pOldSD is
/// <c>NULL</c>, or if the DACL in pOldSD is <c>NULL</c>, the new DACL is <c>NULL</c>.
/// </para>
/// </param>
/// <param name="cCountOfAuditEntries">
/// <para>The number of EXPLICIT_ACCESS structures in the pListOfAuditEntries array.</para>
/// </param>
/// <param name="pListOfAuditEntries">
/// <para>
/// A pointer to an array of EXPLICIT_ACCESS structures that describe audit control information for the SACL of the new security
/// descriptor. The function creates the new SACL by merging the information in the array with the SACL in pOldSD, if any. If pOldSD
/// is <c>NULL</c>, or the SACL in pOldSD is <c>NULL</c>, the function creates a new SACL based solely on the information in the array.
/// </para>
/// <para>
/// If pListOfAuditEntries is <c>NULL</c>, the new security descriptor gets the SACL from pOldSD. In this case, if pOldSD is
/// <c>NULL</c>, or the SACL in pOldSD is <c>NULL</c>, the new SACL is <c>NULL</c>.
/// </para>
/// </param>
/// <param name="pOldSD">
/// <para>
/// A pointer to an existing self-relative SECURITY_DESCRIPTOR structure and its associated security information. The function builds
/// the new security descriptor by merging the specified owner, group, access control, and audit-control information with the
/// information in this security descriptor. This parameter can be <c>NULL</c>.
/// </para>
/// </param>
/// <param name="pSizeNewSD">
/// <para>A pointer to a variable that receives the size, in bytes, of the security descriptor.</para>
/// </param>
/// <param name="pNewSD">
/// <para>
/// A pointer to a variable that receives a pointer to the new security descriptor. The function allocates memory for the new
/// security descriptor. You must call the LocalFree function to free the returned buffer.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns ERROR_SUCCESS.</para>
/// <para>If the function fails, it returns a nonzero error code defined in WinError.h.</para>
/// </returns>
/// <remarks>
/// <para>
/// The <c>BuildSecurityDescriptor</c> function is intended for trusted servers that implement or expose security on their own
/// objects. The function uses self-relative security descriptors suitable for serializing into a stream and storing to disk, as a
/// trusted server might require.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-buildsecuritydescriptora DWORD BuildSecurityDescriptorA(
// PTRUSTEE_A pOwner, PTRUSTEE_A pGroup, ULONG cCountOfAccessEntries, PEXPLICIT_ACCESS_A pListOfAccessEntries, ULONG
// cCountOfAuditEntries, PEXPLICIT_ACCESS_A pListOfAuditEntries, PSECURITY_DESCRIPTOR pOldSD, PULONG pSizeNewSD, PSECURITY_DESCRIPTOR
// *pNewSD );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "becc1218-5bc3-4ab2-86f8-3ebd10e16966")]
public static extern uint BuildSecurityDescriptor(in TRUSTEE pOwner, in TRUSTEE pGroup, [In, Optional] uint cCountOfAccessEntries, [In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] EXPLICIT_ACCESS[] pListOfAccessEntries,
[In, Optional] uint cCountOfAuditEntries, [In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] EXPLICIT_ACCESS[] pListOfAuditEntries, [In, Optional] PSECURITY_DESCRIPTOR pOldSD, out uint pSizeNewSD, out SafePSECURITY_DESCRIPTOR pNewSD);
/// <summary>
/// <para>
/// The <c>BuildSecurityDescriptor</c> function allocates and initializes a new security descriptor. This function can initialize the
/// new security descriptor by merging specified security information with the information in an existing security descriptor. If you
/// do not specify an existing security descriptor, the function initializes a new security descriptor based on the specified
/// security information.
/// </para>
/// <para>
/// The <c>BuildSecurityDescriptor</c> function creates a self-relative security descriptor. The self-relative format makes the
/// security descriptor suitable for storing in a stream.
/// </para>
/// </summary>
/// <param name="pOwner">
/// <para>
/// A pointer to a TRUSTEE structure that identifies the owner for the new security descriptor. If the structure uses the
/// TRUSTEE_IS_NAME form, <c>BuildSecurityDescriptor</c> looks up the security identifier (SID) associated with the specified trustee name.
/// </para>
/// <para>
/// If this parameter is <c>NULL</c>, the function uses the owner SID from the original security descriptor pointed to by pOldSD. If
/// pOldSD is <c>NULL</c>, or if the owner SID in pOldSD is <c>NULL</c>, the owner SID is <c>NULL</c> in the new security descriptor.
/// </para>
/// </param>
/// <param name="pGroup">
/// <para>
/// A pointer to a TRUSTEE structure that identifies the primary group SID for the new security descriptor. If the structure uses the
/// TRUSTEE_IS_NAME form, <c>BuildSecurityDescriptor</c> looks up the SID associated with the specified trustee name.
/// </para>
/// <para>
/// If this parameter is <c>NULL</c>, the function uses the group SID from the original security descriptor pointed to by pOldSD. If
/// pOldSD is <c>NULL</c>, or if the group SID in pOldSD is <c>NULL</c>, the group SID is <c>NULL</c> in the new security descriptor.
/// </para>
/// </param>
/// <param name="cCountOfAccessEntries">
/// <para>The number of EXPLICIT_ACCESS structures in the pListOfAccessEntries array.</para>
/// </param>
/// <param name="pListOfAccessEntries">
/// <para>
/// A pointer to an array of EXPLICIT_ACCESS structures that describe access control information for the discretionary access control
/// list (DACL) of the new security descriptor. The function creates the new DACL by merging the information in the array with the
/// DACL in pOldSD, if any. If pOldSD is <c>NULL</c>, or if the DACL in pOldSD is <c>NULL</c>, the function creates a new DACL based
/// solely on the information in the array. For a description of the rules for creating an ACL from an array of
/// <c>EXPLICIT_ACCESS</c> structures, see the SetEntriesInAcl function.
/// </para>
/// <para>
/// If pListOfAccessEntries is <c>NULL</c>, the new security descriptor gets the DACL from pOldSD. In this case, if pOldSD is
/// <c>NULL</c>, or if the DACL in pOldSD is <c>NULL</c>, the new DACL is <c>NULL</c>.
/// </para>
/// </param>
/// <param name="cCountOfAuditEntries">
/// <para>The number of EXPLICIT_ACCESS structures in the pListOfAuditEntries array.</para>
/// </param>
/// <param name="pListOfAuditEntries">
/// <para>
/// A pointer to an array of EXPLICIT_ACCESS structures that describe audit control information for the SACL of the new security
/// descriptor. The function creates the new SACL by merging the information in the array with the SACL in pOldSD, if any. If pOldSD
/// is <c>NULL</c>, or the SACL in pOldSD is <c>NULL</c>, the function creates a new SACL based solely on the information in the array.
/// </para>
/// <para>
/// If pListOfAuditEntries is <c>NULL</c>, the new security descriptor gets the SACL from pOldSD. In this case, if pOldSD is
/// <c>NULL</c>, or the SACL in pOldSD is <c>NULL</c>, the new SACL is <c>NULL</c>.
/// </para>
/// </param>
/// <param name="pOldSD">
/// <para>
/// A pointer to an existing self-relative SECURITY_DESCRIPTOR structure and its associated security information. The function builds
/// the new security descriptor by merging the specified owner, group, access control, and audit-control information with the
/// information in this security descriptor. This parameter can be <c>NULL</c>.
/// </para>
/// </param>
/// <param name="pSizeNewSD">
/// <para>A pointer to a variable that receives the size, in bytes, of the security descriptor.</para>
/// </param>
/// <param name="pNewSD">
/// <para>
/// A pointer to a variable that receives a pointer to the new security descriptor. The function allocates memory for the new
/// security descriptor. You must call the LocalFree function to free the returned buffer.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns ERROR_SUCCESS.</para>
/// <para>If the function fails, it returns a nonzero error code defined in WinError.h.</para>
/// </returns>
/// <remarks>
/// <para>
/// The <c>BuildSecurityDescriptor</c> function is intended for trusted servers that implement or expose security on their own
/// objects. The function uses self-relative security descriptors suitable for serializing into a stream and storing to disk, as a
/// trusted server might require.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-buildsecuritydescriptora DWORD BuildSecurityDescriptorA(
// PTRUSTEE_A pOwner, PTRUSTEE_A pGroup, ULONG cCountOfAccessEntries, PEXPLICIT_ACCESS_A pListOfAccessEntries, ULONG
// cCountOfAuditEntries, PEXPLICIT_ACCESS_A pListOfAuditEntries, PSECURITY_DESCRIPTOR pOldSD, PULONG pSizeNewSD, PSECURITY_DESCRIPTOR
// *pNewSD );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "becc1218-5bc3-4ab2-86f8-3ebd10e16966")]
public static extern uint BuildSecurityDescriptor([In, Optional] IntPtr pOwner, [In, Optional] IntPtr pGroup, [In, Optional] uint cCountOfAccessEntries, [In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] EXPLICIT_ACCESS[] pListOfAccessEntries,
[In, Optional] uint cCountOfAuditEntries, [In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] EXPLICIT_ACCESS[] pListOfAuditEntries, [In, Optional] PSECURITY_DESCRIPTOR pOldSD, out uint pSizeNewSD, out SafePSECURITY_DESCRIPTOR pNewSD);
/// <summary>
/// <para>
/// The <c>BuildTrusteeWithName</c> function initializes a TRUSTEE structure. The caller specifies the trustee name. The function
/// sets other members of the structure to default values.
/// </para>
/// </summary>
/// <param name="pTrustee">
/// <para>
/// A pointer to a TRUSTEE structure to initialize. The <c>BuildTrusteeWithName</c> function does not allocate any memory. If this
/// parameter is <c>NULL</c> or a pointer that is not valid, the results are undefined.
/// </para>
/// </param>
/// <param name="pName">
/// <para>
/// A pointer to a null-terminated string that contains the name of the trustee for the <c>ptstrName</c> member of the TRUSTEE
/// structure. The <c>BuildTrusteeWithName</c> function sets the other members of the <c>TRUSTEE</c> structure as follows.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>pMultipleTrustee</term>
/// <term>NULL</term>
/// </item>
/// <item>
/// <term>MultipleTrusteeOperation</term>
/// <term>NO_MULTIPLE_TRUSTEE</term>
/// </item>
/// <item>
/// <term>TrusteeForm</term>
/// <term>TRUSTEE_IS_NAME</term>
/// </item>
/// <item>
/// <term>TrusteeType</term>
/// <term>TRUSTEE_IS_UNKNOWN</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>This function does not return a value.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-buildtrusteewithnamea void BuildTrusteeWithNameA( PTRUSTEE_A
// pTrustee, LPSTR pName );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "a66c23ac-8211-40fd-bfe8-ef9089bf3745")]
public static extern void BuildTrusteeWithName(out TRUSTEE pTrustee, string pName);
/// <summary>
/// <para>
/// The <c>BuildTrusteeWithObjectsAndName</c> function initializes a TRUSTEE structure with the object-specific access control entry
/// (ACE) information and initializes the remaining members of the structure to default values. The caller also specifies the name of
/// the trustee.
/// </para>
/// </summary>
/// <param name="pTrustee">
/// <para>
/// A pointer to a TRUSTEE structure that will be initialized by this function. If the value of this parameter is <c>NULL</c> or a
/// pointer that is not valid, the results are undefined.
/// </para>
/// </param>
/// <param name="pObjName">
/// <para>A pointer to an OBJECTS_AND_NAME structure that contains information about the trustee and the securable object.</para>
/// </param>
/// <param name="ObjectType">
/// <para>A pointer to an SE_OBJECT_TYPE enumeration that contains information about the type of securable object.</para>
/// </param>
/// <param name="ObjectTypeName">
/// <para>
/// A pointer to a string that specifies the name that corresponds to the ObjectType GUID to be added to the TRUSTEE structure
/// returned in the pTrustee parameter. This function determines the ObjectType GUID that corresponds to this name.
/// </para>
/// </param>
/// <param name="InheritedObjectTypeName">
/// <para>
/// A pointer to a string that specifies the name that corresponds to the InheritedObjectType GUID to be added to the TRUSTEE
/// structure returned in the pTrustee parameter. This function determines the InheritedObjectType GUID that corresponds to this name.
/// </para>
/// </param>
/// <param name="Name">
/// <para>A pointer to a string that specifies the name used to identify the trustee.</para>
/// </param>
/// <returns>
/// <para>This function does not return a value.</para>
/// </returns>
/// <remarks>
/// <para>This function does not allocate memory for the TRUSTEE and OBJECTS_AND_NAME structures.</para>
/// <para>For more information about object-specific ACEs, see Object-specific ACEs.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-buildtrusteewithobjectsandnamea void
// BuildTrusteeWithObjectsAndNameA( PTRUSTEE_A pTrustee, POBJECTS_AND_NAME_A pObjName, SE_OBJECT_TYPE ObjectType, LPSTR
// ObjectTypeName, LPSTR InheritedObjectTypeName, LPSTR Name );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "62edadfe-0a7b-43ec-bd02-a63f928c7618")]
public static extern void BuildTrusteeWithObjectsAndName(out TRUSTEE pTrustee, in OBJECTS_AND_NAME pObjName, SE_OBJECT_TYPE ObjectType, string ObjectTypeName, string InheritedObjectTypeName, string Name);
/// <summary>
/// <para>
/// The <c>BuildTrusteeWithObjectsAndSid</c> function initializes a TRUSTEE structure with the object-specific access control entry
/// (ACE) information and initializes the remaining members of the structure to default values. The caller also specifies the SID
/// structure that represents the security identifier of the trustee.
/// </para>
/// </summary>
/// <param name="pTrustee">
/// <para>
/// A pointer to a TRUSTEE structure to initialize. The <c>BuildTrusteeWithObjectsAndSid</c> function does not allocate any memory.
/// If this parameter is <c>NULL</c> or a pointer that is not valid, the results are undefined.
/// </para>
/// </param>
/// <param name="pObjSid">
/// <para>A pointer to an OBJECTS_AND_SID structure that contains information about the trustee and the securable object.</para>
/// </param>
/// <param name="pObjectGuid">
/// <para>A pointer to a GUID structure that describes the ObjectType GUID to be added to the TRUSTEE structure.</para>
/// </param>
/// <param name="pInheritedObjectGuid">
/// <para>A pointer to a GUID structure that describes the InheritedObjectType GUID to be added to the TRUSTEE structure.</para>
/// </param>
/// <param name="pSid">
/// <para>A pointer to a SID structure that identifies the trustee.</para>
/// </param>
/// <returns>
/// <para>This function does not return a value.</para>
/// </returns>
/// <remarks>
/// <para>This function does not allocate memory for the TRUSTEE and OBJECTS_AND_SID structures.</para>
/// <para>For more information about object-specific ACEs, see Object-specific ACEs.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-buildtrusteewithobjectsandsidw void
// BuildTrusteeWithObjectsAndSidW( PTRUSTEE_W pTrustee, POBJECTS_AND_SID pObjSid, GUID *pObjectGuid, GUID *pInheritedObjectGuid, PSID
// pSid );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "e940a87f-013e-458c-bdc1-9e81c7d905e0")]
public static extern void BuildTrusteeWithObjectsAndSid(out TRUSTEE pTrustee, in OBJECTS_AND_SID pObjSid, in Guid pObjectGuid, in Guid pInheritedObjectGuid, PSID pSid);
/// <summary>
/// <para>
/// The <c>BuildTrusteeWithSid</c> function initializes a TRUSTEE structure. The caller specifies the security identifier (SID) of
/// the trustee. The function sets other members of the structure to default values and does not look up the name associated with the SID.
/// </para>
/// </summary>
/// <param name="pTrustee">
/// <para>
/// A pointer to a TRUSTEE structure to initialize. The <c>BuildTrusteeWithSid</c> function does not allocate any memory. If this
/// parameter is <c>NULL</c> or a pointer that is not valid, the results are undefined.
/// </para>
/// </param>
/// <param name="pSid">
/// <para>
/// A pointer to a SID structure that identifies the trustee. The <c>BuildTrusteeWithSid</c> function assigns this pointer to the
/// <c>ptstrName</c> member of the TRUSTEE structure. The function sets the other members of the <c>TRUSTEE</c> structure as follows.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>pMultipleTrustee</term>
/// <term>NULL</term>
/// </item>
/// <item>
/// <term>MultipleTrusteeOperation</term>
/// <term>NO_MULTIPLE_TRUSTEE</term>
/// </item>
/// <item>
/// <term>TrusteeForm</term>
/// <term>TRUSTEE_IS_SID</term>
/// </item>
/// <item>
/// <term>TrusteeType</term>
/// <term>TRUSTEE_IS_UNKNOWN</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>This function does not return a value.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-buildtrusteewithsidw void BuildTrusteeWithSidW( PTRUSTEE_W
// pTrustee, PSID pSid );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "3745fbf2-911a-4cb6-81a8-6256c742c700")]
public static extern void BuildTrusteeWithSid(out TRUSTEE pTrustee, PSID pSid);
/// <summary>The FreeInheritedFromArray function frees memory allocated by the GetInheritanceSource function.</summary>
/// <param name="pInheritArray">A pointer to the array of INHERITED_FROM structures returned by GetInheritanceSource.</param>
/// <param name="AceCnt">Number of entries in pInheritArray.</param>
/// <param name="pfnArray">Unused. Set to NULL.</param>
/// <returns>If the function succeeds, the return value is ERROR_SUCCESS. If the function fails, it returns a nonzero error code.</returns>
[DllImport(Lib.AdvApi32, ExactSpelling = true)]
[PInvokeData("Aclapi.h", MSDNShortId = "aa446630")]
public static extern Win32Error FreeInheritedFromArray(IntPtr pInheritArray, ushort AceCnt, IntPtr pfnArray);
/// <summary>
/// <para>
/// The <c>GetAuditedPermissionsFromAcl</c> function retrieves the audited access rights for a specified trustee. The audited rights
/// are based on the access control entries (ACEs) of a specified access control list (ACL). The audited access rights indicate the
/// types of access attempts that cause the system to generate an audit record in the system event log. The audited rights include
/// those that the ACL specifies for the trustee or for any groups of which the trustee is a member. In determining the audited
/// rights, the function does not consider the security privileges held by the trustee.
/// </para>
/// </summary>
/// <param name="pacl">
/// <para>A pointer to an ACL structure from which to get the trustee's audited access rights.</para>
/// </param>
/// <param name="pTrustee">
/// <para>
/// A pointer to a TRUSTEE structure that identifies the trustee. A trustee can be a user, group, or program (such as a Windows
/// service). You can use a name or a security identifier (SID) to identify a trustee. For information about SID structures, see SID.
/// </para>
/// </param>
/// <param name="pSuccessfulAuditedRights">
/// <para>
/// A pointer to an ACCESS_MASK structure that receives the successful audit mask for rights audited for the trustee specified by the
/// pTrustee parameter. The system generates an audit record when the trustee successfully uses any of these access rights.
/// </para>
/// </param>
/// <param name="pFailedAuditRights">
/// <para>
/// A pointer to an ACCESS_MASK structure that receives the failed audit mask for rights audited for the trustee specified by the
/// pTrustee parameter. The system generates an audit record when the trustee fails in an attempt to use any of these rights.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns ERROR_SUCCESS.</para>
/// <para>If the function fails, it returns a nonzero error code defined in WinError.h.</para>
/// </returns>
/// <remarks>
/// <para>
/// The <c>GetAuditedPermissionsFromAcl</c> function checks all system-audit ACEs in the ACL to determine the audited rights for the
/// trustee. For all ACEs that specify audited rights for a group, <c>GetAuditedPermissionsFromAcl</c> enumerates the members of the
/// group to determine whether the trustee is a member. The function returns an error if it cannot enumerate the members of a group.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-getauditedpermissionsfromacla DWORD
// GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEE_A pTrustee, PACCESS_MASK pSuccessfulAuditedRights, PACCESS_MASK
// pFailedAuditRights );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "4381fe12-5fb3-4f9c-8daa-261cb1a466ec")]
public static extern Win32Error GetAuditedPermissionsFromAcl(PACL pacl, in TRUSTEE pTrustee, out ACCESS_MASK pSuccessfulAuditedRights, out ACCESS_MASK pFailedAuditRights);
/// <summary>
/// The GetEffectiveRightsFromAcl function retrieves the effective access rights that an ACL structure grants to a specified trustee.
/// The trustee's effective access rights are the access rights that the ACL grants to the trustee or to any groups of which the
/// trustee is a member.
/// </summary>
/// <param name="pacl">A pointer to an ACL structure from which to get the trustee's effective access rights.</param>
/// <param name="pTrustee">
/// A pointer to a TRUSTEE structure that identifies the trustee. A trustee can be a user, group, or program (such as a Windows
/// service). You can use a name or a security identifier (SID) to identify a trustee.
/// </param>
/// <param name="pAccessRights">A pointer to an ACCESS_MASK variable that receives the effective access rights of the trustee.</param>
[DllImport(Lib.AdvApi32, CharSet = CharSet.Auto)]
[PInvokeData("Aclapi.h", MSDNShortId = "aa446637")]
public static extern Win32Error GetEffectiveRightsFromAcl(PACL pacl, in TRUSTEE pTrustee, out uint pAccessRights);
/// <summary>
/// <para>
/// The <c>GetExplicitEntriesFromAcl</c> function retrieves an array of structures that describe the access control entries (ACEs) in
/// an access control list (ACL).
/// </para>
/// </summary>
/// <param name="pacl">
/// <para>A pointer to an ACL structure from which to get ACE information.</para>
/// </param>
/// <param name="pcCountOfExplicitEntries">
/// <para>
/// A pointer to a variable that receives the number of EXPLICIT_ACCESS structures returned in the pListOfExplicitEntries array.
/// </para>
/// </param>
/// <param name="pListOfExplicitEntries">
/// <para>
/// A pointer to a variable that receives a pointer to an array of EXPLICIT_ACCESS structures that describe the ACEs in the ACL. If
/// the function succeeds, you must call the LocalFree function to free the returned buffer.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns ERROR_SUCCESS.</para>
/// <para>If the function fails, it returns a nonzero error code defined in WinError.h.</para>
/// </returns>
/// <remarks>
/// <para>
/// Each entry in the array of EXPLICIT_ACCESS structures describes access control information from an ACE for a trustee. A trustee
/// can be a user, group, or program (such as a Windows service).
/// </para>
/// <para>
/// Each EXPLICIT_ACCESS structure specifies a set of access rights and an access mode flag that indicates whether the ACE allows,
/// denies, or audits the specified rights.
/// </para>
/// <para>
/// For a discretionary access control list (DACL), the access mode flag can be either GRANT_ACCESS or DENY_ACCESS. For information
/// about these values, see ACCESS_MODE.
/// </para>
/// <para>
/// For a system access control list (SACL), the access mode flag can be SET_AUDIT_ACCESS, SET_AUDIT_FAILURE, or both. For
/// information about these values, see ACCESS_MODE.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-getexplicitentriesfromacla DWORD GetExplicitEntriesFromAclA(
// PACL pacl, PULONG pcCountOfExplicitEntries, PEXPLICIT_ACCESS_A *pListOfExplicitEntries );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "186aa6aa-efc3-4f8a-acad-e257da3dac0b")]
public static extern Win32Error GetExplicitEntriesFromAcl(PACL pacl, out uint pcCountOfExplicitEntries, out SafeLocalHandle pListOfExplicitEntries);
/// <summary>
/// The GetInheritanceSource function returns information about the source of inherited access control entries (ACEs) in an access
/// control list (ACL).
/// </summary>
/// <param name="pObjectName">A pointer to the name of the object that uses the ACL to be checked.</param>
/// <param name="ObjectType">
/// The type of object indicated by pObjectName. The possible values are SE_FILE_OBJECT, SE_REGISTRY_KEY, SE_DS_OBJECT, and SE_DS_OBJECT_ALL.
/// </param>
/// <param name="SecurityInfo">The type of ACL used with the object. The possible values are DACL_SECURITY_INFORMATION or SACL_SECURITY_INFORMATION.</param>
/// <param name="Container">
/// TRUE if the object is a container object or FALSE if the object is a leaf object. Note that the only leaf object is SE_FILE_OBJECT.
/// </param>
/// <param name="pObjectClassGuids">
/// Optional list of GUIDs that identify the object types or names associated with pObjectName. This may be NULL if the object
/// manager only supports one object class or has no GUID associated with the object class.
/// </param>
/// <param name="GuidCount">Number of GUIDs pointed to by pObjectClassGuids.</param>
/// <param name="pAcl">The ACL for the object.</param>
/// <param name="pfnArray">Reserved. Set this parameter to NULL.</param>
/// <param name="pGenericMapping">The mapping of generic rights to specific rights for the object.</param>
/// <param name="pInheritArray">
/// A pointer to an array of INHERITED_FROM structures that the GetInheritanceSource function fills with the inheritance information.
/// The caller must allocate enough memory for an entry for each ACE in the ACL.
/// </param>
/// <returns>
/// If the function succeeds, the function returns ERROR_SUCCESS. If the function fails, it returns a nonzero error code defined in WinError.h.
/// </returns>
[DllImport(Lib.AdvApi32, CharSet = CharSet.Auto)]
[PInvokeData("Aclapi.h", MSDNShortId = "aa446640")]
public static extern Win32Error GetInheritanceSource([MarshalAs(UnmanagedType.LPTStr)] string pObjectName, SE_OBJECT_TYPE ObjectType,
SECURITY_INFORMATION SecurityInfo, [MarshalAs(UnmanagedType.Bool)] bool Container,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 5, ArraySubType = UnmanagedType.LPStruct), Optional] Guid[] pObjectClassGuids,
uint GuidCount, [In] PACL pAcl, [In] IntPtr pfnArray, in GENERIC_MAPPING pGenericMapping, SafeInheritedFromArray pInheritArray);
/// <summary>
/// The GetInheritanceSource function returns information about the source of inherited access control entries (ACEs) in an access
/// control list (ACL).
/// </summary>
/// <param name="objectName">A pointer to the name of the object that uses the ACL to be checked.</param>
/// <param name="objectType">
/// The type of object indicated by pObjectName. The possible values are SE_FILE_OBJECT, SE_REGISTRY_KEY, SE_DS_OBJECT, and SE_DS_OBJECT_ALL.
/// </param>
/// <param name="securityInfo">The type of ACL used with the object. The possible values are DACL_SECURITY_INFORMATION or SACL_SECURITY_INFORMATION.</param>
/// <param name="container">
/// TRUE if the object is a container object or FALSE if the object is a leaf object. Note that the only leaf object is SE_FILE_OBJECT.
/// </param>
/// <param name="pAcl">The ACL for the object.</param>
/// <param name="pGenericMapping">The mapping of generic rights to specific rights for the object.</param>
/// <returns>An enumeration of INHERITED_FROM structures with the inheritance information.</returns>
public static IEnumerable<INHERITED_FROM> GetInheritanceSource(string objectName, System.Security.AccessControl.ResourceType objectType,
SECURITY_INFORMATION securityInfo, bool container, PACL pAcl, ref GENERIC_MAPPING pGenericMapping)
{
var objSize = Marshal.SizeOf(typeof(INHERITED_FROM));
var aceCount = pAcl.GetAclInformation<ACL_SIZE_INFORMATION>().AceCount;
using (var pInherit = new SafeInheritedFromArray((ushort)aceCount))
{
GetInheritanceSource(objectName, (SE_OBJECT_TYPE)objectType, securityInfo, container, null, 0, pAcl, IntPtr.Zero, pGenericMapping, pInherit).ThrowIfFailed();
return pInherit.Results;
}
}
/// <summary>The GetNamedSecurityInfo function retrieves a copy of the security descriptor for an object specified by name.</summary>
/// <param name="pObjectName">
/// A pointer to a null-terminated string that specifies the name of the object from which to retrieve security information. For
/// descriptions of the string formats for the different object types, see SE_OBJECT_TYPE.
/// </param>
/// <param name="ObjectType">
/// Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object named by the pObjectName parameter.
/// </param>
/// <param name="SecurityInfo">
/// A set of bit flags that indicate the type of security information to retrieve. This parameter can be a combination of the
/// SECURITY_INFORMATION bit flags.
/// </param>
/// <param name="ppsidOwner">
/// A pointer to a variable that receives a pointer to the owner SID in the security descriptor returned in ppSecurityDescriptor or
/// NULL if the security descriptor has no owner SID. The returned pointer is valid only if you set the OWNER_SECURITY_INFORMATION
/// flag. Also, this parameter can be NULL if you do not need the owner SID.
/// </param>
/// <param name="ppsidGroup">
/// A pointer to a variable that receives a pointer to the primary group SID in the returned security descriptor or NULL if the
/// security descriptor has no group SID. The returned pointer is valid only if you set the GROUP_SECURITY_INFORMATION flag. Also,
/// this parameter can be NULL if you do not need the group SID.
/// </param>
/// <param name="ppDacl">
/// A pointer to a variable that receives a pointer to the DACL in the returned security descriptor or NULL if the security
/// descriptor has no DACL. The returned pointer is valid only if you set the DACL_SECURITY_INFORMATION flag. Also, this parameter
/// can be NULL if you do not need the DACL.
/// </param>
/// <param name="ppSacl">
/// A pointer to a variable that receives a pointer to the SACL in the returned security descriptor or NULL if the security
/// descriptor has no SACL. The returned pointer is valid only if you set the SACL_SECURITY_INFORMATION flag. Also, this parameter
/// can be NULL if you do not need the SACL.
/// </param>
/// <param name="ppSecurityDescriptor">
/// A pointer to a variable that receives a pointer to the security descriptor of the object. When you have finished using the
/// pointer, free the returned buffer by calling the LocalFree function.
/// <para>This parameter is required if any one of the ppsidOwner, ppsidGroup, ppDacl, or ppSacl parameters is not NULL.</para>
/// </param>
/// <returns>
/// If the function succeeds, the return value is ERROR_SUCCESS. If the function fails, the return value is a nonzero error code
/// defined in WinError.h.
/// </returns>
[DllImport(Lib.AdvApi32, CharSet = CharSet.Auto, SetLastError = true)]
[PInvokeData("Aclapi.h", MSDNShortId = "aa446645")]
public static extern Win32Error GetNamedSecurityInfo(string pObjectName, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, out PSID ppsidOwner,
out PSID ppsidGroup, out PACL ppDacl, out PACL ppSacl, out SafePSECURITY_DESCRIPTOR ppSecurityDescriptor);
/// <summary>
/// <para>The <c>GetSecurityInfo</c> function retrieves a copy of the security descriptor for an object specified by a handle.</para>
/// </summary>
/// <param name="handle">
/// <para>A handle to the object from which to retrieve security information.</para>
/// </param>
/// <param name="ObjectType">
/// <para>SE_OBJECT_TYPE enumeration value that indicates the type of object.</para>
/// </param>
/// <param name="SecurityInfo">
/// <para>
/// A set of bit flags that indicate the type of security information to retrieve. This parameter can be a combination of the
/// SECURITY_INFORMATION bit flags.
/// </para>
/// </param>
/// <param name="ppsidOwner">
/// <para>
/// A pointer to a variable that receives a pointer to the owner SID in the security descriptor returned in ppSecurityDescriptor. The
/// returned pointer is valid only if you set the OWNER_SECURITY_INFORMATION flag. This parameter can be <c>NULL</c> if you do not
/// need the owner SID.
/// </para>
/// </param>
/// <param name="ppsidGroup">
/// <para>
/// A pointer to a variable that receives a pointer to the primary group SID in the returned security descriptor. The returned
/// pointer is valid only if you set the GROUP_SECURITY_INFORMATION flag. This parameter can be <c>NULL</c> if you do not need the
/// group SID.
/// </para>
/// </param>
/// <param name="ppDacl">
/// <para>
/// A pointer to a variable that receives a pointer to the DACL in the returned security descriptor. The returned pointer is valid
/// only if you set the DACL_SECURITY_INFORMATION flag. This parameter can be <c>NULL</c> if you do not need the DACL.
/// </para>
/// </param>
/// <param name="ppSacl">
/// <para>
/// A pointer to a variable that receives a pointer to the SACL in the returned security descriptor. The returned pointer is valid
/// only if you set the SACL_SECURITY_INFORMATION flag. This parameter can be <c>NULL</c> if you do not need the SACL.
/// </para>
/// </param>
/// <param name="ppSecurityDescriptor">
/// <para>
/// A pointer to a variable that receives a pointer to the security descriptor of the object. When you have finished using the
/// pointer, free the returned buffer by calling the LocalFree function.
/// </para>
/// <para>This parameter is required if any one of the ppsidOwner, ppsidGroup, ppDacl, or ppSacl parameters is not <c>NULL</c>.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a nonzero error code defined in WinError.h.</para>
/// </returns>
/// <remarks>
/// <para>
/// If the ppsidOwner, ppsidGroup, ppDacl, and ppSacl parameters are non- <c>NULL</c>, and the SecurityInfo parameter specifies that
/// they be retrieved from the object, those parameters will point to the corresponding parameters in the security descriptor
/// returned in ppSecurityDescriptor.
/// </para>
/// <para>
/// To read the owner, group, or DACL from the object's security descriptor, the calling process must have been granted READ_CONTROL
/// access when the handle was opened. To get READ_CONTROL access, the caller must be the owner of the object or the object's DACL
/// must grant the access.
/// </para>
/// <para>
/// To read the SACL from the security descriptor, the calling process must have been granted ACCESS_SYSTEM_SECURITY access when the
/// handle was opened. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current token,
/// open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege. For information about the security
/// implications of enabling privileges, see Running with Special Privileges.
/// </para>
/// <para>You can use the <c>GetSecurityInfo</c> function with the following types of objects:</para>
/// <list type="bullet">
/// <item>
/// <term>Local or remote files or directories on an NTFS file system</term>
/// </item>
/// <item>
/// <term>Named pipes</term>
/// </item>
/// <item>
/// <term>Local or remote printers</term>
/// </item>
/// <item>
/// <term>Local or remote Windows services</term>
/// </item>
/// <item>
/// <term>Network shares</term>
/// </item>
/// <item>
/// <term>Registry keys</term>
/// </item>
/// <item>
/// <term>Semaphores, events, mutexes, and waitable timers</term>
/// </item>
/// <item>
/// <term>Processes, threads, jobs, and file-mapping objects</term>
/// </item>
/// <item>
/// <term>Interactive service window stations and desktops</term>
/// </item>
/// <item>
/// <term>Directory service objects</term>
/// </item>
/// </list>
/// <para>
/// This function does not handle race conditions. If your thread calls this function at the approximate time that another thread
/// changes the object's security descriptor, then this function could fail.
/// </para>
/// <para>Examples</para>
/// <para>For an example that uses this function, see Finding the Owner of a File Object.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-getsecurityinfo DWORD GetSecurityInfo( HANDLE handle,
// SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner, PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
// PSECURITY_DESCRIPTOR *ppSecurityDescriptor );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("aclapi.h", MSDNShortId = "64767a6b-cd79-4e02-881a-706a078ff446")]
public static extern Win32Error GetSecurityInfo(IntPtr handle, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, out PSID ppsidOwner, out PSID ppsidGroup,
out PACL ppDacl, out PACL ppSacl, out SafePSECURITY_DESCRIPTOR ppSecurityDescriptor);
/// <summary>
/// <para>
/// The <c>GetTrusteeForm</c> function retrieves the trustee name from the specified TRUSTEE structure. This value indicates whether
/// the structure uses a name string or a security identifier (SID) to identify the trustee.
/// </para>
/// </summary>
/// <param name="pTrustee">
/// <para>A pointer to a TRUSTEE structure.</para>
/// </param>
/// <returns>
/// <para>The return value is one of the constants from the TRUSTEE_FORM enumeration.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-gettrusteeforma TRUSTEE_FORM GetTrusteeFormA( PTRUSTEE_A
// pTrustee );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "e5e450b8-0b7b-4324-b453-5c020e74b1ee")]
public static extern TRUSTEE_FORM GetTrusteeForm(in TRUSTEE pTrustee);
/// <summary>
/// <para>The <c>GetTrusteeName</c> function retrieves the trustee name from the specified TRUSTEE structure.</para>
/// </summary>
/// <param name="pTrustee">
/// <para>A pointer to a TRUSTEE structure.</para>
/// </param>
/// <returns>
/// <para>
/// If the <c>TrusteeForm</c> member of the TRUSTEE structure is TRUSTEE_IS_NAME, the return value is the pointer assigned to the
/// <c>ptstrName</c> member of the structure.
/// </para>
/// <para>
/// If the <c>TrusteeForm</c> member is TRUSTEE_IS_SID, the return value is <c>NULL</c>. The function does not look up the name
/// associated with a security identifier (SID).
/// </para>
/// </returns>
/// <remarks>
/// <para>The <c>GetTrusteeName</c> function does not allocate any memory.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-gettrusteenamea LPSTR GetTrusteeNameA( PTRUSTEE_A pTrustee );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "9d3ce528-fb28-4e2e-bf7f-7d84c697fcb6")]
public static extern StrPtrAuto GetTrusteeName(in TRUSTEE pTrustee);
/// <summary>
/// <para>
/// The <c>GetTrusteeType</c> function retrieves the trustee type from the specified TRUSTEE structure. This value indicates whether
/// the trustee is a user, a group, or the trustee type is unknown.
/// </para>
/// </summary>
/// <param name="pTrustee">
/// <para>A pointer to a TRUSTEE structure.</para>
/// </param>
/// <returns>
/// <para>The return value is one of the constants from the TRUSTEE_TYPE enumeration.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-gettrusteetypea TRUSTEE_TYPE GetTrusteeTypeA( PTRUSTEE_A
// pTrustee );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "19777929-43cf-45ea-8283-e42bf9ce8d7a")]
public static extern TRUSTEE_TYPE GetTrusteeType(in TRUSTEE pTrustee);
/// <summary>
/// <para>The <c>LookupSecurityDescriptorParts</c> function retrieves security information from a self-relative security descriptor.</para>
/// </summary>
/// <param name="ppOwner">
/// <para>
/// A pointer to a variable that receives a pointer to a TRUSTEE structure. The function looks up the name associated with the owner
/// security identifier (SID) in the pSD security descriptor, and returns a pointer to the name in the <c>ptstrName</c> member of the
/// <c>TRUSTEE</c> structure. The function sets the <c>TrusteeForm</c> member to TRUSTEE_IS_NAME.
/// </para>
/// <para>This parameter can be <c>NULL</c> if you are not interested in the name of the owner.</para>
/// </param>
/// <param name="ppGroup">
/// <para>
/// A pointer to a variable that receives a pointer to a TRUSTEE structure. The function looks up the name associated with the
/// primary group SID of the security descriptor, and returns a pointer to the name in the <c>ptstrName</c> member of the
/// <c>TRUSTEE</c> structure. The function sets the <c>TrusteeForm</c> member to TRUSTEE_IS_NAME.
/// </para>
/// <para>This parameter can be <c>NULL</c> if you are not interested in the name of the group.</para>
/// </param>
/// <param name="pcCountOfAccessEntries">
/// <para>
/// A pointer to a <c>ULONG</c> that receives the number of EXPLICIT_ACCESS structures returned in the pListOfAccessEntries array.
/// This parameter can be <c>NULL</c> only if the pListOfAccessEntries parameter is also <c>NULL</c>.
/// </para>
/// </param>
/// <param name="ppListOfAccessEntries">
/// <para>
/// A pointer to a variable that receives a pointer to an array of EXPLICIT_ACCESS structures that describe the access control
/// entries (ACEs) in the discretionary access control list (DACL) of the security descriptor. The TRUSTEE structure in these
/// <c>EXPLICIT_ACCESS</c> structures use the TRUSTEE_IS_NAME form. For a description of how an array of <c>EXPLICIT_ACCESS</c>
/// structures describes the ACEs in an access control list (ACL), see the GetExplicitEntriesFromAcl function. If this parameter is
/// <c>NULL</c>, the cCountOfAccessEntries parameter must also be <c>NULL</c>.
/// </para>
/// </param>
/// <param name="pcCountOfAuditEntries">
/// <para>
/// A pointer to a <c>ULONG</c> that receives the number of EXPLICIT_ACCESS structures returned in the pListOfAuditEntries array.
/// This parameter can be <c>NULL</c> only if the pListOfAuditEntries parameter is also <c>NULL</c>.
/// </para>
/// </param>
/// <param name="ppListOfAuditEntries">
/// <para>
/// A pointer to a variable that receives a pointer to an array of EXPLICIT_ACCESS structures that describe the ACEs in the system
/// access control list (SACL) of the security descriptor. The TRUSTEE structure in these <c>EXPLICIT_ACCESS</c> structures uses the
/// TRUSTEE_IS_NAME form. If this parameter is <c>NULL</c>, the cCountOfAuditEntries parameter must also be <c>NULL</c>.
/// </para>
/// </param>
/// <param name="pSD">
/// <para>A pointer to an existing self-relative security descriptor from which the function retrieves security information.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns ERROR_SUCCESS.</para>
/// <para>If the function fails, it returns a nonzero error code defined in WinError.h.</para>
/// </returns>
/// <remarks>
/// <para>
/// The <c>LookupSecurityDescriptorParts</c> function retrieves the names of the owner and primary group of the security descriptor.
/// This function also returns descriptions of the ACEs in the DACL and audit-control entries in the SACL of the security descriptor.
/// </para>
/// <para>
/// The parameters other than pSD can be <c>NULL</c> if you are not interested in the information. If you do not want information
/// about the DACL, both pListOfAccessEntries and cCountOfAuditEntries must be <c>NULL</c>. If you do not want information about the
/// SACL, both pListOfAuditEntries and cCountOfAuditEntries must be <c>NULL</c>. Similarly, if you do want DACL or SACL information,
/// both of the corresponding parameters must not be <c>NULL</c>.
/// </para>
/// <para>
/// When you have finished using any of the buffers returned by the pOwner, pGroup, pListOfAccessEntries, or pListOfAuditEntries
/// parameters, free them by calling the LocalFree function.
/// </para>
/// <para>
/// The <c>LookupSecurityDescriptorParts</c> function is intended for trusted servers that implement or expose security on their own
/// objects. The function works with a self-relative security descriptor suitable for serializing into a stream and storing to disk,
/// as a trusted server might require.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-lookupsecuritydescriptorpartsa DWORD
// LookupSecurityDescriptorPartsA( PTRUSTEE_A *ppOwner, PTRUSTEE_A *ppGroup, PULONG pcCountOfAccessEntries, PEXPLICIT_ACCESS_A
// *ppListOfAccessEntries, PULONG pcCountOfAuditEntries, PEXPLICIT_ACCESS_A *ppListOfAuditEntries, PSECURITY_DESCRIPTOR pSD );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "68c3f56b-6c48-4f4b-bd38-9f4e346c663b")]
public static extern Win32Error LookupSecurityDescriptorParts(out SafeLocalHandle ppOwner, out SafeLocalHandle ppGroup, out uint pcCountOfAccessEntries, out SafeLocalHandle ppListOfAccessEntries,
out uint pcCountOfAuditEntries, out SafeLocalHandle ppListOfAuditEntries, PSECURITY_DESCRIPTOR pSD);
/// <summary>
/// <para>
/// The <c>SetEntriesInAcl</c> function creates a new access control list (ACL) by merging new access control or audit control
/// information into an existing ACL structure.
/// </para>
/// </summary>
/// <param name="cCountOfExplicitEntries">
/// <para>The number of EXPLICIT_ACCESS structures in the pListOfExplicitEntries array.</para>
/// </param>
/// <param name="pListOfExplicitEntries">
/// <para>
/// A pointer to an array of EXPLICIT_ACCESS structures that describe the access control information to merge into the existing ACL.
/// </para>
/// </param>
/// <param name="OldAcl">
/// <para>
/// A pointer to the existing ACL. This parameter can be <c>NULL</c>, in which case, the function creates a new ACL based on the
/// EXPLICIT_ACCESS entries.
/// </para>
/// </param>
/// <param name="NewAcl">
/// <para>
/// A pointer to a variable that receives a pointer to the new ACL. If the function succeeds, you must call the LocalFree function to
/// free the returned buffer.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns ERROR_SUCCESS.</para>
/// <para>If the function fails, it returns a nonzero error code defined in WinError.h.</para>
/// </returns>
/// <remarks>
/// <para>
/// Each entry in the array of EXPLICIT_ACCESS structures specifies access control or audit control information for a specified
/// trustee. A trustee can be a user, group, or other security identifier (SID) value, such as a logon identifier or logon type (for
/// instance, a Windows service or batch job). You can use a name or a SID to identify a trustee.
/// </para>
/// <para>
/// You can use the <c>SetEntriesInAcl</c> function to modify the list of access control entries (ACEs) in a discretionary access
/// control list (DACL) or a system access control list (SACL). Note that <c>SetEntriesInAcl</c> does not prevent you from mixing
/// access control and audit control information in the same ACL; however, the resulting ACL will contain meaningless entries.
/// </para>
/// <para>
/// For a DACL, the <c>grfAccessMode</c> member of the EXPLICIT_ACCESS structure specifies whether to allow, deny, or revoke access
/// rights for the trustee. This member can specify one of the following values:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>GRANT_ACCESS</term>
/// </item>
/// <item>
/// <term>SET_ACCESS</term>
/// </item>
/// <item>
/// <term>DENY_ACCESS</term>
/// </item>
/// <item>
/// <term>REVOKE_ACCESS</term>
/// </item>
/// </list>
/// <para>For information about these values, see ACCESS_MODE.</para>
/// <para>
/// The <c>SetEntriesInAcl</c> function places any new access-denied ACEs at the beginning of the list of ACEs for the new ACL. This
/// function places any new access-allowed ACEs just before any existing access-allowed ACEs.
/// </para>
/// <para>For a SACL, the <c>grfAccessMode</c> member of the EXPLICIT_ACCESS structure can specify the following values:</para>
/// <list type="bullet">
/// <item>
/// <term>REVOKE_ACCESS</term>
/// </item>
/// <item>
/// <term>SET_AUDIT_FAILURE</term>
/// </item>
/// <item>
/// <term>SET_AUDIT_SUCCESS</term>
/// </item>
/// </list>
/// <para>SET_AUDIT_FAILURE and SET_AUDIT_SUCCESS can be combined. For information about these values, see ACCESS_MODE.</para>
/// <para>
/// The <c>SetEntriesInAcl</c> function places any new system-audit ACEs at the beginning of the list of ACEs for the new ACL.
/// </para>
/// <para>Examples</para>
/// <para>
/// For an example that uses this function, see Modifying the ACLs of an Object or Creating a Security Descriptor for a New Object or
/// Taking Object Ownership.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-setentriesinacla DWORD SetEntriesInAclA( ULONG
// cCountOfExplicitEntries, PEXPLICIT_ACCESS_A pListOfExplicitEntries, PACL OldAcl, PACL *NewAcl );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "05960fc1-1ad2-4c19-a65c-62259af5e18c")]
public static extern Win32Error SetEntriesInAcl(uint cCountOfExplicitEntries, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] EXPLICIT_ACCESS[] pListOfExplicitEntries, PACL OldAcl, out SafePACL NewAcl);
/// <summary>
/// The SetNamedSecurityInfo function sets specified security information in the security descriptor of a specified object. The
/// caller identifies the object by name.
/// </summary>
/// <param name="pObjectName">
/// A pointer to a null-terminated string that specifies the name of the object for which to set security information. This can be
/// the name of a local or remote file or directory on an NTFS file system, network share, registry key, semaphore, event, mutex,
/// file mapping, or waitable timer. For descriptions of the string formats for the different object types, see SE_OBJECT_TYPE.
/// </param>
/// <param name="ObjectType">
/// A value of the SE_OBJECT_TYPE enumeration that indicates the type of object named by the pObjectName parameter.
/// </param>
/// <param name="SecurityInfo">
/// A set of bit flags that indicate the type of security information to set. This parameter can be a combination of the
/// SECURITY_INFORMATION bit flags.
/// </param>
/// <param name="ppsidOwner">
/// A pointer to a SID structure that identifies the owner of the object. If the caller does not have the SeRestorePrivilege constant
/// (see Privilege Constants), this SID must be contained in the caller's token, and must have the SE_GROUP_OWNER permission enabled.
/// The SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION flag. To set the owner, the caller must have WRITE_OWNER
/// access to the object or have the SE_TAKE_OWNERSHIP_NAME privilege enabled. If you are not setting the owner SID, this parameter
/// can be NULL.
/// </param>
/// <param name="ppsidGroup">
/// A pointer to a SID that identifies the primary group of the object. The SecurityInfo parameter must include the
/// GROUP_SECURITY_INFORMATION flag. If you are not setting the primary group SID, this parameter can be NULL.
/// </param>
/// <param name="ppDacl">
/// A pointer to the new DACL for the object. The SecurityInfo parameter must include the DACL_SECURITY_INFORMATION flag. The caller
/// must have WRITE_DAC access to the object or be the owner of the object. If you are not setting the DACL, this parameter can be NULL.
/// </param>
/// <param name="ppSacl">
/// A pointer to the new SACL for the object. The SecurityInfo parameter must include any of the following flags:
/// SACL_SECURITY_INFORMATION, LABEL_SECURITY_INFORMATION, ATTRIBUTE_SECURITY_INFORMATION, SCOPE_SECURITY_INFORMATION, or BACKUP_SECURITY_INFORMATION.
/// <para>
/// If setting SACL_SECURITY_INFORMATION or SCOPE_SECURITY_INFORMATION, the caller must have the SE_SECURITY_NAME privilege enabled.
/// If you are not setting the SACL, this parameter can be NULL.
/// </para>
/// </param>
/// <returns>
/// If the function succeeds, the function returns ERROR_SUCCESS. If the function fails, it returns a nonzero error code defined in WinError.h.
/// </returns>
[DllImport(Lib.AdvApi32, CharSet = CharSet.Auto)]
[PInvokeData("Aclapi.h", MSDNShortId = "aa379579")]
public static extern Win32Error SetNamedSecurityInfo(string pObjectName, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, [Optional] PSID ppsidOwner,
[Optional] PSID ppsidGroup, [Optional] PACL ppDacl, [Optional] PACL ppSacl);
/// <summary>
/// <para>
/// The <c>SetSecurityInfo</c> function sets specified security information in the security descriptor of a specified object. The
/// caller identifies the object by a handle.
/// </para>
/// <para>To set the SACL of an object, the caller must have the <c>SE_SECURITY_NAME</c> privilege enabled.</para>
/// </summary>
/// <param name="handle">
/// <para>A handle to the object for which to set security information.</para>
/// </param>
/// <param name="ObjectType">
/// <para>A member of the SE_OBJECT_TYPE enumeration that indicates the type of object identified by the handle parameter.</para>
/// </param>
/// <param name="SecurityInfo">
/// <para>
/// A set of bit flags that indicate the type of security information to set. This parameter can be a combination of the
/// SECURITY_INFORMATION bit flags.
/// </para>
/// </param>
/// <param name="psidOwner">
/// <para>
/// A pointer to a SID that identifies the owner of the object. The SID must be one that can be assigned as the owner SID of a
/// security descriptor. The SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION flag. This parameter can be
/// <c>NULL</c> if you are not setting the owner SID.
/// </para>
/// </param>
/// <param name="psidGroup">
/// <para>
/// A pointer to a SID that identifies the primary group of the object. The SecurityInfo parameter must include the
/// GROUP_SECURITY_INFORMATION flag. This parameter can be <c>NULL</c> if you are not setting the primary group SID.
/// </para>
/// </param>
/// <param name="pDacl">
/// <para>
/// A pointer to the new DACL for the object. This parameter is ignored unless the value of the SecurityInfo parameter includes the
/// <c>DACL_SECURITY_INFORMATION</c> flag. If the value of the SecurityInfo parameter includes the <c>DACL_SECURITY_INFORMATION</c>
/// flag and the value of this parameter is set to <c>NULL</c>, full access to the object is granted to everyone. For information
/// about <c>null</c> DACLs, see Creating a DACL.
/// </para>
/// </param>
/// <param name="pSacl">
/// <para>
/// A pointer to the new SACL for the object. The SecurityInfo parameter must include any of the following flags:
/// SACL_SECURITY_INFORMATION, LABEL_SECURITY_INFORMATION, ATTRIBUTE_SECURITY_INFORMATION, SCOPE_SECURITY_INFORMATION, or
/// BACKUP_SECURITY_INFORMATION. If setting SACL_SECURITY_INFORMATION or SCOPE_SECURITY_INFORMATION, the caller must have the
/// SE_SECURITY_NAME privilege enabled. This parameter can be <c>NULL</c> if you are not setting the SACL.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns ERROR_SUCCESS.</para>
/// <para>If the function fails, it returns a nonzero error code defined in WinError.h.</para>
/// </returns>
/// <remarks>
/// <para>
/// If you are setting the discretionary access control list (DACL) or any elements in the system access control list (SACL) of an
/// object, the system automatically propagates any inheritable access control entries (ACEs) to existing child objects, according to
/// the ACE inheritance rules.
/// </para>
/// <para>You can use the <c>SetSecurityInfo</c> function with the following types of objects:</para>
/// <list type="bullet">
/// <item>
/// <term>Local or remote files or directories on an NTFS</term>
/// </item>
/// <item>
/// <term>Named pipes</term>
/// </item>
/// <item>
/// <term>Local or remote printers</term>
/// </item>
/// <item>
/// <term>Local or remote Windows services</term>
/// </item>
/// <item>
/// <term>Network shares</term>
/// </item>
/// <item>
/// <term>Registry keys</term>
/// </item>
/// <item>
/// <term>Semaphores, events, mutexes, and waitable timers</term>
/// </item>
/// <item>
/// <term>Processes, threads, jobs, and file-mapping objects</term>
/// </item>
/// <item>
/// <term>Window stations and desktops</term>
/// </item>
/// <item>
/// <term>Directory service objects</term>
/// </item>
/// </list>
/// <para>
/// The <c>SetSecurityInfo</c> function does not reorder access-allowed or access-denied ACEs based on the preferred order. When
/// propagating inheritable ACEs to existing child objects, <c>SetSecurityInfo</c> puts inherited ACEs in order after all of the
/// noninherited ACEs in the DACLs of the child objects.
/// </para>
/// <para>
/// <c>Note</c> If share access to the children of the object is not available, this function will not propagate unprotected ACEs to
/// the children. For example, if a directory is opened with exclusive access, the operating system will not propagate unprotected
/// ACEs to the subdirectories or files of that directory when the security on the directory is changed.
/// </para>
/// <para>
/// <c>Warning</c> If the supplied handle was opened with an ACCESS_MASK value of <c>MAXIMUM_ALLOWED</c>, then the
/// <c>SetSecurityInfo</c> function will not propagate ACEs to children.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-setsecurityinfo DWORD SetSecurityInfo( HANDLE handle,
// SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("aclapi.h", MSDNShortId = "f1781ba9-81eb-46f9-b530-c390b67d65de")]
public static extern Win32Error SetSecurityInfo(IntPtr handle, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, [Optional] PSID psidOwner, [Optional] PSID psidGroup, [Optional] PACL pDacl, [Optional] PACL pSacl);
/// <summary>
/// <para>
/// The <c>TreeResetNamedSecurityInfo</c> function resets specified security information in the security descriptor of a specified
/// tree of objects. This function allows a specified discretionary access control list (DACL) or any elements in the system access
/// control list (SACL) to be propagated throughout an entire tree. This function supports a callback function to track the progress
/// of the tree operation.
/// </para>
/// </summary>
/// <param name="pObjectName">
/// <para>
/// Pointer to a <c>null</c>-terminated string that specifies the name of the root node object for the objects that are to receive
/// updated security information. Supported objects are registry keys and file objects. For descriptions of the string formats for
/// the different object types, see SE_OBJECT_TYPE.
/// </para>
/// </param>
/// <param name="ObjectType">
/// <para>
/// A value of the SE_OBJECT_TYPE enumeration that indicates the type of object named by the pObjectName parameter. The supported
/// values are SE_REGISTRY_KEY and SE_FILE_OBJECT, for registry keys and file objects, respectively.
/// </para>
/// </param>
/// <param name="SecurityInfo">
/// <para>
/// A set of bit flags that indicate the type of security information to reset. This parameter can be a combination of the
/// SECURITY_INFORMATION bit flags.
/// </para>
/// </param>
/// <param name="pOwner">
/// <para>
/// A pointer to a SID structure that identifies the owner of the object. The SID must be one that can be assigned as the owner SID
/// of a security descriptor. The SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION flag. To set the owner, the
/// caller must have WRITE_OWNER access to each object, including the root object. If you are not setting the owner SID, this
/// parameter can be <c>NULL</c>.
/// </para>
/// </param>
/// <param name="pGroup">
/// <para>
/// A pointer to a SID structure that identifies the primary group of the object. The SecurityInfo parameter must include the
/// GROUP_SECURITY_INFORMATION flag. To set the group, the caller must have WRITE_OWNER access to each object, including the root
/// object. If you are not setting the primary group SID, this parameter can be <c>NULL</c>.
/// </para>
/// </param>
/// <param name="pDacl">
/// <para>
/// A pointer to an access control list (ACL) structure that represents the new DACL for the objects being reset. The SecurityInfo
/// parameter must include the DACL_SECURITY_INFORMATION flag. The caller must have READ_CONTROL and WRITE_DAC access to each object,
/// including the root object. If you are not setting the DACL, this parameter can be <c>NULL</c>.
/// </para>
/// </param>
/// <param name="pSacl">
/// <para>
/// A pointer to an ACL structure that represents the new SACL for the objects being reset. The SecurityInfo parameter must include
/// any of the following flags: SACL_SECURITY_INFORMATION, LABEL_SECURITY_INFORMATION, ATTRIBUTE_SECURITY_INFORMATION,
/// SCOPE_SECURITY_INFORMATION, or BACKUP_SECURITY_INFORMATION. If setting SACL_SECURITY_INFORMATION or SCOPE_SECURITY_INFORMATION,
/// the caller must have the SE_SECURITY_NAME privilege enabled. If you are not setting the SACL, this parameter can be <c>NULL</c>.
/// </para>
/// </param>
/// <param name="KeepExplicit">
/// <para>
/// Boolean value that defines whether explicitly defined ACEs are kept or deleted for the sub-tree. If KeepExplicit is <c>TRUE</c>,
/// then explicitly defined ACEs are kept for each subtree DACL and SACL, and inherited ACEs are replaced by the inherited ACEs from
/// pDacl and pSacl. If KeepExplicit is <c>FALSE</c>, then explicitly defined ACEs for each subtree DACL and SACL are deleted before
/// the inherited ACEs are replaced by the inherited ACEs from pDacl and pSacl.
/// </para>
/// </param>
/// <param name="fnProgress">
/// <para>
/// A pointer to the function used to track the progress of the <c>TreeResetNamedSecurityInfo</c> function. The prototype of the
/// progress function is:
/// </para>
/// <para>
/// The progress function provides the caller with progress and error information when nodes are processed. The caller specifies the
/// progress function in fnProgress, and during the tree operation, <c>TreeResetNamedSecurityInfo</c> passes the name of the last
/// object processed, the error status of that operation, and the current PROG_INVOKE_SETTING value. The caller can change the
/// PROG_INVOKE_SETTING value by using pInvokeSetting.
/// </para>
/// <para>If no progress function is to be used, set this parameter to <c>NULL</c>.</para>
/// </param>
/// <param name="ProgressInvokeSetting">
/// <para>A value of the PROG_INVOKE_SETTING enumeration that specifies the initial setting for the progress function.</para>
/// </param>
/// <param name="Args">
/// <para>A pointer to a <c>VOID</c> for progress function arguments specified by the caller.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns ERROR_SUCCESS.</para>
/// <para>If the function fails, it returns an error code defined in WinError.h.</para>
/// </returns>
/// <remarks>
/// <para>Setting a <c>NULL</c> owner, group, DACL, or SACL is not supported by this function.</para>
/// <para>
/// If the caller does not contain the proper privileges and permissions to support the requested owner, group, DACL, and SACL
/// updates, then none of the updates are performed.
/// </para>
/// <para>This function is similar to the TreeSetNamedSecurityInfo function:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// If the KeepExplicit parameter of <c>TreeResetNamedSecurityInfo</c> is set to <c>TRUE</c>, then the function is equivalent to
/// TreeSetNamedSecurityInfo with the dwAction parameter set to TREE_SEC_INFO_RESET_KEEP_EXPLICIT.
/// </term>
/// </item>
/// <item>
/// <term>
/// If the KeepExplicit parameter of <c>TreeResetNamedSecurityInfo</c> is set to <c>FALSE</c>, then the function is equivalent to
/// TreeSetNamedSecurityInfo with the dwActionparameter set to TREE_SEC_INFO_RESET.
/// </term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-treeresetnamedsecurityinfoa DWORD
// TreeResetNamedSecurityInfoA( LPSTR pObjectName, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, PSID pOwner, PSID
// pGroup, PACL pDacl, PACL pSacl, BOOL KeepExplicit, FN_PROGRESS fnProgress, PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "adae7d07-a452-409e-b1a1-e9f86f873e39")]
public static extern Win32Error TreeResetNamedSecurityInfo(string pObjectName, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
[MarshalAs(UnmanagedType.Bool)] bool KeepExplicit, [Optional] FN_PROGRESS fnProgress, PROG_INVOKE_SETTING ProgressInvokeSetting, [Optional] IntPtr Args);
/// <summary>
/// <para>
/// The <c>TreeSetNamedSecurityInfo</c> function sets specified security information in the security descriptor of a specified tree
/// of objects. This function allows a specified discretionary access control list (DACL) or any elements in the system access
/// control list (SACL) to be propagated throughout an entire tree. This function supports a callback function to track the progress
/// of the tree operation.
/// </para>
/// </summary>
/// <param name="pObjectName">
/// <para>
/// Pointer to a <c>null</c>-terminated string that specifies the name of the root node object for the objects that are to receive
/// updated security information. Supported objects are registry keys and file objects. For descriptions of the string formats for
/// the different object types, see SE_OBJECT_TYPE.
/// </para>
/// </param>
/// <param name="ObjectType">
/// <para>
/// A value of the SE_OBJECT_TYPE enumeration that indicates the type of object named by the pObjectName parameter. The supported
/// values are SE_REGISTRY_KEY and SE_FILE_OBJECT, for registry keys and file objects, respectively.
/// </para>
/// </param>
/// <param name="SecurityInfo">
/// <para>
/// A set of bit flags that indicate the type of security information to set. This parameter can be a combination of the
/// SECURITY_INFORMATION bit flags.
/// </para>
/// </param>
/// <param name="pOwner">
/// <para>
/// A pointer to a SID structure that identifies the owner of the object. The SID must be one that can be assigned as the owner SID
/// of a security descriptor. The SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION flag. To set the owner, the
/// caller must have WRITE_OWNER access to each object, including the root object. If you are not setting the owner SID, this
/// parameter can be <c>NULL</c>.
/// </para>
/// </param>
/// <param name="pGroup">
/// <para>
/// A pointer to a SID structure that identifies the primary group of the object. The SecurityInfo parameter must include the
/// GROUP_SECURITY_INFORMATION flag. To set the group, the caller must have WRITE_OWNER access to each object, including the root
/// object. If you are not setting the primary group SID, this parameter can be <c>NULL</c>.
/// </para>
/// </param>
/// <param name="pDacl">
/// <para>
/// A pointer to an access control list (ACL) structure that represents the new DACL for the objects being reset. The SecurityInfo
/// parameter must include the DACL_SECURITY_INFORMATION flag. The caller must have READ_CONTROL and WRITE_DAC access to each object,
/// including the root object. If you are not setting the DACL, this parameter can be <c>NULL</c>.
/// </para>
/// </param>
/// <param name="pSacl">
/// <para>
/// A pointer to an ACL structure that represents the new SACL for the objects being reset. The SecurityInfo parameter must include
/// any of the following flags: SACL_SECURITY_INFORMATION, LABEL_SECURITY_INFORMATION, ATTRIBUTE_SECURITY_INFORMATION,
/// SCOPE_SECURITY_INFORMATION, or BACKUP_SECURITY_INFORMATION. If setting SACL_SECURITY_INFORMATION or SCOPE_SECURITY_INFORMATION,
/// the caller must have the SE_SECURITY_NAME privilege enabled. If you are not setting the SACL, this parameter can be <c>NULL</c>.
/// </para>
/// </param>
/// <param name="dwAction">
/// <para>Specifies the behavior of this function. This must be set to one of the following values, defined in AccCtrl.h.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>TREE_SEC_INFO_SET 0x00000001</term>
/// <term>
/// The security information is set on the object specified by the pObjectName parameter and the tree of child objects of that
/// object. If ACLs are specified in either the pDacl or pSacl parameters, the security descriptors are associated with the object.
/// The security descriptors are propagated to the tree of child objects based on their inheritance properties.
/// </term>
/// </item>
/// <item>
/// <term>TREE_SEC_INFO_RESET 0x00000002</term>
/// <term>
/// The security information is reset on the object specified by the pObjectName parameter and the tree of child objects of that
/// object. Any existing security information is removed from all objects on the tree. If any object in the tree does not grant
/// appropriate permissions to the caller to modify the security descriptor on the object, then the propagation of security
/// information on that particular node of the tree and its objects is skipped. The operation continues on the rest of the tree under
/// the object specified by the pObjectName parameter.
/// </term>
/// </item>
/// <item>
/// <term>TREE_SEC_INFO_RESET_KEEP_EXPLICIT 0x00000003</term>
/// <term>
/// The security information is reset on the object specified by the pObjectName parameter and the tree of child objects of that
/// object. Any existing inherited security information is removed from all objects on the tree. Security information that was
/// explicitly set on objects in the tree is unchanged. If any object in the tree does not grant appropriate permissions to the
/// caller to modify the security descriptor on the object, then the propagation of security information on that particular node of
/// the tree and its objects is skipped. The operation continues on the rest of the tree under the object specified by the
/// pObjectName parameter.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="fnProgress">
/// <para>
/// A pointer to the function used to track the progress of the <c>TreeSetNamedSecurityInfo</c> function. The prototype of the
/// progress function is:
/// </para>
/// <para>
/// The progress function provides the caller with progress and error information when nodes are processed. The caller specifies the
/// progress function in fnProgress, and during the tree operation, <c>TreeSetNamedSecurityInfo</c> passes the name of the last
/// object processed, the error status of that operation, and the current PROG_INVOKE_SETTING value. The caller can change the
/// PROG_INVOKE_SETTING value by using pInvokeSetting.
/// </para>
/// <para>If no progress function is to be used, set this parameter to <c>NULL</c>.</para>
/// </param>
/// <param name="ProgressInvokeSetting">
/// <para>A value of the PROG_INVOKE_SETTING enumeration that specifies the initial setting for the progress function.</para>
/// </param>
/// <param name="Args">
/// <para>A pointer to a <c>VOID</c> for progress function arguments specified by the caller.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>ERROR_SUCCESS</c>.</para>
/// <para>If the function fails, it returns an error code defined in WinError.h.</para>
/// </returns>
/// <remarks>
/// <para>Setting a <c>NULL</c> owner, group, DACL, or SACL is not supported by this function.</para>
/// <para>
/// If the caller does not contain the proper privileges and permissions to support the requested owner, group, DACL, and SACL
/// updates, then none of the updates is performed.
/// </para>
/// <para>
/// This function provides the same functionality as the SetNamedSecurityInfo function when the value of the dwAction parameter is
/// set to <c>TREE_SEC_INFO_SET</c>, the value of the ProgressInvokeSetting parameter is set to <c>ProgressInvokePrePostError</c>,
/// and the function pointed to by the fnProgress parameter sets the value of its pInvokeSetting parameter to <c>ProgressInvokePrePostError</c>.
/// </para>
/// <para>This function is similar to the TreeResetNamedSecurityInfo function:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// If the dwAction parameter of <c>TreeSetNamedSecurityInfo</c> is set to TREE_SEC_INFO_RESET_KEEP_EXPLICIT, then the function is
/// equivalent to TreeResetNamedSecurityInfo with the KeepExplicit parameter set to <c>TRUE</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// If the dwAction parameter of <c>TreeSetNamedSecurityInfo</c> is set to TREE_SEC_INFO_RESET, then the function is equivalent to
/// TreeResetNamedSecurityInfo with the KeepExplicit parameter set to <c>FALSE</c>.
/// </term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/aclapi/nf-aclapi-treesetnamedsecurityinfow DWORD TreeSetNamedSecurityInfoW(
// LPWSTR pObjectName, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, PSID pOwner, PSID pGroup, PACL pDacl, PACL
// pSacl, DWORD dwAction, FN_PROGRESS fnProgress, PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args );
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("aclapi.h", MSDNShortId = "caa711c3-301b-4ed7-b1f4-dc6a48563905")]
public static extern Win32Error TreeSetNamedSecurityInfo(string pObjectName, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, PSID pOwner, PSID pGroup,
PACL pDacl, PACL pSacl, TREE_SEC_INFO dwAction, [Optional] FN_PROGRESS fnProgress, PROG_INVOKE_SETTING ProgressInvokeSetting, [Optional] IntPtr Args);
/// <summary>A <see cref="SafeHandle"/> to hold the array of <see cref="INHERITED_FROM"/> instances returned from <see cref="GetInheritanceSource(string, SE_OBJECT_TYPE, SECURITY_INFORMATION, bool, Guid[], uint, PACL, IntPtr, in GENERIC_MAPPING, SafeInheritedFromArray)"/>.</summary>
public class SafeInheritedFromArray : SafeHGlobalHandle
{
/// <summary>Initializes a new instance of the <see cref="SafeInheritedFromArray"/> class.</summary>
/// <param name="aceCount">The count of ACEs that are contained in the ACL.</param>
public SafeInheritedFromArray(ushort aceCount) : base(aceCount * Marshal.SizeOf(typeof(INHERITED_FROM))) => AceCount = aceCount;
/// <summary>Gets the count of ACEs that are contained in the ACL.</summary>
/// <value>The ACE count.</value>
public ushort AceCount { get; }
/// <summary>Gets the array of inheritance objects.</summary>
/// <value>The array of inheritance objects.</value>
public INHERITED_FROM[] Results => handle.ToArray<INHERITED_FROM>(AceCount);
/// <summary>When overridden in a derived class, executes the code required to free the handle.</summary>
/// <returns>
/// true if the handle is released successfully; otherwise, in the event of a catastrophic failure, false. In this case, it
/// generates a releaseHandleFailed MDA Managed Debugging Assistant.
/// </returns>
protected override bool ReleaseHandle()
{
FreeInheritedFromArray(handle, AceCount, IntPtr.Zero);
return base.ReleaseHandle();
}
}
}
}