Posted by: Christian Wimmer in: Common
I got a bug from someone who told me that he had problems with the TRegistry method DeleteKey on his 64bit Windows. It just didn’t delete a 64bit key* from the registry although he used the KEY_WOW64_64KEY flag in desired access parameter of TRegistry.Create.
At first I thought that it was a problem with the OpenKey function of TRegistry. However, this was already confirmed and fixed as a bug in QC# 23429.
Then I wanted to check the real error value of DeleteKey. Of course, it just returns true or false, so I added a call to GetLastError. And it returned 87 (Invalid Parameter). It must be said that using GetLastError in a framework like VCL is always a problem because you don’t really know how many winapi functions are called subsequent to the actual winapi function. So you may get an error value from another random function. This is one reason I’m using exceptions in JWSCL, btw.
A quick step through debugging session (you have to enable debug dcu in project options and rebuild the project) confirmed that the invalid parameter error (87) came from RegDeleteKey. But why 87? The next step was obvious because I had a windows function and thus I would have to read its MSDN documentation.
Deletes a subkey and its values. Note that key names are not case sensitive.
64-bit Windows: On WOW64, 32-bit applications view a registry tree that is separate from the registry tree that 64-bit applications view. To enable an application to delete an entry in the alternate registry view, use the RegDeleteKeyEx function.
So the RegDeleteKeyEx function must be used. But don’t stop reading here and implement it. We can’t just use this function because MSDN states that this function is only available in XP 64bit or Vista (32 and 64bit). So this gets more complicated and I suggest this way :
|XP 32bit||XP 64bit||Vista and newer (32+64)|
|RegDeleteKey||√||only 32bit keys||only 32bit keys|
√ – will run fine as it is intended.
As a conclusion, you cannot use the TRegistry method DeleteKey with 64bit registry keys. Either you have to use your own RegDeleteKeyEx call or just use a derived class of TRegistry. Of course this is only necessary it you want to access 64bit keys…this article is FYI.
In the end, the question arises to me why RegDeleteKey does not support 64bit registry keys. I couldn’t find any evidences, so I can only use my brain to think of one:
Well, the RegDeleteKey function can be really dangerous if a 32bit application, that is not aware of 64bit, erases 64bit keys. This is especially true for “HKEY_LOCAL_MACHINE\SOFTWARE” because you may have installed two versions of an application with same name. First you installed a 32bit only application (name it X) you bought several years ago for your 32bit Windows. One day the vendor sends you a 64bit only update that you install (*so happy*). You decide to abandon the 32bit version and call its custom made uninstaller which deletes all of its known keys. Of course, it will also delete the 64bit version. This may be fictional but possible without the breakup of 32bit and 64bit keys in heavily used parts of the registry. So RegDeleteKey will not delete the 64bit keys because that would break 64bit applications. It seems to me that Microsoft experienced it already, before they decided to add 32-64bit registry separation. Maybe Raymond Chen would say something like this: Believe us, we tried the other way around: it’s worse.
If you are interested in more information, I suggest you to read Accessing an Alternate Registry View.
* The key was a subkey from “HKEY_LOCAL_MACHINE\SOFTWARE”. In 64bit Windows, a 32bit application (not aware of 64bit) will only see the contents of “HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node”.
I submitted a bug report to QC: #87323