A Basic question about NDIS Filter IM drivers

I’m new to NDIS development and currently trying to develop a NDIS
FILTER IM driver.

I’m reading on all that binding stuff and don’t understand one thing:
After binding the virtual NIC and the protocol part of my driver to
the drivers below and above me, what does actually happen to the REAL
bindings between the REAL NIC and the REAL protocol driver that were
existed BEFORE I’ve installed my IM driver ?

(If my IM can block packets, it means the new bindings REPLACED the
previous? Or that the two bindings exist in the same time?!)

And another question:

If I don’t implement all the OPTIONAL callbacks in my IM, can it cause
problems with different kinds of adapters or disable some of their
features? For example, not implementing *QueryInformationHandler* will
prevent other applications/ drivers to perform queries on the REAL NIC (the
one I’m trying to filter) or will allow OID queries but only prevent them
from passing through me?

Thanks

Omer,
If you new, in NDIS, my advice is don’t think about these on the 1-st
stage.
Your 1st goal has to be building classical filter, which transparent and
abeles debug output for all I/O and OIDs.

I want prevent you from one mistake.
The intermediate DDK example is bad and if it is setup the OS hangs up
on reboot such as image has to be restored from Ghost!?! It was in DDK 2
years ago, but you may check it for last one, I’m about sure, Microsoft
doesn’t check it. :frowning:
2 yeas ago I took 2 drivers: miniport and filter and merged them in one
working IM before implement my code…

Regards,
Michael.

Subject: A Basic question about NDIS Filter IM drivers
From: “Omer B”
>Date: Sun, 25 Feb 2007 19:34:54 +0200
>X-Message-Number: 3
>
>I’m new to NDIS development and currently trying to develop a NDIS
FILTER >IM driver.
>
>I’m reading on all that binding stuff and don’t understand one thing:
>After binding the virtual NIC and the protocol part of my driver to the
>drivers below and above me, what does actually happen to the REAL
bindings >between the REAL NIC and the REAL protocol driver that were
existed BEFORE >I’ve installed my IM driver ?
>
>(If my IM can block packets, it means the new bindings REPLACED the
>previous? Or that the two bindings exist in the same time?!)
>
>And another question:
>
>If I don’t implement all the OPTIONAL callbacks in my IM, can it cause
>problems with different kinds of adapters or disable some of their
>features? For example, not implementing QueryInformationHandler will
>prevent other applications/ drivers to perform queries on the REAL NIC
(the >one I’m trying to filter) or will allow OID queries but only
prevent them >from passing through me?
>
>Thanks

Hi Michael,

I did build a basic NDIS filter by using microsoft’s passthrough sample from
the newest DDK.
I’ve also checked it and it worked after reboot.

What difficulties did you experience?

Can you please help me with the 2 questions i’ve asked in the first mail?

Thanks.

On 2/26/07, Grabelkovsky, Michael <michael.grabelkovsky> wrote:
>
> Omer,
> If you new, in NDIS, my advice is don’t think about these on the 1-st
> stage.
> Your 1st goal has to be building classical filter, which transparent and
> abeles debug output for all I/O and OIDs.
>
> I want prevent you from one mistake.
> The intermediate DDK example is bad and if it is setup the OS hangs up
> on reboot such as image has to be restored from Ghost!?! It was in DDK 2
> years ago, but you may check it for last one, I’m about sure, Microsoft
> doesn’t check it. :frowning:
> 2 yeas ago I took 2 drivers: miniport and filter and merged them in one
> working IM before implement my code…
>
> Regards,
> Michael.
>
>
> >Subject: A Basic question about NDIS Filter IM drivers
> >From: “Omer B”
> >Date: Sun, 25 Feb 2007 19:34:54 +0200
> >X-Message-Number: 3
> >
> >I’m new to NDIS development and currently trying to develop a NDIS
> FILTER >IM driver.
> >
> >I’m reading on all that binding stuff and don’t understand one thing:
> >After binding the virtual NIC and the protocol part of my driver to the
> >drivers below and above me, what does actually happen to the REAL
> bindings >between the REAL NIC and the REAL protocol driver that were
> existed BEFORE >I’ve installed my IM driver ?
> >
> >(If my IM can block packets, it means the new bindings REPLACED the
> >previous? Or that the two bindings exist in the same time?!)
> >
> >And another question:
> >
> >If I don’t implement all the OPTIONAL callbacks in my IM, can it cause
> >problems with different kinds of adapters or disable some of their
> >features? For example, not implementing QueryInformationHandler will
> >prevent other applications/ drivers to perform queries on the REAL NIC
> (the >one I’m trying to filter) or will allow OID queries but only
> prevent them >from passing through me?
> >
> >Thanks
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
></michael.grabelkovsky>

All of the bindings that were enabled on the lower NIC are transferred to
the virtual NIC (essentially they are disabled on the lower NIC and enabled
on the virtual NIC). This is done to achieve an ‘exclusive’ binding of the
IM protocol edge to the lower NIC. The NetService class installer does this
automatically for ‘filter’ style IM drivers. Other IM drivers (like the MUX
sample) require a Notify Object (see notifyobj sample in DDK) to manipulate
the bindings to the desired state.

If you are only building a NDIS 5.x ‘filter’ style IM driver then you can
rely on the NetService class installer to do the right thing for you.

QueryInformationHandler/SetInformationHandler is *not* optional. You must
provide handling of these to (as you point out) ensure that protocols can
query the underlying NIC. Pay careful attention to how PASSTRHU handles
power states and PnP OIDs.

Good Luck,
Dave Cattley
Consulting Engineer
Systems Software Development


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Omer B
Sent: Sunday, February 25, 2007 12:35 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] A Basic question about NDIS Filter IM drivers

I’m new to NDIS development and currently trying to develop a NDIS
FILTER IM driver.

I’m reading on all that binding stuff and don’t understand one thing:
After binding the virtual NIC and the protocol part of my driver to
the drivers below and above me, what does actually happen to the REAL
bindings between the REAL NIC and the REAL protocol driver that were
existed BEFORE I’ve installed my IM driver ?

(If my IM can block packets, it means the new bindings REPLACED the
previous? Or that the two bindings exist in the same time?!)

And another question:

If I don’t implement all the OPTIONAL callbacks in my IM, can it cause
problems with different kinds of adapters or disable some of their
features? For example, not implementing QueryInformationHandler will
prevent other applications/ drivers to perform queries on the REAL NIC (the
one I’m trying to filter) or will allow OID queries but only prevent them
from passing through me?

Thanks

— Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the List
Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Thanks for your detailed response. I don’t know why the DDK help lacks such
a basic information which i think is so vital for beginners in this field.

This subject is a little confusing for me because after dealing with
“regular” filter drivers, the model here is different (you use callbacks
instead of dispatch functions and no generic implementation of “send to the
lower driver and forget”).

If i understood you right, because all the bindings were transferred to my
virtual NIC, if i don’t implement QueryInformationHandler for example, queries
done on the REAL NIC will never get to it… having said that, how can you
explain the fact that when i DIDN"T implement QueryInformationHandler, and
installed my IM driver, i could still make queries (from usermode with OID
Scope util) on the real NIC and on the virtual NIC. How did it work ?
(also, when i did implement it, i couldn’t see debug prints in this function
when i did queries. but i did see lot of debug prints from this function of
someone else doing queries like OID_GEN_LINK_SPEED)

Another question:
In TDI drivers or other basic filters I’ve never had to handle powernd p&p
irps. Why do i need to do it in NDIS IM filters?

Also, can you please explain in simple words all this “packets management”
thing?
I expected a single line of code in the NDIS passthrough sample that sends
the packets down,
but instead i saw a lot of code that most of it dealt with changing packets
descriptors which i didn’t understand why is needed at all …

Thanks

On 2/26/07, David R. Cattley wrote:
>
> All of the bindings that were enabled on the lower NIC are transferred to
> the virtual NIC (essentially they are disabled on the lower NIC and enabled
> on the virtual NIC). This is done to achieve an ‘exclusive’ binding of the
> IM protocol edge to the lower NIC. The NetService class installer does this
> automatically for ‘filter’ style IM drivers. Other IM drivers (like the MUX
> sample) require a Notify Object (see notifyobj sample in DDK) to manipulate
> the bindings to the desired state.
>
> If you are only building a NDIS 5.x ‘filter’ style IM driver then you can
> rely on the NetService class installer to do the right thing for you.
>
> QueryInformationHandler/SetInformationHandler is not optional. You must
> provide handling of these to (as you point out) ensure that protocols can
> query the underlying NIC. Pay careful attention to how PASSTRHU handles
> power states and PnP OIDs.
>
> Good Luck,
> Dave Cattley
> Consulting Engineer
> Systems Software Development
>
> ------------------------------
> From: xxxxx@lists.osr.com [mailto:
> xxxxx@lists.osr.com] *On Behalf Of *Omer B
> Sent: Sunday, February 25, 2007 12:35 PM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] A Basic question about NDIS Filter IM drivers
>
>
> I’m new to NDIS development and currently trying to develop a NDIS
> FILTER IM driver.
>
>
> I’m reading on all that binding stuff and don’t understand one thing:
> After binding the virtual NIC and the protocol part of my driver to
> the drivers below and above me, what does actually happen to the REAL
> bindings between the REAL NIC and the REAL protocol driver that were
> existed BEFORE I’ve installed my IM driver ?
>
> (If my IM can block packets, it means the new bindings REPLACED the
> previous? Or that the two bindings exist in the same time?!)
>
>
> And another question:
>
> If I don’t implement all the OPTIONAL callbacks in my IM, can it cause
> problems with different kinds of adapters or disable some of their
> features? For example, not implementing QueryInformationHandler will
> prevent other applications/ drivers to perform queries on the REAL NIC (the
> one I’m trying to filter) or will allow OID queries but only prevent them
> from passing through me?
>
> Thanks
>
> — Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the List
> Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Omer,

a NDIS IM driver is really hard to write and difficult to install. Excuse my
arrogant question but, have you considered to write a packet-filter for a
different layer?

Hello

This is a real bad time to be starting an NDIS 5.x IM Filter driver beucase
these are legacies of technologies and such beasts do not have native
support in the Vista/Longhorn Network Stack and are replaced with NDIS [6.0]
Lightweight filters or, better, WFP callout drivers.

Cheers
Lyndon

“Omer B” wrote in message news:xxxxx@ntdev…
I’m new to NDIS development and currently trying to develop a NDIS
FILTER IM driver.

I’m reading on all that binding stuff and don’t understand one thing:
After binding the virtual NIC and the protocol part of my driver to
the drivers below and above me, what does actually happen to the REAL
bindings between the REAL NIC and the REAL protocol driver that were
existed BEFORE I’ve installed my IM driver ?
(If my IM can block packets, it means the new bindings REPLACED the
previous? Or that the two bindings exist in the same time?!)

And another question:

If I don’t implement all the OPTIONAL callbacks in my IM, can it cause
problems with different kinds of adapters or disable some of their
features? For example, not implementing QueryInformationHandler will
prevent other applications/ drivers to perform queries on the REAL NIC (the
one I’m trying to filter) or will allow OID queries but only prevent them
from passing through me?

Thanks

Well, Vista has been released literally weeks ago. IMHO a long time will
pass before the majority of PCs will migrate from XP (and even 2000 and
2003) to Vista. So I dont see NDIS 5.x as completely legacy technology…

GV

----- Original Message -----
From: “Lyndon J Clarke”
Newsgroups: ntdev
To: “Windows System Software Devs Interest List”
Sent: Monday, February 26, 2007 3:05 PM
Subject: Re:[ntdev] A Basic question about NDIS Filter IM drivers

> Hello
>
> This is a real bad time to be starting an NDIS 5.x IM Filter driver
> beucase these are legacies of technologies and such beasts do not have
> native support in the Vista/Longhorn Network Stack and are replaced with
> NDIS [6.0] Lightweight filters or, better, WFP callout drivers.
>
> Cheers
> Lyndon
>
> “Omer B” wrote in message news:xxxxx@ntdev…
> I’m new to NDIS development and currently trying to develop a NDIS
> FILTER IM driver.
>
> I’m reading on all that binding stuff and don’t understand one thing:
> After binding the virtual NIC and the protocol part of my driver to
> the drivers below and above me, what does actually happen to the REAL
> bindings between the REAL NIC and the REAL protocol driver that were
> existed BEFORE I’ve installed my IM driver ?
> (If my IM can block packets, it means the new bindings REPLACED the
> previous? Or that the two bindings exist in the same time?!)
>
> And another question:
>
> If I don’t implement all the OPTIONAL callbacks in my IM, can it cause
> problems with different kinds of adapters or disable some of their
> features? For example, not implementing QueryInformationHandler will
> prevent other applications/ drivers to perform queries on the REAL NIC
> (the one I’m trying to filter) or will allow OID queries but only prevent
> them from passing through me?
>
> Thanks
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

Hello Gianluca

I do apologize, I should have written, IMHO, “This is a real bad time to be
starting to learn how to do an NDIS 5.x IM Filter driver …” :wink:

Kind regards
Lyndon

“Gianluca Varenni” wrote in message
news:xxxxx@ntdev…
>
> Well, Vista has been released literally weeks ago. IMHO a long time will
> pass before the majority of PCs will migrate from XP (and even 2000 and
> 2003) to Vista. So I dont see NDIS 5.x as completely legacy technology…
>
> GV
>
>
> ----- Original Message -----
> From: “Lyndon J Clarke”
> Newsgroups: ntdev
> To: “Windows System Software Devs Interest List”
> Sent: Monday, February 26, 2007 3:05 PM
> Subject: Re:[ntdev] A Basic question about NDIS Filter IM drivers
>
>
>> Hello
>>
>> This is a real bad time to be starting an NDIS 5.x IM Filter driver
>> beucase these are legacies of technologies and such beasts do not have
>> native support in the Vista/Longhorn Network Stack and are replaced with
>> NDIS [6.0] Lightweight filters or, better, WFP callout drivers.
>>
>> Cheers
>> Lyndon
>>
>> “Omer B” wrote in message news:xxxxx@ntdev…
>> I’m new to NDIS development and currently trying to develop a NDIS
>> FILTER IM driver.
>>
>> I’m reading on all that binding stuff and don’t understand one thing:
>> After binding the virtual NIC and the protocol part of my driver to
>> the drivers below and above me, what does actually happen to the REAL
>> bindings between the REAL NIC and the REAL protocol driver that were
>> existed BEFORE I’ve installed my IM driver ?
>> (If my IM can block packets, it means the new bindings REPLACED the
>> previous? Or that the two bindings exist in the same time?!)
>>
>> And another question:
>>
>> If I don’t implement all the OPTIONAL callbacks in my IM, can it cause
>> problems with different kinds of adapters or disable some of their
>> features? For example, not implementing QueryInformationHandler will
>> prevent other applications/ drivers to perform queries on the REAL NIC
>> (the one I’m trying to filter) or will allow OID queries but only prevent
>> them from passing through me?
>>
>> Thanks
>>
>>
>> —
>> Questions? First check the Kernel Driver FAQ at
>> http://www.osronline.com/article.cfm?id=256
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>
>

OIDScope (from PCAUSA) uses a technique to submit an OID (NdisRequest) using
DeviceIoControl from usermode which results in the request being directly
presented to the target miniport (device object). As such, the OID is not
‘filtered’ by any other NDIS IM drivers that may be bound to the NIC.

On the other hand, a protocol driver (such as TCPIP.SYS, NDISUIO.SYS, and
others) do not use DeviceIoControl but instead issues NdisRequest() calls to
the ‘binding’ between the protocol and the network ‘stack’ of IM drivers and
miniport.

If you had used NDISUIO or the sample NDISPROT from the DDK to submit OID
requests to the ‘stack’, you would have found that they all failed.
Moreover, I think that NDIS itself would probably fail either explicitly or
in subtle ways since the wrapper itself issues OID requests when
initializing a miniport which it expects a rational answer to.

> In TDI drivers or other basic filters I’ve never had to handle powernd
p&p irps. Why do i need to do it in NDIS IM filters?

For one, TDI ‘transport’ device objects are not PnP device objects and so
filtering one you are not likely to encounter too many PnP IRPs. Keep in
mind that an NT ‘filter’ driver attached to a device stack (PnP or legacy)
has absolutely nothing in common with an NDIS IM ‘filter’ driver. NDIS
drivers exchange packets and requests via an entirely different mechanism
(they do not use IRPs and the fact that some NDIS elements are associated
with NT Device Objects is hidden by the NDIS model).

NDIS IM filter drivers participate (generally) in a PnP device ‘stack’ and
thus the NDIS wrapper delegates certain portions of the PnP and power
management to the miniport driver (via OID requests). Under no
circumstances should an IM driver be processing PnP or Power IRPs directly
but only as OID requests or PnP notifications to either the Miniport of
Protocol edges. NDIS deals with the details and asks only some very modest
and trivially implemented support for PnP and Power from the IM driver.
Passthru does this and I again encourage you to follow the example
carefully.

> Also, can you please explain in simple words all this “packets
management” thing?

I recommend that you read through just about everything on www.ndis.com
about NDIS, IM drivers, and NDIS packets. Thomas Divine of PCAUSA does the
community a great service by collecting, editing, and publishing a
significant amount of tutorial and reference materials on the subjects not
found anywhere else. Thomas is a frequent poster to this NG and I suggest
that you search the archives for anything and everything with his name on
it.

I also recommend that you read the Design Guide sections of the DDK
documentation for all NDIS driver types over and over again. Keep in mind
that an IM driver is the combination of a protocol and a miniport (MAC)
driver. It must live with the restrictions of *both* of these models.

The simple (well, not so simple but direct anyway) answer to your question
about packet management is this: NDIS ‘describes’ packets with a
datastructure NDIS_PACKET. This structure contains fields that are reserved
for NDIS, for the Miniport that is involved in processing the packet, and
the Protocol involved in processing the packet. Packet ownership
transitions between a Miniport and Protocol with the help of NDIS. This
relationship is called a ‘binding’ and an NDIS_PACKET in general can only
traverse a single binding. If you want the packet to traverse another
binding, it needs to get ‘re-described’ with a new NDIS_PACKET so that the
next binding can have access to the reserved (Miniport or Protocol) fields
without stomping on some other bindings use of them.

NDIS 5 introduces packet ‘stacks’ to help IM drivers deal with this issue
more effectively but they are not a complete solution. Don’t try to
understand packet stacking until *after* you fully understand how
NDIS_PACKET structures can only traverse a single binding. It is helpful to
understand the reason packet stacks were introduced because they cannot
solve all of the packet handling scenarios an IM driver faces.

Good Luck,
Dave Cattley
Consulting Engineer
Systems Software Development


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Omer B
Sent: Monday, February 26, 2007 8:20 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] A Basic question about NDIS Filter IM drivers

Thanks for your detailed response. I don’t know why the DDK help lacks such
a basic information which i think is so vital for beginners in this field.

This subject is a little confusing for me because after dealing with
“regular” filter drivers, the model here is different (you use callbacks
instead of dispatch functions and no generic implementation of “send to the
lower driver and forget”).

If i understood you right, because all the bindings were transferred to my
virtual NIC, if i don’t implement QueryInformationHandler for example,
queries done on the REAL NIC will never get to it… having said that, how
can you explain the fact that when i DIDN"T implement
QueryInformationHandler, and installed my IM driver, i could still make
queries (from usermode with OID Scope util) on the real NIC and on the
virtual NIC. How did it work ? (also, when i did implement it, i couldn’t
see debug prints in this function when i did queries. but i did see lot of
debug prints from this function of someone else doing queries like
OID_GEN_LINK_SPEED)

Another question:
In TDI drivers or other basic filters I’ve never had to handle powernd p&p
irps. Why do i need to do it in NDIS IM filters?

Also, can you please explain in simple words all this “packets management”
thing?
I expected a single line of code in the NDIS passthrough sample that sends
the packets down,
but instead i saw a lot of code that most of it dealt with changing packets
descriptors which i didn’t understand why is needed at all …

Thanks

Thanks for your detailed response, it was very helpful.

But I’m still confused with the relationships between my IM and the original
protocol and miniport.

I though that my IM’s protocol calls BindAdapter to bind to the real
miniport, and the real protocol calls BindAdapter to bind to the IM’s
miniport.

I though that there are 2 chains:

  1. Protocol <-> NDIS <-> IM Miniport => Real Miniport
  2. Real protocol <==IM Protocol <-> NDIS <-> Miniport

I still don’t understand how these chains are connected (what is the
inside connection between the IM two edges ?)
My IM miniport’s MiniportInitilize is called when my IM protocol calls
NdisIMInitializeDeviceInstanceEx.

But I though that:

  1. When my protocol tries to bound to a “real” NIC then the real NIC’s
    MiniportInitilize should be called and not mine …
  2. My MiniportInitilize should be called only when the “real”
    protocol tries to bind to my IM’s miniport.

Can someone please help me to solve this confusion? Or maybe show me
how a single call that starts from a protocol driver propagates
through this chain ?

Thanks a lot …

On 2/27/07, David R. Cattley wrote:
>
> OIDScope (from PCAUSA) uses a technique to submit an OID (NdisRequest)
> using
> DeviceIoControl from usermode which results in the request being directly
> presented to the target miniport (device object). As such, the OID is not
> ‘filtered’ by any other NDIS IM drivers that may be bound to the NIC.
>
> On the other hand, a protocol driver (such as TCPIP.SYS, NDISUIO.SYS, and
> others) do not use DeviceIoControl but instead issues NdisRequest() calls
> to
> the ‘binding’ between the protocol and the network ‘stack’ of IM drivers
> and
> miniport.
>
> If you had used NDISUIO or the sample NDISPROT from the DDK to submit OID
> requests to the ‘stack’, you would have found that they all failed.
> Moreover, I think that NDIS itself would probably fail either explicitly
> or
> in subtle ways since the wrapper itself issues OID requests when
> initializing a miniport which it expects a rational answer to.
>
> >> In TDI drivers or other basic filters I’ve never had to handle powernd
> p&p irps. Why do i need to do it in NDIS IM filters?
>
> For one, TDI ‘transport’ device objects are not PnP device objects and so
> filtering one you are not likely to encounter too many PnP IRPs. Keep in
> mind that an NT ‘filter’ driver attached to a device stack (PnP or legacy)
> has absolutely nothing in common with an NDIS IM ‘filter’ driver. NDIS
> drivers exchange packets and requests via an entirely different mechanism
> (they do not use IRPs and the fact that some NDIS elements are associated
> with NT Device Objects is hidden by the NDIS model).
>
> NDIS IM filter drivers participate (generally) in a PnP device ‘stack’ and
> thus the NDIS wrapper delegates certain portions of the PnP and power
> management to the miniport driver (via OID requests). Under no
> circumstances should an IM driver be processing PnP or Power IRPs directly
> but only as OID requests or PnP notifications to either the Miniport of
> Protocol edges. NDIS deals with the details and asks only some very
> modest
> and trivially implemented support for PnP and Power from the IM driver.
> Passthru does this and I again encourage you to follow the example
> carefully.
>
> >> Also, can you please explain in simple words all this “packets
> management” thing?
>
> I recommend that you read through just about everything on www.ndis.com
> about NDIS, IM drivers, and NDIS packets. Thomas Divine of PCAUSA does
> the
> community a great service by collecting, editing, and publishing a
> significant amount of tutorial and reference materials on the subjects not
> found anywhere else. Thomas is a frequent poster to this NG and I
> suggest
> that you search the archives for anything and everything with his name on
> it.
>
> I also recommend that you read the Design Guide sections of the DDK
> documentation for all NDIS driver types over and over again. Keep in
> mind
> that an IM driver is the combination of a protocol and a miniport (MAC)
> driver. It must live with the restrictions of both of these models.
>
> The simple (well, not so simple but direct anyway) answer to your question
> about packet management is this: NDIS ‘describes’ packets with a
> datastructure NDIS_PACKET. This structure contains fields that are
> reserved
> for NDIS, for the Miniport that is involved in processing the packet, and
> the Protocol involved in processing the packet. Packet ownership
> transitions between a Miniport and Protocol with the help of NDIS. This
> relationship is called a ‘binding’ and an NDIS_PACKET in general can only
> traverse a single binding. If you want the packet to traverse another
> binding, it needs to get ‘re-described’ with a new NDIS_PACKET so that the
> next binding can have access to the reserved (Miniport or Protocol) fields
> without stomping on some other bindings use of them.
>
> NDIS 5 introduces packet ‘stacks’ to help IM drivers deal with this issue
> more effectively but they are not a complete solution. Don’t try to
> understand packet stacking until after you fully understand how
> NDIS_PACKET structures can only traverse a single binding. It is helpful
> to
> understand the reason packet stacks were introduced because they cannot
> solve all of the packet handling scenarios an IM driver faces.
>
> Good Luck,
> Dave Cattley
> Consulting Engineer
> Systems Software Development
>
> ________________________________
>
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Omer B
> Sent: Monday, February 26, 2007 8:20 AM
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] A Basic question about NDIS Filter IM drivers
>
>
> Thanks for your detailed response. I don’t know why the DDK help lacks
> such
> a basic information which i think is so vital for beginners in this field.
>
> This subject is a little confusing for me because after dealing with
> “regular” filter drivers, the model here is different (you use callbacks
> instead of dispatch functions and no generic implementation of “send to
> the
> lower driver and forget”).
>
>
> If i understood you right, because all the bindings were transferred to my
> virtual NIC, if i don’t implement QueryInformationHandler for example,
> queries done on the REAL NIC will never get to it… having said that,
> how
> can you explain the fact that when i DIDN"T implement
> QueryInformationHandler, and installed my IM driver, i could still make
> queries (from usermode with OID Scope util) on the real NIC and on the
> virtual NIC. How did it work ? (also, when i did implement it, i couldn’t
> see debug prints in this function when i did queries. but i did see lot of
> debug prints from this function of someone else doing queries like
> OID_GEN_LINK_SPEED)
>
> Another question:
> In TDI drivers or other basic filters I’ve never had to handle powernd p&p
> irps. Why do i need to do it in NDIS IM filters?
>
> Also, can you please explain in simple words all this “packets
> management”
> thing?
> I expected a single line of code in the NDIS passthrough sample that sends
> the packets down,
> but instead i saw a lot of code that most of it dealt with changing
> packets
> descriptors which i didn’t understand why is needed at all …
>
> Thanks
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Omer B
Sent: Sunday, March 04, 2007 12:57 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] A Basic question about NDIS Filter IM drivers

Thanks for your detailed response, it was very helpful.

But I’m still confused with the relationships between my IM and the original
protocol and miniport.

I though that my IM’s protocol calls BindAdapter to bind to the real
miniport, and the real protocol calls BindAdapter to bind to the IM’s
miniport.

I though that there are 2 chains:

  1. Protocol <-> NDIS <-> IM Miniport => Real Miniport

  2. Real protocol <==IM Protocol <-> NDIS <-> Miniport

[PCAUSA] The path is:

Protocol"s Lower-Edge

Your IM Driver Upper-Edge (It’s “Miniport” Edge)

Code within your IM driver

Your IM Driver Lower-Edge (It’s “Protocol” Edge)

Real Miniport

I still don’t understand how these chains are connected (what is the
inside connection between the IM two edges ?)

[PCAUSA] Code within your driver completes the path between the “real”
protocol above it and the “real” miniport below it.

Examine the Passthru driver sample.

Thomas F. Divine

My IM miniport’s MiniportInitilize is called when my IM protocol calls
NdisIMInitializeDeviceInstanceEx.

But I though that:

  1. When my protocol tries to bound to a “real” NIC then the real NIC’s
    MiniportInitilize should be called and not mine …
  2. My MiniportInitilize should be called only when the “real”
    protocol tries to bind to my IM’s miniport.

Can someone please help me to solve this confusion? Or maybe show me
how a single call that starts from a protocol driver propagates
through this chain ?

Thanks a lot …

On 2/27/07, David R. Cattley wrote:

OIDScope (from PCAUSA) uses a technique to submit an OID (NdisRequest) using
DeviceIoControl from usermode which results in the request being directly
presented to the target miniport (device object). As such, the OID is not
‘filtered’ by any other NDIS IM drivers that may be bound to the NIC.

On the other hand, a protocol driver (such as TCPIP.SYS , NDISUIO.SYS, and
others) do not use DeviceIoControl but instead issues NdisRequest() calls to
the ‘binding’ between the protocol and the network ‘stack’ of IM drivers and
miniport.

If you had used NDISUIO or the sample NDISPROT from the DDK to submit OID
requests to the ‘stack’, you would have found that they all failed.
Moreover, I think that NDIS itself would probably fail either explicitly or
in subtle ways since the wrapper itself issues OID requests when
initializing a miniport which it expects a rational answer to.

>> In TDI drivers or other basic filters I’ve never had to handle powernd
p&p irps. Why do i need to do it in NDIS IM filters?

For one, TDI ‘transport’ device objects are not PnP device objects and so
filtering one you are not likely to encounter too many PnP IRPs. Keep in
mind that an NT ‘filter’ driver attached to a device stack (PnP or legacy)
has absolutely nothing in common with an NDIS IM ‘filter’ driver. NDIS
drivers exchange packets and requests via an entirely different mechanism
(they do not use IRPs and the fact that some NDIS elements are associated
with NT Device Objects is hidden by the NDIS model).

NDIS IM filter drivers participate (generally) in a PnP device ‘stack’ and
thus the NDIS wrapper delegates certain portions of the PnP and power
management to the miniport driver (via OID requests). Under no
circumstances should an IM driver be processing PnP or Power IRPs directly
but only as OID requests or PnP notifications to either the Miniport of
Protocol edges. NDIS deals with the details and asks only some very modest
and trivially implemented support for PnP and Power from the IM driver.
Passthru does this and I again encourage you to follow the example
carefully.

>> Also, can you please explain in simple words all this “packets
management” thing?

I recommend that you read through just about everything on www.ndis.com
about NDIS, IM drivers, and NDIS packets. Thomas Divine of PCAUSA does the
community a great service by collecting, editing, and publishing a
significant amount of tutorial and reference materials on the subjects not
found anywhere else. Thomas is a frequent poster to this NG and I suggest
that you search the archives for anything and everything with his name on
it.

I also recommend that you read the Design Guide sections of the DDK
documentation for all NDIS driver types over and over again. Keep in mind
that an IM driver is the combination of a protocol and a miniport (MAC)
driver. It must live with the restrictions of both of these models.

The simple (well, not so simple but direct anyway) answer to your question
about packet management is this: NDIS ‘describes’ packets with a
datastructure NDIS_PACKET. This structure contains fields that are reserved
for NDIS, for the Miniport that is involved in processing the packet, and
the Protocol involved in processing the packet. Packet ownership
transitions between a Miniport and Protocol with the help of NDIS. This
relationship is called a ‘binding’ and an NDIS_PACKET in general can only
traverse a single binding. If you want the packet to traverse another
binding, it needs to get ‘re-described’ with a new NDIS_PACKET so that the
next binding can have access to the reserved (Miniport or Protocol) fields
without stomping on some other bindings use of them.

NDIS 5 introduces packet ‘stacks’ to help IM drivers deal with this issue
more effectively but they are not a complete solution. Don’t try to
understand packet stacking until after you fully understand how
NDIS_PACKET structures can only traverse a single binding. It is helpful to
understand the reason packet stacks were introduced because they cannot
solve all of the packet handling scenarios an IM driver faces.

Good Luck,
Dave Cattley
Consulting Engineer
Systems Software Development

________________________________

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Omer B
Sent: Monday, February 26, 2007 8:20 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] A Basic question about NDIS Filter IM drivers

Thanks for your detailed response. I don’t know why the DDK help lacks such
a basic information which i think is so vital for beginners in this field.

This subject is a little confusing for me because after dealing with
“regular” filter drivers, the model here is different (you use callbacks
instead of dispatch functions and no generic implementation of “send to the
lower driver and forget”).

If i understood you right, because all the bindings were transferred to my
virtual NIC, if i don’t implement QueryInformationHandler for example,
queries done on the REAL NIC will never get to it… having said that, how
can you explain the fact that when i DIDN"T implement
QueryInformationHandler, and installed my IM driver, i could still make
queries (from usermode with OID Scope util) on the real NIC and on the
virtual NIC. How did it work ? (also, when i did implement it, i couldn’t
see debug prints in this function when i did queries. but i did see lot of
debug prints from this function of someone else doing queries like
OID_GEN_LINK_SPEED)

Another question:
In TDI drivers or other basic filters I’ve never had to handle powernd p&p
irps. Why do i need to do it in NDIS IM filters?

Also, can you please explain in simple words all this “packets management”
thing?
I expected a single line of code in the NDIS passthrough sample that sends
the packets down,
but instead i saw a lot of code that most of it dealt with changing packets
descriptors which i didn’t understand why is needed at all …

Thanks


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

— Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the List
Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

>I though that my IM’s protocol calls BindAdapter to bind to the real

miniport, and the real protocol calls BindAdapter to bind to the IM’s
miniport.

This is wrong…

ProtocolBindAdapter() is called not by protocol itself but by NDIS library. In order to bind to underlying miniport, ProtocolBindAdapter() has to call NdisOpenAdapter()…

However, if we replace “BindAdapter” with “NdisOpenAdapter”, your statement becomes true…

I though that there are 2 chains:

  1. Protocol <-> NDIS <-> IM Miniport => Real Miniport
  2. Real protocol <==IM Protocol <-> NDIS <-> Miniport

This is true. Call chains that stands as following:

  1. From “real” protocol to miniport, it goes like “real” protocol ->NDIS library -> IM miniport -> NDIS library -> “real” miniport

  2. From “real” miniport to protocol , it goes like “real” miniport ->NDIS library -> IM protocol -> NDIS library -> “real” protocol

The trick here is that IM miniport calls NDIS functions that protocol drivers are supposed to call,
and IM protocol calls NDIS functions that miniport drivers are supposed to call. This is why NdisMXXXIndicateYYY()functions are called from IM’s ProtocolReceive() and ProtocolReceivePackets() handlers, and NdisSend() and NdisSendPackets() are called from IM’s MiniportSend() and MiniportSendPackets() ones.

But I though that:

  1. When my protocol tries to bound to a “real” NIC then the real NIC’s
    MiniportInitilize should be called and not mine …
  2. My MiniportInitilize should be called only when the “real”
    protocol tries to bind to my IM’s miniport

This is wrong…

“Real” NICs MiniportInitilize() gets called upon NIC’s initialization, so that it has nothing to do with
binding. Your IM’s MiniportInitilize() gets called when *YOUR* protocol calls NdisIMInitializeDeviceInstanceEx(), which is does from ProtocolBindAdapter() handler.
NDIS calls your ProtocolBindAdapter() in order to bind *YOUR* IM protocol to the “real” miniport -
this is why you call NdisOpenAdapter() in context of ProtocolBindAdapter() . It has nothing to do with “real” protocols that get subsequently bound to your IM

Anton Bassov

So when I got IM installed it will be:

Real protocol calls NdisSend()
NDIS calls MiniportSendPackets() on the IM miniport
IM miniport calls NdisSend() from its MiniportSendPackets()
NDIS calls MiniportSendPackets() on the real miniport

How does NDIS know to translate a call of NdisSend() from my miniport to
MiniportSendPackets() on the real miniport ?
NDIS stores a miniport to miniport function mapping in NDIS_OPEN_BLOCK ?!

Now, is there a place in this “real protocol to miniport path” that the IM’s
protocol code is running ? And if so what code? (Or that it only runs in the
"miniport to protocol path) It seems like 2 separate paths (from your
answer…) for me and I still don’t understand if the IM’s protocol is also
involved in this “Send down path” (path 1).

As for MiniportInitilize() stuff:
I was confused and though that that the call to ProtocolBindAdapter() from a
real protocol also calls NdisIMInitializeDeviceInstanceEx…

So you say that MiniportInitilize() in general is called by NDIS to init
miniports,
but in the case of virtual miniport, the IM has to initialize it and it’s
done by calling NdisIMInitializeDeviceInstanceEx() ?
On 3/4/07, xxxxx@hotmail.com wrote:
>
> >I though that my IM’s protocol calls BindAdapter to bind to the real
> >miniport, and the real protocol calls BindAdapter to bind to the IM’s
> >miniport.
>
> This is wrong…
>
> ProtocolBindAdapter() is called not by protocol itself but by NDIS
> library. In order to bind to underlying miniport, ProtocolBindAdapter() has
> to call NdisOpenAdapter()…
>
> However, if we replace “BindAdapter” with “NdisOpenAdapter”, your
> statement becomes true…
>
> > I though that there are 2 chains:
>
>
> > 1. Protocol <-> NDIS <-> IM Miniport => Real Miniport
> > 2. Real protocol <==IM Protocol <-> NDIS <-> Miniport
>
> This is true. Call chains that stands as following:
>
> 1. From “real” protocol to miniport, it goes like “real” protocol ->NDIS
> library -> IM miniport -> NDIS library -> “real” miniport
>
> 2. From “real” miniport to protocol , it goes like “real” miniport ->NDIS
> library -> IM protocol -> NDIS library -> “real” protocol
>
> The trick here is that IM miniport calls NDIS functions that protocol
> drivers are supposed to call,
> and IM protocol calls NDIS functions that miniport drivers are supposed to
> call. This is why NdisMXXXIndicateYYY()functions are called from IM’s
> ProtocolReceive() and ProtocolReceivePackets() handlers, and NdisSend() and
> NdisSendPackets() are called from IM’s MiniportSend() and
> MiniportSendPackets() ones.
>
> >But I though that:
>
> > 1. When my protocol tries to bound to a “real” NIC then the real NIC’s
> > MiniportInitilize should be called and not mine …
> > 2. My MiniportInitilize should be called only when the “real”
> > protocol tries to bind to my IM’s miniport
>
> This is wrong…
>
> “Real” NICs MiniportInitilize() gets called upon NIC’s initialization, so
> that it has nothing to do with
> binding. Your IM’s MiniportInitilize() gets called when YOUR protocol
> calls NdisIMInitializeDeviceInstanceEx(), which is does from
> ProtocolBindAdapter() handler.
> NDIS calls your ProtocolBindAdapter() in order to bind YOUR IM
> protocol to the “real” miniport -
> this is why you call NdisOpenAdapter() in context of ProtocolBindAdapter()
> . It has nothing to do with “real” protocols that get subsequently bound to
> your IM
>
>
> Anton Bassov
>
>
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Omer B
Sent: Sunday, March 04, 2007 4:49 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] A Basic question about NDIS Filter IM drivers

So when I got IM installed it will be:

Real protocol calls NdisSend()
NDIS calls MiniportSendPackets() on the IM miniport
IM miniport calls NdisSend() from its MiniportSendPackets()
NDIS calls MiniportSendPackets() on the real miniport

How does NDIS know to translate a call of NdisSend() from my miniport to
MiniportSendPackets() on the real miniport ?
NDIS stores a miniport to miniport function mapping in NDIS_OPEN_BLOCK ?!

[PCAUSA] NDIS_OPEN_BLOCK is an opaque structure used internally by NDIS.

You don’t need to know the answer to this to write a NDIS driver. You have
the correct basic idea, but it is a fatal mistake to make any references to
the undocumented NDIS_XYZ_BLOCK structures. These structures may be
different on different service packs. In some cases the structures may not
change but their internal use or meaning may change.

Now, is there a place in this “real protocol to miniport path” that the IM’s
protocol code is running? And if so what code? (Or that it only runs in the
"miniport to protocol path) It seems like 2 separate paths (from your
answer…) for me and I still don’t understand if the IM’s protocol is also
involved in this “Send down path” (path 1).

[PCAUSA] You gave the answer yourself:

Real protocol calls NdisSend()
NDIS calls MiniportSendPackets() on the IM miniport
IM miniport calls NdisSend() from its MiniportSendPackets()
NDIS calls MiniportSendPackets() on the real miniport

The for passthru send packets code in the IM driver is “running” from the
point that the IM driver is called at MiniportSendPackets until the point
that the IM driver ProtocolSendComplete is called and has called
NdisMSendComplete to return the original send packet to the higher-level
protocol.

If you examine the “Extending the Passthru.” series of articles at
http:</http:> http://www.wd-3.com you will find an example where
the Passthru driver has been modified to block packets based on their IP
address. A send packet is blocked by examining the packet in the IM driver
MiniportSendPackets routine and simply deciding not to call NdisSend for the
blocked packet.

Thomas F. Divine

As for MiniportInitilize() stuff:
I was confused and though that that the call to ProtocolBindAdapter() from a
real protocol also calls NdisIMInitializeDeviceInstanceEx…

So you say that MiniportInitilize() in general is called by NDIS to init
miniports,
but in the case of virtual miniport, the IM has to initialize it and it’s
done by calling NdisIMInitializeDeviceInstanceEx() ?

On 3/4/07, xxxxx@hotmail.com wrote:

>I though that my IM’s protocol calls BindAdapter to bind to the real
>miniport, and the real protocol calls BindAdapter to bind to the IM’s
>miniport.

This is wrong…

ProtocolBindAdapter() is called not by protocol itself but by NDIS library.
In order to bind to underlying miniport, ProtocolBindAdapter() has to call
NdisOpenAdapter()…

However, if we replace “BindAdapter” with “NdisOpenAdapter”, your statement
becomes true…

> I though that there are 2 chains:

> 1. Protocol <-> NDIS <-> IM Miniport => Real Miniport
> 2. Real protocol <==IM Protocol <-> NDIS <-> Miniport

This is true. Call chains that stands as following:

1. From “real” protocol to miniport, it goes like “real” protocol ->NDIS
library -> IM miniport -> NDIS library -> “real” miniport

2. From “real” miniport to protocol , it goes like “real” miniport ->NDIS
library -> IM protocol -> NDIS library -> “real” protocol

The trick here is that IM miniport calls NDIS functions that protocol
drivers are supposed to call,
and IM protocol calls NDIS functions that miniport drivers are supposed to
call. This is why NdisMXXXIndicateYYY()functions are called from IM’s
ProtocolReceive() and ProtocolReceivePackets() handlers, and NdisSend() and
NdisSendPackets() are called from IM’s MiniportSend() and
MiniportSendPackets() ones.

>But I though that:

> 1. When my protocol tries to bound to a “real” NIC then the real NIC’s
> MiniportInitilize should be called and not mine …
> 2. My MiniportInitilize should be called only when the “real”
> protocol tries to bind to my IM’s miniport

This is wrong…

“Real” NICs MiniportInitilize() gets called upon NIC’s initialization, so
that it has nothing to do with
binding. Your IM’s MiniportInitilize() gets called when YOUR protocol
calls NdisIMInitializeDeviceInstanceEx(), which is does from
ProtocolBindAdapter() handler.
NDIS calls your ProtocolBindAdapter() in order to bind YOUR IM protocol
to the “real” miniport -
this is why you call NdisOpenAdapter() in context of ProtocolBindAdapter() .
It has nothing to do with “real” protocols that get subsequently bound to
your IM

Anton Bassov


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

— Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the List
Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

OK. So after the IM miniport calls NdisSend(), assuming the send is
asynchronous,
the real miniport below will eventually call NdisMSendComplete().

from MSDN: “A call to NdisMSendComplete causes NDIS to call the
ProtocolSendComplete function of the driver that initiated the request with
its call to … NdisSend()”

and the initiating driver is our miniport edge of the IM, so how (and why)
NDIS calls ProtocolSendComplete of our protocol side? not that i see another
choice but still… how and where this “logical” connection to the IM
protocol side is done? i though that the only thing that can cause the IM
protocol code to run are indications coming from the real miniport…

On 3/5/07, Thomas F. Divine wrote:
>
>
>
>
> ------------------------------
>
> From: xxxxx@lists.osr.com [mailto:
> xxxxx@lists.osr.com] *On Behalf Of *Omer B
> Sent: Sunday, March 04, 2007 4:49 PM
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] A Basic question about NDIS Filter IM drivers
>
>
>
> So when I got IM installed it will be:
>
> Real protocol calls NdisSend()
> NDIS calls MiniportSendPackets() on the IM miniport
> IM miniport calls NdisSend() from its MiniportSendPackets()
> NDIS calls MiniportSendPackets() on the real miniport
>
> How does NDIS know to translate a call of NdisSend() from my miniport to
> MiniportSendPackets() on the real miniport ?
> NDIS stores a miniport to miniport function mapping in NDIS_OPEN_BLOCK ?!
>
> [PCAUSA] NDIS_OPEN_BLOCK is an opaque structure used internally by NDIS.
>
> You don’t need to know the answer to this to write a NDIS driver. You
> have the correct basic idea, but it is a fatal mistake to make any
> references to the undocumented NDIS_XYZ_BLOCK structures. These structures
> may be different on different service packs. In some cases the structures
> may not change but their internal use or meaning may change.

>
> Now, is there a place in this “real protocol to miniport path” that the
> IM’s protocol code is running? And if so what code? (Or that it only runs in
> the "miniport to protocol path) It seems like 2 separate paths (from your
> answer…) for me and I still don’t understand if the IM’s protocol is also
> involved in this “Send down path” (path 1).
>
> [PCAUSA] You gave the answer yourself:
>
> Real protocol calls NdisSend()
> NDIS calls MiniportSendPackets() on the IM miniport
> IM miniport calls NdisSend() from its MiniportSendPackets()
> NDIS calls MiniportSendPackets() on the real miniport

>
> The for passthru send packets code in the IM driver is “running” from the
> point that the IM driver is called at MiniportSendPackets until the point
> that the IM driver ProtocolSendComplete is called and has called
> NdisMSendComplete to return the original send packet to the higher-level
> protocol.

>
> If you examine the “Extending the Passthru?” series of articles at
> http://www.wd-3.com you will find an example where the Passthru driver has
> been modified to block packets based on their IP address. A send packet is
> blocked by examining the packet in the IM driver MiniportSendPackets routine
> and simply deciding not to call NdisSend for the blocked packet.

>
> Thomas F. Divine
>
>
> As for MiniportInitilize() stuff:
> I was confused and though that that the call to ProtocolBindAdapter() from
> a real protocol also calls NdisIMInitializeDeviceInstanceEx…
>
> So you say that MiniportInitilize() in general is called by NDIS to init
> miniports,
> but in the case of virtual miniport, the IM has to initialize it and it’s
> done by calling NdisIMInitializeDeviceInstanceEx() ?
>
> On 3/4/07, xxxxx@hotmail.com wrote:
>
> >I though that my IM’s protocol calls BindAdapter to bind to the real
> >miniport, and the real protocol calls BindAdapter to bind to the IM’s
> >miniport.
>
> This is wrong…
>
> ProtocolBindAdapter() is called not by protocol itself but by NDIS
> library. In order to bind to underlying miniport, ProtocolBindAdapter() has
> to call NdisOpenAdapter()…
>
> However, if we replace “BindAdapter” with “NdisOpenAdapter”, your
> statement becomes true…
>
> > I though that there are 2 chains:
>
>
> > 1. Protocol <-> NDIS <-> IM Miniport => Real Miniport
> > 2. Real protocol <==IM Protocol <-> NDIS <-> Miniport
>
> This is true. Call chains that stands as following:
>
> 1. From “real” protocol to miniport, it goes like “real” protocol ->NDIS
> library -> IM miniport -> NDIS library -> “real” miniport
>
> 2. From “real” miniport to protocol , it goes like “real” miniport ->NDIS
> library -> IM protocol -> NDIS library -> “real” protocol
>
> The trick here is that IM miniport calls NDIS functions that protocol
> drivers are supposed to call,
> and IM protocol calls NDIS functions that miniport drivers are supposed to
> call. This is why NdisMXXXIndicateYYY()functions are called from IM’s
> ProtocolReceive() and ProtocolReceivePackets() handlers, and NdisSend() and
> NdisSendPackets() are called from IM’s MiniportSend() and
> MiniportSendPackets() ones.
>
> >But I though that:
>
> > 1. When my protocol tries to bound to a “real” NIC then the real NIC’s
> > MiniportInitilize should be called and not mine …
> > 2. My MiniportInitilize should be called only when the “real”
> > protocol tries to bind to my IM’s miniport
>
> This is wrong…
>
> “Real” NICs MiniportInitilize() gets called upon NIC’s initialization, so
> that it has nothing to do with
> binding. Your IM’s MiniportInitilize() gets called when YOUR protocol
> calls NdisIMInitializeDeviceInstanceEx(), which is does from
> ProtocolBindAdapter() handler.
> NDIS calls your ProtocolBindAdapter() in order to bind YOUR IM
> protocol to the “real” miniport -
> this is why you call NdisOpenAdapter() in context of ProtocolBindAdapter()
> . It has nothing to do with “real” protocols that get subsequently bound to
> your IM
>
>
> Anton Bassov
>
>
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>
> — Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the List
> Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Have you read the DDK Design Guide for NDIS Intermediate drivers? It
describes the binding process in sufficient detail. That document, plus a
look at the DDK sample drivers should get you started.


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Omer B
Sent: Sunday, March 04, 2007 6:59 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] A Basic question about NDIS Filter IM drivers

OK. So after the IM miniport calls NdisSend(), assuming the send is
asynchronous,
the real miniport below will eventually call NdisMSendComplete().

from MSDN: “A call to NdisMSendComplete causes NDIS to call the
ProtocolSendComplete function of the driver that initiated the request with
its call to … NdisSend()”

and the initiating driver is our miniport edge of the IM, so how (and why)
NDIS calls ProtocolSendComplete of our protocol side? not that i see another
choice but still… how and where this “logical” connection to the IM
protocol side is done? i though that the only thing that can cause the IM
protocol code to run are indications coming from the real miniport…

[PCAUSA] NDIS calls the protocol at ProtocolBindAdapter. ProtocolBindAdapter
is given the DeviceName of the “real” lower-level miniport. It calls
NdisOpenAdapter on the DeviceName and if successful has its binding
established to the lower-level miniport.

After NdisOpenAdapter returns successfully ProtocolBindAdapter then calls
NdisIMInitializeDeviceInstanceEx; notice the third parameter to this call is
actually the ADAPT structure that will tie the protocol and miniport
together. This call is what (eventually) causes the IM driver to be called
at MiniportInitialize. In MiniportInitiailize a pointer to the correct ADAPT
structure (just allocated in ProtocolBindAdapter.) is fetched by calling
NdisIMGetDeviceContext. Now the IM driver miniport and protocol instances
are both “in sync”. The ADAPT structure ties them together.

Later, when MiniportSendPackets is called the miniport edge can fetch the
ADAPT structure pointer. It then knows about it’s own information. It also
knows the matching protocol information in sufficient detail to be able to
call NdisSendPackets on the correct binding.

When the lower-level miniport completes the send the IM driver will be
called at ProtocolSendComplete. Here the protocol edge can also fetch the
correct ADAPT structure pointer. Hence, it knows the matching miniport
handle it needs to call NdisMSendComplete to finish the send operation.

So, after ProtocolBindAdapter and MiniportInitialize have both completed
successfully calls to either the IM miniport callbacks or the IM protocol
callbacks cal always fetch the ADAPT structure pointer that contains
information about each 1:1 binding.

Good luck,

Thomas F. Divine

On 3/5/07, Thomas F. Divine wrote:

_____

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Omer B
Sent: Sunday, March 04, 2007 4:49 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] A Basic question about NDIS Filter IM drivers

So when I got IM installed it will be:

Real protocol calls NdisSend()
NDIS calls MiniportSendPackets() on the IM miniport
IM miniport calls NdisSend() from its MiniportSendPackets()
NDIS calls MiniportSendPackets() on the real miniport

How does NDIS know to translate a call of NdisSend() from my miniport to
MiniportSendPackets() on the real miniport ?
NDIS stores a miniport to miniport function mapping in NDIS_OPEN_BLOCK ?!

[PCAUSA] NDIS_OPEN_BLOCK is an opaque structure used internally by NDIS.

You don’t need to know the answer to this to write a NDIS driver. You have
the correct basic idea, but it is a fatal mistake to make any references to
the undocumented NDIS_XYZ_BLOCK structures. These structures may be
different on different service packs. In some cases the structures may not
change but their internal use or meaning may change.

Now, is there a place in this “real protocol to miniport path” that the IM’s
protocol code is running? And if so what code? (Or that it only runs in the
"miniport to protocol path) It seems like 2 separate paths (from your
answer…) for me and I still don’t understand if the IM’s protocol is also
involved in this “Send down path” (path 1).

[PCAUSA] You gave the answer yourself:

Real protocol calls NdisSend()
NDIS calls MiniportSendPackets() on the IM miniport
IM miniport calls NdisSend() from its MiniportSendPackets()
NDIS calls MiniportSendPackets() on the real miniport

The for passthru send packets code in the IM driver is “running” from the
point that the IM driver is called at MiniportSendPackets until the point
that the IM driver ProtocolSendComplete is called and has called
NdisMSendComplete to return the original send packet to the higher-level
protocol.

If you examine the “Extending the Passthru.” series of articles at
http:</http:> http://www.wd-3.com you will find an example where
the Passthru driver has been modified to block packets based on their IP
address. A send packet is blocked by examining the packet in the IM driver
MiniportSendPackets routine and simply deciding not to call NdisSend for the
blocked packet.

Thomas F. Divine

As for MiniportInitilize() stuff:
I was confused and though that that the call to ProtocolBindAdapter() from a
real protocol also calls NdisIMInitializeDeviceInstanceEx…

So you say that MiniportInitilize() in general is called by NDIS to init
miniports,
but in the case of virtual miniport, the IM has to initialize it and it’s
done by calling NdisIMInitializeDeviceInstanceEx() ?

On 3/4/07, xxxxx@hotmail.com wrote:

>I though that my IM’s protocol calls BindAdapter to bind to the real
>miniport, and the real protocol calls BindAdapter to bind to the IM’s
>miniport.

This is wrong…

ProtocolBindAdapter() is called not by protocol itself but by NDIS library.
In order to bind to underlying miniport, ProtocolBindAdapter() has to call
NdisOpenAdapter()…

However, if we replace “BindAdapter” with “NdisOpenAdapter”, your statement
becomes true…

> I though that there are 2 chains:

> 1. Protocol <-> NDIS <-> IM Miniport => Real Miniport
> 2. Real protocol <==IM Protocol <-> NDIS <-> Miniport

This is true. Call chains that stands as following:

1. >From “real” protocol to miniport, it goes like “real” protocol ->NDIS
library -> IM miniport -> NDIS library -> “real” miniport

2. From “real” miniport to protocol , it goes like “real” miniport ->NDIS
library -> IM protocol -> NDIS library -> “real” protocol

The trick here is that IM miniport calls NDIS functions that protocol
drivers are supposed to call,
and IM protocol calls NDIS functions that miniport drivers are supposed to
call. This is why NdisMXXXIndicateYYY()functions are called from IM’s
ProtocolReceive() and ProtocolReceivePackets() handlers, and NdisSend() and
NdisSendPackets() are called from IM’s MiniportSend() and
MiniportSendPackets() ones.

>But I though that:

> 1. When my protocol tries to bound to a “real” NIC then the real NIC’s
> MiniportInitilize should be called and not mine …
> 2. My MiniportInitilize should be called only when the “real”
> protocol tries to bind to my IM’s miniport

This is wrong…

“Real” NICs MiniportInitilize() gets called upon NIC’s initialization, so
that it has nothing to do with
binding. Your IM’s MiniportInitilize() gets called when YOUR protocol
calls NdisIMInitializeDeviceInstanceEx(), which is does from
ProtocolBindAdapter() handler.
NDIS calls your ProtocolBindAdapter() in order to bind YOUR IM protocol
to the “real” miniport -
this is why you call NdisOpenAdapter() in context of ProtocolBindAdapter() .
It has nothing to do with “real” protocols that get subsequently bound to
your IM

Anton Bassov


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

— Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the List
Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

— Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the List
Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

> OK. So after the IM miniport calls NdisSend(), assuming the send is

asynchronous, the real miniport below will eventually call NdisMSendComplete().

from MSDN: “A call to NdisMSendComplete causes NDIS to call the
ProtocolSendComplete function of the driver that initiated the request with
its call to … NdisSend()”

… and the initiating driver is our miniport edge of the IM, so how (and why)
NDIS calls ProtocolSendComplete of our protocol side? not that i see another
choice but still… how and where this “logical” connection to the IM
protocol side is done?

The logical connection between miniport and protocol is all about NDIS_HANDLEs. It does not matter on which edge our call was made - the only thing that matters is NDIS_HANDLE that we have passed in a call. Once we have supplied NDIS_HANDLE(which, in this particular case, happens to be a pointer to NDIS_OPEN_BLOCK that describes the logical correspondence between
our IM and underlying miniport) in NdisSend() call that we made on our miniport edge, we act as a protocol driver, so that SendCompleteHandler callback on our protocol edge gets invoked when operation is completed. Similarly, when we supply a pointer to NDIS_MINIPORT_BLOCK that describes the logical correspondence between our IM and bound protocol to in NdisMXXXIndicateYYY() call that we make on our protocol edge, we act as a miniport driver, so that if you have indicated only a part of data, get ready to receive a call to TransferDataHandler on our miniport edge (it will happen if a bound protocol calls NdisTransferData())…

i though that the only thing that can cause the IM
protocol code to run are indications coming from the real miniport…

This is true…

In our case, a call to our ProtocolSendComplete() directly results from the one to NdisMSendComplete(), made by underlying miniport…

Anton Bassov