Started work on Performance subagent for Windows
[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 HhCounter hhCounter;
34 PDH_RAW_COUNTER rawData;
35 PDH_FMT_COUNTERVALUE hCounterValue;
36 PDH_STATUS rc;
37 PDH_hCounter_INFO ci;
38 TCHAR szhCounter[MAX_PATH], szBuffer[1024];
39 static TCHAR szFName[] = _T("H_PdhhCounterValue");
40
41 NxGetParameterArg(pszParam, 1, szhCounter, MAX_PATH);
42
43 if ((rc = PdhOpenQuery(NULL, 0, &hQuery)) != ERROR_SUCCESS)
44 {
45 ReportPdhError(szFName, _T("PdhOpenQuery"), rc);
46 return SYSINFO_RC_ERROR;
47 }
48
49 if ((rc = PdhAddhCounter(hQuery, szhCounter, 0, &hCounter)) != ERROR_SUCCESS)
50 {
51 ReportPdhError(szFName, _T("PdhAddhCounter"), rc);
52 PdhCloseQuery(hQuery);
53 return SYSINFO_RC_UNSUPPORTED;
54 }
55
56 if ((rc = PdhGethCounterInfo(hCounter, FALSE, &dwSize, &ci)) != ERROR_SUCCESS)
57 {
58 ReportPdhError(szFName, _T("PdhGetCounterInfo"), rc);
59 PdhCloseQuery(hQuery);
60 return SYSINFO_RC_ERROR;
61 }
62
63 if ((rc = PdhCollectQueryData(hQuery)) != ERROR_SUCCESS)
64 {
65 ReportPdhError(szFName, _T("PdhCollectQueryData"), rc);
66 PdhCloseQuery(hQuery);
67 return SYSINFO_RC_ERROR;
68 }
69
70 PdhGetRawCounterValue(hCounter, NULL, &rawData);
71 PdhCalculateCounterFromRawValue(hCounter, PDH_FMT_DOUBLE,
72 &rawData, NULL, &hCounterValue);
73 PdhCloseQuery(hQuery);
74 return SYSINFO_RC_SUCCESS;
75 }
76
77
78 //
79 // List of available performance objects
80 //
81
82 static LONG H_PdhObjects(char *pszParam, char *pArg, NETXMS_VALUES_LIST *pValue)
83 {
84 TCHAR *pszObject, *pszObjList, szHostName[256];
85 LONG iResult = SYSINFO_RC_ERROR;
86 DWORD dwSize;
87
88 dwSize = 256;
89 if (GetComputerName(szHostName, &dwSize))
90 {
91 dwSize = 256000;
92 pszObjList = (TCHAR *)malloc(sizeof(TCHAR) * dwSize);
93 if (PdhEnumObjects(NULL, szHostName, pszObjList, &dwSize, PERF_DETAIL_WIZARD, TRUE) == ERROR_SUCCESS)
94 {
95 for(pszObject = pszObjList; *pszObject != 0; pszObject += _tcslen(pszObject) + 1)
96 NxAddResultString(pValue, pszObject);
97 iResult = SYSINFO_RC_SUCCESS;
98 }
99 else
100 {
101 ReportPdhError(_T("H_PdhObjects"), _T("PdhEnumObjects"), rc);
102 }
103 free(pszObjList);
104 }
105 return iResult;
106 }
107
108
109 //
110 // List of available performance items for given object
111 //
112
113 static LONG H_PdhObjectItems(char *pszParam, char *pArg, NETXMS_VALUES_LIST *pValue)
114 {
115 TCHAR *pszElement, *pszhCounterList, *pszInstanceList, szHostName[256], szObject[256];
116 LONG iResult = SYSINFO_RC_ERROR;
117 DWORD dwSize1, dwSize2;
118 PDH_STATUS rc;
119
120 NxGetParameterArg(pszParam, 1, szObject, 256);
121 if (szObject[0] != 0)
122 {
123 dwSize1 = 256;
124 if (GetComputerName(szHostName, &dwSize1))
125 {
126 dwSize1 = dwSize2 = 256000;
127 pszhCounterList = (TCHAR *)malloc(sizeof(TCHAR) * dwSize1);
128 pszInstanceList = (TCHAR *)malloc(sizeof(TCHAR) * dwSize2);
129 rc = PdhEnumObjectItems(NULL, szHostName, szObject,
130 pszhCounterList, &dwSize1, pszInstanceList, &dwSize2,
131 PERF_DETAIL_WIZARD, 0);
132 if ((rc == ERROR_SUCCESS) || (rc == PDH_MORE_DATA))
133 {
134 for(pszElement = (pArg[0] == _T('C')) ? pszhCounterList : pszInstanceList;
135 *pszElement != 0; pszElement += _tcslen(pszElement) + 1)
136 NxAddResultString(pValue, pszElement);
137 iResult = SYSINFO_RC_SUCCESS;
138 }
139 else
140 {
141 ReportPdhError(_T("H_PdhObjectItems"), _T("PdhEnumObjectItems"), rc);
142 }
143 free(pszhCounterList);
144 free(pszInstanceLIst)
145 }
146 }
147 else
148 {
149 iResult = SYSINFO_RC_UNSUPPORTED;
150 }
151 return iResult;
152 }
153
154
155 //
156 // Subagent information
157 //
158
159 static NETXMS_SUBAGENT_PARAM m_parameters[] =
160 {
161 { "PDH.hCounterValue(*)", H_PdhhCounterValue, NULL }
162 };
163 static NETXMS_SUBAGENT_ENUM m_enums[] =
164 {
165 { "PDH.ObjecthCounters(*)", H_PdhObjectItems, _T("C") },
166 { "PDH.ObjectInstances(*)", H_PdhObjectItems, _T("I") },
167 { "PDH.Objects", H_PdhObjects, NULL }
168 };
169
170 static NETXMS_SUBAGENT_INFO m_info =
171 {
172 "WinPerf", 0x01000000, NULL,
173 sizeof(m_parameters) / sizeof(NETXMS_SUBAGENT_PARAM),
174 m_parameters,
175 sizeof(m_enums) / sizeof(NETXMS_SUBAGENT_ENUM),
176 m_enums
177 };
178
179
180 //
181 // Entry point for NetXMS agent
182 //
183
184 extern "C" BOOL __declspec(dllexport) __cdecl
185 NxSubAgentInit(NETXMS_SUBAGENT_INFO **ppInfo, TCHAR *pszConfigFile)
186 {
187 *ppInfo = &m_info;
188 return TRUE;
189 }
190
191
192 //
193 // DLL entry point
194 //
195
196 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
197 {
198 return TRUE;
199 }