#include-once #include ; =============================================================================================================================== ; Title: _RegFunc ; Author: Erik Pilsits ; Version: 2.0.7 ; =============================================================================================================================== ;~ Global Const $REG_NONE = 0 ;~ Global Const $REG_SZ = 1 ;~ Global Const $REG_EXPAND_SZ = 2 ;~ Global Const $REG_BINARY = 3 ;~ Global Const $REG_DWORD = 4 ;~ Global Const $REG_DWORD_BIG_ENDIAN = 5 ;~ Global Const $REG_LINK = 6 ;~ Global Const $REG_MULTI_SZ = 7 ;~ Global Const $REG_RESOURCE_LIST = 8 ;~ Global Const $REG_FULL_RESOURCE_DESCRIPTOR = 9 ;~ Global Const $REG_RESOURCE_REQUIREMENTS_LIST = 10 Global Const $REG_QWORD = 11 Global Const $HKEY_CLASSES_ROOT = 0x80000000 Global Const $HKEY_CURRENT_USER = 0x80000001 Global Const $HKEY_LOCAL_MACHINE = 0x80000002 Global Const $HKEY_USERS = 0x80000003 Global Const $HKEY_PERFORMANCE_DATA = 0x80000004 Global Const $HKEY_PERFORMANCE_TEXT = 0x80000050 Global Const $HKEY_PERFORMANCE_NLSTEXT = 0x80000060 Global Const $HKEY_CURRENT_CONFIG = 0x80000005 Global Const $HKEY_DYN_DATA = 0x80000006 Global Const $KEY_QUERY_VALUE = 0x0001 Global Const $KEY_SET_VALUE = 0x0002 Global Const $KEY_ENUMERATE_SUB_KEYS = 0x0008 Global Const $KEY_WRITE = 0x20006 Global Const $KEY_READ = 0x20019 Global Const $REG_OPTION_NON_VOLATILE = 0x0000 Global Const $REG_OPTION_VOLATILE = 0x0001 Global Const $KEY_WOW64_64KEY = 0x0100 Global Const $KEY_WOW64_32KEY = 0x0200 Global Const $__g_RF_Is64BitOS = (StringInStr(@OSArch, "64") <> 0) #cs x64 Platforms: For all registry functions, the root key may be suffixed with either 32 or 64 to specify the particular registry view on which to operate. For example, HKLM32 will unconditionally reference the 32-bit registry view, while HKLM64 will unconditionally reference the 64-bit registry view. Examples: HKEY_LOCAL_MACHINE32 HKEY_CURRENT_USER64 HKU32 #ce ; #FUNCTION# ==================================================================================================== ; Name...........: _RegRead ; Description....: Read a registry value. ; Syntax.........: _RegRead($szKey, $szValue) ; Parameters.....: $szKey - Source key ; $szValue - Source value (Empty string for Default value) ; ; Return values..: Success - Requested data and value type in @extended ; | Values with no formal type are returned as binary data ; | REG_MULTI_SZ is returned as CRLF delimited substrings ; Failure - 0 and sets @error ; | 1 - Invalid root key ; | 2 - Failed to open source key (@extended contains RegOpenKeyExW return value) ; | 3 - Unsupported value type ; | 4 - Failed to read source value (@extended contains RegQueryValueExW return value) ; Author.........: Erik Pilsits ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _RegRead($szKey, $szValue, $multiszAsBinary = False) Local $hKey = _RegOpenKey($szKey, $KEY_READ) If @error Then Return SetError(@error, @extended, 0) Local $ret = DllCall("advapi32.dll", "long", "RegQueryValueExW", "ulong_ptr", $hKey, "wstr", $szValue, "ptr", 0, "dword*", 0, "ptr", 0, "dword*", 0) If @error Or ($ret[0] <> 0) Then DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey) If IsArray($ret) Then Return SetError(4, $ret[0], 0) Else Return SetError(4, 0, 0) EndIf EndIf Local $iType = $ret[4], $iLen = $ret[6], $sType Switch $iType ; set type of value Case $REG_SZ, $REG_EXPAND_SZ $sType = "wchar" ; iLen is byte length, if unicode string divide by 2 ; add terminating null for possibly incorrectly stored strings ; handling of extra terminating NULLs is automatic by AutoIt 'wchar' type $iLen = ($iLen / 2) + 1 Case $REG_MULTI_SZ ; multiple string value, returned as binary data ; iLen is byte length ; returns binary data, post handling is necessary $sType = "byte" Case $REG_BINARY, $REG_NONE $sType = "byte" Case $REG_QWORD $sType = "int64" $iLen = $iLen / 8 ; int64 = 8 bytes Case $REG_DWORD $sType = "dword" $iLen = $iLen / 4 ; dword = 4 bytes Case 5, 6, 8, 9, 10 ; other uncommon value types, return as binary data $sType = "byte" Case Else ; unknown type DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey) Return SetError(3, 0, 0) EndSwitch Local $lpData = DllStructCreate($sType & "[" & $iLen & "]") $ret = DllCall("advapi32.dll", "long", "RegQueryValueExW", "ulong_ptr", $hKey, "wstr", $szValue, "ptr", 0, "dword*", 0, _ "ptr", DllStructGetPtr($lpData), "dword*", DllStructGetSize($lpData)) DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey) If (Not IsArray($ret)) Or ($ret[0] <> 0) Then If IsArray($ret) Then Return SetError(4, $ret[0], 0) Else Return SetError(4, 0, 0) EndIf EndIf Local $data ; special processing for REG_MULTI_SZ If $iType = $REG_MULTI_SZ Then ; trim all terminating NULLs, convert to string ; if no data, then return empty "" $data = _RegTrimBinary(DllStructGetData($lpData, 1), Binary("0x0000")) If $multiszAsBinary Then If $data Then $data &= Binary("0x00000000") Else If $data Then $data = StringReplace(BinaryToString($data, 2), ChrW(0), @CRLF) Else $data = "" EndIf EndIf Else ; else just get our data $data = DllStructGetData($lpData, 1) EndIf Return SetError(0, $iType, $data) EndFunc ;==>_RegRead Func _RegTrimBinary($data, $pattern) ; trim a repeating binary pattern from the end of binary data ; set starting point to pattern byte size from end (BinaryMid is 1-based, so decrement 1 byte less than pattern length) Local $pLen = BinaryLen($pattern) Local $start = BinaryLen($data) - ($pLen - 1) While 1 If $start < 0 Then ; if start is < 0, then there is no data left ; set start to 0 (returns empty binary variant from BinaryMid) and exit loop $start = 0 ExitLoop EndIf ; test if a terminating null and decrement If BinaryMid($data, $start, $pLen) = $pattern Then $start -= $pLen Else ; found data, increment one byte $start += ($pLen - 1) ExitLoop EndIf WEnd ; get data Return BinaryMid($data, 1, $start) EndFunc ;==>_RegTrimBinary ; #FUNCTION# ==================================================================================================== ; Name...........: _RegWrite ; Description....: Create a registry key or value. ; Syntax.........: _RegWrite($szKey[, $szValue = ""[, $iType = -1[, $bData = Default[, $dwOptions = $REG_OPTION_NON_VOLATILE]]]]) ; Parameters.....: $szKey - Destination key ; $szValue - [Optional] Destination value (Empty string for Default value, must also supply $iType and $bData) ; $iType - [Optional] Type of data to write to $szValue ($iType < 0 writes key only) ; $bData - [Optional] Data to write to $szValue ($bData = Default creates key only) ; $dwOptions - [Optional] Optional flags (can be $REG_OPTION_NON_VOLATILE or $REG_OPTION_VOLATILE) ; ; Return values..: Success - 1 ; Failure - 0 and sets @error ; | 1 - Invalid root key ; | 2 - Failed to open / create destination key (@extended contains RegCreateKeyExW return value) ; | 3 - Unsupported value type ; | 4 - Failed to write data (@extended contains RegSetValueExW return value) ; Author.........: Erik Pilsits ; Modified.......: ; Remarks........: Provide REG_MULTI_SZ values as a single string made up of CRLF or LF separated substrings (as returned from ; AutoIt native RegRead), or as UTF16LE binary data with NULL separated substrings. ; Terminating NULLs for all string data types are correctly appended by the function. ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _RegWrite($szKey, $szValue = "", $iType = -1, $bData = Default, $dwOptions = $REG_OPTION_NON_VOLATILE) Local $hKey = _RegOpenKey($szKey, $KEY_WRITE, False, $dwOptions) ; open using RegCreateKeyExW If @error Then Return SetError(@error, @extended, 0) Local $lpData If $iType >= 0 And $bData <> Default Then Switch $iType ; handle strings as binary data, make sure they are properly terminated Case $REG_SZ, $REG_EXPAND_SZ If VarGetType($bData) <> "Binary" Then $bData = StringToBinary($bData, 2) ; UTF16LE $bData = _RegTrimBinary($bData, "0x0000") & Binary("0x0000") ; add terminating null $lpData = DllStructCreate("byte[" & BinaryLen($bData) & "]") Case $REG_MULTI_SZ If VarGetType($bData) <> "Binary" Then $bData = StringToBinary(StringReplace(StringStripCR($bData), @LF, ChrW(0)), 2) ; UTF16LE $bData = _RegTrimBinary($bData, "0x0000") & Binary("0x00000000") ; add 2 terminating nulls $lpData = DllStructCreate("byte[" & BinaryLen($bData) & "]") Case $REG_DWORD $lpData = DllStructCreate("dword") Case $REG_QWORD $lpData = DllStructCreate("int64") Case $REG_BINARY, $REG_NONE $lpData = DllStructCreate("byte[" & BinaryLen($bData) & "]") Case 5, 6, 8, 9, 10 ; other uncommon value types $lpData = DllStructCreate("byte[" & BinaryLen($bData) & "]") Case Else DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey) Return SetError(3, 0, 0) EndSwitch DllStructSetData($lpData, 1, $bData) Local $ret = DllCall("advapi32.dll", "long", "RegSetValueExW", "ulong_ptr", $hKey, "wstr", $szValue, "dword", 0, "dword", $iType, _ "ptr", DllStructGetPtr($lpData), "dword", DllStructGetSize($lpData)) If @error Or ($ret[0] <> 0) Then If IsArray($ret) Then Return SetError(4, $ret[0], 0) Else Return SetError(4, 0, 0) EndIf EndIf EndIf DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey) Return SetError(0, 0, 1) EndFunc ;==>_RegWrite ; #FUNCTION# ==================================================================================================== ; Name...........: _RegDelete ; Description....: Delete a key (recursively) or value ; Syntax.........: _RegDelete($szKey[, $szValue = Default]) ; Parameters.....: $szKey - Key to delete ; $szValue - [Optional] Value to delete (Default to recursively delete the key) ; ; Return values..: Success - 1 ; Failure - 0 and sets @error ; |-2 - Cannot delete a root key ; |-1 - Target key / value does not exist ; | 1 - Invalid root key ; | 2 - Failed to open subkey (@extended contains RegOpenKeyExW return value) ; | 3 - Failed to delete key / value (@extended contains RegDelete* return value) ; Author.........: Erik Pilsits ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _RegDelete($szKey, $szValue = Default) If $szValue = Default Then If Not _RegKeyExists($szKey) Then Return SetError(-1, 0, 0) ; recursively delete keys Local $key While 1 $key = _RegEnumKey($szKey, 0) ; removing keys, so always enum index 0 If @error Then ExitLoop ; no more keys _RegDelete($szKey & "\" & $key) ; recurse If @error Then Return SetError(@error, @extended, 0) ; avoid infinite loop on recursion error WEnd _RegDeleteKey($szKey) If @error Then Return SetError(@error, @extended, 0) Return SetError(0, 0, 1) Else If Not _RegValueExists($szKey, $szValue) Then Return SetError(-1, 0, 0) ; delete value _RegDeleteValue($szKey, $szValue) If @error Then Return SetError(@error, @extended, 0) Return SetError(0, 0, 1) EndIf EndFunc ;==>_RegDelete Func _RegDeleteKey($szKey) Local $parentKey = StringLeft($szKey, StringInStr($szKey, "\", 0, -1) - 1) If $parentKey = "" Then Return SetError(-2, 0, 0) ; cannot delete root key Local $szSubkey = StringTrimLeft($szKey, StringLen($parentKey) + 1) Local $hKey = _RegOpenKey($parentKey, $KEY_READ) If @error Then Return SetError(@error, @extended, 0) ; check compatibility ; RegDeleteKeyExW does not exist on XP 32-bit and lower or lower than Server 2003 SP1 ; it is not needed at all on 32-bit OS's, so make decision based on that If $__g_RF_Is64BitOS Then Local $ret = DllCall("advapi32.dll", "long", "RegDeleteKeyExW", "ptr", $hKey, "wstr", $szSubkey, "long", @extended, "dword", 0) Else Local $ret = DllCall("advapi32.dll", "long", "RegDeleteKeyW", "ptr", $hKey, "wstr", $szSubkey) EndIf DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey) If (Not IsArray($ret)) Or ($ret[0] <> 0) Then If IsArray($ret) Then Return SetError(3, $ret[0], 0) Else Return SetError(3, 0, 0) EndIf EndIf Return SetError(0, 0, 1) EndFunc ;==>_RegDeleteKey Func _RegDeleteValue($szKey, $szValue) Local $hKey = _RegOpenKey($szKey, $KEY_WRITE) If @error Then Return SetError(@error, @extended, 0) Local $ret = DllCall("advapi32.dll", "long", "RegDeleteValueW", "ptr", $hKey, "wstr", $szValue) DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey) If (Not IsArray($ret)) Or ($ret[0] <> 0) Then If IsArray($ret) Then Return SetError(3, $ret[0], 0) Else Return SetError(3, 0, 0) EndIf EndIf Return SetError(0, 0, 1) EndFunc ;==>_RegDeleteValue ; #FUNCTION# ==================================================================================================== ; Name...........: _RegEnumKey ; Description....: Enumerate subkeys of the specified key ; Syntax.........: _RegEnumKey($szKey, $iIndex) ; Parameters.....: $szKey - Parent key ; $iIndex - 0-based key instance to retrieve ; ; Return values..: Success - Requested registry key name (name only, not full path) ; Failure - 0 and sets @error ; | 1 - Invalid root key ; | 2 - Failed to open key (@extended contains RegOpenKeyExW return value) ; | 3 - Key index out of range (@extended contains RegEnumKeyExW return value) ; Author.........: Erik Pilsits ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _RegEnumKey($szKey, $iIndex) Local $hKey = _RegOpenKey($szKey, $KEY_READ) If @error Then Return SetError(@error, @extended, 0) Local $ret = DllCall("advapi32.dll", "long", "RegEnumKeyExW", "ptr", $hKey, "dword", $iIndex, "wstr", "", "dword*", 1024, "ptr", 0, "ptr", 0, "ptr", 0, "ptr", 0) DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey) If (Not IsArray($ret)) Or ($ret[0] <> 0) Then If IsArray($ret) Then Return SetError(3, $ret[0], 0) Else Return SetError(3, 0, 0) EndIf EndIf Return SetError(0, 0, $ret[3]) EndFunc ;==>_RegEnumKey ; #FUNCTION# ==================================================================================================== ; Name...........: _RegEnumValue ; Description....: Enumerate values of the specified key ; Syntax.........: _RegEnumValue($szKey, $iIndex) ; Parameters.....: $szKey - Parent key ; $iIndex - 0-based value instance to retrieve ; ; Return values..: Success - Requested registry value ; Failure - 0 and sets @error ; | 1 - Invalid root key ; | 2 - Failed to open key (@extended contains RegOpenKeyExW return value) ; | 3 - Value index out of range (@extended contains RegEnumValueW return value) ; Author.........: Erik Pilsits ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _RegEnumValue($szKey, $iIndex) Local $hKey = _RegOpenKey($szKey, $KEY_READ) If @error Then Return SetError(@error, @extended, 0) Local $ret = DllCall("advapi32.dll", "long", "RegEnumValueW", "ptr", $hKey, "dword", $iIndex, "wstr", "", "dword*", 1024, "ptr", 0, "ptr", 0, "ptr", 0, "ptr", 0) DllCall("advapi32.dll", "long", "RegCloseKey", "ulong_ptr", $hKey) If (Not IsArray($ret)) Or ($ret[0] <> 0) Then If IsArray($ret) Then Return SetError(3, $ret[0], 0) Else Return SetError(3, 0, 0) EndIf EndIf Return SetError(0, 0, $ret[3]) EndFunc ;==>_RegEnumValue ; #FUNCTION# ==================================================================================================== ; Name...........: _RegKeyExists ; Description....: Test for the existence of a registry key ; Syntax.........: _RegKeyExists($s_key) ; Parameters.....: $s_key - Key to test ; ; Return values..: Success - 1 ; Failure - 0 and sets @error ; | 1 - Root key does not exist ; | 2 - Target key does not exist ; Author.........: Erik Pilsits ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _RegKeyExists($s_key) _RegRead($s_key, "") ; try to read default value Switch @error Case 1, 2 ; invalid root key | failed to open key Return SetError(@error, 0, 0) Case Else ; key exists Return SetError(0, 0, 1) EndSwitch EndFunc ;==>_RegKeyExists ; #FUNCTION# ==================================================================================================== ; Name...........: _RegValueExists ; Description....: Test for the existence of a registry value ; Syntax.........: _RegValueExists($s_key, $s_val) ; Parameters.....: $s_key - Source key ; $s_val - Value to test ; ; Return values..: Success - 1 ; Failure - 0 and sets @error ; | 1 - Root key does not exist ; | 2 - Target key does not exist ; | 4 - Target value does not exist ; Author.........: Erik Pilsits ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _RegValueExists($s_key, $s_val) _RegRead($s_key, $s_val) ; @error = 3 is 'unsupported value type', implying value still exists Switch @error Case 1, 2, 4 ; invalid root key | failed to open key | failed to read value Return SetError(@error, 0, 0) Case Else Return SetError(0, 0, 1) EndSwitch EndFunc ;==>_RegValueExists ; #FUNCTION# ==================================================================================================== ; Name...........: _RegCopyKey ; Description....: Recursively copy a registry key, including all subkeys and values ; Syntax.........: _RegCopyKey($s_key, $d_key) ; Parameters.....: $s_key - Source key ; $d_key - Destination key ; $delete - [Internal] ; ; Return values..: Success - 1 ; Failure - 0 and sets @error ; |-1 - Source and destination keys are the same ; | 1 - Source does not exist ; | 2 - Failed to write destination key (@extended contains _RegWrite error code) ; | 3 - Failed to read one or more values from source key or subkey(s) ; Author.........: Erik Pilsits ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _RegCopyKey($s_key, $d_key, $delete = False) If $s_key = $d_key Then Return SetError(-1, 0, 0) ; destination is the same as source If Not _RegKeyExists($s_key) Then Return SetError(1, 0, 0) _RegWrite($d_key) ; write destination key in case source key empty If @error Then Return SetError(2, @error, 0) ; value loop Local $i = 0, $val, $data, $err = 0 While 1 $val = _RegEnumValue($s_key, $i) If @error Then ExitLoop ; no more values _RegCopyValue($s_key, $val, $d_key) If @error Then $err = 3 ContinueLoop ; some error reading value, skip it EndIf $i += 1 WEnd ; key loop Local $key $i = 0 While 1 $key = _RegEnumKey($s_key, $i) If @error Then ExitLoop ; no more keys _RegCopyKey($s_key & "\" & $key, $d_key & "\" & $key) ; recurse If @error = 3 Then $err = 3 ; test for errors reading subkey values $i += 1 WEnd If $err Then Return SetError($err, 0, 0) ; error(s) reading value(s) or subkey value(s) ; move key If $delete Then ; delete source key only if copy was entirely successful _RegDelete($s_key) If @error Then Return SetError(4, @error, 0) ; error deleting source key EndIf Return SetError(0, 0, 1) EndFunc ;==>_RegCopyKey ; #FUNCTION# ==================================================================================================== ; Name...........: _RegMoveKey ; Description....: Move a registry key, including all subkeys and values ; Syntax.........: _RegMoveKey($s_key, $d_key) ; Parameters.....: $s_key - Source key ; $d_key - Destination key ; ; Return values..: Success - 1 ; Failure - 0 and sets @error ; |-1 - Source and destination keys are the same ; | 1 - Source does not exist ; | 2 - Failed to write destination key (@extended contains _RegWrite error code) ; | 3 - Failed to read one or more values from source key or subkey(s) ; | 4 - Failed to delete source key (@extended contains _RegDelete error code) ; Author.........: Erik Pilsits ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _RegMoveKey($s_key, $d_key) Local $ret = _RegCopyKey($s_key, $d_key, True) Return SetError(@error, @extended, $ret) EndFunc ;==>_RegMoveKey ; #FUNCTION# ==================================================================================================== ; Name...........: _RegCopyValue ; Description....: Copy a single registry value ; Syntax.........: _RegCopyValue($s_key, $s_val[, $d_key = Default[, $d_val = Default]]) ; Parameters.....: $s_key - Source key ; $s_val - Source value ; $d_key - [Optional] Destination key (Default to use Source key) ; $d_val - [Optional] Destination value (Default to use Source value) ; $delete - [Internal] ; ; Return values..: Success - 1 ; Failure - 0 and sets @error ; |-1 - Source and destination are the same ; | 1 - Source value does not exist ; | 2 - Failed to read source value (@extended contains _RegRead error code) ; | 3 - Failed to write destination value (@extended contains _RegWrite error code) ; Author.........: Erik Pilsits ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _RegCopyValue($s_key, $s_val, $d_key = Default, $d_val = Default, $delete = False) If $d_key = Default Then $d_key = $s_key ; set destination key to source key If $d_val = Default Then $d_val = $s_val ; set destination value to source value If $s_key = $d_key And $s_val = $d_val Then Return SetError(-1, 0, 0) ; destination is the same as source If Not _RegValueExists($s_key, $s_val) Then Return SetError(1, 0, 0) Local $data = _RegRead($s_key, $s_val) If @error Then Return SetError(2, @error, 0) ; error reading value _RegWrite($d_key, $d_val, @extended, $data) If @error Then Return SetError(3, @error, 0) ; error writing destination value If $delete Then ; delete source value only if copy was successful _RegDelete($s_key, $s_val) If @error Then Return SetError(4, @error, 0) ; error deleting source value EndIf Return SetError(0, 0, 1) EndFunc ;==>_RegCopyValue ; #FUNCTION# ==================================================================================================== ; Name...........: _RegMoveValue ; Description....: Move a single registry value ; Syntax.........: _RegMoveValue($s_key, $s_val[, $d_key = Default[, $d_val = Default]]) ; Parameters.....: $s_key - Source key ; $s_val - Source value ; $d_key - [Optional] Destination key (Default to use Source key) ; $d_val - [Optional] Destination value (Default to use Source value) ; ; Return values..: Success - 1 ; Failure - 0 and sets @error ; |-1 - Source and destination are the same ; | 1 - Source value does not exist ; | 2 - Failed to read source value (@extended contains _RegRead error code) ; | 3 - Failed to write destination value (@extended contains _RegWrite error code) ; | 4 - Failed to delete source value (@extended contains _RegDelete error code) ; Author.........: Erik Pilsits ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _RegMoveValue($s_key, $s_val, $d_key = Default, $d_val = Default) Local $ret = _RegCopyValue($s_key, $s_val, $d_key, $d_val, True) Return SetError(@error, @extended, $ret) EndFunc ;==>_RegMoveValue ; #FUNCTION# ==================================================================================================== ; Name...........: _RegKeyEmpty ; Description....: Test if a registry key is empty of all subkeys and values ; Syntax.........: _RegKeyEmpty($s_key) ; Parameters.....: $s_key - Key to test ; ; Return values..: Success - 1 ; Failure - 0 and sets @error ; | 1 - Key contains subkeys ; | 2 - Key contains values ; | 3 - Key contains subkeys and values ; Author.........: Erik Pilsits ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _RegKeyEmpty($s_key) Local $err = 3 ; check for keys _RegEnumKey($s_key, 0) If @error Then $err -= 1 ; check for values _RegEnumValue($s_key, 0) If @error Then $err -= 2 If $err Then ; not empty Return SetError($err, 0, 0) Else Return SetError(0, 0, 1) EndIf EndFunc ;==>_RegKeyEmpty ; #FUNCTION# ==================================================================================================== ; Name...........: _RegSubkeySearch ; Description....: Search the subkeys of a registry key for the search term and return the index ; Syntax.........: _RegSubkeySearch($s_key, $s_search[, $s_mode = 0[, $s_case = 0]]) ; Parameters.....: $s_key - Key to search ; $s_search - Searchterm ; $s_mode - [Optional] Search mode: 0 - substring search, 1 - search from beginning of key ; $s_case - [Optional] Search case sense: 0 - case insensitive, 1 - case sensitive ; ; Return values..: Success - Index of the subkey ; Failure - 0 ; Author.........: Erik Pilsits ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _RegSubkeySearch($s_key, $s_search, $s_mode = 0, $s_case = 0) ; success returns subkey index ; failure returns 0 Local $i = 0, $key, $string Local $len = StringLen($s_search) While 1 $key = _RegEnumKey($s_key, $i) If @error Then Return 0 ; no more keys Switch $s_mode Case 0 ; substring If StringInStr($key, $s_search, $s_case) Then Return $i Case 1 ; beginning of string $string = StringLeft($key, $len) Switch $s_case Case 0 ; case insensitive If $string = $s_search Then Return $i Case 1 ; case sensitive If $string == $s_search Then Return $i EndSwitch EndSwitch $i += 1 WEnd EndFunc ;==>_RegSubkeySearch ; #FUNCTION# ==================================================================================================== ; Name...........: _RegExport ; Description....: Export a key including all subkeys and values, or a single value to a MS compatible REG file ; Syntax.........: _RegExport($d_file, $s_key[, $s_val = Default[, $fFirstKey = True[, $hFile = -1]]]) ; Parameters.....: $d_file - Destination exported REG file ; $s_key - Source key to be exported ; $s_val - [Optional] Source value (Default for recursive export, otherwise single value export) ; $fFirstKey - [Internal] ; $hFile - [Internal] ; ; Return values..: Success - 1 ; Failure - 0 and sets @error ; | 1 - Source key does not exist ; | 2 - Source value does not exist ; | 3 - Unable to create destination REG file ; | 4 - Error reading one or more values ; Author.........: Erik Pilsits ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _RegExport($d_file, $s_key, $s_val = Default, $fFirstKey = True, $hFile = -1) If Not _RegKeyExists($s_key) Then Return SetError(1, 0, 0) Local $data, $err = 0 If $fFirstKey Then ; first iteration, create new file $hFile = FileOpen($d_file, 2 + 32) ; create a new UTF16LE file If $hFile = -1 Then Return SetError(3, 0, 0) FileWriteLine($hFile, "Windows Registry Editor Version 5.00" & @CRLF) If $s_val <> Default Then ; exporting only one value If Not _RegValueExists($s_key, $s_val) Then FileClose($hFile) Return SetError(2, 0, 0) EndIf ; write base key FileWriteLine($hFile, @CRLF & "[" & _RegFormatHeader($s_key) & "]") $data = _RegRead($s_key, $s_val, True) If @error Then FileClose($hFile) Return SetError(4, 0, 0) ; unsupported value type EndIf Switch @extended Case $REG_LINK ; unsupported value type FileClose($hFile) Return SetError(4, 0, 0) Case Else ; format value If $s_val = "" Then $s_val = "@" ; write data _RegWriteFile($hFile, $s_val, $data, @extended) FileClose($hFile) Return SetError(0, 0, 1) EndSwitch EndIf EndIf ; write base key FileWriteLine($hFile, @CRLF & "[" & _RegFormatHeader($s_key) & "]") ; value loop Local $i = -1, $val While 1 $i += 1 $val = _RegEnumValue($s_key, $i) If @error Then ExitLoop ; no more values $data = _RegRead($s_key, $val, True) If @error Then ; unsupported value type $err = 4 ContinueLoop EndIf Switch @extended Case $REG_LINK ; unsupported value type $err = 4 ContinueLoop Case Else ; format value If $val = "" Then $val = "@" ; write data _RegWriteFile($hFile, $val, $data, @extended) EndSwitch WEnd ; key loop Local $key $i = -1 While 1 $i += 1 $key = _RegEnumKey($s_key, $i) If @error Then ExitLoop ; no more keys ; recurse _RegExport("", $s_key & "\" & $key, Default, False, $hFile) If @error Then $err = 4 ; catch recursion errors WEnd If $fFirstKey Then FileClose($hFile) Return SetError($err, 0, Number(Not $err)) EndFunc ;==>_RegExport Func _RegWriteFile($hFile, $val, $data, $type) If $val <> "@" Then $val = '"' & _RegEscape($val) & '"' ; Switch $type Case $REG_NONE ; returned as binary If Not $data Then FileWriteLine($hFile, $val & '=hex(0):') Else FileWriteLine($hFile, _RegFormatData($val & '=hex(0):', StringLower($data))) EndIf Case $REG_SZ ; returned as string, not NULL terminated FileWriteLine($hFile, $val & '="' & _RegEscape($data) & '"') Case $REG_EXPAND_SZ ; returned as string, not NULL terminated If Not $data Then FileWriteLine($hFile, $val & '=hex(2):00,00') Else FileWriteLine($hFile, _RegFormatData($val & '=hex(2):', StringLower(StringToBinary($data, 2)) & "0000")) EndIf Case $REG_BINARY ; returned as binary If Not $data Then FileWriteLine($hFile, $val & '=hex:') Else FileWriteLine($hFile, _RegFormatData($val & '=hex:', StringLower($data))) EndIf Case $REG_DWORD ; returned as dword FileWriteLine($hFile, $val & "=dword:" & StringLower(Hex($data, 8))) Case $REG_DWORD_BIG_ENDIAN ; returned as binary FileWriteLine($hFile, _RegFormatData($val & '=hex(5):', StringLower($data))) Case $REG_MULTI_SZ ; returned as binary, double NULL terminated If Not $data Then FileWriteLine($hFile, $val & '=hex(7):00,00') Else FileWriteLine($hFile, _RegFormatData($val & '=hex(7):', StringLower($data))) EndIf Case $REG_RESOURCE_LIST ; returned as binary If Not $data Then FileWriteLine($hFile, $val & '=hex(8):') Else FileWriteLine($hFile, _RegFormatData($val & '=hex(8):', StringLower($data))) EndIf Case $REG_FULL_RESOURCE_DESCRIPTOR ; returned as binary If Not $data Then FileWriteLine($hFile, $val & '=hex(9):') Else FileWriteLine($hFile, _RegFormatData($val & '=hex(9):', StringLower($data))) EndIf Case $REG_RESOURCE_REQUIREMENTS_LIST ; returned as binary If Not $data Then FileWriteLine($hFile, $val & '=hex(a):') Else FileWriteLine($hFile, _RegFormatData($val & '=hex(a):', StringLower($data))) EndIf Case $REG_QWORD ; returned as qword If Not $data Then FileWriteLine($hFile, $val & '=hex(b):00,00,00,00,00,00,00,00') Else FileWriteLine($hFile, _RegFormatData($val & '=hex(b):', StringLower(Binary($data)))) EndIf EndSwitch EndFunc ;==>_RegWriteFile Func _RegEscape($string) Return StringRegExpReplace($string, '([\\"])', "\\${1}") EndFunc ;==>_RegEscape Func _RegFormatData($prefix, $data) Local $temp = "", $temp2 = $prefix Local $j = 3, $len = StringLen($data) While $j < $len While $j < $len And StringLen($temp2) < 77 $temp2 &= StringMid($data, $j, 2) & "," $j += 2 WEnd $temp &= $temp2 & "\" & @CRLF $temp2 = " " WEnd Return StringTrimRight($temp, 4) EndFunc ;==>_RegFormatData Func _RegFormatHeader($szHeader) Local $szRoot = StringLeft($szHeader, StringInStr($szHeader, "\") - 1) If $szRoot = "" Then $szRoot = $szHeader ; passed root key $szHeader = StringTrimLeft($szHeader, StringLen($szRoot)) Switch $szRoot Case "HKEY_LOCAL_MACHINE", "HKLM", "HKEY_LOCAL_MACHINE32", "HKLM32", "HKEY_LOCAL_MACHINE64", "HKLM64" $szRoot = "HKEY_LOCAL_MACHINE" Case "HKEY_USERS", "HKU", "HKEY_USERS32", "HKU32", "HKEY_USERS64", "HKU64" $szRoot = "HKEY_USERS" Case "HKEY_CURRENT_USER", "HKCU", "HKEY_CURRENT_USER32", "HKCU32", "HKEY_CURRENT_USER64", "HKCU64" $szRoot = "HKEY_CURRENT_USER" Case "HKEY_CLASSES_ROOT", "HKCR" $szRoot = "HKEY_CLASSES_ROOT" Case "HKEY_CURRENT_CONFIG", "HKCC" $szRoot = "HKEY_CURRENT_CONFIG" Case Else ; EndSwitch Return $szRoot & $szHeader EndFunc ;==>_RegFormatHeader Func _RegOpenKey($szKey, $iAccess, $fOpen = True, $dwOptions = $REG_OPTION_NON_VOLATILE) ; $iView is set and returned because RegDeleteKeyEx takes the 32/64 registry view flag determined in this function Local $iView = 0 Local $hRoot = StringLeft($szKey, StringInStr($szKey, "\") - 1) If $hRoot = "" Then $hRoot = $szKey ; passed a root key Switch $hRoot Case "HKEY_LOCAL_MACHINE", "HKLM" $hRoot = $HKEY_LOCAL_MACHINE Case "HKEY_LOCAL_MACHINE32", "HKLM32" $hRoot = $HKEY_LOCAL_MACHINE $iAccess = BitOR($iAccess, $KEY_WOW64_32KEY) $iView = $KEY_WOW64_32KEY Case "HKEY_LOCAL_MACHINE64", "HKLM64" $hRoot = $HKEY_LOCAL_MACHINE $iAccess = BitOR($iAccess, $KEY_WOW64_64KEY) $iView = $KEY_WOW64_64KEY Case "HKEY_USERS", "HKU" $hRoot = $HKEY_USERS Case "HKEY_USERS32", "HKU32" $hRoot = $HKEY_USERS $iAccess = BitOR($iAccess, $KEY_WOW64_32KEY) $iView = $KEY_WOW64_32KEY Case "HKEY_USERS64", "HKU64" $hRoot = $HKEY_USERS $iAccess = BitOR($iAccess, $KEY_WOW64_64KEY) $iView = $KEY_WOW64_64KEY Case "HKEY_CURRENT_USER", "HKCU" $hRoot = $HKEY_CURRENT_USER Case "HKEY_CURRENT_USER32", "HKCU32" $hRoot = $HKEY_CURRENT_USER $iAccess = BitOR($iAccess, $KEY_WOW64_32KEY) $iView = $KEY_WOW64_32KEY Case "HKEY_CURRENT_USER64", "HKCU64" $hRoot = $HKEY_CURRENT_USER $iAccess = BitOR($iAccess, $KEY_WOW64_64KEY) $iView = $KEY_WOW64_64KEY Case "HKEY_CLASSES_ROOT", "HKCR" $hRoot = $HKEY_CLASSES_ROOT Case "HKEY_CURRENT_CONFIG", "HKCC" $hRoot = $HKEY_CURRENT_CONFIG Case Else Return SetError(1, 0, 0) EndSwitch Local $szSubkey = StringTrimLeft($szKey, StringInStr($szKey, "\")) If $szSubkey = $szKey Then $szSubkey = "" ; root key Local $ret If $fOpen Then ; RegOpenKeyExW $ret = DllCall("advapi32.dll", "long", "RegOpenKeyExW", "ulong_ptr", $hRoot, "wstr", $szSubkey, "dword", 0, "ulong", $iAccess, "ulong_ptr*", 0) If @error Or ($ret[0] <> 0) Then If IsArray($ret) Then Return SetError(2, $ret[0], 0) Else Return SetError(2, 0, 0) EndIf EndIf Return SetError(0, $iView, $ret[5]) Else ; RegCreateKeyExW, really just for _RegWrite $ret = DllCall("advapi32.dll", "long", "RegCreateKeyExW", "ulong_ptr", $hRoot, "wstr", $szSubkey, "dword", 0, "ptr", 0, "dword", $dwOptions, _ "ulong", $iAccess, "ptr", 0, "ulong_ptr*", 0, "ptr*", 0) If @error Or ($ret[0] <> 0) Then If IsArray($ret) Then Return SetError(2, $ret[0], 0) Else Return SetError(2, 0, 0) EndIf EndIf Return SetError(0, $iView, $ret[8]) EndIf EndFunc ;==>_RegOpenKey Func _TypeToString($iType) Local $sType Switch $iType Case $REG_NONE $sType = "REG_NONE" Case $REG_SZ $sType = "REG_SZ" Case $REG_EXPAND_SZ $sType = "REG_EXPAND_SZ" Case $REG_BINARY $sType = "REG_BINARY" Case $REG_DWORD $sType = "REG_DWORD" Case $REG_DWORD_BIG_ENDIAN $sType = "REG_DWORD_BIG_ENDIAN" Case $REG_LINK $sType = "REG_LINK" Case $REG_MULTI_SZ $sType = "REG_MULTI_SZ" Case $REG_RESOURCE_LIST $sType = "REG_RESOURCE_LIST" Case $REG_FULL_RESOURCE_DESCRIPTOR $sType = "REG_FULL_RESOURCE_DESCRIPTOR" Case $REG_RESOURCE_REQUIREMENTS_LIST $sType = "REG_RESOURCE_REQUIREMENTS_LIST" Case $REG_QWORD $sType = "REG_QWORD" Case Else $sType = "UNKNOWN" EndSwitch Return $sType EndFunc ;==>_TypeToString ;~ ;; EXAMPLE ;~ ; just create a key ;~ _RegWrite("HKCU\Software\AAB Test") ;~ ; sets the default value ;~ _RegWrite("HKCU\Software\AAA Test", "", $REG_SZ, "default value") ;~ $read = _RegRead("HKCU\Software\AAA Test", "") ;~ ConsoleWrite("Type: " & _TypeToString(@extended) & @CRLF) ;~ ConsoleWrite("Data: " & $read & @CRLF) ;~ ; writes an empty reg_none value ;~ _RegWrite("HKCU\Software\AAA Test", "value1", $REG_NONE, "") ;~ $read = _RegRead("HKCU\Software\AAA Test", "value1") ;~ ConsoleWrite("Type: " & _TypeToString(@extended) & @CRLF) ;~ ConsoleWrite("Data: " & $read & @CRLF) ;~ ; writes some string data as binary ;~ _RegWrite("HKCU\Software\AAA Test", "value2", $REG_BINARY, "test data") ;~ $read = _RegRead("HKCU\Software\AAA Test", "value2") ;~ ConsoleWrite("Type: " & _TypeToString(@extended) & @CRLF) ;~ ConsoleWrite("Data: " & $read & " (" & BinaryToString($read) & ")" & @CRLF) ;~ ; writes some binary data ;~ _RegWrite("HKCU\Software\AAA Test", "value3", $REG_BINARY, Binary("0x02000000")) ;~ $read = _RegRead("HKCU\Software\AAA Test", "value3") ;~ ConsoleWrite("Type: " & _TypeToString(@extended) & @CRLF) ;~ ConsoleWrite("Data: " & $read & @CRLF) ;~ ; write a string ;~ _RegWrite("HKCU\Software\AAA Test", "value4", $REG_SZ, "here is a string") ;~ $read = _RegRead("HKCU\Software\AAA Test", "value4") ;~ ConsoleWrite("Type: " & _TypeToString(@extended) & @CRLF) ;~ ConsoleWrite("Data: " & $read & @CRLF) ;~ ; write an integer ;~ _RegWrite("HKCU\Software\AAA Test", "value5", $REG_DWORD, 123456) ;~ $read = _RegRead("HKCU\Software\AAA Test", "value5") ;~ ConsoleWrite("Type: " & _TypeToString(@extended) & @CRLF) ;~ ConsoleWrite("Data: " & $read & @CRLF) ;~ ; delete the keys ;~ _RegDelete("HKCU\Software\AAB Test") ;~ _RegDelete("HKCU\Software\AAA Test")