juce_win32_Registry.cpp bug in the latest version

In the latest version of JUCE juce_win32_Registry.cpp has a bug that prevents keys from been found.

It was

static bool keyExists (const String& regKeyPath, const DWORD wow64Flags)
{
    return RegistryKeyWrapper (regKeyPath, false, wow64Flags).key != nullptr;
}

And now it has a + “\\” next to regKeyPath, removing it the keys are found, with it no luck.

Cheers

Anyone?

That piece of code was changed in


which claims to fix a bug.

@t0m maybe the fix was incomplete?

You’re definitely giving the name of a key (the folder things you see in regedit) and not the name of a value?

Yes, the correct whole path, not the value, of course. :-\ It was working for months and months, until they added that + “\\” to the code… :frowning:

Can you provide an example of a key where this isn’t working?

HKEY_CURRENT_USER\Software\Wusik\Wusik Engine\Data Path

in code I added \\ instead of \

As I said, it was working before. Now it doesn’t.

Could you provide an example of a key which would exist on everyone’s computers, such as a property of the operating system?

Sorry, but what’s the point?

So that we can reproduce the problem on one of our computers.

I find this a bit odd, to be honest. As the idea is to create a value and later check if the value is there (the key). Not to check if a key exists in the Windows setup, which I have no idea of a key that exists on every computer. The thing is, the new code is not working, simple as that. The + “slash” doesn’t work somehow on the latest version of Windows 10. And the older code, without the + “slash” was working with my 5000 users on multiple versions of Windows.

Just open REGEDIT and find some keys to test on your machine.

It’s not odd at all. I was just asking if you could provide a test case which would show it not working on one of our computers, as in the example you provided, HKEY_CURRENT_USER\Software\Wusik\Wusik Engine\Data Path, it’s completely ambiguous if that is actually a value or a key, or if there’s anything written in the registry before you do the lookup.

This code

    // A key
    String associationsPath ("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Notepad\\Capabilities\\FileAssociations");
    
    if (WindowsRegistry::keyExists (associationsPath))
        DBG ("associations key exists");

    if (WindowsRegistry::valueExists (associationsPath))
        DBG ("associations value exists");

    DBG (WindowsRegistry::getValue (associationsPath, "XXX"));
    
    // A value
    String dotTxtPath = associationsPath + "\\.txt";

    if (WindowsRegistry::keyExists (dotTxtPath))
        DBG ("dotTxtPath key exists");

    if (WindowsRegistry::valueExists (dotTxtPath))
        DBG ("dotTxtPath value exists");

    DBG (WindowsRegistry::getValue (dotTxtPath, "XXX"));

running on the latest version of Windows 10 produces

associations key exists
XXX
dotTxtPath value exists
txtfile

which is the expected output.

https://docs.microsoft.com/en-us/windows/win32/sysinfo/structure-of-the-registry

In the provided page, no where I can read that I need do read registry keys with

"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Notepad\\Capabilities\\FileAssociations\\"

Instead of just

"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Notepad\\Capabilities\\FileAssociations"

As you have changed the JUCE code from

    return RegistryKeyWrapper (regValuePath, false, wow64Flags).key != 0;

To

return RegistryKeyWrapper (regKeyPath + “\”, false, wow64Flags).key != nullptr;

Hence the whole confusion. All I can say is that no key can be found if I use the latest code. :frowning:

The example I posted above shows that you do not need a trailing backslash to check for the existence of keys, or of values, or to read values. If I add a trailing backslash to the associationsPath key then there’s no difference to the result. If I add a trailing backslash to the dotTxtPath value then it doesn’t find the value. Not finding the value from a path with a trailing backslash is the expected behaviour, as a trailing backslash indicates a key rather than a value.

Are you sure you’re not confusing keys and values? They are explained in the link to the Windows documentation.

You can provide a lot more information than that.

  • Have you tried running the code I provided and does it produce the same result on your machine?
  • If it does produce the same output can you give a concrete example of some code that doesn’t work that we can run on one of our machines?

the problem appears to be that since the patch in question, JUCE adds the trailing backslash, not WilliamkWusik’s code…

But where is it causing a problem? One of us is overlooking something. It’s either a valid use case that the current version of JUCE isn’t handling correctly, or an invalid use case that relied on a previous version of JUCE to work correctly. If it’s a valid use case then we need to be able to reproduce the problem in order to identify what’s going wrong.

The current behaviour appears to work as expected:

Both of these are paths to an already existing key (the trailing slash makes no difference)

"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Notepad\\Capabilities\\FileAssociations"
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Notepad\\Capabilities\\FileAssociations\\"

and in both cases

WindowsRegistry::keyExists = true
WindowsRegistry::valueExists = false

This is a path to an already existing value

"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Notepad\\Capabilities\\FileAssociations\\.txt"

WindowsRegistry::keyExists = false
WindowsRegistry::valueExists = true
WindowsRegistry::getValue = txtfile

This is a path to a key that doesn’t exist (the trailing slash marks it as a key in the same way as a trailing slash indicates a directory on macOS or Linux):

"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Notepad\\Capabilities\\FileAssociations\\.txt\\"

WindowsRegistry::keyExists = false
WindowsRegistry::valueExists = false

There’s also the case where a key can have a default value, indicated by a value name of “(default)” in the registry editor, but I cannot find an example that will be common to other people’s computers. Here the behaviour is:

"HKEY_LOCAL_MACHINE\\SOFTWARE\\Avid\\Audio\\DirectIO64"

WindowsRegistry::keyExists = true
WindowsRegistry::valueExists = false

"HKEY_LOCAL_MACHINE\\SOFTWARE\\Avid\\Audio\\DirectIO64\\"

WindowsRegistry::keyExists = true
WindowsRegistry::valueExists = true
WindowsRegistry::getValue = C:\Program Files\Avid\Pro Tools Developer\

where the implicit empty value name following the trailing slash in the path returns the default value.