RegEnumValue Skips Some Registry Items. How to fix?

john weiss 26 Reputation points
2021-05-05T02:16:07.467+00:00

My registry key contains 8 entries:

HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices  

Microsoft Print to PDF     :    winspool,Ne03:  
Fax    :   winspool,Ne06:  
Send To OneNote 16     :    winspool,nul:  
Hyland Software Virtual Printer   :  winspool,Ne04:  
Faxolution  :  winspool,Ne05:  
Microsoft XPS Document Writer  :  winspool,Ne02:  
PrimoPDF  :  winspool,Ne01:  
Webex Document Loader  :  winspool,Ne00:  

but RegEnumValue returns only 5 items:

Microsoft Print to PDF     :    winspool,Ne03:  
Fax    :   winspool,Ne06:  
Send To OneNote 16     :    winspool,nul:  
Hyland Software Virtual Printer   :  winspool,Ne04:  
Faxolution  :  winspool,Ne05:  

Any fix? Here's my VBA code:

' HIVES
Public Enum RegHive
HKEY_LOCAL_MACHINE = &H80000002
HKEY_CURRENT_USER = &H80000001
End Enum

' COMMON KEY-PATHS
Public Const REGPATH_ODBC = "SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources"
Public Const REGPATH_PRINTERS = "Software\Microsoft\Windows NT\CurrentVersion\Devices"

' DATA-TYPES
Public Enum RegType
REG_NONE = &H0
REG_SZ = &H1 'Nul terminated string -
REG_EXPAND_SZ = &H2 'Nul terminated string (with environment variable references) -
REG_BINARY = &H3 'Free form binary -
REG_DWORD = &H4 '32-bit number -
REG_DWORD_BIG_ENDIAN = &H5 '32-bit number. In big-endian format, the most significant byte of a word is the low-order byte -
REG_LINK = &H6 'Symbolic Link (unicode) -
REG_MULTI_SZ = &H7 'Multiple strings -
REG_RESOURCE_LIST = &H8 'Resource list in the resource map -
End Enum
' https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/25cce700-7fcf-4bb6-a2f3-0f6d08430a55

' CONSTANTS
Public Const REG_KEY_QUERY_VALUE = &H1 ' 1
Public Const REG_KEY_WOW64_64KEY = &H100 ' 256
Public Const REG_ERROR_NO_MORE_ITEMS = &H103 ' 259
Public Const REG_ERROR_MORE_DATA = &HEA ' 234
Public Const REG_KEY_ENUMERATE_SUB_KEYS = &H8
Public Const REG_KEY_READ = &H20019
Public Const REG_KEY_ALL_ACCESS = &HF003F

' DECLARATIONS

' open key
Public Declare PtrSafe Function RegOpenKeyEx Lib "advapi32.dll" Alias _
"RegOpenKeyExA" (ByVal hKey As LongPtr, ByVal lpSubKey As String, _
ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As LongPtr) As Long

' info about all values in key
Declare PtrSafe Function RegQueryInfoKey Lib "advapi32.dll" Alias "RegQueryInfoKeyA" _
(ByVal hKey As LongPtr, ByVal lpClass As String, lpcbClass As Long, ByVal lpReserved As LongPtr, _
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

' get one value.
Declare PtrSafe Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" _
(ByVal hKey As LongPtr, ByVal lpValueName As String, ByVal lpReserved As LongPtr, lpType As Long, _
lpData As Any, lpcbData As Long) As Long ' Note that if you declare the lpData parameter as String, you must pass it By Value.

' enumerate values
Public Declare PtrSafe Function RegEnumValue Lib "advapi32.dll" Alias _
"RegEnumValueA" (ByVal hKey As LongPtr, ByVal dwIndex As Long, _
ByVal lpValueName As String, lpcbValueName As Long, ByVal lpReserved As LongPtr, _
lpType As Long, lpData As Byte, lpcbData As Long) As Long

' WRITE STRING DATA
Public Declare PtrSafe Function RegSetKeyValueString Lib "advapi32.dll" Alias "RegSetKeyValueA" _
(ByVal hKey As LongPtr, ByVal lpSubKey As String, ByVal lpValueName As String, _
ByVal dwType As Long, ByVal lpData As String, ByVal cbData As Long) As Long

' WRITE NUMERIC DATA
Public Declare PtrSafe Function RegSetKeyValueLong Lib "advapi32.dll" Alias "RegSetKeyValueA" _
(ByVal hKey As Long, ByVal lpSubKey As String, ByVal lpValueName As String, _
ByVal dwType As Long, lpData As Long, ByVal cbData As Long) As Long

' Delete Value
Declare PtrSafe Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" _
(ByVal hKey As LongPtr, ByVal lpValueName As String) As Long

' close key
Public Declare PtrSafe Function Reg_CloseKey Lib "advapi32.dll" Alias "RegCloseKey" _
(ByVal hKey As LongPtr) As Long

Sub  Reg_Enumerate_Values()  
          ' open the key whose values to enumerate  
          Dim hKey As LongPtr  ' registry key handle  
          RegOpenKeyEx HKEY_CURRENT_USER, "Software\Microsoft\Windows NT\CurrentVersion\Devices", 0&, REG_KEY_ALL_ACCESS, hKey  
            
          ' loop until all values have been enumerated  
          Dim lValueIndex As Long          ' index for RegEnumValue  
          Dim sValueName As String  ' name of each value in the key  
          Dim lNameLen As Long    ' length of sValueName  
          Dim lType As RegType        ' registry value data type  
          Dim aData() As Byte    ' byte array of registry value value  
          Dim lDataSize As Long  
                      
          Do  
                    ' prep vars to rec'v data  
                    sValueName = String$(300, vbNullChar)  
                    lNameLen = 299  
                    ReDim aData(0 To 999)  
                    sData = ""  
                      
                    ' get the next item  
                    lResult = RegEnumValue(hKey, lValueIndex, sValueName, lNameLen, 0&, lType, aData(0), lDataSize)  
  
                    ' inspect variables here  
                    Stop  
                      
                    ' tell RegEnumValue to get the next registry value  
                    lValueIndex = lValueIndex + 1  
  
          Loop Until lResult = REG_ERROR_NO_MORE_ITEMS  
            
          Reg_CloseKey hKey  
  
End Function  
Windows development | Windows API - Win32
{count} votes

Accepted answer
  1. Viorel 122.9K Reputation points
    2021-05-05T17:14:49.81+00:00

    It seems that you did not initialise the lDataSize variable. Try executing the next lines before each RegEnumValue:

    ReDim aData(0 To 999)
    lDataSize = 1000
    

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.