filter driver location question

Hello,

I am wanting to develop a filter driver that will see all traffic sent
from NTFS to disk. Using the wonderful tool DeviceTree, I see that
the drivers Diskperf and PartMgr are attached to the Disk driver.
Looking in the registry with regedt32, it appears that these drivers
are Upper class filter drivers. I was wondering if this is the
correct place to attach my filter? Or would it be better to be a
lower filter driver on the MED device that NTFS is attached to? In
all honesty, I would like an instance of my filter per NTFS partition.
This is why I was thinking of making a lower filter attached (in some
way) to NTFS. Ok, a few more questions:

Is there any online references on what parts of the driver should/can
be in paged and non paged memory? I was reading filter.c for the
toaster example with the Win2k ddk and that example had PAGED(); in
most of the functions.

Are the #pragma statements necessary for driver writing? If so, is
there any online documentation about what the different “pragmas” are?

Thanks,
-Nick Kidd

ps. I know there are many books on these subjects, but being a student I
am trying to not go out and buy them. Hence the request for online
references :slight_smile:

Nicholas,

You should implement an upper volume filter driver. The best way to
create such a driver is to base it off of the Windows XP DDK’s Toaster
Filter sample. This driver’s source is intended to be used for both W2K
and XP drivers, so use the W2K DDK to build it and the same image will
work on W2K+. Do not use the W2K DDK Toaster Filter sample as it has
bugs. Without any modifications the XP DDK Toaster Filter sample is a
functional volume (and disk) filter driver. It will filter both basic
and dynamic disks. All you need to do is to add your driver’s name to
the UpperFilters or LowerFilters value of the class of devices that you
wish to filter (as Diskperf does). Oh, and you need to make sure that
its service key contains the following values (you can change
ErrorControl if you like):

Value Name Data Type Data

Group REG_SZ Pnp Filter
Start REG_DWORD 0
Type REG_DWORD 1
ErrorControl REG_DWORD 1

There’s one more gotcha. If you want to provide persistent services
from boot to boot, you’ll soon find that the volume does not have a
unique volume name at the time your AddDevice() routine is called (I’m
talking about the kind of unique volume names that get returned by the
Win32 call GetVolumeNameForVolumeMountPoint()). Frankly I think it’s an
architectural bobo that the device has no name when it’s created - it
makes providing persistent services awkward. However, the mount manager
does name volumes shortly after their creation (and as far as I
remember, before any meaningful symbolic links are created - meaning
that no I/O has hit the volume, at least from user mode) by sending
IOCTL_MOUNTDEV_LINK_CREATED to the volume (it’s actually sending it to
the volume device interface, but luckily for us this is the same device
object as the volume itself) and when you receive this IOCTL you can
parse out the unique volume name and recommence whatever services you
were providing on the previous boot before forwarding this IOCTL on to
the volume class driver (or whoever is filtering below you).

If you need to filter volumes for NT4 it’s a different story. Let me
know and I’ll provide more details.

Nate Bushman
PowerQuest Corp.

-----Original Message-----
From: Nicholas Kidd [mailto:kidd@cs.wisc.edu]
Sent: Thursday, November 21, 2002 4:00 PM
To: File Systems Developers
Subject: [ntfsd] filter driver location question

Hello,

I am wanting to develop a filter driver that will see all traffic sent
from NTFS to disk. Using the wonderful tool DeviceTree, I see that
the drivers Diskperf and PartMgr are attached to the Disk driver.
Looking in the registry with regedt32, it appears that these drivers
are Upper class filter drivers. I was wondering if this is the
correct place to attach my filter? Or would it be better to be a
lower filter driver on the MED device that NTFS is attached to? In
all honesty, I would like an instance of my filter per NTFS partition.
This is why I was thinking of making a lower filter attached (in some
way) to NTFS. Ok, a few more questions:

Is there any online references on what parts of the driver should/can
be in paged and non paged memory? I was reading filter.c for the
toaster example with the Win2k ddk and that example had PAGED(); in
most of the functions.

Are the #pragma statements necessary for driver writing? If so, is
there any online documentation about what the different “pragmas” are?

Thanks,
-Nick Kidd

ps. I know there are many books on these subjects, but being a student
I
am trying to not go out and buy them. Hence the request for online
references :slight_smile:


You are currently subscribed to ntfsd as: xxxxx@powerquest.com
To unsubscribe send a blank email to %%email.unsub%%

Nicholas,

You should only place code/data in pageable sections if you know for
sure that the code/data will only be referenced at IRQL <
DISPATCH_LEVEL. Some entry points in your driver (DriverEntry,
AddDevice, DriverUnload, etc) are guaranteed to be called at
PASSIVE_LEVEL in the context of a system thread. These routines can be
placed in pageable code sections (actually you can place DriverEntry in
an Init section so that it’s discarded after use because it’s only ran
once). HOWEVER, be very careful that you don’t raise IRQL to
DISPATCH_LEVEL or higher when you’re in a pageable function. Acquiring
a spinlock within a pageable function will (eventually) cause a bug
check KeAcquireSpinlock() raises IRQL (on the UniProcessor kernel).
PAGED_CODE() is simply a macro that you should call at the start of any
function that you’ve place in a pageable section. It will assert if
IRQL is > APC_LEVEL.

If you don’t want to worry about any of this then my advice (until you
feel you have a better grasp on all of this) is to simply remove the
#pragmas that place things in pageable code/data sections. That way
you’ll have one less thing to worry about, knowing that all of your
code/data is in nonpageable memory.

Nate Bushman
PowerQuest Corp.

-----Original Message-----
From: Nicholas Kidd [mailto:kidd@cs.wisc.edu]
Sent: Thursday, November 21, 2002 4:00 PM
To: File Systems Developers
Subject: [ntfsd] filter driver location question

Hello,

I am wanting to develop a filter driver that will see all traffic sent
from NTFS to disk. Using the wonderful tool DeviceTree, I see that
the drivers Diskperf and PartMgr are attached to the Disk driver.
Looking in the registry with regedt32, it appears that these drivers
are Upper class filter drivers. I was wondering if this is the
correct place to attach my filter? Or would it be better to be a
lower filter driver on the MED device that NTFS is attached to? In
all honesty, I would like an instance of my filter per NTFS partition.
This is why I was thinking of making a lower filter attached (in some
way) to NTFS. Ok, a few more questions:

Is there any online references on what parts of the driver should/can
be in paged and non paged memory? I was reading filter.c for the
toaster example with the Win2k ddk and that example had PAGED(); in
most of the functions.

Are the #pragma statements necessary for driver writing? If so, is
there any online documentation about what the different “pragmas” are?

Thanks,
-Nick Kidd

ps. I know there are many books on these subjects, but being a student
I
am trying to not go out and buy them. Hence the request for online
references :slight_smile:


You are currently subscribed to ntfsd as: xxxxx@powerquest.com
To unsubscribe send a blank email to %%email.unsub%%

Nate-

Thank you very much for your reply. I think I will worry about the
boot to boot problem once my filter driver works :slight_smile:

Just one question though. Will creating an UpperFilter (on my machine
it is for the class DiskDrive) mean that the filter will see *all*
traffic from ntfs, not just the traffic for one partition? Basically,
I just want to keep statistics on how many times NTFS is going to disk
and count the number of reads and writes. I was wanting to keep the
statistics per partition. That is why I was confused as to where to
place the driver (upper / lower). It would seem to me that an upper
class filter for the class DiskDrive would not be able to
differentiate for which partition the request is satisfying. For
example, on my machine I have two partitions. Using DeviceTree v2.8,
it shows 3 DeviceObjects for the disk. One for each partition and one
that Diskperf and PartMgr are attached to. Would I need create filter
objects for the 2 partition DeviceObjects to be able to separate the
statistics.

Thanks Again,
-Nick Kidd

On Thu, Nov 21, 2002 at 04:20:21PM -0700, Nate Bushman wrote:

Nicholas,

You should implement an upper volume filter driver. The best way to
create such a driver is to base it off of the Windows XP DDK’s Toaster
Filter sample. This driver’s source is intended to be used for both W2K
and XP drivers, so use the W2K DDK to build it and the same image will
work on W2K+. Do not use the W2K DDK Toaster Filter sample as it has
bugs. Without any modifications the XP DDK Toaster Filter sample is a
functional volume (and disk) filter driver. It will filter both basic
and dynamic disks. All you need to do is to add your driver’s name to
the UpperFilters or LowerFilters value of the class of devices that you
wish to filter (as Diskperf does). Oh, and you need to make sure that
its service key contains the following values (you can change
ErrorControl if you like):

Value Name Data Type Data

Group REG_SZ Pnp Filter
Start REG_DWORD 0
Type REG_DWORD 1
ErrorControl REG_DWORD 1

There’s one more gotcha. If you want to provide persistent services
from boot to boot, you’ll soon find that the volume does not have a
unique volume name at the time your AddDevice() routine is called (I’m
talking about the kind of unique volume names that get returned by the
Win32 call GetVolumeNameForVolumeMountPoint()). Frankly I think it’s an
architectural bobo that the device has no name when it’s created - it
makes providing persistent services awkward. However, the mount manager
does name volumes shortly after their creation (and as far as I
remember, before any meaningful symbolic links are created - meaning
that no I/O has hit the volume, at least from user mode) by sending
IOCTL_MOUNTDEV_LINK_CREATED to the volume (it’s actually sending it to
the volume device interface, but luckily for us this is the same device
object as the volume itself) and when you receive this IOCTL you can
parse out the unique volume name and recommence whatever services you
were providing on the previous boot before forwarding this IOCTL on to
the volume class driver (or whoever is filtering below you).

If you need to filter volumes for NT4 it’s a different story. Let me
know and I’ll provide more details.

Nate Bushman
PowerQuest Corp.

Nicholas,

Again, you should use an upper filter on the Volume device class. Why
filter DiskDrive devices? That just adds a lot more work for you,
having to distinguish which volume I/O is targeted at. If you filter
volumes then you’re already there. Just use the XP DDK Toaster Filter
sample AS IS and make the necessary settings in the registry so that the
driver will filter volumes. It already has the code in place to attach
filter device objects to any volume devices that are created. Build it,
install it, reboot and then look in DeviceTree and you’ll see the filter
device objects attached to the volumes. The only device object I can
see you needing to create (to add code for) is one that’s meant to
receive custom IOCTLs that you define for controlling your driver. I
don’t believe the toaster filter creates a control device object, but
it’s been a while since I looked at it. How to do that (securely) is
another story.

Nate Bushman
PowerQuest Corp

-----Original Message-----
From: Nicholas Kidd [mailto:kidd@cs.wisc.edu]
Sent: Thursday, November 21, 2002 5:39 PM
To: File Systems Developers
Subject: [ntfsd] RE: filter driver location question

Nate-

Thank you very much for your reply. I think I will worry about the
boot to boot problem once my filter driver works :slight_smile:

Just one question though. Will creating an UpperFilter (on my machine
it is for the class DiskDrive) mean that the filter will see *all*
traffic from ntfs, not just the traffic for one partition? Basically,
I just want to keep statistics on how many times NTFS is going to disk
and count the number of reads and writes. I was wanting to keep the
statistics per partition. That is why I was confused as to where to
place the driver (upper / lower). It would seem to me that an upper
class filter for the class DiskDrive would not be able to
differentiate for which partition the request is satisfying. For
example, on my machine I have two partitions. Using DeviceTree v2.8,
it shows 3 DeviceObjects for the disk. One for each partition and one
that Diskperf and PartMgr are attached to. Would I need create filter
objects for the 2 partition DeviceObjects to be able to separate the
statistics.

Thanks Again,
-Nick Kidd

On Thu, Nov 21, 2002 at 04:20:21PM -0700, Nate Bushman wrote:

Nicholas,

You should implement an upper volume filter driver. The best way to
create such a driver is to base it off of the Windows XP DDK’s Toaster
Filter sample. This driver’s source is intended to be used for both
W2K
and XP drivers, so use the W2K DDK to build it and the same image will
work on W2K+. Do not use the W2K DDK Toaster Filter sample as it has
bugs. Without any modifications the XP DDK Toaster Filter sample is a
functional volume (and disk) filter driver. It will filter both basic
and dynamic disks. All you need to do is to add your driver’s name to
the UpperFilters or LowerFilters value of the class of devices that
you
wish to filter (as Diskperf does). Oh, and you need to make sure that
its service key contains the following values (you can change
ErrorControl if you like):

Value Name Data Type Data

Group REG_SZ Pnp Filter
Start REG_DWORD 0
Type REG_DWORD 1
ErrorControl REG_DWORD 1

There’s one more gotcha. If you want to provide persistent services
from boot to boot, you’ll soon find that the volume does not have a
unique volume name at the time your AddDevice() routine is called (I’m
talking about the kind of unique volume names that get returned by the
Win32 call GetVolumeNameForVolumeMountPoint()). Frankly I think it’s
an
architectural bobo that the device has no name when it’s created - it
makes providing persistent services awkward. However, the mount
manager
does name volumes shortly after their creation (and as far as I
remember, before any meaningful symbolic links are created - meaning
that no I/O has hit the volume, at least from user mode) by sending
IOCTL_MOUNTDEV_LINK_CREATED to the volume (it’s actually sending it to
the volume device interface, but luckily for us this is the same
device
object as the volume itself) and when you receive this IOCTL you can
parse out the unique volume name and recommence whatever services you
were providing on the previous boot before forwarding this IOCTL on to
the volume class driver (or whoever is filtering below you).

If you need to filter volumes for NT4 it’s a different story. Let me
know and I’ll provide more details.

Nate Bushman
PowerQuest Corp.


You are currently subscribed to ntfsd as: xxxxx@powerquest.com
To unsubscribe send a blank email to %%email.unsub%%

Nate-

I want to again thank you for all of your help. The filter driver is
up and running :slight_smile: I think I just misread your previous email when you
said to create the filter as an upper class VOLUME filter. oops.

Thanks again,
-nick

On Fri, Nov 22, 2002 at 09:33:26AM -0700, Nate Bushman wrote:

Nicholas,

Again, you should use an upper filter on the Volume device class. Why
filter DiskDrive devices? That just adds a lot more work for you,
having to distinguish which volume I/O is targeted at. If you filter
volumes then you’re already there. Just use the XP DDK Toaster Filter
sample AS IS and make the necessary settings in the registry so that the
driver will filter volumes. It already has the code in place to attach
filter device objects to any volume devices that are created. Build it,
install it, reboot and then look in DeviceTree and you’ll see the filter
device objects attached to the volumes. The only device object I can
see you needing to create (to add code for) is one that’s meant to
receive custom IOCTLs that you define for controlling your driver. I
don’t believe the toaster filter creates a control device object, but
it’s been a while since I looked at it. How to do that (securely) is
another story.

Nate Bushman
PowerQuest Corp