diff --git a/common.h b/common.h index e3a8b53..6ffe5d5 100644 --- a/common.h +++ b/common.h @@ -32,6 +32,9 @@ #include #include #include +#include +#include +#include //#include //#include @@ -85,6 +88,21 @@ void Log(char* Msg); void Log(wchar_t* Msg); +// convert string to wstring +inline std::wstring to_wide_string(const std::string & input) +{ + std::wstring_convert> converter; + return converter.from_bytes(input); +} +// convert wstring to string +inline std::string to_byte_string(const std::wstring & input) +{ + //std::wstring_convert> converter; + std::wstring_convert> converter; + return converter.to_bytes(input); +} + + FORCEINLINE HINSTANCE GetDLLInstance() { extern HINSTANCE g_hinstDLL; diff --git a/expfunc.cpp b/expfunc.cpp index a71598c..077b5dc 100644 --- a/expfunc.cpp +++ b/expfunc.cpp @@ -1031,3 +1031,14 @@ EXTERN_C LPWSTR WINAPI GdippEnvironment(DWORD& dwCreationFlags, LPVOID lpEnviron dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT; return pEnvW; } + +void DebugOut(const WCHAR* szFormat, ...) { +#ifdef TRACE + va_list args; + va_start(args, szFormat); + WCHAR buffer[1024] = { 0 }; + vswprintf(buffer, szFormat, args); + std::wstring fullmsg = L"[MTCore] " + std::wstring(buffer); + OutputDebugString(fullmsg.c_str()); +#endif +} \ No newline at end of file diff --git a/ft.h b/ft.h index 2091c04..322a7f1 100644 --- a/ft.h +++ b/ft.h @@ -32,7 +32,7 @@ private: bool bZoomMode; bool bMirrorX, bMirrorY; public: - CDCTransformer():bMirrorY(false), bMirrorX(false) {}; + CDCTransformer():bMirrorY(false), bMirrorX(false), bZoomMode(false), fXZoomFactor(0), fYZoomFactor(0) {}; void init(XFORM& xfm) { memcpy(&m_xfm, &xfm, sizeof(XFORM)); diff --git a/gdidll.rc b/gdidll.rc index 9952d8b..76bdad5 100644 --- a/gdidll.rc +++ b/gdidll.rc @@ -9,7 +9,7 @@ // // Generated from the TEXTINCLUDE 2 resource. // -#include "afxres.h" ///////////////////////////////////////////////////////////////////////////// +//#include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// diff --git a/gdipp.sln b/gdipp.sln index 63591d7..c3615bf 100644 --- a/gdipp.sln +++ b/gdipp.sln @@ -1,7 +1,6 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.21005.1 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31515.178 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MacType", "gdipp.vcxproj", "{15C33FD9-0811-4981-B08F-E0BAD74A3028}" EndProject @@ -11,6 +10,8 @@ Global Debug Infinality|x64 = Debug Infinality|x64 Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 + Rel+Trace|Win32 = Rel+Trace|Win32 + Rel+Trace|x64 = Rel+Trace|x64 Release Infinality|Win32 = Release Infinality|Win32 Release Infinality|x64 = Release Infinality|x64 Release|Win32 = Release|Win32 @@ -25,6 +26,10 @@ Global {15C33FD9-0811-4981-B08F-E0BAD74A3028}.Debug|Win32.Build.0 = Debug|Win32 {15C33FD9-0811-4981-B08F-E0BAD74A3028}.Debug|x64.ActiveCfg = Debug|x64 {15C33FD9-0811-4981-B08F-E0BAD74A3028}.Debug|x64.Build.0 = Debug|x64 + {15C33FD9-0811-4981-B08F-E0BAD74A3028}.Rel+Trace|Win32.ActiveCfg = Rel+Trace|Win32 + {15C33FD9-0811-4981-B08F-E0BAD74A3028}.Rel+Trace|Win32.Build.0 = Rel+Trace|Win32 + {15C33FD9-0811-4981-B08F-E0BAD74A3028}.Rel+Trace|x64.ActiveCfg = Rel+Trace|x64 + {15C33FD9-0811-4981-B08F-E0BAD74A3028}.Rel+Trace|x64.Build.0 = Rel+Trace|x64 {15C33FD9-0811-4981-B08F-E0BAD74A3028}.Release Infinality|Win32.ActiveCfg = Release Infinality|Win32 {15C33FD9-0811-4981-B08F-E0BAD74A3028}.Release Infinality|Win32.Build.0 = Release Infinality|Win32 {15C33FD9-0811-4981-B08F-E0BAD74A3028}.Release Infinality|x64.ActiveCfg = Release Infinality|x64 @@ -37,4 +42,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3F209D78-C531-4FA9-941E-68BEF65161FD} + EndGlobalSection EndGlobal diff --git a/gdipp.vcxproj b/gdipp.vcxproj index 5399398..7f8b15b 100644 --- a/gdipp.vcxproj +++ b/gdipp.vcxproj @@ -25,6 +25,18 @@ Debug x64 + + Rel+Trace + ARM + + + Rel+Trace + Win32 + + + Rel+Trace + x64 + Release Infinality ARM @@ -62,66 +74,84 @@ DynamicLibrary Unicode true - v142 + v143 + + + DynamicLibrary + Unicode + true + v143 DynamicLibrary - v142 + v143 Unicode true DynamicLibrary - v140 + v143 Unicode DynamicLibrary - v142 + v143 Unicode DynamicLibrary - v142 + v143 + Unicode + true + + + DynamicLibrary + v143 Unicode true DynamicLibrary - v142 + v143 Unicode true DynamicLibrary - v142 + v143 + Unicode + true + + + DynamicLibrary + v143 Unicode true DynamicLibrary - v142 + v143 Unicode true DynamicLibrary - v140 + v143 Unicode DynamicLibrary - v142 + v143 Unicode DynamicLibrary - v142 + v143 Unicode DynamicLibrary - v142 + v143 Unicode @@ -130,6 +160,9 @@ + + + @@ -142,12 +175,18 @@ + + + + + + @@ -230,6 +269,15 @@ $(INI_PARSER_PATH);$(FREETYPE_PATH)\include;$(IncludePath) $(SolutionDir)lib;$(LibraryPath) + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + false + $(ProjectName).Core + $(INI_PARSER_PATH);$(FREETYPE_PATH)\include;$(IncludePath) + $(SolutionDir)lib;$(LibraryPath) + $(SolutionDir)$(Configuration)\ $(Configuration)\ @@ -248,6 +296,15 @@ $(INI_PARSER_PATH);$(FREETYPE_PATH)\include;$(IncludePath) $(SolutionDir)lib;$(LibraryPath) + + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + false + $(ProjectName)64.Core + $(INI_PARSER_PATH);$(FREETYPE_PATH)\include;$(IncludePath) + $(SolutionDir)lib;$(LibraryPath) + $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ @@ -266,6 +323,15 @@ $(INI_PARSER_PATH);$(FREETYPE_PATH)\include;$(IncludePath) $(SolutionDir)lib;$(LibraryPath) + + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + false + $(ProjectName)64.Core + $(INI_PARSER_PATH);$(FREETYPE_PATH)\include;$(IncludePath) + $(SolutionDir)lib;$(LibraryPath) + $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ @@ -299,7 +365,7 @@ true MachineX86 /DEBUG - easyhook32.dll + easyhk32.dll @@ -482,6 +548,42 @@ UseLinkTimeCodeGeneration + + + MaxSpeed + true + Speed + false + WIN32;NDEBUG;_WINDOWS;_USRDLL;GDIPP_EXPORTS;_GDIPP_DLL;%(PreprocessorDefinitions) + Sync + MultiThreaded + false + false + StreamingSIMDExtensions2 + Precise + + + Level3 + ProgramDatabase + $(SolutionDir)deps\include;%(AdditionalIncludeDirectories) + /Zc:threadSafeInit- /utf-8 %(AdditionalOptions) + + + freetype.lib;usp10.lib;dwrite.lib;%(AdditionalDependencies) + false + expfunc.def + true + Windows + true + true + true + true + MachineX86 + easyhk32.dll + $(SolutionDir)deps\lib;%(AdditionalLibraryDirectories) + UseLinkTimeCodeGeneration + + MaxSpeed @@ -551,6 +653,43 @@ true + + + X64 + + + MaxSpeed + true + Speed + NDEBUG;_WINDOWS;_USRDLL;GDIPP_EXPORTS;_GDIPP_DLL;TRACE;%(PreprocessorDefinitions) + Sync + MultiThreaded + false + true + StreamingSIMDExtensions2 + + + Level3 + ProgramDatabase + $(SolutionDir)deps\include;%(AdditionalIncludeDirectories) + /utf-8 %(AdditionalOptions) + + + freetype64.lib;usp10.lib;%(AdditionalDependencies) + false + expfunc.def + true + Windows + true + true + true + true + MachineX64 + easyhk64.dll + $(SolutionDir)deps\lib;%(AdditionalLibraryDirectories) + true + + X64 @@ -616,6 +755,37 @@ easyhook64.dll + + + + MaxSpeed + true + Speed + NDEBUG;_WINDOWS;_USRDLL;GDIPP_EXPORTS;_GDIPP_DLL;%(PreprocessorDefinitions) + Sync + MultiThreaded + false + true + StreamingSIMDExtensions2 + + + Level3 + ProgramDatabase + /utf-8 %(AdditionalOptions) + + + freetype64.lib;usp10.lib;%(AdditionalDependencies) + false + expfunc.def + true + Windows + true + true + true + true + easyhook64.dll + + @@ -664,6 +834,7 @@ Sync + Sync Sync @@ -690,6 +861,7 @@ + @@ -707,4 +879,4 @@ - + \ No newline at end of file diff --git a/gdipp.vcxproj.filters b/gdipp.vcxproj.filters index 3c81bf7..3c4ed04 100644 --- a/gdipp.vcxproj.filters +++ b/gdipp.vcxproj.filters @@ -154,10 +154,13 @@ Header Files + + Header Files + Resource Files - + \ No newline at end of file diff --git a/hook.cpp b/hook.cpp index 73b4f35..3ce2bc1 100644 --- a/hook.cpp +++ b/hook.cpp @@ -410,6 +410,7 @@ BOOL AddEasyHookEnv() extern FT_Int * g_charmapCache; extern BYTE* AACache, *AACacheFull; extern HFONT g_alterGUIFont; +extern void DebugOut(const WCHAR* szFormat, ...); extern COLORCACHE* g_AACache2[MAX_CACHE_SIZE]; HANDLE hDelayHook = 0; @@ -422,7 +423,8 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID lpReserved) #ifdef DEBUG MessageBox(0, L"Load", NULL, MB_OK); #endif - if (bDllInited) + DebugOut(L"Begin core loading stage, pid %d", ::GetCurrentProcessId()); + if (bDllInited) return true; g_dllInstance = instance; { @@ -438,8 +440,10 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID lpReserved) #endif HMODULE hEasyhk = LoadLibrary(dllPath); delete[]dllPath; - if (!hEasyhk) - return false; + if (!hEasyhk) { + DebugOut(L"Failed to load Easyhook, exiting"); + return false; + } } //初期化順序 //DLL_PROCESS_DETACHではこれの逆順にする @@ -461,7 +465,7 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID lpReserved) //Operaよ止まれ~ //Assert(GetModuleHandleA("opera.exe") == NULL); - setlocale(LC_ALL, ""); + //setlocale(LC_ALL, ""); g_hinstDLL = instance; @@ -472,6 +476,7 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID lpReserved) COwnedCriticalSectionLock::Init(); CThreadCounter::Init(); if (!g_TLInfo.ProcessInit()) { + DebugOut(L"Can't initialize process, exiting"); return FALSE; } @@ -500,6 +505,7 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID lpReserved) InitWow64ext(); #endif if (!FontLInit()) { + DebugOut(L"FreeType failed to initialize, exiting"); return FALSE; } g_pFTEngine = new FreeTypeFontEngine; @@ -509,8 +515,10 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID lpReserved) //if (!AddEasyHookEnv()) return FALSE; //fail to load easyhook InterlockedExchange(&g_bHookEnabled, TRUE); - if (hook_init()!=NOERROR) + if (hook_init() != NOERROR) { + DebugOut(L"Can't do hooking, exiting"); return FALSE; + } //hook d2d if already loaded /* DWORD dwSessionID = 0; @@ -525,11 +533,6 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID lpReserved) HookD2DDll(); //hook_demand_LdrLoadDll(); } - /*if (IsWindows8OrGreater()) { - *(DWORD_PTR*)&(ORIG_MySetProcessMitigationPolicy) = *(DWORD_PTR*)&(MySetProcessMitigationPolicy); - //hook_demand_MySetProcessMitigationPolicy(); - }*/ -// InstallManagerHook(); } //获得当前加载模式 @@ -546,8 +549,10 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID lpReserved) CloseHandle(mutex_CompMode); CloseHandle(mutex_gditray2); CloseHandle(mutex_offical); - if (!HookMode) //非兼容模式下,拒绝加载 + if (!HookMode) { //非兼容模式下,拒绝加载 + DebugOut(L"Process is in unloaddll list, exiting"); return false; + } } //APITracer::Finish(); diff --git a/settings.cpp b/settings.cpp index 44958f2..1bc9a89 100644 --- a/settings.cpp +++ b/settings.cpp @@ -8,6 +8,8 @@ #include #endif +CControlCenter* g_ControlCenter = NULL; + inline BOOL IsFolder(LPCTSTR pszPath) { return pszPath && *pszPath && *(pszPath + wcslen(pszPath) - 1) == '\\'; } diff --git a/settings.h b/settings.h index a5d9d04..63fe638 100644 --- a/settings.h +++ b/settings.h @@ -6,6 +6,10 @@ #include "hash_list.h" #include #include +#include "json.hpp" +#include + +using json = nlohmann::json; #ifdef _WIN64 #ifdef DEBUG @@ -21,7 +25,7 @@ #endif #endif -#define MACTYPE_VERSION 20170628 +#define MACTYPE_VERSION 20220712 #define MAX_FONT_SETTINGS 16 #define DEFINE_FS_MEMBER(name, param) \ int Get##name() const { return GetParam(param); } \ @@ -236,7 +240,9 @@ interface IControlCenter virtual BOOL WINAPI ClearIndividual() = 0; virtual BOOL WINAPI AddIndividual(WCHAR* fontSetting) = 0; virtual BOOL WINAPI DelIndividual(WCHAR* lpFaceName) = 0; - virtual void WINAPI LoadSetting(WCHAR* lpFileName) = 0; + virtual void WINAPI LoadSetting(const WCHAR* lpFileName) = 0; + virtual HWND WINAPI CreateMessageWnd() = 0; + virtual void WINAPI DestroyMessageWnd() = 0; }; class CControlCenter; @@ -538,11 +544,14 @@ extern FreeTypeFontEngine* g_pFTEngine; extern BOOL g_ccbCache; extern BOOL g_ccbRender; +extern CControlCenter* g_ControlCenter; + class CControlCenter: public IControlCenter { private: int m_nRefCount; bool m_bDirty; + HWND m_msgwnd; enum eMTSettings{ ATTR_HINTINGMODE, ATTR_ANTIALIASMODE, @@ -881,7 +890,7 @@ public: } m_bDirty = true; return true;}; - void WINAPI LoadSetting(WCHAR* lpFileName) + void WINAPI LoadSetting(const WCHAR* lpFileName) { CGdippSettings* pSettings = CGdippSettings::GetInstance(); ClearIndividual(); @@ -894,8 +903,12 @@ public: RefreshAlphaTable(); RefreshSetting(); } - CControlCenter():m_nRefCount(1), m_bDirty(false){}; - ~CControlCenter(){}; + CControlCenter():m_nRefCount(1), m_bDirty(false), m_msgwnd(NULL) { + g_ControlCenter = this; + }; + ~CControlCenter(){ + g_ControlCenter = NULL; + }; static void WINAPI ReloadConfig() { //CCriticalSectionLock __lock(CCriticalSectionLock::CS_LIBRARY); @@ -912,4 +925,97 @@ public: if (g_pFTEngine) g_pFTEngine->ReloadAll(); } + HWND WINAPI CreateMessageWnd() { + HANDLE event = CreateEvent(NULL, true, false, NULL); + + auto run = [&]() -> void { + if (this->m_msgwnd) { + SendMessage(this->m_msgwnd, WM_CLOSE, 0, 0); + } + WNDCLASS wndclass; + wndclass.style = 0; + wndclass.lpfnWndProc = [](HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -> LRESULT { + return g_ControlCenter ? g_ControlCenter->MsgProc(hwnd, message, wParam, lParam) : DefWindowProc(hwnd, message, wParam, lParam); + }; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = 0; + wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = L"MT_CMSGWND"; + RegisterClass(&wndclass); + this->m_msgwnd = CreateWindow(L"MT_CMSGWND", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, NULL); + SetEvent(event); + + MSG msg; + while (GetMessage(&msg, NULL, 0, 0)) //消息循环 + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + DestroyWindow(this->m_msgwnd); + }; + auto wndThread = thread(run); + wndThread.detach(); + WaitForSingleObject(event, 10000); + CloseHandle(event); + return this->m_msgwnd; + } + + void RedrawCurrentApp() { + auto EnumCurrentProcWindow = [](HWND hwnd, LPARAM lparam)->BOOL { + DWORD pid = 0; + GetWindowThreadProcessId(hwnd, &pid); + if (pid == lparam) { + RedrawWindow(hwnd, NULL, 0, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOERASE); + } + return true; + }; + + EnumWindows(EnumCurrentProcWindow, GetCurrentProcessId()); + } + + LRESULT WINAPI MsgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { + switch (msg) { + case WM_COPYDATA: { + COPYDATASTRUCT* data = (COPYDATASTRUCT*)lparam; + if (data->cbData && data->lpData) { // ignore invalid request. + string json; + json.resize(data->cbData); + memcpy((void*)json.c_str(), data->lpData, data->cbData); + // now parse the json string + auto jsonobj = json::parse(json.begin(), json.end()); + string command = jsonobj["command"].get(); + // various command dispatch + if (command == "loadprofile") { // load target profile from disk + string filename = jsonobj["file"].get(); + if (filename.length()) { + this->LoadSetting(to_wide_string(filename).c_str()); + RedrawCurrentApp(); + } + return ERROR_SUCCESS; + } + if (command == "ping") { + //__asm db 0xcc; // cause debugger to break + //DebugBreak(); + return ERROR_SUCCESS; + } + } + break; + } + default: { + return DefWindowProc(hwnd, msg, wparam, lparam); + } + } + return 0; + } + + void WINAPI DestroyMessageWnd() { + if (m_msgwnd) { + DestroyWindow(m_msgwnd); + m_msgwnd = NULL; + } + } };