Minor additional information:
ZwCreateFile is a syscall. It reenters the kernel via INT 2Eh or SYSENTER. This
forms the new trap frame on the stack, and so the ExGetPreviousMode call inside
NtCreateFile (which is just function, registered in a system service table as a
syscall body) will always return KernelMode. In the MJ_CREATE IRP,
the ->RequestorMode field will also be KernelMode.
This relaxes the buffer validity checks in the IO manager and drivers,
Calling NtCreateFile itself (the syscall implementation) will not make a new
trap frame on the stack, and so the requestor mode will be the same as the
ExGetPreviousMode result of the caller. In some cases, this result can be
UserMode, depends on from where the driver wants to open a file.
This will lead to full-scale buffer validity checks, which fill nearly surely
fail if the kernel-space buffers are used for object attributes etc.
Resume: do not use Ntxxx routines in the driver, use ZwXxx.
IoGetDeviceObjectPointer is a sequence of:
Maxim Shatskih, Windows DDK MVP