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.
962 lines
25 KiB
962 lines
25 KiB
/* Copyright (c) 1995-1996, Microsoft Corporation, all rights reserved
|
|
**
|
|
** tapi.c
|
|
** TAPI utility routines
|
|
** Listed alphabetically
|
|
**
|
|
** 10/20/95 Steve Cobb
|
|
*/
|
|
|
|
#include <windows.h> // Win32 root
|
|
#include <debug.h> // Trace/Assert library
|
|
#include <nouiutil.h> // Heap macros
|
|
#include <tapiutil.h> // Our public header
|
|
|
|
|
|
#define TAPIVERSION 0x00010004
|
|
|
|
TCHAR g_szTapiDevClass[] = TEXT("tapi/line");
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
** Private TAPI entrypoint prototypes
|
|
**----------------------------------------------------------------------------
|
|
*/
|
|
|
|
DWORD APIENTRY
|
|
internalNewLocationW(
|
|
IN WCHAR* pszName );
|
|
|
|
DWORD APIENTRY
|
|
internalRemoveLocation(
|
|
IN DWORD dwID );
|
|
|
|
DWORD APIENTRY
|
|
internalRenameLocationW(
|
|
IN WCHAR* pszOldName,
|
|
IN WCHAR* pszNewName );
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
** Local prototypes
|
|
**----------------------------------------------------------------------------
|
|
*/
|
|
|
|
TCHAR*
|
|
GetCanonPhoneNumber(
|
|
IN DWORD dwCountryCode,
|
|
IN TCHAR* pszAreaCode,
|
|
IN TCHAR* pszPhoneNumber );
|
|
|
|
DWORD
|
|
GetDefaultDeviceBlob(
|
|
IN DWORD dwDeviceId,
|
|
OUT VARSTRING** ppVs,
|
|
OUT BYTE** ppBlob,
|
|
OUT DWORD* pcbBlob );
|
|
|
|
void
|
|
TapiLineCallback(
|
|
IN DWORD hDevice,
|
|
IN DWORD dwMessage,
|
|
IN DWORD dwInstance,
|
|
IN DWORD dwParam1,
|
|
IN DWORD dwParam2,
|
|
IN DWORD dwParam3 );
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
** Routines
|
|
**----------------------------------------------------------------------------
|
|
*/
|
|
|
|
VOID
|
|
FreeCountryInfo(
|
|
IN COUNTRY* pCountries,
|
|
IN DWORD cCountries )
|
|
|
|
/* Frees the 'pCountries' buffer of 'cCountries' elements as returned by
|
|
** GetCountryInfo.
|
|
*/
|
|
{
|
|
if (cCountries)
|
|
{
|
|
Free( *((VOID** )(pCountries + cCountries)) );
|
|
Free( pCountries );
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
FreeLocationInfo(
|
|
IN LOCATION* pLocations,
|
|
IN DWORD cLocations )
|
|
|
|
/* Frees the 'pLocations' buffer of 'cLocations' elements as returned by
|
|
** GetLocationInfo.
|
|
*/
|
|
{
|
|
if (cLocations)
|
|
{
|
|
Free( *((VOID** )(pLocations + cLocations)) );
|
|
Free( pLocations );
|
|
}
|
|
}
|
|
|
|
|
|
TCHAR*
|
|
GetCanonPhoneNumber(
|
|
IN DWORD dwCountryCode,
|
|
IN TCHAR* pszAreaCode,
|
|
IN TCHAR* pszPhoneNumber )
|
|
|
|
/* Returns a TAPI canonical phone number from constituent parts or NULL on
|
|
** error or when 'pszPhoneNumber' is NULL. It is caller's responsibility
|
|
** to Free the returned string.
|
|
*/
|
|
{
|
|
TCHAR szBuf[ 512 ];
|
|
|
|
TRACE("GetCanonPhoneNumber");
|
|
|
|
if (!pszPhoneNumber)
|
|
return NULL;
|
|
|
|
if (pszAreaCode && *pszAreaCode)
|
|
{
|
|
wsprintf( szBuf, TEXT("+%d (%s) %s"),
|
|
dwCountryCode, pszAreaCode, pszPhoneNumber );
|
|
}
|
|
else
|
|
{
|
|
wsprintf( szBuf, TEXT("+%d %s"),
|
|
dwCountryCode, pszPhoneNumber );
|
|
}
|
|
|
|
return StrDup( szBuf );
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetCountryInfo(
|
|
OUT COUNTRY** ppCountries,
|
|
OUT DWORD* pcCountries,
|
|
IN DWORD dwCountryID )
|
|
|
|
/* Sets '*ppCountries' to a heap block containing an array of TAPI country
|
|
** information. '*pcCountries' is set to the number of elements in the
|
|
** array. If 'dwCountryID' is 0, all countries are loaded. Otherwise,
|
|
** only the specific country is loaded.
|
|
**
|
|
** Returns 0 if successful, or an error code. If successful, it is
|
|
** caller's responsibility to call FreeLocationInfo on *ppLocations.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
LINECOUNTRYLIST list;
|
|
LINECOUNTRYLIST* pList;
|
|
LINECOUNTRYENTRY* pEntry;
|
|
COUNTRY* pCountry;
|
|
DWORD cb;
|
|
DWORD i;
|
|
|
|
TRACE("GetCountryInfo");
|
|
|
|
*ppCountries = NULL;
|
|
*pcCountries = 0;
|
|
|
|
/* Get the buffer size needed.
|
|
*/
|
|
ZeroMemory( &list, sizeof(list) );
|
|
list.dwTotalSize = sizeof(list);
|
|
TRACE("lineGetCountryW");
|
|
dwErr = lineGetCountryW( dwCountryID, TAPIVERSION, &list );
|
|
TRACE1("lineGetCountryW=$%X",dwErr);
|
|
if (dwErr != 0)
|
|
return dwErr;
|
|
|
|
/* Allocate the buffer.
|
|
*/
|
|
pList = (LINECOUNTRYLIST* )Malloc( list.dwNeededSize );
|
|
if (!pList)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
/* Fill the buffer with TAPI country info.
|
|
*/
|
|
ZeroMemory( pList, list.dwNeededSize );
|
|
pList->dwTotalSize = list.dwNeededSize;
|
|
TRACE("lineGetCountryW");
|
|
dwErr = lineGetCountryW( dwCountryID, TAPIVERSION, pList );
|
|
TRACE1("lineGetCountryW=$%X",dwErr);
|
|
if (dwErr != 0)
|
|
{
|
|
Free( pList );
|
|
return dwErr;
|
|
}
|
|
|
|
/* Allocate array returned to caller.
|
|
*/
|
|
*pcCountries = pList->dwNumCountries;
|
|
TRACE1("countries=%d",*pcCountries);
|
|
cb = (sizeof(COUNTRY) * *pcCountries) + sizeof(LINECOUNTRYLIST*);
|
|
*ppCountries = Malloc( cb );
|
|
if (!*ppCountries)
|
|
{
|
|
*pcCountries = 0;
|
|
Free( pList );
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
/* Fill buffer returned to caller with information from TAPI location
|
|
** buffer. References to the CAPS buffer are included, so the address
|
|
** of the CAPS buffer is tacked on the end for freeing later.
|
|
*/
|
|
pEntry = (LINECOUNTRYENTRY* )
|
|
(((BYTE* )pList) + pList->dwCountryListOffset);
|
|
pCountry = *ppCountries;
|
|
ZeroMemory( pCountry, cb );
|
|
for (i = 0; i < *pcCountries; ++i)
|
|
{
|
|
pCountry->dwId = pEntry->dwCountryID;
|
|
pCountry->dwCode = pEntry->dwCountryCode;
|
|
pCountry->pszName =
|
|
(TCHAR* )(((BYTE* )pList) + pEntry->dwCountryNameOffset);
|
|
|
|
++pEntry;
|
|
++pCountry;
|
|
}
|
|
|
|
*((LINECOUNTRYLIST** )pCountry) = pList;
|
|
return 0;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetCurrentLocation(
|
|
IN HINSTANCE hInst,
|
|
IN OUT HLINEAPP* pHlineapp )
|
|
|
|
/* Returns the ID of the current TAPI location, or the default 0 if there
|
|
** is none. 'HInst' is the module instance handle. '*PHlineapp' is the
|
|
** TAPI handle returned from a previous TAPI call or NULL if none.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
LINETRANSLATECAPS caps;
|
|
DWORD dwId;
|
|
|
|
dwId = 0;
|
|
|
|
#if 0
|
|
dwErr = TapiInit( hInst, pHlineapp, NULL );
|
|
if (dwErr == 0)
|
|
#endif
|
|
{
|
|
ZeroMemory( &caps, sizeof(caps) );
|
|
caps.dwTotalSize = sizeof(caps);
|
|
TRACE("lineGetTranslateCapsW");
|
|
dwErr = lineGetTranslateCapsW( *pHlineapp, TAPIVERSION, &caps );
|
|
TRACE1("lineGetTranslateCapsW=$%X",dwErr);
|
|
if (dwErr == 0)
|
|
dwId = caps.dwCurrentLocationID;
|
|
}
|
|
|
|
TRACE1("GetCurrentLocation=%d",dwId);
|
|
return dwId;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetDefaultDeviceBlob(
|
|
IN DWORD dwDeviceId,
|
|
OUT VARSTRING** ppVs,
|
|
OUT BYTE** ppBlob,
|
|
OUT DWORD* pcbBlob )
|
|
|
|
/* Returns the default device blob for device 'dwDeviceId' in caller's
|
|
** '*ppBlob'. '*pcbBlob' is set to the size of the blob.
|
|
**
|
|
** Returns 0 if successful or an error code. If succussful, it is
|
|
** caller's responsibility to Free the returned '*ppVs', which is a buffer
|
|
** containing the returned blob.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
VARSTRING vs;
|
|
VARSTRING* pVs;
|
|
|
|
*ppVs = NULL;
|
|
*ppBlob = NULL;
|
|
*pcbBlob = 0;
|
|
|
|
/* Get the buffer size needed.
|
|
*/
|
|
ZeroMemory( &vs, sizeof(vs) );
|
|
vs.dwTotalSize = sizeof(vs);
|
|
TRACE("lineGetDevConfigW");
|
|
dwErr = lineGetDevConfigW( dwDeviceId, &vs, g_szTapiDevClass );
|
|
TRACE1("lineGetDevConfigW=$%X",dwErr);
|
|
if (dwErr != LINEERR_STRUCTURETOOSMALL && dwErr != 0)
|
|
return dwErr;
|
|
|
|
/* Allocate the buffer.
|
|
*/
|
|
pVs = (VARSTRING* )Malloc( vs.dwNeededSize );
|
|
if (!pVs)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
/* Fill buffer with TAPI VARSTRING containing blob information.
|
|
*/
|
|
ZeroMemory( pVs, vs.dwNeededSize );
|
|
pVs->dwTotalSize = vs.dwNeededSize;
|
|
TRACE("lineGetDevConfigW");
|
|
dwErr = lineGetDevConfigW( dwDeviceId, pVs, g_szTapiDevClass );
|
|
TRACE1("lineGetDevConfigW=$%X",dwErr);
|
|
if (dwErr != 0)
|
|
{
|
|
Free( pVs );
|
|
return dwErr;
|
|
}
|
|
|
|
*ppVs = pVs;
|
|
*ppBlob = ((BYTE* )pVs) + pVs->dwStringOffset;
|
|
*pcbBlob = pVs->dwStringSize;
|
|
TRACE1("GetDefaultDeviceBlob=0,cb=%d",*pcbBlob);
|
|
return 0;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetLocationInfo(
|
|
IN HINSTANCE hInst,
|
|
IN OUT HLINEAPP* pHlineapp,
|
|
OUT LOCATION** ppLocations,
|
|
OUT DWORD* pcLocations,
|
|
OUT DWORD* pdwCurLocation )
|
|
|
|
/* Sets '*ppLocations' to a heap block containing TAPI location
|
|
** information. '*PcLocations' is set to the number of elements in the
|
|
** array. '*pdwLocation' is set to the TAPI ID of the currently selected
|
|
** location. '*PHlineapp' is the TAPI handle returned from a previous
|
|
** TAPI call or NULL if none. 'HInst' is the module instance handle.
|
|
**
|
|
** Returns 0 if successful, or an error code. If successful, it is
|
|
** caller's responsibility to call FreeLocationInfo on *ppLocations.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
LINETRANSLATECAPS caps;
|
|
LINETRANSLATECAPS* pCaps;
|
|
LINELOCATIONENTRY* pEntry;
|
|
LOCATION* pLocation;
|
|
DWORD cb;
|
|
DWORD i;
|
|
|
|
TRACE("GetLocationInfo");
|
|
|
|
*ppLocations = NULL;
|
|
*pcLocations = 0;
|
|
*pdwCurLocation = 0;
|
|
|
|
#if 0
|
|
dwErr = TapiInit( hInst, pHlineapp, NULL );
|
|
if (dwErr != 0)
|
|
return dwErr;
|
|
#endif
|
|
|
|
/* Get the buffer size needed.
|
|
*/
|
|
ZeroMemory( &caps, sizeof(caps) );
|
|
caps.dwTotalSize = sizeof(caps);
|
|
TRACE("lineGetTranslateCapsW");
|
|
dwErr = lineGetTranslateCapsW( *pHlineapp, TAPIVERSION, &caps );
|
|
TRACE1("lineGetTranslateCapsW=$%X",dwErr);
|
|
if (dwErr != 0)
|
|
{
|
|
if (dwErr == (DWORD )LINEERR_INIFILECORRUPT)
|
|
{
|
|
/* Means the TAPI registry is uninitialized. Return no locations
|
|
** and "default" current location.
|
|
*/
|
|
dwErr = 0;
|
|
}
|
|
return dwErr;
|
|
}
|
|
|
|
/* Allocate the buffer.
|
|
*/
|
|
pCaps = (LINETRANSLATECAPS* )Malloc( caps.dwNeededSize );
|
|
if (!pCaps)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
/* Fill buffer with TAPI location data.
|
|
*/
|
|
ZeroMemory( pCaps, caps.dwNeededSize );
|
|
pCaps->dwTotalSize = caps.dwNeededSize;
|
|
TRACE("lineGetTranslateCapsW");
|
|
dwErr = lineGetTranslateCapsW( *pHlineapp, TAPIVERSION, pCaps );
|
|
TRACE1("lineGetTranslateCapsW=$%X",dwErr);
|
|
if (dwErr != 0)
|
|
{
|
|
Free( pCaps );
|
|
return dwErr;
|
|
}
|
|
|
|
/* Allocate array returned to caller.
|
|
*/
|
|
*pcLocations = pCaps->dwNumLocations;
|
|
*pdwCurLocation = pCaps->dwCurrentLocationID;
|
|
TRACE2("locs=%d,cur=%d",*pcLocations,*pdwCurLocation);
|
|
cb = (sizeof(LOCATION) * *pcLocations) + sizeof(LINETRANSLATECAPS*);
|
|
*ppLocations = Malloc( cb );
|
|
if (!*ppLocations)
|
|
{
|
|
*pcLocations = 0;
|
|
Free( pCaps );
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
/* Fill buffer returned to caller with information from TAPI location
|
|
** buffer. References to the CAPS buffer are included, so the address
|
|
** of the CAPS buffer is tacked on the end for freeing later.
|
|
*/
|
|
pEntry = (LINELOCATIONENTRY* )
|
|
(((BYTE* )pCaps) + pCaps->dwLocationListOffset);
|
|
pLocation = *ppLocations;
|
|
ZeroMemory( pLocation, cb );
|
|
for (i = 0; i < *pcLocations; ++i)
|
|
{
|
|
pLocation->dwId = pEntry->dwPermanentLocationID;
|
|
pLocation->pszName =
|
|
(TCHAR* )(((BYTE* )pCaps) + pEntry->dwLocationNameOffset);
|
|
|
|
++pEntry;
|
|
++pLocation;
|
|
}
|
|
|
|
*((LINETRANSLATECAPS** )pLocation) = pCaps;
|
|
return 0;
|
|
}
|
|
|
|
|
|
DWORD
|
|
SetCurrentLocation(
|
|
IN HINSTANCE hInst,
|
|
IN OUT HLINEAPP* pHlineapp,
|
|
IN DWORD dwLocationId )
|
|
|
|
/* Sets the current TAPI location to 'dwLocationId'. '*PHlineapp' is the
|
|
** TAPI handle returned from a previous TAPI call or NULL if none.
|
|
** 'HInst' is the module instance handle.
|
|
**
|
|
** Returns 0 if successful, or an error code.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
HLINEAPP hlineapp;
|
|
|
|
TRACE1("SetCurrentLocation(id=%d)",dwLocationId);
|
|
|
|
#if 0
|
|
dwErr = TapiInit( hInst, pHlineapp, NULL );
|
|
if (dwErr != 0)
|
|
return dwErr;
|
|
#endif
|
|
|
|
TRACE("lineSetCurrentLocation");
|
|
dwErr = lineSetCurrentLocation( *pHlineapp, dwLocationId );
|
|
TRACE1("lineSetCurrentLocation=$%X",dwErr);
|
|
|
|
if (dwErr == (DWORD )LINEERR_INIFILECORRUPT && dwLocationId == 0)
|
|
{
|
|
/* Means the TAPI registry is uninitialized. If caller is setting the
|
|
** default location, this is OK.
|
|
*/
|
|
return 0;
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
#if 0
|
|
DWORD
|
|
TapiConfigureDlg(
|
|
IN HWND hwndOwner,
|
|
IN DWORD dwDeviceId,
|
|
IN OUT BYTE** ppBlob,
|
|
IN OUT DWORD* pcbBlob )
|
|
|
|
/* Popup the TAPI dialog to edit device 'dwDeviceId, with input blob
|
|
** '*ppBlob' of size '*pcBlob'. '*ppBlob' can be NULL causing the current
|
|
** system defaults for the device to be used as input. 'HwndOwner' is the
|
|
** window owning the modal dialog.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
VARSTRING vs;
|
|
VARSTRING* pVs;
|
|
VARSTRING* pVsDefault;
|
|
BYTE* pIn;
|
|
BYTE* pOut;
|
|
DWORD cbIn;
|
|
DWORD cbOut;
|
|
|
|
TRACE("TapiConfigureDlg");
|
|
|
|
pVs = NULL;
|
|
|
|
if (*ppBlob)
|
|
{
|
|
/* Caller provided input blob.
|
|
*/
|
|
pIn = *ppBlob;
|
|
cbIn = *pcbBlob;
|
|
}
|
|
else
|
|
{
|
|
/* Caller did not provide input blob, so look up the default for this
|
|
** device.
|
|
*/
|
|
dwErr = GetDefaultDeviceBlob( dwDeviceId, &pVsDefault, &pIn, &cbIn );
|
|
if (dwErr != 0)
|
|
return dwErr;
|
|
}
|
|
|
|
/* Get the buffer size needed.
|
|
*/
|
|
ZeroMemory( &vs, sizeof(vs) );
|
|
vs.dwTotalSize = sizeof(vs);
|
|
TRACE("lineConfigDialogEditW");
|
|
dwErr = lineConfigDialogEditW(
|
|
dwDeviceId, hwndOwner, g_szTapiDevClass, pIn, cbIn, &vs );
|
|
TRACE1("lineConfigDialogEditW=$%X",dwErr);
|
|
if (dwErr != LINEERR_STRUCTURETOOSMALL && dwErr != 0)
|
|
goto TapiConfigureDlg_Error;
|
|
|
|
/* Allocate the buffer.
|
|
*/
|
|
pVs = (VARSTRING* )Malloc( vs.dwNeededSize );
|
|
if (!pVs)
|
|
{
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto TapiConfigureDlg_Error;
|
|
}
|
|
|
|
/* Popup the dialog which edits the information in the buffer.
|
|
*/
|
|
ZeroMemory( pVs, vs.dwNeededSize );
|
|
pVs->dwTotalSize = vs.dwNeededSize;
|
|
TRACE("lineConfigDialogEditW");
|
|
dwErr = lineConfigDialogEditW(
|
|
dwDeviceId, hwndOwner, g_szTapiDevClass, pIn, cbIn, pVs );
|
|
TRACE1("lineConfigDialogEditW=$%X",dwErr);
|
|
if (dwErr != 0)
|
|
goto TapiConfigureDlg_Error;
|
|
|
|
/* Allocate a new "blob" buffer and fill it with the "blob" subset of the
|
|
** larger VARSTRING buffer. Can't avoid this copy without introducing
|
|
** Freeing complexity for caller.
|
|
*/
|
|
cbOut = pVs->dwStringSize;
|
|
pOut = Malloc( cbOut );
|
|
if (!pOut)
|
|
{
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto TapiConfigureDlg_Error;
|
|
}
|
|
|
|
CopyMemory( pOut, ((BYTE* )pVs) + pVs->dwStringOffset, cbOut );
|
|
Free( pVs );
|
|
|
|
if (pIn == *ppBlob)
|
|
Free( pIn );
|
|
else
|
|
Free( pVsDefault );
|
|
|
|
*ppBlob = pOut;
|
|
*pcbBlob = cbOut;
|
|
TRACE1("TapiConfigureDlg=0,cbBlob=%d",cbOut);
|
|
return 0;
|
|
|
|
TapiConfigureDlg_Error:
|
|
|
|
Free0( pVs );
|
|
if (pIn != *ppBlob)
|
|
Free( pVsDefault );
|
|
|
|
TRACE1("TapiConfigureDlg=$%X",dwErr);
|
|
return dwErr;
|
|
}
|
|
#endif
|
|
|
|
|
|
#if 0
|
|
DWORD
|
|
TapiInit(
|
|
IN HINSTANCE hInst,
|
|
IN OUT HLINEAPP* pHlineapp,
|
|
OUT DWORD* pcDevices )
|
|
|
|
/* Initialize TAPI and return the app handle and device count. Does
|
|
** nothing if '*pHlineapp' is non-NULL. 'PcDevices' may be NULL if caller
|
|
** is not interested in the device count. 'HInst' is the module instance.
|
|
**
|
|
** According to BernieM, the hlineapp passed to the TAPI location,
|
|
** country, and line translation APIs (the ones we use in the UI) is not
|
|
** currently used. Therefore, since, lineInitialize can take several
|
|
** seconds to complete we optimize for speed by stubbing it out in these
|
|
** wrappers.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
HLINEAPP hlineapp;
|
|
DWORD cDevices;
|
|
|
|
ASSERT(pHlineapp);
|
|
TRACE1("TapiInit(h=$%x)",*pHlineapp);
|
|
|
|
dwErr = 0;
|
|
|
|
if (!*pHlineapp)
|
|
{
|
|
hlineapp = NULL;
|
|
cDevices = 0;
|
|
|
|
TRACE("lineInitializeW");
|
|
dwErr = lineInitializeW(
|
|
&hlineapp, hInst, TapiLineCallback, NULL, &cDevices );
|
|
TRACE1("lineInitializeW=$%X",dwErr);
|
|
|
|
if (dwErr == 0)
|
|
{
|
|
*pHlineapp = hlineapp;
|
|
if (pcDevices)
|
|
*pcDevices = cDevices;
|
|
}
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
#endif
|
|
|
|
|
|
void
|
|
TapiLineCallback(
|
|
IN DWORD hDevice,
|
|
IN DWORD dwMessage,
|
|
IN DWORD dwInstance,
|
|
IN DWORD dwParam1,
|
|
IN DWORD dwParam2,
|
|
IN DWORD dwParam3 )
|
|
|
|
/* Dummy TAPI callback required by lineInitialize.
|
|
*/
|
|
{
|
|
TRACE3("TapiLineCallback(h=$%x,m=$%x,i=$%x...",hDevice,dwMessage,dwInstance);
|
|
TRACE3(" p1=$%x,p2=$%x,p3=$%x)",dwParam1,dwParam2,dwParam3);
|
|
}
|
|
|
|
|
|
DWORD
|
|
TapiLocationDlg(
|
|
IN HINSTANCE hInst,
|
|
IN OUT HLINEAPP* pHlineapp,
|
|
IN HWND hwndOwner,
|
|
IN DWORD dwCountryCode,
|
|
IN TCHAR* pszAreaCode,
|
|
IN TCHAR* pszPhoneNumber,
|
|
IN DWORD dwDeviceId )
|
|
|
|
/* Displays the TAPI location property sheet owned by 'hwndOwner'.
|
|
** '*PHlineapp' is the TAPI handle returned from a previous TAPI call or
|
|
** NULL if none. 'DwCountryCode', 'pszAreaCode', and 'pszPhoneNumber' are
|
|
** the components of the TAPI canonical phone number. 'DwDeviceId'
|
|
** specified the device to which the dialog applies, or 0 for a generic
|
|
** device. 'HInst' is the module instance handle.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
DWORD cDevices;
|
|
TCHAR* pszCanon;
|
|
|
|
TRACE("TapiLocationDlg");
|
|
|
|
#if 0
|
|
dwErr = TapiInit( hInst, pHlineapp, NULL );
|
|
if (dwErr != 0)
|
|
return dwErr;
|
|
#endif
|
|
|
|
pszCanon = GetCanonPhoneNumber(
|
|
dwCountryCode, pszAreaCode, pszPhoneNumber );
|
|
TRACEW1("lineTranslateDialogW(\"%s\")",(pszCanon)?pszCanon:TEXT(""));
|
|
dwErr = lineTranslateDialogW(
|
|
*pHlineapp, dwDeviceId, TAPIVERSION, hwndOwner, pszCanon );
|
|
|
|
if (dwErr == LINEERR_INUSE)
|
|
{
|
|
// This error means the dialog is already up and hence our request was
|
|
// ignored. From our point of view, this is success, e.g. we don't
|
|
// need to do an error popup, so map accordingly. See bug 216683.
|
|
//
|
|
dwErr = 0;
|
|
}
|
|
|
|
TRACE1("lineTranslateDialogW=$%X",dwErr);
|
|
Free0( pszCanon );
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
DWORD APIENTRY
|
|
TapiNewLocation(
|
|
IN TCHAR* pszName )
|
|
|
|
/* Clone current location giving name 'pszName'.
|
|
**
|
|
** Returns 0 if successful, or an error code.
|
|
*/
|
|
{
|
|
TRACEW1("TapiNewLocation(%s)",pszName);
|
|
|
|
#ifdef UNICODE
|
|
|
|
return internalNewLocationW( pszName );
|
|
|
|
#else
|
|
{
|
|
DWORD dwErr;
|
|
WCHAR* pszNameW;
|
|
|
|
pszNameW = StrDupWFromA( pszName );
|
|
dwErr = internalNewLocation( pszNameW );
|
|
Free0( pszNameW );
|
|
return dwErr;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
DWORD
|
|
TapiNoLocationDlg(
|
|
IN HINSTANCE hInst,
|
|
IN HLINEAPP* pHlineapp,
|
|
IN HWND hwndOwner )
|
|
|
|
/* Gives TAPI a chance to initialize the first location, if necessary.
|
|
** Call this before any other TAPI calls. 'HInst' is the module instance
|
|
** handle. '*pHlineapp' is the handle returned from a previous TAPI call
|
|
** or NULL if none (typical in this case). 'HwndOwner' is the window to
|
|
** own the TAPI dialog, if it appears.
|
|
**
|
|
** Returns 0 if successful, or an error code.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
LINETRANSLATECAPS caps;
|
|
|
|
TRACE("TapiNoLocationDlg");
|
|
|
|
#if 0
|
|
dwErr = TapiInit( hInst, pHlineapp, NULL );
|
|
if (dwErr != 0)
|
|
return dwErr;
|
|
#endif
|
|
|
|
/* Make an arbitrary TAPI call to see if the TAPI registry has been
|
|
** initialized.
|
|
*/
|
|
ZeroMemory( &caps, sizeof(caps) );
|
|
caps.dwTotalSize = sizeof(caps);
|
|
TRACE("lineGetTranslateCapsW");
|
|
dwErr = lineGetTranslateCapsW( *pHlineapp, TAPIVERSION, &caps );
|
|
TRACE1("lineGetTranslateCapsW=$%X",dwErr);
|
|
|
|
if (dwErr == (DWORD )LINEERR_INIFILECORRUPT)
|
|
{
|
|
/* This semi-private TAPI API allows the "first location" wizard page
|
|
** to appear without the following "TAPI Dialing Properties" sheet.
|
|
*/
|
|
extern LOpenDialAsst(
|
|
IN HWND hwnd,
|
|
IN LPCTSTR lpszAddressIn,
|
|
IN BOOL fSimple,
|
|
IN BOOL fSilentInstall );
|
|
|
|
dwErr = LOpenDialAsst( hwndOwner, NULL, TRUE, TRUE );
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
DWORD APIENTRY
|
|
TapiRemoveLocation(
|
|
IN DWORD dwID )
|
|
|
|
/* Remove TAPI location 'dwID'.
|
|
**
|
|
** Returns 0 if successful, or an error code.
|
|
*/
|
|
{
|
|
TRACE("TapiRemoveLocation");
|
|
|
|
return internalRemoveLocation( dwID );
|
|
}
|
|
|
|
|
|
DWORD APIENTRY
|
|
TapiRenameLocation(
|
|
IN WCHAR* pszOldName,
|
|
IN WCHAR* pszNewName )
|
|
|
|
/* Renames TAPI location 'pszOldName' to 'pszNewName'.
|
|
**
|
|
** Returns 0 if successful, or an error code.
|
|
*/
|
|
{
|
|
TRACEW1("TapiRenameLocation(o=%s...",pszOldName);
|
|
TRACEW1("...n=%s)",pszNewName);
|
|
|
|
#ifdef UNICODE
|
|
|
|
return internalRenameLocationW( pszOldName, pszNewName );
|
|
|
|
#else
|
|
{
|
|
WCHAR* pszOldNameW;
|
|
WCHAR* pszNewNameW;
|
|
|
|
pszOldNameW = StrDupWFromA( pszOldName );
|
|
pszNewNameW = StrDupWFromA( pszNewName );
|
|
dwErr = internalNewLocation( pszOldNameW, pszNewNameW );
|
|
Free0( pszOldNameW );
|
|
Free0( pszNewNameW );
|
|
return dwErr;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
DWORD
|
|
TapiShutdown(
|
|
IN HLINEAPP hlineapp )
|
|
|
|
/* Terminate the TAPI session 'hlineapp', or do nothing if 'hlineapp' is
|
|
** NULL.
|
|
*/
|
|
{
|
|
#if 0
|
|
DWORD dwErr = 0;
|
|
|
|
TRACE1("TapiShutdown(h=$%x)",hlineapp);
|
|
|
|
if (hlineapp)
|
|
{
|
|
TRACE("lineShutdown");
|
|
dwErr = lineShutdown( hlineapp );
|
|
TRACE1("lineShutdown=$%X",dwErr);
|
|
}
|
|
|
|
return dwErr;
|
|
#else
|
|
/* See TapiInit.
|
|
*/
|
|
ASSERT(!hlineapp);
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
|
|
DWORD
|
|
TapiTranslateAddress(
|
|
IN HINSTANCE hInst,
|
|
IN OUT HLINEAPP* pHlineapp,
|
|
IN DWORD dwCountryCode,
|
|
IN TCHAR* pszAreaCode,
|
|
IN TCHAR* pszPhoneNumber,
|
|
IN DWORD dwDeviceId,
|
|
IN BOOL fDialable,
|
|
OUT TCHAR** ppszResult )
|
|
|
|
/* Returns '*pszResult', a heap string containing the TAPI location
|
|
** transformed dialable phone number built from the component phone number
|
|
** parts. '*PHlineapp' is the TAPI handle returned from a previous TAPI
|
|
** call or NULL if none. parts. 'dwDeviceId' is the device to which the
|
|
** number is to be applied or 0 for generic treatment. 'HInst' is the
|
|
** module instance handle. 'FDialable' indicates the dialable, as opposed
|
|
** to the displayable string should be returned.
|
|
**
|
|
** Returns 0 if successful, or an error code.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
TCHAR* pszCanon;
|
|
LINETRANSLATEOUTPUT output;
|
|
LINETRANSLATEOUTPUT* pOutput;
|
|
|
|
TRACE("TapiTranslateAddress");
|
|
|
|
pOutput = NULL;
|
|
pszCanon = NULL;
|
|
*ppszResult = NULL;
|
|
|
|
#if 0
|
|
dwErr = TapiInit( hInst, pHlineapp, NULL );
|
|
if (dwErr != 0)
|
|
return dwErr;
|
|
#endif
|
|
|
|
pszCanon = GetCanonPhoneNumber(
|
|
dwCountryCode, pszAreaCode, pszPhoneNumber );
|
|
|
|
ZeroMemory( &output, sizeof(output) );
|
|
output.dwTotalSize = sizeof(output);
|
|
|
|
TRACE("lineTranslateAddressW");
|
|
dwErr = lineTranslateAddressW(
|
|
*pHlineapp, dwDeviceId, TAPIVERSION, pszCanon, 0,
|
|
LINETRANSLATEOPTION_CANCELCALLWAITING, &output );
|
|
TRACE1("lineTranslateAddressW=$%X",dwErr);
|
|
if (dwErr != 0)
|
|
goto TapiTranslateAddress_Error;
|
|
|
|
pOutput = (LINETRANSLATEOUTPUT* )Malloc( output.dwNeededSize );
|
|
if (!pOutput)
|
|
{
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto TapiTranslateAddress_Error;
|
|
}
|
|
|
|
ZeroMemory( pOutput, output.dwNeededSize );
|
|
pOutput->dwTotalSize = output.dwNeededSize;
|
|
TRACE("lineTranslateAddressW");
|
|
dwErr = lineTranslateAddressW(
|
|
*pHlineapp, dwDeviceId, TAPIVERSION, pszCanon, 0,
|
|
LINETRANSLATEOPTION_CANCELCALLWAITING, pOutput );
|
|
TRACE1("lineTranslateAddressW=$%X",dwErr);
|
|
if (dwErr != 0)
|
|
goto TapiTranslateAddress_Error;
|
|
|
|
if (fDialable)
|
|
{
|
|
*ppszResult = StrDup(
|
|
(TCHAR* )(((BYTE* )pOutput) + pOutput->dwDialableStringOffset) );
|
|
}
|
|
else
|
|
{
|
|
*ppszResult = StrDup(
|
|
(TCHAR* )(((BYTE* )pOutput) + pOutput->dwDisplayableStringOffset) );
|
|
}
|
|
|
|
if (!*ppszResult)
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
TapiTranslateAddress_Error:
|
|
|
|
Free0( pszCanon );
|
|
Free0( pOutput );
|
|
return dwErr;
|
|
}
|