j0kky

_WinApi_GetLogicalProcessorInformation

5 posts in this topic

#1 ·  Posted (edited)

Hi guys,

thanks to this request, I wrote my version of GetLogicalProcessorInformation UDF for x86 e x64:

; #FUNCTION# ========================================================================================================================
; Name...........: _WinAPI_GetLogicalProcessorInformation
; Description ...: Retrieves information about logical processors and related hardware.
; Syntax.........: _WinAPI_GetLogicalProcessorInformation()
; Return values .: On success it returns a bidimensional array: on rows there is the list of processor sets, these are the columns:
;                  |[0] - A logical processor affinity mask, which indicates the logical processors that the information applies to.
;                  |[1] - If setted, then the specified logical processors share a single processor core.
;                  |[2] - How many active processors that share functional units are in the relationship
;                         (it is setted only if the previous element is setted too)
;                  |[3] - If setted, it identifies the NUMA node (it can be 0).
;                  |[4] - If setted, the specified logical processors share a physical package.
;                  |[5] - A bidimensional array: on rows there is the cache list, these are the columns:
;                         |[0] - The cache level
;                         |[1] - The cache associativity
;                         |[2] - The cache line size, in bytes
;                         |[3] - The cache size, in bytes
;                         |[4] - The cache type
;                  On failure it returns -1 and sets @error to non zero:
;                  |-1 - internal error
;                  |-2 - missing DLL (Ws2_32.dll)
; Remarks .......: Search GetLogicalProcessorInformation in MSDN Library.
; Author ........: j0kky
; Modified ......: 1.0.0
; Links .........: https://msdn.microsoft.com/it-it/library/windows/desktop/ms683194(v=vs.85).aspx
; ====================================================================================================================================
Func _WinAPI_GetLogicalProcessorInformation()
    Local $hDll = DllOpen("kernel32.dll")
    If @error Then Return SetError(-2, 0, -1)
    Local Const $ERROR_INSUFFICIENT_BUFFER = 122
    Local $aRet = DllCall($hDll, "BOOL", "GetLogicalProcessorInformation", "ptr", Null, "dword*", 0)
    If @error Or Not (DllCall($hDll, "DWORD", "GetLastError")[0] = $ERROR_INSUFFICIENT_BUFFER) Then
        DllClose($hDll)
        Return SetError(-1, 0, -1)
    EndIf
    Local $nReturnLength = $aRet[2]
    Local $tBuffer = DllStructCreate("byte[" & $nReturnLength & "]")
    Local $pBuffer = DllStructGetPtr($tBuffer)
    $aRet = DllCall($hDll, "BOOL", "GetLogicalProcessorInformation", "ptr", $pBuffer, "dword*", $nReturnLength)
    If @error Or Not $aRet[0] Then
        DllClose($hDll)
        Return SetError(-1, 0, -1)
    EndIf
    Local Const $tagSYSTEM_LOGICAL_PROCESSOR_INFORMATION = "ULONG_PTR ProcessorMask; INT_PTR Relationship; BYTE UnionBuffer[16]"
    Local $tSYSTEM_LOGICAL_PROCESSOR_INFORMATION = DllStructCreate($tagSYSTEM_LOGICAL_PROCESSOR_INFORMATION, $pBuffer)
    Local $nSize = DllStructGetSize($tSYSTEM_LOGICAL_PROCESSOR_INFORMATION), $tCACHE_DESCRIPTOR, _
            $aResult[1][6], _ ;mask, core, logical, numa, package, cache
            $aCacheModel[0][5], _ ;level, associativity, line size, size, processor cache type
            $nOffset = 0, $nArraySize, $aCache, $vProcessor, $nProcessorMask
    $aResult[0][0] = $tSYSTEM_LOGICAL_PROCESSOR_INFORMATION.ProcessorMask
    $aResult[0][5] = $aCacheModel
    Do
        $tSYSTEM_LOGICAL_PROCESSOR_INFORMATION = DllStructCreate($tagSYSTEM_LOGICAL_PROCESSOR_INFORMATION, $pBuffer + $nOffset)
        $nProcessorMask = $tSYSTEM_LOGICAL_PROCESSOR_INFORMATION.ProcessorMask
        $nArraySize = UBound($aResult)
        For $i = 0 To ($nArraySize - 1)
            If $aResult[$i][0] = $nProcessorMask Then
                $vProcessor = $i
                ExitLoop
            EndIf
        Next
        If $vProcessor = Null Then
            ReDim $aResult[$nArraySize + 1][6]
            $aResult[$nArraySize][0] = $nProcessorMask
            $aResult[$nArraySize][5] = $aCacheModel
            $vProcessor = $nArraySize
        EndIf
        Switch $tSYSTEM_LOGICAL_PROCESSOR_INFORMATION.Relationship
            Case 0 ;RelationProcessorCore
                $aResult[$vProcessor][1] += 1
                If (DllStructCreate("byte Flags", DllStructGetPtr($tSYSTEM_LOGICAL_PROCESSOR_INFORMATION, "UnionBuffer")).Flags) = 1 Then
                    For $i = 1 To (($nSize = 24) ? 32 : 64)
                        $aResult[$vProcessor][2] += (Mod($nProcessorMask, 2) ? 1 : 0)
                        $nProcessorMask = Floor($nProcessorMask / 2)
                    Next
                EndIf
            Case 1 ;RelationNumaNode
                $aResult[$vProcessor][3] = DllStructCreate("dword NodeNumber", DllStructGetPtr($tSYSTEM_LOGICAL_PROCESSOR_INFORMATION, "UnionBuffer")).NodeNumber
            Case 2 ;RelationCache
                $tCACHE_DESCRIPTOR = DllStructCreate("byte Level; byte Associativity; word LineSize; dword Size; INT Type", _
                        DllStructGetPtr($tSYSTEM_LOGICAL_PROCESSOR_INFORMATION, "UnionBuffer"))
                $aCache = $aResult[$vProcessor][5]
                $nArraySize = UBound($aCache)
                ReDim $aCache[$nArraySize + 1][5]
                $aCache[$nArraySize][0] = $tCACHE_DESCRIPTOR.Level
                $aCache[$nArraySize][1] = $tCACHE_DESCRIPTOR.Associativity
                $aCache[$nArraySize][2] = $tCACHE_DESCRIPTOR.LineSize
                $aCache[$nArraySize][3] = $tCACHE_DESCRIPTOR.Size
                $aCache[$nArraySize][4] = $tCACHE_DESCRIPTOR.Type
                $aResult[$vProcessor][5] = $aCache
            Case 3 ;RelationProcessorPackage
                $aResult[$vProcessor][4] += 1
        EndSwitch
        $nOffset += $nSize
        $vProcessor = Null
    Until $nOffset = $nReturnLength
    DllClose($hDll)
    Return $aResult
EndFunc   ;==>_WinAPI_GetLogicalProcessorInformation

Usage example:

#include <array.au3>
$array = _WinAPI_GetLogicalProcessorInformation()

_ArrayDisplay($array, "Processor set list:")
For $i = 0 To UBound($array) - 1
    _ArrayDisplay($array[$i][5], "Processor set " & $i + 1 & " cache:")
Next

:)

Edited by j0kky
1 person likes this

Share this post


Link to post
Share on other sites



 Nice version. Thank you. dllcall return type should be BOOL instead BOOLEAN.

 

Saludos

Share this post


Link to post
Share on other sites

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Similar Content

    • powerbass4
      WINAPI GetLogicalProcessorInformation
      By powerbass4
      Hi, I need the help of some "C++ Pros" of you....

      The "WINAPI GetLogicalProcessorInformation" function does not exists in the AutoIt Includes, so I decided to build it on my own ....no success so far.
      I adapted easy functions, but this one seems to be odd and unfamiliar.

      I hope somebody can help me.... and after that this function should be added to the Includes (WinAPISys.au3).
       
      BOOL WINAPI GetLogicalProcessorInformation( _Out_ PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer, _Inout_ PDWORD ReturnLength ); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683194(v=vs.85).aspx
       
      typedef struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION { ULONG_PTR ProcessorMask; LOGICAL_PROCESSOR_RELATIONSHIP Relationship; union { struct { BYTE Flags; } ProcessorCore; struct { DWORD NodeNumber; } NumaNode; CACHE_DESCRIPTOR Cache; ULONGLONG Reserved[2]; }; } SYSTEM_LOGICAL_PROCESSOR_INFORMATION, *PSYSTEM_LOGICAL_PROCESSOR_INFORMATION; https://msdn.microsoft.com/en-us/library/windows/desktop/ms686694(v=vs.85).aspx
    • corgano
      Help / Reading usb controller with _WinAPI_RegisterRawInputDevices
      By corgano
      Edit: If you already read this post, I updated it to better fit the scope of what I want to do.

      My goal is to be able to read the raw output from a usb type controller (or mouse or keyboard, don't want it to be controller-only) so i can see how / what changes when i hit buttons. I've gotten as far as finding HID page documentation and documentation for the device Struct, but I don't know where to go from here
      How do I tell what and Useage to use for any given controller / Keyboard / Mouse? How do I get a list of all HID devices connected and their UsagePage / Usage? How do I register multiple devices / get raw input from multiple devices at once? Here is the modified example script i am using:
      #include <APISysConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WinAPIGdi.au3> #include <WinAPIMisc.au3> #include <WinAPISys.au3> #include <WindowsConstants.au3> Opt('TrayAutoPause', 0) Global $iFlagsOld = 0, $iDataOld = 0 ; Create GUI Global $g_hForm = GUICreate('Test ' & StringReplace(@ScriptName, '.au3', '()'), 160, 212, @DesktopWidth - 179, @DesktopHeight - 283, BitOR($WS_CAPTION, $WS_POPUP, $WS_SYSMENU), $WS_EX_TOPMOST) ; To obtain the values of "UsagePage" and "Usage" members of this structure read HID Usage Tables documentation ; http://www.usb.org/developers/devclass_docs/HID1_11.pdf ; Disregaurd that, official USB documention = useless. Here is a human/normal-person friendly list ; http://www.freebsddiary.org/APC/usb_hid_usages.php ; Information on the Struct (eg what Flags and hTarget do) can be found here ; https://msdn.microsoft.com/en-us/library/ms645565(v=vs.85).aspx Local $tRID = DllStructCreate($tagRAWINPUTDEVICE) DllStructSetData($tRID, 'UsagePage', 0x01) ; Generic Desktop Controls DllStructSetData($tRID, 'Usage', 0x06) ; Mouse DllStructSetData($tRID, 'Flags', $RIDEV_INPUTSINK) ; This flag makes window hTarget accept input even when it's not active. MUST define hTarget DllStructSetData($tRID, 'hTarget', $g_hForm) ; The target window that will be sent events, used with some Flags ; Register HID input to obtain row input _WinAPI_RegisterRawInputDevices($tRID) ; Register WM_INPUT message GUIRegisterMsg($WM_INPUT, 'WM_INPUT') ;~ GUISetState(@SW_SHOW) Do Until GUIGetMsg() = $GUI_EVENT_CLOSE Func WM_INPUT($hWnd, $iMsg, $wParam, $lParam) #forceref $iMsg, $wParam Switch $hWnd Case $g_hForm Local $tRIM = DllStructCreate($tagRAWINPUTMOUSE) If _WinAPI_GetRawInputData($lParam, $tRIM, DllStructGetSize($tRIM), $RID_INPUT) Then Local $iFlags = DllStructGetData($tRIM, 'Flags') Local $sFlag = "", $sData = "" $iFlags = DllStructGetData($tRIM, 'ButtonFlags') If $iFlags <> $iFlagsOld Then $sFlag = $iFlags $iFlagsOld = $iFlags EndIf $iData = DllStructGetData($tRIM, 'ButtonData') If $iData <> $iDataOld Then $sData = $iData $iDataOld = $iData EndIf If $sFlag&$sData <> "" Then ConsoleWrite($sFlag&" "&$sData&@CRLF) EndIf EndIf EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_INPUT
      Old post:
       
    • scintilla4evr
      _WinAPI_DwmEnableBlurBehindWindow for Windows 10
      By scintilla4evr
      Function for enabling Aero-like blur effect in Windows 10.
    • scintilla4evr
      _WinAPI_DwmEnableBlurBehindWindow in Windows 10
      By scintilla4evr
      Hello! As some of you probably know, _WinAPI_DwmEnableBlurBehindWindow does not work as you'd like it to work in Windows 10. It doesn't add Aero-like blur, as seen in the new Start menu or Notification Center. I looked for a solution and found "the most elegant" one:

      The blur only affects the inside of the window and it is not colored. It can be enabled via an undocumented SetWindowCompositionAttribute function in user32.dll.
      _WinAPI_DwmEnableBlurBehindWindow for Windows 10 - this archive contains both the UDF and the example.
    • Wicked_Caty
      Difference between commands
      By Wicked_Caty
      I'm not really sure, if that belongs here. However, I don't need any real help, so I put it here.
      What's the difference between _WinAPI_beep($frequency, $duration) and Beep($frequency, $duration)?
      It does the same. Beeping. Is there any difference at all, apart from the name?
      Thanks xD