From 2f6f1f0e5555e8c41daef9c4f4a0fe033282c9c2 Mon Sep 17 00:00:00 2001
From: Vojtech Bubnik <bubnikv@gmail.com>
Date: Fri, 30 Jul 2021 15:52:43 +0200
Subject: [PATCH] WIN32 specific Blacklisted libraries check: 1) Polished up
 wording of the error messages. 2) Made some messages in the SysInfo dialog
 localized. 3) Renamed LibraryCheck.cpp/hpp to BlacklistedLibraryCheck.cpp/hpp
 4) CPPized the BlacklistedLibraryCheck WIN32 C code.

---
 src/PrusaSlicer.cpp                           | 21 +++++---
 ...yCheck.cpp => BlacklistedLibraryCheck.cpp} | 54 +++++++------------
 ...yCheck.hpp => BlacklistedLibraryCheck.hpp} | 23 ++++----
 src/libslic3r/CMakeLists.txt                  |  4 +-
 src/slic3r/GUI/SysInfoDialog.cpp              | 20 ++++---
 5 files changed, 58 insertions(+), 64 deletions(-)
 rename src/libslic3r/{LibraryCheck.cpp => BlacklistedLibraryCheck.cpp} (55%)
 rename src/libslic3r/{LibraryCheck.hpp => BlacklistedLibraryCheck.hpp} (50%)

diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp
index 04df43496..b3e6841c9 100644
--- a/src/PrusaSlicer.cpp
+++ b/src/PrusaSlicer.cpp
@@ -49,7 +49,7 @@
 #include "libslic3r/Format/SL1.hpp"
 #include "libslic3r/Utils.hpp"
 #include "libslic3r/Thread.hpp"
-#include "libslic3r/LibraryCheck.hpp"
+#include "libslic3r/BlacklistedLibraryCheck.hpp"
 
 #include "PrusaSlicer.hpp"
 
@@ -622,13 +622,18 @@ bool CLI::setup(int argc, char **argv)
     detect_platform();
 
 #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();
+    // Notify user that a blacklisted DLL was injected into PrusaSlicer process (for example Nahimic, see GH #5573).
+    // We hope that if a DLL is being injected into a PrusaSlicer process, it happens at the very start of the application,
+    // thus we shall detect them now.
+    if (BlacklistedLibraryCheck::get_instance().perform_check()) {
+        std::wstring text = L"Following DLLs have been injected into the PrusaSlicer process:\n\n";
+        text += BlacklistedLibraryCheck::get_instance().get_blacklisted_string();
+        text += L"\n\n"
+                L"PrusaSlicer is known to not run correctly with these DLLs injected. "
+                L"We suggest stopping or uninstalling these services if you experience "
+                L"crashes or unexpected behaviour while using PrusaSlicer.\n"
+                L"For example, ASUS Sonic Studio injects a Nahimic driver, which makes PrusaSlicer "
+                L"to crash on a secondary monitor, see PrusaSlicer github issue #5573";
         MessageBoxW(NULL, text.c_str(), L"Warning"/*L"Incopatible library found"*/, MB_OK);
     }
 #endif
diff --git a/src/libslic3r/LibraryCheck.cpp b/src/libslic3r/BlacklistedLibraryCheck.cpp
similarity index 55%
rename from src/libslic3r/LibraryCheck.cpp
rename to src/libslic3r/BlacklistedLibraryCheck.cpp
index 1c7cbe54a..3d2ee3482 100644
--- a/src/libslic3r/LibraryCheck.cpp
+++ b/src/libslic3r/BlacklistedLibraryCheck.cpp
@@ -1,4 +1,4 @@
-#include "LibraryCheck.hpp"
+#include "BlacklistedLibraryCheck.hpp"
 
 #include <cstdio>
 #include <boost/nowide/convert.hpp>
@@ -12,61 +12,46 @@ namespace Slic3r {
 #ifdef  WIN32
 
 //only dll name with .dll suffix - currently case sensitive
-const std::vector<std::wstring> LibraryCheck::blacklist({ L"NahimicOSD.dll" });
+const std::vector<std::wstring> BlacklistedLibraryCheck::blacklist({ L"NahimicOSD.dll" });
 
-bool LibraryCheck::get_blacklisted(std::vector<std::wstring>& names)
+bool BlacklistedLibraryCheck::get_blacklisted(std::vector<std::wstring>& 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 BlacklistedLibraryCheck::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";
-    }
+        ret += lib + L"\n";
     return ret;
 }
 
-bool LibraryCheck::perform_check()
-{
-    
-    DWORD   processID = GetCurrentProcessId();
-    HMODULE hMods[1024];
-    HANDLE  hProcess;
-    DWORD   cbNeeded;
-    unsigned int i;
-
+bool BlacklistedLibraryCheck::perform_check()
+{   
     // Get a handle to the process.
-    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
-        PROCESS_VM_READ,
-        FALSE, processID);
+    HANDLE  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId());
     if (NULL == hProcess)
         return false;
+
     // Get a list of all the modules in this process.
+    HMODULE hMods[1024];
+    DWORD   cbNeeded;
     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++)
+        for (unsigned int i = 0; i < cbNeeded / sizeof(HMODULE); ++ i)
         {
-            TCHAR szModName[MAX_PATH];
+            wchar_t szModName[MAX_PATH];
             // Get the full path to the module's file.
-            if (GetModuleFileNameEx(hProcess, hMods[i], szModName,
-                sizeof(szModName) / sizeof(TCHAR)))
+            if (GetModuleFileNameExW(hProcess, hMods[i], szModName, MAX_PATH))
             {
                 // Add to list if blacklisted
-                if(LibraryCheck::is_blacklisted(szModName)) {
+                if (BlacklistedLibraryCheck::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);
@@ -79,23 +64,22 @@ bool LibraryCheck::perform_check()
     CloseHandle(hProcess);
     //printf("\n");
     return !m_found.empty();
-    
 }
 
-bool LibraryCheck::is_blacklisted(std::wstring dllpath)
+bool BlacklistedLibraryCheck::is_blacklisted(const 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()) {
+    if (std::find(BlacklistedLibraryCheck::blacklist.begin(), BlacklistedLibraryCheck::blacklist.end(), dllname) != BlacklistedLibraryCheck::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)
+bool BlacklistedLibraryCheck::is_blacklisted(const std::string &dllpath)
 {
-    return LibraryCheck::is_blacklisted(boost::nowide::widen(dllpath));
+    return BlacklistedLibraryCheck::is_blacklisted(boost::nowide::widen(dllpath));
 }
 
 #endif //WIN32
diff --git a/src/libslic3r/LibraryCheck.hpp b/src/libslic3r/BlacklistedLibraryCheck.hpp
similarity index 50%
rename from src/libslic3r/LibraryCheck.hpp
rename to src/libslic3r/BlacklistedLibraryCheck.hpp
index 663bf019e..f0cdee6de 100644
--- a/src/libslic3r/LibraryCheck.hpp
+++ b/src/libslic3r/BlacklistedLibraryCheck.hpp
@@ -1,5 +1,5 @@
-#ifndef slic3r_LibraryCheck_hpp_
-#define slic3r_LibraryCheck_hpp_
+#ifndef slic3r_BlacklistedLibraryCheck_hpp_
+#define slic3r_BlacklistedLibraryCheck_hpp_
 
 #ifdef  WIN32
 #include <windows.h>
@@ -10,30 +10,31 @@
 namespace Slic3r {
 
 #ifdef  WIN32
-class LibraryCheck
+class BlacklistedLibraryCheck
 {
 public:
-    static LibraryCheck& get_instance()
+    static BlacklistedLibraryCheck& get_instance()
     {
-        static LibraryCheck instance; 
+        static BlacklistedLibraryCheck instance; 
                               
         return instance;
     }
 private:
-    LibraryCheck() {}
+    BlacklistedLibraryCheck() = default;
 
     std::vector<std::wstring> m_found;
 public:
-    LibraryCheck(LibraryCheck const&) = delete;
-    void operator=(LibraryCheck const&) = delete;
+    BlacklistedLibraryCheck(BlacklistedLibraryCheck const&) = delete;
+    void operator=(BlacklistedLibraryCheck const&) = delete;
     // returns all found blacklisted dlls
     bool get_blacklisted(std::vector<std::wstring>& 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);
+    // UTF-8 encoded path
+    static bool is_blacklisted(const std::string &dllpath);
+    static bool is_blacklisted(const std::wstring &dllpath);
 private:
     static const std::vector<std::wstring> blacklist;
 };
@@ -42,4 +43,4 @@ private:
 
 } // namespace Slic3r
 
-#endif //slic3r_LibraryCheck_hpp_
\ No newline at end of file
+#endif //slic3r_BlacklistedLibraryCheck_hpp_
diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt
index 83590d601..28865149f 100644
--- a/src/libslic3r/CMakeLists.txt
+++ b/src/libslic3r/CMakeLists.txt
@@ -125,8 +125,8 @@ add_library(libslic3r STATIC
     "${CMAKE_CURRENT_BINARY_DIR}/libslic3r_version.h"
     Line.cpp
     Line.hpp
-    LibraryCheck.cpp
-    LibraryCheck.hpp
+    BlacklistedLibraryCheck.cpp
+    BlacklistedLibraryCheck.hpp
     LocalesUtils.cpp
     LocalesUtils.hpp
     Model.cpp
diff --git a/src/slic3r/GUI/SysInfoDialog.cpp b/src/slic3r/GUI/SysInfoDialog.cpp
index 2b835a96b..b727264b6 100644
--- a/src/slic3r/GUI/SysInfoDialog.cpp
+++ b/src/slic3r/GUI/SysInfoDialog.cpp
@@ -14,7 +14,7 @@
 #include "GUI_App.hpp"
 #include "MainFrame.hpp"
 #include "wxExtensions.hpp"
-#include "../libslic3r/LibraryCheck.hpp"
+#include "../libslic3r/BlacklistedLibraryCheck.hpp"
 
 #ifdef _WIN32
 	// The standard Windows includes.
@@ -142,19 +142,23 @@ SysInfoDialog::SysInfoDialog()
         m_opengl_info_html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit()));
         m_opengl_info_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size);
         m_opengl_info_html->SetBorders(10);
-        const auto text = wxString::Format(
+        wxString blacklisted_libraries_message;
+#ifdef WIN32
+        std::wstring blacklisted_libraries = BlacklistedLibraryCheck::get_instance().get_blacklisted_string().c_str();
+        if (! blacklisted_libraries.empty())
+            blacklisted_libraries_message = wxString("<br><b>") + _L("Blacklisted libraries loaded into PrusaSlicer process:") + "</b><br>" + blacklisted_libraries;
+#endif // WIN32
+       const auto text = GUI::format_wxstr(
             "<html>"
             "<body bgcolor= %s link= %s>"
             "<font color=%s>"
-            "%s"
+            "%s<br>%s<br>%s<br>%s"
             "</font>"
             "</body>"
             "</html>", bgr_clr_str, text_clr_str, text_clr_str,
-            get_mem_info(true) + "<br>" + wxGetApp().get_gl_info(true, true) + "<br>Eigen vectorization supported: " + Eigen::SimdInstructionSetsInUse()
-#ifdef WIN32
-            + "<br><br><b>Blacklisted loaded libraries:</b><br>" + LibraryCheck::get_instance().get_blacklisted_string().c_str()
-#endif
-        );
+            blacklisted_libraries_message,
+            get_mem_info(true), wxGetApp().get_gl_info(true, true),
+            "<b>" + _L("Eigen vectorization supported:") + "</b> " + Eigen::SimdInstructionSetsInUse());
 
         m_opengl_info_html->SetPage(text);
         main_sizer->Add(m_opengl_info_html, 1, wxEXPAND | wxBOTTOM, 15);