Jump to content



Photo

Registry Policy File Editor

registry group policy editor

  • Please log in to reply
5 replies to this topic

#1 zorphnog

zorphnog

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 445 posts

Posted 31 May 2012 - 08:48 PM

I needed a tool that would allow me to edit local group policy files. Registry policy files contain registry information used by the local group policy. Editing these files, followed by a `gpupdate /force` command allows you to enforce the modified local group policy. To my surprise, there aren't many editors out there for this type of file. I found a few implementations across the net, but none of them did everything I wanted or they were not free. Mainly I wanted a tool that provided read/write capabilities for the registry policy file format (.pol) via GUI and command line interface.

So I created 'GPO Registry Editor' to solve this problem and I thought I would share it with the community. The script provides read/write access .pol file through GUI and CLI. I created the editor to be compliant with the Registry Policy File Format. However, in my testing the special values **DeleteKeys and **SecureKey do not conform the the format specification (at least not on Windows XP). Although I did implement these features, they do not perform the expected results when updated via gpupdate.

Posted Image


The CLI has the following usage:
GPO Registry Editor v1.0.0.0 Provides read and write capabilities for registry policy files.    Usage:     -a  --add           Add the entry specified by the key, value, type, and data parameters.     -r  --remove         Remove the entry specified by the key and value parameters.     -d  --data         Specifies the data of the registry entry.     -f  --file         Specifies the registry file to load or modify. Use `computer` or `user` to specify the system policy files.     -k  --key           Specifies the key of the registry entry.     -s  --silent         Perform the operation silently (no GUI).     -t  --type         Specifies the type of the registry entry.     -v  --value       Specifies the value of the registry entry.     -h  --help         Display this message.     -?  --?           Display this message.

Example: Add a value to the system Computer/Machine registry file.
gre --add -f=computer -k=SoftwarePoliciesMicrosoftMyTestKey -v="My Test Value" -t REG_SZ -d="Registry Policy File editing"

Example: Remove a value from the system User registry file and suppress GUI error messages.
gre --remove -f user -k SoftwarePoliciesMicrosoftMyTestKey -v "My Test Value" -s

Example: Delete all values of a key from a local file.
gre --add -f=C:Registry.pol -k=SoftwarePoliciesMicrosoftMyTestKey -v=**DelVals



Source code:
AutoIt         
#NoTrayIcon #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Compile_Both=y #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_Res_Description=Provides read and write capabilities for registry policy files. #AutoIt3Wrapper_Res_Fileversion=1.0.0.0 #AutoIt3Wrapper_Res_Language=1033 #AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #cs ---------------------------------------------------------------------------- Title:        GPO Registry Editor AutoIt Version: 3.3.8.1 Author:      Michael Mims (zorphnog) Script Function:     Provides read/write capabilities for the registry policy file format (.pol) via GUI or command line interface.     Registry policy files contain registry information used by the local group policy. Editing these files, followed     by a `gpupdate /force` command will update the local group policy.     **Note: On Windows Vista and above, administrator rights are required to save to the system group policy folder.             Compile with the requestedExecutionLevel=requireAdministrator directive to ensure administrator access. Reference(s):     Registry Policy File Format - http://msdn.microsoft.com/en-us/library/windows/desktop/aa374407(v=vs.85).aspx #ce ---------------------------------------------------------------------------- #include <EditConstants.au3> #include <File.au3> #include <GuiComboBox.au3> #include <GuiConstants.au3> #include <GuiListView.au3> #include <Misc.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include "_OptParse.au3" ; Set Options Opt("GUICloseOnESC", 0) Opt("GUIOnEventMode", 1) Opt("MustDeclareVars", 1) ; Create mutex If @AutoItX64 And @Compiled Then     _Singleton("GPO64_RE") Else     _Singleton("GPO_RE") EndIf ; Application globals Global Const $GRE_TITLE = "GPO Registry Editor" Global Const $GRE_VERSION = "1.0.0.0" Global Const $GRE_DESC = "Provides read and write capabilities for registry policy files." ; File globals Global Const $GRE_LOG_FILE = @ScriptDir & "gre.log" Global Const $USER_REGISTRY_FILE = @SystemDir & "GroupPolicyUserRegistry.pol" Global Const $MACHINE_REGISTRY_FILE = @SystemDir & "GroupPolicyMachineRegistry.pol" ; Policy file format globals Global Const $REGISTRY_FILE_SIGNATURE = 0x67655250 Global Const $REGISTRY_FILE_VERSION = 0x00000001 Global Const $REGISTRY_FILE_ENCODING = 2  ; 1 - ANSI, 2 - UTF16 LE, 3 - UTF16 BE, 4 - UTF8 ; $g_aEntries array indices Global Enum $POLENTRY_KEY, $POLENTRY_VALUE, $POLENTRY_TYPE, $POLENTRY_SIZE, $POLENTRY_DATA ; Registry globals Global Enum $REG_NONE,$REG_SZ,$REG_EXPAND_SZ,$REG_BINARY,$REG_DWORD,$REG_DWORD_BIG_ENDIAN,$REG_LINK,$REG_MULTI_SZ, _     $REG_RESOURCE_LIST,$REG_FULL_RESOURCE_DESCRIPTOR,$REG_RESOURCE_REQUIREMENTS_LIST,$REG_QWORD Global Const $g_REGTYPES[12] = [ "REG_NONE", "REG_SZ", "REG_EXPAND_SZ", "REG_BINARY", _     "REG_DWORD", "REG_DWORD_BIG_ENDIAN", "REG_LINK", "REG_MULTI_SZ", "REG_RESOURCE_LIST", _     "REG_FULL_RESOURCE_DESCRIPTOR", "REG_RESOURCE_REQUIREMENTS_LIST", "REG_QWORD"] Global Const $g_ENTRYREGTYPE_CONV[4] = [$REG_SZ,$REG_EXPAND_SZ,$REG_BINARY,$REG_DWORD] Global Const $g_ENTRYREGTYPES[4] = [$g_REGTYPES[$g_ENTRYREGTYPE_CONV[0]],$g_REGTYPES[$g_ENTRYREGTYPE_CONV[1]], _     $g_REGTYPES[$g_ENTRYREGTYPE_CONV[2]], $g_REGTYPES[$g_ENTRYREGTYPE_CONV[3]]] ; Policy entry type globals Global Enum $ENTRY_TYPE_NORM,$ENTRY_TYPE_DEL,$ENTRY_TYPE_DELMULVALS,$ENTRY_TYPE_DELALLVALS,$ENTRY_TYPE_DELKEYS, _     $ENTRY_TYPE_SECKEY,$_ENTRY_TYPE_SIZE Global Const $g_ENTRYTYPES[$_ENTRY_TYPE_SIZE] = ["Normal Entry", "Delete Value", "Delete Multiple Values", _     "Delete All Values", "Delete Subkeys", "Secure Key"] ; $g_MainCtrl array indices Global Enum $ENT_GUI,$ENT_CBENTR,$ENT_LBKEY,$ENT_INKEY,$ENT_LBVALU,$ENT_INVALU,$ENT_LBTYPE,$ENT_CBTYPE,$ENT_LBDATA, _     $ENT_INDATA,$ENT_LBDESC,$ENT_ILASTENTR,$_ENT_SIZE ; $g_EntryCtrl array indices Global Enum $MAIN_GUI,$MAIN_LVENTR,$MAIN_BTNEW,$MAIN_BTEDIT,$MAIN_BTDEL,$MAIN_MIMPOL,$MAIN_MIUPOL,$MAIN_MISAVE, _     $MAIN_MISAVA,$_MAIN_SIZE ; Command line option array indices Global Enum $GRE_OPT_ACTION,$GRE_OPT_FILE,$GRE_OPT_KEY,$GRE_OPT_VALUE,$GRE_OPT_TYPE,$GRE_OPT_DATA,$_GRE_OPT_SIZE Global Enum $GRE_ACTION_ADD,$GRE_ACTION_REMOVE ; Error code globals Global Enum Step *2 $GRE_ERROR_NONE=0,$GRE_ERROR_NOFILE=1,$GRE_ERROR_NOACTION,$GRE_ERROR_NOKEY,$GRE_ERROR_NOVALUE, _     $GRE_ERROR_NOTYPE,$GRE_ERROR_INVALIDTYPE,$GRE_ERROR_NODATA,$GRE_ERROR_FILENOTEXIST,$GRE_ERROR_INVALIDARG, _     $GRE_ERROR_DUPLICATEARG,$GRE_ERROR_INVALIDSWITCH,$GRE_ERROR_FILEWRITE,$GRE_ERROR_INVALIDREGISTRYSIG, _     $GRE_ERROR_INVALIDREGISTRYVERSION,$GRE_ERROR_ENTRYNOTFOUND,$GRE_ERROR_DELETEENTRY,$GRE_ERROR_INVALIDSPECVAL Global $g_aEntries[1][5], $g_MainCtrl[$_MAIN_SIZE], $g_EntryCtrl[$_ENT_SIZE] Global $g_sRegFile, $g_iEditLVIndex = -1, $g_bOpen = False, $g_bChanged = False, $g_bDebug = False, $g_bSilent = False _Main() Func _AddEntry($sKey, $sValue, $iType = 1, $vData = "")     Local $iIndex = _FindEntry($sKey, $sValue)     If @error Then         $iIndex = UBound($g_aEntries)         ReDim $g_aEntries[$iIndex + 1][5]         $g_aEntries[$iIndex][$POLENTRY_KEY] = $sKey & ChrW(0)         $g_aEntries[$iIndex][$POLENTRY_VALUE] = $sValue & ChrW(0)     EndIf     ; Force type for special values     If StringLeft($sValue, 2) == "**" Then         __DebugPrint("Special value; forcing REG_SZ", "_AddEntry")         $iType = $REG_SZ     EndIf     $g_aEntries[$iIndex][$POLENTRY_TYPE] = Binary(Int($iType))     ; Determine if value is string data and convert properly     Switch $iType         Case $REG_SZ, $REG_EXPAND_SZ             ; Check for special values             If StringLeft($sValue, 2) == "**" Then                 Select                     Case StringMid($sValue, 3, 12) = "DeleteValues" Or StringMid($sValue, 3, 10) = "DeleteKeys"                         $vData = StringToBinary(StringRegExpReplace(StringStripWS($vData, 3), "(s*;s*)", ";") & _                             ChrW(0), $REGISTRY_FILE_ENCODING)                     Case Else                         $vData = StringToBinary(ChrW(0x20) & ChrW(0), $REGISTRY_FILE_ENCODING)                 EndSelect             Else                 $vData = StringToBinary($vData & ChrW(0), $REGISTRY_FILE_ENCODING)             EndIf         Case $REG_DWORD             $vData = Binary(Int($vData))         Case Else             $vData = Binary($vData)     EndSwitch     $g_aEntries[$iIndex][$POLENTRY_SIZE] = BinaryLen($vData)     $g_aEntries[$iIndex][$POLENTRY_DATA] = $vData     Return $iIndex EndFunc   ;==>_AddEntry Func _CloseFile()     If Not $g_bOpen Then Return True     If $g_bOpen And $g_bChanged Then         Local $iRet = MsgBox(0x1033, $GRE_TITLE, "The current registry file has been modified. Would you like to save the changes?", 0, $g_MainCtrl[$MAIN_GUI])         If $iRet = 2 Then  ; CANCEL             Return False         ElseIf $iRet = 6 Then  ; YES             _SaveFile()         EndIf     EndIf     _GUICtrlListView_DeleteAllItems($g_MainCtrl[$MAIN_LVENTR])     _ModifyFile(False, False)     $g_aEntries = 0     Dim $g_aEntries[1][5]     $g_sRegFile = ""     Return True EndFunc   ;==>_CloseFile Func _CreateEntryGUI($bIsNew = True)     Local $sTitle = "Add"     If Not $bIsNew Then $sTitle = "Edit"     $g_EntryCtrl[$ENT_GUI] = GUICreate($sTitle & " Registry Entry", 520, 240, -1, -1, BitOR($WS_POPUP, $WS_CAPTION), $WS_EX_TOOLWINDOW, $g_MainCtrl[$MAIN_GUI])     GUICtrlCreateGroup("", 10, 10, 500, 185)     $g_EntryCtrl[$ENT_CBENTR] = GUICtrlCreateCombo("", 20, 6, 135, 25, BitOR($CBS_DROPDOWNLIST,$CBS_AUTOHSCROLL))     GUICtrlSetData(-1, _ArrayToString($g_ENTRYTYPES), $g_ENTRYTYPES[0])     GUICtrlSetOnEvent(-1, "_Ev_cbEntryType")     $g_EntryCtrl[$ENT_ILASTENTR] = 0     $g_EntryCtrl[$ENT_LBKEY] = GUICtrlCreateLabel("Key:", 20, 44, 45, 17, $SS_RIGHT)     $g_EntryCtrl[$ENT_INKEY] = GUICtrlCreateInput("", 70, 41, 430, 21)     $g_EntryCtrl[$ENT_LBVALU] = GUICtrlCreateLabel("Value:", 20, 76, 45, 17, $SS_RIGHT)     $g_EntryCtrl[$ENT_INVALU] = GUICtrlCreateInput("", 70, 73, 430, 21)     $g_EntryCtrl[$ENT_LBTYPE] = GUICtrlCreateLabel("Type:", 20, 108, 45, 17, $SS_RIGHT)     $g_EntryCtrl[$ENT_CBTYPE] = GUICtrlCreateCombo("", 70, 105, 240, 25, BitOR($CBS_DROPDOWNLIST,$CBS_AUTOHSCROLL))     GUICtrlSetData(-1, _ArrayToString($g_ENTRYREGTYPES), $g_ENTRYREGTYPES[0])     $g_EntryCtrl[$ENT_LBDATA] = GUICtrlCreateLabel("Data:", 20, 140, 45, 17, $SS_RIGHT)     $g_EntryCtrl[$ENT_INDATA] = GUICtrlCreateInput("", 70, 137, 430, 42, $ES_MULTILINE)     $g_EntryCtrl[$ENT_LBDESC] = GUICtrlCreateLabel("", 70, 100, 430, 68)     GUICtrlSetFont(-1, Default, Default, 2)     GUICtrlSetState(-1, $GUI_HIDE)     GUICtrlCreateGroup("", -99, -99, 1, 1)     GUICtrlCreateButton("OK", 350, 205, 75, 25)     GUICtrlSetOnEvent(-1, "_Ev_btEntryOk")     GUICtrlCreateButton("Cancel", 435, 205, 75, 25)     GUICtrlSetOnEvent(-1, "_Ev_btEntryCancel") EndFunc   ;==>_CreateEntryGUI Func _CreateGUI()     $g_MainCtrl[$MAIN_GUI] = GUICreate($GRE_TITLE, 770, 475, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU, $WS_MAXIMIZEBOX, $WS_SIZEBOX))     GUISetOnEvent($GUI_EVENT_CLOSE, "_Ev_miFileClose")     GUICtrlCreateListView("Registry Key|Value|Type|Data", 10, 10, 750, 400)     $g_MainCtrl[$MAIN_LVENTR] = GUICtrlGetHandle(-1)     GUICtrlSendMsg(-1, 0x101E, 0, 350)     GUICtrlSendMsg(-1, 0x101E, 1, 150)     GUICtrlSendMsg(-1, 0x101E, 2, 100)     GUICtrlSendMsg(-1, 0x101E, 3, 100)     GUICtrlSetResizing(-1, $GUI_DOCKBORDERS)     $g_MainCtrl[$MAIN_BTNEW] = GUICtrlCreateButton("New...", 10, 420, 75, 25, 0)     GUICtrlSetState(-1, $GUI_DISABLE)     GUICtrlSetOnEvent(-1, "_Ev_btNew")     GUICtrlSetResizing(-1, BitOR($GUI_DOCKLEFT,$GUI_DOCKBOTTOM,$GUI_DOCKSIZE))     $g_MainCtrl[$MAIN_BTEDIT] = GUICtrlCreateButton("Edit...", 95, 420, 75, 25, 0)     GUICtrlSetState(-1, $GUI_DISABLE)     GUICtrlSetOnEvent(-1, "_Ev_btEdit")     GUICtrlSetResizing(-1, BitOR($GUI_DOCKLEFT,$GUI_DOCKBOTTOM,$GUI_DOCKSIZE))     $g_MainCtrl[$MAIN_BTDEL] = GUICtrlCreateButton("Delete", 180, 420, 75, 25, 0)     GUICtrlSetState(-1, $GUI_DISABLE)     GUICtrlSetOnEvent(-1, "_Ev_btDelete")     GUICtrlSetResizing(-1, BitOR($GUI_DOCKLEFT,$GUI_DOCKBOTTOM,$GUI_DOCKSIZE))     ; Menu items     Local $muFile, $muOpen     $muFile = GUICtrlCreateMenu("File")     GUICtrlCreateMenuItem("New", $muFile)     GUICtrlSetOnEvent(-1, "_Ev_miFileNew")     $muOpen = GUICtrlCreateMenu("Open", $muFile)     $g_MainCtrl[$MAIN_MIMPOL] = GUICtrlCreateMenuItem("Machine Policy", $muOpen)     GUICtrlSetOnEvent(-1, "_Ev_miFileOpenSystem")     $g_MainCtrl[$MAIN_MIUPOL] = GUICtrlCreateMenuItem("User Policy", $muOpen)     GUICtrlSetOnEvent(-1, "_Ev_miFileOpenSystem")     GUICtrlCreateMenuItem("", $muOpen)     GUICtrlCreateMenuItem("File...", $muOpen)     GUICtrlSetOnEvent(-1, "_Ev_miFileOpenFile")     $g_MainCtrl[$MAIN_MISAVE] = GUICtrlCreateMenuItem("Save", $muFile)     GUICtrlSetState(-1, $GUI_DISABLE)     GUICtrlSetOnEvent(-1, "_Ev_miFileSave")     $g_MainCtrl[$MAIN_MISAVA] = GUICtrlCreateMenuItem("Save As...", $muFile)     GUICtrlSetState(-1, $GUI_DISABLE)     GUICtrlSetOnEvent(-1, "_Ev_miFileSave")     GUICtrlCreateMenuItem("", $muFile)     GUICtrlCreateMenuItem("Exit", $muFile)     GUICtrlSetOnEvent(-1, "_Ev_miFileClose")     GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")     GUISetState(@SW_SHOW) EndFunc   ;==>_CreateGUI Func _DeleteEntry($sKey, $sValue)     Local $iIndex = _FindEntry($sKey, $sValue)     If @error Then Return SetError(@error, 0, -1)     __DebugPrint("--key=" & $sKey & " --value=" & $sValue, "_DeleteEntry")     _ArrayDelete($g_aEntries, $iIndex)     If @error Then Return SetError($GRE_ERROR_DELETEENTRY, 0, -1)     Return 1 EndFunc   ;==>_DeleteEntry Func _EditEntry($iEntry = -1)     If $iEntry == -1 Then         $g_iEditLVIndex = $iEntry         _CreateEntryGUI()     Else         _CreateEntryGUI(False)         _LoadEntryValues($iEntry)     EndIf     GUISetState(@SW_DISABLE, $g_MainCtrl[$MAIN_GUI])     GUISetState(@SW_SHOW, $g_EntryCtrl[$ENT_GUI]) EndFunc   ;==>_EditEntry Func _FindEntry($sKey, $sValue)     Local $iCurrent, $iIndex, $iSize     $iCurrent = 0     $iSize = UBound($g_aEntries)     While $iCurrent < $iSize         $iIndex = _ArraySearch($g_aEntries, $sValue, $iCurrent, 0, 0, 0, 1, $POLENTRY_VALUE)         If @error Then ExitLoop         If $g_aEntries[$iIndex][$POLENTRY_KEY] = $sKey Then             __DebugPrint($iIndex & " " & $g_aEntries[$iIndex][$POLENTRY_KEY], "_FindEntry")             Return $iIndex         EndIf         $iCurrent = $iIndex + 1     WEnd     Return SetError($GRE_ERROR_ENTRYNOTFOUND, 0, -1) EndFunc   ;==>_FindEntry Func _GetFormattedData($iIndex, $bHex = True)     Switch $g_aEntries[$iIndex][$POLENTRY_TYPE]         Case $REG_SZ, $REG_EXPAND_SZ             Return BinaryToString($g_aEntries[$iIndex][$POLENTRY_DATA], $REGISTRY_FILE_ENCODING)         Case $REG_BINARY             Return "0x" & Hex(Int($g_aEntries[$iIndex][$POLENTRY_DATA]), 8)         Case $REG_DWORD             If $bHex Then Return "0x" & Hex(Int($g_aEntries[$iIndex][$POLENTRY_DATA]), 8)             Return Int($g_aEntries[$iIndex][$POLENTRY_DATA])         Case Else             Return $g_aEntries[$iIndex][4]     EndSwitch EndFunc   ;==>_GetFormattedData Func _LoadEntryValues($iEntry)     Local $iEntryType, $sKey, $sValue, $iRegType, $sValue     $iEntryType = 0     $sKey = $g_aEntries[$iEntry][$POLENTRY_KEY]     $sValue = $g_aEntries[$iEntry][$POLENTRY_VALUE]     If StringLeft($sValue, 2) == "**" Then         Select             Case StringMid($sValue, 3, 12) = "DeleteValues"                 $iEntryType = $ENTRY_TYPE_DELMULVALS                 $sValue = BinaryToString($g_aEntries[$iEntry][$POLENTRY_DATA], $REGISTRY_FILE_ENCODING)                 $iRegType = 0             Case StringMid($sValue, 3, 4) = "Del."                 $iEntryType = $ENTRY_TYPE_DEL                 $sValue = StringMid($sValue, 7)                 $iRegType = 0             Case StringMid($sValue, 3, 7) = "DelVals"                 $iEntryType = $ENTRY_TYPE_DELALLVALS                 $sValue = ""                 $iRegType = 0             Case StringMid($sValue, 3, 10) = "DeleteKeys"                 $iEntryType = $ENTRY_TYPE_DELKEYS                 $sValue = BinaryToString($g_aEntries[$iEntry][$POLENTRY_DATA], $REGISTRY_FILE_ENCODING)                 $iRegType = 0             Case StringMid($sValue, 3, 9) = "SecureKey"                 $iEntryType = $ENTRY_TYPE_SECKEY                 $iRegType = Int(StringMid($sValue, 13, 1))                 $sValue = ""         EndSelect         _GUICtrlComboBox_SetCurSel($g_EntryCtrl[$ENT_CBENTR], $iEntryType)         _Ev_cbEntryType()         GUICtrlSetData($g_EntryCtrl[$ENT_INKEY], $sKey)         GUICtrlSetData($g_EntryCtrl[$ENT_INVALU], $sValue)         _GUICtrlComboBox_SetCurSel($g_EntryCtrl[$ENT_CBTYPE], $iRegType)     Else         $iRegType = _ArraySearch($g_ENTRYREGTYPE_CONV, $g_aEntries[$iEntry][$POLENTRY_TYPE])         GUICtrlSetData($g_EntryCtrl[$ENT_INKEY], $sKey)         GUICtrlSetData($g_EntryCtrl[$ENT_INVALU], $sValue)         _GUICtrlComboBox_SetCurSel($g_EntryCtrl[$ENT_CBTYPE], $iRegType)         GUICtrlSetData($g_EntryCtrl[$ENT_INDATA], _GetFormattedData($iEntry, False))     EndIf EndFunc   ;==>_LoadEntryValues Func _Main()     Local $aValidOpts, $aOptions, $sFilename = ""     If @CPUArch = "X64" And Not @AutoItX64 Then ;~       __DebugPrint("X64 architecture detected.", "_Main", True)         Local $sDrive, $sDir, $sFile, $sExt, $sExec         _PathSplit(@ScriptFullPath, $sDrive, $sDir, $sFile, $sExt)         $sExec = @ScriptDir & "" & $sFile & "_x64" & $sExt ;~       __DebugPrint("Attempting 64 bit launch: " & $sExec, "_Main", True)         If FileExists($sExec) Then Exit(RunWait($sExec & " " & _ArrayToString($CmdLine, " ", 1), @WorkingDir))     EndIf     If _ParseOptions($aValidOpts, $aOptions) Then         Local $iOption, $iMatches = 0         If _OptParse_MatchOption("h,help,?", $aOptions, $iOption) Then             _OptParse_ShowUsage($aValidOpts, 1)             Exit($GRE_ERROR_NONE)         EndIf         If _OptParse_MatchOption("D,debug", $aOptions, $iOption) Then             $iMatches += 1             $g_bDebug = True             __PrintEnvironment()         EndIf         If _OptParse_MatchOption("s,silent", $aOptions, $iOption) Then             __DebugPrint("Silent mode set", "_Main")             $iMatches += 1             $g_bSilent = True             _OptParse_SetDisplay(0)         EndIf         If _OptParse_MatchOption("f,file", $aOptions, $iOption) Then             $iMatches += 1             Switch StringLower($aOptions[$iOption][1])                 Case "c","comp","computer","m","machine"                     $sFilename = $MACHINE_REGISTRY_FILE                 Case "u","user"                     $sFilename = $USER_REGISTRY_FILE                 Case Else                     $sFilename = _PathFull($aOptions[$iOption][1])             EndSwitch             __DebugPrint("[file] " & $sFilename, "_Main")         EndIf         ; Some command line parameters for testing         ; --add -f Registry.pol -k SoftwareMyTestKey -v TestMe -t REG_SZ -d "test, test, test"         ; --remove -f Registry.pol -k SoftwareMyTestKey -v TestMe         If _OptParse_MatchOption("a,add,r,remove", $aOptions, $iOption) Then             Local $iReturn, $aValidated = _ValidateOptions($aOptions)             _ReadPolFile($sFilename)             If @error Then Exit(@error)             If $aValidated[$GRE_OPT_ACTION] == $GRE_ACTION_ADD Then                 _AddEntry($aValidated[$GRE_OPT_KEY], $aValidated[$GRE_OPT_VALUE], $aValidated[$GRE_OPT_TYPE], _                     $aValidated[$GRE_OPT_DATA])             ElseIf $aValidated[$GRE_OPT_ACTION] == $GRE_ACTION_REMOVE Then                 _DeleteEntry($aValidated[$GRE_OPT_KEY], $aValidated[$GRE_OPT_VALUE])                 If @error Then Exit(@error)             EndIf             _WritePolFile($sFilename)             If @error Then Exit(@error)             Exit($GRE_ERROR_NONE)         ElseIf $iMatches < $aOptions[0][0] Then             _OptParse_Display("No action specified. Use --add or --remove to modify a policy file.", "Error")             Exit($GRE_ERROR_NOACTION)         EndIf     EndIf     _CreateGUI()     If $sFilename <> "" Then _OpenFile($sFilename)     While 1         Sleep(10)     WEnd EndFunc   ;==>_Main Func _ModifyFile($bNewOpen, $bNewChanged)     Local $sTitle, $aClientSize, $a_iCall     __DebugPrint(StringFormat("[%s, %s] => [%s, %s]", $g_bOpen, $g_bChanged, $bNewOpen, $bNewChanged), "_ModifyFile")     If $bNewOpen <> $g_bOpen Then         If $bNewOpen Then             If $g_sRegFile == "" Then                 $sTitle = "New Policy File - " & $GRE_TITLE             Else                 $sTitle = $g_sRegFile & " - " & $GRE_TITLE             EndIf             $aClientSize = WinGetClientSize($g_MainCtrl[$MAIN_GUI])             $a_iCall = DllCall("shlwapi.dll", "int", "PathCompactPathW", _                     "hwnd", 0, _                     "wstr", $sTitle, _                     "dword", $aClientSize[0] - 100)             If Not @error Then $sTitle = $a_iCall[2]             WinSetTitle($g_MainCtrl[$MAIN_GUI], 0, $sTitle)             GUICtrlSetState($g_MainCtrl[$MAIN_MISAVA], $GUI_ENABLE)             GUICtrlSetState($g_MainCtrl[$MAIN_BTNEW], $GUI_ENABLE)             GUICtrlSetState($g_MainCtrl[$MAIN_BTEDIT], $GUI_ENABLE)             GUICtrlSetState($g_MainCtrl[$MAIN_BTDEL], $GUI_ENABLE)         Else             WinSetTitle($g_MainCtrl[$MAIN_GUI], 0, $GRE_TITLE)             GUICtrlSetState($g_MainCtrl[$MAIN_MISAVE], $GUI_DISABLE)             GUICtrlSetState($g_MainCtrl[$MAIN_MISAVA], $GUI_DISABLE)             GUICtrlSetState($g_MainCtrl[$MAIN_BTNEW], $GUI_DISABLE)             GUICtrlSetState($g_MainCtrl[$MAIN_BTEDIT], $GUI_DISABLE)             GUICtrlSetState($g_MainCtrl[$MAIN_BTDEL], $GUI_DISABLE)             $g_bChanged = False         EndIf         $g_bOpen = $bNewOpen         Return     EndIf     If $bNewChanged <> $g_bChanged And $g_bOpen Then         If $bNewChanged Then             If $g_sRegFile == "" Then                 $sTitle = "New Policy File* - " & $GRE_TITLE             Else                 $sTitle = $g_sRegFile & "* - " & $GRE_TITLE             EndIf             $aClientSize = WinGetClientSize($g_MainCtrl[$MAIN_GUI])             $a_iCall = DllCall("shlwapi.dll", "int", "PathCompactPathW", _                     "hwnd", 0, _                     "wstr", $sTitle, _                     "dword", $aClientSize[0] - 100)             If Not @error Then $sTitle = $a_iCall[2]             WinSetTitle($g_MainCtrl[$MAIN_GUI], 0, $sTitle)             GUICtrlSetState($g_MainCtrl[$MAIN_MISAVE], $GUI_ENABLE)         Else             If $g_sRegFile == "" Then                 $sTitle = "New Policy File - " & $GRE_TITLE             Else                 $sTitle = $g_sRegFile & " - " & $GRE_TITLE             EndIf             $aClientSize = WinGetClientSize($g_MainCtrl[$MAIN_GUI])             $a_iCall = DllCall("shlwapi.dll", "int", "PathCompactPathW", _                     "hwnd", 0, _                     "wstr", $sTitle, _                     "dword", $aClientSize[0] - 100)             If Not @error Then $sTitle = $a_iCall[2]             WinSetTitle($g_MainCtrl[$MAIN_GUI], 0, $sTitle)             GUICtrlSetState($g_MainCtrl[$MAIN_MISAVE], $GUI_DISABLE)         EndIf     EndIf     $g_bChanged = $bNewChanged EndFunc   ;==>_ModifyFile Func _OpenFile($sFilename = "")     If Not _CloseFile() Then Return     If $sFilename <> "" Then         GUISetCursor(15, 1, $g_MainCtrl[$MAIN_GUI])         _ReadPolFile($sFilename)         If @error Then             GUISetCursor()             Return         EndIf         _UpdateListView()         GUISetCursor()     EndIf     $g_sRegFile = $sFilename     _ModifyFile(True, False) EndFunc   ;==>_OpenFile Func _ParseOptions(ByRef $aValidOpts, ByRef $aOptions)     Local $local_CmdLine = $CmdLine     $aValidOpts = 0     $aOptions = 0     ; Create the valid options list     _OptParse_Init($aValidOpts, $GRE_TITLE & "n", "v" & $GRE_VERSION & "n", $GRE_DESC & "n")     _OptParse_Add($aValidOpts, "a", "add", $OPT_ARG_NONE, "Add the entry specified by the key, value, type, and data parameters.")     _OptParse_Add($aValidOpts, "r", "remove", $OPT_ARG_NONE, "Remove the entry specified by the key and value parameters.")     _OptParse_Add($aValidOpts, "D", "debug", BitOR($OPT_ARG_NONE,$OPT_ARG_HIDDEN), "Record debugging information.")     _OptParse_Add($aValidOpts, "d", "data", $OPT_ARG_REQ, "Specifies the data of the registry entry.")     _OptParse_Add($aValidOpts, "f", "file", $OPT_ARG_REQ, "Specifies the registry file to load or modify. Use `computer` or `user` to specify the system policy files.")     _OptParse_Add($aValidOpts, "k", "key", $OPT_ARG_REQ, "Specifies the key of the registry entry.")     _OptParse_Add($aValidOpts, "s", "silent", $OPT_ARG_NONE, "Perform the operation silently (no GUI).")     _OptParse_Add($aValidOpts, "t", "type", $OPT_ARG_REQ, "Specifies the type of the registry entry.")     _OptParse_Add($aValidOpts, "v", "value", $OPT_ARG_REQ, "Specifies the value of the registry entry.")     _OptParse_Add($aValidOpts, "h", "help", $OPT_ARG_NONE, "Display this message.")     _OptParse_Add($aValidOpts, "?", "?", $OPT_ARG_NONE, "Display this message.")     $aOptions = _OptParse_GetOpts($local_CmdLine, $aValidOpts)     Switch @error         Case 0             _OptParse_SetDisplay(1)  ; Display via MsgBox             Return True         Case 1             _OptParse_SetDisplay(1)  ; Display via MsgBox             Return False         Case 2             Exit($GRE_ERROR_INVALIDARG)         Case 3             Exit($GRE_ERROR_DUPLICATEARG)         Case 4             Exit($GRE_ERROR_INVALIDSWITCH)     EndSwitch EndFunc   ;==>_ParseOptions Func _ReadPolFile($sFilename)     Local $hInfile, $bBuffer, $iStart, $iCurrent, $iLength, $iColon, $iNumEntries, $bTemp     If Not FileExists($sFilename) Then         If Not $g_bSilent Then MsgBox(0x1010, $GRE_TITLE, "ERROR: File not found: " & $sFilename)         Return SetError($GRE_ERROR_FILENOTEXIST, 0, -1)     EndIf     $hInfile = FileOpen($sFilename, 16)     $bBuffer = FileRead($hInfile)     FileClose($hInfile)     $iLength = BinaryLen($bBuffer)     If BinaryMid($bBuffer, 1, 4) <> Binary($REGISTRY_FILE_SIGNATURE) Then         If Not $g_bSilent Then MsgBox(0x1010, $GRE_TITLE, "ERROR: Invalid file signature. File will not be processed.")         Return SetError($GRE_ERROR_INVALIDREGISTRYSIG, 0, -1)     EndIf     If BinaryMid($bBuffer, 5, 4) <> Binary($REGISTRY_FILE_VERSION) Then         If Not $g_bSilent Then MsgBox(0x1010, $GRE_TITLE, "ERROR: Invalid registry file version. File will not be processed.")         Return SetError($GRE_ERROR_INVALIDREGISTRYVERSION, 0, -1)     EndIf     $iStart = 9     $iCurrent = 9     $iColon = 0     $iNumEntries = 0     $g_aEntries = 0     Dim $g_aEntries[1][5]     ; The body consists of registry values in the following format.     ; [key;value;type;size;data]     While $iCurrent < $iLength         $bTemp = BinaryMid($bBuffer, $iCurrent, 2)         Switch $bTemp             Case 0x005B ; Unicode => [                 ReDim $g_aEntries[$iNumEntries+1][5]                 $iColon = 0                 $iStart = $iCurrent + 2             Case 0x005D ; Unicode => ]                 $iStart = $iCurrent + 2                 $iNumEntries += 1             Case 0x003B ; Unicode => ;                 Switch $iColon                     Case 0                         $g_aEntries[$iNumEntries][$POLENTRY_KEY] = BinaryToString(BinaryMid($bBuffer, $iStart, $iCurrent - $iStart), $REGISTRY_FILE_ENCODING)                         $iColon += 1                         $iStart = $iCurrent + 2                     Case 1                         $g_aEntries[$iNumEntries][$POLENTRY_VALUE] = BinaryToString(BinaryMid($bBuffer, $iStart, $iCurrent - $iStart), $REGISTRY_FILE_ENCODING)                         $iColon += 1                         $iStart = $iCurrent + 2                     Case 2 ;~                       _ArrayDisplay($g_aEntries)                         $g_aEntries[$iNumEntries][$POLENTRY_TYPE] = Int(BinaryMid($bBuffer, $iStart, $iCurrent - $iStart))                         $iColon += 1                         $iStart = $iCurrent + 2                     Case 3                         $g_aEntries[$iNumEntries][$POLENTRY_SIZE] = Int(BinaryMid($bBuffer, $iStart, $iCurrent - $iStart))                         $iColon += 1                         $iStart = $iCurrent + 2                         $g_aEntries[$iNumEntries][$POLENTRY_DATA] = BinaryMid($bBuffer, $iStart, $g_aEntries[$iNumEntries][$POLENTRY_SIZE])                         $iCurrent = $iStart + $g_aEntries[$iNumEntries][$POLENTRY_SIZE] - 2                     Case Else                         $iColon += 1                         $iStart = $iCurrent + 2                 EndSwitch         EndSwitch         $iCurrent += 2     WEnd EndFunc   ;==>_ReadPolFile Func _SaveFile($bSaveAs = False)     If $bSaveAs Or Not FileExists($g_sRegFile) Then         Local $sFilename = FileSaveDialog("Save GPO Registry File...", "", "GPO Registry Files (*.pol)", 18, "", $g_MainCtrl[$MAIN_GUI])         If @error Then Return False         If StringRight($sFilename, 4) <> ".pol" Then $sFilename &= ".pol"         $g_sRegFile = $sFilename     EndIf     _WritePolFile($g_sRegFile)     If @error Then Return False     _ModifyFile($g_bOpen, False) EndFunc   ;==>_SaveFile Func _UpdateListView()     Local $i, $iMax     _GUICtrlListView_BeginUpdate($g_MainCtrl[$MAIN_LVENTR])     _GUICtrlListView_DeleteAllItems($g_MainCtrl[$MAIN_LVENTR])     $iMax = UBound($g_aEntries) - 1     For $i=0 To $iMax         _GUICtrlListView_AddItem($g_MainCtrl[$MAIN_LVENTR], $g_aEntries[$i][$POLENTRY_KEY])         _GUICtrlListView_AddSubItem($g_MainCtrl[$MAIN_LVENTR], $i, $g_aEntries[$i][$POLENTRY_VALUE], 1)         _GUICtrlListView_AddSubItem($g_MainCtrl[$MAIN_LVENTR], $i, $g_REGTYPES[$g_aEntries[$i][$POLENTRY_TYPE]], 2)         _GUICtrlListView_AddSubItem($g_MainCtrl[$MAIN_LVENTR], $i, _GetFormattedData($i), 3)     Next     _GUICtrlListView_EndUpdate($g_MainCtrl[$MAIN_LVENTR]) EndFunc   ;==>_UpdateListView Func _ValidateOptions($aOptions)     Local $aReturn[$_GRE_OPT_SIZE], $iOption     ; Check for policy file definition     If Not _OptParse_MatchOption("f,file", $aOptions, $iOption) Then         _OptParse_Display("File required. Use --file to specify the policy file to modify.", "Error")         Exit($GRE_ERROR_NOFILE)     EndIf     ; Check for key definition     If _OptParse_MatchOption("k,key", $aOptions, $iOption) Then         __DebugPrint("[key] " & $aOptions[$iOption][1], "_ValidateOptions")         $aReturn[$GRE_OPT_KEY] = $aOptions[$iOption][1]     Else         _OptParse_Display("Key required. Use --key to specify the registry key to modify.", "Error")         Exit($GRE_ERROR_NOKEY)     EndIf     ; Check for value definition     If _OptParse_MatchOption("v,value", $aOptions, $iOption) Then         __DebugPrint("[value] " & $aOptions[$iOption][1], "_ValidateOptions")         $aReturn[$GRE_OPT_VALUE] = $aOptions[$iOption][1]     Else         _OptParse_Display("Value required. Use --value to specify the registry value to modify.", "Error")         Exit($GRE_ERROR_NOVALUE)     EndIf     If _OptParse_MatchOption("r,remove", $aOptions, $iOption) Then         __DebugPrint("[action] remove", "_ValidateOptions")         $aReturn[$GRE_OPT_ACTION] = $GRE_ACTION_REMOVE         Return $aReturn     ElseIf _OptParse_MatchOption("a,add", $aOptions, $iOption) Then         Local $sType, $sData, $bTypeRequired = True, $bDataRequired = True         __DebugPrint("[action] add", "_ValidateOptions")         $aReturn[$GRE_OPT_ACTION] = $GRE_ACTION_ADD         ; Handle special values and determine whether data is required         If StringLeft($aReturn[$GRE_OPT_VALUE], "2") == "**" Then             Select                 Case StringMid($aReturn[$GRE_OPT_VALUE], 3, 4) = "Del." Or _                      StringMid($aReturn[$GRE_OPT_VALUE], 3, 7) = "DelVals" Or _                      StringMid($aReturn[$GRE_OPT_VALUE], 3, 9) = "SecureKey"                     __DebugPrint("Special value detected; data not required.", "_ValidateOptions")                     $bTypeRequired = False                     $bDataRequired = False                 Case StringMid($aReturn[$GRE_OPT_VALUE], 3, 12) = "DeleteValues" Or _                      StringMid($aReturn[$GRE_OPT_VALUE], 3, 10) = "DeleteKeys"                     __DebugPrint("Special value detected; data required.", "_ValidateOptions")                     $bTypeRequired = False                 Case Else                     _OptParse_Display("Invalid special value: " & $aReturn[$GRE_OPT_VALUE], "Error")                     Exit($GRE_ERROR_INVALIDSPECVAL)             EndSelect         EndIf         ; Check for type definition         If _OptParse_MatchOption("t,type", $aOptions, $iOption) Then             __DebugPrint("[type] " & $aOptions[$iOption][1], "_ValidateOptions")             $aReturn[$GRE_OPT_TYPE] = StringUpper($aOptions[$iOption][1])             $aReturn[$GRE_OPT_TYPE] = _ArraySearch($g_REGTYPES, $aReturn[$GRE_OPT_TYPE])             If @error Then                 _OptParse_Display("Invalid type argument: " & $aOptions[$iOption][1], "Error")                 Exit($GRE_ERROR_INVALIDTYPE)             EndIf         ElseIf $bTypeRequired Then             _OptParse_Display("Type required. Use --type to specify the registry type to add.", "Error")             Exit($GRE_ERROR_NOTYPE)         EndIf         ; Check for data definition         If _OptParse_MatchOption("d,data", $aOptions, $iOption) Then             __DebugPrint("[data] " & $aOptions[$iOption][1], "_ValidateOptions")             $aReturn[$GRE_OPT_DATA] = $aOptions[$iOption][1]         ElseIf $bDataRequired Then             _OptParse_Display("Data required. Use --data to specify the registry data to add.", "Error")             Exit($GRE_ERROR_NODATA)         EndIf         Return $aReturn     EndIf EndFunc   ;==>_ValidateOptions Func _WritePolFile($sFilename)     Local $hOutfile, $iMax     ; Open file for writing     __DebugPrint("Writing output file...", "_WritePolFile")     $hOutfile = FileOpen($sFilename, 26)     If $hOutfile = -1 Then         If Not $g_bSilent Then MsgBox(0x1010, $GRE_TITLE, "ERROR: File could not be created [" & $sFilename & "].")         Return SetError($GRE_ERROR_FILEWRITE, 0, -1)     EndIf     ; Write header information     FileWrite($hOutfile, Binary($REGISTRY_FILE_SIGNATURE))     FileWrite($hOutfile, Binary($REGISTRY_FILE_VERSION))     ; Write entries     $iMax = UBound($g_aEntries) - 1     For $i = 0 To $iMax         FileWrite($hOutfile, StringToBinary("[" & $g_aEntries[$i][$POLENTRY_KEY], $REGISTRY_FILE_ENCODING))         FileWrite($hOutfile, StringToBinary(";", $REGISTRY_FILE_ENCODING))         FileWrite($hOutfile, StringToBinary($g_aEntries[$i][$POLENTRY_VALUE], $REGISTRY_FILE_ENCODING))         FileWrite($hOutfile, StringToBinary(";", $REGISTRY_FILE_ENCODING))         FileWrite($hOutfile, $g_aEntries[$i][$POLENTRY_TYPE])         FileWrite($hOutfile, StringToBinary(";", $REGISTRY_FILE_ENCODING))         FileWrite($hOutfile, $g_aEntries[$i][$POLENTRY_SIZE])         FileWrite($hOutfile, StringToBinary(";", $REGISTRY_FILE_ENCODING))         FileWrite($hOutfile, $g_aEntries[$i][$POLENTRY_DATA])         FileWrite($hOutfile, StringToBinary("]", $REGISTRY_FILE_ENCODING))     Next     ; Close file     FileClose($hOutfile) EndFunc   ;==>_WritePolFile Func _Ev_btDelete()     Local $iIndex = _GUICtrlListView_GetSelectedIndices($g_MainCtrl[$MAIN_LVENTR])     If $iIndex <> "" Then         _DeleteEntry(_GUICtrlListView_GetItemText($g_MainCtrl[$MAIN_LVENTR], $iIndex), _GUICtrlListView_GetItemText($g_MainCtrl[$MAIN_LVENTR], $iIndex, 1))         If Not @error Then             _GUICtrlListView_DeleteItem($g_MainCtrl[$MAIN_LVENTR], $iIndex)             _ModifyFile($g_bOpen, True)         EndIf     EndIf EndFunc   ;==>_Ev_btDelete Func _Ev_btEdit()     Local $iEntry, $iIndex = _GUICtrlListView_GetSelectedIndices($g_MainCtrl[$MAIN_LVENTR])     If $iIndex <> "" Then         $iEntry = _FindEntry(_GUICtrlListView_GetItemText($g_MainCtrl[$MAIN_LVENTR], $iIndex), _GUICtrlListView_GetItemText($g_MainCtrl[$MAIN_LVENTR], $iIndex, 1))         If Not @error Then             $g_iEditLVIndex = $iIndex             _EditEntry($iEntry)         EndIf     EndIf EndFunc   ;==>_Ev_btEdit Func _Ev_btEntryCancel()     GUISetState(@SW_ENABLE, $g_MainCtrl[$MAIN_GUI])     GUIDelete($g_EntryCtrl[$ENT_GUI]) EndFunc   ;==>_Ev_btEntryCancel Func _Ev_btEntryOk()     Local $iIndex, $iEntry, $sKey, $sValue, $iType, $vData     $sKey = GUICtrlRead($g_EntryCtrl[$ENT_INKEY])     $sValue = GUICtrlRead($g_EntryCtrl[$ENT_INVALU])     $iType = $g_ENTRYREGTYPE_CONV[_GUICtrlComboBox_GetCurSel($g_EntryCtrl[$ENT_CBTYPE])]     $vData = GUICtrlRead($g_EntryCtrl[$ENT_INDATA])     Switch _GUICtrlComboBox_GetCurSel($g_EntryCtrl[$ENT_CBENTR])         Case $ENTRY_TYPE_DEL             $sValue = "**Del." & $sValue             $iType = $REG_SZ         Case $ENTRY_TYPE_DELMULVALS             $vData = $sValue             $sValue = "**DeleteValues"             $iType = $REG_SZ         Case $ENTRY_TYPE_DELALLVALS             $sValue = "**DelVals."             $iType = $REG_SZ         Case $ENTRY_TYPE_DELKEYS             $vData = $sValue             $sValue = "**DeleteKeys" & ChrW(0)             $iType = $REG_SZ         Case $ENTRY_TYPE_SECKEY             $sValue = "**SecureKey=" & _GUICtrlComboBox_GetCurSel($g_EntryCtrl[$ENT_CBTYPE])             $iType = $REG_SZ     EndSwitch     $iEntry = _AddEntry($sKey, $sValue, $iType, $vData)     If $g_iEditLVIndex == -1 Then         $iIndex = _GUICtrlListView_AddItem($g_MainCtrl[$MAIN_LVENTR], $g_aEntries[$iEntry][$POLENTRY_KEY])         If $iIndex <> -1 Then             _GUICtrlListView_AddSubItem($g_MainCtrl[$MAIN_LVENTR], $iIndex, $g_aEntries[$iEntry][$POLENTRY_VALUE], 1)             _GUICtrlListView_AddSubItem($g_MainCtrl[$MAIN_LVENTR], $iIndex, $g_REGTYPES[$g_aEntries[$iEntry][$POLENTRY_TYPE]], 2)             _GUICtrlListView_AddSubItem($g_MainCtrl[$MAIN_LVENTR], $iIndex, _GetFormattedData($iEntry), 3)         EndIf     Else         Local $sLVKey, $sLVValue         $sLVKey = _GUICtrlListView_GetItemText($g_MainCtrl[$MAIN_LVENTR], $g_iEditLVIndex)         $sLVValue = _GUICtrlListView_GetItemText($g_MainCtrl[$MAIN_LVENTR], $g_iEditLVIndex, 1)         ; Update list view entry         _GUICtrlListView_SetItemText($g_MainCtrl[$MAIN_LVENTR], $g_iEditLVIndex, $g_aEntries[$iEntry][$POLENTRY_KEY])         _GUICtrlListView_SetItemText($g_MainCtrl[$MAIN_LVENTR], $g_iEditLVIndex, $g_aEntries[$iEntry][$POLENTRY_VALUE], 1)         _GUICtrlListView_SetItemText($g_MainCtrl[$MAIN_LVENTR], $g_iEditLVIndex, $g_REGTYPES[$g_aEntries[$iEntry][$POLENTRY_TYPE]], 2)         _GUICtrlListView_SetItemText($g_MainCtrl[$MAIN_LVENTR], $g_iEditLVIndex, _GetFormattedData($iEntry), 3)         ; Delete old entry if necessary         If $sLVKey <> $sKey Or $sLVValue <> $sValue Then _DeleteEntry($sLVKey, $sLVValue)     EndIf     _ModifyFile($g_bOpen, True)     GUISetState(@SW_ENABLE, $g_MainCtrl[$MAIN_GUI])     GUIDelete($g_EntryCtrl[$ENT_GUI]) EndFunc   ;==>_Ev_btEntryOk Func _Ev_btNew()     _EditEntry() EndFunc   ;==>_Ev_btNew Func _Ev_cbEntryType()     Local $iSelected = _GUICtrlComboBox_GetCurSel($g_EntryCtrl[$ENT_CBENTR])     If $iSelected = $g_EntryCtrl[$ENT_ILASTENTR] Then Return     Switch $iSelected         Case $ENTRY_TYPE_NORM             GUICtrlSetState($g_EntryCtrl[$ENT_LBDESC], $GUI_HIDE)             GUICtrlSetData($g_EntryCtrl[$ENT_LBVALU], "Value:")             GUICtrlSetState($g_EntryCtrl[$ENT_LBVALU], $GUI_SHOW)             GUICtrlSetState($g_EntryCtrl[$ENT_INVALU], $GUI_SHOW)             GUICtrlSetPos($g_EntryCtrl[$ENT_LBTYPE], 20, 108)             GUICtrlSetData($g_EntryCtrl[$ENT_LBTYPE], "Type:")             GUICtrlSetState($g_EntryCtrl[$ENT_LBTYPE], $GUI_SHOW)             GUICtrlSetPos($g_EntryCtrl[$ENT_CBTYPE], 70, 105, 240)             _GUICtrlComboBox_ResetContent($g_EntryCtrl[$ENT_CBTYPE])             GUICtrlSetData($g_EntryCtrl[$ENT_CBTYPE], _ArrayToString($g_ENTRYREGTYPES), $g_ENTRYREGTYPES[0])             GUICtrlSetState($g_EntryCtrl[$ENT_CBTYPE], $GUI_SHOW)             GUICtrlSetState($g_EntryCtrl[$ENT_LBDATA], $GUI_SHOW)             GUICtrlSetState($g_EntryCtrl[$ENT_INDATA], $GUI_SHOW)         Case $ENTRY_TYPE_DEL             GUICtrlSetState($g_EntryCtrl[$ENT_LBTYPE], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_CBTYPE], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_LBDATA], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_INDATA], $GUI_HIDE)             GUICtrlSetData($g_EntryCtrl[$ENT_LBVALU], "Value:")             GUICtrlSetState($g_EntryCtrl[$ENT_LBVALU], $GUI_SHOW)             GUICtrlSetState($g_EntryCtrl[$ENT_INVALU], $GUI_SHOW)             GUICtrlSetPos($g_EntryCtrl[$ENT_LBDESC], 70, 100)             GUICtrlSetData($g_EntryCtrl[$ENT_LBDESC], "Deletes the value from the associated key.")             GUICtrlSetState($g_EntryCtrl[$ENT_LBDESC], $GUI_SHOW)         Case $ENTRY_TYPE_DELMULVALS             GUICtrlSetState($g_EntryCtrl[$ENT_LBTYPE], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_CBTYPE], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_LBDATA], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_INDATA], $GUI_HIDE)             GUICtrlSetData($g_EntryCtrl[$ENT_LBVALU], "Values:")             GUICtrlSetState($g_EntryCtrl[$ENT_LBVALU], $GUI_SHOW)             GUICtrlSetState($g_EntryCtrl[$ENT_INVALU], $GUI_SHOW)             GUICtrlSetPos($g_EntryCtrl[$ENT_LBDESC], 70, 100)             GUICtrlSetData($g_EntryCtrl[$ENT_LBDESC], _                 StringFormat("Deletes multiple values from the associated key. Specify multiple values using a " & _                 "semicolon-delimited list.rnExample: type;size;NoRun;NoFind"))             GUICtrlSetState($g_EntryCtrl[$ENT_LBDESC], $GUI_SHOW)         Case $ENTRY_TYPE_DELALLVALS             GUICtrlSetState($g_EntryCtrl[$ENT_LBVALU], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_INVALU], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_LBTYPE], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_CBTYPE], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_LBDATA], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_INDATA], $GUI_HIDE)             GUICtrlSetPos($g_EntryCtrl[$ENT_LBDESC], 70, 68)             GUICtrlSetData($g_EntryCtrl[$ENT_LBDESC], "Deletes all values from the associated key.")             GUICtrlSetState($g_EntryCtrl[$ENT_LBDESC], $GUI_SHOW)         Case $ENTRY_TYPE_DELKEYS             GUICtrlSetState($g_EntryCtrl[$ENT_LBTYPE], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_CBTYPE], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_LBDATA], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_INDATA], $GUI_HIDE)             GUICtrlSetData($g_EntryCtrl[$ENT_LBVALU], "Subkeys:")             GUICtrlSetState($g_EntryCtrl[$ENT_LBVALU], $GUI_SHOW)             GUICtrlSetState($g_EntryCtrl[$ENT_INVALU], $GUI_SHOW)             GUICtrlSetPos($g_EntryCtrl[$ENT_LBDESC], 70, 100)             GUICtrlSetData($g_EntryCtrl[$ENT_LBDESC], _                 StringFormat("Deletes multiple subkeys from the associated key. Specify multiple subkeys using a " & _                 "semicolon-delimited list.rnExample: type;size;NoRun;NoFind"))             GUICtrlSetState($g_EntryCtrl[$ENT_LBDESC], $GUI_SHOW)         Case $ENTRY_TYPE_SECKEY             GUICtrlSetState($g_EntryCtrl[$ENT_LBVALU], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_INVALU], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_LBDATA], $GUI_HIDE)             GUICtrlSetState($g_EntryCtrl[$ENT_INDATA], $GUI_HIDE)             GUICtrlSetPos($g_EntryCtrl[$ENT_LBTYPE], 20, 76)             GUICtrlSetData($g_EntryCtrl[$ENT_LBTYPE], "Secure:")             GUICtrlSetState($g_EntryCtrl[$ENT_LBTYPE], $GUI_SHOW)             GUICtrlSetPos($g_EntryCtrl[$ENT_CBTYPE], 70, 73, 50)             _GUICtrlComboBox_ResetContent($g_EntryCtrl[$ENT_CBTYPE])             GUICtrlSetData($g_EntryCtrl[$ENT_CBTYPE], "False|True", "True")             GUICtrlSetState($g_EntryCtrl[$ENT_CBTYPE], $GUI_SHOW)             GUICtrlSetPos($g_EntryCtrl[$ENT_LBDESC], 70, 100)             GUICtrlSetData($g_EntryCtrl[$ENT_LBDESC], _                 "Secures the associated key, giving administrators and the system full control, and giving " & _                 "users read-only access. If set to False, access to the key resets to whatever is set on the root.")             GUICtrlSetState($g_EntryCtrl[$ENT_LBDESC], $GUI_SHOW)     EndSwitch     $g_EntryCtrl[$ENT_ILASTENTR] = $iSelected EndFunc   ;==>_Ev_cbEntryType Func _Ev_miFileClose()     If Not _CloseFile() Then Return     Exit($GRE_ERROR_NONE) EndFunc   ;==>_Ev_miFileClose Func _Ev_miFileNew()     If Not _CloseFile() Then Return     _OpenFile() EndFunc   ;==>_Ev_miFileNew Func _Ev_miFileOpenFile()     If Not _CloseFile() Then Return     Local $sFilename = FileOpenDialog("Select GPO Registry File", "", "GPO Registry Files (*.pol)|All Files (*.*)", 3, "", $g_MainCtrl[$MAIN_GUI])     If @error Then Return     _OpenFile($sFilename) EndFunc   ;==>_Ev_miFileOpenFile Func _Ev_miFileOpenSystem()     If Not _CloseFile() Then Return     Switch @GUI_CtrlId         Case $g_MainCtrl[$MAIN_MIMPOL]             _OpenFile($MACHINE_REGISTRY_FILE)         Case $g_MainCtrl[$MAIN_MIUPOL]             _OpenFile($USER_REGISTRY_FILE)     EndSwitch EndFunc   ;==>_Ev_miFileOpenSystem Func _Ev_miFileSave()     Switch @GUI_CtrlId         Case $g_MainCtrl[$MAIN_MISAVE]             _SaveFile()         Case $g_MainCtrl[$MAIN_MISAVA]             _SaveFile(True)     EndSwitch EndFunc   ;==>_Ev_miFileSave Func _WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)     Local $tNMHDR, $hWndFrom, $iCode     $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)     $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")     $iCode = DllStructGetData($tNMHDR, "Code")     If $hWndFrom = $g_MainCtrl[$MAIN_LVENTR] And $iCode == $NM_DBLCLK Then _Ev_btEdit()     Return $GUI_RUNDEFMSG EndFunc   ;==>_WM_NOTIFY Func __DebugPrint($sMessage, $sSource = "Info", $bOverride = False)     If Not $g_bDebug And Not $bOverride Then Return     Local $sLine = StringFormat("%02d%02d%04d %02d:%02d:%02d   %-20s %srn", _         @MON, @MDAY, @YEAR, @HOUR, @MIN, @SEC, $sSource, $sMessage)     If @Compiled Then         FileWrite($GRE_LOG_FILE, $sLine)     Else         ConsoleWrite($sLine)     EndIf EndFunc   ;==>__DebugPrint Func __PrintEnvironment()     Local $sEnv = @CRLF     $sEnv &= StringFormat("  OSVersion:    %srn", @OSVersion)     $sEnv &= StringFormat("  OSArch:          %srn", @OSArch)     $sEnv &= StringFormat("  AutoItX64:    %srn", @AutoItX64)     $sEnv &= StringFormat("  WindowsDir:      %srn", @WindowsDir)     $sEnv &= StringFormat("  SystemDir:    %srn", @SystemDir)     $sEnv &= StringFormat("  TempDir:        %srn", @TempDir)     $sEnv &= StringFormat("  ComSpec:        %srn", @ComSpec)     $sEnv &= StringFormat("  ProgramFilesDir: %s", @ProgramFilesDir)     __DebugPrint($sEnv, "__PrintEnvironment", True) EndFunc   ;==>__PrintEnvironment



Enjoy and please let me know if there are any issues.

Attached File  GRE_source.zip   12.53KB   1222 downloads

**Note: On Windows Vista and above, administrator rights are required to save to the system group policy folder. Compile with the requestedExecutionLevel=requireAdministrator directive to ensure administrator access.

Edited by zorphnog, 06 June 2012 - 01:48 PM.








#2 eimhym

eimhym

    Seeker

  • Active Members
  • 21 posts

Posted 01 June 2012 - 01:44 AM

Its very usefull! I always find a way to script it do like block executable/script on USB stick. If you do it manually you will have to create new path rules for each targetted drive letter. One question, is this tool already have export/import feature builtin?

#3 zorphnog

zorphnog

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 445 posts

Posted 01 June 2012 - 01:53 PM

One question, is this tool already have export/import feature builtin?


Currently, there is not an import/export feature. It would certainly be a nice feature to implement, and I may try to add it when I have some free time.

#4 eimhym

eimhym

    Seeker

  • Active Members
  • 21 posts

Posted 01 June 2012 - 03:29 PM

Cool, I look forward to the next version ;) Great tool already, thanks for sharing

#5 KNARZ

KNARZ

    Seeker

  • New Members
  • 2 posts

Posted 27 February 2013 - 08:41 AM

GREAT TOOL!

Edited by KNARZ, 27 February 2013 - 08:42 AM.


#6 h82loze

h82loze

    Seeker

  • New Members
  • 1 posts

Posted 03 June 2013 - 05:27 PM

THANK YOU!  This was exactly what I was looking for.  I also wanted to add a couple of notes.

 

1. When specifying the key with -k, you need to add in the '\' which isn't listed in your example.

2. If you will be using this on both x86 and x64 computers, you will need to compile 2 versions.  One for each architecture.







Also tagged with one or more of these keywords: registry, group policy, editor

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users