From fc3ebba3227c38307f2df8f91aa57ef8eb4f3ae5 Mon Sep 17 00:00:00 2001 From: David Hall Date: Tue, 4 Sep 2018 13:43:41 -0600 Subject: [PATCH] Replaced numerous IntPtr calls to SafeSecurityDescriptor. --- PInvoke/NetApi32/Lm.Ext.cs | 4 +-- PInvoke/Security/AdvApi32/WinBase.cs | 2 +- PInvoke/Security/AdvApi32/WinNT.cs | 12 ++++++--- PInvoke/VirtDisk/VirtDisk.cs | 8 +++--- Security/AccessControl/AccCtrlHelper.cs | 30 ++++++++++++++-------- System/VirtualDisk.cs | 29 +++++++++++++-------- UnitTests/PInvoke/AdvApi32/AdvApi32Tests.cs | 11 +++----- UnitTests/System/VirtualDiskTests.cs | 4 +-- .../Dialogs/AccessControlEditor/Providers.cs | 3 ++- .../AccessControlEditor/SecurityInfoImpl.cs | 17 +++++++----- 10 files changed, 72 insertions(+), 48 deletions(-) diff --git a/PInvoke/NetApi32/Lm.Ext.cs b/PInvoke/NetApi32/Lm.Ext.cs index 7b793139..1abbe75e 100644 --- a/PInvoke/NetApi32/Lm.Ext.cs +++ b/PInvoke/NetApi32/Lm.Ext.cs @@ -33,7 +33,7 @@ namespace Vanara.PInvoke var resumeHandle = IntPtr.Zero; var ret = NetServerEnum(null, level, out SafeNetApiBuffer bufptr, MAX_PREFERRED_LENGTH, out int entriesRead, out int totalEntries, netServerEnumFilter, domain, resumeHandle); ret.ThrowIfFailed(); - return ((IntPtr)bufptr).ToIEnum(entriesRead); + return bufptr.DangerousGetHandle().ToIEnum(entriesRead); } /// The NetServerGetInfo function retrieves current configuration information for the specified server. @@ -53,7 +53,7 @@ namespace Vanara.PInvoke throw new ArgumentOutOfRangeException(nameof(level), @"Only SERVER_INFO_100, SERVER_INFO_101, or SERVER_INFO_102 are supported as valid structures."); var ret = NetServerGetInfo(serverName, level, out SafeNetApiBuffer ptr); ret.ThrowIfFailed(); - return ((IntPtr)ptr).ToStructure(); + return ptr.DangerousGetHandle().ToStructure(); } private static int GetLevelFromStructure() diff --git a/PInvoke/Security/AdvApi32/WinBase.cs b/PInvoke/Security/AdvApi32/WinBase.cs index 7db6480d..66f0e704 100644 --- a/PInvoke/Security/AdvApi32/WinBase.cs +++ b/PInvoke/Security/AdvApi32/WinBase.cs @@ -402,7 +402,7 @@ namespace Vanara.PInvoke [return: MarshalAs(UnmanagedType.Bool)] [PInvokeData("Winbase.h", MSDNShortId = "aa446646")] public static extern bool GetPrivateObjectSecurity(SafeSecurityDescriptor ObjectDescriptor, SECURITY_INFORMATION SecurityInformation, - IntPtr ResultantDescriptor, uint DescriptorLength, out uint ReturnLength); + SafeSecurityDescriptor ResultantDescriptor, uint DescriptorLength, out uint ReturnLength); /// /// The GetSecurityDescriptorDacl function retrieves a pointer to the discretionary access control list (DACL) in a specified diff --git a/PInvoke/Security/AdvApi32/WinNT.cs b/PInvoke/Security/AdvApi32/WinNT.cs index cb3b101c..3f457810 100644 --- a/PInvoke/Security/AdvApi32/WinNT.cs +++ b/PInvoke/Security/AdvApi32/WinNT.cs @@ -1389,16 +1389,22 @@ namespace Vanara.PInvoke /// public class SafeSecurityDescriptor : GenericSafeHandle { + private static LocalMemoryMethods lmem = new LocalMemoryMethods(); + /// Initializes a new instance of the class. public SafeSecurityDescriptor() : this(IntPtr.Zero) { } /// Initializes a new instance of the class from an existing pointer. /// The security descriptor pointer. /// if set to true indicates that this pointer should be freed when disposed. - public SafeSecurityDescriptor(IntPtr pSecurityDescriptor, bool own = true) : base(pSecurityDescriptor, h => LocalFree(h) == IntPtr.Zero, own) { } + public SafeSecurityDescriptor(IntPtr pSecurityDescriptor, bool own = true) : base(pSecurityDescriptor, h => { lmem.FreeMem(h); return true; }, own) { } - [DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)] - private static extern IntPtr LocalFree(IntPtr hMem); + /// Initializes a new instance of the class to an empty memory buffer. + /// The size of the uninitialized security descriptor. + public SafeSecurityDescriptor(int size) : this(lmem.AllocMem(size), true) { } + + /// The null value for a SafeSecurityDescriptor. + public static readonly SafeSecurityDescriptor Null = new SafeSecurityDescriptor(); } } } \ No newline at end of file diff --git a/PInvoke/VirtDisk/VirtDisk.cs b/PInvoke/VirtDisk/VirtDisk.cs index 27b4eda6..934bb70c 100644 --- a/PInvoke/VirtDisk/VirtDisk.cs +++ b/PInvoke/VirtDisk/VirtDisk.cs @@ -790,7 +790,7 @@ namespace Vanara.PInvoke /// [DllImport(Lib.VirtDisk, ExactSpelling = true)] [PInvokeData("VirtDisk.h")] - public static extern Win32Error AttachVirtualDisk(SafeFileHandle VirtualDiskHandle, IntPtr SecurityDescriptor, ATTACH_VIRTUAL_DISK_FLAG Flags, uint ProviderSpecificFlags, ref ATTACH_VIRTUAL_DISK_PARAMETERS Parameters, [In] IntPtr Overlapped); + public static extern Win32Error AttachVirtualDisk(SafeFileHandle VirtualDiskHandle, SafeHandle SecurityDescriptor, ATTACH_VIRTUAL_DISK_FLAG Flags, uint ProviderSpecificFlags, ref ATTACH_VIRTUAL_DISK_PARAMETERS Parameters, [In] IntPtr Overlapped); /// Attaches a virtual hard disk (VHD) or CD or DVD image file (ISO) by locating an appropriate VHD provider to accomplish the attachment. /// A handle to an open virtual disk. For information on how to open a virtual disk, see the OpenVirtualDisk function. @@ -815,7 +815,7 @@ namespace Vanara.PInvoke /// [DllImport(Lib.VirtDisk, ExactSpelling = true)] [PInvokeData("VirtDisk.h")] - public static extern Win32Error AttachVirtualDisk(SafeFileHandle VirtualDiskHandle, IntPtr SecurityDescriptor, ATTACH_VIRTUAL_DISK_FLAG Flags, uint ProviderSpecificFlags, ref ATTACH_VIRTUAL_DISK_PARAMETERS Parameters, ref NativeOverlapped Overlapped); + public static extern Win32Error AttachVirtualDisk(SafeFileHandle VirtualDiskHandle, SafeHandle SecurityDescriptor, ATTACH_VIRTUAL_DISK_FLAG Flags, uint ProviderSpecificFlags, ref ATTACH_VIRTUAL_DISK_PARAMETERS Parameters, ref NativeOverlapped Overlapped); /// /// Breaks a previously initiated mirror operation and sets the mirror to be the active virtual disk. @@ -941,7 +941,7 @@ namespace Vanara.PInvoke /// [PInvokeData("VirtDisk.h")] [DllImport(Lib.VirtDisk, CharSet = CharSet.Unicode, ExactSpelling = true)] - public static extern Win32Error CreateVirtualDisk(ref VIRTUAL_STORAGE_TYPE VirtualStorageType, string Path, VIRTUAL_DISK_ACCESS_MASK VirtualDiskAccessMask, IntPtr SecurityDescriptor, CREATE_VIRTUAL_DISK_FLAG Flags, int ProviderSpecificFlags, ref CREATE_VIRTUAL_DISK_PARAMETERS Parameters, IntPtr Overlapped, out SafeFileHandle Handle); + public static extern Win32Error CreateVirtualDisk(ref VIRTUAL_STORAGE_TYPE VirtualStorageType, string Path, VIRTUAL_DISK_ACCESS_MASK VirtualDiskAccessMask, SafeHandle SecurityDescriptor, CREATE_VIRTUAL_DISK_FLAG Flags, int ProviderSpecificFlags, ref CREATE_VIRTUAL_DISK_PARAMETERS Parameters, IntPtr Overlapped, out SafeFileHandle Handle); /// Creates a virtual hard disk (VHD) image file, either using default parameters or using an existing VHD or physical disk. /// A pointer to a VIRTUAL_STORAGE_TYPE structure that contains the desired disk type and vendor information. @@ -962,7 +962,7 @@ namespace Vanara.PInvoke /// [PInvokeData("VirtDisk.h")] [DllImport(Lib.VirtDisk, CharSet = CharSet.Unicode, ExactSpelling = true)] - public static extern Win32Error CreateVirtualDisk(ref VIRTUAL_STORAGE_TYPE VirtualStorageType, string Path, VIRTUAL_DISK_ACCESS_MASK VirtualDiskAccessMask, IntPtr SecurityDescriptor, CREATE_VIRTUAL_DISK_FLAG Flags, int ProviderSpecificFlags, ref CREATE_VIRTUAL_DISK_PARAMETERS Parameters, ref NativeOverlapped Overlapped, out SafeFileHandle Handle); + public static extern Win32Error CreateVirtualDisk(ref VIRTUAL_STORAGE_TYPE VirtualStorageType, string Path, VIRTUAL_DISK_ACCESS_MASK VirtualDiskAccessMask, SafeHandle SecurityDescriptor, CREATE_VIRTUAL_DISK_FLAG Flags, int ProviderSpecificFlags, ref CREATE_VIRTUAL_DISK_PARAMETERS Parameters, ref NativeOverlapped Overlapped, out SafeFileHandle Handle); /// Deletes a snapshot from a VHD Set file. /// A handle to the open virtual disk. diff --git a/Security/AccessControl/AccCtrlHelper.cs b/Security/AccessControl/AccCtrlHelper.cs index c46b59e9..882bbb9a 100644 --- a/Security/AccessControl/AccCtrlHelper.cs +++ b/Security/AccessControl/AccCtrlHelper.cs @@ -38,6 +38,18 @@ namespace Vanara.Security.AccessControl } } + /// Enables access to managed as unmanaged . + public class PinnedSecurityDescriptor : PinnedObject + { + private readonly byte[] bytes; + + public PinnedSecurityDescriptor(ObjectSecurity sd) + { + bytes = sd.GetSecurityDescriptorBinaryForm(); + SetObject(bytes); + } + } + /// Helper methods for working with Access Control structures. public static class AccessControlHelper { @@ -60,7 +72,7 @@ namespace Vanara.Security.AccessControl public static uint GetAclSize(IntPtr pAcl) => GetAclInfo(pAcl).AclBytesInUse; - public static uint GetEffectiveRights(PSID pSid, IntPtr pSD) + public static uint GetEffectiveRights(this PSID pSid, SafeSecurityDescriptor pSD) { var t = new TRUSTEE(pSid); GetSecurityDescriptorDacl(pSD, out bool daclPresent, out IntPtr pDacl, out bool daclDefaulted); @@ -93,19 +105,15 @@ namespace Vanara.Security.AccessControl public static PSID GetPSID(this SecurityIdentifier sid) { using (var ps = new PinnedSid(sid)) return ps.PSID; } - public static IntPtr GetPrivateObjectSecurity(IntPtr pSD, SECURITY_INFORMATION si) + public static SafeSecurityDescriptor GetPrivateObjectSecurity(this SafeSecurityDescriptor pSD, SECURITY_INFORMATION si) { - var pResSD = IntPtr.Zero; - AdvApi32.GetPrivateObjectSecurity(pSD, si, IntPtr.Zero, 0, out uint ret); + var pResSD = SafeSecurityDescriptor.Null; + AdvApi32.GetPrivateObjectSecurity(pSD, si, pResSD, 0, out uint ret); if (ret > 0) { - pResSD = Marshal.AllocHGlobal((int)ret); - if (pResSD != IntPtr.Zero && !AdvApi32.GetPrivateObjectSecurity(pSD, si, pResSD, ret, out ret)) - { - Marshal.FreeHGlobal(pResSD); - pResSD = IntPtr.Zero; + pResSD = new SafeSecurityDescriptor((int)ret); + if (!pResSD.IsInvalid && !AdvApi32.GetPrivateObjectSecurity(pSD, si, pResSD, ret, out ret)) Win32Error.GetLastError().ThrowIfFailed(); - } } return pResSD; } @@ -118,6 +126,6 @@ namespace Vanara.Security.AccessControl return new RawAcl(dest, 0); } - public static string SecurityDescriptorPtrToSdll(IntPtr pSD, SECURITY_INFORMATION si) => ConvertSecurityDescriptorToStringSecurityDescriptor(pSD, SDDL_REVISION.SDDL_REVISION_1, si, out SafeHGlobalHandle ssd, out uint ssdLen) ? ssd.ToString(-1, CharSet.Auto) : null; + public static string ToSddl(this SafeSecurityDescriptor pSD, SECURITY_INFORMATION si) => ConvertSecurityDescriptorToStringSecurityDescriptor(pSD, SDDL_REVISION.SDDL_REVISION_1, si, out var ssd, out var _) ? ssd : null; } } \ No newline at end of file diff --git a/System/VirtualDisk.cs b/System/VirtualDisk.cs index cd96a543..46c87469 100644 --- a/System/VirtualDisk.cs +++ b/System/VirtualDisk.cs @@ -15,6 +15,7 @@ using System.Threading.Tasks; using Vanara.Extensions; using Vanara.InteropServices; using Vanara.PInvoke; +using static Vanara.PInvoke.AdvApi32; using static Vanara.PInvoke.VirtDisk; // ReSharper disable UnusedMember.Global // ReSharper disable MemberCanBePrivate.Global @@ -224,11 +225,11 @@ namespace Vanara.IO /// security descriptor will be used. /// /// If successful, returns a valid instance for the newly created virtual disk. - public static VirtualDisk Create(string path, ref CREATE_VIRTUAL_DISK_PARAMETERS param, CREATE_VIRTUAL_DISK_FLAG flags = CREATE_VIRTUAL_DISK_FLAG.CREATE_VIRTUAL_DISK_FLAG_NONE, VIRTUAL_DISK_ACCESS_MASK mask = VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_NONE, IntPtr securityDescriptor = default(IntPtr)) + public static VirtualDisk Create(string path, ref CREATE_VIRTUAL_DISK_PARAMETERS param, CREATE_VIRTUAL_DISK_FLAG flags = CREATE_VIRTUAL_DISK_FLAG.CREATE_VIRTUAL_DISK_FLAG_NONE, VIRTUAL_DISK_ACCESS_MASK mask = VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_NONE, SafeSecurityDescriptor securityDescriptor = null) { if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); var stType = new VIRTUAL_STORAGE_TYPE(); - CreateVirtualDisk(ref stType, path, mask, securityDescriptor, flags, 0, ref param, IntPtr.Zero, out SafeFileHandle handle).ThrowIfFailed(); + CreateVirtualDisk(ref stType, path, mask, securityDescriptor ?? SafeSecurityDescriptor.Null, flags, 0, ref param, IntPtr.Zero, out SafeFileHandle handle).ThrowIfFailed(); return new VirtualDisk(handle, (OPEN_VIRTUAL_DISK_VERSION)param.Version); } @@ -274,7 +275,7 @@ namespace Vanara.IO if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); var mask = IsPreWin8 ? VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_CREATE : VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_NONE; - var sd = new PinnedObject(access?.GetSecurityDescriptorBinaryForm()); + var sd = FileSecToSd(access); var param = new CREATE_VIRTUAL_DISK_PARAMETERS(size, IsPreWin8 ? 1U : 2U, blockSize, logicalSectorSize); var flags = dynamic ? CREATE_VIRTUAL_DISK_FLAG.CREATE_VIRTUAL_DISK_FLAG_NONE : CREATE_VIRTUAL_DISK_FLAG.CREATE_VIRTUAL_DISK_FLAG_FULL_PHYSICAL_ALLOCATION; return Create(path, ref param, flags, mask, sd); @@ -299,7 +300,7 @@ namespace Vanara.IO // If this is V2 (>=Win8), then let the file extension determine type, otherwise, it has to be a VHD var mask = IsPreWin8 ? VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_CREATE : VIRTUAL_DISK_ACCESS_MASK.VIRTUAL_DISK_ACCESS_NONE; - var sd = new PinnedObject(access?.GetSecurityDescriptorBinaryForm()); + var sd = FileSecToSd(access); var param = new CREATE_VIRTUAL_DISK_PARAMETERS { Version = IsPreWin8 ? CREATE_VIRTUAL_DISK_VERSION.CREATE_VIRTUAL_DISK_VERSION_1 : CREATE_VIRTUAL_DISK_VERSION.CREATE_VIRTUAL_DISK_VERSION_2 }; var pp = new SafeCoTaskMemString(parentPath); if (IsPreWin8) @@ -328,7 +329,7 @@ namespace Vanara.IO param.Version1.SourcePath = (IntPtr)sp; else param.Version2.SourcePath = (IntPtr)sp; - return Create(path, ref param, CREATE_VIRTUAL_DISK_FLAG.CREATE_VIRTUAL_DISK_FLAG_NONE, mask, IntPtr.Zero); + return Create(path, ref param, CREATE_VIRTUAL_DISK_FLAG.CREATE_VIRTUAL_DISK_FLAG_NONE, mask); } /// @@ -418,10 +419,10 @@ namespace Vanara.IO /// accesses the attached virtual disk: The Recycle Bin is corrupted. Do you want to empty the Recycle Bin for this drive? /// /// - public void Attach(ATTACH_VIRTUAL_DISK_FLAG flags, ref ATTACH_VIRTUAL_DISK_PARAMETERS param, IntPtr securityDescriptor = default(IntPtr)) + public void Attach(ATTACH_VIRTUAL_DISK_FLAG flags, ref ATTACH_VIRTUAL_DISK_PARAMETERS param, SafeSecurityDescriptor securityDescriptor) { - AdvApi32.ConvertSecurityDescriptorToStringSecurityDescriptor(securityDescriptor, AdvApi32.SDDL_REVISION.SDDL_REVISION_1, (SECURITY_INFORMATION)7, out SafeHGlobalHandle ssd, out uint _); - Debug.WriteLine($"AttachVD: flags={flags}; sddl={ssd.ToString(-1)}, param={param.Version},{param.Version1.Reserved}"); + AdvApi32.ConvertSecurityDescriptorToStringSecurityDescriptor(securityDescriptor, AdvApi32.SDDL_REVISION.SDDL_REVISION_1, (SECURITY_INFORMATION)7, out var ssd, out uint _); + Debug.WriteLine($"AttachVD: flags={flags}; sddl={ssd}, param={param.Version},{param.Version1.Reserved}"); AttachVirtualDisk(hVhd, securityDescriptor, flags, 0, ref param, IntPtr.Zero).ThrowIfFailed(); if (!flags.IsFlagSet(ATTACH_VIRTUAL_DISK_FLAG.ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME)) attached = true; } @@ -447,7 +448,7 @@ namespace Vanara.IO if (!autoDetach) flags |= ATTACH_VIRTUAL_DISK_FLAG.ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME; if (noDriveLetter) flags |= ATTACH_VIRTUAL_DISK_FLAG.ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER; var param = ATTACH_VIRTUAL_DISK_PARAMETERS.Default; - var sd = new PinnedObject(access?.GetSecurityDescriptorBinaryForm()); + var sd = FileSecToSd(access); Attach(flags, ref param, sd); } @@ -564,7 +565,7 @@ namespace Vanara.IO } var flags = CREATE_VIRTUAL_DISK_FLAG.CREATE_VIRTUAL_DISK_FLAG_NONE; - return CreateVirtualDisk(ref stType, path, mask, IntPtr.Zero, flags, 0, ref param, ref vhdOverlap, out hVhd); + return CreateVirtualDisk(ref stType, path, mask, SafeSecurityDescriptor.Null, flags, 0, ref param, ref vhdOverlap, out hVhd); } ); if (!b) throw new OperationCanceledException(cancellationToken); @@ -731,6 +732,14 @@ namespace Vanara.IO }*/ #endif + private static SafeSecurityDescriptor FileSecToSd(FileSecurity sec) + { + if (sec == null) return SafeSecurityDescriptor.Null; + if (ConvertStringSecurityDescriptorToSecurityDescriptor(sec.GetSecurityDescriptorSddlForm(AccessControlSections.All), SDDL_REVISION.SDDL_REVISION_1, out var sd, out var _)) + return sd; + throw Win32Error.GetLastError().GetException(); + } + private T GetInformation(GET_VIRTUAL_DISK_INFO_VERSION info, long offset = 0) { var sz = 32U; diff --git a/UnitTests/PInvoke/AdvApi32/AdvApi32Tests.cs b/UnitTests/PInvoke/AdvApi32/AdvApi32Tests.cs index 580e63d4..767dcf45 100644 --- a/UnitTests/PInvoke/AdvApi32/AdvApi32Tests.cs +++ b/UnitTests/PInvoke/AdvApi32/AdvApi32Tests.cs @@ -109,9 +109,8 @@ namespace Vanara.PInvoke.Tests { var pSD = GetSD(fn); var b = ConvertSecurityDescriptorToStringSecurityDescriptor(pSD, SDDL_REVISION.SDDL_REVISION_1, - SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, out SafeHGlobalHandle str, out uint len); + SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, out var s, out uint len); Assert.That(b, Is.True); - var s = str.ToString(-1, CharSet.Auto); Assert.That(s, Is.Not.Null); TestContext.WriteLine(s); } @@ -181,12 +180,8 @@ namespace Vanara.PInvoke.Tests { using (var pSD = GetSD(fn)) { - var b = GetPrivateObjectSecurity(pSD, SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION, IntPtr.Zero, 0, out uint rightSize); - Assert.That(rightSize, Is.GreaterThan(0)); - var sdo = new SafeHGlobalHandle((int)rightSize); - b = GetPrivateObjectSecurity(pSD, SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION, (IntPtr)sdo, (uint)sdo.Size, out rightSize); - Assert.That(b); - Assert.That(!sdo.IsInvalid); + var pos = pSD.GetPrivateObjectSecurity(SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION); + Assert.That(!pos.IsInvalid); } } diff --git a/UnitTests/System/VirtualDiskTests.cs b/UnitTests/System/VirtualDiskTests.cs index 9679c4bb..b8a8fad0 100644 --- a/UnitTests/System/VirtualDiskTests.cs +++ b/UnitTests/System/VirtualDiskTests.cs @@ -179,9 +179,9 @@ namespace Vanara.IO.Tests Assert.That(vhd.Attached, Is.False); var flags = ATTACH_VIRTUAL_DISK_FLAG.ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY; var aparam = ATTACH_VIRTUAL_DISK_PARAMETERS.Default; - if (!ConvertStringSecurityDescriptorToSecurityDescriptor("O:BAG:BAD:(A;;GA;;;WD)", SDDL_REVISION.SDDL_REVISION_1, out SafeHGlobalHandle sd, out uint hLen)) + if (!ConvertStringSecurityDescriptorToSecurityDescriptor("O:BAG:BAD:(A;;GA;;;WD)", SDDL_REVISION.SDDL_REVISION_1, out var sd, out uint hLen)) Win32Error.ThrowLastError(); - vhd.Attach(flags, ref aparam, (IntPtr)sd); + vhd.Attach(flags, ref aparam, sd); Assert.That(vhd.Attached, Is.True); vhd.Detach(); Assert.That(vhd.Attached, Is.False); diff --git a/WIndows.Forms/Dialogs/AccessControlEditor/Providers.cs b/WIndows.Forms/Dialogs/AccessControlEditor/Providers.cs index 2f27d76c..ec582c01 100644 --- a/WIndows.Forms/Dialogs/AccessControlEditor/Providers.cs +++ b/WIndows.Forms/Dialogs/AccessControlEditor/Providers.cs @@ -140,7 +140,8 @@ namespace Vanara.Security.AccessControl /// An array of access masks. public virtual uint[] GetEffectivePermission(PSID pUserSid, string serverName, IntPtr pSecurityDescriptor) { - var mask = GetEffectiveRights(pUserSid, pSecurityDescriptor); + var sd = new SafeSecurityDescriptor(pSecurityDescriptor, false); + var mask = pUserSid.GetEffectiveRights(sd); return new[] { mask }; } diff --git a/WIndows.Forms/Dialogs/AccessControlEditor/SecurityInfoImpl.cs b/WIndows.Forms/Dialogs/AccessControlEditor/SecurityInfoImpl.cs index bf92f2cb..c242776a 100644 --- a/WIndows.Forms/Dialogs/AccessControlEditor/SecurityInfoImpl.cs +++ b/WIndows.Forms/Dialogs/AccessControlEditor/SecurityInfoImpl.cs @@ -14,13 +14,15 @@ namespace Vanara.Security.AccessControl { internal class SecurityEventArg : EventArgs { - public SecurityEventArg(IntPtr sd, SECURITY_INFORMATION parts) + public SecurityEventArg(SafeSecurityDescriptor sd, SECURITY_INFORMATION parts) { Parts = parts; SecurityDesciptor = sd; } + public SECURITY_INFORMATION Parts { get; } - public IntPtr SecurityDesciptor { get; } + + public SafeSecurityDescriptor SecurityDesciptor { get; } } internal class SecurityInfoImpl : ISecurityInformation, ISecurityInformation3, ISecurityObjectTypeInfo, IEffectivePermission, ISecurityInformation4, IEffectivePermission2 @@ -91,9 +93,12 @@ namespace Vanara.Security.AccessControl void ISecurityInformation.GetSecurity(SECURITY_INFORMATION requestInformation, out IntPtr ppSecurityDescriptor, bool fDefault) { System.Diagnostics.Debug.WriteLine($"GetSecurity: {requestInformation}{(fDefault ? " (Def)" : "")}"); - ppSecurityDescriptor = GetPrivateObjectSecurity(fDefault ? prov.GetDefaultSecurity() : (IntPtr)pSD, requestInformation); + var sd = new SafeSecurityDescriptor(fDefault ? prov.GetDefaultSecurity() : (IntPtr)pSD, false); + var ret = sd.GetPrivateObjectSecurity(requestInformation); System.Diagnostics.Debug.WriteLine( - $"GetSecurity={SecurityDescriptorPtrToSdll(ppSecurityDescriptor, requestInformation) ?? "null"} <- {SecurityDescriptorPtrToSdll((IntPtr)pSD, requestInformation) ?? "null"}"); + $"GetSecurity={ret.ToSddl(requestInformation) ?? "null"} <- {sd.ToSddl(requestInformation) ?? "null"}"); + ppSecurityDescriptor = ret.DangerousGetHandle(); + ret.SetHandleAsInvalid(); } void ISecurityInformation.MapGeneric(Guid guidObjectType, ref sbyte AceFlags, ref uint Mask) @@ -114,7 +119,7 @@ namespace Vanara.Security.AccessControl void ISecurityInformation.SetSecurity(SECURITY_INFORMATION requestInformation, IntPtr sd) { - OnSetSecurity?.Invoke(this, new SecurityEventArg(sd, requestInformation)); + OnSetSecurity?.Invoke(this, new SecurityEventArg(new SafeSecurityDescriptor(sd, false), requestInformation)); } string ISecurityInformation3.GetFullResourceName() => fullObjectName; @@ -196,7 +201,7 @@ namespace Vanara.Security.AccessControl } if (sd != null) { - var sddl = SecurityDescriptorPtrToSdll(sd.SecurityDesciptor, sd.Parts); + var sddl = sd.SecurityDesciptor.ToSddl(sd.Parts); if (!string.IsNullOrEmpty(sddl)) { System.Diagnostics.Debug.WriteLine($"ShowDialog: Return: {sddl}");