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.

573 lines
16 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: CCertTemplatesDataObject
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. USE_HANDLE_MACROS("CERTTMPL(dataobj.cpp)")
  13. #include "compdata.h"
  14. #include "dataobj.h"
  15. #include "uuids.h"
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. #include "stddtobj.cpp"
  22. // IDataObject interface implementation
  23. CCertTemplatesDataObject::CCertTemplatesDataObject()
  24. : m_pCookie (0),
  25. m_objecttype (CERTTMPL_SNAPIN),
  26. m_dataobjecttype (CCT_UNINITIALIZED),
  27. m_pbMultiSelData(NULL),
  28. m_cbMultiSelData(0),
  29. m_bMultiSelDobj(false),
  30. m_iCurr(0)
  31. {
  32. }
  33. HRESULT CCertTemplatesDataObject::GetDataHere(
  34. FORMATETC __RPC_FAR *pFormatEtcIn,
  35. STGMEDIUM __RPC_FAR *pMedium)
  36. {
  37. const CLIPFORMAT cf=pFormatEtcIn->cfFormat;
  38. if (cf == m_CFNodeType)
  39. {
  40. if ( IsValidObjectType (m_pCookie->m_objecttype) )
  41. {
  42. const GUID* pguid = GetObjectTypeGUID( m_pCookie->m_objecttype );
  43. stream_ptr s(pMedium);
  44. return s.Write(pguid, sizeof(GUID));
  45. }
  46. else
  47. return E_UNEXPECTED;
  48. }
  49. else if (cf == m_CFSnapInCLSID)
  50. {
  51. stream_ptr s(pMedium);
  52. return s.Write(&m_SnapInCLSID, sizeof(GUID));
  53. }
  54. else if (cf == m_CFNodeTypeString)
  55. {
  56. if ( IsValidObjectType (m_pCookie->m_objecttype) )
  57. {
  58. const BSTR strGUID = GetObjectTypeString( m_pCookie->m_objecttype );
  59. stream_ptr s(pMedium);
  60. return s.Write(strGUID);
  61. }
  62. else
  63. return E_UNEXPECTED;
  64. }
  65. else if (cf == m_CFDisplayName)
  66. {
  67. return PutDisplayName(pMedium);
  68. }
  69. else if (cf == m_CFDataObjectType)
  70. {
  71. stream_ptr s(pMedium);
  72. return s.Write(&m_dataobjecttype, sizeof(m_dataobjecttype));
  73. }
  74. else if (cf == m_CFRawCookie)
  75. {
  76. stream_ptr s(pMedium);
  77. if ( m_pCookie )
  78. {
  79. // CODEWORK This cast ensures that the data format is
  80. // always a CCookie*, even for derived subclasses
  81. if ( ((CCertTmplCookie*) MMC_MULTI_SELECT_COOKIE) == m_pCookie ||
  82. IsValidObjectType (m_pCookie->m_objecttype) )
  83. {
  84. CCookie* pcookie = (CCookie*) m_pCookie;
  85. return s.Write(reinterpret_cast<PBYTE>(&pcookie), sizeof(m_pCookie));
  86. }
  87. else
  88. return E_UNEXPECTED;
  89. }
  90. }
  91. else if ( cf == m_CFMultiSel )
  92. {
  93. return CreateMultiSelectObject (pMedium);
  94. }
  95. else if (cf == m_CFSnapinPreloads)
  96. {
  97. stream_ptr s(pMedium);
  98. // If this is TRUE, then the next time this snapin is loaded, it will
  99. // be preloaded to give us the opportunity to change the root node
  100. // name before the user sees it.
  101. BOOL x = 1;
  102. return s.Write (reinterpret_cast<PBYTE>(&x), sizeof (BOOL));
  103. }
  104. return DV_E_FORMATETC;
  105. }
  106. HRESULT CCertTemplatesDataObject::Initialize(
  107. CCertTmplCookie* pcookie,
  108. DATA_OBJECT_TYPES type,
  109. CCertTmplComponentData& refComponentData)
  110. {
  111. if ( !pcookie || m_pCookie )
  112. {
  113. ASSERT(FALSE);
  114. return S_OK; // Initialize must not fail
  115. }
  116. m_dataobjecttype = type;
  117. m_pCookie = pcookie;
  118. if ( ((CCertTmplCookie*) MMC_MULTI_SELECT_COOKIE) != m_pCookie )
  119. ((CRefcountedObject*)m_pCookie)->AddRef();
  120. VERIFY( SUCCEEDED(refComponentData.GetClassID(&m_SnapInCLSID)) );
  121. return S_OK;
  122. }
  123. CCertTemplatesDataObject::~CCertTemplatesDataObject()
  124. {
  125. if ( ((CCertTmplCookie*) MMC_MULTI_SELECT_COOKIE) != m_pCookie &&
  126. m_pCookie && IsValidObjectType (m_pCookie->m_objecttype) )
  127. {
  128. ((CRefcountedObject*)m_pCookie)->Release();
  129. }
  130. if (m_pbMultiSelData)
  131. delete m_pbMultiSelData;
  132. for (int i=0; i < m_rgCookies.GetSize(); ++i)
  133. {
  134. m_rgCookies[i]->Release();
  135. m_rgCookies[i] = 0;
  136. }
  137. }
  138. void CCertTemplatesDataObject::AddCookie(CCertTmplCookie* pCookie)
  139. {
  140. m_rgCookies.Add(pCookie);
  141. pCookie->AddRef();
  142. }
  143. HRESULT CCertTemplatesDataObject::PutDisplayName(STGMEDIUM* pMedium)
  144. // Writes the "friendly name" to the provided storage medium
  145. // Returns the result of the write operation
  146. {
  147. AFX_MANAGE_STATE (AfxGetStaticModuleState ());
  148. CString strDomainName = m_pCookie->GetManagedDomainDNSName();
  149. stream_ptr s (pMedium);
  150. CString snapinName;
  151. // security review 2/21/2002 BryanWal ok
  152. snapinName.FormatMessage (IDS_CERTTMPL_ROOT_NODE_NAME, strDomainName);
  153. return s.Write ((PCWSTR) snapinName);
  154. }
  155. // Register the clipboard formats
  156. CLIPFORMAT CCertTemplatesDataObject::m_CFDisplayName =
  157. (CLIPFORMAT)RegisterClipboardFormat(CCF_DISPLAY_NAME);
  158. CLIPFORMAT CDataObject::m_CFRawCookie =
  159. (CLIPFORMAT)RegisterClipboardFormat(L"CERTTMPL_SNAPIN_RAW_COOKIE");
  160. CLIPFORMAT CCertTemplatesDataObject::m_CFMultiSel =
  161. (CLIPFORMAT)RegisterClipboardFormat(CCF_OBJECT_TYPES_IN_MULTI_SELECT);
  162. CLIPFORMAT CCertTemplatesDataObject::m_CFMultiSelDobj =
  163. (CLIPFORMAT)RegisterClipboardFormat(CCF_MMC_MULTISELECT_DATAOBJECT);
  164. CLIPFORMAT CCertTemplatesDataObject::m_CFMultiSelDataObjs =
  165. (CLIPFORMAT)RegisterClipboardFormat(CCF_MULTI_SELECT_SNAPINS);
  166. CLIPFORMAT CCertTemplatesDataObject::m_CFDsObjectNames =
  167. (CLIPFORMAT)RegisterClipboardFormat(CFSTR_DSOBJECTNAMES);
  168. void CCertTemplatesDataObject::SetMultiSelData(BYTE* pbMultiSelData, UINT cbMultiSelData)
  169. {
  170. m_pbMultiSelData = pbMultiSelData;
  171. m_cbMultiSelData = cbMultiSelData;
  172. }
  173. ///////////////////////////////////////////////////////////////////////////////
  174. ///////////////////////////////////////////////////////////////////////////////
  175. STDMETHODIMP CCertTmplComponentData::QueryDataObject (
  176. MMC_COOKIE cookie,
  177. DATA_OBJECT_TYPES type,
  178. LPDATAOBJECT* ppDataObject)
  179. {
  180. if ( MMC_MULTI_SELECT_COOKIE == cookie )
  181. {
  182. return QueryMultiSelectDataObject (cookie, type, ppDataObject);
  183. }
  184. CCertTmplCookie* pUseThisCookie =
  185. (CCertTmplCookie*) ActiveBaseCookie (
  186. reinterpret_cast<CCookie*> (cookie));
  187. CComObject<CCertTemplatesDataObject>* pDataObject = 0;
  188. HRESULT hRes = CComObject<CCertTemplatesDataObject>::CreateInstance(&pDataObject);
  189. if ( FAILED(hRes) )
  190. return hRes;
  191. HRESULT hr = pDataObject->Initialize (
  192. pUseThisCookie,
  193. type,
  194. *this);
  195. if ( FAILED(hr) )
  196. {
  197. delete pDataObject;
  198. return hr;
  199. }
  200. pDataObject->AddRef();
  201. *ppDataObject = pDataObject;
  202. return hr;
  203. }
  204. typedef CArray<GUID, const GUID&> CGUIDArray;
  205. void GuidArray_Add(CGUIDArray& rgGuids, const GUID& guid)
  206. {
  207. for (INT_PTR i=rgGuids.GetUpperBound(); i >= 0; --i)
  208. {
  209. if (rgGuids[i] == guid)
  210. break;
  211. }
  212. if (i < 0)
  213. rgGuids.Add(guid);
  214. }
  215. HRESULT CCertTmplComponentData::QueryMultiSelectDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
  216. LPDATAOBJECT* ppDataObject)
  217. {
  218. ASSERT(ppDataObject != NULL);
  219. if (ppDataObject == NULL)
  220. return E_POINTER;
  221. HRESULT hr = S_OK;
  222. CGUIDArray rgGuids;
  223. // Determine the items selected
  224. ASSERT(m_pResultData != NULL);
  225. RESULTDATAITEM rdi;
  226. // security review 2/21/2002 BryanWal ok
  227. ZeroMemory(&rdi, sizeof(rdi));
  228. rdi.mask = RDI_STATE;
  229. rdi.nIndex = -1;
  230. rdi.nState = TVIS_SELECTED;
  231. CCookiePtrArray rgCookiesSelected;
  232. while (m_pResultData->GetNextItem (&rdi) == S_OK)
  233. {
  234. const GUID* pguid;
  235. CCertTmplCookie* pCookie = reinterpret_cast <CCertTmplCookie*> (rdi.lParam);
  236. if ( pCookie )
  237. {
  238. rgCookiesSelected.Add (pCookie);
  239. switch (pCookie->m_objecttype)
  240. {
  241. case CERTTMPL_CERT_TEMPLATE:
  242. pguid = &NODEID_CertTmpl_CERT_TEMPLATE;
  243. break;
  244. default:
  245. ASSERT (0);
  246. continue;
  247. }
  248. }
  249. else
  250. {
  251. hr = E_INVALIDARG;
  252. break;
  253. }
  254. GuidArray_Add(rgGuids, *pguid);
  255. }
  256. if ( SUCCEEDED (hr) )
  257. {
  258. CComObject<CCertTemplatesDataObject>* pObject;
  259. hr = CComObject<CCertTemplatesDataObject>::CreateInstance(&pObject);
  260. ASSERT(SUCCEEDED (hr) && pObject != NULL);
  261. if ( SUCCEEDED (hr) )
  262. {
  263. if ( pObject )
  264. {
  265. // Save cookie and type for delayed rendering
  266. pObject->Initialize ((CCertTmplCookie*) cookie,
  267. type,
  268. *this);
  269. pObject->SetMultiSelDobj();
  270. // Store the coclass with the data object
  271. UINT cb = (UINT)(rgGuids.GetSize() * sizeof(GUID));
  272. GUID* pGuid = new GUID[(UINT)rgGuids.GetSize()];
  273. if ( pGuid )
  274. {
  275. // security review 2/21/2002 BryanWal ok
  276. CopyMemory(pGuid, rgGuids.GetData(), cb);
  277. pObject->SetMultiSelData((BYTE*)pGuid, cb);
  278. for (int i=0; i < rgCookiesSelected.GetSize(); ++i)
  279. {
  280. pObject->AddCookie(rgCookiesSelected[i]);
  281. }
  282. hr = pObject->QueryInterface(
  283. IID_PPV_ARG (IDataObject, ppDataObject));
  284. }
  285. else
  286. hr = E_OUTOFMEMORY;
  287. }
  288. else
  289. hr = E_FAIL;
  290. }
  291. }
  292. return hr;
  293. }
  294. //+--------------------------------------------------------------------------
  295. //
  296. // Member: CDataObject::Create
  297. //
  298. // Synopsis: Fill the hGlobal in [lpmedium] with the data in pBuffer
  299. //
  300. // Arguments: [pBuffer] - [in] the data to be written
  301. // [len] - [in] the length of that data
  302. // [pMedium] - [in,out] where to store the data
  303. // History:
  304. //
  305. //---------------------------------------------------------------------------
  306. HRESULT CCertTemplatesDataObject::Create (const void* pBuffer, int len, LPSTGMEDIUM pMedium)
  307. {
  308. HRESULT hr = DV_E_TYMED;
  309. //
  310. // Do some simple validation
  311. //
  312. if (pBuffer == NULL || pMedium == NULL)
  313. return E_POINTER;
  314. //
  315. // Make sure the type medium is HGLOBAL
  316. //
  317. if (pMedium->tymed == TYMED_HGLOBAL) {
  318. //
  319. // Create the stream on the hGlobal passed in
  320. //
  321. LPSTREAM lpStream = 0;
  322. hr = CreateStreamOnHGlobal(pMedium->hGlobal, FALSE, &lpStream);
  323. ASSERT (SUCCEEDED (hr));
  324. if (SUCCEEDED(hr))
  325. {
  326. //
  327. // Write to the stream the number of bytes
  328. //
  329. ULONG written = 0;
  330. hr = lpStream->Write(pBuffer, len, &written);
  331. ASSERT (SUCCEEDED (hr));
  332. //
  333. // Because we told CreateStreamOnHGlobal with 'FALSE',
  334. // only the stream is released here.
  335. // Note - the caller (i.e. snap-in, object) will free the HGLOBAL
  336. // at the correct time. This is according to the IDataObject specification.
  337. //
  338. lpStream->Release();
  339. }
  340. }
  341. return hr;
  342. }
  343. //+----------------------------------------------------------------------------
  344. //
  345. // Method: CCertTemplatesDataObject::CreateMultiSelectObject
  346. //
  347. // Synopsis: this is to create the list of types selected
  348. //
  349. //-----------------------------------------------------------------------------
  350. HRESULT CCertTemplatesDataObject::CreateMultiSelectObject(LPSTGMEDIUM pMedium)
  351. {
  352. ASSERT(m_pbMultiSelData != 0);
  353. ASSERT(m_cbMultiSelData != 0);
  354. pMedium->tymed = TYMED_HGLOBAL;
  355. pMedium->hGlobal = ::GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE,
  356. (m_cbMultiSelData + sizeof(DWORD)));
  357. if (pMedium->hGlobal == NULL)
  358. return STG_E_MEDIUMFULL;
  359. BYTE* pb = reinterpret_cast<BYTE*>(::GlobalLock(pMedium->hGlobal));
  360. *((DWORD*)pb) = m_cbMultiSelData / sizeof(GUID);
  361. pb += sizeof(DWORD);
  362. // security review 2/21/2002 BryanWal ok
  363. CopyMemory(pb, m_pbMultiSelData, m_cbMultiSelData);
  364. ::GlobalUnlock(pMedium->hGlobal);
  365. return S_OK;
  366. }
  367. LPDATAOBJECT ExtractMultiSelect (LPDATAOBJECT lpDataObject)
  368. {
  369. if (lpDataObject == NULL)
  370. return NULL;
  371. SMMCDataObjects * pDO = NULL;
  372. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  373. FORMATETC formatetc = { CCertTemplatesDataObject::m_CFMultiSelDataObjs, NULL,
  374. DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  375. if ( FAILED (lpDataObject->GetData (&formatetc, &stgmedium)) )
  376. {
  377. return NULL;
  378. }
  379. else
  380. {
  381. pDO = reinterpret_cast<SMMCDataObjects*>(stgmedium.hGlobal);
  382. return pDO->lpDataObject[0]; //assume that ours is the 1st
  383. }
  384. }
  385. STDMETHODIMP CCertTemplatesDataObject::GetData(LPFORMATETC lpFormatetc, LPSTGMEDIUM pMedium)
  386. {
  387. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  388. HRESULT hr = DV_E_CLIPFORMAT;
  389. if (lpFormatetc->cfFormat == m_CFMultiSel)
  390. {
  391. ASSERT(((CCertTmplCookie*) MMC_MULTI_SELECT_COOKIE) == m_pCookie);
  392. if ( ((CCertTmplCookie*) MMC_MULTI_SELECT_COOKIE) != m_pCookie )
  393. return E_FAIL;
  394. hr = CreateMultiSelectObject (pMedium);
  395. }
  396. else if ( lpFormatetc->cfFormat == m_CFDsObjectNames )
  397. {
  398. switch (m_pCookie->m_objecttype)
  399. {
  400. case CERTTMPL_CERT_TEMPLATE:
  401. {
  402. CCertTemplate* pCertTemplate = dynamic_cast <CCertTemplate*> (m_pCookie);
  403. ASSERT (pCertTemplate);
  404. if ( pCertTemplate )
  405. {
  406. // figure out how much storage we need
  407. CString adsiPath;
  408. adsiPath = pCertTemplate->GetLDAPPath ();
  409. int cbPath = sizeof (WCHAR) * (adsiPath.GetLength() + 1);
  410. int cbClass = sizeof (WCHAR) * (pCertTemplate->GetClass ().GetLength() + 1);;
  411. int cbStruct = sizeof(DSOBJECTNAMES); //contains already a DSOBJECT embedded struct
  412. LPDSOBJECTNAMES pDSObj = 0;
  413. pDSObj = (LPDSOBJECTNAMES)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  414. cbStruct + cbPath + cbClass);
  415. if ( pDSObj )
  416. {
  417. // write the info
  418. pDSObj->clsidNamespace = CLSID_CertTemplatesSnapin;
  419. pDSObj->cItems = 1;
  420. pDSObj->aObjects[0].dwFlags = 0;
  421. pDSObj->aObjects[0].dwProviderFlags = 0;
  422. pDSObj->aObjects[0].offsetName = cbStruct;
  423. pDSObj->aObjects[0].offsetClass = cbStruct + cbPath;
  424. // security review 2/21/2002 BryanWal ok
  425. wcsncpy((LPWSTR)((BYTE *)pDSObj + (pDSObj->aObjects[0].offsetName)),
  426. (LPCWSTR) adsiPath, cbPath);
  427. // security review 2/21/2002 BryanWal ok
  428. wcsncpy((LPWSTR)((BYTE *)pDSObj + (pDSObj->aObjects[0].offsetClass)),
  429. (LPCWSTR) pCertTemplate->GetClass (), cbClass);
  430. pMedium->hGlobal = (HGLOBAL)pDSObj;
  431. pMedium->tymed = TYMED_HGLOBAL;
  432. pMedium->pUnkForRelease = NULL;
  433. hr = S_OK;
  434. }
  435. else
  436. hr = STG_E_MEDIUMFULL;
  437. }
  438. }
  439. break;
  440. default:
  441. break;
  442. }
  443. }
  444. return hr;
  445. }
  446. STDMETHODIMP CCertTemplatesDataObject::Next(ULONG celt, MMC_COOKIE* rgelt, ULONG *pceltFetched)
  447. {
  448. HRESULT hr = S_OK;
  449. if ((rgelt == NULL) ||
  450. ((celt > 1) && (pceltFetched == NULL)))
  451. {
  452. hr = E_INVALIDARG;
  453. return hr;
  454. }
  455. ULONG celtTemp = (ULONG)(m_rgCookies.GetSize() - m_iCurr);
  456. celtTemp = (celt < celtTemp) ? celt : celtTemp;
  457. if (pceltFetched)
  458. *pceltFetched = celtTemp;
  459. if (celtTemp == 0)
  460. return S_FALSE;
  461. for (ULONG i=0; i < celtTemp; ++i)
  462. {
  463. rgelt[i] = reinterpret_cast<MMC_COOKIE>(m_rgCookies[m_iCurr++]);
  464. }
  465. return (celtTemp < celt) ? S_FALSE : S_OK;
  466. }
  467. STDMETHODIMP CCertTemplatesDataObject::Skip(ULONG celt)
  468. {
  469. ULONG celtTemp = (ULONG)(m_rgCookies.GetSize() - m_iCurr);
  470. celtTemp = (celt < celtTemp) ? celt : celtTemp;
  471. m_iCurr += celtTemp;
  472. return (celtTemp < celt) ? S_FALSE : S_OK;
  473. }
  474. STDMETHODIMP CCertTemplatesDataObject::Reset(void)
  475. {
  476. m_iCurr = 0;
  477. return S_OK;
  478. }