none
Injecting input to fake device with HID minidriver sample? RRS feed

  • Question

  •  

    I am trying to still create my multi-mouse application and have come across this:

    https://code.msdn.microsoft.com/WudfVhidmini-Sample-b304f83a

    I wish to use the above hid miniport driver with the below class:

    https://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.humaninterfacedevice.aspx

    My objective is to create a device (call it joystick1) that has similar characteristic's of a mouse device and a hid mouse device (just their for input injection for the most part) to go along with it.  The reason is so that I can use the above class and pass x,y, left/right click, and possibly scroll wheel data to the device and pass/inject data into the mouse device (I think it would be passed via the input report) from the first device. I have some questions:

    1. How would I implement/create this device? Should I create it in the miniport along with the hid mouse device? Can I specify an extra feature or variable in report descriptor for this joystick1 or the hid miniport device (for mouse data injection) to send to the device to make see how many devices they want to create? (maybe add this to the miniports report descriptor) 

    2. How should I pass data on to the device? Maybe send it via a output report to the first device and then send it via an input report to the mouse device?

    3. Would the windows.devices.humaninterfacedevice class work?

    4. I thought about adding the ability in an API to distinguish between multi-mouse applications is this possible or is it recommended to do this from user mode?

    I was looking at this code that appears to perform device IO functions or sends data to the appropriate function (possibly start from here for input to child device?):

    VOID
    STDMETHODCALLTYPE
    CMyQueue::OnDeviceIoControl(
        _In_ IWDFIoQueue *FxQueue,
        _In_ IWDFIoRequest *FxRequest,
        _In_ ULONG ControlCode,
        _In_ SIZE_T InputBufferSizeInBytes,
        _In_ SIZE_T OutputBufferSizeInBytes
        )
    /*++
    
    Routine Description:
    
        DeviceIoControl dispatch routine
    
    Aruments:
        
        FxQueue - Framework Queue instance
        FxRequest - Framework Request  instance
        ControlCode - IO Control Code
        InputBufferSizeInBytes - Lenth of input buffer
        OutputBufferSizeInBytes - Lenth of output buffer
    
        Always succeeds DeviceIoIoctl
    Return Value:
    
        VOID
    
    --*/
    {
        UNREFERENCED_PARAMETER(FxQueue);
        UNREFERENCED_PARAMETER(InputBufferSizeInBytes);
        UNREFERENCED_PARAMETER(OutputBufferSizeInBytes);
        
        HRESULT hr = S_OK;
        BOOLEAN completeRequest = TRUE;
        IWDFIoRequest2 *fxRequest2;
    
        hr = FxRequest->QueryInterface(IID_PPV_ARGS(&fxRequest2));
        if (FAILED(hr)){
            FxRequest->Complete(hr);
            return;
        }
        fxRequest2->Release();
    
        switch (ControlCode)
        {
        case IOCTL_HID_GET_DEVICE_DESCRIPTOR:   // METHOD_NEITHER
            //
            // Retrieves the device's HID descriptor.
            //
            hr = GetHidDescriptor(fxRequest2);
            break;
        
        case IOCTL_HID_GET_DEVICE_ATTRIBUTES:    // METHOD_NEITHER
            //
            //Retrieves a device's attributes in a HID_DEVICE_ATTRIBUTES structure.
            //
            hr = GetDeviceAttributes(fxRequest2);
            break;
    
        case IOCTL_HID_GET_REPORT_DESCRIPTOR:    // METHOD_NEITHER
            //
            //Obtains the report descriptor for the HID device.
            //
            hr = GetReportDescriptor(fxRequest2);
            break;
    
        case IOCTL_HID_READ_REPORT:    // METHOD_NEITHER
            //
            // Returns a report from the device into a class driver-supplied 
            // buffer. 
            //
            hr = ReadReport(fxRequest2, &completeRequest);
            break;

     

    Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth. - Sherlock Holmes. speak softly and carry a big stick - theodore roosevelt. Fear leads to anger, anger leads to hate, hate leads to suffering - Yoda. Blog - http://www.computerprofessions.us


    • Edited by The Thinker Thursday, April 16, 2015 3:27 PM
    Thursday, April 16, 2015 2:09 PM

Answers

  • you don't need to expose the control / data injection collection as a joystick. you can use a custom usage page and then define your own usages. those custom usages can then be mouse data or whatever you want.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    • Marked as answer by Doron Holan [MSFT] Thursday, April 16, 2015 6:16 PM
    • Unmarked as answer by The Thinker Thursday, April 16, 2015 7:16 PM
    • Marked as answer by The Thinker Monday, April 20, 2015 4:26 PM
    Thursday, April 16, 2015 6:16 PM

  • Question: How do I send data to that mouse device in the collection now?


    Haven't you seen this?


    • Edited by Pavel A Friday, April 17, 2015 12:52 AM
    • Marked as answer by The Thinker Monday, April 20, 2015 4:26 PM
    Friday, April 17, 2015 12:51 AM

All replies

  • you don't need to expose the control / data injection collection as a joystick. you can use a custom usage page and then define your own usages. those custom usages can then be mouse data or whatever you want.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    • Marked as answer by Doron Holan [MSFT] Thursday, April 16, 2015 6:16 PM
    • Unmarked as answer by The Thinker Thursday, April 16, 2015 7:16 PM
    • Marked as answer by The Thinker Monday, April 20, 2015 4:26 PM
    Thursday, April 16, 2015 6:16 PM
  • you don't need to expose the control / data injection collection as a joystick. you can use a custom usage page and then define your own usages. those custom usages can then be mouse data or whatever you want.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

     

    I noticed already that the 

    miniport accepts numeric input for the output report. I am still confused about how to add the child devices though and accept data for them. How would I do that? (I am wondering what function I would call mostly for creating the device and how to pass data along to the mouse device) P.S. Do I add the usage page to the vhidmini sample report descriptor? Could I use the vhidmini's report descriptor and add the usage page to it or do I need to create a descriptor for the sample device? I need multiple devices to be created though during my communication with the miniport device driver either way.   


    Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth. - Sherlock Holmes. speak softly and carry a big stick - theodore roosevelt. Fear leads to anger, anger leads to hate, hate leads to suffering - Yoda. Blog - http://www.computerprofessions.us





    • Edited by The Thinker Thursday, April 16, 2015 8:59 PM
    Thursday, April 16, 2015 8:36 PM
  • you don't need to expose the control / data injection collection as a joystick. you can use a custom usage page and then define your own usages. those custom usages can then be mouse data or whatever you want.


    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

     

    I noticed already that the 

    miniport accepts numeric input for the output report. I am still confused about how to add the child devices though and accept data for them. How would I do that? (I am wondering what function I would call mostly for creating the device and how to pass data along to the mouse device) P.S. Do I add the usage page to the vhidmini sample report descriptor? Could I use the vhidmini's report descriptor and add the usage page to it or do I need to create a descriptor for the sample device? I need multiple devices to be created though during my communication with the miniport device driver either way.   


    Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth. - Sherlock Holmes. speak softly and carry a big stick - theodore roosevelt. Fear leads to anger, anger leads to hate, hate leads to suffering - Yoda. Blog - http://www.computerprofessions.us





    Here's what I messed around with after looking at this post and the next post:

    HID_REPORT_DESCRIPTOR           G_DefaultReportDescriptor[] = {
        0x06,0x00, 0xFF,                // USAGE_PAGE (Vender Defined Usage Page)
        0x09,0x01,                      // USAGE (Vendor Usage 0x01)
        0xA1,0x01,                      // COLLECTION (Application)
        0x85,CONTROL_FEATURE_REPORT_ID,    // REPORT_ID (1)
        0x09,0x01,                         // USAGE (Vendor Usage 0x01)
        0x15,0x00,                         // LOGICAL_MINIMUM(0)
        0x26,0xff, 0x00,                   // LOGICAL_MAXIMUM(255)
        0x75,0x08,                         // REPORT_SIZE (0x08)
        //0x95,FEATURE_REPORT_SIZE_CB,       // REPORT_COUNT 
        0x96,(FEATURE_REPORT_SIZE_CB & 0xff), (FEATURE_REPORT_SIZE_CB >> 8), // REPORT_COUNT 
        0xB1,0x00,                         // FEATURE (Data,Ary,Abs)
        0x09,0x01,                         // USAGE (Vendor Usage 0x01)
        0x75,0x08,                         // REPORT_SIZE (0x08)
        //0x95,INPUT_REPORT_SIZE_CB,       // REPORT_COUNT 
        0x96,(INPUT_REPORT_SIZE_CB & 0xff), (INPUT_REPORT_SIZE_CB >> 8), // REPORT_COUNT 
        0x81,0x00,                         // INPUT (Data,Ary,Abs)
        0x09,0x01,                         // USAGE (Vendor Usage 0x01)
        0x75,0x08,                         // REPORT_SIZE (0x08)
        //0x95,OUTPUT_REPORT_SIZE_CB,      // REPORT_COUNT 
        0x96,(OUTPUT_REPORT_SIZE_CB & 0xff), (OUTPUT_REPORT_SIZE_CB >> 8), // REPORT_COUNT 
        0x91,0x00,                         // OUTPUT (Data,Ary,Abs)
        0xC0,                           // END_COLLECTION
    	0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    	0x09, 0x02,                    // USAGE (Mouse)
    	0xa1, 0x01,                    // COLLECTION (Application)
    	0x09, 0x01,                    //   USAGE (Pointer)
    	0xa1, 0x00,                    //   COLLECTION (Physical)
    	0x05, 0x09,                    //     USAGE_PAGE (Button)
    	0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
    	0x29, 0x03,                    //     USAGE_MAXIMUM (Button 3)
    	0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    	0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    	0x95, 0x03,                    //     REPORT_COUNT (3)
    	0x75, 0x01,                    //     REPORT_SIZE (1)
    	0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    	0x95, 0x01,                    //     REPORT_COUNT (1)
    	0x75, 0x05,                    //     REPORT_SIZE (5)
    	0x81, 0x03,                    //     INPUT (Cnst,Var,Abs)
    	0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
    	0x09, 0x30,                    //     USAGE (X)
    	0x09, 0x31,                    //     USAGE (Y)
    	0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
    	0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
    	0x75, 0x08,                    //     REPORT_SIZE (8)
    	0x95, 0x02,                    //     REPORT_COUNT (2)
    	0x81, 0x06,                    //     INPUT (Data,Var,Rel)
    	0xc0,                          //   END_COLLECTION
    	0xc0                           // END_COLLECTION
    };

    This is probably wrong but I was piecing together the last post I made here: https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/bb6988b7-8f77-4e95-b949-b1c3eeca2e54/how-to-createsimulate-multiple-mouse-devices-in-dev-manager-in-windows-81-and-above?forum=wdk#d19cad22-5391-4a60-962b-79957bd87862

    with this post. So, would the above report descriptor be closer to what you were referring to? Again, I am still working on this but I am starting to learn more about report descriptors and get more comfortable with them and device driver development.


    Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth. - Sherlock Holmes. speak softly and carry a big stick - theodore roosevelt. Fear leads to anger, anger leads to hate, hate leads to suffering - Yoda. Blog - http://www.computerprofessions.us


    • Edited by The Thinker Thursday, April 16, 2015 9:18 PM
    Thursday, April 16, 2015 9:10 PM
  • you don't need to expose the control / data injection collection as a joystick. you can use a custom usage page and then define your own usages. those custom usages can then be mouse data or whatever you want.


    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

     

    I noticed already that the 

    miniport accepts numeric input for the output report. I am still confused about how to add the child devices though and accept data for them. How would I do that? (I am wondering what function I would call mostly for creating the device and how to pass data along to the mouse device) P.S. Do I add the usage page to the vhidmini sample report descriptor? Could I use the vhidmini's report descriptor and add the usage page to it or do I need to create a descriptor for the sample device? I need multiple devices to be created though during my communication with the miniport device driver either way.   


    Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth. - Sherlock Holmes. speak softly and carry a big stick - theodore roosevelt. Fear leads to anger, anger leads to hate, hate leads to suffering - Yoda. Blog - http://www.computerprofessions.us





    Here's what I messed around with after looking at this post and the next post:

    HID_REPORT_DESCRIPTOR           G_DefaultReportDescriptor[] = {
        0x06,0x00, 0xFF,                // USAGE_PAGE (Vender Defined Usage Page)
        0x09,0x01,                      // USAGE (Vendor Usage 0x01)
        0xA1,0x01,                      // COLLECTION (Application)
        0x85,CONTROL_FEATURE_REPORT_ID,    // REPORT_ID (1)
        0x09,0x01,                         // USAGE (Vendor Usage 0x01)
        0x15,0x00,                         // LOGICAL_MINIMUM(0)
        0x26,0xff, 0x00,                   // LOGICAL_MAXIMUM(255)
        0x75,0x08,                         // REPORT_SIZE (0x08)
        //0x95,FEATURE_REPORT_SIZE_CB,       // REPORT_COUNT 
        0x96,(FEATURE_REPORT_SIZE_CB & 0xff), (FEATURE_REPORT_SIZE_CB >> 8), // REPORT_COUNT 
        0xB1,0x00,                         // FEATURE (Data,Ary,Abs)
        0x09,0x01,                         // USAGE (Vendor Usage 0x01)
        0x75,0x08,                         // REPORT_SIZE (0x08)
        //0x95,INPUT_REPORT_SIZE_CB,       // REPORT_COUNT 
        0x96,(INPUT_REPORT_SIZE_CB & 0xff), (INPUT_REPORT_SIZE_CB >> 8), // REPORT_COUNT 
        0x81,0x00,                         // INPUT (Data,Ary,Abs)
        0x09,0x01,                         // USAGE (Vendor Usage 0x01)
        0x75,0x08,                         // REPORT_SIZE (0x08)
        //0x95,OUTPUT_REPORT_SIZE_CB,      // REPORT_COUNT 
        0x96,(OUTPUT_REPORT_SIZE_CB & 0xff), (OUTPUT_REPORT_SIZE_CB >> 8), // REPORT_COUNT 
        0x91,0x00,                         // OUTPUT (Data,Ary,Abs)
        0xC0,                           // END_COLLECTION
    	0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    	0x09, 0x02,                    // USAGE (Mouse)
    	0xa1, 0x01,                    // COLLECTION (Application)
    	0x09, 0x01,                    //   USAGE (Pointer)
    	0xa1, 0x00,                    //   COLLECTION (Physical)
    	0x05, 0x09,                    //     USAGE_PAGE (Button)
    	0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
    	0x29, 0x03,                    //     USAGE_MAXIMUM (Button 3)
    	0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    	0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    	0x95, 0x03,                    //     REPORT_COUNT (3)
    	0x75, 0x01,                    //     REPORT_SIZE (1)
    	0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    	0x95, 0x01,                    //     REPORT_COUNT (1)
    	0x75, 0x05,                    //     REPORT_SIZE (5)
    	0x81, 0x03,                    //     INPUT (Cnst,Var,Abs)
    	0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
    	0x09, 0x30,                    //     USAGE (X)
    	0x09, 0x31,                    //     USAGE (Y)
    	0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
    	0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
    	0x75, 0x08,                    //     REPORT_SIZE (8)
    	0x95, 0x02,                    //     REPORT_COUNT (2)
    	0x81, 0x06,                    //     INPUT (Data,Var,Rel)
    	0xc0,                          //   END_COLLECTION
    	0xc0                           // END_COLLECTION
    };

    This is probably wrong but I was piecing together the last post I made here: https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/bb6988b7-8f77-4e95-b949-b1c3eeca2e54/how-to-createsimulate-multiple-mouse-devices-in-dev-manager-in-windows-81-and-above?forum=wdk#d19cad22-5391-4a60-962b-79957bd87862

    with this post. So, would the above report descriptor be closer to what you were referring to? Again, I am still working on this but I am starting to learn more about report descriptors and get more comfortable with them and device driver development.


    Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth. - Sherlock Holmes. speak softly and carry a big stick - theodore roosevelt. Fear leads to anger, anger leads to hate, hate leads to suffering - Yoda. Blog - http://www.computerprofessions.us


    Okay, you were correct about the collection mapping out roughly to a device. Here's a picture of what the above did (I've changed the REPORT_ID to 2 for the mouse device and added it to the above report descriptor but nothing else):

    Question: How do I send data to that mouse device in the collection now?


    Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth. - Sherlock Holmes. speak softly and carry a big stick - theodore roosevelt. Fear leads to anger, anger leads to hate, hate leads to suffering - Yoda. Blog - http://www.computerprofessions.us


    • Edited by The Thinker Thursday, April 16, 2015 10:05 PM
    Thursday, April 16, 2015 10:04 PM

  • Question: How do I send data to that mouse device in the collection now?


    Haven't you seen this?


    Yes, I knew about that function but was trying out the dot net library and wonder how I can access the device? It wants a UsageId and  UsagePage minimum in its overloads (&H starts out a hex in vb.net). Here's what I have I am trying to first write to the other HID device in the picture above (TLC before where the mouse starts) then will switch to the HID mouse device. Pavel, I still need to write to the mouse's input report buffer or somehow pass the data on down to the mouse device. I prefer using the dot net library first but is it possible to find the UsageId, UsagePage, vendorId, and productId from the data above? Here's my trial vb.net code but I probably have it all wrong:

     Dim vendorId As UInt32 = 48879 '&HBEEF 
                Dim productId As UInt32 = 65261  '&HFEED
                Dim usagePage As UInt32 = 255
                Dim usageId As UInt32 = &H1
    
                ' Create a selector that gets a HID device using VID/PID and a 
                ' VendorDefined usage
                Dim selector As String = HidDevice.GetDeviceSelector(usagePage, usageId, vendorId, productId)
                ' Enumerate devices using the selector
                Dim devices As Windows.Devices.Enumeration.DeviceInformationCollection = DeviceInformation.FindAllAsync(selector)

    Its the device enumeration code translated from C# to vb.net.


    Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth. - Sherlock Holmes. speak softly and carry a big stick - theodore roosevelt. Fear leads to anger, anger leads to hate, hate leads to suffering - Yoda. Blog - http://www.computerprofessions.us

    Friday, April 17, 2015 1:10 AM

  • Question: How do I send data to that mouse device in the collection now?


    Haven't you seen this?


    Yes, I knew about that function but was trying out the dot net library and wonder how I can access the device? It wants a UsageId and  UsagePage minimum in its overloads (&H starts out a hex in vb.net). Here's what I have I am trying to first write to the other HID device in the picture above (TLC before where the mouse starts) then will switch to the HID mouse device. Pavel, I still need to write to the mouse's input report buffer or somehow pass the data on down to the mouse device. I prefer using the dot net library first but is it possible to find the UsageId, UsagePage, vendorId, and productId from the data above? Here's my trial vb.net code but I probably have it all wrong:

     Dim vendorId As UInt32 = 48879 '&HBEEF 
                Dim productId As UInt32 = 65261  '&HFEED
                Dim usagePage As UInt32 = 255
                Dim usageId As UInt32 = &H1
    
                ' Create a selector that gets a HID device using VID/PID and a 
                ' VendorDefined usage
                Dim selector As String = HidDevice.GetDeviceSelector(usagePage, usageId, vendorId, productId)
                ' Enumerate devices using the selector
                Dim devices As Windows.Devices.Enumeration.DeviceInformationCollection = DeviceInformation.FindAllAsync(selector)

    Its the device enumeration code translated from C# to vb.net.


    Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth. - Sherlock Holmes. speak softly and carry a big stick - theodore roosevelt. Fear leads to anger, anger leads to hate, hate leads to suffering - Yoda. Blog - http://www.computerprofessions.us


    I do not understand, it uses 0xFEED (PID) and 0xBEEF (VID). However, I might be using it wrong.

    Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth. - Sherlock Holmes. speak softly and carry a big stick - theodore roosevelt. Fear leads to anger, anger leads to hate, hate leads to suffering - Yoda. Blog - http://www.computerprofessions.us


    Friday, April 17, 2015 1:14 AM

  • Question: How do I send data to that mouse device in the collection now?


    Haven't you seen this?



    The sample program can still write to the default device but the mouse device I am unsure about (No PID or VID at all?). However, I want to change it so their are at least 4 mouse devices. How can I pass data if the VID or PID is not known at all? I would push it down into the mouse collection as suggested by Doran but is my report descriptor correct for that and/or do I need any extra code besides the report descriptor to have this working (I know about write file but I am talking about driver side)?

    Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth. - Sherlock Holmes. speak softly and carry a big stick - theodore roosevelt. Fear leads to anger, anger leads to hate, hate leads to suffering - Yoda. Blog - http://www.computerprofessions.us

    Friday, April 17, 2015 11:59 AM