Beispiel #1
0
// EvtDeviceD0Entry event callback must perform any operations that are necessary before the specified device is used.
// Called every time the hardware needs to be initialized/reinitialized.
// This function is not marked pageable because this function is in the device power up path. 
// This function runs at PASSIVE_LEVEL, even though it is not paged.
//
NTSTATUS HidFx2EvtDeviceD0Entry(_In_  WDFDEVICE hDevice, _In_ WDF_POWER_DEVICE_STATE previousState)
{
    PDEVICE_EXTENSION   pDevContext = NULL;
    NTSTATUS            status = STATUS_SUCCESS;
    unsigned char       bSwitchState = 0;
    unsigned char       bMode = 0;

    pDevContext = GetDeviceContext(hDevice);

    TraceVerbose(DBG_PNP, "(%!FUNC!) Enter - coming from %S\n", DbgDevicePowerString(previousState));

    SendVendorCommand(hDevice, HIDFX2_SET_BARGRAPH_DISPLAY, BARGRAPH_LED_ALL_OFF);

    // Retrieve the current switch state and store it in device context
    status = HidFx2GetSwitchState(hDevice, &bSwitchState);
    if (NT_SUCCESS(status))
    {
        // Left most switches define Mode
        bMode = bSwitchState & MODE_SELECTION_BUTTONS_BIT_MASK;
        switch (bMode)
        {
        case SWITCHPACK_SELECTION_FOR_MODE2:
            pDevContext->driverMode = DM_BUTTON_AND_LED;
            SendVendorCommand(hDevice, HIDFX2_SET_7SEGMENT_DISPLAY, SEGMENT_DISPLAY_2);
            break;
        case SWITCHPACK_SELECTION_FOR_MODE3:
            pDevContext->driverMode = DM_SLIDER_SWITCH;
            SendVendorCommand(hDevice, HIDFX2_SET_7SEGMENT_DISPLAY, SEGMENT_DISPLAY_3);
            break;
        case SWITCHPACK_SELECTION_FOR_MODE4:
            pDevContext->driverMode = DM_SLIDER_SWITCH_AND_LED;
            SendVendorCommand(hDevice, HIDFX2_SET_7SEGMENT_DISPLAY, SEGMENT_DISPLAY_4);
            break;
        case SWITCHPACK_SELECTION_FOR_MODE5:
            pDevContext->driverMode = DM_LED_ONLY;
            SendVendorCommand(hDevice, HIDFX2_SET_7SEGMENT_DISPLAY, SEGMENT_DISPLAY_5);
            break;
        default:
            pDevContext->driverMode = DM_BUTTON;
            SendVendorCommand(hDevice, HIDFX2_SET_7SEGMENT_DISPLAY, SEGMENT_DISPLAY_1);
            break;
        }

        pDevContext->bCurrentSwitchState = bSwitchState;

        // Start the target.  This will start the continuous reader
        status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(pDevContext->hInterruptPipe));
        if (NT_SUCCESS(status))
        {
            pDevContext->fIsPowerUpSwitchState = TRUE;
        }
    }
    else
    {
        TraceErr(DBG_PNP, "(%!FUNC!) Failed to get current switch state, status: %!STATUS!\n", status);
    }

    TraceVerbose(DBG_PNP, "(%!FUNC!) Exit, status: %!STATUS!\n", status);
    return status;
}
NTSTATUS HidFx2SetOutput(_In_ WDFREQUEST hRequest)
{
    NTSTATUS                    status = STATUS_SUCCESS;
    PHID_XFER_PACKET            pTransferPacket = NULL;
    WDF_REQUEST_PARAMETERS      params;
    PHIDFX2_IO_REPORT           pOutputReport = NULL;
    WDFDEVICE                   hDevice;

    PAGED_CODE();

    TraceVerbose(DBG_IOCTL, "(%!FUNC!) Enter\n");

    hDevice = WdfIoQueueGetDevice(WdfRequestGetIoQueue(hRequest));

    WDF_REQUEST_PARAMETERS_INIT(&params);
    WdfRequestGetParameters(hRequest, &params);

    if (params.Parameters.DeviceIoControl.InputBufferLength < sizeof(HID_XFER_PACKET))
    {
        status = STATUS_BUFFER_TOO_SMALL;
        TraceErr(DBG_IOCTL, "(%!FUNC!) Userbuffer is small %!STATUS!\n", status);
        return status;
    }

    pTransferPacket = (PHID_XFER_PACKET) WdfRequestWdmGetIrp(hRequest)->UserBuffer;
    if (pTransferPacket == NULL)
    {
        status = STATUS_INVALID_DEVICE_REQUEST;
        TraceErr(DBG_IOCTL, "(%!FUNC!) Irp->UserBuffer is NULL %!STATUS!\n", status);
        return status;
    }

    if (pTransferPacket->reportBufferLen == 0)
    {
        status = STATUS_BUFFER_TOO_SMALL;
        TraceErr(DBG_IOCTL, "(%!FUNC!) HID_XFER_PACKET->reportBufferLen is 0, %!STATUS!\n", status);
        return status;
    }

    if (pTransferPacket->reportBufferLen < sizeof(UCHAR))
    {
        status = STATUS_BUFFER_TOO_SMALL;
        TraceErr(DBG_IOCTL, "(%!FUNC!) HID_XFER_PACKET->reportBufferLen is too small, %!STATUS!\n", status);
        return status;
    }

    if (pTransferPacket->reportId != GENERIC_DESKTOP_REPORT_ID)
    {
        status = STATUS_INVALID_DEVICE_REQUEST;
        TraceErr(DBG_IOCTL, "(%!FUNC!) Incorrect report ID, %!STATUS!\n", status);
        return status;
    }

    pOutputReport = (PHIDFX2_IO_REPORT)pTransferPacket->reportBuffer;

    if (pOutputReport->bData == 0)
    {
        status = SendVendorCommand(hDevice, HIDFX2_SET_BARGRAPH_DISPLAY, BARGRAPH_LED_ALL_OFF);
    }
    else
    {
        status = SendVendorCommand(hDevice, HIDFX2_SET_BARGRAPH_DISPLAY, BARGRAPH_LED_ALL_ON);
    }

    TraceVerbose(DBG_IOCTL, "(%!FUNC!) Exit status %!STATUS!\n", status);
    return status;
}