lxn / win

A Windows API wrapper package for the Go Programming Language
Other
1.21k stars 315 forks source link

How to add PdhParseCounterPath function #52

Closed jwenz723 closed 6 years ago

jwenz723 commented 6 years ago

I am trying to add the PdhParseCounterPath function (as documented here https://msdn.microsoft.com/en-us/library/windows/desktop/aa372657(v=vs.85).aspx ) into pdh.go, but I am a bit unsure of how to do so. Wondering if any of the contributors could offer a little help? Here is what I've added:


type PDH_COUNTER_PATH_ELEMENTS struct {
    szMachineName string
    szObjectName string
    szInstanceName string
    szParentInstance string
    dwInstanceIndex uintptr
    szCounterName string
}

var (
    // Library
    libpdhDll *syscall.DLL

    // Functions
    pdh_AddCounterW               *syscall.Proc
    pdh_AddEnglishCounterW        *syscall.Proc
    pdh_CloseQuery                *syscall.Proc
    pdh_CollectQueryData          *syscall.Proc
    pdh_GetFormattedCounterValue  *syscall.Proc
    pdh_GetFormattedCounterArrayW *syscall.Proc
    pdh_OpenQuery                 *syscall.Proc
    pdh_ValidatePathW             *syscall.Proc
    pdh_ParseCounterPathW         *syscall.Proc  // added this
)

func init() {
    // Library
    libpdhDll = syscall.MustLoadDLL("pdh.dll")

    // Functions
    pdh_AddCounterW = libpdhDll.MustFindProc("PdhAddCounterW")
    pdh_AddEnglishCounterW, _ = libpdhDll.FindProc("PdhAddEnglishCounterW") // XXX: only supported on versions > Vista.
    pdh_CloseQuery = libpdhDll.MustFindProc("PdhCloseQuery")
    pdh_CollectQueryData = libpdhDll.MustFindProc("PdhCollectQueryData")
    pdh_GetFormattedCounterValue = libpdhDll.MustFindProc("PdhGetFormattedCounterValue")
    pdh_GetFormattedCounterArrayW = libpdhDll.MustFindProc("PdhGetFormattedCounterArrayW")
    pdh_OpenQuery = libpdhDll.MustFindProc("PdhOpenQuery")
    pdh_ValidatePathW = libpdhDll.MustFindProc("PdhValidatePathW")
    pdh_ParseCounterPathW = libpdhDll.MustFindProc("PdhParseCounterPathW") // added this
}

func PdhParseCounterPath(szFullPathBuffer string, pCounterPathElements *PDH_COUNTER_PATH_ELEMENTS) uint32 {
    ptxt, _ := syscall.UTF16PtrFromString(szFullPathBuffer)

    var test uint32

    ret, _, _ := pdh_ParseCounterPathW.Call(
        uintptr(unsafe.Pointer(ptxt)), // I think this is correct
        uintptr(unsafe.Pointer(pCounterPathElements)), // not sure what to do here
        uintptr(unsafe.Pointer(&test)), // not sure what to do here
        0) // I think this is correct

    return uint32(ret)
}
jwenz723 commented 6 years ago

Also, when I run it in this current condition I get the error code: PDH_INVALID_ARGUMENT, so I assume something is incorrect with the arguments I am passing into the function call.

jwenz723 commented 6 years ago

Figured it out finally after many hours of trial and error...

func PdhParseCounterPath(szFullPathBuffer string, pCounterPathElements *PDH_COUNTER_PATH_ELEMENTS, pdwBufferSize *uint32) uint32 {
    ptxt, _ := syscall.UTF16PtrFromString(szFullPathBuffer)

    ret, _, _ := pdh_ParseCounterPathW.Call(
        uintptr(unsafe.Pointer(ptxt)),
        uintptr(unsafe.Pointer(pCounterPathElements)),
        uintptr(unsafe.Pointer(pdwBufferSize)),
        0)

    return uint32(ret)
}