Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UMDF] DMF_VirtualHidMini fails WriteReport requests on descriptors without Report IDs #153

Closed
nefarius opened this issue Feb 24, 2021 · 2 comments

Comments

@nefarius
Copy link
Contributor

Greetings,

just stumbled upon an interesting issue with the DMF_VirtualHidMini module. I have a device which (for compatibility reasons) doesn't utilize Report IDs in its HID Report Descriptor. It exposes one input, feature and output report. Snippet of Output Report definition in descriptor:

	0x06, 0x00, 0xFF,  //     Usage Page (Vendor Defined 0xFF00)
	0x09, 0x01,        //     Usage (0x01)
	0x75, 0x08,        //     Report Size (8)
	0x95, 0x30,        //     Report Count (48)
	0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)

Everything works fine except writing an output report, WriteFile / GetOverlappedResult failed with ERROR_INSUFFICIENT_BUFFER despite the same code working perfectly with the legacy kernel-driver equivalent of my new UMDF-only code, which got me curious.

[2021-02-24 13:11:28.502] [WriteFile] [info] ret=0, lastError=997 (0049) ->  00 02 00 00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[2021-02-24 13:11:28.502] [GetOverlappedResult] [info] ret=0, lastError=122, bytesWritten=0

I am aware of the trickery necessary to get the Report ID delivered from mshidumdf.sys to the reflector and my driver so I examined the VirtualHidMini_RequestGetHidXferPacket_ToWriteToDevice implementation of DmfU and I think I found a bug:

Accessing the output buffer fails with STATUS_BUFFER_TOO_SMALL and my own callback isn't even invoked, the module answers this request with an error. Assuming that a zero-length buffer is the result of an absence of a Report ID (being effectively 0) I introduced this experimental hack and sure enough, my code works now, I receive the buffer content and the user-land API completes with success:

    // Get report Id from output buffer length.
    //
    ntStatus = WdfRequestRetrieveOutputMemory(Request,
                                              &outputMemory);
    if ( !NT_SUCCESS(ntStatus) && ntStatus != STATUS_BUFFER_TOO_SMALL )
    {
        TraceEvents(TRACE_LEVEL_ERROR, DMF_TRACE, "WdfRequestRetrieveOutputMemory fails: ntStatus=%!STATUS!", ntStatus);
        goto Exit;
    }

    // React to this specific case by assuming 0
    //
    if (ntStatus == STATUS_BUFFER_TOO_SMALL)
    {
        Packet->reportId = 0;
    }
    else
    {
        WdfMemoryGetBuffer(outputMemory,
            &outputBufferLength);
        Packet->reportId = (UCHAR)outputBufferLength;
    }

If my assumptions are correct I'd gladly provide a PR and see this change merged so the framework can handle this edge-case properly as well 😁

Thank you!

@samtertzakian
Copy link
Member

Hi, nefarius... We are looking at this now. Thank you for your feedback.

@samtertzakian
Copy link
Member

This issue is corrected by Release v.1.1.83.
We have made the above change.
Thank you nefarius.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants