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

📄 tapifun.c

📁 See Hanoi.cpp for the implementation of this cla
💻 C
字号:
/* Copyright (c) 1999-2000 Microsoft Corporation.  All rights reserved. */
#include "windows.h"
#include "ndis.h"
#include "ndiswan.h"
#include "tapi.h"
#include "ndistapi.h"
#include "asyncmac.h"
#include "windev.h"		// For IsAPIReady()

#define DEV_CLASS_COMM_DATAMODEM TEXT("comm/datamodem")

// ----------------------------------------------------------------
//
//
//	@func	DWORD	|	TapiLineGetID |
//			Get the handle to the underlying serial port.
//
//	@rdesc	Returns the port handle or INVALID_HANDLE_VALUE.
//
//	@parm	HCALL	|	hCall	| The handle to the call
//
//	@comm
//			This function will get the handle to the underlying port of
//			a TAPI call.  This can be used by ReadFile/WriteFile etc.
//
//	@ex		An example of how to use this function follows |
//			No Example
//
//
HANDLE
TapiLineGetID(HLINE hLine, HCALL hCall)
{
	LPVARSTRING	pVStr;
	long 		lReturn;
	DWORD		dwNeededSize;
	DWORD		dwPortID = (DWORD)INVALID_HANDLE_VALUE;

	DEBUGMSG (ZONE_FUNCTION,
			  (TEXT("+TapilineGetID(0x%X, 0x%X)\r\n"), hLine, hCall));

	dwNeededSize = sizeof(VARSTRING);
	while (1) {
		pVStr = (LPVARSTRING)LocalAlloc (LPTR, dwNeededSize);
		if (NULL == pVStr) {
			break;
		}
		pVStr->dwTotalSize = dwNeededSize;
		lReturn = lineGetID(hLine, 0, hCall, LINECALLSELECT_CALL,
							pVStr, DEV_CLASS_COMM_DATAMODEM);

		if (lReturn) {
			DEBUGMSG (ZONE_ERROR,
					 (TEXT(" lineGetID returned 0x%X\r\n"),
					  lReturn));
			LocalFree (pVStr);
			pVStr = NULL;
			break;
		}

		if (pVStr->dwNeededSize > pVStr->dwTotalSize) {
			dwNeededSize = pVStr->dwNeededSize;
			LocalFree (pVStr);
			pVStr = NULL;
			continue;
		}
		break;
	}

	if (pVStr) {
		dwPortID = *((LPDWORD)((LPBYTE)pVStr + pVStr->dwStringOffset));
		DEBUGMSG (ZONE_FUNCTION,
				  (TEXT(" TapilineGetID ID=0x%X\r\n"), dwPortID));
		LocalFree (pVStr);
	}
	DEBUGMSG (ZONE_FUNCTION,
			  (TEXT("-TapilineGetID Returning 0x%X\r\n"), dwPortID));
	return (HANDLE)dwPortID;
}

void
SendLineDown(
	PASYNCMAC_OPEN_LINE pOpenLine)
{
	NDIS_MAC_LINE_DOWN	MacLineDown;
	PASYNCMAC_ADAPTER	pAdapter;

	ASSERT (CHK_AOL(pOpenLine));
	pAdapter = pOpenLine->pAdapter;
	ASSERT (CHK_AA(pAdapter));

	if (!(pOpenLine->dwFlags & AOL_FLAGS_SENT_LINE_UP))
	{
		RETAILMSG (1, (TEXT("SendLineDown: Can't send line down if we never sent a line up\n")));
	}
	else
	{
		memset ((char *)&MacLineDown, 0, sizeof(MacLineDown));
		MacLineDown.NdisLinkContext = pOpenLine->hNdisLinkContext;

		NdisMIndicateStatus (pAdapter->hMiniportAdapter,
							 NDIS_STATUS_WAN_LINE_DOWN,
							 &MacLineDown, sizeof(MacLineDown));
		
		// Turn off the flag
		pOpenLine->dwFlags &= ~(AOL_FLAGS_SENT_LINE_UP);
	}	
}


// -----------------------------------------------------------------------------
//
//  FUNCTION: lineCallbackFunc(..)
//
//  PURPOSE: Receive asynchronous TAPI events
//
//  PARAMETERS:
//    dwDevice  - Device associated with the event, if any
//    dwMsg     - TAPI event that occurred.
//    dwCallbackInstance - User defined data supplied when opening the line.
//    dwParam1  - dwMsg specific information
//    dwParam2  - dwMsg specific information
//    dwParam3  - dwMsg specific information
//
//  RETURN VALUE:
//    none
//
//  COMMENTS:
//    This is the function where all asynchronous events will come.
//    Almost all events will be specific to an open line, but a few
//    will be general TAPI events (such as LINE_REINIT).
//
//
// -----------------------------------------------------------------------------
void CALLBACK
lineCallbackFunc(DWORD dwDevice, DWORD dwMsg, DWORD dwCallbackInstance,
                 DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
	PASYNCMAC_OPEN_LINE	pOpenLine = (PASYNCMAC_OPEN_LINE)dwCallbackInstance;
	PASYNCMAC_ADAPTER	pAdapter;
	NDIS_TAPI_EVENT		TapiEvent;
	NDIS_MAC_LINE_UP	MacLineUp;
	DWORD				dwID;

    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("+lineCallbackFunc(0x%X, %d, %d, 0x%X, 0x%X, 0x%X)\r\n"),
               dwDevice, dwMsg, dwCallbackInstance,
               dwParam1, dwParam2, dwParam3));

	TapiEvent.htLine = 0;
	TapiEvent.htCall = 0;
	TapiEvent.ulMsg = dwMsg;
	TapiEvent.ulParam1 = dwParam1;
	TapiEvent.ulParam2 = dwParam2;
	TapiEvent.ulParam3 = dwParam3;

	if (dwMsg == LINE_CREATE)
	{
		extern PASYNCMAC_ADAPTER	v_pAdapter;

		// A new TAPI device like a PCMCIA card modem has been created.
		// Note that TAPI devices never go away, so their is no LINE_DESTROY message.
		DEBUGMSG (ZONE_FUNCTION, (TEXT(" lineCallbackFunc: LINE_CREATE\n")));

		if (v_pAdapter != NULL)
		{
			// Inform the protocol that the count of devices has changed.

			NdisMIndicateStatus (v_pAdapter->hMiniportAdapter,
								 NDIS_STATUS_TAPI_INDICATION,
								 &TapiEvent, sizeof(NDIS_TAPI_EVENT));
		}
		DEBUGMSG (ZONE_FUNCTION, (TEXT("-lineCallbackFunc\n")));
		return;
	}

	if (0 == dwCallbackInstance) {
		DEBUGMSG (ZONE_ERROR, (TEXT("-lineCallbackFunc: dwCallbackInstance==NULL\r\n")));
		return;
	}

	if (NULL == (pOpenLine = GetOpenLinePtr ((void *)dwCallbackInstance))) {
		DEBUGMSG (ZONE_ERROR, (TEXT("-lineCallbackFunc: dwCallbackInstance(0x%X) not a valid pOpenLine\r\n"),
							  dwCallbackInstance));
		return;
	}

	ASSERT (CHK_AOL(pOpenLine));
	pAdapter = pOpenLine->pAdapter;
	ASSERT (CHK_AA(pAdapter));

	switch (dwMsg)
	{
	case LINE_CALLINFO:
		// Information about the call has changed.
		break;

	case LINE_CALLSTATE :
		// Save away the callstate
		pOpenLine->dwCallState = dwParam1;
		switch (dwParam1) {
		case LINECALLSTATE_CONNECTED :
			DEBUGMSG(ZONE_INTERFACE, (TEXT("LINECALLSTATE_CONNECTED\n")));
			// Let's get the handle to the serial port.
			pOpenLine->hPort = TapiLineGetID(pOpenLine->hLine, pOpenLine->hCall);

			ASSERT (pOpenLine->hRxThrd == NULL);

			// Keep track of the line up.
			pOpenLine->dwFlags |= AOL_FLAGS_SENT_LINE_UP;
			
			pOpenLine->hRxThrd = CreateThread (NULL, 0, MacRxThread, pOpenLine, 0, &dwID);

			ASSERT (pOpenLine->hRxThrd != INVALID_HANDLE_VALUE);

			// Set the receive thread priority
			CeSetThreadPriority(pOpenLine->hRxThrd, pAdapter->dwRecvThreadPrio);

			memset ((char *)&MacLineUp, 0, sizeof(MacLineUp));
			MacLineUp.LinkSpeed = pOpenLine->dwBaudRate;
			//	TODO	MacLineUp.Quality =
			MacLineUp.SendWindow = 1;
			MacLineUp.ConnectionWrapperID = (NDIS_HANDLE)pOpenLine->htCall;
			MacLineUp.NdisLinkHandle = pOpenLine;

			NdisMIndicateStatus (pAdapter->hMiniportAdapter,
								 NDIS_STATUS_WAN_LINE_UP,
								 &MacLineUp, sizeof(MacLineUp));
			
			// Save the NdisLinkContext;
			pOpenLine->hNdisLinkContext = MacLineUp.NdisLinkContext;

			break;

		case LINECALLSTATE_IDLE :
			DEBUGMSG(ZONE_INTERFACE, (TEXT("ASYNCMAC: LINECALLSTATE_IDLE\n")));
			if (pOpenLine->dwFlags & AOL_FLAGS_SENT_LINE_UP) {
				SendLineDown (pOpenLine);
				// Kill recv thread.
				while (pOpenLine->hRxThrd) {
					DEBUGMSG (ZONE_TAPI, (TEXT(" lineCallbackFunc: Calling SetCommMask\n")));
					if (SetCommMask (pOpenLine->hPort, 0) == FALSE)
					{
						// Port is invalid
						DEBUGMSG (ZONE_ERROR, (TEXT(" lineCallbackFunc: SetCommMask failed, error=%d\n"), GetLastError()));
						break;
					}
					Sleep (20);
				}
			}
			break;

		case LINECALLSTATE_DISCONNECTED:
			DEBUGMSG (ZONE_FUNCTION, (TEXT(" lineCallbackFunc: LINECALLSTATE_DISCONNECTED\n")));
			break;

		default :
			DEBUGMSG (1, (TEXT(" lineCallbackFunc: Unhandled LINE_CALLSTATE Callback %d\n"), dwParam1));
			break;
		}
		break;
	case LINE_REPLY :
        //
        // dwParam2 has the error code.  If non-zero then something bad has happened.
        //
        if (dwParam2) {
			// Tell the caller that this failed.
//            SetEvent (s_p->TapiEvent);
        }
		break;

	default :
		DEBUGMSG (1, (TEXT(" lineCallbackFunc: Unhandled callback %d\r\n"), dwMsg));
		break;
	}

	// Let's just let the NDISWAN layer know what happened
	if (pOpenLine->hCall) {

		// Check again just in case we had to wait for the lock......
		if (pOpenLine->hCall) {
			TapiEvent.htLine = pOpenLine->htLine;
			TapiEvent.htCall = pOpenLine->htCall;

			NdisMIndicateStatus (pAdapter->hMiniportAdapter,
								 NDIS_STATUS_TAPI_INDICATION,
								 &TapiEvent, sizeof(NDIS_TAPI_EVENT));
		}

	}
	ReleaseOpenLinePtr (pOpenLine);
    DEBUGMSG (ZONE_FUNCTION, (TEXT("-lineCallbackFunc\r\n")));
    return;
}

VOID NDISAPI
DoLineInitialize(PVOID SystemSpecific1,
				 PVOID FunctionContext,
				 PVOID SystemSpecific2,
				 PVOID SystemSpecific3)
{
	PASYNCMAC_ADAPTER	pAdapter = (PASYNCMAC_ADAPTER)FunctionContext;
	long				lReturn;
	NDIS_TAPI_EVENT		TapiEvent;
	DWORD				i;
	LINEEXTENSIONID		lineExtensionID;

	if (IsAPIReady(SH_TAPI)) {
		// Sleep an extra 5 seconds anyway, why?  I don't know but it seems
		// like a good idea, this allows all of the initial devices to be
		// created.
		Sleep(5000);
		lReturn = lineInitialize (&(pAdapter->hLineApp),
								  v_hInstance, lineCallbackFunc, 
								  TEXT("ASYNCMAC"), &(pAdapter->dwNumDevs));

		if (lReturn == 0) {
			DEBUGMSG (1, (TEXT("lineInitialize say's there's %d devices\r\n"),
						  pAdapter->dwNumDevs));

			// Let's figure out the version number to use?
			// We'll just ask for device 0?
			if (lineNegotiateAPIVersion(pAdapter->hLineApp, 0,
				TAPI_CURRENT_VERSION, TAPI_CURRENT_VERSION,  
				&(pAdapter->dwAPIVersion), &lineExtensionID))  {
				DEBUGMSG (1, (TEXT("Error from lineNegotiateAPIVersion?\r\n")));
			}
			

			// Now inform PPP that we have new devices
			memset ((char *)&TapiEvent, 0, sizeof(TapiEvent));
			//TapiEvent.htLine = 0;
			//TapiEvent.htCall = 0;
			TapiEvent.ulMsg = LINE_CREATE;
			for (i=0; i < pAdapter->dwNumDevs; i++) {
				// Indicate device num
				TapiEvent.ulParam1 = i;
				NdisMIndicateStatus(pAdapter->hMiniportAdapter, NDIS_STATUS_TAPI_INDICATION, &TapiEvent, sizeof(TapiEvent));
			}
		}

		DEBUGMSG (ZONE_ERROR && lReturn,
				  (TEXT("ASYNCMAC: Error %d from lineInitialize\r\n")));

	} else {
		DEBUGMSG (1, (TEXT("ASYNCMAC:Tapi not ready yet... Resetting Timer\r\n")));
		NdisMSetTimer (&(pAdapter->ntLineInit), 1000);
	}
}

⌨️ 快捷键说明

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