5750 lines
135 KiB
C
5750 lines
135 KiB
C
/*++
|
|
|
|
Copyright (C) 1994-98 Microsft Corporation. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
rastapi.c
|
|
|
|
Abstract:
|
|
|
|
This file contains all entry points for TAPI.DLL
|
|
|
|
Author:
|
|
|
|
Gurdeep Singh Pall (gurdeep) 06-Mar-1995
|
|
|
|
Revision History:
|
|
|
|
Miscellaneous Modifications - raos 31-Dec-1997
|
|
|
|
--*/
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
|
|
#include <windows.h>
|
|
#include <tapi.h>
|
|
#include <rasman.h>
|
|
#include <raserror.h>
|
|
#include <mprlog.h>
|
|
#include <rtutils.h>
|
|
|
|
#include <wanpub.h>
|
|
#include <asyncpub.h>
|
|
|
|
#include <media.h>
|
|
#include <device.h>
|
|
#include <rasmxs.h>
|
|
#include <isdn.h>
|
|
#include <serial.h>
|
|
#include <stdlib.h>
|
|
#include <tchar.h>
|
|
#include <malloc.h>
|
|
#include <setupapi.h>
|
|
#include <string.h>
|
|
#include "rastapi.h"
|
|
#include <unimodem.h>
|
|
#include "reghelp.h"
|
|
|
|
|
|
extern DWORD TotalPorts ;
|
|
extern HLINEAPP RasLine ;
|
|
extern HINSTANCE RasInstance ;
|
|
extern TapiLineInfo *RasTapiLineInfoList ;
|
|
extern TapiPortControlBlock *RasPortsList ;
|
|
extern TapiPortControlBlock *RasPortsEnd ;
|
|
extern HANDLE RasTapiMutex ;
|
|
extern BOOL Initialized ;
|
|
extern DWORD TapiThreadId ;
|
|
extern HANDLE TapiThreadHandle;
|
|
// extern DWORD LoaderThreadId;
|
|
extern DWORD ValidPorts;
|
|
extern HANDLE g_hAsyMac ;
|
|
|
|
extern HANDLE g_hIoCompletionPort;
|
|
|
|
extern DWORD *g_pdwNumEndPoints;
|
|
|
|
extern DeviceInfo *g_pDeviceInfoList;
|
|
|
|
BOOL g_fDllLoaded = FALSE;
|
|
|
|
DWORD GetInfo ( TapiPortControlBlock *,
|
|
BYTE *,
|
|
DWORD *) ;
|
|
|
|
DWORD SetInfo ( TapiPortControlBlock *,
|
|
RASMAN_PORTINFO *) ;
|
|
|
|
DWORD GetGenericParams ( TapiPortControlBlock *,
|
|
RASMAN_PORTINFO *,
|
|
PDWORD) ;
|
|
|
|
DWORD GetIsdnParams ( TapiPortControlBlock *,
|
|
RASMAN_PORTINFO * ,
|
|
PDWORD) ;
|
|
|
|
DWORD GetX25Params ( TapiPortControlBlock *,
|
|
RASMAN_PORTINFO *,
|
|
PDWORD) ;
|
|
|
|
DWORD FillInX25Params ( TapiPortControlBlock *,
|
|
RASMAN_PORTINFO *) ;
|
|
|
|
DWORD FillInIsdnParams ( TapiPortControlBlock *,
|
|
RASMAN_PORTINFO *) ;
|
|
|
|
DWORD FillInGenericParams ( TapiPortControlBlock *,
|
|
RASMAN_PORTINFO *) ;
|
|
|
|
DWORD FillInUnimodemParams ( TapiPortControlBlock *,
|
|
RASMAN_PORTINFO *) ;
|
|
|
|
VOID SetModemParams ( TapiPortControlBlock *hIOPort,
|
|
LINECALLPARAMS *linecallparams) ;
|
|
|
|
VOID SetGenericParams (TapiPortControlBlock *,
|
|
LINECALLPARAMS *);
|
|
|
|
VOID
|
|
SetAtmParams (TapiPortControlBlock *,
|
|
LINECALLPARAMS *);
|
|
|
|
VOID
|
|
SetX25Params(TapiPortControlBlock *hIOPort,
|
|
LINECALLPARAMS *linecallparams);
|
|
|
|
DWORD InitiatePortDisconnection (TapiPortControlBlock *hIOPort) ;
|
|
|
|
TapiPortControlBlock *LookUpControlBlock (HANDLE hPort) ;
|
|
|
|
DWORD ValueToNum(RAS_PARAMS *p) ;
|
|
|
|
extern DWORD dwTraceId;
|
|
|
|
#define CCH_GUID_STRING_LEN 39 // 38 chars + terminator null
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Searches for a specific device on a given interface.
|
|
It does this by using setup api to return all of the
|
|
devices in the class given by pguidInterfaceId. It then
|
|
gets device path for each of these device interfaces and
|
|
looks for pguidDeviceId and pszwReferenceString as
|
|
substrings.
|
|
|
|
Arguments:
|
|
pguidDeviceId [in] The device id to find.
|
|
pguidInterfaceId [in] The interface on which to look.
|
|
pszwReferenceString [in] Optional. Further match on this ref string.
|
|
dwFlagsAndAttributes [in] See CreateFile. This is how the device is
|
|
opened if it is found.
|
|
phFile [out] The returned device handle.
|
|
|
|
Return Value:
|
|
|
|
TRUE if found and opened, FALSE if not found, or an error.
|
|
|
|
--*/
|
|
BOOL
|
|
FindDeviceOnInterface (
|
|
const GUID* pguidDeviceId,
|
|
const GUID* pguidInterfaceId,
|
|
LPCWSTR pszwReferenceString,
|
|
DWORD dwFlagsAndAttributes,
|
|
HANDLE* phFile)
|
|
{
|
|
WCHAR szwDeviceId [CCH_GUID_STRING_LEN];
|
|
INT cch;
|
|
HDEVINFO hdi;
|
|
BOOL fFound = FALSE;
|
|
|
|
ASSERT (pguidDeviceId);
|
|
ASSERT (pguidInterfaceId);
|
|
ASSERT (phFile);
|
|
|
|
//
|
|
// Initialize the output parameter.
|
|
//
|
|
*phFile = INVALID_HANDLE_VALUE;
|
|
|
|
cch = StringFromGUID2 (pguidDeviceId,
|
|
szwDeviceId,
|
|
CCH_GUID_STRING_LEN);
|
|
|
|
ASSERT (CCH_GUID_STRING_LEN == cch);
|
|
|
|
CharLowerW (szwDeviceId);
|
|
|
|
//
|
|
// Get the devices in this class.
|
|
//
|
|
hdi = SetupDiGetClassDevsW ((LPGUID)pguidInterfaceId,
|
|
NULL, NULL,
|
|
DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
|
|
if (hdi)
|
|
{
|
|
//
|
|
// pDetail is used to get device interface
|
|
// detail for each device interface enumerated
|
|
// below.
|
|
//
|
|
PSP_DEVICE_INTERFACE_DETAIL_DATA_W pDetail;
|
|
|
|
const ULONG cbDetail = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W)
|
|
+(MAX_PATH * sizeof(WCHAR));
|
|
|
|
pDetail = malloc (cbDetail);
|
|
|
|
if (pDetail)
|
|
{
|
|
//
|
|
// Enumerate the device interfaces looking for
|
|
// the one specified.
|
|
//
|
|
DWORD dwIndex;
|
|
SP_DEVICE_INTERFACE_DATA did;
|
|
|
|
ZeroMemory (&did, sizeof(did));
|
|
|
|
for (dwIndex = 0;
|
|
did.cbSize = sizeof(did),
|
|
SetupDiEnumDeviceInterfaces (hdi, NULL,
|
|
(LPGUID)(pguidInterfaceId),
|
|
dwIndex,
|
|
&did);
|
|
dwIndex++)
|
|
{
|
|
//
|
|
// Now get the details so we can compare the
|
|
// device path.
|
|
//
|
|
pDetail->cbSize = sizeof(*pDetail);
|
|
if (SetupDiGetDeviceInterfaceDetailW (hdi, &did,
|
|
pDetail, cbDetail, NULL, NULL))
|
|
{
|
|
CharLowerW (pDetail->DevicePath);
|
|
|
|
//
|
|
// Look for a substring containing szwDeviceId. Also
|
|
// look for a substring containing pszwReferenceString
|
|
// if it is specified.
|
|
//
|
|
if ( wcsstr (pDetail->DevicePath, szwDeviceId)
|
|
&& ( !pszwReferenceString
|
|
|| !*pszwReferenceString
|
|
|| wcsstr (pDetail->DevicePath,
|
|
pszwReferenceString)))
|
|
{
|
|
//
|
|
// We found it, so open the device and return it.
|
|
//
|
|
HANDLE hFile = CreateFileW (
|
|
pDetail->DevicePath,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
dwFlagsAndAttributes,
|
|
NULL);
|
|
|
|
if ( hFile
|
|
&& (INVALID_HANDLE_VALUE != hFile))
|
|
{
|
|
*phFile = hFile;
|
|
fFound = TRUE;
|
|
}
|
|
else
|
|
{
|
|
DWORD dwErr = GetLastError();
|
|
RasTapiTrace("Createfile %ws failed with %d",
|
|
pDetail->DevicePath, dwErr);
|
|
|
|
}
|
|
|
|
//
|
|
// Now that we've found it, break out of the loop.
|
|
//
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
free (pDetail);
|
|
}
|
|
|
|
SetupDiDestroyDeviceInfoList (hdi);
|
|
}
|
|
|
|
return fFound;
|
|
}
|
|
|
|
|
|
DWORD
|
|
OpenAsyncMac (
|
|
HANDLE *phAsyMac
|
|
)
|
|
{
|
|
static const GUID DEVICE_GUID_ASYNCMAC =
|
|
{0xeeab7790,0xc514,0x11d1,{0xb4,0x2b,0x00,0x80,0x5f,0xc1,0x27,0x0e}};
|
|
|
|
static const GUID GUID_NDIS_LAN_CLASS =
|
|
{0xad498944,0x762f,0x11d0,{0x8d,0xcb,0x00,0xc0,0x4f,0xc3,0x35,0x8c}};
|
|
|
|
HANDLE hAsyMac = INVALID_HANDLE_VALUE;
|
|
HANDLE hSwenum;
|
|
BOOL fFound;
|
|
DWORD dwErr = SUCCESS;
|
|
|
|
fFound = FindDeviceOnInterface (
|
|
&DEVICE_GUID_ASYNCMAC,
|
|
&GUID_NDIS_LAN_CLASS,
|
|
L"asyncmac",
|
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
|
|
&hSwenum);
|
|
if (fFound)
|
|
{
|
|
hAsyMac = CreateFileW (
|
|
L"\\\\.\\ASYNCMAC",
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
|
|
NULL);
|
|
|
|
if(INVALID_HANDLE_VALUE == hAsyMac)
|
|
{
|
|
dwErr = GetLastError();
|
|
RasTapiTrace("Failed to createfile asyncmac. rc=0x%x",
|
|
dwErr);
|
|
}
|
|
|
|
CloseHandle (hSwenum);
|
|
}
|
|
else
|
|
{
|
|
dwErr = ERROR_FILE_NOT_FOUND;
|
|
RasTapiTrace("FindDeviceOnInterface returned FALSE");
|
|
}
|
|
|
|
*phAsyMac = hAsyMac;
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
DWORD APIENTRY
|
|
PortSetIoCompletionPort(HANDLE hIoCompletionPort)
|
|
{
|
|
|
|
|
|
g_hIoCompletionPort = hIoCompletionPort;
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This API returns a buffer containing
|
|
a PortMediaInfo struct.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
ERROR_BUFFER_TOO_SMALL
|
|
ERROR_READING_SECTIONNAME
|
|
ERROR_READING_DEVICETYPE
|
|
ERROR_READING_DEVICENAME
|
|
ERROR_READING_USAGE
|
|
ERROR_BAD_USAGE_IN_INI_FILE
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
PortEnum(
|
|
BYTE *pBuffer,
|
|
DWORD *pdwSize,
|
|
DWORD *pdwNumPorts
|
|
)
|
|
{
|
|
PortMediaInfo *pinfo ;
|
|
TapiPortControlBlock *pports ;
|
|
DWORD numports = 0;
|
|
DWORD i ;
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
RasTapiTrace ("PortEnum");
|
|
|
|
if (!Initialized)
|
|
{
|
|
HANDLE event;
|
|
|
|
// LoaderThreadId = GetCurrentThreadId();
|
|
|
|
event = CreateEvent (NULL, FALSE, FALSE, NULL) ;
|
|
|
|
if(NULL == event)
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
|
|
RasTapiTrace("PortEnum: CreateEvent failed %d",
|
|
dwError);
|
|
|
|
FreeMutex(RasTapiMutex);
|
|
return dwError;
|
|
}
|
|
|
|
TapiThreadHandle = CreateThread (
|
|
NULL,
|
|
5000,
|
|
(LPTHREAD_START_ROUTINE)
|
|
EnumerateTapiPorts,
|
|
(LPVOID) event,
|
|
0,
|
|
&TapiThreadId);
|
|
|
|
if(NULL == TapiThreadHandle)
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
CloseHandle(event);
|
|
FreeMutex(RasTapiMutex);
|
|
|
|
RasTapiTrace("PortEnum: CreateThread failed %d",
|
|
dwError);
|
|
|
|
return dwError;
|
|
}
|
|
|
|
WaitForSingleObject (event, INFINITE) ;
|
|
|
|
if ( RasLine == 0 )
|
|
{
|
|
|
|
//
|
|
// Wait for the thread to go away!
|
|
//
|
|
WaitForSingleObject(TapiThreadHandle, INFINITE);
|
|
|
|
CloseHandle (TapiThreadHandle) ;
|
|
|
|
// *** Exclusion End ***
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
CloseHandle(event);
|
|
|
|
RasTapiTrace("PortEnum: RasLine == 0, returning "
|
|
"ERROR_TAPI_CONFIGURATION");
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return ERROR_TAPI_CONFIGURATION ;
|
|
}
|
|
|
|
CloseHandle (event) ;
|
|
|
|
Initialized = TRUE ;
|
|
}
|
|
|
|
//
|
|
// calculate the number of valid ports
|
|
//
|
|
pports = RasPortsList;
|
|
|
|
while ( pports )
|
|
{
|
|
if (pports->TPCB_State != PS_UNINITIALIZED)
|
|
numports++ ;
|
|
|
|
pports = pports->TPCB_next;
|
|
}
|
|
|
|
RasTapiTrace("PortEnum: Number of Ports = %d", numports );
|
|
|
|
if (*pdwSize < numports * sizeof(PortMediaInfo))
|
|
{
|
|
RasTapiTrace ("PortEnum: size required = %d,"
|
|
" size avail = %d, returning %d",
|
|
numports * sizeof(PortMediaInfo),
|
|
*pdwSize, ERROR_BUFFER_TOO_SMALL );
|
|
|
|
*pdwNumPorts = numports ;
|
|
|
|
*pdwSize = *pdwNumPorts * sizeof(PortMediaInfo) ;
|
|
|
|
// *** Exclusion End ***
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
|
|
return ERROR_BUFFER_TOO_SMALL ;
|
|
|
|
}
|
|
|
|
*pdwNumPorts = 0 ;
|
|
|
|
pinfo = (PortMediaInfo *)pBuffer ;
|
|
|
|
pports = RasPortsList;
|
|
|
|
while ( pports )
|
|
{
|
|
|
|
if (pports->TPCB_State == PS_UNINITIALIZED)
|
|
{
|
|
pports = pports->TPCB_next;
|
|
continue ;
|
|
}
|
|
|
|
strcpy (pinfo->PMI_Name, pports->TPCB_Name) ;
|
|
|
|
pinfo->PMI_Usage = pports->TPCB_Usage ;
|
|
|
|
strcpy (pinfo->PMI_DeviceType, pports->TPCB_DeviceType) ;
|
|
|
|
strcpy (pinfo->PMI_DeviceName, pports->TPCB_DeviceName) ;
|
|
|
|
pinfo->PMI_LineDeviceId = pports->TPCB_Line->TLI_LineId;
|
|
|
|
pinfo->PMI_AddressId = pports->TPCB_AddressId;
|
|
|
|
pinfo->PMI_pDeviceInfo =
|
|
pports->TPCB_Line->TLI_pDeviceInfo;
|
|
|
|
pinfo++ ;
|
|
|
|
(*pdwNumPorts)++ ;
|
|
|
|
pports = pports->TPCB_next;
|
|
}
|
|
|
|
// *** Exclusion End ***
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
return(SUCCESS);
|
|
}
|
|
|
|
DWORD
|
|
DwEnableModemDiagnostics(TapiPortControlBlock *pport)
|
|
{
|
|
DWORD dwErr = SUCCESS;
|
|
|
|
BYTE bvar[1000];
|
|
|
|
LPVARSTRING pvar = (LPVARSTRING) bvar;
|
|
|
|
LONG lr = ERROR_SUCCESS;
|
|
|
|
RasTapiTrace("DwEnableModemDiagnostics");
|
|
|
|
//
|
|
// Get the device config information regarding
|
|
// line diagnostics
|
|
//
|
|
pvar->dwTotalSize = 1000;
|
|
|
|
pvar->dwStringSize = 0;
|
|
|
|
lr = lineGetDevConfig(pport->TPCB_Line->TLI_LineId,
|
|
pvar,
|
|
"tapi/line/diagnostics");
|
|
|
|
if( LINEERR_STRUCTURETOOSMALL == lr
|
|
|| pvar->dwNeededSize > pvar->dwTotalSize)
|
|
{
|
|
DWORD dwNeededSize = pvar->dwNeededSize;
|
|
|
|
//
|
|
// Allocate the required size
|
|
//
|
|
if(NULL == (pvar = LocalAlloc(LPTR,
|
|
dwNeededSize)))
|
|
{
|
|
lr = (LONG) GetLastError();
|
|
|
|
goto done;
|
|
}
|
|
|
|
pvar->dwTotalSize = dwNeededSize;
|
|
|
|
//
|
|
// Call the api again
|
|
//
|
|
lr = lineGetDevConfig(pport->TPCB_Line->TLI_LineId,
|
|
pvar,
|
|
"tapi/line/diagnostics");
|
|
}
|
|
|
|
if(ERROR_SUCCESS != lr)
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
if( STRINGFORMAT_BINARY != pvar->dwStringFormat
|
|
|| pvar->dwStringSize < sizeof(LINEDIAGNOSTICSCONFIG))
|
|
{
|
|
RasTapiTrace("No diagnostics information available");
|
|
|
|
goto done;
|
|
}
|
|
else
|
|
{
|
|
|
|
PLINEDIAGNOSTICSCONFIG lpConfig;
|
|
|
|
lpConfig = (PLINEDIAGNOSTICSCONFIG)
|
|
((LPBYTE) pvar + pvar->dwStringOffset);
|
|
|
|
if(LDSIG_LINEDIAGNOSTICSCONFIG != lpConfig->hdr.dwSig)
|
|
{
|
|
RasTapiTrace("Invalid LineDiagnostics sig. 0x%x",
|
|
lpConfig->hdr.dwSig);
|
|
}
|
|
|
|
lpConfig->hdr.dwParam |= fSTANDARD_CALL_DIAGNOSTICS;
|
|
|
|
lr = lineSetDevConfig(pport->TPCB_Line->TLI_LineId,
|
|
lpConfig,
|
|
pvar->dwStringSize,
|
|
"tapi/line/diagnostics");
|
|
|
|
}
|
|
|
|
done:
|
|
|
|
if(bvar != (PBYTE) pvar)
|
|
{
|
|
LocalFree(pvar);
|
|
}
|
|
|
|
RasTapiTrace("DwEnableModemDiagnostics. 0x%x",
|
|
lr);
|
|
|
|
return (DWORD) lr;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This API opens a COM port. It takes the port name in ASCIIZ
|
|
form and supplies a handle to the open port. hNotify is use
|
|
to notify the caller if the device on the port shuts down.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
ERROR_PORT_NOT_CONFIGURED
|
|
ERROR_DEVICE_NOT_READY
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
PortOpen(
|
|
char *pszPortName,
|
|
HANDLE *phIOPort,
|
|
HANDLE hIoCompletionPort,
|
|
DWORD dwCompletionKey
|
|
)
|
|
{
|
|
TapiPortControlBlock *pports ;
|
|
DWORD retcode ;
|
|
DWORD i ;
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
RasTapiTrace ("PortOpen: %s", pszPortName );
|
|
|
|
pports = RasPortsList ;
|
|
|
|
while ( pports )
|
|
{
|
|
if ( (_stricmp(pszPortName, pports->TPCB_Name) == 0)
|
|
&& (pports->TPCB_State != PS_UNAVAILABLE))
|
|
{
|
|
break ;
|
|
}
|
|
|
|
pports = pports->TPCB_next ;
|
|
}
|
|
|
|
if ( pports )
|
|
{
|
|
|
|
if (pports->TPCB_State == PS_UNINITIALIZED)
|
|
{
|
|
RasTapiTrace ("PortOpen: state = PS_UNINITIALIZED,"
|
|
" returning %d",
|
|
ERROR_TAPI_CONFIGURATION );
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return ERROR_TAPI_CONFIGURATION ;
|
|
|
|
}
|
|
|
|
if (pports->TPCB_State != PS_CLOSED)
|
|
{
|
|
RasTapiTrace("PortOpen: Port is already open. "
|
|
"state = %d != PS_CLOSED",
|
|
pports->TPCB_State );
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return ERROR_PORT_ALREADY_OPEN ;
|
|
}
|
|
|
|
if ((_stricmp (pports->TPCB_DeviceType,
|
|
DEVICETYPE_UNIMODEM) == 0)) {
|
|
|
|
if (INVALID_HANDLE_VALUE == g_hAsyMac)
|
|
{
|
|
retcode = OpenAsyncMac (&g_hAsyMac);
|
|
}
|
|
|
|
if (INVALID_HANDLE_VALUE == g_hAsyMac)
|
|
{
|
|
RasTapiTrace ("PortOpen: Failed to CreateFile asyncmac."
|
|
" %d", retcode );
|
|
|
|
if(SUCCESS == retcode)
|
|
{
|
|
RasTapiTrace("Failed to open asyncmac but no error!!!");
|
|
retcode = ERROR_FILE_NOT_FOUND;
|
|
}
|
|
|
|
// *** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
return(retcode);
|
|
}
|
|
}
|
|
|
|
if (pports->TPCB_Line->TLI_LineState == PS_CLOSED)
|
|
{
|
|
//
|
|
// open line
|
|
//
|
|
LINEDEVCAPS *linedevcaps ;
|
|
BYTE buffer[400] ;
|
|
|
|
linedevcaps = (LINEDEVCAPS *)buffer ;
|
|
linedevcaps->dwTotalSize = sizeof (buffer) ;
|
|
|
|
lineGetDevCaps (RasLine,
|
|
pports->TPCB_Line->TLI_LineId,
|
|
pports->TPCB_Line->NegotiatedApiVersion,
|
|
pports->TPCB_Line->NegotiatedExtVersion,
|
|
linedevcaps) ;
|
|
|
|
//
|
|
// Remove LINEMEDIAMODE_INTERACTIVEVOICE from the
|
|
// media mode since this mode cannot be used for
|
|
// receiving calls.
|
|
//
|
|
pports->TPCB_Line->TLI_MediaMode =
|
|
linedevcaps->dwMediaModes &
|
|
~( LINEMEDIAMODE_INTERACTIVEVOICE |
|
|
LINEMEDIAMODE_AUTOMATEDVOICE) ;
|
|
|
|
retcode =
|
|
lineOpen (RasLine,
|
|
pports->TPCB_Line->TLI_LineId,
|
|
&pports->TPCB_Line->TLI_LineHandle,
|
|
pports->TPCB_Line->NegotiatedApiVersion,
|
|
pports->TPCB_Line->NegotiatedExtVersion,
|
|
(DWORD_PTR) pports->TPCB_Line,
|
|
LINECALLPRIVILEGE_OWNER,
|
|
pports->TPCB_Line->TLI_MediaMode,
|
|
NULL) ;
|
|
|
|
if (retcode)
|
|
{
|
|
RasTapiTrace ("PortOpen: lineOpen Failed. 0x%x",
|
|
retcode );
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return retcode ;
|
|
}
|
|
|
|
//
|
|
// Set monitoring of rings
|
|
//
|
|
lineSetStatusMessages (pports->TPCB_Line->TLI_LineHandle,
|
|
LINEDEVSTATE_RINGING, 0) ;
|
|
|
|
//
|
|
// Always turn off the modem lights incase this
|
|
// is a modem device
|
|
//
|
|
if ((_stricmp (pports->TPCB_DeviceType,
|
|
DEVICETYPE_UNIMODEM) == 0))
|
|
{
|
|
|
|
//
|
|
// unimodem struct not defined in any header
|
|
//
|
|
typedef struct _DEVCFG
|
|
{
|
|
DWORD dwSize;
|
|
DWORD dwVersion;
|
|
WORD fwOptions;
|
|
WORD wWaitBong;
|
|
|
|
} DEVCFG;
|
|
|
|
#define LAUNCH_LIGHTS 8
|
|
|
|
LPVARSTRING var ;
|
|
BYTE buffer[1000] ;
|
|
DEVCFG *devcfg ;
|
|
|
|
var = (LPVARSTRING)buffer ;
|
|
|
|
var->dwTotalSize = 1000 ;
|
|
|
|
var->dwStringSize = 0 ;
|
|
|
|
lineGetDevConfig(pports->TPCB_Line->TLI_LineId,
|
|
var, "comm/datamodem") ;
|
|
|
|
devcfg = (DEVCFG*) (((LPBYTE) var)
|
|
+ var->dwStringOffset) ;
|
|
|
|
devcfg->fwOptions &= ~LAUNCH_LIGHTS ;
|
|
|
|
lineSetDevConfig (pports->TPCB_Line->TLI_LineId,
|
|
devcfg,
|
|
var->dwStringSize,
|
|
"comm/datamodem") ;
|
|
|
|
//
|
|
// Enable diagnostics on the modem
|
|
//
|
|
retcode = DwEnableModemDiagnostics(pports);
|
|
|
|
RasTapiTrace("DwEnableModemDiagnostics returned 0x%x",
|
|
retcode);
|
|
|
|
//
|
|
// clear any error in this case. We don't want
|
|
// to fail a connection just because we couldn't
|
|
// obtain the connect response.
|
|
//
|
|
retcode = SUCCESS;
|
|
|
|
}
|
|
|
|
pports->TPCB_Line->TLI_LineState = PS_OPEN ;
|
|
|
|
}
|
|
|
|
//
|
|
// Initialize the parameters
|
|
//
|
|
pports->TPCB_Info[0][0] = '\0' ;
|
|
pports->TPCB_Info[1][0] = '\0' ;
|
|
pports->TPCB_Info[2][0] = '\0' ;
|
|
pports->TPCB_Info[3][0] = '\0' ;
|
|
pports->TPCB_Info[4][0] = '\0' ;
|
|
|
|
strcpy (pports->TPCB_Info[ISDN_CONNECTBPS_INDEX], "64000") ;
|
|
|
|
pports->TPCB_Line->TLI_OpenCount++ ;
|
|
|
|
pports->TPCB_State = PS_OPEN ;
|
|
|
|
pports->TPCB_DisconnectReason = 0 ;
|
|
|
|
pports->TPCB_CommHandle = INVALID_HANDLE_VALUE ;
|
|
|
|
pports->TPCB_IoCompletionPort = hIoCompletionPort;
|
|
|
|
pports->TPCB_CompletionKey = dwCompletionKey;
|
|
|
|
if (pports->TPCB_Line->CharModeSupported)
|
|
{
|
|
|
|
pports->TPCB_SendRequestId =
|
|
pports->TPCB_RecvRequestId = INFINITE;
|
|
|
|
pports->TPCB_CharMode = FALSE;
|
|
|
|
//
|
|
// If this port does not have a receive fifo
|
|
// allocated to it get one and init.
|
|
//
|
|
if (pports->TPCB_RecvFifo == NULL)
|
|
{
|
|
if ((pports->TPCB_RecvFifo =
|
|
LocalAlloc(LPTR, sizeof(RECV_FIFO) + 1500))
|
|
== NULL)
|
|
{
|
|
|
|
RasTapiTrace("PortOpen: LocalAlloc Failed. "
|
|
"%d, port %s, state = %d",
|
|
GetLastError(),
|
|
pports->TPCB_Name,
|
|
pports->TPCB_State );
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
return(GetLastError()) ;
|
|
}
|
|
|
|
pports->TPCB_RecvFifo->In =
|
|
pports->TPCB_RecvFifo->Out =
|
|
pports->TPCB_RecvFifo->Count = 0;
|
|
pports->TPCB_RecvFifo->Size = 1500;
|
|
}
|
|
}
|
|
|
|
*phIOPort = (HANDLE) pports ;
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace("PortOpen: successfully opened %s",
|
|
pszPortName );
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return(SUCCESS);
|
|
|
|
}
|
|
else
|
|
{
|
|
RasTapiTrace("PortOpen: Port %s not found",
|
|
pszPortName );
|
|
}
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return ERROR_PORT_NOT_CONFIGURED ;
|
|
|
|
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This API closes the COM port for the input handle.
|
|
It also finds the SerialPCB for the input handle,
|
|
removes it from the linked list, and frees the
|
|
memory for it
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
Values returned by GetLastError()
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
PortClose (HANDLE hIOPort)
|
|
{
|
|
TapiPortControlBlock *pports =
|
|
(TapiPortControlBlock *) hIOPort ;
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
RasTapiTrace("PortClose: %s", pports->TPCB_Name );
|
|
|
|
pports->TPCB_Line->TLI_OpenCount-- ;
|
|
|
|
if (pports->TPCB_DevConfig)
|
|
{
|
|
LocalFree (pports->TPCB_DevConfig) ;
|
|
}
|
|
|
|
pports->TPCB_DevConfig = NULL ;
|
|
|
|
if (pports->TPCB_Line->TLI_OpenCount == 0)
|
|
{
|
|
pports->TPCB_Line->TLI_LineState = PS_CLOSED ;
|
|
|
|
lineClose (pports->TPCB_Line->TLI_LineHandle) ;
|
|
}
|
|
|
|
if (pports->TPCB_RecvFifo != NULL)
|
|
{
|
|
|
|
LocalFree(pports->TPCB_RecvFifo);
|
|
|
|
pports->TPCB_RecvFifo = NULL;
|
|
}
|
|
|
|
if ( pports->TPCB_State == PS_UNAVAILABLE )
|
|
{
|
|
RasTapiTrace("PortClose: Removing port %s",
|
|
pports->TPCB_Name );
|
|
|
|
//
|
|
// This port has been marked for removal
|
|
//
|
|
dwRemovePort ( pports );
|
|
|
|
RasTapiTrace("PortClose: Port removed");
|
|
|
|
}
|
|
else
|
|
{
|
|
RasTapiTrace ("PortClose: Changing state for"
|
|
" %s from %d -> %d",
|
|
pports->TPCB_Name,
|
|
pports->TPCB_State,
|
|
PS_CLOSED );
|
|
|
|
pports->TPCB_State = PS_CLOSED ;
|
|
}
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return(SUCCESS);
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This API returns a block of information to the caller about
|
|
the port state. This API may be called before the port is
|
|
open in which case it will return inital default values
|
|
instead of actual port values.
|
|
hIOPort can be null in which case use portname to give
|
|
information hIOPort may be the actual file handle or
|
|
the hIOPort returned in port open.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
PortGetInfo(
|
|
HANDLE hIOPort,
|
|
TCHAR *pszPortName,
|
|
BYTE *pBuffer,
|
|
DWORD *pdwSize
|
|
)
|
|
{
|
|
DWORD i ;
|
|
DWORD retcode = ERROR_FROM_DEVICE ;
|
|
|
|
TapiPortControlBlock *port = RasPortsList;
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
while ( port )
|
|
{
|
|
if ( !_stricmp(port->TPCB_Name, pszPortName)
|
|
|| (hIOPort == (HANDLE) port)
|
|
|| (hIOPort == port->TPCB_CommHandle))
|
|
{
|
|
hIOPort = (HANDLE) port ;
|
|
|
|
retcode = GetInfo ((TapiPortControlBlock *) hIOPort,
|
|
pBuffer, pdwSize) ;
|
|
|
|
break ;
|
|
}
|
|
|
|
port = port->TPCB_next;
|
|
}
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
return (retcode);
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
The values for most input keys are used to set the port
|
|
parameters directly. However, the carrier BPS and the
|
|
error conrol on flag set fields in the Serial Port Control
|
|
Block only, and not the port.
|
|
hIOPort may the port handle returned in portopen or the
|
|
actual file handle.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
ERROR_WRONG_INFO_SPECIFIED
|
|
Values returned by GetLastError()
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
PortSetInfo(HANDLE hIOPort, RASMAN_PORTINFO *pInfo)
|
|
{
|
|
DWORD retcode ;
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
hIOPort = LookUpControlBlock(hIOPort) ;
|
|
|
|
if (NULL == hIOPort)
|
|
{
|
|
FreeMutex ( RasTapiMutex );
|
|
|
|
RasTapiTrace ("PortSetInfo: Port Not found");
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return ERROR_PORT_NOT_FOUND;
|
|
}
|
|
|
|
retcode = SetInfo ((TapiPortControlBlock *) hIOPort, pInfo) ;
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return (retcode);
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Really only has meaning if the
|
|
call was active. Will return
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
Values returned by GetLastError()
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
PortTestSignalState(HANDLE hPort, DWORD *pdwDeviceState)
|
|
{
|
|
BYTE buffer[200] ;
|
|
LINECALLSTATUS *pcallstatus ;
|
|
DWORD retcode = SUCCESS ;
|
|
|
|
TapiPortControlBlock *hIOPort
|
|
= (TapiPortControlBlock *) hPort;
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
*pdwDeviceState = 0 ;
|
|
|
|
memset (buffer, 0, sizeof(buffer)) ;
|
|
|
|
pcallstatus = (LINECALLSTATUS *) buffer ;
|
|
|
|
pcallstatus->dwTotalSize = sizeof (buffer) ;
|
|
|
|
//
|
|
// First check if we have a disconnect reason stored away.
|
|
// if so return that.
|
|
//
|
|
if (hIOPort->TPCB_DisconnectReason)
|
|
{
|
|
*pdwDeviceState = hIOPort->TPCB_DisconnectReason ;
|
|
|
|
RasTapiTrace("PortTestSignalState: DisconnectReason = %d",
|
|
*pdwDeviceState );
|
|
}
|
|
|
|
else if (hIOPort->TPCB_State != PS_CLOSED)
|
|
{
|
|
//
|
|
// Only in case of CONNECTING or CONNECTED do we care
|
|
// how the link dropped
|
|
//
|
|
if ( hIOPort->TPCB_State == PS_CONNECTING
|
|
|| hIOPort->TPCB_State == PS_CONNECTED)
|
|
{
|
|
|
|
retcode = lineGetCallStatus(hIOPort->TPCB_CallHandle,
|
|
pcallstatus) ;
|
|
|
|
if (retcode)
|
|
{
|
|
#if DBG
|
|
DbgPrint("PortTestSignalState: "
|
|
"lineGetCallStatus Failed. retcode = %d\n",
|
|
retcode);
|
|
#endif
|
|
*pdwDeviceState = SS_HARDWAREFAILURE;
|
|
}
|
|
|
|
else if (pcallstatus->dwCallState ==
|
|
LINECALLSTATE_DISCONNECTED)
|
|
{
|
|
*pdwDeviceState = SS_LINKDROPPED ;
|
|
}
|
|
else if (pcallstatus->dwCallState ==
|
|
LINECALLSTATE_IDLE)
|
|
{
|
|
*pdwDeviceState = SS_HARDWAREFAILURE ;
|
|
}
|
|
else if (pcallstatus->dwCallState ==
|
|
LINECALLSTATE_SPECIALINFO)
|
|
{
|
|
*pdwDeviceState = SS_HARDWAREFAILURE ;
|
|
}
|
|
RasTapiTrace("PortTestSignalState: CallState"
|
|
" = 0x%x, DeviceState = %d",
|
|
pcallstatus->dwCallState,
|
|
*pdwDeviceState );
|
|
|
|
}
|
|
else
|
|
{
|
|
RasTapiTrace("PortTestSignalState: DeviceState = %d",
|
|
*pdwDeviceState );
|
|
|
|
*pdwDeviceState = SS_LINKDROPPED | SS_HARDWAREFAILURE ;
|
|
}
|
|
}
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
return retcode ;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This API is called when a connection has been completed.
|
|
It in turn calls the asyncmac device driver in order to
|
|
indicate to asyncmac that the port and the connection
|
|
over it are ready for commumication.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
ERROR_PORT_NOT_OPEN
|
|
ERROR_NO_CONNECTION
|
|
Values returned by GetLastError()
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
PortConnect(HANDLE hPort,
|
|
BOOL bLegacyFlagNotUsed,
|
|
ULONG_PTR *endpoint )
|
|
{
|
|
DCB DCB ;
|
|
LINECALLINFO linecall ;
|
|
ASYMAC_OPEN AsyMacOpen;
|
|
ASYMAC_DCDCHANGE A ;
|
|
DWORD dwBytesReturned ;
|
|
TapiPortControlBlock *hIOPort = (TapiPortControlBlock *) hPort;
|
|
VARSTRING *varstring ;
|
|
BYTE buffer [100] ;
|
|
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
RasTapiTrace("PortConnect: %s", hIOPort->TPCB_Name );
|
|
|
|
//
|
|
// We must be connected to process this
|
|
//
|
|
if (hIOPort->TPCB_State != PS_CONNECTED)
|
|
{
|
|
|
|
RasTapiTrace (
|
|
"PortConnect: Port %s not connected. state = %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_State );
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return ERROR_PORT_DISCONNECTED ;
|
|
}
|
|
|
|
//
|
|
// get the cookie to realize tapi and ndis endpoints
|
|
//
|
|
memset (buffer, 0, sizeof(buffer));
|
|
varstring = (VARSTRING *) buffer ;
|
|
varstring->dwTotalSize = sizeof(buffer) ;
|
|
|
|
//
|
|
// get the actual line speed at which we connected
|
|
//
|
|
memset (&linecall, 0, sizeof (linecall)) ;
|
|
|
|
linecall.dwTotalSize = sizeof (linecall) ;
|
|
|
|
lineGetCallInfo (hIOPort->TPCB_CallHandle, &linecall) ;
|
|
|
|
_ltoa(linecall.dwRate, hIOPort->TPCB_Info[CONNECTBPS_INDEX], 10);
|
|
|
|
if (_stricmp (hIOPort->TPCB_DeviceType,
|
|
DEVICETYPE_UNIMODEM) == 0)
|
|
{
|
|
if(INVALID_HANDLE_VALUE == hIOPort->TPCB_CommHandle)
|
|
{
|
|
DWORD retcode;
|
|
|
|
if ( retcode =
|
|
lineGetID (hIOPort->TPCB_Line->TLI_LineHandle,
|
|
hIOPort->TPCB_AddressId,
|
|
hIOPort->TPCB_CallHandle,
|
|
LINECALLSELECT_CALL,
|
|
varstring,
|
|
"comm/datamodem"))
|
|
{
|
|
RasTapiTrace("PortConnect: %s lineGetID Failed. 0x%x",
|
|
hIOPort->TPCB_Name, retcode );
|
|
|
|
// **** Exclusion End ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
RasTapiTrace(" ");
|
|
|
|
return ERROR_FROM_DEVICE ;
|
|
}
|
|
|
|
hIOPort->TPCB_CommHandle = (HANDLE)
|
|
UlongToPtr((*((DWORD UNALIGNED *)
|
|
((BYTE *)varstring+varstring->dwStringOffset))));
|
|
|
|
RasTapiTrace("PortConnect: TPCB_CommHandle=%d",
|
|
hIOPort->TPCB_CommHandle );
|
|
|
|
//
|
|
// Create the I/O completion port for
|
|
// asynchronous operation completion
|
|
// notificiations.
|
|
//
|
|
if (CreateIoCompletionPort(
|
|
hIOPort->TPCB_CommHandle,
|
|
hIOPort->TPCB_IoCompletionPort,
|
|
hIOPort->TPCB_CompletionKey,
|
|
0) == NULL)
|
|
{
|
|
retcode = GetLastError();
|
|
|
|
RasTapiTrace("PortConnect: %s. CreateIoCompletionPort "
|
|
"failed. %d",
|
|
hIOPort->TPCB_Name,
|
|
retcode );
|
|
|
|
FreeMutex(RasTapiMutex);
|
|
RasTapiTrace(" ");
|
|
|
|
return retcode;
|
|
}
|
|
|
|
//
|
|
// Initialize the port for approp. buffers
|
|
//
|
|
SetupComm (hIOPort->TPCB_CommHandle, 1514, 1514) ;
|
|
}
|
|
|
|
//
|
|
// Before we send IOCTL to asyncmac - sanitize the DCB in
|
|
// case some app left databits, stopbits, parity set to bad
|
|
// values.
|
|
//
|
|
if (!GetCommState(hIOPort->TPCB_CommHandle, &DCB))
|
|
{
|
|
RasTapiTrace ("PortConnect: GetCommState failed for %s",
|
|
hIOPort->TPCB_Name);
|
|
|
|
FreeMutex(RasTapiMutex);
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return(GetLastError());
|
|
}
|
|
|
|
DCB.ByteSize = 8 ;
|
|
DCB.StopBits = ONESTOPBIT ;
|
|
DCB.Parity = NOPARITY ;
|
|
|
|
if (!SetCommState(hIOPort->TPCB_CommHandle, &DCB))
|
|
{
|
|
|
|
DWORD retcode = GetLastError();
|
|
|
|
RasTapiTrace ("PortConnect: SetCommState failed "
|
|
"for %s.handle=0x%x. %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_CommHandle,
|
|
retcode);
|
|
|
|
// FreeMutex(RasTapiMutex);
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
// return(retcode);
|
|
// This is not a fatal error. Ignore the error.
|
|
retcode = ERROR_SUCCESS;
|
|
}
|
|
|
|
RasTapiTrace("PortConnect: dwRate=%d", linecall.dwRate );
|
|
|
|
AsyMacOpen.hNdisEndpoint = INVALID_HANDLE_VALUE ;
|
|
|
|
AsyMacOpen.LinkSpeed = linecall.dwRate ;
|
|
|
|
AsyMacOpen.FileHandle = hIOPort->TPCB_CommHandle ;
|
|
|
|
AsyMacOpen.QualOfConnect = (UINT)NdisWanErrorControl;
|
|
|
|
{
|
|
OVERLAPPED overlapped ;
|
|
memset (&overlapped, 0, sizeof(OVERLAPPED)) ;
|
|
if (!DeviceIoControl(g_hAsyMac,
|
|
IOCTL_ASYMAC_OPEN,
|
|
&AsyMacOpen,
|
|
sizeof(AsyMacOpen),
|
|
&AsyMacOpen,
|
|
sizeof(AsyMacOpen),
|
|
&dwBytesReturned,
|
|
&overlapped))
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
|
|
RasTapiTrace("PortConnect: IOCTL_ASYMAC_OPEN "
|
|
"failed. %d", dwError );
|
|
|
|
// *** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
return(dwError);
|
|
}
|
|
}
|
|
|
|
hIOPort->TPCB_Endpoint = AsyMacOpen.hNdisEndpoint;
|
|
|
|
*endpoint = (ULONG_PTR) AsyMacOpen.hNdisEndpoint;
|
|
|
|
}
|
|
else
|
|
{
|
|
DWORD retcode;
|
|
|
|
if ( retcode = lineGetID (hIOPort->TPCB_Line->TLI_LineHandle,
|
|
hIOPort->TPCB_AddressId,
|
|
hIOPort->TPCB_CallHandle,
|
|
LINECALLSELECT_CALL,
|
|
varstring,
|
|
"NDIS"))
|
|
{
|
|
RasTapiTrace ("PortConnect: %s. lineGetId Failed. 0x%x",
|
|
hIOPort->TPCB_Name,
|
|
retcode );
|
|
|
|
// **** Exclusion End ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return ERROR_FROM_DEVICE ;
|
|
}
|
|
|
|
hIOPort->TPCB_Endpoint =
|
|
*((HANDLE UNALIGNED *) ((BYTE *)varstring+varstring->dwStringOffset)) ;
|
|
|
|
*endpoint = (ULONG_PTR) hIOPort->TPCB_Endpoint ;
|
|
|
|
if ( hIOPort->TPCB_Line->CharModeSupported
|
|
&& hIOPort->TPCB_CharMode)
|
|
{
|
|
|
|
PRASTAPI_DEV_SPECIFIC SetPPP;
|
|
|
|
hIOPort->TPCB_CharMode = FALSE;
|
|
|
|
if ((SetPPP =
|
|
LocalAlloc(LPTR, sizeof(RASTAPI_DEV_SPECIFIC))) == NULL)
|
|
{
|
|
|
|
DWORD dwErr = GetLastError();
|
|
|
|
RasTapiTrace("PortConnect: Failed to allocate. %d, "
|
|
"port %s, State=%d",
|
|
dwErr,
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_State );
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
return(dwErr);
|
|
}
|
|
|
|
SetPPP->Command = RASTAPI_DEV_PPP_MODE;
|
|
|
|
hIOPort->TPCB_ModeRequestDesc = SetPPP;
|
|
|
|
hIOPort->TPCB_ModeRequestId =
|
|
lineDevSpecific(hIOPort->TPCB_Line->TLI_LineHandle,
|
|
hIOPort->TPCB_AddressId,
|
|
hIOPort->TPCB_CallHandle,
|
|
SetPPP,
|
|
sizeof(RASTAPI_DEV_SPECIFIC));
|
|
|
|
if ( hIOPort->TPCB_ModeRequestId == 0
|
|
|| hIOPort->TPCB_ModeRequestId > 0x80000000)
|
|
{
|
|
|
|
LocalFree(SetPPP);
|
|
hIOPort->TPCB_ModeRequestId = INFINITE;
|
|
hIOPort->TPCB_ModeRequestDesc = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
return(SUCCESS);
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This API is called to drop a connection and close AsyncMac.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
PENDING
|
|
ERROR_PORT_NOT_OPEN
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
PortDisconnect(HANDLE hPort)
|
|
{
|
|
DWORD retcode = SUCCESS ;
|
|
TapiPortControlBlock *hIOPort = (TapiPortControlBlock *) hPort;
|
|
|
|
if(NULL == hIOPort)
|
|
{
|
|
RasTapiTrace("PortDisconnect: hioport==NULL");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
RasTapiTrace("PortDisconnect: %s", hIOPort->TPCB_Name );
|
|
|
|
if ( (hIOPort->TPCB_State == PS_CONNECTED)
|
|
|| (hIOPort->TPCB_State == PS_CONNECTING)
|
|
|| ( (hIOPort->TPCB_State == PS_LISTENING)
|
|
&& (hIOPort->TPCB_ListenState != LS_WAIT)))
|
|
{
|
|
|
|
retcode = InitiatePortDisconnection (hIOPort) ;
|
|
|
|
//
|
|
// If we had saved away the device config then we
|
|
// restore it here.
|
|
//
|
|
if (hIOPort->TPCB_DefaultDevConfig)
|
|
{
|
|
lineSetDevConfig (hIOPort->TPCB_Line->TLI_LineId,
|
|
hIOPort->TPCB_DefaultDevConfig,
|
|
hIOPort->TPCB_DefaultDevConfigSize,
|
|
"comm/datamodem") ;
|
|
|
|
LocalFree (hIOPort->TPCB_DefaultDevConfig) ;
|
|
|
|
hIOPort->TPCB_DefaultDevConfig = NULL ;
|
|
}
|
|
}
|
|
else if (hIOPort->TPCB_State == PS_LISTENING)
|
|
{
|
|
RasTapiTrace ("PortDisconnect: Changing State"
|
|
" of %s from %d -> %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_State,
|
|
PS_OPEN );
|
|
//
|
|
// for LS_WAIT listen state case
|
|
//
|
|
hIOPort->TPCB_State = PS_OPEN ;
|
|
|
|
retcode = SUCCESS ;
|
|
|
|
}
|
|
else if (hIOPort->TPCB_State == PS_DISCONNECTING)
|
|
{
|
|
|
|
retcode = PENDING ;
|
|
}
|
|
|
|
if (hIOPort->TPCB_Line->CharModeSupported)
|
|
{
|
|
|
|
hIOPort->TPCB_RecvFifo->In =
|
|
hIOPort->TPCB_RecvFifo->Out =
|
|
hIOPort->TPCB_RecvFifo->Count = 0;
|
|
|
|
}
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
return retcode ;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This API re-initializes the com port after use.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
ERROR_PORT_NOT_CONFIGURED
|
|
ERROR_DEVICE_NOT_READY
|
|
|
|
--*/
|
|
|
|
DWORD APIENTRY
|
|
PortInit(HANDLE hIOPort)
|
|
{
|
|
return(SUCCESS);
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This API sends a buffer to the port. This API is
|
|
asynchronous and normally returns PENDING; however, if
|
|
WriteFile returns synchronously, the API will return
|
|
SUCCESS.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
PENDING
|
|
Return code from GetLastError
|
|
|
|
--*/
|
|
DWORD
|
|
PortSend(
|
|
HANDLE hPort, BYTE *pBuffer,
|
|
DWORD dwSize
|
|
)
|
|
{
|
|
TapiPortControlBlock *hIOPort =
|
|
(TapiPortControlBlock *) hPort;
|
|
DWORD retcode ;
|
|
DWORD pdwBytesWritten;
|
|
BOOL bIODone;
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
if (_stricmp (hIOPort->TPCB_DeviceType,
|
|
DEVICETYPE_UNIMODEM) == 0)
|
|
{
|
|
// DbgPrint("sending %c\n", (CHAR) *pBuffer);
|
|
|
|
// Send Buffer to Port
|
|
//
|
|
bIODone = WriteFile(
|
|
hIOPort->TPCB_CommHandle,
|
|
pBuffer,
|
|
dwSize,
|
|
&pdwBytesWritten,
|
|
(LPOVERLAPPED)&(hIOPort->TPCB_WriteOverlapped));
|
|
|
|
if (bIODone)
|
|
{
|
|
retcode = PENDING;
|
|
}
|
|
|
|
else if ((retcode = GetLastError()) == ERROR_IO_PENDING)
|
|
{
|
|
retcode = PENDING ;
|
|
}
|
|
|
|
}
|
|
else if (hIOPort->TPCB_Line->CharModeSupported)
|
|
{
|
|
|
|
PRASTAPI_DEV_SPECIFIC TapiSend;
|
|
DWORD TapiSendSize;
|
|
|
|
if (hIOPort->TPCB_State != PS_CONNECTED)
|
|
{
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
return SUCCESS;
|
|
}
|
|
|
|
TapiSendSize = sizeof(RASTAPI_DEV_SPECIFIC) + dwSize;
|
|
|
|
if ((TapiSend = LocalAlloc(LPTR, TapiSendSize)) == NULL)
|
|
{
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex(RasTapiMutex);
|
|
return(GetLastError());
|
|
}
|
|
|
|
TapiSend->Command = RASTAPI_DEV_SEND;
|
|
TapiSend->DataSize = dwSize;
|
|
memcpy(TapiSend->Data, pBuffer, dwSize);
|
|
|
|
hIOPort->TPCB_SendDesc = TapiSend;
|
|
hIOPort->TPCB_CharMode = TRUE;
|
|
|
|
hIOPort->TPCB_SendRequestId =
|
|
lineDevSpecific(hIOPort->TPCB_Line->TLI_LineHandle,
|
|
hIOPort->TPCB_AddressId,
|
|
hIOPort->TPCB_CallHandle,
|
|
TapiSend,
|
|
TapiSendSize);
|
|
|
|
if (hIOPort->TPCB_SendRequestId == 0)
|
|
{
|
|
//
|
|
// Do I need to set the event?
|
|
//
|
|
LocalFree(TapiSend);
|
|
|
|
hIOPort->TPCB_SendDesc = NULL;
|
|
|
|
hIOPort->TPCB_SendRequestId = INFINITE;
|
|
|
|
retcode = SUCCESS;
|
|
|
|
}
|
|
else if (hIOPort->TPCB_SendRequestId > 0x80000000)
|
|
{
|
|
|
|
LocalFree(TapiSend);
|
|
|
|
hIOPort->TPCB_SendDesc = NULL;
|
|
|
|
hIOPort->TPCB_SendRequestId = INFINITE;
|
|
|
|
retcode = ERROR_FROM_DEVICE;
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// The request has been pended. We need to free the
|
|
// buffer at completion time.
|
|
//
|
|
//
|
|
retcode = PENDING;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
retcode = SUCCESS;
|
|
}
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
return retcode ;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This API reads from the port. This API is
|
|
asynchronous and normally returns PENDING; however, if
|
|
ReadFile returns synchronously, the API will return
|
|
SUCCESS.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
PENDING
|
|
Return code from GetLastError
|
|
|
|
--*/
|
|
DWORD
|
|
PortReceive(HANDLE hPort,
|
|
BYTE *pBuffer,
|
|
DWORD dwSize,
|
|
DWORD dwTimeOut)
|
|
{
|
|
TapiPortControlBlock *hIOPort
|
|
= (TapiPortControlBlock *) hPort;
|
|
COMMTIMEOUTS CT;
|
|
DWORD pdwBytesRead;
|
|
BOOL bIODone;
|
|
DWORD retcode ;
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
if (_stricmp (hIOPort->TPCB_DeviceType,
|
|
DEVICETYPE_UNIMODEM) == 0)
|
|
{
|
|
|
|
// Set Read Timeouts
|
|
|
|
CT.ReadIntervalTimeout = 0;
|
|
|
|
CT.ReadTotalTimeoutMultiplier = 0;
|
|
|
|
CT.ReadTotalTimeoutConstant = dwTimeOut;
|
|
|
|
if (!SetCommTimeouts(hIOPort->TPCB_CommHandle, &CT))
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
|
|
RasTapiTrace("PorTReceive: SetCommTimeouts failed "
|
|
"for %s. %d", hIOPort->TPCB_Name,
|
|
dwError);
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
return(dwError);
|
|
}
|
|
|
|
//
|
|
// Read from Port
|
|
//
|
|
bIODone = ReadFile(hIOPort->TPCB_CommHandle,
|
|
pBuffer,
|
|
dwSize,
|
|
&pdwBytesRead,
|
|
(LPOVERLAPPED) &(hIOPort->TPCB_ReadOverlapped));
|
|
|
|
if (bIODone)
|
|
{
|
|
retcode = PENDING;
|
|
}
|
|
|
|
else if ((retcode = GetLastError()) == ERROR_IO_PENDING)
|
|
{
|
|
retcode = PENDING;
|
|
}
|
|
|
|
}
|
|
else if (hIOPort->TPCB_Line->CharModeSupported)
|
|
{
|
|
|
|
if (hIOPort->TPCB_State != PS_CONNECTED)
|
|
{
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
return SUCCESS;
|
|
}
|
|
|
|
//
|
|
// What to do about timeouts?
|
|
//
|
|
hIOPort->TPCB_RasmanRecvBuffer = pBuffer;
|
|
hIOPort->TPCB_RasmanRecvBufferSize = dwSize;
|
|
|
|
//
|
|
// If we already have some data buffered
|
|
// go ahead and notify
|
|
//
|
|
if (hIOPort->TPCB_RecvFifo->Count > 0)
|
|
{
|
|
//
|
|
//SetEvent(hAsyncEvent);
|
|
//
|
|
PostNotificationCompletion( hIOPort );
|
|
}
|
|
else
|
|
{
|
|
}
|
|
|
|
retcode = PENDING;
|
|
}
|
|
else
|
|
{
|
|
retcode = SUCCESS ;
|
|
}
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
return retcode ;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Completes a read - if still PENDING it cancels it -
|
|
else it returns the bytes read. PortClearStatistics.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
|
|
--*/
|
|
DWORD
|
|
PortReceiveComplete (HANDLE hPort, PDWORD bytesread)
|
|
{
|
|
TapiPortControlBlock *hIOPort =
|
|
(TapiPortControlBlock *) hPort;
|
|
|
|
DWORD retcode = SUCCESS;
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
if (!GetOverlappedResult(
|
|
hIOPort->TPCB_CommHandle,
|
|
(LPOVERLAPPED)&(hIOPort->TPCB_ReadOverlapped),
|
|
bytesread,
|
|
FALSE))
|
|
{
|
|
retcode = GetLastError() ;
|
|
|
|
RasTapiTrace("PortReceiveComplete: GetOverlappedResult "
|
|
"Failed.%s, %d", hIOPort->TPCB_Name,
|
|
retcode );
|
|
|
|
PurgeComm (hIOPort->TPCB_CommHandle, PURGE_RXABORT) ;
|
|
*bytesread = 0 ;
|
|
|
|
}
|
|
else if (hIOPort->TPCB_Line->CharModeSupported)
|
|
{
|
|
|
|
*bytesread =
|
|
CopyDataFromFifo(hIOPort->TPCB_RecvFifo,
|
|
hIOPort->TPCB_RasmanRecvBuffer,
|
|
hIOPort->TPCB_RasmanRecvBufferSize);
|
|
|
|
hIOPort->TPCB_RasmanRecvBuffer = NULL;
|
|
hIOPort->TPCB_RasmanRecvBufferSize = 0;
|
|
}
|
|
else
|
|
{
|
|
retcode = SUCCESS ;
|
|
}
|
|
|
|
// **** Exclusion END ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
return retcode ;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This API selects Asyncmac compression mode
|
|
by setting Asyncmac's compression bits.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
Return code from GetLastError
|
|
|
|
--*/
|
|
DWORD
|
|
PortCompressionSetInfo(HANDLE hIOPort)
|
|
{
|
|
return SUCCESS;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This API is used to mark the beginning of the
|
|
period for which statistics will be reported.
|
|
The current numbers are copied from the MAC and
|
|
stored in the Serial Port Control Block. At
|
|
the end of the period PortGetStatistics will be
|
|
called to compute the difference.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
ERROR_PORT_NOT_OPEN
|
|
|
|
--*/
|
|
DWORD
|
|
PortClearStatistics(HANDLE hIOPort)
|
|
{
|
|
return SUCCESS;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This API reports MAC statistics since the last call to
|
|
PortClearStatistics.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
ERROR_PORT_NOT_OPEN
|
|
|
|
--*/
|
|
DWORD
|
|
PortGetStatistics(
|
|
HANDLE hIOPort,
|
|
RAS_STATISTICS *pStat
|
|
)
|
|
{
|
|
return(SUCCESS);
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets the framing type with the mac
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
PortSetFraming(
|
|
HANDLE hIOPort,
|
|
DWORD SendFeatureBits,
|
|
DWORD RecvFeatureBits,
|
|
DWORD SendBitMask,
|
|
DWORD RecvBitMask
|
|
)
|
|
{
|
|
|
|
return(SUCCESS);
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This API is used in MS-DOS only.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
PortGetPortState(char *pszPortName, DWORD *pdwUsage)
|
|
{
|
|
return(SUCCESS);
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This API is used in MS-DOS only.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
PortChangeCallback(HANDLE hIOPort)
|
|
{
|
|
return(SUCCESS);
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
For the given hIOPort this returns the file
|
|
handle for the connection
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
SUCCESS
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
PortGetIOHandle(HANDLE hPort, HANDLE *FileHandle)
|
|
{
|
|
DWORD retcode ;
|
|
TapiPortControlBlock *hIOPort = (TapiPortControlBlock *) hPort;
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
if (hIOPort->TPCB_State == PS_CONNECTED)
|
|
{
|
|
//
|
|
// purge the comm since it may still have
|
|
// characters from modem responses
|
|
//
|
|
RasTapiTrace("PortGetIOHandle: Purging Comm %s",
|
|
hIOPort->TPCB_Name );
|
|
|
|
Sleep ( 10 );
|
|
|
|
PurgeComm (hIOPort->TPCB_CommHandle,
|
|
PURGE_RXABORT
|
|
| PURGE_TXCLEAR
|
|
| PURGE_RXCLEAR );
|
|
|
|
*FileHandle = hIOPort->TPCB_CommHandle ;
|
|
retcode = SUCCESS ;
|
|
}
|
|
else
|
|
{
|
|
RasTapiTrace("PortGetIOHandle: %s. port not "
|
|
"open. State = %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_Name);
|
|
|
|
retcode = ERROR_PORT_NOT_OPEN ;
|
|
}
|
|
|
|
// **** Exclusion Begin ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
return retcode ;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Enumerates all devices in the device INF file for the
|
|
specified DevictType.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
Return codes from RasDevEnumDevices
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
DeviceEnum (char *pszDeviceType,
|
|
DWORD *pcEntries,
|
|
BYTE *pBuffer,
|
|
DWORD *pdwSize)
|
|
{
|
|
*pdwSize = 0 ;
|
|
*pcEntries = 0 ;
|
|
|
|
return(SUCCESS);
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns a summary of current information from
|
|
the InfoTable for the device on the port in Pcb.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
Return codes from GetDeviceCB, BuildOutputTable
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
DeviceGetInfo(HANDLE hPort,
|
|
char *pszDeviceType,
|
|
char *pszDeviceName,
|
|
BYTE *pInfo,
|
|
DWORD *pdwSize)
|
|
{
|
|
DWORD retcode ;
|
|
TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
|
|
|
|
if (!hIOPort)
|
|
{
|
|
RasTapiTrace("DeviceGetInfo: Port Not "
|
|
"found. hPort = 0x%x ",
|
|
hPort );
|
|
|
|
return ERROR_PORT_NOT_FOUND ;
|
|
}
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
retcode = GetInfo (hIOPort, pInfo, pdwSize) ;
|
|
|
|
|
|
// **** Exclusion End ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
return(retcode);
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets attributes in the InfoTable for the device on the
|
|
port in Pcb.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
Return codes from GetDeviceCB, UpdateInfoTable
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
DeviceSetInfo(HANDLE hPort,
|
|
char *pszDeviceType,
|
|
char *pszDeviceName,
|
|
RASMAN_DEVICEINFO *pInfo)
|
|
{
|
|
DWORD retcode ;
|
|
TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
|
|
|
|
if (!hIOPort)
|
|
{
|
|
RasTapiTrace ("DeviceSetInfo: Port not "
|
|
"found. hPort = 0x%x",
|
|
hPort );
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return ERROR_PORT_NOT_FOUND ;
|
|
}
|
|
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
retcode = SetInfo (hIOPort, (RASMAN_PORTINFO*) pInfo) ;
|
|
|
|
// **** Exclusion End ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
return (retcode);
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initiates the process of connecting a device.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
Return codes from ConnectListen
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
DeviceConnect(HANDLE hPort,
|
|
char *pszDeviceType,
|
|
char *pszDeviceName)
|
|
{
|
|
LINECALLPARAMS *linecallparams ;
|
|
LPVARSTRING var ;
|
|
BYTE buffer [2000] ;
|
|
BYTE *nextstring ;
|
|
TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
|
|
|
|
if (!hIOPort)
|
|
{
|
|
RasTapiTrace ("DeviceConnect: %s not found",
|
|
( pszDeviceName
|
|
? pszDeviceName
|
|
: "NULL"));
|
|
|
|
return ERROR_PORT_NOT_FOUND ;
|
|
}
|
|
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
//
|
|
// Check to see if the port is in disconnecting state
|
|
//
|
|
if ( hIOPort->TPCB_State != PS_OPEN )
|
|
{
|
|
|
|
#if DBG
|
|
DbgPrint("RASTAPI: port is not "
|
|
"in PS_OPEN state. State = %d \n",
|
|
hIOPort->TPCB_State );
|
|
#endif
|
|
|
|
RasTapiTrace ("DeviceConnect: Device %s is not"
|
|
" in PS_OPEN state state = %d",
|
|
(pszDeviceName)
|
|
? pszDeviceName
|
|
: "NULL",
|
|
hIOPort->TPCB_State );
|
|
|
|
FreeMutex ( RasTapiMutex );
|
|
|
|
return ERROR_PORT_NOT_AVAILABLE;
|
|
}
|
|
|
|
//
|
|
// if dev config has been set for this device we
|
|
// should call down and set it.
|
|
//
|
|
if ( (hIOPort->TPCB_DevConfig)
|
|
&& (_stricmp (hIOPort->TPCB_DeviceType,
|
|
DEVICETYPE_UNIMODEM) == 0))
|
|
{
|
|
RAS_DEVCONFIG *pDevConfig;
|
|
|
|
//
|
|
// Before the write this - save away the current
|
|
// setting for the device.
|
|
//
|
|
var = (LPVARSTRING)buffer ;
|
|
|
|
var->dwTotalSize = 2000 ;
|
|
|
|
var->dwStringSize = 0 ;
|
|
|
|
lineGetDevConfig (hIOPort->TPCB_Line->TLI_LineId,
|
|
var,
|
|
"comm/datamodem") ;
|
|
|
|
if(NULL != hIOPort->TPCB_DefaultDevConfig)
|
|
{
|
|
LocalFree(hIOPort->TPCB_DefaultDevConfig);
|
|
hIOPort->TPCB_DefaultDevConfig = NULL;
|
|
}
|
|
|
|
//
|
|
// Alloc mem for the returned info. If memory allocation
|
|
// fails, its not really fatal - we will just fail to
|
|
// save the dev config - we will try allocating again
|
|
// when this api is called next.
|
|
//
|
|
|
|
hIOPort->TPCB_DefaultDevConfigSize = 0;
|
|
|
|
hIOPort->TPCB_DefaultDevConfig =
|
|
LocalAlloc (LPTR, var->dwStringSize) ;
|
|
|
|
if(NULL != hIOPort->TPCB_DefaultDevConfig)
|
|
{
|
|
|
|
hIOPort->TPCB_DefaultDevConfigSize = var->dwStringSize ;
|
|
|
|
memcpy (hIOPort->TPCB_DefaultDevConfig,
|
|
(CHAR*)var+var->dwStringOffset,
|
|
var->dwStringSize) ;
|
|
}
|
|
|
|
pDevConfig = (RAS_DEVCONFIG *) hIOPort->TPCB_DevConfig;
|
|
|
|
lineSetDevConfig (hIOPort->TPCB_Line->TLI_LineId,
|
|
(PBYTE) ((PBYTE) pDevConfig +
|
|
pDevConfig->dwOffsetofModemSettings),
|
|
pDevConfig->dwSizeofModemSettings,
|
|
"comm/datamodem") ;
|
|
|
|
}
|
|
|
|
memset (buffer, 0, sizeof(buffer)) ;
|
|
|
|
linecallparams = (LINECALLPARAMS *) buffer ;
|
|
|
|
nextstring = (buffer + sizeof (LINECALLPARAMS)) ;
|
|
|
|
linecallparams->dwTotalSize = sizeof(buffer) ;
|
|
|
|
strcpy (nextstring, hIOPort->TPCB_Address) ;
|
|
|
|
linecallparams->dwOrigAddressSize = strlen (nextstring) ;
|
|
|
|
linecallparams->dwOrigAddressOffset = (DWORD)(nextstring - buffer) ;
|
|
|
|
linecallparams->dwAddressMode = LINEADDRESSMODE_DIALABLEADDR ;
|
|
|
|
nextstring += linecallparams->dwOrigAddressSize ;
|
|
|
|
if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_ISDN) == 0)
|
|
{
|
|
SetIsdnParams (hIOPort, linecallparams) ;
|
|
}
|
|
else if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_X25) == 0)
|
|
{
|
|
|
|
if (*hIOPort->TPCB_Info[X25_USERDATA_INDEX] != '\0')
|
|
{
|
|
|
|
strcpy (nextstring,
|
|
hIOPort->TPCB_Info[X25_USERDATA_INDEX]) ;
|
|
|
|
linecallparams->dwUserUserInfoSize =
|
|
strlen (nextstring) ;
|
|
|
|
linecallparams->dwUserUserInfoOffset =
|
|
(DWORD)(nextstring - buffer) ;
|
|
|
|
nextstring += linecallparams->dwUserUserInfoSize ;
|
|
|
|
}
|
|
|
|
if (*hIOPort->TPCB_Info[X25_FACILITIES_INDEX] != '\0')
|
|
{
|
|
|
|
strcpy (nextstring, hIOPort->TPCB_Info[X25_FACILITIES_INDEX]) ;
|
|
|
|
linecallparams->dwDevSpecificSize =
|
|
strlen (nextstring) ;
|
|
|
|
linecallparams->dwDevSpecificOffset =
|
|
(DWORD)(nextstring - buffer) ;
|
|
|
|
nextstring += linecallparams->dwDevSpecificSize ;
|
|
}
|
|
|
|
//
|
|
// Diagnostic key is ignored.
|
|
//
|
|
SetX25Params(hIOPort, linecallparams);
|
|
|
|
}
|
|
else if (_stricmp (hIOPort->TPCB_DeviceType,
|
|
DEVICETYPE_UNIMODEM) == 0)
|
|
{
|
|
SetModemParams (hIOPort, linecallparams) ;
|
|
|
|
} else if (_stricmp(hIOPort->TPCB_DeviceType,
|
|
DEVICETYPE_ATM) == 0)
|
|
{
|
|
SetAtmParams (hIOPort, linecallparams) ;
|
|
} else
|
|
{
|
|
SetGenericParams(hIOPort, linecallparams);
|
|
}
|
|
|
|
//
|
|
// mark request id as unused
|
|
//
|
|
hIOPort->TPCB_RequestId = INFINITE ;
|
|
|
|
//
|
|
// set call handle to bogus value
|
|
//
|
|
hIOPort->TPCB_CallHandle = (HCALL) INFINITE ;
|
|
|
|
hIOPort->TPCB_AsyncErrorCode = SUCCESS ;
|
|
|
|
RasTapiTrace ("DeviceConnect: calling lineMakeCall"
|
|
" for %s, address=%s",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_Info[ADDRESS_INDEX] );
|
|
|
|
if ((hIOPort->TPCB_RequestId =
|
|
lineMakeCall (hIOPort->TPCB_Line->TLI_LineHandle,
|
|
&hIOPort->TPCB_CallHandle,
|
|
hIOPort->TPCB_Info[ADDRESS_INDEX],
|
|
0,
|
|
linecallparams)) > 0x80000000 )
|
|
{
|
|
|
|
RasTapiTrace ("DeviceConnect: lineMakeCall"
|
|
" Failed for %s. 0x%x",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_RequestId );
|
|
|
|
// **** Exclusion End ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
if (hIOPort->TPCB_RequestId == LINEERR_INUSE)
|
|
{
|
|
RasTapiTrace("DeviceConnect: ERROR_PORT_NOT_AVAILABLE");
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return ERROR_PORT_NOT_AVAILABLE ;
|
|
}
|
|
|
|
RasTapiTrace("DeviceConnect: ERROR_FROM_DEVICE");
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return ERROR_FROM_DEVICE ;
|
|
|
|
}
|
|
|
|
RasTapiTrace ("DeviceConnect: Changing state for %s"
|
|
" from %d -> %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_State,
|
|
PS_CONNECTING );
|
|
|
|
hIOPort->TPCB_State = PS_CONNECTING ;
|
|
|
|
hIOPort->TPCB_DisconnectReason = 0 ;
|
|
|
|
// **** Exclusion End ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
return (PENDING);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
SetIsdnParams (
|
|
TapiPortControlBlock *hIOPort,
|
|
LINECALLPARAMS *linecallparams
|
|
)
|
|
{
|
|
WORD numchannels ;
|
|
WORD fallback ;
|
|
|
|
//
|
|
// Line type
|
|
//
|
|
if (_stricmp (hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX],
|
|
ISDN_LINETYPE_STRING_64DATA) == 0)
|
|
{
|
|
linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
|
|
|
|
linecallparams->dwMinRate = 64000 ;
|
|
|
|
linecallparams->dwMaxRate = 64000 ;
|
|
|
|
linecallparams->dwMediaMode = LINEMEDIAMODE_DIGITALDATA ;
|
|
|
|
}
|
|
else if (_stricmp (hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX],
|
|
ISDN_LINETYPE_STRING_56DATA) == 0)
|
|
{
|
|
linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
|
|
|
|
linecallparams->dwMinRate = 56000 ;
|
|
|
|
linecallparams->dwMaxRate = 56000 ;
|
|
|
|
linecallparams->dwMediaMode = LINEMEDIAMODE_DIGITALDATA ;
|
|
|
|
}
|
|
else if (_stricmp (hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX],
|
|
ISDN_LINETYPE_STRING_56VOICE) == 0)
|
|
{
|
|
linecallparams->dwBearerMode = LINEBEARERMODE_VOICE ;
|
|
|
|
linecallparams->dwMinRate = 56000 ;
|
|
|
|
linecallparams->dwMaxRate = 56000 ;
|
|
|
|
linecallparams->dwMediaMode = LINEMEDIAMODE_UNKNOWN ;
|
|
}
|
|
else
|
|
{ // default
|
|
linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
|
|
|
|
linecallparams->dwMinRate = 64000 ;
|
|
|
|
linecallparams->dwMaxRate = 64000 ;
|
|
|
|
linecallparams->dwMediaMode = LINEMEDIAMODE_DIGITALDATA ;
|
|
}
|
|
|
|
if (hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX][0] != '\0')
|
|
{
|
|
numchannels = (USHORT)atoi(hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX]) ;
|
|
}
|
|
else
|
|
{
|
|
numchannels = 1 ; // default
|
|
}
|
|
|
|
if (hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX] != '\0')
|
|
{
|
|
fallback = (USHORT)atoi(hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX]) ;
|
|
}
|
|
else
|
|
{
|
|
fallback = 1 ; // default
|
|
}
|
|
|
|
if (fallback)
|
|
{
|
|
//
|
|
// always allow the min
|
|
//
|
|
linecallparams->dwMinRate = 56000 ;
|
|
}
|
|
else
|
|
{
|
|
linecallparams->dwMinRate =
|
|
numchannels * linecallparams->dwMaxRate ;
|
|
}
|
|
|
|
linecallparams->dwMaxRate =
|
|
numchannels * linecallparams->dwMaxRate ;
|
|
|
|
}
|
|
|
|
VOID
|
|
SetModemParams(
|
|
TapiPortControlBlock *hIOPort,
|
|
LINECALLPARAMS *linecallparams
|
|
)
|
|
{
|
|
WORD numchannels ;
|
|
WORD fallback ;
|
|
BYTE buffer[800] ;
|
|
LINEDEVCAPS *linedevcaps ;
|
|
|
|
memset (buffer, 0, sizeof(buffer)) ;
|
|
|
|
linedevcaps = (LINEDEVCAPS *)buffer ;
|
|
linedevcaps->dwTotalSize = sizeof(buffer) ;
|
|
|
|
//
|
|
// Get a count of all addresses across all lines
|
|
//
|
|
if (lineGetDevCaps (RasLine,
|
|
hIOPort->TPCB_Line->TLI_LineId,
|
|
hIOPort->TPCB_Line->NegotiatedApiVersion,
|
|
hIOPort->TPCB_Line->NegotiatedExtVersion,
|
|
linedevcaps))
|
|
{
|
|
linecallparams->dwBearerMode = LINEBEARERMODE_VOICE;
|
|
}
|
|
|
|
if (linedevcaps->dwBearerModes & LINEBEARERMODE_VOICE)
|
|
{
|
|
linecallparams->dwBearerMode = LINEBEARERMODE_VOICE ;
|
|
}
|
|
else
|
|
{
|
|
linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
|
|
}
|
|
|
|
//
|
|
// do not dial without dialtone
|
|
//
|
|
linecallparams->dwCallParamFlags |= LINECALLPARAMFLAGS_IDLE ;
|
|
|
|
linecallparams->dwMinRate = 2400 ;
|
|
|
|
linecallparams->dwMaxRate = 115200 ;
|
|
|
|
linecallparams->dwMediaMode = LINEMEDIAMODE_DATAMODEM ;
|
|
}
|
|
|
|
VOID
|
|
SetAtmParams (
|
|
TapiPortControlBlock *hIOPort,
|
|
LINECALLPARAMS *linecallparams
|
|
)
|
|
{
|
|
linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
|
|
|
|
//
|
|
// Tell ATM to use the default rates of the underlying
|
|
// miniport adapter.
|
|
//
|
|
linecallparams->dwMinRate = 0;
|
|
linecallparams->dwMaxRate = 0;
|
|
|
|
linecallparams->dwMediaMode = LINEMEDIAMODE_DIGITALDATA ;
|
|
}
|
|
|
|
VOID
|
|
SetGenericParams (
|
|
TapiPortControlBlock *hIOPort,
|
|
LINECALLPARAMS *linecallparams
|
|
)
|
|
{
|
|
linecallparams->dwBearerMode = LINEBEARERMODE_DATA ;
|
|
|
|
linecallparams->dwMinRate = 64000;
|
|
|
|
linecallparams->dwMaxRate = 10000000;
|
|
|
|
linecallparams->dwMediaMode = LINEMEDIAMODE_DIGITALDATA ;
|
|
}
|
|
|
|
VOID
|
|
SetX25Params(TapiPortControlBlock *hIOPort,
|
|
LINECALLPARAMS *linecallparams)
|
|
{
|
|
BYTE buffer[800] ;
|
|
LINEDEVCAPS *linedevcaps ;
|
|
|
|
memset (buffer, 0, sizeof(buffer)) ;
|
|
|
|
linedevcaps = (LINEDEVCAPS *)buffer ;
|
|
linedevcaps->dwTotalSize = sizeof(buffer) ;
|
|
|
|
//
|
|
// Get a count of all addresses across all lines
|
|
//
|
|
if (lineGetDevCaps (RasLine,
|
|
hIOPort->TPCB_Line->TLI_LineId,
|
|
hIOPort->TPCB_Line->NegotiatedApiVersion,
|
|
hIOPort->TPCB_Line->NegotiatedExtVersion,
|
|
linedevcaps))
|
|
{
|
|
|
|
//
|
|
// go for the gold!!!
|
|
//
|
|
linecallparams->dwMaxRate = 0xFFFFFFFF;
|
|
|
|
linecallparams->dwMediaMode = LINEMEDIAMODE_UNKNOWN;
|
|
|
|
} else
|
|
{
|
|
linecallparams->dwMaxRate = linedevcaps->dwMaxRate;
|
|
|
|
if (linedevcaps->dwMediaModes & LINEMEDIAMODE_DIGITALDATA)
|
|
{
|
|
linecallparams->dwMediaMode = LINEMEDIAMODE_DIGITALDATA;
|
|
|
|
}
|
|
else if (linedevcaps->dwMediaModes & LINEMEDIAMODE_DATAMODEM)
|
|
{
|
|
linecallparams->dwMediaMode = LINEMEDIAMODE_DATAMODEM;
|
|
}
|
|
else
|
|
{
|
|
linecallparams->dwMediaMode = LINEMEDIAMODE_UNKNOWN;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initiates the process of listening for a remote device
|
|
to connect to a local device.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
Return codes from ConnectListen
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
DeviceListen(HANDLE hPort,
|
|
char *pszDeviceType,
|
|
char *pszDeviceName)
|
|
{
|
|
DWORD retcode ;
|
|
TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
|
|
|
|
if (!hIOPort)
|
|
{
|
|
RasTapiTrace ("DeviceListen: hPort "
|
|
"= 0x%x not found",
|
|
hPort );
|
|
|
|
return ERROR_PORT_NOT_FOUND ;
|
|
}
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
RasTapiTrace("DeviceListen: %s. State = %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_State );
|
|
|
|
//
|
|
// If the state is DISCONNECTING (this could happen
|
|
// since rasman waits only 10 seconds for the lower
|
|
// layers to complete a disconnect request), then
|
|
// we have no option but to close and open the line.
|
|
//
|
|
if (hIOPort->TPCB_State == PS_DISCONNECTING &&
|
|
!hIOPort->TPCB_Line->TLI_MultiEndpoint)
|
|
{
|
|
|
|
RasTapiTrace ("DeviceListen: Hammering LineClosed!");
|
|
|
|
lineClose (hIOPort->TPCB_Line->TLI_LineHandle) ;
|
|
|
|
Sleep (30L) ;
|
|
|
|
retcode = lineOpen (RasLine,
|
|
hIOPort->TPCB_Line->TLI_LineId,
|
|
&hIOPort->TPCB_Line->TLI_LineHandle,
|
|
hIOPort->TPCB_Line->NegotiatedApiVersion,
|
|
hIOPort->TPCB_Line->NegotiatedExtVersion,
|
|
(DWORD_PTR) hIOPort->TPCB_Line,
|
|
LINECALLPRIVILEGE_OWNER,
|
|
hIOPort->TPCB_Line->TLI_MediaMode,
|
|
NULL) ;
|
|
|
|
if (retcode)
|
|
{
|
|
|
|
RasTapiTrace ("DeviceListen: %s. lineOpen"
|
|
" failed. 0x%x",
|
|
hIOPort->TPCB_Name,
|
|
retcode );
|
|
|
|
// **** Exclusion End ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return ERROR_FROM_DEVICE ;
|
|
}
|
|
|
|
//
|
|
// Set monitoring of rings
|
|
//
|
|
retcode = lineSetStatusMessages(
|
|
hIOPort->TPCB_Line->TLI_LineHandle,
|
|
LINEDEVSTATE_RINGING, 0) ;
|
|
|
|
if (retcode)
|
|
{
|
|
RasTapiTrace("DeviceListen: %s. Failed"
|
|
" to post listen. %d",
|
|
hIOPort->TPCB_Name,
|
|
retcode );
|
|
}
|
|
}
|
|
|
|
if (hIOPort->TPCB_Line->TLI_LineState != PS_LISTENING)
|
|
{
|
|
hIOPort->TPCB_Line->TLI_LineState = PS_LISTENING ;
|
|
}
|
|
|
|
RasTapiTrace ("DeviceListen: Changing State"
|
|
" for %s from %d -> %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_State,
|
|
PS_LISTENING );
|
|
|
|
hIOPort->TPCB_State = PS_LISTENING ;
|
|
|
|
RasTapiTrace ("DeviceListen: Changing Listen"
|
|
" State for %s from %d -> %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_ListenState,
|
|
PS_LISTENING );
|
|
|
|
hIOPort->TPCB_ListenState = LS_WAIT ;
|
|
|
|
hIOPort->TPCB_DisconnectReason = 0 ;
|
|
|
|
hIOPort->TPCB_CallHandle = -1 ;
|
|
|
|
// **** Exclusion End ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
return (PENDING);
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Informs the device dll that the attempt to connect or listen
|
|
has completed.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
nothing
|
|
|
|
--*/
|
|
VOID APIENTRY
|
|
DeviceDone(HANDLE hPort)
|
|
{
|
|
#ifdef notdef
|
|
TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
|
|
|
|
if (!hIOPort)
|
|
return ;
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
// **** Exclusion End ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
#endif
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is called following DeviceConnect or
|
|
DeviceListen to further the asynchronous process of
|
|
connecting or listening.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
ERROR_DCB_NOT_FOUND
|
|
ERROR_STATE_MACHINES_NOT_STARTED
|
|
Return codes from DeviceStateMachine
|
|
|
|
--*/
|
|
DWORD APIENTRY
|
|
DeviceWork(HANDLE hPort)
|
|
{
|
|
LINECALLSTATUS *callstatus ;
|
|
BYTE buffer [1000] ;
|
|
DWORD retcode = ERROR_FROM_DEVICE ;
|
|
TapiPortControlBlock *hIOPort =
|
|
LookUpControlBlock(hPort);
|
|
|
|
if (!hIOPort)
|
|
{
|
|
RasTapiTrace("DeviceWork: port 0x%x not found",
|
|
hPort );
|
|
|
|
return ERROR_PORT_NOT_FOUND ;
|
|
}
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
memset (buffer, 0, sizeof(buffer)) ;
|
|
|
|
callstatus = (LINECALLSTATUS *)buffer ;
|
|
callstatus->dwTotalSize = sizeof(buffer) ;
|
|
|
|
RasTapiTrace ("DeviceWork: %s. State = %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_State );
|
|
|
|
if (hIOPort->TPCB_State == PS_CONNECTING)
|
|
{
|
|
if (hIOPort->TPCB_AsyncErrorCode != SUCCESS)
|
|
{
|
|
|
|
retcode = hIOPort->TPCB_AsyncErrorCode ;
|
|
hIOPort->TPCB_AsyncErrorCode = SUCCESS ;
|
|
|
|
}
|
|
else if (lineGetCallStatus (hIOPort->TPCB_CallHandle,
|
|
callstatus))
|
|
{
|
|
RasTapiTrace( "DeviceWork: lineGetCallStatus failed");
|
|
|
|
retcode = ERROR_FROM_DEVICE ;
|
|
}
|
|
else if (callstatus->dwCallState ==
|
|
LINECALLSTATE_CONNECTED)
|
|
{
|
|
RasTapiTrace("DeviceWork: Changing state"
|
|
" for %s from %d -> %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_State,
|
|
PS_CONNECTED );
|
|
|
|
hIOPort->TPCB_State = PS_CONNECTED ;
|
|
|
|
retcode = SUCCESS ;
|
|
|
|
}
|
|
else if (callstatus->dwCallState ==
|
|
LINECALLSTATE_DISCONNECTED)
|
|
{
|
|
retcode = ERROR_FROM_DEVICE ;
|
|
|
|
/*
|
|
if (callstatus->dwCallStateMode ==
|
|
LINEDISCONNECTMODE_BUSY)
|
|
{
|
|
retcode = ERROR_LINE_BUSY ;
|
|
}
|
|
else if ( (callstatus->dwCallStateMode ==
|
|
LINEDISCONNECTMODE_NOANSWER)
|
|
|| (callstatus->dwCallStateMode ==
|
|
LINEDISCONNECTMODE_OUTOFORDER))
|
|
{
|
|
retcode = ERROR_NO_ANSWER ;
|
|
}
|
|
else if (callstatus->dwCallStateMode ==
|
|
LINEDISCONNECTMODE_CANCELLED)
|
|
{
|
|
retcode = ERROR_USER_DISCONNECTION;
|
|
}
|
|
|
|
*/
|
|
|
|
retcode = DwRasErrorFromDisconnectMode(
|
|
callstatus->dwCallStateMode);
|
|
|
|
RasTapiTrace("DeviceWork: callstate = 0x%x. "
|
|
"callmode = 0x%x, retcode %d",
|
|
callstatus->dwCallState,
|
|
callstatus->dwCallStateMode,
|
|
retcode );
|
|
|
|
}
|
|
else if ( (callstatus->dwCallState ==
|
|
LINECALLSTATE_SPECIALINFO)
|
|
&& (callstatus->dwCallStateMode ==
|
|
LINESPECIALINFO_NOCIRCUIT))
|
|
{
|
|
RasTapiTrace ("DeviceWork: ERROR_NO_ACTIVE_ISDN_LINES" );
|
|
|
|
retcode = ERROR_NO_ACTIVE_ISDN_LINES ;
|
|
}
|
|
}
|
|
|
|
if (hIOPort->TPCB_State == PS_LISTENING)
|
|
{
|
|
|
|
if (hIOPort->TPCB_ListenState == LS_ERROR)
|
|
{
|
|
RasTapiTrace ("DeviceWork: %s. ListenState = LS_ERROR",
|
|
hIOPort->TPCB_Name );
|
|
|
|
retcode = ERROR_FROM_DEVICE ;
|
|
}
|
|
else if (hIOPort->TPCB_ListenState == LS_ACCEPT)
|
|
{
|
|
|
|
hIOPort->TPCB_RequestId =
|
|
lineAccept (hIOPort->TPCB_CallHandle, NULL, 0) ;
|
|
|
|
RasTapiTrace( "DeviceWork: %s. lineAccept returned 0x%x",
|
|
hIOPort->TPCB_Name, hIOPort->TPCB_RequestId );
|
|
|
|
if (hIOPort->TPCB_RequestId > 0x80000000)
|
|
{
|
|
RasTapiTrace("DeviceWork: changing Listen"
|
|
" state for %s from %d -> %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_ListenState,
|
|
LS_ANSWER );
|
|
|
|
hIOPort->TPCB_ListenState = LS_ANSWER ;
|
|
}
|
|
|
|
else if (hIOPort->TPCB_RequestId == 0)
|
|
{
|
|
|
|
RasTapiTrace("DeviceWork: changing Listen "
|
|
"state for %s from %d -> %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_ListenState,
|
|
LS_ANSWER);
|
|
|
|
hIOPort->TPCB_ListenState = LS_ANSWER ;
|
|
}
|
|
|
|
retcode = PENDING ;
|
|
}
|
|
|
|
if (hIOPort->TPCB_ListenState == LS_ANSWER)
|
|
{
|
|
|
|
hIOPort->TPCB_RequestId =
|
|
lineAnswer (hIOPort->TPCB_CallHandle, NULL, 0) ;
|
|
|
|
RasTapiTrace("DeviceWork: %s. lineAnswer returned 0x%x",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_RequestId );
|
|
|
|
if (hIOPort->TPCB_RequestId > 0x80000000 )
|
|
{
|
|
RasTapiTrace("DeviceWork: lineAnswer returned "
|
|
"an error");
|
|
|
|
retcode = ERROR_FROM_DEVICE ;
|
|
}
|
|
|
|
else if (hIOPort->TPCB_RequestId)
|
|
{
|
|
retcode = PENDING ;
|
|
}
|
|
else
|
|
{
|
|
RasTapiTrace("DeviceWork: Changing Listen "
|
|
"state for %s from %d -> %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_ListenState,
|
|
LS_COMPLETE );
|
|
|
|
hIOPort->TPCB_ListenState = LS_COMPLETE ;
|
|
}
|
|
}
|
|
|
|
if (hIOPort->TPCB_ListenState == LS_COMPLETE)
|
|
{
|
|
|
|
if (hIOPort->TPCB_CallHandle == (-1))
|
|
{
|
|
retcode = ERROR_FROM_DEVICE ;
|
|
}
|
|
else
|
|
{
|
|
|
|
RasTapiTrace("DeviceWork: Changing State"
|
|
" for %s from %d -> %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_State,
|
|
PS_CONNECTED );
|
|
|
|
hIOPort->TPCB_State = PS_CONNECTED ;
|
|
|
|
retcode = SUCCESS ;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// If we have connected, then get the com port handle for
|
|
// use in terminal modem i/o
|
|
//
|
|
if (hIOPort->TPCB_State == PS_CONNECTED)
|
|
{
|
|
|
|
VARSTRING *varstring ;
|
|
BYTE buffer [100] ;
|
|
|
|
//
|
|
// get the cookie to realize tapi and ndis endpoints
|
|
//
|
|
varstring = (VARSTRING *) buffer ;
|
|
varstring->dwTotalSize = sizeof(buffer) ;
|
|
|
|
//
|
|
// Unimodem/asyncmac linegetid returns a comm port handle.
|
|
// Other medias give the endpoint itself back in linegetid
|
|
// This has to do with the fact that modems/asyncmac are
|
|
// not a miniport.
|
|
//
|
|
if (_stricmp (hIOPort->TPCB_DeviceType,
|
|
DEVICETYPE_UNIMODEM) == 0)
|
|
{
|
|
|
|
if ( retcode =
|
|
lineGetID (hIOPort->TPCB_Line->TLI_LineHandle,
|
|
hIOPort->TPCB_AddressId,
|
|
hIOPort->TPCB_CallHandle,
|
|
LINECALLSELECT_CALL,
|
|
varstring,
|
|
"comm/datamodem"))
|
|
{
|
|
RasTapiTrace("DeviceWork: %s lineGetID Failed. 0x%x",
|
|
hIOPort->TPCB_Name, retcode );
|
|
|
|
// **** Exclusion End ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
RasTapiTrace(" ");
|
|
|
|
return ERROR_FROM_DEVICE ;
|
|
}
|
|
|
|
hIOPort->TPCB_CommHandle =
|
|
(HANDLE) UlongToPtr((*((DWORD UNALIGNED *)
|
|
((BYTE *)varstring+varstring->dwStringOffset)))) ;
|
|
|
|
RasTapiTrace("DeviceWork: TPCB_CommHandle=%d",
|
|
hIOPort->TPCB_CommHandle );
|
|
|
|
//
|
|
// Create the I/O completion port for
|
|
// asynchronous operation completion
|
|
// notificiations.
|
|
//
|
|
if (CreateIoCompletionPort(
|
|
hIOPort->TPCB_CommHandle,
|
|
hIOPort->TPCB_IoCompletionPort,
|
|
hIOPort->TPCB_CompletionKey,
|
|
0) == NULL)
|
|
{
|
|
retcode = GetLastError();
|
|
|
|
RasTapiTrace("DeviceWork: %s. CreateIoCompletionPort "
|
|
"failed. %d",
|
|
hIOPort->TPCB_Name,
|
|
retcode );
|
|
|
|
FreeMutex(RasTapiMutex);
|
|
RasTapiTrace(" ");
|
|
|
|
return retcode;
|
|
}
|
|
|
|
//
|
|
// Initialize the port for approp. buffers
|
|
//
|
|
SetupComm (hIOPort->TPCB_CommHandle, 1514, 1514) ;
|
|
|
|
}
|
|
#if 0
|
|
|
|
else
|
|
{
|
|
|
|
if ( retcode = lineGetID (hIOPort->TPCB_Line->TLI_LineHandle,
|
|
hIOPort->TPCB_AddressId,
|
|
hIOPort->TPCB_CallHandle,
|
|
LINECALLSELECT_CALL,
|
|
varstring,
|
|
"NDIS"))
|
|
{
|
|
RasTapiTrace ("DeviceWork: %s. lineGetId Failed. 0x%x",
|
|
hIOPort->TPCB_Name,
|
|
retcode );
|
|
|
|
// **** Exclusion End ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return ERROR_FROM_DEVICE ;
|
|
}
|
|
|
|
hIOPort->TPCB_Endpoint =
|
|
*((HANDLE UNALIGNED *) ((BYTE *)varstring+varstring->dwStringOffset)) ;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// **** Exclusion End ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
return(retcode);
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Called to set an opaque blob of
|
|
data to configure a device.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
LocalAlloc returned values.
|
|
|
|
--*/
|
|
DWORD
|
|
DeviceSetDevConfig (
|
|
HANDLE hPort,
|
|
PBYTE devconfig,
|
|
DWORD sizeofdevconfig
|
|
)
|
|
{
|
|
TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
|
|
|
|
if (!hIOPort)
|
|
{
|
|
RasTapiTrace("DeviceSetDevConfig: port"
|
|
" 0x%x not found",
|
|
hPort );
|
|
|
|
return ERROR_PORT_NOT_FOUND ;
|
|
}
|
|
|
|
if (_stricmp (hIOPort->TPCB_DeviceType,
|
|
DEVICETYPE_UNIMODEM))
|
|
{
|
|
return SUCCESS ;
|
|
}
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
if (hIOPort->TPCB_DevConfig != NULL)
|
|
{
|
|
LocalFree (hIOPort->TPCB_DevConfig) ;
|
|
}
|
|
|
|
if ((hIOPort->TPCB_DevConfig =
|
|
LocalAlloc(LPTR, sizeofdevconfig)) == NULL)
|
|
{
|
|
|
|
// **** Exclusion End ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
return(GetLastError());
|
|
}
|
|
|
|
memcpy (hIOPort->TPCB_DevConfig,
|
|
devconfig,
|
|
sizeofdevconfig) ;
|
|
|
|
hIOPort->TPCB_SizeOfDevConfig = sizeofdevconfig ;
|
|
|
|
// **** Exclusion End ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
return (SUCCESS);
|
|
}
|
|
|
|
DWORD
|
|
DwGetConfigInfoForDeviceClass(
|
|
DWORD LineId,
|
|
CHAR *pszDeviceClass,
|
|
LPVARSTRING *ppVar)
|
|
{
|
|
LPVARSTRING var = NULL;
|
|
LONG lr;
|
|
DWORD dwNeededSize;
|
|
|
|
//
|
|
// Make var string
|
|
//
|
|
var = (LPVARSTRING)LocalAlloc(LPTR, 2000) ;
|
|
|
|
if(NULL == var)
|
|
{
|
|
lr = (LONG) GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
var->dwTotalSize = 2000 ;
|
|
|
|
if( (ERROR_SUCCESS != (lr = lineGetDevConfig (
|
|
LineId,
|
|
var,
|
|
pszDeviceClass)))
|
|
&& (LINEERR_STRUCTURETOOSMALL != lr))
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
if(var->dwNeededSize > 2000)
|
|
{
|
|
dwNeededSize = var->dwNeededSize;
|
|
|
|
LocalFree(var);
|
|
|
|
var = (LPVARSTRING) LocalAlloc(LPTR, dwNeededSize);
|
|
|
|
if(NULL == var)
|
|
{
|
|
lr = (LONG) GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
var->dwTotalSize = dwNeededSize;
|
|
|
|
lr = lineGetDevConfig(
|
|
LineId,
|
|
var,
|
|
pszDeviceClass);
|
|
}
|
|
|
|
done:
|
|
|
|
if(ERROR_SUCCESS != lr)
|
|
{
|
|
LocalFree(var);
|
|
var = NULL;
|
|
}
|
|
|
|
*ppVar = var;
|
|
|
|
return ((DWORD) lr);
|
|
}
|
|
|
|
|
|
DWORD
|
|
DwGetDevConfig(
|
|
DWORD LineId,
|
|
PBYTE pBuffer,
|
|
DWORD *pcbSize,
|
|
BOOL fDialIn)
|
|
{
|
|
DWORD dwSize;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
BYTE buffer[2000];
|
|
LPVARSTRING varModem = NULL,
|
|
varExtendedCaps = NULL;
|
|
|
|
if(NULL == pcbSize)
|
|
{
|
|
dwErr = E_INVALIDARG;
|
|
goto done;
|
|
}
|
|
|
|
dwSize = *pcbSize;
|
|
|
|
*pcbSize = 0;
|
|
|
|
if(fDialIn)
|
|
{
|
|
dwErr = DwGetConfigInfoForDeviceClass(
|
|
LineId,
|
|
"comm/datamodem/dialin",
|
|
&varModem);
|
|
|
|
}
|
|
else
|
|
{
|
|
dwErr = DwGetConfigInfoForDeviceClass(
|
|
LineId,
|
|
"comm/datamodem",
|
|
&varModem);
|
|
}
|
|
|
|
if(ERROR_SUCCESS != dwErr)
|
|
{
|
|
RasTapiTrace("DwGetDevConfig returned error=0x%x",
|
|
dwErr);
|
|
|
|
goto done;
|
|
}
|
|
|
|
dwErr = DwGetConfigInfoForDeviceClass(
|
|
LineId,
|
|
"comm/extendedcaps",
|
|
&varExtendedCaps);
|
|
|
|
if(ERROR_SUCCESS != dwErr)
|
|
{
|
|
/*
|
|
RasTapiTrace("DwGetDevConfig returned error=0x%x",
|
|
dwErr);
|
|
*/
|
|
|
|
//
|
|
// Ignore the error
|
|
//
|
|
dwErr = ERROR_SUCCESS;
|
|
}
|
|
|
|
*pcbSize = sizeof(RAS_DEVCONFIG)
|
|
+ varModem->dwStringSize
|
|
+ ((NULL != varExtendedCaps)
|
|
? varExtendedCaps->dwStringSize
|
|
: 0);
|
|
|
|
if(dwSize >= *pcbSize)
|
|
{
|
|
RAS_DEVCONFIG *pConfig = (RAS_DEVCONFIG *) pBuffer;
|
|
|
|
pConfig->dwOffsetofModemSettings =
|
|
FIELD_OFFSET(RAS_DEVCONFIG, abInfo);
|
|
|
|
pConfig->dwSizeofModemSettings = varModem->dwStringSize;
|
|
|
|
memcpy(pConfig->abInfo,
|
|
(PBYTE) ((BYTE *) varModem) + varModem->dwStringOffset,
|
|
pConfig->dwSizeofModemSettings);
|
|
|
|
if(NULL != varExtendedCaps)
|
|
{
|
|
pConfig->dwOffsetofExtendedCaps =
|
|
pConfig->dwOffsetofModemSettings
|
|
+ pConfig->dwSizeofModemSettings;
|
|
|
|
pConfig->dwSizeofExtendedCaps =
|
|
varExtendedCaps->dwStringSize;
|
|
|
|
memcpy(pConfig->abInfo + pConfig->dwSizeofModemSettings,
|
|
(PBYTE) ((PBYTE) varExtendedCaps)
|
|
+ varExtendedCaps->dwStringOffset,
|
|
pConfig->dwSizeofExtendedCaps);
|
|
}
|
|
else
|
|
{
|
|
pConfig->dwOffsetofExtendedCaps = 0;
|
|
pConfig->dwSizeofExtendedCaps = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwErr = ERROR_BUFFER_TOO_SMALL;
|
|
}
|
|
|
|
done:
|
|
if(NULL != varModem)
|
|
{
|
|
LocalFree(varModem);
|
|
}
|
|
|
|
if(NULL != varExtendedCaps)
|
|
{
|
|
LocalFree(varExtendedCaps);
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Called to set an opaque blob of
|
|
data to configure a device.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
LocalAlloc returned values.
|
|
|
|
--*/
|
|
DWORD
|
|
DwDeviceGetDevConfig (
|
|
char *name,
|
|
PBYTE devconfig,
|
|
DWORD *sizeofdevconfig,
|
|
BOOL fDialIn
|
|
)
|
|
{
|
|
TapiPortControlBlock *hIOPort = RasPortsList;
|
|
DWORD i ;
|
|
BYTE buffer[2000] ;
|
|
LPVARSTRING var ;
|
|
PBYTE configptr ;
|
|
DWORD configsize ;
|
|
DWORD retcode = SUCCESS;
|
|
|
|
while ( hIOPort )
|
|
{
|
|
if (!_stricmp(hIOPort->TPCB_Name, name))
|
|
{
|
|
break ;
|
|
}
|
|
|
|
hIOPort = hIOPort->TPCB_next;
|
|
}
|
|
|
|
if (!hIOPort)
|
|
{
|
|
|
|
RasTapiTrace("DeviceGetDevConfig: port"
|
|
" %s not found",
|
|
name );
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return ERROR_PORT_NOT_FOUND ;
|
|
}
|
|
|
|
if (_stricmp (hIOPort->TPCB_DeviceType,
|
|
DEVICETYPE_UNIMODEM))
|
|
{
|
|
*sizeofdevconfig = 0 ;
|
|
|
|
return SUCCESS ;
|
|
}
|
|
|
|
// **** Exclusion Begin ****
|
|
GetMutex (RasTapiMutex, INFINITE) ;
|
|
|
|
if (hIOPort->TPCB_DevConfig != NULL)
|
|
{
|
|
|
|
configptr = hIOPort->TPCB_DevConfig ;
|
|
configsize = hIOPort->TPCB_SizeOfDevConfig ;
|
|
|
|
}
|
|
else
|
|
{
|
|
retcode = DwGetDevConfig(
|
|
hIOPort->TPCB_Line->TLI_LineId,
|
|
devconfig,
|
|
sizeofdevconfig,
|
|
fDialIn);
|
|
|
|
goto done;
|
|
}
|
|
|
|
if (*sizeofdevconfig >= configsize)
|
|
{
|
|
memcpy (devconfig, configptr, configsize) ;
|
|
|
|
retcode = SUCCESS ;
|
|
}
|
|
else
|
|
{
|
|
retcode = ERROR_BUFFER_TOO_SMALL ;
|
|
}
|
|
|
|
*sizeofdevconfig = configsize ;
|
|
|
|
done:
|
|
|
|
// **** Exclusion End ****
|
|
FreeMutex (RasTapiMutex) ;
|
|
|
|
return (retcode);
|
|
}
|
|
|
|
DWORD
|
|
DeviceGetDevConfig(
|
|
char *name,
|
|
PBYTE devconfig,
|
|
DWORD *sizeofdevconfig)
|
|
{
|
|
return DwDeviceGetDevConfig (
|
|
name, devconfig,
|
|
sizeofdevconfig, FALSE);
|
|
|
|
}
|
|
|
|
DWORD
|
|
DeviceGetDevConfigEx(
|
|
char *name,
|
|
PBYTE devconfig,
|
|
DWORD *sizeofdevconfig)
|
|
{
|
|
return DwDeviceGetDevConfig (
|
|
name, devconfig,
|
|
sizeofdevconfig, TRUE);
|
|
}
|
|
|
|
|
|
DWORD
|
|
RastapiGetCalledID(PBYTE pbAdapter,
|
|
BOOL fModem,
|
|
RAS_CALLEDID_INFO *pCalledID,
|
|
DWORD *pdwSize)
|
|
{
|
|
DWORD retcode = ERROR_SUCCESS;
|
|
DeviceInfo *pInfo = NULL;
|
|
DWORD dwSize;
|
|
|
|
RasTapiTrace("RastapiGetCalledID..");
|
|
|
|
if(NULL == pdwSize)
|
|
{
|
|
retcode = E_INVALIDARG;
|
|
goto done;
|
|
}
|
|
|
|
dwSize = *pdwSize;
|
|
|
|
GetMutex(RasTapiMutex, INFINITE);
|
|
|
|
pInfo = GetDeviceInfo(pbAdapter,
|
|
fModem);
|
|
|
|
if(NULL == pInfo)
|
|
{
|
|
retcode = E_FAIL;
|
|
goto done;
|
|
}
|
|
|
|
/*
|
|
if(NULL != pInfo->pCalledID)
|
|
{
|
|
LocalFree(pInfo->pCalledID);
|
|
pInfo->pCalledID = NULL;
|
|
}
|
|
|
|
retcode = DwGetCalledIdInfo(NULL,
|
|
pInfo);
|
|
|
|
if(ERROR_SUCCESS != retcode)
|
|
{
|
|
goto done;
|
|
}
|
|
*/
|
|
|
|
if(NULL == pInfo->pCalledID)
|
|
{
|
|
retcode = E_FAIL;
|
|
goto done;
|
|
}
|
|
|
|
*pdwSize = sizeof(RAS_CALLEDID_INFO) +
|
|
pInfo->pCalledID->dwSize;
|
|
|
|
if( (NULL != pCalledID)
|
|
&& (*pdwSize <= dwSize))
|
|
{
|
|
memcpy(pCalledID,
|
|
pInfo->pCalledID,
|
|
*pdwSize);
|
|
}
|
|
|
|
done:
|
|
|
|
FreeMutex(RasTapiMutex);
|
|
|
|
RasTapiTrace("RastapiGetCalledID. 0x%x",
|
|
retcode);
|
|
|
|
return retcode;
|
|
}
|
|
|
|
DWORD
|
|
RastapiSetCalledID(PBYTE pbAdapter,
|
|
BOOL fModem,
|
|
RAS_CALLEDID_INFO *pCalledID,
|
|
BOOL fWrite)
|
|
{
|
|
DWORD retcode = ERROR_SUCCESS;
|
|
DeviceInfo *pInfo = NULL;
|
|
|
|
RasTapiTrace("RastapiSetCalledID..");
|
|
|
|
if(NULL == pCalledID)
|
|
{
|
|
retcode = E_INVALIDARG;
|
|
goto done;
|
|
}
|
|
|
|
GetMutex(RasTapiMutex, INFINITE);
|
|
|
|
pInfo = GetDeviceInfo(pbAdapter,
|
|
fModem);
|
|
|
|
if(NULL == pInfo)
|
|
{
|
|
retcode = E_FAIL;
|
|
goto done;
|
|
}
|
|
|
|
if(NULL != pInfo->pCalledID)
|
|
{
|
|
LocalFree(pInfo->pCalledID);
|
|
pInfo->pCalledID = NULL;
|
|
}
|
|
|
|
pInfo->pCalledID = LocalAlloc(LPTR,
|
|
sizeof(RAS_CALLEDID_INFO)
|
|
+ pCalledID->dwSize);
|
|
|
|
if(NULL == pInfo->pCalledID)
|
|
{
|
|
retcode = GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
memcpy(pInfo->pCalledID->bCalledId,
|
|
pCalledID->bCalledId,
|
|
pCalledID->dwSize);
|
|
|
|
pInfo->pCalledID->dwSize = pCalledID->dwSize;
|
|
|
|
if(fWrite)
|
|
{
|
|
|
|
retcode = DwSetCalledIdInfo(NULL,
|
|
pInfo);
|
|
|
|
if(ERROR_SUCCESS != retcode)
|
|
{
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
done:
|
|
|
|
FreeMutex(RasTapiMutex);
|
|
|
|
RasTapiTrace("RastapiSetCalledID. 0x%x",
|
|
retcode);
|
|
|
|
return retcode;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Notification that the number of
|
|
pptp endpoints changed
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
DWORD
|
|
AddPorts( PBYTE pbGuidAdapter, PVOID pvReserved )
|
|
{
|
|
DWORD retcode;
|
|
BOOL fINetCfgInited = FALSE;
|
|
DeviceInfo *pDeviceInfo = NULL;
|
|
DeviceInfo *pNewDeviceInfo = NULL;
|
|
|
|
GetMutex( RasTapiMutex, INFINITE );
|
|
|
|
RasTapiTrace("AddPorts");
|
|
|
|
//
|
|
// Get Current DeviceInfo
|
|
//
|
|
pDeviceInfo = GetDeviceInfo(pbGuidAdapter, FALSE);
|
|
|
|
RasTapiTrace("OldInfo");
|
|
|
|
TraceEndPointInfo(pDeviceInfo);
|
|
|
|
#if DBG
|
|
ASSERT( NULL != pDeviceInfo );
|
|
#endif
|
|
|
|
RasTapiTrace("AddPorts: Old: NumEndPoints=%d",
|
|
pDeviceInfo->rdiDeviceInfo.dwNumEndPoints );
|
|
|
|
retcode = GetEndPointInfo(&pNewDeviceInfo,
|
|
pbGuidAdapter,
|
|
TRUE,
|
|
0);
|
|
|
|
if ( retcode )
|
|
{
|
|
|
|
RasTapiTrace("AddPorts: Failed to get enpoint "
|
|
"info from retistry");
|
|
|
|
goto error;
|
|
}
|
|
|
|
pNewDeviceInfo->rdiDeviceInfo.eDeviceType =
|
|
pDeviceInfo->rdiDeviceInfo.eDeviceType;
|
|
|
|
RasTapiTrace("NewInfo");
|
|
|
|
TraceEndPointInfo(pNewDeviceInfo);
|
|
|
|
//
|
|
// Assign the new Number of endpoints to
|
|
// the deviceinfo in the global list
|
|
//
|
|
pDeviceInfo->rdiDeviceInfo.dwNumEndPoints =
|
|
pNewDeviceInfo->rdiDeviceInfo.dwNumEndPoints;
|
|
|
|
//
|
|
// Reset the current endpoints to 0 for
|
|
// this adapter since we are again going
|
|
// to enumerate all the lines.
|
|
//
|
|
pDeviceInfo->dwCurrentEndPoints = 0;
|
|
|
|
LocalFree (pNewDeviceInfo);
|
|
|
|
RasTapiTrace("AddPorts: New: NumEndPoints=%d",
|
|
pDeviceInfo->rdiDeviceInfo.dwNumEndPoints );
|
|
|
|
retcode = dwAddPorts( pbGuidAdapter, pvReserved );
|
|
|
|
//
|
|
// At this point the currentendpoints should also
|
|
// be the Numendpoints. Make it so if its not the
|
|
// case - since otherwise we will get out of ssync.
|
|
//
|
|
if(pDeviceInfo->rdiDeviceInfo.dwNumEndPoints !=
|
|
pDeviceInfo->dwCurrentEndPoints)
|
|
{
|
|
RasTapiTrace(
|
|
"AddPorts: NEP==%d != CEP==%d",
|
|
pDeviceInfo->rdiDeviceInfo.dwNumEndPoints,
|
|
pDeviceInfo->dwCurrentEndPoints);
|
|
|
|
pDeviceInfo->rdiDeviceInfo.dwNumEndPoints =
|
|
pDeviceInfo->dwCurrentEndPoints;
|
|
}
|
|
|
|
if(pvReserved != NULL)
|
|
{
|
|
*((ULONG *) pvReserved) =
|
|
pDeviceInfo->rdiDeviceInfo.dwNumEndPoints;
|
|
}
|
|
|
|
error:
|
|
FreeMutex ( RasTapiMutex );
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
return retcode;
|
|
|
|
}
|
|
|
|
DWORD
|
|
RemovePort (
|
|
CHAR *pszPortName,
|
|
BOOL fRemovePort,
|
|
PBYTE pbGuidAdapter
|
|
)
|
|
{
|
|
TapiPortControlBlock *pport = RasPortsList;
|
|
DWORD dwRetCode = SUCCESS;
|
|
DeviceInfo *pDeviceInfo = NULL;
|
|
TapiPortControlBlock *pportT = NULL;
|
|
|
|
GetMutex ( RasTapiMutex, INFINITE );
|
|
|
|
RasTapiTrace("RemovePort: %s", pszPortName );
|
|
|
|
/*
|
|
pDeviceInfo = GetDeviceInfo(pbGuidAdapter, FALSE);
|
|
|
|
if ( 0 == pDeviceInfo->rdiDeviceInfo.dwNumEndPoints )
|
|
{
|
|
RasTapiTrace("RemovePort: No ports to remove. %s",
|
|
pszPortName );
|
|
|
|
goto done;
|
|
} */
|
|
|
|
while ( pport )
|
|
{
|
|
if ( 0 == _stricmp (pszPortName, pport->TPCB_Name))
|
|
{
|
|
DeviceInfo *pDeviceInfo = pport->TPCB_Line->TLI_pDeviceInfo;
|
|
|
|
pportT = pport;
|
|
|
|
if(RDT_Modem !=
|
|
RAS_DEVICE_TYPE(pDeviceInfo->rdiDeviceInfo.eDeviceType))
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// For modems continue to try to find a port which is marked
|
|
// for removal - this is required since we can end up with 2
|
|
// modems on the same com port and one of them is marked for
|
|
// removal.
|
|
//
|
|
if(PS_UNAVAILABLE == pport->TPCB_State)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
pport = pport->TPCB_next;
|
|
}
|
|
|
|
pport = pportT;
|
|
|
|
if ( NULL == pport )
|
|
{
|
|
|
|
RasTapiTrace ("RemovePort: port %s not found",
|
|
pszPortName );
|
|
|
|
goto done;
|
|
}
|
|
|
|
pDeviceInfo = pport->TPCB_Line->TLI_pDeviceInfo;
|
|
|
|
if ( fRemovePort )
|
|
{
|
|
RasTapiTrace("RemovePort: removing %s",
|
|
pport->TPCB_Name );
|
|
|
|
dwRetCode = dwRemovePort ( pport );
|
|
}
|
|
else
|
|
{
|
|
RasTapiTrace ("RemovePort: Marking %s for removal",
|
|
pport->TPCB_Name );
|
|
|
|
RasTapiTrace ("RemovePorT: Changing state"
|
|
" of %s from %d -> %d",
|
|
pport->TPCB_Name,
|
|
pport->TPCB_State,
|
|
PS_UNAVAILABLE );
|
|
|
|
pport->TPCB_State = PS_UNAVAILABLE;
|
|
|
|
pport->TPCB_dwFlags |= RASTAPI_FLAG_UNAVAILABLE;
|
|
}
|
|
|
|
#if DBG
|
|
|
|
ASSERT(pDeviceInfo->rdiDeviceInfo.dwNumEndPoints);
|
|
ASSERT(pDeviceInfo->dwCurrentEndPoints);
|
|
|
|
if(pDeviceInfo->rdiDeviceInfo.dwNumEndPoints == 0)
|
|
{
|
|
DbgPrint("RemovePort: pDeviceInfo->dwNumEndPoints==0!!!\n");
|
|
}
|
|
|
|
if(pDeviceInfo->dwCurrentEndPoints == 0)
|
|
{
|
|
DbgPrint("RemovePort: pDeviceInfo->dwCurrentEndPoints==0!!!\n");
|
|
}
|
|
|
|
#endif
|
|
|
|
if(pDeviceInfo->rdiDeviceInfo.dwNumEndPoints > 0)
|
|
{
|
|
pDeviceInfo->rdiDeviceInfo.dwNumEndPoints -= 1;
|
|
}
|
|
|
|
if(pDeviceInfo->dwCurrentEndPoints > 0)
|
|
{
|
|
pDeviceInfo->dwCurrentEndPoints -= 1;
|
|
}
|
|
|
|
RasTapiTrace("RemovePort. dwnumEndPoints for port = %d",
|
|
pDeviceInfo->rdiDeviceInfo.dwNumEndPoints);
|
|
|
|
done:
|
|
|
|
FreeMutex ( RasTapiMutex );
|
|
|
|
RasTapiTrace(" ");
|
|
return dwRetCode;
|
|
}
|
|
|
|
DWORD
|
|
EnableDeviceForDialIn(DeviceInfo *pDeviceInfo,
|
|
BOOL fEnable,
|
|
BOOL fEnableRouter,
|
|
BOOL fEnableOutboundRouter)
|
|
{
|
|
DWORD dwRetCode = SUCCESS;
|
|
TapiPortControlBlock *pport = RasPortsList;
|
|
DeviceInfo *pInfo;
|
|
BOOL fModem =
|
|
((RDT_Modem ==
|
|
RAS_DEVICE_TYPE(
|
|
pDeviceInfo->rdiDeviceInfo.eDeviceType))
|
|
? TRUE
|
|
: FALSE);
|
|
|
|
GetMutex(RasTapiMutex, INFINITE);
|
|
|
|
#if DBG
|
|
ASSERT(pDeviceInfo);
|
|
#endif
|
|
|
|
if(NULL == pDeviceInfo)
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
|
|
RasTapiTrace("EnableDeviceForDialIn: fEnable=%d, "
|
|
"fEnableRouter=%d, fEnableOutboundRouter=%d, "
|
|
"device=%s",
|
|
(UINT) fEnable,
|
|
(UINT) fEnableRouter,
|
|
(UINT) fEnableOutboundRouter,
|
|
pDeviceInfo->rdiDeviceInfo.szDeviceName);
|
|
//
|
|
// Run through the list of ports and change the usage of ports
|
|
// on this device.
|
|
//
|
|
while (pport)
|
|
{
|
|
if(fModem)
|
|
{
|
|
if(_stricmp(pport->TPCB_DeviceName,
|
|
pDeviceInfo->rdiDeviceInfo.szDeviceName))
|
|
{
|
|
pport = pport->TPCB_next;
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pInfo = pport->TPCB_Line->TLI_pDeviceInfo;
|
|
|
|
if(memcmp(&pInfo->rdiDeviceInfo.guidDevice,
|
|
&pDeviceInfo->rdiDeviceInfo.guidDevice,
|
|
sizeof(GUID)))
|
|
{
|
|
pport = pport->TPCB_next;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
pInfo = pport->TPCB_Line->TLI_pDeviceInfo;
|
|
|
|
pInfo->rdiDeviceInfo.fRasEnabled = fEnable;
|
|
|
|
pInfo->rdiDeviceInfo.fRouterEnabled = fEnableRouter;
|
|
|
|
pInfo->rdiDeviceInfo.fRouterOutboundEnabled = fEnableOutboundRouter;
|
|
|
|
if(fEnable)
|
|
{
|
|
RasTapiTrace("Enabling %s for dialin",
|
|
pport->TPCB_Name);
|
|
|
|
pport->TPCB_Usage |= CALL_IN;
|
|
}
|
|
else
|
|
{
|
|
RasTapiTrace("Disabling %s for dialin",
|
|
pport->TPCB_Name);
|
|
|
|
pport->TPCB_Usage &= ~CALL_IN;
|
|
}
|
|
|
|
if(fEnableRouter)
|
|
{
|
|
RasTapiTrace("Enabling %s for routing",
|
|
pport->TPCB_Name);
|
|
pport->TPCB_Usage |= CALL_ROUTER;
|
|
}
|
|
else
|
|
{
|
|
RasTapiTrace("Disabling %s for routing",
|
|
pport->TPCB_Name);
|
|
pport->TPCB_Usage &= ~CALL_ROUTER;
|
|
}
|
|
|
|
if(fEnableOutboundRouter)
|
|
{
|
|
RasTapiTrace("Enabling %s for outboundrouting",
|
|
pport->TPCB_Name);
|
|
|
|
pport->TPCB_Usage &= ~(CALL_IN | CALL_ROUTER);
|
|
pport->TPCB_Usage |= CALL_OUTBOUND_ROUTER;
|
|
}
|
|
|
|
pport = pport->TPCB_next;
|
|
}
|
|
|
|
done:
|
|
FreeMutex(RasTapiMutex);
|
|
|
|
return dwRetCode;
|
|
}
|
|
|
|
DWORD
|
|
DwGetSizeofMbcs(
|
|
WCHAR *pwszCalledId,
|
|
DWORD *pdwSize)
|
|
{
|
|
DWORD dwSize = 0;
|
|
DWORD retcode = SUCCESS;
|
|
|
|
*pdwSize = 0;
|
|
|
|
while(*pwszCalledId != L'\0')
|
|
{
|
|
dwSize = WideCharToMultiByte(
|
|
CP_ACP,
|
|
0,
|
|
pwszCalledId,
|
|
-1,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
NULL);
|
|
|
|
if(0 == dwSize)
|
|
{
|
|
retcode = GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
pwszCalledId += wcslen(pwszCalledId) + 1;
|
|
|
|
*pdwSize += dwSize;
|
|
}
|
|
|
|
//
|
|
// Include one char for trailing '\0'
|
|
//
|
|
|
|
*pdwSize += 1;
|
|
|
|
done:
|
|
return retcode;
|
|
}
|
|
|
|
DWORD
|
|
DwFillCalledIDInfo(
|
|
RAS_CALLEDID_INFO *pCalledId,
|
|
RASTAPI_CONNECT_INFO *pConnectInfo,
|
|
DWORD *pdwSize,
|
|
DWORD dwSizeAvailable)
|
|
{
|
|
DWORD dwSize = 0;
|
|
|
|
DWORD retcode = SUCCESS;
|
|
|
|
WCHAR *pwszCalledId = NULL;
|
|
|
|
CHAR *pszCalledId = NULL;
|
|
|
|
DWORD cchLen;
|
|
|
|
ASSERT(NULL != pCalledId);
|
|
|
|
pwszCalledId = (WCHAR *) pCalledId->bCalledId;
|
|
|
|
//
|
|
// Get size of mbcs string equivalent of
|
|
// the unicode string
|
|
//
|
|
retcode = DwGetSizeofMbcs(
|
|
pwszCalledId,
|
|
&dwSize);
|
|
|
|
if(SUCCESS != retcode)
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
*pdwSize += dwSize;
|
|
|
|
if(dwSizeAvailable < dwSize)
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
pConnectInfo->dwAltCalledIdOffset =
|
|
FIELD_OFFSET(RASTAPI_CONNECT_INFO, abdata)
|
|
+ RASMAN_ALIGN8(pConnectInfo->dwCallerIdSize)
|
|
+ RASMAN_ALIGN8(pConnectInfo->dwCalledIdSize)
|
|
+ RASMAN_ALIGN8(pConnectInfo->dwConnectResponseSize);
|
|
|
|
pConnectInfo->dwAltCalledIdSize = dwSize;
|
|
|
|
|
|
pszCalledId = (CHAR *)
|
|
((LPBYTE)
|
|
pConnectInfo
|
|
+ pConnectInfo->dwAltCalledIdOffset);
|
|
|
|
//
|
|
// Make the conversion from wchar to char
|
|
//
|
|
while(*pwszCalledId != L'\0')
|
|
{
|
|
if (0 == (dwSize = WideCharToMultiByte (
|
|
CP_ACP,
|
|
0,
|
|
pwszCalledId,
|
|
-1,
|
|
pszCalledId,
|
|
dwSizeAvailable,
|
|
NULL,
|
|
NULL)))
|
|
{
|
|
retcode = GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
dwSizeAvailable -= dwSize;
|
|
|
|
pwszCalledId += wcslen(pwszCalledId) + 1;
|
|
|
|
pszCalledId = ((PBYTE) pszCalledId) + dwSize;
|
|
|
|
}
|
|
|
|
//
|
|
// Append a NULL to make the string a multisz
|
|
//
|
|
*pszCalledId = '\0';
|
|
|
|
done:
|
|
|
|
return retcode;
|
|
}
|
|
|
|
DWORD
|
|
GetConnectInfo(
|
|
TapiPortControlBlock *hIOPort,
|
|
PBYTE pbDevice,
|
|
BOOL fModem,
|
|
RASTAPI_CONNECT_INFO *pInfo,
|
|
DWORD *pdwSize)
|
|
{
|
|
DWORD retcode = SUCCESS;
|
|
|
|
RASTAPI_CONNECT_INFO *pConnectInfo =
|
|
(NULL != hIOPort)
|
|
? hIOPort->TPCB_pConnectInfo
|
|
: NULL;
|
|
|
|
RAS_CALLEDID_INFO *pCalledId =
|
|
(NULL != hIOPort)
|
|
? hIOPort->TPCB_Line->TLI_pDeviceInfo->pCalledID
|
|
: NULL;
|
|
|
|
DWORD dwSize = 0;
|
|
|
|
GetMutex ( RasTapiMutex, INFINITE );
|
|
|
|
if( (NULL != hIOPort)
|
|
&& (NULL == hIOPort->TPCB_pConnectInfo))
|
|
{
|
|
do
|
|
{
|
|
BYTE buffer[1000];
|
|
LINECALLINFO *linecallinfo;
|
|
|
|
RasTapiTrace(
|
|
"GetConnectInfo: Getting connectinfo because"
|
|
" info not available");
|
|
|
|
|
|
memset (buffer, 0, sizeof(buffer)) ;
|
|
|
|
linecallinfo = (LINECALLINFO *) buffer ;
|
|
|
|
linecallinfo->dwTotalSize = sizeof(buffer) ;
|
|
|
|
if ((retcode = lineGetCallInfo (
|
|
hIOPort->TPCB_CallHandle,
|
|
linecallinfo))
|
|
> 0x80000000)
|
|
{
|
|
if( (LINEERR_STRUCTURETOOSMALL == retcode)
|
|
|| (linecallinfo->dwNeededSize > sizeof(buffer)))
|
|
{
|
|
DWORD dwSizeNeeded =
|
|
linecallinfo->dwNeededSize;
|
|
|
|
//
|
|
// Allocate the correct size and call
|
|
// the api again
|
|
//
|
|
linecallinfo = LocalAlloc(LPTR,
|
|
dwSizeNeeded);
|
|
|
|
if(NULL == linecallinfo)
|
|
{
|
|
retcode = GetLastError();
|
|
break;
|
|
}
|
|
|
|
linecallinfo->dwTotalSize = dwSizeNeeded;
|
|
|
|
retcode = lineGetCallInfo(
|
|
hIOPort->TPCB_CallHandle,
|
|
linecallinfo);
|
|
|
|
}
|
|
}
|
|
|
|
if(retcode > 0x80000000)
|
|
{
|
|
|
|
RasTapiTrace("GetConnectInfo: LINE_CALLSTATE - "
|
|
"lineGetCallInfo Failed. %d",
|
|
retcode );
|
|
|
|
if(buffer != (PBYTE) linecallinfo)
|
|
{
|
|
LocalFree(linecallinfo);
|
|
}
|
|
|
|
break ;
|
|
}
|
|
|
|
//
|
|
// Do the work to get CONNECTINFO, CALLER/CALLEDID
|
|
//
|
|
retcode = DwGetConnectInfo(hIOPort,
|
|
hIOPort->TPCB_CallHandle,
|
|
linecallinfo);
|
|
|
|
RasTapiTrace("GetConnectInfo: DwGetConnectInfo"
|
|
"returned 0x%x",
|
|
retcode);
|
|
|
|
|
|
//
|
|
// don't want to stop the dial from happening
|
|
// because we couldn't the connect info
|
|
//
|
|
retcode = SUCCESS;
|
|
|
|
//
|
|
// Free the linecallinfo struct. if we allocated
|
|
// it above
|
|
//
|
|
if(buffer != (PBYTE) linecallinfo)
|
|
{
|
|
LocalFree(linecallinfo);
|
|
}
|
|
}
|
|
while(FALSE);
|
|
}
|
|
|
|
pConnectInfo = (NULL != hIOPort)
|
|
? hIOPort->TPCB_pConnectInfo
|
|
: NULL;
|
|
|
|
if( (NULL == pCalledId)
|
|
&& (NULL != pbDevice))
|
|
{
|
|
DeviceInfo * pDeviceInfo = NULL;
|
|
|
|
pDeviceInfo = GetDeviceInfo(pbDevice, fModem);
|
|
|
|
if(NULL != pDeviceInfo)
|
|
{
|
|
pCalledId = pDeviceInfo->pCalledID;
|
|
}
|
|
}
|
|
|
|
if(NULL != pConnectInfo)
|
|
{
|
|
dwSize = sizeof(RASTAPI_CONNECT_INFO)
|
|
+ RASMAN_ALIGN8(pConnectInfo->dwCallerIdSize)
|
|
+ RASMAN_ALIGN8(pConnectInfo->dwCalledIdSize)
|
|
+ RASMAN_ALIGN8(pConnectInfo->dwConnectResponseSize);
|
|
|
|
if( (NULL != pInfo)
|
|
&& (*pdwSize >= dwSize))
|
|
{
|
|
|
|
memcpy((PBYTE) pInfo,
|
|
(PBYTE) pConnectInfo,
|
|
dwSize);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Calculate the space required for the alternate
|
|
// calledids - read from registry and adjust the
|
|
// structure to return this information.
|
|
//
|
|
if(NULL != pCalledId)
|
|
{
|
|
DWORD dwSizeRemaining;
|
|
|
|
if(0 == dwSize)
|
|
{
|
|
dwSize = sizeof(RASTAPI_CONNECT_INFO);
|
|
}
|
|
|
|
dwSizeRemaining = (*pdwSize > dwSize)
|
|
? (*pdwSize - dwSize)
|
|
: 0;
|
|
|
|
retcode = DwFillCalledIDInfo(
|
|
pCalledId,
|
|
pInfo,
|
|
&dwSize,
|
|
dwSizeRemaining);
|
|
}
|
|
|
|
if( (NULL == pConnectInfo)
|
|
&& (NULL == pCalledId))
|
|
{
|
|
retcode = E_FAIL;
|
|
}
|
|
|
|
*pdwSize = dwSize;
|
|
|
|
FreeMutex(RasTapiMutex);
|
|
|
|
return retcode;
|
|
}
|
|
|
|
DWORD
|
|
GetZeroDeviceInfo(DWORD *pcDevices,
|
|
DeviceInfo ***pppDeviceInfo)
|
|
{
|
|
DeviceInfo *pDeviceInfo = g_pDeviceInfoList;
|
|
DeviceInfo **ppDeviceInfo = NULL;
|
|
DWORD cDevices = 0;
|
|
DWORD retcode = SUCCESS;
|
|
|
|
ASSERT(NULL != pcDevices);
|
|
ASSERT(NULL != pppDeviceInfo);
|
|
|
|
*pcDevices = 0;
|
|
*pppDeviceInfo = NULL;
|
|
|
|
while(NULL != pDeviceInfo)
|
|
{
|
|
if( (pDeviceInfo->fValid)
|
|
|
|
&& (pDeviceInfo->rdiDeviceInfo.dwMinWanEndPoints
|
|
!= pDeviceInfo->rdiDeviceInfo.dwMaxWanEndPoints)
|
|
|
|
&& (0 == pDeviceInfo->rdiDeviceInfo.dwNumEndPoints))
|
|
{
|
|
cDevices += 1;
|
|
}
|
|
|
|
pDeviceInfo = pDeviceInfo->Next;
|
|
}
|
|
|
|
if(0 == cDevices)
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
ppDeviceInfo = (DeviceInfo **) LocalAlloc(
|
|
LPTR,
|
|
cDevices
|
|
* sizeof(DeviceInfo *));
|
|
|
|
cDevices = 0;
|
|
|
|
if(NULL == ppDeviceInfo)
|
|
{
|
|
retcode = GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
pDeviceInfo = g_pDeviceInfoList;
|
|
|
|
while(NULL != pDeviceInfo)
|
|
{
|
|
if( (pDeviceInfo->fValid)
|
|
|
|
&& (pDeviceInfo->rdiDeviceInfo.dwMinWanEndPoints
|
|
!= pDeviceInfo->rdiDeviceInfo.dwMaxWanEndPoints)
|
|
|
|
&& (0 == pDeviceInfo->rdiDeviceInfo.dwNumEndPoints))
|
|
{
|
|
ppDeviceInfo[cDevices] = pDeviceInfo;
|
|
cDevices += 1;
|
|
}
|
|
|
|
pDeviceInfo = pDeviceInfo->Next;
|
|
}
|
|
|
|
*pppDeviceInfo = ppDeviceInfo;
|
|
*pcDevices = cDevices;
|
|
|
|
done:
|
|
|
|
RasTapiTrace("GetZeroDeviceInfo. rc=%d, cDevices=%d",
|
|
retcode,
|
|
cDevices);
|
|
|
|
return retcode;
|
|
}
|
|
|
|
DWORD
|
|
GetInfo (
|
|
TapiPortControlBlock *hIOPort,
|
|
BYTE *pBuffer,
|
|
DWORD *pdwSize
|
|
)
|
|
{
|
|
if (_stricmp (hIOPort->TPCB_DeviceType,
|
|
DEVICETYPE_ISDN) == 0)
|
|
{
|
|
GetIsdnParams (hIOPort, (RASMAN_PORTINFO *) pBuffer,
|
|
pdwSize) ;
|
|
}
|
|
else if (_stricmp (hIOPort->TPCB_DeviceType,
|
|
DEVICETYPE_X25) == 0)
|
|
{
|
|
GetX25Params (hIOPort, (RASMAN_PORTINFO *) pBuffer,
|
|
pdwSize) ;
|
|
}
|
|
else
|
|
{
|
|
GetGenericParams (hIOPort, (RASMAN_PORTINFO *) pBuffer,
|
|
pdwSize) ;
|
|
}
|
|
return SUCCESS ;
|
|
}
|
|
|
|
DWORD
|
|
SetInfo (
|
|
TapiPortControlBlock *hIOPort,
|
|
RASMAN_PORTINFO *pBuffer
|
|
)
|
|
{
|
|
|
|
if (_stricmp (hIOPort->TPCB_DeviceType,
|
|
DEVICETYPE_UNIMODEM) == 0)
|
|
{
|
|
FillInUnimodemParams (hIOPort, pBuffer) ;
|
|
}
|
|
else if (_stricmp (hIOPort->TPCB_DeviceType,
|
|
DEVICETYPE_ISDN) == 0)
|
|
{
|
|
FillInIsdnParams (hIOPort, pBuffer) ;
|
|
}
|
|
else if (_stricmp (hIOPort->TPCB_DeviceType,
|
|
DEVICETYPE_X25) == 0)
|
|
{
|
|
FillInX25Params (hIOPort, pBuffer) ;
|
|
}
|
|
else
|
|
{
|
|
FillInGenericParams (hIOPort, pBuffer) ;
|
|
}
|
|
|
|
return SUCCESS ;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
We do more than fill in the params if the params are
|
|
ones that are required to be set right then.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
ERROR_WRONG_INFO_SPECIFIED.
|
|
Comm related Win32 errors
|
|
SUCCESS.
|
|
|
|
--*/
|
|
DWORD
|
|
FillInUnimodemParams (
|
|
TapiPortControlBlock *hIOPort,
|
|
RASMAN_PORTINFO *pInfo
|
|
)
|
|
{
|
|
RAS_PARAMS *p;
|
|
WORD i;
|
|
DWORD index = 0xfefefefe ;
|
|
DCB DCB ;
|
|
#define INITIALIZED_VALUE 0xde
|
|
BYTE DCBByteSize = INITIALIZED_VALUE ;
|
|
BYTE DCBParity = INITIALIZED_VALUE ;
|
|
BYTE DCBStopBits = INITIALIZED_VALUE ;
|
|
BOOL DCBProcessingRequired = FALSE ;
|
|
|
|
for (i = 0, p = pInfo->PI_Params;
|
|
i < pInfo->PI_NumOfParams;
|
|
i++, p++)
|
|
{
|
|
|
|
if (_stricmp(p->P_Key, SER_DATABITS_KEY) == 0)
|
|
{
|
|
DCBByteSize = (BYTE) ValueToNum(p);
|
|
DCBProcessingRequired = TRUE ;
|
|
}
|
|
else if (_stricmp(p->P_Key, SER_PARITY_KEY) == 0)
|
|
{
|
|
DCBParity = (BYTE) ValueToNum(p);
|
|
DCBProcessingRequired = TRUE ;
|
|
}
|
|
else if (_stricmp(p->P_Key, SER_STOPBITS_KEY) == 0)
|
|
{
|
|
DCBStopBits = (BYTE) ValueToNum(p);
|
|
DCBProcessingRequired = TRUE ;
|
|
}
|
|
|
|
//
|
|
// The fact we use ISDN_PHONENUMBER_KEY is not a bug.
|
|
// This is just a define.
|
|
//
|
|
else if (_stricmp(p->P_Key, ISDN_PHONENUMBER_KEY) == 0)
|
|
{
|
|
index = ADDRESS_INDEX ;
|
|
}
|
|
else if (_stricmp(p->P_Key, CONNECTBPS_KEY) == 0)
|
|
{
|
|
index = CONNECTBPS_INDEX ;
|
|
}
|
|
else
|
|
{
|
|
return(ERROR_WRONG_INFO_SPECIFIED);
|
|
}
|
|
|
|
if (index != 0xfefefefe)
|
|
{
|
|
strncpy (hIOPort->TPCB_Info[index],
|
|
p->P_Value.String.Data,
|
|
p->P_Value.String.Length);
|
|
|
|
hIOPort->TPCB_Info[index][p->P_Value.String.Length] = '\0' ;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// For parameters that should be set right away - check that
|
|
// the port handle is still valid
|
|
// if so set the parameters.
|
|
//
|
|
if ( DCBProcessingRequired
|
|
&& hIOPort->TPCB_CommHandle != INVALID_HANDLE_VALUE)
|
|
{
|
|
|
|
//
|
|
// Get a Device Control Block with current port values
|
|
//
|
|
if (!GetCommState(hIOPort->TPCB_CommHandle, &DCB))
|
|
{
|
|
return(GetLastError());
|
|
}
|
|
|
|
if (DCBByteSize != INITIALIZED_VALUE)
|
|
{
|
|
DCB.ByteSize = DCBByteSize ;
|
|
}
|
|
if (DCBParity != INITIALIZED_VALUE)
|
|
{
|
|
DCB.Parity = DCBParity ;
|
|
}
|
|
if (DCBStopBits != INITIALIZED_VALUE)
|
|
{
|
|
DCB.StopBits = DCBStopBits ;
|
|
}
|
|
|
|
//
|
|
// Send DCB to Port
|
|
//
|
|
if (!SetCommState(hIOPort->TPCB_CommHandle, &DCB))
|
|
{
|
|
return(GetLastError());
|
|
}
|
|
}
|
|
|
|
return SUCCESS ;
|
|
}
|
|
|
|
DWORD
|
|
FillInIsdnParams (
|
|
TapiPortControlBlock *hIOPort,
|
|
RASMAN_PORTINFO *pInfo
|
|
)
|
|
{
|
|
RAS_PARAMS *p;
|
|
WORD i;
|
|
DWORD index ;
|
|
|
|
for (i = 0, p = pInfo->PI_Params;
|
|
i < pInfo->PI_NumOfParams;
|
|
i++, p++)
|
|
{
|
|
|
|
if (_stricmp(p->P_Key, ISDN_LINETYPE_KEY) == 0)
|
|
{
|
|
index = ISDN_LINETYPE_INDEX ;
|
|
}
|
|
else if (_stricmp(p->P_Key, ISDN_FALLBACK_KEY) == 0)
|
|
{
|
|
index = ISDN_FALLBACK_INDEX ;
|
|
}
|
|
else if (_stricmp(p->P_Key, ISDN_COMPRESSION_KEY) == 0)
|
|
{
|
|
index = ISDN_COMPRESSION_INDEX ;
|
|
}
|
|
else if (_stricmp(p->P_Key, ISDN_CHANNEL_AGG_KEY) == 0)
|
|
{
|
|
index = ISDN_CHANNEL_AGG_INDEX ;
|
|
}
|
|
else if (_stricmp(p->P_Key, ISDN_PHONENUMBER_KEY) == 0)
|
|
{
|
|
index = ADDRESS_INDEX ;
|
|
}
|
|
else if (_stricmp(p->P_Key, CONNECTBPS_KEY) == 0)
|
|
{
|
|
index = ISDN_CONNECTBPS_INDEX ;
|
|
}
|
|
else
|
|
{
|
|
return(ERROR_WRONG_INFO_SPECIFIED);
|
|
}
|
|
|
|
strncpy (hIOPort->TPCB_Info[index],
|
|
p->P_Value.String.Data,
|
|
p->P_Value.String.Length);
|
|
|
|
hIOPort->TPCB_Info[index][p->P_Value.String.Length] = '\0' ;
|
|
}
|
|
|
|
//
|
|
// initialize connectbps to a reasonable default
|
|
//
|
|
strcpy (hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX], "64000") ;
|
|
|
|
return SUCCESS ;
|
|
}
|
|
|
|
DWORD
|
|
FillInX25Params (
|
|
TapiPortControlBlock *hIOPort,
|
|
RASMAN_PORTINFO *pInfo
|
|
)
|
|
{
|
|
RAS_PARAMS *p;
|
|
WORD i;
|
|
DWORD index ;
|
|
|
|
for (i = 0, p = pInfo->PI_Params;
|
|
i < pInfo->PI_NumOfParams;
|
|
i++, p++)
|
|
{
|
|
|
|
if (_stricmp(p->P_Key, MXS_DIAGNOSTICS_KEY) == 0)
|
|
{
|
|
index = X25_DIAGNOSTICS_INDEX ;
|
|
}
|
|
|
|
else if (_stricmp(p->P_Key, MXS_USERDATA_KEY) == 0)
|
|
{
|
|
index = X25_USERDATA_INDEX ;
|
|
}
|
|
|
|
else if (_stricmp(p->P_Key, MXS_FACILITIES_KEY) == 0)
|
|
{
|
|
index = X25_FACILITIES_INDEX;
|
|
}
|
|
|
|
else if (_stricmp(p->P_Key, MXS_X25ADDRESS_KEY) == 0)
|
|
{
|
|
index = ADDRESS_INDEX ;
|
|
}
|
|
|
|
else if (_stricmp(p->P_Key, CONNECTBPS_KEY) == 0)
|
|
{
|
|
index = X25_CONNECTBPS_INDEX ;
|
|
}
|
|
else
|
|
{
|
|
return(ERROR_WRONG_INFO_SPECIFIED);
|
|
}
|
|
|
|
strncpy (hIOPort->TPCB_Info[index],
|
|
p->P_Value.String.Data,
|
|
p->P_Value.String.Length);
|
|
|
|
hIOPort->TPCB_Info[index][p->P_Value.String.Length] = '\0';
|
|
}
|
|
|
|
//
|
|
// initialize connectbps to a reasonable default
|
|
//
|
|
strcpy (hIOPort->TPCB_Info[X25_CONNECTBPS_INDEX], "9600") ;
|
|
|
|
return SUCCESS ;
|
|
}
|
|
|
|
DWORD
|
|
FillInGenericParams (
|
|
TapiPortControlBlock *hIOPort,
|
|
RASMAN_PORTINFO *pInfo
|
|
)
|
|
{
|
|
RAS_PARAMS *p;
|
|
WORD i;
|
|
DWORD index ;
|
|
|
|
for (i=0, p=pInfo->PI_Params; i<pInfo->PI_NumOfParams; i++, p++)
|
|
{
|
|
|
|
if (_stricmp(p->P_Key, ISDN_PHONENUMBER_KEY) == 0)
|
|
{
|
|
index = ADDRESS_INDEX ;
|
|
}
|
|
else if (_stricmp(p->P_Key, CONNECTBPS_KEY) == 0)
|
|
{
|
|
index = CONNECTBPS_INDEX ;
|
|
}
|
|
else
|
|
{
|
|
return(ERROR_WRONG_INFO_SPECIFIED);
|
|
}
|
|
|
|
strncpy (hIOPort->TPCB_Info[index],
|
|
p->P_Value.String.Data,
|
|
p->P_Value.String.Length);
|
|
|
|
hIOPort->TPCB_Info[index][p->P_Value.String.Length] = '\0' ;
|
|
}
|
|
|
|
return SUCCESS ;
|
|
}
|
|
|
|
DWORD
|
|
GetGenericParams (
|
|
TapiPortControlBlock *hIOPort,
|
|
RASMAN_PORTINFO *pBuffer ,
|
|
PDWORD pdwSize
|
|
)
|
|
{
|
|
RAS_PARAMS *pParam;
|
|
CHAR *pValue;
|
|
DWORD dwAvailable ;
|
|
DWORD dwStructSize = sizeof(RASMAN_PORTINFO)
|
|
+ sizeof(RAS_PARAMS) * 2;
|
|
|
|
dwAvailable = *pdwSize;
|
|
*pdwSize = (dwStructSize
|
|
+ strlen (hIOPort->TPCB_Info[ADDRESS_INDEX])
|
|
+ strlen (hIOPort->TPCB_Info[CONNECTBPS_INDEX])
|
|
+ 1L) ;
|
|
|
|
if (*pdwSize > dwAvailable)
|
|
{
|
|
return(ERROR_BUFFER_TOO_SMALL);
|
|
}
|
|
|
|
((RASMAN_PORTINFO *)pBuffer)->PI_NumOfParams = 2;
|
|
|
|
pParam = ((RASMAN_PORTINFO *)pBuffer)->PI_Params;
|
|
|
|
pValue = (CHAR*)pBuffer + dwStructSize;
|
|
|
|
strcpy(pParam->P_Key, MXS_PHONENUMBER_KEY);
|
|
|
|
pParam->P_Type = String;
|
|
|
|
pParam->P_Attributes = 0;
|
|
|
|
pParam->P_Value.String.Length =
|
|
strlen (hIOPort->TPCB_Info[ADDRESS_INDEX]);
|
|
|
|
pParam->P_Value.String.Data = pValue;
|
|
|
|
strcpy(pParam->P_Value.String.Data,
|
|
hIOPort->TPCB_Info[ADDRESS_INDEX]);
|
|
|
|
pParam++;
|
|
|
|
strcpy(pParam->P_Key, CONNECTBPS_KEY);
|
|
|
|
pParam->P_Type = String;
|
|
|
|
pParam->P_Attributes = 0;
|
|
|
|
pParam->P_Value.String.Length =
|
|
strlen (hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX]);
|
|
|
|
pParam->P_Value.String.Data = pValue;
|
|
|
|
strcpy(pParam->P_Value.String.Data,
|
|
hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX]);
|
|
|
|
return(SUCCESS);
|
|
}
|
|
|
|
DWORD
|
|
GetIsdnParams (
|
|
TapiPortControlBlock *hIOPort,
|
|
RASMAN_PORTINFO *pBuffer ,
|
|
PDWORD pdwSize
|
|
)
|
|
{
|
|
RAS_PARAMS *pParam;
|
|
CHAR *pValue;
|
|
DWORD dwAvailable ;
|
|
DWORD dwStructSize = sizeof(RASMAN_PORTINFO)
|
|
+ sizeof(RAS_PARAMS) * 5;
|
|
|
|
dwAvailable = *pdwSize;
|
|
*pdwSize = (dwStructSize
|
|
+ strlen (hIOPort->TPCB_Info[ADDRESS_INDEX])
|
|
+ strlen (hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX])
|
|
+ strlen (hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX])
|
|
+ strlen (hIOPort->TPCB_Info[ISDN_COMPRESSION_INDEX])
|
|
+ strlen (hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX])
|
|
+ strlen (hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX])
|
|
+ 1L) ;
|
|
|
|
if (*pdwSize > dwAvailable)
|
|
{
|
|
return(ERROR_BUFFER_TOO_SMALL);
|
|
}
|
|
|
|
// Fill in Buffer
|
|
|
|
((RASMAN_PORTINFO *)pBuffer)->PI_NumOfParams = 6;
|
|
|
|
pParam = ((RASMAN_PORTINFO *)pBuffer)->PI_Params;
|
|
pValue = (CHAR*)pBuffer + dwStructSize;
|
|
|
|
|
|
strcpy(pParam->P_Key, ISDN_PHONENUMBER_KEY);
|
|
|
|
pParam->P_Type = String;
|
|
|
|
pParam->P_Attributes = 0;
|
|
|
|
pParam->P_Value.String.Length =
|
|
strlen (hIOPort->TPCB_Info[ADDRESS_INDEX]);
|
|
|
|
pParam->P_Value.String.Data = pValue;
|
|
|
|
strcpy(pParam->P_Value.String.Data,
|
|
hIOPort->TPCB_Info[ADDRESS_INDEX]);
|
|
|
|
pValue += pParam->P_Value.String.Length + 1;
|
|
|
|
pParam++;
|
|
|
|
|
|
strcpy(pParam->P_Key, ISDN_LINETYPE_KEY);
|
|
|
|
pParam->P_Type = String;
|
|
|
|
pParam->P_Attributes = 0;
|
|
|
|
pParam->P_Value.String.Length =
|
|
strlen (hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX]);
|
|
|
|
pParam->P_Value.String.Data = pValue;
|
|
|
|
strcpy(pParam->P_Value.String.Data,
|
|
hIOPort->TPCB_Info[ISDN_LINETYPE_INDEX]);
|
|
|
|
pValue += pParam->P_Value.String.Length + 1;
|
|
|
|
pParam++;
|
|
|
|
strcpy(pParam->P_Key, ISDN_FALLBACK_KEY);
|
|
|
|
pParam->P_Type = String;
|
|
|
|
pParam->P_Attributes = 0;
|
|
|
|
pParam->P_Value.String.Length =
|
|
strlen (hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX]);
|
|
|
|
pParam->P_Value.String.Data = pValue;
|
|
|
|
strcpy(pParam->P_Value.String.Data,
|
|
hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX]);
|
|
|
|
pValue += pParam->P_Value.String.Length + 1;
|
|
|
|
pParam++;
|
|
|
|
strcpy(pParam->P_Key, ISDN_COMPRESSION_KEY);
|
|
|
|
pParam->P_Type = String;
|
|
|
|
pParam->P_Attributes = 0;
|
|
|
|
pParam->P_Value.String.Length =
|
|
strlen (hIOPort->TPCB_Info[ISDN_COMPRESSION_INDEX]);
|
|
|
|
pParam->P_Value.String.Data = pValue;
|
|
|
|
strcpy(pParam->P_Value.String.Data,
|
|
hIOPort->TPCB_Info[ISDN_COMPRESSION_INDEX]);
|
|
|
|
pValue += pParam->P_Value.String.Length + 1;
|
|
|
|
pParam++;
|
|
|
|
strcpy(pParam->P_Key, ISDN_CHANNEL_AGG_KEY);
|
|
|
|
pParam->P_Type = String;
|
|
|
|
pParam->P_Attributes = 0;
|
|
|
|
pParam->P_Value.String.Length =
|
|
strlen (hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX]);
|
|
|
|
pParam->P_Value.String.Data = pValue;
|
|
|
|
strcpy(pParam->P_Value.String.Data,
|
|
hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX]);
|
|
|
|
pValue += pParam->P_Value.String.Length + 1;
|
|
|
|
pParam++;
|
|
|
|
strcpy(pParam->P_Key, CONNECTBPS_KEY);
|
|
|
|
pParam->P_Type = String;
|
|
|
|
pParam->P_Attributes = 0;
|
|
|
|
pParam->P_Value.String.Length =
|
|
strlen (hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX]);
|
|
|
|
pParam->P_Value.String.Data = pValue;
|
|
|
|
strcpy(pParam->P_Value.String.Data,
|
|
hIOPort->TPCB_Info[ISDN_CONNECTBPS_INDEX]);
|
|
|
|
|
|
return(SUCCESS);
|
|
}
|
|
|
|
DWORD
|
|
GetX25Params (
|
|
TapiPortControlBlock *hIOPort,
|
|
RASMAN_PORTINFO *pBuffer ,
|
|
PDWORD pdwSize
|
|
)
|
|
{
|
|
RAS_PARAMS *pParam;
|
|
CHAR *pValue;
|
|
DWORD dwAvailable ;
|
|
|
|
DWORD dwStructSize = sizeof(RASMAN_PORTINFO)
|
|
+ sizeof(RAS_PARAMS) * 4 ;
|
|
|
|
dwAvailable = *pdwSize;
|
|
|
|
*pdwSize = (dwStructSize
|
|
+ strlen (hIOPort->TPCB_Info[ADDRESS_INDEX])
|
|
+ strlen (hIOPort->TPCB_Info[X25_DIAGNOSTICS_INDEX])
|
|
+ strlen (hIOPort->TPCB_Info[X25_USERDATA_INDEX])
|
|
+ strlen (hIOPort->TPCB_Info[X25_FACILITIES_INDEX])
|
|
+ strlen (hIOPort->TPCB_Info[X25_CONNECTBPS_INDEX])
|
|
+ 1L) ;
|
|
|
|
if (*pdwSize > dwAvailable)
|
|
{
|
|
return(ERROR_BUFFER_TOO_SMALL);
|
|
}
|
|
|
|
// Fill in Buffer
|
|
|
|
((RASMAN_PORTINFO *)pBuffer)->PI_NumOfParams = 5 ;
|
|
|
|
pParam = ((RASMAN_PORTINFO *)pBuffer)->PI_Params;
|
|
|
|
pValue = (CHAR*)pBuffer + dwStructSize;
|
|
|
|
strcpy(pParam->P_Key, MXS_X25ADDRESS_KEY);
|
|
|
|
pParam->P_Type = String;
|
|
|
|
pParam->P_Attributes = 0;
|
|
|
|
pParam->P_Value.String.Length =
|
|
strlen (hIOPort->TPCB_Info[ADDRESS_INDEX]);
|
|
|
|
pParam->P_Value.String.Data = pValue;
|
|
|
|
strcpy(pParam->P_Value.String.Data,
|
|
hIOPort->TPCB_Info[ADDRESS_INDEX]);
|
|
|
|
pValue += pParam->P_Value.String.Length + 1;
|
|
|
|
pParam++;
|
|
|
|
strcpy(pParam->P_Key, MXS_DIAGNOSTICS_KEY);
|
|
|
|
pParam->P_Type = String;
|
|
|
|
pParam->P_Attributes = 0;
|
|
|
|
pParam->P_Value.String.Length =
|
|
strlen (hIOPort->TPCB_Info[X25_DIAGNOSTICS_INDEX]);
|
|
|
|
pParam->P_Value.String.Data = pValue;
|
|
|
|
strcpy(pParam->P_Value.String.Data,
|
|
hIOPort->TPCB_Info[X25_DIAGNOSTICS_INDEX]);
|
|
|
|
pValue += pParam->P_Value.String.Length + 1;
|
|
|
|
pParam++;
|
|
|
|
strcpy(pParam->P_Key, MXS_USERDATA_KEY);
|
|
|
|
pParam->P_Type = String;
|
|
|
|
pParam->P_Attributes = 0;
|
|
|
|
pParam->P_Value.String.Length =
|
|
strlen (hIOPort->TPCB_Info[X25_USERDATA_INDEX]);
|
|
|
|
pParam->P_Value.String.Data = pValue;
|
|
|
|
strcpy(pParam->P_Value.String.Data,
|
|
hIOPort->TPCB_Info[X25_USERDATA_INDEX]);
|
|
|
|
pValue += pParam->P_Value.String.Length + 1;
|
|
|
|
pParam++;
|
|
|
|
strcpy(pParam->P_Key, MXS_FACILITIES_KEY);
|
|
|
|
pParam->P_Type = String;
|
|
|
|
pParam->P_Attributes = 0;
|
|
|
|
pParam->P_Value.String.Length =
|
|
strlen (hIOPort->TPCB_Info[X25_FACILITIES_INDEX]);
|
|
|
|
pParam->P_Value.String.Data = pValue;
|
|
|
|
strcpy(pParam->P_Value.String.Data,
|
|
hIOPort->TPCB_Info[X25_FACILITIES_INDEX]);
|
|
|
|
pValue += pParam->P_Value.String.Length + 1;
|
|
|
|
pParam++;
|
|
|
|
strcpy(pParam->P_Key, CONNECTBPS_KEY);
|
|
|
|
pParam->P_Type = String;
|
|
|
|
pParam->P_Attributes = 0;
|
|
|
|
pParam->P_Value.String.Length =
|
|
strlen (hIOPort->TPCB_Info[X25_CONNECTBPS_INDEX]);
|
|
|
|
pParam->P_Value.String.Data = pValue;
|
|
|
|
strcpy(
|
|
pParam->P_Value.String.Data,
|
|
hIOPort->TPCB_Info[X25_CONNECTBPS_INDEX]);
|
|
|
|
|
|
return(SUCCESS);
|
|
}
|
|
|
|
VOID
|
|
GetMutex (HANDLE mutex, DWORD to)
|
|
{
|
|
if (WaitForSingleObject (mutex, to) == WAIT_FAILED)
|
|
{
|
|
GetLastError() ;
|
|
DbgBreakPoint() ;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
FreeMutex (HANDLE mutex)
|
|
{
|
|
if (!ReleaseMutex(mutex))
|
|
{
|
|
GetLastError () ;
|
|
DbgBreakPoint() ;
|
|
}
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Starts the disconnect process. Note even though
|
|
this covers SYNC completion of lineDrop this
|
|
is not per TAPI spec.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
DWORD
|
|
InitiatePortDisconnection (TapiPortControlBlock *hIOPort)
|
|
{
|
|
DWORD retcode = SUCCESS;
|
|
|
|
hIOPort->TPCB_RequestId = INFINITE ;
|
|
|
|
RasTapiTrace("InitiatePortDisconnection: %s",
|
|
hIOPort->TPCB_Name );
|
|
|
|
if ( hIOPort->TPCB_dwFlags & RASTAPI_FLAG_DIALEDIN )
|
|
{
|
|
hIOPort->TPCB_dwFlags &= ~(RASTAPI_FLAG_DIALEDIN);
|
|
|
|
if (hIOPort->TPCB_Line->TLI_pDeviceInfo)
|
|
{
|
|
DeviceInfo * pDeviceInfo =
|
|
hIOPort->TPCB_Line->TLI_pDeviceInfo;
|
|
|
|
#if DBG
|
|
ASSERT(pDeviceInfo->dwCurrentDialedInClients > 0);
|
|
#endif
|
|
|
|
pDeviceInfo->dwCurrentDialedInClients -= 1;
|
|
|
|
RasTapiTrace(
|
|
"IntiatePortDisconnection: %s, "
|
|
"CurrenDialedInClients=0x%x",
|
|
hIOPort->TPCB_DeviceName,
|
|
pDeviceInfo->dwCurrentDialedInClients );
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// For asyncmac/unimodem give a close indication to asyncmac if
|
|
// the endpoint is still valid
|
|
//
|
|
if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_UNIMODEM) == 0)
|
|
{
|
|
|
|
// tell asyncmac to close the link
|
|
//
|
|
if (hIOPort->TPCB_Endpoint != INVALID_HANDLE_VALUE)
|
|
{
|
|
|
|
ASYMAC_CLOSE AsyMacClose;
|
|
OVERLAPPED overlapped ;
|
|
DWORD dwBytesReturned ;
|
|
|
|
memset (&overlapped, 0, sizeof(OVERLAPPED)) ;
|
|
|
|
AsyMacClose.MacAdapter = NULL;
|
|
|
|
AsyMacClose.hNdisEndpoint = (HANDLE) hIOPort->TPCB_Endpoint ;
|
|
|
|
DeviceIoControl(g_hAsyMac,
|
|
IOCTL_ASYMAC_CLOSE,
|
|
&AsyMacClose,
|
|
sizeof(AsyMacClose),
|
|
&AsyMacClose,
|
|
sizeof(AsyMacClose),
|
|
&dwBytesReturned,
|
|
&overlapped);
|
|
|
|
hIOPort->TPCB_Endpoint = INVALID_HANDLE_VALUE ;
|
|
|
|
}
|
|
|
|
//
|
|
// Close the handle given by lineGetId on unimodem ports
|
|
//
|
|
if (hIOPort->TPCB_CommHandle != INVALID_HANDLE_VALUE)
|
|
{
|
|
CloseHandle (hIOPort->TPCB_CommHandle) ;
|
|
hIOPort->TPCB_CommHandle = INVALID_HANDLE_VALUE ;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Handle the case where lineMakeCall is not yet
|
|
// complete and the callhandle is invalid
|
|
//
|
|
if (hIOPort->TPCB_CallHandle == (HCALL) INFINITE)
|
|
{
|
|
|
|
RasTapiTrace("InitiatePortDisconnect: Invalid CallHandle - hIOPort %p, State 0x%x",
|
|
hIOPort, hIOPort->TPCB_State);
|
|
|
|
if (!hIOPort->TPCB_Line->TLI_MultiEndpoint) {
|
|
|
|
RasTapiTrace ("InitiatePortDisconnect: Hammering LineClosed!");
|
|
|
|
lineClose (hIOPort->TPCB_Line->TLI_LineHandle) ;
|
|
|
|
Sleep (30L) ;
|
|
|
|
retcode = lineOpen (
|
|
RasLine,
|
|
hIOPort->TPCB_Line->TLI_LineId,
|
|
&hIOPort->TPCB_Line->TLI_LineHandle,
|
|
hIOPort->TPCB_Line->NegotiatedApiVersion,
|
|
hIOPort->TPCB_Line->NegotiatedExtVersion,
|
|
(DWORD_PTR) hIOPort->TPCB_Line,
|
|
LINECALLPRIVILEGE_OWNER,
|
|
hIOPort->TPCB_Line->TLI_MediaMode,
|
|
NULL) ;
|
|
|
|
if (retcode)
|
|
{
|
|
RasTapiTrace("InitiatePortDisconnection: %s."
|
|
" lineOpen Failed. 0x%x",
|
|
hIOPort->TPCB_Name,
|
|
retcode );
|
|
}
|
|
|
|
//
|
|
// Set monitoring of rings
|
|
//
|
|
lineSetStatusMessages (hIOPort->TPCB_Line->TLI_LineHandle,
|
|
LINEDEVSTATE_RINGING, 0) ;
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
retcode = SUCCESS;
|
|
|
|
goto done;
|
|
|
|
} else {
|
|
|
|
//
|
|
// We need to do something here!
|
|
// Change the state?
|
|
// What about the callback case?
|
|
// Fix this post Win2K!
|
|
//
|
|
|
|
RasTapiTrace("InitiatePortDisconnect: Possible lost port: %p", hIOPort);
|
|
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Initiate disconnection.
|
|
//
|
|
if ((hIOPort->TPCB_RequestId =
|
|
lineDrop (hIOPort->TPCB_CallHandle, NULL, 0))
|
|
> 0x80000000 )
|
|
{
|
|
|
|
RasTapiTrace("InitiatePortDisconnection: Error"
|
|
" issuing lineDrop for %s. 0x%x",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_RequestId );
|
|
//
|
|
// Error issuing the linedrop. Should we try
|
|
// to deallocate anyway?
|
|
//
|
|
RasTapiTrace("InitiatePortDisconnection: Changing "
|
|
"state for %s from %d -> %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_State,
|
|
PS_OPEN );
|
|
|
|
hIOPort->TPCB_State = PS_OPEN ;
|
|
|
|
hIOPort->TPCB_RequestId = INFINITE ;
|
|
|
|
lineDeallocateCall (hIOPort->TPCB_CallHandle) ;
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
retcode = ERROR_DISCONNECTION;
|
|
|
|
goto done;
|
|
|
|
}
|
|
else if (hIOPort->TPCB_RequestId)
|
|
{
|
|
|
|
//
|
|
// The linedrop is completeing async
|
|
//
|
|
RasTapiTrace(
|
|
"InitiatePortDisconnection: Changing"
|
|
" state for %s from %d -> %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_State,
|
|
PS_DISCONNECTING );
|
|
|
|
hIOPort->TPCB_State = PS_DISCONNECTING ;
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
retcode = PENDING;
|
|
|
|
goto done;
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
//
|
|
// The linedrop completed sync
|
|
//
|
|
RasTapiTrace("InitiatePortDisconnection: %s. "
|
|
"linedrop completed sync.",
|
|
hIOPort->TPCB_Name );
|
|
|
|
hIOPort->TPCB_RequestId = INFINITE ;
|
|
|
|
if (hIOPort->IdleReceived)
|
|
{
|
|
|
|
|
|
RasTapiTrace(
|
|
"InitiatePortDisconnection: Changing"
|
|
" state for %s from %d -> %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_State,
|
|
PS_OPEN );
|
|
|
|
hIOPort->IdleReceived = FALSE;
|
|
|
|
hIOPort->TPCB_State = PS_OPEN ;
|
|
|
|
lineDeallocateCall (hIOPort->TPCB_CallHandle) ;
|
|
|
|
hIOPort->TPCB_CallHandle = (HCALL) -1 ;
|
|
|
|
RasTapiTrace(" ");
|
|
|
|
retcode = SUCCESS;
|
|
|
|
goto done;
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Wait for IdleReceived
|
|
//
|
|
hIOPort->TPCB_State = PS_DISCONNECTING ;
|
|
|
|
retcode = PENDING;
|
|
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
done:
|
|
|
|
if(hIOPort->TPCB_pConnectInfo)
|
|
{
|
|
LocalFree(hIOPort->TPCB_pConnectInfo);
|
|
|
|
hIOPort->TPCB_pConnectInfo = NULL;
|
|
}
|
|
|
|
return retcode;
|
|
}
|
|
|
|
VOID
|
|
UnloadRastapiDll()
|
|
{
|
|
//
|
|
// If DLL did not successfully initialize for
|
|
// this process
|
|
// dont try to clean up
|
|
//
|
|
if (!g_fDllLoaded)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (RasLine)
|
|
{
|
|
lineShutdown (RasLine) ;
|
|
RasLine = 0;
|
|
}
|
|
|
|
TraceDeregister( dwTraceId );
|
|
|
|
g_fDllLoaded = FALSE;
|
|
|
|
PostThreadMessage (TapiThreadId, WM_QUIT, 0, 0) ;
|
|
}
|
|
|
|
DWORD
|
|
SetCommSettings(TapiPortControlBlock *hIOPort,
|
|
RASMANCOMMSETTINGS *pSettings)
|
|
{
|
|
DCB dcb;
|
|
DWORD retcode = SUCCESS;
|
|
|
|
if(NULL == hIOPort)
|
|
{
|
|
RasTapiTrace("SetCommSettings: NULL hIOPort!");
|
|
retcode = E_INVALIDARG;
|
|
return retcode;
|
|
}
|
|
|
|
GetMutex(RasTapiMutex, INFINITE);
|
|
|
|
if (!GetCommState(hIOPort->TPCB_CommHandle, &dcb))
|
|
{
|
|
retcode = GetLastError();
|
|
|
|
RasTapiTrace(
|
|
"SetCommSettings: GetCommState failed for %s",
|
|
hIOPort->TPCB_Name);
|
|
|
|
RasTapiTrace(" ");
|
|
goto done;
|
|
}
|
|
|
|
dcb.ByteSize = pSettings->bByteSize;
|
|
dcb.StopBits = pSettings->bStop;
|
|
dcb.Parity = pSettings->bParity;
|
|
|
|
RasTapiTrace("SetCommSettings: setting parity=%d, stop=%d, data=%d",
|
|
pSettings->bParity,
|
|
pSettings->bStop,
|
|
pSettings->bByteSize);
|
|
|
|
if (!SetCommState(hIOPort->TPCB_CommHandle, &dcb))
|
|
{
|
|
retcode = GetLastError();
|
|
|
|
RasTapiTrace(
|
|
"SetCommSettings: SetCommState failed "
|
|
"for %s.handle=0x%x. %d",
|
|
hIOPort->TPCB_Name,
|
|
hIOPort->TPCB_CommHandle,
|
|
retcode);
|
|
|
|
RasTapiTrace(" ");
|
|
goto done;
|
|
}
|
|
|
|
done:
|
|
|
|
FreeMutex(RasTapiMutex);
|
|
|
|
RasTapiTrace("SetCommSettings: done. rc=0x%x",
|
|
retcode);
|
|
|
|
return retcode;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function uses the given handle to find
|
|
which TPCB is it refering to. This handle can be
|
|
either a pointer to TPCB itself (in case of non
|
|
unimodem devices) or it is the CommHandle for the
|
|
unimodem port. Consider: Adding a cache for
|
|
lookup speeding.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
Nothing.
|
|
|
|
--*/
|
|
TapiPortControlBlock *
|
|
LookUpControlBlock (HANDLE hPort)
|
|
{
|
|
DWORD i ;
|
|
TapiPortControlBlock *pports = RasPortsList;
|
|
|
|
while ( pports )
|
|
{
|
|
if ( pports == ( TapiPortControlBlock * ) hPort
|
|
&& ((TapiPortControlBlock *)hPort)->TPCB_Signature
|
|
== CONTROLBLOCKSIGNATURE)
|
|
{
|
|
return (TapiPortControlBlock *) hPort;
|
|
}
|
|
|
|
pports = pports->TPCB_next;
|
|
}
|
|
|
|
//
|
|
// hPort is the TPCB pointer
|
|
//
|
|
pports = RasPortsList;
|
|
|
|
//
|
|
// hPort is not the TPCB pointer - see if this
|
|
// matches any of the CommHandles
|
|
//
|
|
while ( pports )
|
|
{
|
|
if (pports->TPCB_CommHandle == hPort)
|
|
{
|
|
return pports ;
|
|
}
|
|
|
|
pports = pports->TPCB_next;
|
|
}
|
|
|
|
return NULL ;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Converts a RAS_PARAMS P_Value, which may
|
|
be either a DWORD or a string, to a DWORD.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
The numeric value of the input as a DWORD.
|
|
|
|
--*/
|
|
|
|
DWORD
|
|
ValueToNum(RAS_PARAMS *p)
|
|
{
|
|
CHAR szStr[RAS_MAXLINEBUFLEN];
|
|
|
|
|
|
if (p->P_Type == String)
|
|
{
|
|
|
|
strncpy(szStr,
|
|
p->P_Value.String.Data,
|
|
p->P_Value.String.Length);
|
|
|
|
szStr[p->P_Value.String.Length] = '\0';
|
|
|
|
return(atol(szStr));
|
|
|
|
}
|
|
else
|
|
{
|
|
return(p->P_Value.Number);
|
|
}
|
|
}
|
|
|