Geoff Chappell - Software Analyst
This page lists the 618 functions and variables that are exported from the i386 (x86) build of the Windows kernel in version 3.10. It is here thought that no changes were made by service packs of version 3.10, but beware that only SP3 has yet been obtained for inspection.
Together with 69 from the contemporaneous HAL, these 618 exported functions and variables are the original kernel-mode programming interface for the Windows that is its own operating system (in contrast to the Windows that runs on DOS). They make up nearly a fifth of all exports from the kernel over all known versions. All but 37 are still exported from the i386 kernel as of Windows 10, but 60 were never adopted as exports from the amd64 (x64) kernel.
To convey more detail with less text, the page relies heavily on several types of shortcut.
The first is that although a few of the kernel’s exports are of variables rather than functions, I tend to talk of all as functions, hoping that no confusion will be caused by the loose terminology. The variables are indicated by a parenthetical “data” after their name in the Functions column.
Documentation status is summarised by colour coding. (Had the website’s scripts run as expected, then hovering over any colour-coded text would produce a tooltip that shows why the text is coloured.) (To decode a colour, hover for a tooltip.)
Functions that appear to be completely undocumented are highlighted yellow. If a function is documented now but was not documented in the first contemporaneous Device Driver Kit (DDK), Windows Driver Kit (WDK) or Installable File System (IFS) Kit, then it is shaded yellow to retain some of its previous status. If a function is documented as reserved or obsolete, it is shaded red or shaded grey, respectively. Otherwise, functions that have their own non-trivial documentation are left with no background colour.
Many undocumented functions (and some variables) have C-language declarations in one or another header file from one or more of Microsoft’s programming kits. Without meaning to suggest that the declaration counts as documentation, no matter that Microsoft does sometimes “document” a function just by repackaging the declaration, the function is shaded orange to distinguish it as not completely undocumented.
A function is highlighted orange for the further distinction that the declaration’s disclosure was limited to headers from the “minwin” subdirectory of the WDK for Windows 10 in its editions for the original and 1511 versions only. Where this is marked as a function’s current documentation status, the understanding is that the function was undocumented before version 10.0 and would still be undocumented except for the exceptional disclosure in these two WDK editions which Microsoft seems since to have withdrawn.
The default understanding is that exporting continues for all later versions, and in both the x86 and x64 builds. Exceptions are sketched in a column headed Export History.
The description “x86 only” means that the function is not exported from any known x64 build but is exported from the x86 build of at least some version that has an x64 build. If it had already ceased as an export before Windows Server 2003 SP1, the “x86 only” is left unstated.
That a function is “discontinued in” some version means that the function is exported up to but not including the stated version and not in any later version unless “restored”.
It’s nothing but fair to note that the majority of these functions were not documented immediately. Even more were then or later said to require later versions. These misrepresentations of actual availability show also in C-language declarations for the functions’ use in programming. Conveying these differences between what the kernel exported and what Microsoft presented for drivers to import is the concern of columns headed Documentation History and Declaration History.
Conventions still in development!
A few of these original functions are affected by changes to the kernel as early as version 3.50. What changed immediately in the documentation or declarations is presently unknown because no DDK for Windows NT 3.50 has yet been found for inspection. Applicable DDK versions are left to the imprecision of “3.50 to 3.51” unless a narrowing to one or the other is inferred and explained.
Many functions in these early versions got their first documentation or declaration not in the ordinary DDK but in a separate IFS Kit because their use was specially anticipated for installable file system (IFS) drivers. This IFS KIt had limited distribution, possibly under conditions of non-disclosure, before its merger into the WDK for Windows Vista. The IFS Kit for Windows 2000 states that it is the first with documentation. There are IFS Kits for Windows XP and Windows Server 2003 but I have not obtained either for inspection. Where applicable DDK versions are left to the imprecision of “5.1 (IFS) to 6.0”, whatever is described is known from the IFS section of the WDK for Windows Vista but is unknown to the IFS Kit for Windows 2000 and to each ordinary DDK for Windows 2000, Windows XP and Windows Server 2003: it may or may not be in an IFS Kit for Windows XP or Windows Server 2003.
As much as I might like to condense into one table as much as might be imagined is possible to summarise about each function’s history of availability both in the binary and according to the documentation and headers, many functions both individually and in groups demand additional explanation in text. I therefore break the tabulation according to Microsoft’s scheme of prefixes for separate areas of functionality within the otherwise monolithic kernel. Each function has its own row in one table, but please be sure to check for explanatory text before and (more usually) after the table.
Function | Documentation History | Declaration History |
---|---|---|
CcCanIWrite | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcCopyRead | before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 |
CcCopyWrite | before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 |
CcDeferWrite | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcFlushCache | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcGetDirtyPages | before 5.1 (IFS), undocumented;
documented start is 5.1 |
since 6.0, declared start is 5.1 |
CcGetFileObjectFromBcb | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcGetFileObjectFromSectionPtrs | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcInitializeCacheMap | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcIsThereDirtyData | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcMapData | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcMdlRead | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcMdlReadComplete | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcMdlWriteComplete | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcPinMappedData | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcPinRead | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcPrepareMdlWrite | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcPreparePinWrite | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcPurgeCacheSection | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcRepinBcb | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcScheduleReadAhead | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcSetAdditionalCacheAttributes | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcSetDirtyPageThreshold | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcSetDirtyPinnedData | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcSetFileSizes | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcSetLogHandleForFile | before 5.1 (IFS), undocumented;
documented start is 5.1 |
since 6.0, declared start is 5.1 |
CcSetReadAheadGranularity | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcUninitializeCacheMap | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcUnpinData | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcUnpinDataForThread | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcUnpinRepinnedBcb | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
CcZeroData | before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 |
Among exported functions that are documented, CcMapData and CcPurgeCacheSection are unusual in having changed their prototypes. For both, what was originally a BOOLEAN argument got widened to a ULONG such that the value 1 which stood for TRUE becomes just one of potentially many bit flags. Changes of prototype in exported functions, and especially in documented functions, are rare enough that I might list each of these as two different functions, except that the changes extend the interface compatibly. Still, one if not both functions present the problem that the documentation did not immediately note the change.
For CcMapData, the change starts with version 5.1. That it was documented as early as the IFS Kit for Windows XP seems likely, but an error is certain: documentation in the WDK for Windows Vista, and ever since, incorrectly dates the change to version 5.0. Do not miss the irony that one of the WDK documentation’s few explicit acknowledgements that a function existed before Windows 2000 is wrong in the detail.
For CcPurgeCacheSection, the new prototype applies first in version 6.0 but does not show in the documentation until version 6.2.
The IFS Kit for Windows XP is listed above as providing the first documentation of CcGetDirtyPages and CcSetLogHandleForFile, but this is mere supposition. Neither is documented in the IFS Kit for Windows 2000. Both are documented in the WDK for Windows Vista. With no intervening IFS Kit for reference, I infer that the version 6.0 documentation requires Windows XP for these ancient functions because it was for Windows XP that Microsoft first documented them. Note that no such generosity of inference is as easily supported for the three (CcCopyRead, CcCopyWrite and CcZeroData) that Microsoft later says require Windows 2000.
Function | Documentation History | Declaration History | NTDLL History |
---|---|---|---|
DbgBreakPoint | in 5.1 to 5.2, documented start is 5.0 | since 6.0, declared start is 5.0 | all |
DbgLoadImageSymbols | |||
DbgPrint | since 5.1, documented start is 5.0 | all |
The DbgBreakPoint function is the only known example of Microsoft’s having retracted a misrepresentation that a function requires Windows 2000 when in fact its availability is ancient. Perhaps someone with a level head (and the right clout) pointed out the absurdity that the one exported function that the kernel provided from the start for the vital matter of breaking to a debugger had been documented all along but suddenly “can only be used in Windows 2000 and later.”
Function | Export History | Documentation History | Declaration History |
---|---|---|---|
ExAcquireResourceExclusive | discontinued in 5.1 | before 3.50, documented | since 5.1, deprecated |
ExAcquireResourceShared | discontinued in 3.50 | before 3.50, undocumented; before 5.0, declared |
since 5.1, deprecated |
ExAllocatePool | before 5.1, documented | since 5.2, deprecated; since 6.0, declared start is 5.0 |
|
ExAllocatePoolWithQuota | before 5.1, documented | since 5.2, deprecated; since 6.0, declared start is 5.0 |
|
ExConvertExclusiveToShared | discontinued in 3.50 | before 3.50, undocumented; before 5.0, declared |
since 5.1, deprecated |
ExDeleteResource | discontinued in 5.1 | before 3.50, documented | since 5.1, deprecated |
ExDisableResourceBoost | discontinued in 3.50 | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
|
ExExtendZone | before 5.0, documented | since 5.1, deprecated; since 6.0, declared start is 5.0 |
|
ExFreePool | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
ExInitializeResource | discontinued in 5.1 | before 3.50, documented | since 5.1, deprecated |
ExInitializeZone | before 5.0, documented | since 5.1, deprecated; since 6.0, declared start is 5.0 |
|
ExInterlockedAddLargeInteger | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
ExInterlockedAddUlong | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
ExInterlockedDecrementLong | x86 only | before 3.51, documented | since 5.1, deprecated |
ExInterlockedExchangeUlong | x86 only | before 3.51, documented | since 5.1, deprecated |
ExInterlockedIncrementLong | x86 only | before 3.51, documented | since 5.1, deprecated |
ExInterlockedInsertHeadList | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
ExInterlockedInsertTailList | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
ExInterlockedPopEntryList | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
ExInterlockedPushEntryList | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
ExInterlockedRemoveHeadList | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
ExIsResourceAcquiredShared | discontinued in 3.50 | before 3.50, undocumented; before 5.2 SP1, declared |
since 5.1, deprecated |
ExLocalTimeToSystemTime | before 3.50 to 3.51, undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | |
ExQueryPoolBlockSize | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 | |
ExQueueWorkItem | before 5.0, documented; before 5.2, obsolete |
since 5.1, deprecated; since 6.0, declared start is 5.0 |
|
ExRaiseHardError | |||
ExRaiseStatus | before 3.51, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | |
ExReleaseResource | discontinued in 3.50 | before 3.50, documented | since 5.1, deprecated |
ExReleaseResourceForThread | discontinued in 5.1 | before 3.50, documented | since 5.1, deprecated |
ExSystemExceptionFilter | |||
ExSystemTimeToLocalTime | before 3.50 to 3.51, undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | |
Exi386InterlockedDecrementLong | x86 only | before 3.50, declared | |
Exi386InterlockedExchangeUlong | x86 only | before 3.50, declared | |
Exi386InterlockedIncrementLong | x86 only | before 3.50, declared |
The nine functions that work with the Executive’s synchronisation resource have a complicated history. The implementation was significantly redeveloped for the very next version but its reduction of the ERESOURCE structure meant that new drivers, allowing only for a smaller size, could not safely use the old functions when running with an old kernel. For new drivers, version 3.50 exports a new set of functions. These are mostly named from the old just by appending Lite. For old drivers, the old functions live on in two ways. First, all the old functions are redefined by macro in terms of the new so that an old driver rebuilt with a new DDK (presumably as early as the one for version 3.50) is in effect a new driver without having needed any rewriting of source code. Second, so that old drivers that are not rebuilt might run on the next few Windows versions, four of the original five functions that had been documented continue to be exported up to and including version 5.0. The other that had been documented had already been redefined by macro such that old drivers should not be importing it. This function and the four that had never been documented cease as exports right from version 3.50. The five that had been documented stayed documented but as the first kernel functions to be documented as obsolete. The four that had never been documented and were now discontinued might have been left to oblivion, but the Windows 2000 DDK revived them just to document them as obsolete (even though they cannot be imported).
The ExQueueWorkItem function is unusual for having been obsolete and then not, and also for having been documented differently concurrently. In the WDK for Windows Vista, the function has one page of documentation for programming that uses just the DDK and another for the more specialised use that is catered to by the IFS Kit. The DDK page has the function as obsolete. This dates from the DDK for Windows 2000, which introduced IoQueueWorkItem for drivers to use instead. For versions 5.1 and 5.2 the function stayed obsolete in the DDK, but perhaps it got different documentation in the IFS Kit for either or both of these versions. The IFS page for Windows Vista looks to have revived the function’s documentation from before Windows 2000, with warnings added about needing “extreme caution”. Though the WDK for Windows Vista has both the DDK and IFS documentation, later WDKs retain only the latter and thus do not present the function as obsolete—as far as spelled out in the documentation. In the headers, however, the status is a little different. Starting with the WDK for Windows 7, an annotation for Microsoft’s tools for static code analysis states clearly that the function is “Obsolete in all drivers for Vista. Obsolete downlevel except for limited use in IFS. See the documentation”, but the cited documentation does not itself say the function is obsolete.
The ExRaiseStatus function may be documented as early as version 3.50 but is here conjectured not to have been, it being thought more natural to have got documented for version 3.51 while working on the latter to introduce ExRaiseAccessViolation and ExRaiseDatatypeMisalignment. Against this, of course, is that these two functions for version 3.51 weren’t also documented.
The three functions whose names start with Exi386 are notable for reversing the usual transition in which undocumented functions get declared (and eventually documented). In version 3.10, they are the explicitly declared exports for their interlocked operations but they are left undocumented as a platform-specific implementation detail. The documented functions, which are platform-independent and do not have i386 in their names, are exported but NTDDK.H redefines them by macro when building for the x86. Version 3.50 has new platform-specific variants with a different calling convention and the new prefix Exfi386 in their names. If there was a DDK for Windows NT 3.50, it surely will have changed to declaring the Exfi386 functions, leaving the Exi386 functions to be lost from the declarations and become undocumented. The documented platform-independent ExInterlockedDecrementLong, etc., will then have become obsolete when version 3.51 simplified to InterlockedDecrement, etc.
Function | Documentation History | Declaration History |
---|---|---|
FsRtlAddLargeMcbEntry | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlAddMcbEntry | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlAllocatePool | before 5.0 (IFS), undocumented | |
FsRtlAllocatePoolWithQuota | before 5.0 (IFS), undocumented | |
FsRtlAllocateResource | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
FsRtlAreNamesEqual | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlBalanceReads | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
FsRtlCheckLockForReadAccess | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlCheckLockForWriteAccess | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlCheckOplock | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared; since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 |
FsRtlCopyRead | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlCopyWrite | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlCurrentBatchOplock | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
FsRtlDeregisterUncProvider | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlDissectDbcs | before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 |
FsRtlDissectName | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlDoesDbcsContainWildCards | before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 |
FsRtlDoesNameContainWildCards | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlFastCheckLockForRead | before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 |
FsRtlFastCheckLockForWrite | before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 |
FsRtlFastUnlockAll | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlFastUnlockAllByKey | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlFastUnlockSingle | before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 |
FsRtlGetNextFileLock | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlGetNextLargeMcbEntry | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlGetNextMcbEntry | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlInitializeFileLock | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlInitializeLargeMcb | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlInitializeMcb | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlInitializeOplock | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
FsRtlIsDbcsInExpression | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlIsFatDbcsLegal | before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 |
FsRtlIsHpfsDbcsLegal | before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 |
FsRtlIsNameInExpression | before 5.0 (IFS), undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 |
FsRtlIsNtstatusExpected | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlIsTotalDeviceFailure | before 5.0 (IFS), declared; since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 |
FsRtlLegalAnsiCharacterArray (data) | before 5.0 (IFS), undocumented | |
FsRtlLookupLargeMcbEntry | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlLookupLastLargeMcbEntry | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlLookupLastMcbEntry | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlLookupMcbEntry | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlMdlRead | ||
FsRtlNormalizeNtstatus | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlNotifyChangeDirectory | ||
FsRtlNotifyCleanup | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlNotifyReportChange | ||
FsRtlNumberOfRunsInLargeMcb | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlNumberOfRunsInMcb | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlOplockFsctrl | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
FsRtlOplockIsFastIoPossible | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
FsRtlPostStackOverflow | before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 |
FsRtlPrepareMdlWrite | ||
FsRtlPrivateLock | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
FsRtlProcessFileLock | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlRegisterUncProvider | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlRemoveLargeMcbEntry | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlRemoveMcbEntry | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlSyncVolumes | ||
FsRtlUninitializeFileLock | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlUninitializeLargeMcb | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlUninitializeMcb | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
FsRtlUninitializeOplock | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
Of kernel exports for which the first known documentation is the IFS Kit for Windows 2000, FsRtlIsTotalDeviceFailure is alone in having been declared in earlier editions of the ordinary DDK—indeed, right from the DDK for Windows NT 3.10.
Though no public documentation of FsRtlMdlRead is known, nor even a declaration except in NTOSP.H from those early editions of the WDK for Windows 10, the function does get mentioned among the Remarks in documentation of FsRtlIncrementCcFastMdlReadWait. This starts for Windows 8, which happens also to be the version that introduces FsRtlMdlReadEx.
Function | Documentation History | Declaration History |
---|---|---|
IoAcquireCancelSpinLock | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoAcquireVpbSpinLock | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
IoAdapterObjectType (data) | ||
IoAllocateAdapterChannel | before 5.0, documented | since 5.1, deprecated; since 6.0, declared start is 5.0 |
IoAllocateController | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoAllocateErrorLogEntry | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoAllocateIrp | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoAllocateMdl | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoAttachDevice | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoAttachDeviceByPointer | before 5.0, documented | since 5.1, deprecated; since 6.0, declared start is 5.0 |
IoBuildAsynchronousFsdRequest | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoBuildDeviceIoControlRequest | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoBuildPartialMdl | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoBuildSynchronousFsdRequest | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoCallDriver | since 6.1 revision, documented start is 5.0 | |
IoCancelIrp | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoCheckDesiredAccess | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
IoCheckEaBufferValidity | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
IoCheckFunctionAccess | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
IoCheckShareAccess | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoCompleteRequest | since 6.1 revision, documented start is 5.0 | |
IoConnectInterrupt | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoCreateController | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoCreateDevice | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoCreateFile | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 |
IoCreateStreamFileObject | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
IoCreateSymbolicLink | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoCreateSynchronizationEvent | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoCreateUnprotectedSymbolicLink | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoDeleteController | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoDeleteDevice | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoDeleteSymbolicLink | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoDetachDevice | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoDeviceObjectType (data) | ||
IoDisconnectInterrupt | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoFileObjectType (data) | before 3.50 to 3.51, undocumented;
since 5.0, indirectly documented |
|
IoFreeController | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoFreeIrp | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoFreeMdl | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoGetConfigurationInformation | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoGetCurrentProcess | before 3.50 to 3.51, declared; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 |
IoGetDeviceObjectPointer | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoGetRelatedDeviceObject | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoInitializeIrp | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoInitializeTimer | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoIsOperationSynchronous | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
IoMakeAssociatedIrp | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoQueryDeviceDescription | before 5.0, documented | since 5.1, deprecated; since 6.0, declared start is 5.0 |
IoRaiseHardError | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoRaiseInformationalHardError | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoReadOperationCount (data) | before 5.0 (IFS), undocumented | |
IoReadTransferCount (data) | before 5.0 (IFS), undocumented | |
IoRegisterDriverReinitialization | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoRegisterFileSystem | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
IoRegisterShutdownNotification | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoReleaseCancelSpinLock | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoReleaseVpbSpinLock | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
IoRemoveShareAccess | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoReportHalResourceUsage | ||
IoReportResourceUsage | before 5.0, documented | since 5.1, deprecated; since 6.0, declared start is 5.0 |
IoSetHardErrorOrVerifyDevice | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoSetInformation | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
IoSetShareAccess | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoStartNextPacket | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoStartNextPacketByKey | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoStartPacket | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoStartTimer | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoStatisticsLock (data) | before 5.0 (IFS), undocumented | |
IoStopTimer | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoUnregisterFileSystem | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
IoUnregisterShutdownNotification | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoUpdateShareAccess | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoVerifyVolume | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
IoWriteErrorLogEntry | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
IoWriteOperationCount (data) | before 5.0 (IFS), undocumented | |
IoWriteTransferCount (data) | before 5.0 (IFS), undocumented |
As with most exported variables, IoFileObjectType is not itself documented. Starting with the DDK for Windows 2000, however, it gets mentioned in the documentation of exported functions such as ObReferenceObjectByHandle from its being intended as an argument.
Though IoReportHalResourceUsage is not known ever to have been documented or declared, it features in a comment in NTDDK.H starting with the DDK for Windows 2000. Some measure of what undocumented can mean is that the (single-line) comment is for a member of an undocumented enumeration that NTDDK.H shows only as a member of an undocumented structure that is presented only as being accessed from four more undocumented structures that are in turn only in an undocumented union whose address can be passed among the arguments of an undocumented function type, a pointer to which can be a member of an undocumented structure that neither NTDDK.H nor any other WDK header refers to.
In version 3.10, IoStatisticsLock is the spin lock that protects the 64-bit counters such as IoReadTransferCount that eventually get declared together in NTIFS.H. What makes it notable for a historical survey is that it got declared only after the kernel had stopped using it—indeed, long after, since this last known use did not survive even to version 3.50.
Function | Documentation History |
---|---|
KdDebuggerEnabled (data) | since 5.2 SP1, indirectly documented; documented start is 5.1 |
KdDebuggerNotPresent (data) | since 5.2 SP1, indirectly documented; documented start is 5.1 |
KdPollBreakIn |
The indirect documentation of the KdDebuggerEnabled and KdDebuggerNotPresent variables is through the macros KD_DEBUGGER_ENABLED and KD_DEBUGGER_NOT_PRESENT which are each presented as a “global kernel variable”. The macros are first documented in the DDK for Windows Server 2003 SP1. The variables are there dated to Windows XP. The macros are indeed defined first in the DDK for Windows XP but the exported variables are declared even in the DDK for Windows NT 3.1.
Function | Export History | Documentation History | Declation History |
---|---|---|---|
Ke386CallBios | x86 only; discontinued in 6.2 |
||
Ke386IoSetAccessProcess | x86 only | ||
Ke386QueryIoAccessMap | x86 only | ||
Ke386SetIoAccessMap | x86 only | ||
KeAcquireSpinLockAtDpcLevel | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeAttachProcess | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 | |
KeBugCheck | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeBugCheckEx | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeCancelTimer | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeConnectInterrupt | |||
KeDcacheFlushCount | discontinued in 5.2 | ||
KeDelayExecutionThread | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeDetachProcess | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 | |
KeDisconnectInterrupt | discontinued in 6.0 | ||
KeEnterKernelDebugger | before 5.1, declared | ||
KeFindConfigurationEntry | |||
KeFlushEntireTb | |||
KeGetCurrentThread | before 5.0, declared; since 6.1 revision, documented start is 5.0 |
||
KeGetPreviousMode | x86 only | ||
KeI386AbiosCall | x86 only; discontinued in 6.2 |
||
KeI386AllocateGdtSelectors | x86 only; discontinued in 6.2 |
||
KeI386FlatToGdtSelector | x86 only; discontinued in 6.2 |
||
KeI386GetLid | x86 only; discontinued in 6.2 |
||
KeI386MachineType (data) | x86 only | ||
KeI386ReleaseLid | x86 only; discontinued in 6.2 |
||
KeIcacheFlushCount | discontinued in 5.2 | ||
KeInitializeApc | |||
KeInitializeDeviceQueue | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeInitializeDpc | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeInitializeEvent | since 6.1 revision, documented start is 5.0 | ||
KeInitializeInterrupt | |||
KeInitializeMutant | before 5.1 (IFS) to 6.0, undocumented | since 6.0, declared start is 5.0 | |
KeInitializeMutex | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeInitializePowerStatus | discontinued in 3.50 | ||
KeInitializeSemaphore | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeInitializeSpinLock | x86 only | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
KeInitializeTimer | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeInsertByKeyDeviceQueue | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeInsertDeviceQueue | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeInsertQueueApc | |||
KeInsertQueueDpc | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeInsertQueuePowerStatus | discontinued in 3.50 | ||
KeIsExecutingDpc | before 6.0, x86 only | before 1803, undocumented; documented start is 1803 |
declared start is 1803 |
KeLeaveCriticalRegion | before 3.50 to 3.51, undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | |
KeNumberProcessors (data) | before 6.1, declared | ||
KeProfileInterrupt | x86 only; discontinued in 6.2 |
||
KeQuerySystemTime | x86 only | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
KeQueryTickCount | x86 only | since 6.1 revision, documented start is 5.0 | |
KeQueryTimeIncrement | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeReadStateEvent | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeReadStateMutex | since 6.1 revision, documented start is 5.0 | in 3.50 to 5.0, not declared; since 6.0, declared start is 5.0 |
|
KeReadStateSemaphore | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeReadStateTimer | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeReleaseMutant | before 5.1 (IFS) to 6.0, undocumented | since 6.0, declared start is 5.0 | |
KeReleaseMutex | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeReleaseSemaphore | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeReleaseSpinLockFromDpcLevel | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeRemoveByKeyDeviceQueue | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeRemoveDeviceQueue | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeRemoveEntryDeviceQueue | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeRemoveQueueDpc | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeRemoveQueuePowerStatus | discontinued in 3.50 | ||
KeResetEvent | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeSetBasePriorityThread | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeSetEvent | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeSetPriorityThread | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeSetTimeIncrement | discontinued in 6.3 | ||
KeSetTimer | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeSynchronizeExecution | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeTerminateThread | discontinued in 6.1 | ||
KeTimeIncrement (data) | discontinued in 3.50 | ||
KeUpdateRunTime | discontinued in 6.3 | ||
KeUpdateSystemTime | discontinued in 6.2 | ||
KeWaitForMultipleObjects | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
KeWaitForMutexObject | before 3.50, undocumented; since 6.1 revision, documented start is 5.0 |
||
KeWaitForSingleObject | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
Kei386EoiHelper | x86 only | ||
KiAcquireSpinLock | x86 only | ||
KiCoprocessorError | x86 only; discontinued in 6.3 |
||
KiDeliverApc | x86 only | ||
KiDispatchInterrupt | x86 only | ||
KiIpiSend | discontinued in 4.0 | ||
KiIpiServiceRoutine | x86 only | ||
KiReleaseSpinLock | x86 only | ||
KiUnexpectedInterrupt | x86 only | ||
Kii386SpinOnSpinLock | x86 only; discontinued in 6.1 |
In all versions of x86 Windows that have both KeGetPreviousMode and ExGetPreviousMode, the two have the same address. The x64 kernel exports only the latter and the former seems never to have been documented for any architecture. Among the headers from the driver kits that are available for inspection, KeGetPreviousMode appears only once: the NTDDK.H in the DDK for Windows XP has it (conditionally) as a macro that can’t compile without whatever private header defines the PreviousMode member of the ordinarily opaque KTHREAD.
Not only are KeInitializeApc and KeInsertQueueApc among the oldest of kernel exports that Microsoft left without public declarations until the presumably accidental disclosure of NTOSP.H in 2015, but there must be a good case that they’re the most signficant. Contrast with KeInitializeDpc and KeInsertQueueDpc, which have been documented from the very beginning. Microsoft needs that drivers for hardware devices can schedule a Deferred Procedure Call (DPC), but scheduling an Asynchronous Procedure Call (APC) from kernel mode has always been functionality that Microsoft keeps to itself, at first for the kernel’s internal use but eventually also for file system drivers if written by Microsoft.
Though practical use of KeNumberProcessors was demonstrated by Microsoft in source code samples published as far back as the DDK for Windows 2000, this variable’s first documentation is only in passing, where the WDK for Windows Vista warns that “Device drivers that are built for Windows Vista and later” should use the new KeQueryActiveProcessorCount function instead. The variable first gets its own page in the WDK for Windows 7, but only then to say formally that it’s obsolete (starting from Windows Vista SP1).
The kernel started with the mutant and mutex as separate types of synchronisation object. Their unification for version 3.50 was problematic because the mutex, which had been documented, was in effect redefined to be the same as the mutant, which had not been documented. For the KeReadStateMutex function, the redefinition is literal: headers in the next few versions of the DDK redefine KeReadStateMutex by macro as KeReadStateMutant. The problem is that the latter is not declared. For all practical effect, at least for programmers outside Microsoft, KeReadStateMutex was documented but not declared.
In version 3.10 only, KeWaitForMutexObject and KeWaitForSingleObject have separate implementations. The former was specialised to waiting on a single object that is known to be a mutex, but it was neither documented nor declared. The more general function was also good for waiting on a mutex, though less good than the specialised function, and was both documented and declared. Later kernels lose the mutex-specific implementation, keeping both functions as exports but with the same address. The corresponding DDK, starting at least for Windows NT 3.51, redefines the one function into the other by macro and documents both. Up to and including the WDK for Windows 7, this documentation of KeWaitForMutexObject presents what looks to be the original declaration, with the function needing the address of a mutex specifically. This declaration does not exist in the headers.
Function | Documentation History |
---|---|
LsaCallAuthenticationPackage | before 3.50 to 3.51, undocumented;
before 6.2, declared |
LsaDeregisterLogonProcess | before 3.50 to 3.51, undocumented;
before 6.2, declared |
LsaFreeReturnBuffer | before 3.50 to 3.51, undocumented |
LsaLogonUser | before 3.50 to 3.51, undocumented |
LsaLookupAuthenticationPackage | before 3.50 to 3.51, undocumented;
before 6.2, declared |
LsaRegisterLogonProcess | before 3.50 to 3.51, undocumented |
The kernel’s six Local Security Authority (LSA) functions are specially difficult for a historical survey of documentation status. All six have long been documented for user-mode programming—the earliest that I have found, from a Platform SDK for January 2000, even says each function “Requires Windows NT 3.1 or later”—but if Microsoft has ever documented any of them for use in kernel mode, then I don’t know where. This might not matter. After all, the kernel’s exported implementations of C Run-Time (CRT) functions are not explicitly documented for kernel-mode use, yet nobody could sensibly count them as undocumented. The complication for the LSA functions is that Microsoft hasn’t just left kernel-mode use as unstated. Things have been done that differentiate the kernel-mode exports from the same-named user-mode exports, and I think this must be taken as deliberate such that kernel-mode use actually is meant not to be documented.
Since neither the DDK nor SDK for Windows NT 3.1 has any mention of these functions either in documentation or in any header for inclusion in source code, there surely can be no dispute that all six are initially undocumented even in user mode. The DDK for Windows NT 3.51 has NTSECAPI.H with declarations of all six. It and the DDK for Windows NT 4.0 also have an LSAAUTH.HLP file that does not formally document any of the functions but does mention four of them and even says that “services” are “callable from both user mode and kernel mode.”
That all six are declared in a header that shipped with the DDK does not obviously mean that all were intended for kernel-mode use. Notably, NTSECAPI.H has the declarations in a conditional-compilation block so that they are dropped if NTIFS.H is included first. For version 3.51, NTIFS.H was still many years away from open distribution. In its first version that’s more or less readily available, with the Windows 2000 IFS Kit, NTIFS.H declares just LsaRegisterLogonProcess and LsaFreeReturnBuffer (and mentions LsaCallAuthenticationPackage and LsaLogonUser in comments). Some time after, but certainly by the WDK for Windows Vista, LsaLogonUser gets declared too. Three of the functions, then, are unambiguously intended for kernel-mode use, at least since the NTIFS.H from version 5.0, even if not documented for it.
The declarations in NTSECAPI.H remain to this day. They’re also in a new header named NTLSA.H, starting with the WDK for Windows Vista. In the WDK for Windows 8, however, a reorganisation of headers into subdirectories named “km”, “um” and “shared” surely is intended by Microsoft as showing which headers are for kernel-mode programming, user-mode programming and both. Since NTSECAPI.H and NTLSA.H both move to the “um” subdirectory, I think their declarations cannot be counted as intended for kernel-mode use.
Function | Export History | Documentation History | Declaration History |
---|---|---|---|
MmAllocateContiguousMemory | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
MmAllocateNonCachedMemory | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
MmBuildMdlForNonPagedPool | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
MmCreateMdl | before 5.0, documented | since 5.1, deprecated; since 6.0, declared start is 5.0 |
|
MmDbgTranslatePhysicalAddress | discontinued in 5.0 | ||
MmFlushImageSection | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | |
MmForceSectionClosed | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | |
MmFreeContiguousMemory | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
MmFreeNonCachedMemory | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
MmGetPhysicalAddress | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
MmIsAddressValid | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
MmIsNonPagedSystemAddressValid | before 4.0, documented | since 5.1, deprecated; since 6.0, declared start is 5.0 |
|
MmMapIoSpace | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
MmMapLockedPages | before 5.2, documented | since 6.0, declared start is 5.0; since 6.0, deprecated |
|
MmProbeAndLockPages | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
MmQuerySystemSize | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
MmSetAddressRangeModified | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | |
MmSizeOfMdl | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
MmUnlockPages | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
MmUnmapIoSpace | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
MmUnmapLockedPages | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
Documentation of MmMapLockedPages is qualified: even now, in 2020, it is “obsolete for Windows 2000 and later”. When this was first said of the function, the point will have been that continued use was anticipated for drivers that find themselves running on an earlier Windows. This would be unremarkable except that by late 2009 it becomes one of the few examples of Microsoft acknowledging a kernel export as being available before Windows 2000. It also presents the quirk that the opposite function, MmUnmapLockedPages, is only “Available starting with Windows 2000.”
Function | Documentation History | NtDLL History |
---|---|---|
NlsLeadByteInfo (data) | ||
NlsMbCodePageTag (data) | before 3.50, undocumented; since 6.1, indirectly documented as reserved |
3.50 and higher |
The indirect documentation of NlsMbCodePageTag is through the macro NLS_MB_CODE_PAGE_TAG which is presented as a “global variable”. The first documentation is in the WDK for Windows 7. Unusually for any kernel export, it is explicitly said to be “Available in all versions”. Less unusually, the macro is also said to be “reserved for system use.”
The functions whose names begin with Nt correspond closely to functions whose names have the Zw prefix instead (see below). Except for some general points about how the two differ—see The Native API—documentation of an Nt function is to a large extent implied by documentation of the corresponding Zw function.
Though this correspondence will have been understood well enough by all competent kernel-mode programmers, Microsoft didn’t make it explicit until some time after releasing the WDK for Windows Vista. This is here taken as an intention to leave the Nt functions undocumented (if not declared) before version 6.1.
Documentation in the WDK for Windows 7 gives each Nt function its own page, but this merely directs attention to the page for the corresponding Zw function. The Zw documentation might then be treated as counting for both, except that the Nt documentation warns expressly “Do not call this routine from kernel-mode code.” This is here taken as documenting the Nt functions as reserved in version 6.1 (certainly for kernel-mode use, which is this survey’s focus).
Microsoft loosened the text significantly for Windows 8 to note that the Nt and Zw versions “can behave differently” and to refer to a page of guidance. These changes, though slight, are taken here as formally permitting the Nt functions’ kernel-mode use, such that they must now be counted as documented (though delayed).
While each Nt function is documented only by reference to the Zw function, whatever documented availability Microsoft gives for the latter is here taken as intended also for the former. In the headers, however, the two functions necessarily each have their own declaration (if they have any), and so any “declared start” shown below is specifically for the Nt function.
Function | Documentation History | Declaration History | NTDLL History |
---|---|---|---|
NtAdjustPrivilegesToken | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all |
NtAllocateLocallyUniqueId | before 6.1, undocumented; before 6.2, reserved; documented start is 6.0 |
not declared | all |
NtAllocateVirtualMemory | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared; since 6.1 revision, documented start is 5.0; before 6.2, reserved |
since 6.0, declared start is 5.0 | all |
NtClose | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared; since 6.1 revision, documented start is 5.0; before 6.2, reserved |
since 6.0, declared start is 5.0 | all |
NtConnectPort | in 6.0 only, declared | declared start is 5.1 | all |
NtCreateEvent | before 6.1, undocumented; documented start is 5.1; before 6.2, reserved |
not declared | all |
NtCreateFile | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared; documented start is 5.0; before 6.2, reserved |
since 6.0, declared start is 5.0 | all |
NtCreateSection | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared; since 6.1 revision, documented start is 5.0; before 6.2, reserved |
since 6.0, declared start is 5.1 | all |
NtDeviceIoControlFile | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared; since 6.1 revision, documented start is 5.0; before 6.2, reserved |
since 6.0, declared start is 5.0 | all |
NtDuplicateObject | before 6.1, undocumented; before 6.2, reserved; documented start is 5.0 |
not declared | all |
NtDuplicateToken | before 5.0 (IFS), undocumented;
before 6.1, declared; documented start is 5.0; before 6.2, reserved |
since 6.0, declared start is 5.1 | all |
NtFreeVirtualMemory | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared; since 6.1 revision, documented start is 5.0; before 6.2, reserved |
since 6.0, declared start is 5.0 | all |
NtFsControlFile | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared; since 6.1 revision, documented start is 5.0; before 6.2, reserved |
since 6.0, declared start is 5.0 | all |
NtGlobalFlag (data) | |||
NtLockFile | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared; documented start is 6.1; before 6.2, reserved |
since 6.0, declared start is 5.0 | all |
NtMapViewOfSection | before 6.1, undocumented; since 6.1 revision, documented start is 5.0; before 6.2, reserved |
not declared | all |
NtNotifyChangeDirectoryFile | all | ||
NtOpenFile | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared; since 6.1 revision, documented start is 5.0; before 6.2, reserved |
since 6.0, declared start is 5.0 | all |
NtOpenProcessToken | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all |
NtQueryDirectoryFile | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared ; documented start is 5.1; before 6.2, reserved |
since 6.0, declared start is 5.0 | all |
NtQueryEaFile | all | ||
NtQueryInformationFile | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared; since 6.1 revision, documented start is 5.0; before 6.2, reserved |
since 6.0, declared start is 5.0 | all |
NtQueryInformationToken | before 5.0 (IFS), undocumented;
before 6.1, declared; documented start is 5.1; before 6.2, reserved |
since 6.0, declared start is 5.0 | all |
NtQuerySecurityObject | before 5.1 (IFS), undocumented;
before 6.1, declared; documented start is 5.1; before 6.2, reserved |
since 6.0, declared start is 5.0 | all |
NtQueryVolumeInformationFile | before 5.1 (IFS), undocumented;
before 6.1, declared; before 6.2, reserved; documented start is 5.1 |
since 6.0, declared start is 5.0 | all |
NtReadFile | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared; since 6.1 revision, documented start is 5.0; before 6.2, reserved |
since 6.0, declared start is 5.0 | all |
NtRequestPort | all | ||
NtRequestWaitReplyPort | in 6.0 only, declared | declared start is 5.1 | all |
NtSetEvent | before 6.1, undocumented; documented start is 5.1; before 6.2, reserved; |
not declared | all |
NtSetInformationFile | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared; since 6.1 revision, documented start is 5.0; before 6.2, reserved |
since 6.0, declared start is 5.0 | all |
NtSetInformationProcess | all | ||
NtSetInformationThread | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared; since 6.1 revision, documented start is 5.0; before 6.2, reserved |
since 6.0, declared start is 5.1 | all |
NtSetSecurityObject | before 5.1 (IFS), undocumented;
before 6.1, declared; documented start is 5.1; before 6.2, reserved; |
since 6.0, declared start is 5.0 | all |
NtUnlockFile | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared; documented start is 6.1; before 6.2, reserved; |
since 6.0, declared start is 5.0 | all |
NtVdmControl | all | ||
NtWaitForSingleObject | before 6.1, undocumented; documented start is 5.1; before 6.2, reserved; |
not declared | all |
NtWriteFile | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared; since 6.1 revision, documented start is 5.0; before 6.2, reserved |
since 6.0, declared start is 5.0 | all |
Though NtGlobalFlag is not formally documented, nor quite counts as indirectly documented, it is well known to kernel-mode programmers as the variable where the kernel keeps what Microsoft’s GFLAGS.EXE tool calls Kernel Flags. Microsoft’s early description of this tool (as for the Knowledge Base article Q206848, titled Windows NT Service Pack 4.0 Tools Not Included on CD-ROM but long gone from Microsoft’s website) was that it “edits the NtGlobalFlag settings for Windows in the registry.” Even before this, some programmers will have known that I386KD has a command-line switch -x that tells this debugger to execute an eb command to set this variable to 9.
The NtNotifyChangeDirectoryFile function is mentioned in comments in NTIFS.H starting from the IFS Kit for Windows 2000 and in WDM.H starting from the WDK for Windows Vista, but has never yet been declared. The story is only slightly different for NtQueryEaFile: it too is mentioned in a comment in NTIFS.H from the IFS Kit for Windows 2000, but the comment then moves to WDM.H.
More obscurely, NtRequestPort and NtRequestWaitReplyPort share a comment in the NTIFS.H from the WDK for Windows Vista, which is never repeated in later editions. The second of this pair is notable because this header also declares the function (and also NtConnectPort). It is here speculated, though with some confidence, that these declarations started as early as an IFS Kit for Windows XP. For however long they were published, they’re long gone now.
The NtSetInformationProcess function is mentioned in increasingly many comments in NTDDK.H, starting as long ago as the DDK for Windows NT 3.51, yet it too never has been declared.
Function | Documentation History | Declaration History |
---|---|---|
ObCreateObject | ||
ObDereferenceObject | since 6.1 revision, documented start is 5.0 | |
ObInsertObject | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, declared |
since 6.0, declared start is 5.0 |
ObOpenObjectByPointer | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
ObQueryNameString | before 5.0 (IFS), undocumented;
since 6.2, documented start is 5.0 |
since 6.0, declared start is 5.0 |
ObReferenceObjectByHandle | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
ObReferenceObjectByPointer | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
Who’s to know why, but documentation of ObReferenceObjectByHandle and ObReferenceObjectByPointer was marked as “preliminary documentation and subject to change” in the DDK for Windows XP (specifically).
Function | Documentation History | Declaration History |
---|---|---|
PfxFindPrefix | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
PfxInitialize | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
PfxInsertPrefix | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
PfxRemovePrefix | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
Function | Export History | Documentation History | Declaration History |
---|---|---|---|
ProbeForRead | discontinued in 3.50; restored in 5.0 |
before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 |
ProbeForWrite | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 |
Though the kernel does not export ProbeForRead in versions 3.50 to 4.0, the function can be identified in these versions as an internal routine—not just in the kernel but in Microsoft’s drivers that had imported it from the kernel in version 3.10. It seems to have been considered simple enough for definition as an inline routine (or even as a macro) in headers that Microsoft kept for its own programming. Perhaps only in version 5.0 did Microsoft care (or realise) that non-Microsoft programmers would better have easy access to a standard way to test the plausibility of inputs received from user mode. The early history of this function, which exists only for security, may thus be useful as a data point in assessing modern perceptions of security’s early neglect.
Function | Export History | Documentation History | Declaration History |
---|---|---|---|
PsChargePoolQuota | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | |
PsCreateSystemProcess | discontinued in 6.0 | ||
PsCreateSystemThread | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
PsInitialSystemProcess (data) | before 6.1, undocumented; before 6.1 revision, documented start is 4.0; documented start is 5.0 |
||
PsProcessType (data) | before 6.0, undocumented; indirectly documented |
||
PsReturnPoolQuota | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | |
PsTerminateSystemThread | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | |
PsThreadType (data) | before 5.0 (IFS), undocumented;
since 6.0, indirectly documented |
For the second edition of the WDK for Windows 7, numbered 7600.16385.1, the most extensive revision was that almost all of the kernel’s original exports became documented as being “Available in Windows 2000 and later versions of Windows.” From some perspective, stating this among the Requirements is even generous: the WDK for Windows 7 explicitly does not support development of drivers for execution on anything older than Windows XP, so why mention Windows 2000 at all? Still, the aim surely was to dismiss earlier versions as if they had never existed. For some measure of Microsoft’s determination in this tidying of history by wiping it out, consider PsInitialSystemProcess. When this original export was newly documented with its own page in the first edition, numbered 7600.16385.0, of the WDK for Windows 7, Microsoft took the liberty of starting the export’s availability at Microsoft Windows NT 4.0. This was not allowed to stand even for six months before needing “correction” to Windows 2000. Call me cynical, but Microsoft is rarely so swift even for true corrections.
Though PsProcessType and PsThreadType are not themselves documented, they get mentioned in the documentation of exported functions such as ObReferenceObjectByHandle from being intended as an argument. This starts with the WDK for Windows Vista.
Function | Export History | Documentation History |
---|---|---|
READ_REGISTER_BUFFER_UCHAR | x86 only | since 6.2, documented start is 5.0 |
READ_REGISTER_BUFFER_ULONG | x86 only | since 6.2, documented start is 5.0 |
READ_REGISTER_BUFFER_USHORT | x86 only | since 6.2, documented start is 5.0 |
READ_REGISTER_UCHAR | x86 only | since 6.2, documented start is 5.0 |
READ_REGISTER_ULONG | x86 only | since 6.2, documented start is 5.0 |
READ_REGISTER_USHORT | x86 only | since 6.2, documented start is 5.0 |
The READ_REGISTER functions have x64 support as inlined routines defined in WDM.H. Exported or not, they abstract the reading of I/O registers in memory space. The HAL exports counterparts that do the same but from I/O space. All have been documented from the start under some such heading as Hardware Abstraction Layer Routines which may be just separate enough that they were missed when a revision of the WDK for Windows 7 spuriously dated almost all the ancient documented functions to Windows 2000. If this was an oversight, it was soon put right, so to speak.
Function | Export History | Documentation History | Declaration History | NTDLL History |
---|---|---|---|---|
RtlAbsoluteToSelfRelativeSD | before 5.2 SP1 (IFS), undocumented;
documented start is 5.2 SP1 |
since 6.0, declared start is 5.2 SP1 | all | |
RtlAddAccessAllowedAce | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlAllocateHeap | before 5.1 (IFS), undocumented;
documented start is 5.1 |
since 6.0, declared start is 5.0 | all | |
RtlAnsiStringToUnicodeSize | since 6.1 revision, documented start is 5.0 | all | ||
RtlAnsiStringToUnicodeString | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlAppendAsciizToString | all | |||
RtlAppendStringToString | before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlAppendUnicodeStringToString | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlAppendUnicodeToString | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlAreBitsClear | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlAreBitsSet | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlAssert | before 5.1, declared | all | ||
RtlCharToInteger | before 3.51, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlCheckRegistryKey | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlClearAllBits | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlClearBits | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlCompareMemory | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlCompareMemoryUlong | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlCompareString | before 3.50 to 3.51, undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlCompareUnicodeString | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlConvertLongToLargeInteger | x86 only | since 6.1 revision, documented start is 5.0 | since 5.1, deprecated; since 6.0, deprecated (5.1) |
all |
RtlConvertSidToUnicodeString | before 6.1, undocumented; documented start is 5.0 |
declared start is 5.0 | all | |
RtlConvertUlongToLargeInteger | x86 only | since 6.1 revision, documented start is 5.0 | since 5.1, deprecated; since 6.0, deprecated (5.1) |
all |
RtlCopyLuid | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlCopySid | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlCopyString | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlCopyUnicodeString | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlCreateAcl | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlCreateHeap | before 5.1 (IFS), undocumented;
documented start is 5.1 |
since 6.0, declared start is 5.1 | all | |
RtlCreateRegistryKey | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlCreateSecurityDescriptor | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlCustomCPToUnicodeN | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 | all | |
RtlDelete | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlDeleteElementGenericTable | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlDeleteRegistryValue | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlDestroyHeap | before 5.1 (IFS), undocumented;
documented start is 5.1 |
since 6.0, declared start is 5.1 | all | |
RtlEnlargedIntegerMultiply | x86 only | before 3.50 to 3.51, documented | since 5.1, deprecated | all |
RtlEnlargedUnsignedDivide | x86 only | before 3.50 to 3.51, documented | since 5.1, deprecated | 3.10 to 6.1 |
RtlEnlargedUnsignedMultiply | x86 only | before 3.50 to 3.51, documented | since 5.1, deprecated | all |
RtlEnumerateGenericTable | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlEnumerateGenericTableWithoutSplaying | before 5.0 (IFS), undocumented;
since 6.2, documented start is 5.1 |
since 6.0, declared start is 5.0 | all | |
RtlEqualLuid | before 4.0, undocumented; before 5.0, declared; since 6.1 revision, documented start is 5.0 |
all | ||
RtlEqualSid | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlEqualString | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlEqualUnicodeString | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlExtendedIntegerMultiply | x86 only | before 3.50 to 3.51, documented | since 5.1, deprecated; since 6.0, declared start is 5.0 |
all |
RtlExtendedLargeIntegerDivide | x86 only | before 3.50 to 3.51, documented | since 5.1, deprecated; since 6.0, declared start is 5.0 |
all |
RtlExtendedMagicDivide | x86 only | before 3.50 to 3.51, documented | since 5.1, deprecated; since 6.0, declared start is 5.0 |
all |
RtlFillMemory | since 6.1 revision, documented start is 5.0 | all | ||
RtlFillMemoryUlong | x86 only | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.1 | all |
RtlFindClearBits | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlFindClearBitsAndSet | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlFindFirstRunClear | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | ||
RtlFindFirstRunSet | discontinued in 5.0 | in 5.0 (IFS), declared | ||
RtlFindLongestRunClear | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlFindLongestRunSet | discontinued in 5.0 | in 5.0 (IFS), declared | 3.10 to 4.0 | |
RtlFindSetBits | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlFindSetBitsAndClear | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlFindUnicodePrefix | before 5.0 (IFS), undocumented;
since 6.2, documented start is 5.1 |
since 6.0, declared start is 5.0 | ||
RtlFreeAnsiString | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlFreeHeap | before 5.1 (IFS), undocumented;
documented start is 5.1 |
since 6.0, declared start is 5.0 | all | |
RtlFreeOemString | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlFreeUnicodeString | since 6.1 revision, documented start is 5.0 | all | ||
RtlGenerate8dot3Name | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlGetCallersAddress | before 3.50 to 3.51, undocumented;
before 5.1, declared |
since 6.0, declared start is 5.0 | all | |
RtlGetDaclSecurityDescriptorriptor | before 5.2 SP1 (IFS), undocumented;
documented start is 5.2 SP1 |
since 6.0, declared start is 5.0 | all | |
RtlGetElementGenericTable | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlGetGroupSecurityDescriptor | before 5.2 SP1 (IFS), undocumented;
documented start is 5.2 SP1 |
since 6.0, declared start is 5.2 SP1 | all | |
RtlGetHeapUserValue | discontinued in 3.50 | 3.10 only | ||
RtlGetOwnerSecurityDescriptor | before 5.0 (IFS), undocumented;
since 6.0, documented start is 5.0 |
before 5.1 (IFS) to 6.0, not declared; since 6.0, declared start is 5.0 |
all | |
RtlInitAnsiString | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlInitCodePageTable | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 | all | |
RtlInitString | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlInitUnicodeString | since 6.1 revision, documented start is 5.0 | all | ||
RtlInitializeBitMap | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlInitializeGenericTable | before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlInitializeUnicodePrefix | before 5.0 (IFS), undocumented;
since 6.2, documented start is 5.1 |
since 6.0, declared start is 5.0 | ||
RtlInsertElementGenericTable | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlInsertUnicodePrefix | before 5.0 (IFS), undocumented;
since 6.2, documented start is 5.1 |
since 6.0, declared start is 5.0 | ||
RtlIntegerToUnicodeString | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlLargeIntegerAdd | x86 only | before 3.50 to 3.51, documented | since 5.1, deprecated | all |
RtlLargeIntegerArithmeticShift | x86 only | before 3.50 to 3.51, documented | since 5.1, deprecated; since 6.0, deprecated (5.1) |
all |
RtlLargeIntegerDivide | x86 only | before 3.50 to 3.51, documented | since 5.1, deprecated; since 6.0, declared start is 5.0 |
all |
RtlLargeIntegerNegate | x86 only | before 3.50 to 3.51, documented | since 5.1, deprecated | all |
RtlLargeIntegerShiftLeft | x86 only | before 3.50 to 3.51, documented | since 5.1, deprecated; since 6.0, deprecated (5.1) |
all |
RtlLargeIntegerShiftRight | x86 only | before 3.50 to 3.51, documented | since 5.1, deprecated; since 6.0, deprecated (5.1) |
all |
RtlLargeIntegerSubtract | x86 only | before 3.50 to 3.51, documented | since 5.1, deprecated | all |
RtlLengthRequiredSid | before 5.0 (IFS), undocumented;
since 5.1 (IFS) to 6.0, documented start is 5.0 |
before 5.1 (IFS) to 6.0, not declared; since 6.0, declared start is 5.0 |
all | |
RtlLengthSecurityDescriptor | before 3.50 to 3.51, undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlLengthSid | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlLookupElementGenericTable | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlMapGenericMask | before 4.0, undocumented; before 5.1, declared; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlMoveMemory | since 6.1 revision, documented start is 5.0 | all | ||
RtlNextUnicodePrefix | before 5.0 (IFS), undocumented;
since 6.2, documented start is 5.1 |
since 6.0, declared start is 5.0 | ||
RtlNtStatusToDosError | before 5.1 (IFS) to 6.0, undocumented;
before 6.1, reserved; since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlNtStatusToDosErrorNoTeb | before 5.1 (IFS) to 6.0, undocumented;
before 10.0, reserved; since 10.0, documented start is 5.0 |
since 6.0, declared start is 5.1 | 5.1 and higher | |
RtlNumberGenericTableElements | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlNumberOfClearBits | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlNumberOfSetBits | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlOemStringToCountedUnicodeString | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | ||
RtlOemStringToUnicodeSize | before 5.0 (IFS), undocumented | all | ||
RtlOemStringToUnicodeString | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlOemToUnicodeN | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlPrefixString | before 6.2, undocumented | all | ||
RtlPrefixUnicodeString | before 4.0, undocumented; before 5.0, declared; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlQueryRegistryValues | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlQueryTimeZoneInformation | all | |||
RtlRandom | before 5.0 (IFS), undocumented;
since 6.2, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlRemoveUnicodePrefix | before 5.0 (IFS), undocumented;
since 6.2, documented start is 5.1 |
since 6.0, declared start is 5.0 | ||
RtlSecondsSince1970ToTime | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlSecondsSince1980ToTime | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlSetAllBits | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlSetBits | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlSetDaclSecurityDescriptor | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlSetGroupSecurityDescriptor | before 5.2 SP1 (IFS), undocumented;
documented start is 5.2 SP1 |
since 6.0, declared start is 5.2 SP1 | all | |
RtlSetHeapUserValue | discontinued in 3.50 | 3.10 only | ||
RtlSetOwnerSecurityDescriptor | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlSetTimeZoneInformation | all | |||
RtlSplay | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlSubAuthorityCountSid | before 5.1 (IFS) to 6.0, undocumented | since 6.0, declared start is 5.1 | all | |
RtlSubAuthoritySid | before 5.0 (IFS), undocumented;
since 6.0, documented start is 5.0 |
before 5.1 (IFS) to 6.0, not declared; since 6.0, declared start is 5.0 |
all | |
RtlTimeFieldsToTime | before 3.50 to 3.51, undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlTimeToSecondsSince1970 | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlTimeToSecondsSince1980 | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlTimeToTimeFields | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlUnicodeStringToAnsiSize | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
all | ||
RtlUnicodeStringToAnsiString | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlUnicodeStringToCountedOemString | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlUnicodeStringToOemSize | before 5.0 (IFS), undocumented | all | ||
RtlUnicodeStringToOemString | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlUnicodeToCustomCPN | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 | all | |
RtlUnicodeToMultiByteN | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlUnicodeToOemN | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlUnwind | documented only in SDK | all | ||
RtlUpcaseUnicodeChar | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlUpcaseUnicodeString | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlUpcaseUnicodeStringToAnsiString | all | |||
RtlUpcaseUnicodeStringToCountedOemString | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlUpcaseUnicodeStringToOemString | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlUpcaseUnicodeToCustomCPN | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 | all | |
RtlUpcaseUnicodeToMultiByteN | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlUpcaseUnicodeToOemN | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlUpperChar | before 4.0, undocumented; before 5.0, declared; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlUpperString | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlValidSecurityDescriptor | before 3.50 to 3.51, undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all | |
RtlValidSid | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 | all | |
RtlWriteRegistryValue | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all | |
RtlZeroMemory | since 6.1 revision, documented start is 5.0 | all |
Some Rtl functions are supposed above to have been documented first in an IFS Kit for Windows XP or for Windows Server 2003 SP1 even though neither kit has been obtained for inspection. In each such case, the function’s documentation in the WDK for Windows Vista is in the IFS section and already gives the earlier version as the minimum. The inference is that although the minimum is entirely fictitious for when the function is first exported from the kernel, it is credibly correct about when the function was first documented for use by non-Microsoft programmers. Beware of a further inference: conditional-compilation blocks that the WDK for Windows Vista adds to the declarations are here dismissed as having been written independently of the documentation, else RtlCreateHeap and RtlDestroyHeap were documented as early as the Windows XP IFS Kit while RtlAllocateHeap and RtlFreeHeap were not.
Though RtlEqualLuid is exported from all known versions of the Windows kernel, no known edition of NTDDK.H and WDM.H declares it as a function: all define it by macro.
That RtlFindFirstRunSet and RtlFindLongestRunSet cease as exported functions in version 5.0 may have been a late decision: both are declared in the NTIFS.H from the Windows 2000 IFS Kit.
The RtlFreeHeap function is another rarity for having changed its prototype while documented. Its return type widens from BOOLEAN to LOGICAL in version 6.2. There are in practice no implications for compatibility in kernel mode (even allowing that any programmers ever do check this function for failure). The change was documented immediately. Conditional compilation ensures that new drivers that are built to run on an old Windows are for this purpose old drivers: they expect the smaller return type and are not troubled if run on a new Windows. The change appears instead to have been motivated by user-mode considerations, there having been a long-running off-and-on problem with matching the NTDLL implementation of RtlFreeHeap (returning an 8-bit BOOLEAN) to the Win32 HeapFree function (returning a 32-bit BOOL).
Another change of prototype affects RtlGenerate8dot3Name. Starting with version 6.0 SP1, it returns an NTSTATUS instead of returning nothing. Again, conditional compilation ensures that the new return type is known only to new drivers that are built to run only on new Windows. This change, however, was not documented immediately. Not until the WDK for Windows 8 does the documentation even show the new return type under the Syntax heading, but nothing in the Remarks alerts the reader to any change of functionality and the textual description of the “Return value” persists as “None”. This didn’t get addressed until some time after the first WDK for Windows 10.
Function | Documentation History | Declaration History |
---|---|---|
SeAccessCheck | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
SeAppendPrivileges | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
SeAssignSecurity | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
SeAuditingFileEvents | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
SeCaptureSubjectContext | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
SeCreateClientSecurity | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
SeDeassignSecurity | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
SeExports (data) | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared; indirectly documented |
|
SeFreePrivileges | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
SeImpersonateClient | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
SeLockSubjectContext | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
SeOpenObjectAuditAlarm | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
SePublicDefaultDacl (data) | ||
SeQueryAuthenticationIdToken | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
SeQuerySecurityDescriptorInfo | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
SeReleaseSubjectContext | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
SeSetSecurityDescriptorInfo | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
SeSinglePrivilegeCheck | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 |
SeSystemDefaultDacl (data) | ||
SeTokenType | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared |
since 6.0, declared start is 5.0 |
SeUnlockSubjectContext | before 5.0 (IFS), undocumented | since 6.0, declared start is 5.0 |
The SeExports variable has its own page of documention in the WDK for Windows Vista and again for Windows 7, yet is not itself documented explicitly. The documentation is instead of the SE_EXPORTS structure, which is what later kits use for the page’s title. In all kits, the variable is presented as a “large external static SE_EXPORTS structure”.
Function | Export History | Documentation History |
---|---|---|
WRITE_REGISTER_BUFFER_UCHAR | x86 only | since 6.2, documented start is 5.0 |
WRITE_REGISTER_BUFFER_ULONG | x86 only | since 6.2, documented start is 5.0 |
WRITE_REGISTER_BUFFER_USHORT | x86 only | since 6.2, documented start is 5.0 |
WRITE_REGISTER_UCHAR | x86 only | since 6.2, documented start is 5.0 |
WRITE_REGISTER_ULONG | x86 only | since 6.2, documented start is 5.0 |
WRITE_REGISTER_USHORT | x86 only | since 6.2, documented start is 5.0 |
As with the READ_REGISTER functions, the WRITE_REGISTER functions have x64 support as inlined routines and are unusual for having been overlooked, at first, when a revision of the WDK for Windows 7 misleadingly marked most of the ancient documented functions as requiring Windows 2000.
Function | Documentation History | Declaration History | NTDLL History |
---|---|---|---|
ZwAccessCheckAndAuditAlarm | all | ||
ZwAllocateVirtualMemory | before 5.0 (IFS), undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all |
ZwClose | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all |
ZwCloseObjectAuditAlarm | all | ||
ZwCreateDirectoryObject | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all |
ZwCreateFile | before 3.50 to 3.51, undocumented;
since 6.1, documented start is 5.0 |
since 6.0, declared start is 5.0 | all |
ZwCreateKey | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all |
ZwCreateSection | before 5.0 (IFS), undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all |
ZwCreateSymbolicLinkObject | all | ||
ZwDeleteKey | before 3.50 to 3.51, undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all |
ZwDeleteValueKey | before 5.1, undocumented; before 6.1, documented start is 5.1; documented start is 5.0 |
since 6.0, declared start is 5.0 | all |
ZwDeviceIoControlFile | before 5.0 (IFS), undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all |
ZwDisplayString | before 6.1, undocumented | declared start is 5.0 | all |
ZwDuplicateObject | before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared; before 6.2, reserved; since 6.2, documented start is 5.0 |
since 6.0, declared start is 5.0 | all |
ZwEnumerateKey | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all |
ZwEnumerateValueKey | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all |
ZwFlushKey | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all |
ZwFreeVirtualMemory | before 5.0 (IFS), undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all |
ZwLoadDriver | before 5.1 (IFS), undocumented;
documented start is 5.1 |
since 6.0, declared start is 5.0 | all |
ZwMakeTemporaryObject | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all |
ZwMapViewOfSection | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all |
ZwOpenDirectoryObject | before 5.1 (IFS), undocumented;
documented start is 5.1 |
since 6.0, declared start is 5.0 | all |
ZwOpenFile | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all |
ZwOpenKey | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all |
ZwOpenProcessToken | all | ||
ZwOpenSection | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all |
ZwOpenSymbolicLinkObject | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all |
ZwOpenThreadToken | all | ||
ZwQueryInformationFile | before 3.50 to 3.51, undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all |
ZwQueryInformationToken | before 5.1 (IFS), undocumented;
documented start is 5.1 |
since 6.0, declared start is 5.0 | all |
ZwQueryKey | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all |
ZwQuerySymbolicLinkObject | before 5.0, undocumented; since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all |
ZwQueryValueKey | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all |
ZwQueryVolumeInformationFile | before 5.1 (IFS) to 6.0, undocumented;
since 6.2, documented start is 5.1 |
since 6.0, declared start is 5.0 | all |
ZwReadFile | before 3.50 to 3.51, undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all |
ZwSetInformationProcess | all | ||
ZwSetValueKey | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all |
ZwUnmapViewOfSection | since 6.1 revision, documented start is 5.0 | since 6.0, declared start is 5.0 | all |
ZwWriteFile | before 3.50 to 3.51, undocumented;
since 6.1 revision, documented start is 5.0 |
since 6.0, declared start is 5.0 | all |
The documentation history of ZwDeleteValueKey is complicated by documentation in parallel. No documentation or declaration is known from any DDK before Windows XP. In the WDK for Windows Vista, however, it has two pages: one under Installable File System; the other in the general section for Driver Support Routines. Presumably, it had been documented in an IFS Kit before the merger into the WDK for Windows Vista. The IFS documentation starts the function’s availability at Windows XP. Without a Windows XP IFS Kit for reference, it can’t be discounted as the first documentation. The less developed documentation in the general section appears first in the DDK for Windows Server 2003 SP1 and says nothing about availability. The WDK for Windows 7 drops it in favour of the IFS documentation, but with the function’s availability changed to Windows 2000 and later.
Function | Export History | Documentation History | Declaration History |
---|---|---|---|
_except_handler2 | x86 only | ||
_itoa | |||
_local_unwind2 | x86 only | before 2012, undocumented | not declared |
_stricmp | |||
_strnicmp | |||
_vsnprintf | |||
_wcsnicmp | |||
sprintf | |||
strncpy | |||
strstr | |||
wcschr | |||
wcscpy | |||
wcscspn | |||
wcslen | |||
wcsstr |
References to the _except_handler2 function are generated by sufficiently early versions of Microsoft’s compilers for the prologue code of C and C++ functions that use Structured Exception Handling (SEH). The function is not known ever to have been documented, not just as an export from the kernel but even as an implementation detail of Microsoft’s compilers. That said, it is named on a page of Internal CRT Globals and Functions, which looks to have been prepared for Visual Studio 2015.
The _local_unwind2 function is similarly old as a compiler-generated name but has survived longer. Calls to it are generated by Microsoft’s compilers when C and C++ functions leave a __finally block non-trivially. As the earliest documentation that I have yet found, the function got a page to itself in the Alphabetical Function Reference within the C Run-Time Library Reference for Visual Studio 2012. Then and still (but now among the Internal CRT Globals and Functions), programmers are warned “Do not call the method in your code”, which is here taken as reason to count the function as reserved.