Added basic support for template objects
authorVictor Kirhenshtein <victor@netxms.org>
Fri, 1 Oct 2004 11:14:28 +0000 (11:14 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Fri, 1 Oct 2004 11:14:28 +0000 (11:14 +0000)
41 files changed:
.gitattributes
images/template.ico [new file with mode: 0644]
images/template.png [new file with mode: 0644]
images/template_group.ico [new file with mode: 0644]
images/template_group.png [new file with mode: 0644]
images/template_root.ico [new file with mode: 0644]
images/template_root.png [new file with mode: 0644]
include/netxmsdb.h
include/nms_common.h
include/nxclapi.h
include/nximage.h
sql/images.in
sql/schema.in
src/console/win32/CreateTGDlg.cpp [new file with mode: 0644]
src/console/win32/CreateTGDlg.h [new file with mode: 0644]
src/console/win32/CreateTemplateDlg.cpp [new file with mode: 0644]
src/console/win32/CreateTemplateDlg.h [new file with mode: 0644]
src/console/win32/ObjectBrowser.cpp
src/console/win32/ObjectBrowser.h
src/console/win32/globals.cpp
src/console/win32/nxcon.clw
src/console/win32/nxcon.cpp
src/console/win32/nxcon.dsp
src/console/win32/nxcon.h
src/console/win32/nxcon.rc
src/console/win32/resource.h
src/libnetxms/hash.cpp
src/libnxcl/objects.cpp
src/server/core/config.cpp
src/server/core/container.cpp
src/server/core/id.cpp
src/server/core/image.cpp
src/server/core/messages.mc
src/server/core/netxmsd.dsp
src/server/core/nms_core.h
src/server/core/nms_objects.h
src/server/core/objects.cpp
src/server/core/rootobj.cpp [copied from include/nximage.h with 55% similarity]
src/server/core/session.cpp
src/server/core/template.cpp
src/server/core/uniroot.cpp [moved from src/server/core/srvroot.cpp with 71% similarity]

index e32d1a8..bc9881a 100644 (file)
@@ -34,6 +34,12 @@ images/service.ico -text
 images/service.png -text
 images/subnet.ico -text
 images/subnet.png -text
+images/template.ico -text
+images/template.png -text
+images/template_group.ico -text
+images/template_group.png -text
+images/template_root.ico -text
+images/template_root.png -text
 include/Makefile.am -text
 include/getopt.h -text
 include/netxms-version.h -text
@@ -123,6 +129,10 @@ src/console/win32/CreateNodeDlg.cpp -text
 src/console/win32/CreateNodeDlg.h -text
 src/console/win32/CreateObjectDlg.cpp -text
 src/console/win32/CreateObjectDlg.h -text
+src/console/win32/CreateTGDlg.cpp -text
+src/console/win32/CreateTGDlg.h -text
+src/console/win32/CreateTemplateDlg.cpp -text
+src/console/win32/CreateTemplateDlg.h -text
 src/console/win32/DCIDataView.cpp -text
 src/console/win32/DCIDataView.h -text
 src/console/win32/DCIPropPage.cpp -text
@@ -368,14 +378,15 @@ src/server/core/node.cpp -text
 src/server/core/np.cpp -text
 src/server/core/objects.cpp -text
 src/server/core/resource.h -text
+src/server/core/rootobj.cpp -text
 src/server/core/session.cpp -text
 src/server/core/snmp.cpp -text
-src/server/core/srvroot.cpp -text
 src/server/core/status.cpp -text
 src/server/core/subnet.cpp -text
 src/server/core/syncer.cpp -text
 src/server/core/template.cpp -text
 src/server/core/tools.cpp -text
+src/server/core/uniroot.cpp -text
 src/server/core/users.cpp -text
 src/server/core/watchdog.cpp -text
 src/server/core/winsrv.cpp -text
diff --git a/images/template.ico b/images/template.ico
new file mode 100644 (file)
index 0000000..d58c5f0
Binary files /dev/null and b/images/template.ico differ
diff --git a/images/template.png b/images/template.png
new file mode 100644 (file)
index 0000000..6fcb64b
Binary files /dev/null and b/images/template.png differ
diff --git a/images/template_group.ico b/images/template_group.ico
new file mode 100644 (file)
index 0000000..a2956ad
Binary files /dev/null and b/images/template_group.ico differ
diff --git a/images/template_group.png b/images/template_group.png
new file mode 100644 (file)
index 0000000..fc214b6
Binary files /dev/null and b/images/template_group.png differ
diff --git a/images/template_root.ico b/images/template_root.ico
new file mode 100644 (file)
index 0000000..eb5ee22
Binary files /dev/null and b/images/template_root.ico differ
diff --git a/images/template_root.png b/images/template_root.png
new file mode 100644 (file)
index 0000000..08c1edf
Binary files /dev/null and b/images/template_root.png differ
index 48955b4..b07441b 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _netxms_db_h
 #define _netxms_db_h
 
-#define DB_FORMAT_VERSION      9
+#define DB_FORMAT_VERSION      10
 
 #endif
index 1f5d870..eeff688 100644 (file)
@@ -94,6 +94,8 @@ typedef int socklen_t;
 
 /********** NETWARE ********************/
 
+#define FS_PATH_SEPARATOR  _T("/")
+
 #include <unistd.h>
 #include <stdlib.h>
 #include <sys/types.h>
index d075d09..a8773dc 100644 (file)
@@ -110,7 +110,8 @@ typedef unsigned long HREQUEST;
 #define OBJECT_ZONE           6
 #define OBJECT_SERVICEROOT    7
 #define OBJECT_TEMPLATE       8
-#define OBJECT_TEMPLATE_GROUP 9
+#define OBJECT_TEMPLATEGROUP  9
+#define OBJECT_TEMPLATEROOT   10
 
 
 //
@@ -761,6 +762,10 @@ typedef struct
          DWORD dwCategory;
          TCHAR *pszDescription;
       } container;
+      struct
+      {
+         TCHAR *pszDescription;
+      } templateGroup;
    } cs;
 } NXC_OBJECT_CREATE_INFO;
 
@@ -815,6 +820,7 @@ NXC_OBJECT LIBNXCL_EXPORTABLE *NXCFindObjectByName(TCHAR *pszName);
 void LIBNXCL_EXPORTABLE NXCEnumerateObjects(BOOL (* pHandler)(NXC_OBJECT *));
 NXC_OBJECT LIBNXCL_EXPORTABLE *NXCGetTopologyRootObject(void);
 NXC_OBJECT LIBNXCL_EXPORTABLE *NXCGetServiceRootObject(void);
+NXC_OBJECT LIBNXCL_EXPORTABLE *NXCGetTemplateRootObject(void);
 void LIBNXCL_EXPORTABLE *NXCGetObjectIndex(DWORD *pdwNumObjects);
 void LIBNXCL_EXPORTABLE NXCLockObjectIndex(void);
 void LIBNXCL_EXPORTABLE NXCUnlockObjectIndex(void);
index 4ec67fa..78f0a95 100644 (file)
@@ -37,5 +37,8 @@
 #define IMG_SUBNET                  6
 #define IMG_SERVICE_ROOT            7
 #define IMG_CONTAINER_SERVICE       8
+#define IMG_TEMPLATE                9
+#define IMG_TEMPLATE_GROUP          10
+#define IMG_TEMPLATE_ROOT           11
 
 #endif
index 0509e4e..0fc844c 100644 (file)
@@ -25,6 +25,15 @@ INSERT INTO images (image_id,name,file_name_png,file_hash_png,file_name_ico,file
 INSERT INTO images (image_id,name,file_name_png,file_hash_png,file_name_ico,file_hash_ico)
        VALUES (IMG_SUBNET,'Obj.Subnet','subnet.png','<invalid_hash>',
                 'subnet.ico','<invalid_hash>');
+INSERT INTO images (image_id,name,file_name_png,file_hash_png,file_name_ico,file_hash_ico)
+       VALUES (IMG_TEMPLATE,'Obj.Template','template.png','<invalid_hash>',
+                'template.ico','<invalid_hash>');
+INSERT INTO images (image_id,name,file_name_png,file_hash_png,file_name_ico,file_hash_ico)
+       VALUES (IMG_TEMPLATE_GROUP,'Obj.TemplateGroup','template_group.png','<invalid_hash>',
+                'template_group.ico','<invalid_hash>');
+INSERT INTO images (image_id,name,file_name_png,file_hash_png,file_name_ico,file_hash_ico)
+       VALUES (IMG_TEMPLATE_ROOT,'Obj.TemplateRoot','template_root.png','<invalid_hash>',
+                'template_root.ico','<invalid_hash>');
 
 
 /*
@@ -43,3 +52,9 @@ INSERT INTO default_images (object_class,image_id)
        VALUES (5, IMG_CONTAINER_NODE_GROUP);
 INSERT INTO default_images (object_class,image_id)
        VALUES (7, IMG_NETWORK);
+INSERT INTO default_images (object_class,image_id)
+       VALUES (8, IMG_TEMPLATE);
+INSERT INTO default_images (object_class,image_id)
+       VALUES (9, IMG_TEMPLATE_GROUP);
+INSERT INTO default_images (object_class,image_id)
+       VALUES (10, IMG_TEMPLATE_ROOT);
index f46670b..1140e4e 100644 (file)
@@ -166,10 +166,37 @@ CREATE TABLE containers
        category integer,
        description TEXT,
        image_id integer,
+       object_class integer not null,
        PRIMARY KEY(id)
 );
 
 
+/*
+** Data collection templates
+*/
+
+CREATE TABLE templates
+(
+       id integer not null,
+       name varchar(63),
+       is_deleted integer not null,
+       image_id integer,
+       PRIMARY KEY(id)
+);
+
+
+/*
+** Mapping hosts to templates
+*/
+
+CREATE TABLE dct_node_map
+(
+       template_id integer not null,
+       node_id integer not null,
+       PRIMARY KEY(template_id,node_id)
+);
+
+
 /*
 ** Nodes to subnets mapping
 */
@@ -413,30 +440,6 @@ CREATE TABLE thresholds
 );
 
 
-/*
-** Data collection templates
-*/
-
-CREATE TABLE dct
-(
-       template_id integer not null,
-       name varchar(255),
-       PRIMARY KEY(template_id)
-);
-
-
-/*
-** Mapping hosts to templates
-*/
-
-CREATE TABLE dct_host_map
-(
-       template_id integer not null,
-       node_id integer not null,
-       PRIMARY KEY(template_id,node_id)
-);
-
-
 /*
 ** Alarms
 */
diff --git a/src/console/win32/CreateTGDlg.cpp b/src/console/win32/CreateTGDlg.cpp
new file mode 100644 (file)
index 0000000..a6736d1
--- /dev/null
@@ -0,0 +1,44 @@
+// CreateTGDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "nxcon.h"
+#include "CreateTGDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CCreateTGDlg dialog
+
+
+CCreateTGDlg::CCreateTGDlg(CWnd* pParent /*=NULL*/)
+       : CCreateObjectDlg(CCreateTGDlg::IDD, pParent)
+{
+       //{{AFX_DATA_INIT(CCreateTGDlg)
+       m_strDescription = _T("");
+       //}}AFX_DATA_INIT
+}
+
+
+void CCreateTGDlg::DoDataExchange(CDataExchange* pDX)
+{
+       CCreateObjectDlg::DoDataExchange(pDX);
+       //{{AFX_DATA_MAP(CCreateTGDlg)
+       DDX_Text(pDX, IDC_EDIT_DESCRIPTION, m_strDescription);
+       DDV_MaxChars(pDX, m_strDescription, 255);
+       //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CCreateTGDlg, CCreateObjectDlg)
+       //{{AFX_MSG_MAP(CCreateTGDlg)
+               // NOTE: the ClassWizard will add message map macros here
+       //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CCreateTGDlg message handlers
diff --git a/src/console/win32/CreateTGDlg.h b/src/console/win32/CreateTGDlg.h
new file mode 100644 (file)
index 0000000..53470d1
--- /dev/null
@@ -0,0 +1,49 @@
+#if !defined(AFX_CREATETGDLG_H__5A71CFF5_7762_47E8_AE58_6E724657EC48__INCLUDED_)
+#define AFX_CREATETGDLG_H__5A71CFF5_7762_47E8_AE58_6E724657EC48__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// CreateTGDlg.h : header file
+//
+
+#include "CreateObjectDlg.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CCreateTGDlg dialog
+
+class CCreateTGDlg : public CCreateObjectDlg
+{
+// Construction
+public:
+       CCreateTGDlg(CWnd* pParent = NULL);   // standard constructor
+
+// Dialog Data
+       //{{AFX_DATA(CCreateTGDlg)
+       enum { IDD = IDD_CREATE_TG };
+       CString m_strDescription;
+       //}}AFX_DATA
+
+
+// Overrides
+       // ClassWizard generated virtual function overrides
+       //{{AFX_VIRTUAL(CCreateTGDlg)
+       protected:
+       virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+       //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+
+       // Generated message map functions
+       //{{AFX_MSG(CCreateTGDlg)
+               // NOTE: the ClassWizard will add member functions here
+       //}}AFX_MSG
+       DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_CREATETGDLG_H__5A71CFF5_7762_47E8_AE58_6E724657EC48__INCLUDED_)
diff --git a/src/console/win32/CreateTemplateDlg.cpp b/src/console/win32/CreateTemplateDlg.cpp
new file mode 100644 (file)
index 0000000..7421f3a
--- /dev/null
@@ -0,0 +1,43 @@
+// CreateTemplateDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "nxcon.h"
+#include "CreateTemplateDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CCreateTemplateDlg dialog
+
+
+CCreateTemplateDlg::CCreateTemplateDlg(CWnd* pParent /*=NULL*/)
+       : CCreateObjectDlg(CCreateTemplateDlg::IDD, pParent)
+{
+       //{{AFX_DATA_INIT(CCreateTemplateDlg)
+               // NOTE: the ClassWizard will add member initialization here
+       //}}AFX_DATA_INIT
+}
+
+
+void CCreateTemplateDlg::DoDataExchange(CDataExchange* pDX)
+{
+       CCreateObjectDlg::DoDataExchange(pDX);
+       //{{AFX_DATA_MAP(CCreateTemplateDlg)
+               // NOTE: the ClassWizard will add DDX and DDV calls here
+       //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CCreateTemplateDlg, CCreateObjectDlg)
+       //{{AFX_MSG_MAP(CCreateTemplateDlg)
+               // NOTE: the ClassWizard will add message map macros here
+       //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CCreateTemplateDlg message handlers
diff --git a/src/console/win32/CreateTemplateDlg.h b/src/console/win32/CreateTemplateDlg.h
new file mode 100644 (file)
index 0000000..40feee1
--- /dev/null
@@ -0,0 +1,49 @@
+#if !defined(AFX_CREATETEMPLATEDLG_H__79782431_AEF6_4657_914D_3BA095729AE5__INCLUDED_)
+#define AFX_CREATETEMPLATEDLG_H__79782431_AEF6_4657_914D_3BA095729AE5__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// CreateTemplateDlg.h : header file
+//
+
+#include "CreateObjectDlg.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CCreateTemplateDlg dialog
+
+class CCreateTemplateDlg : public CCreateObjectDlg
+{
+// Construction
+public:
+       CCreateTemplateDlg(CWnd* pParent = NULL);   // standard constructor
+
+// Dialog Data
+       //{{AFX_DATA(CCreateTemplateDlg)
+       enum { IDD = IDD_CREATE_TEMPLATE };
+               // NOTE: the ClassWizard will add data members here
+       //}}AFX_DATA
+
+
+// Overrides
+       // ClassWizard generated virtual function overrides
+       //{{AFX_VIRTUAL(CCreateTemplateDlg)
+       protected:
+       virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+       //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+
+       // Generated message map functions
+       //{{AFX_MSG(CCreateTemplateDlg)
+               // NOTE: the ClassWizard will add member functions here
+       //}}AFX_MSG
+       DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_CREATETEMPLATEDLG_H__79782431_AEF6_4657_914D_3BA095729AE5__INCLUDED_)
index 7d5ade5..fb443d1 100644 (file)
@@ -172,6 +172,8 @@ BEGIN_MESSAGE_MAP(CObjectBrowser, CMDIChildWnd)
        ON_UPDATE_COMMAND_UI(ID_OBJECT_POLL_STATUS, OnUpdateObjectPollStatus)
        ON_UPDATE_COMMAND_UI(ID_OBJECT_POLL_CONFIGURATION, OnUpdateObjectPollConfiguration)
        ON_WM_CLOSE()
+       ON_COMMAND(ID_OBJECT_CREATE_TEMPLATE, OnObjectCreateTemplate)
+       ON_COMMAND(ID_OBJECT_CREATE_TEMPLATEGROUP, OnObjectCreateTemplategroup)
        //}}AFX_MSG_MAP
    ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_VIEW, OnTreeViewSelChange)
        ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST_VIEW, OnListViewColumnClick)
@@ -348,6 +350,10 @@ void CObjectBrowser::OnViewRefresh()
    if (pObject != NULL)
       AddObjectToTree(pObject, TVI_ROOT);
    
+   pObject = NXCGetTemplateRootObject();
+   if (pObject != NULL)
+      AddObjectToTree(pObject, TVI_ROOT);
+   
    qsort(m_pTreeHash, m_dwTreeHashSize, sizeof(OBJ_TREE_HASH), CompareTreeHashItems);
 
    // Populate object's list
@@ -1173,7 +1179,7 @@ void CObjectBrowser::OnUpdateObjectProperties(CCmdUI* pCmdUI)
 
 void CObjectBrowser::OnUpdateObjectDatacollection(CCmdUI* pCmdUI) 
 {
-   pCmdUI->Enable(CurrObjectIsNode());
+   pCmdUI->Enable(CurrObjectIsNode(TRUE));
 }
 
 void CObjectBrowser::OnUpdateObjectUnmanage(CCmdUI* pCmdUI) 
@@ -1334,6 +1340,26 @@ void CObjectBrowser::OnObjectCreateNode()
 }
 
 
+//
+// WM_COMMAND::ID_OBJECT_CREATE_TEMPLATE message handler
+//
+
+void CObjectBrowser::OnObjectCreateTemplate() 
+{
+   theApp.CreateTemplate((m_pCurrentObject != NULL) ? m_pCurrentObject->dwId : 0);
+}
+
+
+//
+// WM_COMMAND::ID_OBJECT_CREATE_TEMPLATEGROUP message handler
+//
+
+void CObjectBrowser::OnObjectCreateTemplategroup() 
+{
+   theApp.CreateTemplateGroup((m_pCurrentObject != NULL) ? m_pCurrentObject->dwId : 0);
+}
+
+
 //
 // WM_COMMAND::ID_OBJECT_DELETE message handler
 //
@@ -1419,7 +1445,7 @@ void CObjectBrowser::OnObjectPollConfiguration()
 // returns TRUE if currently selected object is node
 //
 
-BOOL CObjectBrowser::CurrObjectIsNode()
+BOOL CObjectBrowser::CurrObjectIsNode(BOOL bIncludeTemplates)
 {
    if (m_pCurrentObject == NULL)
    {
@@ -1428,10 +1454,20 @@ BOOL CObjectBrowser::CurrObjectIsNode()
    else
    {
       if (m_dwFlags & VIEW_OBJECTS_AS_TREE)
-         return (m_pCurrentObject->iClass == OBJECT_NODE);
+      {
+         return bIncludeTemplates ? 
+            ((m_pCurrentObject->iClass == OBJECT_NODE) || 
+             (m_pCurrentObject->iClass == OBJECT_TEMPLATE)) :
+            (m_pCurrentObject->iClass == OBJECT_NODE);
+      }
       else
-         return ((m_pCurrentObject->iClass == OBJECT_NODE) &&
+      {
+         return ((bIncludeTemplates ? 
+            ((m_pCurrentObject->iClass == OBJECT_NODE) || 
+             (m_pCurrentObject->iClass == OBJECT_TEMPLATE)) :
+            (m_pCurrentObject->iClass == OBJECT_NODE)) &&
                  (m_wndListCtrl.GetSelectedCount() == 1));
+      }
    }
 }
 
index 555d9c9..9b6f596 100644 (file)
@@ -146,6 +146,8 @@ protected:
        afx_msg void OnUpdateObjectPollStatus(CCmdUI* pCmdUI);
        afx_msg void OnUpdateObjectPollConfiguration(CCmdUI* pCmdUI);
        afx_msg void OnClose();
+       afx_msg void OnObjectCreateTemplate();
+       afx_msg void OnObjectCreateTemplategroup();
        //}}AFX_MSG
    afx_msg void OnFindObject(WPARAM wParam, LPARAM lParam);
    afx_msg void OnTreeViewSelChange(LPNMTREEVIEW lpnmt);
@@ -155,7 +157,7 @@ protected:
    afx_msg void OnListViewDblClk(LPNMITEMACTIVATE pNMHDR, LRESULT *pResult);
        DECLARE_MESSAGE_MAP()
 private:
-       BOOL CurrObjectIsNode(void);
+       BOOL CurrObjectIsNode(BOOL bIncludeTemplates = FALSE);
        int m_iLastObjectImage;
        void UpdateObjectListEntry(int iItem, NXC_OBJECT *pObject);
        void UpdateObjectList(NXC_OBJECT *pObject);
index b04d7cf..296c1f9 100644 (file)
@@ -66,7 +66,8 @@ CImageList *g_pObjectNormalImageList = NULL;
 char *g_szStatusText[] = { "NORMAL", "WARNING", "MINOR", "MAJOR", "CRITICAL", "UNKNOWN", "UNMANAGED", "DISABLED", "TESTING" };
 char *g_szStatusTextSmall[] = { "Normal", "Warning", "Minor", "Major", "Critical", "Unknown", "Unmanaged", "Disabled", "Testing" };
 char *g_szObjectClass[] = { "Generic", "Subnet", "Node", "Interface", "Network", 
-                            "Container", "Zone", "ServiceRoot", "Template", "TemplateGroup" };
+                            "Container", "Zone", "ServiceRoot", "Template", 
+                            "TemplateGroup", "TemplateRoot" };
 char *g_szActionType[] = { "Execute", "Remote", "E-Mail", "SMS" };
 char *g_szInterfaceTypes[] = {
    "Unknown",
index 31f5e44..805c6ad 100644 (file)
@@ -2,25 +2,25 @@
 
 [General Info]
 Version=1
-LastClass=CNodePoller
-LastTemplate=CMDIChildWnd
+LastClass=CCreateTGDlg
+LastTemplate=CDialog
 NewFileInclude1=#include "stdafx.h"
 NewFileInclude2=#include "nxcon.h"
 LastPage=0
 
-ClassCount=65
+ClassCount=67
 Class1=CConsoleApp
 Class3=CMainFrame
 Class4=CChildFrame
 Class7=CEventBrowser
 Class9=CMapView
 
-ResourceCount=83
+ResourceCount=85
 Resource1=IDD_THRESHOLD (English (U.S.))
-Resource2=IDA_OBJECT_BROWSER
+Resource2=IDR_MAINFRAME
 Resource3=IDM_VIEW_SPECIFIC (English (U.S.))
-Resource4=IDD_EDIT_RULE_SEVERITY
-Resource5=IDD_MIB_BROWSER
+Resource4=IDD_EDIT_RULE_ALARM
+Resource5=IDD_SELECT_OBJECT
 Class2=CChildView
 Class5=CAboutDlg
 Class6=CControlPanel
@@ -28,9 +28,9 @@ Class8=CMapFrame
 Class10=CLoginDialog
 Resource6=IDD_USER_PROPERTIES
 Class11=CProgressDialog
-Resource7=IDD_EDIT_RULE_ALARM
+Resource7=IDD_CP_GENERAL
 Class12=CObjectBrowser
-Resource8=IDD_THRESHOLD
+Resource8=IDD_MIB_BROWSER
 Class13=CObjectPropDlg
 Resource9=IDD_CP_GENERAL (English (U.S.))
 Resource10=IDA_OBJECT_BROWSER (English (U.S.))
@@ -59,32 +59,32 @@ Class23=CNodePropsGeneral
 Resource23=IDD_LOGIN (English (U.S.))
 Class24=CObjectPropCaps
 Class25=CObjectPropSheet
-Resource24=IDD_ABOUTBOX
+Resource24=IDA_ALARM_BROWSER
 Class26=CRequestProcessingDlg
 Resource25=IDD_EDIT_EVENT (English (U.S.))
 Resource26=IDD_PROGRESS (English (U.S.))
-Resource27=IDD_NEW_ACTION
+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_COLLECTION
-Resource32=IDD_SELECT_OBJECT
+Resource32=IDD_EDIT_RULE_COMMENT
 Class29=CUserSelectDlg
 Resource33=IDD_NEW_USER
 Class30=CUserEditor
 Resource34=IDD_DCI_PROPERTIES
 Class31=CNewUserDlg
-Resource35=IDM_CONTEXT
-Resource36=IDR_MAINFRAME
+Resource35=IDA_MDI_DEFAULT
+Resource36=IDD_CREATE_TG
 Class32=CUserPropDlg
 Resource37=IDM_CONTEXT (English (U.S.))
-Resource38=IDD_ACTION_PROPERTIES
+Resource38=IDD_SELECT_ACTION
 Class33=CGroupPropDlg
-Resource39=IDD_SELECT_EVENT
-Resource40=IDA_EPP
-Resource41=IDD_CREATE_NODE
+Resource39=IDD_OBJECT_PRESENTATION
+Resource40=IDA_OBJECT_BROWSER
+Resource41=IDD_DCI_TRANSFORM
 Resource42=IDD_SELECT_OBJECT (English (U.S.))
 Class34=CPasswordChangeDlg
 Class35=CNodeSummary
@@ -100,7 +100,7 @@ Class41=CGraphFrame
 Class42=CDCIThresholdsPage
 Resource46=IDA_MDI_DEFAULT (English (U.S.))
 Resource47=IDD_OBJECT_CAPS (English (U.S.))
-Resource48=IDD_OBJECT_GENERAL
+Resource48=IDD_REQUEST_PROCESSING
 Class43=CThresholdDlg
 Resource49=IDD_SELECT_USER (English (U.S.))
 Resource50=IDD_GROUP_PROPERTIES
@@ -109,12 +109,12 @@ Class45=CEventPolicyEditor
 Class46=CRuleList
 Class47=CRuleHeader
 Resource51=IDR_MAINFRAME (English (U.S.))
-Resource52=IDD_EDIT_EVENT
+Resource52=IDD_LOGIN
 Class48=CObjectSelDlg
-Resource53=IDD_LOGIN
-Resource54=IDD_OBJECT_PRESENTATION
+Resource53=IDD_ABOUTBOX
+Resource54=IDD_EDIT_RULE_SEVERITY
 Class49=CRuleCommentDlg
-Resource55=IDD_OBJECT_SECURITY
+Resource55=IDD_OBJECT_GENERAL
 Class50=CEventSelDlg
 Resource56=IDD_SET_PASSWORD
 Resource57=IDD_REQUEST_PROCESSING (English (U.S.))
@@ -123,32 +123,32 @@ Resource59=IDD_ABOUTBOX (English (U.S.))
 Resource60=IDD_MIB_BROWSER (English (U.S.))
 Class51=CObjectPropsPresentation
 Resource61=IDD_OBJECT_PRESENTATION (English (U.S.))
-Resource62=IDD_REQUEST_PROCESSING
+Resource62=IDD_OBJECT_CAPS
 Class52=CRuleSeverityDlg
-Resource63=IDD_EDIT_RULE_COMMENT
+Resource63=IDD_SELECT_EVENT
 Class53=CRuleAlarmDlg
 Class54=CAlarmBrowser
 Resource64=IDD_SELECT_EVENT (English (U.S.))
-Resource65=IDA_MDI_DEFAULT
+Resource65=IDM_VIEW_SPECIFIC
 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_OBJECT_NODE_GENERAL
-Resource70=IDD_CREATE_CONTAINER
+Resource69=IDD_EDIT_EVENT
+Resource70=IDD_CREATE_NODE
 Class57=CNewActionDlg
-Resource71=IDD_CP_GENERAL
+Resource71=IDD_NEW_ACTION
 Class58=CEditActionDlg
-Resource72=IDA_ALARM_BROWSER
+Resource72=IDA_EPP
 Class59=CActionSelDlg
-Resource73=IDD_SELECT_ACTION
+Resource73=IDD_CREATE_CONTAINER
 Resource74=IDD_EDIT_RULE_COMMENT (English (U.S.))
 Resource75=IDD_EDIT_RULE_ALARM (English (U.S.))
-Resource76=IDM_VIEW_SPECIFIC
+Resource76=IDM_CONTEXT
 Class60=CCreateObjectDlg
 Class61=CCreateContainerDlg
-Resource77=IDD_OBJECT_CAPS
+Resource77=IDD_OBJECT_NODE_GENERAL
 Class62=CCreateNodeDlg
 Resource78=IDA_EPP (English (U.S.))
 Resource79=IDD_CREATE_CONTAINER (English (U.S.))
@@ -158,7 +158,11 @@ Resource81=IDD_ACTION_PROPERTIES (English (U.S.))
 Class64=CPollNodeDlg
 Resource82=IDD_POLL_NODE (English (U.S.))
 Class65=CNodePoller
-Resource83=IDD_DCI_TRANSFORM
+Resource83=IDD_OBJECT_SECURITY
+Resource84=IDD_THRESHOLD
+Class66=CCreateTemplateDlg
+Class67=CCreateTGDlg
+Resource85=IDD_CREATE_TEMPLATE
 
 [CLS:CConsoleApp]
 Type=0
@@ -587,49 +591,51 @@ Command9=ID_OBJECT_VIEW_VIEWASLIST
 Command10=ID_OBJECT_FIND
 Command11=ID_OBJECT_CREATE_NODE
 Command12=ID_OBJECT_CREATE_CONTAINER
-Command13=ID_OBJECT_BIND
-Command14=ID_OBJECT_RENAME
-Command15=ID_OBJECT_DELETE
-Command16=ID_OBJECT_MANAGE
-Command17=ID_OBJECT_UNMANAGE
-Command18=ID_OBJECT_POLL_STATUS
-Command19=ID_OBJECT_POLL_CONFIGURATION
-Command20=ID_OBJECT_DATACOLLECTION
-Command21=ID_OBJECT_PROPERTIES
-Command22=ID_USER_CREATE_USER
-Command23=ID_USER_CREATE_GROUP
-Command24=ID_USER_DELETE
-Command25=ID_USER_SETPASSWORD
-Command26=ID_USER_PROPERTIES
-Command27=ID_ITEM_NEW
-Command28=ID_ITEM_EDIT
-Command29=ID_ITEM_DELETE
-Command30=ID_ITEM_COPY
-Command31=ID_ITEM_ACTIVATE
-Command32=ID_ITEM_DISABLE
-Command33=ID_ITEM_SHOWDATA
-Command34=ID_ITEM_GRAPH
-Command35=ID_POLICY_ADD
-Command36=ID_POLICY_DELETE
-Command37=ID_POLICY_EDIT
-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_ALARM_ACKNOWLEGE
-Command47=ID_ALARM_DELETE
-Command48=ID_ALARM_GOTOSOURCE
-Command49=ID_UPDATE_EVENT_LIST
-Command50=ID_CONTROLPANEL_ACTIONS
-Command51=ID_CONTROLPANEL_EVENTS
-Command52=ID_CONTROLPANEL_EVENTPOLICY
-Command53=ID_CONTROLPANEL_USERS
-Command54=ID_CONTROLPANEL_DCT
-CommandCount=54
+Command13=ID_OBJECT_CREATE_TEMPLATEGROUP
+Command14=ID_OBJECT_CREATE_TEMPLATE
+Command15=ID_OBJECT_BIND
+Command16=ID_OBJECT_RENAME
+Command17=ID_OBJECT_DELETE
+Command18=ID_OBJECT_MANAGE
+Command19=ID_OBJECT_UNMANAGE
+Command20=ID_OBJECT_POLL_STATUS
+Command21=ID_OBJECT_POLL_CONFIGURATION
+Command22=ID_OBJECT_DATACOLLECTION
+Command23=ID_OBJECT_PROPERTIES
+Command24=ID_USER_CREATE_USER
+Command25=ID_USER_CREATE_GROUP
+Command26=ID_USER_DELETE
+Command27=ID_USER_SETPASSWORD
+Command28=ID_USER_PROPERTIES
+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
+CommandCount=56
 
 [ACL:IDA_MDI_DEFAULT]
 Type=1
@@ -1190,57 +1196,59 @@ Command5=ID_USER_DELETE
 Command6=ID_USER_PROPERTIES
 Command7=ID_OBJECT_CREATE_NODE
 Command8=ID_OBJECT_CREATE_CONTAINER
-Command9=ID_OBJECT_BIND
-Command10=ID_OBJECT_RENAME
-Command11=ID_OBJECT_DELETE
-Command12=ID_OBJECT_MANAGE
-Command13=ID_OBJECT_UNMANAGE
-Command14=ID_OBJECT_POLL_STATUS
-Command15=ID_OBJECT_POLL_CONFIGURATION
-Command16=ID_OBJECT_DATACOLLECTION
-Command17=ID_OBJECT_PROPERTIES
-Command18=ID_ITEM_NEW
-Command19=ID_ITEM_EDIT
-Command20=ID_ITEM_DELETE
-Command21=ID_ITEM_COPY
-Command22=ID_ITEM_ACTIVATE
-Command23=ID_ITEM_DISABLE
-Command24=ID_ITEM_SHOWDATA
-Command25=ID_ITEM_GRAPH
-Command26=ID_POLICY_INSERTRULE_ABOVE
-Command27=ID_POLICY_INSERTRULE_BELOW
-Command28=ID_POLICY_INSERTRULE_TOP
-Command29=ID_POLICY_INSERTRULE_BOTTOM
-Command30=ID_POLICY_DELETERULE
-Command31=ID_POLICY_ENABLERULE
-Command32=ID_POLICY_DISABLERULE
-Command33=ID_POLICY_ADD
-Command34=ID_POLICY_DELETE
-Command35=ID_POLICY_NEGATECELL
-Command36=ID_POLICY_INSERTRULE_ABOVE
-Command37=ID_POLICY_INSERTRULE_BELOW
-Command38=ID_POLICY_INSERTRULE_TOP
-Command39=ID_POLICY_INSERTRULE_BOTTOM
-Command40=ID_POLICY_DELETERULE
-Command41=ID_POLICY_ENABLERULE
-Command42=ID_POLICY_DISABLERULE
-Command43=ID_POLICY_EDIT
-Command44=ID_POLICY_INSERTRULE_ABOVE
-Command45=ID_POLICY_INSERTRULE_BELOW
-Command46=ID_POLICY_INSERTRULE_TOP
-Command47=ID_POLICY_INSERTRULE_BOTTOM
-Command48=ID_POLICY_DELETERULE
-Command49=ID_POLICY_ENABLERULE
-Command50=ID_POLICY_DISABLERULE
-Command51=ID_ALARM_ACKNOWLEGE
-Command52=ID_ALARM_DELETE
-Command53=ID_ALARM_GOTOSOURCE
-Command54=ID_ACTION_NEW
-Command55=ID_ACTION_RENAME
-Command56=ID_ACTION_DELETE
-Command57=ID_ACTION_PROPERTIES
-Command58=ID_POLL_RESTART
-CommandCount=58
+Command9=ID_OBJECT_CREATE_TEMPLATEGROUP
+Command10=ID_OBJECT_CREATE_TEMPLATE
+Command11=ID_OBJECT_BIND
+Command12=ID_OBJECT_RENAME
+Command13=ID_OBJECT_DELETE
+Command14=ID_OBJECT_MANAGE
+Command15=ID_OBJECT_UNMANAGE
+Command16=ID_OBJECT_POLL_STATUS
+Command17=ID_OBJECT_POLL_CONFIGURATION
+Command18=ID_OBJECT_DATACOLLECTION
+Command19=ID_OBJECT_PROPERTIES
+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
+CommandCount=60
 
 [MNU:IDM_CONTEXT (English (U.S.))]
 Type=1
@@ -2143,3 +2151,52 @@ BaseClass=CMDIChildWnd
 Filter=W
 VirtualFilter=mfWC
 
+[DLG:IDD_CREATE_TG]
+Type=1
+Class=CCreateTGDlg
+ControlCount=12
+Control1=IDC_EDIT_NAME,edit,1350631552
+Control2=IDC_EDIT_DESCRIPTION,edit,1350631552
+Control3=IDC_SELECT_PARENT,button,1342242816
+Control4=IDOK,button,1342242817
+Control5=IDCANCEL,button,1342242816
+Control6=IDC_STATIC,button,1342177287
+Control7=IDC_STATIC,static,1342308352
+Control8=IDC_STATIC,button,1342177287
+Control9=IDC_ICON_PARENT,static,1342177283
+Control10=IDC_STATIC_ID,static,1342308352
+Control11=IDC_STATIC_NAME,static,1342308352
+Control12=IDC_STATIC,static,1342308352
+
+[DLG:IDD_CREATE_TEMPLATE]
+Type=1
+Class=CCreateTemplateDlg
+ControlCount=10
+Control1=IDC_EDIT_NAME,edit,1350631552
+Control2=IDC_SELECT_PARENT,button,1342242816
+Control3=IDOK,button,1342242817
+Control4=IDCANCEL,button,1342242816
+Control5=IDC_STATIC,button,1342177287
+Control6=IDC_STATIC,static,1342308352
+Control7=IDC_STATIC,button,1342177287
+Control8=IDC_ICON_PARENT,static,1342177283
+Control9=IDC_STATIC_ID,static,1342308352
+Control10=IDC_STATIC_NAME,static,1342308352
+
+[CLS:CCreateTemplateDlg]
+Type=0
+HeaderFile=CreateTemplateDlg.h
+ImplementationFile=CreateTemplateDlg.cpp
+BaseClass=CCreateObjectDlg
+Filter=D
+LastObject=CCreateTemplateDlg
+
+[CLS:CCreateTGDlg]
+Type=0
+HeaderFile=CreateTGDlg.h
+ImplementationFile=CreateTGDlg.cpp
+BaseClass=CCreateObjectDlg
+Filter=D
+VirtualFilter=dWC
+LastObject=CCreateTGDlg
+
index 7c1c003..6fdec19 100644 (file)
@@ -8,6 +8,8 @@
 #include "LoginDialog.h"
 #include "CreateContainerDlg.h"
 #include "CreateNodeDlg.h"
+#include "CreateTemplateDlg.h"
+#include "CreateTGDlg.h"
 #include "NodePoller.h"
 
 #ifdef _DEBUG
@@ -1232,6 +1234,47 @@ void CConsoleApp::CreateNode(DWORD dwParent)
 }
 
 
+//
+// Create template object
+//
+
+void CConsoleApp::CreateTemplate(DWORD dwParent)
+{
+   NXC_OBJECT_CREATE_INFO ci;
+   CCreateTemplateDlg dlg;
+
+   dlg.m_pParentObject = NXCFindObjectById(dwParent);
+   if (dlg.DoModal() == IDOK)
+   {
+      ci.dwParentId = (dlg.m_pParentObject != NULL) ? dlg.m_pParentObject->dwId : 0;
+      ci.iClass = OBJECT_TEMPLATE;
+      ci.pszName = (char *)((LPCTSTR)dlg.m_strObjectName);
+      CreateObject(&ci);
+   }
+}
+
+
+//
+// Create template group object
+//
+
+void CConsoleApp::CreateTemplateGroup(DWORD dwParent)
+{
+   NXC_OBJECT_CREATE_INFO ci;
+   CCreateTGDlg dlg;
+
+   dlg.m_pParentObject = NXCFindObjectById(dwParent);
+   if (dlg.DoModal() == IDOK)
+   {
+      ci.dwParentId = (dlg.m_pParentObject != NULL) ? dlg.m_pParentObject->dwId : 0;
+      ci.iClass = OBJECT_TEMPLATEGROUP;
+      ci.pszName = (char *)((LPCTSTR)dlg.m_strObjectName);
+      ci.cs.templateGroup.pszDescription = (char *)((LPCTSTR)dlg.m_strDescription);
+      CreateObject(&ci);
+   }
+}
+
+
 //
 // Delete object on server
 //
index 26b0618..edc0c5a 100644 (file)
@@ -137,6 +137,14 @@ SOURCE=.\CreateObjectDlg.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\CreateTemplateDlg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CreateTGDlg.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\DataCollectionEditor.cpp
 # End Source File
 # Begin Source File
@@ -394,6 +402,14 @@ SOURCE=.\CreateObjectDlg.h
 # End Source File
 # Begin Source File
 
+SOURCE=.\CreateTemplateDlg.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CreateTGDlg.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\DataCollectionEditor.h
 # End Source File
 # Begin Source File
index e443740..010495d 100644 (file)
@@ -166,6 +166,8 @@ private:
    DC_EDITOR m_openDCEditors[MAX_DC_EDITORS];
 
 public:
+       void CreateTemplateGroup(DWORD dwParent);
+       void CreateTemplate(DWORD dwParent);
        void PollNode(DWORD dwObjectId, int iPollType);
        void DeleteNetXMSObject(NXC_OBJECT *pObject);
        void CreateNode(DWORD dwParent);
index 36241cc..0fe5770 100644 (file)
@@ -203,6 +203,10 @@ BEGIN
             MENUITEM "&Node...",                    ID_OBJECT_CREATE_NODE
             MENUITEM "&Container...",               ID_OBJECT_CREATE_CONTAINER
 
+            MENUITEM "Template &group...",          ID_OBJECT_CREATE_TEMPLATEGROUP
+
+            MENUITEM "&Template...",                ID_OBJECT_CREATE_TEMPLATE
+
         END
         MENUITEM "&Bind...\tCtrl+B",            ID_OBJECT_BIND
         MENUITEM "&Rename",                     ID_OBJECT_RENAME
@@ -311,6 +315,10 @@ BEGIN
             MENUITEM "&Node...",                    ID_OBJECT_CREATE_NODE
             MENUITEM "&Container...",               ID_OBJECT_CREATE_CONTAINER
 
+            MENUITEM "Template &group...",          ID_OBJECT_CREATE_TEMPLATEGROUP
+
+            MENUITEM "&Template...",                ID_OBJECT_CREATE_TEMPLATE
+
         END
         MENUITEM "&Bind...",                    ID_OBJECT_BIND
         MENUITEM "&Rename",                     ID_OBJECT_RENAME
@@ -1117,6 +1125,42 @@ BEGIN
     PUSHBUTTON      "&Create...",IDC_BUTTON_CREATE,171,68,50,14
 END
 
+IDD_CREATE_TG DIALOG DISCARDABLE  0, 0, 229, 126
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Create Template Group"
+FONT 8, "MS Sans Serif"
+BEGIN
+    EDITTEXT        IDC_EDIT_NAME,13,26,146,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_EDIT_DESCRIPTION,13,53,146,14,ES_AUTOHSCROLL
+    PUSHBUTTON      "&Select...",IDC_SELECT_PARENT,110,88,50,12
+    DEFPUSHBUTTON   "OK",IDOK,172,7,50,14
+    PUSHBUTTON      "Cancel",IDCANCEL,172,24,50,14
+    GROUPBOX        "New object",IDC_STATIC,7,7,158,66
+    LTEXT           "Name",IDC_STATIC,13,17,20,8
+    GROUPBOX        "Parent object",IDC_STATIC,7,77,158,42
+    ICON            "",IDC_ICON_PARENT,14,90,21,20
+    LTEXT           "ID:",IDC_STATIC_ID,43,90,54,8
+    LTEXT           "Name",IDC_STATIC_NAME,44,104,112,9
+    LTEXT           "Description",IDC_STATIC,13,44,36,8
+END
+
+IDD_CREATE_TEMPLATE DIALOG DISCARDABLE  0, 0, 229, 100
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Create Template"
+FONT 8, "MS Sans Serif"
+BEGIN
+    EDITTEXT        IDC_EDIT_NAME,13,27,146,14,ES_AUTOHSCROLL
+    PUSHBUTTON      "&Select...",IDC_SELECT_PARENT,110,62,50,12
+    DEFPUSHBUTTON   "OK",IDOK,172,7,50,14
+    PUSHBUTTON      "Cancel",IDCANCEL,172,24,50,14
+    GROUPBOX        "New object",IDC_STATIC,7,7,158,41
+    LTEXT           "Name",IDC_STATIC,13,18,20,8
+    GROUPBOX        "Parent object",IDC_STATIC,7,51,158,42
+    ICON            "",IDC_ICON_PARENT,14,64,21,20
+    LTEXT           "ID:",IDC_STATIC_ID,43,64,54,8
+    LTEXT           "Name",IDC_STATIC_NAME,44,78,112,9
+END
+
 
 #ifndef _MAC
 /////////////////////////////////////////////////////////////////////////////
@@ -1408,6 +1452,22 @@ BEGIN
         TOPMARGIN, 7
         BOTTOMMARGIN, 128
     END
+
+    IDD_CREATE_TG, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 222
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 119
+    END
+
+    IDD_CREATE_TEMPLATE, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 222
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 93
+    END
 END
 #endif    // APSTUDIO_INVOKED
 
index 4343608..2200a84 100644 (file)
 #define IDI_DATACOLLECT                 226
 #define IDI_DCT                         227
 #define IDD_POLL_NODE                   228
+#define IDD_CREATE_TG                   229
+#define IDD_CREATE_TEMPLATE             230
 #define ID_EDIT_BOX                     525
 #define IDC_EDIT_SERVER                 1000
 #define IDC_EDIT_LOGIN                  1001
 #define ID_CONTROLPANEL_DCT             32880
 #define ID_POLL_RESTART                 32881
 #define ID_ITEM_COPY                    32882
+#define ID_OBJECT_CREATE_TEMPLATEGROUP  32883
+#define ID_OBJECT_CREATE_TEMPLATE       32884
 #define IDS_GETFOLDERPATH_FAILED        61216
 #define IDS_WORKDIR_CREATION_FAILED     61217
 
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_3D_CONTROLS                     1
-#define _APS_NEXT_RESOURCE_VALUE        229
-#define _APS_NEXT_COMMAND_VALUE         32883
+#define _APS_NEXT_RESOURCE_VALUE        231
+#define _APS_NEXT_COMMAND_VALUE         32885
 #define _APS_NEXT_CONTROL_VALUE         1173
 #define _APS_NEXT_SYMED_VALUE           120
 #endif
index 2c15862..cd066db 100644 (file)
@@ -169,7 +169,7 @@ BOOL LIBNETXMS_EXPORTABLE CalculateFileMD5Hash(TCHAR *pszFileName, BYTE *pHash)
       I_md5_init(&state);
       while(1)
       {
-         iSize = fread(szBuffer, FILE_BLOCK_SIZE, 1, fileHandle);
+         iSize = fread(szBuffer, 1, FILE_BLOCK_SIZE, fileHandle);
          if (iSize <= 0)
             break;
        I_md5_append(&state, (const md5_byte_t *)szBuffer, iSize);
@@ -203,7 +203,7 @@ BOOL LIBNETXMS_EXPORTABLE CalculateFileSHA1Hash(TCHAR *pszFileName, BYTE *pHash)
       I_SHA1Init(&context);
       while(1)
       {
-         iSize = fread(szBuffer, FILE_BLOCK_SIZE, 1, fileHandle);
+         iSize = fread(szBuffer, 1, FILE_BLOCK_SIZE, fileHandle);
          if (iSize <= 0)
             break;
          I_SHA1Update(&context, (BYTE *)szBuffer, iSize);
index 793a352..a4bee17 100644 (file)
@@ -347,6 +347,19 @@ NXC_OBJECT LIBNXCL_EXPORTABLE *NXCGetServiceRootObject(void)
 }
 
 
+//
+// Get template tree root ("Templates") object
+//
+
+NXC_OBJECT LIBNXCL_EXPORTABLE *NXCGetTemplateRootObject(void)
+{
+   if (m_dwNumObjects > 2)
+      if (m_pIndexById[2].dwKey == 3)
+         return m_pIndexById[2].pObject;
+   return NULL;
+}
+
+
 //
 // Get pointer to first object on objects' list and entire number of objects
 //
@@ -507,6 +520,9 @@ DWORD LIBNXCL_EXPORTABLE NXCCreateObject(NXC_OBJECT_CREATE_INFO *pCreateInfo, DW
          msg.SetVariable(VID_CATEGORY, pCreateInfo->cs.container.dwCategory);
          msg.SetVariable(VID_DESCRIPTION, pCreateInfo->cs.container.pszDescription);
          break;
+      case OBJECT_TEMPLATEGROUP:
+         msg.SetVariable(VID_DESCRIPTION, pCreateInfo->cs.templateGroup.pszDescription);
+         break;
       default:
          break;
    }
index 3b91902..f503f2d 100644 (file)
@@ -246,7 +246,7 @@ BOOL ParseCommandLine(int argc, char *argv[])
 // Read string value from configuration table
 //
 
-BOOL ConfigReadStr(char *szVar, char *szBuffer, int iBufSize, char *szDefault)
+BOOL ConfigReadStr(char *szVar, char *szBuffer, int iBufSize, const char *szDefault)
 {
    DB_RESULT hResult;
    char szQuery[256];
index 76a0ef5..4607aa6 100644 (file)
@@ -161,15 +161,15 @@ BOOL Container::SaveToDB(void)
 
    // Form and execute INSERT or UPDATE query
    if (bNewObject)
-      sprintf(szQuery, "INSERT INTO containers (id,name,status,is_deleted,category,description,image_id)"
-                       " VALUES (%ld,'%s',%d,%d,%ld,'%s',%ld)",
+      sprintf(szQuery, "INSERT INTO containers (id,name,status,is_deleted,category,"
+                       "description,image_id,object_class) VALUES (%ld,'%s',%d,%d,%ld,'%s',%ld,%d)",
               m_dwId, m_szName, m_iStatus, m_bIsDeleted, m_dwCategory,
-              CHECK_NULL(m_pszDescription), m_dwImageId);
+              CHECK_NULL(m_pszDescription), m_dwImageId, Type());
    else
       sprintf(szQuery, "UPDATE containers SET name='%s',status=%d,is_deleted=%d,category=%ld,"
-                       "description='%s',image_id=%ld WHERE id=%ld",
+                       "description='%s',image_id=%ld,object_class=%d WHERE id=%ld",
               m_szName, m_iStatus, m_bIsDeleted, m_dwCategory, 
-              CHECK_NULL(m_pszDescription), m_dwImageId, m_dwId);
+              CHECK_NULL(m_pszDescription), m_dwImageId, Type(), m_dwId);
    DBQuery(g_hCoreDB, szQuery);
 
    // Update members list
index b679512..119c9a8 100644 (file)
@@ -48,7 +48,7 @@ static char *m_pszGroupNames[] =
    "Container Categories",
    "User-defined Events",
    "Data Collection Items",
-   "Data Collection Templates",
+   "<unused>",
    "Images",
    "Actions",
    "Event Groups",
@@ -103,6 +103,14 @@ BOOL InitIdTable(void)
                                                    DBGetFieldULong(hResult, 0, 0) + 1);
       DBFreeResult(hResult);
    }
+   hResult = DBSelect(g_hCoreDB, "SELECT max(id) FROM templates");
+   if (hResult != NULL)
+   {
+      if (DBGetNumRows(hResult) > 0)
+         m_dwFreeIdTable[IDG_NETWORK_OBJECT] = max(m_dwFreeIdTable[IDG_NETWORK_OBJECT],
+                                                   DBGetFieldULong(hResult, 0, 0) + 1);
+      DBFreeResult(hResult);
+   }
    hResult = DBSelect(g_hCoreDB, "SELECT max(object_id) FROM deleted_objects");
    if (hResult != NULL)
    {
@@ -139,15 +147,6 @@ BOOL InitIdTable(void)
       DBFreeResult(hResult);
    }
 
-   // Get first available data collection template id
-   hResult = DBSelect(g_hCoreDB, "SELECT max(template_id) FROM dct");
-   if (hResult != NULL)
-   {
-      if (DBGetNumRows(hResult) > 0)
-         m_dwFreeIdTable[IDG_DCT] = max(1, DBGetFieldULong(hResult, 0, 0) + 1);
-      DBFreeResult(hResult);
-   }
-
    // Get first available action id
    hResult = DBSelect(g_hCoreDB, "SELECT max(action_id) FROM actions");
    if (hResult != NULL)
index b0c5f9e..58470b2 100644 (file)
@@ -30,7 +30,7 @@
 void UpdateImageHashes(void)
 {
    DB_RESULT hResult;
-   int i, j, iNumImages, iPathLen, iFormat;
+   int i, iNumImages, iPathLen, iFormat;
    char szPath[MAX_PATH], szHashText[MD5_DIGEST_SIZE * 2 + 1], szQuery[1024];
    BYTE hash[MD5_DIGEST_SIZE];
    DWORD dwImageId;
@@ -53,10 +53,8 @@ void UpdateImageHashes(void)
             strcpy(&szPath[iPathLen], DBGetField(hResult, i, iFormat));
             if (CalculateFileMD5Hash(szPath, hash))
             {
-               // Convert MD5 hash to text form
-               for(j = 0; j < MD5_DIGEST_SIZE; j++)
-                  sprintf(&szHashText[j << 1], "%02x", hash[j]);
-
+               // Convert MD5 hash to text form and update database
+               BinToStr(hash, MD5_DIGEST_SIZE, szHashText);
                sprintf(szQuery, "UPDATE images SET file_hash_%s='%s' WHERE image_id=%ld",
                        szExt[iFormat], szHashText, dwImageId);
                DBQuery(g_hCoreDB, szQuery);
index b98b835..4e37593 100644 (file)
@@ -110,6 +110,18 @@ Language=English
 Failed to load container object with id %1 from database
 .
 
+MessageId=
+SymbolicName=MSG_TG_LOAD_FAILED
+Language=English
+Failed to load template group object with id %1 from database
+.
+
+MessageId=
+SymbolicName=MSG_TEMPLATE_LOAD_FAILED
+Language=English
+Failed to load template object with id %1 from database
+.
+
 MessageId=
 SymbolicName=MSG_INVALID_SUBNET_ID
 Language=English
@@ -351,9 +363,9 @@ Inconsistent database: container object %1 has reference to non-existing child o
 .
 
 MessageId=
-SymbolicName=MSG_SRVROOT_INVALID_CHILD_ID
+SymbolicName=MSG_ROOT_INVALID_CHILD_ID
 Language=English
-Inconsistent database: service root object has reference to non-existing child object %1
+Inconsistent database: %2 object has reference to non-existing child object %1
 .
 
 MessageId=
@@ -392,4 +404,16 @@ Language=English
 Signal %1 received
 .
 
+MessageId=
+SymbolicName=MSG_INVALID_DCT_MAP
+Language=English
+Inconsistent database: template object %1 has reference to non-existing node object %2
+.
+
+MessageId=
+SymbolicName=MSG_DCT_MAP_NOT_NODE
+Language=English
+Inconsistent database: template object %1 has reference to child object %2 which is not a node object
+.
+
 ;#endif
index 10613d0..ff15e5c 100644 (file)
@@ -219,15 +219,15 @@ SOURCE=.\objects.cpp
 # End Source File
 # Begin Source File
 
-SOURCE=.\session.cpp
+SOURCE=.\rootobj.cpp
 # End Source File
 # Begin Source File
 
-SOURCE=.\snmp.cpp
+SOURCE=.\session.cpp
 # End Source File
 # Begin Source File
 
-SOURCE=.\srvroot.cpp
+SOURCE=.\snmp.cpp
 # End Source File
 # Begin Source File
 
@@ -251,6 +251,10 @@ SOURCE=.\tools.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\uniroot.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\users.cpp
 # End Source File
 # Begin Source File
index 347f38c..d140830 100644 (file)
@@ -115,7 +115,7 @@ typedef void * HSNMPSESSION;
 #define IDG_CONTAINER_CAT     1
 #define IDG_EVENT             2
 #define IDG_ITEM              3
-#define IDG_DCT               4
+//#define IDG_DCT               4
 #define IDG_IMAGE             5
 #define IDG_ACTION            6
 #define IDG_EVENT_GROUP       7
@@ -332,7 +332,7 @@ public:
 // Functions
 //
 
-BOOL ConfigReadStr(char *szVar, char *szBuffer, int iBufSize, char *szDefault);
+BOOL ConfigReadStr(char *szVar, char *szBuffer, int iBufSize, const char *szDefault);
 int ConfigReadInt(char *szVar, int iDefault);
 DWORD ConfigReadULong(char *szVar, DWORD dwDefault);
 BOOL ConfigWriteStr(char *szVar, char *szValue, BOOL bCreate);
index d12731f..9dbd336 100644 (file)
@@ -180,12 +180,14 @@ public:
    Template();
    virtual ~Template();
 
-   virtual int Type(void) { return OBJECT_NODE; }
+   virtual int Type(void) { return OBJECT_TEMPLATE; }
 
    virtual BOOL SaveToDB(void);
    virtual BOOL DeleteFromDB(void);
    virtual BOOL CreateFromDB(DWORD dwId);
 
+   virtual void CalculateCompoundStatus(void);
+
    BOOL AddItem(DCItem *pItem);
    BOOL UpdateItem(DWORD dwItemId, CSCPMessage *pMsg, DWORD *pdwNumMaps, 
                    DWORD **ppdwMapIndex, DWORD **ppdwMapId);
@@ -370,6 +372,25 @@ public:
 };
 
 
+//
+// Universal root object
+//
+
+class UniversalRoot : public NetObj
+{
+public:
+   UniversalRoot();
+   virtual ~UniversalRoot();
+
+   virtual BOOL SaveToDB(void);
+   virtual void LoadFromDB(void);
+   virtual const char *DefaultName(void) { return "Root Object"; }
+
+   void LinkChildObjects(void);
+   void LinkObject(NetObj *pObject) { AddChild(pObject); pObject->AddParent(this); }
+};
+
+
 //
 // Entire network
 //
@@ -392,18 +413,30 @@ public:
 // Service root
 //
 
-class ServiceRoot : public NetObj
+class ServiceRoot : public UniversalRoot
 {
 public:
    ServiceRoot();
    virtual ~ServiceRoot();
 
    virtual int Type(void) { return OBJECT_SERVICEROOT; }
-   virtual BOOL SaveToDB(void);
-   void LoadFromDB(void);
-   void LinkChildObjects(void);
+   virtual const char *DefaultName(void) { return "All Services"; }
+};
 
-   void LinkObject(NetObj *pObject) { AddChild(pObject); pObject->AddParent(this); }
+
+//
+// Template root
+//
+
+class TemplateRoot : public UniversalRoot
+{
+public:
+   TemplateRoot();
+   virtual ~TemplateRoot();
+
+   virtual int Type(void) { return OBJECT_TEMPLATEROOT; }
+   virtual const char *DefaultName(void) { return "Templates"; }
+   virtual void CalculateCompoundStatus(void);
 };
 
 
@@ -453,7 +486,7 @@ public:
    TemplateGroup(char *pszName, char *pszDescription) : Container(pszName, 0, pszDescription) { }
    virtual ~TemplateGroup() { }
 
-   virtual int Type(void) { return OBJECT_TEMPLATE_GROUP; }
+   virtual int Type(void) { return OBJECT_TEMPLATEGROUP; }
 };
 
 
@@ -504,6 +537,8 @@ void DumpObjects(void);
 
 void DeleteUserFromAllObjects(DWORD dwUserId);
 
+BOOL IsValidParentClass(int iChildClass, int iParentClass);
+
 
 //
 // Global variables
@@ -511,6 +546,7 @@ void DeleteUserFromAllObjects(DWORD dwUserId);
 
 extern Network *g_pEntireNet;
 extern ServiceRoot *g_pServiceRoot;
+extern TemplateRoot *g_pTemplateRoot;
 
 extern DWORD g_dwMgmtNode;
 extern INDEX *g_pIndexById;
@@ -528,6 +564,7 @@ extern MUTEX g_hMutexInterfaceIndex;
 extern MUTEX g_hMutexObjectAccess;
 extern DWORD g_dwNumCategories;
 extern CONTAINER_CATEGORY *g_pContainerCatList;
+extern char *g_szClassName[];
 
 
 #endif   /* _nms_objects_h_ */
index 714c702..27914a8 100644 (file)
@@ -29,6 +29,7 @@
 
 Network *g_pEntireNet = NULL;
 ServiceRoot *g_pServiceRoot = NULL;
+TemplateRoot *g_pTemplateRoot = NULL;
 
 DWORD g_dwMgmtNode = 0;
 INDEX *g_pIndexById = NULL;
@@ -51,6 +52,9 @@ CONTAINER_CATEGORY *g_pContainerCatList = NULL;
 
 char *g_pszStatusName[] = { "Normal", "Warning", "Minor", "Major", "Critical",
                             "Unknown", "Unmanaged", "Disabled", "Testing" };
+char *g_szClassName[]={ "Generic", "Subnet", "Node", "Interface",
+                        "Network", "Container", "Zone", "ServiceRoot",
+                        "Template", "TemplateGroup", "TemplateRoot" };
 
 
 //
@@ -72,6 +76,10 @@ void ObjectsInit(void)
    // Create "Service Root" object
    g_pServiceRoot = new ServiceRoot;
    NetObjInsert(g_pServiceRoot, FALSE);
+
+   // Create "Template Root" object
+   g_pTemplateRoot = new TemplateRoot;
+   NetObjInsert(g_pTemplateRoot, FALSE);
 }
 
 
@@ -408,6 +416,7 @@ BOOL LoadObjects(void)
    DB_RESULT hResult;
    DWORD i, dwNumRows;
    DWORD dwId;
+   char szQuery[256];
 
    // Load container categories
    hResult = DBSelect(g_hCoreDB, "SELECT category,name,image_id,description FROM container_categories");
@@ -428,6 +437,7 @@ BOOL LoadObjects(void)
    // Load built-in object properties
    g_pEntireNet->LoadFromDB();
    g_pServiceRoot->LoadFromDB();
+   g_pTemplateRoot->LoadFromDB();
 
    // Load subnets
    hResult = DBSelect(g_hCoreDB, "SELECT id FROM subnets");
@@ -503,8 +513,33 @@ BOOL LoadObjects(void)
       DBFreeResult(hResult);
    }
 
+   // Load templates
+   hResult = DBSelect(g_hCoreDB, "SELECT id FROM templates");
+   if (hResult != 0)
+   {
+      Template *pTemplate;
+
+      dwNumRows = DBGetNumRows(hResult);
+      for(i = 0; i < dwNumRows; i++)
+      {
+         dwId = DBGetFieldULong(hResult, i, 0);
+         pTemplate = new Template;
+         if (pTemplate->CreateFromDB(dwId))
+         {
+            NetObjInsert(pTemplate, FALSE);  // Insert into indexes
+         }
+         else     // Object load failed
+         {
+            delete pTemplate;
+            WriteLog(MSG_TEMPLATE_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
+         }
+      }
+      DBFreeResult(hResult);
+   }
+
    // Load container objects
-   hResult = DBSelect(g_hCoreDB, "SELECT id FROM containers");
+   sprintf(szQuery, "SELECT id FROM containers WHERE object_class=%d", OBJECT_CONTAINER);
+   hResult = DBSelect(g_hCoreDB, szQuery);
    if (hResult != 0)
    {
       Container *pContainer;
@@ -527,17 +562,45 @@ BOOL LoadObjects(void)
       DBFreeResult(hResult);
    }
 
-   // Link childs to container objects
+   // Load template group objects
+   sprintf(szQuery, "SELECT id FROM containers WHERE object_class=%d", OBJECT_TEMPLATEGROUP);
+   hResult = DBSelect(g_hCoreDB, szQuery);
+   if (hResult != 0)
+   {
+      TemplateGroup *pGroup;
+
+      dwNumRows = DBGetNumRows(hResult);
+      for(i = 0; i < dwNumRows; i++)
+      {
+         dwId = DBGetFieldULong(hResult, i, 0);
+         pGroup = new TemplateGroup;
+         if (pGroup->CreateFromDB(dwId))
+         {
+            NetObjInsert(pGroup, FALSE);  // Insert into indexes
+         }
+         else     // Object load failed
+         {
+            delete pGroup;
+            WriteLog(MSG_TG_LOAD_FAILED, EVENTLOG_ERROR_TYPE, "d", dwId);
+         }
+      }
+      DBFreeResult(hResult);
+   }
+
+   // Link childs to container and template group objects
    for(i = 0; i < g_dwIdIndexSize; i++)
-      if (g_pIndexById[i].pObject->Type() == OBJECT_CONTAINER)
+      if ((g_pIndexById[i].pObject->Type() == OBJECT_CONTAINER) ||
+          (g_pIndexById[i].pObject->Type() == OBJECT_TEMPLATEGROUP))
          ((Container *)g_pIndexById[i].pObject)->LinkChildObjects();
 
-   // Link childs to "All services" object
+   // Link childs to "Service Root" and "Template Root" objects
    g_pServiceRoot->LinkChildObjects();
+   g_pTemplateRoot->LinkChildObjects();
 
-   // Recalculate status for "Entire Net" and "All Services" objects
+   // Recalculate status for built-in objects
    g_pEntireNet->CalculateCompoundStatus();
    g_pServiceRoot->CalculateCompoundStatus();
+   g_pTemplateRoot->CalculateCompoundStatus();
 
    return TRUE;
 }
@@ -570,9 +633,6 @@ void DumpObjects(void)
    DWORD i;
    char *pBuffer;
    CONTAINER_CATEGORY *pCat;
-   static char *objTypes[]={ "Generic", "Subnet", "Node", "Interface",
-                             "Network", "Container", "Zone", "ServiceRoot",
-                             "Template", "TemplateGroup" };
 
    pBuffer = (char *)malloc(128000);
    MutexLock(g_hMutexIdIndex, INFINITE);
@@ -581,7 +641,7 @@ void DumpObjects(void)
       printf("Object ID %d \"%s\"\n"
              "   Class: %s  Primary IP: %s  Status: %s  IsModified: %d  IsDeleted: %d\n",
              g_pIndexById[i].pObject->Id(),g_pIndexById[i].pObject->Name(),
-             objTypes[g_pIndexById[i].pObject->Type()],
+             g_szClassName[g_pIndexById[i].pObject->Type()],
              IpToStr(g_pIndexById[i].pObject->IpAddr(), pBuffer),
              g_pszStatusName[g_pIndexById[i].pObject->Status()],
              g_pIndexById[i].pObject->IsModified(), g_pIndexById[i].pObject->IsDeleted());
@@ -611,3 +671,30 @@ void DumpObjects(void)
    MutexUnlock(g_hMutexIdIndex);
    free(pBuffer);
 }
+
+
+//
+// Check is given object class is a valid parent class for other object
+// This function is used to check manually created bindings, so i won't
+// return TRUE for node -- subnet for example
+//
+
+BOOL IsValidParentClass(int iChildClass, int iParentClass)
+{
+   switch(iParentClass)
+   {
+      case OBJECT_SERVICEROOT:
+      case OBJECT_CONTAINER:
+         if ((iChildClass == OBJECT_CONTAINER) || 
+             (iChildClass == OBJECT_NODE))
+            return TRUE;
+         break;
+      case OBJECT_TEMPLATEROOT:
+      case OBJECT_TEMPLATEGROUP:
+         if ((iChildClass == OBJECT_TEMPLATEGROUP) || 
+             (iChildClass == OBJECT_TEMPLATE))
+            return TRUE;
+         break;
+   }
+   return FALSE;
+}
similarity index 55%
copy from include/nximage.h
copy to src/server/core/rootobj.cpp
index 4ec67fa..282d464 100644 (file)
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
-** $module: nximage.h
+** $module: rootobj.cpp
 **
 **/
 
-#ifndef _nximage_h_
-#define _nximage_h_
+#include "nms_core.h"
 
 
 //
-// Default object image IDs
+// Service root class default constructor
 //
 
-#define IMG_DEFAULT                 0
-#define IMG_NETWORK                 1
-#define IMG_INTERFACE               2
-#define IMG_NODE_GENERIC            3
-#define IMG_PRINTER_GENERIC         4
-#define IMG_CONTAINER_NODE_GROUP    5
-#define IMG_SUBNET                  6
-#define IMG_SERVICE_ROOT            7
-#define IMG_CONTAINER_SERVICE       8
+ServiceRoot::ServiceRoot()
+            :UniversalRoot()
+{
+   m_dwId = 2;
+   strcpy(m_szName, "All Services");
+}
 
-#endif
+
+//
+// Service root class destructor
+//
+
+ServiceRoot::~ServiceRoot()
+{
+}
+
+
+//
+// Template root class default constructor
+//
+
+TemplateRoot::TemplateRoot()
+             :UniversalRoot()
+{
+   m_dwId = 3;
+   strcpy(m_szName, "Templates");
+}
+
+
+//
+// Template root class destructor
+//
+
+TemplateRoot::~TemplateRoot()
+{
+}
+
+
+//
+// Redefined status calculation for template root
+//
+
+void TemplateRoot::CalculateCompoundStatus(void)
+{
+   m_iStatus = STATUS_UNMANAGED;
+}
index 6a168da..f36f24e 100644 (file)
@@ -1444,12 +1444,13 @@ void ClientSession::OpenNodeDCIList(CSCPMessage *pRequest)
    pObject = FindObjectById(dwObjectId);
    if (pObject != NULL)
    {
-      if (pObject->Type() == OBJECT_NODE)
+      if ((pObject->Type() == OBJECT_NODE) ||
+          (pObject->Type() == OBJECT_TEMPLATE))
       {
          if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
          {
             // Try to lock DCI list
-            bSuccess = ((Node *)pObject)->LockDCIList(m_dwIndex);
+            bSuccess = ((Template *)pObject)->LockDCIList(m_dwIndex);
             msg.SetVariable(VID_RCC, bSuccess ? RCC_SUCCESS : RCC_COMPONENT_LOCKED);
 
             // Modify list of open nodes DCI lists
@@ -1480,7 +1481,7 @@ void ClientSession::OpenNodeDCIList(CSCPMessage *pRequest)
 
    // If DCI list was successfully locked, send it to client
    if (bSuccess)
-      ((Node *)pObject)->SendItemsToClient(this, pRequest->GetId());
+      ((Template *)pObject)->SendItemsToClient(this, pRequest->GetId());
 }
 
 
@@ -1503,14 +1504,15 @@ void ClientSession::CloseNodeDCIList(CSCPMessage *pRequest)
    pObject = FindObjectById(dwObjectId);
    if (pObject != NULL)
    {
-      if (pObject->Type() == OBJECT_NODE)
+      if ((pObject->Type() == OBJECT_NODE) ||
+          (pObject->Type() == OBJECT_TEMPLATE))
       {
          if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
          {
             BOOL bSuccess;
 
             // Try to unlock DCI list
-            bSuccess = ((Node *)pObject)->UnlockDCIList(m_dwIndex);
+            bSuccess = ((Template *)pObject)->UnlockDCIList(m_dwIndex);
             msg.SetVariable(VID_RCC, bSuccess ? RCC_SUCCESS : RCC_OUT_OF_STATE_REQUEST);
 
             // Modify list of open nodes DCI lists
@@ -1567,9 +1569,10 @@ void ClientSession::ModifyNodeDCI(CSCPMessage *pRequest)
    pObject = FindObjectById(dwObjectId);
    if (pObject != NULL)
    {
-      if (pObject->Type() == OBJECT_NODE)
+      if ((pObject->Type() == OBJECT_NODE) ||
+          (pObject->Type() == OBJECT_TEMPLATE))
       {
-         if (((Node *)pObject)->IsLockedBySession(m_dwIndex))
+         if (((Template *)pObject)->IsLockedBySession(m_dwIndex))
          {
             if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY))
             {
@@ -1584,7 +1587,7 @@ void ClientSession::ModifyNodeDCI(CSCPMessage *pRequest)
                      pItem = new DCItem(CreateUniqueId(IDG_ITEM), "no name", DS_INTERNAL, 
                                         DCI_DT_INT, 60, 30, (Node *)pObject);
                      pItem->SetStatus(ITEM_STATUS_DISABLED);
-                     if (((Node *)pObject)->AddItem(pItem))
+                     if (((Template *)pObject)->AddItem(pItem))
                      {
                         msg.SetVariable(VID_RCC, RCC_SUCCESS);
                         // Return new item id to client
@@ -1598,8 +1601,8 @@ void ClientSession::ModifyNodeDCI(CSCPMessage *pRequest)
                      break;
                   case CMD_MODIFY_NODE_DCI:
                      dwItemId = pRequest->GetVariableLong(VID_DCI_ID);
-                     bSuccess = ((Node *)pObject)->UpdateItem(dwItemId, pRequest, &dwNumMaps,
-                                                              &pdwMapIndex, &pdwMapId);
+                     bSuccess = ((Template *)pObject)->UpdateItem(dwItemId, pRequest, &dwNumMaps,
+                                                                  &pdwMapIndex, &pdwMapId);
                      if (bSuccess)
                      {
                         msg.SetVariable(VID_RCC, RCC_SUCCESS);
@@ -1623,7 +1626,7 @@ void ClientSession::ModifyNodeDCI(CSCPMessage *pRequest)
                      break;
                   case CMD_DELETE_NODE_DCI:
                      dwItemId = pRequest->GetVariableLong(VID_DCI_ID);
-                     bSuccess = ((Node *)pObject)->DeleteItem(dwItemId);
+                     bSuccess = ((Template *)pObject)->DeleteItem(dwItemId);
                      msg.SetVariable(VID_RCC, bSuccess ? RCC_SUCCESS : RCC_INVALID_DCI_ID);
                      break;
                }
@@ -1654,7 +1657,7 @@ void ClientSession::ModifyNodeDCI(CSCPMessage *pRequest)
 
 
 //
-// Copy DCI from one node to another
+// Copy DCI from one node or template to another
 //
 
 void ClientSession::CopyDCI(CSCPMessage *pRequest)
@@ -1672,16 +1675,17 @@ void ClientSession::CopyDCI(CSCPMessage *pRequest)
    if ((pSource != NULL) && (pDestination != NULL))
    {
       // Check object types
-      if ((pSource->Type() == OBJECT_NODE) && (pDestination->Type() == OBJECT_NODE))
+      if (((pSource->Type() == OBJECT_NODE) || (pSource->Type() == OBJECT_TEMPLATE)) && 
+          (pDestination->Type() == OBJECT_NODE))
       {
-         if (((Node *)pSource)->IsLockedBySession(m_dwIndex))
+         if (((Template *)pSource)->IsLockedBySession(m_dwIndex))
          {
             // Check access rights
             if ((pSource->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ)) &&
                 (pDestination->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY)))
             {
                // Attempt to lock destination's DCI list
-               if (((Node *)pDestination)->LockDCIList(m_dwIndex))
+               if (((Template *)pDestination)->LockDCIList(m_dwIndex))
                {
                   DWORD i, *pdwItemList, dwNumItems;
                   const DCItem *pSrcItem;
@@ -1696,13 +1700,13 @@ void ClientSession::CopyDCI(CSCPMessage *pRequest)
                   // Copy items
                   for(i = 0; i < dwNumItems; i++)
                   {
-                     pSrcItem = ((Node *)pSource)->GetItemById(pdwItemList[i]);
+                     pSrcItem = ((Template *)pSource)->GetItemById(pdwItemList[i]);
                      if (pSrcItem != NULL)
                      {
                         pDstItem = new DCItem(pSrcItem);
                         pDstItem->SetId(CreateUniqueId(IDG_ITEM));
                         pDstItem->SetStatus(ITEM_STATUS_ACTIVE);
-                        if (!((Node *)pDestination)->AddItem(pDstItem))
+                        if (!((Template *)pDestination)->AddItem(pDstItem))
                         {
                            delete pDstItem;
                            iErrors++;
@@ -1716,7 +1720,7 @@ void ClientSession::CopyDCI(CSCPMessage *pRequest)
 
                   // Cleanup
                   free(pdwItemList);
-                  ((Node *)pDestination)->UnlockDCIList(m_dwIndex);
+                  ((Template *)pDestination)->UnlockDCIList(m_dwIndex);
                   msg.SetVariable(VID_RCC, (iErrors == 0) ? RCC_SUCCESS : RCC_DCI_COPY_ERRORS);
                }
                else  // Destination's DCI list already locked by someone else
@@ -1863,6 +1867,10 @@ void ClientSession::GetCollectedData(CSCPMessage *pRequest)
             free(pData);
             bSuccess = TRUE;
          }
+         else
+         {
+            msg.SetVariable(VID_RCC, RCC_DB_FAILURE);
+         }
       }
       else
       {
@@ -2214,50 +2222,54 @@ void ClientSession::CreateObject(CSCPMessage *pRequest)
       // User should have create access to parent object
       if (pParent->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_CREATE))
       {
-         // Parent object should be container or service root
-         if ((pParent->Type() == OBJECT_CONTAINER) ||
-             (pParent->Type() == OBJECT_SERVICEROOT))
+         iClass = pRequest->GetVariableShort(VID_OBJECT_CLASS);
+
+         // Parent object should be of valid type
+         if (IsValidParentClass(iClass, pParent->Type()))
          {
-            iClass = pRequest->GetVariableShort(VID_OBJECT_CLASS);
             pRequest->GetVariableStr(VID_OBJECT_NAME, szObjectName, MAX_OBJECT_NAME);
             if (IsValidObjectName(szObjectName))
             {
-               if ((iClass == OBJECT_NODE) || (iClass == OBJECT_CONTAINER))
+               // Create new object
+               switch(iClass)
                {
-                  // Create new object
-                  switch(iClass)
-                  {
-                     case OBJECT_NODE:
-                        pObject = PollNewNode(pRequest->GetVariableLong(VID_IP_ADDRESS),
-                                              pRequest->GetVariableLong(VID_IP_NETMASK),
-                                              DF_DEFAULT, szObjectName);
-                        break;
-                     case OBJECT_CONTAINER:
-                        pDescription = pRequest->GetVariableStr(VID_DESCRIPTION);
-                        pObject = new Container(szObjectName, 
-                                                pRequest->GetVariableLong(VID_CATEGORY),
-                                                pDescription);
-                        safe_free(pDescription);
-                        NetObjInsert(pObject, TRUE);
-                        break;
-                  }
+                  case OBJECT_NODE:
+                     pObject = PollNewNode(pRequest->GetVariableLong(VID_IP_ADDRESS),
+                                           pRequest->GetVariableLong(VID_IP_NETMASK),
+                                           DF_DEFAULT, szObjectName);
+                     break;
+                  case OBJECT_CONTAINER:
+                     pDescription = pRequest->GetVariableStr(VID_DESCRIPTION);
+                     pObject = new Container(szObjectName, 
+                                             pRequest->GetVariableLong(VID_CATEGORY),
+                                             pDescription);
+                     safe_free(pDescription);
+                     NetObjInsert(pObject, TRUE);
+                     break;
+                  case OBJECT_TEMPLATEGROUP:
+                     pDescription = pRequest->GetVariableStr(VID_DESCRIPTION);
+                     pObject = new TemplateGroup(szObjectName, pDescription);
+                     safe_free(pDescription);
+                     NetObjInsert(pObject, TRUE);
+                     break;
+                  case OBJECT_TEMPLATE:
+                     pObject = new Template;
+                     pObject->SetName(szObjectName);
+                     NetObjInsert(pObject, TRUE);
+                     break;
+               }
 
-                  // If creation was successful do binding
-                  if (pObject != NULL)
-                  {
-                     pParent->AddChild(pObject);
-                     pObject->AddParent(pParent);
-                     msg.SetVariable(VID_RCC, RCC_SUCCESS);
-                     msg.SetVariable(VID_OBJECT_ID, pObject->Id());
-                  }
-                  else
-                  {
-                     msg.SetVariable(VID_RCC, RCC_OBJECT_CREATION_FAILED);
-                  }
+               // If creation was successful do binding
+               if (pObject != NULL)
+               {
+                  pParent->AddChild(pObject);
+                  pObject->AddParent(pParent);
+                  msg.SetVariable(VID_RCC, RCC_SUCCESS);
+                  msg.SetVariable(VID_OBJECT_ID, pObject->Id());
                }
                else
                {
-                  msg.SetVariable(VID_RCC, RCC_INCOMPATIBLE_OPERATION);
+                  msg.SetVariable(VID_RCC, RCC_OBJECT_CREATION_FAILED);
                }
             }
             else
index 9015162..aee5337 100644 (file)
@@ -67,7 +67,67 @@ void Template::DestroyItems(void)
 
 BOOL Template::CreateFromDB(DWORD dwId)
 {
-   return FALSE;
+   char szQuery[256];
+   DB_RESULT hResult;
+   DWORD i, dwNumNodes, dwNodeId;
+   NetObj *pObject;
+
+   sprintf(szQuery, "SELECT id,name,is_deleted,image_id FROM templates WHERE id=%d", dwId);
+   hResult = DBSelect(g_hCoreDB, szQuery);
+   if (hResult == NULL)
+      return FALSE;     // Query failed
+
+   if (DBGetNumRows(hResult) == 0)
+   {
+      // No object with given ID in database
+      DBFreeResult(hResult);
+      return FALSE;
+   }
+
+   m_dwId = dwId;
+   strncpy(m_szName, DBGetField(hResult, 0, 1), MAX_OBJECT_NAME);
+   m_bIsDeleted = DBGetFieldLong(hResult, 0, 2);
+   m_dwImageId = DBGetFieldULong(hResult, 0, 3);
+
+   DBFreeResult(hResult);
+
+   // Load access list
+   LoadACLFromDB();
+
+   // Load related nodes list
+   if (!m_bIsDeleted)
+   {
+      sprintf(szQuery, "SELECT node_id FROM dct_node_map WHERE template_id=%d", m_dwId);
+      hResult = DBSelect(g_hCoreDB, szQuery);
+      if (hResult != NULL)
+      {
+         dwNumNodes = DBGetNumRows(hResult);
+         for(i = 0; i < dwNumNodes; i++)
+         {
+            dwNodeId = DBGetFieldULong(hResult, i, 0);
+            pObject = FindObjectById(dwNodeId);
+            if (pObject != NULL)
+            {
+               if (pObject->Type() == OBJECT_NODE)
+               {
+                  AddChild(pObject);
+                  pObject->AddParent(this);
+               }
+               else
+               {
+                  WriteLog(MSG_DCT_MAP_NOT_NODE, EVENTLOG_ERROR_TYPE, "dd", m_dwId, dwNodeId);
+               }
+            }
+            else
+            {
+               WriteLog(MSG_INVALID_DCT_MAP, EVENTLOG_ERROR_TYPE, "dd", m_dwId, dwNodeId);
+            }
+         }
+         DBFreeResult(hResult);
+      }
+   }
+
+   return TRUE;
 }
 
 
@@ -77,7 +137,50 @@ BOOL Template::CreateFromDB(DWORD dwId)
 
 BOOL Template::SaveToDB(void)
 {
-   return FALSE;
+   char szQuery[1024];
+   DB_RESULT hResult;
+   DWORD i;
+   BOOL bNewObject = TRUE;
+
+   // Lock object's access
+   Lock();
+
+   // Check for object's existence in database
+   sprintf(szQuery, "SELECT id FROM templates WHERE id=%ld", m_dwId);
+   hResult = DBSelect(g_hCoreDB, szQuery);
+   if (hResult != 0)
+   {
+      if (DBGetNumRows(hResult) > 0)
+         bNewObject = FALSE;
+      DBFreeResult(hResult);
+   }
+
+   // Form and execute INSERT or UPDATE query
+   if (bNewObject)
+      sprintf(szQuery, "INSERT INTO templates (id,name,is_deleted,image_id) VALUES (%ld,'%s',%d,%ld)",
+              m_dwId, m_szName, m_bIsDeleted, m_dwImageId);
+   else
+      sprintf(szQuery, "UPDATE templates SET name='%s',is_deleted=%d,image_id=%ld WHERE id=%ld",
+              m_szName, m_bIsDeleted, m_dwImageId, m_dwId);
+   DBQuery(g_hCoreDB, szQuery);
+
+   // Update members list
+   sprintf(szQuery, "DELETE FROM dct_node_map WHERE template_id=%d", m_dwId);
+   DBQuery(g_hCoreDB, szQuery);
+   for(i = 0; i < m_dwChildCount; i++)
+   {
+      sprintf(szQuery, "INSERT INTO dct_node_map (template_id,node_id) VALUES (%ld,%ld)", m_dwId, m_pChildList[i]->Id());
+      DBQuery(g_hCoreDB, szQuery);
+   }
+
+   // Save access list
+   SaveACLToDB();
+
+   // Clear modifications flag and unlock object
+   m_bIsModified = FALSE;
+   Unlock();
+
+   return TRUE;
 }
 
 
@@ -95,7 +198,14 @@ BOOL Template::DeleteFromDB(void)
    {
       if (Type() == OBJECT_TEMPLATE)
       {
-         sprintf(szQuery, "DELETE FROM dct WHERE template_id=%ld", m_dwId);
+         sprintf(szQuery, "DELETE FROM templates WHERE id=%ld", m_dwId);
+         QueueSQLRequest(szQuery);
+         sprintf(szQuery, "DELETE FROM dct_node_map WHERE template_id=%ld", m_dwId);
+         QueueSQLRequest(szQuery);
+      }
+      else
+      {
+         sprintf(szQuery, "DELETE FROM dct_node_map WHERE node_id=%ld", m_dwId);
          QueueSQLRequest(szQuery);
       }
       sprintf(szQuery, "DELETE FROM items WHERE node_id=%ld", m_dwId);
@@ -333,3 +443,13 @@ const DCItem *Template::GetItemById(DWORD dwItemId)
    Unlock();
    return pItem;
 }
+
+
+//
+// Redefined status calculation for template
+//
+
+void Template::CalculateCompoundStatus(void)
+{
+   m_iStatus = STATUS_UNMANAGED;
+}
similarity index 71%
rename from src/server/core/srvroot.cpp
rename to src/server/core/uniroot.cpp
index a4602a0..53a1fb7 100644 (file)
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
-** $module: srvroot.cpp
+** $module: uniroot.cpp
 **
 **/
 
 
 
 //
-// Service root class default constructor
+// Constructor
 //
 
-ServiceRoot::ServiceRoot()
-            :NetObj()
+UniversalRoot::UniversalRoot()
+              :NetObj()
 {
-   m_dwId = 2;
-   strcpy(m_szName, "All Services");
 }
 
 
 //
-// Network class destructor
+// Destructor
 //
 
-ServiceRoot::~ServiceRoot()
+UniversalRoot::~UniversalRoot()
 {
 }
 
 
+//
+// Link child objects
+// This method is expected to be called only at startup, so we don't lock
+//
+
+void UniversalRoot::LinkChildObjects(void)
+{
+   DWORD i, dwNumChilds, dwObjectId;
+   NetObj *pObject;
+   char szQuery[256];
+   DB_RESULT hResult;
+
+   // Load child list and link objects
+   sprintf(szQuery, "SELECT object_id FROM container_members WHERE container_id=%d", m_dwId);
+   hResult = DBSelect(g_hCoreDB, szQuery);
+   if (hResult != NULL)
+   {
+      dwNumChilds = DBGetNumRows(hResult);
+      for(i = 0; i < dwNumChilds; i++)
+      {
+         dwObjectId = DBGetFieldULong(hResult, i, 0);
+         pObject = FindObjectById(dwObjectId);
+         if (pObject != NULL)
+            LinkObject(pObject);
+         else
+            WriteLog(MSG_ROOT_INVALID_CHILD_ID, EVENTLOG_WARNING_TYPE, "ds", 
+                     dwObjectId, g_szClassName[Type()]);
+      }
+      DBFreeResult(hResult);
+   }
+}
+
+
 //
 // Save object to database
 //
 
-BOOL ServiceRoot::SaveToDB(void)
+BOOL UniversalRoot::SaveToDB(void)
 {
    char szQuery[1024];
    DWORD i;
 
    Lock();
 
-   // Save name
-   ConfigWriteStr("ServiceRootObjectName", m_szName, TRUE);
-   ConfigWriteULong("ServiceRootImageId", m_dwImageId, TRUE);
+   // Save name and image
+   sprintf(szQuery, "%sObjectName", g_szClassName[Type()]);
+   ConfigWriteStr(szQuery, m_szName, TRUE);
+   sprintf(szQuery, "%sImageId", g_szClassName[Type()]);
+   ConfigWriteULong(szQuery, m_dwImageId, TRUE);
 
    // Update members list
    sprintf(szQuery, "DELETE FROM container_members WHERE container_id=%d", m_dwId);
@@ -82,43 +115,15 @@ BOOL ServiceRoot::SaveToDB(void)
 // Load properties from database
 //
 
-void ServiceRoot::LoadFromDB(void)
+void UniversalRoot::LoadFromDB(void)
 {
+   char szVarName[256];
+
    Lock();
-   ConfigReadStr("ServiceRootObjectName", m_szName, MAX_OBJECT_NAME, "All Services");
-   m_dwImageId = ConfigReadULong("ServiceRootImageId", IMG_DEFAULT);
+   sprintf(szVarName, "%sObjectName", g_szClassName[Type()]);
+   ConfigReadStr(szVarName, m_szName, MAX_OBJECT_NAME, DefaultName());
+   sprintf(szVarName, "%sImageId", g_szClassName[Type()]);
+   m_dwImageId = ConfigReadULong(szVarName, IMG_DEFAULT);
    LoadACLFromDB();
    Unlock();
 }
-
-
-//
-// Link child objects
-// This method is expected to be called only at startup, so we don't lock
-//
-
-void ServiceRoot::LinkChildObjects(void)
-{
-   DWORD i, dwNumChilds, dwObjectId;
-   NetObj *pObject;
-   char szQuery[256];
-   DB_RESULT hResult;
-
-   // Load child list and link objects
-   sprintf(szQuery, "SELECT object_id FROM container_members WHERE container_id=%d", m_dwId);
-   hResult = DBSelect(g_hCoreDB, szQuery);
-   if (hResult != NULL)
-   {
-      dwNumChilds = DBGetNumRows(hResult);
-      for(i = 0; i < dwNumChilds; i++)
-      {
-         dwObjectId = DBGetFieldULong(hResult, i, 0);
-         pObject = FindObjectById(dwObjectId);
-         if (pObject != NULL)
-            LinkObject(pObject);
-         else
-            WriteLog(MSG_SRVROOT_INVALID_CHILD_ID, EVENTLOG_WARNING_TYPE, "d", dwObjectId);
-      }
-      DBFreeResult(hResult);
-   }
-}