├── .appveyor.yml ├── .editorconfig ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── LICENSE ├── README.md ├── cmake └── FindWdk.cmake └── samples ├── CMakeLists.txt ├── KmdfCppDriver ├── CMakeLists.txt └── Main.cpp ├── KmdfCppLib ├── CMakeLists.txt ├── KmdfCppLib.cpp └── KmdfCppLib.h ├── MinifilterCppDriver ├── CMakeLists.txt └── Main.cpp ├── WdmCppDriver ├── CMakeLists.txt └── Main.cpp ├── WdmCppLib ├── CMakeLists.txt ├── WdmCppLib.cpp └── WdmCppLib.h ├── WdmDriver ├── CMakeLists.txt └── Main.c ├── WdmIntrinsicFunctions ├── CMakeLists.txt └── Main.cpp └── WdmLib ├── CMakeLists.txt ├── WdmLib.c └── WdmLib.h /.appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 4 | generator: "Visual Studio 15 2017" 5 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 6 | generator: "Visual Studio 15 2017 Win64" 7 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 8 | generator: "Visual Studio 14 2015" 9 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 10 | generator: "Visual Studio 14 2015 Win64" 11 | 12 | matrix: 13 | fast_finish: true 14 | 15 | shallow_clone: true 16 | 17 | skip_commits: 18 | files: 19 | - .github/ 20 | - .editorconfig 21 | - .gitignore 22 | - LICENSE 23 | - README.md 24 | 25 | before_build: 26 | - cmake -Hsamples -Bbuild -G"%generator%" 27 | 28 | build_script: 29 | - cmake --build build --config Debug -- /m /v:m 30 | - cmake --build build --config Release -- /m /v:m 31 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | charset = utf-8 9 | indent_style = space 10 | indent_size = 4 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | 17 | [*.yml] 18 | indent_size = 2 19 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | paths-ignore: 6 | - '**.md' 7 | pull_request: 8 | paths-ignore: 9 | - '**.md' 10 | 11 | permissions: 12 | contents: read 13 | 14 | concurrency: 15 | cancel-in-progress: true 16 | group: ${{ github.workflow }}-${{ github.head_ref }} 17 | 18 | jobs: 19 | build: 20 | name: ${{ matrix.cxx }}, ${{ matrix.os }} 21 | 22 | strategy: 23 | fail-fast: true 24 | matrix: 25 | include: [ 26 | # You can access the following values via ${{ matrix.??? }} 27 | # 28 | # cxx : C++ compiler executable 29 | # os : GitHub Actions YAML workflow label. See https://github.com/actions/virtual-environments#available-environments 30 | 31 | { os: windows-2019, cxx: 'vs2019' }, 32 | { os: windows-2022, cxx: 'vs2022' } 33 | ] 34 | 35 | runs-on: ${{ matrix.os }} 36 | 37 | steps: 38 | - name: checkout 39 | uses: actions/checkout@v3 40 | with: 41 | fetch-depth: 0 42 | 43 | - name: build 44 | run: | 45 | cmake -Bbuild samples 46 | cmake --build build --parallel --config Release 47 | cmake --build build --parallel --config Debug 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /build32 3 | /build64 4 | /samples/build 5 | /samples/out -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Sergey Podobry (sergey.podobry at gmail.com). All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | Redistributions in binary form must reproduce the above copyright notice, this 10 | list of conditions and the following disclaimer in the documentation and/or 11 | other materials provided with the distribution. 12 | 13 | Neither the name of the {organization} nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 21 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 24 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FindWDK 2 | CMake module for building drivers with Windows Development Kit (WDK) [![Build status](https://ci.appveyor.com/api/projects/status/o7cyircahkb6nv07/branch/master?svg=true)](https://ci.appveyor.com/project/SergiusTheBest/findwdk/branch/master) [![CI](https://github.com/SergiusTheBest/FindWDK/actions/workflows/ci.yml/badge.svg)](https://github.com/SergiusTheBest/FindWDK/actions/workflows/ci.yml) 3 | 4 | - [Introduction](#introduction) 5 | - [Usage](#usage) 6 | - [Kernel driver](#kernel-driver) 7 | - [Kernel library](#kernel-library) 8 | - [Linking to WDK libraries](#linking-to-wdk-libraries) 9 | - [Samples](#samples) 10 | - [License](#license) 11 | - [Version history](#version-history) 12 | 13 | # Introduction 14 | FindWDK makes it possible to build kernel drivers and kernel libraries with Windows Development Kit (WDK) and CMake. 15 | 16 | Requirements: 17 | - WDK 8.0 and higher 18 | - Visual Studio 2015 and higher 19 | - CMake 3.0 and higher 20 | 21 | # Usage 22 | Add FindWDK to the module search path and call `find_package`: 23 | 24 | ```cmake 25 | list(APPEND CMAKE_MODULE_PATH "") 26 | find_package(WDK REQUIRED) 27 | ``` 28 | 29 | FindWDK will search for the latest installed Windows Development Kit (WDK) and expose commands for creating kernel drivers and kernel libraries. Also the following variables will be defined: 30 | - `WDK_FOUND` -- if false, do not try to use WDK 31 | - `WDK_ROOT` -- where WDK is installed 32 | - `WDK_VERSION` -- the version of the selected WDK 33 | - `WDK_WINVER` -- the WINVER used for kernel drivers and libraries (default value is `0x0601` and can be changed per target or globally) 34 | - `WDK_NTDDI_VERSION` -- the NTDDI_VERSION used for kernel drivers and libraries, if not set, the value will be automatically calculated by WINVER 35 | 36 | `WDKContentRoot` environment variable overrides the default WDK search path. 37 | 38 | ## Kernel driver 39 | The following command adds a kernel driver target called `` to be built from the source files listed in the command invocation: 40 | 41 | ```cmake 42 | wdk_add_driver( 43 | [EXCLUDE_FROM_ALL] 44 | [KMDF ] 45 | [WINVER ] 46 | [NTDDI_VERSION ] 47 | source1 [source2 ...] 48 | ) 49 | ``` 50 | 51 | Options: 52 | - `EXCLUDE_FROM_ALL` -- exclude from the default build target 53 | - `KMDF ` -- use KMDF and set KMDF version 54 | - `WINVER ` -- use specific WINVER version 55 | - `NTDDI_VERSION ` -- use specific NTDDI_VERSION 56 | 57 | Example: 58 | 59 | ```cmake 60 | wdk_add_driver(KmdfCppDriver 61 | KMDF 1.15 62 | WINVER 0x0602 63 | Main.cpp 64 | ) 65 | ``` 66 | 67 | ## Kernel library 68 | The following command adds a kernel library target called `` to be built from the source files listed in the command invocation: 69 | 70 | ```cmake 71 | wdk_add_library( [STATIC | SHARED] 72 | [EXCLUDE_FROM_ALL] 73 | [KMDF ] 74 | [WINVER ] 75 | [NTDDI_VERSION ] 76 | source1 [source2 ...] 77 | ) 78 | ``` 79 | 80 | Options: 81 | - `EXCLUDE_FROM_ALL` -- exclude from the default build target 82 | - `KMDF ` -- use KMDF and set KMDF version 83 | - `WINVER ` -- use specific WINVER version 84 | - `NTDDI_VERSION ` -- use specific NTDDI_VERSION 85 | - `STATIC or SHARED` -- specify the type of library to be created 86 | 87 | Example: 88 | 89 | ```cmake 90 | wdk_add_library(KmdfCppLib STATIC 91 | KMDF 1.15 92 | WINVER 0x0602 93 | KmdfCppLib.h 94 | KmdfCppLib.cpp 95 | ) 96 | ``` 97 | 98 | ## Linking to WDK libraries 99 | FindWDK creates imported targets for all WDK libraries. The naming pattern is `WDK::`. Linking a minifilter driver to `FltMgr.lib` is shown below: 100 | 101 | ```cmake 102 | target_link_libraries(MinifilterCppDriver WDK::FLTMGR) 103 | ``` 104 | 105 | # Samples 106 | Take a look at the [samples](samples) folder to see how WMD and KMDF drivers and libraries are built. 107 | 108 | # License 109 | FindWDK is licensed under the OSI-approved 3-clause BSD license. You can freely use it in your commercial or opensource software. 110 | 111 | # Version history 112 | 113 | ## Version 1.0.2 (TBD) 114 | 115 | ## Version 1.0.1 (13 Mar 2018) 116 | - New: Add ability to link to WDK libraries 117 | - New: Add MinifilterCppDriver sample 118 | - Fix: W4 warnings in C version of the driver, add missing /W4 /WX for C compiler 119 | 120 | ## Version 1.0.0 (03 Feb 2018) 121 | - Initial public release 122 | -------------------------------------------------------------------------------- /cmake/FindWdk.cmake: -------------------------------------------------------------------------------- 1 | # Redistribution and use is allowed under the OSI-approved 3-clause BSD license. 2 | # Copyright (c) 2018 Sergey Podobry (sergey.podobry at gmail.com). All rights reserved. 3 | 4 | #.rst: 5 | # FindWDK 6 | # ---------- 7 | # 8 | # This module searches for the installed Windows Development Kit (WDK) and 9 | # exposes commands for creating kernel drivers and kernel libraries. 10 | # 11 | # Output variables: 12 | # - `WDK_FOUND` -- if false, do not try to use WDK 13 | # - `WDK_ROOT` -- where WDK is installed 14 | # - `WDK_VERSION` -- the version of the selected WDK 15 | # - `WDK_WINVER` -- the WINVER used for kernel drivers and libraries 16 | # (default value is `0x0601` and can be changed per target or globally) 17 | # - `WDK_NTDDI_VERSION` -- the NTDDI_VERSION used for kernel drivers and libraries, 18 | # if not set, the value will be automatically calculated by WINVER 19 | # (default value is left blank and can be changed per target or globally) 20 | # 21 | # Example usage: 22 | # 23 | # find_package(WDK REQUIRED) 24 | # 25 | # wdk_add_library(KmdfCppLib STATIC KMDF 1.15 26 | # KmdfCppLib.h 27 | # KmdfCppLib.cpp 28 | # ) 29 | # target_include_directories(KmdfCppLib INTERFACE .) 30 | # 31 | # wdk_add_driver(KmdfCppDriver KMDF 1.15 32 | # Main.cpp 33 | # ) 34 | # target_link_libraries(KmdfCppDriver KmdfCppLib) 35 | # 36 | 37 | if(DEFINED ENV{WDKContentRoot}) 38 | file(GLOB WDK_NTDDK_FILES 39 | "$ENV{WDKContentRoot}/Include/*/km/ntddk.h" # WDK 10 40 | "$ENV{WDKContentRoot}/Include/km/ntddk.h" # WDK 8.0, 8.1 41 | ) 42 | else() 43 | file(GLOB WDK_NTDDK_FILES 44 | "C:/Program Files*/Windows Kits/*/Include/*/km/ntddk.h" # WDK 10 45 | "C:/Program Files*/Windows Kits/*/Include/km/ntddk.h" # WDK 8.0, 8.1 46 | ) 47 | endif() 48 | 49 | if(WDK_NTDDK_FILES) 50 | if (NOT CMAKE_VERSION VERSION_LESS 3.18.0) 51 | list(SORT WDK_NTDDK_FILES COMPARE NATURAL) # sort to use the latest available WDK 52 | endif() 53 | list(GET WDK_NTDDK_FILES -1 WDK_LATEST_NTDDK_FILE) 54 | endif() 55 | 56 | include(FindPackageHandleStandardArgs) 57 | find_package_handle_standard_args(WDK REQUIRED_VARS WDK_LATEST_NTDDK_FILE) 58 | 59 | if(NOT WDK_LATEST_NTDDK_FILE) 60 | return() 61 | endif() 62 | 63 | get_filename_component(WDK_ROOT ${WDK_LATEST_NTDDK_FILE} DIRECTORY) 64 | get_filename_component(WDK_ROOT ${WDK_ROOT} DIRECTORY) 65 | get_filename_component(WDK_VERSION ${WDK_ROOT} NAME) 66 | get_filename_component(WDK_ROOT ${WDK_ROOT} DIRECTORY) 67 | if (NOT WDK_ROOT MATCHES ".*/[0-9][0-9.]*$") # WDK 10 has a deeper nesting level 68 | get_filename_component(WDK_ROOT ${WDK_ROOT} DIRECTORY) # go up once more 69 | set(WDK_LIB_VERSION "${WDK_VERSION}") 70 | set(WDK_INC_VERSION "${WDK_VERSION}") 71 | else() # WDK 8.0, 8.1 72 | set(WDK_INC_VERSION "") 73 | foreach(VERSION winv6.3 win8 win7) 74 | if (EXISTS "${WDK_ROOT}/Lib/${VERSION}/") 75 | set(WDK_LIB_VERSION "${VERSION}") 76 | break() 77 | endif() 78 | endforeach() 79 | set(WDK_VERSION "${WDK_LIB_VERSION}") 80 | endif() 81 | 82 | message(STATUS "WDK_ROOT: " ${WDK_ROOT}) 83 | message(STATUS "WDK_VERSION: " ${WDK_VERSION}) 84 | 85 | set(WDK_WINVER "0x0601" CACHE STRING "Default WINVER for WDK targets") 86 | set(WDK_NTDDI_VERSION "" CACHE STRING "Specified NTDDI_VERSION for WDK targets if needed") 87 | 88 | set(WDK_ADDITIONAL_FLAGS_FILE "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/wdkflags.h") 89 | file(WRITE ${WDK_ADDITIONAL_FLAGS_FILE} "#pragma runtime_checks(\"suc\", off)") 90 | 91 | set(WDK_COMPILE_FLAGS 92 | "/Zp8" # set struct alignment 93 | "/GF" # enable string pooling 94 | "/GR-" # disable RTTI 95 | "/Gz" # __stdcall by default 96 | "/kernel" # create kernel mode binary 97 | "/FIwarning.h" # disable warnings in WDK headers 98 | "/FI${WDK_ADDITIONAL_FLAGS_FILE}" # include file to disable RTC 99 | "/Oi" # enable intrinsic functions so that you can use functions like _disable or _enable 100 | ) 101 | 102 | set(WDK_COMPILE_DEFINITIONS "WINNT=1") 103 | set(WDK_COMPILE_DEFINITIONS_DEBUG "MSC_NOOPT;DEPRECATE_DDK_FUNCTIONS=1;DBG=1") 104 | 105 | if(CMAKE_SIZEOF_VOID_P EQUAL 4) 106 | list(APPEND WDK_COMPILE_DEFINITIONS "_X86_=1;i386=1;STD_CALL") 107 | set(WDK_PLATFORM "x86") 108 | elseif(CMAKE_SIZEOF_VOID_P EQUAL 8 AND CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64") 109 | list(APPEND WDK_COMPILE_DEFINITIONS "_ARM64_;ARM64;_USE_DECLSPECS_FOR_SAL=1;STD_CALL") 110 | set(WDK_PLATFORM "arm64") 111 | elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) 112 | list(APPEND WDK_COMPILE_DEFINITIONS "_AMD64_;AMD64") 113 | set(WDK_PLATFORM "x64") 114 | else() 115 | message(FATAL_ERROR "Unsupported architecture") 116 | endif() 117 | 118 | string(CONCAT WDK_LINK_FLAGS 119 | "/MANIFEST:NO " # 120 | "/DRIVER " # 121 | "/OPT:REF " # 122 | "/INCREMENTAL:NO " # 123 | "/OPT:ICF " # 124 | "/SUBSYSTEM:NATIVE " # 125 | "/MERGE:_TEXT=.text;_PAGE=PAGE " # 126 | "/NODEFAULTLIB " # do not link default CRT 127 | "/SECTION:INIT,d " # 128 | "/VERSION:10.0 " # 129 | ) 130 | 131 | # Generate imported targets for WDK lib files 132 | file(GLOB WDK_LIBRARIES "${WDK_ROOT}/Lib/${WDK_LIB_VERSION}/km/${WDK_PLATFORM}/*.lib") 133 | foreach(LIBRARY IN LISTS WDK_LIBRARIES) 134 | get_filename_component(LIBRARY_NAME ${LIBRARY} NAME_WE) 135 | string(TOUPPER ${LIBRARY_NAME} LIBRARY_NAME) 136 | add_library(WDK::${LIBRARY_NAME} INTERFACE IMPORTED) 137 | set_property(TARGET WDK::${LIBRARY_NAME} PROPERTY INTERFACE_LINK_LIBRARIES ${LIBRARY}) 138 | endforeach(LIBRARY) 139 | unset(WDK_LIBRARIES) 140 | 141 | function(wdk_add_driver _target) 142 | cmake_parse_arguments(WDK "" "KMDF;WINVER;NTDDI_VERSION" "" ${ARGN}) 143 | 144 | add_executable(${_target} ${WDK_UNPARSED_ARGUMENTS}) 145 | 146 | set_target_properties(${_target} PROPERTIES SUFFIX ".sys") 147 | set_target_properties(${_target} PROPERTIES COMPILE_OPTIONS "${WDK_COMPILE_FLAGS}") 148 | set_target_properties(${_target} PROPERTIES COMPILE_DEFINITIONS 149 | "${WDK_COMPILE_DEFINITIONS};$<$:${WDK_COMPILE_DEFINITIONS_DEBUG}>;_WIN32_WINNT=${WDK_WINVER}" 150 | ) 151 | set_target_properties(${_target} PROPERTIES LINK_FLAGS "${WDK_LINK_FLAGS}") 152 | if(WDK_NTDDI_VERSION) 153 | target_compile_definitions(${_target} PRIVATE NTDDI_VERSION=${WDK_NTDDI_VERSION}) 154 | endif() 155 | 156 | target_include_directories(${_target} SYSTEM PRIVATE 157 | "${WDK_ROOT}/Include/${WDK_INC_VERSION}/shared" 158 | "${WDK_ROOT}/Include/${WDK_INC_VERSION}/km" 159 | "${WDK_ROOT}/Include/${WDK_INC_VERSION}/km/crt" 160 | ) 161 | 162 | target_link_libraries(${_target} WDK::NTOSKRNL WDK::HAL WDK::WMILIB) 163 | 164 | if(WDK::BUFFEROVERFLOWK) 165 | target_link_libraries(${_target} WDK::BUFFEROVERFLOWK) # to support Windows 7 and Vista 166 | else() 167 | target_link_libraries(${_target} WDK::BUFFEROVERFLOWFASTFAILK) 168 | endif() 169 | 170 | if(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64") 171 | target_link_libraries(${_target} "arm64rt.lib") 172 | endif() 173 | 174 | if(CMAKE_SIZEOF_VOID_P EQUAL 4) 175 | target_link_libraries(${_target} WDK::MEMCMP) 176 | endif() 177 | 178 | if(DEFINED WDK_KMDF) 179 | target_include_directories(${_target} SYSTEM PRIVATE "${WDK_ROOT}/Include/wdf/kmdf/${WDK_KMDF}") 180 | target_link_libraries(${_target} 181 | "${WDK_ROOT}/Lib/wdf/kmdf/${WDK_PLATFORM}/${WDK_KMDF}/WdfDriverEntry.lib" 182 | "${WDK_ROOT}/Lib/wdf/kmdf/${WDK_PLATFORM}/${WDK_KMDF}/WdfLdr.lib" 183 | ) 184 | 185 | if(CMAKE_SIZEOF_VOID_P EQUAL 4) 186 | set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:FxDriverEntry@8") 187 | elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) 188 | set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:FxDriverEntry") 189 | endif() 190 | else() 191 | if(CMAKE_SIZEOF_VOID_P EQUAL 4) 192 | set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:GsDriverEntry@8") 193 | elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) 194 | set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:GsDriverEntry") 195 | endif() 196 | endif() 197 | endfunction() 198 | 199 | function(wdk_add_library _target) 200 | cmake_parse_arguments(WDK "" "KMDF;WINVER;NTDDI_VERSION" "" ${ARGN}) 201 | 202 | add_library(${_target} ${WDK_UNPARSED_ARGUMENTS}) 203 | 204 | set_target_properties(${_target} PROPERTIES COMPILE_OPTIONS "${WDK_COMPILE_FLAGS}") 205 | set_target_properties(${_target} PROPERTIES COMPILE_DEFINITIONS 206 | "${WDK_COMPILE_DEFINITIONS};$<$:${WDK_COMPILE_DEFINITIONS_DEBUG};>_WIN32_WINNT=${WDK_WINVER}" 207 | ) 208 | if(WDK_NTDDI_VERSION) 209 | target_compile_definitions(${_target} PRIVATE NTDDI_VERSION=${WDK_NTDDI_VERSION}) 210 | endif() 211 | 212 | target_include_directories(${_target} SYSTEM PRIVATE 213 | "${WDK_ROOT}/Include/${WDK_INC_VERSION}/shared" 214 | "${WDK_ROOT}/Include/${WDK_INC_VERSION}/km" 215 | "${WDK_ROOT}/Include/${WDK_INC_VERSION}/km/crt" 216 | ) 217 | 218 | if(DEFINED WDK_KMDF) 219 | target_include_directories(${_target} SYSTEM PRIVATE "${WDK_ROOT}/Include/wdf/kmdf/${WDK_KMDF}") 220 | endif() 221 | endfunction() 222 | -------------------------------------------------------------------------------- /samples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0) 2 | 3 | project(FindWdk) 4 | 5 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 6 | 7 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX") 8 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4 /WX") 9 | 10 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../cmake") 11 | find_package(WDK REQUIRED) 12 | 13 | add_subdirectory(KmdfCppDriver) 14 | add_subdirectory(KmdfCppLib) 15 | add_subdirectory(MinifilterCppDriver) 16 | add_subdirectory(WdmCppDriver) 17 | add_subdirectory(WdmCppLib) 18 | add_subdirectory(WdmDriver) 19 | add_subdirectory(WdmLib) 20 | add_subdirectory(WdmIntrinsicFunctions) -------------------------------------------------------------------------------- /samples/KmdfCppDriver/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | wdk_add_driver(KmdfCppDriver 2 | KMDF 1.15 3 | Main.cpp 4 | ) 5 | target_link_libraries(KmdfCppDriver KmdfCppLib) 6 | -------------------------------------------------------------------------------- /samples/KmdfCppDriver/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "KmdfCppLib.h" 4 | 5 | #include 6 | 7 | EVT_WDF_DRIVER_UNLOAD evtDriverUnload; 8 | VOID evtDriverUnload(_In_ WDFDRIVER /*driver*/) 9 | { 10 | char msg[17]; 11 | _snprintf_s(msg, 17, "%s", "Driver unloaded\n"); 12 | 13 | DbgPrint(msg); 14 | } 15 | 16 | extern "C" DRIVER_INITIALIZE DriverEntry; 17 | extern "C" NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING registryPath) 18 | { 19 | DbgPrint("Driver loaded\n"); 20 | 21 | WDF_DRIVER_CONFIG config; 22 | WDF_DRIVER_CONFIG_INIT(&config, nullptr); 23 | config.EvtDriverUnload = evtDriverUnload; 24 | 25 | NTSTATUS status = WdfDriverCreate(driverObject, registryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE); 26 | if (!NT_SUCCESS(status)) 27 | { 28 | return status; 29 | } 30 | 31 | UNICODE_STRING answer = {}; 32 | WdfStringGetUnicodeString(getAnswer(), &answer); 33 | DbgPrint("The answer is %wZ\n", answer); 34 | 35 | return STATUS_SUCCESS; 36 | } -------------------------------------------------------------------------------- /samples/KmdfCppLib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | wdk_add_library(KmdfCppLib STATIC 2 | KMDF 1.15 3 | KmdfCppLib.h 4 | KmdfCppLib.cpp 5 | ) 6 | target_include_directories(KmdfCppLib INTERFACE .) -------------------------------------------------------------------------------- /samples/KmdfCppLib/KmdfCppLib.cpp: -------------------------------------------------------------------------------- 1 | #include "KmdfCppLib.h" 2 | 3 | #include 4 | 5 | WDFSTRING getAnswer() 6 | { 7 | static wchar_t answer[3]; 8 | _snwprintf_s(answer, 3, L"%s", L"42"); 9 | 10 | static const UNICODE_STRING str = RTL_CONSTANT_STRING(answer); 11 | 12 | WDFSTRING wdfstr = nullptr; 13 | NTSTATUS status = WdfStringCreate(&str, WDF_NO_OBJECT_ATTRIBUTES, &wdfstr); 14 | if (!NT_SUCCESS(status)) 15 | { 16 | return nullptr; 17 | } 18 | 19 | return wdfstr; 20 | } -------------------------------------------------------------------------------- /samples/KmdfCppLib/KmdfCppLib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | WDFSTRING getAnswer(); -------------------------------------------------------------------------------- /samples/MinifilterCppDriver/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | wdk_add_driver(MinifilterCppDriver 2 | Main.cpp 3 | ) 4 | target_link_libraries(MinifilterCppDriver WDK::FLTMGR) 5 | -------------------------------------------------------------------------------- /samples/MinifilterCppDriver/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | PFLT_FILTER g_filterHandle = nullptr; 4 | 5 | NTSTATUS FLTAPI instanceSetup( 6 | _In_ PCFLT_RELATED_OBJECTS /*fltObjects*/, 7 | _In_ FLT_INSTANCE_SETUP_FLAGS /*flags*/, 8 | _In_ DEVICE_TYPE /*volumeDeviceType*/, 9 | _In_ FLT_FILESYSTEM_TYPE /*volumeFilesystemType*/ 10 | ) 11 | { 12 | return STATUS_SUCCESS; 13 | } 14 | 15 | NTSTATUS FLTAPI queryTeardown( 16 | _In_ PCFLT_RELATED_OBJECTS /*fltObjects*/, 17 | _In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS /*flags*/ 18 | ) 19 | { 20 | return STATUS_SUCCESS; 21 | } 22 | 23 | FLT_PREOP_CALLBACK_STATUS FLTAPI preCreate( 24 | _Inout_ PFLT_CALLBACK_DATA /*data*/, 25 | _In_ PCFLT_RELATED_OBJECTS /*fltObjects*/, 26 | _Outptr_result_maybenull_ PVOID* /*completionContext*/ 27 | ) 28 | { 29 | DbgPrint("preCreate\n"); 30 | 31 | return FLT_PREOP_SUCCESS_NO_CALLBACK; 32 | } 33 | 34 | NTSTATUS FLTAPI filterUnloadCallback(_In_ FLT_FILTER_UNLOAD_FLAGS) 35 | { 36 | DbgPrint("filterUnloadCallback\n"); 37 | 38 | FltUnregisterFilter(g_filterHandle); 39 | return STATUS_SUCCESS; 40 | } 41 | 42 | extern "C" DRIVER_INITIALIZE DriverEntry; 43 | extern "C" NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING /*registryPath*/) 44 | { 45 | DbgPrint("Driver loaded\n"); 46 | 47 | const FLT_CONTEXT_REGISTRATION contextRegistration[] = 48 | { 49 | { FLT_CONTEXT_END } 50 | }; 51 | 52 | const FLT_OPERATION_REGISTRATION callbacksRegistration[] = 53 | { 54 | { 55 | IRP_MJ_CREATE, 56 | 0, 57 | &preCreate, 58 | nullptr 59 | }, 60 | 61 | { IRP_MJ_OPERATION_END } 62 | }; 63 | 64 | const FLT_REGISTRATION filterRegistration = 65 | { 66 | sizeof(FLT_REGISTRATION), // Size 67 | FLT_REGISTRATION_VERSION, // Version 68 | 0, // Flags 69 | contextRegistration, // Context 70 | callbacksRegistration, // Operation callbacks 71 | filterUnloadCallback, // Mini filter unload 72 | &instanceSetup, // InstanceSetup 73 | &queryTeardown, // InstanceQueryTeardown 74 | nullptr, // InstanceTeardownStart 75 | nullptr, // InstanceTeardownComplete 76 | nullptr, // GenerateFileNameCallback 77 | nullptr, // NormalizeNameComponentCallback 78 | nullptr, // NormalizeContextCleanupCallback 79 | nullptr, // TransactionNotificationCallback 80 | nullptr // NormalizeNameComponentExCallback 81 | }; 82 | 83 | NTSTATUS status = FltRegisterFilter(driverObject, &filterRegistration, &g_filterHandle); 84 | if (!NT_SUCCESS(status)) 85 | { 86 | return status; 87 | } 88 | 89 | status = FltStartFiltering(g_filterHandle); 90 | if (!NT_SUCCESS(status)) 91 | { 92 | FltUnregisterFilter(g_filterHandle); 93 | return status; 94 | } 95 | 96 | return STATUS_SUCCESS; 97 | } -------------------------------------------------------------------------------- /samples/WdmCppDriver/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | wdk_add_driver(WdmCppDriver 2 | Main.cpp 3 | ) 4 | target_link_libraries(WdmCppDriver WdmCppLib) 5 | -------------------------------------------------------------------------------- /samples/WdmCppDriver/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "WdmCppLib.h" 3 | 4 | DRIVER_UNLOAD driverUnload; 5 | VOID driverUnload(_In_ PDRIVER_OBJECT /*driverObject*/) 6 | { 7 | DbgPrint("Driver unloaded\n"); 8 | } 9 | 10 | extern "C" DRIVER_INITIALIZE DriverEntry; 11 | extern "C" NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING /*registryPath*/) 12 | { 13 | DbgPrint("Driver loaded\n"); 14 | DbgPrint("The answer is %wZ\n", getAnswer()); 15 | 16 | driverObject->DriverUnload = driverUnload; 17 | return STATUS_SUCCESS; 18 | } -------------------------------------------------------------------------------- /samples/WdmCppLib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | wdk_add_library(WdmCppLib STATIC 2 | WdmCppLib.h 3 | WdmCppLib.cpp 4 | ) 5 | target_include_directories(WdmCppLib INTERFACE .) -------------------------------------------------------------------------------- /samples/WdmCppLib/WdmCppLib.cpp: -------------------------------------------------------------------------------- 1 | #include "WdmCppLib.h" 2 | 3 | PCUNICODE_STRING getAnswer() 4 | { 5 | static const UNICODE_STRING str = RTL_CONSTANT_STRING(L"42"); 6 | return &str; 7 | } -------------------------------------------------------------------------------- /samples/WdmCppLib/WdmCppLib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | PCUNICODE_STRING getAnswer(); -------------------------------------------------------------------------------- /samples/WdmDriver/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | wdk_add_driver(WdmDriver 2 | Main.c 3 | ) 4 | target_link_libraries(WdmDriver WdmLib) 5 | -------------------------------------------------------------------------------- /samples/WdmDriver/Main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "WdmLib.h" 3 | 4 | DRIVER_UNLOAD driverUnload; 5 | VOID driverUnload(_In_ PDRIVER_OBJECT driverObject) 6 | { 7 | UNREFERENCED_PARAMETER(driverObject); 8 | 9 | DbgPrint("Driver unloaded\n"); 10 | } 11 | 12 | DRIVER_INITIALIZE DriverEntry; 13 | NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING registryPath) 14 | { 15 | UNREFERENCED_PARAMETER(registryPath); 16 | 17 | DbgPrint("Driver loaded\n"); 18 | DbgPrint("The answer is %wZ\n", getAnswer()); 19 | 20 | driverObject->DriverUnload = driverUnload; 21 | return STATUS_SUCCESS; 22 | } -------------------------------------------------------------------------------- /samples/WdmIntrinsicFunctions/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | wdk_add_driver(WdmIntrinsicFunctions 2 | Main.cpp 3 | ) 4 | target_link_libraries(WdmIntrinsicFunctions WdmCppLib) -------------------------------------------------------------------------------- /samples/WdmIntrinsicFunctions/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | DRIVER_UNLOAD driverUnload; 5 | VOID driverUnload(_In_ PDRIVER_OBJECT driverObject) 6 | { 7 | UNREFERENCED_PARAMETER(driverObject); 8 | 9 | DbgPrint("Driver unloaded\n"); 10 | } 11 | 12 | EXTERN_C NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING registryPath) 13 | { 14 | UNREFERENCED_PARAMETER(registryPath); 15 | 16 | DbgPrint("Driver loaded\n"); 17 | 18 | _disable(); //use intrinsic function 19 | ULONG64 cr3 = __readcr3(); //use intrinsic function 20 | _enable(); //use intrinsic function 21 | 22 | DbgPrint("CR3: %p\n", cr3); 23 | driverObject->DriverUnload = driverUnload; 24 | return STATUS_SUCCESS; 25 | } -------------------------------------------------------------------------------- /samples/WdmLib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | wdk_add_library(WdmLib STATIC 2 | WdmLib.h 3 | WdmLib.c 4 | ) 5 | target_include_directories(WdmLib INTERFACE .) -------------------------------------------------------------------------------- /samples/WdmLib/WdmLib.c: -------------------------------------------------------------------------------- 1 | #include "WdmLib.h" 2 | 3 | PCUNICODE_STRING getAnswer() 4 | { 5 | static const UNICODE_STRING str = RTL_CONSTANT_STRING(L"42"); 6 | return &str; 7 | } -------------------------------------------------------------------------------- /samples/WdmLib/WdmLib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | PCUNICODE_STRING getAnswer(); --------------------------------------------------------------------------------