User interface to configure NDIS miniport driver

Hi,

I wrote an NDIS miniport driver for a network adapter board about a year
ago, which seems to be working fine.

My client would now like to have a user mode program with which he can
modify some internal parameters. I havn’t yet discussed any details, but I’m
pretty sure that he would like to modify at least some parameters on the
fly.

This would require some kind of direct interface from a user mode program to
an NDIS miniport driver. Is this possible?

If it was a standard kernel mode driver, then I could define one or more
IOCTL functions, but as far as I am aware, there is no equivalent function
for an NDIS driver.

Can anybody help?

Thanks in advance,
Phil

I have now found some information, in particular at
http://www.ndis.com/faq/QA10290101.htm

First a quick question to the technique using DeviceIOControl. The article
indicates that my driver would have to use NdisMRegisterDevice. My driver
already calls NdisMRegisterMiniport. Is there any conflict between these two
calls?

However, implementing DeviceIOControl would add significant code to the
driver, which I would prefer not to do.

The better approach seems to be with custom OIDs and WMI. This would
probably require no structural change to the driver and appears to be a
clean solution.

Does anybody have a good sample of how to do this? In particular, I would
like a sample of how to access OIDs using WMI.

I don’t really care what language it is in, but one of VB, VBScript, C++, C#
or Java would be most useful. Since it is a COM interface, VB is probably
the easiest to understand, but most driver writers would probably go for
C++. I think my client would actually favour Java, but that is a different
story!

Best regards
Phil

On Jan 17, 2007, at 3:31 AM, Phil Jollans wrote:

I have now found some information, in particular at
http://www.ndis.com/faq/QA10290101.htm

First a quick question to the technique using DeviceIOControl. The
article
indicates that my driver would have to use NdisMRegisterDevice. My
driver
already calls NdisMRegisterMiniport. Is there any conflict between
these two
calls?

Nope.

However, implementing DeviceIOControl would add significant code to
the
driver, which I would prefer not to do.

You’re going to have to add control code somewhere; the code
shouldn’t be too complex unless you want to do something complex. If
you’re just getting and setting variables or something, it’s very
straightforward.

The better approach seems to be with custom OIDs and WMI. This would
probably require no structural change to the driver and appears to
be a
clean solution.

I don’t personally see anything wrong with the control device
approach, as long as you’re careful.

Does anybody have a good sample of how to do this? In particular, I
would
like a sample of how to access OIDs using WMI.

I don’t really care what language it is in, but one of VB,
VBScript, C++, C#
or Java would be most useful.

Forgive me if I missed something earlier in this thread, but you’re
aware, are you not, that kernel drivers must be in C (or a restricted
C++ if you know what you’re doing)? Or are you just referring to the
usermode client?

Incidentally, netvmini and passthru have control device sample code.
There is a device object reference counting issue that you need to be
careful of, though; see:

http:lifetimes/>

HTH.

-sd</http:>

Of course, I was refering to usermode client code with regard to the
language. My driver is in plain old C.

Thanks for the reply
Phil

> This would require some kind of direct interface from a user mode program to

an NDIS miniport driver. Is this possible?

Yes, by custom OIDs (query only) or WMI.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

> First a quick question to the technique using DeviceIOControl. The article

indicates that my driver would have to use NdisMRegisterDevice. My driver
already calls NdisMRegisterMiniport. Is there any conflict between these two
calls?

NdisMRegisterMiniport() does what its name suggests, i.e. registers miniport that protocol drivers/NDIS IMs can bind to. No one, apart from NDIS library, can access miniport driver.
What if some non-NDIS component needs to query or configure miniport driver? This is what NdisMRegisterDevice() is for - it registers a standalone device that is not related to the network stack, so that non-NDIS components can access your miniport driver via this device, which exposes a regular IRP interface.

However, implementing DeviceIOControl would add significant code to the
driver, which I would prefer not to do().

How are you going to access your driver from non-NDIS components then???

The better approach seems to be with custom OIDs and WMI.

Again, the same question - how can non-NDIS components submit their queries and requests to your miniport driver if your standalone device does not handle IRP_MJ_DEVICE_CONTROL requests???

In other words, registering standalone device and implementing IRP_MJ_DEVICE_CONTROL handler is an absolute must in your situation - otherwise, non-NDIS components will have no chance to access your driver (as far as they are concerned, miniport *IS* this standalone device)…

Anton Bassov

Hi Anton,

this is very interesting, but it conflicts with my previous information.

Clearly one approach is to use NdisMRegisterDevice and handle
IRP_MJ_DEVICE_CONTROL. This probably isn’t difficult and may be the best
way.

The other approach is to define custom OIDs. These are handled by the
SetInformation() and QueryInformation() functions, which my MiniPort driver
already has. The user mode client can use the WMI interface to access these.
Presumably WMI uses the NDIS library, or routes the requests via a protocol
driver. I don’t know the details, but this seems to be a real option.

You seem to suggest that this just doesn’t work. Hmm. I’m sceptical. The
information about this method appears pretty clear to me.

However, WMI does appears to be a complex interface, so I’m not sure I want
to use it.

On the face of it, if the choice is complexity in the driver or complexity
in the client program, then the choice has to be complexity in the client.
However handling IRP_MJ_DEVICE_CONTROL might be much easier than programming
WMI!

Phil

Phil,

The other approach is to define custom OIDs. These are handled by the
SetInformation() and QueryInformation() functions, which my MiniPort driver
already has. The user mode client can use the WMI interface to access these.
Presumably WMI uses the NDIS library, or routes the requests via a protocol
driver. I don’t know the details, but this seems to be a real option.

You seem to suggest that this just doesn’t work. Hmm. I’m sceptical. The
information about this method appears pretty clear to me.

I don’t suggest that WMIit does not work. It does work- this is out of question. The only question here is how WMI gets access to your miniport driver…

I think that, in the end of the day, the whole thing ends up being routed via standalone device’s
Dispatch interface, i.e. IRP_MJ_DEVICE_CONTROL request. Otherwise, WMI would have to implement its own protocol driver that has to be bound to your miniport, and to do so for the sole purpose of being able to submit a query. Once WMI has no idea about the adapter that may be
targeted by these requests, it would have to make sure that this protocol driver is bound to all
adapters that are installed on the target machine. To be honest, such scenario seems to be quite unlikely, at least judging from what I see under ‘Linkage’ subkey of all adapters that are listed under HKLM \SYSTEM\CurrentControlSet\Control\Class{4D36E972-E325-11CE-BFC1-08002bE10318}.

Let’s see what the other guys say - probably, I am just wrong…

Anton Bassov

> -----Original Message-----

From: xxxxx@lists.osr.com [mailto:bounce-276294-
xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Saturday, January 20, 2007 2:02 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] User interface to configure NDIS miniport driver

Phil,

>The other approach is to define custom OIDs. These are handled by the
>SetInformation() and QueryInformation() functions, which my MiniPort
driver
>already has. The user mode client can use the WMI interface to access
these.
> Presumably WMI uses the NDIS library, or routes the requests via a
protocol
> driver. I don’t know the details, but this seems to be a real option.

>You seem to suggest that this just doesn’t work. Hmm. I’m sceptical. The
> information about this method appears pretty clear to me.

I don’t suggest that WMIit does not work. It does work- this is out of
question. The only question here is how WMI gets access to your miniport
driver…

I think that, in the end of the day, the whole thing ends up being routed
via standalone device’s
Dispatch interface, i.e. IRP_MJ_DEVICE_CONTROL request. Otherwise, WMI
would have to implement its own protocol driver that has to be bound to
your miniport, and to do so for the sole purpose of being able to submit a
query. Once WMI has no idea about the adapter that may be
targeted by these requests, it would have to make sure that this protocol
driver is bound to all
adapters that are installed on the target machine. To be honest, such
scenario seems to be quite unlikely, at least judging from what I see
under ‘Linkage’ subkey of all adapters that are listed under HKLM
\SYSTEM\CurrentControlSet\Control\Class{4D36E972-E325-11CE-BFC1-
08002bE10318}.

Let’s see what the other guys say - probably, I am just wrong…

Anton Bassov

[PCAUSA] In this case:

1.) Anton’s on the wrong track.
2.) Pavel might have been tired when he made a reply.
3.) Phil has the right idea.

The DDK e100bex miniport sample illustrates adding custom WMI interfaces to
set and query private data.

The WMI interface to NDIS miniports is routed through the NDIS wrapper
(NDIS.sys and friends). A NDIS miniport doesn’t need to call
NdisMRegisterDevice or have a traditional I/O dispatch API in order for the
custom OIDs to be accessible via WMI - even from remote machines. Just
follow the guidelines described in the DDK topic “NDIS Support for WMI”.

I personally don’t like WMI unless it is being called via .NET managed APIs.
I am just too stupid to understand the raw WMI APIs, but the managed APIs to
WHI actually make sense.

Thomas F. Divine

> I don’t suggest that WMIit does not work. It does work- this is out of
question.

The only question here is how WMI gets access to your miniport driver…

My opinion (I can be wrong):

  • NDIS.SYS creates some control device object for itself, which is possibly
    used for things like binding enumeration and calling ProtocolPnPEvent for a
    binding from user mode (INetCfg provides ways of doing this - this is how IP
    addresses can be changed from the UI on the fly) and so on.
  • this device object has WMI support on it
  • the WMI code in NDIS.SYS maps the WMI requests to OIDs (using the
    miniport-provided table I think) and sends the OIDs down to the miniport.

People with sources can confirm it or deny it.

would have to implement its own protocol driver that has to be bound to your
miniport, and to do so for the sole purpose of being able to submit a query.

I don’t think WMI does this.

Yes, MS once created the protocol driver to route the Wi-Fi OIDs to user mode
Wi-Fi services - the famous NDISUIO, which is the standard OS part in WinCE and
the undocumented binary+sample NDISPROT source in Windows, it allows much more
then Wi-Fi OIDs - but I have doubts they have a protocol driver for WMI.

WMI is older then Wi-Fi, it is w2k-vintage.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

> I personally don’t like WMI unless it is being called via .NET managed APIs.

I am just too stupid to understand the raw WMI APIs, but the managed APIs to
WHI actually make sense.

VB (even VBScript) or C++ with some handicrafted wrapper classes (or possibly
#import declaration of some MS’s DLL or TLB) are also helpful.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Thanks for all of your replies.

I see that there are at least three NDIS samples in the DDK implementing
IRP_MJ_DEVICE_CONTROL which look fairly simple. In comparison, custom OIDs
and WMI look too complex.

In fact, I have a lot of experience programming COM, so I could certainly
cope with WMI. On the other hand, I want to give my client something that
they can maintain and extend themselves (although I don’t really expect them
to do so), and IOCTLs are just easier to explain.

Phil

“Phil Jollans” wrote in message news:xxxxx@ntdev…
> Thanks for all of your replies.
>
> I see that there are at least three NDIS samples in the DDK implementing IRP_MJ_DEVICE_CONTROL which look fairly simple. In
> comparison, custom OIDs and WMI look too complex.

Do they really?
Any NDIS driver anyway will have OID handler, so custom OIDs can be
added almost for free.
Custom WMI objects are handled by NDIS; the miniport receives them
in the form of OIDs.
NDIS takes care of the sync and other complexities.

On the contrary, custom device interface and IOCTLs expose NDIS
driver directly to the user mode as a top-level driver - that IMHO
is a terrible ugly hack. An NDIS driver then becomes a “multiple
inheritance” thing and has to act upon two absolutely diferent contracts.

> In fact, I have a lot of experience programming COM, so I could certainly cope with WMI. On the other hand, I want to give my
> client something that they can maintain and extend themselves (although I don’t really expect them to do so), and IOCTLs are
> just easier to explain.

Ahem. Then do so - many people with unix/linux background
just can’t understand anything besides of ioctl’s, files and sockets.

Regards,
–PA

Thanks Pavel, I will keep my options open.

The point about the unix/linux background applies to my client. They have a
linux driver for their hardware and they have a user mode client which can
update some hareware specific parameters. They want the same basic
functionality under windows.

Although they didn’t write the linux driver themselves, they understand
enough to modify it for their requirements. Fundamentally, they don’t
understand the NDIS driver. The questions they ask reveal an assumption,
that under the hood, Windows must work like Linux.

As I understand, custom OIDs are defined using UUIDs. This makes sense if
you are used to working with COM interfaces. Most Windows programmers have
some notion about UUIDs. However, they are meaningless to Linux programmers.
In fact, they will see it as an unnecessary complication, which confirms
their poor opinion of Microsoft.

My mind is fairly open and I might even try both methods out. However, I do
think my client will understand the IOCTL interface better.

Phil

> I see that there are at least three NDIS samples in the DDK implementing

IRP_MJ_DEVICE_CONTROL which look fairly simple. In comparison, custom
OIDs
and WMI look too complex.

NdisMRegisterDevice has by far more gotchas then WMI.

cope with WMI. On the other hand, I want to give my client something that
they can maintain and extend themselves (although I don’t really expect them
to do so), and IOCTLs are just easier to explain.

Remember managed code. WMI is trivial from there.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

> In fact, they will see it as an unnecessary complication, which confirms

their poor opinion of Microsoft.

Why complication? To copy-paste a long number in braces? Is it complex?

BTW - OIDs are IIRC 32bit values, where the senior bit must be set to
“vendor-specific”.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com