Create new data in registry key? - c++

I just create new registry key called MyTestApp, and want to add new data in it, but don't know how. So I have following code.
bool CreateSectionDataRegistry(CString sectionData, CString sectionValue)
{
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 + "\\" + "MyTestApp", NULL, KEY_ALL_ACCESS, &hKey);
if (lResult == ERROR_SUCCESS || lResult == ERROR_MORE_DATA)
{
//we have successfully opened the registry key. Now try to access the data
lResult = RegQueryValueEx(HKEY_LOCAL_MACHINE, sectionData, 0, &dwType, NULL, &dwSize);
if(lResult == ERROR_SUCCESS || lResult == ERROR_MORE_DATA)
{
//data already exists, so just return
RegCloseKey(hKey);
return true;
}
else//section data does not exist, so create new data
{
DWORD dwDisposition;
lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE, sectionData, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisposition);
RegCloseKey(hKey);
return true;
}
}
return false;
}
But when I trace down to the RegCreateKeyEx() call, it returns success but data is not created under the MyTestApp registry key or anywhere in the registry. Am I using the correct function to create new data under MyTestApp. Also from the argument above, I have CString sectionValue, so how do I check if I need to create data for REG_SZ or REG_DWORD?
Thanks!

It seems I just need to call RegSetValueEx() to create registry value under MyTestApp. Probably just me but when I look at the RegSetValueEx() definition in Microsoft website, it says set the value, but it does not say if value does not exist, it will create the value.
LPTSTR lpszData = new TCHAR[sectionValue.GetLength() + 1];
_tcscpy(lpszData, sectionValue);
lResult = RegSetValueEx(hKey, sectionData, 0, REG_SZ, (LPBYTE)lpszData, sectionValue.GetLength());
So now it creates the registry value, however I cannot still tell if sectionValue is REG_SZ or REG_DWORD.

Related

Returning invalid data from RegQueryValueEx() DWORD

I'm trying to read a DWORD value from the registry. In the registry, it's stored as 0x00000068 (104). When I read the value from the registry, I'm getting a very large number (3435973836). Any help is appreciated!
DWORD getRecentId(PDWORD id) {
HKEY hKey;
LONG lRes = RegOpenKeyEx(HKEY_CURRENT_USER, _T("SOFTWARE\\My App\\Feed Reader"), 0, KEY_QUERY_VALUE, &hKey);
if (!lRes == ERROR_SUCCESS)
{
RegCloseKey(hKey);
return ERROR_FILE_NOT_FOUND;
}
DWORD dwSize = sizeof(DWORD);
lRes = RegQueryValueEx(hKey, _T("Latest"), NULL, NULL, (LPBYTE)&id, &dwSize);
if (!lRes == ERROR_SUCCESS)
{
RegCloseKey(hKey);
return ERROR_NOT_ENOUGH_MEMORY;
}
RegCloseKey(hKey);
return lRes;
}
3435973836 is a magic number. Convert it to hex to get 0xcccccccc. When you see that back in the Visual Studio debugger then you know that you are using an uninitialized variable.
It is, using &id was wrong. That alters the pointer, not the pointed-to value. Use id instead.

Add Application to Startup (Registry)

I'm trying to add my software to registry, I have found some pieces of the codes I can use but not full working code C/C++ is new to me and can't create it on my own. But here is the basic idea: Check if reg key set if not create it.
I was able to get my program location using this code:
TCHAR szPath[MAX_PATH];
GetModuleFileName(NULL,szPath,MAX_PATH);
And was able to create the key with: (Not sure if it's the right way)
HKEY newValue;
RegOpenKey(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&newValue);
RegSetValueEx(newValue,"myprogram",0,REG_SZ,(LPBYTE)szPath,sizeof(szPath));
RegCloseKey(newValue);
return 0;
What is missing, A small check if the key isn't already there...
Thank you!
Here's some code that likely does what you want. Call RegisterProgram for your EXE to self-register itself for automatically being started when the user logs in. This function calls GetModuleFileName and then invokes another helper function called RegisterMyProgramForStartup that does the writing to the registry.
Call IsMyProgramRegisteredForStartup(L"My_Program") to detect if the registration actually exists and appears valid.
One quick note. The performance impact of checking to see if the key exists before actually writing it out again is negligible. You could just call RegisterProgram blindly and it will overwrite the key if it already exists. Detecting if the registration exists is useful for initializing your UI checkbox that enables or disables auto-start. (You are giving your users a choice, right? Because I hate apps that automatically install themselves to run automatically without giving me a choice.)
BOOL IsMyProgramRegisteredForStartup(PCWSTR pszAppName)
{
HKEY hKey = NULL;
LONG lResult = 0;
BOOL fSuccess = TRUE;
DWORD dwRegType = REG_SZ;
wchar_t szPathToExe[MAX_PATH] = {};
DWORD dwSize = sizeof(szPathToExe);
lResult = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_READ, &hKey);
fSuccess = (lResult == 0);
if (fSuccess)
{
lResult = RegGetValueW(hKey, NULL, pszAppName, RRF_RT_REG_SZ, &dwRegType, szPathToExe, &dwSize);
fSuccess = (lResult == 0);
}
if (fSuccess)
{
fSuccess = (wcslen(szPathToExe) > 0) ? TRUE : FALSE;
}
if (hKey != NULL)
{
RegCloseKey(hKey);
hKey = NULL;
}
return fSuccess;
}
BOOL RegisterMyProgramForStartup(PCWSTR pszAppName, PCWSTR pathToExe, PCWSTR args)
{
HKEY hKey = NULL;
LONG lResult = 0;
BOOL fSuccess = TRUE;
DWORD dwSize;
const size_t count = MAX_PATH*2;
wchar_t szValue[count] = {};
wcscpy_s(szValue, count, L"\"");
wcscat_s(szValue, count, pathToExe);
wcscat_s(szValue, count, L"\" ");
if (args != NULL)
{
// caller should make sure "args" is quoted if any single argument has a space
// e.g. (L"-name \"Mark Voidale\"");
wcscat_s(szValue, count, args);
}
lResult = RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, NULL, 0, (KEY_WRITE | KEY_READ), NULL, &hKey, NULL);
fSuccess = (lResult == 0);
if (fSuccess)
{
dwSize = (wcslen(szValue)+1)*2;
lResult = RegSetValueExW(hKey, pszAppName, 0, REG_SZ, (BYTE*)szValue, dwSize);
fSuccess = (lResult == 0);
}
if (hKey != NULL)
{
RegCloseKey(hKey);
hKey = NULL;
}
return fSuccess;
}
void RegisterProgram()
{
wchar_t szPathToExe[MAX_PATH];
GetModuleFileNameW(NULL, szPathToExe, MAX_PATH);
RegisterMyProgramForStartup(L"My_Program", szPathToExe, L"-foobar");
}
int _tmain(int argc, _TCHAR* argv[])
{
RegisterProgram();
IsMyProgramRegisteredForStartup(L"My_Program");
return 0;
}
To check whether or not the value exists, call RegQueryValueEx.
LONG retval = RegQueryValueEx(hKey, "myprogram", NULL, NULL, NULL, NULL);
Note that what you called newValue is actually a key rather than a value. To avoid confusion you should name it such. I used the name hKey.
Then to check whether or not the value exists, compare retval against ERROR_SUCCESS as described in the documentation.
The other problem with your code is that there is absolutely no error checking. I'll leave that to you to address.
You forget to write an argument about security access

Save Me Simple Add to Startup via Registry [duplicate]

I'm trying to add my software to registry, I have found some pieces of the codes I can use but not full working code C/C++ is new to me and can't create it on my own. But here is the basic idea: Check if reg key set if not create it.
I was able to get my program location using this code:
TCHAR szPath[MAX_PATH];
GetModuleFileName(NULL,szPath,MAX_PATH);
And was able to create the key with: (Not sure if it's the right way)
HKEY newValue;
RegOpenKey(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&newValue);
RegSetValueEx(newValue,"myprogram",0,REG_SZ,(LPBYTE)szPath,sizeof(szPath));
RegCloseKey(newValue);
return 0;
What is missing, A small check if the key isn't already there...
Thank you!
Here's some code that likely does what you want. Call RegisterProgram for your EXE to self-register itself for automatically being started when the user logs in. This function calls GetModuleFileName and then invokes another helper function called RegisterMyProgramForStartup that does the writing to the registry.
Call IsMyProgramRegisteredForStartup(L"My_Program") to detect if the registration actually exists and appears valid.
One quick note. The performance impact of checking to see if the key exists before actually writing it out again is negligible. You could just call RegisterProgram blindly and it will overwrite the key if it already exists. Detecting if the registration exists is useful for initializing your UI checkbox that enables or disables auto-start. (You are giving your users a choice, right? Because I hate apps that automatically install themselves to run automatically without giving me a choice.)
BOOL IsMyProgramRegisteredForStartup(PCWSTR pszAppName)
{
HKEY hKey = NULL;
LONG lResult = 0;
BOOL fSuccess = TRUE;
DWORD dwRegType = REG_SZ;
wchar_t szPathToExe[MAX_PATH] = {};
DWORD dwSize = sizeof(szPathToExe);
lResult = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_READ, &hKey);
fSuccess = (lResult == 0);
if (fSuccess)
{
lResult = RegGetValueW(hKey, NULL, pszAppName, RRF_RT_REG_SZ, &dwRegType, szPathToExe, &dwSize);
fSuccess = (lResult == 0);
}
if (fSuccess)
{
fSuccess = (wcslen(szPathToExe) > 0) ? TRUE : FALSE;
}
if (hKey != NULL)
{
RegCloseKey(hKey);
hKey = NULL;
}
return fSuccess;
}
BOOL RegisterMyProgramForStartup(PCWSTR pszAppName, PCWSTR pathToExe, PCWSTR args)
{
HKEY hKey = NULL;
LONG lResult = 0;
BOOL fSuccess = TRUE;
DWORD dwSize;
const size_t count = MAX_PATH*2;
wchar_t szValue[count] = {};
wcscpy_s(szValue, count, L"\"");
wcscat_s(szValue, count, pathToExe);
wcscat_s(szValue, count, L"\" ");
if (args != NULL)
{
// caller should make sure "args" is quoted if any single argument has a space
// e.g. (L"-name \"Mark Voidale\"");
wcscat_s(szValue, count, args);
}
lResult = RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, NULL, 0, (KEY_WRITE | KEY_READ), NULL, &hKey, NULL);
fSuccess = (lResult == 0);
if (fSuccess)
{
dwSize = (wcslen(szValue)+1)*2;
lResult = RegSetValueExW(hKey, pszAppName, 0, REG_SZ, (BYTE*)szValue, dwSize);
fSuccess = (lResult == 0);
}
if (hKey != NULL)
{
RegCloseKey(hKey);
hKey = NULL;
}
return fSuccess;
}
void RegisterProgram()
{
wchar_t szPathToExe[MAX_PATH];
GetModuleFileNameW(NULL, szPathToExe, MAX_PATH);
RegisterMyProgramForStartup(L"My_Program", szPathToExe, L"-foobar");
}
int _tmain(int argc, _TCHAR* argv[])
{
RegisterProgram();
IsMyProgramRegisteredForStartup(L"My_Program");
return 0;
}
To check whether or not the value exists, call RegQueryValueEx.
LONG retval = RegQueryValueEx(hKey, "myprogram", NULL, NULL, NULL, NULL);
Note that what you called newValue is actually a key rather than a value. To avoid confusion you should name it such. I used the name hKey.
Then to check whether or not the value exists, compare retval against ERROR_SUCCESS as described in the documentation.
The other problem with your code is that there is absolutely no error checking. I'll leave that to you to address.
You forget to write an argument about security access

How do I read Registry Key Value

I am Creating the Registry Key using following code:
LPCTSTR lpNDS= TEXT("SOFTWARE\\myKEY");
if(OK==ERROR_SUCCESS)
{
MessageBox ( NULL, "Success",
_T("SimpleShlExt"),
MB_ICONINFORMATION );
}
else
{
MessageBox ( NULL, "Failed" ,
_T("SimpleShlExt"),
MB_ICONINFORMATION );
}
LONG openRes = RegCreateKeyEx(
HKEY_LOCAL_MACHINE,
lpNDS,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hRegKey,
NULL);
if (openRes!=ERROR_SUCCESS)
MessageBox ( NULL, "Registry Createion Failed",
_T("SimpleShlExt"),
MB_ICONINFORMATION );
Now I am writing up to the Key using:
CSimpleShlExt::WriteToRegistry(LPSTR lpRegKeyVal)
{
LONG setRes = RegSetValueEx (hRegKey, "NDS", 0, REG_SZ, (LPBYTE)lpRegKeyVal, strlen(lpRegKeyVal)+1);
CloseRegistryKey();
}
Now I am trying read the registry key value that I have created using WriteToRegistry function. I have tried with
RegOpenKeyEx(hRegKey,lpNDS,0,KEY_QUERY_VALUE,&hRegKey);
But this is failing.
Which function shall I use to read the value contained inside the key?
You can try something like :
TCHAR szValue[TEMP_STR_SIZE] = {0};
DWORD dwStorageSize = TEMP_STR_SIZE;
LPBYTE lpStorage = reinterpret_cast<LPBYTE>(szValue);
// In case of registry value retrieval failure
if (ERROR_SUCCESS != RegQueryValueEx(hRegKey, _T("NDS"), 0, 0, lpStorage, &dwStorageSize))
{
// Prompt error
}
Edit:
Just noticed there are no subkey, changed my sample code
Which function shall I use to read the value contained inside the key?
Try RegQueryValue and/or RegEnumValue. Read the documentation to see which one suits your needs the best.

Delete a registry key recursively

I need to remove a subtree in the Windows registry under Windows Mobile 6. The RegDeleteTree function is not available, and SHDeleteKey is (apparently) not available in any static library under the WM6 SDK, though the declaration is available in shlwapi.h.
I tried to get it from shlwapi.dll, like
typedef DWORD (__stdcall *SHDeleteKey_Proc) (HKEY, LPCWSTR);
SHDeleteKey_Proc procSHDeleteKey;
HINSTANCE shlwapidll = ::LoadLibrary(_T("shlwapi.dll"));
if(shlwapidll) {
procSHDeleteKey =
(SHDeleteKey_Proc)GetProcAddress(shlwapidll,_T("SHDeleteKeyW"));
ASSERT(procSHDeleteKey);
}
But I hit the assert.
Is there a nice way to delete, recursively, a Registry key (empty or not) under Windows Mobile?
I guess I found the answer myself in MSDN. It puzzles me that the functionality is not available through the SDK, though...
I put the code from MSDN here as well, just for the record:
//*************************************************************
//
// RegDelnodeRecurse()
//
// Purpose: Deletes a registry key and all it's subkeys / values.
//
// Parameters: hKeyRoot - Root key
// lpSubKey - SubKey to delete
//
// Return: TRUE if successful.
// FALSE if an error occurs.
//
//*************************************************************
BOOL RegDelnodeRecurse (HKEY hKeyRoot, LPTSTR lpSubKey)
{
LPTSTR lpEnd;
LONG lResult;
DWORD dwSize;
TCHAR szName[MAX_PATH];
HKEY hKey;
FILETIME ftWrite;
// First, see if we can delete the key without having
// to recurse.
lResult = RegDeleteKey(hKeyRoot, lpSubKey);
if (lResult == ERROR_SUCCESS)
return TRUE;
lResult = RegOpenKeyEx (hKeyRoot, lpSubKey, 0, KEY_READ, &hKey);
if (lResult != ERROR_SUCCESS)
{
if (lResult == ERROR_FILE_NOT_FOUND) {
printf("Key not found.\n");
return TRUE;
}
else {
printf("Error opening key.\n");
return FALSE;
}
}
// Check for an ending slash and add one if it is missing.
lpEnd = lpSubKey + lstrlen(lpSubKey);
if (*(lpEnd - 1) != TEXT('\\'))
{
*lpEnd = TEXT('\\');
lpEnd++;
*lpEnd = TEXT('\0');
}
// Enumerate the keys
dwSize = MAX_PATH;
lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL,
NULL, NULL, &ftWrite);
if (lResult == ERROR_SUCCESS)
{
do {
StringCchCopy (lpEnd, MAX_PATH*2, szName);
if (!RegDelnodeRecurse(hKeyRoot, lpSubKey)) {
break;
}
dwSize = MAX_PATH;
lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL,
NULL, NULL, &ftWrite);
} while (lResult == ERROR_SUCCESS);
}
lpEnd--;
*lpEnd = TEXT('\0');
RegCloseKey (hKey);
// Try again to delete the key.
lResult = RegDeleteKey(hKeyRoot, lpSubKey);
if (lResult == ERROR_SUCCESS)
return TRUE;
return FALSE;
}
//*************************************************************
//
// RegDelnode()
//
// Purpose: Deletes a registry key and all it's subkeys / values.
//
// Parameters: hKeyRoot - Root key
// lpSubKey - SubKey to delete
//
// Return: TRUE if successful.
// FALSE if an error occurs.
//
//*************************************************************
BOOL RegDelnode (HKEY hKeyRoot, LPTSTR lpSubKey)
{
TCHAR szDelKey[MAX_PATH*2];
StringCchCopy (szDelKey, MAX_PATH*2, lpSubKey);
return RegDelnodeRecurse(hKeyRoot, szDelKey);
}
The second argument of GetProcAddress is a LPCSTR (that is, it is not a LPCTSTR). So remove the _T() and try this:
GetProcAddress(shlwapidll, "SHDeleteKeyW");
Does that help solve the problem?
You're looking for the RegDeleteTree() function. Just replace RegDeleteKey with it.
Apparently, it took them a while to figure it out, so if you want to support XP or older, you need to have your own implementation of it.