Alright, it's been a long time since I've been to these forums, the last time was regarding a topic that seemed to go on for some 52 pages after I left. I'm back again to bring life to this topic once more.
The topic is that of simulated input to applications (particularily those using DirectInput or other kernel level means of input detection). As before, I solved this problem but the solution was erratic at best. Having lost interest in the project, I moved on and to no big surprise have come full circle to the same problem. After searching the forums, I see some folks have found some ingenious solutions stemming from the original idea. However, nothing concrete has yet been provided to solve this problem.
My original project involved kbdclass and mouclass drivers. At the time, and even now, I was and still am fresh to writing drivers, it's not something I do every day, however at the time of the first attempt I did not understand that the class level drivers are the first stop for all data, it seems like it may be more compatible and friendly to use a higher level filter driver. It is still handled within the kernel, however rather than replacing your standard kbdclass driver, a kbfiltr can attach itself to one (or many) devices as required. A little probing of google rendered some results that allow you to easily attach to the first keyboard on the system which is 99% of the time going to result in the desired effect, attaching to your main keyboard. Within this realm, it is possible to change, remove, or add new data to the buffered IO queues. However, some who could contribute to this may not fully understand how this works so I'm going to elaborate.
The kbfiltr driver is attached to a kbdclass driver. Now, when a kbdclass or kbfiltr is called into, you're not JUST passing keys. In fact, your keyboard in this case, passes various types of IO commands to the same function, you may read a key, write a key, deal with special scan codes to interact with keyboards that have lights, stuff like that. So this one stop access point we'll call the ServiceCallback. So how does this all relate to injecting input undetected? Glad you asked.
First of all, these 2 drivers appear to only work with PS/2 devices, this explains why my first attempt may have failed with the mouse when trying to write that driver, I probably had my keyboard plugged in via PS/2 (to avoid legacy USB support in BIOS when reformatting), but left my mouse plugged in by USB. So herein is the problem, USB devices won't be affected by these drivers. Is this a big problem? Not really, and one I will be overlooking for the remainder of this solution. It will be assumed that your keyboard and mouse can be plugged in via PS/2 ports, but if you're adamant and skilled, you can get the Windows WDK and attempt to write USB drivers to the same effect, it just so happens the PS/2 stuff is significantly less involved not having to deal with many of the intricacies of the USB standard.
Okay, so you asked how this relates to injecting input, I'm getting to that! There is a Win32API function called DeviceIoControl, and this allows you to send IO control commands to the driver, more importantly to that previously mentioned ServiceCallback. So as you may or may not realize, the driver isn't specific about the IO control codes it is sent, it is upto you writing the driver to determine how control codes are processed, including unknown codes. However, if this has interested you then you may have already done a little digging and found that there is mention of an INJECT IO control command, and a little more trial and error would make you realize that it doesn't do anything, the control code appears to be ignored, or at least this was the result of prior testing I had done for the first attempt.
So, the solution to undetectable input lies in kbfiltr and moufiltr. To that end I have recently started playing a game when I'm kinda bored, called 2Moons, suffering from much the same problems as the prior Priston Tale, and many other games it would seem. If I get this solution to work, it should be as simple as updating your driver in device manager with an INF and SYS file to allow injection. From there, it's left to user-land to provide wrappers around the DeviceIOControl calls to make injection more end-user friendly.
I know there is a fairly large interest in this topic, so I guess I'm posting to reactivate that interest and ensure that someone else hasn't already provided this solution and I have somehow overlooked it somewhere. Please disclude my old solution, as it was a kbdclass filter and was far more detrimental to the system in terms of ease of installation. Removing a kbfiltr be as easy as removing a single registry entry and deleting the .SYS file, while the kbdclass stuff required reinstalling the original driver from the windows installation if you wanted to remove it.
Chris, I know I spoke with you directly about this subject quite extensively, and recent posts from you show you haven't followed up on it with AutoHotKey, but that you seem willing to adopt a solution like this as an optional install, or secondary download. This project is not at the top of my priorities list, but if this topic picks up some momentum and discussion by a few coders who know what they're doing, then I might take some of the feedback and get the driver written. It's not that complicated in it's own, but you may want to wrap the DeviceIOControl calls in AHK, or you may want a separate DLL to use for calling into to make it easier, a discussion would be prudent.
On a side note, I see AHK's language grammar and functionality has come a long way from when I last used it, that's great to see as I've considered using Spart (.NET spirit clone) to write my own AHK like clone until I found AHK's grammar had matured a bit to allow more complex concepts. Still, might be a fun project to try.
So, everyone, show your interest, motivate me to write the drivers, show me it won't go to waste
