detect if windows session is locked

Windows specific forum
yabune
User
User
Posts: 65
Joined: Mon Aug 22, 2005 2:31 pm

detect if windows session is locked

Post by yabune »

Hi,

How can I detect if a windows session is locked?

thanks!
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Re: detect if windows session is locked

Post by SFSxOI »

A widnows session can indeed be detected for lock status. The WTSRegisterSessionNotification() API in wtsapi32.dll can be used. Take a look at http://msdn.microsoft.com/en-us/library/Aa383841 There is even visual basic 8 code which you should be able to convert to PureBasic.

Another more crude way is just for lock status for the desktop which is available via OpenInputDesktop() API in user32.dll, but if memory serves me correctly its very sensitive to account privilages. Basically and real quick from memory for OpenInputDesktop, it looks something like this:

Code: Select all

Procedure MachineLocked()
lockstat.i

Lib_LockStat = LoadLibrary_("user32.dll")
*Func_OpenInputDesktop = GetProcAddress_(Lib_LockStat, "OpenInputDesktop")

hDesktopAccess.i = CallFunctionFast(*Func_OpenInputDesktop, dwFlags, fInherit, dwDesiredAccess, @lockstat)

FreeLibrary_(Lib_LockStat)

If lockstat < 1	
  ProcedureReturn #True
  Else
  ProcedureReturn #False
EndIf

EndProcedure
I've got something for WTSRegisterSessionNotification() too, somewhere and can't find it right now, but it was just the code from the MSDN link above converted anyway and its not hard to convert. Is this what you were lookin for? Hope it helps.
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.
Mr Coder
User
User
Posts: 54
Joined: Tue Apr 13, 2010 8:02 am

Re: detect if windows session is locked

Post by Mr Coder »

I read in another thread that GetForegroundWindow_() returns 0 if the workstation is locked, and yep, works fine here with XP and 7.
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: detect if windows session is locked

Post by Dude »

SFSxOI wrote:real quick from memory for OpenInputDesktop, it looks something like this [snip]
SFSxOI's code crashes on Win 7 (illegal memory access). Anyone know how to fix it, to detect when the PC is locked? Thanks!

Also, why does this code return a different handle to the desktop all the time, when there's only one desktop in use?

Code: Select all

Repeat
  Debug OpenInputDesktop_(0,0,0)
  Sleep_(250)
ForEver
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: detect if windows session is locked

Post by RASHAD »

Hi Dude

Code: Select all

GetDesktopWindow_()                    ;Return Root Desktop(Main Desktop Handle)  
OpenDesktop_(@"Default", 0, #False, 0) ;Return Thread Desktop Handle
threadID = GetCurrentThreadId_()
GetThreadDesktop_(threadID)            ;Return Thread Desktop Handle

Try

Code: Select all

Repeat
  thHwnd = OpenDesktop_(@"Default", 0, #False, #DESKTOP_SWITCHDESKTOP)
  If thHwnd
    SetThreadDesktop_(thHwnd)
    result = SwitchDesktop_(thHwnd)
    If result = 0
      Debug "Locked"
      CloseDesktop_(thHwnd)
    Else
      CloseDesktop_(thHwnd)
      Debug "Not Locked"
    EndIf
    Delay(500)
  EndIf
ForEver
Egypt my love
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: detect if windows session is locked

Post by Dude »

Thank you, Rashad -- works great! 8)

Note: I had to remove SetThreadDesktop_(thHwnd) because it was making OpenWindow() and MessageRequesters() be shown on another (unseen) desktop, because I need to check the lock state every second (for a timer tool).
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: detect if windows session is locked

Post by BarryG »

None of these examples work with Windows 10 anymore. Anyone know how to do with Win 10, but also stay compatible with at least Win 7?

I tried several different methods, and one is that when Win 10 is locked, the foreground window has a caption of "Windows Default Lock Screen", but I doubt that will be the same in all languages, and even if it were, it wouldn't work with Win 7. Kinda stuck at the moment because my app plays reminder sounds but I don't want them played if the PC is locked.

I also read that waiting for #WM_WTSSESSION_CHANGE in a callback would work, but that assumes my app is running. My app can (and will) start sometimes when the PC is already locked, so won't be able to catch this message.

Any ideas? Thanks.
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: detect if windows session is locked

Post by Mijikai »

Try this:

Code: Select all

Macro IsLocked()
  Bool(GetForegroundWindow_() = #Null)
EndMacro
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: detect if windows session is locked

Post by BarryG »

Nope, that doesn't work anymore. It returns 0 even if the PC is locked, because GetForegroundWindow_() no longer returns 0 on Win 10 for a locked PC. As mentioned above, that only worked for Win XP and Win 7.
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: detect if windows session is locked

Post by Mijikai »

Ok here is what i came up with:

Code: Select all

EnableExplicit

Procedure.i IsLocked()
  Protected handle.i
  Protected *ProcessIdToSessionId
  Protected *WTSQuerySessionInformation
  Protected *WTSFreeMemory
  Protected sid.i 
  Protected bytes.i
  handle = LoadLibrary_("Wtsapi32.dll")
  *ProcessIdToSessionId = GetProcAddress_(GetModuleHandle_("kernel32.dll"),?ProcessIdToSessionId)
  *WTSQuerySessionInformation = GetProcAddress_(handle,?WTSQuerySessionInformation)
  *WTSFreeMemory = GetProcAddress_(handle,?WTSFreeMemory)
  If *ProcessIdToSessionId And *WTSQuerySessionInformation And *WTSFreeMemory
    If CallFunctionFast(*ProcessIdToSessionId,GetCurrentProcessId_(),@sid)
      If CallFunctionFast(*WTSQuerySessionInformation,#Null,sid,25,@handle,@bytes)
        bytes = PeekL(handle + $10)
        CallFunctionFast(*WTSFreeMemory,handle)  
        If OSVersion() = #PB_OS_Windows_7 Or OSVersion() = #PB_OS_Windows_Server_2008_R2
          ProcedureReturn bytes
        Else
          ProcedureReturn Bool(bytes = #False)
        EndIf
      EndIf
    EndIf
  Else
    handle = OpenDesktop_("Default",#Null,#False,#DESKTOP_SWITCHDESKTOP)
    If handle
      bytes = SwitchDesktop_(handle)
      CloseDesktop_(handle)
      ProcedureReturn Bool(bytes = #Null)
    EndIf
  EndIf
  ProcedureReturn #False
  ProcessIdToSessionId:
  !db 'ProcessIdToSessionId',0x0
  WTSQuerySessionInformation:
  !db 'WTSQuerySessionInformationW',0x0
  WTSFreeMemory:
  !db 'WTSFreeMemory',0x0
EndProcedure

Debug IsLocked()

End
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: detect if windows session is locked

Post by BarryG »

Mijikai, that works perfect on Win 10, but not on Win XP. I don't have Win 7 to test it on - can someone here with 7 and/or Vista try it?

For now, I will use Mijikai's code for Win 10 and later, and Rashad's code for anything up to but not including Win 10. Thanks, Mijikai.

[Edit] Doesn't work with the new C backend. Bug report here -> viewtopic.php?f=43&t=78145
juergenkulow
Enthusiast
Enthusiast
Posts: 544
Joined: Wed Sep 25, 2019 10:18 am

Re: detect if windows session is locked

Post by juergenkulow »

Hello Mijikai,
can you test this code, I am not sure.

Code: Select all

CompilerIf Defined(PB_Compiler_Backend,#PB_Constant) 
  CompilerIf #PB_Compiler_Backend=#PB_Backend_C
  DataSection
    ProcessIdToSessionId:
    Data.b 0
    WTSQuerySessionInformation:
    Data.b 0
    WTSFreeMemory:
    Data.b 0
  EndDataSection
  CompilerEndIf 
CompilerEndIf
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: detect if windows session is locked

Post by infratec »

I think this is the way to go;

Code: Select all

DataSection
  ProcessIdToSessionId:
  Data.a 'P','r','o','c','e','s','s','I','d','T','o','S','e','s','s','i','o','n','I','d',0
  WTSQuerySessionInformation:
  Data.a  'W','T','S','Q','u','e','r','y','S','e','s','s','i','o','n','I','n','f','o','r','m','a','t','i','o','n','W',0
  WTSFreeMemory:
  Data.a 'W','T','S','F','r','e','e','M','e','m','o','r','y',0
EndDataSection
It should work with all compilers :wink:
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: detect if windows session is locked

Post by BarryG »

Thanks infratec! Using Data with broken-up text into characters has freed me of using ASM for this procedure! :) Don't know why I missed your reply several years ago.
Post Reply