Kernel (Windows): detect service pack version

This commit is contained in:
李通洲
2023-09-23 11:51:37 +08:00
parent 597daddf2a
commit 5aa2798e42
5 changed files with 51 additions and 53 deletions
+1
View File
@@ -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)
+12 -11
View File
@@ -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);
}
+1
View File
@@ -21,6 +21,7 @@ typedef struct FFPlatform {
FFstrbuf systemRelease;
FFstrbuf systemVersion;
FFstrbuf systemArchitecture;
FFstrbuf systemDisplayVersion;
} FFPlatform;
void ffPlatformInit(FFPlatform* platform);
+1
View File
@@ -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);
}
+36 -42
View File
@@ -2,10 +2,16 @@
#include "common/io/io.h"
#include "util/stringUtils.h"
#include "util/windows/unicode.h"
#include "util/windows/registry.h"
#include <winternl.h>
#include <Windows.h>
#include <shlobj.h>
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, &currentMajorVersionNumber, &bufSize) == ERROR_SUCCESS &&
RegGetValueW(hKey, NULL, L"CurrentMinorVersionNumber", RRF_RT_REG_DWORD, NULL, &currentMinorVersionNumber, &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);
}