In the previous article "Windows Driver Development-5" We set the callback event Evtiodevicecontrol, we will implement him in this article.
We know we have to make certain arrangements before we read and write, such as synchronization.
The methods for controlling synchronization conventions in WDF are: wdfusbtargetdevicesendcontroltransfersynchronously
NTSTATUS wdfusbtargetdevicesendcontroltransfersynchronously ( [in] wdfusbdevice usbdevice, [In, Optional] wdfrequest Request, [in, optional] pwdf_request_send_options requestoptions, [In] Pwdf_usb_control_setup_packet Setuppacket, [in, optional] pwdf_memory_descriptor memorydescriptor , [out, optional] pulong bytestransferred);
(1) Option request
The settings for the wdf_request_send_options structure.
typedef struct _WDF_REQUEST_SEND_OPTIONS { ULONG Size; ULONG Flags; Longlong Timeout;} Wdf_request_send_options, *pwdf_request_send_options;
1). Initialize
Initialize using the Wdf_request_send_options_init method.
VOID wdf_request_send_options_init ( _out_ pwdf_request_send_options OPTIONS, _in_ ULONG Flags);
2). Set timeout
Use the Wdf_request_send_options_set_timeout method to set the timeout.
VOID wdf_request_send_options_set_timeout ( _inout_ pwdf_request_send_options OPTIONS, _in_ Longlong Timeout);
(2) Package settings
Use the Wdf_usb_control_setup_packet_init_vendor method to set the package.
VOID Wdf_usb_control_setup_packet_init_vendor ( _out_ pwdf_usb_control_setup_packet PACKET, _in_ WDF_ Usb_bmrequest_direction DIRECTION, _in_ wdf_usb_bmrequest_recipient RECIPIENT, _in_ BYTE Request, _in_ USHORT Value, _in_ USHORT Index);
(3) Memory description
1). Memory Request
Use the Wdfrequestretrieveinputmemory method to make the request.
NTSTATUS wdfrequestretrieveinputmemory ( [in] wdfrequest Request, [out] wdfmemory *memory);
2). Initialize the memory handle
Initializes the memory handle using the Wdf_memory_descriptor_init_handle method.
VOID wdf_memory_descriptor_init_handle ( _out_ pwdf_memory_descriptor descriptor, _in_ wdfmemory Memory, _in_opt_ pwdfmemory_offset offsets);
Code:
Step3.c
/*++step3:this steps shows:1) How to create a default parallel queue to receive a IOCTL requests to set Bar graph display. 2) How to retreive memory handle from the requests and use this to send a vendor command to the USB device.--*/#i Nclude "Ntddk.h" #include "wdf.h" #include "prototypes.h" #pragma warning (disable:4200)//Suppress nameless struct/union Warning#pragma Warning (disable:4201)//Suppress nameless struct/union warning#pragma warning (disable:4214)//Suppress Bit field types other than int warning#include "usbdi.h" #pragma warning (default:4200) #pragma warning (default:4201) # pragma warning (default:4214) #include "wdfusb.h" #include "initguid.h" Define_guid (GUID_DEVINTERFACE_OSRUSBFX2,// Generated using Guidgen.exe 0x573e8c73, 0XCB4, 0x4471, 0xa1, 0XBF, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84);//{573E8C73-0CB4 -4471-a1bf-fab26c31d384} #define IOCTL_INDEX 0x800#define file_device_osrusbfx2 0x65500#define Usbfx2lk_set_bargRaph_display 0xd8#define ioctl_osrusbfx2_set_bar_graph_display Ctl_code (FILE_DEVICE_OSRUSBFX2, Ioctl_index + 5, method_buffered, file_write_access) typedef struct _DEVICE_CONTEXT {Wdfusbdevice usbdevice; Wdfusbinterface Usbinterface;} Device_context, *pdevice_context; Wdf_declare_context_type_with_name (Device_context, Getdevicecontext) ntstatusdriverentry (in PDRIVER_OBJECT DriverObject, in punicode_string registrypath) {wdf_driver_config CONFIG; NTSTATUS status; Kdprint (("DriverEntry of Step3\n")); Wdf_driver_config_init (&config, Evtdeviceadd); Status = Wdfdrivercreate (DriverObject, Registrypath, Wdf_no_object_attribute S, &config, Wdf_no_handle); IF (! Nt_success (status) {Kdprint ("Wdfdrivercreate failed 0x%x\n", status)); } return status; Ntstatusevtdeviceadd (in Wdfdriver Driver, in Pwdfdevice_init deviceinit) {wdf_object_attributes Attributes NTSTATUS status; Wdfdevice device; Pdevice_context Pdevcontext; Wdf_pnppower_event_callbacks pnppowercallbacks; Wdf_io_queue_config Ioqueueconfig; Unreferenced_parameter (Driver); Wdf_pnppower_event_callbacks_init (&pnppowercallbacks); Pnppowercallbacks.evtdevicepreparehardware = Evtdevicepreparehardware; Wdfdeviceinitsetpnppowereventcallbacks (DeviceInit, &pnppowercallbacks); Wdf_object_attributes_init_context_type (&attributes, Device_context); Status = Wdfdevicecreate (&deviceinit, &attributes, &device); if (! Nt_success (status) {Kdprint ("Wdfdevicecreate failed 0x%x\n", statUS)); return status; } Pdevcontext = Getdevicecontext (device); Status = Wdfdevicecreatedeviceinterface (device, (Lpguid) &GUID_DEVINTERFACE_OSRUSBFX2, NULL);//Reference String if (! Nt_success (status) {Kdprint ("Wdfdevicecreatedeviceinterface failed 0x%x\n", status)); return status; } wdf_io_queue_config_init_default_queue (&ioqueueconfig, wdfioqueuedispatchparal LEL); Ioqueueconfig.evtiodevicecontrol = Evtiodevicecontrol; Status = Wdfioqueuecreate (device, &ioqueueconfig, Wdf_no_object_attrib UTES, Wdf_no_handle); if (! Nt_success (status)) {Kdprint ("Wdfioqueuecreate failed%! status!\n ", status)); return status; } return status; Ntstatusevtdevicepreparehardware (in Wdfdevice Device, in Wdfcmreslist resourcelist, in Wdfcmreslist Resourcelisttranslated) {NTSTATUS status; Pdevice_context Pdevicecontext; Wdf_usb_device_select_config_params Configparams; Unreferenced_parameter (resourcelist); Unreferenced_parameter (resourcelisttranslated); Pdevicecontext = Getdevicecontext (Device); Create the USB device if it is not already created. if (Pdevicecontext->usbdevice = = NULL) {status = Wdfusbtargetdevicecreate (Device, Wdf_no_object_attributes, &pdevicecontext->usbdevice); if (! Nt_success (status) {Kdprint ("Wdfusbtargetdevicecreate failed 0x%x\n", status)); return status; }} wdf_usb_device_select_config_params_init_single_interface (&configparams); Status = Wdfusbtargetdeviceselectconfig (Pdevicecontext->usbdevice, Wdf_no_object _attributes, &configparams); if (! Nt_success (status) {Kdprint ("Wdfusbtargetdeviceselectconfig failed 0x%x\n", status)); return status; } pdevicecontext->usbinterface = ConfigParams.Types.SingleInterface.ConfiguredUsbInterface; return status;} Voidevtiodevicecontrol (in Wdfqueue Queue, in Wdfrequest Request, in size_t outputbufferlength, in Size_ T inputbufferlength, in ULONG iocontrolcode) {Wdfdevice device; Pdevice_context Pdevcontext; size_t bytestransferred = 0; NTSTATUS status; Wdf_usb_control_setup_packet Controlsetuppacket; Wdf_memory_descriptor Memdesc; Wdfmemory memory; Wdf_request_send_options sendoptions; Unreferenced_parameter (inputbufferlength); Unreferenced_parameter (OuTputbufferlength); device = Wdfioqueuegetdevice (Queue); Pdevcontext = Getdevicecontext (device); Switch (iocontrolcode) {case ioctl_osrusbfx2_set_bar_graph_display:if (Inputbufferlength < sizeof (UCHAR)) { status = Status_buffer_overflow; bytestransferred = sizeof (UCHAR); Break } status = Wdfrequestretrieveinputmemory (Request, &memory); if (! Nt_success (status) {Kdprint ("Wdfrequestretrievememory failed 0x%x", status)); Break } wdf_usb_control_setup_packet_init_vendor (&controlsetuppacket, bmreques Thosttodevice, Bmrequesttodevice, usbfx2lk_s Et_bargraph_display,//Request 0,//Value 0); Index Wdf_memory_deScriptor_init_handle (&memdesc, Memory, NULL); Send the I/O with a timeout to avoid hanging the calling//thread indefinitely. Wdf_request_send_options_init (&sendoptions, Wdf_request_send_option_timeout ); Wdf_request_send_options_set_timeout (&sendoptions, Wdf_rel_timeout_in_ms (100)) ; Status = wdfusbtargetdevicesendcontroltransfersynchronously (Pdevcontext->usbdev Ice, NULL,//Optional wdfrequest &send Options,//Pwdf_request_send_options &controlsetuppacket, &memdesc, (Pulong) &bytestransferred); if (! Nt_success (status) {Kdprint ("Sendcontroltransfer failed 0x%x", status)); Break } break; Default:status = Status_invalid_device_request; Break } wdfrequestcompletewithinformation (Request, status, Bytestransferred); return;}
Windows Driver Development-6