Sys-Info-Driver-Windows

 view release on metacpan or  search on metacpan

Windows.xs  view on Meta::CPAN

#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) );

Windows.xs  view on Meta::CPAN


        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 )