Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Hi all,
The other day I had to develop a small C++ sample which shows how to read the list of values of a REG_MULTI_SZ from the registry, and add a new value just after one of the values of the list. Additionally, I used methods and constants from tchar.h extensively, so it didn't matter if I compiled the code as UNICODE or ANSI. Here is the code:
#include "windows.h"
#include "tchar.h"
#include "conio.h"
#include "stdio.h"
#define MY_KEY _T("PathToMyRegistryKey\\MyRegistryKey") // Registry key
#define MY_VALUES _T("NameOfTheREG_MULTI_SZListOfValues") // Registry values
#define NEW_VALUE _T("MyNewValue") // New value
#define FIND_VALUE _T("AnExistingValue") // We will insert the new value after this one
int _tmain(int argc, _TCHAR* argv[])
{
LONG lResult = 0;
HKEY hKey = NULL;
LPTSTR lpValues = NULL;
LPTSTR lpValue = NULL;
LPTSTR lpNewValues = NULL;
LPTSTR lpNewValue = NULL;
DWORD cbValues = 0;
DWORD cbNewValues = 0;
DWORD cbNewValue = 0;
BOOL bFound = FALSE;
__try
{
// OPEN THE REGISTRY KEY
//
_tprintf(_T("RegOpenKeyEx..."));
lResult = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
MY_KEY,
0,
KEY_ALL_ACCESS,
&hKey
);
if (ERROR_SUCCESS != lResult) { _tprintf(_T("ERROR 0x%x\n"), lResult); return 1; }
_tprintf(_T("SUCCESS\n"));
// READ THE REG_MULTI_SZ VALUES
//
// Get size of the buffer for the values
_tprintf(_T("RegQueryValueEx..."));
lResult = RegQueryValueEx(
hKey,
MY_VALUES,
NULL,
NULL,
NULL,
&cbValues
);
if (ERROR_SUCCESS != lResult) { _tprintf(_T("ERROR 0x%x\n"), lResult); return 1; }
_tprintf(_T("SUCCESS\n"));
// Allocate the buffer
_tprintf(_T("malloc..."));
lpValues = (LPTSTR)malloc(cbValues);
if (NULL == lpValues) { _tprintf(_T("ERROR 0x%x\n"), GetLastError()); return 1; }
_tprintf(_T("SUCCESS\n"));
// Get the values
_tprintf(_T("RegQueryValueEx..."));
lResult = RegQueryValueEx(
hKey,
MY_VALUES,
NULL,
NULL,
(LPBYTE)lpValues,
&cbValues
);
if (ERROR_SUCCESS != lResult) { _tprintf(_T("ERROR 0x%x\n"), lResult); return 1; }
_tprintf(_T("SUCCESS\n"));
// SHOW THE VALUES
//
_tprintf(_T("\n**************************\n"));
_tprintf(_T("OLD VALUES\n"));
_tprintf(_T("**************************\n\n"));
lpValue = lpValues;
for (; '\0' != *lpValue; lpValue += _tcslen(lpValue) + 1)
{
// Show one value
_tprintf(_T("%s\n"), lpValue);
}
_tprintf(_T("\n**************************\n\n"));
// INSERT A NEW VALUE AFTER A SPECIFIC VALUE IN THE LIST OF VALUES
//
// Allocate a new buffer for the old values plus the new one
_tprintf(_T("malloc..."));
cbNewValue = (_tcslen(NEW_VALUE) + 1) * sizeof(TCHAR);
cbNewValues = cbValues + cbNewValue;
lpNewValues = (LPTSTR)malloc(cbNewValues);
if (NULL == lpNewValues) { _tprintf(_T("ERROR 0x%x\n"), GetLastError()); return 1; }
_tprintf(_T("SUCCESS\n"));
// Find the value after which we will insert the new one
lpValue = lpValues;
lpNewValue = lpNewValues;
bFound = FALSE;
for (; '\0' != *lpValue; lpValue += _tcslen(lpValue) + 1)
{
// Copy the current value to the target buffer
memcpy(lpNewValue, lpValue, (_tcslen(lpValue) + 1) * sizeof(TCHAR));
if (0 == _tcscmp(lpValue, FIND_VALUE))
{
// The current value is the one we wanted to find
bFound = TRUE;
// Copy the new value to the target buffer
lpNewValue += _tcslen(lpValue) + 1;
memcpy(lpNewValue, NEW_VALUE, (_tcslen(NEW_VALUE) + 1) * sizeof(TCHAR));
lpNewValue += _tcslen(NEW_VALUE) + 1;
}
else
{
// This is not the value we want, continue to the next one
lpNewValue += _tcslen(lpValue) + 1;
}
}
if (!bFound)
{
// We didn't find the value we wanted. Insert the new value at the end
memcpy(lpNewValue, NEW_VALUE, (_tcslen(NEW_VALUE) + 1) * sizeof(TCHAR));
lpNewValue += _tcslen(NEW_VALUE) + 1;
}
*lpNewValue = *lpValue;
// SHOW THE NEW VALUES
//
_tprintf(_T("\n**************************\n"));
_tprintf(_T("NEW VALUES\n"));
_tprintf(_T("**************************\n\n"));
lpNewValue = lpNewValues;
for (; '\0' != *lpNewValue; lpNewValue += _tcslen(lpNewValue) + 1)
{
// Show one value
_tprintf(_T("%s\n"), lpNewValue);
}
_tprintf(_T("\n**************************\n\n"));
// WRITE THE NEW VALUES BACK TO THE KEY
//
_tprintf(_T("RegSetValueEx..."));
lResult = RegSetValueEx(
hKey,
MY_VALUES,
NULL,
REG_MULTI_SZ,
(LPBYTE)lpNewValues,
cbNewValues
);
if (ERROR_SUCCESS != lResult) { _tprintf(_T("ERROR 0x%x\n"), lResult); return 1; }
_tprintf(_T("SUCCESS\n"));
}
__finally
{
// Clean up
//
if (NULL != lpValues) { free(lpValues); }
if (NULL != lpNewValues) { free(lpNewValues); }
if (NULL != hKey) { RegCloseKey(hKey); }
//_tprintf(_T("\n<<PRESS ANY KEY>>\n"));
//_getch();
}
return 0;
}
Regards,
Alex (Alejandro Campos Magencio)