Kernel Exports Added For Version 3.50

This page lists the 146 functions and variables that are newly exported from the Windows kernel in version 3.50. It is here thought that no service packs of version 3.50 added to these exports, but beware that only SP3 has yet been obtained for inspection.

Conventions

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 first appearance in the Functions column.

Colours

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. To show them as being not completely undocumented they are shaded orange, except for one special case. Some declarations are known only from “minwin” headers that Microsoft published in early editions of the WDK for Windows 10 which seem since to have been withdrawn. These are highlighted orange to indicate that public disclosure even of the declaration was exceptional.

Actual Availability

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”.

Documented Availability

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!

Incompleteness

While no DDK for Windows NT 3.50 is found for reference, the default assumption throughout the following table is that whatever is known about a function’s documentation or declarations from the DDK for Windows NT 3.51 can’t be said to have differed for version 3.50.

Many functions in these early versions may have got their first documentation or declaration because their use was specially anticipated for installable file system (IFS) drivers. Microsoft published a separate IFS Kit for these, apparently starting from Windows 2000. For Windows Vista, the IFS Kit was merged into the WDK. Between, there are known to have been 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 and is excluded from the IFS Kit for Windows 2000 and from the ordinary DDK for all of Windows 2000, Windows XP and Windows Server 2003.

Tabulation

As much as I might like to condense into one table as much as might be imagined is possible to summarise about all these functions’ 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.

Cc Function

Function Export History
CcGetLsnForFileObject  

Ex Functions

Function Export History Documentation History Declaration History
ExAcquireFastMutexUnsafe   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ExAcquireResourceExclusiveLite   since 6.1, documented start is 5.0 since 6.0, declared start is 5.0
ExAcquireResourceSharedLite   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ExAcquireSharedWaitForExclusive   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ExAllocatePoolWithQuotaTag   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ExAllocatePoolWithTag   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ExConvertExclusiveToSharedLite   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ExDeleteResourceLite   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ExDisableResourceBoostLite   before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared
since 6.0, declared start is 5.0
ExGetExclusiveWaiterCount   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ExGetSharedWaiterCount   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ExInitializeResourceLite   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ExInterlockedAddLargeStatistic x86 only before 5.0, declared;
since 6.1 revision, documented start is 5.0
 
ExInterlockedExtendZone   before 5.0, documented since 5.1, deprecated;
since 6.0, declared start is 5.0
ExIsResourceAcquiredExclusiveLite   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ExIsResourceAcquiredSharedLite   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ExReleaseFastMutexUnsafe   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ExReleaseResourceForThreadLite   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ExReleaseResourceLite   before 5.0, declared;
since 6.1 revision, documented start is 5.0
since 6.0, declared start is 5.0
ExfInterlockedAddUlong x86 only    
ExfInterlockedInsertHeadList x86 only    
ExfInterlockedInsertTailList x86 only    
ExfInterlockedPopEntryList x86 only before 6.1, declared  
ExfInterlockedPushEntryList x86 only before 6.1, declared  
ExfInterlockedRemoveHeadList x86 only    
Exfi386InterlockedDecrementLong x86 only in 6.0 only, reserved  
Exfi386InterlockedExchangeUlong x86 only in 6.0 only, reserved  
Exfi386InterlockedIncrementLong x86 only in 6.0 only, reserved  

The ExIsResourceAcquiredSharedLite function is another rarity that changes its prototype while documented. If changes from returning a USHORT to returning a ULONG in version 5.0, but the documentation doesn’t catch up until version 6.0.

FsRtl Functions

Function Documentation History Declaration History
FsRtlAllocatePoolWithQuotaTag before 5.0 (IFS), undocumented  
FsRtlAllocatePoolWithTag before 5.0 (IFS), undocumented  
FsRtlNotifyFullChangeDirectory before 5.0 (IFS), undocumented since 6.0, declared start is 5.0
FsRtlNotifyFullReportChange before 5.0 (IFS), undocumented since 6.0, declared start is 5.0
FsRtlNotifyInitializeSync before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0
since 6.0, declared start is 5.0
FsRtlNotifyUninitializeSync before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0
since 6.0, declared start is 5.0
FsRtlSplitLargeMcb before 5.0 (IFS), undocumented since 6.0, declared start is 5.0
FsRtlTruncateLargeMcb before 5.0 (IFS), undocumented since 6.0, declared start is 5.0
FsRtlTruncateMcb before 5.0 (IFS), undocumented since 6.0, declared start is 5.0

Io Functions

Function Documentation History Declaration History
IoAssignResources before 5.0, documented since 5.1, deprecated;
since 6.0, declared start is 5.0
IoEnqueueIrp    
IoGetDeviceToVerify since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
IoGetFileObjectGenericMapping since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
IoGetInitialStack since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
IoGetRequestorProcess before 5.0 (IFS), undocumented since 6.0, declared start is 5.0
IoGetTopLevelIrp before 5.0 (IFS), undocumented since 6.0, declared start is 5.0
IoIsSystemThread before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared
since 6.0, declared start is 5.0
IoPageRead before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared
since 6.0, declared start is 5.0
IoSetDeviceToVerify before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared
since 6.0, declared start is 5.0
IoSetTopLevelIrp before 5.0 (IFS), undocumented since 6.0, declared start is 5.0
IoSynchronousPageWrite before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared
since 6.0, declared start is 5.0
IoThreadToProcess before 5.0 (IFS), undocumented since 6.0, declared start is 5.0
IofCallDriver   since 6.0, declared start is 5.0
IofCompleteRequest   since 6.0, declared start is 5.0

Ke Functions and Variables

Function Export History Documentation History Declaration History
KeClearEvent   since 6.1 revision, documented start is 5.0  
KeDeregisterBugCheckCallback   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
KeEnterCriticalRegion   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
KeFindConfigurationNextEntry      
KeInitializeQueue   before 5.0 (IFS), undocumented since 6.0, declared start is 5.0
KeInsertQueue   before 5.0 (IFS), undocumented since 6.0, declared start is 5.0
KeLoaderBlock (data)      
KeReadStateMutant   before 5.1 (IFS) to 6.0, undocumented since 6.0, declared start is 5.0
KeReadStateQueue   before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared
since 6.0, declared start is 5.0
KeRegisterBugCheckCallback   since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
KeRemoveQueue   before 5.0 (IFS), undocumented since 6.0, declared start is 5.0
KeSetEventBoostPriority      
KeTickCount (data) x86 only    
KefAcquireSpinLockAtDpcLevel x86 only   since 6.0, declared start is 5.0
KefReleaseSpinLockFromDpcLevel x86 only before 2018, declared;
since 6.1 revision, documented start is 5.0
since 6.0, declared start is 5.0

Documentation of KeDeregisterBugCheckCallback and KeRegisterBugCheckCallback is marked “This is preliminary documentation and subject to change” in the DDK for Windows XP.

Though KeEnterCriticalRegion and KeLeaveCriticalRegion plainly are a pair, the one needing always to be balanced by the other, one preceded the other as an exported function. It is here thought that KeEnterCriticalRegion existed in version 3.10 only as the same macro that Microsoft published in NTDDK.H for versions 3.51 up to and including 5.1 (presumably by oversight since it cannot compile without a definition of the KernelApcDisable member of the opaque KTHREAD).

What documentation I see online today, 17th September 2020, for KefReleaseSpinLockFromDpcLevel is dated 30th April 2018 as is most other online documentation since Microsoft’s reorganisation of it in terms of which headers declare which functions. Who knows when this documentation was written but its publication plausibly is just a side-effect of the reorganisation. What little is presented as Remarks is just for the long-documented KeReleaseSpinLockFromDpcLevel and the page has no partner for KefAcquireSpinLockAtDpcLevel. Still, documented it is.

Mm Functions

Function Documentation History Declaration History
MmCanFileBeTruncated before 5.0 (IFS), undocumented since 6.0, declared start is 5.0
MmDisableModifiedWriteOfSection    
MmIsRecursiveIoFault before 5.0 (IFS), undocumented since 6.0, declared start is 5.0
MmIsThisAnNtAsSystem before 5.2 SP1, documented since 6.0, declared start is 5.0
MmLockPagableImageSection    
MmMapMemoryDumpMdl    
MmUnlockPagableImageSection since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0

Documentation of MmIsThisAnNtAsSystem as obsolete is qualified: even now in 2020 it is “obsolete for Windows XP and later versions”.

Nls Variables

Function Documentation History
NlsMbOemCodePageTag (data)  
NlsOemLeadByteInfo (data) before 5.0 (IFS), undocumented

Both NlsMbOemCodePageTag and NlsOemLeadByteInfo are declared through macros—NLS_MB_OEM_CODE_PAGE_TAG and NLS_OEM_LEAD_BYTE_INFO, respectively—but neither is known to have ever been documented.

Nt Functions

The functions whose names begin with Nt correspond closely to functions whose names have the Zw prefix instead (see below). Put aside some general points about how the two differ—see The Native API— and 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 and 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
NtDeleteFile before 6.1, undocumented;
documented start is 5.1;
before 6.2, reserved
not declared
NtOpenProcess before 6.1, declared;
since 6.1 revision, documented start is 5.0;
before 6.2, reserved
 
NtQueryInformationProcess    

Ob Functions

Function Export History Documentation History Declaration History
ObGetObjectPointerCount discontinued in 5.1 before 5.0 (IFS), undocumented  
ObMakeTemporaryObject   before 5.0 (IFS), undocumented;
before 5.1 (IFS) to 6.0, declared
since 6.0, declared start is 5.0
ObfDereferenceObject     since 6.0, declared start is 5.0

Ps Functions

Function Documentation History Declaration History
PsGetProcessExitTime before 5.0 (IFS), undocumented since 6.0, declared start is 5.0
PsIsThreadTerminating before 5.0 (IFS), undocumented;
since 6.1, documented start is 5.0
since 6.0, declared start is 5.0
PsLookupProcessThreadByCid    
PsSetCreateProcessNotifyRoutine 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

Rtl Functions

Function Documentation History Declaration History
RtlCompressBuffer before 5.1 (IFS) to 6.0, undocumented;
before 6.1, reserved;
since 6.1, documented start is 5.1
since 6.0, declared start is 5.1
RtlDecompressBuffer before 5.1 (IFS) to 6.0, undocumented;
before 6.1, reserved;
since 6.1, documented start is 5.1
since 6.0, declared start is 5.1
RtlDecompressFragment before 5.1 (IFS) to 6.0, undocumented;
before 6.1, reserved;
since 6.1, documented start is 5.1
since 6.0, declared start is 5.1
RtlDowncaseUnicodeString before 5.0 (IFS), undocumented since 6.0, declared start is 5.0
RtlGetCompressionWorkSpaceSize before 5.1 (IFS), undocumented;
before 6.1, reserved;
since 6.1, documented start is 5.1
since 6.0, declared start is 5.1
RtlxAnsiStringToUnicodeSize before 6.0, declared;
since 6.1 revision, documented start is 5.0
since 6.0, declared start is 5.0
RtlxOemStringToUnicodeSize before 5.0 (IFS), undocumented;
before 6.1, declared
since 6.0, declared start is 5.0
RtlxUnicodeStringToAnsiSize before 5.0, undocumented;
since 6.1 revision, documented start is 5.0
since 6.0, declared start is 5.0
RtlxUnicodeStringToOemSize before 5.0 (IFS), undocumented;
before 6.1, declared
since 6.0, declared start is 5.0

Se Function

Function Documentation History Declaration History
SeValidSecurityDescriptor before 5.0, declared;
since 6.1 revision, documented start is 5.0
since 6.0, declared start is 5.0

Zw Functions

Function Documentation History Declaration History
ZwConnectPort in 5.1 (IFS) to 6.0, declared in 6.0, declared start is 6.0
ZwCreateEvent before 5.0 (IFS), undocumented;
before 5.1 (IFS), declared;
documented start is 5.1
since 6.0, declared start is 5.0
ZwDeleteFile before 5.1 (IFS), undocumented;
documented start is 5.1
since 6.0, declared start is 5.0
ZwFlushInstructionCache    
ZwFsControlFile before 5.1 (IFS) to 6.0, undocumented;
since 6.1 revision, documented start is 5.0
since 6.0, declared start is 5.0
ZwOpenEvent before 6.0, undocumented;
documented start is 5.2
since 6.0, declared start is 5.2
ZwQueryDirectoryFile before 5.0 (IFS), undocumented;
since 5.1 (IFS), documented start is 5.1
before 5.1 (IFS), not declared;
since 6.0, declared start is 5.0
ZwQuerySection    
ZwRequestWaitReplyPort in 5.1 (IFS) to 6.0, declared in 6.0, declared start is 5.0
ZwSetEvent before 5.0 (IFS), undocumented;
before 5.1 (IFS), declared;
documented start is 5.1
since 6.0, declared start is 5.0
ZwSetInformationFile since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ZwSetInformationThread since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
ZwWaitForSingleObject before 5.0 (IFS), undocumented;
before 5.1 (IFS), declared;
documented start is 5.1
since 6.0, declared start is 5.0

Though ZwQueryDirectoryFile is documented in the Windows 2000 IFS Kit, it comes with a warning in red that “This is preliminary documentation and subject to change” and the NTIFS.H from the same kit does not declare the function. Presumably, the documentation was settled in time for the Windows XP IFS Kit and Microsoft has ever since meant that Windows XP is when the function became documented for use. A declaration was perhaps also settled on as early as the Windows XP IFS Kit. Certainly, a declaration is presented in the WDK for Windoiws Vista, but with a conditional-compilation block that doesn’t agree with the documentation.

C Run-Time (CRT) Functions

Function Export History Documentation History Declaration History
_abnormal_termination x86 only before 2012, declared  
_global_unwind2 x86 only    
_purecall   before 2012, undocumented not declared
_snprintf      
_snwprintf      
_strlwr      
_strupr      
_wcsicmp      
atoi      
atol      
isdigit      
islower      
isprint      
isspace      
isupper      
isxdigit      
mbstowcs      
memchr      
memcpy      
memmove      
memset      
qsort      
rand      
srand      
strchr      
strncmp      
strrchr      
swprintf      
tolower      
toupper      
vsprintf      
wcscat      
wcscmp      
wcsncmp      
wcsncpy      
wcsrchr      

Visual Studio documentation has long documented the _abnormal_termination function indirectly as AbnormalTermination. Whether this is presented as a macro or is said to be an “intrinsic function”, it is documented for use in the __finally block of a termination handler. Documentation for Visual Studio 2012 gives the function its own page but is clear that it “is not intended to be called from user code.” This is here taken as reason to count the function (not the macro) as reserved.

The _global_unwind2 function has long been an internal routine for the CRT library’s implementation of several functions: _except_handler2 (already exported from the version 3.10 kernel); its successors (of which _except_handler3 is an x86-only export for version 5.0 and higher); and the documented CRT function longjmp (which is not a kernel export for any x86 build of any version). The version 3.10 kernel has it but does not export it. Why it ever got exported in kernel mode is not known. It anyway is not known ever to have been documented, not only as an export from the kernel but even as an implementation detail of Microsoft’s CRT library. That said, it is named on a page of Internal CRT Globals and Functions, which seems to have been prepared for Visual Studio 2015.

Microsoft’s C++ compiler generates references to the _purecall function when a virtual function table is emitted for a base class that has any pure virtual member function. The first explicit documentation that I know of is that the function has its own page in the Alphabetical Function Reference within the C Run-Time Library Reference for Visual Studio 2012.

Discontinued

If only for cross-referencing, note that a dozen of the kernel’s original exports do not survive to version 3.50:

None had yet been documented. Four were sooner (version 3.50) or later (5.0) documented as obsolete, one as reserved. For who knows what reason, this pruning temporarily removed ProbeForRead—but not its close companion, ProbeForWrite—from use by external callers such as drivers who surely would have valued it for validating parameters received from user-mode callers. It doesn’t return to the interface until version 5.0, but at least then it got documented.