WdfIoTargetSendIoctlSynchronously returning STATUS_REQUEST_NOT_ACCEPTED

Since changing one of my drivers from WDF 1.7 to 1.9 I am encountering a problem with WdfIoTargetSendIoctlSynchronously unexpectedly failing.

My driver A attempts to issue an IOCTL to one of my lower drivers B using WdfIoTargetSendIoctlSynchronously.

This works fine when they’re both using WDF 1.7. However since changing driver B to use 1.9 instead, the call to WdfIoTargetSendIoctlSynchronously is returning C00000D0

i.e.

STATUS_REQUEST_NOT_ACCEPTED - The I/O request packet (IRP) that the Request parameter represents does not provide enough IO_STACK_LOCATION structures to allow the driver to forward the request.

But if instead of

status = WdfIoTargetSendIoctlSynchronously(extension->ParentTarget, NULL,
MyIoctl,
NULL, NULL, NULL, NULL);

I use

WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
status = WdfRequestCreate(&attributes,
extension->ParentTarget,
&request);
if (NT_SUCCESS(status)) {
status = WdfIoTargetFormatRequestForIoctl(extension->ParentTarget,
request,
MyIoctl,
NULL,
NULL,
NULL,
NULL);
if (NT_SUCCESS(status)) {
WDF_REQUEST_SEND_OPTIONS options;
WDF_REQUEST_SEND_OPTIONS_INIT(
&options,
WDF_REQUEST_SEND_OPTION_SYNCHRONOUS
);
if (!WdfRequestSend(request,
extension->ParentTarget,
&options)) {
status = WdfRequestGetStatus(request);
}
}
}

then the IOCTL works fine!

Note: increasing the PDO’s (Driver B’s) StackSize doesn’t appear to have any affect.

Any ideas?

Will

> Note: increasing the PDO’s (Driver B’s) StackSize doesn’t appear to have

any affect.

Is DriverA attached to DriverB or are they in separate device stacks?

If DriverA isn’t attached to DriverB and you are taking IRPs targeted at
DriverA and sending them to DriverB, you need to increase DriverA’s stack
size. The I/O manager is going to use DriverA’s stack size when allocating
the IRP, it wouldn’t know about the A->B relationship in this case as it’s
something implemented in your driver.

-scott


Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com

wrote in message news:xxxxx@ntdev…
> Since changing one of my drivers from WDF 1.7 to 1.9 I am encountering a
> problem with WdfIoTargetSendIoctlSynchronously unexpectedly failing.
>
> My driver A attempts to issue an IOCTL to one of my lower drivers B using
> WdfIoTargetSendIoctlSynchronously.
>
> This works fine when they’re both using WDF 1.7. However since changing
> driver B to use 1.9 instead, the call to WdfIoTargetSendIoctlSynchronously
> is returning C00000D0
>
> i.e.
>
> STATUS_REQUEST_NOT_ACCEPTED - The I/O request packet (IRP) that the
> Request parameter represents does not provide enough IO_STACK_LOCATION
> structures to allow the driver to forward the request.
>
> But if instead of
>
> status =
> WdfIoTargetSendIoctlSynchronously(extension->ParentTarget, NULL,
> MyIoctl,
> NULL, NULL,
> NULL, NULL);
>
> I use
>
> WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
> status = WdfRequestCreate(&attributes,
> extension->ParentTarget,
> &request);
> if (NT_SUCCESS(status)) {
> status =
> WdfIoTargetFormatRequestForIoctl(extension->ParentTarget,
> request,
> MyIoctl,
> NULL,
> NULL,
> NULL,
> NULL);
> if (NT_SUCCESS(status)) {
> WDF_REQUEST_SEND_OPTIONS options;
> WDF_REQUEST_SEND_OPTIONS_INIT(
> &options,
>
> WDF_REQUEST_SEND_OPTION_SYNCHRONOUS
> );
> if (!WdfRequestSend(request,
> extension->ParentTarget,
> &options)) {
> status = WdfRequestGetStatus(request);
> }
> }
> }
>
> then the IOCTL works fine!
>
> Note: increasing the PDO’s (Driver B’s) StackSize doesn’t appear to have
> any affect.
>
> Any ideas?
>
> Will
>

What does !wdfkd.wdlogdump say for both driver a and b in the failure case?

d

dent from a phpne with no keynoard

-----Original Message-----
From: xxxxx@farsite.co.uk
Sent: August 23, 2010 8:11 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] WdfIoTargetSendIoctlSynchronously returning STATUS_REQUEST_NOT_ACCEPTED

Since changing one of my drivers from WDF 1.7 to 1.9 I am encountering a problem with WdfIoTargetSendIoctlSynchronously unexpectedly failing.

My driver A attempts to issue an IOCTL to one of my lower drivers B using WdfIoTargetSendIoctlSynchronously.

This works fine when they’re both using WDF 1.7. However since changing driver B to use 1.9 instead, the call to WdfIoTargetSendIoctlSynchronously is returning C00000D0

i.e.

STATUS_REQUEST_NOT_ACCEPTED - The I/O request packet (IRP) that the Request parameter represents does not provide enough IO_STACK_LOCATION structures to allow the driver to forward the request.

But if instead of

status = WdfIoTargetSendIoctlSynchronously(extension->ParentTarget, NULL,
MyIoctl,
NULL, NULL, NULL, NULL);

I use

WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
status = WdfRequestCreate(&attributes,
extension->ParentTarget,
&request);
if (NT_SUCCESS(status)) {
status = WdfIoTargetFormatRequestForIoctl(extension->ParentTarget,
request,
MyIoctl,
NULL,
NULL,
NULL,
NULL);
if (NT_SUCCESS(status)) {
WDF_REQUEST_SEND_OPTIONS options;
WDF_REQUEST_SEND_OPTIONS_INIT(
&options,
WDF_REQUEST_SEND_OPTION_SYNCHRONOUS
);
if (!WdfRequestSend(request,
extension->ParentTarget,
&options)) {
status = WdfRequestGetStatus(request);
}
}
}

then the IOCTL works fine!

Note: increasing the PDO’s (Driver B’s) StackSize doesn’t appear to have any affect.

Any ideas?

Will


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Different stacks

Although Driver B does provide a PDO, in this case Driver A is using WdfIoTargetOpen etc. to gain access to the FDO of Driver B. (So Driver B’s PDO StackSize should, and does appear to, be not related to the problem)

if…you are taking IRPs targeted at DriverA and sending them to DriverB, you need to increase DriverA’s stack size…

no - in this case I’m creating new requests (see above).

But also why the difference between 1.7 and 1.9 & between the WdfIoTargetSendIoctlSynchronously and WdfRequestCreate approaches?

Following the call to WdfIoTargetSendIoctlSynchronously the following has been added to the logs:

DriverA:

947: FxSyncRequest::SelfDestruct - SyncRequest 8B3EF580, signaling event 8B3EF608 on SelfDestruct

DriverB:

2257: FxIoTargetSendIoctl - enter: WDFIOTARGET 0x6F814530, WDFREQUEST 0x00000000, IOCTL 0x750, internal 0
2258: FxIoTargetSendIoctl - WDFIOTARGET 0x6F814530, WDFREQUEST 0x8B3EF580 being submitted
2259: FxIoTarget::SubmitSync - WDFIOTARGET 6F814530, WDFREQUEST 8B3EF580
2260: FxIoTarget::SubmitLocked - WDFREQUEST 8B3EF580 has not been formatted, cannot send, 0xc00000d0(STATUS_REQUEST_NOT_ACCEPTED)
2261: FxIoTarget::SubmitSync - WDFREQUEST 8B3EF580, Action 0x0

> 2260: FxIoTarget::SubmitLocked - WDFREQUEST 8B3EF580 has not been formatted, cannot send, 0xc00000d0(STATUS_REQUEST_NOT_ACCEPTED)

The driver is failing the verifier check that the request must be formatted for send. Is WDF verifier ON with both 1.7 and 1.9?

Praveen

Actually since it is a sync request formatting is done by the framework internally. So it can’t be driver missing formatting. In addition, since the request is created by framework (as driver passed NULL for the request), driver is unlikely to be able to modify its state and cause such a problem (barring memory corruption).

Not sure what could cause this. If you set a breakpoint at wdf01000!FxIoTarget::SubmitLocked and create and upload a full dump we could look into it further.

Thanks,
Praveen

ps: This posting is provided as is and confers no rights.


From: Praveen Rao
Sent: Monday, August 23, 2010 10:29 AM
To: Windows System Software Devs Interest List
Subject: RE: RE:[ntdev] WdfIoTargetSendIoctlSynchronously returning STATUS_REQUEST_NOT_ACCEPTED

2260: FxIoTarget::SubmitLocked - WDFREQUEST 8B3EF580 has not been formatted, cannot send, 0xc00000d0(STATUS_REQUEST_NOT_ACCEPTED)

The driver is failing the verifier check that the request must be formatted for send. Is WDF verifier ON with both 1.7 and 1.9?

Praveen

> Is WDF verifier ON with both 1.7 and 1.9?

Yes

If you set a breakpoint at wdf01000!FxIoTarget::SubmitLocked and create and upload a full dump we could look into it further.

You mean a full MEMORY.DMP? Where should I upload it to?

Apologies - I have redone this again and I think the verifier setting for DriverA (1.7) can’t have worked for some reason (driver not restarted?)

Anyway, I now can see that if verfiier is enabled for both DriverA & DriverB then it works OK.

If, however, you disable it for DriverA (but have it enabled for DriverB) then WdfIoTargetSendIoctlSynchronously fails as before.

But the WdfRequestCreate approach works in both cases.

I’m having some trouble interpreting this thread. Initially it sounds like Driver A sends IOCTL synchrosnously to Driver B and gets a failing status. I move down and I see two log dumps- Driver A succeeds, AFAICT, and Driver B is failing a synchronous send of the IOCTL (does this mean it is forwarding it yet again?).

Which driver is the failing code coming from? Or do both have the same code, and one works and the other fails running that identical code?

My next question is whether the sole variable here (initially, I’m not sure this verifier result is a red herring arising from a race condition already revealed) is Driver B. Is the only thing changing Driver B (toggling between 1.7 and 1.9)? Because if it is, then the KMDF code is the same in both cases (the 1.9 code).

We’re not able to reproduce this problem, and one thing that may mean is we’re making incorrect assumptions about the scenario, which is why I’m asking questions like this.

> Initially it sounds like Driver A sends IOCTL synchrosnously to Driver B and gets a failing status.

That’s certainly what I’m seeing

Driver A succeeds, AFAICT, and Driver B is failing a synchronous send of the IOCTL (does this mean it is forwarding it yet again?).

It shouldn’t be - it should just be processing/completing it - as I say, works OK if verifier is either ON or OFF for *both* drivers.

Which driver is the failing code coming from? Or do both have the same code, and one works and the other fails running that identical code?

Only DriverA issues the IOCTL; only Driver B processes the IOCTL. The failure code comes when DriverB processes it

Is the only thing changing Driver B (toggling between 1.7 and 1.9)?

DriverB–>1.9 *and* setting up verifier on DriverB only. The latter may be sufficient even with a 1.7 version of DriverB - I’d have to experiment more to narrow that down.

However, one further important complication that has come to light - there is actually another (filter) driver between A and B. All this one does in this scenario is forward the IOCTL it receives from A onto B - although of course this has implications WRT stack locations.

It appears that the problem is related to the fact that if verifier is not enabled for DriverA, then even though it is enabled for DriverB, the calculation of the number of required stack locations is wrong - since verifier affects the stack location usage/requirements?

What seems to be confusing the issue is this:



Following the call to WdfIoTargetSendIoctlSynchronously the following has been added to the logs:

DriverA:

947: FxSyncRequest::SelfDestruct - SyncRequest 8B3EF580, signaling event 8B3EF608 on SelfDestruct

DriverB:

2257: FxIoTargetSendIoctl - enter: WDFIOTARGET 0x6F814530, WDFREQUEST 0x00000000, IOCTL 0x750, internal 0
2258: FxIoTargetSendIoctl - WDFIOTARGET 0x6F814530, WDFREQUEST 0x8B3EF580 being submitted
2259: FxIoTarget::SubmitSync - WDFIOTARGET 6F814530, WDFREQUEST 8B3EF580
2260: FxIoTarget::SubmitLocked - WDFREQUEST 8B3EF580 has not been formatted, cannot send, 0xc00000d0(STATUS_REQUEST_NOT_ACCEPTED)
2261: FxIoTarget::SubmitSync - WDFREQUEST 8B3EF580, Action 0x0

The messages attributed to “DriverB” are from the code KMDF uses to perform a synchronous send of an IOCTL to an IOTARGET- so the code, handling the IOCTL from DriverA, *in Driver B*- is to me the apparent source of the failure code. This particular “is it formatted” check also existed in 1.7, so turning verifier on for the 1.7 driver may also cause this to happen. (and I mean “may”).

So we may (and I’d like to emphasize “may”) be looking in the wrong place for the problem. But if the messages above are really from Driver B, then I believe it needs some examination.


Initially it sounds like Driver A sends IOCTL synchrosnously to Driver B and gets a failing status.

That’s certainly what I’m seeing

Driver A succeeds, AFAICT, and Driver B is failing a synchronous send of the IOCTL (does this mean it is forwarding it yet again?).

It shouldn’t be - it should just be processing/completing it - as I say, works OK if verifier is either ON or OFF for *both* drivers.

Which driver is the failing code coming from? Or do both have the same code, and one works and the other fails running that identical code?

Only DriverA issues the IOCTL; only Driver B processes the IOCTL. The failure code comes when DriverB processes it

Is the only thing changing Driver B (toggling between 1.7 and 1.9)?

DriverB–>1.9 *and* setting up verifier on DriverB only. The latter may be sufficient even with a 1.7 version of DriverB - I’d have to experiment more to narrow that down.

However, one further important complication that has come to light - there is actually another (filter) driver between A and B. All this one does in this scenario is forward the IOCTL it receives from A onto B - although of course this has implications WRT stack locations.

It appears that the problem is related to the fact that if verifier is not enabled for DriverA, then even though it is enabled for DriverB, the calculation of the number of required stack locations is wrong - since verifier affects the stack location usage/requirements?


[BobK] No, WDF verifier doesn’t use any stack locations. At the moment, I have no idea why settings on Driver A affect Driver B’s processing, other than some as-yet-undescribed race flipping one way or another based somehow on processing time differences in the two paths. Which is rather nebulous as an eplanation.

I’ve tried it again and get the same results.

With WDF verifier OFF for DriverA but ON for DriverB I get:

Driver A:

739: FxSyncRequest::SelfDestruct - SyncRequest ABEF0580, signaling event ABEF0608 on SelfDestruct

DriverB:

1832: FxIoTargetSendIoctl - enter: WDFIOTARGET 0x6E870818, WDFREQUEST 0x00000000, IOCTL 0x750, internal 0
1833: FxIoTargetSendIoctl - WDFIOTARGET 0x6E870818, WDFREQUEST 0xABEF0580 being submitted
1834: FxIoTarget::SubmitSync - WDFIOTARGET 6E870818, WDFREQUEST ABEF0580
1835: FxIoTarget::SubmitLocked - WDFREQUEST ABEF0580 has not been formatted, cannot send, 0xc00000d0(STATUS_REQUEST_NOT_ACCEPTED)
1836: FxIoTarget::SubmitSync - WDFREQUEST ABEF0580, Action 0x0

With WDF verifier ON for both DriverA and DriverB I get:

DriverA:

731: FxSyncRequest::SelfDestruct - SyncRequest ABEF0580, signaling event ABEF0608 on SelfDestruct

DriverB:

2916: FxIoTargetSendIoctl - enter: WDFIOTARGET 0x6E870818, WDFREQUEST 0x00000000, IOCTL 0x750, internal 0
2917: FxIoTargetSendIoctl - WDFIOTARGET 0x6E870818, WDFREQUEST 0xABEF0580 being submitted
2918: FxIoTarget::SubmitSync - WDFIOTARGET 6E870818, WDFREQUEST ABEF0580
2919: FxIoTarget::SubmitSync - WDFREQUEST ABEF0580, Action 0x1
2920: FxIoTarget::SubmitSync - Sending WDFREQUEST ABEF0580, Irp AB82CE00
2921: FxPkgIo::Dispatch - WDFDEVICE 0x79494FE0 !devobj 0x9162B218 0x0000000e(IRP_MJ_DEVICE_CONTROL), IRP_MN 0, IRP 0xAB82CE00
2922: FxIoQueue::QueueRequest - Queuing WDFREQUEST 0x78C2C0D0 on WDFQUEUE 0x6E874FB0
2923: FxIoQueue::DispatchEvents - Thread 87290928 is processing WDFQUEUE 0x6E874FB0
2924: FxIoQueue::DispatchRequestToDriver - Calling driver EvtIoDeviceControl for WDFREQUEST 0x78C2C0D0
2925: imp_WdfUsbTargetDeviceFormatRequestForControlTransfer - WDFUSBDEVICE 74850BA0, WDFREQUEST 6E8525F8, WDFMEMORY 78CC1558
2926: imp_WdfUsbTargetDeviceFormatRequestForControlTransfer - format control request WDFUSBDEVICE 74850BA0, WDFREQWUEST 6E8525F8, WDFMEMORY 78CC1558, STATUS_SUCCESS
2927: FxIoTarget::SubmitLocked - Starting timer on WDFREQUEST 6E8525F8
2928: FxIoTarget::RequestCompletionRoutine - WDFREQUEST 6E8525F8
2929: FxRequestBase::CancelTimer - Request 917ADA00, canceled timer successfully
2930: FxIoTarget::RemoveCompletedRequestLocked - WDFIOTARGET 74850BA0, WDFREQUEST 6E8525F8
2931: FxIoTarget::RequestCompletionRoutine - WDFREQUEST 6E8525F8 completed in completion routine
2932: imp_WdfUsbTargetDeviceFormatRequestForControlTransfer - WDFUSBDEVICE 74850BA0, WDFREQUEST 6E8525F8, WDFMEMORY 78D94FB0
2933: imp_WdfUsbTargetDeviceFormatRequestForControlTransfer - format control request WDFUSBDEVICE 74850BA0, WDFREQWUEST 6E8525F8, WDFMEMORY 78D94FB0, STATUS_SUCCESS
2934: FxIoTarget::SubmitLocked - Starting timer on WDFREQUEST 6E8525F8
2935: FxIoTarget::RequestCompletionRoutine - WDFREQUEST 6E8525F8
2936: FxRequestBase::CancelTimer - Request 917ADA00, canceled timer successfully
2937: FxIoTarget::RemoveCompletedRequestLocked - WDFIOTARGET 74850BA0, WDFREQUEST 6E8525F8
2938: FxIoTarget::RequestCompletionRoutine - WDFREQUEST 6E8525F8 completed in completion routine
2939: imp_WdfUsbTargetDeviceFormatRequestForControlTransfer - WDFUSBDEVICE 74850BA0, WDFREQUEST 6E8525F8, WDFMEMORY 00000000
2940: imp_WdfUsbTargetDeviceFormatRequestForControlTransfer - format control request WDFUSBDEVICE 74850BA0, WDFREQWUEST 6E8525F8, WDFMEMORY 00000000, STATUS_SUCCESS
2941: FxIoTarget::SubmitLocked - Starting timer on WDFREQUEST 6E8525F8
2942: FxIoTarget::RequestCompletionRoutine - WDFREQUEST 74893E90
2943: FxIoTarget::RemoveCompletedRequestLocked - WDFIOTARGET 6E9600F0, WDFREQUEST 74893E90
2944: FxIoTarget::RequestCompletionRoutine - WDFREQUEST 74893E90 completed in completion routine
2945: FxIoTarget::RequestCompletionRoutine - WDFREQUEST 6E8525F8
2946: FxRequestBase::CancelTimer - Request 917ADA00, canceled timer successfully
2947: FxIoTarget::RemoveCompletedRequestLocked - WDFIOTARGET 74850BA0, WDFREQUEST 6E8525F8
2948: FxIoTarget::RequestCompletionRoutine - WDFREQUEST 6E8525F8 completed in completion routine
2949: imp_WdfUsbTargetDeviceFormatRequestForControlTransfer - WDFUSBDEVICE 74850BA0, WDFREQUEST 6E8525F8, WDFMEMORY 00000000
2950: imp_WdfUsbTargetDeviceFormatRequestForControlTransfer - format control request WDFUSBDEVICE 74850BA0, WDFREQWUEST 6E8525F8, WDFMEMORY 00000000, STATUS_SUCCESS
2951: FxIoTarget::SubmitLocked - Starting timer on WDFREQUEST 6E8525F8
2952: FxIoTarget::RequestCompletionRoutine - WDFREQUEST 6E8525F8
2953: FxRequestBase::CancelTimer - Request 917ADA00, canceled timer successfully
2954: FxIoTarget::RemoveCompletedRequestLocked - WDFIOTARGET 74850BA0, WDFREQUEST 6E8525F8
2955: FxIoTarget::RequestCompletionRoutine - WDFREQUEST 6E8525F8 completed in completion routine
2956: imp_WdfRequestComplete - Completing WDFREQUEST 0x78C2C0D0 for IRP 0xAB82CE00 with Information 0x0, STATUS_SUCCESS
2957: FxIoQueue::DispatchEvents - Thread 80DEE668 is processing WDFQUEUE 0x6E874FB0
2958: FxPkgPnp::Dispatch - WDFDEVICE 0x79494FE0 !devobj 0x9162B218, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xB0CACE00
2959: FxPkgFdo::PnpQueryDeviceRelations - Entering QueryDeviceRelations handler, type TargetDeviceRelation
2960: FxPkgFdo::PnpQueryDeviceRelations - Exiting QueryDeviceRelations handler, status 0x00000002(STATUS_WAIT_2)
2961: FxPkgPnp::Dispatch - WDFDEVICE 0x79494FE0 !devobj 0x9162B218, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xB0DE6E00
2962: FxPkgFdo::PnpQueryDeviceRelations - Entering QueryDeviceRelations handler, type TargetDeviceRelation
2963: FxPkgFdo::PnpQueryDeviceRelations - Exiting QueryDeviceRelations handler, status 0x00000002(STATUS_WAIT_2)
2964: FxPkgIo::Dispatch - WDFDEVICE 0x79494FE0 !devobj 0x9162B218 0x0000000e(IRP_MJ_DEVICE_CONTROL), IRP_MN 0, IRP 0xB107EE28
2965: FxIoQueue::QueueRequest - Queuing WDFREQUEST 0x6E8FD260 on WDFQUEUE 0x6E874FB0
2966: FxIoQueue::DispatchEvents - Thread 873DF1C8 is processing WDFQUEUE 0x6E874FB0
2967: FxIoQueue::DispatchRequestToDriver - Calling driver EvtIoDeviceControl for WDFREQUEST 0x6E8FD260
2968: imp_WdfRequestComplete - Completing WDFREQUEST 0x6E8FD260 for IRP 0xB107EE28 with Information 0x14, STATUS_SUCCESS
2969: FxIoTarget::RequestCompletionRoutine - WDFREQUEST 749CBC48
2970: FxIoTarget::RemoveCompletedRequestLocked - WDFIOTARGET 6E9600F0, WDFREQUEST 749CBC48
2971: FxIoTarget::RequestCompletionRoutine - WDFREQUEST 749CBC48 completed in completion routine
2972: FxPkgIo::Dispatch - WDFDEVICE 0x79494FE0 !devobj 0x9162B218 0x0000000e(IRP_MJ_DEVICE_CONTROL), IRP_MN 0, IRP 0xB0C70E28
2973: FxIoQueue::QueueRequest - Queuing WDFREQUEST 0x6E8FD260 on WDFQUEUE 0x6E874FB0
2974: FxIoQueue::DispatchEvents - Thread 873DF1C8 is processing WDFQUEUE 0x6E874FB0
2975: FxIoQueue::DispatchRequestToDriver - Calling driver EvtIoDeviceControl for WDFREQUEST 0x6E8FD260
2976: imp_WdfRequestComplete - Completing WDFREQUEST 0x6E8FD260 for IRP 0xB0C70E28 with Information 0x0, STATUS_SUCCESS
2977: FxPkgIo::Dispatch - WDFDEVICE 0x79494FE0 !devobj 0x9162B218 0x0000000e(IRP_MJ_DEVICE_CONTROL), IRP_MN 0, IRP 0xB0DEEE28
2978: FxIoQueue::QueueRequest - Queuing WDFREQUEST 0x6E8FD260 on WDFQUEUE 0x6E874FB0
2979: FxIoQueue::DispatchEvents - Thread 873DF1C8 is processing WDFQUEUE 0x6E874FB0
2980: FxIoQueue::DispatchRequestToDriver - Calling driver EvtIoDeviceControl for WDFREQUEST 0x6E8FD260
2981: imp_WdfRequestComplete - Completing WDFREQUEST 0x6E8FD260 for IRP 0xB0DEEE28 with Information 0x0, STATUS_SUCCESS
2982: FxIoTarget::RequestCompletionRoutine - WDFREQUEST ABEF0580
2983: FxIoTarget::RemoveCompletedRequestLocked - WDFIOTARGET 6E870818, WDFREQUEST ABEF0580
2984: FxIoTarget::RequestCompletionRoutine - WDFREQUEST ABEF0580 completed in completion routine

You haven’t been sharing handles between drivers, perchance, have you? Because the most logical explanation for all of these behaviors is that the WDFIOTARGET handle you are using in driver A was created in Driver B.

I had thought not - and certainly in this case, No - DriverA is just using

WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME…
WdfIoTargetOpen(extension->ParentTarget, &openParams);…

before calling WdfIoTargetSendIoctlSynchronously

However, examining that possibility has revealed a sharing problem elsewhere:

The drivers are largely ported code and use a shared chunk of memory (actually a pair of FIFOs). Function-based callbacks are exchanged and the drivers schedule each other (after writing into their particular fifo) by calling the appropriate peer’s callback. The callbacks simply schedule a DPC in the driver that hosts the callback. This all appears to “work” fine. However, of course, when for example, Driver A calls Driver B’s callback, the callback will use WdfDpcEnqueue to schedule Driver B’s DPC - but this will effectively be done whilst executing Driver A! In that case, in which context would the DPC be subsequently scheduled, A or B?

What would you recommend using to avoid this problem - i.e. how to schedule a DPC in another WDF driver? I would really want to avoid a complete change to the existing model if possible.

I’m talking about WdfIoTargetCreate, not WdfIoTargetOpen- where does the WDFIOTARGET in extension->ParentTarget get created? Your logs (when combined, and carefully observing which objects’ activity got logged where) clearly indicate the usage of a handle CREATED (not opened) in driver B being used by driver A to synchronously send an IOCTL. The verifier behaviors you’ve reported are also explained by that, as well as the effects of changing the code used to send the IOCTL.

As for cross-driver scheduling- If it’s WDM you’re porting, I’d not change that part of the code at all. That’s my short answer. The long one would also involve getting a lot of answers about what you would be trying to use those WDFDPC objects for (e.g. WDF-added synchronization wrt queue or device callbacks), and it could well still wind up being the short one. But I’m quite amenable to contradiction.

-----Original Message-----

I had thought not - and certainly in this case, No - DriverA is just using

WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME…
WdfIoTargetOpen(extension->ParentTarget, &openParams);…

before calling WdfIoTargetSendIoctlSynchronously

However, examining that possibility has revealed a sharing problem elsewhere:

The drivers are largely ported code and use a shared chunk of memory (actually a pair of FIFOs). Function-based callbacks are exchanged and the drivers schedule each other (after writing into their particular fifo) by calling the appropriate peer’s callback. The callbacks simply schedule a DPC in the driver that hosts the callback. This all appears to “work” fine. However, of course, when for example, Driver A calls Driver B’s callback, the callback will use WdfDpcEnqueue to schedule Driver B’s DPC - but this will effectively be done whilst executing Driver A! In that case, in which context would the DPC be subsequently scheduled, A or B?

What would you recommend using to avoid this problem - i.e. how to schedule a DPC in another WDF driver? I would really want to avoid a complete change to the existing model if possible.

Yep - you’re absolutely right - that was what was inadvertently happening.

WRT that - can you confirm whether the “Device” specified in the call to WdfIoTargetCreate is completely independent of/unrelated to the actual device subsequently used as the target i.e. specified via WdfIoTargetOpen e.g. using WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME. The lib docs for WdfioTargetCreate just say:

Device [in]
*A* handle to *a* framework device object.

Depends upon what you mean by “completely independent”.

IO has a point of origin and of destination. Device is conceptual point of origin, and iotarget is destination. The target object by default is parented to the device object [in terms of object lifetimes, not in any WDM sense]- in fact, the device must be a parent [although you can specify something in between such as a queue as parent]. They can be the same WDM device (which means the device Is “talking to itself”), but generally are not.

Since the subject has come up already in this thread [not as an attempt to judge intent], one reason I have quotes above is I don’t want this taken as meaning you can use a device handle from one driver as the “Device” parameter to create an iotarget in a different driver.

I’ll see if we can provide better guidance around what the device handle should be in the documentation, although the discussion around parenting there at least hints at this.

-----Original Message-----
Yep - you’re absolutely right - that was what was inadvertently happening.

WRT that - can you confirm whether the “Device” specified in the call to WdfIoTargetCreate is completely independent of/unrelated to the actual device subsequently used as the target i.e. specified via WdfIoTargetOpen e.g. using WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME. The lib docs for WdfioTargetCreate just say:

Device [in]
*A* handle to *a* framework device object.