2017-09-28 14 views
-1

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

Répondre

1

Lorsque vous appelez RegOpenKeyEx(), vous devez utiliser l'opérateur de bits OR (|) à la place de l'opérateur LOGICAL OR (||). Changement:

KEY_READ || KEY_WOW64_64KEY 

Pour:

KEY_READ | KEY_WOW64_64KEY 

Cependant, lorsque votre gestionnaire de mise à jour appelle RegOpenKeyEx(), il ne spécifie pas les droits d'accès du tout, il est correctement le paramètre samDesired à 0. Il devrait donner au moins KEY_SET_VALUE à la place. Quand il appelle RegCreateKeyEx() si RegOpenKeyEx() échoue, il définit le samDesired à KEY_ALL_ACCESS. Ne fais pas ça. Utilisez uniquement les droits d'accès dont vous avez réellement besoin (KEY_SET_VALUE, etc.). De toute façon, il n'est pas nécessaire d'appeler à la fois RegOpenKeyEx() et RegCreateKeyEx(). Il suffit d'appeler RegCreateKeyEx() par lui-même. Il va ouvrir une clé existante et créer une clé non existante. Son paramètre de sortie dwDisposition vous dira ce qui s'est passé.

Il existe également d'autres erreurs dans ce code. Comme passer le mauvais HKEY à RegQueryValueEx(), et ne pas vérifier le code d'erreur ERROR_ACCESS_DENIED correctement (en utilisant l'opérateur d'affectation = au lieu de l'opérateur de comparaison ==). Et la mémoire fuit.

Essayez quelque chose comme ceci:

Update Manager:

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); 
} 

Service Programme:

... 

// 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(); 
    } 
} 

...