Trapping memory access in the kernel

I need to monitor read/write access to memory, like what was described in
the thread from “gameplugin”. However, in my case I want to do it in the
kernel. I’m writing a bus driver that will emulate hardware for testing.
This bus driver will allocate memory and return the allocated memory to an
upper layer driver as part of the IRP_MN_QUERY_RESOURCE_REQUIREMENTS
request. This memory will be used to simulate the hardware registers on the
board. I figured I would use MmProtectMdlSystemAddress to set the protection
on the pages to PAGE_NOACCESS. This will generate an exception anytime the
upper layer driver reads or writes to the memory. The problem is how do I
hook the exception handler to catch EXCEPTION_ACCESS_VIOLATION? Once I have
this hooked I could check the memory that caused the exception. If it was my
allocated memory I can do the appropriate thing to simulate the hardware,
and then return from the exception. If it was not my memory I can then pass
the exception on to the real exception handler for processing.

Or is there a different way to accomplish what I wish to do?

Thanks,

Rick

There’s no documented way I know of to hook into the NT kernel-mode
page-fault handler. And you would have to hook into the page fault
handler since you are dealing with kernel memory, because an unsatisfied
page fault on kernel memory results in a bugcheck, not a catchable
exception. Perhaps Peter Wieland has a suggestion here?

Rick Jones wrote:

I need to monitor read/write access to memory, like what was described in
the thread from “gameplugin”. However, in my case I want to do it in the
kernel. I’m writing a bus driver that will emulate hardware for testing.
This bus driver will allocate memory and return the allocated memory to an
upper layer driver as part of the IRP_MN_QUERY_RESOURCE_REQUIREMENTS
request. This memory will be used to simulate the hardware registers on the
board. I figured I would use MmProtectMdlSystemAddress to set the protection
on the pages to PAGE_NOACCESS. This will generate an exception anytime the
upper layer driver reads or writes to the memory. The problem is how do I
hook the exception handler to catch EXCEPTION_ACCESS_VIOLATION? Once I have
this hooked I could check the memory that caused the exception. If it was my
allocated memory I can do the appropriate thing to simulate the hardware,
and then return from the exception. If it was not my memory I can then pass
the exception on to the real exception handler for processing.

Or is there a different way to accomplish what I wish to do?

Thanks,

Rick


Nick Ryan (MVP for DDK)

do you need to simulate the hardware for an already written driver? Or
is this for bringing up a new driver?

why not have the driver call a function in your emulator to do the
register read rather than trying to trap on a memory access. It seems
like it would be much much faster, not to mention the difficulty of
attempting to hook in to the memory manager for this purpose.

instead of calling READ_REGISTER_UCHAR (for example) you have your
driver call MY_READ_REGISTER_UCHAR. You can then swap this for an
inline that calls the hal version once you’re no longer emulating.

you could retrieve function pointers from the underlying emulator using
a PNP QueryInterface irp.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Rick Jones
Sent: Monday, December 22, 2003 5:10 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Trapping memory access in the kernel

I need to monitor read/write access to memory, like what was described
in the thread from “gameplugin”. However, in my case I want to do it in
the kernel. I’m writing a bus driver that will emulate hardware for
testing.
This bus driver will allocate memory and return the allocated memory to
an upper layer driver as part of the IRP_MN_QUERY_RESOURCE_REQUIREMENTS
request. This memory will be used to simulate the hardware registers on
the board. I figured I would use MmProtectMdlSystemAddress to set the
protection on the pages to PAGE_NOACCESS. This will generate an
exception anytime the upper layer driver reads or writes to the memory.
The problem is how do I hook the exception handler to catch
EXCEPTION_ACCESS_VIOLATION? Once I have this hooked I could check the
memory that caused the exception. If it was my allocated memory I can do
the appropriate thing to simulate the hardware, and then return from the
exception. If it was not my memory I can then pass the exception on to
the real exception handler for processing.

Or is there a different way to accomplish what I wish to do?

Thanks,

Rick


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to xxxxx@lists.osr.com

Rick,

The below technique is exactly how we at 3DLabs do the simulator for our new
graphics chips. Just “hook” the read/write register, and any other hardware
access, to a function call into the simulator.

Of course, what makes this a bit complicated is that the simulator is about
5-6 MB of binary, written in C++, with lots of levels of calling, so we need
to swap the stack (default kernel stack is far too small) and do all sorts
of other nastiness to allow the C++ code to function when linked to a
driver. But it’s working quite well aside from the nasty bits that we have
to do to interface it. Of course, we don’t use all features of C++, for
example exceptions aren’t allowed (try/except isn’t allowed, that is),
because exception handling isn’t supported for the kernel mode driver.

Of course, if you haven’t got source code for the driver, you’d have a
problem… :frowning:


Mats

-----Original Message-----
From: Peter Wieland [mailto:xxxxx@windows.microsoft.com]
Sent: Tuesday, December 23, 2003 1:18 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] RE: Trapping memory access in the kernel

do you need to simulate the hardware for an already written
driver? Or
is this for bringing up a new driver?

why not have the driver call a function in your emulator to do the
register read rather than trying to trap on a memory access. It seems
like it would be much much faster, not to mention the difficulty of
attempting to hook in to the memory manager for this purpose.

instead of calling READ_REGISTER_UCHAR (for example) you have your
driver call MY_READ_REGISTER_UCHAR. You can then swap this for an
inline that calls the hal version once you’re no longer emulating.

you could retrieve function pointers from the underlying
emulator using
a PNP QueryInterface irp.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Rick Jones
Sent: Monday, December 22, 2003 5:10 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Trapping memory access in the kernel

I need to monitor read/write access to memory, like what was described
in the thread from “gameplugin”. However, in my case I want
to do it in
the kernel. I’m writing a bus driver that will emulate hardware for
testing.
This bus driver will allocate memory and return the allocated
memory to
an upper layer driver as part of the
IRP_MN_QUERY_RESOURCE_REQUIREMENTS
request. This memory will be used to simulate the hardware
registers on
the board. I figured I would use MmProtectMdlSystemAddress to set the
protection on the pages to PAGE_NOACCESS. This will generate an
exception anytime the upper layer driver reads or writes to
the memory.
The problem is how do I hook the exception handler to catch
EXCEPTION_ACCESS_VIOLATION? Once I have this hooked I could check the
memory that caused the exception. If it was my allocated
memory I can do
the appropriate thing to simulate the hardware, and then
return from the
exception. If it was not my memory I can then pass the exception on to
the real exception handler for processing.

Or is there a different way to accomplish what I wish to do?

Thanks,

Rick


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@microsoft.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

We do not have the upper layer code to recomplie. So we can’t hook
read/write registers calls into functions in our simulator.

Rick

wrote in message news:xxxxx@ntdev…
>
> Rick,
>
> The below technique is exactly how we at 3DLabs do the simulator for our
new
> graphics chips. Just “hook” the read/write register, and any other
hardware
> access, to a function call into the simulator.
>
> Of course, what makes this a bit complicated is that the simulator is
about
> 5-6 MB of binary, written in C++, with lots of levels of calling, so we
need
> to swap the stack (default kernel stack is far too small) and do all sorts
> of other nastiness to allow the C++ code to function when linked to a
> driver. But it’s working quite well aside from the nasty bits that we have
> to do to interface it. Of course, we don’t use all features of C++, for
> example exceptions aren’t allowed (try/except isn’t allowed, that is),
> because exception handling isn’t supported for the kernel mode driver.
>
> Of course, if you haven’t got source code for the driver, you’d have a
> problem… :frowning:
>
> –
> Mats
>
>
>
> > -----Original Message-----
> > From: Peter Wieland [mailto:xxxxx@windows.microsoft.com]
> > Sent: Tuesday, December 23, 2003 1:18 AM
> > To: Windows System Software Devs Interest List
> > Subject: [ntdev] RE: Trapping memory access in the kernel
> >
> >
> > do you need to simulate the hardware for an already written
> > driver? Or
> > is this for bringing up a new driver?
> >
> > why not have the driver call a function in your emulator to do the
> > register read rather than trying to trap on a memory access. It seems
> > like it would be much much faster, not to mention the difficulty of
> > attempting to hook in to the memory manager for this purpose.
> >
> > instead of calling READ_REGISTER_UCHAR (for example) you have your
> > driver call MY_READ_REGISTER_UCHAR. You can then swap this for an
> > inline that calls the hal version once you’re no longer emulating.
> >
> > you could retrieve function pointers from the underlying
> > emulator using
> > a PNP QueryInterface irp.
> >
> > -p
> >
> > -----Original Message-----
> > From: xxxxx@lists.osr.com
> > [mailto:xxxxx@lists.osr.com] On Behalf Of Rick Jones
> > Sent: Monday, December 22, 2003 5:10 PM
> > To: Windows System Software Devs Interest List
> > Subject: [ntdev] Trapping memory access in the kernel
> >
> > I need to monitor read/write access to memory, like what was described
> > in the thread from “gameplugin”. However, in my case I want
> > to do it in
> > the kernel. I’m writing a bus driver that will emulate hardware for
> > testing.
> > This bus driver will allocate memory and return the allocated
> > memory to
> > an upper layer driver as part of the
> > IRP_MN_QUERY_RESOURCE_REQUIREMENTS
> > request. This memory will be used to simulate the hardware
> > registers on
> > the board. I figured I would use MmProtectMdlSystemAddress to set the
> > protection on the pages to PAGE_NOACCESS. This will generate an
> > exception anytime the upper layer driver reads or writes to
> > the memory.
> > The problem is how do I hook the exception handler to catch
> > EXCEPTION_ACCESS_VIOLATION? Once I have this hooked I could check the
> > memory that caused the exception. If it was my allocated
> > memory I can do
> > the appropriate thing to simulate the hardware, and then
> > return from the
> > exception. If it was not my memory I can then pass the exception on to
> > the real exception handler for processing.
> >
> >
> >
> > Or is there a different way to accomplish what I wish to do?
> >
> >
> >
> > Thanks,
> >
> > Rick
> >
> >
> >
> > —
> > Questions? First check the Kernel Driver FAQ at
> > http://www.osronline.com/article.cfm?id=256
> >
> > You are currently subscribed to ntdev as: xxxxx@microsoft.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
>
>

I presume we’re talking of simulating for the purpose of development, then
this method might work:

On x86, you could do this: Find the base address of IDT (Interrupt
descricptor table) with the SIDT instruction. Find entry 14 in the table
(offset 14 * 8), and grab the 8 bytes there. Make sure you check that it’s a
normal “trap” routine, rather than a task gate. Then hook your own routine
to it, something like this:

__declspec(naked) void MyTrap0E(void)
{
__asm {
push eax // Save EAX and ECX to
preserve their values.
push ecx
mov ecx, [esp+8] // Get error code.
mov cr2, eax // get trap address.
cmp eax, MyLimitLow // if (addr < myLimitLow)
continue;
jb NotMe
cmp eax, MyLimitHigh // if (addr > myLimitHigh)
continue;
ja NotMe
shr ecx, 1 // Get r/w bit
and ecx, 1 // Mask out the bit.
sub eax, MyLimitLow // Get the offset rather than full
address.
push eax
call MySimulatorFunction
add esp, 4
pop ecx
pop eax
iretd

NotMe:
pop ecx
pop eax
jmp dword ptr [oldVector] // OldVector must be the address of
the old Page Fault handler.
}

The above code is just quickly hacked up, so it may be faulty in many
different ways, but I think you get the gist of it.

The above code assumes that your allocated memory is “nonpaged”, so that it
doesn’t get paged out, as this would make life a lot more complicated. If
you have a page-boundary for the address, and it’s within the page, you
could make it simpler to check if it’s the correct page and then just pass
the (addr & (PAGE_SIZE-1)) as offset to the MySimulatorFunction.

Hope this helps.


Mats

-----Original Message-----
From: Rick Jones [mailto:xxxxx@adelphia.net]
Sent: Tuesday, December 23, 2003 12:12 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Re: Trapping memory access in the kernel

We do not have the upper layer code to recomplie. So we can’t hook
read/write registers calls into functions in our simulator.

Rick

wrote in message news:xxxxx@ntdev…
> >
> > Rick,
> >
> > The below technique is exactly how we at 3DLabs do the
> simulator for our
> new
> > graphics chips. Just “hook” the read/write register, and any other
> hardware
> > access, to a function call into the simulator.
> >
> > Of course, what makes this a bit complicated is that the
> simulator is
> about
> > 5-6 MB of binary, written in C++, with lots of levels of
> calling, so we
> need
> > to swap the stack (default kernel stack is far too small)
> and do all sorts
> > of other nastiness to allow the C++ code to function when
> linked to a
> > driver. But it’s working quite well aside from the nasty
> bits that we have
> > to do to interface it. Of course, we don’t use all features
> of C++, for
> > example exceptions aren’t allowed (try/except isn’t
> allowed, that is),
> > because exception handling isn’t supported for the kernel
> mode driver.
> >
> > Of course, if you haven’t got source code for the driver,
> you’d have a
> > problem… :frowning:
> >
> > –
> > Mats
> >
> >
> >
> > > -----Original Message-----
> > > From: Peter Wieland [mailto:xxxxx@windows.microsoft.com]
> > > Sent: Tuesday, December 23, 2003 1:18 AM
> > > To: Windows System Software Devs Interest List
> > > Subject: [ntdev] RE: Trapping memory access in the kernel
> > >
> > >
> > > do you need to simulate the hardware for an already written
> > > driver? Or
> > > is this for bringing up a new driver?
> > >
> > > why not have the driver call a function in your emulator to do the
> > > register read rather than trying to trap on a memory
> access. It seems
> > > like it would be much much faster, not to mention the
> difficulty of
> > > attempting to hook in to the memory manager for this purpose.
> > >
> > > instead of calling READ_REGISTER_UCHAR (for example) you have your
> > > driver call MY_READ_REGISTER_UCHAR. You can then swap this for an
> > > inline that calls the hal version once you’re no longer emulating.
> > >
> > > you could retrieve function pointers from the underlying
> > > emulator using
> > > a PNP QueryInterface irp.
> > >
> > > -p
> > >
> > > -----Original Message-----
> > > From: xxxxx@lists.osr.com
> > > [mailto:xxxxx@lists.osr.com] On Behalf Of Rick Jones
> > > Sent: Monday, December 22, 2003 5:10 PM
> > > To: Windows System Software Devs Interest List
> > > Subject: [ntdev] Trapping memory access in the kernel
> > >
> > > I need to monitor read/write access to memory, like what
> was described
> > > in the thread from “gameplugin”. However, in my case I want
> > > to do it in
> > > the kernel. I’m writing a bus driver that will emulate
> hardware for
> > > testing.
> > > This bus driver will allocate memory and return the allocated
> > > memory to
> > > an upper layer driver as part of the
> > > IRP_MN_QUERY_RESOURCE_REQUIREMENTS
> > > request. This memory will be used to simulate the hardware
> > > registers on
> > > the board. I figured I would use
> MmProtectMdlSystemAddress to set the
> > > protection on the pages to PAGE_NOACCESS. This will generate an
> > > exception anytime the upper layer driver reads or writes to
> > > the memory.
> > > The problem is how do I hook the exception handler to catch
> > > EXCEPTION_ACCESS_VIOLATION? Once I have this hooked I
> could check the
> > > memory that caused the exception. If it was my allocated
> > > memory I can do
> > > the appropriate thing to simulate the hardware, and then
> > > return from the
> > > exception. If it was not my memory I can then pass the
> exception on to
> > > the real exception handler for processing.
> > >
> > >
> > >
> > > Or is there a different way to accomplish what I wish to do?
> > >
> > >
> > >
> > > Thanks,
> > >
> > > Rick
> > >
> > >
> > >
> > > —
> > > Questions? First check the Kernel Driver FAQ at
> > > http://www.osronline.com/article.cfm?id=256
> > >
> > > You are currently subscribed to ntdev as:
> xxxxx@microsoft.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
> >
> >
>
>
>
> —
> 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

Hello Rick,

Tuesday, December 23, 2003, 1:12:24 PM, you wrote:

RJ> We do not have the upper layer code to recomplie. So we can’t hook
RJ> read/write registers calls into functions in our simulator.

AFAIK there’s no need to recompile. simply hook import entries in your driver, or
exports from hal.dll of READ_PORT_* & WRITE_PORT_*

the similar way uses softice to simulate keyboard input (forwarding)
when normal hook is not possible IIRC

the memory hook as Mats Petersson suggests will work perfectly well
too …


Best regards,
Ivona Prenosilova

Thanks,

I’ll look into it.

Rick

wrote in message news:xxxxx@ntdev…
>
> I presume we’re talking of simulating for the purpose of development, then
> this method might work:
>
> On x86, you could do this: Find the base address of IDT (Interrupt
> descricptor table) with the SIDT instruction. Find entry 14 in the table
> (offset 14 * 8), and grab the 8 bytes there. Make sure you check that it’s
a
> normal “trap” routine, rather than a task gate. Then hook your own routine
> to it, something like this:
>
> __declspec(naked) void MyTrap0E(void)
> {
>__asm {
> push eax // Save EAX and ECX to
> preserve their values.
> push ecx
> mov ecx, [esp+8] // Get error code.
> mov cr2, eax // get trap address.
> cmp eax, MyLimitLow // if (addr < myLimitLow)
> continue;
> jb NotMe
> cmp eax, MyLimitHigh // if (addr > myLimitHigh)
> continue;
> ja NotMe
> shr ecx, 1 // Get r/w bit
> and ecx, 1 // Mask out the bit.
> sub eax, MyLimitLow // Get the offset rather than full
> address.
> push eax
> call MySimulatorFunction
> add esp, 4
> pop ecx
> pop eax
> iretd
>
> NotMe:
> pop ecx
> pop eax
> jmp dword ptr [oldVector] // OldVector must be the address of
> the old Page Fault handler.
> }
>
> The above code is just quickly hacked up, so it may be faulty in many
> different ways, but I think you get the gist of it.
>
> The above code assumes that your allocated memory is “nonpaged”, so that
it
> doesn’t get paged out, as this would make life a lot more complicated. If
> you have a page-boundary for the address, and it’s within the page, you
> could make it simpler to check if it’s the correct page and then just pass
> the (addr & (PAGE_SIZE-1)) as offset to the MySimulatorFunction.
>
> Hope this helps.
>
> –
> Mats
>
> > -----Original Message-----
> > From: Rick Jones [mailto:xxxxx@adelphia.net]
> > Sent: Tuesday, December 23, 2003 12:12 PM
> > To: Windows System Software Devs Interest List
> > Subject: [ntdev] Re: Trapping memory access in the kernel
> >
> >
> > We do not have the upper layer code to recomplie. So we can’t hook
> > read/write registers calls into functions in our simulator.
> >
> > Rick
> >
> > wrote in message news:xxxxx@ntdev…
> > >
> > > Rick,
> > >
> > > The below technique is exactly how we at 3DLabs do the
> > simulator for our
> > new
> > > graphics chips. Just “hook” the read/write register, and any other
> > hardware
> > > access, to a function call into the simulator.
> > >
> > > Of course, what makes this a bit complicated is that the
> > simulator is
> > about
> > > 5-6 MB of binary, written in C++, with lots of levels of
> > calling, so we
> > need
> > > to swap the stack (default kernel stack is far too small)
> > and do all sorts
> > > of other nastiness to allow the C++ code to function when
> > linked to a
> > > driver. But it’s working quite well aside from the nasty
> > bits that we have
> > > to do to interface it. Of course, we don’t use all features
> > of C++, for
> > > example exceptions aren’t allowed (try/except isn’t
> > allowed, that is),
> > > because exception handling isn’t supported for the kernel
> > mode driver.
> > >
> > > Of course, if you haven’t got source code for the driver,
> > you’d have a
> > > problem… :frowning:
> > >
> > > –
> > > Mats
> > >
> > >
> > >
> > > > -----Original Message-----
> > > > From: Peter Wieland [mailto:xxxxx@windows.microsoft.com]
> > > > Sent: Tuesday, December 23, 2003 1:18 AM
> > > > To: Windows System Software Devs Interest List
> > > > Subject: [ntdev] RE: Trapping memory access in the kernel
> > > >
> > > >
> > > > do you need to simulate the hardware for an already written
> > > > driver? Or
> > > > is this for bringing up a new driver?
> > > >
> > > > why not have the driver call a function in your emulator to do the
> > > > register read rather than trying to trap on a memory
> > access. It seems
> > > > like it would be much much faster, not to mention the
> > difficulty of
> > > > attempting to hook in to the memory manager for this purpose.
> > > >
> > > > instead of calling READ_REGISTER_UCHAR (for example) you have your
> > > > driver call MY_READ_REGISTER_UCHAR. You can then swap this for an
> > > > inline that calls the hal version once you’re no longer emulating.
> > > >
> > > > you could retrieve function pointers from the underlying
> > > > emulator using
> > > > a PNP QueryInterface irp.
> > > >
> > > > -p
> > > >
> > > > -----Original Message-----
> > > > From: xxxxx@lists.osr.com
> > > > [mailto:xxxxx@lists.osr.com] On Behalf Of Rick Jones
> > > > Sent: Monday, December 22, 2003 5:10 PM
> > > > To: Windows System Software Devs Interest List
> > > > Subject: [ntdev] Trapping memory access in the kernel
> > > >
> > > > I need to monitor read/write access to memory, like what
> > was described
> > > > in the thread from “gameplugin”. However, in my case I want
> > > > to do it in
> > > > the kernel. I’m writing a bus driver that will emulate
> > hardware for
> > > > testing.
> > > > This bus driver will allocate memory and return the allocated
> > > > memory to
> > > > an upper layer driver as part of the
> > > > IRP_MN_QUERY_RESOURCE_REQUIREMENTS
> > > > request. This memory will be used to simulate the hardware
> > > > registers on
> > > > the board. I figured I would use
> > MmProtectMdlSystemAddress to set the
> > > > protection on the pages to PAGE_NOACCESS. This will generate an
> > > > exception anytime the upper layer driver reads or writes to
> > > > the memory.
> > > > The problem is how do I hook the exception handler to catch
> > > > EXCEPTION_ACCESS_VIOLATION? Once I have this hooked I
> > could check the
> > > > memory that caused the exception. If it was my allocated
> > > > memory I can do
> > > > the appropriate thing to simulate the hardware, and then
> > > > return from the
> > > > exception. If it was not my memory I can then pass the
> > exception on to
> > > > the real exception handler for processing.
> > > >
> > > >
> > > >
> > > > Or is there a different way to accomplish what I wish to do?
> > > >
> > > >
> > > >
> > > > Thanks,
> > > >
> > > > Rick
> > > >
> > > >
> > > >
> > > > —
> > > > Questions? First check the Kernel Driver FAQ at
> > > > http://www.osronline.com/article.cfm?id=256
> > > >
> > > > You are currently subscribed to ntdev as:
> > xxxxx@microsoft.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
> > >
> > >
> >
> >
> >
> > —
> > 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
>
>