Windows: support native Windows

This commit is contained in:
李通洲
2022-10-13 18:12:54 +08:00
parent 457c2da67d
commit 3cc6611614
19 changed files with 319 additions and 45 deletions
+1
View File
@@ -3,6 +3,7 @@
**/.cache/
**/.kdev4/
**/.DS_Store
/.vs
cscope.*
tags
fastfetch.kdev4
+33 -17
View File
@@ -15,11 +15,11 @@ if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*")
set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel
elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Bb][Ss][Dd].*")
set(BSD TRUE CACHE BOOL "..." FORCE)
elseif(NOT APPLE AND NOT ANDROID AND NOT MSYS)
elseif(NOT APPLE AND NOT ANDROID AND NOT MSYS AND NOT WIN32)
message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}")
endif()
if(MSYS)
if(MSYS OR WIN32)
enable_language(CXX)
endif()
@@ -27,7 +27,7 @@ endif()
# Compile time dependencies #
#############################
set(THREADS_PREFER_PTHREAD_FLAG ON)
set(THREADS_PREFER_PTHREAD_FLAG NOT WIN32)
find_package(Threads)
find_package(PkgConfig REQUIRED)
@@ -41,7 +41,7 @@ include(CheckIncludeFile)
include(CMakeDependentOption)
cmake_dependent_option(ENABLE_LIBPCI "Enable libpci" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR MSYS" OFF)
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR MSYS OR WIN32" OFF)
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR BSD" OFF)
@@ -60,8 +60,8 @@ cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENAB
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR MSYS" OFF)
cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR MSYS" OFF)
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR MSYS OR WIN32" OFF)
cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR MSYS OR WIN32" OFF)
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND AND NOT ANDROID" OFF)
@@ -78,10 +78,10 @@ endif()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
if(ENABLE_THREADS)
if(CMAKE_USE_PTHREADS_INIT)
message(STATUS "Threads type: pthread")
else()
if(CMAKE_USE_WIN32_THREADS_INIT)
message(STATUS "Threads type: Win32 thread")
elseif(CMAKE_USE_PTHREADS_INIT)
message(STATUS "Threads type: pthread")
endif()
else()
message(STATUS "Threads type: disabled")
@@ -90,7 +90,7 @@ endif()
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion")
if(MSYS)
if(MSYS OR WIN32)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -fno-exceptions -fno-rtti")
endif()
@@ -102,7 +102,7 @@ if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX})
endif()
set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer")
if(NOT MSYS)
if(NOT MSYS AND NOT WIN32)
set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address -fsanitize=undefined")
endif()
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}")
@@ -344,9 +344,8 @@ if(LINUX OR BSD)
)
endif()
if(MSYS)
if(MSYS OR WIN32)
list(APPEND LIBFASTFETCH_SRC
src/common/processing_linux.c
src/detection/host/host_windows.cpp
src/detection/bios/bios_windows.cpp
src/detection/board/board_windows.cpp
@@ -364,9 +363,7 @@ if(MSYS)
src/detection/cpuUsage/cpuUsage_nowait_windows.cpp
src/detection/memory/memory_windows.cpp
src/detection/font/font_windows.cpp
src/detection/terminalshell/terminalshell_linux.c
src/detection/terminalshell/terminalshell_windows.cpp
src/detection/packages/packages_linux.c
src/detection/terminalfont/terminalfont_windows.c
src/detection/packages/packages_windows.c
src/detection/kernel/kernel_windows.cpp
@@ -379,6 +376,23 @@ if(MSYS)
)
endif()
if(MSYS)
list(APPEND LIBFASTFETCH_SRC
src/common/processing_linux.c
src/detection/terminalshell/terminalshell_linux.c
src/detection/packages/packages_linux.c
)
endif()
if(WIN32)
list(APPEND LIBFASTFETCH_SRC
src/common/processing_windows.c
src/util/windows/getline.c
src/util/windows/pwd.c
src/util/windows/utsname.c
)
endif()
if(APPLE)
list(APPEND LIBFASTFETCH_SRC
src/detection/cpuUsage/cpuUsage_apple.c
@@ -497,7 +511,9 @@ ff_lib_enable(FREETYPE freetype2)
if(ENABLE_THREADS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS)
target_link_libraries(libfastfetch PRIVATE Threads::Threads)
if(CMAKE_USE_PTHREADS_INIT) #Threads::Threads is not set for WIN32
target_link_libraries(libfastfetch PRIVATE Threads::Threads)
endif()
endif()
if(APPLE)
@@ -510,7 +526,7 @@ if(APPLE)
PRIVATE "-framework Cocoa"
PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks"
)
elseif(MSYS)
elseif(MSYS OR WIN32)
target_link_libraries(libfastfetch
PRIVATE "wbemuuid"
PRIVATE "ole32"
+5 -3
View File
@@ -2,16 +2,18 @@
#include "common/format.h"
#include "common/parsing.h"
#include <inttypes.h>
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
{
if(formatarg->type == FF_FORMAT_ARG_TYPE_INT)
ffStrbufAppendF(buffer, "%i", *(int*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT)
ffStrbufAppendF(buffer, "%u", *(uint32_t*)formatarg->value);
ffStrbufAppendF(buffer, "%" PRIu32, *(uint32_t*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT16)
ffStrbufAppendF(buffer, "%hu", *(uint16_t*)formatarg->value);
ffStrbufAppendF(buffer, "%" PRIu16, *(uint16_t*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT8)
ffStrbufAppendF(buffer, "%hhu", *(uint8_t*)formatarg->value);
ffStrbufAppendF(buffer, "%" PRIu8, *(uint8_t*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_STRING)
ffStrbufAppendS(buffer, (const char*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_STRBUF)
+43 -7
View File
@@ -9,7 +9,12 @@
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <signal.h>
#ifdef _WIN32
#include <wincon.h>
#include <locale.h>
#else
#include <signal.h>
#endif
static bool strbufEqualsAdapter(const void* first, const void* second)
{
@@ -101,18 +106,35 @@ static void initCacheDir(FFstate* state)
else
ffStrbufEnsureEndsWithC(&state->cacheDir, '/');
mkdir(state->cacheDir.chars, S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH); //I hope everybody has a cache folder, but who knows
mkdir(state->cacheDir.chars
#ifndef WIN32
, S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH
#endif
); //I hope everybody has a cache folder, but who knows
ffStrbufAppendS(&state->cacheDir, "fastfetch/");
mkdir(state->cacheDir.chars, S_IRWXU | S_IRGRP | S_IROTH);
mkdir(state->cacheDir.chars
#ifndef WIN32
, S_IRWXU | S_IRGRP | S_IROTH
#endif
);
}
static void initState(FFstate* state)
{
#ifdef WIN32
//https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendations&view=msvc-170#utf-8-support
setlocale(LC_ALL, ".UTF8");
#endif
state->logoWidth = 0;
state->logoHeight = 0;
state->keysHeight = 0;
state->passwd = getpwuid(getuid());
#ifndef WIN32
state->passwd = getpwuid(getuid());
#else
state->passwd = ffGetPasswd();
#endif
uname(&state->utsname);
#if FF_HAVE_SYSINFO_H
@@ -305,12 +327,24 @@ static void resetConsole()
fputs("\033[?25h", stdout);
}
#ifdef _WIN32
BOOL WINAPI consoleHandler(DWORD signal)
{
if(signal == CTRL_C_EVENT)
{
resetConsole();
return TRUE;
}
return false;
}
#else
static void exitSignalHandler(int signal)
{
FF_UNUSED(signal);
resetConsole();
exit(0);
}
#endif
void ffStart(FFinstance* instance)
{
@@ -320,12 +354,14 @@ void ffStart(FFinstance* instance)
ffDisableLinewrap = instance->config.disableLinewrap && !instance->config.pipe;
ffHideCursor = instance->config.hideCursor && !instance->config.pipe;
struct sigaction action = {};
action.sa_handler = exitSignalHandler;
#ifdef _WIN32
SetConsoleCtrlHandler(consoleHandler, TRUE);
#else
struct sigaction action = { .sa_handler = exitSignalHandler };
sigaction(SIGINT, &action, NULL);
sigaction(SIGTERM, &action, NULL);
sigaction(SIGQUIT, &action, NULL);
#endif
//We do the cache validation here, so we can skip it if --recache is given
if(!instance->config.recache)
+17 -3
View File
@@ -4,8 +4,11 @@
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <poll.h>
#ifndef WIN32
#include <termios.h>
#include <poll.h>
#endif
static void createSubfolders(const char* fileName)
{
@@ -16,7 +19,13 @@ static void createSubfolders(const char* fileName)
{
ffStrbufAppendC(&path, *fileName);
if(*fileName == '/')
mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH);
{
mkdir(path.chars
#ifndef WIN32
, S_IRWXU | S_IRGRP | S_IROTH
#endif
);
}
++fileName;
}
@@ -151,6 +160,7 @@ bool ffFileExists(const char* fileName, mode_t mode)
void ffGetTerminalResponse(const char* request, const char* format, ...)
{
#ifndef WIN32
struct termios oldTerm, newTerm;
if(tcgetattr(STDIN_FILENO, &oldTerm) == -1)
return;
@@ -189,4 +199,8 @@ void ffGetTerminalResponse(const char* request, const char* format, ...)
va_start(args, format);
vsscanf(buffer, format, args);
va_end(args);
#else
//Unimplemented
FF_UNUSED(request, format);
#endif
}
+3
View File
@@ -2,6 +2,9 @@
#include "common/properties.h"
#include <stdlib.h>
#ifdef _WIN32
#include "util/windows/getline.h"
#endif
static bool parsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer)
{
+1 -5
View File
@@ -67,11 +67,7 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance)
ffGetWmiObjString(pclsObj, L"BuildNumber", &os->buildID);
ffGetWmiObjString(pclsObj, L"OSArchitecture", &os->architecture);
#ifdef __MSYS__
ffStrbufSetS(&os->systemName, instance->state.utsname.sysname);
#else
ffStrbufSetS(&os->systemName, "Windows");
#endif
ffStrbufSetS(&os->systemName, instance->state.utsname.sysname);
pclsObj->Release();
pEnumerator->Release();
@@ -125,6 +125,8 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance)
// When running outside of MSYS2, /proc/self/xxx doesn't exist and we must find it in Windows way
if(getenv("MSYSTEM"))
return ffDetectTerminalShellPosix(instance);
#else
FF_UNUSED(instance);
#endif
static FFTerminalShellResult result;
+8
View File
@@ -10,6 +10,10 @@
#include <dirent.h>
#include <sys/stat.h>
#ifdef WIN32
#include "util/windows/getline.h"
#endif
typedef struct CustomValue
{
bool printKey;
@@ -414,6 +418,7 @@ static inline void printCommandHelp(const char* command)
static inline void listAvailablePresetsFromFolder(FFstrbuf* folder, uint8_t indentation, const char* folderName)
{
#ifndef _WIN32
DIR* dir = opendir(folder->chars);
if(dir == NULL)
return;
@@ -447,6 +452,9 @@ static inline void listAvailablePresetsFromFolder(FFstrbuf* folder, uint8_t inde
}
closedir(dir);
#else
FF_UNUSED(folder, indentation, folderName);
#endif
}
static inline void listAvailablePresets(FFinstance* instance)
+7 -2
View File
@@ -8,8 +8,13 @@
#include <stdint.h>
#include <stdbool.h>
#include <pwd.h>
#include <sys/utsname.h>
#ifndef _WIN32
#include <pwd.h>
#include <sys/utsname.h>
#else
#include "util/windows/pwd.h"
#include "util/windows/utsname.h"
#endif
#if FF_HAVE_SYSINFO_H
#include <sys/sysinfo.h>
+3
View File
@@ -26,10 +26,13 @@ static void getLocaleFromEnv(FFstrbuf* locale)
static void getLocaleFromCmd(FFstrbuf* locale)
{
ffStrbufAppendS(locale, setlocale(LC_ALL, NULL));
#ifdef LC_MESSAGES
if(locale->length > 0)
return;
ffStrbufAppendS(locale, setlocale(LC_MESSAGES, NULL));
#endif
}
void ffPrintLocale(FFinstance* instance)
+5
View File
@@ -13,6 +13,11 @@
#include <stdlib.h>
#include <assert.h>
#ifdef _WIN32
#include <shlwapi.h>
#define strcasestr StrStrIA
#endif
#define FASTFETCH_STRBUF_DEFAULT_ALLOC 32
typedef struct FFstrbuf
+58
View File
@@ -0,0 +1,58 @@
#include "getline.h"
#include <stdlib.h>
#include <errno.h>
ssize_t getline(char **lineptr, size_t *n, FILE *stream) {
ssize_t pos = -1;
int c;
if (lineptr == NULL || stream == NULL || n == NULL) {
errno = EINVAL;
return -1;
}
_lock_file(stream);
c = _getc_nolock(stream);
if (c == EOF) {
goto exit;
}
if (*lineptr == NULL) {
*lineptr = malloc(128);
if (*lineptr == NULL) {
goto exit;
}
*n = 128;
}
pos = 0;
while(c != EOF) {
if ((size_t)(pos + 1) >= *n) {
size_t new_size = *n + (*n >> 2);
if (new_size < 128) {
new_size = 128;
}
char *new_ptr = realloc(*lineptr, new_size);
if (new_ptr == NULL) {
pos = -1;
goto exit;
}
*n = new_size;
*lineptr = new_ptr;
}
((char *)(*lineptr))[pos ++] = (char)c;
if (c == '\n') {
break;
}
c = _getc_nolock(stream);
}
(*lineptr)[pos] = '\0';
exit:
_unlock_file(stream);
return pos;
}
+11
View File
@@ -0,0 +1,11 @@
#pragma once
#ifndef FASTFETCH_INCLUDED_UTIL_GETLINE
#define FASTFETCH_INCLUDED_UTIL_GETLINE
#include <stdint.h>
#include <stdio.h>
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
#endif
+17
View File
@@ -0,0 +1,17 @@
#include "pwd.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <shlobj.h>
struct passwd* ffGetPasswd()
{
static struct passwd res;
DWORD len = sizeof(res.pw_name);
GetUserNameA(res.pw_name, &len);
SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, res.pw_dir);
return &res;
}
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#ifndef FASTFETCH_INCLUDED_UTIL_PWD
#define FASTFETCH_INCLUDED_UTIL_PWD
#include <Lmcons.h>
#include <minwindef.h>
struct passwd
{
char pw_name[UNLEN + 1]; /* username */
// char *pw_passwd[1]; /* user password */
// int pw_uid; /* user ID */
// int pw_gid; /* group ID */
// char *pw_gecos; /* user information */
char pw_dir[MAX_PATH]; /* home directory */
// char *pw_shell; /* shell program */
};
struct passwd* ffGetPasswd();
#endif
+59
View File
@@ -0,0 +1,59 @@
// https://github.com/tniessen/iperf-windows/blob/master/win32-compat/sys/utsname.c
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <stdio.h>
#include "utsname.h"
int uname(struct utsname *name)
{
memset(name, 0, sizeof(*name));
// Get Windows version info
OSVERSIONINFOA versionInfo = {
.dwOSVersionInfoSize = sizeof(OSVERSIONINFO),
};
GetVersionExA(&versionInfo);
// Get hardware info
SYSTEM_INFO sysInfo = {0};
GetSystemInfo(&sysInfo);
// Set implementation name
strcpy(name->sysname, "Windows_NT");
sprintf(name->release, "%u.%u.%u", (unsigned)versionInfo.dwMajorVersion, (unsigned)versionInfo.dwMinorVersion, (unsigned)versionInfo.dwBuildNumber);
name->version[0] = '\0';
// Set hostname
DWORD bufSize = UTSNAME_MAXLENGTH - 1;
if(GetComputerNameA(name->nodename, &bufSize))
return 1;
name->nodename[bufSize] = '\0';
// Set processor architecture
switch (sysInfo.wProcessorArchitecture)
{
case PROCESSOR_ARCHITECTURE_AMD64:
strcpy(name->machine, "x86_64");
break;
case PROCESSOR_ARCHITECTURE_IA64:
strcpy(name->machine, "ia64");
break;
case PROCESSOR_ARCHITECTURE_INTEL:
strcpy(name->machine, "x86");
break;
case PROCESSOR_ARCHITECTURE_ARM64:
strcpy(name->machine, "aarch64");
break;
case PROCESSOR_ARCHITECTURE_ARM:
strcpy(name->machine, "arm");
break;
case PROCESSOR_ARCHITECTURE_UNKNOWN:
default:
strcpy(name->machine, "unknown");
}
return 0;
}
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#ifndef FASTFETCH_INCLUDED_UTSNAME_H
#define FASTFETCH_INCLUDED_UTSNAME_H
#define UTSNAME_MAXLENGTH 256
struct utsname
{
char sysname[UTSNAME_MAXLENGTH]; // name of this implementation of the operating system
char nodename[UTSNAME_MAXLENGTH]; // name of this node within an implementation - dependent communications network
char release[UTSNAME_MAXLENGTH]; // current release level of this implementation
char version[UTSNAME_MAXLENGTH]; // current version level of this release
char machine[UTSNAME_MAXLENGTH]; // name of the hardware type on which the system is running
};
int uname(struct utsname *name);
#endif
+5 -8
View File
@@ -13,9 +13,6 @@ static void CoUninitializeWrap()
static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext)
{
static char error[128];
*((char**)lpContext) = error;
HRESULT hres;
// Initialize COM
@@ -37,7 +34,7 @@ static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext)
if (FAILED(hres))
{
CoUninitialize();
snprintf(error, sizeof(error), "Failed to initialize security. Error code = 0x%X", hres);
*((const char**)lpContext) = "Failed to initialize security";
return FALSE;
}
@@ -53,7 +50,7 @@ static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext)
if (FAILED(hres))
{
CoUninitialize();
snprintf(error, sizeof(error), "Failed to create IWbemLocator object. Error code = 0x%X", hres);
*((const char**)lpContext) = "Failed to create IWbemLocator object";
return FALSE;
}
@@ -79,7 +76,7 @@ static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext)
if (FAILED(hres))
{
CoUninitialize();
snprintf(error, sizeof(error), "Could not connect WMI server. Error code = 0x%X", hres);
*((const char**)lpContext) = "Could not connect WMI server";
return FALSE;
}
@@ -99,7 +96,7 @@ static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext)
{
pSvc->Release();
CoUninitialize();
snprintf(error, sizeof(error), "Could not set proxy blanket. Error code = 0x%X", hres);
*((const char**)lpContext) = "Could not set proxy blanket";
return FALSE;
}
@@ -134,7 +131,7 @@ IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error)
if (FAILED(hres))
{
if(error)
ffStrbufAppendF(error, "Query for '%ls' failed. Error code = 0x%X", queryStr, hres);
ffStrbufAppendF(error, "Query for '%ls' failed. Error code = 0x%lX", queryStr, hres);
return nullptr;
}