WTSIsRemoteSession 总是返回 TRUE
我目前正在编写一个 Windows 服务,它也会在用户登录时执行一些操作.如果登录来自远程计算机(例如远程桌面),则有一个想法是什么都不做,并试图找到一种方法来破坏它.但是以下不起作用 - 它总是返回true(Windows 10 64位V1809) - 我在这里做错了什么吗?
I'm currently writing a Windows service, which also does something when a user logs on. There was the idea to do nothing if the logon comes from a remote computer (e.g. Remote desktop), and tried to find a way to dermine this. But following does not work - it always returns true (Windows 10 64 bit V1809) - is there something I doing wrong here?
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);
}
...
}
根据 文档 WTSIsRemoteSession
:
WTSIsRemoteSession
WTSIsRemoteSession
确定当前会话是否为远程会话.
Determines whether the current session is a remote session.
WTSQuerySessionInformation
函数返回值 TRUE
表示当前会话是远程会话,FALSE
表示当前会话是本地会话.此值只能用于本地机器,因此WTSQuerySessionInformation
函数的hServer
参数必须包含WTS_CURRENT_SERVER_HANDLE
.
The WTSQuerySessionInformation
function returns a value of TRUE
to indicate that the current session is a remote session, and FALSE
to indicate that the current session is a local session. This value can only be used for the local machine, so the hServer
parameter of the WTSQuerySessionInformation
function must contain WTS_CURRENT_SERVER_HANDLE
.
Windows Server 2008 和 Windows Vista:不支持此值.
Windows Server 2008 and Windows Vista: This value is not supported.
这意味着 WTSQuerySessionInformation()
的返回值保存了您正在寻找的值,并且该函数可能分配的任何内存(如果有)都是次要的,应该查询WTSIsRemoteSession
时被忽略,例如:
This implies that the return value of WTSQuerySessionInformation()
holds the value you are looking for, and whatever memory the function may allocate, if any, is secondary and should be ignored when querying WTSIsRemoteSession
, eg:
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
始终为真,那么文档具有误导性,您应该检查 pSessionInfo 的 contents代码>缓冲区代替.您正在根据
WTSQuerySessionInformation()
是否分配任何内存来设置您的 isRDP
变量,而不是查看数据中的实际内容.
However, if you find that isRDP
is always true in this case, then the documentation is misleading and you should check the contents of the pSessionInfo
buffer instead. You are setting your isRDP
variable based on whether WTSQuerySessionInformation()
allocates any memory at all, you are not looking at what is actually inside the data.
例如,假设 dataLen
在输出时被设置为 sizeof(BOOL)
然后将您的 pSessionInfo
指针转换为 BOOL*
指针并取消引用它,例如:
For instance, assuming dataLen
is being set to sizeof(BOOL)
on output then cast your pSessionInfo
pointer to a BOOL*
pointer and dereference it, eg:
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...
...
}
或者:
VOID SessionChangeHandler(DWORD reason, DWORD sessionId)
{
BOOL *isRDP = nullptr;
DWORD dataLen = 0;
if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, (LPWSTR*)&isRDP, &dataLen))
{
// Do some error handling...
return;
}
// use isRDP as needed...
WTSFreeMemory(isRDP);
...
}