Operating systems and registry functions

While I was going through my bookmarks, I noticed Larry Osterman had updated his blog. (It’s quite an informative blog.) He writes about the ‘bad’ RegQueryValueEx function and that there’s a new function, RegGetValue to use instead.

Before I write about what this have in relation to DC++, I wanted to take the time and write what RegQueryValueEx (and RegGetValue) actually do. Basically, a registry key is opened (by another function call) and while this key is open, the RegQueryValueEx (and RegGetValue) function retrieve data and the type (of the key, I think) from this key (that was previously opened).

So, what does that have to do with DC++? Well, the adc, dchub and magnet: key is checked with this RegQueryValueEx. So, there’s a potential problem (not that important – but still). For those that’s not on Windows XP x64, Vista (client), “Longhorn” (server) or 2003 (with SP1) atleast. Why isn’t there a potential problem on those systems? That is because Microsoft created the RegGetValue function so we could all sleep better at night.

So, DC++ should use the correct function but only on certain operting systems. Otherwise, we should still use the old function.

This means, before we can jump in at replace RegQueryValueEx, we must make sure that DC++ can actually support those operating systems. We dive in Util.cpp, at Util::getOsVersion(). Down some lines, we see that we can check if the user is running Windows 2003 but not XP x64 or Vista+. So, to add Vista (and up) to the list of detectable operating systems, we add this below the check for NT5:

} else if(ver.dwMajorVersion == 6) {
if(ver.dwMinorVersion == 0) {
os = “WinVista”;
} else {
os = “Unknown WinNT6”;
}
}

The first line check if it’s NT6, if so, which NT6 version? (That is, NT6.0, 6.1 or what?) Since I know no other systems that run NT6 besides Windows Vista, I assume Microsoft call the core for Vista NT6.0. Else, well, we just don’t know.

I know that I’ve not added XP x64, but I didn’t feel like Googling my ass off at 2 am. You do it.

So, we’ve added the check for the operating systems. Now, we need to actually check for them.
Right before a RegQueryValueEx (I’ve used this in WinUtil::registerDchubHandler(), the others are porbably exactly the same except the second parameter in RegGetValue), we add this:

OSVERSIONINFOEX ver;
WinUtil::getVersionInfo(ver);
if( ((DWORD)ver.dwMajorVersion > 5) || (((DWORD)ver.dwMajorVersion == 5) &&((DWORD)ver.dwMinorVersion >= 2) && ((DWORD)ver.wServicePackMajor > 0)) ) {

Now, what this does is that it first create the variable ‘ver’. We then pass ‘ver’ to getVersionInfo to get information about the operating system that DC++ is running under. Next, we check if the operating system’s NT version is above 5, i.e Vista. Or(!) if the NT version is 5 (Windows 2000, XP, 2003) and is using NT5.2 and have atleast SP1. This align nicely with Windows 2003 SP1.

So, if one of these two things return true we should use RegGetValue. Else, still use RegQueryValueEx.

Next we add the RegGetValue function inside this if-block and put an else-block and we complete this validation.
(I have to warn you; I’m not saying this is exactly how it is supposed to be. I’m saying what I’ve gotten out of the docs.) (For your information, RegGetValue isn’t available if you are trying to compile DC++ with VS 2003. Use VS 2005 instead.)

OSVERSIONINFOEX ver;
WinUtil::getVersionInfo(ver);
if( ((DWORD)ver.dwMajorVersion > 5) || (((DWORD)ver.dwMajorVersion == 5) &&((DWORD)ver.dwMinorVersion >= 2) && ((DWORD)ver.wServicePackMajor > 0)) ) {
::RegGetValue(hk, _T(“dchub\\Shell\\Open\\Command”), 0, RRF_RT_ANY, &type, (LPBYTE)Buf, &bufLen); // The new function
} else {
::RegQueryValueEx(hk, NULL, 0, &type, (LPBYTE)Buf, &bufLen); // Original function
}

So. We’ve used the RegGetValue to retrieve data from the key. But only on certain operating systems. Aswell, we added Windows Vista to the list of known operating systems.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: