├── .clang-format ├── .github └── workflows │ └── cmake.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── build.bat ├── build_all.bat ├── cmake ├── CPM.cmake ├── CrtSys.cmake ├── pkg-utils.cmake └── std-cxx.cmake ├── docs └── ko-kr.md ├── include ├── .internal │ ├── adjust_link_order │ ├── msvc │ │ ├── 143 │ │ │ └── stl │ │ │ │ └── mutex │ │ └── 14.29.30133 │ │ │ └── stl │ │ │ └── mutex │ ├── version │ └── winsdk │ │ └── 10.0.17763.0 │ │ └── wdk │ │ └── 10.0.22000.0 │ │ └── forced.h └── ntl │ ├── deps │ └── zpp │ │ └── serializer.h │ ├── device │ ├── driver │ ├── except │ ├── expand_stack │ ├── irql │ ├── resource │ ├── rpc │ ├── client │ ├── common │ └── server │ ├── spin_lock │ ├── status │ └── unicode_string ├── src ├── crtsys.h ├── custom │ ├── crt │ │ ├── fenv │ │ │ └── fenv.c │ │ ├── io.c │ │ ├── isa_available_init.c │ │ ├── math │ │ │ ├── fpclassify.c │ │ │ ├── fpconst.c │ │ │ ├── ftol3.c │ │ │ ├── nextafter.c │ │ │ └── pow.c │ │ ├── misc.c │ │ └── setlocal.h │ ├── misc │ │ ├── chandler3_noexcept.cpp │ │ ├── chandler4_noexcept.cpp │ │ ├── misc.cpp │ │ ├── riscchandler_noexcept.cpp │ │ └── winapi.cpp │ ├── msvc │ │ ├── 141 │ │ │ ├── crt │ │ │ │ └── src │ │ │ │ │ ├── ehhelpers.h │ │ │ │ │ ├── i386 │ │ │ │ │ └── trnsctrl_redirect.cpp │ │ │ │ │ ├── misc │ │ │ │ │ └── cfg_support.inc │ │ │ │ │ ├── stl │ │ │ │ │ └── awint.h │ │ │ │ │ └── vcruntime │ │ │ │ │ ├── frame_redirect.cpp │ │ │ │ │ ├── std_type_info.cpp │ │ │ │ │ └── trnsctrl.h │ │ │ └── include │ │ │ │ ├── ehassert.h │ │ │ │ ├── ehdata4.h │ │ │ │ ├── ehdata4_export.h │ │ │ │ ├── ehhooks.h │ │ │ │ └── vcwininternls.h │ │ ├── 142 │ │ │ ├── crt │ │ │ │ └── src │ │ │ │ │ ├── ehhelpers.h │ │ │ │ │ ├── i386 │ │ │ │ │ └── trnsctrl_redirect.cpp │ │ │ │ │ ├── misc │ │ │ │ │ └── cfg_support.inc │ │ │ │ │ └── vcruntime │ │ │ │ │ ├── frame_redirect.cpp │ │ │ │ │ └── std_type_info.cpp │ │ │ └── include │ │ │ │ ├── arm64 │ │ │ │ └── arm64asmsymbolname.h │ │ │ │ ├── ehassert.h │ │ │ │ ├── ehhooks.h │ │ │ │ └── vcwininternls.h │ │ ├── 143 │ │ │ ├── crt │ │ │ │ └── src │ │ │ │ │ ├── ehhelpers.h │ │ │ │ │ ├── i386 │ │ │ │ │ └── trnsctrl_redirect.cpp │ │ │ │ │ ├── misc │ │ │ │ │ └── cfg_support.inc │ │ │ │ │ └── vcruntime │ │ │ │ │ ├── frame_redirect.cpp │ │ │ │ │ └── std_type_info.cpp │ │ │ └── include │ │ │ │ ├── arm64 │ │ │ │ └── arm64asmsymbolname.h │ │ │ │ ├── ehassert.h │ │ │ │ ├── ehhooks.h │ │ │ │ └── vcwininternls.h │ │ ├── common │ │ │ └── crt │ │ │ │ └── src │ │ │ │ └── stl │ │ │ │ └── winapisupp.cpp │ │ └── crt.props │ ├── private │ │ ├── ehassert.h │ │ ├── ehhooks.h │ │ └── vcwininternls.h │ ├── ucrt │ │ ├── .clang-format │ │ ├── 10.0.17763.0 │ │ │ └── inc │ │ │ │ ├── corecrt_internal_state_isolation.h │ │ │ │ ├── nt.h │ │ │ │ ├── ntrtl.h │ │ │ │ └── nturtl.h │ │ ├── 10.0.19041.0 │ │ │ └── inc │ │ │ │ ├── corecrt_internal_state_isolation.h │ │ │ │ ├── nt.h │ │ │ │ ├── ntrtl.h │ │ │ │ └── nturtl.h │ │ ├── 10.0.22000.0 │ │ │ └── inc │ │ │ │ ├── corecrt_internal_state_isolation.h │ │ │ │ ├── nt.h │ │ │ │ ├── ntrtl.h │ │ │ │ └── nturtl.h │ │ ├── 10.0.22621.0 │ │ │ └── inc │ │ │ │ ├── corecrt_internal_state_isolation.h │ │ │ │ ├── nt.h │ │ │ │ ├── ntrtl.h │ │ │ │ └── nturtl.h │ │ └── common │ │ │ ├── internal │ │ │ └── winapi_thunks.cpp │ │ │ └── startup │ │ │ └── argv_parsing.cpp │ └── winsdk │ │ └── include │ │ └── um │ │ └── crtsys │ │ ├── WinBase.h │ │ ├── WinNls.h │ │ ├── WinUser.h │ │ ├── Windows.h │ │ ├── combaseapi.h │ │ ├── commdlg.h │ │ ├── datetimeapi.h │ │ ├── fileapi.h │ │ ├── processthreadsapi.h │ │ ├── prsht.h │ │ ├── stringapiset.h │ │ ├── synchapi.h │ │ └── winternl.h ├── main.cpp ├── stl.props ├── ucrt.props ├── ucrt_for_ucxxrt.props └── vcruntime.props └── test ├── app ├── CMakeLists.txt └── src │ └── main.cpp ├── build.bat ├── common ├── rpc.hpp └── test_device.h └── driver ├── CMakeLists.txt └── src ├── all.cpp ├── c └── math.c ├── cpp ├── lang │ ├── exceptions.cpp │ └── initialization.cpp └── stl │ ├── chrono.cpp │ └── thread.cpp ├── libs └── nlohmann_json.cpp ├── main.cpp └── ntl.cpp /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM -------------------------------------------------------------------------------- /.github/workflows/cmake.yml: -------------------------------------------------------------------------------- 1 | name: CMake 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | matrix: 14 | os: [windows-2019] 15 | 16 | defaults: 17 | run: 18 | working-directory: test 19 | 20 | steps: 21 | - uses: actions/checkout@v2 22 | with: 23 | submodules: true 24 | 25 | - name: build app x86 26 | shell: cmd 27 | run: ..\build.bat app x86 28 | working-directory: test 29 | 30 | - name: build app x64 31 | shell: cmd 32 | run: ..\build.bat app x64 33 | working-directory: test 34 | 35 | - name: build app ARM 36 | shell: cmd 37 | run: ..\build.bat app ARM 38 | working-directory: test 39 | 40 | - name: build app ARM64 41 | shell: cmd 42 | run: ..\build.bat app ARM64 43 | working-directory: test 44 | 45 | - name: build driver x86 46 | shell: cmd 47 | run: ..\build.bat driver x86 48 | working-directory: test 49 | 50 | - name: build driver x64 51 | shell: cmd 52 | run: ..\build.bat driver x64 53 | working-directory: test 54 | 55 | - name: build driver ARM 56 | shell: cmd 57 | run: ..\build.bat driver ARM 58 | working-directory: test 59 | 60 | - name: build driver ARM64 61 | shell: cmd 62 | run: ..\build.bat driver ARM64 63 | working-directory: test 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build*/ 2 | .vscode 3 | .vs/ 4 | lib/ -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | 3 | # INCLUDE_DIRECTORIES $(VC_IncludePath);$(WindowsSDK_IncludePath) 4 | cmake_policy(SET CMP0021 OLD) 5 | 6 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") 7 | include(pkg-utils) 8 | 9 | pkg_get_version(CRTSYS ${CMAKE_CURRENT_SOURCE_DIR}/include/.internal/version VERSION) 10 | 11 | project( 12 | crtsys 13 | VERSION "${VERSION}" 14 | DESCRIPTION "C Runtime Lbrary for Windows driver file (*.sys)" 15 | HOMEPAGE_URL "https://github.com/ntoskrnl7/crtsys" 16 | LANGUAGES C CXX ASM_MASM 17 | ) 18 | 19 | option(CRTSYS_NTL_MAIN "Set to ON to use ntl::main" ON) 20 | option(CRTSYS_USE_LIBCNTPR "Set to ON to use libcntpr" ON) 21 | 22 | # x64 is always set to use libcntpr. (_NLG_Notify, _NLG_Return2) 23 | if ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64") 24 | set(CRTSYS_USE_LIBCNTPR ON) 25 | endif() 26 | 27 | if(MSVC_TOOLSET_VERSION EQUAL 142 OR MSVC_TOOLSET_VERSION EQUAL 143) 28 | set(UCXXRT_ENABLED OFF) 29 | else() 30 | set(UCXXRT_ENABLED ON) 31 | endif() 32 | 33 | include(cmake/CPM.cmake) 34 | 35 | if ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64") 36 | set(LDK_USE_RAISE_EXCEPTION ON) 37 | set(LDK_USE_RTL_RAISE_EXCEPTION ON) 38 | else() 39 | set(LDK_USE_RAISE_EXCEPTION OFF) 40 | set(LDK_USE_RTL_RAISE_EXCEPTION OFF) 41 | endif() 42 | CPMAddPackage("gh:ntoskrnl7/Ldk@0.7.5") 43 | 44 | CPMAddPackage("gh:ntoskrnl7/FindWDK#master") 45 | list(APPEND CMAKE_MODULE_PATH "${FindWDK_SOURCE_DIR}/cmake") 46 | find_package(WDK REQUIRED) 47 | 48 | # 49 | # Add source files. 50 | # 51 | 52 | file(GLOB SOURCE_FILES 53 | src/*.cpp 54 | 55 | # misc 56 | src/custom/misc/*.cpp 57 | src/custom/misc/*.c 58 | 59 | # crt 60 | src/custom/crt/*.c 61 | src/custom/crt/fenv/*.c 62 | 63 | # ucrt 64 | src/custom/ucrt/common/*.cpp 65 | src/custom/ucrt/common/*/*.cpp 66 | 67 | # ucrt 68 | src/custom/ucrt/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}/*.cpp 69 | src/custom/ucrt/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}/*/*.cpp 70 | ) 71 | 72 | if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32") 73 | file(GLOB MATH_SOURCE_FILES 74 | src/custom/crt/math/*.c 75 | ) 76 | list(APPEND SOURCE_FILES ${MATH_SOURCE_FILES}) 77 | else() 78 | file(GLOB MATH_SOURCE_FILES 79 | src/custom/crt/math/nextafter.c 80 | src/custom/crt/math/fpclassify.c 81 | ) 82 | list(APPEND SOURCE_FILES ${MATH_SOURCE_FILES}) 83 | endif() 84 | 85 | if (UCXXRT_ENABLED) 86 | list(APPEND SOURCE_FILES src/custom/msvc/common/crt/src/stl/winapisupp.cpp) 87 | list(REMOVE_ITEM SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/custom/crt/math/ftol3.c) 88 | 89 | CPMAddPackage("gh:ntoskrnl7/ucxxrt#master") 90 | 91 | file(GLOB_RECURSE UCXXRT_SOURCE_FILES 92 | ${ucxxrt_SOURCE_DIR}/src/*.cpp 93 | ${ucxxrt_SOURCE_DIR}/vcruntime/*.cpp 94 | ${ucxxrt_SOURCE_DIR}/misc/*.cpp 95 | ) 96 | list(REMOVE_ITEM UCXXRT_SOURCE_FILES ${ucxxrt_SOURCE_DIR}/src/vcruntime/crt.cpp) 97 | list(REMOVE_ITEM UCXXRT_SOURCE_FILES ${ucxxrt_SOURCE_DIR}/src/vcruntime/locales.cpp) 98 | list(REMOVE_ITEM UCXXRT_SOURCE_FILES ${ucxxrt_SOURCE_DIR}/src/vcruntime/thread.cpp) 99 | if(NOT "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32" AND NOT "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64" ) 100 | list(REMOVE_ITEM UCXXRT_SOURCE_FILES ${ucxxrt_SOURCE_DIR}/src/vcruntime/x86_exception_filter.cpp) 101 | endif() 102 | list(REMOVE_ITEM UCXXRT_SOURCE_FILES ${ucxxrt_SOURCE_DIR}/src/cpu_disp.cpp) 103 | list(REMOVE_ITEM UCXXRT_SOURCE_FILES ${ucxxrt_SOURCE_DIR}/src/terminate.cpp) 104 | list(REMOVE_ITEM UCXXRT_SOURCE_FILES ${ucxxrt_SOURCE_DIR}/src/misc/invalid_parameter.cpp) 105 | list(REMOVE_ITEM UCXXRT_SOURCE_FILES ${ucxxrt_SOURCE_DIR}/src/sys_main.cpp) 106 | list(REMOVE_ITEM UCXXRT_SOURCE_FILES ${ucxxrt_SOURCE_DIR}/src/unittest.cpp) 107 | if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64") 108 | file(GLOB PLATFORM_SOURCE_FILES 109 | ${ucxxrt_SOURCE_DIR}/src/x64/*.cpp 110 | ${ucxxrt_SOURCE_DIR}/src/x64/*.asm 111 | ) 112 | elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32") 113 | file(GLOB PLATFORM_SOURCE_FILES 114 | ${ucxxrt_SOURCE_DIR}/src/i386/*.cpp 115 | ${ucxxrt_SOURCE_DIR}/src/i386/*.asm 116 | ) 117 | endif() 118 | list(APPEND UCXXRT_SOURCE_FILES ${PLATFORM_SOURCE_FILES}) 119 | 120 | list(APPEND SOURCE_FILES ${UCXXRT_SOURCE_FILES}) 121 | endif() 122 | 123 | wdk_add_library( 124 | crtsys 125 | EXTENDED_CPP_FEATURES 126 | STATIC 127 | ${SOURCE_FILES} 128 | ) 129 | 130 | # 131 | # Add include directories 132 | # 133 | get_target_property(INC_DIR_TMP crtsys INCLUDE_DIRECTORIES) 134 | if (UCXXRT_ENABLED) 135 | set_property(TARGET crtsys PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/src/custom/winsdk/include/um/crtsys;${Ldk_SOURCE_DIR}/include/Ldk;${ucxxrt_SOURCE_DIR}/src;${ucxxrt_SOURCE_DIR}/src/vcruntime;$(VC_IncludePath);$(WindowsSDK_IncludePath);${INC_DIR_TMP}") 136 | target_include_directories(crtsys PRIVATE "${ucxxrt_SOURCE_DIR}") 137 | else() 138 | set_property(TARGET crtsys PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/src/custom/winsdk/include/um/crtsys;${Ldk_SOURCE_DIR}/include/Ldk;$(VC_IncludePath);$(WindowsSDK_IncludePath);${INC_DIR_TMP}") 139 | endif() 140 | 141 | target_include_directories(crtsys PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/custom/msvc/${MSVC_TOOLSET_VERSION}/include") 142 | target_include_directories(crtsys PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/custom/msvc/${MSVC_TOOLSET_VERSION}/crt/src/vcruntime") 143 | target_include_directories(crtsys PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/custom/msvc/${MSVC_TOOLSET_VERSION}/crt/src/stl") 144 | target_include_directories(crtsys BEFORE PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/custom/ucrt/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}/inc") 145 | 146 | # 147 | # link libraries 148 | # 149 | target_link_libraries(crtsys PRIVATE $) 150 | if(CRTSYS_USE_LIBCNTPR) 151 | target_link_libraries(crtsys PRIVATE WDK::LIBCNTPR) 152 | endif() 153 | 154 | # 155 | # Add compile definitions 156 | # 157 | target_compile_definitions(crtsys PUBLIC "_KERNEL32_") 158 | target_compile_definitions(crtsys PUBLIC "_ITERATOR_DEBUG_LEVEL=0") 159 | if (CRTSYS_USE_LIBCNTPR) 160 | target_compile_definitions(crtsys PUBLIC "CRTSYS_USE_LIBCNTPR") 161 | if ("${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}" VERSION_GREATER_EQUAL "10.0.22000.0") 162 | target_compile_definitions(crtsys PRIVATE "CRTSYS_NEED_CRT_IOB_FUNC") 163 | target_compile_definitions(crtsys PRIVATE "CRTSYS_NEED_CRT_ABORT") 164 | endif() 165 | else() 166 | target_compile_definitions(crtsys PRIVATE "CRTSYS_NEED_CRT_IOB_FUNC") 167 | target_compile_definitions(crtsys PRIVATE "CRTSYS_NEED_CRT_ABORT") 168 | endif() 169 | if (CRTSYS_NTL_MAIN) 170 | target_compile_definitions(crtsys PUBLIC CRTSYS_USE_NTL_MAIN) 171 | endif() 172 | target_compile_definitions(crtsys PUBLIC "_HAS_EXCEPTIONS") 173 | if (UCXXRT_ENABLED) 174 | target_compile_definitions(crtsys PUBLIC "UCXXRT") 175 | target_compile_definitions(crtsys PRIVATE "__KERNEL_MODE") 176 | endif() 177 | 178 | # 179 | # Forced Include File 180 | # 181 | if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/include/.internal/winsdk/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}/wdk/${WDK_VERSION}/forced.h") 182 | target_compile_options(crtsys PRIVATE /FI"${CMAKE_CURRENT_SOURCE_DIR}/include/.internal/winsdk/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}/wdk/${WDK_VERSION}/forced.h") 183 | endif() 184 | target_compile_options(crtsys PRIVATE /FI"${CMAKE_CURRENT_SOURCE_DIR}/src/crtsys.h") 185 | if (UCXXRT_ENABLED) 186 | target_compile_options(crtsys PRIVATE /FI"${ucxxrt_SOURCE_DIR}/ucxxrt.inl") 187 | endif() 188 | 189 | # 190 | # TLS isn't supported yet. 191 | # 192 | target_compile_options(crtsys PUBLIC /Zc:threadSafeInit-) 193 | 194 | target_compile_options(crtsys PUBLIC "/MT") # "/MT$<$:d>" 195 | # [not working] set_property(TARGET crtsys PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") 196 | 197 | # 198 | # Generate Debug Info 199 | # 200 | target_compile_options(crtsys PUBLIC "$<$:/Zi>") 201 | target_link_options(crtsys PUBLIC "$<$:/DEBUG>") 202 | 203 | # 204 | # Force File Output 205 | # 206 | if (CRTSYS_USE_LIBCNTPR) 207 | # 10.0.17763.0 208 | # 10.0.22000.0 209 | # km/x64/libcntpr.lib(fpexcept.obj) : error LNK2005: RaiseException already defined in Ldk.lib(errhandlingapi.obj) 210 | 211 | # 10.0.17763.0 212 | # km/x64/ntoskrnl.lib(ntoskrnl.exe) : error LNK2005: _wcslen already defined in km/x64/libcntpr.lib(wcslen.obj) 213 | 214 | # 10.0.17763.0 215 | # libcntpr.lib fflush 216 | # src\custom\ucrt\common\stdio\fflush.cpp fflush 217 | target_link_options(crtsys PUBLIC "/FORCE:MULTIPLE") 218 | elseif(UCXXRT_ENABLED AND "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64") 219 | # ntoskrnl.lib(ntoskrnl.exe) : error LNK2005: RtlRaiseException already defined in Ldk.lib(except.obj). 220 | target_link_options(crtsys PUBLIC "/FORCE:MULTIPLE") 221 | endif() 222 | 223 | if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32") 224 | # crtsys.lib(lowhelpr.obj) : error LNK2026: module unsafe for SAFESEH image. 225 | target_link_options(crtsys PUBLIC "/SAFESEH:NO") 226 | 227 | # Remove Runtime Checks 228 | string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") 229 | string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") 230 | string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") 231 | string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}") 232 | string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") 233 | endif() 234 | 235 | # 236 | # set visual studio properties file 237 | # 238 | if (UCXXRT_ENABLED) 239 | list(APPEND VS_PROPS "${CMAKE_CURRENT_SOURCE_DIR}/src/ucrt_for_ucxxrt.props") 240 | else() 241 | list(APPEND VS_PROPS "${CMAKE_CURRENT_SOURCE_DIR}/src/vcruntime.props;${CMAKE_CURRENT_SOURCE_DIR}/src/custom/msvc/crt.props;${CMAKE_CURRENT_SOURCE_DIR}/src/ucrt.props") 242 | endif() 243 | set_target_properties(crtsys PROPERTIES VS_USER_PROPS "${CMAKE_CURRENT_SOURCE_DIR}/src/stl.props;${VS_PROPS}") 244 | 245 | # 246 | # set library output path (release only) 247 | # 248 | string(TOLOWER "${CMAKE_VS_PLATFORM_NAME}" PLATFROM_SHORT_NAME) 249 | if(PLATFROM_SHORT_NAME STREQUAL "win32") 250 | set(PLATFROM_SHORT_NAME "x86") 251 | endif() 252 | set_target_properties(crtsys PROPERTIES ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/lib/${PLATFROM_SHORT_NAME}) 253 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 ntoskrnl7 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | @REM build.bat "PATH" "x86 | x64" | "ARM" | "ARM64" [Debug (default) | Release] 2 | @REM build.bat "PATH" "2017 | 2019 | 2022" "x86 | x64" | "ARM" | "ARM64" 3 | @REM build.bat "PATH" "2017 | 2019 | 2022" "x86 | x64" | "ARM" | "ARM64" [Debug (default) | Release] 4 | 5 | @ECHO OFF 6 | 7 | SETLOCAL ENABLEDELAYEDEXPANSION 8 | 9 | IF EXIST "%1/CMakeLists.txt" ( 10 | SET WORK_PATH=%1 11 | IF /I "%2" == "x86" ( 12 | SET ARCH=Win32 13 | SET ARCH_NAME=x86 14 | ) 15 | IF /I "%2" == "x64" ( 16 | SET ARCH=x64 17 | SET ARCH_NAME=x64 18 | ) 19 | IF /I "%2" == "Win32" ( 20 | SET ARCH=Win32 21 | SET ARCH_NAME=x86 22 | ) 23 | IF /I "%2" == "Win64" ( 24 | SET ARCH=x64 25 | SET ARCH_NAME=x64 26 | ) 27 | IF /I "%2" == "ARM" ( 28 | SET ARCH=ARM 29 | SET ARCH_NAME=ARM 30 | ) 31 | IF /I "%2" == "ARM64" ( 32 | SET ARCH=ARM64 33 | SET ARCH_NAME=ARM64 34 | ) 35 | IF /I "%3" == "Debug" ( 36 | SET CONFIG=Debug 37 | ) 38 | IF /I "%3" == "Release" ( 39 | SET CONFIG=Release 40 | ) 41 | SET BUILD_PATH=!WORK_PATH!/build_!ARCH_NAME! 42 | 43 | IF /I "!ARCH!" == "" ( 44 | IF %2 == 2017 ( 45 | SET GENERATOR="Visual Studio 15 2017" 46 | SET VS_VERSION=2017 47 | ) 48 | IF %2 == 2019 ( 49 | SET GENERATOR="Visual Studio 16 2019" 50 | SET VS_VERSION=2019 51 | ) 52 | IF %2 == 2022 ( 53 | SET GENERATOR="Visual Studio 17 2022" 54 | SET VS_VERSION=2022 55 | ) 56 | IF /I "%3" == "x86" ( 57 | SET ARCH=Win32 58 | SET ARCH_NAME=x86 59 | ) 60 | IF /I "%3" == "x64" ( 61 | SET ARCH=x64 62 | SET ARCH_NAME=x64 63 | ) 64 | IF /I "%3" == "Win32" ( 65 | SET ARCH=Win32 66 | SET ARCH_NAME=x86 67 | ) 68 | IF /I "%3" == "Win64" ( 69 | SET ARCH=x64 70 | SET ARCH_NAME=x64 71 | ) 72 | IF /I "%3" == "ARM" ( 73 | SET ARCH=ARM 74 | SET ARCH_NAME=ARM 75 | ) 76 | IF /I "%3" == "ARM64" ( 77 | SET ARCH=ARM64 78 | SET ARCH_NAME=ARM64 79 | ) 80 | IF "!VS_VERSION!" == "" ( 81 | SET BUILD_PATH=!WORK_PATH!/build_!ARCH_NAME! 82 | ) ELSE ( 83 | SET BUILD_PATH=!WORK_PATH!/build_!VS_VERSION!_!ARCH_NAME! 84 | ) 85 | IF /I "%4" == "Debug" ( 86 | SET CONFIG=Debug 87 | ) 88 | IF /I "%4" == "Release" ( 89 | SET CONFIG=Release 90 | ) 91 | ) 92 | 93 | IF NOT "!ARCH!" == "" ( 94 | IF "!GENERATOR!" == "" ( 95 | ECHO Unsupported Visual Studio. 96 | ECHO Use Visual Studio set as CMake default generator. 97 | ECHO cmake -S !WORK_PATH! -B !BUILD_PATH! -A !ARCH! -DCMAKE_CXX_FLAGS=/MP 98 | cmake -S !WORK_PATH! -B !BUILD_PATH! -A !ARCH! -DCMAKE_CXX_FLAGS=/MP 99 | ) ELSE ( 100 | ECHO cmake -S !WORK_PATH! -B !BUILD_PATH! -A !ARCH! -DCMAKE_CXX_FLAGS=/MP -G !GENERATOR! 101 | cmake -S !WORK_PATH! -B !BUILD_PATH! -A !ARCH! -DCMAKE_CXX_FLAGS=/MP -G !GENERATOR! 102 | ) 103 | IF "!CONFIG!" == "" ( 104 | ECHO cmake --build !BUILD_PATH! 105 | cmake --build !BUILD_PATH! 106 | ) ELSE ( 107 | ECHO cmake --build !BUILD_PATH! --config !CONFIG! 108 | cmake --build !BUILD_PATH! --config !CONFIG! 109 | ) 110 | ) ELSE ( 111 | ECHO Unsupported architecture. 112 | ) 113 | ) ELSE ( 114 | ECHO "%1/CMakeLists.txt not exist" 115 | ) 116 | ENDLOCAL -------------------------------------------------------------------------------- /build_all.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SETLOCAL ENABLEDELAYEDEXPANSION 4 | 5 | IF EXIST "%1/CMakeLists.txt" ( 6 | IF "%2" == "" ( 7 | ( 8 | START cmake -S %1 cmake -B %1/build_2017_x64 -A x64 -G "Visual Studio 15 2017" 9 | START cmake -S %1 cmake -B %1/build_2017_x86 -A Win32 -G "Visual Studio 15 2017" 10 | START cmake -S %1 cmake -B %1/build_2019_x64 -A x64 -G "Visual Studio 16 2019" 11 | START cmake -S %1 cmake -B %1/build_2019_x86 -A Win32 -G "Visual Studio 16 2019" 12 | START cmake -S %1 cmake -B %1/build_2022_x64 -A x64 -G "Visual Studio 17 2022" 13 | START cmake -S %1 cmake -B %1/build_2022_x86 -A Win32 -G "Visual Studio 17 2022" 14 | 15 | START cmake -S %1 cmake -B %1/build_2017_ARM64 -A ARM64 -G "Visual Studio 15 2017" 16 | START cmake -S %1 cmake -B %1/build_2017_ARM -A ARM -G "Visual Studio 15 2017" 17 | START cmake -S %1 cmake -B %1/build_2019_ARM64 -A ARM64 -G "Visual Studio 16 2019" 18 | START cmake -S %1 cmake -B %1/build_2019_ARM -A ARM -G "Visual Studio 16 2019" 19 | START cmake -S %1 cmake -B %1/build_2022_ARM64 -A ARM64 -G "Visual Studio 17 2022" 20 | START cmake -S %1 cmake -B %1/build_2022_ARM -A ARM -G "Visual Studio 17 2022" 21 | ) | PAUSE 22 | START build_all.bat %1 Debug 23 | START build_all.bat %1 Release 24 | ) 25 | IF /I "%2" == "Release" ( 26 | START CMD /C "build.bat %1 2022 x64 Release && build.bat %1 2019 x64 Release && build.bat %1 2017 x64 Release" 27 | START CMD /C "build.bat %1 2022 x86 Release && build.bat %1 2019 x86 Release && build.bat %1 2017 x86 Release" 28 | START CMD /C "build.bat %1 2022 ARM64 Release && build.bat %1 2019 ARM64 Release && build.bat %1 2017 ARM64 Release" 29 | START CMD /C "build.bat %1 2022 ARM Release && build.bat %1 2019 ARM Release && build.bat %1 2017 ARM Release" 30 | ) 31 | IF /I "%2" == "Debug" ( 32 | START "2022 x64 Debug" build.bat %1 2022 x64 Debug 33 | START "2022 x86 Debug" build.bat %1 2022 x86 Debug 34 | START "2019 x64 Debug" build.bat %1 2019 x64 Debug 35 | START "2019 x86 Debug" build.bat %1 2019 x86 Debug 36 | START "2017 x64 Debug" build.bat %1 2017 x64 Debug 37 | START "2017 x86 Debug" build.bat %1 2017 x86 Debug 38 | START "2022 ARM64 Debug" build.bat %1 2022 ARM64 Debug 39 | START "2022 ARM Debug" build.bat %1 2022 ARM Debug 40 | START "2019 ARM64 Debug" build.bat %1 2019 ARM64 Debug 41 | START "2019 ARM Debug" build.bat %1 2019 ARM Debug 42 | START "2017 ARM64 Debug" build.bat %1 2017 ARM64 Debug 43 | START "2017 ARM Debug" build.bat %1 2017 ARM Debug 44 | ) 45 | ) ELSE ( 46 | ECHO "%1/CMakeLists.txt not exist" 47 | ) 48 | 49 | ENDLOCAL -------------------------------------------------------------------------------- /cmake/CPM.cmake: -------------------------------------------------------------------------------- 1 | set(CPM_DOWNLOAD_VERSION 0.32.0) 2 | 3 | if(CPM_SOURCE_CACHE) 4 | # Expand relative path. This is important if the provided path contains a tilde (~) 5 | get_filename_component(CPM_SOURCE_CACHE ${CPM_SOURCE_CACHE} ABSOLUTE) 6 | set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") 7 | elseif(DEFINED ENV{CPM_SOURCE_CACHE}) 8 | set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") 9 | else() 10 | set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") 11 | endif() 12 | 13 | if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION})) 14 | message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}") 15 | file(DOWNLOAD 16 | https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake 17 | ${CPM_DOWNLOAD_LOCATION} 18 | ) 19 | endif() 20 | 21 | include(${CPM_DOWNLOAD_LOCATION}) -------------------------------------------------------------------------------- /cmake/CrtSys.cmake: -------------------------------------------------------------------------------- 1 | # INCLUDE_DIRECTORIES $(VC_IncludePath);$(WindowsSDK_IncludePath) 2 | cmake_policy(SET CMP0021 OLD) 3 | 4 | set(CMAKE_CXX_STANDARD_LIBRARIES " ") 5 | set(CMAKE_C_STANDARD_LIBRARIES ${CMAKE_CXX_STANDARD_LIBRARIES}) 6 | 7 | # Remove Runtime Checks 8 | string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") 9 | string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") 10 | string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") 11 | string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}") 12 | string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") 13 | 14 | #--------------------------------------------------------------------------------------------------- 15 | # include("${CMAKE_CURRENT_LIST_DIR}/CPM.cmake") 16 | 17 | set(CPM_DOWNLOAD_VERSION 0.32.0) 18 | 19 | if(CPM_SOURCE_CACHE) 20 | # Expand relative path. This is important if the provided path contains a tilde (~) 21 | get_filename_component(CPM_SOURCE_CACHE ${CPM_SOURCE_CACHE} ABSOLUTE) 22 | set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") 23 | elseif(DEFINED ENV{CPM_SOURCE_CACHE}) 24 | set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") 25 | else() 26 | set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") 27 | endif() 28 | 29 | if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION})) 30 | message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}") 31 | file(DOWNLOAD 32 | https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake 33 | ${CPM_DOWNLOAD_LOCATION} 34 | ) 35 | endif() 36 | 37 | include(${CPM_DOWNLOAD_LOCATION}) 38 | #--------------------------------------------------------------------------------------------------- 39 | 40 | 41 | 42 | CPMAddPackage("gh:ntoskrnl7/FindWDK#master") 43 | list(APPEND CMAKE_MODULE_PATH "${FindWDK_SOURCE_DIR}/cmake") 44 | find_package(WDK REQUIRED) 45 | 46 | function(crtsys_add_driver _target) 47 | cmake_parse_arguments(WDK "" "WINVER" "" ${ARGN}) 48 | wdk_add_driver(${_target} ${WDK_UNPARSED_ARGUMENTS} CUSTOM_ENTRY_POINT CrtSysDriverEntry EXTENDED_CPP_FEATURES) 49 | 50 | target_link_libraries(${_target} crtsys) 51 | 52 | get_target_property(INC_DIR_TMP ${_target} INCLUDE_DIRECTORIES) 53 | set_property(TARGET ${_target} PROPERTY INCLUDE_DIRECTORIES "${crtsys_SOURCE_DIR}/include;${crtsys_SOURCE_DIR}/include/.internal/msvc/$(VCToolsVersion);${crtsys_SOURCE_DIR}/include/.internal/msvc/${MSVC_TOOLSET_VERSION};${crtsys_SOURCE_DIR}/include/.internal/msvc/$(VCToolsVersion)/stl;${crtsys_SOURCE_DIR}/include/.internal/msvc/${MSVC_TOOLSET_VERSION}/stl;$(VC_IncludePath);$(WindowsSDK_IncludePath);${INC_DIR_TMP}") 54 | 55 | if(EXISTS "${crtsys_SOURCE_DIR}/include/.internal/winsdk/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}/wdk/${WDK_VERSION}/forced.h") 56 | target_compile_options(${_target} PRIVATE /FI"${crtsys_SOURCE_DIR}/include/.internal/winsdk/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}/wdk/${WDK_VERSION}/forced.h") 57 | endif() 58 | 59 | target_compile_options(${_target} PRIVATE /FI"${crtsys_SOURCE_DIR}/include/.internal/adjust_link_order") 60 | 61 | if(CRTSYS_NTL_MAIN) 62 | target_compile_definitions(${_target} PUBLIC CRTSYS_USE_NTL_MAIN) 63 | endif() 64 | endfunction() 65 | -------------------------------------------------------------------------------- /cmake/pkg-utils.cmake: -------------------------------------------------------------------------------- 1 | if (CMAKE_VERSION VERSION_GREATER 3.10 OR CMAKE_VERSION VERSION_EQUAL 3.10) 2 | include_guard() 3 | endif() 4 | 5 | function(pkg_get_version prefix header_file version_arg) 6 | file(STRINGS ${header_file} version_defines 7 | REGEX "#define ${prefix}_VERSION_(MAJOR|MINOR|PATCH)") 8 | foreach(ver ${version_defines}) 9 | if(ver MATCHES "#define ${prefix}_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$") 10 | set(VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}" CACHE INTERNAL "") 11 | endif() 12 | endforeach() 13 | set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) 14 | 15 | if (CMAKE_VERSION VERSION_GREATER 3.15 OR CMAKE_VERSION VERSION_EQUAL 3.15) 16 | message(DEBUG "${prefix} version ${VERSION}") 17 | else() 18 | message(STATUS "${prefix} version ${VERSION}") 19 | endif() 20 | 21 | set(${version_arg} ${VERSION} PARENT_SCOPE) 22 | endfunction() -------------------------------------------------------------------------------- /cmake/std-cxx.cmake: -------------------------------------------------------------------------------- 1 | if(MSVC) 2 | add_compile_options("/Zc:__cplusplus") 3 | endif() 4 | 5 | macro(set_std_cxx_latest target) 6 | if(MSVC) 7 | check_std_cxx(latest _cxx_latest_flag_supported) 8 | if(_cxx_latest_flag_supported) 9 | set(_version latest) 10 | else() 11 | set(_version 17) 12 | endif() 13 | 14 | else() 15 | check_std_cxx(2a _cxx_2a_flag_supported) 16 | if(_cxx_2a_flag_supported) 17 | set(_version 2a) 18 | else() 19 | set(_version 17) 20 | endif() 21 | endif() 22 | 23 | if(MSVC) 24 | set(_std_cxx_option "/std:c++${_version}") 25 | else() 26 | set(_std_cxx_option "-std=c++${_version}") 27 | endif() 28 | 29 | target_compile_options(${target} PRIVATE ${_std_cxx_option}) 30 | endmacro() 31 | 32 | macro(set_std_cxx) #optional argumanet version 33 | set (extra_macro_args ${ARGN}) 34 | list(LENGTH extra_macro_args num_extra_args) 35 | if(${num_extra_args} GREATER 0) 36 | list(GET extra_macro_args 0 optional_arg) 37 | set(version ${optional_arg}) 38 | endif() 39 | 40 | if (version) 41 | if(MSVC) 42 | set(_std_cxx_option "/std:c++${version}") 43 | else() 44 | set(_std_cxx_option "-std=c++${version}") 45 | endif() 46 | 47 | check_std_cxx(${version} _std_cpp_flag_supported) 48 | if (_std_cpp_flag_supported) 49 | add_compile_options(${_std_cxx_option}) 50 | else() 51 | message(AUTHOR_WARNING "The compiler ${CMAKE_CXX_COMPILER} has no C++${version} support") 52 | set_std_cxx_latest() 53 | endif() 54 | else() 55 | set_std_cxx_latest() 56 | endif() 57 | endmacro() 58 | 59 | set(std_cpp_check_code " 60 | #include 61 | int main() { 62 | printf(\"%lu\", __cplusplus); 63 | return 0; 64 | }") 65 | 66 | function(check_std_cxx version output_variable) 67 | enable_language(CXX) 68 | 69 | file(WRITE ${CMAKE_BINARY_DIR}/std_cpp_check.cpp "${std_cpp_check_code}") 70 | 71 | get_directory_property(_compile_options COMPILE_OPTIONS) 72 | get_directory_property(_compile_definations COMPILE_DEFINITIONS) 73 | 74 | if(MSVC) 75 | set(_compile_std_cxx_option "/std:c++${version}") 76 | else() 77 | set(_compile_std_cxx_option "-std=c++${version}") 78 | endif() 79 | 80 | try_run(SHOULD_PASS COMPILE_RESULT 81 | ${CMAKE_BINARY_DIR} 82 | ${CMAKE_BINARY_DIR}/std_cpp_check.cpp 83 | COMPILE_DEFINITIONS ${_compile_std_cxx_option} ${_compile_options} ${_compile_definations} 84 | COMPILE_OUTPUT_VARIABLE TRY_OUT 85 | RUN_OUTPUT_VARIABLE __cplusplus 86 | ) 87 | if(COMPILE_RESULT) 88 | if(__cplusplus GREATER 201703) #Clang 201707L, gcc 8.2 201709L, MSVC stdc++:lastet 201704L 89 | set(_std_cxx_version 20) 90 | elseif(__cplusplus EQUAL 201703) 91 | set(_std_cxx_version 17) 92 | elseif(__cplusplus EQUAL 201402) 93 | set(_std_cxx_version 14) 94 | elseif(__cplusplus EQUAL 201103) 95 | set(_std_cxx_version 11) 96 | elseif(__cplusplus EQUAL 199711) 97 | set(_std_cxx_version 98) 98 | else() 99 | set(_std_cxx_version "pre-standard(${__cplusplus})") 100 | endif() 101 | 102 | message("${version} == ${_std_cxx_version}") 103 | if(MSVC) 104 | if(version STREQUAL latest) 105 | set(${output_variable} TRUE PARENT_SCOPE) 106 | endif() 107 | else() 108 | if(version STREQUAL 2a AND _std_cxx_version EQUAL 20) 109 | set(${output_variable} TRUE PARENT_SCOPE) 110 | endif() 111 | endif() 112 | if(version EQUAL _std_cxx_version) 113 | set(${output_variable} TRUE PARENT_SCOPE) 114 | endif() 115 | else() 116 | message(ERROR "should pass failed ${TRY_OUT}") 117 | endif() 118 | endfunction(check_std_cxx) 119 | 120 | function(get_std_cxx output_variable) 121 | enable_language(CXX) 122 | 123 | file(WRITE ${CMAKE_BINARY_DIR}/std_cpp_check.cpp "${std_cpp_check_code}") 124 | 125 | if("${CMAKE_CXX_STANDARD}") 126 | set(FLAGS_OPT "CMAKE_FLAGS") 127 | set(FLAGS_VAL "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}") 128 | endif() 129 | 130 | get_directory_property(_compile_options COMPILE_OPTIONS) 131 | get_directory_property(_compile_definations COMPILE_DEFINITIONS) 132 | 133 | try_run(SHOULD_PASS COMPILE_RESULT 134 | ${CMAKE_BINARY_DIR} 135 | ${CMAKE_BINARY_DIR}/std_cpp_check.cpp 136 | COMPILE_DEFINITIONS ${_compile_options} ${_compile_definations} 137 | COMPILE_OUTPUT_VARIABLE TRY_OUT 138 | RUN_OUTPUT_VARIABLE __cplusplus 139 | ${FLAGS_OPT} ${FLAGS_VAL} 140 | ) 141 | 142 | if(NOT COMPILE_RESULT) 143 | message(ERROR "should pass failed ${TRY_OUT}") 144 | endif() 145 | 146 | if(__cplusplus GREATER 201703) #Clang 201707L, gcc 8.2 201709L, MSVC stdc++:lastet 201704L 147 | set(_STD_CPP_VERSION 20) 148 | elseif(__cplusplus EQUAL 201703) 149 | set(_STD_CPP_VERSION 17) 150 | elseif(__cplusplus EQUAL 201402) 151 | set(_STD_CPP_VERSION 14) 152 | elseif(__cplusplus EQUAL 201103) 153 | set(_STD_CPP_VERSION 11) 154 | elseif(__cplusplus EQUAL 199711) 155 | set(_STD_CPP_VERSION 98) 156 | else() 157 | set(_STD_CPP_VERSION "pre-standard(${__cplusplus})") 158 | endif() 159 | set(${output_variable} ${_STD_CPP_VERSION} PARENT_SCOPE) 160 | endfunction() -------------------------------------------------------------------------------- /include/.internal/adjust_link_order: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | [현상] 5 | 6 | MSVC 2019 2017, 2022 7 | SDK 10.0.17763.0 8 | WDK 10.0.17763.0 9 | 10 | 위 환경에서 ARM 모듈료 빌드할 때 11 | read 함수를 io.c에 정의하는 경우, 해당 read함수는 무시되고 12 | C:\Program Files (x86)\Windows 13 | Kits\10\Lib\10.0.17763.0\km\ARM\libcntpr.lib(stubs.obj)의 read를 사용하는 14 | 현상이 발생합니다. 15 | 16 | 이 상황에서 ARM의 경우, fatal error LNK1223 (파일이 잘못되었거나 17 | 손상되었습니다. 파일의 .pdata 정보가 잘못되었습니다.) 링커 오류가 발생합니다. 18 | 링커 오류가 발생하지 않는다해도, 직접 정의한 함수들이 사용되지 못하는 잠재적 19 | 문제가 존재합니다. 20 | 21 | [원인] 22 | 23 | pow 함수를 사용한 코드가 먼저 처리되면서 libcntpr.lib(pow.obj)가 로드 되면서 24 | read함수가 정의된 libcntpr.lib(stub.obj)까지 로드되어지며 25 | 이때 io.c.obj보다 먼저 로드되었기때문에, io.c의 read를 비롯한 함수가 무시되고 26 | libcntpr.lib(stub.obj에 정의된 dummy함수가 사용되게 됩니다. 27 | 28 | [해결책] 29 | 30 | 프로젝트 빌드 시, 이 헤더를 강제로 포함시키도록 처리하여, 31 | libcntpr.lib이 crtsys의 오브젝트보다 먼저 로드 되지 않도록 처리하였습니다. 32 | 33 | - 이 것은 임시 조치이며, 컴파일러 차원에서 링크 순서를 안정적으로 조정하는 34 | 방법을 찾아야합니다. 35 | */ 36 | 37 | #ifdef __cplusplus 38 | extern "C" ___crtsys_crt_io_link_order_dummy(); 39 | extern "C" void ___crtsys_link_order_dummy() { 40 | ___crtsys_crt_io_link_order_dummy(); 41 | } 42 | #endif -------------------------------------------------------------------------------- /include/.internal/msvc/14.29.30133/stl/mutex: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define dllimport 4 | #include <../include/mutex> -------------------------------------------------------------------------------- /include/.internal/msvc/143/stl/mutex: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define dllimport 4 | #include <../include/mutex> -------------------------------------------------------------------------------- /include/.internal/version: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) CrtSys Authors. All rights reserved. 4 | 5 | Module Name: 6 | 7 | version 8 | 9 | Abstract: 10 | 11 | This module defines the version preprocessor. 12 | 13 | Author: 14 | 15 | Jung Kwang Lee (ntoskrnl7@gmail.com) 16 | 17 | Environment: 18 | 19 | Kernel mode 20 | 21 | --*/ 22 | #pragma once 23 | 24 | #ifndef _CRTSYS_VERSION_ 25 | #define _CRTSYS_VERSION_ 26 | 27 | #define CRTSYS_VERSION_MAJOR 0 28 | #define CRTSYS_VERSION_MINOR 1 29 | #define CRTSYS_VERSION_PATCH 10 30 | 31 | #endif // _CRTSYS_VERSION_ -------------------------------------------------------------------------------- /include/.internal/winsdk/10.0.17763.0/wdk/10.0.22000.0/forced.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // 4 | // Windows SDK 10.0.17763.0, Windows Driver Kit 10.0.22000.0를 사용하여 빌드 하는 경우 5 | // Windows SDK 10.0.17763.0의 ntdef.h 6 | // 7 | // 이 프로젝트는 User Mode의 헤더를 우선 참조하기 위해서 8 | // $(VC_IncludePath);$(WindowsSDK_IncludePath)가 WDK의 헤더보다 먼저 참조하도록 설정하기때문에 9 | // Include\10.0.22000.0\shared보다 Include\10.0.17763.0\shared를 먼저 참조합니다. 10 | // 11 | // 이때 아래 문제가 발생하였습니다. 12 | // 1. Include\10.0.17763.0\shared\sdkddkver.h에 NTDDI_WIN10_FE, NTDDI_WIN10_CO가 정의되있지 않아서 13 | // Include\10.0.22000.0\km\wdm.h를 사용한 소스를 빌드할때 NTDDI_WIN10_FE, NTDDI_WIN10_CO아 undefined되어있는것 때문에 빌드 오류가 발생합니다. 14 | // 2. Include\10.0.17763.0\shared\ntdef.h에 PUTF8_STRING, DECLSPEC_RESTRICT, ENCLAVE_SHORT_ID_LENGTH가 정의되어있지 않아서 15 | // Include\10.0.22000.0\km\wdm.h를 사용한 소스를 빌드할때 PUTF8_STRING, DECLSPEC_RESTRICT, ENCLAVE_SHORT_ID_LENGTH 관련 부분에서 빌드 오류가 발생합니다. 16 | // 17 | // 그래서 위 부분을 Include\10.0.22000.0\shared\sdkddkver.h와 ntdef.h의 해당 부분을 복사하여, 이곳에 정의하였습니다. 18 | // 19 | // 추후 다른 부분에서 문제가 발생한다면, 여기에 정의하시기 바랍니다. 20 | // 21 | // 그리고 되도록 SDK와 WDK의 버전이 같은 환경에서 빌드하는것을 권장합니다. 22 | // 23 | 24 | // 25 | // Include\10.0.17763.0\shared\ntdef.h 26 | // 27 | #include 28 | typedef PSTRING PUTF8_STRING; 29 | 30 | #ifndef DECLSPEC_RESTRICT 31 | #if (_MSC_VER >= 1915) && !defined(MIDL_PASS) 32 | #define DECLSPEC_RESTRICT __declspec(restrict) 33 | #else 34 | #define DECLSPEC_RESTRICT 35 | #endif 36 | #endif 37 | 38 | // 39 | // Enclave ID definitions 40 | // 41 | #ifndef ENCLAVE_SHORT_ID_LENGTH 42 | #define ENCLAVE_SHORT_ID_LENGTH 16 43 | #endif 44 | #ifndef ENCLAVE_LONG_ID_LENGTH 45 | #define ENCLAVE_LONG_ID_LENGTH 32 46 | #endif 47 | 48 | // 49 | // Include\10.0.17763.0\shared\sdkddkver.h 50 | // 51 | #ifndef NTDDI_WIN10_FE 52 | #define NTDDI_WIN10_FE 0x0A00000A 53 | #endif 54 | #ifndef NTDDI_WIN10_CO 55 | #define NTDDI_WIN10_CO 0x0A00000B 56 | #endif 57 | -------------------------------------------------------------------------------- /include/ntl/device: -------------------------------------------------------------------------------- 1 | /** 2 | * @file device 3 | * @author jungkwang.lee (ntoskrnl7@google.com) 4 | * @brief 5 | * 6 | * @copyright Copyright (c) 2022 NT Template Library Authoers. 7 | * 8 | */ 9 | #pragma once 10 | 11 | #include "except" 12 | #include 13 | #include 14 | #include 15 | 16 | #ifndef _NTDDK_ 17 | #include 18 | #endif 19 | 20 | namespace ntl { 21 | namespace device_control { 22 | struct code { 23 | code(ULONG code) : value(code) {} 24 | 25 | auto device_type() const { return DEVICE_TYPE_FROM_CTL_CODE(value); } 26 | auto method() const { return METHOD_FROM_CTL_CODE(value); } 27 | auto function() const { return IoGetFunctionCodeFromCtlCode(value); } 28 | bool operator==(const code &rhs) const { return value == rhs.value; } 29 | bool operator==(ULONG rhs) const { return value == rhs; } 30 | bool operator==(int rhs) const { return value == static_cast(rhs); } 31 | 32 | ULONG value; 33 | }; 34 | 35 | struct in_buffer { 36 | in_buffer(const void *ptr, size_t size) : ptr(ptr), size(size) {} 37 | const void *ptr; 38 | size_t size; 39 | }; 40 | 41 | struct out_buffer { 42 | out_buffer(void *ptr, size_t size) : ptr(ptr), size(size) {} 43 | void *ptr; 44 | size_t size; 45 | }; 46 | 47 | using dispatch_fn = std::function; 50 | } // namespace device_control 51 | } // namespace ntl 52 | 53 | namespace ntl { 54 | namespace detail { 55 | namespace device { 56 | struct dispatchers_t { 57 | device_control::dispatch_fn on_device_control; 58 | }; 59 | 60 | template struct extension_data_t; 61 | 62 | template <> struct extension_data_t { dispatchers_t dispatchers; }; 63 | 64 | template struct extension_data_t { 65 | dispatchers_t dispatchers; 66 | Extension data; 67 | }; 68 | 69 | template class extension_t; 70 | 71 | template <> class extension_t { 72 | public: 73 | extension_t() : device_(nullptr) {} 74 | extension_t(PDEVICE_OBJECT device) : device_(device) {} 75 | 76 | extension_data_t *get_context() { 77 | return reinterpret_cast *>(device_->DeviceExtension); 78 | } 79 | 80 | private: 81 | PDEVICE_OBJECT device_; 82 | }; 83 | 84 | template class extension_t { 85 | public: 86 | extension_t() : device_(nullptr) {} 87 | extension_t(PDEVICE_OBJECT device) : device_(device) {} 88 | 89 | extension_data_t *get_context() { 90 | return reinterpret_cast *>( 91 | device_->DeviceExtension); 92 | } 93 | 94 | Extension &extension() { return get_context()->data; } 95 | 96 | private: 97 | PDEVICE_OBJECT device_; 98 | }; 99 | } // namespace device 100 | } // namespace detail 101 | 102 | using device_type = DEVICE_TYPE; 103 | 104 | class device_options { 105 | friend class driver; 106 | 107 | public: 108 | device_options() : type_(FILE_DEVICE_UNKNOWN), exclusive_(false) {} 109 | 110 | device_options &name(const std::wstring &name) { 111 | name_ = name; 112 | return *this; 113 | } 114 | device_options &type(device_type type) { 115 | type_ = type; 116 | return *this; 117 | } 118 | device_options &exclusive(bool exclusive = true) { 119 | exclusive_ = exclusive; 120 | return *this; 121 | } 122 | 123 | const std::wstring &name() const { return name_; } 124 | device_type type() const { return type_; } 125 | bool is_exclusive() const { return exclusive_; } 126 | 127 | private: 128 | std::wstring name_; 129 | device_type type_; 130 | bool exclusive_; 131 | }; 132 | 133 | template 134 | class device : public detail::device::extension_t { 135 | friend class device_dispatch_invoker; 136 | friend class driver; 137 | 138 | protected: 139 | device(PDEVICE_OBJECT device, const device_options &opts) 140 | : detail::device::extension_t(device), object_(device), 141 | name_(opts.name()) {} 142 | 143 | private: 144 | device(const device &) = delete; 145 | 146 | public: 147 | device() : object_(nullptr) {} 148 | 149 | device(device &&other) 150 | : detail::device::extension_t(other.object_) { 151 | *this = std::move(other); 152 | } 153 | 154 | device &operator=(device &&rhs) { 155 | object_ = rhs.detach(); 156 | name_.swap(rhs.name_); 157 | return *this; 158 | } 159 | 160 | ~device() { 161 | auto obj = detach(); 162 | if (obj) { 163 | if (obj->DeviceExtension) 164 | detail::device::extension_t::get_context() 165 | ->~extension_data_t(); 166 | IoDeleteDevice(obj); 167 | } 168 | } 169 | 170 | protected: 171 | detail::device::dispatchers_t &dispatchers() { 172 | return detail::device::extension_t::get_context()->dispatchers; 173 | } 174 | 175 | public: 176 | device &on_device_control(device_control::dispatch_fn &&f) { 177 | dispatchers().on_device_control = f; 178 | return *this; 179 | } 180 | 181 | const std::wstring &name() const { 182 | if (!object_) 183 | throw std::runtime_error("invalid device object."); 184 | return name_; 185 | } 186 | 187 | device_type type() const { 188 | if (!object_) 189 | throw std::runtime_error("invalid device object."); 190 | return object_->DeviceType; 191 | } 192 | 193 | PDEVICE_OBJECT detach() { 194 | return reinterpret_cast( 195 | InterlockedExchangePointer(reinterpret_cast(&object_), NULL)); 196 | } 197 | 198 | private: 199 | PDEVICE_OBJECT object_; 200 | std::wstring name_; 201 | }; 202 | } // namespace ntl -------------------------------------------------------------------------------- /include/ntl/driver: -------------------------------------------------------------------------------- 1 | /** 2 | * @file driver 3 | * @author jungkwang.lee (ntoskrnl7@google.com) 4 | * @brief 5 | * 6 | * @copyright Copyright (c) 2022 NT Template Library Authoers. 7 | * 8 | */ 9 | #pragma once 10 | 11 | #ifndef _NTDDK_ 12 | #include 13 | #endif 14 | #ifndef ClearFlag 15 | #define ClearFlag(_F, _SF) ((_F) &= ~(_SF)) 16 | #endif 17 | 18 | #include "device" 19 | #include "except" 20 | #include "status" 21 | #include "unicode_string" 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | namespace ntl { 28 | namespace detail { 29 | namespace driver { 30 | inline ntl::exception make_exception(NTSTATUS status) { 31 | const char *message; 32 | switch (status) { 33 | case STATUS_INSUFFICIENT_RESOURCES: 34 | message = " Insufficient system resources exist to complete the API."; 35 | break; 36 | case STATUS_OBJECT_NAME_COLLISION: 37 | message = "Object Name already exists."; 38 | break; 39 | default: 40 | message = "Unknown error."; 41 | break; 42 | } 43 | return ntl::exception(status, message); 44 | } 45 | } // namespace driver 46 | } // namespace detail 47 | 48 | class driver { 49 | friend class driver_initializer; 50 | friend class driver_unload_invoker; 51 | friend class device_dispatch_invoker; 52 | 53 | private: 54 | driver(PDRIVER_OBJECT driver) 55 | : object_(driver), name_(driver->DriverName.Buffer, 56 | driver->DriverName.Length / sizeof(WCHAR)) {} 57 | 58 | public: 59 | using unload_routine = std::function; 60 | 61 | template 62 | std::shared_ptr> create_device(device_options &opts) { 63 | PDEVICE_OBJECT dev = NULL; 64 | status s = [&dev, &opts, this]() { 65 | ULONG extension_size = 66 | (ULONG)sizeof(detail::device::extension_data_t); 67 | if (opts.name_.empty()) { 68 | return IoCreateDevice(object_, extension_size, NULL, opts.type_, 0, 69 | opts.exclusive_, &dev); 70 | } else { 71 | unicode_string dev_name(L"\\Device\\" + opts.name_); 72 | return IoCreateDevice(object_, extension_size, &*dev_name, opts.type_, 73 | 0, opts.exclusive_, &dev); 74 | } 75 | }(); 76 | if (s.is_err()) 77 | throw detail::driver::make_exception(s); 78 | 79 | new (dev->DeviceExtension) detail::device::extension_data_t(); 80 | 81 | auto ptr = 82 | std::make_shared>(device(dev, opts)); 83 | 84 | dispatchers_.insert({dev, &ptr->dispatchers()}); 85 | ClearFlag(dev->Flags, DO_DEVICE_INITIALIZING); 86 | 87 | return ptr; 88 | } 89 | 90 | void on_unload(unload_routine &&f) { unload_routine_ = f; } 91 | 92 | const std::wstring &name() const { return name_; } 93 | 94 | protected: 95 | detail::device::dispatchers_t *dispatchers(PDEVICE_OBJECT ptr) noexcept { 96 | try { 97 | return dispatchers_[ptr]; 98 | } catch (...) { 99 | return nullptr; 100 | } 101 | } 102 | 103 | private: 104 | PDRIVER_OBJECT object_; 105 | std::wstring name_; 106 | std::unordered_map 107 | dispatchers_; 108 | unload_routine unload_routine_; 109 | }; 110 | 111 | #if _X86_ 112 | // warning C4007: 'main' : must be '__cdecl' 113 | #pragma warning(disable : 4007) 114 | #endif 115 | status main(driver &driver, const std::wstring ®istry_path); 116 | } // namespace ntl -------------------------------------------------------------------------------- /include/ntl/except: -------------------------------------------------------------------------------- 1 | /** 2 | * @file except 3 | * @author jungkwang.lee (ntoskrnl7@google.com) 4 | * @brief 5 | * 6 | * @copyright Copyright (c) 2022 NT Template Library Authoers. 7 | * 8 | */ 9 | #pragma once 10 | 11 | #include "status" 12 | 13 | #include 14 | #include 15 | 16 | namespace ntl { 17 | class exception : public std::exception { 18 | public: 19 | explicit exception(NTSTATUS status, const std::string &message) 20 | : status_(status), message_(message) {} 21 | explicit exception(status status, const std::string &message) 22 | : status_(status), message_(message) {} 23 | 24 | const status &get_status() const { return status_; } 25 | 26 | private: 27 | status status_; 28 | std::string message_; 29 | }; 30 | 31 | namespace seh { 32 | template 33 | inline std::tuple try_except(Fn &&f, Args &&... args) { 34 | auto code = [&]() -> unsigned long { 35 | __try { 36 | f(std::forward(args)...); 37 | } __except (EXCEPTION_EXECUTE_HANDLER) { 38 | return GetExceptionCode(); 39 | } 40 | return 0; 41 | }(); 42 | if (code) 43 | return {false, code}; 44 | return {true, 0}; 45 | } 46 | } // namespace seh 47 | } // namespace ntl -------------------------------------------------------------------------------- /include/ntl/expand_stack: -------------------------------------------------------------------------------- 1 | /** 2 | * @file expand_stack 3 | * @author jungkwang.lee (ntoskrnl7@google.com) 4 | * @brief KeExpandKernelStackAndCalloutEx Helper features. 5 | * 6 | * @copyright Copyright (c) 2022 NT Template Library Authoers. 7 | * 8 | */ 9 | #pragma once 10 | 11 | #if _MSC_VER < 1911 12 | #error Visual Studio 20017 15.3 or later is required. 13 | #endif 14 | 15 | // clang-format off 16 | #if defined(_WDM_INCLUDED_) 17 | #ifdef _X86_ 18 | #define KERNEL_LARGE_STACK_SIZE 61440 19 | #endif 20 | #ifdef _AMD64_ 21 | #define KERNEL_LARGE_STACK_SIZE 0x12000 22 | #endif 23 | #ifdef _ARM_ 24 | #define KERNEL_LARGE_STACK_SIZE 0xF000 25 | #endif 26 | #ifdef _ARM64_ 27 | #define KERNEL_LARGE_STACK_SIZE 0x12000 28 | #endif 29 | #define MAXIMUM_EXPANSION_SIZE (KERNEL_LARGE_STACK_SIZE - (PAGE_SIZE / 2)) 30 | EXTERN_C_START 31 | typedef 32 | _IRQL_requires_same_ 33 | _Function_class_(EXPAND_STACK_CALLOUT) 34 | VOID 35 | (NTAPI EXPAND_STACK_CALLOUT) ( 36 | _In_opt_ PVOID Parameter 37 | ); 38 | 39 | typedef EXPAND_STACK_CALLOUT *PEXPAND_STACK_CALLOUT; 40 | 41 | #if (NTDDI_VERSION >= NTDDI_VISTA) 42 | _Must_inspect_result_ 43 | _IRQL_requires_min_(PASSIVE_LEVEL) 44 | _IRQL_requires_max_(DISPATCH_LEVEL) 45 | __drv_reportError("DISPATCH_LEVEL is only supported on Windows 7 or later.") 46 | NTKERNELAPI 47 | NTSTATUS 48 | KeExpandKernelStackAndCalloutEx ( 49 | _In_ PEXPAND_STACK_CALLOUT Callout, 50 | _In_opt_ PVOID Parameter, 51 | _In_ SIZE_T Size, 52 | _In_ BOOLEAN Wait, 53 | _In_opt_ PVOID Context 54 | ); 55 | EXTERN_C_END 56 | #endif 57 | #else 58 | #include 59 | #endif 60 | // clang-format on 61 | 62 | #include "except" 63 | #include 64 | #include 65 | #include 66 | #include 67 | 68 | namespace ntl { 69 | #pragma warning(push) 70 | 71 | #ifndef NTL_INVOKE_RESULT 72 | #if _MSVC_LANG >= 201703L 73 | #define NTL_INVOKE_RESULT(F, Args) std::invoke_result_t 74 | #elif _MSVC_LANG >= 201402L 75 | #define NTL_INVOKE_RESULT(F, Args) std::result_of_t 76 | #else 77 | #define NTL_INVOKE_RESULT(F, Args) std::result_of::type 78 | #endif 79 | #endif // NTL_INVOKE_RESULT 80 | 81 | #ifndef NTL_APPLY 82 | #if _MSVC_LANG >= 201703L 83 | #define NTL_APPLY std::apply 84 | #else 85 | namespace detail { 86 | template 87 | constexpr decltype(auto) apply_impl(F &&f, Tuple &&t, 88 | std::index_sequence) { 89 | // This implementation is valid since C++20 (via P1065R2) 90 | // In C++17, a constexpr counterpart of std::invoke is actually needed here 91 | return std::invoke(std::forward(f), 92 | std::get(std::forward(t))...); 93 | } 94 | } // namespace detail 95 | 96 | template 97 | constexpr decltype(auto) apply(F &&f, Tuple &&t) { 98 | return detail::apply_impl( 99 | std::forward(f), std::forward(t), 100 | std::make_index_sequence< 101 | std::tuple_size_v>>{}); 102 | } 103 | #define NTL_APPLY ntl::apply 104 | #endif // _MSVC_LANG >= 201703L 105 | #endif // NTL_APPLY 106 | 107 | #if _MSVC_LANG < 201703L 108 | // warning disable c4984 'if constexpr' is a c++17 language extension 109 | #pragma warning(disable : 4984) 110 | #endif // _MSVC_LANG >= 201703L 111 | 112 | namespace detail { 113 | namespace expand_stack { 114 | inline ntl::exception make_exception(NTSTATUS status) { 115 | const char *message; 116 | switch (status) { 117 | case STATUS_INVALID_PARAMETER_3: 118 | message = 119 | "The stack_size parameter is greater than MAXIMUM_EXPANSION_SIZE."; 120 | break; 121 | case STATUS_INVALID_PARAMETER_4: 122 | message = "The routine was called at IRQL = DISPATCH_LEVEL."; 123 | break; 124 | case STATUS_NO_MEMORY: 125 | message = "Not enough memory is available to expand the stack."; 126 | break; 127 | case STATUS_STACK_OVERFLOW: 128 | message = "The stack, if expanded, would exceed the operating " 129 | "system's internal limits on stack space."; 130 | break; 131 | default: 132 | message = "Unknown error."; 133 | break; 134 | } 135 | return std::move(ntl::exception(status, message)); 136 | } 137 | } // namespace expand_stack 138 | } // namespace detail 139 | 140 | static const size_t expand_stack_size_max = MAXIMUM_EXPANSION_SIZE; 141 | 142 | struct expand_stack_options { 143 | expand_stack_options() 144 | : stack_size_(expand_stack_size_max), wait_(true), 145 | ignore_failure_(false) {} 146 | expand_stack_options(size_t stack_size) 147 | : stack_size_(stack_size), wait_(true), ignore_failure_(false) { 148 | validate(); 149 | } 150 | expand_stack_options(size_t stack_size, bool wait) 151 | : stack_size_(stack_size), wait_(wait), ignore_failure_(false) { 152 | validate(); 153 | } 154 | expand_stack_options(size_t stack_size, bool wait, bool ignore_failure) 155 | : stack_size_(stack_size), wait_(wait), ignore_failure_(ignore_failure) { 156 | validate(); 157 | } 158 | 159 | expand_stack_options &stack_size(size_t stack_size) { 160 | stack_size_ = stack_size; 161 | validate(); 162 | return *this; 163 | } 164 | expand_stack_options &wait(bool wait) { 165 | wait_ = wait; 166 | return *this; 167 | } 168 | expand_stack_options &ignore_failure(bool ignore_failure) { 169 | ignore_failure_ = ignore_failure; 170 | return *this; 171 | } 172 | 173 | void validate() const { 174 | if (stack_size_ > expand_stack_size_max) 175 | throw std::invalid_argument( 176 | "The stack_size parameter is greater than MAXIMUM_EXPANSION_SIZE."); 177 | } 178 | size_t stack_size_; 179 | bool wait_; 180 | bool ignore_failure_; 181 | }; 182 | 183 | template 184 | inline NTL_INVOKE_RESULT(Fn, Args...) 185 | expand_stack(expand_stack_options &&opts, Fn &&f, Args &&... args) { 186 | struct context_t { 187 | context_t(Fn &&f, Args &&... args) 188 | : f(f), args(std::make_tuple(std::forward(args)...)) {} 189 | Fn &f; 190 | std::tuple args; 191 | }; 192 | context_t ctx(std::forward(f), std::forward(args)...); 193 | 194 | using return_type = NTL_INVOKE_RESULT(Fn, Args...); 195 | if constexpr (std::is_void_v) { 196 | NTSTATUS status = KeExpandKernelStackAndCalloutEx( 197 | [](void *ptr) { 198 | auto &ctx = *(context_t *)ptr; 199 | NTL_APPLY(ctx.f, std::forward(ctx.args)); 200 | }, 201 | &ctx, opts.stack_size_, opts.wait_, NULL); 202 | if (NT_SUCCESS(status)) 203 | return; 204 | if (opts.ignore_failure_) 205 | NTL_APPLY(ctx.f, std::move(ctx.args)); 206 | throw detail::expand_stack::make_exception(status); 207 | } else { 208 | std::tuple> context_with_ret = 209 | std::make_tuple(&ctx, nullptr); 210 | NTSTATUS status = KeExpandKernelStackAndCalloutEx( 211 | [](void *ptr) { 212 | auto context_with_ret = 213 | (std::tuple> *)ptr; 214 | auto &ctx = *std::get<0>(*context_with_ret); 215 | std::get<1>(*context_with_ret) = 216 | std::make_unique(std::move(NTL_APPLY( 217 | ctx.f, std::forward(ctx.args)))); 218 | }, 219 | &context_with_ret, opts.stack_size_, opts.wait_, NULL); 220 | if (NT_SUCCESS(status)) 221 | return std::move(*std::get<1>(context_with_ret)); 222 | if (opts.ignore_failure_) 223 | return NTL_APPLY(ctx.f, std::forward(ctx.args)); 224 | throw detail::expand_stack::make_exception(status); 225 | } 226 | } 227 | 228 | template 229 | inline NTL_INVOKE_RESULT(Fn, Args...) expand_stack(Fn &&f, Args &&... args) { 230 | return expand_stack(expand_stack_options{}, std::forward(f), 231 | std::forward(args)...); 232 | } 233 | #pragma warning(pop) 234 | } // namespace ntl -------------------------------------------------------------------------------- /include/ntl/irql: -------------------------------------------------------------------------------- 1 | /** 2 | * @file irql 3 | * @author jungkwang.lee (ntoskrnl7@google.com) 4 | * @brief KIRQL Helper features. 5 | * 6 | * @copyright Copyright (c) 2022 NT Template Library Authoers. 7 | * 8 | */ 9 | 10 | #ifndef _NTDDK_ 11 | #include 12 | #endif 13 | 14 | namespace ntl { 15 | enum irql : KIRQL { 16 | passive = PASSIVE_LEVEL, 17 | low = passive, 18 | apc = APC_LEVEL, 19 | dispatch = DISPATCH_LEVEL, 20 | dpc = dispatch, 21 | #if defined(_X86_) || defined(_AMD64_) 22 | cmci = CMCI_LEVEL, 23 | #endif 24 | clock = CLOCK_LEVEL, 25 | ipi = IPI_LEVEL, 26 | #if !defined(_X86_) 27 | drs = DRS_LEVEL, 28 | #endif 29 | power = POWER_LEVEL, 30 | profile = PROFILE_LEVEL, 31 | #if defined(_X86_) 32 | clock1 = CLOCK1_LEVEL, 33 | clock2 = CLOCK2_LEVEL, 34 | #endif 35 | high = HIGH_LEVEL 36 | }; 37 | 38 | struct to_dpc_level_t { 39 | explicit to_dpc_level_t() = default; 40 | }; 41 | 42 | struct to_synch_level_t { 43 | explicit to_synch_level_t() = default; 44 | }; 45 | 46 | _INLINE_VAR constexpr to_dpc_level_t to_dpc_level{}; 47 | _INLINE_VAR constexpr to_synch_level_t to_synch_level{}; 48 | 49 | class raised_irql { 50 | public: 51 | raised_irql(to_dpc_level_t) : old_irql_(KeRaiseIrqlToDpcLevel()) {} 52 | raised_irql(to_synch_level_t) : old_irql_(KeRaiseIrqlToSynchLevel()) {} 53 | raised_irql(irql irql) { KeRaiseIrql(static_cast(irql), &old_irql_); } 54 | 55 | ~raised_irql() { KeLowerIrql(old_irql_); } 56 | 57 | raised_irql(const raised_irql &) = delete; 58 | raised_irql &operator=(const raised_irql &) = delete; 59 | 60 | irql old() const { return static_cast(old_irql_); } 61 | 62 | private: 63 | KIRQL old_irql_; 64 | }; 65 | 66 | raised_irql raise_irql(KIRQL irql) { 67 | return raised_irql{static_cast(irql)}; 68 | } 69 | 70 | raised_irql raise_irql_to_dpc_level() { return raised_irql{to_dpc_level}; } 71 | 72 | raised_irql raise_irql_to_synch_level() { return raised_irql{to_synch_level}; } 73 | 74 | ntl::irql current_irql() { return static_cast(KeGetCurrentIrql()); } 75 | } // namespace ntl -------------------------------------------------------------------------------- /include/ntl/resource: -------------------------------------------------------------------------------- 1 |  2 | /** 3 | * @file resource 4 | * @author jungkwang.lee (ntoskrnl7@google.com) 5 | * @brief ERESOURCE Helper features. 6 | * 7 | * @copyright Copyright (c) 2022 NT Template Library Authoers. 8 | * 9 | */ 10 | 11 | #ifndef _NTDDK_ 12 | #include 13 | #endif 14 | 15 | #include 16 | 17 | namespace ntl { 18 | namespace detail { 19 | namespace resource { 20 | extern NPAGED_LOOKASIDE_LIST lookaside; 21 | } // namespace resource 22 | } // namespace detail 23 | 24 | class resource { 25 | friend class unique_lock; 26 | 27 | public: 28 | resource() { 29 | res_ = reinterpret_cast( 30 | ExAllocateFromNPagedLookasideList(&detail::resource::lookaside)); 31 | if (res_) 32 | ExInitializeResourceLite(res_); 33 | } 34 | 35 | ~resource() { 36 | if (res_) { 37 | ExDeleteResourceLite(res_); 38 | ExFreeToNPagedLookasideList(&detail::resource::lookaside, res_); 39 | } 40 | } 41 | 42 | resource(const resource &) = delete; 43 | resource &operator=(const resource &) = delete; 44 | 45 | _NODISCARD bool try_lock() { 46 | if (res_ == NULL) 47 | return false; 48 | KeEnterCriticalRegion(); 49 | bool locked = ExAcquireResourceExclusiveLite(res_, FALSE) == TRUE; 50 | if (!locked) 51 | KeLeaveCriticalRegion(); 52 | return locked; 53 | } 54 | 55 | _NODISCARD bool try_lock_shared() { 56 | if (res_ == NULL) 57 | return false; 58 | KeEnterCriticalRegion(); 59 | bool locked = ExAcquireResourceSharedLite(res_, FALSE) == TRUE; 60 | if (!locked) 61 | KeLeaveCriticalRegion(); 62 | return locked; 63 | } 64 | 65 | void lock() { 66 | KeEnterCriticalRegion(); 67 | ExAcquireResourceExclusiveLite(res_, TRUE); 68 | } 69 | 70 | void unlock() { 71 | ExReleaseResourceLite(res_); 72 | KeLeaveCriticalRegion(); 73 | } 74 | 75 | void lock_shared() { 76 | KeEnterCriticalRegion(); 77 | ExAcquireResourceSharedLite(res_, TRUE); 78 | } 79 | 80 | void unlock_shared() { unlock(); } 81 | 82 | bool locked() const { return ExIsResourceAcquiredSharedLite(res_) == TRUE; } 83 | 84 | bool locked_exclusive() const { 85 | return ExIsResourceAcquiredExclusiveLite(res_) == TRUE; 86 | } 87 | 88 | bool locked_shared() const { return (!locked_exclusive()) && locked(); } 89 | 90 | void lock_no_critical_region(bool wait = true) { 91 | ExAcquireResourceExclusiveLite(res_, wait ? TRUE : FALSE); 92 | } 93 | void lock_shared_no_critical_region(bool wait = true) { 94 | ExAcquireResourceSharedLite(res_, wait ? TRUE : FALSE); 95 | } 96 | void unlock_no_critical_region() { ExReleaseResourceLite(res_); } 97 | void unlock_shared_no_critical_region() { unlock_no_critical_region(); } 98 | 99 | void convert_to_shared() { 100 | if (!locked_exclusive()) 101 | throw std::runtime_error(""); 102 | ExConvertExclusiveToSharedLite(res_); 103 | } 104 | 105 | size_t waiter_count() const { 106 | return static_cast(ExGetExclusiveWaiterCount(res_)); 107 | } 108 | 109 | size_t shared_waiter_count() const { 110 | return static_cast(ExGetSharedWaiterCount(res_)); 111 | } 112 | 113 | using native_handle_type = PERESOURCE; 114 | 115 | _NODISCARD native_handle_type native_handle() { return res_; } 116 | 117 | private: 118 | PERESOURCE res_; 119 | }; 120 | 121 | struct adopt_critical_region_t { 122 | explicit adopt_critical_region_t() = default; 123 | }; 124 | 125 | _INLINE_VAR constexpr adopt_critical_region_t adopt_critical_region{}; 126 | 127 | template class unique_lock; 128 | template class shared_lock; 129 | 130 | template <> class unique_lock : public std::unique_lock { 131 | friend class shared_lock; 132 | 133 | public: 134 | using lock_type = resource; 135 | using type = std::unique_lock; 136 | using type::type; 137 | 138 | unique_lock() noexcept : lockable_(nullptr), owns_(false) {} 139 | 140 | unique_lock(lock_type &lockable, std::adopt_lock_t) 141 | : std::unique_lock(lockable, std::adopt_lock), 142 | lockable_(nullptr), owns_(false) { 143 | } // construct and assume already locked 144 | 145 | unique_lock(lock_type &lockable, std::defer_lock_t) noexcept 146 | : std::unique_lock(lockable, std::defer_lock), 147 | lockable_(nullptr), owns_(false) {} // construct but don't lock 148 | 149 | unique_lock(lock_type &lockable, std::try_to_lock_t) 150 | : std::unique_lock(lockable, std::try_to_lock), 151 | lockable_(nullptr), owns_(false) {} // construct and try to lock 152 | 153 | unique_lock(lock_type &lockable, adopt_critical_region_t) 154 | : std::unique_lock(lockable, std::defer_lock), 155 | lockable_(std::addressof(lockable)), owns_(false) { 156 | lockable.lock_no_critical_region(); 157 | owns_ = true; 158 | } // construct but don't enter critical region 159 | 160 | unique_lock &operator=(unique_lock &&other) { 161 | if (this != _STD addressof(other)) { 162 | if (owns_) 163 | lockable_->unlock_no_critical_region(); 164 | else if (std::unique_lock::owns_lock()) 165 | std::unique_lock::unlock(); 166 | lockable_ = other.lockable_; 167 | owns_ = other.owns_; 168 | other.lockable_ = nullptr; 169 | other.owns_ = false; 170 | std::unique_lock::operator=( 171 | std::forward>(other)); 172 | } 173 | return *this; 174 | } 175 | 176 | ~unique_lock() noexcept { 177 | if (owns_) 178 | lockable_->unlock_no_critical_region(); 179 | } 180 | 181 | unique_lock(const unique_lock &) = delete; 182 | unique_lock &operator=(const unique_lock &) = delete; 183 | 184 | _NODISCARD bool owns_lock() const noexcept { 185 | if (owns_) 186 | return true; 187 | return type::owns_lock(); 188 | } 189 | 190 | explicit operator bool() const noexcept { 191 | if (owns_) 192 | return true; 193 | return type::owns_lock(); 194 | } 195 | 196 | protected: 197 | bool owns_; 198 | lock_type *lockable_; 199 | }; 200 | 201 | template <> class shared_lock : public std::shared_lock { 202 | public: 203 | using lock_type = resource; 204 | using type = std::shared_lock; 205 | using type::type; 206 | 207 | shared_lock() noexcept : lockable_(nullptr), owns_(false) {} 208 | 209 | explicit shared_lock(lock_type &lockable) 210 | : lockable_(_STD addressof(lockable)), 211 | owns_(true) { // construct with mutex and lock shared 212 | lockable.lock_shared(); 213 | } 214 | 215 | shared_lock(lock_type &lockable, std::defer_lock_t) noexcept 216 | : std::shared_lock(lockable, std::defer_lock), 217 | lockable_(_STD addressof(lockable)), owns_(false) { 218 | } // construct with unlocked mutex 219 | 220 | shared_lock(lock_type &lockable, std::try_to_lock_t) 221 | : std::shared_lock(lockable, std::try_to_lock), 222 | lockable_(_STD addressof(lockable)), owns_(lockable.try_lock_shared()) { 223 | } // construct with mutex and try to lock shared 224 | 225 | shared_lock(lock_type &lockable, std::adopt_lock_t) 226 | : std::shared_lock(lockable, std::adopt_lock), 227 | lockable_(_STD addressof(lockable)), owns_(true) { 228 | } // construct with mutex and adopt ownership 229 | 230 | shared_lock(lock_type &lockable, adopt_critical_region_t) 231 | : std::shared_lock(lockable, std::defer_lock), 232 | lockable_(std::addressof(lockable)), owns_(false) { 233 | lockable.lock_shared_no_critical_region(); 234 | owns_ = true; 235 | } // construct but don't enter critical region 236 | 237 | shared_lock(unique_lock &lock) 238 | : std::shared_lock(*lock.mutex(), std::defer_lock), 239 | lockable_(lock.mutex()), owns_(false) { 240 | lock.mutex()->convert_to_shared(); 241 | lock.owns_ = false; 242 | owns_ = true; 243 | } // construct with convert lock exclusive to lock shared 244 | 245 | shared_lock &operator=(shared_lock &&other) { 246 | if (this != _STD addressof(other)) { 247 | if (owns_) 248 | lockable_->unlock_no_critical_region(); 249 | else if (std::shared_lock::owns_lock()) 250 | std::shared_lock::unlock(); 251 | lockable_ = other.lockable_; 252 | owns_ = other.owns_; 253 | other.lockable_ = nullptr; 254 | other.owns_ = false; 255 | std::shared_lock::operator=( 256 | std::forward>(other)); 257 | } 258 | return *this; 259 | } 260 | 261 | ~shared_lock() noexcept { 262 | if (owns_) 263 | lockable_->unlock_shared_no_critical_region(); 264 | } 265 | 266 | shared_lock(const shared_lock &) = delete; 267 | shared_lock &operator=(const shared_lock &) = delete; 268 | 269 | _NODISCARD bool owns_lock() const noexcept { 270 | if (owns_) 271 | return true; 272 | return type::owns_lock(); 273 | } 274 | 275 | explicit operator bool() const noexcept { 276 | if (owns_) 277 | return true; 278 | return type::owns_lock(); 279 | } 280 | 281 | private: 282 | bool owns_; 283 | lock_type *lockable_; 284 | }; 285 | } // namespace ntl -------------------------------------------------------------------------------- /include/ntl/rpc/client: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rpc 3 | * @author jungkwang.lee (ntoskrnl7@google.com) 4 | * @brief rpc client 5 | * 6 | * @copyright Copyright (c) 2022 NT Template Library Authoers. 7 | * 8 | */ 9 | 10 | #include "common" 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #if defined(NTL_USER_MODE) 17 | namespace ntl { 18 | namespace rpc { 19 | class client { 20 | public: 21 | client(const std::wstring &rpc_name, size_t out_buffer_size = 4096) 22 | : handle_(::CreateFileW( 23 | (L"\\\\?\\Global\\GLOBALROOT\\Device\\" + rpc_name).c_str(), 24 | GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)), 25 | out_buffer_size_(out_buffer_size) {} 26 | ~client() { 27 | if (handle_ != INVALID_HANDLE_VALUE) 28 | ::CloseHandle(handle_); 29 | } 30 | 31 | template 32 | Ret invoke(uint64_t index, Args &&... args) { 33 | if (handle_ == INVALID_HANDLE_VALUE) 34 | throw std::runtime_error("invalid handle"); 35 | 36 | std::vector in_buffer; 37 | zpp::serializer::memory_output_archive out(in_buffer); 38 | out(args...); 39 | 40 | DWORD returned = 0; 41 | #pragma warning(disable : 4984) 42 | if constexpr (std::is_void_v) { 43 | if (!::DeviceIoControl(handle_, NTL_RPC_DEVICE_CTL(index), 44 | in_buffer.empty() ? NULL : &in_buffer[0], 45 | (DWORD)in_buffer.size(), NULL, 0, &returned, NULL)) 46 | throw std::runtime_error("failed to DeviceIoControl (index : " + 47 | std::to_string(index) + ")"); 48 | } else { 49 | std::vector out_buffer(out_buffer_size_); 50 | if (!::DeviceIoControl(handle_, NTL_RPC_DEVICE_CTL(index), 51 | in_buffer.empty() ? NULL : &in_buffer[0], 52 | (DWORD)in_buffer.size(), &out_buffer[0], 53 | (DWORD)out_buffer.size(), &returned, NULL)) 54 | throw std::runtime_error("failed to DeviceIoControl (index : " + 55 | std::to_string(index) + ")"); 56 | zpp::serializer::memory_input_archive in(out_buffer); 57 | Ret rv; 58 | in(rv); 59 | return std::move(rv); 60 | } 61 | #pragma warning(default : 4984) 62 | } 63 | 64 | private: 65 | HANDLE handle_; 66 | size_t out_buffer_size_; 67 | }; 68 | } // namespace rpc 69 | } // namespace ntl 70 | 71 | #define NTL_RPC_BEGIN(_rpc_name_) namespace _rpc_name_ { 72 | #define NTL_RPC_END(_rpc_name_) } 73 | 74 | #define NTL_ADD_CALLBACK_0(_rpc_name_, _ret_, _name_, ...) \ 75 | static const int _name_##_0_index = __LINE__; \ 76 | inline _ret_ _name_() { \ 77 | return ntl::rpc::client(L#_rpc_name_).invoke<_ret_>(__LINE__); \ 78 | } 79 | 80 | #define NTL_ADD_CALLBACK_1(_rpc_name_, _ret_, _name_, _arg0_type_, \ 81 | _arg0_name_, ...) \ 82 | static const int _name_##_1_index = __LINE__; \ 83 | inline _ret_ _name_(_arg0_type_ _arg0_name_) { \ 84 | return ntl::rpc::client(L#_rpc_name_) \ 85 | .invoke<_ret_>(__LINE__, std::forward<_arg0_type_>(_arg0_name_)); \ 86 | } 87 | 88 | #define NTL_ADD_CALLBACK_2(_rpc_name_, _ret_, _name_, _arg0_type_, \ 89 | _arg0_name_, _arg1_type_, _arg1_name_, ...) \ 90 | static const int _name_##_2_index = __LINE__; \ 91 | inline _ret_ _name_(_arg0_type_ _arg0_name_, _arg1_type_ _arg1_name_) { \ 92 | return ntl::rpc::client(L#_rpc_name_) \ 93 | .invoke<_ret_>(__LINE__, std::forward<_arg0_type_>(_arg0_name_), \ 94 | std::forward<_arg1_type_>(_arg1_name_)); \ 95 | } 96 | 97 | #define NTL_ADD_CALLBACK_3(_rpc_name_, _ret_, _name_, _arg0_type_, \ 98 | _arg0_name_, _arg1_type_, _arg1_name_, _arg2_type_, \ 99 | _arg2_name_, ...) \ 100 | static const int _name_##_3_index = __LINE__; \ 101 | inline _ret_ _name_(_arg0_type_ _arg0_name_, _arg1_type_ _arg1_name_, \ 102 | _arg2_type_ _arg2_name_) { \ 103 | return ntl::rpc::client(L#_rpc_name_) \ 104 | .invoke<_ret_>(__LINE__, std::forward<_arg0_type_>(_arg0_name_), \ 105 | std::forward<_arg1_type_>(_arg1_name_), \ 106 | std::forward<_arg2_type_>(_arg2_name_)); \ 107 | } 108 | 109 | #define NTL_ADD_CALLBACK_4(_rpc_name_, _ret_, _name_, _arg0_type_, \ 110 | _arg0_name_, _arg1_type_, _arg1_name_, _arg2_type_, \ 111 | _arg2_name_, _arg3_type_, _arg3_name_, ...) \ 112 | static const int _name_##_4_index = __LINE__; \ 113 | inline _ret_ _name_(_arg0_type_ _arg0_name_, _arg1_type_ _arg1_name_, \ 114 | _arg2_type_ _arg2_name_, _arg3_type_ _arg3_name_) { \ 115 | return ntl::rpc::client(L#_rpc_name_) \ 116 | .invoke<_ret_>(__LINE__, std::forward<_arg0_type_>(_arg0_name_), \ 117 | std::forward<_arg1_type_>(_arg1_name_), \ 118 | std::forward<_arg2_type_>(_arg2_name_), \ 119 | std::forward<_arg3_type_>(_arg3_name_)); \ 120 | } 121 | 122 | #define NTL_ADD_CALLBACK_5(_rpc_name_, _ret_, _name_, _arg0_type_, \ 123 | _arg0_name_, _arg1_type_, _arg1_name_, _arg2_type_, \ 124 | _arg2_name_, _arg3_type_, _arg3_name_, _arg4_type_, \ 125 | _arg4_name_, ...) \ 126 | static const int _name_##_5_index = __LINE__; \ 127 | inline _ret_ _name_(_arg0_type_ _arg0_name_, _arg1_type_ _arg1_name_, \ 128 | _arg2_type_ _arg2_name_, _arg3_type_ _arg3_name_, \ 129 | _arg4_type_ _arg4_name_) { \ 130 | return ntl::rpc::client(L#_rpc_name_) \ 131 | .invoke<_ret_>(__LINE__, std::forward<_arg0_type_>(_arg0_name_), \ 132 | std::forward<_arg1_type_>(_arg1_name_), \ 133 | std::forward<_arg2_type_>(_arg2_name_), \ 134 | std::forward<_arg3_type_>(_arg3_name_), \ 135 | std::forward<_arg4_type_>(_arg4_name_)); \ 136 | } 137 | #else // !defined(NTL_USER_MODE) 138 | 139 | #endif // !defined(NTL_USER_MODE) 140 | -------------------------------------------------------------------------------- /include/ntl/rpc/common: -------------------------------------------------------------------------------- 1 | /** 2 | * @file common 3 | * @author jungkwang.lee (ntoskrnl7@google.com) 4 | * @brief rpc common 5 | * 6 | * @copyright Copyright (c) 2022 NT Template Library Authoers. 7 | * 8 | */ 9 | 10 | #pragma once 11 | 12 | #if defined(_DDK_DRIVER_) 13 | #undef NTL_USER_MODE 14 | #else 15 | #define NTL_USER_MODE 16 | #endif 17 | 18 | #include "../deps/zpp/serializer.h" 19 | 20 | #if defined(NTL_USER_MODE) 21 | #define WIN32_LEAN_AND_MEAN 22 | #include 23 | #include 24 | #endif // defined(NTL_USER_MODE) 25 | 26 | #define FILE_DEVICE_NTL_RPC 60000 27 | 28 | #define NTL_RPC_DEVICE_CTL(_idx_) \ 29 | ((DWORD)CTL_CODE(FILE_DEVICE_NTL_RPC, _idx_, METHOD_BUFFERED, \ 30 | FILE_ANY_ACCESS)) 31 | 32 | #define NTL_RPC_ARG_PACK(...) __VA_ARGS__ -------------------------------------------------------------------------------- /include/ntl/spin_lock: -------------------------------------------------------------------------------- 1 | /** 2 | * @file spin_lock 3 | * @author jungkwang.lee (ntoskrnl7@google.com) 4 | * @brief KSPIN_LOCK Helper features. 5 | * 6 | * @copyright Copyright (c) 2022 NT Template Library Authoers. 7 | * 8 | */ 9 | 10 | #ifndef _NTDDK_ 11 | #include 12 | #endif 13 | 14 | #include 15 | 16 | namespace ntl { 17 | namespace detail { 18 | namespace spin_lock { 19 | extern NPAGED_LOOKASIDE_LIST lookaside; 20 | } 21 | } // namespace detail 22 | 23 | class spin_lock { 24 | public: 25 | spin_lock() { 26 | lock_ = reinterpret_cast( 27 | ExAllocateFromNPagedLookasideList(&ntl::detail::spin_lock::lookaside)); 28 | KeInitializeSpinLock(lock_); 29 | } 30 | ~spin_lock() { 31 | if (lock_) 32 | ExFreeToNPagedLookasideList(&ntl::detail::spin_lock::lookaside, lock_); 33 | } 34 | spin_lock(const spin_lock &) = delete; 35 | spin_lock &operator=(const spin_lock &) = delete; 36 | 37 | _NODISCARD bool try_lock() { 38 | return KeTryToAcquireSpinLockAtDpcLevel(lock_) == TRUE; 39 | } 40 | 41 | void lock() { KeAcquireSpinLock(lock_, &old_irql_); } 42 | void unlock() { KeReleaseSpinLock(lock_, old_irql_); } 43 | 44 | void lock_at_dpc_level() { KeAcquireSpinLockAtDpcLevel(lock_); } 45 | void unlock_from_dpc_level() { KeReleaseSpinLockFromDpcLevel(lock_); } 46 | 47 | bool test() { return KeTestSpinLock(lock_); } 48 | 49 | using native_handle_type = PKSPIN_LOCK; 50 | 51 | _NODISCARD native_handle_type native_handle() { return lock_; } 52 | 53 | private: 54 | PKSPIN_LOCK lock_; 55 | KIRQL old_irql_; 56 | }; 57 | 58 | struct at_dpc_level_lock_t { 59 | explicit at_dpc_level_lock_t() = default; 60 | }; 61 | 62 | _INLINE_VAR constexpr at_dpc_level_lock_t at_dpc_level_lock{}; 63 | 64 | template class unique_lock; 65 | 66 | template <> class unique_lock : public std::unique_lock { 67 | public: 68 | using lock_type = spin_lock; 69 | using type = std::unique_lock; 70 | using type::type; 71 | 72 | unique_lock() noexcept : lockable_(nullptr), owns_(false) {} 73 | 74 | explicit unique_lock(lock_type &lockable) 75 | : lockable_(_STD addressof(lockable)), 76 | owns_(false) { // construct and lock 77 | lockable_->lock(); 78 | owns_ = true; 79 | } 80 | 81 | unique_lock(lock_type &lockable, std::adopt_lock_t) 82 | : std::unique_lock(lockable, std::adopt_lock), 83 | lockable_(nullptr), owns_(false) { 84 | } // construct and assume already locked 85 | 86 | unique_lock(lock_type &lockable, std::defer_lock_t) noexcept 87 | : std::unique_lock(lockable, std::defer_lock), 88 | lockable_(nullptr), owns_(false) {} // construct but don't lock 89 | 90 | unique_lock(lock_type &lockable, std::try_to_lock_t) 91 | : std::unique_lock(lockable, std::try_to_lock), 92 | lockable_(nullptr), owns_(false) {} // construct and try to lock 93 | 94 | unique_lock(lock_type &lockable, at_dpc_level_lock_t) 95 | : std::unique_lock(lockable, std::defer_lock), 96 | lockable_(std::addressof(lockable)), owns_(false) { 97 | lockable.lock_at_dpc_level(); 98 | owns_ = true; 99 | } // construct and lock at dpc 100 | 101 | unique_lock &operator=(unique_lock &&other) { 102 | if (this != _STD addressof(other)) { 103 | if (owns_) 104 | lockable_->unlock(); 105 | else if (std::unique_lock::owns_lock()) 106 | std::unique_lock::unlock(); 107 | lockable_ = other.lockable_; 108 | owns_ = other.owns_; 109 | other.lockable_ = nullptr; 110 | other.owns_ = false; 111 | std::unique_lock::operator=( 112 | std::forward>(other)); 113 | } 114 | return *this; 115 | } 116 | 117 | ~unique_lock() noexcept { 118 | if (owns_) 119 | lockable_->unlock_from_dpc_level(); 120 | } 121 | 122 | unique_lock(const unique_lock &) = delete; 123 | unique_lock &operator=(const unique_lock &) = delete; 124 | 125 | _NODISCARD bool owns_lock() const noexcept { 126 | if (owns_) 127 | return true; 128 | return type::owns_lock(); 129 | } 130 | 131 | explicit operator bool() const noexcept { 132 | if (owns_) 133 | return true; 134 | return type::owns_lock(); 135 | } 136 | 137 | private: 138 | bool owns_; 139 | lock_type *lockable_; 140 | }; 141 | } // namespace ntl -------------------------------------------------------------------------------- /include/ntl/status: -------------------------------------------------------------------------------- 1 | /** 2 | * @file status 3 | * @author jungkwang.lee (ntoskrnl7@google.com) 4 | * @brief NTSTATUS 5 | * 6 | * @copyright Copyright (c) 2022 NT Template Library Authoers. 7 | * 8 | */ 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace ntl { 14 | class status { 15 | public: 16 | status(NTSTATUS status) : status_(status) {} 17 | 18 | bool is_ok() const { return NT_SUCCESS(status_); } 19 | bool is_info() const { return NT_INFORMATION(status_); } 20 | bool is_warn() const { return NT_WARNING(status_); } 21 | bool is_err() const { return NT_ERROR(status_); } 22 | 23 | operator NTSTATUS() const { return status_; } 24 | 25 | static status ok() { return STATUS_SUCCESS; } 26 | 27 | private: 28 | NTSTATUS status_; 29 | }; 30 | } // namespace ntl -------------------------------------------------------------------------------- /include/ntl/unicode_string: -------------------------------------------------------------------------------- 1 | /** 2 | * @file unicode_string 3 | * @author jungkwang.lee (ntoskrnl7@google.com) 4 | * @brief 5 | * 6 | * @copyright Copyright (c) 2022 NT Template Library Authoers. 7 | * 8 | */ 9 | #pragma once 10 | 11 | #include 12 | 13 | #ifndef _NTDDK_ 14 | #include 15 | #endif 16 | 17 | namespace ntl { 18 | class unicode_string { 19 | public: 20 | unicode_string(std::wstring &&str) : str_(std::move(str)) { 21 | value_.Buffer = &str_[0]; 22 | value_.MaximumLength = value_.Length = (USHORT)str_.size() * sizeof(WCHAR); 23 | } 24 | unicode_string(const std::wstring &str) : str_(str) { 25 | value_.Buffer = &str_[0]; 26 | value_.MaximumLength = value_.Length = (USHORT)str_.size() * sizeof(WCHAR); 27 | } 28 | unicode_string(std::wstring &str) { 29 | value_.Buffer = &str[0]; 30 | value_.MaximumLength = value_.Length = (USHORT)str.size() * sizeof(WCHAR); 31 | } 32 | 33 | const std::wstring &c_str() const { return str_; } 34 | 35 | UNICODE_STRING &operator*() { return value_; } 36 | 37 | private: 38 | std::wstring str_; 39 | UNICODE_STRING value_; 40 | }; 41 | } // namespace ntl -------------------------------------------------------------------------------- /src/crtsys.h: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | 3 | #pragma once 4 | 5 | // sdkddkver.h가 ntddk.h(ntdef.h)보다 포함되는 경우가 발생하여, 6 | // DECLSPEC_DEPRECATED_DDK, DECLSPEC_DEPRECATED_DDK_WINXP 등이 정의되지 않아서 문제가 발생하였습니다. 7 | // 그래서 여기서 ntdef.h가 미리 포함시켰습니다. 8 | 9 | #include -------------------------------------------------------------------------------- /src/custom/crt/fenv/fenv.c: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | 3 | #include 4 | #include 5 | 6 | NTSTATUS 7 | CrtSysInitializeFlsXState ( 8 | VOID 9 | ); 10 | 11 | VOID 12 | NTAPI 13 | CrtySyspCleanupXState ( 14 | _In_ PVOID lpFlsData 15 | ); 16 | 17 | #ifdef ALLOC_PRAGMA 18 | #pragma alloc_text(INIT, CrtSysInitializeFlsXState) 19 | #pragma alloc_text(PAGE, CrtySyspCleanupXState) 20 | #endif 21 | 22 | DWORD CrtSyspFlsXStateSaveIndex; 23 | 24 | VOID 25 | NTAPI 26 | CrtySyspCleanupXState ( 27 | _In_ PVOID lpFlsData 28 | ) 29 | { 30 | PAGED_CODE(); 31 | 32 | if (lpFlsData) { 33 | ExFreePoolWithTag( lpFlsData, 34 | 'ttsX' ); 35 | } 36 | } 37 | 38 | NTSTATUS 39 | CrtSysInitializeFlsXState ( 40 | VOID 41 | ) 42 | { 43 | PAGED_CODE(); 44 | 45 | CrtSyspFlsXStateSaveIndex = FlsAlloc( CrtySyspCleanupXState ); 46 | if (CrtSyspFlsXStateSaveIndex == FLS_OUT_OF_INDEXES) { 47 | return STATUS_UNSUCCESSFUL; 48 | } 49 | return STATUS_SUCCESS; 50 | } 51 | 52 | PXSTATE_SAVE 53 | CrtSyspSaveXState ( 54 | VOID 55 | ) 56 | { 57 | PXSTATE_SAVE StateSave = (PXSTATE_SAVE)FlsGetValue( CrtSyspFlsXStateSaveIndex ); 58 | if (StateSave == NULL) { 59 | #pragma warning(disable:4996) 60 | StateSave = ExAllocatePoolWithTag( NonPagedPool, 61 | sizeof(XSTATE_SAVE), 62 | 'ttsX' ); 63 | #pragma warning(default:4996) 64 | if (StateSave == NULL) { 65 | return NULL; 66 | } 67 | if (! NT_SUCCESS(KeSaveExtendedProcessorState( XSTATE_MASK_LEGACY, 68 | StateSave ))) { 69 | CrtySyspCleanupXState( StateSave ); 70 | return NULL; 71 | } 72 | if (! FlsSetValue( CrtSyspFlsXStateSaveIndex, 73 | StateSave )) { 74 | CrtySyspCleanupXState( StateSave ); 75 | return NULL; 76 | } 77 | #if defined(_ARM_) || defined(_ARM64_) 78 | } else if (StateSave->Dummy == 0) { 79 | if (! NT_SUCCESS(KeSaveExtendedProcessorState( XSTATE_MASK_LEGACY, 80 | StateSave ))) { 81 | return NULL; 82 | } 83 | } 84 | #else 85 | } else if (StateSave->XStateContext.Area == NULL) { 86 | if (! NT_SUCCESS(KeSaveExtendedProcessorState( XSTATE_MASK_LEGACY, 87 | StateSave ))) { 88 | return NULL; 89 | } 90 | } 91 | #endif 92 | return StateSave; 93 | } 94 | 95 | VOID 96 | CrtSyspRestoreXState ( 97 | _In_ PXSTATE_SAVE StateSave 98 | ) 99 | { 100 | if (StateSave == NULL) { 101 | return; 102 | } 103 | KeRestoreExtendedProcessorState( StateSave ); 104 | RtlZeroMemory( StateSave, 105 | sizeof(XSTATE_SAVE) ); 106 | } 107 | 108 | 109 | 110 | _ACRTIMP int __cdecl fegetenv(_Out_ fenv_t *_Env) 111 | { 112 | PXSTATE_SAVE StateSave = CrtSyspSaveXState(); 113 | #if defined(_X86_) || defined(_AMD64_) 114 | if (StateSave == NULL || StateSave->XStateContext.Area == NULL) { 115 | return 1; 116 | } 117 | _Env->_Fe_ctl = StateSave->XStateContext.Area->LegacyState.ControlWord; 118 | _Env->_Fe_stat = StateSave->XStateContext.Area->LegacyState.StatusWord; 119 | CrtSyspRestoreXState( StateSave ); 120 | #else 121 | if (StateSave == NULL) { 122 | return 1; 123 | } 124 | _Env->_Fe_stat = StateSave->Dummy; 125 | CrtSyspRestoreXState( StateSave ); 126 | #endif 127 | return 0; 128 | } 129 | 130 | _ACRTIMP int __cdecl fesetenv(_In_ fenv_t const *_Env) 131 | { 132 | PXSTATE_SAVE StateSave = CrtSyspSaveXState(); 133 | #if defined(_X86_) || defined(_AMD64_) 134 | if (StateSave == NULL || StateSave->XStateContext.Area == NULL) { 135 | return 1; 136 | } 137 | StateSave->XStateContext.Area->LegacyState.ControlWord = (USHORT)_Env->_Fe_ctl; 138 | StateSave->XStateContext.Area->LegacyState.StatusWord = (USHORT)_Env->_Fe_stat; 139 | #else 140 | if (StateSave == NULL) { 141 | return 1; 142 | } 143 | StateSave->Dummy = (USHORT)_Env->_Fe_stat; 144 | #endif 145 | CrtSyspRestoreXState( StateSave ); 146 | return 0; 147 | } 148 | 149 | _ACRTIMP _Success_(return == 0) int __cdecl feholdexcept(_Out_ fenv_t *_Env) 150 | { 151 | PXSTATE_SAVE StateSave = CrtSyspSaveXState(); 152 | #if defined(_X86_) || defined(_AMD64_) 153 | if (StateSave == NULL || StateSave->XStateContext.Area == NULL) { 154 | return 1; 155 | } 156 | _Env->_Fe_ctl = StateSave->XStateContext.Area->LegacyState.ControlWord; 157 | _Env->_Fe_stat = StateSave->XStateContext.Area->LegacyState.StatusWord; 158 | 159 | StateSave->XStateContext.Area->LegacyState.StatusWord &= ~FE_ALL_EXCEPT; 160 | #else 161 | if (StateSave == NULL) { 162 | return 1; 163 | } 164 | _Env->_Fe_stat = StateSave->Dummy; 165 | StateSave->Dummy &= ~FE_ALL_EXCEPT; 166 | #endif 167 | CrtSyspRestoreXState( StateSave ); 168 | return CrtSyspSaveXState() == NULL ? 0 : 1; 169 | } 170 | 171 | _ACRTIMP int __cdecl fegetround(void) 172 | { 173 | #if defined(_X86_) || defined(_AMD64_) 174 | PXSTATE_SAVE StateSave = (PXSTATE_SAVE)FlsGetValue( CrtSyspFlsXStateSaveIndex ); 175 | if (StateSave && StateSave->XStateContext.Area) { 176 | return (int)StateSave->XStateContext.Area->LegacyState.ControlWord & _MCW_RC; 177 | } 178 | #endif 179 | unsigned int state; 180 | if (_controlfp_s(&state, 0, 0)) { 181 | return -1; 182 | } 183 | return (int)state & _MCW_RC; 184 | } -------------------------------------------------------------------------------- /src/custom/crt/io.c: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | 3 | #include 4 | 5 | void ___crtsys_crt_io_link_order_dummy() 6 | { 7 | } 8 | 9 | int __cdecl _creat(char const *const path, int const pmode); 10 | _ACRTIMP int __cdecl creat(_In_z_ char const *_FileName, _In_ int _PermissionMode) 11 | { 12 | return _creat(_FileName, _PermissionMode); 13 | } 14 | 15 | FILE *__cdecl _fdopen(int const fh, char const *const mode); 16 | _Check_return_ _ACRTIMP FILE *__cdecl fdopen(_In_ int _FileHandle, _In_z_ char const *_Mode) 17 | { 18 | return _fdopen(_FileHandle, _Mode); 19 | } 20 | 21 | int __cdecl _read(int const fh, void *const buffer, unsigned const buffer_size); 22 | _Check_return_ _CRT_NONSTDC_DEPRECATE(_read) _ACRTIMP 23 | int __cdecl read(int const fh, void *const buffer, unsigned const buffer_size) 24 | { 25 | return _read(fh, buffer, buffer_size); 26 | } 27 | 28 | int __cdecl _write(int const fh, void const *const buffer, unsigned const size); 29 | _Check_return_ _CRT_NONSTDC_DEPRECATE(_write) _ACRTIMP 30 | int __cdecl write(_In_ int _FileHandle, _In_reads_bytes_(_MaxCharCount) void const *_Buf, 31 | _In_ unsigned int _MaxCharCount) 32 | { 33 | return _write(_FileHandle, _Buf, _MaxCharCount); 34 | } 35 | 36 | int __cdecl _close(int const fh); 37 | _Check_return_opt_ _CRT_NONSTDC_DEPRECATE(_close) _ACRTIMP int __cdecl close(_In_ int _FileHandle) 38 | { 39 | return _close(_FileHandle); 40 | } 41 | 42 | int __cdecl _dup(int const fh); 43 | _Check_return_ _CRT_NONSTDC_DEPRECATE(_dup) _ACRTIMP int __cdecl dup(_In_ int _FileHandle) 44 | { 45 | return _dup(_FileHandle); 46 | } 47 | 48 | int __cdecl _dup2(int const source_fh, int const target_fh); 49 | _Check_return_ _CRT_NONSTDC_DEPRECATE(_dup2) _ACRTIMP int __cdecl dup2(_In_ int _FileHandleSrc, _In_ int _FileHandleDst) 50 | { 51 | return _dup2(_FileHandleSrc, _FileHandleDst); 52 | } -------------------------------------------------------------------------------- /src/custom/crt/math/fpclassify.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #pragma warning(push) 5 | #pragma warning(disable : 4204) 6 | 7 | #if _MSC_VER >= 1920 8 | _Check_return_ _ACRTIMP short __cdecl _dtest(_In_ double *_Px); 9 | #pragma function(_dtest) 10 | #endif 11 | _Check_return_ _ACRTIMP short __cdecl _dtest(_In_ double *_Px) { 12 | // 13 | // https://github.com/bminor/musl/blob/master/src/math/__fpclassify.c 14 | // 15 | union { 16 | double f; 17 | uint64_t i; 18 | } u = {*_Px}; 19 | int e = u.i >> 52 & 0x7ff; 20 | if (!e) 21 | return u.i << 1 ? FP_SUBNORMAL : FP_ZERO; 22 | if (e == 0x7ff) 23 | return u.i << 12 ? FP_NAN : FP_INFINITE; 24 | return FP_NORMAL; 25 | } 26 | 27 | #if _MSC_VER >= 1920 28 | _Check_return_ _ACRTIMP short __cdecl _dclass(_In_ double _X); 29 | #pragma function(_dclass) 30 | #endif 31 | _Check_return_ _ACRTIMP short __cdecl _dclass(_In_ double _X) { 32 | return _dtest(&_X); 33 | } 34 | #pragma warning(pop) -------------------------------------------------------------------------------- /src/custom/crt/math/fpconst.c: -------------------------------------------------------------------------------- 1 | // 2 | // https://github.com/SpoilerScriptsGroup/RetrievAL/blob/develop/SpoilerAL-winmm.dll/crt/math/fpconst.c 3 | // 4 | #include 5 | #include 6 | 7 | #if !CRTSYS_USE_LIBCNTPR 8 | // Floating point used flag 9 | const unsigned int _fltused = 0x9875; 10 | #endif 11 | 12 | // Floating point infinity 13 | const double fpconst_inf = HUGE_VAL; // 0x7FF0000000000000 14 | const double fpconst_minus_inf = -HUGE_VAL; // 0xFFF0000000000000 15 | 16 | // Floating point NaN 17 | const double fpconst_nan = -NAN; // 0x7FF8000000000000 18 | const double fpconst_nan_ind = NAN; // 0xFFF8000000000000 19 | 20 | // Floating point constants 21 | const double fpconst_max = DBL_MAX; // 0x7FEFFFFFFFFFFFFF 22 | const double fpconst_true_min = DBL_TRUE_MIN; // 0x0000000000000001 23 | const double fpconst_half = 0.5; // 0x3FE0000000000000 24 | const double fpconst_one = 1.0; // 0x3FF0000000000000 25 | const double fpconst_two = 2.0; // 0x4000000000000000 26 | const double fpconst_minus_one = -1.0; // 0xBFF0000000000000 27 | const double fpconst_fyl2xp1_limit = 0.29; // 0x3FD28F5C28F5C28F 28 | 29 | // Control word 30 | const unsigned int fpconst_x0363 = 0x0363; 31 | const unsigned int fpconst_x0763 = 0x0763; 32 | const unsigned int fpconst_x0B63 = 0x0B63; 33 | const unsigned int fpconst_x0F63 = 0x0F63; -------------------------------------------------------------------------------- /src/custom/crt/math/nextafter.c: -------------------------------------------------------------------------------- 1 | // 2 | // https://github.com/bminor/musl/blob/master/src/internal/libm.h 3 | // 4 | #include 5 | #include 6 | #include 7 | 8 | /* fp_force_eval ensures that the input value is computed when that's 9 | otherwise unused. To prevent the constant folding of the input 10 | expression, an additional fp_barrier may be needed or a compilation 11 | mode that does so (e.g. -frounding-math in gcc). Then it can be 12 | used to evaluate an expression for its fenv side-effects only. */ 13 | 14 | #ifndef fp_force_evalf 15 | #define fp_force_evalf fp_force_evalf 16 | static inline void fp_force_evalf(float x) { 17 | volatile float y; 18 | y = x; 19 | } 20 | #endif 21 | 22 | #ifndef fp_force_eval 23 | #define fp_force_eval fp_force_eval 24 | static inline void fp_force_eval(double x) { 25 | volatile double y; 26 | y = x; 27 | } 28 | #endif 29 | 30 | #ifndef fp_force_evall 31 | #define fp_force_evall fp_force_evall 32 | static inline void fp_force_evall(long double x) { 33 | volatile long double y; 34 | y = x; 35 | } 36 | #endif 37 | 38 | #define FORCE_EVAL(x) \ 39 | do { \ 40 | if (sizeof(x) == sizeof(float)) { \ 41 | fp_force_evalf((float)x); \ 42 | } else if (sizeof(x) == sizeof(double)) { \ 43 | fp_force_eval((double)x); \ 44 | } else { \ 45 | fp_force_evall(x); \ 46 | } \ 47 | } while (0) 48 | 49 | #pragma warning(push) 50 | #pragma warning(disable : 4127 4204 4244) 51 | 52 | // 53 | // googletest/src/gtest.cc (testing::internal::DoubleNearPredFormat -> 54 | // nextafter) 55 | // 56 | _Check_return_ _ACRTIMP double __cdecl nextafter(_In_ double x, _In_ double y) { 57 | // 58 | // https://github.com/bminor/musl/blob/master/src/math/nextafter.c 59 | // 60 | union { 61 | double f; 62 | uint64_t i; 63 | } ux = {x}, uy = {y}; 64 | uint64_t ax, ay; 65 | int e; 66 | 67 | if (isnan(x) || isnan(y)) 68 | return x + y; 69 | if (ux.i == uy.i) 70 | return y; 71 | ax = ux.i & ULLONG_MAX / 2; 72 | ay = uy.i & ULLONG_MAX / 2; 73 | if (ax == 0) { 74 | if (ay == 0) 75 | return y; 76 | ux.i = (uy.i & 1ULL << 63) | 1; 77 | } else if (ax > ay || ((ux.i ^ uy.i) & 1ULL << 63)) 78 | ux.i--; 79 | else 80 | ux.i++; 81 | e = ux.i >> 52 & 0x7ff; 82 | /* raise overflow if ux.f is infinite and x is finite */ 83 | if (e == 0x7ff) 84 | FORCE_EVAL(x + x); 85 | /* raise underflow if ux.f is subnormal or zero */ 86 | if (e == 0) 87 | FORCE_EVAL(x * x + ux.f * ux.f); 88 | return ux.f; 89 | } 90 | #pragma warning(pop) -------------------------------------------------------------------------------- /src/custom/crt/misc.c: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | 3 | #include 4 | 5 | // 6 | // ucrt/misc/invalid_parameter.cpp (__acrt_call_reportfault -> _CRT_DEBUGGER_HOOK) 7 | // 8 | void __cdecl _CRT_DEBUGGER_HOOK(int reserved) 9 | { 10 | reserved; 11 | KdBreakPoint(); 12 | } 13 | 14 | 15 | 16 | // 17 | // 10.0.17763.0 18 | // 10.0.22000.0 19 | // km\x86\libcntpr.lib(ieee87.obj) 20 | // 21 | #ifdef _M_IX86 22 | void ** __cdecl __pxcptinfoptrs(void); 23 | void ** __cdecl _pxcptinfoptrs(void) 24 | { 25 | return __pxcptinfoptrs(); 26 | } 27 | 28 | unsigned int __cdecl __get_fpsr_sse2() 29 | { 30 | KdBreakPoint(); 31 | return 0; 32 | } 33 | 34 | void __cdecl __set_fpsr_sse2(unsigned int _Arg) 35 | { 36 | _Arg; 37 | KdBreakPoint(); 38 | } 39 | 40 | #include 41 | void __cdecl _setdefaultprecision() 42 | { 43 | KdBreakPoint(); 44 | _controlfp_s(NULL, _PC_53, _MCW_PC); 45 | } 46 | #endif 47 | 48 | 49 | 50 | // 51 | // signbit 52 | // 53 | #include 54 | 55 | _Check_return_ _ACRTIMP int __cdecl _dsign(_In_ double _X) 56 | { 57 | return _DSIGN_C(_X); 58 | } 59 | 60 | _Check_return_ _ACRTIMP int __cdecl _ldsign(_In_ long double _X) 61 | { 62 | return _LSIGN_C(_X); 63 | } 64 | 65 | _Check_return_ _ACRTIMP int __cdecl _fdsign(_In_ float _X) 66 | { 67 | return _FSIGN_C(_X); 68 | } 69 | 70 | 71 | 72 | // 73 | // 74 | // 75 | 76 | #if UCXXRT 77 | #include 78 | 79 | int __do_unsigned_char_lconv_initialization = 255; 80 | 81 | _ACRTIMP __declspec(noreturn) void __cdecl exit(_In_ int _Code) { _exit(_Code); } 82 | _ACRTIMP __declspec(noreturn) void __cdecl _exit(_In_ int _Code) { _Code; } 83 | _ACRTIMP __declspec(noreturn) void __cdecl abort(void) {} 84 | 85 | // 86 | // ucrt\startup\abort.cpp 87 | // 88 | #ifdef _DEBUG 89 | #define _INIT_ABORT_BEHAVIOR _WRITE_ABORT_MSG 90 | #else 91 | #define _INIT_ABORT_BEHAVIOR _CALL_REPORTFAULT 92 | #endif 93 | 94 | unsigned int __abort_behavior = _INIT_ABORT_BEHAVIOR; 95 | 96 | unsigned int __cdecl _set_abort_behavior(unsigned int flags, unsigned int mask) 97 | { 98 | unsigned int oldflags = __abort_behavior; 99 | __abort_behavior = oldflags & (~mask) | flags & mask; 100 | return oldflags; 101 | } 102 | #endif -------------------------------------------------------------------------------- /src/custom/crt/setlocal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifndef __LC_TIME_DATA 6 | typedef struct __lc_time_data { 7 | const char *wday_abbr[7]; 8 | const char *wday[7]; 9 | const char *month_abbr[12]; 10 | const char *month[12]; 11 | const char *ampm[2]; 12 | const char *ww_sdatefmt; 13 | const char *ww_ldatefmt; 14 | const char *ww_timefmt; 15 | int ww_caltype; 16 | long refcount; 17 | const wchar_t *_W_wday_abbr[7]; 18 | const wchar_t *_W_wday[7]; 19 | const wchar_t *_W_month_abbr[12]; 20 | const wchar_t *_W_month[12]; 21 | const wchar_t *_W_ampm[2]; 22 | const wchar_t *_W_ww_sdatefmt; 23 | const wchar_t *_W_ww_ldatefmt; 24 | const wchar_t *_W_ww_timefmt; 25 | const wchar_t *_W_ww_locale_name; 26 | } __lc_time_data; 27 | #define __LC_TIME_DATA 28 | #endif 29 | 30 | #define MAX_LANG_LEN 64 /* max language name length */ 31 | #define MAX_CTRY_LEN 64 /* max country name length */ 32 | #define MAX_MODIFIER_LEN 0 /* max modifier name length - n/a */ 33 | #define MAX_LC_LEN (MAX_LANG_LEN + MAX_CTRY_LEN + MAX_MODIFIER_LEN + 3) 34 | /* max entire locale string length */ 35 | #define MAX_CP_LEN 16 /* max code page name length */ 36 | #define CATNAMES_LEN 57 /* "LC_COLLATE=;LC_CTYPE=;..." length */ 37 | 38 | #define LC_INT_TYPE 0 39 | #define LC_STR_TYPE 1 40 | 41 | #ifndef _TAGLC_ID_DEFINED 42 | typedef struct tagLC_ID { 43 | WORD wLanguage; 44 | WORD wCountry; 45 | WORD wCodePage; 46 | } LC_ID, *LPLC_ID; 47 | #define _TAGLC_ID_DEFINED 48 | #endif /* _TAGLC_ID_DEFINED */ 49 | 50 | typedef struct tagLC_STRINGS { 51 | char szLanguage[MAX_LANG_LEN]; 52 | char szCountry[MAX_CTRY_LEN]; 53 | char szCodePage[MAX_CP_LEN]; 54 | } LC_STRINGS, *LPLC_STRINGS; 55 | 56 | #ifndef _THREADLOCALEINFO 57 | typedef struct threadlocaleinfostruct { 58 | int refcount; 59 | UINT lc_codepage; 60 | UINT lc_collate_cp; 61 | LCID lc_handle[6]; 62 | LC_ID lc_id[6]; 63 | struct { 64 | char *locale; 65 | wchar_t *wlocale; 66 | int *refcount; 67 | int *wrefcount; 68 | } lc_category[6]; 69 | int lc_clike; 70 | int mb_cur_max; 71 | int *lconv_intl_refcount; 72 | int *lconv_num_refcount; 73 | int *lconv_mon_refcount; 74 | struct lconv *lconv; 75 | int *ctype1_refcount; 76 | unsigned short *ctype1; 77 | const unsigned short *pctype; 78 | unsigned char *pclmap; 79 | unsigned char *pcumap; 80 | struct __lc_time_data *lc_time_curr; 81 | } threadlocinfo; 82 | typedef threadlocinfo *pthreadlocinfo; 83 | #define _THREADLOCALEINFO 84 | #endif // _THREADLOCALEINFO 85 | EXTERN_C pthreadlocinfo __ptlocinfo; 86 | 87 | EXTERN_C __lc_time_data __lc_time_c; -------------------------------------------------------------------------------- /src/custom/misc/chandler3_noexcept.cpp: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | 3 | #include 4 | #include 5 | 6 | #if defined(_X86_) 7 | EXTERN_C_START 8 | 9 | int __cdecl 10 | _except_handler3 ( 11 | _In_ struct _EXCEPTION_RECORD *ExceptionRecord, 12 | _In_ struct _EXCEPTION_REGISTRATION *Registration, 13 | _In_ struct _CONTEXT *ContextRecord, 14 | _In_ struct _EXCEPTION_REGISTRATION *Dispatcher 15 | ); 16 | 17 | int __cdecl 18 | _except_handler3_noexcept ( 19 | _In_ struct _EXCEPTION_RECORD *ExceptionRecord, 20 | _In_ struct _EXCEPTION_REGISTRATION *Registration, 21 | _In_ struct _CONTEXT *ContextRecord, 22 | _In_ struct _EXCEPTION_REGISTRATION *Dispatcher 23 | ) 24 | { 25 | KdBreakPoint(); // untested :-( 26 | 27 | int Excption = _except_handler3( ExceptionRecord, 28 | Registration, 29 | ContextRecord, 30 | Dispatcher ); 31 | if (IS_DISPATCHING(ExceptionRecord->ExceptionFlags) && ExceptionRecord->ExceptionCode == EH_EXCEPTION_NUMBER && Excption == ExceptionContinueSearch) { 32 | terminate(); 33 | } 34 | return Excption; 35 | } 36 | 37 | EXTERN_C_END 38 | #endif -------------------------------------------------------------------------------- /src/custom/misc/chandler4_noexcept.cpp: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | 3 | #include 4 | #include 5 | 6 | #if defined(_X86_) 7 | EXTERN_C_START 8 | 9 | EXCEPTION_DISPOSITION __cdecl 10 | _except_handler4( 11 | _In_ struct _EXCEPTION_RECORD *ExceptionRecord, 12 | _In_ PVOID EstablisherFrame, 13 | _Inout_ struct _CONTEXT *ContextRecord, 14 | _Inout_ PVOID DispatcherContext 15 | ); 16 | 17 | EXCEPTION_DISPOSITION __cdecl 18 | _except_handler4_noexcept( 19 | _In_ struct _EXCEPTION_RECORD *ExceptionRecord, 20 | _In_ PVOID EstablisherFrame, 21 | _Inout_ struct _CONTEXT *ContextRecord, 22 | _Inout_ PVOID DispatcherContext 23 | ) 24 | { 25 | KdBreakPoint(); // untested :-( 26 | 27 | EXCEPTION_DISPOSITION Excption = _except_handler4( ExceptionRecord, 28 | EstablisherFrame, 29 | ContextRecord, 30 | DispatcherContext ); 31 | if (IS_DISPATCHING(ExceptionRecord->ExceptionFlags) && ExceptionRecord->ExceptionCode == EH_EXCEPTION_NUMBER && Excption == ExceptionContinueSearch) { 32 | terminate(); 33 | } 34 | return Excption; 35 | } 36 | 37 | EXTERN_C_END 38 | #endif -------------------------------------------------------------------------------- /src/custom/misc/misc.cpp: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | 3 | // 4 | // vcruntime/guard_support.c 5 | // 6 | 7 | extern "C" unsigned char _guard_xfg_dispatch_icall_nop = 0x90; 8 | 9 | 10 | 11 | // 12 | // vcruntime/utility_app.cpp 13 | // 14 | 15 | #include 16 | 17 | #define _ROAPI_ 18 | #include 19 | 20 | EXTERN_C 21 | ROAPI 22 | _Check_return_ 23 | HRESULT 24 | WINAPI 25 | RoInitialize ( 26 | _In_ RO_INIT_TYPE initType 27 | ) 28 | { 29 | KdBreakPoint(); // untested :-( 30 | UNREFERENCED_PARAMETER(initType); 31 | return S_OK; 32 | } 33 | 34 | 35 | 36 | #if CRTSYS_USE_NTL_MAIN 37 | // 38 | // 39 | // /GS 옵션을 사용하여 빌드하는 경우 40 | // BufferOverflowK.lib(gs_support.obj) GsDriverEntry가 포함되며 41 | // GsDriverEntry에서 DriverEntry를 호출하기 때문에 DriverEntry를 임의로 정의하였습니다. 42 | // 43 | 44 | EXTERN_C DRIVER_INITIALIZE DriverEntry; 45 | 46 | #ifdef ALLOC_PRAGMA 47 | #pragma alloc_text(INIT, DriverEntry) 48 | #endif 49 | 50 | // 51 | // BufferOverflowK.lib(gs_support.obj) 52 | // 53 | // GsDriverEntry 54 | // 55 | EXTERN_C DRIVER_INITIALIZE CrtSysDriverEntry; 56 | 57 | EXTERN_C 58 | NTSTATUS 59 | DriverEntry ( 60 | _In_ PDRIVER_OBJECT DriverObject, 61 | _In_ PUNICODE_STRING RegistryPath 62 | ) 63 | { 64 | PAGED_CODE(); 65 | 66 | // 67 | // ntl::main을 사용하도록 빌드하였는데 DriverEntry가 빌드되는건 뭔가 잘못된것입니다. 68 | // 69 | KdBreakPoint(); 70 | 71 | return CrtSysDriverEntry( DriverObject, 72 | RegistryPath ); 73 | } 74 | #endif 75 | 76 | #if CRTSYS_USE_LIBCNTPR 77 | #include "../crt/setlocal.h" 78 | 79 | #pragma warning(disable:4100) 80 | 81 | #include 82 | 83 | EXTERN_C 84 | NTSTATUS 85 | CrtSyspInitializeForLibcntpr ( 86 | VOID 87 | ) 88 | { 89 | // 90 | // 10.0.17763.0 91 | // libcntpr.lib!__ptlocinfo->lc_time_curr가 NULL로 초기화되어있기 때문에 __lc_time_curr를 직접 설정해야합니다. 92 | // 93 | __ptlocinfo->lc_time_curr = &__lc_time_c; 94 | 95 | return STATUS_SUCCESS; 96 | } 97 | 98 | EXTERN_C 99 | VOID 100 | CrtSyspUninitializeForLibcntpr ( 101 | VOID 102 | ) 103 | { 104 | } 105 | 106 | #endif // CRTSYS_USE_LIBCNTPR 107 | 108 | #if UCXXRT 109 | extern "C" void __cdecl __CxxRaiseException( 110 | _In_ DWORD dwExceptionCode, 111 | _In_ DWORD dwExceptionFlags, 112 | _In_ DWORD nNumberOfArguments, 113 | _In_reads_opt_(nNumberOfArguments) CONST ULONG_PTR* lpArguments 114 | ) 115 | { 116 | RaiseException(dwExceptionCode, dwExceptionFlags, nNumberOfArguments, lpArguments); 117 | } 118 | 119 | extern "C" int __cdecl _do_onexit(); 120 | extern "C" int __cdecl _do_quick_onexit(); 121 | extern "C" void __cdecl __initialize_memory(); 122 | 123 | 124 | 125 | // 126 | // ucrt\startup\onexit.cpp 127 | // 128 | // ucrt\internal\initialization.cpp initialize_c -> __acrt_atexit_table 129 | // 130 | #include 131 | 132 | extern "C" _onexit_table_t __acrt_atexit_table{}; 133 | extern "C" _onexit_table_t __acrt_at_quick_exit_table{}; 134 | 135 | extern "C" int __cdecl _initialize_onexit_table(_onexit_table_t* const table) { table; return 0; } 136 | 137 | // ucrt\internal\initialization.cpp initialize_pointers -> __acrt_initialize_thread_local_exit_callback 138 | extern "C" void __cdecl __acrt_initialize_thread_local_exit_callback(void * encoded_null) { encoded_null; } 139 | 140 | 141 | 142 | // 143 | // crt\src\vcruntime\initialization.cpp 144 | // 145 | extern "C" bool __cdecl __vcrt_initialize() 146 | { 147 | return true; 148 | } 149 | 150 | // crt\src\vcruntime\initialization.cpp __acrt_thread_detach -> __acrt_thread_detach 151 | extern "C" bool __cdecl __vcrt_uninitialize(bool const terminating) 152 | { 153 | UNREFERENCED_PARAMETER(terminating); 154 | return true; 155 | } 156 | 157 | 158 | 159 | // 160 | // crt\src\vcruntime\utility.cpp 161 | // 162 | #include 163 | 164 | extern "C" __scrt_native_startup_state __scrt_current_native_startup_state = __scrt_native_startup_state::uninitialized; 165 | 166 | extern "C" bool __cdecl __scrt_initialize_onexit_tables(__scrt_module_type const module_type) 167 | { 168 | module_type; 169 | return true; 170 | } 171 | 172 | extern "C" bool __cdecl __scrt_initialize_crt(__scrt_module_type const module_type) 173 | { 174 | ASSERT(module_type == __scrt_module_type::exe); 175 | UNREFERENCED_PARAMETER(module_type); 176 | 177 | __isa_available_init(); 178 | 179 | if (!__vcrt_initialize()) 180 | { 181 | return false; 182 | } 183 | 184 | if (!__acrt_initialize()) 185 | { 186 | __vcrt_uninitialize(false); 187 | return false; 188 | } 189 | 190 | // ucxxrt 191 | __initialize_memory(); 192 | 193 | return true; 194 | } 195 | 196 | extern "C" _ACRTIMP void __cdecl _cexit(void) 197 | { 198 | _do_onexit(); 199 | } 200 | 201 | extern "C" bool __cdecl __scrt_uninitialize_crt(bool const is_terminating, bool const from_exit) 202 | { 203 | ASSERT(from_exit == false); 204 | UNREFERENCED_PARAMETER(from_exit); 205 | 206 | __acrt_uninitialize(is_terminating); 207 | __vcrt_uninitialize(is_terminating); 208 | 209 | return true; 210 | } 211 | #endif -------------------------------------------------------------------------------- /src/custom/misc/riscchandler_noexcept.cpp: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | 3 | #include 4 | #include 5 | 6 | #if defined _M_AMD64 || defined _M_ARM || defined _M_ARM64 7 | EXTERN_C 8 | EXCEPTION_DISPOSITION 9 | __cdecl 10 | __C_specific_handler_noexcept ( 11 | _In_ struct _EXCEPTION_RECORD* ExceptionRecord, 12 | _In_ void* EstablisherFrame, 13 | _Inout_ struct _CONTEXT* ContextRecord, 14 | _Inout_ struct _DISPATCHER_CONTEXT* DispatcherContext 15 | ) 16 | { 17 | KdBreakPoint(); // untested :-( 18 | 19 | EXCEPTION_DISPOSITION Excption = __C_specific_handler( ExceptionRecord, 20 | EstablisherFrame, 21 | ContextRecord, 22 | DispatcherContext); 23 | if (IS_DISPATCHING(ExceptionRecord->ExceptionFlags) && ExceptionRecord->ExceptionCode == EH_EXCEPTION_NUMBER && Excption == ExceptionContinueSearch) { 24 | terminate(); 25 | } 26 | return Excption; 27 | } 28 | #endif -------------------------------------------------------------------------------- /src/custom/misc/winapi.cpp: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | 3 | #include 4 | 5 | #define WINBASEAPI 6 | 7 | #pragma warning(disable : 4100) 8 | 9 | EXTERN_C_START 10 | 11 | // 12 | // for google test 13 | // 14 | 15 | WINBASEAPI 16 | DWORD 17 | WINAPI 18 | GetTempPathA ( 19 | _In_ DWORD nBufferLength, 20 | _Out_writes_to_opt_(nBufferLength, return +1) LPSTR lpBuffer 21 | ) 22 | { 23 | KdBreakPoint(); 24 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 25 | return 0; 26 | } 27 | 28 | WINBASEAPI 29 | UINT 30 | WINAPI 31 | GetTempFileNameA ( 32 | _In_ LPCSTR lpPathName, _In_ LPCSTR lpPrefixString, 33 | _In_ UINT uUnique, 34 | _Out_writes_(MAX_PATH) LPSTR lpTempFileName 35 | ) 36 | { 37 | KdBreakPoint(); 38 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 39 | return 0; 40 | } 41 | 42 | WINBASEAPI 43 | DWORD 44 | WINAPI 45 | ResumeThread ( 46 | _In_ HANDLE hThread 47 | ) 48 | { 49 | KdBreakPoint(); 50 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 51 | return 0; 52 | } 53 | 54 | WINBASEAPI 55 | BOOL 56 | WINAPI 57 | CreateProcessA ( 58 | _In_opt_ LPCSTR lpApplicationName, 59 | _Inout_opt_ LPSTR lpCommandLine, 60 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 61 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 62 | _In_ BOOL bInheritHandles, 63 | _In_ DWORD dwCreationFlags, 64 | _In_opt_ LPVOID lpEnvironment, 65 | _In_opt_ LPCSTR lpCurrentDirectory, 66 | _In_ struct STARTUPINFOA *lpStartupInfo, 67 | _Out_ struct PROCESS_INFORMATION *lpProcessInformation 68 | ) 69 | { 70 | KdBreakPoint(); 71 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 72 | return FALSE; 73 | } 74 | 75 | WINBASEAPI 76 | BOOL 77 | WINAPI 78 | GetConsoleScreenBufferInfo ( 79 | _In_ HANDLE hConsoleOutput, 80 | _Out_ struct CONSOLE_SCREEN_BUFFER_INFO *lpConsoleScreenBufferInfo 81 | ) 82 | { 83 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 84 | return FALSE; 85 | } 86 | 87 | WINBASEAPI 88 | BOOL 89 | WINAPI 90 | SetConsoleTextAttribute ( 91 | _In_ HANDLE hConsoleOutput, 92 | _In_ WORD wAttributes 93 | ) 94 | { 95 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 96 | return FALSE; 97 | } 98 | 99 | 100 | 101 | // 14.31.31103\crt\src\stl\xdateord.cpp 102 | WINBASEAPI 103 | int 104 | WINAPI 105 | GetLocaleInfoEx ( 106 | _In_opt_ LPCWSTR lpLocaleName, 107 | _In_ LCTYPE LCType, 108 | _Out_writes_to_opt_(cchData, return) LPWSTR lpLCData, 109 | _In_ int cchData 110 | ) 111 | { 112 | KdBreakPoint(); 113 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 114 | return 0; 115 | } 116 | 117 | // 14.31.31103\crt\src\stl\xgetwctype.cpp 118 | WINBASEAPI 119 | BOOL 120 | WINAPI 121 | GetStringTypeW ( 122 | _In_ DWORD dwInfoType, 123 | _In_NLS_string_(cchSrc) LPCWCH lpSrcStr, 124 | _In_ int cchSrc, 125 | _Out_ LPWORD lpCharType 126 | ) 127 | { 128 | KdBreakPoint(); 129 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 130 | return FALSE; 131 | } 132 | 133 | 134 | 135 | // 136 | // ucrt/internal/winapi_thunks.cpp 137 | // 138 | 139 | // __acrt_GetDateFormatEx -> GetDateFormatW 140 | WINBASEAPI 141 | int 142 | WINAPI 143 | GetDateFormatW ( 144 | _In_ LCID Locale, 145 | _In_ DWORD dwFlags, 146 | _In_opt_ CONST SYSTEMTIME* lpDate, 147 | _In_opt_ LPCWSTR lpFormat, 148 | _Out_writes_opt_(cchDate) LPWSTR lpDateStr, 149 | _In_ int cchDate 150 | ) 151 | { 152 | KdBreakPoint(); 153 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 154 | return 0; 155 | } 156 | 157 | // __acrt_GetTimeFormatEx -> GetTimeFormatW 158 | WINBASEAPI 159 | int 160 | WINAPI 161 | GetTimeFormatW ( 162 | _In_ LCID Locale, 163 | _In_ DWORD dwFlags, 164 | _In_opt_ CONST SYSTEMTIME* lpTime, 165 | _In_opt_ LPCWSTR lpFormat, 166 | _Out_writes_opt_(cchTime) LPWSTR lpTimeStr, 167 | _In_ int cchTime 168 | ) 169 | { 170 | KdBreakPoint(); 171 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 172 | return 0; 173 | } 174 | 175 | // __acrt_GetLocaleInfoEx -> GetLocaleInfoW 176 | WINBASEAPI 177 | int 178 | WINAPI 179 | GetLocaleInfoW ( 180 | _In_ LCID Locale, 181 | _In_ LCTYPE LCType, 182 | _Out_writes_opt_(cchData) LPWSTR lpLCData, 183 | _In_ int cchData 184 | ) 185 | { 186 | KdBreakPoint(); 187 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 188 | return 0; 189 | } 190 | 191 | // __acrt_EnumSystemLocalesEx -> EnumSystemLocalesEx 192 | WINBASEAPI 193 | BOOL 194 | WINAPI 195 | EnumSystemLocalesEx ( 196 | _In_ LOCALE_ENUMPROCEX lpLocaleEnumProcEx, 197 | _In_ DWORD dwFlags, 198 | _In_ LPARAM lParam, 199 | _In_opt_ LPVOID lpReserved 200 | ) 201 | { 202 | KdBreakPoint(); 203 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 204 | return FALSE; 205 | } 206 | 207 | // 208 | // ucrt/locale/getqloc_downloevel.cpp (GetLcidFromLangCountry, GetLcidFromLanguage, GetLcidFromCountry) 209 | // 210 | WINBASEAPI 211 | BOOL 212 | WINAPI 213 | EnumSystemLocalesW ( 214 | _In_ LOCALE_ENUMPROCW lpLocaleEnumProc, 215 | _In_ DWORD dwFlags 216 | ) 217 | { 218 | KdBreakPoint(); 219 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 220 | return FALSE; 221 | } 222 | 223 | // 224 | // https://github.com/ntoskrnl7/crtsys/issues/23 225 | // 226 | // Windows Kits\10\Include\10.0.22621.0\winrt\wrl\wrappers\corewrappers.h 227 | // Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.34.31721\crt\src\stl\ppltasks.cpp 228 | // 229 | // MutexTraits::Lock, SemaphoreTraits::Lock 230 | // 231 | WINBASEAPI 232 | BOOL 233 | WINAPI 234 | ReleaseSemaphore ( 235 | _In_ HANDLE hSemaphore, 236 | _In_ LONG lReleaseCount, 237 | _Out_opt_ LPLONG lpPreviousCount 238 | ) 239 | { 240 | KdBreakPoint(); 241 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 242 | return FALSE; 243 | } 244 | 245 | WINBASEAPI 246 | BOOL 247 | WINAPI 248 | ReleaseMutex ( 249 | _In_ HANDLE hMutex 250 | ) 251 | { 252 | KdBreakPoint(); 253 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 254 | return FALSE; 255 | } 256 | 257 | #ifdef WINOLEAPI 258 | #undef WINOLEAPI 259 | #endif 260 | #ifdef WINOLEAPI_ 261 | #undef WINOLEAPI_ 262 | #endif 263 | 264 | #ifdef _OLE32_ 265 | #define WINOLEAPI STDAPI 266 | #define WINOLEAPI_(type) STDAPI_(type) 267 | #else 268 | 269 | #ifdef _68K_ 270 | #ifndef REQUIRESAPPLEPASCAL 271 | #define WINOLEAPI EXTERN_C HRESULT PASCAL 272 | #define WINOLEAPI_(type) EXTERN_C type PASCAL 273 | #else 274 | #define WINOLEAPI EXTERN_C PASCAL HRESULT 275 | #define WINOLEAPI_(type) EXTERN_C PASCAL type 276 | #endif 277 | #else 278 | #define WINOLEAPI EXTERN_C HRESULT STDAPICALLTYPE 279 | #define WINOLEAPI_(type) EXTERN_C type STDAPICALLTYPE 280 | #endif 281 | 282 | #endif 283 | 284 | _Check_return_ 285 | WINOLEAPI 286 | CoGetObjectContext( 287 | _In_ REFIID riid, 288 | _Outptr_ LPVOID FAR * ppv 289 | ) 290 | { 291 | KdBreakPoint(); 292 | return E_NOTIMPL; 293 | } 294 | 295 | typedef 296 | enum _APTTYPEQUALIFIER 297 | { 298 | APTTYPEQUALIFIER_NONE = 0, 299 | APTTYPEQUALIFIER_IMPLICIT_MTA = 1, 300 | APTTYPEQUALIFIER_NA_ON_MTA = 2, 301 | APTTYPEQUALIFIER_NA_ON_STA = 3, 302 | APTTYPEQUALIFIER_NA_ON_IMPLICIT_MTA = 4, 303 | APTTYPEQUALIFIER_NA_ON_MAINSTA = 5, 304 | APTTYPEQUALIFIER_APPLICATION_STA = 6, 305 | APTTYPEQUALIFIER_RESERVED_1 = 7 306 | } APTTYPEQUALIFIER; 307 | 308 | typedef 309 | enum _APTTYPE 310 | { 311 | APTTYPE_CURRENT = -1, 312 | APTTYPE_STA = 0, 313 | APTTYPE_MTA = 1, 314 | APTTYPE_NA = 2, 315 | APTTYPE_MAINSTA = 3 316 | } APTTYPE; 317 | 318 | _Check_return_ 319 | WINOLEAPI 320 | CoGetApartmentType( 321 | _Out_ APTTYPE* pAptType, 322 | _Out_ APTTYPEQUALIFIER* pAptQualifier 323 | ) 324 | { 325 | KdBreakPoint(); 326 | return E_NOTIMPL; 327 | } 328 | 329 | EXTERN_C_END 330 | -------------------------------------------------------------------------------- /src/custom/msvc/141/crt/src/ehhelpers.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | EXTERN_C 4 | NTSYSAPI 5 | VOID 6 | NTAPI 7 | RtlUnwind( 8 | _In_opt_ PVOID TargetFrame, 9 | _In_opt_ PVOID TargetIp, 10 | _In_opt_ PEXCEPTION_RECORD ExceptionRecord, 11 | _In_ PVOID ReturnValue 12 | ); 13 | 14 | #include -------------------------------------------------------------------------------- /src/custom/msvc/141/crt/src/i386/trnsctrl_redirect.cpp: -------------------------------------------------------------------------------- 1 | #include <../i386/trnsctrl.cpp> -------------------------------------------------------------------------------- /src/custom/msvc/141/crt/src/misc/cfg_support.inc: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | 5 | 6 | 7 | extern 8 | __forceinline 9 | void 10 | __fastcall 11 | _guard_check_icall_nop ( 12 | _In_ uintptr_t Target 13 | ) 14 | 15 | /*++ 16 | 17 | Routine Description: 18 | 19 | This function performs a no-op check when invoked by the compiler to check 20 | the integrity of a function pointer for Control Flow Guard (/guard). 21 | 22 | Arguments: 23 | 24 | Target - Supplies the function pointer to check. 25 | 26 | Return Value: 27 | 28 | None. 29 | 30 | --*/ 31 | 32 | { 33 | 34 | UNREFERENCED_PARAMETER(Target); 35 | return; 36 | } 37 | 38 | extern 39 | __forceinline 40 | int 41 | _guard_icall_checks_enforced ( 42 | VOID 43 | ) 44 | 45 | /*++ 46 | 47 | Routine Description: 48 | 49 | This function determines whether Control Flow Guard is enforced for the 50 | current module. 51 | 52 | Arguments: 53 | 54 | None. 55 | 56 | Return Value: 57 | 58 | A nonzero value is returned as the function value if Control Flow Guard 59 | is enforced for the current module. 60 | 61 | --*/ 62 | 63 | { 64 | 65 | return (ReadPointerNoFence(&__guard_check_icall_fptr) != (PVOID)_guard_check_icall_nop); 66 | } -------------------------------------------------------------------------------- /src/custom/msvc/141/crt/src/vcruntime/frame_redirect.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include "ehhelpers.h" 13 | 14 | #if defined(_M_ARM64EC) 15 | #include //PDISPATCHER_CONTEXT_ARM64EC 16 | #include 17 | #endif 18 | 19 | // 20 | // frame.cpp 21 | // 22 | // intptr_t continuationIndex = reinterpret_cast(continuationAddress); 23 | // 24 | // to 25 | // 26 | // uintptr_t continuationIndex = reinterpret_cast(continuationAddress); 27 | // 28 | #define intptr_t uintptr_t 29 | 30 | #include -------------------------------------------------------------------------------- /src/custom/msvc/141/crt/src/vcruntime/std_type_info.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // _unDName function is not implemented yet. 3 | // 4 | 5 | #include 6 | 7 | EXTERN_C int __cdecl __std_type_info_compare ( 8 | __std_type_info_data const* const lhs, 9 | __std_type_info_data const* const rhs 10 | ) 11 | { 12 | if (lhs == rhs) 13 | { 14 | return 0; 15 | } 16 | 17 | return strcmp(lhs->_DecoratedName + 1, rhs->_DecoratedName + 1); 18 | } -------------------------------------------------------------------------------- /src/custom/msvc/141/crt/src/vcruntime/trnsctrl.h: -------------------------------------------------------------------------------- 1 | // 2 | // trnsctrl.h 3 | // 4 | // Copyright (c) Microsoft Corporation. All rights reserved. 5 | // 6 | // Internal VCRuntime header that defines the functions that perform special 7 | // transfer of control operations and related things. 8 | // 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #if !defined(RENAME_EH_EXTERN) 15 | #define RENAME_EH_EXTERN(x) x 16 | #endif 17 | 18 | #pragma pack(push, _CRT_PACKING) 19 | 20 | // Link together all existing catch objects to determine when they should 21 | // be destroyed 22 | typedef struct FrameInfo 23 | { 24 | PVOID pExceptionObject; 25 | 26 | #if defined _M_ARM 27 | 28 | EHRegistrationNode* pRN; 29 | struct _s_FuncInfo* pFuncInfo; 30 | __ehstate_t state; 31 | 32 | #endif 33 | 34 | struct FrameInfo* pNext; 35 | } FRAMEINFO; 36 | 37 | #if defined _M_X64 || defined _M_ARM_NT || defined _M_ARM64 || defined _CHPE_X86_ARM64_EH_ 38 | extern "C" PVOID RENAME_EH_EXTERN(_CallSettingFrame)( 39 | void*, 40 | EHRegistrationNode*, 41 | #if defined _M_ARM_NT || defined _M_ARM64 || defined _CHPE_X86_ARM64_EH_ 42 | PULONG, 43 | #endif 44 | ULONG 45 | ); 46 | 47 | extern "C" PVOID RENAME_EH_EXTERN(_CallSettingFrame_LookupContinuationIndex)( 48 | void*, 49 | EHRegistrationNode*, 50 | #if defined _M_ARM_NT || defined _M_ARM64 || defined _CHPE_X86_ARM64_EH_ 51 | PULONG, 52 | #endif 53 | ULONG 54 | ); 55 | 56 | extern "C" PVOID RENAME_EH_EXTERN(_CallSettingFrame_NotifyContinuationAddr)( 57 | void*, 58 | EHRegistrationNode* 59 | ); 60 | 61 | extern "C" PVOID RENAME_EH_EXTERN(_CallSettingFrameEncoded)( 62 | void*, 63 | EHRegistrationNode, 64 | void*, 65 | #if defined _M_ARM_NT || defined _M_ARM64 || defined _CHPE_X86_ARM64_EH_ 66 | PULONG, 67 | #endif 68 | ULONG 69 | ); 70 | 71 | #define OffsetToAddress(offset, fp) (void*)(((char*)(fp)) + (offset)) 72 | 73 | #define UNWINDSTATE(base, offset) *((int*)((char*)base + offset)) 74 | #define UNWINDTRYBLOCK(base, offset) *((int*)((char*)(OffsetToAddress(offset,base)) + 4)) 75 | #define UNWINDHELP(base, offset) *((__int64*)((char*)base + offset)) 76 | 77 | extern "C" uintptr_t __cdecl _GetImageBase(); 78 | 79 | extern "C" void __cdecl _SetImageBase( 80 | uintptr_t ImageBaseToRestore 81 | ); 82 | 83 | #if !defined(_CHPE_X86_ARM64_EH_) 84 | 85 | extern "C" uintptr_t __cdecl _GetThrowImageBase(); 86 | 87 | extern "C" void __cdecl _SetThrowImageBase( 88 | uintptr_t NewThrowImageBase 89 | ); 90 | 91 | #endif 92 | 93 | template 94 | BOOL _CallSETranslator( 95 | EHExceptionRecord *pExcept, 96 | EHRegistrationNode *pRN, 97 | CONTEXT *pContext, 98 | DispatcherContext *pDC, 99 | typename T::FuncInfo *pFuncInfo, 100 | ULONG CatchDepth, 101 | EHRegistrationNode *pMarkerRN 102 | ); 103 | 104 | #elif defined _M_IX86 105 | 106 | extern "C" void* __stdcall _CallSettingFrame( 107 | void*, 108 | EHRegistrationNode*, 109 | unsigned long 110 | ); 111 | 112 | void __stdcall _JumpToContinuation( 113 | void*, 114 | EHRegistrationNode* 115 | ); 116 | 117 | // Translate an ebp-relative offset to a hard address based on address of 118 | // registration node: 119 | #define OffsetToAddress(off, RN) (void*)((char*)(RN) + FRAME_OFFSET + (off)) 120 | 121 | // Call RtlUnwind in a returning fashion 122 | void __stdcall _UnwindNestedFrames( 123 | EHRegistrationNode*, 124 | EHExceptionRecord* 125 | ); 126 | 127 | void* _CallCatchBlock2( 128 | EHRegistrationNode*, 129 | FuncInfo*, 130 | void*, 131 | int, 132 | unsigned long 133 | ); 134 | 135 | BOOL _CallSETranslator( 136 | EHExceptionRecord*, 137 | EHRegistrationNode*, 138 | void*, 139 | DispatcherContext*, 140 | FuncInfo*, 141 | int, 142 | EHRegistrationNode* 143 | ); 144 | 145 | #else 146 | 147 | #error Special transfer of control routines not defined for this platform 148 | 149 | #endif 150 | 151 | #if !defined(_M_CEE_PURE) 152 | 153 | __declspec(guard(ignore)) inline void __stdcall _CallMemberFunction0( 154 | void* const pthis, 155 | void* const pmfn 156 | ) noexcept(false) 157 | { 158 | auto const OneArgFn = reinterpret_cast(pmfn); 159 | OneArgFn(pthis); 160 | } 161 | 162 | __declspec(guard(ignore)) inline void __stdcall _CallMemberFunction1( 163 | void* const pthis, 164 | void* const pmfn, 165 | void* const pthat 166 | ) noexcept(false) 167 | { 168 | auto const TwoArgFn = reinterpret_cast(pmfn); 169 | TwoArgFn(pthis, pthat); 170 | } 171 | 172 | __declspec(guard(ignore)) inline void __stdcall _CallMemberFunction2( 173 | void* const pthis, 174 | void* const pmfn, 175 | void* const pthat, 176 | int const val2 177 | ) noexcept(false) 178 | { 179 | auto const ThreeArgFn = reinterpret_cast(pmfn); 180 | ThreeArgFn(pthis, pthat, val2); 181 | } 182 | 183 | #endif 184 | 185 | // The following functions are implemented in the common transfer-of-control 186 | // implementation shared by the x64, arm, and arm64 EH implementations. 187 | 188 | extern "C" _VCRTIMP FRAMEINFO* __cdecl RENAME_EH_EXTERN(_CreateFrameInfo)( 189 | FRAMEINFO* fi, 190 | PVOID exception 191 | ); 192 | 193 | extern "C" _VCRTIMP BOOL __cdecl _IsExceptionObjectToBeDestroyed( 194 | PVOID exception 195 | ); 196 | 197 | extern "C" _VCRTIMP void __cdecl RENAME_EH_EXTERN(_FindAndUnlinkFrame)( 198 | FRAMEINFO* fi 199 | ); 200 | 201 | typedef void (__stdcall* PFNPREPARE_FOR_THROW)(void* ExceptionInfo); 202 | 203 | typedef struct WinRTExceptionInfo 204 | { 205 | void* description; 206 | void* restrictedErrorString; 207 | void* restrictedErrorReference; 208 | void* capabilitySid; 209 | long hr; 210 | void* restrictedInfo; 211 | ThrowInfo* throwInfo; 212 | unsigned int size; 213 | PFNPREPARE_FOR_THROW PrepareThrow; 214 | } WINRTEXCEPTIONINFO; 215 | 216 | extern "C" _VCRTIMP void** __cdecl __current_exception(); 217 | extern "C" _VCRTIMP void** __cdecl __current_exception_context(); 218 | extern "C" _VCRTIMP int* __cdecl __processing_throw(); 219 | 220 | // NOTE: __uncaught_exceptions duplicates __ProcessingThrow. 221 | 222 | #ifndef _VCRT_DIRECT_PTD 223 | #ifdef _VCRT_BUILD 224 | #define _VCRT_DIRECT_PTD 1 225 | #else // ^^^ _VCRT_BUILD // !_VCRT_BUILD vvv 226 | #define _VCRT_DIRECT_PTD 0 227 | #endif // _VCRT_BUILD 228 | #endif // _VCRT_DIRECT_PTD 229 | 230 | #if _VCRT_DIRECT_PTD 231 | 232 | #define _pCurrentException (*reinterpret_cast(&RENAME_BASE_PTD(__vcrt_getptd)()->_curexception)) 233 | #define _pCurrentExContext (*reinterpret_cast(&RENAME_BASE_PTD(__vcrt_getptd)()->_curcontext)) 234 | #define __ProcessingThrow (RENAME_BASE_PTD(__vcrt_getptd)()->_ProcessingThrow) 235 | 236 | #else // ^^^ _VCRT_DIRECT_PTD ^^^ // vvv !_VCRT_DIRECT_PTD vvv // 237 | 238 | #define _pCurrentException (*reinterpret_cast(__current_exception())) 239 | #define _pCurrentExContext (*reinterpret_cast(__current_exception_context())) 240 | #define __ProcessingThrow (*__processing_throw()) 241 | 242 | #endif // !_VCRT_DIRECT_PTD 243 | 244 | #ifndef _VCRT_BUILD_FH4 245 | #ifdef _M_X64 246 | #define _VCRT_BUILD_FH4 1 247 | #else // ^^^ _M_X64 // !_M_X64 vvv 248 | #define _VCRT_BUILD_FH4 0 249 | #endif // _M_X64 250 | #endif // _VCRT_BUILD_FH4 251 | 252 | #pragma pack(pop) 253 | -------------------------------------------------------------------------------- /src/custom/msvc/141/include/ehassert.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | using namespace FH4; 7 | 8 | #if !defined(DASSERT) 9 | #if !defined(_VCRT_BUILD) && defined(_DEBUG) 10 | #include 11 | #define DASSERT(x) assert(x) 12 | #else 13 | #define DASSERT(x) 14 | #endif 15 | #else 16 | // This is an FE build; DASSERT is defined properly 17 | #endif 18 | 19 | #if !defined(RENAME_BASE_PTD) 20 | #if defined _VCRT_SAT_1 21 | #define RENAME_BASE_PTD(x) x##base 22 | #else 23 | #define RENAME_BASE_PTD(x) x 24 | #endif 25 | #endif 26 | -------------------------------------------------------------------------------- /src/custom/msvc/141/include/ehhooks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define EHTRACE_ENTER_FMT1(...) 9 | #define EHTRACE_ENTER_FMT2(...) 10 | #define EHTRACE_FMT1(...) 11 | #define EHTRACE_FMT2(...) 12 | 13 | #define EHTRACE_ENTER 14 | #define EHTRACE_EXIT 15 | #define EHTRACE_EXCEPT(x) x 16 | #define EHTRACE_HANDLER_EXIT(x) 17 | #define EHTRACE_SAVE_LEVEL 18 | #define EHTRACE_RESTORE_LEVEL(x) 19 | 20 | #define EHTRACE_RESET 21 | 22 | #define _VCRT_VERIFY(x) 23 | 24 | #define __pSETranslator (_se_translator_function&)(__vcrt_getptd()->_translator) 25 | -------------------------------------------------------------------------------- /src/custom/msvc/141/include/vcwininternls.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define DISABLE_SHRINK_WRAPPING() 6 | #define ENABLE_SHRINK_WRAPPING() 7 | -------------------------------------------------------------------------------- /src/custom/msvc/142/crt/src/ehhelpers.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | EXTERN_C 4 | NTSYSAPI 5 | VOID 6 | NTAPI 7 | RtlUnwind( 8 | _In_opt_ PVOID TargetFrame, 9 | _In_opt_ PVOID TargetIp, 10 | _In_opt_ PEXCEPTION_RECORD ExceptionRecord, 11 | _In_ PVOID ReturnValue 12 | ); 13 | 14 | #include -------------------------------------------------------------------------------- /src/custom/msvc/142/crt/src/i386/trnsctrl_redirect.cpp: -------------------------------------------------------------------------------- 1 | #include <../i386/trnsctrl.cpp> -------------------------------------------------------------------------------- /src/custom/msvc/142/crt/src/misc/cfg_support.inc: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | 5 | 6 | 7 | extern 8 | __forceinline 9 | void 10 | __fastcall 11 | _guard_check_icall_nop ( 12 | _In_ uintptr_t Target 13 | ) 14 | 15 | /*++ 16 | 17 | Routine Description: 18 | 19 | This function performs a no-op check when invoked by the compiler to check 20 | the integrity of a function pointer for Control Flow Guard (/guard). 21 | 22 | Arguments: 23 | 24 | Target - Supplies the function pointer to check. 25 | 26 | Return Value: 27 | 28 | None. 29 | 30 | --*/ 31 | 32 | { 33 | 34 | UNREFERENCED_PARAMETER(Target); 35 | return; 36 | } 37 | 38 | extern 39 | __forceinline 40 | int 41 | _guard_icall_checks_enforced ( 42 | VOID 43 | ) 44 | 45 | /*++ 46 | 47 | Routine Description: 48 | 49 | This function determines whether Control Flow Guard is enforced for the 50 | current module. 51 | 52 | Arguments: 53 | 54 | None. 55 | 56 | Return Value: 57 | 58 | A nonzero value is returned as the function value if Control Flow Guard 59 | is enforced for the current module. 60 | 61 | --*/ 62 | 63 | { 64 | 65 | return (ReadPointerNoFence(&__guard_check_icall_fptr) != (PVOID)_guard_check_icall_nop); 66 | } -------------------------------------------------------------------------------- /src/custom/msvc/142/crt/src/vcruntime/frame_redirect.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include "ehhelpers.h" 13 | 14 | #if defined(_M_ARM64EC) 15 | #include //PDISPATCHER_CONTEXT_ARM64EC 16 | #include 17 | #endif 18 | 19 | // 20 | // frame.cpp 21 | // 22 | // intptr_t continuationIndex = reinterpret_cast(continuationAddress); 23 | // 24 | // to 25 | // 26 | // uintptr_t continuationIndex = reinterpret_cast(continuationAddress); 27 | // 28 | #define intptr_t uintptr_t 29 | 30 | #include -------------------------------------------------------------------------------- /src/custom/msvc/142/crt/src/vcruntime/std_type_info.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // _unDName function is not implemented yet. 3 | // 4 | 5 | #include 6 | 7 | EXTERN_C int __cdecl __std_type_info_compare ( 8 | __std_type_info_data const* const lhs, 9 | __std_type_info_data const* const rhs 10 | ) 11 | { 12 | if (lhs == rhs) 13 | { 14 | return 0; 15 | } 16 | 17 | return strcmp(lhs->_DecoratedName + 1, rhs->_DecoratedName + 1); 18 | } -------------------------------------------------------------------------------- /src/custom/msvc/142/include/arm64/arm64asmsymbolname.h: -------------------------------------------------------------------------------- 1 | #define A64NAME(name) name 2 | 3 | ; 4 | -------------------------------------------------------------------------------- /src/custom/msvc/142/include/ehassert.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifdef _DEBUG 6 | int dprintf( char *, ... ); 7 | #define DASSERT(c) ((c)?0: \ 8 | (DbgPrint("Runtime internal error (%s, line %d)", __FILE__, __LINE__),\ 9 | terminate())) 10 | 11 | #define DEXPECT(c) ((c)?0: \ 12 | DbgPrint("Runtime internal error suspected (%s, line %d)", __FILE__, __LINE__)) 13 | #else 14 | #define dprintf 15 | #define DASSERT(c) (c) 16 | #define DEXPECT(c) (c) 17 | #endif 18 | 19 | #define EHTRACE_RESET 20 | #define EHTRACE_SAVE_LEVEL 21 | #define EHTRACE_RESTORE_LEVEL(x) 22 | #define EHTRACE_ENTER 23 | #define EHTRACE_ENTER_MSG(x) 24 | #define EHTRACE_ENTER_FMT1(x,y) 25 | #define EHTRACE_ENTER_FMT2(x,y,z) 26 | #define EHTRACE_MSG(x) 27 | #define EHTRACE_FMT1(x,y) 28 | #define EHTRACE_FMT2(x,y,z) 29 | #define EHTRACE_EXCEPT(x) (x) 30 | #define EHTRACE_EXIT 31 | #define EHTRACE_HANDLER_EXIT(x) 32 | 33 | // ??? 34 | #define _VCRT_VERIFY(x) 35 | 36 | // #pragma once 37 | 38 | // #include 39 | // #include 40 | 41 | // #if !defined(RENAME_BASE_PTD) 42 | // #if defined _VCRT_SAT_1 43 | // #define RENAME_BASE_PTD(x) x##base 44 | // #else 45 | // #define RENAME_BASE_PTD(x) x 46 | // #endif 47 | // #endif 48 | -------------------------------------------------------------------------------- /src/custom/msvc/142/include/ehhooks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define __pSETranslator (_se_translator_function&)(__vcrt_getptd()->_translator) 6 | -------------------------------------------------------------------------------- /src/custom/msvc/142/include/vcwininternls.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifndef DISABLE_SHRINK_WRAPPING 6 | #define DISABLE_SHRINK_WRAPPING() 7 | #endif 8 | 9 | #ifndef ENABLE_SHRINK_WRAPPING 10 | #define ENABLE_SHRINK_WRAPPING() 11 | #endif -------------------------------------------------------------------------------- /src/custom/msvc/143/crt/src/ehhelpers.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | EXTERN_C 4 | NTSYSAPI 5 | VOID 6 | NTAPI 7 | RtlUnwind( 8 | _In_opt_ PVOID TargetFrame, 9 | _In_opt_ PVOID TargetIp, 10 | _In_opt_ PEXCEPTION_RECORD ExceptionRecord, 11 | _In_ PVOID ReturnValue 12 | ); 13 | 14 | #include -------------------------------------------------------------------------------- /src/custom/msvc/143/crt/src/i386/trnsctrl_redirect.cpp: -------------------------------------------------------------------------------- 1 | #include <../i386/trnsctrl.cpp> -------------------------------------------------------------------------------- /src/custom/msvc/143/crt/src/misc/cfg_support.inc: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | 5 | 6 | 7 | extern 8 | __forceinline 9 | void 10 | __fastcall 11 | _guard_check_icall_nop ( 12 | _In_ uintptr_t Target 13 | ) 14 | 15 | /*++ 16 | 17 | Routine Description: 18 | 19 | This function performs a no-op check when invoked by the compiler to check 20 | the integrity of a function pointer for Control Flow Guard (/guard). 21 | 22 | Arguments: 23 | 24 | Target - Supplies the function pointer to check. 25 | 26 | Return Value: 27 | 28 | None. 29 | 30 | --*/ 31 | 32 | { 33 | 34 | UNREFERENCED_PARAMETER(Target); 35 | return; 36 | } 37 | 38 | extern 39 | __forceinline 40 | int 41 | _guard_icall_checks_enforced ( 42 | VOID 43 | ) 44 | 45 | /*++ 46 | 47 | Routine Description: 48 | 49 | This function determines whether Control Flow Guard is enforced for the 50 | current module. 51 | 52 | Arguments: 53 | 54 | None. 55 | 56 | Return Value: 57 | 58 | A nonzero value is returned as the function value if Control Flow Guard 59 | is enforced for the current module. 60 | 61 | --*/ 62 | 63 | { 64 | 65 | return (ReadPointerNoFence(&__guard_check_icall_fptr) != (PVOID)_guard_check_icall_nop); 66 | } -------------------------------------------------------------------------------- /src/custom/msvc/143/crt/src/vcruntime/frame_redirect.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MSVC\14.33.31629\include\eh.h 3 | // _VCRT_COMPILER_PREPROCESSOR가 1이면서 _VCRT_BUILD가 정의되어있어야 unexpected 함수가 정의됩니다. 4 | // 5 | #define _VCRT_COMPILER_PREPROCESSOR 1 6 | #define _VCRT_BUILD 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include "ehhelpers.h" 20 | 21 | #if defined(_M_ARM64EC) 22 | #include //PDISPATCHER_CONTEXT_ARM64EC 23 | #include 24 | #endif 25 | 26 | // 27 | // frame.cpp 28 | // 29 | // intptr_t continuationIndex = reinterpret_cast(continuationAddress); 30 | // 31 | // to 32 | // 33 | // uintptr_t continuationIndex = reinterpret_cast(continuationAddress); 34 | // 35 | #define intptr_t uintptr_t 36 | 37 | #include -------------------------------------------------------------------------------- /src/custom/msvc/143/crt/src/vcruntime/std_type_info.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // _unDName function is not implemented yet. 3 | // 4 | 5 | #include 6 | 7 | EXTERN_C int __cdecl __std_type_info_compare ( 8 | __std_type_info_data const* const lhs, 9 | __std_type_info_data const* const rhs 10 | ) 11 | { 12 | if (lhs == rhs) 13 | { 14 | return 0; 15 | } 16 | 17 | return strcmp(lhs->_DecoratedName + 1, rhs->_DecoratedName + 1); 18 | } -------------------------------------------------------------------------------- /src/custom/msvc/143/include/arm64/arm64asmsymbolname.h: -------------------------------------------------------------------------------- 1 | #define A64NAME(name) name 2 | 3 | ; 4 | -------------------------------------------------------------------------------- /src/custom/msvc/143/include/ehassert.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifdef _DEBUG 6 | int dprintf( char *, ... ); 7 | #define DASSERT(c) ((c)?0: \ 8 | (DbgPrint("Runtime internal error (%s, line %d)", __FILE__, __LINE__),\ 9 | terminate())) 10 | 11 | #define DEXPECT(c) ((c)?0: \ 12 | DbgPrint("Runtime internal error suspected (%s, line %d)", __FILE__, __LINE__)) 13 | #else 14 | #define dprintf 15 | #define DASSERT(c) (c) 16 | #define DEXPECT(c) (c) 17 | #endif 18 | 19 | #define EHTRACE_RESET 20 | #define EHTRACE_SAVE_LEVEL 21 | #define EHTRACE_RESTORE_LEVEL(x) 22 | #define EHTRACE_ENTER 23 | #define EHTRACE_ENTER_MSG(x) 24 | #define EHTRACE_ENTER_FMT1(x,y) 25 | #define EHTRACE_ENTER_FMT2(x,y,z) 26 | #define EHTRACE_MSG(x) 27 | #define EHTRACE_FMT1(x,y) 28 | #define EHTRACE_FMT2(x,y,z) 29 | #define EHTRACE_EXCEPT(x) (x) 30 | #define EHTRACE_EXIT 31 | #define EHTRACE_HANDLER_EXIT(x) 32 | 33 | // ??? 34 | #define _VCRT_VERIFY(x) 35 | 36 | // #pragma once 37 | 38 | // #include 39 | // #include 40 | 41 | // #if !defined(RENAME_BASE_PTD) 42 | // #if defined _VCRT_SAT_1 43 | // #define RENAME_BASE_PTD(x) x##base 44 | // #else 45 | // #define RENAME_BASE_PTD(x) x 46 | // #endif 47 | // #endif 48 | -------------------------------------------------------------------------------- /src/custom/msvc/143/include/ehhooks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define __pSETranslator (_se_translator_function&)(__vcrt_getptd()->_translator) 6 | -------------------------------------------------------------------------------- /src/custom/msvc/143/include/vcwininternls.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifndef DISABLE_SHRINK_WRAPPING 6 | #define DISABLE_SHRINK_WRAPPING() 7 | #endif 8 | 9 | #ifndef ENABLE_SHRINK_WRAPPING 10 | #define ENABLE_SHRINK_WRAPPING() 11 | #endif -------------------------------------------------------------------------------- /src/custom/msvc/common/crt/src/stl/winapisupp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | EXTERN_C_START 5 | 6 | #if _STL_WIN32_WINNT < _WIN32_WINNT_WIN8 7 | void __cdecl __crtGetSystemTimePreciseAsFileTime( 8 | _Out_ LPFILETIME lpSystemTimeAsFileTime) { 9 | GetSystemTimeAsFileTime(lpSystemTimeAsFileTime); 10 | } 11 | #endif // _STL_WIN32_WINNT < _WIN32_WINNT_WIN8 12 | 13 | BOOL __cdecl __crtQueueUserWorkItem(__in LPTHREAD_START_ROUTINE function, 14 | __in_opt PVOID context, __in ULONG flags) { 15 | return QueueUserWorkItem(function, context, flags); 16 | } 17 | 18 | #pragma warning(disable : 4100) 19 | 20 | int __cdecl __crtLCMapStringA(LPCWSTR LocaleName, DWORD dwMapFlags, 21 | LPCSTR lpSrcStr, int cchSrc, LPSTR lpDestStr, 22 | int cchDest, int code_page, BOOL bError) { 23 | KdBreakPoint(); 24 | return 0; 25 | } 26 | 27 | int __cdecl __crtLCMapStringW(LPCWSTR const locale_name, DWORD const map_flags, 28 | LPCWSTR const source, int source_count, 29 | LPWSTR const destination, 30 | int const destination_count) { 31 | KdBreakPoint(); 32 | return 0; 33 | } 34 | 35 | int __cdecl __crtCompareStringA(LPCWSTR LocaleName, DWORD dwCmpFlags, 36 | LPCSTR lpString1, int cchCount1, 37 | LPCSTR lpString2, int cchCount2, 38 | int code_page) { 39 | KdBreakPoint(); 40 | return 0; 41 | } 42 | 43 | int __cdecl __crtCompareStringW(LPCWSTR LocaleName, DWORD dwCmpFlags, 44 | LPCWSTR lpString1, int cchCount1, 45 | LPCWSTR lpString2, int cchCount2) { 46 | KdBreakPoint(); 47 | return 0; 48 | } 49 | 50 | BOOL __cdecl __crtGetStringTypeA(_In_opt_ _locale_t _Plocinfo, 51 | _In_ DWORD _DWInfoType, _In_ LPCSTR _LpSrcStr, 52 | _In_ int _CchSrc, _Out_ LPWORD _LpCharType, 53 | _In_ int _Code_page, _In_ int _Lcid, 54 | _In_ BOOL _BError) { 55 | KdBreakPoint(); 56 | return FALSE; 57 | } 58 | 59 | EXTERN_C_END -------------------------------------------------------------------------------- /src/custom/msvc/crt.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | $(VC_CRT_SourcePath.Split(%3B)[0])\\vcruntime;$(VC_CRT_SourcePath.Split(%3B)[0])\\stl;%(AdditionalIncludeDirectories) 7 | %(PreprocessorDefinitions);_STL_WIN32_WINNT=_WIN32_WINNT;_VCRT_WIN32_WINNT=_WIN32_WINNT;_VCRT_ALLOW_INTERNALS;_CRT_WINDOWS_USE_VISTA_TSS;_CRTIMP_ALT;_CRTBLD;_KERNELX;_HAS_EXCEPTIONS=1;_ITERATOR_DEBUG_LEVEL=0; 8 | stdcpplatest 9 | 10 | 11 | 12 | 13 | 14 | Cdecl 15 | 16 | 17 | 18 | Cdecl 19 | 20 | 21 | 22 | 23 | Cdecl 24 | 25 | 26 | 27 | 28 | Cdecl 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/custom/private/ehassert.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define EHTRACE_ENTER_FMT1(...) 6 | #define EHTRACE_ENTER_FMT2(...) 7 | #define EHTRACE_FMT1(...) 8 | #define EHTRACE_FMT2(...) 9 | 10 | #define EHTRACE_ENTER 11 | #define EHTRACE_EXIT 12 | #define EHTRACE_EXCEPT(x) x 13 | #define EHTRACE_HANDLER_EXIT(x) 14 | #define EHTRACE_SAVE_LEVEL 15 | #define EHTRACE_RESTORE_LEVEL(x) 16 | 17 | #define EHTRACE_RESET 18 | 19 | #define _VCRT_VERIFY(x) 20 | 21 | // 22 | // frame.cpp 23 | // 24 | // intptr_t continuationIndex = reinterpret_cast(continuationAddress); 25 | // 26 | // to 27 | // 28 | // uintptr_t continuationIndex = reinterpret_cast(continuationAddress); 29 | // 30 | #define intptr_t uintptr_t 31 | 32 | #if !defined(DASSERT) 33 | #if !defined(_VCRT_BUILD) && defined(_DEBUG) 34 | #include 35 | #define DASSERT(x) assert(x) 36 | #else 37 | #define DASSERT(x) 38 | #endif 39 | #else 40 | // This is an FE build; DASSERT is defined properly 41 | #endif -------------------------------------------------------------------------------- /src/custom/private/ehhooks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define __pSETranslator (_se_translator_function&)(__vcrt_getptd()->_translator) 10 | -------------------------------------------------------------------------------- /src/custom/private/vcwininternls.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define DISABLE_SHRINK_WRAPPING() 6 | #define ENABLE_SHRINK_WRAPPING() 7 | -------------------------------------------------------------------------------- /src/custom/ucrt/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Microsoft -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.17763.0/inc/corecrt_internal_state_isolation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define __acrt_select_exit_lock() __acrt_exit_lock 4 | 5 | #pragma warning(disable : 4101) 6 | #ifdef __cplusplus 7 | 8 | extern "C++" 9 | { 10 | namespace __crt_state_management 11 | { 12 | struct scoped_global_state_reset 13 | { 14 | }; 15 | 16 | const size_t state_index_count = 2; 17 | 18 | inline bool initialize_global_state_isolation() 19 | { 20 | return true; 21 | } 22 | 23 | inline void uninitialize_global_state_isolation(bool const terminating) 24 | { 25 | terminating; 26 | } 27 | 28 | inline int get_current_state_index() 29 | { 30 | return 0; 31 | } 32 | 33 | inline int get_current_state_index(__crt_scoped_get_last_error_reset const &last_error_reset) 34 | { 35 | last_error_reset; 36 | return 0; 37 | } 38 | 39 | template class dual_state_global 40 | { 41 | public: 42 | T &value() 43 | { 44 | return _value[0]; 45 | } 46 | 47 | void initialize(const T &value) 48 | { 49 | for (size_t i = 0; i != state_index_count; i++) 50 | _value[i] = value; 51 | } 52 | 53 | template void initialize_from_array(Ta (&arr)[2]) 54 | { 55 | for (size_t i = 0; i != state_index_count; i++) 56 | _value[i] = arr[i]; 57 | } 58 | 59 | template void uninitialize(Fn &&fn) 60 | { 61 | for (size_t i = 0; i != state_index_count; i++) 62 | fn(_value[i]); 63 | } 64 | 65 | T *const dangerous_get_state_array() 66 | { 67 | return reinterpret_cast(&_value); 68 | } 69 | 70 | T _value[state_index_count]; 71 | }; 72 | } // namespace __crt_state_management 73 | } 74 | #endif -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.17763.0/inc/nt.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define FLG_APPLICATION_VERIFIER 0x0100 4 | 5 | typedef struct _LDK_PEB { 6 | ULONG NtGlobalFlag; 7 | } LDK_PEB, *PLDK_PEB; 8 | 9 | -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.17763.0/inc/ntrtl.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ntoskrnl7/crtsys/604b68e6e02484e9d8c510fa5e445957c74d83f2/src/custom/ucrt/10.0.17763.0/inc/ntrtl.h -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.17763.0/inc/nturtl.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ntoskrnl7/crtsys/604b68e6e02484e9d8c510fa5e445957c74d83f2/src/custom/ucrt/10.0.17763.0/inc/nturtl.h -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.19041.0/inc/corecrt_internal_state_isolation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define __acrt_select_exit_lock() __acrt_exit_lock 4 | 5 | #pragma warning(disable : 4101) 6 | #ifdef __cplusplus 7 | 8 | extern "C++" 9 | { 10 | namespace __crt_state_management 11 | { 12 | struct scoped_global_state_reset 13 | { 14 | }; 15 | 16 | const size_t state_index_count = 2; 17 | 18 | inline bool initialize_global_state_isolation() 19 | { 20 | return true; 21 | } 22 | 23 | inline void uninitialize_global_state_isolation(bool const terminating) 24 | { 25 | terminating; 26 | } 27 | 28 | inline int get_current_state_index() 29 | { 30 | return 0; 31 | } 32 | 33 | inline int get_current_state_index(__crt_scoped_get_last_error_reset const &last_error_reset) 34 | { 35 | last_error_reset; 36 | return 0; 37 | } 38 | 39 | template class dual_state_global 40 | { 41 | public: 42 | T &value() 43 | { 44 | return _value[0]; 45 | } 46 | 47 | void initialize(const T &value) 48 | { 49 | for (size_t i = 0; i != state_index_count; i++) 50 | _value[i] = value; 51 | } 52 | 53 | template void initialize_from_array(Ta (&arr)[2]) 54 | { 55 | for (size_t i = 0; i != state_index_count; i++) 56 | _value[i] = arr[i]; 57 | } 58 | 59 | template void uninitialize(Fn &&fn) 60 | { 61 | for (size_t i = 0; i != state_index_count; i++) 62 | fn(_value[i]); 63 | } 64 | 65 | T *const dangerous_get_state_array() 66 | { 67 | return reinterpret_cast(&_value); 68 | } 69 | 70 | T _value[state_index_count]; 71 | }; 72 | } // namespace __crt_state_management 73 | } 74 | #endif -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.19041.0/inc/nt.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define FLG_APPLICATION_VERIFIER 0x0100 4 | 5 | typedef struct _LDK_PEB { 6 | ULONG NtGlobalFlag; 7 | } LDK_PEB, *PLDK_PEB; 8 | 9 | -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.19041.0/inc/ntrtl.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ntoskrnl7/crtsys/604b68e6e02484e9d8c510fa5e445957c74d83f2/src/custom/ucrt/10.0.19041.0/inc/ntrtl.h -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.19041.0/inc/nturtl.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ntoskrnl7/crtsys/604b68e6e02484e9d8c510fa5e445957c74d83f2/src/custom/ucrt/10.0.19041.0/inc/nturtl.h -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.22000.0/inc/corecrt_internal_state_isolation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define __acrt_select_exit_lock() __acrt_exit_lock 4 | 5 | #pragma warning(disable : 4101) 6 | #ifdef __cplusplus 7 | 8 | extern "C++" 9 | { 10 | namespace __crt_state_management 11 | { 12 | struct scoped_global_state_reset 13 | { 14 | }; 15 | 16 | const size_t state_index_count = 2; 17 | 18 | inline bool initialize_global_state_isolation() 19 | { 20 | return true; 21 | } 22 | 23 | inline void uninitialize_global_state_isolation(bool const terminating) 24 | { 25 | terminating; 26 | } 27 | 28 | inline int get_current_state_index() 29 | { 30 | return 0; 31 | } 32 | 33 | inline int get_current_state_index(__crt_scoped_get_last_error_reset const &last_error_reset) 34 | { 35 | last_error_reset; 36 | return 0; 37 | } 38 | 39 | template class dual_state_global 40 | { 41 | public: 42 | T &value() 43 | { 44 | return _value[0]; 45 | } 46 | 47 | T &value_explicit(size_t const current_global_state_index) 48 | { 49 | return _value[current_global_state_index]; 50 | } 51 | 52 | T &value(__crt_cached_ptd_host &ptd) throw(); 53 | 54 | T const &value(__crt_cached_ptd_host &ptd) const throw(); 55 | 56 | void initialize(const T &value) 57 | { 58 | for (size_t i = 0; i != state_index_count; i++) 59 | _value[i] = value; 60 | } 61 | 62 | template void initialize_from_array(Ta (&arr)[2]) 63 | { 64 | for (size_t i = 0; i != state_index_count; i++) 65 | _value[i] = arr[i]; 66 | } 67 | 68 | template void uninitialize(Fn &&fn) 69 | { 70 | for (size_t i = 0; i != state_index_count; i++) 71 | fn(_value[i]); 72 | } 73 | 74 | T *const dangerous_get_state_array() 75 | { 76 | return reinterpret_cast(&_value); 77 | } 78 | 79 | T _value[state_index_count]; 80 | }; 81 | } // namespace __crt_state_management 82 | } 83 | #endif -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.22000.0/inc/nt.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define FLG_APPLICATION_VERIFIER 0x0100 4 | 5 | typedef struct _LDK_PEB { 6 | ULONG NtGlobalFlag; 7 | } LDK_PEB, *PLDK_PEB; 8 | 9 | -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.22000.0/inc/ntrtl.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ntoskrnl7/crtsys/604b68e6e02484e9d8c510fa5e445957c74d83f2/src/custom/ucrt/10.0.22000.0/inc/ntrtl.h -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.22000.0/inc/nturtl.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ntoskrnl7/crtsys/604b68e6e02484e9d8c510fa5e445957c74d83f2/src/custom/ucrt/10.0.22000.0/inc/nturtl.h -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.22621.0/inc/corecrt_internal_state_isolation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define __acrt_select_exit_lock() __acrt_exit_lock 4 | 5 | #pragma warning(disable : 4101) 6 | #ifdef __cplusplus 7 | 8 | extern "C++" 9 | { 10 | namespace __crt_state_management 11 | { 12 | struct scoped_global_state_reset 13 | { 14 | }; 15 | 16 | const size_t state_index_count = 2; 17 | 18 | inline bool initialize_global_state_isolation() 19 | { 20 | return true; 21 | } 22 | 23 | inline void uninitialize_global_state_isolation(bool const terminating) 24 | { 25 | terminating; 26 | } 27 | 28 | inline int get_current_state_index() 29 | { 30 | return 0; 31 | } 32 | 33 | inline int get_current_state_index(__crt_scoped_get_last_error_reset const &last_error_reset) 34 | { 35 | last_error_reset; 36 | return 0; 37 | } 38 | 39 | template class dual_state_global 40 | { 41 | public: 42 | T &value() 43 | { 44 | return _value[0]; 45 | } 46 | 47 | T &value_explicit(size_t const current_global_state_index) 48 | { 49 | return _value[current_global_state_index]; 50 | } 51 | 52 | T &value(__crt_cached_ptd_host &ptd) throw(); 53 | 54 | T const &value(__crt_cached_ptd_host &ptd) const throw(); 55 | 56 | void initialize(const T &value) 57 | { 58 | for (size_t i = 0; i != state_index_count; i++) 59 | _value[i] = value; 60 | } 61 | 62 | template void initialize_from_array(Ta (&arr)[2]) 63 | { 64 | for (size_t i = 0; i != state_index_count; i++) 65 | _value[i] = arr[i]; 66 | } 67 | 68 | template void uninitialize(Fn &&fn) 69 | { 70 | for (size_t i = 0; i != state_index_count; i++) 71 | fn(_value[i]); 72 | } 73 | 74 | T *const dangerous_get_state_array() 75 | { 76 | return reinterpret_cast(&_value); 77 | } 78 | 79 | T _value[state_index_count]; 80 | }; 81 | } // namespace __crt_state_management 82 | } 83 | #endif -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.22621.0/inc/nt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.22621.0/inc/ntrtl.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ntoskrnl7/crtsys/604b68e6e02484e9d8c510fa5e445957c74d83f2/src/custom/ucrt/10.0.22621.0/inc/ntrtl.h -------------------------------------------------------------------------------- /src/custom/ucrt/10.0.22621.0/inc/nturtl.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ntoskrnl7/crtsys/604b68e6e02484e9d8c510fa5e445957c74d83f2/src/custom/ucrt/10.0.22621.0/inc/nturtl.h -------------------------------------------------------------------------------- /src/custom/ucrt/common/internal/winapi_thunks.cpp: -------------------------------------------------------------------------------- 1 | #define WIN32_LEAN_AND_MEAN 2 | #include 3 | 4 | extern "C" bool __cdecl __acrt_uninitialize_winapi_thunks(bool const terminating) 5 | { 6 | UNREFERENCED_PARAMETER(terminating); 7 | return true; 8 | } 9 | 10 | extern "C" BOOL WINAPI __acrt_InitializeCriticalSectionEx(LPCRITICAL_SECTION const critical_section, 11 | DWORD const spin_count, DWORD const flags) 12 | { 13 | UNREFERENCED_PARAMETER(flags); 14 | return InitializeCriticalSectionAndSpinCount(critical_section, spin_count); 15 | } 16 | 17 | extern "C" DWORD WINAPI __acrt_FlsAlloc(PFLS_CALLBACK_FUNCTION const callback) 18 | { 19 | return FlsAlloc(callback); 20 | } 21 | 22 | extern "C" BOOL WINAPI __acrt_FlsFree(DWORD const fls_index) 23 | { 24 | return FlsFree(fls_index); 25 | } 26 | 27 | extern "C" PVOID WINAPI __acrt_FlsGetValue(DWORD const fls_index) 28 | { 29 | return FlsGetValue(fls_index); 30 | } 31 | 32 | extern "C" BOOL WINAPI __acrt_FlsSetValue(DWORD const fls_index, PVOID const fls_data) 33 | { 34 | return FlsSetValue(fls_index, fls_data); 35 | } 36 | 37 | extern "C" BOOL WINAPI __acrt_AreFileApisANSI() 38 | { 39 | return AreFileApisANSI(); 40 | } 41 | 42 | extern "C" 43 | _Success_(return != 0) 44 | int __cdecl __acrt_MultiByteToWideChar( 45 | _In_ UINT _CodePage, 46 | _In_ DWORD _DWFlags, 47 | _In_ LPCSTR _LpMultiByteStr, 48 | _In_ int _CbMultiByte, 49 | _Out_writes_opt_(_CchWideChar) LPWSTR _LpWideCharStr, 50 | _In_ int _CchWideChar 51 | ) 52 | { 53 | return MultiByteToWideChar(_CodePage, _DWFlags, _LpMultiByteStr, _CbMultiByte, _LpWideCharStr, _CchWideChar); 54 | } 55 | 56 | extern "C" 57 | _Success_(return != 0) 58 | int __cdecl __acrt_WideCharToMultiByte( 59 | _In_ UINT _CodePage, 60 | _In_ DWORD _DWFlags, 61 | _In_ LPCWSTR _LpWideCharStr, 62 | _In_ int _CchWideChar, 63 | _Out_writes_opt_(_CbMultiByte) LPSTR _LpMultiByteStr, 64 | _In_ int _CbMultiByte, 65 | _In_opt_ LPCSTR _LpDefaultChar, 66 | _Out_opt_ LPBOOL _LpUsedDefaultChar 67 | ) 68 | { 69 | return WideCharToMultiByte(_CodePage, _DWFlags, _LpWideCharStr, _CchWideChar, _LpMultiByteStr, _CbMultiByte, _LpDefaultChar, _LpUsedDefaultChar); 70 | } 71 | 72 | extern "C" int WINAPI __acrt_GetUserDefaultLocaleName( 73 | LPWSTR const locale_name, 74 | int const locale_name_count 75 | ) 76 | { 77 | return GetUserDefaultLocaleName(locale_name, locale_name_count); 78 | } 79 | 80 | extern "C" int WINAPI __acrt_LCIDToLocaleName( 81 | LCID const locale, 82 | LPWSTR const name, 83 | int const name_count, 84 | DWORD const flags 85 | ) 86 | { 87 | return LCIDToLocaleName(locale, name, name_count, flags); 88 | } 89 | 90 | extern "C" LCID WINAPI __acrt_LocaleNameToLCID( 91 | LPCWSTR const name, 92 | DWORD const flags 93 | ) 94 | { 95 | return LocaleNameToLCID(name, flags); 96 | } 97 | 98 | extern "C" BOOL WINAPI __acrt_IsValidLocaleName(LPCWSTR const locale_name) 99 | { 100 | return IsValidLocale(__acrt_LocaleNameToLCID(locale_name, 0), LCID_INSTALLED); 101 | } 102 | 103 | 104 | 105 | #define _CORECRT_BUILD 106 | #define _CRT_GLOBAL_STATE_ISOLATION 107 | #define _CRT_DECLARE_GLOBAL_VARIABLES_DIRECTLY 108 | #include 109 | 110 | #pragma warning(disable : 4100) 111 | 112 | extern "C" HRESULT WINAPI __acrt_RoInitialize(RO_INIT_TYPE const init_type) 113 | { 114 | return S_OK; 115 | } 116 | 117 | extern "C" void WINAPI __acrt_RoUninitialize() 118 | { 119 | } 120 | 121 | extern "C" void __cdecl __acrt_eagerly_load_locale_apis() 122 | { 123 | } 124 | 125 | extern "C" 126 | begin_thread_init_policy __cdecl __acrt_get_begin_thread_init_policy() 127 | { 128 | return begin_thread_init_policy_none; 129 | } 130 | 131 | extern "C" BOOL WINAPI __acrt_EnumSystemLocalesEx( 132 | LOCALE_ENUMPROCEX const enum_proc, 133 | DWORD const flags, 134 | LPARAM const param, 135 | LPVOID const reserved 136 | ) 137 | { 138 | return EnumSystemLocalesEx(enum_proc, flags, param, reserved); 139 | } 140 | 141 | extern "C" int WINAPI __acrt_GetDateFormatEx( 142 | LPCWSTR const locale_name, 143 | DWORD const flags, 144 | SYSTEMTIME CONST* const date, 145 | LPCWSTR const format, 146 | LPWSTR const buffer, 147 | int const buffer_count, 148 | LPCWSTR const calendar 149 | ) 150 | { 151 | return GetDateFormatW(__acrt_LocaleNameToLCID(locale_name, 0), flags, date, format, buffer, buffer_count); 152 | } 153 | 154 | extern "C" int WINAPI __acrt_GetTimeFormatEx( 155 | LPCWSTR const locale_name, 156 | DWORD const flags, 157 | SYSTEMTIME CONST* const time, 158 | LPCWSTR const format, 159 | LPWSTR const buffer, 160 | int const buffer_count 161 | ) 162 | { 163 | return GetTimeFormatW(__acrt_LocaleNameToLCID(locale_name, 0), flags, time, format, buffer, buffer_count); 164 | } 165 | 166 | extern "C" int WINAPI __acrt_GetLocaleInfoEx( 167 | LPCWSTR const locale_name, 168 | LCTYPE const lc_type, 169 | LPWSTR const data, 170 | int const data_count 171 | ) 172 | { 173 | return GetLocaleInfoW(__acrt_LocaleNameToLCID(locale_name, 0), lc_type, data, data_count); 174 | } 175 | 176 | extern "C" 177 | int __cdecl __acrt_GetLocaleInfoA(_locale_t const locale, int const lc_type, wchar_t const *const locale_name, 178 | LCTYPE const locale_type, void *const void_result) 179 | { 180 | return 0; 181 | } 182 | 183 | extern "C" int __cdecl __acrt_LCMapStringA(_locale_t const plocinfo, PCWSTR const LocaleName, DWORD const dwMapFlags, 184 | PCCH const lpSrcStr, int const cchSrc, PCH const lpDestStr, 185 | int const cchDest, int const code_page, BOOL const bError) 186 | { 187 | return 0; 188 | } 189 | 190 | extern "C" int WINAPI __acrt_MessageBoxA( 191 | HWND const hwnd, 192 | LPCSTR const text, 193 | LPCSTR const caption, 194 | UINT const type 195 | ) 196 | { 197 | KdBreakPoint(); 198 | SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 199 | return 0; 200 | // abort(); // No fallback; callers should check availablility before calling 201 | } 202 | 203 | extern "C" int WINAPI __acrt_MessageBoxW( 204 | HWND const hwnd, 205 | LPCWSTR const text, 206 | LPCWSTR const caption, 207 | UINT const type 208 | ) 209 | { 210 | KdBreakPoint(); 211 | SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 212 | return 0; 213 | // abort(); // No fallback; callers should check availablility before calling 214 | } 215 | 216 | extern "C" bool __cdecl __acrt_can_use_vista_locale_apis() 217 | { 218 | return true; 219 | } 220 | 221 | extern "C" bool __cdecl __acrt_initialize_winapi_thunks() 222 | { 223 | return true; 224 | } 225 | 226 | extern "C" HWND __cdecl __acrt_get_parent_window() 227 | { 228 | return nullptr; 229 | } 230 | 231 | extern "C" bool __cdecl __acrt_is_interactive() 232 | { 233 | return true; 234 | } 235 | 236 | extern "C" bool __cdecl __acrt_can_show_message_box() 237 | { 238 | return false; 239 | } 240 | 241 | // 242 | // unexported sources 243 | // 244 | void __cdecl __acrt_initialize_user_matherr(void* encoded_null) 245 | { 246 | } 247 | 248 | extern "C" process_end_policy __cdecl __acrt_get_process_end_policy(void) 249 | { 250 | return process_end_policy_terminate_process; 251 | } 252 | 253 | extern "C" developer_information_policy __cdecl __acrt_get_developer_information_policy(void) 254 | { 255 | return developer_information_policy_none; 256 | } 257 | 258 | extern "C" windowing_model_policy __cdecl __acrt_get_windowing_model_policy(void) 259 | { 260 | return windowing_model_policy_none; 261 | } -------------------------------------------------------------------------------- /src/custom/ucrt/common/startup/argv_parsing.cpp: -------------------------------------------------------------------------------- 1 | #define _CORECRT_BUILD 2 | #define _CRT_GLOBAL_STATE_ISOLATION 3 | #define _CRT_DECLARE_GLOBAL_VARIABLES_DIRECTLY 4 | #include 5 | 6 | extern "C" errno_t __cdecl _configure_narrow_argv(_crt_argv_mode const mode) 7 | { 8 | mode; 9 | return 0; 10 | } -------------------------------------------------------------------------------- /src/custom/winsdk/include/um/crtsys/WinBase.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRTSYS_WINBASE_ 2 | #define _CRTSYS_WINBASE_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "fileapi.h" 10 | #include "processthreadsapi.h" 11 | 12 | 13 | 14 | #define OFS_MAXPATHNAME 128 15 | typedef struct _OFSTRUCT { 16 | BYTE cBytes; 17 | BYTE fFixedDisk; 18 | WORD nErrCode; 19 | WORD Reserved1; 20 | WORD Reserved2; 21 | CHAR szPathName[OFS_MAXPATHNAME]; 22 | } OFSTRUCT, *LPOFSTRUCT, *POFSTRUCT; 23 | 24 | #endif // _CRTSYS_WINBASE_ -------------------------------------------------------------------------------- /src/custom/winsdk/include/um/crtsys/WinNls.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRTSYS_WINNLS_ 2 | #define _CRTSYS_WINNLS_ 3 | 4 | #include 5 | 6 | #include "datetimeapi.h" 7 | #include "stringapiset.h" 8 | 9 | EXTERN_C_START 10 | 11 | // crt/src/stl/xdateord.cpp 12 | WINBASEAPI 13 | int WINAPI GetLocaleInfoEx(_In_opt_ LPCWSTR lpLocaleName, _In_ LCTYPE LCType, 14 | _Out_writes_to_opt_(cchData, return ) 15 | LPWSTR lpLCData, 16 | _In_ int cchData); 17 | 18 | 19 | 20 | // ucrt/internal/winapi_thunks.cpp 21 | WINBASEAPI 22 | int 23 | WINAPI 24 | GetLocaleInfoW( 25 | _In_ LCID Locale, 26 | _In_ LCTYPE LCType, 27 | _Out_writes_opt_(cchData) LPWSTR lpLCData, 28 | _In_ int cchData); 29 | 30 | 31 | // ucrt\locale\getqloc_downlevel.cpp 32 | typedef BOOL (CALLBACK* LOCALE_ENUMPROCW)(LPWSTR); // DEPRECATED: please use LOCALE_ENUMPROCEX 33 | 34 | WINBASEAPI 35 | BOOL 36 | WINAPI 37 | EnumSystemLocalesW( 38 | _In_ LOCALE_ENUMPROCW lpLocaleEnumProc, 39 | _In_ DWORD dwFlags); 40 | 41 | 42 | 43 | // ucrt/inc/corecrt_internal.h 44 | typedef BOOL (CALLBACK* LOCALE_ENUMPROCEX)(LPWSTR, DWORD, LPARAM); 45 | 46 | // ucrt/internal/winapi_thunks.cpp 47 | WINBASEAPI 48 | BOOL 49 | WINAPI 50 | EnumSystemLocalesEx( 51 | _In_ LOCALE_ENUMPROCEX lpLocaleEnumProcEx, 52 | _In_ DWORD dwFlags, 53 | _In_ LPARAM lParam, 54 | _In_opt_ LPVOID lpReserved 55 | ); 56 | 57 | EXTERN_C_END 58 | 59 | #endif // _CRTSYS_WINNLS_ 60 | -------------------------------------------------------------------------------- /src/custom/winsdk/include/um/crtsys/WinUser.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRTSYS_WINUSER_ 2 | #define _CRTSYS_WINUSER_ 3 | 4 | #include 5 | 6 | typedef struct tagMSG *LPMSG; 7 | 8 | 9 | 10 | #ifndef NOMB 11 | 12 | /* 13 | * MessageBox() Flags 14 | */ 15 | #define MB_OK 0x00000000L 16 | #define MB_OKCANCEL 0x00000001L 17 | #define MB_ABORTRETRYIGNORE 0x00000002L 18 | #define MB_YESNOCANCEL 0x00000003L 19 | #define MB_YESNO 0x00000004L 20 | #define MB_RETRYCANCEL 0x00000005L 21 | #if(WINVER >= 0x0500) 22 | #define MB_CANCELTRYCONTINUE 0x00000006L 23 | #endif /* WINVER >= 0x0500 */ 24 | 25 | 26 | #define MB_ICONHAND 0x00000010L 27 | #define MB_ICONQUESTION 0x00000020L 28 | #define MB_ICONEXCLAMATION 0x00000030L 29 | #define MB_ICONASTERISK 0x00000040L 30 | 31 | #if(WINVER >= 0x0400) 32 | #define MB_USERICON 0x00000080L 33 | #define MB_ICONWARNING MB_ICONEXCLAMATION 34 | #define MB_ICONERROR MB_ICONHAND 35 | #endif /* WINVER >= 0x0400 */ 36 | 37 | #define MB_ICONINFORMATION MB_ICONASTERISK 38 | #define MB_ICONSTOP MB_ICONHAND 39 | 40 | #define MB_DEFBUTTON1 0x00000000L 41 | #define MB_DEFBUTTON2 0x00000100L 42 | #define MB_DEFBUTTON3 0x00000200L 43 | #if(WINVER >= 0x0400) 44 | #define MB_DEFBUTTON4 0x00000300L 45 | #endif /* WINVER >= 0x0400 */ 46 | 47 | #define MB_APPLMODAL 0x00000000L 48 | #define MB_SYSTEMMODAL 0x00001000L 49 | #define MB_TASKMODAL 0x00002000L 50 | #if(WINVER >= 0x0400) 51 | #define MB_HELP 0x00004000L // Help Button 52 | #endif /* WINVER >= 0x0400 */ 53 | 54 | #define MB_NOFOCUS 0x00008000L 55 | #define MB_SETFOREGROUND 0x00010000L 56 | #define MB_DEFAULT_DESKTOP_ONLY 0x00020000L 57 | 58 | #if(WINVER >= 0x0400) 59 | #define MB_TOPMOST 0x00040000L 60 | #define MB_RIGHT 0x00080000L 61 | #define MB_RTLREADING 0x00100000L 62 | 63 | #endif /* WINVER >= 0x0400 */ 64 | 65 | #ifdef _WIN32_WINNT 66 | #if (_WIN32_WINNT >= 0x0400) 67 | #define MB_SERVICE_NOTIFICATION 0x00200000L 68 | #else 69 | #define MB_SERVICE_NOTIFICATION 0x00040000L 70 | #endif 71 | #define MB_SERVICE_NOTIFICATION_NT3X 0x00040000L 72 | #endif 73 | 74 | #define MB_TYPEMASK 0x0000000FL 75 | #define MB_ICONMASK 0x000000F0L 76 | #define MB_DEFMASK 0x00000F00L 77 | #define MB_MODEMASK 0x00003000L 78 | #define MB_MISCMASK 0x0000C000L 79 | 80 | #endif /* !NOMB */ 81 | 82 | 83 | 84 | /* 85 | * Dialog Box Command IDs 86 | */ 87 | #define IDOK 1 88 | #define IDCANCEL 2 89 | #define IDABORT 3 90 | #define IDRETRY 4 91 | #define IDIGNORE 5 92 | #define IDYES 6 93 | #define IDNO 7 94 | #if(WINVER >= 0x0400) 95 | #define IDCLOSE 8 96 | #define IDHELP 9 97 | #endif /* WINVER >= 0x0400 */ 98 | 99 | #if(WINVER >= 0x0500) 100 | #define IDTRYAGAIN 10 101 | #define IDCONTINUE 11 102 | #endif /* WINVER >= 0x0500 */ 103 | 104 | #if(WINVER >= 0x0501) 105 | #ifndef IDTIMEOUT 106 | #define IDTIMEOUT 32000 107 | #endif 108 | #endif /* WINVER >= 0x0501 */ 109 | 110 | 111 | 112 | typedef CONST struct DLGTEMPLATE *LPCDLGTEMPLATEA; 113 | typedef CONST struct DLGTEMPLATE *LPCDLGTEMPLATEW; 114 | #ifdef UNICODE 115 | typedef LPCDLGTEMPLATEW LPCDLGTEMPLATE; 116 | #else 117 | typedef LPCDLGTEMPLATEA LPCDLGTEMPLATE; 118 | #endif // UNICODE 119 | 120 | #endif // _CRTSYS_WINUSER_ 121 | -------------------------------------------------------------------------------- /src/custom/winsdk/include/um/crtsys/Windows.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRTSYS_WINDOWS_ 2 | #define _CRTSYS_WINDOWS_ 3 | 4 | #undef _CTYPE_DISABLE_MACROS 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | // winbase.h 12 | #include // consoleapi.h 13 | #include "fileapi.h" 14 | #include "synchapi.h" 15 | #include "processthreadsapi.h" 16 | // winbase.h 17 | 18 | #include "WinUser.h" 19 | #include "winnls.h" 20 | 21 | #endif // _CRTSYS_WINDOWS_ -------------------------------------------------------------------------------- /src/custom/winsdk/include/um/crtsys/combaseapi.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRTSYS_COMBASEAPI 2 | #define _CRTSYS_COMBASEAPI 3 | 4 | #pragma once 5 | 6 | #undef DECLSPEC_IMPORT 7 | #define DECLSPEC_IMPORT 8 | #include <../um/combaseapi.h> 9 | 10 | #endif // _CRTSYS_COMBASEAPI -------------------------------------------------------------------------------- /src/custom/winsdk/include/um/crtsys/commdlg.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRTSYS_INC_COMMDLG 2 | #define _CRTSYS_INC_COMMDLG 3 | 4 | #endif // _CRTSYS_INC_COMMDLG -------------------------------------------------------------------------------- /src/custom/winsdk/include/um/crtsys/datetimeapi.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRTSYS_DATETIMEAPI_H_ 2 | #define _CRTSYS_DATETIMEAPI_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | EXTERN_C_START 10 | 11 | // ucrt/internal/winapi_thunks.cpp 12 | WINBASEAPI 13 | int 14 | WINAPI 15 | GetDateFormatW( 16 | _In_ LCID Locale, 17 | _In_ DWORD dwFlags, 18 | _In_opt_ CONST SYSTEMTIME* lpDate, 19 | _In_opt_ LPCWSTR lpFormat, 20 | _Out_writes_opt_(cchDate) LPWSTR lpDateStr, 21 | _In_ int cchDate 22 | ); 23 | 24 | // ucrt/internal/winapi_thunks.cpp 25 | WINBASEAPI 26 | int 27 | WINAPI 28 | GetTimeFormatW( 29 | _In_ LCID Locale, 30 | _In_ DWORD dwFlags, 31 | _In_opt_ CONST SYSTEMTIME* lpTime, 32 | _In_opt_ LPCWSTR lpFormat, 33 | _Out_writes_opt_(cchTime) LPWSTR lpTimeStr, 34 | _In_ int cchTime 35 | ); 36 | 37 | EXTERN_C_END 38 | 39 | #endif // _CRTSYS_DATETIMEAPI_H_ 40 | 41 | -------------------------------------------------------------------------------- /src/custom/winsdk/include/um/crtsys/fileapi.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRTSYS_APISETFILE_ 2 | #define _CRTSYS_APISETFILE_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | EXTERN_C_START 10 | 11 | WINBASEAPI 12 | DWORD 13 | WINAPI 14 | GetTempPathA( 15 | _In_ DWORD nBufferLength, 16 | _Out_writes_to_opt_(nBufferLength,return + 1) LPSTR lpBuffer 17 | ); 18 | 19 | WINBASEAPI 20 | DWORD 21 | WINAPI 22 | GetTempPathW( 23 | _In_ DWORD nBufferLength, 24 | _Out_writes_to_opt_(nBufferLength,return + 1) LPWSTR lpBuffer 25 | ); 26 | 27 | WINBASEAPI 28 | UINT 29 | WINAPI 30 | GetTempFileNameA( 31 | _In_ LPCSTR lpPathName, 32 | _In_ LPCSTR lpPrefixString, 33 | _In_ UINT uUnique, 34 | _Out_writes_(MAX_PATH) LPSTR lpTempFileName 35 | ); 36 | 37 | WINBASEAPI 38 | UINT 39 | WINAPI 40 | GetTempFileNameW( 41 | _In_ LPCWSTR lpPathName, 42 | _In_ LPCWSTR lpPrefixString, 43 | _In_ UINT uUnique, 44 | _Out_writes_(MAX_PATH) LPWSTR lpTempFileName 45 | ); 46 | 47 | // ucrt/inc/corecrt_internal.h 48 | WINBASEAPI 49 | BOOL 50 | WINAPI 51 | FindClose( 52 | _Inout_ HANDLE hFindFile 53 | ); 54 | 55 | EXTERN_C_END 56 | 57 | #endif // _CRTSYS_APISETFILE_ 58 | -------------------------------------------------------------------------------- /src/custom/winsdk/include/um/crtsys/processthreadsapi.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRTSYS_PROCESSTHREADSAPI_H_ 2 | #define _CRTSYS_PROCESSTHREADSAPI_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | EXTERN_C_START 10 | 11 | // ucrt\startup\thread.cpp 12 | WINBASEAPI 13 | DWORD 14 | WINAPI 15 | ResumeThread( 16 | _In_ HANDLE hThread 17 | ); 18 | 19 | EXTERN_C_END 20 | 21 | #endif // _CRTSYS_PROCESSTHREADSAPI_H_ 22 | -------------------------------------------------------------------------------- /src/custom/winsdk/include/um/crtsys/prsht.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRTSYS_PRSHT_H_ 2 | #define _CRTSYS_PRSHT_H_ 3 | 4 | #endif // _CRTSYS_PRSHT_H_ -------------------------------------------------------------------------------- /src/custom/winsdk/include/um/crtsys/stringapiset.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRTSYS_APISETSTRING_ 2 | #define _CRTSYS_APISETSTRING_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "winnls.h" 8 | 9 | EXTERN_C_START 10 | 11 | // crt\src\stl\xgetwctype.cpp 12 | WINBASEAPI 13 | BOOL WINAPI GetStringTypeW(_In_ DWORD dwInfoType, 14 | _In_NLS_string_(cchSrc) LPCWCH lpSrcStr, 15 | _In_ int cchSrc, _Out_ LPWORD lpCharType); 16 | 17 | EXTERN_C_END 18 | 19 | #endif // _CRTSYS_APISETSTRING_ 20 | -------------------------------------------------------------------------------- /src/custom/winsdk/include/um/crtsys/synchapi.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRTSYS_SYNCHAPI_H_ 2 | #define _CRTSYS_SYNCHAPI_H_ 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | EXTERN_C_START 12 | 13 | WINBASEAPI 14 | BOOL 15 | WINAPI 16 | ReleaseSemaphore ( 17 | _In_ HANDLE hSemaphore, 18 | _In_ LONG lReleaseCount, 19 | _Out_opt_ LPLONG lpPreviousCount 20 | ); 21 | 22 | WINBASEAPI 23 | BOOL 24 | WINAPI 25 | ReleaseMutex ( 26 | _In_ HANDLE hMutex 27 | ); 28 | 29 | EXTERN_C_END 30 | 31 | #include <../Ldk/synchapi.h> 32 | 33 | #endif // _CRTSYS_SYNCHAPI_H_ -------------------------------------------------------------------------------- /src/custom/winsdk/include/um/crtsys/winternl.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRTSYS_WINTERNL_ 2 | #define _CRTSYS_WINTERNL_ 3 | 4 | #include 5 | 6 | #if !defined(_WDM_INCLUDED_) 7 | #include 8 | #endif 9 | 10 | #endif // _CRTSYS_WINTERNL_ 11 | -------------------------------------------------------------------------------- /test/app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14 FATAL_ERROR) 2 | 3 | project(crtsys_test_app LANGUAGES C CXX) 4 | 5 | include(../../cmake/CPM.cmake) 6 | CPMAddPackage( 7 | NAME googletest 8 | GITHUB_REPOSITORY google/googletest 9 | GIT_TAG release-1.10.0 10 | VERSION 1.10.0 11 | OPTIONS "INSTALL_GTEST OFF" "BUILD_GMOCK OFF" "gtest_force_shared_crt" 12 | ) 13 | 14 | add_executable(crtsys_test_app src/main.cpp) 15 | 16 | target_compile_options(crtsys_test_app PRIVATE "/EHsc") 17 | 18 | target_link_libraries(crtsys_test_app gtest) 19 | 20 | target_include_directories(crtsys_test_app PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../../include ${CMAKE_CURRENT_LIST_DIR}/..) -------------------------------------------------------------------------------- /test/app/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | // rpc client stub code 6 | #include "common/rpc.hpp" 7 | 8 | TEST(ntl_rpc_client, invoke_callback_by_invoke_method) { 9 | ntl::rpc::client cli(L"test_rpc", 1024 * 1024); 10 | 11 | using namespace test_rpc; 12 | EXPECT_EQ(cli.invoke(test_inc_1_index, 1), 2); 13 | EXPECT_EQ(cli.invoke(test_dec_1_index, 1), 0); 14 | 15 | EXPECT_EQ(cli.invoke(test_sum_2_index, 1, 2), 3); 16 | EXPECT_EQ(cli.invoke(test_sum_3_index, 1, 2, 3), 6); 17 | EXPECT_EQ(cli.invoke(test_sum_4_index, 1, 2, 3, 4), 10); 18 | EXPECT_EQ(cli.invoke(test_sum_5_index, 1, 2, 3, 4, 5), 15); 19 | 20 | EXPECT_NO_FATAL_FAILURE(cli.invoke(test_void_0_index)); 21 | 22 | std::vector vec = {1, 2, 3}; 23 | EXPECT_FALSE(cli.invoke(test_vec_1_index, vec)); 24 | 25 | std::set set = {1, 2, 3, 4}; 26 | EXPECT_FALSE(cli.invoke(test_set_1_index, set)); 27 | 28 | auto test_list_ret = test_list({1, 2, 3, 4, 5, 6}); 29 | for (size_t i = 0; i < test_list_ret.size(); i++) 30 | EXPECT_STREQ(std::to_string(i + 1).c_str(), test_list_ret[i].c_str()); 31 | 32 | auto test_map_ret = test_map({{1, 1}, {2, 2}, {3, 3}}); 33 | EXPECT_FALSE(test_map_ret.empty()); 34 | for (auto e : test_map_ret) 35 | EXPECT_STREQ(std::to_string(e.first).c_str(), e.second.c_str()); 36 | 37 | EXPECT_TRUE(test_map2({{1, 1}, {2, 2}, {3, 3}}, {})); 38 | 39 | auto test_point_class_ret = test_point_class(point(1, 1), point(4, 1)); 40 | EXPECT_EQ(test_point_class_ret.get_x(), 4); 41 | EXPECT_EQ(test_point_class_ret.get_y(), 1); 42 | } 43 | 44 | TEST(ntl_rpc_client, invoke_callback_by_symbol) { 45 | using namespace test_rpc; 46 | 47 | EXPECT_EQ(test_inc(1), 2); 48 | EXPECT_EQ(test_dec(1), 0); 49 | 50 | EXPECT_EQ(test_sum(1, 2), 3); 51 | EXPECT_EQ(test_sum(1, 2, 3), 6); 52 | EXPECT_EQ(test_sum(1, 2, 3, 4), 10); 53 | EXPECT_EQ(test_sum(1, 2, 3, 4, 5), 15); 54 | 55 | EXPECT_NO_FATAL_FAILURE(test_void()); 56 | 57 | EXPECT_FALSE(test_vec({1, 2, 3})); 58 | 59 | EXPECT_FALSE(test_set({1, 2, 3, 4})); 60 | 61 | auto test_list_ret = test_list({1, 2, 3, 4, 5, 6}); 62 | for (size_t i = 0; i < test_list_ret.size(); i++) 63 | EXPECT_STREQ(std::to_string(i + 1).c_str(), test_list_ret[i].c_str()); 64 | 65 | auto test_map_ret = test_map({{1, 1}, {2, 2}, {3, 3}}); 66 | EXPECT_FALSE(test_map_ret.empty()); 67 | for (auto e : test_map_ret) 68 | EXPECT_STREQ(std::to_string(e.first).c_str(), e.second.c_str()); 69 | 70 | EXPECT_TRUE(test_map2({{1, 1}, {2, 2}, {3, 3}}, {})); 71 | 72 | auto test_point_class_ret = test_point_class(point(1, 1), point(4, 1)); 73 | EXPECT_EQ(test_point_class_ret.get_x(), 4); 74 | EXPECT_EQ(test_point_class_ret.get_y(), 1); 75 | } 76 | 77 | #include "common/test_device.h" 78 | 79 | TEST(ntl_device, device_io_control) { 80 | HANDLE hDevice = CreateFileW( 81 | L"\\\\?\\Global\\GLOBALROOT\\Device\\" TEST_DEVICE_NAME, 82 | GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 83 | EXPECT_NE(hDevice, INVALID_HANDLE_VALUE); 84 | 85 | if (hDevice != INVALID_HANDLE_VALUE) { 86 | DWORD bytes_returned; 87 | char buffer[sizeof("world")]; 88 | 89 | EXPECT_TRUE(DeviceIoControl(hDevice, TEST_DEVICE_CTL, "hello", 5, buffer, 90 | sizeof("world"), &bytes_returned, NULL)); 91 | 92 | EXPECT_EQ(bytes_returned, sizeof("world")); 93 | EXPECT_STREQ(buffer, "world"); 94 | 95 | CloseHandle(hDevice); 96 | } 97 | } 98 | 99 | int main() { 100 | testing::InitGoogleTest(); 101 | return RUN_ALL_TESTS(); 102 | } 103 | -------------------------------------------------------------------------------- /test/build.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET CURDIR=%~DP0 4 | 5 | IF /I "%PROCESSOR_ARCHITECTURE%" == "x86" ( 6 | SET ARCH_NAME=x86 7 | ) 8 | IF /I "%PROCESSOR_ARCHITECTURE%" == "x64" ( 9 | SET ARCH_NAME=x64 10 | CALL %CURDIR%..\build.bat %CURDIR%\app x86 11 | ) 12 | IF /I "%PROCESSOR_ARCHITECTURE%" == "Win32" ( 13 | SET ARCH_NAME=x86 14 | ) 15 | IF /I "%PROCESSOR_ARCHITECTURE%" == "Win64" ( 16 | SET ARCH_NAME=x64 17 | CALL %CURDIR%..\build.bat %CURDIR%\app x86 18 | ) 19 | IF /I "%PROCESSOR_ARCHITECTURE%" == "AMD64" ( 20 | SET ARCH_NAME=x64 21 | CALL %CURDIR%..\build.bat %CURDIR%\app x86 22 | ) 23 | IF /I "%PROCESSOR_ARCHITECTURE%" == "ARM" ( 24 | SET ARCH_NAME=ARM 25 | ) 26 | IF /I "%PROCESSOR_ARCHITECTURE%" == "ARM64" ( 27 | SET ARCH_NAME=ARM64 28 | CALL %CURDIR%..\build.bat %CURDIR%\app ARM 29 | ) 30 | 31 | CALL %CURDIR%..\build.bat %CURDIR%\app %ARCH_NAME% 32 | CALL %CURDIR%..\build.bat %CURDIR%\driver %ARCH_NAME% 33 | 34 | @ECHO ON -------------------------------------------------------------------------------- /test/common/rpc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | class point { 10 | public: 11 | point() = default; 12 | point(int x, int y) noexcept : m_x(x), m_y(y) {} 13 | friend zpp::serializer::access; 14 | template 15 | static void serialize(Archive &archive, Self &self) { 16 | archive(self.m_x, self.m_y); 17 | } 18 | int get_x() const noexcept { return m_x; } 19 | int get_y() const noexcept { return m_y; } 20 | 21 | private: 22 | int m_x = 0; 23 | int m_y = 0; 24 | }; 25 | 26 | NTL_RPC_BEGIN(test_rpc) 27 | 28 | NTL_ADD_CALLBACK_1(test_rpc, int, test_inc, int, i, { return i + 1; }) 29 | 30 | NTL_ADD_CALLBACK_1(test_rpc, int, test_dec, int, i, { return i - 1; }) 31 | 32 | NTL_ADD_CALLBACK_2(test_rpc, int, test_sum, int, a, int, b, { return a + b; }) 33 | 34 | NTL_ADD_CALLBACK_3(test_rpc, int, test_sum, int, a, int, b, int, c, 35 | { return a + b + c; }) 36 | 37 | NTL_ADD_CALLBACK_4(test_rpc, int, test_sum, int, a, int, b, int, c, int, d, 38 | { return a + b + c + d; }) 39 | 40 | NTL_ADD_CALLBACK_5(test_rpc, int, test_sum, int, a, int, b, int, c, int, d, int, 41 | e, { return a + b + c + d + e; }) 42 | 43 | #if _MSC_VER <= 1916 44 | NTL_ADD_CALLBACK_0(test_rpc, int, test_void, { return 0; }) 45 | #else 46 | NTL_ADD_CALLBACK_0(test_rpc, void, test_void, { return; }) 47 | #endif 48 | 49 | NTL_ADD_CALLBACK_1(test_rpc, bool, test_vec, const std::vector &, vec, 50 | { return vec.empty(); }) 51 | 52 | NTL_ADD_CALLBACK_1(test_rpc, bool, test_set, const std::set &, set, 53 | { return set.empty(); }) 54 | 55 | NTL_ADD_CALLBACK_1(test_rpc, std::vector, test_list, 56 | const std::list &, list, { 57 | std::vector ret; 58 | for (auto i : list) 59 | ret.push_back(std::to_string(i)); 60 | return ret; 61 | }) 62 | 63 | NTL_ADD_CALLBACK_1(test_rpc, NTL_RPC_ARG_PACK(std::map), 64 | test_map, NTL_RPC_ARG_PACK(const std::map &), map, 65 | { 66 | std::map ret; 67 | for (auto e : map) 68 | ret.insert({e.first, std::to_string(e.first)}); 69 | return ret; 70 | ; 71 | }) 72 | 73 | NTL_ADD_CALLBACK_2(test_rpc, bool, test_map2, 74 | NTL_RPC_ARG_PACK(const std::map &), map, 75 | NTL_RPC_ARG_PACK(const std::map &), map2, 76 | { return map.size() > map2.size(); }) 77 | 78 | NTL_ADD_CALLBACK_2(test_rpc, point, test_point_class, const point &, p1, 79 | const point &, p2, 80 | { return p1.get_x() > p2.get_x() ? p1 : p2; }) 81 | 82 | NTL_RPC_END(test_rpc) 83 | -------------------------------------------------------------------------------- /test/common/test_device.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define TEST_DEVICE_NAME L"test_device" 4 | 5 | #define TEST_DEVICE_CTL \ 6 | CTL_CODE(FILE_DEVICE_UNKNOWN, 0, METHOD_BUFFERED, FILE_ANY_ACCESS) -------------------------------------------------------------------------------- /test/driver/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14 FATAL_ERROR) 2 | 3 | project(crtsys_test LANGUAGES C CXX) 4 | 5 | include(../../cmake/CPM.cmake) 6 | 7 | set(CRTSYS_NTL_MAIN ON) 8 | CPMAddPackage(NAME crtsys SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../..) 9 | include(${crtsys_SOURCE_DIR}/cmake/CrtSys.cmake) 10 | 11 | set(CRTSYS_TEST_NLOHMANN_JSON ON) 12 | 13 | if (CRTSYS_TEST_NLOHMANN_JSON) 14 | CPMAddPackage( 15 | NAME nlohmann_json 16 | VERSION 3.10.5 17 | GITHUB_REPOSITORY nlohmann/json 18 | OPTIONS 19 | "JSON_BuildTests OFF" 20 | ) 21 | endif() 22 | 23 | CPMAddPackage( 24 | NAME googletest 25 | GITHUB_REPOSITORY google/googletest 26 | GIT_TAG release-1.11.0 27 | VERSION 1.11.0 28 | OPTIONS 29 | "INSTALL_GTEST OFF" 30 | "BUILD_GMOCK OFF" 31 | ) 32 | target_link_libraries(gtest crtsys) 33 | target_compile_options(gtest PRIVATE "/Gz") 34 | target_link_libraries(gtest_main PRIVATE crtsys) 35 | target_compile_options(gtest_main PRIVATE "/Gd") 36 | 37 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX") 38 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4 /WX") 39 | 40 | file(GLOB SOURCE_FILES 41 | src/*.cpp 42 | src/*/*.cpp 43 | src/*/*/*.cpp 44 | src/*.c 45 | src/*/*.c 46 | src/*/*/*.c 47 | ) 48 | 49 | if (NOT CRTSYS_TEST_NLOHMANN_JSON) 50 | list(REMOVE_ITEM SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/libs/nlohmann_json.cpp) 51 | endif() 52 | 53 | crtsys_add_driver(crtsys_test ${SOURCE_FILES}) 54 | 55 | if (CRTSYS_TEST_NLOHMANN_JSON) 56 | target_compile_definitions(crtsys_test PRIVATE "CRTSYS_TEST_NLOHMANN_JSON") 57 | target_link_libraries(crtsys_test nlohmann_json::nlohmann_json) 58 | endif() 59 | 60 | target_link_libraries(crtsys_test gtest) 61 | 62 | target_include_directories(crtsys_test PRIVATE ${CMAKE_CURRENT_LIST_DIR}/..) 63 | 64 | include(../../cmake/std-cxx.cmake) 65 | set_std_cxx_latest(crtsys_test) -------------------------------------------------------------------------------- /test/driver/src/all.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // 4 | // c/math.c 5 | // 6 | extern "C" void math_test(); 7 | 8 | // 9 | // cpp/lang/initialization.cpp 10 | // 11 | namespace constant_initialization_test { 12 | void run(); 13 | } 14 | namespace zero_initialization_test { 15 | void run(int argc = 5, char *[] = nullptr); 16 | } 17 | // 18 | // cpp/lang/exceptions.cpp 19 | // 20 | namespace throw_test { 21 | void run(); 22 | } 23 | namespace try_catch_test { 24 | void run(); 25 | } 26 | namespace function_try_block_test { 27 | void run(); 28 | } 29 | 30 | // 31 | // cpp/stl/chrono.cpp 32 | // 33 | namespace chrono_test { 34 | void run(); 35 | } 36 | 37 | // 38 | // cpp/stl/thread.cpp 39 | // 40 | namespace condition_variable_test { 41 | void run(); 42 | } 43 | namespace mutex_test { 44 | void run(); 45 | } 46 | namespace shared_mutex_test { 47 | void run(); 48 | } 49 | namespace future_test { 50 | void run(); 51 | } 52 | namespace promise_test { 53 | void run(); 54 | } 55 | namespace packaged_task_test { 56 | void run(); 57 | } 58 | 59 | // 60 | // ntl_test.cpp 61 | // 62 | bool ntl_expand_stack_test(); 63 | 64 | bool ntl_irql_test(); 65 | 66 | bool ntl_spin_lock_test(); 67 | 68 | bool ntl_resource_test(); 69 | 70 | // 71 | // C Standard tests. 72 | // 73 | void c_std_tests() { math_test(); } 74 | 75 | #if defined(_AMD64_) && !defined(CRTSYS_USE_NTL_MAIN) 76 | // x64에서는 throw_test 테스트를 진행하기엔 스택이 부족합니다 :-( 77 | #include 78 | #endif 79 | 80 | // 81 | // C++ Standard tests. 82 | // 83 | void cpp_std_tests() { 84 | // 85 | // C++ Language tests. 86 | // 87 | constant_initialization_test::run(); 88 | zero_initialization_test::run(); 89 | #if defined(_AMD64_) && !defined(CRTSYS_USE_NTL_MAIN) 90 | // x64에서는 throw_test 테스트를 진행하기엔 스택이 부족합니다 :-( 91 | ntl::expand_stack(throw_test::run); 92 | #else 93 | #if !(defined(_X86_) && defined(UCXXRT)) 94 | // UCXXRT의 x86 예외처리 기능은 아래 테스트 수행 시, hang이 발생합니다. :-( 95 | throw_test::run(); 96 | #endif 97 | #endif 98 | try_catch_test::run(); 99 | #if !(defined(_X86_) && defined(UCXXRT)) 100 | // UCXXRT의 x86 예외처리 기능은 아래 테스트 수행 시, 101 | // KeExpandKernelStackAndCallout 루틴으로 스택 크기를 최대로 늘려 놓은 102 | // 상태임에도 불구하고 스택 부족으로 인한 BSOD가 발생합니다. :-( 103 | function_try_block_test::run(); 104 | #endif 105 | // 106 | // C++ STL tests. 107 | // 108 | chrono_test::run(); 109 | condition_variable_test::run(); 110 | mutex_test::run(); 111 | shared_mutex_test::run(); 112 | future_test::run(); 113 | promise_test::run(); 114 | packaged_task_test::run(); 115 | } 116 | 117 | // 118 | // NTL tests. 119 | // 120 | 121 | void ntl_test() { 122 | if (!ntl_expand_stack_test()) { 123 | std::cerr << "ntl_expand_stack_test failed\n"; 124 | } 125 | if (!ntl_irql_test()) { 126 | std::cerr << "ntl_irql_test failed\n"; 127 | } 128 | if (!ntl_spin_lock_test()) { 129 | std::cerr << "ntl_spin_lock_test failed\n"; 130 | } 131 | if (!ntl_resource_test()) { 132 | std::cerr << "ntl_resource_test failed\n"; 133 | } 134 | } 135 | 136 | void test_all() { 137 | ntl_test(); 138 | 139 | c_std_tests(); 140 | 141 | cpp_std_tests(); 142 | } -------------------------------------------------------------------------------- /test/driver/src/c/math.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef char bool; 5 | #define true 1 6 | #define false 0 7 | 8 | bool int64_t_test() { 9 | volatile int64_t s = 1; 10 | s += s; 11 | s -= s; 12 | s *= s; 13 | s /= s; 14 | s %= s; 15 | s >>= 33; 16 | s <<= 33; 17 | return true; 18 | } 19 | 20 | bool uint64_t_test() { 21 | volatile uint64_t u = 1; 22 | u += u; 23 | u -= u; 24 | u *= u; 25 | u /= u; 26 | u %= u; 27 | u >>= 33; 28 | u <<= 33; 29 | return true; 30 | } 31 | 32 | bool float_to_integer() { 33 | float f = 1.6f; 34 | uint8_t i8 = (uint8_t)f; 35 | uint16_t i16 = (uint16_t)f; 36 | uint32_t i32 = (uint32_t)f; 37 | uint64_t i64 = (uint64_t)f; 38 | return i8 + i16 + i32 + i64 == 4; 39 | } 40 | 41 | bool integer_to_float() { 42 | float f_i8 = (uint8_t)1; 43 | float f_i16 = (uint8_t)1; 44 | float f_i32 = (uint8_t)1; 45 | float f_i64 = (uint8_t)1; 46 | return f_i8 + f_i16 + f_i32 + f_i64 == 4; 47 | } 48 | 49 | bool double_to_integer() { 50 | double d = 1.6f; 51 | uint8_t i8 = (uint8_t)d; 52 | uint16_t i16 = (uint16_t)d; 53 | uint32_t i32 = (uint32_t)d; 54 | uint64_t i64 = (uint64_t)d; 55 | return i8 + i16 + i32 + i64 == 4; 56 | } 57 | 58 | bool integer_to_double() { 59 | double d_i8 = (uint8_t)1; 60 | double d_i16 = (uint8_t)1; 61 | double d_i32 = (uint8_t)1; 62 | double d_i64 = (uint8_t)1; 63 | return d_i8 + d_i16 + d_i32 + d_i64 == 4; 64 | } 65 | 66 | #include 67 | 68 | void pow_test() { 69 | int actual; 70 | int excepted = 1; 71 | for (int i = 0; i < 20; i++, excepted <<= 1) { 72 | actual = (int)pow(2, i); 73 | if (excepted != actual) 74 | fprintf(stderr, "pow(2, %d) faield - excepted = %d, actual =%d\n", i, 75 | excepted, actual); 76 | } 77 | } 78 | 79 | void math_test() { 80 | if (!float_to_integer()) 81 | fprintf(stderr, "float_to_integer failed\n"); 82 | 83 | if (!integer_to_float()) 84 | fprintf(stderr, "integer_to_float failed\n"); 85 | 86 | if (!double_to_integer()) 87 | fprintf(stderr, "double_to_integer failed\n"); 88 | 89 | if (!integer_to_double()) 90 | fprintf(stderr, "integer_to_double failed\n"); 91 | 92 | pow_test(); 93 | } -------------------------------------------------------------------------------- /test/driver/src/cpp/lang/exceptions.cpp: -------------------------------------------------------------------------------- 1 | #if !DBG || defined(_ARM_) 2 | #pragma warning(disable : 4702) // line 25 3 | #endif 4 | 5 | // 6 | // https://en.cppreference.com/w/cpp/language/throw#Example 7 | // 8 | #include 9 | #include 10 | namespace throw_test { 11 | struct A { 12 | int n; 13 | 14 | A(int n = 0) : n(n) { 15 | std::cout << "A(" << n << ") constructed successfully\n"; 16 | } 17 | ~A() { std::cout << "A(" << n << ") destroyed\n"; } 18 | }; 19 | 20 | int foo() { throw std::runtime_error("error"); } 21 | 22 | struct B { 23 | A a1, a2, a3; 24 | 25 | B() try : a1(1), a2(foo()), a3(3) { 26 | std::cout << "B constructed successfully\n"; 27 | } catch (...) { 28 | std::cout << "B::B() exiting with exception\n"; 29 | } 30 | 31 | ~B() { std::cout << "B destroyed\n"; } 32 | }; 33 | 34 | struct C : A, B { 35 | C() try { std::cout << "C::C() completed successfully\n"; } catch (...) { 36 | std::cout << "C::C() exiting with exception\n"; 37 | } 38 | 39 | ~C() { std::cout << "C destroyed\n"; } 40 | }; 41 | 42 | void run() try { 43 | // creates the A base subobject 44 | // creates the a1 member of B 45 | // fails to create the a2 member of B 46 | // unwinding destroys the a1 member of B 47 | // unwinding destroys the A base subobject 48 | C c; 49 | } catch (const std::exception &e) { 50 | std::cout << "main() failed to create C with: " << e.what(); 51 | } 52 | } // namespace throw_test 53 | 54 | // 55 | // https://en.cppreference.com/w/cpp/language/try_catch#Example 56 | // 57 | #include 58 | #include 59 | namespace try_catch_test { 60 | void run() { 61 | try { 62 | std::cout << "Throwing an integer exception...\n"; 63 | throw 42; 64 | } catch (int i) { 65 | std::cout << " the integer exception was caught, with value: " << i << '\n'; 66 | } 67 | 68 | try { 69 | std::cout << "Creating a vector of size 5... \n"; 70 | std::vector v(5); 71 | std::cout << "Accessing the 11th element of the vector...\n"; 72 | std::cout << v.at(10); // vector::at() throws std::out_of_range 73 | } catch (const std::exception &e) // caught by reference to base 74 | { 75 | std::cout << " a standard exception was caught, with message '" << e.what() 76 | << "'\n"; 77 | } 78 | } 79 | } // namespace try_catch_test 80 | 81 | // 82 | // https://en.cppreference.com/w/cpp/language/function-try-block#Explanation 83 | // 84 | #include 85 | #include 86 | namespace function_try_block_test { 87 | #include 88 | #include 89 | struct S { 90 | std::string m; 91 | S(const std::string &str, int idx) try : m(str, idx) { 92 | std::cout << "S(" << str << ", " << idx << ") constructed, m = " << m 93 | << '\n'; 94 | } catch (const std::exception &e) { 95 | std::cout << "S(" << str << ", " << idx << ") failed: " << e.what() << '\n'; 96 | } // implicit "throw;" here 97 | }; 98 | void run() { 99 | S s1{"ABC", 1}; // does not throw (index is in bounds) 100 | try { 101 | S s2{"ABC", 4}; // throws (out of bounds) 102 | } catch (std::exception &e) { 103 | std::cout << "S s2... raised an exception: " << e.what() << '\n'; 104 | } 105 | } 106 | } // namespace function_try_block_test -------------------------------------------------------------------------------- /test/driver/src/cpp/lang/initialization.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // https://en.cppreference.com/w/cpp/language/constant_initialization#Example 3 | // 4 | #include 5 | #include 6 | namespace constant_initialization_test { 7 | struct S { 8 | static const int c; 9 | }; 10 | const int d = 10 * S::c; // not a constant expression: S::c has no preceding 11 | // initializer, this initialization happens after const 12 | const int S::c = 5; // constant initialization, guaranteed to happen first 13 | void run() { 14 | std::cout << "d = " << d << '\n'; 15 | std::array a1; // OK: S::c is a constant expression 16 | // std::array a2; // error: d is not a constant expression 17 | a1; 18 | } 19 | } // namespace constant_initialization_test 20 | 21 | // 22 | // https://en.cppreference.com/w/cpp/language/zero_initialization#Example 23 | // 24 | 25 | #include 26 | #include 27 | namespace zero_initialization_test { 28 | struct A { 29 | int a, b, c; 30 | }; 31 | 32 | double f[3]; // zero-initialized to three 0.0's 33 | 34 | int *p; // zero-initialized to null pointer value 35 | // (even if the value is not integral 0) 36 | 37 | std::string 38 | s; // zero-initialized to indeterminate value, then 39 | // default-initialized to "" by the std::string default constructor 40 | 41 | void run(int argc, char *[]) { 42 | delete p; // safe to delete a null pointer 43 | 44 | static int n = argc; // zero-initialized to 0 then copy-initialized to argc 45 | std::cout << "n = " << n << '\n'; 46 | 47 | A a = A(); // the effect is same as: A a{}; or A a = {}; 48 | std::cout << "a = {" << a.a << ' ' << a.b << ' ' << a.c << "}\n"; 49 | } 50 | } // namespace zero_initialization_test 51 | 52 | // 53 | // https://en.cppreference.com/w/cpp/language/initialization#Dynamic_initialization 54 | // (no cppreference example.) 55 | // 56 | namespace dynamic_initialization_test { 57 | struct test_object { 58 | int n; 59 | test_object(int n = 0) : n(n) { 60 | std::cout << "test_object(" << n << ") constructed successfully\n"; 61 | } 62 | ~test_object() { std::cout << "test_object(" << n << ") destroyed\n"; } 63 | }; 64 | 65 | test_object global_object_(1); 66 | static test_object static_object_(2); 67 | } // namespace dynamic_initialization_test -------------------------------------------------------------------------------- /test/driver/src/cpp/stl/chrono.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // 4 | // https://en.cppreference.com/w/cpp/chrono#Example 5 | // 6 | #include 7 | #include 8 | namespace chrono_test { 9 | long fibonacci(unsigned n) { 10 | if (n < 2) 11 | return n; 12 | return fibonacci(n - 1) + fibonacci(n - 2); 13 | } 14 | 15 | void run() { 16 | auto start = std::chrono::steady_clock::now(); 17 | std::cout << "f(42) = " << fibonacci(42) << '\n'; 18 | auto end = std::chrono::steady_clock::now(); 19 | std::chrono::duration elapsed_seconds = end - start; 20 | std::cout << "elapsed time: " << elapsed_seconds.count() << "s\n"; 21 | } 22 | } // namespace chrono_test 23 | 24 | // 25 | // Google Test. 26 | // 27 | TEST(cxx_stl_test, chrono_test) { 28 | auto start = std::chrono::steady_clock::now(); 29 | auto actual = chrono_test::fibonacci(42); 30 | EXPECT_EQ(actual, 267914296); 31 | std::cout << "f(42) = " << actual << '\n'; 32 | auto end = std::chrono::steady_clock::now(); 33 | std::chrono::duration elapsed_seconds = end - start; 34 | std::cout << "elapsed time: " << elapsed_seconds.count() << "s\n"; 35 | } -------------------------------------------------------------------------------- /test/driver/src/cpp/stl/thread.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // https://en.cppreference.com/w/cpp/thread/condition_variable#Example 3 | // 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | namespace condition_variable_test { 10 | std::mutex m; 11 | std::condition_variable cv; 12 | std::string data; 13 | bool ready = false; 14 | bool processed = false; 15 | 16 | void worker_thread() { 17 | // Wait until main() sends data 18 | std::unique_lock lk(m); 19 | cv.wait(lk, [] { return ready; }); 20 | 21 | // after the wait, we own the lock. 22 | std::cout << "Worker thread is processing data\n"; 23 | data += " after processing"; 24 | 25 | // Send data back to main() 26 | processed = true; 27 | std::cout << "Worker thread signals data processing completed\n"; 28 | 29 | // Manual unlocking is done before notifying, to avoid waking up 30 | // the waiting thread only to block again (see notify_one for details) 31 | lk.unlock(); 32 | cv.notify_one(); 33 | } 34 | 35 | void run() { 36 | std::thread worker(worker_thread); 37 | 38 | data = "Example data"; 39 | // send data to the worker thread 40 | { 41 | std::lock_guard lk(m); 42 | ready = true; 43 | std::cout 44 | << "condition_variable_test::run() signals data ready for processing\n"; 45 | } 46 | cv.notify_one(); 47 | 48 | // wait for the worker 49 | { 50 | std::unique_lock lk(m); 51 | cv.wait(lk, [] { return processed; }); 52 | } 53 | std::cout << "Back in main(), data = " << data << '\n'; 54 | 55 | worker.join(); 56 | } 57 | } // namespace condition_variable_test 58 | 59 | // 60 | // https://en.cppreference.com/w/cpp/thread/mutex#Example 61 | // 62 | #include 63 | #include 64 | #include 65 | #include 66 | #include 67 | #include 68 | namespace mutex_test { 69 | std::map g_pages; 70 | std::mutex g_pages_mutex; 71 | 72 | void save_page(const std::string &url) { 73 | // simulate a long page fetch 74 | std::this_thread::sleep_for(std::chrono::seconds(2)); 75 | std::string result = "fake content"; 76 | 77 | std::lock_guard guard(g_pages_mutex); 78 | g_pages[url] = result; 79 | } 80 | 81 | void run() { 82 | std::thread t1(save_page, "http://foo"); 83 | std::thread t2(save_page, "http://bar"); 84 | t1.join(); 85 | t2.join(); 86 | 87 | // safe to access g_pages without lock now, as the threads are joined 88 | for (const auto &pair : g_pages) { 89 | std::cout << pair.first << " => " << pair.second << '\n'; 90 | } 91 | } 92 | } // namespace mutex_test 93 | 94 | // 95 | // https://en.cppreference.com/w/cpp/thread/shared_mutex#Example 96 | // 97 | #include 98 | #include 99 | #include 100 | #include 101 | namespace shared_mutex_test { 102 | class ThreadSafeCounter { 103 | public: 104 | ThreadSafeCounter() = default; 105 | 106 | // Multiple threads/readers can read the counter's value at the same time. 107 | unsigned int get() const { 108 | std::shared_lock lock(mutex_); 109 | return value_; 110 | } 111 | 112 | // Only one thread/writer can increment/write the counter's value. 113 | unsigned int increment() { 114 | std::unique_lock lock(mutex_); 115 | return ++value_; 116 | } 117 | 118 | // Only one thread/writer can reset/write the counter's value. 119 | void reset() { 120 | std::unique_lock lock(mutex_); 121 | value_ = 0; 122 | } 123 | 124 | private: 125 | mutable std::shared_mutex mutex_; 126 | unsigned int value_ = 0; 127 | }; 128 | 129 | void run() { 130 | ThreadSafeCounter counter; 131 | 132 | auto increment_and_print = [&counter]() { 133 | for (int i = 0; i < 3; i++) { 134 | std::cout << std::this_thread::get_id() << ' ' << counter.increment() 135 | << '\n'; 136 | 137 | // Note: Writing to std::cout actually needs to be synchronized as well 138 | // by another std::mutex. This has been omitted to keep the example small. 139 | } 140 | }; 141 | 142 | std::thread thread1(increment_and_print); 143 | std::thread thread2(increment_and_print); 144 | 145 | thread1.join(); 146 | thread2.join(); 147 | } 148 | } // namespace shared_mutex_test 149 | 150 | // 151 | // https://en.cppreference.com/w/cpp/thread/future#Example 152 | // 153 | #include 154 | #include 155 | #include 156 | namespace future_test { 157 | void run() { 158 | // future from a packaged_task 159 | std::packaged_task task([] { return 7; }); // wrap the function 160 | std::future f1 = task.get_future(); // get a future 161 | std::thread t(std::move(task)); // launch on a thread 162 | 163 | // future from an async() 164 | std::future f2 = std::async(std::launch::async, [] { return 8; }); 165 | 166 | // future from a promise 167 | std::promise p; 168 | std::future f3 = p.get_future(); 169 | std::thread([&p] { p.set_value_at_thread_exit(9); }).detach(); 170 | 171 | std::cout << "Waiting..." << std::flush; 172 | f1.wait(); 173 | f2.wait(); 174 | f3.wait(); 175 | std::cout << "Done!\nResults are: " << f1.get() << ' ' << f2.get() << ' ' 176 | << f3.get() << '\n'; 177 | t.join(); 178 | } 179 | } // namespace future_test 180 | 181 | // 182 | // https://en.cppreference.com/w/cpp/thread/promise#Example 183 | // 184 | #include 185 | #include 186 | #include 187 | #include 188 | #include 189 | #include 190 | namespace promise_test { 191 | void accumulate(std::vector::iterator first, 192 | std::vector::iterator last, 193 | std::promise accumulate_promise) { 194 | int sum = std::accumulate(first, last, 0); 195 | accumulate_promise.set_value(sum); // Notify future 196 | } 197 | 198 | void do_work(std::promise barrier) { 199 | std::this_thread::sleep_for(std::chrono::seconds(1)); 200 | barrier.set_value(); 201 | } 202 | 203 | void run() { 204 | // Demonstrate using promise to transmit a result between threads. 205 | std::vector numbers = {1, 2, 3, 4, 5, 6}; 206 | std::promise accumulate_promise; 207 | std::future accumulate_future = accumulate_promise.get_future(); 208 | std::thread work_thread(accumulate, numbers.begin(), numbers.end(), 209 | std::move(accumulate_promise)); 210 | 211 | // future::get() will wait until the future has a valid result and retrieves 212 | // it. Calling wait() before get() is not needed 213 | // accumulate_future.wait(); // wait for result 214 | std::cout << "result=" << accumulate_future.get() << '\n'; 215 | work_thread.join(); // wait for thread completion 216 | 217 | // Demonstrate using promise to signal state between threads. 218 | std::promise barrier; 219 | std::future barrier_future = barrier.get_future(); 220 | std::thread new_work_thread(do_work, std::move(barrier)); 221 | barrier_future.wait(); 222 | new_work_thread.join(); 223 | } 224 | } // namespace promise_test 225 | 226 | // 227 | // https://en.cppreference.com/w/cpp/thread/packaged_task#Example 228 | // 229 | #include 230 | #include 231 | #include 232 | #include 233 | #include 234 | namespace packaged_task_test { 235 | // unique function to avoid disambiguating the std::pow overload set 236 | int f(int x, int y) { return (int)std::pow(x, y); } 237 | 238 | void task_lambda() { 239 | std::packaged_task task( 240 | [](int a, int b) { return (int)std::pow(a, b); }); 241 | std::future result = task.get_future(); 242 | 243 | task(2, 9); 244 | 245 | std::cout << "task_lambda:\t" << result.get() << '\n'; 246 | } 247 | 248 | void task_bind() { 249 | std::packaged_task task(std::bind(f, 2, 11)); 250 | std::future result = task.get_future(); 251 | 252 | task(); 253 | 254 | std::cout << "task_bind:\t" << result.get() << '\n'; 255 | } 256 | 257 | void task_thread() { 258 | std::packaged_task task(f); 259 | std::future result = task.get_future(); 260 | 261 | std::thread task_td(std::move(task), 2, 10); 262 | task_td.join(); 263 | 264 | std::cout << "task_thread:\t" << result.get() << '\n'; 265 | } 266 | 267 | void run() { 268 | task_lambda(); 269 | task_bind(); 270 | task_thread(); 271 | } 272 | } // namespace packaged_task_test -------------------------------------------------------------------------------- /test/driver/src/libs/nlohmann_json.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Google Test. 3 | // 4 | #include 5 | 6 | #include 7 | TEST(nlohmann_json_test, basic_test) { 8 | 9 | // create an empty structure (null) 10 | nlohmann::json j; 11 | 12 | // add a number that is stored as double (note the implicit conversion of j to 13 | // an object) 14 | j["pi"] = 3.141; 15 | 16 | // add a Boolean that is stored as bool 17 | j["happy"] = true; 18 | 19 | // add a string that is stored as std::string 20 | j["name"] = "Niels"; 21 | 22 | // add another null object by passing nullptr 23 | j["nothing"] = nullptr; 24 | 25 | // add an object inside the object 26 | j["answer"]["everything"] = 42; 27 | 28 | // add an array that is stored as std::vector (using an initializer list) 29 | j["list"] = {1, 0, 2}; 30 | 31 | // add another object (using an initializer list of pairs) 32 | j["object"] = {{"currency", "USD"}, {"value", 42.99}}; 33 | 34 | // instead, you could also write (which looks very similar to the JSON above) 35 | nlohmann::json j2 = {{"pi", 3.141}, 36 | {"happy", true}, 37 | {"name", "Niels"}, 38 | {"nothing", nullptr}, 39 | {"answer", {{"everything", 42}}}, 40 | {"list", {1, 0, 2}}, 41 | {"object", {{"currency", "USD"}, {"value", 42.99}}}}; 42 | 43 | EXPECT_STREQ(j.dump().c_str(), j2.dump().c_str()); 44 | } 45 | 46 | TEST(nlohmann_json_test, literal_test) { 47 | // create object from string literal 48 | nlohmann::json j = "{ \"happy\": true, \"pi\": 3.141 }"_json; 49 | 50 | // or even nicer with a raw string literal 51 | auto j2 = R"( 52 | { 53 | "happy": true, 54 | "pi": 3.141 55 | } 56 | )"_json; 57 | 58 | EXPECT_STREQ(j.dump().c_str(), j2.dump().c_str()); 59 | } -------------------------------------------------------------------------------- /test/driver/src/main.cpp: -------------------------------------------------------------------------------- 1 | #define _SILENCE_CXX23_ALIGNED_STORAGE_DEPRECATION_WARNING 2 | 3 | #include 4 | 5 | EXTERN_C DRIVER_INITIALIZE DriverEntry; 6 | EXTERN_C DRIVER_UNLOAD DriverUnload; 7 | 8 | #ifdef ALLOC_PRAGMA 9 | #pragma alloc_text(INIT, DriverEntry) 10 | #pragma alloc_text(PAGE, DriverUnload) 11 | #endif 12 | 13 | void test_all(); 14 | 15 | #include 16 | 17 | #if CRTSYS_USE_NTL_MAIN 18 | #include 19 | #include 20 | 21 | #include 22 | // rpc server stub code 23 | #include "common/rpc.hpp" 24 | 25 | #include "common/test_device.h" 26 | 27 | ntl::status ntl::main(ntl::driver &driver, const std::wstring ®istry_path) { 28 | 29 | KdBreakPoint(); 30 | 31 | std::wcout << "load (registry_path :" << registry_path << ")\n"; 32 | 33 | test_all(); 34 | 35 | struct test_extension { 36 | test_extension() : val(0) { 37 | std::cout << "constructor - val : " << val << '\n'; 38 | } 39 | ~test_extension() { std::cout << "destroctor - val : " << val << '\n'; } 40 | 41 | void inc() { val++; } 42 | 43 | int val; 44 | }; 45 | 46 | auto test_dev = 47 | driver.create_device(ntl::device_options() 48 | .name(TEST_DEVICE_NAME) 49 | .type(FILE_DEVICE_UNKNOWN) 50 | .exclusive()); 51 | if (test_dev) { 52 | test_dev->extension().val = 100; 53 | test_dev->extension().inc(); 54 | 55 | std::weak_ptr test_dev_weak = test_dev; 56 | test_dev->on_device_control([test_dev_weak]( 57 | const ntl::device_control::code &code, 58 | const ntl::device_control::in_buffer &in, 59 | ntl::device_control::out_buffer &out) { 60 | if (code == TEST_DEVICE_CTL) { 61 | if (auto test_dev = test_dev_weak.lock()) 62 | test_dev->extension().val--; 63 | std::string actual(reinterpret_cast(in.ptr), in.size); 64 | if (actual != "hello") 65 | std::cout << "[FAILED] expect : hello, actual : " << actual << '\n'; 66 | if (out.ptr) { 67 | strcpy_s(reinterpret_cast(out.ptr), out.size, "world"); 68 | } else { 69 | std::cout << "[FAILED] out_buffer == null\n"; 70 | } 71 | } 72 | }); 73 | } 74 | 75 | driver.on_unload([registry_path, test_dev, 76 | rpc_svr = test_rpc::init(driver)]() mutable { 77 | if (test_dev) 78 | std::wcout << L"delete device :" << test_dev->name() << " - " 79 | << test_dev->extension().val << L'\n'; 80 | std::wcout << L"unload driver (registry_path :" << registry_path << L")\n"; 81 | }); 82 | 83 | testing::InitGoogleTest(); 84 | return RUN_ALL_TESTS() == 0 ? status::ok() : status(STATUS_UNSUCCESSFUL); 85 | } 86 | #else // !CRTSYS_USE_NTL_MAIN 87 | // clang-format off 88 | EXTERN_C 89 | NTSTATUS 90 | DriverEntry ( 91 | _In_ PDRIVER_OBJECT DriverObject, 92 | _In_ PUNICODE_STRING RegistryPath 93 | ) 94 | { 95 | // clang-format on 96 | PAGED_CODE(); 97 | UNREFERENCED_PARAMETER(RegistryPath); 98 | 99 | KdBreakPoint(); 100 | 101 | test_all(); 102 | 103 | DriverObject->DriverUnload = DriverUnload; 104 | 105 | testing::InitGoogleTest(); 106 | return RUN_ALL_TESTS() == 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; 107 | } 108 | 109 | // clang-format off 110 | EXTERN_C 111 | VOID 112 | DriverUnload ( 113 | _In_ PDRIVER_OBJECT DriverObject 114 | ) 115 | { 116 | // clang-format on 117 | PAGED_CODE(); 118 | UNREFERENCED_PARAMETER(DriverObject); 119 | } 120 | #endif // !CRTSYS_USE_NTL_MAIN 121 | -------------------------------------------------------------------------------- /test/driver/src/ntl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | bool ntl_expand_stack_test() { 6 | long result = 0; 7 | ntl::expand_stack( 8 | [&result](int i, long l, double d) { result = (long)(i + l + d); }, 1, 2, 9 | 3.0); 10 | if (result != 6) 11 | return false; 12 | 13 | result = ntl::expand_stack( 14 | [](int i, long l, double d) -> long { return (long)(i + l + d); }, 1, 2, 15 | 3.0); 16 | if (result != 6) 17 | return false; 18 | 19 | std::string t1; 20 | std::string t2; 21 | std::string t3; 22 | 23 | ntl::expand_stack([&] { 24 | try { 25 | throw std::bad_alloc(); 26 | } catch (const std::exception &e) { 27 | try { 28 | t1 = e.what(); 29 | throw std::bad_array_new_length(); 30 | } catch (const std::exception &e) { 31 | try { 32 | t2 = e.what(); 33 | throw std::runtime_error("test"); 34 | } catch (const std::runtime_error &e) { 35 | t3 = e.what(); 36 | } catch (const std::exception &) { 37 | } 38 | } 39 | } 40 | }); 41 | return !(t1.empty() || t2.empty() || t3.empty()); 42 | } 43 | 44 | #include 45 | 46 | bool ntl_irql_test() { 47 | auto old_irql = ntl::current_irql(); 48 | { 49 | auto raised_irql = ntl::raise_irql(ntl::irql::apc); 50 | 51 | if (old_irql != raised_irql.old()) 52 | return false; 53 | 54 | if (ntl::current_irql() != ntl::irql::apc) 55 | return false; 56 | } 57 | if (ntl::current_irql() != old_irql) 58 | return false; 59 | 60 | old_irql = ntl::current_irql(); 61 | { 62 | auto raised_irql = ntl::raise_irql_to_dpc_level(); 63 | if (old_irql != raised_irql.old()) 64 | return false; 65 | 66 | if (ntl::current_irql() != ntl::irql::dispatch) 67 | return false; 68 | } 69 | old_irql = ntl::current_irql(); 70 | { 71 | auto raised_irql = ntl::raise_irql_to_synch_level(); 72 | if (old_irql != raised_irql.old()) 73 | return false; 74 | } 75 | return (ntl::current_irql() == old_irql); 76 | } 77 | 78 | #include 79 | 80 | bool ntl_spin_lock_test() { 81 | ntl::spin_lock lock; 82 | ntl::spin_lock lock2; 83 | 84 | if (!lock.test()) 85 | return false; 86 | 87 | if (!lock2.test()) 88 | return false; 89 | 90 | std::unique_lock lk(lock); 91 | if (!lk.owns_lock()) 92 | return false; 93 | 94 | std::unique_lock lk2(lock, std::try_to_lock); 95 | if (lk2.owns_lock()) 96 | return false; 97 | 98 | { 99 | ntl::unique_lock nlk(lock2, ntl::at_dpc_level_lock); 100 | if (!nlk.owns_lock()) 101 | return false; 102 | if (lock2.test()) 103 | return false; 104 | 105 | ntl::unique_lock nlk2(lock2, std::try_to_lock); 106 | if (nlk2.owns_lock()) 107 | return false; 108 | } 109 | if (!lock2.test()) 110 | return false; 111 | 112 | return KeTestSpinLock(lock.native_handle()) == FALSE; 113 | } 114 | 115 | #include 116 | 117 | bool ntl_resource_test() { 118 | ntl::resource res; 119 | { 120 | std::shared_lock lk(res); 121 | if (!lk.owns_lock()) 122 | return false; 123 | if (!res.locked()) 124 | return false; 125 | if (!res.locked_shared()) 126 | return false; 127 | 128 | std::unique_lock lk2(res, std::try_to_lock); 129 | if (lk2.owns_lock()) 130 | return false; 131 | if (res.locked_exclusive()) 132 | return false; 133 | } 134 | if (res.locked()) 135 | return false; 136 | if (res.locked_exclusive()) 137 | return false; 138 | if (res.locked_shared()) 139 | return false; 140 | 141 | ntl::resource res2; 142 | std::unique_lock lk3(res); 143 | if (!lk3.owns_lock()) 144 | return false; 145 | if (!res.locked()) 146 | return false; 147 | if (!res.locked_exclusive()) 148 | return false; 149 | 150 | std::shared_lock lk4(res, std::try_to_lock); 151 | if (!lk4.owns_lock()) 152 | return false; 153 | if (res.locked_shared()) 154 | return false; 155 | 156 | ntl::unique_lock lk5(res2, ntl::adopt_critical_region); 157 | if (!lk5.owns_lock()) 158 | return false; 159 | if (!res2.locked()) 160 | return false; 161 | if (!res2.locked_exclusive()) 162 | return false; 163 | if (res2.locked_shared()) 164 | return false; 165 | 166 | ntl::shared_lock lk6(lk5); 167 | if (lk5.owns_lock()) 168 | return false; 169 | if (!lk6.owns_lock()) 170 | return false; 171 | if (!res2.locked()) 172 | return false; 173 | if (!res2.locked_shared()) 174 | return false; 175 | if (res2.locked_exclusive()) 176 | return false; 177 | 178 | ntl::resource res3; 179 | ntl::shared_lock lk7(res3, ntl::adopt_critical_region); 180 | if (!lk7.owns_lock()) 181 | return false; 182 | if (!res3.locked()) 183 | return false; 184 | return res3.locked_shared(); 185 | } 186 | 187 | // 188 | // Google Test. 189 | // 190 | #include 191 | 192 | TEST(ntl_test, ntl_expand_stack_test) { 193 | long result = 0; 194 | ntl::expand_stack( 195 | [&result](int i, long l, double d) { result = (long)(i + l + d); }, 1, 2, 196 | 3.0); 197 | EXPECT_EQ(result, 6); 198 | 199 | result = ntl::expand_stack( 200 | [](int i, long l, double d) -> long { return (long)(i + l + d); }, 1, 2, 201 | 3.0); 202 | EXPECT_EQ(result, 6); 203 | 204 | std::string t1; 205 | std::string t2; 206 | std::string t3; 207 | 208 | ntl::expand_stack([&] { 209 | try { 210 | throw std::bad_alloc(); 211 | } catch (const std::exception &e) { 212 | try { 213 | t1 = e.what(); 214 | throw std::bad_array_new_length(); 215 | } catch (const std::exception &e) { 216 | try { 217 | t2 = e.what(); 218 | throw std::runtime_error("test"); 219 | } catch (const std::runtime_error &e) { 220 | t3 = e.what(); 221 | } catch (const std::exception &) { 222 | } 223 | } 224 | } 225 | }); 226 | EXPECT_FALSE(t1.empty() && t2.empty() && t3.empty()); 227 | } 228 | 229 | TEST(ntl_test, ntl_irql_test) { 230 | auto old_irql = ntl::current_irql(); 231 | { 232 | auto raised_irql = ntl::raise_irql(ntl::irql::apc); 233 | EXPECT_EQ(old_irql, raised_irql.old()); 234 | EXPECT_EQ(ntl::current_irql(), ntl::irql::apc); 235 | } 236 | EXPECT_EQ(ntl::current_irql(), old_irql); 237 | 238 | old_irql = ntl::current_irql(); 239 | { 240 | auto raised_irql = ntl::raise_irql_to_dpc_level(); 241 | EXPECT_EQ(old_irql, raised_irql.old()); 242 | 243 | EXPECT_EQ(ntl::current_irql(), ntl::irql::dispatch); 244 | } 245 | 246 | EXPECT_EQ(ntl::current_irql(), old_irql); 247 | } 248 | 249 | TEST(ntl_test, ntl_spin_lock_test) { 250 | ntl::spin_lock lock; 251 | ntl::spin_lock lock2; 252 | { 253 | EXPECT_TRUE(lock.test()); 254 | 255 | std::unique_lock lk(lock); 256 | EXPECT_FALSE(lock.test()); 257 | EXPECT_TRUE(lk.owns_lock()); 258 | 259 | std::unique_lock lk2(lock, std::try_to_lock); 260 | EXPECT_FALSE(lock.test()); 261 | EXPECT_FALSE(lk2.owns_lock()); 262 | 263 | ntl::unique_lock lk3(lock2, ntl::at_dpc_level_lock); 264 | EXPECT_FALSE(lock2.test()); 265 | EXPECT_TRUE(lk3.owns_lock()); 266 | } 267 | EXPECT_TRUE(lock.test()); 268 | EXPECT_TRUE(KeTestSpinLock(lock.native_handle())); 269 | } 270 | 271 | TEST(ntl_test, ntl_resource_test) { 272 | ntl::resource res; 273 | { 274 | std::shared_lock lk(res); 275 | EXPECT_TRUE(lk.owns_lock()); 276 | EXPECT_TRUE(res.locked()); 277 | EXPECT_TRUE(res.locked_shared()); 278 | 279 | std::unique_lock lk2(res, std::try_to_lock); 280 | EXPECT_FALSE(lk2.owns_lock()); 281 | EXPECT_FALSE(res.locked_exclusive()); 282 | } 283 | EXPECT_FALSE(res.locked()); 284 | EXPECT_FALSE(res.locked_exclusive()); 285 | EXPECT_FALSE(res.locked_shared()); 286 | 287 | ntl::resource res2; 288 | std::unique_lock lk3(res); 289 | EXPECT_TRUE(lk3.owns_lock()); 290 | EXPECT_TRUE(res.locked()); 291 | EXPECT_TRUE(res.locked_exclusive()); 292 | 293 | std::shared_lock lk4(res, std::try_to_lock); 294 | EXPECT_TRUE(lk4.owns_lock()); 295 | EXPECT_FALSE(res.locked_shared()); 296 | 297 | ntl::unique_lock lk5(res2, ntl::adopt_critical_region); 298 | EXPECT_TRUE(lk5.owns_lock()); 299 | EXPECT_TRUE(res2.locked()); 300 | EXPECT_TRUE(res2.locked_exclusive()); 301 | EXPECT_FALSE(res2.locked_shared()); 302 | 303 | ntl::shared_lock lk6(lk5); 304 | EXPECT_FALSE(lk5.owns_lock()); 305 | EXPECT_TRUE(lk6.owns_lock()); 306 | EXPECT_TRUE(res2.locked()); 307 | EXPECT_TRUE(res2.locked_shared()); 308 | EXPECT_FALSE(res2.locked_exclusive()); 309 | 310 | ntl::resource res3; 311 | ntl::shared_lock lk7(res3, ntl::adopt_critical_region); 312 | EXPECT_TRUE(lk7.owns_lock()); 313 | EXPECT_TRUE(res3.locked()); 314 | EXPECT_TRUE(res3.locked_shared()); 315 | } --------------------------------------------------------------------------------