首页 > 代码库 > 从Windows系统服务获取活动用户的注册表信息(当前活动用户的sessionId. 当前活动用户的 hUserToken)

从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 = http://www.mamicode.com/strDefaultValue;"hljs-number">512];    DWORD dwBufferSize = sizeof(szBuffer);    ULONG nError;    nError = RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, (LPBYTE)szBuffer, &dwBufferSize);    if (ERROR_SUCCESS == nError)    {        strValue = http://www.mamicode.com/szBuffer;"hljs-keyword">return nError;}LONG GetDWORDRegKey(HKEY hKey, const std::wstring &strValueName, DWORD &nValue, DWORD nDefaultValue){    nValue = http://www.mamicode.com/nDefaultValue;"hljs-keyword">sizeof(DWORD));    DWORD nResult(0);    LONG nError = ::RegQueryValueExW(hKey,        strValueName.c_str(),        0,        NULL,        reinterpret_cast<LPBYTE>(&nResult),        &dwBufferSize);    if (ERROR_SUCCESS == nError)    {        nValue = http://www.mamicode.com/nResult;"hljs-keyword">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 = http://www.mamicode.com/(nResult != 0) ? true : false;    }    return nError;}

 

http://blog.csdn.net/nirendao/article/details/52077637

 

从Windows系统服务获取活动用户的注册表信息(当前活动用户的sessionId. 当前活动用户的 hUserToken)