Hey Chris, I'm back again.
I was working on the DDK stuff when a friend suggested something else that is almost a solution.
In the past I mentioned DeviceIoControl but I wasn't sure on how to use it. As it stands, it was somewhat explained to be, but documentation remains scarce on what I need to know.
So here's what I figured out so far... By calling DefineDosDevice, you can create a virtual device linked to the original class devices, as so:
Code:
DefineDosDevice(DDD_RAW_TARGET_PATH, "Mouse", "\\Device\\PointerClass0")
Now, the system will recognize the device "\\.\Mouse", and can be used in a call to CreateFile to create a HANDLE to a stream to the mouse. So far I believe this is correct, so here is the code for CreateFile:
Code:
m_hMouse = CreateFile("\\\\.\\Mouse", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)
So now, provided m_hMouse is okay, we have a handle to the mouse device that can be passed to DeviceIoControl. This is where documentation is scarce and I have not been able to figure out the rest. However, here are 2 simple methods that I've used to initialize and close the mouse handles in a simple MFC application:
Code:
bool CPTBotDlg::InitializeMouse()
{
bool bMouse = false;
if(DefineDosDevice(DDD_RAW_TARGET_PATH, "Mouse", "\\Device\\PointerClass0"))
if((m_hMouse = CreateFile("\\\\.\\Mouse", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
bMouse = true;
return bMouse;
}
void CPTBotDlg::UninitializeMouse()
{
if(DefineDosDevice(DDD_REMOVE_DEFINITION, "Mouse", NULL))
if(m_hMouse != INVALID_HANDLE_VALUE)
CloseHandle(m_hMouse);
m_hMouse = INVALID_HANDLE_VALUE;
}
m_hMouse is defined as a HANDLE.
So, the next step I think is to write a method that uses the handle calling DeviceIoControl, and here's what I know about that:
Code:
DeviceIoControl(m_hMouse, CTL_CODE(FILE_DEVICE_MOUSE, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS), NULL, 0, NULL, 0, NULL, NULL)
This is PURELY a non functional example, however it demonstrates the little bit I've pieced together so far. First, m_hMouse, as we described above, is passed in. Second, we have to create an IO Control Code to be passed to the device. In this case, we want to create a device io control code for writing mouse clicks to the data stream. So, the first argument we use is FILE_DEVICE_MOUSE, and I'm about 80% sure about this argument being correct. Next, we have 0x802, and this I'm only about 10% sure on, as I just stumbled across a reference to CTL_CODE on some chinese driver forum, and the only english parts were that 0x801 referred to mouse movement, and 0x802 referred to mouse clicks. So again, not able to find anything clear on this matter. Next comes METHOD_BUFFERED and FILE_ANY_ACCESS which are the typically suggested default arguments to use.
After we can figure out if this is a proper control code, we are still stuck with another problem. Every control code takes a different input and output buffer argument, typecased to LPVOID. So this leaves a big guessing game as to what type of input buffer to allocate. The MSDN only has a short bit to say on DeviceIoControl, that you can pass NULL for the buffers if they are not required for the IO Control Code. My guess is that only the input buffer will be required. That is the first 2 arguments after the control code, an LPVOID to the buffer, and the size of the buffer. The following 4 arguments are the output buffer, size, a pointer to how many bytes are put into the output buffer, and a pointer to any overlapped data. I do not believe, at this point, that the last 4 arguments are of concern, however, I must figure out what sort of input buffer to pass in, and what data to put in the buffer, in order to get mouse movements and clicks to work.
I realize you're probably still tied up with features on the todo list, but I hope this might renew your interest enough to help dig for the missing pieces of information. If this works, then it will negate the need for a separate system driver, as DeviceIoControl can be called from AutoHotkey directly, just have the directive used, take an optional argument for the class devices (some people having 2 mice, would maybe use \\Device\PointerClass1 instead of PointerClass0, as such, allow them to provide a device number to hook, but this is far off still).
My calls to Initialize both Keyboard and Mouse work successfully, I believe my handles are valid, however I have no idea how to use DeviceIoControl to feed input into the device stream. My believe is that once it's in there, like the Kernel level equivilent, it will call the appropriate callbacks to handle the data. I found a small diagram I forgot to bookmark, that showed the different layers for input abstraction, where DirectInput and other Legacy methods were quite high level, and the mouse class, and mouse filter drivers, and DeviceIoControl's point of communication was quite a bit lower, almost at the physical data port itself. If I am correct, DeviceIoControl injects data into the moufiltr level, and from there it's passed to the mouclass, and on upwards to DirectInput and Legacy methods.
Any help on this subject would be greatly appreciated if anyone can even point me in the right direction. I've spent a good number of hours searching google and talking with someone who wrote a Virtual Volume mounting driver using the DDK, and it really seems the information on DeviceIoControl is limited to what you find at MSDN, and they only suggest about 30 different FILE_DEVICE values, that have different input and output buffer arguments, but then never document any of it. This isn't even really something you can guess and test with, I really have NO idea what kind of buffer to allocate, if I'm even doing this right. DeviceIoControl simply just fails right now as could be expected.
Oh well, that's all I have to report, hope somthing sparks a movement forward on this... As you can see, I haven't quite given up yet
