Working on a project to get the current CPU load.
I'm having difficulty accessing the longvalue in this struct: (sizeof is 16 bytes)
PDH_FMT_COUNTERVALUE STRUCT 8
CStatus DWORD ?
UNION
longValue DWORD ?
doubleValue QWORD ?
largeValue QWORD ?
pAnsiStringValue QWORD ?
pWideStringValue QWORD ?
ENDS
PDH_FMT_COUNTERVALUE ENDS
Initially, I tried using this MASM code but the CPU usage was always 0.
(I think it was looking at the member padding after the first 4 bytes for CStatus)
LOCAL value:PDH_FMT_COUNTERVALUE
...
LEA R9,value
MOV EAX,DWORD PTR [R9 PDH_FMT_COUNTERVALUE.longValue]
MOV cput,RAX
However, by adding 4, it correctly finds the longvalue:
LOCAL value:PDH_FMT_COUNTERVALUE
...
LEA R9,value
MOV EAX,DWORD PTR [R9 PDH_FMT_COUNTERVALUE.longValue 4] ;; <-- 4 added here
MOV cput,RAX
Notice the following offset resolves to 8 overall
PDH_FMT_COUNTERVALUE.longValue 4 ;; dword ptr [r9 8]
For comparison, the MSVC compiler generates the correct 8 offset:
(It dereferences a byte, even though it's defined as a DWORD)
cput = value.longValue;
movzx eax,byte ptr [value 8h]
mov byte ptr [cput],al
Question
This code looks hackish [R9 PDH_FMT_COUNTERVALUE.longValue 4], so is there a more legit method to refer to the longvalue member directly in MASM?
EDIT
Possible solution, manually padding the struct allows access to the longValue.
PDH_FMT_COUNTERVALUE STRUCT 8
CStatus DWORD ?
padding BYTE 4 DUP (?)
UNION
longValue DWORD ?
doubleValue QWORD ?
largeValue QWORD ?
pAnsiStringValue QWORD ?
pWideStringValue QWORD ?
ENDS
PDH_FMT_COUNTERVALUE ENDS
CodePudding user response:
Unfortunately I'm not aware of a cleaner solution than this, but this should work:
COUNTERVALUE UNION
longValue DWORD ?
doubleValue QWORD ?
largeValue QWORD ?
pAnsiStringValue QWORD ?
pWideStringValue QWORD ?
COUNTERVALUE ENDS
PDH_FMT_COUNTERVALUE STRUCT 8
CStatus DWORD ?
COUNTERVALUE <>
PDH_FMT_COUNTERVALUE ENDS