How to name a device object in video miniport driver?

Thank Jeffery. Your code is very helpful.

And thank Mats for providing me so much useful information!

Lei

On Fri, 18 Mar 2005 15:52:40 +0000, Mats PETERSSON
wrote:
>
>
> xxxxx@lists.osr.com wrote on 03/18/2005 03:40:40 PM:
>
> > I have another question about the memory mapping.
> >
> > Before I used the ExtEscape in user-mode, I printed the starting
> > address of the input buffer. I also printed the address of input
> > buffer in the DrvEscape() routine. However, I am quite confused that
> > both addresses turned out to be the same.
> >
> > Why the kernel-mode driver and user-mode application share the same
> > value? Is the GDI routines running in the virtual memory space of the
> > user-mode app?
>
> Yes, the ExtEscape will just map[1] the user-mode address into kernel space
> as is, and keep the virtual address. And yes, it will most likely run in
> the virtual space of the application that is running at the moment, and
> whilst you probably shouldn’t rely on that being the case, I’d say that the
> most likely scenario is that all GDI calls are performed completely under
> the task that was running when the call started. [Of course, if you fire
> off a DMA-transfer, and wait for an interrupt from the graphics chip to
> come back with the appropriate KeWaitForSingleObject, some other task will
> probably run for the duration of the wait, as that’s what the OS is
> supposed to do in that situation].
>
> [1]I’m not even sure that it needs to be “mapped” at all. It may just be
> that GDI is passing the original address, and as long as we’re still in the
> same task, it wouldn’t matter. Kernel mode can always access user-space…
> But not the other way around.
>
> –
> Mats
> >
> > Thank you.
> >
> > Lei
> >
> > —
> > Questions? First check the Kernel Driver FAQ at http://www.
> > osronline.com/article.cfm?id=256
> >
> > You are currently subscribed to ntdev as: xxxxx@3dlabs.com
> > To unsubscribe send a blank email to xxxxx@lists.osr.com
>
> > ForwardSourceID:NT0000F08E
>
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@gmail.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

> Sure. I beleive you just call CreateDC with a NULL parameter (it may be

some other Win32 call) to get a handle to the entire screen. Then bitcopy

CreateDC(“DISPLAY”, NULL, NULL, NULL) will do the job.

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

I studied the memory allocation methods these days and found that it
is not that simple.

At the beginning, I allocate a buffer in the driver. When my user-mode
app issue a GDI escape, it waits on an event. After that, another
user-mode app invokes a GDI routine. In the mirror GDI routine, I fill
in the buffer and set the event. But the problem is that my user-mode
app will go on working without copying the data from the buffer when
the event is set.

If we try to use EngAllocateUserMem() to allocate the buffer, there is
another problem. The GDI routine invoked by a latter process can only
access the memory within its virtual space, it cannot switch to the
virtual space of the previous process, i.e. my user-mode app. So it is
still impossible copy the data to my app.

Another bad news is that EngAllocatePrivateUserMem() seems to work
with DirectDraw only…

And I also looked at VideoPortMapMemory(), but it can only map
bus-related physical address.

Lei

On Thu, 17 Mar 2005 16:52:18 +0000, Mats PETERSSON
wrote:
>
>
> You probably could re-map the data to your process, however if the code in
> the calling process does something like:
>
> memset(block, 0xFF, size);
> BitBlt(…, block, size, …);
> memset(block, 0xEE, size);
> BitBlt(…, block, size, …);
>
> What happens if your application sees BOTH bitblt in one of your chunks of
> data because your “copy data from mirror driver” user mode application had
> a lower priority than the above code (perhaps because Windows decides to
> boost priority of the app above).
>
> Now both of your bitblt operations will have 0xEE as the data, rather than
> 0xFF for the first and 0xEE for the second.
>
> Another option of things going wrong would be:
>
> xx = malloc(size);
> …
> BitBlt(… xx, …);
> free(xx);
> …
>
> Now what memory do you have in your user-app?
>
> You would be much better off copying this data in your driver, whilst it’s
> still locked down by the upper GDI layer. [There is of course a performance
> impact of this, but if you do it right, using a “AllocateForUserMode” call
> in your driver, you may be able to pass the data straight to the user-mode
> app without a second copy operation. You may have to invent some way of
> indicating to the user-app that it has a block of data that it needs to
> look at and then free up, but I’m sure that can be done.]
>
> –
> Mats
>
> xxxxx@lists.osr.com wrote on 03/17/2005 04:38:29 PM:
>
> > Thanks for you kind help. I think you have almost solve both problems
> > for me. I just need to have my user-mode application work fast enough
> > so that the circular buffer will not overflow. :slight_smile:
> >
> > Since I am a new driver writer, I have not gone through all the DrvXxx
> > functions. I think they sometimes have to deal with a large block of
> > data, which comes from certain user-mode process. Could I map the
> > pointer to this block of data back to user mode, rather then copy it
> > into my circultar buffer? And how can I make it in display driver?
> >
> > It wil be perfect if this problem is also solved. :slight_smile:
> > Thank you again.
> >
> > Best,
> > Lei
> >
> > On Thu, 17 Mar 2005 16:10:10 +0000, Mats PETERSSON
> > wrote:
> > >
> > >
> > > Ok. so I would use a circular buffer mechanism, where the “read”
> pointer is
> > > ONLY updated when you ask for the data, and the write pointer is only
> > > updated when your display driver is called. So, everything between the
> read
> > > pointer and the write pointer is “fair game” to give to your user-mode
> app.
> > >
> > > I guess your mirror driver will have a separate display-name (or
> Monitor
> > > name), which you can use to call CreateDC to get a hDC to your own
> display
> > > driver. This is what you use to call your ExtEscape. You shouldn’t call
> the
> > > escape on the main monitor (Display1 or Display0 for instance), as that
> > > would probably not have the desired effect. [It should handel
> “unexpected”
> > > Escape calls properly, but it may do funny things if you happen to
> match
> > > something that means something to that display driver].
> > >
> > > –
> > > Mats
> > > xxxxx@lists.osr.com wrote on 03/17/2005 03:54:01 PM:
> > >
> > > > Great, it sounds like a good way to go. Thank you very much.
> > > >
> > > > I think the most difficult thing in this scheme is that there might
> be
> > > > one or more GDI calls invoked between two GDI escape command sent by
> > > > the user-application. So I still have to keep track of what happen
> > > > after the previous event is set. How do you think about it.
> > > >
> > > > And another question is will the GDI escape goes to the primary
> driver
> > > > and cause some unexpected error?
> > > >
> > > > Best,
> > > > Lei
> > > >
> > > > On Thu, 17 Mar 2005 15:31:26 +0000, Mats PETERSSON
> > > > wrote:
> > > > >
> > > > >
> > > > > So, if you want to “poll”, why don’t you do it the other way
> around.
> > > > > Presumably your mirror driver will be called with the same
> information
> > > as
> > > > > the ordinary display driver.
> > > > >
> > > > > So here’s what I’d do:
> > > > > Create a memory region in the display driver (by calling an IOCTL
> to
> > > your
> > > > > Miniport, that allocates a suitable memory region and returns the
> > > address
> > > > > for it to your display driver).
> > > > > Then have the user-mode application call a GDI escape which says
> “I’d
> > > like
> > > > > to be told when there is some GDI calls to process”.
> > > > > - This GDI escape either takes an event as input, or creates an
> event
> > > that
> > > > > is passed to the display driver.
> > > > > The user app then waits for the it’s event.
> > > > >
> > > > > When a GDI drawing call is made to your display driver, you set the
> > > event
> > > > > after you’ve filled the information into your buffer.
> > > > >
> > > > > When the application wakes up after the event, it calls another GDI
> > > Escape
> > > > > to “Fetch all GDI calls since last call”. This GDI call also resets
> the
> > > > > event flag, so that next call to WaitForEvent (WaitForSingleObject
> or
> > > > > whatever you use) will wait again.
> > > > >
> > > > > Does that sound like something you could use?
> > > > >
> > > > > This way, the user-mode application isn’t polling to see if
> anything
> > > > > changed, only fetching information when something ACTUALLY changed.
> > > > >
> > > > > There’s a lot that can be done to optimise the above for particular
> > > types
> > > > > of operations, but as a basic principle, I think it would be
> efficient
> > > and
> > > > > work.
> > > > >
> > > > > –
> > > > > Mats
> > > > >
> > > > > xxxxx@lists.osr.com wrote on 03/17/2005 03:16:14 PM:
> > > > >
> > > > > > Thanks Mats.
> > > > > >
> > > > > > Actually, I plan to intercept the GDI calls in a mirror driver.
> Will
> > > > > > the primary video driver work well if I frequently call
> ExtEscape? I
> > > > > > just want the communicate with the mirror driver.
> > > > > >
> > > > > > I am thinking about allocating a block of memory in miniport
> driver
> > > to
> > > > > > record the GDI function calls. This block of memory is shared
> with
> > > > > > display driver so that it can put down which DrvXxxx functions
> are
> > > > > > called. The memory is also shared with a user-mode application,
> which
> > > > > > polls it to see what happens in the driver.
> > > > > >
> > > > > > So I also wonder whether this method will be effective eoungh
> since
> > > > > > polling may be frequent.
> > > > > >
> > > > > > Thank you.
> > > > > >
> > > > > > Lei
> > > > > >
> > > > > >
> > > > > > On Thu, 17 Mar 2005 09:12:54 +0000, Mats PETERSSON
> > > > > > wrote:
> > > > > > >
> > > > > > >
> > > > > > > Generally, we solve this sort of situation by wrapping the
> IOCTL
> > > with
> > > > > an
> > > > > > > GDI Escape (using the ExtEscape function call, which ends up in
> > > your
> > > > > > > drivers DrvEscape), so your user applicaiton would call the
> escape
> > > for
> > > > > the
> > > > > > > DISPLAY, and the display driver would call the IOCTL using the
> > > handle
> > > > > that
> > > > > > > we’re given early on in the driver initialization. Thus
> avoiding
> > > > > actually
> > > > > > > exposing a “Video” device, which is not how Microsoft intended
> > > things,
> > > > > and
> > > > > > > that’s why you can’t call the ioCreateDevice.
> > > > > > >
> > > > > > > –
> > > > > > > Mats
> > > > > > >
> > > > > > > xxxxx@lists.osr.com wrote on 03/17/2005 05:15:51
> AM:
> > > > > > >
> > > > > > > > I am going to have a user-mode application to talk with video
> > > > > miniport
> > > > > > > > driver by IOCTL. I have to specify the device object name
> when I
> > > use
> > > > > > > > CreateFile in user-mode application. However, there are no
> video
> > > port
> > > > > > > > routines that can be used to create a device object. I cannot
> use
> > > > > > > > IoCreateDevice either. So I am unable to specify a name for
> the
> > > > > device
> > > > > > > > object.
> > > > > > > >
> > > > > > > > So my question is, how to name a device object in video
> miniport
> > > > > driver?
> > > > > > > >
> > > > > > > > Can anyone give me some hints on that? Thank you.
> > > > > > > >
> > > > > > > > Lei
> > > > > > > >
> > > > > > > > —
> > > > > > > > Questions? First check the Kernel Driver FAQ at http://www.
> > > > > > > > osronline.com/article.cfm?id=256
> > > > > > > >
> > > > > > > > You are currently subscribed to ntdev as:
> > > xxxxx@3dlabs.com
> > > > > > > > To unsubscribe send a blank email to
> > > xxxxx@lists.osr.com
> > > > > > >
> > > > > > > > ForwardSourceID:NT0000ECE6
> > > > > > >
> > > > > > > —
> > > > > > > Questions? First check the Kernel Driver FAQ at http://www.
> > > > > > osronline.com/article.cfm?id=256
> > > > > > >
> > > > > > > You are currently subscribed to ntdev as: xxxxx@gmail.com
> > > > > > > To unsubscribe send a blank email to
> > > xxxxx@lists.osr.com
> > > > > > >
> > > > > >
> > > > > > —
> > > > > > Questions? First check the Kernel Driver FAQ at http://www.
> > > > > > osronline.com/article.cfm?id=256
> > > > > >
> > > > > > You are currently subscribed to ntdev as:
> xxxxx@3dlabs.com
> > > > > > To unsubscribe send a blank email to
> xxxxx@lists.osr.com
> > > > >
> > > > > > ForwardSourceID:NT0000ED46
> > > > >
> > > > > —
> > > > > Questions? First check the Kernel Driver FAQ at http://www.
> > > > osronline.com/article.cfm?id=256
> > > > >
> > > > > You are currently subscribed to ntdev as: xxxxx@gmail.com
> > > > > To unsubscribe send a blank email to
> xxxxx@lists.osr.com
> > > > >
> > > >
> > > > —
> > > > Questions? First check the Kernel Driver FAQ at http://www.
> > > > osronline.com/article.cfm?id=256
> > > >
> > > > You are currently subscribed to ntdev as: xxxxx@3dlabs.com
> > > > To unsubscribe send a blank email to xxxxx@lists.osr.com
> > >
> > > > ForwardSourceID:NT0000ED56
> > >
> > > —
> > > Questions? First check the Kernel Driver FAQ at http://www.
> > osronline.com/article.cfm?id=256
> > >
> > > You are currently subscribed to ntdev as: xxxxx@gmail.com
> > > To unsubscribe send a blank email to xxxxx@lists.osr.com
> > >
> >
> > —
> > Questions? First check the Kernel Driver FAQ at http://www.
> > osronline.com/article.cfm?id=256
> >
> > You are currently subscribed to ntdev as: xxxxx@3dlabs.com
> > To unsubscribe send a blank email to xxxxx@lists.osr.com
>
> > ForwardSourceID:NT0000ED76
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@gmail.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

You are correct in that the user-mode memory is not available when running
in a different user process.

However, when you get the call from the user-mode app, you know that it’s
your user-mode app, so you can THEN allocate for that user. But you could
also let the user-mode app supply a buffer. It doesn’t make a tremendous
difference either way. One thing to consider would be to have a
“auto-expanding” buffer that is kept around by the user-mode app. So you
start with a relatively small buffer that you allocate with malloc and pass
to the driver via an Escape. The escape passes back the size of the data
that it copied and how much is left to copy. If what’s left is bigger than
the current buffer-size, you double the current buffer-size until it’s
bigger than “what’s left”. Within reason of course, if your buffer ends up
being several megabytes, you’ll eventually fill the whole memory. So limit
the buffer to, say 4MB or so. Start with something like 32KB.


Mats

xxxxx@lists.osr.com wrote on 03/19/2005 06:26:06 PM:

I studied the memory allocation methods these days and found that it
is not that simple.

At the beginning, I allocate a buffer in the driver. When my user-mode
app issue a GDI escape, it waits on an event. After that, another
user-mode app invokes a GDI routine. In the mirror GDI routine, I fill
in the buffer and set the event. But the problem is that my user-mode
app will go on working without copying the data from the buffer when
the event is set.

If we try to use EngAllocateUserMem() to allocate the buffer, there is
another problem. The GDI routine invoked by a latter process can only
access the memory within its virtual space, it cannot switch to the
virtual space of the previous process, i.e. my user-mode app. So it is
still impossible copy the data to my app.

Another bad news is that EngAllocatePrivateUserMem() seems to work
with DirectDraw only…

And I also looked at VideoPortMapMemory(), but it can only map
bus-related physical address.

Lei

On Thu, 17 Mar 2005 16:52:18 +0000, Mats PETERSSON
wrote:
> >
> >
> > You probably could re-map the data to your process, however if the code
in
> > the calling process does something like:
> >
> > memset(block, 0xFF, size);
> > BitBlt(…, block, size, …);
> > memset(block, 0xEE, size);
> > BitBlt(…, block, size, …);
> >
> > What happens if your application sees BOTH bitblt in one of your chunks
of
> > data because your “copy data from mirror driver” user mode application
had
> > a lower priority than the above code (perhaps because Windows decides
to
> > boost priority of the app above).
> >
> > Now both of your bitblt operations will have 0xEE as the data, rather
than
> > 0xFF for the first and 0xEE for the second.
> >
> > Another option of things going wrong would be:
> >
> > xx = malloc(size);
> > …
> > BitBlt(… xx, …);
> > free(xx);
> > …
> >
> > Now what memory do you have in your user-app?
> >
> > You would be much better off copying this data in your driver, whilst
it’s
> > still locked down by the upper GDI layer. [There is of course a
performance
> > impact of this, but if you do it right, using a “AllocateForUserMode”
call
> > in your driver, you may be able to pass the data straight to the
user-mode
> > app without a second copy operation. You may have to invent some way of
> > indicating to the user-app that it has a block of data that it needs to
> > look at and then free up, but I’m sure that can be done.]
> >
> > –
> > Mats
> >
> > xxxxx@lists.osr.com wrote on 03/17/2005 04:38:29 PM:
> >
> > > Thanks for you kind help. I think you have almost solve both problems
> > > for me. I just need to have my user-mode application work fast enough
> > > so that the circular buffer will not overflow. :slight_smile:
> > >
> > > Since I am a new driver writer, I have not gone through all the
DrvXxx
> > > functions. I think they sometimes have to deal with a large block of
> > > data, which comes from certain user-mode process. Could I map the
> > > pointer to this block of data back to user mode, rather then copy it
> > > into my circultar buffer? And how can I make it in display driver?
> > >
> > > It wil be perfect if this problem is also solved. :slight_smile:
> > > Thank you again.
> > >
> > > Best,
> > > Lei
> > >
> > > On Thu, 17 Mar 2005 16:10:10 +0000, Mats PETERSSON
> > > wrote:
> > > >
> > > >
> > > > Ok. so I would use a circular buffer mechanism, where the “read”
> > pointer is
> > > > ONLY updated when you ask for the data, and the write pointer is
only
> > > > updated when your display driver is called. So, everything between
the
> > read
> > > > pointer and the write pointer is “fair game” to give to your
user-mode
> > app.
> > > >
> > > > I guess your mirror driver will have a separate display-name (or
> > Monitor
> > > > name), which you can use to call CreateDC to get a hDC to your own
> > display
> > > > driver. This is what you use to call your ExtEscape. You shouldn’t
call
> > the
> > > > escape on the main monitor (Display1 or Display0 for instance), as
that
> > > > would probably not have the desired effect. [It should handel
> > “unexpected”
> > > > Escape calls properly, but it may do funny things if you happen to
> > match
> > > > something that means something to that display driver].
> > > >
> > > > –
> > > > Mats
> > > > xxxxx@lists.osr.com wrote on 03/17/2005 03:54:01 PM:
> > > >
> > > > > Great, it sounds like a good way to go. Thank you very much.
> > > > >
> > > > > I think the most difficult thing in this scheme is that there
might
> > be
> > > > > one or more GDI calls invoked between two GDI escape command sent
by
> > > > > the user-application. So I still have to keep track of what
happen
> > > > > after the previous event is set. How do you think about it.
> > > > >
> > > > > And another question is will the GDI escape goes to the primary
> > driver
> > > > > and cause some unexpected error?
> > > > >
> > > > > Best,
> > > > > Lei
> > > > >
> > > > > On Thu, 17 Mar 2005 15:31:26 +0000, Mats PETERSSON
> > > > > wrote:
> > > > > >
> > > > > >
> > > > > > So, if you want to “poll”, why don’t you do it the other way
> > around.
> > > > > > Presumably your mirror driver will be called with the same
> > information
> > > > as
> > > > > > the ordinary display driver.
> > > > > >
> > > > > > So here’s what I’d do:
> > > > > > Create a memory region in the display driver (by calling an
IOCTL
> > to
> > > > your
> > > > > > Miniport, that allocates a suitable memory region and returns
the
> > > > address
> > > > > > for it to your display driver).
> > > > > > Then have the user-mode application call a GDI escape which
says
> > “I’d
> > > > like
> > > > > > to be told when there is some GDI calls to process”.
> > > > > > - This GDI escape either takes an event as input, or creates an
> > event
> > > > that
> > > > > > is passed to the display driver.
> > > > > > The user app then waits for the it’s event.
> > > > > >
> > > > > > When a GDI drawing call is made to your display driver, you set
the
> > > > event
> > > > > > after you’ve filled the information into your buffer.
> > > > > >
> > > > > > When the application wakes up after the event, it calls another
GDI
> > > > Escape
> > > > > > to “Fetch all GDI calls since last call”. This GDI call also
resets
> > the
> > > > > > event flag, so that next call to WaitForEvent
(WaitForSingleObject
> > or
> > > > > > whatever you use) will wait again.
> > > > > >
> > > > > > Does that sound like something you could use?
> > > > > >
> > > > > > This way, the user-mode application isn’t polling to see if
> > anything
> > > > > > changed, only fetching information when something ACTUALLY
changed.
> > > > > >
> > > > > > There’s a lot that can be done to optimise the above for
particular
> > > > types
> > > > > > of operations, but as a basic principle, I think it would be
> > efficient
> > > > and
> > > > > > work.
> > > > > >
> > > > > > –
> > > > > > Mats
> > > > > >
> > > > > > xxxxx@lists.osr.com wrote on 03/17/2005 03:16:14
PM:
> > > > > >
> > > > > > > Thanks Mats.
> > > > > > >
> > > > > > > Actually, I plan to intercept the GDI calls in a mirror
driver.
> > Will
> > > > > > > the primary video driver work well if I frequently call
> > ExtEscape? I
> > > > > > > just want the communicate with the mirror driver.
> > > > > > >
> > > > > > > I am thinking about allocating a block of memory in miniport
> > driver
> > > > to
> > > > > > > record the GDI function calls. This block of memory is shared
> > with
> > > > > > > display driver so that it can put down which DrvXxxx
functions
> > are
> > > > > > > called. The memory is also shared with a user-mode
application,
> > which
> > > > > > > polls it to see what happens in the driver.
> > > > > > >
> > > > > > > So I also wonder whether this method will be effective eoungh
> > since
> > > > > > > polling may be frequent.
> > > > > > >
> > > > > > > Thank you.
> > > > > > >
> > > > > > > Lei
> > > > > > >
> > > > > > >
> > > > > > > On Thu, 17 Mar 2005 09:12:54 +0000, Mats PETERSSON
> > > > > > > wrote:
> > > > > > > >
> > > > > > > >
> > > > > > > > Generally, we solve this sort of situation by wrapping the
> > IOCTL
> > > > with
> > > > > > an
> > > > > > > > GDI Escape (using the ExtEscape function call, which ends
up in
> > > > your
> > > > > > > > drivers DrvEscape), so your user applicaiton would call the
> > escape
> > > > for
> > > > > > the
> > > > > > > > DISPLAY, and the display driver would call the IOCTL using
the
> > > > handle
> > > > > > that
> > > > > > > > we’re given early on in the driver initialization. Thus
> > avoiding
> > > > > > actually
> > > > > > > > exposing a “Video” device, which is not how Microsoft
intended
> > > > things,
> > > > > > and
> > > > > > > > that’s why you can’t call the ioCreateDevice.
> > > > > > > >
> > > > > > > > –
> > > > > > > > Mats
> > > > > > > >
> > > > > > > > xxxxx@lists.osr.com wrote on 03/17/2005
05:15:51
> > AM:
> > > > > > > >
> > > > > > > > > I am going to have a user-mode application to talk with
video
> > > > > > miniport
> > > > > > > > > driver by IOCTL. I have to specify the device object
name
> > when I
> > > > use
> > > > > > > > > CreateFile in user-mode application. However, there are
no
> > video
> > > > port
> > > > > > > > > routines that can be used to create a device object. I
cannot
> > use
> > > > > > > > > IoCreateDevice either. So I am unable to specify a name
for
> > the
> > > > > > device
> > > > > > > > > object.
> > > > > > > > >
> > > > > > > > > So my question is, how to name a device object in video
> > miniport
> > > > > > driver?
> > > > > > > > >
> > > > > > > > > Can anyone give me some hints on that? Thank you.
> > > > > > > > >
> > > > > > > > > Lei
> > > > > > > > >
> > > > > > > > > —
> > > > > > > > > Questions? First check the Kernel Driver FAQ at
http://www.
> > > > > > > > > osronline.com/article.cfm?id=256
> > > > > > > > >
> > > > > > > > > You are currently subscribed to ntdev as:
> > > > xxxxx@3dlabs.com
> > > > > > > > > To unsubscribe send a blank email to
> > > > xxxxx@lists.osr.com
> > > > > > > >
> > > > > > > > > ForwardSourceID:NT0000ECE6
> > > > > > > >
> > > > > > > > —
> > > > > > > > Questions? First check the Kernel Driver FAQ at http://www.
> > > > > > > osronline.com/article.cfm?id=256
> > > > > > > >
> > > > > > > > You are currently subscribed to ntdev as: xxxxx@gmail.com
> > > > > > > > To unsubscribe send a blank email to
> > > > xxxxx@lists.osr.com
> > > > > > > >
> > > > > > >
> > > > > > > —
> > > > > > > Questions? First check the Kernel Driver FAQ at http://www.
> > > > > > > osronline.com/article.cfm?id=256
> > > > > > >
> > > > > > > You are currently subscribed to ntdev as:
> > xxxxx@3dlabs.com
> > > > > > > To unsubscribe send a blank email to
> > xxxxx@lists.osr.com
> > > > > >
> > > > > > > ForwardSourceID:NT0000ED46
> > > > > >
> > > > > > —
> > > > > > Questions? First check the Kernel Driver FAQ at http://www.
> > > > > osronline.com/article.cfm?id=256
> > > > > >
> > > > > > You are currently subscribed to ntdev as: xxxxx@gmail.com
> > > > > > To unsubscribe send a blank email to
> > xxxxx@lists.osr.com
> > > > > >
> > > > >
> > > > > —
> > > > > Questions? First check the Kernel Driver FAQ at http://www.
> > > > > osronline.com/article.cfm?id=256
> > > > >
> > > > > You are currently subscribed to ntdev as:
xxxxx@3dlabs.com
> > > > > To unsubscribe send a blank email to
xxxxx@lists.osr.com
> > > >
> > > > > ForwardSourceID:NT0000ED56
> > > >
> > > > —
> > > > Questions? First check the Kernel Driver FAQ at http://www.
> > > osronline.com/article.cfm?id=256
> > > >
> > > > You are currently subscribed to ntdev as: xxxxx@gmail.com
> > > > To unsubscribe send a blank email to
xxxxx@lists.osr.com
> > > >
> > >
> > > —
> > > Questions? First check the Kernel Driver FAQ at http://www.
> > > osronline.com/article.cfm?id=256
> > >
> > > You are currently subscribed to ntdev as: xxxxx@3dlabs.com
> > > To unsubscribe send a blank email to xxxxx@lists.osr.com
> >
> > > ForwardSourceID:NT0000ED76
> >
> > —
> > Questions? First check the Kernel Driver FAQ at http://www.
> osronline.com/article.cfm?id=256
> >
> > You are currently subscribed to ntdev as: xxxxx@gmail.com
> > To unsubscribe send a blank email to xxxxx@lists.osr.com
> >
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.
> osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@3dlabs.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com

> ForwardSourceID:NT0000F17E