powerbass4 Posted November 11, 2016 Posted November 11, 2016 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
Moderators JLogan3o13 Posted November 11, 2016 Moderators Posted November 11, 2016 Moved to a more appropriate forum "Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball How to get your question answered on this forum!
AndyG Posted November 12, 2016 Posted November 12, 2016 (edited) maybe there is a better way to "translate" the union expandcollapse popup#include <Array.au3> #include <WinAPI.au3> #include <array.au3> #AutoIt3Wrapper_UseX64=n ;variablen zuordnen Enum $RelationProcessorCore, _ $RelationNumaNode, _ $RelationCache, _ $RelationProcessorPackage, _ $RelationGroup, _ $RelationAll Global $processorCoreCount = 0, _ $logicalProcessorCount = 0, _ $processorPackageCount = 0, _ $numaNodeCount = 0, _ $L1CacheCount = 0, _ $L2CacheCount = 0, _ $L3CacheCount = 0, _ $L1CacheSize = 0, _ $L2CacheSize = 0, _ $L3CacheSize = 0 $dll = DllOpen("kernel32.dll") ConsoleWrite('- Debug(' & @ScriptLineNumber & ') : $dll = ' & $dll & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console ConsoleWrite('- : $dll = ' & $dll & @CRLF) ;### Debug Console ;adresse holen $procaddress = DllCall($dll, "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("kernel32.dll"), "str", "GetLogicalProcessorInformation") ConsoleWrite('- : $ret = ' & $procaddress[0] & @CRLF) ;### Debug Console ;Funktion callen, um buffer größe zu erhalten $return_length = 0 $ret = DllCallAddress("uint", $procaddress[0], "dword", 0, "uint*", $return_length) ;~ ConsoleWrite('- : $ret = ' & $ret & @CRLF ) ;### Debug Console $return_length = $ret[2] ;~ ConsoleWrite('- : $return_length = ' & $return_length & @CRLF ) ;### Debug Console ;~ _arraydisplay($ret) $struct_bytes = DllStructCreate("byte [" & $return_length & "]") $ptr = DllStructGetPtr($struct_bytes) ;~ ConsoleWrite('- : $ptr = ' & $ptr & @CRLF ) ;### Debug Console ;Funktion callen, um bufferpointer zu übergeben und buffer zu füllen $ret = DllCallAddress("uint", $procaddress[0], "ptr", $ptr, "uint*", $return_length) ;~ ConsoleWrite('- : $ret = ' & $ret[0] & @CRLF ) ;### Debug Console ;~ _arraydisplay($ret) ;zeig´s mir baby!!! $ret = DllStructGetData($struct_bytes, 1) ConsoleWrite('- : $ret = ' & ($ret) & @CRLF) ;### Debug Console For $i = 3 To $return_length * 2 Step 48 $a = StringMid($ret, $i, 48) ConsoleWrite(" " & $a & @CRLF) Next ConsoleWrite(@CRLF & @CRLF & "+ Ergebnisse:" & @CRLF & @CRLF) ;zuordnen For $i = 0 To $return_length - 24 Step 24 $a = StringMid($ret, 3 + $i * 2, 48) ConsoleWrite($a & @CRLF) ;~ ;PLPI = PSYSTEM_LOGICAL_PROCESSOR_INFORMATION $struct_PLPI = DllStructCreate("dword ProcessorMask;" & _ "dword Relationship;" & _ "byte [16];", $ptr + $i) ;die "union" nachbasteln....alle $struct_Processorcore = DllStructCreate("byte Flags", DllStructGetPtr($struct_PLPI) + 8) $struct_NumaNode = DllStructCreate("dword NodeNumber", DllStructGetPtr($struct_PLPI) + 8) $struct_CACHE_DESCRIPTOR = DllStructCreate("byte Level;" & _ "byte Associativity;" & _ "word Linesize;" & _ "dword Size;" & _ "dword Type", DllStructGetPtr($struct_PLPI) + 8) ;~ $structsize = DllStructGetSize($struct_PLPI) ;~ ConsoleWrite('- : $structsize = ' & $structsize & @CRLF ) ;### Debug Console ;Daten auslesen $ProcessorMask = DllStructGetData($struct_PLPI, "ProcessorMask") ConsoleWrite('> $ProcessorMask = ' & $ProcessorMask & @CRLF) $Relationship = DllStructGetData($struct_PLPI, "Relationship") ConsoleWrite('> $Relationship = ' & $Relationship) $Relationship = Int(DllStructGetData($struct_PLPI, "Relationship")) Switch $Relationship Case $RelationProcessorCore ;0 es werden Prozessor daten abgefragt ConsoleWrite(" ProcessorCore" & @CRLF) $ProcessorCore = DllStructGetData($struct_Processorcore, "Flags") ConsoleWrite('- : $ProcessorCore = ' & $ProcessorCore & @CRLF) ;### Debug Console $processorCoreCount += 1 $logicalProcessorCount += CountSetBits($ProcessorMask) Case $RelationNumaNode ConsoleWrite(" NumaNode" & @CRLF) $NodeNumber = DllStructGetData($struct_NumaNode, "NodeNumber") ConsoleWrite('- : $NodeNumber = ' & $NodeNumber & @CRLF) ;### Debug Console $numaNodeCount += 1 Case $RelationCache ConsoleWrite(" RelationCache" & @CRLF) $Level = DllStructGetData($struct_CACHE_DESCRIPTOR, "Level") ConsoleWrite('- : $Level = ' & $Level & @CRLF) ;### Debug Console $Associativity = DllStructGetData($struct_CACHE_DESCRIPTOR, "Associativity") ConsoleWrite('- : $Associativity = ' & $Associativity & @CRLF) ;### Debug Console $Linesize = DllStructGetData($struct_CACHE_DESCRIPTOR, "Linesize") ConsoleWrite('- : $Linesize = ' & $Linesize & @CRLF) ;### Debug Console $Size = DllStructGetData($struct_CACHE_DESCRIPTOR, "Size") ConsoleWrite('- : $Size = ' & $Size & @CRLF) ;### Debug Console $Type = DllStructGetData($struct_CACHE_DESCRIPTOR, "Type") ConsoleWrite('- : $Type = ' & $Type & @CRLF) ;### Debug Console Switch $Level Case 1 $L1CacheCount += 1 $L1CacheSize += $Size Case 2 $L2CacheCount += 1 $L2CacheSize += $Size Case 3 $L3CacheCount += 1 $L3CacheSize += $Size EndSwitch Case $RelationProcessorPackage ConsoleWrite(" ProcessorPackage" & @CRLF) $processorPackageCount += 1 Case $RelationGroup ConsoleWrite(" Group" & @CRLF) EndSwitch ConsoleWrite(@CRLF & @CRLF) Next $returnstring = "GetLogicalProcessorInformation:" & @CRLF & @CRLF & _ StringFormat("Number %-30s = %u", "Processorcores", $processorCoreCount) & @CRLF & _ StringFormat("Number %-30s = %u", "NumaNodes", $numaNodeCount) & @CRLF & _ StringFormat("Number %-30s = %u", "logicalProcessorCount", $logicalProcessorCount) & @CRLF & _ StringFormat("Number %-30s = %u", "processorPackageCount", $processorPackageCount) & @CRLF & _ StringFormat("Number %-30s = %u/%u/%u", "Level1/2/3-Caches", $L1CacheCount, $L2CacheCount, $L3CacheCount) & @CRLF & _ StringFormat("Number %-30s = %u/%u/%u", "L1/L2/L3 cache sizes (kB)", $L1CacheSize / 1024, $L2CacheSize / 1024, $L3CacheSize / 1024) & @CRLF & _ "" ConsoleWrite($returnstring & @CRLF) MsgBox(0, "GetLogicalProcessorInformation", $returnstring) Func CountSetBits($uint) ;zählt gesetzte bits $anz = 0 For $i = 0 To 31 If BitAND(2 ^ $i, $uint) Then $anz += 1 Next Return $anz EndFunc ;==>CountSetBits Edited November 12, 2016 by AndyG
powerbass4 Posted November 12, 2016 Author Posted November 12, 2016 Thanks again Andy ! Maybe someone will optimize it and give it to the AutoIt devs....
j0kky Posted November 12, 2016 Posted November 12, 2016 (edited) @AndyG: Hi! Please, can you be so kind to explain me these two issues: Quote For $i = 0 To $return_length - 48 Step 24 Why do you exclude last 48 bytes? Quote $a = StringMid($ret, 3 + $i * 2, 48) Why do you exclude first 3 bytes and $i is multiplied by 2? Edited November 12, 2016 by j0kky Spoiler Some UDFs I created: Winsock UDF STUN UDF WinApi_GetAdaptersAddresses _WinApi_GetLogicalProcessorInformation Bitwise with 64 bit integers An useful collection of zipping file UDFs
AndyG Posted November 12, 2016 Posted November 12, 2016 (edited) @j0kky, Because I can not program (only "read" a little bit) C(++)-code, i had to examine those "UNION"-stuff. The "showing" of the bytes in several "lines" helped me to understand the structure, so i converted the bytes to chars to have a better "view" into the data! The SYSTEM_LOGICAL_PROCESSOR_INFORMATION - struct has a lenght of 24bytes. In HEX-representation, the length is 48 chars....the length of the entire string is 2 (chars/bytes) for the "0x" and X*48(chars/bytes). The data starts at the third character, the first 2 are the "0x". Imagine, that the 24Byte-SYSTEM_LOGICAL_PROCESSOR_INFORMATION - struct is a "Window" to show only 24Bytes in the memory from all the bytes given back from the GetLogicalProcessorInformation-Function-call. The start-address for every "24-bytes-Window" is the pointer to the memory plus 24 Bytes.... If you reach the end, the last "24-bytes-Window" is the region/area 24 bytes in front of the last byte....in HEX-reperesentation 48 chars. The last "address" for stringmid() to show the next(last) 48 chars is (endaddress-48). I hope that i could clarify a little bit and that my explanations were useful. If not, ask again and surely someone with a much better phrasing/mode of expression than me will help you! [OT]What should I do without google translate[OT] code for 32/64Bit expandcollapse popup#include <Array.au3> #include <WinAPI.au3> #AutoIt3Wrapper_UseX64=y ;für 32/64Bit ;variablen zuordnen Enum $RelationProcessorCore, _ $RelationNumaNode, _ $RelationCache, _ $RelationProcessorPackage, _ $RelationGroup, _ $RelationAll Global $processorCoreCount = 0, _ $logicalProcessorCount = 0, _ $processorPackageCount = 0, _ $numaNodeCount = 0, _ $L1CacheCount = 0, _ $L2CacheCount = 0, _ $L3CacheCount = 0, _ $L1CacheSize = 0, _ $L2CacheSize = 0, _ $L3CacheSize = 0 If @AutoItX64 Then $32_64 = 32 $sSize = 16 Else $32_64 = 24 $sSize = 8 EndIf $dll = DllOpen("kernel32.dll") ;~ ConsoleWrite('- Debug(' & @ScriptLineNumber & ') : $dll = ' & $dll & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console ;~ ConsoleWrite('- : $dll = ' & $dll & @CRLF) ;### Debug Console ;adresse holen $procaddress = DllCall($dll, "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("kernel32.dll"), "str", "GetLogicalProcessorInformation") ;~ ConsoleWrite('- : $ret = ' & $procaddress[0] & @CRLF) ;### Debug Console ;Funktion callen, um buffer größe zu erhalten $return_length = 0 $ret = DllCallAddress("uint", $procaddress[0], "dword", 0, "uint*", $return_length) ;~ ConsoleWrite('- : $ret = ' & $ret & @CRLF ) ;### Debug Console $return_length = $ret[2] ;~ ConsoleWrite('- : $return_length = ' & $return_length & @CRLF ) ;### Debug Console ;~ _ArrayDisplay($ret) $struct_bytes = DllStructCreate("byte [" & $return_length & "]") $ptr = DllStructGetPtr($struct_bytes) ;~ ConsoleWrite('- : $ptr = ' & $ptr & @CRLF ) ;### Debug Console ;Funktion callen, um bufferpointer zu übergeben und buffer zu füllen $ret = DllCallAddress("uint", $procaddress[0], "ptr", $ptr, "uint*", $return_length) ;~ ConsoleWrite('- : $ret = ' & $ret[0] & @CRLF ) ;### Debug Console ;~ _arraydisplay($ret) ;zeig´s mir baby!!! $ret = DllStructGetData($struct_bytes, 1) ConsoleWrite('- : $ret = ' & ($ret) & @CRLF) ;### Debug Console For $i = 3 To $return_length * 2 Step $32_64 * 2 $a = StringMid($ret, $i, $32_64 * 2) ConsoleWrite(" " & $a & @CRLF) Next ConsoleWrite(@CRLF & @CRLF & "+ Ergebnisse:" & @CRLF & @CRLF) ;zuordnen For $i = 0 To $return_length - $32_64 Step $32_64 $a = StringMid($ret, 3 + $i * 2, $32_64 * 2) ConsoleWrite($a & @CRLF) ;~ ;PLPI = PSYSTEM_LOGICAL_PROCESSOR_INFORMATION $struct_PLPI = DllStructCreate("uint_ptr ProcessorMask;" & _ "uint_ptr Relationship;" & _ "byte [" & $32_64 - 16 & "]", $ptr + $i) ;die "union" nachbasteln....alle $struct_Processorcore = DllStructCreate("byte Flags", DllStructGetPtr($struct_PLPI) + $sSize) $struct_NumaNode = DllStructCreate("dword NodeNumber", DllStructGetPtr($struct_PLPI) + $sSize) $struct_CACHE_DESCRIPTOR = DllStructCreate("byte Level;" & _ "byte Associativity;" & _ "word Linesize;" & _ "dword Size;" & _ "dword Type", DllStructGetPtr($struct_PLPI) + $sSize) ;~ $structsize = DllStructGetSize($struct_PLPI) ;~ ConsoleWrite('- : $structsize = ' & $structsize & @CRLF ) ;### Debug Console ;Daten auslesen $ProcessorMask = DllStructGetData($struct_PLPI, "ProcessorMask") ConsoleWrite('> $ProcessorMask = ' & $ProcessorMask & @CRLF) $Relationship = DllStructGetData($struct_PLPI, "Relationship") ConsoleWrite('> $Relationship = ' & $Relationship) $Relationship = Int(DllStructGetData($struct_PLPI, "Relationship")) Switch $Relationship Case $RelationProcessorCore ;0 es werden Prozessor daten abgefragt ConsoleWrite(" ProcessorCore" & @CRLF) $ProcessorCore = DllStructGetData($struct_Processorcore, "Flags") ConsoleWrite('- : $ProcessorCore = ' & $ProcessorCore & @CRLF) ;### Debug Console $processorCoreCount += 1 $logicalProcessorCount += CountSetBits($ProcessorMask) Case $RelationNumaNode ConsoleWrite(" NumaNode" & @CRLF) $NodeNumber = DllStructGetData($struct_NumaNode, "NodeNumber") ConsoleWrite('- : $NodeNumber = ' & $NodeNumber & @CRLF) ;### Debug Console $numaNodeCount += 1 Case $RelationCache ConsoleWrite(" RelationCache" & @CRLF) $Level = DllStructGetData($struct_CACHE_DESCRIPTOR, "Level") ConsoleWrite('- : $Level = ' & $Level & @CRLF) ;### Debug Console $Associativity = DllStructGetData($struct_CACHE_DESCRIPTOR, "Associativity") ConsoleWrite('- : $Associativity = ' & $Associativity & @CRLF) ;### Debug Console $Linesize = DllStructGetData($struct_CACHE_DESCRIPTOR, "Linesize") ConsoleWrite('- : $Linesize = ' & $Linesize & @CRLF) ;### Debug Console $Size = DllStructGetData($struct_CACHE_DESCRIPTOR, "Size") ConsoleWrite('- : $Size = ' & $Size & @CRLF) ;### Debug Console $Type = DllStructGetData($struct_CACHE_DESCRIPTOR, "Type") ConsoleWrite('- : $Type = ' & $Type & @CRLF) ;### Debug Console Switch $Level Case 1 $L1CacheCount += 1 $L1CacheSize += $Size Case 2 $L2CacheCount += 1 $L2CacheSize += $Size Case 3 $L3CacheCount += 1 $L3CacheSize += $Size EndSwitch Case $RelationProcessorPackage ConsoleWrite(" ProcessorPackage" & @CRLF) $processorPackageCount += 1 Case $RelationGroup ConsoleWrite(" Group" & @CRLF) EndSwitch ConsoleWrite(@CRLF & @CRLF) Next $returnstring = "GetLogicalProcessorInformation: " & 32 * (1 + @AutoItX64) & "Bit" & @CRLF & @CRLF & _ StringFormat("Number %-30s = %u", "Processorcores", $processorCoreCount) & @CRLF & _ StringFormat("Number %-30s = %u", "NumaNodes", $numaNodeCount) & @CRLF & _ StringFormat("Number %-30s = %u", "logicalProcessorCount", $logicalProcessorCount) & @CRLF & _ StringFormat("Number %-30s = %u", "processorPackageCount", $processorPackageCount) & @CRLF & _ StringFormat("Number %-30s = %u/%u/%u", "Level1/2/3-Caches", $L1CacheCount, $L2CacheCount, $L3CacheCount) & @CRLF & _ StringFormat("Number %-30s = %u/%u/%u", "L1/L2/L3 cache sizes (kB)", $L1CacheSize / 1024, $L2CacheSize / 1024, $L3CacheSize / 1024) & @CRLF & _ "" ConsoleWrite($returnstring & @CRLF) MsgBox(0, "GetLogicalProcessorInformation", $returnstring) Func CountSetBits($uint) ;zählt gesetzte bits $anz = 0 For $i = 0 To 31 If BitAND(2 ^ $i, $uint) Then $anz += 1 Next Return $anz EndFunc ;==>CountSetBits Edited November 12, 2016 by AndyG
j0kky Posted November 12, 2016 Posted November 12, 2016 You have been extremely clear, my mistake was not to consider what DllStructGetData does to binary data (it multiplies by 2 the final lenght and adds 2 characters "0x" at the start) Thank you very much! Spoiler Some UDFs I created: Winsock UDF STUN UDF WinApi_GetAdaptersAddresses _WinApi_GetLogicalProcessorInformation Bitwise with 64 bit integers An useful collection of zipping file UDFs
j0kky Posted November 12, 2016 Posted November 12, 2016 (edited) @Andy G: On second thought I'm quite sure in first script it should be: For $i = 0 To $return_length - 24 Step 24 In fact, in my system, if you exclude 48 bytes instead of 24, you don't count a NumaNode! Edited November 12, 2016 by j0kky Spoiler Some UDFs I created: Winsock UDF STUN UDF WinApi_GetAdaptersAddresses _WinApi_GetLogicalProcessorInformation Bitwise with 64 bit integers An useful collection of zipping file UDFs
AndyG Posted November 12, 2016 Posted November 12, 2016 You are right, thank you very much! I´ll edit the scripts...
j0kky Posted November 12, 2016 Posted November 12, 2016 We helped each other Maybe next days I'll post my version of GetLogicalProcessorInformation wrapper, I don't know if GetProcAddress involvement is really necessary! Spoiler Some UDFs I created: Winsock UDF STUN UDF WinApi_GetAdaptersAddresses _WinApi_GetLogicalProcessorInformation Bitwise with 64 bit integers An useful collection of zipping file UDFs
AndyG Posted November 12, 2016 Posted November 12, 2016 (edited) 2 hours ago, j0kky said: I don't know if GetProcAddress involvement is really necessary! No, it´s not! "Stolen" from chesstiger´s not fully working try : $hDll = DllOpen("Kernel32.dll") $tBufferSize = DllStructCreate("dword size;") DllCall($hDll, "bool", "GetLogicalProcessorInformation", "struct*", 0, "DWORD_PTR", DllStructGetPtr($tBufferSize, "size")) $hMem = _MemGlobalAlloc($tBufferSize.size, $GPTR) ;Nötig, da sonst nach Verlassen der Funktion der Speicherbereich freigegeben wird... $tBuffer = DllStructCreate("byte[" & $tBufferSize.size & "]", $hMem) DllCall($hDll, "bool", "GetLogicalProcessorInformation", "struct*", DllStructGetPtr($tBuffer), "DWORD_PTR", DllStructGetPtr($tBufferSize, "size")) this and the use of something like an OO-Style (to get the content of the structs by their name like $buffer.item ) should lead to a good result. Have fun! Edited November 12, 2016 by AndyG
j0kky Posted November 21, 2016 Posted November 21, 2016 Here you are my version! Spoiler Some UDFs I created: Winsock UDF STUN UDF WinApi_GetAdaptersAddresses _WinApi_GetLogicalProcessorInformation Bitwise with 64 bit integers An useful collection of zipping file UDFs
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now