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.

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