diff --git a/CMakeLists.txt b/CMakeLists.txt index 3810ed60..5033985c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,19 @@ if(TARGET secude_compat) set_property(TARGET secude_compat PROPERTY INTERFACE_COMPILE_FEATURES "") endif() add_subdirectory(port/mfcwx) +# These libraries open files by paths CrypTool passes in Windows form; the app links mfcwx, which +# converts them, and the library tests use plain stubs. +foreach(target cryptool_analyse cryptool_cracklib) + target_compile_options(${target} PRIVATE "SHELL:-iquote ${CMAKE_SOURCE_DIR}/port/mfcwx/include" + "SHELL:-include ${CMAKE_SOURCE_DIR}/port/mfcwx/include/mfcwx/pathcompat.h") +endforeach() +add_library(mfcwx_path_stubs STATIC port/mfcwx/tests/path_stubs.cpp) +target_include_directories(mfcwx_path_stubs PRIVATE port/mfcwx/include) +foreach(test test_analyse test_cracklib) + if(TARGET ${test}) + target_link_libraries(${test} PRIVATE mfcwx_path_stubs) + endif() +endforeach() add_subdirectory(port/app) option(CRYPTOOL_DIALOG_GALLERY "Build the dialog snapshot tool" OFF) diff --git a/port/app/CMakeLists.txt b/port/app/CMakeLists.txt index 18b2d002..94fc03af 100644 --- a/port/app/CMakeLists.txt +++ b/port/app/CMakeLists.txt @@ -18,7 +18,8 @@ file(GLOB CT_EXTRA_SOURCES CONFIGURE_DEPENDS ${REPO_ROOT}/libVolRen/CQuaternion.cpp ${REPO_ROOT}/libVolRen/CVector.cpp ${REPO_ROOT}/libVolRen/Volume.cpp ${REPO_ROOT}/libVolRen/VolumeUtilities.cpp ${REPO_ROOT}/ChallengeResponse/*.cpp) -add_executable(CrypTool ${CT_SOURCES} ${CT_EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/platform.cpp) +add_executable(CrypTool ${CT_SOURCES} ${CT_EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/platform.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/miracl_rand.cpp) mfcwx_add_rc(CrypTool RC ${CT_SRC}/CrypTool.rc MODULE CrypTool HEADERS ${CT_SRC}/resource.h REPLACE "[CRYPTOOL_VERSION_FULL]=CrypTool ${PROJECT_VERSION}" "[CRYPTOOL_VERSION]=${PROJECT_VERSION}") diff --git a/port/app/miracl_rand.cpp b/port/app/miracl_rand.cpp new file mode 100644 index 00000000..c7fe4326 --- /dev/null +++ b/port/app/miracl_rand.cpp @@ -0,0 +1,5 @@ +// Compiled without mfcwx/crtcompat.h: app code sees MIRACL's rand overloads renamed to mfcwx_rand. +#include "BIG.H" + +Big mfcwx_rand(const Big& w) { return rand(w); } +Big mfcwx_rand(int n, int b) { return rand(n, b); } diff --git a/port/mfcwx/include/mfcwx/crtcompat.h b/port/mfcwx/include/mfcwx/crtcompat.h index 17fe75b0..b2b2ac4c 100644 --- a/port/mfcwx/include/mfcwx/crtcompat.h +++ b/port/mfcwx/include/mfcwx/crtcompat.h @@ -387,8 +387,20 @@ int _findclose(intptr_t handle); #define _findfirsti64 _findfirst #define _findnexti64 _findnext +/* rand() of the Microsoft C runtime (per-thread LCG, RAND_MAX 0x7fff); CrypTool sizes buffers for it. */ +int mfcwx_rand(void); +void mfcwx_srand(unsigned int seed); +#undef RAND_MAX +#define RAND_MAX 0x7fff +#define rand mfcwx_rand +#define srand mfcwx_srand + #endif /* _MFCWX_CRTCOMPAT */ #ifdef __cplusplus } +namespace std { +using ::mfcwx_rand; +using ::mfcwx_srand; +} #endif diff --git a/port/mfcwx/include/mfcwx/pathcompat.h b/port/mfcwx/include/mfcwx/pathcompat.h new file mode 100644 index 00000000..5422a201 --- /dev/null +++ b/port/mfcwx/include/mfcwx/pathcompat.h @@ -0,0 +1,17 @@ +#pragma once + +// Force-included into third-party libraries that open files by paths coming from CrypTool, +// which are in Windows form ("\dir\file"). + +#include + +#ifdef __cplusplus +extern "C" { +#endif +FILE* mfcwx_fopen(const char* name, const char* mode); +#ifdef __cplusplus +} +#include "mfcwx/fstreamcompat.h" +#endif + +#define fopen mfcwx_fopen diff --git a/port/mfcwx/src/crt.cpp b/port/mfcwx/src/crt.cpp index e9353cd5..5adc1ddd 100644 --- a/port/mfcwx/src/crt.cpp +++ b/port/mfcwx/src/crt.cpp @@ -848,3 +848,16 @@ intptr_t _spawnl(int mode, const char* cmdname, const char* arg0, ...) { CloseHandle(pi.hProcess); return 0; } + +namespace { + +thread_local unsigned int g_randSeed = 1; + +} // namespace + +extern "C" int mfcwx_rand(void) { + g_randSeed = g_randSeed * 214013u + 2531011u; + return static_cast((g_randSeed >> 16) & 0x7fff); +} + +extern "C" void mfcwx_srand(unsigned int seed) { g_randSeed = seed; } diff --git a/port/mfcwx/src/snapshot.cpp b/port/mfcwx/src/snapshot.cpp index 88656884..68559456 100644 --- a/port/mfcwx/src/snapshot.cpp +++ b/port/mfcwx/src/snapshot.cpp @@ -7,6 +7,9 @@ #include #include +#include +#include +#include namespace mfcwx { @@ -78,9 +81,109 @@ class SnapshotTimer : public wxTimer { int m_round = 0; }; +std::string SafeName(const wxString& title) { + std::string name; + for (wxUniChar c : title) + name += (c.IsAscii() && isalnum(static_cast(c.GetValue()))) ? static_cast(c.GetValue()) : '_'; + return name.substr(0, 40); +} + +wxWindow* ActiveDialog() { + wxWindow* found = nullptr; + for (wxWindow* w : wxTopLevelWindows) { + auto* d = wxDynamicCast(w, wxDialog); + if (d && d->IsShown()) + found = d; + } + return found; +} + +// Development aid: MFCWX_AUTOMATION=file runs one step per line on a timer, for UI tests: +// command WM_COMMAND to the main window +// button WM_COMMAND (BN_CLICKED) to the topmost dialog +// text sets the text of a control of the topmost dialog +// wait +// snapshot