2017-09-28 2 views
-1

Also im Grunde habe ich einen Dienst, der als mein Programm Update Manager fungieren soll. Das ist alles in meine Bemühungen um eine automatische Aktualisierung Programm zu machen, die den Benutzer nicht sein müssen angemeldetWie lese/ändere ich die Registrierungswerte, die ein anderer Windows-Dienst erstellt hat?

Also, wenn meine Update-Manager erstellt einige anfängliche Registrierungswerte/Strukturen mit dem folgenden Code installiert.

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

Wenn es deinstalliert wird, löscht es dann die Registrierungswerte. Mein aktuelles Programm ist ein Windows-Dienst, der auf dem installierten Computer ausgeführt wird, der auf einige dieser Registrierungswerte zugreifen muss.

Zuvor hatte ich diesen Update-Manager nicht und legte stattdessen die Werte in der Registrierung im eigentlichen Programmdienst fest. Lesen und Schreiben funktionierte dann gut. Aber seit ich meinen Update-Manager dazu gebracht habe, diese Anfangswerte festzulegen, beabsichtige ich, dass mein Haupt-Windows-Dienst auf sie zugreift.

Wenn ich dies versuche, habe ich jedes Mal einen ERROR_ACCESS_DENIED-Fehler erhalten, obwohl ich verschiedene Arten von Sicherheitstoken wie KEY_READ || versucht habe KEY_WOW64_64KEY und andere in vielen Kombinationen beim Versuch, den Schlüssel zu öffnen. Wie Sie oben gesehen haben, ordere ich KEY_ALL_ACCESS, wenn ich das Token setze. Ich würde denken, dass ich in der Lage sein sollte, in Ordnung zu gehen, aber es lässt mich nicht. Die einzige Schlussfolgerung, zu der ich kommen kann, ist, dass mein Update-Manager irgendwie Eigentümer der Schlüssel/Werte in der Registrierung ist.

Was wäre der richtige Code für den Zugriff auf diese Registrierungsdateien von meinem Hauptfenster Service?

Meine aktuellen Code für diese Registrierungswerte zugreift (die clientguid, die ich auf der Update Manager installieren erzeugen siehe oben 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); 

Antwort

1

Wenn RegOpenKeyEx() Aufruf, müssen Sie das bitweise verwenden OR (|) Operator anstelle des Operators LOGICAL OR (||). Wechsel:

KEY_READ || KEY_WOW64_64KEY 

An:

KEY_READ | KEY_WOW64_64KEY 

Wenn jedoch Ihre Update Manager RegOpenKeyEx() aufrufen, wird es keine Zugriffsrechte auf alle spezifiziert, wird die Einstellung der samDesired Parameter auf 0 sollte es seine Einstellung es zu mindestens KEY_SET_VALUE stattdessen. Wenn RegCreateKeyEx() aufgerufen wird, wenn RegOpenKeyEx() fehlschlägt, wird samDesired auf KEY_ALL_ACCESS gesetzt. Tu das nicht. Verwenden Sie nur die Zugriffsrechte, die Sie tatsächlich benötigen (KEY_SET_VALUE, usw.).

In jedem Fall müssen weder RegOpenKeyEx() noch RegCreateKeyEx() aufgerufen werden. Rufen Sie einfach RegCreateKeyEx() an. Es wird einen vorhandenen Schlüssel öffnen und einen nicht vorhandenen Schlüssel erstellen. Sein dwDisposition Ausgabeparameter wird Ihnen sagen, was passiert ist.

Es gibt auch andere Fehler in diesem Code. Wenn Sie den Fehlercode HKEY an RegQueryValueEx() übergeben und den Fehlercode ERROR_ACCESS_DENIED nicht korrekt überprüfen (verwenden Sie den = Zuweisungsoperator anstelle des Vergleichsoperators ==). Und Speicherlecks.

etwas mehr wie das Versuchen Sie stattdessen:

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

Program Service:

... 

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

... 
Verwandte Themen