Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1625
  • Last Modified:

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

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?

John

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
#Else
    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_ALL_ACCESS = &H3F
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
Const KEY_QUERY_VALUE = &H1

'Check if642bit office
If IsOffice64Bit() Then
    strKeyPath = "SOFTWARE\ODBC\ODBCINST.INI"
Else
    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
    Wend
End If

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

End Function

Open in new window

0
askolits
Asked:
askolits
  • 5
  • 2
  • 2
1 Solution
 
BeartlaoiCommented:
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?
0
 
askolitsAuthor Commented:
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
0
 
BeartlaoiCommented:
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
    strKeyPath = "SOFTWARE\ODBC\ODBCINST.INI"
Else '32-bit office on 64-bit windows
    strKeyPath = "SOFTWARE\Wow6432Node\ODBC\ODBCINST.INI"
End If

Open in new window

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
askolitsAuthor Commented:
Actually, I removed the logic and tried both those paths and it still didn't work.
0
 
askolitsAuthor Commented:
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)
0
 
askolitsAuthor Commented:
I finally figured it out for myself and the code would be of value to others having the same problem.
0
 
CrazyBritCommented:
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 [http://www.cpearson.com/excel/GetPrinters.aspx]

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 HKCU = HKEY_CURRENT_USER
Const KEY_QUERY_VALUE = &H1&
Const ERROR_NO_MORE_ITEMS = 259&
Const ERROR_MORE_DATA = 234

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

Res = RegOpenKeyEx(HKCU, PRINTER_KEY, 0&, KEY_QUERY_VALUE, hKey)
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
0
 
askolitsAuthor Commented:
&H20019 - Permission for general read access.
Essentially allows you to read the info.

I found this info at:
http://www.jasinskionline.com/windowsapi/ref/r/regopenkeyex.html

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.
1
 
CrazyBritCommented:
Thanks askolits - the link has what I needed!
1

Featured Post

Granular recovery for Microsoft Exchange

With Veeam Explorer for Microsoft Exchange you can choose the Exchange Servers and restore points you’re interested in, and Veeam Explorer will present the contents of those mailbox stores for browsing, searching and exporting.

  • 5
  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now