Skip to content

Commit 03b2884

Browse files
committed
SetEntriesInAcl function, aclapi.h line 75
1 parent f35973b commit 03b2884

File tree

6 files changed

+186
-4
lines changed

6 files changed

+186
-4
lines changed

src-shared/THNETII.WinApi.NativeLibraryNames/NativeLibraryNames.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
namespace THNETII.WinApi
1+
namespace THNETII.WinApi
22
{
33
public static class NativeLibraryNames
44
{
5+
public const string Advapi32 = "Advapi32.dll";
56
public const string KernelBase = "KernelBase.dll";
67
public const string Kernel32 = "Kernel32.dll";
78
public const string Ntdll = "Ntdll.dll";

src/THNETII.WinApi.Headers.AccCtrl/EXPLICIT_ACCESS.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public struct EXPLICIT_ACCESS_W
7373
/// <seealso cref="BuildSecurityDescriptor"/>
7474
/// <seealso cref="GetExplicitEntriesFromAcl"/>
7575
/// <seealso cref="LookupSecurityDescriptorParts"/>
76-
/// <seealso cref="SetEntriesInAcl"/>
76+
/// <seealso cref="M:THNETII.WinApi.Native.AclApi.AclApiFunctions.SetEntriesInAcl(System.ReadOnlySpan{THNETII.WinApi.Native.AccCtrl.EXPLICIT_ACCESS},System.IntPtr,System.IntPtr@)"/>
7777
/// <seealso cref="TRUSTEE"/>
7878
#if !NETSTANDARD1_6
7979
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

src/THNETII.WinApi.Headers.AccCtrl/GlobalSuppressions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
using System.Diagnostics.CodeAnalysis;
77

88
[assembly: SuppressMessage("Documentation", "CS1591: Missing XML comment for publicly visible type or member")]
9+
[assembly: SuppressMessage("Documentation", "CA1200: Avoid using cref tags with a prefix")]
910
[assembly: SuppressMessage("Design", "CA1028: Enum Storage should be Int32")]
11+
[assembly: SuppressMessage("Design", "CA1051: Do not declare visible instance fields")]
1012
[assembly: SuppressMessage("Naming", "CA1714: Flags enums should have plural names")]
1113
[assembly: SuppressMessage("Naming", "CA1707: Identifiers should not contain underscores")]
12-
[assembly: SuppressMessage("Design", "CA1051: Do not declare visible instance fields")]
1314
[assembly: SuppressMessage("Performance", "CA1815: Override equals and operator equals on value types")]
1415
[assembly: SuppressMessage("Style", "IDE1006: Naming Styles")]
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
using System.Security.AccessControl;
4+
5+
using THNETII.WinApi.Native.AccCtrl;
6+
using THNETII.WinApi.Native.WinError;
7+
using THNETII.WinApi.Native.WinNT;
8+
9+
#if NETSTANDARD1_6
10+
using EntryPointNotFoundException = System.Exception;
11+
#endif
12+
13+
namespace THNETII.WinApi.Native.AclApi
14+
{
15+
using static ACCESS_MODE;
16+
using static NativeLibraryNames;
17+
using static WinErrorConstants;
18+
19+
/// <summary>
20+
/// Win32 Access Control APIs
21+
/// </summary>
22+
public static class AclApiFunctions
23+
{
24+
// C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\um\AclAPI.h, line 53
25+
#region SetEntriesInAclA function
26+
/// <inheritdoc cref="SetEntriesInAcl"/>
27+
public static unsafe int SetEntriesInAclA(
28+
ReadOnlySpan<EXPLICIT_ACCESS_A> pListOfExplicitEntries,
29+
[Optional] IntPtr OldAcl,
30+
out IntPtr NewAcl
31+
)
32+
{
33+
fixed (EXPLICIT_ACCESS_A* ptrListOfExplicitEntries = pListOfExplicitEntries)
34+
return SetEntriesInAclA(
35+
pListOfExplicitEntries.Length,
36+
ptrListOfExplicitEntries,
37+
OldAcl,
38+
out NewAcl);
39+
}
40+
41+
[DllImport(Advapi32, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Ansi)]
42+
private static extern unsafe int SetEntriesInAclA(
43+
[In] int cCountOfExplicitEntries,
44+
[In] EXPLICIT_ACCESS_A* pListOfExplicitEntries,
45+
[In, Optional] IntPtr OldAcl,
46+
out IntPtr NewAcl
47+
);
48+
#endregion
49+
#region SetEntriesInAclW function
50+
/// <inheritdoc cref="SetEntriesInAcl"/>
51+
public static unsafe int SetEntriesInAclW(
52+
ReadOnlySpan<EXPLICIT_ACCESS_W> pListOfExplicitEntries,
53+
[Optional] IntPtr OldAcl,
54+
out IntPtr NewAcl
55+
)
56+
{
57+
fixed (EXPLICIT_ACCESS_W* ptrListOfExplicitEntries = pListOfExplicitEntries)
58+
return SetEntriesInAclW(
59+
pListOfExplicitEntries.Length,
60+
ptrListOfExplicitEntries,
61+
OldAcl,
62+
out NewAcl);
63+
}
64+
65+
[DllImport(Advapi32, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode)]
66+
private static extern unsafe int SetEntriesInAclW(
67+
[In] int cCountOfExplicitEntries,
68+
[In] EXPLICIT_ACCESS_W* pListOfExplicitEntries,
69+
[In, Optional] IntPtr OldAcl,
70+
out IntPtr NewAcl
71+
);
72+
#endregion
73+
#region SetEntriesInAcl function
74+
/// <summary>
75+
/// The <see cref="SetEntriesInAcl"/> function creates a new <a href="https://docs.microsoft.com/windows/desktop/SecGloss/a-gly">access control list</a> (ACL) by merging new access control or audit control information into an existing <see cref="ACL"/> structure.
76+
/// </summary>
77+
/// <param name="pListOfExplicitEntries">A span of <see cref="EXPLICIT_ACCESS"/> structures that describe the access control information to merge into the existing ACL.</param>
78+
/// <param name="OldAcl">A pointer to the existing ACL. This parameter can be <see cref="IntPtr.Zero"/>, in which case, the function creates a new ACL based on the <see cref="EXPLICIT_ACCESS"/> entries.</param>
79+
/// <param name="NewAcl">A variable that receives a pointer to the new ACL. If the function succeeds, you must call the <see cref="LocalFree"/> function to free the returned buffer.</param>
80+
/// <returns>
81+
/// <para>If the function succeeds, the function returns <see cref="ERROR_SUCCESS"/>.</para>
82+
/// <para>If the function fails, it returns a nonzero error code.</para>
83+
/// </returns>
84+
/// <remarks>
85+
/// <para>Each entry in the array of <see cref="EXPLICIT_ACCESS"/> structures specifies access control or audit control information for a specified trustee. A trustee can be a user, group, or other <a href="https://docs.microsoft.com/windows/desktop/SecGloss/s-gly">security identifier</a> (SID) value, such as a <a href="https://docs.microsoft.com/windows/desktop/SecGloss/l-gly">logon identifier</a> or logon type (for instance, a Windows service or batch job). You can use a name or a SID to identify a trustee.</para>
86+
/// <para>You can use the <see cref="SetEntriesInAcl"/> function to modify the list of <a href="https://docs.microsoft.com/windows/desktop/SecGloss/a-gly">access control entries</a> (ACEs) in a <a href="https://docs.microsoft.com/windows/desktop/SecGloss/d-gly">discretionary access control list</a> (DACL) or a <a href="https://docs.microsoft.com/windows/desktop/SecGloss/s-gly">system access control list</a> (SACL). Note that <see cref="SetEntriesInAcl"/> does not prevent you from mixing access control and audit control information in the same <see cref="ACL"/>; however, the resulting ACL will contain meaningless entries.</para>
87+
/// <para>
88+
/// For a DACL, the <see cref="EXPLICIT_ACCESS.grfAccessMode"/> member of the <see cref="EXPLICIT_ACCESS"/> structure specifies whether to allow, deny, or revoke access rights for the trustee. This member can specify one of the following values:
89+
/// <list type="bullet">
90+
/// <item><see cref="GRANT_ACCESS"/></item>
91+
/// <item><see cref="SET_ACCESS"/></item>
92+
/// <item><see cref="DENY_ACCESS"/></item>
93+
/// <item><see cref="REVOKE_ACCESS"/></item>
94+
/// </list>
95+
/// For information about these values, see <see cref="ACCESS_MODE"/>.
96+
/// </para>
97+
/// <para>The <see cref="SetEntriesInAcl"/> function places any new access-denied ACEs at the beginning of the list of ACEs for the new <see cref="ACL"/>. This function places any new access-allowed ACEs just before any existing access-allowed ACEs.</para>
98+
/// <para>
99+
/// For a SACL, the <see cref="EXPLICIT_ACCESS.grfAccessMode"/> member of the <see cref="EXPLICIT_ACCESS"/> structure can specify the following values:
100+
/// <list type="bullet">
101+
/// <item><see cref="REVOKE_ACCESS"/></item>
102+
/// <item><see cref="SET_AUDIT_FAILURE"/></item>
103+
/// <item><see cref="SET_AUDIT_SUCCESS"/></item>
104+
/// </list>
105+
/// <see cref="SET_AUDIT_FAILURE"/> and <see cref="SET_AUDIT_SUCCESS"/> can be combined. For information about these values, see <see cref="ACCESS_MODE"/>.
106+
/// </para>
107+
/// <para>The <see cref="SetEntriesInAcl"/> function places any new system-audit ACEs at the beginning of the list of ACEs for the new ACL.</para>
108+
/// <para>
109+
/// <list type="table">
110+
/// <listheader><term>Requirements</term></listheader>
111+
/// <item><term><strong>Minimum supported client:</strong></term><description>Windows XP [desktop apps | UWP apps]</description></item>
112+
/// <item><term><strong>Minimum supported server:</strong></term><description>Windows Server 2003 [desktop apps | UWP apps]</description></item>
113+
/// </list>
114+
/// </para>
115+
/// <para>Microsoft Docs page: <a href="https://docs.microsoft.com/en-us/windows/win32/api/aclapi/nf-aclapi-setentriesinaclw">SetEntriesInAclW function</a></para>
116+
/// </remarks>
117+
/// <exception cref="DllNotFoundException">The native library containg the function could not be found.</exception>
118+
/// <exception cref="EntryPointNotFoundException">Unable to find the entry point for the function in the native library.</exception>
119+
/// <seealso cref="ACL"/>
120+
/// <seealso cref="GenericAce"/>
121+
/// <seealso cref="GenericAcl"/>
122+
/// <seealso href="https://docs.microsoft.com/windows/desktop/SecAuthZ/access-control">Access Control</seealso>
123+
/// <seealso href="https://docs.microsoft.com/windows/desktop/SecAuthZ/authorization-functions">Basic Access Control Functions</seealso>
124+
/// <seealso cref="EXPLICIT_ACCESS"/>
125+
/// <seealso cref="LocalFree"/>
126+
public static unsafe int SetEntriesInAcl(
127+
ReadOnlySpan<EXPLICIT_ACCESS> pListOfExplicitEntries,
128+
[Optional] IntPtr OldAcl,
129+
out IntPtr NewAcl
130+
)
131+
{
132+
fixed (EXPLICIT_ACCESS* ptrListOfExplicitEntries = pListOfExplicitEntries)
133+
return SetEntriesInAcl(
134+
pListOfExplicitEntries.Length,
135+
ptrListOfExplicitEntries,
136+
OldAcl,
137+
out NewAcl);
138+
}
139+
140+
#if !NETSTANDARD1_6
141+
[DllImport(Advapi32, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
142+
private static extern
143+
#else
144+
private static
145+
#endif // !NETSTANDARD1_6
146+
unsafe int SetEntriesInAcl(
147+
[In] int cCountOfExplicitEntries,
148+
[In] EXPLICIT_ACCESS* pListOfExplicitEntries,
149+
[In, Optional] IntPtr OldAcl,
150+
out IntPtr NewAcl
151+
)
152+
#if !NETSTANDARD1_6
153+
;
154+
#else
155+
=> Marshal.SystemDefaultCharSize switch
156+
{
157+
1 => SetEntriesInAclA(cCountOfExplicitEntries,
158+
(EXPLICIT_ACCESS_A*)pListOfExplicitEntries,
159+
OldAcl, out NewAcl),
160+
2 => SetEntriesInAclW(cCountOfExplicitEntries,
161+
(EXPLICIT_ACCESS_W*)pListOfExplicitEntries,
162+
OldAcl, out NewAcl),
163+
_ => throw new PlatformNotSupportedException()
164+
};
165+
#endif // !NETSTANDARD1_6
166+
#endregion
167+
}
168+
}

src/THNETII.WinApi.Headers.AclApi/GlobalSuppressions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55

66
using System.Diagnostics.CodeAnalysis;
77

8+
[assembly: SuppressMessage("Documentation", "CS0419: Ambiguous reference in cref attribute")]
89
[assembly: SuppressMessage("Naming", "CA1707: Identifiers should not contain underscores")]
910
[assembly: SuppressMessage("Design", "CA1051: Do not declare visible instance fields")]
1011
[assembly: SuppressMessage("Performance", "CA1815: Override equals and operator equals on value types")]
1112
[assembly: SuppressMessage("Style", "IDE1006: Naming Styles")]
13+
[assembly: SuppressMessage("Usage", "PC003: Native API not available in UWP")]

src/THNETII.WinApi.Headers.AclApi/THNETII.WinApi.Headers.AclApi.csproj

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<Project Sdk="Microsoft.NET.Sdk">
33

44
<PropertyGroup>
@@ -7,8 +7,18 @@
77
<TargetFrameworks>netstandard1.6;netstandard2.0</TargetFrameworks>
88
<GenerateDocumentationFile>true</GenerateDocumentationFile>
99
<RootNamespace>THNETII.WinApi.Native.AclApi</RootNamespace>
10+
<NoWarn>$(NoWarn);0419</NoWarn>
1011
</PropertyGroup>
1112

13+
<ItemGroup>
14+
<ProjectReference Include="..\..\src-shared\THNETII.WinApi.NativeLibraryNames\THNETII.WinApi.NativeLibraryNames.csproj">
15+
<PrivateAssets>All</PrivateAssets>
16+
</ProjectReference>
17+
<ProjectReference Include="..\THNETII.WinApi.Constants.WinError\THNETII.WinApi.Constants.WinError.csproj">
18+
<PrivateAssets>All</PrivateAssets>
19+
</ProjectReference>
20+
</ItemGroup>
21+
1222
<ItemGroup>
1323
<ProjectReference Include="..\THNETII.WinApi.Headers.AccCtrl\THNETII.WinApi.Headers.AccCtrl.csproj" />
1424
</ItemGroup>

0 commit comments

Comments
 (0)