一个关于WDF驱动开打的问题

有个关于WDF的问题,因为之前玩游戏,我买了一个游戏外设,我在尝试给它写个过滤驱动,我使用的是WDF框架,驱动中创建了一个并行队列,并实现了其EvtIoRead例程。在该例程中,我想对原始Read请求执行完成操作,然后创建一个新的Read请求,我根据书上所示,通过 WdfRequestCreate,WdfMemoryCreate以及WdfIoTargetFormatRequestForRead等创建并格式化了一个新请求,但是我在使用WdfIoTargetFormatRequestForRead格式化请求后,通过调用WdfRequestGetParameters获取请求的参数信息,但是我发现 ,其类型却是WdfRequestTypeCreate,这种是什么什么原因呢 ?

这是因为在WDF中,当你调用WdfIoTargetFormatRequestForRead格式化一个请求以后,WDF实际上会重新创建一个新的请求,原来的请求会被释放。所以当你调用WdfRequestGetParameters获取请求的参数时,得到的请求类型是WDFRequestTypeCreate,而不是WDFRequestTypeRead。
解决方法是,在格式化新请求前,你需要先保存原始读请求的参数信息,然后在格式化新请求时传入保存的参数信息。具体可以这样做:

  1. 在EvtIoRead中,首先调用WdfRequestGetParameters获取原始读请求的参数,保存下来:
    c
    WDF_REQUEST_PARAMETERS params;
    WDF_REQUEST_REUSE_PARAMS reuseParams;
    WDF_REQUEST_REUSE_PARAMS_INIT(&reuseParams);
    status = WdfRequestGetParameters(Request, &params);
  2. 然后创建新请求,并且传入reuseParams来重用原始请求的参数:
    c
    WDF_OBJECT_ATTRIBUTES attributes;
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.EvtCleanupCallback = EvtChildCleanupCb;
    WDFREQUEST newRequest;
    status = WdfRequestCreate(&attributes, Request, &newRequest);
    status = WdfIoTargetFormatRequestForRead(Target, newRequest, &reuseParams);
  3. 这时,新请求的类型将仍然是WDFRequestTypeRead,你调用WdfRequestGetParameters获取的参数也和原始读请求一致。