[Winpcap-users] Checking whether adapter is alive

Gianluca Varenni gianluca.varenni at cacetech.com
Wed Mar 22 18:47:13 GMT 2006


Bryan,

as you pointed out in your mail, the problem is basically due to some broken 
code inside the driver when a board is disabled, both me and Loris are aware 
of this issues, but haven't worked on fixing it, yet. In practice npf.sys 
gets notified about this unbinding from the underlying miniport, but it 
doesn't operate correctly. In particular, not all the accesses to the 
underlying miniport (NdisRequest is one of them) are properly protected, and 
you experience crashes.

The solution you propose (apart for possibly being dependent on the 
particular NT platform) is not effective, as it's not atomic: there's no 
guarantee that after checking PNDIS_OPEN_BLOCK::BindingHandle!=NULL, the 
same field will not become NULL before calling NdisRequest.

We are planning to work on this unbinding issue in the next weeks, in any 
case.

Have a nice day
GV


----- Original Message ----- 
From: "Bryan Kadzban" <bryan at kadzban.is-a-geek.net>
To: <winpcap-users at winpcap.org>
Sent: Wednesday, March 22, 2006 10:01 AM
Subject: Re: [Winpcap-users] Checking whether adapter is alive


Loris Degioanni wrote:
> Thanks Bryan, I'll give a look at it probably next weekend.

Any progress on this?  I've done some debugging here with the dump file,
and I think I found the reason for the blue screen.  I don't know why
the values are what they are, but I do know what the issue is.

Inside the DeviceIoControl handler (NPF_IoControl in packet.c), in the
handler for BIOCSETOID / BIOCQUERYOID, the code does this after setting
up parameters:

NdisRequest(
            &Status,
            Open->AdapterHandle,
            &pRequest->Request);

ndis.h has a #define for NdisRequest, though, that turns this whole
thing into something like:

PNDIS_OPEN_BLOCK var = (PNDIS_OPEN_BLOCK)(Open->AdapterHandle);
Status = (var->RequestHandler)(var->BindingHandle, &pRequest->Request);

(Although it doesn't have the temporary variable; I added that to more
closely match the disassembly I was seeing inside the debugger.)

var->RequestHandler is set to the address of ndisMRequest, inside
NDIS.sys (and that's the function that's causing the BSOD).  The first
thing that that function does is dereference var->BindingHandle, which
is NULL in the memory dump that I have.  This blue-screens.

Now, I'm not sure *why* the handle is NULL, but I suspect it may be the
way NDIS responds to device removals.  (Using kd's !drvobject and
!devobj commands, I verified that the wireless device that I was
querying did *not* exist as a \Device\NPF_{<guid>} device while this was
happening.)

The easiest fix that I can come up with is to cast Open->AdapterHandle
to a PNDIS_OPEN_BLOCK, then check whether its BindingHandle is NULL,
before calling NdisRequest.  (If your copy of ndis.h doesn't call it
BindingHandle, then it's the second field in the structure.  I've seen
some ndis.h files while searching Google that call it other names.)
Then return some special error code to userspace.  When my program gets
that error code, it'll close its handles and re-run its "get a handle" code.

The only possible problem I see is that the AdapterHandle might not be a
PNDIS_OPEN_BLOCK on all versions of Windows.  It is on 2000, and
presumably is on XP and Vista, but I doubt that's the case on 9x.  Maybe
that isn't a problem though.
> _______________________________________________
> Winpcap-users mailing list
> Winpcap-users at winpcap.org
> https://www.winpcap.org/mailman/listinfo/winpcap-users
> 



More information about the Winpcap-users mailing list