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.

344 lines
10 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. Events.h
  5. Abstract:
  6. This file provides declaration of the service
  7. notification mechanism.
  8. Author:
  9. Oded Sacher (OdedS) Jan, 2000
  10. Revision History:
  11. --*/
  12. #ifndef _SERVER_EVENTS_H
  13. #define _SERVER_EVENTS_H
  14. #include <map>
  15. #include <queue>
  16. #include <algorithm>
  17. #include <string>
  18. #define STRSAFE_NO_DEPRECATE
  19. #include <strsafe.h>
  20. using namespace std;
  21. #pragma hdrstop
  22. #pragma warning (disable : 4786) // identifier was truncated to '255' characters in the debug information
  23. // This pragma does not work KB ID: Q167355
  24. #define MAX_EVENTS_THREADS 2
  25. #define TOTAL_EVENTS_THREADS (MAX_EVENTS_THREADS * 2)
  26. #define EVENT_COMPLETION_KEY 0x00000001
  27. #define CLIENT_COMPLETION_KEY 0x00000002
  28. #define CLIENT_OPEN_CONN_COMPLETION_KEY 0x00000003
  29. /************************************
  30. * *
  31. * CFaxEvent *
  32. * *
  33. ************************************/
  34. class CFaxEvent
  35. {
  36. public:
  37. CFaxEvent() {}
  38. virtual ~CFaxEvent() {}
  39. virtual DWORD GetEvent (LPBYTE* lppBuffer, LPDWORD lpdwBufferSize) const = 0;
  40. virtual CFaxEvent* Clone() const = 0;
  41. virtual BOOL MatchEvent(PSID pUserSid, DWORD dwEventType, BOOL , BOOL bAllOutArchiveMessages) const = 0;
  42. void RemoveOffendingExtendedJobStatus() {}
  43. }; // CFaxEvent
  44. /************************************
  45. * *
  46. * CFaxEventExtended *
  47. * *
  48. ************************************/
  49. class CFaxEventExtended : public CFaxEvent
  50. {
  51. public:
  52. CFaxEventExtended(const FAX_EVENT_EX* pEvent, DWORD dwEventSize, PSID pSid);
  53. virtual ~CFaxEventExtended ()
  54. {
  55. MemFree ((void*)m_pEvent);
  56. m_pEvent = NULL;
  57. MemFree (m_pSid);
  58. m_pSid = NULL;
  59. m_dwEventSize = 0;
  60. }
  61. virtual CFaxEvent* Clone() const
  62. {
  63. DEBUG_FUNCTION_NAME(TEXT("CFaxEventExtended::Clone"));
  64. CFaxEventExtended* pFaxExtendedEvent = NULL;
  65. try
  66. {
  67. pFaxExtendedEvent = new (std::nothrow) CFaxEventExtended (m_pEvent, m_dwEventSize, m_pSid);
  68. }
  69. catch (exception &ex)
  70. {
  71. DebugPrintEx(DEBUG_ERR,
  72. TEXT("Exception: %S"),
  73. ex.what()
  74. );
  75. }
  76. return pFaxExtendedEvent;
  77. }
  78. virtual DWORD GetEvent (LPBYTE* lppBuffer, LPDWORD lpdwBufferSize) const;
  79. void RemoveOffendingExtendedJobStatus();
  80. virtual BOOL MatchEvent(PSID pUserSid, DWORD dwEventType, BOOL bAllQueueMessages, BOOL bAllOutArchiveMessages) const;
  81. private:
  82. const FAX_EVENT_EX* m_pEvent;
  83. DWORD m_dwEventSize;
  84. PSID m_pSid; // Pointer to the SID associated with the event
  85. }; // CFaxEventExtended
  86. /************************************
  87. * *
  88. * CFaxEventLegacy *
  89. * *
  90. ************************************/
  91. class CFaxEventLegacy : public CFaxEvent
  92. {
  93. public:
  94. CFaxEventLegacy(const FAX_EVENT* pEvent);
  95. virtual ~CFaxEventLegacy ()
  96. {
  97. MemFree ((void*)m_pEvent);
  98. m_pEvent = NULL;
  99. }
  100. virtual CFaxEvent* Clone() const
  101. {
  102. DEBUG_FUNCTION_NAME(TEXT("CFaxEventLegacy::Clone"));
  103. CFaxEventLegacy* pFaxLegacyEvent = NULL;
  104. try
  105. {
  106. pFaxLegacyEvent = new (std::nothrow) CFaxEventLegacy (m_pEvent);
  107. }
  108. catch (exception &ex)
  109. {
  110. DebugPrintEx(DEBUG_ERR,
  111. TEXT("Exception: %S"),
  112. ex.what()
  113. );
  114. }
  115. return pFaxLegacyEvent;
  116. }
  117. virtual DWORD GetEvent (LPBYTE* lppBuffer, LPDWORD lpdwBufferSize) const;
  118. virtual BOOL MatchEvent(PSID pUserSid, DWORD dwEvenTtype, BOOL bAllQueueMessages, BOOL bAllOutArchiveMessages) const;
  119. private:
  120. const FAX_EVENT* m_pEvent;
  121. }; // CFaxEventExtended
  122. /************************************
  123. * *
  124. * CClientID *
  125. * *
  126. ************************************/
  127. class CClientID
  128. {
  129. public:
  130. CClientID (DWORDLONG dwlClientID, LPCWSTR lpcwstrMachineName, LPCWSTR lpcwstrEndPoint, ULONG64 Context)
  131. {
  132. HRESULT hr;
  133. Assert (lpcwstrMachineName && lpcwstrEndPoint && Context);
  134. m_dwlClientID = dwlClientID;
  135. hr = StringCchCopy (m_wstrMachineName, ARR_SIZE(m_wstrMachineName), lpcwstrMachineName);
  136. if (FAILED(hr))
  137. {
  138. ASSERT_FALSE;
  139. }
  140. hr = StringCchCopy (m_wstrEndPoint, ARR_SIZE(m_wstrEndPoint), lpcwstrEndPoint);
  141. if (FAILED(hr))
  142. {
  143. ASSERT_FALSE;
  144. }
  145. m_Context = Context;
  146. }
  147. CClientID (const CClientID& rhs)
  148. {
  149. m_dwlClientID = rhs.m_dwlClientID;
  150. wcscpy (m_wstrMachineName, rhs.m_wstrMachineName);
  151. wcscpy (m_wstrEndPoint, rhs.m_wstrEndPoint);
  152. m_Context = rhs.m_Context;
  153. }
  154. ~CClientID ()
  155. {
  156. ZeroMemory (this, sizeof(CClientID));
  157. }
  158. bool operator < ( const CClientID &other ) const;
  159. CClientID& operator= (const CClientID& rhs)
  160. {
  161. if (this == &rhs)
  162. {
  163. return *this;
  164. }
  165. m_dwlClientID = rhs.m_dwlClientID;
  166. wcscpy (m_wstrMachineName, rhs.m_wstrMachineName);
  167. wcscpy (m_wstrEndPoint, rhs.m_wstrEndPoint);
  168. m_Context = rhs.m_Context;
  169. return *this;
  170. }
  171. ULONG64 GetContext() const { return m_Context; }
  172. DWORDLONG GetID() const { return m_dwlClientID; }
  173. private:
  174. DWORDLONG m_dwlClientID;
  175. WCHAR m_wstrMachineName[MAX_COMPUTERNAME_LENGTH + 1]; // Machine name
  176. WCHAR m_wstrEndPoint[MAX_ENDPOINT_LEN]; // End point used for RPC connection
  177. ULONG64 m_Context; // context (Client assync info)
  178. }; // CClientID
  179. typedef queue<CFaxEvent*> CLIENT_EVENTS, *PCLIENT_EVENTS;
  180. /************************************
  181. * *
  182. * CClient *
  183. * *
  184. ************************************/
  185. class CClient
  186. {
  187. public:
  188. CClient (CClientID ClientID,
  189. PSID pUserSid,
  190. DWORD dwEventTypes,
  191. HANDLE hFaxHandle,
  192. BOOL bAllQueueMessages,
  193. BOOL bAllOutArchiveMessages,
  194. DWORD dwAPIVersion);
  195. CClient (const CClient& rhs);
  196. ~CClient ();
  197. CClient& operator= (const CClient& rhs);
  198. const CClientID& GetClientID () const { return m_ClientID; }
  199. DWORD AddEvent (CFaxEvent* pFaxEvent);
  200. DWORD GetEvent (LPBYTE* lppBuffer, LPDWORD lpdwBufferSize, PHANDLE phClientContext) const;
  201. DWORD DelEvent ();
  202. BOOL IsConnectionOpened() const { return (m_hFaxClientContext != NULL); }
  203. VOID SetContextHandle(HANDLE hContextHandle) { m_hFaxClientContext = hContextHandle; }
  204. HANDLE GetContextHandle () const { return m_hFaxClientContext; }
  205. HANDLE GetFaxHandle() const { return m_FaxHandle; }
  206. DWORD GetAPIVersion() const { return m_dwAPIVersion; }
  207. BOOL IsLegacyClient() const { return (FAX_EVENT_TYPE_LEGACY == m_dwEventTypes); }
  208. DWORD Release() { return (m_dwRefCount ? --m_dwRefCount : 1); } // There might be race between 2 or more threads trying to destroy the same client
  209. VOID Lock() { m_dwRefCount++; }
  210. DWORD GetRefCount()const { return m_dwRefCount; }
  211. private:
  212. HANDLE m_FaxHandle; // binding handle FaxBindToFaxClient
  213. DWORD m_dwEventTypes; // Bit wise combination of FAX_ENUM_EVENT_TYPE
  214. PSID m_pUserSid; // Pointer to the user SID
  215. CLIENT_EVENTS m_Events;
  216. HANDLE m_hFaxClientContext; // Client context handle
  217. CClientID m_ClientID;
  218. BOOL m_bPostClientID; // Flag that indicates whether to notify the service (using the events
  219. // completion port) that this client has events.
  220. BOOL m_bAllQueueMessages; // flag that indicates Outbox view rights.
  221. BOOL m_bAllOutArchiveMessages; // flag that indicates Sent items view rights.
  222. DWORD m_dwAPIVersion; // API version of the client
  223. DWORD m_dwRefCount; // Handles the object refernce count
  224. }; // CClient
  225. typedef CClient *PCCLIENT;
  226. /***********************************\
  227. * *
  228. * CClientsMap *
  229. * *
  230. \***********************************/
  231. typedef map<CClientID, CClient> CLIENTS_MAP, *PCLIENTS_MAP;
  232. //
  233. // The CClientsMap class maps between client ID and a specific client
  234. //
  235. class CClientsMap
  236. {
  237. public:
  238. CClientsMap () {}
  239. ~CClientsMap () {}
  240. DWORD AddClient (const CClient& Client);
  241. DWORD ReleaseClient (const CClientID& ClientID, BOOL fRunDown = FALSE);
  242. PCCLIENT FindClient (const CClientID& ClientID) const;
  243. DWORD AddEvent (CFaxEvent* pFaxEvent);
  244. DWORD Notify (const CClientID& ClientID);
  245. DWORD OpenClientConnection (const CClientID& ClientID);
  246. private:
  247. CLIENTS_MAP m_ClientsMap;
  248. }; // CClientsMap
  249. /************************************
  250. * *
  251. * Externes *
  252. * *
  253. ************************************/
  254. extern CClientsMap* g_pClientsMap; // Map of clients ID to client.
  255. extern HANDLE g_hDispatchEventsCompPort; // Events completion port. The events are dispatched to the client in the client map.
  256. extern HANDLE g_hSendEventsCompPort; // Completion port of client IDs that have events in their queue.
  257. //The events mechanism uses 2 completion ports.
  258. // 1. g_hDispatchEventsCompPort, is monitored by 1 thread only!!!, and is responsible for dispatching the events to each one of the registered clients events queue. It is important that only 1 thread will dispatch the events, so the order of the events will be retained.
  259. // 2. g_hSendEventsCompPort is monitored by TOTAL_EVENTS_THREADS, and is responsible for sending the events to the remote clients over RPC.
  260. extern DWORDLONG g_dwlClientID; // Client ID
  261. //
  262. // IMPORTANT - No locking mechanism - USE g_CsClients to serialize calls to g_pClientsMap
  263. //
  264. #endif