Wil*_* K. 1 windows service winapi
我目前正在编写一个 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);
}
...
}
Run Code Online (Sandbox Code Playgroud)
根据文档WTSIsRemoteSession:
\n\nWTSI远程会话
\n确定当前会话是否为远程会话。
\n该
\nWTSQuerySessionInformation函数返回值\xc2\xa0TRUE\xc2\xa0表示当前会话是远程会话,\xc2\xa0FALSE\xc2\xa0表示当前会话是本地会话。该值只能用于本地机器,因此函数hServer的\xc2\xa0参数WTSQuerySessionInformation必须包含WTS_CURRENT_SERVER_HANDLE.Windows Server\xc2\xa02008 和 Windows\xc2\xa0Vista:\xc2\xa0\xc2\xa0 不支持此值。
\n
这意味着 的返回值保存WTSQuerySessionInformation()您正在查找的值,并且该函数可能分配的任何内存(如果有)都是次要的,在查询时应该被忽略WTSIsRemoteSession,例如:
VOID SessionChangeHandler(DWORD reason, DWORD sessionId)\n{\n LPWSTR *pSessionInfo = nullptr;\n DWORD dataLen = 0;\n\n bool isRDP = WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, &pSessionInfo, &dataLen);\n if ((!isRDP) && (GetLastError() != 0))\n {\n // Do some error handling...\n return;\n }\n\n if (pSessionInfo)\n WTSFreeMemory(pSessionInfo);\n\n // use isRDP as needed...\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\n但是,如果您发现isRDP在这种情况下总是如此,则说明文档具有误导性,您应该检查缓冲区的内容pSessionInfo。isRDP您正在根据是否设置变量WTSQuerySessionInformation()变量,而不是查看数据中实际包含的内容。
例如,假设dataLen被设置为sizeof(BOOL)输出,然后将pSessionInfo指针转换为BOOL*指针并取消引用它,例如:
VOID SessionChangeHandler(DWORD reason, DWORD sessionId)\n{\n LPWSTR *pSessionInfo = nullptr;\n DWORD dataLen = 0;\n\n if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, &pSessionInfo, &dataLen))\n {\n // Do some error handling...\n return;\n }\n\n bool isRDP = * (BOOL*) pSessionInfo;\n WTSFreeMemory(pSessionInfo);\n\n // use isRDP as needed...\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\n或者:
\nVOID SessionChangeHandler(DWORD reason, DWORD sessionId)\n{\n BOOL *isRDP = nullptr;\n DWORD dataLen = 0;\n\n if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, (LPWSTR*)&isRDP, &dataLen))\n {\n // Do some error handling...\n return;\n }\n\n // use *isRDP as needed...\n\n WTSFreeMemory(isRDP);\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\n更新:
\n另一方面,如果dataLen将其设置为sizeof(UCHAR)输出,则将pSessionInfo指针转换为UCHAR*指针并取消引用它,例如:
VOID SessionChangeHandler(DWORD reason, DWORD sessionId)\n{\n LPWSTR *pSessionInfo = nullptr;\n DWORD dataLen = 0;\n\n if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, &pSessionInfo, &dataLen))\n {\n // Do some error handling...\n return;\n }\n\n bool isRDP = * (UCHAR*) pSessionInfo;\n WTSFreeMemory(pSessionInfo);\n\n // use isRDP as needed...\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\n或者:
\nVOID SessionChangeHandler(DWORD reason, DWORD sessionId)\n{\n UCHAR *isRDP = nullptr;\n DWORD dataLen = 0;\n\n if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, (LPWSTR*)&isRDP, &dataLen))\n {\n // Do some error handling...\n return;\n }\n\n // use *isRDP as needed...\n\n WTSFreeMemory(isRDP);\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
874 次 |
| 最近记录: |