Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

HELP: How to Emulate Keyboard Input

158 views
Skip to first unread message

Scott Leonard

unread,
Oct 19, 1999, 3:00:00 AM10/19/99
to
I don't understand why this is so hard. I need to emulate keyboard input on
all 32bit windows (95, 98, NT). I also need to emulate keyboard input to
ANY application (in particular, a DOS app). For some reason this is a
problem. On NT I wrote a small app (in VB 'cause it was quick and dirty)
which called AppActivate followed by keybd_event (I did not use SendInput
because it won't work on 95). I could set the focus to any window and then
send it a series of WM_KEYDOWN and WM_KEYUP events. I could even manually
start a DOS session and send it keystrokes (like "dir"). However, when I
sent "edit" to my DOS window and started the old faithful MS-DOS Edit,
everything fell apart. No longer could I synthesize input to that window.
As soon as I exited the editor, I could send keystrokes again. Just for
fun, I ran this little app on a Win95 machine. Once again, I could send
keystrokes to any Win app just fine, but I couldn't send any keystrokes to a
plain old DOS window, even without edit running.

WHAT GIVES???

I know this is possible because I searched the internet and found a couple
"schedulers" that will emulate keyboard input to any application on all
three platforms. I thought if I called a low-level function I could get
this to work. The documentation says: The keyboard driver's interrupt
handler calls the keybd_event function. I don't know how I could go any
lower.

Some additional info:
Another application spawns the DOS app I want to control, so I can't
AllocConsole, start the app in my console and call GetStdHandle.
If I have to detect the OS and emulate input differently on the three
platforms, I can do that.
If I have to sacrifice any platform, it would be NT.
Please CC my email also.

My sincere thanks to anyone who can help.

Waiting impatiently so I don't have to call Microsoft and pay them $100 so
they can run me around in circles until it's too late,
Scott Leonard
sbl"AT"msn.com

Howard Johnson

unread,
Oct 19, 1999, 3:00:00 AM10/19/99
to
In article <OO#ORjmG$GA.231@cppssbbsa05>, Scott Leonard <s...@msn.com> wrote:
>I don't understand why this is so hard. I need to emulate keyboard input on
>all 32bit windows (95, 98, NT). I also need to emulate keyboard input to
>ANY application (in particular, a DOS app).

I've written a keyboard filter driver for Win9X and WinNT4. The Win9X
driver is a VxD, and the NT driver is a layered driver which does an
IoAttachDevice to L"\\Device\\KeyboardPort0". Both present the same
DosDevIoCtl interface to Win32 apps. The IoCtl takes an unadorned array
of scan codes to drop into the kernel's keyboard buffer.

The Win9X driver was simple: I found a hook in the sample keyboard driver
which I could call. My NT driver had to know intimate details about the
i8042prt.sys's keyboard buffer (it works with i8042prt.sys up through SP2,
and if later service packs are applies, I have to back-rev i8042prt.sys).

The motivation for writing this driver was to automate testing logons.

I've played with the sample kbfiltr.sys driver in Win2000's RC2 DDK and
can't for the life of me get control when I call DosDevIoCtl from my app.
It seems KeyboardPort0 and KeyboardClass0 don't exist. I suspect that
kbdclass.sys is not passing through requests via IoCallDriver because
I get an INVALID_PARAMETER error in my app.

Any clues?

Kevin Liao

unread,
Oct 20, 1999, 3:00:00 AM10/20/99
to
Hi,

In win2000, PNP manager will automatically load your filter driver if you
install your driver correctly. So you don't need to know the name of the
driver(i8042prt.sys) under yours. Your app can still communicate with your
driver through IOCTLs just like before.

Regards,
Kevin

Howard Johnson 撰寫於文章 <7uikkl$lb7$1...@xmission.xmission.com>...

Howard Johnson

unread,
Oct 20, 1999, 3:00:00 AM10/20/99
to
In article <#GnahCrG$GA....@cppssbbsa02.microsoft.com>,

Kevin Liao <mei...@neto.net> wrote:
>Hi,
>
>In win2000, PNP manager will automatically load your filter driver if you
>install your driver correctly. So you don't need to know the name of the
>driver(i8042prt.sys) under yours. Your app can still communicate with your
>driver through IOCTLs just like before.

My driver gets loaded and it is on the !devstack right below
\Driver\Kbdclass and right above \Driver\i8042prt, followed by
\Driver\PnpManager. I recompiled kbdclass.sys and put an _asm int 3
in the case for the ioctl I'm using, but that doesn't get executed either.

I would just trace into the kernel from the DosDevIoCtl call, but I can't
find symbols for any RC2 revision I have (I'm using a checked Build 2130).

Next?

>Howard Johnson <7uikkl$lb7$1...@xmission.xmission.com>...

Kevin Liao

unread,
Oct 21, 1999, 3:00:00 AM10/21/99
to
Can't your ap communicate to your drvier directly without going through
keyboard class driver?

Howard Johnson 撰寫於文章 <7uksbe$25e$1...@xmission.xmission.com>...

Howard Johnson

unread,
Oct 21, 1999, 3:00:00 AM10/21/99
to
To date: I've written a driver which implements a DeviceIoControl (ioctl)
that takes raw scan codes from an app and feeds them to the kernel's
keyboard buffer. It's derived from the sample kbfiltr.sys driver in the
Win 2000 RC2 DDK. I see the IRP_MJ_CREATE and IRP_MJ_CLOSE requests, but
not the IRP_MJ_DEVICE_CONTROL requests.

In article <#pF4eu2G$GA....@cppssbbsa02.microsoft.com>,


Kevin Liao <mei...@neto.net> wrote:
>Can't your ap communicate to your drvier directly without going through
>keyboard class driver?

My app opens \\.\kbfiltr directly; indeed, it's the only device name
in the stack that it can see. I believe the driver needs to be a filter
so it can get the keyboard DeviceObject used by i8042prt.sys, and that
DeviceObject is needed to get access to the kernel's keyboard buffer.
The i8042prt.sys driver no longer names it's keyboard ports. And
I'd rather not have to touch kbdclass.sys or i8042prt.sys; that makes
it hard to use SoftIce.

Kevin Liao

unread,
Oct 22, 1999, 3:00:00 AM10/22/99
to
Do you create two Device Objects? One is for driver ifself (that is the one
your app is talking to and the same one you pass to IoCreateSymbolicLink)
and the other is for the Keyboard device stack (that is the one you pass to
IoAttachDeviceToDeviceStack). Your dispatch routine must be able to
distinguish them. Could you give some part of your source code if you can so
that we can find where the problem is more efficiently.

Howard Johnson 撰寫於文章 <7unej7$a53$1...@xmission.xmission.com>...

0 new messages