//**************************************************************************** // // 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 //These first five headers are used by media.h #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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); }