From 5aa2798e4267054a462cfeb803f226a62fee4f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 23 Sep 2023 11:51:37 +0800 Subject: [PATCH] Kernel (Windows): detect service pack version --- CHANGELOG.md | 1 + src/modules/kernel/kernel.c | 23 ++++---- src/util/platform/FFPlatform.h | 1 + src/util/platform/FFPlatform_unix.c | 1 + src/util/platform/FFPlatform_windows.c | 78 ++++++++++++-------------- 5 files changed, 51 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f59238c45..a56bb1878 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Features: * Support `--title-format`. See `fastfetch --help title-format` for detail * Support `--colors-key` (Colors) * Add `-c` as a shortcut of `--load-config`. Note it was used as the shortcut of `--color` before 2.0.5 +* Support Windows Service Pack version detection (Kernel, Windows) Bugfixes: * Fix fastfetch hanging in specific environment (#561) diff --git a/src/modules/kernel/kernel.c b/src/modules/kernel/kernel.c index b8c9e31cf..89aab0af1 100644 --- a/src/modules/kernel/kernel.c +++ b/src/modules/kernel/kernel.c @@ -7,25 +7,25 @@ void ffPrintKernel(FFKernelOptions* options) { + const FFPlatform* platform = &instance.state.platform; if(options->moduleArgs.outputFormat.length == 0) { ffPrintLogoAndKey(FF_KERNEL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT); - ffStrbufWriteTo(&instance.state.platform.systemRelease, stdout); + ffStrbufWriteTo(&platform->systemRelease, stdout); - #ifdef _WIN32 - if(instance.state.platform.systemVersion.length > 0) - printf(" (%s)", instance.state.platform.systemVersion.chars); - #endif - - putchar('\n'); + if(platform->systemDisplayVersion.length > 0) + printf(" (%s)\n", platform->systemDisplayVersion.chars); + else + putchar('\n'); } else { ffPrintFormat(FF_KERNEL_MODULE_NAME, 0, &options->moduleArgs, FF_KERNEL_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &instance.state.platform.systemName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &instance.state.platform.systemRelease}, - {FF_FORMAT_ARG_TYPE_STRBUF, &instance.state.platform.systemVersion}, - {FF_FORMAT_ARG_TYPE_STRBUF, &instance.state.platform.systemArchitecture} + {FF_FORMAT_ARG_TYPE_STRBUF, &platform->systemName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &platform->systemRelease}, + {FF_FORMAT_ARG_TYPE_STRBUF, &platform->systemVersion}, + {FF_FORMAT_ARG_TYPE_STRBUF, &platform->systemArchitecture}, + {FF_FORMAT_ARG_TYPE_STRBUF, &platform->systemDisplayVersion} }); } } @@ -75,4 +75,5 @@ void ffGenerateKernelJson(FF_MAYBE_UNUSED FFKernelOptions* options, yyjson_mut_d yyjson_mut_obj_add_strbuf(doc, obj, "name", &instance.state.platform.systemName); yyjson_mut_obj_add_strbuf(doc, obj, "release", &instance.state.platform.systemRelease); yyjson_mut_obj_add_strbuf(doc, obj, "version", &instance.state.platform.systemVersion); + yyjson_mut_obj_add_strbuf(doc, obj, "displayVersion", &instance.state.platform.systemDisplayVersion); } diff --git a/src/util/platform/FFPlatform.h b/src/util/platform/FFPlatform.h index 536b09aed..48c72513e 100644 --- a/src/util/platform/FFPlatform.h +++ b/src/util/platform/FFPlatform.h @@ -21,6 +21,7 @@ typedef struct FFPlatform { FFstrbuf systemRelease; FFstrbuf systemVersion; FFstrbuf systemArchitecture; + FFstrbuf systemDisplayVersion; } FFPlatform; void ffPlatformInit(FFPlatform* platform); diff --git a/src/util/platform/FFPlatform_unix.c b/src/util/platform/FFPlatform_unix.c index 2c9b0f4c6..cc6fa803a 100644 --- a/src/util/platform/FFPlatform_unix.c +++ b/src/util/platform/FFPlatform_unix.c @@ -175,4 +175,5 @@ void ffPlatformInitImpl(FFPlatform* platform) ffStrbufAppendS(&platform->systemRelease, uts.release); ffStrbufAppendS(&platform->systemVersion, uts.version); ffStrbufAppendS(&platform->systemArchitecture, uts.machine); + ffStrbufInit(&platform->systemVersion); } diff --git a/src/util/platform/FFPlatform_windows.c b/src/util/platform/FFPlatform_windows.c index fea0c26c6..0774c81c3 100644 --- a/src/util/platform/FFPlatform_windows.c +++ b/src/util/platform/FFPlatform_windows.c @@ -2,10 +2,16 @@ #include "common/io/io.h" #include "util/stringUtils.h" #include "util/windows/unicode.h" +#include "util/windows/registry.h" +#include #include #include +NTSTATUS NTAPI RtlGetVersion( + _Inout_ PRTL_OSVERSIONINFOW lpVersionInformation +); + static void getExePath(FFPlatform* platform) { wchar_t exePathW[MAX_PATH]; @@ -137,55 +143,44 @@ static void getUserShell(FFPlatform* platform) ffStrbufReplaceAllC(&platform->userShell, '\\', '/'); } -static void getSystemName(FFPlatform* platform) -{ - ffStrbufAppendS(&platform->systemName, getenv("OS")); -} - static void getSystemReleaseAndVersion(FFPlatform* platform) { - HKEY hKey; - if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) + RTL_OSVERSIONINFOW osVersion = { .dwOSVersionInfoSize = sizeof(osVersion) }; + if (!NT_SUCCESS(RtlGetVersion(&osVersion))) return; - DWORD bufSize; + FF_HKEY_AUTO_DESTROY hKey = NULL; + if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", &hKey, NULL)) + return; - char currentVersion[32]; + uint32_t ubr = 0; + ffRegReadUint(hKey, L"UBR", &ubr, NULL); + ffStrbufAppendF(&platform->systemRelease, + "%u.%u.%u.%u", + (unsigned) osVersion.dwMajorVersion, + (unsigned) osVersion.dwMinorVersion, + (unsigned) osVersion.dwBuildNumber, + (unsigned) ubr); + + ffStrbufInit(&platform->systemDisplayVersion); + if(!ffRegReadStrbuf(hKey, L"DisplayVersion", &platform->systemDisplayVersion, NULL) && osVersion.szCSDVersion[0]) + ffStrbufSetWS(&platform->systemDisplayVersion, osVersion.szCSDVersion); + + ffRegReadStrbuf(hKey, L"BuildLabEx", &platform->systemVersion, NULL); + + switch (osVersion.dwPlatformId) { - DWORD currentMajorVersionNumber; - DWORD currentMinorVersionNumber; - bufSize = sizeof(currentMajorVersionNumber); - if(RegGetValueW(hKey, NULL, L"CurrentMajorVersionNumber", RRF_RT_REG_DWORD, NULL, ¤tMajorVersionNumber, &bufSize) == ERROR_SUCCESS && - RegGetValueW(hKey, NULL, L"CurrentMinorVersionNumber", RRF_RT_REG_DWORD, NULL, ¤tMinorVersionNumber, &bufSize) == ERROR_SUCCESS - ) - snprintf(currentVersion, sizeof(currentVersion), "%u.%u", (unsigned)currentMajorVersionNumber, (unsigned)currentMinorVersionNumber); - else - { - bufSize = sizeof(currentVersion); - if(RegGetValueA(hKey, NULL, "CurrentVersion", RRF_RT_REG_SZ, NULL, currentVersion, &bufSize) != ERROR_SUCCESS) - strcpy(currentVersion, "0.0"); - } + case VER_PLATFORM_WIN32s: + ffStrbufAppendS(&platform->systemName, "WIN32s"); + break; + case VER_PLATFORM_WIN32_WINDOWS: + ffStrbufAppendS(&platform->systemName, "WIN32_WINDOWS"); + break; + case VER_PLATFORM_WIN32_NT: + ffStrbufAppendS(&platform->systemName, "WIN32_NT"); + break; } - - char currentBuildNumber[32]; - bufSize = sizeof(currentBuildNumber); - if(RegGetValueA(hKey, NULL, "CurrentBuildNumber", RRF_RT_REG_SZ, NULL, currentBuildNumber, &bufSize) != ERROR_SUCCESS) - strcpy(currentBuildNumber, "0"); - - DWORD ubr; - bufSize = sizeof(ubr); - if(RegGetValueW(hKey, NULL, L"UBR", RRF_RT_REG_DWORD, NULL, &ubr, &bufSize) != ERROR_SUCCESS || bufSize != sizeof(ubr)) - ubr = 0; - - ffStrbufAppendF(&platform->systemRelease, "%s.%s.%u", currentVersion, currentBuildNumber, (unsigned)ubr); - - ffStrbufEnsureFree(&platform->systemVersion, 256); - bufSize = (DWORD) ffStrbufGetFree(&platform->systemVersion); - if(RegGetValueA(hKey, NULL, "DisplayVersion", RRF_RT_REG_SZ, NULL, platform->systemVersion.chars, &bufSize) == ERROR_SUCCESS) - platform->systemVersion.length = (uint32_t) bufSize - 1; - - RegCloseKey(hKey); } static void getSystemArchitecture(FFPlatform* platform) @@ -234,7 +229,6 @@ void ffPlatformInitImpl(FFPlatform* platform) getHostName(platform); getUserShell(platform); - getSystemName(platform); getSystemReleaseAndVersion(platform); getSystemArchitecture(platform); }