Leaked source code of windows server 2003
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.

2580 lines
105 KiB

  1. /*++
  2. Copyright (C) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. compdata.cpp
  5. Abstract:
  6. Implementation of the CComponentData class.
  7. This class is the interface to handle anything to do
  8. with the scope pane. MMC calls the IComponentData interfaces.
  9. This class keeps a few pointers to interfaces that MMC
  10. implements.
  11. --*/
  12. #include "stdafx.h"
  13. #include <shfolder.h>
  14. #include <strsafe.h>
  15. #include <pdhp.h> // For pdhi structures and methods
  16. #include "smcfgmsg.h"
  17. #include "smtprov.h"
  18. #include "smrootnd.h"
  19. #include "ipropbag.h"
  20. #include "smlogqry.h"
  21. #include "cmponent.h"
  22. #include "smcfgmsg.h"
  23. #include "newqdlg.h"
  24. #include "logwarnd.h"
  25. #include "strnoloc.h"
  26. #include "ctrsprop.h"
  27. #include "fileprop.h"
  28. #include "provprop.h"
  29. #include "schdprop.h"
  30. #include "tracprop.h"
  31. #include "AlrtGenP.h"
  32. #include "AlrtActP.h"
  33. //
  34. #include "compdata.h"
  35. USE_HANDLE_MACROS("SMLOGCFG(compdata.cpp)");
  36. GUID g_guidSystemTools = structuuidNodetypeSystemTools;
  37. extern DWORD g_dwRealTimeQuery;
  38. /////////////////////////////////////////////////////////////////////////////
  39. // CComponentData
  40. CComponentData::CComponentData()
  41. : m_bIsExtension( FALSE ),
  42. m_ipConsoleNameSpace ( NULL ),
  43. m_ipConsole ( NULL ),
  44. m_ipResultData ( NULL ),
  45. m_ipPrshtProvider ( NULL ),
  46. m_ipScopeImage ( NULL )
  47. {
  48. m_hModule = (HINSTANCE)GetModuleHandleW (_CONFIG_DLL_NAME_W_);
  49. }
  50. CComponentData::~CComponentData()
  51. {
  52. // Make sure the list is empty.
  53. ASSERT ( m_listpRootNode.IsEmpty() );
  54. ASSERT ( m_listpOrphanedRootNode.IsEmpty() );
  55. }
  56. /////////////////////////////////////////////////////////////////////////////
  57. // IComponentData methods
  58. //
  59. //---------------------------------------------------------------------------
  60. // We get here only once, when the user clicks on the snapin.
  61. //
  62. // This method should not change as we progress through further steps.
  63. // Here we get a chance to get pointer to some interfaces MMC provides.
  64. // We QueryInterface for pointers to the name space and console, which
  65. // we cache in local variables
  66. // The other task to acomplish here is the adding of a bitmap that contains
  67. // the icons to be used in the scope pane.
  68. //
  69. STDMETHODIMP
  70. CComponentData::Initialize (
  71. LPUNKNOWN pUnknown // [in] Pointer to the IConsole�s IUnknown interface
  72. )
  73. {
  74. HRESULT hr;
  75. ASSERT( NULL != pUnknown );
  76. HBITMAP hbmpSNodes16 = NULL;
  77. HBITMAP hbmpSNodes32 = NULL;
  78. BOOL bWasReleased;
  79. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  80. // LPIMAGELIST lpScopeImage;
  81. // MMC should only call ::Initialize once!
  82. ASSERT( NULL == m_ipConsoleNameSpace );
  83. // Get pointer to name space interface
  84. hr = pUnknown->QueryInterface(IID_IConsoleNameSpace, (VOID**)(&m_ipConsoleNameSpace));
  85. ASSERT( S_OK == hr );
  86. // Get pointer to console interface
  87. hr = pUnknown->QueryInterface(IID_IConsole, (VOID**)(&m_ipConsole));
  88. ASSERT( S_OK == hr );
  89. // Get pointer to property sheet provider interface
  90. hr = m_ipConsole->QueryInterface(IID_IPropertySheetProvider, (VOID**)&m_ipPrshtProvider);
  91. ASSERT( S_OK == hr );
  92. // Add the images for the scope tree
  93. hr = m_ipConsole->QueryScopeImageList(&m_ipScopeImage);
  94. ASSERT( S_OK == hr );
  95. // Load the bitmaps from the dll
  96. hbmpSNodes16 = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_NODES_16x16));
  97. ASSERT( NULL != hbmpSNodes16 );
  98. hbmpSNodes32 = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_NODES_32x32));
  99. ASSERT( NULL != hbmpSNodes32 );
  100. // Set the images
  101. hr = m_ipScopeImage->ImageListSetStrip(
  102. (LONG_PTR *)hbmpSNodes16,
  103. (LONG_PTR *)hbmpSNodes32,
  104. 0,
  105. RGB(0,255,0)
  106. );
  107. ASSERT( S_OK == hr );
  108. if ( NULL != hbmpSNodes16 ) {
  109. bWasReleased = DeleteObject( hbmpSNodes16 );
  110. ASSERT( bWasReleased );
  111. }
  112. if ( NULL != hbmpSNodes32 ) {
  113. bWasReleased = DeleteObject( hbmpSNodes32 );
  114. ASSERT( bWasReleased );
  115. }
  116. return S_OK;
  117. } // end Initialize()
  118. //---------------------------------------------------------------------------
  119. // Release interfaces and clean up objects which allocated memory
  120. //
  121. STDMETHODIMP
  122. CComponentData::Destroy()
  123. {
  124. CSmRootNode* pRootNode = NULL;
  125. POSITION Pos = m_listpRootNode.GetHeadPosition();
  126. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  127. while ( Pos != NULL) {
  128. pRootNode = m_listpRootNode.GetNext( Pos );
  129. // Close all queries and the connection to the log service.
  130. pRootNode->Destroy();
  131. delete (pRootNode);
  132. }
  133. // empty the list now that everything has been closed;
  134. m_listpRootNode.RemoveAll();
  135. Pos = m_listpOrphanedRootNode.GetHeadPosition();
  136. while ( Pos != NULL) {
  137. pRootNode = m_listpOrphanedRootNode.GetNext( Pos );
  138. // Close all queries and the connection to the log service.
  139. pRootNode->Destroy();
  140. delete (pRootNode);
  141. }
  142. // empty the list now that everything has been closed;
  143. m_listpOrphanedRootNode.RemoveAll();
  144. // Free interfaces
  145. if ( NULL != m_ipConsoleNameSpace )
  146. m_ipConsoleNameSpace->Release();
  147. if ( NULL != m_ipConsole )
  148. m_ipConsole->Release();
  149. if ( NULL != m_ipResultData )
  150. m_ipResultData->Release();
  151. if ( NULL != m_ipScopeImage )
  152. m_ipScopeImage->Release();
  153. if ( NULL != m_ipPrshtProvider)
  154. m_ipPrshtProvider->Release();
  155. return S_OK;
  156. } // end Destroy()
  157. //---------------------------------------------------------------------------
  158. // Come in here once right after Initialize. MMC wants a pointer to the
  159. // IComponent interface.
  160. //
  161. STDMETHODIMP
  162. CComponentData::CreateComponent (
  163. LPCOMPONENT* ppComponent // [out] Pointer to the location that stores
  164. ) // the newly created pointer to IComponent
  165. {
  166. HRESULT hr = E_FAIL;
  167. CComObject<CComponent>* pObject;
  168. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  169. // MMC asks us for a pointer to the IComponent interface
  170. //
  171. // For those getting up to speed with COM...
  172. // If we had implemented IUnknown with its methods QueryInterface, AddRef,
  173. // and Release in our CComponent class...
  174. // The following line would have worked
  175. //
  176. // pNewSnapin = new CComponent(this);
  177. //
  178. // In this code we will have ATL take care of IUnknown for us and create
  179. // an object in the following manner...
  180. if ( NULL == ppComponent ) {
  181. ASSERT ( FALSE );
  182. hr = E_INVALIDARG;
  183. } else {
  184. CComObject<CComponent>::CreateInstance( &pObject );
  185. if ( NULL != pObject ) {
  186. hr = pObject->SetIComponentData( this );
  187. if ( SUCCEEDED ( hr ) ) {
  188. hr = pObject->QueryInterface (
  189. IID_IComponent,
  190. reinterpret_cast<void**>(ppComponent) );
  191. } else {
  192. // SetIComponentData adds reference.
  193. pObject->Release();
  194. }
  195. }
  196. }
  197. return hr;
  198. } // end CreateComponent()
  199. //---------------------------------------------------------------------------
  200. // In this first step, we only implement EXPAND.
  201. // The expand message asks us to populate what is under our root node.
  202. // We just put one item under there.
  203. //
  204. STDMETHODIMP
  205. CComponentData::Notify (
  206. LPDATAOBJECT pDataObject, // [in] Points to the selected data object
  207. MMC_NOTIFY_TYPE event, // [in] Identifies action taken by user.
  208. LPARAM arg, // [in] Depends on the notification type
  209. LPARAM param // [in] Depends on the notification type
  210. )
  211. {
  212. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  213. HRESULT hr = S_OK;
  214. switch (event)
  215. {
  216. case MMCN_EXPAND:
  217. hr = OnExpand( pDataObject, arg, param );
  218. break;
  219. case MMCN_DELETE: // Function not implemented
  220. LOCALTRACE( L"ComponentData::Notify: MMCN_DELETE unimplemented\n" );
  221. hr = S_FALSE;
  222. break;
  223. case MMCN_RENAME: // Function not implemented
  224. LOCALTRACE( L"ComponentData::Notify: MMCN_RENAME unimplemented\n" );
  225. hr = S_FALSE; // False signifies Rename not allowed.
  226. break;
  227. case MMCN_SELECT: // Function not implemented
  228. LOCALTRACE( L"ComponentData::Notify: MMCN_SELECT unimplemented\n" );
  229. hr = S_FALSE;
  230. break;
  231. case MMCN_PROPERTY_CHANGE: // Function not implemented
  232. LOCALTRACE( L"ComponentData::Notify: MMCN_PROPERTY_CHANGE unimplemented\n" );
  233. hr = S_FALSE;
  234. break;
  235. case MMCN_REMOVE_CHILDREN: // Function not implemented
  236. hr = OnRemoveChildren( pDataObject, arg, param );
  237. break;
  238. default:
  239. LOCALTRACE( L"CComponentData::Notify: unimplemented event %x\n", event );
  240. hr = S_FALSE;
  241. break;
  242. }
  243. return hr;
  244. } // end Notify()
  245. //---------------------------------------------------------------------------
  246. // This is where MMC asks us to provide IDataObjects for every node in the
  247. // scope pane. We have to QI the object so it gets AddRef'd. The node
  248. // manager handles deleting the objects.
  249. //
  250. STDMETHODIMP
  251. CComponentData::QueryDataObject (
  252. LPARAM mmcCookie, // [in] Data object's unique identifier
  253. DATA_OBJECT_TYPES context, // [in] Data object's type
  254. LPDATAOBJECT* ppDataObject // [out] Points to the returned data object
  255. )
  256. {
  257. HRESULT hr = S_OK;
  258. CSmNode* pNode = NULL;
  259. CComObject<CDataObject>* pDataObj = NULL;
  260. CString strMessage;
  261. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  262. UNREFERENCED_PARAMETER (context);
  263. ASSERT( CCT_SCOPE == context || // Must have a context
  264. CCT_RESULT == context || // we understand
  265. CCT_SNAPIN_MANAGER == context
  266. );
  267. if ( NULL != ppDataObject
  268. && ( CCT_SCOPE == context
  269. || CCT_RESULT == context
  270. || CCT_SNAPIN_MANAGER == context ) ) {
  271. CComObject<CDataObject>::CreateInstance( &pDataObj );
  272. if( NULL == pDataObj ) { // DataObject was not created
  273. MFC_TRY
  274. strMessage.LoadString ( IDS_ERRMSG_UNABLEALLOCDATAOBJECT );
  275. ::MessageBox( NULL,
  276. (LPCWSTR)strMessage,
  277. L"CComponentData::QueryDataObject",
  278. MB_OK | MB_ICONERROR
  279. );
  280. MFC_CATCH_HR;
  281. hr = E_OUTOFMEMORY;
  282. } else {
  283. // If the passed-in mmcCookie is non-NULL, then it should be one we
  284. // created when we added a node to the scope pane.
  285. //
  286. // Otherwise the mmcCookie refers to the root folder (this snapin's
  287. // static folder in the scope pane or snapin manager).
  288. //
  289. // Init the mmCookie, context and type in the data object.
  290. if( mmcCookie ) {
  291. pNode = (CSmNode*)mmcCookie;
  292. if ( NULL != pNode->CastToRootNode() ) {
  293. pDataObj->SetData( mmcCookie, CCT_SCOPE, COOKIE_IS_ROOTNODE );
  294. } else if ( NULL != pNode->CastToCounterLogService() ) {
  295. pDataObj->SetData( mmcCookie, CCT_SCOPE, COOKIE_IS_COUNTERMAINNODE );
  296. } else if ( NULL != pNode->CastToTraceLogService() ) {
  297. pDataObj->SetData( mmcCookie, CCT_SCOPE, COOKIE_IS_TRACEMAINNODE );
  298. } else if ( NULL != pNode->CastToAlertService() ) {
  299. pDataObj->SetData( mmcCookie, CCT_SCOPE, COOKIE_IS_ALERTMAINNODE );
  300. } else {
  301. ::MessageBox( NULL,
  302. L"Bad mmcCookie",
  303. L"CComponentData::QueryDataObject",
  304. MB_OK | MB_ICONERROR
  305. );
  306. hr = E_FAIL;
  307. }
  308. } else {
  309. ASSERT( CCT_RESULT != context );
  310. // NOTE: Passed in scope might be either CCT_SNAPIN_MANAGER or CCT_SCOPE
  311. // This case occcurs when the snapin is not an extension.
  312. pDataObj->SetData( mmcCookie, CCT_SCOPE, COOKIE_IS_ROOTNODE );
  313. }
  314. if ( SUCCEEDED ( hr ) ) {
  315. hr = pDataObj->QueryInterface(
  316. IID_IDataObject,
  317. reinterpret_cast<void**>(ppDataObject) );
  318. } else {
  319. if ( NULL != pDataObj ) {
  320. delete pDataObj;
  321. }
  322. *ppDataObject = NULL;
  323. }
  324. }
  325. } else {
  326. ASSERT ( FALSE );
  327. hr = E_POINTER;
  328. }
  329. return hr;
  330. } // end QueryDataObject()
  331. //---------------------------------------------------------------------------
  332. // This is where we provide strings for nodes in the scope pane.
  333. // MMC handles the root node string.
  334. //
  335. STDMETHODIMP
  336. CComponentData::GetDisplayInfo (
  337. LPSCOPEDATAITEM pItem ) // [in, out] Points to a SCOPEDATAITEM struct
  338. {
  339. HRESULT hr = S_OK;
  340. PSMNODE pTmp = NULL;
  341. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  342. ResourceStateManager rsm;
  343. if ( NULL != pItem ) {
  344. if( pItem->mask & SDI_STR ) {
  345. // Note: Text buffer allocated for each information type, so that
  346. // the buffer pointer is persistent for a single item (line in the result pane).
  347. // Set the name of the selected node
  348. pTmp = reinterpret_cast<PSMNODE>(pItem->lParam);
  349. if ( NULL != pTmp ) {
  350. m_strDisplayInfoName = pTmp->GetDisplayName();
  351. pItem->displayname = m_strDisplayInfoName.GetBuffer( m_strDisplayInfoName.GetLength() );
  352. }
  353. }
  354. if( pItem->mask & SDI_IMAGE ) { // Looking for image
  355. pTmp = reinterpret_cast<PSMNODE>(pItem->lParam);
  356. if ( NULL != pTmp ) {
  357. if ( NULL != pTmp->CastToRootNode() ) {
  358. ASSERT((pItem->mask & (SDI_IMAGE | SDI_OPENIMAGE)) == 0);
  359. pItem->nImage = eBmpRootIcon;
  360. pItem->nOpenImage = eBmpRootIcon;
  361. hr = S_OK;
  362. } else if ( NULL != pTmp->CastToAlertService() ){
  363. pItem->nImage = eBmpAlertType;
  364. } else {
  365. pItem->nImage = eBmpLogType;
  366. }
  367. }
  368. }
  369. } else {
  370. ASSERT ( FALSE );
  371. hr = E_POINTER;
  372. }
  373. return hr;
  374. } // end GetDisplayInfo()
  375. //---------------------------------------------------------------------------
  376. //
  377. STDMETHODIMP
  378. CComponentData::CompareObjects (
  379. LPDATAOBJECT pDataObjectA, // [in] First data object to compare
  380. LPDATAOBJECT pDataObjectB ) // [in] Second data object to compare
  381. {
  382. HRESULT hr = S_OK;
  383. CDataObject *pdoA = NULL;
  384. CDataObject *pdoB = NULL;
  385. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  386. // At least one of these data objects is supposed to be ours, so one
  387. // of the extracted pointers should be non-NULL.
  388. pdoA = ExtractOwnDataObject( pDataObjectA );
  389. pdoB = ExtractOwnDataObject( pDataObjectB );
  390. ASSERT( pdoA || pdoB ); // Assert if we can't get any objects
  391. // If extraction failed for one of them, then that one is foreign and
  392. // can't be equal to the other one. (Or else ExtractOwnDataObject
  393. // returned NULL because it ran out of memory, but the most conservative
  394. // thing to do in that case is say they're not equal.)
  395. if( !pdoA || !pdoB ) {
  396. hr = S_FALSE;
  397. } else {
  398. if( pdoA->GetCookieType() != pdoB->GetCookieType() ) {
  399. // The cookie type could be COOKIE_IS_ROOTNODE or COOKIE_IS_MAINNODE
  400. // If they differ then the objects refer to different things.
  401. hr = S_FALSE;
  402. }
  403. }
  404. return hr;
  405. } // end CompareObjects()
  406. /////////////////////////////////////////////////////////////////////////////
  407. // Methods needed to support IComponentData
  408. //
  409. //---------------------------------------------------------------------------
  410. // Here is our chance to place things under the root node.
  411. //
  412. HRESULT
  413. CComponentData::OnExpand (
  414. LPDATAOBJECT pDataObject, // [in] Points to data object
  415. LPARAM arg, // [in] TRUE is we are expanding
  416. LPARAM param ) // [in] Points to the HSCOPEITEM
  417. {
  418. HRESULT hr = S_FALSE;
  419. HRESULT hrBootState= NOERROR;
  420. INT iBootState;
  421. GUID guidObjectType;
  422. CSmRootNode* pRootNode = NULL;
  423. CDataObject* pDO = NULL;
  424. SCOPEDATAITEM sdi;
  425. INT iResult;
  426. CString strTmp;
  427. CString strServerName;
  428. CString strMessage;
  429. CString strSysMessage;
  430. CString strTitle;
  431. CString strComputerName;
  432. ResourceStateManager rsm;
  433. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  434. ASSERT( NULL != m_ipConsoleNameSpace ); // Make sure we QI'ed for the interface
  435. ASSERT( NULL != pDataObject ); // Must have valid data object
  436. if ( NULL == pDataObject ) {
  437. ASSERT ( FALSE );
  438. hr = E_POINTER;
  439. } else {
  440. if( TRUE == arg ) {
  441. hr = ExtractObjectTypeGUID (pDataObject, &guidObjectType);
  442. ASSERT ( SUCCEEDED (hr) );
  443. if ( SUCCEEDED ( hr) ) {
  444. if ( IsMyComputerNodetype (guidObjectType) ) {
  445. // Is extension of Computer Management snapin
  446. hr = ExtractMachineName (
  447. pDataObject,
  448. strServerName);
  449. ASSERT ( SUCCEEDED ( hr ) );
  450. if ( SUCCEEDED (hr) ) {
  451. pRootNode = GetOrphanedRootNode ( strServerName );
  452. if ( NULL == pRootNode ) {
  453. MFC_TRY
  454. pRootNode = new CSmRootNode;
  455. MFC_CATCH_HR
  456. if ( SUCCEEDED (hr) ) {
  457. pRootNode->SetMachineName ( strServerName );
  458. }
  459. }
  460. if ( SUCCEEDED (hr) ) {
  461. //
  462. // As an extension snapin, the log nodes should be added
  463. // beneath a "Performance Logs and Alerts" node. Insert that node,
  464. // and remember it as the root of the Performance Logs and Alerts namespace.
  465. //
  466. ZeroMemory(&sdi, sizeof sdi);
  467. sdi.mask = SDI_STR |
  468. SDI_PARAM |
  469. SDI_IMAGE |
  470. SDI_OPENIMAGE | // nOpenImage is valid
  471. SDI_PARENT;
  472. sdi.relativeID = (HSCOPEITEM)param;
  473. sdi.displayname = MMC_CALLBACK;
  474. sdi.nImage = eBmpRootIcon;
  475. sdi.nOpenImage = eBmpRootIcon;
  476. sdi.lParam = reinterpret_cast<LPARAM>(pRootNode);
  477. hr = m_ipConsoleNameSpace->InsertItem( &sdi );
  478. if (SUCCEEDED(hr)) {
  479. // Make this node the the root node
  480. pRootNode->SetExpanded ( FALSE );
  481. pRootNode->SetScopeItemHandle ( (HSCOPEITEM)sdi.ID );
  482. pRootNode->SetParentScopeItemHandle( (HSCOPEITEM)param );
  483. pRootNode->SetExtension( TRUE );
  484. SetExtension( TRUE );
  485. m_listpRootNode.AddTail(pRootNode);
  486. } else {
  487. hr = E_UNEXPECTED;
  488. }
  489. } // Allocate CSmRootNode
  490. } // ExtractMachineName
  491. } else { // Not IsMyComputerNodeType
  492. pDO = ExtractOwnDataObject( pDataObject );
  493. if( NULL != pDO ) {
  494. // Make sure that what we are placing ourselves under is the root node
  495. // or the extension root node!
  496. if ( COOKIE_IS_ROOTNODE == pDO->GetCookieType() ) {
  497. pRootNode = (CSmRootNode*)pDO->GetCookie();
  498. if ( NULL == pRootNode ) {
  499. // If root node cookie is null, then the root node was created by
  500. // the snapin manager, and this is a standalone node.
  501. pRootNode = GetOrphanedRootNode ( strServerName );
  502. if ( NULL == pRootNode ) {
  503. MFC_TRY
  504. pRootNode = new CSmRootNode;
  505. MFC_CATCH_HR
  506. if ( SUCCEEDED (hr) ) {
  507. pRootNode->SetMachineName ( strServerName );
  508. }
  509. }
  510. if ( SUCCEEDED ( hr ) ) {
  511. pRootNode->SetExpanded ( FALSE );
  512. // Cache the root node handle
  513. pRootNode->SetScopeItemHandle ( (HSCOPEITEM)param );
  514. pRootNode->SetParentScopeItemHandle( NULL );
  515. pRootNode->SetExtension( FALSE );
  516. SetExtension( FALSE );
  517. // NOTE: No way to associate root node data directly with node.
  518. // Node only added once, so no need to check for duplicates.
  519. m_listpRootNode.AddTail(pRootNode);
  520. }
  521. } else {
  522. if ( m_listpRootNode.IsEmpty() ) {
  523. hr = S_FALSE;
  524. }
  525. }
  526. if ( SUCCEEDED ( hr ) && S_FALSE != hr ) {
  527. ASSERT ( NULL != pRootNode->CastToRootNode() );
  528. ASSERT ( NULL != pRootNode->GetScopeItemHandle() );
  529. ASSERT( CCT_SCOPE == pDO->GetContext() ); // Scope pane must be current context
  530. // For extensions, the root node was created in a previous call to this method.
  531. // The root was NOT expanded in that call.
  532. // For non-extensions, the root node is expanded in the same call as it is created.
  533. if ( !pRootNode->IsExpanded() ) {
  534. strServerName = pRootNode->GetMachineName();
  535. if ( !IsPreWindows2000Server( strServerName ) ) {
  536. CWaitCursor WaitCursor;
  537. DWORD dwStatus = ERROR_SUCCESS;
  538. hr = S_OK;
  539. // Open each node independently of status of last loaded node.
  540. dwStatus = ERROR_SUCCESS;
  541. if ( !pRootNode->GetCounterLogService()->IsOpen() ) {
  542. pRootNode->GetCounterLogService()->SetRootNode( pRootNode );
  543. dwStatus = pRootNode->GetCounterLogService()->Open ( strServerName );
  544. }
  545. if ( ERROR_SUCCESS == dwStatus ) {
  546. // Place node for counter logs
  547. memset( &sdi, 0, sizeof(SCOPEDATAITEM) );
  548. sdi.mask = SDI_STR | // Displayname is valid
  549. SDI_PARAM | // lParam is valid
  550. SDI_IMAGE | // nImage is valid
  551. SDI_OPENIMAGE | // nOpenImage is valid
  552. SDI_CHILDREN | // Children count (0 vs. 1) is valid.
  553. SDI_PARENT;
  554. sdi.relativeID = pRootNode->GetScopeItemHandle(); // Performance Logs and Alerts root node
  555. sdi.nImage = eBmpLogType;
  556. sdi.nOpenImage = sdi.nImage; // select icon is same as non select
  557. sdi.displayname = MMC_CALLBACK;
  558. sdi.lParam = reinterpret_cast<LPARAM>(pRootNode->GetCounterLogService()); // The cookie
  559. sdi.cChildren = 0; // No children in the scope pane.
  560. hr = m_ipConsoleNameSpace->InsertItem( &sdi );
  561. } else {
  562. hr = E_FAIL;
  563. strComputerName = strServerName;
  564. if ( strComputerName.IsEmpty() )
  565. strComputerName.LoadString ( IDS_LOCAL );
  566. if ( SMCFG_NO_READ_ACCESS == dwStatus
  567. || SMCFG_NO_INSTALL_ACCESS == dwStatus )
  568. {
  569. FormatSmLogCfgMessage (
  570. strMessage,
  571. m_hModule,
  572. dwStatus,
  573. (LPCWSTR)strComputerName);
  574. } else {
  575. FormatMessage (
  576. FORMAT_MESSAGE_FROM_SYSTEM,
  577. NULL,
  578. dwStatus,
  579. 0,
  580. strMessage.GetBufferSetLength( MAX_PATH ),
  581. MAX_PATH,
  582. NULL );
  583. strMessage.ReleaseBuffer();
  584. if ( strMessage.IsEmpty() ) {
  585. strMessage.Format ( L"0x%08lX", dwStatus );
  586. }
  587. }
  588. strTitle.LoadString ( IDS_PROJNAME );
  589. m_ipConsole->MessageBox(
  590. (LPCWSTR)strMessage,
  591. (LPCWSTR)strTitle,
  592. MB_OK | MB_ICONWARNING,
  593. &iResult
  594. );
  595. }
  596. // Open each node independently of status of last loaded node,
  597. // except in case of SMCFG_NO_READ_ACCESS or SMCFG_NO_INSTALL_ACCESS
  598. if ( SMCFG_NO_READ_ACCESS != dwStatus
  599. && SMCFG_NO_INSTALL_ACCESS != dwStatus ) {
  600. dwStatus = ERROR_SUCCESS;
  601. hr = NOERROR;
  602. if ( SUCCEEDED(hr) && !pRootNode->GetTraceLogService()->IsOpen() ) {
  603. pRootNode->GetTraceLogService()->SetRootNode( pRootNode );
  604. dwStatus = pRootNode->GetTraceLogService()->Open ( strServerName );
  605. }
  606. if ( ERROR_SUCCESS == dwStatus ) {
  607. hrBootState = NOERROR;
  608. hrBootState = pRootNode->GetTraceLogService()->GetProviders()->GetBootState ( iBootState );
  609. }
  610. if ( ERROR_SUCCESS == dwStatus
  611. && SUCCEEDED ( hrBootState )
  612. && 0 == iBootState )
  613. {
  614. // Place node for trace logs
  615. memset( &sdi, 0, sizeof(SCOPEDATAITEM) );
  616. sdi.mask = SDI_STR | // Displayname is valid
  617. SDI_PARAM | // lParam is valid
  618. SDI_IMAGE | // nImage is valid
  619. SDI_OPENIMAGE | // nOpenImage is valid
  620. SDI_CHILDREN | // Children count (0 vs. 1) is valid.
  621. SDI_PARENT;
  622. sdi.relativeID = pRootNode->GetScopeItemHandle(); // Performance Logs and Alerts root node
  623. sdi.nImage = eBmpLogType;
  624. sdi.nOpenImage = sdi.nImage; // select icon is same as non select
  625. sdi.displayname = MMC_CALLBACK;
  626. sdi.lParam = reinterpret_cast<LPARAM>(pRootNode->GetTraceLogService()); // The cookie
  627. sdi.cChildren = 0; // No children in the scope pane.
  628. hr = m_ipConsoleNameSpace->InsertItem( &sdi );
  629. } else {
  630. strComputerName = strServerName;
  631. if ( strComputerName.IsEmpty() )
  632. strComputerName.LoadString ( IDS_LOCAL );
  633. if ( SMCFG_NO_READ_ACCESS == dwStatus
  634. || SMCFG_NO_INSTALL_ACCESS == dwStatus )
  635. {
  636. hr = E_FAIL;
  637. FormatSmLogCfgMessage (
  638. strMessage,
  639. m_hModule,
  640. dwStatus,
  641. (LPCWSTR)strComputerName);
  642. } else if ( ERROR_SUCCESS != dwStatus ) {
  643. hr = E_FAIL;
  644. FormatMessage (
  645. FORMAT_MESSAGE_FROM_SYSTEM,
  646. NULL,
  647. dwStatus,
  648. 0,
  649. strMessage.GetBufferSetLength( MAX_PATH ),
  650. MAX_PATH,
  651. NULL );
  652. strMessage.ReleaseBuffer();
  653. if ( strMessage.IsEmpty() ) {
  654. strMessage.Format ( L"0x%08lX", dwStatus );
  655. }
  656. } else if ( FAILED ( hrBootState ) ) {
  657. FormatSmLogCfgMessage (
  658. strMessage,
  659. m_hModule,
  660. SMCFG_UNABLE_OPEN_TRACESVC,
  661. (LPCWSTR)strComputerName);
  662. FormatMessage (
  663. FORMAT_MESSAGE_FROM_SYSTEM,
  664. NULL,
  665. hrBootState,
  666. 0,
  667. strSysMessage.GetBufferSetLength( MAX_PATH ),
  668. MAX_PATH,
  669. NULL );
  670. strSysMessage.ReleaseBuffer();
  671. if ( strSysMessage.IsEmpty() ) {
  672. strSysMessage.Format ( L"0x%08lX", hrBootState );
  673. }
  674. strMessage += strSysMessage;
  675. } else if ( 0 != iBootState ) {
  676. FormatSmLogCfgMessage (
  677. strMessage,
  678. m_hModule,
  679. SMCFG_SAFE_BOOT_STATE,
  680. (LPCWSTR)strComputerName);
  681. }
  682. strTitle.LoadString ( IDS_PROJNAME );
  683. m_ipConsole->MessageBox(
  684. (LPCWSTR)strMessage,
  685. (LPCWSTR)strTitle,
  686. MB_OK | MB_ICONWARNING,
  687. &iResult
  688. );
  689. }
  690. }
  691. // Open each node independently of status of last loaded node,
  692. // except in case of SMCFG_NO_READ_ACCESS or SMCFG_NO_INSTALL_ACCESS
  693. if ( SMCFG_NO_READ_ACCESS != dwStatus
  694. && SMCFG_NO_INSTALL_ACCESS != dwStatus ) {
  695. dwStatus = ERROR_SUCCESS;
  696. hr = NOERROR;
  697. if ( SUCCEEDED(hr) && !pRootNode->GetAlertService()->IsOpen() ) {
  698. pRootNode->GetAlertService()->SetRootNode( pRootNode );
  699. dwStatus = pRootNode->GetAlertService()->Open ( strServerName );
  700. }
  701. if ( ERROR_SUCCESS == dwStatus ) {
  702. // Place node for alerts
  703. memset( &sdi, 0, sizeof(SCOPEDATAITEM) );
  704. sdi.mask = SDI_STR | // Displayname is valid
  705. SDI_PARAM | // lParam is valid
  706. SDI_IMAGE | // nImage is valid
  707. SDI_OPENIMAGE | // nOpenImage is valid
  708. SDI_CHILDREN | // Children count (0 vs. 1) is valid.
  709. SDI_PARENT;
  710. sdi.relativeID = pRootNode->GetScopeItemHandle(); // Performance Logs and Alerts root node
  711. sdi.nImage = eBmpAlertType;
  712. sdi.nOpenImage = sdi.nImage; // select icon is same as non select
  713. sdi.displayname = MMC_CALLBACK;
  714. sdi.lParam = reinterpret_cast<LPARAM>(pRootNode->GetAlertService()); // The cookie
  715. sdi.cChildren = 0; // No children in the scope pane.
  716. hr = m_ipConsoleNameSpace->InsertItem( &sdi );
  717. } else {
  718. hr = E_FAIL;
  719. strComputerName = strServerName;
  720. if ( strComputerName.IsEmpty() )
  721. strComputerName.LoadString ( IDS_LOCAL );
  722. if ( SMCFG_NO_READ_ACCESS == dwStatus
  723. || SMCFG_NO_INSTALL_ACCESS == dwStatus )
  724. {
  725. FormatSmLogCfgMessage (
  726. strMessage,
  727. m_hModule,
  728. dwStatus,
  729. (LPCWSTR)strComputerName);
  730. } else {
  731. FormatMessage (
  732. FORMAT_MESSAGE_FROM_SYSTEM,
  733. NULL,
  734. dwStatus,
  735. 0,
  736. strMessage.GetBufferSetLength( MAX_PATH ),
  737. MAX_PATH,
  738. NULL );
  739. strMessage.ReleaseBuffer();
  740. if ( strMessage.IsEmpty() ) {
  741. strMessage.Format ( L"0x%08lX", dwStatus );
  742. }
  743. }
  744. strTitle.LoadString ( IDS_PROJNAME );
  745. m_ipConsole->MessageBox(
  746. (LPCWSTR)strMessage,
  747. (LPCWSTR)strTitle,
  748. MB_OK | MB_ICONWARNING,
  749. &iResult
  750. );
  751. }
  752. }
  753. if ( SMCFG_NO_READ_ACCESS != dwStatus
  754. && SMCFG_NO_INSTALL_ACCESS != dwStatus ) {
  755. pRootNode->SetExpanded( TRUE );
  756. hr = ProcessCommandLine( strServerName );
  757. }
  758. } else { // NT4 system or earlier
  759. strComputerName = strServerName;
  760. if ( strComputerName.IsEmpty() ) {
  761. strComputerName.LoadString ( IDS_LOCAL );
  762. }
  763. strMessage.Format ( IDS_ERRMSG_PREWIN2000, strComputerName );
  764. strTitle.LoadString ( IDS_PROJNAME );
  765. m_ipConsole->MessageBox(
  766. (LPCWSTR)strMessage,
  767. (LPCWSTR)strTitle,
  768. MB_OK | MB_ICONWARNING,
  769. &iResult
  770. );
  771. }
  772. }
  773. } // Insert other scope nodes
  774. } // COOKIE_IS_ROOTNODE
  775. } else {
  776. // Unknown data object
  777. strMessage.LoadString ( IDS_ERRMSG_UNKDATAOBJ );
  778. m_ipConsole->MessageBox(
  779. (LPCWSTR)strMessage,
  780. L"CComponentData::OnExpand",
  781. MB_OK | MB_ICONERROR,
  782. &iResult
  783. );
  784. hr = E_UNEXPECTED;
  785. } // ExtractOwnDataObject
  786. } // IsMyComputerNodeType
  787. } // ExtractObjectTypeGUID
  788. } else { // FALSE == arg
  789. hr = S_FALSE;
  790. }
  791. } // Parameters are valid
  792. return hr;
  793. } // end OnExpand()
  794. //---------------------------------------------------------------------------
  795. // Remove and delete all children under the specified node.
  796. //
  797. HRESULT
  798. CComponentData::OnRemoveChildren (
  799. LPDATAOBJECT pDataObject, // [in] Points to data object of node whose children are to be deleted.
  800. LPARAM arg, // [in] HSCOPEITEM of node whose children are to be deleted;
  801. LPARAM /* param */ // [in] Not used
  802. )
  803. {
  804. HRESULT hr = S_FALSE;
  805. HRESULT hrLocal;
  806. CSmRootNode* pRootNode = NULL;
  807. CSmRootNode* pTestNode;
  808. POSITION Pos;
  809. HSCOPEITEM hParent = (HSCOPEITEM)arg;
  810. LPRESULTDATA pResultData;
  811. CDataObject* pDO = NULL;
  812. ASSERT ( !m_listpRootNode.IsEmpty() );
  813. if ( NULL == pDataObject ) {
  814. hr = E_POINTER;
  815. } else {
  816. // Multiple root nodes can exist if multiple smlogcfg snapins are loaded into
  817. // a single console.
  818. // If the user selects "Create Window From Here", a second view is created on the same
  819. // (root or other) node.
  820. Pos = m_listpRootNode.GetHeadPosition();
  821. while ( NULL != Pos ) {
  822. pTestNode = m_listpRootNode.GetNext( Pos );
  823. // For standalone, the root node's parent handle is NULL.
  824. if ( hParent == pTestNode->GetScopeItemHandle()
  825. || ( hParent == pTestNode->GetParentScopeItemHandle()
  826. && pTestNode->IsExtension() ) ) {
  827. pRootNode = pTestNode;
  828. break;
  829. }
  830. }
  831. // Optimization - If root node, remove all of the result items here.
  832. if ( pRootNode ) {
  833. pResultData = GetResultData ();
  834. ASSERT (pResultData);
  835. if ( pResultData ) {
  836. hrLocal = pResultData->DeleteAllRsltItems ();
  837. }
  838. }
  839. // For standalone, we didn't create the root node view, so don't delete it.
  840. // For extension, the parent of the root node is passed so the root node gets deleted.
  841. hrLocal = m_ipConsoleNameSpace->DeleteItem ( hParent, FALSE );
  842. if ( pRootNode ) {
  843. // Remove the root node from its list and add it to the list
  844. // of orphaned root nodes.
  845. // All queries are left open, and the connection to the log service
  846. // remains.
  847. m_listpRootNode.RemoveAt( m_listpRootNode.Find ( pRootNode ) );
  848. // Service should attempt to refresh query data when loaded
  849. // into the result pane
  850. pRootNode->GetCounterLogService()->SetRefreshOnShow ( TRUE );
  851. pRootNode->GetTraceLogService()->SetRefreshOnShow ( TRUE );
  852. pRootNode->GetAlertService()->SetRefreshOnShow ( TRUE );
  853. m_listpOrphanedRootNode.AddHead ( pRootNode );
  854. hr = S_OK;
  855. } else {
  856. // Close all queries and the connection to the log service for this service type.
  857. // Orphan mechanism applies to Root node only.
  858. pDO = ExtractOwnDataObject( pDataObject );
  859. if ( NULL != pDO ) {
  860. if ( NULL != pDO->GetCookie() ) {
  861. if ( COOKIE_IS_COUNTERMAINNODE == pDO->GetCookieType() ) {
  862. CSmCounterLogService* pService = (CSmCounterLogService*)pDO->GetCookie();
  863. pService->Close();
  864. } else if ( COOKIE_IS_TRACEMAINNODE == pDO->GetCookieType() ) {
  865. CSmTraceLogService* pService = (CSmTraceLogService*)pDO->GetCookie();
  866. pService->Close();
  867. } else if ( COOKIE_IS_ALERTMAINNODE == pDO->GetCookieType() ) {
  868. CSmAlertService* pService = (CSmAlertService*)pDO->GetCookie();
  869. pService->Close();
  870. } else {
  871. ASSERT ( FALSE );
  872. }
  873. }
  874. } else {
  875. hr = E_UNEXPECTED;
  876. }
  877. }
  878. }
  879. return hr;
  880. }
  881. BOOL CComponentData::IsMyComputerNodetype (GUID& refguid)
  882. {
  883. return (::IsEqualGUID (refguid, g_guidSystemTools));
  884. }
  885. BOOL
  886. CComponentData::IsScopeNode
  887. (
  888. MMC_COOKIE mmcCookie
  889. )
  890. {
  891. BOOL bIsScopeNode = FALSE;
  892. CSmRootNode* pRootNode = NULL;
  893. POSITION Pos = m_listpRootNode.GetHeadPosition();
  894. while ( Pos != NULL) {
  895. pRootNode = m_listpRootNode.GetNext( Pos );
  896. if ( mmcCookie == (MMC_COOKIE)pRootNode ) {
  897. bIsScopeNode = TRUE;
  898. break;
  899. }
  900. if ( !bIsScopeNode ) {
  901. bIsScopeNode = IsLogService ( mmcCookie );
  902. }
  903. }
  904. return bIsScopeNode;
  905. }
  906. BOOL
  907. CComponentData::IsLogService (
  908. MMC_COOKIE mmcCookie )
  909. {
  910. CSmRootNode* pRootNode = NULL;
  911. POSITION Pos = m_listpRootNode.GetHeadPosition();
  912. BOOL bReturn = FALSE;
  913. while ( Pos != NULL) {
  914. pRootNode = m_listpRootNode.GetNext( Pos );
  915. bReturn = pRootNode->IsLogService( mmcCookie );
  916. if ( bReturn )
  917. break;
  918. }
  919. return bReturn;
  920. }
  921. BOOL
  922. CComponentData::IsAlertService ( MMC_COOKIE mmcCookie)
  923. {
  924. CSmRootNode* pRootNode = NULL;
  925. POSITION Pos = m_listpRootNode.GetHeadPosition();
  926. BOOL bReturn = FALSE;
  927. while ( Pos != NULL) {
  928. pRootNode = m_listpRootNode.GetNext( Pos );
  929. bReturn = pRootNode->IsAlertService( mmcCookie );
  930. if ( bReturn )
  931. break;
  932. }
  933. return bReturn;
  934. }
  935. BOOL
  936. CComponentData::IsLogQuery (
  937. MMC_COOKIE mmcCookie )
  938. {
  939. CSmRootNode* pRootNode = NULL;
  940. POSITION Pos = m_listpRootNode.GetHeadPosition();
  941. BOOL bReturn = FALSE;
  942. while ( Pos != NULL ) {
  943. pRootNode = m_listpRootNode.GetNext ( Pos );
  944. bReturn = pRootNode->IsLogQuery ( mmcCookie );
  945. if ( bReturn )
  946. break;
  947. }
  948. return bReturn;
  949. }
  950. BOOL
  951. CComponentData::IsRunningQuery (
  952. PSLQUERY pQuery )
  953. {
  954. return pQuery->IsRunning();
  955. }
  956. ///////////////////////////////////////////////////////////////////////////////
  957. /// IExtendPropertySheet
  958. STDMETHODIMP
  959. CComponentData::QueryPagesFor ( LPDATAOBJECT pDataObject )
  960. {
  961. HRESULT hr = S_FALSE;
  962. CDataObject *pDO = NULL;
  963. if (NULL == pDataObject) {
  964. ASSERT(FALSE);
  965. hr = E_POINTER;
  966. } else {
  967. pDO = ExtractOwnDataObject( pDataObject );
  968. if ( NULL == pDO ) {
  969. ASSERT(FALSE);
  970. hr = E_UNEXPECTED;
  971. } else {
  972. if ( NULL != pDO->GetCookie() ) {
  973. hr = m_ipPrshtProvider->FindPropertySheet((MMC_COOKIE)pDO->GetCookie(), NULL, pDataObject);
  974. } else {
  975. hr = S_FALSE;
  976. }
  977. }
  978. }
  979. return hr;
  980. } // CComponentData::QueryPagesFor()
  981. //---------------------------------------------------------------------------
  982. // Implement some context menu items
  983. //
  984. STDMETHODIMP
  985. CComponentData::AddMenuItems (
  986. LPDATAOBJECT pDataObject, // [in] Points to data object
  987. LPCONTEXTMENUCALLBACK pCallbackUnknown, // [in] Points to callback function
  988. long* pInsertionAllowed ) // [in,out] Insertion flags
  989. {
  990. HRESULT hr = S_OK;
  991. BOOL bIsLogSvc = FALSE;
  992. CDataObject* pDO = NULL;
  993. PSLSVC pLogService;
  994. static CONTEXTMENUITEM ctxMenu[1];
  995. CString strTemp1, strTemp2, strTemp3, strTemp4;
  996. ResourceStateManager rsm;
  997. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  998. if ( NULL == pDataObject ) {
  999. ASSERT ( FALSE );
  1000. hr = E_POINTER;
  1001. } else if ( NULL == pCallbackUnknown ) {
  1002. ASSERT ( FALSE );
  1003. hr = E_POINTER;
  1004. } else {
  1005. pDO = ExtractOwnDataObject( pDataObject );
  1006. if ( NULL == pDO ) {
  1007. ASSERT ( FALSE );
  1008. hr = E_UNEXPECTED;
  1009. }
  1010. }
  1011. // Only add menu items when we are allowed to.
  1012. if ( SUCCEEDED ( hr ) ) {
  1013. if ( ( COOKIE_IS_COUNTERMAINNODE == pDO->GetCookieType() )
  1014. || ( COOKIE_IS_TRACEMAINNODE == pDO->GetCookieType() )
  1015. || ( COOKIE_IS_ALERTMAINNODE == pDO->GetCookieType() ) )
  1016. {
  1017. if( CCM_INSERTIONALLOWED_NEW & *pInsertionAllowed ) {
  1018. // Add "New Query..." context menu item
  1019. bIsLogSvc = IsLogService ( pDO->GetCookie() );
  1020. if (bIsLogSvc) {
  1021. pLogService = (PSLSVC)pDO->GetCookie();
  1022. ZeroMemory ( &ctxMenu, sizeof ctxMenu );
  1023. MFC_TRY
  1024. if ( NULL != pLogService->CastToCounterLogService() ) {
  1025. strTemp1.LoadString( IDS_MMC_MENU_NEW_PERF_LOG );
  1026. strTemp2.LoadString( IDS_MMC_STATUS_NEW_PERF_LOG );
  1027. strTemp3.LoadString( IDS_MMC_MENU_PERF_LOG_FROM );
  1028. strTemp4.LoadString( IDS_MMC_STATUS_PERF_LOG_FROM );
  1029. } else if ( pLogService->CastToTraceLogService() ) {
  1030. strTemp1.LoadString( IDS_MMC_MENU_NEW_TRACE_LOG );
  1031. strTemp2.LoadString( IDS_MMC_STATUS_NEW_TRACE_LOG );
  1032. strTemp3.LoadString( IDS_MMC_MENU_TRACE_LOG_FROM );
  1033. strTemp4.LoadString( IDS_MMC_STATUS_TRACE_LOG_FROM );
  1034. } else if ( pLogService->CastToAlertService() ) {
  1035. strTemp1.LoadString( IDS_MMC_MENU_NEW_ALERT );
  1036. strTemp2.LoadString( IDS_MMC_STATUS_NEW_ALERT );
  1037. strTemp3.LoadString( IDS_MMC_MENU_ALERT_FROM );
  1038. strTemp4.LoadString( IDS_MMC_STATUS_ALERT_FROM );
  1039. } else {
  1040. ::MessageBox( NULL,
  1041. L"Bad Cookie",
  1042. L"CComponent::AddMenuItems",
  1043. MB_OK | MB_ICONERROR
  1044. );
  1045. hr = E_OUTOFMEMORY;
  1046. }
  1047. MFC_CATCH_HR_RETURN
  1048. if ( SUCCEEDED( hr ) ) {
  1049. // Create new...
  1050. ctxMenu[0].strName = const_cast<LPWSTR>((LPCWSTR)strTemp1);
  1051. ctxMenu[0].strStatusBarText = const_cast<LPWSTR>((LPCWSTR)strTemp2);
  1052. ctxMenu[0].lCommandID = IDM_NEW_QUERY;
  1053. ctxMenu[0].lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
  1054. ctxMenu[0].fFlags = MF_ENABLED;
  1055. ctxMenu[0].fSpecialFlags = 0;
  1056. hr = pCallbackUnknown->AddItem( &ctxMenu[0] );
  1057. if ( SUCCEEDED(hr) ) {
  1058. // Create from...
  1059. ctxMenu[0].strName = const_cast<LPWSTR>((LPCWSTR)strTemp3);
  1060. ctxMenu[0].strStatusBarText = const_cast<LPWSTR>((LPCWSTR)strTemp4);
  1061. ctxMenu[0].lCommandID = IDM_NEW_QUERY_FROM;
  1062. ctxMenu[0].lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
  1063. ctxMenu[0].fFlags = MF_ENABLED;
  1064. ctxMenu[0].fSpecialFlags = 0;
  1065. hr = pCallbackUnknown->AddItem( &ctxMenu[0] );
  1066. }
  1067. }
  1068. }
  1069. }
  1070. }
  1071. }
  1072. return hr;
  1073. } // end AddMenuItems()
  1074. //---------------------------------------------------------------------------
  1075. // Implement the command method so we can handle notifications
  1076. // from our Context menu extensions.
  1077. //
  1078. STDMETHODIMP
  1079. CComponentData::Command (
  1080. long nCommandID, // [in] Command to handle
  1081. LPDATAOBJECT pDataObject // [in] Points to data object, pass through
  1082. )
  1083. {
  1084. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1085. HRESULT hr = S_OK;
  1086. switch( nCommandID ) {
  1087. case IDM_NEW_QUERY:
  1088. CreateNewLogQuery( pDataObject );
  1089. break;
  1090. case IDM_NEW_QUERY_FROM:
  1091. CreateLogQueryFrom( pDataObject );
  1092. break;
  1093. default:
  1094. hr = S_FALSE;
  1095. }
  1096. return hr;
  1097. } // end Command()
  1098. STDMETHODIMP
  1099. CComponentData::CreatePropertyPages(
  1100. LPPROPERTYSHEETCALLBACK pCallBack,
  1101. LONG_PTR /* handle */, // This handle must be saved in the property
  1102. // page object to notify the parent when modified
  1103. LPDATAOBJECT pDataObject)
  1104. {
  1105. if (NULL == pCallBack || NULL == pDataObject)
  1106. {
  1107. ASSERT(FALSE);
  1108. return E_POINTER;
  1109. }
  1110. return S_FALSE;
  1111. } // CComponentData::CreatePropertyPages()
  1112. LPCWSTR
  1113. CComponentData::GetConceptsHTMLHelpFileName()
  1114. {
  1115. return CGlobalString::m_cszConceptsHTMLHelpFileName;
  1116. }
  1117. LPCWSTR
  1118. CComponentData::GetSnapinHTMLHelpFileName()
  1119. {
  1120. return CGlobalString::m_cszSnapinHTMLHelpFileName;
  1121. }
  1122. LPCWSTR
  1123. CComponentData::GetHTMLHelpTopic()
  1124. {
  1125. return CGlobalString::m_cszHTMLHelpTopic;
  1126. }
  1127. const CString&
  1128. CComponentData::GetContextHelpFilePath()
  1129. {
  1130. LPWSTR lpszBuffer;
  1131. UINT nLen;
  1132. if ( m_strContextHelpFilePath.IsEmpty() ) {
  1133. MFC_TRY
  1134. if ( m_strWindowsDirectory.IsEmpty() ) {
  1135. lpszBuffer = m_strWindowsDirectory.GetBuffer(2*MAX_PATH);
  1136. nLen = ::GetWindowsDirectory(lpszBuffer, 2*MAX_PATH);
  1137. m_strWindowsDirectory.ReleaseBuffer();
  1138. }
  1139. if ( !m_strWindowsDirectory.IsEmpty() )
  1140. {
  1141. m_strContextHelpFilePath = m_strWindowsDirectory + CGlobalString::m_cszContextHelpFileName;
  1142. }
  1143. MFC_CATCH_MINIMUM;
  1144. }
  1145. return m_strContextHelpFilePath;
  1146. }
  1147. // CComponentData::GetHelpTopic()
  1148. HRESULT
  1149. CComponentData::GetHelpTopic (
  1150. LPOLESTR* lpCompiledHelpFile )
  1151. {
  1152. HRESULT hr = E_FAIL;
  1153. LPCWSTR lpszHelpFileName;
  1154. CString strHelpFilePath;
  1155. LPWSTR lpszBuffer;
  1156. UINT nLen;
  1157. UINT nBytes;
  1158. if ( NULL == lpCompiledHelpFile) {
  1159. hr = E_POINTER;
  1160. } else {
  1161. *lpCompiledHelpFile = NULL;
  1162. MFC_TRY
  1163. lpszHelpFileName = GetSnapinHTMLHelpFileName();
  1164. if ( NULL == lpszHelpFileName) {
  1165. hr = E_UNEXPECTED;
  1166. } else {
  1167. lpszBuffer = strHelpFilePath.GetBuffer(2*MAX_PATH);
  1168. nLen = ::GetWindowsDirectory(lpszBuffer, 2*MAX_PATH);
  1169. if ( 0 == nLen ) {
  1170. hr = E_UNEXPECTED;
  1171. } else {
  1172. hr = StringCchCopy (&lpszBuffer[nLen], (2*MAX_PATH) - nLen, lpszHelpFileName );
  1173. hr = ERROR_SUCCESS;
  1174. nBytes = (lstrlen(lpszBuffer)+1) * sizeof(WCHAR);
  1175. *lpCompiledHelpFile = (LPOLESTR)::CoTaskMemAlloc(nBytes);
  1176. if ( NULL == *lpCompiledHelpFile ) {
  1177. hr = E_OUTOFMEMORY;
  1178. } else {
  1179. memcpy(*lpCompiledHelpFile, (LPCWSTR)strHelpFilePath, nBytes);
  1180. hr = S_OK;
  1181. }
  1182. }
  1183. strHelpFilePath.ReleaseBuffer();
  1184. }
  1185. MFC_CATCH_HR
  1186. }
  1187. return hr;
  1188. }
  1189. LPRESULTDATA
  1190. CComponentData::GetResultData()
  1191. {
  1192. if ( !m_ipResultData )
  1193. {
  1194. if ( m_ipConsole )
  1195. {
  1196. HRESULT hResult = m_ipConsole->QueryInterface(IID_IResultData, (void**)&m_ipResultData);
  1197. ASSERT (SUCCEEDED (hResult));
  1198. }
  1199. }
  1200. return m_ipResultData;
  1201. }
  1202. HRESULT
  1203. CComponentData::ProcessCommandLine ( CString& rstrMachineName )
  1204. {
  1205. HRESULT hr = S_OK;
  1206. LPCWSTR pszNext = NULL;
  1207. LPWSTR* pszArgList = NULL;
  1208. INT iNumArgs;
  1209. INT iArgIndex;
  1210. LPWSTR pszNextArg = NULL;
  1211. LPWSTR pszThisArg = NULL;
  1212. WCHAR szTemp[MAX_PATH + 1];
  1213. LPWSTR pszToken = NULL;
  1214. WCHAR szFileName[MAX_PATH + 1];
  1215. CString strSettings;
  1216. CString strWmi;
  1217. // Process only for local node.
  1218. if ( rstrMachineName.IsEmpty() ) {
  1219. pszNext = GetCommandLineW();
  1220. pszArgList = CommandLineToArgvW ( pszNext, &iNumArgs );
  1221. }
  1222. if ( NULL != pszArgList ) {
  1223. for ( iArgIndex = 0; iArgIndex < iNumArgs; iArgIndex++ ) {
  1224. pszNextArg = (LPWSTR)pszArgList[iArgIndex];
  1225. pszThisArg = pszNextArg;
  1226. while (pszThisArg ) {
  1227. if (0 == *pszThisArg) {
  1228. break;
  1229. }
  1230. if ( *pszThisArg++ == L'/' ) { // argument found
  1231. hr = StringCchCopyN (szTemp, MAX_PATH + 1, pszThisArg, lstrlen(pszThisArg)+1 );
  1232. hr = S_OK;
  1233. pszToken = _tcstok ( szTemp, L"/ =\"" );
  1234. MFC_TRY
  1235. strSettings.LoadString( IDS_CMDARG_SYSMONLOG_SETTINGS );
  1236. strWmi.LoadString(IDS_CMDARG_SYSMONLOG_WMI);
  1237. MFC_CATCH_MINIMUM;
  1238. if ( !strSettings.IsEmpty() && !strWmi.IsEmpty() ) {
  1239. if ( 0 == strSettings.CompareNoCase ( pszToken ) ) {
  1240. // Strip the initial non-token characters for string comparison.
  1241. pszThisArg = _tcsspnp ( pszNextArg, L"/ =\"" );
  1242. if ( NULL != pszThisArg ) {
  1243. if ( 0 == strSettings.CompareNoCase ( pszThisArg ) ) {
  1244. // Get the next argument (the file name)
  1245. iArgIndex++;
  1246. pszNextArg = (LPWSTR)pszArgList[iArgIndex];
  1247. pszThisArg = pszNextArg;
  1248. } else {
  1249. // File was created by Windows 2000 perfmon5.exe,
  1250. // so file name is part of the arg.
  1251. ZeroMemory ( szFileName, sizeof ( szFileName ) );
  1252. pszThisArg += strSettings.GetLength();
  1253. hr = StringCchCopyN (szFileName, MAX_PATH + 1, pszThisArg, lstrlen(pszThisArg)+1 );
  1254. hr = S_OK;
  1255. pszThisArg = _tcstok ( szFileName, L"=\"" );
  1256. }
  1257. hr = LoadFromFile( pszThisArg );
  1258. }
  1259. } else if ( 0 == strWmi.CompareNoCase ( pszToken ) ) {
  1260. g_dwRealTimeQuery = DATA_SOURCE_WBEM;
  1261. }
  1262. }
  1263. }
  1264. }
  1265. }
  1266. }
  1267. if ( NULL != pszArgList ) {
  1268. GlobalFree ( pszArgList );
  1269. }
  1270. return hr;
  1271. }
  1272. HRESULT
  1273. CComponentData::LoadFromFile ( LPWSTR pszFileName )
  1274. {
  1275. HRESULT hr = S_OK;
  1276. WCHAR szLocalName [MAX_PATH + 1];
  1277. LPWSTR pFileNameStart;
  1278. HANDLE hFindFile;
  1279. WIN32_FIND_DATA FindFileInfo;
  1280. INT iNameOffset;
  1281. szLocalName [0] = L'\0';
  1282. hr = StringCchCopyN (szLocalName, MAX_PATH + 1, pszFileName, lstrlen(pszFileName)+1 );
  1283. pFileNameStart = ExtractFileName (szLocalName) ;
  1284. iNameOffset = (INT)(pFileNameStart - szLocalName);
  1285. // convert short filename to long NTFS filename if necessary
  1286. hFindFile = FindFirstFile ( szLocalName, &FindFileInfo) ;
  1287. if (hFindFile && hFindFile != INVALID_HANDLE_VALUE) {
  1288. HANDLE hOpenFile;
  1289. // append the file name back to the path name
  1290. hr = StringCchCopyN (
  1291. &szLocalName[iNameOffset],
  1292. (MAX_PATH + 1) - lstrlen (szLocalName),
  1293. FindFileInfo.cFileName,
  1294. lstrlen(FindFileInfo.cFileName)+1 );
  1295. FindClose (hFindFile) ;
  1296. // Open the file
  1297. hOpenFile = CreateFile (
  1298. szLocalName,
  1299. GENERIC_READ,
  1300. 0, // Not shared
  1301. NULL, // Security attributes
  1302. OPEN_EXISTING,
  1303. FILE_ATTRIBUTE_NORMAL,
  1304. NULL );
  1305. if ( hOpenFile && hOpenFile != INVALID_HANDLE_VALUE ) {
  1306. DWORD dwFileSize;
  1307. DWORD dwFileSizeHigh;
  1308. LPWSTR pszFirstData = NULL;
  1309. // Read the file contents into a memory buffer.
  1310. dwFileSize = GetFileSize ( hOpenFile, &dwFileSizeHigh );
  1311. ASSERT ( 0 == dwFileSizeHigh );
  1312. MFC_TRY
  1313. pszFirstData = new WCHAR[(dwFileSize + sizeof(WCHAR))/sizeof(WCHAR)];
  1314. MFC_CATCH_HR
  1315. if ( NULL != pszFirstData ) {
  1316. BOOL bAtLeastOneSysmonObjectRead = FALSE;
  1317. if ( FileRead ( hOpenFile, pszFirstData, dwFileSize ) ) {
  1318. LPWSTR pszCurrentObject = NULL;
  1319. LPWSTR pszNextObject = NULL;
  1320. pszCurrentObject = pszFirstData;
  1321. while ( SUCCEEDED ( hr ) && NULL != pszCurrentObject ) {
  1322. CImpIPropertyBag* pPropBag = NULL;
  1323. // Write contents to a property bag
  1324. MFC_TRY
  1325. pPropBag = new CImpIPropertyBag;
  1326. MFC_CATCH_HR
  1327. if ( NULL != pPropBag ) {
  1328. DWORD dwStatus = pPropBag->LoadData( pszCurrentObject, &pszNextObject );
  1329. hr = HRESULT_FROM_WIN32( dwStatus );
  1330. if ( SUCCEEDED ( hr ) ) {
  1331. PSLSVC pSvc = NULL;
  1332. PSLQUERY pQuery = NULL;
  1333. DWORD dwLogType;
  1334. LPWSTR pszQueryName = NULL;
  1335. DWORD dwBufSize = 0;
  1336. CSmRootNode* pRoot = NULL;
  1337. CString strQueryName;
  1338. bAtLeastOneSysmonObjectRead = TRUE;
  1339. // Get root node
  1340. ASSERT ( !m_listpRootNode.IsEmpty() );
  1341. pRoot = m_listpRootNode.GetHead();
  1342. // Determine log type from property bag. Default to counter log.
  1343. hr = CSmLogQuery::DwordFromPropertyBag (
  1344. pPropBag,
  1345. NULL,
  1346. IDS_HTML_LOG_TYPE,
  1347. SLQ_COUNTER_LOG,
  1348. dwLogType);
  1349. // Get service pointer and log/alert name based on log type.
  1350. if ( SLQ_ALERT == dwLogType ) {
  1351. pSvc = pRoot->GetAlertService();
  1352. hr = CSmLogQuery::StringFromPropertyBag (
  1353. pPropBag,
  1354. NULL,
  1355. IDS_HTML_ALERT_NAME,
  1356. L"",
  1357. &pszQueryName,
  1358. &dwBufSize );
  1359. if ( NULL == pszQueryName ) {
  1360. hr = CSmLogQuery::StringFromPropertyBag (
  1361. pPropBag,
  1362. NULL,
  1363. IDS_HTML_LOG_NAME,
  1364. L"",
  1365. &pszQueryName,
  1366. &dwBufSize );
  1367. }
  1368. } else {
  1369. if ( SLQ_TRACE_LOG == dwLogType ) {
  1370. pSvc = pRoot->GetTraceLogService();
  1371. } else {
  1372. // Default to counter log service
  1373. pSvc = pRoot->GetCounterLogService();
  1374. }
  1375. hr = CSmLogQuery::StringFromPropertyBag (
  1376. pPropBag,
  1377. NULL,
  1378. IDS_HTML_LOG_NAME,
  1379. L"",
  1380. &pszQueryName,
  1381. &dwBufSize );
  1382. if ( NULL == pszQueryName ) {
  1383. hr = CSmLogQuery::StringFromPropertyBag (
  1384. pPropBag,
  1385. NULL,
  1386. IDS_HTML_ALERT_NAME,
  1387. L"",
  1388. &pszQueryName,
  1389. &dwBufSize );
  1390. }
  1391. }
  1392. strQueryName = pszQueryName;
  1393. delete [] pszQueryName;
  1394. while ( NULL == pQuery ) {
  1395. if ( !strQueryName.IsEmpty() ) {
  1396. pQuery = pSvc->CreateQuery ( strQueryName );
  1397. if ( NULL != pQuery ) {
  1398. BOOL bRegistryUpdated;
  1399. pQuery->LoadFromPropertyBag ( pPropBag, NULL );
  1400. dwStatus = pQuery->UpdateService ( bRegistryUpdated );
  1401. break;
  1402. } else {
  1403. dwStatus = GetLastError();
  1404. }
  1405. if ( ERROR_SUCCESS != dwStatus ) {
  1406. INT iResult;
  1407. CString strMessage;
  1408. CString csTitle;
  1409. BOOL bBreakImmediately = TRUE;
  1410. if ( SMCFG_NO_MODIFY_ACCESS == dwStatus ) {
  1411. CString strMachineName;
  1412. strMachineName = pSvc->GetMachineDisplayName ();
  1413. FormatSmLogCfgMessage (
  1414. strMessage,
  1415. m_hModule,
  1416. SMCFG_NO_MODIFY_ACCESS,
  1417. (LPCWSTR)strMachineName);
  1418. } else if ( SMCFG_DUP_QUERY_NAME == dwStatus ) {
  1419. FormatSmLogCfgMessage (
  1420. strMessage,
  1421. m_hModule,
  1422. SMCFG_DUP_QUERY_NAME,
  1423. (LPCWSTR)strQueryName);
  1424. bBreakImmediately = FALSE;
  1425. } else {
  1426. CString strSysMessage;
  1427. FormatSmLogCfgMessage (
  1428. strMessage,
  1429. m_hModule,
  1430. SMCFG_SYSTEM_MESSAGE,
  1431. (LPCWSTR)strQueryName);
  1432. FormatMessage (
  1433. FORMAT_MESSAGE_FROM_SYSTEM,
  1434. NULL,
  1435. dwStatus,
  1436. 0,
  1437. strSysMessage.GetBufferSetLength( MAX_PATH ),
  1438. MAX_PATH,
  1439. NULL );
  1440. strSysMessage.ReleaseBuffer();
  1441. if ( strSysMessage.IsEmpty() ) {
  1442. strSysMessage.Format ( L"0x%08lX", dwStatus );
  1443. }
  1444. strMessage += strSysMessage;
  1445. }
  1446. csTitle.LoadString ( IDS_PROJNAME );
  1447. hr = m_ipConsole->MessageBox(
  1448. (LPCWSTR)strMessage,
  1449. (LPCWSTR)csTitle,
  1450. MB_OK | MB_ICONERROR,
  1451. &iResult
  1452. );
  1453. if ( bBreakImmediately ) {
  1454. break;
  1455. }
  1456. }
  1457. }
  1458. if ( NULL == pQuery ) {
  1459. CNewQueryDlg cNewDlg(NULL, ((SLQ_ALERT == dwLogType) ? FALSE : TRUE));
  1460. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1461. cNewDlg.SetContextHelpFilePath( GetContextHelpFilePath() );
  1462. cNewDlg.m_strName = strQueryName;
  1463. if ( IDOK == cNewDlg.DoModal() ) {
  1464. strQueryName = cNewDlg.m_strName;
  1465. } else {
  1466. break;
  1467. }
  1468. }
  1469. }
  1470. }
  1471. }
  1472. pszCurrentObject = pszNextObject;
  1473. delete pPropBag;
  1474. } // end while
  1475. }
  1476. delete [] pszFirstData;
  1477. // Message to the user if no queries Read.
  1478. if ( !bAtLeastOneSysmonObjectRead ) {
  1479. CString strMessage;
  1480. CString strTitle;
  1481. INT iResult;
  1482. FormatSmLogCfgMessage (
  1483. strMessage,
  1484. m_hModule,
  1485. SMCFG_NO_HTML_SYSMON_OBJECT );
  1486. strTitle.LoadString ( IDS_PROJNAME );
  1487. m_ipConsole->MessageBox (
  1488. strMessage,
  1489. strTitle,
  1490. MB_OK | MB_ICONERROR,
  1491. &iResult );
  1492. }
  1493. } else {
  1494. hr = E_OUTOFMEMORY;
  1495. }
  1496. CloseHandle ( hOpenFile );
  1497. }
  1498. }
  1499. return hr;
  1500. }
  1501. HRESULT
  1502. CComponentData::InitPropertySheet (
  1503. CSmLogQuery* pQuery,
  1504. MMC_COOKIE mmcCookie,
  1505. LONG_PTR handle,
  1506. CPropertySheet* pcpsMain )
  1507. {
  1508. CCountersProperty *pPage1 = NULL;
  1509. CFilesProperty *pPage2 = NULL;
  1510. CScheduleProperty *pPage3 = NULL;
  1511. CTraceProperty *pPage4 = NULL;
  1512. CProvidersProperty *pPage5 = NULL;
  1513. CAlertActionProp *pPage6 = NULL;
  1514. CAlertGenProp *pPage7 = NULL;
  1515. HRESULT hr = NOERROR;
  1516. ASSERT ( NULL != pQuery );
  1517. pcpsMain->SetTitle (pQuery->GetLogName());
  1518. //
  1519. // Load all property pages
  1520. //
  1521. pcpsMain->m_psh.dwFlags |= PSP_PREMATURE;
  1522. MFC_TRY
  1523. if ( SLQ_ALERT == pQuery->GetLogType() ) {
  1524. pPage7 = new CAlertGenProp (mmcCookie, handle);
  1525. pPage6 = new CAlertActionProp (mmcCookie, handle);
  1526. pPage3 = new CScheduleProperty (mmcCookie, handle, NULL);
  1527. if ( NULL != pPage7 ) {
  1528. pPage7->SetContextHelpFilePath( GetContextHelpFilePath() );
  1529. pPage7->m_psp.dwFlags |= PSP_PREMATURE;
  1530. pcpsMain->AddPage (pPage7);
  1531. }
  1532. if ( NULL != pPage6 ) {
  1533. pPage6->SetContextHelpFilePath( GetContextHelpFilePath() );
  1534. pPage6->m_psp.dwFlags |= PSP_PREMATURE;
  1535. pcpsMain->AddPage (pPage6);
  1536. }
  1537. if ( NULL != pPage3 ) {
  1538. pPage3->SetContextHelpFilePath( GetContextHelpFilePath() );
  1539. pPage3->m_psp.dwFlags |= PSP_PREMATURE;
  1540. pcpsMain->AddPage (pPage3);
  1541. }
  1542. } else {
  1543. if ( SLQ_TRACE_LOG == pQuery->GetLogType() ) {
  1544. CWaitCursor WaitCursor;
  1545. // Connect to the server before creating the dialog
  1546. // so that the wait cursor can be used consistently.
  1547. // Sync the providers here so that the WMI calls are consistently
  1548. // from a single thread.
  1549. ASSERT ( NULL != pQuery->CastToTraceLogQuery() );
  1550. hr = (pQuery->CastToTraceLogQuery())->SyncGenProviders();
  1551. if ( SUCCEEDED ( hr ) ) {
  1552. pPage5 = new CProvidersProperty(mmcCookie, handle);
  1553. if ( NULL != pPage5 )
  1554. pPage5->SetContextHelpFilePath( GetContextHelpFilePath() );
  1555. pPage5->m_psp.dwFlags |= PSP_PREMATURE;
  1556. pcpsMain->AddPage (pPage5);
  1557. } else {
  1558. CString strMachineName;
  1559. CString strLogName;
  1560. pQuery->GetMachineDisplayName( strMachineName );
  1561. strLogName = pQuery->GetLogName();
  1562. HandleTraceConnectError (
  1563. hr,
  1564. strLogName,
  1565. strMachineName );
  1566. }
  1567. } else {
  1568. pPage1 = new CCountersProperty ( mmcCookie, handle );
  1569. if ( NULL != pPage1 ) {
  1570. pPage1->SetContextHelpFilePath( GetContextHelpFilePath() );
  1571. pPage1->m_psp.dwFlags |= PSP_PREMATURE;
  1572. pcpsMain->AddPage (pPage1);
  1573. }
  1574. }
  1575. if ( SUCCEEDED ( hr ) ) {
  1576. pPage2 = new CFilesProperty(mmcCookie, handle);
  1577. if ( NULL != pPage2 ) {
  1578. pPage2->SetContextHelpFilePath( GetContextHelpFilePath() );
  1579. pPage2->m_psp.dwFlags |= PSP_PREMATURE;
  1580. pcpsMain->AddPage (pPage2);
  1581. }
  1582. pPage3 = new CScheduleProperty(mmcCookie, handle, NULL);
  1583. if ( NULL != pPage3 ) {
  1584. pPage3->SetContextHelpFilePath( GetContextHelpFilePath() );
  1585. pPage3->m_psp.dwFlags |= PSP_PREMATURE;
  1586. pcpsMain->AddPage (pPage3);
  1587. }
  1588. if ( SLQ_TRACE_LOG == pQuery->GetLogType() ) {
  1589. pPage4 = new CTraceProperty(mmcCookie, handle);
  1590. if ( NULL != pPage4 ) {
  1591. pPage4->SetContextHelpFilePath( GetContextHelpFilePath() );
  1592. pPage4->m_psp.dwFlags |= PSP_PREMATURE;
  1593. pcpsMain->AddPage (pPage4);
  1594. }
  1595. }
  1596. }
  1597. }
  1598. MFC_CATCH_HR
  1599. if ( SUCCEEDED ( hr ) ) {
  1600. pQuery->SetInitialPropertySheet ( pcpsMain );
  1601. }
  1602. return hr;
  1603. } // End InitPropertySheet
  1604. void
  1605. CComponentData::HandleTraceConnectError (
  1606. HRESULT& rhr,
  1607. CString& rstrLogName,
  1608. CString& rstrMachineName )
  1609. {
  1610. ASSERT ( FAILED ( rhr ) );
  1611. if ( FAILED ( rhr ) ) {
  1612. CString strMessage;
  1613. CString strSysMessage;
  1614. INT iResult;
  1615. FormatSmLogCfgMessage (
  1616. strMessage,
  1617. m_hModule,
  1618. SMCFG_UNABLE_OPEN_TRACESVC_DLG,
  1619. rstrMachineName,
  1620. rstrLogName );
  1621. FormatMessage (
  1622. FORMAT_MESSAGE_FROM_SYSTEM,
  1623. NULL,
  1624. rhr,
  1625. 0,
  1626. strSysMessage.GetBufferSetLength( MAX_PATH ),
  1627. MAX_PATH,
  1628. NULL );
  1629. strSysMessage.ReleaseBuffer();
  1630. if ( strSysMessage.IsEmpty() ) {
  1631. strSysMessage.Format ( L"0x%08lX", rhr );
  1632. }
  1633. strMessage += strSysMessage;
  1634. m_ipConsole->MessageBox(
  1635. strMessage,
  1636. rstrLogName,
  1637. MB_OK | MB_ICONERROR,
  1638. &iResult);
  1639. }
  1640. return;
  1641. }// end HandleTraceConnectError()
  1642. HRESULT
  1643. CComponentData::NewTypedQuery (
  1644. CSmLogService* pSvc,
  1645. IPropertyBag* pPropBag,
  1646. LPDATAOBJECT pDataObject ) // [in] Points to the data object
  1647. {
  1648. HRESULT hr = S_OK;
  1649. LPWSTR szQueryName = NULL;
  1650. CString strPreviousQueryName;
  1651. DWORD dwBufSize = 0;
  1652. ResourceStateManager rsm;
  1653. CNewQueryDlg cNewDlg(NULL, (((CSmNode*)pSvc)->CastToAlertService() ? FALSE : TRUE));
  1654. CThemeContextActivator activator;
  1655. ASSERT ( NULL != pSvc );
  1656. if ( NULL != pPropBag && NULL != pSvc ) {
  1657. if ( NULL != ((CSmNode*)pSvc)->CastToAlertService() ) {
  1658. hr = CSmLogQuery::StringFromPropertyBag (
  1659. pPropBag,
  1660. NULL,
  1661. IDS_HTML_ALERT_NAME,
  1662. L"",
  1663. &szQueryName,
  1664. &dwBufSize );
  1665. if ( NULL == szQueryName ) {
  1666. hr = CSmLogQuery::StringFromPropertyBag (
  1667. pPropBag,
  1668. NULL,
  1669. IDS_HTML_LOG_NAME,
  1670. L"",
  1671. &szQueryName,
  1672. &dwBufSize );
  1673. }
  1674. } else {
  1675. hr = CSmLogQuery::StringFromPropertyBag (
  1676. pPropBag,
  1677. NULL,
  1678. IDS_HTML_LOG_NAME,
  1679. L"",
  1680. &szQueryName,
  1681. &dwBufSize );
  1682. if ( NULL == szQueryName ) {
  1683. hr = CSmLogQuery::StringFromPropertyBag (
  1684. pPropBag,
  1685. NULL,
  1686. IDS_HTML_ALERT_NAME,
  1687. L"",
  1688. &szQueryName,
  1689. &dwBufSize );
  1690. }
  1691. }
  1692. }
  1693. cNewDlg.SetContextHelpFilePath( GetContextHelpFilePath() );
  1694. if ( NULL != szQueryName ) {
  1695. strPreviousQueryName = szQueryName;
  1696. cNewDlg.m_strName = szQueryName;
  1697. } else {
  1698. strPreviousQueryName.Empty();
  1699. cNewDlg.m_strName.Empty();
  1700. }
  1701. // Loop until the user hits Cancel or CreateQuery fails.
  1702. while ( IDOK == cNewDlg.DoModal() ) {
  1703. PSLQUERY pQuery;
  1704. pQuery = pSvc->CreateQuery ( cNewDlg.m_strName );
  1705. if ( NULL != pQuery ) {
  1706. MMC_COOKIE mmcQueryCookie = (MMC_COOKIE)pQuery;
  1707. LONG_PTR handle = NULL;
  1708. INT iPageIndex;
  1709. CPropertySheet* pcpsMain;
  1710. CSmPropertyPage* pActivePage = NULL;
  1711. CString strFolderName;
  1712. CString strBaseFileName;
  1713. CString strSqlName;
  1714. CString strDsn;
  1715. CString strSqlLogSetName;
  1716. INT iPageCount;
  1717. INT iTotalLength;
  1718. INT iRightLength;
  1719. BOOL bDirty = FALSE;
  1720. // If property bag provided, override defaults with the provided properties.
  1721. if ( NULL != pPropBag ) {
  1722. hr = pQuery->LoadFromPropertyBag ( pPropBag, NULL );
  1723. if ( FAILED(hr) ) {
  1724. hr = S_OK;
  1725. }
  1726. pQuery->GetFileNameParts ( strFolderName, strBaseFileName );
  1727. //
  1728. // Compare base file name with the old query name from the settings file.
  1729. // If they match, change the file name to match the new query name.
  1730. //
  1731. if ( ! strBaseFileName.CompareNoCase ( strPreviousQueryName ) ) {
  1732. pQuery->SetFileNameParts ( strFolderName, cNewDlg.m_strName );
  1733. bDirty = TRUE;
  1734. }
  1735. // Format string: "SQL:%s!%s"
  1736. MFC_TRY
  1737. strSqlName = pQuery->GetSqlName();
  1738. iTotalLength = strSqlName.GetLength();
  1739. iRightLength = iTotalLength - strSqlName.Find(L"!");
  1740. strDsn = strSqlName.Mid ( 4, iTotalLength - iRightLength - 4 );
  1741. strSqlLogSetName = strSqlName.Right( iTotalLength - strSqlName.Find(L"!") - 1 );
  1742. if ( ! strSqlLogSetName.CompareNoCase ( strPreviousQueryName ) ) {
  1743. strSqlName.Format ( L"SQL:%s!%s",strDsn, cNewDlg.m_strName );
  1744. pQuery->SetSqlName ( strSqlName );
  1745. bDirty = TRUE;
  1746. }
  1747. MFC_CATCH_HR;
  1748. if ( bDirty ) {
  1749. pQuery->SyncPropPageSharedData();
  1750. }
  1751. }
  1752. if ( FAILED(hr) ) {
  1753. hr = S_OK;
  1754. }
  1755. // now show property pages to modify the new query
  1756. MFC_TRY
  1757. pcpsMain = new CPropertySheet;
  1758. hr = InitPropertySheet ( pQuery, mmcQueryCookie, handle, pcpsMain );
  1759. iPageCount = pcpsMain->GetPageCount();
  1760. if ( SUCCEEDED(hr) ) {
  1761. pActivePage = (CSmPropertyPage*)pcpsMain->GetActivePage();
  1762. if (pActivePage) {
  1763. pActivePage->SetModifiedPage(TRUE);
  1764. }
  1765. pcpsMain->DoModal();
  1766. }
  1767. if ( pQuery->IsFirstModification() ) {
  1768. pQuery->SetInitialPropertySheet ( NULL );
  1769. m_ipConsole->UpdateAllViews ( pDataObject, 0, eSmHintNewQuery );
  1770. } else {
  1771. // Delete query if newly created and OnApply was never called.
  1772. pSvc->DeleteQuery ( pQuery );
  1773. }
  1774. for ( iPageIndex = iPageCount - 1; iPageIndex >= 0; iPageIndex-- ) {
  1775. delete pcpsMain->GetPage( iPageIndex );
  1776. }
  1777. delete pcpsMain;
  1778. pcpsMain = NULL;
  1779. break;
  1780. MFC_CATCH_HR
  1781. } else {
  1782. INT iResult;
  1783. CString strMessage;
  1784. CString csTitle;
  1785. DWORD dwStatus;
  1786. BOOL bBreakImmediately = TRUE;
  1787. dwStatus = GetLastError();
  1788. if ( SMCFG_NO_MODIFY_ACCESS == dwStatus ) {
  1789. CString strMachineName;
  1790. strMachineName = pSvc->GetMachineDisplayName ();
  1791. FormatSmLogCfgMessage (
  1792. strMessage,
  1793. m_hModule,
  1794. SMCFG_NO_MODIFY_ACCESS,
  1795. (LPCWSTR)strMachineName);
  1796. } else if ( SMCFG_DUP_QUERY_NAME == dwStatus ) {
  1797. FormatSmLogCfgMessage (
  1798. strMessage,
  1799. m_hModule,
  1800. SMCFG_DUP_QUERY_NAME,
  1801. (LPCWSTR)cNewDlg.m_strName);
  1802. bBreakImmediately = FALSE;
  1803. } else {
  1804. FormatMessage (
  1805. FORMAT_MESSAGE_FROM_SYSTEM,
  1806. NULL,
  1807. dwStatus,
  1808. 0,
  1809. strMessage.GetBufferSetLength( MAX_PATH ),
  1810. MAX_PATH,
  1811. NULL );
  1812. strMessage.ReleaseBuffer();
  1813. if ( strMessage.IsEmpty() ) {
  1814. strMessage.Format ( L"0x%08lX", dwStatus );
  1815. }
  1816. }
  1817. csTitle.LoadString ( IDS_PROJNAME );
  1818. hr = m_ipConsole->MessageBox(
  1819. (LPCWSTR)strMessage,
  1820. (LPCWSTR)csTitle,
  1821. MB_OK | MB_ICONERROR,
  1822. &iResult
  1823. );
  1824. if ( bBreakImmediately ) {
  1825. break;
  1826. }
  1827. }
  1828. }
  1829. delete [] szQueryName;
  1830. return hr;
  1831. }
  1832. HRESULT
  1833. CComponentData::CreateNewLogQuery (
  1834. LPDATAOBJECT pDataObject, // [in] Points to the data object
  1835. IPropertyBag* pPropBag )
  1836. {
  1837. HRESULT hr = S_OK;
  1838. CDataObject* pDO = NULL;
  1839. MMC_COOKIE mmcSvcCookie;
  1840. BOOL bIsLogSvc;
  1841. PSLSVC pLogService;
  1842. ResourceStateManager rsm;
  1843. ASSERT( NULL != GetResultData() );
  1844. if ( NULL == pDataObject ) {
  1845. ASSERT ( FALSE );
  1846. hr = E_POINTER;
  1847. } else {
  1848. pDO = ExtractOwnDataObject( pDataObject );
  1849. if ( NULL == pDO ) {
  1850. ASSERT ( FALSE );
  1851. hr = E_UNEXPECTED;
  1852. }
  1853. }
  1854. if ( SUCCEEDED ( hr ) ) {
  1855. // If this is the root node, don't need to do anything
  1856. if( COOKIE_IS_ROOTNODE == pDO->GetCookieType() ) {
  1857. hr = S_FALSE;
  1858. } else {
  1859. // Just make sure we are where we think we are
  1860. ASSERT ( COOKIE_IS_COUNTERMAINNODE == pDO->GetCookieType()
  1861. || COOKIE_IS_TRACEMAINNODE == pDO->GetCookieType()
  1862. || COOKIE_IS_ALERTMAINNODE == pDO->GetCookieType() );
  1863. mmcSvcCookie = (MMC_COOKIE)pDO->GetCookie();
  1864. bIsLogSvc = IsLogService (mmcSvcCookie);
  1865. if (bIsLogSvc) {
  1866. pLogService = (PSLSVC)mmcSvcCookie;
  1867. hr = NewTypedQuery ( pLogService, pPropBag, pDataObject );
  1868. }
  1869. hr = S_OK;
  1870. }
  1871. }
  1872. return hr;
  1873. } // end CreateNewLogQuery()
  1874. HRESULT
  1875. CComponentData::CreateLogQueryFrom (
  1876. LPDATAOBJECT pDataObject ) // [in] Points to the data object
  1877. {
  1878. HRESULT hr = S_OK;
  1879. INT_PTR iPtrResult = IDCANCEL;
  1880. INT iResult = IDCANCEL;
  1881. CDataObject* pDO = NULL;
  1882. HWND hwndMain;
  1883. CString strFileExtension;
  1884. CString strFileFilter;
  1885. HANDLE hOpenFile;
  1886. WCHAR szInitialDir[MAX_PATH + 1];
  1887. DWORD dwFileSize;
  1888. DWORD dwFileSizeHigh;
  1889. LPWSTR pszData = NULL;
  1890. CString strMessage;
  1891. CString strTitle;
  1892. CImpIPropertyBag* pPropBag = NULL;
  1893. DWORD dwStatus;
  1894. DWORD dwLogType;
  1895. CLogWarnd LogWarnd;
  1896. DWORD dwCookieType;
  1897. ResourceStateManager rsm;
  1898. if ( NULL == pDataObject ) {
  1899. ASSERT ( FALSE );
  1900. hr = E_POINTER;
  1901. } else {
  1902. pDO = ExtractOwnDataObject( pDataObject );
  1903. if ( NULL == pDO ) {
  1904. ASSERT ( FALSE );
  1905. hr = E_UNEXPECTED;
  1906. }
  1907. }
  1908. if ( SUCCEEDED ( hr ) ) {
  1909. if ( IsLogService ( pDO->GetCookie() ) ) {
  1910. // Find file to create from.
  1911. MFC_TRY
  1912. strFileExtension.LoadString ( IDS_HTML_EXTENSION );
  1913. strFileFilter.LoadString ( IDS_HTML_FILE );
  1914. MFC_CATCH_HR
  1915. strFileFilter.Replace ( L'|', L'\0' );
  1916. hr = m_ipConsole->GetMainWindow( &hwndMain );
  1917. if ( SUCCEEDED(hr) ) {
  1918. OPENFILENAME ofn;
  1919. BOOL bResult;
  1920. WCHAR szFileName[MAX_PATH + 1];
  1921. ZeroMemory( szFileName, MAX_PATH*sizeof(WCHAR) );
  1922. ZeroMemory( &ofn, sizeof( OPENFILENAME ) );
  1923. ofn.lStructSize = sizeof(OPENFILENAME);
  1924. ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
  1925. ofn.lpstrFile = szFileName;
  1926. ofn.nMaxFile = MAX_PATH;
  1927. ofn.lpstrDefExt = (LPCWSTR)strFileExtension;
  1928. ofn.lpstrFilter = strFileFilter;
  1929. ofn.hwndOwner = hwndMain;
  1930. ofn.hInstance = m_hModule;
  1931. if ( SUCCEEDED ( SHGetFolderPathW ( NULL, CSIDL_PERSONAL, NULL, 0, szInitialDir ) ) ) {
  1932. ofn.lpstrInitialDir = szInitialDir;
  1933. }
  1934. bResult = GetOpenFileName( &ofn );
  1935. if ( bResult ) {
  1936. // Open the file to find the query name.
  1937. hOpenFile = CreateFile (
  1938. ofn.lpstrFile,
  1939. GENERIC_READ,
  1940. 0, // Not shared
  1941. NULL, // Security attributes
  1942. OPEN_EXISTING, //
  1943. FILE_ATTRIBUTE_NORMAL,
  1944. NULL );
  1945. if ( hOpenFile && INVALID_HANDLE_VALUE != hOpenFile ) {
  1946. // Create a property bag and load it. Use the existing query
  1947. // name as the default to ask the user for a new query name.
  1948. // New query name is required if the current name exists in the registry.
  1949. // Read the file contents into a memory buffer.
  1950. dwFileSize = GetFileSize ( hOpenFile, &dwFileSizeHigh );
  1951. // kathsetodo: Handle larger files?
  1952. ASSERT ( 0 == dwFileSizeHigh );
  1953. if ( 0 == dwFileSizeHigh ) {
  1954. // 1 for NULL
  1955. MFC_TRY
  1956. pszData = new WCHAR[(dwFileSize/sizeof(WCHAR)) + 1 ];
  1957. MFC_CATCH_HR
  1958. if ( NULL != pszData ) {
  1959. if ( FileRead ( hOpenFile, pszData, dwFileSize ) ) {
  1960. // Read contents from a property bag
  1961. MFC_TRY
  1962. pPropBag = new CImpIPropertyBag;
  1963. MFC_CATCH_HR
  1964. if ( NULL != pPropBag ) {
  1965. MFC_TRY
  1966. strTitle.LoadString ( IDS_PROJNAME );
  1967. MFC_CATCH_HR
  1968. dwStatus = pPropBag->LoadData( pszData );
  1969. hr = HRESULT_FROM_WIN32( dwStatus );
  1970. if ( SUCCEEDED ( hr ) ) {
  1971. //get the log type from the pPropBag and compare it with service(cookie) type
  1972. // Determine log type from property bag. Default to -1 SMONCTRL_LOG
  1973. hr = CSmLogQuery::DwordFromPropertyBag (
  1974. pPropBag,
  1975. NULL,
  1976. IDS_HTML_LOG_TYPE,
  1977. SMONCTRL_LOG, //indicates tha it's a smonctrl log
  1978. dwLogType);
  1979. if (SUCCEEDED (hr) ){
  1980. dwCookieType = (DWORD)pDO->GetCookieType();
  1981. switch(dwCookieType){
  1982. case COOKIE_IS_COUNTERMAINNODE:
  1983. if (dwLogType != SLQ_COUNTER_LOG ){
  1984. //Error
  1985. LogWarnd.m_ErrorMsg = ID_ERROR_COUNTER_LOG;
  1986. hr = S_FALSE;
  1987. }
  1988. break;
  1989. case COOKIE_IS_TRACEMAINNODE:
  1990. if (dwLogType != SLQ_TRACE_LOG ){
  1991. //Error
  1992. LogWarnd.m_ErrorMsg = ID_ERROR_TRACE_LOG;
  1993. hr = S_FALSE;
  1994. }
  1995. break;
  1996. case COOKIE_IS_ALERTMAINNODE:
  1997. if (dwLogType != SLQ_ALERT){
  1998. //Error
  1999. LogWarnd.m_ErrorMsg = ID_ERROR_ALERT_LOG;
  2000. hr = S_FALSE;
  2001. }
  2002. break;
  2003. case SMONCTRL_LOG:
  2004. //Error
  2005. LogWarnd.m_ErrorMsg = ID_ERROR_SMONCTRL_LOG;
  2006. hr = S_FALSE;
  2007. break;
  2008. }
  2009. if (hr == S_FALSE){
  2010. if(dwLogType == SLQ_TRACE_LOG || LogWarnd.m_ErrorMsg == ID_ERROR_TRACE_LOG ){
  2011. MFC_TRY
  2012. strMessage.LoadString(IDS_ERRMSG_TRACE_LOG);
  2013. MFC_CATCH_HR
  2014. m_ipConsole->MessageBox (
  2015. strMessage,
  2016. strTitle,
  2017. MB_OK | MB_ICONERROR,
  2018. &iResult );
  2019. } else {
  2020. LogWarnd.m_dwLogType = dwLogType;
  2021. MFC_TRY
  2022. LogWarnd.m_strContextHelpFile = GetContextHelpFilePath();
  2023. // TODO: Handle error
  2024. MFC_CATCH_MINIMUM
  2025. if(!LogTypeCheckNoMore(&LogWarnd)){
  2026. LogWarnd.SetTitleString ( strTitle );
  2027. LogWarnd.DoModal();
  2028. }
  2029. CreateNewLogQuery ( pDataObject, pPropBag );
  2030. }
  2031. }
  2032. }
  2033. if ( S_OK == hr ) {
  2034. hr = CreateNewLogQuery ( pDataObject, pPropBag );
  2035. }
  2036. } else {
  2037. FormatSmLogCfgMessage (
  2038. strMessage,
  2039. m_hModule,
  2040. SMCFG_NO_HTML_SYSMON_OBJECT );
  2041. m_ipConsole->MessageBox (
  2042. strMessage,
  2043. strTitle,
  2044. MB_OK | MB_ICONERROR,
  2045. &iResult );
  2046. }
  2047. }
  2048. }
  2049. delete [] pszData;
  2050. }
  2051. } else {
  2052. // kathsetodo: error message re: file too large.
  2053. }
  2054. CloseHandle ( hOpenFile );
  2055. }
  2056. }
  2057. }
  2058. }
  2059. }
  2060. return hr;
  2061. } // End CreateLogQueryFrom
  2062. BOOL
  2063. CComponentData::LogTypeCheckNoMore (
  2064. CLogWarnd* LogWarnd )
  2065. {
  2066. BOOL bretVal = FALSE;
  2067. long nErr;
  2068. HKEY hKey;
  2069. DWORD dwWarnFlag;
  2070. DWORD dwDataType = 0;
  2071. DWORD dwDataSize = 0;
  2072. DWORD dwDisposition;
  2073. WCHAR RegValName[MAX_PATH];
  2074. switch (LogWarnd->m_dwLogType){
  2075. case SLQ_COUNTER_LOG:
  2076. StringCchPrintf ( RegValName, MAX_PATH,L"NoWarnCounterLog");
  2077. break;
  2078. case SLQ_ALERT:
  2079. StringCchPrintf ( RegValName, MAX_PATH,L"NoWarnAlertLog");
  2080. break;
  2081. }
  2082. // check registry setting to see if we need to pop up warning dialog
  2083. nErr = RegOpenKey(
  2084. HKEY_CURRENT_USER,
  2085. L"Software\\Microsoft\\PerformanceLogsAndAlerts",
  2086. &hKey );
  2087. if( nErr != ERROR_SUCCESS ) {
  2088. nErr = RegCreateKeyEx(
  2089. HKEY_CURRENT_USER,
  2090. L"Software\\Microsoft\\PerformanceLogsAndAlerts",
  2091. 0,
  2092. L"REG_DWORD",
  2093. REG_OPTION_NON_VOLATILE,
  2094. KEY_READ | KEY_WRITE,
  2095. NULL,
  2096. &hKey,
  2097. &dwDisposition );
  2098. }
  2099. dwWarnFlag = 0;
  2100. if( nErr == ERROR_SUCCESS ) {
  2101. dwDataSize = sizeof(DWORD);
  2102. nErr = RegQueryValueExW(
  2103. hKey,
  2104. RegValName,
  2105. NULL,
  2106. &dwDataType,
  2107. (LPBYTE) &dwWarnFlag,
  2108. (LPDWORD) &dwDataSize
  2109. );
  2110. if (ERROR_SUCCESS == nErr ){
  2111. LogWarnd->m_hKey = hKey;
  2112. }
  2113. if ( (dwDataType != REG_DWORD) || (dwDataSize != sizeof(DWORD)))
  2114. dwWarnFlag = 0;
  2115. if (dwWarnFlag)
  2116. bretVal = TRUE;
  2117. nErr = RegCloseKey( hKey );
  2118. if( ERROR_SUCCESS != nErr ){
  2119. // DisplayError( GetLastError(), L"Close PerfLog user Key Failed" );
  2120. bretVal = FALSE;
  2121. }
  2122. }
  2123. return bretVal;
  2124. }
  2125. BOOL
  2126. CComponentData::IsPreWindows2000Server ( const CString& rstrMachineName )
  2127. {
  2128. BOOL bIsPreWindows2000Server = FALSE;
  2129. PLA_VERSION structVersion;
  2130. if ( ERROR_SUCCESS == PdhiPlaGetVersion ( rstrMachineName, &structVersion ) )
  2131. {
  2132. if ( 5 > structVersion.dwMajorVersion
  2133. && 2195 > structVersion.dwBuild )
  2134. {
  2135. bIsPreWindows2000Server = TRUE;
  2136. }
  2137. }
  2138. return bIsPreWindows2000Server;
  2139. }
  2140. CSmRootNode*
  2141. CComponentData::GetOrphanedRootNode ( const CString& rstrMachineName )
  2142. {
  2143. CSmRootNode* pRootNode = NULL;
  2144. CSmRootNode* pFoundNode = NULL;
  2145. POSITION Pos1, Pos2;
  2146. // Remove the selected node from the list and return it, if it exists.
  2147. for (
  2148. Pos1 = m_listpOrphanedRootNode.GetHeadPosition();
  2149. NULL != (Pos2 = Pos1); )
  2150. {
  2151. pRootNode = m_listpOrphanedRootNode.GetNext( Pos1 );
  2152. if ( !pRootNode->GetMachineName().CompareNoCase ( rstrMachineName ) ) {
  2153. pRootNode = m_listpOrphanedRootNode.GetAt( Pos2 );
  2154. pFoundNode = pRootNode;
  2155. m_listpOrphanedRootNode.RemoveAt ( Pos2 );
  2156. break;
  2157. }
  2158. }
  2159. return pFoundNode;
  2160. }