기본적으로 저는 프로그램 업데이트 관리자의 역할을하는 서비스를 가지고 있습니다. 이것은 사용자가 필요로하지 않는 자동 업데이트 프로그램을 만들어 내 노력에 모두 서명하는 것입니다 다른 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 서비스입니다.
이전에는이 업데이트 관리자가 없었으며 대신 실제 프로그램 서비스의 레지스트리 값을 설정했습니다. 읽기와 쓰기가 잘되었습니다. 그러나 업데이트 관리자가 이러한 초기 값을 설정하고 내 메인 윈도우 서비스에 액세스하려고합니다.
이렇게하려고 할 때마다 KEY_READ와 같은 모든 종류의 보안 토큰을 시도해도 ERROR_ACCESS_DENIED 오류가 발생했습니다. KEY_WOW64_64KEY 및 기타 여러 가지 조합으로 키를 열려고 시도 할 때 위에서 보았 듯이 토큰을 설정할 때 KEY_ALL_ACCESS를 실행하려고합니다. 나는 내가 잘 액세스 할 수 있어야한다고 생각하지만, 그것은 나를 허용하지 않습니다. 내가 올 수있는 유일한 결론은 어떻게 든 내 업데이트 관리자는 레지스트리의 키/값에 대한 소유권을가집니다.
기본 Windows 서비스에서이 레지스트리 파일에 액세스하려면 어떤 코드가 필요합니까?
(I가 업데이트 관리자 의 설치 코드 위의 볼에 생성 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);