首先,对“活动用户”的定义是,当前拥有桌面的用户。对于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