|
|
//****************************************************************************
//
// Terminal Server CDmodem
//
//
// Copyright 1996, Citrix Systems Inc.
// Copyright (C) 1994-95 Microsft Corporation. All rights reserved.
//
// Filename: rastapi.c
//
// Revision History
//
// November 1998 updated by Qunbiao Guo for terminal server
// Mar 28 1992 Gurdeep Singh Pall Created
//
//
// Description: This file contains tapi codes for cdmodem.dll
//
//****************************************************************************
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <tapi.h>
#include <rasndis.h>
#include <wanioctl.h>
#include <rasman.h>
#include <raserror.h>
#include <eventlog.h>
#include <media.h>
#include <device.h>
#include <rasmxs.h>
#include <isdn.h>
#include <serial.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include "rastapi.h"
#ifdef CITRIX
#include <winstaw.h>
#include <icadd.h>
#include <icaapi.h>
#include "cdmodem.h"
#endif // CITRIX
#ifdef CITRIX
#ifdef DBG
#define DBGPRINT(_arg) DbgPrint _arg
#else
#define DBGPRINT(_arg) { }
#endif
#endif // CITRIX
#pragma warning (error:4312)
extern DWORD TotalPorts ; extern HLINEAPP RasLine ; extern HINSTANCE RasInstance ; extern TapiLineInfo *RasTapiLineInfo ; extern TapiPortControlBlock *RasPorts ; extern TapiPortControlBlock *RasPortsEnd ; extern HANDLE RasTapiMutex ; extern BOOL Initialized ; extern DWORD TapiThreadId ; extern HANDLE TapiThreadHandle; extern DWORD LoaderThreadId; extern DWORD ValidPorts; extern HANDLE ghAsyMac ;
DWORD GetInfo (TapiPortControlBlock *, BYTE *, WORD *) ; DWORD SetInfo (TapiPortControlBlock *, RASMAN_PORTINFO *) ; DWORD GetGenericParams (TapiPortControlBlock *, RASMAN_PORTINFO *, PWORD) ; DWORD GetIsdnParams (TapiPortControlBlock *, RASMAN_PORTINFO * , PWORD) ; DWORD GetX25Params (TapiPortControlBlock *, RASMAN_PORTINFO *, PWORD) ; 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) ; DWORD InitiatePortDisconnection (TapiPortControlBlock *hIOPort) ; TapiPortControlBlock *LookUpControlBlock (HANDLE hPort) ; DWORD ValueToNum(RAS_PARAMS *p) ;
//* Serial APIs ************************************************************
//
//* PortEnum ---------------------------------------------------------------
//
// Function: This API returns a buffer containing a PortMediaInfo struct.
//
// Returns: 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(PCDMODEM pCdModem, BYTE *pBuffer, WORD *pwSize, WORD *pwNumPorts) { PortMediaInfo *pinfo ; TapiPortControlBlock *pports ; DWORD numports = 0; DWORD i ;
DBGPRINT(( "CDMODEM: PortEnum: Entry\n" ));
// **** Exclusion Begin ****
GetMutex (RasTapiMutex, INFINITE) ; DBGPRINT(( "CDMODEM: PortEnum: Lock obtained\n" ));
if (!Initialized) { HANDLE event;
LoaderThreadId = GetCurrentThreadId();
event = CreateEvent (NULL, FALSE, FALSE, NULL) ; TapiThreadHandle = CreateThread (NULL, 5000, (LPTHREAD_START_ROUTINE) EnumerateTapiPorts, (LPVOID) event, 0, &TapiThreadId);
DBGPRINT(( "CDMODEM: PortEnum: waiting for ETP thread..." )); IcaCdWaitForSingleObject (pCdModem->hStack, event, INFINITE) ; DBGPRINT(( "complete\n" ));
if (RasLine == 0 || !ValidPorts) {
//
// Wait for the thread to go away!
//
DBGPRINT(( "CDMODEM: PortEnum: ETP didn't init waitin..." )); IcaCdWaitForSingleObject(pCdModem->hStack, TapiThreadHandle, INFINITE); DBGPRINT(( "complete\n" ));
CloseHandle (TapiThreadHandle) ;
// *** Exclusion End ***
FreeMutex (RasTapiMutex) ; return ERROR_TAPI_CONFIGURATION ; }
CloseHandle (event) ;
Initialized = TRUE ; }
DBGPRINT(( "CDMODEM: PortEnum: TAPI init complete\n" )); // calculate the number of valid ports
//
for (pports = RasPorts, i=0; i < TotalPorts; i++, pports++) { if (pports->TPCB_State == PS_UNINITIALIZED) continue ; numports++ ; }
if (*pwSize < numports*sizeof(PortMediaInfo)) {
*pwNumPorts = (WORD) numports ; *pwSize = (WORD) *pwNumPorts*sizeof(PortMediaInfo) ;
// *** Exclusion End ***
FreeMutex (RasTapiMutex) ; return ERROR_BUFFER_TOO_SMALL ; }
*pwNumPorts = 0 ; pinfo = (PortMediaInfo *)pBuffer ;
for (pports = RasPorts, i=0; i < TotalPorts; i++, pports++) {
if (pports->TPCB_State == PS_UNINITIALIZED) 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++ ; (*pwNumPorts)++ ; }
// *** Exclusion End ***
FreeMutex (RasTapiMutex) ;
return(SUCCESS); }
//* PortOpen ---------------------------------------------------------------
//
// Function: 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.
//
// PortOpen allocates a SerialPCB and places it at the head of
// the linked list of Serial Port Control Blocks.
//
// Returns: SUCCESS
// ERROR_PORT_NOT_CONFIGURED
// ERROR_DEVICE_NOT_READY
//
//*
DWORD APIENTRY PortOpen(char *pszPortName, HANDLE *phIOPort, HANDLE hNotify) { TapiPortControlBlock *pports ; DWORD retcode ; DWORD i ;
// **** Exclusion Begin ****
GetMutex (RasTapiMutex, INFINITE) ;
pports = RasPorts ;
for (i=0; i < TotalPorts; i++) { if (_stricmp(pszPortName, pports->TPCB_Name) == 0) break ; pports++ ; }
if (i < TotalPorts) {
if (pports->TPCB_State == PS_UNINITIALIZED) { // **** Exclusion END ****
FreeMutex (RasTapiMutex) ; return ERROR_TAPI_CONFIGURATION ; }
if (pports->TPCB_State != PS_CLOSED) { // **** Exclusion END ****
FreeMutex (RasTapiMutex) ; return ERROR_PORT_ALREADY_OPEN ; }
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_MediaMode = linedevcaps->dwMediaModes & ~(LINEMEDIAMODE_INTERACTIVEVOICE) ;
retcode = lineOpen (RasLine, pports->TPCB_Line->TLI_LineId, &pports->TPCB_Line->TLI_LineHandle, pports->TPCB_Line->NegotiatedApiVersion, pports->TPCB_Line->NegotiatedExtVersion, (ULONG) (ULONG_PTR)pports->TPCB_Line, LINECALLPRIVILEGE_OWNER, pports->TPCB_MediaMode, NULL) ;
if (retcode) {
// **** Exclusion END ****
FreeMutex (RasTapiMutex) ; 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") ;
}
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_DiscNotificationHandle = hNotify ;
// DbgPrint ("RASTAPI: TPCB_DiscNotificationHandle == %x\n", pports->TPCB_DiscNotificationHandle) ;
pports->TPCB_State = PS_OPEN ; pports->TPCB_DisconnectReason = 0 ; pports->TPCB_CommHandle = INVALID_HANDLE_VALUE ;
*phIOPort = (HANDLE) pports ;
// **** Exclusion END ****
FreeMutex (RasTapiMutex) ;
return(SUCCESS);
}
// **** Exclusion END ****
FreeMutex (RasTapiMutex) ;
return ERROR_PORT_NOT_CONFIGURED ;
}
//* PortClose --------------------------------------------------------------
//
// Function: 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
//
// Returns: SUCCESS
// Values returned by GetLastError()
//
//*
DWORD APIENTRY PortClose (HANDLE hIOPort) { TapiPortControlBlock *pports = (TapiPortControlBlock *) hIOPort ;
// **** Exclusion Begin ****
GetMutex (RasTapiMutex, INFINITE) ;
pports->TPCB_Line->TLI_OpenCount-- ; pports->TPCB_State = PS_CLOSED ;
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) ; }
// **** Exclusion END ****
FreeMutex (RasTapiMutex) ;
return(SUCCESS); }
//* PortGetInfo ------------------------------------------------------------
//
// Function: 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.
//
// Returns: SUCCESS
//
//*
DWORD APIENTRY PortGetInfo(HANDLE hIOPort, CHAR *pszPortName, BYTE *pBuffer, WORD *pwSize) { DWORD i ; DWORD retcode = ERROR_FROM_DEVICE ;
// **** Exclusion Begin ****
GetMutex (RasTapiMutex, INFINITE) ;
// hIOPort or pszPortName must be valid:
//
for (i=0; i < TotalPorts; i++) { if (!_stricmp(RasPorts[i].TPCB_Name, pszPortName) || (hIOPort == (HANDLE) &RasPorts[i]) || (hIOPort == RasPorts[i].TPCB_CommHandle)) { hIOPort = (HANDLE) &RasPorts[i] ; retcode = GetInfo ((TapiPortControlBlock *) hIOPort, pBuffer, pwSize) ; break ; } }
// **** Exclusion END ****
FreeMutex (RasTapiMutex) ;
return (retcode); }
//* PortSetInfo ------------------------------------------------------------
//
// Function: 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.
//
// Returns: SUCCESS
// ERROR_WRONG_INFO_SPECIFIED
// Values returned by GetLastError()
//*
DWORD APIENTRY PortSetInfo(HANDLE hIOPort, RASMAN_PORTINFO *pInfo) { DWORD retcode = ERROR_WRONG_INFO_SPECIFIED ;
// **** Exclusion Begin ****
GetMutex (RasTapiMutex, INFINITE) ;
if (hIOPort = LookUpControlBlock(hIOPort)) {
retcode = SetInfo ((TapiPortControlBlock *) hIOPort, pInfo) ;
}
// **** Exclusion END ****
FreeMutex (RasTapiMutex) ;
return (retcode); }
//* PortTestSignalState ----------------------------------------------------
//
// Function: Really only has meaning if the call was active. Will return
//
// Returns: 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 ;
} 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) ; 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 ;
} else
*pdwDeviceState = SS_LINKDROPPED | SS_HARDWAREFAILURE ; }
// **** Exclusion END ****
FreeMutex (RasTapiMutex) ; return retcode ; }
//* PortDisconnect ---------------------------------------------------------
//
// Function: This API is called to drop a connection and close AsyncMac.
//
// Returns: SUCCESS
// PENDING
// ERROR_PORT_NOT_OPEN
//
//*
DWORD APIENTRY PortDisconnect(HANDLE hPort) { DWORD retcode = SUCCESS ; TapiPortControlBlock *hIOPort = (TapiPortControlBlock *) hPort;
// **** Exclusion Begin ****
GetMutex (RasTapiMutex, INFINITE) ;
// DbgPrint ("PortDisconnect, state = %d\n", hIOPort->TPCB_State) ;
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) {
hIOPort->TPCB_State = PS_OPEN ; // for LS_WAIT listen state case
retcode = SUCCESS ;
} else if (hIOPort->TPCB_State == PS_DISCONNECTING) {
retcode = PENDING ; }
// **** Exclusion END ****
FreeMutex (RasTapiMutex) ;
return retcode ; }
//* PortInit ---------------------------------------------------------------
//
// Function: This API re-initializes the com port after use.
//
// Returns: SUCCESS
// ERROR_PORT_NOT_CONFIGURED
// ERROR_DEVICE_NOT_READY
//
//*
DWORD APIENTRY PortInit(HANDLE hIOPort) { return(SUCCESS); }
//* PortCompressionSetInfo -------------------------------------------------
//
// Function: This API selects Asyncmac compression mode by setting
// Asyncmac's compression bits.
//
// Returns: SUCCESS
// Return code from GetLastError
//
//*
DWORD PortCompressionSetInfo(HANDLE hIOPort) { return SUCCESS; }
//* PortClearStatistics ----------------------------------------------------
//
// Function: 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.
//
// Returns: SUCCESS
// ERROR_PORT_NOT_OPEN
//*
DWORD PortClearStatistics(HANDLE hIOPort) { return SUCCESS; }
//* PortGetStatistics ------------------------------------------------------
//
// Function: This API reports MAC statistics since the last call to
// PortClearStatistics.
//
// Returns: SUCCESS
// ERROR_PORT_NOT_OPEN
//*
DWORD PortGetStatistics(HANDLE hIOPort, RAS_STATISTICS *pStat) {
return(SUCCESS); }
//* PortSetFraming -------------------------------------------------------
//
// Function: Sets the framing type with the mac
//
// Returns: SUCCESS
//
//*
DWORD APIENTRY PortSetFraming(HANDLE hIOPort, DWORD SendFeatureBits, DWORD RecvFeatureBits, DWORD SendBitMask, DWORD RecvBitMask) {
return(SUCCESS); }
//* PortGetPortState -------------------------------------------------------
//
// Function: This API is used in MS-DOS only.
//
// Returns: SUCCESS
//
//*
DWORD APIENTRY PortGetPortState(char *pszPortName, DWORD *pdwUsage) { return(SUCCESS); }
//* PortChangeCallback -----------------------------------------------------
//
// Function: This API is used in MS-DOS only.
//
// Returns: SUCCESS
//
//*
DWORD APIENTRY PortChangeCallback(HANDLE hIOPort) { return(SUCCESS); }
//* PortGetIOHandle()
//
// Function: For the given hIOPort this returns the file handle for the connection
//
// Returns: 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) { *FileHandle = hIOPort->TPCB_CommHandle ; retcode = SUCCESS ; } else retcode = ERROR_PORT_NOT_OPEN ;
// **** Exclusion Begin ****
FreeMutex (RasTapiMutex) ; return retcode ; }
//* DeviceEnum() -----------------------------------------------------------
//
// Function: Enumerates all devices in the device INF file for the
// specified DevictType.
//
// Returns: Return codes from RasDevEnumDevices
//
//*
DWORD APIENTRY DeviceEnum (char *pszDeviceType, WORD *pcEntries, BYTE *pBuffer, WORD *pwSize) { *pwSize = 0 ; *pcEntries = 0 ;
return(SUCCESS); }
//* DeviceGetInfo() --------------------------------------------------------
//
// Function: Returns a summary of current information from the InfoTable
// for the device on the port in Pcb.
//
// Returns: Return codes from GetDeviceCB, BuildOutputTable
//*
DWORD APIENTRY DeviceGetInfo(HANDLE hPort, char *pszDeviceType, char *pszDeviceName, BYTE *pInfo, WORD *pwSize) { DWORD retcode ; TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
if (!hIOPort) return ERROR_PORT_NOT_FOUND ;
// **** Exclusion Begin ****
GetMutex (RasTapiMutex, INFINITE) ;
retcode = GetInfo (hIOPort, pInfo, pwSize) ;
// **** Exclusion End ****
FreeMutex (RasTapiMutex) ;
return(retcode); }
//* DeviceSetInfo() --------------------------------------------------------
//
// Function: Sets attributes in the InfoTable for the device on the
// port in Pcb.
//
// Returns: 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) return ERROR_PORT_NOT_FOUND ;
// **** Exclusion Begin ****
GetMutex (RasTapiMutex, INFINITE) ;
retcode = SetInfo (hIOPort, (RASMAN_PORTINFO*) pInfo) ;
// **** Exclusion End ****
FreeMutex (RasTapiMutex) ;
return (retcode); }
//* DeviceConnect() --------------------------------------------------------
//
// Function: Initiates the process of connecting a device.
//
// Returns: Return codes from ConnectListen
//*
DWORD APIENTRY DeviceConnect(HANDLE hPort, char *pszDeviceType, char *pszDeviceName, HANDLE hNotifier) { LINECALLPARAMS *linecallparams ; LPVARSTRING var ; BYTE buffer [2000] ; BYTE *nextstring ; TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
if (!hIOPort) return ERROR_PORT_NOT_FOUND ;
// **** Exclusion Begin ****
GetMutex (RasTapiMutex, INFINITE) ;
// 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)) {
// 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") ;
// Alloc mem for the returned info
//
hIOPort->TPCB_DefaultDevConfig = LocalAlloc (LPTR, var->dwStringSize) ;
if (hIOPort->TPCB_DefaultDevConfig == NULL) { FreeMutex (RasTapiMutex) ; return ERROR_NOT_ENOUGH_MEMORY; }
hIOPort->TPCB_DefaultDevConfigSize = var->dwStringSize ; memcpy (hIOPort->TPCB_DefaultDevConfig, (CHAR*)var+var->dwStringOffset, var->dwStringSize) ;
lineSetDevConfig (hIOPort->TPCB_Line->TLI_LineId, hIOPort->TPCB_DevConfig, hIOPort->TPCB_SizeOfDevConfig, "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 = (ULONG) (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 = (ULONG) (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 = (ULONG) (nextstring - buffer) ; nextstring += linecallparams->dwDevSpecificSize ; }
// Diagnostic key is ignored.
} else if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_UNIMODEM) == 0) {
SetModemParams (hIOPort, linecallparams) ;
}
hIOPort->TPCB_RequestId = INFINITE ; // mark request id as unused
hIOPort->TPCB_CallHandle = (HCALL) INFINITE ; // set call handle to bogus value
hIOPort->TPCB_AsyncErrorCode = SUCCESS ; // initialize
if ((hIOPort->TPCB_RequestId = lineMakeCall (hIOPort->TPCB_Line->TLI_LineHandle, &hIOPort->TPCB_CallHandle, hIOPort->TPCB_Info[ADDRESS_INDEX], 0, linecallparams)) > 0x80000000 ) {
// **** Exclusion End ****
FreeMutex (RasTapiMutex) ;
// DbgPrint ("RASTAPI: lineMakeCall failed -> returned %x\n", hIOPort->TPCB_RequestId) ;
if (hIOPort->TPCB_RequestId == LINEERR_INUSE) return ERROR_PORT_NOT_AVAILABLE ;
return ERROR_FROM_DEVICE ;
}
ResetEvent (hNotifier) ;
hIOPort->TPCB_ReqNotificationHandle = hNotifier ;
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 ;
#ifndef CITRIX
// 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 = atoi(hIOPort->TPCB_Info[ISDN_CHANNEL_AGG_INDEX]) ; else numchannels = 1 ; // default
if (hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX] != '\0') fallback = atoi(hIOPort->TPCB_Info[ISDN_FALLBACK_INDEX]) ; else fallback = 1 ; // default
if (fallback) linecallparams->dwMinRate = 56000 ; // always allow the min
else linecallparams->dwMinRate = numchannels * linecallparams->dwMaxRate ;
linecallparams->dwMaxRate = numchannels * linecallparams->dwMaxRate ;
#else // CITRIX
DBGPRINT(("CDMODEM: SetIsdnParams: ISDN not supported\n")); ASSERT(FALSE); #endif // CITRIX
}
//*
//
//
//
//
//*
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 ; // in case of failure try the common case - modems
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 ; }
//* DeviceListen() ---------------------------------------------------------
//
// Function: Initiates the process of listening for a remote device
// to connect to a local device.
//
// Returns: Return codes from ConnectListen
//*
DWORD APIENTRY DeviceListen(HANDLE hPort, char *pszDeviceType, char *pszDeviceName, HANDLE hNotifier) { DWORD retcode ; TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
if (!hIOPort) return ERROR_PORT_NOT_FOUND ;
// **** Exclusion Begin ****
GetMutex (RasTapiMutex, INFINITE) ;
// DbgPrint ("DevListen, State = %d\n", 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) {
// DbgPrint ("DevListen: Hit code path where device is still disconnecting\n") ;
lineClose (hIOPort->TPCB_Line->TLI_LineHandle) ;
Sleep (30L) ; // allow a "reasonable" time to allow clean up.
retcode = lineOpen (RasLine, hIOPort->TPCB_Line->TLI_LineId, &hIOPort->TPCB_Line->TLI_LineHandle, hIOPort->TPCB_Line->NegotiatedApiVersion, hIOPort->TPCB_Line->NegotiatedExtVersion, (ULONG) (ULONG_PTR) hIOPort->TPCB_Line, LINECALLPRIVILEGE_OWNER, hIOPort->TPCB_MediaMode, NULL) ;
if (retcode) { // **** Exclusion End ****
FreeMutex (RasTapiMutex) ; // DbgPrint ("DevListen: lineOpen failed with %d \n", retcode) ;
return ERROR_FROM_DEVICE ; }
//
// Set monitoring of rings
//
lineSetStatusMessages (hIOPort->TPCB_Line->TLI_LineHandle, LINEDEVSTATE_RINGING, 0) ; }
if (hIOPort->TPCB_Line->TLI_LineState != PS_LISTENING) hIOPort->TPCB_Line->TLI_LineState = PS_LISTENING ;
hIOPort->TPCB_State = PS_LISTENING ; hIOPort->TPCB_ListenState = LS_WAIT ; hIOPort->TPCB_DisconnectReason = 0 ;
ResetEvent (hNotifier) ;
hIOPort->TPCB_ReqNotificationHandle = hNotifier ;
hIOPort->TPCB_CallHandle = (HCALL)(ULONG_PTR)INVALID_HANDLE_VALUE ;
// **** Exclusion End ****
FreeMutex (RasTapiMutex) ;
return (PENDING); }
//* DeviceDone() -----------------------------------------------------------
//
// Function: Informs the device dll that the attempt to connect or listen
// has completed.
//
// Returns: nothing
//*
VOID APIENTRY DeviceDone(HANDLE hPort) { TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
if (!hIOPort) return ;
// **** Exclusion Begin ****
GetMutex (RasTapiMutex, INFINITE) ;
hIOPort->TPCB_ReqNotificationHandle = NULL ; // no more needed.
// **** Exclusion End ****
FreeMutex (RasTapiMutex) ;
}
//* DeviceWork() -----------------------------------------------------------
//
// Function: This function is called following DeviceConnect or
// DeviceListen to further the asynchronous process of
// connecting or listening.
//
// Returns: ERROR_DCB_NOT_FOUND
// ERROR_STATE_MACHINES_NOT_STARTED
// Return codes from DeviceStateMachine
//*
DWORD APIENTRY DeviceWork(HANDLE hPort, HANDLE hNotifier) { LINECALLSTATUS *callstatus ; BYTE buffer [1000] ; DWORD retcode = ERROR_FROM_DEVICE ; TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
if (!hIOPort) return ERROR_PORT_NOT_FOUND ;
// **** Exclusion Begin ****
GetMutex (RasTapiMutex, INFINITE) ;
memset (buffer, 0, sizeof(buffer)) ;
callstatus = (LINECALLSTATUS *)buffer ; callstatus->dwTotalSize = sizeof(buffer) ;
DBGPRINT(("Devicework enter with ps status: %d \n", 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)) retcode = ERROR_FROM_DEVICE ;
else if (callstatus->dwCallState == LINECALLSTATE_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) retcode = ERROR_NO_ANSWER ; else if (callstatus->dwCallStateMode == LINEDISCONNECTMODE_CANCELLED) retcode = ERROR_USER_DISCONNECTION;
} else if ((callstatus->dwCallState == LINECALLSTATE_SPECIALINFO) && (callstatus->dwCallStateMode == LINESPECIALINFO_NOCIRCUIT)) { retcode = ERROR_NO_ACTIVE_ISDN_LINES ; } }
if (hIOPort->TPCB_State == PS_LISTENING) {
DBGPRINT(("DEvicework PS listning, listeining status: %d \n", hIOPort->TPCB_ListenState));
if (hIOPort->TPCB_ListenState == LS_ERROR) retcode = ERROR_FROM_DEVICE ;
else if (hIOPort->TPCB_ListenState == LS_ACCEPT) { hIOPort->TPCB_RequestId = lineAccept (hIOPort->TPCB_CallHandle, NULL, 0) ;
DBGPRINT(("Devicework lineAccept return status: 0x%x \n", hIOPort->TPCB_RequestId)); DBGPRINT(("Devicework: change listening status from LS_ACCEPT to LS_ANSWER \n"));
if (hIOPort->TPCB_RequestId > 0x80000000 ) // ERROR or SUCCESS
hIOPort->TPCB_ListenState = LS_ANSWER ;
else if (hIOPort->TPCB_RequestId == 0) hIOPort->TPCB_ListenState = LS_ANSWER ;
retcode = PENDING ; }
if (hIOPort->TPCB_ListenState == LS_ANSWER) {
hIOPort->TPCB_RequestId = lineAnswer (hIOPort->TPCB_CallHandle, NULL, 0) ;
DBGPRINT(("Devicework lineAnswer return status: 0x%x \n", hIOPort->TPCB_RequestId));
if (hIOPort->TPCB_RequestId > 0x80000000 ) retcode = ERROR_FROM_DEVICE ; else if (hIOPort->TPCB_RequestId) retcode = PENDING ; else // SUCCESS
hIOPort->TPCB_ListenState = LS_COMPLETE ; }
if (hIOPort->TPCB_ListenState == LS_COMPLETE) {
DBGPRINT(("Devicework: LS_COMPLETE \n"));
if (hIOPort->TPCB_CallHandle == (HCALL)(ULONG_PTR)INVALID_HANDLE_VALUE) {
retcode = ERROR_FROM_DEVICE ;
} else {
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 (lineGetID (hIOPort->TPCB_Line->TLI_LineHandle, hIOPort->TPCB_AddressId, hIOPort->TPCB_CallHandle, LINECALLSELECT_CALL, varstring, "comm/datamodem")) { // **** Exclusion End ****
FreeMutex (RasTapiMutex) ; return ERROR_FROM_DEVICE ; }
hIOPort->TPCB_CommHandle = LongToHandle(*((DWORD *) ((BYTE *)varstring+varstring->dwStringOffset))) ;
// Initialize the port for approp. buffers
//
SetupComm (hIOPort->TPCB_CommHandle, 1514, 1514) ;
} else {
if (lineGetID (hIOPort->TPCB_Line->TLI_LineHandle, hIOPort->TPCB_AddressId, hIOPort->TPCB_CallHandle, LINECALLSELECT_CALL, varstring, "NDIS")) { // **** Exclusion End ****
FreeMutex (RasTapiMutex) ; return ERROR_FROM_DEVICE ; }
hIOPort->TPCB_Endpoint = *((DWORD *) ((BYTE *)varstring+varstring->dwStringOffset)) ; }
// DbgPrint ("L\n") ;
}
if (retcode == PENDING) { DBGPRINT(("Devicework: Reset event \n")); ResetEvent (hNotifier) ; }
// **** Exclusion End ****
FreeMutex (RasTapiMutex) ; return(retcode); }
//* DeviceSetDevConfig()
//
// Function: Called to set an opaque blob of data to configure a device.
//
// Returns: LocalAlloc returned values.
//
DWORD DeviceSetDevConfig (HANDLE hPort, PBYTE devconfig, DWORD sizeofdevconfig) { TapiPortControlBlock *hIOPort = LookUpControlBlock(hPort);
if (!hIOPort) 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); }
//* DeviceGetDevConfig()
//
// Function: Called to set an opaque blob of data to configure a device.
//
// Returns: LocalAlloc returned values.
//
DWORD DeviceGetDevConfig (char *name, PBYTE devconfig, DWORD *sizeofdevconfig) { TapiPortControlBlock *hIOPort = NULL; DWORD i ; BYTE buffer[2000] ; LPVARSTRING var ; PBYTE configptr ; DWORD configsize ; DWORD retcode ;
// hIOPort or pszPortName must be valid:
//
for (i=0; i < TotalPorts; i++) { if (!_stricmp(RasPorts[i].TPCB_Name, name)) { hIOPort = (HANDLE) &RasPorts[i] ; break ; } }
if (!hIOPort) 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 {
// Make var string
//
var = (LPVARSTRING)buffer ; var->dwTotalSize = 2000 ; var->dwStringSize = 0 ; lineGetDevConfig (hIOPort->TPCB_Line->TLI_LineId, var, "comm/datamodem") ; configptr = ((CHAR *)var + var->dwStringOffset) ; configsize = var->dwStringSize ; }
if (*sizeofdevconfig > configsize) { memcpy (devconfig, configptr, configsize) ; retcode = SUCCESS ; } else retcode = ERROR_BUFFER_TOO_SMALL ;
*sizeofdevconfig = configsize ;
// **** Exclusion End ****
FreeMutex (RasTapiMutex) ; return (retcode); }
//*
//
//
//
//*
DWORD GetInfo (TapiPortControlBlock *hIOPort, BYTE *pBuffer, WORD *pwSize) { if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_ISDN) == 0) GetIsdnParams (hIOPort, (RASMAN_PORTINFO *) pBuffer, pwSize) ; else if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_X25) == 0) GetX25Params (hIOPort, (RASMAN_PORTINFO *) pBuffer, pwSize) ; else GetGenericParams (hIOPort, (RASMAN_PORTINFO *) pBuffer, pwSize) ;
return SUCCESS ; }
//* SetInfo()
//
//
//
//*
DWORD SetInfo (TapiPortControlBlock *hIOPort, RASMAN_PORTINFO *pBuffer) {
DWORD Error;
if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_UNIMODEM) == 0) Error = FillInUnimodemParams (hIOPort, pBuffer) ; if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_ISDN) == 0) Error = FillInIsdnParams (hIOPort, pBuffer) ; else if (_stricmp (hIOPort->TPCB_DeviceType, DEVICETYPE_X25) == 0) Error = FillInX25Params (hIOPort, pBuffer) ; else Error = FillInGenericParams (hIOPort, pBuffer) ;
return Error ;
}
//* FillInUnimodemParams()
//
// Function: We do more than fill in the params if the params are ones that are required to be set
// right then.
//
// Returns: 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 ; }
//* FillInIsdnParams()
//
//
//
//*
DWORD FillInIsdnParams (TapiPortControlBlock *hIOPort, RASMAN_PORTINFO *pInfo) { RAS_PARAMS *p; WORD i; DWORD index ;
DBGPRINT(("CDMODEM: FillInIsdnParams: ISDN not supported\n")); ASSERT(FALSE); return SUCCESS ; }
//*
//
//
//
//*
DWORD FillInX25Params (TapiPortControlBlock *hIOPort, RASMAN_PORTINFO *pInfo) { RAS_PARAMS *p; WORD i; DWORD index ;
#ifndef CITRIX
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' ; }
strcpy (hIOPort->TPCB_Info[X25_CONNECTBPS_INDEX], "9600") ; // initialize connectbps to a
// reasonable default
#else // CITRIX
DBGPRINT(("CDMODEM: FillInX25Params: X25 not supported\n")); ASSERT(FALSE); #endif // CITRIX
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 , PWORD pwSize) { RAS_PARAMS *pParam; CHAR *pValue; WORD wAvailable ; DWORD dwStructSize = sizeof(RASMAN_PORTINFO) + sizeof(RAS_PARAMS) * 2;
wAvailable = *pwSize; *pwSize = (WORD) (dwStructSize + strlen (hIOPort->TPCB_Info[ADDRESS_INDEX]) + strlen (hIOPort->TPCB_Info[CONNECTBPS_INDEX]) + 1L) ;
if (*pwSize > wAvailable) return(ERROR_BUFFER_TOO_SMALL);
// Fill in Buffer
((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 , PWORD pwSize) { RAS_PARAMS *pParam; CHAR *pValue; WORD wAvailable ; DWORD dwStructSize = sizeof(RASMAN_PORTINFO) + sizeof(RAS_PARAMS) * 5;
#ifndef CITRIX
wAvailable = *pwSize;
*pwSize = (WORD) (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 (*pwSize > wAvailable) 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]);
#else // CITRIX
DBGPRINT(("CDMODEM: GetIsdnParams: ISDN not supported\n")); ASSERT(FALSE); #endif // CITRIX
return(SUCCESS); }
//*
//
//
//
//*
DWORD GetX25Params (TapiPortControlBlock *hIOPort, RASMAN_PORTINFO *pBuffer ,PWORD pwSize) { RAS_PARAMS *pParam; CHAR *pValue; WORD wAvailable ; DWORD dwStructSize = sizeof(RASMAN_PORTINFO) + sizeof(RAS_PARAMS) * 4 ;
#ifndef CITRIX
wAvailable = *pwSize; *pwSize = (WORD) (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 (*pwSize > wAvailable) 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]);
#else // CITRIX
DBGPRINT(("CDMODEM: GetX25Params: X25 not supported\n")); ASSERT(FALSE); #endif // CITRIX
return(SUCCESS); }
//* GetMutex
//
//
//
//*
VOID GetMutex (HANDLE mutex, DWORD to) { if (WaitForSingleObject (mutex, to) == WAIT_FAILED) { GetLastError() ; DbgBreakPoint() ; } }
//* FreeMutex
//
//
//
//*
VOID FreeMutex (HANDLE mutex) { if (!ReleaseMutex(mutex)) { GetLastError () ; DbgBreakPoint() ; } }
//* InitiatePortDisconnection()
//
// Function: Starts the disconnect process. Note even though this covers SYNC completion of lineDrop this
// is not per TAPI spec.
//
// Returns:
//*
DWORD InitiatePortDisconnection (TapiPortControlBlock *hIOPort) { DWORD retcode ;
hIOPort->TPCB_RequestId = INFINITE ; // mark requestid as unused
// 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 != 0xffffffff) {
ASYMAC_CLOSE AsyMacClose; OVERLAPPED overlapped ; DWORD dwBytesReturned ;
memset (&overlapped, 0, sizeof(OVERLAPPED)) ;
AsyMacClose.MacAdapter = NULL; AsyMacClose.hNdisEndpoint = LongToHandle(hIOPort->TPCB_Endpoint) ;
DeviceIoControl(ghAsyMac, IOCTL_ASYMAC_CLOSE, &AsyMacClose, sizeof(AsyMacClose), &AsyMacClose, sizeof(AsyMacClose), &dwBytesReturned, &overlapped);
hIOPort->TPCB_Endpoint = 0xffffffff ;
}
// Close the handle given by lineGetId on unimodem ports
//
if (hIOPort->TPCB_CommHandle != INVALID_HANDLE_VALUE) { DBGPRINT(( "InitiatePortDisconnection: Closing handle 0x%x", hIOPort->TPCB_CommHandle )); 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) {
lineClose (hIOPort->TPCB_Line->TLI_LineHandle) ;
Sleep (30L) ; // arbitrary sleep time to allow cleanup in lower layers
retcode = lineOpen (RasLine, hIOPort->TPCB_Line->TLI_LineId, &hIOPort->TPCB_Line->TLI_LineHandle, hIOPort->TPCB_Line->NegotiatedApiVersion, hIOPort->TPCB_Line->NegotiatedExtVersion, (ULONG) (ULONG_PTR) hIOPort->TPCB_Line, LINECALLPRIVILEGE_OWNER, hIOPort->TPCB_MediaMode, NULL) ;
if (retcode) DbgPrint ("InitiateDisconnection: lineOpen failed with %d\n", retcode) ;
//
// Set monitoring of rings
//
lineSetStatusMessages (hIOPort->TPCB_Line->TLI_LineHandle, LINEDEVSTATE_RINGING, 0) ;
return SUCCESS ; }
// Initiate disconnection.
//
if ((hIOPort->TPCB_RequestId = lineDrop (hIOPort->TPCB_CallHandle, NULL, 0)) > 0x80000000 ) {
//
// Error issuing the linedrop. Should we try to deallocate anyway?
//
hIOPort->TPCB_State = PS_OPEN ; hIOPort->TPCB_RequestId = INFINITE ; lineDeallocateCall (hIOPort->TPCB_CallHandle) ;
// DbgPrint ("D\n") ;
return ERROR_DISCONNECTION ; // generic disconnect message
} else if (hIOPort->TPCB_RequestId) {
//
// The linedrop is completeing async
//
hIOPort->TPCB_State = PS_DISCONNECTING ;
// DbgPrint ("InitiatePortDisconnection: ReqId:%d\n", hIOPort->TPCB_RequestId) ;
return PENDING ;
} else { // SUCCESS
//
// The linedrop completed sync
//
hIOPort->TPCB_RequestId = INFINITE ; if (hIOPort->TPCB_Line->IdleReceived) {
hIOPort->TPCB_Line->IdleReceived = FALSE; hIOPort->TPCB_State = PS_OPEN ; lineDeallocateCall (hIOPort->TPCB_CallHandle) ;
// DbgPrint ("D\n") ;
hIOPort->TPCB_CallHandle = (HCALL) 0xffffffff ; return SUCCESS ;
} else {
//
// Wait for IdleReceived
//
hIOPort->TPCB_State = PS_DISCONNECTING ; return PENDING ; } }
}
// LookUpControlBlock()
//
// Function: 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.
//
// Returns: Nothing.
//
TapiPortControlBlock * LookUpControlBlock (HANDLE hPort) { DWORD i ; TapiPortControlBlock *pports ;
// hPort is the TPCB pointer
//
if (((TapiPortControlBlock *)hPort >= RasPorts) && ((TapiPortControlBlock *)hPort < RasPortsEnd) && (((TapiPortControlBlock *)hPort)->TPCB_Signature == CONTROLBLOCKSIGNATURE)) return (TapiPortControlBlock *)hPort ;
// hPort is not the TPCB pointer - see if this matches any of the CommHandles
//
for (pports = RasPorts, i=0; i < TotalPorts; i++, pports++) { if (pports->TPCB_CommHandle == hPort) return pports ; }
return NULL ; }
//* ValueToNum -------------------------------------------------------------
//
// Function: Converts a RAS_PARAMS P_Value, which may be either a DWORD or
// a string, to a DWORD.
//
// Returns: 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); }
|