From 0fde8356296ce5d97cc371a5fd54f0ad8b6f44da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 2 Jan 2025 14:01:44 +0800 Subject: [PATCH] WM (Windows): detect version of DWM --- CMakeLists.txt | 1 + src/detection/terminalshell/terminalshell.c | 49 +++++-------------- .../terminalshell/terminalshell_windows.c | 30 +----------- src/detection/wm/wm_windows.cpp | 19 ++++++- src/util/platform/FFPlatform_windows.c | 12 ++--- src/util/windows/version.c | 31 ++++++++++++ src/util/windows/version.h | 3 ++ 7 files changed, 74 insertions(+), 71 deletions(-) create mode 100644 src/util/windows/version.c create mode 100644 src/util/windows/version.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d4b1cd98d..405508d4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1003,6 +1003,7 @@ elseif(WIN32) src/util/windows/registry.c src/util/windows/unicode.c src/util/windows/wmi.cpp + src/util/windows/version.c src/util/platform/FFPlatform_windows.c src/util/binary_windows.c ) diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c index a591829a2..fb1717043 100644 --- a/src/detection/terminalshell/terminalshell.c +++ b/src/detection/terminalshell/terminalshell.c @@ -15,41 +15,18 @@ #define _PATH_LOCALBASE "/usr/local" #elif __NetBSD__ #define _PATH_LOCALBASE "/usr/pkg" -#endif +#elif _WIN32 -#ifdef _WIN32 +#include "util/windows/version.h" +#include -#include "util/mallocHelper.h" - -#include - -static bool getFileVersion(const char* exePath, FFstrbuf* version) +static bool getFileVersion(const FFstrbuf* exePath, FFstrbuf* version) { - DWORD handle; - DWORD size = GetFileVersionInfoSizeA(exePath, &handle); - if(size > 0) - { - FF_AUTO_FREE void* versionData = malloc(size); - if(GetFileVersionInfoA(exePath, handle, size, versionData)) - { - VS_FIXEDFILEINFO* verInfo; - UINT len; - if(VerQueryValueW(versionData, L"\\", (void**)&verInfo, &len) && len && verInfo->dwSignature == 0xFEEF04BD) - { - ffStrbufAppendF(version, "%u.%u.%u.%u", - (unsigned)(( verInfo->dwFileVersionMS >> 16 ) & 0xffff), - (unsigned)(( verInfo->dwFileVersionMS >> 0 ) & 0xffff), - (unsigned)(( verInfo->dwFileVersionLS >> 16 ) & 0xffff), - (unsigned)(( verInfo->dwFileVersionLS >> 0 ) & 0xffff) - ); - return true; - } - } - } - - return false; + wchar_t exePathW[PATH_MAX]; + int len = MultiByteToWideChar(CP_UTF8, 0, exePath->chars, (int)exePath->length, exePathW, ARRAY_SIZE(exePathW)); + if (len <= 0) return false; + return ffGetFileVersion(exePathW, version); } - #endif static bool getExeVersionRaw(FFstrbuf* exe, FFstrbuf* version) @@ -119,7 +96,7 @@ static bool getShellVersionPwsh(FFstrbuf* exe, FFstrbuf* version) } #ifdef _WIN32 - if(getFileVersion(exe->chars, version)) + if(getFileVersion(exe, version)) { ffStrbufSubstrBeforeLastC(version, '.'); return true; @@ -312,7 +289,7 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* exePath, if(ffStrEqualsIgnCase(exeName, "powershell") || ffStrEqualsIgnCase(exeName, "powershell_ise")) return getShellVersionWinPowerShell(exe, version); - return getFileVersion(exe->chars, version); + return getFileVersion(exe, version); #endif return false; @@ -706,7 +683,7 @@ static bool getTerminalVersionWindowsTerminal(FFstrbuf* exe, FFstrbuf* version) return true; } - return getFileVersion(exe->chars, version); + return getFileVersion(exe, version); } static bool getTerminalVersionConEmu(FFstrbuf* exe, FFstrbuf* version) @@ -716,7 +693,7 @@ static bool getTerminalVersionConEmu(FFstrbuf* exe, FFstrbuf* version) if(version->length) return true; - return getFileVersion(exe->chars, version); + return getFileVersion(exe, version); } #endif @@ -875,7 +852,7 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe #ifdef _WIN32 - return getFileVersion(exe->chars, version); + return getFileVersion(exe, version); #else diff --git a/src/detection/terminalshell/terminalshell_windows.c b/src/detection/terminalshell/terminalshell_windows.c index ca567bcc0..97bfe1820 100644 --- a/src/detection/terminalshell/terminalshell_windows.c +++ b/src/detection/terminalshell/terminalshell_windows.c @@ -5,39 +5,13 @@ #include "util/mallocHelper.h" #include "util/windows/registry.h" #include "util/windows/unicode.h" +#include "util/windows/version.h" #include "util/stringUtils.h" #include #include #include -static bool getProductVersion(const wchar_t* filePath, FFstrbuf* version) -{ - DWORD handle; - DWORD size = GetFileVersionInfoSizeW(filePath, &handle); - if(size > 0) - { - FF_AUTO_FREE void* versionData = malloc(size); - if(GetFileVersionInfoW(filePath, handle, size, versionData)) - { - VS_FIXEDFILEINFO* verInfo; - UINT len; - if(VerQueryValueW(versionData, L"\\", (void**)&verInfo, &len) && len && verInfo->dwSignature == 0xFEEF04BD) - { - ffStrbufAppendF(version, "%u.%u.%u.%u", - (unsigned)(( verInfo->dwProductVersionMS >> 16 ) & 0xffff), - (unsigned)(( verInfo->dwProductVersionMS >> 0 ) & 0xffff), - (unsigned)(( verInfo->dwProductVersionLS >> 16 ) & 0xffff), - (unsigned)(( verInfo->dwProductVersionLS >> 0 ) & 0xffff) - ); - return true; - } - } - } - - return false; -} - bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, const FFstrbuf* exePath, FFstrbuf* version); static uint32_t getShellInfo(FFShellResult* result, uint32_t pid) @@ -113,7 +87,7 @@ static void setShellInfoDetails(FFShellResult* result) if(wcsncmp(module.szModule, L"clink_dll_", strlen("clink_dll_")) == 0) { ffStrbufAppendS(&result->prettyName, " (with Clink "); - getProductVersion(module.szExePath, &result->prettyName); + ffGetFileVersion(module.szExePath, &result->prettyName); ffStrbufAppendC(&result->prettyName, ')'); break; } diff --git a/src/detection/wm/wm_windows.cpp b/src/detection/wm/wm_windows.cpp index f784d3b62..e11196805 100644 --- a/src/detection/wm/wm_windows.cpp +++ b/src/detection/wm/wm_windows.cpp @@ -3,6 +3,7 @@ extern "C" #include "wm.h" #include "common/io/io.h" #include "detection/terminalshell/terminalshell.h" +#include "util/windows/version.h" } #include "util/windows/com.hpp" @@ -65,7 +66,23 @@ const char* ffDetectWMPlugin(FFstrbuf* pluginName) return NULL; } -const char* ffDetectWMVersion(FF_MAYBE_UNUSED const FFstrbuf* wmName, FF_MAYBE_UNUSED FFstrbuf* result, FF_MAYBE_UNUSED FFWMOptions* options) +const char* ffDetectWMVersion(const FFstrbuf* wmName, FFstrbuf* result, FF_MAYBE_UNUSED FFWMOptions* options) { + if (!wmName) + return "No WM detected"; + + if (ffStrbufEqualS(wmName, "dwm.exe")) + { + PWSTR pPath = NULL; + if(SUCCEEDED(SHGetKnownFolderPath(FOLDERID_System, KF_FLAG_DEFAULT, NULL, &pPath))) + { + wchar_t fullPath[MAX_PATH]; + wcscpy(fullPath, pPath); + wcscat(fullPath, L"\\dwm.exe"); + ffGetFileVersion(fullPath, result); + } + CoTaskMemFree(pPath); + return NULL; + } return "Not supported on this platform"; } diff --git a/src/util/platform/FFPlatform_windows.c b/src/util/platform/FFPlatform_windows.c index 5357bde3d..71feae3f3 100644 --- a/src/util/platform/FFPlatform_windows.c +++ b/src/util/platform/FFPlatform_windows.c @@ -31,13 +31,12 @@ static void getExePath(FFPlatform* platform) static void getHomeDir(FFPlatform* platform) { - PWSTR pPath; + PWSTR pPath = NULL; if(SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_Profile, KF_FLAG_DEFAULT, NULL, &pPath))) { ffStrbufSetWS(&platform->homeDir, pPath); ffStrbufReplaceAllC(&platform->homeDir, '\\', '/'); ffStrbufEnsureEndsWithC(&platform->homeDir, '/'); - CoTaskMemFree(pPath); } else { @@ -45,28 +44,29 @@ static void getHomeDir(FFPlatform* platform) ffStrbufReplaceAllC(&platform->homeDir, '\\', '/'); ffStrbufEnsureEndsWithC(&platform->homeDir, '/'); } + CoTaskMemFree(pPath); } static void getCacheDir(FFPlatform* platform) { - PWSTR pPath; + PWSTR pPath = NULL; if(SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_LocalAppData, KF_FLAG_DEFAULT, NULL, &pPath))) { ffStrbufSetWS(&platform->cacheDir, pPath); ffStrbufReplaceAllC(&platform->cacheDir, '\\', '/'); ffStrbufEnsureEndsWithC(&platform->cacheDir, '/'); - CoTaskMemFree(pPath); } else { ffStrbufAppend(&platform->cacheDir, &platform->homeDir); ffStrbufAppendS(&platform->cacheDir, "AppData/Local/"); } + CoTaskMemFree(pPath); } static void platformPathAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId) { - PWSTR pPath; + PWSTR pPath = NULL; if(SUCCEEDED(SHGetKnownFolderPath(folderId, 0, NULL, &pPath))) { FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateWS(pPath); @@ -74,8 +74,8 @@ static void platformPathAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId) ffStrbufEnsureEndsWithC(&buffer, '/'); if (!ffListContains(dirs, &buffer, (void*) ffStrbufEqual)) ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer); - CoTaskMemFree(pPath); } + CoTaskMemFree(pPath); } static void platformPathAddEnvSuffix(FFlist* dirs, const char* env, const char* suffix) diff --git a/src/util/windows/version.c b/src/util/windows/version.c new file mode 100644 index 000000000..e01fe27a1 --- /dev/null +++ b/src/util/windows/version.c @@ -0,0 +1,31 @@ +#include "util/windows/version.h" +#include "util/mallocHelper.h" + +#include + +bool ffGetFileVersion(const wchar_t* filePath, FFstrbuf* version) +{ + DWORD handle; + DWORD size = GetFileVersionInfoSizeW(filePath, &handle); + if(size > 0) + { + FF_AUTO_FREE void* versionData = malloc(size); + if(GetFileVersionInfoW(filePath, handle, size, versionData)) + { + VS_FIXEDFILEINFO* verInfo; + UINT len; + if(VerQueryValueW(versionData, L"\\", (void**)&verInfo, &len) && len && verInfo->dwSignature == 0xFEEF04BD) + { + ffStrbufAppendF(version, "%u.%u.%u.%u", + (unsigned)(( verInfo->dwProductVersionMS >> 16 ) & 0xffff), + (unsigned)(( verInfo->dwProductVersionMS >> 0 ) & 0xffff), + (unsigned)(( verInfo->dwProductVersionLS >> 16 ) & 0xffff), + (unsigned)(( verInfo->dwProductVersionLS >> 0 ) & 0xffff) + ); + return true; + } + } + } + + return false; +} diff --git a/src/util/windows/version.h b/src/util/windows/version.h new file mode 100644 index 000000000..c6206fa5b --- /dev/null +++ b/src/util/windows/version.h @@ -0,0 +1,3 @@ +#include "fastfetch.h" + +bool ffGetFileVersion(const wchar_t* filePath, FFstrbuf* version);