Skip to content

Commit 51bb7cd

Browse files
Initial commit.
0 parents  commit 51bb7cd

20 files changed

+445
-0
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/build
2+
/build32
3+
/build64

LICENSE

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# FindWDK
2+
CMake module for building drivers with Windows Development Kit (WDK)
3+
4+
- [Introduction](#introduction)
5+
- [Usage](#usage)
6+
- [Kernel driver](#kernel-driver)
7+
- [Kernel library](#kernel-library)
8+
- [Samples](#samples)
9+
- [License](#license)
10+
- [Version history](#version-history)
11+
12+
# Introduction
13+
FindWDK makes it possible to build kernel drivers and kernel libraries with Windows Development Kit (WDK) and CMake.
14+
15+
Requirements:
16+
- WDK10
17+
- Visual Studio 2012 and higher
18+
- CMake 3.0 and higher
19+
20+
# Usage
21+
Add FindWDK to the module search path and call `find_package`:
22+
23+
```cmake
24+
list(APPEND CMAKE_MODULE_PATH "<path_to_FindWDK>")
25+
find_package(WDK REQUIRED)
26+
```
27+
28+
FindWDK will search for the installed Windows Development Kit (WDK) and expose commands for creating kernel drivers and kernel libraries. Also the following variables will be defined:
29+
- `WDK_FOUND` -- if false, do not try to use WDK
30+
- `WDK_ROOT` -- where WDK is installed
31+
- `WDK_VERSION` -- the version of the selected WDK
32+
- `WDK_WINVER` -- the WINVER used for kernel drivers and libraries (default value is `0x0601` and can be changed per target or globally)
33+
34+
## Kernel driver
35+
The following command adds a kernel driver target called `<name>` to be built from the source files listed in the command invocation:
36+
37+
```cmake
38+
wdk_add_driver(<name>
39+
[EXCLUDE_FROM_ALL]
40+
[KMDF <kmdf_version>]
41+
[WINVER <winver_version>]
42+
source1 [source2 ...]
43+
)
44+
```
45+
46+
Options:
47+
- `EXCLUDE_FROM_ALL` -- exclude from the default build target
48+
- `KMDF <kmdf_version>` -- use KMDF and set KMDF version
49+
- `WINVER <winver_version>` -- use specific WINVER version
50+
51+
Example:
52+
53+
```cmake
54+
wdk_add_driver(KmdfCppDriver
55+
KMDF 1.15
56+
WINVER 0x0602
57+
Main.cpp
58+
)
59+
```
60+
61+
## Kernel library
62+
The following command adds a kernel library target called `<name>` to be built from the source files listed in the command invocation:
63+
64+
```cmake
65+
wdk_add_library(<name> [STATIC | SHARED]
66+
[EXCLUDE_FROM_ALL]
67+
[KMDF <kmdf_version>]
68+
[WINVER <winver_version>]
69+
source1 [source2 ...]
70+
)
71+
```
72+
73+
Options:
74+
- `EXCLUDE_FROM_ALL` -- exclude from the default build target
75+
- `KMDF <kmdf_version>` -- use KMDF and set KMDF version
76+
- `WINVER <winver_version>` -- use specific WINVER version
77+
- `STATIC or SHARED` -- specify the type of library to be created
78+
79+
Example:
80+
81+
```cmake
82+
wdk_add_library(KmdfCppLib STATIC
83+
KMDF 1.15
84+
WINVER 0x0602
85+
KmdfCppLib.h
86+
KmdfCppLib.cpp
87+
)
88+
```
89+
90+
# Samples
91+
Take a look at the [samples](samples) folder to see how WMD and KMDF drivers and libraries are built.
92+
93+
# License
94+
FindWDK is licensed under the OSI-approved 3-clause BSD license. You can freely use it in your commercial or opensource software.
95+
96+
# Version history
97+
98+
## Version 1.0.0 (03 Feb 2018)
99+
- Initial public release

cmake/FindWdk.cmake

+162
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
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+
#
18+
# Example usage:
19+
#
20+
# find_package(WDK REQUIRED)
21+
#
22+
# wdk_add_library(KmdfCppLib STATIC KMDF 1.15
23+
# KmdfCppLib.h
24+
# KmdfCppLib.cpp
25+
# )
26+
# target_include_directories(KmdfCppLib INTERFACE .)
27+
#
28+
# wdk_add_driver(KmdfCppDriver KMDF 1.15
29+
# Main.cpp
30+
# )
31+
# target_link_libraries(KmdfCppDriver KmdfCppLib)
32+
#
33+
34+
file(GLOB WDK_NTDDK_FILES
35+
"C:/Program Files*/Windows Kits/10/Include/*/km/ntddk.h"
36+
)
37+
38+
if(WDK_NTDDK_FILES)
39+
list(GET WDK_NTDDK_FILES -1 WDK_LATEST_NTDDK_FILE)
40+
endif()
41+
42+
include(FindPackageHandleStandardArgs)
43+
find_package_handle_standard_args(WDK REQUIRED_VARS WDK_LATEST_NTDDK_FILE)
44+
45+
get_filename_component(WDK_ROOT ${WDK_LATEST_NTDDK_FILE} DIRECTORY)
46+
get_filename_component(WDK_ROOT ${WDK_ROOT} DIRECTORY)
47+
get_filename_component(WDK_VERSION ${WDK_ROOT} NAME)
48+
get_filename_component(WDK_ROOT ${WDK_ROOT} DIRECTORY)
49+
get_filename_component(WDK_ROOT ${WDK_ROOT} DIRECTORY)
50+
51+
message(STATUS "WDK_ROOT: " ${WDK_ROOT})
52+
message(STATUS "WDK_VERSION: " ${WDK_VERSION})
53+
54+
set(WDK_WINVER "0x0601" CACHE STRING "Default WINVER for WDK targets")
55+
56+
set(WDK_ADDITIONAL_FLAGS_FILE "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/wdkflags.h")
57+
file(WRITE ${WDK_ADDITIONAL_FLAGS_FILE} "#pragma runtime_checks(\"suc\", off)")
58+
59+
set(WDK_COMPILE_FLAGS
60+
"/Zp8" # set struct alignment
61+
"/GF" # enable string pooling
62+
"/GR-" # disable RTTI
63+
"/Gz" # __stdcall by default
64+
"/kernel" # create kernel mode binary
65+
"/FIwarning.h" # disable warnings in WDK headers
66+
"/FI${WDK_ADDITIONAL_FLAGS_FILE}" # include file to disable RTC
67+
)
68+
69+
set(WDK_COMPILE_DEFINITIONS "WINNT=1")
70+
set(WDK_COMPILE_DEFINITIONS_DEBUG "MSC_NOOPT;DEPRECATE_DDK_FUNCTIONS=1;DBG=1")
71+
72+
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
73+
list(APPEND WDK_COMPILE_DEFINITIONS "_X86_=1;i386=1;STD_CALL")
74+
set(WDK_PLATFORM "x86")
75+
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
76+
list(APPEND WDK_COMPILE_DEFINITIONS "_WIN64;_AMD64_;AMD64")
77+
set(WDK_PLATFORM "x64")
78+
else()
79+
message(FATAL_ERROR "Unsupported architecture")
80+
endif()
81+
82+
string(CONCAT WDK_LINK_FLAGS
83+
"/MANIFEST:NO " #
84+
"/DRIVER " #
85+
"/OPT:REF " #
86+
"/INCREMENTAL:NO " #
87+
"/OPT:ICF " #
88+
"/SUBSYSTEM:NATIVE " #
89+
"/MERGE:_TEXT=.text;_PAGE=PAGE " #
90+
"/NODEFAULTLIB " # do not link default CRT
91+
"/SECTION:INIT,d " #
92+
"/VERSION:10.0 " #
93+
)
94+
95+
function(wdk_add_driver _target)
96+
cmake_parse_arguments(WDK "" "KMDF;WINVER" "" ${ARGN})
97+
98+
add_executable(${_target} ${WDK_UNPARSED_ARGUMENTS})
99+
100+
set_target_properties(${_target} PROPERTIES SUFFIX ".sys")
101+
set_target_properties(${_target} PROPERTIES COMPILE_OPTIONS "${WDK_COMPILE_FLAGS}")
102+
set_target_properties(${_target} PROPERTIES COMPILE_DEFINITIONS
103+
"${WDK_COMPILE_DEFINITIONS};$<$<CONFIG:Debug>:${WDK_COMPILE_DEFINITIONS_DEBUG}>;_WIN32_WINNT=${WDK_WINVER}"
104+
)
105+
set_target_properties(${_target} PROPERTIES LINK_FLAGS "${WDK_LINK_FLAGS}")
106+
107+
target_include_directories(${_target} SYSTEM PRIVATE
108+
"${WDK_ROOT}/Include/${WDK_VERSION}/shared"
109+
"${WDK_ROOT}/Include/${WDK_VERSION}/km"
110+
)
111+
112+
target_link_libraries(${_target}
113+
"${WDK_ROOT}/Lib/${WDK_VERSION}/km/${WDK_PLATFORM}/ntoskrnl.lib"
114+
"${WDK_ROOT}/Lib/${WDK_VERSION}/km/${WDK_PLATFORM}/hal.lib"
115+
"${WDK_ROOT}/Lib/${WDK_VERSION}/km/${WDK_PLATFORM}/BufferOverflowK.lib"
116+
"${WDK_ROOT}/Lib/${WDK_VERSION}/km/${WDK_PLATFORM}/wmilib.lib"
117+
)
118+
119+
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
120+
target_link_libraries(${_target} "${WDK_ROOT}/Lib/${WDK_VERSION}/km/${WDK_PLATFORM}/memcmp.lib")
121+
endif()
122+
123+
if(DEFINED WDK_KMDF)
124+
target_include_directories(${_target} SYSTEM PRIVATE "${WDK_ROOT}/Include/wdf/kmdf/${WDK_KMDF}")
125+
target_link_libraries(${_target}
126+
"${WDK_ROOT}/Lib/wdf/kmdf/${WDK_PLATFORM}/${WDK_KMDF}/WdfDriverEntry.lib"
127+
"${WDK_ROOT}/Lib/wdf/kmdf/${WDK_PLATFORM}/${WDK_KMDF}/WdfLdr.lib"
128+
)
129+
130+
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
131+
set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:FxDriverEntry@8")
132+
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
133+
set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:FxDriverEntry")
134+
endif()
135+
else()
136+
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
137+
set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:GsDriverEntry@8")
138+
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
139+
set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:GsDriverEntry")
140+
endif()
141+
endif()
142+
endfunction()
143+
144+
function(wdk_add_library _target)
145+
cmake_parse_arguments(WDK "" "KMDF;WINVER" "" ${ARGN})
146+
147+
add_library(${_target} ${WDK_UNPARSED_ARGUMENTS})
148+
149+
set_target_properties(${_target} PROPERTIES COMPILE_OPTIONS "${WDK_COMPILE_FLAGS}")
150+
set_target_properties(${_target} PROPERTIES COMPILE_DEFINITIONS
151+
"${WDK_COMPILE_DEFINITIONS};$<$<CONFIG:Debug>:${WDK_COMPILE_DEFINITIONS_DEBUG};_WIN32_WINNT=${WDK_WINVER}>"
152+
)
153+
154+
target_include_directories(${_target} SYSTEM PRIVATE
155+
"${WDK_ROOT}/Include/${WDK_VERSION}/shared"
156+
"${WDK_ROOT}/Include/${WDK_VERSION}/km"
157+
)
158+
159+
if(DEFINED WDK_KMDF)
160+
target_include_directories(${_target} SYSTEM PRIVATE "${WDK_ROOT}/Include/wdf/kmdf/${WDK_KMDF}")
161+
endif()
162+
endfunction()

samples/CMakeLists.txt

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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+
9+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../cmake")
10+
find_package(WDK REQUIRED)
11+
12+
add_subdirectory(KmdfCppDriver)
13+
add_subdirectory(KmdfCppLib)
14+
add_subdirectory(WdmCppDriver)
15+
add_subdirectory(WdmCppLib)
16+
add_subdirectory(WdmDriver)
17+
add_subdirectory(WdmLib)

samples/KmdfCppDriver/CMakeLists.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
wdk_add_driver(KmdfCppDriver
2+
KMDF 1.15
3+
Main.cpp
4+
)
5+
target_link_libraries(KmdfCppDriver KmdfCppLib)

samples/KmdfCppDriver/Main.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <wdm.h>
2+
#include <wdf.h>
3+
#include "KmdfCppLib.h"
4+
5+
EVT_WDF_DRIVER_UNLOAD evtDriverUnload;
6+
VOID evtDriverUnload(_In_ WDFDRIVER /*driver*/)
7+
{
8+
DbgPrint("Driver unloaded\n");
9+
}
10+
11+
extern "C" DRIVER_INITIALIZE DriverEntry;
12+
extern "C" NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING registryPath)
13+
{
14+
DbgPrint("Driver loaded\n");
15+
16+
WDF_DRIVER_CONFIG config;
17+
WDF_DRIVER_CONFIG_INIT(&config, nullptr);
18+
config.EvtDriverUnload = evtDriverUnload;
19+
20+
NTSTATUS status = WdfDriverCreate(driverObject, registryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE);
21+
if (!NT_SUCCESS(status))
22+
{
23+
return status;
24+
}
25+
26+
UNICODE_STRING answer = {};
27+
WdfStringGetUnicodeString(getAnswer(), &answer);
28+
DbgPrint("The answer is %wZ\n", answer);
29+
30+
return STATUS_SUCCESS;
31+
}

samples/KmdfCppLib/CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
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

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include "KmdfCppLib.h"
2+
3+
WDFSTRING getAnswer()
4+
{
5+
static const UNICODE_STRING str = RTL_CONSTANT_STRING(L"42");
6+
7+
WDFSTRING wdfstr = nullptr;
8+
NTSTATUS status = WdfStringCreate(&str, WDF_NO_OBJECT_ATTRIBUTES, &wdfstr);
9+
if (!NT_SUCCESS(status))
10+
{
11+
return nullptr;
12+
}
13+
14+
return wdfstr;
15+
}

samples/KmdfCppLib/KmdfCppLib.h

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#pragma once
2+
#include <wdm.h>
3+
#include <wdf.h>
4+
5+
WDFSTRING getAnswer();

samples/WdmCppDriver/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
wdk_add_driver(WdmCppDriver
2+
Main.cpp
3+
)
4+
target_link_libraries(WdmCppDriver WdmCppLib)

0 commit comments

Comments
 (0)