Is this possible?

Hi all,

I have written a USB Device driver.
I need a Virtual network adapter [like NetVMini in DDK examples] to open when i plug in my PnP USB device i.e as part of the DriverEntry process for my USB Device, i should be able to register a NDIS miniport and when i unplug my USB device the miniport should disappear too.

In a way, my USB device driver should act partly like a NetVMini Network device driver for my virtual network adapter.

Is this possible?

If yes, do i just need to merge the .inf files of the USB device and the NetVMini device? By doing so, will i be able to see a “USB Device” and a “Network Adapter” in my device manager window?

Thanks for the pointers. Appreciate your inputs a lot.

The best thing to do here is just to write USB driver plus virtual miniport one, and make virtual miniport deal with USB driver on its lower edge and with NDIS on its upper one

Anton Bassov

That depends on what you’re trying to do. If there is a 1:1 mapping from your USB function to NDIS miniport instance, then you are simply implementing an NDIS/WDM driver. Your devices will speak the NDIS miniport interface on top, and will send WDM (USB) requests down the stack. I believe this situation is covered in the DDK docs. This is the “easy” case because WDM basically hands your device driver a ready-made device stack, and your job is to fill in the goop between the NDIS miniport interface and the USB stack API. In this situation, it doesn’t sound like you have a “virtual” device – you have a USB device (definitely a physical device, or at least physical from this point of view), and you need to plug it into NDIS.

But if you don’t have a 1:1 mapping, then you’ll need to solve a few design issues before you can continue, and before more definite answers are possible. How many NDIS miniport instances do you want, when do they get started, torn down, how does data flow from hardware to NDIS miniport, and the other direction, etc.? The answers depends a lot on what you are trying to do. What does your USB device look like?

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Thursday, April 19, 2007 11:10 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Is this possible?

Hi all,

I have written a USB Device driver.
I need a Virtual network adapter [like NetVMini in DDK examples] to open when i plug in my PnP USB device i.e as part of the DriverEntry process for my USB Device, i should be able to register a NDIS miniport and when i unplug my USB device the miniport should disappear too.

In a way, my USB device driver should act partly like a NetVMini Network device driver for my virtual network adapter.

Is this possible?

If yes, do i just need to merge the .inf files of the USB device and the NetVMini device? By doing so, will i be able to see a “USB Device” and a “Network Adapter” in my device manager window?

Thanks for the pointers. Appreciate your inputs a lot.


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

Hi Arlie,

There is a 1:1 mapping between USB device and miniport instance.
Currently, the driver is a purely WDM driver i.e it uses IRPs on both upper and lower edge.
I am using the “DisptachRoutine” table - DispatchRead/DispatchCreate/DispatchWrite, etc on the upper edge of my driver to communicate with the application.

But in a classic NdisWDM driver, the upper edge exposes only Ndis Miniport interface.

I tried to open and register a network adapter in my existing WDM driver. The miniport registration routine returns with Ndis status success but then the OS (I/O manager or PnP manager) fails to automatically invoke the MiniportInitialize routine.

In a classic WDM driver, we have a DriverEntry and a AddDevice routine. In a NdisWDM driver, we have a DriverEntry and a MPInitialise (miniportintialize) routine. I guess, i am confused as to how to make my WDM driver open/register and initialize the miniport like a miniport driver manages to do.

Is writing two different drivers the only solution?

Thanks.

You are either going to need two drivers, or rewrite your driver to be an
NDIS/WDM or better yet an NDIS/KMDF driver. You should not call NDIS
functions from a WDM driver, this will nor work.


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply

wrote in message news:xxxxx@ntdev…
> Hi Arlie,
>
> There is a 1:1 mapping between USB device and miniport instance.
> Currently, the driver is a purely WDM driver i.e it uses IRPs on both
> upper and lower edge.
> I am using the “DisptachRoutine” table -
> DispatchRead/DispatchCreate/DispatchWrite, etc on the upper edge of my
> driver to communicate with the application.
>
> But in a classic NdisWDM driver, the upper edge exposes only Ndis
> Miniport interface.
>
> I tried to open and register a network adapter in my existing WDM driver.
> The miniport registration routine returns with Ndis status success but
> then the OS (I/O manager or PnP manager) fails to automatically invoke
> the MiniportInitialize routine.
>
> In a classic WDM driver, we have a DriverEntry and a AddDevice routine.
> In a NdisWDM driver, we have a DriverEntry and a MPInitialise
> (miniportintialize) routine. I guess, i am confused as to how to make my
> WDM driver open/register and initialize the miniport like a miniport
> driver manages to do.
>
> Is writing two different drivers the only solution?
>
> Thanks.
>
>

> I tried to open and register a network adapter in my existing WDM driver. The

miniport registration routine returns with Ndis status success but then the OS
(I/O manager or PnP manager) fails to automatically invoke the
MiniportInitialize routine.

Why do you think MiniportInitialize routine() should be invoked in a driver than has no mentioning under
HKLM \SYSTEM\CurrentControlSet\Control\Class{4D36E972-E325-11CE-BFC1-08002bE10318} registry key??? MiniportInitialize routine() gets invoked by NDIS wrapper, rather than by I/O manager or PnP manager, and it gets invoked only if your miniport driver been has installed properly. This is what INF files are for…

Furthermore, after all call to NdisMRegisterMiniport() has been made you cannot create devices with IoCreateDevice() - if you do, these devices will be not really functional, although IoCreateDevice() returns successfully. For example, if someone tries to open this device with CreateFile(), you will get a call to IRP_MJ_CREATE handler that will be immediately followed by the one IRP_MJ_CLOSE handler (this call will be done by NDIS wrapper), so that callers would be unable to access your devices. If you want your driver to communicate with non-NDIS clients you have to register a standalone device with NdisMRegisterDevice().

To summarize, mixing NDIS and WDM in the same driver is not a good idea. As I told you already, the best option here is to write 2 drivers

Anton Bassov

As Anton said, “mixing NDIS and WDM in the same driver is a bad idea.” But let me clarify that – the same driver cannot use both NDIS and WDM as its “top” edge, at least not without some dancing.

So the next question is – what kind of WDM requests do you need to perform on the “top” edge? If you build an NDIS driver, then NDIS controls your top edge. You receive network packets, indicate packets, handle set/get property requests, etc. You don’t get IRP_MJ_CREATE, or IRP_MJ_DEVICE_CONTROL, etc. These are all “consumed” or hidden by the NDIS wrapper layer. This is because your device is supposed to look and feel like a network device, not a WDM device.

So what kind of requests do you need to send down? Who will send those requests? If you need to manage configuration or status information, then NDIS provides a decent framework for that. But if you need something else (I don’t know what – you tell me), then you may need to use one of the uglier aspects of NDIS. You may need to use NdisMRegisterDevice, which will allow your driver to create a single WDM-style device object. A *single* device object – all of your miniports will need to multiplex access through this single device object.

But before continuing, is this necessary? What are you trying to do?

A few linkes on NdisMRegisterDevice:

http://msdn2.microsoft.com/en-us/library/ms804174.aspx
http://www.ndis.com/faq/QA10290101.htm

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Saturday, April 21, 2007 10:20 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Is this possible?

Hi Arlie,

There is a 1:1 mapping between USB device and miniport instance.
Currently, the driver is a purely WDM driver i.e it uses IRPs on both upper and lower edge.
I am using the “DisptachRoutine” table - DispatchRead/DispatchCreate/DispatchWrite, etc on the upper edge of my driver to communicate with the application.

But in a classic NdisWDM driver, the upper edge exposes only Ndis Miniport interface.

I tried to open and register a network adapter in my existing WDM driver. The miniport registration routine returns with Ndis status success but then the OS (I/O manager or PnP manager) fails to automatically invoke the MiniportInitialize routine.

In a classic WDM driver, we have a DriverEntry and a AddDevice routine. In a NdisWDM driver, we have a DriverEntry and a MPInitialise (miniportintialize) routine. I guess, i am confused as to how to make my WDM driver open/register and initialize the miniport like a miniport driver manages to do.

Is writing two different drivers the only solution?

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

Hi All,
Thanks for all your inputs. Looks like, I definitely need two drivers - one WDM drivers exposing IRP_MJ_xxx kinda "TOP-EDGE "interface and another an NDISWDM miniport driver exposing Ndis Top-edge interface.

Don - I am not sure about KMDF model. And i think, given the time constraints, i will have to get this driver off my table with WDM. For my next driver, i surely intend to update myself with the new framework.

I have been resisting writing two drivers because of my lack of expertise in inter-driver communication. But looks like i have no choice now.

So, folks, kindly point me to appropriate literature on “Do’s and Dont’s” of managing multiple drivers. I would love to -

  1. Make my network adapter PnP - i.e when i plug my USB device, the network adapter should load and when i remove my USB device, the network adapter should unload/shutdown.

  2. In my case, my WDM driver will be providing IP packets to the miniport driver. Yes, the flow of information is one-way - always from the WDM to the miniport driver. Do i use IRPs’ to do this?

  3. How will my WDM driver know the existence of a “network adapter” device object and how will it address it (handle to the device object, etc.)?

  4. Will i need two different INF files - one for the USB device (Vendor ID and product ID) and one for the Network device (Ndis\Interfaces)?

  5. The order of loading these two drivers - i guess my network adapter should load first.

I know that it’s a long list. I would appreciate if you can direct me to the right resources

Thanks in advance.

Actually, given your time constraints, the only way you can get this
project done is using KMDF. The intricacies of WDM are going to bite
you very quickly.

This is what I think you should do. Write a bus driver. This is the
WDM top edge part of the design. You can communicate with user mode or
anything else as much as you want. This driver will control the usb
parts of the device (select config, etc). Your bus driver will
enumerate one PDO. Your 2nd NDIS miniport driver will load on this PDO.
This means the WDM part will always load and start before the NDIS part.
Your miniport driver can use IRPs or a direct call interface (acquired
via query interface) to get data from the bus driver FDO.

To answer your questions with respect to the proposed design:

  1. by enumerating the NDIS stack from your driver, the NDIS stack’s pnp
    state is tied to your bus driver’s state
  2. for pushing up data into the NDIS stack, I would use a direct call.
  3. your bus driver has a PDO, all information flows through the PDO
  4. yes, 2 INFs is probably the right way to go, you don’t want to
    install the bus driver in the net class
  5. in this design, the bus driver loads first, then the NDIS part

D

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Monday, April 23, 2007 8:52 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Is this possible?

Hi All,
Thanks for all your inputs. Looks like, I definitely need two drivers -
one WDM drivers exposing IRP_MJ_xxx kinda "TOP-EDGE "interface and
another an NDISWDM miniport driver exposing Ndis Top-edge interface.

Don - I am not sure about KMDF model. And i think, given the time
constraints, i will have to get this driver off my table with WDM. For
my next driver, i surely intend to update myself with the new framework.

I have been resisting writing two drivers because of my lack of
expertise in inter-driver communication. But looks like i have no choice
now.

So, folks, kindly point me to appropriate literature on “Do’s and
Dont’s” of managing multiple drivers. I would love to -

  1. Make my network adapter PnP - i.e when i plug my USB device, the
    network adapter should load and when i remove my USB device, the network
    adapter should unload/shutdown.

  2. In my case, my WDM driver will be providing IP packets to the
    miniport driver. Yes, the flow of information is one-way - always from
    the WDM to the miniport driver. Do i use IRPs’ to do this?

  3. How will my WDM driver know the existence of a “network adapter”
    device object and how will it address it (handle to the device object,
    etc.)?

  4. Will i need two different INF files - one for the USB device (Vendor
    ID and product ID) and one for the Network device (Ndis\Interfaces)?

  5. The order of loading these two drivers - i guess my network adapter
    should load first.

I know that it’s a long list. I would appreciate if you can direct me to
the right resources

Thanks in advance.


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

Makes sense Doron.
One quick question about KMDF before i start digging in.
Is KMDF a driver framework for re-writing just the WDM drivers or is it a framework applicable for miniport drivers too?
Thanks.

ok. i think i got my answer for my last question on kmdf. please ignore it.
thanks all.

Hi Doran,

I am now able to make the miniport driver PnP as suggested by you by integrating the bus driver functionality into my function driver.

I am not able to think how i would now pump the IP packets from the function/bus driver into the ndis miniport driver. You mentioned

  1. for pushing up data into the NDIS stack, I would use a direct call.

What is direct call? And should i register some sort of interface on my function/bus driver and/or miniport driver?

If i am right, the device stack currently looks something like

Function/Bus Driver (parent) -----------------> (child) PDO <--------> miniport FDO

How did i get the data from the parent FDO driver to the miniport FDO driver?

Thanks.

Direct call means that you are passing function pointers down the stack instead using IRPs. First, register to handle a query interface on the child PDO by calling WdfDeviceAddQueryInterface on the PDO. Second, in the miniport FDO you send a IRP_MJ_PNP/IRP_MN_QUERY_INTERFACE (or WdfFdoQueryForInterface if the miniport is written using KMDF) to register the function that is implemented in the miniport FDO with the PDO. The PDO or the bus driver(parent) device then calls this function when it has data to push up. You can define the structure that defines the interface, but it must start with the INTERFACE header. The signature of the direct call function cal be anything you want.

d

Thank You.

Hi Doron,

Excuse me. I got confused while implementing the direct-call inteface.

First, register to handle a query interface on the child PDO by calling WdfDeviceAddQueryInterface on the PDO.


This happens in the bus driver(parent), right?

If the answer is yes, then is this statement valid? -


The PDO or the bus driver(parent) device then calls this function when it has data to push up.

The bus/parent driver exports an interface that miniport driver can query and use, right?
Or is it the other way around?

According to my requirement, the info flows from the bus/parent driver to the miniport driver. So, should not i then be sending an IRP_MJ_PNP/IRP_MN_QUERY_INTERFACE or or WdfFdoQueryForInterface from the bus/parent driver?

I am sorry. I am just confused. I looked at the toaster example and it looks like the toaster driver is the one that calls functions registered in the bus driver and not the other way round.

Kindly advise if you have a minute.

Thanks in advance.

The query interface structure can contain both input and output
parameters. The miniport FDO sets the input value in the structure and
the bus PDO captures the value.

First read this,
http://blogs.msdn.com/doronh/archive/2007/03/06/interfaces-can-contain-b
oth-input-and-output-parameters-and-not-just-function-pointers.aspx

And then this,
http://blogs.msdn.com/doronh/archive/2007/03/12/supporting-query-interfa
ce-in-kmdf.aspx

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Monday, May 07, 2007 7:07 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Is this possible?

Hi Doron,

Excuse me. I got confused while implementing the direct-call inteface.

First, register to handle a query interface on the child PDO by
calling WdfDeviceAddQueryInterface on the PDO.


This happens in the bus driver(parent), right?

If the answer is yes, then is this statement valid? -


The PDO or the bus driver(parent) device then calls this function when
it has data to push up.

The bus/parent driver exports an interface that miniport driver can
query and use, right?
Or is it the other way around?

According to my requirement, the info flows from the bus/parent driver
to the miniport driver. So, should not i then be sending an
IRP_MJ_PNP/IRP_MN_QUERY_INTERFACE or or WdfFdoQueryForInterface from the
bus/parent driver?

I am sorry. I am just confused. I looked at the toaster example and it
looks like the toaster driver is the one that calls functions registered
in the bus driver and not the other way round.

Kindly advise if you have a minute.

Thanks in advance.


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

Hi All,

I am feeling good about where i am in the project. Thanks for all your support (particularly Doron).

I have one question, not very crictical though.

I see a message on the debugger in the process of installing the driver. The drivers (USB function/bus driver and the miniport network driver) are all installing properly. But i see this message -

IPX: Failed to allocate 176 bytes for IO error log entry.

I have no clue what this “warning” message is. As i said, since the driver installations are happening smoothly as planned, i am not worrying too much about this message. Am i being too naive? Is this some message that will bite me really hard sometime later?

Thanks in advance.