From c0daeb16dffaded1c529e198e1b8e704bb448d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 6 Oct 2022 17:47:49 +0800 Subject: [PATCH] Users: add support for Windows --- CMakeLists.txt | 28 +++++++++++----- src/detection/users/users.h | 10 ++++++ src/detection/users/users_linux.c | 36 ++++++++++++++++++++ src/detection/users/users_windows.cpp | 42 +++++++++++++++++++++++ src/modules/users.c | 48 ++++++++------------------- src/util/windows/wmi.cpp | 6 ++-- 6 files changed, 125 insertions(+), 45 deletions(-) create mode 100644 src/detection/users/users.h create mode 100644 src/detection/users/users_linux.c create mode 100644 src/detection/users/users_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fbbd97bb1..f28955d12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -269,19 +269,21 @@ if(BSD OR APPLE) ) endif() -if(LINUX OR ANDROID OR WIN_MSYS) +if(LINUX OR ANDROID) list(APPEND LIBFASTFETCH_SRC src/detection/cpu/cpu_linux.c src/detection/memory/memory_linux.c ) endif() -if(LINUX OR ANDROID OR BSD OR WIN_MSYS) +if(LINUX OR ANDROID OR BSD) list(APPEND LIBFASTFETCH_SRC src/detection/cpuUsage/cpuUsage_linux.c src/detection/disk/disk_linux.c src/detection/poweradapter/poweradapter_linux.c src/detection/temps/temps_linux.c + src/detection/users/users_linux.c + src/detection/opengl/opengl_linux.c ) endif() @@ -302,7 +304,6 @@ if(LINUX OR BSD) src/detection/media/media_linux.c src/detection/wmtheme/wmtheme_linux.c src/detection/font/font_linux.c - src/detection/opengl/opengl_linux.c ) endif() @@ -311,16 +312,27 @@ if(WIN_MSYS) src/detection/host/host_windows.cpp src/detection/bios/bios_windows.cpp src/detection/board/board_windows.cpp - src/detection/os/os_linux.c src/detection/gpu/gpu_windows.cpp src/detection/battery/battery_windows.cpp src/detection/displayserver/displayserver_windows.c - src/detection/terminalfont/terminalfont_linux.c - src/detection/media/media_linux.c src/detection/wmtheme/wmtheme_windows.c - src/detection/font/font_linux.c src/detection/opengl/opengl_windows.c + src/detection/users/users_windows.cpp src/util/windows/wmi.cpp + + # Shared + src/detection/terminalfont/terminalfont_linux.c + src/detection/poweradapter/poweradapter_linux.c + + # TODO + src/detection/os/os_linux.c + src/detection/media/media_linux.c + src/detection/font/font_linux.c + src/detection/cpu/cpu_linux.c + src/detection/memory/memory_linux.c + src/detection/cpuUsage/cpuUsage_linux.c + src/detection/disk/disk_linux.c + src/detection/temps/temps_linux.c ) endif() @@ -345,6 +357,7 @@ if(APPLE) src/detection/wmtheme/wmtheme_apple.m src/detection/temps/temps_apple.c src/detection/font/font_apple.m + src/detection/users/users_linux.c src/detection/opengl/opengl_apple.c ) endif() @@ -369,7 +382,6 @@ if(ANDROID) src/detection/media/media_android.c src/detection/wmtheme/wmtheme_android.c src/detection/font/font_android.c - src/detection/opengl/opengl_linux.c ) endif() diff --git a/src/detection/users/users.h b/src/detection/users/users.h new file mode 100644 index 000000000..8842e16a2 --- /dev/null +++ b/src/detection/users/users.h @@ -0,0 +1,10 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_users_users +#define FF_INCLUDED_detection_users_users + +#include "fastfetch.h" + +void ffDetectUsers(FFlist* users /* List of FFstrbuf */, FFstrbuf* error); + +#endif diff --git a/src/detection/users/users_linux.c b/src/detection/users/users_linux.c new file mode 100644 index 000000000..b1dcee8ed --- /dev/null +++ b/src/detection/users/users_linux.c @@ -0,0 +1,36 @@ +#include "fastfetch.h" +#include "users.h" + +#if FF_HAVE_UTMPX_H + #include +#else + //for Android compatibility + #include + #define utmpx utmp + #define setutxent setutent + #define getutxent getutent +#endif + +void ffDetectUsers(FFlist* users, FFstrbuf* error) +{ + struct utmpx* n = NULL; + setutxent(); + +next: + while((n = getutxent())) + { + if(n->ut_type != USER_PROCESS) + continue; + + for(uint32_t i = 0; i < users->length; ++i) + { + if(ffStrbufCompS((FFstrbuf*)ffListGet(users, i), n->ut_user) == 0) + goto next; + } + + ffStrbufInitS((FFstrbuf*)ffListAdd(users), n->ut_user); + } + + if(users->length == 0) + ffStrbufAppendS(error, "Unable to detect users"); +} diff --git a/src/detection/users/users_windows.cpp b/src/detection/users/users_windows.cpp new file mode 100644 index 000000000..7728c1ff3 --- /dev/null +++ b/src/detection/users/users_windows.cpp @@ -0,0 +1,42 @@ +extern "C" { +#include "users.h" +} +#include "util/windows/wmi.hpp" + +void ffDetectUsers(FFlist* users, FFstrbuf* error) +{ + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Antecedent FROM Win32_LoggedOnUser", error); + + if(!pEnumerator) + return; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + +next: + while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0) + { + FFstrbuf antecedent; + ffStrbufInit(&antecedent); + ffGetWmiObjValue(pclsObj, L"Antecedent", &antecedent); // \\.\root\cimv2:Win32_Account.Domain="DOMAIN",Name="NAME" + ffStrbufTrimRight(&antecedent, '"'); // \\.\root\cimv2:Win32_Account.Domain="DOMAIN",Name="NAME + ffStrbufSubstrAfterFirstC(&antecedent, '"'); // DOMAIN",Name="NAME + uint32_t index = ffStrbufFirstIndexC(&antecedent, '"'); + ffStrbufRemoveSubstr(&antecedent, index, ffStrbufLastIndexC(&antecedent, '"')); // DOMAIN"NAME + antecedent.chars[index] = '\\'; + + for(uint32_t i = 0; i < users->length; ++i) + { + if(ffStrbufComp((FFstrbuf*)ffListGet(users, i), &antecedent) == 0) + goto next; + } + + *(FFstrbuf*)ffListAdd(users) = antecedent; + } + + if(users->length == 0) + ffStrbufAppendS(error, "Unable to detect users"); + + pclsObj->Release(); + pEnumerator->Release(); +} diff --git a/src/modules/users.c b/src/modules/users.c index c1b85f8da..1c78571b2 100644 --- a/src/modules/users.c +++ b/src/modules/users.c @@ -1,48 +1,25 @@ #include "fastfetch.h" #include "common/printing.h" - -#if FF_HAVE_UTMPX_H - #include -#else - //for Android compatibility - #include - #define utmpx utmp - #define setutxent setutent - #define getutxent getutent -#endif +#include "detection/users/users.h" #define FF_USERS_MODULE_NAME "Users" #define FF_USERS_NUM_FORMAT_ARGS 1 void ffPrintUsers(FFinstance* instance) { - struct utmpx* n = NULL; - setutxent(); - FFlist users; - ffListInit(&users, sizeof(n->ut_user) + 1); + ffListInit(&users, sizeof(FFstrbuf)); -next: - while((n = getutxent())) - { - if(n->ut_type == USER_PROCESS) - { - for(uint32_t i = 0; i < users.length; ++i) - { - if(strcmp((const char*)ffListGet(&users, i), n->ut_user) == 0) - goto next; - } - - char* dest = ffListAdd(&users); - strncpy(dest, n->ut_user, sizeof(n->ut_user)); - dest[sizeof(n->ut_user)] = '\0'; - } - } - - if(users.length == 0) + FFstrbuf error; + ffStrbufInit(&error); + + ffDetectUsers(&users, &error); + + if(error.length > 0) { + ffPrintError(instance, FF_USERS_MODULE_NAME, 0, &instance->config.users, "%*s", error.length, error.chars); ffListDestroy(&users); - ffPrintError(instance, FF_USERS_MODULE_NAME, 0, &instance->config.users, "Unable to detect users"); + ffStrbufDestroy(&error); return; } @@ -52,8 +29,11 @@ next: { if(i > 0) ffStrbufAppendS(&result, ", "); - ffStrbufAppendS(&result, (const char*)ffListGet(&users, i)); + FFstrbuf* user = (FFstrbuf*)ffListGet(&users, i); + ffStrbufAppend(&result, user); + ffStrbufDestroy(user); } + ffListDestroy(&users); if(instance->config.users.outputFormat.length == 0) diff --git a/src/util/windows/wmi.cpp b/src/util/windows/wmi.cpp index 30ba20a4f..b79fb33a4 100644 --- a/src/util/windows/wmi.cpp +++ b/src/util/windows/wmi.cpp @@ -145,6 +145,7 @@ void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf) { ffStrbufEnsureFree(strbuf, (uint32_t)size_needed); WideCharToMultiByte(CP_UTF8, 0, bstr, len, strbuf->chars, size_needed, nullptr, nullptr); strbuf->length = (uint32_t)size_needed; + strbuf->chars[size_needed] = '\0'; } bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf) @@ -176,7 +177,6 @@ bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbu case CIM_REAL32: ffStrbufAppendF(strbuf, "%f", vtProp.fltVal); break; case CIM_REAL64: ffStrbufAppendF(strbuf, "%f", vtProp.dblVal); break; case CIM_BOOLEAN: ffStrbufAppendF(strbuf, "%s", vtProp.boolVal ? "True" : "False"); break; - case CIM_STRING: ffBstrToStrbuf(vtProp.bstrVal, strbuf); break; case CIM_DATETIME: { ISWbemDateTime *pDateTime; BSTR dateStr; @@ -190,8 +190,8 @@ bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbu ffBstrToStrbuf(dateStr, strbuf); break; }; - - default: result = false; break; + case CIM_STRING: + default: ffBstrToStrbuf(vtProp.bstrVal, strbuf); break; } } VariantClear(&vtProp);