Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

990 lines
32 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 dwRet = ptlsTapiLink->pfnlineGetDevConfig(ptlsTapiLink->dwDeviceId, lpVar, "comm/datamodem/dialout");
if (LINEERR_STRUCTURETOOSMALL == dwRet || 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
//
dwRet = ptlsTapiLink->pfnlineGetDevConfig(ptlsTapiLink->dwDeviceId, lpVar, "comm/datamodem/dialout");
if (ERROR_SUCCESS != dwRet)
{
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 = ERROR_INVALID_PARAMETER;
//
// 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, (lstrlenU(*ppszPhone) + 1));
}
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
{
UINT uLen = 2 + lstrlenU(pszOriginalPhoneNumber);// 2 == one for NULL term and one for first char of pszDialable
*ppszDial = (LPTSTR) CmMalloc(sizeof(TCHAR)*uLen);
if (*ppszDial)
{
(*ppszDial)[0] = pszDialable[0];
lstrcpynU((*ppszDial + 1), pszOriginalPhoneNumber, uLen - 1);
}
}
}
else
{
if (fDialingRules)
{
*ppszDial = SzToWzWithAlloc(pszAnsiDialable);
}
else
{
UINT uLen = 2 + lstrlenU(pszOriginalPhoneNumber);// 2 == one for NULL term and one for first char of pszDialable
*ppszDial = (LPTSTR) CmMalloc(sizeof(TCHAR)*uLen);
if (*ppszDial)
{
int lRet = MultiByteToWideChar(CP_ACP, 0, pszAnsiDialable, 1, *ppszDial, 1);
lstrcpynU((*ppszDial + lRet), pszOriginalPhoneNumber, uLen - lRet);
}
}
}
}
}
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;
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);
if (LINEERR_STRUCTURETOOSMALL == lRes)
{
dwLen = lpTranslateCaps->dwNeededSize;
}
} while(LINEERR_STRUCTURETOOSMALL == lRes);
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);
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)
{
SetCurrentTapiLocation(ptlsTapiLink, ptlsTapiLink->dwOldTapiLocation);
}
}