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.
This commit is contained in:
Vojtech Bubnik 2021-07-30 15:52:43 +02:00
parent 64c8a6de8f
commit 2f6f1f0e55
5 changed files with 58 additions and 64 deletions

View file

@ -49,7 +49,7 @@
#include "libslic3r/Format/SL1.hpp" #include "libslic3r/Format/SL1.hpp"
#include "libslic3r/Utils.hpp" #include "libslic3r/Utils.hpp"
#include "libslic3r/Thread.hpp" #include "libslic3r/Thread.hpp"
#include "libslic3r/LibraryCheck.hpp" #include "libslic3r/BlacklistedLibraryCheck.hpp"
#include "PrusaSlicer.hpp" #include "PrusaSlicer.hpp"
@ -622,13 +622,18 @@ bool CLI::setup(int argc, char **argv)
detect_platform(); detect_platform();
#ifdef WIN32 #ifdef WIN32
// Notify user if blacklisted library is already loaded (Nahimic) // Notify user that a blacklisted DLL was injected into PrusaSlicer process (for example Nahimic, see GH #5573).
// If there are cases of no reports with blacklisted lib - this check should be performed later. // We hope that if a DLL is being injected into a PrusaSlicer process, it happens at the very start of the application,
// Some libraries are loaded when we load libraries during startup. // thus we shall detect them now.
if (LibraryCheck::get_instance().perform_check()) { if (BlacklistedLibraryCheck::get_instance().perform_check()) {
std::wstring text = L"Following libraries has been detected inside of the PrusaSlicer process." std::wstring text = L"Following DLLs have been injected into the PrusaSlicer process:\n\n";
L" We suggest stopping or uninstalling these services if you experience crashes or unexpected behaviour while using PrusaSlicer.\n\n"; text += BlacklistedLibraryCheck::get_instance().get_blacklisted_string();
text += LibraryCheck::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); MessageBoxW(NULL, text.c_str(), L"Warning"/*L"Incopatible library found"*/, MB_OK);
} }
#endif #endif

View file

@ -1,4 +1,4 @@
#include "LibraryCheck.hpp" #include "BlacklistedLibraryCheck.hpp"
#include <cstdio> #include <cstdio>
#include <boost/nowide/convert.hpp> #include <boost/nowide/convert.hpp>
@ -12,61 +12,46 @@ namespace Slic3r {
#ifdef WIN32 #ifdef WIN32
//only dll name with .dll suffix - currently case sensitive //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()) if (m_found.empty())
return false; return false;
for (const auto& lib : m_found) for (const auto& lib : m_found)
names.emplace_back(lib); names.emplace_back(lib);
return true; return true;
} }
std::wstring LibraryCheck::get_blacklisted_string() std::wstring BlacklistedLibraryCheck::get_blacklisted_string()
{ {
std::wstring ret; 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) for (const auto& lib : m_found)
{ ret += lib + L"\n";
ret += lib;
ret += L"\n";
}
return ret; return ret;
} }
bool LibraryCheck::perform_check() bool BlacklistedLibraryCheck::perform_check()
{ {
DWORD processID = GetCurrentProcessId();
HMODULE hMods[1024];
HANDLE hProcess;
DWORD cbNeeded;
unsigned int i;
// Get a handle to the process. // Get a handle to the process.
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId());
PROCESS_VM_READ,
FALSE, processID);
if (NULL == hProcess) if (NULL == hProcess)
return false; return false;
// Get a list of all the modules in this process. // 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)) if (EnumProcessModulesEx(hProcess, hMods, sizeof(hMods), &cbNeeded, LIST_MODULES_ALL))
{ {
//printf("Total Dlls: %d\n", cbNeeded / sizeof(HMODULE)); //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. // Get the full path to the module's file.
if (GetModuleFileNameEx(hProcess, hMods[i], szModName, if (GetModuleFileNameExW(hProcess, hMods[i], szModName, MAX_PATH))
sizeof(szModName) / sizeof(TCHAR)))
{ {
// Add to list if blacklisted // Add to list if blacklisted
if(LibraryCheck::is_blacklisted(szModName)) { if (BlacklistedLibraryCheck::is_blacklisted(szModName)) {
//wprintf(L"Contains library: %s\n", szModName); //wprintf(L"Contains library: %s\n", szModName);
if (std::find(m_found.begin(), m_found.end(), szModName) == m_found.end()) if (std::find(m_found.begin(), m_found.end(), szModName) == m_found.end())
m_found.emplace_back(szModName); m_found.emplace_back(szModName);
@ -79,23 +64,22 @@ bool LibraryCheck::perform_check()
CloseHandle(hProcess); CloseHandle(hProcess);
//printf("\n"); //printf("\n");
return !m_found.empty(); 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::wstring dllname = boost::filesystem::path(dllpath).filename().wstring();
//std::transform(dllname.begin(), dllname.end(), dllname.begin(), std::tolower); //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()); //std::wprintf(L"%s is blacklisted\n", dllname.c_str());
return true; return true;
} }
//std::wprintf(L"%s is NOT blacklisted\n", dllname.c_str()); //std::wprintf(L"%s is NOT blacklisted\n", dllname.c_str());
return false; 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 #endif //WIN32

View file

@ -1,5 +1,5 @@
#ifndef slic3r_LibraryCheck_hpp_ #ifndef slic3r_BlacklistedLibraryCheck_hpp_
#define slic3r_LibraryCheck_hpp_ #define slic3r_BlacklistedLibraryCheck_hpp_
#ifdef WIN32 #ifdef WIN32
#include <windows.h> #include <windows.h>
@ -10,30 +10,31 @@
namespace Slic3r { namespace Slic3r {
#ifdef WIN32 #ifdef WIN32
class LibraryCheck class BlacklistedLibraryCheck
{ {
public: public:
static LibraryCheck& get_instance() static BlacklistedLibraryCheck& get_instance()
{ {
static LibraryCheck instance; static BlacklistedLibraryCheck instance;
return instance; return instance;
} }
private: private:
LibraryCheck() {} BlacklistedLibraryCheck() = default;
std::vector<std::wstring> m_found; std::vector<std::wstring> m_found;
public: public:
LibraryCheck(LibraryCheck const&) = delete; BlacklistedLibraryCheck(BlacklistedLibraryCheck const&) = delete;
void operator=(LibraryCheck const&) = delete; void operator=(BlacklistedLibraryCheck const&) = delete;
// returns all found blacklisted dlls // returns all found blacklisted dlls
bool get_blacklisted(std::vector<std::wstring>& names); bool get_blacklisted(std::vector<std::wstring>& names);
std::wstring get_blacklisted_string(); std::wstring get_blacklisted_string();
// returns true if enumerating found blacklisted dll // returns true if enumerating found blacklisted dll
bool perform_check(); bool perform_check();
static bool is_blacklisted(std::string dllpath); // UTF-8 encoded path
static bool is_blacklisted(std::wstring dllpath); static bool is_blacklisted(const std::string &dllpath);
static bool is_blacklisted(const std::wstring &dllpath);
private: private:
static const std::vector<std::wstring> blacklist; static const std::vector<std::wstring> blacklist;
}; };
@ -42,4 +43,4 @@ private:
} // namespace Slic3r } // namespace Slic3r
#endif //slic3r_LibraryCheck_hpp_ #endif //slic3r_BlacklistedLibraryCheck_hpp_

View file

@ -125,8 +125,8 @@ add_library(libslic3r STATIC
"${CMAKE_CURRENT_BINARY_DIR}/libslic3r_version.h" "${CMAKE_CURRENT_BINARY_DIR}/libslic3r_version.h"
Line.cpp Line.cpp
Line.hpp Line.hpp
LibraryCheck.cpp BlacklistedLibraryCheck.cpp
LibraryCheck.hpp BlacklistedLibraryCheck.hpp
LocalesUtils.cpp LocalesUtils.cpp
LocalesUtils.hpp LocalesUtils.hpp
Model.cpp Model.cpp

View file

@ -14,7 +14,7 @@
#include "GUI_App.hpp" #include "GUI_App.hpp"
#include "MainFrame.hpp" #include "MainFrame.hpp"
#include "wxExtensions.hpp" #include "wxExtensions.hpp"
#include "../libslic3r/LibraryCheck.hpp" #include "../libslic3r/BlacklistedLibraryCheck.hpp"
#ifdef _WIN32 #ifdef _WIN32
// The standard Windows includes. // 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->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit()));
m_opengl_info_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size); m_opengl_info_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size);
m_opengl_info_html->SetBorders(10); 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>" "<html>"
"<body bgcolor= %s link= %s>" "<body bgcolor= %s link= %s>"
"<font color=%s>" "<font color=%s>"
"%s" "%s<br>%s<br>%s<br>%s"
"</font>" "</font>"
"</body>" "</body>"
"</html>", bgr_clr_str, text_clr_str, text_clr_str, "</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() blacklisted_libraries_message,
#ifdef WIN32 get_mem_info(true), wxGetApp().get_gl_info(true, true),
+ "<br><br><b>Blacklisted loaded libraries:</b><br>" + LibraryCheck::get_instance().get_blacklisted_string().c_str() "<b>" + _L("Eigen vectorization supported:") + "</b> " + Eigen::SimdInstructionSetsInUse());
#endif
);
m_opengl_info_html->SetPage(text); m_opengl_info_html->SetPage(text);
main_sizer->Add(m_opengl_info_html, 1, wxEXPAND | wxBOTTOM, 15); main_sizer->Add(m_opengl_info_html, 1, wxEXPAND | wxBOTTOM, 15);