Donc, fondamentalement, j'ai un service qui est censé agir comme mon gestionnaire de mise à jour de programme. Tout cela est dans mes efforts pour faire un programme de mise à jour automatique qui n'a pas besoin que l'utilisateur soit signé enComment lire/modifier les valeurs de registre créées par un autre service Windows?
Donc, mon gestionnaire de mise à jour lorsqu'il est installé crée des valeurs de registre initiales/structures avec le code suivant:.
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);
Lorsqu'il est désinstallé, il supprime les valeurs de registre.
Mon programme actuel est un service Windows qui sera exécuté sur l'ordinateur installé qui doit accéder à certaines de ces valeurs de registre.
Auparavant, je n'avais pas ce gestionnaire de mise à jour, et définissais plutôt les valeurs dans le registre dans le service de programme réel. La lecture et l'écriture fonctionnaient très bien alors. Mais depuis que mon Gestionnaire de mise à jour a défini ces valeurs initiales, mon service Windows principal doit y accéder. Quand j'essaye de faire ceci, j'ai toujours reçu une erreur ERROR_ACCESS_DENIED, malgré avoir essayé toutes sortes de différents jetons de sécurité comme KEY_READ || KEY_WOW64_64KEY et d'autres dans de nombreuses combinaisons lorsque vous essayez d'ouvrir la clé. Comme vous l'avez vu ci-dessus, je suis ou-KEY_ALL_ACCESS lors de la définition du jeton. Je pense que je devrais être en mesure d'y accéder très bien, mais il ne me laisse pas. La seule conclusion à laquelle je parviens est que mon gestionnaire de mise à jour a la propriété des clés/valeurs du registre.
Quel serait le bon code pour accéder à ces fichiers de registre à partir de mon service Windows principal?
Mon code actuel pour accéder à ces valeurs de registre (le clientguid que je produis lors de l'installation du gestionnaire de mise à jour voir ci-dessus le code):
// 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);