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.

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