From 67ca907e38f0cb41dc3fd20a8cdf9312d85aa4b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 1 Mar 2026 14:01:18 +0800 Subject: [PATCH] Kmod (Windows): adds support --- CMakeLists.txt | 11 +++- src/common/impl/kmod.c | 95 -------------------------------- src/common/impl/kmod_apple.c | 13 +++++ src/common/impl/kmod_bsd.c | 8 +++ src/common/impl/kmod_linux.c | 23 ++++++++ src/common/impl/kmod_nbsd.c | 43 +++++++++++++++ src/common/impl/kmod_nosupport.c | 6 ++ src/common/impl/kmod_windows.c | 27 +++++++++ src/common/windows/nt.h | 21 +++++++ 9 files changed, 151 insertions(+), 96 deletions(-) delete mode 100644 src/common/impl/kmod.c create mode 100644 src/common/impl/kmod_apple.c create mode 100644 src/common/impl/kmod_bsd.c create mode 100644 src/common/impl/kmod_linux.c create mode 100644 src/common/impl/kmod_nbsd.c create mode 100644 src/common/impl/kmod_nosupport.c create mode 100644 src/common/impl/kmod_windows.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 88f77fcd9..75273b39d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -398,7 +398,6 @@ set(LIBFASTFETCH_SRC src/common/impl/base64.c src/common/impl/FFlist.c src/common/impl/FFstrbuf.c - src/common/impl/kmod.c src/common/impl/path.c src/common/impl/FFPlatform.c src/common/impl/smbiosHelper.c @@ -523,6 +522,7 @@ if(LINUX) src/common/impl/processing_linux.c src/common/impl/FFPlatform_unix.c src/common/impl/binary_linux.c + src/common/impl/kmod_linux.c src/detection/battery/battery_linux.c src/detection/bios/bios_linux.c src/detection/board/board_linux.c @@ -607,6 +607,7 @@ elseif(ANDROID) src/common/impl/processing_linux.c src/common/impl/FFPlatform_unix.c src/common/impl/binary_linux.c + src/common/impl/kmod_linux.c src/detection/battery/battery_android.c src/detection/bios/bios_android.c src/detection/bluetooth/bluetooth_nosupport.c @@ -681,6 +682,7 @@ elseif(FreeBSD) src/common/impl/sysctl.c src/common/impl/FFPlatform_unix.c src/common/impl/binary_linux.c + src/common/impl/kmod_bsd.c src/detection/battery/battery_bsd.c src/detection/bios/bios_bsd.c src/detection/bluetoothradio/bluetoothradio_nosupport.c @@ -774,6 +776,7 @@ elseif(NetBSD) src/common/impl/sysctl.c src/common/impl/FFPlatform_unix.c src/common/impl/binary_linux.c + src/common/impl/kmod_nbsd.c src/detection/battery/battery_nbsd.c src/detection/bios/bios_nbsd.c src/detection/bluetooth/bluetooth_bsd.c @@ -857,6 +860,7 @@ elseif(OpenBSD) src/common/impl/FFPlatform_unix.c src/common/impl/binary_linux.c src/common/impl/smbiosHelper.c + src/common/impl/kmod_nosupport.c src/detection/battery/battery_obsd.c src/detection/bios/bios_windows.c src/detection/bluetooth/bluetooth_nosupport.c @@ -938,6 +942,7 @@ elseif(APPLE) src/common/impl/sysctl.c src/common/impl/FFPlatform_unix.c src/common/impl/binary_apple.c + src/common/impl/kmod_apple.c src/common/apple/cf_helpers.c src/common/apple/osascript.m src/common/apple/smc_temps.c @@ -1009,6 +1014,7 @@ elseif(WIN32) src/common/impl/FFPlatform_windows.c src/common/impl/binary_windows.c src/common/impl/debug_windows.c + src/common/impl/kmod_windows.c src/common/windows/getline.c src/common/windows/com.cpp src/common/windows/registry.c @@ -1082,6 +1088,7 @@ elseif(SunOS) src/common/impl/processing_linux.c src/common/impl/FFPlatform_unix.c src/common/impl/binary_linux.c + src/common/impl/kmod_nosupport.c src/detection/battery/battery_nosupport.c src/detection/bios/bios_windows.c src/detection/board/board_windows.c @@ -1163,6 +1170,7 @@ elseif(Haiku) src/common/impl/processing_linux.c src/common/impl/FFPlatform_unix.c src/common/impl/binary_linux.c + src/common/impl/kmod_nosupport.c src/common/haiku/version.cpp src/detection/battery/battery_haiku.c src/detection/bios/bios_windows.c @@ -1232,6 +1240,7 @@ elseif(GNU) src/common/impl/processing_linux.c src/common/impl/FFPlatform_unix.c src/common/impl/binary_linux.c + src/common/impl/kmod_nosupport.c src/detection/battery/battery_nosupport.c src/detection/bios/bios_nosupport.c src/detection/board/board_nosupport.c diff --git a/src/common/impl/kmod.c b/src/common/impl/kmod.c deleted file mode 100644 index 145c6ab78..000000000 --- a/src/common/impl/kmod.c +++ /dev/null @@ -1,95 +0,0 @@ -#include "common/kmod.h" - -#if __linux__ -#include "common/io.h" - -bool ffKmodLoaded(const char* modName) -{ - static FFstrbuf modules; - if (modules.chars == NULL) - { - ffStrbufInitS(&modules, "\n"); - ffAppendFileBuffer("/proc/modules", &modules); - } - - if (modules.length == 0) return false; - - uint32_t len = (uint32_t) strlen(modName); - if (len > 250) return false; - - char temp[256]; - temp[0] = '\n'; - memcpy(temp + 1, modName, len); - temp[1 + len] = ' '; - return memmem(modules.chars, modules.length, temp, len + 2) != NULL; -} -#elif __FreeBSD__ -#include -#include - -bool ffKmodLoaded(const char* modName) -{ - return modfind(modName) >= 0; -} -#elif __NetBSD__ -#include "common/stringUtils.h" - -#include -#include - -typedef struct __attribute__((__packed__)) FFNbsdModList -{ - int len; - modstat_t mods[]; -} FFNbsdModList; - -bool ffKmodLoaded(const char* modName) -{ - static FFNbsdModList* list = NULL; - - if (list == NULL) - { - struct iovec iov = {}; - - for (size_t len = 8192;; len = iov.iov_len) - { - iov.iov_len = len; - iov.iov_base = realloc(iov.iov_base, len); - if (modctl(MODCTL_STAT, &iov) < 0) - { - free(iov.iov_base); - return true; // ignore errors - } - - if (len >= iov.iov_len) break; - } - list = (FFNbsdModList*) iov.iov_base; - } - - for (int i = 0; i < list->len; i++) - { - if (ffStrEquals(list->mods[i].ms_name, modName)) - return true; - } - - return false; -} -#elif __APPLE__ -#include "common/apple/cf_helpers.h" -#include -#include - -bool ffKmodLoaded(const char* modName) -{ - FF_CFTYPE_AUTO_RELEASE CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, modName, kCFStringEncodingUTF8); - FF_CFTYPE_AUTO_RELEASE CFArrayRef identifiers = CFArrayCreate(kCFAllocatorDefault, (const void**) &name, 1, &kCFTypeArrayCallBacks); - FF_CFTYPE_AUTO_RELEASE CFArrayRef keys = CFArrayCreate(kCFAllocatorDefault, NULL, 0, NULL); - FF_CFTYPE_AUTO_RELEASE CFDictionaryRef kextInfo = KextManagerCopyLoadedKextInfo(identifiers, keys); - return CFDictionaryContainsKey(kextInfo, name); -} -#else -bool ffKmodLoaded(FF_MAYBE_UNUSED const char* modName) -{ - return true; // Don't generate kernel module related errors -} -#endif diff --git a/src/common/impl/kmod_apple.c b/src/common/impl/kmod_apple.c new file mode 100644 index 000000000..eb28faee6 --- /dev/null +++ b/src/common/impl/kmod_apple.c @@ -0,0 +1,13 @@ +#include "common/kmod.h" +#include "common/apple/cf_helpers.h" +#include +#include + +bool ffKmodLoaded(const char* modName) +{ + FF_CFTYPE_AUTO_RELEASE CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, modName, kCFStringEncodingUTF8); + FF_CFTYPE_AUTO_RELEASE CFArrayRef identifiers = CFArrayCreate(kCFAllocatorDefault, (const void**) &name, 1, &kCFTypeArrayCallBacks); + FF_CFTYPE_AUTO_RELEASE CFArrayRef keys = CFArrayCreate(kCFAllocatorDefault, NULL, 0, NULL); + FF_CFTYPE_AUTO_RELEASE CFDictionaryRef kextInfo = KextManagerCopyLoadedKextInfo(identifiers, keys); + return CFDictionaryContainsKey(kextInfo, name); +} diff --git a/src/common/impl/kmod_bsd.c b/src/common/impl/kmod_bsd.c new file mode 100644 index 000000000..99ebafda7 --- /dev/null +++ b/src/common/impl/kmod_bsd.c @@ -0,0 +1,8 @@ +#include "common/kmod.h" +#include +#include + +bool ffKmodLoaded(const char* modName) +{ + return modfind(modName) >= 0; +} diff --git a/src/common/impl/kmod_linux.c b/src/common/impl/kmod_linux.c new file mode 100644 index 000000000..940093b5d --- /dev/null +++ b/src/common/impl/kmod_linux.c @@ -0,0 +1,23 @@ +#include "common/kmod.h" +#include "common/io.h" + +bool ffKmodLoaded(const char* modName) +{ + static FFstrbuf modules; + if (modules.chars == NULL) + { + ffStrbufInitS(&modules, "\n"); + ffAppendFileBuffer("/proc/modules", &modules); + } + + if (modules.length == 0) return false; + + uint32_t len = (uint32_t) strlen(modName); + if (len > 250) return false; + + char temp[256]; + temp[0] = '\n'; + memcpy(temp + 1, modName, len); + temp[1 + len] = ' '; + return memmem(modules.chars, modules.length, temp, len + 2) != NULL; +} diff --git a/src/common/impl/kmod_nbsd.c b/src/common/impl/kmod_nbsd.c new file mode 100644 index 000000000..f4e78eed8 --- /dev/null +++ b/src/common/impl/kmod_nbsd.c @@ -0,0 +1,43 @@ +#include "common/kmod.h" +#include "common/stringUtils.h" + +#include +#include + +typedef struct __attribute__((__packed__)) FFNbsdModList +{ + int len; + modstat_t mods[]; +} FFNbsdModList; + +bool ffKmodLoaded(const char* modName) +{ + static FFNbsdModList* list = NULL; + + if (list == NULL) + { + struct iovec iov = {}; + + for (size_t len = 8192;; len = iov.iov_len) + { + iov.iov_len = len; + iov.iov_base = realloc(iov.iov_base, len); + if (modctl(MODCTL_STAT, &iov) < 0) + { + free(iov.iov_base); + return true; // ignore errors + } + + if (len >= iov.iov_len) break; + } + list = (FFNbsdModList*) iov.iov_base; + } + + for (int i = 0; i < list->len; i++) + { + if (ffStrEquals(list->mods[i].ms_name, modName)) + return true; + } + + return false; +} diff --git a/src/common/impl/kmod_nosupport.c b/src/common/impl/kmod_nosupport.c new file mode 100644 index 000000000..1ae3b0b33 --- /dev/null +++ b/src/common/impl/kmod_nosupport.c @@ -0,0 +1,6 @@ +#include "common/kmod.h" + +bool ffKmodLoaded(FF_MAYBE_UNUSED const char* modName) +{ + return true; // Don't generate kernel module related errors +} diff --git a/src/common/impl/kmod_windows.c b/src/common/impl/kmod_windows.c new file mode 100644 index 000000000..ea46ae019 --- /dev/null +++ b/src/common/impl/kmod_windows.c @@ -0,0 +1,27 @@ +#include "common/kmod.h" +#include "common/windows/nt.h" +#include "common/mallocHelper.h" +#include "common/stringUtils.h" + +bool ffKmodLoaded(FF_MAYBE_UNUSED const char* modName) +{ + ULONG bufferSize = 0; + NtQuerySystemInformation(SystemModuleInformation, NULL, 0, &bufferSize); + if (bufferSize == 0) + return true; // ignore errors + + FF_AUTO_FREE RTL_PROCESS_MODULES* buffer = malloc(bufferSize); + + if (!NT_SUCCESS(NtQuerySystemInformation(SystemModuleInformation, buffer, bufferSize, &bufferSize))) + return true; // ignore errors + + for (ULONG i = 0; i < buffer->NumberOfModules; i++) + { + const char* name = (const char*) buffer->Modules[i].FullPathName + buffer->Modules[i].OffsetToFileName; + + if (ffStrEqualsIgnCase(name, modName)) + return true; + } + + return false; +} diff --git a/src/common/windows/nt.h b/src/common/windows/nt.h index f934c6f45..ea648937d 100644 --- a/src/common/windows/nt.h +++ b/src/common/windows/nt.h @@ -4,6 +4,7 @@ #include enum { + SystemModuleInformation = 11, SystemBootEnvironmentInformation = 90, }; @@ -357,3 +358,23 @@ typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION }; }; } SYSTEM_BOOT_ENVIRONMENT_INFORMATION; + +typedef struct _RTL_PROCESS_MODULE_INFORMATION +{ + PVOID Section; + PVOID MappedBase; + PVOID ImageBase; + ULONG ImageSize; + ULONG Flags; + USHORT LoadOrderIndex; + USHORT InitOrderIndex; + USHORT LoadCount; + USHORT OffsetToFileName; + UCHAR FullPathName[256]; +} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION; + +typedef struct _RTL_PROCESS_MODULES +{ + ULONG NumberOfModules; + _Field_size_(NumberOfModules) RTL_PROCESS_MODULE_INFORMATION Modules[1]; +} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;