diff --git a/PolicyPlus/EditSetting.vb b/PolicyPlus/EditSetting.vb index f98380a..66ce54a 100644 --- a/PolicyPlus/EditSetting.vb +++ b/PolicyPlus/EditSetting.vb @@ -2,7 +2,9 @@ Public CurrentSetting As PolicyPlusPolicy Public CurrentSection As AdmxPolicySection Public AdmxWorkspace As AdmxBundle + Public CompPolSource, UserPolSource As IPolicySource Dim ElementControls As Dictionary(Of String, Control) + Dim CurrentSource As IPolicySource Private Sub CancelButton_Click(sender As Object, e As EventArgs) Handles CancelButton.Click Close() End Sub @@ -17,8 +19,8 @@ SectionDropdown.Enabled = False CurrentSection = CurrentSetting.RawPolicy.Section End If - SectionDropdown.Text = IIf(CurrentSection = AdmxPolicySection.Machine, "Computer", "User") PreparePolicyElements() + SectionDropdown.Text = IIf(CurrentSection = AdmxPolicySection.Machine, "Computer", "User") PreparePolicyState() End Sub Sub PreparePolicyElements() @@ -150,7 +152,37 @@ End If End Sub Sub PreparePolicyState() - + Select Case PolicyProcessing.GetPolicyState(CurrentSource, CurrentSetting) + Case PolicyState.Disabled + DisabledOption.Checked = True + Case PolicyState.Enabled + EnabledOption.Checked = True + Dim optionStates = PolicyProcessing.GetPolicyOptionStates(CurrentSource, CurrentSetting) + For Each kv In optionStates + Dim uiControl As Control = ElementControls(kv.Key) + If TypeOf kv.Value Is UInteger Then ' Numeric box + If TypeOf uiControl Is TextBox Then + CType(uiControl, TextBox).Text = kv.Value.ToString + Else + CType(uiControl, NumericUpDown).Value = kv.Value + End If + ElseIf TypeOf kv.Value Is String Then ' Text box or combo box + If TypeOf uiControl Is ComboBox Then + CType(uiControl, ComboBox).Text = kv.Value + Else + CType(uiControl, TextBox).Text = kv.Value + End If + ElseIf TypeOf kv.Value Is Integer Then ' Dropdown list + CType(uiControl, ComboBox).SelectedIndex = kv.Value + ElseIf TypeOf kv.Value Is Boolean Then ' Check box + CType(uiControl, CheckBox).Checked = kv.Value + Else ' List box (pop-out button) + uiControl.Tag = kv.Value + End If + Next + Case Else + NotConfiguredOption.Checked = True + End Select End Sub Private Sub StateRadiosChanged(sender As Object, e As EventArgs) Handles DisabledOption.CheckedChanged, EnabledOption.CheckedChanged, NotConfiguredOption.CheckedChanged Dim allowOptions = EnabledOption.Checked @@ -158,6 +190,10 @@ kv.Value.Enabled = allowOptions Next End Sub + Private Sub SectionDropdown_SelectedIndexChanged(sender As Object, e As EventArgs) Handles SectionDropdown.SelectedIndexChanged + CurrentSource = IIf(SectionDropdown.Text = "User", UserPolSource, CompPolSource) + PreparePolicyState() + End Sub Private Class DropdownPresentationMap Public ID As Integer Public DisplayName As String diff --git a/PolicyPlus/Main.vb b/PolicyPlus/Main.vb index 07922c3..ffa4592 100644 --- a/PolicyPlus/Main.vb +++ b/PolicyPlus/Main.vb @@ -167,6 +167,8 @@ EditSetting.CurrentSetting = Policy EditSetting.CurrentSection = Section EditSetting.AdmxWorkspace = AdmxWorkspace + EditSetting.CompPolSource = CompPolicySource + EditSetting.UserPolSource = UserPolicySource If EditSetting.ShowDialog() = DialogResult.OK Then UpdateCategoryListing() End Sub Sub ClearSelections() diff --git a/PolicyPlus/PolicyProcessing.vb b/PolicyPlus/PolicyProcessing.vb index e54bbee..a159e96 100644 --- a/PolicyPlus/PolicyProcessing.vb +++ b/PolicyPlus/PolicyProcessing.vb @@ -66,6 +66,13 @@ Throw New InvalidOperationException("Illegal value type") End Select End Function + Private Shared Function ValueListPresent(ValueList As PolicyRegistrySingleList, Source As IPolicySource, Key As String, ValueName As String) As Boolean + Dim sublistKey = IIf(ValueList.DefaultRegistryKey = "", Key, ValueList.DefaultRegistryKey) + Return ValueList.AffectedValues.All(Function(e) + Dim entryKey = IIf(e.RegistryKey = "", sublistKey, e.RegistryKey) + Return ValuePresent(e.Value, Source, entryKey, e.RegistryValue) + End Function) + End Function Public Shared Function DeduplicatePolicies(Workspace As AdmxBundle) As Integer Dim dedupeCount = 0 For Each cat In Workspace.Policies.GroupBy(Function(c) c.Value.Category) @@ -84,6 +91,74 @@ Next Return dedupeCount End Function + Public Shared Function GetPolicyOptionStates(PolicySource As IPolicySource, Policy As PolicyPlusPolicy) As Dictionary(Of String, Object) + Dim state As New Dictionary(Of String, Object) + If Policy.RawPolicy.Elements Is Nothing Then Return state + For Each elem In Policy.RawPolicy.Elements + Dim elemKey = IIf(elem.RegistryKey = "", Policy.RawPolicy.RegistryKey, elem.RegistryKey) + Select Case elem.ElementType + Case "decimal" + state.Add(elem.ID, PolicySource.GetValue(elemKey, elem.RegistryValue)) + Case "boolean" + Dim booleanElem As BooleanPolicyElement = elem + state.Add(elem.ID, GetRegistryListState(PolicySource, booleanElem.AffectedRegistry, elemKey, elem.RegistryValue)) + Case "text" + state.Add(elem.ID, PolicySource.GetValue(elemKey, elem.RegistryValue)) + Case "list" + Dim listElem As ListPolicyElement = elem + If listElem.UserProvidesNames Then + Dim entries As New Dictionary(Of String, String) + For Each value In PolicySource.GetValueNames(elemKey) + entries.Add(value, PolicySource.GetValue(elemKey, value)) + Next + state.Add(elem.ID, entries) + Else + Dim entries As New List(Of String) + If listElem.HasPrefix Then + Dim n As Integer = 1 + Do While PolicySource.ContainsValue(elemKey, elem.RegistryValue & n) + entries.Add(PolicySource.GetValue(elemKey, elem.RegistryValue & n)) + Loop + Else + For Each value In PolicySource.GetValueNames(elem.RegistryKey) + entries.Add(value) + Next + End If + state.Add(elem.ID, entries) + End If + Case "enum" + Dim enumElem As EnumPolicyElement = elem + Dim selectedIndex As Integer = -1 + For n = 0 To enumElem.Items.Count - 1 + Dim enumItem = enumElem.Items(n) + If ValuePresent(enumItem.Value, PolicySource, elemKey, elem.RegistryValue) Then + If enumItem.ValueList Is Nothing OrElse ValueListPresent(enumItem.ValueList, PolicySource, elemKey, elem.RegistryValue) Then + selectedIndex = n + Exit For + End If + End If + Next + state.Add(elem.ID, selectedIndex) + End Select + Next + Return state + End Function + Private Shared Function GetRegistryListState(PolicySource As IPolicySource, RegList As PolicyRegistryList, DefaultKey As String, DefaultValueName As String) As Boolean + Dim isListAllPresent = Function(l As PolicyRegistrySingleList) ValueListPresent(l, PolicySource, DefaultKey, DefaultValueName) + If RegList.OnValue IsNot Nothing Then + If ValuePresent(RegList.OnValue, PolicySource, DefaultKey, DefaultValueName) Then Return True + ElseIf RegList.OnValueList IsNot Nothing Then + If isListAllPresent(RegList.OnValueList) Then Return True + Else + If PolicySource.GetValue(DefaultKey, DefaultValueName) = 1UI Then Return True + End If + If RegList.OffValue IsNot Nothing Then + If ValuePresent(RegList.OffValue, PolicySource, DefaultKey, DefaultValueName) Then Return False + ElseIf RegList.OffValueList IsNot Nothing Then + If isListAllPresent(RegList.OffValueList) Then Return False + End If + Return False + End Function End Class Public Enum PolicyState NotConfigured = 0 diff --git a/PolicyPlus/PolicySource.vb b/PolicyPlus/PolicySource.vb index 0056baa..4cb2a1b 100644 --- a/PolicyPlus/PolicySource.vb +++ b/PolicyPlus/PolicySource.vb @@ -128,7 +128,7 @@ Public Class PolFile Dim prefix = GetDictKey(Key, "") Dim valNames As New List(Of String) For Each k In Entries.Keys - If k.StartsWith(prefix) Then valNames.Add(k) + If k.StartsWith(prefix) Then valNames.Add(Split(k, "\\", 2)(1)) Next Return valNames End Function