You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
5.5 KiB
208 lines
5.5 KiB
14 years ago
|
/*==LICENSE==*
|
||
|
|
||
|
CyanWorlds.com Engine - MMOG client, server and tools
|
||
|
Copyright (C) 2011 Cyan Worlds, Inc.
|
||
|
|
||
|
This program 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.
|
||
|
|
||
|
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||
|
or by snail mail at:
|
||
|
Cyan Worlds, Inc.
|
||
|
14617 N Newport Hwy
|
||
|
Mead, WA 99021
|
||
|
|
||
|
*==LICENSE==*/
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/Win32/pnUtW32Misc.cpp
|
||
|
*
|
||
|
***/
|
||
|
|
||
|
#include "../../Pch.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* Private
|
||
|
*
|
||
|
***/
|
||
|
static MEMORYSTATUSEX s_memstatus;
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* Exports
|
||
|
*
|
||
|
***/
|
||
|
|
||
|
//============================================================================
|
||
|
const wchar * AppGetCommandLine () {
|
||
|
return GetCommandLineW();
|
||
|
}
|
||
|
|
||
|
//============================================================================
|
||
|
void MachineGetName (wchar *computerName, unsigned int length) {
|
||
|
DWORD len = length;
|
||
|
GetComputerNameW(computerName, &len);
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* System status
|
||
|
*
|
||
|
***/
|
||
|
|
||
|
//============================================================================
|
||
|
void MemoryGetStatus (MemoryStatus * status) {
|
||
|
MEMORYSTATUSEX mem;
|
||
|
mem.dwLength = sizeof(mem);
|
||
|
GlobalMemoryStatusEx(&mem);
|
||
|
|
||
|
const qword BYTES_PER_MB = 1024 * 1024;
|
||
|
status->totalPhysMB = unsigned(mem.ullTotalPhys / BYTES_PER_MB);
|
||
|
status->availPhysMB = unsigned(mem.ullAvailPhys / BYTES_PER_MB);
|
||
|
status->totalPageFileMB = unsigned(mem.ullTotalPageFile / BYTES_PER_MB);
|
||
|
status->availPageFileMB = unsigned(mem.ullAvailPageFile / BYTES_PER_MB);
|
||
|
status->totalVirtualMB = unsigned(mem.ullTotalVirtual / BYTES_PER_MB);
|
||
|
status->availVirtualMB = unsigned(mem.ullAvailVirtual / BYTES_PER_MB);
|
||
|
status->memoryLoad = mem.dwMemoryLoad;
|
||
|
}
|
||
|
|
||
|
//============================================================================
|
||
|
void DiskGetStatus (ARRAY(DiskStatus) * disks) {
|
||
|
for (;;) {
|
||
|
DWORD length = GetLogicalDriveStrings(0, NULL);
|
||
|
if (!length || length > 2048)
|
||
|
break;
|
||
|
|
||
|
wchar * buffer = ALLOCA(wchar, length + 1);
|
||
|
if (!GetLogicalDriveStringsW(length, buffer))
|
||
|
break;
|
||
|
|
||
|
for (; *buffer; buffer += StrLen(buffer) + 1) {
|
||
|
UINT driveType = GetDriveTypeW(buffer);
|
||
|
if (driveType != DRIVE_FIXED)
|
||
|
continue;
|
||
|
|
||
|
ULARGE_INTEGER freeBytes;
|
||
|
ULARGE_INTEGER totalBytes;
|
||
|
if (!GetDiskFreeSpaceExW(buffer, &freeBytes, &totalBytes, NULL))
|
||
|
continue;
|
||
|
|
||
|
DiskStatus status;
|
||
|
StrCopy(status.name, buffer, arrsize(status.name));
|
||
|
|
||
|
const qword BYTES_PER_MB = 1024 * 1024;
|
||
|
status.totalSpaceMB = unsigned(totalBytes.QuadPart / BYTES_PER_MB);
|
||
|
status.freeSpaceMB = unsigned(freeBytes.QuadPart / BYTES_PER_MB);
|
||
|
|
||
|
disks->Add(status);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//============================================================================
|
||
|
// Loosely taken from MS's cpuid code sample
|
||
|
void CpuGetInfo (
|
||
|
word * cpuCaps,
|
||
|
dword * cpuVendor,
|
||
|
word * cpuSignature
|
||
|
) {
|
||
|
dword signature = 0;
|
||
|
dword extended = 0;
|
||
|
dword flags[2] = { 0, 0 };
|
||
|
cpuVendor[0] = 0;
|
||
|
|
||
|
_asm {
|
||
|
// Detect if cpuid instruction is supported by attempting
|
||
|
// to change the ID bit of EFLAGS
|
||
|
pushfd
|
||
|
pop eax // get EFLAGS
|
||
|
mov ecx, eax // store copy of original EFLAGS
|
||
|
xor eax, 0x200000 // flip ID bit
|
||
|
push eax
|
||
|
popfd // replace EFLAGS
|
||
|
pushfd // get EFLAGS
|
||
|
pop eax
|
||
|
xor eax, ecx
|
||
|
je DONE
|
||
|
|
||
|
// Get processor id (GenuineIntel, AuthenticAMD, etc)
|
||
|
xor eax, eax
|
||
|
cpuid
|
||
|
mov edi, cpuVendor
|
||
|
mov [edi + 0], ebx
|
||
|
mov [edi + 4], edx
|
||
|
mov [edi + 8], ecx
|
||
|
|
||
|
// Check if capability flags are supported
|
||
|
cmp eax, 1
|
||
|
jl DONE
|
||
|
|
||
|
// Get processor capability flags and signature
|
||
|
mov eax, 1
|
||
|
cpuid
|
||
|
mov signature, eax
|
||
|
mov [flags + 0], edx
|
||
|
mov [flags + 4], ecx
|
||
|
|
||
|
// Check for extended capabilities
|
||
|
mov eax, 0x80000000
|
||
|
cpuid
|
||
|
cmp eax, 0x80000001
|
||
|
jl DONE
|
||
|
|
||
|
// Get extended capabilities
|
||
|
mov eax, 0x80000001
|
||
|
cpuid
|
||
|
mov extended, edx
|
||
|
|
||
|
DONE:
|
||
|
}
|
||
|
|
||
|
// Decode capability flags
|
||
|
const static struct CpuCap {
|
||
|
word cpuFlag;
|
||
|
byte field;
|
||
|
byte bit;
|
||
|
} s_caps[] = {
|
||
|
// feature field bit
|
||
|
// ------- ----- ---
|
||
|
{ kCpuCapCmov, 0, 15 },
|
||
|
{ kCpuCapEst, 1, 7 },
|
||
|
{ kCpuCapHtt, 0, 28 },
|
||
|
{ kCpuCapMmx, 0, 23 },
|
||
|
{ kCpuCapPsn, 0, 18 },
|
||
|
{ kCpuCapSse, 0, 25 },
|
||
|
{ kCpuCapSse2, 0, 26 },
|
||
|
{ kCpuCapSse3, 1, 0 },
|
||
|
{ kCpuCapTsc, 0, 4 },
|
||
|
};
|
||
|
for (unsigned i = 0; i < arrsize(s_caps); ++i) {
|
||
|
const CpuCap & cap = s_caps[i];
|
||
|
if (flags[cap.field] & (1 << cap.bit))
|
||
|
*cpuCaps |= cap.cpuFlag;
|
||
|
}
|
||
|
|
||
|
// Copy signature
|
||
|
*cpuSignature = word(signature & 0xfff);
|
||
|
|
||
|
// If this is an AMD CPU, check for 3DNow support
|
||
|
const char * vendorAmd = "AuthenticAMD";
|
||
|
if (!MemCmp(vendorAmd, cpuVendor, 12)) {
|
||
|
if (extended & (1 << 31))
|
||
|
*cpuCaps |= kCpuCap3dNow;
|
||
|
}
|
||
|
}
|