Почему функция RegQueryValueEx () возвращает ERROR_FILE_NOT_FOUND при попытке чтения из раздела реестра? - PullRequest
7 голосов
/ 21 декабря 2011

Система: Windows 7 32bit
Язык: C ++

Я пытался получить доступ к регистру HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0, ключ Driver (тип REG_SZ) - без проблем.

То же самое для чтения из HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM, все ключи (типы REG_SZ) имеют косую черту, например \Device\Serial0.

При чтении таких ключей всегда возвращается 2 (такого файла нет) с кодом следующего примера:

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 ---

Как правильно читать значения ключей с косой чертой в имени?


Выше был правильно ответил Коди Грей.
Ниже еще одна проблема.

У меня та же проблема, когда я использую переменную вместо текстовой строки.
Ив рассмотрел оба подхода с одинарной и двойной косой чертой:

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!

Я перепробовал все варианты с "\ Device ..", "/ Device", "\ Device" и т. Д.

1 Ответ

8 голосов
/ 21 декабря 2011

Вы должны убежать от косой черты, как вы это делали в первой строке ...

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

Если этого не сделать, функция RegQueryValueEx не может найти указанную клавишу и возвращает ERROR_FILE_NOT_FOUND (== 2).


Но есть и другая проблема. Вы должны объявить буферный массив как тип wchar_t (или TCHAR), а не char:

TCHAR buf[255] = {0};

В противном случае функция RegQueryValueEx попытается заполнить массив строкой Юникода, считанной из указанного ключа реестра, и вы получите что-то нечитаемое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...