打印名称,注册表类型和数据 [英] Print name, type and data of registry

查看:94
本文介绍了打印名称,注册表类型和数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to print info about registry. My problem is in the first for loop.

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

I can't get it to print dataType and data correctly.

此外,将它们添加到同一个打印中将会导致程序崩溃或无法正确打印。

Also, adding them in the same print will crash the program or not print correctly.

#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;
}


推荐答案

$ c> RegEnumValue 不正确。它有以下问题:

Your call to RegEnumValue is incorrect. It has the following problems:


  1. 您需要在调用之前初始化 valNameLen

  2. 您需要在调用该函数之前初始化 dataSize

  3. 检查 RegEnumValue 的返回值,从而假设函数成功。

  1. You are expected to initialise valNameLen before calling the function.
  2. You are expected to initialise dataSize before calling the function.
  3. You fail to check the return value of RegEnumValue and thus assume that the function succeeds. And in fact it fails because you of the aforementioned errors.

让我们忽略现在的值,因为这个值要复杂得多。让我们尝试并枚举值的名称。该代码如下所示:

Let's ignore the value for now, since that's much more complex. Let's just try and enumerate the names of the values. That code would look like this:

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
        }
    }
}

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

Note also that I stopped using a dynamically allocated character array as your code did. Your code leaked that array. Obviously if you need to cope with arbitrarily large value names, then you would need to use dynamically allocated arrays.

对于提取数据,这是一个更大的任务,我不相信是在
的范围这个问题。

As for extracting the data, that's a bigger task that I don't believe is in the scope of this question. You need special code for each individual data type.

例如,要读取 REG_SZ ,您需要使用类似的代码this:

For instance, to read a REG_SZ you would use code like this:

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;

这篇关于打印名称,注册表类型和数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆