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.

489 lines
8.4 KiB

  1. //***************************************************************************
  2. //
  3. // VPSINKS.CPP
  4. //
  5. // Module: WBEM VIEW PROVIDER
  6. //
  7. // Purpose: Contains the sinks implementations
  8. //
  9. // Copyright (c) 1998-2001 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. #include <provexpt.h>
  14. #include <provcoll.h>
  15. #include <provtempl.h>
  16. #include <provmt.h>
  17. #include <typeinfo.h>
  18. #include <process.h>
  19. #include <objbase.h>
  20. #include <objidl.h>
  21. #include <stdio.h>
  22. #include <wbemidl.h>
  23. #include <provcont.h>
  24. #include <provevt.h>
  25. #include <provthrd.h>
  26. #include <provlog.h>
  27. #include <cominit.h>
  28. #include <dsgetdc.h>
  29. #include <lmcons.h>
  30. #include <lmapibuf.h>
  31. #include <instpath.h>
  32. #include <genlex.h>
  33. #include <sql_1.h>
  34. #include <objpath.h>
  35. #include <vpdefs.h>
  36. #include <vpcfac.h>
  37. #include <vpquals.h>
  38. #include <vpserv.h>
  39. #include <vptasks.h>
  40. extern CRITICAL_SECTION g_CriticalSection;
  41. CWbemClassObjectWithIndex :: CWbemClassObjectWithIndex(DWORD a_indx, IWbemClassObject *a_pObj)
  42. : m_pObject(NULL), m_ReferenceCount(0), m_nsindex(a_indx)
  43. {
  44. if (a_pObj)
  45. {
  46. a_pObj->AddRef();
  47. m_pObject = a_pObj;
  48. }
  49. }
  50. CWbemClassObjectWithIndex :: ~CWbemClassObjectWithIndex()
  51. {
  52. if (m_pObject)
  53. {
  54. m_pObject->Release();
  55. }
  56. }
  57. ULONG CWbemClassObjectWithIndex :: AddRef ()
  58. {
  59. return InterlockedIncrement(&m_ReferenceCount);
  60. }
  61. ULONG CWbemClassObjectWithIndex :: Release ()
  62. {
  63. ULONG t_Ref;
  64. if ( (t_Ref = InterlockedDecrement(&m_ReferenceCount)) == 0 )
  65. {
  66. delete this ;
  67. return 0 ;
  68. }
  69. else
  70. {
  71. return t_Ref ;
  72. }
  73. }
  74. CObjectSinkResults::CObjectSinkResults(WbemTaskObject* parent, DWORD index)
  75. {
  76. m_ReferenceCount = 0;
  77. m_index = index;
  78. m_bSet = FALSE;
  79. m_hr = 0;
  80. m_parent = parent;
  81. m_parent->AddRef();
  82. m_ObjArray.SetSize(0, 10); //grow by 10s
  83. }
  84. CObjectSinkResults::~CObjectSinkResults()
  85. {
  86. if (m_parent != NULL)
  87. {
  88. m_parent->Release();
  89. }
  90. m_ObjArray.RemoveAll();
  91. }
  92. ULONG CObjectSinkResults::AddRef()
  93. {
  94. return InterlockedIncrement(&m_ReferenceCount);
  95. }
  96. ULONG CObjectSinkResults::Release()
  97. {
  98. LONG t_Ref;
  99. if ( (t_Ref = InterlockedDecrement(&m_ReferenceCount)) == 0 )
  100. {
  101. delete this ;
  102. return 0 ;
  103. }
  104. else
  105. {
  106. return t_Ref ;
  107. }
  108. }
  109. void CObjectSinkResults::SetStatus(HRESULT hr, CViewProvObjectSink *pSnk)
  110. {
  111. if (m_CriticalSection.Lock())
  112. {
  113. if (SUCCEEDED(m_hr))
  114. {
  115. m_hr = hr;
  116. }
  117. RemoveSink(pSnk);
  118. m_bSet = TRUE;
  119. if (m_parent != NULL)
  120. {
  121. m_parent->SetStatus(hr, m_index);
  122. }
  123. m_CriticalSection.Unlock();
  124. }
  125. }
  126. void CObjectSinkResults::SetSink(CViewProvObjectSink *pSnk)
  127. {
  128. if (m_CriticalSection.Lock())
  129. {
  130. m_realSnks.AddTail(pSnk);
  131. m_CriticalSection.Unlock();
  132. }
  133. }
  134. BOOL CObjectSinkResults::RemoveSink(CViewProvObjectSink *pSnk)
  135. {
  136. BOOL retVal = FALSE;
  137. if (m_CriticalSection.Lock())
  138. {
  139. POSITION t_pos = m_realSnks.GetHeadPosition();
  140. while (t_pos)
  141. {
  142. POSITION t_badPos = t_pos;
  143. CViewProvObjectSink * t_pSnk = m_realSnks.GetNext(t_pos);
  144. if (pSnk == t_pSnk)
  145. {
  146. m_realSnks.RemoveAt(t_badPos);
  147. retVal = TRUE;
  148. break;
  149. }
  150. }
  151. m_CriticalSection.Unlock();
  152. }
  153. return retVal;
  154. }
  155. void CObjectSinkResults::Disconnect()
  156. {
  157. //can't call disconnect when locked, since this calls CancelAsyncCall
  158. CList<CViewProvObjectSink*,CViewProvObjectSink*> t_realSnks;
  159. if (m_CriticalSection.Lock())
  160. {
  161. while (m_realSnks.GetCount() > 0)
  162. {
  163. CViewProvObjectSink* t_pSnk = m_realSnks.RemoveTail();
  164. if (t_pSnk)
  165. {
  166. t_pSnk->AddRef();
  167. t_realSnks.AddTail(t_pSnk);
  168. }
  169. }
  170. if (m_parent != NULL)
  171. {
  172. m_parent->Release();
  173. m_parent = NULL;
  174. }
  175. m_CriticalSection.Unlock();
  176. }
  177. while (t_realSnks.GetCount() > 0)
  178. {
  179. CViewProvObjectSink* t_pSnk = t_realSnks.RemoveTail();
  180. if (t_pSnk)
  181. {
  182. t_pSnk->Disconnect();
  183. t_pSnk->Release();
  184. }
  185. }
  186. }
  187. HRESULT CObjectSinkResults::Indicate(LONG count, IWbemClassObject** ppObjArray, DWORD a_indx)
  188. {
  189. HRESULT hr = WBEM_NO_ERROR;
  190. if ( (count > 0) && m_CriticalSection.Lock() )
  191. {
  192. if (m_parent != NULL)
  193. {
  194. m_parent->SetResultReceived();
  195. for (LONG x = 0; x < count; x++)
  196. {
  197. if (ppObjArray[x] != NULL)
  198. {
  199. CWbemClassObjectWithIndex *t_clsWrap = new CWbemClassObjectWithIndex(a_indx, ppObjArray[x]);
  200. t_clsWrap->AddRef();
  201. m_ObjArray.Add(t_clsWrap);
  202. }
  203. else
  204. {
  205. hr = WBEM_E_INVALID_PARAMETER;
  206. }
  207. }
  208. }
  209. else
  210. {
  211. hr = WBEM_E_CALL_CANCELLED;
  212. }
  213. m_CriticalSection.Unlock();
  214. }
  215. else
  216. {
  217. if (count < 0)
  218. {
  219. hr = WBEM_E_INVALID_PARAMETER;
  220. }
  221. }
  222. return hr;
  223. }
  224. CViewProvObjectSink::CViewProvObjectSink(CObjectSinkResults* parent, CWbemServerWrap *pServ, DWORD a_indx)
  225. :m_parent(NULL), m_ServWrap(NULL), m_nsindex(a_indx)
  226. {
  227. EnterCriticalSection(&g_CriticalSection);
  228. CViewProvClassFactory :: objectsInProgress++;
  229. LeaveCriticalSection(&g_CriticalSection);
  230. m_ReferenceCount = 0;
  231. m_parent = parent;
  232. m_parent->AddRef();
  233. m_parent->SetSink(this);
  234. m_ServWrap = pServ;
  235. m_ServWrap->AddRef();
  236. m_RemoteSink = NULL;
  237. m_DoCancel = TRUE;
  238. }
  239. CViewProvObjectSink::~CViewProvObjectSink()
  240. {
  241. if (m_parent != NULL)
  242. {
  243. //set status has not been called so call it...
  244. m_parent->SetStatus(WBEM_E_FAILED, this);
  245. m_parent->Release();
  246. }
  247. if (m_ServWrap != NULL)
  248. {
  249. m_ServWrap->Release();
  250. }
  251. if (m_RemoteSink != NULL)
  252. {
  253. m_RemoteSink->Release();
  254. }
  255. EnterCriticalSection(&g_CriticalSection);
  256. CViewProvClassFactory :: objectsInProgress--;
  257. LeaveCriticalSection(&g_CriticalSection);
  258. }
  259. STDMETHODIMP CViewProvObjectSink::QueryInterface (REFIID refIID, LPVOID FAR * ppV)
  260. {
  261. if (ppV == NULL)
  262. {
  263. return E_INVALIDARG;
  264. }
  265. *ppV = NULL ;
  266. if ( refIID == IID_IUnknown )
  267. {
  268. *ppV = ( IWbemObjectSink* ) this ;
  269. }
  270. else if ( refIID == IID_IWbemObjectSink )
  271. {
  272. *ppV = ( IWbemObjectSink* ) this ;
  273. }
  274. if ( *ppV )
  275. {
  276. ( ( LPUNKNOWN ) *ppV )->AddRef () ;
  277. return S_OK ;
  278. }
  279. else
  280. {
  281. return E_NOINTERFACE ;
  282. }
  283. }
  284. STDMETHODIMP_(ULONG) CViewProvObjectSink::AddRef()
  285. {
  286. return InterlockedIncrement(&m_ReferenceCount);
  287. }
  288. STDMETHODIMP_(ULONG) CViewProvObjectSink::Release()
  289. {
  290. LONG t_Ref;
  291. if ( (t_Ref = InterlockedDecrement(&m_ReferenceCount)) == 0 )
  292. {
  293. delete this ;
  294. return 0 ;
  295. }
  296. else
  297. {
  298. return t_Ref ;
  299. }
  300. }
  301. HRESULT CViewProvObjectSink::Indicate(LONG count, IWbemClassObject** ppObjArray)
  302. {
  303. HRESULT hr = WBEM_NO_ERROR;
  304. if (m_lock.Lock())
  305. {
  306. if (m_parent != NULL)
  307. {
  308. hr = m_parent->Indicate(count, ppObjArray, m_nsindex);
  309. }
  310. m_lock.Unlock();
  311. }
  312. return hr;
  313. }
  314. HRESULT CViewProvObjectSink::SetStatus(LONG lFlags, HRESULT hr, BSTR bStr, IWbemClassObject* pObj)
  315. {
  316. if (m_lock.Lock())
  317. {
  318. if (m_parent != NULL)
  319. {
  320. m_parent->SetStatus(hr, this);
  321. m_parent->Release();
  322. m_parent = NULL;
  323. DisAssociate();
  324. m_DoCancel = FALSE;
  325. }
  326. m_lock.Unlock();
  327. }
  328. return WBEM_NO_ERROR;
  329. }
  330. void CViewProvObjectSink::Disconnect()
  331. {
  332. BOOL doCancel = FALSE;
  333. if (m_lock.Lock())
  334. {
  335. if (m_DoCancel)
  336. {
  337. doCancel = TRUE;
  338. m_DoCancel = FALSE;
  339. if (m_parent != NULL)
  340. {
  341. m_parent->Release();
  342. m_parent = NULL;
  343. }
  344. }
  345. m_lock.Unlock();
  346. }
  347. if (doCancel)
  348. {
  349. if (m_ServWrap != NULL)
  350. {
  351. IWbemServices *ptmpServ = m_ServWrap->GetServerOrProxy();
  352. if (ptmpServ)
  353. {
  354. if (m_RemoteSink != NULL)
  355. {
  356. ptmpServ->CancelAsyncCall(this);
  357. }
  358. else
  359. {
  360. ptmpServ->CancelAsyncCall(m_RemoteSink);
  361. DisAssociate();
  362. }
  363. m_ServWrap->ReturnServerOrProxy(ptmpServ);
  364. }
  365. m_ServWrap->Release();
  366. m_ServWrap = NULL;
  367. }
  368. }
  369. }
  370. IWbemObjectSink* CViewProvObjectSink::Associate()
  371. {
  372. IUnsecuredApartment* pUA = NULL;
  373. if ( SUCCEEDED(CViewProvServ::GetUnsecApp(&pUA)) )
  374. {
  375. IUnknown* pUnk = NULL;
  376. if ( SUCCEEDED(pUA->CreateObjectStub(this, &pUnk)) )
  377. {
  378. if ( FAILED(pUnk->QueryInterface(IID_IWbemObjectSink, (void **)&m_RemoteSink)) )
  379. {
  380. pUnk = NULL;
  381. }
  382. pUnk->Release();
  383. }
  384. pUA->Release();
  385. }
  386. return m_RemoteSink;
  387. }
  388. void CViewProvObjectSink::DisAssociate()
  389. {
  390. if (m_RemoteSink != NULL)
  391. {
  392. m_RemoteSink->Release();
  393. m_RemoteSink = NULL;
  394. }
  395. if (m_lock.Lock())
  396. {
  397. if (m_parent != NULL)
  398. {
  399. m_parent->Release();
  400. m_parent = NULL;
  401. }
  402. m_lock.Unlock();
  403. }
  404. }