From 2b99c81de040f074a1735f55c33f68b47832330c Mon Sep 17 00:00:00 2001 From: David Hall Date: Tue, 25 Jun 2019 17:21:08 -0600 Subject: [PATCH] Lots of bug fixes for namespace api --- PInvoke/Kernel32/NameSpaceApi.cs | 82 +++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 18 deletions(-) diff --git a/PInvoke/Kernel32/NameSpaceApi.cs b/PInvoke/Kernel32/NameSpaceApi.cs index 7ce928c9..cc2b54d6 100644 --- a/PInvoke/Kernel32/NameSpaceApi.cs +++ b/PInvoke/Kernel32/NameSpaceApi.cs @@ -1,5 +1,7 @@ using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Security; namespace Vanara.PInvoke { @@ -50,7 +52,7 @@ namespace Vanara.PInvoke [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winbase.h", MSDNShortId = "6b56e664-7795-4e30-8bca-1e4df2764606")] [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool AddIntegrityLabelToBoundaryDescriptor(ref BoundaryDescriptorHandle BoundaryDescriptor, IntPtr IntegrityLabel); + public static extern bool AddIntegrityLabelToBoundaryDescriptor(ref BoundaryDescriptorHandle BoundaryDescriptor, PSID IntegrityLabel); /// Adds a security identifier (SID) to the specified boundary descriptor. /// @@ -65,18 +67,20 @@ namespace Vanara.PInvoke [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] [PInvokeData("WinBase.h", MSDNShortId = "ms681937")] [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool AddSIDToBoundaryDescriptor(ref BoundaryDescriptorHandle BoundaryDescriptor, IntPtr RequiredSid); + public static extern bool AddSIDToBoundaryDescriptor(ref BoundaryDescriptorHandle BoundaryDescriptor, PSID RequiredSid); /// Closes an open namespace handle. - /// The namespace handle. This handle is created by CreatePrivateNamespace or OpenPrivateNamespace. + /// The namespace handle. This handle is created by CreatePrivateNamespace or OpenPrivateNamespace. /// If this parameter is PRIVATE_NAMESPACE_FLAG_DESTROY (0x00000001), the namespace is destroyed. /// /// If the function succeeds, the return value is nonzero. - /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// - // BOOLEAN WINAPI ClosePrivateNamespace( _In_ HANDLE Handle, _In_ ULONG Flags); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682026(v=vs.85).aspx + /// To compile an application that uses this function, define _WIN32_WINNT as 0x0600 or later. + // https://docs.microsoft.com/en-us/windows/desktop/api/namespaceapi/nf-namespaceapi-closeprivatenamespace + // BOOLEAN ClosePrivateNamespace( HANDLE Handle, ULONG Flags ); [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] - [PInvokeData("WinBase.h", MSDNShortId = "ms682026")] + [PInvokeData("namespaceapi.h", MSDNShortId = "b9b74cf2-bf13-4ceb-9242-bc6a884ac6f1")] [return: MarshalAs(UnmanagedType.U1)] public static extern bool ClosePrivateNamespace(NamespaceHandle Handle, uint Flags); @@ -112,16 +116,17 @@ namespace Vanara.PInvoke // lpBoundaryDescriptor, _In_ LPCTSTR lpAliasPrefix); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682419(v=vs.85).aspx [DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "ms682419")] - public static extern SafeNamespaceHandle CreatePrivateNamespace(SECURITY_ATTRIBUTES lpPrivateNamespaceAttributes, BoundaryDescriptorHandle lpBoundaryDescriptor, string lpAliasPrefix); + public static extern SafeNamespaceHandle CreatePrivateNamespace([In, Optional] SECURITY_ATTRIBUTES lpPrivateNamespaceAttributes, BoundaryDescriptorHandle lpBoundaryDescriptor, string lpAliasPrefix); /// Deletes the specified boundary descriptor. - /// - /// A handle to the boundary descriptor. The CreateBoundaryDescriptor function returns this handle. - /// + /// A handle to the boundary descriptor. The CreateBoundaryDescriptor function returns this handle. /// This function does not return a value. - // VOID WINAPI DeleteBoundaryDescriptor( _In_ HANDLE BoundaryDescriptor); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682549(v=vs.85).aspx + /// To compile an application that uses this function, define _WIN32_WINNT as 0x0600 or later. + // https://docs.microsoft.com/en-us/windows/desktop/api/namespaceapi/nf-namespaceapi-deleteboundarydescriptor + // void DeleteBoundaryDescriptor( HANDLE BoundaryDescriptor ); [DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)] - [PInvokeData("WinBase.h", MSDNShortId = "ms682549")] + [SecurityCritical, SuppressUnmanagedCodeSecurity] + [PInvokeData("namespaceapi.h", MSDNShortId = "759d9cd9-9ef2-4bbe-9e99-8aec87f5ba4a")] public static extern void DeleteBoundaryDescriptor(BoundaryDescriptorHandle BoundaryDescriptor); /// Opens a private namespace. @@ -133,9 +138,25 @@ namespace Vanara.PInvoke /// /// The function returns the handle to the existing namespace. // HANDLE WINAPI OpenPrivateNamespace( _In_ LPVOID lpBoundaryDescriptor, _In_ LPCTSTR lpAliasPrefix); https://msdn.microsoft.com/en-us/library/windows/desktop/ms684318(v=vs.85).aspx - [DllImport(Lib.Kernel32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("WinBase.h", MSDNShortId = "ms684318")] - public static extern NamespaceHandle OpenPrivateNamespace(BoundaryDescriptorHandle lpBoundaryDescriptor, string lpAliasPrefix); + public static SafeNamespaceHandle OpenPrivateNamespace(BoundaryDescriptorHandle lpBoundaryDescriptor, string lpAliasPrefix) + { + var h = OpenPrivateNamespaceInternal(lpBoundaryDescriptor, lpAliasPrefix); + h.flag = 0; + return h; + } + + /// Opens a private namespace. + /// + /// A descriptor that defines how the namespace is to be isolated. The CreateBoundaryDescriptor function creates a boundary descriptor. + /// + /// + /// The prefix for the namespace. To create an object in this namespace, specify the object name as prefix\objectname. + /// + /// The function returns the handle to the existing namespace. + [DllImport(Lib.Kernel32, SetLastError = false, CharSet = CharSet.Auto, EntryPoint = "OpenPrivateNamespace")] + [PInvokeData("WinBase.h", MSDNShortId = "ms684318")] + private static extern SafeNamespaceHandle OpenPrivateNamespaceInternal(BoundaryDescriptorHandle lpBoundaryDescriptor, string lpAliasPrefix); /// Provides a handle to a boundary descriptor. [StructLayout(LayoutKind.Sequential)] @@ -187,7 +208,7 @@ namespace Vanara.PInvoke /// Provides a handle to a private namespace. [StructLayout(LayoutKind.Sequential)] - public struct NamespaceHandle + public struct NamespaceHandle : IHandle { private IntPtr handle; @@ -228,6 +249,9 @@ namespace Vanara.PInvoke /// public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; } /// @@ -251,13 +275,35 @@ namespace Vanara.PInvoke /// The result of the conversion. public static implicit operator BoundaryDescriptorHandle(SafeBoundaryDescriptorHandle h) => h.handle; + /// Adds a security identifier (SID) to the boundary descriptor. + /// A pointer to a SID structure. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + public bool AddSid(PSID pSid) + { + BoundaryDescriptorHandle h = handle; + if (Marshal.ReadByte(pSid.DangerousGetHandle(), 7) == 16) + return AddIntegrityLabelToBoundaryDescriptor(ref h, pSid); + return AddSIDToBoundaryDescriptor(ref h, pSid); + } + /// - protected override bool InternalReleaseHandle() { DeleteBoundaryDescriptor(this); return true; } + [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)] + protected override bool InternalReleaseHandle() + { + BoundaryDescriptorHandle h = handle; + DeleteBoundaryDescriptor(h); + return true; + } } - /// Provides a to a that releases a created NamespaceHandle instance at disposal using CloseHandle. + /// Provides a to a that releases a created NamespaceHandle instance at disposal using ClosePrivateNamespace. public class SafeNamespaceHandle : SafeHANDLE { + internal uint flag = PRIVATE_NAMESPACE_FLAG_DESTROY; + /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// @@ -275,7 +321,7 @@ namespace Vanara.PInvoke public static implicit operator NamespaceHandle(SafeNamespaceHandle h) => h.handle; /// - protected override bool InternalReleaseHandle() => ClosePrivateNamespace(this, 1); + protected override bool InternalReleaseHandle() => ClosePrivateNamespace(handle, flag); } } } \ No newline at end of file