From fa2568a5e33acf6af96c097505665cba6f607028 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 27 Jan 2021 10:39:39 +0100 Subject: [PATCH] Check loading of blacklisted dlls and show warning dialog at startup. Also show these dlls in sysinfo dialog. --- src/CMakeLists.txt | 5 ++ src/PrusaSlicer.cpp | 14 +++++ src/PrusaSlicer_app_msvc.cpp | 1 - src/hidapi/win/hid.c | 3 +- src/libslic3r/CMakeLists.txt | 2 + src/libslic3r/LibraryCheck.cpp | 100 +++++++++++++++++++++++++++++++ src/libslic3r/LibraryCheck.hpp | 45 ++++++++++++++ src/slic3r/GUI/GUI_App.cpp | 1 + src/slic3r/GUI/GUI_Utils.cpp | 1 - src/slic3r/GUI/SysInfoDialog.cpp | 4 +- src/slic3r/GUI/SysInfoDialog.hpp | 1 - 11 files changed, 172 insertions(+), 5 deletions(-) create mode 100644 src/libslic3r/LibraryCheck.cpp create mode 100644 src/libslic3r/LibraryCheck.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index acd8d465c..293cbcd79 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -140,6 +140,11 @@ target_link_libraries(PrusaSlicer libslic3r_gui) else () target_link_libraries(PrusaSlicer -ldl) endif () + if (WIN32) + include_directories(detours) + find_library(PSAPI_LIB NAMES Psapi) + target_link_libraries(PrusaSlicer ${PSAPI_LIB}) + endif () endif () # On Windows, a shim application is required to produce a console / non console version of the Slic3r application. diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 35450782b..a68c5cd0f 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -48,6 +48,7 @@ #include "libslic3r/Format/SL1.hpp" #include "libslic3r/Utils.hpp" #include "libslic3r/Thread.hpp" +#include "libslic3r/LibraryCheck.hpp" #include "PrusaSlicer.hpp" @@ -566,6 +567,7 @@ int CLI::run(int argc, char **argv) } } + if (start_gui) { #ifdef SLIC3R_GUI Slic3r::GUI::GUI_InitParams params; @@ -600,6 +602,18 @@ bool CLI::setup(int argc, char **argv) } } +#ifdef WIN32 + // Notify user if blacklisted library is already loaded (Nahimic) + // If there are cases of no reports with blacklisted lib - this check should be performed later. + // Some libraries are loaded when we load libraries during startup. + if (LibraryCheck::get_instance().perform_check()) { + std::wstring text = L"Following libraries has been detected inside of the PrusaSlicer process." + L" We suggest stopping or uninstalling these services if you experience crashes or unexpected behaviour while using PrusaSlicer.\n\n"; + text += LibraryCheck::get_instance().get_blacklisted_string(); + MessageBoxW(NULL, text.c_str(), L"Warning"/*L"Incopatible library found"*/, MB_OK); + } +#endif + // See Invoking prusa-slicer from $PATH environment variable crashes #5542 // boost::filesystem::path path_to_binary = boost::filesystem::system_complete(argv[0]); boost::filesystem::path path_to_binary = boost::dll::program_location(); diff --git a/src/PrusaSlicer_app_msvc.cpp b/src/PrusaSlicer_app_msvc.cpp index 5f12c9147..7710d9eb7 100644 --- a/src/PrusaSlicer_app_msvc.cpp +++ b/src/PrusaSlicer_app_msvc.cpp @@ -208,7 +208,6 @@ extern "C" { } extern "C" { - #ifdef SLIC3R_WRAPPER_NOCONSOLE int APIENTRY wWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, PWSTR /* lpCmdLine */, int /* nCmdShow */) { diff --git a/src/hidapi/win/hid.c b/src/hidapi/win/hid.c index 4a71e2552..881aedf5b 100644 --- a/src/hidapi/win/hid.c +++ b/src/hidapi/win/hid.c @@ -130,7 +130,7 @@ extern "C" { static HMODULE lib_handle = NULL; static BOOLEAN initialized = FALSE; #endif /* HIDAPI_USE_DDK */ - + struct hid_device_ { HANDLE device_handle; BOOL blocking; @@ -200,6 +200,7 @@ static void register_error(hid_device *dev, const char *op) } #ifndef HIDAPI_USE_DDK + static int lookup_functions() { lib_handle = LoadLibraryA("hid.dll"); diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 11e37afc6..7b7067d9f 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -120,6 +120,8 @@ add_library(libslic3r STATIC "${CMAKE_CURRENT_BINARY_DIR}/libslic3r_version.h" Line.cpp Line.hpp + LibraryCheck.cpp + LibraryCheck.hpp Model.cpp Model.hpp ModelArrange.hpp diff --git a/src/libslic3r/LibraryCheck.cpp b/src/libslic3r/LibraryCheck.cpp new file mode 100644 index 000000000..7cd507a8e --- /dev/null +++ b/src/libslic3r/LibraryCheck.cpp @@ -0,0 +1,100 @@ +#include "LibraryCheck.hpp" + +#include +#include +#include + +namespace Slic3r { + +#ifdef WIN32 + +//only dll name with .dll suffix - currently case sensitive +const std::vector LibraryCheck::blacklist({ L"NahimicOSD.dll" }); + +bool LibraryCheck::get_blacklisted(std::vector& names) +{ + if (m_found.empty()) + return false; + for (const auto& lib : m_found) + names.emplace_back(lib); + return true; + +} + +std::wstring LibraryCheck::get_blacklisted_string() +{ + std::wstring ret; + if (m_found.empty()) + return ret; + //ret = L"These libraries has been detected inside of the PrusaSlicer process.\n" + // L"We suggest stopping or uninstalling these services if you experience crashes while using PrusaSlicer.\n\n"; + for (const auto& lib : m_found) + { + ret += lib; + ret += L"\n"; + } + return ret; +} + +bool LibraryCheck::perform_check() +{ + + DWORD processID = GetCurrentProcessId(); + HMODULE hMods[1024]; + HANDLE hProcess; + DWORD cbNeeded; + unsigned int i; + + // Get a handle to the process. + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | + PROCESS_VM_READ, + FALSE, processID); + if (NULL == hProcess) + return false; + // Get a list of all the modules in this process. + if (EnumProcessModulesEx(hProcess, hMods, sizeof(hMods), &cbNeeded, LIST_MODULES_ALL)) + { + //printf("Total Dlls: %d\n", cbNeeded / sizeof(HMODULE)); + for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) + { + TCHAR szModName[MAX_PATH]; + // Get the full path to the module's file. + if (GetModuleFileNameEx(hProcess, hMods[i], szModName, + sizeof(szModName) / sizeof(TCHAR))) + { + // Add to list if blacklisted + if(LibraryCheck::is_blacklisted(szModName)) { + //wprintf(L"Contains library: %s\n", szModName); + if (std::find(m_found.begin(), m_found.end(), szModName) == m_found.end()) + m_found.emplace_back(szModName); + } + //wprintf(L"%s\n", szModName); + } + } + } + + CloseHandle(hProcess); + //printf("\n"); + return !m_found.empty(); + +} + +bool LibraryCheck::is_blacklisted(std::wstring dllpath) +{ + std::wstring dllname = boost::filesystem::path(dllpath).filename().wstring(); + //std::transform(dllname.begin(), dllname.end(), dllname.begin(), std::tolower); + if (std::find(LibraryCheck::blacklist.begin(), LibraryCheck::blacklist.end(), dllname) != LibraryCheck::blacklist.end()) { + //std::wprintf(L"%s is blacklisted\n", dllname.c_str()); + return true; + } + //std::wprintf(L"%s is NOT blacklisted\n", dllname.c_str()); + return false; +} +bool LibraryCheck::is_blacklisted(std::string dllpath) +{ + return LibraryCheck::is_blacklisted(boost::nowide::widen(dllpath)); +} + +#endif //WIN32 + +} // namespace Slic3r diff --git a/src/libslic3r/LibraryCheck.hpp b/src/libslic3r/LibraryCheck.hpp new file mode 100644 index 000000000..663bf019e --- /dev/null +++ b/src/libslic3r/LibraryCheck.hpp @@ -0,0 +1,45 @@ +#ifndef slic3r_LibraryCheck_hpp_ +#define slic3r_LibraryCheck_hpp_ + +#ifdef WIN32 +#include +#include +#include +#endif //WIN32 + +namespace Slic3r { + +#ifdef WIN32 +class LibraryCheck +{ +public: + static LibraryCheck& get_instance() + { + static LibraryCheck instance; + + return instance; + } +private: + LibraryCheck() {} + + std::vector m_found; +public: + LibraryCheck(LibraryCheck const&) = delete; + void operator=(LibraryCheck const&) = delete; + // returns all found blacklisted dlls + bool get_blacklisted(std::vector& names); + std::wstring get_blacklisted_string(); + // returns true if enumerating found blacklisted dll + bool perform_check(); + + static bool is_blacklisted(std::string dllpath); + static bool is_blacklisted(std::wstring dllpath); +private: + static const std::vector blacklist; +}; + +#endif //WIN32 + +} // namespace Slic3r + +#endif //slic3r_LibraryCheck_hpp_ \ No newline at end of file diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 4c4b4b4c2..e144df6d0 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -775,6 +775,7 @@ bool GUI_App::on_init_inner() // Slic3r::debugf "wxWidgets version %s, Wx version %s\n", wxVERSION_STRING, wxVERSION; + if (is_editor()) { std::string msg = Http::tls_global_init(); std::string ssl_cert_store = app_config->get("tls_accepted_cert_store_location"); diff --git a/src/slic3r/GUI/GUI_Utils.cpp b/src/slic3r/GUI/GUI_Utils.cpp index e2a6ccb88..adb9633ea 100644 --- a/src/slic3r/GUI/GUI_Utils.cpp +++ b/src/slic3r/GUI/GUI_Utils.cpp @@ -17,7 +17,6 @@ #include "libslic3r/Config.hpp" - namespace Slic3r { namespace GUI { diff --git a/src/slic3r/GUI/SysInfoDialog.cpp b/src/slic3r/GUI/SysInfoDialog.cpp index 8d9572b47..508d7a930 100644 --- a/src/slic3r/GUI/SysInfoDialog.cpp +++ b/src/slic3r/GUI/SysInfoDialog.cpp @@ -14,6 +14,7 @@ #include "GUI_App.hpp" #include "MainFrame.hpp" #include "wxExtensions.hpp" +#include "../libslic3r/LibraryCheck.hpp" #ifdef _WIN32 // The standard Windows includes. @@ -149,7 +150,8 @@ SysInfoDialog::SysInfoDialog() "" "" "", bgr_clr_str, text_clr_str, text_clr_str, - get_mem_info(true) + "
" + wxGetApp().get_gl_info(true, true) + "
Eigen vectorization supported: " + Eigen::SimdInstructionSetsInUse()); + get_mem_info(true) + "
" + wxGetApp().get_gl_info(true, true) + "
Eigen vectorization supported: " + Eigen::SimdInstructionSetsInUse() + + "

Blacklisted loaded libraries:
" + LibraryCheck::get_instance().get_blacklisted_string().c_str()); m_opengl_info_html->SetPage(text); main_sizer->Add(m_opengl_info_html, 1, wxEXPAND | wxBOTTOM, 15); } diff --git a/src/slic3r/GUI/SysInfoDialog.hpp b/src/slic3r/GUI/SysInfoDialog.hpp index 3b1459648..070db61b2 100644 --- a/src/slic3r/GUI/SysInfoDialog.hpp +++ b/src/slic3r/GUI/SysInfoDialog.hpp @@ -29,7 +29,6 @@ private: void onCopyToClipboard(wxEvent &); void onCloseDialog(wxEvent &); }; - } // namespace GUI } // namespace Slic3r