Results 1 to 16 of 16

Thread: List of Values from a Key in the registry

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Oct 2002
    Posts
    241

    List of Values from a Key in the registry

    How can I get a list of all the values from a Key in a registry? All the values would be strings if this helps.

    thx

  2. #2
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    All the names? Look at RegEnumKeysEx
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  3. #3
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    RegEnumValue
    The RegEnumValue function enumerates the values for the specified open registry key. The function copies one indexed value name and data block for the key each time it is called.

    LONG RegEnumValue(
    HKEY hKey, // handle to key to query
    DWORD dwIndex, // index of value to query
    LPTSTR lpValueName, // value buffer
    LPDWORD lpcValueName, // size of value buffer
    LPDWORD lpReserved, // reserved
    LPDWORD lpType, // type buffer
    LPBYTE lpData, // data buffer
    LPDWORD lpcbData // size of data buffer
    );
    Parameters
    hKey
    [in] Handle to a currently open key or one of the following predefined keys:
    HKEY_CLASSES_ROOT
    HKEY_CURRENT_CONFIG
    HKEY_CURRENT_USER
    HKEY_LOCAL_MACHINE
    HKEY_USERS
    Windows NT/2000/XP: HKEY_PERFORMANCE_DATA
    Windows 95/98/Me: HKEY_DYN_DATA

    The enumerated values are associated with the key identified by hKey.

    dwIndex
    [in] Specifies the index of the value to retrieve. This parameter should be zero for the first call to the RegEnumValue function and then be incremented for subsequent calls.
    Because values are not ordered, any new value will have an arbitrary index. This means that the function may return values in any order.

    lpValueName
    [out] Pointer to a buffer that receives the name of the value, including the terminating null character.
    lpcValueName
    [in/out] Pointer to a variable that specifies the size, in TCHARs, of the buffer pointed to by the lpValueName parameter. This size should include the terminating null character. When the function returns, the variable pointed to by lpcValueName contains the number of characters stored in the buffer. The count returned does not include the terminating null character.
    lpReserved
    Reserved; must be NULL.
    lpType
    [out] Pointer to a variable that receives a code indicating the type of data stored in the specified value. For a list of the possible type codes, see Registry Value Types. The lpType parameter can be NULL if the type code is not required.
    lpData
    [out] Pointer to a buffer that receives the data for the value entry. This parameter can be NULL if the data is not required.
    lpcbData
    [in] Pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the lpData parameter. When the function returns, the variable pointed to by the lpcbData parameter contains the number of bytes stored in the buffer. This parameter can be NULL, only if lpData is NULL.
    Return Values
    If the function succeeds, the return value is ERROR_SUCCESS.

    If the function fails, the return value is a nonzero error code defined in Winerror.h. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

    Remarks
    To enumerate values, an application should initially call the RegEnumValue function with the dwIndex parameter set to zero. The application should then increment dwIndex and call the RegEnumValue function until there are no more values (until the function returns ERROR_NO_MORE_ITEMS).

    The application can also set dwIndex to the index of the last value on the first call to the function and decrement the index until the value with index 0 is enumerated. To retrieve the index of the last value, use the RegQueryInfoKey function.

    While using RegEnumValue, an application should not call any registration functions that might change the key being queried.

    The key identified by the hKey parameter must have been opened with KEY_QUERY_VALUE access. To open the key, use the RegCreateKeyEx or RegOpenKeyEx function.

    To determine the maximum size of the name and data buffers, use the RegQueryInfoKey function.

    Windows 95/98/Me: No registry subkey or value name may exceed 255 characters.

    Windows 95/98/Me: RegEnumValueW is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows 95/98/Me Systems.

    Example Code
    For an example, see Using the Registry.

    Requirements
    Windows NT/2000/XP: Included in Windows NT 3.1 and later.
    Windows 95/98/Me: Included in Windows 95 and later.
    Header: Declared in Winreg.h; include Windows.h.
    Library: Use Advapi32.lib.
    Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000/XP. Also supported by Microsoft Layer for Unicode.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  4. #4

    Thread Starter
    Addicted Member
    Join Date
    Oct 2002
    Posts
    241
    do u see anything wrong with this function:

    Code:
    string EnumRegKey(HKEY Key, char *mySubkey)
    {
    	string tmpStr;
    
    	int i = 0;
    	
    	char tmpBuff[1000] = {0};
    	char tmpArray[1000] = {0};
    
    	HKEY myKey;
    
    	RegOpenKey(Key, mySubKey, &myKey);
    
    	DWORD dwDataSize=0;
    	DWORD dwDataSize2=1000;
    	LPDWORD dwType = REG_SZ;
    
    	while(tmpBuff[1] != NULL)
    	{
    
    	RegEnumKeyEx(myKey, i, tmpBuff, &dwDataSize, NULL, &dwType, tmpArray, &dwDataSize2);
    
    	tmpStr = tmpStr + tmpBuff;
    
    	i++;
    
    	}
    	
    	return tmpStr;
    }
    i get the following errors with it:

    c:\program files\microsoft visual studio\vc98\include\myreg.h(124) : error C2065: 'mySubKey' : undeclared identifier
    c:\program files\microsoft visual studio\vc98\include\myreg.h(128) : error C2440: 'initializing' : cannot convert from 'const int' to 'unsigned long *'
    Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
    c:\program files\microsoft visual studio\vc98\include\myreg.h(133) : error C2664: 'RegEnumKeyExA' : cannot convert parameter 6 from 'unsigned long ** ' to 'char *'

  5. #5
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    The first error is one of case. Once you write mySubkey and once mySubKey.

    The second is a typedef trick of MS. You have the wrong variable type: make dwType DWORD, not LPDWORD.

    The third seems like a wrong ordering of parameters to me. Or maybe just a follow-up of the second.

    The fourth is coding style: NULL should be a value reserved for pointer and not be used for individual chars.

    The fifth is logical: because you init the tmpBuff array to 0 it will never enter the while loop.

    The sixth is a question of short-sighted programming: you app is not UNICODE-ready.

    The seventh is efficiency. You shouldn't have the string as return value, rather you should ask for a string and act on that.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  6. #6

    Thread Starter
    Addicted Member
    Join Date
    Oct 2002
    Posts
    241
    would it be possible for me to see an example of this since i seem to be getting a typecasting error on many parameters.

  7. #7
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    busy right now, I'll do it later.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  8. #8

    Thread Starter
    Addicted Member
    Join Date
    Oct 2002
    Posts
    241
    well regardless of whatever logical, technical, syntax, or moral errors the following function may have I did get the following to compile and sort of work.

    Code:
    string EnumRegKey(HKEY Key, char *mySubkey)
    {
    	string tmpStr;
    
    	int i = 0;
    	
    	char tmpBuff[1000] = {0};
    	unsigned char *tmpArray = 0;
    
    	HKEY myKey;
    
    	cout<<mySubkey<<endl;
    
    	cout<<RegOpenKey(Key, mySubkey, &myKey)<<endl;
    
    	DWORD dwDataSize=1000;
    	DWORD dwDataSize2=1000;
    	DWORD dwType = REG_SZ;
    
    	while(RegEnumValue(myKey, i, tmpBuff, &dwDataSize, NULL, &dwType, tmpArray, &dwDataSize2) != ERROR_NO_MORE_ITEMS)
    	{
    		cout<<i<<"     "<<tmpBuff<<endl;
    
    	if((tmpStr.find(tmpBuff, strlen(tmpBuff)) >= tmpStr.length()) && (strlen(tmpBuff) > 2))
    	{
    	tmpStr = tmpStr + tmpBuff;
    	tmpStr = tmpStr + "\n";
    	}
    
    	i++;
    
    	}
    	
    	return tmpStr;
    }
    the output is:

    Code:
    DevicePath
    DevicePath
    ProductId
    MediaPat
    and i can tell that it loops the right amount of times (14), and there are 14 values in the key, but it only returns these three, and the first one it returns twice.

    i appreciate any further help u guys can give.

  9. #9
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    I can't find any errors in this code. Have you tried going through it step by step with a debugger?
    Here's the code, slightly adjusted for more efficiency. I might later explain how you make it UNICODE-ready. It's not hard, just some replacing to do. And you gain easier internationalization and faster running on NT-derivates.

    Code:
    string EnumRegKey(HKEY Key, char *mySubkey)
    {
    	string tmpStr;
    
    	int i = 0;
    	
    	char tmpBuff[1000] = {0};
    
    	HKEY myKey;
    
    	cout<<mySubkey<<endl;
    
    	cout<<RegOpenKey(Key, mySubkey, &myKey)<<endl;
    
    	DWORD dwDataSize=1000;
    
    	while(RegEnumValue(myKey, i, tmpBuff, &dwDataSize, NULL, NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
    	{
    		cout<<i<<"     "<<tmpBuff<<endl;
    
    		if((tmpStr.find(tmpBuff, strlen(tmpBuff)) == string::npos) && (strlen(tmpBuff) > 2))
    		{
    			tmpStr += tmpBuff;
    			tmpStr += '\n';
    		}
    
    		i++;
    
    	}
    	
    	return tmpStr;
    }
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  10. #10

    Thread Starter
    Addicted Member
    Join Date
    Oct 2002
    Posts
    241
    thx. i have the same problem with ur function also. have u tried it urself? it would be pretty simple to make a driver for.

  11. #11
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    No, I didn't try it. I didn't say it would solve the problem. Only debugging can.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  12. #12

    Thread Starter
    Addicted Member
    Join Date
    Oct 2002
    Posts
    241
    what does the ERROR_MORE_DATA error mean?

  13. #13
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    It means there is still more data. (At least that's how I interpret this message:
    More data is available.
    )
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  14. #14
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    It returns ERROR_INVALID_FUNCTION for me...
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  15. #15
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    But I'm sure you can solve your problem by resetting dwDataSize to 1000 after each iteration.
    This code works:
    Code:
    #include <windows.h>
    #include <iostream>
    #include <string>
    #include <cstdlib>
    
    using namespace std;
    
    string EnumRegKey(HKEY Key, char *mySubkey)
    {
    	string tmpStr;
    
    	int i = 0;
    	
    	char tmpBuff[1000] = {0};
    	BYTE tmpData[1000] = {0};
    
    	HKEY myKey;
    
    	cout<<mySubkey<<endl;
    
    	cout<<RegOpenKey(Key, mySubkey, &myKey)<<endl;
    
    	DWORD dwBuffSize=1000;
    	DWORD dwDataSize = 1000;
    	DWORD dwType = 0;
    	LONG ret;
    
    	while((ret=RegEnumValue(myKey, i, tmpBuff, &dwBuffSize, NULL, &dwType, tmpData, &dwDataSize) != ERROR_NO_MORE_ITEMS))
    	{
    		cout<<i<<"     "<<tmpBuff<<endl;
    
    		if((tmpStr.find(tmpBuff, strlen(tmpBuff)) == string::npos) && (strlen(tmpBuff) > 2))
    		{
    			tmpStr += tmpBuff;
    			tmpStr += '\n';
    		}
    
    		dwDataSize = dwBuffSize = 1000;
    
    		i++;
    
    	}
    	
    	return tmpStr;
    }
    
    int main() {
    	cout << EnumRegKey(HKEY_CURRENT_USER, "Testkey") << endl;
    	return 0;
    }
    Here's the output:
    Code:
    Testkey
    0
    0
    1     Str1
    2     Str2
    3     Str3
    4     Str4
    5     Str5
    Str1
    Str2
    Str3
    Str4
    Str5
    
    Press any key to continue
    The first 0 is the return from RegOpenKey (ERROR_SUCCESS)
    The second is i when querying the std value.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  16. #16

    Thread Starter
    Addicted Member
    Join Date
    Oct 2002
    Posts
    241
    cornedbee ur the man. it worked wonderfully. thx a lot.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width