Sys-Info-Driver-Windows
view release on metacpan or search on metacpan
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <tchar.h>
#include <string.h>
#include "detect.h"
#include "include/cpu.h"
MODULE = Sys::Info::Driver::Windows PACKAGE = Sys::Info::Driver::Windows
int
GetSystemMetrics(index)
int index
CODE:
RETVAL = GetSystemMetrics(index);
OUTPUT:
RETVAL
void
GetSystemInfo()
PREINIT:
OSVERSIONINFOEX osvi;
SYSTEM_INFO si;
SYSTEM_INFO si2;
PGNSI pGNSI;
LPFN_ISWOW64PROCESS fnIsWow64Process;
//PGPI pGPI;
BOOL bOsVersionInfoEx;
BOOL bIsWow;
//DWORD dwType;
TCHAR wProcessorModel [10];
TCHAR wProcessorStepping [10];
TCHAR wProcessorArchitecture2 [64];
unsigned int wProcessBitness;
unsigned int wProcessorBitness;
PPCODE:
/*
See:
- http://msdn.microsoft.com/en-us/library/ms724429(VS.85).aspx
- http://blogs.msdn.com/junfeng/archive/2005/07/01/434574.aspx
*/
ZeroMemory(&si, sizeof(SYSTEM_INFO));
ZeroMemory(&si2, sizeof(SYSTEM_INFO));
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
XSRETURN(1);
// Copy the hardware information to the SYSTEM_INFO structure.
pGNSI = (PGNSI) GetProcAddress(
GetModuleHandle( TEXT("kernel32.dll") ),
"GetNativeSystemInfo"
);
wProcessBitness = 0;
wProcessorBitness = 0;
bIsWow = FALSE;
(NULL != pGNSI) ? pGNSI(&si) : GetSystemInfo(&si);
if ( VER_PLATFORM_WIN32_NT == osvi.dwPlatformId && osvi.dwMajorVersion > 4 ) {
// We have Win2k or later
EXTEND(SP, 26);
switch (si.wProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_ALPHA:
lstrcpy( wProcessorArchitecture2, TEXT("Alpha"));
wsprintf( wProcessorModel , TEXT("%d"), HIBYTE(si.wProcessorRevision) );
wsprintf( wProcessorStepping , TEXT("%d"), LOBYTE(si.wProcessorRevision) );
wProcessBitness = 64;
wProcessorBitness = 64;
break;
case PROCESSOR_ARCHITECTURE_IA64:
lstrcpy( wProcessorArchitecture2, TEXT("IA-64"));
wsprintf( wProcessorModel , TEXT("%d"), HIBYTE(si.wProcessorRevision) );
wsprintf( wProcessorStepping , TEXT("%d"), LOBYTE(si.wProcessorRevision) );
wProcessBitness = 64;
wProcessorBitness = 64;
break;
case PROCESSOR_ARCHITECTURE_ALPHA64:
lstrcpy(wProcessorArchitecture2 , TEXT("Alpha64"));
wsprintf( wProcessorModel , TEXT("%d"), HIBYTE(si.wProcessorRevision) );
wsprintf( wProcessorStepping , TEXT("%d"), LOBYTE(si.wProcessorRevision) );
wProcessBitness = 64;
wProcessorBitness = 64;
break;
case PROCESSOR_ARCHITECTURE_INTEL:
lstrcpy( wProcessorArchitecture2, TEXT("x86") );
wsprintf( wProcessorModel , TEXT("%d"), HIBYTE(si.wProcessorRevision) );
wsprintf( wProcessorStepping , TEXT("%d"), LOBYTE(si.wProcessorRevision) );
PUSHs( sv_2mortal( newSVpv( "wProcessorArchitecture" , 0 ) ) );
PUSHs( sv_2mortal( newSVuv( si.wProcessorArchitecture ) ) );
PUSHs( sv_2mortal( newSVpv( "wProcessorLevel" , 0 ) ) );
PUSHs( sv_2mortal( newSVuv( si.wProcessorLevel ) ) );
PUSHs( sv_2mortal( newSVpv( "dwActiveProcessorMask" , 0 ) ) );
PUSHs( sv_2mortal( newSVuv( si.dwActiveProcessorMask ) ) );
PUSHs( sv_2mortal( newSVpv( "wProcessorRevision" , 0 ) ) );
PUSHs( sv_2mortal( newSVuv( si.wProcessorRevision ) ) );
PUSHs( sv_2mortal( newSVpv( "wProcessorModel" , 0 ) ) );
PUSHs( sv_2mortal( newSVpv( wProcessorModel , 0 ) ) );
PUSHs( sv_2mortal( newSVpv( "wProcessorStepping" , 0 ) ) );
PUSHs( sv_2mortal( newSVpv( wProcessorStepping , 0 ) ) );
PUSHs( sv_2mortal( newSVpv( "wProcessorArchitecture2" , 0 ) ) );
PUSHs( sv_2mortal( newSVpv( wProcessorArchitecture2 , 0 ) ) );
// other
PUSHs( sv_2mortal( newSVpv( "dwOemId" , 0 ) ) );
PUSHs( sv_2mortal( newSVuv( si.dwOemId ) ) );
PUSHs( sv_2mortal( newSVpv( "dwPageSize" , 0 ) ) );
PUSHs( sv_2mortal( newSViv( si.dwPageSize ) ) );
PUSHs( sv_2mortal( newSVpv( "lpMinimumApplicationAddress" , 0 ) ) );
PUSHs( sv_2mortal( newSVuv( si.lpMinimumApplicationAddress ) ) );
PUSHs( sv_2mortal( newSVpv( "lpMaximumApplicationAddress" , 0 ) ) );
PUSHs( sv_2mortal( newSVuv( si.lpMaximumApplicationAddress ) ) );
PUSHs( sv_2mortal( newSVpv( "wProcessBitness" , 0 ) ) );
PUSHs( sv_2mortal( newSViv( wProcessBitness ) ) );
PUSHs( sv_2mortal( newSVpv( "wProcessorBitness" , 0 ) ) );
PUSHs( sv_2mortal( newSViv( wProcessorBitness ) ) );
}
else {
croak( "GetSystemInfo() can not be run on this version of Windows.");
}
void
CPUFeatures()
PREINIT:
int CPUInfo[4] = {-1};
unsigned infoext[4];
CPUDATA cpu;
ULONG FeatureBits;
unsigned i;
unsigned ebx = 0;
unsigned ecx = 0;
unsigned CpuFeatures = 0;
unsigned Flags;
unsigned KFBits;
unsigned FeatureFlags;
PPCODE:
/*
Resources:
- http://msdn.microsoft.com/en-us/library/hskdteyh(VS.80).aspx
- http://stackoverflow.com/questions/794632/programmatically-get-the-cache-line-size
- http://en.wikipedia.org/wiki/CPUID
__cpuid with an InfoType argument of 0 returns the number of
valid Ids in CPUInfo[0] and the CPU identification string in
the other three array elements. The CPU identification string is
not in linear order. The code below arranges the information
in a human readable form.
*/
__cpuid(CPUInfo, 0);
cpu.Ids = CPUInfo[0];
memset(cpu.String, 0, sizeof(cpu.String));
*((int*)cpu.String) = CPUInfo[1];
*((int*)(cpu.String+4)) = CPUInfo[3];
*((int*)(cpu.String+8)) = CPUInfo[2];
// Get the information associated with each valid Id
for ( i = 0; i <= cpu.Ids; ++i ) {
__cpuid(CPUInfo, i);
/*
warn("\nFor InfoType %d\n", i);
warn("CPUInfo[0] = 0x%x\n", CPUInfo[0]);
warn("CPUInfo[1] = 0x%x\n", CPUInfo[1]);
warn("CPUInfo[2] = 0x%x\n", CPUInfo[2]);
warn("CPUInfo[3] = 0x%x\n", CPUInfo[3]);
*/
// Interpret CPU feature information.
if ( i == 1 ) {
ebx = CPUInfo[1];
ecx = CPUInfo[2];
CpuFeatures = CPUInfo[3];
cpu.SteppingID = CPUInfo[0] & 0xf;
cpu.Model = (CPUInfo[0] >> 4) & 0xf;
cpu.Family = (CPUInfo[0] >> 8) & 0xf;
cpu.ProcessorType = (CPUInfo[0] >> 12) & 0x3;
cpu.Extendedmodel = (CPUInfo[0] >> 16) & 0xf;
cpu.Extendedfamily = (CPUInfo[0] >> 20) & 0xff;
cpu.BrandIndex = CPUInfo[1] & 0xff;
cpu.CLFLUSHcachelinesize = ((CPUInfo[1] >> 8) & 0xff) * 8;
cpu.APICPhysicalID = (CPUInfo[1] >> 24) & 0xff;
cpu.SSE3NewInstructions = (CPUInfo[2] & 0x1 ) || 0;
cpu.MONITOR_MWAIT = (CPUInfo[2] & 0x8 ) || 0;
cpu.CPLQualifiedDebugStore = (CPUInfo[2] & 0x10 ) || 0;
cpu.ThermalMonitor2 = (CPUInfo[2] & 0x100) || 0;
cpu.FeatureInfo = CPUInfo[3];
}
}
// Calling __cpuid with 0x80000000 as the InfoType argument
// gets the number of valid extended IDs.
__cpuid( CPUInfo, 0x80000000 );
cpu.ExIds = CPUInfo[0];
memset(cpu.BrandString, 0, sizeof(cpu.BrandString));
if( cpu.ExIds >= 0x80000001 ) {
__cpuid(infoext, 0x80000001);
if( CF_MMX & CpuFeatures ) Flags |= CF_MMX;
( run in 1.045 second using v1.01-cache-2.11-cpan-5511b514fd6 )