c444f98260e757f3e5e20126b61759f2a8e410f0
[public/netxms.git] / src / agent / core / getparam.cpp
1 /*
2 ** NetXMS multiplatform core agent
3 ** Copyright (C) 2003-2016 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 ** File: getparam.cpp
20 **
21 **/
22
23 #include "nxagentd.h"
24
25 /**
26 * Parameter handlers
27 */
28 LONG H_ActiveConnections(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
29 LONG H_AgentTraps(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
30 LONG H_AgentUptime(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
31 LONG H_CRC32(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
32 LONG H_DataCollectorQueueSize(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
33 LONG H_DirInfo(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
34 LONG H_FileTime(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
35 LONG H_IsSubagentLoaded(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
36 LONG H_MD5Hash(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
37 LONG H_SHA1Hash(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
38 LONG H_SubAgentList(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session);
39 LONG H_SubAgentTable(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
40 LONG H_ActionList(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session);
41 LONG H_ExternalParameter(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
42 LONG H_ExternalList(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session);
43 LONG H_PlatformName(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
44 LONG H_SessionAgents(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
45 LONG H_SystemTime(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
46 LONG H_ThreadPoolInfo(const TCHAR *param, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
47 LONG H_ThreadPoolList(const TCHAR *param, const TCHAR *arg, StringList *value, AbstractCommSession *session);
48 LONG H_ResolverAddrByName(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
49 LONG H_ResolverNameByAddr(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
50
51 #ifdef _WIN32
52 LONG H_CPUCount(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
53 LONG H_DiskInfo(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
54 LONG H_FileSystems(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *session);
55 LONG H_FileSystemType(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
56 LONG H_HostName(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
57 LONG H_MemoryInfo(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
58 LONG H_MountPoints(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session);
59 LONG H_PhysicalDiskInfo(const TCHAR *cmd, const TCHAR *arg, TCHAR *pValue, AbstractCommSession *session);
60 LONG H_SystemUname(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
61 #endif
62
63 /**
64 * Static data
65 */
66 static NETXMS_SUBAGENT_PARAM *m_pParamList = NULL;
67 static int m_iNumParams = 0;
68 static NETXMS_SUBAGENT_PUSHPARAM *m_pPushParamList = NULL;
69 static int m_iNumPushParams = 0;
70 static NETXMS_SUBAGENT_LIST *m_pEnumList = NULL;
71 static int m_iNumEnums = 0;
72 static NETXMS_SUBAGENT_TABLE *m_pTableList = NULL;
73 static int m_iNumTables = 0;
74 static UINT32 m_dwTimedOutRequests = 0;
75 static UINT32 m_dwAuthenticationFailures = 0;
76 static UINT32 m_dwProcessedRequests = 0;
77 static UINT32 m_dwFailedRequests = 0;
78 static UINT32 m_dwUnsupportedRequests = 0;
79
80 /**
81 * Handler for parameters which always returns string constant
82 */
83 static LONG H_StringConstant(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session)
84 {
85 ret_string(value, arg);
86 return SYSINFO_RC_SUCCESS;
87 }
88
89 /**
90 * Handler for parameters which returns UINT32 value from specific variable
91 */
92 static LONG H_UIntPtr(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session)
93 {
94 ret_uint(value, *((UINT32 *)arg));
95 return SYSINFO_RC_SUCCESS;
96 }
97
98 /**
99 * Handler for Agent.SupportedCiphers
100 */
101 static LONG H_SupportedCiphers(const TCHAR *pszCmd, const TCHAR *pArg, TCHAR *pValue, AbstractCommSession *session)
102 {
103 UINT32 dwCiphers;
104
105 dwCiphers = NXCPGetSupportedCiphers();
106 if (dwCiphers == 0)
107 {
108 ret_string(pValue, _T("NONE"));
109 }
110 else
111 {
112 *pValue = 0;
113 if (dwCiphers & NXCP_SUPPORT_AES_256)
114 _tcscat(pValue, _T("AES-256 "));
115 if (dwCiphers & NXCP_SUPPORT_AES_128)
116 _tcscat(pValue, _T("AES-128 "));
117 if (dwCiphers & NXCP_SUPPORT_BLOWFISH_256)
118 _tcscat(pValue, _T("BF-256 "));
119 if (dwCiphers & NXCP_SUPPORT_BLOWFISH_128)
120 _tcscat(pValue, _T("BF-128 "));
121 if (dwCiphers & NXCP_SUPPORT_IDEA)
122 _tcscat(pValue, _T("IDEA "));
123 if (dwCiphers & NXCP_SUPPORT_3DES)
124 _tcscat(pValue, _T("3DES "));
125 pValue[_tcslen(pValue) - 1] = 0;
126 }
127 return SYSINFO_RC_SUCCESS;
128 }
129
130 /**
131 * Handler for parameters list
132 */
133 static LONG H_ParamList(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session)
134 {
135 int i;
136
137 for(i = 0; i < m_iNumParams; i++)
138 if (m_pParamList[i].dataType != DCI_DT_DEPRECATED)
139 value->add(m_pParamList[i].name);
140 ListParametersFromExtProviders(value);
141 ListParametersFromExtSubagents(value);
142 return SYSINFO_RC_SUCCESS;
143 }
144
145 /**
146 * Handler for push parameters list
147 */
148 static LONG H_PushParamList(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session)
149 {
150 int i;
151
152 for(i = 0; i < m_iNumPushParams; i++)
153 value->add(m_pPushParamList[i].name);
154 return SYSINFO_RC_SUCCESS;
155 }
156
157 /**
158 * Handler for enums list
159 */
160 static LONG H_EnumList(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session)
161 {
162 int i;
163
164 for(i = 0; i < m_iNumEnums; i++)
165 value->add(m_pEnumList[i].name);
166 ListListsFromExtSubagents(value);
167 return SYSINFO_RC_SUCCESS;
168 }
169
170 /**
171 * Handler for table list
172 */
173 static LONG H_TableList(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session)
174 {
175 int i;
176
177 for(i = 0; i < m_iNumTables; i++)
178 value->add(m_pTableList[i].name);
179 ListTablesFromExtSubagents(value);
180 return SYSINFO_RC_SUCCESS;
181 }
182
183 /**
184 * Handler for component statuses based on failure flags
185 */
186 static LONG H_ComponentStatus(const TCHAR *pszParam, const TCHAR *pArg, TCHAR *pValue, AbstractCommSession *session)
187 {
188 UINT32 result = 0;
189 switch(*pArg)
190 {
191 case 'D':
192 if ((g_failFlags & FAIL_OPEN_DATABASE) != 0)
193 result++;
194 if ((g_failFlags & FIAL_UPGRADE_DATABASE) != 0)
195 result++;
196 break;
197 case 'L':
198 if ((g_failFlags & FAIL_OPEN_LOG) != 0)
199 result++;
200 break;
201 }
202
203 ret_uint(pValue, result);
204 return SYSINFO_RC_SUCCESS;
205 }
206
207 /**
208 * Handler for local database counters
209 */
210 static LONG H_LocalDatabaseCounters(const TCHAR *pszParam, const TCHAR *pArg, TCHAR *pValue, AbstractCommSession *session)
211 {
212 LIBNXDB_PERF_COUNTERS counters;
213 DBGetPerfCounters(&counters);
214 switch(*pArg)
215 {
216 case 'F':
217 ret_int64(pValue, counters.failedQueries);
218 break;
219 case 'L':
220 ret_int64(pValue, counters.longRunningQueries);
221 break;
222 case 'T':
223 ret_int64(pValue, counters.totalQueries);
224 break;
225 default:
226 return SYSINFO_RC_UNSUPPORTED;
227 }
228 return SYSINFO_RC_SUCCESS;
229 }
230
231 /**
232 * Standard agent's parameters
233 */
234 static NETXMS_SUBAGENT_PARAM m_stdParams[] =
235 {
236 #ifdef _WIN32
237 { _T("Disk.Free(*)"), H_DiskInfo, (TCHAR *)DISKINFO_FREE_BYTES, DCI_DT_DEPRECATED, DCIDESC_DEPRECATED },
238 { _T("Disk.FreePerc(*)"), H_DiskInfo, (TCHAR *)DISKINFO_FREE_SPACE_PCT, DCI_DT_DEPRECATED, DCIDESC_DEPRECATED },
239 { _T("Disk.Total(*)"), H_DiskInfo, (TCHAR *)DISKINFO_TOTAL_BYTES, DCI_DT_DEPRECATED, DCIDESC_DEPRECATED },
240 { _T("Disk.Used(*)"), H_DiskInfo, (TCHAR *)DISKINFO_USED_BYTES, DCI_DT_DEPRECATED, DCIDESC_DEPRECATED },
241 { _T("Disk.UsedPerc(*)"), H_DiskInfo, (TCHAR *)DISKINFO_USED_SPACE_PCT, DCI_DT_DEPRECATED, DCIDESC_DEPRECATED },
242 { _T("FileSystem.Free(*)"), H_DiskInfo, (TCHAR *)DISKINFO_FREE_BYTES, DCI_DT_UINT64, DCIDESC_FS_FREE },
243 { _T("FileSystem.FreePerc(*)"), H_DiskInfo, (TCHAR *)DISKINFO_FREE_SPACE_PCT, DCI_DT_FLOAT, DCIDESC_FS_FREEPERC },
244 { _T("FileSystem.Total(*)"), H_DiskInfo, (TCHAR *)DISKINFO_TOTAL_BYTES, DCI_DT_UINT64, DCIDESC_FS_TOTAL },
245 { _T("FileSystem.Type(*)"), H_FileSystemType, NULL, DCI_DT_STRING, DCIDESC_FS_TYPE },
246 { _T("FileSystem.Used(*)"), H_DiskInfo, (TCHAR *)DISKINFO_USED_BYTES, DCI_DT_UINT64, DCIDESC_FS_USED },
247 { _T("FileSystem.UsedPerc(*)"), H_DiskInfo, (TCHAR *)DISKINFO_USED_SPACE_PCT, DCI_DT_FLOAT, DCIDESC_FS_USEDPERC },
248 { _T("PhysicalDisk.Firmware(*)"), H_PhysicalDiskInfo, _T("F"), DCI_DT_STRING, DCIDESC_PHYSICALDISK_FIRMWARE },
249 { _T("PhysicalDisk.Model(*)"), H_PhysicalDiskInfo, _T("M"), DCI_DT_STRING, DCIDESC_PHYSICALDISK_MODEL },
250 { _T("PhysicalDisk.SerialNumber(*)"), H_PhysicalDiskInfo, _T("N"), DCI_DT_STRING, DCIDESC_PHYSICALDISK_SERIALNUMBER },
251 { _T("PhysicalDisk.SmartAttr(*)"), H_PhysicalDiskInfo, _T("A"), DCI_DT_STRING, DCIDESC_PHYSICALDISK_SMARTATTR },
252 { _T("PhysicalDisk.SmartStatus(*)"), H_PhysicalDiskInfo, _T("S"), DCI_DT_INT, DCIDESC_PHYSICALDISK_SMARTSTATUS },
253 { _T("PhysicalDisk.Temperature(*)"), H_PhysicalDiskInfo, _T("T"), DCI_DT_INT, DCIDESC_PHYSICALDISK_TEMPERATURE },
254 { _T("System.CPU.Count"), H_CPUCount, NULL, DCI_DT_UINT, DCIDESC_SYSTEM_CPU_COUNT },
255 { _T("System.Hostname"), H_HostName, NULL, DCI_DT_STRING, DCIDESC_SYSTEM_HOSTNAME },
256 { _T("System.Memory.Physical.Available"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_FREE, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_PHYSICAL_AVAILABLE },
257 { _T("System.Memory.Physical.AvailablePerc"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_FREE_PCT, DCI_DT_UINT, DCIDESC_SYSTEM_MEMORY_PHYSICAL_AVAILABLE_PCT },
258 { _T("System.Memory.Physical.Free"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_FREE, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_PHYSICAL_FREE },
259 { _T("System.Memory.Physical.FreePerc"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_FREE_PCT, DCI_DT_UINT, DCIDESC_SYSTEM_MEMORY_PHYSICAL_FREE_PCT },
260 { _T("System.Memory.Physical.Total"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_TOTAL, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_PHYSICAL_TOTAL },
261 { _T("System.Memory.Physical.Used"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_USED, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_PHYSICAL_USED },
262 { _T("System.Memory.Physical.UsedPerc"), H_MemoryInfo, (TCHAR *)MEMINFO_PHYSICAL_USED_PCT, DCI_DT_UINT, DCIDESC_SYSTEM_MEMORY_PHYSICAL_USED_PCT },
263 { _T("System.Memory.Virtual.Free"), H_MemoryInfo, (TCHAR *)MEMINFO_VIRTUAL_FREE, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_VIRTUAL_FREE },
264 { _T("System.Memory.Virtual.FreePerc"), H_MemoryInfo, (TCHAR *)MEMINFO_VIRTUAL_FREE_PCT, DCI_DT_UINT, DCIDESC_SYSTEM_MEMORY_VIRTUAL_FREE_PCT },
265 { _T("System.Memory.Virtual.Total"), H_MemoryInfo, (TCHAR *)MEMINFO_VIRTUAL_TOTAL, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_VIRTUAL_TOTAL },
266 { _T("System.Memory.Virtual.Used"), H_MemoryInfo, (TCHAR *)MEMINFO_VIRTUAL_USED, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_VIRTUAL_USED },
267 { _T("System.Memory.Virtual.UsedPerc"), H_MemoryInfo, (TCHAR *)MEMINFO_VIRTUAL_USED_PCT, DCI_DT_UINT, DCIDESC_SYSTEM_MEMORY_VIRTUAL_USED_PCT },
268 { _T("System.Uname"), H_SystemUname, NULL, DCI_DT_STRING, DCIDESC_SYSTEM_UNAME },
269 #endif
270
271 { _T("Agent.AcceptedConnections"), H_UIntPtr, (TCHAR *)&g_dwAcceptedConnections, DCI_DT_UINT, DCIDESC_AGENT_ACCEPTEDCONNECTIONS },
272 { _T("Agent.AcceptErrors"), H_UIntPtr, (TCHAR *)&g_dwAcceptErrors, DCI_DT_UINT, DCIDESC_AGENT_ACCEPTERRORS },
273 { _T("Agent.ActiveConnections"), H_ActiveConnections, NULL, DCI_DT_UINT, DCIDESC_AGENT_ACTIVECONNECTIONS },
274 { _T("Agent.AuthenticationFailures"), H_UIntPtr, (TCHAR *)&m_dwAuthenticationFailures, DCI_DT_UINT, DCIDESC_AGENT_AUTHENTICATIONFAILURES },
275 { _T("Agent.ConfigurationServer"), H_StringConstant, g_szConfigServer, DCI_DT_STRING, DCIDESC_AGENT_CONFIG_SERVER },
276 { _T("Agent.DataCollectorQueueSize"), H_DataCollectorQueueSize, NULL, DCI_DT_UINT, DCIDESC_AGENT_DATACOLLQUEUESIZE },
277 { _T("Agent.FailedRequests"), H_UIntPtr, (TCHAR *)&m_dwFailedRequests, DCI_DT_UINT, DCIDESC_AGENT_FAILEDREQUESTS },
278 { _T("Agent.GeneratedTraps"), H_AgentTraps, _T("G"), DCI_DT_UINT64, DCIDESC_AGENT_GENERATED_TRAPS },
279 { _T("Agent.IsSubagentLoaded(*)"), H_IsSubagentLoaded, NULL, DCI_DT_INT, DCIDESC_AGENT_IS_SUBAGENT_LOADED },
280 { _T("Agent.LastTrapTime"), H_AgentTraps, _T("T"), DCI_DT_UINT64, DCIDESC_AGENT_LAST_TRAP_TIME },
281 { _T("Agent.LocalDatabase.FailedQueries"), H_LocalDatabaseCounters, _T("F"), DCI_DT_UINT64, DCIDESC_AGENT_LOCALDB_FAILED_QUERIES },
282 { _T("Agent.LocalDatabase.LongRunningQueries"), H_LocalDatabaseCounters, _T("L"), DCI_DT_UINT64, DCIDESC_AGENT_LOCALDB_SLOW_QUERIES },
283 { _T("Agent.LocalDatabase.Status"), H_ComponentStatus, _T("D"), DCI_DT_UINT, DCIDESC_AGENT_LOCALDB_STATUS },
284 { _T("Agent.LocalDatabase.TotalQueries"), H_LocalDatabaseCounters, _T("T"), DCI_DT_UINT64, DCIDESC_AGENT_LOCALDB_TOTAL_QUERIES },
285 { _T("Agent.LogFile.Status"), H_ComponentStatus, _T("L"), DCI_DT_UINT, DCIDESC_AGENT_LOG_STATUS },
286 { _T("Agent.ProcessedRequests"), H_UIntPtr, (TCHAR *)&m_dwProcessedRequests, DCI_DT_UINT, DCIDESC_AGENT_PROCESSEDREQUESTS },
287 { _T("Agent.Registrar"), H_StringConstant, g_szRegistrar, DCI_DT_STRING, DCIDESC_AGENT_REGISTRAR },
288 { _T("Agent.RejectedConnections"), H_UIntPtr, (TCHAR *)&g_dwRejectedConnections, DCI_DT_UINT, DCIDESC_AGENT_REJECTEDCONNECTIONS },
289 { _T("Agent.SentTraps"), H_AgentTraps, _T("S"), DCI_DT_UINT64, DCIDESC_AGENT_SENT_TRAPS },
290 { _T("Agent.SourcePackageSupport"), H_StringConstant, _T("0"), DCI_DT_INT, DCIDESC_AGENT_SOURCEPACKAGESUPPORT },
291 { _T("Agent.SupportedCiphers"), H_SupportedCiphers, NULL, DCI_DT_STRING, DCIDESC_AGENT_SUPPORTEDCIPHERS },
292 { _T("Agent.ThreadPool.ActiveRequests(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_REQUESTS, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_ACTIVEREQUESTS },
293 { _T("Agent.ThreadPool.CurrSize(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_CURR_SIZE, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_CURRSIZE },
294 { _T("Agent.ThreadPool.Load(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_LOAD, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_LOAD },
295 { _T("Agent.ThreadPool.LoadAverage(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_LOADAVG_1, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_LOADAVG },
296 { _T("Agent.ThreadPool.LoadAverage5(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_LOADAVG_5, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_LOADAVG_5 },
297 { _T("Agent.ThreadPool.LoadAverage15(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_LOADAVG_15, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_LOADAVG_15 },
298 { _T("Agent.ThreadPool.MaxSize(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_MAX_SIZE, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_MAXSIZE },
299 { _T("Agent.ThreadPool.MinSize(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_MIN_SIZE, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_MINSIZE },
300 { _T("Agent.ThreadPool.Usage(*)"), H_ThreadPoolInfo, (TCHAR *)THREAD_POOL_USAGE, DCI_DT_UINT, DCIDESC_AGENT_THREADPOOL_USAGE },
301 { _T("Agent.TimedOutRequests"), H_UIntPtr, (TCHAR *)&m_dwTimedOutRequests, DCI_DT_UINT, DCIDESC_AGENT_TIMEDOUTREQUESTS },
302 { _T("Agent.UnsupportedRequests"), H_UIntPtr, (TCHAR *)&m_dwUnsupportedRequests, DCI_DT_UINT, DCIDESC_AGENT_UNSUPPORTEDREQUESTS },
303 { _T("Agent.Uptime"), H_AgentUptime, NULL, DCI_DT_UINT, DCIDESC_AGENT_UPTIME },
304 { _T("Agent.Version"), H_StringConstant, AGENT_VERSION_STRING, DCI_DT_STRING, DCIDESC_AGENT_VERSION },
305 { _T("File.Count(*)"), H_DirInfo, (TCHAR *)DIRINFO_FILE_COUNT, DCI_DT_UINT, DCIDESC_FILE_COUNT },
306 { _T("File.FolderCount(*)"), H_DirInfo, (TCHAR *)DIRINFO_FOLDER_COUNT, DCI_DT_UINT, DCIDESC_FILE_FOLDERCOUNT },
307 { _T("File.Hash.CRC32(*)"), H_CRC32, NULL, DCI_DT_UINT, DCIDESC_FILE_HASH_CRC32 },
308 { _T("File.Hash.MD5(*)"), H_MD5Hash, NULL, DCI_DT_STRING, DCIDESC_FILE_HASH_MD5 },
309 { _T("File.Hash.SHA1(*)"), H_SHA1Hash, NULL, DCI_DT_STRING, DCIDESC_FILE_HASH_SHA1 },
310 { _T("File.Size(*)"), H_DirInfo, (TCHAR *)DIRINFO_FILE_SIZE, DCI_DT_UINT64, DCIDESC_FILE_SIZE },
311 { _T("File.Time.Access(*)"), H_FileTime, (TCHAR *)FILETIME_ATIME, DCI_DT_UINT64, DCIDESC_FILE_TIME_ACCESS },
312 { _T("File.Time.Change(*)"), H_FileTime, (TCHAR *)FILETIME_CTIME, DCI_DT_UINT64, DCIDESC_FILE_TIME_CHANGE },
313 { _T("File.Time.Modify(*)"), H_FileTime, (TCHAR *)FILETIME_MTIME, DCI_DT_UINT64, DCIDESC_FILE_TIME_MODIFY },
314 { _T("Net.Resolver.AddressByName(*)"), H_ResolverAddrByName, NULL, DCI_DT_STRING, DCIDESC_NET_RESOLVER_ADDRBYNAME },
315 { _T("Net.Resolver.NameByAddress(*)"), H_ResolverNameByAddr, NULL, DCI_DT_STRING, DCIDESC_NET_RESOLVER_NAMEBYADDR },
316 { _T("System.CurrentTime"), H_SystemTime, NULL, DCI_DT_INT64, DCIDESC_SYSTEM_CURRENTTIME },
317 { _T("System.PlatformName"), H_PlatformName, NULL, DCI_DT_STRING, DCIDESC_SYSTEM_PLATFORMNAME }
318 };
319
320 /**
321 * Standard agent's lists
322 */
323 static NETXMS_SUBAGENT_LIST m_stdLists[] =
324 {
325 #ifdef _WIN32
326 { _T("FileSystem.MountPoints"), H_MountPoints, NULL },
327 #endif
328 { _T("Agent.ActionList"), H_ActionList, NULL },
329 { _T("Agent.SubAgentList"), H_SubAgentList, NULL },
330 { _T("Agent.SupportedLists"), H_EnumList, NULL },
331 { _T("Agent.SupportedParameters"), H_ParamList, NULL },
332 { _T("Agent.SupportedPushParameters"), H_PushParamList, NULL },
333 { _T("Agent.SupportedTables"), H_TableList, NULL },
334 { _T("Agent.ThreadPools"), H_ThreadPoolList, NULL }
335 };
336
337 /**
338 * Standard agent's tables
339 */
340 static NETXMS_SUBAGENT_TABLE m_stdTables[] =
341 {
342 { _T("Agent.SessionAgents"), H_SessionAgents, NULL, _T("SESSION_ID"), DCTDESC_AGENT_SUBAGENTS },
343 { _T("Agent.SubAgents"), H_SubAgentTable, NULL, _T("NAME"), DCTDESC_AGENT_SUBAGENTS },
344 #ifdef _WIN32
345 { _T("FileSystem.Volumes"), H_FileSystems, NULL, _T("VOLUME"), DCTDESC_FILESYSTEM_VOLUMES }
346 #endif
347 };
348
349 /**
350 * Initialize dynamic parameters list from default static list
351 */
352 BOOL InitParameterList()
353 {
354 if ((m_pParamList != NULL) || (m_pEnumList != NULL) || (m_pTableList != NULL))
355 return FALSE;
356
357 m_iNumParams = sizeof(m_stdParams) / sizeof(NETXMS_SUBAGENT_PARAM);
358 if (m_iNumParams > 0)
359 {
360 m_pParamList = (NETXMS_SUBAGENT_PARAM *)malloc(sizeof(NETXMS_SUBAGENT_PARAM) * m_iNumParams);
361 if (m_pParamList == NULL)
362 return FALSE;
363 memcpy(m_pParamList, m_stdParams, sizeof(NETXMS_SUBAGENT_PARAM) * m_iNumParams);
364 }
365
366 m_iNumEnums = sizeof(m_stdLists) / sizeof(NETXMS_SUBAGENT_LIST);
367 if (m_iNumEnums > 0)
368 {
369 m_pEnumList = (NETXMS_SUBAGENT_LIST *)malloc(sizeof(NETXMS_SUBAGENT_LIST) * m_iNumEnums);
370 if (m_pEnumList == NULL)
371 return FALSE;
372 memcpy(m_pEnumList, m_stdLists, sizeof(NETXMS_SUBAGENT_LIST) * m_iNumEnums);
373 }
374
375 m_iNumTables = sizeof(m_stdTables) / sizeof(NETXMS_SUBAGENT_TABLE);
376 if (m_iNumTables > 0)
377 {
378 m_pTableList = (NETXMS_SUBAGENT_TABLE *)malloc(sizeof(NETXMS_SUBAGENT_TABLE) * m_iNumTables);
379 if (m_pTableList == NULL)
380 return FALSE;
381 memcpy(m_pTableList, m_stdTables, sizeof(NETXMS_SUBAGENT_TABLE) * m_iNumTables);
382 }
383
384 return TRUE;
385 }
386
387 /**
388 * Add push parameter to list
389 * by LWX
390 */
391 void AddPushParameter(const TCHAR *name, int dataType, const TCHAR *description)
392 {
393 int i;
394
395 // Search for existing parameter
396 for(i = 0; i < m_iNumPushParams; i++)
397 if (!_tcsicmp(m_pPushParamList[i].name, name))
398 break;
399 if (i < m_iNumPushParams)
400 {
401 // Replace existing attributes
402 m_pPushParamList[i].dataType = dataType;
403 nx_strncpy(m_pPushParamList[i].description, description, MAX_DB_STRING);
404 }
405 else
406 {
407 // Add new parameter
408 m_pPushParamList = (NETXMS_SUBAGENT_PUSHPARAM *)realloc(m_pPushParamList, sizeof(NETXMS_SUBAGENT_PUSHPARAM) * (m_iNumPushParams + 1));
409 nx_strncpy(m_pPushParamList[m_iNumPushParams].name, name, MAX_PARAM_NAME - 1);
410 m_pPushParamList[m_iNumPushParams].dataType = dataType;
411 nx_strncpy(m_pPushParamList[m_iNumPushParams].description, description, MAX_DB_STRING);
412 m_iNumPushParams++;
413 }
414 }
415
416 /**
417 * Add parameter to list
418 */
419 void AddParameter(const TCHAR *pszName, LONG (* fpHandler)(const TCHAR *, const TCHAR *, TCHAR *, AbstractCommSession *), const TCHAR *pArg,
420 int iDataType, const TCHAR *pszDescription)
421 {
422 int i;
423
424 // Search for existing parameter
425 for(i = 0; i < m_iNumParams; i++)
426 if (!_tcsicmp(m_pParamList[i].name, pszName))
427 break;
428 if (i < m_iNumParams)
429 {
430 // Replace existing handler and attributes
431 m_pParamList[i].handler = fpHandler;
432 m_pParamList[i].dataType = iDataType;
433 nx_strncpy(m_pParamList[i].description, pszDescription, MAX_DB_STRING);
434
435 // If we are replacing System.PlatformName, add pointer to
436 // platform suffix as argument, otherwise, use supplied pArg
437 if (!_tcscmp(pszName, _T("System.PlatformName")))
438 {
439 m_pParamList[i].arg = g_szPlatformSuffix; // to be TCHAR
440 }
441 else
442 {
443 m_pParamList[i].arg = pArg;
444 }
445 }
446 else
447 {
448 // Add new parameter
449 m_pParamList = (NETXMS_SUBAGENT_PARAM *)realloc(m_pParamList, sizeof(NETXMS_SUBAGENT_PARAM) * (m_iNumParams + 1));
450 nx_strncpy(m_pParamList[m_iNumParams].name, pszName, MAX_PARAM_NAME - 1);
451 m_pParamList[m_iNumParams].handler = fpHandler;
452 m_pParamList[m_iNumParams].arg = pArg;
453 m_pParamList[m_iNumParams].dataType = iDataType;
454 nx_strncpy(m_pParamList[m_iNumParams].description, pszDescription, MAX_DB_STRING);
455 m_iNumParams++;
456 }
457 }
458
459 /**
460 * Add list
461 */
462 void AddList(const TCHAR *name, LONG (* handler)(const TCHAR *, const TCHAR *, StringList *, AbstractCommSession *), const TCHAR *arg)
463 {
464 int i;
465
466 // Search for existing enum
467 for(i = 0; i < m_iNumEnums; i++)
468 if (!_tcsicmp(m_pEnumList[i].name, name))
469 break;
470 if (i < m_iNumEnums)
471 {
472 // Replace existing handler and arg
473 m_pEnumList[i].handler = handler;
474 m_pEnumList[i].arg = arg;
475 }
476 else
477 {
478 // Add new enum
479 m_pEnumList = (NETXMS_SUBAGENT_LIST *)realloc(m_pEnumList, sizeof(NETXMS_SUBAGENT_LIST) * (m_iNumEnums + 1));
480 nx_strncpy(m_pEnumList[m_iNumEnums].name, name, MAX_PARAM_NAME - 1);
481 m_pEnumList[m_iNumEnums].handler = handler;
482 m_pEnumList[m_iNumEnums].arg = arg;
483 m_iNumEnums++;
484 }
485 }
486
487 /**
488 * Add table
489 */
490 void AddTable(const TCHAR *name, LONG (* handler)(const TCHAR *, const TCHAR *, Table *, AbstractCommSession *), const TCHAR *arg,
491 const TCHAR *instanceColumns, const TCHAR *description, int numColumns, NETXMS_SUBAGENT_TABLE_COLUMN *columns)
492 {
493 int i;
494
495 // Search for existing table
496 for(i = 0; i < m_iNumTables; i++)
497 if (!_tcsicmp(m_pTableList[i].name, name))
498 break;
499 if (i < m_iNumTables)
500 {
501 // Replace existing handler and arg
502 m_pTableList[i].handler = handler;
503 m_pTableList[i].arg = arg;
504 nx_strncpy(m_pTableList[m_iNumTables].instanceColumns, instanceColumns, MAX_COLUMN_NAME * MAX_INSTANCE_COLUMNS);
505 nx_strncpy(m_pTableList[m_iNumTables].description, description, MAX_DB_STRING);
506 m_pTableList[i].numColumns = numColumns;
507 m_pTableList[i].columns = columns;
508 }
509 else
510 {
511 // Add new table
512 m_pTableList = (NETXMS_SUBAGENT_TABLE *)realloc(m_pTableList, sizeof(NETXMS_SUBAGENT_TABLE) * (m_iNumTables + 1));
513 nx_strncpy(m_pTableList[m_iNumTables].name, name, MAX_PARAM_NAME);
514 m_pTableList[m_iNumTables].handler = handler;
515 m_pTableList[m_iNumTables].arg = arg;
516 nx_strncpy(m_pTableList[m_iNumTables].instanceColumns, instanceColumns, MAX_COLUMN_NAME * MAX_INSTANCE_COLUMNS);
517 nx_strncpy(m_pTableList[m_iNumTables].description, description, MAX_DB_STRING);
518 m_pTableList[m_iNumTables].numColumns = numColumns;
519 m_pTableList[m_iNumTables].columns = columns;
520 m_iNumTables++;
521 }
522 }
523
524 /**
525 * Add external parameter
526 */
527 BOOL AddExternalParameter(TCHAR *pszCfgLine, BOOL bShellExec, BOOL bIsList) //to be TCHAR
528 {
529 TCHAR *pszCmdLine, *pszArg;
530
531 pszCmdLine = _tcschr(pszCfgLine, _T(':'));
532 if (pszCmdLine == NULL)
533 return FALSE;
534
535 *pszCmdLine = 0;
536 pszCmdLine++;
537 StrStrip(pszCfgLine);
538 StrStrip(pszCmdLine);
539 if ((*pszCfgLine == 0) || (*pszCmdLine == 0))
540 return FALSE;
541
542 pszArg = (TCHAR *)malloc((_tcslen(pszCmdLine) + 2) * sizeof(TCHAR));
543 pszArg[0] = bShellExec ? _T('S') : _T('E');
544 _tcscpy(&pszArg[1], pszCmdLine);
545 if (bIsList)
546 {
547 AddList(pszCfgLine, H_ExternalList, pszArg);
548 }
549 else
550 {
551 AddParameter(pszCfgLine, H_ExternalParameter, pszArg, DCI_DT_STRING, _T(""));
552 }
553 return TRUE;
554 }
555
556 /**
557 * Get parameter's value
558 */
559 UINT32 GetParameterValue(UINT32 sessionId, const TCHAR *param, TCHAR *value, AbstractCommSession *session)
560 {
561 int i, rc;
562 UINT32 dwErrorCode;
563
564 DebugPrintf(sessionId, 5, _T("Requesting parameter \"%s\""), param);
565 for(i = 0; i < m_iNumParams; i++)
566 {
567 if (MatchString(m_pParamList[i].name, param, FALSE))
568 {
569 rc = m_pParamList[i].handler(param, m_pParamList[i].arg, value, session);
570 switch(rc)
571 {
572 case SYSINFO_RC_SUCCESS:
573 dwErrorCode = ERR_SUCCESS;
574 m_dwProcessedRequests++;
575 break;
576 case SYSINFO_RC_ERROR:
577 dwErrorCode = ERR_INTERNAL_ERROR;
578 m_dwFailedRequests++;
579 break;
580 case SYSINFO_RC_NO_SUCH_INSTANCE:
581 dwErrorCode = ERR_NO_SUCH_INSTANCE;
582 m_dwFailedRequests++;
583 break;
584 case SYSINFO_RC_UNSUPPORTED:
585 dwErrorCode = ERR_UNKNOWN_PARAMETER;
586 m_dwUnsupportedRequests++;
587 break;
588 default:
589 nxlog_write(MSG_UNEXPECTED_IRC, EVENTLOG_ERROR_TYPE, "ds", rc, param);
590 dwErrorCode = ERR_INTERNAL_ERROR;
591 m_dwFailedRequests++;
592 break;
593 }
594 break;
595 }
596 }
597
598 if (i == m_iNumParams)
599 {
600 rc = GetParameterValueFromExtProvider(param, value);
601 if (rc == SYSINFO_RC_SUCCESS)
602 {
603 dwErrorCode = ERR_SUCCESS;
604 m_dwProcessedRequests++;
605 }
606 else
607 {
608 dwErrorCode = ERR_UNKNOWN_PARAMETER;
609 }
610 }
611
612 if ((dwErrorCode == ERR_UNKNOWN_PARAMETER) && (i == m_iNumParams))
613 {
614 dwErrorCode = GetParameterValueFromAppAgent(param, value);
615 if (dwErrorCode == ERR_SUCCESS)
616 {
617 m_dwProcessedRequests++;
618 }
619 else if (dwErrorCode != ERR_UNKNOWN_PARAMETER)
620 {
621 m_dwFailedRequests++;
622 }
623 }
624
625 if ((dwErrorCode == ERR_UNKNOWN_PARAMETER) && (i == m_iNumParams))
626 {
627 dwErrorCode = GetParameterValueFromExtSubagent(param, value);
628 if (dwErrorCode == ERR_SUCCESS)
629 {
630 m_dwProcessedRequests++;
631 }
632 else if (dwErrorCode == ERR_UNKNOWN_PARAMETER)
633 {
634 m_dwUnsupportedRequests++;
635 }
636 else
637 {
638 m_dwFailedRequests++;
639 }
640 }
641
642 DebugPrintf(sessionId, 7, _T("GetParameterValue(): result is %d (%s)"), (int)dwErrorCode,
643 dwErrorCode == ERR_SUCCESS ? _T("SUCCESS") : (dwErrorCode == ERR_UNKNOWN_PARAMETER ? _T("UNKNOWN_PARAMETER") : _T("INTERNAL_ERROR")));
644 return dwErrorCode;
645 }
646
647 /**
648 * Get list's value
649 */
650 UINT32 GetListValue(UINT32 sessionId, const TCHAR *param, StringList *value, AbstractCommSession *session)
651 {
652 int i, rc;
653 UINT32 dwErrorCode;
654
655 DebugPrintf(sessionId, 5, _T("Requesting list \"%s\""), param);
656 for(i = 0; i < m_iNumEnums; i++)
657 {
658 if (MatchString(m_pEnumList[i].name, param, FALSE))
659 {
660 rc = m_pEnumList[i].handler(param, m_pEnumList[i].arg, value, session);
661 switch(rc)
662 {
663 case SYSINFO_RC_SUCCESS:
664 dwErrorCode = ERR_SUCCESS;
665 m_dwProcessedRequests++;
666 break;
667 case SYSINFO_RC_ERROR:
668 dwErrorCode = ERR_INTERNAL_ERROR;
669 m_dwFailedRequests++;
670 break;
671 case SYSINFO_RC_NO_SUCH_INSTANCE:
672 dwErrorCode = ERR_NO_SUCH_INSTANCE;
673 m_dwFailedRequests++;
674 break;
675 case SYSINFO_RC_UNSUPPORTED:
676 dwErrorCode = ERR_UNKNOWN_PARAMETER;
677 m_dwUnsupportedRequests++;
678 break;
679 default:
680 nxlog_write(MSG_UNEXPECTED_IRC, EVENTLOG_ERROR_TYPE, "ds", rc, param);
681 dwErrorCode = ERR_INTERNAL_ERROR;
682 m_dwFailedRequests++;
683 break;
684 }
685 break;
686 }
687 }
688
689 if (i == m_iNumEnums)
690 {
691 dwErrorCode = GetListValueFromExtSubagent(param, value);
692 if (dwErrorCode == ERR_SUCCESS)
693 {
694 m_dwProcessedRequests++;
695 }
696 else if (dwErrorCode == ERR_UNKNOWN_PARAMETER)
697 {
698 m_dwUnsupportedRequests++;
699 }
700 else
701 {
702 m_dwFailedRequests++;
703 }
704 }
705
706 DebugPrintf(sessionId, 7, _T("GetListValue(): result is %d (%s)"), (int)dwErrorCode,
707 dwErrorCode == ERR_SUCCESS ? _T("SUCCESS") : (dwErrorCode == ERR_UNKNOWN_PARAMETER ? _T("UNKNOWN_PARAMETER") : _T("INTERNAL_ERROR")));
708 return dwErrorCode;
709 }
710
711 /**
712 * Get table's value
713 */
714 UINT32 GetTableValue(UINT32 sessionId, const TCHAR *param, Table *value, AbstractCommSession *session)
715 {
716 int i, rc;
717 UINT32 dwErrorCode;
718
719 DebugPrintf(sessionId, 5, _T("Requesting table \"%s\""), param);
720 for(i = 0; i < m_iNumTables; i++)
721 {
722 if (MatchString(m_pTableList[i].name, param, FALSE))
723 {
724 // pre-fill table columns if specified in table definition
725 if (m_pTableList[i].numColumns > 0)
726 {
727 for(int c = 0; c < m_pTableList[i].numColumns; c++)
728 {
729 NETXMS_SUBAGENT_TABLE_COLUMN *col = &m_pTableList[i].columns[c];
730 value->addColumn(col->name, col->dataType, col->displayName, col->isInstance);
731 }
732 }
733
734 rc = m_pTableList[i].handler(param, m_pTableList[i].arg, value, session);
735 switch(rc)
736 {
737 case SYSINFO_RC_SUCCESS:
738 dwErrorCode = ERR_SUCCESS;
739 m_dwProcessedRequests++;
740 break;
741 case SYSINFO_RC_ERROR:
742 dwErrorCode = ERR_INTERNAL_ERROR;
743 m_dwFailedRequests++;
744 break;
745 case SYSINFO_RC_NO_SUCH_INSTANCE:
746 dwErrorCode = ERR_NO_SUCH_INSTANCE;
747 m_dwFailedRequests++;
748 break;
749 case SYSINFO_RC_UNSUPPORTED:
750 dwErrorCode = ERR_UNKNOWN_PARAMETER;
751 m_dwUnsupportedRequests++;
752 break;
753 default:
754 nxlog_write(MSG_UNEXPECTED_IRC, EVENTLOG_ERROR_TYPE, "ds", rc, param);
755 dwErrorCode = ERR_INTERNAL_ERROR;
756 m_dwFailedRequests++;
757 break;
758 }
759 break;
760 }
761 }
762
763 if (i == m_iNumTables)
764 {
765 dwErrorCode = GetTableValueFromExtSubagent(param, value);
766 if (dwErrorCode == ERR_SUCCESS)
767 {
768 m_dwProcessedRequests++;
769 }
770 else if (dwErrorCode == ERR_UNKNOWN_PARAMETER)
771 {
772 m_dwUnsupportedRequests++;
773 }
774 else
775 {
776 m_dwFailedRequests++;
777 }
778 }
779
780 DebugPrintf(sessionId, 7, _T("GetTableValue(): result is %d (%s)"), (int)dwErrorCode,
781 dwErrorCode == ERR_SUCCESS ? _T("SUCCESS") : (dwErrorCode == ERR_UNKNOWN_PARAMETER ? _T("UNKNOWN_PARAMETER") : _T("INTERNAL_ERROR")));
782 return dwErrorCode;
783 }
784
785 /**
786 * Put complete list of supported parameters into NXCP message
787 */
788 void GetParameterList(NXCPMessage *pMsg)
789 {
790 int i;
791 UINT32 dwId, count;
792
793 // Parameters
794 for(i = 0, count = 0, dwId = VID_PARAM_LIST_BASE; i < m_iNumParams; i++)
795 {
796 if (m_pParamList[i].dataType != DCI_DT_DEPRECATED)
797 {
798 pMsg->setField(dwId++, m_pParamList[i].name);
799 pMsg->setField(dwId++, m_pParamList[i].description);
800 pMsg->setField(dwId++, (WORD)m_pParamList[i].dataType);
801 count++;
802 }
803 }
804 ListParametersFromExtProviders(pMsg, &dwId, &count);
805 ListParametersFromExtSubagents(pMsg, &dwId, &count);
806 pMsg->setField(VID_NUM_PARAMETERS, count);
807
808 // Push parameters
809 pMsg->setField(VID_NUM_PUSH_PARAMETERS, (UINT32)m_iNumPushParams);
810 for(i = 0, dwId = VID_PUSHPARAM_LIST_BASE; i < m_iNumPushParams; i++)
811 {
812 pMsg->setField(dwId++, m_pPushParamList[i].name);
813 pMsg->setField(dwId++, m_pPushParamList[i].description);
814 pMsg->setField(dwId++, (WORD)m_pPushParamList[i].dataType);
815 }
816
817 // Lists
818 pMsg->setField(VID_NUM_ENUMS, (UINT32)m_iNumEnums);
819 for(i = 0, dwId = VID_ENUM_LIST_BASE; i < m_iNumEnums; i++)
820 {
821 pMsg->setField(dwId++, m_pEnumList[i].name);
822 }
823 ListListsFromExtSubagents(pMsg, &dwId, &count);
824
825 // Tables
826 pMsg->setField(VID_NUM_TABLES, (UINT32)m_iNumTables);
827 for(i = 0, dwId = VID_TABLE_LIST_BASE; i < m_iNumTables; i++)
828 {
829 pMsg->setField(dwId++, m_pTableList[i].name);
830 pMsg->setField(dwId++, m_pTableList[i].instanceColumns);
831 pMsg->setField(dwId++, m_pTableList[i].description);
832 }
833 ListTablesFromExtSubagents(pMsg, &dwId, &count);
834 }
835
836 /**
837 * Put list of supported tables into NXCP message
838 */
839 void GetTableList(NXCPMessage *pMsg)
840 {
841 int i;
842 UINT32 dwId, count;
843
844 pMsg->setField(VID_NUM_TABLES, (UINT32)m_iNumTables);
845 for(i = 0, dwId = VID_TABLE_LIST_BASE; i < m_iNumTables; i++)
846 {
847 pMsg->setField(dwId++, m_pTableList[i].name);
848 pMsg->setField(dwId++, m_pTableList[i].instanceColumns);
849 pMsg->setField(dwId++, m_pTableList[i].description);
850 }
851 ListTablesFromExtSubagents(pMsg, &dwId, &count);
852 }
853
854 /**
855 * Put list of supported lists (enums) into NXCP message
856 */
857 void GetEnumList(NXCPMessage *pMsg)
858 {
859 int i;
860 UINT32 dwId, count;
861
862 pMsg->setField(VID_NUM_ENUMS, (UINT32)m_iNumEnums);
863 for(i = 0, dwId = VID_ENUM_LIST_BASE; i < m_iNumEnums; i++)
864 {
865 pMsg->setField(dwId++, m_pEnumList[i].name);
866 }
867 ListListsFromExtSubagents(pMsg, &dwId, &count);
868 }