mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
WM (Windows): supports komorebi detection
This commit is contained in:
@@ -278,3 +278,54 @@ typedef struct _CURDIR
|
||||
} CURDIR, *PCURDIR;
|
||||
|
||||
PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader(IN PVOID BaseOfImage);
|
||||
|
||||
/**
|
||||
* The SECTION_IMAGE_INFORMATION structure contains detailed information about an image section.
|
||||
*/
|
||||
typedef struct _SECTION_IMAGE_INFORMATION
|
||||
{
|
||||
PVOID TransferAddress; // The address of the image entry point function.
|
||||
ULONG ZeroBits; // The number of high-order address bits that must be zero in the image base address.
|
||||
SIZE_T MaximumStackSize; // The maximum stack size of threads from the PE file header.
|
||||
SIZE_T CommittedStackSize; // The initial stack size of threads from the PE file header.
|
||||
ULONG SubSystemType; // The image subsystem from the PE file header (e.g., Windows GUI, Windows CUI, POSIX).
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
USHORT SubSystemMinorVersion;
|
||||
USHORT SubSystemMajorVersion;
|
||||
};
|
||||
ULONG SubSystemVersion;
|
||||
};
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
USHORT MajorOperatingSystemVersion;
|
||||
USHORT MinorOperatingSystemVersion;
|
||||
};
|
||||
ULONG OperatingSystemVersion;
|
||||
};
|
||||
USHORT ImageCharacteristics; // The image characteristics from the PE file header.
|
||||
USHORT DllCharacteristics; // The DLL characteristics flags (e.g., ASLR, NX compatibility).
|
||||
USHORT Machine; // The image architecture (e.g., x86, x64, ARM).
|
||||
BOOLEAN ImageContainsCode; // The image contains native executable code.
|
||||
union
|
||||
{
|
||||
UCHAR ImageFlags;
|
||||
struct
|
||||
{
|
||||
UCHAR ComPlusNativeReady : 1; // The image contains precompiled .NET assembly generated by NGEN (Native Image Generator).
|
||||
UCHAR ComPlusILOnly : 1; // the image contains only Microsoft Intermediate Language (IL) assembly.
|
||||
UCHAR ImageDynamicallyRelocated : 1; // The image was mapped using a random base address rather than the preferred base address.
|
||||
UCHAR ImageMappedFlat : 1; // The image was mapped using a single contiguous region, rather than separate regions for each section.
|
||||
UCHAR BaseBelow4gb : 1; // The image was mapped using a base address below the 4 GB boundary.
|
||||
UCHAR ComPlusPrefer32bit : 1; // The image prefers to run as a 32-bit process, even on a 64-bit system.
|
||||
UCHAR Reserved : 2;
|
||||
};
|
||||
};
|
||||
ULONG LoaderFlags; // Reserved by ntdll.dll for the Windows loader.
|
||||
ULONG ImageFileSize; // The size of the image, in bytes, including all headers.
|
||||
ULONG CheckSum; // The image file checksum, from the PE optional header.
|
||||
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#include "wm.h"
|
||||
#include "common/mallocHelper.h"
|
||||
#include "common/windows/version.h"
|
||||
#include "common/io.h"
|
||||
#include "common/processing.h"
|
||||
#include "common/windows/nt.h"
|
||||
#include "common/windows/unicode.h"
|
||||
#include "common/windows/version.h"
|
||||
|
||||
#include <stdalign.h>
|
||||
#include <windows.h>
|
||||
@@ -10,7 +13,15 @@
|
||||
#include <shlobj.h>
|
||||
#include <softpub.h>
|
||||
|
||||
bool isProcessTrusted(DWORD processId, UNICODE_STRING* buffer, size_t bufSize)
|
||||
typedef enum {
|
||||
FF_PROCESS_TYPE_NONE,
|
||||
FF_PROCESS_TYPE_SIGNED = 1 << 0,
|
||||
FF_PROCESS_TYPE_WINDOWS_STORE = 1 << 1,
|
||||
FF_PROCESS_TYPE_GUI = 1 << 2,
|
||||
FF_PROCESS_TYPE_CUI = 1 << 3,
|
||||
} FFProcessType;
|
||||
|
||||
bool isProcessTrusted(DWORD processId, FFProcessType processType, UNICODE_STRING* buffer, size_t bufSize)
|
||||
{
|
||||
FF_AUTO_CLOSE_FD HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId);
|
||||
if (!hProcess)
|
||||
@@ -21,51 +32,72 @@ bool isProcessTrusted(DWORD processId, UNICODE_STRING* buffer, size_t bufSize)
|
||||
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)
|
||||
if (processType & FF_PROCESS_TYPE_WINDOWS_STORE)
|
||||
{
|
||||
PWSTR pPath = NULL;
|
||||
if(SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_ProgramFiles, KF_FLAG_DEFAULT, NULL, &pPath)))
|
||||
static wchar_t windowsAppsPath[MAX_PATH];
|
||||
static uint32_t windowsAppsPathLen;
|
||||
if (windowsAppsPathLen == 0)
|
||||
{
|
||||
windowsAppsPathLen = (uint32_t) wcslen(pPath);
|
||||
memcpy(windowsAppsPath, pPath, windowsAppsPathLen * sizeof(wchar_t));
|
||||
memcpy(windowsAppsPath + windowsAppsPathLen, L"\\WindowsApps\\", sizeof(L"\\WindowsApps\\"));
|
||||
windowsAppsPathLen += strlen("\\WindowsApps\\");
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
windowsAppsPathLen = -1u;
|
||||
}
|
||||
CoTaskMemFree(pPath);
|
||||
if (windowsAppsPathLen != -1u &&
|
||||
buffer->Length > windowsAppsPathLen * sizeof(wchar_t) &&
|
||||
_wcsnicmp(buffer->Buffer, windowsAppsPath, windowsAppsPathLen) != 0
|
||||
) return false;
|
||||
}
|
||||
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,
|
||||
};
|
||||
if (processType & FF_PROCESS_TYPE_SIGNED)
|
||||
{
|
||||
WINTRUST_FILE_INFO fileInfo = {
|
||||
.cbStruct = sizeof(fileInfo),
|
||||
.pcwszFilePath = buffer->Buffer,
|
||||
};
|
||||
|
||||
GUID actionID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
|
||||
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,
|
||||
};
|
||||
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);
|
||||
LONG status = WinVerifyTrustEx(NULL, &actionID, &trustData);
|
||||
trustData.dwStateAction = WTD_STATEACTION_CLOSE;
|
||||
WinVerifyTrust(NULL, &actionID, &trustData);
|
||||
|
||||
return status == ERROR_SUCCESS;
|
||||
if (status != ERROR_SUCCESS)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (processType & (FF_PROCESS_TYPE_GUI | FF_PROCESS_TYPE_CUI))
|
||||
{
|
||||
SECTION_IMAGE_INFORMATION info = {};
|
||||
if(!NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessImageInformation, &info, sizeof(info), &size)) ||
|
||||
size != sizeof(info)) return false;
|
||||
|
||||
if ((processType & FF_PROCESS_TYPE_GUI) && info.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_GUI)
|
||||
return false;
|
||||
if ((processType & FF_PROCESS_TYPE_CUI) && info.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_CUI)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* ffDetectWMPlugin(FFstrbuf* pluginName)
|
||||
@@ -98,7 +130,7 @@ const char* ffDetectWMPlugin(FFstrbuf* pluginName)
|
||||
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))
|
||||
isProcessTrusted((DWORD) (uintptr_t) ptr->UniqueProcessId, FF_PROCESS_TYPE_WINDOWS_STORE | FF_PROCESS_TYPE_GUI, filePath, sizeof(buffer))
|
||||
) {
|
||||
if (ffGetFileVersion(filePath->Buffer, NULL, pluginName))
|
||||
ffStrbufPrependS(pluginName, "FancyWM ");
|
||||
@@ -108,7 +140,7 @@ const char* ffDetectWMPlugin(FFstrbuf* pluginName)
|
||||
}
|
||||
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))
|
||||
isProcessTrusted((DWORD) (uintptr_t) ptr->UniqueProcessId, FF_PROCESS_TYPE_SIGNED | FF_PROCESS_TYPE_GUI, filePath, sizeof(buffer))
|
||||
) {
|
||||
if (ffGetFileVersion(filePath->Buffer, NULL, pluginName))
|
||||
ffStrbufPrependS(pluginName, "GlazeWM ");
|
||||
@@ -116,6 +148,21 @@ const char* ffDetectWMPlugin(FFstrbuf* pluginName)
|
||||
ffStrbufSetStatic(pluginName, "GlazeWM");
|
||||
break;
|
||||
}
|
||||
else if (ptr->ImageName.Length == strlen("komorebi.exe") * sizeof(wchar_t) &&
|
||||
memcmp(ptr->ImageName.Buffer, L"komorebi.exe", ptr->ImageName.Length) == 0 &&
|
||||
isProcessTrusted((DWORD) (uintptr_t) ptr->UniqueProcessId, FF_PROCESS_TYPE_CUI, filePath, sizeof(buffer))
|
||||
) {
|
||||
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateNWS(filePath->Length / sizeof(wchar_t), filePath->Buffer);
|
||||
if (ffProcessAppendStdOut(pluginName, (char *const[]) {
|
||||
path.chars,
|
||||
"--version",
|
||||
NULL,
|
||||
}) == NULL)
|
||||
ffStrbufSubstrBeforeFirstC(pluginName, '\n');
|
||||
else
|
||||
ffStrbufSetStatic(pluginName, "Komorebi");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
Reference in New Issue
Block a user