IoCreateSystemThread routine

The IoCreateSystemThread routine creates a system thread that executes in kernel mode, and supplies a handle for the thread.


NTSTATUS IoCreateSystemThread(
  _Inout_   PVOID              IoObject,
  _Out_     PHANDLE            ThreadHandle,
  _In_      ULONG              DesiredAccess,
  _In_opt_  POBJECT_ATTRIBUTES ObjectAttributes,
  _In_opt_  HANDLE             ProcessHandle,
  _Out_opt_ PCLIENT_ID         ClientId,
  _In_      PKSTART_ROUTINE    StartRoutine,
  _In_opt_  PVOID              StartContext


IoObject [in, out]

A pointer to the DEVICE_OBJECT or DRIVER_OBJECT to associate with the created thread. IoCreateSystemThread takes a counted reference to this object. The I/O manager later releases this reference when the thread exits. For more information, see Remarks.

ThreadHandle [out]

A pointer to a variable to which the routine writes the kernel handle for the created thread. When the handle is no longer needed, the driver must close the handle by calling the ZwClose routine.

DesiredAccess [in]

The ACCESS_MASK value that represents the types of access the caller requests to the created thread.

ObjectAttributes [in, optional]

A pointer to an OBJECT_ATTRIBUTES structure that specifies the thread object's attributes. The OBJ_PERMANENT, OBJ_EXCLUSIVE, and OBJ_OPENIF attributes are not valid attributes for a thread object. If the caller is not running in the system process context, it must set the OBJ_KERNEL_HANDLE attribute in the OBJECT_ATTRIBUTES structure.

ProcessHandle [in, optional]

An open handle for the process in whose address space the created thread is to run. The caller's thread must have PROCESS_CREATE_THREAD access to this process. If this parameter is NULL, the thread will be created in the initial system process. This parameter should be NULL for a driver-created thread. Use the NtCurrentProcess macro, defined in the Wdm.h header file, to specify the current process.

ClientId [out, optional]

A pointer to a structure to which the routine writes the client identifier for the created thread. This parameter should be NULL for a driver-created thread.

StartRoutine [in]

A pointer to a ThreadStart routine that is the entry point for the created thread.

StartContext [in, optional]

A context pointer that is passed as the StartContext parameter to the ThreadStart routine when the created thread starts to run.

Return value

IoCreateSystemThread returns STATUS_SUCCESS if the new thread was successfully created. Possible return values include the following error status codes.

Return codeDescription

ProcessHandle is not a valid process handle.


The process specified by ProcessHandle is terminating.


Insufficient system resources are available to perform the requested operation.



Starting with Windows 8, a driver can call IoCreateSystemThread to create a device-dedicated thread. This routine creates a new system thread that has no thread environment block (TEB) or user-mode context, and runs only in kernel mode.

Typically, the driver calls IoCreateSystemThread either when it starts the device, or when the driver's DispatchXxx routines start to receive I/O requests. For example, a driver might call this routine to create a thread when a DispatchXxx routine receives an asynchronous device control request.

If the ProcessHandle parameter is NULL, the created thread is associated with the system process. Such a thread continues running until either the system is shut down or the thread exits.

Driver routines that run in a process context other than that of the system process must set the OBJ_KERNEL_HANDLE attribute for the ObjectAttributes parameter of IoCreateSystemThread. This attribute restricts the use of the handle returned by IoCreateSystemThread to processes running in kernel mode. Otherwise, the thread handle could be accessed by the process in whose context the driver is running. Drivers can call the InitializeObjectAttributes macro to set the OBJ_KERNEL_HANDLE attribute in the object attributes, as shown in the following code example.


InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

IoCreateSystemThread is similar to the PsCreateSystemThread routine, but has an additional parameter, IoObject, which is a pointer to the caller's driver object or device object. IoCreateSystemThread uses this parameter to ensure that the driver cannot unload while the created thread exists. Before scheduling StartRoutine to run in this thread, IoCreateSystemThread takes a counted reference to the IoObject object. The I/O manager releases this reference after the created thread exits. Thus, this object persists for the lifetime of the created thread.

In contrast to a system thread that is created by the PsCreateSystemThread routine, a thread created by IoCreateSystemThread does not call the PsTerminateSystemThread routine to terminate itself. Instead, the I/O manager calls PsTerminateSystemThread on behalf of the created thread when the thread exits.


Target platform



Available starting with Windows 8.


Wdm.h (include Wdm.h, Ntddk.h, or Ntifs.h)







See also




Send comments about this topic to Microsoft