There are many methods to compile the USB-to-COM driver. Recently, the most common method on the network is to virtualize A Comport and open a USB device at the first test of COM.
When the USB serial comport driver processes IRQ such as write and read, it actually reads and writes the USB device driver. The read and write method directly uses the zwreadfile and zwwritefile functions. however, the real implementation is not so simple. The real implementation is to open up a thread and a large buffer. The thread is used to read data from the USB device in a timely manner and store the data in the buffer zone. when the upper-layer application sends read IRP (irp_mj_read) to this virtual comport, it can directly read data from this buffer zone and return it. of course, do not forget to handle timeout issues.
Therefore, the USB-to-COM driver needs to load two drivers when loading the INF file. One is the USB driver, which corresponds to the vid and PID of the USB device, and the other is the com virtual driver, set the com slogan accordingly. key codes are listed as follows;
- Create a comport device object
Status = iocreatedevice (driverobject, <br/> sizeof (vcp4usb_device_extension), <br/> & ntdevicename, <br/> file_device_serial_port, <br/> 0, <br/> true, // exclusive <br/> & fdo );
- Obtain the USB device name to enable the device.
Status = iogetdeviceinterfaces (pguid, null, 0, & psymlink); <br/> dprint (dbg_other, ("iogetdeviceinterface return % d/N", status )); </P> <p> If (status = status_invalid_device_request) | (* psymlink = NULL) <br/> return status_unsuccessful; </P> <p> pcur = psymlink; <br/> instancecur = 0; <br/> Status = status_invalid_info_class; <br/> while (* pcur! = NULL) <br/>{< br/> P = pcur; <br/> for (size = 0; * P! = NULL; size ++) <br/> P ++; <br/> dprint (dbg_other, ("no. % d: size = % d/N ", instancecur, size); <br/> dprint (dbg_other, (" Name: % WS/N ", pcur )); <br/> If (instance = instancecur) <br/> {<br/> If (rtlcomparememory (pcur, pprefix, prefixlength) = prefixlength) <br/>{< br/> dprint (dbg_other, ("find OK/N"); <br/> devname-> maximumlength = size * sizeof (wchar ); <br/> devname-> buffer = (pwstr) exallocatepool (nonpagedpool, (size + 1) * sizeof (wchar )); <br/> If (devname-> buffer = NULL) <br/> {<br/> dprint (dbg_other, ("allocate devname error. /n "); <br/> Status = status_insufficient_resources; <br/> break; <br/>}< br/> rtlcopymemory (devname-> buffer, pcur, (size + 1) * sizeof (wchar); <br/> rtlinitunicodestring (devname, devname-> buffer); <br/> Status = STATUS_SUCCESS; <br/> break; // find OK and break <br/>}< br/> pcur + = size + 1; // skip last null <br/> instancecur ++; <br/> If (instancecur> = 2) // For debug <br/> break; <br/>}</P> <p> exfreepool (psymlink ); <br/> return status;
- Open the port of the USB device
Curstatus = getusbdevicename (& usbdevicename, & guid_class_xxxx_bulk, <br/> & xxxx_symlink_cmpstr, xxxx_symlink_strlen, 0); <br/> If (! Hread) <br/> rdstatus = createfile (& hread, & usbdevicename, l "// pipe0", 6, generic_read); <br/> If (! Hwrite) <br/> wtstatus = createfile (& hwrite, & usbdevicename, l "// pipe1", 6, generic_write );
The processing of other drivers is normal, so I will not introduce them here!