我有這個問題發生過一次,我仍然不知道如何解決它。我有一個Windows服務,當服務運行時,它首先需要模擬登錄用戶(活動用戶)加載保存在用戶應用程序數據文件夾中的一些路徑和設置。我使用的代碼在每次有新用戶登錄到Windows時都能很好地工作,除非服務得到錯誤模擬的地方,並且模擬了系統會話而不是實際的會話。正如我所說,這隻發生過一次,但我無法真正說出原因。WTSGetActiveConsoleSessionId返回系統會話
這是怎麼了檢查什麼活動會話並冒充是如何完成的:
首先在服務調用
WTSGetActiveConsoleSessionId();
然後檢查檢測登錄事件是查詢的活動會話ID如果會話是活動的,通過調用WTSQuerySessionInformation(連接的),如下所示:
WTS_CONNECTSTATE_CLASS wts_connect_state = WTSDisconnected;
WTS_CONNECTSTATE_CLASS* ptr_wts_connect_state = NULL;
DWORD bytes_returned = 0;
if (::WTSQuerySessionInformation(
WTS_CURRENT_SERVER_HANDLE,
session_id,
WTSConnectState,
reinterpret_cast<LPTSTR*>(&ptr_wts_connect_state),
&bytes_returned))
{
ASSERT(bytes_returned == sizeof(*ptr_wts_connect_state));
wts_connect_state = *ptr_wts_connect_state;
::WTSFreeMemory(ptr_wts_connect_state);
return (WTSActive == wts_connect_state);
}
其中SESSION_ID是會話ID由WTSG返回etActiveConsoleSessionId()。
然後我查詢使用用戶令牌WTSQueryUserToken
那麼如果成功的服務調用GetTokenInformation
如下:
DWORD neededSize = 0;
HANDLE *realToken = new HANDLE;
if(GetTokenInformation(hImpersonationToken, (::TOKEN_INFORMATION_CLASS) TokenLinkedToken, realToken, sizeof(HANDLE), &neededSize))
{
CloseHandle(hImpersonationToken);
hImpersonationToken = *realToken;
}
其中hImpersonationToken是GetTokenInformation
如果所有檢索到的令牌上面的成功就叫
DuplicateTokenEx(hImpersonationToken,
0,
NULL,
SecurityImpersonation,
TokenPrimary,
phUserToken);
CloseHandle(hImpersonationToken);
,如果它成功,那麼它與檢索到的令牌
ImpersonateLoggedOnUser(phUserToken);
我的服務模擬寫入日誌文件,並根據記錄所有以前調用在成功的情況又冒充服後加載的系統配置文件,而不是的用戶。
現在這個問題發生了一次,當我重新啓動我的機器,但我甚至不再重現它,我一直在努力數週。
我不確定系統配置文件會話如何成爲活動會話。我只是想知道如果我在那裏做錯了什麼,不知道我在查詢會話信息時是否使用了錯誤的信息類。
還想知道是否有可能確定查詢的會話是否實際上是系統會話之前模擬與返回的令牌纔可以再次重試模擬?
正如我所說的,所有提到的調用都有他們的返回對象和代碼在移動到下一步之前被檢查,所以他們沒有來自調用的任何錯誤,因爲它不應該繼續模擬,但它做到了:(
希望得到任何幫助可能...謝謝。