LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Weird error trying to read the registry - CVI 2020

Solved!
Go to solution

I'm sure this is obvious to someone but...

 

I need to read and then write a registry value from my CVI program.  I found examples of RegReadString  and came up with this test case:

-----------------------------------------------------------------------------------------

 

unsigned char buffer[260];
unsigned int size = 0;
static const char *subKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
static const char *valName = "Common Documents";
 
status = RegReadString(REGKEY_HKLM, subKey, valName, buffer, 259, &size);
MessagePopup("foo", buffer);
static const char *subKey2 = "SOFTWARE\\BAE Systems\\MyApp";
static const char *valName2 = "Data_directory";
status = RegReadString(REGKEY_HKLM, subKey2, valName2, buffer, 259, &size);
MessagePopup("foo2", buffer);
 
-------------------------------------
 
The first  read works fine and pops up the expected result.  The second one is supposed to be the same thing, except I creates a new subkey other tham 'Microsoft'.  I created my subkey and string value in regedit and I can see it.  I also made sure that the registry permissions are full access.  What happens is that the read fails with an error -5070 and buffer is simply not written.  What am I missing?
 
Your next cup of coffee is on me if you know what the problem is.  Thanks!  This is a major showstopper and I'm just not finding answers on the web.
 
Howard
0 Kudos
Message 1 of 6
(643 Views)
Solution
Accepted by HowardE

-5070 is error ToolErr_MissingKey. It means that your "SOFTWARE\\BAE Systems\\MyApp" doesn't exist in the registry.

 

Most likely reason: You are running a CVI 32-bit application on a Windows 64-bit system. Windows will redirect all registry requests from a 32-bit app to "HKLM\\SOFTWARE\\xxxxx" to "HKLM\\SOFTWARE\\WOW6432Node\\xxxxxx" instead.

 

Your "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders" exists in both places (not necessarily with the same contents though), so you thought it was reading "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders" but it was really reading "SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"

Rolf Kalbermatter
My Blog
Message 2 of 6
(599 Views)

Awesome - thanks!  It is a 32-bit app on a 64-bit machine.  I had finished implementing a solution with .INI files but I may go back and tweak it.

 

The offer for the coffee is good. I can share my email here and we can discuss a way I can send a credit of some sort.

 

This is why I love these forums - someone here always knows the answer to every question.

 

Howard

0 Kudos
Message 3 of 6
(574 Views)

@HowardE wrote:

Awesome - thanks!  It is a 32-bit app on a 64-bit machine.  I had finished implementing a solution with .INI files but I may go back and tweak it.

 

The offer for the coffee is good. I can share my email here and we can discuss a way I can send a credit of some sort.

 

This is why I love these forums - someone here always knows the answer to every question.


You are welcome. 😁

 

If you are really inclined to part with a little bit of money of some sorts, please consider doing a donation to some good cause of your choice. 🤗

Rolf Kalbermatter
My Blog
0 Kudos
Message 4 of 6
(563 Views)

A donation to the NH state science fair will be in your name.  Thanks!

Message 5 of 6
(550 Views)

Just to add a bit more of potentially useless information:

 

The Windows RegOpenKeyEx() function allows to specify which registry bitness to access if you do not want the automatic redirection.

 

LSTATUS RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult);

 

The fourth parameter lets you specify this by or-ing in one of the two values:

KEY_WOW64_32KEY (0x0200)

KEY_WOW64_64KEY (0x0100)

 

Your CVI Toolbox function RegReadString() doesn't give you direct access to that, but you do have the source code of that toolbox library in your CVI install folder: <CVI>\toolslib\toolbox\toolbox.c

 

It's not a trivial change and you would have to change several functions because it involves various APIs until you reach the final one:

 

static int CVIFUNC RegReadStringExW(unsigned int userRootKey, wchar_t* userSubKeyNameW, wchar_t* userValNameW, wchar_t** userStringW, unsigned int* prealStringSize, unsigned int bitness)
{
    int   retVal   = 0;
    DWORD sdkErr;
    DWORD keyType;
    HKEY  huserKey = NULL;

    Assert(userSubKeyNameW);
    Assert(prealStringSize);

    if ((sdkErr = RegOpenKeyExW ((HKEY)(ULONG_PTR)((LONG)userRootKey), userSubKeyNameW, 0, KEY_QUERY_VALUE | bitness, &huserKey))
        != ERROR_SUCCESS)
        {
        retVal = (sdkErr == ERROR_FILE_NOT_FOUND) ? ToolErr_MissingKey : ToolErr_CantOpenKey;
        goto Error;
        }
..........
Error:
    if (huserKey)
        RegCloseKey (huserKey);
    return retVal;
}

static int CVIFUNC RegReadStringW(unsigned int userRootKey, wchar_t* userSubKeyNameW, wchar_t* userValNameW, wchar_t** userStringW, unsigned int* prealStringSize)
{
    return RegReadStringExW(userRootKey, userSubKeyNameW, userValNameW, userStringW, prealStringSize, 0);
}

 

This way you could call RegReadStringExW() with the last parameter one of the two mentioned values, or 0 if you want to do the previous behavior.

 

If you need the ANSI variant you would have to also create the according wrapper to call RegReadStringExW() instead of RegReadStringW() )

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 6
(535 Views)