WTSIsRemoteSession всегда возвращает TRUE - PullRequest
0 голосов
/ 11 июля 2019

В настоящее время я пишу службу Windows, которая также что-то делает, когда пользователь входит в систему.Была идея ничего не делать, если вход в систему происходит с удаленного компьютера (например, с удаленного рабочего стола), и он пытался найти способ решить эту проблему.Но следующее не работает - оно всегда возвращает истину (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 Ответ

4 голосов
/ 11 июля 2019

Согласно документации для WTSIsRemoteSession:

WTSIsRemoteSession

Определяет, является ли текущий сеанс удаленным сеансом.

Функция WTSQuerySessionInformation возвращает значение TRUE, чтобы указать, что текущий сеанс является удаленным сеансом, и FALSE, чтобы указать, что текущий сеанс является локальным сеансом . Это значение может использоваться только для локальной машины, поэтому параметр hServer функции WTSQuerySessionInformation должен содержать WTS_CURRENT_SERVER_HANDLE.

Windows Server 2008 и Windows Vista: это значение не поддерживается.

Это означает, что возвращаемое значение из WTSQuerySessionInformation() содержит искомое значение, и любая память, которую функция может выделить, если таковая имеется, является вторичной и должна игнорироваться при запросе 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 всегда верно в этом случае, то документация вводит в заблуждение, и вам следует вместо этого проверить содержимое буфера 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...
    ...
}

В качестве альтернативы:

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);
    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...