zoukankan      html  css  js  c++  java
  • 从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

  • 相关阅读:
    Jquery 复习练习(01)
    web前段 弹出小例子
    MacBook 显示隐藏文件夹命令
    sqlserver 纵横
    C#获取当前页面的url
    C# Json 转对象
    jquery导航栏
    AJAX
    hao dongxi
    微信网页获取openId
  • 原文地址:https://www.cnblogs.com/findumars/p/7296518.html
Copyright © 2011-2022 走看看