mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:14:37 +02:00
WM (Windows): detect FancyWM & GlazeWM and their versions
This commit is contained in:
+2
-1
@@ -1068,7 +1068,7 @@ elseif(WIN32)
|
||||
src/detection/users/users_windows.c
|
||||
src/detection/wallpaper/wallpaper_windows.c
|
||||
src/detection/wifi/wifi_windows.c
|
||||
src/detection/wm/wm_windows.cpp
|
||||
src/detection/wm/wm_windows.c
|
||||
src/detection/de/de_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_windows.c
|
||||
src/detection/camera/camera_windows.cpp
|
||||
@@ -1729,6 +1729,7 @@ elseif(WIN32)
|
||||
PRIVATE "cfgmgr32"
|
||||
PRIVATE "propsys"
|
||||
PRIVATE "secur32"
|
||||
PRIVATE "wintrust"
|
||||
)
|
||||
if(NOT ENABLE_WIN7_COMPAT)
|
||||
target_link_libraries(libfastfetch
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
#include "wm.h"
|
||||
#include "common/mallocHelper.h"
|
||||
#include "common/windows/version.h"
|
||||
#include "common/io.h"
|
||||
|
||||
#include <stdalign.h>
|
||||
#include <windows.h>
|
||||
#include <ntstatus.h>
|
||||
#include <winternl.h>
|
||||
#include <shlobj.h>
|
||||
#include <softpub.h>
|
||||
|
||||
bool isProcessTrusted(DWORD processId, UNICODE_STRING* buffer, size_t bufSize)
|
||||
{
|
||||
FF_AUTO_CLOSE_FD HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId);
|
||||
if (!hProcess)
|
||||
return false;
|
||||
|
||||
ULONG size;
|
||||
if(!NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessImageFileNameWin32, buffer, (ULONG) bufSize, &size)) ||
|
||||
buffer->Length == 0) return false;
|
||||
assert(buffer->MaximumLength >= buffer->Length + 2); // NULL terminated
|
||||
|
||||
static wchar_t windowsAppsPath[MAX_PATH];
|
||||
static uint32_t windowsAppsPathLen;
|
||||
if (windowsAppsPathLen == 0)
|
||||
{
|
||||
PWSTR pPath = NULL;
|
||||
if(SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_ProgramFiles, KF_FLAG_DEFAULT, NULL, &pPath)))
|
||||
{
|
||||
windowsAppsPathLen = (uint32_t) wcslen(pPath);
|
||||
memcpy(windowsAppsPath, pPath, windowsAppsPathLen * sizeof(wchar_t));
|
||||
memcpy(windowsAppsPath + windowsAppsPathLen, L"\\WindowsApps\\", sizeof(L"\\WindowsApps\\"));
|
||||
windowsAppsPathLen += strlen("\\WindowsApps\\");
|
||||
}
|
||||
else
|
||||
{
|
||||
windowsAppsPathLen = -1u;
|
||||
}
|
||||
CoTaskMemFree(pPath);
|
||||
}
|
||||
if (windowsAppsPathLen != -1u &&
|
||||
buffer->Length > windowsAppsPathLen * sizeof(wchar_t) &&
|
||||
_wcsnicmp(buffer->Buffer, windowsAppsPath, windowsAppsPathLen) == 0
|
||||
) return true; // Always trust Windows Store apps, in case the exe is not signed (FancyWM-GUI)
|
||||
|
||||
WINTRUST_FILE_INFO fileInfo = {
|
||||
.cbStruct = sizeof(fileInfo),
|
||||
.pcwszFilePath = buffer->Buffer,
|
||||
};
|
||||
|
||||
GUID actionID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
|
||||
|
||||
WINTRUST_DATA trustData = {
|
||||
.cbStruct = sizeof(trustData),
|
||||
.dwUIChoice = WTD_UI_NONE,
|
||||
.fdwRevocationChecks = WTD_REVOKE_NONE,
|
||||
.dwUnionChoice = WTD_CHOICE_FILE,
|
||||
.pFile = &fileInfo,
|
||||
.dwStateAction = WTD_STATEACTION_VERIFY,
|
||||
.dwProvFlags = WTD_SAFER_FLAG,
|
||||
};
|
||||
|
||||
LONG status = WinVerifyTrustEx(NULL, &actionID, &trustData);
|
||||
trustData.dwStateAction = WTD_STATEACTION_CLOSE;
|
||||
WinVerifyTrust(NULL, &actionID, &trustData);
|
||||
|
||||
return status == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
const char* ffDetectWMPlugin(FFstrbuf* pluginName)
|
||||
{
|
||||
alignas(UNICODE_STRING) uint8_t buffer[4096];
|
||||
UNICODE_STRING* filePath = (UNICODE_STRING*) buffer;
|
||||
SYSTEM_PROCESS_INFORMATION* FF_AUTO_FREE pstart = NULL;
|
||||
|
||||
// Multiple attempts in case processes change while
|
||||
// we are in the middle of querying them.
|
||||
ULONG size = 0;
|
||||
for (int attempts = 0;; ++attempts)
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
pstart = (SYSTEM_PROCESS_INFORMATION*)realloc(pstart, size);
|
||||
assert(pstart);
|
||||
}
|
||||
NTSTATUS status = NtQuerySystemInformation(SystemProcessInformation, pstart, size, &size);
|
||||
if(NT_SUCCESS(status))
|
||||
break;
|
||||
else if(status == STATUS_INFO_LENGTH_MISMATCH && attempts < 4)
|
||||
size += sizeof(SYSTEM_PROCESS_INFORMATION) * 5;
|
||||
else
|
||||
return "NtQuerySystemInformation(SystemProcessInformation) failed";
|
||||
}
|
||||
|
||||
for (SYSTEM_PROCESS_INFORMATION* ptr = pstart; ptr->NextEntryOffset; ptr = (SYSTEM_PROCESS_INFORMATION*)((uint8_t*)ptr + ptr->NextEntryOffset))
|
||||
{
|
||||
assert(ptr->ImageName.Length == 0 || ptr->ImageName.MaximumLength >= ptr->ImageName.Length + 2); // NULL terminated
|
||||
if (ptr->ImageName.Length == strlen("FancyWM-GUI.exe") * sizeof(wchar_t) &&
|
||||
memcmp(ptr->ImageName.Buffer, L"FancyWM-GUI.exe", ptr->ImageName.Length) == 0 &&
|
||||
isProcessTrusted((DWORD) (uintptr_t) ptr->UniqueProcessId, filePath, sizeof(buffer))
|
||||
) {
|
||||
if (ffGetFileVersion(filePath->Buffer, NULL, pluginName))
|
||||
ffStrbufPrependS(pluginName, "FancyWM ");
|
||||
else
|
||||
ffStrbufSetStatic(pluginName, "FancyWM");
|
||||
break;
|
||||
}
|
||||
else if (ptr->ImageName.Length == strlen("glazewm-watcher.exe") * sizeof(wchar_t) &&
|
||||
memcmp(ptr->ImageName.Buffer, L"glazewm-watcher.exe", ptr->ImageName.Length) == 0 &&
|
||||
isProcessTrusted((DWORD) (uintptr_t) ptr->UniqueProcessId, filePath, sizeof(buffer))
|
||||
) {
|
||||
if (ffGetFileVersion(filePath->Buffer, NULL, pluginName))
|
||||
ffStrbufPrependS(pluginName, "GlazeWM ");
|
||||
else
|
||||
ffStrbufSetStatic(pluginName, "GlazeWM");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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, NULL, result);
|
||||
}
|
||||
CoTaskMemFree(pPath);
|
||||
return NULL;
|
||||
}
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
extern "C"
|
||||
{
|
||||
#include "wm.h"
|
||||
#include "common/io.h"
|
||||
#include "common/windows/version.h"
|
||||
#include "detection/terminalshell/terminalshell.h"
|
||||
}
|
||||
|
||||
#include "common/windows/com.hpp"
|
||||
#include "common/windows/util.hpp"
|
||||
|
||||
#include <windows.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <shlobj.h>
|
||||
#include <propkey.h>
|
||||
|
||||
extern "C"
|
||||
const char* ffDetectWMPlugin(FFstrbuf* pluginName)
|
||||
{
|
||||
DWORD pid = ffDetectTerminal()->pid; // Whatever GUI program
|
||||
if (pid == 0) return "Unable to find a GUI program";
|
||||
|
||||
FF_AUTO_CLOSE_FD HANDLE snapshot = NULL;
|
||||
while(!(snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid)) && GetLastError() == ERROR_BAD_LENGTH) {}
|
||||
|
||||
if(!snapshot)
|
||||
return "CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid) failed";
|
||||
|
||||
if (ffInitCom())
|
||||
return "ffInitCom() failed";
|
||||
|
||||
MODULEENTRY32W module;
|
||||
module.dwSize = sizeof(module);
|
||||
for(BOOL success = Module32FirstW(snapshot, &module); success; success = Module32NextW(snapshot, &module))
|
||||
{
|
||||
if(wcscmp(module.szModule, L"wbhelp64.dll") == 0 || wcscmp(module.szModule, L"wbhelp.dll") == 0)
|
||||
{
|
||||
IShellItem2* shellItem = NULL;
|
||||
if (FAILED(SHCreateItemFromParsingName(module.szExePath, NULL, IID_IShellItem2, (void**) &shellItem)))
|
||||
continue;
|
||||
|
||||
on_scope_exit destroyShellItem([=] { shellItem->Release(); });
|
||||
|
||||
wchar_t* desc = NULL;
|
||||
if (FAILED(shellItem->GetString(PKEY_FileDescription, &desc)))
|
||||
continue;
|
||||
|
||||
on_scope_exit destroyDesc([=] { CoTaskMemFree(desc); });
|
||||
|
||||
if (wcscmp(desc, L"WindowBlinds Helper DLL") == 0)
|
||||
{
|
||||
ffStrbufSetStatic(pluginName, "WindowBlinds");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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, NULL, result);
|
||||
}
|
||||
CoTaskMemFree(pPath);
|
||||
return NULL;
|
||||
}
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
Reference in New Issue
Block a user