NdisWriteConfiguration crashes.

Hi folks,

I’m having a problem using NdisWriteConfiguration: It crashes when I
don’t run it in the context of MiniportInitialize. I’ve found a previous
post on NTDEV (back in '01) about this issue, which is enclosed below.

I have a WDF bus driver creating the PDO for my NDIS driver, and that
bus driver may at times, wish to change the configuration for the NDIS
driver, and then unload and reload the NDIS device if the config change
requires it.

I’d planned to proxy the “set property” calls from the bus to the NDIS
driver via an interface, and then execute them in an NDIS workitem - I
had assumed that at least at that point I’d be in some sort of NDIS
callback at passive IRQL, and hence, things would have a reasonable
chance of working. Unfortunately, this appears not to be the case.

So … it looks like I’ll have to:

  1. Call from my bus driver to the NDIS driver to update any
    nonpersistent (in memory) state.
  2. Make the appropriate registry changes from within the Bus driver.
  3. If necessary mark the NDIS device as not present, and then present to
    reload the NDIS driver.

1 and 3 are pretty trivial, given what I have,

So, my big question is handling #2: Is there a guaranteed good method of
finding the appropriate chunk of registry to modify from the WDF bus
driver for a particular device? I’d strongly prefer not to use NDIS
calls in the NDIS drivers, as, of course, that has WHQL / Logo implications.

MH.

Steve Dispensa
xxxxx@positivenetworks.net

Join Date: 26 Jun 2001
Posts To This List: 351

Re: NdisWriteConfiguration crashes

On Tue, 2004-09-07 at 07:49, Jayadev M N wrote:
> hi,
>

> I am trying to write back some data on to the
> driver
key in registry for my ndis driver using
>
NdisWriteConfiguration(). However, this api causes a
> system
crash if used from a non MiniportInitialize
> thread
context…

This mechanism is really designed for use in
MiniportInitialize only. I
think you’re going to have to use Zw
functions for any registry updating
after the fact. This could have
an impact on WHQL though; I’m not sure
what their policy here is.
Maybe Bryan Burgin can comment.

-sd


Steve Dispensa
MVP - Windows
DDK
www.kernelmustard.com

Martin Harvey wrote:

I’d strongly prefer not to use NDIS calls in the NDIS drivers, as,
of course, that has WHQL / Logo implications.

Of course, that should read: “I’d strongly prefer to use only NDIS calls
in the NDIS drivers …”

MH.

Martin,

The WrapperConfigurationContext passed to MiniportInitialize is only valid
for the duration of that call (as you have discovered).

I am not entirely sure I follow you explanation of what entity is updating
what configuration but I have the following to offer:

  • NdisOpenProtocolConfiguration() can get you a ConfigurationHandle which
    can access a subset of the registry beneath
    HKLM\System\CurrentControlSet\Services. The “ProtocolSection”
    PUNICODE_STRING ProtocolSection parameter is a subkey path from
    HKLM.…\Services. If your configuration lives in HKLM.…\Services, you
    are free to use that (at PASSIVE_LEVEL) from any NDIS driver AFAIK.

  • My recollection is that the stuff you would normally read via the
    WrapperConfigurationContext in MiniportInitialize() is stored in the ‘driver
    key’ of the DevNode. You can access that using IoOpenDeviceRegistryKey()
    and specify the PDO. From within the Miniport, you can get the PDO (during
    MiniportInitialize) with NdisMGetDeviceProperty(). The Device Registry Key
    can be used with ZwXxx to get/set values, etc. Of course, all at
    PASSIVE_LEVEL. I am not sure about signability but I thought that this was
    OK for a NDIS/WDM miniport since these are all WDM functions.

  • Is it an operational parameter that you wish to control in the NIC? Have
    you considered WMI?

  • What about having the bus driver write to the registry
    (IoOpenDeviceRegistry(pdo,PLUGPLAY_REGKEY_DRIVER,…)/ZwXxxx) *and* notify
    the Miniport via a private interface negotiated via IRP_MN_QUERY_INTERFACE?
    If you goal is to simply have a ‘callback’ mechanism from the bus driver
    into the miniport to change the ‘active’ configuration, this is a way to
    accomplish that. The miniport does not need to change the peristed
    configuration, the bus driver can do that.

  • What is wrong with stopping/starting the PnP device? I presume that these
    configuration changes are are a result of some administrative or operational
    action initiated in usermode. Why not just do it all there and leave the
    bus driver blissfully un-aware (although it would know its PDO was just
    stopped) and let the NDIS Miniport just pickup the new configuration when
    MiniportInitialize() is called on the restart? Is this something you
    *need* to do from kernel mode?

Good Luck,
Dave Cattley
Consulting Engineer
Systems Software Development

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Martin Harvey
Sent: Tuesday, September 25, 2007 9:29 AM
To: Windows System Software Devs Interest List
Cc: xxxxx@solarflare.com; xxxxx@solarflare.com
Subject: [ntdev] NdisWriteConfiguration crashes.

Hi folks,

I’m having a problem using NdisWriteConfiguration: It crashes when I don’t
run it in the context of MiniportInitialize. I’ve found a previous post on
NTDEV (back in '01) about this issue, which is enclosed below.

I have a WDF bus driver creating the PDO for my NDIS driver, and that bus
driver may at times, wish to change the configuration for the NDIS driver,
and then unload and reload the NDIS device if the config change requires it.

I’d planned to proxy the “set property” calls from the bus to the NDIS
driver via an interface, and then execute them in an NDIS workitem - I had
assumed that at least at that point I’d be in some sort of NDIS callback at
passive IRQL, and hence, things would have a reasonable chance of working.
Unfortunately, this appears not to be the case.

So … it looks like I’ll have to:

  1. Call from my bus driver to the NDIS driver to update any nonpersistent
    (in memory) state.
  2. Make the appropriate registry changes from within the Bus driver.
  3. If necessary mark the NDIS device as not present, and then present to
    reload the NDIS driver.

1 and 3 are pretty trivial, given what I have,

So, my big question is handling #2: Is there a guaranteed good method of
finding the appropriate chunk of registry to modify from the WDF bus driver
for a particular device? I’d strongly prefer not to use NDIS calls in the
NDIS drivers, as, of course, that has WHQL / Logo implications.

MH.

Steve Dispensa
xxxxx@positivenetworks.net

Join Date: 26 Jun 2001
Posts To This List: 351

Re: NdisWriteConfiguration crashes

On Tue, 2004-09-07 at 07:49, Jayadev M N wrote:
> hi,
>

I am trying to write back some data on to the
> driver key in
registry for my ndis driver using
> NdisWriteConfiguration().
However, this api causes a
> system crash if used from a non
MiniportInitialize
> thread context…

This mechanism is
really designed for use in MiniportInitialize only. I
think you’re going
to have to use Zw functions for any registry updating
after the fact.
This could have an impact on WHQL though; I’m not sure
what their policy
here is.
Maybe Bryan Burgin can comment.

-sd


Steve Dispensa
MVP - Windows DDK

www.kernelmustard.com


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

David R. Cattley wrote:

  • My recollection is that the stuff you would normally read via the
    WrapperConfigurationContext in MiniportInitialize() is stored in the ‘driver
    key’ of the DevNode. You can access that using IoOpenDeviceRegistryKey()
    and specify the PDO. From within the Miniport, you can get the PDO (during
    MiniportInitialize) with NdisMGetDeviceProperty().

OK, yes this is generally what I want to do. If I’m going to use
Non-NDIS registry functions, then it seems to make sense to me, to have
them in the bus driver, not the NDIS driver.

  • Is it an operational parameter that you wish to control in the NIC? Have
    you considered WMI?

Haha :slight_smile: WMI is what’s got me into this hole in the first place.

The Bus driver creates a whole load of PDO’s for NDIS drivers (typically
for VLAN / Teaming). As a result of this, quite a lot of the NDIS device
config has to be cross-checked against other NDIS PDO’s that may be in
the same team. Hence, the Bus driver exports a WMI interface for
manipulating team membership / VLAN configuration on a global level, and
can cross-check everything for consistency.

  • What about having the bus driver write to the registry
    (IoOpenDeviceRegistry(pdo,PLUGPLAY_REGKEY_DRIVER,…)/ZwXxxx) *and* notify
    the Miniport via a private interface negotiated via IRP_MN_QUERY_INTERFACE?

Yes, this is the way I am leaning:

  1. Bus driver checks param for global consistency / uniqueness etc (e.g.
    VLAN Tagging when combined with teaming).
  2. Bus driver informs NDIS device of parameter change.
  3. NDIS device modifies volatile config (if OK), and informs bus driver
    whether parameter in range and/or restart needed.
  4. Bus driver writes registry config, and restarts NDIS device if required.
  • What is wrong with stopping/starting the PnP device? I presume that these
    configuration changes are are a result of some administrative or operational
    action initiated in usermode. Why not just do it all there and leave the
    bus driver blissfully un-aware (although it would know its PDO was just
    stopped) and let the NDIS Miniport just pickup the new configuration when
    MiniportInitialize() is called on the restart? Is this something you
    *need* to do from kernel mode?

From my point of view, it’s very advantageous to do from kernel mode
rather than user mode:

  1. We can provide a WMI interface for Teaming / VLAN changes that “any
    old” user app can use, without having to know the details, and that
    management app can obtain a “global unified view” of what’s going on
    very easily.
  2. The consistency of configuration and “re-plumbing” of config and
    datapaths is carried out in one place. This removes an awful lot of
    problems with respect to ensuring consistent configuration across many
    NDIS devices.
  3. Using WDF dynamic enumeration, it’s surprisingly easy to un-enumerate
    and re-enumerate an NDIS device.

MH.

> Haha :slight_smile: WMI is what’s got me into this hole in the first place.

Yeah, ok, everyone sort of reaches that place :slight_smile: but I was referring to
using the NDIS-WMI mapper to expose custom operational control via private
OIDs and not WMI in the bus driver. But the point is probably moot.

  1. Using WDF dynamic enumeration, it’s surprisingly
    easy to un-enumerate and re-enumerate an NDIS device.

I would not presume to know *anyting* about the requirements and design
decisions that led you to build a bus driver but I have to ask the standard
NDIS guy question to cover the base :slight_smile: -

Have you considered a MUX driver? (And I am sure the answer is yes and that
you have really good reasons to build a bus driver but the next newbie
reading this might think - hey, teaming, virtual VLANs, let’s build a KMDF
bus driver and have a go of it. They too should convince themselves that a
NDIS IM MUX is *not* the right thing first.)

Using NDIS IM driver architecture and using
NdisIMDeinitializeDeviceInstance()/NdisIMIntializeDeviceInstanceEx() it is
likewise pretty easy to make a virtual miniport re-initialize. Of course,
the miniport PDOs are root enumerated in this case and I think they are just
simply being stopped/started but is de-enumeration necessary?

Good Luck,
-dave

David R. Cattley
Consulting Engineer
Systems Software Development

David R. Cattley wrote:

Have you considered a MUX driver? (And I am sure the answer is yes and that
you have really good reasons to build a bus driver but the next newbie
reading this might think - hey, teaming, virtual VLANs, let’s build a KMDF
bus driver and have a go of it. They too should convince themselves that a
NDIS IM MUX is *not* the right thing first.)

Yes, we did consider that for a while. We decided not to on the basis of
several issues, including dev time, the various things we might have to
interoperate with (and whether they had vendor neutral implementations
of teaming), and last but not least, the requirement to get 10Gb/s data
throughput with an absolute minimum of CPU load.

Using NDIS IM driver architecture and using
NdisIMDeinitializeDeviceInstance()/NdisIMIntializeDeviceInstanceEx() it is
likewise pretty easy to make a virtual miniport re-initialize. Of course,
the miniport PDOs are root enumerated in this case and I think they are just
simply being stopped/started but is de-enumeration necessary?

I agree de-enumation is a bit of a sledgehammer - I’m looking at lighter
weight options.

MH.