Hi All,
I’m developing a PCI video card driver based on WDK6000.
Between app and driver there are 2 types IOCTLs–One is METHOD_BUFFERED and another METHOD_NEITHER.
I handle these as the WDF NonPnP sample demonstrates.METHOD_BUFFERED can do,but METHOD_NEITHER has problem.
When called WdfRequestProbeAndLockUserBufferForRead in EvtIoInCallerContext callback function,error happened.
“NTSTATUS Value 0xc000 0005”[STATUS_ACCESS_VIOLATION],Error is “The current thread is not the creator of the I/O request” references to WDK doc.
Well,I’m not well understand it.How to solve this problem?
Any help is appreciated.Thanks.
Best Regards
Zhou ChengJun
Related to the code below[Simplify]:
#define IOCTL_METHOD_NEITHER CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER , FILE_ANY_ACCESS)
#define IOCTL_METHOD_BUFFERED CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
EvtDriverDeviceAdd(
IN WDFDRIVER Driver,
IN PWDFDEVICE_INIT DeviceInit
)
{
…
WdfDeviceInitSetIoInCallerContextCallback(DeviceInit,
PLxEvtDeviceIoInCallerContext);
…
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig,
WdfIoQueueDispatchSequential);
queueConfig.EvtIoDeviceControl = PLxEvtIoDeviceControl;
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
status = WdfIoQueueCreate(devExt->Device,
&queueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&devExt->DeviceControlQueue );
WdfControlFinishInitializing(devExt->Device);
…
}
VOID
PLxEvtDeviceIoInCallerContext(
IN WDFDEVICE Device,
IN WDFREQUEST Request
)
{
NTSTATUS status = STATUS_SUCCESS;
PREQUEST_CONTEXT reqContext = NULL;
WDF_OBJECT_ATTRIBUTES attributes;
WDF_REQUEST_PARAMETERS params;
size_t inBufLen,outBufLen;
PVOID inBuf,outBuf;
WDF_REQUEST_PARAMETERS_INIT(¶ms);
WdfRequestGetParameters(Request, ¶ms );
if(!(params.Type == WdfRequestTypeDeviceControl &&
params.Parameters.DeviceIoControl.IoControlCode == IOCTL_METHOD_NEITHER))
{
status = WdfDeviceEnqueueRequest(Device, Request);
return;
}
status = WdfRequestRetrieveUnsafeUserInputBuffer(Request, 0, &inBuf, &inBufLen);
status = WdfRequestRetrieveUnsafeUserOutputBuffer(Request, 0, &outBuf, &outBufLen);
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, REQUEST_CONTEXT);
status = WdfObjectAllocateContext(Request, &attributes, &reqContext);
status = WdfRequestProbeAndLockUserBufferForRead(Request,
inBuf,
inBufLen,
&reqContext->InputMemoryBuffer); //failed,0xc000 0005
if(!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
“Error WdfRequestProbeAndLockUserBufferForRead failed 0x%x”, status);
goto End;
}
status = WdfRequestProbeAndLockUserBufferForWrite(Request,
outBuf,
outBufLen,
&reqContext->OutputMemoryBuffer);
if(!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
“Error WdfRequestProbeAndLockUserBufferForWrite failed 0x%x”, status);
goto End;
}
// Finally forward it for processing by the I/O package
status = WdfDeviceEnqueueRequest(Device, Request);
return;
End:
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, “EvtIoPreProcess failed %x \n”, status);
WdfRequestComplete(Request, status);
return;
}