windows-nt/Source/XPSP1/NT/net/rras/ras/rasman/mxs32/rasmxs.c
2020-09-26 16:20:57 +08:00

590 lines
13 KiB
C

//****************************************************************************
//
// Microsoft NT Remote Access Service
//
// Copyright (C) 1992-93 Microsft Corporation. All rights reserved.
//
// Filename: rasmxs.c
//
// Revision History
//
// Jun 5, 1992 J. Perry Hannah Created
//
//
// Description: This file contains all entry points for the RASMXS.DLL
// which is the device dll for modems, pads, and switches.
//
//****************************************************************************
#include <nt.h> //These first five headers are used by media.h
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <wanpub.h>
#include <asyncpub.h>
#include <malloc.h>
#include <rasman.h>
#include <raserror.h>
#include <serial.h>
#include <rasfile.h>
#include <media.h>
#include <mprlog.h>
#include <rtutils.h>
#include <rasmxs.h>
#include <mxsint.h>
#include <mxspriv.h>
#include "mxswrap.h" //Inf file wrapper
//* Global Variables *******************************************************
//
RESPSECTION ResponseSection ; //Shared response section
DEVICE_CB *pDeviceList; //Points to DCB linked list
HANDLE *pDeviceListMutex; //Mutex for above list
PortSetInfo_t PortSetInfo = NULL; //API typedef defined in media.h
PortGetInfo_t PortGetInfo = NULL; //API typedef defined in media.h
BOOL gbLogDeviceDialog = FALSE; //Indicates logging on if TRUE
HANDLE ghLogFile; //Handle of device log file
SavedSections *gpSavedSections = NULL; // Pointer to cached sections
#ifdef DBGCON
BOOL gbConsole = TRUE; //Indicates console logging on
#endif
//* RasmxsDllEntryPoint ****************************************************
//
//* RasmxsDllEntryPoint()
//
// Function: Used for detecting processes attaching and detaching to the DLL.
//
//*
BOOL APIENTRY
RasmxsDllEntryPoint(HANDLE hDll, DWORD dwReason, LPVOID pReserved)
{
DebugPrintf(("RasmxsDllEntryPoint\n"));
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
// Init global variables
pDeviceList = NULL;
if ((pDeviceListMutex = CreateMutex (NULL,FALSE,NULL)) == NULL)
{
return FALSE ;
}
if ((ResponseSection.Mutex = CreateMutex (NULL,FALSE,NULL)) == NULL)
{
CloseHandle(pDeviceListMutex);
pDeviceListMutex = NULL;
return FALSE ;
}
// Open device log file
if (gbLogDeviceDialog = IsLoggingOn())
InitLog();
// Open degugging console window
#ifdef DBGCON
if (gbConsole)
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
COORD coord;
AllocConsole( );
GetConsoleScreenBufferInfo( GetStdHandle(STD_OUTPUT_HANDLE), &csbi );
coord.X = (SHORT)(csbi.srWindow.Right - csbi.srWindow.Left + 1);
coord.Y = (SHORT)((csbi.srWindow.Bottom - csbi.srWindow.Top + 1) * 20);
SetConsoleScreenBufferSize( GetStdHandle(STD_OUTPUT_HANDLE), coord );
gbConsole = FALSE;
}
#endif
break;
case DLL_PROCESS_DETACH:
{
if(NULL != pDeviceListMutex)
{
CloseHandle(pDeviceListMutex);
pDeviceListMutex = NULL;
}
if(NULL != ResponseSection.Mutex)
{
CloseHandle(ResponseSection.Mutex);
ResponseSection.Mutex = NULL;
}
break;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return(TRUE);
UNREFERENCED_PARAMETER(hDll);
UNREFERENCED_PARAMETER(pReserved);
}
//* RAS Modem/X.25/Switch APIS *********************************************
//
//* DeviceEnum() -----------------------------------------------------------
//
// Function: Enumerates all devices in the device INF file for the
// specified DevictType.
//
// Returns: Return codes from RasDevEnumDevices
//
//*
DWORD APIENTRY
DeviceEnum (char *pszDeviceType,
DWORD *pcEntries,
BYTE *pBuffer,
DWORD *pdwSize)
{
TCHAR szFileName[MAX_PATH];
ConsolePrintf(("DeviceEnum DeviceType: %s\n", pszDeviceType));
*szFileName = TEXT('\0');
GetInfFileName(pszDeviceType, szFileName, sizeof(szFileName));
return(RasDevEnumDevices(szFileName, pcEntries, pBuffer, pdwSize));
}
//* DeviceGetInfo() --------------------------------------------------------
//
// Function: Returns a summary of current information from the InfoTable
// for the device on the port in Pcb.
//
// Returns: Return codes from GetDeviceCB, BuildOutputTable
//*
DWORD APIENTRY
DeviceGetInfo(HANDLE hIOPort,
char *pszDeviceType,
char *pszDeviceName,
BYTE *pInfo,
DWORD *pdwSize)
{
DWORD dRC;
DEVICE_CB *pDevice;
ConsolePrintf(("DeviceGetInfo hIOPort: 0x%08lx\n", hIOPort));
// **** Exclusion Begin ****
WaitForSingleObject(pDeviceListMutex, INFINITE) ;
// Get Device Control Block for this hIOPort
dRC = GetDeviceCB(hIOPort, pszDeviceType, pszDeviceName, &pDevice);
if (dRC != SUCCESS) {
// *** Exclusion End ***
ReleaseMutex(pDeviceListMutex);
return(dRC);
}
// Write summary of InfoTable in DCB to caller's buffer
dRC = BuildOutputTable(pDevice, pInfo, pdwSize) ;
// *** Exclusion End ***
ReleaseMutex(pDeviceListMutex);
return dRC ;
}
//* DeviceSetInfo() --------------------------------------------------------
//
// Function: Sets attributes in the InfoTable for the device on the
// port in Pcb.
//
// Returns: Return codes from GetDeviceCB, UpdateInfoTable
//*
DWORD APIENTRY
DeviceSetInfo(HANDLE hIOPort,
char *pszDeviceType,
char *pszDeviceName,
RASMAN_DEVICEINFO *pInfo)
{
DWORD dwRC;
DEVICE_CB *pDevice;
DWORD dwMemSize = 0;
char szDefaultOff[RAS_MAXLINEBUFLEN];
RASMAN_PORTINFO *pPortInfo = NULL;
ConsolePrintf(("DeviceSetInfo hIOPort: 0x%08lx\n", hIOPort));
// **** Exclusion Begin ****
WaitForSingleObject(pDeviceListMutex, INFINITE) ;
// Get Device Control Block for this hIOPort
dwRC = GetDeviceCB(hIOPort, pszDeviceType, pszDeviceName, &pDevice);
if (dwRC != SUCCESS) {
// *** Exclusion End ***
ReleaseMutex(pDeviceListMutex);
return(dwRC);
}
// Write input data to InfoTable
dwRC = UpdateInfoTable(pDevice, pInfo);
if (dwRC != SUCCESS) {
// *** Exclusion End ***
ReleaseMutex(pDeviceListMutex);
return(dwRC);
}
// Get port info data
dwRC = PortGetInfo(hIOPort, NULL, (BYTE *)NULL, &dwMemSize);
if (dwRC == ERROR_BUFFER_TOO_SMALL)
{
GetMem(dwMemSize, (BYTE **)&pPortInfo);
if (pPortInfo == NULL) {
// *** Exclusion End ***
ReleaseMutex(pDeviceListMutex);
return(ERROR_ALLOCATING_MEMORY);
}
dwRC = PortGetInfo(hIOPort, NULL, (BYTE *)pPortInfo, &dwMemSize);
}
/*
else
{
if(ERROR_SUCCESS == dwRC)
{
dwRC = ERROR_PORT_NOT_FOUND;
}
return dwRC;
}
*/
// Save current values of DefaultOff macros as new defaults if this
// device is immediately attached to its port.
if (dwRC == SUCCESS && DeviceAttachedToPort(pPortInfo, pszDeviceType, pszDeviceName))
{
CreateDefaultOffString(pDevice, szDefaultOff);
dwRC = PortSetStringInfo(hIOPort,
SER_DEFAULTOFF_KEY,
szDefaultOff,
strlen(szDefaultOff));
} else
dwRC = SUCCESS ;
free(pPortInfo);
// *** Exclusion End ***
ReleaseMutex(pDeviceListMutex);
return(dwRC);
}
//* DeviceConnect() --------------------------------------------------------
//
// Function: Initiates the process of connecting a device.
//
// Returns: Return codes from ConnectListen
//*
DWORD APIENTRY
DeviceConnect(HANDLE hIOPort,
char *pszDeviceType,
char *pszDeviceName)
{
DWORD dRC;
ConsolePrintf(("DeviceConnect hIOPort: 0x%08lx\n", hIOPort));
// **** Exclusion Begin ****
WaitForSingleObject(pDeviceListMutex, INFINITE) ;
dRC = ConnectListen(hIOPort,
pszDeviceType,
pszDeviceName,
CT_DIAL);
// *** Exclusion End ***
ReleaseMutex(pDeviceListMutex);
return dRC ;
}
//* DeviceListen() ---------------------------------------------------------
//
// Function: Initiates the process of listening for a remote device
// to connect to a local device.
//
// Returns: Return codes from ConnectListen
//*
DWORD APIENTRY
DeviceListen(HANDLE hIOPort,
char *pszDeviceType,
char *pszDeviceName)
{
DWORD dwRC;
ConsolePrintf(("DeviceListen hIOPort: 0x%08lx\n", hIOPort));
// **** Exclusion Begin ****
WaitForSingleObject(pDeviceListMutex, INFINITE) ;
dwRC = ConnectListen(hIOPort,
pszDeviceType,
pszDeviceName,
CT_LISTEN);
ConsolePrintf(("DeviceListen returns: %d\n", dwRC));
// *** Exclusion End ***
ReleaseMutex(pDeviceListMutex);
return(dwRC);
}
//* DeviceDone() -----------------------------------------------------------
//
// Function: Informs the device dll that the attempt to connect or listen
// has completed.
//
// Returns: nothing
//*
VOID APIENTRY
DeviceDone(HANDLE hIOPort)
{
DEVICE_CB *pDevice, *pRemainder, *pPrevDev;
WORD i;
// **** Exclusion Begin ****
WaitForSingleObject(pDeviceListMutex, INFINITE) ;
ConsolePrintf(("DeviceDone\n"));
for (pRemainder = pDeviceList; 1; )
{
// Find device control block for this port
pDevice = FindPortInList(pRemainder, hIOPort, &pPrevDev);
if (pDevice == NULL)
break; //Loop Exit
pRemainder = pDevice->pNextDeviceCB;
// Now clean up the found DCB
// Close INF file section(s)
if (pDevice->hInfFile != INVALID_HRASFILE)
CloseOpenDevSection (pDevice->hInfFile) ;
// See notes on OpenResponseSecion, mxsutils.c
//if (pDevice->eDeviceType == DT_MODEM)
// CloseResponseSection() ;
// Drop device control block from linked list
if (pDevice == pDeviceList) //DCB to drop is 1st on list
pDeviceList = pRemainder;
else
pPrevDev->pNextDeviceCB = pRemainder;
// Free all value strings in InfoTable, then free InfoTable
if (pDevice->pInfoTable != NULL)
{
for (i=0; i < pDevice->pInfoTable->DI_NumOfParams; i++)
if (pDevice->pInfoTable->DI_Params[i].P_Type == String &&
pDevice->pInfoTable->DI_Params[i].P_Value.String.Data != NULL)
free(pDevice->pInfoTable->DI_Params[i].P_Value.String.Data);
free(pDevice->pInfoTable);
}
// Free Macro Table and DCB
if (pDevice->pMacros != NULL)
free(pDevice->pMacros);
free(pDevice);
}
// *** Exclusion End ***
ReleaseMutex(pDeviceListMutex);
}
//* DeviceWork() -----------------------------------------------------------
//
// Function: This function is called following DeviceConnect or
// DeviceListen to further the asynchronous process of
// connecting or listening.
//
// Returns: ERROR_DCB_NOT_FOUND
// ERROR_STATE_MACHINES_NOT_STARTED
// Return codes from DeviceStateMachine
//*
DWORD APIENTRY
DeviceWork(HANDLE hIOPort)
{
DEVICE_CB *pDevice;
DWORD dwRC;
ConsolePrintf(("DeviceWork hIOPort: 0x%08lx hNotifier: 0x%08x\n",
hIOPort, hNotifier));
// Find device control block for this port
// **** Exclusion Begin ****
WaitForSingleObject(pDeviceListMutex, INFINITE) ;
pDevice = FindPortInList(pDeviceList, hIOPort, NULL);
if (pDevice == NULL) {
// *** Exclusion End ***
ReleaseMutex(pDeviceListMutex);
return(ERROR_DCB_NOT_FOUND);
}
// Check that DeviceStateMachine is started (not reset)
if (pDevice->eDevNextAction == SEND) {
// *** Exclusion End ***
ReleaseMutex(pDeviceListMutex);
return(ERROR_STATE_MACHINES_NOT_STARTED);
}
// Advance state machine
while(1)
{
dwRC = DeviceStateMachine(pDevice, hIOPort);
ConsolePrintf(("DeviceWork returns: %d\n", dwRC));
if (dwRC == ERROR_PORT_OR_DEVICE &&
pDevice->eDeviceType == DT_MODEM &&
pDevice->dwRetries++ < MODEM_RETRIES )
{
// Initialize command types
switch(RasDevIdFirstCommand(pDevice->hInfFile))
{
case CT_INIT:
pDevice->eCmdType = CT_INIT; //Reset eCmdType
break;
case CT_DIAL:
case CT_LISTEN:
case CT_GENERIC:
break; //Use old value for eCmdType
default:
// *** Exclusion End ***
ReleaseMutex(pDeviceListMutex);
return(ERROR_NO_COMMAND_FOUND);
}
// Reset state variables to initial values
pDevice->eDevNextAction = SEND;
pDevice->eRcvState = GETECHO;
// Cancel any pending com port action and purge com buffers
PurgeComm(hIOPort,
PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
}
else
break;
}
// *** Exclusion End ***
ReleaseMutex(pDeviceListMutex);
return(dwRC);
}