⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tspi.c

📁 See Hanoi.cpp for the implementation of this cla
💻 C
📖 第 1 页 / 共 5 页
字号:
/***********************************************************************/
/**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 + -