Win32 API provides only 1 function for locking workstation, named LockWorkstation. What does it do and how we can use it?

When a new session is started, smss.exe invokes winlogon.exe. It registers its process id in win32k.sys by calling RegisterLogonProcess. It has this prototype:

function RegisterLogonProcess(dwProcessId : DWORD; fSecure : BOOL) : BOOL; stdcall; external ‘user32.dll’;

Functional code in win32k.sys for RegisterLogonProcess is very simple:

BOOL __stdcall _RegisterLogonProcess(DWORD processId, BOOL fSecure) {
  if ( gpidLogon || !IsPrivileged(&psTcb)) {
    return FALSE;
  }
  else {
    gpidLogon = processId;
    return TRUE;
  }
}

gpidLogon is a global variable in win32k.sys. So, only processes with SE_TCB_NAME can call it and only once per session (each session has its own instance of win32k.sys).

Later, when winlogon.exe continues its initialization, it creates a hidden window with ‘SAS window’ name and registers it handle using this function:

function SetLogonNotifyWindow(Window : HWND) : BOOL; stdcall; external ‘user32.dll’;

Its functional code is very simple again:

BOOL __stdcall NtUserSetLogonNotifyWindow(HWND Window) {
  void * pWND;

  pWND = ValidateHwnd(Window);
  if (pWND)  {
    return _SetLogonNotifyWindow(pWND);
  }
  else {
    return FALSE;
  }
}

BOOL __stdcall _SetLogonNotifyWindow(void * pWnd) {
  if (PsGetCurrentProcessId() == gpidLogon) {
    HMAssignmentLock(&gspwndLogonNotify, pWnd);
    return TRUE;
  }
  else {
    return FALSE;
  }
}

So only a logon process is allowed to set logon notify window. Let’s look what does LockWorkstation does:

BOOL __stdcall _LockWorkStation() {
  PostMessage(gspwndLogonNotify, WM_LOGONNOTIFY, LOCK_WORKSTATION_WPARAM, 0);
  return TRUE;
}

Hmm… maybe there are some more messages we can post?

In next part I’ll show how winlogon.exe registers keyboard shortcuts and how we can use them

Related posts:

  1. Using Windows Server 2008 as a SUPER workstation OS