none
VBA RegQueryInfoKey() returns incorrect number of sub keys when calling RegOpenKey() with KEY_QUERY_VALUE RRS feed

  • Question

  • Recently, one of our Excel COM-addin stop working; debug into the code, the function RegQueryInfoKey() returns incorrect number of sub keys when RegOpenKey() with KEY_QUERY_VALUE; it always return 0. But it returns correct number when RegOpenKey() with KEY_READ.

    Code example:

    Public Const HKEY_LOCAL_MACHINE = &H80000002

    Public Const KEY_QUERY_VALUE = &H1
    Public Const KEY_ENUMERATE_SUB_KEYS = &H8
    Public Const KEY_NOTIFY = &H10
    Public Const READ_CONTROL = &H20000
    Public Const STANDARD_RIGHTS_READ = (READ_CONTROL)
    Public Const SYNCHRONIZE = &H100000
    Public Const STANDARD_RIGHTS_WRITE = (READ_CONTROL)
    Public Const KEY_READ = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) And (Not SYNCHRONIZE))
     
     
    Public Type FILETIME
      dwLowDateTime As Long
      dwHighDateTime As Long
    End Type
    Public Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias _
    "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, _
    ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
    Public Declare Function RegCloseKey Lib "advapi32.dll" _
    (ByVal hKey As Long) As Long
    Public Declare Function RegQueryInfoKey Lib "advapi32.dll" Alias _
    "RegQueryInfoKeyA" (ByVal hKey As Long, ByVal lpClass As String, _
    lpcbClass As Long, ByVal lpReserved As Long, lpcSubKeys As Long, _
    lpcbMaxSubKeyLen As Long, lpcbMaxClassLen As Long, lpcValues As Long, _
    lpcbMaxValueNameLen As Long, lpcbMaxValueLen As Long, lpcbSecurityDescriptor _
    As Long, lpftLastWriteTime As FILETIME) As Long

    Sub registry()
      Dim hKey            As Long           ' handle to the registry key
      Dim retVal          As Long           ' API return value
      Dim strKey          As String         ' Key to query
      Dim keyCount        As Long           ' Number of subkeys
      Dim FT              As FILETIME       ' File write info
     
      strKey = "SOFTWARE\\Microsoft\\Office"
      ' Open the registry key with KEY_QUERY_VALUE, returns keyCount 0 in RegQueryInfoKey()
      retVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKey, 0, KEY_QUERY_VALUE, hKey)
     
      ' Open the registry key with KEY_READ returns correct keyCount in RegQueryInfoKey().
      ' retVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKey, 0, KEY_READ, hKey)
     
      ' Check to see if an error occured.
      If retVal <> 0 Then
        Debug.Print "Registry key could not be opened. Error: " & retVal
        GoTo ExitHere
      End If
     
      ' Get the number of keys below the main key.
      retVal = RegQueryInfoKey(hKey, 0, 0, 0, keyCount, 0, 0, 0, 0, 0, 0, FT)
     
      ' Check results again.
      If (retVal <> ERROR_SUCCESS) Or (keyCount <= 0) Then
        Debug.Print "Subkey count undetermined. Error: " & retVal & "  Key Count: " & keyCount
        GoTo ExitHere
      End If
     
      ' Close the key
      retVal = RegCloseKey(hKey)
    ExitHere:
    End Sub

    • Edited by LuMing1 Monday, June 22, 2020 3:53 PM
    Monday, June 22, 2020 3:53 PM

All replies