pikaaaaaaaaa
pikaaaaaaaaa

Reputation: 95

RegGetValue() returns wrong information

I am writing a VC++ program that is supposed to return the Java versions along with the Java Home from the registry. The purpose of the code is to display all the versions of JRE installed within a single system and also display the highest version. I have JRE 1.5, 1.6, 1.7 and 1.8 installed in my system. I have no problems in displaying the information about the versions. But when displaying the JavaHome from the registry, the path is coming right for Java versions 1.5,1.6 and 1.7 only. For version 1.8, it is displaying the path of JRE 7. I tried displaying path using INSTALLDIR from the MSI directory present within each JRE installed. Then also, there is problem with JRE 8. Initially I thought it was the error in the loop which was used in displaying all the JRE versions. So I uninstalled JRE 1.8 and checked if now, JRE 1.7 is showing the path of JRE 1.6. But nope. JRE 1.7 shows the correct path. Only when it comes to JRE 1.8, it is displaying the path of 1.7 instead of 1.8. Please help me out. I'm attaching the code below. And yeah, Checked the path present in Registry for JRE 1.8. It does have a seperate path of its own. Not the path of JRE 1.7. Also, when I tried to display the length of the Java 1.8 path, it is showing correct length 36 (as it should since that is the length of the path of JAVA 1.8) even though the output shows path of 1.7 for version 1.8. Is it something wrong with the string comparison? Help me out in this one please.

#include "StdAfx.h"
#include "targetver.h"
#include "windows.h"
#include"stdio.h"
#include "sstream"
#include"string.h"
#include"tchar.h"
#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383
#define BUFFER 8192
char value[BUFFER];
TCHAR** versions = new TCHAR*[];
DWORD BufferSize = BUFFER;
char str1[20];
char *javapath;
void QueryKey(HKEY hKey) 
{ 
TCHAR    achKey[MAX_KEY_LENGTH];   // buffer for subkey name
DWORD    cbName;                   // size of name string 
TCHAR    achClass[MAX_PATH] = TEXT("");  // buffer for class name 
DWORD    cchClassName = MAX_PATH;  // size of class string 
DWORD    cSubKeys=0;               // number of subkeys 
DWORD    cbMaxSubKey;              // longest subkey size 
DWORD    cchMaxClass;              // longest class string 
DWORD    cValues;              // number of values for key 
DWORD    cchMaxValue;          // longest value name 
DWORD    cbMaxValueData;       // longest value data 
DWORD    cbSecurityDescriptor; // size of security descriptor 
FILETIME ftLastWriteTime;      // last write time
DWORD i, retCode;
// Get the class name and the value count. 
retCode = RegQueryInfoKey(
hKey,                    // key handle 
achClass,                // buffer for class name 
&cchClassName,           // size of class string 
NULL,                    // reserved 
&cSubKeys,               // number of subkeys 
&cbMaxSubKey,            // longest subkey size 
&cchMaxClass,            // longest class string 
&cValues,                // number of values for this key 
&cchMaxValue,            // longest value name 
&cbMaxValueData,         // longest value data 
&cbSecurityDescriptor,   // security descriptor 
&ftLastWriteTime);       // last write time 

// Enumerate the subkeys, until RegEnumKeyEx fails.
TCHAR** versions = new TCHAR*[];
for(int i = 0; i < cSubKeys; i++)
versions[i] = new TCHAR[MAX_KEY_LENGTH];
if (cSubKeys)
{
for (i=0; i<cSubKeys; i++) 
    { 
        cbName = MAX_KEY_LENGTH;
        retCode = RegEnumKeyEx(hKey, i,
                                achKey, 
                                &cbName, 
                                NULL, 
                                NULL, 
                                NULL, 
                                &ftLastWriteTime); 
            if (retCode == ERROR_SUCCESS) 
            {
                if(strlen(achKey)==8)
                {
                    printf( "\nJava Version:");
                    _tprintf(TEXT("%s"),achKey);    
                    printf( "\nJava Home:");
                    strcpy(str1,"SOFTWARE\\\\JavaSoft\\\\Java Runtime Environment\\\\");
                    strcat(str1,achKey);
                    strcat(str1,"\\\\");
                    RegGetValue(HKEY_LOCAL_MACHINE,str1, "JavaHome", RRF_RT_ANY, NULL, (PVOID)&value, &BufferSize);
                    printf("%s",value);
                    printf("\n");
                    strcpy(versions[i],achKey);

            }
            else
                continue;
        }
    }
}
            TCHAR* big=0;
        for(i=0;i<cSubKeys;i++)
        {

            if(strlen(versions[i])==8)
            {
                _tprintf(TEXT(" versions are %s:\n"),versions[i]);
                if(versions[i]>big)
                    big=versions[i];
            }
                else
                    continue;
        }
            _tprintf(" \nLatest version in the system is %s\n",big);
}
int _tmain(int argc, _TCHAR* argv[])
{
  HKEY hKey;
LONG dwRegOPenKey = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\JavaSoft\\Java Runtime Environment\\"), 0, KEY_READ, &hKey);
if(dwRegOPenKey == ERROR_SUCCESS)
{
    printf("RegOpenKeyEx succeeded, error code %d\n", GetLastError());
    QueryKey(hKey);

} 
else
{
    printf("RegOpenKeyEx failed, error code %d\n", dwRegOPenKey);
}
    RegCloseKey(hKey);
    return 0;
}

Upvotes: 0

Views: 556

Answers (1)

Raymond Chen
Raymond Chen

Reputation: 45172

You are not checking the return value of RegGetValue, which would be telling you ERROR_INSUFFICIENT_BUFFER. Some debugging would reveal that the BufferSize variable keeps getting smaller and smaller. That's because you are not resetting the BufferSize variable to sizeof(value) prior to each call to RegGetValue, so each call reuses the value left over from the previous call, which is the size of the value retrieved. The call succeeds for Java 1.5 because it is the first call. It succeeds for Java 1.6 and 1.7 because those values happen to be the same length as Java 1.5's value. And finally, it fails for Java 1.8 because that value is longer than the others.

TL;DR: Set BufferSize = sizeof(value); before calling RegGetValue.

Upvotes: 3

Related Questions