mirror of https://github.com/tongzx/nt5src
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
344 lines
11 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
events.c
|
|
|
|
Abstract:
|
|
|
|
This module:
|
|
1) Determines if the port is valid
|
|
2) Post a completion packet to a completion port. This packet indicates for the Fax Event Queue thread to exit.
|
|
3) Thread to handle the Fax Event Queue logic
|
|
|
|
Author:
|
|
|
|
Steven Kehrli (steveke) 11/15/1997
|
|
|
|
--*/
|
|
|
|
#ifndef _EVENTS_C
|
|
#define _EVENTS_C
|
|
|
|
BOOL
|
|
fnIsPortValid(
|
|
PFAX_PORT_INFO pFaxPortsConfig,
|
|
DWORD dwNumPorts,
|
|
DWORD dwDeviceId
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Determines if the port is valid
|
|
|
|
Arguments:
|
|
|
|
pFaxPortsConfig - pointer to the ports configuration
|
|
dwNumFaxPorts - number of ports
|
|
dwDeviceId - port id
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
|
|
--*/
|
|
{
|
|
// dwIndex is a counter to enumerate each port
|
|
DWORD dwIndex;
|
|
|
|
for (dwIndex = 0; dwIndex < dwNumPorts; dwIndex++) {
|
|
// Search, by priority, each port for the appropriate port
|
|
if (pFaxPortsConfig[dwIndex].DeviceId == dwDeviceId) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
VOID
|
|
fnPostExitToCompletionPort(
|
|
HANDLE hCompletionPort
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Post a completion packet to a completion port. This packet indicates for the Fax Event Queue thread to exit.
|
|
|
|
Arguments:
|
|
|
|
hCompletionPort - handle to the completion port
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PFAX_EVENT pFaxEvent;
|
|
|
|
pFaxEvent = LocalAlloc(LPTR, sizeof(FAX_EVENT));
|
|
pFaxEvent->EventId = -1;
|
|
|
|
PostQueuedCompletionStatus(hCompletionPort, sizeof(FAX_EVENT), 0, (LPOVERLAPPED) pFaxEvent);
|
|
}
|
|
|
|
DWORD WINAPI fnFaxEventQueueProc (LPVOID lpv)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Thread to handle the Fax Event Queue logic
|
|
|
|
Return Value:
|
|
|
|
DWORD - exit code
|
|
|
|
--*/
|
|
{
|
|
// pFaxEvent is a pointer to the port event
|
|
PFAX_EVENT pFaxEvent;
|
|
DWORD dwBytes;
|
|
UINT_PTR upCompletionKey;
|
|
|
|
// FaxDialingInfo is the fax dialing info
|
|
FAX_DIALING_INFO FaxDialingInfo;
|
|
|
|
// bFaxPassed indicates a fax passed
|
|
BOOL bFaxPassed = FALSE;
|
|
// bFaxFailed indicates a fax failed
|
|
BOOL bFaxFailed = FALSE;
|
|
// dwDeviceId is the port id
|
|
DWORD dwDeviceId = 0;
|
|
|
|
while (GetQueuedCompletionStatus(g_hCompletionPort, &dwBytes, &upCompletionKey, (LPOVERLAPPED *) &pFaxEvent, INFINITE)) {
|
|
|
|
if (pFaxEvent->EventId == -1) {
|
|
// g_hExitEvent was signaled, so thread should exit
|
|
LocalFree(pFaxEvent);
|
|
break;
|
|
}
|
|
|
|
if (pFaxEvent->EventId == FEI_FAXSVC_ENDED) {
|
|
// Signal the g_hFaxEvent
|
|
SetEvent(g_hFaxEvent);
|
|
|
|
// Free the packet
|
|
LocalFree(pFaxEvent);
|
|
break;
|
|
}
|
|
|
|
if (pFaxEvent->EventId == FEI_MODEM_POWERED_OFF) {
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_DEVICE_POWERED_OFF, pFaxEvent->DeviceId);
|
|
|
|
// Free the packet
|
|
LocalFree(pFaxEvent);
|
|
|
|
// Decrement g_dwNumAvailPorts
|
|
g_dwNumAvailPorts--;
|
|
if (!g_dwNumAvailPorts) {
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_PORTS_NOT_AVAILABLE, 0);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (pFaxEvent->EventId == FEI_MODEM_POWERED_ON) {
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_DEVICE_POWERED_ON, pFaxEvent->DeviceId);
|
|
|
|
// Free the packet
|
|
LocalFree(pFaxEvent);
|
|
|
|
// Increment g_dwNumAvailPorts
|
|
g_dwNumAvailPorts++;
|
|
continue;
|
|
}
|
|
|
|
// Verify the port is valid
|
|
if (!fnIsPortValid(g_pFaxPortsConfig, g_dwNumPorts, pFaxEvent->DeviceId)) {
|
|
// Free the packet
|
|
LocalFree(pFaxEvent);
|
|
continue;
|
|
}
|
|
|
|
if ((pFaxEvent->EventId == FEI_IDLE) && (g_bFaxSndInProgress) && (pFaxEvent->DeviceId == dwDeviceId) && ((bFaxPassed) || (bFaxFailed))) {
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_IDLE, pFaxEvent->DeviceId);
|
|
if (bFaxPassed) {
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_SEND_PASSED, pFaxEvent->DeviceId);
|
|
// Signal the Send Passed event
|
|
SetEvent(g_hSendPassedEvent);
|
|
}
|
|
else {
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_SEND_FAILED, pFaxEvent->DeviceId);
|
|
// Signal the Send Failed event
|
|
SetEvent(g_hSendFailedEvent);
|
|
}
|
|
dwDeviceId = 0;
|
|
bFaxPassed = FALSE;
|
|
bFaxFailed = FALSE;
|
|
continue;
|
|
}
|
|
|
|
if ((pFaxEvent->EventId == FEI_IDLE) && (g_bFaxSndInProgress)) {
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_IDLE, pFaxEvent->DeviceId);
|
|
}
|
|
|
|
if ((pFaxEvent->JobId == g_dwFaxId) && (g_bFaxSndInProgress)) {
|
|
switch (pFaxEvent->EventId) {
|
|
case FEI_INITIALIZING:
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_INITIALIZING, pFaxEvent->DeviceId);
|
|
break;
|
|
|
|
case FEI_DIALING:
|
|
g_dwAttempt++;
|
|
// Set FaxDialingInfo
|
|
FaxDialingInfo.dwAttempt = g_dwAttempt;
|
|
FaxDialingInfo.dwDeviceId = pFaxEvent->DeviceId;
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_DIALING, (LPARAM) &FaxDialingInfo);
|
|
dwDeviceId = pFaxEvent->DeviceId;
|
|
break;
|
|
|
|
case FEI_NO_DIAL_TONE:
|
|
if (g_dwAttempt < (FAXSVC_RETRIES + 1)) {
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_NO_DIAL_TONE_RETRY, pFaxEvent->DeviceId);
|
|
}
|
|
else {
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_NO_DIAL_TONE_ABORT, pFaxEvent->DeviceId);
|
|
bFaxFailed = TRUE;
|
|
}
|
|
break;
|
|
|
|
case FEI_BUSY:
|
|
if (g_dwAttempt < (FAXSVC_RETRIES + 1)) {
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_BUSY_RETRY, pFaxEvent->DeviceId);
|
|
}
|
|
else {
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_BUSY_ABORT, pFaxEvent->DeviceId);
|
|
bFaxFailed = TRUE;
|
|
}
|
|
break;
|
|
|
|
case FEI_NO_ANSWER:
|
|
if (g_dwAttempt < (FAXSVC_RETRIES + 1)) {
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_NO_ANSWER_RETRY, pFaxEvent->DeviceId);
|
|
}
|
|
else {
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_NO_ANSWER_ABORT, pFaxEvent->DeviceId);
|
|
bFaxFailed = TRUE;
|
|
}
|
|
break;
|
|
|
|
case FEI_SENDING:
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_SENDING, pFaxEvent->DeviceId);
|
|
break;
|
|
|
|
case FEI_FATAL_ERROR:
|
|
if (g_dwAttempt < (FAXSVC_RETRIES + 1)) {
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_FATAL_ERROR_RETRY, pFaxEvent->DeviceId);
|
|
}
|
|
else {
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_FATAL_ERROR_ABORT, pFaxEvent->DeviceId);
|
|
bFaxFailed = TRUE;
|
|
}
|
|
break;
|
|
|
|
case FEI_ABORTING:
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_ABORTING, pFaxEvent->DeviceId);
|
|
bFaxFailed = TRUE;
|
|
break;
|
|
|
|
case FEI_COMPLETED:
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_COMPLETED, pFaxEvent->DeviceId);
|
|
bFaxPassed = TRUE;
|
|
break;
|
|
|
|
default:
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_UNEXPECTED_STATE, pFaxEvent->DeviceId);
|
|
bFaxFailed = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (g_bFaxRcvInProgress) {
|
|
switch (pFaxEvent->EventId) {
|
|
case FEI_INITIALIZING:
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_INITIALIZING, pFaxEvent->DeviceId);
|
|
break;
|
|
|
|
case FEI_RINGING:
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_RINGING, pFaxEvent->DeviceId);
|
|
break;
|
|
|
|
case FEI_ANSWERED:
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_ANSWERED, pFaxEvent->DeviceId);
|
|
break;
|
|
|
|
case FEI_NOT_FAX_CALL:
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_NOT_FAX_CALL, pFaxEvent->DeviceId);
|
|
break;
|
|
|
|
case FEI_RECEIVING:
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_RECEIVING, pFaxEvent->DeviceId);
|
|
break;
|
|
|
|
case FEI_FATAL_ERROR:
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_FATAL_ERROR, pFaxEvent->DeviceId);
|
|
break;
|
|
|
|
case FEI_ABORTING:
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_ABORTING, pFaxEvent->DeviceId);
|
|
break;
|
|
|
|
case FEI_COMPLETED:
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_COMPLETED, pFaxEvent->DeviceId);
|
|
break;
|
|
|
|
case FEI_IDLE:
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_FAX_IDLE, pFaxEvent->DeviceId);
|
|
break;
|
|
|
|
default:
|
|
// Update the status
|
|
SendMessage(g_hWndDlg, UM_UPDATE_STATUS, IDS_STATUS_UNEXPECTED_STATE, pFaxEvent->DeviceId);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Free the packet
|
|
LocalFree(pFaxEvent);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif
|