siho
July 23, 2025, 12:03am
1
Hi. I'm currently making a software similar to linux's iowatcher in Windows, and is making a filter driver to filter I/O requests.
Since I'm making recreating iowatcher, I need to know which LBA is the target of the request and the length in blocks.
Currently, I'm filtering from \Filesystem\FltMgr with IRP_MJ_READ and IRP_MJ_WRITE packets handled, but I don't think the packet contains the LBA for I/O.
My question is: to which device should I attach in order to filter IRP packets containing LBA and read/write length?
Thank you in advance.
LBAs are present in the SRBs sent from the storage class drivers to the storage port drivers. So you need to filter IRP_MJ_SCSI either as a lower filter driver for disk devices or an upper filter for storage port devices.
1 Like
siho
July 24, 2025, 5:05pm
3
Thanks for the reply.
This got me thinking about something:
I'm using NVMe in my VM.
Does disks with NVMe also use IRP_MJ_SCSI?
For storage port devices, would \Device\RaidPortX or \Device\IdePortX be sufficient?
The storage class drivers don't care what type of adapter they are communicating with, they just send IRP_MJ_SCSI Irps containing an SRB.
The architecture is described here: Windows Storage Driver Architecture - Windows drivers | Microsoft Learn
A disk class lower filter driver would attach to all disk devices and allow you to filter all the SRB's going through.
1 Like
siho
July 24, 2025, 7:08pm
5
Thanks alot.
I'll try to add the lower filter device tomorrow, and ask some question if needed.
siho
July 27, 2025, 7:46pm
6
Okay. I've made the lower filter driver for the storage class driver, and am experiencing some problems.
Apparently, the driver seems to be causing access violation.
This is the stack trace:
1: kd> kb
# RetAddr : Args to Child : Call Site
00 fffff805`f049697e : fffff805`85807a70 fffff805`857b824c ffff8208`152e7b90 ffff8208`159031b0 : 0x0
01 fffff805`8580dd8e : ffff8208`15903a20 fffff805`f106c400 00000000`00001001 00000000`00000fff : nt!IofCallDriver+0xbe
02 fffff805`857b510a : ffff8cc3`005000b0 00000000`00000000 ffff8208`15903a20 00000058`00140016 : CLASSPNP!ClassDispatchPnp+0x17e
03 fffff805`f049697e : ffffba8b`278075b0 fffff805`f0d310d1 00000000`00000000 00000000`00000000 : CLASSPNP!ClassGlobalDispatch+0x3a
04 fffff805`82aa48eb : 00000000`00000100 ffff8208`15903a20 00000000`00000000 ffff8208`15904040 : nt!IofCallDriver+0xbe
05 fffff805`82a83bb1 : ffff8208`15903a20 00000000`00000000 ffff8208`15904040 ffff8208`13844e10 : partmgr!PmPnp+0x8b
06 fffff805`f049697e : ffff8208`15904040 ffffaa06`b4806590 00000000`00000020 00000000`69706e04 : partmgr!PmGlobalDispatch+0x101
07 fffff805`f0af7cb0 : ffff8208`15904040 00000000`00000000 ffffaa06`b4806590 ffff8208`13fb23c0 : nt!IofCallDriver+0xbe
08 fffff805`f0bb0f9a : ffff8208`13fb2584 ffffaa06`b48066f0 ffff8208`151e2050 ffff8208`13fb2580 : nt!IopSynchronousCall+0xf8
09 fffff805`f0bb0bf7 : ffff8208`13fb2584 00000000`00000000 ffffaa06`b48066f0 ffff8208`13fb2580 : nt!IopQueryLegacyBusInformation+0x62
0a fffff805`f08f3084 : 00000000`00000000 ffff8208`13fb23c0 ffff8208`13fb23c0 ffffba8b`276818e0 : nt!PipCallDriverAddDevice+0x8af
0b fffff805`f0ddea1b : 00000000`00000000 ffffba8b`27807710 00000000`00000000 00000000`00000000 : nt!PiProcessAddBootDevices+0x60
0c fffff805`f08f1d65 : 00000000`00000001 ffffaa06`b4806870 ffffba8b`276818e0 fffff805`f0bdacb8 : nt!PipAddDevicesToBootDriverWorker+0x23
0d fffff805`f0ddd190 : ffffffff`800002c8 ffffba8b`276739d0 ffff8208`00000092 ffffba8b`00000078 : nt!PipApplyFunctionToServiceInstances+0x1c5
0e fffff805`f0dda06c : 00000000`00000006 00000000`00000006 00000000`00000010 fffff805`7cd4c3a0 : nt!IopInitializeBootDrivers+0x5ac
0f fffff805`f0dd90bf : fffff805`85ab2fc0 fffff805`7cd4c3a0 fffff805`f08ca6f0 fffff805`7cd4c300 : nt!IoInitSystemPreDrivers+0xf40
10 fffff805`f08ca72b : fffff805`f08ca6f0 fffff805`f118b9f0 fffff805`f08ca6f0 fffff805`7cd4c3a0 : nt!IoInitSystem+0x17
11 fffff805`f065904a : ffff8208`1369b100 fffff805`f08ca6f0 608b8b4c`000000f4 0f41c78a`44000003 : nt!Phase1Initialization+0x3b
12 fffff805`f08741c4 : fffff805`7d0fb180 ffff8208`1369b100 fffff805`f0658ff0 e0ba0f48`00000698 : nt!PspSystemThreadStartup+0x5a
13 00000000`00000000 : ffffaa06`b4807000 ffffaa06`b4801000 00000000`00000000 00000000`00000000 : nt!KiStartSystemThread+0x34
May I ask you about some directions as to how to debug this error?
siho
July 28, 2025, 3:28pm
7
Apparently, the arguments passed to 0x0 matched the arguments of the routine that goes into IoSetCompletionRoutine.
NTSTATUS
WINIOWATCHER_DispatchDefault(
PDEVICE_OBJECT DeviceObject,
PIRP Irp
)
{
PDEVICE_EXTENSION Ext;
Ext = DeviceObject->DeviceExtension;
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(
Irp,
CompletionRoutine,
NULL,
TRUE,
TRUE,
TRUE
);
return IoCallDriver(Ext->LowerDeviceObject, Irp);
}
This is my dispatch function. Is there something missing?
Use the windbg command !analyze -v with correct symbols set up.
Set a breakpoint in your WINIOWATCHER_DispatchDefault routine and step through it.
Why are you not using KMDF for this driver? It would make your life much simpler.
1 Like
siho
July 28, 2025, 4:17pm
9
Unfortunately, I was not able to find any useful resources related to KMDF in my country, so I had to stick to this.
Anyway, I'll try to set some breakpoints and debug the driver.
siho
July 28, 2025, 5:14pm
10
Okay. I found the problem.
I forgot to register the major function for function number 0x1b.
// ↓ this had to be <=
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
if (DriverObject->MajorFunction[i] == NULL)
DriverObject->MajorFunction[i] = WINIOWATCHER_DispatchDefault;
}
Now I can successfully boot the OS.
Thanks a lot for your help!
system
Closed
September 26, 2025, 5:14pm
11
This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.