Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1367 lines
33 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. /* File: snapin.cpp
  3. Description: Implements the MMC snapin for disk quota policy.
  4. Revision History:
  5. Date Description Programmer
  6. -------- --------------------------------------------------- ----------
  7. 02/14/98 Initial creation. BrianAu
  8. 06/25/98 Disabled snapin code with #ifdef POLICY_MMC_SNAPIN. BrianAu
  9. Switching to ADM-file approach to entering policy
  10. data. Keeping snapin code available in case
  11. we decide to switch back at a later time.
  12. */
  13. ///////////////////////////////////////////////////////////////////////////////
  14. #include "pch.h"
  15. #pragma hdrstop
  16. #ifdef POLICY_MMC_SNAPIN
  17. #include "snapin.h"
  18. #include "resource.h"
  19. #include "guidsp.h"
  20. #include "policy.h"
  21. //-----------------------------------------------------------------------------
  22. // CSnapInItem
  23. //-----------------------------------------------------------------------------
  24. //
  25. // General rendering function usable by this class and any
  26. // derived classes to render data onto a medium. Only accepts
  27. // TYMED_HGLOBAL.
  28. //
  29. HRESULT
  30. CSnapInItem::RenderData( // [ static ]
  31. LPVOID pvData,
  32. int cbData,
  33. LPSTGMEDIUM pMedium
  34. )
  35. {
  36. DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CSnapInItem::RenderData [ general ]")));
  37. HRESULT hr = DV_E_TYMED;
  38. if (NULL == pvData || NULL == pMedium)
  39. return E_INVALIDARG;
  40. //
  41. // Make sure the type medium is HGLOBAL
  42. //
  43. if (TYMED_HGLOBAL == pMedium->tymed)
  44. {
  45. //
  46. // Create the stream on the hGlobal passed in
  47. //
  48. LPSTREAM pStream;
  49. hr = CreateStreamOnHGlobal(pMedium->hGlobal, FALSE, &pStream);
  50. if (SUCCEEDED(hr))
  51. {
  52. //
  53. // Write to the stream the number of bytes
  54. //
  55. unsigned long written;
  56. hr = pStream->Write(pvData, cbData, &written);
  57. //
  58. // Because we told CreateStreamOnHGlobal with 'FALSE',
  59. // only the stream is released here.
  60. // Note - the caller (i.e. snap-in, object) will free the HGLOBAL
  61. // at the correct time. This is according to the IDataObject specification.
  62. //
  63. pStream->Release();
  64. }
  65. }
  66. return hr;
  67. }
  68. //
  69. // Format a GUID as a string.
  70. //
  71. void
  72. CSnapInItem::GUIDToString( // [ static ]
  73. const GUID& guid,
  74. CString *pstr
  75. )
  76. {
  77. StringFromGUID2(guid, pstr->GetBuffer(50), 50);
  78. pstr->ReleaseBuffer();
  79. }
  80. //-----------------------------------------------------------------------------
  81. // CScopeItem
  82. //-----------------------------------------------------------------------------
  83. UINT CScopeItem::m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
  84. UINT CScopeItem::m_cfNodeTypeString = RegisterClipboardFormat(CCF_SZNODETYPE);
  85. UINT CScopeItem::m_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
  86. UINT CScopeItem::m_cfCoClass = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
  87. //
  88. // Returns: S_OK = Data successfully rendered.
  89. // DV_E_CLIPFORMAT = Clipboard format not supported.
  90. // DV_E_TYMED = Medium is not HGLOBAL.
  91. // Other = Rendering error.
  92. HRESULT
  93. CScopeItem::RenderData(
  94. UINT cf,
  95. LPSTGMEDIUM pMedium
  96. ) const
  97. {
  98. DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CScopeItem::RenderData")));
  99. HRESULT hr = DV_E_CLIPFORMAT;
  100. if (cf == m_cfNodeType)
  101. {
  102. DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("Rendering CCF_NODETYPE")));
  103. hr = CSnapInItem::RenderData((LPVOID)&m_idType, sizeof(m_idType), pMedium);
  104. }
  105. else if (cf == m_cfNodeTypeString)
  106. {
  107. DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("Rendering CCF_SZNODETYPE")));
  108. CString s;
  109. GUIDToString(m_idType, &s);
  110. hr = CSnapInItem::RenderData((LPVOID)s.Cstr(), (s.Length() + 1) * sizeof(TCHAR), pMedium);
  111. }
  112. else if (cf == m_cfDisplayName)
  113. {
  114. DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("Rendering CCF_DISPLAY_NAME")));
  115. const CString& s = m_cd.DisplayName();
  116. hr = CSnapInItem::RenderData((LPVOID)s.Cstr(), (s.Length() + 1) * sizeof(TCHAR), pMedium);
  117. }
  118. else if (cf == m_cfCoClass)
  119. {
  120. DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("Rendering CCF_SNAPIN_CLASSID")));
  121. hr = CSnapInItem::RenderData((LPVOID)&m_cd.ClassId(), sizeof(GUID), pMedium);
  122. }
  123. return hr;
  124. }
  125. CScopeItem::~CScopeItem(
  126. void
  127. )
  128. {
  129. DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CScopeItem::~CScopeItem")));
  130. while(0 < m_rgpChildren.Count())
  131. {
  132. delete m_rgpChildren[0];
  133. m_rgpChildren.Delete(0);
  134. }
  135. while(0 < m_rgpResultItems.Count())
  136. {
  137. delete m_rgpResultItems[0];
  138. m_rgpResultItems.Delete(0);
  139. }
  140. }
  141. //-----------------------------------------------------------------------------
  142. // CSnapInComp
  143. //-----------------------------------------------------------------------------
  144. CSnapInComp::CSnapInComp(
  145. HINSTANCE hInstance,
  146. CSnapInCompData& cd
  147. ) : m_cRef(0),
  148. m_hInstance(hInstance),
  149. m_cd(cd),
  150. m_pConsole(NULL),
  151. m_pResult(NULL),
  152. m_pHeader(NULL),
  153. m_pImageResult(NULL),
  154. m_strColumn(hInstance, IDS_SNAPIN_COLUMN),
  155. m_cxColumn(200),
  156. m_lViewMode(LVS_ICON)
  157. {
  158. DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CSnapInComp::CSnapInComp")));
  159. }
  160. CSnapInComp::~CSnapInComp(
  161. void
  162. )
  163. {
  164. DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CSnapInComp::~CSnapInComp")));
  165. if (NULL != m_pImageResult)
  166. {
  167. m_pImageResult->Release();
  168. m_pImageResult = NULL;
  169. }
  170. if (NULL != m_pResult)
  171. {
  172. m_pResult->Release();
  173. m_pResult = NULL;
  174. }
  175. if (NULL != m_pHeader)
  176. {
  177. m_pHeader->Release();
  178. m_pHeader = NULL;
  179. }
  180. if (NULL != m_pConsole)
  181. {
  182. m_pConsole->Release();
  183. m_pConsole = NULL;
  184. }
  185. }
  186. HRESULT
  187. CSnapInComp::QueryInterface(
  188. REFIID riid,
  189. LPVOID *ppvOut
  190. )
  191. {
  192. DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CSnapInComp::QueryInterface")));
  193. DBGPRINTIID(DM_SNAPIN, DL_MID, riid);
  194. HRESULT hr = E_NOINTERFACE;
  195. if (NULL == ppvOut)
  196. return E_INVALIDARG;
  197. *ppvOut = NULL;
  198. if (IID_IUnknown == riid || IID_IComponent == riid)
  199. {
  200. *ppvOut = this;
  201. }
  202. else if (IID_IExtendContextMenu == riid)
  203. {
  204. *ppvOut = static_cast<IExtendContextMenu *>(this);
  205. }
  206. if (NULL != *ppvOut)
  207. {
  208. ((LPUNKNOWN)*ppvOut)->AddRef();
  209. hr = NOERROR;
  210. }
  211. return hr;
  212. }
  213. ULONG
  214. CSnapInComp::AddRef(
  215. void
  216. )
  217. {
  218. DBGTRACE((DM_SNAPIN, DL_LOW, TEXT("CSnapInComp::AddRef")));
  219. ULONG ulReturn = m_cRef + 1;
  220. InterlockedIncrement(&m_cRef);
  221. return ulReturn;
  222. }
  223. ULONG
  224. CSnapInComp::Release(
  225. void
  226. )
  227. {
  228. DBGTRACE((DM_SNAPIN, DL_LOW, TEXT("CSnapInComp::Release")));
  229. ULONG ulReturn = m_cRef - 1;
  230. if (InterlockedDecrement(&m_cRef) == 0)
  231. {
  232. delete this;
  233. ulReturn = 0;
  234. }
  235. return ulReturn;
  236. }
  237. HRESULT
  238. CSnapInComp::Initialize(
  239. LPCONSOLE lpConsole
  240. )
  241. {
  242. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::Initialize")));
  243. HRESULT hr = NOERROR;
  244. m_pConsole = lpConsole;
  245. m_pConsole->AddRef();
  246. //
  247. // Get IResultData interface to result pane.
  248. //
  249. hr = m_pConsole->QueryInterface(IID_IResultData,
  250. reinterpret_cast<void **>(&m_pResult));
  251. if (FAILED(hr))
  252. return hr;
  253. //
  254. // Get IHeaderCtrl interface to header control.
  255. //
  256. hr = m_pConsole->QueryInterface(IID_IHeaderCtrl,
  257. reinterpret_cast<void **>(&m_pHeader));
  258. if (FAILED(hr))
  259. return hr;
  260. // m_pConsole->SetHeader(m_pHeader); // Needed?
  261. hr = m_pConsole->QueryResultImageList(&m_pImageResult);
  262. return hr;
  263. }
  264. HRESULT
  265. CSnapInComp::Notify(
  266. LPDATAOBJECT lpDataObject,
  267. MMC_NOTIFY_TYPE event,
  268. long arg,
  269. long param
  270. )
  271. {
  272. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::Notify")));
  273. DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("\tpObj = 0x%08X, event = %d, arg = %d, param = 0x%08X"), lpDataObject, event, arg, param));
  274. HRESULT hr = S_OK;
  275. switch(event)
  276. {
  277. case MMCN_ADD_IMAGES:
  278. DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("MMCN_ADD_IMAGES")));
  279. {
  280. //
  281. // Result pane image list has only one icon.
  282. //
  283. HICON hIcon = LoadIcon(m_hInstance, MAKEINTRESOURCE(IDI_QUOTA));
  284. m_pImageResult->ImageListSetIcon(reinterpret_cast<long *>(hIcon), 0);
  285. }
  286. break;
  287. case MMCN_SHOW:
  288. DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("MMCN_SHOW, arg = %d"), arg));
  289. if (arg)
  290. {
  291. //
  292. // Showing view. Set view information.
  293. //
  294. m_pHeader->InsertColumn(0, m_strColumn, LVCFMT_LEFT, m_cxColumn);
  295. m_pResult->SetViewMode(m_lViewMode);
  296. CScopeItem *psi;
  297. hr = GetScopeItem((HSCOPEITEM)param, &psi);
  298. if (FAILED(hr))
  299. {
  300. DBGERROR((TEXT("Failed getting item for MMCN_SHOW")));
  301. return hr;
  302. }
  303. RESULTDATAITEM rdi;
  304. rdi.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  305. int cResultItems = psi->NumResultItems();
  306. for (int i = 0; i < cResultItems; i++)
  307. {
  308. CResultItem *pri = psi->ResultItem(i);
  309. DBGASSERT((NULL != pri));
  310. rdi.str = MMC_CALLBACK;
  311. rdi.nImage = pri->ImageIndex();
  312. rdi.lParam = (LPARAM)pri;
  313. m_pResult->InsertItem(&rdi);
  314. }
  315. }
  316. else
  317. {
  318. //
  319. // Hiding view. Gather view information.
  320. //
  321. m_pHeader->GetColumnWidth(0, &m_cxColumn);
  322. m_pResult->GetViewMode(&m_lViewMode);
  323. }
  324. break;
  325. case MMCN_CLICK:
  326. case MMCN_DBLCLICK:
  327. DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("MMCN_CLICK or MMCN_DBLCLICK")));
  328. m_cd.OpenVolumeQuotaProperties();
  329. break;
  330. default:
  331. break;
  332. }
  333. return hr;
  334. }
  335. HRESULT
  336. CSnapInComp::Destroy(
  337. LONG cookie
  338. )
  339. {
  340. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::Destroy")));
  341. if (NULL != m_pImageResult)
  342. {
  343. m_pImageResult->Release();
  344. m_pImageResult = NULL;
  345. }
  346. if (NULL != m_pResult)
  347. {
  348. m_pResult->Release();
  349. m_pResult = NULL;
  350. }
  351. if (NULL != m_pHeader)
  352. {
  353. m_pHeader->Release();
  354. m_pHeader = NULL;
  355. }
  356. if (NULL != m_pConsole)
  357. {
  358. m_pConsole->Release();
  359. m_pConsole = NULL;
  360. }
  361. return NOERROR;
  362. }
  363. HRESULT
  364. CSnapInComp::QueryDataObject(
  365. long cookie,
  366. DATA_OBJECT_TYPES type,
  367. LPDATAOBJECT *ppDataObject
  368. )
  369. {
  370. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::QueryDataObject")));
  371. //
  372. // Forward the data object query to the component data object.
  373. //
  374. return m_cd.QueryDataObject(cookie, type, ppDataObject);
  375. }
  376. HRESULT
  377. CSnapInComp::GetResultViewType(
  378. long cookie,
  379. LPOLESTR *ppViewType,
  380. long *pViewOptions
  381. )
  382. {
  383. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::GetResultViewType")));
  384. //
  385. // Tell snapin mgr to use default listview.
  386. //
  387. return S_FALSE;
  388. }
  389. HRESULT
  390. CSnapInComp::GetDisplayInfo(
  391. RESULTDATAITEM *prdi
  392. )
  393. {
  394. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::GetDisplayInfo")));
  395. CSnapInItem *psi = reinterpret_cast<CSnapInItem *>(prdi->lParam);
  396. if (RDI_STR & prdi->mask)
  397. {
  398. prdi->str = (LPOLESTR)psi->DisplayName().Cstr();
  399. }
  400. if (RDI_IMAGE & prdi->mask)
  401. {
  402. prdi->nImage = psi->ImageIndex();
  403. }
  404. if (RDI_STATE & prdi->mask)
  405. {
  406. prdi->nState = 0;
  407. }
  408. if (RDI_INDEX & prdi->mask)
  409. {
  410. prdi->nIndex = 0;
  411. }
  412. if (RDI_INDENT & prdi->mask)
  413. {
  414. prdi->iIndent = 0;
  415. }
  416. return S_OK;
  417. }
  418. HRESULT
  419. CSnapInComp::CompareObjects(
  420. LPDATAOBJECT pdoA,
  421. LPDATAOBJECT pdoB
  422. )
  423. {
  424. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::CompareObjects")));
  425. return m_cd.CompareObjects(pdoA, pdoB);
  426. }
  427. HRESULT
  428. CSnapInComp::AddMenuItems(
  429. LPDATAOBJECT pDataObject,
  430. LPCONTEXTMENUCALLBACK piCallback,
  431. long *pInsertionAllowed
  432. )
  433. {
  434. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::AddMenuItems")));
  435. return m_cd.AddMenuItems(pDataObject, piCallback, pInsertionAllowed);
  436. }
  437. HRESULT
  438. CSnapInComp::Command(
  439. long lCommandID,
  440. LPDATAOBJECT pDataObject
  441. )
  442. {
  443. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::Command")));
  444. return m_cd.Command(lCommandID, pDataObject);
  445. }
  446. HRESULT
  447. CSnapInComp::GetScopeItem(
  448. HSCOPEITEM hItem,
  449. CScopeItem **ppsi
  450. ) const
  451. {
  452. HRESULT hr;
  453. SCOPEDATAITEM item;
  454. item.mask = SDI_PARAM;
  455. item.ID = hItem;
  456. hr = m_cd.m_pScope->GetItem(&item);
  457. if (SUCCEEDED(hr))
  458. {
  459. *ppsi = reinterpret_cast<CScopeItem *>(item.lParam);
  460. }
  461. return hr;
  462. }
  463. //-----------------------------------------------------------------------------
  464. // CSnapInCompData
  465. //-----------------------------------------------------------------------------
  466. CSnapInCompData::CSnapInCompData(
  467. HINSTANCE hInstance,
  468. LPCTSTR pszDisplayName,
  469. const GUID& idClass
  470. ) : m_cRef(0),
  471. m_hInstance(hInstance),
  472. m_strDisplayName(pszDisplayName),
  473. m_idClass(idClass),
  474. m_pConsole(NULL),
  475. m_pScope(NULL),
  476. m_pRootScopeItem(NULL),
  477. m_hRoot(NULL),
  478. m_pGPEInformation(NULL)
  479. {
  480. DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CSnapInCompData::CSnapInCompData")));
  481. InterlockedIncrement(&g_cRefThisDll);
  482. //
  483. // Root node.
  484. //
  485. m_pRootScopeItem = new CScopeItem(NODEID_DiskQuotaRoot, // Node ID
  486. *this, // Snapin comp data ref.
  487. NULL, // Parent node ptr.
  488. TEXT("<root>"), // Node name str.
  489. -1, // Image index.
  490. -1); // Image index "open".
  491. //
  492. // Add "Disk Quota Settings" as a child of the root.
  493. //
  494. CString strName(hInstance, IDS_SNAPIN_SCOPENAME);
  495. CScopeItem *psi = new CScopeItem(NODEID_DiskQuotaSettings,
  496. *this,
  497. m_pRootScopeItem,
  498. strName,
  499. iICON_QUOTA,
  500. iICON_QUOTA_OPEN);
  501. m_pRootScopeItem->AddChild(psi);
  502. //
  503. // Add single result item to "Disk Quota Settings".
  504. //
  505. strName.Format(hInstance, IDS_SNAPIN_RESULTNAME);
  506. psi->AddResultItem(new CResultItem(strName, 0, *psi));
  507. }
  508. CSnapInCompData::~CSnapInCompData(
  509. void
  510. )
  511. {
  512. DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CSnapInCompData::~CSnapInCompData")));
  513. delete m_pRootScopeItem;
  514. if (NULL != m_pScope)
  515. m_pScope->Release();
  516. if (NULL != m_pConsole)
  517. m_pConsole->Release();
  518. if (NULL != m_pGPEInformation)
  519. m_pGPEInformation->Release();
  520. InterlockedDecrement(&g_cRefThisDll);
  521. }
  522. HRESULT
  523. CSnapInCompData::QueryInterface(
  524. REFIID riid,
  525. LPVOID *ppvOut
  526. )
  527. {
  528. DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CSnapInCompData::QueryInterface")));
  529. DBGPRINTIID(DM_SNAPIN, DL_MID, riid);
  530. HRESULT hr = E_NOINTERFACE;
  531. if (NULL == ppvOut)
  532. return E_INVALIDARG;
  533. *ppvOut = NULL;
  534. if (IID_IUnknown == riid || IID_IComponentData == riid)
  535. {
  536. *ppvOut = this;
  537. }
  538. else if (IID_IPersistStreamInit == riid)
  539. {
  540. *ppvOut = static_cast<IPersistStreamInit *>(this);
  541. }
  542. else if (IID_IExtendContextMenu == riid)
  543. {
  544. *ppvOut = static_cast<IExtendContextMenu *>(this);
  545. }
  546. if (NULL != *ppvOut)
  547. {
  548. ((LPUNKNOWN)*ppvOut)->AddRef();
  549. hr = NOERROR;
  550. }
  551. return hr;
  552. }
  553. ULONG
  554. CSnapInCompData::AddRef(
  555. void
  556. )
  557. {
  558. DBGTRACE((DM_SNAPIN, DL_LOW, TEXT("CSnapInCompData::AddRef")));
  559. ULONG ulReturn = m_cRef + 1;
  560. InterlockedIncrement(&m_cRef);
  561. return ulReturn;
  562. }
  563. ULONG
  564. CSnapInCompData::Release(
  565. void
  566. )
  567. {
  568. DBGTRACE((DM_SNAPIN, DL_LOW, TEXT("CSnapInCompData::Release")));
  569. ULONG ulReturn = m_cRef - 1;
  570. if (InterlockedDecrement(&m_cRef) == 0)
  571. {
  572. delete this;
  573. ulReturn = 0;
  574. }
  575. return ulReturn;
  576. }
  577. HRESULT
  578. CSnapInCompData::Initialize(
  579. LPUNKNOWN pUnk
  580. )
  581. {
  582. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::Initialize")));
  583. DBGASSERT((NULL != pUnk));
  584. DBGASSERT((NULL == m_pConsole));
  585. HRESULT hr = pUnk->QueryInterface(IID_IConsole,
  586. reinterpret_cast<void **>(&m_pConsole));
  587. if (FAILED(hr))
  588. {
  589. DBGERROR((TEXT("CSnapInCompData failed QI for IID_IConsole")));
  590. return hr;
  591. }
  592. hr = pUnk->QueryInterface(IID_IConsoleNameSpace,
  593. reinterpret_cast<void **>(&m_pScope));
  594. if (FAILED(hr))
  595. {
  596. DBGERROR((TEXT("CSnapInCompData failed QI for IID_IConsoleNameSpace")));
  597. return hr;
  598. }
  599. LPIMAGELIST pImageList = NULL;
  600. hr = m_pConsole->QueryScopeImageList(&pImageList);
  601. if (FAILED(hr))
  602. {
  603. DBGERROR((TEXT("CSnapInCompData failed to get scope image list")));
  604. return hr;
  605. }
  606. //
  607. // Set the scope pane's image list icons.
  608. //
  609. static const struct
  610. {
  611. int idIcon;
  612. int iIconIndex;
  613. } rgIcons[] = { { IDI_QUOTA, iICON_QUOTA },
  614. { IDI_QUOTA_OPEN, iICON_QUOTA_OPEN } };
  615. for (int i = 0; i < ARRAYSIZE(rgIcons); i++)
  616. {
  617. HICON hIcon = LoadIcon(m_hInstance,
  618. MAKEINTRESOURCE(rgIcons[i].idIcon));
  619. pImageList->ImageListSetIcon(reinterpret_cast<long *>(hIcon),
  620. rgIcons[i].iIconIndex);
  621. }
  622. pImageList->Release();
  623. return hr;
  624. }
  625. HRESULT
  626. CSnapInCompData::CreateComponent(
  627. LPCOMPONENT *ppComp
  628. )
  629. {
  630. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::CreateComponent")));
  631. HRESULT hr = S_OK;
  632. try
  633. {
  634. CSnapInComp *pComp = new CSnapInComp(m_hInstance, *this);
  635. hr = pComp->QueryInterface(IID_IComponent, reinterpret_cast<void **>(ppComp));
  636. }
  637. catch(CAllocException& e)
  638. {
  639. DBGERROR((TEXT("Insufficient memory")));
  640. hr = E_OUTOFMEMORY;
  641. }
  642. return hr;
  643. }
  644. HRESULT
  645. CSnapInCompData::Destroy(
  646. void
  647. )
  648. {
  649. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::Destroy")));
  650. if (NULL != m_pScope)
  651. {
  652. m_pScope->Release();
  653. m_pScope = NULL;
  654. }
  655. if (NULL != m_pConsole)
  656. {
  657. m_pConsole->Release();
  658. m_pConsole = NULL;
  659. }
  660. return S_OK;
  661. }
  662. HRESULT
  663. CSnapInCompData::Notify(
  664. LPDATAOBJECT pDataObject,
  665. MMC_NOTIFY_TYPE event,
  666. long arg,
  667. long param
  668. )
  669. {
  670. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::Notify")));
  671. DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("\tpDataObj = 0x%08X, event = 0x%08X, arg = %d, param = 0x%08X"),
  672. pDataObject, event, arg, param));
  673. HRESULT hr = S_OK;
  674. try
  675. {
  676. switch(event)
  677. {
  678. case MMCN_EXPAND:
  679. if (arg)
  680. {
  681. if (NULL == m_pGPEInformation)
  682. {
  683. hr = pDataObject->QueryInterface(IID_IGPEInformation,
  684. reinterpret_cast<void **>(&m_pGPEInformation));
  685. }
  686. if (NULL != m_pGPEInformation)
  687. {
  688. hr = EnumerateScopePane((HSCOPEITEM)param);
  689. }
  690. }
  691. break;
  692. default:
  693. break;
  694. }
  695. }
  696. catch(CAllocException& e)
  697. {
  698. DBGERROR((TEXT("Insufficient memory")));
  699. hr = E_OUTOFMEMORY;
  700. }
  701. return hr;
  702. }
  703. HRESULT
  704. CSnapInCompData::GetDisplayInfo(
  705. SCOPEDATAITEM *psdi
  706. )
  707. {
  708. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::GetDispInfo")));
  709. DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("\tmask = 0x%08X"), psdi->mask));
  710. HRESULT hr = S_OK;
  711. CScopeItem *pItem = reinterpret_cast<CScopeItem *>(psdi->lParam);
  712. if (psdi->mask & SDI_STR)
  713. {
  714. psdi->displayname = (LPOLESTR)((LPCTSTR)pItem->DisplayName());
  715. }
  716. if (psdi->mask & SDI_IMAGE)
  717. {
  718. psdi->nImage = pItem->ImageIndex();
  719. }
  720. if (psdi->mask & SDI_OPENIMAGE)
  721. {
  722. psdi->nOpenImage = pItem->OpenImageIndex();
  723. }
  724. if (psdi->mask & SDI_CHILDREN)
  725. {
  726. psdi->cChildren = pItem->NumChildren();
  727. }
  728. return hr;
  729. }
  730. HRESULT
  731. CSnapInCompData::CompareObjects(
  732. LPDATAOBJECT pdoA,
  733. LPDATAOBJECT pdoB
  734. )
  735. {
  736. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::GetDispInfo")));
  737. LPQUOTADATAOBJECT pDataA, pDataB;
  738. HRESULT hr = S_FALSE;
  739. if (FAILED(pdoA->QueryInterface(IID_IDiskQuotaSnapInData, reinterpret_cast<void **>(&pDataA))))
  740. return S_FALSE;
  741. if (FAILED(pdoB->QueryInterface(IID_IDiskQuotaSnapInData, reinterpret_cast<void **>(&pDataB))))
  742. {
  743. pDataA->Release();
  744. return FALSE;
  745. }
  746. CSnapInItem *psiA, *psiB;
  747. pDataA->GetItem(&psiA);
  748. pDataB->GetItem(&psiB);
  749. if (psiA == psiB)
  750. hr = S_OK;
  751. pDataA->Release();
  752. pDataB->Release();
  753. return hr;
  754. }
  755. HRESULT
  756. CSnapInCompData::QueryDataObject(
  757. long cookie,
  758. DATA_OBJECT_TYPES type,
  759. LPDATAOBJECT *ppDataObject
  760. )
  761. {
  762. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::QueryDataObject")));
  763. HRESULT hr = E_NOINTERFACE;
  764. CDataObject *pDataObject = NULL;
  765. LPQUOTADATAOBJECT pQuotaData = NULL;
  766. try
  767. {
  768. pDataObject = new CDataObject(*this);
  769. pDataObject->SetType(type);
  770. pDataObject->SetItem(reinterpret_cast<CSnapInItem *>(cookie));
  771. hr = pDataObject->QueryInterface(IID_IDataObject, (LPVOID *)ppDataObject);
  772. }
  773. catch(CAllocException& e)
  774. {
  775. DBGERROR((TEXT("Insufficient memory")));
  776. hr = E_OUTOFMEMORY;
  777. }
  778. return hr;
  779. }
  780. HRESULT
  781. CSnapInCompData::EnumerateScopePane (
  782. HSCOPEITEM hParent
  783. )
  784. {
  785. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::EnumerateScopePane")));
  786. HRESULT hr = S_OK;
  787. CScopeItem *psi = m_pRootScopeItem; // Default to enumerating from root.
  788. SCOPEDATAITEM item;
  789. if (NULL == m_hRoot)
  790. m_hRoot = hParent; // Remember the root node's handle.
  791. if (m_hRoot != hParent)
  792. {
  793. item.mask = SDI_PARAM;
  794. item.ID = hParent;
  795. hr = m_pScope->GetItem (&item);
  796. if (FAILED(hr))
  797. {
  798. DBGERROR((TEXT("Failed getting item")));
  799. return hr;
  800. }
  801. psi = reinterpret_cast<CScopeItem *>(item.lParam);
  802. }
  803. item.mask = SDI_STR | SDI_STATE | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
  804. item.nState = 0;
  805. item.relativeID = hParent;
  806. int cChildren = psi->NumChildren();
  807. for (int iChild = 0; iChild < cChildren; iChild++)
  808. {
  809. CScopeItem *pChild = psi->Child(iChild);
  810. item.displayname = MMC_CALLBACK;
  811. item.nImage = pChild->ImageIndex();
  812. item.nOpenImage = pChild->OpenImageIndex();
  813. item.cChildren = pChild->NumChildren();
  814. item.lParam = reinterpret_cast<LPARAM>(pChild);
  815. m_pScope->InsertItem (&item);
  816. }
  817. return S_OK;
  818. }
  819. HRESULT
  820. CSnapInCompData::InitNew(
  821. void
  822. )
  823. {
  824. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::InitNew")));
  825. return S_OK;
  826. }
  827. HRESULT
  828. CSnapInCompData::GetClassID(
  829. CLSID *pClassID
  830. )
  831. {
  832. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::GetClassID")));
  833. if (!pClassID)
  834. return E_FAIL;
  835. *pClassID = ClassId();
  836. return S_OK;
  837. }
  838. HRESULT
  839. CSnapInCompData::IsDirty(
  840. void
  841. )
  842. {
  843. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::IsDirty")));
  844. return S_FALSE;
  845. }
  846. HRESULT
  847. CSnapInCompData::Load(
  848. IStream *pStm
  849. )
  850. {
  851. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::Load")));
  852. return S_OK;
  853. }
  854. HRESULT
  855. CSnapInCompData::Save(
  856. IStream *pStm,
  857. BOOL fClearDirty
  858. )
  859. {
  860. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::Save")));
  861. return S_OK;
  862. }
  863. HRESULT
  864. CSnapInCompData::GetSizeMax(
  865. ULARGE_INTEGER *pcbSize
  866. )
  867. {
  868. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::GetSizeMax")));
  869. DWORD dwSize = 0;
  870. if (NULL == pcbSize)
  871. return E_FAIL;
  872. pcbSize->QuadPart = 0;
  873. return S_OK;
  874. }
  875. HRESULT
  876. CSnapInCompData::AddMenuItems(
  877. LPDATAOBJECT pDataObject,
  878. LPCONTEXTMENUCALLBACK piCallback,
  879. long *pInsertionAllowed
  880. )
  881. {
  882. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::AddMenuItems")));
  883. HRESULT hr = S_OK;
  884. if (CCM_INSERTIONALLOWED_TOP & *pInsertionAllowed)
  885. {
  886. CString strOpen(m_hInstance, IDS_VERB_OPEN);
  887. CONTEXTMENUITEM ci;
  888. ci.strName = strOpen;
  889. ci.strStatusBarText = NULL;
  890. ci.lCommandID = 0;
  891. ci.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
  892. ci.fFlags = 0;
  893. ci.fSpecialFlags = CCM_SPECIAL_DEFAULT_ITEM;
  894. hr = piCallback->AddItem(&ci);
  895. if (FAILED(hr))
  896. {
  897. DBGERROR((TEXT("Error 0x%08X adding context menu item"), hr));
  898. }
  899. }
  900. return hr;
  901. }
  902. HRESULT
  903. CSnapInCompData::Command(
  904. long lCommandID,
  905. LPDATAOBJECT pDataObject
  906. )
  907. {
  908. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::Command")));
  909. DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("Command ID = %d"), lCommandID));
  910. if (0 == lCommandID)
  911. OpenVolumeQuotaProperties();
  912. else
  913. DBGERROR((TEXT("Unrecognized command ID (%d)"), lCommandID));
  914. return S_OK;
  915. }
  916. const int MAX_SNAPIN_PROP_PAGES = 1;
  917. BOOL CALLBACK
  918. CSnapInCompData::AddPropSheetPage(
  919. HPROPSHEETPAGE hpage,
  920. LPARAM lParam
  921. )
  922. {
  923. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::AddPropSheetPage")));
  924. PROPSHEETHEADER * ppsh = (PROPSHEETHEADER *)lParam;
  925. if (ppsh->nPages < MAX_SNAPIN_PROP_PAGES)
  926. {
  927. ppsh->phpage[ppsh->nPages++] = hpage;
  928. return TRUE;
  929. }
  930. return FALSE;
  931. }
  932. DWORD
  933. CSnapInCompData::PropPageThreadProc(
  934. LPVOID pvParam
  935. )
  936. {
  937. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::PropPageThreadProc")));
  938. MSG msg;
  939. HWND hwndPropSheet = NULL;
  940. CSnapInCompData *pThis = (CSnapInCompData *)pvParam;
  941. com_autoptr<IShellExtInit> psei;
  942. HRESULT hr = CoInitialize(NULL);
  943. if (SUCCEEDED(hr))
  944. {
  945. hr = CoCreateInstance(CLSID_DiskQuotaUI,
  946. NULL,
  947. CLSCTX_INPROC_SERVER,
  948. IID_IShellExtInit,
  949. reinterpret_cast<void **>(psei.getaddr()));
  950. if (SUCCEEDED(hr))
  951. {
  952. com_autoptr<IShellPropSheetExt> pspse;
  953. hr = psei->QueryInterface(IID_ISnapInPropSheetExt,
  954. reinterpret_cast<void **>(pspse.getaddr()));
  955. if (SUCCEEDED(hr))
  956. {
  957. com_autoptr<IDiskQuotaPolicy> pdqp;
  958. hr = pspse->QueryInterface(IID_IDiskQuotaPolicy,
  959. reinterpret_cast<void **>(pdqp.getaddr()));
  960. if (SUCCEEDED(hr))
  961. {
  962. pdqp->Initialize(pThis->m_pGPEInformation, NULL);
  963. HPROPSHEETPAGE rghPages[1];
  964. PROPSHEETHEADER psh;
  965. ZeroMemory(&psh, sizeof(psh));
  966. //
  967. // Define sheet.
  968. //
  969. psh.dwSize = sizeof(PROPSHEETHEADER);
  970. psh.dwFlags = PSH_MODELESS;
  971. psh.hInstance = pThis->m_hInstance;
  972. psh.pszIcon = NULL;
  973. psh.pszCaption = NULL;
  974. psh.nPages = 0;
  975. psh.nStartPage = 0;
  976. psh.phpage = rghPages;
  977. pThis->m_pConsole->GetMainWindow(&psh.hwndParent);
  978. hr = pspse->AddPages(AddPropSheetPage, (LPARAM)&psh);
  979. if (SUCCEEDED(hr))
  980. {
  981. hwndPropSheet = (HWND)PropertySheet(&psh);
  982. if (NULL != hwndPropSheet)
  983. {
  984. //
  985. // Set the title on the property sheet.
  986. //
  987. CString strTitle(pThis->m_hInstance, IDS_SNAPIN_POLICYDLG_TITLE);
  988. SetWindowText(hwndPropSheet, strTitle);
  989. MSG msg;
  990. while (0 != ::GetMessage(&msg, NULL, 0, 0))
  991. {
  992. if (!PropSheet_IsDialogMessage(hwndPropSheet, &msg))
  993. {
  994. ::TranslateMessage(&msg);
  995. ::DispatchMessage(&msg);
  996. }
  997. if (NULL == PropSheet_GetCurrentPageHwnd(hwndPropSheet))
  998. {
  999. DestroyWindow(hwndPropSheet);
  1000. PostQuitMessage(0);
  1001. }
  1002. }
  1003. }
  1004. else if (-1 == (int)hwndPropSheet)
  1005. {
  1006. DBGERROR((TEXT("PropertySheet failed with error %d"), GetLastError()));
  1007. }
  1008. }
  1009. else
  1010. {
  1011. DBGERROR((TEXT("AddPages failed")));
  1012. }
  1013. }
  1014. }
  1015. }
  1016. else
  1017. DBGERROR((TEXT("CoCreateInstance failed with result 0x%08X"), hr));
  1018. CoUninitialize();
  1019. }
  1020. else
  1021. DBGERROR((TEXT("CoInitialize failed with result 0x%08X"), hr));
  1022. return 0;
  1023. }
  1024. //
  1025. // Create a new thread and run the volume properties dialog (modified for
  1026. // policy snapin).
  1027. //
  1028. HRESULT
  1029. CSnapInCompData::OpenVolumeQuotaProperties(
  1030. void
  1031. )
  1032. {
  1033. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::OpenVolumeQuotaProperties")));
  1034. HRESULT hr = E_FAIL;
  1035. UINT idThread;
  1036. HANDLE hThread = CreateThread(NULL,
  1037. 0, // Default stack size
  1038. (LPTHREAD_START_ROUTINE)PropPageThreadProc,
  1039. (LPVOID)this,
  1040. 0,
  1041. (LPDWORD)&idThread);
  1042. if (INVALID_HANDLE_VALUE != hThread)
  1043. {
  1044. hr = NOERROR;
  1045. CloseHandle(hThread);
  1046. }
  1047. return hr;
  1048. }
  1049. //-----------------------------------------------------------------------------
  1050. // Snap-in data object implementation. CDataObject
  1051. //-----------------------------------------------------------------------------
  1052. CDataObject::CDataObject(
  1053. CSnapInCompData& cd
  1054. ) : m_cRef(0),
  1055. m_cd(cd),
  1056. m_type(CCT_UNINITIALIZED),
  1057. m_pItem(NULL)
  1058. {
  1059. DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CDataObject::CDataObject")));
  1060. }
  1061. CDataObject::~CDataObject(
  1062. void
  1063. )
  1064. {
  1065. DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CDataObject::~CDataObject")));
  1066. }
  1067. HRESULT
  1068. CDataObject::QueryInterface(
  1069. REFIID riid,
  1070. LPVOID *ppvOut
  1071. )
  1072. {
  1073. DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CDataObject::QueryInterface")));
  1074. DBGPRINTIID(DM_SNAPIN, DL_MID, riid);
  1075. HRESULT hr = E_NOINTERFACE;
  1076. if (NULL == ppvOut)
  1077. return E_INVALIDARG;
  1078. *ppvOut = NULL;
  1079. if (IID_IDiskQuotaSnapInData == riid)
  1080. {
  1081. *ppvOut = reinterpret_cast<IQuotaDataObject *>(this);
  1082. }
  1083. else if(IID_IUnknown == riid || IID_IDataObject == riid)
  1084. {
  1085. *ppvOut = this;
  1086. }
  1087. if (NULL != *ppvOut)
  1088. {
  1089. ((LPUNKNOWN)*ppvOut)->AddRef();
  1090. hr = NOERROR;
  1091. }
  1092. return hr;
  1093. }
  1094. ULONG
  1095. CDataObject::AddRef(
  1096. void
  1097. )
  1098. {
  1099. DBGTRACE((DM_SNAPIN, DL_LOW, TEXT("CDataObject::AddRef")));
  1100. ULONG ulReturn = m_cRef + 1;
  1101. InterlockedIncrement(&m_cRef);
  1102. return ulReturn;
  1103. }
  1104. ULONG
  1105. CDataObject::Release(
  1106. void
  1107. )
  1108. {
  1109. DBGTRACE((DM_SNAPIN, DL_LOW, TEXT("CDataObject::Release")));
  1110. ULONG ulReturn = m_cRef - 1;
  1111. if (InterlockedDecrement(&m_cRef) == 0)
  1112. {
  1113. delete this;
  1114. ulReturn = 0;
  1115. }
  1116. return ulReturn;
  1117. }
  1118. HRESULT
  1119. CDataObject::GetDataHere(
  1120. LPFORMATETC lpFormatetc,
  1121. LPSTGMEDIUM lpMedium
  1122. )
  1123. {
  1124. DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CDataObject::GetDataHere")));
  1125. HRESULT hr = S_OK;
  1126. try
  1127. {
  1128. //
  1129. // Forward the rendering request to the data object's item object.
  1130. //
  1131. hr = m_pItem->RenderData(lpFormatetc->cfFormat, lpMedium);
  1132. }
  1133. catch(CAllocException& e)
  1134. {
  1135. DBGERROR((TEXT("Insufficient memory")));
  1136. hr = E_OUTOFMEMORY;
  1137. }
  1138. return hr;
  1139. }
  1140. #endif // POLICY_MMC_SNAPIN