1717// the original author James Forshaw to be used under the Apache License for this
1818// project.
1919
20+ using NtApiDotNet . Win32 ;
2021using System ;
2122using System . Drawing ;
23+ using System . Linq ;
24+ using System . Runtime . InteropServices ;
2225using System . Windows . Forms ;
2326
2427namespace NtApiDotNet . Forms
@@ -28,6 +31,13 @@ namespace NtApiDotNet.Forms
2831 /// </summary>
2932 public partial class AclViewerControl : UserControl
3033 {
34+ private Acl _acl ;
35+ private Type _access_type ;
36+ private GenericMapping _mapping ;
37+ private AccessMask _valid_access ;
38+ private Type _current_access_type ;
39+ private bool _read_only_checks ;
40+
3141 /// <summary>
3242 /// Constructor.
3343 /// </summary>
@@ -42,12 +52,18 @@ public AclViewerControl()
4252 /// <param name="acl">The ACL to view.</param>
4353 /// <param name="access_type">The enum type for the view.</param>
4454 /// <param name="mapping">Generic mapping for the type.</param>
45- /// <param name="unmap_mask">True to unmap mask into generic access rights .</param>
46- public void SetAcl ( Acl acl , Type access_type , GenericMapping mapping , bool unmap_mask )
55+ /// <param name="valid_access">The valid bit mask for access for this type .</param>
56+ public void SetAcl ( Acl acl , Type access_type , GenericMapping mapping , AccessMask valid_access )
4757 {
58+ _acl = acl ;
59+ _access_type = access_type ;
60+ _mapping = mapping ;
61+ _valid_access = valid_access ;
62+
4863 if ( ! acl . HasConditionalAce )
4964 {
5065 listViewAcl . Columns . Remove ( columnHeaderCondition ) ;
66+ copyConditionToolStripMenuItem . Visible = false ;
5167 }
5268
5369 foreach ( var ace in acl )
@@ -62,19 +78,19 @@ public void SetAcl(Acl acl, Type access_type, GenericMapping mapping, bool unmap
6278 else
6379 {
6480 AccessMask mapped_mask = mapping . MapMask ( ace . Mask ) ;
65- if ( unmap_mask )
66- {
67- mapped_mask = mapping . UnmapMask ( mapped_mask ) ;
68- }
81+ mapped_mask = mapping . UnmapMask ( mapped_mask ) ;
6982 access = mapped_mask . ToSpecificAccess ( access_type ) . ToString ( ) ;
7083 }
7184
7285 item . SubItems . Add ( access ) ;
86+ item . SubItems . Add ( ace . Flags . ToString ( ) ) ;
7387 if ( ace . IsConditionalAce )
7488 {
7589 item . SubItems . Add ( ace . Condition ) ;
7690 }
7791
92+ item . Tag = ace ;
93+
7894 switch ( ace . Type )
7995 {
8096 case AceType . Allowed :
@@ -100,5 +116,126 @@ public void SetAcl(Acl acl, Type access_type, GenericMapping mapping, bool unmap
100116 listViewAcl . AutoResizeColumns ( ColumnHeaderAutoResizeStyle . ColumnContent ) ;
101117 listViewAcl . AutoResizeColumns ( ColumnHeaderAutoResizeStyle . HeaderSize ) ;
102118 }
119+
120+ private Ace GetSelectedAce ( )
121+ {
122+ if ( _acl == null )
123+ {
124+ return null ;
125+ }
126+ if ( listViewAcl . SelectedItems . Count == 0 )
127+ {
128+ return null ;
129+ }
130+ return ( Ace ) listViewAcl . SelectedItems [ 0 ] . Tag ;
131+ }
132+
133+ private void listViewAcl_SelectedIndexChanged ( object sender , EventArgs e )
134+ {
135+ Ace ace = GetSelectedAce ( ) ;
136+ if ( ace == null )
137+ {
138+ return ;
139+ }
140+
141+ Type access_type = _access_type ;
142+ AccessMask valid_access = _valid_access ;
143+ AccessMask mapped_mask = _mapping . MapMask ( ace . Mask ) & _valid_access ;
144+
145+ if ( ace . Type == AceType . MandatoryLabel )
146+ {
147+ mapped_mask = ace . Mask ;
148+ access_type = typeof ( MandatoryLabelPolicy ) ;
149+ valid_access = 0x7 ;
150+ }
151+
152+ if ( access_type != _current_access_type )
153+ {
154+ _current_access_type = access_type ;
155+ ListViewItem [ ] items = Win32Utils . GetMaskDictionary ( access_type , valid_access ) . Select ( pair =>
156+ {
157+ ListViewItem item = new ListViewItem ( pair . Value ) ;
158+ item . SubItems . Add ( $ "0x{ pair . Key : X08} ") ;
159+ item . Tag = pair . Key ;
160+ return item ;
161+ }
162+ ) . ToArray ( ) ;
163+ listViewAccess . Items . Clear ( ) ;
164+ listViewAccess . Items . AddRange ( items ) ;
165+ listViewAccess . AutoResizeColumns ( ColumnHeaderAutoResizeStyle . ColumnContent ) ;
166+ listViewAccess . AutoResizeColumns ( ColumnHeaderAutoResizeStyle . HeaderSize ) ;
167+ }
168+
169+ _read_only_checks = false ;
170+ foreach ( ListViewItem item in listViewAccess . Items )
171+ {
172+ uint mask = ( uint ) item . Tag ;
173+ item . Checked = ( mapped_mask & mask ) != 0 ;
174+ }
175+ _read_only_checks = true ;
176+ }
177+
178+ private void listViewAccess_ItemCheck ( object sender , ItemCheckEventArgs e )
179+ {
180+ if ( _read_only_checks )
181+ {
182+ e . NewValue = e . CurrentValue ;
183+ }
184+ }
185+
186+ private static void CopyToClipboard ( string value )
187+ {
188+ try
189+ {
190+ Clipboard . SetText ( value ) ;
191+ }
192+ catch ( ExternalException )
193+ {
194+ }
195+ }
196+
197+ private void copySIDToolStripMenuItem_Click ( object sender , EventArgs e )
198+ {
199+ Ace ace = GetSelectedAce ( ) ;
200+ if ( ace == null )
201+ {
202+ return ;
203+ }
204+
205+ CopyToClipboard ( ace . Sid . ToString ( ) ) ;
206+ }
207+
208+ private void contextMenuStripAcl_Opening ( object sender , System . ComponentModel . CancelEventArgs e )
209+ {
210+ Ace ace = GetSelectedAce ( ) ;
211+ bool selected = ace != null ;
212+ copySIDToolStripMenuItem . Enabled = selected ;
213+ copyAccountToolStripMenuItem . Enabled = selected ;
214+ copyConditionToolStripMenuItem . Enabled = selected && ace . IsConditionalAce ;
215+ }
216+
217+ private void copyAccountToolStripMenuItem_Click ( object sender , EventArgs e )
218+ {
219+ Ace ace = GetSelectedAce ( ) ;
220+ if ( ace == null )
221+ {
222+ return ;
223+ }
224+
225+ CopyToClipboard ( ace . Sid . Name ) ;
226+ }
227+
228+ private void copyConditionToolStripMenuItem_Click ( object sender , EventArgs e )
229+ {
230+ Ace ace = GetSelectedAce ( ) ;
231+ if ( ace == null )
232+ {
233+ return ;
234+ }
235+ if ( ace . IsConditionalAce )
236+ {
237+ CopyToClipboard ( ace . Condition ) ;
238+ }
239+ }
103240 }
104241}
0 commit comments