go-tg-screenshot-bot

Форк
0
437 строк · 19.4 Кб
1
// Copyright 2013 The win Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4

5
// +build windows
6

7
package win
8

9
import (
10
	"golang.org/x/sys/windows"
11
	"syscall"
12
	"unsafe"
13
)
14

15
// PDH error codes, which can be returned by all Pdh* functions. Taken from mingw-w64 pdhmsg.h
16
const (
17
	PDH_CSTATUS_VALID_DATA                     = 0x00000000 // The returned data is valid.
18
	PDH_CSTATUS_NEW_DATA                       = 0x00000001 // The return data value is valid and different from the last sample.
19
	PDH_CSTATUS_NO_MACHINE                     = 0x800007D0 // Unable to connect to the specified computer, or the computer is offline.
20
	PDH_CSTATUS_NO_INSTANCE                    = 0x800007D1
21
	PDH_MORE_DATA                              = 0x800007D2 // The PdhGetFormattedCounterArray* function can return this if there's 'more data to be displayed'.
22
	PDH_CSTATUS_ITEM_NOT_VALIDATED             = 0x800007D3
23
	PDH_RETRY                                  = 0x800007D4
24
	PDH_NO_DATA                                = 0x800007D5 // The query does not currently contain any counters (for example, limited access)
25
	PDH_CALC_NEGATIVE_DENOMINATOR              = 0x800007D6
26
	PDH_CALC_NEGATIVE_TIMEBASE                 = 0x800007D7
27
	PDH_CALC_NEGATIVE_VALUE                    = 0x800007D8
28
	PDH_DIALOG_CANCELLED                       = 0x800007D9
29
	PDH_END_OF_LOG_FILE                        = 0x800007DA
30
	PDH_ASYNC_QUERY_TIMEOUT                    = 0x800007DB
31
	PDH_CANNOT_SET_DEFAULT_REALTIME_DATASOURCE = 0x800007DC
32
	PDH_CSTATUS_NO_OBJECT                      = 0xC0000BB8
33
	PDH_CSTATUS_NO_COUNTER                     = 0xC0000BB9 // The specified counter could not be found.
34
	PDH_CSTATUS_INVALID_DATA                   = 0xC0000BBA // The counter was successfully found, but the data returned is not valid.
35
	PDH_MEMORY_ALLOCATION_FAILURE              = 0xC0000BBB
36
	PDH_INVALID_HANDLE                         = 0xC0000BBC
37
	PDH_INVALID_ARGUMENT                       = 0xC0000BBD // Required argument is missing or incorrect.
38
	PDH_FUNCTION_NOT_FOUND                     = 0xC0000BBE
39
	PDH_CSTATUS_NO_COUNTERNAME                 = 0xC0000BBF
40
	PDH_CSTATUS_BAD_COUNTERNAME                = 0xC0000BC0 // Unable to parse the counter path. Check the format and syntax of the specified path.
41
	PDH_INVALID_BUFFER                         = 0xC0000BC1
42
	PDH_INSUFFICIENT_BUFFER                    = 0xC0000BC2
43
	PDH_CANNOT_CONNECT_MACHINE                 = 0xC0000BC3
44
	PDH_INVALID_PATH                           = 0xC0000BC4
45
	PDH_INVALID_INSTANCE                       = 0xC0000BC5
46
	PDH_INVALID_DATA                           = 0xC0000BC6 // specified counter does not contain valid data or a successful status code.
47
	PDH_NO_DIALOG_DATA                         = 0xC0000BC7
48
	PDH_CANNOT_READ_NAME_STRINGS               = 0xC0000BC8
49
	PDH_LOG_FILE_CREATE_ERROR                  = 0xC0000BC9
50
	PDH_LOG_FILE_OPEN_ERROR                    = 0xC0000BCA
51
	PDH_LOG_TYPE_NOT_FOUND                     = 0xC0000BCB
52
	PDH_NO_MORE_DATA                           = 0xC0000BCC
53
	PDH_ENTRY_NOT_IN_LOG_FILE                  = 0xC0000BCD
54
	PDH_DATA_SOURCE_IS_LOG_FILE                = 0xC0000BCE
55
	PDH_DATA_SOURCE_IS_REAL_TIME               = 0xC0000BCF
56
	PDH_UNABLE_READ_LOG_HEADER                 = 0xC0000BD0
57
	PDH_FILE_NOT_FOUND                         = 0xC0000BD1
58
	PDH_FILE_ALREADY_EXISTS                    = 0xC0000BD2
59
	PDH_NOT_IMPLEMENTED                        = 0xC0000BD3
60
	PDH_STRING_NOT_FOUND                       = 0xC0000BD4
61
	PDH_UNABLE_MAP_NAME_FILES                  = 0x80000BD5
62
	PDH_UNKNOWN_LOG_FORMAT                     = 0xC0000BD6
63
	PDH_UNKNOWN_LOGSVC_COMMAND                 = 0xC0000BD7
64
	PDH_LOGSVC_QUERY_NOT_FOUND                 = 0xC0000BD8
65
	PDH_LOGSVC_NOT_OPENED                      = 0xC0000BD9
66
	PDH_WBEM_ERROR                             = 0xC0000BDA
67
	PDH_ACCESS_DENIED                          = 0xC0000BDB
68
	PDH_LOG_FILE_TOO_SMALL                     = 0xC0000BDC
69
	PDH_INVALID_DATASOURCE                     = 0xC0000BDD
70
	PDH_INVALID_SQLDB                          = 0xC0000BDE
71
	PDH_NO_COUNTERS                            = 0xC0000BDF
72
	PDH_SQL_ALLOC_FAILED                       = 0xC0000BE0
73
	PDH_SQL_ALLOCCON_FAILED                    = 0xC0000BE1
74
	PDH_SQL_EXEC_DIRECT_FAILED                 = 0xC0000BE2
75
	PDH_SQL_FETCH_FAILED                       = 0xC0000BE3
76
	PDH_SQL_ROWCOUNT_FAILED                    = 0xC0000BE4
77
	PDH_SQL_MORE_RESULTS_FAILED                = 0xC0000BE5
78
	PDH_SQL_CONNECT_FAILED                     = 0xC0000BE6
79
	PDH_SQL_BIND_FAILED                        = 0xC0000BE7
80
	PDH_CANNOT_CONNECT_WMI_SERVER              = 0xC0000BE8
81
	PDH_PLA_COLLECTION_ALREADY_RUNNING         = 0xC0000BE9
82
	PDH_PLA_ERROR_SCHEDULE_OVERLAP             = 0xC0000BEA
83
	PDH_PLA_COLLECTION_NOT_FOUND               = 0xC0000BEB
84
	PDH_PLA_ERROR_SCHEDULE_ELAPSED             = 0xC0000BEC
85
	PDH_PLA_ERROR_NOSTART                      = 0xC0000BED
86
	PDH_PLA_ERROR_ALREADY_EXISTS               = 0xC0000BEE
87
	PDH_PLA_ERROR_TYPE_MISMATCH                = 0xC0000BEF
88
	PDH_PLA_ERROR_FILEPATH                     = 0xC0000BF0
89
	PDH_PLA_SERVICE_ERROR                      = 0xC0000BF1
90
	PDH_PLA_VALIDATION_ERROR                   = 0xC0000BF2
91
	PDH_PLA_VALIDATION_WARNING                 = 0x80000BF3
92
	PDH_PLA_ERROR_NAME_TOO_LONG                = 0xC0000BF4
93
	PDH_INVALID_SQL_LOG_FORMAT                 = 0xC0000BF5
94
	PDH_COUNTER_ALREADY_IN_QUERY               = 0xC0000BF6
95
	PDH_BINARY_LOG_CORRUPT                     = 0xC0000BF7
96
	PDH_LOG_SAMPLE_TOO_SMALL                   = 0xC0000BF8
97
	PDH_OS_LATER_VERSION                       = 0xC0000BF9
98
	PDH_OS_EARLIER_VERSION                     = 0xC0000BFA
99
	PDH_INCORRECT_APPEND_TIME                  = 0xC0000BFB
100
	PDH_UNMATCHED_APPEND_COUNTER               = 0xC0000BFC
101
	PDH_SQL_ALTER_DETAIL_FAILED                = 0xC0000BFD
102
	PDH_QUERY_PERF_DATA_TIMEOUT                = 0xC0000BFE
103
)
104

105
// Formatting options for GetFormattedCounterValue().
106
const (
107
	PDH_FMT_RAW          = 0x00000010
108
	PDH_FMT_ANSI         = 0x00000020
109
	PDH_FMT_UNICODE      = 0x00000040
110
	PDH_FMT_LONG         = 0x00000100 // Return data as a long int.
111
	PDH_FMT_DOUBLE       = 0x00000200 // Return data as a double precision floating point real.
112
	PDH_FMT_LARGE        = 0x00000400 // Return data as a 64 bit integer.
113
	PDH_FMT_NOSCALE      = 0x00001000 // can be OR-ed: Do not apply the counter's default scaling factor.
114
	PDH_FMT_1000         = 0x00002000 // can be OR-ed: multiply the actual value by 1,000.
115
	PDH_FMT_NODATA       = 0x00004000 // can be OR-ed: unknown what this is for, MSDN says nothing.
116
	PDH_FMT_NOCAP100     = 0x00008000 // can be OR-ed: do not cap values > 100.
117
	PERF_DETAIL_COSTLY   = 0x00010000
118
	PERF_DETAIL_STANDARD = 0x0000FFFF
119
)
120

121
type (
122
	PDH_HQUERY   HANDLE // query handle
123
	PDH_HCOUNTER HANDLE // counter handle
124
)
125

126
// Union specialization for double values
127
type PDH_FMT_COUNTERVALUE_DOUBLE struct {
128
	CStatus     uint32
129
	DoubleValue float64
130
}
131

132
// Union specialization for 64 bit integer values
133
type PDH_FMT_COUNTERVALUE_LARGE struct {
134
	CStatus    uint32
135
	LargeValue int64
136
}
137

138
// Union specialization for long values
139
type PDH_FMT_COUNTERVALUE_LONG struct {
140
	CStatus   uint32
141
	LongValue int32
142
	padding   [4]byte
143
}
144

145
// Union specialization for double values, used by PdhGetFormattedCounterArrayDouble()
146
type PDH_FMT_COUNTERVALUE_ITEM_DOUBLE struct {
147
	SzName   *uint16 // pointer to a string
148
	FmtValue PDH_FMT_COUNTERVALUE_DOUBLE
149
}
150

151
// Union specialization for 'large' values, used by PdhGetFormattedCounterArrayLarge()
152
type PDH_FMT_COUNTERVALUE_ITEM_LARGE struct {
153
	SzName   *uint16 // pointer to a string
154
	FmtValue PDH_FMT_COUNTERVALUE_LARGE
155
}
156

157
// Union specialization for long values, used by PdhGetFormattedCounterArrayLong()
158
type PDH_FMT_COUNTERVALUE_ITEM_LONG struct {
159
	SzName   *uint16 // pointer to a string
160
	FmtValue PDH_FMT_COUNTERVALUE_LONG
161
}
162

163
var (
164
	// Library
165
	libpdhDll *windows.LazyDLL
166

167
	// Functions
168
	pdh_AddCounterW               *windows.LazyProc
169
	pdh_AddEnglishCounterW        *windows.LazyProc
170
	pdh_CloseQuery                *windows.LazyProc
171
	pdh_CollectQueryData          *windows.LazyProc
172
	pdh_GetFormattedCounterValue  *windows.LazyProc
173
	pdh_GetFormattedCounterArrayW *windows.LazyProc
174
	pdh_OpenQuery                 *windows.LazyProc
175
	pdh_ValidatePathW             *windows.LazyProc
176
)
177

178
func init() {
179
	// Library
180
	libpdhDll = windows.NewLazySystemDLL("pdh.dll")
181

182
	// Functions
183
	pdh_AddCounterW = libpdhDll.NewProc("PdhAddCounterW")
184
	pdh_AddEnglishCounterW = libpdhDll.NewProc("PdhAddEnglishCounterW")
185
	pdh_CloseQuery = libpdhDll.NewProc("PdhCloseQuery")
186
	pdh_CollectQueryData = libpdhDll.NewProc("PdhCollectQueryData")
187
	pdh_GetFormattedCounterValue = libpdhDll.NewProc("PdhGetFormattedCounterValue")
188
	pdh_GetFormattedCounterArrayW = libpdhDll.NewProc("PdhGetFormattedCounterArrayW")
189
	pdh_OpenQuery = libpdhDll.NewProc("PdhOpenQuery")
190
	pdh_ValidatePathW = libpdhDll.NewProc("PdhValidatePathW")
191
}
192

193
// Adds the specified counter to the query. This is the internationalized version. Preferably, use the
194
// function PdhAddEnglishCounter instead. hQuery is the query handle, which has been fetched by PdhOpenQuery.
195
// szFullCounterPath is a full, internationalized counter path (this will differ per Windows language version).
196
// dwUserData is a 'user-defined value', which becomes part of the counter information. To retrieve this value
197
// later, call PdhGetCounterInfo() and access dwQueryUserData of the PDH_COUNTER_INFO structure.
198
//
199
// Examples of szFullCounterPath (in an English version of Windows):
200
//
201
//	\\Processor(_Total)\\% Idle Time
202
//	\\Processor(_Total)\\% Processor Time
203
//	\\LogicalDisk(C:)\% Free Space
204
//
205
// To view all (internationalized...) counters on a system, there are three non-programmatic ways: perfmon utility,
206
// the typeperf command, and the the registry editor. perfmon.exe is perhaps the easiest way, because it's basically a
207
// full implemention of the pdh.dll API, except with a GUI and all that. The registry setting also provides an
208
// interface to the available counters, and can be found at the following key:
209
//
210
// 	HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\CurrentLanguage
211
//
212
// This registry key contains several values as follows:
213
//
214
//	1
215
//	1847
216
//	2
217
//	System
218
//	4
219
//	Memory
220
//	6
221
//	% Processor Time
222
//	... many, many more
223
//
224
// Somehow, these numeric values can be used as szFullCounterPath too:
225
//
226
//	\2\6 will correspond to \\System\% Processor Time
227
//
228
// The typeperf command may also be pretty easy. To find all performance counters, simply execute:
229
//
230
//	typeperf -qx
231
func PdhAddCounter(hQuery PDH_HQUERY, szFullCounterPath string, dwUserData uintptr, phCounter *PDH_HCOUNTER) uint32 {
232
	ptxt, _ := syscall.UTF16PtrFromString(szFullCounterPath)
233
	ret, _, _ := pdh_AddCounterW.Call(
234
		uintptr(hQuery),
235
		uintptr(unsafe.Pointer(ptxt)),
236
		dwUserData,
237
		uintptr(unsafe.Pointer(phCounter)))
238

239
	return uint32(ret)
240
}
241

242
// Adds the specified language-neutral counter to the query. See the PdhAddCounter function. This function only exists on
243
// Windows versions higher than Vista.
244
func PdhAddEnglishCounter(hQuery PDH_HQUERY, szFullCounterPath string, dwUserData uintptr, phCounter *PDH_HCOUNTER) uint32 {
245
	if pdh_AddEnglishCounterW.Find() != nil {
246
		return ERROR_INVALID_FUNCTION
247
	}
248

249
	ptxt, _ := syscall.UTF16PtrFromString(szFullCounterPath)
250
	ret, _, _ := pdh_AddEnglishCounterW.Call(
251
		uintptr(hQuery),
252
		uintptr(unsafe.Pointer(ptxt)),
253
		dwUserData,
254
		uintptr(unsafe.Pointer(phCounter)))
255

256
	return uint32(ret)
257
}
258

259
// Closes all counters contained in the specified query, closes all handles related to the query,
260
// and frees all memory associated with the query.
261
func PdhCloseQuery(hQuery PDH_HQUERY) uint32 {
262
	ret, _, _ := pdh_CloseQuery.Call(uintptr(hQuery))
263

264
	return uint32(ret)
265
}
266

267
// Collects the current raw data value for all counters in the specified query and updates the status
268
// code of each counter. With some counters, this function needs to be repeatedly called before the value
269
// of the counter can be extracted with PdhGetFormattedCounterValue(). For example, the following code
270
// requires at least two calls:
271
//
272
// 	var handle win.PDH_HQUERY
273
// 	var counterHandle win.PDH_HCOUNTER
274
// 	ret := win.PdhOpenQuery(0, 0, &handle)
275
//	ret = win.PdhAddEnglishCounter(handle, "\\Processor(_Total)\\% Idle Time", 0, &counterHandle)
276
//	var derp win.PDH_FMT_COUNTERVALUE_DOUBLE
277
//
278
//	ret = win.PdhCollectQueryData(handle)
279
//	fmt.Printf("Collect return code is %x\n", ret) // return code will be PDH_CSTATUS_INVALID_DATA
280
//	ret = win.PdhGetFormattedCounterValueDouble(counterHandle, 0, &derp)
281
//
282
//	ret = win.PdhCollectQueryData(handle)
283
//	fmt.Printf("Collect return code is %x\n", ret) // return code will be ERROR_SUCCESS
284
//	ret = win.PdhGetFormattedCounterValueDouble(counterHandle, 0, &derp)
285
//
286
// The PdhCollectQueryData will return an error in the first call because it needs two values for
287
// displaying the correct data for the processor idle time. The second call will have a 0 return code.
288
func PdhCollectQueryData(hQuery PDH_HQUERY) uint32 {
289
	ret, _, _ := pdh_CollectQueryData.Call(uintptr(hQuery))
290

291
	return uint32(ret)
292
}
293

294
// Formats the given hCounter using a 'double'. The result is set into the specialized union struct pValue.
295
// This function does not directly translate to a Windows counterpart due to union specialization tricks.
296
func PdhGetFormattedCounterValueDouble(hCounter PDH_HCOUNTER, lpdwType *uint32, pValue *PDH_FMT_COUNTERVALUE_DOUBLE) uint32 {
297
	ret, _, _ := pdh_GetFormattedCounterValue.Call(
298
		uintptr(hCounter),
299
		uintptr(PDH_FMT_DOUBLE),
300
		uintptr(unsafe.Pointer(lpdwType)),
301
		uintptr(unsafe.Pointer(pValue)))
302

303
	return uint32(ret)
304
}
305

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

315
	return uint32(ret)
316
}
317

318
// Formats the given hCounter using a 'long'. The result is set into the specialized union struct pValue.
319
// This function does not directly translate to a Windows counterpart due to union specialization tricks.
320
//
321
// BUG(krpors): Testing this function on multiple systems yielded inconsistent results. For instance,
322
// the pValue.LongValue kept the value '192' on test system A, but on B this was '0', while the padding
323
// bytes of the struct got the correct value. Until someone can figure out this behaviour, prefer to use
324
// the Double or Large counterparts instead. These functions provide actually the same data, except in
325
// a different, working format.
326
func PdhGetFormattedCounterValueLong(hCounter PDH_HCOUNTER, lpdwType *uint32, pValue *PDH_FMT_COUNTERVALUE_LONG) uint32 {
327
	ret, _, _ := pdh_GetFormattedCounterValue.Call(
328
		uintptr(hCounter),
329
		uintptr(PDH_FMT_LONG),
330
		uintptr(unsafe.Pointer(lpdwType)),
331
		uintptr(unsafe.Pointer(pValue)))
332

333
	return uint32(ret)
334
}
335

336
// Returns an array of formatted counter values. Use this function when you want to format the counter values of a
337
// counter that contains a wildcard character for the instance name. The itemBuffer must a slice of type PDH_FMT_COUNTERVALUE_ITEM_DOUBLE.
338
// An example of how this function can be used:
339
//
340
//	okPath := "\\Process(*)\\% Processor Time" // notice the wildcard * character
341
//
342
//	// ommitted all necessary stuff ...
343
//
344
//	var bufSize uint32
345
//	var bufCount uint32
346
//	var size uint32 = uint32(unsafe.Sizeof(win.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE{}))
347
//	var emptyBuf [1]win.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE // need at least 1 addressable null ptr.
348
//
349
//	for {
350
//		// collect
351
//		ret := win.PdhCollectQueryData(queryHandle)
352
//		if ret == win.ERROR_SUCCESS {
353
//			ret = win.PdhGetFormattedCounterArrayDouble(counterHandle, &bufSize, &bufCount, &emptyBuf[0]) // uses null ptr here according to MSDN.
354
//			if ret == win.PDH_MORE_DATA {
355
//				filledBuf := make([]win.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE, bufCount*size)
356
//				ret = win.PdhGetFormattedCounterArrayDouble(counterHandle, &bufSize, &bufCount, &filledBuf[0])
357
//				for i := 0; i < int(bufCount); i++ {
358
//					c := filledBuf[i]
359
//					var s string = win.UTF16PtrToString(c.SzName)
360
//					fmt.Printf("Index %d -> %s, value %v\n", i, s, c.FmtValue.DoubleValue)
361
//				}
362
//
363
//				filledBuf = nil
364
//				// Need to at least set bufSize to zero, because if not, the function will not
365
//				// return PDH_MORE_DATA and will not set the bufSize.
366
//				bufCount = 0
367
//				bufSize = 0
368
//			}
369
//
370
//			time.Sleep(2000 * time.Millisecond)
371
//		}
372
//	}
373
func PdhGetFormattedCounterArrayDouble(hCounter PDH_HCOUNTER, lpdwBufferSize *uint32, lpdwBufferCount *uint32, itemBuffer *PDH_FMT_COUNTERVALUE_ITEM_DOUBLE) uint32 {
374
	ret, _, _ := pdh_GetFormattedCounterArrayW.Call(
375
		uintptr(hCounter),
376
		uintptr(PDH_FMT_DOUBLE),
377
		uintptr(unsafe.Pointer(lpdwBufferSize)),
378
		uintptr(unsafe.Pointer(lpdwBufferCount)),
379
		uintptr(unsafe.Pointer(itemBuffer)))
380

381
	return uint32(ret)
382
}
383

384
// Returns an array of formatted counter values. Use this function when you want to format the counter values of a
385
// counter that contains a wildcard character for the instance name. The itemBuffer must a slice of type PDH_FMT_COUNTERVALUE_ITEM_LARGE.
386
// For an example usage, see PdhGetFormattedCounterArrayDouble.
387
func PdhGetFormattedCounterArrayLarge(hCounter PDH_HCOUNTER, lpdwBufferSize *uint32, lpdwBufferCount *uint32, itemBuffer *PDH_FMT_COUNTERVALUE_ITEM_LARGE) uint32 {
388
	ret, _, _ := pdh_GetFormattedCounterArrayW.Call(
389
		uintptr(hCounter),
390
		uintptr(PDH_FMT_LARGE),
391
		uintptr(unsafe.Pointer(lpdwBufferSize)),
392
		uintptr(unsafe.Pointer(lpdwBufferCount)),
393
		uintptr(unsafe.Pointer(itemBuffer)))
394

395
	return uint32(ret)
396
}
397

398
// Returns an array of formatted counter values. Use this function when you want to format the counter values of a
399
// counter that contains a wildcard character for the instance name. The itemBuffer must a slice of type PDH_FMT_COUNTERVALUE_ITEM_LONG.
400
// For an example usage, see PdhGetFormattedCounterArrayDouble.
401
//
402
// BUG(krpors): See description of PdhGetFormattedCounterValueLong().
403
func PdhGetFormattedCounterArrayLong(hCounter PDH_HCOUNTER, lpdwBufferSize *uint32, lpdwBufferCount *uint32, itemBuffer *PDH_FMT_COUNTERVALUE_ITEM_LONG) uint32 {
404
	ret, _, _ := pdh_GetFormattedCounterArrayW.Call(
405
		uintptr(hCounter),
406
		uintptr(PDH_FMT_LONG),
407
		uintptr(unsafe.Pointer(lpdwBufferSize)),
408
		uintptr(unsafe.Pointer(lpdwBufferCount)),
409
		uintptr(unsafe.Pointer(itemBuffer)))
410

411
	return uint32(ret)
412
}
413

414
// Creates a new query that is used to manage the collection of performance data.
415
// szDataSource is a null terminated string that specifies the name of the log file from which to
416
// retrieve the performance data. If 0, performance data is collected from a real-time data source.
417
// dwUserData is a user-defined value to associate with this query. To retrieve the user data later,
418
// call PdhGetCounterInfo and access dwQueryUserData of the PDH_COUNTER_INFO structure. phQuery is
419
// the handle to the query, and must be used in subsequent calls. This function returns a PDH_
420
// constant error code, or ERROR_SUCCESS if the call succeeded.
421
func PdhOpenQuery(szDataSource uintptr, dwUserData uintptr, phQuery *PDH_HQUERY) uint32 {
422
	ret, _, _ := pdh_OpenQuery.Call(
423
		szDataSource,
424
		dwUserData,
425
		uintptr(unsafe.Pointer(phQuery)))
426

427
	return uint32(ret)
428
}
429

430
// Validates a path. Will return ERROR_SUCCESS when ok, or PDH_CSTATUS_BAD_COUNTERNAME when the path is
431
// erroneous.
432
func PdhValidatePath(path string) uint32 {
433
	ptxt, _ := syscall.UTF16PtrFromString(path)
434
	ret, _, _ := pdh_ValidatePathW.Call(uintptr(unsafe.Pointer(ptxt)))
435

436
	return uint32(ret)
437
}
438

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.