mirror of
https://github.com/HIllya51/LunaHook.git
synced 2024-10-22 23:18:16 +08:00
everyone
This reverts commit 975f049797
.
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 MenuPluginRankDown L"Down"
|
||||||
#define MenuPluginEnable L"Enable"
|
#define MenuPluginEnable L"Enable"
|
||||||
#define DefaultFont L"Arial"
|
#define DefaultFont L"Arial"
|
||||||
#define LblPluginNotify L"Qt Plugins Will be Loaded at Start Only."
|
#define CantLoadQtLoader L"Can't Load QtLoader.dll"
|
||||||
#define LblPluginRemove L"Remove Plugins Will be Useful after Restart."
|
|
||||||
#define InvalidPlugin L"Invalid Plugin!"
|
#define InvalidPlugin L"Invalid Plugin!"
|
||||||
#define InvalidDll L"Invalid Dll!"
|
#define InvalidDll L"Invalid Dll!"
|
||||||
#define InvalidDump L"Dumplicated!"
|
#define InvalidDump L"Dumplicated!"
|
||||||
|
@ -68,8 +68,7 @@
|
|||||||
#define MenuPluginRankDown L"下移"
|
#define MenuPluginRankDown L"下移"
|
||||||
#define MenuPluginEnable L"使用"
|
#define MenuPluginEnable L"使用"
|
||||||
#define DefaultFont L"微软雅黑"
|
#define DefaultFont L"微软雅黑"
|
||||||
#define LblPluginNotify L"依赖于Qt的插件仅会在启动时载入。"
|
#define CantLoadQtLoader L"无法加载QtLoader.dll"
|
||||||
#define LblPluginRemove L"移除插件要在重启后生效。"
|
|
||||||
#define InvalidPlugin L"插件无效!"
|
#define InvalidPlugin L"插件无效!"
|
||||||
#define InvalidDll L"Dll无效!"
|
#define InvalidDll L"Dll无效!"
|
||||||
#define InvalidDump L"重复!"
|
#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)
|
target_precompile_headers(LunaHost REUSE_FROM pch)
|
||||||
set_target_properties(LunaHost PROPERTIES OUTPUT_NAME "LunaHost${bitappendix}")
|
set_target_properties(LunaHost PROPERTIES OUTPUT_NAME "LunaHost${bitappendix}")
|
||||||
target_link_libraries(LunaHost comctl32 pch host ${YY_Thunks_for_WinXP})
|
target_link_libraries(LunaHost comctl32 pch host ${YY_Thunks_for_WinXP})
|
||||||
|
@ -394,7 +394,7 @@ Settingwindow::Settingwindow(LunaHost* host):mainwindow(host){
|
|||||||
settext(WndSetting);
|
settext(WndSetting);
|
||||||
}
|
}
|
||||||
void Pluginwindow::on_size(int w,int h){
|
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){
|
void Pluginwindow::pluginrankmove(int moveoffset){
|
||||||
auto idx=listplugins->currentidx();
|
auto idx=listplugins->currentidx();
|
||||||
@ -412,8 +412,7 @@ void Pluginwindow::pluginrankmove(int moveoffset){
|
|||||||
listplugins->setdata(b,(LONG_PTR)pa);
|
listplugins->setdata(b,(LONG_PTR)pa);
|
||||||
}
|
}
|
||||||
Pluginwindow::Pluginwindow(mainwindow*p,Pluginmanager* pl):mainwindow(p),pluginmanager(pl){
|
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){
|
static auto listadd=[&](const std::wstring& s){
|
||||||
auto idx=listplugins->additem(std::filesystem::path(s).stem());
|
auto idx=listplugins->additem(std::filesystem::path(s).stem());
|
||||||
auto _s=new wchar_t[s.size()+1];wcscpy(_s,s.c_str());
|
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)
|
if(idx!=-1)
|
||||||
{
|
{
|
||||||
menu.add(MenuRemovePlugin,[&,idx](){
|
menu.add(MenuRemovePlugin,[&,idx](){
|
||||||
pluginmanager->remove((LPCWSTR)listplugins->getdata(idx));
|
pluginmanager->remove((LPCWSTR)listplugins->getdata(idx),false);
|
||||||
listplugins->deleteitem(idx);
|
listplugins->deleteitem(idx);
|
||||||
});
|
});
|
||||||
menu.add_sep();
|
menu.add_sep();
|
||||||
@ -452,6 +451,10 @@ Pluginwindow::Pluginwindow(mainwindow*p,Pluginmanager* pl):mainwindow(p),pluginm
|
|||||||
menu.add_sep();
|
menu.add_sep();
|
||||||
menu.add_checkable(MenuPluginEnable,pluginmanager->getenable(idx),[&,idx](bool check){
|
menu.add_checkable(MenuPluginEnable,pluginmanager->getenable(idx),[&,idx](bool check){
|
||||||
pluginmanager->setenable(idx,check);
|
pluginmanager->setenable(idx,check);
|
||||||
|
if(check)
|
||||||
|
pluginmanager->addplugin((LPCWSTR)listplugins->getdata(idx),true);
|
||||||
|
else
|
||||||
|
pluginmanager->remove((LPCWSTR)listplugins->getdata(idx),true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return menu;
|
return menu;
|
||||||
|
@ -5,15 +5,15 @@ set_target_properties(ToClipboard PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_L
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(0)
|
if(0)
|
||||||
include(QtUtils.cmake)
|
include(QtUtils.cmake)
|
||||||
msvc_registry_search()
|
msvc_registry_search()
|
||||||
if(Qt5_DIR)
|
if(Qt5_DIR)
|
||||||
find_qt5(Core Widgets)
|
find_qt5(Core Widgets)
|
||||||
#set(CMAKE_AUTOMOC ON)
|
#set(CMAKE_AUTOMOC ON)
|
||||||
add_library(QtLoader MODULE QtLoader.cpp)
|
add_library(QtLoader MODULE QtLoader.cpp)
|
||||||
#qt5_wrap_cpp(MOC_SOURCES QtLoader.h)
|
#qt5_wrap_cpp(MOC_SOURCES QtLoader.h)
|
||||||
#target_sources(QtLoader PRIVATE ${MOC_SOURCES})
|
#target_sources(QtLoader PRIVATE ${MOC_SOURCES})
|
||||||
target_link_libraries(QtLoader Qt5::Widgets Qt5::Core)
|
target_link_libraries(QtLoader Qt5::Widgets Qt5::Core)
|
||||||
set_target_properties(QtLoader PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/plugin${bitappendix}")
|
set_target_properties(QtLoader PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/plugin${bitappendix}")
|
||||||
endif()
|
endif()
|
||||||
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 {};
|
else return {};
|
||||||
}
|
}
|
||||||
|
typedef std::vector<HMODULE>* (*QtLoadLibrary_t)(std::vector<std::wstring>* dlls);
|
||||||
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 Pluginmanager::loadqtdlls(std::vector<std::wstring>&collectQtplugs){
|
void tryaddqttoenv(std::vector<std::wstring>&collectQtplugs){
|
||||||
if(collectQtplugs.size()==0)return;
|
static HMODULE qt5core=0;
|
||||||
auto pluginpath=std::filesystem::current_path()/(x64?"plugin64":"plugin32");
|
if(qt5core==0)
|
||||||
wchar_t env[65535];
|
{
|
||||||
GetEnvironmentVariableW(L"PATH",env,65535);
|
auto pluginpath=std::filesystem::current_path()/(x64?"plugin64":"plugin32");
|
||||||
auto envs=std::wstring(env);
|
wchar_t env[65535];
|
||||||
envs+=L";";envs+=pluginpath;
|
GetEnvironmentVariableW(L"PATH",env,65535);
|
||||||
for(auto&p:collectQtplugs){
|
auto envs=std::wstring(env);
|
||||||
envs+=L";";envs+=std::filesystem::path(p).parent_path();
|
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());
|
std::vector<HMODULE>loadqtdllsX(std::vector<std::wstring>&collectQtplugs){
|
||||||
|
if(collectQtplugs.empty())return {};
|
||||||
auto QtLoadLibrary = (QtLoadLibrary_t)GetProcAddress(GetModuleHandle(0), "QtLoadLibrary");
|
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);
|
auto modules=QtLoadLibrary(&collectQtplugs);
|
||||||
|
|
||||||
if(modules->empty())return;
|
std::vector<HMODULE> _{*modules};
|
||||||
|
|
||||||
for(int i=0;i<collectQtplugs.size();i++){
|
|
||||||
OnNewSentenceS[collectQtplugs[i]]=GetProcAddress(modules->at(i),"OnNewSentence");
|
|
||||||
}
|
|
||||||
|
|
||||||
delete 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){
|
Pluginmanager::Pluginmanager(LunaHost* _host):host(_host),configs(_host->configs){
|
||||||
try {
|
try {
|
||||||
@ -62,17 +80,19 @@ Pluginmanager::Pluginmanager(LunaHost* _host):host(_host),configs(_host->configs
|
|||||||
auto plg=get(i);
|
auto plg=get(i);
|
||||||
bool isqt=plg.isQt;
|
bool isqt=plg.isQt;
|
||||||
auto path=plg.wpath();
|
auto path=plg.wpath();
|
||||||
OnNewSentenceS[path]=0;
|
OnNewSentenceS[path]={false,0,0};
|
||||||
if(isqt){
|
if(isqt){
|
||||||
if(plg.enable==false)continue;
|
if(plg.enable==false)continue;
|
||||||
collectQtplugs.push_back((path));
|
collectQtplugs.push_back((path));
|
||||||
}
|
}
|
||||||
else
|
else{
|
||||||
OnNewSentenceS[path]=GetProcAddress(LoadLibraryW(path.c_str()),"OnNewSentence");
|
auto base=LoadLibraryW(path.c_str());
|
||||||
|
OnNewSentenceS[path]={false,GetProcAddress(base,"OnNewSentence"),base};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
loadqtdlls(collectQtplugs);
|
loadqtdlls(collectQtplugs);
|
||||||
|
|
||||||
OnNewSentenceS[L"InternalClipBoard"]=GetProcAddress(GetModuleHandle(0),"OnNewSentence");//内部链接的剪贴板插件
|
OnNewSentenceS[L"InternalClipBoard"]={false,GetProcAddress(GetModuleHandle(0),"OnNewSentence"),GetModuleHandle(0)};//内部链接的剪贴板插件
|
||||||
|
|
||||||
|
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
@ -94,7 +114,7 @@ bool Pluginmanager::dispatch(TextThread& thread, std::wstring& sentence){
|
|||||||
path=getname(i);
|
path=getname(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto funptr=OnNewSentenceS[path];
|
auto funptr=OnNewSentenceS[path].funcptr;
|
||||||
if(funptr==0)continue;
|
if(funptr==0)continue;
|
||||||
if (!*(sentenceBuffer = ((OnNewSentence_t)funptr)(sentenceBuffer, sentenceInfo)))
|
if (!*(sentenceBuffer = ((OnNewSentence_t)funptr)(sentenceBuffer, sentenceInfo)))
|
||||||
break;
|
break;
|
||||||
@ -105,15 +125,6 @@ bool Pluginmanager::dispatch(TextThread& thread, std::wstring& sentence){
|
|||||||
return !sentence.empty();
|
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){
|
void Pluginmanager::add(const pluginitem& item){
|
||||||
configs->configs["plugins"].push_back(item.dump());
|
configs->configs["plugins"].push_back(item.dump());
|
||||||
}
|
}
|
||||||
@ -193,8 +204,23 @@ bool Pluginmanager::checkisdump(const std::wstring& dll){
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void Pluginmanager::remove(const std::wstring& ss){
|
void Pluginmanager::remove(const std::wstring& wss,bool onlyload){
|
||||||
remove(WideStringToString(ss));
|
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(){
|
std::optional<std::wstring>Pluginmanager::selectpluginfile(){
|
||||||
return SelectFile(0,L"Plugin Files\0*.dll;*.xdll\0");
|
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 true;
|
||||||
return false;
|
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);
|
auto importtable=getimporttable(p);
|
||||||
if(importtable.empty())return addpluginresult::invaliddll;
|
if(importtable.empty())return addpluginresult::invaliddll;
|
||||||
auto isQt=qtchecker(importtable);
|
auto isQt=qtchecker(importtable);
|
||||||
LPVOID plugin;
|
HMODULE base;
|
||||||
if(isQt){
|
if(isQt){
|
||||||
plugin=0;
|
base=loadqtdllsX(p);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
auto base=LoadLibraryW(p.c_str());
|
base=LoadLibraryW(p.c_str());
|
||||||
if(base==0)return addpluginresult::invaliddll;
|
|
||||||
plugin=GetProcAddress(base,"OnNewSentence");
|
|
||||||
if(!plugin)return addpluginresult::isnotaplugins;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(base==0)return addpluginresult::invaliddll;
|
||||||
|
auto plugin=GetProcAddress(base,"OnNewSentence");
|
||||||
|
if(!plugin)return addpluginresult::isnotaplugins;
|
||||||
std::scoped_lock lock(OnNewSentenceSLock);
|
std::scoped_lock lock(OnNewSentenceSLock);
|
||||||
if(checkisdump(p))return addpluginresult::dumplicate;
|
|
||||||
|
OnNewSentenceS[p]={isQt,plugin,base};
|
||||||
OnNewSentenceS[p]=plugin;
|
if(!onlyload)
|
||||||
add({p,isQt});
|
add({p,isQt});
|
||||||
|
|
||||||
return addpluginresult::success;
|
return addpluginresult::success;
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,13 @@ struct pluginitem{
|
|||||||
std::wstring wpath();
|
std::wstring wpath();
|
||||||
nlohmann::json dump() const;
|
nlohmann::json dump() const;
|
||||||
};
|
};
|
||||||
|
struct plugindata{
|
||||||
|
bool isQt;
|
||||||
|
LPVOID funcptr;
|
||||||
|
HMODULE hmodule;
|
||||||
|
};
|
||||||
class Pluginmanager{
|
class Pluginmanager{
|
||||||
std::unordered_map<std::wstring,LPVOID>OnNewSentenceS;
|
std::unordered_map<std::wstring,plugindata>OnNewSentenceS;
|
||||||
std::optional<LPVOID> checkisvalidplugin(const std::wstring&);
|
std::optional<LPVOID> checkisvalidplugin(const std::wstring&);
|
||||||
concurrency::reader_writer_lock OnNewSentenceSLock;
|
concurrency::reader_writer_lock OnNewSentenceSLock;
|
||||||
bool checkisdump(const std::wstring&);
|
bool checkisdump(const std::wstring&);
|
||||||
@ -33,7 +38,7 @@ class Pluginmanager{
|
|||||||
public:
|
public:
|
||||||
Pluginmanager(LunaHost*);
|
Pluginmanager(LunaHost*);
|
||||||
bool dispatch(TextThread&, std::wstring& sentence);
|
bool dispatch(TextThread&, std::wstring& sentence);
|
||||||
addpluginresult addplugin(const std::wstring&);
|
addpluginresult addplugin(const std::wstring&,bool onlyload=false);
|
||||||
std::optional<std::wstring>selectpluginfile();
|
std::optional<std::wstring>selectpluginfile();
|
||||||
|
|
||||||
pluginitem get(int);
|
pluginitem get(int);
|
||||||
@ -43,8 +48,7 @@ public:
|
|||||||
void setenable(int ,bool);
|
void setenable(int ,bool);
|
||||||
int count();
|
int count();
|
||||||
void add(const pluginitem&);
|
void add(const pluginitem&);
|
||||||
void remove(const std::string&);
|
void remove(const std::wstring&,bool);
|
||||||
void remove(const std::wstring&);
|
|
||||||
void swaprank(int,int);
|
void swaprank(int,int);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user