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

📄 tspi.c

📁 See Hanoi.cpp for the implementation of this cla
💻 C
📖 第 1 页 / 共 5 页
字号:
    (LINECALLSTATE_IDLE        |
    LINECALLSTATE_OFFERING     |
    LINECALLSTATE_ACCEPTED     |
    LINECALLSTATE_CONNECTED    |
    LINECALLSTATE_DISCONNECTED |
    LINECALLSTATE_UNKNOWN)      :

    (LINECALLSTATE_IDLE        |
    LINECALLSTATE_DIALTONE     |
    LINECALLSTATE_DIALING      |
    LINECALLSTATE_PROCEEDING   |
    LINECALLSTATE_CONNECTED    |
    LINECALLSTATE_DISCONNECTED |
    LINECALLSTATE_UNKNOWN);
    
    
    lpCallInfo->dwOrigin = pLineDev->dwCallFlags & CALL_INBOUND ?
                                LINECALLORIGIN_INBOUND : LINECALLORIGIN_OUTBOUND;
    lpCallInfo->dwReason = pLineDev->dwCallFlags & CALL_INBOUND ?
                                LINECALLREASON_UNAVAIL : LINECALLREASON_DIRECT;
    lpCallInfo->dwCallerIDFlags      = LINECALLPARTYID_UNAVAIL;
    lpCallInfo->dwCalledIDFlags      = LINECALLPARTYID_UNAVAIL;
    lpCallInfo->dwConnectedIDFlags   = LINECALLPARTYID_UNAVAIL;
    lpCallInfo->dwRedirectionIDFlags = LINECALLPARTYID_UNAVAIL;
    lpCallInfo->dwRedirectingIDFlags = LINECALLPARTYID_UNAVAIL;

    lpCallInfo->dwAddressType = LINEADDRESSTYPE_PHONENUMBER;
    
exitPoint:  
    DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetCallInfo %x\n"), rc));
    return rc;
}   // TSPI_lineGetCallInfo


LONG
TSPIAPI
TSPI_lineGetCallStatus(
    HDRVCALL hdCall,
    LPLINECALLSTATUS lpCallStatus
    )
{
    PTLINEDEV  pLineDev;
    LONG rc;
    
    DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineGetCallStatus\n")));
    
    InitVarData((LPVOID)lpCallStatus, sizeof(LINECALLSTATUS));
    
    if ((pLineDev = GetLineDevfromHandle ((DWORD)hdCall)) == NULL) {
        DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineGetCallStatus Invalid hdCall\n")));
        rc = LINEERR_INVALCALLHANDLE;
        goto exitPoint;
    }
    
    rc = 0;

    //
    // Current call information
    //
    lpCallStatus->dwCallState     = pLineDev->dwCallState;
    lpCallStatus->dwCallStateMode = pLineDev->dwCallStateMode;
    
    // if we are in takeover mode, disallow all dwCallFeatures
    if (!pLineDev->fTakeoverMode) {
        switch(lpCallStatus->dwCallState) {
        case LINECALLSTATE_OFFERING:
            lpCallStatus->dwCallFeatures  = LINECALLFEATURE_ACCEPT |
            LINECALLFEATURE_SETCALLPARAMS |
            LINECALLFEATURE_DROP;
            // We can only answer if a possible media mode is DATAMODEM.
            if (pLineDev->dwCurMediaModes & LINEMEDIAMODE_DATAMODEM) {
                lpCallStatus->dwCallFeatures |= LINECALLFEATURE_ANSWER;
            }
            break;
        
        case LINECALLSTATE_DIALTONE:
            lpCallStatus->dwCallFeatures  = LINECALLFEATURE_DROP;
            break;
        
        case LINECALLSTATE_DIALING:
            lpCallStatus->dwCallFeatures  = LINECALLFEATURE_DROP;
            if (DEVST_PORTCONNECTWAITFORLINEDIAL == pLineDev->DevState) {
                lpCallStatus->dwCallFeatures |= LINECALLFEATURE_DIAL;
            }
            break;
        
        case LINECALLSTATE_ACCEPTED:
            lpCallStatus->dwCallFeatures  = LINECALLFEATURE_SETCALLPARAMS|LINECALLFEATURE_DROP;
            // We can only answer if a possible media mode is DATAMODEM.
            if (pLineDev->dwCurMediaModes & LINEMEDIAMODE_DATAMODEM) {
                lpCallStatus->dwCallFeatures |= LINECALLFEATURE_ANSWER;
            }
            break;
        
        case LINECALLSTATE_CONNECTED:
            lpCallStatus->dwCallFeatures  = LINECALLFEATURE_SETCALLPARAMS |
            LINECALLFEATURE_DROP;
            break;
        
        case LINECALLSTATE_UNKNOWN:
        case LINECALLSTATE_PROCEEDING:
        case LINECALLSTATE_DISCONNECTED:
            lpCallStatus->dwCallFeatures  = LINECALLFEATURE_DROP;
            break;
        
        case LINECALLSTATE_IDLE:
        default:
            lpCallStatus->dwCallFeatures  = 0;
            break;
        }
    }

exitPoint:
    DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetCallStatus %x\n"), rc));
    return rc;
}   // TSPI_lineGetCallStatus


static const WCHAR szProviderName[] = TEXT("UNIMODEM");

//
// Determine Telephony capabilites for the specified device.
//
// NOTES:
// WinCE UNIMODEM uses a DWORD of DevSpecific information (denoted by
// LINEDEVCAPS.dwDevSpecificSize and LINEDEVCAPS.dwDevSpecificOffset).
// The format of of these 4 bytes is that the first WORD is a device type
// and the second WORD is an "active" indicator (0 for PC card modems that
// have been removed).
//
// The provider name is stored in the ProviderInfo section (denoted by
// LINEDEVCAPS.dwProviderInfoSize and LINEDEVCAPS.dwProviderInfoOffset).
// 
LONG TSPIAPI
TSPI_lineGetDevCaps(
    DWORD dwDeviceID,
    DWORD dwTSPIVersion,
    DWORD dwExtVersion,
    LPLINEDEVCAPS lpLineDevCaps
    )
{
    PTLINEDEV pLineDev;
    int  cbLineNameLen = 0;
    int  cbProviderNameLen = 0;
    int  cbDevClassLen = 0;
    int cbAvailMem = 0;
    DWORD dwRet = SUCCESS;
    
    DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineGetDevCaps\n")));

    InitVarData((LPVOID)lpLineDevCaps, sizeof(LINEDEVCAPS));

     // We need to fill in a device caps struct specific to
     // the device.
    if ((pLineDev = GetLineDevfromID ((DWORD)dwDeviceID)) == NULL)
        return LINEERR_NODEVICE;

    // Check to see how much memory we'll need.
    cbLineNameLen = (wcslen(pLineDev->szFriendlyName) + 1) * sizeof(WCHAR);
    cbProviderNameLen = (wcslen(szProviderName) + 1) * sizeof(WCHAR);
    cbDevClassLen = sizeof(g_szzClassList);
    
    cbAvailMem = (int) (lpLineDevCaps->dwTotalSize - lpLineDevCaps->dwUsedSize);
  
    // Enter the size we ideally need.
    lpLineDevCaps->dwNeededSize = lpLineDevCaps->dwUsedSize +
        cbLineNameLen +         // room for linename
        cbProviderNameLen +     // room for provider name
        cbDevClassLen +         // room for device class list
        (2*sizeof(WORD));       // and room for DevSpecific info

        if (cbAvailMem >= sizeof(DWORD) )
    {
        *(LPWORD)((LPSTR)lpLineDevCaps + lpLineDevCaps->dwUsedSize) = pLineDev->wDeviceType;
        *((LPWORD)((LPSTR)lpLineDevCaps + lpLineDevCaps->dwUsedSize) + 1) = pLineDev->wDeviceAvail;
        
        DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:TSPI_lineGetDevCaps Storing Device Type x%X, available x%X\n"),
                  pLineDev->wDeviceType,
                  pLineDev->wDeviceAvail));

        lpLineDevCaps->dwDevSpecificSize = sizeof( DWORD );
        lpLineDevCaps->dwDevSpecificOffset = lpLineDevCaps->dwUsedSize;        
        lpLineDevCaps->dwUsedSize += lpLineDevCaps->dwDevSpecificSize;
        cbAvailMem -= lpLineDevCaps->dwDevSpecificSize;
    }
    else
    {
        lpLineDevCaps->dwDevSpecificSize = 0;
        lpLineDevCaps->dwDevSpecificOffset = 0;
        lpLineDevCaps->dwNeededSize += sizeof(WORD);
    }
    
     // If the provider info fits, then also append the line name
    if (cbAvailMem >= cbLineNameLen)
    {
        wcscpy((LPWSTR)((LPSTR)lpLineDevCaps + lpLineDevCaps->dwUsedSize),
                pLineDev->szFriendlyName);
        lpLineDevCaps->dwLineNameSize = cbLineNameLen;
        lpLineDevCaps->dwLineNameOffset = lpLineDevCaps->dwUsedSize;
        lpLineDevCaps->dwUsedSize += cbLineNameLen;
        cbAvailMem -= cbLineNameLen;
    }
    else
    {
        lpLineDevCaps->dwLineNameSize = 0;
        lpLineDevCaps->dwLineNameOffset = 0;
    }

    if (cbAvailMem >= cbProviderNameLen)
    {
        wcscpy((LPWSTR)((LPSTR)lpLineDevCaps + lpLineDevCaps->dwUsedSize), szProviderName);
        lpLineDevCaps->dwProviderInfoSize = cbProviderNameLen;
        lpLineDevCaps->dwProviderInfoOffset = lpLineDevCaps->dwUsedSize;
        lpLineDevCaps->dwUsedSize += cbProviderNameLen;
        cbAvailMem -= cbProviderNameLen;
    }
    else
    {
        lpLineDevCaps->dwProviderInfoSize = 0;
        lpLineDevCaps->dwProviderInfoOffset = 0;
    }
    

     // TODO - We don't have permanent ID's yet.
    lpLineDevCaps->dwPermanentLineID = 0;
    lpLineDevCaps->dwStringFormat = STRINGFORMAT_UNICODE;
    lpLineDevCaps->dwAddressModes = LINEADDRESSMODE_ADDRESSID;
    lpLineDevCaps->dwNumAddresses = 1;

     // Bearer mode & information
    lpLineDevCaps->dwMaxRate      = pLineDev->dwMaxDCERate;
    lpLineDevCaps->dwBearerModes  = pLineDev->dwBearerModes;

     // Media mode
    lpLineDevCaps->dwMediaModes = pLineDev->dwMediaModes;

    // We can simulate wait-for-bong if the modem isn't capable of
    // supporting it.
    lpLineDevCaps->dwDevCapFlags  = pLineDev->dwDevCapFlags |
        LINEDEVCAPFLAGS_DIALBILLING |
        LINEDEVCAPFLAGS_CLOSEDROP;

    lpLineDevCaps->dwRingModes         = 1;
    lpLineDevCaps->dwMaxNumActiveCalls = 1;

     // Line device state to be notified
    lpLineDevCaps->dwLineStates = LINEDEVSTATE_CONNECTED |
        LINEDEVSTATE_DISCONNECTED |
        LINEDEVSTATE_OPEN |
        LINEDEVSTATE_CLOSE |
        LINEDEVSTATE_INSERVICE |
        LINEDEVSTATE_OUTOFSERVICE |
        LINEDEVSTATE_REMOVED |
        LINEDEVSTATE_RINGING |
        LINEDEVSTATE_REINIT;

    lpLineDevCaps->dwLineFeatures = LINEFEATURE_MAKECALL;

    //
    // Don't go beyond older version app's buffer
    //
    if (lpLineDevCaps->dwTotalSize >= sizeof(LINEDEVCAPS)) {
        lpLineDevCaps->dwSettableDevStatus = 0; 
        
        // Copy device classes if it fits
        if (cbAvailMem >= cbDevClassLen) {
            memcpy((LPBYTE)lpLineDevCaps + lpLineDevCaps->dwUsedSize, g_szzClassList, cbDevClassLen);
            lpLineDevCaps->dwDeviceClassesSize  = cbDevClassLen;
            lpLineDevCaps->dwDeviceClassesOffset= lpLineDevCaps->dwUsedSize;
            lpLineDevCaps->dwUsedSize += cbDevClassLen;
            cbAvailMem -= cbDevClassLen;
        } else {
            lpLineDevCaps->dwDeviceClassesSize = 0;
            lpLineDevCaps->dwDeviceClassesOffset = 0;
        }    
    
        lpLineDevCaps->dwAddressTypes = LINEADDRESSTYPE_PHONENUMBER;
        lpLineDevCaps->dwAvailableTracking = 0;
    }

    DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetDevCaps x%X\n"), dwRet));    
    return dwRet;
}

//
// WINCE NOTE:
// TSPI_lineGetDevConfig returns the default device configuration for the specified device.
// This is done so applications can avoid storing the devcfg when the user wants the default
// settings. If the settings are different than the default, then the application needs to store
// them and set them via lineSetDevConfig whether lineGetDevConfig returns defaults or not.
// 
LONG TSPIAPI
TSPI_lineGetDevConfig(
    DWORD dwDeviceID,
    LPVARSTRING lpDeviceConfig,
    LPCWSTR lpszDeviceClass
    )
{
    PTLINEDEV pLineDev;
    DWORD dwRet = SUCCESS;
    BYTE  cbSize;
    PDEVMINICFG pDevMiniCfg;
    
    DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineGetDevConfig\n")));

    // Validate the requested device class
    //
    if (lpszDeviceClass != NULL)
    {
        if (!ValidateDevCfgClass(lpszDeviceClass))
            return LINEERR_INVALDEVICECLASS;
    }
    
    // Validate the buffer
    //
    if (lpDeviceConfig == NULL)
        return LINEERR_INVALPOINTER;

    if (lpDeviceConfig->dwTotalSize < sizeof(VARSTRING))
        return LINEERR_STRUCTURETOOSMALL;

    // Validate the device ID
    //
    if ((pLineDev = GetLineDevfromID (dwDeviceID)) == NULL)
        return LINEERR_NODEVICE;
    
    // Validate the buffer size
    //
    cbSize = sizeof(DEVMINICFG);
    lpDeviceConfig->dwUsedSize = sizeof(VARSTRING);
    lpDeviceConfig->dwNeededSize = sizeof(VARSTRING) + cbSize;

    if (lpDeviceConfig->dwTotalSize >= lpDeviceConfig->dwNeededSize)
    {
        pDevMiniCfg = (PDEVMINICFG)(((LPBYTE)lpDeviceConfig) + sizeof(VARSTRING));

        // If someone does a SetDevCfg for some provider who needs a post-dial-terminal
        // and they then want to create a new connection via GetDevCfg/CfgDialogEdit,
        // they will end up with the default connection lookin like the original.
        // To work around this, I will always return the default config here.  If the app
        // needs to remember a specific config for later edit, they must store it themselves.
        // LAM
        getDefaultDevConfig( pLineDev, pDevMiniCfg );
        
        lpDeviceConfig->dwStringFormat = STRINGFORMAT_BINARY;
        lpDeviceConfig->dwStringSize = cbSize;
        lpDeviceConfig->dwStringOffset = sizeof(VARSTRING);
        lpDeviceConfig->dwUsedSize += cbSize;

        DEBUGMSG(ZONE_FUNC|ZONE_CALLS,
                 (TEXT("UNIMODEM:TSPI_lineGetDevConfig (DevID %d): dwModemOptions x%X, fwOptions x%X, dwCallSetupFail x%X\n"),
                  dwDeviceID, pDevMiniCfg->dwModemOptions, pDevMiniCfg->fwOptions, pDevMiniCfg->dwCallSetupFailTimer));
    }
    else
    {
        // Not enough room
        DEBUGMSG(ZONE_FUNC,
                 (TEXT("UNIMODEM:TSPI_lineGetDevConfig needed %d bytes, had %d\n"),
                  lpDeviceConfig->dwNeededSize, lpDeviceConfig->dwTotalSize));
    };

    DEBUGMSG(ZONE_FUNC,
             (TEXT("UNIMODEM:-TSPI_lineGetDevConfig x%X (Used %d, Need %d)\n"),
              dwRet, lpDeviceConfig->dwUsedSize, lpDeviceConfig->dwNeededSize));
    return dwRet;
}

typedef HICON (WINAPI * PFN_LOADICON)(HINSTANCE, LPCWSTR);

LONG
TSPIAPI
TSPI_lineGetIcon(
    DWORD    dwDeviceID,
    LPCWSTR   lpszDeviceClass,
    LPHICON  lphIcon
    )
{
    LONG rc;
    PFN_LOADICON pfnLoadIcon;

⌨️ 快捷键说明

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