From 74315872e5104396feb90c1155adbc20bf6ee78c Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Sun, 30 Apr 2023 17:57:02 -0400 Subject: Add windows support --- CMakeLists.txt | 2 +- common.h | 19 +++++---- main.c | 2 +- win.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ win.h | 49 ++++++++++++++++++++++++ x86.c | 19 +++++++++ x86.h | 2 +- 7 files changed, 202 insertions(+), 10 deletions(-) create mode 100644 win.c create mode 100644 win.h diff --git a/CMakeLists.txt b/CMakeLists.txt index dd032c7..93a0e40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,4 +3,4 @@ project(whatami C) set(CMAKE_C_STANDARD 99) -add_executable(whatami main.c util.c darwin.c linux.c common.h x86.c x86.h) +add_executable(whatami main.c util.c darwin.c linux.c common.h x86.c x86.h win.c win.h) diff --git a/common.h b/common.h index a5a1fee..c69b058 100644 --- a/common.h +++ b/common.h @@ -4,18 +4,24 @@ #include #include #include -#include -#include -#include #include -#include #include -#if defined(__x86_64__) || defined(__i386__) +#if defined(_WINDOWS) || defined(__MINGW32__) +#include "win.h" +#else +#include +#include +#include +#include +#endif + +#if defined(__x86_64__) || defined(__i386__) || defined(__MACHINEX86_X64) #include "x86.h" #endif #if defined(__linux__) +// nothing yet #elif defined(__APPLE__) #include #include @@ -51,11 +57,10 @@ unsigned int get_cpu_count(); char *get_cpu_manufacturer(); char *get_cpu_vendor(); - size_t rstrip(char *s); +char *get_sys_dmi_product(); int get_sys_os_dist(char **name, char **version); ssize_t get_sys_memory(); -char *get_sys_dmi_product(); struct Block_Device **get_block_devices(size_t *total); #endif //WHATAMI_COMMON_H diff --git a/main.c b/main.c index 0486f11..60cd05a 100644 --- a/main.c +++ b/main.c @@ -59,7 +59,7 @@ int main() { for (size_t bd = 0; bd < device_count; bd++) { struct Block_Device *p; p = block_device[bd]; - printf(" %s /dev/%s (%.2lfGB)\n", p->model, p->path, (double) p->size / 1024 / 1024); + printf(" %s %s (%.2lfGB)\n", p->model, p->path, (double) p->size / 1024 / 1024); } } diff --git a/win.c b/win.c new file mode 100644 index 0000000..a7a1951 --- /dev/null +++ b/win.c @@ -0,0 +1,119 @@ +#if defined(_MSC_VER) || defined(__MINGW32__) +#include "common.h" +#include + +static OSVERSIONINFO get_os_version_info() { + static OSVERSIONINFO osinfo; + static int cached = 0; + if (cached) { + return osinfo; + } + memset(&osinfo, 0, sizeof(OSVERSIONINFOA)); + osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + GetVersionExA((OSVERSIONINFOA *) &osinfo); + cached = 1; + return osinfo; +} + +int uname(struct utsname *buf) { + char value[255] = {0}; + unsigned long size; + + memset(buf, 0, sizeof(struct utsname)); + size = sizeof(value) - 1; + strcpy_s(buf->sysname, sizeof(buf->sysname) - 1, "Win" BITSUFFIX); + GetComputerNameEx(ComputerNameDnsFullyQualified, value, &size); + strcpy_s(buf->nodename, sizeof(buf->nodename) - 1, value); + + SYSTEM_INFO sysinfo; + GetNativeSystemInfo(&sysinfo); + switch (sysinfo.wProcessorArchitecture) { + case PROCESSOR_AMD_X8664: + case PROCESSOR_ARCHITECTURE_AMD64: + strcpy_s(buf->machine, sizeof(buf->machine) - 1, "x86_64"); + break; + case PROCESSOR_ARCHITECTURE_ARM64: + strcpy_s(buf->machine, sizeof(buf->machine) - 1, "arm64"); + break; + case PROCESSOR_ARCHITECTURE_UNKNOWN: + default: + strcpy_s(buf->machine, sizeof(buf->machine) - 1, "unknown"); + break; + } + + OSVERSIONINFO osinfo; + memset(&osinfo, 0, sizeof(OSVERSIONINFOA)); + osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + GetVersionExA((OSVERSIONINFOA *) &osinfo); + sprintf_s(buf->release, sizeof(buf->release) - 1, "%lu.%lu", osinfo.dwMajorVersion, osinfo.dwMinorVersion); + sprintf_s(buf->version, sizeof(buf->release) - 1, "build %lu", osinfo.dwBuildNumber); + return 0; +} + +int get_sys_os_dist(char **name, char **version) { + char lversion[255]; + OSVERSIONINFO osinfo; + osinfo = get_os_version_info(); + + if (IsWindows10OrGreater()) { + strcpy_s(lversion, sizeof(lversion) - 1, "Windows 10"); + } else if (IsWindows8OrGreater()) { + strcpy_s(lversion, sizeof(lversion) - 1, "Windows 8"); + } else if (IsWindows7OrGreater()) { + strcpy_s(lversion, sizeof(lversion) - 1, "Windows 7"); + } else if (IsWindowsVistaOrGreater()) { + strcpy_s(lversion, sizeof(lversion) - 1, "Windows Vista"); + } else if (IsWindowsXPOrGreater()) { + strcpy_s(lversion, sizeof(lversion) - 1, "Windows XP"); + } else if (IsWindowsServer()) { + strcpy_s(lversion, sizeof(lversion) - 1, "Windows Server"); + } else if (osinfo.dwMajorVersion == 5 && osinfo.dwMinorVersion == 0) { + strcpy_s(lversion, sizeof(lversion) - 1, "Windows 2000"); + } else if (osinfo.dwMajorVersion == 4 && osinfo.dwMinorVersion == 0 && osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) { + strcpy_s(lversion, sizeof(lversion) - 1, "Windows NT 4.0"); + } else if (osinfo.dwMajorVersion == 4 && osinfo.dwMinorVersion == 90 && osinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { + strcpy_s(lversion, sizeof(lversion) - 1, "Windows ME"); + } else if (osinfo.dwMajorVersion == 4 && osinfo.dwMinorVersion == 10 && osinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { + strcpy_s(lversion, sizeof(lversion) - 1, "Windows 98"); + } else { + strcpy_s(lversion, sizeof(lversion) - 1, "Windows"); + } + + *name = _strdup("Microsoft"); + *version = _strdup(lversion); + return 0; +} + +ssize_t get_sys_memory() { + MEMORYSTATUSEX buf; + buf.dwLength = sizeof(buf); + GlobalMemoryStatusEx(&buf); + return (ssize_t) buf.ullTotalPhys / 1024; +} + +struct Block_Device **get_block_devices(size_t *total) { + struct Block_Device **device; + char buf[256] = {0}; + DWORD len; + + // Each drive name record is 4 bytes (e.g. "C:\\0") + len = GetLogicalDriveStringsA(sizeof(buf) - 1, buf); + if (!len) { + return NULL; + } + + size_t device_count; + device_count = len / 4; + device = calloc(device_count + 1, sizeof(**device)); + for (DWORD i = 0, j = 0; strlen(&buf[j]) != 0 && i < device_count; i++) { + device[i] = calloc(1, sizeof(*device[0])); + device[i]->model = _strdup("Unnamed"); + device[i]->path = _strdup(&buf[j]); + GetDiskFreeSpaceExA(device[i]->path, NULL, (PULARGE_INTEGER) &device[i]->size, NULL); + device[i]->size /= 1024; + j += 4; + } + *total = device_count; + return device; +} +#endif // _WINDOWS \ No newline at end of file diff --git a/win.h b/win.h new file mode 100644 index 0000000..96dfb68 --- /dev/null +++ b/win.h @@ -0,0 +1,49 @@ +#ifndef WHATAMI_WIN_H +#define WHATAMI_WIN_H + +#include + +#if defined(_WIN32) +#undef BITSUFFIX +#define BITSUFFIX "32" +#endif + +#if defined(_WIN64) +#undef BITSUFFIX +#define BITSUFFIX "64" +#endif + +#if defined(_MSC_VER) +#include + +#if defined(__get_cpuid) +#undef __get_cpuid +#endif + +static inline int __get_cpuid(int leaf, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { + int info[4] = {0}; + __cpuid(info, leaf); + *eax = info[0]; + *ebx = info[1]; + *ecx = info[2]; + *edx = info[3]; + return info[0]; +} +#else +#include +#endif + +struct utsname { + char sysname[255]; + char nodename[255]; + char release[255]; + char version[255]; + char machine[255]; +}; +int uname(struct utsname *buf); + +#if !defined(ssize_t) +typedef long long ssize_t; +#endif + +#endif //WHATAMI_WIN_H diff --git a/x86.c b/x86.c index e26271e..12bde66 100644 --- a/x86.c +++ b/x86.c @@ -54,6 +54,25 @@ char *get_sys_product() { strcpy(vendor, get_sys_product_darwin()); rstrip(vendor); } +#elif defined(_WIN32) || defined(_WIN64) + HKEY data; + long result; + DWORD size = sizeof(vendor) - 1; + result = RegOpenKeyExA(HKEY_LOCAL_MACHINE, + "SYSTEM\\CurrentControlSet\\Control\\SystemInformation", + 0, + KEY_READ, + &data); + if (!result) { + if (!RegQueryValueEx(data, + "SystemProductName", + 0, + NULL, + (LPBYTE) vendor, + &size)) { + RegCloseKey(data); + } + } #endif return vendor; } diff --git a/x86.h b/x86.h index 9d7ec4f..91d481d 100644 --- a/x86.h +++ b/x86.h @@ -1,6 +1,6 @@ #ifndef WHATAMI_X86_H #define WHATAMI_X86_H -#if defined(__x86_64__) || defined(__i386__) +#if defined(__x86_64__) || defined(__i386__) || defined(__MACHINEX86_X64) #ifndef bit_HTT // Hyperthreading -- cgit