C++: check if computer is locked

2019-02-23 21:58发布

I'm trying to figure out whether the computer is locked.

I've looked at LockWorkStation function, but the function that I'm hoping to find is IsWorkStationLocked.


I need to support all windows version >= XP

3条回答
Root(大扎)
2楼-- · 2019-02-23 22:21

Alex Vershynin's version works well, with a few code changes that I had to make.

I had to: change DW_WTSSessionInfoEx to WTSSessionInfoEx (Answering user586399), define "g_dwSessionID" to WTSGetActiveConsoleSessionId(), include Wtsapi32.h. I think that's it ...

Since I can't comment, I'll paste the whole code here.

#include "Wtsapi32.h"
bool IsSessionLocked()
{
    typedef BOOL( PASCAL * WTSQuerySessionInformation )( HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPTSTR* ppBuffer, DWORD* pBytesReturned );
    typedef void ( PASCAL * WTSFreeMemory )( PVOID pMemory );

    WTSINFOEXW * pInfo = NULL;
    WTS_INFO_CLASS wtsic = WTSSessionInfoEx;
    bool bRet = false;
    LPTSTR ppBuffer = NULL;
    DWORD dwBytesReturned = 0;
    LONG dwFlags = 0;
    WTSQuerySessionInformation pWTSQuerySessionInformation = NULL;
    WTSFreeMemory pWTSFreeMemory = NULL;

    HMODULE hLib = LoadLibrary( "wtsapi32.dll" );
    if( !hLib )
    {
        return false;
    }
    pWTSQuerySessionInformation = (WTSQuerySessionInformation) GetProcAddress( hLib, "WTSQuerySessionInformationW" );
    if( pWTSQuerySessionInformation )
    {
        pWTSFreeMemory = (WTSFreeMemory) GetProcAddress( hLib, "WTSFreeMemory" );
        if( pWTSFreeMemory != NULL )
        {
            DWORD dwSessionID = WTSGetActiveConsoleSessionId();
            if( pWTSQuerySessionInformation( WTS_CURRENT_SERVER_HANDLE, dwSessionID, wtsic, &ppBuffer, &dwBytesReturned ) )
            {
                if( dwBytesReturned > 0 )
                {
                    pInfo = (WTSINFOEXW*) ppBuffer;
                    if( pInfo->Level == 1 )
                    {
                        dwFlags = pInfo->Data.WTSInfoExLevel1.SessionFlags;
                    }
                    if( dwFlags == WTS_SESSIONSTATE_LOCK )
                    {
                        bRet = true;
                    }
                }
                pWTSFreeMemory( ppBuffer );
                ppBuffer = NULL;
            }
        }
    }
    if( hLib != NULL )
    {
        FreeLibrary( hLib );
    }
    return bRet;
}
查看更多
地球回转人心会变
3楼-- · 2019-02-23 22:27

For windows 7 and abowe WTS API can be used:

bool IsSessionLocked() {
    typedef BOOL (PASCAL * WTSQuerySessionInformation)(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPTSTR* ppBuffer, DWORD* pBytesReturned);
    typedef void (PASCAL * WTSFreeMemory)( PVOID pMemory);

    WTSINFOEXW * pInfo = NULL;
    WTS_INFO_CLASS wtsic = DW_WTSSessionInfoEx;
    bool bRet = false;
    LPTSTR ppBuffer = NULL;
    DWORD dwBytesReturned = 0;
    LONG dwFlags = 0;
    WTSQuerySessionInformation pWTSQuerySessionInformation = NULL;
    WTSFreeMemory pWTSFreeMemory = NULL;

    HMODULE hLib = LoadLibrary( _T("wtsapi32.dll") );
    if (!hLib) {
        return false;
    }
    pWTSQuerySessionInformation = (WTSQuerySessionInformation)GetProcAddress(hLib, "WTSQuerySessionInformationW" );
    if (!pWTSQuerySessionInformation) {
        goto EXIT;
    }

    pWTSFreeMemory = (WTSFreeMemory)GetProcAddress(hLib, "WTSFreeMemory" );
    if (pWTSFreeMemory == NULL) {
        goto EXIT;
    }

    if(pWTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, g_dwSessionID, wtsic, &ppBuffer, &dwBytesReturned)) {
        if(dwBytesReturned > 0) {
            pInfo =  (WTSINFOEXW*)ppBuffer; 
            if (pInfo->Level == 1) {
                dwFlags = pInfo->Data.WTSInfoExLevel1.SessionFlags;
            }
            if (dwFlags == WTS_SESSIONSTATE_LOCK) {
                bRet = true;
            }
        }
        pWTSFreeMemory(ppBuffer);
        ppBuffer = NULL;
    }
EXIT:
    if (hLib != NULL) {
        FreeLibrary(hLib);
    }
    return bRet;
}

Please check following article for supported platforms for WTSINFOEX structure: https://technet.microsoft.com/ru-ru/sysinternals/ee621017

查看更多
Anthone
4楼-- · 2019-02-23 22:43

From the same MSDN link you gave, the third paragraph of "Remarks" says:

This function has the same result as pressing Ctrl+Alt+Del and clicking Lock Workstation. To unlock the workstation, the user must log in. There is no function you can call to determine whether the workstation is locked. To receive notification when the user logs in, use the WTSRegisterSessionNotification function to receive WM_WTSSESSION_CHANGE messages. You can use session notifications to track the desktop state so you know whether it is possible to interact with the user.

查看更多
登录 后发表回答