📄 dialdlg._cp
字号:
case LINENOTUSEABLE_NODATAMODEM:
MessageBox("The selected line doesn't support DATAMODEM capabilities",
"Warning",MB_OK);
break;
case LINENOTUSEABLE_NOMAKECALL:
MessageBox("The selected line doesn't support MAKECALL capabilities",
"Warning",MB_OK);
break;
case LINENOTUSEABLE_ALLOCATED:
MessageBox("The selected line is already in use by a non-TAPI application",
"Warning",MB_OK);
break;
case LINENOTUSEABLE_INUSE:
MessageBox("The selected line is already in use by a TAPI application",
"Warning",MB_OK);
break;
case LINENOTUSEABLE_NOCOMMDATAMODEM:
MessageBox("The selected line doesn't support the COMM/DATAMODEM device class",
"Warning",MB_OK);
break;
}
// m_pConn->m_dwDeviceID == MAXDWORD mean the selected device isn't usable.
m_pConn->m_dwDeviceID = MAXDWORD;
return FALSE;
}
//
// FUNCTION: void PreConfigureDevice(DWORD)
//
// PURPOSE:
//
// PARAMETERS:
// dwDeviceID - line device to be configured
//
// RETURN VALUE:
// none
//
// COMMENTS:
//
// At one point, PreConfigureDevice used lineConfigDialog to
// configure the device. This has the unfortunate effect of configuring
// the device immediately, even if it is in use by another TAPI app.
// This can be really bad if data communications are already in
// progress (like with RAS).
//
// Now, PreConfigureDevice uses lineConfigDialogEdit to give the
// user the configuration UI, but it doesn't actually do anything to
// the line device. TapiComm stores the configuration information so
// that it can be set later, just before making the call.
//
//
void CDialDlg::PreConfigureDevice(DWORD dwDeviceID)
{
long lReturn;
LPVARSTRING lpVarString = NULL;
DWORD dwSizeofVarString = sizeof(VARSTRING);
// If there isn't already any device configuration information,
// then we need to get some.
if (m_lpDeviceConfig == NULL)
{
do
{
lpVarString = (LPVARSTRING)CTapiConnection::CheckAndReAllocBuffer(
(LPVOID) lpVarString, dwSizeofVarString);//,
// "PreConfigureDevice - lineGetDevConfig: ");
if (lpVarString == NULL)
return;
lReturn = lineGetDevConfig(dwDeviceID, lpVarString,
"comm/datamodem");
if (m_pConn->HandleLineErr(lReturn))
;
else
{
OutputDebugLineError(lReturn,
"lineGetDevCaps unhandled error: ");
LocalFree(lpVarString);
return;
}
if ((lpVarString->dwNeededSize) > (lpVarString->dwTotalSize))
{
dwSizeofVarString = lpVarString -> dwNeededSize;
lReturn = -1; // Lets loop again.
}
}
while (lReturn != TAPISUCCESS);
m_pConn->m_dwSizeDeviceConfig = lpVarString->dwStringSize;
// The extra byte allocated is in case dwStringSize is 0.
m_lpDeviceConfig = CTapiConnection::CheckAndReAllocBuffer(
m_lpDeviceConfig, m_pConn->m_dwSizeDeviceConfig+1);//,
// "PreConfigureDevice - Allocate device config: ");
if (!m_lpDeviceConfig)
{
LocalFree(lpVarString);
return;
}
memcpy(m_lpDeviceConfig,
((LPBYTE) lpVarString + lpVarString -> dwStringOffset),
m_pConn->m_dwSizeDeviceConfig);
}
// Next make the lineConfigDialogEdit call.
// Note that we determine the initial size of the VARSTRING
// structure based on the known size of the existing configuration
// information. I make the assumption that this configuration
// information is very unlikely to grow by more than 5K or by
// more than 5 times. This is a *very* conservative number.
// We do *not* want lineConfigDialogEdit to fail just because there
// wasn't enough room to stored the data. This would require the user
// to go through configuration again and that would be annoying.
dwSizeofVarString = 5 * m_pConn->m_dwSizeDeviceConfig + 5000;
do
{
lpVarString = (LPVARSTRING)CTapiConnection::CheckAndReAllocBuffer(
(LPVOID) lpVarString, dwSizeofVarString);//,
// "PreConfigureDevice - lineConfigDialogEdit: ");
if (lpVarString == NULL)
return;
lReturn = ::lineConfigDialogEdit(dwDeviceID, GetSafeHwnd(), "comm/datamodem",
m_lpDeviceConfig, m_pConn->m_dwSizeDeviceConfig, lpVarString);
if (m_pConn->HandleLineErr(lReturn))
;
else
{
OutputDebugLineError(lReturn,
"lineConfigDialogEdit unhandled error: ");
LocalFree(lpVarString);
return;
}
if ((lpVarString->dwNeededSize) > (lpVarString->dwTotalSize))
{
// We had been conservative about making sure the structure was
// big enough. Unfortunately, not conservative enough. Hopefully,
// this will not happen a second time because we are *DOUBLING*
// the NeededSize.
MessageBox(
"Internal Error: Unable to set line configuration.\n"
"Please try again.",
"Oops", MB_OK);
dwSizeofVarString = (lpVarString->dwNeededSize) * 2;
lReturn = -1; // Lets loop again.
}
}
while (lReturn != TAPISUCCESS);
// Store the configuration information into a global structure
// so it can be set at a later time.
m_pConn->m_dwSizeDeviceConfig = lpVarString->dwStringSize;
m_lpDeviceConfig = CTapiConnection::CheckAndReAllocBuffer(
m_lpDeviceConfig, m_pConn->m_dwSizeDeviceConfig+1);//,
// "PreConfigureDevice - Reallocate device config: ");
if (!m_lpDeviceConfig)
{
LocalFree(lpVarString);
return;
}
memcpy(m_lpDeviceConfig,
((LPBYTE)lpVarString + lpVarString->dwStringOffset),
m_pConn->m_dwSizeDeviceConfig);
::LocalFree(lpVarString);
}
//
// FUNCTION: long VerifyUsableLine(DWORD)
//
// PURPOSE: Verifies that a specific line device is useable by TapiComm.
//
// PARAMETERS:
// dwDeviceID - The ID of the line device to be verified
//
// RETURN VALUE:
// Returns TAPISUCCESS if dwDeviceID is a usable line device.
// Returns a LINENOTUSEABLE_ constant otherwise.
//
// COMMENTS:
//
// VerifyUsableLine takes the give device ID and verifies step by step
// that the device supports all the features that TapiComm requires.
//
//
long CDialDlg::VerifyUsableLine(DWORD dwDeviceID)
{
LPLINEADDRESSSTATUS lpLineAddressStatus = NULL;
LPVARSTRING lpVarString = NULL;
long lReturn;
long lUsableLine = TAPISUCCESS;
HLINE hLine = 0;
TRACE1("Testing Line ID '0x%lx'", dwDeviceID);
// The line device must support an API Version that TapiComm does.
DWORD dwAPIVersion = m_pConn->I_lineNegotiateAPIVersion(dwDeviceID);
if (dwAPIVersion == 0)
return LINENOTUSEABLE_ERROR;
LPLINEDEVCAPS lpLineDevCaps = NULL;
lpLineDevCaps = m_pConn->I_lineGetDevCaps(lpLineDevCaps,
dwDeviceID, dwAPIVersion);
if (lpLineDevCaps == NULL)
return LINENOTUSEABLE_ERROR;
// Must support LINEBEARERMODE_VOICE
if (!(lpLineDevCaps->dwBearerModes & LINEBEARERMODE_VOICE ))
{
lUsableLine = LINENOTUSEABLE_NOVOICE;
TRACE0("LINEBEARERMODE_VOICE not supported\n");
goto LABEL_DELETEBUFFERS;
}
// Must support LINEMEDIAMODE_DATAMODEM
if (!(lpLineDevCaps->dwMediaModes & LINEMEDIAMODE_DATAMODEM))
{
lUsableLine = LINENOTUSEABLE_NODATAMODEM;
TRACE0("LINEMEDIAMODE_DATAMODEM not supported\n");
goto LABEL_DELETEBUFFERS;
}
// Must be able to make calls
if (!(lpLineDevCaps->dwLineFeatures & LINEFEATURE_MAKECALL))
{
lUsableLine = LINENOTUSEABLE_NOMAKECALL;
TRACE0("LINEFEATURE_MAKECALL not supported\n");
goto LABEL_DELETEBUFFERS;
}
// It is necessary to open the line so we can check if
// there are any call appearances available. Other TAPI
// applications could be using all call appearances.
// Opening the line also checks for other possible problems.
do
{
lReturn = ::lineOpen(m_pConn->m_hLineApp, dwDeviceID, &hLine,
dwAPIVersion, 0, 0,
/*LINECALLPRIVILEGE_NONE*/LINECALLPRIVILEGE_OWNER, LINEMEDIAMODE_DATAMODEM,
0);
if (lReturn == LINEERR_ALLOCATED)
{
TRACE0("Line is already in use by a non-TAPI app or"
" another Service Provider.\n");
lUsableLine = LINENOTUSEABLE_ALLOCATED;
goto LABEL_DELETEBUFFERS;
}
if (m_pConn->HandleLineErr(lReturn))
continue;
else
{
OutputDebugLineError(lReturn, "lineOpen unhandled error: ");
lUsableLine = LINENOTUSEABLE_ERROR;
goto LABEL_DELETEBUFFERS;
}
}
while (lReturn != TAPISUCCESS);
// Get LineAddressStatus to make sure the line isn't already in use.
lpLineAddressStatus =
m_pConn->I_lineGetAddressStatus(lpLineAddressStatus, hLine, 0);
if (lpLineAddressStatus == NULL)
{
lUsableLine = LINENOTUSEABLE_ERROR;
goto LABEL_DELETEBUFFERS;
}
// Are there any available call appearances (ie: is it in use)?
if (!((lpLineAddressStatus->dwAddressFeatures) & LINEADDRFEATURE_MAKECALL))
{
TRACE0("LINEADDRFEATURE_MAKECALL not available\n");
lUsableLine = LINENOTUSEABLE_INUSE;
goto LABEL_DELETEBUFFERS;
}
// Make sure the "comm/datamodem" device class is supported
// Note that we don't want any of the 'extra' information
// normally returned in the VARSTRING structure. All we care
// about is if lineGetID succeeds.
do
{
lpVarString = (LPVARSTRING)CTapiConnection::CheckAndReAllocBuffer((LPVOID) lpVarString,
sizeof(VARSTRING));//,"VerifyUsableLine:lineGetID: ");
if (lpVarString == NULL)
{
lUsableLine = LINENOTUSEABLE_ERROR;
goto LABEL_DELETEBUFFERS;
}
lReturn = ::lineGetID(hLine, 0, 0, LINECALLSELECT_LINE,
lpVarString, "comm/datamodem");
if (m_pConn->HandleLineErr(lReturn))
continue;
else
{
OutputDebugLineError(lReturn,
"lineGetID unhandled error: ");
lUsableLine = LINENOTUSEABLE_NOCOMMDATAMODEM;
goto LABEL_DELETEBUFFERS;
}
}
while (lReturn != TAPISUCCESS);
TRACE0("Line is suitable and available for use.\n");
LABEL_DELETEBUFFERS:
if (hLine)
::lineClose(hLine);
if (lpLineAddressStatus)
::LocalFree(lpLineAddressStatus);
if (lpLineDevCaps)
::LocalFree(lpLineDevCaps);
if (lpVarString)
::LocalFree(lpVarString);
return lUsableLine;
}
//
// FUNCTION: I_lineTranslateAddress
// (LPLINETRANSLATEOUTPUT, DWORD, DWORD, LPCSTR)
//
// PURPOSE: Retrieve a LINECALLSTATUS structure for the specified line.
//
// PARAMETERS:
// lpLineTranslateOutput - Pointer to a LINETRANSLATEOUTPUT structure.
// dwDeviceID - Device that we're translating for.
// dwAPIVersion - API Version to use.
// lpszDialAddress - pointer to the DialAddress string to translate.
//
// RETURN VALUE:
// Returns a pointer to a LINETRANSLATEOUTPUT structure if successful.
// Returns NULL if unsuccessful.
//
// COMMENTS:
//
// This function is a wrapper around lineGetTranslateOutput to make it
// easy to handle the variable sized structure and any errors received.
//
// The returned structure has been allocated with LocalAlloc,
// so LocalFree has to be called on it when you're finished with it,
// or there will be a memory leak.
//
// Similarly, if a lpLineTranslateOutput structure is passed in, it
// *must* have been allocated with LocalAlloc and it could potentially be
// LocalFree()d.
//
// If lpLineTranslateOutput == NULL, then a new structure is allocated.
// It is normal to pass in NULL for this parameter unless you want to use
// a lpLineTranslateOutput that has been returned by previous
// I_lineTranslateOutput call.
//
//
LPLINETRANSLATEOUTPUT CDialDlg::I_lineTranslateAddress(
LPLINETRANSLATEOUTPUT lpLineTranslateOutput,
DWORD dwDeviceID, DWORD dwAPIVersion,
LPCSTR lpszDialAddress)
{
size_t sizeofLineTranslateOutput = sizeof(LINETRANSLATEOUTPUT) + 1024;
long lReturn;
// Continue this loop until the structure is big enough.
while(TRUE)
{
// Make sure the buffer exists, is valid and big enough.
lpLineTranslateOutput =
(LPLINETRANSLATEOUTPUT)m_pConn->CheckAndReAllocBuffer(
(LPVOID)lpLineTranslateOutput,
sizeofLineTranslateOutput);//,
// "lineTranslateOutput");
if (lpLineTranslateOutput == NULL)
return NULL;
// Make the call to fill the structure.
do
{
// Note that CALLWAITING is disabled
// (assuming the service provider can disable it)
lReturn =
lineTranslateAddress(m_pConn->m_hLineApp, dwDeviceID, dwAPIVersion,
lpszDialAddress, 0,
LINETRANSLATEOPTION_CANCELCALLWAITING,
lpLineTranslateOutput);
// If the address isn't translatable, notify the user.
if (lReturn == LINEERR_INVALADDRESS)
MessageBox("Unable to translate phone number", "Warning", MB_OK);
if (m_pConn->HandleLineErr(lReturn))
continue;
else
{
OutputDebugLineError(lReturn,
"lineTranslateOutput unhandled error: ");
::LocalFree(lpLineTranslateOutput);
return NULL;
}
}
while (lReturn != TAPISUCCESS);
// If the buffer was big enough, then succeed.
if ((lpLineTranslateOutput->dwNeededSize) <=
(lpLineTranslateOutput->dwTotalSize))
{
return lpLineTranslateOutput;
}
// Buffer wasn't big enough. Make it bigger and try again.
sizeofLineTranslateOutput = lpLineTranslateOutput->dwNeededSize;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -