MSVC: Set /DEPENDENTLOADFLAG:0x800 to restrict DLL loading to SYSTEM32 on startup.

On Windows 10 1607+, this flag is equivalent to calling the
SetDefaultDllDirectories() function before the program starts.

We're already calling SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32)
in librpsecure/win32/restrict-dll.c, but this ensures that it's set even
before the program starts.

Related changes:

- amiiboc: Use delay-loading for libfmt. Otherwise, it fails with
  error code 0xC0000135.
  - Added a dummy stdafx.h file, required by DelayLoadHelper.c.

- All tests: Set /DEPENDENTLOADFLAG:0xA00 because gtest cannot be
  delay-loaded.

- msvc.cmake: Fix linker flags for RelWithDebInfo.

TODO:
- EXE: Show DEPENDENTLOADFLAG.
- Test svrplus.
This commit is contained in:
David Korth 2025-03-20 20:49:11 -04:00
parent 66c0382bce
commit 734a72ca78
11 changed files with 98 additions and 13 deletions

View File

@ -172,6 +172,30 @@ ENDIF(NOT CMAKE_SIZEOF_VOID_P)
# (It ignores the "\0" in string tables, too.)
SET(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} /n")
# Dependent load flags (MSVC 2017+, Windows 10 1607+)
# For most executables and DLLs, this will be set to 0x800 (LOAD_LIBRARY_SEARCH_SYSTEM32),
# which disables loading DLLs from the current directory and application directory.
# For unit tests, we have to use 0xA00, which adds LOAD_LIBRARY_SEARCH_APPLICATION_DIR,
# because Google Test doesn't support delay-load due to exported data symbols.
#
# LINK : fatal error LNK1194: cannot delay-load 'gtestd.dll' due to import of data symbol
# '"__declspec(dllimport) class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > testing::FLAGS_gtest_death_test_style"'
# link without /DELAYLOAD:gtestd.dll
IF(MSVC_VERSION GREATER 1909)
SET(RP_LINKER_FLAG_DEPENDENT_LOAD_FLAG_DEFAULT "/DEPENDENTLOADFLAG:0x800")
SET(RP_LINKER_FLAG_DEPENDENT_LOAD_FLAG_GTEST "/DEPENDENTLOADFLAG:0xA00")
MACRO(SET_DEPENDENT_LOAD_FLAG_GTEST)
FOREACH(_type EXE SHARED MODULE)
STRING(REPLACE "${RP_LINKER_FLAG_DEPENDENT_LOAD_FLAG_DEFAULT}" "${RP_LINKER_FLAG_DEPENDENT_LOAD_FLAG_GTEST}" CMAKE_${_type}_LINKER_FLAGS "${CMAKE_${_type}_LINKER_FLAGS}")
ENDFOREACH(_type)
ENDMACRO(SET_DEPENDENT_LOAD_FLAG_GTEST)
ENDIF(MSVC_VERSION GREATER 1909)
FOREACH(_type EXE SHARED MODULE)
SET(RP_${_type}_LINKER_FLAGS_COMMON "${RP_${_type}_LINKER_FLAGS_COMMON} ${RP_LINKER_FLAG_DEPENDENT_LOAD_FLAG_DEFAULT}")
ENDFOREACH(_type)
# TODO: Code coverage checking for MSVC?
IF(ENABLE_COVERAGE)
MESSAGE(FATAL_ERROR "Code coverage testing is currently only supported on gcc and clang.")
@ -191,11 +215,11 @@ SET(RP_EXE_LINKER_FLAGS_RELEASE "/DEBUG /INCREMENTAL:NO /OPT:ICF,REF")
SET(RP_SHARED_LINKER_FLAGS_RELEASE "${RP_EXE_LINKER_FLAGS_RELEASE}")
SET(RP_MODULE_LINKER_FLAGS_RELEASE "${RP_EXE_LINKER_FLAGS_RELEASE}")
SET(RP_C_FLAGS_RELWITHDEBINFO "/Zi")
SET(RP_CXX_FLAGS_RELWITHDEBINFO "/Zi")
SET(RP_EXE_LINKER_FLAGS_RELEASE "/DEBUG /INCREMENTAL:NO /OPT:ICF,REF")
SET(RP_SHARED_LINKER_FLAGS_RELEASE "${RP_EXE_LINKER_FLAGS_RELEASE}")
SET(RP_MODULE_LINKER_FLAGS_RELEASE "${RP_EXE_LINKER_FLAGS_RELEASE}")
SET(RP_C_FLAGS_RELWITHDEBINFO "/Zi")
SET(RP_CXX_FLAGS_RELWITHDEBINFO "/Zi")
SET(RP_EXE_LINKER_FLAGS_RELWITHDEBINFO "/DEBUG /INCREMENTAL:NO /OPT:ICF,REF")
SET(RP_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${RP_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
SET(RP_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${RP_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
# Check for link-time optimization. (Release builds only.)
IF(ENABLE_LTO)

View File

@ -3,12 +3,16 @@ PROJECT(amiibo-data LANGUAGES CXX)
SET(amiiboc_SRCS amiiboc.cpp)
IF(MSVC)
# Delay-load sources.
SET(${PROJECT_NAME}-DELAYLOAD_SRC ../libwin32common/DelayLoadHelper.c)
SET(${PROJECT_NAME}-DELAYLOAD_H ../libwin32common/DelayLoadHelper.h)
ENDIF(MSVC)
#########################
# Build the executable. #
#########################
INCLUDE(SetMSVCDebugPath)
IF(CMAKE_CROSSCOMPILING)
# Cross-compiling.
# Use executables from a native build.
@ -19,6 +23,12 @@ Set IMPORT_EXECUTABLES to the path to a CMake build for the host system's build
INCLUDE("${IMPORT_EXECUTABLES}/src/amiibo-data/ImportExecutables.cmake")
ELSE(CMAKE_CROSSCOMPILING)
# Not cross-compiling.
# Delay-load extlibs.
INCLUDE(../libwin32common/DelayLoadHelper.cmake)
SET_DELAYLOAD_EXTLIB_FLAGS()
INCLUDE(SetMSVCDebugPath)
ADD_EXECUTABLE(amiiboc ${amiiboc_SRCS})
DO_SPLIT_DEBUG(amiiboc)
SET_WINDOWS_SUBSYSTEM(amiiboc CONSOLE)

11
src/amiibo-data/stdafx.h Normal file
View File

@ -0,0 +1,11 @@
/***************************************************************************
* ROM Properties Page shell extension. (amiibo-data) *
* stdafx.h: Common definitions and includes. *
* *
* Copyright (c) 2016-2025 by David Korth. *
* SPDX-License-Identifier: GPL-2.0-or-later *
***************************************************************************/
#pragma once
// NOTE: Dummy file for DelayLoadHelper.c.

View File

@ -1,10 +1,15 @@
# libcachecommon test suite
PROJECT(libcachecommon-tests LANGUAGES CXX)
# Top-level src directory.
# Top-level src directory
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../..)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/../..)
# MSVC: Set /DEPENDENTLOADFLAG:0xA00 for unit tests.
IF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
SET_DEPENDENT_LOAD_FLAG_GTEST()
ENDIF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
# LibCacheCommon::filterCacheKey() test.
ADD_EXECUTABLE(FilterCacheKeyTest FilterCacheKeyTest.cpp)
TARGET_LINK_LIBRARIES(FilterCacheKeyTest PRIVATE rptest cachecommon rptext)

View File

@ -8,6 +8,11 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../..)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/../..)
# MSVC: Set /DEPENDENTLOADFLAG:0xA00 for unit tests.
IF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
SET_DEPENDENT_LOAD_FLAG_GTEST()
ENDIF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
IF(NOT WIN32)
INCLUDE(CheckSymbolExists)
CHECK_SYMBOL_EXISTS(posix_fadvise "fcntl.h" HAVE_POSIX_FADVISE)

View File

@ -1,10 +1,15 @@
# librpbase test suite
PROJECT(librpbase-tests LANGUAGES CXX)
# Top-level src directory.
# Top-level src directory
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../..)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/../..)
# MSVC: Set /DEPENDENTLOADFLAG:0xA00 for unit tests.
IF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
SET_DEPENDENT_LOAD_FLAG_GTEST()
ENDIF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
# ZLIB and libpng are checked in the top-level CMakeLists.txt.
IF(NOT WIN32)

View File

@ -7,10 +7,15 @@ IF(POLICY CMP0063)
ENDIF(POLICY CMP0063)
PROJECT(librpbyteswap-tests LANGUAGES CXX)
# Top-level src directory.
# Top-level src directory
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../..)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/../..)
# MSVC: Set /DEPENDENTLOADFLAG:0xA00 for unit tests.
IF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
SET_DEPENDENT_LOAD_FLAG_GTEST()
ENDIF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
# ByteswapTest
ADD_EXECUTABLE(ByteswapTest
ByteswapTest.cpp

View File

@ -1,10 +1,15 @@
# librptext test suite
PROJECT(librpbase-tests LANGUAGES CXX)
# Top-level src directory.
# Top-level src directory
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../..)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/../..)
# MSVC: Set /DEPENDENTLOADFLAG:0xA00 for unit tests.
IF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
SET_DEPENDENT_LOAD_FLAG_GTEST()
ENDIF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
# TextFuncsTest
ADD_EXECUTABLE(TextFuncsTest
TextFuncsTest.cpp

View File

@ -1,10 +1,15 @@
# librptexture test suite
PROJECT(librptexture-tests LANGUAGES CXX)
# Top-level src directory.
# Top-level src directory
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../..)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/../..)
# MSVC: Set /DEPENDENTLOADFLAG:0xA00 for unit tests.
IF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
SET_DEPENDENT_LOAD_FLAG_GTEST()
ENDIF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
# ImageDecoderLinear test
# TODO: Move to libromdata, or move libromdata stuff here?
ADD_EXECUTABLE(ImageDecoderLinearTest ImageDecoderLinearTest.cpp)

View File

@ -5,6 +5,11 @@ PROJECT(rp-download-tests LANGUAGES CXX)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../..)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/../..)
# MSVC: Set /DEPENDENTLOADFLAG:0xA00 for unit tests.
IF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
SET_DEPENDENT_LOAD_FLAG_GTEST()
ENDIF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
# CacheKeyVerifyTest
# NOTE: We can't disable NLS here due to its usage
# in FstPrint.cpp. gtest_init.cpp will set LC_ALL=C.

View File

@ -5,10 +5,15 @@ PROJECT(win32-tests LANGUAGES CXX)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../..)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/../..)
# GTK source directory
# Win32 source directory
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/..)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/..)
# MSVC: Set /DEPENDENTLOADFLAG:0xA00 for unit tests.
IF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
SET_DEPENDENT_LOAD_FLAG_GTEST()
ENDIF(COMMAND SET_DEPENDENT_LOAD_FLAG_GTEST)
### RomDataFormat tests
SET(RomDataFormatTest_SRCS