?? tspi.c
字號:
/***********************************************************************/
/**Copyright (c) 1995-2000 Microsoft Corporation. All rights reserved**/
/***********************************************************************/
//
// tapi.c The Telephony Service Provider Interface
//
// @doc EX_TSPI
//
// @topic TSPI |
//
// Tspi Stuff
//
//
#include "windows.h"
#include "types.h"
#include "memory.h"
#include "mcx.h"
#include "tspi.h"
#include "linklist.h"
#include "tspip.h"
#include "tapicomn.h"
#include "config.h"
#include "resource.h"
TSPIGLOBALS TspiGlobals;
const GETIDINFO aGetID[] ={{TEXT("tapi/line"), STRINGFORMAT_BINARY},
{TEXT("comm"), STRINGFORMAT_UNICODE},
{TEXT("comm/datamodem"),STRINGFORMAT_BINARY},
{TEXT("ndis"), STRINGFORMAT_BINARY}};
const WCHAR g_szzClassList[] = {TEXT("tapi/line")TEXT("\0")
TEXT("comm")TEXT("\0")
TEXT("comm/datamodem")TEXT("\0")
TEXT("ndis")TEXT("\0\0")};
const WCHAR g_szDeviceClass[] = TEXT("com");
extern const WCHAR szSettings[];
extern const WCHAR szDialSuffix[];
HANDLE g_hCoreDLL;
// Debug Zones.
#ifdef DEBUG
DBGPARAM dpCurSettings = {
TEXT("Unimodem"), {
TEXT("Init"), TEXT("Temp"), TEXT("Async"), TEXT(""),
TEXT(""), TEXT(""), TEXT(""), TEXT("Dial"),
TEXT("Thread"), TEXT("Lists"), TEXT("Call State"), TEXT("Misc"),
TEXT("Alloc"), TEXT("Function"), TEXT("Warning"), TEXT("Error") },
0xC000
};
#endif
extern BOOL IsAPIReady(DWORD dwAPISet);
// **********************************************************************
// First, we have the TSPI_provider functions
// **********************************************************************
LONG TSPIAPI
TSPI_providerInit(
DWORD dwTSPIVersion, // @parm TSPI Version - in
DWORD dwPermanentProviderID, // @parm Permanent Provider ID - in
DWORD dwLineDeviceIDBase, // @parm Line Base ID - in
DWORD dwPhoneDeviceIDBase, // @parm phone Base ID - in
DWORD dwNumLines, // @parm Number of lines - in
DWORD dwNumPhones, // @parm Number of phones - in
ASYNC_COMPLETION lpfnCompletionProc, // @parm Pointer to callback - in
LPDWORD lpdwTSPIOptions // @parm Optional Behaviour Flags - out
)
{
DEBUGMSG(ZONE_FUNC|ZONE_INIT,
(TEXT("UNIMODEM:+TSPI_providerInit, dwPPID 0x%X, dwDeviceIDBase 0x%X, dwNumLines 0x%X\n"),
dwPermanentProviderID,
dwLineDeviceIDBase,
dwNumLines));
TspiGlobals.fnCompletionCallback = lpfnCompletionProc;
DEBUGMSG(ZONE_FUNC|ZONE_INIT, (TEXT("UNIMODEM:-TSPI_providerInit\n")));
return SUCCESS;
}
LONG TSPIAPI
TSPI_providerInstall(
HWND hwndOwner,
DWORD dwPermanentProviderID
)
{
DEBUGMSG(ZONE_FUNC|ZONE_INIT,
(TEXT("UNIMODEM:+TSPI_providerInstall, dwPPID 0x%X\n"),
dwPermanentProviderID ));
// Unimodem doesn't really need an install. Just say OK.
DEBUGMSG(ZONE_FUNC|ZONE_INIT, (TEXT("UNIMODEM:-TSPI_providerInstall\n")));
return SUCCESS;
}
LONG TSPIAPI
TSPI_providerShutdown(
DWORD dwTSPIVersion
)
{
DEBUGMSG(ZONE_FUNC|ZONE_INIT, (TEXT("UNIMODEM:+TSPI_providerShutdown\n")));
DEBUGMSG(ZONE_FUNC|ZONE_INIT, (TEXT("UNIMODEM:-TSPI_providerShutdown\n")));
return SUCCESS;
}
LONG TSPIAPI TSPI_providerEnumDevices(
DWORD dwPermanentProviderID,
LPDWORD lpdwNumLines,
LPDWORD lpdwNumPhones,
HPROVIDER hProvider,
LINEEVENT lpfnLineCreateProc,
PHONEEVENT lpfnPhoneCreateProc
)
{
DEBUGMSG(ZONE_FUNC|ZONE_INIT, (TEXT("UNIMODEM:+TSPI_providerEnumDevices\n")));
*lpdwNumLines = 0;
// This should be the same event proc that gets passed in to
// lineOpen. but I need it here and now so that I can notify
// TAPI about devices coming and going. I'll probably go ahead
// and store the per device copy just in case TAPI decides that
// the two funcs should be different for some reason.
TspiGlobals.fnLineEventProc = lpfnLineCreateProc;
TspiGlobals.dwProviderID = dwPermanentProviderID;
TspiGlobals.hProvider = hProvider;
// Note that the only devices that we actually enumerate are
// the external modems. All other entries are created when the
// device loader loads the physical device and notifies us about
// it.
EnumExternModems();
DEBUGMSG(ZONE_FUNC|ZONE_INIT, (TEXT("UNIMODEM:-TSPI_providerEnumDevices\n")));
return SUCCESS;
}
// **********************************************************************
// Then, we have the TSPI_line functions
// **********************************************************************
//
// This function serves as a stub in the vtbl for any of the TSPI
// functions which we choose not to support
//
LONG
TSPIAPI
TSPI_Unsupported( void )
{
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_Unsupported\n")));
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_Unsupported\n")));
return LINEERR_OPERATIONUNAVAIL;
}
LONG
TSPIAPI
TSPI_lineAccept(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
LPCSTR lpsUserUserInfo,
DWORD dwSize
)
{
PTLINEDEV pLineDev;
LONG rc;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineAccept\n")));
if ((pLineDev = GetLineDevfromHandle ((DWORD)hdCall)) == NULL) {
DEBUGMSG(ZONE_ERROR|ZONE_CALLS, (TEXT("UNIMODEM:TSPI_lineAccept ** Invalid Call Handle\n")));
rc = LINEERR_INVALCALLHANDLE;
goto exitPoint;
}
if (LINECALLSTATE_OFFERING == pLineDev->dwCallState) {
SetAsyncOp(pLineDev, PENDING_LINEACCEPT);
SetAsyncStatus(pLineDev, 0);
NewCallState(pLineDev, LINECALLSTATE_ACCEPTED, 0);
rc = SetAsyncID(pLineDev, dwRequestID);
} else {
DEBUGMSG(ZONE_ERROR|ZONE_CALLS, (TEXT("UNIMODEM:TSPI_lineAccept ** Invalid Call State\n")));
rc = LINEERR_INVALCALLSTATE;
}
exitPoint:
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineAccept %x\n"), rc));
return rc;
}
LONG
TSPIAPI
TSPI_lineAnswer(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
LPCSTR lpsUserUserInfo,
DWORD dwSize
)
{
LONG rc;
PTLINEDEV pLineDev;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineAnswer\n")));
if ((pLineDev = GetLineDevfromHandle ((DWORD)hdCall)) == NULL) {
DEBUGMSG(ZONE_ERROR|ZONE_CALLS, (TEXT("UNIMODEM:TSPI_lineAnswer ** Invalid Call Handle\n")));
rc = LINEERR_INVALCALLHANDLE;
goto exitPoint;
}
if ((pLineDev->dwCallState != LINECALLSTATE_OFFERING) &&
(pLineDev->dwCallState != LINECALLSTATE_ACCEPTED)) {
DEBUGMSG(ZONE_ERROR|ZONE_CALLS, (TEXT("UNIMODEM:TSPI_lineAnswer ** Invalid Call State\n")));
rc = LINEERR_INVALCALLSTATE;
goto exitPoint;
}
rc = ControlThreadCmd(pLineDev, PENDING_LINEANSWER, dwRequestID);
if (!(rc & 0x80000000)) {
rc = SetAsyncID(pLineDev, dwRequestID);
}
exitPoint:
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineAnswer %x\n"), rc));
return rc;
} // TSPI_lineAnswer
//
// Close a specified open line device
//
LONG TSPIAPI
TSPI_lineClose(
HDRVLINE hdLine
)
{
PTLINEDEV pLineDev;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineClose\n")));
if ((pLineDev = GetLineDevfromHandle ((DWORD)hdLine)) == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:-TSPI_lineClose ** Invalid Line Handle\n")));
return LINEERR_OPERATIONFAILED;
}
EnterCriticalSection(&pLineDev->OpenCS);
pLineDev->dwDetMediaModes = 0;
pLineDev->htLine = NULL;
LeaveCriticalSection(&pLineDev->OpenCS);
if (ControlThreadCmd(pLineDev, PENDING_EXIT, INVALID_PENDINGID)) {
// Make sure that we do not leave anything open
DevlineClose(pLineDev, TRUE);
}
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineClose\n")));
return SUCCESS;
}
LONG TSPIAPI
TSPI_lineCloseCall(
HDRVCALL hdCall
)
{
LONG rc;
PTLINEDEV pLineDev;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineCloseCall\n")));
if ((pLineDev = GetLineDevfromHandle ((DWORD)hdCall)) == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineCloseCall ** Invalid Call Handle\n")));
rc = LINEERR_OPERATIONFAILED;
goto exitPoint;
}
// Mark call as unused
pLineDev->dwCallFlags &= ~(CALL_ALLOCATED|CALL_ACTIVE);
pLineDev->htCall = NULL;
rc = 0;
exitPoint:
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineCloseCall\n")));
return rc;
}
LONG TSPIAPI
TSPI_lineConditionalMediaDetection(
HDRVLINE hdLine,
DWORD dwMediaModes,
LPLINECALLPARAMS const lpCallParams
)
{
LONG rc;
PTLINEDEV pLineDev;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineConditionalMediaDetection\n")));
if ((pLineDev = GetLineDevfromHandle ((DWORD)hdLine)) == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineConditionalMediaDetection ** Invalid Line Handle\n")));
rc = LINEERR_OPERATIONFAILED;
goto exitPoint;
}
// Check the requested modes. There must be only our media modes.
//
if (dwMediaModes & ~pLineDev->dwMediaModes) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineConditionalMediaDetection ** Invalid Media Mode\n")));
rc = LINEERR_INVALMEDIAMODE;
goto exitPoint;
}
// Check the call paramaters
//
if ((lpCallParams->dwBearerMode & (~pLineDev->dwBearerModes)) ||
(lpCallParams->dwMediaMode & (~pLineDev->dwMediaModes)) ||
(lpCallParams->dwAddressMode & (~LINEADDRESSMODE_ADDRESSID))) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineConditionalMediaDetection ** Invalid Call Params\n")));
rc = LINEERR_INVALCALLPARAMS;
goto exitPoint;
}
if ((lpCallParams->dwAddressType) && (lpCallParams->dwAddressType != LINEADDRESSTYPE_PHONENUMBER)) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineConditionalMediaDetection ** Invalid Call Params Address Type\n")));
rc = LINEERR_INVALCALLPARAMS;
goto exitPoint;
}
rc = 0;
exitPoint:
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineConditionalMediaDetection\n")));
return rc;
} // TSPI_lineConditionalMediaDetection
LONG TSPIAPI
TSPI_lineConfigDialogEdit(
DWORD dwDeviceID,
HWND hwndOwner,
LPCWSTR lpszDeviceClass,
LPVOID const lpDeviceConfigIn,
DWORD dwSize,
LPVARSTRING lpDeviceConfigOut
)
{
PTLINEDEV pLineDev;
BYTE cbSize;
DWORD dwRet = SUCCESS;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineConfigDialogEdit\n")));
// Validate the input/output buffer
//
if (lpDeviceConfigOut == NULL) {
DEBUGMSG(ZONE_FUNC|ZONE_ERROR, (TEXT("UNIMODEM:-TSPI_lineConfigDialogEdit Invalid lpDeviceConfigOut\n")));
return LINEERR_INVALPOINTER;
}
if (lpDeviceConfigIn == NULL) {
DEBUGMSG(ZONE_FUNC|ZONE_ERROR, (TEXT("UNIMODEM:-TSPI_lineConfigDialogEdit Invalid lpDeviceConfigIn\n")));
return LINEERR_INVALPOINTER;
}
if (lpDeviceConfigOut->dwTotalSize < sizeof(VARSTRING)) {
DEBUGMSG(ZONE_FUNC|ZONE_ERROR, (TEXT("UNIMODEM:-TSPI_lineConfigDialogEdit lpDeviceConfigOut too small\n")));
return LINEERR_STRUCTURETOOSMALL;
}
// Validate the requested device class
//
if (lpszDeviceClass != NULL)
{
if (!ValidateDevCfgClass(lpszDeviceClass))
return LINEERR_INVALDEVICECLASS;
};
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -