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.

345 lines
10 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation
  6. //
  7. // File: iasprofa.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. // IASProfA.cpp: implementation of the CIASProfileAttribute class.
  11. //
  12. //////////////////////////////////////////////////////////////////////
  13. #include "stdafx.h"
  14. #include "resource.h"
  15. #include "helper.h"
  16. #include "IASHelper.h"
  17. #include "iasprofa.h"
  18. #include "napmmc.h"
  19. #include "napmmc_i.c"
  20. //////////////////////////////////////////////////////////////////////
  21. // Forward declarations of some utilities used here
  22. //////////////////////////////////////////////////////////////////////
  23. static HRESULT getCLSIDForEditorToUse( /* in */ IIASAttributeInfo *pIASAttributeInfo
  24. , /* in */ VARIANT * pvarValue
  25. , /* out */ CLSID &clsid
  26. );
  27. static HRESULT SetUpAttributeEditor( /* in */ IIASAttributeInfo *pIASAttributeInfo
  28. , /* in */ VARIANT * pvarValue
  29. , /* out */ IIASAttributeEditor ** ppIASAttributeEditor
  30. );
  31. //////////////////////////////////////////////////////////////////////
  32. // Construction/Destruction
  33. //////////////////////////////////////////////////////////////////////
  34. //////////////////////////////////////////////////////////////////////////////
  35. /*++
  36. CIASProfileAttribute::CIASProfileAttribute
  37. Constructor
  38. --*/
  39. //////////////////////////////////////////////////////////////////////////////
  40. CIASProfileAttribute::CIASProfileAttribute(
  41. IIASAttributeInfo * pIASAttributeInfo
  42. , VARIANT & varValue
  43. )
  44. {
  45. // Check for preconditions:
  46. _ASSERTE( pIASAttributeInfo );
  47. HRESULT hr;
  48. // The smartpointer calls AddRef on this interface.
  49. m_spIASAttributeInfo = pIASAttributeInfo;
  50. // Make a copy of the passed variant.
  51. hr = VariantCopy( &m_varValue, &varValue );
  52. if( FAILED( hr ) ) throw hr;
  53. // ISSUE: Make sure that if anything here fails, m_spIASAttributeInfo gets release.
  54. }
  55. //////////////////////////////////////////////////////////////////////////////
  56. /*++
  57. CIASProfileAttribute::~CIASProfileAttribute
  58. Destructor
  59. --*/
  60. //////////////////////////////////////////////////////////////////////////////
  61. CIASProfileAttribute::~CIASProfileAttribute()
  62. {
  63. }
  64. //////////////////////////////////////////////////////////////////////////////
  65. /*++
  66. CIASProfileAttribute::Edit
  67. Call this to ask a profile attribute to edit itself.
  68. --*/
  69. //////////////////////////////////////////////////////////////////////////////
  70. STDMETHODIMP CIASProfileAttribute::Edit()
  71. {
  72. // Check for preconditions:
  73. _ASSERTE( m_spIASAttributeInfo );
  74. CLSID clsidEditorToUse;
  75. HRESULT hr = S_OK;
  76. CComPtr<IIASAttributeEditor> spIASAttributeEditor;
  77. // Get the editor to use.
  78. hr = SetUpAttributeEditor( m_spIASAttributeInfo.p, &m_varValue, &spIASAttributeEditor );
  79. if( FAILED( hr ) ) return hr;
  80. // Edit it!
  81. CComBSTR bstrReserved;
  82. hr = spIASAttributeEditor->Edit( m_spIASAttributeInfo.p, &m_varValue, &bstrReserved );
  83. if( FAILED( hr ) ) return hr;
  84. return hr;
  85. }
  86. //////////////////////////////////////////////////////////////////////////////
  87. /*++
  88. CIASProfileAttribute::getAttributeName
  89. --*/
  90. //////////////////////////////////////////////////////////////////////////////
  91. STDMETHODIMP CIASProfileAttribute::get_AttributeName( BSTR * pbstrVal )
  92. {
  93. // Check for preconditions:
  94. _ASSERTE( m_spIASAttributeInfo );
  95. HRESULT hr = S_OK;
  96. hr = m_spIASAttributeInfo->get_AttributeName( pbstrVal );
  97. return hr;
  98. }
  99. //////////////////////////////////////////////////////////////////////////////
  100. /*++
  101. CIASProfileAttribute::GetDisplayInfo
  102. Rather than asking the AttributeInfo directly for information
  103. about the vendor name, this method will use an AttributeEditor
  104. to ask for this information.
  105. This is the most generic way of asking for this info as
  106. for some attributes, e.g. RADIUS Vendor Specific, Vendor Name
  107. is not stored in the AttributeInfo but is encapsulated in
  108. the value of the attribute itself.
  109. So we don't use our own knowledge of the attribute, rather we
  110. create an editor and ask the editor to give back this
  111. information for us.
  112. --*/
  113. //////////////////////////////////////////////////////////////////////////////
  114. STDMETHODIMP CIASProfileAttribute::GetDisplayInfo( BSTR * pbstrVendor, BSTR * pbstrDisplayValue )
  115. {
  116. // Check for preconditions:
  117. _ASSERTE( m_spIASAttributeInfo );
  118. HRESULT hr = S_OK;
  119. CComBSTR bstrVendor, bstrDisplayValue, bstrReserved;
  120. try
  121. {
  122. CComPtr<IIASAttributeEditor> spIASAttributeEditor;
  123. // Get the editor to use.
  124. hr = SetUpAttributeEditor( m_spIASAttributeInfo.p, &m_varValue, &spIASAttributeEditor );
  125. if( FAILED( hr ) ) throw hr;
  126. hr = spIASAttributeEditor->GetDisplayInfo( m_spIASAttributeInfo.p, &m_varValue, &bstrVendor, &bstrDisplayValue, &bstrReserved );
  127. if( FAILED( hr ) ) throw hr;
  128. }
  129. catch(...)
  130. {
  131. // If anything above fails, just fall through -- we will return a pointer to an empty bstr.
  132. hr = E_FAIL;
  133. }
  134. *pbstrVendor = bstrVendor.Copy();
  135. *pbstrDisplayValue = bstrDisplayValue.Copy();
  136. return hr;
  137. }
  138. //////////////////////////////////////////////////////////////////////////////
  139. /*++
  140. CIASProfileAttribute::get_VarValue
  141. --*/
  142. //////////////////////////////////////////////////////////////////////////////
  143. STDMETHODIMP CIASProfileAttribute::get_VarValue( VARIANT * pvarVal )
  144. {
  145. // Check for preconditions:
  146. // None.
  147. HRESULT hr = S_OK;
  148. hr = VariantCopy( pvarVal, &m_varValue );
  149. return hr;
  150. }
  151. //////////////////////////////////////////////////////////////////////////////
  152. /*++
  153. CIASProfileAttribute::get_AttributeID
  154. --*/
  155. //////////////////////////////////////////////////////////////////////////////
  156. STDMETHODIMP CIASProfileAttribute::get_AttributeID( ATTRIBUTEID * pID )
  157. {
  158. // Check for preconditions:
  159. _ASSERTE( m_spIASAttributeInfo );
  160. HRESULT hr = S_OK;
  161. hr = m_spIASAttributeInfo->get_AttributeID( pID );
  162. return hr;
  163. }
  164. //////////////////////////////////////////////////////////////////////////////
  165. /*++
  166. ::getCLSIDForEditorToUse
  167. The ShemaAttribute for a node stores a ProgID which indicates which
  168. editor to use to manipulate an attribute.
  169. For non-multivalued attributes, we query the schema attribute to find
  170. out the ProgID for its editor.
  171. For multivalued attributes, we always create the multivalued editor.
  172. When it is used, the multivalued editor is passed the schema attribute which it will
  173. then use to query for the appropriate editor to pop up for editing
  174. each indivdual elements
  175. --*/
  176. //////////////////////////////////////////////////////////////////////////////
  177. HRESULT getCLSIDForEditorToUse( /* in */ IIASAttributeInfo *pIASAttributeInfo
  178. , /* in */ VARIANT * pvarValue
  179. , /* out */ CLSID &clsid
  180. )
  181. {
  182. // Check for preconditions:
  183. _ASSERTE( pIASAttributeInfo );
  184. HRESULT hr = S_OK;
  185. // Get attribute restrictions to see if multivalued.
  186. long lRestriction;
  187. hr = pIASAttributeInfo->get_AttributeRestriction( &lRestriction );
  188. if( lRestriction & MULTIVALUED )
  189. {
  190. _ASSERTE( V_VT(pvarValue) == (VT_ARRAY | VT_VARIANT) || V_VT(pvarValue) == VT_EMPTY );
  191. // Create the multi-attribute editor.
  192. // It will figure out the appropriate editor to use to
  193. // edit individual attribute values.
  194. clsid = CLSID_IASMultivaluedAttributeEditor;
  195. }
  196. else
  197. {
  198. // Query the schema attribute to see which attribute editor to use.
  199. CComBSTR bstrProgID;
  200. hr = pIASAttributeInfo->get_EditorProgID( &bstrProgID );
  201. if( FAILED( hr ) )
  202. {
  203. // We could try putting up a default (e.g. hex) editor, but for now:
  204. return hr;
  205. }
  206. hr = CLSIDFromProgID( bstrProgID, &clsid );
  207. if( FAILED( hr ) )
  208. {
  209. // We could try putting up a default (e.g. hex) editor, but for now:
  210. return hr;
  211. }
  212. }
  213. return hr;
  214. }
  215. //////////////////////////////////////////////////////////////////////////////
  216. /*++
  217. ::SetUpAttributeEditor
  218. --*/
  219. //////////////////////////////////////////////////////////////////////////////
  220. HRESULT SetUpAttributeEditor( /* in */ IIASAttributeInfo *pIASAttributeInfo
  221. , /* in */ VARIANT * pvarValue
  222. , /* out */ IIASAttributeEditor ** ppIASAttributeEditor
  223. )
  224. {
  225. // Check for preconditions:
  226. _ASSERTE( pIASAttributeInfo );
  227. _ASSERTE( ppIASAttributeEditor );
  228. // Initialize the interface pointer to NULL so we know whether we need to release it if there is an error.
  229. *ppIASAttributeEditor = NULL;
  230. // Query the schema attribute to see which attribute editor to use.
  231. CLSID clsidEditorToUse;
  232. CComBSTR bstrProgID;
  233. HRESULT hr;
  234. try
  235. {
  236. hr = getCLSIDForEditorToUse( pIASAttributeInfo, pvarValue, clsidEditorToUse );
  237. if( FAILED( hr ) )
  238. {
  239. // We could try putting up a default (e.g. hex) editor, but for now:
  240. return hr;
  241. }
  242. hr = CoCreateInstance( clsidEditorToUse , NULL, CLSCTX_INPROC_SERVER, IID_IIASAttributeEditor, (LPVOID *) ppIASAttributeEditor );
  243. if( FAILED( hr ) )
  244. {
  245. return hr;
  246. }
  247. if( ! *ppIASAttributeEditor )
  248. {
  249. return E_FAIL;
  250. }
  251. }
  252. catch(...)
  253. {
  254. // No smart pointers here -- need to make sure we release ourselves.
  255. if( *ppIASAttributeEditor )
  256. {
  257. (*ppIASAttributeEditor)->Release();
  258. *ppIASAttributeEditor = NULL;
  259. }
  260. }
  261. return hr;
  262. }