1055 lines
29 KiB
C
1055 lines
29 KiB
C
/* Copyright (c) 1995, Microsoft Corporation, all rights reserved
|
|
**
|
|
** rasman.c
|
|
** RAS Manager helpers
|
|
** Listed alphabetically
|
|
**
|
|
** These routines have been exempted from the TCHARizing applied to the rest
|
|
** of the library because RASMAN is still an ANSI interface.
|
|
**
|
|
** 09/20/95 Steve Cobb
|
|
*/
|
|
|
|
#include <windows.h> // Win32 root
|
|
#include <stdlib.h> // for atol()
|
|
#include <debug.h> // Trace/Assert library
|
|
#include <nouiutil.h> // Our public header
|
|
#include <raserror.h> // RAS error constants
|
|
#include <mcx.h> // Unimodem
|
|
|
|
|
|
/* 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;
|
|
|
|
#define MANUAL_DIAL 0x0004
|
|
#define TERMINAL_PRE 0x0001
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
** Local prototypes
|
|
**----------------------------------------------------------------------------
|
|
*/
|
|
|
|
DWORD
|
|
GetRasDevices(
|
|
IN CHAR* pszDeviceType,
|
|
OUT RASMAN_DEVICE** ppDevices,
|
|
OUT WORD* pwEntries );
|
|
|
|
DWORD
|
|
GetRasPortParam(
|
|
IN HPORT hport,
|
|
IN CHAR* pszKey,
|
|
OUT RASMAN_PORTINFO** ppPortInfo,
|
|
OUT RAS_PARAMS** ppParam );
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
** Routines
|
|
**----------------------------------------------------------------------------
|
|
*/
|
|
|
|
|
|
DWORD
|
|
ClearRasdevStats(
|
|
IN RASDEV* pdev,
|
|
IN BOOL fBundle )
|
|
|
|
/* Resets statistics counters for a device.
|
|
**
|
|
** (Abolade Gbadegesin Nov-9-1995)
|
|
*/
|
|
{
|
|
if (pdev == NULL) { return ERROR_INVALID_PARAMETER; }
|
|
|
|
if ((HPORT)UlongToPtr(pdev->RD_Handle) == (HPORT)INVALID_HANDLE_VALUE) {
|
|
return ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
ASSERT(g_pRasPortClearStatistics);
|
|
return (fBundle ? g_pRasBundleClearStatistics((HPORT)UlongToPtr(pdev->RD_Handle))
|
|
: g_pRasPortClearStatistics((HPORT)UlongToPtr(pdev->RD_Handle)));
|
|
}
|
|
|
|
|
|
#if 0
|
|
DWORD
|
|
DeviceIdFromDeviceName(
|
|
TCHAR* pszDeviceName )
|
|
|
|
/* Returns the TAPI device ID associated with 'pszDeviceName'. Returns
|
|
** 0xFFFFFFFE if not found, 0xFFFFFFFF if found but not a Unimodem.
|
|
**
|
|
** This routine assumes that TAPI devices have unique names.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
DWORD dwId;
|
|
WORD wPorts;
|
|
RASMAN_PORT* pPorts;
|
|
|
|
TRACE("DeviceIdFromDeviceName");
|
|
|
|
dwId = 0xFFFFFFFE;
|
|
|
|
if (pszDeviceName)
|
|
{
|
|
dwErr = GetRasPorts( &pPorts, &wPorts );
|
|
if (dwErr == 0)
|
|
{
|
|
CHAR* pszDeviceNameA;
|
|
pszDeviceNameA = StrDupAFromT( pszDeviceName );
|
|
if (pszDeviceNameA)
|
|
{
|
|
INT i;
|
|
RASMAN_PORT* pPort;
|
|
|
|
for (i = 0, pPort = pPorts; i < wPorts; ++i, ++pPort)
|
|
{
|
|
if (lstrcmpiA( pszDeviceNameA, pPort->P_DeviceName ) == 0)
|
|
{
|
|
dwId = pPort->P_LineDeviceId;
|
|
break;
|
|
}
|
|
}
|
|
Free( pszDeviceNameA );
|
|
}
|
|
Free( pPorts );
|
|
}
|
|
}
|
|
|
|
TRACE1("DeviceIdFromDeviceName=%d",dwErr);
|
|
return dwId;
|
|
}
|
|
#endif
|
|
|
|
DWORD
|
|
GetRasDevices(
|
|
IN CHAR* pszDeviceType,
|
|
OUT RASMAN_DEVICE** ppDevices,
|
|
OUT WORD* pwEntries )
|
|
|
|
/* Fills caller's '*ppDevices' with the address of a heap block containing
|
|
** '*pwEntries' RASMAN_DEVICE structures.
|
|
**
|
|
** Returns 0 if successful, otherwise a non-0 error code. If successful,
|
|
** it is the caller's responsibility to free the returned memory block.
|
|
*/
|
|
{
|
|
WORD wSize = 0;
|
|
DWORD dwErr;
|
|
|
|
TRACE1("GetRasDevices(%s)",pszDeviceType);
|
|
|
|
ASSERT(g_pRasDeviceEnum);
|
|
TRACE("RasDeviceEnum...");
|
|
dwErr = g_pRasDeviceEnum( pszDeviceType, NULL, &wSize, pwEntries );
|
|
TRACE2("RasDeviceEnum=%d,c=%d",dwErr,*pwEntries);
|
|
|
|
if (dwErr == 0)
|
|
{
|
|
/* No devices to enumerate. Set up to allocate a single byte anyway,
|
|
** so things work without lots of special code.
|
|
*/
|
|
wSize = 1;
|
|
}
|
|
else if (dwErr != ERROR_BUFFER_TOO_SMALL)
|
|
return dwErr;
|
|
|
|
*ppDevices = (RASMAN_DEVICE* )Malloc( wSize );
|
|
if (!*ppDevices)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
TRACE("RasDeviceEnum...");
|
|
dwErr = g_pRasDeviceEnum(
|
|
pszDeviceType, (PBYTE )*ppDevices, &wSize, pwEntries );
|
|
TRACE1("RasDeviceEnum=%d",dwErr);
|
|
|
|
if (dwErr != 0)
|
|
{
|
|
Free( *ppDevices );
|
|
return dwErr;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetRasDeviceString(
|
|
IN HPORT hport,
|
|
IN CHAR* pszDeviceType,
|
|
IN CHAR* pszDeviceName,
|
|
IN CHAR* pszKey,
|
|
OUT CHAR** ppszValue,
|
|
IN DWORD dwXlate )
|
|
|
|
/* Loads callers '*ppszValue' with the address of a heap block containing
|
|
** a NUL-terminated copy of the value string associated with key 'pszKey'
|
|
** for the device on port 'hport'. 'pszDeviceType' specifies the type of
|
|
** device, e.g. "modem". 'pszDeviceName' specifies the name of the
|
|
** device, e.g. "Hayes V-Series 9600". 'dwXlate' is a bit mask of XLATE_
|
|
** bits specifying translations to perform on the returned string.
|
|
**
|
|
** Returns 0 if successful, otherwise a non-0 error code. If successful,
|
|
** it is the caller's responsibility to Free the returned string.
|
|
*/
|
|
{
|
|
DWORD dwErr = 0;
|
|
RASMAN_DEVICEINFO* pDeviceInfo = NULL;
|
|
RAS_PARAMS* pParam;
|
|
WORD wSize = 0;
|
|
INT i;
|
|
|
|
TRACE2("GetRasDeviceString(%s,%s)",pszDeviceName,pszKey);
|
|
|
|
*ppszValue = NULL;
|
|
|
|
do
|
|
{
|
|
ASSERT(g_pRasDeviceGetInfo);
|
|
TRACE("RasDeviceGetInfo...");
|
|
dwErr = g_pRasDeviceGetInfo(
|
|
hport, pszDeviceType, pszDeviceName, NULL, &wSize );
|
|
TRACE2("RasDeviceGetInfo=%d,s=%d",dwErr,(INT)wSize);
|
|
|
|
if (dwErr != ERROR_BUFFER_TOO_SMALL && dwErr != 0)
|
|
break;
|
|
|
|
/* So it will fall thru and be "not found".
|
|
*/
|
|
if (wSize == 0)
|
|
wSize = 1;
|
|
|
|
pDeviceInfo = (RASMAN_DEVICEINFO* )Malloc( wSize );
|
|
if (!pDeviceInfo)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
TRACE("RasDeviceGetInfo...");
|
|
dwErr = g_pRasDeviceGetInfo(
|
|
hport, pszDeviceType, pszDeviceName, (PBYTE )pDeviceInfo, &wSize );
|
|
TRACE2("RasDeviceGetInfo=%d,s=%d",dwErr,(INT)wSize);
|
|
|
|
if (dwErr != 0)
|
|
break;
|
|
|
|
dwErr = ERROR_KEY_NOT_FOUND;
|
|
|
|
for (i = 0, pParam = pDeviceInfo->DI_Params;
|
|
i < (INT )pDeviceInfo->DI_NumOfParams;
|
|
++i, ++pParam)
|
|
{
|
|
if (lstrcmpiA( pParam->P_Key, pszKey ) == 0)
|
|
{
|
|
*ppszValue = PszFromRasValue( &pParam->P_Value, dwXlate );
|
|
|
|
dwErr = (*ppszValue) ? 0 : ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
while (FALSE);
|
|
|
|
Free0( pDeviceInfo );
|
|
|
|
TRACE1("String=\"%s\"",(*ppszValue)?*ppszValue:"");
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
DWORD
|
|
GetRasMessage(
|
|
IN HRASCONN hrasconn,
|
|
OUT TCHAR** ppszMessage )
|
|
|
|
/* Loads caller's '*ppszMessage' with the address of a heap block
|
|
** containing the current MXS_MESSAGE_KEY value associated with RAS
|
|
** connection 'hrasconn'.
|
|
**
|
|
** Returns 0 if successful or an error code. It is caller's
|
|
** responsibility to Free the returned string.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
RASCONNSTATUS rcs;
|
|
CHAR* pszMessage;
|
|
|
|
TRACE("GetRasMessage");
|
|
|
|
*ppszMessage = 0;
|
|
|
|
ZeroMemory( &rcs, sizeof(rcs) );
|
|
rcs.dwSize = sizeof(rcs);
|
|
ASSERT(g_pRasGetConnectStatus);
|
|
TRACE("RasGetConnectStatus");
|
|
dwErr = g_pRasGetConnectStatus( hrasconn, &rcs );
|
|
TRACE1("RasGetConnectStatus=%d",dwErr);
|
|
|
|
if (dwErr == 0)
|
|
{
|
|
CHAR* pszDeviceTypeA;
|
|
CHAR* pszDeviceNameA;
|
|
|
|
pszDeviceTypeA = StrDupAFromT( rcs.szDeviceType );
|
|
pszDeviceNameA = StrDupAFromT( rcs.szDeviceName );
|
|
if (!pszDeviceTypeA || !pszDeviceNameA)
|
|
{
|
|
Free0( pszDeviceNameA );
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
dwErr = GetRasDeviceString(
|
|
g_pRasGetHport( hrasconn ), pszDeviceTypeA, pszDeviceNameA,
|
|
MXS_MESSAGE_KEY, &pszMessage, XLATE_ErrorResponse );
|
|
|
|
Free0( pszDeviceTypeA );
|
|
Free0( pszDeviceNameA );
|
|
|
|
if (dwErr == 0)
|
|
{
|
|
*ppszMessage = StrDupTFromA( pszMessage );
|
|
if (!*ppszMessage)
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
Free0( pszMessage );
|
|
}
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetRasPads(
|
|
OUT RASMAN_DEVICE** ppDevices,
|
|
OUT WORD* pwEntries )
|
|
|
|
/* Fills caller's '*ppDevices' with the address of a heap block containing
|
|
** '*pwEntries' X.25 PAD DEVICE structures.
|
|
**
|
|
** Returns 0 if successful, otherwise a non-0 error code. If successful,
|
|
** it is the caller's responsibility to free the returned memory block.
|
|
*/
|
|
{
|
|
return GetRasDevices( MXS_PAD_TXT, ppDevices, pwEntries );
|
|
}
|
|
|
|
|
|
VOID
|
|
GetRasPortMaxBps(
|
|
IN HPORT hport,
|
|
OUT DWORD* pdwMaxConnectBps,
|
|
OUT DWORD* pdwMaxCarrierBps )
|
|
|
|
/* Loads callers '*pdwMaxConnectBps' with the maximum port->modem bps rate
|
|
** for port 'pport', or with 0 if not found. '*pdwMaxCarrierBps' is the
|
|
** same but for maximum modem->modem speed.
|
|
*/
|
|
{
|
|
CHAR* pszValue;
|
|
DWORD dwErr;
|
|
|
|
TRACE("GetRasPortMaxBps");
|
|
|
|
dwErr = GetRasPortString(
|
|
hport, SER_CONNECTBPS_KEY, &pszValue, XLATE_None );
|
|
if (dwErr == 0)
|
|
*pdwMaxConnectBps = (DWORD )atol( pszValue );
|
|
else
|
|
*pdwMaxConnectBps = 0;
|
|
|
|
dwErr = GetRasPortString(
|
|
hport, SER_CARRIERBPS_KEY, &pszValue, XLATE_None );
|
|
if (dwErr == 0)
|
|
*pdwMaxCarrierBps = (DWORD )atol( pszValue );
|
|
else
|
|
*pdwMaxCarrierBps = 0;
|
|
}
|
|
|
|
|
|
VOID
|
|
GetRasPortModemSettings(
|
|
IN HPORT hport,
|
|
OUT BOOL* pfHwFlowDefault,
|
|
OUT BOOL* pfEcDefault,
|
|
OUT BOOL* pfEccDefault )
|
|
|
|
/* Loads caller's flags with the default setting of Hardware Flow Control,
|
|
** Error Control, and Error Control and Compression for the given 'hport'.
|
|
*/
|
|
{
|
|
CHAR* pszValue = NULL;
|
|
|
|
*pfHwFlowDefault = TRUE;
|
|
*pfEcDefault = TRUE;
|
|
*pfEccDefault = TRUE;
|
|
|
|
if (GetRasPortString(
|
|
hport, SER_C_DEFAULTOFFSTR_KEY, &pszValue, XLATE_None ) == 0)
|
|
{
|
|
if (StrStrA( pszValue, MXS_HDWFLOWCONTROL_KEY ) != NULL)
|
|
*pfHwFlowDefault = FALSE;
|
|
|
|
if (StrStrA( pszValue, MXS_PROTOCOL_KEY ) != NULL)
|
|
*pfEcDefault = FALSE;
|
|
|
|
if (StrStrA( pszValue, MXS_COMPRESSION_KEY ) != NULL)
|
|
*pfEccDefault = FALSE;
|
|
|
|
Free0( pszValue );
|
|
}
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetRasPortParam(
|
|
IN HPORT hport,
|
|
IN CHAR* pszKey,
|
|
OUT RASMAN_PORTINFO** ppPortInfo,
|
|
OUT RAS_PARAMS** ppParam )
|
|
|
|
/* Loads callers '*ppParam' with the address of a RAS_PARAM block
|
|
** associated with key 'pszKey', or NULL if none. 'ppPortInfo' is the
|
|
** address of the array of RAS_PARAMS containing the found 'pparam'.
|
|
**
|
|
** Returns 0 if successful, otherwise a non-0 error code. If successful,
|
|
** it is the caller's responsibility to Free the returned '*ppPortInfo'.
|
|
*/
|
|
{
|
|
DWORD dwErr = 0;
|
|
WORD wSize = 0;
|
|
INT i;
|
|
|
|
TRACE("GetRasPortParam");
|
|
|
|
*ppPortInfo = NULL;
|
|
|
|
do
|
|
{
|
|
ASSERT(g_pRasPortGetInfo);
|
|
TRACE("RasPortGetInfo");
|
|
dwErr = g_pRasPortGetInfo( hport, NULL, &wSize );
|
|
TRACE2("RasPortGetInfo=%d,s=%d",dwErr,(INT)wSize);
|
|
|
|
if (dwErr != ERROR_BUFFER_TOO_SMALL && dwErr != 0)
|
|
break;
|
|
|
|
/* So it will fall thru and be "not found".
|
|
*/
|
|
if (wSize == 0)
|
|
wSize = 1;
|
|
|
|
*ppPortInfo = (RASMAN_PORTINFO* )Malloc( wSize );
|
|
if (!*ppPortInfo)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
TRACE("RasPortGetInfo");
|
|
dwErr = g_pRasPortGetInfo( hport, (PBYTE )*ppPortInfo, &wSize );
|
|
TRACE2("RasPortGetInfo=%d,s=%d",dwErr,(INT)wSize);
|
|
|
|
if (dwErr != 0)
|
|
break;
|
|
|
|
for (i = 0, *ppParam = (*ppPortInfo)->PI_Params;
|
|
i < (INT )(*ppPortInfo)->PI_NumOfParams;
|
|
++i, ++(*ppParam))
|
|
{
|
|
if (lstrcmpiA( (*ppParam)->P_Key, pszKey ) == 0)
|
|
break;
|
|
}
|
|
|
|
if (i >= (INT )(*ppPortInfo)->PI_NumOfParams)
|
|
dwErr = ERROR_KEY_NOT_FOUND;
|
|
}
|
|
while (FALSE);
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetRasPorts(
|
|
OUT RASMAN_PORT** ppPorts,
|
|
OUT WORD* pwEntries )
|
|
|
|
/* Enumerate RAS ports. Sets '*ppPort' to the address of a heap memory
|
|
** block containing an array of PORT structures with '*pwEntries'
|
|
** elements.
|
|
**
|
|
** Returns 0 if successful, otherwise a non-0 error code. If successful,
|
|
** it is the caller's responsibility to free the returned memory block.
|
|
*/
|
|
{
|
|
WORD wSize = 0;
|
|
DWORD dwErr;
|
|
|
|
TRACE("GetRasPorts");
|
|
|
|
#if 0 // Phonebook test dummies
|
|
|
|
{
|
|
RASMAN_PORT* pPort;
|
|
|
|
TRACE("TEST: Fake ISDN ports");
|
|
|
|
*pwEntries = 5;
|
|
wSize = *pwEntries * sizeof(RASMAN_PORT);
|
|
|
|
*ppPorts = (RASMAN_PORT* )Malloc( wSize );
|
|
if (!*ppPorts)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
pPort = *ppPorts;
|
|
ZeroMemory( pPort, sizeof(*pPort) );
|
|
lstrcpyA( pPort->P_PortName, "ISDN1" );
|
|
pPort->P_Status = CLOSED;
|
|
pPort->P_ConfiguredUsage = CALL_OUT;
|
|
pPort->P_CurrentUsage = CALL_OUT;
|
|
lstrcpyA( pPort->P_MediaName, "rastapi" );
|
|
lstrcpyA( pPort->P_DeviceName, "Digiboard PCIMac ISDN adapter" );
|
|
lstrcpyA( pPort->P_DeviceType, "ISDN" );
|
|
|
|
++pPort;
|
|
ZeroMemory( pPort, sizeof(*pPort) );
|
|
lstrcpyA( pPort->P_PortName, "ISDN2" );
|
|
pPort->P_Status = CLOSED;
|
|
pPort->P_ConfiguredUsage = CALL_OUT;
|
|
pPort->P_CurrentUsage = CALL_OUT;
|
|
lstrcpyA( pPort->P_MediaName, "rastapi" );
|
|
lstrcpyA( pPort->P_DeviceName, "Digiboard PCIMac ISDN adapter" );
|
|
lstrcpyA( pPort->P_DeviceType, "ISDN" );
|
|
|
|
++pPort;
|
|
ZeroMemory( pPort, sizeof(*pPort) );
|
|
lstrcpyA( pPort->P_PortName, "COM1" );
|
|
pPort->P_Status = CLOSED;
|
|
pPort->P_ConfiguredUsage = CALL_OUT;
|
|
pPort->P_CurrentUsage = CALL_OUT;
|
|
lstrcpyA( pPort->P_MediaName, "rasser" );
|
|
lstrcpyA( pPort->P_DeviceName, "US Robotics Courier V32 bis" );
|
|
lstrcpyA( pPort->P_DeviceType, "MODEM" );
|
|
|
|
++pPort;
|
|
ZeroMemory( pPort, sizeof(*pPort) );
|
|
lstrcpyA( pPort->P_PortName, "COM500" );
|
|
pPort->P_Status = CLOSED;
|
|
pPort->P_ConfiguredUsage = CALL_OUT;
|
|
pPort->P_CurrentUsage = CALL_OUT;
|
|
lstrcpyA( pPort->P_MediaName, "rasser" );
|
|
lstrcpyA( pPort->P_DeviceName, "Eicon X.PAD" );
|
|
lstrcpyA( pPort->P_DeviceType, "PAD" );
|
|
|
|
++pPort;
|
|
ZeroMemory( pPort, sizeof(*pPort) );
|
|
lstrcpyA( pPort->P_PortName, "VPN1" );
|
|
pPort->P_Status = CLOSED;
|
|
pPort->P_ConfiguredUsage = CALL_OUT;
|
|
pPort->P_CurrentUsage = CALL_OUT;
|
|
lstrcpyA( pPort->P_MediaName, "rastapi" );
|
|
lstrcpyA( pPort->P_DeviceName, "RASPPTPM" );
|
|
lstrcpyA( pPort->P_DeviceType, "VPN1" );
|
|
|
|
return 0;
|
|
}
|
|
|
|
#else
|
|
|
|
ASSERT(g_pRasPortEnum);
|
|
TRACE("RasPortEnum...");
|
|
dwErr = g_pRasPortEnum( NULL, &wSize, pwEntries );
|
|
TRACE2("RasPortEnum=%d,c=%d",dwErr,(INT)*pwEntries);
|
|
|
|
if (dwErr == 0)
|
|
{
|
|
/* No ports to enumerate. Set up to allocate a single byte anyway, so
|
|
** things work without lots of special code.
|
|
*/
|
|
wSize = 1;
|
|
}
|
|
else if (dwErr != ERROR_BUFFER_TOO_SMALL)
|
|
return dwErr;
|
|
|
|
*ppPorts = (RASMAN_PORT* )Malloc( wSize );
|
|
if (!*ppPorts)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
TRACE("RasPortEnum...");
|
|
dwErr = g_pRasPortEnum( (PBYTE )*ppPorts, &wSize, pwEntries );
|
|
TRACE2("RasPortEnum=%d,c=%d",dwErr,(INT)*pwEntries);
|
|
|
|
if (dwErr != 0)
|
|
{
|
|
Free( *ppPorts );
|
|
*ppPorts = NULL;
|
|
return dwErr;
|
|
}
|
|
|
|
#endif
|
|
|
|
#if 1 // Verbose trace
|
|
{
|
|
RASMAN_PORT* pPort;
|
|
WORD i;
|
|
|
|
for (pPort = *ppPorts, i = 0; i < *pwEntries; ++i, ++pPort)
|
|
{
|
|
TRACE4("Port[%d]=%s,DID=$%08x,AID=$%08x",
|
|
pPort->P_Handle,pPort->P_PortName,
|
|
pPort->P_LineDeviceId,pPort->P_AddressId);
|
|
TRACE3(" M=%s,DT=%s,DN=%s",
|
|
pPort->P_MediaName,pPort->P_DeviceType,pPort->P_DeviceName);
|
|
TRACE3(" S=$%08x,CfgU=$%08x,CurU=$%08x",
|
|
pPort->P_Status,pPort->P_ConfiguredUsage,pPort->P_CurrentUsage);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetRasPortString(
|
|
IN HPORT hport,
|
|
IN CHAR* pszKey,
|
|
OUT CHAR** ppszValue,
|
|
IN DWORD dwXlate )
|
|
|
|
/* Loads callers '*ppszValue' with the address of a heap block containing
|
|
** a NUL-terminated copy of the value string associated with key 'pszKey'
|
|
** on port 'hport'. 'dwXlate' is a bit mask of XLATE_ bits specifying
|
|
** translations to be done on the string value.
|
|
**
|
|
** Returns 0 if successful, otherwise a non-0 error code. If successful,
|
|
** it is the caller's responsibility to Free the returned string.
|
|
*/
|
|
{
|
|
RASMAN_PORTINFO* pPortInfo;
|
|
RAS_PARAMS* pParam;
|
|
DWORD dwErr;
|
|
|
|
TRACE("GetRasPortString");
|
|
|
|
dwErr = GetRasPortParam( hport, pszKey, &pPortInfo, &pParam );
|
|
|
|
*ppszValue = NULL;
|
|
|
|
if (dwErr == 0)
|
|
{
|
|
*ppszValue = PszFromRasValue( &pParam->P_Value, dwXlate );
|
|
dwErr = (*ppszValue) ? 0 : ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
Free0( pPortInfo );
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
GetRasSwitches(
|
|
OUT RASMAN_DEVICE** ppDevices,
|
|
OUT WORD* pwEntries )
|
|
|
|
/* Fills caller's '*ppDevices' with the address of a heap block containing
|
|
** '*pwEntries' switch DEVICE structures.
|
|
**
|
|
** Returns 0 if successful, otherwise a non-0 error code. If successful,
|
|
** it is the caller's responsibility to free the returned memory block.
|
|
*/
|
|
{
|
|
return GetRasDevices( MXS_SWITCH_TXT, ppDevices, pwEntries );
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetRasUnimodemBlob(
|
|
IN HPORT hport,
|
|
IN CHAR* pszDeviceType,
|
|
OUT BYTE** ppBlob,
|
|
OUT DWORD* pcbBlob )
|
|
|
|
/* Loads '*ppBlob' and '*pcbBlob' with the sanitized Unimodem blob and
|
|
** size associated with 'hport' and 'pszDeviceType'. It is caller's
|
|
** responsibility to Free the returned '*ppBlob'.
|
|
**
|
|
** Returns 0 if successful, or an error code.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
BYTE* pBlob;
|
|
DWORD cbBlob;
|
|
|
|
cbBlob = 0;
|
|
|
|
ASSERT(g_pRasGetDevConfig);
|
|
TRACE("RasGetDevConfig");
|
|
dwErr = g_pRasGetDevConfig( hport, pszDeviceType, NULL, &cbBlob );
|
|
TRACE1("RasGetDevConfig=%d",dwErr);
|
|
|
|
if (dwErr != 0 && dwErr != ERROR_BUFFER_TOO_SMALL)
|
|
return dwErr;
|
|
|
|
if (cbBlob > 0)
|
|
{
|
|
pBlob = Malloc( cbBlob );
|
|
if (!pBlob)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
TRACE("RasGetDevConfig");
|
|
dwErr = g_pRasGetDevConfig( hport, pszDeviceType, pBlob, &cbBlob );
|
|
TRACE1("RasGetDevConfig=%d",dwErr);
|
|
|
|
if (dwErr != 0)
|
|
{
|
|
Free( pBlob );
|
|
return dwErr;
|
|
}
|
|
|
|
SanitizeUnimodemBlob( pBlob );
|
|
}
|
|
else
|
|
pBlob = NULL;
|
|
|
|
*ppBlob = pBlob;
|
|
*pcbBlob = cbBlob;
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
VOID
|
|
GetRasUnimodemInfo(
|
|
IN HPORT hport,
|
|
IN CHAR* pszDeviceType,
|
|
OUT UNIMODEMINFO* pInfo )
|
|
|
|
/* Loads 'pInfo' with the RAS-relevant information of the port 'hport'
|
|
** with device name 'pszDeviceName'.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
BYTE* pBlob;
|
|
DWORD cbBlob;
|
|
|
|
SetDefaultUnimodemInfo( pInfo );
|
|
|
|
dwErr = GetRasUnimodemBlob( hport, pszDeviceType, &pBlob, &cbBlob );
|
|
if (dwErr == 0 && cbBlob > 0)
|
|
UnimodemInfoFromBlob( pBlob, pInfo );
|
|
|
|
Free0( pBlob );
|
|
}
|
|
|
|
CHAR*
|
|
PszFromRasValue(
|
|
IN RAS_VALUE* prasvalue,
|
|
IN DWORD dwXlate )
|
|
|
|
/* Returns the address of a heap block containing a NUL-terminated string
|
|
** value from caller's '*prasvalue', or NULL if out of memory. 'dwXlate'
|
|
** is a bit mask of XLATE_ bits specifying translations to be performed on
|
|
** the string. The value is assumed to be of format String. It is
|
|
** translated to modem.inf style.
|
|
*/
|
|
{
|
|
#define MAXEXPANDPERCHAR 5
|
|
#define HEXCHARS "0123456789ABCDEF"
|
|
|
|
INT i;
|
|
BOOL fXlate;
|
|
BOOL fXlateCtrl;
|
|
BOOL fXlateCr;
|
|
BOOL fXlateCrSpecial;
|
|
BOOL fXlateLf;
|
|
BOOL fXlateLfSpecial;
|
|
BOOL fXlateLAngle;
|
|
BOOL fXlateRAngle;
|
|
BOOL fXlateBSlash;
|
|
BOOL fXlateSSpace;
|
|
BOOL fNoCharSinceLf;
|
|
INT nLen;
|
|
CHAR* pszIn;
|
|
CHAR* pszBuf;
|
|
CHAR* pszOut;
|
|
|
|
nLen = prasvalue->String.Length;
|
|
pszIn = prasvalue->String.Data;
|
|
|
|
pszBuf = Malloc( (nLen * MAXEXPANDPERCHAR) + 1 );
|
|
if (!pszBuf)
|
|
return NULL;
|
|
|
|
/* Translate the returned string based on the translation bit map. The
|
|
** assumption here is that all these devices talk ASCII and not some
|
|
** localized ANSI.
|
|
*/
|
|
fXlate = (dwXlate != 0);
|
|
fXlateCtrl = (dwXlate & XLATE_Ctrl);
|
|
fXlateCr = (dwXlate & XLATE_Cr);
|
|
fXlateCrSpecial = (dwXlate & XLATE_CrSpecial);
|
|
fXlateLf = (dwXlate & XLATE_Lf);
|
|
fXlateLfSpecial = (dwXlate & XLATE_LfSpecial);
|
|
fXlateLAngle = (dwXlate & XLATE_LAngle);
|
|
fXlateRAngle = (dwXlate & XLATE_RAngle);
|
|
fXlateBSlash = (dwXlate & XLATE_BSlash);
|
|
fXlateSSpace = (dwXlate & XLATE_SSpace);
|
|
|
|
pszOut = pszBuf;
|
|
fNoCharSinceLf = TRUE;
|
|
for (i = 0; i < nLen; ++i)
|
|
{
|
|
CHAR ch = pszIn[ i ];
|
|
|
|
if (fXlate)
|
|
{
|
|
if (ch == 0x0D)
|
|
{
|
|
if (fXlateSSpace && fNoCharSinceLf)
|
|
continue;
|
|
|
|
if (fXlateCrSpecial)
|
|
{
|
|
/* Special symbol for carriage return.
|
|
*/
|
|
lstrcpyA( pszOut, "<cr>" );
|
|
pszOut += 4;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (ch == 0x0A)
|
|
{
|
|
if (fXlateSSpace && fNoCharSinceLf)
|
|
continue;
|
|
|
|
fNoCharSinceLf = TRUE;
|
|
|
|
if (fXlateLfSpecial)
|
|
{
|
|
/* Special symbol for line feed.
|
|
*/
|
|
lstrcpyA( pszOut, "<lf>" );
|
|
pszOut += 4;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (ch != 0x0A && ch != 0x0D)
|
|
fNoCharSinceLf = FALSE;
|
|
|
|
if ((((ch < 0x20 || ch > 0x7E)
|
|
&& ch != 0x0D && ch != 0x0A) && fXlateCtrl)
|
|
|| (ch == 0x0D && fXlateCr)
|
|
|| (ch == 0x0A && fXlateLf)
|
|
|| (ch == 0x3C && fXlateLAngle)
|
|
|| (ch == 0x3E && fXlateRAngle)
|
|
|| (ch == 0x5C && fXlateBSlash))
|
|
{
|
|
/* Expand to "dump" form, i.e. <hFF> where FF is the hex value
|
|
** of the character.
|
|
*/
|
|
*pszOut++ = '<';
|
|
*pszOut++ = 'h';
|
|
*pszOut++ = HEXCHARS[ ch / 16 ];
|
|
*pszOut++ = HEXCHARS[ ch % 16 ];
|
|
*pszOut++ = '>';
|
|
continue;
|
|
}
|
|
}
|
|
|
|
/* Just copy without translation.
|
|
*/
|
|
*pszOut++ = ch;
|
|
}
|
|
|
|
*pszOut = '\0';
|
|
pszOut = Realloc( pszBuf, lstrlenA( pszBuf ) + 1 );
|
|
if(!pszOut)
|
|
{
|
|
Free(pszBuf);
|
|
return NULL;
|
|
}
|
|
|
|
return pszOut;
|
|
}
|
|
|
|
|
|
VOID
|
|
SanitizeUnimodemBlob(
|
|
IN OUT BYTE* pBlob )
|
|
|
|
/* Fix non-RAS-compatible settings in unimodem blob 'pBlob'.
|
|
**
|
|
** (Based on Gurdeepian routine)
|
|
*/
|
|
{
|
|
DEVCFG* pDevCfg;
|
|
MODEMSETTINGS* pModemSettings;
|
|
|
|
pDevCfg = (DEVCFG* )pBlob;
|
|
pModemSettings = (MODEMSETTINGS* )(((BYTE* )&pDevCfg->commconfig)
|
|
+ pDevCfg->commconfig.dwProviderOffset);
|
|
|
|
/* No unimodem service provider pre/post-connect terminal, operator dial,
|
|
** or tray lights. RAS does these itself.
|
|
*/
|
|
pDevCfg->dfgHdr.fwOptions = 0;
|
|
|
|
pDevCfg->commconfig.dcb.fBinary = TRUE;
|
|
pDevCfg->commconfig.dcb.fParity = TRUE;
|
|
pDevCfg->commconfig.dcb.fOutxDsrFlow = FALSE;
|
|
pDevCfg->commconfig.dcb.fDtrControl = DTR_CONTROL_ENABLE;
|
|
pDevCfg->commconfig.dcb.fTXContinueOnXoff = FALSE;
|
|
pDevCfg->commconfig.dcb.fOutX = FALSE;
|
|
pDevCfg->commconfig.dcb.fInX = FALSE;
|
|
pDevCfg->commconfig.dcb.fErrorChar = FALSE;
|
|
pDevCfg->commconfig.dcb.fNull = FALSE;
|
|
pDevCfg->commconfig.dcb.fAbortOnError = FALSE;
|
|
pDevCfg->commconfig.dcb.ByteSize = 8;
|
|
pDevCfg->commconfig.dcb.Parity = NOPARITY;
|
|
pDevCfg->commconfig.dcb.StopBits = ONESTOPBIT;
|
|
|
|
/* Wait 55 seconds to establish call.
|
|
*/
|
|
pModemSettings->dwCallSetupFailTimer = 55;
|
|
|
|
/* Disable inactivity timeout.
|
|
*/
|
|
pModemSettings->dwInactivityTimeout = 0;
|
|
}
|
|
|
|
|
|
VOID
|
|
SetDefaultUnimodemInfo(
|
|
OUT UNIMODEMINFO* pInfo )
|
|
|
|
/* Sets 'pInfo' to default settings.
|
|
*/
|
|
{
|
|
pInfo->fHwFlow = FALSE;
|
|
pInfo->fEc = FALSE;
|
|
pInfo->fEcc = FALSE;
|
|
pInfo->dwBps = 9600;
|
|
pInfo->fSpeaker = TRUE;
|
|
pInfo->fOperatorDial = FALSE;
|
|
pInfo->fUnimodemPreTerminal = FALSE;
|
|
}
|
|
|
|
|
|
VOID
|
|
UnimodemInfoFromBlob(
|
|
IN BYTE* pBlob,
|
|
OUT UNIMODEMINFO* pInfo )
|
|
|
|
/* Loads 'pInfo' with RAS-relevant Unimodem information retrieved from
|
|
** Unimodem blob 'pBlob'.
|
|
**
|
|
** (Based on Gurdeepian routine)
|
|
*/
|
|
{
|
|
DEVCFG* pDevCfg;
|
|
MODEMSETTINGS* pModemSettings;
|
|
|
|
pDevCfg = (DEVCFG* )pBlob;
|
|
pModemSettings = (MODEMSETTINGS* )(((BYTE* )&pDevCfg->commconfig)
|
|
+ pDevCfg->commconfig.dwProviderOffset);
|
|
|
|
pInfo->fSpeaker =
|
|
(pModemSettings->dwSpeakerMode != MDMSPKR_OFF)
|
|
? TRUE : FALSE;
|
|
|
|
pInfo->fHwFlow =
|
|
(pModemSettings->dwPreferredModemOptions & MDM_FLOWCONTROL_HARD)
|
|
? TRUE : FALSE;
|
|
|
|
pInfo->fEcc =
|
|
(pModemSettings->dwPreferredModemOptions & MDM_COMPRESSION)
|
|
? TRUE : FALSE;
|
|
|
|
pInfo->fEc =
|
|
(pModemSettings->dwPreferredModemOptions & MDM_ERROR_CONTROL)
|
|
? TRUE : FALSE;
|
|
|
|
pInfo->dwBps = pDevCfg->commconfig.dcb.BaudRate;
|
|
|
|
pInfo->fOperatorDial =
|
|
(pDevCfg->dfgHdr.fwOptions & MANUAL_DIAL)
|
|
? TRUE : FALSE;
|
|
|
|
pInfo->fUnimodemPreTerminal =
|
|
(pDevCfg->dfgHdr.fwOptions & TERMINAL_PRE)
|
|
? TRUE : FALSE;
|
|
}
|
|
|
|
|
|
VOID
|
|
UnimodemInfoToBlob(
|
|
IN UNIMODEMINFO* pInfo,
|
|
IN OUT BYTE* pBlob )
|
|
|
|
/* Applies RAS-relevant Unimodem information supplied in 'pInfo' to
|
|
** Unimodem blob 'pBlob'.
|
|
**
|
|
** (Based on Gurdeepian routine)
|
|
*/
|
|
{
|
|
DEVCFG* pDevCfg;
|
|
MODEMSETTINGS* pModemSettings;
|
|
|
|
pDevCfg = (DEVCFG* )pBlob;
|
|
pModemSettings = (MODEMSETTINGS* )(((BYTE* )&pDevCfg->commconfig)
|
|
+ pDevCfg->commconfig.dwProviderOffset);
|
|
|
|
pModemSettings->dwSpeakerMode =
|
|
(pInfo->fSpeaker) ? MDMSPKR_DIAL : MDMSPKR_OFF;
|
|
|
|
if (pInfo->fHwFlow)
|
|
{
|
|
pDevCfg->commconfig.dcb.fOutxCtsFlow = TRUE;
|
|
pDevCfg->commconfig.dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
|
|
pModemSettings->dwPreferredModemOptions |= MDM_FLOWCONTROL_HARD;
|
|
}
|
|
else
|
|
{
|
|
pDevCfg->commconfig.dcb.fOutxCtsFlow = FALSE;
|
|
pDevCfg->commconfig.dcb.fRtsControl = RTS_CONTROL_DISABLE;
|
|
pModemSettings->dwPreferredModemOptions &= ~(MDM_FLOWCONTROL_HARD);
|
|
}
|
|
|
|
if (pInfo->fEc)
|
|
pModemSettings->dwPreferredModemOptions |= MDM_ERROR_CONTROL;
|
|
else
|
|
pModemSettings->dwPreferredModemOptions &= ~(MDM_ERROR_CONTROL);
|
|
|
|
if (pInfo->fEcc)
|
|
pModemSettings->dwPreferredModemOptions |= MDM_COMPRESSION;
|
|
else
|
|
pModemSettings->dwPreferredModemOptions &= ~(MDM_COMPRESSION);
|
|
|
|
pDevCfg->commconfig.dcb.BaudRate = pInfo->dwBps;
|
|
|
|
if (pInfo->fOperatorDial)
|
|
pDevCfg->dfgHdr.fwOptions |= MANUAL_DIAL;
|
|
|
|
if (pInfo->fUnimodemPreTerminal)
|
|
pDevCfg->dfgHdr.fwOptions |= TERMINAL_PRE;
|
|
}
|