Search code examples
cwindowsdriverhidkmdf

Windows Virtual HID Framework VhfCreate method returning STATUS_INVALID_DEVICE_REQUEST


I'm working on creating a virtual HID device in Windows 10. I'm trying to use the Windows Virtual HID Framework (as described here: https://msdn.microsoft.com/en-us/library/windows/hardware/dn925056(v=vs.85).aspx) to build the driver. At my current stage, I am just working on getting the driver to properly install on a Windows 10 virtual machine. My driver code is as follows:

#include <ntddk.h>
#include <wdf.h>
#include <vhf.h>

DRIVER_INITIALIZE DriverEntry;
EVT_WDF_DRIVER_DEVICE_ADD BBKbdEvtDeviceAdd;

typedef struct _DEVICE_CONTEXT
{
    VHFHANDLE VhfHandle;
    HID_XFER_PACKET VhfHidReport;

} DEVICE_CONTEXT, *PDEVICE_CONTEXT;

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, DeviceGetContext)

UCHAR MouseReportDescriptor[] = {
    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
    };

NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT  DriverObject, _In_     PUNICODE_STRING RegistryPath)
{
    NTSTATUS status;
    WDF_DRIVER_CONFIG config;

    WDF_DRIVER_CONFIG_INIT(&config, BBKbdEvtDeviceAdd);
    status = WdfDriverCreate(DriverObject, RegistryPath,     WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE);
    return status;
}

NTSTATUS BBKbdEvtDeviceAdd(_In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit)
{
    WDF_OBJECT_ATTRIBUTES   deviceAttributes;
    PDEVICE_CONTEXT deviceContext;
    VHF_CONFIG vhfConfig;
    WDFDEVICE device;
    NTSTATUS status;

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);

    status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);

    if (NT_SUCCESS(status))
    {
        deviceContext = DeviceGetContext(device);

        VHF_CONFIG_INIT(&vhfConfig,
            WdfDeviceWdmGetDeviceObject(device),
            sizeof(MouseReportDescriptor),
            MouseReportDescriptor);

        status = VhfCreate(&vhfConfig, &(deviceContext->VhfHandle));

        if (NT_SUCCESS(status))
            status = VhfStart(deviceContext->VhfHandle);

    }

    return status;
}

For extra context, here's my .inf file:

;
; BBKbdKernalMode.inf
;

[Version]
Signature="$WINDOWS NT$"
Class=Mouse ; TODO: edit Class
ClassGuid={4d36e96f-e325-11ce-bfc1-08002be10318} ; TODO: edit ClassGuid
Provider=%ManufacturerName%
CatalogFile=BBKbdKernalMode.cat
DriverVer= ; TODO: set DriverVer in stampinf property pages

[DestinationDirs]
DefaultDestDir = 12

; ================= Class section =====================

[SampleClassReg]
HKR,,,0,%ClassName%
HKR,,Icon,,-5

[SourceDisksNames]
1 = %DiskName%,,,""

[SourceDisksFiles]
BBKbdKernalMode.sys  = 1,,

;*****************************************
; Install Section
;*****************************************

[Manufacturer]
%ManufacturerName%=Standard,NT$ARCH$

[Standard.NT$ARCH$]
%BBKbdKernalMode.DeviceDesc%=BBKbdKernalMode_Device, Root\BBKbdKernalMode ; TODO: edit hw-id

[BBKbdKernalMode_Device.NT]
CopyFiles=Drivers_Dir

[Drivers_Dir]
BBKbdKernalMode.sys

[HIDVHF_Inst.NT.HW]  
AddReg = HIDVHF_Inst.NT.AddReg  

[HIDVHF_Inst.NT.AddReg]  
HKR,,"LowerFilters",0x00010000,"vhf"  

;-------------- Service installation
[BBKbdKernalMode_Device.NT.Services]
AddService = BBKbdKernalMode,%SPSVCINST_ASSOCSERVICE%,     BBKbdKernalMode_Service_Inst

; -------------- BBKbdKernalMode driver install sections
[BBKbdKernalMode_Service_Inst]
DisplayName    = %BBKbdKernalMode.SVCDESC%
ServiceType    = 1               ; SERVICE_KERNEL_DRIVER
StartType      = 3               ; SERVICE_DEMAND_START
ErrorControl   = 1               ; SERVICE_ERROR_NORMAL
ServiceBinary  = %12%\BBKbdKernalMode.sys

;
;--- BBKbdKernalMode_Device Coinstaller installation ------
;

[DestinationDirs]
BBKbdKernalMode_Device_CoInstaller_CopyFiles = 11

[BBKbdKernalMode_Device.NT.CoInstallers]
AddReg=BBKbdKernalMode_Device_CoInstaller_AddReg
CopyFiles=BBKbdKernalMode_Device_CoInstaller_CopyFiles

[BBKbdKernalMode_Device_CoInstaller_AddReg]
HKR,,CoInstallers32,0x00010000,     "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"

[BBKbdKernalMode_Device_CoInstaller_CopyFiles]
WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll

[SourceDisksFiles]
WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames

[BBKbdKernalMode_Device.NT.Wdf]
KmdfService =  BBKbdKernalMode, BBKbdKernalMode_wdfsect
[BBKbdKernalMode_wdfsect]
KmdfLibraryVersion = $KMDFVERSION$

[Strings]
SPSVCINST_ASSOCSERVICE= 0x00000002
ManufacturerName="<Your manufacturer name>" ;TODO: Replace with your manufacturer name
ClassName="Samples" ; TODO: edit ClassName
DiskName = "BBKbdKernalMode Installation Disk"
BBKbdKernalMode.DeviceDesc = "BBKbdKernalMode Device"
BBKbdKernalMode.SVCDESC = "BBKbdKernalMode Service"

I've followed the guide that I linked to as best as I could, but the call to VhfCreate is returning STATUS_INVALID_DEVICE_REQUEST. I'm wondering what would cause VhfCreate to return this error, and how to go about fixing it.


Solution

  • Change the following in your inf file from

    [HIDVHF_Inst.NT.HW]  
    AddReg = HIDVHF_Inst.NT.AddReg  
    

    to

    [BBKbdKernalMode_Device.NT.HW]  
    AddReg = HIDVHF_Inst.NT.AddReg