Skip to content

ntoskrnl7/crtsys

Repository files navigation

crtsys

C/C++ Runtime support for Windows kernel drivers (.sys).

CMake GitHub GitHub release Windows 7+ Visual Studio 2017+ CMake 3.14+ C++14+

Korean documentation

crtsys is an experimental runtime layer that helps Windows kernel drivers use C++ language features, selected Microsoft STL facilities, and small kernel-friendly helper abstractions. It is intended for driver projects that want a more familiar C++ development model without leaving the WDK/CMake build flow.

The project combines three pieces:

  • CRT/STL compatibility glue for kernel-mode builds.
  • Ldk, which provides a subset of Win32/NTDLL-like APIs used by the runtime and STL.
  • NTL, a small C++ helper layer for common driver objects and synchronization.

Design Model

crtsys is a kernel-mode C++ runtime substrate. It exists to make a controlled subset of MSVC C++ runtime, CRT, STL, and NTL facilities usable in Windows drivers while staying inside the normal WDK driver model.

It is designed primarily for driver control paths: initialization, unload, device setup, IOCTL/RPC handling, worker-thread coordination, ownership cleanup, and error handling. These paths are normally PASSIVE_LEVEL, with selected APC_LEVEL use where the underlying WDK APIs allow it.

It is not a promise that arbitrary user-mode C++ code, arbitrary STL usage, or arbitrary Win32 assumptions are safe in kernel mode. Unless an API explicitly documents a broader contract, assume PASSIVE_LEVEL. Do not use runtime-backed helpers in DPC, ISR, paging I/O, spin-lock-held, or other elevated-IRQL paths unless that exact API is documented and tested for that context.

See Design Rationale and Operational Boundaries for the full model.

Status

This project is not a full user-mode CRT, not a complete Windows compatibility layer, and not a replacement for careful driver design. It enables useful C++ and STL scenarios in kernel mode, but every driver should still be tested under the exact Windows, WDK, SDK, Visual Studio, architecture, and verifier settings that it will ship with.

Known constraints:

  • Runtime-backed C++/CRT/STL features should be treated as PASSIVE_LEVEL facilities unless the API reference says otherwise.
  • Thread-local storage and thread-safe local static initialization are not supported yet.
  • Kernel stacks are small; use ntl::expand_stack for paths that need more stack, especially exception-heavy or STL-heavy paths.
  • SDK and WDK version mismatches can cause build failures. Prefer matching SDK and WDK versions.
  • New Windows 11 24H2 WDK releases no longer support x86 kernel-mode driver development. Use WDK 23H2 or older when x86 driver targets are required.

Features

The README keeps this section short. The detailed, test-linked checklist lives in the documentation directory:

High-level coverage:

  • C++ runtime support
    • non-local static initialization
    • dynamic initialization
    • exceptions
  • Microsoft STL support
    • time utilities
    • threading primitives
    • synchronization primitives
    • async primitives
    • stream objects
  • C runtime support
    • CRT glue needed by the supported STL paths
    • math helpers
    • floating-point classification helpers
  • NTL support
    • C++ driver entry point wrapper
    • driver and device helpers
    • RPC helpers
    • IRQL and synchronization helpers

Requirements

  • Windows 7 or later
  • Visual Studio or Build Tools 2017 or later
  • Windows SDK and WDK compatible with the selected Visual Studio toolset
  • CMake 3.14 or later
  • Git

Tested toolchains include Visual Studio 2017, 2019, and 2022 with WDK/SDK versions such as 10.0.17763.0, 10.0.18362.0, 10.0.22000.0, and 10.0.22621.0.

Visual Studio 2017 has missing CRT source/header pieces for some paths, so crtsys uses selected UCXXRT compatibility code for that toolset.

Quick Start

Create a driver project, place CPM at cmake/CPM.cmake, and add crtsys:

cmake_minimum_required(VERSION 3.14 FATAL_ERROR)

project(my_driver LANGUAGES C CXX)

include(cmake/CPM.cmake)

set(CRTSYS_NTL_MAIN ON)
CPMAddPackage("gh:ntoskrnl7/crtsys@<version>")
include(${crtsys_SOURCE_DIR}/cmake/CrtSys.cmake)

crtsys_add_driver(my_driver src/main.cpp)

CRTSYS_NTL_MAIN enables the C++ entry point wrapper. With it enabled, define ntl::main instead of writing DriverEntry directly:

#include <iostream>
#include <string>
#include <ntl/driver>

ntl::status ntl::main(ntl::driver& driver,
                      const std::wstring& registry_path) {
  std::wcout << L"load: " << registry_path << L"\n";

  driver.on_unload([registry_path]() {
    std::wcout << L"unload: " << registry_path << L"\n";
  });

  return ntl::status::ok();
}

If CRTSYS_NTL_MAIN is disabled, keep the normal WDK DriverEntry entry point and initialize your driver manually.

Build the project with a Visual Studio generator:

cmake -S . -B build_x64 -A x64
cmake --build build_x64 --config Debug

NuGet Package

crtsys NuGet distribution is:

  • crtsys.<version>.nupkg: install from Visual Studio/MSBuild.

Install from VS/MSBuild:

Install-Package crtsys

GitHub Release Prebuilt Bundle

GitHub Release publishes these offline-only assets:

  • crtsys-<version>-prebuilt.zip: headers, docs, CMake helpers, and prebuilt x64/ARM64 Debug/Release libraries.
  • crtsys-<version>-SHA256SUMS.txt

Use the prebuilt bundle for WDK CMake/offline bootstrap:

Expand-Archive .\crtsys-<version>-prebuilt.zip .
include(path/to/crtsys-<version>/cmake/CrtSys.cmake)
crtsys_add_driver(my_driver src/main.cpp)

For full packaging and publishing command details, see nuget/README.md.

To publish a new version from main:

.\scripts\release\Prepare-CrtSysRelease.ps1 -Version <version> -Push

The helper updates include/.internal/version, commits the version bump, creates the matching v<version> tag, and pushes both the commit and tag. The tag push starts the Package workflow.

The same flow is also available from the GitHub UI: open Actions, select Release, choose Run workflow, and enter the release version. The workflow creates the version bump commit and tag, then dispatches the Package workflow for that tag. If branch protection blocks direct pushes to main, use the local helper or adjust the release rule first.

Building This Repository

Clone the repository and build the test app and driver for the host architecture:

git clone https://github.com/ntoskrnl7/crtsys
cd crtsys
test\build.bat

Build a specific target manually:

build.bat test\cmake\app x64 Debug
build.bat test\cmake\driver x64 Debug
build.bat test\cmake\app x64 Release
build.bat test\cmake\driver x64 Release

Build all supported architecture/configuration combinations:

build_all.bat test\cmake\app
build_all.bat test\cmake\driver

Typical Debug outputs:

test\cmake\driver\build_x64\Debug\crtsys_test.sys
test\cmake\app\build_x64\Debug\crtsys_test_app.exe

Running Tests

crtsys_test.sys is a kernel driver. Build validation can happen in CI, but loading and executing the test driver must happen in a Windows driver test environment.

The CI build workflow and optional self-hosted driver load test path are documented in CI driver load tests.

sc create CrtSysTest binpath= "C:\path\to\crtsys_test.sys" displayname= "crtsys test" start= demand type= kernel
sc start CrtSysTest

C:\path\to\crtsys_test_app.exe

sc stop CrtSysTest
sc delete CrtSysTest

The test driver uses Google Test internally. Inspect output with DebugView, WinDbg, or your normal kernel debugging setup.

Repository Layout

cmake/             CMake helpers, including CrtSys.cmake
include/ntl/       NTL C++ helper headers
include/.internal/ Internal version and toolchain compatibility headers
src/               crtsys runtime and CRT/STL compatibility code
test/cmake/app/    CMake user-mode test companion application
test/cmake/driver/ CMake kernel-mode test driver
test/nuget/        Visual Studio WDK NuGet consumer test project
docs/              Additional documentation

Background

crtsys was created after experimenting with other kernel C++ runtime projects, especially UCXXRT and KTL. The design goal is to keep the CMake/WDK workflow practical while supporting a broad enough subset of Microsoft CRT/STL behavior for real driver experiments.

The project avoids treating the Microsoft CRT/STL source as a vendored library. Instead, it relies on the locally installed Visual Studio/Build Tools layout and layers kernel-mode compatibility code around it. For older toolsets where the Microsoft-provided source/header layout is incomplete, small compatibility pieces are used.

Several standalone implementations are also referenced where they are a better fit for kernel-mode support:

Roadmap

  • Add CMake install/package handling.
  • Expand unsupported C++ and STL feature coverage.
  • Reduce Visual Studio 2017 compatibility gaps.
  • Add CI coverage for actual driver load/run tests where the environment supports it.