我当前正在编写Windows服务,当用户登录时该服务也会执行某些操作。如果登录来自远程计算机(例如,远程桌面),并且试图找到一种方法可以阻止这种情况,那么就有想法什么也不做。但是,以下操作不起作用-它总是返回true(Windows 10 64位V1809)-我在这里做错了什么吗?
DWORD SvcHandlerEx(DWORD controlCode, DWORD eventType, ... )
{
...
switch(controlCode)
{
case SERVICE_CONTROL_SESSIONCHANGE:
{
WTSSESSION_NOTIFICATION *pSessInfo = (WTSSESSION_NOTIFICATION *)pEvtData;
// invoke SessionChangeHandler(eventId, pSessInfo->dwSessionId)
}
...
}
...
}
...
VOID SessionChangeHandler(DWORD reason, DWORD sessionId)
{
LPWSTR *pSessionInfo = nullptr;
DWORD dataLen = 0;
BOOL isRDP = false;
if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId,
WTSIsRemoteSession, &pSessionInfo, &dataLen))
{
// Do some error handling...
return;
}
if (dataLen)
{
if (dataLen)
{
isRDP = (bool)pSessionInfo; // Always 1 (TRUE) !!!
}
WTSFreeMemory(pSessionInfo);
}
...
}
答案 0 :(得分:4)
根据WTSIsRemoteSession
的{{3}}:
WTSIsRemoteSession
确定当前会话是否为远程会话。
WTSQuerySessionInformation
函数返回值TRUE
表示当前会话是远程会话,而FALSE
返回值表示当前会话是本地会话< / strong>。此值只能用于本地计算机,因此hServer
函数的WTSQuerySessionInformation
参数必须包含WTS_CURRENT_SERVER_HANDLE
。Windows Server 2008和Windows Vista:不支持此值。
这意味着WTSQuerySessionInformation()
的返回值保留了您要查找的值,并且该函数可能分配的任何内存(如果有的话)都是次要的,并且在查询{ {1}},例如:
WTSIsRemoteSession
但是,如果您发现VOID SessionChangeHandler(DWORD reason, DWORD sessionId)
{
LPWSTR *pSessionInfo = nullptr;
DWORD dataLen = 0;
bool isRDP = WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, &pSessionInfo, &dataLen);
if ((!isRDP) && (GetLastError() != 0))
{
// Do some error handling...
return;
}
if (pSessionInfo)
WTSFreeMemory(pSessionInfo);
// use isRDP as needed...
...
}
在这种情况下总是正确的,则说明文档具有误导性,您应该检查isRDP
缓冲区的 contents 。您要根据pSessionInfo
是否分配任何内存来设置isRDP
变量,而不是查看数据内部的实际内容。
例如,假设在输出中将WTSQuerySessionInformation()
设置为dataLen
,然后将sizeof(BOOL)
指针强制转换为pSessionInfo
指针并取消引用,例如:
BOOL*
或者:
VOID SessionChangeHandler(DWORD reason, DWORD sessionId)
{
LPWSTR *pSessionInfo = nullptr;
DWORD dataLen = 0;
if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, &pSessionInfo, &dataLen))
{
// Do some error handling...
return;
}
bool isRDP = * (BOOL*) pSessionInfo;
WTSFreeMemory(pSessionInfo);
// use isRDP as needed...
...
}