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.

357 lines
9.3 KiB

  1. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Microsoft Windows, Copyright (C) Microsoft Corporation, 2000
  3. File: Extensions.cpp
  4. Contents: Implementation of CExtensions class for collection of
  5. IExtension objects.
  6. Remarks: This object is not creatable by user directly. It can only be
  7. created via property/method of other CAPICOM objects.
  8. The collection container is implemented usign STL::map of
  9. STL::pair of BSTR and IExtension..
  10. See Chapter 9 of "BEGINNING ATL 3 COM Programming" for algorithm
  11. adopted in here.
  12. History: 06-15-2001 dsie created
  13. ------------------------------------------------------------------------------*/
  14. #include "StdAfx.h"
  15. #include "CAPICOM.h"
  16. #include "Extensions.h"
  17. ////////////////////////////////////////////////////////////////////////////////
  18. //
  19. // Exported functions.
  20. //
  21. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  22. Function : CreateExtensionsObject
  23. Synopsis : Create an IExtensions collection object, and load the object with
  24. Extensions from the specified location.
  25. Parameter: PCCERT_CONTEXT pCertContext - Pointer to CERT_CONTEXT to be used
  26. to initialize the IExtensions object.
  27. IExtensions ** ppIExtensions - Pointer to pointer IExtensions
  28. to recieve the interface pointer.
  29. Remark :
  30. ------------------------------------------------------------------------------*/
  31. HRESULT CreateExtensionsObject (PCCERT_CONTEXT pCertContext,
  32. IExtensions ** ppIExtensions)
  33. {
  34. HRESULT hr = S_OK;
  35. CComObject<CExtensions> * pCExtensions = NULL;
  36. DebugTrace("Entering CreateExtensionsObject().\n");
  37. //
  38. // Sanity check.
  39. //
  40. ATLASSERT(pCertContext);
  41. ATLASSERT(ppIExtensions);
  42. try
  43. {
  44. //
  45. // Create the object. Note that the ref count will still be 0
  46. // after the object is created.
  47. //
  48. if (FAILED(hr = CComObject<CExtensions>::CreateInstance(&pCExtensions)))
  49. {
  50. DebugTrace("Error [%#x]: CComObject<CExtensions>::CreateInstance() failed.\n", hr);
  51. goto ErrorExit;
  52. }
  53. //
  54. // Init object with extensions.
  55. //
  56. if (FAILED(hr = pCExtensions->Init(pCertContext->pCertInfo->cExtension,
  57. pCertContext->pCertInfo->rgExtension)))
  58. {
  59. DebugTrace("Error [%#x]: pCExtensions->Init() failed.\n", hr);
  60. goto ErrorExit;
  61. }
  62. //
  63. // Return interface pointer to caller.
  64. //
  65. if (FAILED(hr = pCExtensions->QueryInterface(ppIExtensions)))
  66. {
  67. DebugTrace("Error [%#x]: pCExtensions->QueryInterface() failed.\n", hr);
  68. goto ErrorExit;
  69. }
  70. }
  71. catch(...)
  72. {
  73. hr = E_POINTER;
  74. DebugTrace("Exception: invalid parameter.\n");
  75. goto ErrorExit;
  76. }
  77. CommonExit:
  78. DebugTrace("Leaving CreateExtensionsObject().\n");
  79. return hr;
  80. ErrorExit:
  81. //
  82. // Sanity check.
  83. //
  84. ATLASSERT(FAILED(hr));
  85. //
  86. // Free resource.
  87. //
  88. if (pCExtensions)
  89. {
  90. delete pCExtensions;
  91. }
  92. goto CommonExit;
  93. }
  94. ////////////////////////////////////////////////////////////////////////////////
  95. //
  96. // CExtensions
  97. //
  98. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  99. Function : CExtensions::get_Item
  100. Synopsis : Return item in the collection.
  101. Parameter: VARIANT Index - Numeric index or string OID.
  102. VARIANT * pVal - Pointer to VARIANT to receive the IDispatch.
  103. Remark :
  104. ------------------------------------------------------------------------------*/
  105. STDMETHODIMP CExtensions::get_Item (VARIANT Index, VARIANT * pVal)
  106. {
  107. HRESULT hr = S_OK;
  108. CComBSTR bstrIndex;
  109. CComPtr<IExtension> pIExtension = NULL;
  110. DebugTrace("Entering CExtensions::get_Item().\n");
  111. try
  112. {
  113. //
  114. // Lock access to this object.
  115. //
  116. m_Lock.Lock();
  117. //
  118. // Check parameters.
  119. //
  120. if (NULL == pVal)
  121. {
  122. hr = E_INVALIDARG;
  123. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  124. goto ErrorExit;
  125. }
  126. //
  127. // Intialize.
  128. //
  129. ::VariantInit(pVal);
  130. //
  131. // Numeric or string?
  132. //
  133. if (VT_BSTR == Index.vt)
  134. {
  135. //
  136. // Index by OID string.
  137. //
  138. ExtensionMap::iterator it;
  139. //
  140. // Find the item with this OID.
  141. //
  142. it = m_coll.find(Index.bstrVal);
  143. if (it == m_coll.end())
  144. {
  145. DebugTrace("Info: Extension (%ls) not found in the collection.\n", Index.bstrVal);
  146. goto CommonExit;
  147. }
  148. //
  149. // Point to found item.
  150. //
  151. pIExtension = (*it).second;
  152. //
  153. // Return to caller.
  154. //
  155. pVal->vt = VT_DISPATCH;
  156. if (FAILED(hr = pIExtension->QueryInterface(IID_IDispatch, (void **) &(pVal->pdispVal))))
  157. {
  158. DebugTrace("Error [%#x]: pIExtension->QueryInterface() failed.\n", hr);
  159. goto ErrorExit;
  160. }
  161. }
  162. else
  163. {
  164. //
  165. // Coerce to integer.
  166. //
  167. if (FAILED(hr = ::VariantChangeType(&Index, &Index, 0, VT_I4)))
  168. {
  169. DebugTrace("Error [%#x]: VariantChangeType() failed.\n", hr);
  170. goto ErrorExit;
  171. }
  172. //
  173. // Use the base class implemented by ATL.
  174. //
  175. if (FAILED(hr = IExtensionsCollection::get_Item(Index.lVal, pVal)))
  176. {
  177. DebugTrace("Error [%#x]: IExtensionsCollection::get_Item() failed.\n", hr);
  178. goto ErrorExit;
  179. }
  180. }
  181. }
  182. catch(...)
  183. {
  184. hr = E_POINTER;
  185. DebugTrace("Exception: invalid parameter.\n");
  186. goto ErrorExit;
  187. }
  188. CommonExit:
  189. //
  190. // Unlock access to this object.
  191. //
  192. m_Lock.Unlock();
  193. DebugTrace("Leaving CExtensions::get_Item().\n");
  194. return hr;
  195. ErrorExit:
  196. //
  197. // Sanity check.
  198. //
  199. ATLASSERT(FAILED(hr));
  200. ReportError(hr);
  201. goto CommonExit;
  202. }
  203. ////////////////////////////////////////////////////////////////////////////////
  204. //
  205. // Non COM functions.
  206. //
  207. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  208. Function : CExtensions::Init
  209. Synopsis : Load all extensions into the collection.
  210. Parameter: DWORD cExtensions - Number of extensions.
  211. PCERT_EXTENSION * rgExtensions - Array of extensions.
  212. Remark : This method is not part of the COM interface (it is a normal C++
  213. member function). We need it to initialize the object created
  214. internally by us.
  215. Since it is only a normal C++ member function, this function can
  216. only be called from a C++ class pointer, not an interface pointer.
  217. ------------------------------------------------------------------------------*/
  218. STDMETHODIMP CExtensions::Init (DWORD cExtensions,
  219. PCERT_EXTENSION rgExtensions)
  220. {
  221. HRESULT hr = S_OK;
  222. DebugTrace("Entering CExtensions::Init().\n");
  223. try
  224. {
  225. //
  226. // Add all to the collection.
  227. //
  228. for (DWORD i = 0; i < cExtensions; i++)
  229. {
  230. CComBSTR bstrIndex;
  231. CComPtr<IExtension> pIExtension = NULL;
  232. //
  233. // Create the IExtension object.
  234. //
  235. if (FAILED(hr = ::CreateExtensionObject(&rgExtensions[i], &pIExtension.p)))
  236. {
  237. DebugTrace("Error [%#x]: CreateExtensionObject() failed.\n", hr);
  238. goto ErrorExit;
  239. }
  240. //
  241. // BSTR index of OID string.
  242. //
  243. if (!(bstrIndex = rgExtensions[i].pszObjId))
  244. {
  245. hr = E_OUTOFMEMORY;
  246. DebugTrace("Error [%#x]: bstrIndex = rgExtensions[i].pszObjId failed.\n", hr);
  247. goto ErrorExit;
  248. }
  249. //
  250. // Now add object to collection map.
  251. //
  252. // Note that the overloaded = operator for CComPtr will
  253. // automatically AddRef to the object. Also, when the CComPtr
  254. // is deleted (happens when the Remove or map destructor is called),
  255. // the CComPtr destructor will automatically Release the object.
  256. //
  257. m_coll[bstrIndex] = pIExtension;
  258. }
  259. }
  260. catch(...)
  261. {
  262. hr = E_POINTER;
  263. DebugTrace("Exception: invalid parameter.\n");
  264. goto ErrorExit;
  265. }
  266. CommonExit:
  267. DebugTrace("Leaving CExtensions::Init().\n");
  268. return hr;
  269. ErrorExit:
  270. //
  271. // Sanity check.
  272. //
  273. ATLASSERT(FAILED(hr));
  274. goto CommonExit;
  275. }