mirror of
https://github.com/HIllya51/LunaHook.git
synced 2024-12-24 04:04:14 +08:00
everyone
This reverts commit 975f049797bcd6b9de0e11f9a926d5ac3ec79ef8. 1 1 Revert "Update QtLoader_inline.cpp" This reverts commit 372dd2dc3e2f23c810f13e51437904fac1422c04. Update QtLoader_inline.cpp Update QtLoader_inline.cpp 1 1 1 Update CMakeLists.txt 1 1
This commit is contained in:
parent
b0fcc4cd72
commit
c94547bbc9
@ -68,8 +68,7 @@
|
||||
#define MenuPluginRankDown L"Down"
|
||||
#define MenuPluginEnable L"Enable"
|
||||
#define DefaultFont L"Arial"
|
||||
#define LblPluginNotify L"Qt Plugins Will be Loaded at Start Only."
|
||||
#define LblPluginRemove L"Remove Plugins Will be Useful after Restart."
|
||||
#define CantLoadQtLoader L"Can't Load QtLoader.dll"
|
||||
#define InvalidPlugin L"Invalid Plugin!"
|
||||
#define InvalidDll L"Invalid Dll!"
|
||||
#define InvalidDump L"Dumplicated!"
|
||||
|
@ -68,8 +68,7 @@
|
||||
#define MenuPluginRankDown L"下移"
|
||||
#define MenuPluginEnable L"使用"
|
||||
#define DefaultFont L"微软雅黑"
|
||||
#define LblPluginNotify L"依赖于Qt的插件仅会在启动时载入。"
|
||||
#define LblPluginRemove L"移除插件要在重启后生效。"
|
||||
#define CantLoadQtLoader L"无法加载QtLoader.dll"
|
||||
#define InvalidPlugin L"插件无效!"
|
||||
#define InvalidDll L"Dll无效!"
|
||||
#define InvalidDump L"重复!"
|
||||
|
@ -1,4 +1,4 @@
|
||||
add_executable(LunaHost WIN32 confighelper.cpp controls.cpp main.cpp processlistwindow.cpp LunaHost.cpp window.cpp luna.rc pluginmanager.cpp Plugin/pluginexample.cpp QtLoader.cpp app.manifest)
|
||||
add_executable(LunaHost WIN32 confighelper.cpp controls.cpp main.cpp processlistwindow.cpp LunaHost.cpp window.cpp luna.rc pluginmanager.cpp Plugin/pluginexample.cpp QtLoader_inline.cpp app.manifest)
|
||||
target_precompile_headers(LunaHost REUSE_FROM pch)
|
||||
set_target_properties(LunaHost PROPERTIES OUTPUT_NAME "LunaHost${bitappendix}")
|
||||
target_link_libraries(LunaHost comctl32 pch host ${YY_Thunks_for_WinXP})
|
||||
|
@ -394,7 +394,7 @@ Settingwindow::Settingwindow(LunaHost* host):mainwindow(host){
|
||||
settext(WndSetting);
|
||||
}
|
||||
void Pluginwindow::on_size(int w,int h){
|
||||
listplugins->setgeo(10,80,w-20,h-90);
|
||||
listplugins->setgeo(10,10,w-20,h-20);
|
||||
}
|
||||
void Pluginwindow::pluginrankmove(int moveoffset){
|
||||
auto idx=listplugins->currentidx();
|
||||
@ -412,8 +412,7 @@ void Pluginwindow::pluginrankmove(int moveoffset){
|
||||
listplugins->setdata(b,(LONG_PTR)pa);
|
||||
}
|
||||
Pluginwindow::Pluginwindow(mainwindow*p,Pluginmanager* pl):mainwindow(p),pluginmanager(pl){
|
||||
(new label(this,LblPluginNotify))->setgeo(10,10,500,30);
|
||||
(new label(this,LblPluginRemove))->setgeo( 10,40,500,30);
|
||||
|
||||
static auto listadd=[&](const std::wstring& s){
|
||||
auto idx=listplugins->additem(std::filesystem::path(s).stem());
|
||||
auto _s=new wchar_t[s.size()+1];wcscpy(_s,s.c_str());
|
||||
@ -443,7 +442,7 @@ Pluginwindow::Pluginwindow(mainwindow*p,Pluginmanager* pl):mainwindow(p),pluginm
|
||||
if(idx!=-1)
|
||||
{
|
||||
menu.add(MenuRemovePlugin,[&,idx](){
|
||||
pluginmanager->remove((LPCWSTR)listplugins->getdata(idx));
|
||||
pluginmanager->remove((LPCWSTR)listplugins->getdata(idx),false);
|
||||
listplugins->deleteitem(idx);
|
||||
});
|
||||
menu.add_sep();
|
||||
@ -452,6 +451,10 @@ Pluginwindow::Pluginwindow(mainwindow*p,Pluginmanager* pl):mainwindow(p),pluginm
|
||||
menu.add_sep();
|
||||
menu.add_checkable(MenuPluginEnable,pluginmanager->getenable(idx),[&,idx](bool check){
|
||||
pluginmanager->setenable(idx,check);
|
||||
if(check)
|
||||
pluginmanager->addplugin((LPCWSTR)listplugins->getdata(idx),true);
|
||||
else
|
||||
pluginmanager->remove((LPCWSTR)listplugins->getdata(idx),true);
|
||||
});
|
||||
}
|
||||
return menu;
|
||||
|
@ -5,15 +5,15 @@ set_target_properties(ToClipboard PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_L
|
||||
endif()
|
||||
|
||||
if(0)
|
||||
include(QtUtils.cmake)
|
||||
msvc_registry_search()
|
||||
if(Qt5_DIR)
|
||||
find_qt5(Core Widgets)
|
||||
#set(CMAKE_AUTOMOC ON)
|
||||
add_library(QtLoader MODULE QtLoader.cpp)
|
||||
#qt5_wrap_cpp(MOC_SOURCES QtLoader.h)
|
||||
#target_sources(QtLoader PRIVATE ${MOC_SOURCES})
|
||||
target_link_libraries(QtLoader Qt5::Widgets Qt5::Core)
|
||||
set_target_properties(QtLoader PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/plugin${bitappendix}")
|
||||
endif()
|
||||
include(QtUtils.cmake)
|
||||
msvc_registry_search()
|
||||
if(Qt5_DIR)
|
||||
find_qt5(Core Widgets)
|
||||
#set(CMAKE_AUTOMOC ON)
|
||||
add_library(QtLoader MODULE QtLoader.cpp)
|
||||
#qt5_wrap_cpp(MOC_SOURCES QtLoader.h)
|
||||
#target_sources(QtLoader PRIVATE ${MOC_SOURCES})
|
||||
target_link_libraries(QtLoader Qt5::Widgets Qt5::Core)
|
||||
set_target_properties(QtLoader PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/plugin${bitappendix}")
|
||||
endif()
|
||||
endif()
|
72
LunaHost/GUI/Plugin/QtLoader.cpp
Normal file
72
LunaHost/GUI/Plugin/QtLoader.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
#include<Windows.h>
|
||||
#include<QApplication>
|
||||
#include<QFont>
|
||||
#include<QDir>
|
||||
#include<thread>
|
||||
#include<queue>
|
||||
#include<mutex>
|
||||
#include<Shlwapi.h>
|
||||
#include<filesystem>
|
||||
#include"../lockedqueue.hpp"
|
||||
|
||||
lockedqueue<std::wstring>waitingtask;
|
||||
lockedqueue<HMODULE>waitingresult;
|
||||
|
||||
extern "C" __declspec(dllexport) int QtStartUp(std::vector<std::wstring>* dlls){
|
||||
static bool once=false;
|
||||
if(once)return 0;
|
||||
once=true;
|
||||
std::thread([=](){
|
||||
for(int i=0;i<dlls->size();i++)
|
||||
QApplication::addLibraryPath(QString::fromStdWString(std::filesystem::path(dlls->at(i)).parent_path()));
|
||||
|
||||
int _=0;
|
||||
QApplication app(_, nullptr);
|
||||
app.setFont(QFont("MS Shell Dlg 2", 10));
|
||||
|
||||
while(true)
|
||||
{
|
||||
if(!waitingtask.empty())
|
||||
{
|
||||
auto top=waitingtask.pop();
|
||||
waitingresult.push(LoadLibraryW(top.c_str()));
|
||||
}
|
||||
app.processEvents(0);
|
||||
}
|
||||
|
||||
}).detach();
|
||||
return 0;
|
||||
}
|
||||
std::mutex loadmutex;
|
||||
|
||||
extern "C" __declspec(dllexport) std::vector<HMODULE>* QtLoadLibraryBatch(std::vector<std::wstring>* dlls){
|
||||
std::lock_guard _(loadmutex);
|
||||
static auto once=QtStartUp(dlls);
|
||||
auto hdlls=new std::vector<HMODULE>;
|
||||
for(int i=0;i<dlls->size();i++){
|
||||
waitingtask.push(dlls->at(i));
|
||||
hdlls->push_back(waitingresult.pop());
|
||||
}
|
||||
return hdlls;
|
||||
}
|
||||
#if 0
|
||||
extern "C" __declspec(dllexport) std::vector<HMODULE>* QtLoadLibrary(std::vector<std::wstring>* dlls){
|
||||
auto hdlls=new std::vector<HMODULE>;
|
||||
auto mutex=CreateSemaphoreW(0,0,1,0);
|
||||
std::thread([=](){
|
||||
for(int i=0;i<dlls->size();i++)
|
||||
QApplication::addLibraryPath(QString::fromStdWString(std::filesystem::path(dlls->at(i)).parent_path()));
|
||||
|
||||
int _=0;
|
||||
QApplication app(_, nullptr);
|
||||
app.setFont(QFont("MS Shell Dlg 2", 10));
|
||||
for(int i=0;i<dlls->size();i++)
|
||||
hdlls->push_back(LoadLibraryW(dlls->at(i).c_str()));
|
||||
ReleaseSemaphore(mutex,1,0);
|
||||
app.exec();
|
||||
|
||||
}).detach();
|
||||
WaitForSingleObject(mutex,INFINITE);
|
||||
return hdlls;
|
||||
}
|
||||
#endif
|
@ -1,89 +0,0 @@
|
||||
#include<Windows.h>
|
||||
#include<thread>
|
||||
#include<mutex>
|
||||
#include<Shlwapi.h>
|
||||
#include<filesystem>
|
||||
|
||||
|
||||
#ifndef _WIN64
|
||||
#define THISCALL __thiscall
|
||||
#define _CDECL __cdecl
|
||||
#define fnQString_fromStdWString "?fromStdWString@QString@@SA?AV1@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z"
|
||||
#define fnQCoreApplication_addLibraryPath "?addLibraryPath@QCoreApplication@@SAXABVQString@@@Z"
|
||||
#define fnQString_dtor "??1QString@@QAE@XZ"
|
||||
#define fnQApplication_ctor "??0QApplication@@QAE@AAHPAPADH@Z"
|
||||
#define fnQFont_ctor "??0QFont@@QAE@ABVQString@@HH_N@Z"
|
||||
#define fnQApplication_setFont "?setFont@QApplication@@SAXABVQFont@@PBD@Z"
|
||||
#define fnQFont_dtor "??1QFont@@QAE@XZ"
|
||||
#define fnQApplication_exec "?exec@QApplication@@SAHXZ"
|
||||
#define fnQApplication_dtor "??1QApplication@@UAE@XZ"
|
||||
#else
|
||||
#define THISCALL __fastcall
|
||||
#define _CDECL __fastcall
|
||||
#define fnQString_fromStdWString "?fromStdWString@QString@@SA?AV1@AEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z"
|
||||
#define fnQCoreApplication_addLibraryPath "?addLibraryPath@QCoreApplication@@SAXAEBVQString@@@Z"
|
||||
#define fnQString_dtor "??1QString@@QEAA@XZ"
|
||||
#define fnQApplication_ctor "??0QApplication@@QEAA@AEAHPEAPEADH@Z"
|
||||
#define fnQFont_ctor "??0QFont@@QEAA@AEBVQString@@HH_N@Z"
|
||||
#define fnQApplication_setFont "?setFont@QApplication@@SAXAEBVQFont@@PEBD@Z"
|
||||
#define fnQFont_dtor "??1QFont@@QEAA@XZ"
|
||||
#define fnQApplication_exec "?exec@QApplication@@SAHXZ"
|
||||
#define fnQApplication_dtor "??1QApplication@@UEAA@XZ"
|
||||
#endif
|
||||
|
||||
extern "C" __declspec(dllexport) std::vector<HMODULE>* QtLoadLibrary(std::vector<std::wstring>* dlls){
|
||||
|
||||
auto Qt5Widgets=LoadLibrary(L"Qt5Widgets.dll");
|
||||
auto Qt5Gui=LoadLibrary(L"Qt5Gui.dll");
|
||||
auto Qt5Core=LoadLibrary(L"Qt5Core.dll");
|
||||
if(Qt5Core==0||Qt5Gui==0||Qt5Widgets==0)return new std::vector<HMODULE>{};
|
||||
|
||||
auto QString_fromStdWString=GetProcAddress(Qt5Core,fnQString_fromStdWString);
|
||||
auto QCoreApplication_addLibraryPath=GetProcAddress(Qt5Core,fnQCoreApplication_addLibraryPath);
|
||||
auto QString_dtor=GetProcAddress(Qt5Core,fnQString_dtor);
|
||||
auto QApplication_ctor=GetProcAddress(Qt5Widgets,fnQApplication_ctor);
|
||||
auto QFont_ctor=GetProcAddress(Qt5Gui,fnQFont_ctor);
|
||||
auto QFont_dtor=GetProcAddress(Qt5Gui,fnQFont_dtor);
|
||||
auto QApplication_setFont=GetProcAddress(Qt5Widgets,fnQApplication_setFont);
|
||||
auto QApplication_exec=GetProcAddress(Qt5Widgets,fnQApplication_exec);
|
||||
auto QApplication_dtor=GetProcAddress(Qt5Widgets,fnQApplication_dtor);
|
||||
|
||||
if(QString_fromStdWString==0||QCoreApplication_addLibraryPath==0||QString_dtor==0||QApplication_ctor==0||QFont_ctor==0||QFont_dtor==0||QApplication_setFont==0||QApplication_exec==0||QApplication_dtor==0)return {};
|
||||
auto hdlls=new std::vector<HMODULE>;
|
||||
auto mutex=CreateSemaphoreW(0,0,1,0);
|
||||
std::thread([=](){
|
||||
static void* qapp; //必须static
|
||||
void* qstring;
|
||||
void* qfont;
|
||||
for(int i=0;i<dlls->size();i++){
|
||||
auto dirname=std::filesystem::path(dlls->at(i)).parent_path().wstring();
|
||||
((void* (_CDECL*)(void*,void*))QString_fromStdWString)(&qstring,&dirname);
|
||||
((void(_CDECL *)(void*))QCoreApplication_addLibraryPath)(&qstring);
|
||||
((void(THISCALL*)(void*))QString_dtor)(&qstring);
|
||||
//QCoreApplication_addLibraryPath(QString_fromStdWString(std::filesystem::path(collectQtplugs[i]).parent_path()));
|
||||
}
|
||||
|
||||
int _=0;
|
||||
((void*(THISCALL*)(void*,int*,char**,int))QApplication_ctor)(&qapp,&_,0,331266);
|
||||
|
||||
std::wstring font=L"MS Shell Dlg 2";
|
||||
((void* (_CDECL*)(void*,void*))QString_fromStdWString)(&qstring,&font);
|
||||
((void*(THISCALL*)(void*,void*,int,int,bool))QFont_ctor)(&qfont,&qstring,10,-1,0);
|
||||
((void(_CDECL*)(void*,void*))QApplication_setFont)(&qfont,0);
|
||||
((void(THISCALL*)(void*))QFont_dtor)(&qfont);
|
||||
((void(THISCALL*)(void*))QString_dtor)(&qstring);
|
||||
for(int i=0;i<dlls->size();i++){
|
||||
hdlls->push_back(LoadLibrary(dlls->at(i).c_str()));
|
||||
}
|
||||
ReleaseSemaphore(mutex,1,0);
|
||||
|
||||
((void(*)())QApplication_exec)();
|
||||
|
||||
((void(THISCALL*)(void*))QApplication_dtor)(&qapp);
|
||||
|
||||
|
||||
}).detach();
|
||||
WaitForSingleObject(mutex,INFINITE);
|
||||
|
||||
return hdlls;
|
||||
}
|
141
LunaHost/GUI/QtLoader_inline.cpp
Normal file
141
LunaHost/GUI/QtLoader_inline.cpp
Normal file
@ -0,0 +1,141 @@
|
||||
#include<Windows.h>
|
||||
#include<thread>
|
||||
#include<mutex>
|
||||
#include<Shlwapi.h>
|
||||
#include<filesystem>
|
||||
#include<queue>
|
||||
#include"pluginmanager.h"
|
||||
#include"lockedqueue.hpp"
|
||||
#ifndef _WIN64
|
||||
#define THISCALL __thiscall
|
||||
#define _CDECL __cdecl
|
||||
#define fnQString_fromStdWString "?fromStdWString@QString@@SA?AV1@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z"
|
||||
#define fnQCoreApplication_addLibraryPath "?addLibraryPath@QCoreApplication@@SAXABVQString@@@Z"
|
||||
#define fnQString_dtor "??1QString@@QAE@XZ"
|
||||
#define fnQApplication_ctor "??0QApplication@@QAE@AAHPAPADH@Z"
|
||||
#define fnQFont_ctor "??0QFont@@QAE@ABVQString@@HH_N@Z"
|
||||
#define fnQApplication_setFont "?setFont@QApplication@@SAXABVQFont@@PBD@Z"
|
||||
#define fnQFont_dtor "??1QFont@@QAE@XZ"
|
||||
#define fnQApplication_exec "?exec@QApplication@@SAHXZ"
|
||||
#define fnQApplication_dtor "??1QApplication@@UAE@XZ"
|
||||
#else
|
||||
#define THISCALL __fastcall
|
||||
#define _CDECL __fastcall
|
||||
#define fnQString_fromStdWString "?fromStdWString@QString@@SA?AV1@AEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z"
|
||||
#define fnQCoreApplication_addLibraryPath "?addLibraryPath@QCoreApplication@@SAXAEBVQString@@@Z"
|
||||
#define fnQString_dtor "??1QString@@QEAA@XZ"
|
||||
#define fnQApplication_ctor "??0QApplication@@QEAA@AEAHPEAPEADH@Z"
|
||||
#define fnQFont_ctor "??0QFont@@QEAA@AEBVQString@@HH_N@Z"
|
||||
#define fnQApplication_setFont "?setFont@QApplication@@SAXAEBVQFont@@PEBD@Z"
|
||||
#define fnQFont_dtor "??1QFont@@QEAA@XZ"
|
||||
#define fnQApplication_exec "?exec@QApplication@@SAHXZ"
|
||||
#define fnQApplication_dtor "??1QApplication@@UEAA@XZ"
|
||||
#endif
|
||||
#define fnQApplication_processEvents "?processEvents@QCoreApplication@@SAXV?$QFlags@W4ProcessEventsFlag@QEventLoop@@@@@Z"
|
||||
|
||||
|
||||
FARPROC QString_fromStdWString,QCoreApplication_addLibraryPath,QString_dtor,QApplication_ctor,QFont_ctor,QFont_dtor,QApplication_setFont,QApplication_exec,QApplication_dtor,QApplication_processEvents;
|
||||
|
||||
|
||||
bool checkqterror(){
|
||||
return QString_fromStdWString==0||QCoreApplication_addLibraryPath==0||QString_dtor==0||QApplication_ctor==0||QFont_ctor==0||QFont_dtor==0||QApplication_setFont==0||QApplication_exec==0||QApplication_dtor==0||QApplication_processEvents==0;
|
||||
}
|
||||
int loadqtdlls(){
|
||||
QString_fromStdWString=QCoreApplication_addLibraryPath=QString_dtor=QApplication_ctor=QFont_ctor=QFont_dtor=QApplication_setFont=QApplication_exec=QApplication_dtor=QApplication_processEvents=0;
|
||||
|
||||
auto Qt5Widgets=LoadLibrary(L"Qt5Widgets.dll");
|
||||
auto Qt5Gui=LoadLibrary(L"Qt5Gui.dll");
|
||||
auto Qt5Core=LoadLibrary(L"Qt5Core.dll");
|
||||
if(Qt5Core==0||Qt5Gui==0||Qt5Widgets==0)return 0;
|
||||
|
||||
QString_fromStdWString=GetProcAddress(Qt5Core,fnQString_fromStdWString);
|
||||
QCoreApplication_addLibraryPath=GetProcAddress(Qt5Core,fnQCoreApplication_addLibraryPath);
|
||||
QString_dtor=GetProcAddress(Qt5Core,fnQString_dtor);
|
||||
QApplication_ctor=GetProcAddress(Qt5Widgets,fnQApplication_ctor);
|
||||
QFont_ctor=GetProcAddress(Qt5Gui,fnQFont_ctor);
|
||||
QFont_dtor=GetProcAddress(Qt5Gui,fnQFont_dtor);
|
||||
QApplication_setFont=GetProcAddress(Qt5Widgets,fnQApplication_setFont);
|
||||
QApplication_exec=GetProcAddress(Qt5Widgets,fnQApplication_exec);
|
||||
QApplication_dtor=GetProcAddress(Qt5Widgets,fnQApplication_dtor);
|
||||
QApplication_processEvents=GetProcAddress(Qt5Core,fnQApplication_processEvents);
|
||||
return 0;
|
||||
}
|
||||
struct info{
|
||||
int type;
|
||||
std::wstring dll;
|
||||
HMODULE hdll;
|
||||
};
|
||||
lockedqueue<info>waitingtask;
|
||||
lockedqueue<HMODULE>waitingresult;
|
||||
|
||||
extern "C" __declspec(dllexport) int QtStartUp(std::vector<std::wstring>* dlls){
|
||||
static bool once=false;
|
||||
if(once)return 0;
|
||||
once=true;
|
||||
|
||||
static auto once1=loadqtdlls();
|
||||
if(checkqterror())return 0;
|
||||
std::thread([=](){
|
||||
static void* qapp; //必须static
|
||||
void* qstring;
|
||||
void* qfont;
|
||||
for(int i=0;i<dlls->size();i++){
|
||||
auto dirname=std::filesystem::path(dlls->at(i)).parent_path().wstring();
|
||||
((void* (_CDECL*)(void*,void*))QString_fromStdWString)(&qstring,&dirname);
|
||||
((void(_CDECL *)(void*))QCoreApplication_addLibraryPath)(&qstring);
|
||||
((void(THISCALL*)(void*))QString_dtor)(&qstring);
|
||||
//QCoreApplication_addLibraryPath(QString_fromStdWString(std::filesystem::path(collectQtplugs[i]).parent_path()));
|
||||
}
|
||||
|
||||
int _=0;
|
||||
((void*(THISCALL*)(void*,int*,char**,int))QApplication_ctor)(&qapp,&_,0,331266);
|
||||
|
||||
std::wstring font=L"MS Shell Dlg 2";
|
||||
((void* (_CDECL*)(void*,void*))QString_fromStdWString)(&qstring,&font);
|
||||
((void*(THISCALL*)(void*,void*,int,int,bool))QFont_ctor)(&qfont,&qstring,10,-1,0);
|
||||
((void(_CDECL*)(void*,void*))QApplication_setFont)(&qfont,0);
|
||||
((void(THISCALL*)(void*))QFont_dtor)(&qfont);
|
||||
((void(THISCALL*)(void*))QString_dtor)(&qstring);
|
||||
|
||||
while(true)
|
||||
{
|
||||
if(!waitingtask.empty())
|
||||
{
|
||||
auto top=waitingtask.pop();
|
||||
if(top.type==1)
|
||||
{
|
||||
waitingresult.push(LoadLibraryW(top.dll.c_str()));
|
||||
}
|
||||
else if(top.type==2)
|
||||
{
|
||||
FreeLibrary(top.hdll);
|
||||
}
|
||||
}
|
||||
((void(_CDECL*)(DWORD))QApplication_processEvents)(0);
|
||||
}
|
||||
|
||||
// ((void(*)())QApplication_exec)();
|
||||
|
||||
// ((void(THISCALL*)(void*))QApplication_dtor)(&qapp);
|
||||
|
||||
}).detach();
|
||||
return 0;
|
||||
}
|
||||
std::mutex loadmutex;
|
||||
|
||||
extern "C" __declspec(dllexport) std::vector<HMODULE>* QtLoadLibraryBatch(std::vector<std::wstring>* dlls){
|
||||
std::lock_guard _(loadmutex);
|
||||
static auto once=QtStartUp(dlls);
|
||||
auto hdlls=new std::vector<HMODULE>;
|
||||
for(int i=0;i<dlls->size();i++){
|
||||
waitingtask.push({1,dlls->at(i)});
|
||||
hdlls->push_back(waitingresult.pop());
|
||||
}
|
||||
return hdlls;
|
||||
}
|
||||
|
||||
|
||||
extern "C" __declspec(dllexport) void QtFreeLibrary(HMODULE hd){
|
||||
std::lock_guard _(loadmutex);
|
||||
waitingtask.push({2,L"",hd});
|
||||
}
|
29
LunaHost/GUI/lockedqueue.hpp
Normal file
29
LunaHost/GUI/lockedqueue.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
template<class T>
|
||||
class lockedqueue{
|
||||
std::mutex lock;
|
||||
std::queue<T>data;
|
||||
HANDLE hsema;
|
||||
public:
|
||||
lockedqueue(){
|
||||
hsema=CreateSemaphore(NULL,0,65535,NULL);
|
||||
}
|
||||
~lockedqueue(){
|
||||
CloseHandle(hsema);
|
||||
}
|
||||
void push(T _){
|
||||
std::lock_guard _l(lock);
|
||||
data.push(std::move(_));
|
||||
ReleaseSemaphore(hsema,1,NULL);
|
||||
}
|
||||
T pop(){
|
||||
WaitForSingleObject(hsema,INFINITE);
|
||||
std::lock_guard _l(lock);
|
||||
auto _=data.front();
|
||||
data.pop();
|
||||
return _;
|
||||
}
|
||||
bool empty(){
|
||||
std::lock_guard _l(lock);
|
||||
return data.empty();
|
||||
}
|
||||
};
|
@ -25,33 +25,51 @@ std::optional<std::wstring>SelectFile(HWND hwnd,LPCWSTR lpstrFilter){
|
||||
}
|
||||
else return {};
|
||||
}
|
||||
|
||||
typedef std::vector<HMODULE>*(* QtLoadLibrary_t)(std::vector<std::wstring>* dlls);
|
||||
|
||||
void Pluginmanager::loadqtdlls(std::vector<std::wstring>&collectQtplugs){
|
||||
if(collectQtplugs.size()==0)return;
|
||||
auto pluginpath=std::filesystem::current_path()/(x64?"plugin64":"plugin32");
|
||||
wchar_t env[65535];
|
||||
GetEnvironmentVariableW(L"PATH",env,65535);
|
||||
auto envs=std::wstring(env);
|
||||
envs+=L";";envs+=pluginpath;
|
||||
for(auto&p:collectQtplugs){
|
||||
envs+=L";";envs+=std::filesystem::path(p).parent_path();
|
||||
typedef std::vector<HMODULE>* (*QtLoadLibrary_t)(std::vector<std::wstring>* dlls);
|
||||
typedef std::vector<HMODULE>* (*QtLoadLibraryBatch_t)(std::vector<std::wstring>* dlls);
|
||||
typedef void (*QtFreeLibrary_t)(HMODULE hd);
|
||||
void tryaddqttoenv(std::vector<std::wstring>&collectQtplugs){
|
||||
static HMODULE qt5core=0;
|
||||
if(qt5core==0)
|
||||
{
|
||||
auto pluginpath=std::filesystem::current_path()/(x64?"plugin64":"plugin32");
|
||||
wchar_t env[65535];
|
||||
GetEnvironmentVariableW(L"PATH",env,65535);
|
||||
auto envs=std::wstring(env);
|
||||
for(auto&p:collectQtplugs){
|
||||
envs+=L";";envs+=std::filesystem::path(p).parent_path();
|
||||
}
|
||||
SetEnvironmentVariableW(L"PATH",envs.c_str());
|
||||
qt5core= LoadLibrary(L"Qt5Core.dll");
|
||||
}
|
||||
|
||||
SetEnvironmentVariableW(L"PATH",envs.c_str());
|
||||
|
||||
auto QtLoadLibrary = (QtLoadLibrary_t)GetProcAddress(GetModuleHandle(0), "QtLoadLibrary");
|
||||
}
|
||||
std::vector<HMODULE>loadqtdllsX(std::vector<std::wstring>&collectQtplugs){
|
||||
if(collectQtplugs.empty())return {};
|
||||
tryaddqttoenv(collectQtplugs);
|
||||
#if 1
|
||||
HMODULE base=GetModuleHandle(0);
|
||||
#else
|
||||
HMODULE base=LoadLibrary((std::filesystem::current_path()/(x64?"plugin64":"plugin32")/"QtLoader.dll").wstring().c_str());
|
||||
#endif
|
||||
|
||||
//auto QtLoadLibrary = (QtLoadLibrary_t)GetProcAddress(base, "QtLoadLibrary");
|
||||
auto QtLoadLibrary = (QtLoadLibrary_t)GetProcAddress(base, "QtLoadLibraryBatch");
|
||||
|
||||
auto modules=QtLoadLibrary(&collectQtplugs);
|
||||
|
||||
if(modules->empty())return;
|
||||
|
||||
for(int i=0;i<collectQtplugs.size();i++){
|
||||
OnNewSentenceS[collectQtplugs[i]]=GetProcAddress(modules->at(i),"OnNewSentence");
|
||||
}
|
||||
|
||||
|
||||
std::vector<HMODULE> _{*modules};
|
||||
delete modules;
|
||||
return _;
|
||||
}
|
||||
HMODULE loadqtdllsX(const std::wstring&collectQtplugs){
|
||||
std::vector<std::wstring> _ {collectQtplugs};
|
||||
return loadqtdllsX(_)[0];
|
||||
}
|
||||
void Pluginmanager::loadqtdlls(std::vector<std::wstring>&collectQtplugs){
|
||||
auto modules=loadqtdllsX(collectQtplugs);
|
||||
for(int i=0;i<collectQtplugs.size();i++){
|
||||
OnNewSentenceS[collectQtplugs[i]]={true,GetProcAddress(modules[i],"OnNewSentence"),modules[i]};
|
||||
}
|
||||
}
|
||||
Pluginmanager::Pluginmanager(LunaHost* _host):host(_host),configs(_host->configs){
|
||||
try {
|
||||
@ -62,17 +80,19 @@ Pluginmanager::Pluginmanager(LunaHost* _host):host(_host),configs(_host->configs
|
||||
auto plg=get(i);
|
||||
bool isqt=plg.isQt;
|
||||
auto path=plg.wpath();
|
||||
OnNewSentenceS[path]=0;
|
||||
OnNewSentenceS[path]={false,0,0};
|
||||
if(isqt){
|
||||
if(plg.enable==false)continue;
|
||||
collectQtplugs.push_back((path));
|
||||
}
|
||||
else
|
||||
OnNewSentenceS[path]=GetProcAddress(LoadLibraryW(path.c_str()),"OnNewSentence");
|
||||
else{
|
||||
auto base=LoadLibraryW(path.c_str());
|
||||
OnNewSentenceS[path]={false,GetProcAddress(base,"OnNewSentence"),base};
|
||||
}
|
||||
}
|
||||
loadqtdlls(collectQtplugs);
|
||||
|
||||
OnNewSentenceS[L"InternalClipBoard"]=GetProcAddress(GetModuleHandle(0),"OnNewSentence");//内部链接的剪贴板插件
|
||||
OnNewSentenceS[L"InternalClipBoard"]={false,GetProcAddress(GetModuleHandle(0),"OnNewSentence"),GetModuleHandle(0)};//内部链接的剪贴板插件
|
||||
|
||||
|
||||
} catch (const std::exception& ex) {
|
||||
@ -94,7 +114,7 @@ bool Pluginmanager::dispatch(TextThread& thread, std::wstring& sentence){
|
||||
path=getname(i);
|
||||
}
|
||||
|
||||
auto funptr=OnNewSentenceS[path];
|
||||
auto funptr=OnNewSentenceS[path].funcptr;
|
||||
if(funptr==0)continue;
|
||||
if (!*(sentenceBuffer = ((OnNewSentence_t)funptr)(sentenceBuffer, sentenceInfo)))
|
||||
break;
|
||||
@ -105,15 +125,6 @@ bool Pluginmanager::dispatch(TextThread& thread, std::wstring& sentence){
|
||||
return !sentence.empty();
|
||||
}
|
||||
|
||||
void Pluginmanager::remove(const std::string&s){
|
||||
|
||||
auto &plgs=configs->configs["plugins"];
|
||||
auto it=std::remove_if(plgs.begin(),plgs.end(),[&](auto&t){
|
||||
std::string p=t["path"];
|
||||
return p==s;
|
||||
});
|
||||
plgs.erase(it, plgs.end());
|
||||
}
|
||||
void Pluginmanager::add(const pluginitem& item){
|
||||
configs->configs["plugins"].push_back(item.dump());
|
||||
}
|
||||
@ -193,8 +204,23 @@ bool Pluginmanager::checkisdump(const std::wstring& dll){
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void Pluginmanager::remove(const std::wstring& ss){
|
||||
remove(WideStringToString(ss));
|
||||
void Pluginmanager::remove(const std::wstring& wss,bool onlyload){
|
||||
auto hm=OnNewSentenceS[wss].hmodule;
|
||||
if(OnNewSentenceS[wss].isQt && hm){
|
||||
((QtFreeLibrary_t)GetProcAddress(GetModuleHandle(0),"QtFreeLibrary"))(hm);
|
||||
}
|
||||
else
|
||||
FreeLibrary(hm);
|
||||
OnNewSentenceS[wss].funcptr=OnNewSentenceS[wss].hmodule=0;
|
||||
|
||||
if(onlyload)return;
|
||||
auto s=WideStringToString(wss);
|
||||
auto &plgs=configs->configs["plugins"];
|
||||
auto it=std::remove_if(plgs.begin(),plgs.end(),[&](auto&t){
|
||||
std::string p=t["path"];
|
||||
return p==s;
|
||||
});
|
||||
plgs.erase(it, plgs.end());
|
||||
}
|
||||
std::optional<std::wstring>Pluginmanager::selectpluginfile(){
|
||||
return SelectFile(0,L"Plugin Files\0*.dll;*.xdll\0");
|
||||
@ -279,26 +305,28 @@ bool qtchecker(const std::set<std::string>& dll)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
addpluginresult Pluginmanager::addplugin(const std::wstring& p){
|
||||
addpluginresult Pluginmanager::addplugin(const std::wstring& p,bool onlyload){
|
||||
if(!onlyload)
|
||||
if(checkisdump(p))return addpluginresult::dumplicate;
|
||||
auto importtable=getimporttable(p);
|
||||
if(importtable.empty())return addpluginresult::invaliddll;
|
||||
auto isQt=qtchecker(importtable);
|
||||
LPVOID plugin;
|
||||
HMODULE base;
|
||||
if(isQt){
|
||||
plugin=0;
|
||||
base=loadqtdllsX(p);
|
||||
}
|
||||
else{
|
||||
auto base=LoadLibraryW(p.c_str());
|
||||
if(base==0)return addpluginresult::invaliddll;
|
||||
plugin=GetProcAddress(base,"OnNewSentence");
|
||||
if(!plugin)return addpluginresult::isnotaplugins;
|
||||
base=LoadLibraryW(p.c_str());
|
||||
}
|
||||
|
||||
if(base==0)return addpluginresult::invaliddll;
|
||||
auto plugin=GetProcAddress(base,"OnNewSentence");
|
||||
if(!plugin)return addpluginresult::isnotaplugins;
|
||||
std::scoped_lock lock(OnNewSentenceSLock);
|
||||
if(checkisdump(p))return addpluginresult::dumplicate;
|
||||
|
||||
OnNewSentenceS[p]=plugin;
|
||||
add({p,isQt});
|
||||
|
||||
OnNewSentenceS[p]={isQt,plugin,base};
|
||||
if(!onlyload)
|
||||
add({p,isQt});
|
||||
|
||||
return addpluginresult::success;
|
||||
}
|
||||
|
@ -21,8 +21,13 @@ struct pluginitem{
|
||||
std::wstring wpath();
|
||||
nlohmann::json dump() const;
|
||||
};
|
||||
struct plugindata{
|
||||
bool isQt;
|
||||
LPVOID funcptr;
|
||||
HMODULE hmodule;
|
||||
};
|
||||
class Pluginmanager{
|
||||
std::unordered_map<std::wstring,LPVOID>OnNewSentenceS;
|
||||
std::unordered_map<std::wstring,plugindata>OnNewSentenceS;
|
||||
std::optional<LPVOID> checkisvalidplugin(const std::wstring&);
|
||||
concurrency::reader_writer_lock OnNewSentenceSLock;
|
||||
bool checkisdump(const std::wstring&);
|
||||
@ -33,7 +38,7 @@ class Pluginmanager{
|
||||
public:
|
||||
Pluginmanager(LunaHost*);
|
||||
bool dispatch(TextThread&, std::wstring& sentence);
|
||||
addpluginresult addplugin(const std::wstring&);
|
||||
addpluginresult addplugin(const std::wstring&,bool onlyload=false);
|
||||
std::optional<std::wstring>selectpluginfile();
|
||||
|
||||
pluginitem get(int);
|
||||
@ -43,8 +48,7 @@ public:
|
||||
void setenable(int ,bool);
|
||||
int count();
|
||||
void add(const pluginitem&);
|
||||
void remove(const std::string&);
|
||||
void remove(const std::wstring&);
|
||||
void remove(const std::wstring&,bool);
|
||||
void swaprank(int,int);
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user