From 97cca85bc8098796f3b84e09600f4e0701bb0d4f Mon Sep 17 00:00:00 2001 From: "[ ]" <[ ]> Date: Thu, 22 Jan 2026 08:22:00 +0900 Subject: [PATCH] refactor: Lazy load winscard > still requires proper testing with hardware --- CMakeLists.txt | 8 +++--- external/scard/scard.cpp | 62 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eea7b3b..9ccaf07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -627,7 +627,7 @@ source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "Source Files" FILES ${SOUR set(RESOURCE_FILES build/manifest.manifest build/manifest.rc build/icon.rc cfg/Win32D.rc) add_executable(spicetools_spice ${SOURCE_FILES} ${RESOURCE_FILES}) target_link_libraries(spicetools_spice - PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winscard winhttp + PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features) set_target_properties(spicetools_spice PROPERTIES PREFIX "") set_target_properties(spicetools_spice PROPERTIES OUTPUT_NAME "spice") @@ -642,7 +642,7 @@ endif() set(RESOURCE_FILES build/manifest.manifest build/manifest.rc build/icon.rc cfg/Win32D.rc) add_executable(spicetools_spice_laa ${SOURCE_FILES} ${RESOURCE_FILES}) target_link_libraries(spicetools_spice_laa - PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winscard winhttp + PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features) set_target_properties(spicetools_spice_laa PROPERTIES PREFIX "") set_target_properties(spicetools_spice_laa PROPERTIES OUTPUT_NAME "spice_laa") @@ -660,7 +660,7 @@ add_executable(spicetools_spice64 ${SOURCE_FILES} ${RESOURCE_FILES}) # do NOT link against: mf, mfplat, mfreadwrite; otherwise unity games will break target_link_libraries(spicetools_spice64 - PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winscard winhttp mfuuid strmiids dxva2 + PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp mfuuid strmiids dxva2 PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features) set_target_properties(spicetools_spice64 PROPERTIES PREFIX "") @@ -678,7 +678,7 @@ set(SOURCE_FILES ${SOURCE_FILES} launcher/options.h launcher/options.cpp) set(RESOURCE_FILES cfg/manifest.manifest cfg/manifest.rc cfg/icon.rc cfg/Win32D.rc) add_executable(spicetools_cfg WIN32 ${SOURCE_FILES} ${RESOURCE_FILES}) target_link_libraries(spicetools_cfg - PUBLIC ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winscard winhttp strmiids + PUBLIC ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp strmiids PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features) set_target_properties(spicetools_cfg PROPERTIES PREFIX "") set_target_properties(spicetools_cfg PROPERTIES OUTPUT_NAME "spicecfg") diff --git a/external/scard/scard.cpp b/external/scard/scard.cpp index d3d6b52..221c7f4 100644 --- a/external/scard/scard.cpp +++ b/external/scard/scard.cpp @@ -30,8 +30,65 @@ #include #include "util/utils.h" #include "util/logging.h" +#include "util/libutils.h" #include "hooks/sleephook.h" +//_INFO: Lazy load winscard, not tested on actual hardware +struct Winscard +{ + + decltype(&::SCardEstablishContext) SCardEstablishContext; + decltype(&::SCardListReadersA) SCardListReadersA; + decltype(&::SCardFreeMemory) SCardFreeMemory; + decltype(&::SCardGetStatusChangeA) SCardGetStatusChangeA; + decltype(&::SCardConnectA) SCardConnectA; + decltype(&::SCardTransmit) SCardTransmit; + decltype(&::SCardStatusA) SCardStatusA; + decltype(&::SCardDisconnect) SCardDisconnect; + decltype(::g_rgSCardT0Pci)* g_rgSCardT0Pci; + decltype(::g_rgSCardT1Pci)* g_rgSCardT1Pci; + inline static Winscard *instance = nullptr; + + static HMODULE attach() + { + if (instance) return instance->lib_; + instance = new Winscard(); + return instance->lib_; + } + +private: + HMODULE lib_; + + Winscard() + { + #define GETPROC(name) (name) = reinterpret_cast(GetProcAddress(lib_, #name)) + if ((lib_ = libutils::try_library("winscard.dll"))) + { + GETPROC(SCardEstablishContext); + GETPROC(SCardListReadersA); + GETPROC(SCardFreeMemory); + GETPROC(SCardGetStatusChangeA); + GETPROC(SCardConnectA); + GETPROC(SCardTransmit); + GETPROC(SCardStatusA); + GETPROC(SCardDisconnect); + GETPROC(g_rgSCardT0Pci); + GETPROC(g_rgSCardT1Pci); + } + #undef GETPROC + } +}; +#define SCardEstablishContext Winscard::instance->SCardEstablishContext +#define SCardListReadersA Winscard::instance->SCardListReadersA +#define SCardFreeMemory Winscard::instance->SCardFreeMemory +#define SCardGetStatusChangeA Winscard::instance->SCardGetStatusChangeA +#define SCardConnectA Winscard::instance->SCardConnectA +#define SCardTransmit Winscard::instance->SCardTransmit +#define SCardStatusA Winscard::instance->SCardStatusA +#define SCardDisconnect Winscard::instance->SCardDisconnect +#define g_rgSCardT0Pci (*Winscard::instance->g_rgSCardT0Pci) +#define g_rgSCardT1Pci (*Winscard::instance->g_rgSCardT1Pci) + #define MAX_APDU_SIZE 255 #define SCARD_POLL_INTERVAL_MS 100 @@ -402,6 +459,11 @@ int scard_threadmain() { } void scard_threadstart() { + if(!Winscard::attach()) + { + log_warning("scard", "Support disabled due to missing winscard.dll"); + return; + } std::thread t(scard_threadmain); t.detach(); }