Как мне прочитать / изменить значения реестра, созданные другой службой Windows?

Таким образом, в основном у меня есть служба, которая должна выполнять функции моего диспетчера обновлений программ. Это все, что я пытаюсь сделать автоматически обновляемой программой, в которую не нужно входить пользователю.

Поэтому мой менеджер обновлений при установке создает некоторые начальные значения / структуры реестра со следующим кодом:

LPCWSTR strInITKeyName = L"SOFTWARE\\InIT\\";
DWORD rtime = 0;
HKEY InITKey;
LONG nInITError;
nInITError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strInITKeyName, 0, 0, &InITKey);
if (ERROR_NO_MATCH == nInITError || ERROR_FILE_NOT_FOUND == nInITError)
{
std::cout << "Registry key not found.  Setting up..." << std::endl;
long nError = RegCreateKeyEx(HKEY_LOCAL_MACHINE, strInITKeyName, 0L, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &InITKey, NULL);
if (ERROR_SUCCESS != nError)
std::cout << "Error:  Could not create registry key HKEY_LOCAL_MACHINE\\" << strInITKeyName << std::endl << "\tERROR: " << nError << std::endl;
else
{
std::cout << "Successfully created registry key HKEY_LOCAL_MACHINE\\" << strInITKeyName << std::endl;

// See https://www.experts-exchange.com/questions/10171094/Using-RegSetKeySecurity.html for example
//SECURITY_DESCRIPTOR sd;
//PACL pDacl = NULL;

//RegSetKeySecurity(InITKey);
}
}
else if (nInITError == ERROR_ACCESS_DENIED)
{
long nError = RegCreateKeyEx(HKEY_LOCAL_MACHINE, strInITKeyName, 0L, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &InITKey, NULL);
if (ERROR_SUCCESS != nError)
std::cout << "Error:  Could not create registry key HKEY_LOCAL_MACHINE\\" << strInITKeyName << std::endl << "\tERROR: " << nError << std::endl;
else
std::cout << "Successfully created registry key HKEY_LOCAL_MACHINE\\" << strInITKeyName << std::endl;
}
else if (ERROR_SUCCESS != nInITError)
{
std::cout << "Cannot open registry key HKEY_LOCAL_MACHINE\\" << strInITKeyName << std::endl << "\tERROR: " << nInITError << std::endl;
rtime = 0;
}

// Generate guid
//
GUID guid;
HRESULT hr = CoCreateGuid(&guid);

// Convert the GUID to a string
OLECHAR* guidString;
StringFromCLSID(guid, &guidString);

// Setup registry values
// Sets clientguid value and ties to strInITKeyName
std::wstring clientguid = guidString;   // InITKey
clientguid = clientguid.substr(1, 36);

LONG nClientGUIDError = RegSetValueEx(InITKey, L"clientguid", NULL, REG_SZ, (const BYTE*)clientguid.c_str(), (clientguid.size() + 1) * sizeof(wchar_t));
if (nClientGUIDError)
std::cout << "Error: " << nClientGUIDError << " Could not set registry value: " << "clientguid" << std::endl;
else
std::wcout << "Successfully set InIT clientguid to " << clientguid << std::endl;

// ensure memory is freed
::CoTaskMemFree(guidString);
RegCloseKey(InITKey);

Когда он удаляется, он удаляет значения реестра. Моя настоящая программа — это служба Windows, которая будет работать на установленном компьютере и должна иметь доступ к некоторым из этих значений реестра.

Раньше у меня не было этого менеджера обновлений, а вместо этого я устанавливал значения в реестре в реальной службе программы. Чтение и письмо работали тогда просто отлично. Но так как я переключился на то, чтобы мой Менеджер обновлений установил эти начальные значения и намеревался, чтобы мой главный сервис Windows получил к ним доступ.

Когда я пытаюсь это сделать, я каждый раз получаю ошибку ERROR_ACCESS_DENIED, несмотря на то, что пробовал все виды различных токенов безопасности, таких как KEY_READ || KEY_WOW64_64KEY и другие во многих комбинациях при попытке открыть ключ. Как вы видели выше, я устанавливаю KEY_ALL_ACCESS при установке токена. Я бы подумал, что смогу получить к нему доступ нормально, но это не позволяет мне. Единственный вывод, к которому я могу прийти, это то, что каким-то образом мой менеджер обновлений владеет ключами / значениями в реестре.

Каким будет правильный код для доступа к этим файлам реестра из моей службы Windows?

Мой текущий код для доступа к этим значениям реестра (клиентский гид, который я генерирую при установке диспетчера обновлений) см. код выше):

// Log a service start message to the Application log.
WriteEventLogEntry(L"InITService Starting in OnStart", EVENTLOG_INFORMATION_TYPE);
this->m_ServiceLogger->info("Initialized logger bruh");

// Query clientguid from registry
HKEY InITKey;
std::wstring valuename;

ULONG nError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\InIT\\", 0, KEY_READ || KEY_WOW64_64KEY, &InITKey);

DWORD dwBufferSize = TOTALBYTES;
DWORD cbData;

WCHAR *wcBuffer = (WCHAR*)malloc(dwBufferSize);
cbData = dwBufferSize;
if (nError == ERROR_SUCCESS)
this->m_ServiceLogger->info("Getting reg");

if (nError == ERROR_SUCCESS)
{
std::wstring clientguid;
clientguid = L"";
valuename = L"clientguid";

nError = RegQueryValueExW(HKEY_LOCAL_MACHINE, valuename.c_str(), 0, NULL, (LPBYTE) wcBuffer, &cbData);

while (nError == ERROR_MORE_DATA)       // Get a buffer that is big enough if not already
{
this->m_ServiceLogger->info("Increasing clientguid buffer size");
dwBufferSize += BYTEINCREMENT;
wcBuffer = (WCHAR*) realloc( wcBuffer, dwBufferSize );
cbData = dwBufferSize;

nError = RegQueryValueExW(HKEY_LOCAL_MACHINE, valuename.c_str(), 0, NULL, (LPBYTE)wcBuffer, &cbData);
}
if (ERROR_SUCCESS == nError)
{
clientguid = wcBuffer;
std::string cg(clientguid.begin(), clientguid.end());
this->m_ClientGuid = cg;
this->m_ServiceLogger->info("Clientguid yo: " + cg);
}
else if (nError = ERROR_ACCESS_DENIED)
this->m_ServiceLogger->info("ClientGUID:  Access Denied");
if (!this->checkRegistryValues())
{
this->generateRegistry();
}
}
else
{
std::stringstream errstr;
errstr << nError;
this->m_ServiceLogger->info("Error: " + errstr.str() + " RegOpenKeyEx failed");
}

this->setSchedulingUtility();  // Hardcoded to set scheduled update at 1:00 AM

WriteEventLogEntry(L"InITService Initialized Schedule in OnStart", EVENTLOG_INFORMATION_TYPE);
this->m_ServiceLogger->info("Initialized ClientGUID: " + this->m_ClientGuid);
this->m_ServiceLogger->info("Initialized CurrentVersion: " + this->m_CurrentVersion);
this->m_ServiceLogger->info("Initialized WebServerURL: " + this->m_POSTAddress);
this->m_ServiceLogger->flush();

RegCloseKey(InITKey);

// Queue the main service function for execution in a worker thread.
CThreadPool::QueueUserWorkItem(&CSampleService::ServiceWorkerThread, this);

-1

Решение

При звонке RegOpenKeyEx(), вам нужно использовать BITWISE ИЛИ (|) вместо ЛОГИЧЕСКОГО ИЛИ (||) оператор. Изменить:

KEY_READ || KEY_WOW64_64KEY

Для того, чтобы:

KEY_READ | KEY_WOW64_64KEY

Тем не менее, когда ваш менеджер обновлений вызывает RegOpenKeyEx(), это не указывает никаких прав доступа вообще, это установка samDesired параметр в 0. Это должно быть установлено по крайней мере KEY_SET_VALUE вместо. Когда это вызывает RegCreateKeyEx() если RegOpenKeyEx() не удается, это установка samDesired в KEY_ALL_ACCESS, Не делай этого. Используйте только те права доступа, которые вам действительно нужны (KEY_SET_VALUE, так далее).

В любом случае, нет необходимости звонить обоим RegOpenKeyEx() а также RegCreateKeyEx() тем не мение. Просто позвони RegCreateKeyEx() само собой. Он откроет существующий ключ и создаст несуществующий ключ. это dwDisposition Выходной параметр скажет вам, что произошло.

В этом коде есть и другие ошибки. Как передать неправильно HKEY в RegQueryValueEx()и не проверяя на ERROR_ACCESS_DENIED код ошибки правильно (используя = оператор присваивания вместо == оператор сравнения). И утечки памяти.

Попробуйте что-то более похожее на это:

Менеджер обновлений:

LPCWSTR strInITKeyName = L"SOFTWARE\\InIT\\";
HKEY InITKey;
DWORD dwDisposition;

LONG nError = RegCreateKeyEx(HKEY_LOCAL_MACHINE, strInITKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE | KEY_WOW64_64KEY, NULL, &InITKey, &dwDisposition);

if (ERROR_SUCCESS != nError)
{
std::cout << "Error: Could not open/create registry key HKEY_LOCAL_MACHINE\\" << strInITKeyName << std::endl << "\tERROR: " << nError << std::endl;
}
else
{
std::cout << "Successfully " << ((REG_CREATED_NEW_KEY == dwDisposition) ? "created" : "opened") << " registry key HKEY_LOCAL_MACHINE\\" << strInITKeyName << std::endl;

// Generate guid and convert to a string
//
std::wstring clientguid;
GUID guid;

HRESULT hr = CoCreateGuid(&guid);
if (FAILED(hr))
{
std::cout << "Error: Could not generate clientguid" << std::endl << "\tERROR: " << (int)hr << std::endl;
}
else
{
WCHAR guidString[40] = {0};
int len = StringFromGUID2(guid, guidString, 40);
if (len > 2)
{
// Sets clientguid value and ties to strInITKeyName
clientguid.assign(&guidString[1], len-2);
}
}

// Setup registry values

nError = RegSetValueEx(InITKey, L"clientguid", NULL, REG_SZ, (const BYTE*) clientguid.c_str(), (clientguid.size() + 1) * sizeof(wchar_t));
if (ERROR_SUCCESS != nError)
std::cout << "Error: Could not set registry value: clientguid" << std::endl << "\tERROR: " << nError << std::endl;
else
std::wcout << "Successfully set InIT clientguid to " << clientguid << std::endl;

RegCloseKey(InITKey);
}

Программа обслуживания:

...

// Query clientguid from registry
HKEY InITKey;

LONG nError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\InIT\\", 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &InITKey);

if (ERROR_SUCCESS != nError)
{
std::stringstream errstr;
errstr << nError;
this->m_ServiceLogger->info("Error: " + errstr.str() + " RegOpenKeyEx failed");
}
else
{
this->m_ServiceLogger->info("Getting reg");

std::vector<BYTE> buffer(TOTALBYTES + sizeof(wchar_t), 0); // extra room for a null terminator, in case it is missing in the Registry data
DWORD cbData = TOTALBYTES;

do
{
nError = RegQueryValueExW(InITKey, L"clientguid", 0, NULL, &buffer[0], &cbData);

if (ERROR_MORE_DATA != nError)
break;

// Get a buffer that is big enough if not already
this->m_ServiceLogger->info("Resizing clientguid buffer");

buffer.resize(cbData + sizeof(wchar_t));
}
while (true);

if (ERROR_SUCCESS == nError)
{
std::wstring clientguid = (WCHAR*) &buffer[0];
std::string cg(clientguid.begin(), clientguid.end());

this->m_ClientGuid = cg;
this->m_ServiceLogger->info("Clientguid yo: " + cg);
}
else if (ERROR_ACCESS_DENIED == nError)
{
this->m_ServiceLogger->info("ClientGUID: Access Denied");
}
else
{
std::stringstream errstr;
errstr << nError;
this->m_ServiceLogger->info("Error: " + errstr.str() + " RegQueryValueEx failed");
}

RegCloseKey(InITKey);

if (!this->checkRegistryValues())
{
this->generateRegistry();
}
}

...
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector