从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

原文地址:https://www.cnblogs.com/findumars/p/7296518.html