HAL Version 3.10 Exports

The table below lists the 69 exports from the HAL in version 3.10. These functions (and one variable) are in effect the original programming interface for the HAL. They represent nearly three quarters of all HAL exports that have ever existed. All but a handful are still exported as of version 10.0. Just over a half of these original exports are documented, though mostly as obsolete or reserved.

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.

Function Export History Documentation History Declaration History
HalAcquireDisplayOwnership x64 since 2004, forwarded to kernel before 6.0, declared since 5.2, deprecated
since 6.0, declared start is 5.0
HalAllocateAdapterChannel x64 since 2004, forwarded to kernel before 3.50 to 3.51, undocumented
before 6.0, declared
since 5.2, deprecated
since 6.0, declared start is 5.0
HalAllocateCommonBuffer x64 since 2004, forwarded to kernel before 5.0, documented since 5.1, deprecated
since 6.0, declared start is 5.0
HalBeginSystemInterrupt x86 only    
HalCalibratePerformanceCounter x64 since 2004, forwarded to kernel    
HalDisableSystemInterrupt discontinued in 6.0    
HalDisplayString x64 since 2004, forwarded to kernel    
HalEnableSystemInterrupt discontinued in 6.0    
HalEndSystemInterrupt x86 only    
HalFlushCommonBuffer x64 since 2004, forwarded to kernel    
HalFreeCommonBuffer x64 since 2004, forwarded to kernel before 5.0, documented since 5.1, deprecated
since 6.0, declared start is 5.0
HalGetAdapter x64 since 2004, forwarded to kernel before 5.0, documented since 5.1, deprecated
since 6.0, declared start is 5.0
HalGetBusData x64 since 2004, forwarded to kernel before 5.0, documented since 5.1, deprecated
since 6.0, declared start is 5.0
HalGetEnvironmentVariable x64 since 2004, forwarded to kernel    
HalGetInterruptVector x64 since 2004, forwarded to kernel before 5.0, documented since 5.1, deprecated
since 6.0, declared start is 5.0
HalHandleNMI x64 since 2004, forwarded to kernel    
HalInitSystem x64 since 2004, forwarded to kernel    
HalInitializeProcessor x64 since 2004, forwarded to kernel    
HalMakeBeep x64 since 2004, forwarded to kernel before 5.0, undocumented
before 6.0, declared
since 5.2, deprecated
since 6.0, declared start is 5.0
HalQueryDisplayParameters x64 since 2004, forwarded to kernel    
HalQueryRealTimeClock x64 since 2004, forwarded to kernel    
HalReadDmaCounter x64 since 2004, forwarded to kernel before 5.0, documented since 5.1, deprecated
since 6.0, declared start is 5.0
HalReportResourceUsage x64 since 2004, forwarded to kernel    
HalRequestIpi x64 since 2004, forwarded to kernel    
HalRequestSoftwareInterrupt x64 since 2004, forwarded to kernel    
HalReturnToFirmware x64 since 2004, forwarded to kernel before 6.1, undocumented
before 6.2, documented start is 5.1
since 6.2, documented start is 5.2
not declared, except in “minwin”
HalSetDisplayParameters x64 since 2004, forwarded to kernel    
HalSetEnvironmentVariable x64 since 2004, forwarded to kernel    
HalSetProfileInterval x64 since 2004, forwarded to kernel    
HalSetRealTimeClock x64 since 2004, forwarded to kernel    
HalStartNextProcessor x64 since 2004, forwarded to kernel    
HalStartProfileInterrupt x64 since 2004, forwarded to kernel    
HalStopProfileInterrupt x64 since 2004, forwarded to kernel    
HalTranslateBusAddress x64 since 2004, forwarded to kernel before 5.0, documented since 5.1, deprecated
since 6.0, declared start is 5.0

The particularities of how the few Hal functions that have ever been documented (and some of the Io functions too) became obsolete or reserved are a separate story. Here it must suffice to note that starting with the DDK for Windows 2000 most of these functions are replaced by inline definitions, and some are not declared at all, depending on macros USE_DMA_MACROS and NO_LEGACY_DRIVERS.

The whole documentation of most functions that are shown above as reserved is just that the name is in a list, but HalReturnToFirmware has its own page with a prototype and rudimentary description. Indeed, it’s not explicitly reserved, but is instead said to be “not supported and should not be used.” While splitting hairs, note that its documentation in the WDK for Windows 7 says the function is “Available in Microsoft Windows Server 2003 and Windows XP.” Whether this is meant to exclude the function’s continuation to Windows Vista and beyond is not known. The WDK for Windows 8 explicitly allows later versions, but somehow for the price that the function is no longer available on Windows XP.

Function Export History Documentation History Declaration History
IoAssignDriveLetters discontinued in 6.1
   
IoFlushAdapterBuffers x64 since 2004, forwarded to kernel before 5.0, documented since 5.1, deprecated
since 6.0, declared start is 5.0
IoFreeAdapterChannel x64 since 2004, forwarded to kernel before 5.0, documented since 5.1, deprecated
since 6.0, declared start is 5.0
IoFreeMapRegisters x64 since 2004, forwarded to kernel before 5.0, documented since 5.1, deprecated
since 6.0, declared start is 5.0
IoMapTransfer x64 since 2004, forwarded to kernel before 5.0, documented since 5.1, deprecated
since 6.0, declared start is 5.0
IoReadPartitionTable x64 since 2004, forwarded to kernel before 5.1, documented since 5.1, deprecated
since 6.0, declared start is 5.1
IoSetPartitionInformation x64 since 2004, forwarded to kernel before 5.1, documented since 5.1, deprecated
since 6.0, declared start is 5.1
IoWritePartitionTable x64 since 2004, forwarded to kernel before 5.1, documented since 5.1, deprecated
since 6.0, declared start is 5.1

Starting with version 5.1, IoAssignDriveLetters (only to version 6.0), IoReadPartitionTable, IoSetPartitionInformation and IoWritePartitionTable are also exported from the kernel. The HAL’s implementations are just stubs that call the corresponding but substantial implementations in the kernel. Stubs, in contrast to forwards, are needed for the x86 architecture because the HAL and kernel functions have different calling conventions: __stdcall and __fastcall, respectively. Though this need does not apply to the x64 architecture, no special case was made for forwarding the x64 functions until Version 2004 has the x64 HAL forward all its exports to the kernel.

Function Export History
KdComPortInUse (data) x64 since 2004, forwarded to kernel
KdPortGetByte discontinued in 5.1
KdPortInitialize discontinued in 5.1
KdPortPollByte discontinued in 5.1
KdPortPutByte discontinued in 5.1
KdPortRestore discontinued in 5.1
KdPortSave discontinued in 5.1

The HAL’s role in debugging the kernel through a serial port ceased when Windows XP allowed IEEE1394 as a significantly faster alternative. The work was separated to a replacable module whose internal name is KDCOM.DLL even if a different filename is chosen by the loader from a boot option. The kernel imports functions from this module instead of from the HAL. The HAL functions that earlier kernels had called, and which ought never to have been called except from the kernel, were dropped. The exported variable, however, presented a compatibility problem. Though KdComPortInUse never was formally documented, nor declared in any DDK header, Microsoft had long published sample code that shows the variable’s use—indeed, its all-but-necessary use—by serial drivers such as might be written by arbitrary non-Microsoft programmers. Its exporting has needed to continue.

Function Export History Documentation History Declaration History
KeAcquireSpinLock x86 only;
since 6.2, forwarded to kernel
since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
KeFlushWriteBuffer x64 since 2004, forwarded to kernel before 5.1, declared  
KeGetCurrentIrql x86 only since 6.1 revision, documented start is 5.0  
KeLowerIrql x86 only since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
KeQueryPerformanceCounter x64 since 2004, forwarded to kernel since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
KeRaiseIrql x86 only since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
KeReleaseSpinLock x86 only;
since 6.2, forwarded to kernel
since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0
KeStallExecutionProcessor x64 since 2004, forwarded to kernel since 6.1 revision, documented start is 5.0 since 6.0, declared start is 5.0

Though the Interrupt Request Level (IRQL) is fundamental to kernel-mode programming, it is originally the business of the HAL, not the kernel. Functions that raise, lower or get the IRQL started as HAL exports and remain so for the x86. The x64 processor, however, has built-in support for the IRQL through the cr8 register. The x64 functions that work with the IRQL have only ever been exported from the kernel, not the HAL.

Whether the IRQL is controlled by the HAL or the kernel affects a division of functionality for the spin lock. Acquiring and releasing a spin lock can have two parts to it: the synchronisation itself, necessarily, and a change of IRQL, possibly. On the x64, both are the kernel’s work, which means again that x64 functions for spin locks have only ever been exported from the kernel, not the HAL. The x86 division of labour is that the kernel handles the synchronisation itself but leaves the changes of IRQL to the HAL. The original division of functionality is that the generality is with the HAL. The KeAcquireSpinLock and KeReleaseSpinLock functions may change the IRQL and are exported from the HAL, which calls the kernel to handle the synchronisation. Windows 8 changes this division so the generality is with the kernel. All functions that work with these synchronisation objects are exported from the kernel, which calls the HAL for changing the IRQL. The HAL’s exports for the general work remain, but not as implemented functions: they continue only as forwards to the kernel.

Not since ancient times do x86 drivers import the Ke functions that raise or lower the Interrupt Request Level (IRQL) whether directly or while acquiring or releasing a spin lock. These are well known to be redirected by macros to the Kf variants, plausibly as early as the DDK for Windows NT 3.50 (which is not yet obtained for reference). The macros depend on their targets’ declarations, of course.

Function Export History Documentation History
READ_PORT_BUFFER_UCHAR x86 only since 6.2, documented start is 5.0
READ_PORT_BUFFER_ULONG x86 only since 6.2, documented start is 5.0
READ_PORT_BUFFER_USHORT x86 only since 6.2, documented start is 5.0
READ_PORT_UCHAR x86 only since 6.2, documented start is 5.0
READ_PORT_ULONG x86 only since 6.2, documented start is 5.0
READ_PORT_USHORT x86 only since 6.2, documented start is 5.0
WRITE_PORT_BUFFER_UCHAR x86 only since 6.2, documented start is 5.0
WRITE_PORT_BUFFER_ULONG x86 only since 6.2, documented start is 5.0
WRITE_PORT_BUFFER_USHORT x86 only since 6.2, documented start is 5.0
WRITE_PORT_UCHAR x86 only since 6.2, documented start is 5.0
WRITE_PORT_ULONG x86 only since 6.2, documented start is 5.0
WRITE_PORT_USHORT x86 only since 6.2, documented start is 5.0

The READ_PORT and WRITE_PORT functions have x64 support as inlined routines defined in WDM.H. Exported or not, they abstract the reading of I/O registers in I/O space. The kernel exports counterparts that do the same but from memory 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 to Windows 2000 all the other ancient documented (but not yet obsolete) functions. Of course this was “fixed” in the very next WDK.