How to correct store LPTSTR in map - c++

I need to store values from registry in map. I have such code:
map<int, LPTSTR> mymap;
for (i = 0, retCode = ERROR_SUCCESS; i<cValues; i++)
{
cchValue = MAX_VALUE_NAME;
achValue[0] = '\0';
retCode = RegEnumValue(hKey, i,
achValue,
&cchValue,
NULL,
NULL,
NULL,
NULL);
if (retCode == ERROR_SUCCESS)
{
DWORD lpData = cbMaxValueData;
buffer[0] = '\0';
LONG dwRes = RegQueryValueEx(hKey, achValue, 0, NULL, buffer, &lpData);
LPTSTR val = (TCHAR*)buffer;
MessageBox(NULL, val, L"VALUE", MB_OK);
auto r = mymap.insert(pair<int, LPTSTR>(i, val));
for (map<int, LPTSTR>::const_iterator it = mymap.begin(); it != mymap.end(); it++)
{
wchar_t szMessage2[1300];
if (SUCCEEDED(StringCchPrintf(szMessage2, ARRAYSIZE(szMessage2), L"+ %d : %s\n", it->first, it->second)))
{
MessageBox(NULL, szMessage2, L"MAP", MB_OK);
}
}
}
}
How to correct save val to map? Right now all keys have the same value (latest).

The problem is that you have a single buffer that you are reusing during enumeration, and you are storing just a pointer to that buffer into your map. So every entry will be pointing at the same physical memory, which contains the last piece of data written to it.
You need to store copies of the enumerated string data into your map. Use std::string/std::wstring for that, eg:
using tstring = basic_string<TCHAR>;
map<int, tstring> mymap;
for (i = 0, retCode = ERROR_SUCCESS; i < cValues; i++)
{
cchValue = MAX_VALUE_NAME;
retCode = RegEnumValue(hKey, i,
achValue,
&cchValue,
NULL,
NULL,
NULL,
NULL);
if (retCode == ERROR_SUCCESS)
{
DWORD dwData = cbMaxValueData;
DWORD dwType = 0;
LONG dwRes = RegQueryValueEx(hKey, achValue, 0, &dwType, buffer, &dwData);
if (dwRes == ERROR_SUCCESS)
{
switch (dwType)
{
case REG_SZ:
case REG_MULTI_SZ:
case REG_EXPAND_SZ:
{
tstring val((LPTSTR)buffer, dwData / sizeof(TCHAR));
//MessageBox(NULL, val.c_str(), TEXT("VALUE"), MB_OK);
mymap.insert(make_pair(i, val));
break;
}
}
}
}
}
for (auto &value: mymap)
{
TCHAR szMessage2[1300];
if (SUCCEEDED(StringCchPrintf(szMessage2, ARRAYSIZE(szMessage2), TEXT("+ %d : %s\n"), value.first, value.second.c_str())))
{
MessageBox(NULL, szMessage2, TEXT("MAP"), MB_OK);
}
}
However, since you are clearly compiling with UNICODE enabled, you shouldn't be using TCHAR at all:
map<int, wstring> mymap;
for (i = 0, retCode = ERROR_SUCCESS; i < cValues; i++)
{
cchValue = MAX_VALUE_NAME;
retCode = RegEnumValueW(hKey, i,
achValue,
&cchValue,
NULL,
NULL,
NULL,
NULL);
if (retCode == ERROR_SUCCESS)
{
DWORD dwData = cbMaxValueData;
DWORD dwType = 0;
LONG dwRes = RegQueryValueExW(hKey, achValue, 0, &dwType, buffer, &dwData);
if (dwRes == ERROR_SUCCESS)
{
switch (dwType)
{
case REG_SZ:
case REG_MULTI_SZ:
case REG_EXPAND_SZ:
{
wstring val((LPWSTR)buffer, dwData / sizeof(WCHAR));
//MessageBoxW(NULL, val.c_str(), L"VALUE", MB_OK);
mymap.insert(make_pair(i, val));
break;
}
}
}
}
}
for (auto &value: mymap)
{
WCHAR szMessage2[1300];
if (SUCCEEDED(StringCchPrintfW(szMessage2, ARRAYSIZE(szMessage2), L"+ %d : %s\n", value.first, value.second.c_str())))
{
MessageBoxW(NULL, szMessage2, L"MAP", MB_OK);
}
}

Related

Error: argument of type "const wchar_t *" is incompatible with parameter of type "WCHAR *"

I have a below code for WinHTTPRequest:
DWORD WinHTTPRequest(LPCTSTR pServerName, LPCTSTR pRequest, WCHAR* sCommand, LPVOID pPostData, int nPostDataLength, LPCWSTR pwszHeaders, char **dataOut, int *nRead, WCHAR **dataHeaderOut, BOOL bTestProxy, BOOL bSecure, WCHAR* wsRedirect, DWORD *dwReturnStatus)
{
HINTERNET hCurrentOpen = NULL;
if (bTestProxy)
{
WCHAR sProxy[255] = L"";
GetProxy(sProxy);
if (lstrcmp(sProxy, L"") == 0)
hCurrentOpen = hOpen;
else if (lstrcmp(sProxy, g_wsCurrentProxy) != 0)
{
if (hOpenProxy)
WinHttpCloseHandle(hOpenProxy);
hOpenProxy = WinHttpOpen(L"Test", WINHTTP_ACCESS_TYPE_NAMED_PROXY, sProxy, NULL, 0/*INTERNET_FLAG_ASYNC*/);
lstrcpy(g_wsCurrentProxy, sProxy);
hCurrentOpen = hOpenProxy;
}
else
hCurrentOpen = hOpenProxy;
}
else
hCurrentOpen = hOpen;
HINTERNET hConnect = NULL;
if (bSecure)
hConnect = WinHttpConnect(hCurrentOpen, pServerName, INTERNET_DEFAULT_HTTPS_PORT, 0);
else
hConnect = WinHttpConnect(hCurrentOpen, pServerName, INTERNET_DEFAULT_HTTP_PORT, 0);
if (!hConnect)
{
DWORD dwError = GetLastError();
return dwError;
}
DWORD dwFlags;
if (bSecure)
dwFlags = WINHTTP_FLAG_SECURE | WINHTTP_FLAG_REFRESH;
else
dwFlags = WINHTTP_FLAG_REFRESH;
HINTERNET hRequest = WinHttpOpenRequest(hConnect, sCommand, pRequest, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, dwFlags);
if (!hRequest)
{
DWORD dwError = GetLastError();
WinHttpCloseHandle(hConnect);
return dwError;
}
WinHttpAddRequestHeaders(hRequest, pwszHeaders, -1, WINHTTP_ADDREQ_FLAG_ADD);
int nLengthPostData;
if (nPostDataLength == NULL)
{
if (pPostData)
nLengthPostData = strlen((char*)pPostData);
else
nLengthPostData = 0;
}
else
nLengthPostData = nPostDataLength;
BOOL bSuccess;
if (wsRedirect != NULL)
{
DWORD dwOption;
DWORD dwOptionSize;
dwOption = WINHTTP_OPTION_REDIRECT_POLICY_NEVER;
dwOptionSize = sizeof(DWORD);
bSuccess = WinHttpSetOption(hRequest, WINHTTP_OPTION_REDIRECT_POLICY, (LPVOID)&dwOption, dwOptionSize);
DWORD dwOptionValue = WINHTTP_DISABLE_REDIRECTS;
bSuccess = WinHttpSetOption(hRequest, WINHTTP_OPTION_DISABLE_FEATURE, &dwOptionValue, sizeof(dwOptionValue));
}
BOOL b = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, pPostData, pPostData == NULL ? 0 : nLengthPostData, nLengthPostData, 0);
if (!b)
{
DWORD dwError = GetLastError();
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hRequest);
return dwError;
}
WinHttpReceiveResponse(hRequest, NULL);
DWORD dwStatus = 0;
DWORD dwStatusSize = sizeof(DWORD);
if (WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwStatus, &dwStatusSize, NULL))
{
if (HTTP_STATUS_REDIRECT == dwStatus || HTTP_STATUS_MOVED == dwStatus)
{
DWORD dwSize;
WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_LOCATION, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwSize, WINHTTP_NO_HEADER_INDEX);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return 500;
LPWSTR pwsRedirectURL = new WCHAR[dwSize];
bSuccess = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_LOCATION, WINHTTP_HEADER_NAME_BY_INDEX, pwsRedirectURL, &dwSize, WINHTTP_NO_HEADER_INDEX);
if (!bSuccess)
return 500;
if (wsRedirect != NULL)
lstrcpy(wsRedirect, pwsRedirectURL);
if (dwReturnStatus != NULL)
*dwReturnStatus = dwStatus;
delete[] pwsRedirectURL;
}
else if (dwStatus != HTTP_STATUS_OK && dwStatus != HTTP_STATUS_BAD_REQUEST && dwStatus != HTTP_STATUS_CREATED)
{
DWORD dwError = GetLastError();
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hRequest);
if (dwReturnStatus != NULL)
*dwReturnStatus = dwStatus;
return dwError;
}
}
if (dataHeaderOut != NULL)
{
DWORD dwSize = 0;
WCHAR *pOutBuffer = NULL;
if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwSize, WINHTTP_NO_HEADER_INDEX))
{
DWORD dwErr = GetLastError();
if (dwErr != ERROR_INSUFFICIENT_BUFFER)
{
DWORD dwError = GetLastError();
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hRequest);
return dwError;
}
}
pOutBuffer = new WCHAR[dwSize];
if (WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, pOutBuffer, &dwSize, WINHTTP_NO_HEADER_INDEX))
{
pOutBuffer[dwSize] = '\0';
*dataHeaderOut = (WCHAR*)pOutBuffer;
}
//delete[] pOutBuffer;
}
char *sReadBuffer = NULL;
DWORD nTotalRead = 0;
DWORD nToRead = 0;
DWORD nBytesRead = 0;
do {
if (!WinHttpQueryDataAvailable(hRequest, &nToRead))
break;
if (nToRead == 0)
break;
sReadBuffer = (char*)((sReadBuffer == NULL) ? malloc(nToRead) : realloc(sReadBuffer, nTotalRead + nToRead + 1));
if (WinHttpReadData(hRequest, sReadBuffer + nTotalRead, nToRead, &nBytesRead))
{
nTotalRead += nBytesRead;
}
} while (nToRead > 0);
if (sReadBuffer != NULL && nTotalRead > 0)
{
{
char *sBuffer = new char[nTotalRead + 1];
memcpy(sBuffer, sReadBuffer, nTotalRead + 1);
sBuffer[nTotalRead] = '\0';
*dataOut = sBuffer;
}
free(sReadBuffer);
}
*nRead = nTotalRead;
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hRequest);
return ERROR_SUCCESS;
}
I am calling the above function as:
dwReturn = WinHTTPRequest(wsHostName, wsURLPathPost, L"POST", sPostData, NULL, wsAdditionalHeaders, &sHTTPData, &nDataRead, &wsDataHeader, 0, 0, wsRedirect, &dwStatus);
But at L"POST", its giving me below error:
Error (active) E0167 argument of type "const wchar_t *" is incompatible with parameter of type "WCHAR *"
Error C2664 'DWORD WinHTTPRequest(LPCTSTR,LPCTSTR,WCHAR *,LPVOID,int,LPCWSTR,char **,int *,WCHAR **,BOOL,BOOL,WCHAR *,DWORD *)': cannot convert argument 3 from 'const unsigned short [4]' to 'WCHAR *'
I tried changing the L"POST" to _T("POST") but didnt worked. How can I resolve this. Thanks
You take sCommand as a pointer to non-const, suggesting that you plan to modify the buffer it points to. But you pass a string literal there, which cannot be modified. Either make the parameter const, or pass a modifiable buffer.

Manipulating Windows Registry

I want every time my program runs make this process:
1- Check if there is a windows registry key called "foo"
2- If it not exists create with the value 10
3- If it exists decrement its value
4- If its value == 0 close de program
I know that i will use this functions, but i don't know how to use them:
RegCreateKeyA, RegSetValueExA
The function to create the key worked, but I can not to set the values and do not know how to do what I need.
HKEY key;
RegCreateKeyA(HKEY_CURRENT_USER,"foo",&key);
RegOpenKeyExA(HKEY_CURRENT_USER,"foo", 0, KEY_ALL_ACCESS, &key);
RegSetValueExA(key,"bar",0,REG_DWORD,(LPBYTE)10,sizeof(10));
Try something like this:
HKEY key;
DWORD disposition;
LONG lRet = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("foo"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &key, &disposition);
if (lRet != 0)
{
// error handling...
}
else
{
DWORD value;
if (disposition == REG_CREATED_NEW_KEY)
{
value = 10;
lRet = RegSetValueEx(key, TEXT("bar"), 0, REG_DWORD, (LPBYTE)&value, sizeof(value));
if (lRet != 0)
{
// error handling...
}
}
else
{
DWORD size = sizeof(value);
lRet = RegQueryValueEx(key, TEXT("bar"), NULL, NULL, (LPBYTE)&value, &size);
if (lRet != 0)
{
// error handling...
}
else
{
if (value != 0)
{
--value;
lRet = RegSetValueEx(key, TEXT("bar"), 0, REG_DWORD, (LPBYTE)&value, sizeof(value));
if (lRet != 0)
{
// error handling...
}
}
if (value == 0)
{
// signal app to terminate...
}
}
}
RegCloseKey(key);
}

Getting md5 hash code for dll file in c++

Hi guys i am trying to get dll md5 hash but it is returning same value all the time, what i did wrong?
this dll is already loaded when i am trying to getHash
i am getting hash with getHash() method and calculating it with CalcHash
thnks in advanced.
#define BUFSIZE 1024
#define MD5LEN 16
int CalcHash(HANDLE hFile, char *md5sum)
{
BOOL bResult = FALSE;
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
BYTE rgbFile[BUFSIZE];
DWORD cbRead = 0;
BYTE rgbHash[MD5LEN];
DWORD cbHash = 0;
CHAR rgbDigits[] = "0123456789abcdef";
char byt[3];
int rc, err;
rc = CryptAcquireContext(&hProv, NULL, MS_STRONG_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
if(!rc)
{
err = GetLastError();
if(err==0x80090016)
{
//first time using crypto API, need to create a new keyset
rc=CryptAcquireContext(&hProv, NULL, MS_STRONG_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET);
if(!rc)
{
err=GetLastError();
return 0;
}
}
}
CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
while(bResult = ReadFile(hFile, rgbFile, BUFSIZE, &cbRead, NULL))
{
if (0 == cbRead)
{
break;
}
CryptHashData(hHash, rgbFile, cbRead, 0);
}
cbHash = MD5LEN;
CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0);
md5sum[0] = 0;
for (DWORD i = 0; i < cbHash; i++)
{
sprintf(byt, "%c%c", rgbDigits[rgbHash[i] >> 4], rgbDigits[rgbHash[i] & 0xf]);
strcat(md5sum, byt);
}
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return 1;
}
char *getHash()
{
CalcHash(L"dsetup.dll", md5sum);
Logger(md5sum);
return md5sum;
}

Heap allocation problems

I am running into memory errors when I try to run my C++ program in Visual Studio 2012. I am thinking that this code is the cause (since when I remove it, it runs fine):
void GetMachineHash(CString &strHashHex) {
CMD5 cMD5;
BYTE *szHash = (BYTE*)malloc(48);
LPBYTE szMachineNameHash, szNetworkAddressHash, szVolumeIdHash;
TCHAR szMachineId[100];
DWORD nMachineIdLen = 100;
TCHAR szNetworkAddress[13];
IP_ADAPTER_INFO *pAdapterInfo, *pAdapter = NULL;
DWORD dwRetVal = 0;
ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
TCHAR szVolumeId[20];
TCHAR szVolumeName[MAX_PATH];
TCHAR szFileSystemName[MAX_PATH];
DWORD dwSerialNumber = 0;
DWORD dwMaxComponentLen = 0;
DWORD dwFileSystemFlags = 0;
ZeroMemory(szHash, 48);
ZeroMemory(szMachineId, 100);
ZeroMemory(szVolumeId, 20);
ZeroMemory(szVolumeName, MAX_PATH);
ZeroMemory(szFileSystemName, MAX_PATH);
ZeroMemory(szNetworkAddress, 13);
GetComputerName(szMachineId, &nMachineIdLen);
cMD5.Calculate(szMachineId);
szMachineNameHash = cMD5.Hash();
pAdapterInfo = (IP_ADAPTER_INFO *) malloc(sizeof(IP_ADAPTER_INFO));
if (pAdapterInfo == NULL) {
TRACE(_T("Error allocating memory needed to call GetAdaptersinfo()"));
szNetworkAddressHash = NULL;
}
// Make an initial call to GetAdaptersInfo to get the necessary size into the ulOutBufLen variable
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
if (pAdapterInfo == NULL) {
TRACE(_T("Error allocating memory needed to call GetAdaptersinfo()"));
szNetworkAddressHash = NULL;
}
}
if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
pAdapter = pAdapterInfo;
while (pAdapter) {
if (pAdapter->Type != MIB_IF_TYPE_LOOPBACK) {
_stprintf_s(szNetworkAddress, 13, _T("%.2X%.2X%.2X%.2X%.2X%.2X"),
pAdapter->Address[0],
pAdapter->Address[1],
pAdapter->Address[2],
pAdapter->Address[3],
pAdapter->Address[4],
pAdapter->Address[5]
);
break;
}
pAdapter = pAdapter->Next;
}
} else {
TRACE(_T("GetAdaptersInfo() call failed"));
szNetworkAddressHash = NULL;
}
cMD5.Calculate(szNetworkAddress);
szNetworkAddressHash = cMD5.Hash();
if (GetVolumeInformation(
NULL,
szVolumeName,
sizeof(szVolumeName),
&dwSerialNumber,
&dwMaxComponentLen,
&dwFileSystemFlags,
szFileSystemName,
sizeof(szFileSystemName))) {
_stprintf_s(szVolumeId, 20, _T("%lu"), dwSerialNumber);
}
cMD5.Calculate(szVolumeId);
szVolumeIdHash = cMD5.Hash();
// Calculate hash from hashes
memcpy(szHash, szMachineNameHash, 16);
memcpy(szHash+16, szNetworkAddressHash, 16);
memcpy(szHash+32, szVolumeIdHash, 16);
cMD5.Calculate(szHash, 48);
strHashHex.Preallocate(33);
strHashHex = cMD5.HexHash();
free(szHash);
free(pAdapterInfo);
return;
}
And then if I leave the function and just remove this code:
strHashHex.Preallocate(33);
strHashHex = cMD5.HexHash();
Then it will work fine as well. So I am wondering if that is the code that's causing the memory problems, and if it is, how can I fix it?
Here's the CMD5 class (which utilizes the Windows API to generate a MD5 sum):
class CMD5
{
public:
CMD5() {
if(CryptAcquireContext(&m_hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET) == 0){
if(GetLastError() == NTE_EXISTS){
CryptAcquireContext(&m_hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0);
}
}
}
~CMD5() {
if(m_hCryptProv)
CryptReleaseContext(m_hCryptProv, 0);
m_hCryptProv = NULL;
free(m_szHash);
}
bool Calculate(LPCTSTR szText) {
DWORD dwLen = sizeof(TCHAR) * _tcslen(szText);
DWORD dwHashLen;
DWORD dwHashLenSize = sizeof(DWORD);
if (CryptCreateHash(m_hCryptProv, CALG_MD5, 0, 0, &m_hHash)) {
if (CryptHashData(m_hHash, (const BYTE*)szText, dwLen, 0)) {
if (CryptGetHashParam(m_hHash, HP_HASHSIZE, (BYTE *)&dwHashLen, &dwHashLenSize, 0)) {
if(m_szHash = (BYTE*)malloc(dwHashLen)) {
if (CryptGetHashParam(m_hHash, HP_HASHVAL, (BYTE*)m_szHash, &dwHashLen, 0)) {
CryptDestroyHash(m_hHash);
}
}
}
}
}
return false;
}
bool Calculate(const LPBYTE szText, DWORD dwLen) {
DWORD dwHashLen;
DWORD dwHashLenSize = sizeof(DWORD);
if (CryptCreateHash(m_hCryptProv, CALG_MD5, 0, 0, &m_hHash)) {
if (CryptHashData(m_hHash, (const BYTE*)szText, dwLen, 0)) {
if (CryptGetHashParam(m_hHash, HP_HASHSIZE, (BYTE *)&dwHashLen, &dwHashLenSize, 0)) {
if(m_szHash = (BYTE*)malloc(dwHashLen)) {
if (CryptGetHashParam(m_hHash, HP_HASHVAL, (BYTE*)m_szHash, &dwHashLen, 0)) {
CryptDestroyHash(m_hHash);
}
}
}
}
}
return false;
}
LPBYTE Hash() const {
LPBYTE szHash = new BYTE[16];
ZeroMemory(szHash, 16);
memcpy(szHash, m_szHash, 16);
return szHash;
}
LPTSTR HexHash() const {
LPTSTR szBuf = new TCHAR[33];
ZeroMemory(szBuf, 33);
for (int i=0; i<16; i++)
_stprintf_s(szBuf+i*2, 33, _T("%02X"), m_szHash[i]);
szBuf[32]=0;
return szBuf;
}
private:
BYTE *m_szHash;
DWORD m_hHash;
HCRYPTPROV m_hCryptProv;
};
Also, the error I get from VS2012 is Critical error detected c0000374 and the call stack ends with a call to HeapAlloc() from _heap_alloc. Not sure if it matters but this code is being called in a DLL.
It looks like I was able to solve the memory allocation problems by changing the CMD5::HexHash() function to
void HexHash(CString &strHash) {
for (int i=0; i<16; i++)
strHash += StringFormat(_T("%02X"), m_szHash[i]);
return;
}
and call it via cMD5.HexHash(strHashHex);

C++ RegEnumValue() - fail to iterate to each value

I want to get all the registry values under specific key path, but RegEnumValue() always returns back the error code 259 as ERROR_NO_MORE_ITEMS and sectionValue has nonsense value. I check the registry manually and there are values under the specified key.
For example.
key is MyTestApp
key value is ManualTestCase = 10
key value is AutomationTestCase = 50
HKEY hKey; //registry key handle
LONG lResult; //result of registry operations
DWORD dwType, dwSize=0;
//try to open the key that we are currently pointing at with rootPath
lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, rootPath, NULL, KEY_ALL_ACCESS, &hKey);
if (lResult == ERROR_SUCCESS)
{
LPTSTR className = NULL;
DWORD classNameSize = MAX_PATH;
DWORD subKey = 0;
DWORD maxSubKey;
DWORD maxClass;
DWORD value;
DWORD maxValue;
DWORD maxValueData;
DWORD securityDescriptor;
FILETIME ftLastWriteTime;
DWORD sectionNameSize;
int j;
//to get total keys for the specified path
lResult = RegQueryInfoKey(hKey, className, &classNameSize, NULL,
&subKey, &maxSubKey, &maxClass, &value, &maxValue,
&maxValueData, &securityDescriptor, &ftLastWriteTime);
if(lResult == ERROR_SUCCESS)
{
for(int i = 0; i < subKey; i++)
{
LPTSTR sectionName = new TCHAR[1096];
sectionNameSize = 1096;
ftLastWriteTime.dwHighDateTime = 0;
ftLastWriteTime.dwLowDateTime = 0;
//enumerate all the registry key names for specified path
lResult = RegEnumKeyEx(hKey, i, sectionName,
&sectionNameSize, NULL, NULL,
NULL, &ftLastWriteTime);
CString testStr = sectionName;
if(lResult == ERROR_SUCCESS)
{
j = 0;
do
{
LPTSTR sectionValue;
DWORD sectionValueSize = 4096;
DWORD dwType;
//enumerate all the values for specified key
lResult = RegEnumValue(hKey, j, sectionName,
&sectionNameSize, NULL, &dwType,
(LPBYTE)sectionValue, &sectionValueSize);
//
if(lResult == ERROR_SUCCESS)
{
//do something to the data
bool whatever = true;
}
else if(lResult == ERROR_MORE_DATA)
{
//
bool yeahSure = true;
}
j++;
}while(lResult != ERROR_NO_MORE_ITEMS);
}
delete[] sectionName;
}
}
}
RegCloseKey(hKey);
My guess is your problem is with how you use lResult = RegEnumKeyEx(hKey, i, sectionName,...
You are trying to enumerate values of a subkey without actually opening that subkey.