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.

1020 lines
26 KiB

  1. // This is a part of the Microsoft Management Console.
  2. // Copyright (C) Microsoft Corporation, 1995 - 1999
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Management Console and related
  7. // electronic documentation provided with the interfaces.
  8. #include "stdafx.h"
  9. //#include <atlimpl.cpp>
  10. //#include <gpedit.h>
  11. #include <sceattch.h>
  12. #include "wiz.h"
  13. //#include <userenv.h>
  14. #include "genpage.h"
  15. #include <atlimpl.cpp>
  16. // Array of menu item commands to be inserted into the contest menu.
  17. // Note - the first item is the menu text, // CCM_SPECIAL_DEFAULT_ITEM
  18. // the second item is the status string
  19. ///////////////////////////////////////////////////////////////////////////////
  20. // IComponentData implementation
  21. DEBUG_DECLARE_INSTANCE_COUNTER(CComponentDataImpl);
  22. CComponentDataImpl::CComponentDataImpl()
  23. : m_bIsDirty(TRUE), m_pScope(NULL), m_pConsole(NULL),
  24. #if DBG
  25. m_bInitializedCD(false), m_bDestroyedCD(false),
  26. #endif
  27. m_fAdvancedServer(false), m_hrCreateFolder(S_OK)
  28. {
  29. DEBUG_INCREMENT_INSTANCE_COUNTER(CComponentDataImpl);
  30. #ifdef _DEBUG
  31. m_cDataObjects = 0;
  32. #endif
  33. }
  34. CComponentDataImpl::~CComponentDataImpl()
  35. {
  36. DEBUG_DECREMENT_INSTANCE_COUNTER(CComponentDataImpl);
  37. ASSERT(m_pScope == NULL);
  38. ASSERT(!m_bInitializedCD || m_bDestroyedCD);
  39. // Some snap-in is hanging on to data objects.
  40. // If they access, it will crash!!!
  41. ASSERT(m_cDataObjects <= 1);
  42. }
  43. STDMETHODIMP CComponentDataImpl::Initialize(LPUNKNOWN pUnknown)
  44. {
  45. DBX_PRINT(_T(" ---------- CComponentDataImpl::Initialize<0x08x>\n"), this);
  46. #if DBG
  47. m_bInitializedCD = true;
  48. #endif
  49. ASSERT(pUnknown != NULL);
  50. HRESULT hr;
  51. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  52. // MMC should only call ::Initialize once!
  53. ASSERT(m_pScope == NULL);
  54. pUnknown->QueryInterface(IID_IConsoleNameSpace,
  55. reinterpret_cast<void**>(&m_pScope));
  56. // add the images for the scope tree
  57. ::CBitmap bmp16x16;
  58. LPIMAGELIST lpScopeImage;
  59. hr = pUnknown->QueryInterface(IID_IConsole2, reinterpret_cast<void**>(&m_pConsole));
  60. ASSERT(hr == S_OK);
  61. hr = m_pConsole->QueryScopeImageList(&lpScopeImage);
  62. ASSERT(hr == S_OK);
  63. // Load the bitmaps from the dll
  64. bmp16x16.LoadBitmap(IDB_16x16);
  65. // Set the images
  66. lpScopeImage->ImageListSetStrip(reinterpret_cast<LONG_PTR *>(static_cast<HBITMAP>(bmp16x16)),
  67. reinterpret_cast<LONG_PTR *>(static_cast<HBITMAP>(bmp16x16)),
  68. 0, RGB(255, 0, 255));
  69. lpScopeImage->Release();
  70. // Add any init code here NOT based on info from .MSC file
  71. return S_OK;
  72. }
  73. STDMETHODIMP CComponentDataImpl::CreateComponent(LPCOMPONENT* ppComponent)
  74. {
  75. ASSERT(ppComponent != NULL);
  76. CComObject<CSnapin>* pObject;
  77. CComObject<CSnapin>::CreateInstance(&pObject);
  78. ASSERT(pObject != NULL);
  79. // Store IComponentData
  80. pObject->SetIComponentData(this);
  81. return pObject->QueryInterface(IID_IComponent,
  82. reinterpret_cast<void**>(ppComponent));
  83. }
  84. STDMETHODIMP CComponentDataImpl::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  85. {
  86. ASSERT(m_pScope != NULL);
  87. HRESULT hr = S_OK;
  88. HWND hwndConsole;
  89. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  90. INTERNAL* pInternal;
  91. MMC_COOKIE cookie;
  92. // Since it's my folder it has an internal format.
  93. // Design Note: for extension. I can use the fact, that the data object doesn't have
  94. // my internal format and I should look at the node type and see how to extend it.
  95. // switch on events where we don't care about pInternal->m_cookie
  96. switch(event)
  97. {
  98. case MMCN_PROPERTY_CHANGE:
  99. hr = OnProperties(param);
  100. goto Ret;
  101. case MMCN_EXPAND:
  102. hr = OnExpand(lpDataObject, arg, param);
  103. goto Ret;
  104. default:
  105. break;
  106. }
  107. // handle cases where we do care about pInternal->m_cookie
  108. pInternal = ExtractInternalFormat(lpDataObject);
  109. if (pInternal == NULL)
  110. return S_OK;
  111. cookie = pInternal->m_cookie;
  112. ::GlobalFree(reinterpret_cast<HANDLE>(pInternal));
  113. switch(event)
  114. {
  115. case MMCN_PASTE:
  116. break;
  117. case MMCN_DELETE:
  118. hr = OnDelete(cookie);
  119. break;
  120. case MMCN_REMOVE_CHILDREN:
  121. hr = OnRemoveChildren(arg);
  122. break;
  123. case MMCN_RENAME:
  124. hr = OnRename(cookie, arg, param);
  125. break;
  126. default:
  127. break;
  128. }
  129. Ret:
  130. return hr;
  131. }
  132. STDMETHODIMP CComponentDataImpl::Destroy()
  133. {
  134. DBX_PRINT(_T(" ---------- CComponentDataImpl::Destroy<0x08x>\n"), this);
  135. ASSERT(m_bInitializedCD);
  136. #if DBG
  137. m_bDestroyedCD = true;
  138. #endif
  139. // Delete enumerated scope items
  140. DeleteList();
  141. SAFE_RELEASE(m_pScope);
  142. SAFE_RELEASE(m_pConsole);
  143. return S_OK;
  144. }
  145. STDMETHODIMP CComponentDataImpl::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
  146. {
  147. #ifdef _DEBUG
  148. if (cookie == 0)
  149. {
  150. ASSERT(type != CCT_RESULT);
  151. }
  152. else
  153. {
  154. ASSERT(type == CCT_SCOPE);
  155. DWORD dwItemType = GetItemType(cookie);
  156. ASSERT(dwItemType == SCOPE_LEVEL_ITEM);
  157. //ASSERT((dwItemType == SCOPE_LEVEL_ITEM) || (dwItemType == CA_LEVEL_ITEM));
  158. }
  159. #endif
  160. return _QueryDataObject(cookie, type, this, ppDataObject);
  161. }
  162. ///////////////////////////////////////////////////////////////////////////////
  163. //// ISnapinHelp interface
  164. STDMETHODIMP CComponentDataImpl::GetHelpTopic(LPOLESTR* lpCompiledHelpFile)
  165. {
  166. if (lpCompiledHelpFile == NULL)
  167. return E_POINTER;
  168. UINT cbWindows = 0;
  169. WCHAR szWindows[MAX_PATH+1];
  170. cbWindows = GetSystemWindowsDirectory(szWindows, MAX_PATH);
  171. if (cbWindows == 0)
  172. return S_FALSE;
  173. cbWindows++; // include null term
  174. cbWindows *= sizeof(WCHAR); // make this bytes, not chars
  175. *lpCompiledHelpFile = (LPOLESTR) CoTaskMemAlloc(sizeof(HTMLHELP_COLLECTION_FILENAME) + cbWindows);
  176. if (*lpCompiledHelpFile == NULL)
  177. return E_OUTOFMEMORY;
  178. myRegisterMemFree(*lpCompiledHelpFile, CSM_COTASKALLOC); // this is freed by mmc, not our tracking
  179. USES_CONVERSION;
  180. wcscpy(*lpCompiledHelpFile, T2OLE(szWindows));
  181. wcscat(*lpCompiledHelpFile, T2OLE(HTMLHELP_COLLECTION_FILENAME));
  182. return S_OK;
  183. }
  184. // tells of other topics my chm links to
  185. STDMETHODIMP CComponentDataImpl::GetLinkedTopics(LPOLESTR* lpCompiledHelpFiles)
  186. {
  187. if (lpCompiledHelpFiles == NULL)
  188. return E_POINTER;
  189. UINT cbWindows = 0;
  190. WCHAR szWindows[MAX_PATH+1];
  191. cbWindows = GetSystemWindowsDirectory(szWindows, MAX_PATH);
  192. if (cbWindows == 0)
  193. return S_FALSE;
  194. cbWindows++; // include null term
  195. cbWindows *= sizeof(WCHAR); // make this bytes, not chars
  196. *lpCompiledHelpFiles = (LPOLESTR) CoTaskMemAlloc(sizeof(HTMLHELP_COLLECTIONLINK_FILENAME) + cbWindows);
  197. if (*lpCompiledHelpFiles == NULL)
  198. return E_OUTOFMEMORY;
  199. myRegisterMemFree(*lpCompiledHelpFiles, CSM_COTASKALLOC); // this is freed by mmc, not our tracking
  200. USES_CONVERSION;
  201. wcscpy(*lpCompiledHelpFiles, T2OLE(szWindows));
  202. wcscat(*lpCompiledHelpFiles, T2OLE(HTMLHELP_COLLECTIONLINK_FILENAME));
  203. return S_OK;
  204. }
  205. ///////////////////////////////////////////////////////////////////////////////
  206. //// IPersistStream interface members
  207. /*
  208. STDMETHODIMP CComponentDataImpl::GetClassID(CLSID *pClassID)
  209. {
  210. ASSERT(pClassID != NULL);
  211. // Copy the CLSID for this snapin
  212. *pClassID = CLSID_CAPolicyExtensionSnapIn;
  213. return E_NOTIMPL;
  214. }
  215. */
  216. STDMETHODIMP CComponentDataImpl::IsDirty()
  217. {
  218. // Always save / Always dirty.
  219. return ThisIsDirty() ? S_OK : S_FALSE;
  220. }
  221. STDMETHODIMP CComponentDataImpl::Load(IStream *pStm)
  222. {
  223. DBX_PRINT(_T(" ---------- CComponentDataImpl::Load<0x08x>\n"), this);
  224. ASSERT(pStm);
  225. ASSERT(m_bInitializedCD);
  226. // Read the string
  227. DWORD dwVer;
  228. ULONG nBytesRead;
  229. HRESULT hr = pStm->Read(&dwVer, sizeof(DWORD), &nBytesRead);
  230. // Verify that the read succeeded
  231. ASSERT(SUCCEEDED(hr) && nBytesRead == sizeof(DWORD));
  232. // check to see if this is the correct version
  233. if (dwVer != 0x1)
  234. {
  235. return STG_E_OLDFORMAT;
  236. }
  237. ClearDirty();
  238. return SUCCEEDED(hr) ? S_OK : E_FAIL;
  239. }
  240. STDMETHODIMP CComponentDataImpl::Save(IStream *pStm, BOOL fClearDirty)
  241. {
  242. DBX_PRINT(_T(" ---------- CComponentDataImpl::Save<0x08x>\n"), this);
  243. ASSERT(pStm);
  244. ASSERT(m_bInitializedCD);
  245. // Write the string
  246. ULONG nBytesWritten;
  247. DWORD dwVer = 0x1;
  248. HRESULT hr = pStm->Write(&dwVer, sizeof(DWORD), &nBytesWritten);
  249. // Verify that the write operation succeeded
  250. ASSERT(SUCCEEDED(hr) && nBytesWritten == sizeof(DWORD));
  251. if (FAILED(hr))
  252. return STG_E_CANTSAVE;
  253. if (fClearDirty)
  254. ClearDirty();
  255. return S_OK;
  256. }
  257. STDMETHODIMP CComponentDataImpl::GetSizeMax(ULARGE_INTEGER *pcbSize)
  258. {
  259. ASSERT(pcbSize);
  260. DWORD cbSize;
  261. cbSize = sizeof(DWORD); // version
  262. // Set the size of the string to be saved
  263. ULISet32(*pcbSize, cbSize);
  264. return S_OK;
  265. }
  266. ///////////////////////////////////////////////////////////////////////////////
  267. //// Notify handlers for IComponentData
  268. HRESULT CComponentDataImpl::OnDelete(MMC_COOKIE cookie)
  269. {
  270. return S_OK;
  271. }
  272. HRESULT CComponentDataImpl::OnRemoveChildren(LPARAM arg)
  273. {
  274. return S_OK;
  275. }
  276. HRESULT CComponentDataImpl::OnRename(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
  277. {
  278. if (arg == 0)
  279. return S_OK;
  280. LPOLESTR pszNewName = reinterpret_cast<LPOLESTR>(param);
  281. if (pszNewName == NULL)
  282. return E_INVALIDARG;
  283. CFolder* pFolder = reinterpret_cast<CFolder*>(cookie);
  284. ASSERT(pFolder != NULL);
  285. if (pFolder == NULL)
  286. return E_INVALIDARG;
  287. pFolder->SetName(pszNewName);
  288. return S_OK;
  289. }
  290. HRESULT CComponentDataImpl::OnExpand(LPDATAOBJECT lpDataObject, LPARAM arg, LPARAM param)
  291. {
  292. HRESULT hr = S_OK;
  293. GUID* pNodeGUID = NULL;
  294. CFolder* pFolder=NULL;
  295. bool fInsertFolder = false;
  296. STGMEDIUM stgmediumNodeType = { TYMED_HGLOBAL, NULL };
  297. STGMEDIUM stgmediumCAType = { TYMED_HGLOBAL, NULL };
  298. STGMEDIUM stgmediumCAName = { TYMED_HGLOBAL, NULL };
  299. LPWSTR pszDSName = NULL;
  300. if (arg == TRUE)
  301. {
  302. // Did Initialize get called?
  303. ASSERT(m_pScope != NULL);
  304. //
  305. // get the guid of the current node
  306. //
  307. UINT s_cfNodeType;
  308. s_cfNodeType = RegisterClipboardFormat(W2T(CCF_NODETYPE));
  309. FORMATETC formatetcNodeType = { (CLIPFORMAT)s_cfNodeType, NULL,
  310. DVASPECT_CONTENT, -1, TYMED_HGLOBAL
  311. };
  312. hr = lpDataObject->GetDataHere(&formatetcNodeType, &stgmediumNodeType);
  313. _JumpIfError(hr, Ret, "GetDataHere NodeType");
  314. pNodeGUID = (GUID*) GlobalLock(stgmediumNodeType.hGlobal);
  315. if (pNodeGUID == NULL)
  316. {
  317. hr = E_UNEXPECTED;
  318. _JumpError(hr, Ret, "GlobalLock failed");
  319. }
  320. //
  321. // if this is the parents node then add our node undeneath it
  322. //
  323. // CA Manager parent
  324. if (memcmp(pNodeGUID, (void *)&cCAManagerParentNodeID, sizeof(GUID)) == 0)
  325. {
  326. fInsertFolder = true;
  327. CString szFolderName;
  328. // Only add node under ENT ROOT, ENT SUB
  329. UINT cfCAType = RegisterClipboardFormat(W2T((LPWSTR)SNAPIN_CA_INSTALL_TYPE));
  330. FORMATETC formatetcCAType = { (CLIPFORMAT)cfCAType, NULL,
  331. DVASPECT_CONTENT, -1, TYMED_HGLOBAL
  332. };
  333. hr = lpDataObject->GetDataHere(&formatetcCAType, &stgmediumCAType);
  334. _JumpIfError(hr, Ret, "GetDataHere CAType");
  335. PDWORD rgdw = (DWORD*)GlobalLock(stgmediumCAType.hGlobal);
  336. ENUM_CATYPES caType = (ENUM_CATYPES)rgdw[0];
  337. DBGPRINT((DBG_SS_CERTMMC, "CA Type: %d\n", caType));
  338. // return immediately if we're not an ENT {ROOT | SUB}
  339. if ((caType != ENUM_ENTERPRISE_SUBCA) &&
  340. (caType != ENUM_ENTERPRISE_ROOTCA))
  341. {
  342. hr = S_OK;
  343. goto Ret;
  344. }
  345. m_fAdvancedServer = (rgdw[1]!=0)?true:false;
  346. DBGPRINT((DBG_SS_CERTMMC, "Advanced Server: %s\n",
  347. m_fAdvancedServer?"yes":"no"));
  348. VERIFY(szFolderName.LoadString(IDS_POLICYSETTINGS));
  349. pFolder = new CFolder();
  350. if(pFolder == NULL)
  351. {
  352. hr = E_OUTOFMEMORY;
  353. goto Ret;
  354. }
  355. pFolder->Create(
  356. (LPWSTR)((LPCTSTR)szFolderName),
  357. IMGINDEX_FOLDER,
  358. IMGINDEX_FOLDER_OPEN,
  359. SCOPE_LEVEL_ITEM,
  360. POLICYSETTINGS,
  361. FALSE);
  362. m_scopeItemList.AddTail(pFolder);
  363. pFolder->m_pScopeItem->relativeID = param;
  364. // Set the folder as the cookie
  365. pFolder->m_pScopeItem->mask |= SDI_PARAM;
  366. pFolder->m_pScopeItem->lParam = reinterpret_cast<LPARAM>(pFolder);
  367. pFolder->SetCookie(reinterpret_cast<LONG_PTR>(pFolder));
  368. // get the name of the CA that we are administering
  369. LPWSTR pCAName = NULL;
  370. // nab CA Name
  371. UINT cfCAName = RegisterClipboardFormat(W2T((LPWSTR)CA_SANITIZED_NAME));
  372. FORMATETC formatetcCAName = { (CLIPFORMAT)cfCAName, NULL,
  373. DVASPECT_CONTENT, -1, TYMED_HGLOBAL
  374. };
  375. hr = lpDataObject->GetDataHere(&formatetcCAName, &stgmediumCAName);
  376. _JumpIfError(hr, Ret, "GetDataHere CAName");
  377. pCAName = (LPWSTR)GlobalLock(stgmediumCAName.hGlobal);
  378. if (pCAName == NULL)
  379. {
  380. hr = E_UNEXPECTED;
  381. _JumpError(hr, Ret, "GlobalLock");
  382. }
  383. pFolder->m_szCAName = pCAName;
  384. hr = mySanitizedNameToDSName(pCAName, &pszDSName);
  385. _JumpIfError(hr, Ret, "mySanitizedNameToDSName");
  386. //
  387. // get a handle to the CA based on the name
  388. //
  389. hr = CAFindByName(
  390. pszDSName,
  391. NULL,
  392. CA_FIND_INCLUDE_UNTRUSTED,
  393. &pFolder->m_hCAInfo);
  394. _JumpIfErrorStr(hr, Ret, "CAFindByName", pszDSName);
  395. // if we made it here then everything is initialized, so add the folder
  396. }
  397. }
  398. // undo fix to add folder under all circumstances -- we were
  399. // inserting a NULL ptr!
  400. if(fInsertFolder && (NULL != pFolder))
  401. {
  402. m_hrCreateFolder = hr;
  403. m_pScope->InsertItem(pFolder->m_pScopeItem);
  404. }
  405. // Note - On return, the ID member of 'm_pScopeItem'
  406. // contains the handle to the newly inserted item!
  407. ASSERT(pFolder->m_pScopeItem->ID != NULL);
  408. Ret:
  409. if (stgmediumNodeType.hGlobal)
  410. {
  411. GlobalUnlock(stgmediumNodeType.hGlobal);
  412. ReleaseStgMedium(&stgmediumNodeType);
  413. }
  414. if (stgmediumCAType.hGlobal)
  415. {
  416. GlobalUnlock(stgmediumCAType.hGlobal);
  417. ReleaseStgMedium(&stgmediumCAType);
  418. }
  419. if (stgmediumCAName.hGlobal)
  420. {
  421. GlobalUnlock(stgmediumCAName.hGlobal);
  422. ReleaseStgMedium(&stgmediumCAName);
  423. }
  424. if (pszDSName)
  425. LocalFree(pszDSName);
  426. return hr;
  427. }
  428. HRESULT CComponentDataImpl::OnSelect(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
  429. {
  430. return E_UNEXPECTED;
  431. }
  432. HRESULT CComponentDataImpl::OnProperties(LPARAM param)
  433. {
  434. HRESULT hr = S_OK;
  435. CFolder* pItem = NULL;
  436. CFolder* pFolder = NULL;
  437. POSITION pos = 0;
  438. if (param == NULL)
  439. {
  440. goto error;
  441. }
  442. ASSERT(param != NULL);
  443. pFolder = new CFolder();
  444. if(pFolder == NULL)
  445. {
  446. hr = E_OUTOFMEMORY;
  447. goto error;
  448. }
  449. // Create a new folder object
  450. pFolder->Create( reinterpret_cast<LPOLESTR>(param), 0, 0, SCOPE_LEVEL_ITEM, STATIC, FALSE);
  451. // The static folder in the last item in the list
  452. pos = m_scopeItemList.GetTailPosition();
  453. ASSERT(pos);
  454. // Add it to the internal list
  455. if (pos)
  456. {
  457. pItem = m_scopeItemList.GetAt(pos);
  458. if(pItem == NULL)
  459. {
  460. hr = E_OUTOFMEMORY;
  461. goto error;
  462. }
  463. m_scopeItemList.AddTail(pFolder);
  464. if((pFolder->m_pScopeItem == NULL) || (pItem->m_pScopeItem == NULL))
  465. {
  466. hr = E_POINTER;
  467. goto error;
  468. }
  469. pFolder->m_pScopeItem->relativeID = pItem->m_pScopeItem->relativeID;
  470. // Set the folder as the cookie
  471. pFolder->m_pScopeItem->mask |= SDI_PARAM;
  472. pFolder->m_pScopeItem->lParam = reinterpret_cast<LPARAM>(pFolder);
  473. pFolder->SetCookie(reinterpret_cast<LONG_PTR>(pFolder));
  474. m_pScope->InsertItem(pFolder->m_pScopeItem);
  475. pFolder = NULL;
  476. }
  477. ::GlobalFree(reinterpret_cast<void*>(param));
  478. error:
  479. if(pFolder)
  480. {
  481. delete pFolder;
  482. }
  483. return hr;
  484. }
  485. void CComponentDataImpl::DeleteList()
  486. {
  487. POSITION pos = m_scopeItemList.GetHeadPosition();
  488. while (pos)
  489. delete m_scopeItemList.GetNext(pos);
  490. m_scopeItemList.RemoveAll();
  491. }
  492. CFolder* CComponentDataImpl::FindObject(MMC_COOKIE cookie)
  493. {
  494. CFolder* pFolder = NULL;
  495. POSITION pos = m_scopeItemList.GetHeadPosition();
  496. while(pos)
  497. {
  498. pFolder = m_scopeItemList.GetNext(pos);
  499. if (*pFolder == cookie)
  500. return pFolder;
  501. }
  502. return NULL;
  503. }
  504. STDMETHODIMP CComponentDataImpl::GetDisplayInfo(SCOPEDATAITEM* pScopeDataItem)
  505. {
  506. ASSERT(pScopeDataItem != NULL);
  507. if (pScopeDataItem == NULL)
  508. return E_POINTER;
  509. CFolder* pFolder = reinterpret_cast<CFolder*>(pScopeDataItem->lParam);
  510. if (pScopeDataItem->mask & SDI_STR)
  511. {
  512. //
  513. // if this is certtype folder, and it is for the second column, then add usages string
  514. //
  515. if (FALSE)//(pFolder->m_hCertType != NULL) && (pScopeDataItem-> == ))
  516. {
  517. }
  518. else
  519. {
  520. pScopeDataItem->displayname = pFolder->m_pszName;
  521. }
  522. }
  523. if (pScopeDataItem->mask & SDI_IMAGE)
  524. pScopeDataItem->nImage = pFolder->m_pScopeItem->nImage;
  525. if (pScopeDataItem->mask & SDI_OPENIMAGE)
  526. pScopeDataItem->nOpenImage = pFolder->m_pScopeItem->nOpenImage;
  527. return S_OK;
  528. }
  529. STDMETHODIMP CComponentDataImpl::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  530. {
  531. if (lpDataObjectA == NULL || lpDataObjectB == NULL)
  532. return E_POINTER;
  533. // Make sure both data object are mine
  534. INTERNAL* pA;
  535. INTERNAL* pB;
  536. HRESULT hr = S_FALSE;
  537. pA = ExtractInternalFormat(lpDataObjectA);
  538. pB = ExtractInternalFormat(lpDataObjectA);
  539. if (pA != NULL && pB != NULL)
  540. hr = (*pA == *pB) ? S_OK : S_FALSE;
  541. if(pA != NULL)
  542. {
  543. ::GlobalFree(reinterpret_cast<HANDLE>(pA));
  544. }
  545. if(pB != NULL)
  546. {
  547. ::GlobalFree(reinterpret_cast<HANDLE>(pB));
  548. }
  549. return hr;
  550. }
  551. /////////////////////////////////////////////////////////////////////////////
  552. // IExtendPropertySheet Implementation
  553. STDMETHODIMP CComponentDataImpl::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
  554. LONG_PTR handle,
  555. LPDATAOBJECT lpIDataObject)
  556. {
  557. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  558. // Look at the data object and determine if this an extension or a primary
  559. ASSERT(lpIDataObject != NULL);
  560. #if DBG
  561. CLSID* pCoClassID = ExtractClassID(lpIDataObject);
  562. if(pCoClassID == NULL)
  563. {
  564. ASSERT(FALSE);
  565. return E_UNEXPECTED;
  566. }
  567. // Which page is needed? (determined by which node is active)
  568. ASSERT(IsEqualCLSID(*pCoClassID, GetCoClassID()));
  569. FREE_DATA(pCoClassID);
  570. #endif
  571. PropertyPage* pBasePage;
  572. INTERNAL* pInternal = ExtractInternalFormat(lpIDataObject);
  573. if (pInternal == NULL)
  574. {
  575. return S_OK;
  576. }
  577. ASSERT(pInternal->m_type == CCT_SCOPE);
  578. ASSERT(pInternal->m_cookie);
  579. CFolder* pFolder = reinterpret_cast<CFolder*>(pInternal->m_cookie);
  580. ASSERT(pFolder != NULL);
  581. if (pFolder == NULL)
  582. return E_INVALIDARG;
  583. switch (pFolder->m_type)
  584. {
  585. case POLICYSETTINGS:
  586. {
  587. //1
  588. /*
  589. CPolicySettingsGeneralPage* pControlPage = new CPolicySettingsGeneralPage(pFolder->m_szCAName, pFolder->m_hCAInfo);
  590. if(pControlPage == NULL)
  591. {
  592. return E_OUTOFMEMORY;
  593. }
  594. {
  595. pControlPage->m_hConsoleHandle = handle; // only do this on primary
  596. pBasePage = pControlPage;
  597. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
  598. if (hPage == NULL)
  599. {
  600. delete(pControlPage);
  601. return E_UNEXPECTED;
  602. }
  603. lpProvider->AddPage(hPage);
  604. }
  605. //2
  606. {
  607. CSvrSettingsPolicyPage* pPage = new CSvrSettingsPolicyPage(pControlPage);
  608. pBasePage = pPage;
  609. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
  610. if (hPage == NULL)
  611. return E_UNEXPECTED;
  612. lpProvider->AddPage(hPage);
  613. }
  614. */
  615. return S_OK;
  616. }
  617. break;
  618. default:
  619. break;
  620. }
  621. return S_OK;
  622. }
  623. STDMETHODIMP CComponentDataImpl::QueryPagesFor(LPDATAOBJECT lpDataObject)
  624. {
  625. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  626. // Get the node type and see if it's one of mine
  627. BOOL bResult = FALSE;
  628. INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
  629. if (pInternal == NULL)
  630. {
  631. return S_OK;
  632. }
  633. ASSERT(pInternal);
  634. ASSERT(pInternal->m_cookie);
  635. CFolder* pFolder = reinterpret_cast<CFolder*>(pInternal->m_cookie);
  636. switch(pFolder->m_type)
  637. {
  638. case POLICYSETTINGS:
  639. case SCE_EXTENSION:
  640. bResult = TRUE;
  641. break;
  642. default:
  643. bResult = FALSE;
  644. break;
  645. }
  646. FREE_DATA(pInternal);
  647. return (bResult) ? S_OK : S_FALSE;
  648. }
  649. ///////////////////////////////////////////////////////////////////////////////
  650. // IExtendContextMenu implementation
  651. //
  652. STDMETHODIMP CComponentDataImpl::AddMenuItems(LPDATAOBJECT pDataObject,
  653. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  654. long *pInsertionAllowed)
  655. {
  656. HRESULT hr = S_OK;
  657. CONTEXTMENUITEM menuItem;
  658. CString szMenu;
  659. CString szHint;
  660. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  661. // Note - snap-ins need to look at the data object and determine
  662. // in what context, menu items need to be added. They must also
  663. // observe the insertion allowed flags to see what items can be
  664. // added.
  665. if (IsMMCMultiSelectDataObject(pDataObject) == TRUE)
  666. return S_FALSE;
  667. INTERNAL* pInternal = ExtractInternalFormat(pDataObject);
  668. if (pInternal == NULL)
  669. {
  670. return S_OK;
  671. }
  672. CFolder* pFolder = reinterpret_cast<CFolder*>(pInternal->m_cookie);
  673. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW)
  674. {
  675. ::ZeroMemory (&menuItem, sizeof (menuItem));
  676. menuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_NEW;
  677. menuItem.fFlags = 0;
  678. menuItem.fSpecialFlags = 0;
  679. switch(pFolder->m_type)
  680. {
  681. case POLICYSETTINGS:
  682. VERIFY (szMenu.LoadString (IDS_CERTIFICATE_TYPE));
  683. menuItem.strName = (LPTSTR)(LPCTSTR) szMenu;
  684. VERIFY (szHint.LoadString (IDS_CERTIFICATE_TYPE_HINT));
  685. menuItem.strStatusBarText = (LPTSTR)(LPCTSTR) szHint;
  686. menuItem.lCommandID = IDM_NEW_CERTTYPE;
  687. hr = pContextMenuCallback->AddItem (&menuItem);
  688. ASSERT (SUCCEEDED (hr));
  689. break;
  690. default:
  691. break;
  692. }
  693. }
  694. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  695. {
  696. ::ZeroMemory (&menuItem, sizeof (menuItem));
  697. menuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
  698. menuItem.fFlags = 0;
  699. menuItem.fSpecialFlags = 0;
  700. switch(pFolder->m_type)
  701. {
  702. case POLICYSETTINGS:
  703. VERIFY (szMenu.LoadString (IDS_MANAGETASK));
  704. menuItem.strName = (LPTSTR)(LPCTSTR) szMenu;
  705. VERIFY (szHint.LoadString (IDS_MANAGETASK_HINT));
  706. menuItem.strStatusBarText = (LPTSTR)(LPCTSTR) szHint;
  707. menuItem.lCommandID = IDM_MANAGE;
  708. hr = pContextMenuCallback->AddItem (&menuItem);
  709. ASSERT (SUCCEEDED (hr));
  710. break;
  711. }
  712. }
  713. return hr;
  714. }
  715. STDMETHODIMP CComponentDataImpl::Command(long nCommandID, LPDATAOBJECT pDataObject)
  716. {
  717. // Note - snap-ins need to look at the data object and determine
  718. // in what context the command is being called.
  719. DWORD dwErr;
  720. HCERTTYPE hNewCertType;
  721. HWND hwndConsole;
  722. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  723. INTERNAL* pi = ExtractInternalFormat(pDataObject);
  724. if(pi == NULL)
  725. {
  726. return E_POINTER;
  727. }
  728. ASSERT(pi);
  729. ASSERT(pi->m_type == CCT_SCOPE);
  730. CFolder* pFolder = reinterpret_cast<CFolder*>(pi->m_cookie);
  731. // Handle each of the commands.
  732. switch (nCommandID)
  733. {
  734. case IDM_NEW_CERTTYPE:
  735. {
  736. if (pFolder)
  737. {
  738. switch(pFolder->m_type)
  739. {
  740. case POLICYSETTINGS:
  741. {
  742. // NOMFC
  743. CCertTemplateSelectDialog TemplateSelectDialog;
  744. TemplateSelectDialog.SetCA(pFolder->m_hCAInfo, m_fAdvancedServer);
  745. // if fails, NULL will work
  746. HWND hWnd = NULL;
  747. m_pConsole->GetMainWindow(&hWnd);
  748. DialogBoxParam(
  749. g_hInstance,
  750. MAKEINTRESOURCE(IDD_SELECT_CERTIFICATE_TEMPLATE),
  751. hWnd,
  752. SelectCertTemplateDialogProc,
  753. (LPARAM)&TemplateSelectDialog);
  754. break;
  755. }
  756. default:
  757. break;
  758. }
  759. }
  760. m_pConsole->UpdateAllViews(pDataObject, 0, 0);
  761. break;
  762. }
  763. case IDM_MANAGE:
  764. if (pFolder && pFolder->m_type == POLICYSETTINGS)
  765. {
  766. StartCertificateTemplatesSnapin();
  767. }
  768. break;
  769. default:
  770. ASSERT(FALSE); // Unknown command!
  771. break;
  772. }
  773. return S_OK;
  774. }
  775. HRESULT CComponentDataImpl::StartCertificateTemplatesSnapin()
  776. {
  777. HRESULT hr = S_OK;
  778. SHELLEXECUTEINFO shi;
  779. HWND hwnd = NULL;
  780. m_pConsole->GetMainWindow(&hwnd);
  781. ZeroMemory(&shi, sizeof(shi));
  782. shi.cbSize = sizeof(shi);
  783. shi.hwnd = hwnd;
  784. shi.lpVerb = SZ_VERB_OPEN;
  785. shi.lpFile = SZ_CERTTMPL_MSC;
  786. shi.fMask = SEE_MASK_FLAG_NO_UI;
  787. if(!ShellExecuteEx(&shi))
  788. {
  789. hr = myHLastError();
  790. _JumpError(hr, error, "ShellExecuteEx");
  791. }
  792. error:
  793. return hr;
  794. }