Hello,
I’m a beginner when it comes to driver programming, so pardon what may be a stupid question.
I’m writing an HID mini-driver (mini-port?) for a keyboard that has both a qwerty keyboard as well as a musical keyboard.
Currently, I can’t use RAWINPUT because the Music Keyboard report descriptor states that the the report size is 30 bytes, when in actuality the size ranges from 2 bytes to 30 bytes. RAWINPUT doesn’t pass the input unless there are 30 bytes received. (15 musical keys at once!)
To get around this issue, I’m writing an HID mini-driver (mini-port? semantics fail me at the moment) and I have a raw PDO created to help transfer the musical key data from the HID/Rawinput path to my own RawPDO communication path. I’m stuck at the point where I’m sending data from the KMDF driver to the User mode application. I use a DeviceIOControl() call and it comes back true with the number of bytes written that I tell it to. However, the buffer is full of 0x0s. and not the data that’s expected. An example of what is happening:
I press a key on the keyboard, it sends 0x03|0x7F|0x56. I watch the KMDF procedures (via WinDBG) from the notification that there is data from the continuous reader to when the rawPDO pops my IOCTL from the rawPDO’s queue, get the output buffer, take the data and assign 0x03|etc to the user buffer. I ‘receieve’ the data in my Windows Application and it shows 0x0|0x0|0x0.
I’m stuck, so I figured I’d ask the KMDF gurus for some help. I suspect it’s the way I’m allocating my buffers or something of the sort.
Here’s the code from the KMDF code and the application:
KMDF:
VOID
MusicKBDFilter_Send_MIDI_Data(
IN PDEVICE_EXTENSION devContext, // Device Context
IN BYTE MIDI_DATA, // Actual MIDI Data
IN size_t BufferLength //Number of Bytes
)
{
WDFREQUEST irRequest;
NTSTATUS status = STATUS_SUCCESS;
PRPDO_DEVICE_DATA myPdoData = NULL;
BYTE outMIDI_DATA[30]={0};
size_t bytesReturned=0;
size_t i;
myPdoData = PdoGetData(devContext->PdoDevice);
status = WdfIoQueueRetrieveNextRequest(myPdoData->MIDI_Queue, &irRequest);
if(NT_SUCCESS(status))
{
status = WdfRequestRetrieveUnsafeUserOutputBuffer(
irRequest,
BufferLength,
(PVOID *)outMIDI_DATA,
&bytesReturned);// BufferLength
for (i=0;i {
outMIDI_DATA[i]=MIDI_DATA[i];
}
if(NT_SUCCESS(status))
{
WdfRequestCompleteWithInformation(irRequest, STATUS_SUCCESS, bytesReturned);
}
}
return;
}
The Application Code: (not all code, but the essentials)
BYTE reportBuffer[0x20] = {0};
reportBuffer[0]=0x3;
result = DeviceIoControl(m_hDev, IOCTL_CTPKFILTER_GET_MIDI_DATA, NULL,0,reportBuffer, 0x20,&dwBytesRead,NULL);
And that returns 0x3|0x0|0x0|etc.
Thanks!