The Credibility of NTDLL Export Availability

For the handful of NTDLL exports that are documented explicitly as NTDLL functions and the many more for which a corresponding kernel-mode export is documented in the WDK, Microsoft either lies about the applicable versions or says nothing.

Though saying nothing is unhelpful, it seems the less unethical and it anyway was readily understandable in the early years as natural neglect: the Windows kernel itself didn’t export any sort of function for reporting the Windows version until version 4.0. Early Device Driver Kit (DDK) documentation only rarely mentions any Windows version other than the one the kit was prepared for, so much so that the DDK for Windows XP stood out for its promotion of new functionality as new for Windows XP.

The first big change from mostly saying nothing was not in the documentation but in the declarations. The Windows Driver Kit (WDK) for Windows Vista, with headers dated 2nd November 2006, wrapped many declarations in conditional compilation blocks such that functions are exposed for programming only if building with an expected value of the NTDDI_VERSION macro. The lowest defined of these expected values was for Windows 2000. As appropriate as this may have been for a kit that had Windows 2000 as its oldest supported target version for building drivers, conditional blocks were added even for functions that long pre-date Windows 2000. These functions’ declarations might just as well have been left unadorned as far as could affect any programming.

A second change in 2009 carried this notion of Windows 2000 as the beginning of time into the documentation. The second WDK for Windows 7 (version 7600.16385.1, dated 1st December 2009) added “Available in Windows 2000 and later versions of Windows” to the documentation of nearly every function for which no minimum version was yet specified. This is not unreasonable inasmuch as it means only that Microsoft no longer supports earlier versions of Windows, but of course it will easily be taken by some as accurate history.

Of course, where Microsoft documents a function as available only in some versions, the intention may just be that those are the versions for which the function is implemented well enough to consider usable by programmers in general. It could be that the function is exported from earlier versions but in an experimental or even defective implementation that Microsoft cannot support. Certainly, a pattern is discernable in which a function is said to be available starting from whatever Windows version was contemporaneous with the function’s introduction to the documentation. This is perhaps how RtlGetDaclSecurityDescriptor is dated to Windows Server 2003 SP1—yes, so precisely—even though it is an original export in both kernel and user modes.

There is anyway the complication that although the WDK is Microsoft’s only known public reference material for functions that happen to have the same names and types (and often the same implementations too) as a good selection of user-mode exports from NTDLL, it is a kit for writing device drivers, mostly for execution in kernel mode to import the functions not from NTDLL but from the kernel.

Special mention must be made of a few NTDLL functions that Microsoft documented as Settlement Program Interfaces in late 2002 apparently because they are used by Microsoft Middleware products such as Internet Explorer. There were not many at this low level. A good proportion have become re-undocumented in the years since, at least as exports from NTDLL. It should anyway not go unnoticed that Microsoft’s selection of functions to document for the settlement was very strict, if not grudging and perverse. For instance, RtlTimeToSecondsSince1970 got documented explicitly as a user-mode function but its inverse RtlSecondsSince1970ToTime did not.