System: Windows 7 32bit
Language: C++
I have tried to access register HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0
, key Driver
(type REG_SZ
) -- no problem.
The same for reading from HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM
, all keys (types REG_SZ
) got slashes, for example \Device\Serial0
.
While reading such keys it always returns 2 (no such file) with following example code:
HKEY hKey = 0;
DWORD dwType = REG_SZ;
char buf[255] = {0};
DWORD dwBufSize = sizeof(buf);
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS )
{
auto ret = RegQueryValueEx( hKey, TEXT("\Device\Serial0"), 0, &dwType, (LPBYTE)buf, &dwBufSize );
// ret always == 2 for key with slashes
--- CUT ---
What is the proper way to read key values with slashes in name?
Im getting the same problem when Im using variable instead of a text string.
Iv considered both approaches with single and double slashes:
HKEY hKey = 0;
DWORD keyType = REG_SZ;
TCHAR buf[255] = {0};
DWORD bufSize = sizeof(buf);
QSettings winReg("HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM", QSettings::NativeFormat);
auto comsKey = winReg.allKeys();
FOREACH( auto com, comsKey )
{
// FOREACH - boost macro
// comsKey = QList<QString> (list of key names) [from Qt framework]
// com = QString (single key name) [from Qt framework]
if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS )
{
wchar_t* keyw = new wchar_t();
//com.replace("/", "\\\\"); <- checked both variants commented and not commented; com == /Device/Serial0 so im converting to \\Device\\Serial0
int size = com.size();
mbstowcs( keyw, com.toStdString().data(), size );
//auto ret = RegQueryValueEx( hKey, TEXT("\\Device\\Serial0"), 0, &keyType, (LPBYTE)buf, &bufSize ); // <- this works!
auto ret = RegQueryValueExW( hKey, (LPCWSTR)&keyw, 0, &keyType, (LPBYTE)buf, &bufSize ); // <- this one not works!
I have tried all variants with "\Device..", "/Device", "\Device", etc.
You have to escape the slashes, just like you did in the first line...
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS )
{
auto ret = RegQueryValueEx( hKey, TEXT("\\Device\\Serial0"), 0, &dwType, (LPBYTE)buf, &dwBufSize );
// ret always == 2 for key with slashes
If you don't, the RegQueryValueEx
function can't find the specified key, and it returns ERROR_FILE_NOT_FOUND
(== 2).
But there's another problem. You should be declaring the buffer array as type wchar_t
(or TCHAR
), rather than char
:
TCHAR buf[255] = {0};
Otherwise, the RegQueryValueEx
function is going to attempt to fill the array with a Unicode string read from the specified registry key, and you're going to get something unreadable.