Hi,

As I'm new to C++, but not to programming, I tried to start simple by reading off value from the registry. I'm talking about standard values such as the processor's name.
I made a little function which checked how many processors the user has, that works fine. But I would then like to give the user the names of the processors. But I'm having trouble with the RegQueryValueEx function from Windows.h.
I use this function to retreive the name:

char * processor(double index)
	{
	HKEY key;
	LONG succeeded;

	succeeded = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\"+(char)index, NULL, KEY_READ, &key);
	if (succeeded == ERROR_SUCCESS)
		{
		char *value = ;
		DWORD value_size = sizeof(value);
		
		while (RegQueryValueEx(key, "ProcessorNameString", NULL, NULL, (BYTE *)value, &value_size) == ERROR_MORE_DATA)
			{
			value = new char[1];
			value_size = sizeof(value);
			}
		RegCloseKey(key);

		return value;
		}
	else
		{
		return "FAILED";
		}
	}

There is no error, but an even more annoying problem: my computer has 2 processors, so the code has to return this:

processor(0) == "Intel(R) Core(TM)2 Duo CPU E7300 @ 2.66GHz"
processor(1) == "Intel(R) Core(TM)2 Duo CPU E7300 @ 2.66GHz"

But instead, is returns this:

processor(0) == ""
processor(1) == "FAILED"

Which isn't the same :P.
I was hoping that one of you knows what I do wrong. If so, please answer simple, as I do not know a lot about C++.

Ragoune

line 9: >> char *value = ;
Will that even compile ????

>>DWORD value_size = sizeof(value);

value is a pointer, and the sizeof(any pointer here) is 4 on most 32-bit platforms.

you don't have to put that in a loop. Call it the first time with the size of the buffer = 0 and it will return the required size

If the buffer specified by lpData parameter is not large enough to hold the data, the function returns ERROR_MORE_DATA and stores the required buffer size in the variable pointed to by lpcbData.

if( (RegQueryValueEx(key, "ProcessorNameString", NULL, NULL, (BYTE *)value, &value_size) == ERROR_MORE_DATA )
{
     value = new char[value_size];     
    (RegQueryValueEx(key, "ProcessorNameString", NULL, NULL, (BYTE *)value, &value_size);
}

line 9: >> char *value = ;
Will that even compile ????

No :P, it was a mistake I made while copying, it should be char *value = "";. But anyways, thanks for the help. I changed the code to this one:

char * processor(double index)
	{
	HKEY key;
	LONG succeeded;

	succeeded = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\"+(char)index, NULL, KEY_READ, &key);
	if (succeeded == ERROR_SUCCESS)
		{
		char *value = "";
		DWORD value_size = 0;
		
		if (RegQueryValueEx(key, "ProcessorNameString", NULL, NULL, (BYTE *)value, &value_size) == ERROR_MORE_DATA)
			{
			value = new char[value_size];

			RegQueryValueEx(key, "ProcessorNameString", NULL, NULL, (BYTE *)value, &value_size);
			}
		RegCloseKey(key);

		return value;
		}
	else
		{
		return "FAILED";
		}
	}

But it still returns the same. I hope you know what is (still) wrong.

>> "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\"+(char)index
You can not concantinate a double to a float like that.

What you want to do is enumerate all the keys with the CentralProcessor key.

Here is what you want:

int main ()
{
	HKEY key;
	LONG succeeded;
    std::string keyname = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\";
    std::string processor_name;
    vector<string> processor_list;

	succeeded = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname.c_str(), NULL, KEY_READ, &key);
	if (succeeded == ERROR_SUCCESS)
	{
		char *value = "";
		DWORD value_size = 0;
        bool done = false;
        for(int i = 0; done == false; i++)
        {
            char buf[255];
            succeeded =  RegEnumKey(key, i, buf, sizeof(buf));
            if( succeeded != ERROR_SUCCESS)
            {
                done = true;
                break;
            }
            cout << "key: " << buf << "\n";
            HKEY key1;
            string name = keyname + buf;
            succeeded = RegOpenKey(HKEY_LOCAL_MACHINE, name.c_str(), &key1);
            if( succeeded == ERROR_SUCCESS)
            {
                value_size = sizeof(buf);
                memset(buf,0,sizeof(buf));
                succeeded = RegQueryValueEx(key1, "ProcessorNameString", 0,0, (unsigned char*) buf, &value_size);
                if( succeeded == ERROR_SUCCESS)
                {
                    cout << buf << "\n";
                }
                RegCloseKey(key1);
            }
        }
    }

	RegCloseKey(key);
        
	return 0;
}

Thanks for your reply, but that code is way too complicated for me, isn't there a way to just simple change a double in a char * so I can add it to the path of the registry value? I've tried to made a function myself, this is how far I've come:

char * double_to_characters(double number)
	{
	char *index_char = "";

	if (sprintf_s(index_char, sizeof(index_char), "%d", number) > 0)
		{
		return index_char;
		}
	else
		{
		return "0";
		}
	}

And this is how it is used in the processor() function:

char *index_string = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\";
strcat(index_string, double_to_characters(index));

succeeded = RegOpenKeyEx(HKEY_LOCAL_MACHINE, index_string, NULL, KEY_READ, &key);

But I get a runtime error when I get to this point, so I may come due to the function, or the code used in processor(). Do you know what I've done wrong?

Ragoune

you can't do it like that either (which you have already found out). use sprintf() to format the string, like this: Note in the below code variable buf can NOT be a pointer.

char buf[255];
sprintf(buf,"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", (int)index);

My computer is 64-bit quad-core and the value of ProcessorNameString is the same for each key. So if that's all you want then all you have to do is get the name from the first one, and you might just as well hard-code it "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"

Edited 7 Years Ago by Ancient Dragon: n/a

char buf[255];
sprintf(buf,"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", (int)index);

Thanks a lot, that did it!

This article has been dead for over six months. Start a new discussion instead.