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.

813 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997-2001.
  5. //
  6. // File: DataObj.cpp
  7. //
  8. // Contents: Implementation of data object classes
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. USE_HANDLE_MACROS("CERTMGR(dataobj.cpp)")
  13. #include <gpedit.h>
  14. #include "compdata.h"
  15. #include "dataobj.h"
  16. #pragma warning(push,3)
  17. #include <sceattch.h>
  18. #pragma warning(pop)
  19. #include "uuids.h"
  20. #ifdef _DEBUG
  21. #ifndef ALPHA
  22. #define new DEBUG_NEW
  23. #endif
  24. #undef THIS_FILE
  25. static char THIS_FILE[] = __FILE__;
  26. #endif
  27. #include "stddtobj.cpp"
  28. // IDataObject interface implementation
  29. CCertMgrDataObject::CCertMgrDataObject()
  30. : m_pCookie (0),
  31. m_objecttype (CERTMGR_SNAPIN),
  32. m_dataobjecttype (CCT_UNINITIALIZED),
  33. m_dwLocation (0),
  34. m_pGPEInformation (0),
  35. m_pRSOPInformation (0),
  36. m_pbMultiSelData(NULL),
  37. m_cbMultiSelData(0),
  38. m_bMultiSelDobj(false),
  39. m_iCurr(0)
  40. {
  41. }
  42. HRESULT CCertMgrDataObject::GetDataHere(
  43. FORMATETC __RPC_FAR *pFormatEtcIn,
  44. STGMEDIUM __RPC_FAR *pMedium)
  45. {
  46. HRESULT hr = DV_E_FORMATETC;
  47. const CLIPFORMAT cf=pFormatEtcIn->cfFormat;
  48. if (cf == m_CFNodeType)
  49. {
  50. if ( IsValidObjectType (m_pCookie->m_objecttype) )
  51. {
  52. const GUID* pguid = GetObjectTypeGUID( m_pCookie->m_objecttype );
  53. stream_ptr s(pMedium);
  54. hr = s.Write(pguid, sizeof(GUID));
  55. }
  56. else
  57. hr = E_UNEXPECTED;
  58. }
  59. else if (cf == m_CFSnapInCLSID)
  60. {
  61. stream_ptr s(pMedium);
  62. hr = s.Write(&m_SnapInCLSID, sizeof(GUID));
  63. }
  64. else if (cf == m_CFNodeTypeString)
  65. {
  66. if ( IsValidObjectType (m_pCookie->m_objecttype) )
  67. {
  68. const BSTR strGUID = GetObjectTypeString( m_pCookie->m_objecttype );
  69. stream_ptr s(pMedium);
  70. hr = s.Write(strGUID);
  71. }
  72. else
  73. hr = E_UNEXPECTED;
  74. }
  75. else if (cf == m_CFDisplayName)
  76. {
  77. hr = PutDisplayName(pMedium);
  78. }
  79. else if (cf == m_CFDataObjectType)
  80. {
  81. stream_ptr s(pMedium);
  82. hr = s.Write(&m_dataobjecttype, sizeof(m_dataobjecttype));
  83. }
  84. else if (cf == m_CFMachineName)
  85. {
  86. if ( IsValidObjectType (m_pCookie->m_objecttype) )
  87. {
  88. stream_ptr s(pMedium);
  89. hr = s.Write(m_pCookie->QueryNonNULLMachineName());
  90. }
  91. else
  92. hr = E_UNEXPECTED;
  93. }
  94. else if (cf == m_CFRawCookie)
  95. {
  96. stream_ptr s(pMedium);
  97. if ( m_pCookie )
  98. {
  99. // CODEWORK This cast ensures that the data format is
  100. // always a CCookie*, even for derived subclasses
  101. if ( ((CCertMgrCookie*) MMC_MULTI_SELECT_COOKIE) == m_pCookie ||
  102. IsValidObjectType (m_pCookie->m_objecttype) )
  103. {
  104. CCookie* pcookie = (CCookie*) m_pCookie;
  105. hr = s.Write(reinterpret_cast<PBYTE>(&pcookie), sizeof(m_pCookie));
  106. }
  107. else
  108. hr = E_UNEXPECTED;
  109. }
  110. }
  111. else if ( cf == m_CFSCE_GPTUnknown )
  112. {
  113. hr = CreateGPTUnknown (pMedium);
  114. }
  115. else if ( cf == m_CFSCE_RSOPUnknown )
  116. {
  117. hr = CreateRSOPUnknown (pMedium);
  118. }
  119. else if ( cf == m_CFMultiSel )
  120. {
  121. hr = CreateMultiSelectObject (pMedium);
  122. }
  123. else if (cf == m_CFSnapinPreloads)
  124. {
  125. stream_ptr s(pMedium);
  126. // If this is TRUE, then the next time this snapin is loaded, it will
  127. // be preloaded to give us the opportunity to change the root node
  128. // name before the user sees it.
  129. hr = s.Write (reinterpret_cast<PBYTE>(&m_fAllowOverrideMachineName), sizeof (BOOL));
  130. }
  131. return hr;
  132. }
  133. HRESULT CCertMgrDataObject::Initialize(
  134. CCertMgrCookie* pcookie,
  135. DATA_OBJECT_TYPES type,
  136. BOOL fAllowOverrideMachineName,
  137. DWORD dwLocation,
  138. CString szManagedUser,
  139. CString szManagedComputer,
  140. CString szManagedService,
  141. CCertMgrComponentData& refComponentData)
  142. {
  143. if ( !pcookie || m_pCookie )
  144. {
  145. ASSERT(FALSE);
  146. return S_OK; // Initialize must not fail
  147. }
  148. m_dataobjecttype = type;
  149. m_pCookie = pcookie;
  150. m_fAllowOverrideMachineName = fAllowOverrideMachineName;
  151. m_dwLocation = dwLocation;
  152. m_szManagedUser = szManagedUser;
  153. m_szManagedComputer = szManagedComputer;
  154. m_szManagedService = szManagedService;
  155. if ( ((CCertMgrCookie*) MMC_MULTI_SELECT_COOKIE) != m_pCookie )
  156. ((CRefcountedObject*)m_pCookie)->AddRef();
  157. VERIFY( SUCCEEDED(refComponentData.GetClassID(&m_SnapInCLSID)) );
  158. return S_OK;
  159. }
  160. CCertMgrDataObject::~CCertMgrDataObject()
  161. {
  162. if ( m_pGPEInformation )
  163. {
  164. m_pGPEInformation->Release ();
  165. m_pGPEInformation = 0;
  166. }
  167. if ( m_pRSOPInformation )
  168. {
  169. m_pRSOPInformation->Release ();
  170. m_pRSOPInformation = 0;
  171. }
  172. if ( ((CCertMgrCookie*) MMC_MULTI_SELECT_COOKIE) != m_pCookie &&
  173. m_pCookie && IsValidObjectType (m_pCookie->m_objecttype) )
  174. {
  175. ((CRefcountedObject*)m_pCookie)->Release();
  176. }
  177. if (m_pbMultiSelData)
  178. delete m_pbMultiSelData;
  179. for (int i=0; i < m_rgCookies.GetSize(); ++i)
  180. {
  181. m_rgCookies[i]->Release();
  182. }
  183. }
  184. void CCertMgrDataObject::AddCookie(CCertMgrCookie* pCookie)
  185. {
  186. m_rgCookies.Add(pCookie);
  187. pCookie->AddRef();
  188. }
  189. HRESULT CCertMgrDataObject::PutDisplayName(STGMEDIUM* pMedium)
  190. // Writes the "friendly name" to the provided storage medium
  191. // Returns the result of the write operation
  192. {
  193. AFX_MANAGE_STATE (AfxGetStaticModuleState ());
  194. CString strDisplayName = m_pCookie->QueryTargetServer();
  195. CString formattedName;
  196. switch (m_dwLocation)
  197. {
  198. case CERT_SYSTEM_STORE_CURRENT_USER:
  199. VERIFY (formattedName.LoadString (IDS_SCOPE_SNAPIN_TITLE_USER));
  200. break;
  201. case CERT_SYSTEM_STORE_LOCAL_MACHINE:
  202. if (strDisplayName.IsEmpty())
  203. {
  204. VERIFY (formattedName.LoadString (IDS_SCOPE_SNAPIN_TITLE_LOCAL_MACHINE));
  205. }
  206. else
  207. formattedName.FormatMessage (IDS_SCOPE_SNAPIN_TITLE_MACHINE, strDisplayName);
  208. break;
  209. case CERT_SYSTEM_STORE_CURRENT_SERVICE:
  210. case CERT_SYSTEM_STORE_SERVICES:
  211. if (strDisplayName.IsEmpty())
  212. {
  213. // Get this machine name and add it to the string.
  214. formattedName.FormatMessage (IDS_SCOPE_SNAPIN_TITLE_SERVICE_LOCAL_MACHINE,
  215. m_szManagedService);
  216. }
  217. else
  218. {
  219. formattedName.FormatMessage (IDS_SCOPE_SNAPIN_TITLE_SERVICE,
  220. m_szManagedService, strDisplayName);
  221. }
  222. break;
  223. // These next two titles can only be set from the debugger. They are used
  224. // to create custom .MSC files.
  225. case -1:
  226. formattedName.FormatMessage (IDS_SCOPE_SNAPIN_TITLE_CERT_MGR_CURRENT_USER);
  227. break;
  228. case 0:
  229. formattedName.FormatMessage (IDS_SCOPE_SNAPIN_TITLE_FILE);
  230. break;
  231. default:
  232. ASSERT (0);
  233. break;
  234. }
  235. stream_ptr s (pMedium);
  236. return s.Write (formattedName);
  237. }
  238. // Register the clipboard formats
  239. CLIPFORMAT CCertMgrDataObject::m_CFDisplayName =
  240. (CLIPFORMAT)RegisterClipboardFormat(CCF_DISPLAY_NAME);
  241. CLIPFORMAT CCertMgrDataObject::m_CFMachineName =
  242. (CLIPFORMAT)RegisterClipboardFormat(L"MMC_SNAPIN_MACHINE_NAME");
  243. CLIPFORMAT CDataObject::m_CFRawCookie =
  244. (CLIPFORMAT)RegisterClipboardFormat(L"CERTMGR_SNAPIN_RAW_COOKIE");
  245. CLIPFORMAT CCertMgrDataObject::m_CFMultiSel =
  246. (CLIPFORMAT)RegisterClipboardFormat(CCF_OBJECT_TYPES_IN_MULTI_SELECT);
  247. CLIPFORMAT CCertMgrDataObject::m_CFMultiSelDobj =
  248. (CLIPFORMAT)RegisterClipboardFormat(CCF_MMC_MULTISELECT_DATAOBJECT);
  249. CLIPFORMAT CCertMgrDataObject::m_CFSCEModeType =
  250. (CLIPFORMAT)RegisterClipboardFormat(CCF_SCE_MODE_TYPE);
  251. CLIPFORMAT CCertMgrDataObject::m_CFSCE_GPTUnknown =
  252. (CLIPFORMAT)RegisterClipboardFormat(CCF_SCE_GPT_UNKNOWN);
  253. CLIPFORMAT CCertMgrDataObject::m_CFSCE_RSOPUnknown =
  254. (CLIPFORMAT)RegisterClipboardFormat(CCF_SCE_RSOP_UNKNOWN);
  255. CLIPFORMAT CCertMgrDataObject::m_CFMultiSelDataObjs =
  256. (CLIPFORMAT)RegisterClipboardFormat(CCF_MULTI_SELECT_SNAPINS);
  257. void CCertMgrDataObject::SetMultiSelData(BYTE* pbMultiSelData, UINT cbMultiSelData)
  258. {
  259. m_pbMultiSelData = pbMultiSelData;
  260. m_cbMultiSelData = cbMultiSelData;
  261. }
  262. ///////////////////////////////////////////////////////////////////////////////
  263. ///////////////////////////////////////////////////////////////////////////////
  264. STDMETHODIMP CCertMgrComponentData::QueryDataObject (
  265. MMC_COOKIE cookie,
  266. DATA_OBJECT_TYPES type,
  267. LPDATAOBJECT* ppDataObject)
  268. {
  269. if ( MMC_MULTI_SELECT_COOKIE == cookie )
  270. {
  271. return QueryMultiSelectDataObject (cookie, type, ppDataObject);
  272. }
  273. CCertMgrCookie* pUseThisCookie =
  274. (CCertMgrCookie*) ActiveBaseCookie (
  275. reinterpret_cast<CCookie*> (cookie));
  276. CComObject<CCertMgrDataObject>* pDataObject = 0;
  277. HRESULT hRes = CComObject<CCertMgrDataObject>::CreateInstance(&pDataObject);
  278. if ( FAILED(hRes) )
  279. return hRes;
  280. if ( m_szManagedUser.IsEmpty () )
  281. m_szManagedUser = m_szLoggedInUser;
  282. m_szManagedComputer = pUseThisCookie->QueryTargetServer();
  283. if ( m_szManagedComputer.IsEmpty () && m_strMachineNamePersist.CompareNoCase (m_szThisComputer) ) // !=
  284. {
  285. m_szManagedComputer = m_strMachineNamePersist;
  286. }
  287. if ( m_szManagedComputer.IsEmpty () )
  288. m_szManagedComputer = pUseThisCookie->QueryNonNULLMachineName ();
  289. if ( m_szManagedComputer.IsEmpty () )
  290. m_szManagedComputer = m_szThisComputer;
  291. // Raid bug 278491 US: Cert search for a remote computer application
  292. // fails to search certs on a remote computer, instead running a search
  293. // on Local machine
  294. if ( m_szManagedComputer.CompareNoCase (m_szThisComputer) )
  295. pUseThisCookie->SetMachineName (m_szManagedComputer);
  296. // Truncate leading "\\"
  297. if ( !wcsncmp (m_szManagedComputer, L"\\\\", 2) )
  298. m_szManagedComputer = m_szManagedComputer.Mid (2);
  299. HRESULT hr = pDataObject->Initialize (
  300. pUseThisCookie,
  301. type,
  302. m_fAllowOverrideMachineName,
  303. m_dwLocationPersist,
  304. m_szManagedUser,
  305. m_szManagedComputer,
  306. m_szManagedServiceDisplayName,
  307. *this);
  308. if ( FAILED(hr) )
  309. {
  310. delete pDataObject;
  311. return hr;
  312. }
  313. if ( m_pGPEInformation )
  314. pDataObject->SetGPTInformation (m_pGPEInformation);
  315. if ( m_bIsRSOP )
  316. {
  317. IRSOPInformation* pRSOPInformation = 0;
  318. switch (pUseThisCookie->m_objecttype)
  319. {
  320. case CERTMGR_CERT_POLICIES_COMPUTER:
  321. case CERTMGR_PKP_AUTOENROLLMENT_COMPUTER_SETTINGS:
  322. case CERTMGR_SAFER_COMPUTER_ROOT:
  323. case CERTMGR_SAFER_COMPUTER_LEVELS:
  324. case CERTMGR_SAFER_COMPUTER_ENTRIES:
  325. case CERTMGR_SAFER_COMPUTER_LEVEL:
  326. case CERTMGR_SAFER_COMPUTER_ENTRY:
  327. case CERTMGR_SAFER_COMPUTER_TRUSTED_PUBLISHERS:
  328. case CERTMGR_SAFER_COMPUTER_DEFINED_FILE_TYPES:
  329. pRSOPInformation = m_pRSOPInformationComputer;
  330. break;
  331. case CERTMGR_CERT_POLICIES_USER:
  332. case CERTMGR_PKP_AUTOENROLLMENT_USER_SETTINGS:
  333. case CERTMGR_SAFER_USER_ROOT:
  334. case CERTMGR_SAFER_USER_LEVELS:
  335. case CERTMGR_SAFER_USER_ENTRIES:
  336. case CERTMGR_SAFER_USER_LEVEL:
  337. case CERTMGR_SAFER_USER_ENTRY:
  338. case CERTMGR_SAFER_USER_TRUSTED_PUBLISHERS:
  339. case CERTMGR_SAFER_USER_DEFINED_FILE_TYPES:
  340. case CERTMGR_SAFER_COMPUTER_ENFORCEMENT:
  341. case CERTMGR_SAFER_USER_ENFORCEMENT:
  342. pRSOPInformation = m_pRSOPInformationUser;
  343. break;
  344. case CERTMGR_CERTIFICATE:
  345. case CERTMGR_LOG_STORE:
  346. case CERTMGR_PHYS_STORE:
  347. case CERTMGR_USAGE:
  348. case CERTMGR_CRL_CONTAINER:
  349. case CERTMGR_CTL_CONTAINER:
  350. case CERTMGR_CERT_CONTAINER:
  351. case CERTMGR_CRL:
  352. case CERTMGR_CTL:
  353. case CERTMGR_AUTO_CERT_REQUEST:
  354. case CERTMGR_LOG_STORE_GPE:
  355. case CERTMGR_LOG_STORE_RSOP:
  356. default:
  357. pRSOPInformation = m_pRSOPInformationComputer;
  358. break;
  359. }
  360. pDataObject->SetRSOPInformation (pRSOPInformation);
  361. }
  362. pDataObject->AddRef();
  363. *ppDataObject = pDataObject;
  364. return hr;
  365. }
  366. typedef CArray<GUID, const GUID&> CGUIDArray;
  367. void GuidArray_Add(CGUIDArray& rgGuids, const GUID& guid)
  368. {
  369. for (INT_PTR i=rgGuids.GetUpperBound(); i >= 0; --i)
  370. {
  371. if (rgGuids[i] == guid)
  372. break;
  373. }
  374. if (i < 0)
  375. rgGuids.Add(guid);
  376. }
  377. HRESULT CCertMgrComponentData::QueryMultiSelectDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
  378. LPDATAOBJECT* ppDataObject)
  379. {
  380. ASSERT(ppDataObject != NULL);
  381. if (ppDataObject == NULL)
  382. return E_POINTER;
  383. HRESULT hr = S_OK;
  384. CGUIDArray rgGuids;
  385. // Determine the items selected
  386. ASSERT(m_pResultData != NULL);
  387. RESULTDATAITEM rdi;
  388. ZeroMemory(&rdi, sizeof(rdi));
  389. rdi.mask = RDI_STATE;
  390. rdi.nIndex = -1;
  391. rdi.nState = TVIS_SELECTED;
  392. CCookiePtrArray rgCookiesSelected;
  393. while (m_pResultData->GetNextItem (&rdi) == S_OK)
  394. {
  395. const GUID* pguid;
  396. CCertMgrCookie* pCookie = reinterpret_cast <CCertMgrCookie*> (rdi.lParam);
  397. if ( pCookie )
  398. {
  399. rgCookiesSelected.Add (pCookie);
  400. switch (pCookie->m_objecttype)
  401. {
  402. case CERTMGR_CERTIFICATE:
  403. pguid = &NODEID_CertMgr_CERTIFICATE;
  404. break;
  405. case CERTMGR_CTL:
  406. pguid = &NODEID_CertMgr_CTL;
  407. break;
  408. case CERTMGR_CRL:
  409. pguid = &NODEID_CertMgr_CRL;
  410. break;
  411. case CERTMGR_AUTO_CERT_REQUEST:
  412. pguid = &NODEID_CertMgr_AUTOCERT;
  413. break;
  414. case CERTMGR_SAFER_COMPUTER_ENTRY:
  415. pguid = &NODEID_Safer_COMPUTER_ENTRY;
  416. break;
  417. case CERTMGR_SAFER_USER_ENTRY:
  418. pguid = &NODEID_Safer_USER_ENTRY;
  419. break;
  420. default:
  421. ASSERT (0);
  422. continue;
  423. }
  424. }
  425. else
  426. {
  427. hr = E_INVALIDARG;
  428. break;
  429. }
  430. GuidArray_Add(rgGuids, *pguid);
  431. }
  432. CComObject<CCertMgrDataObject>* pObject;
  433. CComObject<CCertMgrDataObject>::CreateInstance(&pObject);
  434. ASSERT(pObject != NULL);
  435. // Save cookie and type for delayed rendering
  436. pObject->Initialize ((CCertMgrCookie*) cookie,
  437. type,
  438. m_fAllowOverrideMachineName,
  439. m_dwLocationPersist,
  440. m_szManagedUser,
  441. m_szManagedComputer,
  442. m_szManagedServiceDisplayName,
  443. *this);
  444. pObject->SetMultiSelDobj();
  445. // Store the coclass with the data object
  446. UINT cb = (UINT)(rgGuids.GetSize() * sizeof(GUID));
  447. GUID* pGuid = new GUID[(UINT)rgGuids.GetSize()];
  448. if ( pGuid )
  449. {
  450. CopyMemory(pGuid, rgGuids.GetData(), cb);
  451. pObject->SetMultiSelData((BYTE*)pGuid, cb);
  452. for (int i=0; i < rgCookiesSelected.GetSize(); ++i)
  453. {
  454. pObject->AddCookie(rgCookiesSelected[i]);
  455. }
  456. return pObject->QueryInterface(
  457. IID_PPV_ARG (IDataObject, ppDataObject));
  458. }
  459. else
  460. return E_OUTOFMEMORY;
  461. }
  462. HRESULT CCertMgrDataObject::SetGPTInformation(IGPEInformation * pGPTInformation)
  463. {
  464. HRESULT hr = S_OK;
  465. if ( pGPTInformation )
  466. {
  467. m_pGPEInformation = pGPTInformation;
  468. m_pGPEInformation->AddRef ();
  469. }
  470. else
  471. hr = E_POINTER;
  472. return hr;
  473. }
  474. HRESULT CCertMgrDataObject::SetRSOPInformation(IRSOPInformation * pRSOPInformation)
  475. {
  476. HRESULT hr = S_OK;
  477. if ( pRSOPInformation )
  478. {
  479. m_pRSOPInformation = pRSOPInformation;
  480. m_pRSOPInformation->AddRef ();
  481. }
  482. else
  483. hr = E_POINTER;
  484. return hr;
  485. }
  486. //+--------------------------------------------------------------------------
  487. //
  488. // Member: CDataObject::CreateGPTUnknown
  489. //
  490. // Synopsis: Fill the hGlobal in [lpMedium] with a pointer to GPT's
  491. // IUnknown interface. The object requesting this will be
  492. // responsible for Releasing the interface
  493. //
  494. // History:
  495. //
  496. //---------------------------------------------------------------------------
  497. HRESULT CCertMgrDataObject::CreateGPTUnknown(LPSTGMEDIUM lpMedium)
  498. {
  499. HRESULT hr = S_OK;
  500. LPUNKNOWN pUnk = 0;
  501. if ( !m_pGPEInformation )
  502. {
  503. //
  504. // If we don't have a pointer to a GPT interface then we must not
  505. // be in a mode where we're extending GPT and we can't provide a
  506. // pointer to its IUnknown
  507. //
  508. return E_UNEXPECTED;
  509. }
  510. hr = m_pGPEInformation->QueryInterface (
  511. IID_PPV_ARG (IUnknown, &pUnk));
  512. if ( SUCCEEDED(hr) )
  513. {
  514. return Create (&pUnk, sizeof(pUnk), lpMedium);
  515. }
  516. else
  517. {
  518. return hr;
  519. }
  520. }
  521. //+--------------------------------------------------------------------------
  522. //
  523. // Member: CDataObject::CreateRSOPUnknown
  524. //
  525. // Synopsis: Fill the hGlobal in [lpMedium] with a pointer to RSOP's
  526. // IUnknown interface. The object requesting this will be
  527. // responsible for Releasing the interface
  528. //
  529. // History:
  530. //
  531. //---------------------------------------------------------------------------
  532. HRESULT CCertMgrDataObject::CreateRSOPUnknown(LPSTGMEDIUM lpMedium)
  533. {
  534. HRESULT hr = S_OK;
  535. LPUNKNOWN pUnk = 0;
  536. if ( !m_pRSOPInformation )
  537. {
  538. //
  539. // If we don't have a pointer to a GPT interface then we must not
  540. // be in a mode where we're extending GPT and we can't provide a
  541. // pointer to its IUnknown
  542. //
  543. return E_UNEXPECTED;
  544. }
  545. hr = m_pRSOPInformation->QueryInterface (
  546. IID_PPV_ARG (IUnknown, &pUnk));
  547. if ( SUCCEEDED(hr) )
  548. {
  549. return Create (&pUnk, sizeof(pUnk), lpMedium);
  550. }
  551. else
  552. {
  553. return hr;
  554. }
  555. }
  556. //+--------------------------------------------------------------------------
  557. //
  558. // Member: CDataObject::Create
  559. //
  560. // Synopsis: Fill the hGlobal in [lpmedium] with the data in pBuffer
  561. //
  562. // Arguments: [pBuffer] - [in] the data to be written
  563. // [len] - [in] the length of that data
  564. // [lpMedium] - [in,out] where to store the data
  565. // History:
  566. //
  567. //---------------------------------------------------------------------------
  568. HRESULT CCertMgrDataObject::Create (const void* pBuffer, int len, LPSTGMEDIUM lpMedium)
  569. {
  570. HRESULT hr = DV_E_TYMED;
  571. //
  572. // Do some simple validation
  573. //
  574. if (pBuffer == NULL || lpMedium == NULL)
  575. return E_POINTER;
  576. //
  577. // Make sure the type medium is HGLOBAL
  578. //
  579. if (lpMedium->tymed == TYMED_HGLOBAL) {
  580. //
  581. // Create the stream on the hGlobal passed in
  582. //
  583. LPSTREAM lpStream = 0;
  584. hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &lpStream);
  585. ASSERT (SUCCEEDED (hr));
  586. if (SUCCEEDED(hr))
  587. {
  588. //
  589. // Write to the stream the number of bytes
  590. //
  591. ULONG written = 0;
  592. hr = lpStream->Write(pBuffer, len, &written);
  593. ASSERT (SUCCEEDED (hr));
  594. //
  595. // Because we told CreateStreamOnHGlobal with 'FALSE',
  596. // only the stream is released here.
  597. // Note - the caller (i.e. snap-in, object) will free the HGLOBAL
  598. // at the correct time. This is according to the IDataObject specification.
  599. //
  600. lpStream->Release();
  601. }
  602. }
  603. return hr;
  604. }
  605. //+----------------------------------------------------------------------------
  606. //
  607. // Method: CCertMgrDataObject::CreateMultiSelectObject
  608. //
  609. // Synopsis: this is to create the list of types selected
  610. //
  611. //-----------------------------------------------------------------------------
  612. HRESULT CCertMgrDataObject::CreateMultiSelectObject(LPSTGMEDIUM lpMedium)
  613. {
  614. ASSERT(m_pbMultiSelData != 0);
  615. ASSERT(m_cbMultiSelData != 0);
  616. lpMedium->tymed = TYMED_HGLOBAL;
  617. lpMedium->hGlobal = ::GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE,
  618. (m_cbMultiSelData + sizeof(DWORD)));
  619. if (lpMedium->hGlobal == NULL)
  620. return STG_E_MEDIUMFULL;
  621. BYTE* pb = reinterpret_cast<BYTE*>(::GlobalLock(lpMedium->hGlobal));
  622. *((DWORD*)pb) = m_cbMultiSelData / sizeof(GUID);
  623. pb += sizeof(DWORD);
  624. CopyMemory(pb, m_pbMultiSelData, m_cbMultiSelData);
  625. ::GlobalUnlock(lpMedium->hGlobal);
  626. return S_OK;
  627. }
  628. LPDATAOBJECT ExtractMultiSelect (LPDATAOBJECT lpDataObject)
  629. {
  630. if (lpDataObject == NULL)
  631. return NULL;
  632. SMMCDataObjects * pDO = NULL;
  633. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  634. FORMATETC formatetc = { CCertMgrDataObject::m_CFMultiSelDataObjs, NULL,
  635. DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  636. if ( FAILED (lpDataObject->GetData (&formatetc, &stgmedium)) )
  637. {
  638. return NULL;
  639. }
  640. else
  641. {
  642. pDO = reinterpret_cast<SMMCDataObjects*>(stgmedium.hGlobal);
  643. return pDO->lpDataObject[0]; //assume that ours is the 1st
  644. }
  645. }
  646. STDMETHODIMP CCertMgrDataObject::GetData(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
  647. {
  648. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  649. HRESULT hr = DV_E_CLIPFORMAT;
  650. if (lpFormatetc->cfFormat == m_CFMultiSel)
  651. {
  652. ASSERT(((CCertMgrCookie*) MMC_MULTI_SELECT_COOKIE) == m_pCookie);
  653. if ( ((CCertMgrCookie*) MMC_MULTI_SELECT_COOKIE) == m_pCookie )
  654. {
  655. hr = CreateMultiSelectObject (lpMedium);
  656. }
  657. else
  658. hr = E_FAIL;
  659. }
  660. return hr;
  661. }
  662. STDMETHODIMP CCertMgrDataObject::Next(ULONG celt, MMC_COOKIE* rgelt, ULONG *pceltFetched)
  663. {
  664. HRESULT hr = S_OK;
  665. if ((rgelt == NULL) ||
  666. ((celt > 1) && (pceltFetched == NULL)))
  667. {
  668. hr = E_INVALIDARG;
  669. CHECK_HRESULT(hr);
  670. return hr;
  671. }
  672. ULONG celtTemp = (ULONG)(m_rgCookies.GetSize() - m_iCurr);
  673. celtTemp = (celt < celtTemp) ? celt : celtTemp;
  674. if (pceltFetched)
  675. *pceltFetched = celtTemp;
  676. if (celtTemp == 0)
  677. return S_FALSE;
  678. for (ULONG i=0; i < celtTemp; ++i)
  679. {
  680. rgelt[i] = reinterpret_cast<MMC_COOKIE>(m_rgCookies[m_iCurr++]);
  681. }
  682. return (celtTemp < celt) ? S_FALSE : S_OK;
  683. }
  684. STDMETHODIMP CCertMgrDataObject::Skip(ULONG celt)
  685. {
  686. ULONG celtTemp = (ULONG)(m_rgCookies.GetSize() - m_iCurr);
  687. celtTemp = (celt < celtTemp) ? celt : celtTemp;
  688. m_iCurr += celtTemp;
  689. return (celtTemp < celt) ? S_FALSE : S_OK;
  690. }
  691. STDMETHODIMP CCertMgrDataObject::Reset(void)
  692. {
  693. m_iCurr = 0;
  694. return S_OK;
  695. }