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

📄 wavetsp.cpp

📁 使用环境VC++ 6.0
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// WaveTsp.cpp

#include "pch.h"
#include "wavetsp.h"
#include "tspline.h"
#include "tspcall.h"
#include "resource.h"

HINSTANCE           g_hinst = 0;
HPROVIDER           g_hProvider = 0;
DWORD               g_dwLineDeviceIDBase = 0;
DWORD               g_dwPermanentProviderID = 0;
ASYNC_COMPLETION    g_pfnCompletionProc = 0;

// { dwDialPause, dwDialSpeed, dwDigitDuration, dwWaitForDialtone }
LINEDIALPARAMS      g_dpMin = { 100,  50, 100,  100 };
LINEDIALPARAMS      g_dpDef = { 250,  50, 250,  500 };
LINEDIALPARAMS      g_dpMax = { 1000, 50, 1000, 1000 };

BOOL WINAPI DllMain(
    HINSTANCE   hinst,
    DWORD       dwReason,
    void*      /*pReserved*/)
{
    if( dwReason == DLL_PROCESS_ATTACH )
    {
        g_hinst = hinst;
    }
    
    return TRUE;
}

// TSPI_providerXxx functions /////////////////////////////////////////

LONG TSPIAPI TSPI_providerEnumDevices(
    DWORD       dwPermanentProviderID,
    LPDWORD     pdwNumLines,
    LPDWORD     pdwNumPhones,
    HPROVIDER   hProvider,
    LINEEVENT   pfnLineCreateProc,
    PHONEEVENT  pfnPhoneCreateProc)
{
    BEGIN_PARAM_TABLE("TSPI_providerEnumDevices")
        DWORD_IN_ENTRY(dwPermanentProviderID)
        DWORD_OUT_ENTRY(pdwNumLines)
        DWORD_OUT_ENTRY(pdwNumPhones)
        DWORD_IN_ENTRY(hProvider)
        DWORD_IN_ENTRY(pfnLineCreateProc)
        DWORD_IN_ENTRY(pfnPhoneCreateProc)
    END_PARAM_TABLE()

    g_hProvider = hProvider;
    *pdwNumLines = 1;
    *pdwNumPhones = 0;

    return EPILOG(0);
}

LONG TSPIAPI TSPI_providerInit(
    DWORD               dwTSPIVersion,
    DWORD               dwPermanentProviderID,
    DWORD               dwLineDeviceIDBase,
    DWORD               dwPhoneDeviceIDBase,
    DWORD               dwNumLines,
    DWORD               dwNumPhones,
    ASYNC_COMPLETION    pfnCompletionProc,
    LPDWORD             pdwTSPIOptions)
{
    BEGIN_PARAM_TABLE("TSPI_providerInit")
        DWORD_IN_ENTRY(dwTSPIVersion)
        DWORD_IN_ENTRY(dwPermanentProviderID)
        DWORD_IN_ENTRY(dwLineDeviceIDBase)
        DWORD_IN_ENTRY(dwPhoneDeviceIDBase)
        DWORD_IN_ENTRY(dwNumLines)
        DWORD_IN_ENTRY(dwNumPhones)
        DWORD_IN_ENTRY(pfnCompletionProc)
        DWORD_OUT_ENTRY(pdwTSPIOptions)
    END_PARAM_TABLE()

    g_dwPermanentProviderID = dwPermanentProviderID;
    g_dwLineDeviceIDBase = dwLineDeviceIDBase;
    g_pfnCompletionProc  = pfnCompletionProc;
    *pdwTSPIOptions = LINETSPIOPTION_NONREENTRANT;

    return EPILOG(0);
}

LONG TSPIAPI TSPI_providerShutdown(
    DWORD   dwTSPIVersion,
    DWORD   dwPermanentProviderID)
{
    BEGIN_PARAM_TABLE("TSPI_providerShutdown")
        DWORD_IN_ENTRY(dwTSPIVersion)
        DWORD_IN_ENTRY(dwPermanentProviderID)
    END_PARAM_TABLE()

    return EPILOG(0);
}

LONG TSPIAPI TSPI_providerConfig(
    HWND    hwndOwner,
    DWORD   dwPermanentProviderID)
{
    // Although this func is never called by TAPI v2.0, we export
    // it so that the Telephony Control Panel Applet knows that it
    // can configure this provider via lineConfigProvider(),
    // otherwise Telephon.cpl will not consider it configurable
    BEGIN_PARAM_TABLE("TSPI_providerConfig")
        DWORD_IN_ENTRY(hwndOwner)
        DWORD_IN_ENTRY(dwPermanentProviderID)
    END_PARAM_TABLE()

    return EPILOG(0);
}

LONG TSPIAPI TSPI_providerGenericDialogData(
    DWORD   dwObjectID,
    DWORD   dwObjectType,
    LPVOID  pParams,
    DWORD   dwSize)
{
    BEGIN_PARAM_TABLE("TSPI_providerGenericDialogData")
        DWORD_IN_ENTRY(dwObjectID)
        DWORD_IN_ENTRY(dwObjectType)
        DWORD_IN_ENTRY(pParams)
        DWORD_IN_ENTRY(dwSize)
    END_PARAM_TABLE()

    if( dwObjectType == TUISPIDLL_OBJECT_DIALOGINSTANCE )
    {
        // Handle requests from the UI for dialog-related data
        TSPUIDATA*  pData = (TSPUIDATA*)pParams;
        if( pData->dwRequestID )
        {
            // Complete asynch operation
            g_pfnCompletionProc(pData->dwRequestID, pData->tr);
        }

        // Update call state
        if( pData->tr == 0 )
        {
            pData->pCall->SetCallState(pData->nCallState);
        }
    }

    return EPILOG(0);
}

LONG TSPIAPI TSPI_providerFreeDialogInstance(
    HDRVDIALOGINSTANCE hdDlgInst)
{
    BEGIN_PARAM_TABLE("TSPI_providerFreeDialogInstance")
        DWORD_IN_ENTRY(hdDlgInst)
    END_PARAM_TABLE()

    // W/o this function, TAPISVR.EXE crashes
    return EPILOG(0);
}

LONG TSPIAPI TSPI_providerInstall(
    HWND    hwndOwner,
    DWORD   dwPermanentProviderID)
{
    // Although this func is never called by TAPI v2.0, we export
    // it so that the Telephony Control Panel Applet knows that it
    // can add this provider via lineAddProvider(), otherwise
    // Telephon.cpl will not consider it installable
    BEGIN_PARAM_TABLE("TSPI_providerInstall")
        DWORD_IN_ENTRY(hwndOwner)
        DWORD_IN_ENTRY(dwPermanentProviderID)
    END_PARAM_TABLE()

    return EPILOG(0);
}

LONG TSPIAPI TSPI_providerRemove(
    HWND    hwndOwner,
    DWORD   dwPermanentProviderID)
{
    // Although this func is never called by TAPI v2.0, we export
    // it so that the Telephony Control Panel Applet knows that it
    // can remove this provider via lineRemoveProvider(), otherwise
    // Telephon.cpl will not consider it removable
    BEGIN_PARAM_TABLE("TSPI_providerRemove")
        DWORD_IN_ENTRY(hwndOwner)
        DWORD_IN_ENTRY(dwPermanentProviderID)
    END_PARAM_TABLE()

    return EPILOG(0);
}

LONG TSPIAPI TSPI_providerUIIdentify(
    LPWSTR   pszUIDLLName)
{
    BEGIN_PARAM_TABLE("TSPI_providerUIIdentify")
        STRING_OUT_ENTRY(pszUIDLLName)
    END_PARAM_TABLE()

    // Use the same DLL for both non-UI and UI functions
    char    szFileName[MAX_PATH+1];
    GetModuleFileNameA(g_hinst, szFileName, MAX_PATH);
    mbstowcs(pszUIDLLName, szFileName, strlen(szFileName) + 1);

    return EPILOG(0);
}

// TSPI_lineXxx functions /////////////////////////////////////////////

#define MIN(a, b) (a < b ? a : b)

LONG TSPIAPI TSPI_lineNegotiateTSPIVersion(
    DWORD   dwDeviceID,
    DWORD   dwLowVersion,
    DWORD   dwHighVersion,
    LPDWORD pdwTSPIVersion)
{
    BEGIN_PARAM_TABLE("TSPI_lineNegotiateTSPIVersion")
        DWORD_IN_ENTRY(dwDeviceID)
        DWORD_IN_ENTRY(dwLowVersion)
        DWORD_IN_ENTRY(dwHighVersion)
        DWORD_OUT_ENTRY(pdwTSPIVersion)
    END_PARAM_TABLE()

    LONG    tr = 0;
    
    if( dwLowVersion <= TAPI_CURRENT_VERSION )
    {
        *pdwTSPIVersion = MIN(TAPI_CURRENT_VERSION, dwHighVersion);
    }
    else
    {
        tr = LINEERR_INCOMPATIBLEAPIVERSION;
    }

    return EPILOG(tr);
}

LONG TSPIAPI TSPI_lineGetDevCaps(
    DWORD           dwDeviceID,
    DWORD           dwTSPIVersion,
    DWORD           dwExtVersion,
    LPLINEDEVCAPS   pldc)
{
    BEGIN_PARAM_TABLE("TSPI_lineGetDevCaps")
        DWORD_IN_ENTRY(dwDeviceID)
        DWORD_IN_ENTRY(dwTSPIVersion)
        DWORD_IN_ENTRY(dwExtVersion)
        DWORD_IN_ENTRY(pldc)
    END_PARAM_TABLE()

    LONG            tr = 0;
    const wchar_t   szProviderInfo[] = L"WAVE Service Provider";
    const wchar_t   szLineName[] = L"WaveLine";

    pldc->dwNeededSize = sizeof(LINEDEVCAPS) +
                         sizeof(szProviderInfo) +
                         sizeof(szLineName);
    
    if( pldc->dwNeededSize <= pldc->dwTotalSize )
    {
        pldc->dwUsedSize = pldc->dwNeededSize;

        pldc->dwProviderInfoSize    = sizeof(szProviderInfo);
        pldc->dwProviderInfoOffset  = sizeof(LINEDEVCAPS) + 0;
        wchar_t* pszProviderInfo = (wchar_t*)((BYTE*)pldc + pldc->dwProviderInfoOffset);
        wcscpy(pszProviderInfo, szProviderInfo);
        
        pldc->dwLineNameSize        = sizeof(szLineName);
        pldc->dwLineNameOffset      = sizeof(LINEDEVCAPS) + sizeof(szProviderInfo);
        wchar_t* pszLineName = (wchar_t*)((BYTE*)pldc + pldc->dwLineNameOffset);
        wcscpy(pszLineName, szLineName);
    }
    else
    {
        pldc->dwUsedSize = sizeof(LINEDEVCAPS);
    }
    
    pldc->dwStringFormat      = STRINGFORMAT_ASCII;

// Microsoft recommended algorithm for
// calculating the permanent line ID
#define MAKEPERMLINEID(dwPermProviderID, dwDeviceID) \
    ((LOWORD(dwPermProviderID) << 16) | dwDeviceID)

    pldc->dwPermanentLineID   = MAKEPERMLINEID(g_dwPermanentProviderID, dwDeviceID - g_dwLineDeviceIDBase);
    pldc->dwAddressModes      = LINEADDRESSMODE_ADDRESSID;
    pldc->dwNumAddresses      = 1;
    pldc->dwBearerModes       = LINEBEARERMODE_VOICE;
    pldc->dwMediaModes        = LINEMEDIAMODE_INTERACTIVEVOICE;
    pldc->dwGenerateDigitModes= LINEDIGITMODE_DTMF;
    pldc->dwDevCapFlags       = LINEDEVCAPFLAGS_CLOSEDROP;
    pldc->dwMaxNumActiveCalls = 1;
    pldc->dwLineFeatures      = LINEFEATURE_MAKECALL;

    // DialParams
    pldc->MinDialParams = g_dpMin;
    pldc->MaxDialParams = g_dpMax;
    pldc->DefaultDialParams = g_dpDef;
    
    return EPILOG(tr);
}

LONG TSPIAPI TSPI_lineGetAddressCaps(
    DWORD              dwDeviceID,
    DWORD              dwAddressID,
    DWORD              dwTSPIVersion,
    DWORD              dwExtVersion,
    LPLINEADDRESSCAPS  pac)
{
    BEGIN_PARAM_TABLE("TSPI_lineGetAddressCaps")
        DWORD_IN_ENTRY(dwDeviceID)
        DWORD_IN_ENTRY(dwAddressID)
        DWORD_IN_ENTRY(dwTSPIVersion)
        DWORD_IN_ENTRY(dwExtVersion)
    END_PARAM_TABLE()

    if( dwAddressID != 0 ) return EPILOG(LINEERR_INVALADDRESSID);

    pac->dwNeededSize           = sizeof(LINEADDRESSCAPS);
    pac->dwUsedSize             = sizeof(LINEADDRESSCAPS);

    pac->dwLineDeviceID         = dwDeviceID;
    pac->dwAddressSharing       = LINEADDRESSSHARING_PRIVATE;
    pac->dwCallInfoStates       = LINECALLINFOSTATE_MEDIAMODE |
                                  LINECALLINFOSTATE_APPSPECIFIC;

    pac->dwCallerIDFlags        = LINECALLPARTYID_UNAVAIL;
    pac->dwCalledIDFlags        = LINECALLPARTYID_UNAVAIL;
    pac->dwRedirectionIDFlags   = LINECALLPARTYID_UNAVAIL;
    pac->dwRedirectingIDFlags   = LINECALLPARTYID_UNAVAIL;

    pac->dwCallStates           = LINECALLSTATE_IDLE |
                                  LINECALLSTATE_DIALING |
                                  LINECALLSTATE_CONNECTED;

    pac->dwDialToneModes        = LINEDIALTONEMODE_UNAVAIL;
    pac->dwBusyModes            = LINEBUSYMODE_UNAVAIL;
    pac->dwSpecialInfo          = LINESPECIALINFO_UNAVAIL;

    pac->dwDisconnectModes      = LINEDISCONNECTMODE_UNAVAIL;

    pac->dwMaxNumActiveCalls    = 1;
    pac->dwAddrCapFlags         = LINEADDRCAPFLAGS_DIALED;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -