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.

594 lines
17 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. #define __dwFILE__ __dwFILE_CERTMMC_DATAOBJ_CPP__
  10. #ifdef _DEBUG
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14. ///////////////////////////////////////////////////////////////////////////////
  15. // Sample code to show how to Create DataObjects
  16. // Minimal error checking for clarity
  17. ///////////////////////////////////////////////////////////////////////////////
  18. // Snap-in NodeType in both GUID format and string format
  19. // Note - Typically there is a node type for each different object, sample
  20. // only uses one node type.
  21. unsigned int CDataObject::m_cfNodeType = 0;
  22. unsigned int CDataObject::m_cfNodeID = 0;
  23. unsigned int CDataObject::m_cfCoClass = 0;
  24. unsigned int CDataObject::m_cfNodeTypeString = 0;
  25. unsigned int CDataObject::m_cfDisplayName = 0;
  26. unsigned int CDataObject::m_cfInternal = 0;
  27. unsigned int CDataObject::m_cfObjInMultiSel = 0;
  28. unsigned int CDataObject::m_cfIsMultiSel = 0;
  29. unsigned int CDataObject::m_cfPreloads = 0;
  30. // The only additional clipboard format supported is to get the workstation name.
  31. unsigned int CDataObject::m_cfSelectedCA_InstallType = 0;
  32. unsigned int CDataObject::m_cfSelectedCA_CommonName = 0;
  33. unsigned int CDataObject::m_cfSelectedCA_SanitizedName= 0;
  34. unsigned int CDataObject::m_cfSelectedCA_MachineName = 0;
  35. unsigned int CDataObject::m_cfSelectedCA_Roles = 0;
  36. /////////////////////////////////////////////////////////////////////////////
  37. // CDataObject implementations
  38. CDataObject::CDataObject()
  39. {
  40. USES_CONVERSION;
  41. m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
  42. m_cfNodeID = RegisterClipboardFormat(CCF_COLUMN_SET_ID);
  43. m_cfCoClass = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
  44. m_cfNodeTypeString = RegisterClipboardFormat(CCF_SZNODETYPE);
  45. m_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
  46. m_cfInternal = RegisterClipboardFormat(SNAPIN_INTERNAL);
  47. m_cfObjInMultiSel = RegisterClipboardFormat(CCF_OBJECT_TYPES_IN_MULTI_SELECT);
  48. m_cfIsMultiSel = RegisterClipboardFormat(CCF_MMC_MULTISELECT_DATAOBJECT);
  49. m_cfPreloads = RegisterClipboardFormat(CCF_SNAPIN_PRELOADS);
  50. m_cfSelectedCA_InstallType = RegisterClipboardFormat(SNAPIN_CA_INSTALL_TYPE);
  51. m_cfSelectedCA_CommonName = RegisterClipboardFormat(SNAPIN_CA_COMMON_NAME);
  52. m_cfSelectedCA_MachineName = RegisterClipboardFormat(SNAPIN_CA_MACHINE_NAME);
  53. m_cfSelectedCA_SanitizedName = RegisterClipboardFormat(SNAPIN_CA_SANITIZED_NAME);
  54. m_cfSelectedCA_Roles = RegisterClipboardFormat(SNAPIN_CA_ROLES);
  55. m_pComponentData = NULL;
  56. #ifdef _DEBUG
  57. dbg_refCount = 0;
  58. #endif
  59. m_cbMultiSelData = 0;
  60. m_bMultiSelDobj = FALSE;
  61. m_dwViewID = MAXDWORD;
  62. }
  63. STDMETHODIMP CDataObject::QueryGetData(LPFORMATETC lpFormatetc)
  64. {
  65. HRESULT hr = S_FALSE;
  66. if ( lpFormatetc )
  67. {
  68. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  69. if ( cf == m_cfIsMultiSel )
  70. {
  71. hr = S_FALSE; // always return this; MMC returns S_OK if ptr to SI_MS_DO
  72. // hr = (m_bMultiSelDobj ? S_OK : S_FALSE);
  73. }
  74. else if ( cf == m_cfNodeType ||
  75. cf == m_cfNodeID ||
  76. cf == m_cfCoClass ||
  77. cf == m_cfNodeTypeString ||
  78. cf == m_cfDisplayName ||
  79. cf == m_cfObjInMultiSel ||
  80. cf == m_cfInternal ||
  81. cf == m_cfPreloads ||
  82. cf == m_cfSelectedCA_SanitizedName ||
  83. cf == m_cfSelectedCA_MachineName ||
  84. cf == m_cfSelectedCA_CommonName ||
  85. cf == m_cfSelectedCA_InstallType
  86. )
  87. {
  88. hr = S_OK;
  89. }
  90. }
  91. return hr;
  92. }
  93. STDMETHODIMP CDataObject::GetData(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
  94. {
  95. HRESULT hr = DV_E_CLIPFORMAT;
  96. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  97. if (cf == m_cfObjInMultiSel)
  98. {
  99. hr = CreateObjInMultiSel(lpMedium);
  100. }
  101. else if (cf == m_cfNodeID)
  102. {
  103. hr = CreateNodeIDData(lpMedium);
  104. }
  105. return hr;
  106. }
  107. STDMETHODIMP CDataObject::GetDataHere(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
  108. {
  109. HRESULT hr = DV_E_CLIPFORMAT;
  110. // Based on the CLIPFORMAT write data to the stream
  111. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  112. if (cf == m_cfNodeType)
  113. {
  114. hr = CreateNodeTypeData(lpMedium);
  115. }
  116. else if (cf == m_cfCoClass)
  117. {
  118. hr = CreateCoClassID(lpMedium);
  119. }
  120. else if(cf == m_cfNodeTypeString)
  121. {
  122. hr = CreateNodeTypeStringData(lpMedium);
  123. }
  124. else if (cf == m_cfDisplayName)
  125. {
  126. hr = CreateDisplayName(lpMedium);
  127. }
  128. else if (cf == m_cfInternal)
  129. {
  130. hr = CreateInternal(lpMedium);
  131. }
  132. else if (cf == m_cfPreloads)
  133. {
  134. hr = CreatePreloadsData(lpMedium);
  135. }
  136. else if (cf == m_cfSelectedCA_CommonName)
  137. {
  138. hr = CreateSelectedCA_CommonName(lpMedium);
  139. }
  140. else if (cf == m_cfSelectedCA_SanitizedName)
  141. {
  142. hr = CreateSelectedCA_SanitizedName(lpMedium);
  143. }
  144. else if (cf == m_cfSelectedCA_MachineName)
  145. {
  146. hr = CreateSelectedCA_MachineName(lpMedium);
  147. }
  148. else if (cf == m_cfSelectedCA_InstallType)
  149. {
  150. hr = CreateSelectedCA_InstallType(lpMedium);
  151. }
  152. else if (cf == m_cfSelectedCA_Roles)
  153. {
  154. hr = CreateSelectedCA_Roles(lpMedium);
  155. }
  156. return hr;
  157. }
  158. STDMETHODIMP
  159. CDataObject::EnumFormatEtc(
  160. DWORD, // dwDirection
  161. LPENUMFORMATETC * /* ppEnumFormatEtc */ )
  162. {
  163. return E_NOTIMPL;
  164. }
  165. /////////////////////////////////////////////////////////////////////////////
  166. // CDataObject creation members
  167. HRESULT CDataObject::Create(const void* pBuffer, int len, LPSTGMEDIUM lpMedium)
  168. {
  169. HRESULT hr = DV_E_TYMED;
  170. // Do some simple validation
  171. if (pBuffer == NULL || lpMedium == NULL)
  172. return E_POINTER;
  173. // Make sure the type medium is HGLOBAL
  174. if (lpMedium->tymed == TYMED_HGLOBAL)
  175. {
  176. // Create the stream on the hGlobal passed in
  177. LPSTREAM lpStream;
  178. hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &lpStream);
  179. if (SUCCEEDED(hr))
  180. {
  181. ULONG written;
  182. if (NULL == lpMedium->hGlobal)
  183. {
  184. // always return a valid hGlobal for the caller
  185. hr = GetHGlobalFromStream(lpStream, &lpMedium->hGlobal);
  186. if (hr != S_OK)
  187. goto err;
  188. }
  189. // Write to the stream the number of bytes
  190. hr = lpStream->Write(pBuffer, len, &written);
  191. // Because we told CreateStreamOnHGlobal with 'FALSE',
  192. // only the stream is released here.
  193. // Note - the caller (i.e. snap-in, object) will free the HGLOBAL
  194. // at the correct time. This is according to the IDataObject specification.
  195. lpStream->Release();
  196. }
  197. }
  198. err:
  199. return hr;
  200. }
  201. HRESULT CDataObject::CreateVariableLen(const void* pBuffer, int len, LPSTGMEDIUM lpMedium)
  202. {
  203. HRESULT hr = DV_E_TYMED;
  204. BYTE* pb;
  205. // Do some simple validation
  206. if (pBuffer == NULL || lpMedium == NULL)
  207. {
  208. hr = E_POINTER;
  209. _JumpError(hr, Ret, "Invalid args");
  210. }
  211. // Make sure the type medium is HGLOBAL
  212. lpMedium->tymed = TYMED_HGLOBAL;
  213. lpMedium->hGlobal = ::GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE, (len));
  214. _JumpIfOutOfMemory(hr, Ret, lpMedium->hGlobal);
  215. pb = reinterpret_cast<BYTE*>(::GlobalLock(lpMedium->hGlobal));
  216. CopyMemory(pb, pBuffer, len);
  217. ::GlobalUnlock(lpMedium->hGlobal);
  218. hr = S_OK;
  219. Ret:
  220. return hr;
  221. }
  222. const GUID* FolderTypeToNodeGUID(DATA_OBJECT_TYPES type, CFolder* pFolder)
  223. {
  224. const GUID* pcObjectType = NULL;
  225. if (pFolder == NULL)
  226. {
  227. pcObjectType = &cNodeTypeMachineInstance;
  228. }
  229. else if (type == CCT_SCOPE)
  230. {
  231. switch (pFolder->GetType())
  232. {
  233. case SERVER_INSTANCE:
  234. pcObjectType = &cNodeTypeServerInstance;
  235. break;
  236. case SERVERFUNC_CRL_PUBLICATION:
  237. pcObjectType = &cNodeTypeCRLPublication;
  238. break;
  239. case SERVERFUNC_ISSUED_CERTIFICATES:
  240. pcObjectType = &cNodeTypeIssuedCerts;
  241. break;
  242. case SERVERFUNC_PENDING_CERTIFICATES:
  243. pcObjectType = &cNodeTypePendingCerts;
  244. break;
  245. case SERVERFUNC_FAILED_CERTIFICATES:
  246. pcObjectType = &cNodeTypeFailedCerts;
  247. break;
  248. case SERVERFUNC_ALIEN_CERTIFICATES:
  249. pcObjectType = &cNodeTypeAlienCerts;
  250. break;
  251. case SERVERFUNC_ISSUED_CRLS:
  252. pcObjectType = &cNodeTypeIssuedCRLs;
  253. break;
  254. default:
  255. ASSERT(0);
  256. pcObjectType = &cNodeTypeDynamic;
  257. break;
  258. }
  259. }
  260. else if (type == CCT_RESULT)
  261. {
  262. // RESULT_DATA* pData = reinterpret_cast<RESULT_DATA*>(m_internal.m_cookie);
  263. pcObjectType = &cObjectTypeResultItem;
  264. }
  265. else
  266. {
  267. ASSERT(0);
  268. }
  269. return pcObjectType;
  270. }
  271. HRESULT CDataObject::CreateNodeIDData(LPSTGMEDIUM lpMedium)
  272. {
  273. // Create the node type object in GUID format
  274. const GUID* pFolderGuid = NULL;
  275. PBYTE pbWritePtr;
  276. // Instance guid, node guid, dwViewIndex
  277. #define CDO_CNID_SIZE ( (2*sizeof(GUID))+ sizeof(DWORD) + FIELD_OFFSET(SNodeID2, id) )
  278. BYTE bSNodeID2[CDO_CNID_SIZE];
  279. ZeroMemory(bSNodeID2, CDO_CNID_SIZE);
  280. SNodeID2* psColID = (SNodeID2*)bSNodeID2;
  281. pFolderGuid = FolderTypeToNodeGUID(m_internal.m_type, reinterpret_cast<CFolder*>(m_internal.m_cookie));
  282. if (pFolderGuid == NULL)
  283. return E_FAIL;
  284. if (m_pComponentData == NULL)
  285. return E_FAIL;
  286. // node ID is {GUIDInstance|GUIDNode}
  287. psColID->cBytes = 2*sizeof(GUID) + sizeof(DWORD);
  288. pbWritePtr = psColID->id;
  289. CopyMemory(pbWritePtr, &m_pComponentData->m_guidInstance, sizeof(GUID));
  290. pbWritePtr += sizeof(GUID);
  291. CopyMemory(pbWritePtr, pFolderGuid, sizeof(GUID));
  292. pbWritePtr += sizeof(GUID);
  293. // ASSERT(m_dwViewID != -1);
  294. // UNDONE UNDONE: MMC will soon call for this data through IComponent, not IComponentData
  295. // this will allow us to set this as we desire
  296. *(DWORD*)pbWritePtr = m_dwViewID;
  297. // copy structure only
  298. return CreateVariableLen(reinterpret_cast<const void*>(psColID), CDO_CNID_SIZE, lpMedium);
  299. }
  300. HRESULT CDataObject::CreateObjInMultiSel(LPSTGMEDIUM lpMedium)
  301. {
  302. HRESULT hr;
  303. ASSERT(m_cbMultiSelData != 0);
  304. ASSERT(m_internal.m_cookie == MMC_MULTI_SELECT_COOKIE);
  305. if (m_internal.m_cookie != MMC_MULTI_SELECT_COOKIE)
  306. return E_FAIL;
  307. // copy guid + len
  308. hr = CreateVariableLen(&m_sGuidObjTypes, m_cbMultiSelData, lpMedium);
  309. //Ret:
  310. return hr;
  311. }
  312. HRESULT CDataObject::CreateNodeTypeData(LPSTGMEDIUM lpMedium)
  313. {
  314. // Create the node type object in GUID format
  315. const GUID* pcObjectType = NULL;
  316. pcObjectType = FolderTypeToNodeGUID(m_internal.m_type, reinterpret_cast<CFolder*>(m_internal.m_cookie));
  317. if (pcObjectType == NULL)
  318. return E_FAIL;
  319. return Create(reinterpret_cast<const void*>(pcObjectType), sizeof(GUID),
  320. lpMedium);
  321. }
  322. HRESULT CDataObject::CreateNodeTypeStringData(LPSTGMEDIUM lpMedium)
  323. {
  324. // Create the node type object in GUID string format
  325. const WCHAR* cszObjectType = NULL;
  326. if (m_internal.m_cookie == NULL)
  327. {
  328. cszObjectType = cszNodeTypeMachineInstance;
  329. }
  330. else if (m_internal.m_type == CCT_SCOPE)
  331. {
  332. CFolder* pFolder = reinterpret_cast<CFolder*>(m_internal.m_cookie);
  333. ASSERT(pFolder != NULL);
  334. if (pFolder == NULL)
  335. return E_UNEXPECTED;
  336. switch (pFolder->GetType())
  337. {
  338. case SERVER_INSTANCE:
  339. cszObjectType = cszNodeTypeServerInstance;
  340. break;
  341. case SERVERFUNC_CRL_PUBLICATION:
  342. cszObjectType = cszNodeTypeCRLPublication;
  343. break;
  344. case SERVERFUNC_ISSUED_CERTIFICATES:
  345. cszObjectType = cszNodeTypeIssuedCerts;
  346. break;
  347. case SERVERFUNC_PENDING_CERTIFICATES:
  348. cszObjectType = cszNodeTypePendingCerts;
  349. break;
  350. case SERVERFUNC_FAILED_CERTIFICATES:
  351. cszObjectType = cszNodeTypeFailedCerts;
  352. break;
  353. default:
  354. ASSERT(0);
  355. cszObjectType = cszNodeTypeDynamic;
  356. break;
  357. }
  358. }
  359. else if (m_internal.m_type == CCT_RESULT)
  360. {
  361. // RESULT_DATA* pData = reinterpret_cast<RESULT_DATA*>(m_internal.m_cookie);
  362. cszObjectType = cszObjectTypeResultItem;
  363. }
  364. else
  365. return E_UNEXPECTED;
  366. return Create(cszObjectType, ((wcslen(cszObjectType)+1) * sizeof(WCHAR)), lpMedium);
  367. }
  368. HRESULT CDataObject::CreateDisplayName(LPSTGMEDIUM lpMedium)
  369. {
  370. // This is the display named used in the scope pane and snap-in manager
  371. // Load the name to display
  372. // Note - if this is not provided, the console will used the snap-in name
  373. CString strFormat, strMachine, strFinished;
  374. strFormat.LoadString(IDS_NODENAME_FORMAT);
  375. if (NULL == m_pComponentData)
  376. return E_POINTER;
  377. if (m_pComponentData->m_pCertMachine->m_strMachineName.IsEmpty())
  378. strMachine.LoadString(IDS_LOCALMACHINE);
  379. else
  380. strMachine = m_pComponentData->m_pCertMachine->m_strMachineName;
  381. strFinished.Format(strFormat, strMachine);
  382. return Create(strFinished, ((strFinished.GetLength()+1)* sizeof(WCHAR)), lpMedium);
  383. }
  384. HRESULT CDataObject::CreateInternal(LPSTGMEDIUM lpMedium)
  385. {
  386. return Create(&m_internal, sizeof(INTERNAL), lpMedium);
  387. }
  388. HRESULT CDataObject::CreateSelectedCA_CommonName(LPSTGMEDIUM lpMedium)
  389. {
  390. CertSvrCA* pCA = NULL;
  391. CFolder* pFolder = GetParentFolder(&m_internal);
  392. ASSERT(pFolder != NULL);
  393. if (pFolder == NULL)
  394. return E_UNEXPECTED;
  395. pCA = pFolder->GetCA();
  396. ASSERT(pCA != NULL);
  397. ASSERT(pCA->m_strCommonName.GetLength() != 0);
  398. // Add 1 for the NULL and calculate the bytes for the stream
  399. return Create(pCA->m_strCommonName, ((pCA->m_strCommonName.GetLength()+1)*sizeof(WCHAR)), lpMedium);
  400. }
  401. HRESULT CDataObject::CreateSelectedCA_SanitizedName(LPSTGMEDIUM lpMedium)
  402. {
  403. CertSvrCA* pCA = NULL;
  404. CFolder* pFolder = GetParentFolder(&m_internal);
  405. ASSERT(pFolder != NULL);
  406. if (pFolder == NULL)
  407. return E_UNEXPECTED;
  408. pCA = pFolder->GetCA();
  409. ASSERT(pCA != NULL);
  410. ASSERT(pCA->m_strSanitizedName.GetLength() != 0);
  411. // Add 1 for the NULL and calculate the bytes for the stream
  412. return Create(pCA->m_strSanitizedName, ((pCA->m_strSanitizedName.GetLength()+1)* sizeof(WCHAR)), lpMedium);
  413. }
  414. HRESULT CDataObject::CreateSelectedCA_MachineName(LPSTGMEDIUM lpMedium)
  415. {
  416. CertSvrCA* pCA = NULL;
  417. CFolder* pFolder = GetParentFolder(&m_internal);
  418. ASSERT(pFolder != NULL);
  419. if (pFolder == NULL)
  420. return E_UNEXPECTED;
  421. pCA = pFolder->GetCA();
  422. ASSERT(pCA != NULL);
  423. // Add 1 for the NULL and calculate the bytes for the stream
  424. return Create(pCA->m_strServer, ((pCA->m_strServer.GetLength()+1)* sizeof(WCHAR)), lpMedium);
  425. }
  426. HRESULT CDataObject::CreateSelectedCA_InstallType(LPSTGMEDIUM lpMedium)
  427. {
  428. CertSvrCA* pCA = NULL;
  429. CFolder* pFolder = GetParentFolder(&m_internal);
  430. ASSERT(pFolder != NULL);
  431. if (pFolder == NULL)
  432. return E_UNEXPECTED;
  433. pCA = pFolder->GetCA();
  434. ASSERT(pCA != NULL);
  435. DWORD adwFlags[2] =
  436. {
  437. (DWORD) pCA->GetCAType(),
  438. (DWORD) pCA->FIsAdvancedServer(),
  439. };
  440. return Create(adwFlags, sizeof(adwFlags), lpMedium);
  441. }
  442. HRESULT CDataObject::CreateSelectedCA_Roles(LPSTGMEDIUM lpMedium)
  443. {
  444. CertSvrCA* pCA = NULL;
  445. CFolder* pFolder = GetParentFolder(&m_internal);
  446. ASSERT(pFolder != NULL);
  447. if (pFolder == NULL)
  448. return E_UNEXPECTED;
  449. pCA = pFolder->GetCA();
  450. ASSERT(pCA != NULL);
  451. DWORD dwRoles = pCA->GetMyRoles();
  452. return Create(&dwRoles, sizeof(dwRoles), lpMedium);
  453. }
  454. HRESULT CDataObject::CreateCoClassID(LPSTGMEDIUM lpMedium)
  455. {
  456. // Create the CoClass information
  457. return Create(reinterpret_cast<const void*>(&m_internal.m_clsid), sizeof(CLSID), lpMedium);
  458. }
  459. HRESULT CDataObject::CreatePreloadsData(LPSTGMEDIUM lpMedium)
  460. {
  461. BOOL bPreload = TRUE;
  462. return Create((LPVOID)&bPreload, sizeof(bPreload), lpMedium);
  463. }