Windows NT 3.51 graphics drivers had access to all user-mode system functions provided in user-mode DLLs such as kernel32.dll and advapi32.dll, and to all the GDI helper routines exported by winsrv.dll. In Windows NT 4.0, graphics drivers have access to functions exported by win32k.sys only. Except for a few obsolete functions, win32k.sys exports all the original exports that were found in winsrv.dll, such as EngBitBlt. The win32k.sys library also exports a new set of functions that provide basic operating system services, such as memory allocations and synchronization.
So why do all the graphics drivers need to change? One could argue that the existing graphics drivers should just be loaded in the kernel, with Microsoft’s assurance that they work.
The first step to this approach would be to write stubs for all the Win32 functions called by the driver. These stubs would map the Win32 functions to their kernel-mode equivalents, letting drivers run with no modifications. Many of the functions, such as the memory allocators, would be easy to stub. However, some of the drivers used a very large number of user-mode functions, and some of these functions were almost impossible, technically, to implement in kernel mode. Since all of the required stubs could not be implemented, this meant that at least a few of the 3.51 drivers would not run.
It was also discovered that some Windows NT 3.51 drivers depended on certain special features of a user-mode process:
Any driver relying on these features in user-mode would cause Windows NT to crash when running in kernel mode.
For all of these reasons, it was decided that graphics drivers should be moved to the executive and revised.