DeviceIoControl 用于和应用层和驱动层之间的数据传送。是应用层调用驱动文件(SYS)中的控制请求的重要方法。

今天在使用DeviceIoControl 调用一个自行编写的驱动程序的使用返回值总是FALSE,使用GetLastError获得错误码为87

这个错误码对应的错误是:参数不正确。可是应用层的参数怎么看都没有问题。最终发现是驱动层的编码出现了问题。

在驱动层的分发函数中,在指定的控制请求分支,完成自定义的请求业务逻辑之后应该调用:

status=irp->IoStatus.Status;

来返回一个错误码,然后调用
IoCompleteRequest(irp,IO_NO_INCREMENT);

来结束对控制请求的处理

而发生错误的处理方法使用了

IoCallDriver(s_nextobj,irp);

将请求继续传递给了后续的驱动对象,这是系统的驱动对象

由于这个控制请求是自定义的,系统的驱动对象中没有这个处理分支,而一般的处理方法就是,对没有的分支返回参数错误。即是控制请求这个参数传递错误。

由此可以总结出在驱动层编写自定义的消息请求时,处理完成之后不能再路由到系统的驱动中,因为对控制请求这个参数的判断是以最后一个处理来判断的。使用IoCallDriver(s_nextobj,irp);不但在自己编写的代码中处理白做了,返回了错误码,同时也接受不到返回信息。因为这里对irpsp的处理被后续的处理覆盖了。

在来重新审视:

BOOL WINAPI DeviceIoControl(
  __in          HANDLE hDevice,
  __in          DWORD dwIoControlCode,//自定义的控制码就是这一项
  __in          LPVOID lpInBuffer,
  __in          DWORD nInBufferSize,
  __out         LPVOID lpOutBuffer,
  __in          DWORD nOutBufferSize,
  __out         LPDWORD lpBytesReturned,
  __in          LPOVERLAPPED lpOverlapped
);

这里遇到的问题只是针对参数dwIoControlCode的错误的解决,这个问题也比较隐蔽。

正确的调用当然还要保证其它的所有的参数都是正确的。在调试的时候要特别关注错误码,和对代码进行例行的分析。

附,我遇到这个问题的驱动程序的分发函数的代码,是正在调试中的代码,所以比较乱:

这里是一个串口的Filter驱动,对读写请求都要路由到系统,而对于自定义的消息一定要调用IoCompleteRequest完成请求

NTSTATUS ccpDispatch(PDEVICE_OBJECT device,PIRP irp) { PIO_STACK_LOCATION irpsp=IoGetCurrentIrpStackLocation(irp); NTSTATUS status; ULONG len; ULONG j; PUCHAR buffer=NULL; ULONG dwInputBufferLength; ULONG dwOutputBufferLength; PVOID pvIOBuffer; pvIOBuffer = irp->AssociatedIrp.SystemBuffer; dwInputBufferLength = irpsp->Parameters.DeviceIoControl.InputBufferLength; dwOutputBufferLength = irpsp->Parameters.DeviceIoControl.OutputBufferLength; switch (irpsp->MajorFunction) { case IRP_MJ_POWER: PoStartNextPowerIrp(irp); IoSkipCurrentIrpStackLocation(irp); return PoCallDriver(s_nextobj,irp); case IRP_MJ_WRITE: len=irpsp->Parameters.Write.Length; if (irp->MdlAddress!=NULL) { buffer=(PUCHAR)MmGetSystemAddressForMdlSafe(irp->MdlAddress,NormalPagePriority); } else { buffer=(PUCHAR)irp->UserBuffer; } if (buffer==NULL) { buffer=(PUCHAR)irp->AssociatedIrp.SystemBuffer; } for(j=0;j<len;++j) { DbgPrint("comcap:Send Data:%2x/r/n",buffer[j]); } break; case IRP_MJ_READ: IoCopyCurrentIrpStackLocationToNext(irp); IoSetCompletionRoutine(irp,ReadComplete,device,TRUE,TRUE,TRUE); return IoCallDriver(s_nextobj,irp); case IRP_MJ_DEVICE_CONTROL: DbgPrint("IRP_MJ_DEVICE_CONTROL/n"); switch(irpsp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_WINIO_SETDEVICE: DbgPrint("IOCTL_WINIO_SETDEVICE/n"); DbgPrint("Bytes Received:%d/n",dwInputBufferLength); DbgPrint("Received:%ws/n",pvIOBuffer); //if (dwInputBufferLength!=0) //{ // ccpAttachCom(s_driver,L"//Device//com0com11"); //} status=irp->IoStatus.Status; IoCompleteRequest(irp,IO_NO_INCREMENT); return status; case IOCTL_WINIO_READ://这个是自定义的,不要再路由给系统驱动 DbgPrint("IOCTL_WINIO_READ/n"); memcpy(pvIOBuffer,L"aaa",sizeof(L"aaa")); irp->IoStatus.Information=sizeof(L"aaa"); status=irp->IoStatus.Status; IoCompleteRequest(irp,IO_NO_INCREMENT); return status; default: DbgPrint("Invalid Request:%0xx/n",irpsp->Parameters.DeviceIoControl.IoControlCode); } break; } IoSkipCurrentIrpStackLocation(irp); status=IoCallDriver(s_nextobj,irp); DbgPrint("Dispath Result:%d/n",status); return status; //err irp->IoStatus.Information=0; irp->IoStatus.Status=STATUS_INVALID_PARAMETER; IoCompleteRequest(irp,IO_NO_INCREMENT); return status; }

DeviceIoControl 错误码:error code 87 问题解决相关推荐

  1. KMS验证 错误码ERROR CODE0xC004F074

    KMS验证 错误码ERROR CODE:0xC004F074 原因 无法连接KMS服务器 解决方案 使用管理员身份打开命令行. 移动到C:\Program Files (x86)\Microsoft ...

  2. MySQL 报错:Error Code: 1264. Out of range value for column ‘final‘ at row 5

    初学MySQL,总是遇到各种各样的问题,今天在练习用子查询更新数据时,报错Error Code: 1264. Out of range value for column 'final' at row ...

  3. sql报错:Error Code: 1292. Incorrect date value: ‘1978‘ for column ‘video_date‘ at row 1记录

    报错:Error Code: 1292. Incorrect date value: '1978' for column 'video_date' at row 1 记录 1.产生原因 写了一个插入数 ...

  4. ADS1.2出现erro starting external process,Process error code 87(0x57)参数错误

    系统是win7的,做了一个简单的程序 make之后没有错误,然后debug,弹出窗口error starting external process process error code 87.(0x5 ...

  5. Ldap同步报错 [LDAP: error code 21 - 00000057: LdapErr: DSID-0C090EC7

    Ldap同步报错 [LDAP: error code 21 - 00000057: LdapErr: DSID-0C090EC7 异常: javax.naming.directory.InvalidA ...

  6. 达梦数据库报错“[警告]Error Code:-70037,字符串不完整”

    [问题描述]: 使用管理工具或dexp导出数据的时候报"[警告]Error Code:-70037,字符串不完整",导致表的数据没有导出或者导出的数据不完整.如下图所示: [问题解 ...

  7. 生成MySQL数据库表报错:Error Code: 1022. Can't write; duplicate key in table '#sql-e88_23'

    生成MySQL数据库表报错SQL: alter table position add constraint FK_Reference_1 foreign key (partner_id)       ...

  8. 执行update和delete的SQL语句时,报错:Error Code: 1175. You are using safe update mode and you tried to update a

    执行SQL语句时,报错: 13:36:42 delete from users where username='lisi' Error Code: 1175. You are using safe u ...

  9. Python安装过程报错The error code is 2503的解决方案

    版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 问题描述 在Win10设备中安装Python3.7.2的过程中报错:The error cod ...

最新文章

  1. 密码学研究-数字签名
  2. EPSON机器人_SPEL+语言
  3. PYTHON __main__
  4. Linux 升级 Python 至 3.x
  5. 路由器固件下的小试牛刀,与漏洞相关的经验分享
  6. jQuery EasyUI API 中文文档 - 进度条
  7. 摩尔投票法(力扣- -229. 求众数 II)
  8. Bigmart数据集销售预测
  9. cmd中无法连接MySQL
  10. ionic 幻灯指令 ion-slide-box
  11. 【转】女人最想要的是什么
  12. c语言100道经典编程题,100道经典C语言编程题
  13. pdf怎么解除限制?如何解密?一步解决
  14. 机器学习笔记 - EfficientNet论文解读
  15. python有什么颜色_Python中常见颜色记录
  16. 首份财报营收增长扭亏为盈,为何怪兽充电的出路依旧“迷雾重重”
  17. 简易计算器,你值得拥有
  18. 51单片机c语言工作手册,51单片机C语言编程手册
  19. Mean Average Precision(MAP):平均精度均值
  20. SEO 搜索引擎优化(Google 排名)

热门文章

  1. Windows10远程桌面无法复制粘贴问题
  2. springboot+jsp人事工资管理系统 java ssm maven
  3. matlab r2020b百度网盘下载链接及安装过程
  4. 微信小程序swiper上下滑动卡顿
  5. 如果显示直播连接不成功问题
  6. 【测试】用Chrome在电脑上模拟微信浏览器
  7. 《计算机软件保护条例》
  8. 爬虫入门教程 | 使用selenium爬取微博热门数据
  9. 金蝶k3单据编码规则_编码规则
  10. mysql数据库修复_MySQL数据库修复方法(MyISAM/InnoDB)