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.

829 lines
22 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997-2002.
  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. // security review 2/27/2002 BryanWal ok
  298. if ( !wcsncmp (m_szManagedComputer, L"\\\\", 2) )
  299. m_szManagedComputer = m_szManagedComputer.Mid (2);
  300. HRESULT hr = pDataObject->Initialize (
  301. pUseThisCookie,
  302. type,
  303. m_fAllowOverrideMachineName,
  304. m_dwLocationPersist,
  305. m_szManagedUser,
  306. m_szManagedComputer,
  307. m_szManagedServiceDisplayName,
  308. *this);
  309. if ( FAILED(hr) )
  310. {
  311. delete pDataObject;
  312. return hr;
  313. }
  314. if ( m_pGPEInformation )
  315. pDataObject->SetGPTInformation (m_pGPEInformation);
  316. if ( m_bIsRSOP )
  317. {
  318. IRSOPInformation* pRSOPInformation = 0;
  319. switch (pUseThisCookie->m_objecttype)
  320. {
  321. case CERTMGR_CERT_POLICIES_COMPUTER:
  322. case CERTMGR_PKP_AUTOENROLLMENT_COMPUTER_SETTINGS:
  323. case CERTMGR_SAFER_COMPUTER_ROOT:
  324. case CERTMGR_SAFER_COMPUTER_LEVELS:
  325. case CERTMGR_SAFER_COMPUTER_ENTRIES:
  326. case CERTMGR_SAFER_COMPUTER_LEVEL:
  327. case CERTMGR_SAFER_COMPUTER_ENTRY:
  328. case CERTMGR_SAFER_COMPUTER_TRUSTED_PUBLISHERS:
  329. case CERTMGR_SAFER_COMPUTER_DEFINED_FILE_TYPES:
  330. pRSOPInformation = m_pRSOPInformationComputer;
  331. break;
  332. case CERTMGR_CERT_POLICIES_USER:
  333. case CERTMGR_PKP_AUTOENROLLMENT_USER_SETTINGS:
  334. case CERTMGR_SAFER_USER_ROOT:
  335. case CERTMGR_SAFER_USER_LEVELS:
  336. case CERTMGR_SAFER_USER_ENTRIES:
  337. case CERTMGR_SAFER_USER_LEVEL:
  338. case CERTMGR_SAFER_USER_ENTRY:
  339. case CERTMGR_SAFER_USER_TRUSTED_PUBLISHERS:
  340. case CERTMGR_SAFER_USER_DEFINED_FILE_TYPES:
  341. case CERTMGR_SAFER_COMPUTER_ENFORCEMENT:
  342. case CERTMGR_SAFER_USER_ENFORCEMENT:
  343. pRSOPInformation = m_pRSOPInformationUser;
  344. break;
  345. case CERTMGR_CERTIFICATE:
  346. case CERTMGR_LOG_STORE:
  347. case CERTMGR_PHYS_STORE:
  348. case CERTMGR_USAGE:
  349. case CERTMGR_CRL_CONTAINER:
  350. case CERTMGR_CTL_CONTAINER:
  351. case CERTMGR_CERT_CONTAINER:
  352. case CERTMGR_CRL:
  353. case CERTMGR_CTL:
  354. case CERTMGR_AUTO_CERT_REQUEST:
  355. case CERTMGR_LOG_STORE_GPE:
  356. case CERTMGR_LOG_STORE_RSOP:
  357. default:
  358. pRSOPInformation = m_pRSOPInformationComputer;
  359. break;
  360. }
  361. pDataObject->SetRSOPInformation (pRSOPInformation);
  362. }
  363. pDataObject->AddRef();
  364. *ppDataObject = pDataObject;
  365. return hr;
  366. }
  367. typedef CArray<GUID, const GUID&> CGUIDArray;
  368. void GuidArray_Add(CGUIDArray& rgGuids, const GUID& guid)
  369. {
  370. for (INT_PTR i=rgGuids.GetUpperBound(); i >= 0; --i)
  371. {
  372. if (rgGuids[i] == guid)
  373. break;
  374. }
  375. if (i < 0)
  376. rgGuids.Add(guid);
  377. }
  378. HRESULT CCertMgrComponentData::QueryMultiSelectDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
  379. LPDATAOBJECT* ppDataObject)
  380. {
  381. ASSERT(ppDataObject != NULL);
  382. if (ppDataObject == NULL)
  383. return E_POINTER;
  384. HRESULT hr = S_OK;
  385. CGUIDArray rgGuids;
  386. // Determine the items selected
  387. ASSERT(m_pResultData != NULL);
  388. RESULTDATAITEM rdi;
  389. // security review 2/27/2002 BryanWal ok
  390. ::ZeroMemory(&rdi, sizeof(rdi));
  391. rdi.mask = RDI_STATE;
  392. rdi.nIndex = -1;
  393. rdi.nState = TVIS_SELECTED;
  394. CCookiePtrArray rgCookiesSelected;
  395. while (m_pResultData->GetNextItem (&rdi) == S_OK)
  396. {
  397. const GUID* pguid;
  398. CCertMgrCookie* pCookie = reinterpret_cast <CCertMgrCookie*> (rdi.lParam);
  399. if ( pCookie )
  400. {
  401. rgCookiesSelected.Add (pCookie);
  402. switch (pCookie->m_objecttype)
  403. {
  404. case CERTMGR_CERTIFICATE:
  405. pguid = &NODEID_CertMgr_CERTIFICATE;
  406. break;
  407. case CERTMGR_CTL:
  408. pguid = &NODEID_CertMgr_CTL;
  409. break;
  410. case CERTMGR_CRL:
  411. pguid = &NODEID_CertMgr_CRL;
  412. break;
  413. case CERTMGR_AUTO_CERT_REQUEST:
  414. pguid = &NODEID_CertMgr_AUTOCERT;
  415. break;
  416. case CERTMGR_SAFER_COMPUTER_ENTRY:
  417. pguid = &NODEID_Safer_COMPUTER_ENTRY;
  418. break;
  419. case CERTMGR_SAFER_USER_ENTRY:
  420. pguid = &NODEID_Safer_USER_ENTRY;
  421. break;
  422. default:
  423. ASSERT (0);
  424. continue;
  425. }
  426. }
  427. else
  428. {
  429. hr = E_INVALIDARG;
  430. break;
  431. }
  432. GuidArray_Add(rgGuids, *pguid);
  433. }
  434. CComObject<CCertMgrDataObject>* pObject;
  435. CComObject<CCertMgrDataObject>::CreateInstance(&pObject);
  436. ASSERT(pObject != NULL);
  437. // Save cookie and type for delayed rendering
  438. pObject->Initialize ((CCertMgrCookie*) cookie,
  439. type,
  440. m_fAllowOverrideMachineName,
  441. m_dwLocationPersist,
  442. m_szManagedUser,
  443. m_szManagedComputer,
  444. m_szManagedServiceDisplayName,
  445. *this);
  446. pObject->SetMultiSelDobj();
  447. // Store the coclass with the data object
  448. UINT cb = (UINT)(rgGuids.GetSize() * sizeof(GUID));
  449. GUID* pGuid = new GUID[(UINT)rgGuids.GetSize()];
  450. if ( pGuid )
  451. {
  452. // security review 2/27/2002 BryanWal ok
  453. ::CopyMemory(pGuid, rgGuids.GetData(), cb);
  454. pObject->SetMultiSelData((BYTE*)pGuid, cb);
  455. for (int i=0; i < rgCookiesSelected.GetSize(); ++i)
  456. {
  457. pObject->AddCookie(rgCookiesSelected[i]);
  458. }
  459. return pObject->QueryInterface(
  460. IID_PPV_ARG (IDataObject, ppDataObject));
  461. }
  462. else
  463. return E_OUTOFMEMORY;
  464. }
  465. HRESULT CCertMgrDataObject::SetGPTInformation(IGPEInformation * pGPTInformation)
  466. {
  467. HRESULT hr = S_OK;
  468. if ( pGPTInformation )
  469. {
  470. m_pGPEInformation = pGPTInformation;
  471. m_pGPEInformation->AddRef ();
  472. }
  473. else
  474. hr = E_POINTER;
  475. return hr;
  476. }
  477. HRESULT CCertMgrDataObject::SetRSOPInformation(IRSOPInformation * pRSOPInformation)
  478. {
  479. HRESULT hr = S_OK;
  480. if ( pRSOPInformation )
  481. {
  482. m_pRSOPInformation = pRSOPInformation;
  483. m_pRSOPInformation->AddRef ();
  484. }
  485. else
  486. hr = E_POINTER;
  487. return hr;
  488. }
  489. //+--------------------------------------------------------------------------
  490. //
  491. // Member: CDataObject::CreateGPTUnknown
  492. //
  493. // Synopsis: Fill the hGlobal in [lpMedium] with a pointer to GPT's
  494. // IUnknown interface. The object requesting this will be
  495. // responsible for Releasing the interface
  496. //
  497. // History:
  498. //
  499. //---------------------------------------------------------------------------
  500. HRESULT CCertMgrDataObject::CreateGPTUnknown(LPSTGMEDIUM lpMedium)
  501. {
  502. HRESULT hr = S_OK;
  503. LPUNKNOWN pUnk = 0;
  504. if ( !m_pGPEInformation )
  505. {
  506. //
  507. // If we don't have a pointer to a GPT interface then we must not
  508. // be in a mode where we're extending GPT and we can't provide a
  509. // pointer to its IUnknown
  510. //
  511. return E_UNEXPECTED;
  512. }
  513. hr = m_pGPEInformation->QueryInterface (
  514. IID_PPV_ARG (IUnknown, &pUnk));
  515. if ( SUCCEEDED(hr) )
  516. {
  517. return Create (&pUnk, sizeof(pUnk), lpMedium);
  518. }
  519. else
  520. {
  521. return hr;
  522. }
  523. }
  524. //+--------------------------------------------------------------------------
  525. //
  526. // Member: CDataObject::CreateRSOPUnknown
  527. //
  528. // Synopsis: Fill the hGlobal in [lpMedium] with a pointer to RSOP's
  529. // IUnknown interface. The object requesting this will be
  530. // responsible for Releasing the interface
  531. //
  532. // History:
  533. //
  534. //---------------------------------------------------------------------------
  535. HRESULT CCertMgrDataObject::CreateRSOPUnknown(LPSTGMEDIUM lpMedium)
  536. {
  537. HRESULT hr = S_OK;
  538. LPUNKNOWN pUnk = 0;
  539. if ( !m_pRSOPInformation )
  540. {
  541. //
  542. // If we don't have a pointer to a GPT interface then we must not
  543. // be in a mode where we're extending GPT and we can't provide a
  544. // pointer to its IUnknown
  545. //
  546. return E_UNEXPECTED;
  547. }
  548. hr = m_pRSOPInformation->QueryInterface (
  549. IID_PPV_ARG (IUnknown, &pUnk));
  550. if ( SUCCEEDED(hr) )
  551. {
  552. return Create (&pUnk, sizeof(pUnk), lpMedium);
  553. }
  554. else
  555. {
  556. return hr;
  557. }
  558. }
  559. //+--------------------------------------------------------------------------
  560. //
  561. // Member: CDataObject::Create
  562. //
  563. // Synopsis: Fill the hGlobal in [lpmedium] with the data in pBuffer
  564. //
  565. // Arguments: [pBuffer] - [in] the data to be written
  566. // [len] - [in] the length of that data
  567. // [lpMedium] - [in,out] where to store the data
  568. // History:
  569. //
  570. //---------------------------------------------------------------------------
  571. HRESULT CCertMgrDataObject::Create (const void* pBuffer, int len, LPSTGMEDIUM lpMedium)
  572. {
  573. HRESULT hr = DV_E_TYMED;
  574. //
  575. // Do some simple validation
  576. //
  577. if (pBuffer == NULL || lpMedium == NULL)
  578. return E_POINTER;
  579. //
  580. // Make sure the type medium is HGLOBAL
  581. //
  582. if (lpMedium->tymed == TYMED_HGLOBAL) {
  583. //
  584. // Create the stream on the hGlobal passed in
  585. //
  586. LPSTREAM lpStream = 0;
  587. hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &lpStream);
  588. ASSERT (SUCCEEDED (hr));
  589. if (SUCCEEDED(hr))
  590. {
  591. //
  592. // Write to the stream the number of bytes
  593. //
  594. ULONG written = 0;
  595. hr = lpStream->Write(pBuffer, len, &written);
  596. ASSERT (SUCCEEDED (hr));
  597. //
  598. // Because we told CreateStreamOnHGlobal with 'FALSE',
  599. // only the stream is released here.
  600. // Note - the caller (i.e. snap-in, object) will free the HGLOBAL
  601. // at the correct time. This is according to the IDataObject specification.
  602. //
  603. lpStream->Release();
  604. }
  605. }
  606. return hr;
  607. }
  608. //+----------------------------------------------------------------------------
  609. //
  610. // Method: CCertMgrDataObject::CreateMultiSelectObject
  611. //
  612. // Synopsis: this is to create the list of types selected
  613. //
  614. //-----------------------------------------------------------------------------
  615. HRESULT CCertMgrDataObject::CreateMultiSelectObject(LPSTGMEDIUM lpMedium)
  616. {
  617. ASSERT(m_pbMultiSelData != 0);
  618. ASSERT(m_cbMultiSelData != 0);
  619. if ( !m_pbMultiSelData || !m_cbMultiSelData )
  620. return E_FAIL;
  621. if ( !lpMedium )
  622. return E_POINTER;
  623. lpMedium->tymed = TYMED_HGLOBAL;
  624. lpMedium->hGlobal = ::GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE,
  625. (m_cbMultiSelData + sizeof(DWORD)));
  626. if (lpMedium->hGlobal == NULL)
  627. return STG_E_MEDIUMFULL;
  628. BYTE* pb = reinterpret_cast<BYTE*>(::GlobalLock(lpMedium->hGlobal));
  629. if ( pb )
  630. {
  631. *((DWORD*)pb) = m_cbMultiSelData / sizeof(GUID);
  632. pb += sizeof(DWORD);
  633. // security review 2/27/2002 BryanWal ok
  634. ::CopyMemory(pb, m_pbMultiSelData, m_cbMultiSelData);
  635. ::GlobalUnlock(lpMedium->hGlobal);
  636. }
  637. else
  638. {
  639. ::GlobalFree (lpMedium->hGlobal);
  640. return HRESULT_FROM_WIN32 (GetLastError ());
  641. }
  642. return S_OK;
  643. }
  644. LPDATAOBJECT ExtractMultiSelect (LPDATAOBJECT lpDataObject)
  645. {
  646. if (lpDataObject == NULL)
  647. return NULL;
  648. SMMCDataObjects * pDO = NULL;
  649. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  650. FORMATETC formatetc = { CCertMgrDataObject::m_CFMultiSelDataObjs, NULL,
  651. DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  652. if ( FAILED (lpDataObject->GetData (&formatetc, &stgmedium)) )
  653. {
  654. return NULL;
  655. }
  656. else
  657. {
  658. pDO = reinterpret_cast<SMMCDataObjects*>(stgmedium.hGlobal);
  659. return pDO->lpDataObject[0]; //assume that ours is the 1st
  660. }
  661. }
  662. STDMETHODIMP CCertMgrDataObject::GetData(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
  663. {
  664. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  665. HRESULT hr = DV_E_CLIPFORMAT;
  666. if (lpFormatetc->cfFormat == m_CFMultiSel)
  667. {
  668. ASSERT(((CCertMgrCookie*) MMC_MULTI_SELECT_COOKIE) == m_pCookie);
  669. if ( ((CCertMgrCookie*) MMC_MULTI_SELECT_COOKIE) == m_pCookie )
  670. {
  671. hr = CreateMultiSelectObject (lpMedium);
  672. }
  673. else
  674. hr = E_FAIL;
  675. }
  676. return hr;
  677. }
  678. STDMETHODIMP CCertMgrDataObject::Next(ULONG celt, MMC_COOKIE* rgelt, ULONG *pceltFetched)
  679. {
  680. HRESULT hr = S_OK;
  681. if ((rgelt == NULL) ||
  682. ((celt > 1) && (pceltFetched == NULL)))
  683. {
  684. hr = E_INVALIDARG;
  685. CHECK_HRESULT(hr);
  686. return hr;
  687. }
  688. ULONG celtTemp = (ULONG)(m_rgCookies.GetSize() - m_iCurr);
  689. celtTemp = (celt < celtTemp) ? celt : celtTemp;
  690. if (pceltFetched)
  691. *pceltFetched = celtTemp;
  692. if (celtTemp == 0)
  693. return S_FALSE;
  694. for (ULONG i=0; i < celtTemp; ++i)
  695. {
  696. rgelt[i] = reinterpret_cast<MMC_COOKIE>(m_rgCookies[m_iCurr++]);
  697. }
  698. return (celtTemp < celt) ? S_FALSE : S_OK;
  699. }
  700. STDMETHODIMP CCertMgrDataObject::Skip(ULONG celt)
  701. {
  702. ULONG celtTemp = (ULONG)(m_rgCookies.GetSize() - m_iCurr);
  703. celtTemp = (celt < celtTemp) ? celt : celtTemp;
  704. m_iCurr += celtTemp;
  705. return (celtTemp < celt) ? S_FALSE : S_OK;
  706. }
  707. STDMETHODIMP CCertMgrDataObject::Reset(void)
  708. {
  709. m_iCurr = 0;
  710. return S_OK;
  711. }