HAL_DISPATCH

The HAL_DISPATCH structure is a table of pointers to optional HAL functionality. The kernel keeps the one instance of this table. It’s in the kernel’s read-write data section and its address is exported as HalDispatchTable. The table initially has the kernel’s built-in implementations of most (but not all) functions. Many are trivial. Some are substantial. The HAL overrides some. No known HAL overrides all. Functionality that has no meaning to a particular HAL is left to the kernel’s default (and HAL programmers are spared from writing even dummy code for nothing that matters to them). Moreover, since the address is exported, rather than communicated specifically to the HAL, it seems to have been intended all along that the functionality is exposed to other kernel-mode modules such as drivers not only for them to call but also to override further.

Documentation Status and Variability

Neither the HAL_DISPATCH nor the HalDispatchTable are formally documented, but they have always been semi-documented: a C-language definition appears in every NTDDK.H even from as far back as the Device Driver Kit (DDK) for Windows NT 3.51. In each DDK or Windows Driver Kit (WDK), the definition is true for the Windows version that the kit is released for, but with no explicit indication that the definition might not be correct for other versions. This would be unremarkable if the history were just of extending the structure and incrementing the Version member at the very beginning. Instead, members have been added, or their types changed, without increasing the Version. One change of Version removes a member, thus shifting all subsequent ones. That said, since then, meaning Windows 7, the structure has not changed up to and including Windows 10, and may now be stable.

Microsoft’s C-language definitions don’t list what to expect as the Version member for each Windows version or what to expect in the structure for any given Version. The following table shows what correspondence is known from inspection:

Version Windows Versions Size (x86) Size (x64)
1 3.51 0x28  
4.0 0x34  
2 5.0 0x44  
3 5.1 to 6.0 0x58 0xB0
4 6.1 and higher 0x5C 0xB8

Layout

These sizes in the preceding table, and the offsets, types and names in the table that follows, are from Microsoft’s C-language definitions, checked against (some) inspection of what the kernel actually does have as its HalDispatchTable. It is left as understood that x64 offsets are meaningful only for those versions that have x64 builds, i.e., 5.2 from Windows Server 2003 SP1, and higher.

Offset (x86) Offset (x64) Definition Versions Remarks
0x00 0x00
ULONG Version;
3.51 and higher  
0x04 0x08
NTSTATUS
(*HalQuerySystemInformation) (
    HAL_QUERY_INFORMATION_CLASS,
    ULONG,
    PVOID,
    ULONG *);
3.51 and higher  
0x08 0x10
NTSTATUS
(*HalSetSystemInformation) (
    HAL_SET_INFORMATION_CLASS,
    ULONG,
    PVOID);
3.51 and higher  
0x0C  
NTSTATUS
(*HalQueryBusSlots) (
    INTERFACE_TYPE,
    ULONG,
    ULONG,
    ULONG *,
    ULONG *);
3.51 only  
0x18
NTSTATUS
(*HalQueryBusSlots) (
    BUS_HANDLER *,
    ULONG,
    ULONG *,
    ULONG *);
4.0 and higher  
0x10  
NTSTATUS
(*HalSlotControl) (
    INTERFACE_TYPE,
    ULONG,
    ULONG,
    DEVICE_OBJECT *,
    ULONG,
    PVOID,
    ULONG *,
    PVOID,
    PSLOT_CONTROL_COMPLETION);
3.51 only  
 
NTSTATUS
(*HalDeviceControl) (
    DEVICE_HANDLER_OBJECT *,
    DEVICE_OBJECT *,
    ULONG,
    PVOID,
    ULONG *,
    PVOID,
    PDEVICE_CONTROL_COMPLETION);
4.0 only  
0x20
ULONG Spare1;
5.0 and higher  
0x14 0x28
VOID
(FASTCALL *HalExamineMBR) (
    DEVICE_OBJECT *,
    ULONG,
    ULONG,
    PVOID *);
3.51 and higher  
0x18 0x30
VOID
(FASTCALL *HalIoAssignDriverLetters) (
    LOADER_PARAMETER_BLOCK *,
    STRING *,
    UCHAR *,
    STRING *);
3.51 to 6.0  
0x1C (before 6.1)
0x18
0x38 (before 6.1)
0x30
NTSTATUS
(FASTCALL *HalIoReadPartitionTable) (
    DEVICE_OBJECT *,
    ULONG,
    BOOLEAN,
    DRIVE_LAYOUT_INFORMATION **);
3.51 and higher  
0x20 (before 6.1)
0x1C
0x40 (before 6.1)
0x38
NTSTATUS
(FASTCALL *HalIoSetPartitionInformation) (
    DEVICE_OBJECT *,
    ULONG,
    ULONG,
    ULONG);
3.51 and higher  
0x24 (before 6.1)
0x20
0x48 (before 6.1)
0x40
NTSTATUS 
(FASTCALL *HalIoWritePartitionTable) (
    DEVICE_OBJECT *,
    ULONG,
    ULONG,
    ULONG,
    DRIVE_LAYOUT_INFORMATION *);
3.51 and higher  
0x28 (before 6.1)
0x24
0x50 (before 6.1)
0x48
BUS_HANDLER *
(FASTCALL *HalReferenceHandlerForBus) (
    INTERFACE_TYPE,
    ULONG);
4.0 and higher  
0x2C (before 6.1)
0x28
0x58 (before 6.1)
0x50
VOID
(FASTCALL *HalReferenceBusHandler) (
    BUS_HANDLER *);
4.0 and higher  
0x30 (before 6.1)
0x2C
0x60 (before 6.1)
0x58
VOID
(FASTCALL *HalDereferenceBusHandler) (
    BUS_HANDLER *);
4.0 and higher  
0x34 (before 6.1)
0x30
0x68 (before 6.1)
0x60
NTSTATUS
(*HalInitPnpDriver) (
    VOID);
5.0 and higher  
0x38 (before 6.1)
0x34
0x70 (before 6.1)
0x68
NTSTATUS
(*HalInitPowerManagement) (
    PM_DISPATCH_TABLE *,
    PM_DISPATCH_TABLE *);
5.0 and higher  
0x3C (before 6.1)
0x38
0x78 (before 6.1)
0x70
DMA_ADAPTER *
(*HalGetDmaAdapter) (
    PVOID,
    DEVICE_DESCRIPTION *,
    ULONG *);
5.0 and higher no default
0x40 (before 6.1)
0x3C
0x80 (before 6.1)
0x78
NTSTATUS
(*HalGetInterruptTranslator) (
    INTERFACE_TYPE,
    ULONG,
    INTERFACE_TYPE,
    USHORT,
    USHORT,
    TRANSLATOR_INTERFACE *,
    ULONG *);
5.0 and higher  
0x44 (before 6.1)
0x40
0x88 (before 6.1)
0x80
NTSTATUS
(*HalStartMirroring) (
    VOID);
5.1 and higher  
0x48 (before 6.1)
0x44
0x90 (before 6.1)
0x88
NTSTATUS
(*HalEndMirroring) (
    ULONG);
5.1 and higher  
0x4C (before 6.1)
0x48
0x98 (before 6.1)
0x90
NTSTATUS
(*HalMirrorPhysicalMemory) (
    PHYSICAL_ADDRESS,
    LARGE_INTEGER);
5.1 and higher  
0x50 (before 6.1)
0x4C
0xA0 (before 6.1)
0x98
VOID
(*HalEndOfBoot) (
    VOID);
5.1 and higher  
0x54 (before 6.1)
0x50
0xA8 (before 6.1)
0xA0
NTSTATUS
(*HalMirrorVerify) (
    PHYSICAL_ADDRESS,
    LARGE_INTEGER);
5.1 and higher  
0x54 0xA8
PVOID
(*HalGetCachedAcpiTable) (
    ULONG,
    PCSTR,
    PCSTR);
6.1 and higher no default
0x58 0xB0
VOID
(*HalSetPciErrorHandlerCallback) (
    PCI_ERROR_HANDLER_CALLBACK);
6.1 and higher no default

All non-obvious types in the preceding table are structures or enumerations except for the following function pointers:

typedef VOID (*PSLOT_CONTROL_COMPLETION) (SLOT_CONTROL_CONTEXT *);
typedef VOID (*PDEVICE_CONTROL_COMPLETION) (DEVICE_CONTROL_CONTEXT *);
typedef VOID (*PCI_ERROR_HANDLER_CALLBACK) (VOID);

Of course, almost all members of the HAL_DISPATCH are function pointers, but these are the ones that can be given as arguments: function pointers in function pointers get just a bit too complicated for easy presentation.