You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Win10下WinDivert报错997:TCP三次握手及RST包规避方案咨询

解决WinDivert错误997(重叠I/O操作正在进行中)的排查方案

这种WinDivert错误997的问题我之前做网络路由项目时也碰到过好几次,结合你描述的情况——旧版本突然失效、重启驱动后WinDivertOpen正常但WinDivertSend/WinDivertSendEx仍报错,咱们可以从这几个核心方向排查解决:

1. 重叠I/O上下文未正确重置或清理

WinDivert底层依赖Windows的重叠I/O模型,如果之前的I/O操作(比如上一次的发送/接收请求)没有完全完成,或者对应的OVERLAPPED结构体被重复使用但未重置,就会触发这个冲突错误。尤其是旧版本之前正常现在失效,大概率是系统或进程残留了未完成的I/O请求。

  • 修复步骤
    • 每次调用WinDivertSend/WinDivertSendEx前,务必用ZeroMemory(&overlapped, sizeof(OVERLAPPED))重置OVERLAPPED结构体,绝对不要复用还在等待完成的结构体。
    • 关闭WinDivert句柄时,先调用CancelIoEx终止所有关联的未完成I/O请求,再执行WinDivertClose,避免驱动端残留无效请求。

2. 驱动服务未彻底重置

有时候单纯重启电脑并没有完全清理WinDivert驱动的内部状态,比如驱动的I/O队列里还积压着未处理的请求,导致新进程调用发送接口时触发冲突。

  • 修复步骤
    • 管理员权限打开命令提示符,执行以下命令彻底重启驱动服务:
      sc stop WinDivert
      sc start WinDivert
      
    • 用Process Explorer或类似工具检查是否有其他进程在使用WinDivert.sys,如果有,关闭这些进程后再测试——多个进程共享WinDivert驱动时,很容易出现I/O操作冲突。

3. 异步I/O的同步逻辑存在漏洞

如果你的代码中使用了异步I/O模式,但没有正确等待前一次操作完成就发起新的请求,比如调用WinDivertSend后立刻再次调用,或者没有用GetOverlappedResult/WaitForSingleObject确认操作结束,就会触发错误997。

  • 修复示例
    确保每次发送操作都等待完成后再继续:
    OVERLAPPED overlapped = {0};
    BOOL result = WinDivertSend(divertHandle, packetBuffer, packetLength, NULL, &overlapped);
    
    if (!result) {
        DWORD err = GetLastError();
        if (err == ERROR_IO_PENDING) {
            DWORD bytesSent;
            // 等待异步操作完成,第二个TRUE表示阻塞等待
            GetOverlappedResult(divertHandle, &overlapped, &bytesSent, TRUE);
        } else {
            // 处理其他错误
            printf("WinDivertSend failed with error: %d\n", err);
        }
    }
    
    如果是批量发送场景,要为每个请求分配独立的OVERLAPPED结构体,不要共用一个。

4. 系统更新导致的兼容性问题

最近的Windows系统更新可能修改了网络栈的行为,或者旧版本的WinDivert驱动与新系统组件不兼容,导致原本正常的代码失效。

  • 修复步骤
    • 下载WinDivert的最新稳定版本,替换项目中的驱动文件(WinDivert.sys)和静态库/动态库,重新编译项目后测试。
    • 检查WinDivert的官方文档,确认是否有针对你当前Windows版本的适配注意事项。

内容的提问来源于stack exchange,提问作者ThisIsNotMyThirdAccount

火山引擎 最新活动