Rough suggestion:
Code:
#include <windows.h>
#include "config.h"
#include "debug.h"
#include "global_definitions.h"
#include "memory.h"
#include "numio.h"
#include "stringio.h"
MYAPPSTATUS g_appStatus;
// Functions prototypes /////////
void InitAppStatus(MYAPPSTATUS * myappStatus);
LONG CheckRegValue(HKEY hKey, LPTSTR regValue, DWORD dataType, void * configPointer,
DWORD defValueSize, DWORD maxValueSize, BOOL notFoundIsError, BOOL * errorMB);
#define NOTE_INVALID_REGISTRY_VALUE(szValueName) \
ErrorMessage("Registry value \"" szValueName "\" was invalid. Default value used",
NULL, NULL, MB_ICONEXCLAMATION, 1);
// Function definitions ///////
void InitMyappStatus(MYAPPSTATUS * myappStatus)
{
DWORD dwKeyDisposition;
BOOL bNotFoundIsError;
BOOL bErrorMB = 1;
HKEY hKey;
DWORD dwDefault;
RegCreateKeyEx(
HKEY_CURRENT_USER,
myapp_DEFAULT_REGKEY,
0,
TEXT(""),
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
(LPSECURITY_ATTRIBUTES) NULL,
&hKey,
&dwKeyDisposition);
bNotFoundIsError = (dwKeyDisposition == REG_OPENED_EXISTING_KEY);
// a bool or dword value...
dwDefault = MY_DEFAULT;
CheckRegValue(hKey,"Test", REG_DWORD,
&myappStatus->btest, &dwDefault,
sizeof(BOOL), sizeof(BOOL),
notFoundIsError, &errorMB);
if(myappStatus->btest > 1 || myappStatus->btest < 0)
{
myappStatus->test = MY_DEFAULT;
NOTE_INVALID_REGISTRY_VALUE("Test");
}
// now a string...
CheckRegValue(hKey, "StrTest", REG_SZ,
myappStatus->szTest, "Default Value",
sizeof(myappStatus->szTest), sizeof("Default Value"),
notFoundIsError, &errorMB);
if (invalidvalue)
{
lstrcpy(myappstatus->szTest, "Default Value");
NOTE_INVALID_REGISTRY_VALUE("StrTest");
}
// etc...
return;
}
LONG CheckRegValue(HKEY hKey,
LPCTSTR szRegValue,
DWORD dwDataType,
LPVOID pvData,
LPVOID pvDefault,
DWORD cbMaxData,
DWORD cbDefault,
BOOL notFoundIsError,
BOOL * errorMB)
{
LONG error;
error = RegQueryValueEx(hKey, szRegValue, NULL, NULL, pvData, &cbMaxData)
if (error != ERROR_SUCCESS)
{
if(error == ERROR_FILE_NOT_FOUND)
{
if(notFoundIsError)
{
*errorMB = (IDOK ==
ErrorPrintf("Failed to Read Registry Key",
MB_ICONEXCLAMATION | MB_OKCANCEL, *errorMB,
"Couldn't find registry value: %s. If you have not deleted any %s"
"keys then you may have a corrupted registry. Press OK to continue or Cancel "
"to continue and skip any subsequent registy errors.",
regValue, VERSION)
);
}
else
{
ErrorPrintf("Registy value initialized.",
MB_ICONINFORMATION, 0,
"The following registry value was successfully initialized: %s",
regValue);
}
}
else
{
*errorMB = (IDOK ==
ErrorPrintf("Failed to Read Registry Key",
MB_ICONEXCLAMATION | MB_OKCANCEL, *errorMB,
"Failed to read registry value \"%s\". Error code: %d."
"Press OK to continue or Cancel to continue and skip any subsequent registy errors.",
regValue, error)
);
}
RegSetValueEx(hKey, regValue, 0, dataType, (CONST BYTE *) pvDefault, cbDefault);
memcpy(pvData, pvDefault, min(cbData, cbDefault));
}
return error;
}
I think your error reporting is probably execessive in some places while missing in much more important places like creating the registry key in the first place. As a guide, here is the registry code for a recent project of mine:
Code:
/* ============================================== */
void Registry_LoadData(void) {
TCHAR szRegKey[MAX_REG_NAME];
HKEY hKey;
HRESULT hr;
LONG lr;
GetRegistryKeyName(szRegKey);
/* Open the job specific registry key */
lr = RegOpenKeyEx(HKEY_CURRENT_USER, szRegKey, 0, KEY_QUERY_VALUE, &hKey);
if (ERROR_SUCCESS != lr) {
ReportError(MSG_ERR_OPEN_REG_KEY, lr, ET_WARNING2, __FILE__, __LINE__, szRegKey);
return;
}
/* Get the last backup time, incremented id number and the number of files that were found during the last backup */
hr = RegGetBinary(hKey, TEXT("Last Backup Time"), &pbj->ftLastBackup, sizeof(pbj->ftLastBackup));
hr |= RegGetBinary(hKey, TEXT("Next Id Number"), &pbj->nBackupId, sizeof(pbj->nBackupId));
hr |= RegGetBinary(hKey, TEXT("LastFoundFiles"), &pbj->cLastFoundFiles, sizeof(pbj->cLastFoundFiles));
if (NOERROR != hr)
ReportError(MSG_ERR_GET_REG_VALUE, hr, ET_WARNING1, __FILE__, __LINE__, szRegKey);
if (0 == pbj->cLastFoundFiles) pbj->cLastFoundFiles = 100; /* Default estimate */
RegCloseKey(hKey);
}
/* ============================================== */
void Registry_SaveData(void)
{
TCHAR szRegKey[MAX_REG_NAME];
HKEY hKey;
LONG lr;
DWORD dwBackupId = pbj->nBackupId + 1;
GetRegistryKeyName(szRegKey);
lr = RegCreateKeyEx(HKEY_CURRENT_USER, szRegKey, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_SET_VALUE, NULL, &hKey, NULL);
if (ERROR_SUCCESS != lr) {
ReportError(MSG_ERR_CREATE_REG_KEY, lr, ET_WARNING1, __FILE__, __LINE__, szRegKey);
return;
}
lr = RegSetValueEx(hKey, TEXT("Last Backup Time"), 0, REG_BINARY, (LPBYTE) &pbj->ftSnapped, sizeof(pbj->ftSnapped));
lr |= RegSetValueEx(hKey, TEXT("Next Id Number"), 0, REG_DWORD, (LPBYTE) &dwBackupId, sizeof(dwBackupId));
lr |= RegSetValueEx(hKey, TEXT("LastFoundFiles"), 0, REG_DWORD, (LPBYTE) &pbj->cFoundFiles, sizeof(pbj->cFoundFiles));
if (ERROR_SUCCESS != lr)
ReportError(MSG_ERR_SET_REG_VALUE, lr, ET_WARNING1, __FILE__, __LINE__, szRegKey);
RegCloseKey(hKey);
}
Note that the error messages are stored in a message file and are not polluting the code.