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.

313 lines
7.4 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation
  6. //
  7. // File: sdowrap.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "stdafx.h"
  11. #include "rasdial.h"
  12. #include "sdowrap.h"
  13. #include "profsht.h"
  14. #include "iastrace.h"
  15. //========================================
  16. //
  17. // CSdoWrapper Class Implementation
  18. //
  19. CSdoWrapper::~CSdoWrapper()
  20. {
  21. // clear the map
  22. POSITION pos = m_mapProperties.GetStartPosition();
  23. ULONG id;
  24. ISdo* pSdo = NULL;
  25. while(pos)
  26. {
  27. pSdo = NULL;
  28. m_mapProperties.GetNextAssoc(pos, id, pSdo);
  29. if(pSdo)
  30. pSdo->Release();
  31. }
  32. m_mapProperties.RemoveAll();
  33. }
  34. // Initialize the map of the attribute collection object
  35. HRESULT CSdoWrapper::Init(ULONG collectionId, ISdo* pISdo, ISdoDictionaryOld* pIDic)
  36. {
  37. HRESULT hr = S_OK;
  38. VARIANT var;
  39. VARIANT* pVar = NULL;
  40. CComPtr<IEnumVARIANT> spEnum;
  41. CComPtr<IUnknown> spIUnk;
  42. ULONG count = 0;
  43. VariantInit(&var);
  44. // it must be new
  45. ASSERT(!m_spISdoCollection.p);
  46. ASSERT(!m_spIDictionary.p);
  47. ASSERT(!m_spISdo.p);
  48. // must be valid
  49. ASSERT(pISdo && pIDic);
  50. m_spISdo = pISdo;
  51. CHECK_HR(hr = pISdo->GetProperty(collectionId, &var));
  52. ASSERT(V_VT(&var) & VT_DISPATCH);
  53. CHECK_HR(hr = V_DISPATCH(&var)->QueryInterface(IID_ISdoCollection, (void**)&m_spISdoCollection));
  54. ASSERT(m_spISdoCollection.p);
  55. m_spIDictionary = pIDic;
  56. // prepare the existing property ( in the collection) to map
  57. CHECK_HR(hr = m_spISdoCollection->get__NewEnum((IUnknown**)&spIUnk));
  58. CHECK_HR(hr = spIUnk->QueryInterface(IID_IEnumVARIANT, (void**)&spEnum));
  59. // get the list of variant
  60. CHECK_HR(hr = m_spISdoCollection->get_Count((long*)&count));
  61. if(count > 0)
  62. {
  63. try
  64. {
  65. pVar = new VARIANT[count];
  66. for(ULONG i = 0; i < count; i++)
  67. VariantInit(pVar + i);
  68. if(!pVar)
  69. {
  70. CHECK_HR(hr = E_OUTOFMEMORY);
  71. }
  72. CHECK_HR(hr = spEnum->Reset());
  73. CHECK_HR(hr = spEnum->Next(count, pVar, &count));
  74. // prepare the map
  75. {
  76. ISdo* pISdo = NULL;
  77. ULONG id;
  78. VARIANT var;
  79. VariantInit(&var);
  80. for(ULONG i = 0; i < count; i++)
  81. {
  82. CHECK_HR(hr = V_DISPATCH(pVar + i)->QueryInterface(IID_ISdo, (void**)&pISdo));
  83. CHECK_HR(hr = pISdo->GetProperty(PROPERTY_ATTRIBUTE_ID, &var));
  84. ASSERT(V_VT(&var) == VT_I4);
  85. m_mapProperties[V_I4(&var)] = pISdo;
  86. pISdo->AddRef();
  87. }
  88. }
  89. }
  90. catch(CMemoryException* pException)
  91. {
  92. pException->Delete();
  93. pVar = NULL;
  94. CHECK_HR(hr = E_OUTOFMEMORY);
  95. }
  96. }
  97. L_ERR:
  98. delete[] pVar;
  99. VariantClear(&var);
  100. return hr;
  101. }
  102. // set a property based on ID
  103. HRESULT CSdoWrapper::PutProperty(ULONG id, VARIANT* pVar)
  104. {
  105. ASSERT(m_spISdoCollection.p);
  106. ASSERT(m_spIDictionary.p);
  107. ISdo* pProp = NULL;
  108. IDispatch* pDisp = NULL;
  109. HRESULT hr = S_OK;
  110. int ref = 0;
  111. IASTracePrintf("PutProperty %d", id);
  112. if(!m_mapProperties.Lookup(id, pProp)) // no ref change to pProp
  113. {
  114. IASTracePrintf("IDictionary::CreateAttribute %d", id);
  115. CHECK_HR(hr = m_spIDictionary->CreateAttribute((ATTRIBUTEID)id, &pDisp));
  116. IASTracePrintf("hr = %8x", hr);
  117. ASSERT(pDisp);
  118. // since pDisp is both in, out parameter, we assume the Ref is added within the function call
  119. IASTracePrintf("ISdoCollection::Add %x", pDisp);
  120. CHECK_HR(hr = m_spISdoCollection->Add(NULL, (IDispatch**)&pDisp)); // pDisp AddRef
  121. IASTracePrintf("hr = %8x", hr);
  122. //
  123. ASSERT(pDisp);
  124. CHECK_HR(hr = pDisp->QueryInterface(IID_ISdo, (void**)&pProp)); // one ref add
  125. ASSERT(pProp);
  126. // after we have the pProp, the pDisp can be released
  127. pDisp->Release();
  128. // add to the wrapper's map
  129. m_mapProperties[id] = pProp; // no need to addref again, since there is one already
  130. }
  131. IASTracePrintf("ISdo::PutProperty PROPERTY_ATTRIBUTE_VALUE %x", pVar);
  132. CHECK_HR(hr = pProp->PutProperty(PROPERTY_ATTRIBUTE_VALUE, pVar));
  133. IASTracePrintf("hr = %8x", hr);
  134. // for debug, ensure each attribute can be commited
  135. #ifdef WEI_SPECIAL_DEBUG
  136. ASSERT(S_OK == Commit(TRUE));
  137. #endif
  138. L_ERR:
  139. IASTracePrintf("hr = %8x", hr);
  140. return hr;
  141. }
  142. // get property based on ID
  143. HRESULT CSdoWrapper::GetProperty(ULONG id, VARIANT* pVar)
  144. {
  145. ISdo* pProp;
  146. HRESULT hr = S_OK;
  147. IASTracePrintf("Enter CSdoWrapper::GetProperty %d", id);
  148. if(m_mapProperties.Lookup(id, pProp)) // no ref change to pProp
  149. {
  150. ASSERT(pProp);
  151. CHECK_HR(hr = pProp->GetProperty(PROPERTY_ATTRIBUTE_VALUE, pVar));
  152. }
  153. else
  154. {
  155. V_VT(pVar) = VT_ERROR;
  156. V_ERROR(pVar) = DISP_E_PARAMNOTFOUND;
  157. }
  158. L_ERR:
  159. return hr;
  160. }
  161. // remove a property based on ID
  162. HRESULT CSdoWrapper::RemoveProperty(ULONG id)
  163. {
  164. ASSERT(m_spISdoCollection.p);
  165. ISdo* pProp;
  166. HRESULT hr = S_OK;
  167. IASTracePrintf("RemoveProperty %d", id);
  168. if(m_mapProperties.Lookup(id, pProp)) // no ref change to pProp
  169. {
  170. ASSERT(pProp);
  171. CHECK_HR(hr = m_spISdoCollection->Remove((IDispatch*)pProp));
  172. m_mapProperties.RemoveKey(id);
  173. pProp->Release();
  174. // for debug, ensure each attribute can be commited
  175. ASSERT(S_OK == Commit(TRUE));
  176. }
  177. else
  178. hr = S_FALSE;
  179. L_ERR:
  180. IASTracePrintf("hr = %8x", hr);
  181. return hr;
  182. }
  183. // commit changes to the properties
  184. HRESULT CSdoWrapper::Commit(BOOL bCommit)
  185. {
  186. HRESULT hr = S_OK;
  187. IASTracePrintf("Commit %d", bCommit);
  188. if(bCommit)
  189. {
  190. CHECK_HR(hr = m_spISdo->Apply());
  191. }
  192. else
  193. {
  194. CHECK_HR(hr = m_spISdo->Restore());
  195. }
  196. L_ERR:
  197. IASTracePrintf("hr = %8x", hr);
  198. return hr;
  199. }
  200. //========================================
  201. //
  202. // CSdoUserWrapper Class Implementation
  203. //
  204. // set a property based on ID
  205. HRESULT CUserSdoWrapper::PutProperty(ULONG id, VARIANT* pVar)
  206. {
  207. ASSERT(m_spISdo.p);
  208. IASTracePrintf("PutProperty %d", id);
  209. HRESULT hr = m_spISdo->PutProperty(id, pVar);
  210. IASTracePrintf("hr = %8x", hr);
  211. return hr;
  212. }
  213. // get property based on ID
  214. HRESULT CUserSdoWrapper::GetProperty(ULONG id, VARIANT* pVar)
  215. {
  216. IASTracePrintf("GetProperty %d", id);
  217. HRESULT hr = m_spISdo->GetProperty(id, pVar);
  218. IASTracePrintf("hr = %8x", hr);
  219. return hr;
  220. }
  221. // remove a property based on ID
  222. HRESULT CUserSdoWrapper::RemoveProperty(ULONG id)
  223. {
  224. VARIANT v;
  225. VariantInit(&v);
  226. V_VT(&v) = VT_EMPTY;
  227. IASTracePrintf("RemoveProperty %d", id);
  228. HRESULT hr = m_spISdo->PutProperty(id, &v);
  229. IASTracePrintf("hr = %8x", hr);
  230. return hr;
  231. }
  232. // commit changes to the properties
  233. HRESULT CUserSdoWrapper::Commit(BOOL bCommit)
  234. {
  235. HRESULT hr = S_OK;
  236. IASTracePrintf("Commit %d", bCommit);
  237. if(bCommit)
  238. {
  239. CHECK_HR(hr = m_spISdo->Apply());
  240. }
  241. else
  242. {
  243. CHECK_HR(hr = m_spISdo->Restore());
  244. }
  245. L_ERR:
  246. IASTracePrintf("hr = %8x", hr);
  247. return hr;
  248. }