Results 1 to 13 of 13

Thread: access 64 bit registry from 32 bit app

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Oct 2008
    Posts
    248

    access 64 bit registry from 32 bit app

    I have a 32 bit VB6 application which checks a registry path of a 64 bit application installed in a 64 bit machine.So if try to access HKEY_LOCAL_MACHINE\SOFTWARE then it will be redirected to HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node. So this problem is by nature of the windows registry that 32 bit application will be accessing wow6432node. So how can avoid redirecting to wow6432node and instead access HKEY_LOCAL_MACHINE\SOFTWARE.

  2. #2
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: access 64 bit registry from 32 bit app

    Should be several threads on this here if you search. Sample code too.

    Also see Accessing an Alternate Registry View (Windows)

  3. #3
    New Member
    Join Date
    Mar 2014
    Posts
    11

    Re: access 64 bit registry from 32 bit app

    I know this thread is old but I have been trying to figure this out for several months now and am even having trouble finding some good examples. I need to force my application to read and write to HKLM regardless of if it's 64 bit or 32 bit.

    Could someone please provide me with some links to valid examples? At this point I will gladly pay for help as well.

    Thanks

  4. #4
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: access 64 bit registry from 32 bit app

    Quote Originally Posted by Mike VB View Post
    I need to force my application to read and write to HKLM regardless of if it's 64 bit or 32 bit.
    dilettante already gave a link to the MSDN topic that discusses how it can be done. Here's an excerpt of the relevant parts:

    Quote Originally Posted by MSDN
    Accessing an Alternate Registry View

    By default, a 32-bit application running on WOW64 accesses the 32-bit registry view and a 64-bit application accesses the 64-bit registry view. The following flags enable 32-bit applications to access redirected keys in the 64-bit registry view and 64-bit applications to access redirected keys in the 32-bit registry view. These flags have no effect on shared registry keys. For more information, see Registry Keys Affected by WOW64.

    Flag name Value Description
    KEY_WOW64_64KEY 0x0100 Access a 64-bit key from either a 32-bit or 64-bit application.
    KEY_WOW64_32KEY 0x0200 Access a 32-bit key from either a 32-bit or 64-bit application.
    Quote Originally Posted by Mike VB View Post
    Could someone please provide me with some links to valid examples?
    The example here shows how to open and delete a 64-bit key and its subkeys that are under HKLM.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  5. #5
    New Member
    Join Date
    Mar 2014
    Posts
    11

    Re: access 64 bit registry from 32 bit app

    Quote Originally Posted by Bonnie West View Post
    dilettante already gave a link to the MSDN topic that discusses how it can be done. Here's an excerpt of the relevant parts:





    The example here shows how to open and delete a 64-bit key and its subkeys that are under HKLM.
    Thanks, Bonnie. Do you know of any examples for writing to HKLM in 64 bit?

  6. #6
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: access 64 bit registry from 32 bit app

    Quote Originally Posted by Mike VB View Post
    Do you know of any examples for writing to HKLM in 64 bit?
    Well, I could search for examples, ... or I could make one for you. Can you describe the specific details of your problem?
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  7. #7
    New Member
    Join Date
    Mar 2014
    Posts
    11

    Re: access 64 bit registry from 32 bit app

    Quote Originally Posted by Bonnie West View Post
    Well, I could search for examples, ... or I could make one for you. Can you describe the specific details of your problem?
    Thanks, Bonnie. I wrote an application that is a companion application to another application (not written by me). The application not written by me was designed specifically to write values to HKLM and not Wow6432Node despite being on a 64 bit or 32 bit machine (for his own reasons, IDK why). Basically I need to read and write registry values to HKLM\Software\x\x regardless of if my application is being run on a 64 bit or 32 bit machine. My application is used by thousands of people around the world (literally) and is offered for free, but is not working properly anymore since the other application's developer changed the registry structure.

    Thanks very much for your help.

  8. #8
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: access 64 bit registry from 32 bit app

    OK, the following example might help you get going:

    Code:
    Option Explicit 'In a standard (.BAS) module
    
    Private Const ERROR_SUCCESS           As Long = 0
    Private Const HKEY_LOCAL_MACHINE      As Long = &H80000002
    Private Const KEY_ALL_ACCESS          As Long = &HF003F
    Private Const KEY_WOW64_32KEY         As Long = &H200
    Private Const KEY_WOW64_64KEY         As Long = &H100
    Private Const REG_OPTION_NON_VOLATILE As Long = &H0
    Private Const REG_SZ                  As Long = 1
    
    Private Const DUMMY_SUBKEY            As String = "SOFTWARE\0 Dummy Subkey"
    Private Const DUMMY_VALUE_NAME        As String = "Dummy Value Name"
    Private Const DUMMY_DATA              As String = "Dummy Data"
    
    Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
    Private Declare Function RegCreateKeyExW Lib "advapi32.dll" (ByVal hKey As Long, ByVal lpSubKey As Long, ByVal Reserved As Long, ByVal lpClass As Long, ByVal dwOptions As Long, ByVal samDesired As Long, ByVal lpSecurityAttributes As Long, ByRef phkResult As Long, Optional ByRef lpdwDisposition As Long) As Long
    Private Declare Function RegDeleteKeyExW Lib "advapi32.dll" (ByVal hKey As Long, ByVal lpSubKey As Long, ByVal samDesired As Long, Optional ByVal Reserved As Long) As Long
    Private Declare Function RegDeleteValueW Lib "advapi32.dll" (ByVal hKey As Long, Optional ByVal lpValueName As Long) As Long
    Private Declare Function RegQueryValueExW Lib "advapi32.dll" (ByVal hKey As Long, Optional ByVal lpValueName As Long, Optional ByVal lpReserved As Long, Optional ByRef lpType As Long, Optional ByVal lpData As Long, Optional ByRef lpcbData As Long) As Long
    Private Declare Function RegSetValueExW Lib "advapi32.dll" (ByVal hKey As Long, ByVal lpValueName As Long, ByVal Reserved As Long, ByVal dwType As Long, ByRef lpData As Any, ByVal cbData As Long) As Long
    Private Declare Function SysReAllocStringLen Lib "oleaut32.dll" (ByVal pBSTR As Long, Optional ByVal pszStrPtr As Long, Optional ByVal Length As Long) As Long
    
    Private Sub Main()
        Dim hKey As Long, nSize As Long, RV As Long, sBuffer As String
    
       'Create a registry key (or open it if it already exists).
       'KEY_WOW64_64KEY indicates that all operations on a 64-bit OS should be
       'done on the 64-bit registry view. That flag is ignored on a 32-bit OS.
       'The app must be running elevated if it's going to modify/delete keys under HKLM,
       'else the operation(s) will be redirected to HKCU\Software\Classes\VirtualStore.
        If RegCreateKeyExW(HKEY_LOCAL_MACHINE, StrPtr(DUMMY_SUBKEY), 0&, 0&, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS Or KEY_WOW64_64KEY, 0&, hKey) = ERROR_SUCCESS Then
    
           'Create/write a value and its corresponding data
            nSize = LenB(DUMMY_DATA) + 2& '<-- Include size of terminating Unicode null char
            If RegSetValueExW(hKey, StrPtr(DUMMY_VALUE_NAME), 0&, REG_SZ, ByVal StrPtr(DUMMY_DATA), nSize) = ERROR_SUCCESS Then
    
               'Retrieve/read the previously written value
               'Request the required buffer size first
                If RegQueryValueExW(hKey, StrPtr(DUMMY_VALUE_NAME), , , , nSize) = ERROR_SUCCESS Then
                   'Allocate the exact buffer size required
                    SysReAllocStringLen VarPtr(sBuffer), , nSize \ 2& - 1& 'nSize is in Bytes & includes the terminating Unicode null char
                   'Retrieve the value and see whether it is indeed the same data
                    RV = RegQueryValueExW(hKey, StrPtr(DUMMY_VALUE_NAME), , , StrPtr(sBuffer), nSize): Debug.Assert RV = ERROR_SUCCESS
                    Debug.Assert sBuffer = DUMMY_DATA
                End If
    
               'Delete the value and its corresponding data
                RV = RegDeleteValueW(hKey, StrPtr(DUMMY_VALUE_NAME)): Debug.Assert RV = ERROR_SUCCESS
            End If
    
            RV = RegCloseKey(hKey): Debug.Assert RV = ERROR_SUCCESS
    
           'Remove the subkey from the 64-bit view of the registry. KEY_WOW64_64KEY is ignored on a 32-bit OS.
            RV = RegDeleteKeyExW(HKEY_LOCAL_MACHINE, StrPtr(DUMMY_SUBKEY), KEY_WOW64_64KEY): Debug.Assert RV = ERROR_SUCCESS
        End If
    End Sub
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  9. #9
    New Member
    Join Date
    Mar 2014
    Posts
    11

    Re: access 64 bit registry from 32 bit app

    Quote Originally Posted by Bonnie West View Post
    OK, the following example might help you get going:

    Code:
    Option Explicit 'In a standard (.BAS) module
    
    Private Const ERROR_SUCCESS           As Long = 0
    Private Const HKEY_LOCAL_MACHINE      As Long = &H80000002
    Private Const KEY_ALL_ACCESS          As Long = &HF003F
    Private Const KEY_WOW64_32KEY         As Long = &H200
    Private Const KEY_WOW64_64KEY         As Long = &H100
    Private Const REG_OPTION_NON_VOLATILE As Long = &H0
    Private Const REG_SZ                  As Long = 1
    
    Private Const DUMMY_SUBKEY            As String = "SOFTWARE\0 Dummy Subkey"
    Private Const DUMMY_VALUE_NAME        As String = "Dummy Value Name"
    Private Const DUMMY_DATA              As String = "Dummy Data"
    
    Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
    Private Declare Function RegCreateKeyExW Lib "advapi32.dll" (ByVal hKey As Long, ByVal lpSubKey As Long, ByVal Reserved As Long, ByVal lpClass As Long, ByVal dwOptions As Long, ByVal samDesired As Long, ByVal lpSecurityAttributes As Long, ByRef phkResult As Long, Optional ByRef lpdwDisposition As Long) As Long
    Private Declare Function RegDeleteKeyExW Lib "advapi32.dll" (ByVal hKey As Long, ByVal lpSubKey As Long, ByVal samDesired As Long, Optional ByVal Reserved As Long) As Long
    Private Declare Function RegDeleteValueW Lib "advapi32.dll" (ByVal hKey As Long, Optional ByVal lpValueName As Long) As Long
    Private Declare Function RegQueryValueExW Lib "advapi32.dll" (ByVal hKey As Long, Optional ByVal lpValueName As Long, Optional ByVal lpReserved As Long, Optional ByRef lpType As Long, Optional ByVal lpData As Long, Optional ByRef lpcbData As Long) As Long
    Private Declare Function RegSetValueExW Lib "advapi32.dll" (ByVal hKey As Long, ByVal lpValueName As Long, ByVal Reserved As Long, ByVal dwType As Long, ByRef lpData As Any, ByVal cbData As Long) As Long
    Private Declare Function SysReAllocStringLen Lib "oleaut32.dll" (ByVal pBSTR As Long, Optional ByVal pszStrPtr As Long, Optional ByVal Length As Long) As Long
    
    Private Sub Main()
        Dim hKey As Long, nSize As Long, RV As Long, sBuffer As String
    
       'Create a registry key (or open it if it already exists).
       'KEY_WOW64_64KEY indicates that all operations on a 64-bit OS should be
       'done on the 64-bit registry view. That flag is ignored on a 32-bit OS.
       'The app must be running elevated if it's going to modify/delete keys under HKLM,
       'else the operation(s) will be redirected to HKCU\Software\Classes\VirtualStore.
        If RegCreateKeyExW(HKEY_LOCAL_MACHINE, StrPtr(DUMMY_SUBKEY), 0&, 0&, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS Or KEY_WOW64_64KEY, 0&, hKey) = ERROR_SUCCESS Then
    
           'Create/write a value and its corresponding data
            nSize = LenB(DUMMY_DATA) + 2& '<-- Include size of terminating Unicode null char
            If RegSetValueExW(hKey, StrPtr(DUMMY_VALUE_NAME), 0&, REG_SZ, ByVal StrPtr(DUMMY_DATA), nSize) = ERROR_SUCCESS Then
    
               'Retrieve/read the previously written value
               'Request the required buffer size first
                If RegQueryValueExW(hKey, StrPtr(DUMMY_VALUE_NAME), , , , nSize) = ERROR_SUCCESS Then
                   'Allocate the exact buffer size required
                    SysReAllocStringLen VarPtr(sBuffer), , nSize \ 2& - 1& 'nSize is in Bytes & includes the terminating Unicode null char
                   'Retrieve the value and see whether it is indeed the same data
                    RV = RegQueryValueExW(hKey, StrPtr(DUMMY_VALUE_NAME), , , StrPtr(sBuffer), nSize): Debug.Assert RV = ERROR_SUCCESS
                    Debug.Assert sBuffer = DUMMY_DATA
                End If
    
               'Delete the value and its corresponding data
                RV = RegDeleteValueW(hKey, StrPtr(DUMMY_VALUE_NAME)): Debug.Assert RV = ERROR_SUCCESS
            End If
    
            RV = RegCloseKey(hKey): Debug.Assert RV = ERROR_SUCCESS
    
           'Remove the subkey from the 64-bit view of the registry. KEY_WOW64_64KEY is ignored on a 32-bit OS.
            RV = RegDeleteKeyExW(HKEY_LOCAL_MACHINE, StrPtr(DUMMY_SUBKEY), KEY_WOW64_64KEY): Debug.Assert RV = ERROR_SUCCESS
        End If
    End Sub
    Thank you VERY much! I am playing around with it now and it looks like this will be a huge help.

    Thanks again.

  10. #10
    New Member
    Join Date
    Aug 2016
    Posts
    11

    Re: access 64 bit registry from 32 bit app

    This solution is great, except for one small part at the end:
    'Remove the subkey from the 64-bit view of the registry. KEY_WOW64_64KEY is ignored on a 32-bit OS.
    RV = RegDeleteKeyExW(HKEY_LOCAL_MACHINE, StrPtr(DUMMY_SUBKEY), KEY_WOW64_64KEY): Debug.Assert RV = ERROR_SUCCESS

    On XP 32-bit, RegDeleteKeyEx doesn't exist in advapi32.dll. It was introduced in XP-64 and newer OSes (newer versions of advapi32.dll, specifically from the 5.1.x versions that didn't have it, to the 6.1.x version that do). So I came up with this alternative:
    'Remove the subkey from the 64-bit view of the registry. KEY_WOW64_64KEY is ignored on a 32-bit OS.
    On Error Resume Next
    RV = RegDeleteKeyExW(HKEY_LOCAL_MACHINE, StrPtr(DUMMY_SUBKEY), KEY_WOW64_64KEY): Debug.Assert RV = ERROR_SUCCESS
    If Err Then
    'On older OS, RegDeleteKeyEx doesn't exist. Use regular RegDeleteKey()

    RV = RegDeleteKey(HKEY_LOCAL_MACHINE, DUMMY_SUBKEY): Debug.Assert RV = ERROR_SUCCESS
    End If

    Is there an easier / better way? (In case it wasn't clear, I intend to run this code on everything from XP 32-bit to Windows 10 64-bit, and also the servers from Server 2003 to Server 2012 R2.)
    Last edited by MickeyF; Aug 3rd, 2016 at 04:10 PM.

  11. #11
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: access 64 bit registry from 32 bit app

    Quote Originally Posted by MickeyF View Post
    On XP 32-bit, RegDeleteKeyEx doesn't exist in advapi32.dll. It was introduced in XP-64 and newer OSes (newer versions of advapi32.dll, specifically from the 5.1.x versions that didn't have it, to the 6.1.x version that do). So I came up with this alternative:
    Thanks for the bug report and the suggested fix!

    Quote Originally Posted by MickeyF View Post
    Is there an easier / better way?
    I think it's already the best solution. I couldn't find a better Registry API function than those 2 functions.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  12. #12
    New Member
    Join Date
    Aug 2016
    Posts
    11

    Re: access 64 bit registry from 32 bit app

    I was really thinking along the lines of using GetProcAddress to see if the function exists, which is a little cleaner, but this is quicker and does have one other major advantage - it already works!

  13. #13
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: access 64 bit registry from 32 bit app

    Quote Originally Posted by MickeyF View Post
    I was really thinking along the lines of using GetProcAddress to see if the function exists, which is a little cleaner, ...
    It is my understanding that VB6 already internally calls GetProcAddress the 1st time that a Declare'd API function is called (VB6 caches the return value and uses it the next time the function is called). Personally, I prefer the OERN approach because it is less code, GetProcAddress is called only once per API function and EXE size is slightly reduced because there is at least 1 less Unicode string instance of the API function's name in the EXE.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width