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

📄 tapiconn._cp

📁 串口调试助手的源代码
💻 _CP
📖 第 1 页 / 共 5 页
字号:
//
LPLINEDEVCAPS	CTapiConnection::GetDeviceLine(DWORD*  pdwAPIVersion, LPLINEDEVCAPS  lpLineDevCaps)
{
	LPCTSTR	szLineUnavail = _T("Line Unavailable");
	LPCTSTR	szLineUnnamed = _T("Line Unnamed");
	LPCTSTR	szLineNameEmpty = _T("Line Name is Empty");
	LPCTSTR	lpszLineName;

	LINEEXTENSIONID	lineExtID;
	long	lReturn;

	BOOL bDone = FALSE;
	for (DWORD  dwDeviceID = 0; (dwDeviceID < m_dwNumDevs) && !bDone; ++ dwDeviceID)
	{
		*pdwAPIVersion = I_lineNegotiateLegacyAPIVersion(dwDeviceID);
		if (*pdwAPIVersion)
		{
			lpLineDevCaps = I_lineGetDevCaps(lpLineDevCaps, dwDeviceID, *pdwAPIVersion);

			if ((lpLineDevCaps->dwLineNameSize) &&
				(lpLineDevCaps->dwLineNameOffset) &&
				(lpLineDevCaps->dwStringFormat == STRINGFORMAT_ASCII))
			{
				// This is the name of the device.
				lpszLineName = ((char*)lpLineDevCaps) + 
					lpLineDevCaps->dwLineNameOffset;
				TRACE1("Name of device is: %s\n", lpszLineName);
			}
			else  // DevCaps doesn't have a valid line name. Unnamed.
				lpszLineName = szLineUnnamed;
		}
		else  // Couldn't NegotiateAPIVersion. Line is unavail.
			lpszLineName = szLineUnavail;

		// If this line is usable and we don't have a default initial
		// line yet, make this the initial line.
		if ((lpszLineName != szLineUnavail) && (lReturn == TAPISUCCESS)) 
		{          
			m_dwDeviceID = dwDeviceID;
			bDone = TRUE;
		}
		else 
			m_dwDeviceID = MAXDWORD;
	}
	return  lpLineDevCaps;
}

//
//  FUNCTION: I_lineGetDevCaps(LPLINEDEVCAPS, DWORD , DWORD)
//
//  PURPOSE: Gets a LINEDEVCAPS structure for the specified line.
//
//  COMMENTS:
//
//    This function is a wrapper around lineGetDevCaps 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 lpLineDevCaps structure is passed in, it *must*
//    have been allocated with LocalAlloc and it could potentially be 
//    LocalFree()d.
//
//    If lpLineDevCaps == NULL, then a new structure is allocated.  It is
//    normal to pass in NULL for this parameter unless you want to use a 
//    I_lineGetDevCaps that has been returned by a previous MylineGetDevCaps
//    call.
//
//
LPLINEDEVCAPS CTapiConnection::I_lineGetDevCaps(
	LPLINEDEVCAPS  lpLineDevCaps,
	DWORD  dwDeviceID, DWORD  dwAPIVersion)
{
	// Allocate enough space for the structure plus 1024.
	size_t	sizeofLineDevCaps = sizeof(LINEDEVCAPS) + 1024;
	long	lReturn;
    
	// Continue this loop until the structure is big enough.
	while (TRUE)
	{
		// Make sure the buffer exists, is valid and big enough.
		lpLineDevCaps = 
			(LPLINEDEVCAPS)CheckAndReAllocBuffer(
				(LPVOID)lpLineDevCaps, // Pointer to existing buffer, if any
				sizeofLineDevCaps);      // Minimum size the buffer should be

		if (lpLineDevCaps == NULL)
			return  NULL;

		// Make the call to fill the structure.
		do
		{            
			lReturn = 
				::lineGetDevCaps(m_hLineApp, 
					dwDeviceID, dwAPIVersion, 0, lpLineDevCaps);

			if (HandleLineErr(lReturn))
				continue;
			else
			{
				TRACE0("lineGetDevCaps unhandled error/n");
				::LocalFree(lpLineDevCaps);
				return  NULL;
			}
		}
		while (lReturn != TAPISUCCESS);

		// If the buffer was big enough, then succeed.
		if ((lpLineDevCaps->dwNeededSize) <= (lpLineDevCaps->dwTotalSize))
			return  lpLineDevCaps;

		// Buffer wasn't big enough.  Make it bigger and try again.
		sizeofLineDevCaps = lpLineDevCaps->dwNeededSize;
	}
}

//
//  FUNCTION: LPVOID CheckAndReAllocBuffer(LPVOID, size_t, LPCSTR)
//
//  PURPOSE: Checks and ReAllocates a buffer if necessary.
//
LPVOID CTapiConnection::CheckAndReAllocBuffer(LPVOID  lpBuffer, size_t  sizeBufferMinimum)
{
	size_t	sizeBuffer;

	if (lpBuffer == NULL)	// Allocate the buffer if necessary.
	{
		sizeBuffer = sizeBufferMinimum;
		lpBuffer = (LPVOID)::LocalAlloc(LPTR, sizeBuffer);
            
		if (lpBuffer == NULL)
		{
			TRACE0("LocalAlloc failed in CheckAndReAllocBuffer./n");
			return  NULL;
		}
	}
	else	// If the structure already exists, make sure its good.
	{
		sizeBuffer = ::LocalSize((HLOCAL)lpBuffer);

		if (sizeBuffer == 0)	// Bad pointer?
		{
			TRACE0("LocalSize returned 0 in CheckAndReAllocBuffer/n");
			return  NULL;
		}

		// Was the buffer big enough for the structure?
		if (sizeBuffer < sizeBufferMinimum)
		{
			TRACE0("Reallocating structure\n");
			::LocalFree(lpBuffer);
			return  CheckAndReAllocBuffer(NULL, sizeBufferMinimum);
		}
	}
                
	((LPVARSTRING)lpBuffer)->dwTotalSize = (DWORD)sizeBuffer;
	return  lpBuffer;
}

//
//  FUNCTION: I_lineGetAddressCaps(LPLINEADDRESSCAPS, ..)
//
//  PURPOSE: Retrieve a LINEADDRESSCAPS structure for the specified line.
//
//  PARAMETERS:
//    lpLineAddressCaps - Pointer to a LINEADDRESSCAPS, or NULL.
//    dwDeviceID        - Device to get the address caps for.
//    dwAddressID       - This sample always assumes the first address.
//    dwAPIVersion      - API version negotiated for the device.
//    dwExtVersion      - Always 0 for this sample.
//
//  RETURN VALUE:
//    Returns a pointer to a LINEADDRESSCAPS structure if successful.
//    Returns NULL if unsuccessful.
//
//  COMMENTS:
//
//    This function is a wrapper around lineGetAddressCaps 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 lpLineAddressCaps structure is passed in, it *must*
//    have been allocated with LocalAlloc and it could potentially be 
//    LocalFree()d.  It also *must* have the dwTotalSize field set.
//
//    If lpLineAddressCaps == NULL, then a new structure is allocated.  It
//    is normal to pass in NULL for this parameter unless you want to use a
//    lpLineCallStatus that has been returned by previous I_lineGetAddressCaps
//    call.
//
//
LPLINEADDRESSCAPS	CTapiConnection::I_lineGetAddressCaps(
    LPLINEADDRESSCAPS  lpLineAddressCaps,
    DWORD  dwDeviceID, DWORD  dwAddressID,
    DWORD  dwAPIVersion, DWORD  dwExtVersion)
{
	size_t	sizeofLineAddressCaps = sizeof(LINEADDRESSCAPS) + 1024;
	long	lReturn;
    
	// Continue this loop until the structure is big enough.
	while (TRUE)
	{
		// Make sure the buffer exists, is valid and big enough.
		lpLineAddressCaps = 
			(LPLINEADDRESSCAPS)CheckAndReAllocBuffer(
				(LPVOID)lpLineAddressCaps,
				sizeofLineAddressCaps);

		if (lpLineAddressCaps == NULL)
			return  NULL;
            
		// Make the call to fill the structure.
		do
		{
			lReturn = 
				::lineGetAddressCaps(m_hLineApp,
					dwDeviceID, dwAddressID, dwAPIVersion, dwExtVersion,
					lpLineAddressCaps);

			if (HandleLineErr(lReturn))
				continue;
			else
			{
				TRACE0("lineGetAddressCaps unhandled error\n");
				::LocalFree(lpLineAddressCaps);
				return  NULL;
			}
		}
		while (lReturn != TAPISUCCESS);

		// If the buffer was big enough, then succeed.
		if ((lpLineAddressCaps->dwNeededSize) <= 
			(lpLineAddressCaps->dwTotalSize))
		{
			return  lpLineAddressCaps;
		}

		// Buffer wasn't big enough.  Make it bigger and try again.
		sizeofLineAddressCaps = lpLineAddressCaps->dwNeededSize;
	}
}
/*
//
//  FUNCTION: MakeTheCall(LPLINEDEVCAPS, LPCSTR)
//
//  PURPOSE: Dials the call
//
BOOL	CTapiConnection::MakeTheCall(LPLINEDEVCAPS  lpLineDevCaps, LPCTSTR  lpszAddress)
{
	LPLINECALLPARAMS	lpCallParams = NULL;
	LPLINEADDRESSCAPS	lpAddressCaps = NULL;
	long	lReturn;
	BOOL	bFirstDial = TRUE;
                               
	// Get the capabilities for the line device we're going to use.
	lpAddressCaps = I_lineGetAddressCaps(lpAddressCaps,
		m_dwDeviceID, 0, m_dwAPIVersion, 0);
	if (lpAddressCaps == NULL)
		return  FALSE;

	// Setup our CallParams.
	lpCallParams = CreateCallParams (lpCallParams, lpszAddress);
	if (lpCallParams == NULL)
		return  FALSE;

	do
	{                   
		if (bFirstDial)
			lReturn = WaitForReply(::lineMakeCall(m_hLine, &m_hCall, lpszAddress,
				0, lpCallParams));
		else
			lReturn = WaitForReply(::lineDial(m_hCall, lpszAddress, 0));

		if (lReturn == WAITERR_WAITABORTED)
		{
			TRACE0("While Dialing, WaitForReply aborted.\n");
			goto  LABEL_ERREXIT;
		}
            
		if (HandleLineErr(lReturn))
			continue;
		else
		{
			if (bFirstDial)
				TRACE0("lineMakeCall unhandled error\n");
			else
				TRACE0("lineDial unhandled error\n");

			goto  LABEL_ERREXIT;
		}
	}
	while (lReturn != TAPISUCCESS);
        
	bFirstDial = FALSE;

	if (lpCallParams)
		::LocalFree(lpCallParams);
	if (lpAddressCaps)
		::LocalFree(lpAddressCaps);
    
	return  TRUE;
    
LABEL_ERREXIT:
	if (lpCallParams)
		::LocalFree(lpCallParams);
	if (lpAddressCaps)
		::LocalFree(lpAddressCaps);

	::AfxMessageBox("Dial failed.");
	return  FALSE;
}   
*/

//
//  FUNCTION: CreateCallParams(LPLINECALLPARAMS, LPCSTR)
//
//  PURPOSE: Allocates and fills a LINECALLPARAMS structure
//
//
LPLINECALLPARAMS	CTapiConnection::CreateCallParams(
	LPLINECALLPARAMS  lpCallParams, LPCSTR  lpszDisplayableAddress)
{
	size_t	sizeDisplayableAddress;

	if (lpszDisplayableAddress == NULL)
		lpszDisplayableAddress = _T("");
        
	sizeDisplayableAddress = strlen(lpszDisplayableAddress) + 1;
                          
	lpCallParams = (LPLINECALLPARAMS)CheckAndReAllocBuffer(
		(LPVOID)lpCallParams, 
		sizeof(LINECALLPARAMS) + sizeDisplayableAddress);
//        "CreateCallParams: ");

	if (lpCallParams == NULL)
		return  NULL;

	// set everything to 0
//	memset(lpCallParams, 0, sizeof(lpCallParams));
    
	// This is where we configure the line for DATAMODEM usage.
	lpCallParams->dwBearerMode = LINEBEARERMODE_VOICE;
	lpCallParams->dwMediaMode = LINEMEDIAMODE_DATAMODEM;//LINEMEDIAMODE_INTERACTIVEVOICE;

	// This specifies that we want to use only IDLE calls and
	// don't want to cut into a call that might not be IDLE (ie, in use).
	lpCallParams->dwCallParamFlags = LINECALLPARAMFLAGS_IDLE;
                                    
	// if there are multiple addresses on line, use first anyway.
	// It will take a more complex application than a simple tty app
	// to use multiple addresses on a line anyway.
	lpCallParams->dwAddressMode = LINEADDRESSMODE_ADDRESSID;
	lpCallParams->dwAddressID = 0;

	// Since we don't know where we originated, leave these blank.
	lpCallParams->dwOrigAddressSize = 0;
	lpCallParams->dwOrigAddressOffset = 0;
    
	// Unimodem ignores these values.
	(lpCallParams->DialParams).dwDialSpeed = 0;
	(lpCallParams->DialParams).dwDigitDuration = 0;
	(lpCallParams->DialParams).dwDialPause = 0;
	(lpCallParams->DialParams).dwWaitForDialtone = 0;
    
	// Address we are dialing.
	lpCallParams->dwDisplayableAddressOffset = sizeof(LINECALLPARAMS);
	lpCallParams->dwDisplayableAddressSize = sizeDisplayableAddress;
	strcpy((LPSTR)lpCallParams + sizeof(LINECALLPARAMS),
		lpszDisplayableAddress);

	return  lpCallParams;
}

//
//  FUNCTION: long WaitForReply(long)
//
//  PURPOSE: Resynchronize by waiting for a LINE_REPLY 
//
//  PARAMETERS:
//    lRequestID - The asynchronous request ID that we're
//                 on a LINE_REPLY for.
//
//  RETURN VALUE:
//    - 0 if LINE_REPLY responded with a success.
//    - LINEERR constant if LINE_REPLY responded with a LINEERR
//    - 1 if the line was shut down before LINE_REPLY is received.
//
//  COMMENTS:
//
//    This function allows us to resynchronize an asynchronous
//    TAPI line call by waiting for the LINE_REPLY message.  It
//    waits until a LINE_REPLY is received or the line is shut down.
//
//    Note that this could cause re-entrancy problems as
//    well as mess with any message preprocessing that might
//    occur on this thread (such as TranslateAccelerator).
//
//    This function should to be called from the thread that did
//    lineInitialize, or the PeekMessage is on the wrong thread
//    and the synchronization is not guaranteed to work.  Also note
//    that if another PeekMessage loop is entered while waiting,
//    this could also cause synchronization problems.
//
//    One more note.  This function can potentially be re-entered
//    if the call is dropped for any reason while waiting.  If this
//    happens, just drop out and assume the wait has been canceled.  
//    This is signaled by setting bReentered to FALSE when the function 
//    is entered and TRUE when it is left.  If bReentered is ever TRUE 
//    during the function, then the function was re-entered.
//
//    This function times out and returns WAITERR_WAITTIMEDOUT
//    after WAITTIMEOUT milliseconds have elapsed.
//
//
long	CTapiConnection::WaitForReply(long  lRequestID)
{
	static BOOL	bReentered;
	bReentered = FALSE;

	if (lRequestID > TAPISUCCESS)
	{
		MSG	msg; 
		DWORD	dwTimeStarted;

		m_bReplyRecieved = FALSE;
		m_dwRequestedID = (DWORD)lRequestID;

		// Initializing this just in case there is a bug
		// that sets m_bReplyRecieved without setting the reply value.
		m_lAsyncReply = LINEERR_OPERATIONFAILED;

		dwTimeStarted = GetTickCount();

		while (!m_bReplyRecieved)
		{
			if (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
			{
				::TranslateMessage(&msg);
				::DispatchMessage(&msg);
			}

			// This should only occur if the line is shut down while waiting.
			if ((m_hCall != NULL) &&(!m_bTapiInUse || bReentered))
			{
				bReentered = TRUE;
				return  WAITERR_WAITABORTED;
			}

			// Its a really bad idea to timeout a wait for a LINE_REPLY.
			// If we are execting a LINE_REPLY, we should wait till we get
			// it; it might take a long time to dial (for example).

			// If 5 seconds go by without a reply, it might be a good idea
			// to display a dialog box to tell the user that a
			// wait is in progress and to give the user the capability to
			// abort the wait.
		}

		bReentered = TRUE;
		return  m_lAsyncReply;
	}

	bReentered = TRUE;
	return  lRequestID;
}

//
//  FUNCTION: lineCallbackFunc(..)
//
//  PURPOSE: Receive asynchronous TAPI events
//
void CALLBACK	CTapiConnection::lineCallbackFunc(
	DWORD  dwDevice, DWORD  dwMsg, DWORD  dwCallbackInstance,
	DWORD  dwParam1, DWORD  dwParam2, DWORD  dwParam3)
{
	OutputDebugLineCallback(dwDevice, dwMsg, dwCallbackInstance,
		dwParam1, dwParam2, dwParam3);

⌨️ 快捷键说明

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