Using RegOpenKeyEx to enumerate through registry on 64bit office/64 bit windows

Posted on 2013-12-06
Last Modified: 2016-09-30
The main objective is to see if an ODBC driver has been installed. I've been doing this by enumerating through the registry using RegOpenKeyEx . No problem using 32 bit Office on 64 Bit windows.
But won't work on 64Bit Office on 64bit  windows.

The code below shows the many things I tried. Only line 10 works when testing on 32 bit office. otherwise none of the other lines work for either 32 or 64 bit. Any ideas?


Option Compare Database
Option Explicit

#If VBA7 Then
    'For Office 64Bit
    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
    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
#End If
Function CheckForMySQlDriverInstallTest() As Boolean

'*********BEGIN CODE HERE ********
Dim strKeyPath As String, key As String
Dim i As Long, lrc As Long
Dim hkey As Long, lRetval As Long

'Various key constants
Const KEY_WOW64_64KEY As Long = &H100& '32 bit app to access 64 bit hive
Const KEY_WOW64_32KEY As Long = &H200& '64 bit app to access 32 bit hive

'Check if642bit office
If IsOffice64Bit() Then
    strKeyPath = "SOFTWARE\Wow6432Node\ODBC\ODBCINST.INI"
End If

hkey = 0

'Try various keys. Only line 10 below works, and only for 32bit office
10 lRetval = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKeyPath, 0, KEY_ALL_ACCESS, hkey)
'20 lRetval = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKeyPath, 0, KEY_WOW64_64KEY, hkey)
'30 lRetval = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKeyPath, 0, KEY_WOW64_32KEY, hkey)
'40 lRetval = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKeyPath, 0, KEY_QUERY_VALUE, hkey)

If (lRetval = 0) Then
    lrc = 0
    i = 0
    'Request all keys
    While lrc = 0
        lrc = EnumKey(hkey, i, key)
        Debug.Print key
        'If the version is found, set function to TRUE and exit
        If InStr(1, key, "MySQL ODBC 5.2 ANSI Driver") > 0 Then
            Exit Function
        End If
        If (lrc = 0) Then
            i = i + 1
        End If
End If

If (hkey <> 0) Then
    RegCloseKey hkey
End If

End Function

Open in new window

Question by:askolits
  • 5
  • 2
  • 2

Expert Comment

ID: 39702233
Make sure that the name of the driver is as you expect it to be on the 64 bit systems.  Some drivers differentiate their name between 32 and 64 bit so that matching processes dont find the wrong one.
Also make sure that IsOffice64Bit() absolutely means you will always have the 64-bit version of the MySQL driver.  If we are talking about MS office then I dont see this as guaranteed since I'm not sure that MySQL drivers come with MS Office.  
On your Office 64-bit system search the registry just for "MySQL ODBC" and see whats installed.  Was the 64-bit driver installed yet?

Author Comment

ID: 39702262
MYSQL 64Bit?
Yes, I already have a routine that will install the proper driver and I do see the key in the registry when I use regedit. So I know it's there (See image)

ODBC Reginfo For MySql

Expert Comment

ID: 39702338
On a 64-bit OS the 64-bit part of the registry is not in the Wow6432Node subkey, this subkey is actually for 32-bit stuff on the 64-bit system.
On a 64-bit OS the 64-bit part of the registry is in the same place as it would be on a 32-bit system.

If (NOT IsWindow64Bit() ) OR IsOffice64Bit() Then
Else '32-bit office on 64-bit windows
    strKeyPath = "SOFTWARE\Wow6432Node\ODBC\ODBCINST.INI"
End If

Open in new window

Three Reasons Why Backup is Strategic

Backup is strategic to your business because your data is strategic to your business. Without backup, your business will fail. This white paper explains why it is vital for you to design and immediately execute a backup strategy to protect 100 percent of your data.


Author Comment

ID: 39702354
Actually, I removed the logic and tried both those paths and it still didn't work.

Accepted Solution

askolits earned 0 total points
ID: 39709711
Figured it out.

Have to use the key "KEY_READ = &H20019" and use it in the following line:
lRetval = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKeyPath, 0, KEY_READ, hkey)

Author Closing Comment

ID: 39719752
I finally figured it out for myself and the code would be of value to others having the same problem.

Expert Comment

ID: 41822807
Registry Entry@askolits

What does the KEY_READ = &H20019 values mean?  Are there other values, how do I find what the available values and what they are used for?
 I'm trying to get list of available printers:

Code I'm using is from []

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

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

Sub get_printers()

Dim Printers()          As String       ' array of names to be returned
Dim PNdx                As Long         ' index into Printers()
Dim hKey                As LongPtr      ' registry key handle
Dim Res                 As LongPtr      ' result of API calls
Dim Ndx                 As Long         ' index for RegEnumValue
Dim ValueName           As String       ' name of each value in the printer key
Dim ValueNameLen        As Long         ' length of ValueName
Dim DataType            As Long         ' registry value data type
Dim ValueValue()        As Byte         ' byte array of registry value value
Dim ValueValueS         As String       ' ValueValue converted to String
Dim CommaPos            As Long         ' position of comma character in ValueValue
Dim ColonPos            As Long         ' position of colon character in ValueValue
Dim M                   As Long         ' string index

Const HKEY_CURRENT_USER As Long = &H80000001

Const PRINTER_KEY = "Software\Microsoft\Windows NT\CurrentVersion\Devices"

Const maxPrinters As Long = 100

ReDim ValueValue(0 To maxPrinters - 1)
ReDim Printers(1 To maxPrinters)

Ndx = 0
ValueName = String$(256, Chr(0))
ValueNameLen = Len(ValueName) - 1

MsgBox "RegOpenKeyEx Result = " & Res
'* Returns 0

Res = RegEnumValue(hKey, Ndx, ValueName, ValueNameLen, 0&, DataType, ValueValue(0), 100)
MsgBox "RegEnumValue Result = " & Res
'* Returns 87

End Sub

Author Comment

ID: 41823278
&H20019 - Permission for general read access.
Essentially allows you to read the info.

I found this info at:

I use Microsoft Access to get a list of active printers through VBA.
So, I don't read the registry. If you want the VBA code I use, I can post it.

Expert Comment

ID: 41824036
Thanks askolits - the link has what I needed!

Featured Post

Use Case: Protecting a Hybrid Cloud Infrastructure

Microsoft Azure is rapidly becoming the norm in dynamic IT environments. This document describes the challenges that organizations face when protecting data in a hybrid cloud IT environment and presents a use case to demonstrate how Acronis Backup protects all data.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
With User Account Control (UAC) enabled in Windows 7, one needs to open an elevated Command Prompt in order to run scripts under administrative privileges. Although the elevated Command Prompt accomplishes the task, the question How to run as script…
Familiarize people with the process of utilizing SQL Server stored procedures from within Microsoft Access. Microsoft Access is a very powerful client/server development tool. One of the SQL Server objects that you can interact with from within Micr…
With Microsoft Access, learn how to start a database in different ways and produce different start-up actions allowing you to use a single database to perform multiple tasks. Specify a start-up form through options: Specify an Autoexec macro: Us…

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question