Re: Detecting is hyperthreading is enabled with WMI?

From: David Holcomb (dholcomb_at_msn.com)
Date: 08/09/04

  • Next message: Tim Gorgs: "WMI problems after installation of SP2 on Windows XP"
    Date: Mon, 9 Aug 2004 10:41:39 -0700
    
    

    [Sorry for re-post, the last time I replied Outlook Express was configured to ]
    [truncate or wrap my lines at 76 characters.]
    [Plus, posting in HTML format wreaks havoc on your ability to copy/paste the]
    [text directly into a text file. So I am re-posting as plain text.]
    [Hope this works...]

    It is too bad that WMI does not give this info. Since I was also having
    trouble with the Win32_Processor.Family returning what seemed to be
    incorrect information, I looked into the possiblity of getting my own
    results from the CPUID instruction from VBScript. It seems that if you
    execute CPUID function 1 you can look at EBX bits 16-23 (or more
    appropriately bits 23-16) if the HTT bit is set (bit 28) and the CPUID
    function 0 returned GenuineIntel in the EBX/EDX/ECX registers.

    I went to the Intel and AMD sites for how to execute the CPUID instruction.
    Then I wrapped it in a little C program to display the CPUID functions and
    all the register results like this:

    C:\cpuid>cpuidx86.exe
    StandardFunction:00000000,EAX:00000001,EBX:68747541,ECX:444D4163,EDX:69746E65
    StandardFunction:00000001,EAX:00000662,EBX:00000000,ECX:00000000,EDX:0383FBFF
    ExtendedFunction:80000000,EAX:80000008,EBX:68747541,ECX:444D4163,EDX:69746E65
    ExtendedFunction:80000001,EAX:00000762,EBX:00000000,ECX:00000000,EDX:C1C3FBFF
    ExtendedFunction:80000002,EAX:20444D41,EBX:6C687441,ECX:54286E6F,EDX:5820294D
    ExtendedFunction:80000003,EAX:39312050,EBX:002B3030,ECX:00000000,EDX:00000000
    ExtendedFunction:80000004,EAX:00000000,EBX:00000000,ECX:00000000,EDX:00000000
    ExtendedFunction:80000005,EAX:0408FF08,EBX:FF20FF10,ECX:40020140,EDX:40020140
    ExtendedFunction:80000006,EAX:00000000,EBX:41004100,ECX:01008140,EDX:00000000
    ExtendedFunction:80000007,EAX:00000000,EBX:00000000,ECX:00000000,EDX:00000001
    ExtendedFunction:80000008,EAX:00002022,EBX:00000000,ECX:00000000,EDX:00000000

    The program basically executes the first basic/standard CPUID function,
    checks EAX and enumerates all available standard functions. Then it
    executes the first extended CPUID function, checks EAX and
    enumerates/executes all extended functions. This program does not attempt
    to decode all the results, the idea was that some script could parse the
    output and do its own decoding.

    I took my simple binary and encoded it into a VBScript which can decode and
    execute cpuidx86.exe, storing the output into several arrays. It is not
    very pretty, perhaps I will improve on it. But I thought this might be an
    interesting way to solve the problem of detecting if hyperthreading is
    enabled, identify the processor with the family/model/stepping and cache
    information, and possibly also leverage other useful information returned
    from various CPUID functions. To decode everything, much much more would
    have to be done to the script. At the moment I am only interested in
    identifying if hyperthreading is enabled (and the number of physical CPUs),
    and identifying the processor correctly.

    Some similar CPUID programs will also calculate the processor speed. I
    didn't implement that. It is another thing I might improve on later.

    Unlike WMI, this script cannot enumerate this data on a remote machine using
    security credentials. It has to run on the local machine (it uses WMI and
    standard WSH objects). However, if the script already exists on the remote
    computer, you might be able to do a Win32_Process.Create() to invoke the
    script (or binary) on the remote computer. But then you still might have to
    find a way to get the CPUID data back to your local computer if that is
    where you want to process the results. I haven't solved all that stuff yet,
    I'm taking this one step at a time. Eventually I would like to be able to
    query for this data on a remote computer. I suppose there is a possibility
    of creating and registering my own WMI provider that collects this data.
    That would open up the possibility to query this data remotely as I would
    like, but you would have to register the provider on all clients first.
    That doesn't sound like a good solution to me, I would rather simply ensure
    a program or script exists on a remote computer and invoke it remotely,
    finding some other way to get the data back from the remote computer.

    If anyone knows of a way to execute a process on a remote computer through
    WMI and get its stdout (sstandard output, like from a batch file or this
    cpuidx86.exe), please give me some suggestions.

    I really wish WMI had the ability to return this same basic data from the
    processor. I mean, I wish through the Win32_Processor class you could
    simply query for the results from each CPUID function. Then, even if
    Win32_Processor did not provide all the CPU properties you cared about, you
    could still interpret the data for yourself. Currently WMI does provide
    Win32_Processor.ProcessorId, but it only contains the EAX and EDX results
    from CPUID standard function 1.

    Here is my first attempt to solve this problem. It is not complete as it
    probably does not work on Cyrix chips, and the CPUID part won't work on
    AMD64 or IA64 machines. Still, I think this is going to work for most of my
    purposes. Feel free to reply to me directly with comments, criticisms and
    bugs (mailto:dholcomb@msn.com).

    The output will look like this (select a fixed size font to view it aligned
    properly):

    C:\cpuid>cscript //nologo cpuinfo.vbs
    ---------------------------- Processor Information: ---------------------------
    | |
    | CPU: AMD Athlon(TM) XP 1900+, 1.6 Ghz (1 proc) |
    | Architecture: x86 |
    | |
    | CPUID Info: |
    | Function EAX EBX ECX EDX |
    | ======== ======== ======== ======== ======== |
    | 00000000 00000001 68747541 444D4163 69746E65 |
    | 00000001 00000662 00000000 00000000 0383FBFF |
    | 80000000 80000008 68747541 444D4163 69746E65 |
    | 80000001 00000762 00000000 00000000 C1C3FBFF |
    | 80000002 20444D41 6C687441 54286E6F 5820294D |
    | 80000003 39312050 002B3030 00000000 00000000 |
    | 80000004 00000000 00000000 00000000 00000000 |
    | 80000005 0408FF08 FF20FF10 40020140 40020140 |
    | 80000006 00000000 41004100 01008140 00000000 |
    | 80000007 00000000 00000000 00000000 00000001 |
    | 80000008 00002022 00000000 00000000 00000000 |
    | |
    -------------------------------------------------------------------------------

    This output is from a Pentium 4 Xeon processor with Hyperthreading , or Hyper-
    threading, enabled:

    C:\cpuinfo>cscript cpuinfo.vbs
    Microsoft (R) Windows Script Host Version 5.6
    Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

    ---------------------------- Processor Information: ---------------------------
    | |
    | CPU: Intel(R) Pentium(R) 4 CPU 2.40GHz, 2.4 Ghz (2 proc) |
    | Architecture: x86 |
    | |
    | CPUID Info: |
    | Function EAX EBX ECX EDX |
    | ======== ======== ======== ======== ======== |
    | 00000000 00000002 756E6547 6C65746E 49656E69 |
    | 00000001 00000F29 00020809 00004400 BFEBFBFF |
    | 00000002 665B5001 00000000 00000000 007B7040 |
    | 80000000 80000004 00000000 00000000 00000000 |
    | 80000001 00000000 00000000 00000000 00000000 |
    | 80000002 20202020 20202020 20202020 6E492020 |
    | 80000003 286C6574 50202952 69746E65 52286D75 |
    | 80000004 20342029 20555043 30342E32 007A4847 |
    | |
    -------------------------------------------------------------------------------

    Copy/paste the script below into a file called cpuinfo.vbs, then run
    "cscript //nologo cpuinfo.vbs".

    =========================== CUT HERE ===========================
    szComputerName = "."
    set WshShell = CreateObject("WScript.Shell")
    set WMIService_CIMV2 = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & szComputerName & "\root\cimv2")

    call DisplayProcessorInfo()

    WScript.Quit 0

    ' ============================================================================
    ' = Subroutine: DisplayProcessorInfo
    ' =
    ' = Purpose:
    ' ============================================================================
    Public Sub DisplayProcessorInfo
        dim TotalProcessors
        dim ProcessorSet, Processor
        dim ClockSpeed, Name, Family, Architecture
        dim ArchitectureString

        call PrintTitleSeparator("Processor Information:")
        call PrintBlankLineWithBorder

        TotalProcessors = 0
        set ProcessorSet = WMIService_CIMV2.ExecQuery ("select * from Win32_Processor")
        for each Processor in ProcessorSet
            TotalProcessors = TotalProcessors + 1
            ' CurrentClockSpeed can apparently report different results,
            ' especially if using a laptop with Intel SpeedStep technology,
            ' so we use MaxClockSpeed
            ClockSpeed = Processor.MaxClockSpeed
            Name = LTrim(Processor.Name)
            if (Right(Name, Len(" processor")) = " processor") then
                Name = Left(Name, Len(Name) - Len(" processor"))
            end if
            Family = Processor.Family
            Architecture = Processor.Architecture
        next

        if (ClockSpeed >= 1000) then
            call PrintFormattedLine(" CPU: " & Name & ", " & _
                                    FormatNumber(Round(ClockSpeed/1000.0, 2), 1) & _
                                    " Ghz (" & TotalProcessors & " proc)")
        else
            call PrintFormattedLine(" CPU: " & Name & ", " & _
                                    ClockSpeed & _
                                    " Mhz (" & TotalProcessors & " proc)")
        end if

        ArchitectureString = ArchitectureToString(Architecture)
        call PrintFormattedLine(" Architecture: " & ArchitectureString)

        if (ArchitectureString = "x86") then
            call QueryCPUIDx86()
        end if

        call PrintBlankLineWithBorder
        call PrintSeparator

        set ProcessorSet = Nothing

    End Sub 'DisplayProcessorInfo

    const MAX_CPUID_FUNCTIONS = 32

    Public Sub QueryCPUIDx86
        dim PathToCPUIDx86EXE
        dim CPUIDFunctions_Array()
        dim EAX_Array(), EBX_Array()
        dim ECX_Array(), EDX_Array()

        redim CPUIDFunctions_Array(MAX_CPUID_FUNCTIONS)
        redim EAX_Array(MAX_CPUID_FUNCTIONS)
        redim EBX_Array(MAX_CPUID_FUNCTIONS)
        redim ECX_Array(MAX_CPUID_FUNCTIONS)
        redim EDX_Array(MAX_CPUID_FUNCTIONS)

        ' Decodes CPUIDx86.EXE from this script and returns full path
        CPUIDx86EXEPath = GetCPUIDx86EXEPath()

        ' Executes CPUIDx86.EXE and returns CPUID function result
        ' in arrays
        call ExecuteCPUID(CPUIDx86EXEPath, _
                          CPUIDFunctions_Array, _
                          EAX_Array, _
                          EBX_Array, _
                          ECX_Array, _
                          EDX_Array)

        call DisplayCPUID(CPUIDFunctions_Array, _
                          EAX_Array, _
                          EBX_Array, _
                          ECX_Array, _
                          EDX_Array)

    End Sub 'QueryCPUIDx86

    Public Sub ExecuteCPUID(CPUIDEXEPath, _
                            CPUIDFunctions_Array, _
                            EAX_Array, _
                            EBX_Array, _
                            ECX_Array, _
                            EDX_Array)

        dim lines
        dim TextLine

        set WshScriptExec = WshShell.Exec(CPUIDEXEPath)

        lines = 0
        while Not WshScriptExec.StdOut.AtEndOfStream

            TextLine = WshScriptExec.StdOut.ReadLine
            call ParseCPUIDOutput(TextLine, _
                                  CPUIDFunctions_Array(lines), _
                                  EAX_Array(lines), _
                                  EBX_Array(lines), _
                                  ECX_Array(lines), _
                                  EDX_Array(lines))

            lines = lines + 1

        wend

        lines = lines - 1

        ' Trim down array sizes so LBound and UBound work
        redim preserve CPUIDFunctions_Array(lines)
        redim preserve EAX_Array(lines)
        redim preserve EBX_Array(lines)
        redim preserve ECX_Array(lines)
        redim preserve EDX_Array(lines)

    End Sub 'ExecuteCPUID

    Public Sub ParseCPUIDOutput(TextLine, _
                                CPUIDFunction, _
                                EAX, _
                                EBX, _
                                ECX, _
                                EDX)
        dim StartPos, EndPos
        dim Length

        ' Format is:
        ' StandardFunction:00000000,EAX:00000001,EBX:68747541,ECX:444D4163,EDX:69746E65

        StartPos = InStr(1, TextLine, ":", vbBinaryCompare) + 1
        EndPos = Instr(StartPos, TextLine, ",", vbBinaryCompare)
        Length = EndPos - StartPos
        CPUIDFunction = Mid(TextLine, StartPos, Length)

        StartPos = InStr(EndPos + 1, TextLine, ":", vbBinaryCompare) + 1
        EndPos = Instr(StartPos, TextLine, ",", vbBinaryCompare)
        Length = EndPos - StartPos
        EAX = Mid(TextLine, StartPos, Length)

        StartPos = InStr(EndPos + 1, TextLine, ":", vbBinaryCompare) + 1
        EndPos = Instr(StartPos, TextLine, ",", vbBinaryCompare)
        Length = EndPos - StartPos
        EBX = Mid(TextLine, StartPos, Length)

        StartPos = InStr(EndPos + 1, TextLine, ":", vbBinaryCompare) + 1
        EndPos = Instr(StartPos, TextLine, ",", vbBinaryCompare)
        Length = EndPos - StartPos
        ECX = Mid(TextLine, StartPos, Length)

        StartPos = InStr(EndPos + 1, TextLine, ":", vbBinaryCompare) + 1
        Length = Len(TextLine) - StartPos + 1
        EDX = Mid(TextLine, StartPos, Length)

    End Sub ' ParseCPUIDOutput

    Public Sub DisplayCPUID(CPUIDFunctions_Array, _
                            EAX_Array, _
                            EBX_Array, _
                            ECX_Array, _
                            EDX_Array)

        call PrintBlankLineWithBorder
        call PrintFormattedLine(" CPUID Info:")

        call PrintFormattedLine(PadChar(" ", 22) & _
                                "Function " & _
                                " EAX " & _
                                " EBX " & _
                                " ECX " & _
                                " EDX")
        call PrintFormattedLine(PadChar(" ", 22) & _
                                "======== " & _
                                "======== " & _
                                "======== " & _
                                "======== " & _
                                "========")
        dim i
        for i = LBound(CPUIDFunctions_Array) to UBound (CPUIDFunctions_Array)
            call PrintFormattedLine(PadChar(" ", 22) & _
                   CPUIDFunctions_Array(i) & " " & _
                   EAX_Array(i) & " " & _
                   EBX_Array(i) & " " & _
                   ECX_Array(i) & " " & _
                   EDX_Array(i))
        next

    End Sub ' DisplayCPUID

    Public Sub DecodeCPUIDx86EXE
        dim ScriptName

        ScriptName = WScript.ScriptFullName

    End Sub 'DecodeCPUIDx86EXE

    ' ============================================================================
    ' = Function: ArchitectureToString
    ' =
    ' = Purpose: Returns textual representation of the processor Architecture
    ' ============================================================================
    Public Function ArchitectureToString(Architecture)

        select case Architecture
            case 0
                ArchitectureString = "x86"
            case 1
                ArchitectureString = "MIPS"
            case 2
                ArchitectureString = "Alpha"
            case 3
                ArchitectureString = "PowerPC"
            case 6
                ArchitectureString = "ia64"
            case else
                ArchitectureString = "Unknown" & " (" & CStr(Architecture) & ")"
        end select

        ArchitectureToString = ArchitectureString

    End Function 'ArchitectureToString

    ' ============================================================================
    ' = Subroutine: PrintTitleSeparator
    ' =
    ' = Purpose: Centers a given title string between an equal number of hyphens
    ' = on either side of the string, forming a 79 character line of text.
    ' = Intended to be used as a title or header of a formatted block of text.
    ' ============================================================================
    Public Sub PrintTitleSeparator(Str)
        Len_Str = Len(Str)
        if ((Len_Str / 2) <> (Len_Str \ 2)) then
            Len_Str = Len_Str + 1
            Str = Str + " "
        end if
        WScript.Echo PadChar("-", (79-Len_Str)/2) & " " & Str & " " & _
                     PadChar("-", (79 - Len_Str-2)/2)
    End Sub 'PrintTitleSeparator

    ' ============================================================================
    ' = Function: PrintSeparator
    ' =
    ' = Purpose: Displays 79 character line of hyphens to be used as a separator
    ' = line
    ' ============================================================================
    Public Sub PrintSeparator
        WScript.Echo PadChar("-", 79)
    End Sub 'PrintSeparator

    ' ============================================================================
    ' = Function: PrintBlankLineWithBorder
    ' =
    ' = Purpose: Displays 79 character line of text with a vertical bar in the
    ' = leftmost and rightmost position. This is used to print a blank line
    ' = of text in combination with the other Print*Separator formatting
    ' = subroutines.
    ' ============================================================================
    Public Sub PrintBlankLineWithBorder
        WScript.Echo "|" & PadChar(" ", 77) & "|"
    End Sub 'PrintBlankLineWithBorrder

    ' ============================================================================
    ' = Function: PrintFormattedLine
    ' =
    ' = Purpose: Similar to PrintTitleSeparator, but left-justifies text within a
    ' = 79 character line of characters and places a vertical bar in the leftmost
    ' = and rightmost position
    ' ============================================================================
    Public Sub PrintFormattedLine(Str)
        Str = "| " & Str
        WScript.Echo Str & PadChar(" ", 78-Len(Str)) & "|"
    End Sub 'PrintLine

    ' ============================================================================
    ' = Function: PadChar
    ' =
    ' = Purpose: Creates a string which consists of one particular character and a
    ' = specified length. This is meant to be used to help format output which is
    ' = meant to be displayed in a columnar format.
    ' =
    ' = Example:
    ' = WScript.Echo "JobID" & PadChar(" ", 20 - Len("JobID")) & "Status" & _
    ' = PadChar(" ", 15 - Len("Status")) & "Priority"
    ' =
    ' = The above would create three columns of output. The first column is 20
    ' = chars wide, the second is 15. The three headings are "JobID", "Status",
    ' = and "Priority".
    ' ============================================================================
    Function PadChar(char, length)
        dim str
        dim i

        str = ""
        for i = 1 to length
            str = str + char
        next

        PadChar = str
    End Function

    const ForWriting = 2
    const TristateUseDefault = 1
    const TristateTrue = -1
    const TristateFalse = 0

    Function GetCPUIDx86EXEPath()
        dim StringCPUIDx86EXE

        StringCPUIDx86EXE = _
    "4D5A90000300000004000000FFFF0000B80000000000000040000000000000000000000000000000" & _
    "0000000000000000000000000000000000000000D80000000E1FBA0E00B409CD21B8014CCD215468" & _
    "69732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A" & _
    "2400000000000000364A251D722B4B4E722B4B4E722B4B4EF123444E702B4B4E722B4A4E662B4B4E" & _
    "F123164E712B4B4EFC23144E7C2B4B4EF123114E732B4B4E52696368722B4B4E0000000000000000" & _
    "00000000000000000000000000000000504500004C010200595317410000000000000000E0000F01" & _
    "0B01070A000800000002000000000000031400000010000000200000000000010010000000020000" & _
    "05000200050002000400000000000000003000000004000063180000030000800000040000200000" & _
    "0000100000100000000000001000000000000000000000000C160000280000000000000000000000" & _
    "000000000000000000000000000000000000000000000000601000001C0000000000000000000000" & _
    "0000000000000000000000000000000018110000400000000000000000000000001000004C000000" & _
    "0000000000000000000000000000000000000000000000002E746578740000007807000000100000" & _
    "0008000000040000000000000000000000000000200000602E646174610000002400000000200000" & _
    "00020000000C0000000000000000000000000000400000C000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "000000000000000000000000000000000000000000000000801600008A160000941600009C160000" & _
    "B0160000BA160000C2160000D0160000DA160000E2160000EE160000FE1600000A1700001E170000" & _
    "2E1700003E1700004C1700006A170000000000000000000000000000000000000000000000000000" & _
    "000000005953174100000000020000004F000000601100006005000046756E6374696F6E3A253038" & _
    "6C582C4541583A2530386C582C4542583A2530386C582C4543583A2530386C582C4544583A253038" & _
    "6C580A00457874656E646564000000005374616E64617264000000004552524F523A204350554944" & _
    "20696E737472756374696F6E206E6F7420737570706F727465640A0000000000FFFFFFFFB0120001" & _
    "B612000100000000FFFFFFFF4F150001631500010000000048000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "0000000004200001B0110001010000004E423130000000005953174101000000433A5C6462672E36" & _
    "2E332E31315C73646B5C73616D706C65735C63707569645C6F626A63686B5F776E65745F7838365C" & _
    "693338365C63707569642E706462000090150000000000000000000000000000558BEC83EC10C745" & _
    "F000000000C745F800000000C745F400000000C745FC000000008B45080FA28945F0895DF8894DF4" & _
    "8955FC8B450C8B4DF089088B55108B45F889028B4D148B55F489118B45188B4DFC89088BE55DC214" & _
    "00CCCCCCCCCCCCCC558BEC817D0800000080731068C0100001FF150010000183C404EB0E68B41000" & _
    "01FF150010000183C4048B4518508B4D14518B5510528B450C508B4D0851687C100001FF15001000" & _
    "0183C4185DC21400558BEC6AFF68F8100001689015000164A100000000506489250000000083C4DC" & _
    "5356578965E8C745FC0000000033C033DB33C933D20FA2C745FCFFFFFFFFEB36B801000000C38B65" & _
    "E868CC100001A10810000183C04050FF150410000183C408C745CCFFFFFFFFC745FCFFFFFFFF8B45" & _
    "CCE90C0100008D4DE4518D55D4528D45D8508D4DD0516A00E8C3FEFFFF8B55D08955DC8B45E4508B" & _
    "4DD4518B55D8528B45D0506A00E806FFFFFFC745E001000000EB098B4DE083C101894DE08B55E03B" & _
    "55DC77348D45E4508D4DD4518D55D8528D45D0508B4DE051E873FEFFFF8B55E4528B45D4508B4DD8" & _
    "518B55D0528B45E050E8BAFEFFFFEBBB8D4DE4518D55D4528D45D8508D4DD0516800000080E83EFE" & _
    "FFFF8B55D08955DC8B45E4508B4DD4518B55D8528B45D0506800000080E87EFEFFFFC745E0010000" & _
    "80EB098B4DE083C101894DE08B55E03B55DC77348D45E4508D4DD4518D55D8528D45D0508B4DE051" & _
    "E8EBFDFFFF8B55E4528B45D4508B4DD8518B55D0528B45E050E832FEFFFFEBBB33C08B4DF064890D" & _
    "000000005F5E5B8BE55DC36A286808110001E8A901000066813D000000014D5A7528A13C00000181" & _
    "B8000000015045000075170FB7881800000181F90B010000742181F90B02000074068365E400EB2A" & _
    "83B8840000010E76F133C93988F8000001EB1183B8740000010E76DE33C93988E80000010F95C189" & _
    "4DE48365FC006A01FF154010000159830D18200001FF830D1C200001FFFF153C1000018B0D142000" & _
    "018908FF15381000018B0D102000018908A1341000018B00A320200001E8FA000000833D00200001" & _
    "00750C68B4150001FF153010000159E8CE00000068581000016854100001E8B9000000A10C200001" & _
    "8945DC8D45DC50FF35082000018D45E0508D45D8508D45D450FF15281000018945CC685010000168" & _
    "4C100001E8830000008B45E08B0D241000018901FF75E0FF75D8FF75D4E83EFDFFFF83C4308BF089" & _
    "75C8837DE400750756FF1520100001FF151C100001EB2D8B45EC8B088B09894DD05051E836000000" & _
    "5959C38B65E88B75D0837DE400750756FF1514100001FF1510100001834DFCFF8BC6E86C000000C3" & _
    "CCCCCCCCCCCCCCCCFF250C100001FF2518100001FF252C10000168000003006800000100E8530000" & _
    "005959C333C0C3CC689015000164A100000000508B442410896C24108D6C24102BE05356578B45F8" & _
    "8965E8508B45FCC745FCFFFFFFFF8945F88D45F064A300000000C38B4DF064890D00000000595F5E" & _
    "5BC951C3FF2544100001CCCC3416000000000000000000005E170000001000000000000000000000" & _
    "000000000000000000000000801600008A160000941600009C160000B0160000BA160000C2160000" & _
    "D0160000DA160000E2160000EE160000FE1600000A1700001E1700002E1700003E1700004C170000" & _
    "6A17000000000000EF027072696E74660000A902667072696E74660044015F696F620000F2005F65" & _
    "78636570745F68616E646C6572330000CA005F635F6578697400FB005F65786974004E005F586370" & _
    "7446696C74657200CD005F636578697400009A0265786974000071005F5F696E6974656E76007000" & _
    "5F5F6765746D61696E617267730040015F696E69747465726D009E005F5F736574757365726D6174" & _
    "686572720000BB005F61646A7573745F66646976000083005F5F705F5F636F6D6D6F646500008800" & _
    "5F5F705F5F666D6F646500009C005F5F7365745F6170705F7479706500006D73766372742E646C6C" & _
    "0000DB005F636F6E74726F6C66700000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "0000000000000000000000000000000000000000000000000000000000000000010000004EE640BB" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "00000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
    "000000000000000000000000000000000000000000000000"
        dim BinFile
        set fso = CreateObject("Scripting.FileSystemObject")
        set f = fso.CreateTextFile("cpuidx86.exe")

        filelen = Len(StringCPUIDx86EXE)

        for i = 1 to filelen step 2
            while ((i <= filelen) And (IsWhiteSpace(Mid(StringCPUIDx86EXE, i, 1))))
                i = i + 1
            wend

            if (i <= filelen) then
                BinFile = BinFile & Chr(HexStringToInt(Mid(StringCPUIDx86EXE, i, 2)))
            end if
        next

        call f.Write(BinFile)
        call f.Close()

        GetCPUIDx86EXEPath = fso.GetAbsolutePathName("cpuidx86.exe")

        set f = Nothing
        set fso = Nothing

    End Function 'GetCPUIDx86EXEPath

    Public Function IsWhiteSpace(char)
        dim result
        if (Len(char) = 0) then
            result = false
        elseif (Asc(char) < 32) then
            result = True
        else
            result = False
        end if
        IsWhiteSpace = result
    End Function

    Public Function HexStringToInt(hexstring)
        dim i, dblval, hexchar, hexval
        ' Hex is treated as unsigned for the conversion, so
        ' use CDbl
        dblval = CDbl(0)
        for i = 1 to Len(hexstring)
            hexchar = Mid(hexstring, i, 1)
            if (IsNumeric(hexchar)) then
                hexval = CLng(Mid(hexstring, i, 1))
            else
                hexval = 10 + CLng(Asc(UCase(Mid(hexstring, i, 1))) - Asc("A"))
            end if
            dblval = CDbl(dblval*16) + CDbl(hexval)
        next
        HexStringToInt = dblval
    End Function
    =========================== END CUT ===========================

    "Torgeir Bakken (MVP)" <Torgeir.Bakken-spam@hydro.com> wrote in message
    news:%23oNCj59eEHA.2560@TK2MSFTNGP09.phx.gbl...
    > David Holcomb wrote:
    >
    > > Is there any way to do this with WMI? Perhaps, even, a way to query for
    the
    > > number of logical versus physical CPUs? Perhaps something stored in the
    > > registry? Or some way to query for the number of "licensed PHYSICAL
    > > processors" (which, if different from the number of processors
    enumerated by
    > > Win32_Processor would indicate a form of hyperthreading is enabled).
    > Hi
    >
    > You will not be able to use WMI to detect if hyperthreading is enabled
    > and I don't know any other script method either that will do it.
    >
    >
    > From: Steve Lee [MSFT] (slee@online.microsoft.com)
    > Subject: Re: hyperthreading oddity
    > Newsgroups: microsoft.public.win32.programmer.wmi
    > Date: 2003-03-03 13:32:05 PST
    >
    > <quote>
    > This is a known issue. WMI is currently not hyperthreading aware and
    > simply reports what the OS is reporting.
    > </quote>
    >
    >
    > --
    > torgeir, Microsoft MVP Scripting and WMI, Porsgrunn Norway
    > Administration scripting examples and an ONLINE version of
    > the 1328 page Scripting Guide:
    > http://www.microsoft.com/technet/scriptcenter/default.mspx

    "Torgeir Bakken (MVP)" <Torgeir.Bakken-spam@hydro.com> wrote in message news:%23oNCj59eEHA.2560@TK2MSFTNGP09.phx.gbl...
    > David Holcomb wrote:
    >
    >> Is there any way to do this with WMI? Perhaps, even, a way to query for the number of logical versus physical CPUs? Perhaps
    >> something stored in the registry? Or some way to query for the number of "licensed PHYSICAL processors" (which, if different
    >> from the number of processors enumerated by Win32_Processor would indicate a form of hyperthreading is enabled).
    > Hi
    >
    > You will not be able to use WMI to detect if hyperthreading is enabled
    > and I don't know any other script method either that will do it.
    >
    >
    > From: Steve Lee [MSFT] (slee@online.microsoft.com)
    > Subject: Re: hyperthreading oddity
    > Newsgroups: microsoft.public.win32.programmer.wmi
    > Date: 2003-03-03 13:32:05 PST
    >
    > <quote>
    > This is a known issue. WMI is currently not hyperthreading aware and
    > simply reports what the OS is reporting.
    > </quote>
    >
    >
    > --
    > torgeir, Microsoft MVP Scripting and WMI, Porsgrunn Norway
    > Administration scripting examples and an ONLINE version of
    > the 1328 page Scripting Guide:
    > http://www.microsoft.com/technet/scriptcenter/default.mspx


  • Next message: Tim Gorgs: "WMI problems after installation of SP2 on Windows XP"

    Relevant Pages