be2dd8a9058e814949940612464adc144e53ce68
[public/netxms.git] / src / console / win32 / tools.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Windows Console
4 ** Copyright (C) 2004 Victor Kirhenshtein
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2 of the License, or
9 ** (at your option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 **
20 ** $module: tools.cpp
21 ** Various tools and helper functions
22 **
23 **/
24
25 #include "stdafx.h"
26 #include "nxcon.h"
27
28 #define _GETOPT_H_ 1 /* Prevent including getopt.h from net-snmp */
29 #define HAVE_SOCKLEN_T /* Prevent defining socklen_t in net-snmp */
30 #include <net-snmp/net-snmp-config.h>
31 #include <net-snmp/mib_api.h>
32 #include <net-snmp/config_api.h>
33
34
35 //
36 // Format time stamp
37 //
38
39 char *FormatTimeStamp(DWORD dwTimeStamp, char *pszBuffer, int iType)
40 {
41 struct tm *pTime;
42 static char *pFormat[] = { "%d-%b-%Y %H:%M:%S", "%H:%M:%S" };
43
44 pTime = localtime((const time_t *)&dwTimeStamp);
45 strftime(pszBuffer, 32, pFormat[iType], pTime);
46 return pszBuffer;
47 }
48
49
50 //
51 // Get size of a window
52 //
53
54 CSize GetWindowSize(CWnd *pWnd)
55 {
56 RECT rect;
57 CSize size;
58
59 pWnd->GetWindowRect(&rect);
60 size.cx = rect.right - rect.left;
61 size.cy = rect.bottom - rect.top;
62 return size;
63 }
64
65
66 //
67 // Enable or disable dialog item
68 //
69
70 void EnableDlgItem(CDialog *pWnd, int nCtrl, BOOL bEnable)
71 {
72 CWnd *pCtrl;
73
74 pCtrl = pWnd->GetDlgItem(nCtrl);
75 if (pCtrl != NULL)
76 pCtrl->EnableWindow(bEnable);
77 }
78
79
80 //
81 // Select given item in list view
82 // Will remove selection from all currently selected items and set
83 // LVIS_SELECTED and LVIS_FOCUSED flags to specified item
84 //
85
86 void SelectListViewItem(CListCtrl *pListCtrl, int iItem)
87 {
88 int i;
89
90 i = pListCtrl->GetNextItem(-1, LVIS_SELECTED);
91 while(i != -1)
92 {
93 pListCtrl->SetItemState(i, 0, LVIS_SELECTED | LVIS_FOCUSED);
94 i = pListCtrl->GetNextItem(i, LVIS_SELECTED);
95 }
96 pListCtrl->SetItemState(iItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
97 pListCtrl->SetSelectionMark(iItem);
98 }
99
100
101 //
102 // Create SNMP MIB tree
103 //
104
105 BOOL CreateMIBTree(void)
106 {
107 char szBuffer[MAX_PATH + 32];
108
109 init_mib();
110 netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SAVE_MIB_DESCRS, TRUE);
111 strcpy(szBuffer, g_szWorkDir);
112 strcat(szBuffer, WORKDIR_MIBCACHE);
113 add_mibdir(szBuffer);
114 read_all_mibs();
115 return TRUE;
116 }
117
118
119 //
120 // Destroy previously created MIB tree
121 //
122
123 void DestroyMIBTree(void)
124 {
125 //shutdown_mib();
126 }
127
128
129 //
130 // Build full OID for MIB tree leaf
131 //
132
133 void BuildOIDString(struct tree *pNode, char *pszBuffer)
134 {
135 DWORD dwPos, dwSubIdList[MAX_OID_LEN];
136 int iBufPos = 0;
137 struct tree *pCurr;
138
139 if (!strcmp(pNode->label, "[root]"))
140 {
141 pszBuffer[0] = 0;
142 }
143 else
144 {
145 for(dwPos = 0, pCurr = pNode; pCurr != NULL; pCurr = pCurr->parent)
146 dwSubIdList[dwPos++] = pCurr->subid;
147 while(dwPos > 0)
148 {
149 sprintf(&pszBuffer[iBufPos], ".%u", dwSubIdList[--dwPos]);
150 iBufPos = strlen(pszBuffer);
151 }
152 }
153 }
154
155
156 //
157 // Build full symbolic OID for MIB tree leaf
158 //
159
160 char *BuildSymbolicOIDString(struct tree *pNode, DWORD dwInstance)
161 {
162 DWORD dwPos, dwSize;
163 char *pszBuffer, *pszSubIdList[MAX_OID_LEN];
164 int iBufPos = 0;
165 struct tree *pCurr;
166
167 if (!strcmp(pNode->label, "[root]"))
168 {
169 pszBuffer = (char *)malloc(4);
170 pszBuffer[0] = 0;
171 }
172 else
173 {
174 for(dwPos = 0, dwSize = 0, pCurr = pNode; pCurr != NULL; pCurr = pCurr->parent)
175 {
176 pszSubIdList[dwPos++] = pCurr->label;
177 dwSize += strlen(pCurr->label) + 1;
178 }
179 pszBuffer = (char *)malloc(dwSize + 16);
180 for(iBufPos = 0; dwPos > 0;)
181 {
182 iBufPos += sprintf(&pszBuffer[iBufPos], ".%s", pszSubIdList[--dwPos]);
183 }
184 sprintf(&pszBuffer[iBufPos], ".%lu", dwInstance);
185 }
186 return pszBuffer;
187 }
188
189
190 //
191 // Translate given code to text
192 //
193
194 const char *CodeToText(int iCode, CODE_TO_TEXT *pTranslator, const char *pszDefaultText)
195 {
196 int i;
197
198 for(i = 0; pTranslator[i].pszText != NULL; i++)
199 if (pTranslator[i].iCode == iCode)
200 return pTranslator[i].pszText;
201 return pszDefaultText;
202 }
203
204
205 //
206 // Translate UNIX text to MSDOS (i.e. convert LF to CR/LF)
207 //
208
209 char *TranslateUNIXText(const char *pszText)
210 {
211 int n;
212 const char *ptr;
213 char *dptr, *pDst;
214
215 // Count newline characters
216 for(ptr = pszText, n = 0; *ptr != 0; ptr++)
217 if (*ptr == '\n')
218 n++;
219
220 pDst = (char *)malloc(strlen(pszText) + n + 1);
221 for(ptr = pszText, dptr = pDst; *ptr != 0; ptr++)
222 if (*ptr == '\n')
223 {
224 *dptr++ = '\r';
225 *dptr++ = '\n';
226 }
227 else
228 {
229 *dptr++ = *ptr;
230 }
231 *dptr = 0;
232 return pDst;
233 }
234
235
236 //
237 // Load bitmap into image list
238 //
239
240 void LoadBitmapIntoList(CImageList *pImageList, UINT nIDResource, COLORREF rgbMaskColor)
241 {
242 CBitmap bmp;
243
244 bmp.LoadBitmap(nIDResource);
245 pImageList->Add(&bmp, rgbMaskColor);
246 }
247
248
249 //
250 // Find image's index in list by image id
251 //
252
253 int ImageIdToIndex(DWORD dwImageId)
254 {
255 DWORD i;
256
257 for(i = 0; i < g_pSrvImageList->dwNumImages; i++)
258 if (g_pSrvImageList->pImageList[i].dwId == dwImageId)
259 return i;
260 return -1;
261 }
262
263
264 //
265 // Create image list with object images
266 //
267
268 void CreateObjectImageList(void)
269 {
270 HICON hIcon;
271 DWORD i, dwPos;
272 char szFileName[MAX_PATH];
273
274 // Create small (16x16) image list
275 if (g_pObjectSmallImageList != NULL)
276 delete g_pObjectSmallImageList;
277 g_pObjectSmallImageList = new CImageList;
278 g_pObjectSmallImageList->Create(16, 16, ILC_COLOR24 | ILC_MASK, 16, 8);
279
280 // Create normal (32x32) image list
281 if (g_pObjectNormalImageList != NULL)
282 delete g_pObjectNormalImageList;
283 g_pObjectNormalImageList = new CImageList;
284 g_pObjectNormalImageList->Create(32, 32, ILC_COLOR24 | ILC_MASK, 16, 8);
285
286 strcpy(szFileName, g_szWorkDir);
287 strcat(szFileName, WORKDIR_IMAGECACHE);
288 strcat(szFileName, "\\");
289 dwPos = strlen(szFileName);
290
291 for(i = 0; i < g_pSrvImageList->dwNumImages; i++)
292 {
293 sprintf(&szFileName[dwPos], "%08x.ico", g_pSrvImageList->pImageList[i].dwId);
294
295 // Load and add 16x16 image
296 hIcon = (HICON)LoadImage(NULL, szFileName, IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
297 g_pObjectSmallImageList->Add(hIcon);
298 DestroyIcon(hIcon);
299
300 // Load and add 32x32 image
301 hIcon = (HICON)LoadImage(NULL, szFileName, IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
302 g_pObjectNormalImageList->Add(hIcon);
303 DestroyIcon(hIcon);
304 }
305 }
306
307
308 //
309 // Get image index for given object
310 //
311
312 int GetObjectImageIndex(NXC_OBJECT *pObject)
313 {
314 DWORD i;
315
316 // Check if object has custom image
317 if (pObject->dwImage != IMG_DEFAULT)
318 return ImageIdToIndex(pObject->dwImage);
319
320 // Find default image for class
321 for(i = 0; i < g_dwDefImgListSize; i++)
322 if (g_pDefImgList[i].dwObjectClass == (DWORD)pObject->iClass)
323 return g_pDefImgList[i].iImageIndex;
324
325 return -1;
326 }
327
328
329 //
330 // Create image list with event severity icons
331 //
332
333 CImageList *CreateEventImageList(void)
334 {
335 CImageList *pImageList;
336
337 pImageList = new CImageList;
338 pImageList->Create(16, 16, ILC_COLOR24 | ILC_MASK, 8, 8);
339 pImageList->Add(theApp.LoadIcon(IDI_SEVERITY_NORMAL));
340 pImageList->Add(theApp.LoadIcon(IDI_SEVERITY_WARNING));
341 pImageList->Add(theApp.LoadIcon(IDI_SEVERITY_MINOR));
342 pImageList->Add(theApp.LoadIcon(IDI_SEVERITY_MAJOR));
343 pImageList->Add(theApp.LoadIcon(IDI_SEVERITY_CRITICAL));
344 pImageList->Add(theApp.LoadIcon(IDI_UNKNOWN)); // For alarms
345 pImageList->Add(theApp.LoadIcon(IDI_ACK));
346 return pImageList;
347 }
348
349
350 //
351 // Find action in list by ID
352 //
353
354 NXC_ACTION *FindActionById(DWORD dwActionId)
355 {
356 DWORD i;
357
358 for(i = 0; i < g_dwNumActions; i++)
359 if (g_pActionList[i].dwId == dwActionId)
360 return &g_pActionList[i];
361 return NULL;
362 }
363
364
365 //
366 // Update action list with information received from server
367 //
368
369 void UpdateActions(DWORD dwCode, NXC_ACTION *pAction)
370 {
371 DWORD i;
372 NXC_ACTION *pCurrAction;
373
374 LockActions();
375
376 // Find action with given ID
377 pCurrAction = FindActionById(pAction->dwId);
378
379 // Update action list depending on notification code
380 switch(dwCode)
381 {
382 case NX_NOTIFY_ACTION_CREATED:
383 case NX_NOTIFY_ACTION_MODIFIED:
384 if (pCurrAction == NULL)
385 {
386 i = g_dwNumActions;
387 g_dwNumActions++;
388 g_pActionList = (NXC_ACTION *)realloc(g_pActionList, sizeof(NXC_ACTION) * g_dwNumActions);
389 memcpy(&g_pActionList[i], pAction, sizeof(NXC_ACTION));
390 g_pActionList[i].pszData = strdup(pAction->pszData);
391 }
392 else
393 {
394 // Action with given id already exist, just update it
395 safe_free(pCurrAction->pszData);
396 memcpy(pCurrAction, pAction, sizeof(NXC_ACTION));
397 pCurrAction->pszData = strdup(pAction->pszData);
398 }
399 break;
400 case NX_NOTIFY_ACTION_DELETED:
401 if (pCurrAction != NULL)
402 {
403 theApp.DebugPrintf("Deleting action %d '%s'",pAction->dwId,pCurrAction->szName);
404 for(i = 0; i < g_dwNumActions; i++)
405 if (g_pActionList[i].dwId == pAction->dwId)
406 {
407 g_dwNumActions--;
408 safe_free(g_pActionList[i].pszData);
409 memmove(&g_pActionList[i], &g_pActionList[i + 1],
410 sizeof(NXC_ACTION) * (g_dwNumActions - i));
411 break;
412 }
413 }
414 break;
415 }
416
417 UnlockActions();
418 }
419
420
421 //
422 // Restore placement of MDI child window
423 //
424
425 void RestoreMDIChildPlacement(CMDIChildWnd *pWnd, WINDOWPLACEMENT *pwp)
426 {
427 BOOL bMaximized;
428
429 bMaximized = (pwp->showCmd == SW_SHOWMAXIMIZED);
430 pwp->showCmd = SW_SHOWNORMAL;
431 pWnd->SetWindowPlacement(pwp);
432 if (bMaximized)
433 ::PostMessage(pWnd->GetParent()->m_hWnd, WM_MDIMAXIMIZE, (WPARAM)pWnd->m_hWnd, 0);
434 }