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.

661 lines
20 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. /*++
  3. Copyright (C) Microsoft Corporation, 1997 - 1999
  4. Module Name:
  5. LoggingMethodsNode.cpp
  6. Abstract:
  7. Implementation file for the CLoggingMethodsNode class.
  8. Author:
  9. Michael A. Maguire 12/15/97
  10. Revision History:
  11. mmaguire 12/15/97 - created
  12. --*/
  13. //////////////////////////////////////////////////////////////////////////////
  14. //////////////////////////////////////////////////////////////////////////////
  15. // BEGIN INCLUDES
  16. //
  17. // standard includes:
  18. //
  19. #include "Precompiled.h"
  20. //
  21. // where we can find declaration for main class in this file:
  22. //
  23. #include "LoggingMethodsNode.h"
  24. //
  25. //
  26. // where we can find declarations needed in this file:
  27. //
  28. #include "LocalFileLoggingNode.h"
  29. #include "LogCompD.h" // this must be included before NodeWithResultChildrenList.cpp
  30. #include "LogComp.h" // this must be included before NodeWithResultChildrenList.cpp
  31. #include "NodeWithResultChildrenList.cpp" // Implementation of template class.
  32. #include "LogMacNd.h"
  33. //
  34. // END INCLUDES
  35. //////////////////////////////////////////////////////////////////////////////
  36. #define COLUMN_WIDTH__LOGGING_METHOD 150
  37. #define COLUMN_WIDTH__DESCRIPTION 300
  38. //////////////////////////////////////////////////////////////////////////////
  39. /*++
  40. CLoggingMethodsNode::CLoggingMethodsNode
  41. Constructor
  42. --*/
  43. //////////////////////////////////////////////////////////////////////////////
  44. CLoggingMethodsNode::CLoggingMethodsNode(
  45. CSnapInItem* pParentNode,
  46. bool extendRasNode
  47. )
  48. :CNodeWithResultChildrenList<CLoggingMethodsNode, CLocalFileLoggingNode, CSimpleArray<CLocalFileLoggingNode*>, CLoggingComponentData, CLoggingComponent>(pParentNode, extendRasNode?RAS_HELP_INDEX:0),
  49. m_ExtendRas(extendRasNode)
  50. {
  51. ATLTRACE(_T("# +++ CLoggingMethodsNode::CLoggingMethodsNode\n"));
  52. // Check for preconditions:
  53. // None.
  54. // Set the display name for this object
  55. TCHAR lpszName[IAS_MAX_STRING];
  56. int nLoadStringResult = LoadString( _Module.GetResourceInstance(), IDS_LOGGING_METHODS_NODE__NAME, lpszName, IAS_MAX_STRING );
  57. _ASSERT( nLoadStringResult > 0 );
  58. m_bstrDisplayName = lpszName;
  59. // In IComponentData::Initialize, we are asked to inform MMC of
  60. // the icons we would like to use for the scope pane.
  61. // Here we store an index to which of these images we
  62. // want to be used to display this node
  63. m_scopeDataItem.nImage = IDBI_NODE_LOGGING_METHODS_CLOSED;
  64. m_scopeDataItem.nOpenImage = IDBI_NODE_LOGGING_METHODS_OPEN;
  65. m_pLocalFileLoggingNode = NULL;
  66. // We create the LocalFileLoggingNode now.
  67. // Usually we don't create objects until they have become
  68. // visible (when this LoggingMethodsNode receives the MMCN_SHOW
  69. // notification).
  70. // But because of the main IAS taskpad's Configure Logging
  71. // option, we need to make sure that this node has been
  72. // created and is available in case the user clicks on
  73. // configure logging before they ever saw or clicked on this node.
  74. // It should not already exist at this point.
  75. _ASSERTE( NULL == m_pLocalFileLoggingNode );
  76. m_pLocalFileLoggingNode = new CLocalFileLoggingNode( this );
  77. _ASSERTE( NULL != m_pLocalFileLoggingNode );
  78. // ATTENTION: We did something a little unusual in
  79. // this class to solve a problem.
  80. // We want to be able to have a fixed pointer which other
  81. // parts of the snapin (e.g. the taskpad's Configure Logging command)
  82. // can use to get at the local file logging node.
  83. // So we have a member variable m_pLocalFileLoggingNode which
  84. // points to that node object. However, we wanted to re-use
  85. // the features of CResultNodeWithChildrenList,
  86. // so we added this node to the children list above.
  87. // The children list will automatically take care of deleting
  88. // any nodes added to the list, so we must be careful that if the
  89. // list of children ever deletes these nodes,
  90. // we don't still try to use m_pLocalFileLoggingNode.
  91. // The practical solution is to never allow the children
  92. // list to try to repopulate itself, which in this case
  93. // means to not enable the MMC_VERB_REFRESH for the
  94. // CLoggingMethodsNode. This is what we do.
  95. AddChildToList(m_pLocalFileLoggingNode);
  96. }
  97. //////////////////////////////////////////////////////////////////////////////
  98. /*++
  99. CLoggingMethodsNode::InitSdoPointers
  100. Call as soon as you have constructed this class and pass in it's SDO pointer.
  101. --*/
  102. //////////////////////////////////////////////////////////////////////////////
  103. HRESULT CLoggingMethodsNode::InitSdoPointers( ISdo *pSdo )
  104. {
  105. ATLTRACE(_T("# CLoggingMethodsNode::InitSdoPointers\n"));
  106. // Check for preconditions:
  107. _ASSERTE( pSdo != NULL );
  108. HRESULT hr = S_OK;
  109. // Release the old pointer if we had one.
  110. if( m_spSdo != NULL )
  111. {
  112. m_spSdo.Release();
  113. }
  114. // Save our client sdo pointer.
  115. m_spSdo = pSdo;
  116. // Give the node its Sdo -- in this case it's just our Sdo, which is the SdoServer.
  117. m_pLocalFileLoggingNode->InitSdoPointers( m_spSdo );
  118. return hr;
  119. }
  120. //////////////////////////////////////////////////////////////////////////////
  121. /*++
  122. CLoggingMethodsNode::~CLoggingMethodsNode
  123. Destructor
  124. --*/
  125. //////////////////////////////////////////////////////////////////////////////
  126. CLoggingMethodsNode::~CLoggingMethodsNode()
  127. {
  128. ATLTRACE(_T("# --- CLoggingMethodsNode::~CLoggingMethodsNode\n"));
  129. // Check for preconditions:
  130. // None.
  131. // ATTENTION: We did something a little unusual in
  132. // this class to solve a problem.
  133. // We want to be able to have a fixed pointer which other
  134. // parts of the snapin (e.g. the taskpad's Configure Logging command)
  135. // can use to get at the local file logging node.
  136. // So we have a member variable m_pLocalFileLoggingNode which
  137. // points to that node object. However, we wanted to re-use
  138. // the features of CResultNodeWithChildrenList,
  139. // so we added this node to the list of children.
  140. // The children list will automatically take care of deleting
  141. // any nodes added to the list, so we must be careful that if the
  142. // list of children ever deletes these nodes,
  143. // we don't still try to use m_pLocalFileLoggingNode.
  144. // The practical solution is to never allow the children
  145. // list to try to repopulate itself, which in this case
  146. // means to not enable the MMC_VERB_REFRESH for the
  147. // CLoggingMethodsNode. This is what we do.
  148. // So DON'T "delete m_pLocalFileLoggingNode;"
  149. }
  150. //////////////////////////////////////////////////////////////////////////////
  151. /*++
  152. CLoggingMethodsNode::GetResultPaneColInfo
  153. See CSnapinNode::GetResultPaneColInfo (which this method overrides) for detailed info.
  154. --*/
  155. //////////////////////////////////////////////////////////////////////////////
  156. OLECHAR* CLoggingMethodsNode::GetResultPaneColInfo(int nCol)
  157. {
  158. ATLTRACE(_T("# CLoggingMethodsNode::GetResultPaneColInfo\n"));
  159. // Check for preconditions:
  160. // None.
  161. if (nCol == 0 && m_bstrDisplayName != NULL)
  162. return m_bstrDisplayName;
  163. return NULL;
  164. }
  165. // This is no longer needed. We have chosen to handle images on a
  166. // per-IComponent basis. See CComponent::OnAddImages.
  167. // We keep this here because it demonstrates how IImageList::ImageListSetIcon
  168. // can be used.
  169. //////////////////////////////////////////////////////////////////////////////
  170. /*++
  171. CLoggingMethodsNode::OnAddImages
  172. See CSnapinNode::OnAddImages (which this method overrides) for detailed info.
  173. --*/
  174. //////////////////////////////////////////////////////////////////////////////
  175. //HRESULT CLoggingMethodsNode::OnAddImages( LPARAM arg
  176. // , LPARAM param
  177. // , IComponentData * pComponentData
  178. // , IComponent * pComponent
  179. // , DATA_OBJECT_TYPES type
  180. // )
  181. //{
  182. // ATLTRACE(_T("# CLoggingMethodsNode::OnAddImages\n"));
  183. //
  184. //
  185. // // Check for preconditions:
  186. // _ASSERTE( arg != NULL );
  187. //
  188. //
  189. // HRESULT hr = S_FALSE;
  190. //
  191. // // Load bitmaps associated with the result pane
  192. // // and add them to the image list
  193. // // Loads the default bitmaps generated by the wizard
  194. // // Change as needed
  195. //
  196. // // ISSUE: sburns in localsec does a trick where he combines
  197. // // scope and result pane ImageLists into one
  198. // // is this necessary?
  199. //
  200. // CComPtr<IImageList> spImageList = reinterpret_cast<IImageList*>(arg);
  201. // _ASSERTE( spImageList != NULL );
  202. //
  203. // HICON icon = LoadIcon(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDI_RESULT_NODE_LOGGING_METHOD));
  204. // if (NULL == icon)
  205. // return E_UNEXPECTED;
  206. //
  207. // // ISSUE: We use nImage = 0 here as that is what the default
  208. // // constructor of CSnapinNode does
  209. //
  210. // hr = spImageList->ImageListSetIcon( reinterpret_cast<LONG_PTR*>(icon), 0 );
  211. //
  212. // return hr;
  213. //
  214. //}
  215. //////////////////////////////////////////////////////////////////////////////
  216. /*++
  217. CLoggingMethodsNode::SetVerbs
  218. See CSnapinNode::SetVerbs (which this method overrides) for detailed info.
  219. --*/
  220. //////////////////////////////////////////////////////////////////////////////
  221. HRESULT CLoggingMethodsNode::SetVerbs( IConsoleVerb * pConsoleVerb )
  222. {
  223. ATLTRACE(_T("# CLoggingMethodsNode::SetVerbs\n"));
  224. // Check for preconditions:
  225. // None.
  226. HRESULT hr = S_OK;
  227. hr = pConsoleVerb->SetVerbState( MMC_VERB_REFRESH, ENABLED, TRUE );
  228. // CLoggingMethodsNode has no properties
  229. // hr = pConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, ENABLED, FALSE );
  230. // We don't want the user deleting or renaming this node, so we
  231. // don't set the MMC_VERB_RENAME or MMC_VERB_DELETE verbs.
  232. // By default, when a node becomes selected, these are disabled.
  233. // We want double-clicking on a collection node to show its children.
  234. // hr = pConsoleVerb->SetVerbState( MMC_VERB_OPEN, ENABLED, TRUE );
  235. // hr = pConsoleVerb->SetDefaultVerb( MMC_VERB_OPEN );
  236. return hr;
  237. }
  238. //+---------------------------------------------------------------------------
  239. //
  240. // Function: DataRefresh -- to support
  241. //
  242. // Class: CPoliciesNode
  243. //
  244. // Synopsis: Initialize the CPoliciesNode using the SDO pointers
  245. //
  246. // Arguments: ISdo* pMachineSdo - Server SDO
  247. // ISdoDictionaryOld* pDictionarySdo - Sdo Dictionary
  248. // Returns: HRESULT - how the initialization goes
  249. //
  250. // History: Created byao 2/6/98 8:03:12 PM
  251. //
  252. //+---------------------------------------------------------------------------
  253. HRESULT CLoggingMethodsNode::DataRefresh( ISdo* pSdo )
  254. {
  255. HRESULT hr = S_OK;
  256. _ASSERTE( pSdo != NULL );
  257. // Save away the interface pointers.
  258. m_spSdo.Release();
  259. m_spSdo = pSdo;
  260. hr = m_pLocalFileLoggingNode->DataRefresh(pSdo);
  261. return hr;
  262. }
  263. //////////////////////////////////////////////////////////////////////////////
  264. /*++
  265. CPoliciesNode::OnRefresh
  266. See CSnapinNode::OnRefresh (which this method overrides) for detailed info.
  267. --*/
  268. //////////////////////////////////////////////////////////////////////////////
  269. HRESULT CLoggingMethodsNode::OnRefresh(
  270. LPARAM arg
  271. , LPARAM param
  272. , IComponentData * pComponentData
  273. , IComponent * pComponent
  274. , DATA_OBJECT_TYPES type
  275. )
  276. {
  277. HRESULT hr = S_OK;
  278. CWaitCursor WC;
  279. CComPtr<IConsole> spConsole;
  280. // We need IConsole
  281. if( pComponentData != NULL )
  282. {
  283. spConsole = ((CLoggingComponentData*)pComponentData)->m_spConsole;
  284. }
  285. else
  286. {
  287. spConsole = ((CLoggingComponent*)pComponent)->m_spConsole;
  288. }
  289. _ASSERTE( spConsole != NULL );
  290. hr = BringUpPropertySheetForNode(
  291. m_pLocalFileLoggingNode
  292. , pComponentData
  293. , pComponent
  294. , spConsole
  295. );
  296. if( S_OK == hr )
  297. {
  298. // We found a property sheet already up for this node.
  299. ShowErrorDialog( NULL, IDS_ERROR_CLOSE_PROPERTY_SHEET, NULL, hr, 0, spConsole );
  300. return hr;
  301. }
  302. // reload SDO from
  303. hr = ((CLoggingMachineNode *) m_pParentNode)->DataRefresh();
  304. m_pLocalFileLoggingNode->OnPropertyChange(arg, param, pComponentData, pComponent, type);
  305. // refresh the node
  306. // hr = CNodeWithResultChildrenList< CLoggingMethodsNode, CLocalFileLoggingNode, CSimpleArray<CLocalFileLoggingNode*>, CLoggingComponentData, CLoggingComponent >::OnRefresh( arg, param, pComponentData, pComponent, type);
  307. return hr;
  308. }
  309. //////////////////////////////////////////////////////////////////////////////
  310. /*++
  311. CLoggingMethodsNode::InsertColumns
  312. See CNodeWithResultChildrenList::InsertColumns (which this method overrides)
  313. for detailed info.
  314. --*/
  315. //////////////////////////////////////////////////////////////////////////////
  316. HRESULT CLoggingMethodsNode::InsertColumns( IHeaderCtrl* pHeaderCtrl )
  317. {
  318. ATLTRACE(_T("# CLoggingMethodsNode::InsertColumns\n"));
  319. // Check for preconditions:
  320. _ASSERTE( pHeaderCtrl != NULL );
  321. HRESULT hr;
  322. int nLoadStringResult;
  323. TCHAR szLoggingMethod[IAS_MAX_STRING];
  324. TCHAR szDescription[IAS_MAX_STRING];
  325. nLoadStringResult = LoadString( _Module.GetResourceInstance(), IDS_LOGGING_METHODS_NODE__LOGGING_METHOD, szLoggingMethod, IAS_MAX_STRING );
  326. _ASSERT( nLoadStringResult > 0 );
  327. nLoadStringResult = LoadString( _Module.GetResourceInstance(), IDS_LOGGING_METHODS_NODE__DESCRIPTION, szDescription, IAS_MAX_STRING );
  328. _ASSERT( nLoadStringResult > 0 );
  329. hr = pHeaderCtrl->InsertColumn( 0, szLoggingMethod, LVCFMT_LEFT, COLUMN_WIDTH__LOGGING_METHOD );
  330. _ASSERT( S_OK == hr );
  331. hr = pHeaderCtrl->InsertColumn( 1, szDescription, LVCFMT_LEFT, COLUMN_WIDTH__DESCRIPTION );
  332. _ASSERT( S_OK == hr );
  333. return hr;
  334. }
  335. //////////////////////////////////////////////////////////////////////////////
  336. /*++
  337. CLoggingMethodsNode::PopulateResultChildrenList
  338. See CNodeWithResultChildrenList::PopulateResultChildrenList (which this method overrides)
  339. for detailed info.
  340. --*/
  341. //////////////////////////////////////////////////////////////////////////////
  342. HRESULT CLoggingMethodsNode::PopulateResultChildrenList( void )
  343. {
  344. ATLTRACE(_T("# CLoggingMethodsNode::PopulateResultChildrenList\n"));
  345. // Check for preconditions:
  346. // None.
  347. HRESULT hr = S_OK;
  348. // ISSUE: in the future, when we have more than one kind of logging
  349. // method, we should make an abstract class called
  350. // CLoggingMethodNode which CLocalFileLoggingNode derives from.
  351. // Then we can pass CLoggingMethodNode as the child class for the
  352. // template to enable us to use different types of logging method
  353. // nodes here polymorphically.
  354. // This node should already have been created in our Constructor.
  355. // See notes there for reason why we didn't leave creating
  356. // it until now.
  357. _ASSERTE( NULL != m_pLocalFileLoggingNode );
  358. return hr;
  359. }
  360. //////////////////////////////////////////////////////////////////////////////
  361. /*++
  362. CLoggingMethodsNode::GetComponentData
  363. This method returns our unique CComponentData object representing the scope
  364. pane of this snapin.
  365. It relies upon the fact that each node has a pointer to its parent,
  366. except for the root node, which instead has a member variable pointing
  367. to CComponentData.
  368. This would be a useful function to use if, for example, you need a reference
  369. to some IConsole but you weren't passed one. You can use GetComponentData
  370. and then use the IConsole pointer which is a member variable of our
  371. CComponentData object.
  372. --*/
  373. //////////////////////////////////////////////////////////////////////////////
  374. CLoggingComponentData * CLoggingMethodsNode::GetComponentData( void )
  375. {
  376. ATLTRACE(_T("# CLoggingMethodsNode::GetComponentData\n"));
  377. // Check for preconditions:
  378. _ASSERTE( m_pParentNode );
  379. return ((CLoggingMachineNode *) m_pParentNode)->GetComponentData();
  380. }
  381. //////////////////////////////////////////////////////////////////////////////
  382. /*++
  383. CLoggingMethodsNode::GetServerRoot
  384. This method returns the Server node under which this node can be found.
  385. It relies upon the fact that each node has a pointer to its parent,
  386. all the way up to the server node.
  387. This would be a useful function to use if, for example, you need a reference
  388. to some data specific to a server.
  389. --*/
  390. //////////////////////////////////////////////////////////////////////////////
  391. CLoggingMachineNode * CLoggingMethodsNode::GetServerRoot( void )
  392. {
  393. ATLTRACE(_T("# CLoggingMethodsNode::GetServerRoot\n"));
  394. // Check for preconditions:
  395. _ASSERTE( m_pParentNode != NULL );
  396. return (CLoggingMachineNode *) m_pParentNode;
  397. }
  398. //////////////////////////////////////////////////////////////////////////////
  399. /*++
  400. CLoggingMethodsNode::OnPropertyChange
  401. This is our own custom response to the MMCN_PROPERTY_CHANGE notification.
  402. MMC never actually sends this notification to our snapin with a specific lpDataObject,
  403. so it would never normally get routed to a particular node but we have arranged it
  404. so that our property pages can pass the appropriate CSnapInItem pointer as the param
  405. argument. In our CComponent::Notify override, we map the notification message to
  406. the appropriate node using the param argument.
  407. --*/
  408. //////////////////////////////////////////////////////////////////////////////
  409. HRESULT CLoggingMethodsNode::OnPropertyChange(
  410. LPARAM arg
  411. , LPARAM param
  412. , IComponentData * pComponentData
  413. , IComponent * pComponent
  414. , DATA_OBJECT_TYPES type
  415. )
  416. {
  417. ATLTRACE(_T("# CLoggingMethodsNode::OnPropertyChange\n"));
  418. // Check for preconditions:
  419. // None.
  420. return LoadCachedInfoFromSdo();
  421. }
  422. //////////////////////////////////////////////////////////////////////////////
  423. /*++
  424. CLoggingMethodsNode::LoadCachedInfoFromSdo
  425. Causes this node and its children to re-read all their cached info from
  426. the SDO's. Call if you change something and you want to make sure that
  427. the display reflects this change.
  428. --*/
  429. //////////////////////////////////////////////////////////////////////////////
  430. HRESULT CLoggingMethodsNode::LoadCachedInfoFromSdo( void )
  431. {
  432. ATLTRACE(_T("# CLoggingMethodsNode::LoadCachedInfoFromSdo\n"));
  433. // Check for preconditions:
  434. HRESULT hr;
  435. // Do it to each of its children.
  436. // At the moment, there should only ever be one child
  437. // to do this to.
  438. CLocalFileLoggingNode* pChildNode;
  439. int iSize = m_ResultChildrenList.GetSize();
  440. for (int i = 0; i < iSize; i++)
  441. {
  442. pChildNode = m_ResultChildrenList[i];
  443. _ASSERTE( pChildNode != NULL );
  444. hr = pChildNode->LoadCachedInfoFromSdo();
  445. // Ignore failed HRESULT.
  446. }
  447. return S_OK;
  448. }
  449. //////////////////////////////////////////////////////////////////////////////
  450. /*++
  451. CPoliciesNode::FillData
  452. The server node need to override CSnapInItem's implementation of this so that
  453. we can
  454. also support a clipformat for exchanging machine names with any snapins
  455. extending us.
  456. --*/
  457. //////////////////////////////////////////////////////////////////////////////
  458. STDMETHODIMP CLoggingMethodsNode::FillData(CLIPFORMAT cf, LPSTREAM pStream)
  459. {
  460. ATLTRACE(_T("# CClientsNode::FillData\n"));
  461. // Check for preconditions:
  462. // None.
  463. HRESULT hr = DV_E_CLIPFORMAT;
  464. ULONG uWritten = 0;
  465. if (cf == CF_MMC_NodeID)
  466. {
  467. ::CString SZNodeID = (LPCTSTR)GetSZNodeType();
  468. if (INTERNET_AUTHENTICATION_SERVICE_SNAPIN == GetServerRoot()->m_enumExtendedSnapin)
  469. SZNodeID += L":Ext_IAS:";
  470. SZNodeID += GetServerRoot()->m_bstrServerAddress;
  471. DWORD dwIdSize = 0;
  472. SNodeID2* NodeId = NULL;
  473. BYTE *id = NULL;
  474. DWORD textSize = (SZNodeID.GetLength()+ 1) * sizeof(TCHAR);
  475. dwIdSize = textSize + sizeof(SNodeID2);
  476. try{
  477. NodeId = (SNodeID2 *)_alloca(dwIdSize);
  478. }
  479. catch(...)
  480. {
  481. hr = E_OUTOFMEMORY;
  482. return hr;
  483. }
  484. NodeId->dwFlags = 0;
  485. NodeId->cBytes = textSize;
  486. memcpy(NodeId->id,(BYTE*)(LPCTSTR)SZNodeID, textSize);
  487. hr = pStream->Write(NodeId, dwIdSize, &uWritten);
  488. return hr;
  489. }
  490. // Call the method which we're overriding to let it handle the
  491. // rest of the possible cases as usual.
  492. return CNodeWithResultChildrenList< CLoggingMethodsNode, CLocalFileLoggingNode, CSimpleArray<CLocalFileLoggingNode*>, CLoggingComponentData, CLoggingComponent >::FillData( cf, pStream );
  493. }