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.
996 lines
33 KiB
996 lines
33 KiB
//+----------------------------------------------------------------------------
|
|
//
|
|
// File: tapi.cpp
|
|
//
|
|
// Module: CMDIAL32.DLL
|
|
//
|
|
// Synopsis: The module contains the code related to TAPI.
|
|
//
|
|
// Copyright (c) 1996-1999 Microsoft Corporation
|
|
//
|
|
// Author: byao created 04/29/97
|
|
// quintinb created Header 08/16/99
|
|
//
|
|
//+----------------------------------------------------------------------------
|
|
#include "cmmaster.h"
|
|
#include "unimodem.h"
|
|
|
|
//
|
|
// Local prototype
|
|
//
|
|
|
|
DWORD GetModemSpeakerMode(TapiLinkageStruct *ptlsTapiLink);
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: TapiCallback
|
|
//
|
|
// Synopsis: NULL callback required param when intializing line
|
|
//
|
|
// Arguments: DWORD hDevice -
|
|
// DWORD dwMsg -
|
|
// DWORD dwCallbackInstance -
|
|
// DWORD dwParam1 -
|
|
// DWORD dwParam2 -
|
|
// DWORD dwParam3 -
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
// History: nickball Created Header 7/7/99
|
|
//
|
|
//+----------------------------------------------------------------------------
|
|
|
|
VOID FAR PASCAL TapiCallback(DWORD hDevice,
|
|
DWORD dwMsg,
|
|
DWORD dwCallbackInstance,
|
|
DWORD dwParam1,
|
|
DWORD dwParam2,
|
|
DWORD dwParam3)
|
|
{
|
|
// nothing
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: OpenTapi
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments: HINSTANCE hInst -
|
|
// TapiLinkageStruct *ptlsTapiLink -
|
|
//
|
|
// Returns: BOOL -
|
|
//
|
|
// History: quintinb Created Header 5/1/99
|
|
//
|
|
//+----------------------------------------------------------------------------
|
|
BOOL OpenTapi(HINSTANCE hInst, TapiLinkageStruct *ptlsTapiLink)
|
|
{
|
|
LONG lRes;
|
|
|
|
if (ptlsTapiLink->bOpen)
|
|
{
|
|
return (TRUE);
|
|
}
|
|
|
|
if (!ptlsTapiLink->pfnlineInitialize || !ptlsTapiLink->pfnlineShutdown)
|
|
{
|
|
SetLastError(ERROR_PROC_NOT_FOUND);
|
|
return (FALSE);
|
|
}
|
|
|
|
lRes = ptlsTapiLink->pfnlineInitialize(&ptlsTapiLink->hlaLine,
|
|
hInst,
|
|
TapiCallback,
|
|
NULL,
|
|
&ptlsTapiLink->dwDevCnt);
|
|
|
|
CMTRACE3(TEXT("OpenTapi() lineInitialize() returns %u, hlaLine=0x%x, dwDevCnt=%u."),
|
|
lRes, ptlsTapiLink->hlaLine, ptlsTapiLink->dwDevCnt);
|
|
|
|
if (lRes != 0)
|
|
{
|
|
DWORD dwErr = ERROR_INVALID_PARAMETER;
|
|
|
|
switch (lRes)
|
|
{
|
|
|
|
case LINEERR_REINIT:
|
|
dwErr = ERROR_BUSY;
|
|
break;
|
|
|
|
case LINEERR_RESOURCEUNAVAIL:
|
|
case LINEERR_NOMEM:
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
SetLastError(dwErr);
|
|
return (FALSE);
|
|
}
|
|
|
|
ptlsTapiLink->bOpen = TRUE;
|
|
ptlsTapiLink->bDevicePicked = FALSE;
|
|
ptlsTapiLink->bModemSpeakerOff = FALSE;
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: CloseTapi
|
|
//
|
|
// Synopsis: Helper function to clean up TAPI line.
|
|
//
|
|
// Arguments: TapiLinkageStruct *ptlsTapiLink - Our TAPI linkage struct
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
// History: nickball Created Header 7/7/99
|
|
//
|
|
//+----------------------------------------------------------------------------
|
|
|
|
void CloseTapi(TapiLinkageStruct *ptlsTapiLink)
|
|
{
|
|
if (ptlsTapiLink->bOpen)
|
|
{
|
|
ptlsTapiLink->bOpen = FALSE;
|
|
ptlsTapiLink->pfnlineShutdown(ptlsTapiLink->hlaLine);
|
|
}
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: LinkToTapi
|
|
//
|
|
// Synopsis: Encapsulates the calling of LinkToDll with the correct table of
|
|
// function names to be used therein with GetProcAddress
|
|
//
|
|
// Arguments: TapiLinkageStruct *ptlsTapiLink - The Tapi linkage struct to receive the function addresses
|
|
// LPCTSTR pszTapi - The explicit name of the DLL
|
|
//
|
|
// Returns: BOOL - TRUE if fully linked
|
|
//
|
|
// History: nickball Created Header 12/31/97
|
|
//
|
|
//+----------------------------------------------------------------------------
|
|
|
|
BOOL LinkToTapi(TapiLinkageStruct *ptlsTapiLink, LPCSTR pszTapi)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
|
|
if (OS_NT)
|
|
{
|
|
static LPCSTR apszTapi[] =
|
|
{
|
|
//
|
|
// Several of the Tapi Functions don't have W versions. Use all the Unicode functions
|
|
// that we can however.
|
|
//
|
|
"lineInitialize", // no W version
|
|
"lineNegotiateAPIVersion", // no W version
|
|
"lineGetDevCapsW",
|
|
"lineGetDevConfig",
|
|
"lineShutdown", // no W version
|
|
"lineTranslateAddressW",
|
|
"lineTranslateDialogW",
|
|
"lineGetTranslateCaps",
|
|
"lineSetCurrentLocation",
|
|
NULL
|
|
};
|
|
|
|
MYDBGASSERT(sizeof(ptlsTapiLink->apvPfnTapi)/sizeof(ptlsTapiLink->apvPfnTapi[0])==sizeof(apszTapi)/sizeof(apszTapi[0]));
|
|
bRet = LinkToDll(&ptlsTapiLink->hInstTapi,pszTapi,apszTapi,ptlsTapiLink->apvPfnTapi);
|
|
}
|
|
else
|
|
{
|
|
static LPCSTR apszTapi[] =
|
|
{
|
|
"lineInitialize",
|
|
"lineNegotiateAPIVersion",
|
|
"lineGetDevCaps",
|
|
"lineGetDevConfig",
|
|
"lineShutdown",
|
|
"lineTranslateAddress",
|
|
"lineTranslateDialog",
|
|
"lineGetTranslateCaps",
|
|
"lineSetCurrentLocation",
|
|
NULL
|
|
};
|
|
MYDBGASSERT(sizeof(ptlsTapiLink->apvPfnTapi)/sizeof(ptlsTapiLink->apvPfnTapi[0])==sizeof(apszTapi)/sizeof(apszTapi[0]));
|
|
bRet = LinkToDll(&ptlsTapiLink->hInstTapi,pszTapi,apszTapi,ptlsTapiLink->apvPfnTapi);
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: UnlinkFromTapi
|
|
//
|
|
// Synopsis: Helper function to release link to TAPI and clear linkage struct
|
|
//
|
|
// Arguments: TapiLinkageStruct *ptlsTapiLink - Ptr to our TAPI linkage struct
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
// History: nickball Created Header 7/7/99
|
|
//
|
|
// t-urama Modified 08/04/00 Access Points: Restore Tapi
|
|
// location when CM was started
|
|
//+----------------------------------------------------------------------------
|
|
|
|
void UnlinkFromTapi(TapiLinkageStruct *ptlsTapiLink)
|
|
{
|
|
if (ptlsTapiLink->hInstTapi)
|
|
{
|
|
//
|
|
// If we changed the original Tapi location, restore it
|
|
//
|
|
if (-1 != ptlsTapiLink->dwOldTapiLocation)
|
|
{
|
|
RestoreOldTapiLocation(ptlsTapiLink);
|
|
}
|
|
|
|
CloseTapi(ptlsTapiLink);
|
|
|
|
FreeLibrary(ptlsTapiLink->hInstTapi);
|
|
|
|
memset(ptlsTapiLink,0,sizeof(*ptlsTapiLink));
|
|
}
|
|
}
|
|
|
|
LPTSTR GetModemFromLineDevCapsWithAlloc(LPLINEDEVCAPS pldcLineDevCaps)
|
|
{
|
|
LPTSTR pszTmp = NULL;
|
|
|
|
if (OS_NT)
|
|
{
|
|
pszTmp = (LPTSTR) CmMalloc((pldcLineDevCaps->dwLineNameSize + 1)*sizeof(TCHAR));
|
|
|
|
if (pszTmp)
|
|
{
|
|
LPTSTR pszPointerIntoTapiBuffer = LPTSTR((DWORD_PTR)pldcLineDevCaps + pldcLineDevCaps->dwLineNameOffset);
|
|
lstrcpynU (pszTmp, pszPointerIntoTapiBuffer, pldcLineDevCaps->dwLineNameSize + 1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// If this is Win9x, then we have an Ansi buffer that we need to convert to Unicode
|
|
//
|
|
LPSTR pszAnsiTmp = (LPSTR) CmMalloc((pldcLineDevCaps->dwLineNameSize + 1)*sizeof(CHAR));
|
|
|
|
if (pszAnsiTmp)
|
|
{
|
|
LPSTR pszPointerIntoTapiBuffer = LPSTR((DWORD_PTR)pldcLineDevCaps + pldcLineDevCaps->dwLineNameOffset);
|
|
lstrcpynA (pszAnsiTmp, pszPointerIntoTapiBuffer, pldcLineDevCaps->dwLineNameSize + 1);
|
|
|
|
pszTmp = SzToWzWithAlloc(pszAnsiTmp);
|
|
|
|
CmFree(pszAnsiTmp);
|
|
}
|
|
|
|
}
|
|
|
|
return pszTmp;
|
|
}
|
|
|
|
BOOL SetTapiDevice(HINSTANCE hInst,
|
|
TapiLinkageStruct *ptlsTapiLink,
|
|
LPCTSTR pszModem)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
LONG lRes;
|
|
DWORD dwTmp;
|
|
LPLINEDEVCAPS pldcLineDevCaps;
|
|
|
|
if (!OpenTapi(hInst,ptlsTapiLink))
|
|
{
|
|
return (FALSE);
|
|
}
|
|
|
|
if (ptlsTapiLink->bDevicePicked && (lstrcmpU(ptlsTapiLink->szDeviceName, pszModem) == 0))
|
|
{
|
|
return (TRUE);
|
|
}
|
|
|
|
CMTRACE1(TEXT("SetTapiDevice() looking for device name match with (%s)."), pszModem);
|
|
|
|
ptlsTapiLink->bDevicePicked = FALSE;
|
|
|
|
//
|
|
// LineGetDevCaps has both an Ansi version (win9x) and a Unicode version. Thus we must use
|
|
// the correct char size as needed.
|
|
//
|
|
dwTmp = sizeof(LINEDEVCAPS) + (2048 * (OS_NT ? sizeof(WCHAR) : sizeof(CHAR)));
|
|
|
|
pldcLineDevCaps = (LPLINEDEVCAPS) CmMalloc(dwTmp);
|
|
if (NULL == pldcLineDevCaps)
|
|
{
|
|
return FALSE;
|
|
}
|
|
pldcLineDevCaps->dwTotalSize = dwTmp;
|
|
|
|
for (ptlsTapiLink->dwDeviceId=0; ptlsTapiLink->dwDeviceId < ptlsTapiLink->dwDevCnt; ptlsTapiLink->dwDeviceId++)
|
|
{
|
|
LINEEXTENSIONID leiLineExtensionId;
|
|
|
|
lRes = ptlsTapiLink->pfnlineNegotiateAPIVersion(ptlsTapiLink->hlaLine,
|
|
ptlsTapiLink->dwDeviceId,
|
|
MIN_TAPI_VERSION,
|
|
MAX_TAPI_VERSION,
|
|
&ptlsTapiLink->dwApiVersion,
|
|
&leiLineExtensionId);
|
|
|
|
CMTRACE3(TEXT("******* SetTapiDevice() lineNegotiateAPIVersion(dwDeviceId=%u) returns %u, dwApiVersion=0x%x."),
|
|
ptlsTapiLink->dwDeviceId, lRes, ptlsTapiLink->dwApiVersion);
|
|
|
|
if (lRes == ERROR_SUCCESS)
|
|
{
|
|
lRes = ptlsTapiLink->pfnlineGetDevCaps(ptlsTapiLink->hlaLine,
|
|
ptlsTapiLink->dwDeviceId,
|
|
ptlsTapiLink->dwApiVersion,
|
|
0,
|
|
pldcLineDevCaps);
|
|
|
|
CMTRACE2(TEXT("SetTapiDevice() lineGetDevCaps(dwDeviceId=%u) returns %u."),
|
|
ptlsTapiLink->dwDeviceId, lRes);
|
|
|
|
if (lRes == ERROR_SUCCESS)
|
|
{
|
|
//
|
|
// Copy out the device name according to reported offset and
|
|
// length. Don't assume that its a NULL terminated string.
|
|
//
|
|
LPTSTR pszTmp = GetModemFromLineDevCapsWithAlloc(pldcLineDevCaps);
|
|
|
|
if (pszTmp)
|
|
{
|
|
//
|
|
// Okay, we have a device name from TAPI, first try to do a straight
|
|
// comparision with the one we are looking for
|
|
//
|
|
|
|
CMTRACE1(TEXT("SetTapiDevice() - examining LineName of (%s)."), pszTmp);
|
|
|
|
if (0 == lstrcmpU(pszModem, pszTmp))
|
|
{
|
|
ptlsTapiLink->bDevicePicked = TRUE;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// We didn't find a straight match but that doesn't mean that
|
|
// this isn't our device. On NT, RAS keeps its device names in ANSI
|
|
// internally. Thus we can try roundtripping the string to MBCS and
|
|
// back and see if they match now. Another possibility is that this
|
|
// is an ISDN device, because on NT4 the RAS name and TAPI name are
|
|
// different for ISDN devices. So, instead of checking the LineName
|
|
// we should check the ProviderInfo (it is concatenation of two NULL terminated strings
|
|
// and the second string is the used by RAS as device name)
|
|
//
|
|
if (OS_NT)
|
|
{
|
|
DWORD dwSize = WzToSz(pszTmp, NULL, 0); // cannot use WzToSzWithAlloc or we would get asserts
|
|
// that the string didn't roundtrip on debug builds.
|
|
// The point here is not to have it round trip so
|
|
// that is what we want but we don't want to assert.
|
|
|
|
if (0 != dwSize)
|
|
{
|
|
LPSTR pszAnsiTmp = (LPSTR)CmMalloc(dwSize*sizeof(CHAR));
|
|
|
|
if (pszAnsiTmp)
|
|
{
|
|
if (WzToSz(pszTmp, pszAnsiTmp, dwSize))
|
|
{
|
|
LPWSTR pszRoundTripped = SzToWzWithAlloc(pszAnsiTmp);
|
|
|
|
if (pszRoundTripped)
|
|
{
|
|
if (0 == lstrcmpU(pszModem, pszRoundTripped))
|
|
{
|
|
ptlsTapiLink->bDevicePicked = TRUE;
|
|
}
|
|
}
|
|
CmFree(pszRoundTripped);
|
|
}
|
|
CmFree(pszAnsiTmp);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Okay, check for an ISDN device name if it is one
|
|
//
|
|
if (!ptlsTapiLink->bDevicePicked)
|
|
{
|
|
//
|
|
// Copy out the provider info according to reported offset
|
|
// and length. Don't assume that its NULL terminated.
|
|
//
|
|
CmFree(pszTmp);
|
|
pszTmp = (LPTSTR) CmMalloc((pldcLineDevCaps->dwProviderInfoSize + 1)*sizeof(TCHAR));
|
|
|
|
if (pszTmp)
|
|
{
|
|
lstrcpynU(pszTmp, (LPTSTR)((LPBYTE)pldcLineDevCaps + pldcLineDevCaps->dwProviderInfoOffset), (pldcLineDevCaps->dwProviderInfoSize + 1));
|
|
|
|
//
|
|
// We should do this only if the device type is ISDN
|
|
// The device type is the first string in the ProviderInfo
|
|
//
|
|
|
|
CMTRACE1(TEXT("SetTapiDevice() - examining ProviderInfo of (%s) for match with (RASDT_Isdn)."), pszTmp);
|
|
|
|
if (0 == lstrcmpiU(pszTmp, RASDT_Isdn))
|
|
{
|
|
ptlsTapiLink->bDevicePicked = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// If we found a device, then we need to copy the name over
|
|
//
|
|
if (ptlsTapiLink->bDevicePicked)
|
|
{
|
|
lstrcpynU(ptlsTapiLink->szDeviceName, pszModem, CELEMS(ptlsTapiLink->szDeviceName));
|
|
|
|
if (OS_NT)
|
|
{
|
|
dwTmp = GetModemSpeakerMode(ptlsTapiLink);
|
|
|
|
if (-1 != dwTmp && MDMSPKR_OFF == dwTmp)
|
|
{
|
|
ptlsTapiLink->bModemSpeakerOff = TRUE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// We found a device, stop looking...
|
|
//
|
|
CmFree(pszTmp);
|
|
break;
|
|
}
|
|
|
|
CmFree(pszTmp);
|
|
}
|
|
}
|
|
}
|
|
|
|
CmFree(pldcLineDevCaps);
|
|
bRet = ptlsTapiLink->bDevicePicked;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: GetModemSpeakerMode
|
|
//
|
|
// Synopsis: Queries Modem settings for Speaker modeof a modem device.
|
|
//
|
|
// Arguments: TapiLinkageStruct *ptlsTapiLink - Ptr to TAPI linkage
|
|
//
|
|
// Returns: DWORD - The speaker mode for a valid modem device or 0xFFFFFFFF
|
|
//
|
|
// History: nickball Created 7/7/99
|
|
//
|
|
//+----------------------------------------------------------------------------
|
|
DWORD GetModemSpeakerMode(TapiLinkageStruct *ptlsTapiLink)
|
|
{
|
|
DWORD dwRet = -1;
|
|
|
|
LPVARSTRING lpVar = (LPVARSTRING) CmMalloc(sizeof(VARSTRING));
|
|
|
|
//
|
|
// Get the required buffer size by querying the config.
|
|
//
|
|
|
|
if (lpVar)
|
|
{
|
|
lpVar->dwTotalSize = sizeof(VARSTRING);
|
|
lpVar->dwUsedSize = lpVar->dwTotalSize;
|
|
|
|
DWORD dwTmpRet = ptlsTapiLink->pfnlineGetDevConfig(ptlsTapiLink->dwDeviceId, lpVar, "comm/datamodem/dialout");
|
|
|
|
if (LINEERR_STRUCTURETOOSMALL == dwTmpRet || lpVar->dwNeededSize > lpVar->dwTotalSize)
|
|
{
|
|
//
|
|
// We need a bigger buffer, re-allocate
|
|
//
|
|
|
|
DWORD dwTmp = lpVar->dwNeededSize;
|
|
|
|
CmFree(lpVar);
|
|
lpVar = (LPVARSTRING) CmMalloc(dwTmp);
|
|
|
|
if (lpVar)
|
|
{
|
|
lpVar->dwTotalSize = dwTmp;
|
|
lpVar->dwUsedSize = lpVar->dwTotalSize;
|
|
|
|
//
|
|
// Now get the actual config
|
|
//
|
|
|
|
dwTmpRet = ptlsTapiLink->pfnlineGetDevConfig(ptlsTapiLink->dwDeviceId, lpVar, "comm/datamodem/dialout");
|
|
|
|
if (ERROR_SUCCESS != dwTmpRet)
|
|
{
|
|
CmFree(lpVar);
|
|
lpVar = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// If we don't have a valid VARSTRING something failed, error out.
|
|
//
|
|
|
|
if (NULL == lpVar)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
//
|
|
// We have a VARSTRING for the "dialout" config,
|
|
// get the MODEMSETTINGS info. and see how the
|
|
// modem speaker is configured.
|
|
//
|
|
|
|
PUMDEVCFG lpDevConfig = NULL;
|
|
LPCOMMCONFIG lpCommConfig = NULL;
|
|
LPMODEMSETTINGS lpModemSettings = NULL;
|
|
|
|
if (lpVar->dwStringFormat == STRINGFORMAT_BINARY &&
|
|
lpVar->dwStringSize >= sizeof(UMDEVCFG))
|
|
{
|
|
lpDevConfig = (PUMDEVCFG)
|
|
((LPBYTE) lpVar + lpVar->dwStringOffset);
|
|
|
|
lpCommConfig = &lpDevConfig->commconfig;
|
|
|
|
//
|
|
// Check modems only
|
|
//
|
|
|
|
if (lpCommConfig->dwProviderSubType == PST_MODEM)
|
|
{
|
|
lpModemSettings = (LPMODEMSETTINGS)((LPBYTE) lpCommConfig +
|
|
lpCommConfig->dwProviderOffset);
|
|
|
|
dwRet = lpModemSettings->dwSpeakerMode;
|
|
}
|
|
}
|
|
|
|
CmFree(lpVar);
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Func: MungePhone
|
|
//
|
|
// Desc: call TAPI to do phone dial info translation
|
|
//
|
|
// Args: [pszModem] - IN, modem string
|
|
// [ppszPhone] - INOUT, phone number for display
|
|
// [ptlsTapiLink] - IN, argument string for connect action
|
|
// [hInst] - IN, instance handle (needed to call TAPI)
|
|
// [fDialingRules] - are dialing rules enabled
|
|
// [ppszDial] - OUT, dialable phone number
|
|
// [fAccessPointsEnabled] - IN, are access points enabled
|
|
// Return: LRESULT
|
|
//
|
|
// Notes:
|
|
//
|
|
// History: 01-Mar-2000 SumitC Added header block
|
|
// 04-Mar-2000 SumitC fixed case for dialing rules not enabled
|
|
// 04-Aug-2000 t-urama Added changing the TAPI location based on access point
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
LRESULT MungePhone(LPCTSTR pszModem,
|
|
LPTSTR *ppszPhone,
|
|
TapiLinkageStruct *ptlsTapiLink,
|
|
HINSTANCE hInst,
|
|
BOOL fDialingRules,
|
|
LPTSTR *ppszDial,
|
|
BOOL fAccessPointsEnabled)
|
|
{
|
|
|
|
LPLINETRANSLATEOUTPUT pltoOutput = NULL;
|
|
DWORD dwLen;
|
|
LPWSTR pszDisplayable = NULL;
|
|
LPWSTR pszDialable = NULL;
|
|
LPSTR pszAnsiDisplayable = NULL;
|
|
LPSTR pszAnsiDialable = NULL;
|
|
LPTSTR pszOriginalPhoneNumber = NULL;
|
|
LRESULT lRes;
|
|
|
|
//
|
|
// Check the input params. Note that ppszDial could be NULL.
|
|
//
|
|
if ((NULL == pszModem) || (NULL == ppszPhone) || (NULL == *ppszPhone) || (NULL == ptlsTapiLink) || (NULL == hInst))
|
|
{
|
|
lRes = ERROR_INVALID_PARAMETER;
|
|
CMASSERTMSG(FALSE, TEXT("MungePhone - invalid param."));
|
|
goto done;
|
|
}
|
|
|
|
if (!SetTapiDevice(hInst, ptlsTapiLink, pszModem))
|
|
{
|
|
lRes = ERROR_NOT_FOUND;
|
|
goto done;
|
|
}
|
|
|
|
if (FALSE == fDialingRules)
|
|
{
|
|
pszOriginalPhoneNumber = CmStrCpyAlloc(*ppszPhone);
|
|
}
|
|
|
|
if (TRUE == fDialingRules)
|
|
{
|
|
if (fAccessPointsEnabled)
|
|
{
|
|
//
|
|
// Access Points are enabled. we now have to change the TAPI location
|
|
// to that of the current access point. First get the current TAPI
|
|
// location from TAPI
|
|
//
|
|
|
|
DWORD dwRet = GetCurrentTapiLocation(ptlsTapiLink);
|
|
if (-1 == dwRet)
|
|
{
|
|
lRes = ERROR_NOT_FOUND;
|
|
goto done;
|
|
}
|
|
|
|
if ((0 != ptlsTapiLink->dwTapiLocationForAccessPoint) && (dwRet != ptlsTapiLink->dwTapiLocationForAccessPoint))
|
|
{
|
|
//
|
|
// The current TAPI location is different from the access point TAPI location
|
|
// Change it. Note that if the current TAPI location is 0, this just means we haven't written
|
|
// one for the favorite yet. Don't try to change it as SetCurrentTapiLocation will error out.
|
|
//
|
|
|
|
lRes = SetCurrentTapiLocation(ptlsTapiLink, ptlsTapiLink->dwTapiLocationForAccessPoint);
|
|
|
|
if (lRes != ERROR_SUCCESS)
|
|
{
|
|
CMASSERTMSG(FALSE, TEXT("MungePhone -- unable to set the current TAPI location."));
|
|
goto done;
|
|
}
|
|
|
|
CMTRACE1(TEXT("MungePhone() - Changed TAPI location to %u."), ptlsTapiLink->dwTapiLocationForAccessPoint);
|
|
|
|
//
|
|
// Save the TAPI location that was being used when CM started.
|
|
// This will be restored when CM exits
|
|
//
|
|
if (-1 == ptlsTapiLink->dwOldTapiLocation)
|
|
{
|
|
ptlsTapiLink->dwOldTapiLocation = dwRet;
|
|
CMTRACE1(TEXT("Saved TAPI location used when CM started, location is %d"), ptlsTapiLink->dwOldTapiLocation);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Setup buffer for output, make sure to size the CHARs properly
|
|
//
|
|
dwLen = sizeof(*pltoOutput) + (1024 * (OS_NT ? sizeof(WCHAR) : sizeof(CHAR)));
|
|
|
|
pltoOutput = (LPLINETRANSLATEOUTPUT) CmMalloc(dwLen);
|
|
if (NULL == pltoOutput)
|
|
{
|
|
lRes = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto done;
|
|
}
|
|
pltoOutput->dwTotalSize = dwLen;
|
|
|
|
//
|
|
// Do the translation
|
|
//
|
|
|
|
if (OS_NT)
|
|
{
|
|
lRes = ptlsTapiLink->pfnlineTranslateAddress(ptlsTapiLink->hlaLine,
|
|
ptlsTapiLink->dwDeviceId,
|
|
ptlsTapiLink->dwApiVersion,
|
|
*ppszPhone,
|
|
0,
|
|
LINETRANSLATEOPTION_CANCELCALLWAITING,
|
|
pltoOutput);
|
|
}
|
|
else
|
|
{
|
|
LPSTR pszAnsiPhone = WzToSzWithAlloc(*ppszPhone);
|
|
|
|
if (pszAnsiPhone)
|
|
{
|
|
//
|
|
// Note that the Cast on parameter 4 is to fake out the compiler,
|
|
// rather than building a full set of "U" infrastructure for
|
|
// the tapi linkage when only a couple of TAPI calls take strings.
|
|
//
|
|
|
|
lRes = ptlsTapiLink->pfnlineTranslateAddress(ptlsTapiLink->hlaLine,
|
|
ptlsTapiLink->dwDeviceId,
|
|
ptlsTapiLink->dwApiVersion,
|
|
(LPWSTR)pszAnsiPhone,
|
|
0,
|
|
LINETRANSLATEOPTION_CANCELCALLWAITING,
|
|
pltoOutput);
|
|
}
|
|
|
|
CmFree(pszAnsiPhone);
|
|
}
|
|
|
|
CMTRACE3(TEXT("MungePhone(Modem=%s,Phone=%s) lineTranslateAddress(DeviceId=%u)"),
|
|
MYDBGSTR(pszModem), MYDBGSTR(*ppszPhone), ptlsTapiLink->dwDeviceId);
|
|
CMTRACE1(TEXT("\treturns %u."), lRes);
|
|
|
|
if (lRes == ERROR_SUCCESS)
|
|
{
|
|
//
|
|
// Get ptrs to displayable and dialable variations
|
|
//
|
|
LPBYTE pBase = (LPBYTE) pltoOutput;
|
|
|
|
if (OS_NT)
|
|
{
|
|
pszDisplayable = (LPTSTR) (pBase + pltoOutput->dwDisplayableStringOffset);
|
|
pszDialable = (LPTSTR) (pBase + pltoOutput->dwDialableStringOffset);
|
|
}
|
|
else
|
|
{
|
|
pszAnsiDisplayable = (LPSTR)(pBase + pltoOutput->dwDisplayableStringOffset);
|
|
pszAnsiDialable = (LPSTR)(pBase + pltoOutput->dwDialableStringOffset);
|
|
}
|
|
}
|
|
|
|
done:
|
|
CmFree(*ppszPhone);
|
|
*ppszPhone = NULL;
|
|
if (ppszDial)
|
|
{
|
|
CmFree(*ppszDial);
|
|
*ppszDial = NULL;
|
|
}
|
|
|
|
// Allocate buffers using the ptr ptrs specified by the caller
|
|
// and fill them with the displayable and dialable versions
|
|
|
|
|
|
if (ERROR_SUCCESS == lRes)
|
|
{
|
|
if (OS_NT)
|
|
{
|
|
if (fDialingRules)
|
|
{
|
|
*ppszPhone = CmStrCpyAlloc(pszDisplayable);
|
|
}
|
|
else
|
|
{
|
|
*ppszPhone = CmStrCpyAlloc(pszOriginalPhoneNumber);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (fDialingRules)
|
|
{
|
|
*ppszPhone = SzToWzWithAlloc(pszAnsiDisplayable);
|
|
}
|
|
else
|
|
{
|
|
*ppszPhone = CmStrCpyAlloc(pszOriginalPhoneNumber);
|
|
}
|
|
}
|
|
|
|
MYDBGASSERT(*ppszPhone);
|
|
if (*ppszPhone)
|
|
{
|
|
//
|
|
// TAPI prepends a space, so trim the displayable number.
|
|
//
|
|
CmStrTrim(*ppszPhone);
|
|
SingleSpace(*ppszPhone);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// If we failed to alloc *ppszPhone, continue because we don't
|
|
// depend on it below but we want the return code to be a failure.
|
|
//
|
|
lRes = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
if (ppszDial)
|
|
{
|
|
if (OS_NT)
|
|
{
|
|
if (fDialingRules)
|
|
{
|
|
*ppszDial = CmStrCpyAlloc(pszDialable);
|
|
}
|
|
else
|
|
{
|
|
*ppszDial = (LPTSTR) CmMalloc(sizeof(TCHAR)*(2 + lstrlenU(pszOriginalPhoneNumber))); // 2 == one for NULL term and one for first char of pszDialable
|
|
|
|
if (*ppszDial)
|
|
{
|
|
(*ppszDial)[0] = pszDialable[0];
|
|
(*ppszDial)[1] = 0;
|
|
lstrcatU(*ppszDial, pszOriginalPhoneNumber);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (fDialingRules)
|
|
{
|
|
*ppszDial = SzToWzWithAlloc(pszAnsiDialable);
|
|
}
|
|
else
|
|
{
|
|
*ppszDial = (LPTSTR) CmMalloc(sizeof(TCHAR)*(2 + lstrlenU(pszOriginalPhoneNumber))); // 2 == one for NULL term and one for first char of pszDialable
|
|
|
|
if (*ppszDial)
|
|
{
|
|
int lRet = MultiByteToWideChar(CP_ACP, 0, pszAnsiDialable, 1, *ppszDial, 1);
|
|
|
|
(*ppszDial)[lRet] = 0;
|
|
lstrcatU(*ppszDial, pszOriginalPhoneNumber);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (FALSE == fDialingRules)
|
|
{
|
|
CmFree(pszOriginalPhoneNumber);
|
|
}
|
|
CmFree(pltoOutput);
|
|
return (lRes);
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Func: GetCurrentTapiLocation
|
|
//
|
|
// Desc: get the current Tapi location
|
|
//
|
|
// Args: [ptlsTapiLink] - IN, Ptr to TAPI linkage
|
|
//
|
|
// Return: DWORD dwCurrentLoc - Current Tapi Location
|
|
//
|
|
// Notes:
|
|
//
|
|
// History: t-urama 07/21/2000 Created
|
|
//-----------------------------------------------------------------------------
|
|
|
|
DWORD GetCurrentTapiLocation(TapiLinkageStruct *ptlsTapiLink)
|
|
{
|
|
MYDBGASSERT(ptlsTapiLink->pfnlineGetTranslateCaps);
|
|
if (!ptlsTapiLink->pfnlineGetTranslateCaps)
|
|
{
|
|
SetLastError(ERROR_PROC_NOT_FOUND);
|
|
return (-1);
|
|
}
|
|
|
|
LPLINETRANSLATECAPS lpTranslateCaps = NULL;
|
|
DWORD dwLen;
|
|
LRESULT lRes;
|
|
DWORD dwRes = -1;
|
|
BOOL bLoopAgain = FALSE;
|
|
|
|
dwLen = sizeof(*lpTranslateCaps) + (1024 * (OS_NT ? sizeof(WCHAR) : sizeof(CHAR)));
|
|
|
|
do
|
|
{
|
|
CmFree(lpTranslateCaps);
|
|
lpTranslateCaps = (LPLINETRANSLATECAPS) CmMalloc(dwLen);
|
|
MYDBGASSERT(lpTranslateCaps);
|
|
|
|
if (NULL == lpTranslateCaps)
|
|
{
|
|
lRes = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
lpTranslateCaps->dwTotalSize = dwLen;
|
|
|
|
lRes = ptlsTapiLink->pfnlineGetTranslateCaps(ptlsTapiLink->hlaLine,
|
|
ptlsTapiLink->dwApiVersion,
|
|
lpTranslateCaps);
|
|
|
|
bLoopAgain = (LINEERR_STRUCTURETOOSMALL == lRes) || ((ERROR_SUCCESS == lRes) && (lpTranslateCaps->dwNeededSize > lpTranslateCaps->dwTotalSize));
|
|
|
|
if (bLoopAgain)
|
|
{
|
|
dwLen = lpTranslateCaps->dwNeededSize;
|
|
}
|
|
|
|
} while(bLoopAgain);
|
|
|
|
if (ERROR_SUCCESS != lRes)
|
|
{
|
|
CMTRACE1(TEXT("lineGetTranslateCaps returns error code %u."), lRes);
|
|
}
|
|
else
|
|
{
|
|
dwRes = lpTranslateCaps->dwCurrentLocationID;
|
|
}
|
|
CmFree(lpTranslateCaps);
|
|
return dwRes;
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Func: SetCurrentTapiLocation
|
|
//
|
|
// Desc: Set the current Tapi location
|
|
//
|
|
// Args: TapiLinkageStruct *ptlsTapiLink - Ptr to TAPI linkage
|
|
// DWORD dwLocation - New location
|
|
//
|
|
// Return: DWORD - Error code
|
|
//
|
|
// Notes:
|
|
//
|
|
// History: t-urama 07/21/2000 Created
|
|
//-----------------------------------------------------------------------------
|
|
|
|
DWORD SetCurrentTapiLocation(TapiLinkageStruct *ptlsTapiLink, DWORD dwLocation)
|
|
{
|
|
MYDBGASSERT(ptlsTapiLink->pfnlineSetCurrentLocation);
|
|
if (!ptlsTapiLink->pfnlineSetCurrentLocation)
|
|
{
|
|
SetLastError(ERROR_PROC_NOT_FOUND);
|
|
return (-1);
|
|
}
|
|
|
|
DWORD dwRes = 0;
|
|
dwRes = ptlsTapiLink->pfnlineSetCurrentLocation(ptlsTapiLink->hlaLine, dwLocation);
|
|
|
|
CMTRACE1(TEXT("SetCurrentTapiLocation -- setting TAPI location to %d"), dwLocation);
|
|
|
|
return dwRes;
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Func: RestoreOldTapiLocation
|
|
//
|
|
// Desc: Restore the Tapi location to the one when CM was started
|
|
//
|
|
// Args: TapiLinkageStruct *ptlsTapiLink - IN, Ptr to TAPI linkage
|
|
//
|
|
// Return: Nothing
|
|
//
|
|
// Notes:
|
|
//
|
|
// History: t-urama 07/21/2000 Created
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void RestoreOldTapiLocation(TapiLinkageStruct *ptlsTapiLink)
|
|
{
|
|
if (ptlsTapiLink->dwOldTapiLocation != ptlsTapiLink->dwTapiLocationForAccessPoint)
|
|
{
|
|
CMTRACE1(TEXT("RestoreOldTapiLocation -- setting TAPI location to %d"), ptlsTapiLink->dwOldTapiLocation);
|
|
MYVERIFY (0 == SetCurrentTapiLocation(ptlsTapiLink, ptlsTapiLink->dwOldTapiLocation));
|
|
}
|
|
}
|