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.

1028 lines
26 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1998 **/
  4. /**********************************************************************/
  5. /*
  6. ccompont.cpp
  7. base classes for IComponent and IComponentData
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "extract.h"
  12. #include "compdata.h"
  13. #include "proppage.h"
  14. #include "tregkey.h"
  15. #ifdef _DEBUG
  16. #define new DEBUG_NEW
  17. #undef THIS_FILE
  18. static char THIS_FILE[] = __FILE__;
  19. #endif
  20. /*!--------------------------------------------------------------------------
  21. FUseTaskpadsByDefault
  22. See comments in header file.
  23. Author: KennT
  24. ---------------------------------------------------------------------------*/
  25. BOOL FUseTaskpadsByDefault(LPCTSTR pszMachineName)
  26. {
  27. static DWORD s_dwStopTheInsanity = 42;
  28. RegKey regkeyMMC;
  29. DWORD dwErr;
  30. if (s_dwStopTheInsanity == 42)
  31. {
  32. // Set the default to FALSE (i.e. use taskpads by default)
  33. // ------------------------------------------------------------
  34. s_dwStopTheInsanity = 0;
  35. dwErr = regkeyMMC.Open(HKEY_LOCAL_MACHINE,
  36. _T("Software\\Microsoft\\MMC"),
  37. KEY_READ, pszMachineName);
  38. if (dwErr == ERROR_SUCCESS)
  39. {
  40. regkeyMMC.QueryValue(_T("TFSCore_StopTheInsanity"), s_dwStopTheInsanity);
  41. }
  42. }
  43. return !s_dwStopTheInsanity;
  44. }
  45. /*!--------------------------------------------------------------------------
  46. IComponentData implementation
  47. ---------------------------------------------------------------------------*/
  48. DEBUG_DECLARE_INSTANCE_COUNTER(TFSComponentData);
  49. /*!--------------------------------------------------------------------------
  50. TFSComponentData::TFSComponentData
  51. Constructor.
  52. Author: KennT
  53. ---------------------------------------------------------------------------*/
  54. TFSComponentData::TFSComponentData()
  55. : m_cRef(1),
  56. m_pWatermarkInfo(NULL)
  57. {
  58. DEBUG_INCREMENT_INSTANCE_COUNTER(TFSComponentData);
  59. m_hWnd = NULL;
  60. m_bFirstTimeRun = FALSE;
  61. m_fTaskpadInitialized = FALSE;
  62. }
  63. /*!--------------------------------------------------------------------------
  64. TFSComponentData::~TFSComponentData
  65. Destructor
  66. Author: KennT
  67. ---------------------------------------------------------------------------*/
  68. TFSComponentData::~TFSComponentData()
  69. {
  70. DEBUG_DECREMENT_INSTANCE_COUNTER(TFSComponentData);
  71. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  72. if (m_hiddenWnd.GetSafeHwnd())
  73. ::DestroyWindow(m_hiddenWnd.GetSafeHwnd());
  74. Assert(m_cRef == 0);
  75. }
  76. /*!--------------------------------------------------------------------------
  77. TFSComponentData::Construct
  78. Call this to fully initialize this object.
  79. Author: KennT
  80. ---------------------------------------------------------------------------*/
  81. HRESULT TFSComponentData::Construct(ITFSCompDataCallback *pCallback)
  82. {
  83. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  84. HRESULT hr = hrOK;
  85. COM_PROTECT_TRY
  86. {
  87. m_spCallback.Set(pCallback);
  88. // Create the node mgr
  89. CORg( CreateTFSNodeMgr(&m_spNodeMgr,
  90. (IComponentData *) this,
  91. m_spConsole,
  92. m_spConsoleNameSpace));
  93. // Initialize the node manager by pasing the ptr to ourselves
  94. // in
  95. CORg( m_spCallback->OnInitializeNodeMgr(
  96. static_cast<ITFSComponentData *>(this),
  97. m_spNodeMgr) );
  98. COM_PROTECT_ERROR_LABEL;
  99. }
  100. COM_PROTECT_CATCH;
  101. return hr;
  102. }
  103. IMPLEMENT_ADDREF_RELEASE(TFSComponentData)
  104. /*!--------------------------------------------------------------------------
  105. TFSComponentData::QueryInterface
  106. Implementation of IUnknown::QueryInterface
  107. Author: KennT
  108. ---------------------------------------------------------------------------*/
  109. STDMETHODIMP TFSComponentData::QueryInterface(REFIID riid, LPVOID *ppv)
  110. {
  111. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  112. // Is the pointer bad?
  113. if (ppv == NULL)
  114. return E_INVALIDARG;
  115. // Place NULL in *ppv in case of failure
  116. *ppv = NULL;
  117. // This is the non-delegating IUnknown implementation
  118. if (riid == IID_IUnknown)
  119. *ppv = (LPVOID) this;
  120. else if (riid == IID_IComponentData)
  121. *ppv = (IComponentData *) this;
  122. else if (riid == IID_IExtendPropertySheet)
  123. *ppv = (IExtendPropertySheet *) this;
  124. else if (riid == IID_IExtendPropertySheet2)
  125. *ppv = (IExtendPropertySheet2 *) this;
  126. else if (riid == IID_IExtendContextMenu)
  127. *ppv = (IExtendContextMenu *) this;
  128. else if (riid == IID_IPersistStreamInit)
  129. *ppv = (IPersistStreamInit *) this;
  130. else if (riid == IID_ISnapinHelp)
  131. *ppv = (ISnapinHelp *) this;
  132. else if (riid == IID_ITFSComponentData)
  133. *ppv = (ITFSComponentData *) this;
  134. // If we're going to return an interface, AddRef it first
  135. if (*ppv)
  136. {
  137. ((LPUNKNOWN) *ppv)->AddRef();
  138. return hrOK;
  139. }
  140. else
  141. return E_NOINTERFACE;
  142. }
  143. TFSCORE_API(HRESULT) ExtractNodeFromDataObject(ITFSNodeMgr *pNodeMgr,
  144. const CLSID *pClsid,
  145. LPDATAOBJECT pDataObject,
  146. BOOL fCheckForCreate,
  147. ITFSNode **ppNode,
  148. DWORD *pdwType,
  149. INTERNAL **ppInternal)
  150. {
  151. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  152. Assert(pNodeMgr);
  153. Assert(pClsid);
  154. Assert(ppNode);
  155. SPINTERNAL spInternal = ExtractInternalFormat(pDataObject);
  156. BOOL bExtension;
  157. MMC_COOKIE cookie;
  158. SPITFSNode spNode;
  159. SPITFSNodeHandler spNodeHandler;
  160. HRESULT hr = hrOK;
  161. // Set the default value
  162. if (pdwType)
  163. *pdwType |= TFS_COMPDATA_NORMAL;
  164. if (ppInternal)
  165. *ppInternal = NULL;
  166. //
  167. // No pInternal means that we are an extension and this is
  168. // our root node... translate by calling find object
  169. //
  170. // Check the CLSID for a match (because we are in shared code
  171. // multiple snapins are using the SNAPIN_INTERNAL format). Thus
  172. // we need to do an extra check to make sure that this is really us.
  173. //
  174. if ((spInternal == NULL) || (*pClsid != spInternal->m_clsid) )
  175. {
  176. CORg( pNodeMgr->GetRootNode(&spNode) );
  177. if (pdwType)
  178. {
  179. *pdwType |= (TFS_COMPDATA_EXTENSION | TFS_COMPDATA_UNKNOWN_DATAOBJECT);
  180. }
  181. }
  182. else
  183. {
  184. DATA_OBJECT_TYPES type = spInternal->m_type;
  185. if (fCheckForCreate && type == CCT_SNAPIN_MANAGER)
  186. {
  187. CORg( pNodeMgr->GetRootNode(&spNode) );
  188. //$ Review (kennt): is this always true, can we always
  189. // depend on a create node being available?
  190. Assert(spNode);
  191. if (pdwType)
  192. *pdwType |= TFS_COMPDATA_CREATE;
  193. }
  194. else
  195. {
  196. if (pdwType && (spInternal->m_clsid != *pClsid))
  197. *pdwType |= TFS_COMPDATA_EXTENSION;
  198. cookie = spInternal->m_cookie;
  199. CORg( pNodeMgr->FindNode(cookie, &spNode) );
  200. Assert((MMC_COOKIE) spNode->GetData(TFS_DATA_COOKIE) == cookie);
  201. }
  202. }
  203. if (ppInternal)
  204. *ppInternal = spInternal.Transfer();
  205. *ppNode = spNode.Transfer();
  206. Error:
  207. return hr;
  208. }
  209. /*!--------------------------------------------------------------------------
  210. TFSComponentData::Initialize
  211. Implementation of IComponentData::Initialize
  212. MMC calls this to initialize the IComponentData interface
  213. Author:
  214. ---------------------------------------------------------------------------*/
  215. STDMETHODIMP TFSComponentData::Initialize
  216. (
  217. LPUNKNOWN pUnk
  218. )
  219. {
  220. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  221. Assert(pUnk != NULL);
  222. HRESULT hr = hrOK;
  223. COM_PROTECT_TRY
  224. {
  225. // MMC should only call ::Initialize once!
  226. Assert(m_spConsoleNameSpace == NULL);
  227. pUnk->QueryInterface(IID_IConsoleNameSpace2,
  228. reinterpret_cast<void**>(&m_spConsoleNameSpace));
  229. Assert(m_spConsoleNameSpace);
  230. // add the images for the scope tree
  231. SPIImageList spScopeImageList;
  232. CORg( pUnk->QueryInterface(IID_IConsole2,
  233. reinterpret_cast<void**>(&m_spConsole)) );
  234. CORg( m_spConsole->QueryScopeImageList(&spScopeImageList) );
  235. // call the derived class
  236. Assert(m_spCallback);
  237. CORg( m_spCallback->OnInitialize(spScopeImageList) );
  238. // Create the utility members
  239. if (!m_hiddenWnd.GetSafeHwnd())
  240. {
  241. if (!m_hiddenWnd.Create())
  242. {
  243. Trace0("Failed to create hidden window\n");
  244. CORg( E_FAIL );
  245. }
  246. m_hWnd = m_hiddenWnd.GetSafeHwnd();
  247. }
  248. Assert(m_hWnd);
  249. // Setup the node mgr
  250. // As strange as it seems, the Initialize() method is not
  251. // necessarily the first function called.
  252. Assert(m_spNodeMgr);
  253. m_spNodeMgr->SetConsole(m_spConsoleNameSpace, m_spConsole);
  254. COM_PROTECT_ERROR_LABEL;
  255. }
  256. COM_PROTECT_CATCH;
  257. if (!FHrSucceeded(hr))
  258. {
  259. m_spNodeMgr.Release();
  260. m_spConsoleNameSpace.Release();
  261. m_spConsole.Release();
  262. }
  263. return hr;
  264. }
  265. /*!--------------------------------------------------------------------------
  266. TFSComponentData::CreateComponent
  267. Implementation of IComponentData::CreateComponent
  268. Author: KennT
  269. ---------------------------------------------------------------------------*/
  270. STDMETHODIMP TFSComponentData::CreateComponent(LPCOMPONENT *ppComponent)
  271. {
  272. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  273. return m_spCallback->OnCreateComponent(ppComponent);
  274. }
  275. /*!--------------------------------------------------------------------------
  276. TFSComponentData::Notify
  277. Implementation of IComponentData::Notify
  278. Author: KennT
  279. ---------------------------------------------------------------------------*/
  280. STDMETHODIMP TFSComponentData::Notify(LPDATAOBJECT lpDataObject,
  281. MMC_NOTIFY_TYPE event,
  282. LPARAM arg, LPARAM lParam)
  283. {
  284. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  285. Assert(m_spConsoleNameSpace != NULL);
  286. HRESULT hr = hrOK;
  287. SPITFSNode spNode;
  288. SPITFSNodeHandler spNodeHandler;
  289. DWORD dwType = 0;
  290. COM_PROTECT_TRY
  291. {
  292. if (event == MMCN_PROPERTY_CHANGE)
  293. {
  294. hr = m_spCallback->OnNotifyPropertyChange(lpDataObject, event, arg, lParam);
  295. if (hr != E_NOTIMPL)
  296. {
  297. return hr;
  298. }
  299. CPropertyPageHolderBase * pHolder =
  300. reinterpret_cast<CPropertyPageHolderBase *>(lParam);
  301. spNode = pHolder->GetNode();
  302. }
  303. else
  304. {
  305. //
  306. // Since it's my folder it has an internal format.
  307. // Design Note: for extension. I can use the fact, that the
  308. // data object doesn't have my internal format and I should
  309. // look at the node type and see how to extend it.
  310. //
  311. CORg( ExtractNodeFromDataObject(m_spNodeMgr,
  312. m_spCallback->GetCoClassID(),
  313. lpDataObject,
  314. FALSE,
  315. &spNode,
  316. &dwType,
  317. NULL) );
  318. }
  319. // pass the event to the event handler
  320. Assert(spNode);
  321. CORg( spNode->GetHandler(&spNodeHandler) );
  322. CORg( spNodeHandler->Notify(spNode, lpDataObject, dwType, event, arg, lParam) );
  323. COM_PROTECT_ERROR_LABEL;
  324. }
  325. COM_PROTECT_CATCH;
  326. return hr;
  327. }
  328. /*!--------------------------------------------------------------------------
  329. TFSComponentData::Destroy
  330. Implementation of IComponentData::Destroy
  331. Author: KennT
  332. ---------------------------------------------------------------------------*/
  333. STDMETHODIMP TFSComponentData::Destroy()
  334. {
  335. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  336. SPITFSNode spNode;
  337. HRESULT hr = hrOK;
  338. COM_PROTECT_TRY
  339. {
  340. if (m_spCallback)
  341. m_spCallback->OnDestroy();
  342. m_spConsole.Release();
  343. m_spConsoleNameSpace.Release();
  344. if (m_spNodeMgr)
  345. {
  346. m_spNodeMgr->GetRootNode(&spNode);
  347. if (spNode)
  348. {
  349. spNode->DeleteAllChildren(FALSE);
  350. spNode->Destroy();
  351. }
  352. spNode.Release();
  353. m_spNodeMgr->SetRootNode(NULL);
  354. }
  355. m_spNodeMgr.Release();
  356. m_spCallback.Release();
  357. }
  358. COM_PROTECT_CATCH;
  359. return hr;
  360. }
  361. /*!--------------------------------------------------------------------------
  362. TFSComponentData::QueryDataObject
  363. Implementation of IComponentData::QueryDataObject
  364. MMC calls this to get a data object from us to hand us data in
  365. Author: KennT
  366. ---------------------------------------------------------------------------*/
  367. STDMETHODIMP TFSComponentData::QueryDataObject(MMC_COOKIE cookie,
  368. DATA_OBJECT_TYPES type,
  369. LPDATAOBJECT *ppDataObject)
  370. {
  371. return m_spCallback->OnCreateDataObject(cookie, type, ppDataObject);
  372. }
  373. /*!--------------------------------------------------------------------------
  374. TFSComponentData::CompareObjects
  375. Implementation of IComponentData::CompareObject
  376. Author: KennT
  377. ---------------------------------------------------------------------------*/
  378. STDMETHODIMP TFSComponentData::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  379. {
  380. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  381. if (lpDataObjectA == NULL || lpDataObjectB == NULL)
  382. return E_POINTER;
  383. // Make sure both data object are mine
  384. SPINTERNAL spA;
  385. SPINTERNAL spB;
  386. HRESULT hr = S_FALSE;
  387. COM_PROTECT_TRY
  388. {
  389. spA = ExtractInternalFormat(lpDataObjectA);
  390. spB = ExtractInternalFormat(lpDataObjectA);
  391. if (spA != NULL && spB != NULL)
  392. hr = (*spA == *spB) ? S_OK : S_FALSE;
  393. }
  394. COM_PROTECT_CATCH;
  395. return hr;
  396. }
  397. /*!--------------------------------------------------------------------------
  398. TFSComponentData::GetDisplayInfo
  399. Implementation of IComponentData::GetDisplayInfo
  400. MMC calls this to get the display string for scope items
  401. Author: KennT
  402. ---------------------------------------------------------------------------*/
  403. STDMETHODIMP TFSComponentData::GetDisplayInfo(LPSCOPEDATAITEM pScopeDataItem)
  404. {
  405. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  406. wchar_t* pswzString = NULL;
  407. Assert(pScopeDataItem != NULL);
  408. SPITFSNode spNode;
  409. MMC_COOKIE cookie = pScopeDataItem->lParam;
  410. HRESULT hr = hrOK;
  411. COM_PROTECT_TRY
  412. {
  413. m_spNodeMgr->FindNode(cookie, &spNode);
  414. pswzString = const_cast<LPTSTR>(spNode->GetString(0));
  415. Assert(pswzString != NULL);
  416. //$ Review (kennt) : will need to convert string to Wide from Tchar
  417. //$ Review (kennt) : when do we free this string up?
  418. if (*pswzString != NULL)
  419. pScopeDataItem->displayname = pswzString;
  420. }
  421. COM_PROTECT_CATCH;
  422. return hr;
  423. }
  424. /*---------------------------------------------------------------------------
  425. IExtendPropertySheet Implementation
  426. ---------------------------------------------------------------------------*/
  427. /*!--------------------------------------------------------------------------
  428. TFSComponentData::CreatePropertyPages
  429. Implementation of IExtendPropertySheet::CreatePropertyPages
  430. Called for a node to put up property pages
  431. Author:
  432. ---------------------------------------------------------------------------*/
  433. STDMETHODIMP
  434. TFSComponentData::CreatePropertyPages
  435. (
  436. LPPROPERTYSHEETCALLBACK lpProvider,
  437. LONG_PTR handle,
  438. LPDATAOBJECT pDataObject
  439. )
  440. {
  441. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  442. SPITFSNode spNode;
  443. SPITFSNodeHandler spNodeHandler;
  444. HRESULT hr = hrOK;
  445. DWORD dwType = 0;
  446. SPINTERNAL spInternal;
  447. COM_PROTECT_TRY
  448. {
  449. spInternal = ExtractInternalFormat(pDataObject);
  450. // this was an object created by the modal wizard, do nothing
  451. if (spInternal && spInternal->m_type == CCT_UNINITIALIZED)
  452. {
  453. return hr;
  454. }
  455. CORg( ExtractNodeFromDataObject(m_spNodeMgr,
  456. m_spCallback->GetCoClassID(),
  457. pDataObject,
  458. TRUE, &spNode, &dwType, NULL) );
  459. //
  460. // Create the property page for a particular node
  461. //
  462. CORg( spNode->GetHandler(&spNodeHandler) );
  463. CORg( spNodeHandler->CreatePropertyPages(spNode, lpProvider,
  464. pDataObject,
  465. handle, dwType) );
  466. COM_PROTECT_ERROR_LABEL;
  467. }
  468. COM_PROTECT_CATCH;
  469. return hr;
  470. }
  471. /*!--------------------------------------------------------------------------
  472. TFSComponentData::QueryPagesFor
  473. Implementation of IExtendPropertySheet::QueryPagesFor
  474. MMC calls this to see if a node has property pages
  475. Author:
  476. ---------------------------------------------------------------------------*/
  477. STDMETHODIMP
  478. TFSComponentData::QueryPagesFor
  479. (
  480. LPDATAOBJECT pDataObject
  481. )
  482. {
  483. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  484. DATA_OBJECT_TYPES type;
  485. SPITFSNode spNode;
  486. SPITFSNodeHandler spNodeHandler;
  487. DWORD dwType = 0;
  488. SPINTERNAL spInternal;
  489. HRESULT hr = hrOK;
  490. COM_PROTECT_TRY
  491. {
  492. spInternal = ExtractInternalFormat(pDataObject);
  493. // this was an object created by the modal wizard, do nothing
  494. if (spInternal && spInternal->m_type == CCT_UNINITIALIZED)
  495. {
  496. return hr;
  497. }
  498. CORg( ExtractNodeFromDataObject(m_spNodeMgr,
  499. m_spCallback->GetCoClassID(),
  500. pDataObject,
  501. TRUE, &spNode, &dwType, NULL) );
  502. if (spInternal)
  503. type = spInternal->m_type;
  504. else
  505. type = CCT_SCOPE;
  506. CORg( spNode->GetHandler(&spNodeHandler) );
  507. CORg( spNodeHandler->HasPropertyPages(spNode, pDataObject,
  508. type, dwType) );
  509. COM_PROTECT_ERROR_LABEL;
  510. }
  511. COM_PROTECT_CATCH;
  512. return hr;
  513. }
  514. /*!--------------------------------------------------------------------------
  515. TFSComponentData::GetWatermarks
  516. Implementation of IExtendPropertySheet::Watermarks
  517. MMC calls this for wizard 97 info
  518. Author:
  519. ---------------------------------------------------------------------------*/
  520. STDMETHODIMP
  521. TFSComponentData::GetWatermarks
  522. (
  523. LPDATAOBJECT pDataObject,
  524. HBITMAP * lphWatermark,
  525. HBITMAP * lphHeader,
  526. HPALETTE * lphPalette,
  527. BOOL * bStretch
  528. )
  529. {
  530. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  531. HRESULT hr = hrOK;
  532. COM_PROTECT_TRY
  533. {
  534. // set some defaults
  535. *lphWatermark = NULL;
  536. *lphHeader = NULL;
  537. *lphPalette = NULL;
  538. *bStretch = FALSE;
  539. if (m_pWatermarkInfo)
  540. {
  541. *lphWatermark = m_pWatermarkInfo->hWatermark;
  542. *lphHeader = m_pWatermarkInfo->hHeader;
  543. *lphPalette = m_pWatermarkInfo->hPalette;
  544. *bStretch = m_pWatermarkInfo->bStretch;
  545. }
  546. }
  547. COM_PROTECT_CATCH;
  548. return hr;
  549. }
  550. /*---------------------------------------------------------------------------
  551. IExtendContextMenu implementation
  552. ---------------------------------------------------------------------------*/
  553. /*!--------------------------------------------------------------------------
  554. TFSComponentData::AddMenuItems
  555. Implementation of IExtendContextMenu::AddMenuItems
  556. MMC calls this so that a node can add menu items to a context menu
  557. Author:
  558. ---------------------------------------------------------------------------*/
  559. STDMETHODIMP
  560. TFSComponentData::AddMenuItems
  561. (
  562. LPDATAOBJECT pDataObject,
  563. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  564. long * pInsertionAllowed
  565. )
  566. {
  567. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  568. HRESULT hr = S_OK;
  569. SPINTERNAL spInternal;
  570. DATA_OBJECT_TYPES type;
  571. SPITFSNode spNode;
  572. SPITFSNodeHandler spNodeHandler;
  573. DWORD dwType;
  574. COM_PROTECT_TRY
  575. {
  576. CORg( ExtractNodeFromDataObject(m_spNodeMgr,
  577. m_spCallback->GetCoClassID(),
  578. pDataObject,
  579. FALSE, &spNode, &dwType,
  580. &spInternal) );
  581. type = (spInternal ? spInternal->m_type : CCT_SCOPE);
  582. // Note - snap-ins need to look at the data object and determine
  583. // in what context, menu items need to be added. They must also
  584. // observe the insertion allowed flags to see what items can be
  585. // added.
  586. CORg( spNode->GetHandler(&spNodeHandler) );
  587. hr = spNodeHandler->OnAddMenuItems(spNode, pContextMenuCallback,
  588. pDataObject,
  589. type,
  590. dwType,
  591. pInsertionAllowed);
  592. COM_PROTECT_ERROR_LABEL;
  593. }
  594. COM_PROTECT_CATCH;
  595. return hr;
  596. }
  597. /*!--------------------------------------------------------------------------
  598. TFSComponentData::Command
  599. Implemenation of IExtendContextMenu::Command
  600. Command handler for any items added to a context menu
  601. Author:
  602. ---------------------------------------------------------------------------*/
  603. STDMETHODIMP
  604. TFSComponentData::Command
  605. (
  606. long nCommandID,
  607. LPDATAOBJECT pDataObject
  608. )
  609. {
  610. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  611. HRESULT hr = S_OK;
  612. SPINTERNAL spInternal;
  613. DATA_OBJECT_TYPES type;
  614. SPITFSNode spNode;
  615. SPITFSNodeHandler spNodeHandler;
  616. DWORD dwType;
  617. COM_PROTECT_TRY
  618. {
  619. CORg( ExtractNodeFromDataObject(m_spNodeMgr,
  620. m_spCallback->GetCoClassID(),
  621. pDataObject,
  622. FALSE, &spNode, &dwType,
  623. &spInternal) );
  624. type = (spInternal ? spInternal->m_type : CCT_SCOPE);
  625. CORg( spNode->GetHandler(&spNodeHandler) );
  626. hr = spNodeHandler->OnCommand(spNode, nCommandID,
  627. type,
  628. pDataObject,
  629. dwType);
  630. COM_PROTECT_ERROR_LABEL;
  631. }
  632. COM_PROTECT_CATCH;
  633. return hr;
  634. }
  635. /*---------------------------------------------------------------------------
  636. ISnapinHelp implementation
  637. ---------------------------------------------------------------------------*/
  638. /*!--------------------------------------------------------------------------
  639. TFSComponentData::GetHelpTopic
  640. Implementation of ISnapinHelp::GetHelpTopic
  641. MMC calls this so that a snapin can add it's .chm file to the main index
  642. Author: EricDav
  643. ---------------------------------------------------------------------------*/
  644. STDMETHODIMP
  645. TFSComponentData::GetHelpTopic
  646. (
  647. LPOLESTR* lpCompiledHelpFile
  648. )
  649. {
  650. HRESULT hr = S_OK;
  651. if (lpCompiledHelpFile == NULL)
  652. return E_INVALIDARG;
  653. LPCWSTR lpszHelpFileName = GetHTMLHelpFileName();
  654. if (lpszHelpFileName == NULL)
  655. {
  656. *lpCompiledHelpFile = NULL;
  657. return E_NOTIMPL;
  658. }
  659. CString szHelpFilePath;
  660. UINT nLen = ::GetWindowsDirectory (szHelpFilePath.GetBufferSetLength(2 * MAX_PATH), 2 * MAX_PATH);
  661. if (nLen == 0)
  662. return E_FAIL;
  663. szHelpFilePath.ReleaseBuffer();
  664. szHelpFilePath += L"\\help\\";
  665. szHelpFilePath += lpszHelpFileName;
  666. UINT nBytes = (szHelpFilePath.GetLength() + 1) * sizeof(WCHAR);
  667. *lpCompiledHelpFile = (LPOLESTR)::CoTaskMemAlloc(nBytes);
  668. if (*lpCompiledHelpFile)
  669. {
  670. memcpy(*lpCompiledHelpFile, (LPCWSTR)szHelpFilePath, nBytes);
  671. }
  672. else
  673. {
  674. hr = E_OUTOFMEMORY;
  675. }
  676. return hr;
  677. }
  678. STDMETHODIMP TFSComponentData::GetNodeMgr(ITFSNodeMgr **ppNodeMgr)
  679. {
  680. Assert(ppNodeMgr);
  681. SetI((LPUNKNOWN *) ppNodeMgr, m_spNodeMgr);
  682. return hrOK;
  683. }
  684. STDMETHODIMP TFSComponentData::GetConsole(IConsole2 **ppConsole)
  685. {
  686. Assert(ppConsole);
  687. SetI((LPUNKNOWN *) ppConsole, m_spConsole);
  688. return hrOK;
  689. }
  690. STDMETHODIMP TFSComponentData::GetConsoleNameSpace(IConsoleNameSpace2 **ppConsoleNS)
  691. {
  692. Assert(ppConsoleNS);
  693. SetI((LPUNKNOWN *) ppConsoleNS, m_spConsoleNameSpace);
  694. return hrOK;
  695. }
  696. STDMETHODIMP TFSComponentData::GetRootNode(ITFSNode **ppNode)
  697. {
  698. return m_spNodeMgr->GetRootNode(ppNode);
  699. }
  700. STDMETHODIMP_(const CLSID *) TFSComponentData::GetCoClassID()
  701. {
  702. Assert(m_spCallback);
  703. return m_spCallback->GetCoClassID();
  704. }
  705. STDMETHODIMP_(HWND) TFSComponentData::GetHiddenWnd()
  706. {
  707. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  708. if (!m_hiddenWnd.GetSafeHwnd())
  709. {
  710. m_hiddenWnd.Create();
  711. m_hWnd = m_hiddenWnd.GetSafeHwnd();
  712. }
  713. Assert(m_hWnd);
  714. return m_hWnd;
  715. }
  716. STDMETHODIMP_(LPWATERMARKINFO) TFSComponentData::SetWatermarkInfo(LPWATERMARKINFO pNewWatermarkInfo)
  717. {
  718. LPWATERMARKINFO pOldWatermarkInfo = m_pWatermarkInfo;
  719. m_pWatermarkInfo = pNewWatermarkInfo;
  720. return pOldWatermarkInfo;
  721. }
  722. STDMETHODIMP TFSComponentData::GetClassID(LPCLSID lpClassID)
  723. {
  724. Assert(m_spCallback);
  725. return m_spCallback->GetClassID(lpClassID);
  726. }
  727. STDMETHODIMP TFSComponentData::IsDirty()
  728. {
  729. Assert(m_spCallback);
  730. return m_spCallback->IsDirty();
  731. }
  732. STDMETHODIMP TFSComponentData::Load(LPSTREAM pStm)
  733. {
  734. Assert(m_spCallback);
  735. return m_spCallback->Load(pStm);
  736. }
  737. STDMETHODIMP TFSComponentData::Save(LPSTREAM pStm, BOOL fClearDirty)
  738. {
  739. Assert(m_spCallback);
  740. return m_spCallback->Save(pStm, fClearDirty);
  741. }
  742. STDMETHODIMP TFSComponentData::GetSizeMax(ULARGE_INTEGER FAR *pcbSize)
  743. {
  744. Assert(m_spCallback);
  745. return m_spCallback->GetSizeMax(pcbSize);
  746. }
  747. STDMETHODIMP TFSComponentData::InitNew()
  748. {
  749. Assert(m_spCallback);
  750. return m_spCallback->InitNew();
  751. }
  752. STDMETHODIMP
  753. TFSComponentData::SetTaskpadState(int nIndex, BOOL fEnable)
  754. {
  755. DWORD dwMask = 0x00000001 << nIndex;
  756. if (!m_fTaskpadInitialized)
  757. {
  758. // this will initialize the states to the deafult value
  759. GetTaskpadState(0);
  760. }
  761. if (fEnable)
  762. m_dwTaskpadStates |= dwMask;
  763. else
  764. m_dwTaskpadStates &= ~dwMask;
  765. return hrOK;
  766. }
  767. // taskpad states are kept track of on a pernode basis.
  768. // we can store up to 32 (DWORD) different node states here
  769. // if you don't want taskpads on a per node basis, always
  770. // pass an index of 0
  771. STDMETHODIMP_(BOOL)
  772. TFSComponentData::GetTaskpadState(int nIndex)
  773. {
  774. DWORD dwMask = 0x00000001 << nIndex;
  775. if (!m_fTaskpadInitialized)
  776. {
  777. // assume taskpads on
  778. BOOL fDefault = TRUE;
  779. m_fTaskpadInitialized = TRUE;
  780. // get the default state from MMC
  781. if (m_spConsole)
  782. fDefault = (m_spConsole->IsTaskpadViewPreferred() == S_OK) ? TRUE : FALSE;
  783. if (fDefault)
  784. {
  785. // now check our private override
  786. fDefault = FUseTaskpadsByDefault(NULL);
  787. }
  788. if (fDefault)
  789. m_dwTaskpadStates = 0xFFFFFFFF;
  790. else
  791. m_dwTaskpadStates = 0;
  792. }
  793. return m_dwTaskpadStates & dwMask;
  794. }
  795. STDMETHODIMP_(LPCTSTR)
  796. TFSComponentData::GetHTMLHelpFileName()
  797. {
  798. if (m_strHTMLHelpFileName.IsEmpty())
  799. return NULL;
  800. else
  801. return (LPCTSTR) m_strHTMLHelpFileName;
  802. }
  803. STDMETHODIMP
  804. TFSComponentData::SetHTMLHelpFileName(LPCTSTR pszHelpFileName)
  805. {
  806. m_strHTMLHelpFileName = pszHelpFileName;
  807. return S_OK;
  808. }
  809. TFSCORE_API(HRESULT) CreateTFSComponentData(IComponentData **ppCompData,
  810. ITFSCompDataCallback *pCallback)
  811. {
  812. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  813. TFSComponentData * pCompData = NULL;
  814. HRESULT hr = hrOK;
  815. COM_PROTECT_TRY
  816. {
  817. *ppCompData = NULL;
  818. pCompData = new TFSComponentData;
  819. CORg( pCompData->Construct(pCallback) );
  820. *ppCompData = static_cast<IComponentData *>(pCompData);
  821. (*ppCompData)->AddRef();
  822. COM_PROTECT_ERROR_LABEL;
  823. }
  824. COM_PROTECT_CATCH;
  825. // Note: to balance the AddRef()/Release() we Release() this pointer
  826. // even in the success case
  827. if (pCompData)
  828. pCompData->Release();
  829. return hr;
  830. }