Ternick
@Ternick

Как правильно передать в RegSetValueEx в lpData NULL?

Суть вопроса в чём. Я написал такую функцию:
bool modifyKey(HKEY _hKey, wstring path, LPCWSTR name, LPCWSTR value) {
	HKEY hKey;
	if (RegOpenKey(_hKey, path.data(), &hKey) == ERROR_SUCCESS) {
		if (RegSetValueEx(hKey, name, NULL, REG_SZ, (BYTE*)value, sizeof(value)) == ERROR_SUCCESS) {//SIZEOF(VALUE), сюда не смотреть, я уже пробовал по разному и оставил так.
				return RegCloseKey(hKey) == ERROR_SUCCESS;
		}
		else {
			RegCloseKey(hKey);
		}
	}
	else {
		if (RegCreateKey(_hKey, path.data(), &hKey) == ERROR_SUCCESS) {
			if (RegSetValueEx(hKey, name, NULL, REG_SZ, (BYTE*)value, sizeof(value)) == ERROR_SUCCESS)//SIZEOF(VALUE), сюда не смотреть, я уже пробовал по разному и оставил так. {
				return RegCloseKey(hKey) == ERROR_SUCCESS;
			}
			else {
				RegCloseKey(hKey);
			}
		}
	}
	return false;
}

Мне нужно создавать в реестре не заполненный скелет данных по определённому пути.
И так получается, что в переменные name, value время от времени попадает NULL.
Сама проблема в том, что программа падает из-за того,что я хочу получить длину строки(wcslen) или её размеры(sizeof) т.к. в переменной value лежит NULL.
Как это исправить и было бы интересно узнать, что в функцию RegSetValueEx нужно передавать в cbData ?
  • Вопрос задан
  • 73 просмотра
Решения вопроса 1
@MarkusD Куратор тега C++
все время мелю чепуху :)
Начнем с простого.
sizeof( expresion ) позволяет узнать минимально допустимый размер памяти, требуемый для того чтобы память могла вместить объект с типом результата утверждения expresion.
sizeof( value ) вернет размер LPCWSTR, т.е. размер типа const wchar_t*.

wcslen не допускает передачу нуля в качестве своего параметра. Забота об этом лежит полностью на тебе.

RegSetValueExW может принимать нуль в параметре lpData, но тогда cbData обязан содержать 0. Но в целом, это очень плохая практика. Если тебе нужно записать пустую строку, пиши пустую. строку. Т.е. "", но не нуль.

cbData должен быть задан размером буфера строки в байтах, включая терминальный символ, или оба терминальных символа в случае многострочного аргумента в lpData. Важным замечанием будет именно то, что в cbData указывается размер в байтах, а не в символах. У тебя в lpData передается строка из wchar_t, размер которого больше одного байта.

Далее, по самому коду. Его тяжело читать.
Как читать будет легче
bool modifyKey( HKEY root_hey, const std::wstring_view& path, const std::wstring_view& key_name, const std::wstring_view& new_value )
{
   HKEY folder_key;

   if( RegCreateKeyW( root_hey, path.data(), &folder_key ) != ERROR_SUCCESS )
   {
      return false;
   }

   const BYTE* const value_buffer = reinterpret_cast<const BYTE*>( new_value.data() );
   const DWORD buffer_size = static_cast<DWORD>( new_value.length() * sizeof( wchar_t ) + 1 );
   if( RegSetValueExW( folder_key, key_name.data(), 0, REG_SZ, value_buffer, buffer_size ) != ERROR_SUCCESS )
   {
      RegCloseKey( folder_key );
      return false;
   }

   if( RegFlushKey( folder_key ) != ERROR_SUCCESS )
   {
      RegCloseKey( folder_key );
      return false;
   }

   RegCloseKey( folder_key );
   return true;
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы