I would write a driver that creates a WDF device object. I would then open this device from user-mode and send custom IO control requests” – A typical user-kernel communication scenario.

Today, when I was doing this, I hit an issue opening the device in user-mode. I received ERROR_ACCESS_DENIED. User mode application is running with admin credentials, then what went wrong?

Screen Shot 2017-03-30 at 7.10.49 PM

I used WinObj to confirm that my DosDevice and Device are set correctly. I also confirmed that in user-mode, I am using path as “\.MyDevice” (L”.MyDevice”).

If you have not used WinObj, it is a great tool from Microsoft to explore Windows Object Manager Namespace and Security ACLs of these objects.

I tried all access modes – GENERIC_READ, GENERIC_WRITE, BOTH (GENERIC_READ | GENERIC_WRITE) and NONE (0). I also tried different share modes – FILE_SHARE_[READ | WRITE], NONE (0).

I should admit, that was more of hit-try from frustration. And that does not help 🙂

Then, I looked at the way I created my device.

WdfDeviceInitSetCharacteristics(pWDFDeviceInit, FILE_DEVICE_SECURE_OPEN, FALSE);

This is also fine. Device characteristics was to Secure Open and since this was the only characteristic I was setting, the third argument was False.

So, I went another step back…

pWDFDeviceInit = WdfControlDeviceInitAllocate(*pDriver, &SDDL_DEVOBJ_KERNEL_ONLY);

With SDDL_DEVOBJ_KERNEL_ONLY, I am setting the device to be only accessible from Kernel. I need to set it to SDDL_DEVOBJ_SYS_ALL to allow Kernel and user mode code running as System! Problem found and fixed!

WdfControlDeviceInitAllocate(*pDriver, &SDDL_DEVOBJ_SYS_ALL);


Reference SDDL for Device Objects on MSDN.

Since there was a lot of discussion around this on various forums and none pointed me to this direction, I though it be a good idea to document my fix as well. Hope this helps!