//go:build windows
// +build windows
/*
** Copyright (C) 2001-2025 Zabbix SIA
**
** This program is free software: you can redistribute it and/or modify it under the terms of
** the GNU Affero General Public License as published by the Free Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
** without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
** See the GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License along with this program.
** If not, see <https://www.gnu.org/licenses/>.
**/
package win32
import (
"errors"
"fmt"
"sync"
"syscall"
"time"
"unsafe"
"golang.org/x/sys/windows"
"golang.zabbix.com/sdk/log"
)
const (
PDH_CSTATUS_VALID_DATA = 0x00000000
PDH_CSTATUS_NEW_DATA = 0x00000001
PDH_CSTATUS_INVALID_DATA = 0xC0000BBA
PDH_MORE_DATA = 0x800007D2
PDH_NO_DATA = 0x800007D5
PDH_INVALID_DATA = 0xc0000bc6
PDH_CALC_NEGATIVE_DENOMINATOR = 0x800007D6
PDH_FMT_DOUBLE = 0x00000200
PDH_FMT_LARGE = 0x00000400
PDH_FMT_NOCAP100 = 0x00008000
PDH_MAX_COUNTER_NAME = 1024
PERF_DETAIL_WIZARD = 400
objectListSizeInit = 16384
)
var (
NegDenomErr = newPdhError(PDH_CALC_NEGATIVE_DENOMINATOR)
hPdh = mustLoadLibrary("pdh.dll")
pdhOpenQuery = hPdh.mustGetProcAddress("PdhOpenQuery")
pdhCloseQuery = hPdh.mustGetProcAddress("PdhCloseQuery")
pdhAddCounter = hPdh.mustGetProcAddress("PdhAddCounterW")
pdhAddEnglishCounter = hPdh.mustGetProcAddress("PdhAddEnglishCounterW")
pdhCollectQueryData = hPdh.mustGetProcAddress("PdhCollectQueryData")
pdhGetFormattedCounterValue = hPdh.mustGetProcAddress("PdhGetFormattedCounterValue")
pdhParseCounterPath = hPdh.mustGetProcAddress("PdhParseCounterPathW")
pdhMakeCounterPath = hPdh.mustGetProcAddress("PdhMakeCounterPathW")
pdhLookupPerfNameByIndex = hPdh.mustGetProcAddress("PdhLookupPerfNameByIndexW")
pdhLookupPerfIndexByName = hPdh.mustGetProcAddress("PdhLookupPerfIndexByNameW")
pdhRemoveCounter = hPdh.mustGetProcAddress("PdhRemoveCounter")
pdhEnumObjectItems = hPdh.mustGetProcAddress("PdhEnumObjectItemsW")
pdhEnumObjects = hPdh.mustGetProcAddress("PdhEnumObjectsW")
objectListSize uint32 = objectListSizeInit
// mutex to prevent concurrent calls of Windows API PDH functions when one of the following is already being executed
// pdhEnumObjectItems(), pdhEnumObjects() and pdhCollectQueryData()
pdhMu sync.RWMutex
)
type Instance struct {
Name string `json:"{#INSTANCE}"`
}
func PdhOpenQuery(dataSource *string, userData uintptr) (query PDH_HQUERY, err error) {
var source uintptr
if dataSource != nil {
wcharSource := windows.StringToUTF16(*dataSource)
source = uintptr(unsafe.Pointer(&wcharSource[0]))
}
pdhMu.RLock()
defer pdhMu.RUnlock()
ret, _, _ := syscall.Syscall(pdhOpenQuery, 3, source, userData, uintptr(unsafe.Pointer(&query)))