2017-09-28 5 views
-1

基本的に私は自分のプログラムアップデートマネージャーとして働くことを意図したサービスを持っています。 。これは、すべてに署名するユーザーを必要としない自動的に更新プログラムを作るための私の努力である別の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サービスです。

以前私は、このアップデートマネージャを持っていなかった、代わりに実際のプログラムのサービスでレジストリの値を設定しました。読書、執筆はうまくいった。しかし、私はUpdate Managerにこれらの初期値を設定させ、メインウィンドウサービスがそれらにアクセスするようにすることにしました。

私がこれをやろうとすると、毎回、KEY_READ ||のようなさまざまな種類のセキュリティトークンを試すにもかかわらず、ERROR_ACCESS_DENIEDエラーが発生しました。 KEY_WOW64_64KEYなどの多くの組み合わせで、キーを開こうとしています。上記のように、私はトークンを設定するときにKEY_ALL_ACCESSを実行しています。私はそれにアクセスできるはずだと思うが、それは私には許されない。私が来ることができる唯一の結論は、何とか私の更新マネージャーがレジストリのキー/値に対する所有権を持っているということです。

何右のコードは、私のメインのWindowsサービスからこれらのレジストリファイルにアクセスするだろうか?

これらのレジストリ値にアクセスするための私の現在のコード(私はアップデートマネージャのインストールに発生clientguidがコード上記参照):

// 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()を呼び出すとき、あなたはビットごとのOR(を使用する必要がありますLOGICAL OR(||)演算子ではなく、|)演算子を使用します。変更:ただし

KEY_READ | KEY_WOW64_64KEY 

、あなたのアップデートマネージャが、それはまったくのアクセス権を指定していない、RegOpenKeyEx()を呼び出したときに、それが0にsamDesiredパラメータを設定していることを設定する必要がありますへ

KEY_READ || KEY_WOW64_64KEY 

代わりに少なくともKEY_SET_VALUEにしてください。 RegOpenKeyEx()が失敗した場合はRegCreateKeyEx()を呼び出し、samDesiredKEY_ALL_ACCESSに設定しています。それをしないでください。実際に必要なアクセス権のみを使用してください(KEY_SET_VALUEなど)。

とにかく、RegOpenKeyEx()RegCreateKeyEx()の両方を呼び出す必要はありません。それだけでRegCreateKeyEx()に電話してください。既存のキーを開き、存在しないキーを作成します。そのdwDisposition出力パラメータは、発生したことを通知します。

このコードには他の誤りもあります。 HKEYRegQueryValueEx()に間違って渡し、エラーコードを正しくチェックしないようにしてください(==比較演算子の代わりに=代入演算子を使用)。そしてメモリリーク。

代わりに、より多くのこのような何かを試してみてください:

アップデートマネージャ:

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

... 
関連する問題