Tech Support > Microsoft Windows > Drivers > Querying IP Address / Connection Info on Vista: returns TDI_PENDIN
Querying IP Address / Connection Info on Vista: returns TDI_PENDIN
Posted by David Yon on July 12th, 2006


I'm using DriverNetworks to access TCP sockets via kernel-mode TDI, and I'm
getting an assert when my code queries information about the connected
socket. Here's the code snippet in question:

===============================
// prepare irp & call the transport
TdiBuildQueryInformation (irp,
m_pDevice,
FileObj,
(PIO_COMPLETION_ROUTINE) pReq->RequestNotifyObject, // completion
routine, sh be NULL
pReq->RequestContext, // completion
context
QueryType,
pBuf
);

TDI_STATUS Status = CallDriver(irp, pReq->RequestNotifyObject==NULL);
ASSERT (Status != TDI_PENDING); // Async not supported
if (Status != TDI_PENDING && pReq->RequestNotifyObject==NULL) {
*BufferSize = (ULONG)irp->IoStatus.Information;
FreeIrp(irp);
}
===============================

I'm getting the ASSERT because CallDriver() is returning TDI_PENDING when
run on Vista, whereas every other version of Windows completes this request
synchronously (and there's no reason it can't complete it synchronously).
What's interesting is that by the time I hit the ASSERT, I've observed the
following:

1) The request buffer already contains the desired information (IP
Address, for example).
2) Windbg claims that the IRP has been completed already.

Anyone else run into this yet? My theory is that there is a bug in the
TDI->WSX translation layer, and they are returning PENDING unnecessarily
(legal, to be sure, but a PITA for the code that calls CallDriver()). As
such, I'm tempted to get rid of the ASSERT, and just flip a TDI_PENDING
result into TDI_SUCCESS for this call.

Thoughts and insights greatly appreciated.
--

David Yon
Tactical Software

Posted by Thomas F. Divine [DDK MVP] on July 12th, 2006


It sure would be tempting to just ignore the ASSERT, and it just might work
in this specific case. BUT, I'd avoid going that route if at all possible.

I'd suggest that you analyze the code to understand why the ASSERT was there
in the first place. Perhaps it was because the call is being made at too
high an IRQL - where it is not possible to wait.

If the IRQL is OK for waiting on an event, I'd suggest that you create an
event before making the call and add a completion routine to set the event.
Then, after making the call wait on the event _if_ Status == TDI_PENDING.

If the IRQL isn't suitable for waiting on an event, then you've got a bigger
restructuring task.

Thomas F. Divine, Windows DDK MVP
http://www.pcausa.com


"David Yon" <DavidYon@discussions.microsoft.com> wrote in message
news:E8177F32-FAE3-4035-94FE-E8366DD9F7A2@microsoft.com...

Posted by David Yon on July 12th, 2006


To answer some of the questions:

1) The ASSERT is there because the function (supplied in KTDInterface) is
designed to return its answer synchronously. Up until now, every version of
Windows has included a TCP stack which makes this design possible.

2) The function is called from various places at both PASSIVE and DISPATCH,
so waiting is not an option without some serious refactors elsewhere.

The infrastructure around this function includes a structure which tracks
when the IRP has been completed. So I've adjusted the code to read:

===================
SYNCTDIREQ* req = static_cast<SYNCTDIREQ*>(pReq->RequestContext);
ASSERT (!((Status == TDI_PENDING) && !req->IsCompleted()));
if (Status != TDI_PENDING && pReq->RequestNotifyObject==NULL) {
*BufferSize = (ULONG)irp->IoStatus.Information;
FreeIrp(irp);
}
if ((Status == TDI_PENDING) && req->IsCompleted()) Status = TDI_SUCCESS;
===================

In a nutshell, it now ASSERTs only if status was TDI_PENDING *and* the irp
has *not* yet been completed. Ditto the return value adjustment---it will
only flip from TDI_PENDING to TDI_SUCCESS if the irp has been completed
already.

So far, in initial testing, this seems to work. I.e., the lack of ASSERT is
proving my point that in fact CallDriver() is completing the IRP
synchronously despite the TDI_PENDING return value. Make sense, since every
other version of Windows is able to query the current IP Address
synchronously. The only difference with Vista is that it's throwing the
caller a curveball with TDI_PENDING.

I'll probably raise this issue with Microsoft (hey out there! aren't you
guys supposed to be monitoring this newgroup?), since the Right Thing(tm) is
for the stack to return TDI_SUCCESS if it in fact has completed the IRP.

--

David Yon
Tactical Software



"Thomas F. Divine [DDK MVP]" wrote: