winapivb6registrywindows-security

RegSetValueEx returns "Access is denied", even though regedit allows the same user to edit this value


Our VB6 legacy application calls RegSetValueEx to set a registry value. This registry value can be easily set using regedit. However, when our application tries to set it, RegSetValueEx returns 5 - Access Is Denied.

We use the same code to write to other registry keys and everything works fine. Also, the user is a local administrator.

The key is opened using KEY_ALL_ACCESS, but I tried using (KEY_READ or KEY_WRITE) and that didn't work either.

Private Const READ_CONTROL = &H20000
Private Const KEY_QUERY_VALUE = &H1
Private Const KEY_SET_VALUE = &H2
Private Const KEY_CREATE_SUB_KEY = &H4
Private Const KEY_ENUMERATE_SUB_KEYS = &H8
Private Const KEY_NOTIFY = &H10
Private Const SYNCHRONIZE = &H100000
Private Const STANDARD_RIGHTS_ALL = &H1F0000
Private Const STANDARD_RIGHTS_EXECUTE = (READ_CONTROL)
Private Const STANDARD_RIGHTS_READ = (READ_CONTROL)
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const STANDARD_RIGHTS_WRITE = (READ_CONTROL)
Private Const KEY_READ = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or     KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) And (Not SYNCHRONIZE))
Private Const KEY_WRITE = ((STANDARD_RIGHTS_WRITE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY) And (Not SYNCHRONIZE))

Private Const KEY_CREATE_LINK = &H20
Private Const KEY_ALL_ACCESS = &H3F

Private Const REG_OPTION_NON_VOLATILE = 0&

Private Const HKEY_LOCAL_MACHINE = &H80000002

Dim hKey As Long
Dim e As Long
Dim lCreate As Long
Dim tSA As SECURITY_ATTRIBUTES
Dim keyOpened   As Boolean

e = RegCreateKeyEx(HKEY_LOCAL_MACHINE , "SOFTWARE\Classes\Word.Document.8", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, tSA, hKey, lCreate)

e = RegSetValueExLong(hKey, "BrowerFlags", 0&, REG_DWORD, newValue, 4)

Solution

  • Since Vista was released in 2005, access to HKEY_LOCAL_MACHINE is restricted by UAC. Your user may well be an administrator, but unless the process is started with elevated rights (which RegEdit is), UAC will prevent write access.

    In order to write to HKEY_LOCAL_MACHINE you will need to ensure that the Registry access is performed in code that is running with elevated rights. To do that, you wil need to either:

    1. Add a UAC manifest to your application to force it to execute with elevated rights. However, this means that the user will have to deal with the UAC elevation prompt every time the application is run.

    2. If you do not want to elevate your application, you will need to separate the parts of code that need elevation into a separate process, or into a COM object instantiated via the COM Elevation Moniker, whenever your application needs to perform an elevated operation.