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.

386 lines
8.5 KiB

  1. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Microsoft Windows, Copyright (C) Microsoft Corporation, 2000.
  3. File: Recipients.cpp
  4. Content: Implementation of CRecipients.
  5. History: 11-15-99 dsie created
  6. ------------------------------------------------------------------------------*/
  7. #include "StdAfx.h"
  8. #include "CAPICOM.h"
  9. #include "Recipients.h"
  10. ////////////////////////////////////////////////////////////////////////////////
  11. //
  12. // Exported functions.
  13. //
  14. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  15. Function : CreateRecipientsObject
  16. Synopsis : Create and initialize an IRecipients collection object.
  17. Parameter: IRecipients ** ppIRecipients - Pointer to pointer to IRecipients
  18. to receive the interface pointer.
  19. Remark :
  20. ------------------------------------------------------------------------------*/
  21. HRESULT CreateRecipientsObject (IRecipients ** ppIRecipients)
  22. {
  23. HRESULT hr = S_OK;
  24. CComObject<CRecipients> * pCRecipients = NULL;
  25. DebugTrace("Entering CreateRecipientsObject().\n");
  26. //
  27. // Sanity check.
  28. //
  29. ATLASSERT(NULL != ppIRecipients);
  30. try
  31. {
  32. //
  33. // Create the object. Note that the ref count will still be 0
  34. // after the object is created.
  35. //
  36. if (FAILED(hr = CComObject<CRecipients>::CreateInstance(&pCRecipients)))
  37. {
  38. DebugTrace("Error [%#x]: CComObject<CRecipients>::CreateInstance() failed.\n", hr);
  39. goto ErrorExit;
  40. }
  41. //
  42. // Return IRecipients pointer to caller.
  43. //
  44. if (FAILED(hr = pCRecipients->QueryInterface(ppIRecipients)))
  45. {
  46. DebugTrace("Error [%#x]: pCRecipients->QueryInterface().\n", hr);
  47. goto ErrorExit;
  48. }
  49. }
  50. catch(...)
  51. {
  52. hr = E_POINTER;
  53. DebugTrace("Exception: invalid parameter.\n");
  54. goto ErrorExit;
  55. }
  56. CommonExit:
  57. DebugTrace("Leaving CreateRecipientsObject().\n");
  58. return hr;
  59. ErrorExit:
  60. //
  61. // Sanity check.
  62. //
  63. ATLASSERT(FAILED(hr));
  64. //
  65. // Free resource.
  66. //
  67. if (pCRecipients)
  68. {
  69. delete pCRecipients;
  70. }
  71. goto CommonExit;
  72. }
  73. ////////////////////////////////////////////////////////////////////////////////
  74. //
  75. // CRecipients
  76. //
  77. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  78. Function : CRecipients::Add
  79. Synopsis : Add a recipient to the collection.
  80. Parameter: ICertificate * pVal - Recipient to be added.
  81. Remark :
  82. ------------------------------------------------------------------------------*/
  83. STDMETHODIMP CRecipients::Add (ICertificate * pVal)
  84. {
  85. HRESULT hr = S_OK;
  86. char szIndex[33];
  87. CComBSTR bstrIndex;
  88. PCCERT_CONTEXT pCertContext = NULL;
  89. DebugTrace("Entering CRecipients::Add().\n");
  90. try
  91. {
  92. //
  93. // Lock access to this object.
  94. //
  95. m_Lock.Lock();
  96. //
  97. // Check parameters.
  98. //
  99. if (NULL == pVal)
  100. {
  101. hr = E_INVALIDARG;
  102. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  103. goto ErrorExit;
  104. }
  105. //
  106. // Make sure we have a valid cert by getting the CERT_CONTEXT.
  107. //
  108. if (FAILED(hr = ::GetCertContext(pVal, &pCertContext)))
  109. {
  110. DebugTrace("Error [%#x]: GetCertContext() failed.\n", hr);
  111. goto ErrorExit;
  112. }
  113. //
  114. // Free the CERT_CONTEXT.
  115. //
  116. if (!::CertFreeCertificateContext(pCertContext))
  117. {
  118. hr = HRESULT_FROM_WIN32(::GetLastError());
  119. DebugTrace("Error [%#x]: CertFreeCertificateContext() failed.\n", hr);
  120. goto ErrorExit;
  121. }
  122. //
  123. // If we don't have room to use numeric index, force to use thumbprint.
  124. //
  125. if ((m_dwNextIndex + 1) > m_coll.max_size())
  126. {
  127. if (FAILED(hr = pVal->get_Thumbprint(&bstrIndex)))
  128. {
  129. DebugTrace("Error [%#x]: pVal->get_Thumbprint() failed.\n", hr);
  130. goto ErrorExit;
  131. }
  132. }
  133. else
  134. {
  135. //
  136. // BSTR index of numeric value.
  137. //
  138. wsprintfA(szIndex, "%#08x", ++m_dwNextIndex);
  139. if (!(bstrIndex = szIndex))
  140. {
  141. hr = E_OUTOFMEMORY;
  142. DebugTrace("Error [%#x]: bstrIndex = szIndex failed.\n", hr);
  143. goto ErrorExit;
  144. }
  145. }
  146. //
  147. // Now add object to collection map.
  148. //
  149. // Note that the overloaded = operator for CComPtr will
  150. // automatically AddRef to the object. Also, when the CComPtr
  151. // is deleted (happens when the Remove or map destructor is called),
  152. // the CComPtr destructor will automatically Release the object.
  153. //
  154. m_coll[bstrIndex] = pVal;
  155. }
  156. catch(...)
  157. {
  158. hr = E_POINTER;
  159. DebugTrace("Exception: invalid parameter.\n");
  160. goto ErrorExit;
  161. }
  162. UnlockExit:
  163. //
  164. // Unlock access to this object.
  165. //
  166. m_Lock.Unlock();
  167. DebugTrace("Leaving CRecipients::Add().\n");
  168. return hr;
  169. ErrorExit:
  170. //
  171. // Sanity check.
  172. //
  173. ATLASSERT(FAILED(hr));
  174. ReportError(hr);
  175. goto UnlockExit;
  176. }
  177. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  178. Function : CRecipients::Remove
  179. Synopsis : Remove a recipient from the collection.
  180. Parameter: long Index - Recipient index (1-based).
  181. Remark :
  182. ------------------------------------------------------------------------------*/
  183. STDMETHODIMP CRecipients::Remove (long Index)
  184. {
  185. HRESULT hr = S_OK;
  186. RecipientMap::iterator iter;
  187. DebugTrace("Entering CRecipients::Remove().\n");
  188. try
  189. {
  190. //
  191. // Lock access to this object.
  192. //
  193. m_Lock.Lock();
  194. //
  195. // Make sure parameter is valid.
  196. //
  197. if (Index < 1 || (DWORD) Index > m_coll.size())
  198. {
  199. hr = E_INVALIDARG;
  200. DebugTrace("Error [%#x]: Parameter Index (%#d) is out of range.\n", hr, Index);
  201. goto ErrorExit;
  202. }
  203. //
  204. // Find object in map.
  205. //
  206. Index--;
  207. iter = m_coll.begin();
  208. while (iter != m_coll.end() && Index > 0)
  209. {
  210. iter++;
  211. Index--;
  212. }
  213. //
  214. // This should not happen.
  215. //
  216. if (iter == m_coll.end())
  217. {
  218. hr = CAPICOM_E_INTERNAL;
  219. DebugTrace("Unexpected internal error [%#x]: iterator went pass end of map.\n", hr);
  220. goto ErrorExit;
  221. }
  222. //
  223. // Now remove object in map.
  224. //
  225. m_coll.erase(iter);
  226. }
  227. catch(...)
  228. {
  229. hr = E_POINTER;
  230. DebugTrace("Exception: invalid parameter.\n");
  231. goto ErrorExit;
  232. }
  233. UnlockExit:
  234. //
  235. // Unlock access to this object.
  236. //
  237. m_Lock.Unlock();
  238. DebugTrace("Leaving CRecipients::Remove().\n");
  239. return hr;
  240. ErrorExit:
  241. //
  242. // Sanity check.
  243. //
  244. ATLASSERT(FAILED(hr));
  245. ReportError(hr);
  246. goto UnlockExit;
  247. }
  248. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  249. Function : CRecipients::Clear
  250. Synopsis : Remove all recipients from the collection.
  251. Parameter: None.
  252. Remark :
  253. ------------------------------------------------------------------------------*/
  254. STDMETHODIMP CRecipients::Clear (void)
  255. {
  256. HRESULT hr = S_OK;
  257. DebugTrace("Entering CRecipients::Clear().\n");
  258. try
  259. {
  260. //
  261. // Lock access to this object.
  262. //
  263. m_Lock.Lock();
  264. //
  265. // Clear it.
  266. //
  267. m_coll.clear();
  268. }
  269. catch(...)
  270. {
  271. hr = E_POINTER;
  272. DebugTrace("Exception: invalid parameter.\n");
  273. goto ErrorExit;
  274. }
  275. UnlockExit:
  276. //
  277. // Unlock access to this object.
  278. //
  279. m_Lock.Unlock();
  280. DebugTrace("Leaving CRecipients::Clear().\n");
  281. return hr;
  282. ErrorExit:
  283. //
  284. // Sanity check.
  285. //
  286. ATLASSERT(FAILED(hr));
  287. ReportError(hr);
  288. goto UnlockExit;
  289. }