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.

631 lines
16 KiB

  1. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Microsoft Windows, Copyright (C) Microsoft Corporation, 2000.
  3. File: ExtendedProperties.cpp
  4. Content: Implementation of CExtendedProperties.
  5. History: 06-15-2001 dsie created
  6. ------------------------------------------------------------------------------*/
  7. #include "StdAfx.h"
  8. #include "CAPICOM.h"
  9. #include "ExtendedProperties.h"
  10. ////////////////////////////////////////////////////////////////////////////////
  11. //
  12. // Exported functions.
  13. //
  14. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  15. Function : CreateExtendedPropertiesObject
  16. Synopsis : Create and initialize an IExtendedProperties collection object.
  17. Parameter: PCCERT_CONTEXT pCertContext - Pointer to CERT_CONTEXT.
  18. BOOL bReadOnly - TRUE if read only instance, else FALSE.
  19. IExtendedProperties ** ppIExtendedProperties - Pointer to pointer
  20. to IExtendedProperties
  21. to receive the
  22. interface pointer.
  23. Remark :
  24. ------------------------------------------------------------------------------*/
  25. HRESULT CreateExtendedPropertiesObject (PCCERT_CONTEXT pCertContext,
  26. BOOL bReadOnly,
  27. IExtendedProperties ** ppIExtendedProperties)
  28. {
  29. HRESULT hr = S_OK;
  30. CComObject<CExtendedProperties> * pCExtendedProperties = NULL;
  31. DebugTrace("Entering CreateExtendedPropertiesObject().\n");
  32. //
  33. // Sanity check.
  34. //
  35. ATLASSERT(pCertContext);
  36. ATLASSERT(ppIExtendedProperties);
  37. try
  38. {
  39. //
  40. // Create the object. Note that the ref count will still be 0
  41. // after the object is created.
  42. //
  43. if (FAILED(hr = CComObject<CExtendedProperties>::CreateInstance(&pCExtendedProperties)))
  44. {
  45. DebugTrace("Error [%#x]: CComObject<CExtendedProperties>::CreateInstance() failed.\n", hr);
  46. goto ErrorExit;
  47. }
  48. if (FAILED(hr = pCExtendedProperties->Init(pCertContext, bReadOnly)))
  49. {
  50. DebugTrace("Error [%#x]: pCExtendedProperties->Init() failed.\n", hr);
  51. goto ErrorExit;
  52. }
  53. //
  54. // Return IExtendedProperties pointer to caller.
  55. //
  56. if (FAILED(hr = pCExtendedProperties->QueryInterface(ppIExtendedProperties)))
  57. {
  58. DebugTrace("Error [%#x]: pCExtendedProperties->QueryInterface() failed.\n", hr);
  59. goto ErrorExit;
  60. }
  61. }
  62. catch(...)
  63. {
  64. hr = E_POINTER;
  65. DebugTrace("Exception: invalid parameter.\n");
  66. goto ErrorExit;
  67. }
  68. CommonExit:
  69. DebugTrace("Leaving CreateExtendedPropertiesObject().\n");
  70. return hr;
  71. ErrorExit:
  72. //
  73. // Sanity check.
  74. //
  75. ATLASSERT(FAILED(hr));
  76. //
  77. // Free resource.
  78. //
  79. if (pCExtendedProperties)
  80. {
  81. delete pCExtendedProperties;
  82. }
  83. goto CommonExit;
  84. }
  85. ////////////////////////////////////////////////////////////////////////////////
  86. //
  87. // CExtendedProperties
  88. //
  89. #if (0)
  90. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  91. Function : CExtendedProperties::get_Item
  92. Synopsis : Return item in the collection.
  93. Parameter: long Index - Numeric index.
  94. VARIANT * pVal - Pointer to VARIANT to receive the IDispatch.
  95. Remark :
  96. ------------------------------------------------------------------------------*/
  97. STDMETHODIMP CExtendedProperties::get_Item (long Index, VARIANT * pVal)
  98. {
  99. HRESULT hr = S_OK;
  100. char szIndex[33];
  101. CComBSTR bstrIndex;
  102. CComPtr<IExtendedProperty> pIExtendedProperty = NULL;
  103. DebugTrace("Entering CExtendedProperties::get_Item().\n");
  104. try
  105. {
  106. //
  107. // Lock access to this object.
  108. //
  109. m_Lock.Lock();
  110. //
  111. // Check parameters.
  112. //
  113. if (NULL == pVal)
  114. {
  115. hr = E_INVALIDARG;
  116. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  117. goto ErrorExit;
  118. }
  119. //
  120. // Intialize.
  121. //
  122. ::VariantInit(pVal);
  123. //
  124. // BSTR index of prop ID.
  125. //
  126. wsprintfA(szIndex, "%#08x", Index);
  127. if (!(bstrIndex = szIndex))
  128. {
  129. hr = E_OUTOFMEMORY;
  130. DebugTrace("Error [%#x]: bstrIndex = szIndex failed.\n", hr);
  131. goto ErrorExit;
  132. }
  133. //
  134. // Index by PropID string.
  135. //
  136. ExtendedPropertyMap::iterator it;
  137. //
  138. // Find the item with this PropID.
  139. //
  140. it = m_coll.find(bstrIndex);
  141. if (it == m_coll.end())
  142. {
  143. DebugTrace("Info: PropID (%d) not found in the collection.\n", Index);
  144. goto CommonExit;
  145. }
  146. //
  147. // Point to found item.
  148. //
  149. pIExtendedProperty = (*it).second;
  150. //
  151. // Return to caller.
  152. //
  153. pVal->vt = VT_DISPATCH;
  154. if (FAILED(hr = pIExtendedProperty->QueryInterface(IID_IDispatch, (void **) &(pVal->pdispVal))))
  155. {
  156. DebugTrace("Error [%#x]: pIExtendedProperty->QueryInterface() failed.\n", hr);
  157. goto ErrorExit;
  158. }
  159. }
  160. catch(...)
  161. {
  162. hr = CAPICOM_E_INTERNAL;
  163. DebugTrace("Exception: internal error.\n");
  164. goto ErrorExit;
  165. }
  166. CommonExit:
  167. //
  168. // Unlock access to this object.
  169. //
  170. m_Lock.Unlock();
  171. DebugTrace("Leaving CExtendedProperties::get_Item().\n");
  172. return hr;
  173. ErrorExit:
  174. //
  175. // Sanity check.
  176. //
  177. ATLASSERT(FAILED(hr));
  178. ReportError(hr);
  179. goto CommonExit;
  180. }
  181. #endif
  182. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  183. Function : CExtendedProperties::Add
  184. Synopsis : Add a ExtendedProperty to the collection.
  185. Parameter: IExtendedProperty * pVal - ExtendedProperty to be added.
  186. Remark :
  187. ------------------------------------------------------------------------------*/
  188. STDMETHODIMP CExtendedProperties::Add (IExtendedProperty * pVal)
  189. {
  190. HRESULT hr = S_OK;
  191. char szIndex[33];
  192. CComBSTR bstrIndex;
  193. CComBSTR bstrProperty;
  194. CAPICOM_PROPID PropId;
  195. CComPtr<IExtendedProperty> pIExtendedProperty = NULL;
  196. DebugTrace("Entering CExtendedProperties::Add().\n");
  197. try
  198. {
  199. //
  200. // Lock access to this object.
  201. //
  202. m_Lock.Lock();
  203. //
  204. // Do not allowed if called from WEB script.
  205. //
  206. if (m_bReadOnly)
  207. {
  208. hr = CAPICOM_E_NOT_ALLOWED;
  209. DebugTrace("Error [%#x]: Adding extended property from WEB script is not allowed.\n", hr);
  210. goto ErrorExit;
  211. }
  212. //
  213. // Check parameters.
  214. //
  215. if (NULL == pVal)
  216. {
  217. hr = E_INVALIDARG;
  218. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  219. goto ErrorExit;
  220. }
  221. //
  222. // Sanity check.
  223. //
  224. ATLASSERT(m_pCertContext);
  225. //
  226. // Create a new object for this property.
  227. //
  228. if (FAILED(hr = pVal->get_PropID(&PropId)))
  229. {
  230. DebugTrace("Error [%#x]: pVal->get_PropID() failed.\n", hr);
  231. goto ErrorExit;
  232. }
  233. if (FAILED(hr = ::CreateExtendedPropertyObject(m_pCertContext,
  234. (DWORD) PropId,
  235. FALSE,
  236. &pIExtendedProperty)))
  237. {
  238. DebugTrace("Error [%#x]: CreateExtendedPropertyObject() failed.\n", hr);
  239. goto ErrorExit;
  240. }
  241. //
  242. // Put value (will write thru).
  243. //
  244. if (FAILED(hr = pVal->get_Value(CAPICOM_ENCODE_BINARY, &bstrProperty)))
  245. {
  246. DebugTrace("Error [%#x]: pVal->get_Value() failed.\n", hr);
  247. goto ErrorExit;
  248. }
  249. if (FAILED(hr = pIExtendedProperty->put_Value(CAPICOM_ENCODE_BINARY, bstrProperty)))
  250. {
  251. DebugTrace("Error [%#x]: pIExtendedProperty->put_Value() failed.\n", hr);
  252. goto ErrorExit;
  253. }
  254. //
  255. // BSTR index of prop ID.
  256. //
  257. wsprintfA(szIndex, "%#08x", PropId);
  258. if (!(bstrIndex = szIndex))
  259. {
  260. hr = E_OUTOFMEMORY;
  261. DebugTrace("Error [%#x]: bstrIndex = szIndex failed.\n", hr);
  262. goto ErrorExit;
  263. }
  264. //
  265. // Now add object to collection map.
  266. //
  267. // Note that the overloaded = operator for CComPtr will
  268. // automatically AddRef to the object. Also, when the CComPtr
  269. // is deleted (happens when the Remove or map destructor is called),
  270. // the CComPtr destructor will automatically Release the object.
  271. //
  272. m_coll[bstrIndex] = pIExtendedProperty;
  273. }
  274. catch(...)
  275. {
  276. hr = E_POINTER;
  277. DebugTrace("Exception: invalid parameter.\n");
  278. goto ErrorExit;
  279. }
  280. UnlockExit:
  281. //
  282. // Unlock access to this object.
  283. //
  284. m_Lock.Unlock();
  285. DebugTrace("Leaving CExtendedProperties::Add().\n");
  286. return hr;
  287. ErrorExit:
  288. //
  289. // Sanity check.
  290. //
  291. ATLASSERT(FAILED(hr));
  292. ReportError(hr);
  293. goto UnlockExit;
  294. }
  295. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  296. Function : CExtendedProperties::Remove
  297. Synopsis : Remove a ExtendedProperty from the collection.
  298. Parameter: CAPICOM_PROPID PropId - Property ID.
  299. Remark :
  300. ------------------------------------------------------------------------------*/
  301. STDMETHODIMP CExtendedProperties::Remove (CAPICOM_PROPID PropId)
  302. {
  303. HRESULT hr = S_OK;
  304. char szIndex[33];
  305. CComBSTR bstrIndex;
  306. CComPtr<IExtendedProperty> pIExtendedProperty = NULL;
  307. ExtendedPropertyMap::iterator iter;
  308. DebugTrace("Entering CExtendedProperties::Remove().\n");
  309. try
  310. {
  311. //
  312. // Lock access to this object.
  313. //
  314. m_Lock.Lock();
  315. //
  316. // Do not allowed if called from WEB script.
  317. //
  318. if (m_bReadOnly)
  319. {
  320. hr = CAPICOM_E_NOT_ALLOWED;
  321. DebugTrace("Error [%#x]: Removing extended property from WEB script is not allowed.\n", hr);
  322. goto ErrorExit;
  323. }
  324. //
  325. // Sanity check.
  326. //
  327. ATLASSERT(m_pCertContext);
  328. //
  329. // BSTR index of prop ID.
  330. //
  331. wsprintfA(szIndex, "%#08x", PropId);
  332. if (!(bstrIndex = szIndex))
  333. {
  334. hr = E_OUTOFMEMORY;
  335. DebugTrace("Error [%#x]: bstrIndex = szIndex failed.\n", hr);
  336. goto ErrorExit;
  337. }
  338. //
  339. // Find the item in the map.
  340. //
  341. if (m_coll.end() == (iter = m_coll.find(bstrIndex)))
  342. {
  343. hr = HRESULT_FROM_WIN32(CRYPT_E_NOT_FOUND);
  344. DebugTrace("Error [%#x]: Prod ID (%u) does not exist.\n", hr, PropId);
  345. goto ErrorExit;
  346. }
  347. //
  348. // Remove from the cert.
  349. //
  350. if (!::CertSetCertificateContextProperty(m_pCertContext,
  351. (DWORD) PropId,
  352. 0,
  353. NULL))
  354. {
  355. hr = HRESULT_FROM_WIN32(::GetLastError());
  356. DebugTrace("Error [%#x]: CertSetCertificateContextProperty() failed.\n", hr);
  357. goto ErrorExit;
  358. }
  359. //
  360. // Now remove object in map.
  361. //
  362. m_coll.erase(iter);
  363. }
  364. catch(...)
  365. {
  366. hr = E_POINTER;
  367. DebugTrace("Exception: invalid parameter.\n");
  368. goto ErrorExit;
  369. }
  370. UnlockExit:
  371. //
  372. // Unlock access to this object.
  373. //
  374. m_Lock.Unlock();
  375. DebugTrace("Leaving CExtendedProperties::Remove().\n");
  376. return hr;
  377. ErrorExit:
  378. //
  379. // Sanity check.
  380. //
  381. ATLASSERT(FAILED(hr));
  382. ReportError(hr);
  383. goto UnlockExit;
  384. }
  385. ////////////////////////////////////////////////////////////////////////////////
  386. //
  387. // Non COM functions.
  388. //
  389. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  390. Function : CExtendedProperties::Init
  391. Synopsis : Initialize the collection object by adding all individual
  392. ExtendedProperty object to the collection.
  393. Parameter: PCCERT_CONTEXT pCertContext - Pointer to CERT_CONTEXT.
  394. BOOL bReadOnly - TRUE if read only instance, else FALSE.
  395. Remark : This method is not part of the COM interface (it is a normal C++
  396. member function). We need it to initialize the object created
  397. internally by us.
  398. Since it is only a normal C++ member function, this function can
  399. only be called from a C++ class pointer, not an interface pointer.
  400. ------------------------------------------------------------------------------*/
  401. STDMETHODIMP CExtendedProperties::Init (PCCERT_CONTEXT pCertContext,
  402. BOOL bReadOnly)
  403. {
  404. HRESULT hr = S_OK;
  405. DWORD dwPropId = 0;
  406. DebugTrace("Entering CExtendedProperties::Init().\n");
  407. //
  408. // Sanity check.
  409. //
  410. ATLASSERT(pCertContext);
  411. try
  412. {
  413. //
  414. // Duplicate the handle.
  415. //
  416. if (!(m_pCertContext = ::CertDuplicateCertificateContext(pCertContext)))
  417. {
  418. hr = HRESULT_FROM_WIN32(::GetLastError());
  419. DebugTrace("Error [%#x]: CertDuplicateCertificateContext() failed.\n", hr);
  420. goto ErrorExit;
  421. }
  422. //
  423. // Add all proerties to the map.
  424. //
  425. while (dwPropId = ::CertEnumCertificateContextProperties(pCertContext, dwPropId))
  426. {
  427. char szIndex[33];
  428. CComBSTR bstrIndex;
  429. CComPtr<IExtendedProperty> pIExtendedProperty = NULL;
  430. if (FAILED(hr = ::CreateExtendedPropertyObject(pCertContext,
  431. dwPropId,
  432. bReadOnly,
  433. &pIExtendedProperty)))
  434. {
  435. DebugTrace("Error [%#x]: CreateExtendedPropertyObject() failed.\n", hr);
  436. goto ErrorExit;
  437. }
  438. //
  439. // BSTR index of prop ID.
  440. //
  441. wsprintfA(szIndex, "%#08x", dwPropId);
  442. if (!(bstrIndex = szIndex))
  443. {
  444. hr = E_OUTOFMEMORY;
  445. DebugTrace("Error [%#x]: bstrIndex = szIndex failed.\n", hr);
  446. goto ErrorExit;
  447. }
  448. //
  449. // Now add object to collection map.
  450. //
  451. // Note that the overloaded = operator for CComPtr will
  452. // automatically AddRef to the object. Also, when the CComPtr
  453. // is deleted (happens when the Remove or map destructor is called),
  454. // the CComPtr destructor will automatically Release the object.
  455. //
  456. m_coll[bstrIndex] = pIExtendedProperty;
  457. }
  458. m_bReadOnly = bReadOnly;
  459. }
  460. catch(...)
  461. {
  462. hr = E_POINTER;
  463. DebugTrace("Exception: invalid parameter.\n");
  464. goto ErrorExit;
  465. }
  466. CommonExit:
  467. DebugTrace("Leaving CExtendedProperties::Init().\n");
  468. return hr;
  469. ErrorExit:
  470. //
  471. // Sanity check.
  472. //
  473. ATLASSERT(FAILED(hr));
  474. //
  475. // Free resource.
  476. //
  477. m_coll.clear();
  478. if (m_pCertContext)
  479. {
  480. ::CertFreeCertificateContext(m_pCertContext);
  481. m_pCertContext = NULL;
  482. }
  483. goto CommonExit;
  484. }