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.

352 lines
8.5 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: DPNSVRQ.h
  6. * Content: DirectPlay8 Server Queues Header
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 03/19/00 rmt Modified from dplmsgq
  12. * 04/03/2001 RichGr Bug #325752 - Improved Queue mutex so opens, updates and closes don't clash.
  13. *@@END_MSINTERNAL
  14. *
  15. ***************************************************************************/
  16. #ifndef __DPNSVRQ_H__
  17. #define __DPNSVRQ_H__
  18. #define DPNSVR_MSGQ_SIGNATURE 'QMSD'
  19. //**********************************************************************
  20. // Constant definitions
  21. //**********************************************************************
  22. #define DPNSVR_MSGQ_OBJECT_IDCHAR_FILEMAP 'F'
  23. #define DPNSVR_MSGQ_OBJECT_IDCHAR_MUTEX 'M'
  24. #define DPNSVR_MSGQ_OBJECT_IDCHAR_EVENT 'E'
  25. #define DPNSVR_MSGQ_OBJECT_IDCHAR_EVENT2 'V'
  26. #define DPNSVR_MSGQ_OBJECT_IDCHAR_SEMAPHORE 'S'
  27. //
  28. // Message Queue Flags
  29. //
  30. #define DPNSVR_MSGQ_FLAG_AVAILABLE 0x00001
  31. #define DPNSVR_MSGQ_FLAG_RECEIVING 0x00010
  32. #define DPNSVR_MSGQ_OPEN_FLAG_NO_CREATE 0x10000
  33. //
  34. // Message Queue File Size
  35. //
  36. #define DPNSVR_MSGQ_SIZE 0x010000
  37. //
  38. // Internal Message IDs
  39. //
  40. #define DPNSVR_MSGQ_MSGID_SEND 0x0001
  41. #define DPNSVR_MSGQ_MSGID_TERMINATE 0x0003
  42. #define DPNSVR_MSGQ_MSGID_IDLE 0x0004
  43. #define DPNSVR_MSGQ_MSGFLAGS_QUEUESYSTEM 0x0001
  44. #define DPNSVR_MSGQ_MSGFLAGS_USER1 0x0002
  45. #define DPNSVR_MSGQ_MSGFLAGS_USER2 0x0004
  46. //**********************************************************************
  47. // Macro definitions
  48. //**********************************************************************
  49. //**********************************************************************
  50. // Structure definitions
  51. //**********************************************************************
  52. #pragma pack(push,4)
  53. //
  54. // Message Queue File Map Info
  55. //
  56. typedef struct _DPNSVR_MSGQ_INFO
  57. {
  58. DWORD dwFlags; // Queue usage flags
  59. DWORD dwStartOffset;
  60. DWORD dwEndOffset;
  61. DWORD dwFreeBytes;
  62. DWORD dwQueueSize;
  63. LONG lRefCount; // Number of connections
  64. } DPNSVR_MSGQ_INFO, *PDPNSVR_MSGQ_INFO;
  65. //
  66. // Message Queue Send Message
  67. //
  68. typedef struct _DPNSVR_MSGQ_SEND
  69. {
  70. DWORD dwCurrentSize; // Size of this frame (in BYTES)
  71. DWORD dwTotalSize; // Total size of message
  72. DWORD dwMsgId; // Message ID
  73. DPNHANDLE hSender;
  74. DWORD dwFlags;
  75. DWORD dwCurrentOffset; // Offset of this frame in message
  76. } DPNSVR_MSGQ_HEADER, *PDPNSVR_MSGQ_HEADER;
  77. //
  78. // Message Queue Terminate Message
  79. //
  80. typedef struct _DPNSVR_MSGQ_TERMINATE
  81. {
  82. DWORD dwMsgId;
  83. } DPNSVR_MSGQ_TERMINATE, *PDPNSVR_MSGQ_TERMINATE;
  84. #pragma pack(pop)
  85. //
  86. // Message Handler Callback
  87. //
  88. typedef HRESULT (*PFNDPNSVRMSGQMESSAGEHANDLER)(DPNHANDLE,const PVOID,DWORD,BYTE *const,const DWORD);
  89. //**********************************************************************
  90. // Variable definitions
  91. //**********************************************************************
  92. //**********************************************************************
  93. // Function prototypes
  94. //**********************************************************************
  95. //**********************************************************************
  96. // Class prototypes
  97. //**********************************************************************
  98. class CDPNSVRIPCQueue
  99. {
  100. public:
  101. CDPNSVRIPCQueue()
  102. {
  103. m_hFileMap = NULL;
  104. m_hEvent = NULL;
  105. m_hQueueGUIDMutex = NULL;
  106. m_hSemaphore = NULL;
  107. m_pFileMapAddress = NULL;
  108. m_pInfo = NULL;
  109. m_pData = NULL;
  110. m_hSender = NULL;
  111. m_pfnMessageHandler = NULL;
  112. m_pvSenderContext = NULL;
  113. m_hReceiveThreadRunningEvent = NULL;
  114. };
  115. ~CDPNSVRIPCQueue() { };
  116. void SetMessageHandler(DPNHANDLE hSender,PFNDPNSVRMSGQMESSAGEHANDLER pfn)
  117. {
  118. m_hSender = hSender;
  119. m_pfnMessageHandler = pfn;
  120. };
  121. void SetSenderContext(PVOID pvSenderContext)
  122. {
  123. m_pvSenderContext = pvSenderContext;
  124. };
  125. HRESULT CallMessageHandler(const PVOID pvSenderContext,DWORD dwMessageFlags,BYTE *const pBuffer,const DWORD dwBufferSize)
  126. {
  127. return((m_pfnMessageHandler)(m_hSender,pvSenderContext,dwMessageFlags,pBuffer,dwBufferSize));
  128. };
  129. HRESULT Open(const GUID * const pguidQueueName, const DWORD dwQueueSize, const DWORD dwFlags);
  130. void Close(void);
  131. void CloseHandles(void);
  132. LONG GetRefCount(void)
  133. {
  134. DWORD lRefCount;
  135. if (m_pInfo == NULL)
  136. {
  137. return(0);
  138. }
  139. Lock();
  140. lRefCount = m_pInfo->lRefCount;
  141. Unlock();
  142. return(lRefCount);
  143. };
  144. HRESULT AddData( BYTE *const pBuffer,const DWORD dwSize );
  145. HRESULT Send(BYTE *const pBuffer,const DWORD dwSize,const DWORD dwTimeOut,const DWORD dwMessageFlags,const DWORD dwFlags);
  146. void Lock(void)
  147. {
  148. DNWaitForSingleObject(m_hQueueGUIDMutex,INFINITE);
  149. };
  150. void Unlock(void)
  151. {
  152. DNReleaseMutex(m_hQueueGUIDMutex);
  153. };
  154. void WaitForMessages(void)
  155. {
  156. DNWaitForSingleObject(m_hSemaphore,INFINITE);
  157. };
  158. void IndicateMessage(void)
  159. {
  160. DNReleaseSemaphore(m_hSemaphore,1,NULL);
  161. };
  162. BOOL WaitForConsumption(const DWORD dwTimeOut)
  163. {
  164. DWORD dwError;
  165. dwError = DNWaitForSingleObject(m_hEvent,dwTimeOut);
  166. if (dwError==WAIT_OBJECT_0)
  167. {
  168. return(TRUE);
  169. }
  170. return(FALSE);
  171. };
  172. void IndicateConsumption(void)
  173. {
  174. //DNSetEvent(m_hEvent); // Will auto-reset (i.e. pulse)
  175. DNReleaseSemaphore( m_hEvent, 1, NULL );
  176. };
  177. void MakeAvailable(void)
  178. {
  179. Lock();
  180. m_pInfo->dwFlags |= DPNSVR_MSGQ_FLAG_AVAILABLE;
  181. Unlock();
  182. };
  183. HRESULT MakeUnavailable(void)
  184. {
  185. HRESULT hResultCode;
  186. Lock();
  187. if (m_pInfo->dwFlags & DPNSVR_MSGQ_FLAG_AVAILABLE)
  188. {
  189. m_pInfo->dwFlags &= (~DPNSVR_MSGQ_FLAG_AVAILABLE);
  190. hResultCode = DPN_OK;
  191. }
  192. else
  193. {
  194. hResultCode = DPNERR_ALREADYCONNECTED;
  195. }
  196. Unlock();
  197. return(hResultCode);
  198. };
  199. void MakeReceiving(void)
  200. {
  201. Lock();
  202. m_pInfo->dwFlags |= DPNSVR_MSGQ_FLAG_RECEIVING;
  203. Unlock();
  204. DNSetEvent(m_hReceiveThreadRunningEvent);
  205. };
  206. void MakeNotReceiving(void)
  207. {
  208. DNResetEvent(m_hReceiveThreadRunningEvent);
  209. Lock();
  210. m_pInfo->dwFlags &= (~DPNSVR_MSGQ_FLAG_RECEIVING);
  211. Unlock();
  212. };
  213. BOOL WaitForReceiveThread(const DWORD dwTimeOut)
  214. {
  215. DWORD dwError;
  216. dwError = DNWaitForSingleObject(m_hReceiveThreadRunningEvent,dwTimeOut);
  217. if (dwError==WAIT_OBJECT_0)
  218. {
  219. return(TRUE);
  220. }
  221. return(FALSE);
  222. };
  223. BOOL IsOpen(void) const
  224. {
  225. if (m_hFileMap!= NULL)
  226. {
  227. return(TRUE);
  228. }
  229. return(FALSE);
  230. };
  231. BOOL IsAvailable(void) const
  232. {
  233. if (m_pInfo->dwFlags & DPNSVR_MSGQ_FLAG_AVAILABLE)
  234. {
  235. return(TRUE);
  236. }
  237. return(FALSE);
  238. };
  239. BOOL IsReceiving(void) const
  240. {
  241. if (m_pInfo->dwFlags & DPNSVR_MSGQ_FLAG_RECEIVING)
  242. {
  243. return(TRUE);
  244. }
  245. };
  246. HRESULT GetNextMessage( PDPNSVR_MSGQ_HEADER pMsgHeader, PBYTE pbPayload, DWORD *pdwBufferSize );
  247. void Terminate(void);
  248. DNHANDLE GetReceiveSemaphoreHandle() { return m_hSemaphore; };
  249. private:
  250. // GetData
  251. //
  252. // Get dwSize bytes from the queue. If the queue is empty this function will return
  253. // DPNERR_DOESNOTEXIST. Once this function returns the dwSize bytes will be consumed
  254. //
  255. // Needs LOCK()
  256. //
  257. HRESULT GetData( BYTE *pbData, DWORD dwSize );
  258. // Consume
  259. //
  260. // Marks dwSize bytes as consumed
  261. //
  262. // Needs LOCK()
  263. void Consume( const DWORD dwSize );
  264. DWORD m_dwSig; // Signature (ensure initialized)
  265. PBYTE m_pFileMapAddress; // File Mapping address
  266. DPNSVR_MSGQ_INFO *m_pInfo; // Message queue file mapping info
  267. PBYTE m_pData; // Message data starts here
  268. DNHANDLE m_hReceiveThreadRunningEvent;
  269. // Notes:
  270. // Each message queue has four shared memory items: file map, mutex, event, semaphore.
  271. // The file map is a circular queue of messages.
  272. // The mutex controls access to the file map.
  273. // The event signals when an item has been taken off the queue by the consumer.
  274. // The semaphore indicates to the consumer that there are messages in the queue
  275. DNHANDLE m_hFileMap; // File Mapping handle
  276. DNHANDLE m_hQueueGUIDMutex; // Mutex handle
  277. DNHANDLE m_hEvent; // Event handle
  278. DNHANDLE m_hSemaphore; // Semaphore handle
  279. PFNDPNSVRMSGQMESSAGEHANDLER m_pfnMessageHandler;
  280. DPNHANDLE m_hSender;
  281. PVOID m_pvSenderContext; // For all SEND messages
  282. };
  283. #undef DPF_MODNAME
  284. #undef DPF_SUBCOMP
  285. #endif // __DPLMSGQ_H__