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.

431 lines
11 KiB

  1. //---------------------------------------------------------------------------
  2. // Notifier.cpp : Notifier implementation
  3. //
  4. // Copyright (c) 1996 Microsoft Corporation, All Rights Reserved
  5. // Developed by Sheridan Software Systems, Inc.
  6. //---------------------------------------------------------------------------
  7. #include "stdafx.h"
  8. #include "Notifier.h"
  9. SZTHISFILE
  10. #include "array_p.inl"
  11. //=--------------------------------------------------------------------------=
  12. // CVDNotifier - Constructor
  13. //
  14. CVDNotifier::CVDNotifier()
  15. {
  16. m_dwRefCount = 1;
  17. m_pParent = NULL;
  18. #ifdef _DEBUG
  19. g_cVDNotifierCreated++;
  20. #endif
  21. }
  22. //=--------------------------------------------------------------------------=
  23. // ~CVDNotifier - Destructor
  24. //
  25. CVDNotifier::~CVDNotifier()
  26. {
  27. #ifdef _DEBUG
  28. g_cVDNotifierDestroyed++;
  29. #endif
  30. }
  31. //=--------------------------------------------------------------------------=
  32. // IUnknown QueryInterface - stub implemntation - does nothing
  33. //
  34. HRESULT CVDNotifier::QueryInterface(REFIID riid, void **ppvObjOut)
  35. {
  36. return E_NOINTERFACE;
  37. }
  38. //=--------------------------------------------------------------------------=
  39. // AddRef
  40. //
  41. ULONG CVDNotifier::AddRef(void)
  42. {
  43. return ++m_dwRefCount;
  44. }
  45. //=--------------------------------------------------------------------------=
  46. // Release
  47. //
  48. ULONG CVDNotifier::Release(void)
  49. {
  50. if (1 > --m_dwRefCount)
  51. {
  52. delete this;
  53. return 0;
  54. }
  55. return m_dwRefCount;
  56. }
  57. /////////////////////////////////////////////////////////////////////
  58. // family maintenance
  59. /////////////////////////////////////////////////////////////////////
  60. //+-------------------------------------------------------------------------
  61. // Member: Join Family (public)
  62. //
  63. // Synopsis: add myself to the family of the given parent
  64. //
  65. // Arguments: pParent [in] parent of family I should join
  66. //
  67. // Returns: S_OK it worked
  68. // other it didn't
  69. HRESULT
  70. CVDNotifier::JoinFamily(CVDNotifier* pParent)
  71. {
  72. ASSERT_POINTER(pParent, CVDNotifier);
  73. m_pParent = pParent;
  74. return m_pParent->AddChild(this);
  75. }
  76. //+-------------------------------------------------------------------------
  77. // Member: Leave Family (public)
  78. //
  79. // Synopsis: remove myself from my parent's family
  80. //
  81. // Arguments: none
  82. //
  83. // Returns: S_OK it worked
  84. // other it didn't
  85. HRESULT
  86. CVDNotifier::LeaveFamily()
  87. {
  88. if (m_pParent)
  89. return m_pParent->DeleteChild(this);
  90. return S_OK;
  91. }
  92. //+-------------------------------------------------------------------------
  93. // Member: Add Child (public)
  94. //
  95. // Synopsis: add a notifier to my child list
  96. //
  97. // Arguments: pChild [in] notifier to add as a child
  98. //
  99. // Returns: S_OK it worked
  100. // other error while appending to dynamic array
  101. HRESULT
  102. CVDNotifier::AddChild(CVDNotifier *pChild)
  103. {
  104. return m_Children.Add(pChild);
  105. }
  106. //+-------------------------------------------------------------------------
  107. // Member: Delete Child (public)
  108. //
  109. // Synopsis: delete a notifier from my child list. When the last
  110. // notifier is deleted, delete myself from my parent's
  111. // child list.
  112. //
  113. // Arguments: pChild [in] notifier to delete
  114. //
  115. // Returns: S_OK it worked
  116. // E_FAIL error while deleting from dynamic array
  117. // other error while deleting from parent's child list
  118. HRESULT
  119. CVDNotifier::DeleteChild(CVDNotifier *pChild)
  120. {
  121. int k;
  122. for (k=0; k<m_Children.GetSize(); k++)
  123. {
  124. if (((CVDNotifier*)m_Children[k]) == pChild)
  125. {
  126. m_Children.RemoveAt(k);
  127. return S_OK;
  128. }
  129. }
  130. return E_FAIL;
  131. }
  132. /////////////////////////////////////////////////////////////////////
  133. // notification
  134. /////////////////////////////////////////////////////////////////////
  135. //+-------------------------------------------------------------------------
  136. // Member: Notify Before (public)
  137. //
  138. // Synopsis: send OKToDo, SyncBefore, and AboutToDo notifications
  139. // before doing an event. Send FailedToDo notification
  140. // if anything goes wrong during the process.
  141. //
  142. // Arguments: dwEventWhat [in] what event is causing the notification
  143. // cReasons [in] how many reasons
  144. // rgReasons [in] list of reasons for the event
  145. //
  146. // Returns: S_OK everything is OK so far
  147. // other some client indicated failure
  148. HRESULT
  149. CVDNotifier::NotifyBefore(DWORD dwEventWhat, ULONG cReasons,
  150. CURSOR_DBNOTIFYREASON rgReasons[])
  151. {
  152. HRESULT hr;
  153. // phase 1: send OKToDo, and Cancelled if anyone objects
  154. hr = NotifyOKToDo(dwEventWhat, cReasons, rgReasons);
  155. if (hr)
  156. return hr;
  157. // phase 2: send SyncBefore, and send FailedToDo if anything goes wrong
  158. hr = NotifySyncBefore(dwEventWhat, cReasons, rgReasons);
  159. if (hr) {
  160. NotifyFail(dwEventWhat, cReasons, rgReasons);
  161. return hr;
  162. }
  163. // phase 3: send AboutToDo, and send FailedToDo if anything goes wrong
  164. hr = NotifyAboutToDo(dwEventWhat, cReasons, rgReasons);
  165. if (hr) {
  166. NotifyFail(dwEventWhat, cReasons, rgReasons);
  167. return hr;
  168. }
  169. return S_OK;
  170. }
  171. //+-------------------------------------------------------------------------
  172. // Member: Notify After (public)
  173. //
  174. // Synopsis: send SyncAfter and DidEvent notifications after an event
  175. //
  176. // Arguments: dwEventWhat [in] what event is causing the notification
  177. // cReasons [in] how many reasons
  178. // rgReasons [in] list of reasons for the event
  179. //
  180. // Returns: S_OK it worked
  181. HRESULT
  182. CVDNotifier::NotifyAfter(DWORD dwEventWhat, ULONG cReasons,
  183. CURSOR_DBNOTIFYREASON rgReasons[])
  184. {
  185. // phase 5: send SyncAfter. Ignore errors - all clients need to hear this
  186. NotifySyncAfter(dwEventWhat, cReasons, rgReasons);
  187. // phase 6: send DidEvent. Ignore errors - all clients need to hear this
  188. NotifyDidEvent(dwEventWhat, cReasons, rgReasons);
  189. return S_OK;
  190. }
  191. //+-------------------------------------------------------------------------
  192. // Member: Notify Fail (public)
  193. //
  194. // Synopsis: send FailedToDo notification
  195. //
  196. // Arguments: dwEventWhat [in] what event is causing the notification
  197. // cReasons [in] how many reasons
  198. // rgReasons [in] list of reasons for the event
  199. //
  200. // Returns: S_OK it worked
  201. HRESULT
  202. CVDNotifier::NotifyFail(DWORD dwEventWhat, ULONG cReasons,
  203. CURSOR_DBNOTIFYREASON rgReasons[])
  204. {
  205. int k;
  206. // send FailedToDo to all clients, ignoring errors
  207. for (k=0; k<m_Children.GetSize(); k++) {
  208. ((CVDNotifier*)m_Children[k])->NotifyFail(dwEventWhat, cReasons, rgReasons);
  209. }
  210. return S_OK;
  211. }
  212. /////////////////////////////////////////////////////////////////////////
  213. // helper functions
  214. /////////////////////////////////////////////////////////////////////////
  215. //+-------------------------------------------------------------------------
  216. // Member: Notify OK To Do (protected)
  217. //
  218. // Synopsis: Send OKToDo notification. If a client objects (by
  219. // returning a non-zero HR), send Cancelled to notified
  220. // clients to cancel the event.
  221. //
  222. // Arguments: dwEventWhat [in] what event is causing the notification
  223. // cReasons [in] how many reasons
  224. // rgReasons [in] list of reasons for the event
  225. //
  226. // Returns: S_OK all clients agree it's OK to do the event
  227. // other some client disagrees
  228. HRESULT
  229. CVDNotifier::NotifyOKToDo(DWORD dwEventWhat, ULONG cReasons,
  230. CURSOR_DBNOTIFYREASON rgReasons[])
  231. {
  232. HRESULT hr = S_OK;
  233. int j, k;
  234. // poll all clients, see if they think it's OKToDo the event
  235. for (k=0; k<m_Children.GetSize(); k++) {
  236. hr = ((CVDNotifier*)m_Children[k])->NotifyOKToDo(dwEventWhat, cReasons, rgReasons);
  237. if (hr) { // somone objects, inform polled clients it's cancelled
  238. for (j=0; j<=k; j++) {
  239. ((CVDNotifier*)m_Children[j])->NotifyCancel(dwEventWhat, cReasons, rgReasons);
  240. }
  241. break;
  242. }
  243. }
  244. return hr;
  245. }
  246. //+-------------------------------------------------------------------------
  247. // Member: Notify Sync Before (public)
  248. //
  249. // Synopsis: Send SyncBefore notification
  250. //
  251. // Arguments: dwEventWhat [in] what event is causing the notification
  252. // cReasons [in] how many reasons
  253. // rgReasons [in] list of reasons for the event
  254. //
  255. // Returns: S_OK all clients received notification
  256. // other some client returned an error
  257. HRESULT
  258. CVDNotifier::NotifySyncBefore(DWORD dwEventWhat, ULONG cReasons,
  259. CURSOR_DBNOTIFYREASON rgReasons[])
  260. {
  261. HRESULT hr = S_OK;
  262. int k;
  263. for (k=0; k<m_Children.GetSize(); k++) {
  264. hr = ((CVDNotifier*)m_Children[k])->NotifySyncBefore(dwEventWhat, cReasons, rgReasons);
  265. if (hr)
  266. break;
  267. }
  268. return hr;
  269. }
  270. //+-------------------------------------------------------------------------
  271. // Member: Notify About To Do (protected)
  272. //
  273. // Synopsis: Send AboutToDo notification
  274. //
  275. // Arguments: dwEventWhat [in] what event is causing the notification
  276. // cReasons [in] how many reasons
  277. // rgReasons [in] list of reasons for the event
  278. //
  279. // Returns: S_OK all clients notified
  280. // other some client returned an error
  281. HRESULT
  282. CVDNotifier::NotifyAboutToDo(DWORD dwEventWhat, ULONG cReasons,
  283. CURSOR_DBNOTIFYREASON rgReasons[])
  284. {
  285. HRESULT hr = S_OK;
  286. int k;
  287. for (k=0; k<m_Children.GetSize(); k++) {
  288. hr = ((CVDNotifier*)m_Children[k])->NotifyAboutToDo(dwEventWhat, cReasons, rgReasons);
  289. if (hr)
  290. break;
  291. }
  292. return hr;
  293. }
  294. //+-------------------------------------------------------------------------
  295. // Member: Notify Sync After (protected)
  296. //
  297. // Synopsis: Send SyncAfter notification.
  298. //
  299. // Arguments: dwEventWhat [in] what event is causing the notification
  300. // cReasons [in] how many reasons
  301. // rgReasons [in] list of reasons for the event
  302. //
  303. // Returns: S_OK all clients notified
  304. HRESULT
  305. CVDNotifier::NotifySyncAfter(DWORD dwEventWhat, ULONG cReasons,
  306. CURSOR_DBNOTIFYREASON rgReasons[])
  307. {
  308. int k;
  309. // send SyncAfter to all clients, ignoring errors
  310. for (k=0; k<m_Children.GetSize(); k++) {
  311. ((CVDNotifier*)m_Children[k])->NotifySyncAfter(dwEventWhat, cReasons, rgReasons);
  312. }
  313. return S_OK;
  314. }
  315. //+-------------------------------------------------------------------------
  316. // Member: Notify Did Event (protected)
  317. //
  318. // Synopsis: Send DidEvent notification
  319. //
  320. // Arguments: dwEventWhat [in] what event is causing the notification
  321. // cReasons [in] how many reasons
  322. // rgReasons [in] list of reasons for the event
  323. //
  324. // Returns: S_OK all clients notified
  325. HRESULT
  326. CVDNotifier::NotifyDidEvent(DWORD dwEventWhat, ULONG cReasons,
  327. CURSOR_DBNOTIFYREASON rgReasons[])
  328. {
  329. int k;
  330. // send DidEvent to all clients, ignoring errors
  331. for (k=0; k<m_Children.GetSize(); k++) {
  332. ((CVDNotifier*)m_Children[k])->NotifyDidEvent(dwEventWhat, cReasons, rgReasons);
  333. }
  334. return S_OK;
  335. }
  336. //+-------------------------------------------------------------------------
  337. // Member: Notify Cancel (protected)
  338. //
  339. // Synopsis: Send Cancelled notification
  340. //
  341. // Arguments: dwEventWhat [in] what event is causing the notification
  342. // cReasons [in] how many reasons
  343. // rgReasons [in] list of reasons for the event
  344. //
  345. // Returns: S_OK all clients notified
  346. HRESULT
  347. CVDNotifier::NotifyCancel(DWORD dwEventWhat, ULONG cReasons,
  348. CURSOR_DBNOTIFYREASON rgReasons[])
  349. {
  350. int k;
  351. // send Cancelled to all clients, ignoring errors
  352. for (k=0; k<m_Children.GetSize(); k++) {
  353. ((CVDNotifier*)m_Children[k])->NotifyCancel(dwEventWhat, cReasons, rgReasons);
  354. }
  355. return S_OK;
  356. }