Minor changes
[public/netxms.git] / src / agent / subagents / winperf / winperf.cpp
1 /*
2 ** Windows Performance NetXMS subagent
3 ** Copyright (C) 2004 Victor Kirhenshtein
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** $module: winperf.cpp
20 **
21 **/
22
23 #include "winperf.h"
24
25
26 //
27 // CPU utilization
28 //
29
30 static LONG H_PdhhCounterValue(char *pszParam, char *pArg, char *pValue)
31 {
32 HQUERY hQuery;
33 HCOUNTER hCounter;
34 PDH_RAW_COUNTER rawData;
35 PDH_FMT_COUNTERVALUE counterValue;
36 PDH_STATUS rc;
37 PDH_COUNTER_INFO ci;
38 TCHAR szCounter[MAX_PATH];
39 static TCHAR szFName[] = _T("H_PdhCounterValue");
40 DWORD dwSize;
41
42 NxGetParameterArg(pszParam, 1, szCounter, MAX_PATH);
43
44 if ((rc = PdhOpenQuery(NULL, 0, &hQuery)) != ERROR_SUCCESS)
45 {
46 ReportPdhError(szFName, _T("PdhOpenQuery"), rc);
47 return SYSINFO_RC_ERROR;
48 }
49
50 if ((rc = PdhAddCounter(hQuery, szCounter, 0, &hCounter)) != ERROR_SUCCESS)
51 {
52 ReportPdhError(szFName, _T("PdhAddCounter"), rc);
53 PdhCloseQuery(hQuery);
54 return SYSINFO_RC_UNSUPPORTED;
55 }
56
57 if ((rc = PdhCollectQueryData(hQuery)) != ERROR_SUCCESS)
58 {
59 ReportPdhError(szFName, _T("PdhCollectQueryData"), rc);
60 PdhCloseQuery(hQuery);
61 return SYSINFO_RC_ERROR;
62 }
63
64 dwSize = sizeof(ci);
65 if ((rc = PdhGetCounterInfo(hCounter, FALSE, &dwSize, &ci)) != ERROR_SUCCESS)
66 {
67 ReportPdhError(szFName, _T("PdhGetCounterInfo"), rc);
68 PdhCloseQuery(hQuery);
69 return SYSINFO_RC_ERROR;
70 }
71
72 PdhGetRawCounterValue(hCounter, NULL, &rawData);
73 if (ci.dwType & PERF_SIZE_LARGE)
74 {
75 PdhCalculateCounterFromRawValue(hCounter, PDH_FMT_LARGE,
76 &rawData, NULL, &counterValue);
77 ret_int64(pValue, counterValue.largeValue);
78 }
79 else
80 {
81 PdhCalculateCounterFromRawValue(hCounter, PDH_FMT_LONG,
82 &rawData, NULL, &counterValue);
83 ret_int64(pValue, counterValue.longValue);
84 }
85 PdhCloseQuery(hQuery);
86 return SYSINFO_RC_SUCCESS;
87 }
88
89
90 //
91 // List of available performance objects
92 //
93
94 static LONG H_PdhObjects(char *pszParam, char *pArg, NETXMS_VALUES_LIST *pValue)
95 {
96 TCHAR *pszObject, *pszObjList, szHostName[256];
97 LONG iResult = SYSINFO_RC_ERROR;
98 PDH_STATUS rc;
99 DWORD dwSize;
100
101 dwSize = 256;
102 if (GetComputerName(szHostName, &dwSize))
103 {
104 dwSize = 256000;
105 pszObjList = (TCHAR *)malloc(sizeof(TCHAR) * dwSize);
106 if ((rc = PdhEnumObjects(NULL, szHostName, pszObjList, &dwSize,
107 PERF_DETAIL_WIZARD, TRUE)) == ERROR_SUCCESS)
108 {
109 for(pszObject = pszObjList; *pszObject != 0; pszObject += _tcslen(pszObject) + 1)
110 NxAddResultString(pValue, pszObject);
111 iResult = SYSINFO_RC_SUCCESS;
112 }
113 else
114 {
115 ReportPdhError(_T("H_PdhObjects"), _T("PdhEnumObjects"), rc);
116 }
117 free(pszObjList);
118 }
119 return iResult;
120 }
121
122
123 //
124 // List of available performance items for given object
125 //
126
127 static LONG H_PdhObjectItems(char *pszParam, char *pArg, NETXMS_VALUES_LIST *pValue)
128 {
129 TCHAR *pszElement, *pszCounterList, *pszInstanceList, szHostName[256], szObject[256];
130 LONG iResult = SYSINFO_RC_ERROR;
131 DWORD dwSize1, dwSize2;
132 PDH_STATUS rc;
133
134 NxGetParameterArg(pszParam, 1, szObject, 256);
135 if (szObject[0] != 0)
136 {
137 dwSize1 = 256;
138 if (GetComputerName(szHostName, &dwSize1))
139 {
140 dwSize1 = dwSize2 = 256000;
141 pszCounterList = (TCHAR *)malloc(sizeof(TCHAR) * dwSize1);
142 pszInstanceList = (TCHAR *)malloc(sizeof(TCHAR) * dwSize2);
143 rc = PdhEnumObjectItems(NULL, szHostName, szObject,
144 pszCounterList, &dwSize1, pszInstanceList, &dwSize2,
145 PERF_DETAIL_WIZARD, 0);
146 if ((rc == ERROR_SUCCESS) || (rc == PDH_MORE_DATA))
147 {
148 for(pszElement = (pArg[0] == _T('C')) ? pszCounterList : pszInstanceList;
149 *pszElement != 0; pszElement += _tcslen(pszElement) + 1)
150 NxAddResultString(pValue, pszElement);
151 iResult = SYSINFO_RC_SUCCESS;
152 }
153 else
154 {
155 ReportPdhError(_T("H_PdhObjectItems"), _T("PdhEnumObjectItems"), rc);
156 }
157 free(pszCounterList);
158 free(pszInstanceList);
159 }
160 }
161 else
162 {
163 iResult = SYSINFO_RC_UNSUPPORTED;
164 }
165 return iResult;
166 }
167
168
169 //
170 // Subagent information
171 //
172
173 static NETXMS_SUBAGENT_PARAM m_parameters[] =
174 {
175 { _T("PDH.CounterValue(*)"), H_PdhhCounterValue, NULL }
176 };
177 static NETXMS_SUBAGENT_ENUM m_enums[] =
178 {
179 { _T("PDH.ObjectCounters(*)"), H_PdhObjectItems, _T("C") },
180 { _T("PDH.ObjectInstances(*)"), H_PdhObjectItems, _T("I") },
181 { _T("PDH.Objects"), H_PdhObjects, NULL }
182 };
183
184 static NETXMS_SUBAGENT_INFO m_info =
185 {
186 "WinPerf", 0x01000000, NULL,
187 sizeof(m_parameters) / sizeof(NETXMS_SUBAGENT_PARAM),
188 m_parameters,
189 sizeof(m_enums) / sizeof(NETXMS_SUBAGENT_ENUM),
190 m_enums
191 };
192
193
194 //
195 // Entry point for NetXMS agent
196 //
197
198 extern "C" BOOL __declspec(dllexport) __cdecl
199 NxSubAgentInit(NETXMS_SUBAGENT_INFO **ppInfo, TCHAR *pszConfigFile)
200 {
201 *ppInfo = &m_info;
202 return TRUE;
203 }
204
205
206 //
207 // DLL entry point
208 //
209
210 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
211 {
212 return TRUE;
213 }