首先,對“活動用戶”的定義是,當前擁有桌面的用戶。對於Windows XP及其以后的系統,即使是可以多個用戶同時登錄了,擁有桌面的也僅僅只有一個。
如果系統級服務調用Windows API來獲取注冊表鍵值的時候,直接以HKEY_CURRENT_USER為參數,則取到的並不是活動用戶的注冊表信息,而是系統用戶的注冊表信息,即,位於HKEY_LOCAL_MACHINE之下的。那么如何以系統服務的身份獲取活動用戶(真正的HKEY_CURRENT_USER)之下的注冊表信息呢?主要有以下這么幾步:
- 系統服務程序調用 WTSGetActiveConsoleSessionId() 以獲取當前活動用戶的sessionId.
- 以此sessionId為參數,調用 WTSQueryUserToken() 以獲取當前活動用戶的 hUserToken.
- 以此hUserToken為參數,調用 DuplicateTokenEx() 以復制一個token,如hFakeToken.
- 以此hFakeToken為參數,調用 ImpersonateLoggedOnUser() 以模擬活動用戶登錄的環境.
- 調用 RegOpenCurrentUser() 以打開活動用戶的 HKEY_CURRENT_USER.
- 調用 RegOpenKeyEx() 以獲取指定位置的注冊表鍵值.
以QT和Windows API來實現的代碼如下:
void GetUserRegistryFromSystemService() { #ifdef Q_OS_WIN DWORD sessionId = WTSGetActiveConsoleSessionId(); qInfo() << "Session ID = " << sessionId; wchar_t * ppUserName[100]; DWORD sizeOfUserName; WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSUserName, ppUserName, &sizeOfUserName); qInfo() << "Windows User Name = " << QString::fromWCharArray(*ppUserName); std::wstring strValueOfBinDir = L"Unknown Value"; LONG regOpenResult = ERROR_SUCCESS; HANDLE hUserToken = NULL; HANDLE hFakeToken = NULL; if (WTSQueryUserToken(sessionId, &hUserToken)) { if (DuplicateTokenEx(hUserToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, &hFakeToken) == TRUE) { if (ImpersonateLoggedOnUser(hFakeToken)) { HKEY hKey; regOpenResult = RegOpenCurrentUser(KEY_READ, &hKey); if (regOpenResult != ERROR_SUCCESS) { qCritical() << "Failed to call RegOpenCurrentUser(), Error is " << regOpenResult; } HKEY hSubKey; RegOpenKeyEx(hKey, TEXT("Software\\Baidu\\BaiduYunGuanjia"), 0, KEY_READ, &hSubKey); GetStringRegKey(hSubKey, TEXT("installDir"), strValueOfBinDir, TEXT("Unknown")); RevertToSelf(); } else { qCritical() << "Failed to ImpersonateLoggedOnUser..."; } CloseHandle(hFakeToken); } else { qCritical() << "Failed to call DuplicateTokenEx..."; } CloseHandle(hUserToken); } else { qCritical() << "Failed to get the user token of session " << sessionId; } qInfo() << "The value of Registry is " << QString::fromWCharArray( strValueOfBinDir.c_str() ); #endif }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
最后,取注冊表信息一些方法:
HKEY hKey;
LONG lRes = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Perl", 0, KEY_READ, &hKey); bool bExistsAndSuccess (lRes == ERROR_SUCCESS); bool bDoesNotExistsSpecifically (lRes == ERROR_FILE_NOT_FOUND); std::wstring strValueOfBinDir; std::wstring strKeyDefaultValue; GetStringRegKey(hKey, L"BinDir", strValueOfBinDir, L"bad"); GetStringRegKey(hKey, L"", strKeyDefaultValue, L"bad"); LONG GetStringRegKey(HKEY hKey, const std::wstring &strValueName, std::wstring &strValue, const std::wstring &strDefaultValue) { strValue = strDefaultValue; WCHAR szBuffer[512]; DWORD dwBufferSize = sizeof(szBuffer); ULONG nError; nError = RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, (LPBYTE)szBuffer, &dwBufferSize); if (ERROR_SUCCESS == nError) { strValue = szBuffer; } return nError; } LONG GetDWORDRegKey(HKEY hKey, const std::wstring &strValueName, DWORD &nValue, DWORD nDefaultValue) { nValue = nDefaultValue; DWORD dwBufferSize(sizeof(DWORD)); DWORD nResult(0); LONG nError = ::RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, reinterpret_cast<LPBYTE>(&nResult), &dwBufferSize); if (ERROR_SUCCESS == nError) { nValue = nResult; } return nError; } LONG GetBoolRegKey(HKEY hKey, const std::wstring &strValueName, bool &bValue, bool bDefaultValue) { DWORD nDefValue((bDefaultValue) ? 1 : 0); DWORD nResult(nDefValue); LONG nError = GetDWORDRegKey(hKey, strValueName.c_str(), nResult, nDefValue); if (ERROR_SUCCESS == nError) { bValue = (nResult != 0) ? true : false; } return nError; }
http://blog.csdn.net/nirendao/article/details/52077637