diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index 00a7b1ed51..6d3929abca 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -1,5 +1,3 @@ -// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003. - #include "Core/Config.h" #include "Core/MemMap.h" #include "Windows/resource.h" @@ -13,6 +11,7 @@ #include "Windows/Debugger/Debugger_Disasm.h" #include "Windows/Debugger/Debugger_VFPUDlg.h" #include "Windows/Debugger/DebuggerShared.h" +#include "Windows/W32Util/DarkMode.h" #include "Windows/main.h" #include "Windows/Debugger/CtrlRegisterList.h" @@ -350,10 +349,8 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) switch(message) { case WM_INITDIALOG: - { - return TRUE; - } - break; + DarkModeInitDialog(m_hDlg); + return TRUE; case WM_NOTIFY: switch (wParam) @@ -692,7 +689,7 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) } break; } - return FALSE; + return DarkModeDlgProc(m_hDlg, message, wParam, lParam); } void CDisasm::updateThreadLabel(bool clear) diff --git a/Windows/Debugger/Debugger_Disasm.h b/Windows/Debugger/Debugger_Disasm.h index 73367f02f4..e186e3e238 100644 --- a/Windows/Debugger/Debugger_Disasm.h +++ b/Windows/Debugger/Debugger_Disasm.h @@ -1,5 +1,3 @@ -// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003. - #pragma once #include "Windows/W32Util/DialogManager.h" diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 65e6e5385e..b960d4fa5e 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -56,6 +56,7 @@ #include "Windows/GPU/WindowsGLContext.h" #include "Windows/GEDebugger/GEDebugger.h" #endif +#include "Windows/W32Util/DarkMode.h" #include "Windows/Debugger/Debugger_Disasm.h" #include "Windows/Debugger/Debugger_MemoryDlg.h" @@ -735,6 +736,9 @@ namespace MainWindow // Remove the D3D11 choice on versions below XP RemoveMenu(GetMenu(hWnd), ID_OPTIONS_DIRECT3D11, MF_BYCOMMAND); } + if (g_darkModeSupported) { + SendMessageW(hWnd, WM_THEMECHANGED, 0, 0); + } break; case WM_USER_GET_BASE_POINTER: @@ -1048,6 +1052,23 @@ namespace MainWindow } return DefWindowProc(hWnd, message, wParam, lParam); } + break; + case WM_SETTINGCHANGE: + { + if (g_darkModeSupported && IsColorSchemeChangeMessage(lParam)) + SendMessageW(hWnd, WM_THEMECHANGED, 0, 0); + } + return DefWindowProc(hWnd, message, wParam, lParam); + + case WM_THEMECHANGED: + { + if (g_darkModeSupported) + { + _AllowDarkModeForWindow(hWnd, g_darkModeEnabled); + RefreshTitleBarThemeColor(hWnd); + } + return DefWindowProc(hWnd, message, wParam, lParam); + } default: return DefWindowProc(hWnd, message, wParam, lParam); diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 25af2cd08e..0183f033c4 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -44,6 +44,7 @@ #include "Windows/W32Util/Misc.h" #include "Windows/InputBox.h" #include "Windows/main.h" +#include "Windows/W32Util/DarkMode.h" #include "Core/HLE/sceUmd.h" #include "Core/SaveState.h" @@ -65,7 +66,7 @@ namespace MainWindow { static bool menuShaderInfoLoaded = false; std::vector menuShaderInfo; - LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); + LRESULT CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM); void SetIngameMenuItemStates(HMENU menu, const GlobalUIState state) { UINT menuEnable = state == UISTATE_INGAME || state == UISTATE_EXCEPTION ? MF_ENABLED : MF_GRAYED; @@ -942,7 +943,7 @@ namespace MainWindow { case ID_HELP_ABOUT: DialogManager::EnableAll(FALSE); - DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); + DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)AboutDlgProc); DialogManager::EnableAll(TRUE); break; @@ -1274,24 +1275,31 @@ namespace MainWindow { } // Message handler for about box. - LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + LRESULT CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { - case WM_INITDIALOG: - { - W32Util::CenterWindow(hDlg); - HWND versionBox = GetDlgItem(hDlg, IDC_VERSION); - std::string windowText = System_GetPropertyBool(SYSPROP_APP_GOLD) ? "PPSSPP Gold " : "PPSSPP "; - windowText.append(PPSSPP_GIT_VERSION); - SetWindowText(versionBox, ConvertUTF8ToWString(windowText).c_str()); - } - return TRUE; - - case WM_COMMAND: - if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { - EndDialog(hDlg, LOWORD(wParam)); + case WM_INITDIALOG: + { + W32Util::CenterWindow(hDlg); + HWND versionBox = GetDlgItem(hDlg, IDC_VERSION); + std::string windowText = System_GetPropertyBool(SYSPROP_APP_GOLD) ? "PPSSPP Gold " : "PPSSPP "; + windowText.append(PPSSPP_GIT_VERSION); + SetWindowText(versionBox, ConvertUTF8ToWString(windowText).c_str()); + DarkModeInitDialog(hDlg); return TRUE; } - break; + + case WM_COMMAND: + { + if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + } + break; + return FALSE; + } + + default: + return DarkModeDlgProc(hDlg, message, wParam, lParam); } return FALSE; } diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index 659056d695..eedcf2fa90 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -917,6 +917,7 @@ + $(IntDir)%(Filename)2.obj @@ -1484,7 +1485,9 @@ + + @@ -1763,4 +1766,4 @@ - \ No newline at end of file + diff --git a/Windows/PPSSPP.vcxproj.filters b/Windows/PPSSPP.vcxproj.filters index b5f7795084..e6f148b185 100644 --- a/Windows/PPSSPP.vcxproj.filters +++ b/Windows/PPSSPP.vcxproj.filters @@ -59,6 +59,9 @@ {8f39c005-9738-41c5-a8d8-cfc05bf178e8} + + {e6f1a7f6-807b-484e-9595-bdb58ecaa2ae} + @@ -271,6 +274,9 @@ Other Platforms\libretro + + Windows\W32Util + @@ -553,6 +559,12 @@ Other Platforms\iOS\iCade + + Windows\W32Util + + + Windows\W32Util + @@ -820,4 +832,4 @@ Other Platforms\SDL - \ No newline at end of file + diff --git a/Windows/W32Util/DarkMode.cpp b/Windows/W32Util/DarkMode.cpp new file mode 100644 index 0000000000..efd38829b8 --- /dev/null +++ b/Windows/W32Util/DarkMode.cpp @@ -0,0 +1,224 @@ +#include "IatHook.h" +#include "DarkMode.h" + +fnSetWindowCompositionAttribute _SetWindowCompositionAttribute = nullptr; +fnShouldAppsUseDarkMode _ShouldAppsUseDarkMode = nullptr; +fnAllowDarkModeForWindow _AllowDarkModeForWindow = nullptr; +fnAllowDarkModeForApp _AllowDarkModeForApp = nullptr; +fnFlushMenuThemes _FlushMenuThemes = nullptr; +fnRefreshImmersiveColorPolicyState _RefreshImmersiveColorPolicyState = nullptr; +fnIsDarkModeAllowedForWindow _IsDarkModeAllowedForWindow = nullptr; +fnGetIsImmersiveColorUsingHighContrast _GetIsImmersiveColorUsingHighContrast = nullptr; +fnOpenNcThemeData _OpenNcThemeData = nullptr; +// 1903 18362 +fnShouldSystemUseDarkMode _ShouldSystemUseDarkMode = nullptr; +fnSetPreferredAppMode _SetPreferredAppMode = nullptr; +fnSetWindowTheme _SetWindowTheme = nullptr; + +bool g_darkModeSupported = false; +bool g_darkModeEnabled = false; +DWORD g_buildNumber = 0; + +bool AllowDarkModeForWindow(HWND hWnd, bool allow) +{ + if (g_darkModeSupported) + return _AllowDarkModeForWindow(hWnd, allow); + return false; +} + +bool IsHighContrast() +{ + HIGHCONTRASTW highContrast = { sizeof(highContrast) }; + if (SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(highContrast), &highContrast, FALSE)) + return highContrast.dwFlags & HCF_HIGHCONTRASTON; + return false; +} + +void RefreshTitleBarThemeColor(HWND hWnd) +{ + BOOL dark = FALSE; + if (_IsDarkModeAllowedForWindow(hWnd) && + _ShouldAppsUseDarkMode() && + !IsHighContrast()) + { + dark = TRUE; + } + if (g_buildNumber < 18362) + SetPropW(hWnd, L"UseImmersiveDarkModeColors", reinterpret_cast(static_cast(dark))); + else if (_SetWindowCompositionAttribute) + { + WINDOWCOMPOSITIONATTRIBDATA data = { WCA_USEDARKMODECOLORS, &dark, sizeof(dark) }; + _SetWindowCompositionAttribute(hWnd, &data); + } +} + +bool IsColorSchemeChangeMessage(LPARAM lParam) +{ + bool is = false; + if (lParam && CompareStringOrdinal(reinterpret_cast(lParam), -1, L"ImmersiveColorSet", -1, TRUE) == CSTR_EQUAL) + { + _RefreshImmersiveColorPolicyState(); + is = true; + } + _GetIsImmersiveColorUsingHighContrast(IHCM_REFRESH); + return is; +} + +bool IsColorSchemeChangeMessage(UINT message, LPARAM lParam) +{ + if (message == WM_SETTINGCHANGE) + return IsColorSchemeChangeMessage(lParam); + return false; +} + +void AllowDarkModeForApp(bool allow) +{ + if (_AllowDarkModeForApp) + _AllowDarkModeForApp(allow); + else if (_SetPreferredAppMode) + _SetPreferredAppMode(allow ? AllowDark : Default); +} + +void FixDarkScrollBar() +{ + HMODULE hComctl = LoadLibraryExW(L"comctl32.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); + if (hComctl) + { + auto addr = FindDelayLoadThunkInModule(hComctl, "uxtheme.dll", 49); // OpenNcThemeData + if (addr) + { + DWORD oldProtect; + if (VirtualProtect(addr, sizeof(IMAGE_THUNK_DATA), PAGE_READWRITE, &oldProtect)) + { + auto MyOpenThemeData = [](HWND hWnd, LPCWSTR classList) -> HTHEME { + if (wcscmp(classList, L"ScrollBar") == 0) + { + hWnd = nullptr; + classList = L"Explorer::ScrollBar"; + } + return _OpenNcThemeData(hWnd, classList); + }; + + addr->u1.Function = reinterpret_cast(static_cast(MyOpenThemeData)); + VirtualProtect(addr, sizeof(IMAGE_THUNK_DATA), oldProtect, &oldProtect); + } + } + } +} + +void DarkModeInitDialog(HWND hDlg) { + if (g_darkModeSupported) { + _SetWindowTheme(GetDlgItem(hDlg, IDOK), L"Explorer", nullptr); + SendMessageW(hDlg, WM_THEMECHANGED, 0, 0); + } +} + +LRESULT DarkModeDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + constexpr COLORREF darkBkColor = 0x383838; + constexpr COLORREF darkTextColor = 0xFFFFFF; + static HBRUSH hbrBkgnd = nullptr; + + switch (message) { + case WM_CTLCOLORDLG: + case WM_CTLCOLORSTATIC: + { + if (g_darkModeSupported && g_darkModeEnabled) + { + HDC hdc = reinterpret_cast(wParam); + SetTextColor(hdc, darkTextColor); + SetBkColor(hdc, darkBkColor); + if (!hbrBkgnd) + hbrBkgnd = CreateSolidBrush(darkBkColor); + return reinterpret_cast(hbrBkgnd); + } + break; + } + case WM_SETTINGCHANGE: + { + if (g_darkModeSupported && IsColorSchemeChangeMessage(lParam)) + SendMessageW(hDlg, WM_THEMECHANGED, 0, 0); + break; + } + case WM_THEMECHANGED: + { + if (g_darkModeSupported) + { + _AllowDarkModeForWindow(hDlg, g_darkModeEnabled); + RefreshTitleBarThemeColor(hDlg); + + HWND hButton = GetDlgItem(hDlg, IDOK); + _AllowDarkModeForWindow(hButton, g_darkModeEnabled); + SendMessageW(hButton, WM_THEMECHANGED, 0, 0); + + UpdateWindow(hDlg); + } + break; + } + } + return FALSE; +} + + +constexpr bool CheckBuildNumber(DWORD buildNumber) +{ + // TODO: This is BS. + + return (buildNumber == 17763 || // 1809 + buildNumber == 18362 || // 1903 + buildNumber == 18363 || // 1909 + buildNumber >= 19041); // Windows 11 +} + +void InitDarkMode() +{ + auto RtlGetNtVersionNumbers = reinterpret_cast(GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlGetNtVersionNumbers")); + if (RtlGetNtVersionNumbers) + { + DWORD major, minor; + RtlGetNtVersionNumbers(&major, &minor, &g_buildNumber); + g_buildNumber &= ~0xF0000000; + if (major == 10 && minor == 0 && CheckBuildNumber(g_buildNumber)) + { + HMODULE hUxtheme = LoadLibraryExW(L"uxtheme.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); + if (hUxtheme) + { + + _OpenNcThemeData = reinterpret_cast(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(49))); + _RefreshImmersiveColorPolicyState = reinterpret_cast(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(104))); + _GetIsImmersiveColorUsingHighContrast = reinterpret_cast(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(106))); + _ShouldAppsUseDarkMode = reinterpret_cast(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(132))); + _AllowDarkModeForWindow = reinterpret_cast(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(133))); + + auto ord135 = GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135)); + if (g_buildNumber < 18362) + _AllowDarkModeForApp = reinterpret_cast(ord135); + else + _SetPreferredAppMode = reinterpret_cast(ord135); + + //_FlushMenuThemes = reinterpret_cast(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(136))); + _IsDarkModeAllowedForWindow = reinterpret_cast(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(137))); + + _SetWindowCompositionAttribute = reinterpret_cast(GetProcAddress(GetModuleHandleW(L"user32.dll"), "SetWindowCompositionAttribute")); + _SetWindowTheme = reinterpret_cast(GetProcAddress(hUxtheme, "SetWindowTheme")); + + if (_OpenNcThemeData && + _RefreshImmersiveColorPolicyState && + _ShouldAppsUseDarkMode && + _AllowDarkModeForWindow && + (_AllowDarkModeForApp || _SetPreferredAppMode) && + //_FlushMenuThemes && + _IsDarkModeAllowedForWindow) + { + g_darkModeSupported = true; + + AllowDarkModeForApp(true); + _RefreshImmersiveColorPolicyState(); + + g_darkModeEnabled = _ShouldAppsUseDarkMode() && !IsHighContrast(); + + FixDarkScrollBar(); + } + } + } + } +} diff --git a/Windows/W32Util/DarkMode.h b/Windows/W32Util/DarkMode.h new file mode 100644 index 0000000000..76288e0495 --- /dev/null +++ b/Windows/W32Util/DarkMode.h @@ -0,0 +1,109 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#include +#include +#include +#include +#include + +#include "IatHook.h" + +enum IMMERSIVE_HC_CACHE_MODE +{ + IHCM_USE_CACHED_VALUE, + IHCM_REFRESH +}; + +// 1903 18362 +enum PreferredAppMode +{ + Default, + AllowDark, + ForceDark, + ForceLight, + Max +}; + +enum WINDOWCOMPOSITIONATTRIB +{ + WCA_UNDEFINED = 0, + WCA_NCRENDERING_ENABLED = 1, + WCA_NCRENDERING_POLICY = 2, + WCA_TRANSITIONS_FORCEDISABLED = 3, + WCA_ALLOW_NCPAINT = 4, + WCA_CAPTION_BUTTON_BOUNDS = 5, + WCA_NONCLIENT_RTL_LAYOUT = 6, + WCA_FORCE_ICONIC_REPRESENTATION = 7, + WCA_EXTENDED_FRAME_BOUNDS = 8, + WCA_HAS_ICONIC_BITMAP = 9, + WCA_THEME_ATTRIBUTES = 10, + WCA_NCRENDERING_EXILED = 11, + WCA_NCADORNMENTINFO = 12, + WCA_EXCLUDED_FROM_LIVEPREVIEW = 13, + WCA_VIDEO_OVERLAY_ACTIVE = 14, + WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15, + WCA_DISALLOW_PEEK = 16, + WCA_CLOAK = 17, + WCA_CLOAKED = 18, + WCA_ACCENT_POLICY = 19, + WCA_FREEZE_REPRESENTATION = 20, + WCA_EVER_UNCLOAKED = 21, + WCA_VISUAL_OWNER = 22, + WCA_HOLOGRAPHIC = 23, + WCA_EXCLUDED_FROM_DDA = 24, + WCA_PASSIVEUPDATEMODE = 25, + WCA_USEDARKMODECOLORS = 26, + WCA_LAST = 27 +}; + +struct WINDOWCOMPOSITIONATTRIBDATA +{ + WINDOWCOMPOSITIONATTRIB Attrib; + PVOID pvData; + SIZE_T cbData; +}; + +using fnRtlGetNtVersionNumbers = void (WINAPI *)(LPDWORD major, LPDWORD minor, LPDWORD build); +using fnSetWindowCompositionAttribute = BOOL (WINAPI *)(HWND hWnd, WINDOWCOMPOSITIONATTRIBDATA*); +// 1809 17763 +using fnShouldAppsUseDarkMode = bool (WINAPI *)(); // ordinal 132 +using fnAllowDarkModeForWindow = bool (WINAPI *)(HWND hWnd, bool allow); // ordinal 133 +using fnAllowDarkModeForApp = bool (WINAPI *)(bool allow); // ordinal 135, in 1809 +using fnFlushMenuThemes = void (WINAPI *)(); // ordinal 136 +using fnRefreshImmersiveColorPolicyState = void (WINAPI *)(); // ordinal 104 +using fnIsDarkModeAllowedForWindow = bool (WINAPI *)(HWND hWnd); // ordinal 137 +using fnGetIsImmersiveColorUsingHighContrast = bool (WINAPI *)(IMMERSIVE_HC_CACHE_MODE mode); // ordinal 106 +using fnOpenNcThemeData = HTHEME(WINAPI *)(HWND hWnd, LPCWSTR pszClassList); // ordinal 49 +// 1903 18362 +using fnShouldSystemUseDarkMode = bool (WINAPI *)(); // ordinal 138 +using fnSetPreferredAppMode = PreferredAppMode (WINAPI *)(PreferredAppMode appMode); // ordinal 135, in 1903 +using fnIsDarkModeAllowedForApp = bool (WINAPI *)(); // ordinal 139 +using fnSetWindowTheme = void (WINAPI*)(HWND, LPCWSTR, LPCWSTR); +//--------------------------------------------------------------------------- + +extern fnSetWindowCompositionAttribute _SetWindowCompositionAttribute; +extern fnShouldAppsUseDarkMode _ShouldAppsUseDarkMode; +extern fnAllowDarkModeForWindow _AllowDarkModeForWindow; +extern fnAllowDarkModeForApp _AllowDarkModeForApp; +extern fnFlushMenuThemes _FlushMenuThemes; +extern fnRefreshImmersiveColorPolicyState _RefreshImmersiveColorPolicyState; +extern fnIsDarkModeAllowedForWindow _IsDarkModeAllowedForWindow; +extern fnGetIsImmersiveColorUsingHighContrast _GetIsImmersiveColorUsingHighContrast; +extern fnOpenNcThemeData _OpenNcThemeData; +// 1903 18362 +extern fnShouldSystemUseDarkMode _ShouldSystemUseDarkMode; +extern fnSetPreferredAppMode _SetPreferredAppMode; +extern fnSetWindowTheme _SetWindowTheme; + +extern bool g_darkModeSupported; +extern bool g_darkModeEnabled; + +void InitDarkMode(); +bool AllowDarkModeForWindow(HWND hWnd, bool allow); +void RefreshTitleBarThemeColor(HWND hWnd); +bool IsColorSchemeChangeMessage(LPARAM lParam); + +void DarkModeInitDialog(HWND hDlg); +LRESULT DarkModeDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); diff --git a/Windows/W32Util/IatHook.h b/Windows/W32Util/IatHook.h new file mode 100644 index 0000000000..1f259a5f20 --- /dev/null +++ b/Windows/W32Util/IatHook.h @@ -0,0 +1,91 @@ +// This file contains code from +// https://github.com/stevemk14ebr/PolyHook_2_0/blob/master/sources/IatHook.cpp +// which is licensed under the MIT License. +// See PolyHook_2_0-LICENSE for more information. + +#pragma once + +template +constexpr T RVA2VA(T1 base, T2 rva) +{ + return reinterpret_cast(reinterpret_cast(base) + rva); +} + +template +constexpr T DataDirectoryFromModuleBase(void *moduleBase, size_t entryID) +{ + auto dosHdr = reinterpret_cast(moduleBase); + auto ntHdr = RVA2VA(moduleBase, dosHdr->e_lfanew); + auto dataDir = ntHdr->OptionalHeader.DataDirectory; + return RVA2VA(moduleBase, dataDir[entryID].VirtualAddress); +} + +inline PIMAGE_THUNK_DATA FindAddressByName(void *moduleBase, PIMAGE_THUNK_DATA impName, PIMAGE_THUNK_DATA impAddr, const char *funcName) +{ + for (; impName->u1.Ordinal; ++impName, ++impAddr) + { + if (IMAGE_SNAP_BY_ORDINAL(impName->u1.Ordinal)) + continue; + + auto import = RVA2VA(moduleBase, impName->u1.AddressOfData); + if (strcmp(import->Name, funcName) != 0) + continue; + return impAddr; + } + return nullptr; +} + +inline PIMAGE_THUNK_DATA FindAddressByOrdinal(void *moduleBase, PIMAGE_THUNK_DATA impName, PIMAGE_THUNK_DATA impAddr, uint16_t ordinal) +{ + for (; impName->u1.Ordinal; ++impName, ++impAddr) + { + if (IMAGE_SNAP_BY_ORDINAL(impName->u1.Ordinal) && IMAGE_ORDINAL(impName->u1.Ordinal) == ordinal) + return impAddr; + } + return nullptr; +} + +inline PIMAGE_THUNK_DATA FindIatThunkInModule(void *moduleBase, const char *dllName, const char *funcName) +{ + auto imports = DataDirectoryFromModuleBase(moduleBase, IMAGE_DIRECTORY_ENTRY_IMPORT); + for (; imports->Name; ++imports) + { + if (_stricmp(RVA2VA(moduleBase, imports->Name), dllName) != 0) + continue; + + auto origThunk = RVA2VA(moduleBase, imports->OriginalFirstThunk); + auto thunk = RVA2VA(moduleBase, imports->FirstThunk); + return FindAddressByName(moduleBase, origThunk, thunk, funcName); + } + return nullptr; +} + +inline PIMAGE_THUNK_DATA FindDelayLoadThunkInModule(void *moduleBase, const char *dllName, const char *funcName) +{ + auto imports = DataDirectoryFromModuleBase(moduleBase, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT); + for (; imports->DllNameRVA; ++imports) + { + if (_stricmp(RVA2VA(moduleBase, imports->DllNameRVA), dllName) != 0) + continue; + + auto impName = RVA2VA(moduleBase, imports->ImportNameTableRVA); + auto impAddr = RVA2VA(moduleBase, imports->ImportAddressTableRVA); + return FindAddressByName(moduleBase, impName, impAddr, funcName); + } + return nullptr; +} + +inline PIMAGE_THUNK_DATA FindDelayLoadThunkInModule(void *moduleBase, const char *dllName, uint16_t ordinal) +{ + auto imports = DataDirectoryFromModuleBase(moduleBase, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT); + for (; imports->DllNameRVA; ++imports) + { + if (_stricmp(RVA2VA(moduleBase, imports->DllNameRVA), dllName) != 0) + continue; + + auto impName = RVA2VA(moduleBase, imports->ImportNameTableRVA); + auto impAddr = RVA2VA(moduleBase, imports->ImportAddressTableRVA); + return FindAddressByOrdinal(moduleBase, impName, impAddr, ordinal); + } + return nullptr; +} diff --git a/Windows/main.cpp b/Windows/main.cpp index ebfff8b6dc..35cf5436e3 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -42,6 +42,7 @@ #include "Common/Thread/ThreadUtil.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/Net/Resolve.h" +#include "W32Util/DarkMode.h" #include "Core/Config.h" #include "Core/ConfigValues.h" @@ -553,6 +554,8 @@ static void WinMainInit() { // FMA3 support in the 2013 CRT is broken on Vista and Windows 7 RTM (fixed in SP1). Just disable it. _set_FMA3_enable(0); #endif + + InitDarkMode(); } static void WinMainCleanup() {