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.
 
 
 
 
 
 

541 lines
11 KiB

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
t30util.c
Abstract:
Utilities for t30
Author:
Rafael Lisitsa (RafaelL) 2-Feb-1996
Revision History:
--*/
#include "prep.h"
#include "glbproto.h"
#include "t30gl.h"
#define IDVARSTRINGSIZE (sizeof(VARSTRING)+128)
#define BAD_HANDLE(h) (!(h) || (h)==INVALID_HANDLE_VALUE)
///////////////////////////////////////////////////////////////////////////////////
PVOID
T30AllocThreadGlobalData(
VOID
)
{
PVOID pTG;
pTG = MemAlloc (sizeof(ThrdGlbl) );
FillMemory (pTG, sizeof(ThrdGlbl), 0);
return (pTG);
}
/////////////////////////////////////////////////////////////
BOOL itapi_async_setup(PThrdGlbl pTG)
{
EnterCriticalSection(&T30CritSection);
if (pTG->fWaitingForEvent) {
MyDebugPrint(pTG, LOG_ERR, "ERROR:Already waiting for event!\n");
}
if (pTG->dwSignalledRID) {
MyDebugPrint(pTG, LOG_ERR, "ERROR:Nonzero old NONZERO ID 0x%lx\n",(unsigned long) pTG->dwSignalledRID);
}
pTG->fWaitingForEvent=TRUE;
ResetEvent(pTG->hevAsync);
LeaveCriticalSection(&T30CritSection);
return TRUE;
}
BOOL itapi_async_wait(PThrdGlbl pTG,
DWORD dwRequestID,
PDWORD lpdwParam2,
PDWORD_PTR lpdwParam3,
DWORD dwTimeout)
{
DWORD NumHandles=2;
HANDLE HandlesArray[2];
DWORD WaitResult;
if (!pTG->fWaitingForEvent) {
MyDebugPrint(pTG, LOG_ERR, "ERROR:Not waiting for event!\n");
// ASSERT(FALSE);
}
HandlesArray[1] = pTG->AbortReqEvent;
//
// We want to be able to un-block ONCE only from waiting on I/O when the AbortReqEvent is signaled.
//
if (pTG->fAbortRequested) {
if (pTG->fOkToResetAbortReqEvent && (!pTG->fAbortReqEventWasReset)) {
MyDebugPrint(pTG, LOG_ALL, "itapi_async_wait RESETTING AbortReqEvent at %lx\n",GetTickCount() );
pTG->fAbortReqEventWasReset = 1;
ResetEvent(pTG->AbortReqEvent);
}
pTG->fUnblockIO = 1;
}
HandlesArray[0] = pTG->hevAsync;
if (pTG->fUnblockIO) {
NumHandles = 1;
}
else {
NumHandles = 2;
}
WaitResult = WaitForMultipleObjects(NumHandles, HandlesArray, FALSE, dwTimeout);
if (WaitResult == WAIT_FAILED) {
MyDebugPrint(pTG, LOG_ERR, "itapi_async_wait: WaitForMultipleObjects FAILED le=%lx at %ld \n",
GetLastError(), GetTickCount() );
}
if ( (NumHandles == 2) && (WaitResult == WAIT_OBJECT_0 + 1) ) {
pTG->fUnblockIO = 1;
MyDebugPrint(pTG, LOG_ALL, "itapi_async_wait ABORTED at %ld\n", GetTickCount() );
return FALSE;
}
switch( WaitResult ) {
case (WAIT_OBJECT_0): {
BOOL fRet=TRUE;
EnterCriticalSection(&T30CritSection);
if(pTG->dwSignalledRID == dwRequestID) {
pTG->dwSignalledRID = 0;
pTG->fWaitingForEvent = FALSE;
}
else {
MyDebugPrint(pTG, LOG_ERR, "ERROR:Request ID mismatch. Input:0x%p; Curent:0x%p\n",
dwRequestID,
pTG->dwSignalledRID);
fRet=FALSE;
}
LeaveCriticalSection(&T30CritSection);
if (!fRet)
goto failure;
}
break;
case WAIT_TIMEOUT:
MyDebugPrint(pTG, LOG_ERR, "ERROR:Wait timed out. RequestID=0x%p\n",
dwRequestID);
goto failure;
default:
MyDebugPrint(pTG, LOG_ERR, "ERROR:Wait returns error. GetLastError=%ld\n",
(long) GetLastError());
goto failure;
}
if (lpdwParam2) *lpdwParam2 = pTG->dwSignalledParam2;
if (lpdwParam3) *lpdwParam3 = pTG->dwSignalledParam3;
return TRUE;
failure:
EnterCriticalSection(&T30CritSection);
if(pTG->dwSignalledRID==dwRequestID) {
pTG->dwSignalledRID=0;
pTG->fWaitingForEvent=FALSE;
}
LeaveCriticalSection(&T30CritSection);
return FALSE;
}
BOOL itapi_async_signal(PThrdGlbl pTG,
DWORD dwRequestID,
DWORD dwParam2,
DWORD_PTR dwParam3)
{
BOOL fRet=FALSE;
EnterCriticalSection(&T30CritSection);
if (!pTG->fWaitingForEvent) {
MyDebugPrint(pTG, LOG_ERR, "ERROR:Not waiting for event, ignoring ID=0x%lx \n",
(unsigned long) dwRequestID);
goto end;
}
if (pTG->dwSignalledRID) {
MyDebugPrint(pTG, LOG_ERR, "ERROR:Nonzero old NONZERO ID 0x%lx. New ID=0x%lx \n",
(unsigned long) pTG->dwSignalledRID,
(unsigned long) dwRequestID);
}
pTG->dwSignalledRID=dwRequestID;
pTG->dwSignalledParam2= 0;
pTG->dwSignalledParam3= 0;
if (!SetEvent(pTG->hevAsync)) {
MyDebugPrint(pTG, LOG_ERR, "ERROR:SetEvent(0x%lx) returns failure code: %ld \n",
(ULONG_PTR) pTG->hevAsync,
(long) GetLastError());
fRet=FALSE;
goto end;
}
pTG->dwSignalledParam2= dwParam2;
pTG->dwSignalledParam3= dwParam3;
fRet=TRUE;
end:
LeaveCriticalSection(&T30CritSection);
return fRet;
}
VOID
MyDebugPrint(
PThrdGlbl pTG,
int DbgLevel,
LPSTR Format,
...
)
{
char buf[1024];
char c;
va_list arg_ptr;
int u;
int i;
DWORD dwWritten;
if ( (DbgLevel > gT30.DbgLevel) || (! gfFilePrint) ) {
return;
}
va_start(arg_ptr, Format);
if (pTG == NULL) {
wsprintf(buf, "----");
}
else {
wsprintf(buf, "-%02d-", pTG->DeviceId);
}
u = wvsprintf(&buf[4], Format, arg_ptr) + 4;
// _vsnprintf(buf, sizeof(buf), Format, arg_ptr);
va_end(arg_ptr);
//
// scramble buf
//
for (i=0; i<u; i++) {
c = buf[i];
buf[i] = ( (c << 4 ) & 0xf0 ) | ( (c >> 4) & 0x0f );
}
WriteFile(ghLogFile, buf, u, &dwWritten, NULL);
}
#define CALLPARAMS_SIZE (sizeof(LINECALLPARAMS)+512)
LPLINECALLPARAMS itapi_create_linecallparams(void)
{
UINT cb = CALLPARAMS_SIZE;
LPLINECALLPARAMS lpParams = MemAlloc(cb);
if (!lpParams)
goto end;
_fmemset(lpParams,0, cb);
lpParams->dwTotalSize= cb;
lpParams->dwBearerMode = LINEBEARERMODE_PASSTHROUGH;
lpParams->dwMediaMode = LINEMEDIAMODE_DATAMODEM; // Unimodem only accepts
lpParams->dwCallParamFlags = 0;
lpParams->dwAddressMode = LINEADDRESSMODE_ADDRESSID;
lpParams->dwAddressID = 0; // +++ assumes addreddid 0.
lpParams->dwCalledPartySize = 0; // +++
lpParams->dwCalledPartyOffset = 0; // +++
end:
return lpParams;
}
BOOL
SignalStatusChange(
PThrdGlbl pTG,
DWORD StatusId
)
{
FAX_DEV_STATUS *pFaxStatus;
LPWSTR lpwCSI; // inside the FaxStatus struct.
LPBYTE lpTemp;
//
// If Aborting OR completed then do NOT override the statusId
//
if ( (pTG->StatusId == FS_USER_ABORT) || (pTG->StatusId == FS_COMPLETED) ) {
return (TRUE);
}
pTG->StatusId = StatusId;
// should use HeapAlloc because FaxSvc frees it.
pFaxStatus = HeapAlloc(gT30.HeapHandle , HEAP_ZERO_MEMORY, sizeof(FAX_DEV_STATUS) + 4096 );
if (!pFaxStatus) {
MyDebugPrint(pTG, LOG_ERR, "ERROR: SignalStatusChange HeapAlloc failed\n");
goto failure;
}
pFaxStatus->SizeOfStruct = sizeof (FAX_DEV_STATUS) + 4096;
pFaxStatus->StatusId = pTG->StatusId;
pFaxStatus->StringId = pTG->StringId;
if (pTG->StatusId == FS_RECEIVING) {
pFaxStatus->PageCount = pTG->PageCount + 1;
}
else {
pFaxStatus->PageCount = pTG->PageCount;
}
if (pTG->fRemoteIdAvail) {
lpTemp = (LPBYTE) pFaxStatus;
lpTemp += sizeof(FAX_DEV_STATUS);
lpwCSI = (LPWSTR) lpTemp;
wcscpy(lpwCSI, pTG->RemoteID);
pFaxStatus->CSI = (LPWSTR) lpwCSI;
}
else {
pFaxStatus->CSI = NULL;
}
// RSL BUGBUG
pFaxStatus->CallerId = NULL;
pFaxStatus->RoutingInfo = NULL;
if (! PostQueuedCompletionStatus(pTG->CompletionPortHandle,
sizeof (FAX_DEV_STATUS),
pTG->CompletionKey,
(LPOVERLAPPED) pFaxStatus) ) {
MyDebugPrint(pTG, LOG_ERR, "ERROR: PostQueuedCompletionStatus failed LE=%x\n",
GetLastError() );
goto failure;
}
MyDebugPrint(pTG, LOG_ALL, "SignalStatusChange ID=%x Page=%d \n", pTG->StatusId, pTG->PageCount);
return (TRUE);
failure:
return (FALSE);
}
BOOL
SignalRecoveryStatusChange(
T30_RECOVERY_GLOB *Recovery
)
{
FAX_DEV_STATUS *pFaxStatus;
// should use HeapAlloc because FaxSvc frees it.
pFaxStatus = HeapAlloc(gT30.HeapHandle , HEAP_ZERO_MEMORY, sizeof(FAX_DEV_STATUS) + 4096 );
if (!pFaxStatus) {
goto failure;
}
pFaxStatus->SizeOfStruct = sizeof (FAX_DEV_STATUS) + 4096;
pFaxStatus->StatusId = FS_FATAL_ERROR; // RSL better: FS_FSP_EXCEPTION_HANDLED;
pFaxStatus->StringId = 0;
pFaxStatus->PageCount = 0;
pFaxStatus->CSI = NULL;
pFaxStatus->CallerId = NULL;
pFaxStatus->RoutingInfo = NULL;
if (! PostQueuedCompletionStatus(Recovery->CompletionPortHandle,
sizeof (FAX_DEV_STATUS),
Recovery->CompletionKey,
(LPOVERLAPPED) pFaxStatus) ) {
goto failure;
}
return (TRUE);
failure:
return (FALSE);
}
DWORD
ComputeCheckSum(
LPDWORD BaseAddr,
DWORD NumDwords
)
{
DWORD RetValue = 0;
DWORD i;
for (i=0; i<NumDwords; i++) {
RetValue += *(BaseAddr+i);
}
return (RetValue);
}
VOID
SimulateError(
DWORD ErrorType
)
{
LPDWORD lpdwPtr;
DWORD dw1,
dw2;
switch (ErrorType) {
case EXCEPTION_ACCESS_VIOLATION:
lpdwPtr = NULL;
*lpdwPtr = 5;
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
dw1 = 5;
dw2 = dw1 - 1;
dw2 = dw1 / (dw1 + dw2 - 9);
break;
}
}