1 /* Copyright (c) 2015 Goldstein Lyor, All Rights Reserved
2  *
3  * The contents of this file is dual-licensed under 2
4  * alternative Open Source/Free licenses: LGPL 2.1 or later and
5  * Apache License 2.0. (starting with JNA version 4.0.0).
6  *
7  * You can freely decide which license you want to apply to
8  * the project.
9  *
10  * You may obtain a copy of the LGPL License at:
11  *
12  * http://www.gnu.org/licenses/licenses.html
13  *
14  * A copy is also included in the downloadable source code package
15  * containing JNA, in file "LGPL2.1".
16  *
17  * You may obtain a copy of the Apache License at:
18  *
19  * http://www.apache.org/licenses/
20  *
21  * A copy is also included in the downloadable source code package
22  * containing JNA, in file "AL2.0".
23  */
24 package com.sun.jna.platform.win32;
25 
26 import com.sun.jna.Native;
27 import com.sun.jna.Pointer;
28 import com.sun.jna.Structure;
29 import com.sun.jna.Structure.FieldOrder;
30 import com.sun.jna.platform.win32.BaseTSD.DWORD_PTR;
31 import com.sun.jna.platform.win32.WinBase.FILETIME;
32 import com.sun.jna.platform.win32.WinDef.DWORDByReference;
33 import com.sun.jna.platform.win32.WinDef.LONGLONGByReference;
34 import com.sun.jna.platform.win32.WinNT.HANDLE;
35 import com.sun.jna.platform.win32.WinNT.HANDLEByReference;
36 import com.sun.jna.win32.StdCallLibrary;
37 import com.sun.jna.win32.W32APIOptions;
38 
39 /**
40  * Windows Performance Data Helper (a.k.a. PDH).
41  * @author Lyor Goldstein
42  * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa373083(v=vs.85).aspx">Performance Counters</A>
43  */
44 public interface Pdh extends StdCallLibrary {
45     Pdh INSTANCE = Native.load("Pdh", Pdh.class, W32APIOptions.DEFAULT_OPTIONS);
46 
47     /** Maximum counter name length. */
48     int PDH_MAX_COUNTER_NAME = 1024;
49     /** Maximum counter instance name length. */
50     int PDH_MAX_INSTANCE_NAME = 1024;
51     /** Maximum full counter path length. */
52     int PDH_MAX_COUNTER_PATH = 2048;
53     /** Maximum full counter log name length. */
54     int PDH_MAX_DATASOURCE_PATH = 1024;
55 
56     int PDH_MORE_DATA = 0x800007D2;
57     int PDH_INSUFFICIENT_BUFFER = 0xC0000BC2;
58     int PDH_INVALID_ARGUMENT =  0xC0000BBD;
59     int PDH_MEMORY_ALLOCATION_FAILURE = 0xC0000BBB;
60     int PDH_CSTATUS_NO_MACHINE = 0x800007D0;
61     int PDH_CSTATUS_NO_OBJECT = 0xC0000BB8;
62 
63     /* TODO
64      * LPVOID CALLBACK AllocateMemory(_In_ SIZE_T AllocSize,_In_ LPVOID pContext)
65      * void CALLBACK FreeMemory(LPVOID pBuffer,LPVOID pContext)
66      */
67 
68     /**
69      * Connects to the specified computer.
70      * @param szMachineName The name of the computer to connect to. If
71      * {@code null}, PDH connects to the local computer.
72      * @return ERROR_SUCCESS if successful
73      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa372578(v=vs.85).aspx">PdhConnectMachine</A>
74      */
PdhConnectMachine(String szMachineName)75     int PdhConnectMachine(String szMachineName);
76 
77     // Known values for the PdhGetDllVersion result
78     int PDH_CVERSION_WIN40 = 0x0400;
79     int PDH_CVERSION_WIN50 = 0x0500;
80     // v1.1 revision of PDH -- basic log functions
81     // v1.2 of the PDH -- adds variable instance counters
82     // v1.3 of the PDH -- adds log service control & stubs for NT5/PDH v2 fn's
83     // v2.0 of the PDH -- is the NT v 5.0 B2 version
84     int PDH_VERSION = PDH_CVERSION_WIN50 + 0x0003;
85 
86     /**
87      * Returns the version of the currently installed Pdh.dll file.
88      * @param lpdwVersion A variable that receives the version of Pdh.dll.
89      * @return ERROR_SUCCESS if successful
90      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa372630(v=vs.85).aspx">PdhGetDllVersion</A>
91      */
PdhGetDllVersion(DWORDByReference lpdwVersion)92     int PdhGetDllVersion(DWORDByReference lpdwVersion);
93 
94     /**
95      * Creates a new query that is used to manage the collection of performance data.
96      * @param szDataSource The name of the log file from which to retrieve performance data.
97      * If {@code null}, performance data is collected from a real-time data source.
98      * @param dwUserData User-defined value to associate with this query.
99      * @param phQuery (Out) Handle to the query. You use this handle in subsequent calls.
100      * @return ERROR_SUCCESS if successful
101      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa372652(v=vs.85).aspx">PdhOpenQuery</A>
102      */
PdhOpenQuery(String szDataSource, DWORD_PTR dwUserData, HANDLEByReference phQuery)103     int PdhOpenQuery(String szDataSource, DWORD_PTR dwUserData, HANDLEByReference phQuery);
104 
105     /**
106      * Closes all counters contained in the specified query, closes all
107      * handles related to the query, and frees all memory associated with
108      * the query.
109      * @param hQuery Handle to the query to close.
110      * @return ERROR_SUCCESS if successful
111      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa372558(v=vs.85).aspx">PdhCloseQuery</A>
112      */
PdhCloseQuery(HANDLE hQuery)113     int PdhCloseQuery(HANDLE hQuery);
114 
115     /**
116      * Components of a counter path
117      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa373041(v=vs.85).aspx">PDH_COUNTER_PATH_ELEMENTS</A>
118      * @see <A HREF="https://technet.microsoft.com/en-us/library/cc776490(v=ws.10).aspx">Windows Server 2003 Performance Counters Reference</A>
119      */
120     @FieldOrder({"szMachineName", "szObjectName", "szInstanceName",
121                 "szParentInstance", "dwInstanceIndex", "szCounterName"})
122     public class PDH_COUNTER_PATH_ELEMENTS extends Structure {
123         public String szMachineName;
124         public String szObjectName;
125         public String szInstanceName;
126         public String szParentInstance;
127         public int  dwInstanceIndex;
128         public String szCounterName;
129     }
130 
131     // flags for the PdhMakeCounterPath
132     int PDH_PATH_WBEM_RESULT = 0x00000001;
133     int PDH_PATH_WBEM_INPUT  = 0x00000002;
134 
135     /**
136      * Creates a full counter path using the members specified in the
137      * {@link Pdh.PDH_COUNTER_PATH_ELEMENTS} structure.
138      * @param pCounterPathElements Structure that contains the members
139      * used to make up the path
140      * @param szFullPathBuffer Caller-allocated buffer that receives a null-terminated
141      * counter path. The maximum length of a counter path is PDH_MAX_COUNTER_PATH.
142      * Set to {@code null} if <tt>pcchBufferSize</tt> is zero.
143      * @param pcchBufferSize Size of the <tt>szFullPathBuffer</tt> buffer. If
144      * zero on input, the function returns PDH_MORE_DATA and sets this parameter
145      * to the required buffer size. If the buffer is larger than the required
146      * size, the function sets this parameter to the actual size of the buffer
147      * that was used.
148      * @param dwFlags Format of the input and output counter values.
149      * @return ERROR_SUCCESS (or PDH_MORE_DATA)
150      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa372649(v=vs.85).aspx">PdhMakeCounterPath</A>
151      */
PdhMakeCounterPath(PDH_COUNTER_PATH_ELEMENTS pCounterPathElements, char[] szFullPathBuffer, DWORDByReference pcchBufferSize, int dwFlags)152     int PdhMakeCounterPath(PDH_COUNTER_PATH_ELEMENTS pCounterPathElements, char[] szFullPathBuffer, DWORDByReference pcchBufferSize, int dwFlags);
153 
154     /**
155      * Adds the specified counter to the query.
156      * @param hQuery Handle to the query to which you want to add the counter.
157      * @param szFullCounterPath String that contains the counter path.
158      * The maximum length of a counter path is {@link #PDH_MAX_COUNTER_PATH}.
159      * @param dwUserData User-defined value.
160      * @param phCounter (Out) Handle to the counter that was added to the query.
161      * @return ERROR_SUCCESS if successful
162      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa372204(v=vs.85).aspx">PdhAddCounter</A>
163      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa373193(v=vs.85).aspx">Specifying a Counter Path</A>
164      */
PdhAddCounter(HANDLE hQuery, String szFullCounterPath, DWORD_PTR dwUserData, HANDLEByReference phCounter)165     int PdhAddCounter(HANDLE hQuery, String szFullCounterPath, DWORD_PTR dwUserData, HANDLEByReference phCounter);
PdhAddEnglishCounter(HANDLE hQuery, String szFullCounterPath, DWORD_PTR dwUserData, HANDLEByReference phCounter)166     int PdhAddEnglishCounter(HANDLE hQuery, String szFullCounterPath, DWORD_PTR dwUserData, HANDLEByReference phCounter);
167 
168     /**
169      * Removes a counter from a query.
170      * @param hCounter Handle of the counter to remove from its query.
171      * @return ERROR_SUCCESS if successful
172      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa372665(v=vs.85).aspx">PdhRemoveCounter</A>
173      */
PdhRemoveCounter(HANDLE hCounter)174     int PdhRemoveCounter(HANDLE hCounter);
175 
176     /**
177      * The data as it was collected from the counter provider. No translation,
178      * formatting, or other interpretation is performed on the data.
179      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa373060(v=vs.85).aspx">PDH_RAW_COUNTER</A>
180      */
181     @FieldOrder({"CStatus", "TimeStamp", "FirstValue", "SecondValue", "MultiCount"})
182     public class PDH_RAW_COUNTER extends Structure {
183         /** Counter status that indicates if the counter value is valid. */
184         public int CStatus;
185         /** Local time for when the data was collected */
186         public FILETIME TimeStamp = new FILETIME();
187         /** First raw counter value. */
188         public long FirstValue;
189         /** Second raw counter value. */
190         public long SecondValue;
191         /**
192          * If the counter type contains the PERF_MULTI_COUNTER flag,
193          * this member contains the additional counter data used in the
194          * calculation
195          */
196         public int MultiCount;
197     }
198 
199     /**
200      * @param hCounter Handle of the counter from which to retrieve the current raw value.
201      * @param lpdwType Receives the counter type - this parameter is optional
202      * @param pValue The {@link PDH_RAW_COUNTER} structure to receive the data
203      * @return ERROR_SUCCESS if successful
204      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa372644(v=vs.85).aspx">PdhGetRawCounterValue</A>
205      */
PdhGetRawCounterValue(HANDLE hCounter, DWORDByReference lpdwType, PDH_RAW_COUNTER pValue)206     int PdhGetRawCounterValue(HANDLE hCounter, DWORDByReference lpdwType, PDH_RAW_COUNTER pValue);
207 
208     // counter value types
209     int PDH_FMT_RAW          = 0x00000010;
210     int PDH_FMT_ANSI         = 0x00000020;
211     int PDH_FMT_UNICODE      = 0x00000040;
212     int PDH_FMT_LONG         = 0x00000100;
213     int PDH_FMT_DOUBLE       = 0x00000200;
214     int PDH_FMT_LARGE        = 0x00000400;
215     int PDH_FMT_NOSCALE      = 0x00001000;
216     int PDH_FMT_1000         = 0x00002000;
217     int PDH_FMT_NODATA       = 0x00004000;
218     int PDH_FMT_NOCAP100     = 0x00008000;
219     int PERF_DETAIL_COSTLY   = 0x00010000;
220     int PERF_DETAIL_STANDARD = 0x0000FFFF;
221 
222     /**
223      * Validates that the counter is present on the computer specified in the counter path.
224      * @param szFullCounterPath The counter path to validate
225      * @return ERROR_SUCCESS if successful
226      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa372986(v=vs.85).aspx">PdhValidatePath</A>
227      */
PdhValidatePath(String szFullCounterPath)228     int PdhValidatePath(String szFullCounterPath);
229 
230     /**
231      * Collects the current raw data value for all counters in the specified
232      * query and updates the status code of each counter.
233      * @param hQuery Handle to the query
234      * @return ERROR_SUCCESS if successful
235      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa372563(v=vs.85).aspx">PdhCollectQueryData</A>
236      */
PdhCollectQueryData(HANDLE hQuery)237     int PdhCollectQueryData(HANDLE hQuery);
238 
239     /**
240      * Uses a separate thread to collect the current raw data value for all counters
241      * in the specified query. The function then signals the application-defined
242      * event and waits the specified time interval before returning.
243      * @param hQuery Handle to the query
244      * @param dwIntervalTime Time interval to wait, in seconds.
245      * @param hNewDataEvent Handle to the event that you want PDH to signal after
246      * the time interval expires. To create an event object, call the
247      * {@link Kernel32#CreateEvent(com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, boolean, boolean, String)}
248      * function
249      * @return ERROR_SUCCESS if successful
250      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa372566(v=vs.85).aspx">PdhCollectQueryDataEx</A>
251      */
PdhCollectQueryDataEx(HANDLE hQuery, int dwIntervalTime, HANDLE hNewDataEvent)252     int PdhCollectQueryDataEx(HANDLE hQuery, int dwIntervalTime, HANDLE hNewDataEvent);
253 
254     /**
255      * Collects the current raw data value for all counters in the specified
256      * query and updates the status code of each counter.
257      * @param hQuery Handle to the query
258      * @param pllTimeStamp Time stamp when the first counter value in the query
259      * was retrieved. The time is specified as {@link WinBase.FILETIME}.
260      * @return ERROR_SUCCESS if successful
261      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa372569(v=vs.85).aspx">PdhCollectQueryDataWithTime</A>
262      */
PdhCollectQueryDataWithTime(HANDLE hQuery, LONGLONGByReference pllTimeStamp)263     int PdhCollectQueryDataWithTime(HANDLE hQuery, LONGLONGByReference pllTimeStamp);
264 
265     /**
266      * Information on time intervals as applied to the sampling of performance data.
267      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa373071(v=vs.85).aspx">PDH_TIME_INFO</A>
268      */
269     @FieldOrder({"StartTime", "EndTime", "SampleCount"})
270     public class PDH_TIME_INFO extends Structure {
271         /** Starting time of the sample interval, in local FILETIME format. */
272         public long StartTime;
273         /** Ending time of the sample interval, in local FILETIME format. */
274         public long EndTime;
275         /** Number of samples collected during the interval. */
276         public int SampleCount;
277     }
278 
279     /**
280      * @param hQuery Handle to the query.
281      * @param pInfo A {@link PDH_TIME_INFO} structure that specifies the time range.
282      * @return ERROR_SUCCESS if successful
283      * @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa372677(v=vs.85).aspx">PdhSetQueryTimeRange</A>
284      */
PdhSetQueryTimeRange(HANDLE hQuery, PDH_TIME_INFO pInfo)285     int PdhSetQueryTimeRange(HANDLE hQuery, PDH_TIME_INFO pInfo);
286 
287     /**
288      * Returns the specified object's counter and instance names that exist on
289      * the specified computer or in the specified log file.
290      *
291      * @param szDataSource
292      *            String that specifies the name of the log file used to
293      *            enumerate the counter and instance names. If NULL, the
294      *            function uses the computer specified in the szMachineName
295      *            parameter to enumerate the names.
296      * @param szMachineName
297      *            String that specifies the name of the computer that contains
298      *            the counter and instance names that you want to enumerate.
299      *            Include the leading slashes in the computer name, for example,
300      *            \\computername. If the szDataSource parameter is NULL, you can
301      *            set szMachineName to NULL to specify the local computer.
302      * @param szObjectName
303      *            String that specifies the name of the object whose counter and
304      *            instance names you want to enumerate.
305      * @param mszCounterList
306      *            Caller-allocated buffer that receives a list of
307      *            null-terminated counter names provided by the specified
308      *            object. The list contains unique counter names. The list is
309      *            terminated by two NULL characters. Set to NULL if the
310      *            pcchCounterListLengthparameter is zero.
311      * @param pcchCounterListLength
312      *            Size of the mszCounterList buffer, in TCHARs. If zero on input
313      *            and the object exists, the function returns PDH_MORE_DATA and
314      *            sets this parameter to the required buffer size. If the buffer
315      *            is larger than the required size, the function sets this
316      *            parameter to the actual size of the buffer that was used. If
317      *            the specified size on input is greater than zero but less than
318      *            the required size, you should not rely on the returned size to
319      *            reallocate the buffer.
320      * @param mszInstanceList
321      *            Caller-allocated buffer that receives a list of
322      *            null-terminated instance names provided by the specified
323      *            object. The list contains unique instance names. The list is
324      *            terminated by two NULL characters. Set to NULL if
325      *            pcchInstanceListLength is zero.
326      * @param pcchInstanceListLength
327      *            Size of the mszInstanceList buffer, in TCHARs. If zero on
328      *            input and the object exists, the function returns
329      *            PDH_MORE_DATA and sets this parameter to the required buffer
330      *            size. If the buffer is larger than the required size, the
331      *            function sets this parameter to the actual size of the buffer
332      *            that was used. If the specified size on input is greater than
333      *            zero but less than the required size, you should not rely on
334      *            the returned size to reallocate the buffer. If the specified
335      *            object does not support variable instances, then the returned
336      *            value will be zero. If the specified object does support
337      *            variable instances, but does not currently have any instances,
338      *            then the value returned is 2, which is the size of an empty
339      *            MULTI_SZ list string.
340      * @param dwDetailLevel
341      *            Detail level of the performance items to return. All items
342      *            that are of the specified detail level or less will be
343      *            returned.
344      * @param dwFlags
345      *            This parameter must be zero.
346      * @return If the function succeeds, it returns ERROR_SUCCESS. If the
347      *         function fails, the return value is a system error code or a PDH
348      *         error code.
349      * @see <A HREF=
350      *      "https://msdn.microsoft.com/en-us/library/windows/desktop/aa372677(v=vs.85).aspx">PdhEnumObjectItems</A>
351      */
PdhEnumObjectItems(String szDataSource, String szMachineName, String szObjectName, Pointer mszCounterList, DWORDByReference pcchCounterListLength, Pointer mszInstanceList, DWORDByReference pcchInstanceListLength, int dwDetailLevel, int dwFlags)352     int PdhEnumObjectItems(String szDataSource, String szMachineName, String szObjectName, Pointer mszCounterList,
353             DWORDByReference pcchCounterListLength, Pointer mszInstanceList, DWORDByReference pcchInstanceListLength,
354             int dwDetailLevel, int dwFlags);
355 
356     /**
357      * Returns the counter index corresponding to the specified counter name.
358      *
359      * @param szMachineName
360      *            Null-terminated string that specifies the name of the computer
361      *            where the specified counter is located. The computer name can
362      *            be specified by the DNS name or the IP address. If NULL, the
363      *            function uses the local computer.
364      * @param szNameBuffer
365      *            Null-terminated string that contains the counter name.
366      * @param pdwIndex
367      *            Index of the counter.
368      * @return If the function succeeds, it returns ERROR_SUCCESS. If the
369      *         function fails, the return value is a system error code or a PDH
370      *         error code.
371      * @see <A HREF=
372      *      "https://msdn.microsoft.com/en-us/library/windows/desktop/aa372647(v=vs.85).aspx">PdhLookupPerfIndexByName</A>
373      */
PdhLookupPerfIndexByName(String szMachineName, String szNameBuffer, DWORDByReference pdwIndex)374     int PdhLookupPerfIndexByName(String szMachineName, String szNameBuffer, DWORDByReference pdwIndex);
375 
376     /**
377      * Returns the performance object name or counter name corresponding to the
378      * specified index.
379      *
380      * @param szMachineName
381      *            Null-terminated string that specifies the name of the computer
382      *            where the specified performance object or counter is located.
383      *            The computer name can be specified by the DNS name or the IP
384      *            address. If NULL, the function uses the local computer.
385      * @param dwNameIndex
386      *            Index of the performance object or counter.
387      * @param szNameBuffer
388      *            Caller-allocated buffer that receives the null-terminated name
389      *            of the performance object or counter. Set to NULL if
390      *            pcchNameBufferSize is zero.
391      * @param pcchNameBufferSize
392      *            Size of the szNameBuffer buffer, in TCHARs. If zero on input,
393      *            the function returns PDH_MORE_DATA and sets this parameter to
394      *            the required buffer size. If the buffer is larger than the
395      *            required size, the function sets this parameter to the actual
396      *            size of the buffer that was used. If the specified size on
397      *            input is greater than zero but less than the required size,
398      *            you should not rely on the returned size to reallocate the
399      *            buffer.
400      * @return If the function succeeds, it returns ERROR_SUCCESS. If the
401      *         function fails, the return value is a system error code or a PDH
402      *         error code.
403      * @see <A HREF=
404      *      "https://msdn.microsoft.com/en-us/library/windows/desktop/aa372648(v=vs.85).aspx">PdhLookupPerfNameByIndex</A>
405      */
PdhLookupPerfNameByIndex(String szMachineName, int dwNameIndex, Pointer szNameBuffer, DWORDByReference pcchNameBufferSize)406     int PdhLookupPerfNameByIndex(String szMachineName, int dwNameIndex, Pointer szNameBuffer,
407             DWORDByReference pcchNameBufferSize);
408 }
409