oblitum / Interception

The Interception API aims to build a portable programming interface that allows one to intercept and control a range of input devices.
http://oblita.com/interception
1.37k stars 267 forks source link

Question: Is there a particular reason for padding event when registering? #81

Closed x0a closed 5 years ago

x0a commented 5 years ago

I'm trying to port the following code to Rust. https://github.com/oblitum/Interception/blob/513556e660893ca294b2e287143abb40a9170bb3/library/interception.c#L55-L76

And have something like the following:

pub struct Device {
    handle: HANDLE,
    event: HANDLE,
}
impl Device {
    fn new(query: LPCSTR) -> Option<Device> {
        unsafe {
            let handle = CreateFileA(
                query,
                GENERIC_READ,
                0,
                null_mut(),
                OPEN_EXISTING,
                0,
                null_mut(),
            );
            if handle == INVALID_HANDLE_VALUE {
                return None;
            }
            let event = CreateEventA(null_mut(), true, false, null_mut()) as LPVOID;

            if event == INVALID_HANDLE_VALUE {
                CloseHandle(handle);
                return None;
            }
            let mut padded_event: [HANDLE; 2] = [event, 0 as HANDLE];
            let mut output_size: u32 = 0;

            if !DeviceIoControl(
                handle,
                IOCTL_SET_EVENT!(),
                padded_event.as_mut_ptr() as LPVOID,
                std::mem::size_of_val(&padded_event) as DWORD,
                null_mut(),
                0,
                &mut output_size,
                null_mut(),
            ) {
                CloseHandle(handle);
                CloseHandle(event);

                return None;
            }
            return Some(Device { handle, event });
        }
    }
    //....

The driver happily accepts the event handle, overwrites my string buffer asking for hardware ID, accepts my "SET_FILTER" request; but it will not actually trigger the event when I WaitForMultipleObjects, with the event handles for 10 keyboards. It will timeout.

My question is, what exactly does the driver do with the handle provided with IOCTL_SET_EVENT, so I know what to send?

oblitum commented 5 years ago

It should send exactly what the API does. If the API works but your implementation doesn't, there should be some mistake in the port.

As for what the driver does, I don't recall now from top of my head exactly, I'd need to check it out, but AFAIR, it had to do with some internal Windows behavior when there was a need to handle both 32 and 64 bit applications from a 64 bit driver.

Notice the README states that distribution of binaries for free applications are OK only if communication happens solely by use of the official library.