2 ** NetXMS - Network Management System
4 ** Copyright (C) 2004, 2005, 2006, 2007, 2008 Victor Kirhenshtein
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2 of the License, or
9 ** (at your option) any later version.
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 void DestroyObject(NXC_OBJECT
*pObject
)
33 DebugPrintf(_T("DestroyObject(id:%d, name:\"%s\")"), pObject
->dwId
, pObject
->szName
);
34 switch(pObject
->iClass
)
36 case OBJECT_NETWORKSERVICE
:
37 safe_free(pObject
->netsrv
.pszRequest
);
38 safe_free(pObject
->netsrv
.pszResponse
);
41 safe_free(pObject
->zone
.pdwAddrList
);
43 case OBJECT_VPNCONNECTOR
:
44 safe_free(pObject
->vpnc
.pLocalNetList
);
45 safe_free(pObject
->vpnc
.pRemoteNetList
);
47 case OBJECT_CONDITION
:
48 safe_free(pObject
->cond
.pszScript
);
49 safe_free(pObject
->cond
.pDCIList
);
52 safe_free(pObject
->cluster
.pSyncNetList
);
53 safe_free(pObject
->cluster
.pResourceList
);
56 safe_free(pObject
->pdwChildList
);
57 safe_free(pObject
->pdwParentList
);
58 safe_free(pObject
->pAccessList
);
59 safe_free(pObject
->pszComments
);
60 safe_free(pObject
->pdwTrustedNodes
);
61 delete pObject
->pCustomAttrs
;
67 // Perform binary search on index
68 // Returns INVALID_INDEX if key not found or position of appropriate network object
69 // We assume that pIndex == NULL will not be passed
72 static DWORD
SearchIndex(INDEX
*pIndex
, DWORD dwIndexSize
, DWORD dwKey
)
74 DWORD dwFirst
, dwLast
, dwMid
;
80 dwLast
= dwIndexSize
- 1;
82 if ((dwKey
< pIndex
[0].dwKey
) || (dwKey
> pIndex
[dwLast
].dwKey
))
85 while(dwFirst
< dwLast
)
87 dwMid
= (dwFirst
+ dwLast
) / 2;
88 if (dwKey
== pIndex
[dwMid
].dwKey
)
90 if (dwKey
< pIndex
[dwMid
].dwKey
)
96 if (dwKey
== pIndex
[dwLast
].dwKey
)
104 // Index comparision callback for qsort()
107 static int IndexCompare(const void *pArg1
, const void *pArg2
)
109 return ((INDEX
*)pArg1
)->dwKey
< ((INDEX
*)pArg2
)->dwKey
? -1 :
110 (((INDEX
*)pArg1
)->dwKey
> ((INDEX
*)pArg2
)->dwKey
? 1 : 0);
115 // Add object to list
118 void NXCL_Session::AddObject(NXC_OBJECT
*pObject
, BOOL bSortIndex
)
120 DebugPrintf(_T("AddObject(id:%d, name:\"%s\")"), pObject
->dwId
, pObject
->szName
);
122 m_pIndexById
= (INDEX
*)realloc(m_pIndexById
, sizeof(INDEX
) * (m_dwNumObjects
+ 1));
123 m_pIndexById
[m_dwNumObjects
].dwKey
= pObject
->dwId
;
124 m_pIndexById
[m_dwNumObjects
].pObject
= pObject
;
127 qsort(m_pIndexById
, m_dwNumObjects
, sizeof(INDEX
), IndexCompare
);
133 // Replace object's data in list
136 static void ReplaceObject(NXC_OBJECT
*pObject
, NXC_OBJECT
*pNewObject
)
138 DebugPrintf(_T("ReplaceObject(id:%d, name:\"%s\")"), pObject
->dwId
, pObject
->szName
);
139 switch(pObject
->iClass
)
141 case OBJECT_NETWORKSERVICE
:
142 safe_free(pObject
->netsrv
.pszRequest
);
143 safe_free(pObject
->netsrv
.pszResponse
);
146 safe_free(pObject
->zone
.pdwAddrList
);
148 case OBJECT_VPNCONNECTOR
:
149 safe_free(pObject
->vpnc
.pLocalNetList
);
150 safe_free(pObject
->vpnc
.pRemoteNetList
);
152 case OBJECT_CONDITION
:
153 safe_free(pObject
->cond
.pszScript
);
154 safe_free(pObject
->cond
.pDCIList
);
157 safe_free(pObject
->cluster
.pSyncNetList
);
158 safe_free(pObject
->cluster
.pResourceList
);
161 safe_free(pObject
->pdwChildList
);
162 safe_free(pObject
->pdwParentList
);
163 safe_free(pObject
->pAccessList
);
164 safe_free(pObject
->pszComments
);
165 safe_free(pObject
->pdwTrustedNodes
);
166 delete pObject
->pCustomAttrs
;
167 memcpy(pObject
, pNewObject
, sizeof(NXC_OBJECT
));
173 // Create new object from message
176 static NXC_OBJECT
*NewObjectFromMsg(CSCPMessage
*pMsg
)
179 DWORD i
, dwId1
, dwId2
, dwCount
;
181 // Allocate memory for new object structure
182 pObject
= (NXC_OBJECT
*)malloc(sizeof(NXC_OBJECT
));
183 memset(pObject
, 0, sizeof(NXC_OBJECT
));
186 pObject
->dwId
= pMsg
->GetVariableLong(VID_OBJECT_ID
);
187 pObject
->iClass
= pMsg
->GetVariableShort(VID_OBJECT_CLASS
);
188 pMsg
->GetVariableStr(VID_OBJECT_NAME
, pObject
->szName
, MAX_OBJECT_NAME
);
189 pObject
->iStatus
= pMsg
->GetVariableShort(VID_OBJECT_STATUS
);
190 pObject
->dwIpAddr
= pMsg
->GetVariableLong(VID_IP_ADDRESS
);
191 pObject
->bIsDeleted
= pMsg
->GetVariableShort(VID_IS_DELETED
);
192 pObject
->dwImage
= pMsg
->GetVariableLong(VID_IMAGE_ID
);
193 pObject
->iStatusCalcAlg
= (int)pMsg
->GetVariableShort(VID_STATUS_CALCULATION_ALG
);
194 pObject
->iStatusPropAlg
= (int)pMsg
->GetVariableShort(VID_STATUS_PROPAGATION_ALG
);
195 pObject
->iFixedStatus
= (int)pMsg
->GetVariableShort(VID_FIXED_STATUS
);
196 pObject
->iStatusShift
= pMsg
->GetVariableShortAsInt32(VID_STATUS_SHIFT
);
197 pObject
->iStatusTrans
[0] = (int)pMsg
->GetVariableShort(VID_STATUS_TRANSLATION_1
);
198 pObject
->iStatusTrans
[1] = (int)pMsg
->GetVariableShort(VID_STATUS_TRANSLATION_2
);
199 pObject
->iStatusTrans
[2] = (int)pMsg
->GetVariableShort(VID_STATUS_TRANSLATION_3
);
200 pObject
->iStatusTrans
[3] = (int)pMsg
->GetVariableShort(VID_STATUS_TRANSLATION_4
);
201 pObject
->iStatusSingleTh
= (int)pMsg
->GetVariableShort(VID_STATUS_SINGLE_THRESHOLD
);
202 pObject
->iStatusThresholds
[0] = (int)pMsg
->GetVariableShort(VID_STATUS_THRESHOLD_1
);
203 pObject
->iStatusThresholds
[1] = (int)pMsg
->GetVariableShort(VID_STATUS_THRESHOLD_2
);
204 pObject
->iStatusThresholds
[2] = (int)pMsg
->GetVariableShort(VID_STATUS_THRESHOLD_3
);
205 pObject
->iStatusThresholds
[3] = (int)pMsg
->GetVariableShort(VID_STATUS_THRESHOLD_4
);
206 pObject
->pszComments
= pMsg
->GetVariableStr(VID_COMMENTS
);
207 pObject
->dwNumTrustedNodes
= pMsg
->GetVariableLong(VID_NUM_TRUSTED_NODES
);
208 if (pObject
->dwNumTrustedNodes
> 0)
210 pObject
->pdwTrustedNodes
= (DWORD
*)malloc(sizeof(DWORD
) * pObject
->dwNumTrustedNodes
);
211 pMsg
->GetVariableInt32Array(VID_TRUSTED_NODES
, pObject
->dwNumTrustedNodes
, pObject
->pdwTrustedNodes
);
215 pObject
->pCustomAttrs
= new StringMap
;
216 dwCount
= pMsg
->GetVariableLong(VID_NUM_CUSTOM_ATTRIBUTES
);
217 for(i
= 0, dwId1
= VID_CUSTOM_ATTRIBUTES_BASE
; i
< dwCount
; i
++, dwId1
+= 2)
219 pObject
->pCustomAttrs
->SetPreallocated(pMsg
->GetVariableStr(dwId1
), pMsg
->GetVariableStr(dwId1
+ 1));
223 pObject
->dwNumParents
= pMsg
->GetVariableLong(VID_PARENT_CNT
);
224 pObject
->pdwParentList
= (DWORD
*)malloc(sizeof(DWORD
) * pObject
->dwNumParents
);
225 for(i
= 0, dwId1
= VID_PARENT_ID_BASE
; i
< pObject
->dwNumParents
; i
++, dwId1
++)
226 pObject
->pdwParentList
[i
] = pMsg
->GetVariableLong(dwId1
);
229 pObject
->dwNumChilds
= pMsg
->GetVariableLong(VID_CHILD_CNT
);
230 pObject
->pdwChildList
= (DWORD
*)malloc(sizeof(DWORD
) * pObject
->dwNumChilds
);
231 for(i
= 0, dwId1
= VID_CHILD_ID_BASE
; i
< pObject
->dwNumChilds
; i
++, dwId1
++)
232 pObject
->pdwChildList
[i
] = pMsg
->GetVariableLong(dwId1
);
235 pObject
->bInheritRights
= pMsg
->GetVariableShort(VID_INHERIT_RIGHTS
);
236 pObject
->dwAclSize
= pMsg
->GetVariableLong(VID_ACL_SIZE
);
237 pObject
->pAccessList
= (NXC_ACL_ENTRY
*)malloc(sizeof(NXC_ACL_ENTRY
) * pObject
->dwAclSize
);
238 for(i
= 0, dwId1
= VID_ACL_USER_BASE
, dwId2
= VID_ACL_RIGHTS_BASE
;
239 i
< pObject
->dwAclSize
; i
++, dwId1
++, dwId2
++)
241 pObject
->pAccessList
[i
].dwUserId
= pMsg
->GetVariableLong(dwId1
);
242 pObject
->pAccessList
[i
].dwAccessRights
= pMsg
->GetVariableLong(dwId2
);
245 // Class-specific attributes
246 switch(pObject
->iClass
)
248 case OBJECT_INTERFACE
:
249 pObject
->iface
.dwIpNetMask
= pMsg
->GetVariableLong(VID_IP_NETMASK
);
250 pObject
->iface
.dwIfIndex
= pMsg
->GetVariableLong(VID_IF_INDEX
);
251 pObject
->iface
.dwIfType
= pMsg
->GetVariableLong(VID_IF_TYPE
);
252 pMsg
->GetVariableBinary(VID_MAC_ADDR
, pObject
->iface
.bMacAddr
, MAC_ADDR_LENGTH
);
253 pObject
->iface
.wRequiredPollCount
= pMsg
->GetVariableShort(VID_REQUIRED_POLLS
);
256 pObject
->node
.dwFlags
= pMsg
->GetVariableLong(VID_FLAGS
);
257 pObject
->node
.dwNodeType
= pMsg
->GetVariableLong(VID_NODE_TYPE
);
258 pObject
->node
.dwPollerNode
= pMsg
->GetVariableLong(VID_POLLER_NODE_ID
);
259 pObject
->node
.dwProxyNode
= pMsg
->GetVariableLong(VID_PROXY_NODE
);
260 pObject
->node
.dwSNMPProxy
= pMsg
->GetVariableLong(VID_SNMP_PROXY
);
261 pObject
->node
.dwZoneGUID
= pMsg
->GetVariableLong(VID_ZONE_GUID
);
262 pObject
->node
.wAgentPort
= pMsg
->GetVariableShort(VID_AGENT_PORT
);
263 pObject
->node
.wAuthMethod
= pMsg
->GetVariableShort(VID_AUTH_METHOD
);
264 pMsg
->GetVariableStr(VID_SHARED_SECRET
, pObject
->node
.szSharedSecret
, MAX_SECRET_LENGTH
);
265 pMsg
->GetVariableStr(VID_COMMUNITY_STRING
, pObject
->node
.szCommunityString
, MAX_COMMUNITY_LENGTH
);
266 pMsg
->GetVariableStr(VID_SNMP_OID
, pObject
->node
.szObjectId
, MAX_OID_LENGTH
);
267 pObject
->node
.nSNMPVersion
= (BYTE
)pMsg
->GetVariableShort(VID_SNMP_VERSION
);
268 pMsg
->GetVariableStr(VID_AGENT_VERSION
, pObject
->node
.szAgentVersion
, MAX_AGENT_VERSION_LEN
);
269 pMsg
->GetVariableStr(VID_PLATFORM_NAME
, pObject
->node
.szPlatformName
, MAX_PLATFORM_NAME_LEN
);
270 pObject
->node
.wRequiredPollCount
= pMsg
->GetVariableShort(VID_REQUIRED_POLLS
);
271 pMsg
->GetVariableStr(VID_SYS_DESCRIPTION
, pObject
->node
.szSysDescription
, MAX_DB_STRING
);
272 pObject
->node
.nUseIfXTable
= (BYTE
)pMsg
->GetVariableShort(VID_USE_IFXTABLE
);
275 pObject
->subnet
.dwIpNetMask
= pMsg
->GetVariableLong(VID_IP_NETMASK
);
276 pObject
->subnet
.dwZoneGUID
= pMsg
->GetVariableLong(VID_ZONE_GUID
);
278 case OBJECT_CONTAINER
:
279 pObject
->container
.dwCategory
= pMsg
->GetVariableLong(VID_CATEGORY
);
281 case OBJECT_TEMPLATE
:
282 pObject
->dct
.dwVersion
= pMsg
->GetVariableLong(VID_TEMPLATE_VERSION
);
284 case OBJECT_NETWORKSERVICE
:
285 pObject
->netsrv
.iServiceType
= (int)pMsg
->GetVariableShort(VID_SERVICE_TYPE
);
286 pObject
->netsrv
.wProto
= pMsg
->GetVariableShort(VID_IP_PROTO
);
287 pObject
->netsrv
.wPort
= pMsg
->GetVariableShort(VID_IP_PORT
);
288 pObject
->netsrv
.dwPollerNode
= pMsg
->GetVariableLong(VID_POLLER_NODE_ID
);
289 pObject
->netsrv
.pszRequest
= pMsg
->GetVariableStr(VID_SERVICE_REQUEST
);
290 pObject
->netsrv
.pszResponse
= pMsg
->GetVariableStr(VID_SERVICE_RESPONSE
);
291 pObject
->netsrv
.wRequiredPollCount
= pMsg
->GetVariableShort(VID_REQUIRED_POLLS
);
294 pObject
->zone
.dwZoneGUID
= pMsg
->GetVariableLong(VID_ZONE_GUID
);
295 pObject
->zone
.wZoneType
= pMsg
->GetVariableShort(VID_ZONE_TYPE
);
296 pObject
->zone
.dwControllerIpAddr
= pMsg
->GetVariableLong(VID_CONTROLLER_IP_ADDR
);
297 pObject
->zone
.dwAddrListSize
= pMsg
->GetVariableLong(VID_ADDR_LIST_SIZE
);
298 pObject
->zone
.pdwAddrList
= (DWORD
*)malloc(sizeof(DWORD
) * pObject
->zone
.dwAddrListSize
);
299 pMsg
->GetVariableInt32Array(VID_IP_ADDR_LIST
, pObject
->zone
.dwAddrListSize
, pObject
->zone
.pdwAddrList
);
301 case OBJECT_VPNCONNECTOR
:
302 pObject
->vpnc
.dwPeerGateway
= pMsg
->GetVariableLong(VID_PEER_GATEWAY
);
303 pObject
->vpnc
.dwNumLocalNets
= pMsg
->GetVariableLong(VID_NUM_LOCAL_NETS
);
304 pObject
->vpnc
.pLocalNetList
= (IP_NETWORK
*)malloc(sizeof(IP_NETWORK
) * pObject
->vpnc
.dwNumLocalNets
);
305 for(i
= 0, dwId1
= VID_VPN_NETWORK_BASE
; i
< pObject
->vpnc
.dwNumLocalNets
; i
++)
307 pObject
->vpnc
.pLocalNetList
[i
].dwAddr
= pMsg
->GetVariableLong(dwId1
++);
308 pObject
->vpnc
.pLocalNetList
[i
].dwMask
= pMsg
->GetVariableLong(dwId1
++);
310 pObject
->vpnc
.dwNumRemoteNets
= pMsg
->GetVariableLong(VID_NUM_REMOTE_NETS
);
311 pObject
->vpnc
.pRemoteNetList
= (IP_NETWORK
*)malloc(sizeof(IP_NETWORK
) * pObject
->vpnc
.dwNumRemoteNets
);
312 for(i
= 0; i
< pObject
->vpnc
.dwNumRemoteNets
; i
++)
314 pObject
->vpnc
.pRemoteNetList
[i
].dwAddr
= pMsg
->GetVariableLong(dwId1
++);
315 pObject
->vpnc
.pRemoteNetList
[i
].dwMask
= pMsg
->GetVariableLong(dwId1
++);
318 case OBJECT_CONDITION
:
319 pObject
->cond
.dwActivationEvent
= pMsg
->GetVariableLong(VID_ACTIVATION_EVENT
);
320 pObject
->cond
.dwDeactivationEvent
= pMsg
->GetVariableLong(VID_DEACTIVATION_EVENT
);
321 pObject
->cond
.dwSourceObject
= pMsg
->GetVariableLong(VID_SOURCE_OBJECT
);
322 pObject
->cond
.pszScript
= pMsg
->GetVariableStr(VID_SCRIPT
);
323 pObject
->cond
.wActiveStatus
= pMsg
->GetVariableShort(VID_ACTIVE_STATUS
);
324 pObject
->cond
.wInactiveStatus
= pMsg
->GetVariableShort(VID_INACTIVE_STATUS
);
325 pObject
->cond
.dwNumDCI
= pMsg
->GetVariableLong(VID_NUM_ITEMS
);
326 pObject
->cond
.pDCIList
= (INPUT_DCI
*)malloc(sizeof(INPUT_DCI
) * pObject
->cond
.dwNumDCI
);
327 for(i
= 0, dwId1
= VID_DCI_LIST_BASE
; i
< pObject
->cond
.dwNumDCI
; i
++)
329 pObject
->cond
.pDCIList
[i
].dwId
= pMsg
->GetVariableLong(dwId1
++);
330 pObject
->cond
.pDCIList
[i
].dwNodeId
= pMsg
->GetVariableLong(dwId1
++);
331 pObject
->cond
.pDCIList
[i
].nFunction
= pMsg
->GetVariableShort(dwId1
++);
332 pObject
->cond
.pDCIList
[i
].nPolls
= pMsg
->GetVariableShort(dwId1
++);
337 pObject
->cluster
.dwClusterType
= pMsg
->GetVariableLong(VID_CLUSTER_TYPE
);
338 pObject
->cluster
.dwNumSyncNets
= pMsg
->GetVariableLong(VID_NUM_SYNC_SUBNETS
);
339 pObject
->cluster
.pSyncNetList
= (IP_NETWORK
*)malloc(sizeof(IP_NETWORK
) * pObject
->cluster
.dwNumSyncNets
);
340 pMsg
->GetVariableInt32Array(VID_SYNC_SUBNETS
, pObject
->cluster
.dwNumSyncNets
* 2, (DWORD
*)pObject
->cluster
.pSyncNetList
);
341 pObject
->cluster
.dwNumResources
= pMsg
->GetVariableLong(VID_NUM_RESOURCES
);
342 if (pObject
->cluster
.dwNumResources
> 0)
344 pObject
->cluster
.pResourceList
= (CLUSTER_RESOURCE
*)malloc(sizeof(CLUSTER_RESOURCE
) * pObject
->cluster
.dwNumResources
);
345 for(i
= 0, dwId1
= VID_RESOURCE_LIST_BASE
; i
< pObject
->cluster
.dwNumResources
; i
++, dwId1
+= 6)
347 pObject
->cluster
.pResourceList
[i
].dwId
= pMsg
->GetVariableLong(dwId1
++);
348 pMsg
->GetVariableStr(dwId1
++, pObject
->cluster
.pResourceList
[i
].szName
, MAX_DB_STRING
);
349 pObject
->cluster
.pResourceList
[i
].dwIpAddr
= pMsg
->GetVariableLong(dwId1
++);
350 pObject
->cluster
.pResourceList
[i
].dwCurrOwner
= pMsg
->GetVariableLong(dwId1
++);
363 // Process object information received from server
366 void NXCL_Session::ProcessObjectUpdate(CSCPMessage
*pMsg
)
368 NXC_OBJECT
*pObject
, *pNewObject
;
371 switch(pMsg
->GetCode())
373 case CMD_OBJECT_LIST_END
:
374 if (!(m_dwFlags
& NXC_SF_HAS_OBJECT_CACHE
))
377 qsort(m_pIndexById
, m_dwNumObjects
, sizeof(INDEX
), IndexCompare
);
380 CompleteSync(SYNC_OBJECTS
, RCC_SUCCESS
);
383 pTmp
= pMsg
->GetVariableStr(VID_OBJECT_NAME
);
384 DebugPrintf(_T("RECV_OBJECT: ID=%d Name=\"%s\" Class=%d"), pMsg
->GetVariableLong(VID_OBJECT_ID
),
385 pTmp
, pMsg
->GetVariableShort(VID_OBJECT_CLASS
));
388 // Create new object from message and add it to list
389 pNewObject
= NewObjectFromMsg(pMsg
);
390 if (m_dwFlags
& NXC_SF_HAS_OBJECT_CACHE
)
392 // We already have some objects loaded from cache file
393 pObject
= FindObjectById(pNewObject
->dwId
, TRUE
);
396 AddObject(pNewObject
, TRUE
);
400 ReplaceObject(pObject
, pNewObject
);
405 // No cache file, all objects are new
406 AddObject(pNewObject
, FALSE
);
409 case CMD_OBJECT_UPDATE
:
410 pNewObject
= NewObjectFromMsg(pMsg
);
411 pObject
= FindObjectById(pNewObject
->dwId
, TRUE
);
414 AddObject(pNewObject
, TRUE
);
415 pObject
= pNewObject
;
419 ReplaceObject(pObject
, pNewObject
);
421 CallEventHandler(NXC_EVENT_OBJECT_CHANGED
, pObject
->dwId
, pObject
);
430 // Synchronize objects with the server
431 // This function is NOT REENTRANT
434 DWORD
NXCL_Session::SyncObjects(const TCHAR
*pszCacheFile
, BOOL bSyncComments
)
437 DWORD dwRetCode
, dwRqId
;
439 dwRqId
= CreateRqId();
440 PrepareForSync(SYNC_OBJECTS
);
444 m_dwFlags
&= ~NXC_SF_HAS_OBJECT_CACHE
;
445 if (pszCacheFile
!= NULL
)
446 LoadObjectsFromCache(pszCacheFile
);
448 msg
.SetCode(CMD_GET_OBJECTS
);
450 msg
.SetVariable(VID_TIMESTAMP
, m_dwTimeStamp
);
451 msg
.SetVariable(VID_SYNC_COMMENTS
, (WORD
)bSyncComments
);
454 dwRetCode
= WaitForRCC(dwRqId
);
456 // If request was successful, wait for object list end or for disconnection
457 if (dwRetCode
== RCC_SUCCESS
)
458 dwRetCode
= WaitForSync(SYNC_OBJECTS
, INFINITE
);
460 UnlockSyncOp(SYNC_OBJECTS
);
467 // Wrappers for NXCL_Session::SyncObjects()
470 DWORD LIBNXCL_EXPORTABLE
NXCSyncObjects(NXC_SESSION hSession
)
472 return ((NXCL_Session
*)hSession
)->SyncObjects(NULL
, FALSE
);
475 DWORD LIBNXCL_EXPORTABLE
NXCSyncObjectsEx(NXC_SESSION hSession
, const TCHAR
*pszCacheFile
,
478 return ((NXCL_Session
*)hSession
)->SyncObjects(pszCacheFile
, bSyncComments
);
486 NXC_OBJECT
*NXCL_Session::FindObjectById(DWORD dwId
, BOOL bLock
)
494 dwPos
= SearchIndex(m_pIndexById
, m_dwNumObjects
, dwId
);
495 pObject
= (dwPos
== INVALID_INDEX
) ? NULL
: m_pIndexById
[dwPos
].pObject
;
503 NXC_OBJECT LIBNXCL_EXPORTABLE
*NXCFindObjectById(NXC_SESSION hSession
, DWORD dwId
)
505 return ((NXCL_Session
*)hSession
)->FindObjectById(dwId
, TRUE
);
508 NXC_OBJECT LIBNXCL_EXPORTABLE
*NXCFindObjectByIdNoLock(NXC_SESSION hSession
, DWORD dwId
)
510 return ((NXCL_Session
*)hSession
)->FindObjectById(dwId
, FALSE
);
515 // Find object by name
518 NXC_OBJECT
*NXCL_Session::FindObjectByName(TCHAR
*pszName
, DWORD dwCurrObject
)
520 NXC_OBJECT
*pObject
= NULL
;
528 if (dwCurrObject
!= 0)
530 pObject
= FindObjectById(dwCurrObject
, FALSE
);
533 if (!RegexpMatch(pObject
->szName
, pszName
, FALSE
))
535 // Current object doesn't match, start search from the beginning
546 for(i
= 0; i
< m_dwNumObjects
; i
++)
547 if (RegexpMatch(m_pIndexById
[i
].pObject
->szName
, pszName
, FALSE
))
549 if (dwCurrObject
== 0)
551 pObject
= m_pIndexById
[i
].pObject
;
556 if (m_pIndexById
[i
].dwKey
== dwCurrObject
)
558 dwCurrObject
= 0; // Next match will stop the loop
568 NXC_OBJECT LIBNXCL_EXPORTABLE
*NXCFindObjectByName(NXC_SESSION hSession
, TCHAR
*pszName
, DWORD dwCurrObject
)
570 return ((NXCL_Session
*)hSession
)->FindObjectByName(pszName
, dwCurrObject
);
575 // Find object by IP address
578 NXC_OBJECT
*NXCL_Session::FindObjectByIPAddress(DWORD dwIpAddr
, DWORD dwCurrObject
)
580 NXC_OBJECT
*pObject
= NULL
;
585 if (dwCurrObject
!= 0)
587 pObject
= FindObjectById(dwCurrObject
, FALSE
);
590 if (pObject
->dwIpAddr
!= dwIpAddr
)
592 // Current object doesn't match, start search from the beginning
603 for(i
= 0; i
< m_dwNumObjects
; i
++)
604 if (m_pIndexById
[i
].pObject
->dwIpAddr
== dwIpAddr
)
606 if (dwCurrObject
== 0)
608 pObject
= m_pIndexById
[i
].pObject
;
613 if (m_pIndexById
[i
].dwKey
== dwCurrObject
)
615 dwCurrObject
= 0; // Next match will stop the loop
624 NXC_OBJECT LIBNXCL_EXPORTABLE
*NXCFindObjectByIPAddress(NXC_SESSION hSession
, DWORD dwIpAddr
, DWORD dwCurrObject
)
626 return ((NXCL_Session
*)hSession
)->FindObjectByIPAddress(dwIpAddr
, dwCurrObject
);
631 // Enumerate all objects
634 void NXCL_Session::EnumerateObjects(BOOL (* pHandler
)(NXC_OBJECT
*))
639 for(i
= 0; i
< m_dwNumObjects
; i
++)
640 if (!pHandler(m_pIndexById
[i
].pObject
))
645 void LIBNXCL_EXPORTABLE
NXCEnumerateObjects(NXC_SESSION hSession
, BOOL (* pHandler
)(NXC_OBJECT
*))
647 ((NXCL_Session
*)hSession
)->EnumerateObjects(pHandler
);
655 NXC_OBJECT
*NXCL_Session::GetRootObject(DWORD dwId
, DWORD dwIndex
)
657 if (m_dwNumObjects
> dwIndex
)
658 if (m_pIndexById
[dwIndex
].dwKey
== dwId
)
659 return m_pIndexById
[dwIndex
].pObject
;
665 // Get topology root ("Entire Network") object
668 NXC_OBJECT LIBNXCL_EXPORTABLE
*NXCGetTopologyRootObject(NXC_SESSION hSession
)
670 return ((NXCL_Session
*)hSession
)->GetRootObject(1, 0);
675 // Get service tree root ("All Services") object
678 NXC_OBJECT LIBNXCL_EXPORTABLE
*NXCGetServiceRootObject(NXC_SESSION hSession
)
680 return ((NXCL_Session
*)hSession
)->GetRootObject(2, 1);
685 // Get template tree root ("Templates") object
688 NXC_OBJECT LIBNXCL_EXPORTABLE
*NXCGetTemplateRootObject(NXC_SESSION hSession
)
690 return ((NXCL_Session
*)hSession
)->GetRootObject(3, 2);
695 // Get pointer to first object on objects' list and entire number of objects
698 void *NXCL_Session::GetObjectIndex(DWORD
*pdwNumObjects
)
700 if (pdwNumObjects
!= NULL
)
701 *pdwNumObjects
= m_dwNumObjects
;
705 void LIBNXCL_EXPORTABLE
*NXCGetObjectIndex(NXC_SESSION hSession
, DWORD
*pdwNumObjects
)
707 return ((NXCL_Session
*)hSession
)->GetObjectIndex(pdwNumObjects
);
715 void LIBNXCL_EXPORTABLE
NXCLockObjectIndex(NXC_SESSION hSession
)
717 ((NXCL_Session
*)hSession
)->LockObjectIndex();
722 // Unlock object index
725 void LIBNXCL_EXPORTABLE
NXCUnlockObjectIndex(NXC_SESSION hSession
)
727 ((NXCL_Session
*)hSession
)->UnlockObjectIndex();
735 DWORD LIBNXCL_EXPORTABLE
NXCModifyObject(NXC_SESSION hSession
, NXC_OBJECT_UPDATE
*pUpdate
)
738 DWORD dwRqId
, i
, dwId1
, dwId2
;
740 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
742 // Build request message
743 msg
.SetCode(CMD_MODIFY_OBJECT
);
745 msg
.SetVariable(VID_OBJECT_ID
, pUpdate
->dwObjectId
);
746 if (pUpdate
->qwFlags
& OBJ_UPDATE_NAME
)
747 msg
.SetVariable(VID_OBJECT_NAME
, pUpdate
->pszName
);
748 if (pUpdate
->qwFlags
& OBJ_UPDATE_AGENT_PORT
)
749 msg
.SetVariable(VID_AGENT_PORT
, (WORD
)pUpdate
->iAgentPort
);
750 if (pUpdate
->qwFlags
& OBJ_UPDATE_AGENT_AUTH
)
751 msg
.SetVariable(VID_AUTH_METHOD
, (WORD
)pUpdate
->iAuthType
);
752 if (pUpdate
->qwFlags
& OBJ_UPDATE_AGENT_SECRET
)
753 msg
.SetVariable(VID_SHARED_SECRET
, pUpdate
->pszSecret
);
754 if (pUpdate
->qwFlags
& OBJ_UPDATE_SNMP_COMMUNITY
)
755 msg
.SetVariable(VID_COMMUNITY_STRING
, pUpdate
->pszCommunity
);
756 if (pUpdate
->qwFlags
& OBJ_UPDATE_IMAGE
)
757 msg
.SetVariable(VID_IMAGE_ID
, pUpdate
->dwImage
);
758 if (pUpdate
->qwFlags
& OBJ_UPDATE_SNMP_VERSION
)
759 msg
.SetVariable(VID_SNMP_VERSION
, pUpdate
->wSNMPVersion
);
760 if (pUpdate
->qwFlags
& OBJ_UPDATE_CHECK_REQUEST
)
761 msg
.SetVariable(VID_SERVICE_REQUEST
, pUpdate
->pszRequest
);
762 if (pUpdate
->qwFlags
& OBJ_UPDATE_CHECK_RESPONSE
)
763 msg
.SetVariable(VID_SERVICE_RESPONSE
, pUpdate
->pszResponse
);
764 if (pUpdate
->qwFlags
& OBJ_UPDATE_IP_PROTO
)
765 msg
.SetVariable(VID_IP_PROTO
, pUpdate
->wProto
);
766 if (pUpdate
->qwFlags
& OBJ_UPDATE_IP_PORT
)
767 msg
.SetVariable(VID_IP_PORT
, pUpdate
->wPort
);
768 if (pUpdate
->qwFlags
& OBJ_UPDATE_SERVICE_TYPE
)
769 msg
.SetVariable(VID_SERVICE_TYPE
, (WORD
)pUpdate
->iServiceType
);
770 if (pUpdate
->qwFlags
& OBJ_UPDATE_POLLER_NODE
)
771 msg
.SetVariable(VID_POLLER_NODE_ID
, pUpdate
->dwPollerNode
);
772 if (pUpdate
->qwFlags
& OBJ_UPDATE_PROXY_NODE
)
773 msg
.SetVariable(VID_PROXY_NODE
, pUpdate
->dwProxyNode
);
774 if (pUpdate
->qwFlags
& OBJ_UPDATE_SNMP_PROXY
)
775 msg
.SetVariable(VID_SNMP_PROXY
, pUpdate
->dwSNMPProxy
);
776 if (pUpdate
->qwFlags
& OBJ_UPDATE_IP_ADDR
)
777 msg
.SetVariable(VID_IP_ADDRESS
, pUpdate
->dwIpAddr
);
778 if (pUpdate
->qwFlags
& OBJ_UPDATE_PEER_GATEWAY
)
779 msg
.SetVariable(VID_PEER_GATEWAY
, pUpdate
->dwPeerGateway
);
780 if (pUpdate
->qwFlags
& OBJ_UPDATE_NODE_FLAGS
)
781 msg
.SetVariable(VID_FLAGS
, pUpdate
->dwNodeFlags
);
782 if (pUpdate
->qwFlags
& OBJ_UPDATE_ACT_EVENT
)
783 msg
.SetVariable(VID_ACTIVATION_EVENT
, pUpdate
->dwActivationEvent
);
784 if (pUpdate
->qwFlags
& OBJ_UPDATE_DEACT_EVENT
)
785 msg
.SetVariable(VID_DEACTIVATION_EVENT
, pUpdate
->dwDeactivationEvent
);
786 if (pUpdate
->qwFlags
& OBJ_UPDATE_SOURCE_OBJECT
)
787 msg
.SetVariable(VID_SOURCE_OBJECT
, pUpdate
->dwSourceObject
);
788 if (pUpdate
->qwFlags
& OBJ_UPDATE_ACTIVE_STATUS
)
789 msg
.SetVariable(VID_ACTIVE_STATUS
, (WORD
)pUpdate
->nActiveStatus
);
790 if (pUpdate
->qwFlags
& OBJ_UPDATE_INACTIVE_STATUS
)
791 msg
.SetVariable(VID_INACTIVE_STATUS
, (WORD
)pUpdate
->nInactiveStatus
);
792 if (pUpdate
->qwFlags
& OBJ_UPDATE_SCRIPT
)
793 msg
.SetVariable(VID_SCRIPT
, pUpdate
->pszScript
);
794 if (pUpdate
->qwFlags
& OBJ_UPDATE_CLUSTER_TYPE
)
795 msg
.SetVariable(VID_CLUSTER_TYPE
, pUpdate
->dwClusterType
);
796 if (pUpdate
->qwFlags
& OBJ_UPDATE_REQUIRED_POLLS
)
797 msg
.SetVariable(VID_REQUIRED_POLLS
, pUpdate
->wRequiredPollCount
);
798 if (pUpdate
->qwFlags
& OBJ_UPDATE_USE_IFXTABLE
)
799 msg
.SetVariable(VID_USE_IFXTABLE
, (WORD
)pUpdate
->nUseIfXTable
);
800 if (pUpdate
->qwFlags
& OBJ_UPDATE_STATUS_ALG
)
802 msg
.SetVariable(VID_STATUS_CALCULATION_ALG
, (WORD
)pUpdate
->iStatusCalcAlg
);
803 msg
.SetVariable(VID_STATUS_PROPAGATION_ALG
, (WORD
)pUpdate
->iStatusPropAlg
);
804 msg
.SetVariable(VID_FIXED_STATUS
, (WORD
)pUpdate
->iFixedStatus
);
805 msg
.SetVariable(VID_STATUS_SHIFT
, (WORD
)pUpdate
->iStatusShift
);
806 msg
.SetVariable(VID_STATUS_TRANSLATION_1
, (WORD
)pUpdate
->iStatusTrans
[0]);
807 msg
.SetVariable(VID_STATUS_TRANSLATION_2
, (WORD
)pUpdate
->iStatusTrans
[1]);
808 msg
.SetVariable(VID_STATUS_TRANSLATION_3
, (WORD
)pUpdate
->iStatusTrans
[2]);
809 msg
.SetVariable(VID_STATUS_TRANSLATION_4
, (WORD
)pUpdate
->iStatusTrans
[3]);
810 msg
.SetVariable(VID_STATUS_SINGLE_THRESHOLD
, (WORD
)pUpdate
->iStatusSingleTh
);
811 msg
.SetVariable(VID_STATUS_THRESHOLD_1
, (WORD
)pUpdate
->iStatusThresholds
[0]);
812 msg
.SetVariable(VID_STATUS_THRESHOLD_2
, (WORD
)pUpdate
->iStatusThresholds
[1]);
813 msg
.SetVariable(VID_STATUS_THRESHOLD_3
, (WORD
)pUpdate
->iStatusThresholds
[2]);
814 msg
.SetVariable(VID_STATUS_THRESHOLD_4
, (WORD
)pUpdate
->iStatusThresholds
[3]);
816 if (pUpdate
->qwFlags
& OBJ_UPDATE_NETWORK_LIST
)
818 msg
.SetVariable(VID_NUM_LOCAL_NETS
, pUpdate
->dwNumLocalNets
);
819 msg
.SetVariable(VID_NUM_REMOTE_NETS
, pUpdate
->dwNumRemoteNets
);
820 for(i
= 0, dwId1
= VID_VPN_NETWORK_BASE
; i
< pUpdate
->dwNumLocalNets
; i
++)
822 msg
.SetVariable(dwId1
++, pUpdate
->pLocalNetList
[i
].dwAddr
);
823 msg
.SetVariable(dwId1
++, pUpdate
->pLocalNetList
[i
].dwMask
);
825 for(i
= 0; i
< pUpdate
->dwNumRemoteNets
; i
++)
827 msg
.SetVariable(dwId1
++, pUpdate
->pRemoteNetList
[i
].dwAddr
);
828 msg
.SetVariable(dwId1
++, pUpdate
->pRemoteNetList
[i
].dwMask
);
831 if (pUpdate
->qwFlags
& OBJ_UPDATE_ACL
)
833 msg
.SetVariable(VID_ACL_SIZE
, pUpdate
->dwAclSize
);
834 msg
.SetVariable(VID_INHERIT_RIGHTS
, (WORD
)pUpdate
->bInheritRights
);
835 for(i
= 0, dwId1
= VID_ACL_USER_BASE
, dwId2
= VID_ACL_RIGHTS_BASE
;
836 i
< pUpdate
->dwAclSize
; i
++, dwId1
++, dwId2
++)
838 msg
.SetVariable(dwId1
, pUpdate
->pAccessList
[i
].dwUserId
);
839 msg
.SetVariable(dwId2
, pUpdate
->pAccessList
[i
].dwAccessRights
);
842 if (pUpdate
->qwFlags
& OBJ_UPDATE_DCI_LIST
)
844 msg
.SetVariable(VID_NUM_ITEMS
, pUpdate
->dwNumDCI
);
845 for(i
= 0, dwId1
= VID_DCI_LIST_BASE
; i
< pUpdate
->dwNumDCI
; i
++)
847 msg
.SetVariable(dwId1
++, pUpdate
->pDCIList
[i
].dwId
);
848 msg
.SetVariable(dwId1
++, pUpdate
->pDCIList
[i
].dwNodeId
);
849 msg
.SetVariable(dwId1
++, (WORD
)pUpdate
->pDCIList
[i
].nFunction
);
850 msg
.SetVariable(dwId1
++, (WORD
)pUpdate
->pDCIList
[i
].nPolls
);
854 if (pUpdate
->qwFlags
& OBJ_UPDATE_SYNC_NETS
)
856 msg
.SetVariable(VID_NUM_SYNC_SUBNETS
, pUpdate
->dwNumSyncNets
);
857 msg
.SetVariableToInt32Array(VID_SYNC_SUBNETS
, pUpdate
->dwNumSyncNets
* 2, (DWORD
*)pUpdate
->pSyncNetList
);
859 if (pUpdate
->qwFlags
& OBJ_UPDATE_RESOURCES
)
861 msg
.SetVariable(VID_NUM_RESOURCES
, pUpdate
->dwNumResources
);
862 for(i
= 0, dwId1
= VID_RESOURCE_LIST_BASE
; i
< pUpdate
->dwNumResources
; i
++, dwId1
+= 7)
864 msg
.SetVariable(dwId1
++, pUpdate
->pResourceList
[i
].dwId
);
865 msg
.SetVariable(dwId1
++, pUpdate
->pResourceList
[i
].szName
);
866 msg
.SetVariable(dwId1
++, pUpdate
->pResourceList
[i
].dwIpAddr
);
869 if (pUpdate
->qwFlags
& OBJ_UPDATE_TRUSTED_NODES
)
871 msg
.SetVariable(VID_NUM_TRUSTED_NODES
, pUpdate
->dwNumTrustedNodes
);
872 msg
.SetVariableToInt32Array(VID_TRUSTED_NODES
, pUpdate
->dwNumTrustedNodes
, pUpdate
->pdwTrustedNodes
);
874 if (pUpdate
->qwFlags
& OBJ_UPDATE_CUSTOM_ATTRS
)
876 msg
.SetVariable(VID_NUM_CUSTOM_ATTRIBUTES
, pUpdate
->pCustomAttrs
->Size());
877 for(i
= 0, dwId1
= VID_CUSTOM_ATTRIBUTES_BASE
; i
< pUpdate
->pCustomAttrs
->Size(); i
++)
879 msg
.SetVariable(dwId1
++, pUpdate
->pCustomAttrs
->GetKeyByIndex(i
));
880 msg
.SetVariable(dwId1
++, pUpdate
->pCustomAttrs
->GetValueByIndex(i
));
885 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
888 return ((NXCL_Session
*)hSession
)->WaitForRCC(dwRqId
);
893 // Set object's mamagement status
896 DWORD LIBNXCL_EXPORTABLE
NXCSetObjectMgmtStatus(NXC_SESSION hSession
, DWORD dwObjectId
,
902 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
904 // Build request message
905 msg
.SetCode(CMD_SET_OBJECT_MGMT_STATUS
);
907 msg
.SetVariable(VID_OBJECT_ID
, dwObjectId
);
908 msg
.SetVariable(VID_MGMT_STATUS
, (WORD
)bIsManaged
);
911 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
914 return ((NXCL_Session
*)hSession
)->WaitForRCC(dwRqId
);
922 DWORD LIBNXCL_EXPORTABLE
NXCCreateObject(NXC_SESSION hSession
,
923 NXC_OBJECT_CREATE_INFO
*pCreateInfo
,
926 CSCPMessage msg
, *pResponse
;
927 DWORD dwRqId
, dwRetCode
;
929 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
931 // Build request message
932 msg
.SetCode(CMD_CREATE_OBJECT
);
934 msg
.SetVariable(VID_PARENT_ID
, pCreateInfo
->dwParentId
);
935 msg
.SetVariable(VID_OBJECT_CLASS
, (WORD
)pCreateInfo
->iClass
);
936 msg
.SetVariable(VID_OBJECT_NAME
, pCreateInfo
->pszName
);
937 if (pCreateInfo
->pszComments
!= NULL
)
938 msg
.SetVariable(VID_COMMENTS
, pCreateInfo
->pszComments
);
939 switch(pCreateInfo
->iClass
)
942 msg
.SetVariable(VID_IP_ADDRESS
, pCreateInfo
->cs
.node
.dwIpAddr
);
943 msg
.SetVariable(VID_IP_NETMASK
, pCreateInfo
->cs
.node
.dwNetMask
);
944 msg
.SetVariable(VID_CREATION_FLAGS
, pCreateInfo
->cs
.node
.dwCreationFlags
);
945 msg
.SetVariable(VID_PROXY_NODE
, pCreateInfo
->cs
.node
.dwProxyNode
);
946 msg
.SetVariable(VID_SNMP_PROXY
, pCreateInfo
->cs
.node
.dwSNMPProxy
);
948 case OBJECT_CONTAINER
:
949 msg
.SetVariable(VID_CATEGORY
, pCreateInfo
->cs
.container
.dwCategory
);
951 case OBJECT_NETWORKSERVICE
:
952 msg
.SetVariable(VID_SERVICE_TYPE
, (WORD
)pCreateInfo
->cs
.netsrv
.iServiceType
);
953 msg
.SetVariable(VID_IP_PROTO
, pCreateInfo
->cs
.netsrv
.wProto
);
954 msg
.SetVariable(VID_IP_PORT
, pCreateInfo
->cs
.netsrv
.wPort
);
955 msg
.SetVariable(VID_SERVICE_REQUEST
, pCreateInfo
->cs
.netsrv
.pszRequest
);
956 msg
.SetVariable(VID_SERVICE_RESPONSE
, pCreateInfo
->cs
.netsrv
.pszResponse
);
963 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
965 // Wait for response. Creating node object can include polling,
966 // which can take a minute or even more in worst cases
967 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
, 300000);
968 if (pResponse
!= NULL
)
970 dwRetCode
= pResponse
->GetVariableLong(VID_RCC
);
971 if (dwRetCode
== RCC_SUCCESS
)
973 *pdwObjectId
= pResponse
->GetVariableLong(VID_OBJECT_ID
);
979 dwRetCode
= RCC_TIMEOUT
;
987 // Bind/unbind objects
990 static DWORD
ChangeObjectBinding(NXCL_Session
*pSession
, DWORD dwParentObject
,
991 DWORD dwChildObject
, BOOL bBind
, BOOL bRemoveDCI
)
996 dwRqId
= pSession
->CreateRqId();
998 // Build request message
999 msg
.SetCode(bBind
? CMD_BIND_OBJECT
: CMD_UNBIND_OBJECT
);
1001 msg
.SetVariable(VID_PARENT_ID
, dwParentObject
);
1002 msg
.SetVariable(VID_CHILD_ID
, dwChildObject
);
1004 msg
.SetVariable(VID_REMOVE_DCI
, (WORD
)bRemoveDCI
);
1007 pSession
->SendMsg(&msg
);
1010 return pSession
->WaitForRCC(dwRqId
);
1018 DWORD LIBNXCL_EXPORTABLE
NXCBindObject(NXC_SESSION hSession
, DWORD dwParentObject
,
1019 DWORD dwChildObject
)
1021 return ChangeObjectBinding((NXCL_Session
*)hSession
, dwParentObject
,
1022 dwChildObject
, TRUE
, FALSE
);
1030 DWORD LIBNXCL_EXPORTABLE
NXCUnbindObject(NXC_SESSION hSession
, DWORD dwParentObject
,
1031 DWORD dwChildObject
)
1033 return ChangeObjectBinding((NXCL_Session
*)hSession
, dwParentObject
,
1034 dwChildObject
, FALSE
, FALSE
);
1039 // Remove template from node
1042 DWORD LIBNXCL_EXPORTABLE
NXCRemoveTemplate(NXC_SESSION hSession
, DWORD dwTemplateId
,
1043 DWORD dwNodeId
, BOOL bRemoveDCI
)
1045 return ChangeObjectBinding((NXCL_Session
*)hSession
, dwTemplateId
,
1046 dwNodeId
, FALSE
, bRemoveDCI
);
1054 DWORD LIBNXCL_EXPORTABLE
NXCDeleteObject(NXC_SESSION hSession
, DWORD dwObject
)
1059 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
1061 // Build request message
1062 msg
.SetCode(CMD_DELETE_OBJECT
);
1064 msg
.SetVariable(VID_OBJECT_ID
, dwObject
);
1067 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
1070 // For node objects, deletion may take long time if object
1071 // is currently polled
1072 return ((NXCL_Session
*)hSession
)->WaitForRCC(dwRqId
, 300000);
1077 // Load container categories
1080 DWORD LIBNXCL_EXPORTABLE
NXCLoadCCList(NXC_SESSION hSession
, NXC_CC_LIST
**ppList
)
1082 CSCPMessage msg
, *pResponse
;
1083 DWORD dwRqId
, dwRetCode
= RCC_SUCCESS
, dwNumCats
= 0, dwCatId
= 0;
1085 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
1087 msg
.SetCode(CMD_GET_CONTAINER_CAT_LIST
);
1089 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
1091 *ppList
= (NXC_CC_LIST
*)malloc(sizeof(NXC_CC_LIST
));
1092 (*ppList
)->dwNumElements
= 0;
1093 (*ppList
)->pElements
= NULL
;
1097 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_CONTAINER_CAT_DATA
, dwRqId
);
1098 if (pResponse
!= NULL
)
1100 dwCatId
= pResponse
->GetVariableLong(VID_CATEGORY_ID
);
1101 if (dwCatId
!= 0) // 0 is end of list indicator
1103 (*ppList
)->pElements
= (NXC_CONTAINER_CATEGORY
*)realloc((*ppList
)->pElements
,
1104 sizeof(NXC_CONTAINER_CATEGORY
) * ((*ppList
)->dwNumElements
+ 1));
1105 (*ppList
)->pElements
[(*ppList
)->dwNumElements
].dwId
= dwCatId
;
1106 (*ppList
)->pElements
[(*ppList
)->dwNumElements
].dwImageId
=
1107 pResponse
->GetVariableLong(VID_IMAGE_ID
);
1108 pResponse
->GetVariableStr(VID_CATEGORY_NAME
,
1109 (*ppList
)->pElements
[(*ppList
)->dwNumElements
].szName
, MAX_OBJECT_NAME
);
1110 (*ppList
)->pElements
[(*ppList
)->dwNumElements
].pszDescription
=
1111 pResponse
->GetVariableStr(VID_DESCRIPTION
);
1112 (*ppList
)->dwNumElements
++;
1118 dwRetCode
= RCC_TIMEOUT
;
1122 while(dwCatId
!= 0);
1124 // Destroy results on failure
1125 if (dwRetCode
!= RCC_SUCCESS
)
1127 safe_free((*ppList
)->pElements
);
1137 // Destroy list of container categories
1140 void LIBNXCL_EXPORTABLE
NXCDestroyCCList(NXC_CC_LIST
*pList
)
1147 for(i
= 0; i
< pList
->dwNumElements
; i
++)
1148 safe_free(pList
->pElements
[i
].pszDescription
);
1149 safe_free(pList
->pElements
);
1155 // Perform a forced node poll
1158 DWORD LIBNXCL_EXPORTABLE
NXCPollNode(NXC_SESSION hSession
, DWORD dwObjectId
, int iPollType
,
1159 void (* pfCallback
)(TCHAR
*, void *), void *pArg
)
1161 DWORD dwRetCode
, dwRqId
;
1162 CSCPMessage msg
, *pResponse
;
1165 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
1167 msg
.SetCode(CMD_POLL_NODE
);
1169 msg
.SetVariable(VID_OBJECT_ID
, dwObjectId
);
1170 msg
.SetVariable(VID_POLL_TYPE
, (WORD
)iPollType
);
1171 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
1175 // Polls can take a long time, so we wait up to 120 seconds for each message
1176 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_POLLING_INFO
, dwRqId
, 120000);
1177 if (pResponse
!= NULL
)
1179 dwRetCode
= pResponse
->GetVariableLong(VID_RCC
);
1180 if ((dwRetCode
== RCC_OPERATION_IN_PROGRESS
) && (pfCallback
!= NULL
))
1182 pszMsg
= pResponse
->GetVariableStr(VID_POLLER_MESSAGE
);
1183 pfCallback(pszMsg
, pArg
);
1190 dwRetCode
= RCC_TIMEOUT
;
1193 while(dwRetCode
== RCC_OPERATION_IN_PROGRESS
);
1200 // Wake up node by sending magic packet
1203 DWORD LIBNXCL_EXPORTABLE
NXCWakeUpNode(NXC_SESSION hSession
, DWORD dwObjectId
)
1208 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
1210 msg
.SetCode(CMD_WAKEUP_NODE
);
1212 msg
.SetVariable(VID_OBJECT_ID
, dwObjectId
);
1213 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
1214 return ((NXCL_Session
*)hSession
)->WaitForRCC(dwRqId
);
1219 // Retrieve list of supported agent parameters
1222 DWORD LIBNXCL_EXPORTABLE
NXCGetSupportedParameters(NXC_SESSION hSession
, DWORD dwNodeId
,
1223 DWORD
*pdwNumParams
,
1224 NXC_AGENT_PARAM
**ppParamList
)
1226 CSCPMessage msg
, *pResponse
;
1227 DWORD i
, dwId
, dwRqId
, dwRetCode
;
1229 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
1232 *ppParamList
= NULL
;
1234 // Build request message
1235 msg
.SetCode(CMD_GET_PARAMETER_LIST
);
1237 msg
.SetVariable(VID_OBJECT_ID
, dwNodeId
);
1240 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
1242 // Wait for response
1243 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
);
1244 if (pResponse
!= NULL
)
1246 dwRetCode
= pResponse
->GetVariableLong(VID_RCC
);
1247 if (dwRetCode
== RCC_SUCCESS
)
1249 *pdwNumParams
= pResponse
->GetVariableLong(VID_NUM_PARAMETERS
);
1250 *ppParamList
= (NXC_AGENT_PARAM
*)malloc(sizeof(NXC_AGENT_PARAM
) * *pdwNumParams
);
1251 for(i
= 0, dwId
= VID_PARAM_LIST_BASE
; i
< *pdwNumParams
; i
++)
1253 pResponse
->GetVariableStr(dwId
++, (*ppParamList
)[i
].szName
, MAX_PARAM_NAME
);
1254 pResponse
->GetVariableStr(dwId
++, (*ppParamList
)[i
].szDescription
, MAX_DB_STRING
);
1255 (*ppParamList
)[i
].iDataType
= (int)pResponse
->GetVariableShort(dwId
++);
1262 dwRetCode
= RCC_TIMEOUT
;
1270 // Check if object has default name formed from IP address
1273 static BOOL
ObjectHasDefaultName(NXC_OBJECT
*pObject
)
1275 if (pObject
->iClass
== OBJECT_SUBNET
)
1277 TCHAR szBuffer
[64], szIpAddr
[32];
1278 _sntprintf(szBuffer
, 64, _T("%s/%d"), IpToStr(pObject
->dwIpAddr
, szIpAddr
),
1279 BitsInMask(pObject
->subnet
.dwIpNetMask
));
1280 return !_tcscmp(szBuffer
, pObject
->szName
);
1284 return ((pObject
->dwIpAddr
!= 0) &&
1285 (ntohl(_t_inet_addr(pObject
->szName
)) == pObject
->dwIpAddr
));
1291 // Get object name suitable for comparision
1294 void LIBNXCL_EXPORTABLE
NXCGetComparableObjectName(NXC_SESSION hSession
, DWORD dwObjectId
, TCHAR
*pszName
)
1296 NXCGetComparableObjectNameEx(((NXCL_Session
*)hSession
)->FindObjectById(dwObjectId
, TRUE
), pszName
);
1301 // Get object name suitable for comparision
1304 void LIBNXCL_EXPORTABLE
NXCGetComparableObjectNameEx(NXC_OBJECT
*pObject
, TCHAR
*pszName
)
1306 if (pObject
!= NULL
)
1308 // If object has an IP address as name, we sort as numbers
1309 // otherwise in alphabetical order
1310 if (ObjectHasDefaultName(pObject
))
1312 _sntprintf(pszName
, MAX_OBJECT_NAME
, _T("\x01%03d%03d%03d%03d"),
1313 pObject
->dwIpAddr
>> 24, (pObject
->dwIpAddr
>> 16) & 255,
1314 (pObject
->dwIpAddr
>> 8) & 255, pObject
->dwIpAddr
& 255);
1318 _tcscpy(pszName
, pObject
->szName
);
1329 // Save object's cache to file
1332 DWORD LIBNXCL_EXPORTABLE
NXCSaveObjectCache(NXC_SESSION hSession
, const TCHAR
*pszFile
)
1335 OBJECT_CACHE_HEADER hdr
;
1336 DWORD i
, j
, dwResult
, dwNumObjects
, dwSize
;
1339 hFile
= _tfopen(pszFile
, _T("wb"));
1342 ((NXCL_Session
*)hSession
)->LockObjectIndex();
1343 pList
= (INDEX
*)((NXCL_Session
*)hSession
)->GetObjectIndex(&dwNumObjects
);
1345 // Write cache file header
1346 hdr
.dwMagic
= OBJECT_CACHE_MAGIC
;
1347 hdr
.dwStructSize
= sizeof(NXC_OBJECT
);
1348 hdr
.dwTimeStamp
= ((NXCL_Session
*)hSession
)->GetTimeStamp();
1349 hdr
.dwNumObjects
= dwNumObjects
;
1350 memcpy(hdr
.bsServerId
, ((NXCL_Session
*)hSession
)->m_bsServerId
, 8);
1351 fwrite(&hdr
, 1, sizeof(OBJECT_CACHE_HEADER
), hFile
);
1353 // Write all objects
1354 for(i
= 0; i
< dwNumObjects
; i
++)
1356 fwrite(pList
[i
].pObject
, 1, sizeof(NXC_OBJECT
), hFile
);
1357 fwrite(pList
[i
].pObject
->pdwChildList
, 1,
1358 sizeof(DWORD
) * pList
[i
].pObject
->dwNumChilds
, hFile
);
1359 fwrite(pList
[i
].pObject
->pdwParentList
, 1,
1360 sizeof(DWORD
) * pList
[i
].pObject
->dwNumParents
, hFile
);
1361 fwrite(pList
[i
].pObject
->pAccessList
, 1,
1362 sizeof(NXC_ACL_ENTRY
) * pList
[i
].pObject
->dwAclSize
, hFile
);
1364 dwSize
= (DWORD
)_tcslen(pList
[i
].pObject
->pszComments
) * sizeof(TCHAR
);
1365 fwrite(&dwSize
, 1, sizeof(DWORD
), hFile
);
1366 fwrite(pList
[i
].pObject
->pszComments
, 1, dwSize
, hFile
);
1368 if (pList
[i
].pObject
->dwNumTrustedNodes
> 0)
1369 fwrite(pList
[i
].pObject
->pdwTrustedNodes
, pList
[i
].pObject
->dwNumTrustedNodes
, sizeof(DWORD
), hFile
);
1371 // Custom attributes
1372 dwSize
= pList
[i
].pObject
->pCustomAttrs
->Size();
1373 fwrite(&dwSize
, 1, sizeof(DWORD
), hFile
);
1374 for(j
= 0; j
< pList
[i
].pObject
->pCustomAttrs
->Size(); j
++)
1376 dwSize
= (DWORD
)_tcslen(pList
[i
].pObject
->pCustomAttrs
->GetKeyByIndex(j
)) * sizeof(TCHAR
);
1377 fwrite(&dwSize
, 1, sizeof(DWORD
), hFile
);
1378 fwrite(pList
[i
].pObject
->pCustomAttrs
->GetKeyByIndex(j
), 1, dwSize
, hFile
);
1380 dwSize
= (DWORD
)_tcslen(pList
[i
].pObject
->pCustomAttrs
->GetValueByIndex(j
)) * sizeof(TCHAR
);
1381 fwrite(&dwSize
, 1, sizeof(DWORD
), hFile
);
1382 fwrite(pList
[i
].pObject
->pCustomAttrs
->GetValueByIndex(j
), 1, dwSize
, hFile
);
1385 switch(pList
[i
].pObject
->iClass
)
1387 case OBJECT_NETWORKSERVICE
:
1388 dwSize
= (DWORD
)_tcslen(pList
[i
].pObject
->netsrv
.pszRequest
) * sizeof(TCHAR
);
1389 fwrite(&dwSize
, 1, sizeof(DWORD
), hFile
);
1390 fwrite(pList
[i
].pObject
->netsrv
.pszRequest
, 1, dwSize
, hFile
);
1392 dwSize
= (DWORD
)_tcslen(pList
[i
].pObject
->netsrv
.pszResponse
) * sizeof(TCHAR
);
1393 fwrite(&dwSize
, 1, sizeof(DWORD
), hFile
);
1394 fwrite(pList
[i
].pObject
->netsrv
.pszResponse
, 1, dwSize
, hFile
);
1397 if (pList
[i
].pObject
->zone
.dwAddrListSize
> 0)
1398 fwrite(pList
[i
].pObject
->zone
.pdwAddrList
, sizeof(DWORD
),
1399 pList
[i
].pObject
->zone
.dwAddrListSize
, hFile
);
1401 case OBJECT_VPNCONNECTOR
:
1402 fwrite(pList
[i
].pObject
->vpnc
.pLocalNetList
, 1,
1403 pList
[i
].pObject
->vpnc
.dwNumLocalNets
* sizeof(IP_NETWORK
), hFile
);
1404 fwrite(pList
[i
].pObject
->vpnc
.pRemoteNetList
, 1,
1405 pList
[i
].pObject
->vpnc
.dwNumRemoteNets
* sizeof(IP_NETWORK
), hFile
);
1407 case OBJECT_CONDITION
:
1408 dwSize
= (DWORD
)_tcslen(pList
[i
].pObject
->cond
.pszScript
) * sizeof(TCHAR
);
1409 fwrite(&dwSize
, 1, sizeof(DWORD
), hFile
);
1410 fwrite(pList
[i
].pObject
->cond
.pszScript
, 1, dwSize
, hFile
);
1412 fwrite(pList
[i
].pObject
->cond
.pDCIList
, 1,
1413 pList
[i
].pObject
->cond
.dwNumDCI
* sizeof(INPUT_DCI
), hFile
);
1415 case OBJECT_CLUSTER
:
1416 fwrite(pList
[i
].pObject
->cluster
.pResourceList
, 1,
1417 pList
[i
].pObject
->cluster
.dwNumResources
* sizeof(CLUSTER_RESOURCE
), hFile
);
1418 fwrite(pList
[i
].pObject
->cluster
.pSyncNetList
, 1,
1419 pList
[i
].pObject
->cluster
.dwNumSyncNets
* sizeof(IP_NETWORK
), hFile
);
1426 ((NXCL_Session
*)hSession
)->UnlockObjectIndex();
1428 dwResult
= RCC_SUCCESS
;
1432 dwResult
= RCC_IO_ERROR
;
1440 // Load objects from cache file
1443 void NXCL_Session::LoadObjectsFromCache(const TCHAR
*pszFile
)
1446 OBJECT_CACHE_HEADER hdr
;
1448 DWORD i
, j
, dwSize
, dwCount
;
1451 hFile
= _tfopen(pszFile
, _T("rb"));
1455 DebugPrintf(_T("Checking cache file %s"), pszFile
);
1456 if (fread(&hdr
, 1, sizeof(OBJECT_CACHE_HEADER
), hFile
) == sizeof(OBJECT_CACHE_HEADER
))
1458 if ((hdr
.dwMagic
== OBJECT_CACHE_MAGIC
) &&
1459 (hdr
.dwStructSize
== sizeof(NXC_OBJECT
)) &&
1460 (!memcmp(hdr
.bsServerId
, m_bsServerId
, 8)))
1462 DebugPrintf(_T("Cache file OK, loading objects"));
1463 m_dwTimeStamp
= hdr
.dwTimeStamp
;
1464 for(i
= 0; i
< hdr
.dwNumObjects
; i
++)
1466 if (fread(&object
, 1, sizeof(NXC_OBJECT
), hFile
) == sizeof(NXC_OBJECT
))
1468 object
.pdwChildList
= (DWORD
*)malloc(sizeof(DWORD
) * object
.dwNumChilds
);
1469 fread(object
.pdwChildList
, 1, sizeof(DWORD
) * object
.dwNumChilds
, hFile
);
1471 object
.pdwParentList
= (DWORD
*)malloc(sizeof(DWORD
) * object
.dwNumParents
);
1472 fread(object
.pdwParentList
, 1, sizeof(DWORD
) * object
.dwNumParents
, hFile
);
1474 object
.pAccessList
= (NXC_ACL_ENTRY
*)malloc(sizeof(NXC_ACL_ENTRY
) * object
.dwAclSize
);
1475 fread(object
.pAccessList
, 1, sizeof(NXC_ACL_ENTRY
) * object
.dwAclSize
, hFile
);
1477 fread(&dwSize
, 1, sizeof(DWORD
), hFile
);
1478 object
.pszComments
= (TCHAR
*)malloc(dwSize
+ sizeof(TCHAR
));
1479 fread(object
.pszComments
, 1, dwSize
, hFile
);
1480 object
.pszComments
[dwSize
/ sizeof(TCHAR
)] = 0;
1482 if (object
.dwNumTrustedNodes
> 0)
1484 object
.pdwTrustedNodes
= (DWORD
*)malloc(sizeof(DWORD
) * object
.dwNumTrustedNodes
);
1485 fread(object
.pdwTrustedNodes
, sizeof(DWORD
), object
.dwNumTrustedNodes
, hFile
);
1489 object
.pdwTrustedNodes
= NULL
;
1492 // Custom attributes
1493 object
.pCustomAttrs
= new StringMap
;
1494 fread(&dwCount
, 1, sizeof(DWORD
), hFile
);
1495 for(j
= 0; j
< dwCount
; j
++)
1497 fread(&dwSize
, 1, sizeof(DWORD
), hFile
);
1498 key
= (TCHAR
*)malloc(dwSize
+ sizeof(TCHAR
));
1499 fread(key
, 1, dwSize
, hFile
);
1500 key
[dwSize
/ sizeof(TCHAR
)] = 0;
1502 fread(&dwSize
, 1, sizeof(DWORD
), hFile
);
1503 value
= (TCHAR
*)malloc(dwSize
+ sizeof(TCHAR
));
1504 fread(value
, 1, dwSize
, hFile
);
1505 value
[dwSize
/ sizeof(TCHAR
)] = 0;
1507 object
.pCustomAttrs
->SetPreallocated(key
, value
);
1510 switch(object
.iClass
)
1512 case OBJECT_NETWORKSERVICE
:
1513 fread(&dwSize
, 1, sizeof(DWORD
), hFile
);
1514 object
.netsrv
.pszRequest
= (TCHAR
*)malloc(dwSize
+ sizeof(TCHAR
));
1515 fread(object
.netsrv
.pszRequest
, 1, dwSize
, hFile
);
1516 object
.netsrv
.pszRequest
[dwSize
/ sizeof(TCHAR
)] = 0;
1518 fread(&dwSize
, 1, sizeof(DWORD
), hFile
);
1519 object
.netsrv
.pszResponse
= (TCHAR
*)malloc(dwSize
+ sizeof(TCHAR
));
1520 fread(object
.netsrv
.pszResponse
, 1, dwSize
, hFile
);
1521 object
.netsrv
.pszResponse
[dwSize
/ sizeof(TCHAR
)] = 0;
1524 if (object
.zone
.dwAddrListSize
> 0)
1526 object
.zone
.pdwAddrList
= (DWORD
*)malloc(object
.zone
.dwAddrListSize
* sizeof(DWORD
));
1527 fread(object
.zone
.pdwAddrList
, sizeof(DWORD
), object
.zone
.dwAddrListSize
, hFile
);
1531 object
.zone
.pdwAddrList
= NULL
;
1534 case OBJECT_VPNCONNECTOR
:
1535 dwSize
= object
.vpnc
.dwNumLocalNets
* sizeof(IP_NETWORK
);
1536 object
.vpnc
.pLocalNetList
= (IP_NETWORK
*)malloc(dwSize
);
1537 fread(object
.vpnc
.pLocalNetList
, 1, dwSize
, hFile
);
1539 dwSize
= object
.vpnc
.dwNumRemoteNets
* sizeof(IP_NETWORK
);
1540 object
.vpnc
.pRemoteNetList
= (IP_NETWORK
*)malloc(dwSize
);
1541 fread(object
.vpnc
.pRemoteNetList
, 1, dwSize
, hFile
);
1543 case OBJECT_CONDITION
:
1544 fread(&dwSize
, 1, sizeof(DWORD
), hFile
);
1545 object
.cond
.pszScript
= (TCHAR
*)malloc(dwSize
+ sizeof(TCHAR
));
1546 fread(object
.cond
.pszScript
, 1, dwSize
, hFile
);
1547 object
.cond
.pszScript
[dwSize
/ sizeof(TCHAR
)] = 0;
1549 dwSize
= object
.cond
.dwNumDCI
* sizeof(INPUT_DCI
);
1550 object
.cond
.pDCIList
= (INPUT_DCI
*)malloc(dwSize
);
1551 fread(object
.cond
.pDCIList
, 1, dwSize
, hFile
);
1553 case OBJECT_CLUSTER
:
1554 if (object
.cluster
.dwNumResources
> 0)
1556 object
.cluster
.pResourceList
= (CLUSTER_RESOURCE
*)malloc(sizeof(CLUSTER_RESOURCE
) * object
.cluster
.dwNumResources
);
1557 fread(object
.cluster
.pResourceList
, 1, sizeof(CLUSTER_RESOURCE
) * object
.cluster
.dwNumResources
, hFile
);
1561 object
.cluster
.pResourceList
= NULL
;
1563 if (object
.cluster
.dwNumSyncNets
> 0)
1565 object
.cluster
.pSyncNetList
= (IP_NETWORK
*)malloc(sizeof(IP_NETWORK
) * object
.cluster
.dwNumSyncNets
);
1566 fread(object
.cluster
.pSyncNetList
, 1, sizeof(IP_NETWORK
) * object
.cluster
.dwNumSyncNets
, hFile
);
1570 object
.cluster
.pSyncNetList
= NULL
;
1577 AddObject((NXC_OBJECT
*)nx_memdup(&object
, sizeof(NXC_OBJECT
)), FALSE
);
1581 qsort(m_pIndexById
, m_dwNumObjects
, sizeof(INDEX
), IndexCompare
);
1582 UnlockObjectIndex();
1583 m_dwFlags
|= NXC_SF_HAS_OBJECT_CACHE
;
1593 // Change node's IP address
1596 DWORD LIBNXCL_EXPORTABLE
NXCChangeNodeIP(NXC_SESSION hSession
, DWORD dwNodeId
, DWORD dwIpAddr
)
1601 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
1603 msg
.SetCode(CMD_CHANGE_IP_ADDR
);
1605 msg
.SetVariable(VID_OBJECT_ID
, dwNodeId
);
1606 msg
.SetVariable(VID_IP_ADDRESS
, dwIpAddr
);
1607 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
1608 return ((NXCL_Session
*)hSession
)->WaitForRCC(dwRqId
, 300000);
1613 // Read agent's configuration file
1616 DWORD LIBNXCL_EXPORTABLE
NXCGetAgentConfig(NXC_SESSION hSession
, DWORD dwNodeId
,
1619 CSCPMessage msg
, *pResponse
;
1620 DWORD dwRqId
, dwRetCode
;
1622 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
1626 // Build request message
1627 msg
.SetCode(CMD_GET_AGENT_CONFIG
);
1629 msg
.SetVariable(VID_OBJECT_ID
, dwNodeId
);
1632 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
1634 // Wait for response
1635 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
, 60000);
1636 if (pResponse
!= NULL
)
1638 dwRetCode
= pResponse
->GetVariableLong(VID_RCC
);
1639 if (dwRetCode
== RCC_SUCCESS
)
1641 *ppszConfig
= pResponse
->GetVariableStr(VID_CONFIG_FILE
);
1647 dwRetCode
= RCC_TIMEOUT
;
1655 // Update agent's configuration file
1658 DWORD LIBNXCL_EXPORTABLE
NXCUpdateAgentConfig(NXC_SESSION hSession
, DWORD dwNodeId
,
1659 TCHAR
*pszConfig
, BOOL bApply
)
1664 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
1666 // Build request message
1667 msg
.SetCode(CMD_UPDATE_AGENT_CONFIG
);
1669 msg
.SetVariable(VID_OBJECT_ID
, dwNodeId
);
1670 msg
.SetVariable(VID_CONFIG_FILE
, pszConfig
);
1671 msg
.SetVariable(VID_APPLY_FLAG
, (WORD
)bApply
);
1674 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
1676 return ((NXCL_Session
*)hSession
)->WaitForRCC(dwRqId
, 60000);
1681 // Execute action on agent
1684 DWORD LIBNXCL_EXPORTABLE
NXCExecuteAction(NXC_SESSION hSession
, DWORD dwObjectId
,
1690 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
1692 msg
.SetCode(CMD_EXECUTE_ACTION
);
1694 msg
.SetVariable(VID_OBJECT_ID
, dwObjectId
);
1695 msg
.SetVariable(VID_ACTION_NAME
, pszAction
);
1696 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
1697 return ((NXCL_Session
*)hSession
)->WaitForRCC(dwRqId
);
1702 // Get object's comments
1705 DWORD LIBNXCL_EXPORTABLE
NXCGetObjectComments(NXC_SESSION hSession
,
1706 DWORD dwObjectId
, TCHAR
**ppszText
)
1708 DWORD dwRqId
, dwResult
;
1709 CSCPMessage msg
, *pResponse
;
1711 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
1713 msg
.SetCode(CMD_GET_OBJECT_COMMENTS
);
1715 msg
.SetVariable(VID_OBJECT_ID
, dwObjectId
);
1716 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
1718 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
);
1719 if (pResponse
!= NULL
)
1721 dwResult
= pResponse
->GetVariableLong(VID_RCC
);
1722 if (dwResult
== RCC_SUCCESS
)
1723 *ppszText
= pResponse
->GetVariableStr(VID_COMMENTS
);
1727 dwResult
= RCC_TIMEOUT
;
1734 // Update object's comments
1737 DWORD LIBNXCL_EXPORTABLE
NXCUpdateObjectComments(NXC_SESSION hSession
,
1738 DWORD dwObjectId
, TCHAR
*pszText
)
1743 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
1745 msg
.SetCode(CMD_UPDATE_OBJECT_COMMENTS
);
1747 msg
.SetVariable(VID_OBJECT_ID
, dwObjectId
);
1748 msg
.SetVariable(VID_COMMENTS
, pszText
);
1749 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
1750 return ((NXCL_Session
*)hSession
)->WaitForRCC(dwRqId
);
1755 // Actual check for parent-child relation
1758 static BOOL
IsParent(NXC_SESSION hSession
, DWORD dwParent
, DWORD dwChild
)
1761 NXC_OBJECT
*pObject
;
1764 pObject
= ((NXCL_Session
*)hSession
)->FindObjectById(dwChild
, FALSE
);
1765 if (pObject
!= NULL
)
1767 for(i
= 0; i
< pObject
->dwNumParents
; i
++)
1769 if (pObject
->pdwParentList
[i
] == dwParent
)
1778 for(i
= 0; i
< pObject
->dwNumParents
; i
++)
1780 if (IsParent(hSession
, dwParent
, pObject
->pdwParentList
[i
]))
1793 // Check if first object is a parent of second object
1796 BOOL LIBNXCL_EXPORTABLE
NXCIsParent(NXC_SESSION hSession
, DWORD dwParent
, DWORD dwChild
)
1800 ((NXCL_Session
*)hSession
)->LockObjectIndex();
1801 bRet
= IsParent(hSession
, dwParent
, dwChild
);
1802 ((NXCL_Session
*)hSession
)->UnlockObjectIndex();
1808 // Get list of events used by template's or node's DCIs
1811 DWORD LIBNXCL_EXPORTABLE
NXCGetDCIEventsList(NXC_SESSION hSession
, DWORD dwObjectId
,
1812 DWORD
**ppdwList
, DWORD
*pdwListSize
)
1814 DWORD dwRqId
, dwResult
;
1815 CSCPMessage msg
, *pResponse
;
1820 dwRqId
= ((NXCL_Session
*)hSession
)->CreateRqId();
1822 msg
.SetCode(CMD_GET_DCI_EVENTS_LIST
);
1824 msg
.SetVariable(VID_OBJECT_ID
, dwObjectId
);
1825 ((NXCL_Session
*)hSession
)->SendMsg(&msg
);
1827 pResponse
= ((NXCL_Session
*)hSession
)->WaitForMessage(CMD_REQUEST_COMPLETED
, dwRqId
);
1828 if (pResponse
!= NULL
)
1830 dwResult
= pResponse
->GetVariableLong(VID_RCC
);
1831 if (dwResult
== RCC_SUCCESS
)
1833 *pdwListSize
= pResponse
->GetVariableLong(VID_NUM_EVENTS
);
1834 if (*pdwListSize
> 0)
1836 *ppdwList
= (DWORD
*)malloc(sizeof(DWORD
) * (*pdwListSize
));
1837 pResponse
->GetVariableInt32Array(VID_EVENT_LIST
, *pdwListSize
, *ppdwList
);
1844 dwResult
= RCC_TIMEOUT
;