Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

911 lines
25 KiB

  1. // LogAdvPg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "logui.h"
  5. #include "wrapmb.h"
  6. #include <iiscnfg.h>
  7. #include <metatool.h>
  8. #include "LogAdvPg.h"
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14. //
  15. // Possible Item States
  16. //
  17. #define TVIS_GCEMPTY 0
  18. #define TVIS_GCNOCHECK 1
  19. #define TVIS_GCCHECK 2
  20. #define TVIS_GCTRINOCHECK 3
  21. #define TVIS_GCTRICHECK 4
  22. #define STATEIMAGEMASKTOINDEX(i) ((i) >> 12)
  23. static int CALLBACK LogUICompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
  24. {
  25. // lParamSort contains a pointer to the tree control
  26. CLogAdvanced::PCONFIG_INFORMATION pCnfgInfo1 = (CLogAdvanced::PCONFIG_INFORMATION) lParam1;
  27. CLogAdvanced::PCONFIG_INFORMATION pCnfgInfo2 = (CLogAdvanced::PCONFIG_INFORMATION) lParam2;
  28. CTreeCtrl* pTreeCtrl = (CTreeCtrl*) lParamSort;
  29. if (pCnfgInfo1->iOrder < pCnfgInfo2->iOrder)
  30. return(-1);
  31. else if (pCnfgInfo1->iOrder > pCnfgInfo2->iOrder)
  32. return(1);
  33. else
  34. return(0);
  35. }
  36. /////////////////////////////////////////////////////////////////////////////
  37. // CLogAdvanced property page
  38. IMPLEMENT_DYNCREATE(CLogAdvanced, CPropertyPage)
  39. CLogAdvanced::CLogAdvanced() : CPropertyPage(CLogAdvanced::IDD)
  40. {
  41. //{{AFX_DATA_INIT(CLogAdvanced)
  42. // NOTE: the ClassWizard will add member initialization here
  43. //}}AFX_DATA_INIT
  44. m_mapLogUIOrder[IDS_DATE] = 1;
  45. m_mapLogUIOrder[IDS_TIME] = 2;
  46. m_mapLogUIOrder[IDS_EXTENDED] = 3;
  47. m_mapLogUIOrder[IDS_PROCESS_ACCT] = 4;
  48. m_mapLogUIOrder[IDS_CLIENT] = 1;
  49. m_mapLogUIOrder[IDS_USER] = 2;
  50. m_mapLogUIOrder[IDS_SERVICE_NAME_T] = 3;
  51. m_mapLogUIOrder[IDS_SERVER_NAME_T] = 4;
  52. m_mapLogUIOrder[IDS_SERVER_IP] = 5;
  53. m_mapLogUIOrder[IDS_SERVER_PORT] = 6;
  54. m_mapLogUIOrder[IDS_METHOD] = 7;
  55. m_mapLogUIOrder[IDS_URI_STEM] = 8;
  56. m_mapLogUIOrder[IDS_URI_QUERY] = 9;
  57. m_mapLogUIOrder[IDS_PROTOCOL] = 10;
  58. m_mapLogUIOrder[IDS_WIN32] = 11;
  59. m_mapLogUIOrder[IDS_BYTES_SENT_T] = 12;
  60. m_mapLogUIOrder[IDS_BYTES_RECEIVED] = 13;
  61. m_mapLogUIOrder[IDS_TIME_TAKEN] = 14;
  62. m_mapLogUIOrder[IDS_PROTOCOL_VER] = 15;
  63. m_mapLogUIOrder[IDS_HOST] = 16;
  64. m_mapLogUIOrder[IDS_USER_AGENT] = 17;
  65. m_mapLogUIOrder[IDS_COOKIE_T] = 18;
  66. m_mapLogUIOrder[IDS_REFERER] = 19;
  67. m_mapLogUIOrder[IDS_PROCESS_EVENT] = 1;
  68. m_mapLogUIOrder[IDS_PROCESS_TYPE] = 2;
  69. m_mapLogUIOrder[IDS_TOTAL_USER_TIME] = 3;
  70. m_mapLogUIOrder[IDS_TOTAL_KERNEL_TIME] = 4;
  71. m_mapLogUIOrder[IDS_TOTAL_PAGE_FAULTS] = 5;
  72. m_mapLogUIOrder[IDS_TOTAL_PROCESSES] = 6;
  73. m_mapLogUIOrder[IDS_ACTIVE_PROCESSES] = 7;
  74. m_mapLogUIOrder[IDS_TOTAL_TERM_PROCS] = 8;
  75. }
  76. /////////////////////////////////////////////////////////////////////////////
  77. void CLogAdvanced::DoDataExchange(CDataExchange* pDX)
  78. {
  79. CPropertyPage::DoDataExchange(pDX);
  80. //{{AFX_DATA_MAP(CLogAdvanced)
  81. DDX_Control(pDX, IDC_PROP_TREE, m_wndTreeCtrl);
  82. //}}AFX_DATA_MAP
  83. }
  84. /////////////////////////////////////////////////////////////////////////////
  85. BEGIN_MESSAGE_MAP(CLogAdvanced, CPropertyPage)
  86. //{{AFX_MSG_MAP(CLogAdvanced)
  87. ON_NOTIFY(NM_CLICK, IDC_PROP_TREE, OnClickTree)
  88. ON_NOTIFY(TVN_KEYDOWN, IDC_PROP_TREE, OnKeydownTree)
  89. ON_WM_DESTROY()
  90. //}}AFX_MSG_MAP
  91. ON_COMMAND(ID_HELP_FINDER, DoHelp)
  92. ON_COMMAND(ID_HELP, DoHelp)
  93. ON_COMMAND(ID_CONTEXT_HELP, DoHelp)
  94. ON_COMMAND(ID_DEFAULT_HELP, DoHelp)
  95. END_MESSAGE_MAP()
  96. /////////////////////////////////////////////////////////////////////////////
  97. // CLogAdvanced message handlers
  98. BOOL CLogAdvanced::OnInitDialog()
  99. {
  100. CPropertyPage::OnInitDialog();
  101. HIMAGELIST hImage = ImageList_LoadImage(AfxGetResourceHandle(),
  102. MAKEINTRESOURCE(IDB_CHECKBOX), 16, 5, RGB(255,0,0), IMAGE_BITMAP, LR_DEFAULTCOLOR);
  103. if (hImage != NULL)
  104. {
  105. m_wndTreeCtrl.SetImageList(CImageList::FromHandle(hImage), TVSIL_STATE);
  106. }
  107. TCHAR szTemp[256];
  108. HINSTANCE hWinPtr = (HINSTANCE)GetWindowLongPtr(m_wndTreeCtrl, GWLP_HINSTANCE);
  109. // initialize ordering scheme
  110. ::LoadString(hWinPtr, IDS_DATE, szTemp, 256);
  111. m_mapLogUI[szTemp] = IDS_DATE;
  112. ::LoadString(hWinPtr, IDS_TIME, szTemp, 256);
  113. m_mapLogUI[szTemp] = IDS_TIME;
  114. ::LoadString(hWinPtr, IDS_EXTENDED, szTemp, 256);
  115. m_mapLogUI[szTemp] = IDS_EXTENDED;
  116. ::LoadString(hWinPtr, IDS_CLIENT, szTemp, 256);
  117. m_mapLogUI[szTemp] = IDS_CLIENT;
  118. ::LoadString(hWinPtr, IDS_USER, szTemp, 256);
  119. m_mapLogUI[szTemp] = IDS_USER;
  120. ::LoadString(hWinPtr, IDS_SERVICE_NAME_T, szTemp, 256);
  121. m_mapLogUI[szTemp] = IDS_SERVICE_NAME_T;
  122. ::LoadString(hWinPtr, IDS_SERVER_NAME_T, szTemp, 256);
  123. m_mapLogUI[szTemp] = IDS_SERVER_NAME_T;
  124. ::LoadString(hWinPtr, IDS_SERVER_IP, szTemp, 256);
  125. m_mapLogUI[szTemp] = IDS_SERVER_IP;
  126. ::LoadString(hWinPtr, IDS_SERVER_PORT, szTemp, 256);
  127. m_mapLogUI[szTemp] = IDS_SERVER_PORT;
  128. ::LoadString(hWinPtr, IDS_METHOD, szTemp, 256);
  129. m_mapLogUI[szTemp] = IDS_METHOD;
  130. ::LoadString(hWinPtr, IDS_URI_STEM, szTemp, 256);
  131. m_mapLogUI[szTemp] = IDS_URI_STEM;
  132. ::LoadString(hWinPtr, IDS_URI_QUERY, szTemp, 256);
  133. m_mapLogUI[szTemp] = IDS_URI_QUERY;
  134. ::LoadString(hWinPtr, IDS_PROTOCOL, szTemp, 256);
  135. m_mapLogUI[szTemp] = IDS_PROTOCOL;
  136. ::LoadString(hWinPtr, IDS_WIN32, szTemp, 256);
  137. m_mapLogUI[szTemp] = IDS_WIN32;
  138. ::LoadString(hWinPtr, IDS_BYTES_SENT_T, szTemp, 256);
  139. m_mapLogUI[szTemp] = IDS_BYTES_SENT_T;
  140. ::LoadString(hWinPtr, IDS_BYTES_RECEIVED, szTemp, 256);
  141. m_mapLogUI[szTemp] = IDS_BYTES_RECEIVED;
  142. ::LoadString(hWinPtr, IDS_TIME_TAKEN, szTemp, 256);
  143. m_mapLogUI[szTemp] = IDS_TIME_TAKEN;
  144. ::LoadString(hWinPtr, IDS_PROTOCOL_VER, szTemp, 256);
  145. m_mapLogUI[szTemp] = IDS_PROTOCOL_VER;
  146. ::LoadString(hWinPtr, IDS_HOST, szTemp, 256);
  147. m_mapLogUI[szTemp] = IDS_HOST;
  148. ::LoadString(hWinPtr, IDS_USER_AGENT, szTemp, 256);
  149. m_mapLogUI[szTemp] = IDS_USER_AGENT;
  150. ::LoadString(hWinPtr, IDS_COOKIE_T, szTemp, 256);
  151. m_mapLogUI[szTemp] = IDS_COOKIE_T;
  152. ::LoadString(hWinPtr, IDS_REFERER, szTemp, 256);
  153. m_mapLogUI[szTemp] = IDS_REFERER;
  154. ::LoadString(hWinPtr, IDS_PROCESS_ACCT, szTemp, 256);
  155. m_mapLogUI[szTemp] = IDS_PROCESS_ACCT;
  156. ::LoadString(hWinPtr, IDS_PROCESS_EVENT, szTemp, 256);
  157. m_mapLogUI[szTemp] = IDS_PROCESS_EVENT;
  158. ::LoadString(hWinPtr, IDS_PROCESS_TYPE, szTemp, 256);
  159. m_mapLogUI[szTemp] = IDS_PROCESS_TYPE;
  160. ::LoadString(hWinPtr, IDS_TOTAL_USER_TIME, szTemp, 256);
  161. m_mapLogUI[szTemp] = IDS_TOTAL_USER_TIME;
  162. ::LoadString(hWinPtr, IDS_TOTAL_KERNEL_TIME, szTemp, 256);
  163. m_mapLogUI[szTemp] = IDS_TOTAL_KERNEL_TIME;
  164. ::LoadString(hWinPtr, IDS_TOTAL_PAGE_FAULTS, szTemp, 256);
  165. m_mapLogUI[szTemp] = IDS_TOTAL_PAGE_FAULTS;
  166. ::LoadString(hWinPtr, IDS_TOTAL_PROCESSES, szTemp, 256);
  167. m_mapLogUI[szTemp] = IDS_TOTAL_PROCESSES;
  168. ::LoadString(hWinPtr, IDS_ACTIVE_PROCESSES, szTemp, 256);
  169. m_mapLogUI[szTemp] = IDS_ACTIVE_PROCESSES;
  170. ::LoadString(hWinPtr, IDS_TOTAL_TERM_PROCS, szTemp, 256);
  171. m_mapLogUI[szTemp] = IDS_TOTAL_TERM_PROCS;
  172. CreateTreeFromMB();
  173. ProcessProperties(false);
  174. //
  175. // set up the modified property list array
  176. //
  177. m_fTreeModified = false;
  178. m_cModifiedProperties = 0;
  179. int cProperties = m_wndTreeCtrl.GetCount();
  180. m_pModifiedPropIDs[0] = new DWORD[cProperties];
  181. m_pModifiedPropIDs[1] = new DWORD[cProperties];
  182. SetModified(FALSE);
  183. return TRUE;
  184. }
  185. /////////////////////////////////////////////////////////////////////////////
  186. void CLogAdvanced::OnClickTree(NMHDR* pNMHDR, LRESULT* pResult)
  187. {
  188. DWORD dwpos;
  189. TV_HITTESTINFO tvhti;
  190. HTREEITEM htiItemClicked;
  191. POINT point;
  192. //
  193. // Find out where the cursor was
  194. //
  195. dwpos = GetMessagePos();
  196. point.x = LOWORD(dwpos);
  197. point.y = HIWORD(dwpos);
  198. ::MapWindowPoints(HWND_DESKTOP, m_wndTreeCtrl.m_hWnd, &point, 1);
  199. tvhti.pt = point;
  200. htiItemClicked = m_wndTreeCtrl.HitTest(&tvhti);
  201. //
  202. // If the state image was clicked, lets get the state from the item and toggle it.
  203. //
  204. if (tvhti.flags & TVHT_ONITEMSTATEICON)
  205. {
  206. ProcessClick(htiItemClicked);
  207. }
  208. *pResult = 0;
  209. }
  210. /////////////////////////////////////////////////////////////////////////////
  211. void CLogAdvanced::OnKeydownTree(NMHDR* pNMHDR, LRESULT* pResult)
  212. {
  213. TV_KEYDOWN* pTVKeyDown = (TV_KEYDOWN*)pNMHDR;
  214. if ( 0x20 != pTVKeyDown->wVKey)
  215. {
  216. // User didn't press the space key. Continue default action
  217. *pResult = 0;
  218. return;
  219. }
  220. ProcessClick(m_wndTreeCtrl.GetSelectedItem());
  221. //
  222. // Stop any more processing
  223. //
  224. *pResult = 1;
  225. }
  226. /////////////////////////////////////////////////////////////////////////////
  227. void CLogAdvanced::ProcessClick( HTREEITEM htiItemClicked)
  228. {
  229. TV_ITEM tvi;
  230. UINT state;
  231. HTREEITEM htiChild;
  232. PCONFIG_INFORMATION pCnfg;
  233. if(htiItemClicked)
  234. {
  235. //
  236. // Flip the state of the clicked item if the item is enabled
  237. //
  238. tvi.hItem = htiItemClicked;
  239. tvi.mask = TVIF_STATE;
  240. tvi.stateMask = TVIS_STATEIMAGEMASK;
  241. m_wndTreeCtrl.GetItem(&tvi);
  242. state = STATEIMAGEMASKTOINDEX(tvi.state);
  243. pCnfg = (PCONFIG_INFORMATION)(tvi.lParam);
  244. htiChild = m_wndTreeCtrl.GetNextItem(htiItemClicked, TVGN_CHILD);
  245. if ( TVIS_GCNOCHECK == state )
  246. {
  247. tvi.state = INDEXTOSTATEIMAGEMASK (TVIS_GCCHECK) ;
  248. pCnfg->fItemModified = true;
  249. m_wndTreeCtrl.SetItem(&tvi);
  250. m_fTreeModified = true;
  251. SetModified();
  252. // Reset properties for child nodes
  253. if (htiChild)
  254. {
  255. SetSubTreeProperties(NULL, htiChild, TRUE, FALSE);
  256. }
  257. }
  258. else if ( TVIS_GCCHECK == state )
  259. {
  260. tvi.state = INDEXTOSTATEIMAGEMASK (TVIS_GCNOCHECK) ;
  261. pCnfg->fItemModified = true;
  262. m_wndTreeCtrl.SetItem(&tvi);
  263. m_fTreeModified = true;
  264. SetModified();
  265. // Reset properties for child nodes
  266. if (htiChild)
  267. {
  268. SetSubTreeProperties(NULL, htiChild, FALSE, FALSE);
  269. }
  270. }
  271. }
  272. }
  273. /////////////////////////////////////////////////////////////////////////////
  274. void CLogAdvanced::ProcessProperties(bool fSave)
  275. {
  276. CWrapMetaBase mbWrap;
  277. HTREEITEM hRoot;
  278. if ( NULL == (hRoot = m_wndTreeCtrl.GetRootItem()))
  279. {
  280. return;
  281. }
  282. // Initialize MB wrapper
  283. if ( !mbWrap.FInit(m_pMB) )
  284. {
  285. return;
  286. }
  287. if (fSave && m_fTreeModified && (mbWrap.Open(m_szMeta, METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE)))
  288. {
  289. m_cModifiedProperties = 0;
  290. SaveSubTreeProperties(mbWrap, hRoot);
  291. mbWrap.Close();
  292. //
  293. // Now we need to throw an inheritance dialog for each of these modified properties
  294. //
  295. for(int i=0; i < m_cModifiedProperties; i++)
  296. {
  297. //
  298. // Set the value and check inheritance.
  299. //
  300. SetMetaDword(m_pMB, m_szServer, m_szMeta, _T(""), m_pModifiedPropIDs[0][i],
  301. IIS_MD_UT_SERVER, m_pModifiedPropIDs[1][i], TRUE);
  302. }
  303. m_fTreeModified = false;
  304. }
  305. else if ( mbWrap.Open(m_szMeta, METADATA_PERMISSION_READ) )
  306. {
  307. SetSubTreeProperties(&mbWrap, hRoot, TRUE, TRUE);
  308. mbWrap.Close();
  309. }
  310. }
  311. /////////////////////////////////////////////////////////////////////////////
  312. void CLogAdvanced::SetSubTreeProperties(CWrapMetaBase * pMBWrap, HTREEITEM hTreeRoot,
  313. BOOL fParentState, BOOL fInitialize)
  314. {
  315. HTREEITEM hTreeChild, hTreeSibling;
  316. PCONFIG_INFORMATION pCnfg;
  317. UINT iState;
  318. DWORD dwProperty = 0;
  319. if (NULL == hTreeRoot)
  320. {
  321. return;
  322. }
  323. pCnfg = (PCONFIG_INFORMATION)(m_wndTreeCtrl.GetItemData(hTreeRoot));
  324. if ( NULL != pCnfg)
  325. {
  326. if (fInitialize)
  327. {
  328. //
  329. // Read property state from Metabase.
  330. //
  331. if (pMBWrap->GetDword(_T(""), pCnfg->dwPropertyID, IIS_MD_UT_SERVER, &dwProperty))
  332. {
  333. dwProperty &= pCnfg->dwPropertyMask;
  334. }
  335. }
  336. else
  337. {
  338. //
  339. // we are not initializing, so use the value from the tree
  340. //
  341. iState = STATEIMAGEMASKTOINDEX(m_wndTreeCtrl.GetItemState(hTreeRoot, TVIS_STATEIMAGEMASK));
  342. if ( (TVIS_GCCHECK == iState) || (TVIS_GCTRICHECK == iState))
  343. {
  344. dwProperty = TRUE;
  345. }
  346. else
  347. {
  348. dwProperty = FALSE;
  349. }
  350. }
  351. //
  352. // Choose the new state depending on parent state
  353. //
  354. if (fParentState)
  355. {
  356. iState = ( 0 == dwProperty) ? INDEXTOSTATEIMAGEMASK(TVIS_GCNOCHECK) :
  357. INDEXTOSTATEIMAGEMASK(TVIS_GCCHECK);
  358. }
  359. else
  360. {
  361. iState = ( 0 == dwProperty) ? INDEXTOSTATEIMAGEMASK(TVIS_GCTRINOCHECK) :
  362. INDEXTOSTATEIMAGEMASK(TVIS_GCTRICHECK);
  363. }
  364. m_wndTreeCtrl.SetItemState(hTreeRoot, iState, TVIS_STATEIMAGEMASK);
  365. }
  366. else
  367. {
  368. //
  369. // Tree node with no checkbox (hence no config info)
  370. //
  371. dwProperty = TRUE;
  372. m_wndTreeCtrl.SetItemState(hTreeRoot, INDEXTOSTATEIMAGEMASK(TVIS_GCEMPTY), TVIS_STATEIMAGEMASK);
  373. }
  374. //
  375. // Recurse through children and siblings
  376. //
  377. if ( NULL != (hTreeChild = m_wndTreeCtrl.GetNextItem(hTreeRoot, TVGN_CHILD)))
  378. {
  379. if ( dwProperty && fParentState)
  380. {
  381. SetSubTreeProperties(pMBWrap, hTreeChild, TRUE, fInitialize);
  382. }
  383. else
  384. {
  385. SetSubTreeProperties(pMBWrap, hTreeChild, FALSE, fInitialize);
  386. }
  387. }
  388. if ( NULL != (hTreeSibling = m_wndTreeCtrl.GetNextItem(hTreeRoot, TVGN_NEXT)))
  389. {
  390. SetSubTreeProperties(pMBWrap, hTreeSibling, fParentState, fInitialize);
  391. }
  392. }
  393. /////////////////////////////////////////////////////////////////////////////
  394. void CLogAdvanced::SaveSubTreeProperties(CWrapMetaBase& mbWrap, HTREEITEM hTreeRoot)
  395. {
  396. HTREEITEM hTreeChild, hTreeSibling;
  397. PCONFIG_INFORMATION pCnfg;
  398. if (NULL == hTreeRoot)
  399. {
  400. return;
  401. }
  402. pCnfg = (PCONFIG_INFORMATION)(m_wndTreeCtrl.GetItemData(hTreeRoot));
  403. if ((NULL != pCnfg) && ( pCnfg->fItemModified))
  404. {
  405. //
  406. // There is configuration Information. Write to Metabase.
  407. //
  408. UINT NewState = STATEIMAGEMASKTOINDEX(m_wndTreeCtrl.GetItemState(hTreeRoot, TVIS_STATEIMAGEMASK));
  409. if ( (TVIS_GCNOCHECK <= NewState) && (TVIS_GCTRICHECK >= NewState) )
  410. {
  411. //
  412. // Get the property, reset the bit mask & write it back
  413. //
  414. DWORD dwProperty = 0;
  415. //
  416. // Get modified value from array if it exists
  417. //
  418. if ( !GetModifiedFieldFromArray(pCnfg->dwPropertyID, &dwProperty))
  419. {
  420. mbWrap.GetDword(_T(""), pCnfg->dwPropertyID, IIS_MD_UT_SERVER, &dwProperty);
  421. }
  422. //
  423. // 0 the appropriate bit & then set it depending on the item state
  424. //
  425. dwProperty &= ~(pCnfg->dwPropertyMask);
  426. if ((TVIS_GCCHECK == NewState) || (TVIS_GCTRICHECK == NewState))
  427. {
  428. dwProperty |= pCnfg->dwPropertyMask;
  429. }
  430. // mbWrap.SetDword(_T(""), pCnfg->dwPropertyID, IIS_MD_UT_SERVER, dwProperty);
  431. InsertModifiedFieldInArray(pCnfg->dwPropertyID, dwProperty);
  432. }
  433. }
  434. //
  435. // Recurse through children and siblings
  436. //
  437. if ( NULL != (hTreeChild = m_wndTreeCtrl.GetNextItem(hTreeRoot, TVGN_CHILD)))
  438. {
  439. SaveSubTreeProperties(mbWrap, hTreeChild);
  440. }
  441. if( NULL != (hTreeSibling = m_wndTreeCtrl.GetNextItem(hTreeRoot, TVGN_NEXT)))
  442. {
  443. SaveSubTreeProperties(mbWrap, hTreeSibling);
  444. }
  445. }
  446. /////////////////////////////////////////////////////////////////////////////
  447. void CLogAdvanced::DeleteSubTreeConfig(HTREEITEM hTreeRoot)
  448. {
  449. HTREEITEM hTreeChild, hTreeSibling;
  450. PCONFIG_INFORMATION pCnfg;
  451. if (NULL == hTreeRoot)
  452. {
  453. return;
  454. }
  455. if ( NULL != (hTreeChild = m_wndTreeCtrl.GetNextItem(hTreeRoot, TVGN_CHILD)))
  456. {
  457. DeleteSubTreeConfig(hTreeChild);
  458. }
  459. if ( NULL != (hTreeSibling = m_wndTreeCtrl.GetNextItem(hTreeRoot, TVGN_NEXT)))
  460. {
  461. DeleteSubTreeConfig(hTreeSibling);
  462. }
  463. pCnfg = (PCONFIG_INFORMATION)(m_wndTreeCtrl.GetItemData(hTreeRoot));
  464. if (pCnfg)
  465. {
  466. delete pCnfg;
  467. }
  468. }
  469. /////////////////////////////////////////////////////////////////////////////
  470. void CLogAdvanced::CreateTreeFromMB()
  471. {
  472. TCHAR szLoggingUIPath[] = _T("/LM/Logging/Custom Logging");
  473. CWrapMetaBase mbWrap;
  474. // Initialize MB wrapper
  475. if ( !mbWrap.FInit(m_pMB) )
  476. {
  477. return;
  478. }
  479. //
  480. // open the logging UI path & create the UI tree
  481. //
  482. if ( mbWrap.Open(szLoggingUIPath, METADATA_PERMISSION_READ ) )
  483. {
  484. CreateSubTree(mbWrap, _T(""), NULL);
  485. }
  486. mbWrap.Close();
  487. m_wndTreeCtrl.EnsureVisible(m_wndTreeCtrl.GetRootItem());
  488. }
  489. /////////////////////////////////////////////////////////////////////////////
  490. void CLogAdvanced::CreateSubTree(CWrapMetaBase& mbWrap, LPTSTR szPath, HTREEITEM hTreeRoot)
  491. {
  492. int index = 0;
  493. TCHAR szChildName[256];
  494. TCHAR szLocalizedChildName[256];
  495. TCHAR szW3CHeader[256] = _T("");
  496. TCHAR szNewPath[256] = _T("");
  497. TV_ITEM tvi;
  498. TV_INSERTSTRUCT tvins;
  499. HTREEITEM hChild = NULL;
  500. PCONFIG_INFORMATION pCnfgInfo;
  501. // Prepare the item for insertion
  502. tvi.mask = TVIF_TEXT | TVIF_PARAM | TVIF_STATE;
  503. tvi.state = INDEXTOSTATEIMAGEMASK(TVIS_GCEMPTY) ;
  504. tvi.stateMask = TVIS_STATEIMAGEMASK;
  505. tvins.hParent = hTreeRoot;
  506. tvins.hInsertAfter = TVI_LAST;
  507. while( mbWrap.EnumObjects(szPath, szChildName, sizeof(szChildName), index) )
  508. {
  509. DWORD size;
  510. DWORD dwPropertyID, dwPropertyMask;
  511. //
  512. // Create the new path.
  513. //
  514. lstrcpy(szNewPath, szPath);
  515. lstrcat(szNewPath,_T("\\"));
  516. lstrcat(szNewPath, szChildName);
  517. //
  518. // Check if these properties are available to the requesting service
  519. //
  520. TCHAR szSupportedServices[256] = _T("");
  521. size = 256;
  522. if ( (! mbWrap.GetMultiSZString(szNewPath,
  523. MD_LOGCUSTOM_SERVICES_STRING,
  524. IIS_MD_UT_SERVER,
  525. szSupportedServices,
  526. sizeof(szSupportedServices))) ||
  527. (! IsPresentServiceSupported(szSupportedServices))
  528. )
  529. {
  530. //
  531. // This property is not supported by this service. Skip the node
  532. //
  533. index++;
  534. continue;
  535. }
  536. //
  537. // Copy configuration information into internal structures &
  538. // insert it into tree control for future use.
  539. //
  540. //
  541. // Don't zero out the child name. In case we are unable to retrieve the localized
  542. // name from the MetaBase, just use the name used in the path.
  543. //
  544. mbWrap.GetString(szNewPath, MD_LOGCUSTOM_PROPERTY_NAME, IIS_MD_UT_SERVER,
  545. szChildName, sizeof(szChildName), 0); // name not inheritable
  546. szW3CHeader[0] = 0;
  547. size = 256;
  548. mbWrap.GetString(szNewPath, MD_LOGCUSTOM_PROPERTY_HEADER, IIS_MD_UT_SERVER,
  549. szW3CHeader, sizeof(szChildName), 0); // header not inheritable
  550. pCnfgInfo = new CONFIG_INFORMATION;
  551. // if we fail memory alloc, then simply break the loop
  552. if (pCnfgInfo == NULL) {
  553. break;
  554. }
  555. if ( mbWrap.GetDword( szNewPath, MD_LOGCUSTOM_PROPERTY_ID, IIS_MD_UT_SERVER,
  556. &dwPropertyID) &&
  557. mbWrap.GetDword( szNewPath, MD_LOGCUSTOM_PROPERTY_MASK, IIS_MD_UT_SERVER,
  558. &dwPropertyMask)
  559. )
  560. {
  561. pCnfgInfo->dwPropertyID = dwPropertyID;
  562. pCnfgInfo->dwPropertyMask = dwPropertyMask;
  563. }
  564. else
  565. {
  566. pCnfgInfo->dwPropertyID = NULL;
  567. pCnfgInfo->dwPropertyMask = NULL;
  568. }
  569. pCnfgInfo->fItemModified = false;
  570. //
  571. // Append the W3C Header to the name and add this node to the Tree Control.
  572. //
  573. if ( 0 != szW3CHeader[0])
  574. {
  575. lstrcat(szChildName,_T(" ( ") );
  576. lstrcat(szChildName,szW3CHeader);
  577. lstrcat(szChildName,_T(" )") );
  578. }
  579. int iOrder = LocalizeUIString(szChildName, szLocalizedChildName);
  580. tvi.pszText = szLocalizedChildName;
  581. pCnfgInfo->iOrder = iOrder;
  582. tvi.lParam = (LPARAM)pCnfgInfo;
  583. tvins.item = tvi;
  584. hChild = m_wndTreeCtrl.InsertItem((LPTV_INSERTSTRUCT) &tvins);
  585. //
  586. // Enumerate children
  587. //
  588. CreateSubTree(mbWrap, szNewPath, hChild);
  589. index++;
  590. }
  591. if (0 != index)
  592. {
  593. m_wndTreeCtrl.Expand(hTreeRoot, TVE_EXPAND);
  594. }
  595. // Now sort the tree from subtree root down
  596. TVSORTCB tvs;
  597. tvs.hParent = hTreeRoot;
  598. tvs.lpfnCompare = LogUICompareProc;
  599. tvs.lParam = (LPARAM) &m_wndTreeCtrl;
  600. m_wndTreeCtrl.SortChildrenCB(&tvs);
  601. }
  602. /////////////////////////////////////////////////////////////////////////////
  603. int CLogAdvanced::LocalizeUIString(LPCTSTR szOrig, LPTSTR szLocalized)
  604. {
  605. int iStringID = m_mapLogUI[szOrig];
  606. if (iStringID < 1)
  607. {
  608. lstrcpy(szLocalized, szOrig);
  609. // need to return a number greater than the number of properties in the tree
  610. // 10000 seems reasonable
  611. return(10000);
  612. }
  613. else
  614. {
  615. ::LoadString((HINSTANCE)GetWindowLongPtr(m_wndTreeCtrl, GWLP_HINSTANCE), iStringID, szLocalized, 256);
  616. return(m_mapLogUIOrder[iStringID]);
  617. }
  618. }
  619. /////////////////////////////////////////////////////////////////////////////
  620. bool CLogAdvanced::IsPresentServiceSupported(LPTSTR szSupportedServices)
  621. {
  622. while ( szSupportedServices[0] != 0)
  623. {
  624. if ( 0 == lstrcmpi(m_szServiceName, szSupportedServices) )
  625. {
  626. return true;
  627. }
  628. szSupportedServices += lstrlen(szSupportedServices)+1;
  629. }
  630. return false;
  631. }
  632. /////////////////////////////////////////////////////////////////////////////
  633. BOOL CLogAdvanced::OnApply()
  634. {
  635. //
  636. // Save the state of the tree into the metabase
  637. //
  638. ProcessProperties(true);
  639. return CPropertyPage::OnApply();
  640. }
  641. /////////////////////////////////////////////////////////////////////////////
  642. void CLogAdvanced::DoHelp()
  643. {
  644. WinHelp( HIDD_LOGUI_EXTENDED );
  645. }
  646. /////////////////////////////////////////////////////////////////////////////
  647. void CLogAdvanced::InsertModifiedFieldInArray(DWORD dwPropID, DWORD dwPropValue)
  648. {
  649. int index;
  650. bool fFound = false;
  651. if (m_pModifiedPropIDs[0])
  652. {
  653. //
  654. // Search if this property ID pre-exists in the array
  655. //
  656. for(index = 0; index < m_cModifiedProperties; index++)
  657. {
  658. if (dwPropID == m_pModifiedPropIDs[0][index])
  659. {
  660. fFound = true;
  661. break;
  662. }
  663. }
  664. if (fFound)
  665. {
  666. m_pModifiedPropIDs[1][index] = dwPropValue;
  667. }
  668. else
  669. {
  670. m_pModifiedPropIDs[0][m_cModifiedProperties] = dwPropID;
  671. m_pModifiedPropIDs[1][m_cModifiedProperties]= dwPropValue;
  672. m_cModifiedProperties++;
  673. }
  674. }
  675. }
  676. /////////////////////////////////////////////////////////////////////////////
  677. bool CLogAdvanced::GetModifiedFieldFromArray(DWORD dwPropID, DWORD * pdwPropValue)
  678. {
  679. int index;
  680. bool fFound = false;
  681. if (m_pModifiedPropIDs[0])
  682. {
  683. //
  684. // Search if this property ID pre-exists in the array
  685. //
  686. for(index = 0; index < m_cModifiedProperties; index++)
  687. {
  688. if (dwPropID == m_pModifiedPropIDs[0][index])
  689. {
  690. fFound = true;
  691. break;
  692. }
  693. }
  694. if (fFound)
  695. {
  696. *pdwPropValue = m_pModifiedPropIDs[1][index];
  697. }
  698. }
  699. return fFound;
  700. }
  701. /////////////////////////////////////////////////////////////////////////////
  702. void CLogAdvanced::OnDestroy()
  703. {
  704. CPropertyPage::OnDestroy();
  705. //
  706. // Delete all the CONFIG_INFORMATION structures
  707. //
  708. CImageList * pImage = m_wndTreeCtrl.SetImageList(CImageList::FromHandle(NULL), TVSIL_STATE);
  709. if (pImage != NULL && pImage->m_hImageList != NULL)
  710. {
  711. ImageList_Destroy(pImage->m_hImageList);
  712. }
  713. DeleteSubTreeConfig(m_wndTreeCtrl.GetRootItem());
  714. delete [] m_pModifiedPropIDs[0];
  715. delete [] m_pModifiedPropIDs[1];
  716. }
  717. /////////////////////////////////////////////////////////////////////////////