Discussion:
XP SP2 WDM driver - Sharing Memory between driver and application
(too old to reply)
Paulo
2005-01-12 19:46:18 UTC
Permalink
:
Hi all,

I have to confess... I'm almost translating my application from
Windows to Linux just because I can't make a WDM driver for my PCI
card... Help me, please!
I have a motion control PCI card that can command 2 motors. That
card generate interrupts. I have an application and an old driver (VxD)
working very well with Windows 98 SE, but now I'm trying to make a WDM
driver for Windows XP Professional SP2 because Microsoft is not selling
Win98 anymore.
In my new WDM driver, the communication with the PCI card from the
driver and from the application (I pass an address from the driver to
the application, so the app can communicate directly with the card) is
tested and working fine. The interrupt service routine (ISR) is working
very weel too.
The only big problem is that I need to share 10 buffers between the
driver and the user app (velocity, aceleration, etc). Those buffers
can't be swaped to the disk and some of then are 1MB length, and one is
9MB lentgth. They are filled with velocity, aceleration and other
information by the application, and the driver fill some buffers with
other kind of information.
My PCI card has no memory, so I have to make use of "user buffers"
(created in the app) or "system buffers" (created in the driver).
The most important thing is that those buffers MUST be used (read &
write) inside the ISR, at any moment, as weel as the buffers MUST be
accessed (read & write) from the user app at any time (of course, not
when the driver is inside the ISR). The app must be running all the time
because it needs to get events from the user to communicate the driver
to start or stop listening to interrupts, so it seems to me that I can't
return STATUS_PENDING with METHOD_DIRECT (can I?).
And the two big questions are:
1. Is that realy possible? (Are you sure?)
2. How?

I've been reading all the posts about this subject from all lists
and years, since Jan.2004 to this day, and I couldn't find a way to get
that driver working ok.
I also have the Viscarola & Mason "Windows NT Device Driver
Development" book... Good help, but couldn't sove the problem.
Can you help me?
Thanks a lot.

Paulo.
Don Burn
2005-01-12 19:56:11 UTC
Permalink
Paulo,

Create a set of IOCTL's to pass the buffers from user space. Use
METHOD_IN_DIRECT for each IOCTL (one for each buffer) and then
MmProbeAndLockPages to lock them into memory. Pend each operation, so if
the application terminates you will get a cancel and be able to cleanup the
buffers.
--
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Remove StopSpam from the email to reply
Post by Paulo
Hi all,
I have to confess... I'm almost translating my application from
Windows to Linux just because I can't make a WDM driver for my PCI
card... Help me, please!
I have a motion control PCI card that can command 2 motors. That
card generate interrupts. I have an application and an old driver (VxD)
working very well with Windows 98 SE, but now I'm trying to make a WDM
driver for Windows XP Professional SP2 because Microsoft is not selling
Win98 anymore.
In my new WDM driver, the communication with the PCI card from the
driver and from the application (I pass an address from the driver to
the application, so the app can communicate directly with the card) is
tested and working fine. The interrupt service routine (ISR) is working
very weel too.
The only big problem is that I need to share 10 buffers between the
driver and the user app (velocity, aceleration, etc). Those buffers
can't be swaped to the disk and some of then are 1MB length, and one is
9MB lentgth. They are filled with velocity, aceleration and other
information by the application, and the driver fill some buffers with
other kind of information.
My PCI card has no memory, so I have to make use of "user buffers"
(created in the app) or "system buffers" (created in the driver).
The most important thing is that those buffers MUST be used (read &
write) inside the ISR, at any moment, as weel as the buffers MUST be
accessed (read & write) from the user app at any time (of course, not
when the driver is inside the ISR). The app must be running all the time
because it needs to get events from the user to communicate the driver
to start or stop listening to interrupts, so it seems to me that I can't
return STATUS_PENDING with METHOD_DIRECT (can I?).
1. Is that realy possible? (Are you sure?)
2. How?
I've been reading all the posts about this subject from all lists
and years, since Jan.2004 to this day, and I couldn't find a way to get
that driver working ok.
I also have the Viscarola & Mason "Windows NT Device Driver
Development" book... Good help, but couldn't sove the problem.
Can you help me?
Thanks a lot.
Paulo.
Paulo
2005-01-13 10:53:21 UTC
Permalink
Post by Don Burn
Paulo,
Create a set of IOCTL's to pass the buffers from user space. Use
METHOD_IN_DIRECT for each IOCTL (one for each buffer) and then
MmProbeAndLockPages to lock them into memory. Pend each operation, so if
the application terminates you will get a cancel and be able to cleanup the
buffers.
Hmmm... New informations :) It's getting better :)
Tell me three things:
MmProbeAndLockPages or MmGetSystemAddressForMdlSafe?
Can I pend an IRP without locking my App?
Can I allocate memory in the App that can't be paged to the disk,
or the only way is to allocate non paged memory in the driver?

Thanks again, you're helping me a lot. When I get it to work I will
send you the solution.
Paulo.
Don Burn
2005-01-13 14:07:56 UTC
Permalink
Paulo,
Post by Paulo
Hmmm... New informations :) It's getting better :)
MmProbeAndLockPages or MmGetSystemAddressForMdlSafe?
Use MmProbeAndLockPages to be sure they are locked down.
Post by Paulo
Can I pend an IRP without locking my App?
Yes if you open the device with CreateFile with FILE_FLAG_OVERLAPPED and use
overlapped I/O for the DeviceIoControl calls.
Post by Paulo
Can I allocate memory in the App that can't be paged to the disk,
or the only way is to allocate non paged memory in the driver?
The app's memory will get locked into physical memory by
MmProbeAndLockPages.
Post by Paulo
Thanks again, you're helping me a lot. When I get it to work I will
send you the solution.
Paulo.
--
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Remove StopSpam from the email to reply
Alexander Grigoriev
2005-01-13 16:09:02 UTC
Permalink
I think METHOD_DIRECT buffer is already locked (but not mapped).
Post by Don Burn
Paulo,
Post by Paulo
Hmmm... New informations :) It's getting better :)
MmProbeAndLockPages or MmGetSystemAddressForMdlSafe?
Use MmProbeAndLockPages to be sure they are locked down.
Post by Paulo
Can I pend an IRP without locking my App?
Yes if you open the device with CreateFile with FILE_FLAG_OVERLAPPED and use
overlapped I/O for the DeviceIoControl calls.
Post by Paulo
Can I allocate memory in the App that can't be paged to the disk,
or the only way is to allocate non paged memory in the driver?
The app's memory will get locked into physical memory by
MmProbeAndLockPages.
Post by Paulo
Thanks again, you're helping me a lot. When I get it to work I will
send you the solution.
Paulo.
--
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Remove StopSpam from the email to reply
Paulo
2005-01-13 18:27:38 UTC
Permalink
Post by Don Burn
Paulo,
Use MmProbeAndLockPages to be sure they are locked down.
With METHOD_IN_DIRECT? I think there's no need to do that... Maybe
if I use METHOD_NEITHER. Am I wrong?
Post by Don Burn
Post by Paulo
Can I pend an IRP without locking my App?
Yes if you open the device with CreateFile with FILE_FLAG_OVERLAPPED and use
overlapped I/O for the DeviceIoControl calls.
I need to pend it during the application lifetime. The application
tells the driver when to map the buffers (app start) and when to unmap
the buffers (app closed). Can I really use FILE_FLAG_OVERLAPPED with 10
calls from the app (10 buffers)? How?

Paulo.
Don Burn
2005-01-13 18:35:15 UTC
Permalink
Post by Paulo
Post by Don Burn
Paulo,
Use MmProbeAndLockPages to be sure they are locked down.
With METHOD_IN_DIRECT? I think there's no need to do that... Maybe
if I use METHOD_NEITHER. Am I wrong?
You are right, I answered this too early in the morning?
Post by Paulo
Post by Don Burn
Post by Paulo
Can I pend an IRP without locking my App?
Yes if you open the device with CreateFile with FILE_FLAG_OVERLAPPED and use
overlapped I/O for the DeviceIoControl calls.
I need to pend it during the application lifetime. The application
tells the driver when to map the buffers (app start) and when to unmap
the buffers (app closed). Can I really use FILE_FLAG_OVERLAPPED with 10
calls from the app (10 buffers)? How?
Just issue device I/O control calls with OVERLAPPED, then put the IRP's on a
cancel safe queue (see IoCsqInitialize) to hold them.
--
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Remove StopSpam from the email to reply
Paulo
2005-01-25 10:44:38 UTC
Permalink
Post by Don Burn
Just issue device I/O control calls with OVERLAPPED, then put the IRP's on a
cancel safe queue (see IoCsqInitialize) to hold them.
It's working now! :o)
But I'm not using shared memory. It seems to me that Windows XP doesn't
have a good solution to do that... threads "eating" my processor time
when I'm using OVERLAPPED I/O looks very "inelegant" to me.
I decided to change the way I use the driver and now I have buffers
created from the nonpaged pool in the driver, and "clones" of those
buffers created in my application (memory today is not so expesive and I
waste only up to 40MB total). I'm using "METHOD_IN_DIRECT" for each
buffer to pass them from my app to the driver (using
mmGetSystemAddressForMdlSafe and copying them to my driver with
RtlCopyMemory), and "METHOD_BUFFERED" to read information from the driver.
Now it's working fine.
Thanks for the help.

Paulo.

JimE
2005-01-12 20:13:02 UTC
Permalink
Just a couple of suggestions - I've never worked on a driver like that:

Get Walter Oney's Programming the Windows Driver Model 2nd edition. It has
most everything you will need to know to write a WDM driver. NT is very
different.

You might attempt to allocate all the buffer space you need from
NonPagedPool when you start your device. I have no idea if that much space
can be allocated, but if it can, it will never get paged to disk.

Sharing buffer space of any type between a user application and a kernel
mode driver is generally not a good idea. A set of custom IOCTL codes to
manipulate the data/device might be a better approach.

Of course, these suggestions are provided without warranty, blah, blah,
blah...
Post by Paulo
Hi all,
I have to confess... I'm almost translating my application from
Windows to Linux just because I can't make a WDM driver for my PCI
card... Help me, please!
I have a motion control PCI card that can command 2 motors. That
card generate interrupts. I have an application and an old driver (VxD)
working very well with Windows 98 SE, but now I'm trying to make a WDM
driver for Windows XP Professional SP2 because Microsoft is not selling
Win98 anymore.
In my new WDM driver, the communication with the PCI card from the
driver and from the application (I pass an address from the driver to
the application, so the app can communicate directly with the card) is
tested and working fine. The interrupt service routine (ISR) is working
very weel too.
The only big problem is that I need to share 10 buffers between the
driver and the user app (velocity, aceleration, etc). Those buffers
can't be swaped to the disk and some of then are 1MB length, and one is
9MB lentgth. They are filled with velocity, aceleration and other
information by the application, and the driver fill some buffers with
other kind of information.
My PCI card has no memory, so I have to make use of "user buffers"
(created in the app) or "system buffers" (created in the driver).
The most important thing is that those buffers MUST be used (read &
write) inside the ISR, at any moment, as weel as the buffers MUST be
accessed (read & write) from the user app at any time (of course, not
when the driver is inside the ISR). The app must be running all the time
because it needs to get events from the user to communicate the driver
to start or stop listening to interrupts, so it seems to me that I can't
return STATUS_PENDING with METHOD_DIRECT (can I?).
1. Is that realy possible? (Are you sure?)
2. How?
I've been reading all the posts about this subject from all lists
and years, since Jan.2004 to this day, and I couldn't find a way to get
that driver working ok.
I also have the Viscarola & Mason "Windows NT Device Driver
Development" book... Good help, but couldn't sove the problem.
Can you help me?
Thanks a lot.
Paulo.
Arkady Frenkel
2005-01-12 20:15:19 UTC
Permalink
Really , that do possible and defined in
http://www.microsoft.com/whdc/driver/kernel/KM-UMGuide.mspx
Arkady
Post by JimE
Get Walter Oney's Programming the Windows Driver Model 2nd edition. It has
most everything you will need to know to write a WDM driver. NT is very
different.
You might attempt to allocate all the buffer space you need from
NonPagedPool when you start your device. I have no idea if that much space
can be allocated, but if it can, it will never get paged to disk.
Sharing buffer space of any type between a user application and a kernel
mode driver is generally not a good idea. A set of custom IOCTL codes to
manipulate the data/device might be a better approach.
Of course, these suggestions are provided without warranty, blah, blah,
blah...
Post by Paulo
Hi all,
I have to confess... I'm almost translating my application from
Windows to Linux just because I can't make a WDM driver for my PCI
card... Help me, please!
I have a motion control PCI card that can command 2 motors. That
card generate interrupts. I have an application and an old driver (VxD)
working very well with Windows 98 SE, but now I'm trying to make a WDM
driver for Windows XP Professional SP2 because Microsoft is not selling
Win98 anymore.
In my new WDM driver, the communication with the PCI card from the
driver and from the application (I pass an address from the driver to
the application, so the app can communicate directly with the card) is
tested and working fine. The interrupt service routine (ISR) is working
very weel too.
The only big problem is that I need to share 10 buffers between the
driver and the user app (velocity, aceleration, etc). Those buffers
can't be swaped to the disk and some of then are 1MB length, and one is
9MB lentgth. They are filled with velocity, aceleration and other
information by the application, and the driver fill some buffers with
other kind of information.
My PCI card has no memory, so I have to make use of "user buffers"
(created in the app) or "system buffers" (created in the driver).
The most important thing is that those buffers MUST be used (read &
write) inside the ISR, at any moment, as weel as the buffers MUST be
accessed (read & write) from the user app at any time (of course, not
when the driver is inside the ISR). The app must be running all the time
because it needs to get events from the user to communicate the driver
to start or stop listening to interrupts, so it seems to me that I can't
return STATUS_PENDING with METHOD_DIRECT (can I?).
1. Is that realy possible? (Are you sure?)
2. How?
I've been reading all the posts about this subject from all lists
and years, since Jan.2004 to this day, and I couldn't find a way to get
that driver working ok.
I also have the Viscarola & Mason "Windows NT Device Driver
Development" book... Good help, but couldn't sove the problem.
Can you help me?
Thanks a lot.
Paulo.
Maxim S. Shatskih
2005-01-12 20:46:20 UTC
Permalink
Send a MDL to the driver via IOCTL request, probe&lock it there, then
MmGetSystemAddressForMdlSafe - and voila, the nonpaged shared memory between
the user app and the ISR.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
***@storagecraft.com
http://www.storagecraft.com
Post by Paulo
Hi all,
I have to confess... I'm almost translating my application from
Windows to Linux just because I can't make a WDM driver for my PCI
card... Help me, please!
I have a motion control PCI card that can command 2 motors. That
card generate interrupts. I have an application and an old driver (VxD)
working very well with Windows 98 SE, but now I'm trying to make a WDM
driver for Windows XP Professional SP2 because Microsoft is not selling
Win98 anymore.
In my new WDM driver, the communication with the PCI card from the
driver and from the application (I pass an address from the driver to
the application, so the app can communicate directly with the card) is
tested and working fine. The interrupt service routine (ISR) is working
very weel too.
The only big problem is that I need to share 10 buffers between the
driver and the user app (velocity, aceleration, etc). Those buffers
can't be swaped to the disk and some of then are 1MB length, and one is
9MB lentgth. They are filled with velocity, aceleration and other
information by the application, and the driver fill some buffers with
other kind of information.
My PCI card has no memory, so I have to make use of "user buffers"
(created in the app) or "system buffers" (created in the driver).
The most important thing is that those buffers MUST be used (read &
write) inside the ISR, at any moment, as weel as the buffers MUST be
accessed (read & write) from the user app at any time (of course, not
when the driver is inside the ISR). The app must be running all the time
because it needs to get events from the user to communicate the driver
to start or stop listening to interrupts, so it seems to me that I can't
return STATUS_PENDING with METHOD_DIRECT (can I?).
1. Is that realy possible? (Are you sure?)
2. How?
I've been reading all the posts about this subject from all lists
and years, since Jan.2004 to this day, and I couldn't find a way to get
that driver working ok.
I also have the Viscarola & Mason "Windows NT Device Driver
Development" book... Good help, but couldn't sove the problem.
Can you help me?
Thanks a lot.
Paulo.
Loading...