Some descriptions changed
[public/netxms.git] / src / agent / core / getparam.cpp
CommitLineData
e7474978
VK
1/*
2** NetXMS multiplatform core agent
3** Copyright (C) 2003, 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: getparam.cpp
20**
21**/
22
23#include "nxagentd.h"
24
25
26//
27// Externals
28//
29
30LONG H_AgentStats(char *cmd, char *arg, char *value);
31LONG H_AgentUptime(char *cmd, char *arg, char *value);
32LONG H_CRC32(char *cmd, char *arg, char *value);
33LONG H_FileSize(char *cmd, char *arg, char *value);
bb722c91 34LONG H_FileCount(char *pszCmd, char *pszArg, char *pValue);
e7474978
VK
35LONG H_MD5Hash(char *cmd, char *arg, char *value);
36LONG H_SHA1Hash(char *cmd, char *arg, char *value);
901c96c7 37LONG H_SubAgentList(char *cmd, char *arg, NETXMS_VALUES_LIST *value);
3c774461 38LONG H_ActionList(char *cmd, char *arg, NETXMS_VALUES_LIST *value);
21a2454a 39LONG H_ExternalParameter(char *pszCmd, char *pszArg, char *pValue);
d558abc4 40LONG H_PlatformName(char *cmd, char *arg, char *value);
dc0e93b4 41
901c96c7
VK
42#ifdef _WIN32
43LONG H_ArpCache(char *cmd, char *arg, NETXMS_VALUES_LIST *value);
44LONG H_InterfaceList(char *cmd, char *arg, NETXMS_VALUES_LIST *value);
c2a9af16 45LONG H_ProcessList(char *cmd, char *arg, NETXMS_VALUES_LIST *value);
dc0e93b4
VK
46LONG H_ProcCount(char *cmd, char *arg, char *value);
47LONG H_ProcCountSpecific(char *cmd, char *arg, char *value);
48LONG H_ProcInfo(char *cmd, char *arg, char *value);
49LONG H_DiskInfo(char *cmd, char *arg, char *value);
50LONG H_MemoryInfo(char *cmd, char *arg, char *value);
51LONG H_HostName(char *cmd, char *arg, char *value);
52LONG H_SystemUname(char *cmd, char *arg, char *value);
53LONG H_ThreadCount(char *cmd, char *arg, char *value);
6849d9be
VK
54LONG H_NetIPStats(char *cmd, char *arg, char *value);
55LONG H_NetInterfaceStats(char *cmd, char *arg, char *value);
38f733bb 56LONG H_ServiceState(char *cmd, char *arg, char *value);
c2a9af16 57LONG H_CPUCount(char *cmd, char *arg, char *value);
901c96c7
VK
58#endif
59
e7474978
VK
60
61//
62// Static data
63//
64
a72a1fb1 65static NETXMS_SUBAGENT_PARAM *m_pParamList = NULL;
e7474978 66static int m_iNumParams = 0;
901c96c7
VK
67static NETXMS_SUBAGENT_ENUM *m_pEnumList = NULL;
68static int m_iNumEnums = 0;
e7474978 69static DWORD m_dwTimedOutRequests = 0;
e7474978
VK
70static DWORD m_dwAuthenticationFailures = 0;
71static DWORD m_dwProcessedRequests = 0;
72static DWORD m_dwFailedRequests = 0;
73static DWORD m_dwUnsupportedRequests = 0;
74
75
76//
77// Handler for parameters which always returns string constant
78//
79
80static LONG H_StringConstant(char *cmd, char *arg, char *value)
81{
82 ret_string(value, arg);
83 return SYSINFO_RC_SUCCESS;
84}
85
86
87//
88// Handler for parameters which returns floating point value from specific variable
89//
90
91static LONG H_FloatPtr(char *cmd, char *arg, char *value)
92{
93 ret_double(value, *((double *)arg));
94 return SYSINFO_RC_SUCCESS;
95}
96
97
98//
99// Handler for parameters which returns DWORD value from specific variable
100//
101
102static LONG H_UIntPtr(char *cmd, char *arg, char *value)
103{
104 ret_uint(value, *((DWORD *)arg));
105 return SYSINFO_RC_SUCCESS;
106}
107
108
901c96c7
VK
109//
110// Handler for parameters list
111//
112
113static LONG H_ParamList(char *cmd, char *arg, NETXMS_VALUES_LIST *value)
114{
115 int i;
116
117 for(i = 0; i < m_iNumParams; i++)
a72a1fb1 118 NxAddResultString(value, m_pParamList[i].szName);
901c96c7
VK
119 return SYSINFO_RC_SUCCESS;
120}
121
122
123//
124// Handler for enums list
125//
126
127static LONG H_EnumList(char *cmd, char *arg, NETXMS_VALUES_LIST *value)
128{
129 int i;
130
131 for(i = 0; i < m_iNumEnums; i++)
132 NxAddResultString(value, m_pEnumList[i].szName);
133 return SYSINFO_RC_SUCCESS;
134}
135
136
e7474978
VK
137//
138// Standard agent's parameters
139//
140
a72a1fb1 141static NETXMS_SUBAGENT_PARAM m_stdParams[] =
e7474978 142{
dc0e93b4 143#ifdef _WIN32
a72a1fb1
VK
144 { "Disk.Free(*)", H_DiskInfo, NULL, DCI_DT_UINT64, "Free disk space on *" },
145 { "Disk.Total(*)", H_DiskInfo, NULL, DCI_DT_UINT64, "Total disk space on *" },
125c0e81 146 { "Disk.Used(*)", H_DiskInfo, NULL, DCI_DT_UINT64, "Used disk space on *" },
954e730f 147 { "Net.Interface.AdminStatus(*)", H_NetInterfaceStats, (char *)NET_IF_ADMIN_STATUS, DCI_DT_INT, "Administrative status of interface {instance}" },
be4a0185
VK
148 { "Net.Interface.BytesIn(*)", H_NetInterfaceStats, (char *)NET_IF_BYTES_IN, DCI_DT_UINT, "Number of input bytes on interface {instance}" },
149 { "Net.Interface.BytesOut(*)", H_NetInterfaceStats, (char *)NET_IF_BYTES_OUT, DCI_DT_UINT, "Number of output bytes on interface {instance}" },
a72a1fb1 150 { "Net.Interface.Description(*)", H_NetInterfaceStats, (char *)NET_IF_DESCR, DCI_DT_STRING, "" },
be4a0185
VK
151 { "Net.Interface.InErrors(*)", H_NetInterfaceStats, (char *)NET_IF_IN_ERRORS, DCI_DT_UINT, "Number of input errors on interface {instance}" },
152 { "Net.Interface.Link(*)", H_NetInterfaceStats, (char *)NET_IF_LINK, DCI_DT_INT, "Link status for interface {instance}" },
153 { "Net.Interface.OutErrors(*)", H_NetInterfaceStats, (char *)NET_IF_OUT_ERRORS, DCI_DT_UINT, "Number of output errors on interface {instance}" },
154 { "Net.Interface.PacketsIn(*)", H_NetInterfaceStats, (char *)NET_IF_PACKETS_IN, DCI_DT_UINT, "Number of input packets on interface {instance}" },
155 { "Net.Interface.PacketsOut(*)", H_NetInterfaceStats, (char *)NET_IF_PACKETS_OUT, DCI_DT_UINT, "Number of output packets on interface {instance}" },
156 { "Net.Interface.Speed(*)", H_NetInterfaceStats, (char *)NET_IF_SPEED, DCI_DT_UINT, "Speed of interface {instance}" },
a72a1fb1
VK
157 { "Net.IP.Forwarding", H_NetIPStats, (char *)NET_IP_FORWARDING, DCI_DT_INT, "IP forwarding status" },
158 { "Process.Count(*)", H_ProcCountSpecific, NULL, DCI_DT_UINT, "" },
159 { "Process.GdiObj(*)", H_ProcInfo, (char *)PROCINFO_GDI_OBJ, DCI_DT_UINT64, "" },
160 { "Process.IO.OtherB(*)", H_ProcInfo, (char *)PROCINFO_IO_OTHER_B, DCI_DT_UINT64, "" },
161 { "Process.IO.OtherOp(*)", H_ProcInfo, (char *)PROCINFO_IO_OTHER_OP, DCI_DT_UINT64, "" },
162 { "Process.IO.ReadB(*)", H_ProcInfo, (char *)PROCINFO_IO_READ_B, DCI_DT_UINT64, "" },
163 { "Process.IO.ReadOp(*)", H_ProcInfo, (char *)PROCINFO_IO_READ_OP, DCI_DT_UINT64, "" },
164 { "Process.IO.WriteB(*)", H_ProcInfo, (char *)PROCINFO_IO_WRITE_B, DCI_DT_UINT64, "" },
165 { "Process.IO.WriteOp(*)", H_ProcInfo, (char *)PROCINFO_IO_WRITE_OP, DCI_DT_UINT64, "" },
166 { "Process.KernelTime(*)", H_ProcInfo, (char *)PROCINFO_KTIME, DCI_DT_UINT64, "" },
167 { "Process.PageFaults(*)", H_ProcInfo, (char *)PROCINFO_PF, DCI_DT_UINT64, "" },
168 { "Process.UserObj(*)", H_ProcInfo, (char *)PROCINFO_USER_OBJ, DCI_DT_UINT64, "" },
169 { "Process.UserTime(*)", H_ProcInfo, (char *)PROCINFO_UTIME, DCI_DT_UINT64, "" },
170 { "Process.VMSize(*)", H_ProcInfo, (char *)PROCINFO_VMSIZE, DCI_DT_UINT64, "" },
171 { "Process.WkSet(*)", H_ProcInfo, (char *)PROCINFO_WKSET, DCI_DT_UINT64, "" },
172 { "System.CPU.Count", H_CPUCount, NULL, DCI_DT_UINT, "Number of CPU in the system" },
173 { "System.Hostname", H_HostName, NULL, DCI_DT_STRING, "Host name" },
174 { "System.Memory.Physical.Free", H_MemoryInfo, (char *)MEMINFO_PHYSICAL_FREE, DCI_DT_UINT64, "Free physical memory" },
175 { "System.Memory.Physical.Total", H_MemoryInfo, (char *)MEMINFO_PHYSICAL_TOTAL, DCI_DT_UINT64, "Total amount of physical memory" },
176 { "System.Memory.Physical.Used", H_MemoryInfo, (char *)MEMINFO_PHYSICAL_USED, DCI_DT_UINT64, "Used physical memory" },
177 { "System.Memory.Swap.Free", H_MemoryInfo, (char *)MEMINFO_SWAP_FREE, DCI_DT_UINT64, "Free swap space" },
178 { "System.Memory.Swap.Total", H_MemoryInfo, (char *)MEMINFO_SWAP_TOTAL, DCI_DT_UINT64, "Total amount of swap space" },
179 { "System.Memory.Swap.Used", H_MemoryInfo, (char *)MEMINFO_SWAP_USED, DCI_DT_UINT64, "Used swap space" },
180 { "System.Memory.Virtual.Free", H_MemoryInfo, (char *)MEMINFO_VIRTUAL_FREE, DCI_DT_UINT64, "Free virtual memory" },
181 { "System.Memory.Virtual.Total", H_MemoryInfo, (char *)MEMINFO_VIRTUAL_TOTAL, DCI_DT_UINT64, "Total amount of virtual memory" },
182 { "System.Memory.Virtual.Used", H_MemoryInfo, (char *)MEMINFO_VIRTUAL_USED, DCI_DT_UINT64, "Used virtual memory" },
183 { "System.ProcessCount", H_ProcCount, NULL, DCI_DT_INT, "Total number of processes" },
18f8db9b 184 { "System.ServiceState(*)", H_ServiceState, NULL, DCI_DT_INT, "State of {instance} service" },
a72a1fb1
VK
185 { "System.ThreadCount", H_ThreadCount, NULL, DCI_DT_INT, "Total number of threads" },
186 { "System.Uname", H_SystemUname, NULL, DCI_DT_STRING, "System uname" },
dc0e93b4 187#endif
a72a1fb1
VK
188 { "Agent.AcceptedConnections", H_UIntPtr, (char *)&g_dwAcceptedConnections, DCI_DT_UINT, "" },
189 { "Agent.AcceptErrors", H_UIntPtr, (char *)&g_dwAcceptErrors, DCI_DT_UINT, "" },
190 { "Agent.AuthenticationFailures", H_UIntPtr, (char *)&m_dwAuthenticationFailures, DCI_DT_UINT, "" },
191 { "Agent.FailedRequests", H_UIntPtr, (char *)&m_dwFailedRequests, DCI_DT_UINT, "" },
192 { "Agent.ProcessedRequests", H_UIntPtr, (char *)&m_dwProcessedRequests, DCI_DT_UINT, "" },
193 { "Agent.RejectedConnections", H_UIntPtr, (char *)&g_dwRejectedConnections, DCI_DT_UINT, "" },
194 { "Agent.SourcePackageSupport", H_StringConstant, "0", DCI_DT_INT, "" },
195 { "Agent.TimedOutRequests", H_UIntPtr, (char *)&m_dwTimedOutRequests, DCI_DT_UINT, "" },
196 { "Agent.UnsupportedRequests", H_UIntPtr, (char *)&m_dwUnsupportedRequests, DCI_DT_UINT, "" },
197 { "Agent.Uptime", H_AgentUptime, NULL, DCI_DT_UINT, "Agent's uptime" },
198 { "Agent.Version", H_StringConstant, AGENT_VERSION_STRING, DCI_DT_STRING, "Agent's version" },
199 { "File.Count(*)", H_FileCount, NULL, DCI_DT_UINT, "" },
e3846581
VK
200 { "File.Hash.CRC32(*)", H_CRC32, NULL, DCI_DT_UINT, "CRC32 checksum of *" },
201 { "File.Hash.MD5(*)", H_MD5Hash, NULL, DCI_DT_STRING, "MD5 has of *" },
202 { "File.Hash.SHA1(*)", H_SHA1Hash, NULL, DCI_DT_STRING, "SHA1 hash of *" },
a72a1fb1
VK
203 { "File.Size(*)", H_FileSize, NULL, DCI_DT_UINT64, "" },
204 { "System.PlatformName", H_PlatformName, NULL, DCI_DT_STRING, "" }
e7474978
VK
205};
206
207
901c96c7
VK
208//
209// Standard agent's enumerations
210//
211
212static NETXMS_SUBAGENT_ENUM m_stdEnums[] =
213{
214#ifdef _WIN32
6849d9be
VK
215 { "Net.ArpCache", H_ArpCache, NULL },
216 { "Net.InterfaceList", H_InterfaceList, NULL },
c2a9af16 217 { "System.ProcessList", H_ProcessList, NULL },
901c96c7 218#endif
c2a9af16 219 { "Agent.ActionList", H_ActionList, NULL },
6849d9be
VK
220 { "Agent.SubAgentList", H_SubAgentList, NULL },
221 { "Agent.SupportedEnums", H_EnumList, NULL },
222 { "Agent.SupportedParameters", H_ParamList, NULL }
901c96c7
VK
223};
224
225
e7474978
VK
226//
227// Initialize dynamic parameters list from default static list
228//
229
230BOOL InitParameterList(void)
231{
901c96c7 232 if ((m_pParamList != NULL) || (m_pEnumList != NULL))
e7474978
VK
233 return FALSE;
234
a72a1fb1
VK
235 m_iNumParams = sizeof(m_stdParams) / sizeof(NETXMS_SUBAGENT_PARAM);
236 m_pParamList = (NETXMS_SUBAGENT_PARAM *)malloc(sizeof(NETXMS_SUBAGENT_PARAM) * m_iNumParams);
e7474978
VK
237 if (m_pParamList == NULL)
238 return FALSE;
a72a1fb1 239 memcpy(m_pParamList, m_stdParams, sizeof(NETXMS_SUBAGENT_PARAM) * m_iNumParams);
901c96c7
VK
240
241 m_iNumEnums = sizeof(m_stdEnums) / sizeof(NETXMS_SUBAGENT_ENUM);
242 m_pEnumList = (NETXMS_SUBAGENT_ENUM *)malloc(sizeof(NETXMS_SUBAGENT_ENUM) * m_iNumEnums);
243 if (m_pEnumList == NULL)
244 return FALSE;
245 memcpy(m_pEnumList, m_stdEnums, sizeof(NETXMS_SUBAGENT_ENUM) * m_iNumEnums);
246
e7474978
VK
247 return TRUE;
248}
249
250
251//
252// Add parameter to list
253//
254
125c0e81
VK
255void AddParameter(char *pszName, LONG (* fpHandler)(char *,char *,char *), char *pArg,
256 int iDataType, char *pszDescription)
e7474978 257{
19acf449
VK
258 int i;
259
260 // Search for existing parameter
261 for(i = 0; i < m_iNumParams; i++)
a72a1fb1 262 if (!stricmp(m_pParamList[i].szName, pszName))
19acf449
VK
263 break;
264 if (i < m_iNumParams)
265 {
125c0e81 266 // Replace existing handler and attributes
a72a1fb1 267 m_pParamList[i].fpHandler = fpHandler;
125c0e81
VK
268 m_pParamList[i].iDataType = iDataType;
269 strncpy(m_pParamList[i].szDescription, pszDescription, MAX_DB_STRING);
19acf449
VK
270
271 // If we are replacing System.PlatformName, add pointer to
272 // platform suffix as argument, otherwise, use supplied pArg
273 if (!strcmp(pszName, "System.PlatformName"))
274 {
a72a1fb1 275 m_pParamList[i].pArg = g_szPlatformSuffix;
19acf449
VK
276 }
277 else
278 {
a72a1fb1 279 m_pParamList[i].pArg = pArg;
19acf449
VK
280 }
281 }
282 else
283 {
284 // Add new parameter
a72a1fb1
VK
285 m_pParamList = (NETXMS_SUBAGENT_PARAM *)realloc(m_pParamList, sizeof(NETXMS_SUBAGENT_PARAM) * (m_iNumParams + 1));
286 strncpy(m_pParamList[m_iNumParams].szName, pszName, MAX_PARAM_NAME - 1);
287 m_pParamList[m_iNumParams].fpHandler = fpHandler;
288 m_pParamList[m_iNumParams].pArg = pArg;
125c0e81
VK
289 m_pParamList[m_iNumParams].iDataType = iDataType;
290 strncpy(m_pParamList[m_iNumParams].szDescription, pszDescription, MAX_DB_STRING);
19acf449
VK
291 m_iNumParams++;
292 }
e7474978
VK
293}
294
295
962b3915
VK
296//
297// Add enum to list
298//
299
19acf449 300void AddEnum(char *pszName, LONG (* fpHandler)(char *,char *,NETXMS_VALUES_LIST *), char *pArg)
962b3915 301{
19acf449
VK
302 int i;
303
304 // Search for existing enum
305 for(i = 0; i < m_iNumEnums; i++)
306 if (!stricmp(m_pEnumList[i].szName, pszName))
307 break;
308 if (i < m_iNumEnums)
309 {
310 // Replace existing handler and arg
311 m_pEnumList[i].fpHandler = fpHandler;
312 m_pEnumList[i].pArg = pArg;
313 }
314 else
315 {
316 // Add new enum
317 m_pEnumList = (NETXMS_SUBAGENT_ENUM *)realloc(m_pEnumList, sizeof(NETXMS_SUBAGENT_ENUM) * (m_iNumEnums + 1));
318 strncpy(m_pEnumList[m_iNumEnums].szName, pszName, MAX_PARAM_NAME - 1);
319 m_pEnumList[m_iNumEnums].fpHandler = fpHandler;
320 m_pEnumList[m_iNumEnums].pArg = pArg;
321 m_iNumEnums++;
322 }
962b3915
VK
323}
324
325
21a2454a
VK
326//
327// Add external parameter
328//
329
330BOOL AddExternalParameter(char *pszCfgLine)
331{
332 char *pszCmdLine;
333
334 pszCmdLine = strchr(pszCfgLine, ':');
335 if (pszCmdLine == NULL)
336 return FALSE;
337
338 *pszCmdLine = 0;
339 pszCmdLine++;
340 StrStrip(pszCfgLine);
341 StrStrip(pszCmdLine);
342 if ((*pszCfgLine == 0) || (*pszCmdLine == 0))
343 return FALSE;
344
125c0e81 345 AddParameter(pszCfgLine, H_ExternalParameter, strdup(pszCmdLine), DCI_DT_STRING, "");
21a2454a
VK
346 return TRUE;
347}
348
349
e7474978
VK
350//
351// Get parameter's value
352//
353
7c205c0c 354DWORD GetParameterValue(char *pszParam, char *pszValue)
e7474978
VK
355{
356 int i, rc;
7c205c0c 357 DWORD dwErrorCode;
e7474978 358
6082bd00 359 DebugPrintf("Requesting parameter \"%s\"", pszParam);
e7474978 360 for(i = 0; i < m_iNumParams; i++)
a72a1fb1 361 if (MatchString(m_pParamList[i].szName, pszParam, FALSE))
e7474978 362 {
a72a1fb1 363 rc = m_pParamList[i].fpHandler(pszParam, m_pParamList[i].pArg, pszValue);
e7474978
VK
364 switch(rc)
365 {
366 case SYSINFO_RC_SUCCESS:
7c205c0c 367 dwErrorCode = ERR_SUCCESS;
e7474978
VK
368 m_dwProcessedRequests++;
369 break;
370 case SYSINFO_RC_ERROR:
7c205c0c 371 dwErrorCode = ERR_INTERNAL_ERROR;
e7474978
VK
372 m_dwFailedRequests++;
373 break;
374 case SYSINFO_RC_UNSUPPORTED:
7c205c0c 375 dwErrorCode = ERR_UNKNOWN_PARAMETER;
e7474978
VK
376 m_dwUnsupportedRequests++;
377 break;
378 default:
7c205c0c
VK
379 WriteLog(MSG_UNEXPECTED_IRC, EVENTLOG_ERROR_TYPE, "ds", rc, pszParam);
380 dwErrorCode = ERR_INTERNAL_ERROR;
e7474978
VK
381 m_dwFailedRequests++;
382 break;
383 }
384 break;
385 }
386 if (i == m_iNumParams)
387 {
7c205c0c 388 dwErrorCode = ERR_UNKNOWN_PARAMETER;
e7474978
VK
389 m_dwUnsupportedRequests++;
390 }
7c205c0c 391 return dwErrorCode;
e7474978 392}
901c96c7
VK
393
394
395//
396// Get parameter's value
397//
398
399DWORD GetEnumValue(char *pszParam, NETXMS_VALUES_LIST *pValue)
400{
401 int i, rc;
402 DWORD dwErrorCode;
403
6082bd00 404 DebugPrintf("Requesting enum \"%s\"", pszParam);
901c96c7
VK
405 for(i = 0; i < m_iNumEnums; i++)
406 if (MatchString(m_pEnumList[i].szName, pszParam, FALSE))
407 {
408 rc = m_pEnumList[i].fpHandler(pszParam, m_pEnumList[i].pArg, pValue);
409 switch(rc)
410 {
411 case SYSINFO_RC_SUCCESS:
412 dwErrorCode = ERR_SUCCESS;
413 m_dwProcessedRequests++;
414 break;
415 case SYSINFO_RC_ERROR:
416 dwErrorCode = ERR_INTERNAL_ERROR;
417 m_dwFailedRequests++;
418 break;
419 case SYSINFO_RC_UNSUPPORTED:
420 dwErrorCode = ERR_UNKNOWN_PARAMETER;
421 m_dwUnsupportedRequests++;
422 break;
423 default:
424 WriteLog(MSG_UNEXPECTED_IRC, EVENTLOG_ERROR_TYPE, "ds", rc, pszParam);
425 dwErrorCode = ERR_INTERNAL_ERROR;
426 m_dwFailedRequests++;
427 break;
428 }
429 break;
430 }
431 if (i == m_iNumEnums)
432 {
433 dwErrorCode = ERR_UNKNOWN_PARAMETER;
434 m_dwUnsupportedRequests++;
435 }
436 return dwErrorCode;
437}
a72a1fb1
VK
438
439
440//
441// Put complete list of supported parameters into CSCP message
442//
443
444void GetParameterList(CSCPMessage *pMsg)
445{
446 int i;
447 DWORD dwId;
448
449 pMsg->SetVariable(VID_NUM_PARAMETERS, (DWORD)m_iNumParams);
450 for(i = 0, dwId = VID_PARAM_LIST_BASE; i < m_iNumParams; i++)
451 {
452 pMsg->SetVariable(dwId++, m_pParamList[i].szName);
453 pMsg->SetVariable(dwId++, m_pParamList[i].szDescription);
454 pMsg->SetVariable(dwId++, (WORD)m_pParamList[i].iDataType);
455 }
456}