Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix PDH functions to use actual C structs #14

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 42 additions & 7 deletions pdh.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,30 @@

package win

/*
#include <pdh.h>

// Union specialization for double values
typedef struct _PDH_FMT_COUNTERVALUE_DOUBLE {
DWORD CStatus;
double doubleValue;
} PDH_FMT_COUNTERVALUE_DOUBLE;

// Union specialization for 64 bit integer values
typedef struct _PDH_FMT_COUNTERVALUE_LARGE {
DWORD CStatus;
LONGLONG largeValue;
} PDH_FMT_COUNTERVALUE_LARGE;

// Union specialization for long values
typedef struct _PDH_FMT_COUNTERVALUE_LONG {
DWORD CStatus;
BYTE padding[4];
LONG longValue;
} PDH_FMT_COUNTERVALUE_LONG;
*/
import "C"

import (
"syscall"
"unsafe"
Expand Down Expand Up @@ -120,23 +144,22 @@ type (
PDH_HCOUNTER HANDLE // counter handle
)

// Union specialization for double values
// Go struct for double values
type PDH_FMT_COUNTERVALUE_DOUBLE struct {
CStatus uint32
DoubleValue float64
}

// Union specialization for 64 bit integer values
// Go struct for 64 bit integer values
type PDH_FMT_COUNTERVALUE_LARGE struct {
CStatus uint32
LargeValue int64
}

// Union specialization for long values
// Go struct for long values
type PDH_FMT_COUNTERVALUE_LONG struct {
CStatus uint32
LongValue int32
padding [4]byte
}

// Union specialization for double values, used by PdhGetFormattedCounterArrayDouble()
Expand Down Expand Up @@ -291,23 +314,31 @@ func PdhCollectQueryData(hQuery PDH_HQUERY) uint32 {
// Formats the given hCounter using a 'double'. The result is set into the specialized union struct pValue.
// This function does not directly translate to a Windows counterpart due to union specialization tricks.
func PdhGetFormattedCounterValueDouble(hCounter PDH_HCOUNTER, lpdwType *uint32, pValue *PDH_FMT_COUNTERVALUE_DOUBLE) uint32 {
var value C.PDH_FMT_COUNTERVALUE_DOUBLE
ret, _, _ := pdh_GetFormattedCounterValue.Call(
uintptr(hCounter),
uintptr(PDH_FMT_DOUBLE),
uintptr(unsafe.Pointer(lpdwType)),
uintptr(unsafe.Pointer(pValue)))
uintptr(unsafe.Pointer(&value)))

pValue.CStatus = uint32(value.CStatus)
pValue.DoubleValue = float64(value.doubleValue)

return uint32(ret)
}

// Formats the given hCounter using a large int (int64). The result is set into the specialized union struct pValue.
// This function does not directly translate to a Windows counterpart due to union specialization tricks.
func PdhGetFormattedCounterValueLarge(hCounter PDH_HCOUNTER, lpdwType *uint32, pValue *PDH_FMT_COUNTERVALUE_LARGE) uint32 {
var value C.PDH_FMT_COUNTERVALUE_LARGE
ret, _, _ := pdh_GetFormattedCounterValue.Call(
uintptr(hCounter),
uintptr(PDH_FMT_LARGE),
uintptr(unsafe.Pointer(lpdwType)),
uintptr(unsafe.Pointer(pValue)))
uintptr(unsafe.Pointer(&value)))

pValue.CStatus = uint32(value.CStatus)
pValue.LargeValue = int64(value.largeValue)

return uint32(ret)
}
Expand All @@ -321,11 +352,15 @@ func PdhGetFormattedCounterValueLarge(hCounter PDH_HCOUNTER, lpdwType *uint32, p
// the Double or Large counterparts instead. These functions provide actually the same data, except in
// a different, working format.
func PdhGetFormattedCounterValueLong(hCounter PDH_HCOUNTER, lpdwType *uint32, pValue *PDH_FMT_COUNTERVALUE_LONG) uint32 {
var value C.PDH_FMT_COUNTERVALUE_LONG
ret, _, _ := pdh_GetFormattedCounterValue.Call(
uintptr(hCounter),
uintptr(PDH_FMT_LONG),
uintptr(unsafe.Pointer(lpdwType)),
uintptr(unsafe.Pointer(pValue)))
uintptr(unsafe.Pointer(&value)))

pValue.CStatus = uint32(value.CStatus)
pValue.LongValue = int32(value.longValue)

return uint32(ret)
}
Expand Down