WTSIsRemoteSession始终返回TRUE

时间:2019-07-11 13:52:33

标签: windows winapi service

我当前正在编写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);
    }

    ...

}

1 个答案:

答案 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...
    ...
}