-
June 26th, 2013, 06:10 PM
#1
Can CWinApp::SetRegistryKey() setup application registry under HKEY_LOCAL_MACHINE?
By default CWinApp::SetRegistryKey() set the application registry under HKEY_CURRENT_USER so each user (windows login account) has their private settings stored for them. However I would like my applications settings to be common for all windows users so I want to store them under HKEY_LOCAL_MACHINE.
Can I do this use MFC registry functions? I hope I don't have to discard the MFC registry access functions in favor of independent registry calls to accomplish this!
-
June 26th, 2013, 07:10 PM
#2
Re: Can CWinApp::SetRegistryKey() setup application registry under HKEY_LOCAL_MACHINE
SetRegistryKey was designed to store read/write user specific data, so that's why HKCU was chosen. You can step into the SetRegistryKey call and look at the appui3.cpp file in the mfc sources. You'll see it's hardcoded to use HKCU.
If you want different behavior, you'll need to roll your own, but keep in mind that on the newer OS's, apps won't have access to HKLM by default, so your app will need to run under higher access privileges.
-
June 27th, 2013, 03:46 AM
#3
Re: Can CWinApp::SetRegistryKey() setup application registry under HKEY_LOCAL_MACHINE
Originally Posted by zspirit
By default CWinApp::SetRegistryKey() set the application registry under HKEY_CURRENT_USER so each user (windows login account) has their private settings stored for them. However I would like my applications settings to be common for all windows users so I want to store them under HKEY_LOCAL_MACHINE.
HKEY_LOCAL_MACHINE was designed to be used as read-only for normal users. So you could write some initial data to it while installing your application; then all users would be able to read those data.
To write to HKLM as Arjay pointed out the users have to run under higher access privileges, which nowaday almost impossible (except some cases like software installing.)
So I'd recommend you to change your design.
Victor Nijegorodov
-
June 27th, 2013, 04:58 AM
#4
Re: Can CWinApp::SetRegistryKey() setup application registry under HKEY_LOCAL_MACHINE
If you need to store data that is common accross all users but is not installation specifc, then this data can be stored as a file under \documents and settings\All users\Application data\{app name}.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
June 27th, 2013, 09:48 AM
#5
Re: Can CWinApp::SetRegistryKey() setup application registry under HKEY_LOCAL_MACHINE
Originally Posted by 2kaud
If you need to store data that is common accross all users but is not installation specifc, then this data can be stored as a file under \documents and settings\All users\Application data\{app name}.
Are there any specific functions that I can create/access such file perhaps with the registry functions?
-
June 27th, 2013, 09:50 AM
#6
Re: Can CWinApp::SetRegistryKey() setup application registry under HKEY_LOCAL_MACHINE
Originally Posted by Arjay
SetRegistryKey was designed to store read/write user specific data, so that's why HKCU was chosen. You can step into the SetRegistryKey call and look at the appui3.cpp file in the mfc sources. You'll see it's hardcoded to use HKCU.
If you want different behavior, you'll need to roll your own, but keep in mind that on the newer OS's, apps won't have access to HKLM by default, so your app will need to run under higher access privileges.
That's a good idea but string thing is that it nevers allow me to step into SetRegistryKey() function so I can't get to its source otherwise I thought I could use function cloning here.
-
June 27th, 2013, 10:00 AM
#7
Re: Can CWinApp::SetRegistryKey() setup application registry under HKEY_LOCAL_MACHINE
Originally Posted by zspirit
That's a good idea but string thing is that it nevers allow me to step into SetRegistryKey() function so I can't get to its source otherwise I thought I could use function cloning here.
Who (or what) never allows you to step in? Do you try it in Debug bulid? What VS are you using?
Besides, as Arjay wrote you could just open appui3.cpp file to see its code. For SetRegistryKey ther is:
Code:
void CWinApp::SetRegistryKey(LPCTSTR lpszRegistryKey)
{
ASSERT(m_pszRegistryKey == NULL);
ASSERT(lpszRegistryKey != NULL);
ASSERT(m_pszAppName != NULL);
BOOL bEnable = AfxEnableMemoryTracking(FALSE);
free((void*)m_pszRegistryKey);
m_pszRegistryKey = _tcsdup(lpszRegistryKey);
free((void*)m_pszProfileName);
m_pszProfileName = _tcsdup(m_pszAppName);
AfxEnableMemoryTracking(bEnable);
}
Victor Nijegorodov
-
June 27th, 2013, 02:35 PM
#8
Re: Can CWinApp::SetRegistryKey() setup application registry under HKEY_LOCAL_MACHINE
Originally Posted by VictorN
Who (or what) never allows you to step in? Do you try it in Debug bulid? What VS are you using?
Besides, as Arjay wrote you could just open appui3.cpp file to see its code. For SetRegistryKey ther is:
Code:
void CWinApp::SetRegistryKey(LPCTSTR lpszRegistryKey)
{
ASSERT(m_pszRegistryKey == NULL);
ASSERT(lpszRegistryKey != NULL);
ASSERT(m_pszAppName != NULL);
BOOL bEnable = AfxEnableMemoryTracking(FALSE);
free((void*)m_pszRegistryKey);
m_pszRegistryKey = _tcsdup(lpszRegistryKey);
free((void*)m_pszProfileName);
m_pszProfileName = _tcsdup(m_pszAppName);
AfxEnableMemoryTracking(bEnable);
}
I am using VS2010 and I 'step in' at this line with debugger it just do 'step over'. I was surprised too by this behavior. Thanks for the code but I don't really see the harcoded value for HKEY_CURRENT_USER. I see another thing though which I also wanted to fix. The default registry entry is the executable name which I wanted to be fixed so I see I could fix that too by cloning this function. However how I direct this to HKEY_LOCAL_MACHINE or anywhere else that I don't have to run into permission issues?
-
June 27th, 2013, 06:50 PM
#9
Re: Can CWinApp::SetRegistryKey() setup application registry under HKEY_LOCAL_MACHINE
Originally Posted by zspirit
I am using VS2010 and I 'step in' at this line with debugger it just do 'step over'. I was surprised too by this behavior. Thanks for the code but I don't really see the harcoded value for HKEY_CURRENT_USER. I see another thing though which I also wanted to fix. The default registry entry is the executable name which I wanted to be fixed so I see I could fix that too by cloning this function. However how I direct this to HKEY_LOCAL_MACHINE or anywhere else that I don't have to run into permission issues?
You have to open the appui3.cpp file to see it. Order to do this, you needed to install the mfc sources when you installed VS. If you didn't, try searching the files in the VS install folder for CWinApp::SetRegistryKey.
As far as directing it to HKLM - you don't (I thought we explained this already???). And if you attempt to access HKLM from your program without the proper permissions, it will fail.
If you need read-only access to info for all users, then use 2kaud's suggestion from his earlier post.
-
June 27th, 2013, 11:23 PM
#10
Re: Can CWinApp::SetRegistryKey() setup application registry under HKEY_LOCAL_MACHINE
Originally Posted by Arjay
You have to open the appui3.cpp file to see it. Order to do this, you needed to install the mfc sources when you installed VS. If you didn't, try searching the files in the VS install folder for CWinApp::SetRegistryKey.
As far as directing it to HKLM - you don't (I thought we explained this already???). And if you attempt to access HKLM from your program without the proper permissions, it will fail.
If you need read-only access to info for all users, then use 2kaud's suggestion from his earlier post.
Since you said its hardcoded to use HKCU, I just wanted to redirect it to HKLM and see what happens. I thought it would be interesting to try on XP (which are my users) but Windows 7 will definitely pose a problem with permission. I was just not able to see the hardcoded part but I will go with the other suggestion.
-
June 27th, 2013, 11:49 PM
#11
Re: Can CWinApp::SetRegistryKey() setup application registry under HKEY_LOCAL_MACHINE
Originally Posted by zspirit
Thanks for the code but I don't really see the harcoded value for HKEY_CURRENT_USER.
Code:
// returns key for HKEY_CURRENT_USER\"Software"\RegistryKey\ProfileName
// creating it if it doesn't exist
// responsibility of the caller to call RegCloseKey() on the returned HKEY
HKEY CWinApp::GetAppRegistryKey(CAtlTransactionManager* pTM)
{
ASSERT(m_pszRegistryKey != NULL);
ASSERT(m_pszProfileName != NULL);
HKEY hAppKey = NULL;
HKEY hSoftKey = NULL;
HKEY hCompanyKey = NULL;
LSTATUS lStatus = pTM != NULL ?
pTM->RegOpenKeyEx(HKEY_CURRENT_USER, _T("software"), 0, KEY_WRITE|KEY_READ, &hSoftKey) :
::RegOpenKeyEx(HKEY_CURRENT_USER, _T("software"), 0, KEY_WRITE|KEY_READ, &hSoftKey);
if (lStatus == ERROR_SUCCESS)
{
DWORD dw;
lStatus = pTM != NULL ?
pTM->RegCreateKeyEx(hSoftKey, m_pszRegistryKey, 0, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL, &hCompanyKey, &dw) :
::RegCreateKeyEx(hSoftKey, m_pszRegistryKey, 0, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL, &hCompanyKey, &dw);
if (lStatus == ERROR_SUCCESS)
{
lStatus = pTM != NULL ?
pTM->RegCreateKeyEx(hCompanyKey, m_pszProfileName, 0, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL, &hAppKey, &dw) :
::RegCreateKeyEx(hCompanyKey, m_pszProfileName, 0, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL, &hAppKey, &dw);
}
}
if (hSoftKey != NULL)
RegCloseKey(hSoftKey);
if (hCompanyKey != NULL)
RegCloseKey(hCompanyKey);
return hAppKey;
}
// returns key for:
// HKEY_CURRENT_USER\"Software"\RegistryKey\AppName\lpszSection
// creating it if it doesn't exist.
// responsibility of the caller to call RegCloseKey() on the returned HKEY
HKEY CWinApp::GetSectionKey(LPCTSTR lpszSection, CAtlTransactionManager* pTM)
{
ASSERT(lpszSection != NULL);
HKEY hSectionKey = NULL;
HKEY hAppKey = GetAppRegistryKey(pTM);
if (hAppKey == NULL)
return NULL;
DWORD dw;
if (pTM != NULL)
{
pTM->RegCreateKeyEx(hAppKey, lpszSection, 0, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL, &hSectionKey, &dw);
}
else
{
::RegCreateKeyEx(hAppKey, lpszSection, 0, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL, &hSectionKey, &dw);
}
RegCloseKey(hAppKey);
return hSectionKey;
}
. . . I see I could fix that too by cloning this function. However how I direct this to HKEY_LOCAL_MACHINE or anywhere else that I don't have to run into permission issues?
Cloning Windows OS?
Okay, getting serious. You were told several times: once you get to writing to local machine hive you inevitably run into permission issue. Once you get to writing under system Program Files folder, you're in trouble again. That was done by Windows architects on purpose, and you have no other way but live with that. If your design contradicts to very basic Windows security guidelines, you're on your own and free to go wherever you want until (or unless) Windows stops you.
I don't know why would anybody need a multi-user app settings be kept in the same storage (.ini or registry or xml, whatever), but if you want to do that, just do that, but don't expect too much help from OS or MFC framework for unwelcomed things.
Best regards,
Igor
-
June 28th, 2013, 12:06 PM
#12
Re: Can CWinApp::SetRegistryKey() setup application registry under HKEY_LOCAL_MACHINE
Originally Posted by zspirit
Since you said its hardcoded to use HKCU, I just wanted to redirect it to HKLM and see what happens.
If you change the file to point to HKLM and recompiled the MFC source files, the data would be redirected to HKLM. But then you would have to distribute the recompiled MFC dll with your app and that would violate MS's MFC redistributable agreement, not to mention break other apps that happened to use the modified DLL. On newer OS's you are also going to run into issues with the private copy and it may be flagged as spyware (because it's been modified). In short - you open up a big can of worms here just because you are attempting to do something that is non-standard and has been locked down by MS.
Originally Posted by zspirit
I thought it would be interesting to try on XP (which are my users) but Windows 7 will definitely pose a problem with permission. I was just not able to see the hardcoded part but I will go with the other suggestion.
If it were me, I would just would store an xml file in the shared location that was mentioned and use IXMLDocument interface to manipulate the xml. I would write a wrapper class to make it simple to access it from my class.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|