|
I've added these two member functions to the class so I could enumerate keys/values. Maybe they are of use to you...
Don't forget to include <vector>!
BOOL CRegistry::EnumKeys(std::vector<CString> *sv)
{
BOOL bSuccess = TRUE;
_TCHAR sz[255];
DWORD dwSize;
HKEY hKey;
ASSERT(m_strCurrentPath.GetLength() > 0);
sv->clear();
m_nLastError = ::RegOpenKeyEx(m_hRootKey, LPCTSTR(m_strCurrentPath), 0,
KEY_READ, &hKey);
if (m_nLastError != ERROR_SUCCESS) return FALSE;
DWORD idx = 0;
DWORD err;
do
{
dwSize = 255;
err = ::RegEnumKeyEx(hKey,idx,(LPTSTR)sz,&dwSize,NULL,NULL,NULL,NULL);
if (ERROR_SUCCESS == err)
{
sv->push_back(CString((LPCTSTR)sz));
++idx;
}
} while (ERROR_SUCCESS == err);
::RegCloseKey(hKey);
m_nLastError = err;
if (m_nLastError != ERROR_NO_MORE_ITEMS) bSuccess = FALSE;
if (!bSuccess) return FALSE;
return TRUE;
}
BOOL CRegistry::EnumValues(std::vector<CString> *sv)
{
BOOL bSuccess = TRUE;
_TCHAR sz[16383];
DWORD dwSize;
HKEY hKey;
ASSERT(m_strCurrentPath.GetLength() > 0);
sv->clear();
m_nLastError = ::RegOpenKeyEx(m_hRootKey, LPCTSTR(m_strCurrentPath), 0,
KEY_READ, &hKey);
if (m_nLastError != ERROR_SUCCESS) return FALSE;
DWORD idx = 0;
DWORD err;
do
{
dwSize = 16383;
err = ::RegEnumValue(hKey,idx,(LPTSTR)sz,&dwSize,NULL,NULL,NULL,NULL);
if (ERROR_SUCCESS == err)
{
sv->push_back(CString((LPCTSTR)sz));
++idx;
}
} while (ERROR_SUCCESS == err);
::RegCloseKey(hKey);
m_nLastError = err;
if (m_nLastError != ERROR_NO_MORE_ITEMS) bSuccess = FALSE;
if (!bSuccess) return FALSE;
return TRUE;
}
|
|
|
|
|
I get the warning
"LINK : warning LNK4089: all references to "GDI32.dll" discarded by
/OPT:REF"
when building in Release Mode.
For testing I created a new dialogbased project and built it in Release Mode without any errors/warnings. After adding CRegistry class and rebuilding in Release Mode I got this warning. I only use the methods "SetRootKey", "SetKey", "WriteString", "ReadString", "ClearKey"
It builds without warnings in Debug Mode.
I'm using VC++6 (german version, latest SP) on Win2k.
--
Karl
|
|
|
|
|
Problem solved,
the references to GDI32.dll were caused by "ReadPoint()" and "WritePoint()". I took those out. Now it's linking without any warnings.
--
Karl
|
|
|
|
|
Obviously this warning is generated because the class is linking to functions in this DLL which your code is not calling. The compiler omits these references to optimize your code -- no sense in loading a bunch of code you don't need.
Of course, you could just simply ignore this warning, as it's basically just an FYI message.
If you ABSOLUTELY MUST achieve a warning-free compile, you may need to omit more than ReadPoint() and WritePoint(). I still received the warning after commenting out these two functions in VC6. In my case, I commented out the Read and Write functions for Color, Font, Point, Size and Rect.
To fully optimize your code, it's actually a good idea to comment out all functions that you aren't using. Of course, it goes without saying you should also comment out the corresponding declarations in the header file.
I LOVE this class! I use it all the time, and have NEVER had a problem with it.
|
|
|
|
|
I think this is an excellent class, but still it has a little problem .
If you working with Unicode and trying to write a string to the registry only the first half of the string is written. The reason: the length is calculated correctly but every character is 2 bytes. RegSetValueEx want's the size in bytes so it's necessary to multiply with 2. OK, no more details . Here is the fix:
Remove these lines:
#ifdef _UNICODE
if (::RegSetValueEx(hKey, LPCTSTR(strName), 0,
REG_SZ, (LPBYTE)sz, wcslen(sz) + 1)
!= ERROR_SUCCESS) bSuccess = FALSE;
#else
if (::RegSetValueEx(hKey, LPCTSTR(strName), 0,
REG_SZ, (LPBYTE)sz, strlen(sz) + 1)
!= ERROR_SUCCESS) bSuccess = FALSE;
#endif
…and replace width these:
if (::RegSetValueEx(hKey, LPCTSTR(strName), NULL,
REG_SZ, (LPBYTE)sz, (lstrlen(sz)+1)*sizeof(TCHAR))
!= ERROR_SUCCESS) bSuccess = FALSE;
Yes, these lines are enough to do the work in Unicode and none-Unicode versions.
|
|
|
|
|
another method could be
if (::RegSetValueEx(hKey, LPCTSTR(strName), 0,<br />
REG_SZ, (LPBYTE)sz, (DWORD)(_tcslen(sz) + 1))<br />
!= ERROR_SUCCESS) bSuccess = FALSE;
|
|
|
|
|
I am trying to use the simple class but I am problably stupid
because I can t found how to get the default data of a Key.
I mean the value to entrer in the function ReadString("???", "***");
My registry :
(par défaut) REG_SZ Winzip <- Who to get this value
Content Type REG_SZ application/mac-binhex40
Any idees ?
|
|
|
|
|
Sorry I am found the solution 10 secondes later LOL
Put empty CString to get the default value !!!!!!!
|
|
|
|
|
I'm not even sure that this is the problem, but when I run my application using your CRegistry class, it seems to have a problem writing the keys when I run as a user that does not have administrative privileges. Do you know why this might be?
Here's my code:
void CPreferences::InitializeRegistry()
{
CRegistry Reg;
Reg.SetRootKey(HKEY_LOCAL_MACHINE);
if( !Reg.KeyExists( "Software\\Compact Power" ) )
{
Reg.CreateKey( "Software\\Compact Power" );
}
if( !Reg.KeyExists( "Software\\Compact Power\\BMS Monitor" ) )
{
Reg.CreateKey( "Software\\Compact Power\\BMS Monitor" );
}
if( !Reg.KeyExists( "Software\\Compact Power\\BMS Monitor\\Settings" ) )
{
Reg.CreateKey( "Software\\Compact Power\\BMS Monitor\\Settings" );
}
Reg.SetKey( "Software\\Compact Power\\BMS Monitor\\Settings", FALSE );
if( !Reg.ValueExists( "COMPORT" ) )
Reg.WriteString( "COMPORT", "COM1" );
if( !Reg.ValueExists( "PARITY" ) )
Reg.WriteString( "PARITY", "NONE" );
if( !Reg.ValueExists( "DATABITS" ) )
Reg.WriteString( "DATABITS", "8" );
if( !Reg.ValueExists( "STOPBITS" ) )
Reg.WriteString( "STOPBITS", "1" );
if( !Reg.ValueExists( "BAUDRATE" ) )
Reg.WriteString( "BAUDRATE", "57600" );
if( !Reg.ValueExists( "HANDSHAKING" ) )
Reg.WriteString( "HANDSHAKING", "NONE" );
if( !Reg.ValueExists( "RUNMODE" ) )
Reg.WriteString( "RUNMODE", "1" );
if( !Reg.ValueExists( "LASTDB" ) )
Reg.WriteString( "LASTDB", "" );
if( !Reg.ValueExists( "BASEDBDIR" ) )
Reg.WriteString( "BASEDBDIR", "C:\\BMSMonitorData" );
if( !Reg.ValueExists( "AUTOSAVE" ) )
Reg.WriteString( "AUTOSAVE", "5" );
if( !Reg.ValueExists( "SAVEDATA" ) )
Reg.WriteString( "SAVEDATA", "0" );
if( !Reg.ValueExists( "LOGFILE" ) )
Reg.WriteString( "LOGFILE", "" );
}
Thanks for your help.
-Matt
------------------------------------------
The 3 great virtues of a programmer:
Laziness, Impatience, and Hubris.
--Larry Wall
|
|
|
|
|
If you are are running an NT based windows then the user will need to be given privleges access the registry. This can be done through a program called regedt32.exe. In there you can set the permissions on the registry keys the same way that you can set up with files and directories, ie. Full Control, Read, Write etc.
Cheers,
Clint
|
|
|
|
|
That is good to know, but how do I do this programatically? I need to ensure that *anyone* can have permission to read and write these settings. I want my app to be able to add the keys as necessary if they don't exist starting with a key just under the Software directory in HKEY_LOCAL_MACHINE regardless of the current user's permissions.
Thanks for your help.
-Matt
------------------------------------------
The 3 great virtues of a programmer:
Laziness, Impatience, and Hubris.
--Larry Wall
|
|
|
|
|
From what I could find out it seems that it can't be done programatically. Unless there is a way to run the program as a privledged user. Only one with administrator privleges can even make the changes to the registry keys to give lower users access. That means the lower privledged user is going a pretty hard time accessing the registry. If they did have access then that would be a potential security breach. In any case good luck with your endevour.
Cheers,
Clint
|
|
|
|
|
Duh! I'm an idiot. You might expect this kind of question from a long time Windows guy, but I started with Unix. If anyone should understand permissions, I should. If a user had the ability to give himself super-user rights, what's the point of security? Sorry for the stupid question. I guess I just have a hard time getting it through my head that Microsoft finally got around to adding security after those excuses for OSs Win95/98.
I think I'm just going to start looking through the registry for a spot that is not as protected.
Thanks for your help.
-Matt
------------------------------------------
The 3 great virtues of a programmer:
Laziness, Impatience, and Hubris.
--Larry Wall
|
|
|
|
|
That's what HKEY_CURRENT_USER\Software is for
These are not the droids you're looking for...
|
|
|
|
|
This is probably a dumb question, but Should this work with windows 98?
Thanks.
-Matt
------------------------------------------
The 3 great virtues of a programmer:
Laziness, Impatience, and Hubris.
--Larry Wall
|
|
|
|
|
Yes, unless you are using the Windows from Microsoft. Then it's a crap shoot.
|
|
|
|
|
Seriously, I have never had a problem using it on Windows 95, 98, ME, NT4, 2000, XP.
Except maybe if some paranoid network administrator configured the system so that you can't write to the registry. I actually had a customer that complained because my software wouldn't work. Their network admin configured the system so no software wrote to the registry. Yeah, the software doesn't work if you disable Windows.
|
|
|
|
|
Very nice job! This is very simple and intuitive! Nice work!
-Matt
------------------------------------------
The 3 great virtues of a programmer:
Laziness, Impatience, and Hubris.
--Larry Wall
|
|
|
|
|
I belive you could use a GenericRead()/GenericWrite() functions instead of all the ReadRect/WriteTime ect.
In all the above cases, you use the binary method for reading/writing, so I guess the only reason to give the users a whole set of function is to make their life easier... but, if the users know what they should read or write, why won't they use a simple type-cast instead?
give them a couple of functions like the following ones:
bool ReadGeneric(CString strKey, CString strValue, LPVOID lpData, DWORD& dwDataSize);
bool WriteGeneric(CString strKey, CString strValue, LPVOID lpData, DWORD dwDataSize);
and in there do a binary read/write with the given data and size.
the user will do the casting back and forth between these functions and the calling function.
simple, clean and useful.
and btw, nice work with the helper class thanks!
alpha+
|
|
|
|
|
I'd like to suggest adding the following function to your class. This allows querying of a remote registry.
BOOL RemoteConnection(CString strComputerName);
BOOL CRegistry::RemoteConnection(CString strComputerName)
{
if (RegConnectRegistry(strComputerName, m_hRootKey, &m_hRootKey)==ERROR_SUCCESS)
return TRUE;
else
return FALSE;
}
Please note : you must call SetRootKey before using RegConnectRegistry
i386 the source for Windows XP/2000/NT
http://www.i386.com
|
|
|
|
|
... does somebody know how to access the registry programmatically by a non administrative user?
thanks,
tobi
|
|
|
|
|
A non administrative user can still access the registry just like an administrative user, but the Security settings for that registry key must be set to allow it.
|
|
|
|
|
WriteDword function is creating a Binary value instead of a DWORD.
To create a DWORD value, the functionshould use
if (::RegSetValueEx(hKey, LPCTSTR(strName), 0,
REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue))
!= ERROR_SUCCESS) bSuccess = FALSE;
in the place of
if (::RegSetValueEx(hKey, LPCTSTR(strName), 0,
REG_BINARY, (LPBYTE)&dwValue, sizeof(dwValue))
!= ERROR_SUCCESS) bSuccess = FALSE;
Regards!
asX
|
|
|
|
|
Robert,
Thanks for making such a kick ass class and releasing it.
You inspired me to release some wrapper classes that are useful as well.
This was well written and again, thanks
-- Dan
www.dancclark.com
|
|
|
|
|
I want to know more about registry. All about this.
I want to know what is happening when I plug a card in my computer, haw the Win recognize it, how it write the inform and the configuration in the registry, from where Win take that informationwhere are this inform saved.
I want to make drivers. Where can i find some information about this?
very nice
|
|
|
|
|