registrypath) { pdevice_object deviceobject; ntstatus status; unicode_string uninamestring, unidosstring; // 为iopm分配内存 piopm = mmallocatenoncachedmemory(sizeof(iopm)); if (piopm == 0) { return status_insufficient_resources; } // iopm全部初始化为0(允许访问所有端口) rtlzeromemory(piopm, sizeof(iopm)); // 将iopm加载到当前进程 ke386iosetaccessprocess(psgetcurrentprocess(), 1); ke386setioaccessmap(1, piopm); // 指定驱动名字 rtlinitunicodestring(&uninamestring, namebuffer); rtlinitunicodestring(&unidosstring, dosnamebuffer); // 创建设备 status = iocreatedevice(driverobject, 0, &uninamestring, file_device_myport, 0, false, &deviceobject); if (!nt_success(status)) { return status; } // 创建win32应用程序需要的符号连接 status = iocreatesymboliclink (&unidosstring, &uninamestring); if (!nt_success(status)) { return status; } // 指定驱动程序有关操作的模块入口(函数指针) // 涉及以下两个模块:myportdispatch和myportunload driverobject->majorfunction[irp_mj_create] = driverobject->majorfunction[irp_mj_close] = driverobject->majorfunction[irp_mj_device_control] = myportdispatch; driverobject->driverunload = myportunload; return status_success; } // irp处理模块 ntstatus myportdispatch(in pdevice_object deviceobject, in pirp irp) { pio_stack_location irpstack; ulong dwinputbufferlength; ulong dwoutputbufferlength; ulong dwiocontrolcode; pulong pviobuffer; ntstatus ntstatus; // 填充几个默认值 irp->iostatus.status = status_success; // 返回状态 irp->iostatus.information = 0; // 输出长度 irpstack = iogetcurrentirpstacklocation(irp); // get the pointer to the input/output buffer and it's length // 输入输出共用的缓冲区 // 因为我们在ioctl中指定了method_buffered, pviobuffer = irp->associatedirp.systembuffer; switch (irpstack->majorfunction) { case irp_mj_create: // 与win32应用程序中的createfile对应 break; case irp_mj_close: // 与win32应用程序中的closehandle对应 break; case irp_mj_device_control: // 与win32应用程序中的deviceiocontrol对应 dwiocontrolcode = irpstack->parameters.deviceiocontrol.iocontrolcode; switch (dwiocontrolcode) { // 我们约定,缓冲区共两个dword,第一个dword为端口,第二个dword为数据 // 一般做法是专门定义一个结构,此处简单化处理了 case ioctl_myport_read_byte: // 从端口读字节 pviobuffer[1] = _inp(pviobuffer[0]); irp->iostatus.information = 8; // 输出长度为8 break; case ioctl_myport_write_byte: // 写字节到端口 _outp(pviobuffer[0], pviobuffer[1]); break; default: // 不支持的ioctl irp->iostatus.status = status_invalid_parameter; } } ntstatus = irp->iostatus.status; iocompleterequest (irp, io_no_increment); return ntstatus; } // 删除驱动 void myportunload(in pdriver_object driverobject) { unicode_string unidosstring; if(piopm) { // 释放iopm占用的空间 mmfreenoncachedmemory(piopm, sizeof(iopm)); } rtlinitunicodestring(&unidosstring, dosnamebuffer); // 删除符号连接和设备 iodeletesymboliclink (&unidosstr