Introduce FFPlatform

This commit is contained in:
Linus Dierheimer
2023-01-15 15:57:26 +01:00
parent dd77ebe11e
commit a1d8e3e598
39 changed files with 622 additions and 560 deletions
+11
View File
@@ -3,6 +3,17 @@
#include <ctype.h>
#include <inttypes.h>
bool ffStrSet(const char* str)
{
if(str == NULL)
return false;
while(isspace(*str))
str++;
return *str != '\0';
}
static char* CHAR_NULL_PTR = "";
void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate)
+2
View File
@@ -18,6 +18,8 @@
#define strcasestr StrStrIA
#endif
bool ffStrSet(const char* str);
#define FASTFETCH_STRBUF_DEFAULT_ALLOC 32
typedef struct FFstrbuf
+118
View File
@@ -0,0 +1,118 @@
#include "FFPlatform_private.h"
void ffPlatformInit(FFPlatform* platform)
{
ffStrbufInit(&platform->homeDir);
ffStrbufInit(&platform->cacheDir);
ffListInit(&platform->configDirs, sizeof(FFstrbuf));
ffListInit(&platform->dataDirs, sizeof(FFstrbuf));
ffStrbufInit(&platform->userName);
ffStrbufInit(&platform->hostName);
ffStrbufInit(&platform->domainName);
ffStrbufInit(&platform->userShell);
ffStrbufInit(&platform->systemName);
ffStrbufInit(&platform->systemRelease);
ffStrbufInit(&platform->systemVersion);
ffStrbufInit(&platform->systemArchitecture);
ffPlatformInitÎmpl(platform);
if(platform->domainName.length == 0)
ffStrbufAppend(&platform->domainName, &platform->hostName);
if(platform->systemName.length == 0)
{
#if defined(__linux__)
ffStrbufAppendS(&platform->systemName, "Linux");
#elif defined(__FreeBSD__)
ffStrbufAppendS(&platform->systemName, "FreeBSD");
#elif defined(__APPLE__)
ffStrbufAppendS(&platform->systemName, "Darwin");
#elif defined(__WIN32__) || defined(__WIN64__)
ffStrbufAppendS(&platform->systemName, "Windows_NT");
#endif
}
if(platform->systemArchitecture.length == 0)
{
#if defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64)
ffStrbufAppendS(&platform->systemArchitecture, "x86_64");
#elif defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(__i586__) || defined(__i586) || defined(__i686__) || defined(__i686)
ffStrbufAppendS(&platform->systemArchitecture, "i386");
#elif defined(__aarch64__)
ffStrbufAppendS(&platform->systemArchitecture, "aarch64");
#elif defined(__arm__)
ffStrbufAppendS(&platform->systemArchitecture, "arm");
#endif
}
}
void ffPlatformDestroy(FFPlatform* platform)
{
ffStrbufDestroy(&platform->homeDir);
ffStrbufDestroy(&platform->cacheDir);
FF_LIST_FOR_EACH(FFstrbuf, dir, platform->configDirs)
ffStrbufDestroy(dir);
ffListDestroy(&platform->configDirs);
FF_LIST_FOR_EACH(FFstrbuf, dir, platform->dataDirs)
ffStrbufDestroy(dir);
ffListDestroy(&platform->dataDirs);
ffStrbufDestroy(&platform->userName);
ffStrbufDestroy(&platform->hostName);
ffStrbufDestroy(&platform->domainName);
ffStrbufDestroy(&platform->userShell);
}
void ffPlatformPathAddAbsolute(FFlist* dirs, const char* path)
{
FFstrbuf* buffer = (FFstrbuf*) ffListAdd(dirs);
ffStrbufInitA(buffer, 64);
ffStrbufAppendS(buffer, path);
ffStrbufEnsureEndsWithC(buffer, '/');
FF_PLATFORM_PATH_UNIQUE(dirs, buffer);
}
void ffPlatformPathAddHome(FFlist* dirs, const FFPlatform* platform, const char* suffix)
{
FFstrbuf* buffer = (FFstrbuf*) ffListAdd(dirs);
ffStrbufInitA(buffer, 64);
ffStrbufAppend(buffer, &platform->homeDir);
ffStrbufAppendS(buffer, suffix);
ffStrbufEnsureEndsWithC(buffer, '/');
FF_PLATFORM_PATH_UNIQUE(dirs, buffer);
}
void ffPlatformPathAddEnv(FFlist* dirs, const char* env)
{
const char* envValue = getenv(env);
if(!ffStrSet(envValue))
return;
FFstrbuf value;
ffStrbufInitA(&value, 64);
ffStrbufAppendS(&value, envValue);
uint32_t startIndex = 0;
while (startIndex < value.length)
{
uint32_t colonIndex = ffStrbufNextIndexC(&value, startIndex, ':');
value.chars[colonIndex] = '\0';
if(!ffStrSet(value.chars + startIndex))
{
startIndex = colonIndex + 1;
continue;
}
ffPlatformPathAddAbsolute(dirs, value.chars + startIndex);
startIndex = colonIndex + 1;
}
ffStrbufDestroy(&value);
}
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#ifndef FF_INCLUDED_util_platform_FFPlatform
#define FF_INCLUDED_util_platform_FFPlatform
#include "util/FFstrbuf.h"
#include "util/FFlist.h"
typedef struct FFPlatform {
FFstrbuf homeDir; // Trailing slash included
FFstrbuf cacheDir; // Trailing slash included
FFlist configDirs; // List of FFstrbuf, trailing slash included
FFlist dataDirs; // List of FFstrbuf, trailing slash included
FFstrbuf userName;
FFstrbuf hostName;
FFstrbuf domainName;
FFstrbuf userShell;
FFstrbuf systemName;
FFstrbuf systemRelease;
FFstrbuf systemVersion;
FFstrbuf systemArchitecture;
} FFPlatform;
void ffPlatformInit(FFPlatform* platform);
void ffPlatformDestroy(FFPlatform* platform);
#endif
+21
View File
@@ -0,0 +1,21 @@
#pragma once
#ifndef FF_INCLUDED_util_platform_FFPlatform_private
#define FF_INCLUDED_util_platform_FFPlatform_private
#include "FFPlatform.h"
void ffPlatformInitÎmpl(FFPlatform* platform);
#define FF_PLATFORM_PATH_UNIQUE(list, element) \
if(ffListFirstIndexComp(list, element, (bool(*)(const void*, const void*))ffStrbufEqual) < list->length - 1) \
{ \
ffStrbufDestroy(ffListGet(list, list->length - 1)); \
--list->length; \
}
void ffPlatformPathAddAbsolute(FFlist* dirs, const char* path);
void ffPlatformPathAddHome(FFlist* dirs, const FFPlatform* platform, const char* suffix);
void ffPlatformPathAddEnv(FFlist* dirs, const char* env);
#endif
+138
View File
@@ -0,0 +1,138 @@
#include "FFPlatform_private.h"
#include "fastfetch_config.h"
#include <unistd.h>
#include <pwd.h>
#include <sys/utsname.h>
#include <netdb.h>
static void getHomeDir(FFPlatform* platform, const struct passwd* pwd)
{
const char* home = getenv("HOME");
if(!ffStrSet(home) && pwd)
home = pwd->pw_dir;
ffStrbufAppendS(&platform->homeDir, home);
ffStrbufEnsureEndsWithC(&platform->homeDir, '/');
}
static void getCacheDir(FFPlatform* platform)
{
const char* cache = getenv("XDG_CACHE_HOME");
if(ffStrSet(cache))
{
ffStrbufAppendS(&platform->cacheDir, cache);
ffStrbufEnsureEndsWithC(&platform->cacheDir, '/');
}
else
{
ffStrbufAppend(&platform->cacheDir, &platform->homeDir);
ffStrbufAppendS(&platform->cacheDir, ".cache/");
}
ffStrbufAppendS(&platform->cacheDir, "fastfetch/");
}
static void getConfigDirs(FFPlatform* platform)
{
ffPlatformPathAddEnv(&platform->configDirs, "XDG_CONFIG_HOME");
ffPlatformPathAddHome(&platform->configDirs, platform, ".config/");
#if defined(__APPLE__)
pathsAddHome(&state->configDirs, state, "/Library/Preferences/");
#endif
ffPlatformPathAddHome(&platform->configDirs, platform, "");
ffPlatformPathAddEnv(&platform->configDirs, "XDG_CONFIG_DIRS");
#if !defined(__APPLE__)
ffPlatformPathAddAbsolute(&platform->configDirs, FASTFETCH_TARGET_DIR_ETC"/xdg/");
#endif
ffPlatformPathAddAbsolute(&platform->configDirs, FASTFETCH_TARGET_DIR_ETC"/");
ffPlatformPathAddAbsolute(&platform->configDirs, FASTFETCH_TARGET_DIR_INSTALL_SYSCONF"/");
}
static void getDataDirs(FFPlatform* platform)
{
ffPlatformPathAddEnv(&platform->dataDirs, "XDG_DATA_HOME");
ffPlatformPathAddHome(&platform->dataDirs, platform, ".local/share/");
ffPlatformPathAddHome(&platform->dataDirs, platform, "");
ffPlatformPathAddEnv(&platform->dataDirs, "XDG_DATA_DIRS");
ffPlatformPathAddAbsolute(&platform->dataDirs, FASTFETCH_TARGET_DIR_USR"/local/share/");
ffPlatformPathAddAbsolute(&platform->dataDirs, FASTFETCH_TARGET_DIR_USR"/share/");
}
static void getUserName(FFPlatform* platform, const struct passwd* pwd)
{
const char* user = getenv("USER");
if(!ffStrSet(user) && pwd)
user = pwd->pw_name;
ffStrbufAppendS(&platform->userName, user);
}
static void getHostName(FFPlatform* platform, const struct utsname* uts)
{
char hostname[256];
if(gethostname(hostname, sizeof(hostname)) == 0)
ffStrbufAppendS(&platform->hostName, hostname);
if(platform->hostName.length == 0)
ffStrbufAppendS(&platform->hostName, uts->nodename);
}
static void getDomainName(FFPlatform* platform)
{
struct addrinfo hints = {0};
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_CANONNAME;
struct addrinfo* info = NULL;
if(getaddrinfo(platform->hostName.chars, "80", &hints, &info) != 0)
return;
struct addrinfo* current = info;
while(platform->domainName.length == 0 && current != NULL)
{
ffStrbufAppendS(&platform->domainName, current->ai_canonname);
current = current->ai_next;
}
freeaddrinfo(info);
}
static void getUserShell(FFPlatform* platform, const struct passwd* pwd)
{
const char* shell = getenv("SHELL");
if(!ffStrSet(shell) && pwd)
shell = pwd->pw_shell;
ffStrbufAppendS(&platform->userShell, shell);
}
void ffPlatformInitÎmpl(FFPlatform* platform)
{
struct passwd* pwd = getpwuid(getuid());
struct utsname uts;
if(uname(&uts) != 0)
memset(&uts, 0, sizeof(uts));
getHomeDir(platform, pwd);
getCacheDir(platform);
getConfigDirs(platform);
getDataDirs(platform);
getUserName(platform, pwd);
getHostName(platform, &uts);
getDomainName(platform);
getUserShell(platform, pwd);
ffStrbufAppendS(&platform->systemName, uts.sysname);
ffStrbufAppendS(&platform->systemRelease, uts.release);
ffStrbufAppendS(&platform->systemVersion, uts.version);
ffStrbufAppendS(&platform->systemArchitecture, uts.machine);
}
+228
View File
@@ -0,0 +1,228 @@
#include "FFPlatform_private.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <shlobj.h>
#include "util/windows/unicode.h"
static void getHomeDir(FFPlatform* platform)
{
PWSTR pPath;
if(SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_Profile, KF_FLAG_DEFAULT, NULL, &pPath)))
{
ffStrbufSetWS(&platform->home_dir, pPath);
ffStrbufReplaceAllC(&platform->home_dir, '\\', '/');
ffStrbufEnsureEndsWithC(&platform->home_dir, '/');
}
CoTaskMemFree(pPath);
}
static void getCacheDir(FFPlatform* platform)
{
PWSTR pPath;
if(SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_LocalAppData, KF_FLAG_DEFAULT, NULL, &pPath)))
{
ffStrbufSetWS(&platform->cache_dir, pPath);
ffStrbufReplaceAllC(&platform->cache_dir, '\\', '/');
ffStrbufEnsureEndsWithC(&platform->cache_dir, '/');
}
else
{
ffStrbufAppend(&platform->cache_dir, &platform->home_dir);
ffStrbufAppendS(&platform->cache_dir, "AppData/Local/");
}
CoTaskMemFree(pPath);
ffStrbufAppendS(&platform->cache_dir, "fastfetch/");
}
static void platformPathAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId)
{
PWSTR pPath;
if(SUCCEEDED(SHGetKnownFolderPath(folderId, 0, NULL, &pPath)))
{
FFstrbuf* buffer = (FFstrbuf*) ffListAdd(dirs);
ffStrbufInit(buffer);
ffStrbufSetWS(buffer, pPath);
ffStrbufReplaceAllC(buffer, '\\', '/');
ffStrbufEnsureEndsWithC(buffer, '/');
FF_PLATFORM_PATH_UNIQUE(dirs, buffer);
}
CoTaskMemFree(pPath);
}
static void platformPathAddEnvSuffix(FFlist* dirs, const char* env, const char* suffix)
{
const char* value = getenv(env);
if(!ffStrSet(value))
return;
FFstrbuf* buffer = ffListAdd(dirs);
ffStrbufInitA(buffer, 64);
ffStrbufAppendS(buffer, value);
ffStrbufReplaceAllC(buffer, '\\', '/');
ffStrbufEnsureEndsWithC(buffer, '/');
ffStrbufAppendS(buffer, suffix);
ffStrbufEnsureEndsWithC(buffer, '/');
FF_PLATFORM_PATH_UNIQUE(dirs, buffer);
}
static void getConfigDirs(FFPlatform* platform)
{
ffListInit(&platform->configDirs, sizeof(FFstrbuf));
ffPlatformPathAddEnv(&platform->configDirs, "XDG_CONFIG_HOME");
ffPlatformPathAddHome(&platform->configDirs, platform, "/.config/");
platformPathAddKnownFolder(&platform->configDirs, &FOLDERID_RoamingAppData);
platformPathAddKnownFolder(&platform->configDirs, &FOLDERID_LocalAppData);
ffPlatformPathAddHome(&platform->configDirs, platform, "");
if(getenv("MSYSTEM") && getenv("HOME"))
{
// We are in MSYS2 / Git Bash
platformPathAddEnvSuffix(&platform->configDirs, "HOME", ".config/");
platformPathAddEnvSuffix(&platform->configDirs, "HOME", "");
}
ffPlatformPathAddEnv(&platform->configDirs, "XDG_CONFIG_DIRS");
}
static void getConfigDirs(FFPlatform* platform)
{
ffPlatformPathAddEnv(&platform->dataDirs, "XDG_DATA_HOME");
ffPlatformPathAddHome(&platform->dataDirs, platform, "/.local/share/");
platformPathAddKnownFolder(&platform->dataDirs, &FOLDERID_RoamingAppData);
platformPathAddKnownFolder(&platform->dataDirs, &FOLDERID_LocalAppData);
ffPlatformPathAddHome(&platform->dataDirs, platform, "");
if(getenv("MSYSTEM") && getenv("HOME"))
{
// We are in MSYS2 / Git Bash
platformPathAddEnvSuffix(&platform->dataDirs, "HOME", ".local/share/");
platformPathAddEnvSuffix(&platform->dataDirs, "HOME", "");
}
ffPlatformPathAddEnv(&platform->dataDirs, "XDG_DATA_DIRS");
}
static void getUserName(FFPlatform* platform)
{
ffStrbufEnsureFree(&platform->userName, 64);
GetUserNameA(platform->userName.chars, (LPDWORD) ffStrbufGetFree(&platform->userName));
ffStrbufRecalculateLength(&platform->userName);
}
static void getHostName(FFPlatform* platform)
{
ffStrbufEnsureFree(&platform->hostName, 64);
GetComputerNameA(platform->hostName.chars, (LPDWORD) ffStrbufGetFree(&platform->hostName));
ffStrbufRecalculateLength(&platform->hostName);
}
static void getDomainName(FFPlatform* platform)
{
ffStrbufEnsureFree(&platform->domainName, 64);
GetComputerNameExA(ComputerNameDnsDomain, platform->domainName.chars, (LPDWORD) ffStrbufGetFree(&platform->domainName));
ffStrbufRecalculateLength(&platform->domainName);
}
static void getSystemName(FFPlatform* platform)
{
ffStrbufAppendS(&platform->systemName, "Windows_NT");
}
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)
return;
DWORD bufSize;
char currentVersion[32];
{
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");
}
}
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(RegGetValueA(hKey, NULL, "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);
RegGetValueA(hKey, NULL, "DisplayVersion", RRF_RT_REG_SZ, NULL, platform->systemVersion.chars, (LPDWORD) ffStrbufGetFree(&platform->systemVersion));
ffStrbufRecalculateLength(&platform->systemVersion);
RegCloseKey(hKey);
}
static void getSystemArchitecture(FFPlatform* platform)
{
SYSTEM_INFO sysInfo = {0};
GetNativeSystemInfo(&sysInfo);
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_PPC:
strcpy(name->machine, "ppc");
break;
case PROCESSOR_ARCHITECTURE_MIPS:
strcpy(name->machine, "mips");
break;
case PROCESSOR_ARCHITECTURE_UNKNOWN:
default:
break;
}
}
void ffPlatformInitÎmpl(FFPlatform* platform)
{
getHomeDir(platform);
getCacheDir(platform);
getConfigDirs(platform);
getDataDirs(platform);
getUserName(platform);
getHostName(platform);
getDomainName(platform);
getSystemName(platform);
getSystemReleaseAndVersion(platform);
getSystemArchitecture(platform);
}
-22
View File
@@ -1,22 +0,0 @@
#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);
PWSTR pPath;
if(SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_Profile, KF_FLAG_DEFAULT, NULL, &pPath)))
WideCharToMultiByte(CP_UTF8, 0, pPath, -1, res.pw_dir, sizeof(res.pw_dir), NULL, NULL); //res has been NULL inited
CoTaskMemFree(pPath);
for (char *current_pos = strchr(res.pw_dir, '\\'); current_pos; current_pos = strchr(current_pos + 1, '\\'))
*current_pos = '/';
return &res;
}
-22
View File
@@ -1,22 +0,0 @@
#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
+3 -1
View File
@@ -3,16 +3,18 @@
#ifndef FASTFETCH_INCLUDED_UNICODE_H
#define FASTFETCH_INCLUDED_UNICODE_H
#include "fastfetch.h"
#include "util/FFstrbuf.h"
#include <wchar.h>
void ffStrbufSetNWS(FFstrbuf* result, uint32_t length, const wchar_t* source);
static inline void ffStrbufSetWS(FFstrbuf* result, const wchar_t* source)
{
return ffStrbufSetNWS(result, (uint32_t)wcslen(source), source);
}
FFstrbuf ffStrbufCreateNWS(uint32_t length, const wchar_t* source);
static inline FFstrbuf ffStrbufCreateWS(const wchar_t* source)
{
return ffStrbufCreateNWS((uint32_t)wcslen(source), source);
-116
View File
@@ -1,116 +0,0 @@
#include "fastfetch.h"
#include "utsname.h"
#define WIN32_LEAN_AND_MEAN 1
#include <Windows.h>
static int detectSysname(struct utsname *name)
{
strncpy(name->sysname, "Windows_NT", UTSNAME_MAXLENGTH);
return 0;
}
static int detectNodename(struct utsname *name)
{
DWORD bufSize = UTSNAME_MAXLENGTH - 1;
if(!GetComputerNameExA(ComputerNameDnsFullyQualified, name->nodename, &bufSize))
return 1;
name->nodename[bufSize] = '\0';
return 0;
}
static int detectVersion(struct utsname *name)
{
HKEY hKey;
if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
return 1;
DWORD bufSize;
char currentVersion[32];
{
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");
}
}
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(RegGetValueA(hKey, NULL, "UBR", RRF_RT_REG_DWORD, NULL, &ubr, &bufSize) != ERROR_SUCCESS || bufSize != sizeof(ubr))
ubr = 0;
snprintf(name->release, sizeof(name->release), "%s.%s.%u", currentVersion, currentBuildNumber, (unsigned)ubr);
bufSize = sizeof(name->version);
RegGetValueA(hKey, NULL, "DisplayVersion", RRF_RT_REG_SZ, NULL, name->version, &bufSize);
RegCloseKey(hKey);
return 0;
}
static int detectMachine(struct utsname *name)
{
// Get hardware info
SYSTEM_INFO sysInfo = {0};
GetNativeSystemInfo(&sysInfo);
// 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_PPC:
strcpy(name->machine, "ppc");
break;
case PROCESSOR_ARCHITECTURE_MIPS:
strcpy(name->machine, "mips");
break;
case PROCESSOR_ARCHITECTURE_UNKNOWN:
default:
strcpy(name->machine, "unknown");
break;
}
return 0;
}
int uname(struct utsname *name)
{
memset(name, 0, sizeof(*name));
int sysnameResult = detectSysname(name);
int nodenameResult = detectNodename(name);
int versionResult = detectVersion(name);
int machineResult = detectMachine(name);
return sysnameResult || nodenameResult || versionResult || machineResult;
}
-19
View File
@@ -1,19 +0,0 @@
#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