diff --git a/Docs/Components.md b/Docs/Components.md index 5a25f25..e7c6aca 100644 --- a/Docs/Components.md +++ b/Docs/Components.md @@ -6,6 +6,7 @@ This list shows which code files are responsible for which parts of Policy Plus' * `AdmxBundle.vb`: Defines the `AdmxBundle` class, which represents a policy workspace. Information is taken out of multiple `AdmxFile` and `AdmlFile` instances and processed to discover properties of and relationships between policy objects. Bundle objects serve as links between ADMX data and ADML data, providing methods to resolve text from a language-neutral identifier. Also defines the `AdmxLoadFailType` enumeration and `AdmxLoadFailure` class, which represent problems encountered while trying to add ADMX files to the bundle. * `AdmxFile.vb`: Defines the `AdmxFile` class, which represents an administrative template's policy objects: categories, policies, products, and support definitions. That information is loaded from ADMX files parsed as XML. All text in these files is language-neutral; the ADML files provide the human-readable strings. * `AdmxStructures.vb`: Defines several classes used to hold information extracted from ADMX files. Since ADMX files rarely make sense on their own, these classes have minimal interconnectedness. Rather, string fields hold the IDs of referenced policy objects. +* `BitReinterpretation.vb`: Defines explicit-layout structures used to reinterpret signed integers/longs as unsigned or vice versa so that large unsigned values can be read or written from the Registry using the standard `RegistryKey` class. * `CmtxFile.vb`: Defines the `CmtxFile` class, which represents a comments file, which holds the user's annotations on policy settings. Information can be loaded from and saved to a CMTX file (XML format). For ease of use, the class also provides methods for translating policy-ID-to-comment mappings to `CmtxFile` instances and back. * `CompiledStructures.vb`: Defines several interconnected classes used to hold information about policy objects. `AdmxBundle` creates these by weaving together information from several ADMX and ADML files. These instances are the object-oriented equivalents of their `AdmxStructures.vb` counterparts. * `ConfigurationStorage.vb`: Helps load and store program configuration that resides in the Registry. diff --git a/PolicyPlus/BitReinterpretation.vb b/PolicyPlus/BitReinterpretation.vb new file mode 100644 index 0000000..b985a92 --- /dev/null +++ b/PolicyPlus/BitReinterpretation.vb @@ -0,0 +1,13 @@ +Imports System.Runtime.InteropServices + + +Public Structure ReinterpretableDword + Public Signed As Integer + Public Unsigned As UInteger +End Structure + + +Public Structure ReinterpretableQword + Public Signed As Long + Public Unsigned As ULong +End Structure \ No newline at end of file diff --git a/PolicyPlus/PolicyPlus.vbproj b/PolicyPlus/PolicyPlus.vbproj index 5d01882..a3e28e8 100644 --- a/PolicyPlus/PolicyPlus.vbproj +++ b/PolicyPlus/PolicyPlus.vbproj @@ -78,6 +78,7 @@ + diff --git a/PolicyPlus/PolicySource.vb b/PolicyPlus/PolicySource.vb index d9143e4..51c0aa3 100644 --- a/PolicyPlus/PolicySource.vb +++ b/PolicyPlus/PolicySource.vb @@ -372,6 +372,11 @@ Public Class RegistryPolicyProxy ' Pass operations through to the real Registry DeleteValue(Key, Value) ' The Registry has no concept of "will delete this when I see it" End Sub Public Sub SetValue(Key As String, Value As String, Data As Object, DataType As RegistryValueKind) Implements IPolicySource.SetValue + If TypeOf Data Is UInteger Then + Data = (New ReinterpretableDword With {.Unsigned = Data}).Signed + ElseIf TypeOf Data Is ULong Then + Data = (New ReinterpretableQword With {.Unsigned = Data}).Signed + End If Using regKey = RootKey.CreateSubKey(Key) regKey.SetValue(Value, Data, DataType) End Using @@ -386,7 +391,14 @@ Public Class RegistryPolicyProxy ' Pass operations through to the real Registry Public Function GetValue(Key As String, Value As String) As Object Implements IPolicySource.GetValue Using regKey = RootKey.OpenSubKey(Key, False) If regKey Is Nothing Then Return Nothing - Return regKey.GetValue(Value, Nothing, RegistryValueOptions.DoNotExpandEnvironmentNames) + Dim data = regKey.GetValue(Value, Nothing, RegistryValueOptions.DoNotExpandEnvironmentNames) + If TypeOf data Is Integer Then + Return (New ReinterpretableDword With {.Signed = data}).Unsigned + ElseIf TypeOf data Is Long Then + Return (New ReinterpretableQword With {.Signed = data}).Unsigned + Else + Return data + End If End Using End Function Public Function GetValueNames(Key As String) As List(Of String) Implements IPolicySource.GetValueNames