從Windows系統服務獲取活動用戶的注冊表信息(當前活動用戶的sessionId. 當前活動用戶的 hUserToken)


首先,對“活動用戶”的定義是,當前擁有桌面的用戶。對於Windows XP及其以后的系統,即使是可以多個用戶同時登錄了,擁有桌面的也僅僅只有一個。 
如果系統級服務調用Windows API來獲取注冊表鍵值的時候,直接以HKEY_CURRENT_USER為參數,則取到的並不是活動用戶的注冊表信息,而是系統用戶的注冊表信息,即,位於HKEY_LOCAL_MACHINE之下的。那么如何以系統服務的身份獲取活動用戶(真正的HKEY_CURRENT_USER)之下的注冊表信息呢?主要有以下這么幾步:

  1. 系統服務程序調用 WTSGetActiveConsoleSessionId() 以獲取當前活動用戶的sessionId.
  2. 以此sessionId為參數,調用 WTSQueryUserToken() 以獲取當前活動用戶的 hUserToken.
  3. 以此hUserToken為參數,調用 DuplicateTokenEx() 以復制一個token,如hFakeToken.
  4. 以此hFakeToken為參數,調用 ImpersonateLoggedOnUser() 以模擬活動用戶登錄的環境.
  5. 調用 RegOpenCurrentUser() 以打開活動用戶的 HKEY_CURRENT_USER.
  6. 調用 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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM