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.

453 lines
11 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: DPLMsgQ.h
  6. * Content: DirectPlay Lobby Message Queues Header File
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 02/21/00 mjn Created
  12. * 04/26/00 mjn Fixed AddData() to return HRESULT
  13. * 07/07/2000 rmt
  14. *@@END_MSINTERNAL
  15. *
  16. ***************************************************************************/
  17. #ifndef __DPLMSGQ_H__
  18. #define __DPLMSGQ_H__
  19. //**********************************************************************
  20. // Constant definitions
  21. //**********************************************************************
  22. //
  23. // Message Queue Object IDs
  24. //
  25. #define DPL_MSGQ_OBJECT_IDCHAR_FILEMAP _T('F')
  26. #define DPL_MSGQ_OBJECT_IDCHAR_MUTEX _T('M')
  27. #define DPL_MSGQ_OBJECT_IDCHAR_EVENT _T('E')
  28. #define DPL_MSGQ_OBJECT_IDCHAR_EVENT2 _T('V')
  29. #define DPL_MSGQ_OBJECT_IDCHAR_SEMAPHORE _T('S')
  30. //
  31. // Message Queue Object Suffixes
  32. //
  33. #define DPL_MSGQ_OBJECT_SUFFIX_CLIENT _T('C')
  34. #define DPL_MSGQ_OBJECT_SUFFIX_APPLICATION _T('A')
  35. //
  36. // Message Queue Flags
  37. //
  38. #define DPL_MSGQ_FLAG_AVAILABLE 0x00001
  39. #define DPL_MSGQ_FLAG_RECEIVING 0x00010
  40. #define DPL_MSGQ_OPEN_FLAG_NO_CREATE 0x10000
  41. //
  42. // Message Queue File Size
  43. //
  44. // Increased so user can send a 64K message
  45. #define DPL_MSGQ_SIZE 0x010030
  46. //
  47. // Internal Message IDs
  48. //
  49. #define DPL_MSGQ_MSGID_SEND 0x0001
  50. #define DPL_MSGQ_MSGID_TERMINATE 0x0003
  51. #define DPL_MSGQ_MSGID_IDLE 0x0004
  52. #define DPL_MSGQ_MSGFLAGS_QUEUESYSTEM 0x0001
  53. #define DPL_MSGQ_MSGFLAGS_USER1 0x0002
  54. #define DPL_MSGQ_MSGFLAGS_USER2 0x0004
  55. #define DPL_MSGQ_SIGNATURE 'QMLD'
  56. #undef DPF_SUBCOMP
  57. #define DPF_SUBCOMP DN_SUBCOMP_LOBBY
  58. //**********************************************************************
  59. // Macro definitions
  60. //**********************************************************************
  61. //**********************************************************************
  62. // Structure definitions
  63. //**********************************************************************
  64. #pragma pack(push,4)
  65. //
  66. // Message Queue File Map Info
  67. //
  68. typedef struct _DPL_MSGQ_INFO
  69. {
  70. DWORD dwFlags; // Queue usage flags
  71. DWORD dwStartOffset;
  72. DWORD dwEndOffset;
  73. DWORD dwFreeBytes;
  74. DWORD dwQueueSize;
  75. LONG lRefCount; // Number of connections
  76. } DPL_MSGQ_INFO, *PDPL_MSGQ_INFO;
  77. //
  78. // Message Queue Send Message
  79. //
  80. typedef struct _DPL_MSGQ_SEND
  81. {
  82. DWORD dwCurrentSize; // Size of this frame (in BYTES)
  83. DWORD dwTotalSize; // Total size of message
  84. DWORD dwMsgId; // Message ID
  85. DPNHANDLE hSender;
  86. DWORD dwFlags;
  87. DWORD dwCurrentOffset; // Offset of this frame in message
  88. } DPL_MSGQ_HEADER, *PDPL_MSGQ_HEADER;
  89. //
  90. // Message Queue Terminate Message
  91. //
  92. typedef struct _DPL_MSGQ_TERMINATE
  93. {
  94. DWORD dwMsgId;
  95. } DPL_MSGQ_TERMINATE, *PDPL_MSGQ_TERMINATE;
  96. #pragma pack(pop)
  97. //
  98. // Message Handler Callback
  99. //
  100. typedef HRESULT (*PFNDPLMSGQMESSAGEHANDLER)(PVOID,const DPNHANDLE,DWORD, BYTE *const,const DWORD);
  101. //**********************************************************************
  102. // Variable definitions
  103. //**********************************************************************
  104. //**********************************************************************
  105. // Function prototypes
  106. //**********************************************************************
  107. BOOL DPLIsApplicationAvailable(const DWORD dwPid);
  108. HRESULT DPLMakeApplicationUnavailable(const DWORD dwPid);
  109. DWORD WINAPI DPLProcessMessageQueue(PVOID pvReceiveQueue);
  110. //**********************************************************************
  111. // Class prototypes
  112. //**********************************************************************
  113. class CMessageQueue
  114. {
  115. public:
  116. CMessageQueue()
  117. {
  118. m_dwPID = 0;
  119. m_hFileMap = NULL;
  120. m_hEvent = NULL;
  121. m_hMutex = NULL;
  122. m_hSemaphore = NULL;
  123. m_pFileMapAddress = NULL;
  124. m_pInfo = NULL;
  125. m_pvContext = NULL;
  126. m_pfnMessageHandler = NULL;
  127. m_hSender = 0xFFFFFFFF;
  128. m_hReceiveThreadRunningEvent = NULL;
  129. m_dwIdleTimeout = INFINITE;
  130. };
  131. // ~CMessageQueue() { };
  132. #undef DPF_MODNAME
  133. #define DPF_MODNAME "CMessageQueue::SetMessageHandler"
  134. void CMessageQueue::SetMessageHandler(PVOID pvContext,PFNDPLMSGQMESSAGEHANDLER pfn )
  135. {
  136. DNASSERT(pfn != NULL);
  137. m_pvContext = pvContext;
  138. m_pfnMessageHandler = pfn;
  139. };
  140. void CMessageQueue::SetSenderHandle(DPNHANDLE hSender)
  141. {
  142. m_hSender = hSender;
  143. };
  144. #undef DPF_MODNAME
  145. #define DPF_MODNAME "CMessageQueue::CallMessageHandler"
  146. HRESULT CMessageQueue::CallMessageHandler(const DPNHANDLE hSender,
  147. DWORD dwMessageFlags,
  148. BYTE *const pBuffer,
  149. const DWORD dwBufferSize)
  150. {
  151. DNASSERT(m_pfnMessageHandler != NULL);
  152. return((m_pfnMessageHandler)(m_pvContext,hSender,dwMessageFlags,pBuffer,dwBufferSize));
  153. };
  154. HRESULT CMessageQueue::Open(const DWORD dwPID,
  155. const TCHAR cSuffix,
  156. const DWORD dwQueueSize,
  157. const DWORD dwIdleTimeout,
  158. const DWORD dwFlags
  159. );
  160. void CMessageQueue::Close(void);
  161. LONG CMessageQueue::GetRefCount(void)
  162. {
  163. DWORD lRefCount;
  164. if (m_pInfo == NULL)
  165. return(0);
  166. Lock();
  167. lRefCount = m_pInfo->lRefCount;
  168. Unlock();
  169. return(lRefCount);
  170. };
  171. HRESULT CMessageQueue::AddData(BYTE *const pBuffer,
  172. const DWORD dwSize);
  173. HRESULT CMessageQueue::Send(BYTE *const pBuffer,
  174. const DWORD dwSize,
  175. const DWORD dwTimeOut,
  176. const DWORD dwMessageFlags,
  177. const DWORD dwFlags);
  178. #undef DPF_MODNAME
  179. #define DPF_MODNAME "CMessageQueue::Lock"
  180. void CMessageQueue::Lock(void)
  181. {
  182. DNASSERT(m_hMutex != NULL);
  183. DNWaitForSingleObject(m_hMutex,INFINITE);
  184. };
  185. #undef DPF_MODNAME
  186. #define DPF_MODNAME "CMessageQueue::Unlock"
  187. void CMessageQueue::Unlock(void)
  188. {
  189. DNASSERT(m_hMutex != NULL);
  190. DNReleaseMutex(m_hMutex);
  191. };
  192. #undef DPF_MODNAME
  193. #define DPF_MODNAME "CMessageQueue::WaitForMessages"
  194. DWORD CMessageQueue::WaitForMessages(void)
  195. {
  196. DNASSERT(m_hSemaphore != NULL);
  197. return DNWaitForSingleObject(m_hSemaphore,m_dwIdleTimeout);
  198. };
  199. #undef DPF_MODNAME
  200. #define DPF_MODNAME "CMessageQueue::IndicateMessage"
  201. void CMessageQueue::IndicateMessage(void)
  202. {
  203. DNASSERT(m_hSemaphore != NULL);
  204. DNReleaseSemaphore(m_hSemaphore,1,NULL);
  205. };
  206. #undef DPF_MODNAME
  207. #define DPF_MODNAME "CMessageQueue::WaitForConsumption"
  208. BOOL CMessageQueue::WaitForConsumption(const DWORD dwTimeOut)
  209. {
  210. DWORD dwError;
  211. DNASSERT(m_hEvent != NULL);
  212. dwError = DNWaitForSingleObject(m_hEvent,dwTimeOut);
  213. if (dwError==WAIT_OBJECT_0)
  214. {
  215. return(TRUE);
  216. }
  217. return(FALSE);
  218. };
  219. #undef DPF_MODNAME
  220. #define DPF_MODNAME "CMessageQueue::IndicateConsumption"
  221. void CMessageQueue::IndicateConsumption(void)
  222. {
  223. DNASSERT(m_hEvent != NULL);
  224. //DNSetEvent(m_hEvent); // Will auto-reset (i.e. pulse)
  225. DNReleaseSemaphore( m_hEvent, 1, NULL );
  226. };
  227. #undef DPF_MODNAME
  228. #define DPF_MODNAME "CMessageQueue::MakeAvailable"
  229. void CMessageQueue::MakeAvailable(void)
  230. {
  231. DNASSERT(m_pInfo != NULL);
  232. Lock();
  233. m_pInfo->dwFlags |= DPL_MSGQ_FLAG_AVAILABLE;
  234. Unlock();
  235. };
  236. #undef DPF_MODNAME
  237. #define DPF_MODNAME "CMessageQueue::MakeUnavailable"
  238. HRESULT CMessageQueue::MakeUnavailable(void)
  239. {
  240. HRESULT hResultCode;
  241. DNASSERT(m_pInfo != NULL);
  242. Lock();
  243. if (m_pInfo->dwFlags & DPL_MSGQ_FLAG_AVAILABLE)
  244. {
  245. m_pInfo->dwFlags &= (~DPL_MSGQ_FLAG_AVAILABLE);
  246. hResultCode = DPN_OK;
  247. }
  248. else
  249. {
  250. hResultCode = DPNERR_ALREADYCONNECTED;
  251. }
  252. Unlock();
  253. return(hResultCode);
  254. };
  255. #undef DPF_MODNAME
  256. #define DPF_MODNAME "CMessageQueue::MakeReceiving"
  257. void CMessageQueue::MakeReceiving(void)
  258. {
  259. DNASSERT(m_pInfo != NULL);
  260. Lock();
  261. m_pInfo->dwFlags |= DPL_MSGQ_FLAG_RECEIVING;
  262. Unlock();
  263. DNSetEvent(m_hReceiveThreadRunningEvent);
  264. };
  265. #undef DPF_MODNAME
  266. #define DPF_MODNAME "CMessageQueue::MakeNotReceiving"
  267. void CMessageQueue::MakeNotReceiving(void)
  268. {
  269. DNASSERT(m_pInfo != NULL);
  270. DNResetEvent(m_hReceiveThreadRunningEvent);
  271. Lock();
  272. m_pInfo->dwFlags &= (~DPL_MSGQ_FLAG_RECEIVING);
  273. Unlock();
  274. };
  275. #undef DPF_MODNAME
  276. #define DPF_MODNAME "CMessageQueue::WaitForReceiveThread"
  277. BOOL CMessageQueue::WaitForReceiveThread(const DWORD dwTimeOut)
  278. {
  279. DWORD dwError;
  280. DNASSERT(m_hEvent != NULL);
  281. dwError = DNWaitForSingleObject(m_hReceiveThreadRunningEvent,dwTimeOut);
  282. if (dwError==WAIT_OBJECT_0)
  283. {
  284. return(TRUE);
  285. }
  286. return(FALSE);
  287. };
  288. #undef DPF_MODNAME
  289. #define DPF_MODNAME "CMessageQueue::IsOpen"
  290. BOOL CMessageQueue::IsOpen(void) const
  291. {
  292. if (m_hFileMap!= NULL) return(TRUE);
  293. else return(FALSE);
  294. };
  295. #undef DPF_MODNAME
  296. #define DPF_MODNAME "CMessageQueue::IsAvailable"
  297. BOOL CMessageQueue::IsAvailable(void) const
  298. {
  299. DNASSERT(m_pInfo != NULL);
  300. if (m_pInfo->dwFlags & DPL_MSGQ_FLAG_AVAILABLE)
  301. return(TRUE);
  302. else
  303. return(FALSE);
  304. };
  305. #undef DPF_MODNAME
  306. #define DPF_MODNAME "CMessageQueue::IsReceiving"
  307. BOOL CMessageQueue::IsReceiving(void) const
  308. {
  309. DNASSERT(m_pInfo != NULL);
  310. if (m_pInfo->dwFlags & DPL_MSGQ_FLAG_RECEIVING)
  311. return(TRUE);
  312. else
  313. return(FALSE);
  314. };
  315. HRESULT GetNextMessage( PDPL_MSGQ_HEADER pMsgHeader, PBYTE pbPayload, DWORD *pdwBufferSize );
  316. /*
  317. #undef DPF_MODNAME
  318. #define DPF_MODNAME "CMessageQueue::Realign"
  319. void CMessageQueue::Realign(void)
  320. {
  321. DNASSERT(m_pInfo != NULL);
  322. m_pInfo->dwFirstMsgOffset = 0;
  323. m_pInfo->dwFreeSpaceAtEnd = m_pInfo->dwTotalUsableSpace
  324. - (m_pInfo->dwNextFreeOffset - m_pInfo->dwFirstMsgOffset);
  325. m_pInfo->dwTotalFreeSpace = m_pInfo->dwFreeSpaceAtEnd;
  326. };*/
  327. void CMessageQueue::Terminate(void);
  328. private:
  329. // GetData
  330. //
  331. // Get dwSize bytes from the queue. If the queue is empty this function will return
  332. // DPNERR_DOESNOTEXIST. Once this function returns the dwSize bytes will be consumed
  333. //
  334. // Needs LOCK()
  335. //
  336. HRESULT GetData( BYTE *pbData, DWORD dwSize );
  337. // Consume
  338. //
  339. // Marks dwSize bytes as consumed
  340. //
  341. // Needs LOCK()
  342. void Consume( const DWORD dwSize );
  343. DWORD m_dwSig; // Signature (ensure initialized)
  344. DWORD m_dwPID; // Queue PID
  345. PBYTE m_pFileMapAddress; // File Mapping address
  346. DPL_MSGQ_INFO *m_pInfo; // Message queue file mapping info
  347. PBYTE m_pData; // Message data starts here
  348. DNHANDLE m_hReceiveThreadRunningEvent;
  349. // Notes:
  350. // Each message queue has four shared memory items: file map, mutex, event, semaphore.
  351. // The file map is a circular queue of messages.
  352. // The mutex controls access to the file map.
  353. // The event signals when an item has been taken off the queue by the consumer.
  354. // The semaphore indicates to the consumer that there are messages in the queue
  355. DNHANDLE m_hFileMap; // File Mapping handle
  356. DNHANDLE m_hMutex; // Mutex handle
  357. DNHANDLE m_hEvent; // Event handle
  358. DNHANDLE m_hSemaphore; // Semaphore handle
  359. PFNDPLMSGQMESSAGEHANDLER m_pfnMessageHandler;
  360. PVOID m_pvContext;
  361. DPNHANDLE m_hSender; // For all SEND messages
  362. DWORD m_dwIdleTimeout; // Amount of time between idle messages
  363. };
  364. #undef DPF_MODNAME
  365. #endif // __DPLMSGQ_H__