757 lines
17 KiB
C
757 lines
17 KiB
C
/*******************************************************************/
|
||
/* Copyright(c) 1996 Microsoft Corporation */
|
||
/*******************************************************************/
|
||
|
||
//***
|
||
//
|
||
// Filename: arapif.c
|
||
//
|
||
// Description: This module contains the procedures for the
|
||
// DDM-Arap interface
|
||
//
|
||
// Author: Shirish Koti Sep 9, 1996
|
||
//
|
||
// Revision History:
|
||
//
|
||
//***
|
||
|
||
#include "ddm.h"
|
||
#include "util.h"
|
||
#include "isdn.h"
|
||
#include "objects.h"
|
||
#include "rasmanif.h"
|
||
#include "handlers.h"
|
||
#include <ddmif.h>
|
||
#include "arapif.h"
|
||
|
||
#include <timer.h>
|
||
#include <ctype.h>
|
||
#include <memory.h>
|
||
#include <string.h>
|
||
|
||
|
||
//
|
||
// prototypes for functions used in this file
|
||
//
|
||
|
||
VOID
|
||
ArapDDMAuthenticated(
|
||
IN PDEVICE_OBJECT pDeviceObj,
|
||
IN ARAPDDM_AUTH_RESULT * pAuthResult
|
||
);
|
||
|
||
VOID
|
||
ArapDDMCallbackRequest(
|
||
IN PDEVICE_OBJECT pDeviceObj,
|
||
IN ARAPDDM_CALLBACK_REQUEST *pCbReq
|
||
);
|
||
|
||
VOID
|
||
ArapDDMDone(
|
||
IN PDEVICE_OBJECT pDeviceObj,
|
||
IN DWORD NetAddress,
|
||
IN DWORD SessTimeOut
|
||
);
|
||
|
||
VOID
|
||
ArapDDMFailure(
|
||
IN PDEVICE_OBJECT pDeviceObj,
|
||
IN ARAPDDM_DISCONNECT *pFailInfo
|
||
);
|
||
|
||
|
||
VOID
|
||
ArapDDMTimeOut(
|
||
IN HANDLE hObject
|
||
);
|
||
|
||
|
||
//***
|
||
//
|
||
// Function: ArapEventHandler
|
||
// Waits for a message from Arap and depending on the message
|
||
// type, executes the appropriate routine Loads Arap.dll and
|
||
// gets all the entry points
|
||
//
|
||
// Parameters: None
|
||
//
|
||
// Return: Nothing
|
||
//
|
||
//
|
||
//***$
|
||
|
||
|
||
VOID
|
||
ArapEventHandler(
|
||
IN VOID
|
||
)
|
||
{
|
||
ARAP_MESSAGE ArapMsg;
|
||
PDEVICE_OBJECT pDevObj;
|
||
LPWSTR portnamep;
|
||
|
||
//
|
||
// loop to get all messages
|
||
//
|
||
|
||
while( ServerReceiveMessage( MESSAGEQ_ID_ARAP, (BYTE *)&ArapMsg) )
|
||
{
|
||
|
||
EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
|
||
|
||
//
|
||
// identify the message recipient
|
||
//
|
||
|
||
if ( ( pDevObj = DeviceObjGetPointer( ArapMsg.hPort ) ) == NULL )
|
||
{
|
||
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
|
||
|
||
return;
|
||
}
|
||
|
||
//
|
||
// action on the message type
|
||
//
|
||
|
||
switch( ArapMsg.dwMsgId )
|
||
{
|
||
|
||
case ARAPDDMMSG_Authenticated:
|
||
|
||
ArapDDMAuthenticated(
|
||
pDevObj,
|
||
&ArapMsg.ExtraInfo.AuthResult);
|
||
break;
|
||
|
||
case ARAPDDMMSG_CallbackRequest:
|
||
|
||
ArapDDMCallbackRequest(
|
||
pDevObj,
|
||
&ArapMsg.ExtraInfo.CallbackRequest);
|
||
break;
|
||
|
||
case ARAPDDMMSG_Done:
|
||
|
||
pDevObj->fFlags &= (~DEV_OBJ_AUTH_ACTIVE);
|
||
ArapDDMDone(pDevObj,
|
||
ArapMsg.ExtraInfo.Done.NetAddress,
|
||
ArapMsg.ExtraInfo.Done.SessTimeOut);
|
||
break;
|
||
|
||
case ARAPDDMMSG_Inactive:
|
||
|
||
//
|
||
// Client has been inactive on all protocols for time
|
||
// specified in the registry. We disconnect the client.
|
||
//
|
||
|
||
portnamep = pDevObj->wchPortName;
|
||
|
||
DDMLogInformation( ROUTERLOG_AUTODISCONNECT, 1, &portnamep );
|
||
|
||
// break intentionally omitted here
|
||
|
||
case ARAPDDMMSG_Disconnected:
|
||
|
||
// in case we had this puppy sitting in the timer queue
|
||
TimerQRemove( (HANDLE)pDevObj->hPort, ArapDDMTimeOut);
|
||
|
||
DevStartClosing(pDevObj);
|
||
|
||
break;
|
||
|
||
case ARAPDDMMSG_Failure:
|
||
|
||
pDevObj->fFlags &= (~DEV_OBJ_AUTH_ACTIVE);
|
||
ArapDDMFailure(pDevObj, &ArapMsg.ExtraInfo.FailureInfo);
|
||
break;
|
||
|
||
default:
|
||
|
||
RTASSERT(FALSE);
|
||
break;
|
||
}
|
||
|
||
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
//***
|
||
//
|
||
// Function: ArapDDMAuthenticated
|
||
// Retrieves username and domain from the message and stores it
|
||
// in the dcb.
|
||
//
|
||
// Parameters: pDeviceObj - the dcb for this connection
|
||
// pAuthResult - info for the user who is authenticated
|
||
//
|
||
// Return: Nothing
|
||
//
|
||
//
|
||
//***$
|
||
|
||
VOID
|
||
ArapDDMAuthenticated(
|
||
IN PDEVICE_OBJECT pDeviceObj,
|
||
IN ARAPDDM_AUTH_RESULT * pAuthResult
|
||
)
|
||
{
|
||
DWORD dwRetCode;
|
||
WCHAR wchUserName[UNLEN+1];
|
||
PCONNECTION_OBJECT pConnObj;
|
||
|
||
|
||
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
||
"ArapDDMAuthenticated: Entered, hPort=%d", pDeviceObj->hPort);
|
||
|
||
if ( pDeviceObj->DeviceState != DEV_OBJ_AUTH_IS_ACTIVE )
|
||
{
|
||
return;
|
||
}
|
||
|
||
pConnObj = ConnObjGetPointer( pDeviceObj->hConnection );
|
||
|
||
RTASSERT( pConnObj != NULL );
|
||
|
||
// this shouldn't happen, but if it does, just ignore this call
|
||
if (pConnObj == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
//
|
||
// Stop authentication timer
|
||
//
|
||
|
||
TimerQRemove( (HANDLE)pDeviceObj->hPort, SvAuthTimeout );
|
||
|
||
//
|
||
// devObj: copy the user name, domain name
|
||
//
|
||
|
||
if ( wcslen( pAuthResult->wchUserName ) > 0 )
|
||
{
|
||
wcscpy(wchUserName, pAuthResult->wchUserName);
|
||
}
|
||
else
|
||
{
|
||
wcscpy( wchUserName, gblpszUnknown );
|
||
}
|
||
|
||
wcscpy( pDeviceObj->wchUserName, wchUserName );
|
||
wcscpy( pDeviceObj->wchDomainName, pAuthResult->wchLogonDomain );
|
||
|
||
//
|
||
// connObj: copy the user name, domain name, etc.
|
||
//
|
||
|
||
wcscpy( pConnObj->wchUserName, wchUserName );
|
||
wcscpy( pConnObj->wchDomainName, pAuthResult->wchLogonDomain );
|
||
wcscpy( pConnObj->wchInterfaceName, pDeviceObj->wchUserName );
|
||
pConnObj->hPort = pDeviceObj->hPort;
|
||
|
||
}
|
||
|
||
|
||
|
||
//***
|
||
//
|
||
// Function: ArapDDMCallbackRequest
|
||
// Disconnects the connection, setting it up for a callback
|
||
//
|
||
// Parameters: pDeviceObj - the dcb for this connection
|
||
// pCbReq - call back info
|
||
//
|
||
// Return: Nothing
|
||
//
|
||
//
|
||
//***$
|
||
|
||
VOID
|
||
ArapDDMCallbackRequest(
|
||
IN PDEVICE_OBJECT pDeviceObj,
|
||
IN ARAPDDM_CALLBACK_REQUEST *pCbReq
|
||
)
|
||
{
|
||
|
||
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
||
"ArapDDMCallbackRequest: Entered, hPort = %d\n",
|
||
pDeviceObj->hPort);
|
||
|
||
//
|
||
// check the state
|
||
//
|
||
|
||
if (pDeviceObj->DeviceState != DEV_OBJ_AUTH_IS_ACTIVE)
|
||
{
|
||
return;
|
||
}
|
||
|
||
TimerQRemove( (HANDLE)pDeviceObj->hPort, SvAuthTimeout );
|
||
|
||
//
|
||
// copy relevant fields in our dcb
|
||
//
|
||
|
||
if (pCbReq->fUseCallbackDelay)
|
||
{
|
||
pDeviceObj->dwCallbackDelay = pCbReq->dwCallbackDelay;
|
||
}
|
||
else
|
||
{
|
||
pDeviceObj->dwCallbackDelay = gblDDMConfigInfo.dwCallbackTime;
|
||
}
|
||
|
||
mbstowcs(pDeviceObj->wchCallbackNumber, pCbReq->szCallbackNumber,
|
||
MAX_PHONE_NUMBER_LEN + 1 );
|
||
|
||
//
|
||
// Disconnect the line and change the state
|
||
//
|
||
|
||
pDeviceObj->DeviceState = DEV_OBJ_CALLBACK_DISCONNECTING;
|
||
|
||
//
|
||
// Wait to enable the client to get the message
|
||
//
|
||
|
||
TimerQRemove( (HANDLE)pDeviceObj->hPort, SvDiscTimeout );
|
||
|
||
TimerQInsert( (HANDLE)pDeviceObj->hPort,
|
||
DISC_TIMEOUT_CALLBACK, SvDiscTimeout );
|
||
}
|
||
|
||
|
||
//***
|
||
//
|
||
// Function: ArapDDMDone
|
||
// Logs an event, marks the state
|
||
//
|
||
// Parameters: pDeviceObj - the dcb for this connection
|
||
//
|
||
// Return: Nothing
|
||
//
|
||
//
|
||
//***$
|
||
|
||
VOID
|
||
ArapDDMDone(
|
||
IN PDEVICE_OBJECT pDeviceObj,
|
||
IN DWORD NetAddress,
|
||
IN DWORD SessTimeOut
|
||
)
|
||
{
|
||
LPWSTR lpstrAudit[2];
|
||
PCONNECTION_OBJECT pConnObj;
|
||
WCHAR wchFullUserName[UNLEN+DNLEN+2];
|
||
ROUTER_INTERFACE_OBJECT * pIfObject;
|
||
DWORD dwRetCode;
|
||
|
||
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
||
"ArapDDMDone: Entered, hPort=%d", pDeviceObj->hPort);
|
||
|
||
if ( pDeviceObj->DeviceState != DEV_OBJ_AUTH_IS_ACTIVE )
|
||
{
|
||
return;
|
||
}
|
||
|
||
//
|
||
// Get connection object for this connection
|
||
//
|
||
|
||
pConnObj = ConnObjGetPointer( pDeviceObj->hConnection );
|
||
|
||
RTASSERT( pConnObj != NULL );
|
||
|
||
// this shouldn't happen, but if it does, just ignore this call
|
||
if (pConnObj == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
pConnObj->PppProjectionResult.at.dwError = NO_ERROR;
|
||
pConnObj->PppProjectionResult.at.dwRemoteAddress = NetAddress;
|
||
|
||
//
|
||
// Create client interface object for this connection
|
||
//
|
||
|
||
pIfObject = IfObjectAllocateAndInit( pConnObj->wchUserName,
|
||
RISTATE_CONNECTED,
|
||
ROUTER_IF_TYPE_CLIENT,
|
||
pConnObj->hConnection,
|
||
TRUE,
|
||
0,
|
||
0,
|
||
NULL );
|
||
|
||
if ( pIfObject == (ROUTER_INTERFACE_OBJECT *)NULL )
|
||
{
|
||
//
|
||
// Error log this and stop the connection.
|
||
//
|
||
|
||
DDMLogError( ROUTERLOG_NOT_ENOUGH_MEMORY, 1, NULL, GetLastError() );
|
||
|
||
DevStartClosing( pDeviceObj );
|
||
|
||
return;
|
||
}
|
||
|
||
//
|
||
// Insert in table now
|
||
//
|
||
|
||
dwRetCode = IfObjectInsertInTable( pIfObject );
|
||
|
||
if ( dwRetCode != NO_ERROR )
|
||
{
|
||
LOCAL_FREE( pIfObject );
|
||
|
||
DDMLogError( ROUTERLOG_NOT_ENOUGH_MEMORY, 1, NULL, dwRetCode );
|
||
|
||
DevStartClosing( pDeviceObj );
|
||
|
||
return;
|
||
}
|
||
|
||
pConnObj->hDIMInterface = pIfObject->hDIMInterface;
|
||
|
||
//
|
||
// Reduce the media count for this device
|
||
//
|
||
|
||
if ( !(pDeviceObj->fFlags & DEV_OBJ_MARKED_AS_INUSE) )
|
||
{
|
||
if ( pDeviceObj->fFlags & DEV_OBJ_ALLOW_ROUTERS )
|
||
{
|
||
MediaObjRemoveFromTable( pDeviceObj->wchDeviceType );
|
||
}
|
||
|
||
pDeviceObj->fFlags |= DEV_OBJ_MARKED_AS_INUSE;
|
||
|
||
gblDeviceTable.NumDevicesInUse++;
|
||
|
||
//
|
||
// Possibly need to notify the router managers of unreachability
|
||
//
|
||
|
||
EnterCriticalSection( &(gblpInterfaceTable->CriticalSection) );
|
||
|
||
IfObjectNotifyAllOfReachabilityChange( FALSE,
|
||
INTERFACE_OUT_OF_RESOURCES );
|
||
|
||
LeaveCriticalSection( &(gblpInterfaceTable->CriticalSection) );
|
||
}
|
||
|
||
//
|
||
// Stop authentication timer (this will be running in case of callback)
|
||
//
|
||
|
||
TimerQRemove( (HANDLE)pDeviceObj->hPort, SvAuthTimeout );
|
||
|
||
//
|
||
// if a session timeout is specified in the policy, put this connection on
|
||
// the timer queue so the user gets kicked off after the session timeout
|
||
//
|
||
if (SessTimeOut != (DWORD)-1)
|
||
{
|
||
TimerQInsert( (HANDLE)pDeviceObj->hPort, SessTimeOut, ArapDDMTimeOut);
|
||
}
|
||
|
||
//
|
||
// log authentication success
|
||
//
|
||
|
||
if ( pDeviceObj->wchDomainName[0] != TEXT('\0') )
|
||
{
|
||
wcscpy( wchFullUserName, pDeviceObj->wchDomainName );
|
||
wcscat( wchFullUserName, TEXT("\\") );
|
||
wcscat( wchFullUserName, pDeviceObj->wchUserName );
|
||
}
|
||
else
|
||
{
|
||
wcscpy( wchFullUserName, pDeviceObj->wchUserName );
|
||
}
|
||
|
||
lpstrAudit[0] = wchFullUserName;
|
||
lpstrAudit[1] = pDeviceObj->wchPortName;
|
||
|
||
|
||
DDMLogInformation( ROUTERLOG_AUTH_SUCCESS, 2, lpstrAudit);
|
||
|
||
//
|
||
// and finaly go to ACTIVE state
|
||
//
|
||
|
||
pDeviceObj->DeviceState = DEV_OBJ_ACTIVE;
|
||
|
||
pDeviceObj->dwTotalNumberOfCalls++;
|
||
|
||
//
|
||
// and initialize the active time
|
||
//
|
||
|
||
GetSystemTimeAsFileTime( (FILETIME*)&(pConnObj->qwActiveTime) );
|
||
|
||
GetSystemTimeAsFileTime( (FILETIME*)&(pDeviceObj->qwActiveTime) );
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
|
||
//***
|
||
//
|
||
// Function: ArapDDMFailure
|
||
// Closes the dcb, and logs an event depending on why connection failed
|
||
//
|
||
// Parameters: pDeviceObj - the dcb for this connection
|
||
// pFailInfo - info about who disconnected and how (or why)
|
||
//
|
||
// Return: Nothing
|
||
//
|
||
//
|
||
//***$
|
||
|
||
VOID
|
||
ArapDDMFailure(
|
||
IN PDEVICE_OBJECT pDeviceObj,
|
||
IN ARAPDDM_DISCONNECT *pFailInfo
|
||
)
|
||
{
|
||
LPWSTR auditstrp[3];
|
||
WCHAR wchErrorString[256+1];
|
||
WCHAR wchUserName[UNLEN+1];
|
||
WCHAR wchDomainName[DNLEN+1];
|
||
DWORD dwRetCode;
|
||
|
||
|
||
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
||
"ArapDDMFailure: Entered, hPort=%d\n", pDeviceObj->hPort);
|
||
|
||
//
|
||
// ignore the DeviceState here: disconnect can happen at any time during
|
||
// the connection
|
||
//
|
||
|
||
switch( pFailInfo->dwError )
|
||
{
|
||
case ERROR_AUTHENTICATION_FAILURE:
|
||
|
||
wcscpy( wchUserName, pFailInfo->wchUserName );
|
||
|
||
auditstrp[0] = wchUserName;
|
||
auditstrp[1] = pDeviceObj->wchPortName;
|
||
DDMLogWarning(ROUTERLOG_AUTH_FAILURE,2,auditstrp );
|
||
break;
|
||
|
||
case ERROR_PASSWD_EXPIRED:
|
||
|
||
wcscpy( wchUserName, pFailInfo->wchUserName );
|
||
wcscpy( wchDomainName, pFailInfo->wchLogonDomain );
|
||
|
||
auditstrp[0] = wchDomainName;
|
||
auditstrp[1] = wchUserName;
|
||
auditstrp[2] = pDeviceObj->wchPortName;
|
||
|
||
DDMLogWarning( ROUTERLOG_PASSWORD_EXPIRED,3,auditstrp );
|
||
break;
|
||
|
||
case ERROR_ACCT_EXPIRED:
|
||
|
||
wcscpy( wchUserName, pFailInfo->wchUserName );
|
||
wcscpy( wchDomainName, pFailInfo->wchLogonDomain );
|
||
|
||
auditstrp[0] = wchDomainName;
|
||
auditstrp[1] = wchUserName;
|
||
auditstrp[2] = pDeviceObj->wchPortName;
|
||
|
||
DDMLogWarning( ROUTERLOG_ACCT_EXPIRED, 3, auditstrp );
|
||
break;
|
||
|
||
case ERROR_NO_DIALIN_PERMISSION:
|
||
|
||
wcscpy( wchUserName, pFailInfo->wchUserName );
|
||
wcscpy( wchDomainName, pFailInfo->wchLogonDomain );
|
||
|
||
auditstrp[0] = wchDomainName;
|
||
auditstrp[1] = wchUserName;
|
||
auditstrp[2] = pDeviceObj->wchPortName;
|
||
|
||
DDMLogWarning( ROUTERLOG_NO_DIALIN_PRIVILEGE,3,auditstrp );
|
||
break;
|
||
|
||
default:
|
||
|
||
auditstrp[0] = pDeviceObj->wchPortName;
|
||
auditstrp[1] = wchErrorString;
|
||
|
||
DDMLogErrorString( ROUTERLOG_ARAP_FAILURE, 2, auditstrp,
|
||
pFailInfo->dwError, 2 );
|
||
break;
|
||
}
|
||
|
||
DevStartClosing( pDeviceObj );
|
||
}
|
||
|
||
|
||
|
||
//***
|
||
//
|
||
// Function: ArapDDMTimeOut
|
||
// Closes the connection when the timeout specified in policy elapses
|
||
//
|
||
// Parameters: hPort
|
||
//
|
||
// Return: Nothing
|
||
//
|
||
//
|
||
//***$
|
||
|
||
VOID
|
||
ArapDDMTimeOut(
|
||
IN HANDLE hPort
|
||
)
|
||
{
|
||
PDEVICE_OBJECT pDeviceObj;
|
||
|
||
|
||
EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
|
||
|
||
pDeviceObj = DeviceObjGetPointer( (HPORT)hPort );
|
||
|
||
if ( pDeviceObj == NULL )
|
||
{
|
||
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
|
||
return;
|
||
}
|
||
|
||
ArapDisconnect((HPORT)pDeviceObj->hPort);
|
||
|
||
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
|
||
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// The following two structures (and the RasSetDevConfig call) copied from
|
||
// ras\ui\common\nouiutil\rasman.c, courtesy SteveC
|
||
//
|
||
/* These types are described in MSDN and appear in Win95's unimdm.h private
|
||
** header (complete with typo) but not in any SDK headers.
|
||
*/
|
||
|
||
typedef struct tagDEVCFGGDR
|
||
{
|
||
DWORD dwSize;
|
||
DWORD dwVersion;
|
||
WORD fwOptions;
|
||
WORD wWaitBong;
|
||
}DEVCFGHDR;
|
||
|
||
typedef struct tagDEVCFG
|
||
{
|
||
DEVCFGHDR dfgHdr;
|
||
COMMCONFIG commconfig;
|
||
} DEVCFG;
|
||
|
||
|
||
|
||
VOID
|
||
ArapSetModemParms(
|
||
IN PVOID pDevObjPtr,
|
||
IN BOOLEAN TurnItOff
|
||
)
|
||
{
|
||
|
||
DWORD dwErr;
|
||
DWORD dwBlobSize=0;
|
||
RAS_DEVCONFIG *pRasDevCfg;
|
||
PDEVICE_OBJECT pDeviceObj;
|
||
MODEMSETTINGS *pModemSettings;
|
||
DEVCFG *pDevCfg;
|
||
|
||
|
||
|
||
pDeviceObj = (PDEVICE_OBJECT)pDevObjPtr;
|
||
|
||
//
|
||
// if this was not a callback case, we never messed with modem settings:
|
||
// don't do anything here
|
||
//
|
||
if (pDeviceObj->wchCallbackNumber[0] == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
dwErr = RasGetDevConfig(NULL, pDeviceObj->hPort,"modem",NULL,&dwBlobSize);
|
||
|
||
if (dwErr != ERROR_BUFFER_TOO_SMALL)
|
||
{
|
||
// what else can we do here? callback will faile, that's about it
|
||
DbgPrint("ArapSetModemParms: RasGetDevConfig failed with %ld\n",dwErr);
|
||
return;
|
||
}
|
||
|
||
pRasDevCfg = (RAS_DEVCONFIG *)LOCAL_ALLOC(LPTR,dwBlobSize);
|
||
if (pRasDevCfg == NULL)
|
||
{
|
||
// what else can we do here? callback will faile, that's about it
|
||
DbgPrint("ArapSetModemParms: alloc failed\n");
|
||
return;
|
||
}
|
||
|
||
dwErr = RasGetDevConfig(NULL, pDeviceObj->hPort,"modem",(PBYTE)pRasDevCfg,&dwBlobSize);
|
||
if (dwErr != 0)
|
||
{
|
||
// what else can we do here? callback will faile, that's about it
|
||
DbgPrint("ArapSetModemParms: RasGetDevConfig failed with %ld\n",dwErr);
|
||
LOCAL_FREE((PBYTE)pRasDevCfg);
|
||
return;
|
||
}
|
||
|
||
pDevCfg = (DEVCFG *) ((PBYTE) pRasDevCfg + pRasDevCfg->dwOffsetofModemSettings);
|
||
|
||
pModemSettings = (MODEMSETTINGS* )(((PBYTE)&pDevCfg->commconfig)
|
||
+ pDevCfg->commconfig.dwProviderOffset);
|
||
|
||
//
|
||
// is this routine called to turn the compression and errorcontrol off?
|
||
//
|
||
if (TurnItOff)
|
||
{
|
||
//
|
||
// turn error-control and compression off if it's on
|
||
//
|
||
pModemSettings->dwPreferredModemOptions &=
|
||
~(MDM_COMPRESSION | MDM_ERROR_CONTROL);
|
||
}
|
||
|
||
//
|
||
// no, it's called to turn it back on: just do it
|
||
//
|
||
else
|
||
{
|
||
pModemSettings->dwPreferredModemOptions |=
|
||
(MDM_COMPRESSION | MDM_ERROR_CONTROL);
|
||
}
|
||
|
||
RasSetDevConfig(pDeviceObj->hPort,"modem",(PBYTE)pRasDevCfg,dwBlobSize);
|
||
|
||
LOCAL_FREE((PBYTE)pRasDevCfg);
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|