打印注册表的名称,类型和数据

时间:2014-03-02 20:47:56

标签: c++ winapi registry

我正在尝试打印有关注册表的信息。我的问题出现在第一个for循环中。

我无法正确打印dataType和数据。

此外,在同一打印件中添加它们会使程序崩溃或无法正确打印。

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>

void EnumerateValues(HKEY hKey, DWORD numValues)
{
 DWORD dwIndex = 0;
    LPSTR valueName = new CHAR[64];
 DWORD valNameLen;
 DWORD dataType;
 DWORD data;
 DWORD dataSize;

    for (int i = 0; i < numValues; i++)
 {
  RegEnumValue(hKey,
     dwIndex,
     valueName,
     &valNameLen,
     NULL,
     &dataType,
     (BYTE*)&data,
     &dataSize);

  dwIndex++;

_tprintf(TEXT("(%d) %s %d\n"), i+1, valueName, dataType); 
      // printf("Code: 0x%08X\n", data);

 }
}


void EnumerateSubKeys(HKEY RootKey, char* subKey, unsigned int tabs = 0) 
{
 HKEY hKey;
    DWORD cSubKeys;        //Used to store the number of Subkeys
    DWORD maxSubkeyLen;    //Longest Subkey name length
    DWORD cValues;        //Used to store the number of Subkeys
    DWORD maxValueLen;    //Longest Subkey name length
    DWORD retCode;        //Return values of calls

 RegOpenKeyEx(RootKey, subKey, 0, KEY_ALL_ACCESS, &hKey);

    RegQueryInfoKey(hKey,            // key handle
                    NULL,            // buffer for class name
                    NULL,            // size of class string
                    NULL,            // reserved
                    &cSubKeys,        // number of subkeys
                    &maxSubkeyLen,    // longest subkey length
                    NULL,            // longest class string 
                    &cValues,        // number of values for this key 
                    &maxValueLen,    // longest value name 
                    NULL,            // longest value data 
                    NULL,            // security descriptor 
                    NULL);            // last write time

    if(cSubKeys>0)
 {
        char currentSubkey[MAX_PATH];

        for(int i=0;i < cSubKeys;i++){
   DWORD currentSubLen=MAX_PATH;

            retCode=RegEnumKeyEx(hKey,    // Handle to an open/predefined key
            i,                // Index of the subkey to retrieve.
            currentSubkey,            // buffer to receives the name of the subkey
            &currentSubLen,            // size of that buffer
            NULL,                // Reserved
            NULL,                // buffer for class string 
            NULL,                // size of that buffer
            NULL);                // last write time

            if(retCode==ERROR_SUCCESS)
   {
                for (int i = 0; i < tabs; i++)
                    printf("\t");
                printf("(%d) %s\n", i+1, currentSubkey);

                char* subKeyPath = new char[currentSubLen + strlen(subKey)];
                sprintf(subKeyPath, "%s\\%s", subKey, currentSubkey);
    EnumerateSubKeys(RootKey, subKeyPath, (tabs + 1));
   }
  }
 }
    else
 {
  EnumerateValues(hKey, cValues);
 }

 RegCloseKey(hKey); 
}


int main()
{
    EnumerateSubKeys(HKEY_CURRENT_USER,"SOFTWARE\\Dropbox");
   getchar();
    return 0;
}

1 个答案:

答案 0 :(得分:2)

您对RegEnumValue的来电不正确。它有以下问题:

  1. 在调用函数之前,您需要初始化valNameLen
  2. 在调用函数之前,您需要初始化dataSize
  3. 您无法检查RegEnumValue的返回值,因此假定该函数成功。事实上它失败了,因为你有上述错误。
  4. 让我们忽略现在的价值,因为那要复杂得多。让我们尝试枚举值的名称。该代码看起来像这样:

    void EnumerateValues(HKEY hKey, DWORD numValues)
    {
        for (DWORD dwIndex = 0; dwIndex < numValues; dwIndex++)
        {
            char valueName[64];
            DWORD valNameLen = sizeof(valueName);
            DWORD dataType;
            DWORD dataSize = 0;
            DWORD retval = RegEnumValue(hKey, dwIndex, valueName, &valNameLen,
                NULL, &dataType, NULL, &dataSize);
            if (retval == ERROR_SUCCESS)
            {
                printf("(%d) %s %d\n", dwIndex+1, valueName, dataType);
            }
            else
            {
                // handle error
            }
        }
    }
    

    另请注意,我已停止使用动态分配的字符数组作为代码。你的代码泄漏了那个数组。显然,如果你需要处理任意大的值名称,那么你需要使用动态分配的数组。

    至于提取数据,这是一个我认为不在范围内的更大任务 这个问题。您需要为每种单独的数据类型提供特殊代码。

    例如,要阅读REG_SZ,您将使用以下代码:

    char *data = new char [dataSize+1];
    data[dataSize] = '\0';
    valNameLen = sizeof(valueName);
    DWORD retval = RegEnumValue(hKey, dwIndex, valueName, &valNameLen,
        NULL, NULL, (LPBYTE)data, &dataSize);
    if (retval == ERROR_SUCCESS)
    {
        printf("(%d) %s %d %s\n", dwIndex+1, valueName, dataType, data);
    }
    else
    {
        // handle error
    }
    delete[] data;