Announcement

Collapse
No announcement yet.

determine Windows version and 32/64 bit

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • determine Windows version and 32/64 bit

    I tried to detect from PB, if Windows is a 32 or 64 bit (x86,x64) version. Found some threads here in this forum, they tried to detect, if the process is running in WOW or not.
    Found an example on MSDN and i think the definition of the SYSTEM_INFO type/structure is different in PB/C.
    => my PBCC example does not work on x64 architecture

    Any hint appreciated.


    Here is the C code from WinBase.h (VisualStudio 2008)
    Code:
    typedef struct _SYSTEM_INFO {
        union {
            DWORD dwOemId;          // Obsolete field...do not use
            struct {
                WORD wProcessorArchitecture;
                WORD wReserved;
            };
        };
        DWORD dwPageSize;
        LPVOID lpMinimumApplicationAddress;
        LPVOID lpMaximumApplicationAddress;
        DWORD_PTR dwActiveProcessorMask;
        DWORD dwNumberOfProcessors;
        DWORD dwProcessorType;
        DWORD dwAllocationGranularity;
        WORD wProcessorLevel;
        WORD wProcessorRevision;
    } SYSTEM_INFO, *LPSYSTEM_INFO;

    And here is my PBCC 5 code, which does not work:
    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "Win32API.inc"
    
    TYPE SI_Processor
        wProcessorArchitecture      AS WORD
        wReserved                   AS WORD
    END TYPE
    
    TYPE SYSTEM_INFO2
      dwOemID                       AS SI_Processor
      dwPageSize                    AS DWORD
      lpMinimumApplicationAddress   AS DWORD
      lpMaximumApplicationAddress   AS DWORD
      dwActiveProcessorMask         AS DWORD
      dwNumberOfProcessors          AS DWORD
      dwProcessorType               AS DWORD
      dwAllocationGranularity       AS DWORD
      wProcessorLevel               AS WORD
      wProcessorRevision            AS WORD
    END TYPE
    
    'processor architecures stored in .wProcessorArchitecture
    %PROCESSOR_ARCHITECTURE_INTEL               = 0
    %PROCESSOR_ARCHITECTURE_MIPS                = 1
    %PROCESSOR_ARCHITECTURE_ALPHA               = 2
    %PROCESSOR_ARCHITECTURE_PPC                 = 3
    %PROCESSOR_ARCHITECTURE_SHX                 = 4
    %PROCESSOR_ARCHITECTURE_ARM                 = 5
    %PROCESSOR_ARCHITECTURE_IA64                = 6
    %PROCESSOR_ARCHITECTURE_ALPHA64             = 7
    %PROCESSOR_ARCHITECTURE_MSIL                = 8
    %PROCESSOR_ARCHITECTURE_AMD64               = 9
    %PROCESSOR_ARCHITECTURE_IA32_ON_WIN64       = 10
    '%PROCESSOR_ARCHITECTURE_UNKNOWN             = &HFFFF
    
    
    
    FUNCTION GetOSVersion() AS STRING
    
        LOCAL osvi              AS OSVERSIONINFOEX
        LOCAL bOsVersionInfoEx  AS LONG
        LOCAL OSver             AS STRING
    
        osvi.dwOsVersionInfoSize    = SIZEOF( osvi )
        bOsVersionInfoEx            = GetVersionEx(osvi)
    
        IF bOsVersionInfoEx = %ERROR_OLD_WIN_VERSION THEN
            OSver = "-1"
        ELSE
            'LOCAL lPlatform AS LONG
            'lPlatform = osvi.dwPlatformId
            OSver = FORMAT$( osvi.dwMajorVersion + ( osvi.dwMinorVersion \ 10 ), "0.0" )
        END IF
        
        FUNCTION = OSver
    
    END FUNCTION
    
    
    
    
    FUNCTION IsWindowsx64() AS LONG
    
        LOCAL si        AS SYSTEM_INFO2
        LOCAL arch      AS LONG
    
        'get system information
        GetSystemInfo BYVAL VARPTR(si)
        arch = si.dwOemID.wProcessorArchitecture
        'STDOUT "CPUs:"+STR$(si.dwNumberOfProcessors) 'this is just for testing, if structure is still OK
    
        IF arch = %PROCESSOR_ARCHITECTURE_AMD64 OR _
           arch = %PROCESSOR_ARCHITECTURE_IA64 THEN
            FUNCTION = %True
        ELSEIF arch = %PROCESSOR_ARCHITECTURE_INTEL THEN
            FUNCTION = %False
        ELSE
            FUNCTION = %False
        END IF
        
    END FUNCTION
    
    
    FUNCTION PBMAIN () AS LONG
    
        LOCAL WinVer    AS STRING
        LOCAL Is64      AS LONG
    
        WinVer = GetOSVersion()
        Is64 = IsWindowsx64()
        IF Is64 THEN
            STDOUT "Windows x64, Version: "+WinVer
        ELSE
            STDOUT "Windows x86, Version: "+WinVer
        END IF
    
        WAITKEY$
    
    END FUNCTION
    Last edited by Michael Zimmer; 27 May 2009, 04:03 AM. Reason: comment
    I'am still confused...but on a higher level.

  • #2
    Does this give the correct results:
    Code:
    ' ========================================================================================
    ' WMI example - Retrieving CPU information
    ' Use the PBWIN compiler
    ' ========================================================================================
    
    #Compile Exe
    #Dim All
    #Include "win32api.inc"
    #Include "TB_WMILIB.INC"    ' // WMI helper functions
                                ' [url]http://www.powerbasic.com/support/pbforums/showpost.php?p=171374&postcount=3 [/url]
    
    ' ========================================================================================
    ' Main
    ' ========================================================================================
    Function PBMain
    
       Local hr As Long                   ' // HRESULT
       Local oServices As Dispatch        ' // Services object
       Local vServices As Variant         ' // Services object reference
       Local oItems As Dispatch           ' // Generic collection object
       Local vItems As Variant            ' // Generic collection object reference
       Local oItem As Dispatch            ' // Generic item object
       Local vItem As Variant             ' // Generic item object reference
       Local penum As Dword               ' // Collection's enumerator reference
       Local vCount As Variant            ' // Number of items in the collection
       Local vVar As Variant              ' // General purpose variant
       Local vRes As Variant              ' // General purpose variant
       Local i As Long                    ' // Loop counter
       Local x As Long                    ' // Loop counter
       Local Result As Long
       Local Tmp As String
       Local Disp As String
       Dim vArray(0) As Variant           ' // General purpose array of variants
    
    
       ' // Connect to WMI using a moniker
       hr = WmiGetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2", vServices)
       If hr <> %S_OK Then GoTo Terminate
       Set oServices = vServices
       vServices = Empty
       If IsFalse IsObject(oServices) Then GoTo Terminate
    
       ' // Execute a query to get a reference to the collection of running processes
       vVar = "SELECT * FROM Win32_Processor"
       Object Call oServices.ExecQuery(vVar) To vItems
       If ObjResult Then GoTo Terminate
       Set oItems = vItems
       vItems = Empty
       If IsFalse IsObject(oItems) Then GoTo Terminate
    
       ' // Retrieve the number of items in the collection
       Object Get oItems.Count To vCount
    
       ' // Retrieve a reference to the collection's enumerator
       hr = Wmi_NewEnum(ObjPtr(oItems), penum)
       If hr <> %S_OK Or penum = %NULL Then GoTo Terminate
    
       ' // Iterate throught the collection of objects.
       For i = 1 To Variant#(vCount)
          ' // Retrieve a reference to the next object in the collection
          hr = WmiEnum_NextItem(penum, vItem)
          If hr <> %S_OK Then Exit For
          Set oItem = vItem
          If IsFalse IsObject(oItem) Then Exit For
          '------------------------------------------------------------------------
          Object Get oItem.AddressWidth To vRes
          Disp = $Cr & "Address width: "  & $Tab & Format$(Variant#(vRes)) &  " bits"
          '------------------------------------------------------------------------
          Object Get oItem.Architecture To vRes
          Result = Variant#(vRes)
          Select Case Result
            Case 0 : Disp = Disp & $Cr & "Architecture: "  & $Tab & "x86"
            Case 1 : Disp = Disp & $Cr & "Architecture: "  & $Tab & "MIPS"
            Case 2 : Disp = Disp & $Cr & "Architecture: "  & $Tab & "Alpha"
            Case 3 : Disp = Disp & $Cr & "Architecture: "  & $Tab & "PowerPC"
            Case 6 : Disp = Disp & $Cr & "Architecture: "  & $Tab & "Intel Itanium Processor Family (IPF)"
            Case 9 : Disp = Disp & $Cr & "Architecture: "  & $Tab & "x64"
          End Select
          '------------------------------------------------------------------------
          Object Get oItem.Caption To vRes
          Disp = Disp & $Cr & "Caption string: " & $Tab &  Variant$(vRes)
          '------------------------------------------------------------------------
          Object Get oItem.CpuStatus To vRes
          Result = Variant#(vRes)
          Select Case Result
            Case 0 : Disp = Disp & $Cr & "Cpu status: "  & $Tab & "Unknown"
            Case 1 : Disp = Disp & $Cr & "Cpu status: "  & $Tab & "CPU enabled"
            Case 2 : Disp = Disp & $Cr & "Cpu status: "  & $Tab & "CPU Disabled by User via BIOS Setup"
            Case 3 : Disp = Disp & $Cr & "Cpu status: "  & $Tab & "CPU Disabled By BIOS (POST Error)"
            Case 4 : Disp = Disp & $Cr & "Cpu status: "  & $Tab & "CPU is Idle"
            Case 7 : Disp = Disp & $Cr & "Cpu status: "  & $Tab & "Other"
          End Select
          '------------------------------------------------------------------------
          Object Get oItem.CurrentClockSpeed To vRes
          Disp = Disp & $Cr & "Clock speed: "  & $Tab & Format$(Variant#(vRes)) &  " Mhz"
          '------------------------------------------------------------------------
          Object Get oItem.MaxClockSpeed To vRes
          Disp = Disp & $Cr & "Max clock speed: "  & $Tab & Format$(Variant#(vRes)) &  " MHz"
          '------------------------------------------------------------------------
          Object Get oItem.CurrentVoltage To vRes
          Disp = Disp & $Cr & "Core voltage: "  & $Tab & Format$(Variant#(vRes)/ 10, "0.00") &  " volts"
          '------------------------------------------------------------------------
          Object Get oItem.DataWidth To vRes
          Disp = Disp & $Cr & "Data width: "  & $Tab & Format$(Variant#(vRes)) &  " bits"
          '------------------------------------------------------------------------
          Object Get oItem.L2CacheSize To vRes
          Disp = Disp & $Cr & "Cache size: "  & $Tab & Format$(Variant#(vRes)) &  " Kb"
          '------------------------------------------------------------------------
          Object Get oItem.Manufacturer To vRes
          Disp = Disp & $Cr & "Manufacturer: "  & $Tab & Variant$(vRes)
          '------------------------------------------------------------------------
          Object Get oItem.Name To vRes
          Disp = Disp & $Cr & "CPU Name: "  & $Tab & Variant$(vRes)
          '------------------------------------------------------------------------
          Object Get oItem.DeviceID To vRes
          Tmp = "CPU Info for device:   "  & Variant$(vRes)
          '------------------------------------------------------------------------
          Object Get oItem.SocketDesignation To vRes
          Disp = Disp & $Cr & "CPU Socket: "  & $Tab & Variant$(vRes)
          '------------------------------------------------------------------------
          Object Get oItem.NumberOfCores To vRes
          Disp = Disp & $Cr & "Number of cores: "  & $Tab & Format$(Variant#(vRes)) & "   (Vista only)"
          '------------------------------------------------------------------------
          Object Get oItem.NumberOfLogicalProcessors To vRes
          Disp = Disp & $Cr & "Logical CPU count: "  & $Tab & Format$(Variant#(vRes)) & "   (Vista only)"
          '------------------------------------------------------------------------
          Set oItem = Nothing
          MsgBox Disp,, Tmp
       Next
    
       WmiRelease penum
       If IsObject(oItems) Then Set oItems = Nothing
    Terminate:
       If IsObject(oServices) Then Set oServices = Nothing
    End Function
    ' ========================================================================================
    Last edited by Peter Lameijn; 27 May 2009, 06:54 AM.
    Regards,
    Peter

    "Simplicity is a prerequisite for reliability"

    Comment


    • #3
      Sorry, that was CPU info only. This one tests OS:
      Code:
      ' ========================================================================================
      ' WMI example - Retrieving Operating System information.
      ' ========================================================================================
      
      #Compile Exe
      #Dim All
      #Include "TB_WMILIB.INC"    ' // WMI helper functions
                                  '[url]http://www.powerbasic.com/support/pbforums/showpost.php?p=171374&postcount=3 [/url]
      
      Function PBMain
         Local hr As Long                   ' // HRESULT
         Local oServices As Dispatch        ' // Services object
         Local vServices As Variant         ' // Services object reference
         Local oItems As Dispatch           ' // Generic collection object
         Local vItems As Variant            ' // Generic collection object reference
         Local oItem As Dispatch            ' // Generic item object
         Local vItem As Variant             ' // Generic item object reference
         Local penum As Dword               ' // Collection's enumerator reference
         Local vCount As Variant            ' // Number of items in the collection
         Local vVar As Variant              ' // General purpose variant
         Local vRes As Variant              ' // General purpose variant
         Local i As Long                    ' // Loop counter
         Local x As Long                    ' // Loop counter
         Local Result As Long
         Local Tmp As String
         Dim vArray(0) As Variant           ' // General purpose array of variants
      
      
         hr = WmiGetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2", vServices)
         If hr <> %S_OK Then GoTo Terminate
         Set oServices = vServices
         vServices = Empty
         If IsFalse IsObject(oServices) Then GoTo Terminate
      
         vVar = "SELECT * FROM Win32_OperatingSystem"
         Object Call oServices.ExecQuery(vVar) To vItems
         If ObjResult Then GoTo Terminate
         Set oItems = vItems
         vItems = Empty
         If IsFalse IsObject(oItems) Then GoTo Terminate
      
         Object Get oItems.Count To vCount
      
         hr = Wmi_NewEnum(ObjPtr(oItems), penum)
         If hr <> %S_OK Or penum = %NULL Then GoTo Terminate
      
         For i = 1 To Variant#(vCount)
            hr = WmiEnum_NextItem(penum, vItem)
            If hr <> %S_OK Then Exit For
            Set oItem = vItem
            If IsFalse IsObject(oItem) Then Exit For
            '------------------------------------------------------------------------
            Object Get oItem.OSArchitecture To vRes
            Tmp = Variant$(vRes)
            MsgBox Tmp,, "OS Architecture: (Vista and above only)"
            '------------------------------------------------------------------------
            Set oItem = Nothing
         Next
      
         WmiRelease penum
         If IsObject(oItems) Then Set oItems = Nothing
      
      Terminate:
         If IsObject(oServices) Then Set oServices = Nothing
      End Function
      ' ========================================================================================
      Last edited by Peter Lameijn; 27 May 2009, 07:53 AM.
      Regards,
      Peter

      "Simplicity is a prerequisite for reliability"

      Comment


      • #4
        First, thanks Peter.

        I assume the result should be in there:

        OBJECT GET oItem.OSArchitecture TO vRes

        and then copied to the Tmp variable.
        If so, sorry nothing in there. I'am testing on Windows Vista Enterprise Edition x64 on an Intel Core 2 Duo T7600 CPU.

        Looks like:
        FOR x = LBOUND(vArray) to UBOUND(vArray)
        arraybounds are both zero
        I'am still confused...but on a higher level.

        Comment


        • #5
          Sorry, was an (cut&paste) error in the last example. Maybe it now works.
          Cannot test it here, have W2K...
          Regards,
          Peter

          "Simplicity is a prerequisite for reliability"

          Comment


          • #6
            Found a solution with API function: instead using GetSystemInfo() it's better to try to get information on GetNativeSystemInformation(). This function is only available since Vista/W2K3, so if you don't get a pointer to this kernel function, calling GetSystemInfo() is OK.
            The TYPE had a little error too.

            This one is working with Vista:

            Code:
            '----------------------------------------------------------
            ' M.Zimmer (20090527)
            ' based on MSDN and serveral PB-Forum Threads
            '----------------------------------------------------------
            #COMPILE EXE
            #DIM ALL
            #INCLUDE "Win32API.inc"
            
            
            
            'processor architecures stored in .wProcessorArchitecture
            %PROCESSOR_ARCHITECTURE_INTEL               = 0
            %PROCESSOR_ARCHITECTURE_MIPS                = 1
            %PROCESSOR_ARCHITECTURE_ALPHA               = 2
            %PROCESSOR_ARCHITECTURE_PPC                 = 3
            %PROCESSOR_ARCHITECTURE_SHX                 = 4
            %PROCESSOR_ARCHITECTURE_ARM                 = 5
            %PROCESSOR_ARCHITECTURE_IA64                = 6
            %PROCESSOR_ARCHITECTURE_ALPHA64             = 7
            %PROCESSOR_ARCHITECTURE_MSIL                = 8
            %PROCESSOR_ARCHITECTURE_AMD64               = 9
            %PROCESSOR_ARCHITECTURE_IA32_ON_WIN64       = 10
            '%PROCESSOR_ARCHITECTURE_UNKNOWN             = &HFFFF
            
            
            TYPE NATIVE_SYSTEM_INFO
              wProcessorArchitecture AS WORD
              wReserved AS WORD
              dwPageSize AS DWORD
              lpMinimumApplicationAddress AS DWORD
              lpMaximumApplicationAddress AS DWORD
              dwActiveProcessorMask AS DWORD
              dwNumberOfProcessors AS DWORD
              dwProcessorType AS DWORD
              dwAllocationGranularity AS DWORD
              wProcessorLevel AS WORD
              wProcessorRevision AS WORD
            END TYPE
            
            DECLARE FUNCTION GetNativeSystemInfo(SystemInfo AS NATIVE_SYSTEM_INFO) AS LONG
            
            
            
            FUNCTION GetOSVersion() AS STRING
            
                LOCAL osvi              AS OSVERSIONINFOEX
                LOCAL bOsVersionInfoEx  AS LONG
                LOCAL OSver             AS STRING
            
                osvi.dwOsVersionInfoSize    = SIZEOF( osvi )
                bOsVersionInfoEx            = GetVersionEx(osvi)
            
                IF bOsVersionInfoEx = %ERROR_OLD_WIN_VERSION THEN
                    OSver = "-1"
                ELSE
                    'LOCAL lPlatform AS LONG
                    'lPlatform = osvi.dwPlatformId
                    OSver = FORMAT$( osvi.dwMajorVersion + ( osvi.dwMinorVersion \ 10 ), "0.0" )
                END IF
            
                FUNCTION = OSver
            
            END FUNCTION
            
            
            
            
            FUNCTION IsWindowsx64() AS LONG
            
                LOCAL si                    AS NATIVE_SYSTEM_INFO
                LOCAL arch,CPUnum           AS LONG
                LOCAL SystemInfo            AS NATIVE_SYSTEM_INFO
                LOCAL pGetNativeSystemInfo  AS LONG
            
                pGetNativeSystemInfo = GetProcAddress(GetModuleHandle("kernel32.dll"), "GetNativeSystemInfo")
                IF (pGetNativeSystemInfo) THEN
                    CALL DWORD pGetNativeSystemInfo USING GetNativeSystemInfo(SystemInfo)
                    arch = SystemInfo.wProcessorArchitecture
                    CPUnum=SystemInfo.dwNumberOfProcessors
                    'stdout "CPU:"+str$(CPUnum)+" Architektur:"+hex$(arch)
                    IF (arch = %PROCESSOR_ARCHITECTURE_AMD64) THEN
                        FUNCTION = %True
                    ELSE
                        FUNCTION = %False
                    END IF
                ELSE
                    'get system information
                    GetSystemInfo BYVAL VARPTR(si)
                    arch = si.wProcessorArchitecture
                    'STDOUT "CPUs:"+STR$(si.dwNumberOfProcessors) 'this is just for testing, if structure is still OK
                    IF arch = %PROCESSOR_ARCHITECTURE_AMD64 OR _
                       arch = %PROCESSOR_ARCHITECTURE_IA64 THEN
                        FUNCTION = %True
                    ELSEIF arch = %PROCESSOR_ARCHITECTURE_INTEL THEN
                        FUNCTION = %False
                    ELSE
                        FUNCTION = %False
                    END IF
                END IF
            
            
            
            END FUNCTION
            
            
            FUNCTION PBMAIN () AS LONG
            
                LOCAL WinVer    AS STRING
                LOCAL Is64      AS LONG
            
                WinVer = GetOSVersion()
                Is64 = IsWindowsx64()
                IF Is64 THEN
                    STDOUT "Windows x64, Version: "+WinVer
                ELSE
                    STDOUT "Windows x86, Version: "+WinVer
                END IF
            
                WAITKEY$
            
            END FUNCTION
            I'am still confused...but on a higher level.

            Comment


            • #7
              Originally posted by Peter Lameijn View Post
              Cannot test it here, have W2K...
              Tested with Vista x64, works properly now.
              Thanks.
              I'am still confused...but on a higher level.

              Comment

              Working...
              X