odin report: Add FreeBSD OS & RAM detection.

This commit is contained in:
Jeroen van Rijn
2022-09-05 15:00:29 +02:00
parent 8421cb6d21
commit fb2cbe471b
+264 -211
View File
@@ -22,6 +22,10 @@
#include <sys/utsname.h> #include <sys/utsname.h>
#endif #endif
#if defined(GB_SYSTEM_FREEBSD)
#include <sys/sysctl.h>
#endif
/* /*
NOTE(Jeroen): This prints the Windows product edition only, to be called from `print_platform_details`. NOTE(Jeroen): This prints the Windows product edition only, to be called from `print_platform_details`.
*/ */
@@ -217,7 +221,6 @@ void report_cpu_info() {
Report the amount of installed RAM. Report the amount of installed RAM.
*/ */
void report_ram_info() { void report_ram_info() {
gb_printf("\tRAM: "); gb_printf("\tRAM: ");
#if defined(GB_SYSTEM_WINDOWS) #if defined(GB_SYSTEM_WINDOWS)
@@ -255,235 +258,213 @@ void report_ram_info() {
if (sysctl(sysctls, 2, &ram_amount, &val_size, NULL, 0) != -1) { if (sysctl(sysctls, 2, &ram_amount, &val_size, NULL, 0) != -1) {
gb_printf("%lld MiB\n", ram_amount / gb_megabytes(1)); gb_printf("%lld MiB\n", ram_amount / gb_megabytes(1));
} }
#elif defined(GB_SYSTEM_FREEBSD)
uint64_t ram_amount;
size_t val_size = sizeof(ram_amount);
int sysctls[] = { CTL_HW, HW_PHYSMEM };
if (sysctl(sysctls, 2, &ram_amount, &val_size, NULL, 0) != -1) {
gb_printf("%lu MiB\n", ram_amount / gb_megabytes(1));
}
#else #else
gb_printf("Unknown.\n"); gb_printf("Unknown.\n");
#endif #endif
} }
/* void report_os_info() {
NOTE(Jeroen): `odin report` prints some system information for easier bug reporting.
*/
void print_bug_report_help() {
gb_printf("Where to find more information and get into contact when you encounter a bug:\n\n");
gb_printf("\tWebsite: https://odin-lang.org\n");
gb_printf("\tGitHub: https://github.com/odin-lang/Odin/issues\n");
/*
Uncomment and update URL once we have a Discord vanity URL. For now people can get here from the site.
gb_printf("\tDiscord: https://discord.com/invite/sVBPHEv\n");
*/
gb_printf("\n\n");
gb_printf("Useful information to add to a bug report:\n\n");
gb_printf("\tOdin: %.*s", LIT(ODIN_VERSION));
#ifdef NIGHTLY
gb_printf("-nightly");
#endif
#ifdef GIT_SHA
gb_printf(":%s", GIT_SHA);
#endif
gb_printf("\n");
/*
Print OS information.
*/
gb_printf("\tOS: "); gb_printf("\tOS: ");
#if defined(GB_SYSTEM_WINDOWS) #if defined(GB_SYSTEM_WINDOWS)
/* /*
NOTE(Jeroen): NOTE(Jeroen):
`GetVersionEx` will return 6.2 for Windows 10 unless the program is manifested for Windows 10. `GetVersionEx` will return 6.2 for Windows 10 unless the program is manifested for Windows 10.
`RtlGetVersion` will return the true version. `RtlGetVersion` will return the true version.
Rather than include the WinDDK, we ask the kernel directly. Rather than include the WinDDK, we ask the kernel directly.
`HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion` is for the minor build version (Update Build Release) `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion` is for the minor build version (Update Build Release)
*/ */
OSVERSIONINFOEXW osvi; OSVERSIONINFOEXW osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEXW)); ZeroMemory(&osvi, sizeof(OSVERSIONINFOEXW));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
typedef NTSTATUS (WINAPI* RtlGetVersionPtr)(OSVERSIONINFOW*); typedef NTSTATUS (WINAPI* RtlGetVersionPtr)(OSVERSIONINFOW*);
typedef BOOL (WINAPI* GetProductInfoPtr)(DWORD dwOSMajorVersion, DWORD dwOSMinorVersion, DWORD dwSpMajorVersion, DWORD dwSpMinorVersion, PDWORD pdwReturnedProductType); typedef BOOL (WINAPI* GetProductInfoPtr)(DWORD dwOSMajorVersion, DWORD dwOSMinorVersion, DWORD dwSpMajorVersion, DWORD dwSpMinorVersion, PDWORD pdwReturnedProductType);
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlgetversion // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlgetversion
RtlGetVersionPtr RtlGetVersion = (RtlGetVersionPtr)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "RtlGetVersion"); RtlGetVersionPtr RtlGetVersion = (RtlGetVersionPtr)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "RtlGetVersion");
// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getproductinfo // https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getproductinfo
GetProductInfoPtr GetProductInfo = (GetProductInfoPtr)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo"); GetProductInfoPtr GetProductInfo = (GetProductInfoPtr)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo");
NTSTATUS status = {}; NTSTATUS status = {};
DWORD ProductType = {}; DWORD ProductType = {};
if (RtlGetVersion != nullptr) { if (RtlGetVersion != nullptr) {
status = RtlGetVersion((OSVERSIONINFOW*)&osvi); status = RtlGetVersion((OSVERSIONINFOW*)&osvi);
}
if (RtlGetVersion == nullptr || status != 0x0) {
gb_printf("Windows (Unknown Version)");
} else {
if (GetProductInfo != nullptr) {
GetProductInfo(osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.wServicePackMajor, osvi.wServicePackMinor, &ProductType);
} }
if (RtlGetVersion == nullptr || status != 0x0) { if (false) {
gb_printf("Windows (Unknown Version)"); gb_printf("dwMajorVersion: %u\n", cast(unsigned)osvi.dwMajorVersion);
} else { gb_printf("dwMinorVersion: %u\n", cast(unsigned)osvi.dwMinorVersion);
if (GetProductInfo != nullptr) { gb_printf("dwBuildNumber: %u\n", cast(unsigned)osvi.dwBuildNumber);
GetProductInfo(osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.wServicePackMajor, osvi.wServicePackMinor, &ProductType); gb_printf("dwPlatformId: %u\n", cast(unsigned)osvi.dwPlatformId);
} gb_printf("wServicePackMajor: %u\n", cast(unsigned)osvi.wServicePackMajor);
gb_printf("wServicePackMinor: %u\n", cast(unsigned)osvi.wServicePackMinor);
gb_printf("wSuiteMask: %u\n", cast(unsigned)osvi.wSuiteMask);
gb_printf("wProductType: %u\n", cast(unsigned)osvi.wProductType);
}
if (false) { gb_printf("Windows ");
gb_printf("dwMajorVersion: %u\n", cast(unsigned)osvi.dwMajorVersion);
gb_printf("dwMinorVersion: %u\n", cast(unsigned)osvi.dwMinorVersion);
gb_printf("dwBuildNumber: %u\n", cast(unsigned)osvi.dwBuildNumber);
gb_printf("dwPlatformId: %u\n", cast(unsigned)osvi.dwPlatformId);
gb_printf("wServicePackMajor: %u\n", cast(unsigned)osvi.wServicePackMajor);
gb_printf("wServicePackMinor: %u\n", cast(unsigned)osvi.wServicePackMinor);
gb_printf("wSuiteMask: %u\n", cast(unsigned)osvi.wSuiteMask);
gb_printf("wProductType: %u\n", cast(unsigned)osvi.wProductType);
}
gb_printf("Windows "); switch (osvi.dwMajorVersion) {
case 10:
switch (osvi.dwMajorVersion) { /*
case 10: Windows 10 (Pro), Windows 2016 Server, Windows 2019 Server, Windows 2022 Server
/* */
Windows 10 (Pro), Windows 2016 Server, Windows 2019 Server, Windows 2022 Server switch (osvi.wProductType) {
*/ case VER_NT_WORKSTATION: // Workstation
switch (osvi.wProductType) { if (osvi.dwBuildNumber < 22000) {
case VER_NT_WORKSTATION: // Workstation gb_printf("10 ");
if (osvi.dwBuildNumber < 22000) { } else {
gb_printf("10 "); gb_printf("11 ");
} else { }
gb_printf("11 ");
} report_windows_product_type(ProductType);
report_windows_product_type(ProductType);
break;
default: // Server or Domain Controller
switch(osvi.dwBuildNumber) {
case 14393:
gb_printf("2016 Server");
break; break;
default: // Server or Domain Controller case 17763:
switch(osvi.dwBuildNumber) { gb_printf("2019 Server");
case 14393: break;
gb_printf("2016 Server"); case 20348:
break; gb_printf("2022 Server");
case 17763: break;
gb_printf("2019 Server"); default:
break; gb_printf("Unknown Server");
case 20348: break;
gb_printf("2022 Server"); }
break; }
default: break;
gb_printf("Unknown Server"); case 6:
break; switch (osvi.dwMinorVersion) {
case 0:
switch (osvi.wProductType) {
case VER_NT_WORKSTATION:
gb_printf("Windows Vista ");
report_windows_product_type(ProductType);
break;
case 3:
gb_printf("Windows Server 2008");
break;
} }
} break;
break;
case 6:
switch (osvi.dwMinorVersion) {
case 0:
switch (osvi.wProductType) {
case VER_NT_WORKSTATION:
gb_printf("Windows Vista ");
report_windows_product_type(ProductType);
break;
case 3:
gb_printf("Windows Server 2008");
break;
}
break;
case 1: case 1:
switch (osvi.wProductType) { switch (osvi.wProductType) {
case VER_NT_WORKSTATION: case VER_NT_WORKSTATION:
gb_printf("Windows 7 "); gb_printf("Windows 7 ");
report_windows_product_type(ProductType); report_windows_product_type(ProductType);
break; break;
case 3: case 3:
gb_printf("Windows Server 2008 R2"); gb_printf("Windows Server 2008 R2");
break; break;
} }
break; break;
case 2: case 2:
switch (osvi.wProductType) { switch (osvi.wProductType) {
case VER_NT_WORKSTATION: case VER_NT_WORKSTATION:
gb_printf("Windows 8 "); gb_printf("Windows 8 ");
report_windows_product_type(ProductType); report_windows_product_type(ProductType);
break; break;
case 3: case 3:
gb_printf("Windows Server 2012"); gb_printf("Windows Server 2012");
break; break;
} }
break; break;
case 3: case 3:
switch (osvi.wProductType) { switch (osvi.wProductType) {
case VER_NT_WORKSTATION: case VER_NT_WORKSTATION:
gb_printf("Windows 8.1 "); gb_printf("Windows 8.1 ");
report_windows_product_type(ProductType); report_windows_product_type(ProductType);
break; break;
case 3: case 3:
gb_printf("Windows Server 2012 R2"); gb_printf("Windows Server 2012 R2");
break; break;
} }
break; break;
}
break;
case 5:
switch (osvi.dwMinorVersion) {
case 0:
gb_printf("Windows 2000");
break;
case 1:
gb_printf("Windows XP");
break;
case 2:
gb_printf("Windows Server 2003");
break;
}
break;
default:
break;
} }
break;
/* case 5:
Grab Windows DisplayVersion (like 20H02) switch (osvi.dwMinorVersion) {
*/ case 0:
LPDWORD ValueType = {}; gb_printf("Windows 2000");
DWORD UBR; break;
char DisplayVersion[256]; case 1:
DWORD ValueSize = 256; gb_printf("Windows XP");
break;
status = RegGetValue( case 2:
HKEY_LOCAL_MACHINE, gb_printf("Windows Server 2003");
TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), break;
TEXT("DisplayVersion"),
RRF_RT_REG_SZ,
ValueType,
DisplayVersion,
&ValueSize
);
if (status == 0x0) {
gb_printf(" (version: %s)", DisplayVersion);
} }
break;
/* default:
Now print build number. break;
*/
gb_printf(", build %u", cast(unsigned)osvi.dwBuildNumber);
ValueSize = sizeof(UBR);
status = RegGetValue(
HKEY_LOCAL_MACHINE,
TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"),
TEXT("UBR"),
RRF_RT_REG_DWORD,
ValueType,
&UBR,
&ValueSize
);
if (status == 0x0) {
gb_printf(".%u", cast(unsigned)UBR);
}
gb_printf("\n");
} }
/*
Grab Windows DisplayVersion (like 20H02)
*/
LPDWORD ValueType = {};
DWORD UBR;
char DisplayVersion[256];
DWORD ValueSize = 256;
status = RegGetValue(
HKEY_LOCAL_MACHINE,
TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"),
TEXT("DisplayVersion"),
RRF_RT_REG_SZ,
ValueType,
DisplayVersion,
&ValueSize
);
if (status == 0x0) {
gb_printf(" (version: %s)", DisplayVersion);
}
/*
Now print build number.
*/
gb_printf(", build %u", cast(unsigned)osvi.dwBuildNumber);
ValueSize = sizeof(UBR);
status = RegGetValue(
HKEY_LOCAL_MACHINE,
TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"),
TEXT("UBR"),
RRF_RT_REG_DWORD,
ValueType,
&UBR,
&ValueSize
);
if (status == 0x0) {
gb_printf(".%u", cast(unsigned)UBR);
}
gb_printf("\n");
}
#elif defined(GB_SYSTEM_LINUX) #elif defined(GB_SYSTEM_LINUX)
/* /*
Try to parse `/etc/os-release` for `PRETTY_NAME="Ubuntu 20.04.3 LTS` Try to parse `/etc/os-release` for `PRETTY_NAME="Ubuntu 20.04.3 LTS`
@@ -542,10 +523,10 @@ void print_bug_report_help() {
b32 found = 1; b32 found = 1;
uint32_t major, minor; uint32_t major, minor;
#define osx_version_buffer 100 #define freebsd_version_buffer 100
char buffer[osx_version_buffer]; char buffer[freebsd_version_buffer];
size_t buffer_size = osx_version_buffer - 1; size_t buffer_size = freebsd_version_buffer - 1;
#undef osx_version_buffer #undef freebsd_version_buffer
int sysctls[] = { CTL_KERN, KERN_OSRELEASE }; int sysctls[] = { CTL_KERN, KERN_OSRELEASE };
if (sysctl(sysctls, 2, buffer, &buffer_size, NULL, 0) == -1) { if (sysctl(sysctls, 2, buffer, &buffer_size, NULL, 0) == -1) {
@@ -664,10 +645,82 @@ void print_bug_report_help() {
} else { } else {
gb_printf("OpenBSD: Unknown\n"); gb_printf("OpenBSD: Unknown\n");
} }
#else #elif defined(GB_SYSTEM_FREEBSD)
gb_printf("Unknown\n"); #define freebsd_version_buffer 129
char buffer[freebsd_version_buffer];
size_t buffer_size = freebsd_version_buffer - 1;
#undef freebsd_version_buffer
int sysctls[] = { CTL_KERN, KERN_VERSION };
if (sysctl(sysctls, 2, buffer, &buffer_size, NULL, 0) == -1) {
gb_printf("FreeBSD: Unknown\n");
} else {
// KERN_VERSION can end in a \n, replace it with a \0
for (int i = 0; i < buffer_size; i += 1) {
if (buffer[i] == '\n') buffer[i] = 0;
}
gb_printf("%s", &buffer[0]);
// Retrieve kernel revision using `sysctl`, e.g. 199506
sysctls[1] = KERN_OSREV;
uint64_t revision;
size_t revision_size = sizeof(revision);
if (sysctl(sysctls, 2, &revision, &revision_size, NULL, 0) == -1) {
gb_printf("\n");
} else {
gb_printf(", revision %ld\n", revision);
}
}
// if (found) {
// gb_printf("FreeBSD ")
// }
// // Retrieve kernel revision using `sysctl`, e.g. 199506
// mib = []i32{sys.CTL_KERN, sys.KERN_OSREV}
// revision: int
// if !sys.sysctl(mib, &revision) {
// return
// }
// os_version.patch = revision
// strings.write_string(&b, ", revision ")
// strings.write_int(&b, revision)
#else
gb_printf("Unknown");
#endif #endif
}
// NOTE(Jeroen): `odin report` prints some system information for easier bug reporting.
void print_bug_report_help() {
gb_printf("Where to find more information and get into contact when you encounter a bug:\n\n");
gb_printf("\tWebsite: https://odin-lang.org\n");
gb_printf("\tGitHub: https://github.com/odin-lang/Odin/issues\n");
/*
Uncomment and update URL once we have a Discord vanity URL. For now people can get here from the site.
gb_printf("\tDiscord: https://discord.com/invite/sVBPHEv\n");
*/
gb_printf("\n\n");
gb_printf("Useful information to add to a bug report:\n\n");
gb_printf("\tOdin: %.*s", LIT(ODIN_VERSION));
#ifdef NIGHTLY
gb_printf("-nightly");
#endif
#ifdef GIT_SHA
gb_printf(":%s", GIT_SHA);
#endif
gb_printf("\n");
/*
Print OS information.
*/
report_os_info();
/* /*
Now print CPU info. Now print CPU info.
@@ -678,4 +731,4 @@ void print_bug_report_help() {
And RAM info. And RAM info.
*/ */
report_ram_info(); report_ram_info();
} }