Vanara/Windows.Forms/Dialogs/AccessControlEditor/AccessControlEditorDialog.cs

542 lines
29 KiB
C#

using System;
using System.ComponentModel;
using System.Security.AccessControl;
using System.Windows.Forms;
using Vanara.Security.AccessControl;
using static Vanara.PInvoke.AclUI;
using ResourceType = System.Security.AccessControl.ResourceType;
namespace Vanara.Windows.Forms
{
/// <summary>Values that indicate the types of property pages in an access control editor property sheet.</summary>
public enum SecurityPageType : uint
{
/// <summary>Permissions page.</summary>
BasicPermissions = 0,
/// <summary>Advanced page.</summary>
AdvancedPermissions,
/// <summary>Audit page.</summary>
Audit,
/// <summary>Owner page.</summary>
Owner,
/// <summary>Effective Rights page.</summary>
EffectiveRights,
/// <summary>Take Ownership page.</summary>
TakeOwnership,
/// <summary>Share page.</summary>
Share
}
/// <summary>
/// Displays a property sheet that contains a basic security property page. This property page enables the user to view and edit the access rights allowed or
/// denied by the ACEs in an object's DACL.
/// </summary>
[ToolboxItem(true), ToolboxItemFilter("System.Windows.Forms.Control.TopLevel")]
[Designer("System.ComponentModel.Design.ComponentDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
[DesignTimeVisible(true)]
[DefaultProperty("ObjectName"), Description("Displays a property sheet that contains a basic security property page.")]
[System.Drawing.ToolboxBitmap(typeof(AccessControlEditorDialog))]
public class AccessControlEditorDialog : CommonDialog
{
/// <summary>Pseudo type cast for a Task specific ResourceType.</summary>
public const ResourceType taskResourceType = (ResourceType)99;
private static SI_OBJECT_INFO_Flags defaultFlags = SI_OBJECT_INFO_Flags.SI_EDIT_ALL | SI_OBJECT_INFO_Flags.SI_ADVANCED | SI_OBJECT_INFO_Flags.SI_VIEW_ONLY;
private SI_OBJECT_INFO_Flags flags = defaultFlags;
private SecurityInfoImpl iSecInfo;
private string objectName, serverName, title;
/// <summary>Initializes a new instance of the <see cref="AccessControlEditorDialog"/> class.</summary>
public AccessControlEditorDialog()
{
if (System.Threading.Thread.CurrentThread.GetApartmentState() != System.Threading.ApartmentState.STA)
throw new InvalidOperationException("Current thread must be STA in order to use the AccessControlEditorDialog.");
}
/// <summary>
/// When set, this flag displays the Reset permissions on all child objects and enable propagation of inheritable permissions check box in the
/// Permissions page of the Access Control Settings window. This function does not reset the permissions and enable propagation of inheritable permissions.
/// </summary>
[DefaultValue(false), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Displays the Reset permissions on all child objects and enable propagation of inheritable permissions check box")]
public bool AllowDaclInheritanceReset
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_RESET_DACL_TREE); set => SetFlag(SI_OBJECT_INFO_Flags.SI_RESET_DACL_TREE, value, true);
}
/// <summary>
/// If this flag is set and the user clicks the Advanced button, the system displays an advanced security property sheet that includes an Auditing
/// property page for editing the object's SACL.
/// </summary>
[DefaultValue(true), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("On Advanced button, shows Audit page.")]
public bool AllowEditAudit
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_EDIT_AUDITS); set => SetFlag(SI_OBJECT_INFO_Flags.SI_EDIT_AUDITS, value, true);
}
/// <summary>
/// If this flag is set and the user clicks the Advanced button, the system displays an advanced security property sheet that includes an Owner property
/// page for changing the object's owner.
/// </summary>
[DefaultValue(true), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("On Advanced button, shows Owner page.")]
public bool AllowEditOwner
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_EDIT_OWNER); set => SetFlag(SI_OBJECT_INFO_Flags.SI_EDIT_OWNER, value, true);
}
/// <summary>
/// When set, this flag displays the Reset auditing entries on all child objects and enables propagation of the inheritable auditing entries check box in
/// the Auditing page of the Access Control Settings window. This function does not reset the permissions and enable propagation of inheritable permissions.
/// </summary>
[DefaultValue(false), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Displays the Reset auditing entries on all child objects and enables propagation of the inheritable auditing entries check box.")]
public bool AllowSaclInheritanceReset
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_RESET_SACL_TREE); set => SetFlag(SI_OBJECT_INFO_Flags.SI_RESET_SACL_TREE, value, true);
}
/// <summary>When set, this flag displays a shield on the Edit button of the advanced Auditing pages.</summary>
[DefaultValue(false), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Displays a shield on the Edit button of the advanced Auditing pages.")]
public bool AuditElevationRequired
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_AUDITS_ELEVATION_REQUIRED); set => SetFlag(SI_OBJECT_INFO_Flags.SI_AUDITS_ELEVATION_REQUIRED, value, true);
}
/// <summary>
/// If this flag is set, the Title property value is used as the title of the basic security property page. Otherwise, a default title is used.
/// </summary>
[DefaultValue(false), Browsable(false), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Title property value is used as the title of the basic security property page.")]
public bool CustomPageTitle
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_PAGE_TITLE); private set => SetFlag(SI_OBJECT_INFO_Flags.SI_PAGE_TITLE, value);
}
/// <summary>
/// If this flag is set, the access control editor hides the check box that controls the NO_PROPAGATE_INHERIT_ACE flag. This flag is relevant only when
/// the Advanced flag is also set.
/// </summary>
[DefaultValue(false), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Hides the check box that controls the NO_PROPAGATE_INHERIT_ACE flag")]
public bool DisallowInheritance
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_NO_TREE_APPLY); set { SetFlag(SI_OBJECT_INFO_Flags.SI_NO_TREE_APPLY, value, true); if (value) ShowAdvancedButton = true; }
}
/// <summary>
/// If this flag is set, the access control editor hides the check box that allows inheritable ACEs to propagate from the parent object to this object.
/// If this flag is not set, the check box is visible. The check box is clear if the SE_DACL_PROTECTED flag is set in the object's security descriptor.
/// In this case, the object's DACL is protected from being modified by inheritable ACEs. If the user clears the check box, any inherited ACEs in the
/// security descriptor are deleted or converted to non-inherited ACEs. Before proceeding with this conversion, the system displays a warning message box
/// to confirm the change.
/// </summary>
[DefaultValue(false), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Display of check box that allows inheritable ACEs to propagate from the parent object to this object.")]
public bool DisallowProtectedAcls
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_NO_ACL_PROTECT); set => SetFlag(SI_OBJECT_INFO_Flags.SI_NO_ACL_PROTECT, value);
}
/// <summary>
/// If this flag is set, the system enables controls for editing ACEs that apply to the object's property sets and properties. These controls are
/// available only on the property sheet displayed when the user clicks the Advanced button.
/// </summary>
[DefaultValue(false), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Enables controls for editing ACEs that apply to the object's property sets and properties.")]
public bool EditProperties
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_EDIT_PROPERTIES); set { SetFlag(SI_OBJECT_INFO_Flags.SI_EDIT_PROPERTIES, value, true); if (value) ShowAdvancedButton = true; }
}
/// <summary>When set, this flag displays a shield on the Edit button of the simple and advanced Permissions pages.</summary>
[DefaultValue(false), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Displays a shield on the Edit button of the simple and advanced Permissions pages.")]
public bool ElevationRequired
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_PERMS_ELEVATION_REQUIRED); set => SetFlag(SI_OBJECT_INFO_Flags.SI_PERMS_ELEVATION_REQUIRED, value, true);
}
/// <summary>Gets or sets the flags.</summary>
/// <value>The flags.</value>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public SI_OBJECT_INFO_Flags Flags
{
get => flags; set { flags = value; if (iSecInfo != null) iSecInfo.objectInfo.dwFlags = value; }
}
/// <summary>If this flag is set, the access control editor hides the Special Permissions tab on the Advanced Security Settings page.</summary>
[DefaultValue(false), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Hides the Special Permissions tab on the Advanced Security Settings page.")]
public bool HideSpecialPermissionTab
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_NO_ADDITIONAL_PERMISSION); set => SetFlag(SI_OBJECT_INFO_Flags.SI_NO_ADDITIONAL_PERMISSION, value, true);
}
/// <summary>Indicates that the access control editor cannot read the DACL but might be able to write to the DACL.</summary>
[DefaultValue(false), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Editor cannot read the DACL but might be able to write to the DACL.")]
public bool MayWrite
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_MAY_WRITE); set => SetFlag(SI_OBJECT_INFO_Flags.SI_MAY_WRITE, value);
}
/// <summary>
/// When set, indicates that the ObjectGuid property is valid. This is set in comparisons with object-specific ACEs in determining whether the ACE
/// applies to the current object.
/// </summary>
[DefaultValue(false), Browsable(false), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Indicates that the ObjectGuid property is valid")]
public bool ObjectGuid
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_OBJECT_GUID); private set => SetFlag(SI_OBJECT_INFO_Flags.SI_OBJECT_GUID, value);
}
/// <summary>
/// Indicates that the object is a container. If this flag is set, the access control editor enables the controls relevant to the inheritance of
/// permissions onto child objects.
/// </summary>
[DefaultValue(false), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Indicates that the object is a container.")]
public bool ObjectIsContainer
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_CONTAINER); set => SetFlag(SI_OBJECT_INFO_Flags.SI_CONTAINER, value);
}
/// <summary>Gets or sets the name of the object. If the <see cref="Initialize(object)"/> method is used, it will overwrite this value. If not, then the control will attempt to get the security information for this object based on the type specified by <see cref="ResourceType"/>.</summary>
[DefaultValue(null), Category("Data")]
[Description("The full name of the object.")]
public string ObjectName
{
get => objectName; set
{
objectName = value;
if (iSecInfo != null)
iSecInfo.objectInfo.pszObjectName = value;
}
}
/// <summary>
/// When set, this flag displays a shield on the Edit button of the advanced Owner page.
/// </summary>
[DefaultValue(false), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Displays a shield on the Edit button of the advanced Owner page.")]
public bool OwnerElevationRequired
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_OWNER_ELEVATION_REQUIRED); set => SetFlag(SI_OBJECT_INFO_Flags.SI_OWNER_ELEVATION_REQUIRED, value, true);
}
/// <summary>
/// If this flag is set, the user cannot change the owner of the object. Set this flag if EditOwner is set but the user does not have permission to
/// change the owner.
/// </summary>
[DefaultValue(false), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("User cannot change the owner of the object.")]
public bool OwnerReadOnly
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_OWNER_READONLY); set { var opt = value ? SI_OBJECT_INFO_Flags.SI_OWNER_READONLY | SI_OBJECT_INFO_Flags.SI_EDIT_OWNER : SI_OBJECT_INFO_Flags.SI_OWNER_READONLY; SetFlag(opt, value, true); }
}
/// <summary>
/// Combine this flag with Container to display a check box on the owner page that indicates whether the user intends the new owner to be applied to all
/// child objects as well as the current object. The access control editor does not perform the recursion.
/// </summary>
[DefaultValue(false), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Display a check box on the owner page that indicates whether the user intends the new owner to be applied to all child objects as well as the current object.")]
public bool OwnerRecurse
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_OWNER_RECURSE); set => SetFlag(SI_OBJECT_INFO_Flags.SI_OWNER_RECURSE, value, true);
}
/// <summary>Gets or sets the type of the page to display.</summary>
/// <value>The type of the page.</value>
[DefaultValue(typeof(SecurityPageType), "BasicPermissions"), Category("Behavior")]
[Description("The type of the page to display.")]
public SecurityPageType PageType { get; set; } = SecurityPageType.BasicPermissions;
/// <summary>
/// If this flag is set, the editor displays the object's security information, but the controls for editing the information are disabled. This flag
/// cannot be combined with the ViewOnly flag.
/// </summary>
[DefaultValue(false), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Disables controls for editing the information.")]
public bool ReadOnly
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_READONLY); set { if (value) SetFlag(SI_OBJECT_INFO_Flags.SI_VIEW_ONLY, false); SetFlag(SI_OBJECT_INFO_Flags.SI_READONLY, value); }
}
/// <summary>Gets or sets the resource type of the object. If the <see cref="Initialize(object)"/> method is used, it will overwrite this value. If not, then the control will attempt to get the security information for this object based on the type specified by <see cref="ObjectName"/>.</summary>
/// <value>The type of the resource.</value>
[DefaultValue(ResourceType.Unknown), Category("Data")]
[Description("The resource type of the object.")]
public ResourceType ResourceType { get; set; } = ResourceType.Unknown;
/// <summary>Gets the resulting Security Descriptor.</summary>
/// <value>The resulting Security Descriptor.</value>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public RawSecurityDescriptor Result { get; private set; }
/// <summary>Gets the resulting Security Descriptor in SDDL form.</summary>
/// <value>The resulting Security Descriptor in SDDL form.</value>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string Sddl => Result.GetSddlForm(AccessControlSections.All);
/// <summary>
/// Set this flag if the computer defined by the ServerName property is known to be a domain controller. If this flag is set, the domain name is included
/// in the scope list of the Add Users and Groups dialog box. Otherwise, the pszServerName computer is used to determine the scope list of the dialog box.
/// </summary>
[DefaultValue(false), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Computer defined by the ServerName property is known to be a domain controller.")]
public bool ServerIsDC
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_SERVER_IS_DC); set => SetFlag(SI_OBJECT_INFO_Flags.SI_SERVER_IS_DC, value);
}
/// <summary>Gets or sets the name of the server on which the object resides. A <c>null</c> value indicates the local machine.</summary>
/// <value>The name of the server.</value>
[DefaultValue(null), Category("Data")]
[Description("Name of the server on which the object resides.")]
public string ServerName
{
get => serverName; set { serverName = value; if (iSecInfo != null) iSecInfo.objectInfo.pszServerName = value; }
}
/// <summary>
/// Determines if the Advanced button is displayed on the basic security property page. If the user clicks this button, the system displays an advanced
/// security property sheet that enables advanced editing of the discretionary access control list (DACL) of the object.
/// </summary>
[DefaultValue(true), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Displays Advanced button on the basic security property page.")]
public bool ShowAdvancedButton
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_ADVANCED); set { SetFlag(SI_OBJECT_INFO_Flags.SI_ADVANCED, value); if (value && PageType == SecurityPageType.BasicPermissions) SetFlag(SI_OBJECT_INFO_Flags.SI_VIEW_ONLY, true); }
}
/// <summary>When set, this flag displays the Reset Defaults button on the Auditing page.</summary>
[DefaultValue(false), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Displays the Reset Defaults button on the Auditing page.")]
public bool ShowAuditingResetButton
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_RESET_SACL); set => SetFlag(SI_OBJECT_INFO_Flags.SI_RESET_SACL, value, true);
}
/// <summary>
/// If this flag is set, the Default button is displayed. If the user clicks this button, the access control editor calls the
/// IAccessControlEditorDialogProvider.DefaultSecurity to retrieve an application-defined default security descriptor. The access control editor uses
/// this security descriptor to reinitialize the property sheet, and the user is allowed to apply the change or cancel.
/// </summary>
[DefaultValue(false), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Displays the Default button.")]
public bool ShowDefaultButton
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_RESET); set => SetFlag(SI_OBJECT_INFO_Flags.SI_RESET, value, true);
}
/// <summary>If this flag is set, the Effective Permissions page is displayed.</summary>
[DefaultValue(false), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Displays the Effective Permissions page.")]
public bool ShowEffectivePermissionsPage
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_EDIT_EFFECTIVE); set => SetFlag(SI_OBJECT_INFO_Flags.SI_EDIT_EFFECTIVE, value, true);
}
/// <summary>When set, this flag displays the Reset Defaults button on the Owner page.</summary>
[DefaultValue(false), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Displays the Reset Defaults button on the Owner page.")]
public bool ShowOwnerResetButton
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_RESET_OWNER); set => SetFlag(SI_OBJECT_INFO_Flags.SI_RESET_OWNER, value, true);
}
/// <summary>When set, this flag displays the Reset Defaults button on the Permissions page.</summary>
[DefaultValue(false), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Displays the Reset Defaults button on the Permissions page.")]
public bool ShowPermissionsResetButton
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_RESET_DACL); set => SetFlag(SI_OBJECT_INFO_Flags.SI_RESET_DACL, value, true);
}
/// <summary>Gets or sets the title of the property page tab. If this value is not set, a default will be used.</summary>
/// <value>The title.</value>
[DefaultValue(null), Category("Appearance")]
[Description("Title of the property page tab.")]
public string TabTitle
{
get => title; set { title = value; if (iSecInfo != null) iSecInfo.objectInfo.pszPageTitle = value; CustomPageTitle = !string.IsNullOrEmpty(value); }
}
/// <summary>
/// If this flag is set, the editor displays the object's security information, but the controls for editing the information are disabled. This flag
/// cannot be combined with the EditOnly flag.
/// </summary>
[DefaultValue(true), Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Displays the object's security information, but the controls for editing the information are disabled.")]
public bool ViewOnly
{
get => HasFlag(SI_OBJECT_INFO_Flags.SI_VIEW_ONLY); set { if (value) SetFlag(SI_OBJECT_INFO_Flags.SI_READONLY, false); SetFlag(SI_OBJECT_INFO_Flags.SI_VIEW_ONLY, value); }
}
/// <summary>Initializes the dialog with the specified known object.</summary>
/// <param name="knownObject">The known object. See Remarks section for acceptable object types.</param>
/// <remarks>
/// Known objects can include:
/// <list type="bullet">
/// <item><description>System.IO.Pipes.PipeStream</description></item>
/// <item><description><see cref="System.Threading.EventWaitHandle"/></description></item>
/// <item><description><see cref="System.IO.DirectoryInfo"/></description></item>
/// <item><description><see cref="System.IO.FileInfo"/></description></item>
/// <item><description><see cref="System.IO.FileStream"/></description></item>
/// <item><description><see cref="System.Threading.Mutex"/></description></item>
/// <item><description>System.Win32.RegistryKey</description></item>
/// <item><description><see cref="System.Threading.Semaphore"/></description></item>
/// <item><description>System.IO.MemoryMappedFiles.MemoryMappedFile</description></item>
/// <item><description><see cref="System.Security.AccessControl.CommonObjectSecurity"/> or derived class. <c>Note:</c> When using this option, be sure to
/// set the <see cref="ObjectIsContainer"/>, <see cref="ResourceType"/>, <see cref="ObjectName"/>, and <see cref="ServerName"/> properties.</description></item>
/// <item><description>Any object that supports the following methods and properties:
/// <list type="bullet"><item><description><code>GetAccessControl()</code> or <code>GetAccessControl(AccessControlSections)</code> method</description></item>
/// <item><description><code>SetAccessControl(CommonObjectSecurity)</code> method</description></item>
/// <item><description><code>Name</code> or <code>FullName</code> property</description></item>
/// </list>
/// </description></item>
/// </list>
/// </remarks>
public void Initialize(object knownObject) => Initialize(new SecuredObject(knownObject));
/// <summary>Initializes the dialog with the specified <see cref="CommonObjectSecurity"/> value and names.</summary>
/// <param name="objSecurity">The object security.</param>
/// <param name="objName">Name of the object.</param>
/// <param name="displayName">The display name.</param>
public void Initialize(CommonObjectSecurity objSecurity, string objName, string displayName) => Initialize(new SecuredObject(objSecurity, objName, displayName));
private void Initialize(SecuredObject secObject)
{
Initialize(secObject.DisplayName, secObject.ObjectName, secObject.IsContainer, ProviderFromResourceType(secObject.ResourceType),
secObject.ObjectSecurity.GetSecurityDescriptorBinaryForm(), secObject.TargetServer);
ResourceType = secObject.ResourceType;
}
/// <summary>Initializes the dialog with the specified known object.</summary>
/// <param name="fullObjectName">Full name of the object.</param>
/// <param name="server">Name of the server. This value can be <c>null</c>.</param>
/// <param name="resourceType">Type of the object resource.</param>
/// <exception cref="System.ArgumentException">Unable to create an object from supplied arguments.</exception>
public void Initialize(string fullObjectName, string server, ResourceType resourceType) => Initialize(SecuredObject.GetKnownObject(resourceType, fullObjectName, server));
/// <summary>Initializes the dialog with a custom provider.</summary>
/// <param name="displayName">The object name.</param>
/// <param name="fullObjectName">Full name of the object.</param>
/// <param name="isContainer">Set to <c>true</c> if object is a container.</param>
/// <param name="customProvider">The custom provider.</param>
/// <param name="sd">The binary Security Descriptor.</param>
/// <param name="targetServer">The target server.</param>
public void Initialize(string displayName, string fullObjectName, bool isContainer, IAccessControlEditorDialogProvider customProvider, byte[] sd, string targetServer = null)
{
if (isContainer)
ObjectIsContainer = true;
iSecInfo = new SecurityInfoImpl(flags, displayName, fullObjectName, targetServer);
ResourceType = ResourceType.Unknown;
if (sd != null)
{
Result = new RawSecurityDescriptor(sd, 0);
iSecInfo.SecurityDescriptor = sd;
}
else
{
Result = new RawSecurityDescriptor("");
iSecInfo.SecurityDescriptor = new byte[20];
}
iSecInfo.SetProvider(customProvider);
}
/// <summary>Initializes the dialog with a known resource type.</summary>
/// <param name="displayName">The display name.</param>
/// <param name="fullName">The full name.</param>
/// <param name="isContainer">if set to <c>true</c> [is container].</param>
/// <param name="resourceType">Type of the resource.</param>
/// <param name="sd">The raw security descriptor.</param>
/// <param name="targetServer">The target server.</param>
public void Initialize(string displayName, string fullName, bool isContainer, ResourceType resourceType, byte[] sd, string targetServer = null)
{
Initialize(displayName, fullName, isContainer, ProviderFromResourceType(resourceType), sd, targetServer);
ResourceType = resourceType;
}
/// <summary>When overridden in a derived class, resets the properties of a common dialog box to their default values.</summary>
/// <exception cref="System.InvalidOperationException">
/// AccessControlEditorDialog cannot be reset. It must be instantiated with a valid securable object.
/// </exception>
public override void Reset() => throw new InvalidOperationException("AccessControlEditorDialog cannot be reset. It must be instantiated with a valid securable object.");
internal void ResetFlags() => flags = defaultFlags;
internal bool ShouldSerializeFlags() => flags != defaultFlags;
/// <summary>Runs the dialog.</summary>
/// <param name="hWndOwner">The h WND owner.</param>
/// <returns></returns>
/// <exception cref="System.InvalidOperationException">The Initialize method must be called before the dialog can be shown.</exception>
protected override bool RunDialog(IntPtr hWndOwner)
{
if (iSecInfo == null && !string.IsNullOrEmpty(ObjectName) && ResourceType != ResourceType.Unknown)
Initialize(ObjectName, ServerName, ResourceType);
if (iSecInfo == null)
throw new InvalidOperationException("The Initialize method must be called before the dialog can be shown.");
var ret = iSecInfo.ShowDialog(hWndOwner, (SI_PAGE_TYPE)(uint)PageType);
if (ret != null) Result = ret;
return ret != null;
}
private bool HasFlag(SI_OBJECT_INFO_Flags flag) => (Flags & flag) == flag;
private IAccessControlEditorDialogProvider ProviderFromResourceType(ResourceType resType)
{
IAccessControlEditorDialogProvider prov;
switch (resType)
{
case ResourceType.FileObject:
prov = new FileProvider();
break;
case ResourceType.KernelObject:
prov = new KernelProvider();
break;
case ResourceType.RegistryKey:
prov = new RegistryProvider();
break;
case taskResourceType:
prov = new TaskProvider();
break;
default:
prov = new GenericProvider();
break;
}
return prov;
}
private void SetFlag(SI_OBJECT_INFO_Flags flag, bool set, bool reqAdvanced = false)
{
if (set)
{
if (reqAdvanced)
flag |= SI_OBJECT_INFO_Flags.SI_ADVANCED;
Flags |= flag;
}
else
Flags &= ~flag;
}
}
}