diff --git a/TH-NETII Windows API.sln b/TH-NETII Windows API.sln index 9aedabfa..d4aec790 100644 --- a/TH-NETII Windows API.sln +++ b/TH-NETII Windows API.sln @@ -97,6 +97,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "THNETII.WinApi.Headers.ApDe EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "THNETII.WinApi.Headers.AccCtrl", "src\THNETII.WinApi.Headers.AccCtrl\THNETII.WinApi.Headers.AccCtrl.csproj", "{8FA68C49-D060-4DE2-94A3-996320B314E2}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "THNETII.WinApi.Headers.AclApi", "src\THNETII.WinApi.Headers.AclApi\THNETII.WinApi.Headers.AclApi.csproj", "{DAA939D2-0C4C-4136-A1C6-6073311E0F3F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -515,6 +517,18 @@ Global {8FA68C49-D060-4DE2-94A3-996320B314E2}.Release|x64.Build.0 = Release|Any CPU {8FA68C49-D060-4DE2-94A3-996320B314E2}.Release|x86.ActiveCfg = Release|Any CPU {8FA68C49-D060-4DE2-94A3-996320B314E2}.Release|x86.Build.0 = Release|Any CPU + {DAA939D2-0C4C-4136-A1C6-6073311E0F3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DAA939D2-0C4C-4136-A1C6-6073311E0F3F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DAA939D2-0C4C-4136-A1C6-6073311E0F3F}.Debug|x64.ActiveCfg = Debug|Any CPU + {DAA939D2-0C4C-4136-A1C6-6073311E0F3F}.Debug|x64.Build.0 = Debug|Any CPU + {DAA939D2-0C4C-4136-A1C6-6073311E0F3F}.Debug|x86.ActiveCfg = Debug|Any CPU + {DAA939D2-0C4C-4136-A1C6-6073311E0F3F}.Debug|x86.Build.0 = Debug|Any CPU + {DAA939D2-0C4C-4136-A1C6-6073311E0F3F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DAA939D2-0C4C-4136-A1C6-6073311E0F3F}.Release|Any CPU.Build.0 = Release|Any CPU + {DAA939D2-0C4C-4136-A1C6-6073311E0F3F}.Release|x64.ActiveCfg = Release|Any CPU + {DAA939D2-0C4C-4136-A1C6-6073311E0F3F}.Release|x64.Build.0 = Release|Any CPU + {DAA939D2-0C4C-4136-A1C6-6073311E0F3F}.Release|x86.ActiveCfg = Release|Any CPU + {DAA939D2-0C4C-4136-A1C6-6073311E0F3F}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -555,6 +569,7 @@ Global {E4A4DA91-3696-40A6-9834-E5FAACEF682E} = {9689DB3E-1ED7-478C-AC14-C734B0397619} {C0B32983-2879-4DAD-B834-8A40570A35CA} = {9689DB3E-1ED7-478C-AC14-C734B0397619} {8FA68C49-D060-4DE2-94A3-996320B314E2} = {9689DB3E-1ED7-478C-AC14-C734B0397619} + {DAA939D2-0C4C-4136-A1C6-6073311E0F3F} = {9689DB3E-1ED7-478C-AC14-C734B0397619} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {6EF7C9CF-E403-4B60-AB44-5F9FFEB668B7} diff --git a/src-native-c/THNETII.WinApi.Sample.Native/main.c b/src-native-c/THNETII.WinApi.Sample.Native/main.c index d00df0ce..f8152ebe 100644 --- a/src-native-c/THNETII.WinApi.Sample.Native/main.c +++ b/src-native-c/THNETII.WinApi.Sample.Native/main.c @@ -1,12 +1,12 @@ -#include +#include int main(int argc, char* argv[]) { - ACE_HEADER instance; + FN_PROGRESS instance; const int size = sizeof(instance); - const int value = ACE_OBJECT_TYPE_PRESENT; + const int value = NULL; - const void* ptr = AccFree; + const void* ptr = SetEntriesInAcl; return EXIT_SUCCESS; } diff --git a/src-shared/THNETII.WinApi.NativeLibraryNames/NativeLibraryNames.cs b/src-shared/THNETII.WinApi.NativeLibraryNames/NativeLibraryNames.cs index 23ff251a..e602ace7 100644 --- a/src-shared/THNETII.WinApi.NativeLibraryNames/NativeLibraryNames.cs +++ b/src-shared/THNETII.WinApi.NativeLibraryNames/NativeLibraryNames.cs @@ -1,7 +1,8 @@ -namespace THNETII.WinApi +namespace THNETII.WinApi { public static class NativeLibraryNames { + public const string Advapi32 = "Advapi32.dll"; public const string KernelBase = "KernelBase.dll"; public const string Kernel32 = "Kernel32.dll"; public const string Ntdll = "Ntdll.dll"; diff --git a/src/THNETII.WinApi.Headers.AccCtrl/EXPLICIT_ACCESS.cs b/src/THNETII.WinApi.Headers.AccCtrl/EXPLICIT_ACCESS.cs index fec0ba23..ec4c6e22 100644 --- a/src/THNETII.WinApi.Headers.AccCtrl/EXPLICIT_ACCESS.cs +++ b/src/THNETII.WinApi.Headers.AccCtrl/EXPLICIT_ACCESS.cs @@ -73,7 +73,7 @@ public struct EXPLICIT_ACCESS_W /// /// /// - /// + /// /// #if !NETSTANDARD1_6 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] diff --git a/src/THNETII.WinApi.Headers.AccCtrl/GlobalSuppressions.cs b/src/THNETII.WinApi.Headers.AccCtrl/GlobalSuppressions.cs index 9290e45f..b5c49254 100644 --- a/src/THNETII.WinApi.Headers.AccCtrl/GlobalSuppressions.cs +++ b/src/THNETII.WinApi.Headers.AccCtrl/GlobalSuppressions.cs @@ -6,9 +6,10 @@ using System.Diagnostics.CodeAnalysis; [assembly: SuppressMessage("Documentation", "CS1591: Missing XML comment for publicly visible type or member")] +[assembly: SuppressMessage("Documentation", "CA1200: Avoid using cref tags with a prefix")] [assembly: SuppressMessage("Design", "CA1028: Enum Storage should be Int32")] +[assembly: SuppressMessage("Design", "CA1051: Do not declare visible instance fields")] [assembly: SuppressMessage("Naming", "CA1714: Flags enums should have plural names")] [assembly: SuppressMessage("Naming", "CA1707: Identifiers should not contain underscores")] -[assembly: SuppressMessage("Design", "CA1051: Do not declare visible instance fields")] [assembly: SuppressMessage("Performance", "CA1815: Override equals and operator equals on value types")] [assembly: SuppressMessage("Style", "IDE1006: Naming Styles")] diff --git a/src/THNETII.WinApi.Headers.AccCtrl/THNETII.WinApi.Headers.AccCtrl.csproj b/src/THNETII.WinApi.Headers.AccCtrl/THNETII.WinApi.Headers.AccCtrl.csproj index 689315df..3daaaefb 100644 --- a/src/THNETII.WinApi.Headers.AccCtrl/THNETII.WinApi.Headers.AccCtrl.csproj +++ b/src/THNETII.WinApi.Headers.AccCtrl/THNETII.WinApi.Headers.AccCtrl.csproj @@ -10,9 +10,7 @@ - - All - + diff --git a/src/THNETII.WinApi.Headers.AclApi/AclApiFunctions.cs b/src/THNETII.WinApi.Headers.AclApi/AclApiFunctions.cs new file mode 100644 index 00000000..312d8bfb --- /dev/null +++ b/src/THNETII.WinApi.Headers.AclApi/AclApiFunctions.cs @@ -0,0 +1,171 @@ +using System; +using System.Runtime.InteropServices; +using System.Security.AccessControl; + +using THNETII.WinApi.Native.AccCtrl; +using THNETII.WinApi.Native.WinError; +using THNETII.WinApi.Native.WinNT; + +#if NETSTANDARD1_6 +using EntryPointNotFoundException = System.Exception; +#endif + +namespace THNETII.WinApi.Native.AclApi +{ + using static ACCESS_MODE; + using static NativeLibraryNames; + using static WinErrorConstants; + + /// + /// Win32 Access Control APIs + /// + public static class AclApiFunctions + { + // C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\um\AclAPI.h, line 53 + #region SetEntriesInAclA function + /// + public static unsafe int SetEntriesInAclA( + ReadOnlySpan pListOfExplicitEntries, + [Optional] IntPtr OldAcl, + out IntPtr NewAcl + ) + { + fixed (EXPLICIT_ACCESS_A* ptrListOfExplicitEntries = pListOfExplicitEntries) + return SetEntriesInAclA( + pListOfExplicitEntries.Length, + ptrListOfExplicitEntries, + OldAcl, + out NewAcl); + } + + [DllImport(Advapi32, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Ansi)] + private static extern unsafe int SetEntriesInAclA( + [In] int cCountOfExplicitEntries, + [In] EXPLICIT_ACCESS_A* pListOfExplicitEntries, + [In, Optional] IntPtr OldAcl, + out IntPtr NewAcl + ); + #endregion + // C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\um\AclAPI.h, line 62 + #region SetEntriesInAclW function + /// + public static unsafe int SetEntriesInAclW( + ReadOnlySpan pListOfExplicitEntries, + [Optional] IntPtr OldAcl, + out IntPtr NewAcl + ) + { + fixed (EXPLICIT_ACCESS_W* ptrListOfExplicitEntries = pListOfExplicitEntries) + return SetEntriesInAclW( + pListOfExplicitEntries.Length, + ptrListOfExplicitEntries, + OldAcl, + out NewAcl); + } + + [DllImport(Advapi32, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode)] + private static extern unsafe int SetEntriesInAclW( + [In] int cCountOfExplicitEntries, + [In] EXPLICIT_ACCESS_W* pListOfExplicitEntries, + [In, Optional] IntPtr OldAcl, + out IntPtr NewAcl + ); + // C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\um\AclAPI.h, line 53 + #endregion + // C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\um\AclAPI.h, line 71 + #region SetEntriesInAcl function + /// + /// The function creates a new access control list (ACL) by merging new access control or audit control information into an existing structure. + /// + /// A span of structures that describe the access control information to merge into the existing ACL. + /// A pointer to the existing ACL. This parameter can be , in which case, the function creates a new ACL based on the entries. + /// A variable that receives a pointer to the new ACL. If the function succeeds, you must call the function to free the returned buffer. + /// + /// If the function succeeds, the function returns . + /// If the function fails, it returns a nonzero error code. + /// + /// + /// Each entry in the array of 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. + /// You can use the 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 does not prevent you from mixing access control and audit control information in the same ; however, the resulting ACL will contain meaningless entries. + /// + /// For a DACL, the member of the structure specifies whether to allow, deny, or revoke access rights for the trustee. This member can specify one of the following values: + /// + /// + /// + /// + /// + /// + /// For information about these values, see . + /// + /// The function places any new access-denied ACEs at the beginning of the list of ACEs for the new . This function places any new access-allowed ACEs just before any existing access-allowed ACEs. + /// + /// For a SACL, the member of the structure can specify the following values: + /// + /// + /// + /// + /// + /// and can be combined. For information about these values, see . + /// + /// The function places any new system-audit ACEs at the beginning of the list of ACEs for the new ACL. + /// + /// + /// Requirements + /// Minimum supported client:Windows XP [desktop apps | UWP apps] + /// Minimum supported server:Windows Server 2003 [desktop apps | UWP apps] + /// + /// + /// Microsoft Docs page: SetEntriesInAclW function + /// + /// The native library containg the function could not be found. + /// Unable to find the entry point for the function in the native library. + /// + /// + /// + /// Access Control + /// Basic Access Control Functions + /// + /// + public static unsafe int SetEntriesInAcl( + ReadOnlySpan pListOfExplicitEntries, + [Optional] IntPtr OldAcl, + out IntPtr NewAcl + ) + { + fixed (EXPLICIT_ACCESS* ptrListOfExplicitEntries = pListOfExplicitEntries) + return SetEntriesInAcl( + pListOfExplicitEntries.Length, + ptrListOfExplicitEntries, + OldAcl, + out NewAcl); + } + +#if !NETSTANDARD1_6 + [DllImport(Advapi32, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)] + private static extern +#else + private static +#endif // !NETSTANDARD1_6 + unsafe int SetEntriesInAcl( + [In] int cCountOfExplicitEntries, + [In] EXPLICIT_ACCESS* pListOfExplicitEntries, + [In, Optional] IntPtr OldAcl, + out IntPtr NewAcl + ) +#if !NETSTANDARD1_6 + ; +#else + => Marshal.SystemDefaultCharSize switch + { + 1 => SetEntriesInAclA(cCountOfExplicitEntries, + (EXPLICIT_ACCESS_A*)pListOfExplicitEntries, + OldAcl, out NewAcl), + 2 => SetEntriesInAclW(cCountOfExplicitEntries, + (EXPLICIT_ACCESS_W*)pListOfExplicitEntries, + OldAcl, out NewAcl), + _ => throw new PlatformNotSupportedException() + }; +#endif // !NETSTANDARD1_6 + #endregion + } +} diff --git a/src/THNETII.WinApi.Headers.AclApi/FN_PROGRESS.cs b/src/THNETII.WinApi.Headers.AclApi/FN_PROGRESS.cs new file mode 100644 index 00000000..9d4b93c1 --- /dev/null +++ b/src/THNETII.WinApi.Headers.AclApi/FN_PROGRESS.cs @@ -0,0 +1,37 @@ +using System; +using System.Runtime.InteropServices; + +using THNETII.WinApi.Native.AccCtrl; + +namespace THNETII.WinApi.Native.AclApi +{ + // C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\um\AclAPI.h, line 32 + /// + /// Progress Function + /// + /// Caller of tree operation implements this Progress function, then + /// passes its function pointer to tree operation. + /// Tree operation invokes Progress function to provide progress and error + /// information to the caller during the potentially long execution + /// of the tree operation. Tree operation provides the name of the object + /// last processed and the error status of the operation on that object. + /// Tree operation also passes the current InvokeSetting value. + /// Caller may change the InvokeSetting value, for example, from "Always" + /// to "Only On Error." + /// + /// + /// name of object just processed + /// status of operation on object + /// Never, always, + /// Caller specific data + /// Whether security was set + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + public delegate void FN_PROGRESS( + [In] LPWSTR pObjectName, // name of object just processed + [In] int Status, // status of operation on object + ref PROG_INVOKE_SETTING pInvokeSetting, // Never, always, + [In] IntPtr Args, // Caller specific data + [In, MarshalAs(UnmanagedType.Bool)] + bool SecuritySet // Whether security was set + ); +} diff --git a/src/THNETII.WinApi.Headers.AclApi/GlobalSuppressions.cs b/src/THNETII.WinApi.Headers.AclApi/GlobalSuppressions.cs new file mode 100644 index 00000000..cd5c08f5 --- /dev/null +++ b/src/THNETII.WinApi.Headers.AclApi/GlobalSuppressions.cs @@ -0,0 +1,13 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Documentation", "CS0419: Ambiguous reference in cref attribute")] +[assembly: SuppressMessage("Naming", "CA1707: Identifiers should not contain underscores")] +[assembly: SuppressMessage("Design", "CA1051: Do not declare visible instance fields")] +[assembly: SuppressMessage("Performance", "CA1815: Override equals and operator equals on value types")] +[assembly: SuppressMessage("Style", "IDE1006: Naming Styles")] +[assembly: SuppressMessage("Usage", "PC003: Native API not available in UWP")] diff --git a/src/THNETII.WinApi.Headers.AclApi/THNETII.WinApi.Headers.AclApi.csproj b/src/THNETII.WinApi.Headers.AclApi/THNETII.WinApi.Headers.AclApi.csproj new file mode 100644 index 00000000..11267ef0 --- /dev/null +++ b/src/THNETII.WinApi.Headers.AclApi/THNETII.WinApi.Headers.AclApi.csproj @@ -0,0 +1,26 @@ + + + + + 8 + true + netstandard1.6;netstandard2.0 + true + THNETII.WinApi.Native.AclApi + $(NoWarn);0419 + + + + + All + + + All + + + + + + + +