Click here to Skip to main content
15,395,290 members
Please Sign up or sign in to vote.
0.00/5 (No votes)

I am trying to set up an event to notify my user mode application from my mini filter driver whenever a callback is used. Currently I have successfully set up a shared event that both can connect to like so:

    Private Shared Function CreateEvent(lpEventAttributes As IntPtr, bManualReset As Boolean, bInitialState As Boolean, lpName As String) As IntPtr
    End Function

Dim RegisterEvent = CreateEvent(Nothing, True, False, "TEST_EVENT2")
        MsgBox("Event Handle: " & RegisterEvent.ToString)

This creates the shared event object I am able to then get a Handle for I then pass that handle via IOCTL to my mini filter driver like so

Const FILE_DEVICE_EVENTSYS As UInteger = 33552


bStatus = DeviceIoControl(hFile, IOCTL_OPEN_EVENT, CLng(RegisterEvent), Marshal.SizeOf(RegisterEvent), Nothing, 0, Bytes_IO, Nothing)
           If bStatus Then
               waitStatus = WaitForSingleObject(RegisterEvent, INFINITE)
               If Not waitStatus = WAIT_OBJECT_0 Then
                   MsgBox("The driver has successfully signaled our named event!")
               End If
           End If

The IOCTL Returns True and the waitforsingleobject is satisfied from my driver or so I think but the waitStatus = WAIT_OBJECT_0 is always 0 for both so no notification was sent from the driver to the user mode application.


#define FILE_DEVICE_EVENTSYS 0x00008310

	PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp);
	ULONG returnLength = 0;
	PVOID* buffer = Irp->AssociatedIrp.SystemBuffer;
	ULONG inLength = irpsp->Parameters.DeviceIoControl.InputBufferLength;
	ULONG outLength = irpsp->Parameters.DeviceIoControl.OutputBufferLength;

	switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
		SharedEvent = IoCreateNotificationEvent(&EventName, &SharedEventHandle);
		if (SharedEvent != NULL) {

			ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
			KeInitializeEvent(SharedEvent, KernelMode, FALSE);
			KeSetEvent(SharedEvent, KernelMode, FALSE);

			status = STATUS_SUCCESS;
		else {
			KdPrint(("Cannot open shared event"));

	Irp->IoStatus.Status = status;
	Irp->IoStatus.Information = returnLength;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	return status;

The way I am thinking about this is that the Shared Event will be created from the user mode application along with the event handle. The IOCTL in the driver will Open the shared event and receive the handle and ObReferenceObject(SharedEvent) for use. Here is where is gets a bit complicated for me when trying to figure out the synchronization and the IRQL Dispatch and passive levels as I know only some calls can be made and some cant causing BSOD. I am experiencing no notifications of the event and also deadlocking. My driver is monitoring process and image loads how can I set the event for each newly added callback from my preoperation so that the user mode application can block or allow or simply just get notified by event? I hope my question makes sense and that I am thinking this correctly.

Here is the link that I am trying to follow:
Kernel Dispatcher Objects | Programming the Microsoft Windows Driver Model[^]

What I have tried:

I have tried setting Dispatch and passive levels for IRQL but not sure its correct or within the correct area. I have tried KeSetEvent and KeInitalizeEvent with Passive IRQL. I have tried setting the event from within the preoperation... probably not a good idea, I think thats a page pool area but im not well informed it causes BSOD. I have also tried setting the event from within the IOCTL but it either does nothing or causes deadlock.

Is this correct?

1. User mode app creates event and handle
2. Driver receives Handle Via IOCTL
3. KeSetEvent sets the Shared Event signaled to true
4. user mode waitforsingleobject is satisfied by true signal
5. Event is fired?
Updated 19-Jul-22 23:01pm
Randor 2-Jun-22 17:07pm
Do you still need help with this? You never reference the HANDLE that you pass. Shouldn't you be calling ObReferenceObjectByHandle on the HANDLE that you pass to your device driver?
Dale Seeley 2-Jun-22 23:16pm
Yes please I would greatly appricate your help Randor. I am trying to understand how the logic works for this. I have changed the driver to include the ObReferenceObjectByHandle like so:

status = ObReferenceObjectByHandle(registerEvent->hEvent,

This code is from the driver event example you suggested to me. I have tried to run that example but it BSOD my system so I am trying to understand and add it to my mini filter driver to notify my user mode application.

is this thinking correct?

application creates the event object and passes the handle to the driver via IOCTL. the driver then gets a object reference by handle and CustomTimerDPC is called to Signal KeSetEvent so waitforsingleobject in user mode is satisfied to show the notification which in my case is just a simple message box but could work for anything.

at the moment the DeviceIoControl is always returning false or I am having BSOD with error code IRQL not equal or less or thread exception not handled... basically I am trying all i can think but getting nowhere.

I am aware but not sure where and when to set apc or dispatch levels and where all this fits into the mini filter driver.
Randor 3-Jun-22 7:53am
Are you saying that the Microsoft code sample is causing you to BSOD?

That doesn't sound right. Can you show me the output of Fltmc.exe

Open a command prompt as Administrator and type fltmc.exe and show me the output.
Dale Seeley 5-Jun-22 19:17pm
Filter Name Num Instances Altitude Frame
------------------------------ ------------- ------------ -----
bindflt 1 409800 0
WdFilter 7 328010 0
storqosflt 0 244000 0
wcifs 0 189900 0
PrjFlt 0 189800 0
CldFlt 1 180451 0
FileCrypt 0 141100 0
luafv 1 135000 0
npsvctrig 1 46000 0
Wof 5 40700 0
FileInfo 7 40500 0

The BSOD occurs when I try to load the Driver sys file using OSRLOADER

Unhandled System Threading Exception
Randor 7-Jun-22 19:14pm
Your filter manager output looks normal. The OSRLOADER program is really old. You should ask Peter Viscarola over in the OSR forum for support with that tool.
Dale Seeley 6-Jun-22 16:07pm
Can you please let me know what is needed on the application side and driver to set up a event so that the driver will pause until the application/user makes a decision. I hope you can still help 🙏
Dale Seeley 6-Jun-22 16:17pm
I have also seen someone say to use inverted call but I have no idea how that works or how it fits into a mini filter driver
Randor 7-Jun-22 19:16pm
I can see that you have been reading OSR documents. Of course, it's up to you what architecture you want to use in your driver. But I don't think that you need to use this "inverted call model" here. Have you considered using io completion ports via FltCreateCommunicationPort and FltSendMessage instead of an event object to communicate with your usermode app? If you are new to minifilter drivers it might be easier for you.

I honestly feel like the distance between where you currently are... and where you need to be is a great distance away. I would recommend that you focus on a single step at a time. You should focus on getting the driver/usermode communication completed first. Once you get that working I can show you how to use FltCbdqInitialize, FltCbdqInsertIo and FltCbdqRemoveIo to cancel or pend your i/o operations.

How do you want to proceed?
Dale Seeley 7-Jun-22 23:06pm
Thank you so much for responding I do indeed need to pend i/o operations so that the driver will wait until the user allows or denies the process to launch (if this is its intended use?) but as you have stated I will need to learn this and research it, hopefully with your help in the future. Currently I have IOCTL working as you know so maybe for now I can try the Communication Port and FltSendMessage way of receiving notifications from the driver to the user mode application. Will this method also cause the driver to wait for a response or can that only be achieved by pending i/o operations?.
Randor 8-Jun-22 0:10am
No, FltSendMessage does not facilitate pending or cancellation of i/o operations. It's just an api for communicating with usermode. You seem to be having trouble with events, so I think it might be easier for you.

Here is what I would propose for pending/cancellation:
1.) Initialize a non-paged queue with FltCbdqInitialize in your FLT_REGISTRATION instance setup.
2.) When you want to pend an i/o call use FltCbdqInsertIo and add it to the queue created in step 1 and return FLT_PREOP_PENDING

But let's focus on your current issue before discussing that.
Dale Seeley 8-Jun-22 0:17am
That sounds like a great plan!! at the moment I am reading up on creating the communication port in the driver. FltCbdqInitialize and FltCbdqInsertIo along with creating and receiving the communication port are callback methods?
Randor 8-Jun-22 0:45am
No, none of the functions you just listed are callbacks.

Call FltCreateCommunicationPort from your DriverEntry

From your usermode app call FilterConnectCommunicationPort to connect to it

Further reading:
Dale Seeley 8-Jun-22 1:21am
Awesome thank you for that very useful info that gets me started! Ill post again tomorrow when I have the first step complete thank you Randor.
Randor 8-Jun-22 1:31am
Just rip out the code from the scanner sample to get it up and running:
Dale Seeley 8-Jun-22 14:13pm
Oh this is amazing thank you very much I really want to complete this chapter of the project and move on lol 😆. I can't wait to check this out after work.
Dale Seeley 10-Jun-22 0:22am
Ok I am happy to report that I have created the Communication Port which I checked with WinObj64 and the port is successfully created and removed and the driver works as expected but I have run into a Problem when trying to use FilterConnectCommunicationPort from within my .NET application. I have Pinvoked FilterConnectCommunicationPort like so:

Dim OpenPortHandle As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(IntPtr)))

<dllimport("fltlib", setlasterror:="True)">
Public Shared Function FilterConnectCommunicationPort(<marshalas(unmanagedtype.lpwstr)> portName As String,
options As UInteger,context As IntPtr, sizeOfContext As UInteger, securityAttributes As IntPtr,portPtr As IntPtr) As Integer
End Function

and then in the start monitor section I call:
Dim OpenPortNumber = FilterConnectCommunicationPort("\\PortName", 0, IntPtr.Zero, 0, IntPtr.Zero, OpenPortHandle)


I have also checked the Name of the port and directory should be exact and seen the example in the scanner which makes the same call. The message box returns -2147024773 which is clear the connection was refused or unable to connect.

Any Ideas what might be going wrong for me?
thank you in advance!
Randor 10-Jun-22 13:43pm
I can see your deleted post but can't respond to it. You build the security descriptor but never assign it to your communication port. You need to call RtlSetDaclSecurityDescriptor.

Really strange that you left that part out.
Dale Seeley 10-Jun-22 14:20pm
I'm not sure it's strange Im just unsure all the steps needed so once I added the code I thought I needed and cleared up the errors in my driver code there appeared to be nothing outstanding but I missed that. Thank you I will include that
Randor 10-Jun-22 14:27pm
It might be easier to give 'everyone' access during the development process. Call it with TRUE,NULL,FALSE to allow 'Everyone'. But make sure that you remember to secure it before release.
Dale Seeley 10-Jun-22 14:37pm
Good point I will do it that way to see it work and then secure it. Is it difficult to secure or do I just change the way its called?
Randor 10-Jun-22 16:58pm
If you are working on a hobby project it probably doesn't matter. But on a commercial security product you might want to consider restricting access to SYSTEM. You should plan/design for this.
Dale Seeley 10-Jun-22 17:39pm
I asked maybe a silly question at first I will protect the port and service/driver from any other process which tries to kill it along with the program itself but what areas do you know of for drivers that should be restricted? I am fairly new to this and having your insight in very valuable.
Randor 10-Jun-22 18:19pm
Well, you probably wouldn't want a rogue program sending IRPs or connecting to your communication port. If your usermode counterpart is a system service then you can restrict access to SYSTEM.
Dale Seeley 10-Jun-22 23:10pm
My user mode counter part is a VB.Net winform. How do I go abouts assigning the descriptor to the communication port? Is it shown in the example? I would imagine of course it is but where? 😅
Randor 11-Jun-22 0:27am
Sorry if I was unclear. I was trying to say that you should consider adding:


Before your call to InitializeObjectAttributes() to see if that allowed you to connect to the communication port. Beware that this allows 'Everyone' to connect to the port.

Check if that fixes your connection issues. Unfortunately I am not a .NET programmer so I can't help very much with your VB.NET code.
Dale Seeley 11-Jun-22 0:41am
OK so adding RtlSetDaclSecurityDescriptor(sd,TRUE,NULL,FALSE) in the driver entry before InitializeObjectAttributes() is what your saying might help?
Randor 11-Jun-22 0:57am
Are you running your usermode client as Administrator or System? The FltBuildDefaultSecurityDescriptor() function builds a default security descriptor that requires Administrator or System. If you are running your VB.NET application as a normal user then you can set a NULL ACL to allow anyone to connect during the development process.

It's your call. I am just responding to your questions and making suggestions.
Dale Seeley 11-Jun-22 1:03am
My .NET application runs as Administrator I will try now
Randor 11-Jun-22 1:07am
It's difficult tp help people when we can't see your code and development setup. I have to make guesses. :)

I have no idea why you can't connect to the communication port in your VB.NET application. Is it returning an error code?
Dale Seeley 11-Jun-22 1:10am
It returns a minus number -2147024773
Dale Seeley 11-Jun-22 1:11am
Tomorrow I will disclose full code for you to analyze please if you can
Dale Seeley 11-Jun-22 1:18am
I added the line above where you suggested but still it does not connect
Dale Seeley 11-Jun-22 1:19am
Is there any way I can pass the project to you?
Dale Seeley 11-Jun-22 1:29am
Randor 11-Jun-22 1:44am
Ok, I think I see the problem. I am not a VB.NET programmer but I think VB.NET does not backslash escape strings.

The C++ code:
const PWSTR ScannerPortName = L"\\BitPort";

Your VB.NET code:
Dim OpenPortNumber = FilterConnectCommunicationPort("\\BitPort", 0, IntPtr.Zero, 0, IntPtr.Zero, OpenPortHandle)

In the C++ language L"\\BitPort" is being escaped to "\BitPort"

So in VB.NET I believe this would be: "\BitPort"
Dale Seeley 11-Jun-22 1:48am
Actually I have tried that also thinking the exact same thing I will try now but I'm pretty sure it will BSOD
Dale Seeley 11-Jun-22 1:52am
Yup BSOD :(
Randor 11-Jun-22 1:54am
I am not guessing. I am telling you that this is the connection problem. I knew where to look because your error code (-2147024773) 0x8007007B means it's an invalid name.

A BSOD is progress. Leave that change in there. Your port name is: "\BitPort"

Now you need to track down why it's generating a BSOD
Dale Seeley 11-Jun-22 2:02am
Gotcha does there appear to be anything wrong with the driver code at the moment?
Randor 11-Jun-22 2:10am
Don't see anything but if I were debugging it I would comment out all that code in your ScannerPortConnect() function. Hollow it out and just leave the paged_code macro, unreferenced macros and DbgPrint
Dale Seeley 11-Jun-22 1:53am
I'm using Visual Studio 2019
Randor 11-Jun-22 2:00am
Are you deploying the driver in a virtual machine? Where are you installing the minifilter?
Dale Seeley 11-Jun-22 2:03am
On the local machine no vm
Randor 11-Jun-22 2:08am
You can't develop a minifilter on your localhost, you will have a very high risk of being locked out of your operating system. I highly suggest that you spend a few days setting up a development VM. You can get free VM images here:
Dale Seeley 11-Jun-22 2:11am
Awesome thank you I set up virtual machines or have often in the past so it's no issue but I've been developing on my local machine for months with no lock outs. Just curious why would you be running such a risk or why does windows lock up, I've never experienced that before
Randor 11-Jun-22 2:35am
You should just take my advice. The Windows operating system is continually writing data into the registry and other very important places. It's just a matter of time before a BSOD occurs and the data is half written.

There are other benefits to deploying your driver to a VM, you can setup WinDbg and see the exact place causing the BSOD
Dale Seeley 17-Jun-22 1:48am
Ok I have created the VMware and also connected Windbg x64 and can break and resume the debugger. Can you give me links or advise how to properly use and view the exceptions that cause the BSOD? I am unsure of the command line arguments or how to pinpoint the issues while the mini-filter driver is running or causing the error. thank you for your time I look forward to hearing back from you.
Randor 17-Jun-22 5:40am
You need to setup your symbols:

Also add the path to your driver PDB file.
Dale Seeley 17-Jun-22 2:26am
8: kd> !analyze -v
* *
* Bugcheck Analysis *
* *

An exception happened while executing a system service routine.
Arg1: 00000000c0000420, Exception code that caused the BugCheck
Arg2: fffff807689f16bc, Address of the instruction which caused the BugCheck
Arg3: ffffb786b1d7f820, Address of the context record for the exception that caused the BugCheck
Arg4: 0000000000000000, zero.

Debugging Details:


Key : Analysis.CPU.mSec
Value: 3358

Key : Analysis.DebugAnalysisManager
Value: Create

Key : Analysis.Elapsed.mSec
Value: 5734

Key : Analysis.Init.CPU.mSec
Value: 421

Key : Analysis.Init.Elapsed.mSec
Value: 4829

Key : Analysis.Memory.CommitPeak.Mb
Value: 96

Key : WER.OS.Branch
Value: co_release

Key : WER.OS.Timestamp
Value: 2021-06-04T16:28:00Z

Key : WER.OS.Version
Value: 10.0.22000.1

FILE_IN_CAB: 061622-6187-01.dmp



BUGCHECK_P1: c0000420

BUGCHECK_P2: fffff807689f16bc

BUGCHECK_P3: ffffb786b1d7f820


CONTEXT: ffffb786b1d7f820 -- (.cxr 0xffffb786b1d7f820)
rax=0000000000000000 rbx=0000000000000000 rcx=ffffc08833eab570
rdx=0000000000000000 rsi=ffffc08833eab570 rdi=ffffc088328c1420
rip=fffff807689f16bc rsp=ffffb786b1d80240 rbp=ffffb786b1d80310
r8=0000000000000000 r9=0000000000000000 r10=ffffc088320f71c8
r11=0000000070634d46 r12=ffffc08833ead838 r13=0000000000000000
r14=0000000000000000 r15=ffffc088362a8270
iopl=0 nv up ei pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040202
fffff807`689f16bc cd2c int 2Ch
Resetting default scope

BLACKBOXBSD: 1 (!blackboxbsd)

BLACKBOXNTFS: 1 (!blackboxntfs)

BLACKBOXPNP: 1 (!blackboxpnp)




ffffb786`b1d80240 00000000`0000f10d : 00000000`00000001 ffffc088`362a8270 00000000`00000000 00000001`00000000 : Bitfilter+0x16bc
ffffb786`b1d80248 00000000`00000001 : ffffc088`362a8270 00000000`00000000 00000001`00000000 00000001`33ead838 : 0xf10d
ffffb786`b1d80250 ffffc088`362a8270 : 00000000`00000000 00000001`00000000 00000001`33ead838 ffffc088`328c1420 : 0x1
ffffb786`b1d80258 00000000`00000000 : 00000001`00000000 00000001`33ead838 ffffc088`328c1420 00000000`00000001 : 0xffffc088`362a8270

SYMBOL_NAME: Bitfilter+16bc

MODULE_NAME: Bitfilter

IMAGE_NAME: Bitfilter.sys

STACK_COMMAND: .cxr 0xffffb786b1d7f820 ; kb


FAILURE_BUCKET_ID: 0x3B_C0000420_Bitfilter!unknown_function

OS_VERSION: 10.0.22000.1

BUILDLAB_STR: co_release


OSNAME: Windows 10

FAILURE_ID_HASH: {23ee73b4-ac33-c70d-8b59-1288cfa8578b}

Followup: MachineOwner

8: kd> .cxr 0xffffb786b1d7f820
rax=0000000000000000 rbx=0000000000000000 rcx=ffffc08833eab570
rdx=0000000000000000 rsi=ffffc08833eab570 rdi=ffffc088328c1420
rip=fffff807689f16bc rsp=ffffb786b1d80240 rbp=ffffb786b1d80310
r8=0000000000000000 r9=0000000000000000 r10=ffffc088320f71c8
r11=0000000070634d46 r12=ffffc08833ead838 r13=0000000000000000
r14=0000000000000000 r15=ffffc088362a8270
iopl=0 nv up ei pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040202
fffff807`689f16bc cd2c int 2Ch
8: kd> lmvm Bitfilter
Browse full module list
start end module name
fffff807`689f0000 fffff807`689f8000 Bitfilter T (no symbols)
Randor 17-Jun-22 5:44am
Setup your symbols, check my last message.

You can also use the .sympath command to manual load the paths.

If you add the path to your driver PDB this will make your WinDbg session usable.
Dale Seeley 29-Jun-22 1:29am
Hello again Randor I believe I have the symbols set up correctly but I am unsure whats happening here is a output of my windbg. the VMware does not BSOD but there is an Assertion failure

Microsoft (R) Windows Debugger Version 10.0.25136.1001 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

Opened \\.\pipe\com_2
Waiting to reconnect...
Connected to Windows 10 22000 x64 target at (Tue Jun 28 23:25:44.066 2022 (UTC - 6:00)), ptr64 TRUE
Kernel Debugger connection established.

************* Path validation summary **************
Response Time (ms) Location
Deferred srv*C:\localsymbols*
Symbol search path is: srv*C:\localsymbols*
Executable search path is:
Windows 10 Kernel Version 22000 MP (12 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Edition build lab: 22000.1.amd64fre.co_release.210604-1628
Machine Name:
Kernel base = 0xfffff802`22a00000 PsLoadedModuleList = 0xfffff802`236296b0
Debug session time: Tue Jun 28 23:25:08.905 2022 (UTC - 6:00)
System Uptime: 0 days 1:17:54.711
Break instruction exception - code 80000003 (first chance)
fffff802`22e1dbf1 c3 ret
1: kd> g
Assertion failure - code c0000420 (first chance)
fffff802`31b91672 cd2c int 2Ch
11: kd> g
Continuing an assertion failure can result in the debuggee
being terminated (bugchecking for kernel debuggees).
If you want to ignore this assertion, use 'ahi'.
If you want to force continuation, use 'gh' or 'gn'.
Dale Seeley 29-Jun-22 2:14am
Here is another output

10: kd> !analyze -v
Connected to Windows 10 22000 x64 target at (Wed Jun 29 00:11:11.874 2022 (UTC - 6:00)), ptr64 TRUE
Loading Kernel Symbols

Press ctrl-c (cdb, kd, ntsd) or ctrl-break (windbg) to abort symbol loads that take too long.
Run !sym noisy before .reload to track down problems loading symbols.

Loading User Symbols

Press ctrl-c (cdb, kd, ntsd) or ctrl-break (windbg) to abort symbol loads that take too long.
Run !sym noisy before .reload to track down problems loading symbols.


Loading unloaded module list
* *
* Bugcheck Analysis *
* *

An exception happened while executing a system service routine.
Arg1: 00000000c0000420, Exception code that caused the BugCheck
Arg2: fffff80231ba1672, Address of the instruction which caused the BugCheck
Arg3: fffff58709e59830, Address of the context record for the exception that caused the BugCheck
Arg4: 0000000000000000, zero.

Debugging Details:


Key : Analysis.CPU.mSec
Value: 2187

Key : Analysis.DebugAnalysisManager
Value: Create

Key : Analysis.Elapsed.mSec
Value: 27410

Key : Analysis.Init.CPU.mSec
Value: 2811

Key : Analysis.Init.Elapsed.mSec
Value: 2766284

Key : Analysis.Memory.CommitPeak.Mb
Value: 92

Key : Bugcheck.Code.DumpHeader
Value: 0x3b

Key : Bugcheck.Code.KiBugCheckData
Value: 0x3b

Key : Bugcheck.Code.Register
Value: 0x3

Key : WER.OS.Branch
Value: co_release

Key : WER.OS.Timestamp
Value: 2021-06-04T16:28:00Z

Key : WER.OS.Version
Value: 10.0.22000.1


BUGCHECK_P1: c0000420

BUGCHECK_P2: fffff80231ba1672

BUGCHECK_P3: fffff58709e59830


CONTEXT: fffff58709e59830 -- (.cxr 0xfffff58709e59830)
rax=fffff80231ba1630 rbx=0000000000000000 rcx=ffffe2835e64ef10
rdx=0000000000000000 rsi=ffffe2835e64ef10 rdi=ffffe2835e185570
rip=fffff80231ba1672 rsp=fffff58709e5a250 rbp=fffff58709e5a310
r8=0000000000000000 r9=0000000000000000 r10=ffffe2835eee97f8
r11=fd55515555555555 r12=ffffe283602c7d38 r13=0000000000000000
r14=0000000000000000 r15=ffffe28363284690
iopl=0 nv up ei pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040202
fffff802`31ba1672 cd2c int 2Ch
Resetting default scope


fffff587`09e5a250 fffff802`20f47548 : ffffe283`5e64ef10 00000000`00000000 00000000`00000000 fffff587`00000000 : Bitfilter+0x1672
fffff587`09e5a290 fffff802`20f4955b : ffffe283`5eee97e0 ffffda8f`c17d4a30 00000000`00000000 ffffffff`8000403c : FLTMGR!FltpOpenClientPort+0x434
fffff587`09e5a350 fffff802`20f4dbba : ffffe283`5b4aec90 fffff587`09e5a409 ffffe283`5fed7a00 ffffe283`5b4aec90 : FLTMGR!FltpMsgDispatch+0x18b
fffff587`09e5a3c0 fffff802`22d02f65 : 00000000`00000000 fffff802`22cc5d33 ffffda8f`c17d4a78 ffffda8f`c17d4960 : FLTMGR!FltpCreate+0x55a
fffff587`09e5a470 fffff802`23153667 : ffffe283`5b4aec90 ffffe283`5b4aec90 fffff587`09e5a770 ffffc40c`00000040 : nt!IofCallDriver+0x55
fffff587`09e5a4b0 fffff802`23172562 : fffff587`09e5a770 fffff802`23152dd0 ffffda8f`bc1f22a0 ffffe283`5e5f4aa0 : nt!IopParseDevice+0x897
fffff587`09e5a670 fffff802`231719d1 : ffffc40c`79947920 fffff
Dale Seeley 29-Jun-22 2:16am
Might be of value to note that the driver upon loading and unloading a time or two had no BSOD but now without changing anything it fails. I am not sure if the communication port is being disposed of and created again properly or if that might be the issue it looks like maybe the driver is ok but the user mode application might have some issue? please advise. thank you Randor
Randor 29-Jun-22 15:18pm
Look at your code:

PFLT_PORT ClientPort;
FLT_ASSERT(ClientPort == NULL);

Can you tell me what the value of your ClientPort is when you never initialize it? Do you know what FLT_ASSERT does?
Dale Seeley 8-Jul-22 2:07am
I actually have no idea what FLT_ASSERT does to be honest so I removed it and revised the code in my driver to the information I found in my book "Windows Kernel Programming" chapter 10 mini filter driver. I can see now when the driver is started My filter connection port is created and within the user mode application I make a call to FilterConnectCommunicationPort and the port handle is as follows, 1818164390016. When I exit and restart the user mode application that number changes but I am not sure if this number is correct as it looks to long compared to the IOCTL port number that is created. I assume that number to be the client port. Please advise and if you have any time I can reupload the project to my google drive if you could be so nice to take a look. thanks again Randor
Randor 11-Jul-22 3:27am
I am observing alot of very fundamental mistakes in your C code such as reading the value of uninitialized variables. I would recommend that you improve your C language skills. It's highly unusual to see those those type of mistakes. Your compiler should be warning you.

Don't be discouraged, everyone has to start somewhere. Everyone has been in your shoes, keep experimenting and you will see progress.

In the C language an 'assert' throws an error.
Dale Seeley 11-Jul-22 22:45pm
Interesting to know about Assert, so in general NT_ASSERT and FLT_ASSERT is to throw certain errors or to check the outcome if a value is valid or not?. If Assert just throws an error when a value is expected can't that lead to issues? Is this a form of lazy coding? I will revise the C code for variables that are not initialized with values is that why I am not able to connect to the communication port?. Thank you for continuing to coach me through this.
Dale Seeley 13-Jul-22 8:23am
I revised the code, made allot of changes since you seen it last and no longer have any warnings to any unitialized code. The user mode application still receives a communication port handle but I am unsure if it's correct or not. I will upload the project like last time to my Google drive if you have time to look things over I would greatly appreciate it. 🙂
Dale Seeley 19-Jul-22 1:08am
Hello again I have created and receive a proper port number for the communication port now I am trying to figure out fltSendmessage and reply so I can impalement the Io blocking feature to allow or block process creation. Can you point me to the next step thanks Randor.
Randor 19-Jul-22 5:48am
I can't see your code. Could you verify that you can connect to the communication port from your usermode application?
Dale Seeley 19-Jul-22 8:23am
Yes I can see from my usermode application the return value from the communication port is zero and the port passed to my handle variable is normal. I can post or upload the project to my Google drive for review later today. Thank you for your continuous reply patience and guidance.
Randor 20-Jul-22 5:02am
Ok, next you will need to design a structure to send to your usermode application. You will be using FltSendMessage. Design a C struct with file path and other things you would be interested in inspecting from usermode.

I also highly recommend adding some code to reduce the filtering scope. I recommended adding the ability to exclude or include paths to monitor.
Dale Seeley 20-Jul-22 8:23am
The structure part is actually what I am a bit confused about because I am not sure how to interact with it in VB.NET. I can confirm the connection seems good but then I use fltgetmessage in the usermode application or should I be using replymessage? I will give it another try after work today and post some updates thank you for your response and start in the right direction.
Randor 20-Jul-22 8:41am
I can help you with the kernelmode code and anything C/C++ or assembler. But I know very little about VB.NET so I won't be much help there.

Codeproject has a VB.NET forum, I think a few members can help you if the need arises. :)
Dale Seeley 20-Jul-22 10:17am
OK great I will post the driver code today after work if your still here
Dale Seeley 20-Jul-22 23:31pm
Ok this is what I am reading and understanding up to now about FltSendMessage. This takes 7 parameters like so:

1. Filter Handle
2. Client Port
3. Message Buffer
4. Message Buffer Length
5. Reply Buffer
6. Reply Buffer Length
7. Timeout

My book is saying the driver can send any buffer/message described by the third parameter Message Buffer with the length of Message Buffer. Typically the driver will define some structure in a common header file the client can include as well called FileBackupPortMessage. This struct contains the file name length and the file name itself but This seems to be my issue because I am unaware of how to interact with this structure or any from my client using VB.NET. I understand VB.NET is not your strong point to offer help but might there be a way to send the message without the use of this struct? there is also the use of another struct _FILTER_MESSAGE_HEADER if a reply is expected this structure indicates the reply length in bytes and the message ID which again the client should use if it calls FilterReply-Message. Timeout specifies the time waited by the driver to send the message to the client. Unless any of this is incorrect the code should be something like this in C

1. Filter Handle declared global PFLT_FILTER FilterHandle;
2. Client Port declared global PFLT_PORT SendClientPort;

and the rest of the example code is placed within the FLT_PREOP_CALLBACK_STATUS:

if (SendClientPort) {
USHORT nameLen = context->FileName.Length;
USHORT len = sizeof(FileBackupPortMessage) + nameLen;
auto msg = (FileBackupPortMessage*)ExAllocatePoolWithTag(PagedPool, len, DRIVER_TAG);
if (msg) {
msg->FileNameLength = nameLen / sizeof(WCHAR);
RtlCopyMemory(msg->FileName, context->FileName.Buffer, nameLen);
timeout.QuadPart = -10000 * 100; // 100msec
FltSendMessage(gFilterHandle, &SendClientPort, msg, len,
nullptr, nullptr, &timeout);

FltSendMessage in the driver example has parameters 5 and 6 as nullptr because to my understanding the example is only sending a message and does not expect a reply which I am sure I will need in order to block or allow process creation.
Dale Seeley 20-Jul-22 23:37pm

PVOID* CompletionContext)

if ((Data->Iopb->Parameters.AcquireForSectionSynchronization.PageProtection & PAGE_EXECUTE) && (Data->Iopb->Parameters.AcquireForSectionSynchronization.SyncType == SyncTypeCreateSection))
NTSTATUS status;

status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &FileNameInfo);

if (NT_SUCCESS(status)) {

status = FltParseFileNameInformation(FileNameInfo);

if (NT_SUCCESS(status)) {

if (FileNameInfo->Name.MaximumLength < 260) {

status = IoVolumeDeviceToDosName(FltObjects->FileObject->DeviceObject, &DoSPath);
if (NT_SUCCESS(status))
//check here to determine if the process should be allowed or not to run
//Data->IoStatus.Status = STATUS_ACCESS_DENIED;
//Data->IoStatus.Information = 0;

if (SendClientPort) {

processName.Length = 0;
processName.MaximumLength = (USHORT)DoSPath.MaximumLength + Data->Iopb->TargetFileObject->FileName.MaximumLength + 2;
processName.Buffer = ExAllocatePoolWithTag(PagedPool, processName.MaximumLength, PROC_TAG);

RtlCopyUnicodeString(&processName, &DoSPath);
RtlAppendUnicodeStringToString(&processName, &Data->Iopb->TargetFileObject->FileName);

KdPrint(("%wZ \r\n", processName));
RtlCopyUnicodeString(&ImageP, &processName);

//RtlCopyMemory(processName, processName.Buffer, processName.MaximumLength);
timeout.QuadPart = 10000 * 100;
FltSendMessage(FilterHandle, &SendClientPort, processName.Buffer, processName.MaximumLength, NULL, NULL, &timeout);

Dale Seeley 20-Jul-22 23:47pm
Of course my MiniDriverPreOperation is probably incorrect and missing allot but was my attempt to send the message without using structs but to send the file path I am using UnicodeString and RtlCopyMemory says its incompatible.
Randor 21-Jul-22 5:41am
Have a look at RtlInitUnicodeString to initialize your UNICODE_STRING
Dale Seeley 21-Jul-22 8:33am
Is the code looking correct though? Is there anything missing and is Rtlinitunicodestring used so I can copy memory?
Randor 21-Jul-22 10:11am
Can you upload it somewhere so I can see more code?
Dale Seeley 21-Jul-22 12:07pm
Sure I'll upload it to my Google drive after my work today thank you very much for taking time for me.
Dale Seeley 22-Jul-22 20:17pm
Here is the link!
Dale Seeley 23-Jul-22 20:43pm
This is the new updated code I have uploaded it to my google drive
Dale Seeley 24-Jul-22 21:30pm
I have created a new question here please check it out Randor when you can I would greatly apricate it and thank you for all your help up to now!
Randor 21-Jul-22 11:15am
I also see where you call ExAllocatePoolWithTag but you never release the memory. Can you confirm?

You could use the stack here with RtlInitUnicodeString and pass it a local WCHAR array of [260] since you seem to be checking for that length.
Dale Seeley 22-Jul-22 19:45pm
I am about to upload the project to my google drive please let me know if your online now or can take a look I am lost. Thank you Randor C coding is still a challenge for me and not my strong point.
Dale Seeley 11-Jun-22 1:37am
Thank you for taking a look allowing or blocking processes is causing me so much headache and prolonging my development by months now so im very greatful for this help to understand and get it done hopefully.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900