NDIS passthru: transferring data to user space

Hi!

I’m a newbie in driver development and I’d like to ask a few questions about NDIS and kernel-user-io in general.

I’ve started with the “Passthru Extended Example - Part 2”, which gives a complete implementation of an NDIS4/5.x packet-filter based on ip numbers. I’d like to extend this example. I need to fill large buffers with packet payload and move these buffers into user space.

Although I’m new to driver development, I’m already a bit familiar with the NDIS world. I wont expect any problems with standard packet handling tasks (parsing, dropping, creating).

The big problem is missing knowledge of window’s standard driver mechanisms. I guess this is the point, why one should not start learning driver development by writing NDIS components… Therefore, the most important questions are, what exactly do I need to learn, and where to start.

To be more specific:

The passthru extended example (thomas’ version to be precise) already registers a Device via NdisMRegisterDevice. (Which should be equivalent to IoCreateDevice if I’m not wrong.) For my application, this device needs an additional high-throughput pipeline to userspace. I’m assuming, that I need to register a handler for IRP_MJ_READ, supporting DO_DIRECT_IO.
Then I could have a userspace dll queueing several reads in advance. The driver should get a memory buffer with each read request. Once a buffer is filled, the corresponding read request can be completed.

This are my ideas so far - after reading some bits about the basics. Did I make any obvious mistakes? Is this (roughly) the preferred way for pushing big blocks of data into userspace?

Do you have any advice, what I should read next? I’ve still some hope, that theres a document like ‘high performance driver buffer handling’, explaining everything I miss about the non-NDIS basics, but unfortunately, I haven’t found it yet.

Comments inline…

Thomas F. Divine

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-321411-
xxxxx@lists.osr.com] On Behalf Of xxxxx@alliedvisiontec.com
Sent: Thursday, April 17, 2008 10:19 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] NDIS passthru: transferring data to user space

Hi!

I’m a newbie in driver development and I’d like to ask a few questions
about NDIS and kernel-user-io in general.

I’ve started with the “Passthru Extended Example - Part 2”, which gives
a complete implementation of an NDIS4/5.x packet-filter based on ip
numbers. I’d like to extend this example. I need to fill large buffers
with packet payload and move these buffers into user space.

Although I’m new to driver development, I’m already a bit familiar with
the NDIS world. I wont expect any problems with standard packet
handling tasks (parsing, dropping, creating).

The big problem is missing knowledge of window’s standard driver
mechanisms. I guess this is the point, why one should not start
learning driver development by writing NDIS components… Therefore,
the most important questions are, what exactly do I need to learn, and
where to start.

To be more specific:

The passthru extended example (thomas’ version to be precise) already
registers a Device via NdisMRegisterDevice. (Which should be equivalent
to IoCreateDevice if I’m not wrong.) For my application, this device
needs an additional high-throughput pipeline to userspace. I’m
assuming, that I need to register a handler for IRP_MJ_READ, supporting
DO_DIRECT_IO.
Then I could have a userspace dll queueing several reads in advance.
The driver should get a memory buffer with each read request. Once a
buffer is filled, the corresponding read request can be completed.

This are my ideas so far - after reading some bits about the basics.
Did I make any obvious mistakes? Is this (roughly) the preferred way
for pushing big blocks of data into userspace?

[PCAUSA] I think that the approach you have in mind will probably satisfy your needs without being too exotic.

Basically, post multiple concurrent reads with large buffers and have driver queue them. As data is received, dequeue a read IRP and begin filling it. Pretty straightforward.

In user mode study various ways to handle asynchronous I/O. See the MSDN topic “I/O Concepts”. Start using the simpler methods, but eventually consider I/O Completion Ports.

There are other schemes, but ignore them for now. One would be to have the application allocate large memory which is then passed to the driver and locked. This “shared memory” can be used BUT there are fairly messy synchronization issues. In many cases the synchronization between user/kernel space may be the performance-limiting issue. This has been discussed in the archives, so start there.

In any event, think in advance about the various bottlenecks involved in sinking the data. It won’t matter at all if you have a wonderful high-performance API between your application and the driver IF you can’t get rid of the data fast enough. If data is going to a file - perhaps the driver should write to the file without involving the user-mode application at all (except for configuration, file name, etc.).

Good luck,

Thomas F. Divine

Do you have any advice, what I should read next? I’ve still some hope,
that theres a document like ‘high performance driver buffer handling’,
explaining everything I miss about the non-NDIS basics, but
unfortunately, I haven’t found it yet.


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