Class Filter Driver for DiskDrive

I am trying to develop a lower level class filter driver for DiskDrive. I was
looking around for ways to achieve this. I have the following questions:

1- Is my assumption correct that a class filter driver is configured as upper or
lower filter according to the specification made in INF file?

For example kbfiltr installs as upper filter according to the relevant INF
section as follows:

[kbfiltr.HW.AddReg]
HKR,“UpperFilters”,0x00010000,“kbfiltr”

If i change this to:

HKR,“LowerFilters”,0x00010000,“kbfiltr”

then it will install as a lower filter driver for keyboard without requiring any
change in the source code for this sample. Is that correct or changes will be
required?

2- If change is required then generally for class filters what portions need to
be modified?

3- For a bare bone class filter driver for diskdrive i just need to have two
functions to begin with:

  • DriverEntry
  • EvtDeviceAdd -----> having a call to WdfDeviceInitSetDeviceType(DeviceInit,
    FILE_DEVICE_DISK);

Is that correct?

Thanks for all the help.

sarshah.

Kbfiltr is a device filter not a class filter.
The sample you want is the diskperf sample.

Bill Wandel

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@Yahoo.com
Sent: Tuesday, April 05, 2011 10:18 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Class Filter Driver for DiskDrive

I am trying to develop a lower level class filter driver for DiskDrive. I
was
looking around for ways to achieve this. I have the following questions:

1- Is my assumption correct that a class filter driver is configured as
upper or
lower filter according to the specification made in INF file?

For example kbfiltr installs as upper filter according to the relevant INF
section as follows:

[kbfiltr.HW.AddReg]
HKR,“UpperFilters”,0x00010000,“kbfiltr”

If i change this to:

HKR,“LowerFilters”,0x00010000,“kbfiltr”

then it will install as a lower filter driver for keyboard without requiring
any
change in the source code for this sample. Is that correct or changes will
be
required?

2- If change is required then generally for class filters what portions need
to
be modified?

3- For a bare bone class filter driver for diskdrive i just need to have two

functions to begin with:

  • DriverEntry
  • EvtDeviceAdd -----> having a call to
    WdfDeviceInitSetDeviceType(DeviceInit,
    FILE_DEVICE_DISK);

Is that correct?

Thanks for all the help.

sarshah.


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

>1- Is my assumption correct that a class filter driver is configured as upper or lower filter according >to the specification made in INF file?
In general, you could use the same code for both type of filters - upper and lower. Look at filter toaster sample
\WinDDK\XXX\src\general\toaster\wdm\filter
Toaster uses the same code for different type of filter.
But you should understand that upper and lower class disk filters work on different levels of storage stack and could get get different I/O requests. For example, SCSI requests could see only in lower filter not in upper. Such request created in disk class driver. And could be additional stuff generated by disk class driver.

Igor Sharovar

Thanks Bill and Igor for your response. I am looking at the diskperf sample now and have a few more questions.

  • In this sample, how can i retrieve LBAs in the handler for IRP_MJ_WRITE? This is an upper class filter driver. Are LBAs available at upper filter level?

  • I only need to handle: IRP_MJ_WRITE & IRP_MJ_READ for my purpose. What are the other necessary IRPs i must handle for the driver to work properly?

Since this is a WDM driver so i am guessing: IRP_MJ_PNP and IRP_MJ_POWER. Are there others that i must handle? I want to remove the IRPs that are specific to diskperf functionality and modify this sample to a bare minimum class filter driver having IRP_MJ_WRITE & IRP_MJ_READ.

  • Is there a WDF equivalent around for diskperf?

  • Igor: Is there an online resource/article that can give me an understanding of what I/O requests are possible at upper and lower filter level? In other words what changes will be needed in diskperf sample to make it usable at lower filter level.

Thanks everyone for the great help and advice.

sarshah.

I have made little progress and answered question 2 using the following link.

http://msdn.microsoft.com/en-us/library/ff566980(v=VS.85).aspx

Rest of the questions still remain unanswered. Any help in this regard will be highly appreciated.

Thanks,

sarshah.

You can do a WDF driver in place of diskperf, there is no sample that is
equivalent but you can look at the toaster\filter code for a decent
starting point.

You should be forwarding all the IRP’s to the lower driver, you will
want to handle IOCTL as well as read and write.

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@Yahoo.com” wrote in message
news:xxxxx@ntdev:

> Thanks Bill and Igor for your response. I am looking at the diskperf sample now and have a few more questions.
>
> - In this sample, how can i retrieve LBAs in the handler for IRP_MJ_WRITE? This is an upper class filter driver. Are LBAs available at upper filter level?
>
> - I only need to handle: IRP_MJ_WRITE & IRP_MJ_READ for my purpose. What are the other necessary IRPs i must handle for the driver to work properly?
>
> Since this is a WDM driver so i am guessing: IRP_MJ_PNP and IRP_MJ_POWER. Are there others that i must handle? I want to remove the IRPs that are specific to diskperf functionality and modify this sample to a bare minimum class filter driver having IRP_MJ_WRITE & IRP_MJ_READ.
>
> - Is there a WDF equivalent around for diskperf?
>
> - Igor: Is there an online resource/article that can give me an understanding of what I/O requests are possible at upper and lower filter level? In other words what changes will be needed in diskperf sample to make it usable at lower filter level.
>
> Thanks everyone for the great help and advice.
>
> sarshah.

>- Igor: Is there an online resource/article that can give me an understanding of what I/O requests >are possible at upper and lower filter level? In other words what changes will be needed in diskperf >sample to make it usable at lower filter level.

I think there is not such resources. In additional to the source you mention I could recommend to study disk class sample of WDK
I:\WinDDK\7600.16385.1\src\storage\class
disk.sys resides just between upper and lower filters and you could understand which request come to upper filter and disk.sys and which requests issued by disk.sys and could be handled by lower filter.
But the most easiest way to you would be install both upper and lower filters, which do nothing. These filters could report which requests they get and simple transfer them.

Igor Sharovar

In the upper filter, you should be able to retrieve ByteOffsets from
IRP_MJ_READ/IRP_MJ_WRITE.

I didn’t quite follow what you mean by “other necessary IRPs i must handle”?
The diskperf sample pretty much handles all the irps to make the driver an
upperfilter, unless you have some special requirement.

You should be able to convert the diskperf into a lower filter by editing
the inf file. (Change “UpperFilters” to “LowerFilters”).

In that case you will have to write a handler for IRP_MJ_SCSI and then
decode the SRB to get the LBA.

Other thing to note would be that the existing diskperf sample sends a few
ioctls in its start device routine. These ioctls may not work when you make
it a lower filter. So be careful with that.

On Wed, Apr 6, 2011 at 8:17 PM, wrote:

> Thanks Bill and Igor for your response. I am looking at the diskperf sample
> now and have a few more questions.
>
> - In this sample, how can i retrieve LBAs in the handler for IRP_MJ_WRITE?
> This is an upper class filter driver. Are LBAs available at upper filter
> level?
>
> - I only need to handle: IRP_MJ_WRITE & IRP_MJ_READ for my purpose. What
> are the other necessary IRPs i must handle for the driver to work properly?
>
> Since this is a WDM driver so i am guessing: IRP_MJ_PNP and IRP_MJ_POWER.
> Are there others that i must handle? I want to remove the IRPs that are
> specific to diskperf functionality and modify this sample to a bare minimum
> class filter driver having IRP_MJ_WRITE & IRP_MJ_READ.
>
> - Is there a WDF equivalent around for diskperf?
>
> - Igor: Is there an online resource/article that can give me an
> understanding of what I/O requests are possible at upper and lower filter
> level? In other words what changes will be needed in diskperf sample to make
> it usable at lower filter level.
>
> Thanks everyone for the great help and advice.
>
> sarshah.
>
> —
> 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
>

I have a few more questions:

  • Is it absolutely necessary to have WMI related code as implemented in diskperf? OR

  • Can i take out all the WMI related code/functions/callbacks and simply pass the request on to the next lower driver in the handler for IRP_MJ_SYSTEM_CONTROL?

> In the upper filter, you should be able to retrieve ByteOffsets from
IRP_MJ_READ/IRP_MJ_WRITE.

Can you please explain this point further? Do you mean that in upper filter, ByteOffsets represents/lead to LBA? Sorry i did not get this point.

> I didn’t quite follow what you mean by “other necessary IRPs i must handle”?

I was referring to providing handlers for major entry points (for example IRP_MJ_CREATE,
IRP_MJ_DEVICE_CONTROL etc). I was not sure which one do i absolutely need to have for a working class filter driver. I thought may be there are some IRPs that are handled only to achieve diskperf functionality and can be removed.

> In that case you will have to write a handler for IRP_MJ_SCSI and then
decode the SRB to get the LBA.

I went throught the SCSI_REQUEST_BLOCK structure at the following link.

http://msdn.microsoft.com/en-us/library/ff565393(VS.85).aspx

Can you please point out what members do i need to decode to get LBA?

>Other thing to note would be that the existing diskperf sample sends a few
ioctls in its start device routine. These ioctls may not work when you make
it a lower filter. So be careful with that.

Its setting up IOCTLS in DiskPerfRegisterDevice. Are you referring to these?

Thanks everyone for the great help. Really appreciate that. I will definitely try out suggestions to develop a better understaning.

sarshah.

At 14:12 11/04/2011, xxxxx@Yahoo.com wrote:

I have a few more questions:

  • Is it absolutely necessary to have WMI related code as implemented
    in diskperf? OR

  • Can i take out all the WMI related code/functions/callbacks and
    simply pass the request on to the next lower driver in the handler
    for IRP_MJ_SYSTEM_CONTROL?

DiskPerf is an example provided in the WDK, the WMI code is there to
show that the sample does something useful. Samples are there for
you to take what you need and to discard the rest. I do suggest that
you don’t delete huge chunks of code in case you delete something you
actually need. Proceed slowly.

>> In the upper filter, you should be able to retrieve ByteOffsets from
IRP_MJ_READ/IRP_MJ_WRITE.

Can you please explain this point further? Do you mean that in upper
filter, ByteOffsets represents/lead to LBA? Sorry i did not get this point.

That all depends on what type of filter it is. DiskPerf can be
installed as either a volume or a disk filter. Read and Write IRPs
have an offset value in bytes in the stack location. For a volume
filter this value is a logical offset in to the volume. As a disk
filter the value is a physical offset on the disk.

Mapping the offset value in a disk to an LBA is quite simple, just
divide by 512 since all reads and writes will be multiples of 512 bytes.

Mapping the volume offset to a disk and an LBA requires understanding
what disks and partitions the volume is located on, there are ioctls
you can use to discover this information.

>> I didn’t quite follow what you mean by “other necessary IRPs i
must handle”?

I was referring to providing handlers for major entry points (for
example IRP_MJ_CREATE,
IRP_MJ_DEVICE_CONTROL etc). I was not sure which one do i absolutely
need to have for a working class filter driver. I thought may be
there are some IRPs that are handled only to achieve diskperf
functionality and can be removed.

>> In that case you will have to write a handler for IRP_MJ_SCSI and then
decode the SRB to get the LBA.

I went throught the SCSI_REQUEST_BLOCK structure at the following link.

http://msdn.microsoft.com/en-us/library/ff565393(VS.85).aspx

Can you please point out what members do i need to decode to get LBA?

You need to read the CDB. The Windows SRB is simply Microsoft’s
wrapper for the SCSI CDB, which is the SCSI command block that
devices actually understand and decode. You’ll need to get the
latest version of the spec from T.10 - SCSI Block Commands (www.t10.org).

Specifically you’ll at least want to decode READ6, READ10, READ16,
WRITE6, WRITE10, WRITE16 and maybe some others (it’s a long time
since I played down here).

Mark

On Mon, Apr 11, 2011 at 10:44 AM, Mark S. Edwards wrote:
> Mapping the offset value in a disk to an LBA is quite simple, just divide by
> 512 since all reads and writes will be multiples of 512 bytes.

You have to be a little bit careful and pro-active here as
(infrequently) sectors are not 512 bytes, and the future looks like
that will be a more common situation. So don’t hard code the sector
size, us the actual runtime value.

Mark Roddy