/* =========================================================================== IceTech GPL Source Code Copyright (C) 2026 Justin Marshall This file is part of the IceTech GPL Source Code (?IceTech Source Code?). IceTech Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. IceTech Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with IceTech Source Code. If not, see . In addition, the IceTech Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the IceTech Source Code. If not, please request a copy in writing from id Software at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com =========================================================================== */ #include "precompiled.h" #pragma hdrstop #include "win_local.h" #include #include #include #include #include #include #include #include #ifndef ID_DEDICATED #include #include #include #pragma comment (lib, "wbemuuid.lib") #endif /* ================ Sys_Milliseconds ================ */ int Sys_Milliseconds(void) { int sys_curtime; static int sys_timeBase; static bool initialized = false; if (!initialized) { sys_timeBase = timeGetTime(); initialized = true; } sys_curtime = timeGetTime() - sys_timeBase; return sys_curtime; } /* ================ Sys_GetSystemRam returns amount of physical memory in MB ================ */ int Sys_GetSystemRam(void) { MEMORYSTATUSEX statex; statex.dwLength = sizeof(statex); GlobalMemoryStatusEx(&statex); int physRam = statex.ullTotalPhys / (1024 * 1024); // HACK: For some reason, ullTotalPhys is sometimes off by a meg or two, so we round up to the nearest 16 megs physRam = (physRam + 8) & ~15; return physRam; } /* ================ Sys_GetDriveFreeSpace returns in megabytes ================ */ int Sys_GetDriveFreeSpace(const char* path) { DWORDLONG lpFreeBytesAvailable; DWORDLONG lpTotalNumberOfBytes; DWORDLONG lpTotalNumberOfFreeBytes; int ret = 26; //FIXME: see why this is failing on some machines if (::GetDiskFreeSpaceEx(path, (PULARGE_INTEGER)&lpFreeBytesAvailable, (PULARGE_INTEGER)&lpTotalNumberOfBytes, (PULARGE_INTEGER)&lpTotalNumberOfFreeBytes)) { ret = (double)(lpFreeBytesAvailable) / (1024.0 * 1024.0); } return ret; } /* ================ Sys_GetVideoRam returns in megabytes ================ */ int Sys_GetVideoRam(void) { #ifdef ID_DEDICATED return 0; #else unsigned int retSize = 64; CComPtr spLoc = NULL; HRESULT hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_SERVER, IID_IWbemLocator, (LPVOID*)&spLoc); if (hr != S_OK || spLoc == NULL) { return retSize; } CComBSTR bstrNamespace(_T("\\\\.\\root\\CIMV2")); CComPtr spServices; // Connect to CIM hr = spLoc->ConnectServer(bstrNamespace, NULL, NULL, 0, NULL, 0, 0, &spServices); if (hr != WBEM_S_NO_ERROR) { return retSize; } // Switch the security level to IMPERSONATE so that provider will grant access to system-level objects. hr = CoSetProxyBlanket(spServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); if (hr != S_OK) { return retSize; } // Get the vid controller CComPtr spEnumInst = NULL; hr = spServices->CreateInstanceEnum(CComBSTR("Win32_VideoController"), WBEM_FLAG_SHALLOW, NULL, &spEnumInst); if (hr != WBEM_S_NO_ERROR || spEnumInst == NULL) { return retSize; } ULONG uNumOfInstances = 0; CComPtr spInstance = NULL; hr = spEnumInst->Next(10000, 1, &spInstance, &uNumOfInstances); if (hr == S_OK && spInstance) { // Get properties from the object CComVariant varSize; hr = spInstance->Get(CComBSTR(_T("AdapterRAM")), 0, &varSize, 0, 0); if (hr == S_OK) { retSize = varSize.intVal / (1024 * 1024); if (retSize == 0) { retSize = 64; } } } return retSize; #endif } /* ================ Sys_GetCurrentMemoryStatus returns OS mem info all values are in kB except the memoryload ================ */ void Sys_GetCurrentMemoryStatus(sysMemoryStats_t& stats) { MEMORYSTATUSEX statex; unsigned __int64 work; memset(&statex, sizeof(statex), 0); statex.dwLength = sizeof(statex); GlobalMemoryStatusEx(&statex); memset(&stats, 0, sizeof(stats)); stats.memoryLoad = statex.dwMemoryLoad; work = statex.ullTotalPhys >> 20; stats.totalPhysical = *(int*)&work; work = statex.ullAvailPhys >> 20; stats.availPhysical = *(int*)&work; work = statex.ullAvailPageFile >> 20; stats.availPageFile = *(int*)&work; work = statex.ullTotalPageFile >> 20; stats.totalPageFile = *(int*)&work; work = statex.ullTotalVirtual >> 20; stats.totalVirtual = *(int*)&work; work = statex.ullAvailVirtual >> 20; stats.availVirtual = *(int*)&work; work = statex.ullAvailExtendedVirtual >> 20; stats.availExtendedVirtual = *(int*)&work; } /* ================ Sys_LockMemory ================ */ bool Sys_LockMemory(void* ptr, int bytes) { return (VirtualLock(ptr, (SIZE_T)bytes) != FALSE); } /* ================ Sys_UnlockMemory ================ */ bool Sys_UnlockMemory(void* ptr, int bytes) { return (VirtualUnlock(ptr, (SIZE_T)bytes) != FALSE); } /* ================ Sys_SetPhysicalWorkMemory ================ */ void Sys_SetPhysicalWorkMemory(int minBytes, int maxBytes) { ::SetProcessWorkingSetSize(GetCurrentProcess(), minBytes, maxBytes); } /* ================ Sys_GetCurrentUser ================ */ char* Sys_GetCurrentUser(void) { static char s_userName[1024]; unsigned long size = sizeof(s_userName); if (!GetUserName(s_userName, &size)) { strcpy(s_userName, "player"); } if (!s_userName[0]) { strcpy(s_userName, "player"); } return s_userName; } /* =============================================================================== Call stack =============================================================================== */ #define PROLOGUE_SIGNATURE 0x00EC8B55 #include const int UNDECORATE_FLAGS = UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS | UNDNAME_NO_FUNCTION_RETURNS | UNDNAME_NO_ALLOCATION_MODEL | UNDNAME_NO_ALLOCATION_LANGUAGE | UNDNAME_NO_MEMBER_TYPE; /* ================== Sym_Init ================== */ void Sym_Init(long addr) { } /* ================== Sym_Shutdown ================== */ void Sym_Shutdown(void) { } /* ================== Sym_GetFuncInfo ================== */ void Sym_GetFuncInfo(long addr, idStr& module, idStr& funcName) { module = ""; sprintf(funcName, "0x%08x", addr); } /* ================== GetFuncAddr ================== */ address_t GetFuncAddr(address_t midPtPtr) { long temp; do { temp = (long)(*(long*)midPtPtr); if ((temp & 0x00FFFFFF) == PROLOGUE_SIGNATURE) { break; } midPtPtr--; } while (true); return midPtPtr; } /* ================== GetCallerAddr ================== */ address_t GetCallerAddr(long _ebp) { long midPtPtr; long res = 0; return res; } /* ================== Sys_GetCallStack use /Oy option ================== */ void Sys_GetCallStack(address_t* callStack, const int callStackSize) { } /* ================== Sys_GetCallStackStr ================== */ const char* Sys_GetCallStackStr(const address_t* callStack, const int callStackSize) { static char string[MAX_STRING_CHARS * 2]; int index, i; idStr module, funcName; index = 0; for (i = callStackSize - 1; i >= 0; i--) { Sym_GetFuncInfo(callStack[i], module, funcName); index += sprintf(string + index, " -> %s", funcName.c_str()); } return string; } /* ================== Sys_GetCallStackCurStr ================== */ const char* Sys_GetCallStackCurStr(int depth) { address_t* callStack; callStack = (address_t*)_alloca(depth * sizeof(address_t)); Sys_GetCallStack(callStack, depth); return Sys_GetCallStackStr(callStack, depth); } /* ================== Sys_GetCallStackCurAddressStr ================== */ const char* Sys_GetCallStackCurAddressStr(int depth) { static char string[MAX_STRING_CHARS * 2]; address_t* callStack; int index, i; callStack = (address_t*)_alloca(depth * sizeof(address_t)); Sys_GetCallStack(callStack, depth); index = 0; for (i = depth - 1; i >= 0; i--) { index += sprintf(string + index, " -> 0x%08x", callStack[i]); } return string; } /* ================== Sys_ShutdownSymbols ================== */ void Sys_ShutdownSymbols(void) { Sym_Shutdown(); }