并行调用VhfReadReportSubmit会导致堆栈溢出BSOD

问题描述

我正在使用vhf framework为虚拟HID设备编写Windows kmdf驱动程序。设备会接收提交给它的所有写报告,对其进行稍加修改,然后通过VhfReadReportSubmit将其吐出。不幸的是,当多个报告同时出现时,我得到了堆栈溢出的BSOD。我应该注意,我依靠vhf框架来缓冲提交的报告(这是默认设置),因此,根据文档,调用VhfReadReportSubmit函数应该没有任何限制。

AddDevice中调用VhfCreate的相关代码:

    DeviceCtx* ctx = getCtx(device);
    ctx->parallel_ops_counter = 0;
    

    VHF_CONFIG_INIT(&vhfCfg,WdfDeviceWdmGetDeviceObject(device),sizeof(report_desc),report_desc);
    vhfCfg.VhfClientContext = ctx;
    vhfCfg.OperationContextSize = MAX_HID_REPORT_SIZE;
    vhfCfg.EvtVhfAsyncOperationWriteReport = ForwardReport;
    vhfCfg.VendorID = VENDOR_ID;
    vhfCfg.ProductID = PRODUCT_ID;

    status = VhfCreate(&vhfCfg,&ctx->vhfHandle);

ForwardReport函数,当有人向设备提交写报告时调用该函数(为简单起见,我删除了一些跟踪消息):

// FIXME: Submitting a lot of HID reports in parallel leads to a bugcheck (BSOD)
void ForwardReport(DeviceCtx* devCtx,VHFOPERATIONHANDLE op,void* opCtx,PHID_XFER_PACKET report) {
    UNREFERENCED_PARAMETER(opCtx);
    NTSTATUS status;
    HID_XFER_PACKET packet_copy;

    // Prevent BSOD (STACK_OVERFLOW) which for some unknown reason
    // happens when too many HID reports are submitted in parallel
    if (devCtx->parallel_ops_counter > MAX_PARALLEL_OPS) {
        VhfAsyncOperationComplete(op,STATUS_INSUFFICIENT_RESOURCES); // STATUS_INTERNAL_ERROR
        return;
    }
    
    devCtx->parallel_ops_counter++;

    // Copy the report to a temporary buffer
    if (report->reportBufferLen > MAX_HID_REPORT_SIZE) {
        VhfAsyncOperationComplete(op,STATUS_BUFFER_OVERFLOW);
        return;
    }
    packet_copy.reportBuffer = opCtx;
    packet_copy.reportBufferLen = report->reportBufferLen;
    packet_copy.reportId = report->reportId;
    memcpy(opCtx,report->reportBuffer,report->reportBufferLen);
    
    // Change the report channel
    Packet* pkt = (Packet*)(packet_copy.reportBuffer);
    if (IS_CLIENT_CHANNEL(pkt->channel)) {
        pkt->channel = ENCODE_CLIENT_CHANNEL(pkt->channel);
    } else if(IS_CONTROL_CHANNEL(pkt->channel)) {
        pkt->channel = DECODE_CLIENT_CHANNEL(pkt->channel);
    }
    else if (pkt->channel == BROADCAST_CHANNEL_SERVER) {
        pkt->channel = BROADCAST_CHANNEL_CLIENT;
    }
    else if (pkt->channel == BROADCAST_CHANNEL_CLIENT) {
        pkt->channel = BROADCAST_CHANNEL_SERVER;
    }

    // Submit the changed report
    status = VhfReadReportSubmit(devCtx->vhfHandle,&packet_copy);

    // Set the operation return code
    VhfAsyncOperationComplete(op,status);
    
    devCtx->parallel_ops_counter--;
}

如果我取消了MAX_PARALLEL_OPS检查,驱动程序会定期导致BSOD。我在做错什么吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...