Today I did a lot of coding.
I started off by defining a PolicyLoader class, each instance of which is responsible for keeping track of the lifecycle of an IPolicySource. The loader figures out where to load a file from based on the option selected in the Open dialog, then constructs the policy source, then saves the policy source when asked to, then does any teardown that's required before the program ends. It also can tell callers whether it's actually writable, and though I haven't implemented any comment functionality yet, can provide the path to the CMTX file. The Open dialog constructs a loader for each source (user and computer), then the main form invokes its functions when necessary.
All the various sources can be opened successfully. Implementing the ntuser.dat loader was very difficult, as it required a lot of very fiddly P/Invoke. (Memory alignment issues are very difficult to debug!) That loader type is the only one that has to do any cleanup, since it has to unload the Registry hive.
All loader kinds can save successfully too. I had to make a few changes to the setting editor to allow for the policy sources to change during the process's existence. I also made the OK and Apply buttons automatically get disabled when the active policy source cannot be written. RefreshPolicyEx works perfectly as a way to cause policy reprocessing, for the normal local GPO and per-user GPOs. Before invoking the refresh, Policy Plus increments the "version" field in gpt.ini so Windows notices the changes. The save results dialog displays exactly what is done for each section. In most cases, in involves saving to disk, but when editing the Registry directly, the changes are already saved.
In other words, it works! I haven't committed the changes to GitHub yet because I'm waiting for a new Windows 7 Home VM to finish setting up so I can test all this in there. (My previous test environment was broken by the Windows 10 1607 upgrade.)
No comments:
Post a Comment