After learning to drive development for a while, I tried to start learning from the simplest driver development. I tried to write the simplest serial port filter driver, but many attempts failed, A blue screen is always loaded. After reading the online examples, they all adopt ioattachdevicetodevicestack, while I use ioattachdevice. Now I want to share the code on the Internet in the simplest form. I hope beginners can benefit from it. I will introduce it in detail in the following blog.
# Include <ntddk. h> # include <string. h> static pdevice_object m_fltobj; static pdevice_object m_topobj; // defines a read completion handler ntstatus fengreadcomplete (in pdevice_object completion, in piririririrp, in pvoid context) {pio_stack_location irpsp; ulong I; irpsp = iogetcurrentirpstacklocation (IRP); If (nt_success (IRP-> iostatus. status) {puchar Buf = (puchar) IRP-> associatedirp. systembuffer; dbuplint ("driver1 read:"); for (I = 0; I <IRP-> iostatus. information; I ++) {dbuplint ("% 02x,", Buf [I]);} dbuplint ("\ r \ n");} If (IRP-> pendingreturned) iomarkirppending (IRP); Return IRP-> iostatus. status;} ntstatus driver=dispatchdevicecontrol (in pdevice_object deviceobject, in pirp) {ulong J; ntstatus status = STATUS_SUCCESS; pio_stack_location irpsp = iogetcurrentirpstacklocation (IRP ); dbuplint ("received IRP \ r \ n"); If (m_fltobj = deviceobject) {if (Irpsp-> majorfunction = irp_mj_power) {postartnextpowerirp (IRP); reset (IRP); Return pocalldriver (m_topobj, IRP);} else if (irpsp-> majorfunction = irp_mj) {puchar Buf = NULL; If (IRP-> mdladdress! = NULL) BUF = (puchar) mmgetsystemaddressformdlsafe (IRP-> mdladdress, normalpagepriority); elsebuf = (puchar) IRP-> userbuffer; If (BUF = NULL) BUF = (puchar) IRP-> associatedirp. systembuffer; dbuplint ("driver1 write:"); For (j = 0; j <irpsp-> parameters. write. length; j ++) {dbuplint ("% 02x,", Buf [J]);} dbuplint ("\ r \ n ");} else if (irpsp-> majorfunction = irp_mj_read) {iocopycurrentirpstacklocationtonext (IRP); iosetcompl Etionroutine (IRP, fengreadcomplete, deviceobject, true); Return iocalldriver (m_topobj, IRP);} ioskipcurrentirpstacklocation (IRP); Return iocalldriver (m_topobj, IRP );} IRP-> iostatus. information = 0; IRP-> iostatus. status = status_invalid_parameter; iocompleterequest (IRP, io_no_increment); Return status;} void driver1_driverunload (in pdriver_objectdriverobject) {large_integer ilval; If (m_topobj! = NULL) iodetachdevice (m_topobj); ilval. quadpart = 5*1000*1000 * (-10); // 5 seconds kedelayexecutionthread (kernelmode, false, & ilval); If (m_fltobj! = NULL) iodeletedevice (m_fltobj) ;}# Pragma code_seg ("init") ntstatus DriverEntry (in out pdriver_object driverobject, in bytes registrypath) {size_t I; ntstatus status; unicode_string namestr; pfile_object fileobj = NULL; pdevice_object upload bj = NULL; dbgbreakpoint (); for (I = 0; I <bytes; I ++) {driverobject-> majorfunction [I] = driver1_dispatchdevicecontrol ;} driverobject-> driverunload = Driver1_driverunload; rtlinitunicodestring (& namestr, l "\ device \ serial0"); status = iogetdeviceobjectpointer (& namestr, file_all_access, & fileobj, & cmdbj ); if (status = STATUS_SUCCESS) obdereferenceobject (fileobj); If (status = STATUS_SUCCESS) {ntstatus status; pdevice_object topdev = NULL; dbuplint ("successfully opened COM1 \ r \ n"); status = iocreatedevice (driverobject, 0, null, 1_bj-> devicetype, 0, false, & m_flto BJ); If (status! = STATUS_SUCCESS) return status; If (cmdbj-> flags & packages) m_fltobj-> flags | = empty; If (cmdbj-> flags & do_direct_io) m_fltobj-> flags | = do_direct_io; if (character BJ-> Characteristics & features) m_fltobj-> characteristics | = character; m_fltobj-> flags | = do_power_pagable; topdev = ioattachdevicetodevicestack (m_fltobj, character BJ ); if (topdev = NULL) {iodeletedevice (m_fltob J); m_fltobj = NULL; status = status_unsuccessful; return status;} dbuplint ("DriverEntry successful \ r \ n"); m_topobj = topdev; m_fltobj-> flags & = ~ Do_device_initializing; return STATUS_SUCCESS ;}
The simplified processing of IRP requests has become the following form. I want to tell you a simple framework for driving filtering.
# Include <ntddk. h> # include <string. h> static pdevice_object m_fltobj; static pdevice_object m_topobj; ntstatus callback (in pdevice_object deviceobject, in pirirp) {ntstatus status = STATUS_SUCCESS; pio_stack_location irpsp = downlink (IRP ); dbuplint ("received IRP \ r \ n"); ioskipcurrentirpstacklocation (IRP); Return iocalldriver (m_topobj, IRP);} void driver1_driverunload (in P Driver_objectdriverobject) {large_integer ilval; If (m_topobj! = NULL) iodetachdevice (m_topobj); ilval. quadpart = 5*1000*1000 * (-10); // 5 seconds kedelayexecutionthread (kernelmode, false, & ilval); If (m_fltobj! = NULL) iodeletedevice (m_fltobj) ;}# Pragma code_seg ("init") ntstatus DriverEntry (in out pdriver_object driverobject, in bytes registrypath) {size_t I; ntstatus status; unicode_string namestr; pfile_object fileobj = NULL; pdevice_object upload bj = NULL; dbgbreakpoint (); for (I = 0; I <bytes; I ++) {driverobject-> majorfunction [I] = driver1_dispatchdevicecontrol ;} driverobject-> driverunload = Driver1_driverunload; rtlinitunicodestring (& namestr, l "\ device \ serial0"); status = iogetdeviceobjectpointer (& namestr, file_all_access, & fileobj, & cmdbj ); if (status = STATUS_SUCCESS) obdereferenceobject (fileobj); If (status = STATUS_SUCCESS) {ntstatus status; pdevice_object topdev = NULL; dbuplint ("successfully opened COM1 \ r \ n"); status = iocreatedevice (driverobject, 0, null, 1_bj-> devicetype, 0, false, & m_flto BJ); If (status! = STATUS_SUCCESS) return status; If (cmdbj-> flags & packages) m_fltobj-> flags | = empty; If (cmdbj-> flags & do_direct_io) m_fltobj-> flags | = do_direct_io; if (character BJ-> Characteristics & features) m_fltobj-> characteristics | = character; m_fltobj-> flags | = do_power_pagable; topdev = ioattachdevicetodevicestack (m_fltobj, character BJ ); if (topdev = NULL) {iodeletedevice (m_fltob J); m_fltobj = NULL; status = status_unsuccessful; return status;} dbuplint ("DriverEntry successful \ r \ n"); m_topobj = topdev; m_fltobj-> flags & = ~ Do_device_initializing; return STATUS_SUCCESS ;}