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.

787 lines
25 KiB

  1. #include "stdafx.h"
  2. #include "common.h"
  3. #include "iisobj.h"
  4. #include "tracker.h"
  5. extern INT g_iDebugOutputLevel;
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. void
  12. CPropertySheetTracker::Dump()
  13. {
  14. #if defined(_DEBUG) || DBG
  15. int iCount = 0;
  16. CString strGUIDName;
  17. GUID * pItemFromListGUID = NULL;
  18. CIISObject * pItemFromList = NULL;
  19. if (!(g_iDebugOutputLevel & DEBUG_FLAG_CIISOBJECT))
  20. {
  21. return;
  22. }
  23. DebugTrace(_T("Dump OpenPropertySheetList -------------- start (count=%d)\r\n"),IISObjectOpenPropertySheets.GetCount());
  24. POSITION pos = IISObjectOpenPropertySheets.GetHeadPosition();
  25. while (pos)
  26. {
  27. pItemFromList = IISObjectOpenPropertySheets.GetNext(pos);
  28. if (pItemFromList)
  29. {
  30. iCount++;
  31. // Get GUID Name
  32. pItemFromListGUID = (GUID*) pItemFromList->GetNodeType();
  33. if (pItemFromListGUID)
  34. {
  35. GetFriendlyGuidName(*pItemFromListGUID,strGUIDName);
  36. }
  37. // Get FriendlyName
  38. LPOLESTR pTempFriendly = pItemFromList->QueryDisplayName();
  39. DebugTrace(_T("Dump:[%3d] %p (%s) '%s'\r\n"),iCount,pItemFromList,strGUIDName,pTempFriendly ? pTempFriendly : _T(""));
  40. }
  41. }
  42. DebugTrace(_T("Dump OpenPropertySheetList -------------- end\r\n"));
  43. #endif // _DEBUG
  44. return;
  45. }
  46. INT
  47. CPropertySheetTracker::OrphanPropertySheetsBelowMe(CComPtr<IConsoleNameSpace> pConsoleNameSpace,CIISObject * pItem,BOOL bOrphan)
  48. {
  49. BOOL bFound = FALSE;
  50. POSITION pos;
  51. INT iOrphanedCount = 0;
  52. // Loop thru all the open property sheets
  53. // and see if there is a property sheet that is below me.
  54. GUID * pItemFromListGUID = NULL;
  55. CIISObject * pItemFromList = NULL;
  56. CIISMBNode * pItemFromListAsNode = NULL;
  57. CIISMachine * pItemFromListOwner = NULL;
  58. GUID * pItemGUID = NULL;
  59. CIISMBNode * pItemAsNode = NULL;
  60. CIISMachine * pItemOwner = NULL;
  61. pItemGUID = (GUID*) pItem->GetNodeType();
  62. // check if it's a leaf node...
  63. if (pItem->IsLeafNode())
  64. {
  65. //cWebServiceExtensionContainer
  66. //cWebServiceExtension
  67. //cApplicationNode
  68. //cFileNode
  69. return FALSE;
  70. }
  71. pItemAsNode = (CIISMBNode *) pItem;
  72. pItemOwner = pItemAsNode->GetOwner();
  73. pos = IISObjectOpenPropertySheets.GetHeadPosition();
  74. while (pos)
  75. {
  76. pItemFromList = IISObjectOpenPropertySheets.GetNext(pos);
  77. if (pItemFromList)
  78. {
  79. // Get Owner, if the owner Pointer
  80. // matches our passed in CIISObject
  81. // then this must be open for this computer...
  82. pItemFromListAsNode = (CIISMBNode *) pItemFromList;
  83. if (!pItemFromListAsNode)
  84. {
  85. // got a bad pointer to an object.
  86. // skip it...
  87. continue;
  88. }
  89. if (pItemFromListAsNode == pItem)
  90. {
  91. // we found ourself...
  92. // skip it
  93. continue;
  94. }
  95. pItemFromListOwner = pItemFromListAsNode->GetOwner();
  96. if (!pItemFromListOwner)
  97. {
  98. // object doesn't have an owner...
  99. // skip it
  100. continue;
  101. }
  102. if (pItemFromListOwner != pItemOwner)
  103. {
  104. // they have different owners
  105. // they must be from different machines..
  106. // skip it
  107. continue;
  108. }
  109. pItemFromListGUID = (GUID*) pItemFromListAsNode->GetNodeType();
  110. if (!pItemFromListGUID)
  111. {
  112. // object doesn't have a guid who knows what type it is!!!
  113. ASSERT("Error:Item Missing GUID!");
  114. //continue;
  115. }
  116. //
  117. // Determine what type of object
  118. // we are checking, and cater to that object
  119. //
  120. bFound = FALSE;
  121. if (IsEqualGUID(*pItemGUID,cWebServiceExtensionContainer))
  122. {
  123. if (IsEqualGUID(*pItemGUID,*pItemFromListGUID))
  124. {
  125. // if we found our own type...
  126. continue;
  127. }
  128. if (IsEqualGUID(*pItemFromListGUID,cWebServiceExtension))
  129. {
  130. if (pItemFromList->IsMyPropertySheetOpen())
  131. {
  132. bFound = TRUE;
  133. break;
  134. }
  135. }
  136. continue;
  137. } else if (IsEqualGUID(*pItemGUID,cAppPoolNode))
  138. {
  139. if (IsEqualGUID(*pItemGUID,*pItemFromListGUID))
  140. {
  141. // if we found our own type...
  142. continue;
  143. }
  144. if (IsEqualGUID(*pItemFromListGUID,cApplicationNode))
  145. {
  146. if (pItemFromList->IsMyPropertySheetOpen())
  147. {
  148. bFound = TRUE;
  149. break;
  150. }
  151. }
  152. continue;
  153. } else if (IsEqualGUID(*pItemGUID,cAppPoolsNode))
  154. {
  155. if (IsEqualGUID(*pItemGUID,*pItemFromListGUID))
  156. {
  157. // if we found our own type...
  158. continue;
  159. }
  160. if (IsEqualGUID(*pItemFromListGUID,cAppPoolNode) ||
  161. IsEqualGUID(*pItemFromListGUID,cApplicationNode)
  162. )
  163. {
  164. if (pItemFromList->IsMyPropertySheetOpen())
  165. {
  166. bFound = TRUE;
  167. break;
  168. }
  169. }
  170. continue;
  171. } else if (IsEqualGUID(*pItemGUID,cInstanceNode))
  172. {
  173. if (IsEqualGUID(*pItemGUID,*pItemFromListGUID))
  174. {
  175. // if we found our own type...
  176. continue;
  177. }
  178. if (!IsEqualGUID(*pItemFromListGUID,cChildNode) &&
  179. !IsEqualGUID(*pItemFromListGUID,cFileNode)
  180. )
  181. {
  182. continue;
  183. }
  184. } else if (IsEqualGUID(*pItemGUID,cInstanceCollectorNode))
  185. {
  186. if (IsEqualGUID(*pItemGUID,*pItemFromListGUID))
  187. {
  188. // if we found our own type...
  189. continue;
  190. }
  191. if (!IsEqualGUID(*pItemFromListGUID,cInstanceNode) &&
  192. !IsEqualGUID(*pItemFromListGUID,cChildNode) &&
  193. !IsEqualGUID(*pItemFromListGUID,cFileNode)
  194. )
  195. {
  196. continue;
  197. }
  198. } else if (IsEqualGUID(*pItemGUID,cServiceCollectorNode))
  199. {
  200. if (IsEqualGUID(*pItemGUID,*pItemFromListGUID))
  201. {
  202. // if we found our own type...
  203. continue;
  204. }
  205. // could have these type below it
  206. if (!IsEqualGUID(*pItemFromListGUID,cInstanceCollectorNode) &&
  207. !IsEqualGUID(*pItemFromListGUID,cInstanceNode) &&
  208. !IsEqualGUID(*pItemFromListGUID,cChildNode) &&
  209. !IsEqualGUID(*pItemFromListGUID,cFileNode)
  210. )
  211. {
  212. continue;
  213. }
  214. } else if (IsEqualGUID(*pItemGUID,cCompMgmtService))
  215. {
  216. // who knows...
  217. }
  218. // check if this item is below the parent item's chain
  219. // of command...
  220. // Get that items parent and check if it's cookie
  221. // points to our object.
  222. // Check if the parent node points to us!
  223. BOOL bMatchedParent = FALSE;
  224. SCOPEDATAITEM si;
  225. ::ZeroMemory(&si, sizeof(SCOPEDATAITEM));
  226. si.mask = SDI_PARAM;
  227. si.ID = pItemFromListAsNode->QueryScopeItem();;
  228. if (SUCCEEDED(pConsoleNameSpace->GetItem(&si)))
  229. {
  230. // walk up the item's parentpath and see if our object is one of them...
  231. INT ICount = 0;
  232. HSCOPEITEM hSI = si.ID;
  233. LONG_PTR lCookie = 0;
  234. HRESULT hr = S_OK;
  235. while (hSI)
  236. {
  237. HSCOPEITEM hSITemp = 0;
  238. ICount++;
  239. if (ICount > 30)
  240. {
  241. // possible infinite loop
  242. break;
  243. }
  244. hr = pConsoleNameSpace->GetParentItem(hSI, &hSITemp, &lCookie);
  245. if (FAILED(hr))
  246. {
  247. break;
  248. }
  249. if ( (LONG_PTR) pItem == lCookie)
  250. {
  251. bMatchedParent = TRUE;
  252. break;
  253. }
  254. hSI = hSITemp;
  255. }
  256. }
  257. if (bMatchedParent)
  258. {
  259. bFound = TRUE;
  260. iOrphanedCount++;
  261. // Mark it as orphaned by
  262. // Erasing it's ScopeItem or ResultItem
  263. if (bOrphan)
  264. {
  265. pItemFromList->ResetScopeItem();
  266. pItemFromList->ResetResultItem();
  267. }
  268. // continue on to the next one...
  269. }
  270. }
  271. }
  272. if (iOrphanedCount > 0)
  273. {
  274. DebugTrace(_T("Orphaned PropertySheets=%d\r\n"),iOrphanedCount);
  275. }
  276. return iOrphanedCount;
  277. }
  278. //
  279. // WARNING: this function will not really be helpfull
  280. // if the objects have already been removed...
  281. //
  282. BOOL
  283. CPropertySheetTracker::IsPropertySheetOpenBelowMe(CComPtr<IConsoleNameSpace> pConsoleNameSpace,CIISObject * pItem,CIISObject ** ppItemReturned)
  284. {
  285. BOOL bFound = FALSE;
  286. POSITION pos;
  287. // Loop thru all the open property sheets
  288. // and see if there is a property sheet that is below me.
  289. GUID * pItemFromListGUID = NULL;
  290. CIISObject * pItemFromList = NULL;
  291. CIISMBNode * pItemFromListAsNode = NULL;
  292. CIISMachine * pItemFromListOwner = NULL;
  293. GUID * pItemGUID = NULL;
  294. CIISMBNode * pItemAsNode = NULL;
  295. CIISMachine * pItemOwner = NULL;
  296. if (!ppItemReturned)
  297. {
  298. return FALSE;
  299. }
  300. pItemGUID = (GUID*) pItem->GetNodeType();
  301. if (IsEqualGUID(*pItemGUID,cInternetRootNode) || IsEqualGUID(*pItemGUID,cMachineNode))
  302. {
  303. // they should be using a different funciton...
  304. return IsPropertySheetOpenComputer(pItem,FALSE,ppItemReturned);
  305. }
  306. // check if it's a leaf node...
  307. if (pItem->IsLeafNode())
  308. {
  309. //cWebServiceExtensionContainer
  310. //cWebServiceExtension
  311. //cApplicationNode
  312. //cFileNode
  313. return FALSE;
  314. }
  315. pItemAsNode = (CIISMBNode *) pItem;
  316. pItemOwner = pItemAsNode->GetOwner();
  317. pos = IISObjectOpenPropertySheets.GetHeadPosition();
  318. while (pos)
  319. {
  320. pItemFromList = IISObjectOpenPropertySheets.GetNext(pos);
  321. if (pItemFromList)
  322. {
  323. // Get Owner, if the owner Pointer
  324. // matches our passed in CIISObject
  325. // then this must be open for this computer...
  326. pItemFromListAsNode = (CIISMBNode *) pItemFromList;
  327. if (!pItemFromListAsNode)
  328. {
  329. // got a bad pointer to an object.
  330. // skip it...
  331. continue;
  332. }
  333. if (pItemFromListAsNode == pItem)
  334. {
  335. // we found ourself...
  336. // skip it
  337. continue;
  338. }
  339. pItemFromListOwner = pItemFromListAsNode->GetOwner();
  340. if (!pItemFromListOwner)
  341. {
  342. // object doesn't have an owner...
  343. // skip it
  344. continue;
  345. }
  346. if (pItemFromListOwner != pItemOwner)
  347. {
  348. // they have different owners
  349. // they must be from different machines..
  350. // skip it
  351. continue;
  352. }
  353. pItemFromListGUID = (GUID*) pItemFromListAsNode->GetNodeType();
  354. if (!pItemFromListGUID)
  355. {
  356. // object doesn't have a guid who knows what type it is!!!
  357. ASSERT("Error:Item Missing GUID!");
  358. //continue;
  359. }
  360. //
  361. // Determine what type of object
  362. // we are checking, and cater to that object
  363. //
  364. if (IsEqualGUID(*pItemGUID,cWebServiceExtensionContainer))
  365. {
  366. if (IsEqualGUID(*pItemGUID,*pItemFromListGUID))
  367. {
  368. // if we found our own type...
  369. continue;
  370. }
  371. if (IsEqualGUID(*pItemFromListGUID,cWebServiceExtension))
  372. {
  373. if (pItemFromList->IsMyPropertySheetOpen())
  374. {
  375. bFound = TRUE;
  376. *ppItemReturned = pItemFromList;
  377. break;
  378. }
  379. }
  380. continue;
  381. } else if (IsEqualGUID(*pItemGUID,cAppPoolNode))
  382. {
  383. if (IsEqualGUID(*pItemGUID,*pItemFromListGUID))
  384. {
  385. // if we found our own type...
  386. continue;
  387. }
  388. if (IsEqualGUID(*pItemFromListGUID,cApplicationNode))
  389. {
  390. if (pItemFromList->IsMyPropertySheetOpen())
  391. {
  392. bFound = TRUE;
  393. *ppItemReturned = pItemFromList;
  394. break;
  395. }
  396. }
  397. continue;
  398. } else if (IsEqualGUID(*pItemGUID,cAppPoolsNode))
  399. {
  400. if (IsEqualGUID(*pItemGUID,*pItemFromListGUID))
  401. {
  402. // if we found our own type...
  403. continue;
  404. }
  405. if (IsEqualGUID(*pItemFromListGUID,cAppPoolNode) ||
  406. IsEqualGUID(*pItemFromListGUID,cApplicationNode)
  407. )
  408. {
  409. if (pItemFromList->IsMyPropertySheetOpen())
  410. {
  411. bFound = TRUE;
  412. *ppItemReturned = pItemFromList;
  413. break;
  414. }
  415. }
  416. continue;
  417. } else if (IsEqualGUID(*pItemGUID,cInstanceNode))
  418. {
  419. if (IsEqualGUID(*pItemGUID,*pItemFromListGUID))
  420. {
  421. // if we found our own type...
  422. continue;
  423. }
  424. if (!IsEqualGUID(*pItemFromListGUID,cChildNode) &&
  425. !IsEqualGUID(*pItemFromListGUID,cFileNode)
  426. )
  427. {
  428. continue;
  429. }
  430. } else if (IsEqualGUID(*pItemGUID,cInstanceCollectorNode))
  431. {
  432. if (IsEqualGUID(*pItemGUID,*pItemFromListGUID))
  433. {
  434. // if we found our own type...
  435. continue;
  436. }
  437. if (!IsEqualGUID(*pItemFromListGUID,cInstanceNode) &&
  438. !IsEqualGUID(*pItemFromListGUID,cChildNode) &&
  439. !IsEqualGUID(*pItemFromListGUID,cFileNode)
  440. )
  441. {
  442. continue;
  443. }
  444. } else if (IsEqualGUID(*pItemGUID,cServiceCollectorNode))
  445. {
  446. if (IsEqualGUID(*pItemGUID,*pItemFromListGUID))
  447. {
  448. // if we found our own type...
  449. continue;
  450. }
  451. // could have these type below it
  452. if (!IsEqualGUID(*pItemFromListGUID,cInstanceCollectorNode) &&
  453. !IsEqualGUID(*pItemFromListGUID,cInstanceNode) &&
  454. !IsEqualGUID(*pItemFromListGUID,cChildNode) &&
  455. !IsEqualGUID(*pItemFromListGUID,cFileNode)
  456. )
  457. {
  458. continue;
  459. }
  460. } else if (IsEqualGUID(*pItemGUID,cCompMgmtService))
  461. {
  462. // who knows...
  463. }
  464. // check if this item is below the parent item's chain
  465. // of command...
  466. // Get that items parent and check if it's cookie
  467. // points to our object.
  468. // Check if the parent node points to us!
  469. BOOL bMatchedParent = FALSE;
  470. SCOPEDATAITEM si;
  471. ::ZeroMemory(&si, sizeof(SCOPEDATAITEM));
  472. si.mask = SDI_PARAM;
  473. si.ID = pItemFromListAsNode->QueryScopeItem();;
  474. if (SUCCEEDED(pConsoleNameSpace->GetItem(&si)))
  475. {
  476. // walk up the item's parentpath and see if our object is one of them...
  477. INT ICount = 0;
  478. HSCOPEITEM hSI = si.ID;
  479. LONG_PTR lCookie = 0;
  480. HRESULT hr = S_OK;
  481. while (hSI)
  482. {
  483. HSCOPEITEM hSITemp = 0;
  484. ICount++;
  485. if (ICount > 30)
  486. {
  487. // possible infinite loop
  488. ASSERT("ERROR:possible infinite loop");
  489. break;
  490. }
  491. hr = pConsoleNameSpace->GetParentItem(hSI, &hSITemp, &lCookie);
  492. if (FAILED(hr))
  493. {
  494. break;
  495. }
  496. if ( (LONG_PTR) pItem == lCookie)
  497. {
  498. bMatchedParent = TRUE;
  499. break;
  500. }
  501. hSI = hSITemp;
  502. }
  503. }
  504. if (bMatchedParent)
  505. {
  506. if (pItemFromList->IsMyPropertySheetOpen())
  507. {
  508. if (ppItemReturned)
  509. {
  510. bFound = TRUE;
  511. *ppItemReturned = pItemFromList;
  512. break;
  513. }
  514. }
  515. }
  516. }
  517. }
  518. if (bFound)
  519. {
  520. DebugTrace(_T("Found item (%p) with propertypage below parent(%p)\r\n"),*ppItemReturned,pItem);
  521. }
  522. return bFound;
  523. }
  524. BOOL
  525. CPropertySheetTracker::IsPropertySheetOpenComputer(CIISObject * pItem,BOOL bIncludeComputerNode,CIISObject ** ppItemReturned)
  526. {
  527. BOOL bFound = FALSE;
  528. BOOL bGuidIsMachine = FALSE;
  529. // Loop thru all the open property sheets
  530. // and see if there is a property sheet that is under the computer node.
  531. GUID * pItemFromListGUID = NULL;
  532. CIISObject * pItemFromList = NULL;
  533. CIISMBNode * pItemFromListAsNode = NULL;
  534. CIISMachine * pOwner = NULL;
  535. POSITION pos = IISObjectOpenPropertySheets.GetHeadPosition();
  536. while (pos)
  537. {
  538. pItemFromList = IISObjectOpenPropertySheets.GetNext(pos);
  539. if (pItemFromList)
  540. {
  541. // Get Owner, if the owner Pointer
  542. // matches our passed in CIISObject
  543. // then this must be open for this computer...
  544. pItemFromListAsNode = (CIISMBNode *) pItemFromList;
  545. if (pItemFromListAsNode)
  546. {
  547. pOwner = pItemFromListAsNode->GetOwner();
  548. if (pOwner)
  549. {
  550. if (pOwner == pItem)
  551. {
  552. // Get GUID Name and make sure it's not
  553. // a CIISRoot or CIISMachine node.
  554. bGuidIsMachine = FALSE;
  555. pItemFromListGUID = (GUID*) pItemFromListAsNode->GetNodeType();
  556. if (pItemFromListGUID)
  557. {
  558. if (IsEqualGUID(*pItemFromListGUID,cInternetRootNode) || IsEqualGUID(*pItemFromListGUID,cMachineNode))
  559. {
  560. // oh well, we don't want these...
  561. bGuidIsMachine = TRUE;
  562. }
  563. }
  564. // But if we want to check if the
  565. // computer node is also open
  566. // then they would have set this parameter
  567. if (bIncludeComputerNode)
  568. {
  569. bGuidIsMachine = FALSE;
  570. }
  571. if (!bGuidIsMachine)
  572. {
  573. if (pItemFromList->IsMyPropertySheetOpen())
  574. {
  575. if (ppItemReturned)
  576. {
  577. bFound = TRUE;
  578. *ppItemReturned = pItemFromList;
  579. break;
  580. }
  581. }
  582. }
  583. }
  584. }
  585. }
  586. }
  587. }
  588. return bFound;
  589. }
  590. BOOL
  591. CPropertySheetTracker::FindAlreadyOpenPropertySheet(CIISObject * pItem,CIISObject ** ppItemReturned)
  592. {
  593. BOOL bFound = FALSE;
  594. POSITION pos;
  595. // Loop thru all the open property sheets
  596. // and see if there is a property sheet that is US
  597. GUID * pItemFromListGUID = NULL;
  598. CIISObject * pItemFromList = NULL;
  599. CIISMBNode * pItemFromListAsNode = NULL;
  600. CIISMachine * pItemFromListOwner = NULL;
  601. CComBSTR bstrItemFromListPath;
  602. GUID * pItemGUID = NULL;
  603. CIISMBNode * pItemAsNode = NULL;
  604. CIISMachine * pItemOwner = NULL;
  605. CComBSTR bstrItemPath;
  606. if (!ppItemReturned)
  607. {
  608. ASSERT("Error:FindAlreadyOpenPropertySheet:Bad Param");
  609. return FALSE;
  610. }
  611. if (!pItem->IsConfigurable())
  612. {
  613. return FALSE;
  614. }
  615. // make sure the item we are checking has a tag set
  616. pItem->CreateTag();
  617. pItemGUID = (GUID*) pItem->GetNodeType();
  618. pItemAsNode = (CIISMBNode *) pItem;
  619. pItemOwner = pItemAsNode->GetOwner();
  620. pos = IISObjectOpenPropertySheets.GetHeadPosition();
  621. while (pos)
  622. {
  623. pItemFromList = IISObjectOpenPropertySheets.GetNext(pos);
  624. if (pItemFromList)
  625. {
  626. // Get Owner, if the owner Pointer
  627. // matches our passed in CIISObject
  628. // then this must be open for this computer...
  629. pItemFromListAsNode = (CIISMBNode *) pItemFromList;
  630. if (!pItemFromListAsNode)
  631. {
  632. // got a bad pointer to an object.
  633. // skip it...
  634. continue;
  635. }
  636. if (pItemFromListAsNode == pItem)
  637. {
  638. // we found ourself!!!!
  639. // that's what we're looking for!
  640. bFound = TRUE;
  641. *ppItemReturned = pItem;
  642. break;
  643. }
  644. pItemFromListOwner = pItemFromListAsNode->GetOwner();
  645. if (!pItemFromListOwner)
  646. {
  647. // object doesn't have an owner...
  648. // skip it
  649. continue;
  650. }
  651. if (pItemFromListOwner != pItemOwner)
  652. {
  653. // they have different owners
  654. // they must be from different machines..
  655. // skip it
  656. continue;
  657. }
  658. pItemFromListGUID = (GUID*) pItemFromListAsNode->GetNodeType();
  659. if (!pItemFromListGUID)
  660. {
  661. // object doesn't have a guid who knows what type it is!!!
  662. ASSERT("Error:Item Missing GUID");
  663. //continue;
  664. }
  665. if (!IsEqualGUID(*pItemGUID,*pItemFromListGUID))
  666. {
  667. // if we found our own type...
  668. // that's what we're sort of looking for
  669. continue;
  670. }
  671. if (!pItemFromList->IsConfigurable())
  672. {
  673. // can't bring up property sheets on these anyways...
  674. continue;
  675. }
  676. // Check if the tag matches
  677. // THIS SHOULD TAKE CARE OF EVERYTHING
  678. if (0 == _tcsicmp(pItem->m_strTag,pItemFromList->m_strTag))
  679. {
  680. DebugTrace(_T("Found matching tag:%s\r\n"),pItem->m_strTag);
  681. if (pItemFromList->IsMyPropertySheetOpen())
  682. {
  683. // that's what we're looking for!
  684. bFound = TRUE;
  685. *ppItemReturned = pItemFromList;
  686. break;
  687. }
  688. }
  689. }
  690. }
  691. if (TRUE == bFound)
  692. {
  693. DebugTrace(_T("FindAlreadyOpenPropertySheet:Found, object=%p, existing obj=%p\r\n"),pItem,pItemFromList);
  694. }
  695. return bFound;
  696. }