Source code of Windows XP (NT5)
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.

387 lines
9.2 KiB

  1. #ifndef WIN32_LEAN_AND_MEAN
  2. #define WIN32_LEAN_AND_MEAN
  3. #endif
  4. #include <windows.h>
  5. #include <windowsx.h>
  6. #include <winsock.h>
  7. #ifndef _MT
  8. #define _MT
  9. #endif
  10. #include <dplay.h>
  11. #include <logit.h>
  12. DWORD dwMsgSeq = 1;
  13. DWORD dwQMsgs = 0;
  14. DWORD dwMsgIndx = 0;
  15. DWORD dwMaxMsgs;
  16. static CRITICAL_SECTION q_Section;
  17. typedef struct
  18. {
  19. DWORD dwSeq;
  20. DWORD dwSize;
  21. BOOL bValid;
  22. DWORD dwIndex;
  23. DPID pidTo;
  24. DPID pidFrom;
  25. } MSG_ARRAY;
  26. typedef struct
  27. {
  28. DWORD dwCount;
  29. DPID pid;
  30. HANDLE hEvent;
  31. } PLAYER_NOTIFY;
  32. char *pmsgElements = NULL;
  33. MSG_ARRAY *pmsgArray = NULL;
  34. PLAYER_NOTIFY *aNotify = NULL;
  35. HANDLE hSystemMsg = NULL;
  36. #define malloc(a) LocalAlloc(LMEM_FIXED, (a))
  37. #define free(a) LocalFree((HLOCAL)(a))
  38. #define min(a,b) (((a) < (b)) ? (a) : (b))
  39. #define max(a,b) (((a) > (b)) ? (a) : (b))
  40. DWORD g_maxMsg = 0;
  41. DWORD g_maxPlayers = 0;
  42. BOOL CreateQueue(DWORD dwElements, DWORD dwmaxMsg, DWORD dwmaxPlayers)
  43. {
  44. DWORD ii;
  45. if (pmsgElements)
  46. return(FALSE);
  47. pmsgElements = (char *) malloc(dwElements * dwmaxMsg);
  48. pmsgArray = (MSG_ARRAY *) malloc(dwElements * sizeof(MSG_ARRAY));
  49. aNotify = (PLAYER_NOTIFY *) malloc(dwmaxPlayers * sizeof(PLAYER_NOTIFY));
  50. if (!pmsgElements || !pmsgArray || !aNotify)
  51. {
  52. if (pmsgElements)
  53. free(pmsgElements);
  54. if (pmsgArray)
  55. free(pmsgArray);
  56. if (aNotify)
  57. free(aNotify);
  58. pmsgElements = NULL;
  59. pmsgArray = NULL;
  60. aNotify = NULL;
  61. return(FALSE);
  62. }
  63. for (ii = 0; ii < dwmaxPlayers; ii++)
  64. {
  65. aNotify[ii].dwCount = 0;
  66. aNotify[ii].pid = 0;
  67. aNotify[ii].hEvent = 0;
  68. }
  69. for (ii = 0; ii < dwElements; ii++)
  70. {
  71. pmsgArray[ii].dwSeq = 0;
  72. pmsgArray[ii].bValid = FALSE;
  73. pmsgArray[ii].dwIndex = ii;
  74. pmsgArray[ii].pidTo = 0;
  75. pmsgArray[ii].pidFrom = 0;
  76. }
  77. dwMaxMsgs = dwElements;
  78. dwMsgSeq = 1;
  79. dwQMsgs = 0;
  80. dwMsgIndx = 0;
  81. g_maxMsg = dwmaxMsg;
  82. g_maxPlayers = dwmaxPlayers;
  83. InitializeCriticalSection( &q_Section );
  84. return(TRUE);
  85. }
  86. BOOL DeleteQueue()
  87. {
  88. if (pmsgElements)
  89. free(pmsgElements);
  90. if (pmsgArray)
  91. free(pmsgArray);
  92. if (aNotify)
  93. free(aNotify);
  94. pmsgElements = NULL;
  95. pmsgArray = NULL;
  96. aNotify = NULL;
  97. DeleteCriticalSection( &q_Section );
  98. return(TRUE);
  99. }
  100. BOOL AddMessage(LPVOID lpvMsg, DWORD dwSize, DPID pidTo, DPID pidFrom, BOOL bHigh)
  101. {
  102. DWORD dwSeq;
  103. DWORD dwIndex;
  104. DWORD ii;
  105. DPID pid;
  106. if (dwSize > g_maxMsg)
  107. return(FALSE);
  108. // DBG_INFO((DBGARG, "AddMessage. Seq %d Current %d", dwMsgSeq, dwQMsgs));
  109. EnterCriticalSection( &q_Section );
  110. dwMsgSeq++;
  111. if (dwQMsgs == dwMaxMsgs)
  112. {
  113. TSHELL_INFO("Queue over-run, start dumping old messages");
  114. dwSeq = 0xffffffff;
  115. for (ii = 0; ii < dwMaxMsgs; ii++)
  116. {
  117. dwSeq = min(dwSeq, pmsgArray[ii].dwSeq);
  118. if (dwSeq == pmsgArray[ii].dwSeq)
  119. dwIndex = ii;
  120. }
  121. pid = pmsgArray[dwIndex].pidTo;
  122. pmsgArray[dwIndex].bValid = FALSE;
  123. for (ii = 0; ii < g_maxPlayers; ii++)
  124. if (aNotify[ii].pid == pid)
  125. aNotify[ii].dwCount--;
  126. dwQMsgs--;
  127. }
  128. else
  129. {
  130. dwQMsgs++;
  131. for (ii = 0; ii < dwMaxMsgs
  132. && (pmsgArray[dwMsgIndx].bValid == TRUE); ii++)
  133. {
  134. dwMsgIndx++;
  135. dwMsgIndx %= dwMaxMsgs;
  136. }
  137. dwIndex = dwMsgIndx;
  138. }
  139. if (pmsgArray[dwIndex].bValid == TRUE)
  140. {
  141. TSHELL_INFO("Invalid Message State!");
  142. }
  143. // DBG_INFO((DBGARG, "Message index %d", dwIndex));
  144. pmsgArray[dwIndex].dwSeq = dwMsgSeq;
  145. pmsgArray[dwIndex].dwSize = dwSize;
  146. pmsgArray[dwIndex].bValid = TRUE;
  147. pmsgArray[dwIndex].pidTo = pidTo;
  148. pmsgArray[dwIndex].pidFrom = pidFrom;
  149. if (bHigh)
  150. {
  151. pmsgArray[dwIndex].dwSeq += 0x80000000;
  152. }
  153. memcpy( pmsgElements + (dwIndex * g_maxMsg), lpvMsg, dwSize);
  154. // TSHELL_INFO("Message in buffer, now handle increments and events");
  155. // DBG_INFO((DBGARG, "pidTo %d pidFrom %d", pidTo, pidFrom));
  156. if (pidTo != 0)
  157. {
  158. for (ii = 0; ii < g_maxPlayers; ii++)
  159. if (aNotify[ii].pid == pidTo)
  160. {
  161. // TSHELL_INFO("Increment");
  162. InterlockedIncrement((LONG *) &(aNotify[ii].dwCount));
  163. if (aNotify[ii].hEvent)
  164. {
  165. // TSHELL_INFO("Set Event");
  166. SetEvent(aNotify[ii].hEvent);
  167. // DBG_INFO((DBGARG, "Signal Event %8x", aNotify[ii].hEvent));
  168. }
  169. else
  170. {
  171. TSHELL_INFO("No Event to Signal.");
  172. }
  173. break;
  174. }
  175. }
  176. LeaveCriticalSection( &q_Section );
  177. return(TRUE);
  178. }
  179. HRESULT GetQMessage(LPVOID lpvMsg, LPDWORD pdwSize, DPID *ppidTo, DPID *ppidFrom,
  180. DWORD dwFlags, BOOL bPeek)
  181. {
  182. DWORD dwSeq;
  183. DWORD dwIndex;
  184. DWORD dwSeqH;
  185. DWORD dwIndexH;
  186. DWORD ii;
  187. HRESULT hr = DP_OK;
  188. // TSHELL_INFO("Retrieve Messages.");
  189. if (dwQMsgs == 0)
  190. return(DPERR_NOMESSAGES);
  191. if (!lpvMsg && !pdwSize)
  192. return(DPERR_INVALIDPARAM);
  193. EnterCriticalSection( &q_Section );
  194. dwSeq = 0xffffffff;
  195. dwIndex = 0xffffffff;
  196. dwSeqH = 0xffffffff;
  197. dwIndexH = 0xffffffff;
  198. for (ii = 0; ii < dwMaxMsgs; ii++)
  199. {
  200. if (pmsgArray[ii].bValid)
  201. {
  202. if ( (dwFlags & DPRECEIVE_ALL)
  203. || ((dwFlags & DPRECEIVE_TOPLAYER) &&
  204. (pmsgArray[ii].pidTo == *ppidTo))
  205. || ((dwFlags & DPRECEIVE_FROMPLAYER) &&
  206. (pmsgArray[ii].pidFrom == *ppidFrom)))
  207. {
  208. // DBG_INFO((DBGARG, "Msg %d Seq %x valid and meets criteria.",
  209. // ii, pmsgArray[ii].dwSeq));
  210. if (0x80000000 & pmsgArray[ii].dwSeq)
  211. {
  212. if (dwSeqH > pmsgArray[ii].dwSeq)
  213. {
  214. dwSeqH = pmsgArray[ii].dwSeq;
  215. dwIndexH = ii;
  216. }
  217. }
  218. else
  219. {
  220. if (dwSeq > pmsgArray[ii].dwSeq)
  221. {
  222. dwSeq = pmsgArray[ii].dwSeq;
  223. dwIndex = ii;
  224. }
  225. }
  226. }
  227. else
  228. {
  229. DBG_INFO((DBGARG, "Msg %d valid but doesn't meet criteria. for Flags %8x", ii, dwFlags));
  230. }
  231. }
  232. }
  233. if (dwIndexH != 0xffffffff)
  234. {
  235. dwIndex = dwIndexH;
  236. }
  237. if (dwIndex != 0xffffffff)
  238. {
  239. // TSHELL_INFO("Return a message.");
  240. if (lpvMsg == NULL || (*pdwSize < pmsgArray[dwIndex].dwSize))
  241. {
  242. *pdwSize = pmsgArray[dwIndex].dwSize;
  243. hr = DPERR_BUFFERTOOSMALL;
  244. }
  245. else
  246. {
  247. memcpy( lpvMsg, pmsgElements + (dwIndex * g_maxMsg),
  248. pmsgArray[dwIndex].dwSize);
  249. *pdwSize = pmsgArray[dwIndex].dwSize;
  250. *ppidTo = pmsgArray[dwIndex].pidTo;
  251. *ppidFrom = pmsgArray[dwIndex].pidFrom;
  252. if (!(dwFlags & DPRECEIVE_PEEK))
  253. {
  254. dwQMsgs--;
  255. pmsgArray[dwIndex].bValid = FALSE;
  256. for (ii = 0; ii < g_maxPlayers; ii++)
  257. if (aNotify[ii].pid == pmsgArray[dwIndex].pidTo)
  258. {
  259. InterlockedDecrement((LONG *) &aNotify[ii].dwCount);
  260. if (aNotify[ii].dwCount == 0 && aNotify[ii].hEvent)
  261. ResetEvent(aNotify[ii].hEvent);
  262. }
  263. }
  264. }
  265. }
  266. else
  267. {
  268. TSHELL_INFO("No messages found.");
  269. hr = DPERR_NOMESSAGES;
  270. }
  271. // TSHELL_INFO("LeaveGetQMessage.");
  272. LeaveCriticalSection( &q_Section );
  273. return(hr);
  274. }
  275. VOID FlushQueue(DPID pid)
  276. {
  277. HRESULT hr = DP_OK;
  278. DWORD ii;
  279. EnterCriticalSection( &q_Section );
  280. for (ii = 0; ii < g_maxPlayers; ii++)
  281. {
  282. if (aNotify[ii].pid == pid)
  283. {
  284. aNotify[ii].dwCount = 0;
  285. if (aNotify[ii].hEvent)
  286. aNotify[ii].hEvent = NULL;
  287. }
  288. }
  289. for (ii = 0; ii < dwMaxMsgs; ii++)
  290. {
  291. if (pmsgArray[ii].bValid && pmsgArray[ii].pidTo == pid)
  292. {
  293. dwQMsgs--;
  294. pmsgArray[ii].bValid = FALSE;
  295. }
  296. }
  297. LeaveCriticalSection( &q_Section );
  298. }
  299. BOOL SetupLocalPlayer(DPID pid, HANDLE hEvent)
  300. {
  301. DWORD ii;
  302. if (pid == 0)
  303. return(FALSE);
  304. for (ii = 0; ii < g_maxPlayers; ii++)
  305. {
  306. if (aNotify[ii].pid == 0)
  307. {
  308. aNotify[ii].pid = pid;
  309. aNotify[ii].hEvent = hEvent;
  310. // DBG_INFO((DBGARG, "Pid %d index %d in Queue with event %8x",
  311. // pid, ii, hEvent));
  312. return(TRUE);
  313. }
  314. }
  315. return(FALSE);
  316. }
  317. DWORD GetPlayerCount(DPID spid)
  318. {
  319. DWORD ii;
  320. for (ii = 0; ii < g_maxPlayers; ii++)
  321. if (aNotify[ii].pid == spid)
  322. return(aNotify[ii].dwCount);
  323. return(0);
  324. }