Leaked source code of windows server 2003
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.

589 lines
14 KiB

  1. //****************************************************************************
  2. //
  3. // Microsoft NT Remote Access Service
  4. //
  5. // Copyright (C) 1992-93 Microsft Corporation. All rights reserved.
  6. //
  7. // Filename: rasmxs.c
  8. //
  9. // Revision History
  10. //
  11. // Jun 5, 1992 J. Perry Hannah Created
  12. //
  13. //
  14. // Description: This file contains all entry points for the RASMXS.DLL
  15. // which is the device dll for modems, pads, and switches.
  16. //
  17. //****************************************************************************
  18. #include <nt.h> //These first five headers are used by media.h
  19. #include <ntrtl.h>
  20. #include <nturtl.h>
  21. #include <windows.h>
  22. #include <wanpub.h>
  23. #include <asyncpub.h>
  24. #include <malloc.h>
  25. #include <rasman.h>
  26. #include <raserror.h>
  27. #include <serial.h>
  28. #include <rasfile.h>
  29. #include <media.h>
  30. #include <mprlog.h>
  31. #include <rtutils.h>
  32. #include <rasmxs.h>
  33. #include <mxsint.h>
  34. #include <mxspriv.h>
  35. #include "mxswrap.h" //Inf file wrapper
  36. //* Global Variables *******************************************************
  37. //
  38. RESPSECTION ResponseSection ; //Shared response section
  39. DEVICE_CB *pDeviceList; //Points to DCB linked list
  40. HANDLE *pDeviceListMutex; //Mutex for above list
  41. PortSetInfo_t PortSetInfo = NULL; //API typedef defined in media.h
  42. PortGetInfo_t PortGetInfo = NULL; //API typedef defined in media.h
  43. BOOL gbLogDeviceDialog = FALSE; //Indicates logging on if TRUE
  44. HANDLE ghLogFile; //Handle of device log file
  45. SavedSections *gpSavedSections = NULL; // Pointer to cached sections
  46. #ifdef DBGCON
  47. BOOL gbConsole = TRUE; //Indicates console logging on
  48. #endif
  49. //* RasmxsDllEntryPoint ****************************************************
  50. //
  51. //* RasmxsDllEntryPoint()
  52. //
  53. // Function: Used for detecting processes attaching and detaching to the DLL.
  54. //
  55. //*
  56. BOOL APIENTRY
  57. RasmxsDllEntryPoint(HANDLE hDll, DWORD dwReason, LPVOID pReserved)
  58. {
  59. DebugPrintf(("RasmxsDllEntryPoint\n"));
  60. switch (dwReason)
  61. {
  62. case DLL_PROCESS_ATTACH:
  63. // Init global variables
  64. pDeviceList = NULL;
  65. if ((pDeviceListMutex = CreateMutex (NULL,FALSE,NULL)) == NULL)
  66. {
  67. return FALSE ;
  68. }
  69. if ((ResponseSection.Mutex = CreateMutex (NULL,FALSE,NULL)) == NULL)
  70. {
  71. CloseHandle(pDeviceListMutex);
  72. pDeviceListMutex = NULL;
  73. return FALSE ;
  74. }
  75. // Open device log file
  76. if (gbLogDeviceDialog = IsLoggingOn())
  77. InitLog();
  78. // Open degugging console window
  79. #ifdef DBGCON
  80. if (gbConsole)
  81. {
  82. CONSOLE_SCREEN_BUFFER_INFO csbi;
  83. COORD coord;
  84. AllocConsole( );
  85. GetConsoleScreenBufferInfo( GetStdHandle(STD_OUTPUT_HANDLE), &csbi );
  86. coord.X = (SHORT)(csbi.srWindow.Right - csbi.srWindow.Left + 1);
  87. coord.Y = (SHORT)((csbi.srWindow.Bottom - csbi.srWindow.Top + 1) * 20);
  88. SetConsoleScreenBufferSize( GetStdHandle(STD_OUTPUT_HANDLE), coord );
  89. gbConsole = FALSE;
  90. }
  91. #endif
  92. break;
  93. case DLL_PROCESS_DETACH:
  94. {
  95. if(NULL != pDeviceListMutex)
  96. {
  97. CloseHandle(pDeviceListMutex);
  98. pDeviceListMutex = NULL;
  99. }
  100. if(NULL != ResponseSection.Mutex)
  101. {
  102. CloseHandle(ResponseSection.Mutex);
  103. ResponseSection.Mutex = NULL;
  104. }
  105. break;
  106. }
  107. case DLL_THREAD_ATTACH:
  108. case DLL_THREAD_DETACH:
  109. break;
  110. }
  111. return(TRUE);
  112. UNREFERENCED_PARAMETER(hDll);
  113. UNREFERENCED_PARAMETER(pReserved);
  114. }
  115. //* RAS Modem/X.25/Switch APIS *********************************************
  116. //
  117. //* DeviceEnum() -----------------------------------------------------------
  118. //
  119. // Function: Enumerates all devices in the device INF file for the
  120. // specified DevictType.
  121. //
  122. // Returns: Return codes from RasDevEnumDevices
  123. //
  124. //*
  125. DWORD APIENTRY
  126. DeviceEnum (char *pszDeviceType,
  127. DWORD *pcEntries,
  128. BYTE *pBuffer,
  129. DWORD *pdwSize)
  130. {
  131. TCHAR szFileName[MAX_PATH];
  132. ConsolePrintf(("DeviceEnum DeviceType: %s\n", pszDeviceType));
  133. *szFileName = TEXT('\0');
  134. GetInfFileName(pszDeviceType, szFileName, sizeof(szFileName));
  135. return(RasDevEnumDevices(szFileName, pcEntries, pBuffer, pdwSize));
  136. }
  137. //* DeviceGetInfo() --------------------------------------------------------
  138. //
  139. // Function: Returns a summary of current information from the InfoTable
  140. // for the device on the port in Pcb.
  141. //
  142. // Returns: Return codes from GetDeviceCB, BuildOutputTable
  143. //*
  144. DWORD APIENTRY
  145. DeviceGetInfo(HANDLE hIOPort,
  146. char *pszDeviceType,
  147. char *pszDeviceName,
  148. BYTE *pInfo,
  149. DWORD *pdwSize)
  150. {
  151. DWORD dRC;
  152. DEVICE_CB *pDevice;
  153. ConsolePrintf(("DeviceGetInfo hIOPort: 0x%08lx\n", hIOPort));
  154. // **** Exclusion Begin ****
  155. WaitForSingleObject(pDeviceListMutex, INFINITE) ;
  156. // Get Device Control Block for this hIOPort
  157. dRC = GetDeviceCB(hIOPort, pszDeviceType, pszDeviceName, &pDevice);
  158. if (dRC != SUCCESS) {
  159. // *** Exclusion End ***
  160. ReleaseMutex(pDeviceListMutex);
  161. return(dRC);
  162. }
  163. // Write summary of InfoTable in DCB to caller's buffer
  164. dRC = BuildOutputTable(pDevice, pInfo, pdwSize) ;
  165. // *** Exclusion End ***
  166. ReleaseMutex(pDeviceListMutex);
  167. return dRC ;
  168. }
  169. //* DeviceSetInfo() --------------------------------------------------------
  170. //
  171. // Function: Sets attributes in the InfoTable for the device on the
  172. // port in Pcb.
  173. //
  174. // Returns: Return codes from GetDeviceCB, UpdateInfoTable
  175. //*
  176. DWORD APIENTRY
  177. DeviceSetInfo(HANDLE hIOPort,
  178. char *pszDeviceType,
  179. char *pszDeviceName,
  180. RASMAN_DEVICEINFO *pInfo)
  181. {
  182. DWORD dwRC;
  183. DEVICE_CB *pDevice;
  184. DWORD dwMemSize = 0;
  185. char szDefaultOff[RAS_MAXLINEBUFLEN];
  186. RASMAN_PORTINFO *pPortInfo = NULL;
  187. ConsolePrintf(("DeviceSetInfo hIOPort: 0x%08lx\n", hIOPort));
  188. // **** Exclusion Begin ****
  189. WaitForSingleObject(pDeviceListMutex, INFINITE) ;
  190. // Get Device Control Block for this hIOPort
  191. dwRC = GetDeviceCB(hIOPort, pszDeviceType, pszDeviceName, &pDevice);
  192. if (dwRC != SUCCESS) {
  193. // *** Exclusion End ***
  194. ReleaseMutex(pDeviceListMutex);
  195. return(dwRC);
  196. }
  197. // Write input data to InfoTable
  198. dwRC = UpdateInfoTable(pDevice, pInfo);
  199. if (dwRC != SUCCESS) {
  200. // *** Exclusion End ***
  201. ReleaseMutex(pDeviceListMutex);
  202. return(dwRC);
  203. }
  204. // Get port info data
  205. dwRC = PortGetInfo(hIOPort, NULL, (BYTE *)NULL, &dwMemSize);
  206. if (dwRC == ERROR_BUFFER_TOO_SMALL)
  207. {
  208. GetMem(dwMemSize, (BYTE **)&pPortInfo);
  209. if (pPortInfo == NULL) {
  210. // *** Exclusion End ***
  211. ReleaseMutex(pDeviceListMutex);
  212. return(ERROR_ALLOCATING_MEMORY);
  213. }
  214. dwRC = PortGetInfo(hIOPort, NULL, (BYTE *)pPortInfo, &dwMemSize);
  215. }
  216. /*
  217. else
  218. {
  219. if(ERROR_SUCCESS == dwRC)
  220. {
  221. dwRC = ERROR_PORT_NOT_FOUND;
  222. }
  223. return dwRC;
  224. }
  225. */
  226. // Save current values of DefaultOff macros as new defaults if this
  227. // device is immediately attached to its port.
  228. if (dwRC == SUCCESS && DeviceAttachedToPort(pPortInfo, pszDeviceType, pszDeviceName))
  229. {
  230. CreateDefaultOffString(pDevice, szDefaultOff);
  231. dwRC = PortSetStringInfo(hIOPort,
  232. SER_DEFAULTOFF_KEY,
  233. szDefaultOff,
  234. strlen(szDefaultOff));
  235. } else
  236. dwRC = SUCCESS ;
  237. free(pPortInfo);
  238. // *** Exclusion End ***
  239. ReleaseMutex(pDeviceListMutex);
  240. return(dwRC);
  241. }
  242. //* DeviceConnect() --------------------------------------------------------
  243. //
  244. // Function: Initiates the process of connecting a device.
  245. //
  246. // Returns: Return codes from ConnectListen
  247. //*
  248. DWORD APIENTRY
  249. DeviceConnect(HANDLE hIOPort,
  250. char *pszDeviceType,
  251. char *pszDeviceName)
  252. {
  253. DWORD dRC;
  254. ConsolePrintf(("DeviceConnect hIOPort: 0x%08lx\n", hIOPort));
  255. // **** Exclusion Begin ****
  256. WaitForSingleObject(pDeviceListMutex, INFINITE) ;
  257. dRC = ConnectListen(hIOPort,
  258. pszDeviceType,
  259. pszDeviceName,
  260. CT_DIAL);
  261. // *** Exclusion End ***
  262. ReleaseMutex(pDeviceListMutex);
  263. return dRC ;
  264. }
  265. //* DeviceListen() ---------------------------------------------------------
  266. //
  267. // Function: Initiates the process of listening for a remote device
  268. // to connect to a local device.
  269. //
  270. // Returns: Return codes from ConnectListen
  271. //*
  272. DWORD APIENTRY
  273. DeviceListen(HANDLE hIOPort,
  274. char *pszDeviceType,
  275. char *pszDeviceName)
  276. {
  277. DWORD dwRC;
  278. ConsolePrintf(("DeviceListen hIOPort: 0x%08lx\n", hIOPort));
  279. // **** Exclusion Begin ****
  280. WaitForSingleObject(pDeviceListMutex, INFINITE) ;
  281. dwRC = ConnectListen(hIOPort,
  282. pszDeviceType,
  283. pszDeviceName,
  284. CT_LISTEN);
  285. ConsolePrintf(("DeviceListen returns: %d\n", dwRC));
  286. // *** Exclusion End ***
  287. ReleaseMutex(pDeviceListMutex);
  288. return(dwRC);
  289. }
  290. //* DeviceDone() -----------------------------------------------------------
  291. //
  292. // Function: Informs the device dll that the attempt to connect or listen
  293. // has completed.
  294. //
  295. // Returns: nothing
  296. //*
  297. VOID APIENTRY
  298. DeviceDone(HANDLE hIOPort)
  299. {
  300. DEVICE_CB *pDevice, *pRemainder, *pPrevDev;
  301. WORD i;
  302. // **** Exclusion Begin ****
  303. WaitForSingleObject(pDeviceListMutex, INFINITE) ;
  304. ConsolePrintf(("DeviceDone\n"));
  305. for (pRemainder = pDeviceList; 1; )
  306. {
  307. // Find device control block for this port
  308. pDevice = FindPortInList(pRemainder, hIOPort, &pPrevDev);
  309. if (pDevice == NULL)
  310. break; //Loop Exit
  311. pRemainder = pDevice->pNextDeviceCB;
  312. // Now clean up the found DCB
  313. // Close INF file section(s)
  314. if (pDevice->hInfFile != INVALID_HRASFILE)
  315. CloseOpenDevSection (pDevice->hInfFile) ;
  316. // See notes on OpenResponseSecion, mxsutils.c
  317. //if (pDevice->eDeviceType == DT_MODEM)
  318. // CloseResponseSection() ;
  319. // Drop device control block from linked list
  320. if (pDevice == pDeviceList) //DCB to drop is 1st on list
  321. pDeviceList = pRemainder;
  322. else
  323. pPrevDev->pNextDeviceCB = pRemainder;
  324. // Free all value strings in InfoTable, then free InfoTable
  325. if (pDevice->pInfoTable != NULL)
  326. {
  327. for (i=0; i < pDevice->pInfoTable->DI_NumOfParams; i++)
  328. if (pDevice->pInfoTable->DI_Params[i].P_Type == String &&
  329. pDevice->pInfoTable->DI_Params[i].P_Value.String.Data != NULL)
  330. free(pDevice->pInfoTable->DI_Params[i].P_Value.String.Data);
  331. free(pDevice->pInfoTable);
  332. }
  333. // Free Macro Table and DCB
  334. if (pDevice->pMacros != NULL)
  335. free(pDevice->pMacros);
  336. free(pDevice);
  337. }
  338. // *** Exclusion End ***
  339. ReleaseMutex(pDeviceListMutex);
  340. }
  341. //* DeviceWork() -----------------------------------------------------------
  342. //
  343. // Function: This function is called following DeviceConnect or
  344. // DeviceListen to further the asynchronous process of
  345. // connecting or listening.
  346. //
  347. // Returns: ERROR_DCB_NOT_FOUND
  348. // ERROR_STATE_MACHINES_NOT_STARTED
  349. // Return codes from DeviceStateMachine
  350. //*
  351. DWORD APIENTRY
  352. DeviceWork(HANDLE hIOPort)
  353. {
  354. DEVICE_CB *pDevice;
  355. DWORD dwRC;
  356. ConsolePrintf(("DeviceWork hIOPort: 0x%08lx hNotifier: 0x%08x\n",
  357. hIOPort, hNotifier));
  358. // Find device control block for this port
  359. // **** Exclusion Begin ****
  360. WaitForSingleObject(pDeviceListMutex, INFINITE) ;
  361. pDevice = FindPortInList(pDeviceList, hIOPort, NULL);
  362. if (pDevice == NULL) {
  363. // *** Exclusion End ***
  364. ReleaseMutex(pDeviceListMutex);
  365. return(ERROR_DCB_NOT_FOUND);
  366. }
  367. // Check that DeviceStateMachine is started (not reset)
  368. if (pDevice->eDevNextAction == SEND) {
  369. // *** Exclusion End ***
  370. ReleaseMutex(pDeviceListMutex);
  371. return(ERROR_STATE_MACHINES_NOT_STARTED);
  372. }
  373. // Advance state machine
  374. while(1)
  375. {
  376. dwRC = DeviceStateMachine(pDevice, hIOPort);
  377. ConsolePrintf(("DeviceWork returns: %d\n", dwRC));
  378. if (dwRC == ERROR_PORT_OR_DEVICE &&
  379. pDevice->eDeviceType == DT_MODEM &&
  380. pDevice->dwRetries++ < MODEM_RETRIES )
  381. {
  382. // Initialize command types
  383. switch(RasDevIdFirstCommand(pDevice->hInfFile))
  384. {
  385. case CT_INIT:
  386. pDevice->eCmdType = CT_INIT; //Reset eCmdType
  387. break;
  388. case CT_DIAL:
  389. case CT_LISTEN:
  390. case CT_GENERIC:
  391. break; //Use old value for eCmdType
  392. default:
  393. // *** Exclusion End ***
  394. ReleaseMutex(pDeviceListMutex);
  395. return(ERROR_NO_COMMAND_FOUND);
  396. }
  397. // Reset state variables to initial values
  398. pDevice->eDevNextAction = SEND;
  399. pDevice->eRcvState = GETECHO;
  400. // Cancel any pending com port action and purge com buffers
  401. PurgeComm(hIOPort,
  402. PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
  403. }
  404. else
  405. break;
  406. }
  407. // *** Exclusion End ***
  408. ReleaseMutex(pDeviceListMutex);
  409. return(dwRC);
  410. }