Using the windows registry

This is a discussion on Using the windows registry within the Windows Programming forums, part of the Platform Specific Boards category; Hello all. I have a question about the windows registry. I've been reading the MSDN on the registry functions and ...

  1. #1
    Registered User
    Join Date
    Mar 2006
    Posts
    150

    Using the windows registry

    Hello all. I have a question about the windows registry. I've been reading the MSDN on the registry functions and I was trying to learn how to use RegQueryValueEx. Here is the code I have to read the default value of HKEY_LOCAL_MACHINE:

    Code:
    #include <windows.h>
    #include <iostream>
    
    using namespace std;
    
    int main ()
    {
     LPDWORD retType;
     LPBYTE retDat;
    
     RegQueryValueEx (HKEY_LOCAL_MACHINE,
                                   "",
                                   NULL,
                                   retType,
                                   retDat,
                                   (LPDWORD) 20);
     
     cout << retType;
     cout << retDat;
    
     return 0;
    }
    The code compiled fine, but when I run it I get a windows system error and the process terminates. Can anyone explain why I may be getting this type of problem from this code?

  2. #2
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,594
    RegQueryValueEx expects a pointer to a buffer to save the data in, not an uninitialized pointer.
    Remember that everything that starts with LP typically means that it wants a pointer to something, it doesn't mean that you SHOULD pass an actual pointer, but the address of a variable.
    The same goes for the last argument. You need to pass the address of a DWORD which will get the size of the data. IF you don't need it, you can pass NULL.

    Code:
    int main ()
    {
    	DWORD retType;
    	BYTE retDat;
    	DWORD dwSize = 1;
    
    	RegQueryValueEx(HKEY_LOCAL_MACHINE, "", NULL, &retType, &retDat, &dwSize);
    	cout << retType;
    	cout << retDat;
    
    	return 0;
    }
    Note also that the last argument must contain the size of your buffer, which in your case is one, since you aren't using an array.
    Since you're reading a string, you need to make sure the size is the length of the string + 1 for the \0 char.
    Last edited by Elysia; 01-24-2008 at 12:12 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,856
    >>BYTE retDat;


    This is only one byte long and will (usually) not be enough to hold the defualt value requested, causing a buffer overrun.

    I use a char array and cast to the required type (or send in the type explicitly if I know what to expect ie int value requested, I send a pointer to an int variable).

    Code:
    char retDat[256]={0};//init to empty
    
    RegQueryValueEx(HKEY_LOCAL_MACHINE, "", NULL, &retType,(unsigned char*) &retDat, &dwSize);
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  4. #4
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,594
    More accurately, it will cause the function to return ERROR_MORE_DATA since I told it my buffer was 1 byte long.
    However, it's also possible to query the size of the data using
    Code:
    RegQueryValueEx(HKEY_LOCAL_MACHINE, "", NULL, &retType, NULL, &dwSize);
    Then you can allocate a buffer and fetch the data:
    Code:
    char* pData;
    DWORD dwDataSize = 0;
    DWORD retType;
    RegQueryValueEx(HKEY_LOCAL_MACHINE, "", NULL, &retType, NULL, &dwSize);
    pData = malloc(dwSize);
    RegQueryValueEx(HKEY_LOCAL_MACHINE, "", NULL, &retType, pData, &dwSize);
    /* Do something */
    free(pData)
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,059
    Also, keep in mind that you must first open the registry before you can query the registry as indicated in the basic sample below.

    Code:
    //Reg.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    
    #define  myReg "Software\\Microsoft\\Windows NT\\CurrentVersion"
    
    int main(void)
    {
    	char* pData = NULL;
    	DWORD dwSize = 0;
    	DWORD retType;
    	HKEY myKey;
    
    	if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, myReg, 0, KEY_ALL_ACCESS, &myKey)	!= ERROR_SUCCESS)
    	{
    		printf ("Could not open key\n");
    		return -1;
    	}   
    	if(RegQueryValueEx(myKey, "BuildLab", NULL, &retType, NULL, &dwSize) != ERROR_SUCCESS)
    	{
    		printf("Could not query key for data size\n");
    		RegCloseKey(myKey);
    		return -1;
    	}
    	pData =  malloc(dwSize * sizeof(char));
    	if(!pData)
    	{
    		printf("Malloc failed\n");
    		RegCloseKey(myKey);
    		return -1;
    	}
    	if(RegQueryValueEx(myKey, "BuildLab", NULL, &retType, pData, &dwSize) != ERROR_SUCCESS)
    	{
    		printf("Could not query key for data\n");
    		RegCloseKey(myKey);
    		return -1;
    	}
    	/* Do something */
    	printf("%s\n", pData);
    	free(pData);
    	RegCloseKey(myKey);
    	return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Network Programming in C for Windows
    By m.mixon in forum C Programming
    Replies: 7
    Last Post: 06-19-2006, 08:27 PM
  2. Menu Item Caption - /a for right aligned Accelerator?
    By JasonD in forum Windows Programming
    Replies: 6
    Last Post: 06-25-2003, 11:14 AM
  3. Manipulating the Windows Clipboard
    By Johno in forum Windows Programming
    Replies: 2
    Last Post: 10-01-2002, 09:37 AM
  4. How come this only works in Windows nt/2000?
    By Unregistered in forum Windows Programming
    Replies: 1
    Last Post: 08-30-2002, 06:54 PM
  5. Windows Registry
    By Nor in forum Windows Programming
    Replies: 1
    Last Post: 02-15-2002, 02:19 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21