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.

344 lines
11 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. events.c
  5. Abstract:
  6. This module:
  7. 1) Determines if the port is valid
  8. 2) Post a completion packet to a completion port. This packet indicates for the Fax Event Queue thread to exit.
  9. 3) Thread to handle the Fax Event Queue logic
  10. Author:
  11. Steven Kehrli (steveke) 11/15/1997
  12. --*/
  13. #ifndef _EVENTS_C
  14. #define _EVENTS_C
  15. BOOL
  16. fnIsPortValid(
  17. PFAX_PORT_INFO pFaxPortsConfig,
  18. DWORD dwNumPorts,
  19. DWORD dwDeviceId
  20. )
  21. /*++
  22. Routine Description:
  23. Determines if the port is valid
  24. Arguments:
  25. pFaxPortsConfig - pointer to the ports configuration
  26. dwNumFaxPorts - number of ports
  27. dwDeviceId - port id
  28. Return Value:
  29. TRUE on success
  30. --*/
  31. {
  32. // dwIndex is a counter to enumerate each port
  33. DWORD dwIndex;
  34. for (dwIndex = 0; dwIndex < dwNumPorts; dwIndex++) {
  35. // Search, by priority, each port for the appropriate port
  36. if (pFaxPortsConfig[dwIndex].DeviceId == dwDeviceId) {
  37. return TRUE;
  38. }
  39. }
  40. return FALSE;
  41. }
  42. VOID
  43. fnPostExitToCompletionPort(
  44. HANDLE hCompletionPort
  45. )
  46. /*++
  47. Routine Description:
  48. Post a completion packet to a completion port. This packet indicates for the Fax Event Queue thread to exit.
  49. Arguments:
  50. hCompletionPort - handle to the completion port
  51. Return Value:
  52. None
  53. --*/
  54. {
  55. PFAX_EVENT pFaxEvent;
  56. pFaxEvent = LocalAlloc(LPTR, sizeof(FAX_EVENT));
  57. pFaxEvent->EventId = -1;
  58. PostQueuedCompletionStatus(hCompletionPort, sizeof(FAX_EVENT), 0, (LPOVERLAPPED) pFaxEvent);
  59. }
  60. DWORD WINAPI fnFaxEventQueueProc (LPVOID lpv)
  61. /*++
  62. Routine Description:
  63. Thread to handle the Fax Event Queue logic
  64. Return Value:
  65. DWORD - exit code
  66. --*/
  67. {
  68. // pFaxEvent is a pointer to the port event
  69. PFAX_EVENT pFaxEvent;
  70. DWORD dwBytes;
  71. UINT_PTR upCompletionKey;
  72. // FaxDialingInfo is the fax dialing info
  73. FAX_DIALING_INFO FaxDialingInfo;
  74. // bFaxPassed indicates a fax passed
  75. BOOL bFaxPassed = FALSE;
  76. // bFaxFailed indicates a fax failed
  77. BOOL bFaxFailed = FALSE;
  78. // dwDeviceId is the port id
  79. DWORD dwDeviceId = 0;
  80. while (GetQueuedCompletionStatus(g_hCompletionPort, &dwBytes, &upCompletionKey, (LPOVERLAPPED *) &pFaxEvent, INFINITE)) {
  81. if (pFaxEvent->EventId == -1) {
  82. // g_hExitEvent was signaled, so thread should exit
  83. LocalFree(pFaxEvent);
  84. break;
  85. }
  86. if (pFaxEvent->EventId == FEI_FAXSVC_ENDED) {
  87. // Signal the g_hFaxEvent
  88. SetEvent(g_hFaxEvent);
  89. // Free the packet
  90. LocalFree(pFaxEvent);
  91. break;
  92. }
  93. if (pFaxEvent->EventId == FEI_MODEM_POWERED_OFF) {
  94. // Update the status
  95. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_DEVICE_POWERED_OFF, pFaxEvent->DeviceId);
  96. // Free the packet
  97. LocalFree(pFaxEvent);
  98. // Decrement g_dwNumAvailPorts
  99. g_dwNumAvailPorts--;
  100. if (!g_dwNumAvailPorts) {
  101. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_PORTS_NOT_AVAILABLE, 0);
  102. }
  103. continue;
  104. }
  105. if (pFaxEvent->EventId == FEI_MODEM_POWERED_ON) {
  106. // Update the status
  107. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_DEVICE_POWERED_ON, pFaxEvent->DeviceId);
  108. // Free the packet
  109. LocalFree(pFaxEvent);
  110. // Increment g_dwNumAvailPorts
  111. g_dwNumAvailPorts++;
  112. continue;
  113. }
  114. // Verify the port is valid
  115. if (!fnIsPortValid(g_pFaxPortsConfig, g_dwNumPorts, pFaxEvent->DeviceId)) {
  116. // Free the packet
  117. LocalFree(pFaxEvent);
  118. continue;
  119. }
  120. if ((pFaxEvent->EventId == FEI_IDLE) && (g_bFaxSndInProgress) && (pFaxEvent->DeviceId == dwDeviceId) && ((bFaxPassed) || (bFaxFailed))) {
  121. // Update the status
  122. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_IDLE, pFaxEvent->DeviceId);
  123. if (bFaxPassed) {
  124. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_SEND_PASSED, pFaxEvent->DeviceId);
  125. // Signal the Send Passed event
  126. SetEvent(g_hSendPassedEvent);
  127. }
  128. else {
  129. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_SEND_FAILED, pFaxEvent->DeviceId);
  130. // Signal the Send Failed event
  131. SetEvent(g_hSendFailedEvent);
  132. }
  133. dwDeviceId = 0;
  134. bFaxPassed = FALSE;
  135. bFaxFailed = FALSE;
  136. continue;
  137. }
  138. if ((pFaxEvent->EventId == FEI_IDLE) && (g_bFaxSndInProgress)) {
  139. // Update the status
  140. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_IDLE, pFaxEvent->DeviceId);
  141. }
  142. if ((pFaxEvent->JobId == g_dwFaxId) && (g_bFaxSndInProgress)) {
  143. switch (pFaxEvent->EventId) {
  144. case FEI_INITIALIZING:
  145. // Update the status
  146. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_INITIALIZING, pFaxEvent->DeviceId);
  147. break;
  148. case FEI_DIALING:
  149. g_dwAttempt++;
  150. // Set FaxDialingInfo
  151. FaxDialingInfo.dwAttempt = g_dwAttempt;
  152. FaxDialingInfo.dwDeviceId = pFaxEvent->DeviceId;
  153. // Update the status
  154. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_DIALING, (LPARAM) &FaxDialingInfo);
  155. dwDeviceId = pFaxEvent->DeviceId;
  156. break;
  157. case FEI_NO_DIAL_TONE:
  158. if (g_dwAttempt < (FAXSVC_RETRIES + 1)) {
  159. // Update the status
  160. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_NO_DIAL_TONE_RETRY, pFaxEvent->DeviceId);
  161. }
  162. else {
  163. // Update the status
  164. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_NO_DIAL_TONE_ABORT, pFaxEvent->DeviceId);
  165. bFaxFailed = TRUE;
  166. }
  167. break;
  168. case FEI_BUSY:
  169. if (g_dwAttempt < (FAXSVC_RETRIES + 1)) {
  170. // Update the status
  171. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_BUSY_RETRY, pFaxEvent->DeviceId);
  172. }
  173. else {
  174. // Update the status
  175. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_BUSY_ABORT, pFaxEvent->DeviceId);
  176. bFaxFailed = TRUE;
  177. }
  178. break;
  179. case FEI_NO_ANSWER:
  180. if (g_dwAttempt < (FAXSVC_RETRIES + 1)) {
  181. // Update the status
  182. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_NO_ANSWER_RETRY, pFaxEvent->DeviceId);
  183. }
  184. else {
  185. // Update the status
  186. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_NO_ANSWER_ABORT, pFaxEvent->DeviceId);
  187. bFaxFailed = TRUE;
  188. }
  189. break;
  190. case FEI_SENDING:
  191. // Update the status
  192. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_SENDING, pFaxEvent->DeviceId);
  193. break;
  194. case FEI_FATAL_ERROR:
  195. if (g_dwAttempt < (FAXSVC_RETRIES + 1)) {
  196. // Update the status
  197. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_FATAL_ERROR_RETRY, pFaxEvent->DeviceId);
  198. }
  199. else {
  200. // Update the status
  201. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_FATAL_ERROR_ABORT, pFaxEvent->DeviceId);
  202. bFaxFailed = TRUE;
  203. }
  204. break;
  205. case FEI_ABORTING:
  206. // Update the status
  207. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_ABORTING, pFaxEvent->DeviceId);
  208. bFaxFailed = TRUE;
  209. break;
  210. case FEI_COMPLETED:
  211. // Update the status
  212. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_COMPLETED, pFaxEvent->DeviceId);
  213. bFaxPassed = TRUE;
  214. break;
  215. default:
  216. // Update the status
  217. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_UNEXPECTED_STATE, pFaxEvent->DeviceId);
  218. bFaxFailed = TRUE;
  219. break;
  220. }
  221. }
  222. if (g_bFaxRcvInProgress) {
  223. switch (pFaxEvent->EventId) {
  224. case FEI_INITIALIZING:
  225. // Update the status
  226. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_INITIALIZING, pFaxEvent->DeviceId);
  227. break;
  228. case FEI_RINGING:
  229. // Update the status
  230. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_RINGING, pFaxEvent->DeviceId);
  231. break;
  232. case FEI_ANSWERED:
  233. // Update the status
  234. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_ANSWERED, pFaxEvent->DeviceId);
  235. break;
  236. case FEI_NOT_FAX_CALL:
  237. // Update the status
  238. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_NOT_FAX_CALL, pFaxEvent->DeviceId);
  239. break;
  240. case FEI_RECEIVING:
  241. // Update the status
  242. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_RECEIVING, pFaxEvent->DeviceId);
  243. break;
  244. case FEI_FATAL_ERROR:
  245. // Update the status
  246. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_FATAL_ERROR, pFaxEvent->DeviceId);
  247. break;
  248. case FEI_ABORTING:
  249. // Update the status
  250. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_ABORTING, pFaxEvent->DeviceId);
  251. break;
  252. case FEI_COMPLETED:
  253. // Update the status
  254. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_COMPLETED, pFaxEvent->DeviceId);
  255. break;
  256. case FEI_IDLE:
  257. // Update the status
  258. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_IDLE, pFaxEvent->DeviceId);
  259. break;
  260. default:
  261. // Update the status
  262. SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_UNEXPECTED_STATE, pFaxEvent->DeviceId);
  263. break;
  264. }
  265. }
  266. // Free the packet
  267. LocalFree(pFaxEvent);
  268. }
  269. return 0;
  270. }
  271. #endif