Skip to content

Commit 92ada88

Browse files
committed
WM (Windows): detect FancyWM & GlazeWM and their versions
1 parent 1789ef8 commit 92ada88

File tree

3 files changed

+145
-80
lines changed

3 files changed

+145
-80
lines changed

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,7 @@ elseif(WIN32)
10681068
src/detection/users/users_windows.c
10691069
src/detection/wallpaper/wallpaper_windows.c
10701070
src/detection/wifi/wifi_windows.c
1071-
src/detection/wm/wm_windows.cpp
1071+
src/detection/wm/wm_windows.c
10721072
src/detection/de/de_nosupport.c
10731073
src/detection/wmtheme/wmtheme_windows.c
10741074
src/detection/camera/camera_windows.cpp
@@ -1729,6 +1729,7 @@ elseif(WIN32)
17291729
PRIVATE "cfgmgr32"
17301730
PRIVATE "propsys"
17311731
PRIVATE "secur32"
1732+
PRIVATE "wintrust"
17321733
)
17331734
if(NOT ENABLE_WIN7_COMPAT)
17341735
target_link_libraries(libfastfetch

src/detection/wm/wm_windows.c

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
#include "wm.h"
2+
#include "common/mallocHelper.h"
3+
#include "common/windows/version.h"
4+
#include "common/io.h"
5+
6+
#include <stdalign.h>
7+
#include <windows.h>
8+
#include <ntstatus.h>
9+
#include <winternl.h>
10+
#include <shlobj.h>
11+
#include <softpub.h>
12+
13+
bool isProcessTrusted(DWORD processId, UNICODE_STRING* buffer, size_t bufSize)
14+
{
15+
FF_AUTO_CLOSE_FD HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId);
16+
if (!hProcess)
17+
return false;
18+
19+
ULONG size;
20+
if(!NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessImageFileNameWin32, buffer, (ULONG) bufSize, &size)) ||
21+
buffer->Length == 0) return false;
22+
assert(buffer->MaximumLength >= buffer->Length + 2); // NULL terminated
23+
24+
static wchar_t windowsAppsPath[MAX_PATH];
25+
static uint32_t windowsAppsPathLen;
26+
if (windowsAppsPathLen == 0)
27+
{
28+
PWSTR pPath = NULL;
29+
if(SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_ProgramFiles, KF_FLAG_DEFAULT, NULL, &pPath)))
30+
{
31+
windowsAppsPathLen = (uint32_t) wcslen(pPath);
32+
memcpy(windowsAppsPath, pPath, windowsAppsPathLen * sizeof(wchar_t));
33+
memcpy(windowsAppsPath + windowsAppsPathLen, L"\\WindowsApps\\", sizeof(L"\\WindowsApps\\"));
34+
windowsAppsPathLen += strlen("\\WindowsApps\\");
35+
}
36+
else
37+
{
38+
windowsAppsPathLen = -1u;
39+
}
40+
CoTaskMemFree(pPath);
41+
}
42+
if (windowsAppsPathLen != -1u &&
43+
buffer->Length > windowsAppsPathLen * sizeof(wchar_t) &&
44+
_wcsnicmp(buffer->Buffer, windowsAppsPath, windowsAppsPathLen) == 0
45+
) return true; // Always trust Windows Store apps, in case the exe is not signed (FancyWM-GUI)
46+
47+
WINTRUST_FILE_INFO fileInfo = {
48+
.cbStruct = sizeof(fileInfo),
49+
.pcwszFilePath = buffer->Buffer,
50+
};
51+
52+
GUID actionID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
53+
54+
WINTRUST_DATA trustData = {
55+
.cbStruct = sizeof(trustData),
56+
.dwUIChoice = WTD_UI_NONE,
57+
.fdwRevocationChecks = WTD_REVOKE_NONE,
58+
.dwUnionChoice = WTD_CHOICE_FILE,
59+
.pFile = &fileInfo,
60+
.dwStateAction = WTD_STATEACTION_VERIFY,
61+
.dwProvFlags = WTD_SAFER_FLAG,
62+
};
63+
64+
LONG status = WinVerifyTrustEx(NULL, &actionID, &trustData);
65+
trustData.dwStateAction = WTD_STATEACTION_CLOSE;
66+
WinVerifyTrust(NULL, &actionID, &trustData);
67+
68+
return status == ERROR_SUCCESS;
69+
}
70+
71+
const char* ffDetectWMPlugin(FFstrbuf* pluginName)
72+
{
73+
alignas(UNICODE_STRING) uint8_t buffer[4096];
74+
UNICODE_STRING* filePath = (UNICODE_STRING*) buffer;
75+
SYSTEM_PROCESS_INFORMATION* FF_AUTO_FREE pstart = NULL;
76+
77+
// Multiple attempts in case processes change while
78+
// we are in the middle of querying them.
79+
ULONG size = 0;
80+
for (int attempts = 0;; ++attempts)
81+
{
82+
if (size)
83+
{
84+
pstart = (SYSTEM_PROCESS_INFORMATION*)realloc(pstart, size);
85+
assert(pstart);
86+
}
87+
NTSTATUS status = NtQuerySystemInformation(SystemProcessInformation, pstart, size, &size);
88+
if(NT_SUCCESS(status))
89+
break;
90+
else if(status == STATUS_INFO_LENGTH_MISMATCH && attempts < 4)
91+
size += sizeof(SYSTEM_PROCESS_INFORMATION) * 5;
92+
else
93+
return "NtQuerySystemInformation(SystemProcessInformation) failed";
94+
}
95+
96+
for (SYSTEM_PROCESS_INFORMATION* ptr = pstart; ptr->NextEntryOffset; ptr = (SYSTEM_PROCESS_INFORMATION*)((uint8_t*)ptr + ptr->NextEntryOffset))
97+
{
98+
assert(ptr->ImageName.Length == 0 || ptr->ImageName.MaximumLength >= ptr->ImageName.Length + 2); // NULL terminated
99+
if (ptr->ImageName.Length == strlen("FancyWM-GUI.exe") * sizeof(wchar_t) &&
100+
memcmp(ptr->ImageName.Buffer, L"FancyWM-GUI.exe", ptr->ImageName.Length) == 0 &&
101+
isProcessTrusted((DWORD) (uintptr_t) ptr->UniqueProcessId, filePath, sizeof(buffer))
102+
) {
103+
if (ffGetFileVersion(filePath->Buffer, NULL, pluginName))
104+
ffStrbufPrependS(pluginName, "FancyWM ");
105+
else
106+
ffStrbufSetStatic(pluginName, "FancyWM");
107+
break;
108+
}
109+
else if (ptr->ImageName.Length == strlen("glazewm-watcher.exe") * sizeof(wchar_t) &&
110+
memcmp(ptr->ImageName.Buffer, L"glazewm-watcher.exe", ptr->ImageName.Length) == 0 &&
111+
isProcessTrusted((DWORD) (uintptr_t) ptr->UniqueProcessId, filePath, sizeof(buffer))
112+
) {
113+
if (ffGetFileVersion(filePath->Buffer, NULL, pluginName))
114+
ffStrbufPrependS(pluginName, "GlazeWM ");
115+
else
116+
ffStrbufSetStatic(pluginName, "GlazeWM");
117+
break;
118+
}
119+
}
120+
121+
return NULL;
122+
}
123+
124+
const char* ffDetectWMVersion(const FFstrbuf* wmName, FFstrbuf* result, FF_MAYBE_UNUSED FFWMOptions* options)
125+
{
126+
if (!wmName)
127+
return "No WM detected";
128+
129+
if (ffStrbufEqualS(wmName, "dwm.exe"))
130+
{
131+
PWSTR pPath = NULL;
132+
if(SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_System, KF_FLAG_DEFAULT, NULL, &pPath)))
133+
{
134+
wchar_t fullPath[MAX_PATH];
135+
wcscpy(fullPath, pPath);
136+
wcscat(fullPath, L"\\dwm.exe");
137+
ffGetFileVersion(fullPath, NULL, result);
138+
}
139+
CoTaskMemFree(pPath);
140+
return NULL;
141+
}
142+
return "Not supported on this platform";
143+
}

src/detection/wm/wm_windows.cpp

Lines changed: 0 additions & 79 deletions
This file was deleted.

0 commit comments

Comments
 (0)