You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2148 lines
55 KiB
2148 lines
55 KiB
/* 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
|
|
|
|
#include <unimodem.h>
|
|
|
|
/* 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
|
|
|
|
// Test rig to return a variety of fake ports from GetRasPorts.
|
|
//
|
|
#define DUMMYPORTS 0
|
|
#if DUMMYPORTS
|
|
DWORD g_cPorts = 6;
|
|
#endif
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
** Local prototypes
|
|
**----------------------------------------------------------------------------
|
|
*/
|
|
|
|
DWORD
|
|
GetRasDevices(
|
|
IN HANDLE hConnection,
|
|
IN CHAR* pszDeviceType,
|
|
OUT RASMAN_DEVICE** ppDevices,
|
|
OUT DWORD* pdwEntries );
|
|
|
|
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)pdev->RD_Handle == (HPORT)INVALID_HANDLE_VALUE) {
|
|
return ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
ASSERT(g_pRasPortClearStatistics);
|
|
return (fBundle ? g_pRasBundleClearStatistics(NULL, (HPORT)pdev->RD_Handle)
|
|
: g_pRasPortClearStatistics(NULL, (HPORT)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;
|
|
DWORD dwPorts;
|
|
RASMAN_PORT* pPorts;
|
|
|
|
TRACE("DeviceIdFromDeviceName");
|
|
|
|
dwId = 0xFFFFFFFE;
|
|
|
|
if (pszDeviceName)
|
|
{
|
|
dwErr = GetRasPorts( &pPorts, &dwPorts );
|
|
if (dwErr == 0)
|
|
{
|
|
CHAR* pszDeviceNameA;
|
|
pszDeviceNameA = StrDupAFromT( pszDeviceName );
|
|
if (pszDeviceNameA)
|
|
{
|
|
INT i;
|
|
RASMAN_PORT* pPort;
|
|
|
|
for (i = 0, pPort = pPorts; i < dwPorts; ++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
|
|
FreeRasdevTable(
|
|
RASDEV* pDevTable,
|
|
DWORD iDevCount )
|
|
|
|
/* Frees a table built by GetRasdevTable.
|
|
**
|
|
** Returns 0 if succesful, or an error code.
|
|
**
|
|
** (Abolade Gbadegesin Nov-9-1995)
|
|
*/
|
|
{
|
|
DWORD i;
|
|
|
|
//
|
|
// validate arguments
|
|
//
|
|
|
|
if (pDevTable == NULL) { return ERROR_INVALID_PARAMETER; }
|
|
|
|
//
|
|
// free the device-name string fields
|
|
//
|
|
|
|
for (i = 0; i < iDevCount; i++) {
|
|
if (pDevTable[i].RD_DeviceName) { Free(pDevTable[i].RD_DeviceName); }
|
|
}
|
|
|
|
//
|
|
// free the array itself
|
|
//
|
|
|
|
Free(pDevTable);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetConnectTime(
|
|
IN HRASCONN hrasconn,
|
|
OUT DWORD* pdwConnectTime )
|
|
|
|
/* Loads '*pdwConnectTime' with the duration in milliseconds of the
|
|
** connection on pdev.
|
|
**
|
|
** Returns 0 if succesful, or an error code.
|
|
**
|
|
** (Abolade Gbadegesin Nov-9-1995)
|
|
*/
|
|
{
|
|
HPORT hport;
|
|
DWORD dwErr;
|
|
RASMAN_INFO info;
|
|
|
|
if (pdwConnectTime == NULL) { return ERROR_INVALID_PARAMETER; }
|
|
|
|
//
|
|
// initialize the argument
|
|
//
|
|
|
|
*pdwConnectTime = 0;
|
|
|
|
//
|
|
// get an HPORT for the HRASCONN
|
|
//
|
|
|
|
ASSERT(g_pRasGetHport);
|
|
hport = g_pRasGetHport(hrasconn);
|
|
if (hport == (HPORT)INVALID_HANDLE_VALUE) { return ERROR_INVALID_HANDLE; }
|
|
|
|
//
|
|
// get information on the HPORT
|
|
//
|
|
|
|
ASSERT(g_pRasGetInfo);
|
|
dwErr = g_pRasGetInfo(NULL, hport, &info);
|
|
if (dwErr != NO_ERROR) { return dwErr; }
|
|
|
|
|
|
if (info.RI_ConnState != CONNECTED) { *pdwConnectTime = 0; }
|
|
else { *pdwConnectTime = info.RI_ConnectDuration; }
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetRasconnFraming(
|
|
IN HRASCONN hrasconn,
|
|
OUT DWORD* pdwSendFraming,
|
|
OUT DWORD* pdwRecvFraming )
|
|
|
|
/* Retrieves the framing bits for an active RAS connection.
|
|
**
|
|
** (Abolade Gbadegesin Nov-9-1995)
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
HPORT hport;
|
|
RAS_FRAMING_INFO info;
|
|
|
|
//
|
|
// validate arguments
|
|
//
|
|
|
|
if (pdwSendFraming == NULL || pdwRecvFraming == NULL) {
|
|
return ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
|
|
//
|
|
// retrieve the HPORT for this connection
|
|
//
|
|
|
|
ASSERT(g_pRasGetHport);
|
|
hport = g_pRasGetHport(hrasconn);
|
|
if (hport == (HPORT)INVALID_HANDLE_VALUE) {
|
|
return ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
//
|
|
// retrieve the framing information for this port
|
|
//
|
|
|
|
ASSERT(g_pRasPortGetFramingEx);
|
|
dwErr = g_pRasPortGetFramingEx(NULL, hport, &info);
|
|
if (dwErr != NO_ERROR) { return dwErr; }
|
|
|
|
|
|
*pdwSendFraming = info.RFI_SendFramingBits;
|
|
*pdwRecvFraming = info.RFI_RecvFramingBits;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetRasconnFromRasdev(
|
|
IN RASDEV* pdev,
|
|
OUT RASCONN** ppconn,
|
|
IN RASCONN* pConnTable OPTIONAL,
|
|
IN DWORD iConnCount OPTIONAL )
|
|
|
|
/* Given a RASDEV structure for an active device, this function retrieves
|
|
** the RASCONN which corresponds to the device's current connection. The
|
|
** second and third arguments are optional; they specify a table of
|
|
** RASCONN structures to be searched. This is useful if the caller has
|
|
** already enumerated the active connections, so that this function does
|
|
** not need to re-enumerate them.
|
|
**
|
|
** (Abolade Gbadegesin Nov-9-1995)
|
|
*/
|
|
{
|
|
BOOL bFreeTable;
|
|
DWORD dwErr, i;
|
|
RASDEVSTATS stats;
|
|
|
|
//
|
|
// validate arguments
|
|
//
|
|
|
|
if (pdev == NULL || ppconn == NULL) { return ERROR_INVALID_PARAMETER; }
|
|
|
|
*ppconn = NULL;
|
|
|
|
//
|
|
// get stats for the RASDEV
|
|
//
|
|
|
|
dwErr = GetRasdevStats(pdev, &stats);
|
|
if (dwErr != NO_ERROR) { return dwErr; }
|
|
|
|
|
|
bFreeTable = FALSE;
|
|
|
|
//
|
|
// if the caller didn't pass in a table of RASCONNs, retrieve one
|
|
//
|
|
|
|
if (pConnTable == NULL) {
|
|
|
|
dwErr = GetRasconnTable(&pConnTable, &iConnCount);
|
|
if (dwErr != NO_ERROR) { return dwErr; }
|
|
|
|
bFreeTable = TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// find the connection which matches the RASDEV passed in
|
|
//
|
|
|
|
for (i = 0; i < iConnCount; i++) {
|
|
|
|
if ((HRASCONN)stats.RDS_Hrasconn == (pConnTable + i)->hrasconn) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// see how the search ended
|
|
//
|
|
|
|
if (i >= iConnCount) {
|
|
dwErr = ERROR_NO_DATA;
|
|
}
|
|
else {
|
|
|
|
dwErr = NO_ERROR;
|
|
|
|
if (!bFreeTable) {
|
|
|
|
//
|
|
// point to the place where we found the RASCONN
|
|
//
|
|
|
|
*ppconn = pConnTable + i;
|
|
}
|
|
else {
|
|
|
|
//
|
|
// make a copy of the RASCONN found
|
|
//
|
|
|
|
*ppconn = Malloc(sizeof(RASCONN));
|
|
|
|
if (!*ppconn) { dwErr = ERROR_NOT_ENOUGH_MEMORY; }
|
|
else { **ppconn = *(pConnTable + i); }
|
|
}
|
|
}
|
|
|
|
if (bFreeTable) { Free(pConnTable); }
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetRasdevBundle(
|
|
IN RASDEV* pdev,
|
|
OUT DWORD* pdwBundle )
|
|
|
|
/* Retrieves a handle which represents the current connection
|
|
** on the given device. This handle has the property that it will be
|
|
** identical for two devices which are multi-linked together.
|
|
** In the case of NT RAS, the RASMAN HBUNDLE is retrieved.
|
|
**
|
|
** (Abolade Gbadegesin Mar-6-1996)
|
|
*/
|
|
{
|
|
|
|
return g_pRasPortGetBundle(NULL, (HPORT)pdev->RD_Handle, (HBUNDLE *)pdwBundle);
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetRasdevFraming(
|
|
IN RASDEV* pdev,
|
|
OUT DWORD* pdwFraming )
|
|
|
|
/* Retrieves the framing bits for an active RAS connection.
|
|
**
|
|
** (Abolade Gbadegesin Nov-9-1995)
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
RAS_FRAMING_INFO info;
|
|
|
|
//
|
|
// validate arguments
|
|
//
|
|
|
|
if (pdwFraming == NULL) { return ERROR_INVALID_HANDLE; }
|
|
|
|
|
|
//
|
|
// retrieve the framing information for this port
|
|
//
|
|
|
|
ASSERT(g_pRasPortGetFramingEx);
|
|
dwErr = g_pRasPortGetFramingEx(NULL, (HPORT)pdev->RD_Handle, &info);
|
|
if (dwErr != NO_ERROR) { return dwErr; }
|
|
|
|
|
|
if (info.RFI_SendFramingBits & OLD_RAS_FRAMING) {
|
|
*pdwFraming = RASFP_Ras;
|
|
}
|
|
else
|
|
if (info.RFI_SendFramingBits & PPP_MULTILINK_FRAMING ||
|
|
info.RFI_SendFramingBits & PPP_FRAMING) {
|
|
*pdwFraming = RASFP_Ppp;
|
|
}
|
|
else
|
|
if (info.RFI_SendFramingBits & SLIP_FRAMING) {
|
|
*pdwFraming = RASFP_Slip;
|
|
}
|
|
else {
|
|
*pdwFraming = 0;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
DWORD
|
|
GetRasdevFromRasconn(
|
|
IN RASCONN* pconn,
|
|
OUT RASDEV** ppdev,
|
|
IN RASDEV* pDevTable OPTIONAL,
|
|
IN DWORD iDevCount OPTIONAL )
|
|
|
|
/* Given a RASCONN structure for an active connection, this function
|
|
** retrieves the RASDEV for the device over which the connection is
|
|
** active. The second and third arguments are optional; they specify a
|
|
** table of RASDEV structures to be searched. This is useful if the
|
|
** caller has already enumerated the existing devices, so that this
|
|
** function does not need to re-enumerate them.
|
|
**
|
|
** (Abolade Gbadegesin Nov-9-1995)
|
|
*/
|
|
{
|
|
HPORT hport;
|
|
DWORD i, dwErr = NO_ERROR;
|
|
BOOL bFreeTable;
|
|
|
|
//
|
|
// validate the arguments
|
|
//
|
|
|
|
if (pconn == NULL || ppdev == NULL) { return ERROR_INVALID_PARAMETER; }
|
|
|
|
*ppdev = NULL;
|
|
|
|
|
|
//
|
|
// retrieve the device table if the caller didn't pass one in
|
|
//
|
|
|
|
bFreeTable = FALSE;
|
|
|
|
// For whistler bug 26403 gangz
|
|
//
|
|
do
|
|
{
|
|
if (pDevTable == NULL) {
|
|
|
|
dwErr = GetRasdevTable(&pDevTable, &iDevCount);
|
|
if (dwErr != NO_ERROR) {
|
|
return dwErr;
|
|
}
|
|
|
|
bFreeTable = TRUE;
|
|
}
|
|
|
|
//
|
|
// retrieve the HPORT for the RASCONN passed in
|
|
//
|
|
|
|
ASSERT(g_pRasGetHport);
|
|
hport = g_pRasGetHport(pconn->hrasconn);
|
|
if (hport == (HPORT)INVALID_HANDLE_VALUE)
|
|
{
|
|
// For whistler bug 26403 gangz
|
|
// here to break rather than return;
|
|
//
|
|
dwErr = ERROR_INVALID_HANDLE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// find the device to which the HPORT corresponds
|
|
//
|
|
|
|
for (i = 0; i < iDevCount; i++) {
|
|
if (hport == pDevTable[i].RD_Handle) { break; }
|
|
}
|
|
|
|
//
|
|
// see how the search ended
|
|
//
|
|
|
|
if (i >= iDevCount)
|
|
{
|
|
dwErr = ERROR_NO_DATA;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
dwErr = NO_ERROR;
|
|
|
|
if (!bFreeTable) {
|
|
*ppdev = pDevTable + i;
|
|
}
|
|
else {
|
|
|
|
*ppdev = Malloc(sizeof(RASDEV));
|
|
|
|
if (!*ppdev) { dwErr = ERROR_NOT_ENOUGH_MEMORY; }
|
|
else {
|
|
|
|
**ppdev = *(pDevTable + i);
|
|
|
|
(*ppdev)->RD_DeviceName = StrDup(pDevTable[i].RD_DeviceName);
|
|
|
|
if (!(*ppdev)->RD_DeviceName) {
|
|
Free(*ppdev);
|
|
*ppdev = NULL;
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}while(FALSE);
|
|
|
|
if (bFreeTable) { FreeRasdevTable(pDevTable, iDevCount); }
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetRasDevices(
|
|
IN HANDLE hConnection,
|
|
IN CHAR* pszDeviceType,
|
|
OUT RASMAN_DEVICE** ppDevices,
|
|
OUT DWORD* pdwEntries )
|
|
|
|
/* 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.
|
|
*/
|
|
{
|
|
DWORD dwSize = 0;
|
|
DWORD dwErr;
|
|
|
|
TRACE1("GetRasDevices(%s)",pszDeviceType);
|
|
|
|
ASSERT(g_pRasDeviceEnum);
|
|
TRACE("RasDeviceEnum...");
|
|
dwErr = g_pRasDeviceEnum(hConnection, pszDeviceType, NULL, &dwSize, pdwEntries );
|
|
TRACE2("RasDeviceEnum=%d,c=%d",dwErr,*pdwEntries);
|
|
|
|
if (dwErr == 0)
|
|
{
|
|
/* No devices to enumerate. Set up to allocate a single byte anyway,
|
|
** so things work without lots of special code.
|
|
*/
|
|
dwSize = 1;
|
|
}
|
|
else if (dwErr != ERROR_BUFFER_TOO_SMALL)
|
|
return dwErr;
|
|
|
|
*ppDevices = (RASMAN_DEVICE* )Malloc( dwSize );
|
|
if (!*ppDevices)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
TRACE("RasDeviceEnum...");
|
|
dwErr = g_pRasDeviceEnum(
|
|
hConnection,
|
|
pszDeviceType,
|
|
(PBYTE )*ppDevices,
|
|
&dwSize,
|
|
pdwEntries );
|
|
|
|
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;
|
|
DWORD dwSize = 0;
|
|
INT i;
|
|
|
|
TRACE2("GetRasDeviceString(%s,%s)",pszDeviceName,pszKey);
|
|
|
|
*ppszValue = NULL;
|
|
|
|
do
|
|
{
|
|
ASSERT(g_pRasDeviceGetInfo);
|
|
TRACE("RasDeviceGetInfo...");
|
|
dwErr = g_pRasDeviceGetInfo(
|
|
NULL, hport, pszDeviceType, pszDeviceName, NULL, &dwSize );
|
|
TRACE2("RasDeviceGetInfo=%d,s=%d",dwErr,(INT)dwSize);
|
|
|
|
if (dwErr != ERROR_BUFFER_TOO_SMALL && dwErr != 0)
|
|
break;
|
|
|
|
/* So it will fall thru and be "not found".
|
|
*/
|
|
if (dwSize == 0)
|
|
dwSize = 1;
|
|
|
|
pDeviceInfo = (RASMAN_DEVICEINFO* )Malloc( dwSize );
|
|
if (!pDeviceInfo)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
TRACE("RasDeviceGetInfo...");
|
|
dwErr = g_pRasDeviceGetInfo(
|
|
NULL, hport, pszDeviceType, pszDeviceName, (PBYTE )pDeviceInfo, &dwSize );
|
|
TRACE2("RasDeviceGetInfo=%d,s=%d",dwErr,(INT)dwSize);
|
|
|
|
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
|
|
GetRasdevStats(
|
|
IN RASDEV* pdev,
|
|
OUT RASDEVSTATS* pstats )
|
|
|
|
/* Retrieves statistics for a device.
|
|
**
|
|
** (Abolade Gbadegesin Nov-9-1995)
|
|
*/
|
|
{
|
|
DWORD dwsize;
|
|
RASMAN_INFO info;
|
|
RAS_STATISTICS *prs;
|
|
BYTE buffer[sizeof(RAS_STATISTICS) + MAX_STATISTICS * 2 * sizeof(DWORD)];
|
|
DWORD dwErr, *pdw, dwGone, dwB, dwBC, dwBU;
|
|
|
|
if (pdev == NULL || pstats == NULL) { return ERROR_INVALID_PARAMETER; }
|
|
|
|
ZeroMemory(pstats, sizeof(RASDEVSTATS));
|
|
|
|
|
|
//
|
|
// retrieve the condition and connect time
|
|
//
|
|
|
|
ASSERT(g_pRasGetInfo);
|
|
dwErr = g_pRasGetInfo(NULL, (HPORT)pdev->RD_Handle, &info);
|
|
|
|
if (dwErr != NO_ERROR) {
|
|
pstats->RDS_Condition = DISCONNECTED;
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// need to handle ports which are not connected
|
|
// already a bug filed.
|
|
//
|
|
|
|
if (info.RI_PortStatus != OPEN) {
|
|
pstats->RDS_Condition = DISCONNECTED;
|
|
return NO_ERROR;
|
|
}
|
|
|
|
pstats->RDS_Condition = info.RI_ConnState;
|
|
if (info.RI_ConnState == CONNECTED) {
|
|
|
|
pstats->RDS_ConnectTime = info.RI_ConnectDuration;
|
|
pstats->RDS_Hrasconn = (HRASCONN)info.RI_ConnectionHandle;
|
|
}
|
|
|
|
|
|
//
|
|
// get dial-in/dial-out usage
|
|
//
|
|
|
|
if (info.RI_CurrentUsage & CALL_IN)
|
|
pstats->RDS_Flags |= RDFLAG_IsDialedIn;
|
|
if (info.RI_CurrentUsage & CALL_OUT)
|
|
pstats->RDS_Flags |= RDFLAG_IsDialedOut;
|
|
if (info.RI_CurrentUsage & CALL_ROUTER)
|
|
pstats->RDS_Flags |= RDFLAG_IsRouter;
|
|
|
|
|
|
//
|
|
// Retrieve the line speed
|
|
//
|
|
|
|
pstats->RDS_LineSpeed = info.RI_LinkSpeed;
|
|
|
|
|
|
//
|
|
// Retrieve the i/o statistics for both the link and the bundle
|
|
//
|
|
|
|
prs = (RAS_STATISTICS *)buffer;
|
|
dwsize = sizeof(RAS_STATISTICS) + MAX_STATISTICS * 2 * sizeof(DWORD);
|
|
ZeroMemory(buffer, dwsize);
|
|
|
|
ASSERT(g_pRasBundleGetStatistics);
|
|
dwErr = g_pRasBundleGetStatistics(
|
|
NULL, (HPORT)pdev->RD_Handle, (PBYTE)prs, &dwsize
|
|
);
|
|
|
|
if (dwErr != NO_ERROR) { return dwErr; }
|
|
|
|
|
|
//
|
|
// Save the statistics in the caller's RASDEVSTATS structure.
|
|
//
|
|
|
|
pdw = prs->S_Statistics;
|
|
|
|
pstats->RDS_InFrames = pdw[FRAMES_RCVED];
|
|
pstats->RDS_OutFrames = pdw[FRAMES_XMITED];
|
|
|
|
pstats->RDS_InBytesTotal =
|
|
pdw[BYTES_RCVED] +
|
|
pdw[BYTES_RCVED_UNCOMPRESSED] -
|
|
pdw[BYTES_RCVED_COMPRESSED];
|
|
pstats->RDS_OutBytesTotal =
|
|
pdw[BYTES_XMITED] +
|
|
pdw[BYTES_XMITED_UNCOMPRESSED] -
|
|
pdw[BYTES_XMITED_COMPRESSED];
|
|
|
|
pstats->RDS_InBytes =
|
|
pdw[MAX_STATISTICS + BYTES_RCVED] +
|
|
pdw[MAX_STATISTICS + BYTES_RCVED_UNCOMPRESSED] -
|
|
pdw[MAX_STATISTICS + BYTES_RCVED_COMPRESSED];
|
|
pstats->RDS_OutBytes =
|
|
pdw[MAX_STATISTICS + BYTES_XMITED] +
|
|
pdw[MAX_STATISTICS + BYTES_XMITED_UNCOMPRESSED] -
|
|
pdw[MAX_STATISTICS + BYTES_XMITED_COMPRESSED];
|
|
|
|
pstats->RDS_ErrCRC =
|
|
pdw[MAX_STATISTICS + CRC_ERR];
|
|
pstats->RDS_ErrTimeout =
|
|
pdw[MAX_STATISTICS + TIMEOUT_ERR];
|
|
pstats->RDS_ErrAlignment =
|
|
pdw[MAX_STATISTICS + ALIGNMENT_ERR];
|
|
pstats->RDS_ErrFraming =
|
|
pdw[MAX_STATISTICS + FRAMING_ERR];
|
|
pstats->RDS_ErrHwOverruns =
|
|
pdw[MAX_STATISTICS + HARDWARE_OVERRUN_ERR];
|
|
pstats->RDS_ErrBufOverruns =
|
|
pdw[MAX_STATISTICS + BUFFER_OVERRUN_ERR];
|
|
|
|
|
|
#if 0
|
|
TRACE4(
|
|
"RasBundleGetStatistics(rx=%d,tx=%d,rxb=%d,txb=%d)",
|
|
pstats->RDS_InBytes, pstats->RDS_OutBytes,
|
|
pstats->RDS_InBytesTotal, pstats->RDS_OutBytesTotal
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Compute compression ratios, using the bundle-stats
|
|
//
|
|
|
|
pstats->RDS_InCompRatio = 0;
|
|
dwGone = 0;
|
|
dwB = pdw[BYTES_RCVED];
|
|
dwBC = pdw[BYTES_RCVED_COMPRESSED];
|
|
dwBU = pdw[BYTES_RCVED_UNCOMPRESSED];
|
|
|
|
if (dwBC < dwBU) { dwGone = dwBU - dwBC; }
|
|
if (dwB + dwGone > 100) {
|
|
DWORD dwDen = (dwB + dwGone) / 100;
|
|
pstats->RDS_InCompRatio = (dwGone + (dwDen / 2)) / dwDen;
|
|
}
|
|
|
|
pstats->RDS_OutCompRatio = 0;
|
|
dwGone = 0;
|
|
dwB = pdw[BYTES_XMITED];
|
|
dwBC = pdw[BYTES_XMITED_COMPRESSED];
|
|
dwBU = pdw[BYTES_XMITED_UNCOMPRESSED];
|
|
|
|
if (dwBC < dwBU) { dwGone = dwBU - dwBC; }
|
|
if (dwB + dwGone > 100) {
|
|
DWORD dwDen = (dwB + dwGone) / 100;
|
|
pstats->RDS_OutCompRatio = (dwGone + (dwDen / 2)) / dwDen;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetRasdevTable(
|
|
OUT RASDEV** ppDevTable,
|
|
OUT DWORD* piDevCount )
|
|
|
|
/* Gets an array of RAS devices configured. Loads '*ppDevTable' with a
|
|
** heap block of '*ppDevTable' entries. On NT, this is essentially the
|
|
** output of GetRasPorts(), in a format which includes a devicename,
|
|
** flags, and a handle. Given a RASMAN_PORT structure, we append the
|
|
** device and port names to make a unique device string which is part of
|
|
** the output.
|
|
**
|
|
** Returns 0 if successful, or an error.
|
|
**
|
|
** (Abolade Gbadegesin Nov-9-1995)
|
|
*/
|
|
{
|
|
DWORD dwPortCount;
|
|
DWORD i, iLength, dwErr;
|
|
RASDEV *pDevTable, *pdev;
|
|
PTSTR pszDevice, pszPort;
|
|
TCHAR szDevice[RAS_MaxDeviceName + 1];
|
|
RASMAN_PORT *pPortTable, *pport;
|
|
|
|
//
|
|
// validate the arguments
|
|
//
|
|
|
|
if (ppDevTable == NULL || piDevCount == NULL) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
*piDevCount = 0;
|
|
*ppDevTable = NULL;
|
|
|
|
//
|
|
// get a table of ports from RASMAN; the string fields are ANSI
|
|
//
|
|
|
|
dwErr = GetRasPorts(NULL, &pPortTable, &dwPortCount);
|
|
if (dwErr != NO_ERROR) { return dwErr; }
|
|
|
|
if (dwPortCount == 0) { return NO_ERROR; }
|
|
|
|
//
|
|
// allocate space for as many device structs as there are ports
|
|
//
|
|
|
|
pDevTable = Malloc(dwPortCount * sizeof(RASDEV));
|
|
if (pDevTable == NULL) {
|
|
Free(pPortTable);
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
ZeroMemory(pDevTable, dwPortCount * sizeof(RASDEV));
|
|
|
|
//
|
|
// convert each RASMAN_PORT structure to a RASDEV structure.
|
|
//
|
|
|
|
for (i = 0, pport = pPortTable; i < dwPortCount; i++, pport++) {
|
|
|
|
pdev = pDevTable + i;
|
|
|
|
//
|
|
// copy over code-page-independent fields
|
|
//
|
|
|
|
pdev->RD_Handle = pport->P_Handle;
|
|
|
|
if (pport->P_ConfiguredUsage & CALL_IN)
|
|
pdev->RD_Flags |= RDFLAG_DialIn;
|
|
if (pport->P_ConfiguredUsage & CALL_OUT)
|
|
pdev->RD_Flags |= RDFLAG_DialOut;
|
|
if (pport->P_ConfiguredUsage & CALL_ROUTER)
|
|
pdev->RD_Flags |= RDFLAG_Router;
|
|
|
|
if (pport->P_CurrentUsage & CALL_IN)
|
|
pdev->RD_Flags |= RDFLAG_IsDialedIn;
|
|
if (pport->P_CurrentUsage & CALL_OUT)
|
|
pdev->RD_Flags |= RDFLAG_IsDialedOut;
|
|
if (pport->P_CurrentUsage & CALL_ROUTER)
|
|
pdev->RD_Flags |= RDFLAG_IsRouter;
|
|
|
|
|
|
//
|
|
// copy the device-type string
|
|
//
|
|
|
|
#ifdef UNICODE
|
|
StrCpyWFromAUsingAnsiEncoding(
|
|
pdev->RD_DeviceType,
|
|
pport->P_DeviceType,
|
|
RAS_MaxDeviceType);
|
|
#else
|
|
lstrcpy(pdev->RD_DeviceType, pport->P_DeviceType);
|
|
#endif
|
|
|
|
|
|
//
|
|
// copy the device-name and portname,
|
|
// storing them in temporary strings
|
|
//
|
|
|
|
#ifdef UNICODE
|
|
StrCpyWFromAUsingAnsiEncoding(
|
|
szDevice,
|
|
pport->P_DeviceName,
|
|
RAS_MaxDeviceName);
|
|
|
|
StrCpyWFromAUsingAnsiEncoding(
|
|
pdev->RD_PortName,
|
|
pport->P_PortName,
|
|
MAX_PORT_NAME);
|
|
|
|
pszDevice = szDevice;
|
|
pszPort = pdev->RD_PortName;
|
|
#else
|
|
pszDevice = pport->P_DeviceName;
|
|
lstrcpyn(pdev->RD_PortName, pport->P_PortName, MAX_PORT_NAME + 1);
|
|
pszPort = pdev->RD_PortName;
|
|
#endif
|
|
|
|
|
|
//
|
|
// get a display name from the device and port names
|
|
//
|
|
|
|
pdev->RD_DeviceName = PszFromDeviceAndPort(pszDevice, pszPort);
|
|
|
|
if (pdev->RD_DeviceName == NULL) {
|
|
Free(pPortTable);
|
|
FreeRasdevTable(pDevTable, dwPortCount);
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
|
|
Free(pPortTable);
|
|
|
|
*ppDevTable = pDevTable;
|
|
*piDevCount = dwPortCount;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
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 DWORD* pdwEntries )
|
|
|
|
/* 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( NULL, MXS_PAD_TXT, ppDevices, pdwEntries );
|
|
}
|
|
|
|
|
|
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 = NULL;
|
|
DWORD dwErr;
|
|
|
|
TRACE("GetRasPortMaxBps");
|
|
|
|
dwErr = GetRasPortString(
|
|
hport, SER_CONNECTBPS_KEY, &pszValue, XLATE_None );
|
|
if (dwErr == 0)
|
|
*pdwMaxConnectBps = (DWORD )atol( pszValue );
|
|
else
|
|
*pdwMaxConnectBps = 0;
|
|
|
|
Free0(pszValue);
|
|
|
|
pszValue = NULL;
|
|
|
|
dwErr = GetRasPortString(
|
|
hport, SER_CARRIERBPS_KEY, &pszValue, XLATE_None );
|
|
if (dwErr == 0)
|
|
*pdwMaxCarrierBps = (DWORD )atol( pszValue );
|
|
else
|
|
*pdwMaxCarrierBps = 0;
|
|
|
|
Free0(pszValue);
|
|
}
|
|
|
|
|
|
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;
|
|
DWORD dwSize = 0;
|
|
INT i;
|
|
|
|
TRACE("GetRasPortParam");
|
|
|
|
*ppPortInfo = NULL;
|
|
|
|
do
|
|
{
|
|
ASSERT(g_pRasPortGetInfo);
|
|
TRACE("RasPortGetInfo");
|
|
dwErr = g_pRasPortGetInfo(NULL, hport, NULL, &dwSize );
|
|
TRACE2("RasPortGetInfo=%d,s=%d",dwErr,(INT)dwSize);
|
|
|
|
if (dwErr != ERROR_BUFFER_TOO_SMALL && dwErr != 0)
|
|
break;
|
|
|
|
/* So it will fall thru and be "not found".
|
|
*/
|
|
if (dwSize == 0)
|
|
dwSize = 1;
|
|
|
|
*ppPortInfo = (RASMAN_PORTINFO* )Malloc( dwSize );
|
|
if (!*ppPortInfo)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
TRACE("RasPortGetInfo");
|
|
dwErr = g_pRasPortGetInfo(NULL, hport, (PBYTE )*ppPortInfo, &dwSize );
|
|
TRACE2("RasPortGetInfo=%d,s=%d",dwErr,(INT)dwSize);
|
|
|
|
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(
|
|
IN HANDLE hConnection,
|
|
OUT RASMAN_PORT** ppPorts,
|
|
OUT DWORD* pdwEntries )
|
|
|
|
/* 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.
|
|
*/
|
|
{
|
|
DWORD dwSize = 0;
|
|
DWORD dwErr;
|
|
|
|
TRACE("GetRasPorts");
|
|
|
|
#if DUMMYPORTS
|
|
|
|
{
|
|
RASMAN_PORT* pPort;
|
|
DWORD c;
|
|
|
|
TRACE("TEST: Fake ISDN ports");
|
|
|
|
*pdwEntries = c = g_cPorts;
|
|
dwSize = *pdwEntries * sizeof(RASMAN_PORT);
|
|
|
|
*ppPorts = (RASMAN_PORT* )Malloc( dwSize );
|
|
if (!*ppPorts)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
do
|
|
{
|
|
pPort = *ppPorts;
|
|
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" );
|
|
if (--c == 0)
|
|
break;
|
|
|
|
++pPort;
|
|
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" );
|
|
if (--c == 0)
|
|
break;
|
|
|
|
++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" );
|
|
if (--c == 0)
|
|
break;
|
|
|
|
++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" );
|
|
if (--c == 0)
|
|
break;
|
|
|
|
++pPort;
|
|
ZeroMemory( pPort, sizeof(*pPort) );
|
|
lstrcpyA( pPort->P_PortName, "X251" );
|
|
pPort->P_Status = CLOSED;
|
|
pPort->P_ConfiguredUsage = CALL_OUT;
|
|
pPort->P_CurrentUsage = CALL_OUT;
|
|
lstrcpyA( pPort->P_MediaName, "rastapi" );
|
|
lstrcpyA( pPort->P_DeviceName, "Digiboard X.25 adapter" );
|
|
lstrcpyA( pPort->P_DeviceType, "X25" );
|
|
if (--c == 0)
|
|
break;
|
|
|
|
++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" );
|
|
if (--c == 0)
|
|
break;
|
|
}
|
|
while (FALSE);
|
|
}
|
|
|
|
#else
|
|
|
|
ASSERT(g_pRasPortEnum);
|
|
TRACE("RasPortEnum...");
|
|
dwErr = g_pRasPortEnum(hConnection, NULL, &dwSize, pdwEntries );
|
|
TRACE2("RasPortEnum=%d,c=%d",dwErr,(INT)*pdwEntries);
|
|
|
|
if (dwErr == 0)
|
|
{
|
|
/* No ports to enumerate. Set up to allocate a single byte anyway, so
|
|
** things work without lots of special code.
|
|
*/
|
|
dwSize = 1;
|
|
}
|
|
else if (dwErr != ERROR_BUFFER_TOO_SMALL)
|
|
return dwErr;
|
|
|
|
*ppPorts = (RASMAN_PORT* )Malloc( dwSize );
|
|
if (!*ppPorts)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
TRACE("RasPortEnum...");
|
|
dwErr = g_pRasPortEnum(hConnection, (PBYTE )*ppPorts, &dwSize, pdwEntries );
|
|
TRACE2("RasPortEnum=%d,c=%d",dwErr,(INT)*pdwEntries);
|
|
|
|
if (dwErr != 0)
|
|
{
|
|
Free( *ppPorts );
|
|
*ppPorts = NULL;
|
|
return dwErr;
|
|
}
|
|
|
|
#endif
|
|
|
|
#if 1 // Verbose trace
|
|
{
|
|
RASMAN_PORT* pPort;
|
|
DWORD i;
|
|
|
|
for (pPort = *ppPorts, i = 0; i < *pdwEntries; ++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(
|
|
IN HANDLE hConnection,
|
|
OUT RASMAN_DEVICE** ppDevices,
|
|
OUT DWORD* pdwEntries )
|
|
|
|
/* 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( hConnection, MXS_SWITCH_TXT, ppDevices, pdwEntries );
|
|
}
|
|
|
|
DWORD
|
|
GetRasUnimodemBlob(
|
|
IN HANDLE hConnection,
|
|
IN HPORT hport,
|
|
IN CHAR* pszDeviceType,
|
|
OUT BYTE** ppBlob,
|
|
OUT DWORD* pcbBlob )
|
|
{
|
|
return GetRasUnimodemBlobEx(
|
|
hConnection,
|
|
hport,
|
|
pszDeviceType,
|
|
FALSE,
|
|
ppBlob,
|
|
pcbBlob);
|
|
}
|
|
|
|
DWORD
|
|
GetRasUnimodemBlobEx(
|
|
IN HANDLE hConnection,
|
|
IN HPORT hport,
|
|
IN CHAR* pszDeviceType,
|
|
IN BOOL fGlobal,
|
|
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;
|
|
PRASGETDEVCONFIG pFunc;
|
|
CHAR* pszFuncName;
|
|
cbBlob = 0;
|
|
|
|
pFunc = (fGlobal) ? g_pRasGetDevConfigEx : g_pRasGetDevConfig;
|
|
pszFuncName = (fGlobal) ? "RasGetDevConfigEx" : "RasGetDevConfig";
|
|
|
|
ASSERT(pFunc);
|
|
TRACE(pszFuncName);
|
|
dwErr = pFunc(hConnection, hport, pszDeviceType, NULL, &cbBlob );
|
|
TRACE2("%s=%d", pszFuncName, 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(pszFuncName);
|
|
dwErr = pFunc(hConnection, hport, pszDeviceType, pBlob, &cbBlob );
|
|
TRACE2("%s=%d", pszFuncName, dwErr);
|
|
|
|
if (dwErr != 0)
|
|
{
|
|
Free( pBlob );
|
|
return dwErr;
|
|
}
|
|
|
|
SanitizeUnimodemBlob( pBlob );
|
|
}
|
|
else
|
|
pBlob = NULL;
|
|
|
|
*ppBlob = pBlob;
|
|
*pcbBlob = cbBlob;
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
VOID
|
|
GetRasUnimodemInfo(
|
|
IN HANDLE hConnection,
|
|
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 = NULL;
|
|
DWORD cbBlob = 0;
|
|
|
|
SetDefaultUnimodemInfo( pInfo );
|
|
|
|
dwErr = GetRasUnimodemBlob(
|
|
hConnection,
|
|
hport,
|
|
pszDeviceType,
|
|
&pBlob,
|
|
&cbBlob );
|
|
|
|
if (dwErr == 0 && cbBlob > 0)
|
|
UnimodemInfoFromBlob( pBlob, pInfo );
|
|
|
|
Free0( pBlob );
|
|
}
|
|
|
|
|
|
TCHAR*
|
|
GetRasX25Diagnostic(
|
|
IN HRASCONN hrasconn )
|
|
|
|
/* Returns the X.25 diagnostics string or NULL if none. It is caller's
|
|
** responsibility to Free the returned string.
|
|
*/
|
|
{
|
|
DWORD dwErr;
|
|
HPORT hport;
|
|
RASMAN_INFO info;
|
|
CHAR* pszDiagnosticA = NULL;
|
|
TCHAR* pszDiagnostic = NULL;
|
|
|
|
pszDiagnosticA = NULL;
|
|
hport = g_pRasGetHport( hrasconn );
|
|
|
|
ASSERT(g_pRasGetInfo);
|
|
TRACE1("RasGetInfo(%d)",hport);
|
|
dwErr = g_pRasGetInfo( NULL, hport, &info );
|
|
TRACE1("RasGetInfo=%d",dwErr);
|
|
|
|
/* Error codes are ignored here since the diagnosistic
|
|
** is informational only. If they fail the diagnostic
|
|
** will simply appear blank.
|
|
*/
|
|
if (dwErr == 0)
|
|
{
|
|
GetRasDeviceString(
|
|
hport, info.RI_DeviceTypeConnecting,
|
|
info.RI_DeviceConnecting, MXS_DIAGNOSTICS_KEY,
|
|
&pszDiagnosticA, XLATE_Diagnostic );
|
|
}
|
|
|
|
if(NULL != pszDiagnosticA)
|
|
{
|
|
pszDiagnostic = StrDupTFromA( pszDiagnosticA );
|
|
Free( pszDiagnosticA );
|
|
}
|
|
return pszDiagnostic;
|
|
}
|
|
|
|
|
|
BOOL
|
|
IsRasdevBundled(
|
|
IN RASDEV* pdev,
|
|
IN RASDEV* pDevTable,
|
|
IN DWORD iDevCount
|
|
)
|
|
|
|
/* Determines whether the device described by 'pdev' is bundled,
|
|
** by looking for another device in 'pDevTable' which has the same bundle
|
|
** as 'pdev'.
|
|
**
|
|
** Returnes TRUE if the device is bundled, FALSE otherwise.
|
|
*/
|
|
{
|
|
|
|
DWORD i;
|
|
RASDEV* pdev2;
|
|
DWORD dwBundle;
|
|
|
|
//
|
|
// First get the device's bundle;
|
|
// If this fails, assume it is not connected and return FALSE.
|
|
//
|
|
|
|
if (GetRasdevBundle(pdev, &dwBundle) != NO_ERROR) { return FALSE; }
|
|
|
|
|
|
//
|
|
// Walk through the other devices in the table, looking for one
|
|
// with the same bundle.
|
|
//
|
|
|
|
for (i = 0, pdev2 = pDevTable;
|
|
i < iDevCount; i++, pdev2++) {
|
|
|
|
DWORD dwBundle2;
|
|
|
|
//
|
|
// skip this if it is the device we already know about
|
|
//
|
|
|
|
if (pdev->RD_Handle == pdev2->RD_Handle) { continue; }
|
|
|
|
|
|
//
|
|
// get the bundle
|
|
//
|
|
|
|
if (GetRasdevBundle(pdev2, &dwBundle2) != NO_ERROR) { continue; }
|
|
|
|
|
|
//
|
|
// if the bundle is the same, we know its multilinked
|
|
//
|
|
|
|
if (dwBundle == dwBundle2) { return TRUE; }
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
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 = NULL;
|
|
CHAR* pszBuf = NULL;
|
|
CHAR* pszOut = NULL;
|
|
CHAR* pszTemp = NULL;
|
|
|
|
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';
|
|
|
|
// For whistler 517011
|
|
//
|
|
pszTemp = Realloc( pszBuf, lstrlenA( pszBuf ) + 1 );
|
|
|
|
if(pszTemp)
|
|
{
|
|
pszBuf = pszTemp;
|
|
}
|
|
else
|
|
{
|
|
Free(pszBuf);
|
|
pszBuf = NULL;
|
|
}
|
|
|
|
return pszBuf;
|
|
}
|
|
|
|
|
|
VOID
|
|
SanitizeUnimodemBlob(
|
|
IN OUT BYTE* pBlob )
|
|
|
|
/* Fix non-RAS-compatible settings in unimodem blob 'pBlob'.
|
|
**
|
|
** (Based on Gurdeepian routine)
|
|
*/
|
|
{
|
|
DEVCFG* pDevCfg;
|
|
MODEMSETTINGS* pModemSettings;
|
|
|
|
RAS_DEVCONFIG* pRasDevCfg;
|
|
|
|
pRasDevCfg = (RAS_DEVCONFIG*)pBlob;
|
|
|
|
pDevCfg = (DEVCFG *)
|
|
((PBYTE) pRasDevCfg + pRasDevCfg->dwOffsetofModemSettings);
|
|
|
|
pModemSettings = (MODEMSETTINGS* )(((BYTE* )&pDevCfg->commconfig)
|
|
+ pDevCfg->commconfig.dwProviderOffset);
|
|
|
|
TRACE1(
|
|
"SanitizeUnimodemBlob: mdm prot=%d",
|
|
MDM_GET_EXTENDEDINFO(pModemSettings->dwPreferredModemOptions));
|
|
|
|
/* 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
|
|
UnimodemProtInfoFromExtendedCaps(
|
|
OUT UNIMODEMINFO* pInfo,
|
|
IN BYTE* pExtCapsBlob)
|
|
|
|
/* Loads the modem protocol info for 'pInfo' from the extended caps
|
|
** blob retrieved from tapi.
|
|
**
|
|
*/
|
|
{
|
|
MODEM_PROTOCOL_CAPS* lpProtCaps = NULL;
|
|
PROTOCOL_ITEM* pProtItem = NULL;
|
|
DWORD dwIndex;
|
|
|
|
do
|
|
{
|
|
// Extract the modem caps
|
|
//
|
|
lpProtCaps = (MODEM_PROTOCOL_CAPS *)pExtCapsBlob;
|
|
|
|
if (lpProtCaps->hdr.dwSig != dwSIG_MODEM_PROTOCOL_CAPS ||
|
|
lpProtCaps->dwNumProtocols == 0 ||
|
|
lpProtCaps->dwProtocolListOffset == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// If no protocols are supported, don't bother creating the
|
|
// list
|
|
if (lpProtCaps->dwNumProtocols == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Create the list
|
|
//
|
|
pInfo->pListProtocols = DtlCreateList(0);
|
|
if (pInfo->pListProtocols == NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Get the list of supported protocols
|
|
//
|
|
pProtItem = (PROTOCOL_ITEM*)
|
|
(((LPBYTE)lpProtCaps) + lpProtCaps->dwProtocolListOffset);
|
|
|
|
// Enumerate the protocols
|
|
//
|
|
for (dwIndex = 0;
|
|
dwIndex < lpProtCaps->dwNumProtocols;
|
|
dwIndex++, pProtItem++)
|
|
{
|
|
DTLNODE * pNode = NULL;
|
|
PWCHAR pszName = NULL;
|
|
DWORD dwSize;
|
|
|
|
// Get the friendly name from the structure
|
|
//
|
|
pszName = (PWCHAR)
|
|
(pExtCapsBlob + pProtItem->dwProtocolNameOffset);
|
|
if (pszName == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Calculate the size of the friendly name
|
|
//
|
|
dwSize = (wcslen(pszName) + 1) * sizeof(WCHAR);
|
|
|
|
// Allocate a node accordingly
|
|
//
|
|
pNode =
|
|
DtlCreateSizedNode(dwSize, (LONG_PTR)pProtItem->dwProtocol);
|
|
if (pNode == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Initialize the node and add it to the list
|
|
//
|
|
wcscpy((PWCHAR) DtlGetData(pNode), pszName);
|
|
DtlAddNodeLast(pInfo->pListProtocols, pNode);
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
// Cleanup
|
|
{
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
RAS_DEVCONFIG* pRasDevCfg;
|
|
|
|
pRasDevCfg = (RAS_DEVCONFIG*)pBlob;
|
|
|
|
pDevCfg = (DEVCFG *)
|
|
((PBYTE) pRasDevCfg + pRasDevCfg->dwOffsetofModemSettings);
|
|
|
|
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;
|
|
|
|
// Get the modem protocol
|
|
//
|
|
pInfo->dwModemProtocol =
|
|
MDM_GET_EXTENDEDINFO(pModemSettings->dwPreferredModemOptions);
|
|
|
|
// Pull out the extended caps stuff
|
|
//
|
|
if ( pRasDevCfg->dwSizeofExtendedCaps )
|
|
{
|
|
UnimodemProtInfoFromExtendedCaps(
|
|
pInfo,
|
|
(BYTE*)(pBlob + pRasDevCfg->dwOffsetofExtendedCaps));
|
|
}
|
|
else
|
|
{
|
|
pInfo->pListProtocols = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
RAS_DEVCONFIG* pRasDevCfg;
|
|
|
|
pRasDevCfg = (RAS_DEVCONFIG*) pBlob;
|
|
|
|
// Pull out the device config stuff
|
|
//
|
|
pDevCfg = (DEVCFG *)
|
|
((PBYTE) pRasDevCfg + pRasDevCfg->dwOffsetofModemSettings);
|
|
|
|
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;
|
|
|
|
// Set the modem protocol
|
|
//
|
|
MDM_SET_EXTENDEDINFO(
|
|
pModemSettings->dwPreferredModemOptions,
|
|
pInfo->dwModemProtocol);
|
|
|
|
}
|
|
|
|
WCHAR *GetUnicodeName(HPORT hport)
|
|
{
|
|
WCHAR *pwsz = Malloc(sizeof(WCHAR) * (MAX_DEVICE_NAME + 1));
|
|
|
|
if(NULL != pwsz)
|
|
{
|
|
if(ERROR_SUCCESS != RasGetUnicodeDeviceName(
|
|
hport,
|
|
pwsz))
|
|
{
|
|
Free(pwsz);
|
|
pwsz = NULL;
|
|
}
|
|
}
|
|
|
|
return pwsz;
|
|
}
|
|
|