Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

9641 lines
240 KiB

/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
esp.c
Abstract:
This module contains
Author:
Dan Knudson (DanKn) dd-Mmm-1995
Revision History:
Notes:
1. Regarding the SP filling in structures with variable length fields
(dwXxxSize/dwXxxOffset) : "The SP's variable size fields start
immediately after the fixed part of the data structure. The order
of filling of the variable size fields owned by the SP is not
specified. The SP can fill them in any order it desires. Filling
should be contiguous, starting at the beginning of the variable
part." (Taken from Chapter 2 of the SPI Programmer's Guide.)
2. The cheesey hack in the MsgLoopInTAPIClientContext() function of
having an in-line (within the calling app context) msg loop should
NOT be implemented by any real service provider. The only place a
real provider should have a msg loop (explicit or implicit [i.e. as
a result of calling DialogBox()]) is in one of the
TSPI_xxxConfigDialog[Edit] functions. If you need a msg processing
context (for handling comm events or whatever) then start up a
companion exe- it's cheap & easy.
// BUGBUG no SendMessage's in calling app context either
Examples of problems with having a msg loop in a service provider
in the calling app context:
* A call to the 16-bit GetMessage() will return a msg that
has a 16-bit WPARAM. If this msg is destined for a 32-bit
window, the high word of the WPARAM, which is 32-bit for
Win32 apps, will have been discarded. However, there is code
in the 16-bit system functions DialogBox(), MessageBox(), etc.
to deal with this and insure 32-bit WPARAM integrity.
* Applications can get re-entered when they don't expect it.
Consider an app that makes what it thinks will be an atomic
function call into TAPI; it waits to get the result back
before doing any manipulation of it's various data structures.
But in the meantime a service provider enters a Get\Dispatch
loop, which in turn causes the app's TapiCallback to be called
because there are some completion and/or async event
notification msgs available.
--*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include "esp.h"
#include "vars.h"
HANDLE hInst;
LONG cxList1, cxWnd;
#ifdef WIN32
HANDLE ghMsgLoopThread = NULL;
#endif
char szdwRequestID[] = "dwRequestID";
char szdwDeviceID[] = "dwDeviceID";
char szhdLine[] = "hdLine";
char szhdCall[] = "hdCall";
char szhdPhone[] = "hdPhone";
char szdwSize[] = "dwSize";
char szlpCallParams[] = "lpCallParams";
char szTab[] = " ";
char szTelephonIni[] = "telephon.ini";
char szhwndOwner[] = "hwndOwner";
char szMySection[] = "ESPExe";
char szCallUp[] = "^^^^";
char szEspTsp[] = "esp.tsp";
char szProvider[] = "Provider";
char szProviders[] = "Providers";
char szProviderID[] = "ProviderID";
char szNumProviders[] = "NumProviders";
char szNextProviderID[] = "NextProviderID";
char szProviderFilename[] = "ProviderFileName";
char szdwPermanentProviderID[] = "dwPermanentProviderID";
static char far *aszDeviceClasses[] =
{
"tapi/line",
"tapi/phone",
"wave",
"wave/in",
"wave/out",
"comm",
"comm/datamodem",
(char far *) NULL
};
void
PASCAL
SendLineEvent(
PDRVLINE pLine,
PDRVCALL pCall,
DWORD dwMsg,
DWORD dwParam1,
DWORD dwParam2,
DWORD dwParam3
);
void
PASCAL
SendPhoneEvent(
PDRVPHONE pPhone,
DWORD dwMsg,
DWORD dwParam1,
DWORD dwParam2,
DWORD dwParam3
);
void
PASCAL
DoCompletion(
char far *lpszFuncName,
DWORD dwRequestID,
LONG lResult,
BOOL bSync
);
void
PASCAL
SetCallState(
PDRVCALL pCall,
DWORD dwCallState,
DWORD dwCallStateMode
);
void
UpdateTelephonIni(
DWORD dwPermanentProviderID
);
void
MsgLoopInTAPIClientContext(
HWND hwnd
);
void
SaveIniSettings(
void
);
BOOL
__loadds
CALLBACK
CallDlgProc(
HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam
);
#ifdef WIN32
HANDLE ghShowStrBufMutex;
BOOL
WINAPI
_CRT_INIT(
HINSTANCE hDLL,
DWORD dwReason,
LPVOID lpReserved
);
BOOL
IsESPInstalled(
HWND hwnd
);
void
MsgLoopThread(
void
)
{
DllMsgLoop();
ExitThread (0);
}
BOOL
WINAPI
DllMain(
HANDLE hDLL,
DWORD dwReason,
LPVOID lpReserved
)
{
if (!_CRT_INIT (hInst, dwReason, lpReserved))
{
OutputDebugString ("ESP: DllMain: _CRT_INIT() failed\n\r");
}
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
hInst = hDLL;
ghShowStrBufMutex = CreateMutex(
NULL, // no security attrs
FALSE, // unowned
NULL // unnamed
);
break;
case DLL_PROCESS_DETACH:
CloseHandle (ghShowStrBufMutex);
break;
} // switch
return TRUE;
}
#else
int
FAR
PASCAL
LibMain(
HANDLE hInstance,
WORD wDataSegment,
WORD wHeapSize,
LPSTR lpszCmdLine
)
{
hInst = hInstance;
return TRUE;
}
#endif
//
// We get a slough of C4047 (different levels of indrection) warnings down
// below in the initialization of FUNC_PARAM structs as a result of the
// real func prototypes having params that are types other than DWORDs,
// so since these are known non-interesting warnings just turn them off
//
#pragma warning (disable:4047)
//
// --------------------------- TAPI_lineXxx funcs -----------------------------
//
void
FAR
PASCAL
TSPI_lineAccept_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
if ((pAsyncReqInfo->lResult == 0))
{
SetCallState(
(PDRVCALL) pAsyncReqInfo->dwParam1,
LINECALLSTATE_ACCEPTED,
0
);
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
}
LONG
TSPIAPI
TSPI_lineAccept(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
LPCSTR lpsUserUserInfo,
DWORD dwSize
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall },
{ "lpsUserUserInfo", lpsUserUserInfo },
{ szdwSize, dwSize }
};
FUNC_INFO info = { "lineAccept", ASYNC, 4, params, TSPI_lineAccept_postProcess };
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdCall;
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_lineAddToConference_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
if ((pAsyncReqInfo->lResult == 0))
{
PDRVCALL pConfCall = (PDRVCALL) pAsyncReqInfo->dwParam1;
PDRVCALL pConsultCall = (PDRVCALL) pAsyncReqInfo->dwParam2;
pConsultCall->pConfParent = pConfCall;
pConsultCall->pNextConfChild = pConfCall->pNextConfChild;
pConfCall->pNextConfChild = pConsultCall;
SetCallState (pConsultCall, LINECALLSTATE_CONFERENCED, 0);
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
}
LONG
TSPIAPI
TSPI_lineAddToConference(
DRV_REQUESTID dwRequestID,
HDRVCALL hdConfCall,
HDRVCALL hdConsultCall
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ "hdConfCall", hdConfCall },
{ "hdConsultCall", hdConsultCall }
};
FUNC_INFO info = { "lineAddToConference", ASYNC, 3, params, TSPI_lineAddToConference_postProcess };
PDRVCALL pConfCall = (PDRVCALL) hdConfCall;
PDRVCALL pConsultCall = (PDRVCALL) hdConsultCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdConfCall;
info.pAsyncReqInfo->dwParam2 = (DWORD) hdConsultCall;
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_lineAnswer_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
if ((pAsyncReqInfo->lResult == 0))
{
SetCallState(
(PDRVCALL) pAsyncReqInfo->dwParam1,
LINECALLSTATE_CONNECTED,
0
);
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
}
LONG
TSPIAPI
TSPI_lineAnswer(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
LPCSTR lpsUserUserInfo,
DWORD dwSize
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall },
{ "lpsUserUserInfo", lpsUserUserInfo },
{ szdwSize, dwSize }
};
FUNC_INFO info = { "lineAnswer", ASYNC, 4, params, TSPI_lineAnswer_postProcess };
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdCall;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineBlindTransfer(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
LPCSTR lpszDestAddress,
DWORD dwCountryCode
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall },
{ "lpszDestAddress", lpszDestAddress },
{ "dwCountryCode", dwCountryCode }
};
FUNC_INFO info = { "lineBlindTransfer", ASYNC, 4, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineClose(
HDRVLINE hdLine
)
{
FUNC_PARAM params[] =
{
{ szhdLine, hdLine }
};
FUNC_INFO info = { "lineClose", SYNC, 1, params };
PDRVLINE pLine = (PDRVLINE) hdLine;
//
// This is more of a "command" than a request, in that TAPI.DLL is
// going to consider the line closed whether we like it or not.
// Therefore we want to free up the line even if the user chooses
// to return an error.
//
if (!Prolog (&info))
{
// return (Epilog (&info));
}
pLine->htLine = (HTAPILINE) NULL;
//UpdateWidgetList();
PostUpdateWidgetListMsg();
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineCloseCall(
HDRVCALL hdCall
)
{
FUNC_PARAM params[] =
{
{ szhdCall, hdCall }
};
FUNC_INFO info = { "lineCloseCall", SYNC, 1, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
//
// This is more of a "command" than a request, in that TAPI.DLL is
// going to consider the call closed whether we like it or not.
// Therefore we want to free up the call even if the user chooses
// to return an error.
//
if (!Prolog (&info))
{
// return (Epilog (&info));
}
FreeCall (pCall);
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineCompleteCall(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
LPDWORD lpdwCompletionID,
DWORD dwCompletionMode,
DWORD dwMessageID
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall },
{ "lpdwCompletionID", lpdwCompletionID },
{ "dwCompletionMode", dwCompletionMode },
{ "dwMessageID", dwMessageID }
};
FUNC_INFO info = { "lineCompleteCall", ASYNC, 5, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_lineCompleteTransfer_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
PDRVCALL pConfCall = (PDRVCALL) NULL;
PDRVCALL pCall = pAsyncReqInfo->dwParam1;
PDRVCALL pConsultCall = pAsyncReqInfo->dwParam2;
HTAPICALL htConfCall = pAsyncReqInfo->dwParam3;
LPHDRVCALL lphdConfCall = pAsyncReqInfo->dwParam4;
if ((pAsyncReqInfo->lResult == 0))
{
if (htConfCall)
{
if ((pAsyncReqInfo->lResult = AllocCall (
pCall->pLine,
htConfCall,
NULL,
&pConfCall
)) == 0)
{
*lphdConfCall = (HDRVCALL) pCall;
}
}
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
if ((pAsyncReqInfo->lResult == 0))
{
if (pConfCall)
{
SetCallState (pConfCall, LINECALLSTATE_CONNECTED, 0);
SetCallState (pCall, LINECALLSTATE_CONFERENCED, 0);
SetCallState (pConsultCall, LINECALLSTATE_CONFERENCED, 0);
}
else
{
SetCallState(
pCall,
LINECALLSTATE_DISCONNECTED,
LINEDISCONNECTMODE_NORMAL
);
SetCallState (pCall, LINECALLSTATE_IDLE, 0);
SetCallState(
pConsultCall,
LINECALLSTATE_DISCONNECTED,
LINEDISCONNECTMODE_NORMAL
);
SetCallState (pConsultCall, LINECALLSTATE_IDLE, 0);
}
}
}
LONG
TSPIAPI
TSPI_lineCompleteTransfer(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
HDRVCALL hdConsultCall,
HTAPICALL htConfCall,
LPHDRVCALL lphdConfCall,
DWORD dwTransferMode
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall },
{ "hdConsultCall", hdConsultCall },
{ "htConfCall", htConfCall },
{ "lphdConfCall", lphdConfCall },
{ "dwTransferMode", dwTransferMode, aTransferModes }
};
FUNC_INFO info = { "lineCompleteTransfer", ASYNC, 6, params, TSPI_lineCompleteTransfer_postProcess };
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdCall;
info.pAsyncReqInfo->dwParam2 = (DWORD) hdConsultCall;
if (dwTransferMode == LINETRANSFERMODE_CONFERENCE)
{
info.pAsyncReqInfo->dwParam3 = (DWORD) htConfCall;
info.pAsyncReqInfo->dwParam4 = (DWORD) lphdConfCall;
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineConditionalMediaDetection(
HDRVLINE hdLine,
DWORD dwMediaModes,
LPLINECALLPARAMS const lpCallParams
)
{
FUNC_PARAM params[] =
{
{ szhdLine, hdLine },
{ "dwMediaModes", dwMediaModes, aMediaModes },
{ szlpCallParams, lpCallParams }
};
FUNC_INFO info = { "lineConditionalMediaDetection", SYNC, 3, params };
PDRVLINE pLine = (PDRVLINE) hdLine;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineConfigDialog(
DWORD dwDeviceID,
HWND hwndOwner,
LPCSTR lpszDeviceClass
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ szhwndOwner, hwndOwner },
{ "lpszDeviceClass", lpszDeviceClass }
};
FUNC_INFO info = { "lineConfigDialog", SYNC, 3, params };
if (!Prolog (&info))
{
return (Epilog (&info));
}
#ifdef WIN32
//
// In Win32...
//
MessageBox(
hwndOwner,
"Config dlg for ESP line device",
"TSPI_lineConfigDialog",
MB_OK // | MB_SERVICE_NOTIFICATION
);
#else
//
// Note: MessageBox() implements a get/dispatch msg loop which allows
// other apps (or other windows within the calling app) to gain
// focus. Once these other windows/apps have focus, it's
// possible that they will call into TAPI, and this service
// provider could be re-entered.
//
MessageBox(
hwndOwner,
"Config dlg for ESP line device",
"TSPI_lineConfigDialog",
MB_OK
);
#endif
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineConfigDialogEdit(
DWORD dwDeviceID,
HWND hwndOwner,
LPCSTR lpszDeviceClass,
LPVOID lpDeviceConfigIn,
DWORD dwSize,
LPVARSTRING lpDeviceConfigOut
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ szhwndOwner, hwndOwner },
{ "lpszDeviceClass", lpszDeviceClass },
{ "lpDeviceConfigIn", lpDeviceConfigIn },
{ szdwSize, dwSize },
{ "lpDeviceConfigOut", lpDeviceConfigOut }
};
FUNC_INFO info = { "lineConfigDialogEdit", SYNC, 6, params };
static char szData[] = "device config out data";
DWORD len;
if (!Prolog (&info))
{
return (Epilog (&info));
}
#ifdef WIN32
//
// In Win32...
//
MessageBox(
(HWND) NULL, // NOTE: if hwndOwner specified dlg never appears
"Config dlg for ESP line device",
"TSPI_lineConfigDialogEdit",
MB_OK | MB_SERVICE_NOTIFICATION
);
#else
//
// Note: MessageBox() implements a get/dispatch msg loop which allows
// other apps (or other windows within the calling app) to gain
// focus. Once these other windows/apps have focus, it's
// possible that they will call into TAPI, and this service
// provider could be re-entered.
//
MessageBox(
hwndOwner,
"Config dlg for ESP line device",
"TSPI_lineConfigDialogEdit",
MB_OK
);
#endif
len = strlen (szData) + 1;
lpDeviceConfigOut->dwNeededSize = sizeof (VARSTRING) + len;
if (lpDeviceConfigOut->dwTotalSize >= lpDeviceConfigOut->dwNeededSize)
{
lpDeviceConfigOut->dwUsedSize = lpDeviceConfigOut->dwNeededSize;
lpDeviceConfigOut->dwStringFormat = STRINGFORMAT_BINARY;
lpDeviceConfigOut->dwStringSize = len;
lpDeviceConfigOut->dwStringOffset = sizeof (VARSTRING);
strcpy ((char *)(lpDeviceConfigOut + 1), szData);
}
else
{
lpDeviceConfigOut->dwUsedSize = 3 * sizeof(DWORD);
}
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_lineDevSpecific_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
LPVOID lpParams = pAsyncReqInfo->dwParam1;
DWORD dwSize = pAsyncReqInfo->dwParam2;
if (pAsyncReqInfo->lResult == 0 && dwSize >= 22)
{
strcpy (lpParams, "ESP dev specific info");
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
}
LONG
TSPIAPI
TSPI_lineDevSpecific(
DRV_REQUESTID dwRequestID,
HDRVLINE hdLine,
DWORD dwAddressID,
HDRVCALL hdCall,
LPVOID lpParams,
DWORD dwSize
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdLine, hdLine },
{ "dwAddressID", dwAddressID },
{ szhdCall, hdCall },
{ "lpParams", lpParams },
{ szdwSize, dwSize }
};
FUNC_INFO info =
{
"lineDevSpecific",
ASYNC,
6,
params,
TSPI_lineDevSpecific_postProcess
};
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = lpParams;
info.pAsyncReqInfo->dwParam2 = dwSize;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineDevSpecificFeature(
DRV_REQUESTID dwRequestID,
HDRVLINE hdLine,
DWORD dwFeature,
LPVOID lpParams,
DWORD dwSize
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdLine, hdLine },
{ "dwFeature", dwFeature },
{ "lpParams", lpParams },
{ szdwSize, dwSize }
};
FUNC_INFO info =
{
"lineDevSpecificFeature",
ASYNC,
5,
params,
TSPI_lineDevSpecific_postProcess
};
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = lpParams;
info.pAsyncReqInfo->dwParam2 = dwSize;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineDial(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
LPCSTR lpszDestAddress,
DWORD dwCountryCode
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall },
{ "lpszDestAddress", lpszDestAddress },
{ "dwCountryCode", dwCountryCode }
};
FUNC_INFO info = { "lineDial", ASYNC, 4, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_lineDrop_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
if ((pAsyncReqInfo->lResult == 0))
{
SetCallState(
(PDRVCALL) pAsyncReqInfo->dwParam1,
LINECALLSTATE_IDLE,
0
);
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
}
LONG
TSPIAPI
TSPI_lineDrop(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
LPCSTR lpsUserUserInfo,
DWORD dwSize
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall },
{ "lpsUserUserInfo", lpsUserUserInfo },
{ szdwSize, dwSize }
};
FUNC_INFO info = { "lineDrop", ASYNC, 4, params, TSPI_lineDrop_postProcess };
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdCall;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineDropOnClose(
HDRVCALL hdCall
)
{
FUNC_PARAM params[] =
{
{ szhdCall, hdCall }
};
FUNC_INFO info = { "lineDropOnClose", SYNC, 1, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
//
// Don't bother indicating call state, TAPI will follow up with
// a CloseCall request regardless
//
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineDropNoOwner(
HDRVCALL hdCall
)
{
FUNC_PARAM params[] =
{
{ szhdCall, hdCall }
};
FUNC_INFO info = { "lineDropNoOwner", SYNC, 1, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
SetCallState ((PDRVCALL) hdCall, LINECALLSTATE_IDLE, 0);
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_lineForward_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
PDRVCALL pConsultCall;
PDRVLINE pLine = (PDRVLINE) pAsyncReqInfo->dwParam1;
BOOL bAllAddresses = (BOOL) pAsyncReqInfo->dwParam2;
DWORD dwAddressID = pAsyncReqInfo->dwParam3;
LPLINEFORWARDLIST lpForwardList = (LPLINEFORWARDLIST) pAsyncReqInfo->dwParam4;
DWORD dwNumRingsNoAnswer = pAsyncReqInfo->dwParam5;
HTAPICALL htConsultCall = (HTAPICALL) pAsyncReqInfo->dwParam6;
LPHDRVCALL lphdConsultCall = (LPHDRVCALL) pAsyncReqInfo->dwParam7;
LPLINECALLPARAMS lpCallParams = (LPLINECALLPARAMS) pAsyncReqInfo->dwParam8;
if (pAsyncReqInfo->lResult == 0)
{
if ((pAsyncReqInfo->lResult = AllocCall (
pLine,
htConsultCall,
lpCallParams,
&pConsultCall
)) == 0)
{
// BUGBUG deal w/ addr id
*lphdConsultCall = (HDRVCALL) pConsultCall;
}
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
if (pAsyncReqInfo->lResult == 0)
{
SetCallState (pConsultCall, LINECALLSTATE_CONNECTED, 0);
}
if (lpForwardList)
{
DrvFree (lpForwardList);
}
if (lpCallParams)
{
DrvFree (lpCallParams);
}
}
LONG
TSPIAPI
TSPI_lineForward(
DRV_REQUESTID dwRequestID,
HDRVLINE hdLine,
DWORD bAllAddresses,
DWORD dwAddressID,
LPLINEFORWARDLIST const lpForwardList,
DWORD dwNumRingsNoAnswer,
HTAPICALL htConsultCall,
LPHDRVCALL lphdConsultCall,
LPLINECALLPARAMS const lpCallParams
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdLine, hdLine },
{ "bAllAddresses", bAllAddresses },
{ "dwAddressID", dwAddressID },
{ "lpForwardList", lpForwardList },
{ "dwNumRingsNoAnswer", dwNumRingsNoAnswer },
{ "htConsultCall", htConsultCall },
{ "lphdConsultCall", lphdConsultCall },
{ szlpCallParams, lpCallParams }
};
FUNC_INFO info = { "lineForward", ASYNC, 9, params, TSPI_lineForward_postProcess };
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdLine;
info.pAsyncReqInfo->dwParam2 = (DWORD) bAllAddresses;
info.pAsyncReqInfo->dwParam3 = dwAddressID;
if (lpForwardList)
{
info.pAsyncReqInfo->dwParam4 = (DWORD) DrvAlloc(
(size_t) lpForwardList->dwTotalSize
);
memcpy(
(void far *) info.pAsyncReqInfo->dwParam4,
(void far *) lpForwardList,
(size_t) lpForwardList->dwTotalSize
);
}
info.pAsyncReqInfo->dwParam5 = dwNumRingsNoAnswer;
info.pAsyncReqInfo->dwParam6 = (DWORD) htConsultCall;
info.pAsyncReqInfo->dwParam7 = (DWORD) lphdConsultCall;
if (lpCallParams)
{
info.pAsyncReqInfo->dwParam8 = (DWORD) DrvAlloc(
(size_t) lpCallParams->dwTotalSize
);
memcpy(
(void far *) info.pAsyncReqInfo->dwParam8,
(void far *) lpCallParams,
(size_t) lpCallParams->dwTotalSize
);
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineGatherDigits(
HDRVCALL hdCall,
DWORD dwEndToEndID,
DWORD dwDigitModes,
LPSTR lpsDigits,
DWORD dwNumDigits,
LPCSTR lpszTerminationDigits,
DWORD dwFirstDigitTimeout,
DWORD dwInterDigitTimeout
)
{
FUNC_PARAM params[] =
{
{ szhdCall, hdCall },
{ "dwEndToEndID", dwEndToEndID },
{ "dwDigitModes", dwDigitModes, aDigitModes },
{ "lpsDigits", lpsDigits },
{ "dwNumDigits", dwNumDigits },
{ "lpszTerminationDigits", lpszTerminationDigits },
{ "dwFirstDigitTimeout", dwFirstDigitTimeout },
{ "dwInterDigitTimeout", dwInterDigitTimeout }
};
FUNC_INFO info = { "lineGatherDigits", SYNC, 8, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineGenerateDigits(
HDRVCALL hdCall,
DWORD dwEndToEndID,
DWORD dwDigitMode,
LPCSTR lpszDigits,
DWORD dwDuration
)
{
FUNC_PARAM params[] =
{
{ szhdCall, hdCall },
{ "dwEndToEndID", dwEndToEndID },
{ "dwDigitMode", dwDigitMode, aDigitModes },
{ "lpszDigits", lpszDigits },
{ "dwDuration", dwDuration }
};
FUNC_INFO info = { "lineGenerateDigits", SYNC, 5, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineGenerateTone(
HDRVCALL hdCall,
DWORD dwEndToEndID,
DWORD dwToneMode,
DWORD dwDuration,
DWORD dwNumTones,
LPLINEGENERATETONE const lpTones
)
{
FUNC_PARAM params[] =
{
{ szhdCall, hdCall },
{ "dwEndToEndID", dwEndToEndID },
{ "dwToneMode", dwToneMode, aToneModes },
{ "dwDuration", dwDuration },
{ "dwNumTones", dwNumTones },
{ "lpTones", lpTones }
};
FUNC_INFO info = { "lineGenerateTone", SYNC, 6, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineGetAddressCaps(
DWORD dwDeviceID,
DWORD dwAddressID,
DWORD dwTSPIVersion,
DWORD dwExtVersion,
LPLINEADDRESSCAPS lpAddressCaps
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ "dwAddressID", dwAddressID },
{ "dwTSPIVersion", dwTSPIVersion },
{ "dwExtVersion", dwExtVersion },
{ "lpAddressCaps", lpAddressCaps }
};
FUNC_INFO info = { "lineGetAddressCaps", SYNC, 5, params };
DWORD dwUsedSize;
PDRVLINE pLine = GetLine (dwDeviceID);
if (!Prolog (&info))
{
return (Epilog (&info));
}
if (dwAddressID >= pLine->LineDevCaps.dwNumAddresses)
{
info.lResult = LINEERR_INVALADDRESSID;
return (Epilog (&info));
}
//
// Figure out how much caps data to copy (don't bother with var length
// fields if there's not room enough for all of them)
//
if (lpAddressCaps->dwTotalSize >= pLine->LineAddrCaps.dwNeededSize)
{
dwUsedSize = pLine->LineAddrCaps.dwNeededSize;
}
else if (lpAddressCaps->dwTotalSize >= sizeof(LINEADDRESSCAPS))
{
dwUsedSize = sizeof(LINEADDRESSCAPS);
}
else // it's a 1.3 app looking for just fixed 1.3 data struct size
{
dwUsedSize = sizeof(LINEADDRESSCAPS) - sizeof(DWORD);
}
memcpy(
&lpAddressCaps->dwNeededSize,
&pLine->LineAddrCaps.dwNeededSize,
(size_t) dwUsedSize - 4 // - 4 since not overwriting dwTotalSize
);
lpAddressCaps->dwUsedSize = dwUsedSize;
//
// If there's no room for the var length fields then we need to zero
// out all the dwXxxSize fields; otherwise, fill in the address field
//
if (lpAddressCaps->dwTotalSize < pLine->LineAddrCaps.dwNeededSize)
{
//lpAddessCaps->dwAddressSize =
//lpAddessCaps->dwDevSpecificSize =
//lpAddessCaps->dwCompletionMsgTextSize = 0;
}
else
{
char far *p = ((char far *) lpAddressCaps) +
lpAddressCaps->dwAddressOffset;
wsprintf (p, "%ld.%ld", dwDeviceID, dwAddressID);
lpAddressCaps->dwAddressSize = strlen (p) + 1;
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineGetAddressID(
HDRVLINE hdLine,
LPDWORD lpdwAddressID,
DWORD dwAddressMode,
LPCSTR lpsAddress,
DWORD dwSize
)
{
FUNC_PARAM params[] =
{
{ szhdLine, hdLine },
{ "lpdwAddressID", lpdwAddressID },
{ "dwAddressMode", dwAddressMode },
{ "lpsAddress", lpsAddress },
{ szdwSize, dwSize }
};
FUNC_INFO info = { "lineGetAddressID", SYNC, 5, params };
PDRVLINE pLine = (PDRVLINE) hdLine;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineGetAddressStatus(
HDRVLINE hdLine,
DWORD dwAddressID,
LPLINEADDRESSSTATUS lpAddressStatus
)
{
FUNC_PARAM params[] =
{
{ szhdLine, hdLine },
{ "dwAddressID", dwAddressID },
{ "lpAddressStatus", lpAddressStatus }
};
FUNC_INFO info = { "lineGetAddressStatus", SYNC, 3, params };
PDRVLINE pLine = (PDRVLINE) hdLine;
if (!Prolog (&info))
{
return (Epilog (&info));
}
if (lpAddressStatus->dwTotalSize >= pLine->LineAddrStatus.dwNeededSize)
{
memcpy(
&lpAddressStatus->dwNeededSize,
&pLine->LineAddrStatus.dwNeededSize,
pLine->LineAddrStatus.dwNeededSize - sizeof (DWORD)
);
}
else
{
lpAddressStatus->dwNeededSize = pLine->LineAddrStatus.dwNeededSize;
lpAddressStatus->dwUsedSize = 3 * sizeof (DWORD);
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineGetCallAddressID(
HDRVCALL hdCall,
LPDWORD lpdwAddressID
)
{
FUNC_PARAM params[] =
{
{ szhdCall, hdCall },
{ "lpdwAddressID", lpdwAddressID }
};
FUNC_INFO info = { "lineGetCallAddressID", SYNC, 2, params };
if (!Prolog (&info))
{
return (Epilog (&info));
}
*lpdwAddressID = ((PDRVCALL) hdCall)->LineCallInfo.dwAddressID;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineGetCallInfo(
HDRVCALL hdCall,
LPLINECALLINFO lpCallInfo
)
{
FUNC_PARAM params[] =
{
{ szhdCall, hdCall },
{ "lpCallInfo", lpCallInfo }
};
FUNC_INFO info = { "lineGetCallInfo", SYNC, 2, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
DWORD dwUsedSize;
if (!Prolog (&info))
{
return (Epilog (&info));
}
//
// Figure out how much data to copy (don't bother with var length fields
// if there's not room enough for all of them)
//
if (lpCallInfo->dwTotalSize >= pCall->LineCallInfo.dwNeededSize)
{
dwUsedSize = pCall->LineCallInfo.dwNeededSize;
}
else
{
dwUsedSize = sizeof(LINECALLINFO);
}
memcpy(
&lpCallInfo->dwNeededSize,
&pCall->LineCallInfo.dwNeededSize,
(size_t) dwUsedSize - 4 // - 4 since not overwriting dwTotalSize
);
lpCallInfo->dwUsedSize = dwUsedSize;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineGetCallStatus(
HDRVCALL hdCall,
LPLINECALLSTATUS lpCallStatus
)
{
FUNC_PARAM params[] =
{
{ szhdCall, hdCall },
{ "lpCallStatus", lpCallStatus }
};
FUNC_INFO info = { "lineGetCallStatus", SYNC, 2, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
DWORD dwDevSpecificSize = pCall->LineCallInfo.dwDevSpecificSize;
if (!Prolog (&info))
{
return (Epilog (&info));
}
lpCallStatus->dwUsedSize = sizeof (LINECALLSTATUS);
lpCallStatus->dwNeededSize = sizeof (LINECALLSTATUS) + dwDevSpecificSize;
lpCallStatus->dwCallState = pCall->dwCallState;
lpCallStatus->dwCallStateMode = pCall->dwCallStateMode;
lpCallStatus->dwCallFeatures = pCall->dwCallFeatures;
//
// We're getting the DevSpecific field from the CalInfo
//
if (dwDevSpecificSize &&
(lpCallStatus->dwTotalSize >= lpCallStatus->dwNeededSize))
{
lpCallStatus->dwDevSpecificSize = dwDevSpecificSize;
lpCallStatus->dwDevSpecificOffset = sizeof(LINECALLSTATUS);
strcpy(
((char far *) lpCallStatus) + sizeof(LINECALLSTATUS),
((char far *) &pCall->LineCallInfo) +
pCall->LineCallInfo.dwDevSpecificOffset
);
lpCallStatus->dwUsedSize = lpCallStatus->dwNeededSize;
}
else
{
lpCallStatus->dwDevSpecificSize =
lpCallStatus->dwDevSpecificOffset = 0;
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineGetDevCaps(
DWORD dwDeviceID,
DWORD dwTSPIVersion,
DWORD dwExtVersion,
LPLINEDEVCAPS lpLineDevCaps
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ "dwTSPIVersion", dwTSPIVersion },
{ "dwExtVersion", dwExtVersion },
{ "lpLineDevCaps", lpLineDevCaps }
};
FUNC_INFO info = { "lineGetDevCaps", SYNC, 4, params };
DWORD dwUsedSize;
PDRVLINE pLine = GetLine (dwDeviceID);
if (!Prolog (&info))
{
return (Epilog (&info));
}
//
// Figure out how much caps data to copy (don't bother with var length
// fields if there's not room enough for all of them)
//
if (lpLineDevCaps->dwTotalSize >= pLine->LineDevCaps.dwNeededSize)
{
dwUsedSize = pLine->LineDevCaps.dwNeededSize;
}
else if (lpLineDevCaps->dwTotalSize >= sizeof(LINEDEVCAPS))
{
dwUsedSize = sizeof(LINEDEVCAPS);
}
else // it's a 1.3 app looking for just fixed 1.3 data struct size
{
dwUsedSize = sizeof(LINEDEVCAPS) - sizeof(DWORD);
}
memcpy(
&lpLineDevCaps->dwNeededSize,
&pLine->LineDevCaps.dwNeededSize,
(size_t) dwUsedSize - 4 // - 4 since not overwriting dwTotalSize
);
lpLineDevCaps->dwUsedSize = dwUsedSize;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineGetDevConfig(
DWORD dwDeviceID,
LPVARSTRING lpDeviceConfig,
LPCSTR lpszDeviceClass
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ "lpDeviceConfig", lpDeviceConfig },
{ "lpszDeviceClass", lpszDeviceClass }
};
FUNC_INFO info = { "lineGetDevConfig", SYNC, 3, params };
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineGetExtensionID(
DWORD dwDeviceID,
DWORD dwTSPIVersion,
LPLINEEXTENSIONID lpExtensionID
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ "dwTSPIVersion", dwTSPIVersion },
{ "lpExtensionID", lpExtensionID }
};
FUNC_INFO info = { "lineGetExtensionID", SYNC, 3, params };
if (!Prolog (&info))
{
return (Epilog (&info));
}
memcpy (lpExtensionID, &gLineExtID, sizeof(LINEEXTENSIONID));
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineGetIcon(
DWORD dwDeviceID,
LPCSTR lpszDeviceClass,
LPHICON lphIcon
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ "lpszDeviceClass", lpszDeviceClass },
{ "lphIcon", lphIcon }
};
FUNC_INFO info = { "lineGetIcon", SYNC, 3, params };
if (!Prolog (&info))
{
return (Epilog (&info));
}
*lphIcon = ghIconLine;
return (Epilog (&info));
}
#ifdef WIN32
LONG
TSPIAPI
TSPI_lineGetID(
HDRVLINE hdLine,
DWORD dwAddressID,
HDRVCALL hdCall,
DWORD dwSelect,
LPVARSTRING lpDeviceID,
LPCSTR lpszDeviceClass,
HANDLE hTargetProcess
)
#else
LONG
TSPIAPI
TSPI_lineGetID(
HDRVLINE hdLine,
DWORD dwAddressID,
HDRVCALL hdCall,
DWORD dwSelect,
LPVARSTRING lpDeviceID,
LPCSTR lpszDeviceClass
)
#endif
{
FUNC_PARAM params[] =
{
{ szhdLine, hdLine },
{ "dwAddressID", dwAddressID },
{ szhdCall, hdCall },
{ "dwSelect", dwSelect, aCallSelects },
{ "lpDeviceID", lpDeviceID },
{ "lpszDeviceClass", lpszDeviceClass }
#ifdef WIN32
,{ "hTargetProcess", hTargetProcess }
#endif
};
#ifdef WIN32
FUNC_INFO info = { "lineGetID", SYNC, 7, params };
#else
FUNC_INFO info = { "lineGetID", SYNC, 6, params };
#endif
PDRVLINE pLine = (PDRVLINE) hdLine;
PDRVCALL pCall = (PDRVCALL) hdCall;
DWORD i, dwDeviceID, dwNeededSize = sizeof(VARSTRING) + sizeof(DWORD);
if (!Prolog (&info))
{
return (Epilog (&info));
}
for (i = 0; aszDeviceClasses[i]; i++)
{
if (_stricmp (lpszDeviceClass, aszDeviceClasses[i]) == 0)
{
break;
}
}
if (!aszDeviceClasses[i])
{
info.lResult = LINEERR_NODEVICE;
return (Epilog (&info));
}
if (lpDeviceID->dwTotalSize < dwNeededSize)
{
lpDeviceID->dwNeededSize = dwNeededSize;
lpDeviceID->dwUsedSize = 3 * sizeof(DWORD);
return (Epilog (&info));
}
if (i == 0)
{
if (dwSelect == LINECALLSELECT_CALL)
{
dwDeviceID = pCall->pLine->dwDeviceID;
}
else
{
dwDeviceID = pLine->dwDeviceID;
}
}
else
{
if (gbShowLineGetIDDlg)
{
char szDlgTitle[64];
EVENT_PARAM params[] =
{
{ "dwDeviceID", PT_DWORD, gdwDefLineGetIDID, 0 }
};
EVENT_PARAM_HEADER paramsHeader =
{ 1, szDlgTitle, XX_REQRESULTPOSTQUIT, params };
HWND hwnd;
if (strlen (lpszDeviceClass) > 20)
{
((char far *)lpszDeviceClass)[19] = 0;
}
wsprintf(
szDlgTitle,
"TSPI_lineGetID: select ID for class '%s'",
lpszDeviceClass
);
hwnd = CreateDialogParam(
hInst,
(LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
(HWND) NULL,
(DLGPROC) CallDlgProc,
(LPARAM) &paramsHeader
);
MsgLoopInTAPIClientContext (hwnd);
dwDeviceID = params[0].dwValue;
}
else
{
dwDeviceID = gdwDefLineGetIDID;
}
}
lpDeviceID->dwNeededSize =
lpDeviceID->dwUsedSize = dwNeededSize;
lpDeviceID->dwStringFormat = STRINGFORMAT_BINARY;
lpDeviceID->dwStringSize = sizeof(DWORD);
lpDeviceID->dwStringOffset = sizeof(VARSTRING);
*((LPDWORD)(lpDeviceID + 1)) = dwDeviceID;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineGetLineDevStatus(
HDRVLINE hdLine,
LPLINEDEVSTATUS lpLineDevStatus
)
{
FUNC_PARAM params[] =
{
{ szhdLine, hdLine },
{ "lpLineDevStatus", lpLineDevStatus }
};
FUNC_INFO info = { "lineGetLineDevStatus", SYNC, 2, params };
PDRVLINE pLine = (PDRVLINE) hdLine;
DWORD dwTotalSize, dwNeededSize;
if (!Prolog (&info))
{
return (Epilog (&info));
}
dwNeededSize = pLine->LineDevStatus.dwNeededSize;
if ((dwTotalSize = lpLineDevStatus->dwTotalSize) < dwNeededSize)
{
lpLineDevStatus->dwNeededSize = dwNeededSize;
lpLineDevStatus->dwUsedSize = 3 * sizeof (DWORD);
}
else
{
memcpy(
lpLineDevStatus,
&pLine->LineDevStatus,
dwNeededSize
);
lpLineDevStatus->dwTotalSize = dwTotalSize;
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineGetNumAddressIDs(
HDRVLINE hdLine,
LPDWORD lpdwNumAddressIDs
)
{
FUNC_PARAM params[] =
{
{ szhdLine, hdLine },
{ "lpdwNumAddressIDs", lpdwNumAddressIDs }
};
FUNC_INFO info = { "lineGetNumAddressIDs", SYNC, 2, params };
PDRVLINE pLine = (PDRVLINE) hdLine;
if (!Prolog (&info))
{
return (Epilog (&info));
}
*lpdwNumAddressIDs = pLine->LineDevCaps.dwNumAddresses;
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_lineHold_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
if ((pAsyncReqInfo->lResult == 0))
{
SetCallState(
(PDRVCALL) pAsyncReqInfo->dwParam1,
LINECALLSTATE_ONHOLD,
0
);
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
}
LONG
TSPIAPI
TSPI_lineHold(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall }
};
FUNC_INFO info = { "lineHold", ASYNC, 2, params, TSPI_lineHold_postProcess };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdCall;
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_lineMakeCall_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
PDRVCALL pCall;
PDRVLINE pLine = (PDRVLINE) pAsyncReqInfo->dwParam1;
HTAPICALL htCall = (HTAPICALL) pAsyncReqInfo->dwParam2;
LPHDRVCALL lphdCall = (LPHDRVCALL) pAsyncReqInfo->dwParam3;
LPSTR lpszDestAddress = (LPSTR) pAsyncReqInfo->dwParam4;
LPLINECALLPARAMS lpCallParams = (LPLINECALLPARAMS) pAsyncReqInfo->dwParam5;
if (pAsyncReqInfo->lResult == 0)
{
if ((pAsyncReqInfo->lResult = AllocCall (
pLine,
htCall,
lpCallParams,
&pCall
)) == 0)
{
*lphdCall = (HDRVCALL) pCall;
}
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
if (pAsyncReqInfo->lResult == 0)
{
int i;
//
// Loop on user-defined call state progression array
//
for (i = 0; ((i < MAX_OUT_CALL_STATES) && aOutCallStates[i]); i++)
{
SetCallState (pCall, aOutCallStates[i], aOutCallStateModes[i]);
}
}
if (lpszDestAddress)
{
DrvFree (lpszDestAddress);
}
if (lpCallParams)
{
DrvFree (lpCallParams);
}
}
LONG
TSPIAPI
TSPI_lineMakeCall(
DRV_REQUESTID dwRequestID,
HDRVLINE hdLine,
HTAPICALL htCall,
LPHDRVCALL lphdCall,
LPCSTR lpszDestAddress,
DWORD dwCountryCode,
LPLINECALLPARAMS const lpCallParams
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdLine, hdLine },
{ "htCall", htCall },
{ "lphdCall", lphdCall },
{ "lpszDestAddress", lpszDestAddress },
{ "dwCountryCode", dwCountryCode },
{ szlpCallParams, lpCallParams }
};
FUNC_INFO info = { "lineMakeCall", ASYNC, 7, params, TSPI_lineMakeCall_postProcess };
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdLine;
info.pAsyncReqInfo->dwParam2 = (DWORD) htCall;
info.pAsyncReqInfo->dwParam3 = (DWORD) lphdCall;
if (lpszDestAddress)
{
size_t len = strlen (lpszDestAddress) + 1;
info.pAsyncReqInfo->dwParam4 = (DWORD) DrvAlloc (len);
memcpy(
(void far *) info.pAsyncReqInfo->dwParam4,
lpszDestAddress,
len
);
}
if (lpCallParams)
{
info.pAsyncReqInfo->dwParam5 = (DWORD) DrvAlloc(
(size_t) lpCallParams->dwTotalSize
);
memcpy(
(void far *) info.pAsyncReqInfo->dwParam5,
(void far *) lpCallParams,
(size_t) lpCallParams->dwTotalSize
);
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineMonitorDigits(
HDRVCALL hdCall,
DWORD dwDigitModes
)
{
FUNC_PARAM params[] =
{
{ szhdCall, hdCall },
{ "dwDigitModes", dwDigitModes, aDigitModes }
};
FUNC_INFO info = { "lineMonitorDigits", SYNC, 2, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineMonitorMedia(
HDRVCALL hdCall,
DWORD dwMediaModes
)
{
FUNC_PARAM params[] =
{
{ szhdCall, hdCall },
{ "dwMediaModes", dwMediaModes, aMediaModes }
};
FUNC_INFO info = { "lineMonitorMedia", SYNC, 2, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineMonitorTones(
HDRVCALL hdCall,
DWORD dwToneListID,
LPLINEMONITORTONE const lpToneList,
DWORD dwNumEntries
)
{
FUNC_PARAM params[] =
{
{ szhdCall, hdCall },
{ "dwToneListID", dwToneListID },
{ "lpToneList", lpToneList },
{ "dwNumEntries", dwNumEntries }
};
FUNC_INFO info = { "lineMonitorTones", SYNC, 4, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineNegotiateExtVersion(
DWORD dwDeviceID,
DWORD dwTSPIVersion,
DWORD dwLowVersion,
DWORD dwHighVersion,
LPDWORD lpdwExtVersion
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ "dwTSPIVersion", dwTSPIVersion },
{ "dwLowVersion", dwLowVersion },
{ "dwHighVersion", dwHighVersion },
{ "lpdwExtVersion", lpdwExtVersion }
};
FUNC_INFO info = { "lineNegotiateExtVersion", SYNC, 5, params };
if (!Prolog (&info))
{
return (Epilog (&info));
}
ShowStr(
"TSPI_lineNegoExtVer: setting *lpdwExtVersion = x%lx",
dwHighVersion
);
*lpdwExtVersion = dwHighVersion;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineNegotiateTSPIVersion(
DWORD dwDeviceID,
DWORD dwLowVersion,
DWORD dwHighVersion,
LPDWORD lpdwTSPIVersion
)
{
#ifdef WIN32
if (!ghMsgLoopThread)
{
DWORD dwTID;
if (!(ghMsgLoopThread = CreateThread(
(LPSECURITY_ATTRIBUTES) NULL,
0,
(LPTHREAD_START_ROUTINE) MsgLoopThread,
NULL,
0,
&dwTID
)))
{
OutputDebugString ("ESP32.TSP: DllMain: CreateThread failed\n\r");
return LINEERR_OPERATIONFAILED;
}
}
#endif
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ "dwLowVersion", dwLowVersion },
{ "dwHighVersion", dwHighVersion },
{ "lpdwTSPIVersion", lpdwTSPIVersion }
};
FUNC_INFO info = { "lineNegotiateTSPIVersion", SYNC, 4, params };
{
// BUGBUG hangs if gbManualResults set, so...
BOOL bManualResultsSav = gbManualResults;
gbManualResults = FALSE;
if (!Prolog (&info))
{
return (Epilog (&info));
}
gbManualResults = bManualResultsSav;
}
*lpdwTSPIVersion = gdwTSPIVersion;
return (Epilog (&info));
}
}
LONG
TSPIAPI
TSPI_lineOpen(
DWORD dwDeviceID,
HTAPILINE htLine,
LPHDRVLINE lphdLine,
DWORD dwTSPIVersion,
LINEEVENT lpfnEventProc
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ "htLine", htLine },
{ "lphdLine", lphdLine },
{ "dwTSPIVersion", dwTSPIVersion },
{ "lpfnEventProc", lpfnEventProc }
};
FUNC_INFO info = { "lineOpen", SYNC, 5, params };
PDRVLINE pLine;
if (!Prolog (&info))
{
return (Epilog (&info));
}
pLine = GetLine (dwDeviceID);
pLine->htLine = htLine;
pLine->lpfnEventProc = lpfnEventProc;
*lphdLine = (HDRVLINE) pLine;
//UpdateWidgetList();
PostUpdateWidgetListMsg();
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_linePark(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
DWORD dwParkMode,
LPCSTR lpszDirAddress,
LPVARSTRING lpNonDirAddress
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall },
{ "dwParkMode", dwParkMode },
{ "lpszDirAddress", lpszDirAddress },
{ "lpNonDirAddress", lpNonDirAddress }
};
FUNC_INFO info = { "linePark", ASYNC, 5, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_linePickup_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
PDRVCALL pCall;
PDRVLINE pLine = (PDRVLINE) pAsyncReqInfo->dwParam1;
DWORD dwAddresssID = pAsyncReqInfo->dwParam2;
HTAPICALL htCall = (HTAPICALL) pAsyncReqInfo->dwParam3;
LPHDRVCALL lphdCall = (LPHDRVCALL) pAsyncReqInfo->dwParam4;
LPSTR lpszDestAddress = (LPSTR) pAsyncReqInfo->dwParam5;
LPSTR lpszGroupID = (LPSTR) pAsyncReqInfo->dwParam6;
if (pAsyncReqInfo->lResult == 0)
{
if ((pAsyncReqInfo->lResult = AllocCall (
pLine,
htCall,
NULL,
&pCall
)) == 0)
{
// BUGBUG deal w/ addr id
*lphdCall = (HDRVCALL) pCall;
}
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
if (pAsyncReqInfo->lResult == 0)
{
SetCallState (pCall, LINECALLSTATE_OFFERING, 0);
}
if (lpszDestAddress)
{
DrvFree (lpszDestAddress);
}
if (lpszGroupID)
{
DrvFree (lpszGroupID);
}
}
LONG
TSPIAPI
TSPI_linePickup(
DRV_REQUESTID dwRequestID,
HDRVLINE hdLine,
DWORD dwAddressID,
HTAPICALL htCall,
LPHDRVCALL lphdCall,
LPCSTR lpszDestAddress,
LPCSTR lpszGroupID
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdLine, hdLine },
{ "dwAddressID", dwAddressID },
{ "htCall", htCall },
{ "lphdCall", lphdCall },
{ "lpszDestAddress", lpszDestAddress },
{ "lpszGroupID", lpszGroupID }
};
FUNC_INFO info = { "linePickup", ASYNC, 7, params, TSPI_linePickup_postProcess };
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdLine;
info.pAsyncReqInfo->dwParam2 = dwAddressID;
info.pAsyncReqInfo->dwParam3 = (DWORD) htCall;
info.pAsyncReqInfo->dwParam4 = (DWORD) lphdCall;
if (lpszDestAddress)
{
size_t len = strlen (lpszDestAddress) + 1;
info.pAsyncReqInfo->dwParam5 = (DWORD) DrvAlloc (len);
memcpy(
(void far *) info.pAsyncReqInfo->dwParam5,
lpszDestAddress,
len
);
}
if (lpszGroupID)
{
size_t len = strlen (lpszGroupID) + 1;
info.pAsyncReqInfo->dwParam6 = (DWORD) DrvAlloc (len);
memcpy(
(void far *) info.pAsyncReqInfo->dwParam6,
lpszGroupID,
len
);
}
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_linePrepareAddToConference_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
PDRVCALL pConsultCall = (PDRVCALL) NULL;
PDRVCALL pConfCall = (PDRVCALL) pAsyncReqInfo->dwParam1;
HTAPICALL htConsultCall = (HTAPICALL) pAsyncReqInfo->dwParam2;
LPHDRVCALL lphdConsultCall = (LPHDRVCALL) pAsyncReqInfo->dwParam3;
LPLINECALLPARAMS lpCallParams = (LPLINECALLPARAMS) pAsyncReqInfo->dwParam4;
if (pAsyncReqInfo->lResult == 0)
{
if ((pAsyncReqInfo->lResult = AllocCall(
pConfCall->pLine,
htConsultCall,
lpCallParams,
&pConsultCall
)) == 0
)
{
*lphdConsultCall = (HDRVCALL) pConsultCall;
}
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
if (pAsyncReqInfo->lResult == 0)
{
SetCallState (pConfCall, LINECALLSTATE_ONHOLDPENDCONF, 0);
SetCallState (pConsultCall, LINECALLSTATE_DIALTONE, 0);
}
if (lpCallParams)
{
DrvFree (lpCallParams);
}
}
LONG
TSPIAPI
TSPI_linePrepareAddToConference(
DRV_REQUESTID dwRequestID,
HDRVCALL hdConfCall,
HTAPICALL htConsultCall,
LPHDRVCALL lphdConsultCall,
LPLINECALLPARAMS const lpCallParams
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ "hdConfCall", hdConfCall },
{ "htConsultCall", htConsultCall },
{ "lphdConsultCall", lphdConsultCall },
{ szlpCallParams, lpCallParams }
};
FUNC_INFO info = { "linePrepareAddToConference", ASYNC, 5, params, TSPI_linePrepareAddToConference_postProcess };
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdConfCall;
info.pAsyncReqInfo->dwParam2 = (DWORD) htConsultCall;
info.pAsyncReqInfo->dwParam3 = (DWORD) lphdConsultCall;
if (lpCallParams)
{
info.pAsyncReqInfo->dwParam4 = (DWORD) DrvAlloc(
(size_t) lpCallParams->dwTotalSize
);
memcpy(
(void far *) info.pAsyncReqInfo->dwParam4,
(void far *) lpCallParams,
(size_t) lpCallParams->dwTotalSize
);
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineRedirect(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
LPCSTR lpszDestAddress,
DWORD dwCountryCode
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall },
{ "lpszDestAddress", lpszDestAddress },
{ "dwCountryCode", dwCountryCode }
};
FUNC_INFO info = { "lineRedirect", ASYNC, 4, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineReleaseUserUserInfo(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall }
};
FUNC_INFO info = { "lineReleaseUserUserInfo", ASYNC, 2, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_lineRemoveFromConference_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
if ((pAsyncReqInfo->lResult == 0))
{
PDRVCALL pCall = (PDRVCALL) pAsyncReqInfo->dwParam1;
PDRVCALL pCall2 = (PDRVCALL) pCall->pConfParent;
while (pCall2->pNextConfChild != pCall)
{
pCall2 = pCall2->pNextConfChild;
}
pCall2->pNextConfChild = pCall->pNextConfChild;
SetCallState (pCall, LINECALLSTATE_CONNECTED, 0);
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
}
LONG
TSPIAPI
TSPI_lineRemoveFromConference(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall }
};
FUNC_INFO info = { "lineRemoveFromConference", ASYNC, 2, params, TSPI_lineRemoveFromConference_postProcess };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdCall;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineSecureCall(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall }
};
FUNC_INFO info = { "lineSecureCall", ASYNC, 2, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineSelectExtVersion(
HDRVLINE hdLine,
DWORD dwExtVersion
)
{
FUNC_PARAM params[] =
{
{ szhdLine, hdLine },
{ "dwExtVersion", dwExtVersion }
};
FUNC_INFO info = { "lineSelectExtVersion", SYNC, 2, params };
PDRVLINE pLine = (PDRVLINE) hdLine;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineSendUserUserInfo(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
LPCSTR lpsUserUserInfo,
DWORD dwSize
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall },
{ "lpsUserUserInfo", lpsUserUserInfo },
{ szdwSize, dwSize }
};
FUNC_INFO info = { "lineSendUserUserInfo", ASYNC, 4, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineSetAppSpecific(
HDRVCALL hdCall,
DWORD dwAppSpecific
)
{
FUNC_PARAM params[] =
{
{ szhdCall, hdCall },
{ "dwAppSpecific", dwAppSpecific }
};
FUNC_INFO info = { "lineSetAppSpecific", SYNC, 2, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineSetCallParams(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
DWORD dwBearerMode,
DWORD dwMinRate,
DWORD dwMaxRate,
LPLINEDIALPARAMS const lpDialParams
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall },
{ "dwBearerMode", dwBearerMode, aBearerModes },
{ "dwMinRate", dwMinRate },
{ "dwMaxRate", dwMaxRate },
{ "lpDialParams", lpDialParams }
};
FUNC_INFO info = { "lineSetCallParams", ASYNC, 6, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineSetCurrentLocation(
DWORD dwLocation
)
{
FUNC_PARAM params[] =
{
{ "dwLocation", dwLocation }
};
FUNC_INFO info = { "lineSetCurrentLocation", SYNC, 1, params };
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineSetDefaultMediaDetection(
HDRVLINE hdLine,
DWORD dwMediaModes
)
{
FUNC_PARAM params[] =
{
{ szhdLine, hdLine },
{ "dwMediaModes", dwMediaModes, aMediaModes }
};
FUNC_INFO info = { "lineSetDefaultMediaDetection", SYNC, 2, params };
PDRVLINE pLine = (PDRVLINE) hdLine;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineSetDevConfig(
DWORD dwDeviceID,
LPVOID const lpDeviceConfig,
DWORD dwSize,
LPCSTR lpszDeviceClass
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ "lpDeviceConfig", lpDeviceConfig },
{ szdwSize, dwSize },
{ "lpszDeviceClass", lpszDeviceClass }
};
FUNC_INFO info = { "lineSetDevConfig", SYNC, 4, params };
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineSetMediaControl(
HDRVLINE hdLine,
DWORD dwAddressID,
HDRVCALL hdCall,
DWORD dwSelect,
LPLINEMEDIACONTROLDIGIT const lpDigitList,
DWORD dwDigitNumEntries,
LPLINEMEDIACONTROLMEDIA const lpMediaList,
DWORD dwMediaNumEntries,
LPLINEMEDIACONTROLTONE const lpToneList,
DWORD dwToneNumEntries,
LPLINEMEDIACONTROLCALLSTATE const lpCallStateList,
DWORD dwCallStateNumEntries
)
{
FUNC_PARAM params[] =
{
{ szhdLine, hdLine },
{ "dwAddressID", dwAddressID },
{ szhdCall, hdCall },
{ "dwSelect", dwSelect, aCallSelects },
{ "lpDigitList", lpDigitList },
{ "dwDigitNumEntries", dwDigitNumEntries },
{ "lpMediaList", lpMediaList },
{ "dwMediaNumEntries", dwMediaNumEntries },
{ "lpToneList", lpToneList },
{ "dwToneNumEntries", dwToneNumEntries },
{ "lpCallStateList", lpCallStateList },
{ "dwCallStateNumEntries", dwCallStateNumEntries }
};
FUNC_INFO info = { "lineSetMediaControl", SYNC, 12, params };
PDRVLINE pLine = (PDRVLINE) hdLine;
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineSetMediaMode(
HDRVCALL hdCall,
DWORD dwMediaMode
)
{
FUNC_PARAM params[] =
{
{ szhdCall, szhdCall },
{ "dwMediaMode", dwMediaMode, aMediaModes }
};
FUNC_INFO info = { "lineSetMediaMode", SYNC, 2, params };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineSetStatusMessages(
HDRVLINE hdLine,
DWORD dwLineStates,
DWORD dwAddressStates
)
{
FUNC_PARAM params[] =
{
{ szhdLine, hdLine },
{ "dwLineStates", dwLineStates, aLineStates },
{ "dwAddressStates", dwAddressStates, aAddressStates }
};
FUNC_INFO info = { "lineSetStatusMessages", SYNC, 3, params };
PDRVLINE pLine = (PDRVLINE) hdLine;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineSetTerminal(
DRV_REQUESTID dwRequestID,
HDRVLINE hdLine,
DWORD dwAddressID,
HDRVCALL hdCall,
DWORD dwSelect,
DWORD dwTerminalModes,
DWORD dwTerminalID,
DWORD bEnable
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdLine, hdLine },
{ "dwAddressID", dwAddressID },
{ szhdCall, hdCall },
{ "dwSelect", dwSelect, aCallSelects },
{ "dwTerminalModes", dwTerminalModes, aTerminalModes },
{ "dwTerminalID", dwTerminalID },
{ "bEnable", bEnable }
};
FUNC_INFO info = { "lineSetTerminal", ASYNC, 8, params };
PDRVLINE pLine = (PDRVLINE) hdLine;
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_lineSetupConference_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
PDRVCALL pConfCall = (PDRVCALL) NULL;
PDRVCALL pConsultCall = (PDRVCALL) NULL;
PDRVCALL pCall = (PDRVCALL) pAsyncReqInfo->dwParam1;
PDRVLINE pLine = (PDRVLINE) pAsyncReqInfo->dwParam2;
HTAPICALL htConfCall = (HTAPICALL) pAsyncReqInfo->dwParam3;
LPHDRVCALL lphdConfCall = (LPHDRVCALL) pAsyncReqInfo->dwParam4;
HTAPICALL htConsultCall = (HTAPICALL) pAsyncReqInfo->dwParam5;
LPHDRVCALL lphdConsultCall = (LPHDRVCALL) pAsyncReqInfo->dwParam6;
LPLINECALLPARAMS lpCallParams = (LPLINECALLPARAMS) pAsyncReqInfo->dwParam7;
if (pAsyncReqInfo->lResult == 0)
{
if ((pAsyncReqInfo->lResult = AllocCall(
pLine,
htConfCall,
lpCallParams,
&pConfCall
)) == 0
&&
(pAsyncReqInfo->lResult = AllocCall(
pLine,
htConsultCall,
lpCallParams,
&pConsultCall
)) == 0
)
{
*lphdConfCall = (HDRVCALL) pConfCall;
*lphdConsultCall = (HDRVCALL) pConsultCall;
pConfCall->pNextConfChild = (pCall ? pCall : pConsultCall);
if (pCall)
{
pCall->pNextConfChild = pConsultCall;
pCall->pConfParent = pConfCall;
}
pConsultCall->pConfParent = pConfCall;
}
else if (pConfCall)
{
FreeCall (pConfCall);
}
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
if (pAsyncReqInfo->lResult == 0)
{
if (pCall)
{
SetCallState (pCall, LINECALLSTATE_CONFERENCED, 0);
}
SetCallState (pConfCall, LINECALLSTATE_ONHOLDPENDCONF, 0);
SetCallState (pConsultCall, LINECALLSTATE_DIALTONE, 0);
}
if (lpCallParams)
{
DrvFree (lpCallParams);
}
}
LONG
TSPIAPI
TSPI_lineSetupConference(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
HDRVLINE hdLine,
HTAPICALL htConfCall,
LPHDRVCALL lphdConfCall,
HTAPICALL htConsultCall,
LPHDRVCALL lphdConsultCall,
DWORD dwNumParties,
LPLINECALLPARAMS const lpCallParams
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall },
{ szhdLine, hdLine },
{ "htConfCall", htConfCall },
{ "lphdConfCall", lphdConfCall },
{ "htConsultCall", htConsultCall },
{ "lphdConsultCall", lphdConsultCall },
{ "dwNumParties", dwNumParties },
{ szlpCallParams, lpCallParams }
};
FUNC_INFO info = { "lineSetupConference", ASYNC, 9, params, TSPI_lineSetupConference_postProcess };
PDRVLINE pLine = (PDRVLINE) hdLine;
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdCall;
info.pAsyncReqInfo->dwParam2 = (DWORD) hdLine;
info.pAsyncReqInfo->dwParam3 = (DWORD) htConfCall;
info.pAsyncReqInfo->dwParam4 = (DWORD) lphdConfCall;
info.pAsyncReqInfo->dwParam5 = (DWORD) htConsultCall;
info.pAsyncReqInfo->dwParam6 = (DWORD) lphdConsultCall;
if (lpCallParams)
{
info.pAsyncReqInfo->dwParam7 = (DWORD) DrvAlloc(
(size_t) lpCallParams->dwTotalSize
);
memcpy(
(void far *) info.pAsyncReqInfo->dwParam7,
lpCallParams,
(size_t) lpCallParams->dwTotalSize
);
}
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_lineSetupTransfer_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
PDRVCALL pConsultCall = (PDRVCALL) NULL;
PDRVCALL pCall = (PDRVCALL) pAsyncReqInfo->dwParam1;
HTAPICALL htConsultCall = (HTAPICALL) pAsyncReqInfo->dwParam2;
LPHDRVCALL lphdConsultCall = (LPHDRVCALL) pAsyncReqInfo->dwParam3;
LPLINECALLPARAMS lpCallParams = (LPLINECALLPARAMS) pAsyncReqInfo->dwParam4;
if (pAsyncReqInfo->lResult == 0)
{
if ((pAsyncReqInfo->lResult = AllocCall(
pCall->pLine,
htConsultCall,
lpCallParams,
&pConsultCall
)) == 0
)
{
*lphdConsultCall = (HDRVCALL) pConsultCall;
}
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
if (pAsyncReqInfo->lResult == 0)
{
SetCallState (pCall, LINECALLSTATE_ONHOLD, 0);
SetCallState (pConsultCall, LINECALLSTATE_DIALTONE, 0);
}
if (lpCallParams)
{
DrvFree (lpCallParams);
}
}
LONG
TSPIAPI
TSPI_lineSetupTransfer(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
HTAPICALL htConsultCall,
LPHDRVCALL lphdConsultCall,
LPLINECALLPARAMS const lpCallParams
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall },
{ "htConsultCall", htConsultCall },
{ "lphdConsultCall", lphdConsultCall },
{ szlpCallParams, lpCallParams }
};
FUNC_INFO info = { "lineSetupTransfer", ASYNC, 5, params, TSPI_lineSetupTransfer_postProcess };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdCall;
info.pAsyncReqInfo->dwParam2 = (DWORD) htConsultCall;
info.pAsyncReqInfo->dwParam3 = (DWORD) lphdConsultCall;
if (lpCallParams)
{
info.pAsyncReqInfo->dwParam4 = (DWORD) DrvAlloc(
(size_t) lpCallParams->dwTotalSize
);
memcpy(
(void far *) info.pAsyncReqInfo->dwParam4,
(void far *) lpCallParams,
(size_t) lpCallParams->dwTotalSize
);
}
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_lineSwapHold_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
if ((pAsyncReqInfo->lResult == 0))
{
SetCallState(
(PDRVCALL) pAsyncReqInfo->dwParam1,
LINECALLSTATE_ONHOLD,
0
);
SetCallState(
(PDRVCALL) pAsyncReqInfo->dwParam2,
LINECALLSTATE_CONNECTED,
0
);
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
}
LONG
TSPIAPI
TSPI_lineSwapHold(
DRV_REQUESTID dwRequestID,
HDRVCALL hdActiveCall,
HDRVCALL hdHeldCall
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ "hdActiveCall", hdActiveCall },
{ "hdHeldCall", hdHeldCall }
};
FUNC_INFO info = { "lineSwapHold", ASYNC, 3, params, TSPI_lineSwapHold_postProcess };
PDRVCALL pActiveCall = (PDRVCALL) hdActiveCall;
PDRVCALL pHeldCall = (PDRVCALL) hdHeldCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdActiveCall;
info.pAsyncReqInfo->dwParam2 = (DWORD) hdHeldCall;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_lineUncompleteCall(
DRV_REQUESTID dwRequestID,
HDRVLINE hdLine,
DWORD dwCompletionID
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdLine, hdLine },
{ "dwCompletionID", dwCompletionID }
};
FUNC_INFO info = { "lineUncompleteCall", ASYNC, 3, params };
PDRVLINE pLine = (PDRVLINE) hdLine;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_lineUnhold_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
if ((pAsyncReqInfo->lResult == 0))
{
PDRVCALL pCall = (PDRVCALL) pAsyncReqInfo->dwParam1;
if (pCall->dwCallState == LINECALLSTATE_ONHOLD)
{
SetCallState (pCall, LINECALLSTATE_CONNECTED, 0);
}
else
{
pAsyncReqInfo->lResult = LINEERR_INVALCALLSTATE;
}
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
}
LONG
TSPIAPI
TSPI_lineUnhold(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdCall, hdCall },
};
FUNC_INFO info = { "lineUnhold", ASYNC, 2, params, TSPI_lineUnhold_postProcess };
PDRVCALL pCall = (PDRVCALL) hdCall;
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdCall;
return (Epilog (&info));
}
void
FAR
PASCAL
TSPI_lineUnpark_postProcess(
char far *lpszFuncName,
PASYNC_REQUEST_INFO pAsyncReqInfo,
BOOL bSync
)
{
PDRVCALL pCall;
PDRVLINE pLine = (PDRVLINE) pAsyncReqInfo->dwParam1;
DWORD dwAddressID = pAsyncReqInfo->dwParam2;
HTAPICALL htCall = (HTAPICALL) pAsyncReqInfo->dwParam3;
LPHDRVCALL lphdCall = (LPHDRVCALL) pAsyncReqInfo->dwParam4;
LPSTR lpszDestAddress = (LPSTR) pAsyncReqInfo->dwParam5;
if (pAsyncReqInfo->lResult == 0)
{
if ((pAsyncReqInfo->lResult = AllocCall (
pLine,
htCall,
NULL,
&pCall
)) == 0)
{
// BUGBUG deal w/ addr id
*lphdCall = (HDRVCALL) pCall;
}
}
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
bSync
);
if (pAsyncReqInfo->lResult == 0)
{
SetCallState (pCall, LINECALLSTATE_ONHOLD, 0);
}
if (lpszDestAddress)
{
DrvFree (lpszDestAddress);
}
}
LONG
TSPIAPI
TSPI_lineUnpark(
DRV_REQUESTID dwRequestID,
HDRVLINE hdLine,
DWORD dwAddressID,
HTAPICALL htCall,
LPHDRVCALL lphdCall,
LPCSTR lpszDestAddress
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdLine, hdLine },
{ "dwAddressID", dwAddressID },
{ "htCall", htCall },
{ "lphdCall", lphdCall },
{ "lpszDestAddress", lpszDestAddress }
};
FUNC_INFO info = { "lineUnpark", ASYNC, 6, params, TSPI_lineUnpark_postProcess };
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = (DWORD) hdLine;
info.pAsyncReqInfo->dwParam2 = dwAddressID;
info.pAsyncReqInfo->dwParam3 = (DWORD) htCall;
info.pAsyncReqInfo->dwParam4 = (DWORD) lphdCall;
if (lpszDestAddress)
{
size_t len = strlen (lpszDestAddress) + 1;
info.pAsyncReqInfo->dwParam5 = (DWORD) DrvAlloc (len);
memcpy(
(void far *) info.pAsyncReqInfo->dwParam5,
lpszDestAddress,
len
);
}
return (Epilog (&info));
}
//
// -------------------------- TSPI_phoneXxx funcs -----------------------------
//
LONG
TSPIAPI
TSPI_phoneClose(
HDRVPHONE hdPhone
)
{
FUNC_PARAM params[] =
{
{ szhdPhone, hdPhone }
};
FUNC_INFO info = { "phoneClose", SYNC, 1, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
//
// This is more of a "command" than a request, in that TAPI.DLL is
// going to consider the phone closed whether we like it or not.
// Therefore we want to free up the phone even if the user chooses
// to return an error.
//
if (!Prolog (&info))
{
// return (Epilog (&info));
}
pPhone->htPhone = (HTAPIPHONE) NULL;
//UpdateWidgetList();
PostUpdateWidgetListMsg();
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneConfigDialog(
DWORD dwDeviceID,
HWND hwndOwner,
LPCSTR lpszDeviceClass
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ szhwndOwner, hwndOwner },
{ "lpszDeviceClass", lpszDeviceClass }
};
FUNC_INFO info = { "phoneConfigDialog", SYNC, 3, params };
if (!Prolog (&info))
{
return (Epilog (&info));
}
//
// Note: MessageBox() implements a get/dispatch msg loop which allows
// other apps (or other windows within the calling app) to gain
// focus. Once these other windows/apps have focus, it's
// possible that they will call into TAPI, and this service
// provider could be re-entered.
//
MessageBox(
hwndOwner,
"Config dlg for ESP phone device",
"TSPI_phoneConfigDialog",
MB_OK
);
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneDevSpecific(
DRV_REQUESTID dwRequestID,
HDRVPHONE hdPhone,
LPVOID lpParams,
DWORD dwSize
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdPhone, hdPhone },
{ "lpParams", lpParams },
{ szdwSize, dwSize }
};
FUNC_INFO info =
{
"phoneDevSpecific",
ASYNC,
4,
params,
TSPI_lineDevSpecific_postProcess
};
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
info.pAsyncReqInfo->dwParam1 = lpParams;
info.pAsyncReqInfo->dwParam2 = dwSize;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneGetButtonInfo(
HDRVPHONE hdPhone,
DWORD dwButtonLampID,
LPPHONEBUTTONINFO lpButtonInfo
)
{
FUNC_PARAM params[] =
{
{ szhdPhone, hdPhone },
{ "dwButtonLampID", dwButtonLampID },
{ "lpButtonInfo", lpButtonInfo }
};
FUNC_INFO info = { "phoneGetButtonInfo", SYNC, 3, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneGetData(
HDRVPHONE hdPhone,
DWORD dwDataID,
LPVOID lpData,
DWORD dwSize
)
{
FUNC_PARAM params[] =
{
{ szhdPhone, hdPhone },
{ "dwDataID", dwDataID },
{ "lpData", lpData },
{ szdwSize, dwSize }
};
FUNC_INFO info = { "phoneGetData", SYNC, 4, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneGetDevCaps(
DWORD dwDeviceID,
DWORD dwTSPIVersion,
DWORD dwExtVersion,
LPPHONECAPS lpPhoneCaps
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ "dwTSPIVersion", dwTSPIVersion },
{ "dwExtVersion", dwExtVersion },
{ "lpPhoneCaps", lpPhoneCaps }
};
FUNC_INFO info = { "phoneGetDevCaps", SYNC, 4, params };
DWORD dwUsedSize;
PDRVPHONE pPhone = GetPhone (dwDeviceID);
if (!Prolog (&info))
{
return (Epilog (&info));
}
//
// Figure out how much caps data to copy
//
if (lpPhoneCaps->dwTotalSize >= pPhone->PhoneCaps.dwNeededSize)
{
dwUsedSize = pPhone->PhoneCaps.dwNeededSize;
}
else
{
dwUsedSize = sizeof(PHONECAPS);
}
memcpy(
&lpPhoneCaps->dwNeededSize,
&pPhone->PhoneCaps.dwNeededSize,
(size_t) dwUsedSize - 4 // - 4 since not overwriting dwTotalSize
);
lpPhoneCaps->dwUsedSize = dwUsedSize;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneGetDisplay(
HDRVPHONE hdPhone,
LPVARSTRING lpDisplay
)
{
FUNC_PARAM params[] =
{
{ szhdPhone, hdPhone },
{ "lpDisplay", lpDisplay }
};
FUNC_INFO info = { "phoneGetDisplay", SYNC, 2, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneGetExtensionID(
DWORD dwDeviceID,
DWORD dwTSPIVersion,
LPPHONEEXTENSIONID lpExtensionID
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ "dwTSPIVersion", dwTSPIVersion },
{ "lpExtensionID", lpExtensionID }
};
FUNC_INFO info = { "phoneGetExtensionID", SYNC, 3, params };
if (!Prolog (&info))
{
return (Epilog (&info));
}
memcpy (lpExtensionID, &gPhoneExtID, sizeof(PHONEEXTENSIONID));
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneGetGain(
HDRVPHONE hdPhone,
DWORD dwHookSwitchDev,
LPDWORD lpdwGain
)
{
FUNC_PARAM params[] =
{
{ szhdPhone, hdPhone },
{ "dwHookSwitchDev", dwHookSwitchDev },
{ "lpdwGain", lpdwGain }
};
FUNC_INFO info = { "phoneGetGain", SYNC, 3, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneGetHookSwitch(
HDRVPHONE hdPhone,
LPDWORD lpdwHookSwitchDevs
)
{
FUNC_PARAM params[] =
{
{ szhdPhone, hdPhone },
{ "lpdwHookSwitchDevs", lpdwHookSwitchDevs }
};
FUNC_INFO info = { "phoneGetHookSwitch", SYNC, 2, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneGetIcon(
DWORD dwDeviceID,
LPCSTR lpszDeviceClass,
LPHICON lphIcon
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ "lpszDeviceClass", lpszDeviceClass },
{ "lphIcon", lphIcon }
};
FUNC_INFO info = { "phoneGetIcon", SYNC, 3, params };
if (!Prolog (&info))
{
return (Epilog (&info));
}
*lphIcon = ghIconPhone;
return (Epilog (&info));
}
#ifdef WIN32
LONG
TSPIAPI
TSPI_phoneGetID(
HDRVPHONE hdPhone,
LPVARSTRING lpDeviceID,
LPCSTR lpszDeviceClass,
HANDLE hTargetProcess
)
#else
LONG
TSPIAPI
TSPI_phoneGetID(
HDRVPHONE hdPhone,
LPVARSTRING lpDeviceID,
LPCSTR lpszDeviceClass
)
#endif
{
FUNC_PARAM params[] =
{
{ szhdPhone, hdPhone },
{ "lpDeviceID", lpDeviceID },
{ "lpszDeviceClass", lpszDeviceClass }
#ifdef WIN32
,{ "hTargetProcess", hTargetProcess }
#endif
};
#ifdef WIN32
FUNC_INFO info = { "phoneGetID", SYNC, 4, params };
#else
FUNC_INFO info = { "phoneGetID", SYNC, 3, params };
#endif
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
DWORD i, dwDeviceID, dwNeededSize = sizeof(VARSTRING) + sizeof(DWORD);
if (!Prolog (&info))
{
return (Epilog (&info));
}
for (i = 0; aszDeviceClasses[i]; i++)
{
if (_stricmp (lpszDeviceClass, aszDeviceClasses[i]) == 0)
{
break;
}
}
if (!aszDeviceClasses[i])
{
info.lResult = PHONEERR_NODEVICE;
return (Epilog (&info));
}
if (lpDeviceID->dwTotalSize < dwNeededSize)
{
lpDeviceID->dwNeededSize = dwNeededSize;
lpDeviceID->dwUsedSize = 3 * sizeof(DWORD);
return (Epilog (&info));
}
if (i == 1)
{
dwDeviceID = pPhone->dwDeviceID;
}
else
{
if (gbShowLineGetIDDlg)
{
char szDlgTitle[64];
EVENT_PARAM params[] =
{
{ "dwDeviceID", PT_DWORD, gdwDefLineGetIDID, 0 }
};
EVENT_PARAM_HEADER paramsHeader =
{ 1, szDlgTitle, XX_REQRESULTPOSTQUIT, params };
HWND hwnd;
if (strlen (lpszDeviceClass) > 20)
{
((char far *)lpszDeviceClass)[19] = 0;
}
wsprintf(
szDlgTitle,
"TSPI_phoneGetID: select ID for class '%s'",
lpszDeviceClass
);
hwnd = CreateDialogParam(
hInst,
(LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
(HWND) NULL,
(DLGPROC) CallDlgProc,
(LPARAM) &paramsHeader
);
MsgLoopInTAPIClientContext (hwnd);
dwDeviceID = params[0].dwValue;
}
else
{
dwDeviceID = gdwDefLineGetIDID;
}
}
lpDeviceID->dwNeededSize =
lpDeviceID->dwUsedSize = dwNeededSize;
lpDeviceID->dwStringFormat = STRINGFORMAT_BINARY;
lpDeviceID->dwStringSize = sizeof(DWORD);
lpDeviceID->dwStringOffset = sizeof(VARSTRING);
*((LPDWORD)(lpDeviceID + 1)) = dwDeviceID;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneGetLamp(
HDRVPHONE hdPhone,
DWORD dwButtonLampID,
LPDWORD lpdwLampMode
)
{
FUNC_PARAM params[] =
{
{ szhdPhone, hdPhone },
{ "dwButtonLampID", dwButtonLampID },
{ "lpdwLampMode", lpdwLampMode }
};
FUNC_INFO info = { "phoneGetLamp", SYNC, 3, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneGetRing(
HDRVPHONE hdPhone,
LPDWORD lpdwRingMode,
LPDWORD lpdwVolume
)
{
FUNC_PARAM params[] =
{
{ szhdPhone, hdPhone },
{ "lpdwRingMode", lpdwRingMode },
{ "lpdwVolume", lpdwVolume }
};
FUNC_INFO info = { "phoneGetRing", SYNC, 3, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneGetStatus(
HDRVPHONE hdPhone,
LPPHONESTATUS lpPhoneStatus
)
{
FUNC_PARAM params[] =
{
{ szhdPhone, hdPhone },
{ "lpPhoneStatus", lpPhoneStatus }
};
FUNC_INFO info = { "phoneGetStatus", SYNC, 2, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
memcpy(
&lpPhoneStatus->dwNeededSize,
&pPhone->PhoneStatus.dwNeededSize,
sizeof(PHONESTATUS) - 4 // - 4 since not overwriting dwTotalSize
);
if (pPhone->PhoneStatus.dwDisplaySize)
{
lpPhoneStatus->dwNeededSize += pPhone->PhoneStatus.dwDisplaySize;
if (lpPhoneStatus->dwTotalSize >= lpPhoneStatus->dwNeededSize)
{
lpPhoneStatus->dwDisplaySize = pPhone->PhoneStatus.dwDisplaySize;
lpPhoneStatus->dwDisplayOffset = (DWORD) sizeof(PHONESTATUS);
strcpy(
((char far *) lpPhoneStatus) + sizeof(PHONESTATUS),
((char far *) &pPhone->PhoneStatus) +
pPhone->PhoneStatus.dwDisplayOffset
);
lpPhoneStatus->dwUsedSize = lpPhoneStatus->dwNeededSize;
}
}
//
// We're getting the LampModes field from the PhoneCaps
//
if (pPhone->PhoneCaps.dwLampModesSize)
{
lpPhoneStatus->dwNeededSize += pPhone->PhoneCaps.dwLampModesSize;
if (lpPhoneStatus->dwTotalSize >= lpPhoneStatus->dwNeededSize)
{
lpPhoneStatus->dwLampModesSize =
pPhone->PhoneCaps.dwLampModesSize;
lpPhoneStatus->dwLampModesOffset = lpPhoneStatus->dwUsedSize;
strcpy(
((char far *) lpPhoneStatus) +
lpPhoneStatus->dwLampModesOffset,
((char far *) &pPhone->PhoneCaps) +
pPhone->PhoneCaps.dwLampModesOffset
);
lpPhoneStatus->dwUsedSize = lpPhoneStatus->dwNeededSize;
}
}
//
// We're getting the DevSpecific field from the PhoneCaps
//
if (pPhone->PhoneCaps.dwDevSpecificSize)
{
lpPhoneStatus->dwNeededSize += pPhone->PhoneCaps.dwDevSpecificSize;
if (lpPhoneStatus->dwTotalSize >= lpPhoneStatus->dwNeededSize)
{
lpPhoneStatus->dwDevSpecificSize =
pPhone->PhoneCaps.dwDevSpecificSize;
lpPhoneStatus->dwDevSpecificOffset = lpPhoneStatus->dwUsedSize;
strcpy(
((char far *) lpPhoneStatus) +
lpPhoneStatus->dwDevSpecificOffset,
((char far *) &pPhone->PhoneCaps) +
pPhone->PhoneCaps.dwDevSpecificOffset
);
lpPhoneStatus->dwUsedSize = lpPhoneStatus->dwNeededSize;
}
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneGetVolume(
HDRVPHONE hdPhone,
DWORD dwHookSwitchDev,
LPDWORD lpdwVolume
)
{
FUNC_PARAM params[] =
{
{ szhdPhone, hdPhone },
{ "dwHookSwitchDev", dwHookSwitchDev, aHookSwitchDevs },
{ "lpdwVolume", lpdwVolume }
};
FUNC_INFO info = { "phoneGetVolume", SYNC, 3, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneNegotiateExtVersion(
DWORD dwDeviceID,
DWORD dwTSPIVersion,
DWORD dwLowVersion,
DWORD dwHighVersion,
LPDWORD lpdwExtVersion
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ "dwTSPIVersion", dwTSPIVersion },
{ "dwLowVersion", dwLowVersion },
{ "dwHighVersion", dwHighVersion },
{ "lpdwExtVersion", lpdwExtVersion }
};
FUNC_INFO info = { "phoneNegotiateExtVersion", SYNC, 5, params };
if (!Prolog (&info))
{
return (Epilog (&info));
}
ShowStr(
"TSPI_phonNegoExtVer: setting *lpdwExtVersion = x%lx",
dwHighVersion
);
*lpdwExtVersion = dwHighVersion;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneNegotiateTSPIVersion(
DWORD dwDeviceID,
DWORD dwLowVersion,
DWORD dwHighVersion,
LPDWORD lpdwTSPIVersion
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ "dwLowVersion", dwLowVersion },
{ "dwHighVersion", dwHighVersion },
{ "lpdwTSPIVersion", lpdwTSPIVersion }
};
FUNC_INFO info = { "phoneNegotiateTSPIVersion", SYNC, 4, params };
{
// BUGBUG hangs if gbManualResults set, so...
BOOL bManualResultsSav = gbManualResults;
gbManualResults = FALSE;
if (!Prolog (&info))
{
return (Epilog (&info));
}
gbManualResults = bManualResultsSav;
}
*lpdwTSPIVersion = gdwTSPIVersion;
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneOpen(
DWORD dwDeviceID,
HTAPIPHONE htPhone,
LPHDRVPHONE lphdPhone,
DWORD dwTSPIVersion,
PHONEEVENT lpfnEventProc
)
{
FUNC_PARAM params[] =
{
{ szdwDeviceID, dwDeviceID },
{ "htPhone", htPhone },
{ "lphdPhone", lphdPhone },
{ "dwTSPIVersion", dwTSPIVersion },
{ "lpfnEventProc", lpfnEventProc }
};
FUNC_INFO info = { "phoneOpen", SYNC, 5, params };
PDRVPHONE pPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
if (!(pPhone = GetPhone (dwDeviceID)))
{
// BUGBUG
}
pPhone->htPhone = htPhone;
pPhone->lpfnEventProc = lpfnEventProc;
*lphdPhone = (HDRVPHONE) pPhone;
//UpdateWidgetList();
PostUpdateWidgetListMsg();
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneSelectExtVersion(
HDRVPHONE hdPhone,
DWORD dwExtVersion
)
{
FUNC_PARAM params[] =
{
{ szhdPhone, hdPhone },
{ "dwExtVersion", dwExtVersion }
};
FUNC_INFO info = { "phoneSelectExtVersion", SYNC, 2, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneSetButtonInfo(
DRV_REQUESTID dwRequestID,
HDRVPHONE hdPhone,
DWORD dwButtonLampID,
LPPHONEBUTTONINFO const lpButtonInfo
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdPhone, hdPhone },
{ "dwButtonLampID", dwButtonLampID },
{ "lpButtonInfo", lpButtonInfo }
};
FUNC_INFO info = { "phoneSetButtonInfo", ASYNC, 4, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneSetData(
DRV_REQUESTID dwRequestID,
HDRVPHONE hdPhone,
DWORD dwDataID,
LPVOID const lpData,
DWORD dwSize
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdPhone, hdPhone },
{ "dwDataID", dwDataID },
{ "lpData", lpData },
{ szdwSize, dwSize }
};
FUNC_INFO info = { "phoneSetData", ASYNC, 5, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneSetDisplay(
DRV_REQUESTID dwRequestID,
HDRVPHONE hdPhone,
DWORD dwRow,
DWORD dwColumn,
LPCSTR lpsDisplay,
DWORD dwSize
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdPhone, hdPhone },
{ "dwRow", dwRow },
{ "dwColumn", dwColumn },
{ "lpsDisplay", lpsDisplay },
{ szdwSize, dwSize }
};
FUNC_INFO info = { "phoneSetDisplay", ASYNC, 6, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneSetGain(
DRV_REQUESTID dwRequestID,
HDRVPHONE hdPhone,
DWORD dwHookSwitchDev,
DWORD dwGain
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdPhone, hdPhone },
{ "dwHookSwitchDev", dwHookSwitchDev, aHookSwitchDevs },
{ "dwGain", dwGain }
};
FUNC_INFO info = { "phoneSetGain", ASYNC, 4, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneSetHookSwitch(
DRV_REQUESTID dwRequestID,
HDRVPHONE hdPhone,
DWORD dwHookSwitchDevs,
DWORD dwHookSwitchMode
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdPhone, hdPhone },
{ "dwHookSwitchDevs", dwHookSwitchDevs, aHookSwitchDevs },
{ "dwHookSwitchMode", dwHookSwitchMode, aHookSwitchModes }
};
FUNC_INFO info = { "phoneSetHookSwitch", ASYNC, 4, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneSetLamp(
DRV_REQUESTID dwRequestID,
HDRVPHONE hdPhone,
DWORD dwButtonLampID,
DWORD dwLampMode
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdPhone, hdPhone },
{ "dwButtonLampID", dwButtonLampID },
{ "dwLampMode", dwLampMode, aLampModes }
};
FUNC_INFO info = { "phoneSetLamp", ASYNC, 4, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneSetRing(
DRV_REQUESTID dwRequestID,
HDRVPHONE hdPhone,
DWORD dwRingMode,
DWORD dwVolume
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdPhone, hdPhone },
{ "dwRingMode", dwRingMode },
{ "dwVolume", dwVolume }
};
FUNC_INFO info = { "phoneSetRing", ASYNC, 4, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneSetStatusMessages(
HDRVPHONE hdPhone,
DWORD dwPhoneStates,
DWORD dwButtonModes,
DWORD dwButtonStates
)
{
FUNC_PARAM params[] =
{
{ szhdPhone, hdPhone },
{ "dwPhoneStates", dwPhoneStates, aPhoneStates },
{ "dwButtonModes", dwButtonModes, aButtonModes },
{ "dwButtonStates", dwButtonStates, aButtonStates }
};
FUNC_INFO info = { "phoneSetStatusMessages", SYNC, 4, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_phoneSetVolume(
DRV_REQUESTID dwRequestID,
HDRVPHONE hdPhone,
DWORD dwHookSwitchDev,
DWORD dwVolume
)
{
FUNC_PARAM params[] =
{
{ szdwRequestID, dwRequestID },
{ szhdPhone, hdPhone },
{ "dwHookSwitchDev", dwHookSwitchDev }, // BUGBUG lookup
{ "dwVolume", dwVolume }
};
FUNC_INFO info = { "phoneSetVolume", ASYNC, 4, params };
PDRVPHONE pPhone = (PDRVPHONE) hdPhone;
if (!Prolog (&info))
{
return (Epilog (&info));
}
return (Epilog (&info));
}
//
// ------------------------- TSPI_providerXxx funcs ---------------------------
//
LONG
TSPIAPI
TSPI_providerConfig(
HWND hwndOwner,
DWORD dwPermanentProviderID
)
{
FUNC_PARAM params[] =
{
{ szhwndOwner, hwndOwner },
{ szdwPermanentProviderID, dwPermanentProviderID }
};
FUNC_INFO info = { "providerConfig", SYNC, 2, params };
//
// Set gbExeStarted to TRUE so we don't get caught in the wait
// loop in Prolog, then reset it as appropriate
//
gbExeStarted = TRUE;
if (!Prolog (&info))
{
return (Epilog (&info));
}
ESPConfigDialog();
gbExeStarted = (ghwndMain ? TRUE : FALSE);
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_providerCreateLineDevice(
DWORD dwTempID,
DWORD dwDeviceID
)
{
FUNC_PARAM params[] =
{
{ "dwTempID", dwTempID },
{ szdwDeviceID, dwDeviceID }
};
FUNC_INFO info = { "providerCreateLineDevice", SYNC, 2, params };
if (!Prolog (&info))
{
return (Epilog (&info));
}
AllocLine (dwDeviceID);
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_providerCreatePhoneDevice(
DWORD dwTempID,
DWORD dwDeviceID
)
{
FUNC_PARAM params[] =
{
{ "dwTempID", dwTempID },
{ szdwDeviceID, dwDeviceID }
};
FUNC_INFO info = { "providerCreatePhoneDevice", SYNC, 2, params };
if (!Prolog (&info))
{
return (Epilog (&info));
}
AllocPhone (dwDeviceID);
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_providerEnumDevices(
DWORD dwPermanentProviderID,
LPDWORD lpdwNumLines,
LPDWORD lpdwNumPhones,
HPROVIDER hProvider,
LINEEVENT lpfnLineCreateProc,
PHONEEVENT lpfnPhoneCreateProc
)
{
FUNC_PARAM params[] =
{
{ szdwPermanentProviderID, dwPermanentProviderID },
{ "lpdwNumLines", lpdwNumLines },
{ "lpdwNumPhones", lpdwNumPhones },
{ "hProvider", hProvider },
{ "lpfnLineCreateProc", lpfnLineCreateProc },
{ "lpfnPhoneCreateProc", lpfnPhoneCreateProc }
};
FUNC_INFO info = { "providerEnumDevices", SYNC, 6, params };
{
// BUGBUG hangs if gbManualResults set, so...
BOOL bManualResultsSav = gbManualResults;
gbManualResults = FALSE;
if (!Prolog (&info))
{
return (Epilog (&info));
}
gbManualResults = bManualResultsSav;
}
*lpdwNumLines = gdwNumLines;
*lpdwNumPhones = gdwNumPhones;
gpfnLineCreateProc = lpfnLineCreateProc;
gpfnPhoneCreateProc = lpfnPhoneCreateProc;
ghProvider = hProvider;
return (Epilog (&info));
}
#ifdef WIN32
LONG
TSPIAPI
TSPI_providerInit(
DWORD dwTSPIVersion,
DWORD dwPermanentProviderID,
DWORD dwLineDeviceIDBase,
DWORD dwPhoneDeviceIDBase,
DWORD dwNumLines,
DWORD dwNumPhones,
ASYNC_COMPLETION lpfnCompletionProc,
LPDWORD lpdwTSPIOptions
)
#else
LONG
TSPIAPI
TSPI_providerInit(
DWORD dwTSPIVersion,
DWORD dwPermanentProviderID,
DWORD dwLineDeviceIDBase,
DWORD dwPhoneDeviceIDBase,
DWORD dwNumLines,
DWORD dwNumPhones,
ASYNC_COMPLETION lpfnCompletionProc
)
#endif
{
FUNC_PARAM params[] =
{
{ "dwTSPIVersion", dwTSPIVersion },
{ szdwPermanentProviderID, dwPermanentProviderID },
{ "dwLineDeviceIDBase", dwLineDeviceIDBase },
{ "dwPhoneDeviceIDBase", dwPhoneDeviceIDBase },
{ "dwNumLines", dwNumLines },
{ "dwNumPhones", dwNumPhones },
{ "lpfnCompletionProc", lpfnCompletionProc }
};
FUNC_INFO info = { "providerInit", SYNC, 7, params };
DWORD i;
LONG lResult;
#ifdef WIN32
*lpdwTSPIOptions = LINETSPIOPTION_NONREENTRANT;
#endif
{
// BUGBUG hangs if gbManualResults set, so...
BOOL bManualResultsSav = gbManualResults;
gbManualResults = FALSE;
if (!Prolog (&info))
{
return (Epilog (&info));
}
gbManualResults = bManualResultsSav;
}
gdwLineDeviceIDBase = dwLineDeviceIDBase;
gdwPermanentProviderID = dwPermanentProviderID;
gpfnCompletionProc = lpfnCompletionProc;
if (info.lResult == 0)
{
gdwNumInits++;
}
for (i = dwLineDeviceIDBase; i < (dwLineDeviceIDBase + dwNumLines); i++)
{
AllocLine (i);
}
for (i = dwPhoneDeviceIDBase; i < (dwPhoneDeviceIDBase + dwNumPhones); i++)
{
AllocPhone (i);
}
ghIconLine = LoadIcon (hInst, (LPCSTR)MAKEINTRESOURCE(IDI_ICON3));
ghIconPhone = LoadIcon (hInst, (LPCSTR)MAKEINTRESOURCE(IDI_ICON2));
if ((lResult = Epilog (&info)) == 0)
{
EnableWindow (GetDlgItem (ghwndMain, IDC_BUTTON1), TRUE);
EnableWindow (GetDlgItem (ghwndMain, IDC_BUTTON2), TRUE);
EnableWindow (GetDlgItem (ghwndMain, IDC_BUTTON3), TRUE);
}
return lResult;
}
LONG
TSPIAPI
TSPI_providerInstall(
HWND hwndOwner,
DWORD dwPermanentProviderID
)
{
FUNC_PARAM params[] =
{
{ szhwndOwner, hwndOwner },
{ szdwPermanentProviderID, dwPermanentProviderID }
};
FUNC_INFO info = { "providerInstall", SYNC, 2, params };
//
// Set gbExeStarted to TRUE so we don't get caught in the wait
// loop in Prolog, then reset it as appropriate
//
gbExeStarted = TRUE;
if (!Prolog (&info))
{
return (Epilog (&info));
}
gbExeStarted = (ghwndMain ? TRUE : FALSE);
//
// Check to see if we're already installed
//
if (IsESPInstalled (hwndOwner))
{
info.lResult = LINEERR_OPERATIONFAILED;
}
else
{
UpdateTelephonIni (dwPermanentProviderID);
}
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_providerRemove(
HWND hwndOwner,
DWORD dwPermanentProviderID
)
{
FUNC_PARAM params[] =
{
{ szhwndOwner, hwndOwner },
{ szdwPermanentProviderID, dwPermanentProviderID }
};
FUNC_INFO info = { "providerRemove", SYNC, 2, params };
char szProviderN[16];
//
// Set gbExeStarted to TRUE so we don't get caught in the wait
// loop in Prolog, then reset it as appropriate
//
gbExeStarted = TRUE;
if (!Prolog (&info))
{
return (Epilog (&info));
}
gbExeStarted = (ghwndMain ? TRUE : FALSE);
//
// Clean up the [ProviderN] section in telephon.ini
//
wsprintf (szProviderN, "%s%ld", szProvider, dwPermanentProviderID);
WritePrivateProfileString(
szProviderN,
(LPCSTR) NULL,
(LPCSTR) NULL,
szTelephonIni
);
return (Epilog (&info));
}
LONG
TSPIAPI
TSPI_providerShutdown(
DWORD dwTSPIVersion
)
{
FUNC_PARAM params[] =
{
{ "dwTSPIVersion", dwTSPIVersion }
};
FUNC_INFO info = { "providerShutdown", SYNC, 1, params };
LONG lResult;
{
// BUGBUG hangs if gbManualResults set, so...
BOOL bManualResultsSav = gbManualResults;
gbManualResults = FALSE;
if (!Prolog (&info))
{
return (Epilog (&info));
}
gbManualResults = bManualResultsSav;
}
if (info.lResult == 0)
{
gdwNumInits--;
}
//
// Since we're shutting down just tear everything down by hand
// (& save having to do all the MostMessage's, etc)
//
while (gaWidgets)
{
PDRVWIDGET pNextWidget = gaWidgets->pNext;
DrvFree (gaWidgets);
gaWidgets = pNextWidget;
}
SendMessage (ghwndList1, LB_RESETCONTENT, 0, 0);
if (gbAutoClose)
{
PostMessage (ghwndMain, WM_CLOSE, 0, 0);
}
DestroyIcon (ghIconLine);
DestroyIcon (ghIconPhone);
ghProvider = NULL;
#ifdef WIN32
SaveIniSettings();
#endif
lResult = Epilog (&info);
#ifdef WIN32
PostMessage (ghwndMain, WM_CLOSE, 0, 0);
WaitForSingleObject (ghMsgLoopThread, INFINITE);
CloseHandle (ghMsgLoopThread);
ghMsgLoopThread = NULL;
#endif
//
// Disable the buttons so the user doesn't press one & cause a GPF
//
EnableWindow (GetDlgItem (ghwndMain, IDC_BUTTON1), FALSE);
EnableWindow (GetDlgItem (ghwndMain, IDC_BUTTON2), FALSE);
EnableWindow (GetDlgItem (ghwndMain, IDC_BUTTON3), FALSE);
return lResult;
}
#pragma warning (default:4047)
//
// ------------------------ Private support routines --------------------------
//
VOID
ShowStr(
char *format,
...
)
{
static char buf[256], bigBuf[2048] = "";
static int iTextLen = 1;
int len;
va_list ap;
if (gbDisableUI)
{
return;
}
va_start(ap, format);
// BUGBUG what if !ghwndMain
wvsprintf (buf, format, ap);
strcat (buf, "\r\n");
len = (int) strlen (buf);
if ((iTextLen + len) <= 2048)
{
iTextLen += len;
//
// Cat the new buf to the global buf that contains all the text
// that'll get added to the edit control the next time a
// WM_ADDTEXT msg is processed
//
#ifdef WIN32
WaitForSingleObject (ghShowStrBufMutex, INFINITE);
#endif
if (bigBuf[0] == 0)
{
//
// The handler for WM_ADDTEXT zeroes out the first byte in the
// buffer when it has added the text to the edit control, so if
// here we know we need to post another msg to alert that more
// text needs to be added
//
PostMessage(
ghwndMain,
WM_ADDTEXT,
ESP_MSG_KEY,
(LPARAM) bigBuf
);
iTextLen = 1; // to acct for null terminator
}
strcat (bigBuf, buf);
#ifdef WIN32
ReleaseMutex (ghShowStrBufMutex);
#endif
}
else
{
OutputDebugString ("ESP.TSP: buf overflow:\t");
OutputDebugString (buf);
}
va_end(ap);
}
BOOL
ScanForDWORD(
char far *pBuf,
LPDWORD lpdw
)
{
char c;
BOOL bValid = FALSE;
DWORD d = 0;
while ((c = *pBuf))
{
if ((c >= '0') && (c <= '9'))
{
c -= '0';
}
else if ((c >= 'a') && (c <= 'f'))
{
c -= ('a' - 10);
}
else if ((c >= 'A') && (c <= 'F'))
{
c -= ('A' - 10);
}
else
{
break;
}
bValid = TRUE;
d *= 16;
d += (DWORD) c;
pBuf++;
}
if (bValid)
{
*lpdw = d;
}
return bValid;
}
void
UpdateTelephonIni(
DWORD dwPermanentProviderID
)
{
//
// 1.3 Support: write out the num lines & phones we support to
// [ProviderN] section in telephon.ini
//
char buf[16], szProviderN[16];
wsprintf (szProviderN, "%s%ld", szProvider, dwPermanentProviderID);
wsprintf (buf, "%ld", gdwNumLines);
WritePrivateProfileString(
szProviderN,
"NumLines",
buf,
szTelephonIni
);
wsprintf (buf, "%ld", gdwNumPhones);
WritePrivateProfileString(
szProviderN,
"NumPhones",
buf,
szTelephonIni
);
}
char far *
GetFlags(
DWORD dwFlags,
PLOOKUP pLookup
)
{
int i;
static char buf[256];
char far *p = (char far *) NULL;
buf[0] = 0;
for (i = 0; (dwFlags && (pLookup[i].dwVal != 0xffffffff)); i++)
{
if (dwFlags & pLookup[i].dwVal)
{
strcat (buf, pLookup[i].lpszVal);
strcat (buf, " ");
dwFlags = dwFlags & (~pLookup[i].dwVal);
}
}
if (buf[0])
{
if ((p = (char far *) DrvAlloc (strlen (buf) + 1)))
{
strcpy (p, buf);
}
}
return p;
}
void
ShowLineEvent(
HTAPILINE htLine,
HTAPICALL htCall,
DWORD dwMsg,
DWORD dwParam1,
DWORD dwParam2,
DWORD dwParam3
)
{
if (gbShowEvents)
{
static DWORD adwLineMsgs[] =
{
LINE_ADDRESSSTATE,
LINE_CALLINFO,
LINE_CALLSTATE,
LINE_CLOSE,
LINE_DEVSPECIFIC,
LINE_DEVSPECIFICFEATURE,
LINE_GATHERDIGITS,
LINE_GENERATE,
LINE_LINEDEVSTATE,
LINE_MONITORDIGITS,
LINE_MONITORMEDIA,
LINE_MONITORTONE,
LINE_CREATE,
LINE_NEWCALL,
LINE_CALLDEVSPECIFIC,
LINE_CALLDEVSPECIFICFEATURE,
0xffffffff
};
static char *aszLineMsgs[] =
{
"LINE_ADDRESSSTATE",
"LINE_CALLINFO",
"LINE_CALLSTATE",
"LINE_CLOSE",
"LINE_DEVSPECIFIC",
"LINE_DEVSPECIFICFEATURE",
"LINE_GATHERDIGITS",
"LINE_GENERATE",
"LINE_LINEDEVSTATE",
"LINE_MONITORDIGITS",
"LINE_MONITORMEDIA",
"LINE_MONITORTONE",
"LINE_CREATE",
"LINE_NEWCALL",
"LINE_CALLDEVSPECIFIC",
"LINE_CALLDEVSPECIFICFEATURE"
};
int i;
char far *lpszParam1 = (char far *) NULL;
char far *lpszParam2 = (char far *) NULL;
char far *lpszParam3 = (char far *) NULL;
for (i = 0; adwLineMsgs[i] != 0xffffffff; i++)
{
if (dwMsg == adwLineMsgs[i])
{
ShowStr(
"%ssent %s : htLine=x%lx, htCall=x%lx",
szCallUp,
aszLineMsgs[i],
htLine,
htCall
);
break;
}
}
if (adwLineMsgs[i] == 0xffffffff)
{
ShowStr(
"%ssent <unknown msg id, x%lx> : htLine=x%lx, htCall=x%lx",
szCallUp,
dwMsg,
htLine,
htCall
);
}
switch (dwMsg)
{
case LINE_ADDRESSSTATE:
lpszParam2 = GetFlags (dwParam2, aAddressStates);
break;
case LINE_CALLINFO:
lpszParam1 = GetFlags (dwParam1, aCallInfoStates);
break;
case LINE_CALLSTATE:
lpszParam1 = GetFlags (dwParam1, aCallStates);
break;
case LINE_LINEDEVSTATE:
lpszParam1 = GetFlags (dwParam1, aLineStates);
break;
} // switch
ShowStr(
"%s%sdwParam1=x%lx, %s",
szCallUp,
szTab,
dwParam1,
(lpszParam1 ? lpszParam1 : "")
);
ShowStr(
"%s%sdwParam2=x%lx, %s",
szCallUp,
szTab,
dwParam2,
(lpszParam2 ? lpszParam2 : "")
);
ShowStr(
"%s%sdwParam3=x%lx, %s",
szCallUp,
szTab,
dwParam3,
(lpszParam3 ? lpszParam3 : "")
);
if (lpszParam1)
{
DrvFree (lpszParam1);
}
if (lpszParam2)
{
DrvFree (lpszParam2);
}
if (lpszParam3)
{
DrvFree (lpszParam3);
}
}
}
void
ShowPhoneEvent(
HTAPIPHONE htPhone,
DWORD dwMsg,
DWORD dwParam1,
DWORD dwParam2,
DWORD dwParam3
)
{
if (gbShowEvents)
{
static char *aszPhoneMsgs[] =
{
"PHONE_BUTTON",
"PHONE_CLOSE",
"PHONE_DEVSPECIFIC",
"PHONE_REPLY",
"PHONE_STATE",
"PHONE_CREATE"
};
char far *lpszParam1 = (char far *) NULL;
char far *lpszParam2 = (char far *) NULL;
char far *lpszParam3 = (char far *) NULL;
if ((dwMsg < PHONE_BUTTON) ||
((dwMsg > PHONE_STATE) && (dwMsg != PHONE_CREATE)))
{
ShowStr(
"%ssent <unknown msg id, x%lx> : htPhone=x%lx",
szCallUp,
dwMsg,
htPhone
);
}
else
{
//
// Munge dwMsg so that we get the right index into aszLineMsgs
//
if (dwMsg == PHONE_CREATE)
{
dwMsg = 5;
}
else
{
dwMsg -= PHONE_BUTTON;
}
ShowStr(
"%ssent %s : htPhone=x%lx",
szCallUp,
aszPhoneMsgs[dwMsg],
htPhone
);
}
switch (dwMsg)
{
case PHONE_BUTTON:
lpszParam2 = GetFlags (dwParam2, aButtonModes);
lpszParam3 = GetFlags (dwParam3, aButtonStates);
break;
case PHONE_STATE:
lpszParam1 = GetFlags (dwParam1, aPhoneStates);
break;
} // switch
ShowStr(
"%s%sdwParam1=x%lx, %s",
szCallUp,
szTab,
dwParam1,
(lpszParam1 ? lpszParam1 : "")
);
ShowStr(
"%s%sdwParam2=x%lx, %s",
szCallUp,
szTab,
dwParam2,
(lpszParam2 ? lpszParam2 : "")
);
ShowStr(
"%s%sdwParam3=x%lx, %s",
szCallUp,
szTab,
dwParam3,
(lpszParam3 ? lpszParam3 : "")
);
if (lpszParam1)
{
DrvFree (lpszParam1);
}
if (lpszParam2)
{
DrvFree (lpszParam2);
}
if (lpszParam3)
{
DrvFree (lpszParam3);
}
}
}
BOOL
CALLBACK
AboutDlgProc(
HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
switch (msg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
EndDialog (hwnd, 0);
break;
}
break;
#ifdef WIN32
case WM_CTLCOLORSTATIC:
SetBkColor ((HDC) wParam, RGB (192,192,192));
return (BOOL) GetStockObject (LTGRAY_BRUSH);
#else
case WM_CTLCOLOR:
{
if (HIWORD(lParam) == CTLCOLOR_STATIC)
{
SetBkColor ((HDC) wParam, RGB (192,192,192));
return (BOOL) GetStockObject (LTGRAY_BRUSH);
}
break;
}
#endif
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint (hwnd, &ps);
FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH));
EndPaint (hwnd, &ps);
break;
}
}
return FALSE;
}
BOOL
__loadds
CALLBACK
CallDlgProc(
HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
DWORD i;
typedef struct _DLG_INST_DATA
{
PEVENT_PARAM_HEADER pParamsHeader;
LONG lLastSel;
char szComboText[MAX_STRING_PARAM_SIZE];
HGLOBAL hComboDS;
LPVOID pComboSeg;
HWND hwndCombo;
} DLG_INST_DATA, *PDLG_INST_DATA;
PDLG_INST_DATA pDlgInstData = (PDLG_INST_DATA)
GetWindowLong (hwnd, DWL_USER);
switch (msg)
{
case WM_INITDIALOG:
{
//
// Alloc a dlg instance data struct, init it, & save a ptr to it
//
pDlgInstData = (PDLG_INST_DATA) DrvAlloc (sizeof(DLG_INST_DATA));
// BUGBUG if (!pDlgInstData)
pDlgInstData->pParamsHeader = (PEVENT_PARAM_HEADER) lParam;
pDlgInstData->lLastSel = -1;
SetWindowLong (hwnd, DWL_USER, (LONG) pDlgInstData);
#ifndef WIN32
{
//
// Go thru the hassle of creating combobox on the fly because
// otherwise we'll blow up when the combo tries to use our DS
// for it's heap.
//
RECT rect = { 116, 16, 80, 47 };
pDlgInstData->hComboDS = GlobalAlloc(
GMEM_DDESHARE | GMEM_MOVEABLE | GMEM_ZEROINIT,
2048
);
pDlgInstData->pComboSeg = GlobalLock (pDlgInstData->hComboDS);
LocalInit(
HIWORD(pDlgInstData->pComboSeg),
0,
(UINT) (GlobalSize (pDlgInstData->hComboDS) - 16)
);
UnlockSegment ((UINT)HIWORD(pDlgInstData->pComboSeg));
MapDialogRect (hwnd, &rect);
pDlgInstData->hwndCombo = CreateWindow(
"combobox",
NULL,
WS_CHILD | WS_VISIBLE | CBS_SIMPLE | CBS_NOINTEGRALHEIGHT |
CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP,
rect.left,
rect.top,
rect.right,
rect.bottom,
hwnd,
(HMENU) IDC_COMBO1,
(HINSTANCE) HIWORD(pDlgInstData->pComboSeg),
NULL
);
}
#endif
//
// Limit the max text length for the combobox's edit field
// (NOTE: A combobox ctrl actually has two child windows: a
// edit ctrl & a listbox. We need to get the hwnd of the
// child edit ctrl & send it the LIMITTEXT msg.)
//
{
HWND hwndChild = GetWindow (pDlgInstData->hwndCombo, GW_CHILD);
while (hwndChild)
{
char buf[8];
GetClassName (hwndChild, buf, 7);
if (_stricmp (buf, "edit") == 0)
{
break;
}
hwndChild = GetWindow (hwndChild, GW_HWNDNEXT);
}
SendMessage(
hwndChild,
EM_LIMITTEXT,
(WPARAM) MAX_STRING_PARAM_SIZE - 1,
0
);
}
//
// Misc other init
//
pDlgInstData->pParamsHeader = (PEVENT_PARAM_HEADER) lParam;
SetWindowText (hwnd, pDlgInstData->pParamsHeader->pszDlgTitle);
for (i = 0; i < pDlgInstData->pParamsHeader->dwNumParams; i++)
{
SendDlgItemMessage(
hwnd,
IDC_LIST1,
LB_INSERTSTRING,
(WPARAM) -1,
(LPARAM) pDlgInstData->pParamsHeader->aParams[i].szName
);
}
break;
}
case WM_COMMAND:
{
LONG lLastSel = pDlgInstData->lLastSel;
char far *lpszComboText = pDlgInstData->szComboText;
PEVENT_PARAM_HEADER pParamsHeader = pDlgInstData->pParamsHeader;
switch (LOWORD(wParam))
{
case IDOK:
if (lLastSel != -1)
{
char buf[MAX_STRING_PARAM_SIZE];
//
// Save val of currently selected param
//
i = GetDlgItemText (hwnd, IDC_COMBO1, buf, MAX_STRING_PARAM_SIZE-1);
switch (pParamsHeader->aParams[lLastSel].dwType)
{
case PT_STRING:
{
LONG lComboSel;
lComboSel = SendDlgItemMessage(
hwnd,
IDC_COMBO1,
CB_GETCURSEL,
0,
0
);
if (lComboSel == 0) // "NULL string (dwXxxSize = 0)"
{
pParamsHeader->aParams[lLastSel].dwValue = (DWORD) 0;
}
else // "Valid string"
{
strncpy(
pParamsHeader->aParams[lLastSel].u.buf,
buf,
MAX_STRING_PARAM_SIZE - 1
);
pParamsHeader->aParams[lLastSel].u.buf[MAX_STRING_PARAM_SIZE-1] = 0;
pParamsHeader->aParams[lLastSel].dwValue = (DWORD)
pParamsHeader->aParams[lLastSel].u.buf;
}
break;
}
case PT_DWORD:
case PT_FLAGS:
case PT_ORDINAL:
{
if (!ScanForDWORD(
buf,
&pParamsHeader->aParams[lLastSel].dwValue
))
{
//
// Default to 0
//
pParamsHeader->aParams[lLastSel].dwValue = 0;
}
break;
}
} // switch
}
// Drop thru to IDCANCEL cleanup code
case IDCANCEL:
#ifndef WIN32
DestroyWindow (pDlgInstData->hwndCombo);
GlobalFree (pDlgInstData->hComboDS);
#endif
DrvFree (pDlgInstData);
EndDialog (hwnd, (int)LOWORD(wParam));
if (pParamsHeader->dwEventType == XX_REQRESULTPOSTQUIT)
{
PostQuitMessage(0);
}
break;
case IDC_LIST1:
#ifdef WIN32
if (HIWORD(wParam) == LBN_SELCHANGE)
#else
if (HIWORD(lParam) == LBN_SELCHANGE)
#endif
{
char buf[MAX_STRING_PARAM_SIZE] = "";
LPCSTR lpstr = buf;
LONG lSel =
SendDlgItemMessage (hwnd, IDC_LIST1, LB_GETCURSEL, 0, 0);
if (lLastSel != -1)
{
//
// Save the old param value
//
i = GetDlgItemText(
hwnd,
IDC_COMBO1,
buf,
MAX_STRING_PARAM_SIZE - 1
);
switch (pParamsHeader->aParams[lLastSel].dwType)
{
case PT_STRING:
{
LONG lComboSel;
lComboSel = SendDlgItemMessage(
hwnd,
IDC_COMBO1,
CB_GETCURSEL,
0,
0
);
if (lComboSel == 0) // "NULL string (dwXxxSize = 0)"
{
pParamsHeader->aParams[lLastSel].dwValue = (DWORD)0;
}
else // "Valid string" or no sel
{
strncpy(
pParamsHeader->aParams[lLastSel].u.buf,
buf,
MAX_STRING_PARAM_SIZE - 1
);
pParamsHeader->aParams[lLastSel].u.buf[MAX_STRING_PARAM_SIZE - 1] = 0;
pParamsHeader->aParams[lLastSel].dwValue = (DWORD)
pParamsHeader->aParams[lLastSel].u.buf;
}
break;
}
case PT_DWORD:
case PT_FLAGS:
case PT_ORDINAL:
{
if (!ScanForDWORD(
buf,
&pParamsHeader->aParams[lLastSel].dwValue
))
{
//
// Default to 0
//
pParamsHeader->aParams[lLastSel].dwValue = 0;
}
break;
}
} // switch
}
SendDlgItemMessage (hwnd, IDC_LIST2, LB_RESETCONTENT, 0, 0);
SendDlgItemMessage (hwnd, IDC_COMBO1, CB_RESETCONTENT, 0, 0);
switch (pParamsHeader->aParams[lSel].dwType)
{
case PT_STRING:
{
char * aszOptions[] =
{
"NUL (dwXxxSize=0)",
"Valid string"
};
for (i = 0; i < 2; i++)
{
SendDlgItemMessage(
hwnd,
IDC_COMBO1,
CB_INSERTSTRING,
(WPARAM) -1,
(LPARAM) aszOptions[i]
);
}
if (pParamsHeader->aParams[lSel].dwValue == 0)
{
i = 0;
buf[0] = 0;
}
else
{
i = 1;
lpstr = (LPCSTR) pParamsHeader->aParams[lSel].dwValue;
}
SendDlgItemMessage(
hwnd,
IDC_COMBO1,
CB_SETCURSEL,
(WPARAM) i,
0
);
break;
}
case PT_DWORD:
{
SendDlgItemMessage(
hwnd,
IDC_COMBO1,
CB_INSERTSTRING,
(WPARAM) -1,
(LPARAM) (char far *) "0000000"
);
if (pParamsHeader->aParams[lSel].u.dwDefValue)
{
//
// Add the default val string to the combo
//
wsprintf(
buf,
"%08lx",
pParamsHeader->aParams[lSel].u.dwDefValue
);
SendDlgItemMessage(
hwnd,
IDC_COMBO1,
CB_INSERTSTRING,
(WPARAM) -1,
(LPARAM) buf
);
}
SendDlgItemMessage(
hwnd,
IDC_COMBO1,
CB_INSERTSTRING,
(WPARAM) -1,
(LPARAM) (char far *) "ffffffff"
);
wsprintf(
buf,
"%08lx",
pParamsHeader->aParams[lSel].dwValue
);
break;
}
case PT_ORDINAL:
{
//
// Stick the bit flag strings in the list box
//
HWND hwndList2 = GetDlgItem (hwnd, IDC_LIST2);
PLOOKUP pLookup = (PLOOKUP)
pParamsHeader->aParams[lSel].u.pLookup;
for (i = 0; pLookup[i].dwVal != 0xffffffff; i++)
{
SendMessage(
hwndList2,
LB_INSERTSTRING,
(WPARAM) -1,
(LPARAM) pLookup[i].lpszVal
);
if (pParamsHeader->aParams[lSel].dwValue ==
pLookup[i].dwVal)
{
SendMessage(
hwndList2,
LB_SETSEL,
(WPARAM) TRUE,
(LPARAM) MAKELPARAM((WORD)i,0)
);
}
}
SendDlgItemMessage(
hwnd,
IDC_COMBO1,
CB_INSERTSTRING,
(WPARAM) -1,
(LPARAM) (char far *) "select none"
);
wsprintf(
buf,
"%08lx",
pParamsHeader->aParams[lSel].dwValue
);
break;
}
case PT_FLAGS:
{
//
// Stick the bit flag strings in the list box
//
HWND hwndList2 = GetDlgItem (hwnd, IDC_LIST2);
PLOOKUP pLookup = (PLOOKUP)
pParamsHeader->aParams[lSel].u.pLookup;
for (i = 0; pLookup[i].dwVal != 0xffffffff; i++)
{
SendMessage(
hwndList2,
LB_INSERTSTRING,
(WPARAM) -1,
(LPARAM) pLookup[i].lpszVal
);
if (pParamsHeader->aParams[lSel].dwValue &
pLookup[i].dwVal)
{
SendMessage(
hwndList2,
LB_SETSEL,
(WPARAM) TRUE,
(LPARAM) MAKELPARAM((WORD)i,0)
);
}
}
SendDlgItemMessage(
hwnd,
IDC_COMBO1,
CB_INSERTSTRING,
(WPARAM) -1,
(LPARAM) (char far *) "select none"
);
SendDlgItemMessage(
hwnd,
IDC_COMBO1,
CB_INSERTSTRING,
(WPARAM) -1,
(LPARAM) (char far *) "select all"
);
wsprintf(
buf,
"%08lx",
pParamsHeader->aParams[lSel].dwValue
);
break;
}
} //switch
SetDlgItemText (hwnd, IDC_COMBO1, lpstr);
pDlgInstData->lLastSel = lSel;
}
break;
case IDC_LIST2:
#ifdef WIN32
if (HIWORD(wParam) == LBN_SELCHANGE)
#else
if (HIWORD(lParam) == LBN_SELCHANGE)
#endif
{
//
// BUGBUG in the PT_ORDINAL case we should compare the
// currently selected item(s) against the previous DWORD
// val and figure out which item we need to deselect,
// if any, in order to maintain a mutex of values
//
PLOOKUP pLookup = (PLOOKUP)
pParamsHeader->aParams[lLastSel].u.pLookup;
char buf[16];
DWORD dwValue = 0;
int far *ai;
LONG i, lSelCount =
SendDlgItemMessage (hwnd, IDC_LIST2, LB_GETSELCOUNT, 0, 0);
ai = (int far *) DrvAlloc ((size_t)lSelCount * sizeof(int));
SendDlgItemMessage(
hwnd,
IDC_LIST2,
LB_GETSELITEMS,
(WPARAM) lSelCount,
(LPARAM) ai
);
if (pParamsHeader->aParams[lLastSel].dwType == PT_FLAGS)
{
for (i = 0; i < lSelCount; i++)
{
dwValue |= pLookup[ai[i]].dwVal;
}
}
else // if (.dwType == PT_ORDINAL)
{
if (lSelCount == 1)
{
dwValue = pLookup[ai[0]].dwVal;
}
else if (lSelCount == 2)
{
//
// Figure out which item we need to de-select, since
// we're doing ordinals & only want 1 item selected
// at a time
//
GetDlgItemText (hwnd, IDC_COMBO1, buf, 16);
if (ScanForDWORD (buf, &dwValue))
{
if (pLookup[ai[0]].dwVal == dwValue)
{
SendDlgItemMessage(
hwnd,
IDC_LIST2,
LB_SETSEL,
0,
(LPARAM) ai[0]
);
dwValue = pLookup[ai[1]].dwVal;
}
else
{
SendDlgItemMessage(
hwnd,
IDC_LIST2,
LB_SETSEL,
0,
(LPARAM) ai[1]
);
dwValue = pLookup[ai[0]].dwVal;
}
}
else
{
// BUGBUG de-select items???
dwValue = 0;
}
}
else if (lSelCount > 2)
{
//
// Determine previous selection & de-select all the
// latest selections
//
GetDlgItemText (hwnd, IDC_COMBO1, buf, 16);
if (ScanForDWORD (buf, &dwValue))
{
for (i = 0; i < lSelCount; i++)
{
if (pLookup[ai[i]].dwVal != dwValue)
{
SendDlgItemMessage(
hwnd,
IDC_LIST2,
LB_SETSEL,
0,
(LPARAM) ai[i]
);
}
}
}
else
{
// BUGBUG de-select items???
dwValue = 0;
}
}
}
DrvFree (ai);
wsprintf (buf, "%08lx", dwValue);
SetDlgItemText (hwnd, IDC_COMBO1, buf);
}
break;
case IDC_COMBO1:
#ifdef WIN32
switch (HIWORD(wParam))
#else
switch (HIWORD(lParam))
#endif
{
case CBN_SELCHANGE:
{
LONG lSel =
SendDlgItemMessage (hwnd, IDC_COMBO1, CB_GETCURSEL, 0, 0);
switch (pParamsHeader->aParams[lLastSel].dwType)
{
case PT_ORDINAL:
//
// The only option here is "select none"
//
strcpy (lpszComboText, "00000000");
PostMessage (hwnd, WM_USER+55, 0, 0);
break;
case PT_FLAGS:
{
BOOL bSelect = (lSel ? TRUE : FALSE);
SendDlgItemMessage(
hwnd,
IDC_LIST2,
LB_SETSEL,
(WPARAM) bSelect,
(LPARAM) -1
);
if (bSelect)
{
PLOOKUP pLookup = (PLOOKUP)
pParamsHeader->aParams[lLastSel].u.pLookup;
DWORD dwValue = 0;
int far *ai;
LONG i, lSelCount =
SendDlgItemMessage (hwnd, IDC_LIST2, LB_GETSELCOUNT, 0, 0);
ai = (int far *) DrvAlloc(
(size_t)lSelCount * sizeof(int)
);
SendDlgItemMessage(
hwnd,
IDC_LIST2,
LB_GETSELITEMS,
(WPARAM) lSelCount,
(LPARAM) ai
);
for (i = 0; i < lSelCount; i++)
{
dwValue |= pLookup[ai[i]].dwVal;
}
DrvFree (ai);
wsprintf (lpszComboText, "%08lx", dwValue);
}
else
{
strcpy (lpszComboText, "00000000");
}
PostMessage (hwnd, WM_USER+55, 0, 0);
break;
}
case PT_STRING:
if (lSel == 1)
{
strncpy(
lpszComboText,
pParamsHeader->aParams[lLastSel].u.buf,
MAX_STRING_PARAM_SIZE
);
lpszComboText[MAX_STRING_PARAM_SIZE-1] = 0;
}
else
{
lpszComboText[0] = 0;
}
PostMessage (hwnd, WM_USER+55, 0, 0);
break;
case PT_DWORD:
break;
} // switch
break;
}
case CBN_EDITCHANGE:
{
//
// If user entered text in the edit field then copy the
// text to our buffer
//
if (pParamsHeader->aParams[lLastSel].dwType == PT_STRING)
{
char buf[MAX_STRING_PARAM_SIZE];
GetDlgItemText(
hwnd,
IDC_COMBO1,
buf,
MAX_STRING_PARAM_SIZE
);
strncpy(
pParamsHeader->aParams[lLastSel].u.buf,
buf,
MAX_STRING_PARAM_SIZE
);
pParamsHeader->aParams[lLastSel].u.buf
[MAX_STRING_PARAM_SIZE-1] = 0;
}
break;
}
} // switch
} // switch
break;
}
case WM_USER+55:
SetDlgItemText (hwnd, IDC_COMBO1, pDlgInstData->szComboText);
break;
#ifdef WIN32
case WM_CTLCOLORSTATIC:
SetBkColor ((HDC) wParam, RGB (192,192,192));
return (BOOL) GetStockObject (LTGRAY_BRUSH);
#else
case WM_CTLCOLOR:
{
if (HIWORD(lParam) == CTLCOLOR_STATIC)
{
SetBkColor ((HDC) wParam, RGB (192,192,192));
return (BOOL) GetStockObject (LTGRAY_BRUSH);
}
break;
}
#endif
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint (hwnd, &ps);
FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH));
EndPaint (hwnd, &ps);
break;
}
}
return FALSE;
}
void
MsgLoopInTAPIClientContext(
HWND hwnd
)
{
//
// -> See NOTE #2 in header above for info on the following
//
// We're filtering msgs here, only letting thru those which are
// destined for the dlg or it's children- we don't want to run
// into a situation where we're re-entering an app that's not
// expecting to be re-entered.
//
// Also, there's a special case in the dlg proc in which a quit
// msg will get posted when the dlg is dismissed so we'll drop
// out of this msg loop
//
MSG msg;
while (1)
{
if (PeekMessage (&msg, hwnd, 0, 0, PM_NOYIELD | PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
break;
}
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
DestroyWindow (hwnd);
}
BOOL
Prolog(
PFUNC_INFO pInfo
)
{
BOOL bLineFunc = (pInfo->lpszFuncName[1] != 'h');
DWORD i, j;
#ifdef WIN32
// BUGBUG move this to the first func called (TSPI nego?)
while (!gbExeStarted)
{
Sleep (0);
}
#else
if (!gbExeStarted)
{
UINT uiResult = WinExec ("espexe.exe", SW_SHOW);
if (uiResult < 32)
{
char buf[64];
wsprintf (buf, "WinExec('espexe.exe') failed, err=x%x", uiResult);
MessageBox ((HWND) NULL, buf, "Error: esp.tsp", MB_SYSTEMMODAL);
pInfo->lResult = LINEERR_OPERATIONFAILED;
return FALSE;
}
while (!gbExeStarted)
{
Yield();
}
}
#endif
if (gbShowFuncEntry)
{
ShowStr ("TSPI_%s: enter", pInfo->lpszFuncName);
}
if (gbShowFuncParams)
{
for (i = 0; i < pInfo->dwNumParams; i++)
{
if (pInfo->aParams[i].dwVal &&
(strncmp (pInfo->aParams[i].lpszVal, "lpsz", 4) == 0))
{
ShowStr(
"%s%s=x%lx, '%s'",
szTab,
pInfo->aParams[i].lpszVal,
pInfo->aParams[i].dwVal,
pInfo->aParams[i].dwVal
);
}
else if (pInfo->aParams[i].pLookup)
{
char buf[90];
PLOOKUP pLookup = pInfo->aParams[i].pLookup;
wsprintf(
buf,
"%s%s=x%lx, ",
szTab,
pInfo->aParams[i].lpszVal,
pInfo->aParams[i].dwVal
);
for (j = 0; pLookup[j].dwVal != 0xffffffff; j++)
{
if (pInfo->aParams[i].dwVal & pLookup[j].dwVal)
{
strcat (buf, pLookup[j].lpszVal);
strcat (buf, " ");
if (strlen (buf) > 60)
{
ShowStr (buf);
wsprintf (buf, "%s%s", szTab, szTab);
}
}
}
ShowStr (buf);
}
else
{
ShowStr(
"%s%s=x%lx",
szTab,
pInfo->aParams[i].lpszVal,
pInfo->aParams[i].dwVal
);
}
}
}
if (gbManualResults)
{
char szDlgTitle[64];
EVENT_PARAM params[] =
{
{ "lResult", PT_ORDINAL, 0, (bLineFunc ? aLineErrs : aPhoneErrs) }
};
EVENT_PARAM_HEADER paramsHeader =
{ 1, szDlgTitle, XX_REQRESULTPOSTQUIT, params };
HWND hwnd;
wsprintf (szDlgTitle, "TSPI_%s request result", pInfo->lpszFuncName);
hwnd = CreateDialogParam(
hInst,
(LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
(HWND) NULL,
(DLGPROC) CallDlgProc,
(LPARAM) &paramsHeader
);
MsgLoopInTAPIClientContext (hwnd);
//
// If user selected to synchronously return an error we'll save
// the error & return FALSE to indicate to caller that it should
// return immediately.
//
if (params[0].dwValue)
{
pInfo->lResult = (LONG) params[0].dwValue;
return FALSE;
}
}
if (pInfo->bAsync)
{
//
// Alloc & init an async request info structure
//
PASYNC_REQUEST_INFO pAsyncReqInfo = (PASYNC_REQUEST_INFO)
DrvAlloc (sizeof(ASYNC_REQUEST_INFO));
if (pAsyncReqInfo)
{
memset (pAsyncReqInfo, 0, sizeof(ASYNC_REQUEST_INFO));
pAsyncReqInfo->pfnPostProcessProc = (FARPROC)
pInfo->pfnPostProcessProc;
pAsyncReqInfo->dwRequestID = pInfo->aParams[0].dwVal;
pInfo->pAsyncReqInfo = pAsyncReqInfo;
strcpy (pAsyncReqInfo->szFuncName, pInfo->lpszFuncName);
}
else
{
pInfo->lResult = (bLineFunc ?
LINEERR_OPERATIONFAILED : PHONEERR_OPERATIONFAILED);
return FALSE;
}
}
if (gbBreakOnFuncEntry)
{
DebugBreak();
}
return TRUE;
}
LONG
Epilog(
PFUNC_INFO pInfo
)
{
if (pInfo->bAsync)
{
if (pInfo->lResult == 0)
{
if (gbManualCompl || gbAsyncCompl)
{
PostMessage(
ghwndMain,
(gbManualCompl ? WM_MANUALCOMPL : WM_ASYNCCOMPL),
ESP_MSG_KEY,
(LPARAM) pInfo->pAsyncReqInfo
);
}
else
{
//
// We're completing this async request synchronously, so call
// the post processing proc (if there is one) or call the
// completion routine directly
//
if (pInfo->pAsyncReqInfo->pfnPostProcessProc)
{
(*((POSTPROCESSPROC)pInfo->pAsyncReqInfo->pfnPostProcessProc))(
pInfo->lpszFuncName,
pInfo->pAsyncReqInfo,
TRUE
);
}
else
{
DoCompletion(
pInfo->lpszFuncName,
pInfo->aParams[0].dwVal,
pInfo->lResult,
TRUE
);
}
DrvFree (pInfo->pAsyncReqInfo);
}
//
// Finally, for success cases want to return the request ID per spec
//
pInfo->lResult = pInfo->aParams[0].dwVal;
}
else
{
if (pInfo->pAsyncReqInfo)
{
DrvFree (pInfo->pAsyncReqInfo);
}
}
}
if (gbShowFuncExit)
{
ShowStr(
"TSPI_%s: exit, returning x%lx",
pInfo->lpszFuncName,
pInfo->lResult
);
}
return (pInfo->lResult);
}
PDRVWIDGET
GetSelectedWidget(
void
)
{
PDRVWIDGET pWidget = NULL;
LONG lSel = SendMessage (ghwndList1, LB_GETCURSEL, 0, 0), i;
if (lSel != LB_ERR)
{
pWidget = gaWidgets;
for (i = 0; i < lSel; i++)
{
if (!pWidget)
{
break;
}
pWidget = pWidget->pNext;
}
}
return pWidget;
}
void
ESPConfigDialog(
void
)
{
EVENT_PARAM params[] =
{
{ "TSPI Version", PT_DWORD, gdwTSPIVersion, NULL },
{ "Num Lines", PT_DWORD, gdwNumLines, NULL },
{ "Num Addrs/Line", PT_DWORD, gdwNumAddrsPerLine, NULL },
{ "Num Phones", PT_DWORD, gdwNumPhones, NULL },
{ "ShowLineGetIDDlg", PT_DWORD, gbShowLineGetIDDlg, NULL },
{ "DefLineGetIDID", PT_DWORD, gdwDefLineGetIDID, NULL },
{ "LineExtID0", PT_DWORD, gLineExtID.dwExtensionID0, NULL },
{ "LineExtID1", PT_DWORD, gLineExtID.dwExtensionID1, NULL },
{ "LineExtID2", PT_DWORD, gLineExtID.dwExtensionID2, NULL },
{ "LineExtID3", PT_DWORD, gLineExtID.dwExtensionID3, NULL },
{ "PhoneExtID0", PT_DWORD, gPhoneExtID.dwExtensionID0, NULL },
{ "PhoneExtID1", PT_DWORD, gPhoneExtID.dwExtensionID1, NULL },
{ "PhoneExtID2", PT_DWORD, gPhoneExtID.dwExtensionID2, NULL },
{ "PhoneExtID3", PT_DWORD, gPhoneExtID.dwExtensionID3, NULL }
};
EVENT_PARAM_HEADER paramsHeader =
{ 12, "Default Provider Values", XX_DEFAULTS, params };
if (DialogBoxParam(
hInst,
(LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
(HWND) ghwndMain,
(DLGPROC) CallDlgProc,
(LPARAM) &paramsHeader
) == IDOK)
{
if (!gdwNumInits)
{
gdwTSPIVersion = params[0].dwValue;
gdwNumAddrsPerLine = params[2].dwValue;
//
// v1.0 support (since 1.0 doesn't call providerEnumDevices). Find
// [ProviderN] section for ESP & updates NumLines & NumPhones.
//
if ((gdwNumLines != params[1].dwValue) ||
(gdwNumPhones != params[3].dwValue))
{
int iNumProviders, i;
char szProviderN[32];
gdwNumLines = params[1].dwValue;
gdwNumPhones = params[3].dwValue;
iNumProviders = GetPrivateProfileInt(
szProviders,
szNumProviders,
0,
szTelephonIni
);
for (i = 0; i < iNumProviders; i++)
{
char szProviderName[16];
wsprintf (szProviderN, "%s%d", szProviderFilename, i);
GetPrivateProfileString(
szProviders,
szProviderN,
"",
szProviderName,
16,
szTelephonIni
);
if (_stricmp (szProviderName, szEspTsp) == 0)
{
wsprintf (szProviderN, "%s%d", szProviderID, i);
i = GetPrivateProfileInt(
szProviders,
szProviderN,
30000,
szTelephonIni
);
// BUGBUG chk if err
break;
}
}
UpdateTelephonIni ((DWORD) i);
}
}
else if ((gdwTSPIVersion != params[0].dwValue) ||
(gdwNumLines != params[1].dwValue) ||
(gdwNumAddrsPerLine != params[2].dwValue) ||
(gdwNumPhones != params[3].dwValue))
{
MessageBox(
ghwndMain,
"You must shut down all active TAPI applications in order " \
"for changes to TSPI Version, Num Lines, NumAddrs/Line," \
" or Num Phones to take effect",
"Note",
MB_OK
);
}
gdwTSPIVersion = params[0].dwValue;
gdwNumLines = params[1].dwValue;
gdwNumAddrsPerLine = params[2].dwValue;
gdwNumPhones = params[3].dwValue;
gbShowLineGetIDDlg = (BOOL) params[4].dwValue;
gdwDefLineGetIDID = params[5].dwValue;
gLineExtID.dwExtensionID0 = params[4].dwValue;
gLineExtID.dwExtensionID1 = params[5].dwValue;
gLineExtID.dwExtensionID2 = params[6].dwValue;
gLineExtID.dwExtensionID3 = params[7].dwValue;
gPhoneExtID.dwExtensionID0 = params[8].dwValue;
gPhoneExtID.dwExtensionID1 = params[9].dwValue;
gPhoneExtID.dwExtensionID2 = params[10].dwValue;
gPhoneExtID.dwExtensionID3 = params[11].dwValue;
}
}
void
WidgetPropertiesDialog(
PDRVWIDGET pWidget,
BOOL bIncomingCall
)
{
static char aszVarFields[17][MAX_STRING_PARAM_SIZE];
DWORD i;
switch (pWidget->dwType)
{
case WT_DRVCALL:
{
//
// We use the bIncomingCall flag here automatically cause a chg in
// the call state (from IDLE to OFFERING) on incoming calls, otherwise
// if the user forgets to chg it (from IDLE) any chgs they make will
// just be ignored by TAPI.DLL
//
PDRVCALL pCall = (PDRVCALL) pWidget;
LPLINECALLINFO lpCallInfo = &pCall->LineCallInfo;
char far *lpVarFields = (char far *) lpCallInfo + sizeof(LINECALLINFO);
EVENT_PARAM params[] =
{
{ "Status.dwCallState", PT_FLAGS, (bIncomingCall ? LINECALLSTATE_OFFERING : pCall->dwCallState), aCallStates },
{ "Status.dwCallStateMode", PT_DWORD, pCall->dwCallStateMode, NULL },
{ "Status.dwCallFeatures", PT_FLAGS, pCall->dwCallFeatures, aCallFeatures },
{ "Info.dwBearerMode", PT_FLAGS, lpCallInfo->dwBearerMode, aBearerModes },
{ "Info.dwRate", PT_DWORD, lpCallInfo->dwRate, NULL },
{ "Info.dwMediaMode", PT_FLAGS, lpCallInfo->dwMediaMode, aMediaModes },
{ "Info.dwAppSpecific", PT_DWORD, lpCallInfo->dwAppSpecific, 0 },
{ "Info.dwCallID", PT_DWORD, lpCallInfo->dwCallID, 0 },
{ "Info.dwRelatedCallID", PT_DWORD, lpCallInfo->dwRelatedCallID, 0 },
{ "Info.dwCallParamFlags", PT_FLAGS, lpCallInfo->dwCallParamFlags, aCallParamFlags },
{ "Info.dwCallStates", PT_FLAGS, lpCallInfo->dwCallStates, aCallStates },
{ "Info.DialParams.dwDialPause", PT_DWORD, lpCallInfo->DialParams.dwDialPause, 0 },
{ "Info.DialParams.dwDialSpeed", PT_DWORD, lpCallInfo->DialParams.dwDialSpeed, 0 },
{ "Info.DialParams.dwDigitDuration", PT_DWORD, lpCallInfo->DialParams.dwDigitDuration, 0 },
{ "Info.DialParams.dwWaitForDialtone", PT_DWORD, lpCallInfo->DialParams.dwWaitForDialtone, 0 },
{ "Info.dwOrigin", PT_FLAGS, lpCallInfo->dwOrigin, aCallOrigins },
{ "Info.dwReason", PT_FLAGS, lpCallInfo->dwReason, aCallReasons },
{ "Info.dwCompletionID", PT_DWORD, lpCallInfo->dwCompletionID, 0 },
{ "Info.dwCountryCode", PT_DWORD, lpCallInfo->dwCountryCode, 0 },
{ "Info.dwTrunk", PT_DWORD, lpCallInfo->dwTrunk, 0 },
{ "Info.dwCallerIDFlags", PT_FLAGS, lpCallInfo->dwCallerIDFlags, aCallerIDFlags },
{ "Info.szCallerID", PT_STRING, (DWORD) (lpCallInfo->dwCallerIDSize ? aszVarFields[0] : 0), (LPVOID) aszVarFields[0] },
{ "Info.szCallerIDName", PT_STRING, (DWORD) (lpCallInfo->dwCallerIDNameSize ? aszVarFields[1] : 0), (LPVOID) aszVarFields[1] },
{ "Info.dwCalledIDFlags", PT_FLAGS, lpCallInfo->dwCalledIDFlags, aCallerIDFlags },
{ "Info.szCalledID", PT_STRING, (DWORD) (lpCallInfo->dwCalledIDSize ? aszVarFields[2] : 0), (LPVOID) aszVarFields[2] },
{ "Info.szCalledIDName", PT_STRING, (DWORD) (lpCallInfo->dwCalledIDNameSize ? aszVarFields[3] : 0), (LPVOID) aszVarFields[3] },
{ "Info.dwConnectedIDFlags", PT_FLAGS, lpCallInfo->dwConnectedIDFlags, aCallerIDFlags },
{ "Info.szConnectedID", PT_STRING, (DWORD) (lpCallInfo->dwConnectedIDSize ? aszVarFields[4] : 0), (LPVOID) aszVarFields[4] },
{ "Info.szConnectedIDName", PT_STRING, (DWORD) (lpCallInfo->dwConnectedIDNameSize ? aszVarFields[5] : 0), (LPVOID) aszVarFields[5] },
{ "Info.dwRedirectionIDFlags", PT_FLAGS, lpCallInfo->dwRedirectionIDFlags, aCallerIDFlags },
{ "Info.szRedirectionID", PT_STRING, (DWORD) (lpCallInfo->dwRedirectionIDSize ? aszVarFields[6] : 0), (LPVOID) aszVarFields[6] },
{ "Info.szRedirectionIDName", PT_STRING, (DWORD) (lpCallInfo->dwRedirectionIDNameSize ? aszVarFields[7] : 0), (LPVOID) aszVarFields[7] },
{ "Info.dwRedirectingIDFlags", PT_FLAGS, lpCallInfo->dwRedirectingIDFlags, aCallerIDFlags },
{ "Info.szRedirectingID", PT_STRING, (DWORD) (lpCallInfo->dwRedirectingIDSize ? aszVarFields[8] : 0), (LPVOID) aszVarFields[8] },
{ "Info.szRedirectingIDName", PT_STRING, (DWORD) (lpCallInfo->dwRedirectingIDNameSize ? aszVarFields[9] : 0), (LPVOID) aszVarFields[9] },
{ "Info.szDisplay", PT_STRING, (DWORD) (lpCallInfo->dwDisplaySize ? aszVarFields[10] : 0), (LPVOID) aszVarFields[10] },
{ "Info.szUserUserInfo", PT_STRING, (DWORD) (lpCallInfo->dwUserUserInfoSize ? aszVarFields[11] : 0), (LPVOID) aszVarFields[11] },
{ "Info.szHighLevelComp", PT_STRING, (DWORD) (lpCallInfo->dwHighLevelCompSize ? aszVarFields[12] : 0), (LPVOID) aszVarFields[12] },
{ "Info.szLowLevelComp", PT_STRING, (DWORD) (lpCallInfo->dwLowLevelCompSize ? aszVarFields[13] : 0), (LPVOID) aszVarFields[13] },
{ "Info.szChargingInfo", PT_STRING, (DWORD) (lpCallInfo->dwChargingInfoSize ? aszVarFields[14] : 0), (LPVOID) aszVarFields[14] },
{ "Info.szTerminalModes", PT_STRING, (DWORD) (lpCallInfo->dwTerminalModesSize ? aszVarFields[15] : 0), (LPVOID) aszVarFields[15] },
{ "Info.szDevSpecific", PT_STRING, (DWORD) (lpCallInfo->dwDevSpecificSize ? aszVarFields[16] : 0), (LPVOID) aszVarFields[16] }
};
EVENT_PARAM_HEADER paramsHeader =
{ 42, "Call status/info", XX_CALL, params };
for (i = 0; i < 17; i++)
{
strcpy (aszVarFields[i], lpVarFields + i*MAX_STRING_PARAM_SIZE);
}
if (DialogBoxParam(
hInst,
(LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
(HWND) ghwndMain,
(DLGPROC) CallDlgProc,
(LPARAM) &paramsHeader
) == IDOK)
{
LPDWORD alpdwXxxSize[17] =
{
&lpCallInfo->dwCallerIDSize,
&lpCallInfo->dwCallerIDNameSize,
&lpCallInfo->dwCalledIDSize,
&lpCallInfo->dwCalledIDNameSize,
&lpCallInfo->dwConnectedIDSize,
&lpCallInfo->dwConnectedIDNameSize,
&lpCallInfo->dwRedirectionIDSize,
&lpCallInfo->dwRedirectionIDNameSize,
&lpCallInfo->dwRedirectingIDSize,
&lpCallInfo->dwRedirectingIDNameSize,
&lpCallInfo->dwDisplaySize,
&lpCallInfo->dwUserUserInfoSize,
&lpCallInfo->dwHighLevelCompSize,
&lpCallInfo->dwLowLevelCompSize,
&lpCallInfo->dwChargingInfoSize,
&lpCallInfo->dwTerminalModesSize,
&lpCallInfo->dwDevSpecificSize
};
LPDWORD alpdwXxx[22] =
{
&lpCallInfo->dwBearerMode,
&lpCallInfo->dwRate,
&lpCallInfo->dwMediaMode,
&lpCallInfo->dwAppSpecific,
&lpCallInfo->dwCallID,
&lpCallInfo->dwRelatedCallID,
&lpCallInfo->dwCallParamFlags,
&lpCallInfo->dwCallStates,
&lpCallInfo->DialParams.dwDialPause,
&lpCallInfo->DialParams.dwDialSpeed,
&lpCallInfo->DialParams.dwDigitDuration,
&lpCallInfo->DialParams.dwWaitForDialtone,
&lpCallInfo->dwOrigin,
&lpCallInfo->dwReason,
&lpCallInfo->dwCompletionID,
&lpCallInfo->dwCountryCode,
&lpCallInfo->dwTrunk,
&lpCallInfo->dwCallerIDFlags,
&lpCallInfo->dwCalledIDFlags,
&lpCallInfo->dwConnectedIDFlags,
&lpCallInfo->dwRedirectionIDFlags,
&lpCallInfo->dwRedirectingIDFlags
};
DWORD dwCallInfoChangedFlags, i;
static DWORD adwVarFieldFlags[17] =
{
LINECALLINFOSTATE_CALLERID,
LINECALLINFOSTATE_CALLERID,
LINECALLINFOSTATE_CALLEDID,
LINECALLINFOSTATE_CALLEDID,
LINECALLINFOSTATE_CONNECTEDID,
LINECALLINFOSTATE_CONNECTEDID,
LINECALLINFOSTATE_REDIRECTIONID,
LINECALLINFOSTATE_REDIRECTIONID,
LINECALLINFOSTATE_REDIRECTINGID,
LINECALLINFOSTATE_REDIRECTINGID,
LINECALLINFOSTATE_DISPLAY,
LINECALLINFOSTATE_USERUSERINFO,
LINECALLINFOSTATE_HIGHLEVELCOMP,
LINECALLINFOSTATE_LOWLEVELCOMP,
LINECALLINFOSTATE_CHARGINGINFO,
LINECALLINFOSTATE_TERMINAL,
LINECALLINFOSTATE_DEVSPECIFIC
};
static DWORD adwDWORDFieldFlags[22] =
{
LINECALLINFOSTATE_BEARERMODE,
LINECALLINFOSTATE_RATE,
LINECALLINFOSTATE_MEDIAMODE,
LINECALLINFOSTATE_APPSPECIFIC,
LINECALLINFOSTATE_CALLID,
LINECALLINFOSTATE_RELATEDCALLID,
LINECALLINFOSTATE_OTHER,
LINECALLINFOSTATE_OTHER,
LINECALLINFOSTATE_DIALPARAMS,
LINECALLINFOSTATE_DIALPARAMS,
LINECALLINFOSTATE_DIALPARAMS,
LINECALLINFOSTATE_DIALPARAMS,
LINECALLINFOSTATE_ORIGIN,
LINECALLINFOSTATE_REASON,
LINECALLINFOSTATE_COMPLETIONID,
LINECALLINFOSTATE_OTHER,
LINECALLINFOSTATE_TRUNK,
LINECALLINFOSTATE_CALLERID,
LINECALLINFOSTATE_CALLEDID,
LINECALLINFOSTATE_CONNECTEDID,
LINECALLINFOSTATE_REDIRECTIONID,
LINECALLINFOSTATE_REDIRECTINGID
};
static int aiVarFieldIndices[17] =
{
21, 22, 24, 25, 27, 28, 30, 31, 33, 34, 35, 36, 37,
38, 39, 40, 41
};
static int aiDWORDFieldIndices[22] =
{
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 23, 26, 29, 32
};
//
// If the state info chgd then save it & send a call state msg
//
if ((params[0].dwValue != pCall->dwCallState) ||
(params[1].dwValue != pCall->dwCallStateMode) ||
(params[2].dwValue != pCall->dwCallFeatures))
{
//
// We want to make sure that the media mode is up to date
// when we send the CALLSTATE msg
//
DWORD dwMediaModeOrig = lpCallInfo->dwMediaMode;
lpCallInfo->dwMediaMode = params[5].dwValue;
//
// We need to zero the state in order to force a msg (even
// if state didn't chg)
//
pCall->dwCallState = 0xdeadbeef;
SetCallState (pCall, params[0].dwValue, params[1].dwValue);
pCall->dwCallFeatures = params[2].dwValue;
//
// Restore the media mode so we can catch the chg down below
//
lpCallInfo->dwMediaMode = dwMediaModeOrig;
}
//
// If the info chgd then save it & send a call info msg
//
dwCallInfoChangedFlags = 0;
for (i = 0; i < 22; i++)
{
if (params[aiDWORDFieldIndices[i]].dwValue != *(alpdwXxx[i]))
{
*(alpdwXxx[i]) = params[aiDWORDFieldIndices[i]].dwValue;
dwCallInfoChangedFlags |= adwDWORDFieldFlags[i];
}
}
for (i = 0; i < 17; i++)
{
if (params[aiVarFieldIndices[i]].dwValue == 0)
{
if (*(alpdwXxxSize[i]) != 0)
{
*(alpdwXxxSize[i]) = *(alpdwXxxSize[i] + 1) = 0;
lpVarFields[i*MAX_STRING_PARAM_SIZE] = 0;
dwCallInfoChangedFlags |= adwVarFieldFlags[i];
}
}
else if (strcmp(
aszVarFields[i],
lpVarFields + i*MAX_STRING_PARAM_SIZE
) ||
(*(alpdwXxxSize[i]) == 0))
{
strcpy(
lpVarFields + i*MAX_STRING_PARAM_SIZE,
aszVarFields[i]
);
*(alpdwXxxSize[i]) = strlen (aszVarFields[i]) + 1;
*(alpdwXxxSize[i] + 1) = sizeof(LINECALLINFO) +
i*MAX_STRING_PARAM_SIZE;
dwCallInfoChangedFlags |= adwVarFieldFlags[i];
}
}
if (dwCallInfoChangedFlags)
{
SendLineEvent(
pCall->pLine,
pCall,
LINE_CALLINFO,
dwCallInfoChangedFlags,
0,
0
);
}
}
break;
}
case WT_DRVLINE:
{
PDRVLINE pLine = (PDRVLINE) pWidget;
EVENT_PARAM params[] =
{
{ "<under contruction>", PT_DWORD, 0, NULL }
// { "Caps.dwBearerModes", PT_FLAGS, pLine->LineDevCaps.dwBearerModes, aBearerModes },
// { "Caps.dwMediaModes", PT_FLAGS, pLine->LineDevCaps.dwMediaModes, aMediaModes }
};
EVENT_PARAM_HEADER paramsHeader =
{ 1, "Line caps/status", XX_LINE, params };
if (DialogBoxParam(
hInst,
(LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
(HWND) ghwndMain,
(DLGPROC) CallDlgProc,
(LPARAM) &paramsHeader
) == IDOK)
{
}
break;
}
case WT_DRVPHONE:
{
PDRVPHONE pPhone = (PDRVPHONE) pWidget;
LPPHONECAPS lpPhoneCaps = &pPhone->PhoneCaps;
char far *lpCapsVarFields = (char far *) lpPhoneCaps + sizeof(PHONECAPS);
LPPHONESTATUS lpPhoneStatus = &pPhone->PhoneStatus;
char far *lpStatusVarFields = (char far *) lpPhoneStatus + sizeof(PHONESTATUS);
EVENT_PARAM params[] =
{
{ "Caps.szProviderInfo", PT_STRING, (DWORD) (lpPhoneCaps->dwProviderInfoSize ? aszVarFields[0] : 0) , (LPVOID) aszVarFields[0] },
{ "Caps.szPhoneInfo", PT_STRING, (DWORD) (lpPhoneCaps->dwPhoneInfoSize ? aszVarFields[1] : 0) , (LPVOID) aszVarFields[1] },
{ "Caps.szPhoneName", PT_STRING, (DWORD) (lpPhoneCaps->dwPhoneNameSize ? aszVarFields[2] : 0) , (LPVOID) aszVarFields[2] },
{ "Caps.dwPhoneStates", PT_FLAGS, lpPhoneCaps->dwPhoneStates, aPhoneStates },
{ "Caps.dwHookSwitchDevs", PT_FLAGS, lpPhoneCaps->dwHookSwitchDevs, aHookSwitchDevs },
{ "Caps.dwHandsetHookSwitchModes", PT_FLAGS, lpPhoneCaps->dwHandsetHookSwitchModes, aHookSwitchModes },
{ "Caps.dwSpeakerHookSwitchModes", PT_FLAGS, lpPhoneCaps->dwSpeakerHookSwitchModes, aHookSwitchModes },
{ "Caps.dwHeadsetHookSwitchModes", PT_FLAGS, lpPhoneCaps->dwHeadsetHookSwitchModes, aHookSwitchModes },
{ "Caps.dwVolumeFlags", PT_FLAGS, lpPhoneCaps->dwVolumeFlags, aHookSwitchDevs },
{ "Caps.dwGainFlags", PT_FLAGS, lpPhoneCaps->dwGainFlags, aHookSwitchDevs },
{ "Caps.dwDisplayNumRows", PT_DWORD, lpPhoneCaps->dwDisplayNumRows, 0 },
{ "Caps.dwDisplayNumColumns", PT_DWORD, lpPhoneCaps->dwDisplayNumColumns, 0 },
{ "Caps.dwNumRingModes", PT_DWORD, lpPhoneCaps->dwNumRingModes, 0 },
{ "Caps.dwNumButtonLamps", PT_DWORD, lpPhoneCaps->dwNumButtonLamps, 0 },
{ "Caps.szButtonModes", PT_STRING, (DWORD) (lpPhoneCaps->dwButtonModesSize ? aszVarFields[3] : 0) , (LPVOID) aszVarFields[3] },
{ "Caps.szButtonFunctions", PT_STRING, (DWORD) (lpPhoneCaps->dwButtonFunctionsSize ? aszVarFields[4] : 0) , (LPVOID) aszVarFields[4] },
{ "Caps.szLampModes", PT_STRING, (DWORD) (lpPhoneCaps->dwLampModesSize ? aszVarFields[5] : 0) , (LPVOID) aszVarFields[5] },
{ "Caps.dwNumSetData", PT_DWORD, lpPhoneCaps->dwNumSetData, 0 },
{ "Caps.szSetData", PT_STRING, (DWORD) (lpPhoneCaps->dwSetDataSize ? aszVarFields[6] : 0) , (LPVOID) aszVarFields[6] },
{ "Caps.dwNumGetData", PT_DWORD, lpPhoneCaps->dwNumGetData, 0 },
{ "Caps.szGetData", PT_STRING, (DWORD) (lpPhoneCaps->dwGetDataSize ? aszVarFields[7] : 0) , (LPVOID) aszVarFields[7] },
{ "Caps.szDevSpecific", PT_STRING, (DWORD) (lpPhoneCaps->dwDevSpecificSize ? aszVarFields[8] : 0) , (LPVOID) aszVarFields[8] },
{ "Status.dwStatusFlags", PT_FLAGS, lpPhoneStatus->dwStatusFlags, aPhoneStatusFlags },
{ "Status.dwRingMode", PT_DWORD, lpPhoneStatus->dwRingMode, 0 },
{ "Status.dwRingVolume", PT_DWORD, lpPhoneStatus->dwRingVolume, 0 },
{ "Status.dwHandsetHookSwitchMode", PT_FLAGS, lpPhoneStatus->dwHandsetHookSwitchMode, aHookSwitchModes },
{ "Status.dwHandsetVolume", PT_DWORD, lpPhoneStatus->dwHandsetVolume, 0 },
{ "Status.dwHandsetGain", PT_DWORD, lpPhoneStatus->dwHandsetGain, 0 },
{ "Status.dwSpeakerHookSwitchMode", PT_FLAGS, lpPhoneStatus->dwSpeakerHookSwitchMode, aHookSwitchModes },
{ "Status.dwSpeakerVolume", PT_DWORD, lpPhoneStatus->dwSpeakerVolume, 0 },
{ "Status.dwSpeakerGain", PT_DWORD, lpPhoneStatus->dwSpeakerGain, 0 },
{ "Status.dwHeadsetHookSwitchMode", PT_FLAGS, lpPhoneStatus->dwHeadsetHookSwitchMode, aHookSwitchModes },
{ "Status.dwHeadsetVolume", PT_DWORD, lpPhoneStatus->dwHeadsetVolume, 0 },
{ "Status.dwHeadsetGain", PT_DWORD, lpPhoneStatus->dwHeadsetGain, 0 },
{ "Status.szDisplay", PT_STRING, (DWORD) (lpPhoneStatus->dwDisplaySize ? aszVarFields[10] : 0) , (LPVOID) aszVarFields[10] }
};
EVENT_PARAM_HEADER paramsHeader =
{ 35, "Phone caps/status", XX_PHONE, params };
for (i = 0; i < 9; i++)
{
strcpy (aszVarFields[i], lpCapsVarFields + i*MAX_STRING_PARAM_SIZE);
}
strcpy (aszVarFields[9], lpStatusVarFields);
if (DialogBoxParam(
hInst,
(LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
(HWND) ghwndMain,
(DLGPROC) CallDlgProc,
(LPARAM) &paramsHeader
) == IDOK)
{
LPDWORD alpdwXxxSize[10] =
{
&lpPhoneCaps->dwProviderInfoSize,
&lpPhoneCaps->dwPhoneInfoSize,
&lpPhoneCaps->dwPhoneNameSize,
&lpPhoneCaps->dwButtonModesSize,
&lpPhoneCaps->dwButtonFunctionsSize,
&lpPhoneCaps->dwLampModesSize,
&lpPhoneCaps->dwSetDataSize,
&lpPhoneCaps->dwGetDataSize,
&lpPhoneCaps->dwDevSpecificSize,
&lpPhoneStatus->dwDisplaySize
};
LPDWORD alpdwXxx[25] =
{
&lpPhoneCaps->dwPhoneStates,
&lpPhoneCaps->dwHookSwitchDevs,
&lpPhoneCaps->dwHandsetHookSwitchModes,
&lpPhoneCaps->dwSpeakerHookSwitchModes,
&lpPhoneCaps->dwHeadsetHookSwitchModes,
&lpPhoneCaps->dwVolumeFlags,
&lpPhoneCaps->dwGainFlags,
&lpPhoneCaps->dwDisplayNumRows,
&lpPhoneCaps->dwDisplayNumColumns,
&lpPhoneCaps->dwNumRingModes,
&lpPhoneCaps->dwNumButtonLamps,
&lpPhoneCaps->dwNumSetData,
&lpPhoneCaps->dwNumGetData,
&lpPhoneStatus->dwStatusFlags,
&lpPhoneStatus->dwRingMode,
&lpPhoneStatus->dwRingVolume,
&lpPhoneStatus->dwHandsetHookSwitchMode,
&lpPhoneStatus->dwHandsetVolume,
&lpPhoneStatus->dwHandsetGain,
&lpPhoneStatus->dwSpeakerHookSwitchMode,
&lpPhoneStatus->dwSpeakerVolume,
&lpPhoneStatus->dwSpeakerGain,
&lpPhoneStatus->dwHeadsetHookSwitchMode,
&lpPhoneStatus->dwHeadsetVolume,
&lpPhoneStatus->dwHeadsetGain
};
DWORD dwStatusChangedFlags, i;
static DWORD adwVarFieldFlags[10] =
{
0,
0,
0,
0,
0,
PHONESTATE_LAMP,
0,
0,
PHONESTATE_DEVSPECIFIC,
PHONESTATE_DISPLAY,
};
static DWORD adwDWORDFieldFlags[12] =
{
PHONESTATE_OTHER,
PHONESTATE_RINGMODE,
PHONESTATE_RINGVOLUME,
PHONESTATE_HANDSETHOOKSWITCH,
PHONESTATE_HANDSETVOLUME,
PHONESTATE_HANDSETGAIN,
PHONESTATE_SPEAKERHOOKSWITCH,
PHONESTATE_SPEAKERVOLUME,
PHONESTATE_SPEAKERGAIN,
PHONESTATE_HEADSETHOOKSWITCH,
PHONESTATE_HEADSETVOLUME,
PHONESTATE_HEADSETGAIN
};
static int aiVarFieldIndices[10] =
{
0, 1, 2, 14, 15, 16, 18, 20, 21, 34
};
static int aiDWORDFieldIndices[25] =
{
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 17, 19, 22, 23,
24, 25, 25, 27, 28, 29, 30, 31, 32, 33
};
//
// If the caps/status chgd then save it & send a state msg
//
dwStatusChangedFlags = 0;
for (i = 0; i < 25; i++)
{
if (params[aiDWORDFieldIndices[i]].dwValue != *(alpdwXxx[i]))
{
*(alpdwXxx[i]) = params[aiDWORDFieldIndices[i]].dwValue;
if (i >= 13)
{
dwStatusChangedFlags |= adwDWORDFieldFlags[i-13];
}
}
}
for (i = 0; i < 10; i++)
{
if (params[aiVarFieldIndices[i]].dwValue == 0)
{
if (*(alpdwXxxSize[i]) != 0)
{
*(alpdwXxxSize[i]) = *(alpdwXxxSize[i] + 1) = 0;
if (i < 9)
{
lpCapsVarFields[i*MAX_STRING_PARAM_SIZE] = 0;
}
else
{
lpStatusVarFields[0] = 0;
}
dwStatusChangedFlags |= adwVarFieldFlags[i];
}
}
else if (strcmp(
aszVarFields[i],
(i < 9 ?
lpCapsVarFields + i*MAX_STRING_PARAM_SIZE :
lpStatusVarFields)
) ||
(*(alpdwXxxSize[i]) == 0))
{
if (i < 9)
{
strcpy(
lpCapsVarFields + i*MAX_STRING_PARAM_SIZE,
aszVarFields[i]
);
*(alpdwXxxSize[i] + 1) = sizeof(PHONECAPS) +
i*MAX_STRING_PARAM_SIZE;
}
else
{
strcpy (lpStatusVarFields, aszVarFields[i]);
*(alpdwXxxSize[i] + 1) = sizeof(PHONESTATUS);
}
*(alpdwXxxSize[i]) = strlen (aszVarFields[i]) + 1;
dwStatusChangedFlags |= adwVarFieldFlags[i];
}
}
if (dwStatusChangedFlags)
{
SendPhoneEvent(
pPhone,
PHONE_STATE,
dwStatusChangedFlags,
0,
0
);
}
}
break;
}
} // switch
}
BOOL
__loadds
CALLBACK
MainWndProc(
HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
static HICON hIcon;
static int icyButton, icyBorder;
static BOOL bCaptured = FALSE;
static LONG xCapture, cxVScroll;
static int cyWnd;
static HFONT hFont;
switch (msg)
{
case WM_INITDIALOG:
{
char buf[64];
RECT rect;
//
// Init some globals
//
hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IDI_ICON1));
ghwndMain = hwnd;
ghwndList1 = GetDlgItem (hwnd, IDC_LIST1);
ghwndList2 = GetDlgItem (hwnd, IDC_LIST2);
ghwndEdit = GetDlgItem (hwnd, IDC_EDIT1);
ghMenu = GetMenu (hwnd);
icyBorder = GetSystemMetrics (SM_CYFRAME);
GetWindowRect (GetDlgItem (hwnd, IDC_BUTTON1), &rect);
icyButton = (rect.bottom - rect.top) + icyBorder + 3;
cxVScroll = 2*GetSystemMetrics (SM_CXVSCROLL);
//
//
//
{
#define MYBOOL 1
#define MYDWORD 2
typedef struct _INIT_VALUE
{
char *lpszValue;
LPVOID lpValue;
int iType;
union
{
DWORD dwMenuItem;
char *lpszDefValueAscii;
} u;
} INIT_VALUE, *PINIT_VALUE;
int i;
INIT_VALUE aValues[] =
{
{ "TSPIVersion", &gdwTSPIVersion, MYDWORD, (DWORD) ((char far *)"10003") },
{ "NumLines", &gdwNumLines, MYDWORD, (DWORD) ((char far *)"3") },
{ "NumAddrsPerLine", &gdwNumAddrsPerLine, MYDWORD, (DWORD) ((char far *)"2") },
{ "NumPhones", &gdwNumPhones, MYDWORD, (DWORD) ((char far *)"2") },
{ "ShowFuncEntry", &gbShowFuncEntry, MYBOOL, (DWORD) IDM_SHOWFUNCENTRY },
{ "ShowFuncExit", &gbShowFuncExit, MYBOOL, (DWORD) IDM_SHOWFUNCEXIT },
{ "ShowFuncParams", &gbShowFuncParams, MYBOOL, (DWORD) IDM_SHOWFUNCPARAMS },
{ "ShowEvents", &gbShowEvents, MYBOOL, (DWORD) IDM_SHOWEVENTS },
{ "ShowCompletions", &gbShowCompletions, MYBOOL, (DWORD) IDM_SHOWCOMPLETIONS },
{ "BreakOnFuncEntry", &gbBreakOnFuncEntry, MYBOOL, (DWORD) IDM_DEBUGBREAK },
{ "AutoClose", &gbAutoClose, MYBOOL, (DWORD) IDM_AUTOCLOSE },
{ "SyncCompl", &gbSyncCompl, MYBOOL, (DWORD) IDM_SYNCCOMPL },
{ "AsyncCompl", &gbAsyncCompl, MYBOOL, (DWORD) IDM_ASYNCCOMPL },
{ "ManualCompl", &gbManualCompl, MYBOOL, (DWORD) IDM_MANUALCOMPL },
{ "ManualResults", &gbManualResults, MYBOOL, (DWORD) IDM_MANUALRESULTS },
{ "DisableUI", &gbDisableUI, MYBOOL, (DWORD) IDM_DISABLEUI },
{ "ShowLineGetIDDlg", &gbShowLineGetIDDlg, MYBOOL, (DWORD) 0 },
{ "DefLineGetIDID", &gdwDefLineGetIDID, MYDWORD, (DWORD) ((char far *)"ffffffff") },
{ "LineExtID0", &gLineExtID.dwExtensionID0, MYDWORD, (DWORD) ((char far *)"6f79f180") },
{ "LineExtID1", &gLineExtID.dwExtensionID1, MYDWORD, (DWORD) ((char far *)"101b0bb0") },
{ "LineExtID2", &gLineExtID.dwExtensionID2, MYDWORD, (DWORD) ((char far *)"00089e96") },
{ "LineExtID3", &gLineExtID.dwExtensionID3, MYDWORD, (DWORD) ((char far *)"8a2e312b") },
{ "PhoneExtID0", &gPhoneExtID.dwExtensionID0, MYDWORD, (DWORD) ((char far *)"0") },
{ "PhoneExtID1", &gPhoneExtID.dwExtensionID1, MYDWORD, (DWORD) ((char far *)"0") },
{ "PhoneExtID2", &gPhoneExtID.dwExtensionID2, MYDWORD, (DWORD) ((char far *)"0") },
{ "PhoneExtID3", &gPhoneExtID.dwExtensionID3, MYDWORD, (DWORD) ((char far *)"0") },
{ "OutCallState1", &aOutCallStates[0], MYDWORD, (DWORD) ((char far *)"10") }, // DIALING
{ "OutCallStateMode1", &aOutCallStateModes[0], MYDWORD, (DWORD) ((char far *)"0") },
{ "OutCallState2", &aOutCallStates[1], MYDWORD, (DWORD) ((char far *)"200") }, // PROCEEDING
{ "OutCallStateMode2", &aOutCallStateModes[1], MYDWORD, (DWORD) ((char far *)"0") },
{ "OutCallState3", &aOutCallStates[2], MYDWORD, (DWORD) ((char far *)"0") },
{ "OutCallStateMode3", &aOutCallStateModes[2], MYDWORD, (DWORD) ((char far *)"0") },
{ "OutCallState4", &aOutCallStates[3], MYDWORD, (DWORD) ((char far *)"0") },
{ "OutCallStateMode4", &aOutCallStateModes[3], MYDWORD, (DWORD) ((char far *)"0") },
{ NULL, NULL, 0, 0 }
};
for (i = 0; aValues[i].lpszValue; i++)
{
switch (aValues[i].iType)
{
case MYBOOL:
*((BOOL *) aValues[i].lpValue) = (BOOL)
GetProfileInt(
szMySection,
aValues[i].lpszValue,
((i == 4) || (i == 12) ? 1 : 0)
);
if (*((BOOL *)aValues[i].lpValue) &&
aValues[i].u.dwMenuItem)
{
CheckMenuItem(
ghMenu,
(UINT) aValues[i].u.dwMenuItem,
MF_BYCOMMAND | MF_CHECKED
);
}
break;
case MYDWORD:
{
char buf[16];
GetProfileString(
szMySection,
aValues[i].lpszValue,
aValues[i].u.lpszDefValueAscii,
buf,
15
);
ScanForDWORD (buf, (LPDWORD) aValues[i].lpValue);
break;
}
} // switch
}
}
//
// Set control fonts
//
{
HWND hwndCtrl = GetDlgItem (hwnd, IDC_BUTTON1);
hFont = CreateFont(
13, 5, 0, 0, 400, 0, 0, 0, 0, 1, 2, 1, 34, "MS Sans Serif"
);
do
{
SendMessage(
hwndCtrl,
WM_SETFONT,
(WPARAM) hFont,
0
);
} while ((hwndCtrl = GetNextWindow (hwndCtrl, GW_HWNDNEXT)));
}
//
// Read in control size ratios
//
cxWnd = GetProfileInt (szMySection, "cxWnd", 100);
cxList1 = GetProfileInt (szMySection, "cxList1", 25);
//
// Send self WM_SIZE to position child controls correctly
//
GetProfileString(
szMySection,
"Left",
"0",
buf,
63
);
if (strcmp (buf, "max") == 0)
{
ShowWindow (hwnd, SW_SHOWMAXIMIZED);
}
else if (strcmp (buf, "min") == 0)
{
ShowWindow (hwnd, SW_SHOWMINIMIZED);
}
else
{
int left, top, right, bottom;
int cxScreen = GetSystemMetrics (SM_CXSCREEN);
int cyScreen = GetSystemMetrics (SM_CYSCREEN);
left = GetProfileInt (szMySection, "Left", 0);
top = GetProfileInt (szMySection, "Top", 3*cyScreen/4);
right = GetProfileInt (szMySection, "Right", cxScreen);
bottom = GetProfileInt (szMySection, "Bottom", cyScreen);
SetWindowPos(
hwnd,
HWND_TOP,
left,
top,
right - left,
bottom - top,
SWP_SHOWWINDOW
);
GetClientRect (hwnd, &rect);
SendMessage(
hwnd,
WM_SIZE,
0,
MAKELONG((rect.right-rect.left),(rect.bottom-rect.top))
);
ShowWindow (hwnd, SW_SHOW);
}
gbExeStarted = TRUE;
break;
}
case WM_ADDTEXT:
{
if (wParam == ESP_MSG_KEY)
{
#ifdef WIN32
SendMessage(
ghwndEdit,
EM_SETSEL,
(WPARAM)0xfffffffd,
(LPARAM)0xfffffffe
);
WaitForSingleObject (ghShowStrBufMutex, INFINITE);
#else
SendMessage(
ghwndEdit,
EM_SETSEL,
(WPARAM)0,
(LPARAM) MAKELONG(0xfffd,0xfffe)
);
#endif
SendMessage (ghwndEdit, EM_REPLACESEL, 0, lParam);
#ifdef WIN32
SendMessage (ghwndEdit, EM_SCROLLCARET, 0, 0);
#endif
memset ((char *) lParam, 0, 16);
#ifdef WIN32
ReleaseMutex (ghShowStrBufMutex);
#endif
}
break;
}
case WM_UPDATEWIDGETLIST:
if (wParam == ESP_MSG_KEY)
{
UpdateWidgetList();
}
break;
case WM_ASYNCCOMPL:
{
PASYNC_REQUEST_INFO pAsyncReqInfo = (PASYNC_REQUEST_INFO) lParam;
char buf[64];
if (gbManualResults)
{
EVENT_PARAM params[] =
{
{ "lResult", PT_ORDINAL, 0, aLineErrs }
};
EVENT_PARAM_HEADER paramsHeader =
{ 1, buf, XX_REQRESULT, params };
if (strstr (pAsyncReqInfo->szFuncName, "pho"))
{
params[0].u.pLookup = aPhoneErrs;
}
wsprintf(
buf,
"Completing ReqID=x%lx, TSPI_%s",
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->szFuncName
);
if (DialogBoxParam(
hInst,
(LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
(HWND) hwnd,
(DLGPROC) CallDlgProc,
(LPARAM) &paramsHeader
) == IDOK)
{
pAsyncReqInfo->lResult = (LONG) params[0].dwValue;
}
else
{
// BUGBUG? for now just return opfailed err if user cancels
if (params[0].u.pLookup == aLineErrs)
{
pAsyncReqInfo->lResult = LINEERR_OPERATIONFAILED;
}
else
{
pAsyncReqInfo->lResult = PHONEERR_OPERATIONFAILED;
}
}
}
wsprintf (buf, "TSPI_%s", pAsyncReqInfo->szFuncName);
if (pAsyncReqInfo->pfnPostProcessProc)
{
(*((POSTPROCESSPROC)pAsyncReqInfo->pfnPostProcessProc))(
buf,
pAsyncReqInfo,
FALSE
);
}
else
{
DoCompletion(
buf,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
FALSE
);
}
DrvFree (pAsyncReqInfo);
break;
}
case WM_MANUALCOMPL:
{
PASYNC_REQUEST_INFO pAsyncReqInfo = (PASYNC_REQUEST_INFO) lParam;
char buf[64];
int iIndex;
wsprintf(
buf,
"ReqID=x%lx, TSPI_%s",
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->szFuncName
);
SendMessage(
ghwndList2,
LB_INSERTSTRING,
(WPARAM) -1,
(LPARAM) buf
);
iIndex = (int) (SendMessage (ghwndList2, LB_GETCOUNT, 0, 0) - 1);
SendMessage(
ghwndList2,
LB_SETITEMDATA,
(WPARAM) iIndex,
(LPARAM) pAsyncReqInfo
);
break;
}
case WM_COMMAND:
{
switch (LOWORD((DWORD)wParam))
{
case IDC_EDIT1:
#ifdef WIN32
if (HIWORD(wParam) == EN_CHANGE)
#else
if (HIWORD(lParam) == EN_CHANGE)
#endif
{
//
// Watch to see if the edit control is full, & if so
// purge the top half of the text to make room for more
//
int length = GetWindowTextLength (ghwndEdit);
if (length > 20000)
{
#ifdef WIN32
SendMessage(
ghwndEdit,
EM_SETSEL,
(WPARAM)0 ,
(LPARAM) 10000
);
#else
SendMessage(
ghwndEdit,
EM_SETSEL,
(WPARAM)1,
(LPARAM) MAKELONG (0, 10000)
);
#endif
SendMessage(
ghwndEdit,
EM_REPLACESEL,
0,
(LPARAM) (char far *) ""
);
#ifdef WIN32
SendMessage(
ghwndEdit,
EM_SETSEL,
(WPARAM)0xfffffffd,
(LPARAM)0xfffffffe
);
#else
SendMessage(
ghwndEdit,
EM_SETSEL,
(WPARAM)1,
(LPARAM) MAKELONG (0xfffd, 0xfffe)
);
#endif
}
}
break;
case IDM_INSTALL:
{
int iNumProviders, iNextProviderID;
char szProviderXxxN[32];
char buf[32];
//
// First, see if ESP is already installed
//
if (IsESPInstalled (hwnd))
{
return FALSE;
}
//
// If here need to add the provider entries to telephon.ini
//
// BUGBUG ought to call lineAddProvider instead
//
MessageBox(
hwnd,
"Please close all active TAPI applications, then press OK.",
"Installing ESP",
MB_OK
);
iNumProviders = GetPrivateProfileInt(
szProviders,
szNumProviders,
0,
szTelephonIni
);
wsprintf (buf, "%d", 1 + iNumProviders);
WritePrivateProfileString(
szProviders,
szNumProviders,
buf,
szTelephonIni
);
iNextProviderID = GetPrivateProfileInt(
szProviders,
szNextProviderID,
0,
szTelephonIni
);
wsprintf (buf, "%d", 1 + iNextProviderID);
WritePrivateProfileString(
szProviders,
szNextProviderID,
buf,
szTelephonIni
);
wsprintf (buf, "%d", iNextProviderID);
wsprintf (szProviderXxxN, "ProviderID%d", iNumProviders);
WritePrivateProfileString(
szProviders,
szProviderXxxN,
buf,
szTelephonIni
);
wsprintf(
szProviderXxxN,
"%s%d",
szProviderFilename,
iNumProviders
);
WritePrivateProfileString(
szProviders,
szProviderXxxN,
szEspTsp,
szTelephonIni
);
UpdateTelephonIni ((DWORD) iNextProviderID);
MessageBox(
hwnd,
"ESP has been successfully installed. " \
"You can now restart your TAPI applications. " \
"(If TAPI fails to successfully initialize ESP " \
"then try manually copying the files ESP.TSP " \
"and ESPEXE.EXE to your <windows>/system directory.)",
"Installing ESP",
MB_OK
);
break;
}
case IDM_UNINSTALL:
{
int iNumProviders, i;
char szProviderN[32], buf[128];
//
// First, see if ESP is already installed
//
iNumProviders = GetPrivateProfileInt(
szProviders,
szNumProviders,
0,
szTelephonIni
);
for (i = 0; i < iNumProviders; i++)
{
char szProviderName[8];
wsprintf (szProviderN, "%s%d", szProviderFilename, i);
GetPrivateProfileString(
szProviders,
szProviderN,
"",
szProviderName,
8,
szTelephonIni
);
if (_stricmp (szProviderName, szEspTsp) == 0)
{
break;
}
}
if (i == iNumProviders)
{
MessageBox(
hwnd,
"ESP is not installed.",
"Uninstalling ESP",
MB_OK
);
break;
}
//
// If here need to remove the provider entries to telephon.ini
//
wsprintf (buf, "%d", iNumProviders - 1);
WritePrivateProfileString(
szProviders,
szNumProviders,
buf,
szTelephonIni
);
//
// Nuke the [ProviderN] section
//
{
int iProviderID;
wsprintf (szProviderN, "%s%d", szProviderID, i);
iProviderID = GetPrivateProfileInt(
szProviders,
szProviderN,
0,
szTelephonIni
);
wsprintf (szProviderN, "%s%d", szProvider, iProviderID);
WritePrivateProfileString(
szProviderN,
(LPCSTR) NULL,
(LPCSTR) NULL,
szTelephonIni
);
}
//
// Shuffle the ProviderID[i+1] & ProviderFilename[i+1] down
// to ProviderID[i] & ProviderFilename[i]
//
for (; i < (iNumProviders - 1); i++)
{
wsprintf (szProviderN, "%s%d", szProviderID, i + 1);
GetPrivateProfileString(
szProviders,
szProviderN,
"",
buf,
128,
szTelephonIni
);
wsprintf (szProviderN, "%s%d", szProviderID, i);
WritePrivateProfileString(
szProviders,
szProviderN,
buf,
szTelephonIni
);
wsprintf (szProviderN, "%s%d", szProviderFilename, i + 1);
GetPrivateProfileString(
szProviders,
szProviderN,
"",
buf,
128,
szTelephonIni
);
wsprintf (szProviderN, "%s%d", szProviderFilename, i);
WritePrivateProfileString(
szProviders,
szProviderN,
buf,
szTelephonIni
);
}
//
// Nuke the last ProviderIDN & ProviderFilenameN entries
//
wsprintf (szProviderN, "%s%d", szProviderID, i);
WritePrivateProfileString(
szProviders,
szProviderN,
(LPCSTR) NULL,
szTelephonIni
);
wsprintf (szProviderN, "%s%d", szProviderFilename, i);
WritePrivateProfileString(
szProviders,
szProviderN,
(LPCSTR) NULL,
szTelephonIni
);
//
// Alert user of success
//
MessageBox(
hwnd,
"ESP has been successfully uninstalled.",
"Uninstalling ESP",
MB_OK
);
break;
}
case IDM_DUMPGLOBALS:
{
typedef struct _MYGLOBAL
{
char far *lpszGlobal;
LPDWORD lpdwGlobal;
} MYGLOBAL, far *PMYGLOBAL;
static MYGLOBAL aGlobals[] =
{
//
// When making chgs here make sure to chg init of iNumGlobals
// down below
//
{ "PermanentProviderID", (LPDWORD) &gdwPermanentProviderID },
//
// Globals past here are 1.4 only
//
{ "hProvider", (LPDWORD) &ghProvider }
};
ShowStr ("ESP globals:");
if (gdwNumInits)
{
int i, iNumGlobals = (gdwTSPIVersion == 0x10003 ? 1 : 2);
for (i = 0; i < iNumGlobals; i++)
{
ShowStr(
"%s%s=x%lx",
szTab,
aGlobals[i].lpszGlobal,
*(aGlobals[i].lpdwGlobal)
);
}
}
else
{
ShowStr(
"%s<Provider not initialized>",
szTab
);
}
break;
}
case IDM_EXIT:
PostMessage (hwnd, WM_CLOSE, 0, 0);
break;
case IDM_OUTCALLSTATEPROG:
{
EVENT_PARAM params[] =
{
{ "State 1", PT_ORDINAL, aOutCallStates[0], aCallStates },
{ "State 1 mode", PT_DWORD, aOutCallStateModes[0], NULL },
{ "State 2", PT_ORDINAL, aOutCallStates[1], aCallStates },
{ "State 2 mode", PT_DWORD, aOutCallStateModes[1], NULL },
{ "State 3", PT_ORDINAL, aOutCallStates[2], aCallStates },
{ "State 3 mode", PT_DWORD, aOutCallStateModes[2], NULL },
{ "State 4", PT_ORDINAL, aOutCallStates[3], aCallStates },
{ "State 4 mode", PT_DWORD, aOutCallStateModes[3], NULL }
};
EVENT_PARAM_HEADER paramsHeader =
{ 2*MAX_OUT_CALL_STATES, "Outgoing call state progress", XX_OUTCALLSTATEPROG, params };
int i;
if (DialogBoxParam(
hInst,
(LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
(HWND) hwnd,
(DLGPROC) CallDlgProc,
(LPARAM) &paramsHeader
) == IDOK)
{
memset(
aOutCallStates,
0,
sizeof(DWORD) * MAX_OUT_CALL_STATES
);
memset(
aOutCallStateModes,
0,
sizeof(DWORD) * MAX_OUT_CALL_STATES
);
for (i = 0; i < MAX_OUT_CALL_STATES; i++)
{
if (params[2*i].dwValue == 0)
{
break;
}
aOutCallStates[i] = params[2*i].dwValue;
aOutCallStateModes[i] = params[(2*i)+1].dwValue;
}
}
break;
}
case IDM_ABOUT:
DialogBox(
hInst,
(LPCSTR)MAKEINTRESOURCE(IDD_DIALOG2),
(HWND) hwnd,
(DLGPROC) AboutDlgProc
);
break;
case IDM_USAGE:
{
static char szDlgText[] =
"ABSTRACT:\n\r" \
" ESP is a TAPI Service Provider that supports " \
"multiple virtual line and phone devices. It is " \
"configurable, requires no special hardware, " \
"and implements the entire Telephony Service Provider " \
"Interface (including Win95 TAPI extensions). ESP " \
"will work in both Windows 3.1/TAPI 1.0 and " \
"Windows95/TAPI 1.1 systems.\n\r" \
"\n\rGETTING STARTED:\n\r" \
" 1. Choose 'File/Install' to install ESP.\n\r" \
" 2. Start a TAPI application and try to make a call " \
"on one of ESP's line devices (watch for messages appearing " \
"in the ESP window).\n\r" \
" *. Choose 'File/Uninstall' to uninstall ESP.\n\r" \
"\n\rMORE INFO:\n\r" \
" * Double-click on a line, call, or phone widget (in " \
"upper-left listbox) to view/modify properties. The 'hd' " \
"widget field is the driver handle; the 'ht' field is the " \
"TAPI handle.\n\r" \
" * Press the 'LEvt' or 'PEvt' button to indicate a " \
"line or phone event to TAPI.DLL. Press the 'Call+' button " \
"to indicate an incoming call.\n\r" \
" * Choose 'Options/Default values...' to modify " \
"provider paramters (SPI version, # lines, etc).\n\r" \
" * All parameter values displayed in hexadecimal " \
"unless specified otherwise (strings displayed by contents)." \
"\n\r" \
" * Choose 'Options/Complete async requests/Xxx' to " \
"specify async requests completion behavior. Manually-" \
"completed requests appear in lower-left listbox.";
MessageBox (hwnd, szDlgText, "Using ESP", MB_OK);
break;
}
case IDM_SHOWFUNCENTRY:
gbShowFuncEntry = (gbShowFuncEntry ? FALSE : TRUE);
CheckMenuItem(
ghMenu,
IDM_SHOWFUNCENTRY,
MF_BYCOMMAND | (gbShowFuncEntry ? MF_CHECKED : MF_UNCHECKED)
);
break;
case IDM_SHOWFUNCEXIT:
gbShowFuncExit = (gbShowFuncExit ? FALSE : TRUE);
CheckMenuItem(
ghMenu,
IDM_SHOWFUNCEXIT,
MF_BYCOMMAND | (gbShowFuncExit ? MF_CHECKED : MF_UNCHECKED)
);
break;
case IDM_SHOWFUNCPARAMS:
gbShowFuncParams = (gbShowFuncParams ? FALSE : TRUE);
CheckMenuItem(
ghMenu,
IDM_SHOWFUNCPARAMS,
MF_BYCOMMAND | (gbShowFuncParams ? MF_CHECKED : MF_UNCHECKED)
);
break;
case IDM_SHOWEVENTS:
gbShowEvents = (gbShowEvents ? FALSE : TRUE);
CheckMenuItem(
ghMenu,
IDM_SHOWEVENTS,
MF_BYCOMMAND | (gbShowEvents ? MF_CHECKED : MF_UNCHECKED)
);
break;
case IDM_SHOWCOMPLETIONS:
gbShowCompletions = (gbShowCompletions ? FALSE : TRUE);
CheckMenuItem(
ghMenu,
IDM_SHOWCOMPLETIONS,
MF_BYCOMMAND | (gbShowCompletions ? MF_CHECKED : MF_UNCHECKED)
);
break;
case IDM_DEBUGBREAK:
gbBreakOnFuncEntry = (gbBreakOnFuncEntry ? FALSE : TRUE);
CheckMenuItem(
ghMenu,
IDM_DEBUGBREAK,
MF_BYCOMMAND | (gbBreakOnFuncEntry ? MF_CHECKED : MF_UNCHECKED)
);
break;
case IDM_SYNCCOMPL:
gbSyncCompl = TRUE;
gbAsyncCompl = gbManualCompl = FALSE;
goto Do_compl_menuitems;
case IDM_ASYNCCOMPL:
gbAsyncCompl = TRUE;
gbSyncCompl = gbManualCompl = FALSE;
goto Do_compl_menuitems;
case IDM_MANUALCOMPL:
gbManualCompl = TRUE;
gbSyncCompl = gbAsyncCompl = FALSE;
goto Do_compl_menuitems;
Do_compl_menuitems:
CheckMenuItem(
ghMenu,
IDM_SYNCCOMPL,
MF_BYCOMMAND | (gbSyncCompl ? MF_CHECKED : MF_UNCHECKED)
);
CheckMenuItem(
ghMenu,
IDM_ASYNCCOMPL,
MF_BYCOMMAND | (gbAsyncCompl ? MF_CHECKED : MF_UNCHECKED)
);
CheckMenuItem(
ghMenu,
IDM_MANUALCOMPL,
MF_BYCOMMAND | (gbManualCompl ? MF_CHECKED : MF_UNCHECKED)
);
break;
case IDM_MANUALRESULTS:
gbManualResults = (gbManualResults ? FALSE : TRUE);
CheckMenuItem(
ghMenu,
IDM_MANUALRESULTS,
MF_BYCOMMAND | (gbManualResults ? MF_CHECKED : MF_UNCHECKED)
);
break;
case IDM_DISABLEUI:
if ((gbDisableUI = (gbDisableUI ? FALSE : TRUE)) == FALSE)
{
PostUpdateWidgetListMsg();
}
CheckMenuItem(
ghMenu,
IDM_DISABLEUI,
MF_BYCOMMAND | (gbDisableUI ? MF_CHECKED : MF_UNCHECKED)
);
break;
case IDM_AUTOCLOSE:
gbAutoClose = (gbAutoClose ? FALSE : TRUE);
CheckMenuItem(
ghMenu,
IDM_AUTOCLOSE,
MF_BYCOMMAND | (gbAutoClose ? MF_CHECKED : MF_UNCHECKED)
);
break;
case IDM_SHOWALL:
{
static UINT ai[5] =
{ IDM_SHOWFUNCENTRY, IDM_SHOWFUNCEXIT, IDM_SHOWFUNCPARAMS,
IDM_SHOWEVENTS, IDM_SHOWCOMPLETIONS };
int i;
gbShowFuncEntry =
gbShowFuncExit =
gbShowFuncParams =
gbShowEvents =
gbShowCompletions = TRUE;
for (i = 0; i < 5; i++)
{
CheckMenuItem (ghMenu, ai[i], MF_BYCOMMAND | MF_CHECKED);
}
break;
}
case IDM_SHOWNONE:
{
static UINT ai[5] =
{ IDM_SHOWFUNCENTRY, IDM_SHOWFUNCEXIT, IDM_SHOWFUNCPARAMS,
IDM_SHOWEVENTS, IDM_SHOWCOMPLETIONS };
int i;
gbShowFuncEntry =
gbShowFuncExit =
gbShowFuncParams =
gbShowEvents =
gbShowCompletions = FALSE;
for (i = 0; i < 5; i++)
{
CheckMenuItem (ghMenu, ai[i], MF_BYCOMMAND | MF_UNCHECKED);
}
break;
}
case IDM_DEFAULTS:
ESPConfigDialog();
break;
case IDC_PREVCTRL:
{
HWND hwndPrev = GetNextWindow (GetFocus (), GW_HWNDPREV);
if (!hwndPrev)
{
hwndPrev = GetDlgItem (hwnd, IDC_LIST2);
}
SetFocus (hwndPrev);
break;
}
case IDC_NEXTCTRL:
{
HWND hwndNext = GetNextWindow (GetFocus (), GW_HWNDNEXT);
if (!hwndNext)
{
hwndNext = GetDlgItem (hwnd, IDC_BUTTON1);
}
SetFocus (hwndNext);
break;
}
case IDC_ENTER:
{
HWND hwndFocus = GetFocus();
if (hwndFocus == ghwndList1)
{
PDRVWIDGET pWidget = GetSelectedWidget();
if (!pWidget)
{
break;
}
WidgetPropertiesDialog (pWidget, FALSE);
}
else if ((hwndFocus == ghwndList2) &&
(SendMessage (ghwndList2, LB_GETCURSEL, 0, 0) != LB_ERR))
{
#ifdef WIN32
wParam = MAKEWPARAM (0, LBN_DBLCLK);
#else
lParam = MAKELPARAM (0, LBN_DBLCLK);
#endif
goto CompleteAsyncRequest;
}
break;
}
case IDC_BUTTON1:
{
EVENT_PARAM params[] =
{
{ "htLine", PT_DWORD, 0, NULL },
{ "htCall", PT_DWORD, 0, NULL },
{ "dwMsg", PT_ORDINAL, 0, aLineMsgs },
{ "dwParam1", PT_DWORD, 0, NULL },
{ "dwParam2", PT_DWORD, 0, NULL },
{ "dwParam3", PT_DWORD, 0, NULL }
};
EVENT_PARAM_HEADER paramsHeader =
{ 6, "Line event", XX_LINEEVENT, params };
PDRVWIDGET pWidget = GetSelectedWidget();
//
// If the selected widget is a line
// or call then reset the defaults
//
if (pWidget)
{
if (pWidget->dwType == WT_DRVCALL)
{
params[0].dwValue = (DWORD)
(((PDRVCALL)pWidget)->pLine->htLine);
params[1].dwValue = (DWORD)
(((PDRVCALL)pWidget)->htCall);
}
else if (pWidget->dwType == WT_DRVLINE)
{
params[0].dwValue = (DWORD)
(((PDRVLINE)pWidget)->htLine);
}
}
if (DialogBoxParam(
hInst,
(LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
(HWND) hwnd,
(DLGPROC) CallDlgProc,
(LPARAM) &paramsHeader
) == IDOK)
{
//
// BUGBUG Currently the pfnLineCreateProc == pfnLineEventProc
//
(*gpfnLineCreateProc)(
(HTAPILINE) params[0].dwValue,
(HTAPICALL) params[1].dwValue,
params[2].dwValue,
params[3].dwValue,
params[4].dwValue,
params[5].dwValue
);
ShowLineEvent(
(HTAPILINE) params[0].dwValue,
(HTAPICALL) params[1].dwValue,
params[2].dwValue,
params[3].dwValue,
params[4].dwValue,
params[5].dwValue
);
//
// BUGBUG
//
// Currently (12/28/94) TAPI.DLL is calling back into the
// SP to clean up calls & lines even after the CLOSE msg
// is sent.
//
if (params[2].dwValue == LINE_CLOSE)
{
//
// See if we can match the htLine specified by the user
// against those in the widgets list, and if so nuke
// the line & all calls on that line
//
pWidget = gaWidgets;
while (pWidget)
{
if ((pWidget->dwType == WT_DRVLINE) &&
( (DWORD) (((PDRVLINE)pWidget)->htLine) ==
params[0].dwValue))
{
// BUGBUG must clean up all pending reqs
ShowStr ("Forcibly closing line, any pending reqs NOT completed");
((PDRVLINE)pWidget)->htLine = (HTAPILINE) NULL;
pWidget = pWidget->pNext;
while (pWidget->dwType == WT_DRVCALL)
{
PDRVWIDGET pWidgetNext = pWidget->pNext;
FreeCall ((PDRVCALL) pWidget);
pWidget = pWidgetNext;
}
UpdateWidgetList();
break;
}
pWidget = pWidget->pNext;
}
}
}
break;
}
case IDC_BUTTON2:
{
EVENT_PARAM params[] =
{
{ "htPhone", PT_DWORD, 0, NULL },
{ "dwMsg", PT_ORDINAL, 0, aPhoneMsgs },
{ "dwParam1", PT_DWORD, 0, NULL },
{ "dwParam2", PT_DWORD, 0, NULL },
{ "dwParam3", PT_DWORD, 0, NULL }
};
EVENT_PARAM_HEADER paramsHeader =
{ 5, "Phone event", XX_PHONEEVENT, params };
PDRVWIDGET pWidget = GetSelectedWidget();
//
// If the selected widget is a phone then reset the default
//
if (pWidget)
{
if (pWidget->dwType == WT_DRVPHONE)
{
params[0].dwValue = (DWORD)
(((PDRVPHONE)pWidget)->htPhone);
}
}
if (DialogBoxParam(
hInst,
(LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
(HWND) hwnd,
(DLGPROC) CallDlgProc,
(LPARAM) &paramsHeader
) == IDOK)
{
//
// BUGBUG Currently the pfnPhoneCreateProc == pfnPhoneEventProc
//
(*gpfnPhoneCreateProc)(
(HTAPIPHONE) params[0].dwValue,
params[1].dwValue,
params[2].dwValue,
params[3].dwValue,
params[4].dwValue
);
ShowPhoneEvent(
(HTAPIPHONE) params[0].dwValue,
params[1].dwValue,
params[2].dwValue,
params[3].dwValue,
params[4].dwValue
);
if (params[1].dwValue == PHONE_CLOSE)
{
//
// See if we can match the htPhone specified by the
// user against those in the widgets list, and if so
// nuke the phone
//
pWidget = gaWidgets;
while (pWidget)
{
if ((pWidget->dwType == WT_DRVPHONE) &&
( (DWORD) (((PDRVPHONE)pWidget)->htPhone) ==
params[0].dwValue))
{
// BUGBUG must clean up all pending reqs
ShowStr ("Forcibly closing phone, any pending reqs NOT completed");
((PDRVPHONE)pWidget)->htPhone = (HTAPIPHONE) NULL;
UpdateWidgetList();
break;
}
pWidget = pWidget->pNext;
}
}
}
break;
}
case IDC_BUTTON3:
{
PDRVWIDGET pWidget = GetSelectedWidget();
PDRVCALL pCall;
if (!pWidget ||
(pWidget->dwType != WT_DRVLINE) ||
!((PDRVLINE)pWidget)->htLine)
{
MessageBox(
hwnd,
"You must select an open provider line",
"Creating an incoming call",
MB_OK
);
break;
}
AllocCall(
(PDRVLINE) pWidget,
(HTAPICALL) NULL,
(LPLINECALLPARAMS) NULL,
&pCall
);
SendLineEvent(
(PDRVLINE) pWidget,
NULL, //pCall,
LINE_NEWCALL,
(DWORD) pCall,
(DWORD) &pCall->htCall,
0
);
if (!pCall->htCall)
{
// BUGBUG try again
break;
}
else
{
//
// Make sure htCall gets shown
//
UpdateWidgetList();
}
SendMessage(
ghwndList1,
LB_SETCURSEL,
(WPARAM) (GetWidgetIndex ((PDRVWIDGET) pCall)),
0
);
//
// Bring up the props dlg for the call automatically so user
// can select call state
//
WidgetPropertiesDialog ((PDRVWIDGET) pCall, TRUE);
break;
}
case IDC_BUTTON4:
SetDlgItemText (hwnd, IDC_EDIT1, "");
break;
case IDC_LIST1:
#ifdef WIN32
if (HIWORD(wParam) == LBN_DBLCLK)
#else
if (HIWORD(lParam) == LBN_DBLCLK)
#endif
{
PDRVWIDGET pWidget = GetSelectedWidget();
if (!pWidget)
{
return FALSE;
}
WidgetPropertiesDialog (pWidget, FALSE);
}
break;
case IDC_LIST2:
CompleteAsyncRequest:
#ifdef WIN32
if (HIWORD(wParam) == LBN_DBLCLK)
#else
if (HIWORD(lParam) == LBN_DBLCLK)
#endif
{
int iSelIndex = (int) SendMessage(ghwndList2,LB_GETCURSEL,0,0);
char buf[64] = "Completing ";
char far *lpszFuncName;
PASYNC_REQUEST_INFO pAsyncReqInfo = (PASYNC_REQUEST_INFO)
SendMessage(
ghwndList2,
LB_GETITEMDATA,
(WPARAM) iSelIndex,
0
);
SendMessage(
ghwndList2,
LB_GETTEXT,
(WPARAM) iSelIndex,
(LPARAM) &buf[11]
);
lpszFuncName = strstr (buf, "TSP") + 5;
if (gbManualResults)
{
EVENT_PARAM params[] =
{
{ "lResult", PT_ORDINAL, 0, aLineErrs }
};
EVENT_PARAM_HEADER paramsHeader =
{ 1, buf, XX_REQRESULT, params };
if (strstr (buf, "pho"))
{
params[0].u.pLookup = aPhoneErrs;
}
if (DialogBoxParam(
hInst,
(LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
(HWND) hwnd,
(DLGPROC) CallDlgProc,
(LPARAM) &paramsHeader
) == IDCANCEL)
{
break;
}
pAsyncReqInfo->lResult = (LONG) params[0].dwValue;
}
if (pAsyncReqInfo->pfnPostProcessProc)
{
(*((POSTPROCESSPROC)pAsyncReqInfo->pfnPostProcessProc))(
lpszFuncName,
pAsyncReqInfo,
FALSE
);
}
else
{
DoCompletion(
lpszFuncName,
pAsyncReqInfo->dwRequestID,
pAsyncReqInfo->lResult,
FALSE
);
}
DrvFree (pAsyncReqInfo);
SendMessage(
ghwndList2,
LB_DELETESTRING,
(WPARAM) iSelIndex,
0
);
}
break;
} //switch
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint (hwnd, &ps);
if (IsIconic (hwnd))
{
DrawIcon (ps.hdc, 0, 0, hIcon);
}
else
{
FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH));
#ifdef WIN32
MoveToEx (ps.hdc, 0, 0, NULL);
#else
MoveTo (ps.hdc, 0, 0);
#endif
LineTo (ps.hdc, 5000, 0);
#ifdef WIN32
MoveToEx (ps.hdc, 0, icyButton - 4, NULL);
#else
MoveTo (ps.hdc, 0, icyButton - 4);
#endif
LineTo (ps.hdc, 5000, icyButton - 4);
}
EndPaint (hwnd, &ps);
break;
}
case WM_SIZE:
{
LONG width = (LONG)LOWORD(lParam);
//
// Adjust globals based on new size
//
cxList1 = (cxList1 * width) / cxWnd;
cxWnd = width;
cyWnd = ((int)HIWORD(lParam)) - icyButton;
//
// Now reposition the child windows
//
SetWindowPos(
ghwndList1,
GetNextWindow (ghwndList1, GW_HWNDPREV),
0,
icyButton,
(int) cxList1,
2*cyWnd/3,
SWP_SHOWWINDOW
);
SetWindowPos(
ghwndList2,
GetNextWindow (ghwndList2, GW_HWNDPREV),
0,
icyButton + 2*cyWnd/3 + icyBorder,
(int) cxList1,
cyWnd/3 - icyBorder,
SWP_SHOWWINDOW
);
SetWindowPos(
ghwndEdit,
GetNextWindow (ghwndEdit, GW_HWNDPREV),
(int) cxList1 + icyBorder,
icyButton,
(int)width - ((int)cxList1 + icyBorder),
cyWnd,
SWP_SHOWWINDOW
);
InvalidateRect (hwnd, NULL, TRUE);
break;
}
case WM_MOUSEMOVE:
{
LONG x = (LONG)((short)LOWORD(lParam));
int y = (int)((short)HIWORD(lParam));
int cxList1New;
if (((y > icyButton) && (x > cxList1)) || bCaptured)
{
SetCursor(
LoadCursor ((HINSTANCE) NULL, MAKEINTRESOURCE(IDC_SIZEWE))
);
}
if (bCaptured)
{
x = (x < cxVScroll ? cxVScroll : x);
x = (x > (cxWnd - cxVScroll) ? (cxWnd - cxVScroll) : x);
cxList1New = (int) (cxList1 + x - xCapture);
SetWindowPos(
ghwndList1,
GetNextWindow (ghwndList1, GW_HWNDPREV),
0,
icyButton,
cxList1New,
2*cyWnd/3,
SWP_SHOWWINDOW
);
SetWindowPos(
ghwndList2,
GetNextWindow (ghwndList2, GW_HWNDPREV),
0,
icyButton + 2*cyWnd/3 + icyBorder,
cxList1New,
cyWnd/3 - icyBorder,
SWP_SHOWWINDOW
);
SetWindowPos(
ghwndEdit,
GetNextWindow (ghwndEdit, GW_HWNDPREV),
(int) cxList1New + icyBorder,
icyButton,
(int)cxWnd - (cxList1New + icyBorder),
cyWnd,
SWP_SHOWWINDOW
);
}
break;
}
case WM_LBUTTONDOWN:
{
if (((int)((short)HIWORD(lParam)) > icyButton) &&
((int)((short)LOWORD(lParam)) > cxList1))
{
xCapture = (LONG)LOWORD(lParam);
SetCapture (hwnd);
bCaptured = TRUE;
}
break;
}
case WM_LBUTTONUP:
{
if (bCaptured)
{
POINT p;
LONG x;
GetCursorPos (&p);
MapWindowPoints (HWND_DESKTOP, hwnd, &p, 1);
x = (LONG) p.x;
ReleaseCapture();
x = (x < cxVScroll ? cxVScroll : x);
x = (x > (cxWnd - cxVScroll) ? (cxWnd - cxVScroll) : x);
cxList1 = cxList1 + (x - xCapture);
bCaptured = FALSE;
InvalidateRect (hwnd, NULL, TRUE);
}
break;
}
case WM_CLOSE:
SaveIniSettings();
ghwndEdit = ghwndList1 = (HWND) NULL;
DestroyIcon (hIcon);
DeleteObject (hFont);
gbExeStarted = FALSE;
PostQuitMessage (0);
break;
} // switch
return FALSE;
}
void
TSPIAPI
DllMsgLoop(
void
)
{
MSG msg;
HACCEL hAccel;
OutputDebugString ("ESP: DllMsgLoop: enter\n\r");
ghwndMain = CreateDialog(
hInst,
(LPCSTR)MAKEINTRESOURCE(IDD_DIALOG1),
(HWND)NULL,
(DLGPROC) MainWndProc
);
if (!ghwndMain)
{
OutputDebugString ("ESP.TSP: DllMsgLoop: CreateDlg failed\n\r");
}
hAccel = LoadAccelerators(
hInst,
(LPCSTR)MAKEINTRESOURCE(IDR_ACCELERATOR1)
);
while (GetMessage (&msg, (HWND) NULL, 0, 0))
{
if (!TranslateAccelerator (ghwndMain, hAccel, &msg))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
#ifdef WIN32
DestroyWindow (ghwndMain);
DestroyAcceleratorTable (hAccel);
#endif
ghwndMain = (HWND) NULL;
}
void
PASCAL
SendLineEvent(
PDRVLINE pLine,
PDRVCALL pCall,
DWORD dwMsg,
DWORD dwParam1,
DWORD dwParam2,
DWORD dwParam3
)
{
//
//
//
(*(pLine->lpfnEventProc))(
pLine->htLine,
(pCall ? pCall->htCall : (HTAPICALL) NULL),
dwMsg,
dwParam1,
dwParam2,
dwParam3
);
if (dwMsg == LINE_CALLSTATE)
{
PostUpdateWidgetListMsg();
}
ShowLineEvent(
pLine->htLine,
(pCall ? pCall->htCall : (HTAPICALL) NULL),
dwMsg,
dwParam1,
dwParam2,
dwParam3
);
}
void
PASCAL
SendPhoneEvent(
PDRVPHONE pPhone,
DWORD dwMsg,
DWORD dwParam1,
DWORD dwParam2,
DWORD dwParam3
)
{
//
//
//
(*(pPhone->lpfnEventProc))(
pPhone->htPhone,
dwMsg,
dwParam1,
dwParam2,
dwParam3
);
ShowPhoneEvent(
pPhone->htPhone,
dwMsg,
dwParam1,
dwParam2,
dwParam3
);
}
void
PASCAL
DoCompletion(
char far *lpszFuncName,
DWORD dwRequestID,
LONG lResult,
BOOL bSync
)
{
(*gpfnCompletionProc)(dwRequestID, lResult);
if (gbShowCompletions)
{
ShowStr(
"%sTSPI_%s: calling compl proc (%ssync), dwReqID=x%lx, lResult = x%lx",
szCallUp,
lpszFuncName,
(bSync ? "" : "a"),
dwRequestID,
lResult
);
}
}
void
PASCAL
SetCallState(
PDRVCALL pCall,
DWORD dwCallState,
DWORD dwCallStateMode
)
{
//
// First, check the current call state. Never send another call state
// msg on a call once you've sent a LINECALLSTATE_IDLE msg (because
// it'll hose apps, and calls instances aren't supposed to be reused).
//
if (pCall->dwCallState == LINECALLSTATE_IDLE)
{
ShowStr(
"SetCallState: call x%lx is IDLE, not changing call state",
pCall
);
return;
}
//
// Next, check to see if the new state matches the current state, and
// if so just return.
//
if (dwCallState == pCall->dwCallState)
{
ShowStr(
"SetCallState: not sending call x%lx state msg " \
"(new state = current state)",
pCall
);
return;
}
//
// Change the call state & notify TAPI
//
pCall->dwCallState = dwCallState;
pCall->dwCallStateMode = dwCallStateMode;
SendLineEvent(
pCall->pLine,
pCall,
LINE_CALLSTATE,
dwCallState,
dwCallStateMode,
pCall->LineCallInfo.dwMediaMode
);
}
LPVOID
DrvAlloc(
size_t numBytes
)
{
LPVOID p = (LPVOID) malloc (numBytes);
if (!p)
{
ShowStr ("Error: DrvAlloc (x%lx) failed", (DWORD) numBytes);
}
return p;
}
void
DrvFree(
LPVOID lp
)
{
free (lp);
}
void
SaveIniSettings(
void
)
{
char buf[32];
RECT rect;
GetWindowRect (ghwndMain, &rect);
{
typedef struct _SAVE_VALUE
{
char *lpszVal;
DWORD dwValue;
} SAVE_VALUE, *PSAVE_VALUE;
SAVE_VALUE aValues[] =
{
{ "Left", (DWORD) rect.left },
{ "Top", (DWORD) rect.top },
{ "Right", (DWORD) rect.right },
{ "Bottom", (DWORD) rect.bottom },
{ "cxWnd", (DWORD) cxWnd },
{ "cxList1", (DWORD) cxList1 },
{ "ShowFuncEntry", (DWORD) gbShowFuncEntry },
{ "ShowFuncExit", (DWORD) gbShowFuncExit },
{ "ShowFuncParams", (DWORD) gbShowFuncParams },
{ "ShowEvents", (DWORD) gbShowEvents },
{ "ShowCompletions", (DWORD) gbShowCompletions },
{ "AutoClose", (DWORD) gbAutoClose },
{ "SyncCompl", (DWORD) gbSyncCompl },
{ "AsyncCompl", (DWORD) gbAsyncCompl },
{ "ManualCompl", (DWORD) gbManualCompl },
{ "ManualResults", (DWORD) gbManualResults },
{ "ShowLineGetIDDlg", (DWORD) gbShowLineGetIDDlg },
{ "DisableUI", (DWORD) gbDisableUI },
{ NULL, 0 },
{ "TSPIVersion", gdwTSPIVersion },
{ "NumLines", gdwNumLines },
{ "NumAddrsPerLine", gdwNumAddrsPerLine },
{ "NumPhones", gdwNumPhones },
{ "LineExtID0", gLineExtID.dwExtensionID0 },
{ "LineExtID1", gLineExtID.dwExtensionID1 },
{ "LineExtID2", gLineExtID.dwExtensionID2 },
{ "LineExtID3", gLineExtID.dwExtensionID3 },
{ "PhoneExtID0", gPhoneExtID.dwExtensionID0 },
{ "PhoneExtID1", gPhoneExtID.dwExtensionID1 },
{ "PhoneExtID2", gPhoneExtID.dwExtensionID2 },
{ "PhoneExtID3", gPhoneExtID.dwExtensionID3 },
{ "OutCallState1", aOutCallStates[0] },
{ "OutCallStateMode1", aOutCallStateModes[0] },
{ "OutCallState2", aOutCallStates[1] },
{ "OutCallStateMode2", aOutCallStateModes[1] },
{ "OutCallState3", aOutCallStates[2] },
{ "OutCallStateMode3", aOutCallStateModes[2] },
{ "OutCallState4", aOutCallStates[3] },
{ "OutCallStateMode4", aOutCallStateModes[3] },
{ "DefLineGetIDID", gdwDefLineGetIDID },
{ NULL, 0 }
};
int i;
for (i = 0; aValues[i].lpszVal; i++)
{
wsprintf (buf, "%ld", aValues[i].dwValue); // decimal
WriteProfileString(
szMySection,
aValues[i].lpszVal,
(LPCSTR) buf
);
}
for (++i; aValues[i].lpszVal; i++)
{
wsprintf (buf, "%lx", aValues[i].dwValue); // hex for DWORDs
WriteProfileString(
szMySection,
aValues[i].lpszVal,
(LPCSTR) buf
);
}
if (IsIconic (ghwndMain))
{
WriteProfileString(
szMySection,
"Left",
"min"
);
}
else if (IsZoomed (ghwndMain))
{
WriteProfileString(
szMySection,
"Left",
"max"
);
}
}
}
BOOL
IsESPInstalled(
HWND hwnd
)
{
int i, iNumProviders;
BOOL bResult = FALSE;
iNumProviders = GetPrivateProfileInt(
szProviders,
szNumProviders,
0,
szTelephonIni
);
for (i = 0; i < iNumProviders; i++)
{
char szProviderFilenameN[32], szProviderName[32];
wsprintf (szProviderFilenameN, "%s%d", szProviderFilename, i);
GetPrivateProfileString(
szProviders,
szProviderFilenameN,
"",
szProviderName,
31,
szTelephonIni
);
if (_stricmp (szProviderName, szEspTsp) == 0)
{
MessageBox(
hwnd,
"ESP is already installed.",
"Installing ESP",
MB_OK
);
bResult = TRUE;
break;
}
}
return bResult;
}