- Added support for data collection item duplication within same node
authorVictor Kirhenshtein <victor@netxms.org>
Wed, 20 Oct 2004 13:06:57 +0000 (13:06 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Wed, 20 Oct 2004 13:06:57 +0000 (13:06 +0000)
- Now possible to copy DCIs to many nodes at once
- Fixed memory management bugs in Windows console DCI editor
- Added "instance" field to DCI which can be used as information text in user-defined data collection events and alarms
- Client library do cleanup after NXCDisconnect()
- User system rights now ORed with its group(s) system rights

26 files changed:
ChangeLog
TODO
include/nms_cscp.h
include/nxclapi.h
sql/events.in
src/console/win32/DCIThresholdsPage.cpp
src/console/win32/DCIThresholdsPage.h
src/console/win32/DataCollectionEditor.cpp
src/console/win32/DataCollectionEditor.h
src/console/win32/comm.cpp
src/console/win32/globals.h
src/console/win32/nxcon.clw
src/console/win32/nxcon.rc
src/console/win32/resource.h
src/libnxcl/actions.cpp
src/libnxcl/comm.cpp
src/libnxcl/datacoll.cpp
src/libnxcl/libnxcl.h
src/libnxcl/objects.cpp
src/libnxcl/users.cpp
src/server/core/dcitem.cpp
src/server/core/users.cpp
src/server/libnxsrv/messages.mc
src/server/tools/nxdbmgr/nxdbmgr.cpp
src/server/tools/nxdbmgr/nxdbmgr.h
src/server/tools/nxdbmgr/upgrade.cpp

index fb3ab3e..c0114a3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,13 @@
 - Added parameter System.ServiceState(*) to core agent (Windows only)
 - Implemented user-defined counters in WinPerf subagent
 - Added support for macros in e-mail subject
+- Added support for data collection item duplication within same node
+- Now possible to copy DCIs to many nodes at once
+- Fixed memory management bugs in Windows console DCI editor
+- Added "instance" field to DCI which can be used as information text in
+  user-defined data collection events and alarms
+- Client library do cleanup after NXCDisconnect()
+- User system rights now ORed with its group(s) system rights
 
 
 *
diff --git a/TODO b/TODO
index 039214b..156e239 100644 (file)
--- a/TODO
+++ b/TODO
@@ -18,6 +18,7 @@ GENERAL:
 - Allow converting counters to deltas in data collection
 - Add ability to clear collected DCI data
 - Add ability to send Wake-On-LAN packets to managed nodes
+- Add possibility to set different polling timeouts for different nodes
 
 
 SERVER:
@@ -43,8 +44,6 @@ CORE AGENT:
 WINDOWS CONSOLE:
 
 - Add custom background erasing code in policy editor for smooth painting
-- Add support for "View -> Refresh" in data collection configurator
-  (or, even better, automatic update)
 - Automatically select data type in DCI configuration dialog based on
   selected parameter
 - Add parameter selection for native agents in DCI configuration dialog
index d1f7244..cd15fd2 100644 (file)
@@ -375,6 +375,7 @@ typedef struct
 #define VID_MAC_ADDR                ((DWORD)113)
 #define VID_TEMPLATE_VERSION        ((DWORD)114)
 #define VID_NODE_TYPE               ((DWORD)115)
+#define VID_INSTANCE                ((DWORD)116)
 
 // Variable ranges for object's ACL
 #define VID_ACL_USER_BASE           ((DWORD)0x00001000)
index 0fb126f..7ea6832 100644 (file)
@@ -647,6 +647,7 @@ typedef struct
    DWORD dwTemplateId;
    TCHAR szName[MAX_ITEM_NAME];
    TCHAR szDescription[MAX_DB_STRING];
+   TCHAR szInstance[MAX_DB_STRING];
    int iPollingInterval;
    int iRetentionTime;
    BYTE iSource;
index e96631b..f28a7c5 100644 (file)
@@ -308,7 +308,7 @@ INSERT INTO events (event_id,name,severity,flags,message,description) VALUES
        (
                4004, 'DC_SERVICE_NOT_RUNNING',
                EVENT_SEVERITY_MAJOR, 1,
-               'Service "%5" is not running',
+               'Service "%6" is not running',
                'Custom data collection threshold event.#0D#0A' CONCAT
                'Parameters:#0D#0A' CONCAT
                THRESHOLD_EVENT_PARAMS
index 285fac1..c78250e 100644 (file)
@@ -19,6 +19,7 @@ IMPLEMENT_DYNCREATE(CDCIThresholdsPage, CPropertyPage)
 CDCIThresholdsPage::CDCIThresholdsPage() : CPropertyPage(CDCIThresholdsPage::IDD)
 {
        //{{AFX_DATA_INIT(CDCIThresholdsPage)
+       m_strInstance = _T("");
        //}}AFX_DATA_INIT
 }
 
@@ -35,6 +36,8 @@ void CDCIThresholdsPage::DoDataExchange(CDataExchange* pDX)
        DDX_Control(pDX, IDC_BUTTON_MOVEDOWN, m_wndButtonDown);
        DDX_Control(pDX, IDC_BUTTON_MOVEUP, m_wndButtonUp);
        DDX_Control(pDX, IDC_LIST_THRESHOLDS, m_wndListCtrl);
+       DDX_Text(pDX, IDC_EDIT_INSTANCE, m_strInstance);
+       DDV_MaxChars(pDX, m_strInstance, 255);
        //}}AFX_DATA_MAP
 }
 
@@ -68,7 +71,9 @@ BOOL CDCIThresholdsPage::OnInitDialog()
    // Setup buttons
    m_wndButtonUp.SetBitmap(CreateMappedBitmap(theApp.m_hInstance, IDB_UP_ARROW, 0, NULL, 0));
    m_wndButtonDown.SetBitmap(CreateMappedBitmap(theApp.m_hInstance, IDB_DOWN_ARROW, 0, NULL, 0));
-       
+   m_wndButtonModify.EnableWindow(FALSE);
+   m_wndButtonDelete.EnableWindow(FALSE);
+   
    // Setup list view
    m_wndListCtrl.GetClientRect(&rect);
    m_wndListCtrl.InsertColumn(0, "Operation", LVCFMT_LEFT, rect.right - 150 - GetSystemMetrics(SM_CXVSCROLL));
index 7f260b4..87434de 100644 (file)
@@ -30,6 +30,7 @@ public:
        CButton m_wndButtonDown;
        CButton m_wndButtonUp;
        CListCtrl       m_wndListCtrl;
+       CString m_strInstance;
        //}}AFX_DATA
 
 
index a65d2c9..6eb77aa 100644 (file)
@@ -55,6 +55,10 @@ BEGIN_MESSAGE_MAP(CDataCollectionEditor, CMDIChildWnd)
        ON_COMMAND(ID_ITEM_COPY, OnItemCopy)
        ON_COMMAND(ID_FILE_EXPORT, OnFileExport)
        ON_UPDATE_COMMAND_UI(ID_FILE_EXPORT, OnUpdateFileExport)
+       ON_COMMAND(ID_VIEW_REFRESH, OnViewRefresh)
+       ON_COMMAND(ID_ITEM_DUPLICATE, OnItemDuplicate)
+       ON_UPDATE_COMMAND_UI(ID_ITEM_COPY, OnUpdateItemCopy)
+       ON_UPDATE_COMMAND_UI(ID_ITEM_DUPLICATE, OnUpdateItemDuplicate)
        //}}AFX_MSG_MAP
        ON_NOTIFY(NM_DBLCLK, IDC_LIST_VIEW, OnListViewDblClk)
 END_MESSAGE_MAP()
@@ -132,7 +136,7 @@ void CDataCollectionEditor::OnClose()
 {
    DWORD dwResult;
 
-   dwResult = DoRequestArg1(NXCCloseNodeDCIList, m_pItemList, "Saving node's data collection information...");
+   dwResult = DoRequestArg1(NXCCloseNodeDCIList, m_pItemList, "Unlocking node's data collection information...");
    if (dwResult != RCC_SUCCESS)
       theApp.ErrorBox(dwResult, "Unable to close data collection configuration:\n%s");
        
@@ -272,20 +276,29 @@ void CDataCollectionEditor::OnItemEdit()
       if (dwIndex != INVALID_INDEX)
       {
          memcpy(&item, &m_pItemList->pItems[dwIndex], sizeof(NXC_DCI));
+         item.pThresholdList = (NXC_DCI_THRESHOLD *)nx_memdup(
+                           m_pItemList->pItems[dwIndex].pThresholdList, 
+                           sizeof(NXC_DCI_THRESHOLD) * item.dwNumThresholds);
          if (EditItem(&item))
          {
             dwResult = DoRequestArg2(NXCUpdateDCI, (void *)m_pItemList->dwNodeId, &item,
                                      "Updating data collection item...");
             if (dwResult == RCC_SUCCESS)
             {
+               free(m_pItemList->pItems[dwIndex].pThresholdList);
                memcpy(&m_pItemList->pItems[dwIndex], &item, sizeof(NXC_DCI));
                UpdateListItem(iItem, &m_pItemList->pItems[dwIndex]);
             }
             else
             {
+               free(item.pThresholdList);
                theApp.ErrorBox(dwResult, "Unable to update data collection item: %s");
             }
          }
+         else
+         {
+            free(item.pThresholdList);
+         }
       }
    }
 }
@@ -318,6 +331,7 @@ BOOL CDataCollectionEditor::EditItem(NXC_DCI *pItem)
 
    // Setup "Thresholds" page
    pgThresholds.m_pItem = pItem;
+   pgThresholds.m_strInstance = pItem->szInstance;
 
    // Setup property sheet and run
    dlg.SetTitle("Data Collection Item");
@@ -340,6 +354,8 @@ BOOL CDataCollectionEditor::EditItem(NXC_DCI *pItem)
       pItem->iDeltaCalculation = pgTransform.m_iDeltaProc;
       safe_free(pItem->pszFormula);
       pItem->pszFormula = strdup((LPCTSTR)pgTransform.m_strFormula);
+      strcpy(pItem->szInstance, (LPCTSTR)pgThresholds.m_strInstance);
+      StrStrip(pItem->szInstance);
       bSuccess = TRUE;
    }
    return bSuccess;
@@ -381,6 +397,16 @@ void CDataCollectionEditor::OnUpdateItemGraph(CCmdUI* pCmdUI)
    pCmdUI->Enable(m_wndListCtrl.GetSelectedCount() == 1);
 }
 
+void CDataCollectionEditor::OnUpdateItemCopy(CCmdUI* pCmdUI) 
+{
+   pCmdUI->Enable(m_wndListCtrl.GetSelectedCount() > 0);
+}
+
+void CDataCollectionEditor::OnUpdateItemDuplicate(CCmdUI* pCmdUI) 
+{
+   pCmdUI->Enable(m_wndListCtrl.GetSelectedCount() > 0);
+}
+
 void CDataCollectionEditor::OnUpdateFileExport(CCmdUI* pCmdUI) 
 {
    NXC_OBJECT *pObject;
@@ -520,6 +546,25 @@ BOOL CDataCollectionEditor::PreCreateWindow(CREATESTRUCT& cs)
 }
 
 
+//
+// Copy DCIs to host(s)
+//
+
+static DWORD __cdecl CopyItems(DWORD dwSourceNode, DWORD dwNumObjects, DWORD *pdwObjectList,
+                       DWORD dwNumItems, DWORD *pdwItemList)
+{
+   DWORD i, dwResult;
+
+   for(i = 0; i < dwNumObjects; i++)
+   {
+      dwResult = NXCCopyDCI(dwSourceNode, pdwObjectList[i], dwNumItems, pdwItemList);
+      if (dwResult != RCC_SUCCESS)
+         break;
+   }
+   return dwResult;
+}
+
+
 //
 // WM_COMMAND::ID_ITEM_COPY message handler
 //
@@ -548,10 +593,10 @@ void CDataCollectionEditor::OnItemCopy()
       dlg.m_dwAllowedClasses = SCL_NODE;
       if (dlg.DoModal() == IDOK)
       {
-         // Perform request to server
-         dwResult = DoRequestArg4(NXCCopyDCI, (void *)m_pItemList->dwNodeId, 
-               (void *)dlg.m_pdwObjectList[0], (void *)dwNumItems
-               pdwItemList, "Copying items...");
+         // Perform request(s) to server
+         dwResult = DoRequestArg5(CopyItems, (void *)m_pItemList->dwNodeId, 
+               (void *)dlg.m_dwNumObjects, dlg.m_pdwObjectList
+               (void *)dwNumItems, pdwItemList, "Copying items...");
          if (dwResult != RCC_SUCCESS)
             theApp.ErrorBox(dwResult, "Error copying items: %s");
       }
@@ -562,6 +607,43 @@ void CDataCollectionEditor::OnItemCopy()
 }
 
 
+//
+// WM_COMMAND::ID_ITEM_DUPLICATE message handler
+//
+
+void CDataCollectionEditor::OnItemDuplicate() 
+{
+   int iPos, iItem;
+   DWORD dwResult, dwNumItems, *pdwItemList;
+
+   dwNumItems = m_wndListCtrl.GetSelectedCount();
+   if (dwNumItems > 0)
+   {
+      pdwItemList = (DWORD *)malloc(sizeof(DWORD) * dwNumItems);
+
+      // Build list of items to be copied
+      iPos = 0;
+      iItem = m_wndListCtrl.GetNextItem(-1, LVNI_SELECTED);
+      while(iItem != -1)
+      {
+         pdwItemList[iPos++] = m_wndListCtrl.GetItemData(iItem);
+         iItem = m_wndListCtrl.GetNextItem(iItem, LVNI_SELECTED);
+      }
+
+      // Perform request(s) to server
+      dwResult = DoRequestArg4(NXCCopyDCI, (void *)m_pItemList->dwNodeId, 
+               (void *)m_pItemList->dwNodeId, (void *)dwNumItems, 
+               pdwItemList, "Copying items...");
+      if (dwResult != RCC_SUCCESS)
+         theApp.ErrorBox(dwResult, "Error copying items: %s");
+      PostMessage(WM_COMMAND, ID_VIEW_REFRESH, 0);
+
+      // Cleanup
+      free(pdwItemList);
+   }
+}
+
+
 //
 // WM_COMMAND::ID_FILE_EXPORT message handler
 //
@@ -578,3 +660,30 @@ void CDataCollectionEditor::OnFileExport()
       MessageBox(dlg.m_ofn.lpstrFile,"FILE");
    }
 }
+
+
+//
+// WM_COMMAND::ID_VIEW_REFRESH message handler
+//
+
+void CDataCollectionEditor::OnViewRefresh() 
+{
+   DWORD i, dwResult, dwObjectId;
+
+   dwObjectId = m_pItemList->dwNodeId;
+
+   // Re-open node's DCI list
+   dwResult = DoRequestArg1(NXCCloseNodeDCIList, m_pItemList, "Unlocking node's data collection information...");
+   if (dwResult != RCC_SUCCESS)
+      theApp.ErrorBox(dwResult, "Unable to close data collection configuration:\n%s");
+
+   dwResult = DoRequestArg2(NXCOpenNodeDCIList, (void *)dwObjectId, 
+                            &m_pItemList, "Loading node's data collection information...");
+   if (dwResult != RCC_SUCCESS)
+      theApp.ErrorBox(dwResult, "Unable to load data collection information for node:\n%s");
+
+   // Fill list view with data
+   m_wndListCtrl.DeleteAllItems();
+   for(i = 0; i < m_pItemList->dwNumItems; i++)
+      AddListItem(&m_pItemList->pItems[i]);
+}
index 91b48fb..a139687 100644 (file)
@@ -60,6 +60,10 @@ protected:
        afx_msg void OnItemCopy();
        afx_msg void OnFileExport();
        afx_msg void OnUpdateFileExport(CCmdUI* pCmdUI);
+       afx_msg void OnViewRefresh();
+       afx_msg void OnItemDuplicate();
+       afx_msg void OnUpdateItemCopy(CCmdUI* pCmdUI);
+       afx_msg void OnUpdateItemDuplicate(CCmdUI* pCmdUI);
        //}}AFX_MSG
    afx_msg void OnListViewDblClk(LPNMITEMACTIVATE pNMHDR, LRESULT *pResult);
        DECLARE_MESSAGE_MAP()
index 57fd5dc..a434ca0 100644 (file)
@@ -110,6 +110,8 @@ static DWORD WINAPI LoginThread(void *pArg)
    {
       SetInfoText(hWnd, "Loading action configuration...");
       dwResult = NXCLoadActions(&g_dwNumActions, &g_pActionList);
+      if (dwResult == RCC_ACCESS_DENIED)
+         dwResult = RCC_SUCCESS;    // User may not have rights to see actions, it's ok here
    }
 
    if (dwResult == RCC_SUCCESS)
@@ -235,6 +237,10 @@ static DWORD WINAPI RequestThread(void *pArg)
       case 4:
          dwResult = pData->pFunc(pData->pArg1, pData->pArg2, pData->pArg3, pData->pArg4);
          break;
+      case 5:
+         dwResult = pData->pFunc(pData->pArg1, pData->pArg2, pData->pArg3, 
+                                 pData->pArg4, pData->pArg5);
+         break;
       case 6:
          dwResult = pData->pFunc(pData->pArg1, pData->pArg2, pData->pArg3, 
                                  pData->pArg4, pData->pArg5, pData->pArg6);
@@ -373,6 +379,27 @@ DWORD DoRequestArg4(void *pFunc, void *pArg1, void *pArg2, void *pArg3,
 }
 
 
+//
+// Perform request with 5 parameter
+//
+
+DWORD DoRequestArg5(void *pFunc, void *pArg1, void *pArg2, void *pArg3, void *pArg4, 
+                    void *pArg5, char *pszInfoText)
+{
+   RqData rqData;
+
+   rqData.hWnd = NULL;
+   rqData.dwNumParams = 5;
+   rqData.pArg1 = pArg1;
+   rqData.pArg2 = pArg2;
+   rqData.pArg3 = pArg3;
+   rqData.pArg4 = pArg4;
+   rqData.pArg5 = pArg5;
+   rqData.pFunc = (DWORD (*)(...))pFunc;
+   return ExecuteRequest(&rqData, pszInfoText);
+}
+
+
 //
 // Perform request with 6 parameter
 //
index cddab5a..2f541e2 100644 (file)
@@ -141,6 +141,8 @@ DWORD DoRequestArg1(void *pFunc, void *pArg1, char *pszInfoText);
 DWORD DoRequestArg2(void *pFunc, void *pArg1, void *pArg2, char *pszInfoText);
 DWORD DoRequestArg3(void *pFunc, void *pArg1, void *pArg2, void *pArg3, char *pszInfoText);
 DWORD DoRequestArg4(void *pFunc, void *pArg1, void *pArg2, void *pArg3, void *pArg4, char *pszInfoText);
+DWORD DoRequestArg5(void *pFunc, void *pArg1, void *pArg2, void *pArg3, void *pArg4, 
+                    void *pArg5, char *pszInfoText);
 DWORD DoRequestArg6(void *pFunc, void *pArg1, void *pArg2, void *pArg3, void *pArg4, 
                     void *pArg5, void *pArg6, char *pszInfoText);
 DWORD WINAPI PollerThread(void *pArg);
index df4bd28..d7b757d 100644 (file)
@@ -2,7 +2,7 @@
 
 [General Info]
 Version=1
-LastClass=CCreateNodeDlg
+LastClass=CDCIThresholdsPage
 LastTemplate=CDialog
 NewFileInclude1=#include "stdafx.h"
 NewFileInclude2=#include "nxcon.h"
@@ -17,20 +17,20 @@ Class9=CMapView
 
 ResourceCount=86
 Resource1=IDD_THRESHOLD (English (U.S.))
-Resource2=IDD_SELECT_USER
+Resource2=IDD_OBJECT_SECURITY
 Resource3=IDM_VIEW_SPECIFIC (English (U.S.))
-Resource4=IDD_LOGIN
-Resource5=IDA_NETMAP
+Resource4=IDA_EPP
+Resource5=IDA_MDI_DEFAULT
 Class2=CChildView
 Class5=CAboutDlg
 Class6=CControlPanel
 Class8=CMapFrame
 Class10=CLoginDialog
-Resource6=IDD_SELECT_ACTION
+Resource6=IDD_EDIT_RULE_ALARM
 Class11=CProgressDialog
-Resource7=IDD_REQUEST_PROCESSING
+Resource7=IDD_LOGIN
 Class12=CObjectBrowser
-Resource8=IDA_MDI_DEFAULT
+Resource8=IDD_CREATE_NODE
 Class13=CObjectPropDlg
 Resource9=IDD_CP_GENERAL (English (U.S.))
 Resource10=IDA_OBJECT_BROWSER (English (U.S.))
@@ -46,7 +46,7 @@ Resource17=IDD_SET_PASSWORD (English (U.S.))
 Class16=CDebugFrame
 Resource18=IDD_OBJECT_SECURITY (English (U.S.))
 Resource19=IDD_OBJECT_PROPERTIES (English (U.S.))
-Resource20=IDD_NEW_ACTION
+Resource20=IDD_OBJECT_PRESENTATION
 Class17=CObjectPreview
 Resource21=IDD_DCI_TRANSFORM (English (U.S.))
 Class18=CToolBox
@@ -59,32 +59,32 @@ Class23=CNodePropsGeneral
 Resource23=IDD_LOGIN (English (U.S.))
 Class24=CObjectPropCaps
 Class25=CObjectPropSheet
-Resource24=IDD_EDIT_RULE_COMMENT
+Resource24=IDD_DCI_THRESHOLDS
 Class26=CRequestProcessingDlg
 Resource25=IDD_EDIT_EVENT (English (U.S.))
 Resource26=IDD_PROGRESS (English (U.S.))
-Resource27=IDD_SET_PASSWORD
+Resource27=IDD_ACTION_PROPERTIES
 Resource28=IDD_USER_PROPERTIES (English (U.S.))
 Class27=CObjectPropsGeneral
 Resource29=IDA_ALARM_BROWSER (English (U.S.))
 Class28=CObjectPropsSecurity
 Resource30=IDD_CREATE_NODE (English (U.S.))
-Resource31=IDD_DCI_TRANSFORM
-Resource32=IDR_MAINFRAME
+Resource31=IDD_SELECT_USER
+Resource32=IDD_NEW_USER
 Class29=CUserSelectDlg
-Resource33=IDD_EDIT_RULE_ALARM
+Resource33=IDD_EDIT_RULE_COMMENT
 Class30=CUserEditor
 Resource34=IDD_DCI_PROPERTIES
 Class31=CNewUserDlg
-Resource35=IDD_OBJECT_GENERAL
-Resource36=IDD_USER_PROPERTIES
+Resource35=IDD_EDIT_EVENT
+Resource36=IDD_OBJECT_GENERAL
 Class32=CUserPropDlg
 Resource37=IDM_CONTEXT (English (U.S.))
-Resource38=IDD_MIB_BROWSER
+Resource38=IDD_SET_PASSWORD
 Class33=CGroupPropDlg
-Resource39=IDD_NEW_USER
-Resource40=IDD_CREATE_NODE
-Resource41=IDD_GROUP_PROPERTIES
+Resource39=IDD_REQUEST_PROCESSING
+Resource40=IDD_OBJECT_CAPS
+Resource41=IDD_NEW_ACTION
 Resource42=IDD_SELECT_OBJECT (English (U.S.))
 Class34=CPasswordChangeDlg
 Class35=CNodeSummary
@@ -100,55 +100,55 @@ Class41=CGraphFrame
 Class42=CDCIThresholdsPage
 Resource46=IDA_MDI_DEFAULT (English (U.S.))
 Resource47=IDD_OBJECT_CAPS (English (U.S.))
-Resource48=IDD_EDIT_RULE_SEVERITY
+Resource48=IDD_SELECT_OBJECT
 Class43=CThresholdDlg
 Resource49=IDD_SELECT_USER (English (U.S.))
-Resource50=IDD_ACTION_PROPERTIES
+Resource50=IDD_EDIT_RULE_SEVERITY
 Class44=CMIBBrowserDlg
 Class45=CEventPolicyEditor
 Class46=CRuleList
 Class47=CRuleHeader
 Resource51=IDR_MAINFRAME (English (U.S.))
-Resource52=IDD_SELECT_OBJECT
+Resource52=IDD_DCI_COLLECTION
 Class48=CObjectSelDlg
-Resource53=IDD_EDIT_EVENT
-Resource54=IDM_CONTEXT
+Resource53=IDA_ALARM_BROWSER
+Resource54=IDM_VIEW_SPECIFIC
 Class49=CRuleCommentDlg
-Resource55=IDD_SELECT_EVENT
+Resource55=IDD_THRESHOLD
 Class50=CEventSelDlg
-Resource56=IDA_ALARM_BROWSER
+Resource56=IDR_MAINFRAME
 Resource57=IDD_REQUEST_PROCESSING (English (U.S.))
-Resource58=IDD_CREATE_CONTAINER
+Resource58=IDD_CP_GENERAL
 Resource59=IDD_ABOUTBOX (English (U.S.))
 Resource60=IDD_MIB_BROWSER (English (U.S.))
 Class51=CObjectPropsPresentation
 Resource61=IDD_OBJECT_PRESENTATION (English (U.S.))
-Resource62=IDD_OBJECT_PRESENTATION
+Resource62=IDM_CONTEXT
 Class52=CRuleSeverityDlg
-Resource63=IDM_VIEW_SPECIFIC
+Resource63=IDD_MIB_BROWSER
 Class53=CRuleAlarmDlg
 Class54=CAlarmBrowser
 Resource64=IDD_SELECT_EVENT (English (U.S.))
-Resource65=IDD_CREATE_TG
+Resource65=IDD_SELECT_ACTION
 Resource66=IDD_NEW_ACTION (English (U.S.))
 Resource67=IDD_DCI_COLLECTION (English (U.S.))
 Resource68=IDD_NEW_USER (English (U.S.))
 Class55=CConsolePropsGeneral
 Class56=CActionEditor
-Resource69=IDD_THRESHOLD
-Resource70=IDD_OBJECT_SECURITY
+Resource69=IDD_GROUP_PROPERTIES
+Resource70=IDD_OBJECT_NODE_GENERAL
 Class57=CNewActionDlg
-Resource71=IDD_ABOUTBOX
+Resource71=IDA_OBJECT_BROWSER
 Class58=CEditActionDlg
-Resource72=IDD_DCI_THRESHOLDS
+Resource72=IDD_CREATE_CONTAINER
 Class59=CActionSelDlg
-Resource73=IDD_OBJECT_NODE_GENERAL
+Resource73=IDA_NETMAP
 Resource74=IDD_EDIT_RULE_COMMENT (English (U.S.))
 Resource75=IDD_EDIT_RULE_ALARM (English (U.S.))
-Resource76=IDA_OBJECT_BROWSER
+Resource76=IDD_DCI_TRANSFORM
 Class60=CCreateObjectDlg
 Class61=CCreateContainerDlg
-Resource77=IDD_DCI_COLLECTION
+Resource77=IDD_USER_PROPERTIES
 Class62=CCreateNodeDlg
 Resource78=IDA_EPP (English (U.S.))
 Resource79=IDD_CREATE_CONTAINER (English (U.S.))
@@ -158,11 +158,11 @@ Resource81=IDD_ACTION_PROPERTIES (English (U.S.))
 Class64=CPollNodeDlg
 Resource82=IDD_POLL_NODE (English (U.S.))
 Class65=CNodePoller
-Resource83=IDD_CP_GENERAL
-Resource84=IDA_EPP
+Resource83=IDD_SELECT_EVENT
+Resource84=IDD_CREATE_TG
 Class66=CCreateTemplateDlg
 Class67=CCreateTGDlg
-Resource85=IDD_OBJECT_CAPS
+Resource85=IDD_ABOUTBOX
 Resource86=IDD_CREATE_TEMPLATE
 
 [CLS:CConsoleApp]
@@ -612,47 +612,48 @@ Command29=ID_ITEM_NEW
 Command30=ID_ITEM_EDIT
 Command31=ID_ITEM_DELETE
 Command32=ID_ITEM_COPY
-Command33=ID_ITEM_ACTIVATE
-Command34=ID_ITEM_DISABLE
-Command35=ID_ITEM_SHOWDATA
-Command36=ID_ITEM_GRAPH
-Command37=ID_POLICY_ADD
-Command38=ID_POLICY_DELETE
-Command39=ID_POLICY_EDIT
-Command40=ID_POLICY_NEGATECELL
-Command41=ID_POLICY_INSERTRULE_ABOVE
-Command42=ID_POLICY_INSERTRULE_BELOW
-Command43=ID_POLICY_INSERTRULE_TOP
-Command44=ID_POLICY_INSERTRULE_BOTTOM
-Command45=ID_POLICY_DELETERULE
-Command46=ID_POLICY_ENABLERULE
-Command47=ID_POLICY_DISABLERULE
-Command48=ID_ALARM_ACKNOWLEGE
-Command49=ID_ALARM_DELETE
-Command50=ID_ALARM_GOTOSOURCE
-Command51=ID_UPDATE_EVENT_LIST
-Command52=ID_CONTROLPANEL_ACTIONS
-Command53=ID_CONTROLPANEL_EVENTS
-Command54=ID_CONTROLPANEL_EVENTPOLICY
-Command55=ID_CONTROLPANEL_USERS
-Command56=ID_CONTROLPANEL_DCT
-Command57=ID_OBJECT_OPEN
-Command58=ID_OBJECT_OPENPARENT
-Command59=ID_OBJECT_FIND
-Command60=ID_OBJECT_CREATE_NODE
-Command61=ID_OBJECT_CREATE_CONTAINER
-Command62=ID_OBJECT_CREATE_TEMPLATEGROUP
-Command63=ID_OBJECT_CREATE_TEMPLATE
-Command64=ID_OBJECT_BIND
-Command65=ID_OBJECT_RENAME
-Command66=ID_OBJECT_DELETE
-Command67=ID_OBJECT_MANAGE
-Command68=ID_OBJECT_UNMANAGE
-Command69=ID_OBJECT_POLL_STATUS
-Command70=ID_OBJECT_POLL_CONFIGURATION
-Command71=ID_OBJECT_DATACOLLECTION
-Command72=ID_OBJECT_PROPERTIES
-CommandCount=72
+Command33=ID_ITEM_DUPLICATE
+Command34=ID_ITEM_ACTIVATE
+Command35=ID_ITEM_DISABLE
+Command36=ID_ITEM_SHOWDATA
+Command37=ID_ITEM_GRAPH
+Command38=ID_POLICY_ADD
+Command39=ID_POLICY_DELETE
+Command40=ID_POLICY_EDIT
+Command41=ID_POLICY_NEGATECELL
+Command42=ID_POLICY_INSERTRULE_ABOVE
+Command43=ID_POLICY_INSERTRULE_BELOW
+Command44=ID_POLICY_INSERTRULE_TOP
+Command45=ID_POLICY_INSERTRULE_BOTTOM
+Command46=ID_POLICY_DELETERULE
+Command47=ID_POLICY_ENABLERULE
+Command48=ID_POLICY_DISABLERULE
+Command49=ID_ALARM_ACKNOWLEGE
+Command50=ID_ALARM_DELETE
+Command51=ID_ALARM_GOTOSOURCE
+Command52=ID_UPDATE_EVENT_LIST
+Command53=ID_CONTROLPANEL_ACTIONS
+Command54=ID_CONTROLPANEL_EVENTS
+Command55=ID_CONTROLPANEL_EVENTPOLICY
+Command56=ID_CONTROLPANEL_USERS
+Command57=ID_CONTROLPANEL_DCT
+Command58=ID_OBJECT_OPEN
+Command59=ID_OBJECT_OPENPARENT
+Command60=ID_OBJECT_FIND
+Command61=ID_OBJECT_CREATE_NODE
+Command62=ID_OBJECT_CREATE_CONTAINER
+Command63=ID_OBJECT_CREATE_TEMPLATEGROUP
+Command64=ID_OBJECT_CREATE_TEMPLATE
+Command65=ID_OBJECT_BIND
+Command66=ID_OBJECT_RENAME
+Command67=ID_OBJECT_DELETE
+Command68=ID_OBJECT_MANAGE
+Command69=ID_OBJECT_UNMANAGE
+Command70=ID_OBJECT_POLL_STATUS
+Command71=ID_OBJECT_POLL_CONFIGURATION
+Command72=ID_OBJECT_DATACOLLECTION
+Command73=ID_OBJECT_PROPERTIES
+CommandCount=73
 
 [ACL:IDA_MDI_DEFAULT]
 Type=1
@@ -1228,59 +1229,60 @@ Command20=ID_ITEM_NEW
 Command21=ID_ITEM_EDIT
 Command22=ID_ITEM_DELETE
 Command23=ID_ITEM_COPY
-Command24=ID_ITEM_ACTIVATE
-Command25=ID_ITEM_DISABLE
-Command26=ID_ITEM_SHOWDATA
-Command27=ID_ITEM_GRAPH
-Command28=ID_POLICY_INSERTRULE_ABOVE
-Command29=ID_POLICY_INSERTRULE_BELOW
-Command30=ID_POLICY_INSERTRULE_TOP
-Command31=ID_POLICY_INSERTRULE_BOTTOM
-Command32=ID_POLICY_DELETERULE
-Command33=ID_POLICY_ENABLERULE
-Command34=ID_POLICY_DISABLERULE
-Command35=ID_POLICY_ADD
-Command36=ID_POLICY_DELETE
-Command37=ID_POLICY_NEGATECELL
-Command38=ID_POLICY_INSERTRULE_ABOVE
-Command39=ID_POLICY_INSERTRULE_BELOW
-Command40=ID_POLICY_INSERTRULE_TOP
-Command41=ID_POLICY_INSERTRULE_BOTTOM
-Command42=ID_POLICY_DELETERULE
-Command43=ID_POLICY_ENABLERULE
-Command44=ID_POLICY_DISABLERULE
-Command45=ID_POLICY_EDIT
-Command46=ID_POLICY_INSERTRULE_ABOVE
-Command47=ID_POLICY_INSERTRULE_BELOW
-Command48=ID_POLICY_INSERTRULE_TOP
-Command49=ID_POLICY_INSERTRULE_BOTTOM
-Command50=ID_POLICY_DELETERULE
-Command51=ID_POLICY_ENABLERULE
-Command52=ID_POLICY_DISABLERULE
-Command53=ID_ALARM_ACKNOWLEGE
-Command54=ID_ALARM_DELETE
-Command55=ID_ALARM_GOTOSOURCE
-Command56=ID_ACTION_NEW
-Command57=ID_ACTION_RENAME
-Command58=ID_ACTION_DELETE
-Command59=ID_ACTION_PROPERTIES
-Command60=ID_POLL_RESTART
-Command61=ID_OBJECT_OPEN
-Command62=ID_OBJECT_OPENPARENT
-Command63=ID_OBJECT_CREATE_NODE
-Command64=ID_OBJECT_CREATE_CONTAINER
-Command65=ID_OBJECT_CREATE_TEMPLATEGROUP
-Command66=ID_OBJECT_CREATE_TEMPLATE
-Command67=ID_OBJECT_BIND
-Command68=ID_OBJECT_RENAME
-Command69=ID_OBJECT_DELETE
-Command70=ID_OBJECT_MANAGE
-Command71=ID_OBJECT_UNMANAGE
-Command72=ID_OBJECT_POLL_STATUS
-Command73=ID_OBJECT_POLL_CONFIGURATION
-Command74=ID_OBJECT_DATACOLLECTION
-Command75=ID_OBJECT_PROPERTIES
-CommandCount=75
+Command24=ID_ITEM_DUPLICATE
+Command25=ID_ITEM_ACTIVATE
+Command26=ID_ITEM_DISABLE
+Command27=ID_ITEM_SHOWDATA
+Command28=ID_ITEM_GRAPH
+Command29=ID_POLICY_INSERTRULE_ABOVE
+Command30=ID_POLICY_INSERTRULE_BELOW
+Command31=ID_POLICY_INSERTRULE_TOP
+Command32=ID_POLICY_INSERTRULE_BOTTOM
+Command33=ID_POLICY_DELETERULE
+Command34=ID_POLICY_ENABLERULE
+Command35=ID_POLICY_DISABLERULE
+Command36=ID_POLICY_ADD
+Command37=ID_POLICY_DELETE
+Command38=ID_POLICY_NEGATECELL
+Command39=ID_POLICY_INSERTRULE_ABOVE
+Command40=ID_POLICY_INSERTRULE_BELOW
+Command41=ID_POLICY_INSERTRULE_TOP
+Command42=ID_POLICY_INSERTRULE_BOTTOM
+Command43=ID_POLICY_DELETERULE
+Command44=ID_POLICY_ENABLERULE
+Command45=ID_POLICY_DISABLERULE
+Command46=ID_POLICY_EDIT
+Command47=ID_POLICY_INSERTRULE_ABOVE
+Command48=ID_POLICY_INSERTRULE_BELOW
+Command49=ID_POLICY_INSERTRULE_TOP
+Command50=ID_POLICY_INSERTRULE_BOTTOM
+Command51=ID_POLICY_DELETERULE
+Command52=ID_POLICY_ENABLERULE
+Command53=ID_POLICY_DISABLERULE
+Command54=ID_ALARM_ACKNOWLEGE
+Command55=ID_ALARM_DELETE
+Command56=ID_ALARM_GOTOSOURCE
+Command57=ID_ACTION_NEW
+Command58=ID_ACTION_RENAME
+Command59=ID_ACTION_DELETE
+Command60=ID_ACTION_PROPERTIES
+Command61=ID_POLL_RESTART
+Command62=ID_OBJECT_OPEN
+Command63=ID_OBJECT_OPENPARENT
+Command64=ID_OBJECT_CREATE_NODE
+Command65=ID_OBJECT_CREATE_CONTAINER
+Command66=ID_OBJECT_CREATE_TEMPLATEGROUP
+Command67=ID_OBJECT_CREATE_TEMPLATE
+Command68=ID_OBJECT_BIND
+Command69=ID_OBJECT_RENAME
+Command70=ID_OBJECT_DELETE
+Command71=ID_OBJECT_MANAGE
+Command72=ID_OBJECT_UNMANAGE
+Command73=ID_OBJECT_POLL_STATUS
+Command74=ID_OBJECT_POLL_CONFIGURATION
+Command75=ID_OBJECT_DATACOLLECTION
+Command76=ID_OBJECT_PROPERTIES
+CommandCount=76
 
 [MNU:IDM_CONTEXT (English (U.S.))]
 Type=1
@@ -1510,13 +1512,16 @@ LastObject=CDCIThresholdsPage
 [DLG:IDD_DCI_THRESHOLDS]
 Type=1
 Class=CDCIThresholdsPage
-ControlCount=6
-Control1=IDC_LIST_THRESHOLDS,SysListView32,1342275593
-Control2=IDC_BUTTON_ADD,button,1342242816
-Control3=IDC_BUTTON_MODIFY,button,1342242816
-Control4=IDC_BUTTON_DELETE,button,1342242816
-Control5=IDC_BUTTON_MOVEUP,button,1342242944
-Control6=IDC_BUTTON_MOVEDOWN,button,1342242944
+ControlCount=9
+Control1=IDC_EDIT_INSTANCE,edit,1350631552
+Control2=IDC_LIST_THRESHOLDS,SysListView32,1342275593
+Control3=IDC_BUTTON_MOVEUP,button,1342242944
+Control4=IDC_BUTTON_MOVEDOWN,button,1342242944
+Control5=IDC_BUTTON_ADD,button,1342242816
+Control6=IDC_BUTTON_MODIFY,button,1342242816
+Control7=IDC_BUTTON_DELETE,button,1342242816
+Control8=IDC_STATIC,static,1342308352
+Control9=IDC_STATIC,static,1342308352
 
 [DLG:IDD_THRESHOLD (English (U.S.))]
 Type=1
index d706004..6800696 100644 (file)
@@ -249,6 +249,7 @@ BEGIN
         MENUITEM "&Edit...\tAlt+Enter",         ID_ITEM_EDIT
         MENUITEM "&Delete\tDel",                ID_ITEM_DELETE
         MENUITEM "&Copy to other node(s)...\tCtrl+C", ID_ITEM_COPY
+        MENUITEM "D&uplicate",                  ID_ITEM_DUPLICATE
         MENUITEM SEPARATOR
         MENUITEM "&Activate\tAlt+A",            ID_ITEM_ACTIVATE
         MENUITEM "D&isable\tAlt+D",             ID_ITEM_DISABLE
@@ -383,6 +384,7 @@ BEGIN
         MENUITEM "&Edit...",                    ID_ITEM_EDIT
         MENUITEM "&Delete",                     ID_ITEM_DELETE
         MENUITEM "&Copy to other node(s)...",   ID_ITEM_COPY
+        MENUITEM "D&uplicate",                  ID_ITEM_DUPLICATE
         MENUITEM SEPARATOR
         MENUITEM "&Activate",                   ID_ITEM_ACTIVATE
         MENUITEM "D&isable",                    ID_ITEM_DISABLE
@@ -904,16 +906,19 @@ END
 IDD_DCI_THRESHOLDS DIALOGEX 0, 0, 228, 170
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Thresholds"
-FONT 8, "MS Sans Serif", 0, 0, 0x1
+FONT 8, "MS Sans Serif"
 BEGIN
+    EDITTEXT        IDC_EDIT_INSTANCE,7,16,214,14,ES_AUTOHSCROLL
     CONTROL         "List1",IDC_LIST_THRESHOLDS,"SysListView32",LVS_REPORT | 
-                    LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_TABSTOP,7,7,
-                    193,135,WS_EX_CLIENTEDGE
+                    LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_TABSTOP,7,47,
+                    193,96,WS_EX_CLIENTEDGE
+    PUSHBUTTON      "&U",IDC_BUTTON_MOVEUP,205,46,16,16,BS_BITMAP
+    PUSHBUTTON      "D",IDC_BUTTON_MOVEDOWN,205,66,16,16,BS_BITMAP
     PUSHBUTTON      "&Add...",IDC_BUTTON_ADD,59,149,50,14
     PUSHBUTTON      "&Modify...",IDC_BUTTON_MODIFY,115,149,50,14
     PUSHBUTTON      "&Delete",IDC_BUTTON_DELETE,171,149,50,14
-    PUSHBUTTON      "&U",IDC_BUTTON_MOVEUP,205,7,16,16,BS_BITMAP
-    PUSHBUTTON      "D",IDC_BUTTON_MOVEDOWN,205,27,16,16,BS_BITMAP
+    LTEXT           "Instance",IDC_STATIC,7,7,28,8
+    LTEXT           "Threshold list",IDC_STATIC,7,37,42,8
 END
 
 IDD_THRESHOLD DIALOG DISCARDABLE  0, 0, 211, 169
index bfdc3d9..71389b1 100644 (file)
 #define IDC_CHECK_SAVE                  1172
 #define IDC_BUTTON_RESOLVE              1173
 #define IDC_BUTTON_NONE                 1174
+#define IDC_EDIT_INSTANCE               1175
 #define ID_VIEW_CONTROLPANEL            32771
 #define ID_VIEW_EVENTS                  32774
 #define ID_VIEW_MAP                     32776
 #define ID_OBJECT_CREATE_TEMPLATE       32884
 #define ID_OBJECT_OPEN                  32885
 #define ID_OBJECT_OPENPARENT            32887
+#define ID_ITEM_DUPLICATE               32889
 #define IDS_GETFOLDERPATH_FAILED        61216
 #define IDS_WORKDIR_CREATION_FAILED     61217
 
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_3D_CONTROLS                     1
 #define _APS_NEXT_RESOURCE_VALUE        240
-#define _APS_NEXT_COMMAND_VALUE         32889
-#define _APS_NEXT_CONTROL_VALUE         1175
+#define _APS_NEXT_COMMAND_VALUE         32891
+#define _APS_NEXT_CONTROL_VALUE         1176
 #define _APS_NEXT_SYMED_VALUE           120
 #endif
 #endif
index 3b6d1e6..d07639e 100644 (file)
@@ -72,28 +72,32 @@ DWORD LIBNXCL_EXPORTABLE NXCLoadActions(DWORD *pdwNumActions, NXC_ACTION **ppAct
    msg.SetId(dwRqId);
    SendMsg(&msg);
 
-   do
+   dwRetCode = WaitForRCC(dwRqId);
+   if (dwRetCode == RCC_SUCCESS)
    {
-      pResponce = WaitForMessage(CMD_ACTION_DATA, dwRqId, g_dwCommandTimeout);
-      if (pResponce != NULL)
+      do
       {
-         dwActionId = pResponce->GetVariableLong(VID_ACTION_ID);
-         if (dwActionId != 0)  // 0 is end of list indicator
+         pResponce = WaitForMessage(CMD_ACTION_DATA, dwRqId, g_dwCommandTimeout);
+         if (pResponce != NULL)
          {
-            pList = (NXC_ACTION *)realloc(pList, sizeof(NXC_ACTION) * (dwNumActions + 1));
-            pList[dwNumActions].dwId = dwActionId;
-            ActionFromMsg(pResponce, &pList[dwNumActions]);
-            dwNumActions++;
+            dwActionId = pResponce->GetVariableLong(VID_ACTION_ID);
+            if (dwActionId != 0)  // 0 is end of list indicator
+            {
+               pList = (NXC_ACTION *)realloc(pList, sizeof(NXC_ACTION) * (dwNumActions + 1));
+               pList[dwNumActions].dwId = dwActionId;
+               ActionFromMsg(pResponce, &pList[dwNumActions]);
+               dwNumActions++;
+            }
+            delete pResponce;
+         }
+         else
+         {
+            dwRetCode = RCC_TIMEOUT;
+            dwActionId = 0;
          }
-         delete pResponce;
-      }
-      else
-      {
-         dwRetCode = RCC_TIMEOUT;
-         dwActionId = 0;
       }
+      while(dwActionId != 0);
    }
-   while(dwActionId != 0);
 
    // Destroy results on failure or save on success
    if (dwRetCode == RCC_SUCCESS)
index b9d6dc2..986e829 100644 (file)
@@ -322,6 +322,9 @@ void LIBNXCL_EXPORTABLE NXCDisconnect(void)
 
    // Clear message wait queue
    m_msgWaitQueue.Clear();
+
+   // Cleanup
+   DestroyAllObjects();
 }
 
 
@@ -366,4 +369,4 @@ DWORD WaitForRCC(DWORD dwRqId)
       dwRetCode = RCC_TIMEOUT;
    }
    return dwRetCode;
-}
+}
\ No newline at end of file
index 4066685..e3ca312 100644 (file)
@@ -63,6 +63,8 @@ void ProcessDCI(CSCPMessage *pMsg)
             pMsg->GetVariableStr(VID_NAME, m_pItemList->pItems[i].szName, MAX_ITEM_NAME);
             pMsg->GetVariableStr(VID_DESCRIPTION, m_pItemList->pItems[i].szDescription,
                                  MAX_DB_STRING);
+            pMsg->GetVariableStr(VID_INSTANCE, m_pItemList->pItems[i].szInstance,
+                                 MAX_DB_STRING);
             m_pItemList->pItems[i].dwNumThresholds = pMsg->GetVariableLong(VID_NUM_THRESHOLDS);
             m_pItemList->pItems[i].pThresholdList = 
                (NXC_DCI_THRESHOLD *)malloc(sizeof(NXC_DCI_THRESHOLD) * m_pItemList->pItems[i].dwNumThresholds);
@@ -253,6 +255,7 @@ DWORD LIBNXCL_EXPORTABLE NXCUpdateDCI(DWORD dwNodeId, NXC_DCI *pItem)
    msg.SetVariable(VID_DCI_STATUS, (WORD)pItem->iStatus);
    msg.SetVariable(VID_NAME, pItem->szName);
    msg.SetVariable(VID_DESCRIPTION, pItem->szDescription);
+   msg.SetVariable(VID_INSTANCE, pItem->szInstance);
    msg.SetVariable(VID_DCI_FORMULA, pItem->pszFormula);
    msg.SetVariable(VID_NUM_THRESHOLDS, pItem->dwNumThresholds);
    for(i = 0, dwId = VID_DCI_THRESHOLD_BASE; i < pItem->dwNumThresholds; i++, dwId++)
@@ -513,8 +516,9 @@ BOOL LIBNXCL_EXPORTABLE NXCDeleteThresholdFromItem(NXC_DCI *pItem, DWORD dwIndex
    if (pItem->dwNumThresholds > dwIndex)
    {
       pItem->dwNumThresholds--;
-      memmove(&pItem->pThresholdList[dwIndex], &pItem->pThresholdList[dwIndex + 1],
-              sizeof(NXC_DCI_THRESHOLD) * (pItem->dwNumThresholds - dwIndex));
+      if (pItem->dwNumThresholds > 0)
+         memmove(&pItem->pThresholdList[dwIndex], &pItem->pThresholdList[dwIndex + 1],
+                 sizeof(NXC_DCI_THRESHOLD) * (pItem->dwNumThresholds - dwIndex));
       bResult = TRUE;
    }
    return bResult;
index 26ecdd4..e657b63 100644 (file)
@@ -82,6 +82,7 @@ typedef struct
 //
 
 void ObjectsInit(void);
+void DestroyAllObjects(void);
 
 void ProcessAlarmUpdate(CSCPMessage *pMsg);
 void ProcessObjectUpdate(CSCPMessage *pMsg);
index 51e0d64..1356ffc 100644 (file)
@@ -43,6 +43,50 @@ void ObjectsInit(void)
 }
 
 
+//
+// Destroy object
+//
+
+static void DestroyObject(NXC_OBJECT *pObject)
+{
+   DebugPrintf(_T("DestroyObject(id:%ld, name:\"%s\")"), pObject->dwId, pObject->szName);
+   switch(pObject->iClass)
+   {
+      case OBJECT_CONTAINER:
+         safe_free(pObject->container.pszDescription);
+         break;
+      case OBJECT_NODE:
+         safe_free(pObject->node.pszDescription);
+         break;
+      case OBJECT_TEMPLATE:
+         safe_free(pObject->dct.pszDescription);
+         break;
+   }
+   safe_free(pObject->pdwChildList);
+   safe_free(pObject->pdwParentList);
+   safe_free(pObject->pAccessList);
+   free(pObject);
+}
+
+
+//
+// Destroy all objects
+//
+
+void DestroyAllObjects(void)
+{
+   DWORD i;
+
+   MutexLock(m_mutexIndexAccess, INFINITE);
+   for(i = 0; i < m_dwNumObjects; i++)
+      DestroyObject(m_pIndexById[i].pObject);
+   m_dwNumObjects = 0;
+   free(m_pIndexById);
+   m_pIndexById = NULL;
+   MutexUnlock(m_mutexIndexAccess);
+}
+
+
 //
 // Perform binary search on index
 // Returns INVALID_INDEX if key not found or position of appropriate network object
@@ -123,32 +167,6 @@ static void ReplaceObject(NXC_OBJECT *pObject, NXC_OBJECT *pNewObject)
 }
 
 
-//
-// Destroy object
-//
-
-static void DestroyObject(NXC_OBJECT *pObject)
-{
-   DebugPrintf(_T("DestroyObject(id:%ld, name:\"%s\")"), pObject->dwId, pObject->szName);
-   switch(pObject->iClass)
-   {
-      case OBJECT_CONTAINER:
-         safe_free(pObject->container.pszDescription);
-         break;
-      case OBJECT_NODE:
-         safe_free(pObject->node.pszDescription);
-         break;
-      case OBJECT_TEMPLATE:
-         safe_free(pObject->dct.pszDescription);
-         break;
-   }
-   safe_free(pObject->pdwChildList);
-   safe_free(pObject->pdwParentList);
-   safe_free(pObject->pAccessList);
-   free(pObject);
-}
-
-
 //
 // Create new object from message
 //
@@ -290,6 +308,8 @@ DWORD LIBNXCL_EXPORTABLE NXCSyncObjects(void)
    dwRqId = g_dwMsgId++;
    PrepareForSync();
 
+   DestroyAllObjects();
+
    msg.SetCode(CMD_GET_OBJECTS);
    msg.SetId(dwRqId);
    SendMsg(&msg);
index 89ba8b2..30a7f5d 100644 (file)
@@ -154,6 +154,10 @@ DWORD LIBNXCL_EXPORTABLE NXCLoadUserDB(void)
    dwRqId = g_dwMsgId++;
    PrepareForSync();
 
+   safe_free(m_pUserList);
+   m_pUserList = NULL;
+   m_dwNumUsers = 0;
+
    msg.SetCode(CMD_LOAD_USER_DB);
    msg.SetId(dwRqId);
    SendMsg(&msg);
index ac78abb..dac2a8c 100644 (file)
@@ -238,7 +238,7 @@ BOOL DCItem::SaveToDB(void)
    if (bNewObject)
       sprintf(szQuery, "INSERT INTO items (item_id,node_id,template_id,name,description,source,"
                        "datatype,polling_interval,retention_time,status,delta_calculation,"
-                       "transformation,instance) VALUES (%ld,%ld,%ld,'%s','%s',%d,%d,%ld,%ld,%d,%d,'%s')",
+                       "transformation,instance) VALUES (%ld,%ld,%ld,'%s','%s',%d,%d,%ld,%ld,%d,%d,'%s','%s')",
                        m_dwId, (m_pNode == NULL) ? 0 : m_pNode->Id(), m_dwTemplateId,
                        m_szName, pszEscDescr, m_iSource, m_iDataType, m_iPollingInterval,
                        m_iRetentionTime, m_iStatus, m_iDeltaCalculation, pszEscFormula, pszEscInstance);
index 21296c6..c886105 100644 (file)
@@ -298,7 +298,7 @@ void SaveUsers(void)
 
 BOOL AuthenticateUser(char *szName, BYTE *szPassword, DWORD *pdwId, DWORD *pdwSystemRights)
 {
-   DWORD i;
+   DWORD i, j;
    BOOL bResult = FALSE;
 
    MutexLock(m_hMutexUserAccess, INFINITE);
@@ -311,6 +311,13 @@ BOOL AuthenticateUser(char *szName, BYTE *szPassword, DWORD *pdwId, DWORD *pdwSy
          *pdwId = g_pUserList[i].dwId;
          *pdwSystemRights = (DWORD)g_pUserList[i].wSystemRights;
          bResult = TRUE;
+         
+         // Collect system rights from groups this user belongs to
+         MutexLock(m_hMutexGroupAccess, INFINITE);
+         for(j = 0; j < g_dwNumGroups; j++)
+            if (CheckUserMembership(g_pUserList[i].dwId, g_pGroupList[j].dwId))
+               *pdwSystemRights |= (DWORD)g_pGroupList[j].wSystemRights;
+         MutexUnlock(m_hMutexGroupAccess);
          break;
       }
    }
index 5cea729..aee0fb2 100644 (file)
@@ -263,7 +263,7 @@ Unable to load users and user groups from database (probably database is corrupt
 MessageId=
 SymbolicName=MSG_SQL_ERROR
 Language=English
-SQL query failed (Query = '%1')
+SQL query failed (Query = "%1")
 .
 
 MessageId=
index b612e8f..80e111d 100644 (file)
@@ -73,6 +73,42 @@ BOOL SQLQuery(TCHAR *pszQuery)
 }
 
 
+//
+// Execute SQL batch
+//
+
+BOOL SQLBatch(TCHAR *pszBatch)
+{
+   TCHAR *pszQuery, *ptr;
+
+   pszQuery = pszBatch;
+   while(1)
+   {
+      ptr = _tcschr(pszQuery, _T('\n'));
+      if (ptr != NULL)
+         *ptr = 0;
+      if (!_tcscmp(pszQuery, _T("<END>")))
+         break;
+      if (!DBQuery(g_hCoreDB, pszQuery))
+      {
+#ifdef _WIN32
+         _tprintf(_T("SQL query failed:\n"));
+         SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0E);
+         _tprintf(_T("%s\n"), pszQuery);
+         SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x07);
+#else
+         _tprintf(_T("SQL query failed:\n%s\n"), pszQuery);
+#endif
+         if (!g_bIgnoreErrors)
+            return FALSE;
+      }
+      ptr++;
+      pszQuery = ptr;
+   }
+   return TRUE;
+}
+
+
 //
 // Startup
 //
index 6f4873b..3b969f0 100644 (file)
@@ -36,6 +36,7 @@
 void CheckDatabase(BOOL bForce);
 void UpgradeDatabase(void);
 BOOL SQLQuery(TCHAR *pszQuery);
+BOOL SQLBatch(TCHAR *pszBatch);
 
 
 //
index 0bcc6eb..52c34b0 100644 (file)
 #include "nxdbmgr.h"
 
 
-//
-// Execute SQL batch
-//
-
-static BOOL SQLBatch(TCHAR *pszBatch)
-{
-   TCHAR *pszQuery, *ptr;
-
-   pszQuery = pszBatch;
-   while(1)
-   {
-      ptr = _tcschr(pszQuery, _T('\n'));
-      if (ptr != NULL)
-         *ptr = 0;
-      if (!_tcscmp(pszQuery, _T("<END>")))
-         break;
-      if (!DBQuery(g_hCoreDB, pszQuery))
-      {
-#ifdef _WIN32
-         _tprintf(_T("SQL query failed:\n"));
-         SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0E);
-         _tprintf(_T("%s\n"), pszQuery);
-         SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x07);
-#else
-         _tprintf(_T("SQL query failed:\n%s\n"), pszQuery);
-#endif
-         if (!g_bIgnoreErrors)
-            return FALSE;
-      }
-      ptr++;
-      pszQuery = ptr;
-   }
-   return TRUE;
-}
-
-
 //
 // Upgrade from V14 to V15
 //
 
 static BOOL H_UpgradeFromV14(void)
 {
-   static TCHAR m_szBatch[] = 
+   static TCHAR m_szBatch[] =
       "ALTER TABLE items ADD COLUMN instance varchar(255)\n"
+      "UPDATE items SET instance=''\n"
       "INSERT INTO config (var_name,var_value,is_visible,need_server_restart) VALUES "
          "('SMTPServer','localhost',1,0)\n"
       "INSERT INTO config (var_name,var_value,is_visible,need_server_restart) VALUES "
          "('SMTPFromAddr','netxms@localhost',1,0)\n"
       "INSERT INTO events (event_id,name,severity,flags,message,description) VALUES "
-             "(4003, 'DC_AGENT_RESTARTED',     0 , 1,"
+             "(4003, 'DC_AGENT_RESTARTED',     0, 1,"
          "'NetXMS agent was restarted within last 5 minutes',"
          "'Custom data collection threshold event.#0D#0AParameters:#0D#0A"
                   "   1) Parameter name#0D#0A   2) Item description#0D#0A"
          "   3) Threshold value#0D#0A   4) Actual value#0D#0A"
          "   5) Data collection item ID#0D#0A   6) Instance')\n"
+      "INSERT INTO events (event_id,name,severity,flags,message,description) VALUES "
+             "(4004, 'DC_SERVICE_NOT_RUNNING', 3, 1,"
+                  "'Service #22%6#22 is not running',"
+                  "'Custom data collection threshold event.#0D#0AParameters:#0D#0A"
+                  "   1) Parameter name#0D#0A   2) Item description#0D#0A"
+         "   3) Threshold value#0D#0A   4) Actual value#0D#0A"
+         "   5) Data collection item ID#0D#0A   6) Instance')\n"
       "UPDATE events SET "
-         "description='   1) Parameter name#0D#0A   2) Item description#0D#0A"
+         "description='Generated when threshold value reached "
+         "for specific data collection item.#0D#0A"
+         "   1) Parameter name#0D#0A   2) Item description#0D#0A"
          "   3) Threshold value#0D#0A   4) Actual value#0D#0A"
          "   5) Data collection item ID#0D#0A   6) Instance' WHERE "
          "event_id=17 OR (event_id>=4000 AND event_id<5000)\n"
+      "UPDATE events SET "
+         "description='Generated when threshold check is rearmed "
+         "for specific data collection item.#0D#0A"
+                  "Parameters:#0D#0A   1) Parameter name#0D#0A"
+                  "   2) Item description#0D#0A   3) Data collection item ID' "
+         "WHERE event_id=18\n"
       "<END>";
 
    if (!SQLBatch(m_szBatch))
@@ -117,7 +97,7 @@ static struct
 void UpgradeDatabase(void)
 {
    DB_RESULT hResult;
-   long i, iVersion = 0;
+   long i, iVersion = 0, iLock = -1;
 
    _tprintf(_T("Upgrading database...\n"));
 
@@ -141,24 +121,40 @@ void UpgradeDatabase(void)
    }
    else
    {
-      while(iVersion < DB_FORMAT_VERSION)
+      // Check if database is locked
+      hResult = DBSelect(g_hCoreDB, _T("SELECT lock_status FROM locks WHERE component_id=0"));
+      if (hResult != NULL)
       {
-         // Find upgrade procedure
-         for(i = 0; m_dbUpgradeMap[i].fpProc != NULL; i++)
-            if (m_dbUpgradeMap[i].iVersion == iVersion)
-               break;
-         if (m_dbUpgradeMap[i].fpProc == NULL)
+         if (DBGetNumRows(hResult) > 0)
+            iLock = DBGetFieldLong(hResult, 0, 0);
+         DBFreeResult(hResult);
+      }
+      if (iLock == -1)
+      {
+         // Upgrade database
+         while(iVersion < DB_FORMAT_VERSION)
          {
-            _tprintf(_T("Unable to find upgrade procedure for version %d\n"), iVersion);
-            break;
+            // Find upgrade procedure
+            for(i = 0; m_dbUpgradeMap[i].fpProc != NULL; i++)
+               if (m_dbUpgradeMap[i].iVersion == iVersion)
+                  break;
+            if (m_dbUpgradeMap[i].fpProc == NULL)
+            {
+               _tprintf(_T("Unable to find upgrade procedure for version %d\n"), iVersion);
+               break;
+            }
+            printf("Upgrading from version %d to %d\n", iVersion, iVersion + 1);
+            if (m_dbUpgradeMap[i].fpProc())
+               iVersion++;
+            else
+               break;
          }
-         printf("Upgrading from version %d to %d\n", iVersion, iVersion + 1);
-         if (m_dbUpgradeMap[i].fpProc())
-            iVersion++;
-         else
-            break;
-      }
 
-      _tprintf(_T("Database upgrade %s\n"), (iVersion == DB_FORMAT_VERSION) ? _T("succeeded") : _T("failed"));
+         _tprintf(_T("Database upgrade %s\n"), (iVersion == DB_FORMAT_VERSION) ? _T("succeeded") : _T("failed"));
+      }
+      else
+      {
+         _tprintf(_T("Database is locked\n"));
+      }
    }
 }