你好,並提前感謝。 我今天的問題是我回到「垃圾」字符串的註冊表鍵值名稱和值數據。這似乎是一個鍵/文件夾內的所有註冊表值的問題,除了最後一個值,但有時我能夠讀取第一個值的名稱(但仍然不是數據)註冊表失敗的字符串/值枚舉調用
我在試圖要做的是能夠顯示在一個單一的,可能是變量,註冊表項中的值名稱和值數據(我不在乎子項在這一點) 我試圖用windows unicode字符串,WCHAR *和LPWSTR類型。 我在問題字符串中看到的「垃圾」是重複的一系列非英文字符,它們混淆了隨後的wcout顯示。 在註冊表編輯器顯示中,我試圖讀取的值有REG_SZ類型的數據,我知道它是一個字符串。
可能是我最大的問題是我無法找到一個簡單的指南,簡單地說明如何完成我想要做的事情,查看註冊表項中的內容,並列出值名稱和值數據。任何幫助將不勝感激。我是新來的unicode字符串和Windows API。我的環境是windows xp sp3,visual C++ 2010 express。
#include <stdio.h>
#include <iostream> /* for std::wcin and wcout */
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include "conio.h"
#
include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
int return_val;
DWORD error;
HKEY hkey;
BYTE iterations = 0;
/* 1. first, open key (folder) */
return_val = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"HARDWARE\\DEVICEMAP\\VIDEO", 0, KEY_READ, &hkey);
/* check how the open went */
if(return_val != ERROR_SUCCESS)
{
std::wcout << L"error opening the key: " << return_val << std::endl;
}
else
{
std::wcout << L"it's cool" << std::endl;
/* 1.a. query the key (optional) */
LPTSTR className = new WCHAR[255];
DWORD classNameSize = MAX_PATH;
DWORD subKey = 0;
DWORD maxSubKey;
DWORD maxClass;
DWORD value;
DWORD maxValue;
DWORD maxValueData;
DWORD securityDescriptor;
FILETIME ftLastWriteTime;
DWORD sectionNameSize;
return_val = RegQueryInfoKey(hkey, className, &classNameSize, NULL,
&subKey, &maxSubKey, &maxClass, &value, &maxValue,
&maxValueData, &securityDescriptor, &ftLastWriteTime);
std::wcout << L"query return: " << return_val << std::endl;
std::wcout << L"class name: " << className << L", (size): " << classNameSize << std::endl;
std::wcout << L"subkey: " << subKey << L", max: " << maxSubKey << L", maxClass: " << maxClass << std::endl;
std::wcout << L"Value: " << value << L", maxval: " << maxValue << L", maxvaldata: " << maxValueData << std::endl;
std::wcout << L"Sec descrpt: " << securityDescriptor << std::endl << std::endl;
/* now enumerate the strings in the key */
int count = 0;
DWORD valuename_size = 16, type_return = 0, data_size = 102;
LPWSTR valuename = new WCHAR[valuename_size];//maxValue
LPWSTR data = new WCHAR[data_size];//maxValueData>>1
/* 2. the outer loop grabs the values one at a time (the data within the key/folder) */
do {
iterations++; /* just for debugging */
return_val = RegEnumValue(hkey, count, valuename, &valuename_size, 0, &type_return, (LPBYTE)data, &data_size);
/* return of RegEnumValue */
std::wcout << L"RegEnumValue return val: " << return_val << std::endl;
/* double check sizes */
std::wcout << L"size: valname_size: " << valuename_size << L", data_size: " << data_size << std::endl;
if(return_val == ERROR_SUCCESS || return_val == ERROR_MORE_DATA)
{
/* to try and avoid bad strings */
if(type_return == REG_DWORD || count == 0)
std::wcout << L"Value - " << valuename << L", Type: " << type_return << L" Data - " << (BYTE)(*data) << std::endl;
else
std::wcout << L"Value - " << valuename << L", Type: " << type_return << L" Data - " << data << std::endl;
}
//data = REG_SZ;
count++;
} while (return_val != ERROR_NO_MORE_ITEMS && count < value);
}
/* just to check my code */
std::wcout << L"iterations: " << iterations << std::endl;
/* to "pause" during debugging */
std::wcin >> input;
return 0;
}
這個版本部分基於評論者的幫助似乎工作如何我想要的,我發佈這個供他人蔘考。對我來說很明顯的是,當爲角色獲取角色數量時,不會包含空終止字符(當然),而且您傳遞給它的緩衝區的大小需要包含該字符,因此如果您返回16你輸入16,這就是爲什麼它會返回234,(不公平的是,輸入如下比輸出diferent約束,但是生活是不公平的),然後需要輸入17字符串大小
/* now enumerate the strings in the key */
int count = 0;
DWORD valuename_size, type_return = 0, data_size;
LPWSTR valuename;
BYTE *data;
/* 2. the outer loop grabs the values one at a time (the data within the key/folder) */
do {
valuename_size = maxValue;
data_size = maxValueData;
iterations++; /* just for debugging */
return_val = RegEnumValue(hkey, count, NULL, &valuename_size, 0, &type_return, NULL, &data_size); /* value name */
//return_val = RegEnumValue(hkey, count, NULL, NULL, 0, &type_return, NULL, &data_size); /* value data */
valuename = new WCHAR[valuename_size+1];
data = new BYTE[data_size]; /* data_size is in BYTES, of any type */
valuename[0] = L'\0'; /* if the string returned is still invalid, this will help make sure wcout doesnt mess up */
return_val = RegEnumValue(hkey, count, valuename, &valuename_size, 0, &type_return, (LPBYTE)data, &data_size); /* value name */
//return_val = RegEnumValue(hkey, count, NULL, NULL, 0, &type_return, (LPBYTE)data, &data_size); /* value data */
/* return of RegEnumValue */
std::wcout << L"RegEnumValue return val: " << return_val << std::endl;
/* double check sizes */
std::wcout << L"size: valname_size: " << valuename_size << L", data_size: " << data_size << L", Type: " << type_return << std::endl;
if(return_val == ERROR_MORE_DATA /*&& type_return == REG_DWORD*/)
{
/* try again? */
delete valuename;//free(valuename);
delete data;
/* double the "global" max number of WORDs for the string (including null termination) */
maxValue <<= 1;
valuename_size = maxValue;
maxValueData <<= 1;
data_size = maxValueData;
/* doublecheck */
std::wcout << L"new val size before enum: " << valuename_size << L", new data size before enum: " << data_size << std::endl;
return_val = RegEnumValue(hkey, count, NULL, &valuename_size, 0, &type_return, NULL, &data_size); /* value name */
/* the return version of valuename_size is the number of characters, not including the null terminating character */
valuename = new WCHAR[valuename_size+1];
data = new BYTE[data_size];
valuename[0] = L'\0'; /* if the string returned is still invalid, this will help make sure wcout doesnt mess up */
return_val = RegEnumValue(hkey, count, valuename, &valuename_size, 0, &type_return, (LPBYTE)data, &data_size); /* value name */
std::wcout << std::endl << L"return: " << return_val << L", Val size: " << valuename_size << L", data_size: " << data_size << std::endl << std::endl;
}
if(return_val == ERROR_SUCCESS)
{
valuename[valuename_size] = L'\0'; /* null terminate the string before printing */
/* I only care about string data */
if (type_return == REG_SZ)
{
data[data_size] = 0; /* null terminate the string before printing */
std::wcout << L"Value - " << valuename << L", Type: " << type_return << L" Data - " << (LPWSTR)data << std::endl;
}
}
count++;
} while (return_val != ERROR_NO_MORE_ITEMS && count < value);
}
/* just to check my code */
std::wcout << L"iterations: " << iterations << std::endl;
/* to "pause" during debugging */
std::wcin >> input;
return 0;
}
1&2.根據您的評論和一些研究,我已添加valuename [0] = L'\ 0';和數據[0] = L'\ 0';在do-while循環的頂部,並且valuename [valuename_size] = L'\ 0';和data [data_size] = L'\ 0';然後將它們用作字符串。 3.我保持我的測試限於REG_SZ和REG_DWORD類型,直到我糾正了當前的問題。 雖然我有一個新的問題,我似乎無法得到一個DWORD的數據(RegEnumValue返回ERROR_MORE_DATA(234),即使我的緩衝區的大小應該至少是正確的) – Venevus 2013-02-22 19:38:56
在調用之前終止數組RegEnumValue將不會實現任何操作,每次調用之前需要重新初始化valuename_size和data_size,否則將解釋ERROR_MORE_DATA。正如我在第2點所述,您需要將字節長度除以2,即數據[ data_size/2] = 0,當你聲明數組的時候,你也應該這樣做;如果data_size是102字節,那麼它只有51個WCHARs,更可讀的是,在BYTE中聲明緩衝區,並且只有在數據是字符串時才轉換爲WCHARs 。 – arx 2013-02-22 20:40:53
我沒有提及我在do-while循環「data_size = maxValueData; valuename_size = maxValue;」的末尾重新初始化data_size和valuename_size。我也發現我在某些按鍵中仍然存在字符串問題,所以當我有時間的時候,我會在此處發佈我的代碼的完整更新 – Venevus 2013-02-22 21:17:38