In my DispatchWrite routine I need more processing for the IRP so I pend it and queue it to a worker thread.
If I have a neither I/O write then first I allocate a MDL, lock it and get a system space mapped virtual address with MmGetSystemAddressForMdlSafe, the i use MmProtectMdlSystemAddress to set the PAGE_EXECUTE_READWRITE flag.
Now for my IRP to be succesfully completed in the worker thread I change the IRP->UserBuffer with what MmGetSystemAddressForMdlSafe returns.
In most of the cases this works really fine.
The whole cleanup (unlocking the pages and free ing the mdl are done in the worker thread)
The worker thread mostly calls IoCallDriver with the lower device object I am attached to, than calls MmUnlockPages.
But sometimes on the virtual machine IoCallDriver throws an exception and I see written in WinDbg: “a driver has leaked xxxx bytes of virtual memory”
sometimes IoCallDriver works fine but when I call MmUnlockPages i get another exception that it ultimately is handled by the OS (because the debugger is connected), but on the real machine I get blue screen with the messahe: a thread tried to free a resource that I did not own.
I tested it on a real machine and it works fine, except when I receive a Write request from my usb connected hdd, which is “\Device\HarddiskVolume2”
I thought of another way. I should copy the contents of the user buffer in a different system buffer and the build an irp and send it, and complete the initial irp without sending it and put the status code from my built irp.
But I am still puzzled what is wrong with what am I doing and why it works only in certain
cases.