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.

1954 lines
55 KiB

  1. /*--------------------------------------------------------------------------*
  2. *
  3. * Microsoft Windows
  4. * Copyright (C) Microsoft Corporation, 1999 - 1999
  5. *
  6. * File: fldrsnap.cpp
  7. *
  8. * Contents: Implementation file for built-in snapins that implement
  9. * the Folder, ActiveX Control, and Web Link nodes.
  10. * These replace earlier code that had special "built-in"
  11. * nodetypes.
  12. *
  13. * History: 23-Jul-98 vivekj Created
  14. *
  15. *--------------------------------------------------------------------------*/
  16. #include "stdafx.h"
  17. #include "tstring.h"
  18. #include "fldrsnap.h"
  19. #include "imageid.h"
  20. #include <comcat.h> // COM Component Categoories Manager
  21. #include "compcat.h"
  22. #include "guids.h"
  23. #include "regutil.h"
  24. #include "newnode.h"
  25. // These must now be the same - CMTNode::ScConvertLegacyNode depends on it.
  26. #define SZ_OCXSTREAM (L"ocx_streamorstorage")
  27. #define SZ_OCXSTORAGE (L"ocx_streamorstorage")
  28. /*+-------------------------------------------------------------------------*
  29. *
  30. * ScLoadAndAllocateString
  31. *
  32. * PURPOSE: Loads the string specified by the string ID and returns a string
  33. * whose storage has been allocated by CoTaskMemAlloc.
  34. *
  35. * PARAMETERS:
  36. * UINT ids :
  37. * LPOLESTR * lpstrOut :
  38. *
  39. * RETURNS:
  40. * SC
  41. *
  42. *+-------------------------------------------------------------------------*/
  43. SC
  44. ScLoadAndAllocateString(UINT ids, LPOLESTR *lpstrOut)
  45. {
  46. DECLARE_SC(sc, TEXT("ScLoadAndAllocateString"));
  47. sc = ScCheckPointers(lpstrOut);
  48. if(sc)
  49. return sc;
  50. USES_CONVERSION;
  51. CStr str;
  52. str.LoadString(GetStringModule(), ids);
  53. int cchStrOut = str.GetLength() +1;
  54. *lpstrOut = (LPOLESTR) CoTaskMemAlloc( cchStrOut *sizeof(OLECHAR) );
  55. if(*lpstrOut)
  56. {
  57. sc = StringCchCopyW(*lpstrOut, cchStrOut, T2CW(str));
  58. if(sc)
  59. return sc;
  60. }
  61. else
  62. sc = E_OUTOFMEMORY;
  63. return sc;
  64. }
  65. //############################################################################
  66. //############################################################################
  67. //
  68. // Implementation of class CSnapinDescriptor
  69. //
  70. //############################################################################
  71. //############################################################################
  72. /*+-------------------------------------------------------------------------*
  73. *
  74. * CSnapinDescriptor::CSnapinDescriptor
  75. *
  76. * PURPOSE: Constructor
  77. *
  78. *+-------------------------------------------------------------------------*/
  79. CSnapinDescriptor::CSnapinDescriptor()
  80. : m_idsName(0), m_idsDescription(0), m_idiSnapinImage(0), m_idbSmallImage(0), m_idbSmallImageOpen(0),
  81. m_idbLargeImage(0), m_clsidSnapin(GUID_NULL), m_szClsidSnapin(TEXT("")),
  82. m_guidNodetype(GUID_NULL), m_szGuidNodetype(TEXT("")), m_szClassName(TEXT("")),
  83. m_szProgID(TEXT("")), m_szVersionIndependentProgID(TEXT("")), m_viewOptions(0)
  84. {
  85. }
  86. CSnapinDescriptor::CSnapinDescriptor(UINT idsName, UINT idsDescription, UINT idiSnapinImage,
  87. UINT idbSmallImage,UINT idbSmallImageOpen, UINT idbLargeImage,
  88. const CLSID &clsidSnapin, LPCTSTR szClsidSnapin,
  89. const GUID &guidNodetype, LPCTSTR szGuidNodetype,
  90. LPCTSTR szClassName, LPCTSTR szProgID,
  91. LPCTSTR szVersionIndependentProgID,
  92. long viewOptions)
  93. : m_idsName(idsName), m_idsDescription(idsDescription), m_idiSnapinImage(idiSnapinImage),
  94. m_idbSmallImage(idbSmallImage), m_idbSmallImageOpen(idbSmallImageOpen),
  95. m_idbLargeImage(idbLargeImage), m_clsidSnapin(clsidSnapin), m_szClsidSnapin(szClsidSnapin),
  96. m_guidNodetype(guidNodetype), m_szGuidNodetype(szGuidNodetype), m_szClassName(szClassName),
  97. m_szProgID(szProgID), m_szVersionIndependentProgID(szVersionIndependentProgID),
  98. m_viewOptions(viewOptions)
  99. {
  100. }
  101. /*+-------------------------------------------------------------------------*
  102. * ScFormatIndirectSnapInName
  103. *
  104. * Returns the name of the snap-in in the indirect form supported by
  105. * SHLoadRegUIString:
  106. *
  107. * @<dllname>,-<strId>
  108. *--------------------------------------------------------------------------*/
  109. SC ScFormatIndirectSnapInName (
  110. HINSTANCE hInst, /* I:module containing the resource */
  111. int idNameString, /* I:ID of name's string resource */
  112. CStr& strName) /* O:formatted indirect name string */
  113. {
  114. DECLARE_SC (sc, _T("ScFormatIndirectSnapInName"));
  115. /*
  116. * allocate a buffer for GetModuleFileName
  117. */
  118. const int cchBuffer = MAX_PATH;
  119. WTL::CString strStringModule;
  120. LPTSTR szBuffer = strStringModule.GetBuffer (cchBuffer);
  121. /*
  122. * if we couldn't allocate a buffer, return an error
  123. */
  124. if (szBuffer == NULL)
  125. return (sc = E_OUTOFMEMORY);
  126. /*
  127. * get the name of the module that provides strings
  128. */
  129. const DWORD cbCopied = GetModuleFileName (hInst, szBuffer, cchBuffer);
  130. strStringModule.ReleaseBuffer();
  131. /*
  132. * if GetModuleFileName failed, return its failure code
  133. */
  134. if (cbCopied == 0)
  135. {
  136. sc.FromLastError();
  137. /*
  138. * just in case GetModuleFileName didn't set the last error, make
  139. * sure the SC contains some kind of failure code
  140. */
  141. if (!sc.IsError())
  142. sc = E_FAIL;
  143. return (sc);
  144. }
  145. /*
  146. * if a path is present, SHLoadRegUIString won't search for the DLL
  147. * based on the current UI language; remove the path portion of the
  148. * module name so it will
  149. */
  150. int nLastPathSep = strStringModule.ReverseFind (_T('\\'));
  151. if (nLastPathSep != -1)
  152. strStringModule = strStringModule.Mid (nLastPathSep + 1);
  153. /*
  154. * format the name the way SHLoadRegUIString expects it
  155. */
  156. strStringModule.MakeLower();
  157. strName.Format (_T("@%s,-%d"), (LPCTSTR) strStringModule, idNameString);
  158. return (sc);
  159. }
  160. /*+-------------------------------------------------------------------------*
  161. * CSnapinDescriptor::GetRegisteredIndirectName
  162. *
  163. * Returns the name of the snap-in in the indirect form supported by
  164. * SHLoadRegUIString:
  165. *
  166. * @<dllname>,-<strId>
  167. *--------------------------------------------------------------------------*/
  168. void
  169. CSnapinDescriptor::GetRegisteredIndirectName(CStr &strIndirectName)
  170. {
  171. DECLARE_SC (sc, _T("CSnapinDescriptor::GetRegisteredIndirectName"));
  172. sc = ScFormatIndirectSnapInName (GetStringModule(), m_idsName, strIndirectName);
  173. if (sc)
  174. sc.TraceAndClear();
  175. }
  176. /*+-------------------------------------------------------------------------*
  177. * CSnapinDescriptor::GetRegisteredDefaultName
  178. *
  179. * Returns the name of the snap-in in the indirect form supported by
  180. * SHLoadRegUIString:
  181. *
  182. * @<dllname>,-<strId>
  183. *--------------------------------------------------------------------------*/
  184. void
  185. CSnapinDescriptor::GetRegisteredDefaultName(CStr &str)
  186. {
  187. str.LoadString (GetStringModule(), m_idsName);
  188. }
  189. /*+-------------------------------------------------------------------------*
  190. * CSnapinDescriptor::GetName
  191. *
  192. * Returns the human-readable name of the snap-in.
  193. *--------------------------------------------------------------------------*/
  194. void
  195. CSnapinDescriptor::GetName(CStr &str)
  196. {
  197. DECLARE_SC (sc, _T("CSnapinDescriptor::GetName"));
  198. /*
  199. * get the name from the registry
  200. */
  201. sc = ScGetSnapinNameFromRegistry (m_szClsidSnapin, str);
  202. if (sc)
  203. sc.TraceAndClear();
  204. }
  205. long
  206. CSnapinDescriptor::GetViewOptions()
  207. {
  208. return m_viewOptions;
  209. }
  210. //############################################################################
  211. //############################################################################
  212. //
  213. // Implementation of class CSnapinComponentDataImpl
  214. //
  215. //############################################################################
  216. //############################################################################
  217. /*+-------------------------------------------------------------------------*
  218. *
  219. * CSnapinComponentDataImpl::CSnapinComponentDataImpl
  220. *
  221. * PURPOSE: Constructor
  222. *
  223. *+-------------------------------------------------------------------------*/
  224. CSnapinComponentDataImpl::CSnapinComponentDataImpl()
  225. : m_bDirty(false)
  226. {
  227. }
  228. void
  229. CSnapinComponentDataImpl::SetName(LPCTSTR sz)
  230. {
  231. m_strName = sz;
  232. }
  233. /*+-------------------------------------------------------------------------*
  234. *
  235. * CSnapinComponentDataImpl::SetView
  236. *
  237. * PURPOSE: Sets the view.
  238. *
  239. * PARAMETERS:
  240. * LPCTSTR sz :
  241. *
  242. * RETURNS:
  243. * void
  244. *
  245. *+-------------------------------------------------------------------------*/
  246. void
  247. CSnapinComponentDataImpl::SetView(LPCTSTR sz)
  248. {
  249. m_strView = sz;
  250. }
  251. STDMETHODIMP
  252. CSnapinComponentDataImpl::Initialize(LPUNKNOWN pUnknown)
  253. {
  254. m_spConsole2 = pUnknown;
  255. m_spConsoleNameSpace2 = pUnknown;
  256. return S_OK;
  257. }
  258. /*+-------------------------------------------------------------------------*
  259. *
  260. * CSnapinComponentDataImpl::Notify
  261. *
  262. * PURPOSE: Notification handler for the IComponentData implementation.
  263. *
  264. * PARAMETERS:
  265. * LPDATAOBJECT lpDataObject : As per MMC docs.
  266. * MMC_NOTIFY_TYPE event :
  267. * LPARAM arg :
  268. * LPARAM param :
  269. *
  270. * RETURNS:
  271. * STDMETHODIMP
  272. *
  273. *+-------------------------------------------------------------------------*/
  274. STDMETHODIMP
  275. CSnapinComponentDataImpl::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event,
  276. LPARAM arg, LPARAM param)
  277. {
  278. USES_CONVERSION;
  279. switch(event)
  280. {
  281. case MMCN_RENAME: // the root node is being renamed
  282. m_strName = OLE2T((LPOLESTR)param);
  283. SetDirty();
  284. return S_OK;
  285. case MMCN_PRELOAD:
  286. return OnPreload((HSCOPEITEM) arg);
  287. }
  288. return S_FALSE;
  289. }
  290. /*+-------------------------------------------------------------------------*
  291. *
  292. * CSnapinComponentDataImpl::OnPreload
  293. *
  294. * PURPOSE: sets the icon of the root node (which is the only node.)
  295. *
  296. * PARAMETERS:
  297. * HSCOPEITEM scopeItem :
  298. *
  299. * RETURNS:
  300. * HRESULT
  301. *
  302. *+-------------------------------------------------------------------------*/
  303. HRESULT
  304. CSnapinComponentDataImpl::OnPreload(HSCOPEITEM scopeItem)
  305. {
  306. SCOPEDATAITEM item;
  307. ZeroMemory (&item, sizeof(SCOPEDATAITEM));
  308. item.mask = SDI_CHILDREN;
  309. item.ID = scopeItem;
  310. item.cChildren = 0; // make sure no "+" sign is displayed.
  311. m_spConsoleNameSpace2->SetItem (&item);
  312. return S_OK;
  313. }
  314. /*+-------------------------------------------------------------------------*
  315. *
  316. * CSnapinComponentDataImpl::Destroy
  317. *
  318. * PURPOSE: Gives up all references to MMC.
  319. *
  320. * RETURNS:
  321. * STDMETHODIMP
  322. *
  323. *+-------------------------------------------------------------------------*/
  324. STDMETHODIMP
  325. CSnapinComponentDataImpl::Destroy()
  326. {
  327. m_spConsole2 = NULL;
  328. m_spConsoleNameSpace2 = NULL;
  329. return S_OK;
  330. }
  331. /*+-------------------------------------------------------------------------*
  332. *
  333. * CSnapinComponentDataImpl::QueryDataObject
  334. *
  335. * PURPOSE: Returns a data object for the specified node.
  336. *
  337. * PARAMETERS:
  338. * MMC_COOKIE cookie : NULL for the root node.
  339. * DATA_OBJECT_TYPES type :
  340. * LPDATAOBJECT* ppDataObject :
  341. *
  342. * RETURNS:
  343. * STDMETHODIMP
  344. *
  345. *+-------------------------------------------------------------------------*/
  346. STDMETHODIMP
  347. CSnapinComponentDataImpl::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
  348. LPDATAOBJECT* ppDataObject)
  349. {
  350. ASSERT(cookie == NULL);
  351. if(cookie != NULL)
  352. return E_UNEXPECTED;
  353. CComObject<CSnapinDataObject> * pDataObject;
  354. CComObject<CSnapinDataObject>::CreateInstance(&pDataObject);
  355. if(pDataObject == NULL)
  356. return E_UNEXPECTED;
  357. pDataObject->Initialize(this, type);
  358. return pDataObject->QueryInterface(IID_IDataObject, (void**)ppDataObject);
  359. }
  360. /*+-------------------------------------------------------------------------*
  361. *
  362. * CSnapinComponentDataImpl::GetDisplayInfo
  363. *
  364. * PURPOSE: Gets the display info for the root (the only) node.
  365. *
  366. * PARAMETERS:
  367. * SCOPEDATAITEM* pScopeDataItem : [IN/OUT]: The structure to fill in
  368. * based on the mask value.
  369. *
  370. * RETURNS:
  371. * STDMETHODIMP
  372. *
  373. *+-------------------------------------------------------------------------*/
  374. STDMETHODIMP
  375. CSnapinComponentDataImpl::GetDisplayInfo( SCOPEDATAITEM* pScopeDataItem)
  376. {
  377. SCOPEDATAITEM &sdi = *pScopeDataItem;
  378. DWORD mask = sdi.mask;
  379. if(mask & SDI_STR)
  380. {
  381. sdi.displayname = (LPOLESTR) GetName();
  382. }
  383. if(mask & SDI_IMAGE)
  384. {
  385. sdi.nImage = m_iImage;
  386. }
  387. if(mask & SDI_OPENIMAGE)
  388. {
  389. sdi.nImage = m_iOpenImage;
  390. }
  391. if(mask & SDI_STATE)
  392. {
  393. }
  394. if(mask & SDI_CHILDREN)
  395. {
  396. sdi.cChildren =0;
  397. }
  398. return S_OK;
  399. }
  400. /*+-------------------------------------------------------------------------*
  401. *
  402. * CSnapinComponentDataImpl::CompareObjects
  403. *
  404. * PURPOSE: Determines whether two data objects correspond to the same
  405. * underlying object.
  406. *
  407. * PARAMETERS:
  408. * LPDATAOBJECT lpDataObjectA :
  409. * LPDATAOBJECT lpDataObjectB :
  410. *
  411. * RETURNS:
  412. * STDMETHODIMP : S_OK if they correspond to the same object, else S_FALSE.
  413. *
  414. *+-------------------------------------------------------------------------*/
  415. STDMETHODIMP
  416. CSnapinComponentDataImpl::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  417. {
  418. return (lpDataObjectA == lpDataObjectB) ? S_OK : S_FALSE;
  419. }
  420. // IPersistStream
  421. /*+-------------------------------------------------------------------------*
  422. *
  423. * CSnapinComponentDataImpl::GetClassID
  424. *
  425. * PURPOSE:
  426. *
  427. * PARAMETERS:
  428. * CLSID * pClassID :
  429. *
  430. * RETURNS:
  431. * STDMETHODIMP
  432. *
  433. *+-------------------------------------------------------------------------*/
  434. STDMETHODIMP
  435. CSnapinComponentDataImpl::GetClassID(CLSID *pClassID)
  436. {
  437. return E_NOTIMPL;
  438. }
  439. /*+-------------------------------------------------------------------------*
  440. *
  441. * CSnapinComponentDataImpl::IsDirty
  442. *
  443. * PURPOSE:
  444. *
  445. * PARAMETERS:
  446. * voi d :
  447. *
  448. * RETURNS:
  449. * STDMETHODIMP
  450. *
  451. *+-------------------------------------------------------------------------*/
  452. STDMETHODIMP
  453. CSnapinComponentDataImpl::IsDirty(void)
  454. {
  455. TraceDirtyFlag(TEXT("CSnapinComponentDataImpl (MMC Built-in snapin)"), m_bDirty);
  456. return m_bDirty ? S_OK : S_FALSE;
  457. }
  458. /*+-------------------------------------------------------------------------*
  459. *
  460. * CSnapinComponentDataImpl::Load
  461. *
  462. * PURPOSE:
  463. *
  464. * PARAMETERS:
  465. * LPSTREAM pStm :
  466. *
  467. * RETURNS:
  468. * STDMETHODIMP
  469. *
  470. *+-------------------------------------------------------------------------*/
  471. STDMETHODIMP
  472. CSnapinComponentDataImpl::Load(LPSTREAM pStm)
  473. {
  474. return CSerialObject::Read(*pStm);
  475. }
  476. /*+-------------------------------------------------------------------------*
  477. *
  478. * CSnapinComponentDataImpl::Save
  479. *
  480. * PURPOSE:
  481. *
  482. * PARAMETERS:
  483. * LPSTREAM pStm :
  484. * BOOL fClearDirty :
  485. *
  486. * RETURNS:
  487. * STDMETHODIMP
  488. *
  489. *+-------------------------------------------------------------------------*/
  490. STDMETHODIMP
  491. CSnapinComponentDataImpl::Save(LPSTREAM pStm , BOOL fClearDirty)
  492. {
  493. HRESULT hr = CSerialObjectRW::Write(*pStm);
  494. if (SUCCEEDED(hr) && fClearDirty)
  495. SetDirty(FALSE);
  496. return hr;
  497. }
  498. /*+-------------------------------------------------------------------------*
  499. *
  500. * CSnapinComponentDataImpl::GetSizeMax
  501. *
  502. * PURPOSE:
  503. *
  504. * PARAMETERS:
  505. * ULARGE_INTEGER* pcbSize :
  506. *
  507. * RETURNS:
  508. * STDMETHODIMP
  509. *
  510. *+-------------------------------------------------------------------------*/
  511. STDMETHODIMP
  512. CSnapinComponentDataImpl::GetSizeMax(ULARGE_INTEGER* pcbSize )
  513. {
  514. return E_NOTIMPL;
  515. }
  516. /*+-------------------------------------------------------------------------*
  517. *
  518. * CSnapinComponentDataImpl::GetWatermarks
  519. *
  520. * PURPOSE: Sets the header for the wizard
  521. *
  522. * PARAMETERS:
  523. * LPDATAOBJECT lpIDataObject :
  524. * HBITMAP * lphWatermark :
  525. * HBITMAP * lphHeader :
  526. * HPALETTE * lphPalette :
  527. * BOOL* bStretch :
  528. *
  529. * RETURNS:
  530. * STDMETHODIMP
  531. *
  532. *+-------------------------------------------------------------------------*/
  533. STDMETHODIMP
  534. CSnapinComponentDataImpl::GetWatermarks(LPDATAOBJECT lpIDataObject, HBITMAP * lphWatermark, HBITMAP * lphHeader, HPALETTE * lphPalette, BOOL* bStretch)
  535. {
  536. DECLARE_SC(sc, TEXT("COCXSnapinData::ScGetWatermarks"));
  537. // validate inputs
  538. sc = ScCheckPointers(lpIDataObject, lphWatermark, lphHeader, lphPalette);
  539. if(sc)
  540. return sc.ToHr();
  541. // initialize outputs
  542. *lphWatermark = GetWatermark() ? ::LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(GetWatermark()))
  543. : NULL;
  544. // if there is a header, use it.
  545. *lphHeader = GetHeaderBitmap() ? ::LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(GetHeaderBitmap()))
  546. : NULL;
  547. *lphPalette = NULL;
  548. return sc.ToHr();
  549. }
  550. /*+-------------------------------------------------------------------------*
  551. *
  552. * CSnapinComponentDataImpl::QueryPagesFor
  553. *
  554. * PURPOSE:
  555. *
  556. * PARAMETERS:
  557. * LPDATAOBJECT lpDataObject :
  558. *
  559. * RETURNS:
  560. * STDMETHODIMP
  561. *
  562. *+-------------------------------------------------------------------------*/
  563. STDMETHODIMP
  564. CSnapinComponentDataImpl::QueryPagesFor(LPDATAOBJECT lpDataObject)
  565. {
  566. CSnapinDataObject *pDataObject = dynamic_cast<CSnapinDataObject *>(lpDataObject);
  567. if(pDataObject == NULL)
  568. return E_UNEXPECTED;
  569. if(pDataObject->GetType() != CCT_SNAPIN_MANAGER)
  570. return S_FALSE;
  571. return S_OK; // properties exist only in the snap-in manager.
  572. }
  573. /*+-------------------------------------------------------------------------*
  574. * CSnapinComponentDataImpl::GetHelpTopic
  575. *
  576. * Default implementation of ISnapinHelp::GetHelpTopic for built-in snap-
  577. * ins (folder, OCX, web page).
  578. *
  579. * We need to implement ISnapinHelp in the built-ins to avoid getting
  580. * "Help for <snap-in>" on the Help menu (bug 453700). They don't really
  581. * have help info, so we simply return S_FALSE so the help engine doesn't
  582. * complain.
  583. *--------------------------------------------------------------------------*/
  584. STDMETHODIMP CSnapinComponentDataImpl::GetHelpTopic (
  585. LPOLESTR* /*ppszCompiledHelpTopic*/)
  586. {
  587. return (S_FALSE); // no help topic
  588. }
  589. // CSerialObject methods
  590. /*+-------------------------------------------------------------------------*
  591. *
  592. * CSnapinComponentDataImpl::ReadSerialObject
  593. *
  594. * PURPOSE:
  595. *
  596. * PARAMETERS:
  597. * IStream & stm :
  598. * UINT nVersion :
  599. *
  600. * RETURNS:
  601. * HRESULT
  602. *
  603. *+-------------------------------------------------------------------------*/
  604. HRESULT
  605. CSnapinComponentDataImpl::ReadSerialObject (IStream &stm, UINT nVersion)
  606. {
  607. if(nVersion==1)
  608. {
  609. stm >> m_strName;
  610. stm >> m_strView;
  611. return S_OK;
  612. }
  613. else
  614. return S_FALSE; //unknown version, skip.
  615. }
  616. /*+-------------------------------------------------------------------------*
  617. *
  618. * CSnapinComponentDataImpl::WriteSerialObject
  619. *
  620. * PURPOSE:
  621. *
  622. * PARAMETERS:
  623. * IStream & stm :
  624. *
  625. * RETURNS:
  626. * HRESULT
  627. *
  628. *+-------------------------------------------------------------------------*/
  629. HRESULT
  630. CSnapinComponentDataImpl::WriteSerialObject(IStream &stm)
  631. {
  632. stm << m_strName;
  633. stm << m_strView;
  634. return S_OK;
  635. }
  636. //############################################################################
  637. //############################################################################
  638. //
  639. // Implementation of class CSnapinComponentImpl
  640. //
  641. //############################################################################
  642. //############################################################################
  643. /*+-------------------------------------------------------------------------*
  644. *
  645. * CSnapinComponentImpl::Init
  646. *
  647. * PURPOSE:
  648. *
  649. * PARAMETERS:
  650. * IComponentData * pComponentData :
  651. *
  652. * RETURNS:
  653. * void
  654. *
  655. *+-------------------------------------------------------------------------*/
  656. void
  657. CSnapinComponentImpl::Init(IComponentData *pComponentData)
  658. {
  659. m_spComponentData = pComponentData;
  660. }
  661. // IComponent
  662. /*+-------------------------------------------------------------------------*
  663. *
  664. * CSnapinComponentImpl::Initialize
  665. *
  666. * PURPOSE:
  667. *
  668. * PARAMETERS:
  669. * LPCONSOLE lpConsole :
  670. *
  671. * RETURNS:
  672. * STDMETHODIMP
  673. *
  674. *+-------------------------------------------------------------------------*/
  675. STDMETHODIMP
  676. CSnapinComponentImpl::Initialize(LPCONSOLE lpConsole)
  677. {
  678. m_spConsole2 = lpConsole;
  679. return S_OK;
  680. }
  681. /*+-------------------------------------------------------------------------*
  682. *
  683. * CSnapinComponentImpl::Notify
  684. *
  685. * PURPOSE:
  686. *
  687. * PARAMETERS:
  688. * LPDATAOBJECT lpDataObject :
  689. * MMC_NOTIFY_TYPE event :
  690. * LPARAM arg :
  691. * LPARAM param :
  692. *
  693. * RETURNS:
  694. * STDMETHODIMP
  695. *
  696. *+-------------------------------------------------------------------------*/
  697. STDMETHODIMP
  698. CSnapinComponentImpl::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event,
  699. LPARAM arg, LPARAM param)
  700. {
  701. switch(event)
  702. {
  703. case MMCN_SELECT:
  704. {
  705. BOOL bScope = (BOOL) LOWORD(arg);
  706. BOOL bSelect = (BOOL) HIWORD(arg);
  707. SC sc = ScOnSelect(bScope, bSelect);
  708. if(sc)
  709. return sc.ToHr();
  710. }
  711. return S_OK;
  712. break;
  713. default:
  714. break;
  715. }
  716. return S_FALSE;
  717. }
  718. /*+-------------------------------------------------------------------------*
  719. *
  720. * CSnapinComponentImpl::ScOnSelect
  721. *
  722. * PURPOSE:
  723. *
  724. * PARAMETERS:
  725. * BOOL bScope :
  726. * BOOL bSelect :
  727. *
  728. * RETURNS:
  729. * SC
  730. *
  731. *+-------------------------------------------------------------------------*/
  732. SC
  733. CSnapinComponentImpl::ScOnSelect(BOOL bScope, BOOL bSelect)
  734. {
  735. DECLARE_SC(sc, TEXT("CSnapinComponentImpl::ScOnSelect"));
  736. IConsoleVerbPtr spConsoleVerb;
  737. sc = m_spConsole2->QueryConsoleVerb(&spConsoleVerb);
  738. if(sc)
  739. return sc;
  740. sc = spConsoleVerb->SetVerbState(MMC_VERB_RENAME, ENABLED, (bSelect && bScope));
  741. if(sc)
  742. return sc;
  743. return sc;
  744. }
  745. /*+-------------------------------------------------------------------------*
  746. *
  747. * CSnapinComponentImpl::Destroy
  748. *
  749. * PURPOSE:
  750. *
  751. * PARAMETERS:
  752. * MMC_COOKIE cookie :
  753. *
  754. * RETURNS:
  755. * STDMETHODIMP
  756. *
  757. *+-------------------------------------------------------------------------*/
  758. STDMETHODIMP
  759. CSnapinComponentImpl::Destroy(MMC_COOKIE cookie)
  760. {
  761. m_spConsole2 = NULL;
  762. m_spComponentData = NULL;
  763. return S_OK;
  764. }
  765. /*+-------------------------------------------------------------------------*
  766. *
  767. * CSnapinComponentImpl::QueryDataObject
  768. *
  769. * PURPOSE:
  770. *
  771. * PARAMETERS:
  772. * MMC_COOKIE cookie :
  773. * DATA_OBJECT_TYPES type :
  774. * LPDATAOBJECT* ppDataObject :
  775. *
  776. * RETURNS:
  777. * STDMETHODIMP
  778. *
  779. *+-------------------------------------------------------------------------*/
  780. STDMETHODIMP
  781. CSnapinComponentImpl::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
  782. LPDATAOBJECT* ppDataObject)
  783. {
  784. return E_NOTIMPL;
  785. }
  786. /*+-------------------------------------------------------------------------*
  787. *
  788. * CSnapinComponentImpl::GetComponentData
  789. *
  790. * PURPOSE:
  791. *
  792. * RETURNS:
  793. * CSnapinComponentDataImpl *
  794. *
  795. *+-------------------------------------------------------------------------*/
  796. CSnapinComponentDataImpl *
  797. CSnapinComponentImpl::GetComponentData()
  798. {
  799. CSnapinComponentDataImpl *pCD = dynamic_cast<CSnapinComponentDataImpl *>(m_spComponentData.GetInterfacePtr());
  800. ASSERT(pCD != NULL);
  801. return pCD;
  802. }
  803. /*+-------------------------------------------------------------------------*
  804. *
  805. * CSnapinComponentImpl::GetResultViewType
  806. *
  807. * PURPOSE:
  808. *
  809. * PARAMETERS:
  810. * MMC_COOKIE cookie :
  811. * LPOLESTR* ppViewType :
  812. * long* pViewOptions : Set to MMC_VIEW_OPTIONS_NOLISTVIEWS for the HTML and OCX snapins,
  813. * 0 for the folder snapin.
  814. *
  815. * RETURNS:
  816. * STDMETHODIMP
  817. *
  818. *+-------------------------------------------------------------------------*/
  819. STDMETHODIMP
  820. CSnapinComponentImpl::GetResultViewType(MMC_COOKIE cookie, LPOLESTR* ppViewType,
  821. long* pViewOptions)
  822. {
  823. DECLARE_SC(sc, TEXT("CSnapinComponentImpl::GetResultViewType"));
  824. // check parameters
  825. if(!ppViewType || !pViewOptions)
  826. return E_UNEXPECTED;
  827. if(!GetComponentData())
  828. return E_UNEXPECTED;
  829. USES_CONVERSION;
  830. int cchViewType = _tcslen(GetComponentData()->GetView())+1;
  831. *ppViewType = (LPOLESTR)CoTaskMemAlloc( cchViewType * sizeof(OLECHAR) );
  832. *pViewOptions = GetComponentData()->GetDescriptor().GetViewOptions();
  833. sc = StringCchCopyW(*ppViewType, cchViewType, T2OLE((LPTSTR)GetComponentData()->GetView()));
  834. if(sc)
  835. return sc.ToHr();
  836. return S_OK;
  837. }
  838. /*+-------------------------------------------------------------------------*
  839. *
  840. * CSnapinComponentImpl::GetDisplayInfo
  841. *
  842. * PURPOSE:
  843. *
  844. * PARAMETERS:
  845. * RESULTDATAITEM* pResultDataItem :
  846. *
  847. * RETURNS:
  848. * STDMETHODIMP
  849. *
  850. *+-------------------------------------------------------------------------*/
  851. STDMETHODIMP
  852. CSnapinComponentImpl::GetDisplayInfo( RESULTDATAITEM* pResultDataItem)
  853. {
  854. RESULTDATAITEM &rdi = *pResultDataItem;
  855. DWORD mask = rdi.mask;
  856. if(mask & RDI_STR)
  857. {
  858. rdi.str = (LPOLESTR) GetComponentData()->GetName();
  859. }
  860. if(mask & RDI_IMAGE)
  861. {
  862. rdi.nImage = GetComponentData()->m_iImage;
  863. }
  864. return S_OK;
  865. }
  866. /*+-------------------------------------------------------------------------*
  867. *
  868. * CSnapinComponentImpl::CompareObjects
  869. *
  870. * PURPOSE:
  871. *
  872. * PARAMETERS:
  873. * LPDATAOBJECT lpDataObjectA :
  874. * LPDATAOBJECT lpDataObjectB :
  875. *
  876. * RETURNS:
  877. * STDMETHODIMP
  878. *
  879. *+-------------------------------------------------------------------------*/
  880. STDMETHODIMP
  881. CSnapinComponentImpl::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  882. {
  883. return E_NOTIMPL;
  884. }
  885. //############################################################################
  886. //############################################################################
  887. //
  888. // Implementation of class CSnapinDataObject
  889. //
  890. //############################################################################
  891. //############################################################################
  892. // Clipboard formats that are required by the console
  893. UINT CSnapinDataObject::s_cfNodeType;
  894. UINT CSnapinDataObject::s_cfNodeTypeString;
  895. UINT CSnapinDataObject::s_cfDisplayName;
  896. UINT CSnapinDataObject::s_cfCoClass;
  897. UINT CSnapinDataObject::s_cfSnapinPreloads;
  898. /*+-------------------------------------------------------------------------*
  899. *
  900. * CSnapinDataObject::RegisterClipboardFormats
  901. *
  902. * PURPOSE:
  903. *
  904. * RETURNS:
  905. * void
  906. *
  907. *+-------------------------------------------------------------------------*/
  908. void
  909. CSnapinDataObject::RegisterClipboardFormats()
  910. {
  911. static bool bRegistered = false;
  912. if(!bRegistered)
  913. {
  914. USES_CONVERSION;
  915. CSnapinDataObject::s_cfNodeType = RegisterClipboardFormat(OLE2T(CCF_NODETYPE));
  916. CSnapinDataObject::s_cfNodeTypeString = RegisterClipboardFormat(OLE2T(CCF_SZNODETYPE));
  917. CSnapinDataObject::s_cfDisplayName = RegisterClipboardFormat(OLE2T(CCF_DISPLAY_NAME));
  918. CSnapinDataObject::s_cfCoClass = RegisterClipboardFormat(OLE2T(CCF_SNAPIN_CLASSID));
  919. CSnapinDataObject::s_cfSnapinPreloads = RegisterClipboardFormat(OLE2T(CCF_SNAPIN_PRELOADS));
  920. bRegistered = true;
  921. }
  922. }
  923. CSnapinDataObject::CSnapinDataObject() : m_bInitialized(false)
  924. {
  925. }
  926. /*+-------------------------------------------------------------------------*
  927. *
  928. * CSnapinDataObject::GetDataHere
  929. *
  930. * PURPOSE:
  931. *
  932. * PARAMETERS:
  933. * FORMATETC * pformatetc :
  934. * STGMEDIUM * pmedium :
  935. *
  936. * RETURNS:
  937. * STDMETHODIMP
  938. *
  939. *+-------------------------------------------------------------------------*/
  940. STDMETHODIMP
  941. CSnapinDataObject::GetDataHere(FORMATETC *pformatetc, STGMEDIUM *pmedium)
  942. {
  943. DECLARE_SC(sc, TEXT("CSnapinDataObject::GetDataHere"));
  944. // validate inputs
  945. sc = ScCheckPointers(pformatetc, pmedium);
  946. if(sc)
  947. return sc.ToHr();
  948. USES_CONVERSION;
  949. RegisterClipboardFormats();
  950. // Based on the CLIPFORMAT write data to the stream
  951. const CLIPFORMAT cf = pformatetc->cfFormat;
  952. // ensure the medium is an HGLOBAL
  953. if(pformatetc->tymed != TYMED_HGLOBAL)
  954. return (sc = DV_E_TYMED).ToHr();
  955. IStreamPtr spStream;
  956. HGLOBAL hGlobal = pmedium->hGlobal;
  957. pmedium->pUnkForRelease = NULL; // by OLE spec
  958. sc = CreateStreamOnHGlobal( hGlobal, FALSE, &spStream );
  959. if(sc)
  960. return sc.ToHr();
  961. CSnapinComponentDataImpl *pComponentDataImpl =
  962. dynamic_cast<CSnapinComponentDataImpl *>(m_spComponentData.GetInterfacePtr());
  963. ASSERT(pComponentDataImpl != NULL);
  964. if (cf == s_cfNodeType)
  965. {
  966. spStream<<pComponentDataImpl->GetDescriptor().m_guidNodetype;
  967. }
  968. else if (cf == s_cfCoClass)
  969. {
  970. spStream<<pComponentDataImpl->GetDescriptor().m_clsidSnapin;
  971. }
  972. else if(cf == s_cfNodeTypeString)
  973. {
  974. WriteString(spStream, T2OLE((LPTSTR)pComponentDataImpl->GetDescriptor().m_szGuidNodetype));
  975. }
  976. else if (cf == s_cfDisplayName)
  977. {
  978. WriteString(spStream, T2OLE((LPTSTR)pComponentDataImpl->GetName()));
  979. }
  980. else if (cf == s_cfSnapinPreloads)
  981. {
  982. BOOL bPreload = true;
  983. spStream->Write ((void *)&bPreload, sizeof(BOOL), NULL);
  984. }
  985. else
  986. {
  987. return (sc = DV_E_CLIPFORMAT).ToHr(); // invalid format.
  988. }
  989. return sc.ToHr();
  990. }
  991. /*+-------------------------------------------------------------------------*
  992. *
  993. * CSnapinDataObject::WriteString
  994. *
  995. * PURPOSE:
  996. *
  997. * PARAMETERS:
  998. * IStream * pStream :
  999. * LPCOLESTR sz :
  1000. *
  1001. * RETURNS:
  1002. * HRESULT
  1003. *
  1004. *+-------------------------------------------------------------------------*/
  1005. HRESULT
  1006. CSnapinDataObject::WriteString(IStream *pStream, LPCOLESTR sz)
  1007. {
  1008. DECLARE_SC(sc, TEXT("CSnapinDataObject::WriteString"));
  1009. sc = ScCheckPointers(pStream, sz);
  1010. if(sc)
  1011. return sc.ToHr();
  1012. UINT cbToWrite = wcslen(sz)*sizeof(WCHAR);
  1013. ULONG cbActuallyWritten=0;
  1014. sc = pStream->Write (sz, cbToWrite, &cbActuallyWritten);
  1015. if(sc)
  1016. return sc.ToHr();
  1017. ASSERT(cbToWrite==cbActuallyWritten);
  1018. return sc.ToHr();
  1019. }
  1020. /*+-------------------------------------------------------------------------*
  1021. *
  1022. * CSnapinDataObject::Initialize
  1023. *
  1024. * PURPOSE:
  1025. *
  1026. * PARAMETERS:
  1027. * IComponentData * pComponentData :
  1028. * DATA_OBJECT_TYPES type :
  1029. *
  1030. * RETURNS:
  1031. * void
  1032. *
  1033. *+-------------------------------------------------------------------------*/
  1034. void
  1035. CSnapinDataObject::Initialize(IComponentData *pComponentData, DATA_OBJECT_TYPES type)
  1036. {
  1037. ASSERT(pComponentData != NULL);
  1038. m_spComponentData = pComponentData;
  1039. m_type = type;
  1040. m_bInitialized = true;
  1041. }
  1042. //############################################################################
  1043. //############################################################################
  1044. //
  1045. // Implementation of class CFolderSnapinData
  1046. //
  1047. //############################################################################
  1048. //############################################################################
  1049. STDMETHODIMP
  1050. CFolderSnapinData::CreateComponent(LPCOMPONENT* ppComponent)
  1051. {
  1052. typedef CComObject<CFolderSnapinComponent> CComponent;
  1053. CComponent * pComponent = NULL;
  1054. CComObject<CFolderSnapinComponent>::CreateInstance(&pComponent);
  1055. ASSERT(pComponent != NULL);
  1056. if(pComponent == NULL)
  1057. {
  1058. //TraceError(TEXT("CFolderSnapinData::CreateComponent"));
  1059. return E_UNEXPECTED;
  1060. }
  1061. pComponent->Init(this);
  1062. return pComponent->QueryInterface(IID_IComponent, (void **)ppComponent); // does the Addref.
  1063. }
  1064. CFolderSnapinData::CFolderSnapinData()
  1065. {
  1066. m_iImage = eStockImage_Folder;
  1067. m_iOpenImage = eStockImage_OpenFolder;
  1068. }
  1069. const CLSID CLSID_FolderSnapin = {0xC96401CC, 0x0E17,0x11D3, {0x88,0x5B,0x00,0xC0,0x4F,0x72,0xC7,0x17}};
  1070. static const GUID GUID_FolderSnapinNodetype = {0xc96401ce, 0xe17, 0x11d3, { 0x88, 0x5b, 0x0, 0xc0, 0x4f, 0x72, 0xc7, 0x17 } };
  1071. static LPCTSTR szClsid_FolderSnapin = TEXT("{C96401CC-0E17-11D3-885B-00C04F72C717}");
  1072. static LPCTSTR szGuidFolderSnapinNodetype = TEXT("{C96401CE-0E17-11D3-885B-00C04F72C717}");
  1073. CSnapinDescriptor &
  1074. CFolderSnapinData::GetSnapinDescriptor()
  1075. {
  1076. static CSnapinDescriptor snapinDescription(IDS_FOLDER,
  1077. IDS_FOLDERSNAPIN_DESC, IDI_FOLDER, IDB_FOLDER_16, IDB_FOLDEROPEN_16, IDB_FOLDER_32,
  1078. CLSID_FolderSnapin, szClsid_FolderSnapin, GUID_FolderSnapinNodetype,
  1079. szGuidFolderSnapinNodetype, TEXT("Folder"), TEXT("Snapins.FolderSnapin"),
  1080. TEXT("Snapins.FolderSnapin.1"), 0 /*viewOptions*/ );
  1081. return snapinDescription;
  1082. }
  1083. // IExtendPropertySheet2
  1084. STDMETHODIMP
  1085. CFolderSnapinData::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, LPDATAOBJECT lpIDataObject)
  1086. {
  1087. return S_FALSE;
  1088. }
  1089. //############################################################################
  1090. //############################################################################
  1091. //
  1092. // Implementation of class CHTMLSnapinData
  1093. //
  1094. //############################################################################
  1095. //############################################################################
  1096. STDMETHODIMP
  1097. CHTMLSnapinData::CreateComponent(LPCOMPONENT* ppComponent)
  1098. {
  1099. typedef CComObject<CHTMLSnapinComponent> CComponent;
  1100. CComponent * pComponent = NULL;
  1101. CComObject<CHTMLSnapinComponent>::CreateInstance(&pComponent);
  1102. ASSERT(pComponent != NULL);
  1103. if(pComponent == NULL)
  1104. {
  1105. //TraceError(TEXT("CHTMLSnapinData::CreateComponent"));
  1106. return E_UNEXPECTED;
  1107. }
  1108. pComponent->Init(this);
  1109. return pComponent->QueryInterface(IID_IComponent, (void **)ppComponent); // does the Addref.
  1110. }
  1111. CHTMLSnapinData::CHTMLSnapinData()
  1112. {
  1113. m_pHtmlPage1 = NULL;
  1114. m_pHtmlPage2 = NULL;
  1115. m_iImage = eStockImage_HTML;
  1116. m_iOpenImage = eStockImage_HTML;
  1117. }
  1118. CHTMLSnapinData::~CHTMLSnapinData()
  1119. {
  1120. }
  1121. STDMETHODIMP
  1122. CHTMLSnapinData::Destroy()
  1123. {
  1124. if(m_pHtmlPage1 != NULL)
  1125. {
  1126. delete m_pHtmlPage1;
  1127. m_pHtmlPage1 = NULL;
  1128. }
  1129. if(m_pHtmlPage2 != NULL)
  1130. {
  1131. delete m_pHtmlPage2;
  1132. m_pHtmlPage2 = NULL;
  1133. }
  1134. return BC::Destroy();
  1135. }
  1136. const CLSID CLSID_HTMLSnapin = {0xC96401D1, 0x0E17,0x11D3, {0x88,0x5B,0x00,0xC0,0x4F,0x72,0xC7,0x17}};
  1137. static const GUID GUID_HTMLSnapinNodetype = {0xc96401d2, 0xe17, 0x11d3, { 0x88, 0x5b, 0x0, 0xc0, 0x4f, 0x72, 0xc7, 0x17 } };
  1138. static LPCTSTR szClsid_HTMLSnapin = TEXT("{C96401D1-0E17-11D3-885B-00C04F72C717}");
  1139. static LPCTSTR szGuidHTMLSnapinNodetype = TEXT("{C96401D2-0E17-11D3-885B-00C04F72C717}");
  1140. CSnapinDescriptor &
  1141. CHTMLSnapinData::GetSnapinDescriptor()
  1142. {
  1143. static CSnapinDescriptor snapinDescription(IDS_HTML,
  1144. IDS_HTMLSNAPIN_DESC, IDI_HTML, IDB_HTML_16, IDB_HTML_16, IDB_HTML_32,
  1145. CLSID_HTMLSnapin, szClsid_HTMLSnapin, GUID_HTMLSnapinNodetype,
  1146. szGuidHTMLSnapinNodetype, TEXT("HTML"), TEXT("Snapins.HTMLSnapin"),
  1147. TEXT("Snapins.HTMLSnapin.1"), MMC_VIEW_OPTIONS_NOLISTVIEWS /*viewOptions*/ );
  1148. return snapinDescription;
  1149. }
  1150. // IExtendPropertySheet2
  1151. /*+-------------------------------------------------------------------------*
  1152. *
  1153. * CHTMLSnapinData::CreatePropertyPages
  1154. *
  1155. * PURPOSE:
  1156. *
  1157. * PARAMETERS:
  1158. * LPPROPERTYSHEETCALLBACK lpProvider :
  1159. * LONG_PTR handle :
  1160. * LPDATAOBJECT lpIDataObject :
  1161. *
  1162. * RETURNS:
  1163. * STDMETHODIMP
  1164. *
  1165. *+-------------------------------------------------------------------------*/
  1166. STDMETHODIMP
  1167. CHTMLSnapinData::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, LPDATAOBJECT lpIDataObject)
  1168. {
  1169. HPROPSHEETPAGE hPage;
  1170. ASSERT(lpProvider != NULL);
  1171. if(lpProvider == NULL)
  1172. {
  1173. //TraceError(TEXT("CHTMLSnapinData::CreatePropertyPages"));
  1174. return E_UNEXPECTED;
  1175. }
  1176. ASSERT(m_pHtmlPage1 == NULL);
  1177. ASSERT(m_pHtmlPage2 == NULL);
  1178. // create property pages
  1179. m_pHtmlPage1 = new CHTMLPage1;
  1180. m_pHtmlPage2 = new CHTMLPage2;
  1181. // pass in pointer to data structure
  1182. m_pHtmlPage1->Initialize(this);
  1183. m_pHtmlPage2->Initialize(this);
  1184. // Add Pages to property sheet
  1185. hPage=CreatePropertySheetPage(&m_pHtmlPage1->m_psp);
  1186. lpProvider->AddPage(hPage);
  1187. hPage=CreatePropertySheetPage(&m_pHtmlPage2->m_psp);
  1188. lpProvider->AddPage(hPage);
  1189. return S_OK;
  1190. }
  1191. //############################################################################
  1192. //############################################################################
  1193. //
  1194. // Implementation of class CHTMLSnapinComponent
  1195. //
  1196. //############################################################################
  1197. //############################################################################
  1198. /*+-------------------------------------------------------------------------*
  1199. *
  1200. * CHTMLSnapinComponent::ScOnSelect
  1201. *
  1202. * PURPOSE: Handles the MMCN_SELECT notification. Enables the Refresh verb,
  1203. * which uses the default MMC handler to refresh the page.
  1204. *
  1205. * PARAMETERS:
  1206. * BOOL bScope :
  1207. * BOOL bSelect :
  1208. *
  1209. * RETURNS:
  1210. * SC
  1211. *
  1212. *+-------------------------------------------------------------------------*/
  1213. SC
  1214. CHTMLSnapinComponent::ScOnSelect(BOOL bScope, BOOL bSelect)
  1215. {
  1216. DECLARE_SC(sc, TEXT("CHTMLSnapinComponent::ScOnSelect"));
  1217. // call the base class method
  1218. sc = BC::ScOnSelect(bScope, bSelect);
  1219. if(sc)
  1220. return sc;
  1221. IConsoleVerbPtr spConsoleVerb;
  1222. sc = ScCheckPointers(m_spConsole2, E_UNEXPECTED);
  1223. if(sc)
  1224. return sc;
  1225. sc = m_spConsole2->QueryConsoleVerb(&spConsoleVerb);
  1226. if(sc)
  1227. return sc;
  1228. sc = ScCheckPointers(spConsoleVerb, E_UNEXPECTED);
  1229. if(sc)
  1230. return sc;
  1231. // enable the Refresh verb - the default MMC handler is adequate to refresh the page.
  1232. sc = spConsoleVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, (bSelect && bScope));
  1233. if(sc)
  1234. return sc;
  1235. //NOTE: (vivekj): I'm intentionally not setting the HIDDEN state to false here, because
  1236. // we have an explicit test in our verb code for MMC1.0 snapins that wrote code like this,
  1237. // and this provides a useful compatibility test.
  1238. return sc;
  1239. }
  1240. /*+-------------------------------------------------------------------------*
  1241. *
  1242. * CHTMLSnapinComponent::GetResultViewType
  1243. *
  1244. * PURPOSE: Performs parameter substitution on the URL for the environment variables
  1245. * %windir% and %systemroot% (only) and returns the expanded URL.
  1246. *
  1247. * NOTE: We don't expand ALL variables using ExpandEnvironmentString. Doing so could
  1248. * break compatibility with URL's that have %var% but DON'T want to be
  1249. * expanded.
  1250. *
  1251. * PARAMETERS:
  1252. * MMC_COOKIE cookie :
  1253. * LPOLESTR* ppViewType :
  1254. * long* pViewOptions :
  1255. *
  1256. * RETURNS:
  1257. * STDMETHODIMP
  1258. *
  1259. *+-------------------------------------------------------------------------*/
  1260. STDMETHODIMP
  1261. CHTMLSnapinComponent::GetResultViewType(MMC_COOKIE cookie, LPOLESTR* ppViewType, long* pViewOptions)
  1262. {
  1263. DECLARE_SC(sc, TEXT("CHTMLSnapinComponent::GetResultViewType"));
  1264. // check parameters
  1265. if(!ppViewType || !pViewOptions)
  1266. return (sc = E_UNEXPECTED).ToHr();
  1267. if(!GetComponentData())
  1268. return (sc = E_UNEXPECTED).ToHr();
  1269. // add support for expanding the environment variables %WINDIR% and %SYSTEMROOT% to maintain compatibility with MMC1.2
  1270. CStr strTarget = GetComponentData()->GetView();
  1271. CStr strRet = strTarget; // the return value
  1272. CStr strTemp = strTarget; // both initialized to the same value.
  1273. strTemp.MakeLower(); // NOTE: this lowercase conversion is used only for comparison. The original case is preserved in the output.
  1274. // Find out if %windir% or %systemroot% is in the target string
  1275. int nWndDir = strTemp.Find(MMC_WINDIR_VARIABLE_PERC);
  1276. int nSysDir = strTemp.Find(MMC_SYSTEMROOT_VARIABLE_PERC);
  1277. if (nWndDir != -1 || nSysDir != -1)
  1278. {
  1279. const UINT cchBuffer = 4096;
  1280. // Get start pos and length of replacement string
  1281. int nStpos = (nWndDir != -1) ? nWndDir : nSysDir;
  1282. int nLen = (nWndDir != -1) ? _tcslen(MMC_WINDIR_VARIABLE_PERC) : _tcslen(MMC_SYSTEMROOT_VARIABLE_PERC);
  1283. // Setup temp variable to hold BUFFERLEN chars
  1284. CStr strRoot;
  1285. LPTSTR szBuffer = strRoot.GetBuffer(cchBuffer);
  1286. if (szBuffer != NULL)
  1287. {
  1288. int iReturn = -1;
  1289. if (nWndDir != -1)
  1290. iReturn = GetWindowsDirectory(szBuffer, cchBuffer);
  1291. else
  1292. iReturn = GetEnvironmentVariable(MMC_SYSTEMROOT_VARIABLE, szBuffer, cchBuffer);
  1293. // release string buffer
  1294. strRoot.ReleaseBuffer();
  1295. // Build up new target string based on environemnt variable.
  1296. if (iReturn != 0)
  1297. {
  1298. strRet = strTarget.Left(nStpos);
  1299. strRet += strRoot;
  1300. strRet += strTarget.Mid(nStpos + nLen, strTarget.GetLength() - (nStpos + nLen));
  1301. }
  1302. }
  1303. }
  1304. USES_CONVERSION;
  1305. int cchViewType = _tcslen(strRet)+1;
  1306. *ppViewType = (LPOLESTR)CoTaskMemAlloc( cchViewType * sizeof(OLECHAR) );
  1307. *pViewOptions = GetComponentData()->GetDescriptor().GetViewOptions();
  1308. sc = ScCheckPointers(*ppViewType, *pViewOptions);
  1309. if(sc)
  1310. return sc.ToHr();
  1311. sc = StringCchCopyW(*ppViewType, cchViewType, T2COLE(strRet));
  1312. if(sc)
  1313. return sc.ToHr();
  1314. return sc.ToHr();
  1315. }
  1316. //############################################################################
  1317. //############################################################################
  1318. //
  1319. // Implementation of class COCXSnapinData
  1320. //
  1321. //############################################################################
  1322. //############################################################################
  1323. STDMETHODIMP
  1324. COCXSnapinData::CreateComponent(LPCOMPONENT* ppComponent)
  1325. {
  1326. typedef CComObject<COCXSnapinComponent> CComponent;
  1327. CComponent * pComponent = NULL;
  1328. CComObject<COCXSnapinComponent>::CreateInstance(&pComponent);
  1329. ASSERT(pComponent != NULL);
  1330. if(pComponent == NULL)
  1331. {
  1332. //TraceError(TEXT("COCXSnapinData::CreateComponent"));
  1333. return E_UNEXPECTED;
  1334. }
  1335. pComponent->Init(this);
  1336. return pComponent->QueryInterface(IID_IComponent, (void **)ppComponent); // does the Addref.
  1337. }
  1338. COCXSnapinData::COCXSnapinData()
  1339. {
  1340. m_pActiveXPage0 = NULL;
  1341. m_pActiveXPage1 = NULL;
  1342. m_pActiveXPage2 = NULL;
  1343. m_iImage = eStockImage_OCX;
  1344. m_iOpenImage = eStockImage_OCX;
  1345. }
  1346. COCXSnapinData::~COCXSnapinData()
  1347. {
  1348. }
  1349. STDMETHODIMP
  1350. COCXSnapinData::Destroy()
  1351. {
  1352. if(m_pActiveXPage0 != NULL)
  1353. {
  1354. delete m_pActiveXPage0;
  1355. m_pActiveXPage0 = NULL;
  1356. }
  1357. if(m_pActiveXPage1 != NULL)
  1358. {
  1359. delete m_pActiveXPage1;
  1360. m_pActiveXPage1 = NULL;
  1361. }
  1362. if(m_pActiveXPage2 != NULL)
  1363. {
  1364. delete m_pActiveXPage2;
  1365. m_pActiveXPage2 = NULL;
  1366. }
  1367. return BC::Destroy();
  1368. }
  1369. const CLSID CLSID_OCXSnapin = {0xC96401CF, 0x0E17,0x11D3, {0x88,0x5B,0x00,0xC0,0x4F,0x72,0xC7,0x17}};
  1370. static const GUID GUID_OCXSnapinNodetype = {0xc96401d0, 0xe17, 0x11d3, { 0x88, 0x5b, 0x0, 0xc0, 0x4f, 0x72, 0xc7, 0x17 } };
  1371. static LPCTSTR szClsid_OCXSnapin = TEXT("{C96401CF-0E17-11D3-885B-00C04F72C717}");
  1372. static LPCTSTR szGuidOCXSnapinNodetype = TEXT("{C96401D0-0E17-11D3-885B-00C04F72C717}");
  1373. CSnapinDescriptor &
  1374. COCXSnapinData::GetSnapinDescriptor()
  1375. {
  1376. static CSnapinDescriptor snapinDescription(IDS_ACTIVEXCONTROL,
  1377. IDS_OCXSNAPIN_DESC, IDI_OCX, IDB_OCX_16, IDB_OCX_16, IDB_OCX_32,
  1378. CLSID_OCXSnapin, szClsid_OCXSnapin, GUID_OCXSnapinNodetype,
  1379. szGuidOCXSnapinNodetype, TEXT("OCX"), TEXT("Snapins.OCXSnapin"),
  1380. TEXT("Snapins.OCXSnapin.1"), MMC_VIEW_OPTIONS_NOLISTVIEWS /*viewOptions*/ );
  1381. return snapinDescription;
  1382. }
  1383. // IExtendPropertySheet2
  1384. STDMETHODIMP
  1385. COCXSnapinData::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, LPDATAOBJECT lpIDataObject)
  1386. {
  1387. HPROPSHEETPAGE hPage;
  1388. ASSERT(lpProvider != NULL);
  1389. if(lpProvider == NULL)
  1390. {
  1391. //TraceError(TEXT("CHTMLSnapinData::CreatePropertyPages"));
  1392. return E_UNEXPECTED;
  1393. }
  1394. ASSERT(m_pActiveXPage0 == NULL);
  1395. ASSERT(m_pActiveXPage1 == NULL);
  1396. ASSERT(m_pActiveXPage2 == NULL);
  1397. // create property pages
  1398. m_pActiveXPage0 = new CActiveXPage0;
  1399. m_pActiveXPage1 = new CActiveXPage1;
  1400. m_pActiveXPage2 = new CActiveXPage2;
  1401. // pass in pointer to data structure
  1402. m_pActiveXPage0->Initialize(this);
  1403. m_pActiveXPage1->Initialize(this);
  1404. m_pActiveXPage2->Initialize(this);
  1405. // Add Pages to property sheet
  1406. hPage=CreatePropertySheetPage(&m_pActiveXPage0->m_psp);
  1407. lpProvider->AddPage(hPage);
  1408. hPage=CreatePropertySheetPage(&m_pActiveXPage1->m_psp);
  1409. lpProvider->AddPage(hPage);
  1410. hPage=CreatePropertySheetPage(&m_pActiveXPage2->m_psp);
  1411. lpProvider->AddPage(hPage);
  1412. return S_OK;
  1413. }
  1414. //############################################################################
  1415. //############################################################################
  1416. //
  1417. // Implementation of class COCXSnapinComponent
  1418. //
  1419. //############################################################################
  1420. //############################################################################
  1421. /*+-------------------------------------------------------------------------*
  1422. *
  1423. * COCXSnapinComponent::Notify
  1424. *
  1425. * PURPOSE: Implements the CComponent::Notify method
  1426. *
  1427. * PARAMETERS:
  1428. * LPDATAOBJECT lpDataObject :
  1429. * MMC_NOTIFY_TYPE event :
  1430. * LPARAM arg :
  1431. * LPARAM param :
  1432. *
  1433. * RETURNS:
  1434. * HRESULT
  1435. *
  1436. *+-------------------------------------------------------------------------*/
  1437. HRESULT
  1438. COCXSnapinComponent::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  1439. {
  1440. HRESULT hr = S_OK;
  1441. switch(event)
  1442. {
  1443. // Handle just the OCX initialization notify
  1444. case MMCN_INITOCX:
  1445. return OnInitOCX(lpDataObject, arg, param);
  1446. break;
  1447. default:
  1448. // Pass other notifications on to base class
  1449. return CSnapinComponentImpl::Notify(lpDataObject, event, arg, param);
  1450. break;
  1451. }
  1452. return hr;
  1453. }
  1454. /*+-------------------------------------------------------------------------*
  1455. *
  1456. * COCXSnapinComponent::OnInitOCX
  1457. *
  1458. * PURPOSE: Handles the MMCN_INITOCX message.
  1459. *
  1460. * PARAMETERS:
  1461. * LPDATAOBJECT lpDataObject :
  1462. * LPARAM arg :
  1463. * LPARAM param :
  1464. *
  1465. * RETURNS:
  1466. * HRESULT
  1467. *
  1468. *+-------------------------------------------------------------------------*/
  1469. HRESULT
  1470. COCXSnapinComponent::OnInitOCX(LPDATAOBJECT lpDataObject, LPARAM arg, LPARAM param)
  1471. {
  1472. HRESULT hr = S_OK;
  1473. ASSERT(param != NULL);
  1474. IUnknown* pUnknown = reinterpret_cast<IUnknown*>(param);
  1475. ASSERT(m_bLoaded || m_bInitialized);
  1476. // Load or initialze the OCX
  1477. if (m_bLoaded || m_bInitialized)
  1478. {
  1479. IPersistStreamInitPtr spIPStmInit;
  1480. // Query for stream support
  1481. m_spIPStm = pUnknown;
  1482. // if none, try streamInit
  1483. if (m_spIPStm == NULL)
  1484. {
  1485. spIPStmInit = pUnknown;
  1486. // if streamInit found, cast to normal stream pointer
  1487. // so common methods can be called from single pointer
  1488. if (spIPStmInit != NULL)
  1489. m_spIPStm = (IPersistStream*)spIPStmInit.GetInterfacePtr();
  1490. }
  1491. // if either type of stream persistance supported
  1492. if (m_spIPStm != NULL)
  1493. {
  1494. // if load method was called, then ask OCX to load from inner stream
  1495. // Note that inner stream will not exist if OCX was never created
  1496. if (m_bLoaded)
  1497. {
  1498. IStreamPtr spStm;
  1499. HRESULT hr2 = m_spStg->OpenStream(SZ_OCXSTREAM, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, NULL, &spStm);
  1500. if (SUCCEEDED(hr2))
  1501. hr = m_spIPStm->Load(spStm);
  1502. else
  1503. m_bLoaded = FALSE;
  1504. }
  1505. // if no load was done and OCX requires an InitNew, give it one now
  1506. if (!m_bLoaded && spIPStmInit != NULL)
  1507. hr = spIPStmInit->InitNew();
  1508. }
  1509. else
  1510. {
  1511. // Query for storage support
  1512. m_spIPStg = pUnknown;
  1513. // if storage supported, ask OCX to load from inner storage
  1514. // Note that inner storage will not exist if OCX was never created
  1515. if (m_spIPStg != NULL)
  1516. {
  1517. if (m_bLoaded)
  1518. {
  1519. ASSERT(m_spStgInner == NULL);
  1520. HRESULT hr2 = m_spStg->OpenStorage(SZ_OCXSTORAGE, NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE,
  1521. NULL, NULL, &m_spStgInner);
  1522. if (SUCCEEDED(hr2))
  1523. hr = m_spIPStg->Load(m_spStgInner);
  1524. else
  1525. m_bLoaded = FALSE;
  1526. }
  1527. // if no load done, create an inner storage and init from it
  1528. if (!m_bLoaded)
  1529. {
  1530. ASSERT(m_spStgInner == NULL);
  1531. hr = m_spStg->CreateStorage(SZ_OCXSTORAGE, STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL,
  1532. NULL, &m_spStgInner);
  1533. if (SUCCEEDED(hr))
  1534. hr = m_spIPStg->InitNew(m_spStgInner);
  1535. }
  1536. }
  1537. }
  1538. }
  1539. return hr;
  1540. }
  1541. STDMETHODIMP COCXSnapinComponent::InitNew(IStorage* pStg)
  1542. {
  1543. if (pStg == NULL)
  1544. return E_POINTER;
  1545. if (m_bInitialized)
  1546. return CO_E_ALREADYINITIALIZED;
  1547. // Hold onto storage
  1548. m_spStg = pStg;
  1549. m_bInitialized = TRUE;
  1550. return S_OK;
  1551. }
  1552. HRESULT COCXSnapinComponent::Load(IStorage* pStg)
  1553. {
  1554. if (pStg == NULL)
  1555. return E_POINTER;
  1556. if (m_bInitialized)
  1557. return CO_E_ALREADYINITIALIZED;
  1558. // Hold onto storage
  1559. m_spStg = pStg;
  1560. m_bLoaded = TRUE;
  1561. m_bInitialized = TRUE;
  1562. return S_OK;
  1563. }
  1564. HRESULT COCXSnapinComponent::IsDirty()
  1565. {
  1566. HRESULT hr = S_FALSE;
  1567. if (m_spIPStm != NULL)
  1568. {
  1569. hr = m_spIPStm->IsDirty();
  1570. }
  1571. else if (m_spIPStg != NULL)
  1572. {
  1573. hr = m_spIPStg->IsDirty();
  1574. }
  1575. return hr;
  1576. }
  1577. HRESULT COCXSnapinComponent::Save(IStorage* pStg, BOOL fSameAsLoad)
  1578. {
  1579. DECLARE_SC(sc, TEXT("COCXSnapinComponent::Save"));
  1580. // parameter check
  1581. sc = ScCheckPointers( pStg );
  1582. if (sc)
  1583. return sc.ToHr();
  1584. // to be able to save we need to be initialized
  1585. sc = ScCheckPointers( m_spStg, E_UNEXPECTED );
  1586. if (sc)
  1587. return sc.ToHr();
  1588. // if need to use the new storage - make a copy
  1589. if (!fSameAsLoad)
  1590. {
  1591. sc = m_spStg->CopyTo(0, NULL, NULL, pStg);
  1592. if (sc)
  1593. return sc.ToHr();
  1594. // release cached storage (in case we have it) - it must change
  1595. m_spStgInner = NULL;
  1596. // hold onto the new storage
  1597. m_spStg = pStg;
  1598. // assignment uses QI - recheck!
  1599. sc = ScCheckPointers( m_spStg, E_UNEXPECTED );
  1600. if (sc)
  1601. return sc.ToHr();
  1602. }
  1603. // if storage support, ask OCX to save to inner storage
  1604. if (m_spIPStg)
  1605. {
  1606. bool bSameStorageForSnapin = true;
  1607. // if saving to different storage, create new inner storage on it and pass to OCX
  1608. if ( m_spStgInner == NULL )
  1609. {
  1610. sc = pStg->CreateStorage(SZ_OCXSTORAGE, STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, NULL, NULL, &m_spStgInner);
  1611. if (sc)
  1612. return sc.ToHr();
  1613. bSameStorageForSnapin = false;
  1614. }
  1615. // recheck the pointer
  1616. sc = ScCheckPointers( m_spStgInner, E_UNEXPECTED );
  1617. if (sc)
  1618. return sc.ToHr();
  1619. // save to the storage
  1620. sc = m_spIPStg->Save( m_spStgInner, (fSameAsLoad && bSameStorageForSnapin) );
  1621. if (sc)
  1622. return sc.ToHr();
  1623. }
  1624. // else if stream support, create/open stream and save to it
  1625. else if (m_spIPStm)
  1626. {
  1627. // if stream support, create internal stream and pass to OCX
  1628. IStreamPtr spStm;
  1629. sc = m_spStg->CreateStream(SZ_OCXSTREAM, STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, NULL, NULL, &spStm);
  1630. if (sc)
  1631. return sc.ToHr();
  1632. sc = m_spIPStm->Save(spStm, TRUE);
  1633. if (sc)
  1634. return sc.ToHr();
  1635. }
  1636. else
  1637. {
  1638. // we are here if the OCX was never created (i.e., this component never owned the result pane)
  1639. // if node was loaded and has to save to a new file, just copy the current storage to the new one
  1640. }
  1641. return sc.ToHr();
  1642. }
  1643. HRESULT COCXSnapinComponent::HandsOffStorage()
  1644. {
  1645. // Release storage if holding ref
  1646. // if ocx is holding storage, forward call to it
  1647. if (m_spIPStg != NULL && m_spStgInner != NULL)
  1648. m_spIPStg->HandsOffStorage();
  1649. // Free our own refs
  1650. m_spStgInner = NULL;
  1651. m_spStg = NULL;
  1652. return S_OK;
  1653. }
  1654. HRESULT COCXSnapinComponent::SaveCompleted(IStorage* pStgNew)
  1655. {
  1656. HRESULT hr = S_OK;
  1657. if (m_spIPStg != NULL)
  1658. {
  1659. // if new storage provided
  1660. if (pStgNew != NULL && pStgNew != m_spStg)
  1661. {
  1662. // Create new inner storage and give to OCX
  1663. IStoragePtr spStgInner;
  1664. hr = pStgNew->CreateStorage(SZ_OCXSTORAGE, STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, NULL, NULL, &spStgInner);
  1665. if (SUCCEEDED(hr))
  1666. hr = m_spIPStg->SaveCompleted(spStgInner);
  1667. // Free current inner storage and hold onto new one
  1668. m_spStgInner = spStgInner;
  1669. }
  1670. else
  1671. {
  1672. m_spIPStg->SaveCompleted(NULL);
  1673. }
  1674. }
  1675. if (pStgNew != NULL)
  1676. m_spStg = pStgNew;
  1677. return hr;
  1678. }
  1679. HRESULT COCXSnapinComponent::GetClassID(CLSID *pClassID)
  1680. {
  1681. return E_NOTIMPL;
  1682. }