To call RegSaveKeyEx successfully, you need the SE_BACKUP_NAME privilege. It seems that administrators have this privilege by default so it probably just needs to be enabled in your program. You can check on your machine by looking under Control Panel->Administrative Tools->Local Security Policy->Local Policies->User Rights Assignment. The SE_BACKUP_NAME privilege has the friendly name "Back up files and directories".
To enable a privilege, you can use this function from Microsoft or a function that I have (shown below). The advantage of my function is that it will not cause load problems on Windows 9x. By using RegSaveKeyEx, your program will only load on Windows XP or better anyway so you may as well use the simpler Microsoft function.
Code:
/*
* This function enables or disables a privilege for the current process.
* Common privileges include SE_SHUTDOWN_NAME, SE_BACKUP_NAME, SE_SYSTEMTIME_NAME, etc.
* This function dynamically loads the required functions so as not to cause load
* problems on 9x where these functions may not be available.
*/
BOOL WINAPI EnableProcessPrivilege(LPCTSTR lpPrivilege, BOOL bEnable)
{
typedef BOOL (WINAPI * fnptr_openprocesstoken)(HANDLE,DWORD,PHANDLE);
typedef BOOL (WINAPI * fnptr_adjusttokenprivileges)(HANDLE,BOOL,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
typedef BOOL (WINAPI * fnptr_lookupprivilegevalue)(LPCTSTR,LPCTSTR,PLUID);
TOKEN_PRIVILEGES tp = { 0 };
HMODULE hAdvapi = NULL;
HANDLE hToken = NULL;
BOOL bResult = FALSE;
fnptr_openprocesstoken openprocesstoken;
fnptr_adjusttokenprivileges adjusttokenprivileges;
fnptr_lookupprivilegevalue lookupprivilegevalue;
/* Load the required functions */
if (!(hAdvapi = LoadLibrary(TEXT("Advapi32.dll"))) ||
!(openprocesstoken = (fnptr_openprocesstoken) GetProcAddress(hAdvapi, "OpenProcessToken")) ||
!(adjusttokenprivileges = (fnptr_adjusttokenprivileges) GetProcAddress(hAdvapi, "AdjustTokenPrivileges")) ||
#ifndef UNICODE
!(lookupprivilegevalue = (fnptr_lookupprivilegevalue) GetProcAddress(hAdvapi, "LookupPrivilegeValueA")))
#else
!(lookupprivilegevalue = (fnptr_lookupprivilegevalue) GetProcAddress(hAdvapi, "LookupPrivilegeValueW")))
#endif
{
goto cleanup;
}
/* Get the local id of our desired privilege */
if (!lookupprivilegevalue(NULL, lpPrivilege, &tp.Privileges[0].Luid))
goto cleanup;
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = (bEnable ? SE_PRIVILEGE_ENABLED : 0);
/* Get the access token for the current process */
if (!openprocesstoken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
goto cleanup;
/* Enable the privilege */
if (!adjusttokenprivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
goto cleanup;
bResult = TRUE;
cleanup:
if (hAdvapi) FreeLibrary(hAdvapi);
if (hToken) CloseHandle(hToken);
return bResult;
}