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)