#RequireAdmin #Region ;**** Global vars for Registry Function **** If Not IsDeclared("arDllCall") Then Global Static $arDllCall Global Const $hKernel32DLL = DllOpen("Kernel32.dll") Global Const $hAdvapi32Dll = DllOpen("AdvApi32.dll") Global Const $hShlwapiDll = DllOpen("Shlwapi.dll") Global Const $_WIN32_WINNT5 = StringRegExp(@OSVersion, "(?i)WIN_(?:XP|XPe|2000|2003)") Global Const $_WIN32_WINNT = $_WIN32_WINNT5 ? 5 : 6 ;;Global Static $iTokenPrivilegesState ;; ;; Reserved Key Handles. ;; 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_CURRENT_CONFIG = 0x80000005 Global Const $HKEY_DYN_DATA = 0x80000006 Global Const $HKEY_CURRENT_USER_LOCAL_SETTINGS = 0x80000007 Global Const $HKEY_PERFORMANCE_TEXT = 0x80000050 Global Const $HKEY_PERFORMANCE_NLSTEXT = 0x80000060 Global Const $SE_REGISTRY_KEY = 4 ;; Indicates a registry key. A registry key object can be in the local registry, such as CLASSES_ROOT\SomePath or in a remote registry, such as \\ComputerName\CLASSES_ROOT\SomePath. The names of registry keys must use the following literal strings to identify the predefined registry keys: "CLASSES_ROOT", "CURRENT_USER", "MACHINE", and "USERS". Global Const $SE_REGISTRY_WOW64_32KEY = 12 ;; Indicates an object for a registry entry under WOW64. Global Const $KEY_WOW64_64KEY = 0x0100 ;; Indicates that an application on 64-bit Windows should operate on the 64-bit registry view. This flag is ignored by 32-bit Windows. For more information, see Accessing an Alternate Registry View. This flag must be combined using the OR operator with the other flags in this table that either query or access registry values. Global Const $KEY_WOW64_32KEY = 0x0200 ;; Indicates that an application on 64-bit Windows should operate on the 32-bit registry view. This flag is ignored by 32-bit Windows. For more information, see Accessing an Alternate Registry View. This flag must be combined using the OR operator with the other flags in this table that either query or access registry values. Global Const $KEY_WOW64_RES = 0x0300 Global Const $HKEY_PREDEFINED[11][6] = [[0x80000000,"HKCR","CLASSES_ROOT","\Registry\Machine\SOFTWARE\Classes","HKEY_CLASSES_ROOT","HKCR"],[0x80000001,"HKCU","CURRENT_USER","\Registry\User\CurrentUser","HKEY_CURRENT_USER","HKCU"],[0x80000002,"HKLM","MACHINE","\Registry\Machine","HKEY_LOCAL_MACHINE","HKLM"],[0x80000003,"HKU","USERS","\Registry\User","HKEY_USERS","HKU"],[0x80000005,"HKLM","MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles\Current","\Registry\Machine\SYSTEM\CurrentControlSet\Hardware Profiles\Current","HKEY_CURRENT_CONFIG","HKCC"],[0x80000007,"HKCU","CURRENT_USER\Software\Classes\Local Settings","\Registry\User\CurrentUser\Software\Classes\Local Settings","HKEY_CURRENT_USER_LOCAL_SETTINGS","HKLS"],[0x80000004,"HKPD","PERFORMANCE_DATA\","","HKEY_PERFORMANCE_DATA","HKPD"],[0x80000006,"HKDD","DYN_DATA\","","HKEY_DYN_DATA","HKDD"],[0x80000050,"HKPT","PERFORMANCE_TEXT\","","HKEY_PERFORMANCE_TEXT","HKPT"],[0x80000060,"HKPN","PERFORMANCE_NLSTEXT\","","HKEY_PERFORMANCE_NLSTEXT","HKPN"],[0,";",0,""]] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; NT Defined Privileges ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Global Const $SE_DEBUG_NAME = "SeDebugPrivilege" Global Const $SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege" Global Const $SE_SECURITY_NAME = "SeSecurityPrivilege" Global Const $SE_BACKUP_NAME = "SeBackupPrivilege" Global Const $SE_RESTORE_NAME = "SeRestorePrivilege" Global Const $SE_CREATE_SYMBOLIC_LINK_NAME = "SeCreateSymbolicLinkPrivilege" Global Static $aTokenPrivilegesNewState[6][2] = [[$SE_RESTORE_NAME,2],[$SE_BACKUP_NAME,2],[$SE_SECURITY_NAME,2],[$SE_TAKE_OWNERSHIP_NAME,2],[$SE_DEBUG_NAME,2],[$SE_CREATE_SYMBOLIC_LINK_NAME,2]] Global Static $aTokenPrivilegesPreviousState = _WinAPI_SetPrivilegeEx($aTokenPrivilegesNewState) Global Const $REG_SPECIAL_ACCESS = (IsDeclared("iTokenPrivilegesState") ? 4 : 0) ;; $REG_OPTION_BACKUP_RESTORE = 4 - open for backup or restore special access rules privilege required Global Const $KEY_ALL_ACCESS = 0x000F003F ;; BitOr($STANDARD_RIGHTS_REQUIRED, $KEY_QUERY_VALUE, $KEY_SET_VALUE, $KEY_CREATE_SUB_KEY, $KEY_ENUMERATE_SUB_KEYS, $KEY_NOTIFY, $KEY_CREATE_LINK) Global Static $BA_SIDS Global Static $US_SIDS Global Const $PSIDADMIN = _GetUserSid("BA") #EndRegion ;**** Global vars for Registry Function **** ; #FUNCTION# ==================================================================================================================================== ; Name...........: _WinAPI_SetPrivilegeEx ; Description ...: Enables or disables special privileges as required by some DllCalls ; Syntax.........: _WinAPI_SetPrivilegeEx($avPrivilege) ; Parameters ....: $avPrivilege - An array of privileges and respective attributes ; $SE_PRIVILEGE_ENABLED - The function enables the privilege ; $SE_PRIVILEGE_REMOVED - The privilege is removed from the list of privileges in the token ; 0 - The function disables the privilege ; Requirement(s).: None ; Return values .: Success - An array of modified privileges and their respective previous attribute state ; Failure - An empty array ; Sets @Error ; Author ........: engine ; Modified.......: FredAI, DXRW4E ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; =============================================================================================================================================== Func _WinAPI_SetPrivilegeEx($avPrivilege) ;;$iTokenPrivilegesState = $iTokenPrivilegesState ? 0 : 1 If Not UBound($avPrivilege) Then Return SetError(1, 0, 0) Local $tagTP = "DWORD", $iTokens = UBound($avPrivilege), $iError = 0, $iCount For $i = 1 To $iTokens $tagTP &= ";DWORD;LONG;DWORD" Next Local $tCurrState = DLLStructCreate($tagTP), $tPrevState = DllStructCreate($tagTP), $tLUID = DllStructCreate("DWORD;LONG") DLLStructSetData($tCurrState, 1, $iTokens) For $i = 0 To $iTokens - 1 DllCall($hAdvapi32Dll, "BOOL", "LookupPrivilegeValueW", "WSTR", Null, "WSTR", $avPrivilege[$i][0], "STRUCT*", $tLUID) DLLStructSetData($tCurrState, 3 * $i + 2, DllStructGetData($tLUID, 1)) DLLStructSetData($tCurrState, 3 * $i + 3, DllStructGetData($tLUID, 2)) DLLStructSetData($tCurrState, 3 * $i + 4, $avPrivilege[$i][1]) Next Local $hToken = DllCall($hAdvapi32Dll, "BOOL", "OpenProcessToken", "HANDLE", DllCall($hKernel32DLL, "HANDLE", "GetCurrentProcess")[0], "DWORD", 40, "HANDLE*", 0)[3] ;; TOKEN_ADJUST_PRIVILEGES + TOKEN_QUERY = 40 DllCall($hAdvapi32Dll, "BOOL", "AdjustTokenPrivileges", "HANDLE", $hToken, "BOOL", False, "STRUCT*", $tCurrState, "DWORD", DllStructGetSize($tCurrState), "STRUCT*", $tPrevState, "DWORD*", 0) $iError = DllCall($hKernel32DLL, "DWORD", "GetLastError")[0] DllCall($hKernel32DLL, "BOOL", "CloseHandle", "HANDLE", $hToken) $iCount = DllStructGetData($tPrevState, 1) If $iCount < 1 Then Return SetError($iError, 0, 0) Local $pLUID, $tName, $avPrevState[$iCount][2], $pPrevState = DllStructGetPtr($tPrevState) For $i = 0 To $iCount - 1 $pLUID = $pPrevState + 12 * $i + 4 $tName = DllStructCreate("WCHAR[" & DllCall($hAdvapi32Dll, "BOOL", "LookupPrivilegeNameW", "WSTR", Null, "PTR", $pLUID, "PTR", 0, "DWORD*", 0)[4] & "]") DllCall($hAdvapi32Dll, "BOOL", "LookupPrivilegeNameW", "WSTR", Null, "PTR", $pLUID, "STRUCT*", $tName, "DWORD*", DllStructGetSize($tName)) $avPrevState[$i][0] = DllStructGetData($tName, 1) $avPrevState[$i][1] = DllStructGetData($tPrevState, 3 * $i + 4) Next Return SetError($iError, 1, $avPrevState) EndFunc ;==> _WinAPI_SetPrivilegeEx ; #FUNCTION# ==================================================================================================================== ; Name...........: _GetUserSid ; Description ...: Get BUILTIN ADMINISTRATORS a binary SID ; Syntax.........: _GetUserSid() ; Parameters ....: $SDDLUser - SDDL User ; Return values .: Success - BUILTIN ADMINISTRATORS SID in a byte structure ; Author ........: Paul Campbell (PaulIA) & trancexx ; Modified.......: DXRW4E ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func _GetUserSid($SDDLUser = "BA") Local $SIDS, $SIDSB, $PSID = DllCall($hAdvapi32Dll, "BOOL", "ConvertStringSidToSidW", "WSTR", $SDDLUser, "PTR*", 0) If @Error Or Not $PSID[0] Then $SIDS = DllStructCreate("byte Data[16]") DllStructSetData($SIDS, "Data", "0x01020000000000052000000020020000") Else $SIDSB = DllCall($hAdvapi32Dll, "DWORD", "GetLengthSid", "PTR", $PSID[2]) $SIDS = DllStructCreate("byte Data[" & $SIDSB[0] & "]") DllStructSetData($SIDS, "Data", DllStructGetData(DllStructCreate("byte Data[" & $SIDSB[0] & "]", $PSID[2]), "Data")) DllCall($hKernel32DLL, "PTR", "LocalFree", "PTR", $PSID[2]) EndIf If $SDDLUser = "BA" Then $BA_SIDS = $SIDS Else $US_SIDS = $SIDS EndIf Return DllStructGetPtr($SIDS) EndFunc ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegOpenKey ; Description ...: Opens the specified registry key. ; If the calling thread has not the $SE_BACKUP_NAME and $SE_RESTORE_NAME privilege enabled, the function fails ; Syntax.........: _WinAPI_RegOpenKey($hKey[, $sSubKey[, $samDesired[, $ulOptions]]) ; Parameters ....: $hKey - A handle to an open registry key. This handle is returned by the _WinAPI_RegCreateKeyEx or _WinAPI_RegOpenKeyEx ; or _WinAPI_RegCreateKey or _WinAPI_RegOpenKey function, or it can be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_USERS ; This parameter can be NULL, use the NULL or 0 to set NULL this parameter, If $hKey is NULL, ; $sSubKey must be contain Full String KeyName, for more see $sSubKey ; $sSubKey - Optional, The name of the registry key to be opened. Key names are not case sensitive. ; This key must be a subkey of the key identified by the $hKey parameter. ; if $hKey is Null this key must be a Full String KeyName, example ; "HKLM\SOFTWARE\Example" or "HKEY_USERS" or "HKEY_CURRENT_USER\Software" ; "\Registry\Machine\SOFTWARE\Example" or "\Registry\User" or "\Registry\User\CurrentUser" ; "MACHINE\Software\Example" or "USERS" or "CURRENT_USER\Software" ; "CLASSES_ROOT\Example" or in a remote registry such as \\ComputerName\CLASSES_ROOT\Example. ; If this parameter is NULL or an empty string, the function returns the same handle that was passed in. ; $samDesired - Optional, An access mask the specifies the platform-specific view of the registry. ; | This parameter can be one of the following values, These flags are ignored by 32-bit Windows ; |$KEY_WOW64_64KEY (256) - operate on the 64-bit registry view ; |$KEY_WOW64_32KEY (512) - operate on the 32-bit registry view ; $ulOptions - Optional, This parameter is reserved and must be zero. ; | however will have to support flags such as ; |$REG_OPTION_OPEN_LINK (8) - Open symbolic link, query L"SymbolicLinkValue" or set L"SymbolicLinkValue" ; Return values .: If the function succeeds, the return value is a handle to the opened key and set ERROR_SUCCESS error code ; If the function fails, the return value is a 0, and set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: The _WinAPI_RegOpenKey function ignores the security access mask and attempts to open the key (Not Volatile) with the ; access required to backup or restore the key. If the calling thread has the $SE_BACKUP_NAME privilege enabled, ; the key is opened with the ACCESS_SYSTEM_SECURITY and KEY_READ access rights. If the calling thread has ; the $SE_RESTORE_NAME privilege enabled, beginning with Windows Vista, the key is opened with the ; $ACCESS_SYSTEM_SECURITY, $DELETE and $KEY_WRITE access rights. If both privileges are enabled, the key has ; the combined access rights for both privileges. For more information, see Running with Special Privileges msdn.microsoft.com/en-us/library/windows/desktop/ms717802(v=vs.85).aspx ; If opening the key requires adifferent access right, An application should use the _WinAPI_RegOpenKeyEx function to ; specify an access mask in this situation, or to specify other options. ; _WinAPI_RegOpenKey does not create the specified key if the key does not exist in the database. ; If your service or application impersonates different users, do not use this function with $HKEY_CURRENT_USER. ; Instead, call the _WinAPI_RegOpenCurrentUser function. ; Note that operations that access certain registry keys are redirected. For more information, ; see Registry Virtualization http://msdn.microsoft.com/en-us/library/windows/desktop/aa965884%28v=vs.85%29.aspx ; and 32-bit and 64-bit Application Data in the Registry http://msdn.microsoft.com/en-us/library/windows/desktop/ms724072(v=vs.85).aspx ; If the key is not one of the predefined registry keys you must call the _WinAPI_RegCloseKey() ; function after finished using the handle. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegOpenKey(0, "HKLM\Software\KeyName") ; _WinAPI_RegOpenKey($HKEY_LOCAL_MACHINE, "Software\KeyName") ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegOpenKey(Const ByRef $hKey, $sSubKey = "", $samDesired = 0, $ulOptions = 0) ;; Static $REG_OPTION_BACKUP_RESTORE = 4 $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegOpenKeyExW", "ULONG_PTR", ($hKey ? $hKey : _RegGetPredefinedKeyEx($sSubKey, $samDesired)), "WSTR", $sSubKey, "DWORD", BitOR($ulOptions, 4), "DWORD", $samDesired, "ULONG_PTR*", 0) If @Error Then Return SetError(1, -@Error, 0) If $arDllCall[0] = 206 Then ;; ERROR_FILENAME_EXCED_RANGE - 206 (0xCE) - The filename or extension is too long. $sSubKey = StringRegExp($sSubKey, "(?>[^\\]+\\+){1,29}(?>[^\\]*)", 3) If @Error Or UBound($sSubKey) > 17 Then Return SetError(2, 206, 0) $arDllCall[5] = $arDllCall[1] For $i = 0 To UBound($sSubKey) - 1 $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegOpenKeyExW", "ULONG_PTR", $arDllCall[5], "WSTR", $sSubKey[$i], "DWORD", $arDllCall[3], "DWORD", $samDesired, "ULONG_PTR*", 0) If $i Then DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $arDllCall[1]) If $arDllCall[0] Then Return SetError(3, $arDllCall[0], 0) Next EndIf Return SetError($arDllCall[0], $arDllCall[0], $arDllCall[5]) EndFunc ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegCreateKey ; Description ...: Creates the specified registry key. If the key already exists in the registry, the function opens it. ; If the calling thread has not the $SE_BACKUP_NAME and $SE_RESTORE_NAME privilege enabled, the function fails ; Syntax.........: _WinAPI_RegCreateKey($hKey[, $sSubKey[, $samDesired[, $dwOptions]]]) ; Parameters ....: $hKey - A handle to an open registry key. This handle is returned by the _WinAPI_RegCreateKeyEx or _WinAPI_RegOpenKeyEx ; or _WinAPI_RegCreateKey or _WinAPI_RegOpenKey function, or it can be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_USERS ; This parameter can be NULL, use the NULL or 0 to set NULL this parameter, If $hKey is NULL, ; $sSubKey must be contain Full String KeyName, for more see $sSubKey ; $sSubKey - Optional, The name of a key that this function opens or creates. Key names are not case sensitive. ; This key must be a subkey of the key identified by the $hKey parameter. ; This parameter cannot be NULL. ; if $hKey is Null this key must be a Full String KeyName, example ; "HKLM\SOFTWARE\Example" or "HKEY_USERS" or "HKEY_CURRENT_USER\Software" ; "\Registry\Machine\SOFTWARE\Example" or "\Registry\User" or "\Registry\User\CurrentUser" ; "MACHINE\Software\Example" or "USERS" or "CURRENT_USER\Software" ; "CLASSES_ROOT\Example" or in a remote registry such as \\ComputerName\CLASSES_ROOT\Example. ; If $hKey is one of the predefined keys, $sSubKey may be NULL. In that case, return the same $hKey handle passed in to the function. ; $samDesired - Optional, An access mask the specifies the platform-specific view of the registry. ; | This parameter can be one of the following values, These flags are ignored by 32-bit Windows ; |$KEY_WOW64_64KEY (256) - operate on the 64-bit registry view ; |$KEY_WOW64_32KEY (512) - operate on the 32-bit registry view ; $dwOptions - Optional, This parameter can be one of the following values. ; | (add the flags together for multiple operations): ; |$REG_OPTION_NON_VOLATILE (0) - (Default) This key is not volatile; this is the default. The information is stored in a file and is ; | preserved when the system is restarted. The RegSaveKey function saves keys that are not volatile. ; |$REG_OPTION_VOLATILE (1) - All keys created by the function are volatile. The information is stored in memory and is not preserved ; | when the corresponding registry hive is unloaded. For HKEY_LOCAL_MACHINE, this occurs only when the system ; | initiates a full shutdown. For registry keys loaded by the RegLoadKey function, this occurs when the ; | corresponding RegUnLoadKey is performed. The RegSaveKey function does not save volatile keys. This flag ; | is ignored for keys that already exist. ; | Note On a user selected shutdown, a fast startup shutdown is the default behavior for the system. ; |$REG_OPTION_CREATE_LINK (2) - Note Registry symbolic links should only be used for for application compatibility when absolutely necessary. ; | This key is a symbolic link. The target path is assigned to the L"SymbolicLinkValue" value of the key. ; | The target path must be an absolute registry path. ; Return values .: If the function succeeds, the return value is a handle to the opened or created key and set ERROR_SUCCESS error code, and set Extended ; @Extended: $REG_CREATED_NEW_KEY (1) = The key did not exist and was created. ; $REG_OPENED_EXISTING_KEY (2) = The key existed and was simply opened without being changed. ; If the function fails, the return value is a 0, and set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: The _WinAPI_RegCreateKey function ignores the security access mask and attempts to open\create the key (Not Volatile) with the ; access required to backup or restore the key. If the calling thread has the $SE_BACKUP_NAME privilege enabled, ; the key is opened with the ACCESS_SYSTEM_SECURITY and KEY_READ access rights. If the calling thread has ; the $SE_RESTORE_NAME privilege enabled, beginning with Windows Vista, the key is opened with the ; ACCESS_SYSTEM_SECURITY, DELETE and KEY_WRITE access rights. If both privileges are enabled, the key has ; the combined access rights for both privileges. For more information, see Running with Special Privileges msdn.microsoft.com/en-us/library/windows/desktop/ms717802(v=vs.85).aspx ; If opening\creates the key requires adifferent access right, An application should use the _WinAPI_RegCreateKeyEx function to ; specify an access mask in this situation, or to specify other options. ; The key that the _WinAPI_RegCreateKey function creates has no values. An application can use the ; _WinAPI_RegSetValueEx function to set key values. ; The _WinAPI_RegCreateKey function creates all missing keys in the specified path. An application can take advantage ; of this behavior to create several keys at once. For example, an application can create a subkey four levels deep ; at the same time as the three preceding subkeys by specifying a string of the following form for the $sSubKey parameter: ; "subkey1\subkey2\subkey3\subkey4" ; Note that this behavior will result in creation of unwanted keys if an existing key in the path is spelled incorrectly. ; An application cannot create a key that is a direct child of $HKEY_USERS or $HKEY_LOCAL_MACHINE. An application can create ; subkeys in lower levels of the $HKEY_USERS or $HKEY_LOCAL_MACHINE trees. ; If your service or application impersonates different users, do not use this function with $HKEY_CURRENT_USER. Instead, ; call the _WinAPI_RegOpenCurrentUser function. ; Note that operations that access certain registry keys are redirected. For more information, ; see Registry Virtualization http://msdn.microsoft.com/en-us/library/windows/desktop/aa965884%28v=vs.85%29.aspx ; and 32-bit and 64-bit Application Data in the Registry http://msdn.microsoft.com/en-us/library/windows/desktop/ms724072(v=vs.85).aspx ; If the key is not one of the predefined registry keys you must call the _WinAPI_RegCloseKey() ; function after finished using the handle. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegCreateKey(0, "HKLM\Software\KeyName") ; _WinAPI_RegCreateKey($HKEY_LOCAL_MACHINE, "Software\KeyName") ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegCreateKey(Const ByRef $hKey, $sSubKey = "", $samDesired = 0, $dwOptions = 0) ;; Static $REG_OPTION_RESERVED = 0, $REG_OPTION_BACKUP_RESTORE = 4 $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegCreateKeyExW", "ULONG_PTR", ($hKey ? $hKey : _RegGetPredefinedKeyEx($sSubKey, $samDesired)), "WSTR", ($sSubKey ? $sSubKey : ""), "DWORD", 0, "WSTR", Null, "DWORD", BitOR($dwOptions, 4), "DWORD", $samDesired, "PTR", Null, "ULONG_PTR*", 0, "DWORD*", 0) If @Error Then Return SetError(1, -@Error, 0) If $arDllCall[0] = 206 Then ;; ERROR_FILENAME_EXCED_RANGE - 206 (0xCE) - The filename or extension is too long. $sSubKey = StringRegExp($arDllCall[2], "(?>[^\\]+\\+){1,29}(?>[^\\]*)", 3) If @Error Or UBound($sSubKey) > 17 Then Return SetError(2, $arDllCall[0], 0) $arDllCall[8] = $arDllCall[1] For $i = 0 To UBound($sSubKey) - 1 $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegCreateKeyExW", "ULONG_PTR", $arDllCall[8], "WSTR", $sSubKey[$i], "DWORD", 0, "WSTR", Null, "DWORD", $arDllCall[5], "DWORD", $samDesired, "PTR", Null, "ULONG_PTR*", 0, "DWORD*", 0) If $i Then DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $arDllCall[1]) If $arDllCall[0] Then Return SetError(3, $arDllCall[0], 0) Next EndIf Return SetError($arDllCall[0], ($arDllCall[0] ? $arDllCall[0] : $arDllCall[9]), $arDllCall[8]) EndFunc ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegEnumKey ; Description ...: Enumerates the subkeys of the specified open registry key. The function retrieves information about one subkey each time it is called. ; Syntax.........: _WinAPI_RegEnumKey($hKey, $dwIndex) ; Parameters ....: $hKey - A handle to an open registry key. The key must have been opened with the KEY_ENUMERATE_SUB_KEYS access right. ; For more information, see Registry Key Security and Access Rights. ; This handle is returned by the _WinAPI_RegCreateKeyEx or _WinAPI_RegOpenKeyEx or _WinAPI_RegCreateKey or _WinAPI_RegOpenKey ; function, or it can be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_PERFORMANCE_DATA ; $HKEY_USERS ; $dwIndex - The index of the subkey to retrieve. This parameter should be zero for the first call to the _WinAPI_RegEnumKey ; function and then incremented for subsequent calls. ; Because subkeys are not ordered, any new subkey will have an arbitrary index. This means that the function ; may return subkeys in any order. ; Return values .: If the function succeeds, the return value is name of the subkey and set ERROR_SUCCESS error code ; If the function fails, the return value is a None '', and set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: To enumerate subkeys, an application should initially call the _WinAPI_RegEnumKey function with the dwIndex ; parameter set to zero. The application should then increment the dwIndex parameter and call _WinAPI_RegEnumKey ; until there are no more subkeys (meaning the function returns ERROR_NO_MORE_ITEMS). ; The application can also set dwIndex to the index of the last subkey on the first call to the function and decrement the index ; until the subkey with the index 0 is enumerated. To retrieve the index of the last subkey, use the RegQueryInfoKey function. ; While an application is using the _WinAPI_RegEnumKey function, it should not make calls to any registration ; functions that might change the key being enumerated. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegEnumKey($hKey, $dwIndex) ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegEnumKey(Const ByRef $hKey, Const ByRef $dwIndex) $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegEnumKeyExW", "ULONG_PTR", $hKey, "DWORD", $dwIndex, "WSTR", "", "DWORD*", 256, "DWORD", Null, "WSTR", Null, "DWORD*", Null, "PTR", Null) If @Error Or $arDllCall[0] Then Return SetError(1, (@Error ? -@Error : $arDllCall[0]), "") Return $arDllCall[3] EndFunc ;==>_WinAPI_RegEnumKey ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegEnumKeyEx ; Description ...: Enumerates the subkeys of the specified open registry key. The function retrieves information about one subkey each time it is called. ; Syntax.........: _WinAPI_RegEnumKeyEx($hKey[, $sSubKey[, $iFlags[, $sFilter]]]) ; Parameters ....: $hKey - A handle to an open registry key. The key must have been opened with the KEY_ENUMERATE_SUB_KEYS access right. ; For more information, see Registry Key Security and Access Rights. ; This handle is returned by the _WinAPI_RegCreateKeyEx or _WinAPI_RegOpenKeyEx or _WinAPI_RegCreateKey or _WinAPI_RegOpenKey ; function, or it can be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_PERFORMANCE_DATA ; $HKEY_USERS ; This parameter can be NULL, use the NULL or 0 to set NULL this parameter, If $hKey is NULL, ; $sSubKey must be contain Full String KeyName, for more see $sSubKey ; $sSubKey - Optional, The name of the registry key to Enumerate. Key names are not case sensitive. ; This key must be a subkey of the key identified by the $hKey parameter. ; if $hKey is Null this parameter must be a Full String KeyName, example ; "HKLM\SOFTWARE\Example" or "HKEY_USERS" or "HKEY_CURRENT_USER\Software" ; "\Registry\Machine\SOFTWARE\Example" or "\Registry\User" or "\Registry\User\CurrentUser" ; "MACHINE\Software\Example" or "USERS" or "CURRENT_USER\Software" ; "CLASSES_ROOT\Example" or in a remote registry such as \\ComputerName\CLASSES_ROOT\Example. ; If $hKey is one of the predefined keys, $sSubKey may be NULL. In that case, return the same $hKey handle passed in to the function. ; $iFlags - Optional specifies Recursion (add the flags together for multiple operations): ; |$iFlags = 0 (Default) All Key-SubKeys Recursive Mod ; |$iFlags = 1 All SubKeys Not Recursive Mod ; |$iFlags = 2 Disable the return the count in the first element - effectively makes the array 0-based (must use UBound() ; | to get the size in this case). By Default the first element ($array[0]) contains the number of ; | keys\subkeys\values returned, the remaining elements ($array[1], $array[2], etc.) ; | These flags are ignored by 32-bit Windows ; |$iFlags = 256 operate on the 64-bit registry view, $KEY_WOW64_64KEY (256) ; |$iFlags = 512 operate on the 32-bit registry view, $KEY_WOW64_32KEY (512) ; $sFilter - Optional the filter to use, default is ".*", $sFilter is REGEXP Mod, See Pattern Parameters in StringRegExp ; Return values .: return value is Array, If the function succeeds set ERROR_SUCCESS error code ; If the function fails set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: While an application is using the _WinAPI_RegEnumKeyEx function, it should not make calls to any registration ; functions that might change the key being enumerated. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegEnumKeyEx($HKEY_LOCAL_MACHINE, "SOFTWARE\KeyName") ; _WinAPI_RegEnumKeyEx(Null, "HKEY_LOCAL_MACHINE\SOFTWARE\KeyName") ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegEnumKeyEx(Const ByRef $hKey, $sSubKey = "", $iFlags = 0, $sFilter = ".*") Static $aIndexSubKey[515][3] = [[512],[0,0]], $I, $aArray[1] = [Null] Local $sKeyList, $iNoRecursive = BitAND($iFlags, 1), $iFilter = ($sFilter == ".*" ? 0 : 1), $samDesired = 8 + BitAND($iFlags, 768) ;; $KEY_WOW64_* + $KEY_ENUMERATE_SUB_KEYS = 0x0008 $aIndexSubKey[1][1] = _WinAPI_RegOpenKey($hKey, $sSubKey, $samDesired) If @Error Then Return SetError(1, @Extended, $aArray) ;; just to check DllCall @Error, to not check it more during the While\WEnd $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegEnumKeyExW", "ULONG_PTR", $aIndexSubKey[1][1], "DWORD", 0, "WSTR", "", "DWORD*", 256, "DWORD", Null, "WSTR", Null, "DWORD*", Null, "PTR", Null) $I = (@Error Or $arDllCall[0]) ? 0 : 1 While $I $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegEnumKeyExW", "ULONG_PTR", $aIndexSubKey[$I][1], "DWORD", $aIndexSubKey[$I][0], "WSTR", "", "DWORD*", 256, "DWORD", Null, "WSTR", Null, "DWORD*", Null, "PTR", Null) If $arDllCall[0] Then DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $arDllCall[1]) $aIndexSubKey[$I][0] = 0 $aIndexSubKey[$I][1] = 0 $aIndexSubKey[$I][2] = "" $I -= 1 ContinueLoop EndIf $aIndexSubKey[$I][0] += 1 $aIndexSubKey[$I+1][2] = $aIndexSubKey[$I][2] & "\" & $arDllCall[3] $sKeyList &= Not $iFilter ? @LF & $aIndexSubKey[$I+1][2] : (StringRegExp($arDllCall[3], $sFilter) ? @LF & $aIndexSubKey[$I+1][2] : "") If $iNoRecursive Then ContinueLoop $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegOpenKeyExW", "ULONG_PTR", $aIndexSubKey[$I][1], "WSTR", $arDllCall[3], "DWORD", $REG_SPECIAL_ACCESS, "DWORD", $samDesired, "ULONG_PTR*", 0) If $arDllCall[0] Then ContinueLoop $I += 1 ;;If $I > $aIndexSubKey[0][0] Then ;; (will not have to ever happen) Error Registry Element Size Limits (A registry tree can be 512 levels deep) - http://msdn.microsoft.com/en-us/library/windows/desktop/ms724872%28v=vs.85%29.aspx ;; $aIndexSubKey[0][0] *= 2 ;; ReDim $aIndexSubKey[$aIndexSubKey[0][0] + 1][3] ;;EndIf $aIndexSubKey[$I][1] = $arDllCall[5] WEnd If $aIndexSubKey[1][1] Then SetError(@Error + DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $aIndexSubKey[1][1])) If Not $sKeyList Then Return SetError(3, (@Error ? -@Error : $arDllCall[0]), $aArray) Return StringSplit(StringTrimLeft($sKeyList, 2), @LF & "\", 1 + BitAND($iFlags, 2)) EndFunc ;==>_WinAPI_RegEnumKeyEx ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegEnumValue ; Description ...: Enumerates the values for the specified open registry key. The function copies one indexed value name and data block ; for the key each time it is called. ; Syntax.........: _WinAPI_RegEnumValue($hKey, $dwIndex) ; Parameters ....: $hKey - A handle to an open registry key. The key must have been opened with the KEY_QUERY_VALUE access right. ; For more information, see Registry Key Security and Access Rights. ; This handle is returned by the _WinAPI_RegCreateKeyEx or _WinAPI_RegOpenKeyEx or _WinAPI_RegCreateKey or _WinAPI_RegOpenKey ; function, or it can be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_PERFORMANCE_DATA ; $HKEY_USERS ; $dwIndex - The index of the subkey to retrieve. This parameter should be zero for the first call to the _WinAPI_RegEnumValue ; function and then incremented for subsequent calls. ; Because values are not ordered, any new value will have an arbitrary index. This means that the function ; may return values in any order. ; Return values .: If the function succeeds, the return value is name of the subkey and set ERROR_SUCCESS error code ; If the function fails, the return value is a None '', and set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: To enumerate values, an application should initially call the _WinAPI_RegEnumValue function with the dwIndex ; parameter set to zero. The application should then increment dwIndex and call the _WinAPI_RegEnumValue function ; until there are no more values (until the function returns ERROR_NO_MORE_ITEMS). ; The application can also set dwIndex to the index of the last value on the first call to the function ; and decrement the index until the value with index 0 is enumerated. To retrieve the index of the last value, ; use the RegQueryInfoKey function. ; While using _WinAPI_RegEnumValue, an application should not call any registry functions that might change the key being queried. ; If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, the string may not have been stored with ; the proper null-terminating characters. Therefore, even if the function returns ERROR_SUCCESS, the ; application should ensure that the string is properly terminated before using it; otherwise, it may ; overwrite a buffer. (Note that REG_MULTI_SZ strings should have two null-terminating characters.) ; To determine the maximum size of the name and data buffers, use the RegQueryInfoKey function. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegEnumValue($hKey, $dwIndex) ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegEnumValue(Const ByRef $hKey, Const ByRef $dwIndex) $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegEnumValueW", "ULONG_PTR", $hKey, "DWORD", $dwIndex, "WSTR", "", "DWORD*", 16384, "DWORD", Null, "DWORD*", 0, "PTR", Null, "PTR", Null) If @Error Or $arDllCall[0] Then Return SetError(1, (@Error ? -@Error : $arDllCall[0]), "") Return SetExtended($arDllCall[6], $arDllCall[3]) EndFunc ;==>_WinAPI_RegEnumValue ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegEnumValueEx ; Description ...: Enumerates the values for the specified open registry key. The function copies one indexed value name and data block ; for the key each time it is called. ; Syntax.........: _WinAPI_RegEnumValueEx($hKey[, $sSubKey[, $samDesired, $sFilter]]]) ; Parameters ....: $hKey - A handle to an open registry key. The key must have been opened with the KEY_QUERY_VALUE access right. ; For more information, see Registry Key Security and Access Rights. ; This handle is returned by the _WinAPI_RegCreateKeyEx or _WinAPI_RegOpenKeyEx or _WinAPI_RegCreateKey or _WinAPI_RegOpenKey ; function, or it can be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_PERFORMANCE_DATA ; $HKEY_USERS ; $sSubKey - Optional, The name of the registry key to enumerate value. Key names are not case sensitive. ; This key must be a subkey of the key identified by the $hKey parameter. ; if $hKey is Null this key must be a Full String KeyName, example ; "HKLM\SOFTWARE\Example" or "HKEY_USERS" or "HKEY_CURRENT_USER\Software" ; "\Registry\Machine\SOFTWARE\Example" or "\Registry\User" or "\Registry\User\CurrentUser" ; "MACHINE\Software\Example" or "USERS" or "CURRENT_USER\Software" ; "CLASSES_ROOT\Example" or in a remote registry such as \\ComputerName\CLASSES_ROOT\Example. ; $samDesired - Optional, An access mask the specifies the platform-specific view of the registry. ; |$KEY_SYMBOLIC_LINK (64) - Key is Symbolic Link, query\check "SymbolicLinkValue" ; | These flags are ignored by 32-bit Windows ; |$KEY_WOW64_64KEY (256) - operate on the 64-bit registry view ; |$KEY_WOW64_32KEY (512) - operate on the 32-bit registry view ; $sFilter - Optional the filter to use, default is ".*", $sFilter is REGEXP Mod, See Pattern Parameters in StringRegExp ; Return values .: return value is 2D Array, If the function succeeds set ERROR_SUCCESS error code ; If the function fails set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: To enumerate values, an application should initially call the _WinAPI_RegEnumValueEx function with the dwIndex ; parameter set to zero. The application should then increment dwIndex and call the _WinAPI_RegEnumValueEx function ; until there are no more values (until the function returns ERROR_NO_MORE_ITEMS). ; The application can also set dwIndex to the index of the last value on the first call to the function ; and decrement the index until the value with index 0 is enumerated. To retrieve the index of the last value, ; use the RegQueryInfoKey function. ; While using _WinAPI_RegEnumValueEx, an application should not call any registry functions that might change the key being queried. ; If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, the string may not have been stored with ; the proper null-terminating characters. Therefore, even if the function returns ERROR_SUCCESS, the ; application should ensure that the string is properly terminated before using it; otherwise, it may ; overwrite a buffer. (Note that REG_MULTI_SZ strings should have two null-terminating characters.) ; To determine the maximum size of the name and data buffers, use the RegQueryInfoKey function. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegEnumValueEx($hKey) ; _WinAPI_RegEnumValueEx(Null, "HKLM\Software\KeyName") ; _WinAPI_RegEnumValueEx(Null, "HKLM\Software\KeyName", $KEY_WOW64_64KEY) ; _WinAPI_RegEnumValueEx(Null, "HKLM\Software\KeyName", 0, ".*ValueName.*") ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegEnumValueEx($hKey, $sSubKey = "", $samDesired = 0, $sFilter = ".*") If Not $hKey Then $hKey = _RegGetPredefinedKeyEx($sSubKey, $samDesired) ;;Static $dwIndex = 0 ;;$arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegEnumValueW", "ULONG_PTR", $hKey, "DWORD", $dwIndex, "WSTR", "", "DWORD*", 16384, "DWORD", Null, "DWORD*", 0, "PTR", Null, "PTR", Null) ;;If @Error Or $arDllCall[0] Then ;; $dwIndex = 0 ;; Return SetError(1, (@Error ? -@Error : $arDllCall[0]), "") ;;EndIf ;;$dwIndex += 1 ;;Return SetExtended($arDllCall[6], $arDllCall[3]) Local $dwIndex = 0, $tData = DllStructCreate("BYTE[4096]"), $aRegEnumValue[11][3] = [[0,10,0]], $iFilter = $sFilter == ".*" ? 0 : 1 If $sSubKey Or $samDesired Then $hKey = _WinAPI_RegOpenKey($hKey, $sSubKey, 1 + BitAND($samDesired, 768), (BitAND($samDesired, 64) ? 8 : 0)) ;; $KEY_QUERY_VALUE = 0x0001 If @Error Then Return SetError(1, @Extended, $aRegEnumValue) EndIf While 1 $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegEnumValueW", "ULONG_PTR", $hKey, "DWORD", $dwIndex, "WSTR", "", "DWORD*", 16384, "DWORD", Null, "DWORD*", 0, "STRUCT*", $tData, "DWORD*", 4096) If @Error Then ExitLoop If $arDllCall[8] > 4096 Then $tData = DllStructCreate("BYTE[" & $arDllCall[8] & "]") $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegEnumValueW", "ULONG_PTR", $hKey, "DWORD", $dwIndex, "WSTR", "", "DWORD*", 16384, "DWORD", Null, "DWORD*", 0, "STRUCT*", $tData, "DWORD*", $arDllCall[8]) EndIf If $arDllCall[0] Then ExitLoop If $iFilter And StringRegExp($arDllCall[3], $sFilter) = 0 Then ContinueLoop $dwIndex += 1 If $dwIndex > $aRegEnumValue[0][1] Then $aRegEnumValue[0][1] *= 2 ReDim $aRegEnumValue[$aRegEnumValue[0][1] + 1][3] EndIf $aRegEnumValue[$dwIndex][0] = $arDllCall[3] $aRegEnumValue[$dwIndex][1] = $arDllCall[6] Switch $arDllCall[6] Case 1, 2, 6 ;; $REG_SZ, $REG_EXPAND_SZ, $REG_LINK $aRegEnumValue[$dwIndex][2] = BinaryToString(BinaryMid(DllStructGetData($tData, 1), 1, $arDllCall[8]), 2) Case 7 ;; $REG_MULTI_SZ $aRegEnumValue[$dwIndex][2] = StringRegExpReplace(BinaryToString(BinaryMid(DllStructGetData($tData, 1), 1, $arDllCall[8]), 2), "\x00+", @LF) Case 4 ;; $REG_DWORD, $REG_DWORD_LITTLE_ENDIAN $aRegEnumValue[$dwIndex][2] = DllStructGetData(DllStructCreate("DWORD", DllStructGetPtr($tData, 1)), 1) ;; Or Dec(StringRegExpReplace(BinaryMid(DllStructGetData($tData, 1), 1, 4), "^..(..)(..)(..)(..)","$4$3$2$1"), 1) Case 5 ;; $REG_DWORD_BIG_ENDIAN $aRegEnumValue[$dwIndex][2] = Dec(StringMid(BinaryMid(DllStructGetData($tData, 1), 1, $arDllCall[8]), 3, 8), 1) ;; Or Number(StringLeft(DllStructGetData($tData, 1), 10), 3) Case 11 ;; $REG_QWORD, $REG_QWORD_LITTLE_ENDIAN $aRegEnumValue[$dwIndex][2] = DllStructGetData(DllStructCreate("UINT64", DllStructGetPtr($tData, 1)), 1) ;; Or Dec(StringRegExpReplace(BinaryMid(DllStructGetData($tData, 1), 1, 8), "^..(..)(..)(..)(..)(..)(..)(..)(..)","0x$8$7$6$5$4$3$2$1"), 2) Case Else ;; 0 To 11 ;; 0, 3, 8, 9, 10 ;; $REG_NONE, $REG_BINARY, $REG_RESOURCE_LIST, $REG_FULL_RESOURCE_DESCRIPTOR, $REG_RESOURCE_REQUIREMENTS_LIST $aRegEnumValue[$dwIndex][2] = BinaryMid(DllStructGetData($tData, 1), 1, $arDllCall[8]) EndSwitch WEnd If $sSubKey Then SetError(@Error + DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKey)) If Not $dwIndex Then Return SetError(2, (@Error ? -@Error : $arDllCall[0]), $aRegEnumValue) $aRegEnumValue[0][0] = $dwIndex + 1 Return $aRegEnumValue EndFunc ;==>_WinAPI_RegEnumValueEx ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegKeyExistEx ; Description ...: Check is the specified registry key exist. Note that key names are not case sensitive. ; Syntax.........: _WinAPI_RegKeyExistEx($hKey[, $sSubKey[, $samDesired[, $ulOptions]]]) ; Parameters ....: $hKey - A handle to an open registry key. This handle is returned by the _WinAPI_RegCreateKeyEx or _WinAPI_RegOpenKeyEx ; or _WinAPI_RegCreateKey or _WinAPI_RegOpenKey function, or it can be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_USERS ; This parameter can be NULL, use the NULL or 0 to set NULL this parameter, If $hKey is NULL, ; $sSubKey must be contain Full String KeyName, for more see $sSubKey ; $sSubKey - Optional, The name of the registry subkey to be opened. Key names are not case sensitive. ; This key must be a subkey of the key identified by the $hKey parameter. ; if $hKey is Null this parameter must be a Full String KeyName, example ; "HKLM\SOFTWARE\Example" or "HKEY_USERS" or "HKEY_CURRENT_USER\Software" ; "\Registry\Machine\SOFTWARE\Example" or "\Registry\User" or "\Registry\User\CurrentUser" ; "MACHINE\Software\Example" or "USERS" or "CURRENT_USER\Software" ; "CLASSES_ROOT\Example" or in a remote registry such as \\ComputerName\CLASSES_ROOT\Example. ; The $sSubKey parameter can be an empty string. If $sSubKey is an empty string and $hKey is $HKEY_CLASSES_ROOT, ; function return the same $hKey handle passed into the function. Otherwise, return a new handle to the key specified by $hKey. ; The $sSubKey parameter can be NULL only if $hKey is one of the predefined keys. If $sSubKey is NULL and $hKey is ; $HKEY_CLASSES_ROOT, function return a new handle to the key specified by $hKey. Otherwise, retun the same ; $hKey handle passed in to the function. ; $samDesired - Optional, An access mask the specifies the platform-specific view of the registry. ; |$KEY_SYMBOLIC_LINK (64) - Key is Symbolic Link, Check for Symbolic Link ; | This parameter can be one of the following values, These flags are ignored by 32-bit Windows ; |$KEY_WOW64_64KEY (256) - operate on the 64-bit registry view ; |$KEY_WOW64_32KEY (512) - operate on the 32-bit registry view ; $ulOptions - Optional, This parameter is reserved and must be zero. ; | however will have to support flags such as ; $ulOptions - Optional, This parameter is reserved and must be zero. ; | however will have to support flags such as ; |$REG_OPTION_OPEN_LINK (8) - Open symbolic link, query L"SymbolicLinkValue" or set L"SymbolicLinkValue" ; Return values .: If the function succeeds, the return value is True, and set ERROR_SUCCESS error code, If the function fails, ; the return value is a False, and set error code defined in WinError.h ; And set Extended ; @Extended: 1 = Key is Normal Registry Key (Normale Key Exist) ; 2 = Key is Symbolic Link (Symbolic Link Key Exist) ; 4 = Key is Empty (5 = Normal Key & Empty Key - 6 = Symbolic Link & Key that the symbolic link refers to is Empty) ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: For safety is always best to check the @Extended, for example ; _WinAPI_RegKeyExistEx(0, "HKLM\Software\NormalKeyName", $KEY_SYMBOLIC_LINK) - Return False and set Extended 1 or 5 ; _WinAPI_RegKeyExistEx(0, "HKLM\Software\SymbolicLinkKeyName") - Return False and set Extended 2 or 6 ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegKeyExistEx(0, "HKLM\Software\KeyName") ; _WinAPI_RegKeyExistEx($HKEY_LOCAL_MACHINE, "Software\KeyName", $KEY_WOW64_64KEY) ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegKeyExistEx(Const ByRef $hKey, $sSubKey = "", $samDesired = 0) Static $hKeyEx = 0, $hLinkKey = 0, $iEmptyKey = 0, $bLinkKey ;; $KEY_QUERY_VALUE = 0x1 ;; $KEY_ENUMERATE_SUB_KEYS = 0x8 ;; $KEY_ALL_ACCESS = 0xF003F ;; $_KEY_ALL_ACCESS = 0x3F If Not $sSubKey Then If Not _NTAPI_GetRegKeyNameByHandle($hKey) Then Return SetError(6, 0, False) ;; ERROR_INVALID_HANDLE - 6 (0x6) - The handle is invalid. $iEmptyKey = ((Not _WinAPI_RegEnumValue($hKeyEx, 0) And @Error) And (Not _WinAPI_RegEnumKey($hKeyEx, 0) And @Error)) ? 5 : 1 If Not BitAND($samDesired, 64) Then Return SetExtended($iEmptyKey, True) $bLinkKey = ((_WinAPI_RegEnumValue($hKey, 0) = "SymbolicLinkValue" And @Extended = 6) And (Not _WinAPI_RegEnumValue($hKey, 1) And @Error) And (Not _WinAPI_RegEnumKey($hKey, 0) And @Error)) Return SetExtended(Int($bLinkKey) + $iEmptyKey, $bLinkKey) EndIf $hKeyEx = _WinAPI_RegOpenKey($hKey, $sSubKey, BitOR($samDesired, 9)) If @Extended = 5 Then Return SetError(5, 1, True) If @Error Then $hLinkKey = _WinAPI_RegOpenKey($hKey, $sSubKey, BitOR($samDesired, 1), 8) ;; $REG_OPTION_OPEN_LINK = 8 If @Error Then Return SetError(@Extended, 0, False) Return SetExtended(2 + DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hLinkKey), (BitAND($samDesired, 64) ? True : False)) EndIf $iEmptyKey = ((Not _WinAPI_RegEnumValue($hKeyEx, 0) And @Error) And (Not _WinAPI_RegEnumKey($hKeyEx, 0) And @Error)) ? 5 : 1 If Not BitAND($samDesired, 64) Then Return SetExtended($iEmptyKey + DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKeyEx), True) $hLinkKey = _WinAPI_RegOpenKey($hKey, $sSubKey, 1, 8) ;; $REG_OPTION_OPEN_LINK = 8 $bLinkKey = $sSubKey ? (_NTAPI_GetRegKeyNameByHandle($hKeyEx) <> _NTAPI_GetRegKeyNameByHandle($hLinkKey)) : ((_WinAPI_RegEnumValue($hKey, 0) = "SymbolicLinkValue" And @Extended = 6) And (Not _WinAPI_RegEnumValue($hLinkKey, 1) And @Error) And (Not _WinAPI_RegEnumKey($hLinkKey, 0) And @Error)) DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKeyEx) DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hLinkKey) Return SetExtended(Int($bLinkKey) + $iEmptyKey, $bLinkKey) EndFunc ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegSetValue ; Description ...: Sets the data and type of a specified value under a registry key. ; Syntax.........: _WinAPI_RegSetValue($hKey[, $sValueName[, $vData[, $dwType]]]) ; Parameters ....: $hKey - A handle to an open registry key. The key must have been opened with the $KEY_SET_VALUE access right. ; For more information, see Registry Key Security and Access Rights. ; This handle is returned by the _WinAPI_RegCreateKey, _WinAPI_RegCreateKeyEx, _WinAPI_RegOpenKey, _WinAPI_RegOpenKeyEx, ; or RegOpenKeyTransacted function. It can also be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_USERS ; The Unicode version of this function supports the following additional predefined keys: ; $HKEY_PERFORMANCE_TEXT ; $HKEY_PERFORMANCE_NLSTEXT ; $sValueName - Optional, The name of the value to be set. If a value with this name is not already present in the key, the function adds it to the key. ; If $sValueName is NULL or an empty string, "", the function sets the type and data for the key's unnamed or default value. ; For more information, see Registry Element Size Limits. ; Registry keys do not have default values, but they can have one unnamed value, which can be of any type. ; $dwType - Optional, The type of data pointed to by the lpData parameter. For a list of the possible types, see Registry Value Types. ; |$REG_NONE (0) - No defined value type. ; |$REG_SZ (1) - (Default) A null-terminated string. This will be either a Unicode or an ANSI string, depending on whether ; | you use the Unicode or ANSI functions. ; |$REG_EXPAND_SZ (2) - A null-terminated string that contains unexpanded references to environment variables (for example, ; | "%PATH%"). It will be a Unicode or ANSI string depending on whether you use the Unicode or ANSI functions. ; | To expand the environment variable references, use the ExpandEnvironmentStrings function. ; |$REG_BINARY (3) - Binary data in any form. ; |$REG_DWORD (4) - A 32-bit number. ; |$REG_DWORD_LITTLE_ENDIAN (4) - A 32-bit number in little-endian format. ; | Windows is designed to run on little-endian computer architectures. Therefore, this value is defined ; | as REG_DWORD in the Windows header files. ; |$REG_DWORD_BIG_ENDIAN (5) - A 32-bit number in big-endian format. Some UNIX systems support big-endian architectures. ; |$REG_LINK (6) - A null-terminated Unicode string that contains the target path of a symbolic link that was ; | created by calling the RegCreateKeyEx function with REG_OPTION_CREATE_LINK. ; |$REG_MULTI_SZ (7) - A sequence of null-terminated strings, terminated by an empty string (\0). ; | The following is an example: ; | String1\0String2\0String3\0LastString\0\0 ; | The first \0 terminates the first string, the second to the last \0 terminates the last string, and the ; | final \0 terminates the sequence. Note that the final terminator must be factored into the length of the string. ; |$REG_RESOURCE_LIST (8) - Resource list in the resource map ; |$REG_FULL_RESOURCE_DESCRIPTOR (9) - Resource list in the hardware description ; |$REG_RESOURCE_REQUIREMENTS_LIST (10) - Resource list in the hardware description ; |$REG_QWORD (11) - A 64-bit number. ; |$REG_QWORD_LITTLE_ENDIAN (11) - A 64-bit number in little-endian format. ; | Windows is designed to run on little-endian computer architectures. Therefore, this value is defined ; | as REG_QWORD in the Windows header files. ; Return values .: If the function succeeds, the return value is ERROR_SUCCESS. and set ERROR_SUCCESS error code ; If the function fails, the return value is nonzero, and set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: Calling _WinAPI_RegSetValue is an expensive operation that significantly affects system-wide performance as ; it consumes disk bandwidth and blocks modifications to all keys by all processes in the registry hive that ; is being flushed until the flush operation completes. _WinAPI_RegSetValue should only be called xplicitly ; ewhen an application must guarantee that registry changes are persisted to disk immediately after modification. ; All modifications made to keys are visible to other processes without the need to flush them to disk. ; Alternatively, the registry has a 'lazy flush' mechanism that flushes registry modifications to disk at regular ; intervals of time. In addition to this regular flush operation, registry changes are also flushed to disk at ; system shutdown. Allowing the 'lazy flush' to flush registry changes is the most efficient way to manage registry ; writes to the registry store on disk. ; The _WinAPI_RegSetValue function returns only when all the data for the hive that contains the specified key ; has been written to the registry store on disk. ; The _WinAPI_RegSetValue function writes out the data for other keys in the hive that have been modified since ; the last lazy flush or system start. ; After _WinAPI_RegSetValue returns, use _WinAPI_RegCloseKey to close the handle to the registry key. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegSetValue($hKey, "Test", "This is Test", $REG_SZ) ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegSetValue(Const ByRef $hKey, $sValueName = "", $vData = "", $dwType = 1) ;; $REG_SZ = 1 Static $tData = DllStructCreate("BYTE[4096]"), $cbData, $lpData = $tData Switch $dwType Case 1, 2 ;; $REG_SZ, $REG_EXPAND_SZ If Not IsBinary($vData) Then $vData = StringToBinary(StringRegExpReplace(StringRegExpReplace($vData, "\\", "\\\\"), "\x00*+$", "") & Chr(0), 2) ;$tData = DllStructCreate("BYTE[" & BinaryLen($vData) & "]") Case 5 ;; $REG_DWORD_BIG_ENDIAN If Not IsBinary($vData) Then $vData = Binary("0x" & Hex($vData, 8)) Case 6 ;; $REG_LINK ;;If (_WinAPI_RegEnumValue($hKey, 0) = "SymbolicLinkValue" And @Extended = 6) And (Not _WinAPI_RegEnumValue($hKey, 1) And @Error) And (Not _WinAPI_RegEnumKey($hKey, 0) And @Error) Then Return SetError(2, 87, 87) If Not IsBinary($vData) Then $vData = StringToBinary((StringRegExp($vData, "(?i)^\\Registry\\") ? $vData : _RegGetObjectNameKey($vData)), 2) Case 7 ;; $REG_MULTI_SZ If Not IsBinary($vData) Then $vData = StringToBinary(StringRegExpReplace(StringRegExpReplace(StringRegExpReplace($vData, "\n", Chr(0)), "\\", "\\\\"), "\x00*+$", "") & Chr(0) & Chr(0), 2) ;$tData = DllStructCreate("BYTE[" & BinaryLen($vData) & "]") Case 0 To 11 ;; 0, 3, 4, 8, 9, 10, 11 ;; $REG_NONE, $REG_BINARY, $REG_DWORD, $REG_RESOURCE_LIST, $REG_FULL_RESOURCE_DESCRIPTOR, $REG_RESOURCE_REQUIREMENTS_LIST, $REG_QWORD ;;Case 4 ;; $REG_DWORD, $REG_DWORD_LITTLE_ENDIAN ;; $tData = DllStructCreate("DWORD") ;; or ;; DllStructCreate("BYTE[4]") ;; If Not IsBinary($vData) Then $vData = Binary(StringRegExpReplace(Hex($vData, 8), "^(..)(..)(..)(..)","0x$4$3$2$1")) ;;Case 11 ;; $REG_QWORD, $REG_QWORD_LITTLE_ENDIAN ;; $tData = DllStructCreate("UINT64") ;; or ;; DllStructCreate("BYTE[8]") ;; If Not IsBinary($vData) Then $vData = Binary(StringRegExpReplace(Hex($vData, 16), "^(..)(..)(..)(..)(..)(..)(..)(..)","0x$8$7$6$5$4$3$2$1")) ;;Case 0, 3, 8, 9, 10 ;; $REG_NONE, $REG_BINARY, $REG_RESOURCE_LIST, $REG_FULL_RESOURCE_DESCRIPTOR, $REG_RESOURCE_REQUIREMENTS_LIST ;; $tData = DllStructCreate("BYTE[" & BinaryLen($vData) & "]") Case Else Return SetError(2, 87, 87) EndSwitch $cbData = $dwType = 11 ? 8 : BinaryLen($vData) If $cbData > 4096 Then $tData = DllStructCreate("BYTE[" & $cbData & "]") DllStructSetData($tData, 1, $vData) $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegSetValueExW", "ULONG_PTR", $hKey, "WSTR", $sValueName, "DWORD", 0, "DWORD", $dwType, "STRUCT*", $tData, "DWORD", $cbData) If $cbData > 4096 Then $tData = $lpData If @Error Then Return SetError(1, -@Error, -@Error) Return SetError($arDllCall[0], $arDllCall[0], $arDllCall[0]) EndFunc ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegSetValueEx ; Description ...: Sets the data and type of a specified value under a registry key. ; Syntax.........: _WinAPI_RegSetValueEx($hKey[, $sSubKey[, $sValueName[, $vData[, $dwType[, $samDesired]]]]]) ; Parameters ....: $hKey - A handle to an open registry key. The key must have been opened with the $KEY_SET_VALUE access right. ; For more information, see Registry Key Security and Access Rights. ; This handle is returned by the _WinAPI_RegCreateKey, _WinAPI_RegCreateKeyEx, _WinAPI_RegOpenKey, _WinAPI_RegOpenKeyEx, ; or RegOpenKeyTransacted function. It can also be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_USERS ; The Unicode version of this function supports the following additional predefined keys: ; $HKEY_PERFORMANCE_TEXT ; $HKEY_PERFORMANCE_NLSTEXT ; This parameter can be NULL, use the NULL or 0 to set NULL this parameter, If $hKey is NULL, ; $sSubKey must be contain Full String KeyName, for more see $sSubKey ; $sSubKey - Optional, The name of the registry key to set the value. Key names are not case sensitive. ; This key must be a subkey of the key identified by the $hKey parameter. ; if $hKey is Null this key must be a Full String KeyName, example ; "HKLM\SOFTWARE\Example" or "HKEY_USERS" or "HKEY_CURRENT_USER\Software" ; "\Registry\Machine\SOFTWARE\Example" or "\Registry\User" or "\Registry\User\CurrentUser" ; "MACHINE\Software\Example" or "USERS" or "CURRENT_USER\Software" ; "CLASSES_ROOT\Example" or in a remote registry such as \\ComputerName\CLASSES_ROOT\Example. ; If this parameter is NULL or an empty string, the function returns the same handle that was passed in. ; $sValueName - Optional, The name of the value to be set. If a value with this name is not already present in the key, the function adds it to the key. ; If $sValueName is NULL or an empty string, "", the function sets the type and data for the key's unnamed or default value. ; For more information, see Registry Element Size Limits. ; Registry keys do not have default values, but they can have one unnamed value, which can be of any type. ; $dwType - Optional, The type of data pointed to by the lpData parameter. For a list of the possible types, see Registry Value Types. ; |$REG_NONE (0) - No defined value type. ; |$REG_SZ (1) - (Default) A null-terminated string. This will be either a Unicode or an ANSI string, depending on whether ; | you use the Unicode or ANSI functions. ; |$REG_EXPAND_SZ (2) - A null-terminated string that contains unexpanded references to environment variables (for example, ; | "%PATH%"). It will be a Unicode or ANSI string depending on whether you use the Unicode or ANSI functions. ; | To expand the environment variable references, use the ExpandEnvironmentStrings function. ; |$REG_BINARY (3) - Binary data in any form. ; |$REG_DWORD (4) - A 32-bit number. ; |$REG_DWORD_LITTLE_ENDIAN (4) - A 32-bit number in little-endian format. ; | Windows is designed to run on little-endian computer architectures. Therefore, this value is defined ; | as REG_DWORD in the Windows header files. ; |$REG_DWORD_BIG_ENDIAN (5) - A 32-bit number in big-endian format. Some UNIX systems support big-endian architectures. ; |$REG_LINK (6) - A null-terminated Unicode string that contains the target path of a symbolic link that was ; | created by calling the RegCreateKeyEx function with REG_OPTION_CREATE_LINK. ; |$REG_MULTI_SZ (7) - A sequence of null-terminated strings, terminated by an empty string (\0). ; | The following is an example: ; | String1\0String2\0String3\0LastString\0\0 ; | The first \0 terminates the first string, the second to the last \0 terminates the last string, and the ; | final \0 terminates the sequence. Note that the final terminator must be factored into the length of the string. ; |$REG_RESOURCE_LIST (8) - Resource list in the resource map ; |$REG_FULL_RESOURCE_DESCRIPTOR (9) - Resource list in the hardware description ; |$REG_RESOURCE_REQUIREMENTS_LIST (10) - Resource list in the hardware description ; |$REG_QWORD (11) - A 64-bit number. ; |$REG_QWORD_LITTLE_ENDIAN (11) - A 64-bit number in little-endian format. ; | Windows is designed to run on little-endian computer architectures. Therefore, this value is defined ; | as REG_QWORD in the Windows header files. ; $samDesired - Optional, An access mask the specifies the platform-specific view of the registry. ; | This parameter can be one of the following values, These flags are ignored by 32-bit Windows ; |$KEY_WOW64_64KEY (256) - operate on the 64-bit registry view ; |$KEY_WOW64_32KEY (512) - operate on the 32-bit registry view ; Return values .: If the function succeeds, the return value is ERROR_SUCCESS. and set ERROR_SUCCESS error code ; If the function fails, the return value is nonzero, and set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: Calling _WinAPI_RegSetValueEx is an expensive operation that significantly affects system-wide performance as ; it consumes disk bandwidth and blocks modifications to all keys by all processes in the registry hive that ; is being flushed until the flush operation completes. _WinAPI_RegSetValueEx should only be called xplicitly ; ewhen an application must guarantee that registry changes are persisted to disk immediately after modification. ; All modifications made to keys are visible to other processes without the need to flush them to disk. ; Alternatively, the registry has a 'lazy flush' mechanism that flushes registry modifications to disk at regular ; intervals of time. In addition to this regular flush operation, registry changes are also flushed to disk at ; system shutdown. Allowing the 'lazy flush' to flush registry changes is the most efficient way to manage registry ; writes to the registry store on disk. ; The _WinAPI_RegSetValueEx function returns only when all the data for the hive that contains the specified key ; has been written to the registry store on disk. ; The _WinAPI_RegSetValueEx function writes out the data for other keys in the hive that have been modified since ; the last lazy flush or system start. ; After _WinAPI_RegSetValueEx returns, use _WinAPI_RegCloseKey to close the handle to the registry key. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegSetValueEx($hKey, Null, "Test", "This is Test", $REG_SZ) ; _WinAPI_RegSetValueEx($HKEY_LOCAL_MACHINE, "SOFTWARE\KeyName", "Test", "This is Test", $REG_SZ) ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegSetValueEx($hKey, $sSubKey = "", $sValueName = "", $vData = "", $dwType = 1, $samDesired = 0) ;Static $_WIN32_WINNT5 = StringRegExp(@OSVersion, "(?i)WIN_(?:XP|XPe|2000|2003)") Switch $dwType Case 1, 2 ;; $REG_SZ, $REG_EXPAND_SZ If Not IsBinary($vData) Then $vData = StringToBinary(StringRegExpReplace(StringRegExpReplace($vData, "\\", "\\\\"), "\x00*+$", "") & Chr(0), 2) Case 5 ;; $REG_DWORD_BIG_ENDIAN If Not IsBinary($vData) Then $vData = Binary("0x" & Hex($vData, 8)) Case 6 ;; $REG_LINK If Not _WinAPI_RegKeyExistEx($hKey, $sSubKey, BitOR($samDesired, 64)) And @Extended Then Return SetError(4, 2, 2) If Not IsBinary($vData) Then $vData = StringToBinary((StringRegExp($vData, "(?i)^\\Registry\\") ? $vData : _RegGetObjectNameKey($vData)), 2) Case 7 ;; $REG_MULTI_SZ If Not IsBinary($vData) Then $vData = StringToBinary(StringRegExpReplace(StringRegExpReplace(StringRegExpReplace($vData, "\n", Chr(0)), "\\", "\\\\"), "\x00*+$", "") & Chr(0) & Chr(0), 2) Case 0 To 11 ;; 0, 3, 4, 8, 9, 10, 11 ;; $REG_NONE, $REG_BINARY, $REG_DWORD, $REG_RESOURCE_LIST, $REG_FULL_RESOURCE_DESCRIPTOR, $REG_RESOURCE_REQUIREMENTS_LIST, $REG_QWORD ;; Case Else Return SetError(2, 87, 87) EndSwitch Local $cbData = ($dwType = 11 ? 8 : BinaryLen($vData)), $tData = DllStructCreate("BYTE[" & $cbData & "]") DllStructSetData($tData, 1, $vData) If Not $hKey Then $hKey = _RegGetPredefinedKeyEx($sSubKey, $samDesired) If $sSubKey Or $samDesired Then Local $hKeyEx = _WinAPI_RegCreateKey($hKey, $sSubKey, 2 + BitAND($samDesired, 768), ($dwType = 6 ? 2 : 0)) If @Error And $dwType = 6 Then $hKeyEx = _WinAPI_RegOpenKey($hKey, $sSubKey, 2 + BitAND($samDesired, 768), 8) If @Error Then Return SetError(3, @Extended, @Extended) $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegSetValueExW", "ULONG_PTR", $hKeyEx, "WSTR", $sValueName, "DWORD", 0, "DWORD", $dwType, "STRUCT*", $tData, "DWORD", $cbData) SetError(@Error + DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKeyEx)) Else $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegSetValueExW", "ULONG_PTR", $hKey, "WSTR", $sValueName, "DWORD", 0, "DWORD", $dwType, "STRUCT*", $tData, "DWORD", $cbData) EndIf If @Error Then Return SetError(1, -@Error, -@Error) Return SetError($arDllCall[0], $arDllCall[0], $arDllCall[0]) EndFunc ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegSetKeyValue ; Description ...: Sets the data for the specified value in the specified registry key and subkey, Minimum supported client Windows Vista ; Syntax.........: _WinAPI_RegSetKeyValue($hKey[, $sSubKey[, $sValueName[, $vData[, $dwType[, $samDesired]]]]]) ; Parameters ....: $hKey - A handle to an open registry key. The key must have been opened with the $KEY_SET_VALUE access right. ; For more information, see Registry Key Security and Access Rights. ; This handle is returned by the _WinAPI_RegCreateKey, _WinAPI_RegCreateKeyEx, _WinAPI_RegOpenKey, _WinAPI_RegOpenKeyEx, ; or RegOpenKeyTransacted function. It can also be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_USERS ; The Unicode version of this function supports the following additional predefined keys: ; $HKEY_PERFORMANCE_TEXT ; $HKEY_PERFORMANCE_NLSTEXT ; This parameter can be NULL, use the NULL or 0 to set NULL this parameter, If $hKey is NULL, ; $sSubKey must be contain Full String KeyName, for more see $sSubKey ; $sSubKey - Optional, The name of the registry key to set the value. Key names are not case sensitive. ; This key must be a subkey of the key identified by the $hKey parameter. ; if $hKey is Null this key must be a Full String KeyName, example ; "HKLM\SOFTWARE\Example" or "HKEY_USERS" or "HKEY_CURRENT_USER\Software" ; "\Registry\Machine\SOFTWARE\Example" or "\Registry\User" or "\Registry\User\CurrentUser" ; "MACHINE\Software\Example" or "USERS" or "CURRENT_USER\Software" ; "CLASSES_ROOT\Example" or in a remote registry such as \\ComputerName\CLASSES_ROOT\Example. ; If this parameter is NULL or an empty string, the function returns the same handle that was passed in. ; $sValueName - Optional, The name of the value to be set. If a value with this name is not already present in the key, the function adds it to the key. ; If $sValueName is NULL or an empty string, "", the function sets the type and data for the key's unnamed or default value. ; For more information, see Registry Element Size Limits. ; Registry keys do not have default values, but they can have one unnamed value, which can be of any type. ; $dwType - Optional, The type of data pointed to by the lpData parameter. For a list of the possible types, see Registry Value Types. ; |$REG_NONE (0) - No defined value type. ; |$REG_SZ (1) - (Default) A null-terminated string. This will be either a Unicode or an ANSI string, depending on whether ; | you use the Unicode or ANSI functions. ; |$REG_EXPAND_SZ (2) - A null-terminated string that contains unexpanded references to environment variables (for example, ; | "%PATH%"). It will be a Unicode or ANSI string depending on whether you use the Unicode or ANSI functions. ; | To expand the environment variable references, use the ExpandEnvironmentStrings function. ; |$REG_BINARY (3) - Binary data in any form. ; |$REG_DWORD (4) - A 32-bit number. ; |$REG_DWORD_LITTLE_ENDIAN (4) - A 32-bit number in little-endian format. ; | Windows is designed to run on little-endian computer architectures. Therefore, this value is defined ; | as REG_DWORD in the Windows header files. ; |$REG_DWORD_BIG_ENDIAN (5) - A 32-bit number in big-endian format. Some UNIX systems support big-endian architectures. ; |$REG_LINK (6) - A null-terminated Unicode string that contains the target path of a symbolic link that was ; | created by calling the RegCreateKeyEx function with REG_OPTION_CREATE_LINK. ; |$REG_MULTI_SZ (7) - A sequence of null-terminated strings, terminated by an empty string (\0). ; | The following is an example: ; | String1\0String2\0String3\0LastString\0\0 ; | The first \0 terminates the first string, the second to the last \0 terminates the last string, and the ; | final \0 terminates the sequence. Note that the final terminator must be factored into the length of the string. ; |$REG_RESOURCE_LIST (8) - Resource list in the resource map ; |$REG_FULL_RESOURCE_DESCRIPTOR (9) - Resource list in the hardware description ; |$REG_RESOURCE_REQUIREMENTS_LIST (10) - Resource list in the hardware description ; |$REG_QWORD (11) - A 64-bit number. ; |$REG_QWORD_LITTLE_ENDIAN (11) - A 64-bit number in little-endian format. ; | Windows is designed to run on little-endian computer architectures. Therefore, this value is defined ; | as REG_QWORD in the Windows header files. ; $samDesired - Optional, An access mask the specifies the platform-specific view of the registry. ; | This parameter can be one of the following values, These flags are ignored by 32-bit Windows ; |$KEY_WOW64_64KEY (256) - operate on the 64-bit registry view ; |$KEY_WOW64_32KEY (512) - operate on the 32-bit registry view ; Return values .: If the function succeeds, the return value is ERROR_SUCCESS. and set ERROR_SUCCESS error code ; If the function fails, the return value is nonzero, and set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: Calling _WinAPI_RegSetKeyValue is an expensive operation that significantly affects system-wide performance as ; it consumes disk bandwidth and blocks modifications to all keys by all processes in the registry hive that ; is being flushed until the flush operation completes. _WinAPI_RegSetKeyValue should only be called xplicitly ; ewhen an application must guarantee that registry changes are persisted to disk immediately after modification. ; All modifications made to keys are visible to other processes without the need to flush them to disk. ; Alternatively, the registry has a 'lazy flush' mechanism that flushes registry modifications to disk at regular ; intervals of time. In addition to this regular flush operation, registry changes are also flushed to disk at ; system shutdown. Allowing the 'lazy flush' to flush registry changes is the most efficient way to manage registry ; writes to the registry store on disk. ; The _WinAPI_RegSetKeyValue function returns only when all the data for the hive that contains the specified key ; has been written to the registry store on disk. ; The _WinAPI_RegSetKeyValue function writes out the data for other keys in the hive that have been modified since ; the last lazy flush or system start. ; After _WinAPI_RegSetKeyValue returns, use _WinAPI_RegCloseKey to close the handle to the registry key. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegSetKeyValue($hKey, Null, "Test", "This is Test", $REG_SZ) ; _WinAPI_RegSetKeyValue($HKEY_LOCAL_MACHINE, "SOFTWARE\KeyName", "Test", "This is Test", $REG_SZ) ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegSetKeyValue($hKey, $sSubKey = "", $sValueName = "", $vData = "", $dwType = 1, $samDesired = 0) ;;If $_WIN32_WINNT5 Then Return SetError(_WinAPI_RegSetValueEx($hKey, $sSubKey, $sValueName, $vData, $dwType) + @Error, @Extended, @Error) Switch $dwType Case 1, 2 ;; $REG_SZ, $REG_EXPAND_SZ If Not IsBinary($vData) Then $vData = StringToBinary(StringRegExpReplace(StringRegExpReplace($vData, "\\", "\\\\"), "\x00*+$", "") & Chr(0), 2) Case 5 ;; $REG_DWORD_BIG_ENDIAN If Not IsBinary($vData) Then $vData = Binary("0x" & Hex($vData, 8)) Case 6 ;; $REG_LINK $samDesired = BitOR($samDesired, 64) If Not _WinAPI_RegKeyExistEx($hKey, $sSubKey, $samDesired) And @Extended Then Return SetError(4, 2, 2) If Not IsBinary($vData) Then $vData = StringToBinary((StringRegExp($vData, "(?i)^\\Registry\\") ? $vData : _RegGetObjectNameKey($vData)), 2) Case 7 ;; $REG_MULTI_SZ If Not IsBinary($vData) Then $vData = StringToBinary(StringRegExpReplace(StringRegExpReplace(StringRegExpReplace($vData, "\n", Chr(0)), "\\", "\\\\"), "\x00*+$", "") & Chr(0) & Chr(0), 2) Case 0 To 11 ;; 0, 3, 4, 8, 9, 10, 11 ;; $REG_NONE, $REG_BINARY, $REG_DWORD, $REG_RESOURCE_LIST, $REG_FULL_RESOURCE_DESCRIPTOR, $REG_RESOURCE_REQUIREMENTS_LIST, $REG_QWORD ;; Case Else Return SetError(2, 87, 87) EndSwitch Local $cbData = ($dwType = 11 ? 8 : BinaryLen($vData)), $tData = DllStructCreate("BYTE[" & $cbData & "]") DllStructSetData($tData, 1, $vData) If Not $hKey Then $hKey = _RegGetPredefinedKeyEx($sSubKey, $samDesired) If $samDesired Then Local $hKeyEx = _WinAPI_RegCreateKey($hKey, $sSubKey, 2 + BitAND($samDesired, 768), ($dwType = 6 ? 2 : 0)) If @Error And $dwType = 6 Then $hKeyEx = _WinAPI_RegOpenKey($hKey, $sSubKey, 2 + BitAND($samDesired, 768), 8) If @Error Then Return SetError(3, @Extended, @Extended) $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegSetValueExW", "ULONG_PTR", $hKeyEx, "WSTR", $sValueName, "DWORD", 0, "DWORD", $dwType, "STRUCT*", $tData, "DWORD", $cbData) SetError(@Error + DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKeyEx)) Else $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegSetKeyValueW", "ULONG_PTR", $hKey, "WSTR", $sSubKey, "WSTR", $sValueName, "DWORD", $dwType, "STRUCT*", $tData, "DWORD", $cbData) If Not @Error And $arDllCall[0] = 5 And $REG_SPECIAL_ACCESS Then $hKey = _WinAPI_RegCreateKey($arDllCall[1], $sSubKey, 2) ;; $KEY_SET_VALUE = 0x0002 If @Error Then Return SetError(2, @Extended, @Extended) $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegSetKeyValueW", "ULONG_PTR", $hKey, "WSTR", Null, "WSTR", $sValueName, "DWORD", $dwType, "STRUCT*", $tData, "DWORD", $cbData) SetError(@Error + DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKey)) EndIf EndIf If @Error Then Return SetError(1, -@Error, 1) Return SetError($arDllCall[0], $arDllCall[0], $arDllCall[0]) EndFunc ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegQueryValue ; Description ...: Retrieves the type and data for the specified value name associated with an open registry key. ; Syntax.........: _WinAPI_RegQueryValue($hKey[, $sSubKey[, $sValueName]) ; Parameters ....: $hKey - A handle to an open registry key. The key must have been opened with the KEY_QUERY_VALUE access right. ; For more information, see Registry Key Security and Access Rights. ; This handle is returned by the _WinAPI_RegCreateKey, _WinAPI_RegCreateKeyEx, _WinAPI_RegOpenKey, _WinAPI_RegOpenKeyEx, ; It can also be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_PERFORMANCE_DATA ; $HKEY_PERFORMANCE_NLSTEXT ; $HKEY_PERFORMANCE_TEXT ; $HKEY_USERS ; This parameter can be NULL, use the NULL or 0 to set NULL this parameter, If $hKey is NULL, ; $sSubKey must be contain Full String KeyName, for more see $sSubKey ; $sSubKey - Optional, The name of the registry key to query value. Key names are not case sensitive. ; This key must be a subkey of the key identified by the $hKey parameter. ; if $hKey is Null this key must be a Full String KeyName, example ; "HKLM\SOFTWARE\Example" or "HKEY_USERS" or "HKEY_CURRENT_USER\Software" ; "\Registry\Machine\SOFTWARE\Example" or "\Registry\User" or "\Registry\User\CurrentUser" ; "MACHINE\Software\Example" or "USERS" or "CURRENT_USER\Software" ; "CLASSES_ROOT\Example" or in a remote registry such as \\ComputerName\CLASSES_ROOT\Example. ; If this parameter is NULL or an empty string, the function returns the same handle that was passed in. ; $sValueName - Optional, The name of the registry value. ; If $sValueName is NULL or an empty string, "", the function retrieves the type and data for the key's ; unnamed or default value, if any. ; If $sValueName specifies a value that is not in the registry, the function returns ERROR_FILE_NOT_FOUND. ; Keys do not automatically have an unnamed or default value. Unnamed values can be of any type. For more information, ; see Registry Element Size Limits http://msdn.microsoft.com/en-us/library/windows/desktop/ms724872(v=vs.85).aspx ; Return values .: If the function succeeds, the return value is String or INT or Binary, and set error code ERROR_SUCCESS ; and set Extended code dwValueType ; @Extended: $REG_NONE (0) ; $REG_SZ (1) ; $REG_EXPAND_SZ (2) ; $REG_BINARY (3) ; $REG_DWORD (4) - $REG_DWORD_LITTLE_ENDIAN (4) ; $REG_DWORD_BIG_ENDIAN (5) ; $REG_LINK (6) ; $REG_MULTI_SZ (7) ; $REG_RESOURCE_LIST (8) ; $REG_FULL_RESOURCE_DESCRIPTOR (9) ; $REG_RESOURCE_REQUIREMENTS_LIST (10) ; $REG_QWORD (11) - $REG_QWORD_LITTLE_ENDIAN (11) ; If the function fails, the return value is a None '', and set nonzero error code ; @Extended : -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: An application typically calls _WinAPI_RegEnumValue to determine the value names and then ; _WinAPI_RegQueryValueEx to retrieve the data for the names. ; If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, the string may not have been stored ; with the proper terminating null characters. Therefore, even if the function returns ERROR_SUCCESS, ; the application should ensure that the string is properly terminated before using it; otherwise, it ; may overwrite a buffer. (Note that REG_MULTI_SZ strings should have two terminating null characters.) ; One way an application can ensure that the string is properly terminated is to use RegGetValue, which ; adds terminating null characters if needed. ; When calling the _WinAPI_RegQueryValueEx function with $hKey set to the HKEY_PERFORMANCE_DATA handle and ; a value string of a specified object, the returned data structure sometimes has unrequested objects. ; Do not be surprised; this is normal behavior. When calling the _WinAPI_RegQueryValueEx function, you ; should always expect to walk the returned data structure to look for the requested object. ; Note that operations that access certain registry keys are redirected. For more information, ; see Registry Virtualization and 32-bit and 64-bit Application Data in the Registry. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegQueryValue($hKey, "Test") ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegQueryValue(Const ByRef $hKey, $sValueName = "") Local $tData = DllStructCreate("BYTE[4096]") $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegQueryValueExW", "ULONG_PTR", $hKey, "WSTR", $sValueName, "DWORD", 0, "DWORD*", 0, "STRUCT*", $tData, "DWORD*", 4096) If @Error Then Return SetError(1, -@Error, "") If $arDllCall[6] > 4096 Then $tData = DllStructCreate("BYTE[" & $arDllCall[6] & "]") $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegQueryValueExW", "ULONG_PTR", $hKey, "WSTR", $sValueName, "DWORD", 0, "DWORD*", 0, "STRUCT*", $tData, "DWORD*", $arDllCall[6]) EndIf If $arDllCall[0] Then Return SetError(2, $arDllCall[0], "") Switch $arDllCall[4] Case 1, 2, 6 ;; $REG_SZ, $REG_EXPAND_SZ, $REG_LINK Return SetExtended($arDllCall[4], BinaryToString(BinaryMid(DllStructGetData($tData, 1), 1, $arDllCall[6]), 2)) Case 7 ;; $REG_MULTI_SZ Return SetExtended($arDllCall[4], StringRegExpReplace(BinaryToString(BinaryMid(DllStructGetData($tData, 1), 1, $arDllCall[6]), 2), "\x00+", @LF)) Case 4 ;; $REG_DWORD, $REG_DWORD_LITTLE_ENDIAN Return SetExtended($arDllCall[4], DllStructGetData(DllStructCreate("DWORD", DllStructGetPtr($tData, 1)), 1)) ;; Or Dec(StringRegExpReplace(BinaryMid(DllStructGetData($tData, 1), 1, 4), "^..(..)(..)(..)(..)","$4$3$2$1"), 1) Case 5 ;; $REG_DWORD_BIG_ENDIAN Return SetExtended($arDllCall[4], Dec(StringMid(BinaryMid(DllStructGetData($tData, 1), 1, $arDllCall[6]), 3, 8), 1)) ;; Or Number(StringLeft(DllStructGetData($tData, 1), 10), 3) Case 11 ;; $REG_QWORD, $REG_QWORD_LITTLE_ENDIAN Return SetExtended($arDllCall[4], DllStructGetData(DllStructCreate("UINT64", DllStructGetPtr($tData, 1)), 1)) ;; Or Dec(StringRegExpReplace(BinaryMid(DllStructGetData($tData, 1), 1, 8), "^..(..)(..)(..)(..)(..)(..)(..)(..)","0x$8$7$6$5$4$3$2$1"), 2) Case Else ;; 0 To 11 ;; 0, 3, 8, 9, 10 ;; $REG_NONE, $REG_BINARY, $REG_RESOURCE_LIST, $REG_FULL_RESOURCE_DESCRIPTOR, $REG_RESOURCE_REQUIREMENTS_LIST Return SetExtended($arDllCall[4], BinaryMid(DllStructGetData($tData, 1), 1, $arDllCall[6])) EndSwitch EndFunc ;==>_WinAPI_RegQueryValue ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegQueryValueEx ; Description ...: Retrieves the type and data for the specified value name associated with an open registry key. ; Syntax.........: _WinAPI_RegQueryValueEx($hKey[, $sSubKey[, $sValueName[, $samDesired]]]) ; Parameters ....: $hKey - A handle to an open registry key. The key must have been opened with the KEY_QUERY_VALUE access right. ; For more information, see Registry Key Security and Access Rights. ; This handle is returned by the _WinAPI_RegCreateKey, _WinAPI_RegCreateKeyEx, _WinAPI_RegOpenKey, _WinAPI_RegOpenKeyEx, ; It can also be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_PERFORMANCE_DATA ; $HKEY_PERFORMANCE_NLSTEXT ; $HKEY_PERFORMANCE_TEXT ; $HKEY_USERS ; This parameter can be NULL, use the NULL or 0 to set NULL this parameter, If $hKey is NULL, ; $sSubKey must be contain Full String KeyName, for more see $sSubKey ; $sSubKey - Optional, The name of the registry key to be opened. Key names are not case sensitive. ; This key must be a subkey of the key identified by the $hKey parameter. ; if $hKey is Null this key must be a Full String KeyName, example ; "HKLM\SOFTWARE\Example" or "HKEY_USERS" or "HKEY_CURRENT_USER\Software" ; "\Registry\Machine\SOFTWARE\Example" or "\Registry\User" or "\Registry\User\CurrentUser" ; "MACHINE\Software\Example" or "USERS" or "CURRENT_USER\Software" ; "CLASSES_ROOT\Example" or in a remote registry such as \\ComputerName\CLASSES_ROOT\Example. ; If this parameter is NULL or an empty string, the function returns the same handle that was passed in. ; $sValueName - Optional, The name of the registry value. ; If $sValueName is NULL or an empty string, "", the function retrieves the type and data for the key's ; unnamed or default value, if any. ; If $sValueName specifies a value that is not in the registry, the function returns ERROR_FILE_NOT_FOUND. ; Keys do not automatically have an unnamed or default value. Unnamed values can be of any type. For more information, ; see Registry Element Size Limits http://msdn.microsoft.com/en-us/library/windows/desktop/ms724872(v=vs.85).aspx ; $samDesired - Optional, An access mask the specifies the platform-specific view of the registry. ; | this flags will be ignored if the $sSubKey is Null ; | This parameter can be one of the following values, These flags are ignored by 32-bit Windows ; |$KEY_WOW64_64KEY (256) - operate on the 64-bit registry view ; |$KEY_WOW64_32KEY (512) - operate on the 32-bit registry view ; Return values .: If the function succeeds, the return value is String or INT or Binary, and set error code ERROR_SUCCESS ; and set Extended code dwValueType ; @Extended: $REG_NONE (0) ; $REG_SZ (1) ; $REG_EXPAND_SZ (2) ; $REG_BINARY (3) ; $REG_DWORD (4) - $REG_DWORD_LITTLE_ENDIAN (4) ; $REG_DWORD_BIG_ENDIAN (5) ; $REG_LINK (6) ; $REG_MULTI_SZ (7) ; $REG_RESOURCE_LIST (8) ; $REG_FULL_RESOURCE_DESCRIPTOR (9) ; $REG_RESOURCE_REQUIREMENTS_LIST (10) ; $REG_QWORD (11) - $REG_QWORD_LITTLE_ENDIAN (11) ; If the function fails, the return value is a None '', and set nonzero error code ; @Extended : -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: An application typically calls _WinAPI_RegEnumValue to determine the value names and then ; _WinAPI_RegQueryValueEx to retrieve the data for the names. ; If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, the string may not have been stored ; with the proper terminating null characters. Therefore, even if the function returns ERROR_SUCCESS, ; the application should ensure that the string is properly terminated before using it; otherwise, it ; may overwrite a buffer. (Note that REG_MULTI_SZ strings should have two terminating null characters.) ; One way an application can ensure that the string is properly terminated is to use RegGetValue, which ; adds terminating null characters if needed. ; When calling the _WinAPI_RegQueryValueEx function with $hKey set to the HKEY_PERFORMANCE_DATA handle and ; a value string of a specified object, the returned data structure sometimes has unrequested objects. ; Do not be surprised; this is normal behavior. When calling the _WinAPI_RegQueryValueEx function, you ; should always expect to walk the returned data structure to look for the requested object. ; Note that operations that access certain registry keys are redirected. For more information, ; see Registry Virtualization and 32-bit and 64-bit Application Data in the Registry. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegQueryValueEx($hKey, Null, "Test") ; _WinAPI_RegQueryValueEx($HKEY_LOCAL_MACHINE, "SOFTWARE\KeyName", "Test") ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegQueryValueEx($hKey, $sSubKey = "", $sValueName = "", $samDesired = 0) Local $tData = DllStructCreate("BYTE[4096]") If Not $hKey Then $hKey = _RegGetPredefinedKeyEx($sSubKey, $samDesired) If $sSubKey Then $hKey = _WinAPI_RegOpenKey($hKey, $sSubKey, 1 + BitAND($samDesired, 768), BitAND($samDesired, 8)) ;; $KEY_QUERY_VALUE = 0x0001 $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegQueryValueExW", "ULONG_PTR", $hKey, "WSTR", $sValueName, "DWORD", 0, "DWORD*", 0, "STRUCT*", $tData, "DWORD*", 4096) If @Error Then Return SetError(1, -@Error + ($sSubKey ? DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKey) : 0), "") If $arDllCall[6] > 4096 Then $tData = DllStructCreate("BYTE[" & $arDllCall[6] & "]") $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegQueryValueExW", "ULONG_PTR", $hKey, "WSTR", $sValueName, "DWORD", 0, "DWORD*", 0, "STRUCT*", $tData, "DWORD*", $arDllCall[6]) EndIf If $sSubKey Then DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKey) If $arDllCall[0] Then Return SetError(2, $arDllCall[0], "") Switch $arDllCall[4] Case 1, 2, 6 ;; $REG_SZ, $REG_EXPAND_SZ, $REG_LINK Return SetExtended($arDllCall[4], BinaryToString(BinaryMid(DllStructGetData($tData, 1), 1, $arDllCall[6]), 2)) Case 7 ;; $REG_MULTI_SZ Return SetExtended($arDllCall[4], StringRegExpReplace(BinaryToString(BinaryMid(DllStructGetData($tData, 1), 1, $arDllCall[6]), 2), "\x00+", @LF)) Case 4 ;; $REG_DWORD, $REG_DWORD_LITTLE_ENDIAN Return SetExtended($arDllCall[4], DllStructGetData(DllStructCreate("DWORD", DllStructGetPtr($tData, 1)), 1)) ;; Or Dec(StringRegExpReplace(BinaryMid(DllStructGetData($tData, 1), 1, 4), "^..(..)(..)(..)(..)","$4$3$2$1"), 1) Case 5 ;; $REG_DWORD_BIG_ENDIAN Return SetExtended($arDllCall[4], Dec(StringMid(BinaryMid(DllStructGetData($tData, 1), 1, $arDllCall[6]), 3, 8), 1)) ;; Or Number(StringLeft(DllStructGetData($tData, 1), 10), 3) Case 11 ;; $REG_QWORD, $REG_QWORD_LITTLE_ENDIAN Return SetExtended($arDllCall[4], DllStructGetData(DllStructCreate("UINT64", DllStructGetPtr($tData, 1)), 1)) ;; Or Dec(StringRegExpReplace(BinaryMid(DllStructGetData($tData, 1), 1, 8), "^..(..)(..)(..)(..)(..)(..)(..)(..)","0x$8$7$6$5$4$3$2$1"), 2) Case Else ;; 0 To 11 ;; 0, 3, 8, 9, 10 ;; $REG_NONE, $REG_BINARY, $REG_RESOURCE_LIST, $REG_FULL_RESOURCE_DESCRIPTOR, $REG_RESOURCE_REQUIREMENTS_LIST Return SetExtended($arDllCall[4], BinaryMid(DllStructGetData($tData, 1), 1, $arDllCall[6])) EndSwitch EndFunc ;==>_WinAPI_RegQueryValueEx ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegSaveKeyEx ; Description ...: Saves the specified key and all of its subkeys and values to a registry file, in the specified format. ; Syntax.........: _WinAPI_RegSaveKeyEx($hKey, $lpFile[, $dwFlags]) ; Parameters ....: $hKey - A handle to an open registry key. This function does not support the HKEY_CLASSES_ROOT predefined key. ; $lpFile - The name of the file in which the specified key and subkeys are to be saved. If the file already exists, the function fails. ; The new file has the archive attribute. ; If the string does not include a path, the file is created in the current directory of the calling process ; for a local key, or in the %systemroot%\system32 directory for a remote key. ; $dwFlags - Optional The format of the saved key or hive. This parameter can be one of the following values. ; |$dwFlags = 1 The key or hive is saved in standard format. The standard format is the only format supported by Windows 2000. ; |$dwFlags = 2 (Default) The key or hive is saved in the latest format. The latest format is supported starting with Windows XP. ; | After the key or hive is saved in this format, it cannot be loaded on an earlier system. ; |$dwFlags = 4 The hive is saved with no compression, for faster save operations. The hKey parameter must specify the root of ; | a hive under HKEY_LOCAL_MACHINE or HKEY_USERS. For example, HKLM\SOFTWARE is the root of a hive. ; Return values .: If the function succeeds set ERROR_SUCCESS error code ; If the function fails set nonzero error code, and set Extended error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: Unlike RegSaveKey, this function does not support the HKEY_CLASSES_ROOT predefined key. ; If hKey represents a key on a remote computer, the path described by lpFile is relative to the remote computer. ; The RegSaveKeyEx function saves only nonvolatile keys. It does not save volatile keys. A key is ; made volatile or nonvolatile at its creation; see RegCreateKeyEx. ; You can use the file created by RegSaveKeyEx in subsequent calls to the RegLoadKey, RegReplaceKey, ; or RegRestoreKey function. If RegSaveKeyEx fails partway through its operation, the file will be ; corrupt and subsequent calls to RegLoadKey, RegReplaceKey, or RegRestoreKey for the file will fail. ; Using RegSaveKeyEx together with RegRestoreKey to copy subtrees in the registry is not recommended. ; This method does not trigger notifications and can invalidate handles used by other applications. ; Instead, use the SHCopyKey function or the RegCopyTree function. ; The calling process must have the SE_BACKUP_NAME privilege enabled. For more information, see Running with Special Privileges. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegSaveKeyEx($HKEY_LOCAL_MACHINE, "SOFTWARE\KeyName") ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegSaveKeyEx(Const ByRef $hKey, $lpFile, $dwFlags = 2) FileDelete($lpFile) $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegSaveKeyExW", "ULONG_PTR", $hKey, "WSTR", $lpFile, "PTR", Null, "DWORD", $dwFlags) If @Error Then Return SetError(1, -@Error, 0) Return SetError($arDllCall[0], 0, 0) EndFunc ;==>_WinAPI_RegSaveKeyEx ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegRestoreKey ; Description ...: Reads the registry information in a specified file and copies it over the specified key. This registry ; information may be in the form of a key and multiple levels of subkeys. ; Applications that back up or restore system state including system files and registry hives ; should use the Volume Shadow Copy Service instead of the registry functions. ; Syntax.........: _WinAPI_RegRestoreKey($hKey, $lpFile[, $dwFlags]) ; Parameters ....: $hKey - A handle to an open registry key. The key must have been opened with the KEY_QUERY_VALUE access right. ; For more information, see Registry Key Security and Access Rights. ; This handle is returned by the _WinAPI_RegCreateKeyEx or _WinAPI_RegOpenKeyEx or _WinAPI_RegCreateKey or _WinAPI_RegOpenKey ; function, or it can be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_PERFORMANCE_DATA ; $HKEY_USERS ; Any information contained in this key and its descendent keys is overwritten by the information ; in the file pointed to by the $lpFile parameter. ; $lpFile - The name of the file with the registry information. This file is typically created by using the _WinAPI_RegSaveKeyEx function. ; $dwFlags - Optional, The flags that indicate how the key or keys are to be restored. This parameter can be one of the following values. ; |$dwFlags = 1 If specified, a new, volatile (memory only) set of registry information, or hive, is created. If REG_WHOLE_HIVE_VOLATILE ; is specified, the key identified by the hKey parameter must be either the HKEY_USERS or HKEY_LOCAL_MACHINE value. ; |$dwFlags = 8 If specified, the restore operation is executed even if open handles exist at or beneath the location ; | in the registry hierarchy to which the hKey parameter points. ; Return values .: If the function succeeds set ERROR_SUCCESS error code ; If the function fails set nonzero error code, and set Extended error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: There are two different registry hive file formats. Registry hives created on current operating systems ; typically cannot be loaded by earlier ones. ; If any subkeys of the hKey parameter are open, RegRestoreKey fails. ; The calling process must have the SE_RESTORE_NAME and SE_BACKUP_NAME privileges on the computer in which ; the registry resides. For more information, see Running with Special Privileges. ; This function replaces the keys and values below the specified key with the keys and values that are subsidiary ; to the top-level key in the file, no matter what the name of the top-level key in the file might be. For example, ; hKey might identify a key A with subkeys B and C, while the lpFile parameter specifies a file containing key X ; with subkeys Y and Z. After a call to RegRestoreKey, the registry would contain key A with subkeys Y and Z. ; The value entries of A would be replaced by the value entries of X. ; The new information in the file specified by lpFile overwrites the contents of the key specified by the hKey parameter, ; except for the key name. ; If hKey represents a key in a remote computer, the path described by lpFile is relative to the remote computer. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegRestoreKey($HKEY_LOCAL_MACHINE, "SOFTWARE\KeyName") ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegRestoreKey(Const ByRef $hKey, $lpFile, $dwFlags = 8) $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegRestoreKeyW", "ULONG_PTR", $hKey, "WSTR", $lpFile, "DWORD", $dwFlags) If @Error Then Return SetError(1, -@Error, 0) Return SetError($arDllCall[0], 0, 0) EndFunc ;==>_WinAPI_RegRestoreKey ; #FUNCTION# ==================================================================================================================== ; Name...........: _RegGetPredefinedKeyEx ; Description ...: Get HKEY Handle\KeyName\ObjectName ; Syntax.........: _RegGetPredefinedKeyEx(ByRef $szKey, ByRef $iType[, $iFlags]) ; Parameters ....: $szKey - HKEY Name ; $iType - A mask that specifies the access rights for the key ; $iFlags - Optional ; |0 - (Default) Return $iPredefinedKey ; |1 - Return HKEY String for Inf File (AddReg\DelReg Directive) ; |2 - Return SE_REGISTRY_KEY String for SDDL (StringSecurityDescriptorEx) ; |3 - Return KEY ObjectName String (Registry Key Object Routines) ; Return values .: HKEY Handle\KeyName\ObjectName ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func _RegGetPredefinedKeyEx(ByRef $szKey, ByRef $iType, $iFlags = 0) $iFlags = BitAND($iFlags, 3) Local $ahKey = StringRegExp($szKey, "^[\h\\]*+([^\W\d]*+)((?:32|64)?+(?!\w))\\*+(.*)", 1) If @Error Then Return SetError(1, 0, $HKEY_PREDEFINED[10][$iFlags]) Switch $ahKey[0] Case "HKCR","HKEY_CLASSES_ROOT", "CLASSES_ROOT";, "MACHINE\SOFTWARE\Classes" $ahKey[0] = 0 Case "HKCU", "HKEY_CURRENT_USER", "CURRENT_USER" $ahKey[0] = 1 Case "HKLM", "HKEY_LOCAL_MACHINE", "MACHINE" $ahKey[0] = 2 Case "HKU", "HKEY_USERS", "USERS" $ahKey[0] = 3 Case "HKCC", "HKEY_CURRENT_CONFIG";, "MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles\Current" $ahKey[0] = 4 If $iFlags = 1 Then $ahKey[2] = "SYSTEM\CurrentControlSet\Hardware Profiles\Current" & StringRegExpReplace($ahKey[2], "^.", "\\$0") Case "HKLS", "HKEY_CURRENT_USER_LOCAL_SETTINGS";, "CURRENT_USER\Software\Classes\Local Settings" $ahKey[0] = 5 If $iFlags = 1 Then $ahKey[2] = "Software\Classes\Local Settings" & StringRegExpReplace($ahKey[2], "^.", "\\$0") Case "HKPD", "HKEY_PERFORMANCE_DATA" $ahKey[0] = 6 Case "HKDD", "HKEY_DYN_DATA" $ahKey[0] = 7 Case "HKPT", "HKEY_PERFORMANCE_TEXT" $ahKey[0] = 8 Case "HKPN", "HKEY_PERFORMANCE_NLSTEXT" $ahKey[0] = 9 Case "Registry" $ahKey = StringRegExp($ahKey[2], "(?i)^(?|(Machine)((?:\\+SYSTEM\\+CurrentControlSet\\+Hardware Profiles\\+Current(?!\w)|\\+SOFTWARE\\+Classes(?!\w))?+)|User((?:\\+CurrentUser(?!\w)|\\+S-1-5-\d+-\d+-\d+-\d+-\d+)?+)((?:\\+Software\\+Classes\\+Local Settings(?!\w)|\\+_CLASSES\\+Local Settings(?!\w)|\\+_CLASSES(?!\w))?+))\\*(.*)", 1) If @Error Then Return SetError(1, 0, $HKEY_PREDEFINED[10][$iFlags]) If $ahKey[0] = "Machine" Then $ahKey[0] = Not $ahKey[1] ? 2 : (StringRegExp($ahKey[1], "(?i)^\\+SO") ? 0 : 4) If $ahKey[0] = 4 And $iFlags = 1 Then $ahKey[2] = "SYSTEM\CurrentControlSet\Hardware Profiles\Current" & StringRegExpReplace($ahKey[2], "^.", "\\$0") Else $ahKey[0] = Not $ahKey[0] ? 3 : (StringRight($ahKey[1], 2) = "gs" ? 5 : 1) If ($ahKey[0] = 5 And $iFlags = 1) Or ($ahKey[1] And $ahKey[0] = 3) Then $ahKey[2] = "Software\Classes" & ($ahKey[0] = 5 ? "\Local Settings" : "") & StringRegExpReplace($ahKey[2], "^.", "\\$0") EndIf Case Else If $iFlags = 2 Then $iType = ($iType = 12) ? $SE_REGISTRY_WOW64_32KEY : $SE_REGISTRY_KEY If $iFlags = 2 Or Not StringRegExp($szKey, "^\h*\\+[^\\]+\\+") Then Return SetError(1, 0, $HKEY_PREDEFINED[10][$iFlags]) $ahKey[0] = StringRegExpReplace($szKey, "^\h*\\+[^\\]+\\+", "") $ahKey[1] = _RegGetPredefinedKeyEx($ahKey[0], $iType, $iFlags) If Not @Error Then $szKey = $ahKey[0] Return SetError(@Error, 0, $ahKey[1]) EndSwitch If $iFlags = 2 Then $iType = ($ahKey[1] == "32") ? $SE_REGISTRY_WOW64_32KEY : $SE_REGISTRY_KEY $szKey = $HKEY_PREDEFINED[$ahKey[0]][$iFlags] & StringRegExpReplace($ahKey[2], "^.", "\\$0") Return $szKey ElseIf $iFlags = 3 Then If $ahKey[0] > 5 Then Return SetError(1, 0, "") Return $HKEY_PREDEFINED[$ahKey[0]][$iFlags] & StringRegExpReplace($ahKey[2], "^.", "\\$0") Else ;;If $ahKey[1] Then $iType = BitOR($iType, ($ahKey[1] == "32" ? $KEY_WOW64_32KEY : $KEY_WOW64_64KEY)) If $ahKey[1] Then $iType = BitXOR(BitOR($iType, $KEY_WOW64_RES), ($ahKey[1] == "32" ? $KEY_WOW64_64KEY : $KEY_WOW64_32KEY)) $szKey = $ahKey[2] ? $ahKey[2] : Null Return $HKEY_PREDEFINED[$ahKey[0]][$iFlags] EndIf EndFunc ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegDeleteValue ; Description ...: Removes a named value from the specified registry key. Note that value names are not case sensitive. ; Syntax.........: _WinAPI_RegDeleteValue($hKey[, $sValueName]) ; Parameters ....: $hKey - A handle to an open registry key. The key must have been opened with the $KEY_SET_VALUE access right. ; For more information, see Registry Key Security and Access Rights. ; This handle is returned by the _WinAPI_RegCreateKeyEx or _WinAPI_RegOpenKeyEx or _WinAPI_RegCreateKey or _WinAPI_RegOpenKey ; function, or it can be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_USERS ; $sValueName - Optional, The name of the registry value to be removed from the key. ; If $sValueName is NULL or an empty string, "", the function retrieves the type and data for the key's ; unnamed or default value, if any. ; If $sValueName specifies a value that is not in the registry, the function returns ERROR_FILE_NOT_FOUND. ; Keys do not automatically have an unnamed or default value. Unnamed values can be of any type. For more information, ; see Registry Element Size Limits http://msdn.microsoft.com/en-us/library/windows/desktop/ms724872(v=vs.85).aspx ; Return values .: If the function succeeds, the return value is ERROR_SUCCESS and set ERROR_SUCCESS error code ; If the function fails, the return value is a nonzero, and set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegDeleteValue($hKey, "ValueName") ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegDeleteValue(Const ByRef $hKey, $sValueName = "") $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegDeleteValueW", "ULONG_PTR", $hKey, "WSTR", $sValueName) If @Error Then Return SetError(1, -@Error, 1) Return SetError($arDllCall[0], $arDllCall[0], $arDllCall[0]) EndFunc ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegDeleteEmptyKey ; Description ...: Deletes an empty key. ; Syntax.........: _WinAPI_RegDeleteEmptyKey($hKey[, $sSubKey[, $samDesired]]) ; Parameters ....: $hKey - A handle to an open registry key. This handle is returned by the _WinAPI_RegCreateKeyEx or _WinAPI_RegOpenKeyEx ; or _WinAPI_RegCreateKey or _WinAPI_RegOpenKey function, or it can be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_USERS ; This parameter can be NULL, use the NULL or 0 to set NULL this parameter, If $hKey is NULL, ; $sSubKey must be contain Full String KeyName, for more see $sSubKey ; $sSubKey - The name of the key to be deleted. Key names are not case sensitive. ; This key must be a subkey of the key specified by the value of the $hKey parameter. ; The function opens the subkey with the DELETE access right ; if $hKey is Null this key must be a Full String KeyName, example ; "HKLM\SOFTWARE\Example" or "HKEY_USERS" or "HKEY_CURRENT_USER\Software" ; "\Registry\Machine\SOFTWARE\Example" or "\Registry\User" or "\Registry\User\CurrentUser" ; "MACHINE\Software\Example" or "USERS" or "CURRENT_USER\Software" ; "CLASSES_ROOT\Example" or in a remote registry such as \\ComputerName\CLASSES_ROOT\Example. ; $samDesired - Optional, An access mask the specifies the platform-specific view of the registry. ; | These flags are ignored by 32-bit Windows ; |$KEY_WOW64_64KEY (256) - operate on the 64-bit registry view ; |$KEY_WOW64_32KEY (512) - operate on the 32-bit registry view ; Return values .: If the function succeeds, the return value is ERROR_SUCCESS and set ERROR_SUCCESS error code ; If the function fails, the return value is a nonzero, and set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: _WinAPI_RegDeleteEmptyKey does not delete a key if it contains any subkeys or values. Use _WinAPI_SHDeleteKey instead. ; Alternatively, use the _WinAPI_RegDeleteKey or _WinAPI_RegDeleteTree function. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegDeleteEmptyKey($HKEY_LOCAL_MACHINE, "Software\KeyName") ; _WinAPI_RegDeleteEmptyKey(Null, "HKLM\Software\KeyName") ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegDeleteEmptyKey($hKey, $sSubKey = Null, $samDesired = 0) If Not $hKey Then $hKey = _RegGetPredefinedKeyEx($sSubKey, $samDesired) If $sSubKey Or $samDesired Then $hKey = _WinAPI_RegOpenKey($hKey, $sSubKey, BitOR($samDesired, 65539)) ;; 65539 = BitOr($DELETE, $KEY_QUERY_VALUE, $KEY_SET_VALUE) If @Error Then Return SetError(2, @Extended, 2) $arDllCall = DllCall($hShlwapiDll, "LONG", "SHDeleteEmptyKeyW", "ULONG_PTR", $hKey, "WSTR", "") SetError(@Error + DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKey)) Else $arDllCall = DllCall($hShlwapiDll, "LONG", "SHDeleteEmptyKeyW", "ULONG_PTR", $hKey, "WSTR", "") ;; ($sSubKey ? $sSubKey : "") EndIf If @Error Then Return SetError(1, -@Error, 1) Return SetError($arDllCall[0], $arDllCall[0], $arDllCall[0]) EndFunc ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegDeleteEmptyKeyEx ; Description ...: Deletes an empty key. ; Syntax.........: _WinAPI_RegDeleteEmptyKeyEx($hKey[, $sSubKey[, $samDesired]]) ; Parameters ....: $hKey - A handle to an open registry key. This handle is returned by the _WinAPI_RegCreateKeyEx or _WinAPI_RegOpenKeyEx ; or _WinAPI_RegCreateKey or _WinAPI_RegOpenKey function, or it can be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_USERS ; This parameter can be NULL, use the NULL or 0 to set NULL this parameter, If $hKey is NULL, ; $sSubKey must be contain Full String KeyName, for more see $sSubKey ; $sSubKey - The name of the key to be deleted. Key names are not case sensitive. ; This key must be a subkey of the key specified by the value of the $hKey parameter. ; The function opens the subkey with the DELETE access right ; if $hKey is Null this key must be a Full String KeyName, example ; "HKLM\SOFTWARE\Example" or "HKEY_USERS" or "HKEY_CURRENT_USER\Software" ; "\Registry\Machine\SOFTWARE\Example" or "\Registry\User" or "\Registry\User\CurrentUser" ; "MACHINE\Software\Example" or "USERS" or "CURRENT_USER\Software" ; "CLASSES_ROOT\Example" or in a remote registry such as \\ComputerName\CLASSES_ROOT\Example. ; $samDesired - Optional, An access mask the specifies the platform-specific view of the registry. ; | These flags are ignored by 32-bit Windows ; |$KEY_WOW64_64KEY (256) - operate on the 64-bit registry view ; |$KEY_WOW64_32KEY (512) - operate on the 32-bit registry view ; Return values .: If the function succeeds, the return value is ERROR_SUCCESS and set ERROR_SUCCESS error code ; If the function fails, the return value is a nonzero, and set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: Unlike the _WinAPI_RegDeleteEmptyKey function, the _WinAPI_RegDeleteEmptyKeyEx function check is Key ; is Symbolic Link, if Key is Symbolic Link the _WinAPI_RegDeleteEmptyKeyEx delete symbolic link itself ; and not the Key that the symbolic link refers to ; _WinAPI_RegDeleteEmptyKeyEx does not delete a key if it contains any subkeys or values. Use _WinAPI_SHDeleteKey instead. ; Alternatively, use the _WinAPI_RegDeleteKey or _WinAPI_RegDeleteTree function. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegDeleteEmptyKeyEx($HKEY_LOCAL_MACHINE, "Software\KeyName") ; _WinAPI_RegDeleteEmptyKeyEx(Null, "HKLM\Software\KeyName") ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegDeleteEmptyKeyEx($hKey, $sSubKey = Null, $samDesired = 0) If Not $hKey Then $hKey = _RegGetPredefinedKeyEx($sSubKey, $samDesired) If $sSubKey Or $samDesired Then Local $hLinkKey = _WinAPI_RegOpenKey($hKey, $sSubKey, BitOR($samDesired, 65539), 8) ;; 65539 = BitOr($DELETE, $KEY_QUERY_VALUE, $KEY_SET_VALUE, $KEY_ENUMERATE_SUB_KEYS) If @Error Then Return SetError(2, @Extended, 2) $hKey = _WinAPI_RegOpenKey($hKey, $sSubKey, BitOR($samDesired, 65539)) ;; 65539 = BitOr($DELETE, $KEY_QUERY_VALUE, $KEY_SET_VALUE, $KEY_ENUMERATE_SUB_KEYS) If @Error Or (_NTAPI_GetRegKeyNameByHandle($hLinkKey) <> _NTAPI_GetRegKeyNameByHandle($hKey)) Then _WinAPI_RegDeleteValue($hLinkKey, "SymbolicLinkValue") DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKey) If (_WinAPI_RegEnumValue($hLinkKey, 0) Or Not @Error) Or (_WinAPI_RegEnumKey($hLinkKey, 0) Or Not @Error) Then Return SetError(1, 145, 1 + _WinAPI_RegCloseKey($hLinkKey)) $hKey = _WinAPI_RegDeleteKey($hLinkKey) Return SetError(@Error, @Extended + DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hLinkKey), $hKey) ElseIf (Not _WinAPI_RegEnumValue($hKey, Int(_WinAPI_RegEnumValue($hKey, 0) = "SymbolicLinkValue" And @Extended = 6)) And @Error) And (Not _WinAPI_RegEnumKey($hKey, 0) And @Error) Then _WinAPI_RegDeleteValue($hKey, "SymbolicLinkValue") $hKey = _WinAPI_RegDeleteKey($hKey) Return SetError(@Error, @Extended, $hKey) EndIf Return SetError(1, 145, 1) ;; ERROR_DIR_NOT_EMPTY - 145 (0x91) - The directory is not empty. EndFunc ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegDeleteKey ; Description ...: Deletes a subkey and its values. Note that key names are not case sensitive. ; Syntax.........: _WinAPI_RegDeleteKey($hKey[, $sSubKey[, $samDesired]]) ; Parameters ....: $hKey - A handle to an open registry key. This handle is returned by the _WinAPI_RegCreateKeyEx or _WinAPI_RegOpenKeyEx ; or _WinAPI_RegCreateKey or _WinAPI_RegOpenKey function, or it can be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_USERS ; This parameter can be NULL, use the NULL or 0 to set NULL this parameter, If $hKey is NULL, ; $sSubKey must be contain Full String KeyName, for more see $sSubKey ; $sSubKey - The name of the key to be deleted. Key names are not case sensitive. ; This key must be a subkey of the key specified by the value of the $hKey parameter. ; The function opens the subkey with the $DELETE access right ; The value of this parameter cannot be NULL, if this parameter is NULL _WinAPI_RegDeleteKey ; will use The ZwDeleteKey routine deletes an open key from the registry. ; if $hKey is Null this key must be a Full String KeyName, example ; "HKLM\SOFTWARE\Example" or "HKEY_USERS" or "HKEY_CURRENT_USER\Software" ; "\Registry\Machine\SOFTWARE\Example" or "\Registry\User" or "\Registry\User\CurrentUser" ; "MACHINE\Software\Example" or "USERS" or "CURRENT_USER\Software" ; "CLASSES_ROOT\Example" or in a remote registry such as \\ComputerName\CLASSES_ROOT\Example. ; $samDesired - Optional, An access mask the specifies the platform-specific view of the registry. ; | if Minimum supported client is not Windows Vista, Windows XP Professional x64 Edition ; | this flags will be ignored if the $hKey is not Null ; | This parameter can be one of the following values, These flags are ignored by 32-bit Windows ; |$KEY_WOW64_64KEY (256) - operate on the 64-bit registry view ; |$KEY_WOW64_32KEY (512) - operate on the 32-bit registry view ; Return values .: If the function succeeds, the return value is ERROR_SUCCESS and set ERROR_SUCCESS error code ; If the function fails, the return value is a nonzero, and set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: A deleted key is not removed until the last handle to it is closed. ; The subkey to be deleted must not have subkeys. To delete a key and all its subkeys, you need to enumerate the subkeys ; and delete them individually. To delete keys recursively, use the _WinAPI_RegDeleteTree or _WinAPI_SHDeleteKey function. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegDeleteKey($HKEY_LOCAL_MACHINE, "Software\KeyName") ; _WinAPI_RegDeleteKey(Null, "HKLM\Software\KeyName") ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegDeleteKey($hKey, $sSubKey = Null, $samDesired = 0) If $sSubKey Then ;;Static $_WIN32_WINNT5 = StringRegExp(@OSVersion, "(?i)WIN_(?:XP|XPe|2000|2003)") If Not $hKey Then $hKey = _RegGetPredefinedKeyEx($sSubKey, $samDesired) $arDllCall = $_WIN32_WINNT5 ? DllCall($hAdvapi32Dll, "LONG", "RegDeleteKeyW", "ULONG_PTR", $hKey, "WSTR", $sSubKey) : DllCall($hAdvapi32Dll, "LONG", "RegDeleteKeyExW", "ULONG_PTR", $hKey, "WSTR", $sSubKey, "DWORD", $samDesired, "DWORD", 0) If @Error Then Return SetError(1, -@Error, 1) If $arDllCall[0] = 5 Or $arDllCall[0] = 206 Then ;; ERROR_ACCESS_DENIED - 5 (0x5) or ERROR_FILENAME_EXCED_RANGE - 206 (0xCE) - The filename or extension is too long. $sSubKey = StringRegExp($sSubKey, "^\\*+(?|(.*)\\+([^\\]*)|(\x00?)(.*))$", 1) $hKey = _WinAPI_RegOpenKey($hKey, $sSubKey[0], BitOR($samDesired, 65539)) ;; 65539 = BitOr($DELETE, $KEY_QUERY_VALUE, $KEY_SET_VALUE) If @Error Then Return SetError(3, @Extended, 3) $arDllCall = $_WIN32_WINNT5 ? DllCall($hAdvapi32Dll, "LONG", "RegDeleteKeyW", "ULONG_PTR", $hKey, "WSTR", $sSubKey[1]) : DllCall($hAdvapi32Dll, "LONG", "RegDeleteKeyExW", "ULONG_PTR", $hKey, "WSTR", $sSubKey[1], "DWORD", $samDesired, "DWORD", 0) If $arDllCall[0] = 5 And _WinAPI_RegSetKeyDefaultAccess($hKey, $sSubKey[1], $samDesired) Then $arDllCall = $_WIN32_WINNT5 ? DllCall($hAdvapi32Dll, "LONG", "RegDeleteKeyW", "ULONG_PTR", $hKey, "WSTR", $sSubKey[1]) : DllCall($hAdvapi32Dll, "LONG", "RegDeleteKeyExW", "ULONG_PTR", $hKey, "WSTR", $sSubKey[1], "DWORD", $samDesired, "DWORD", 0) EndIf SetError(@Error + DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKey)) EndIf Else ;;;;If BitAND($samDesired, $KEY_SYMBOLIC_LINK) Then DllCall($hAdvapi32Dll, "LONG", "RegDeleteValueW", "ULONG_PTR", $hKey, "WSTR", "SymbolicLinkValue") $arDllCall = DllCall("Ntdll.dll", "LONG", "ZwDeleteKey", "ULONG_PTR", $hKey) If @Error Then Return SetError(1, -@Error, 1) If $arDllCall[0] = -1073741790 And $REG_SPECIAL_ACCESS Then ;; STATUS_ACCESS_DENIED - -1073741790 (0xC0000022) $hKey = _WinAPI_RegOpenKey($hKey, Null, 0) If @Error Then Return SetError(3, @Extended, 3) $arDllCall = DllCall("Ntdll.dll", "LONG", "ZwDeleteKey", "ULONG_PTR", $hKey) SetError(@Error + DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKey)) EndIf EndIf If @Error Or $arDllCall[0] Then Return SetError(2, (@Error ? -@Error : $arDllCall[0]), 2) Return $arDllCall[0] EndFunc ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegCloseKey ; Description ...: Closes a handle to the specified registry key. ; Syntax.........: _WinAPI_RegCloseKey($hKey) ; Parameters ....: $hKey - A handle to the open key to be closed. The handle must have been opened by the ; _WinAPI_RegCreateKey, _WinAPI_RegCreateKeyEx, _WinAPI_RegOpenKey, _WinAPI_RegOpenKeyEx function. ; Return values .: If the function succeeds, the return value is ERROR_SUCCESS and set ERROR_SUCCESS error code ; If the function fails, the return value is a 0, and set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: The handle for a specified key should not be used after it has been closed, because it will no longer be valid. ; Key handles should not be left open any longer than necessary. ; The _WinAPI_RegCloseKey function does not necessarily write information to the registry before returning; it can ; take as much as several seconds for the cache to be flushed to the hard disk. If an application must explicitly ; write registry information to the hard disk, it can use the _WinAPI_RegFlushKey function. _WinAPI_RegFlushKey, ; however, uses many system resources and should be called only when necessary. ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegCloseKey($hKey) ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegCloseKey(Const ByRef $hKey) $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKey) If @Error Then Return SetError(1, -@Error, 0) Return SetError($arDllCall[0], $arDllCall[0], 0) EndFunc ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegSetKeyDefaultAccess ; Description ...: Sets default security information in the security descriptor of a registry key ; Syntax.........: _WinAPI_RegSetKeyDefaultAccess($hKey[, $sSubKey[, $samDesired[, $sSecurityDescriptor]]]) ; Parameters ....: $hKey - A handle to an open registry key. This handle is returned by the _WinAPI_RegCreateKeyEx or _WinAPI_RegOpenKeyEx ; or _WinAPI_RegCreateKey or _WinAPI_RegOpenKey function, or it can be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_USERS ; This parameter can be NULL, use the NULL or 0 to set NULL this parameter, If $hKey is NULL, ; $sSubKey must be contain Full String KeyName, for more see $sSubKey ; $sSubKey - Optional, The name of the key to be deleted. Key names are not case sensitive. ; This key must be a subkey of the key specified by the value of the $hKey parameter. ; if $hKey is Null this key must be a Full String KeyName, example ; "HKLM\SOFTWARE\Example" or "HKEY_USERS" or "HKEY_CURRENT_USER\Software" ; "\Registry\Machine\SOFTWARE\Example" or "\Registry\User" or "\Registry\User\CurrentUser" ; "MACHINE\Software\Example" or "USERS" or "CURRENT_USER\Software" ; "CLASSES_ROOT\Example" or in a remote registry such as \\ComputerName\CLASSES_ROOT\Example. ; $samDesired - Optional, An access mask the specifies the platform-specific view of the registry. ; | This parameter can be one of the following values, These flags are ignored by 32-bit Windows ; |$KEY_WOW64_64KEY (256) - operate on the 64-bit registry view ; |$KEY_WOW64_32KEY (512) - operate on the 32-bit registry view ; $sSecurityDescriptor - String containing the string-format security descriptor, Default is "O:BAD:P(A;CI;KA;;;BA)(A;CI;KA;;;SY)(A;CI;KRKW;;;BU)" ; BuiltinAdministrators = Owner - "O:BA" ; BuiltinAdministrators = All Access - "(A;CI;KA;;;BA)" ; System = All Access - "(A;CI;KA;;;SY)" ; BuiltinUsers = Read\Write - "(A;CI;KRKW;;;BU)" ; see http://msdn.microsoft.com/en-us/library/windows/desktop/aa374928%28v=vs.85%29.aspx ; Return values .: If the function succeeds, the return value is ERROR_SUCCESS and set ERROR_SUCCESS error code ; If the function fails, the return value is a nonzero, and set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegSetKeyDefaultAccess($HKEY_LOCAL_MACHINE, "Software\KeyName") ; _WinAPI_RegSetKeyDefaultAccess(Null, "HKLM\Software\KeyName", $KEY_WOW64_64KEY) ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegSetKeyDefaultAccess($hKey, $sSubKey = "", $samDesired = 0, $sSecurityDescriptor = "O:BAD:P(A;CI;KA;;;BA)(A;CI;KA;;;SY)(A;CI;KRKW;;;BU)") Static $pSecurityDescriptor, $psidOwner, $pDacl ;, $dwSecurityInfo = 0x80000005 ;; BitOr($OWNER_SECURITY_INFORMATION, $DACL_SECURITY_INFORMATION, $PROTECTED_DACL_SECURITY_INFORMATION) $hKey = _WinAPI_RegOpenKey($hKey, $sSubKey, $samDesired) If @Error Then Return SetError(1, @Extended, 0) $arDllCall = DllCall($hAdvapi32Dll, "BOOL", "ConvertStringSecurityDescriptorToSecurityDescriptorW", "WSTR", $sSecurityDescriptor, "DWORD", 1, "PTR*", 0, "ULONG*", 0) If @Error Or Not $arDllCall[0] Then Return SetError(2, 5 + DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKey), 0) $pSecurityDescriptor = $arDllCall[3] $arDllCall = DllCall($hAdvapi32Dll,"BOOL", "GetSecurityDescriptorOwner", "PTR", $pSecurityDescriptor, "PTR*", 0, "BOOL*", 0) $psidOwner = @Error ? $PSIDADMIN : $arDllCall[2] $arDllCall = DllCall($hAdvapi32Dll, "BOOL", "GetSecurityDescriptorDacl", "PTR", $pSecurityDescriptor, "BOOL*", 0, "PTR*", 0, "BOOL*", 0) $pDacl = @Error ? Null : $arDllCall[3] $arDllCall = DllCall($hAdvapi32Dll, "DWORD", "SetSecurityInfo", "HANDLE", $hKey, "INT", 6, "DWORD", 0x80000005, "PTR", $psidOwner, "PTR", Null, "PTR", $pDacl, "PTR", Null) SetError(@Error + DllCall($hKernel32DLL, "HANDLE", "LocalFree", "HANDLE", $pSecurityDescriptor) + DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKey)) If @Error Or $arDllCall[0] Then Return SetError(3, (@Error ? -@Error : $arDllCall[0]), 0) Return 1 EndFunc ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_RegSetKeyDefaultAccessTree ; Description ...: Sets default security information in the security descriptor of the specified key recursively ; Syntax.........: _WinAPI_RegSetKeyDefaultAccessTree($hKey[, $sSubKey[, $samDesired[, $sSecurityDescriptor]]]) ; Parameters ....: $hKey - A handle to an open registry key. This handle is returned by the _WinAPI_RegCreateKeyEx or _WinAPI_RegOpenKeyEx ; or _WinAPI_RegCreateKey or _WinAPI_RegOpenKey function, or it can be one of the following predefined keys: ; $HKEY_CLASSES_ROOT ; $HKEY_CURRENT_CONFIG ; $HKEY_CURRENT_USER ; $HKEY_LOCAL_MACHINE ; $HKEY_USERS ; This parameter can be NULL, use the NULL or 0 to set NULL this parameter, If $hKey is NULL, ; $sSubKey must be contain Full String KeyName, for more see $sSubKey ; $sSubKey - Optional, The name of the key to be deleted. Key names are not case sensitive. ; This key must be a subkey of the key specified by the value of the $hKey parameter. ; if $hKey is Null this key must be a Full String KeyName, example ; "HKLM\SOFTWARE\Example" or "HKEY_USERS" or "HKEY_CURRENT_USER\Software" ; "\Registry\Machine\SOFTWARE\Example" or "\Registry\User" or "\Registry\User\CurrentUser" ; "MACHINE\Software\Example" or "USERS" or "CURRENT_USER\Software" ; "CLASSES_ROOT\Example" or in a remote registry such as \\ComputerName\CLASSES_ROOT\Example. ; $samDesired - Optional, An access mask the specifies the platform-specific view of the registry. ; | This parameter can be one of the following values, These flags are ignored by 32-bit Windows ; |$KEY_WOW64_64KEY (256) - operate on the 64-bit registry view ; |$KEY_WOW64_32KEY (512) - operate on the 32-bit registry view ; $sSecurityDescriptor - String containing the string-format security descriptor, Default is "O:BAD:P(A;CI;KA;;;BA)(A;CI;KA;;;SY)(A;CI;KRKW;;;BU)" ; BuiltinAdministrators = Owner - "O:BA" ; BuiltinAdministrators = All Access - "(A;CI;KA;;;BA)" ; System = All Access - "(A;CI;KA;;;SY)" ; BuiltinUsers = Read\Write - "(A;CI;KRKW;;;BU)" ; see http://msdn.microsoft.com/en-us/library/windows/desktop/aa374928%28v=vs.85%29.aspx ; Return values .: If the function succeeds, the return value is ERROR_SUCCESS and set ERROR_SUCCESS error code ; If the function fails, the return value is a nonzero, and set nonzero error code, and set Extended error code defined in WinError.h ; @Extended: -1 = unable to use the DLL file, ; -2 = unknown "return type", ; -3 = "function" not found in the DLL file, ; -4 = bad number of parameters, ; -5 = bad parameter. ; 0+ = error code defined in WinError.h ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; Example .......: _WinAPI_RegSetKeyDefaultAccessTree($HKEY_LOCAL_MACHINE, "Software\KeyName") ; _WinAPI_RegSetKeyDefaultAccessTree(Null, "HKLM\Software\KeyName", $KEY_WOW64_64KEY) ; Note ..........: ; =================================================================================================================================== Func _WinAPI_RegSetKeyDefaultAccessTree(Const ByRef $hKey, $sSubKey = "", $samDesired = 0, $sSecurityDescriptor = "O:BAD:P(A;CI;KA;;;BA)(A;CI;KA;;;SY)(A;CI;KRKW;;;BU)") Static $aIndexSubKey[515][2] = [[512],[0,0]], $I, $iReturn, $pSecurityDescriptor, $psidOwner, $pDacl ;, $dwSecurityInfo = 0x80000005 ;; BitOr($OWNER_SECURITY_INFORMATION, $DACL_SECURITY_INFORMATION, $PROTECTED_DACL_SECURITY_INFORMATION) $iReturn = 0 $aIndexSubKey[1][1] = _WinAPI_RegOpenKey($hKey, $sSubKey, $samDesired) If @Error Then Return SetError(1, @Extended, $iReturn) $arDllCall = DllCall($hAdvapi32Dll, "BOOL", "ConvertStringSecurityDescriptorToSecurityDescriptorW", "WSTR", $sSecurityDescriptor, "DWORD", 1, "PTR*", 0, "ULONG*", 0) If @Error Or Not $arDllCall[0] Then Return SetError(2, 5 + DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $aIndexSubKey[1][1]), $iReturn) $pSecurityDescriptor = $arDllCall[3] $arDllCall = DllCall($hAdvapi32Dll,"BOOL", "GetSecurityDescriptorOwner", "PTR", $pSecurityDescriptor, "PTR*", 0, "BOOL*", 0) $psidOwner = @Error ? $PSIDADMIN : $arDllCall[2] $arDllCall = DllCall($hAdvapi32Dll, "BOOL", "GetSecurityDescriptorDacl", "PTR", $pSecurityDescriptor, "BOOL*", 0, "PTR*", 0, "BOOL*", 0) $pDacl = @Error ? Null : $arDllCall[3] $arDllCall = DllCall($hAdvapi32Dll, "DWORD", "SetSecurityInfo", "HANDLE", $aIndexSubKey[1][1], "INT", 6, "DWORD", 0x80000005, "PTR", $psidOwner, "PTR", Null, "PTR", $pDacl, "PTR", Null) If Not (@Error Or $arDllCall[0]) Then ;; just to check DllCall @Error, to not check it more during the While\WEnd $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegEnumKeyExW", "ULONG_PTR", $aIndexSubKey[1][1], "DWORD", 0, "WSTR", "", "DWORD*", 256, "DWORD", Null, "WSTR", Null, "DWORD*", Null, "PTR", Null) $I = (@Error Or $arDllCall[0]) ? 0 : 1 $iReturn = $I While $I $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegEnumKeyExW", "ULONG_PTR", $aIndexSubKey[$I][1], "DWORD", $aIndexSubKey[$I][0], "WSTR", "", "DWORD*", 256, "DWORD", Null, "WSTR", Null, "DWORD*", Null, "PTR", Null) If $arDllCall[0] Then DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $arDllCall[1]) $aIndexSubKey[$I][0] = 0 $aIndexSubKey[$I][1] = 0 $I -= 1 ContinueLoop EndIf $aIndexSubKey[$I][0] += 1 $arDllCall = DllCall($hAdvapi32Dll, "LONG", "RegOpenKeyExW", "ULONG_PTR", $aIndexSubKey[$I][1], "WSTR", $arDllCall[3], "DWORD", 4, "DWORD", $samDesired, "ULONG_PTR*", 0) If $arDllCall[0] Then ContinueLoop DllCall($hAdvapi32Dll, "DWORD", "SetSecurityInfo", "HANDLE", $arDllCall[5], "INT", 6, "DWORD", 0x80000005, "PTR", $psidOwner, "PTR", Null, "PTR", $pDacl, "PTR", Null) $I += 1 ;;If $I > $aIndexSubKey[0][0] Then ;; (will not have to ever happen) Error Registry Element Size Limits (A registry tree can be 512 levels deep) - http://msdn.microsoft.com/en-us/library/windows/desktop/ms724872%28v=vs.85%29.aspx ;; $aIndexSubKey[0][0] *= 2 ;; ReDim $aIndexSubKey[$aIndexSubKey[0][0] + 1][2] ;;EndIf $aIndexSubKey[$I][1] = $arDllCall[5] WEnd EndIf DllCall($hKernel32DLL, "HANDLE", "LocalFree", "HANDLE", $pSecurityDescriptor) If $aIndexSubKey[1][1] Then DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $aIndexSubKey[1][1]) Return $iReturn EndFunc Func _RegGetObjectNameKey($sObjectName) Local $hKey = $sObjectName, $iDelete, $iError, $samDesired = 8 ;; $KEY_ENUMERATE_SUB_KEYS = 0x0008 Or $KEY_QUERY_VALUE = 0x0001 If IsString($sObjectName) Then $hKey = _RegGetPredefinedKeyEx($sObjectName, $samDesired) If @Error Then SetError(1, 1, "") $hKey = _WinAPI_RegOpenKey($hKey, $sObjectName, $samDesired) If @Error Then $hKey = _WinAPI_RegCreateKey($hKey, $sObjectName, $samDesired) If @Error Then Return SetError(@Error, @Extended, "") $iDelete = @Extended = 1 ? 1 : 0 EndIf EndIf $sObjectName = _NTAPI_GetRegKeyNameByHandle($hKey) $iError = @Error If $iDelete Then DllCall($hAdvapi32Dll, "LONG", "RegDeleteKeyExW", "ULONG_PTR", $hKey, "WSTR", Null, "DWORD", $samDesired, "DWORD", 0) DllCall($hAdvapi32Dll, "LONG", "RegCloseKey", "ULONG_PTR", $hKey) Return SetError($iError, 0, $sObjectName) EndFunc Func _NTAPI_GetRegKeyNameByHandle(Const ByRef $KeyHandle) Local $tKEY_INFORMATION_CLASS = DllStructCreate("ULONG;WCHAR[4096]") $arDllCall = DllCall("Ntdll.dll", "LONG", "ZwQueryKey", "ULONG_PTR", $KeyHandle, "INT", 3, "STRUCT*", $tKEY_INFORMATION_CLASS, "ULONG", DllStructGetSize($tKEY_INFORMATION_CLASS), "ULONG*", 0) If @Error Then Return SetError(@Error, 1, 0) If $arDllCall[5] > $arDllCall[4] Then ;;Or $arDllCall[0] = $STATUS_BUFFER_OVERFLOW Or $arDllCall[0] = $STATUS_BUFFER_TOO_SMALL $tKEY_INFORMATION_CLASS = DllStructCreate("ULONG;WCHAR[" & $arDllCall[5] & "]") $arDllCall = DllCall("Ntdll.dll", "LONG", "ZwQueryKey", "ULONG_PTR", $KeyHandle, "INT", 3, "STRUCT*", $tKEY_INFORMATION_CLASS, "ULONG", DllStructGetSize($tKEY_INFORMATION_CLASS), "ULONG*", 0) EndIf Return SetError($arDllCall[0], ($arDllCall[5] / 2) - 2, DllStructGetData($tKEY_INFORMATION_CLASS, 2)) EndFunc