Filter Manager Concepts: Part 7 – IRP_CTRL
One very important structure that everyone writing minifilters very quickly becomes familiar is the FLT_CALLBACK_DATA. This is pretty much the equivalent of an IRP in the minifilter model. The structure is public and is pretty well documented. However, it is in fact just the public part of the picture. Filter manager has an internal structure (the IRP_CTRL) that wraps the FLT_CALLBACK_DATA. So there is a one-to-one relationship between the IRP, the IRP_CTRL and the FLT_CALLBACK_DATA. Let’s see that !fltkd tells us about it:
3: kd> !fltkd.irpctrl fffffa80075ef7d0
IRP_CTRL: fffffa80075ef720 CREATE (0) [00000009] Irp SystemBuffer
Flags : [1000000c] DontCopyParms Synchronize FixedAlloc
Irp : fffffa8003e6dc60
DeviceObject : fffffa8004603be0 "\Device\HarddiskVolume1"
FileObject : fffffa8008437070
CompletionNodeStack : fffffa80075ef870 Size=2 Next=1
SyncEvent : (fffffa80075ef738)
InitiatingInstance : 0000000000000000
Icc : fffff8800244f5b0
CreateIrp.NameCacheCtrl : 0000000000000000
CreateIrp.SavedFsContext : 0000000000000000
CallbackData : (fffffa80075ef7d0)
Flags : [00000009] Irp SystemBuffer
Thread : fffffa8006b9cb60
Iopb : fffffa80075ef828
RequestorMode : [01] UserMode
IoStatus.Status : 0x00000000
IoStatus.Information : 0000000000000000
TagData : 0000000000000000
FilterContext[0] : 0000000000000000
FilterContext[1] : 0000000000000000
FilterContext[2] : 0000000000000000
FilterContext[3] : 0000000000000000
Cmd IrpFl OpFl CmpFl Instance FileObjt Completion-Context Node Adr
--------- -------- ----- ----- -------- -------- ------------------ --------
[0,0] 00000000 00 0000 0000000000000000 0000000000000000 0000000000000000-0000000000000000 fffffa80075ef8f0
Args: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000
[0,0] 00000884 00 0000 fffffa800623a010 fffffa8008437070 fffff88004e5e474-0000000000000000 fffffa80075ef870
("luafv","luafv") luafv!LuafvPostCreate
Args: fffff8800244f750 0000000001200000 0000000000070000 0000000000000000 0000000000000000 0000000000000000
Working IOPB:
>[0,0] 00000884 00 fffffa800623a010 fffffa8008437070 fffffa80075ef828
("luafv","luafv")
Args: fffff8800244f750 0000000001200000 0000000000070000 0000000000000000 0000000000000000 0000000000000000
3: kd>
As you can see, a lot of information. The first thing I’d like to point out is there is another extension you could have used to display exactly the same information, !fltkd.cbd. In fact, they are exactly the same function internally and you can pass in the address of an IRP_CTRL or a FLT_CALLBACK_DATA and it’ll figure out what it is and display it. Also, very useful in debugging is the flag ‘1’. I didn’t use in this because it tends to generate a lot of output but try it yourself and you’ll see it displays a lot of good stuff.
This structure is central to filter manager and it is pretty much where the vast majority of my debugging sessions start. Some of the very interesting things you can get using this listing are, of course, the IRP, the InitiatingInstance (who initiated this IO? does it come from the user or was it a minifilter ?) and the Flags of the IRP_CTRL itself.
Comments
- Anonymous
May 12, 2010
If there is a one-to-one relationship between the IRP, the IRP_CTRL and the FLT_CALLBACK_DATA, supposedly you can getthe IRP from the data or address of FLT_CALLBACK_DATA.What is the best way to do that in minifilter's *PreOperationCallback() function?John W.