Link to home
Start Free TrialLog in
Avatar of moczar
moczar

asked on

keybd_event() in interactive service...

I'm developing a very special purpose service for NT4.0. In some situations the service would synthesize mouse and keyboard actions. I use mouse_event() and keybd_event() functions, which work fine if a user has already logged in the system.
The problem is, that the keybd_event() does not work if noone has logged in yet. I would like the service to synthesize the Ctrl+alt+delete key combination in the 'Begin Logon' window, and produce keystrokes in the 'Logon Information' window too. (The mouse_event() works.)
Is there a solution to get the keybd_event work in that state of the system?
Avatar of MichaelS
MichaelS

Ctrl+alt+delete is not possible.
Try to read about GINA. May be writing of your own gina is a way for you or using autologon or ...
.. keyboard driver
Avatar of jkr
moczar :
Investigate API SendInput()
to saurabh_dasgupta,

SendInput() is just a "new version" of keybd_event. It works only at

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 98.

and doesn't helps here.
Have a look at http://skyscraper.fortunecity.com/gigo/311/winprog.html#lockws

Also, you can try to attach your thread to Winlogon desktop and then try to use keybd_event().
Avatar of moczar

ASKER

To NickRepin,

Thank you for your comment.
After I had attached my tread to Winlogon desktop the keybd_event() worked.
I have visited your web site and tried your programs that also worked well.
However I have further problems with ctrl+alt+del. I tried to use the 0x659 message in my service. The problem is, if the system is in 'logged out' state, there is no 'Winlogon generic control dialog' window on the 'Winlogon' desktop. There are 'Begin Logon', 'SAS window' and '' windows. I tried to send the 0x659 message to the 'Begin Logon' window, but it made the system shut down and the 'Shutdown Computer' window appeared.
Could you give any description of this 0x659 message and the parameters, please?
It is still confusing for me what window would be the target of this message. If the system is in 'logged on' state, the 'Winlogon generic control dialog' is OK. But, if the system is in 'locked workstation' state, there is a dialog displaying 'Press Ctrl+alt+del'. In this case I had to send this message to this dialog. Can we determine what window should be the target?
Thanks.
I discovered 0x659  messages when I answered a question about the locking of a window station. Quite possible, that it doesn't work when there is no logged on user.

You said that keybd_event() works. So what's a problem? Can you emulate C-A-D with keyb_event?

If not, then may be I'll try to find a solution in a few days.
ASKER CERTIFIED SOLUTION
Avatar of NickRepin
NickRepin

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Note: you must be logged off, so you see "Press Ctrl-Alt-Del", then you run my code above from the console, and User/Password dialog appears.

Also you can try to send WM_HOTKEY to "SAS Window".
This code is more "generic" and emulates C-A-D equally fine, regardless of the presence of a logged on user, so it's better to use this:

HWND w=FindWindow("SAS window class","SAS window");
SendMessage(w,WM_HOTKEY,0,MAKELPARAM(MOD_ALT|MOD_CONTROL,VK_DELETE));


Here is a slightly modified LOCKWS.CPP from the "Locking a window station" example which emulates C-A-D if you run LOCK.EXE:

// lockws.cpp

#define STRICT
#include <windows.h>
#include <fstream.h>

HINSTANCE   hDll;
CHAR        libName[MAX_PATH];
HDESK       hWinlogon;
HANDLE      hThread=0;
DWORD       dwThreadId;
HWND        hGeneric,hDialog;
PSECURITY_DESCRIPTOR psd;

// Log files
//ofstream o("C:\\out");
//ofstream o2("C:\\out2");

DWORD WINAPI threadProc(LPVOID);

//---------------------------------------------------------------------------
//
// Finds Winlogon generic control dialog
//
BOOL CALLBACK findGeneric(HWND hwnd,LPARAM)
{
   CHAR text[1024];
   GetWindowText(hwnd,text,sizeof(text));
   if(!strcmp(text,"Winlogon generic control dialog")) {
      hGeneric=hwnd;
      return FALSE;
   }
   return TRUE;
}
//---------------------------------------------------------------------------
//
// Finds Windows NT security dialog
//
BOOL CALLBACK findDialog(HWND hwnd,LPARAM)
{
   CHAR text[1024];
   GetWindowText(hwnd,text,sizeof(text));
   //o2<<text<<' '<<hwnd<<endl;
   if(!strcmp(text,"Windows NT Security")) {
      hDialog=hwnd;
      return FALSE;
   }
   return TRUE;
}
//---------------------------------------------------------------------------
BOOL WINAPI DllEntryPoint(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID)
{
   if(fdwReason==DLL_PROCESS_ATTACH) {
      //MessageBeep(-1);
      hDll=hinstDLL;
      GetModuleFileName(hDll,libName,sizeof(libName));

      hWinlogon=OpenDesktop("Winlogon",0,FALSE,
         //DESKTOP_CREATEMENU  |
         //DESKTOP_CREATEWINDOW |
         DESKTOP_ENUMERATE |
         //DESKTOP_HOOKCONTROL |
         //DESKTOP_JOURNALPLAYBACK |
         //DESKTOP_JOURNALRECORD |
         DESKTOP_READOBJECTS
         //DESKTOP_SWITCHDESKTOP |
         //DESKTOP_WRITEOBJECTS
      );
      //o<<"hWinlogon="<<hWinlogon<<endl;

      hThread=CreateThread(0,0,threadProc,0,0,&dwThreadId);
      //o<<"hThread="<<hThread<<endl;

      //if(hThread) {
         // Make sure we are remain after NINJLIB.EXE
         //LoadLibrary(libName);
      //}
   }
   else if(fdwReason==DLL_PROCESS_DETACH) {
      //MessageBeep(-1);
      if(hThread) {
         TerminateThread(hThread,0);
         CloseHandle(hThread);
      }
      CloseDesktop(hWinlogon);
   }

   return TRUE;
}
//---------------------------------------------------------------------------
DWORD WINAPI threadProc(LPVOID)
{
   psd=(PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
      SECURITY_DESCRIPTOR_MIN_LENGTH);
   InitializeSecurityDescriptor(psd,SECURITY_DESCRIPTOR_REVISION);
   SetSecurityDescriptorDacl(psd,TRUE,0,FALSE);
   SECURITY_ATTRIBUTES sa={
      sizeof(SECURITY_ATTRIBUTES),
      psd,
      FALSE
   };

   HANDLE hEvent=CreateEvent(&sa,FALSE,FALSE,"Nick Lock Station");
   //o2<<"hEvent="<<hEvent<<endl;
   if(hEvent) {
      while(1) {
         //MessageBeep(-1);
         DWORD r=WaitForSingleObject(hEvent,INFINITE);
         if(r==WAIT_OBJECT_0) {
            HWND w=FindWindow("SAS window class","SAS window");
            SendMessage(w,WM_HOTKEY,0,MAKELPARAM(MOD_ALT|MOD_CONTROL,VK_DELETE));
         }
      }
   }
   return 0;
}

Avatar of moczar

ASKER

Thank you very much, your answer is excellent!
moczar
Avatar of moczar

ASKER

To NickRepin,
I'm just realizing, that my previously offered 500 points changed to 50. I don't understand it, since I did not change my offer.
If you have any disadvantage because of this, please inform!
moczar
Thank you.
I received 500*A=500*4=2000 points.
Now your answered question costs 50 points (500/10) so that somebody else can buy it.
I mean, other user can purchase this answer for 50 points, and these points will be deducted from the user's account, but will not be added to my one.