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.

1020 lines
27 KiB

  1. /*******************************************************************/
  2. /* Copyright(c) 1995 Microsoft Corporation */
  3. /*******************************************************************/
  4. //***
  5. //
  6. // Filename: rmhand.c
  7. //
  8. // Description: This module contains the procedures for the
  9. // DDM's procedure-driven state machine
  10. // that handles RasMan events.
  11. //
  12. // NOTE:Rasman should be modified to set a flag when a frame is
  13. // received or and state change has occurred. This will save
  14. // DDM from getting info for all the ports.
  15. //
  16. // Author: Stefan Solomon (stefans) May 26, 1992.
  17. //
  18. //***
  19. #include "ddm.h"
  20. #include "timer.h"
  21. #include "handlers.h"
  22. #include "objects.h"
  23. #include "util.h"
  24. #include "routerif.h"
  25. #include <raserror.h>
  26. #include <rasppp.h>
  27. #include <ddmif.h>
  28. #include <serial.h>
  29. #include "rasmanif.h"
  30. #include <ras.h>
  31. #include <string.h>
  32. #include <stdlib.h>
  33. #include <memory.h>
  34. //***
  35. //
  36. // Function: SvDevConnected
  37. //
  38. // Description: Handles the device transition to connected state
  39. //
  40. //***
  41. VOID
  42. SvDevConnected(
  43. IN PDEVICE_OBJECT pDeviceObj
  44. )
  45. {
  46. PCONNECTION_OBJECT pConnObj;
  47. HCONN hConnection;
  48. DWORD dwRetCode;
  49. LPWSTR auditstrp[3];
  50. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  51. "SvDevConnected: Entered, hPort=%d", pDeviceObj->hPort);
  52. //
  53. // Get handle to the connection or bundle for this link
  54. //
  55. if ( RasPortGetBundle( NULL,
  56. pDeviceObj->hPort,
  57. &hConnection ) != NO_ERROR )
  58. {
  59. DevStartClosing(pDeviceObj);
  60. return;
  61. }
  62. switch (pDeviceObj->DeviceState)
  63. {
  64. case DEV_OBJ_LISTEN_COMPLETE:
  65. pDeviceObj->hConnection = hConnection;
  66. //
  67. // reset the H/W Error signal state
  68. //
  69. pDeviceObj->dwHwErrorSignalCount = HW_FAILURE_CNT;
  70. //
  71. // get the system time for this connection
  72. //
  73. GetLocalTime( &pDeviceObj->ConnectionTime );
  74. //
  75. // get the frame broadcasted by the client
  76. //
  77. if ( ( dwRetCode = RmReceiveFrame( pDeviceObj ) ) != NO_ERROR )
  78. {
  79. //
  80. // can't get the broadcast frame. This is a fatal error
  81. // Log the error
  82. //
  83. auditstrp[0] = pDeviceObj->wchPortName;
  84. DDMLogErrorString( ROUTERLOG_CANT_RECEIVE_FRAME, 1, auditstrp,
  85. dwRetCode, 1);
  86. DevStartClosing( pDeviceObj );
  87. }
  88. else
  89. {
  90. //
  91. // switch to frame receiving state
  92. //
  93. pDeviceObj->DeviceState = DEV_OBJ_RECEIVING_FRAME;
  94. if ( RAS_DEVICE_TYPE( pDeviceObj->dwDeviceType ) != RDT_Atm )
  95. {
  96. //
  97. // start authentication timer
  98. //
  99. TimerQRemove( (HANDLE)pDeviceObj->hPort, SvAuthTimeout );
  100. TimerQInsert( (HANDLE)pDeviceObj->hPort,
  101. gblDDMConfigInfo.dwAuthenticateTime,
  102. SvAuthTimeout );
  103. }
  104. }
  105. break;
  106. case DEV_OBJ_CALLBACK_CONNECTING:
  107. {
  108. //
  109. // log on the client disconnection
  110. //
  111. WCHAR wchFullUserName[UNLEN+DNLEN+2];
  112. if ( pDeviceObj->wchDomainName[0] != TEXT('\0') )
  113. {
  114. wcscpy( wchFullUserName, pDeviceObj->wchDomainName );
  115. wcscat( wchFullUserName, TEXT("\\") );
  116. wcscat( wchFullUserName, pDeviceObj->wchUserName );
  117. }
  118. else
  119. {
  120. wcscpy( wchFullUserName, pDeviceObj->wchUserName );
  121. }
  122. auditstrp[0] = wchFullUserName;
  123. auditstrp[1] = pDeviceObj->wchPortName;
  124. auditstrp[2] = pDeviceObj->wchCallbackNumber;
  125. DDMLogInformation( ROUTERLOG_CLIENT_CALLED_BACK, 3, auditstrp);
  126. }
  127. //
  128. // set up the new state
  129. //
  130. pDeviceObj->DeviceState = DEV_OBJ_AUTH_IS_ACTIVE;
  131. //
  132. // start authentication timer
  133. //
  134. TimerQRemove( (HANDLE)pDeviceObj->hPort, SvAuthTimeout );
  135. TimerQInsert( (HANDLE)pDeviceObj->hPort,
  136. gblDDMConfigInfo.dwAuthenticateTime,
  137. SvAuthTimeout );
  138. //
  139. // and tell auth to restart conversation
  140. //
  141. if ( pDeviceObj->fFlags & DEV_OBJ_IS_PPP )
  142. {
  143. //
  144. // Need to set framing to PPP to make callback over ISDN
  145. // work.
  146. //
  147. RAS_FRAMING_INFO RasFramingInfo;
  148. ZeroMemory( &RasFramingInfo, sizeof( RasFramingInfo ) );
  149. //
  150. // Default ACCM for PPP is 0xFFFFFFFF
  151. //
  152. RasFramingInfo.RFI_RecvACCM = 0xFFFFFFFF;
  153. RasFramingInfo.RFI_SendACCM = 0xFFFFFFFF;
  154. RasFramingInfo.RFI_MaxSendFrameSize = 1500;
  155. RasFramingInfo.RFI_MaxRecvFrameSize = 1500;
  156. RasFramingInfo.RFI_SendFramingBits = PPP_FRAMING;
  157. RasFramingInfo.RFI_RecvFramingBits = PPP_FRAMING;
  158. RasPortSetFramingEx( pDeviceObj->hPort, &RasFramingInfo );
  159. pDeviceObj->hConnection = hConnection;
  160. PppDdmCallbackDone(pDeviceObj->hPort, pDeviceObj->wchCallbackNumber);
  161. }
  162. else
  163. {
  164. // We only suport PPP framing in the server
  165. //
  166. RTASSERT(FALSE);
  167. }
  168. break;
  169. default:
  170. break;
  171. }
  172. }
  173. //***
  174. //
  175. // Function: SvDevDisconnected
  176. //
  177. // Descr: Handles the device transition to disconnected state
  178. //
  179. //***
  180. VOID
  181. SvDevDisconnected(
  182. IN PDEVICE_OBJECT pDeviceObj
  183. )
  184. {
  185. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  186. "SvDevDisconnected:Entered, hPort=%d",pDeviceObj->hPort);
  187. switch (pDeviceObj->DeviceState)
  188. {
  189. case DEV_OBJ_LISTENING:
  190. //
  191. // h/w error; start h/w error timer
  192. //
  193. pDeviceObj->DeviceState = DEV_OBJ_HW_FAILURE;
  194. TimerQRemove( (HANDLE)pDeviceObj->hPort, SvHwErrDelayCompleted );
  195. TimerQInsert( (HANDLE)pDeviceObj->hPort, HW_FAILURE_WAIT_TIME,
  196. SvHwErrDelayCompleted );
  197. //
  198. // if hw error has not been signaled for this port,
  199. // decrement the counter and signal when 0
  200. //
  201. if(pDeviceObj->dwHwErrorSignalCount)
  202. {
  203. pDeviceObj->dwHwErrorSignalCount--;
  204. if(pDeviceObj->dwHwErrorSignalCount == 0)
  205. {
  206. SignalHwError(pDeviceObj);
  207. }
  208. }
  209. break;
  210. case DEV_OBJ_CALLBACK_DISCONNECTING:
  211. //
  212. // disconnection done; can start waiting the callback delay
  213. //
  214. pDeviceObj->DeviceState = DEV_OBJ_CALLBACK_DISCONNECTED;
  215. TimerQRemove( (HANDLE)pDeviceObj->hPort, SvCbDelayCompleted );
  216. TimerQInsert( (HANDLE)pDeviceObj->hPort, pDeviceObj->dwCallbackDelay,
  217. SvCbDelayCompleted);
  218. break;
  219. case DEV_OBJ_CALLBACK_CONNECTING:
  220. if (gblDDMConfigInfo.dwCallbackRetries > pDeviceObj->dwCallbackRetries)
  221. {
  222. DDMTRACE( "Callback failed, retrying" );
  223. pDeviceObj->dwCallbackRetries++;
  224. pDeviceObj->DeviceState = DEV_OBJ_CALLBACK_DISCONNECTED;
  225. TimerQRemove( (HANDLE)pDeviceObj->hPort, SvCbDelayCompleted );
  226. TimerQInsert( (HANDLE)pDeviceObj->hPort,
  227. pDeviceObj->dwCallbackDelay,
  228. SvCbDelayCompleted );
  229. break;
  230. }
  231. case DEV_OBJ_LISTEN_COMPLETE:
  232. case DEV_OBJ_RECEIVING_FRAME:
  233. case DEV_OBJ_AUTH_IS_ACTIVE:
  234. //
  235. // accidental disconnection; clean-up and restart on this device
  236. //
  237. DevStartClosing( pDeviceObj );
  238. break;
  239. case DEV_OBJ_ACTIVE:
  240. DevStartClosing(pDeviceObj);
  241. break;
  242. case DEV_OBJ_CLOSING:
  243. DevCloseComplete(pDeviceObj);
  244. break;
  245. default:
  246. break;
  247. }
  248. }
  249. VOID
  250. SvDevListenComplete(
  251. IN PDEVICE_OBJECT pDeviceObj
  252. )
  253. {
  254. LPWSTR auditstrp[1];
  255. DWORD dwLength;
  256. DWORD dwRetCode;
  257. DWORD dwBucketIndex = DeviceObjHashPortToBucket( pDeviceObj->hPort );
  258. //
  259. // We reset these values here is case they were set for dialout and the
  260. // dialout failed, we may have not been able to clean up in
  261. // the RasConnectCallback routine in rasapiif.c since the
  262. // RasGetSubEntryHandle may have failed and we hence do not get a
  263. // pointer to the port so we could not cleanup.
  264. //
  265. pDeviceObj->DeviceState = DEV_OBJ_LISTEN_COMPLETE;
  266. pDeviceObj->fFlags &= ~DEV_OBJ_OPENED_FOR_DIALOUT;
  267. pDeviceObj->fFlags &= ~DEV_OBJ_SECURITY_DLL_USED;
  268. pDeviceObj->hConnection = (HCONN)INVALID_HANDLE_VALUE;
  269. pDeviceObj->wchUserName[0] = (WCHAR)NULL;
  270. pDeviceObj->wchDomainName[0] = (WCHAR)NULL;
  271. pDeviceObj->wchCallbackNumber[0] = (WCHAR)NULL;
  272. pDeviceObj->hRasConn = (HRASCONN)NULL;
  273. pDeviceObj->pRasmanSendBuffer = NULL;
  274. pDeviceObj->pRasmanRecvBuffer = NULL;
  275. pDeviceObj->dwCallbackRetries = 0;
  276. pDeviceObj->dwRecvBufferLen = 1500;
  277. dwRetCode = RasGetBuffer((CHAR**)&pDeviceObj->pRasmanRecvBuffer,
  278. &((pDeviceObj->dwRecvBufferLen)) );
  279. if ( dwRetCode != NO_ERROR )
  280. {
  281. auditstrp[0] = pDeviceObj->wchPortName;
  282. DDMLogErrorString( ROUTERLOG_CANT_RECEIVE_BYTES, 1, auditstrp,
  283. dwRetCode, 1);
  284. DevStartClosing(pDeviceObj);
  285. return;
  286. }
  287. //
  288. // If the security DLL is not loaded or we are not serial, simply
  289. // change the state
  290. //
  291. if ( ( gblDDMConfigInfo.lpfnRasBeginSecurityDialog == NULL ) ||
  292. ( gblDDMConfigInfo.lpfnRasEndSecurityDialog == NULL ) ||
  293. (RAS_DEVICE_TYPE(pDeviceObj->dwDeviceType) != RDT_Modem) )
  294. {
  295. //
  296. // Change RASMAN state to CONNECTED from LISTENCOMPLETE and signal
  297. // RmEventHandler
  298. //
  299. if ( RasPortConnectComplete(pDeviceObj->hPort) != NO_ERROR )
  300. {
  301. DevStartClosing(pDeviceObj);
  302. return;
  303. }
  304. SetEvent( gblSupervisorEvents[NUM_DDM_EVENTS+dwBucketIndex] );
  305. }
  306. else
  307. {
  308. // Otherwise call the security dll ordinal to begin the 3rd party
  309. // security dialog with the client
  310. dwLength = 1500;
  311. dwRetCode = RasGetBuffer((CHAR**)&pDeviceObj->pRasmanSendBuffer,
  312. &dwLength );
  313. if ( dwRetCode != NO_ERROR )
  314. {
  315. auditstrp[0] = pDeviceObj->wchPortName;
  316. DDMLogErrorString( ROUTERLOG_CANT_RECEIVE_BYTES, 1, auditstrp,
  317. dwRetCode, 1);
  318. DevStartClosing(pDeviceObj);
  319. return;
  320. }
  321. //
  322. // Make sure that this device type supports raw mode.
  323. //
  324. if ( RasPortSend( pDeviceObj->hPort,
  325. (CHAR*)pDeviceObj->pRasmanSendBuffer,
  326. 0 ) != NO_ERROR )
  327. {
  328. RasFreeBuffer( pDeviceObj->pRasmanSendBuffer );
  329. pDeviceObj->pRasmanSendBuffer = NULL;
  330. //
  331. // Change RASMAN state to CONNECTED from LISTENCOMPLETE and signal
  332. // RmEventHandler
  333. //
  334. if ( RasPortConnectComplete( pDeviceObj->hPort ) != NO_ERROR )
  335. {
  336. DevStartClosing(pDeviceObj);
  337. return;
  338. }
  339. SetEvent( gblSupervisorEvents[NUM_DDM_EVENTS+dwBucketIndex] );
  340. return;
  341. }
  342. dwRetCode = (*gblDDMConfigInfo.lpfnRasBeginSecurityDialog)(
  343. pDeviceObj->hPort,
  344. pDeviceObj->pRasmanSendBuffer ,
  345. dwLength,
  346. pDeviceObj->pRasmanRecvBuffer,
  347. pDeviceObj->dwRecvBufferLen,
  348. RasSecurityDialogComplete );
  349. if ( dwRetCode != NO_ERROR )
  350. {
  351. //
  352. // Audit failure due to error and hangup the line
  353. //
  354. auditstrp[0] = pDeviceObj->wchPortName;
  355. DDMLogErrorString( ROUTERLOG_SEC_AUTH_INTERNAL_ERROR,1,auditstrp,
  356. dwRetCode, 1);
  357. DevStartClosing(pDeviceObj);
  358. return;
  359. }
  360. else
  361. {
  362. pDeviceObj->SecurityState = DEV_OBJ_SECURITY_DIALOG_ACTIVE;
  363. pDeviceObj->fFlags |= DEV_OBJ_SECURITY_DLL_USED;
  364. //
  365. // Start timer for 3rd party security
  366. //
  367. TimerQRemove( (HANDLE)pDeviceObj->hPort, SvSecurityTimeout );
  368. TimerQInsert( (HANDLE)pDeviceObj->hPort,
  369. gblDDMConfigInfo.dwSecurityTime,
  370. SvSecurityTimeout);
  371. }
  372. }
  373. return;
  374. }
  375. //
  376. //*** Array of previous connection state/ current connection state
  377. // used to select the Ras Manager signaled event handler
  378. //
  379. typedef VOID (* RMEVHDLR)(PDEVICE_OBJECT);
  380. typedef struct _RMEHNODE
  381. {
  382. RASMAN_STATE previous_state;
  383. RASMAN_STATE current_state;
  384. RMEVHDLR rmevhandler;
  385. } RMEHNODE, *PRMEHNODE;
  386. RMEHNODE rmehtab[] =
  387. {
  388. // Transition
  389. // Previous --> Current
  390. { CONNECTING, CONNECTED, SvDevConnected },
  391. { LISTENING, LISTENCOMPLETED, SvDevListenComplete },
  392. { LISTENCOMPLETED, CONNECTED, SvDevConnected },
  393. { LISTENCOMPLETED, DISCONNECTED, SvDevDisconnected },
  394. { LISTENING, DISCONNECTED, SvDevDisconnected },
  395. { CONNECTED, DISCONNECTED, SvDevDisconnected },
  396. { DISCONNECTING, DISCONNECTED, SvDevDisconnected },
  397. { CONNECTED, CONNECTING, SvDevDisconnected },
  398. { 0xffff, 0xffff, NULL }// Table Guard
  399. };
  400. VOID
  401. RmEventHandler(
  402. DWORD dwEventIndex
  403. )
  404. {
  405. RASMAN_INFO RasPortInfo;
  406. PDEVICE_OBJECT pDevObj;
  407. PRMEHNODE ehnp;
  408. DWORD dwRetCode;
  409. DWORD dwBucketIndex = dwEventIndex - NUM_DDM_EVENTS;
  410. EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
  411. //
  412. // for each port in this bucket
  413. //
  414. for ( pDevObj = gblDeviceTable.DeviceBucket[dwBucketIndex];
  415. pDevObj != (DEVICE_OBJECT *)NULL;
  416. pDevObj = pDevObj->pNext )
  417. {
  418. //
  419. // get the port state
  420. //
  421. dwRetCode = RasGetInfo( NULL, pDevObj->hPort, &RasPortInfo );
  422. if ( dwRetCode != NO_ERROR )
  423. {
  424. SetLastError( dwRetCode );
  425. DDMTRACE3( "RasGetInfo( 0x%x, 0x%x ) = %d",
  426. pDevObj->hPort, &RasPortInfo, dwRetCode );
  427. //
  428. // Assume the the port is disconnected
  429. //
  430. pDevObj->ConnectionState = DISCONNECTED;
  431. SvDevDisconnected( pDevObj );
  432. continue;
  433. }
  434. //
  435. // check if we own the port now
  436. //
  437. if (!RasPortInfo.RI_OwnershipFlag)
  438. {
  439. //
  440. // skip biplexed ports used by other processes
  441. //
  442. continue;
  443. }
  444. //
  445. // switch on our private connection state
  446. //
  447. switch (pDevObj->ConnectionState)
  448. {
  449. case CONNECTING:
  450. if (RasPortInfo.RI_ConnState == CONNECTING)
  451. {
  452. switch (RasPortInfo.RI_LastError)
  453. {
  454. case SUCCESS:
  455. RasPortConnectComplete(pDevObj->hPort);
  456. //
  457. // force current state to connected.
  458. //
  459. RasPortInfo.RI_ConnState = CONNECTED;
  460. break;
  461. case PENDING:
  462. //
  463. // no action
  464. //
  465. break;
  466. default:
  467. //
  468. // error occured -> force state to disconnecting
  469. //
  470. pDevObj->ConnectionState = DISCONNECTING;
  471. DDM_PRINT(
  472. gblDDMConfigInfo.dwTraceId,
  473. TRACE_FSM,
  474. "RmEventHandler: RI_LastError indicates error when");
  475. DDM_PRINT(
  476. gblDDMConfigInfo.dwTraceId,
  477. TRACE_FSM,
  478. " CONNECTING on port %d !!!\n", pDevObj->hPort );
  479. DDM_PRINT(
  480. gblDDMConfigInfo.dwTraceId,
  481. TRACE_FSM,
  482. "RmEventHandler:RasPortDisconnect posted on port%d\n",
  483. pDevObj->hPort);
  484. if ( pDevObj->DeviceState == DEV_OBJ_CALLBACK_CONNECTING )
  485. {
  486. LPWSTR Parms[3];
  487. WCHAR wchFullUserName[UNLEN+DNLEN+2];
  488. if ( pDevObj->wchDomainName[0] != TEXT('\0') )
  489. {
  490. wcscpy( wchFullUserName, pDevObj->wchDomainName);
  491. wcscat( wchFullUserName, TEXT("\\") );
  492. wcscat( wchFullUserName, pDevObj->wchUserName );
  493. }
  494. else
  495. {
  496. wcscpy( wchFullUserName, pDevObj->wchUserName );
  497. }
  498. Parms[0] = wchFullUserName;
  499. Parms[1] = pDevObj->wchPortName;
  500. Parms[2] = pDevObj->wchCallbackNumber;
  501. DDMLogErrorString(ROUTERLOG_CALLBACK_FAILURE, 3, Parms,
  502. RasPortInfo.RI_LastError, 3 );
  503. }
  504. dwRetCode = RasPortDisconnect(
  505. pDevObj->hPort,
  506. gblSupervisorEvents[NUM_DDM_EVENTS +
  507. dwBucketIndex ] );
  508. RTASSERT((dwRetCode == PENDING) || (dwRetCode == SUCCESS));
  509. break;
  510. }
  511. }
  512. break;
  513. case LISTENING:
  514. if (RasPortInfo.RI_ConnState != LISTENING)
  515. {
  516. break;
  517. }
  518. switch (RasPortInfo.RI_LastError)
  519. {
  520. case PENDING:
  521. //
  522. // no action
  523. //
  524. break;
  525. default:
  526. //
  527. // error occured -> force state to disconnecting
  528. //
  529. pDevObj->ConnectionState = DISCONNECTING;
  530. DDM_PRINT(
  531. gblDDMConfigInfo.dwTraceId,
  532. TRACE_FSM,
  533. "RmEventHandler: RI_LastError indicates error %d when",
  534. RasPortInfo.RI_LastError );
  535. DDM_PRINT(
  536. gblDDMConfigInfo.dwTraceId,
  537. TRACE_FSM,
  538. " LISTENING on port %d !!!\n", pDevObj->hPort );
  539. DDM_PRINT(
  540. gblDDMConfigInfo.dwTraceId,
  541. TRACE_FSM,
  542. "RmEventHandler:RasPortDisconnect posted on port%d\n",
  543. pDevObj->hPort);
  544. dwRetCode = RasPortDisconnect(
  545. pDevObj->hPort,
  546. gblSupervisorEvents[NUM_DDM_EVENTS +
  547. dwBucketIndex ] );
  548. RTASSERT((dwRetCode == PENDING) || (dwRetCode == SUCCESS));
  549. break;
  550. }
  551. break;
  552. default:
  553. break;
  554. }
  555. //
  556. // try to find the table element with the matching previous and
  557. // current connection states
  558. //
  559. for (ehnp=rmehtab; ehnp->rmevhandler != NULL; ehnp++)
  560. {
  561. if ((ehnp->previous_state == pDevObj->ConnectionState) &&
  562. (ehnp->current_state == RasPortInfo.RI_ConnState))
  563. {
  564. //
  565. //*** Match ***
  566. //
  567. DDM_PRINT(
  568. gblDDMConfigInfo.dwTraceId,
  569. TRACE_FSM,
  570. "Rasman state change received from port %d, %d->%d",
  571. pDevObj->hPort, ehnp->previous_state, ehnp->current_state );
  572. //
  573. // change the dcb conn state (previous state) with the
  574. // current state
  575. //
  576. pDevObj->ConnectionState = RasPortInfo.RI_ConnState;
  577. //
  578. // invoke the handler
  579. //
  580. (*ehnp->rmevhandler)(pDevObj);
  581. break;
  582. }
  583. }
  584. }
  585. LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
  586. }
  587. //***
  588. //
  589. // Function: SvFrameReceived
  590. //
  591. // Descr: starts authentication
  592. //
  593. //***
  594. VOID
  595. SvFrameReceived(
  596. IN PDEVICE_OBJECT pDeviceObj,
  597. IN CHAR *framep, // pointer to the received frame
  598. IN DWORD framelen,
  599. IN DWORD dwBucketIndex
  600. )
  601. {
  602. DWORD dwRetCode;
  603. DWORD FrameType;
  604. LPWSTR portnamep;
  605. PCONNECTION_OBJECT pConnObj;
  606. BYTE RecvBuffer[1500];
  607. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  608. "SvFrameReceived: Entered, hPort: %d", pDeviceObj->hPort);
  609. if ( framelen > sizeof( RecvBuffer ) )
  610. {
  611. DDMTRACE2( "Illegal frame length of %d received for port %d",
  612. framelen, pDeviceObj->hPort );
  613. RTASSERT( FALSE );
  614. //
  615. // Frame length is illegal so truncate it
  616. //
  617. framelen = sizeof( RecvBuffer );
  618. }
  619. memcpy( RecvBuffer, framep, framelen);
  620. switch (pDeviceObj->DeviceState)
  621. {
  622. case DEV_OBJ_RECEIVING_FRAME:
  623. if ( !DDMRecognizeFrame( RecvBuffer, (WORD)framelen, &FrameType) )
  624. {
  625. portnamep = pDeviceObj->wchPortName;
  626. DDMLogError(ROUTERLOG_UNRECOGNIZABLE_FRAME_RECVD, 1, &portnamep, 0);
  627. DevStartClosing(pDeviceObj);
  628. return;
  629. }
  630. //
  631. // check first with our authentication module
  632. //
  633. switch( FrameType )
  634. {
  635. case PPP_LCP_PROTOCOL:
  636. pDeviceObj->fFlags |= DEV_OBJ_IS_PPP;
  637. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  638. "SvFrameReceived: PPP frame on port %d",
  639. pDeviceObj->hPort);
  640. dwRetCode = PppDdmStart( pDeviceObj->hPort,
  641. pDeviceObj->wchPortName,
  642. RecvBuffer,
  643. framelen,
  644. gblDDMConfigInfo.dwAuthenticateRetries
  645. );
  646. if ( dwRetCode != NO_ERROR )
  647. {
  648. portnamep = pDeviceObj->wchPortName;
  649. DDMLogErrorString( ROUTERLOG_CANT_START_PPP, 1, &portnamep,
  650. dwRetCode,1);
  651. DevStartClosing(pDeviceObj);
  652. return;
  653. }
  654. break;
  655. case APPLETALK:
  656. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  657. "SvFrameReceived: protocol not supported! %d",
  658. pDeviceObj->hPort);
  659. RTASSERT( FALSE );
  660. break;
  661. default:
  662. break;
  663. }
  664. //
  665. // auth has started OK. Update state
  666. // start auth timer
  667. //
  668. pDeviceObj->DeviceState = DEV_OBJ_AUTH_IS_ACTIVE;
  669. pDeviceObj->fFlags |= DEV_OBJ_AUTH_ACTIVE;
  670. break;
  671. case DEV_OBJ_CLOSING:
  672. DevCloseComplete(pDeviceObj);
  673. break;
  674. default:
  675. break;
  676. }
  677. }
  678. //***
  679. //
  680. // Function: RmRecvFrameEventHandler
  681. //
  682. // Description: Scans the set of opened ports and detects the ports where
  683. // RasPortReceive has completed. Invokes the FSM handling
  684. // procedure for each detected port and frees the receive
  685. // buffer.
  686. //
  687. //***
  688. VOID
  689. RmRecvFrameEventHandler(
  690. DWORD dwEventIndex
  691. )
  692. {
  693. PDEVICE_OBJECT pDevObj;
  694. RASMAN_INFO RasPortInfo;
  695. DWORD dwRetCode;
  696. DWORD dwBucketIndex = dwEventIndex
  697. - NUM_DDM_EVENTS
  698. - gblDeviceTable.NumDeviceBuckets;
  699. EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
  700. //
  701. // for each port in this bucket
  702. //
  703. for ( pDevObj = gblDeviceTable.DeviceBucket[dwBucketIndex];
  704. pDevObj != (DEVICE_OBJECT *)NULL;
  705. pDevObj = pDevObj->pNext )
  706. {
  707. //
  708. // get the port state
  709. //
  710. dwRetCode = RasGetInfo( NULL, pDevObj->hPort, &RasPortInfo );
  711. if ( dwRetCode != NO_ERROR )
  712. {
  713. //
  714. // Assume port is disconncted, so clean up
  715. //
  716. DevStartClosing(pDevObj);
  717. continue;
  718. }
  719. //
  720. // check if we own the port now
  721. //
  722. if (!RasPortInfo.RI_OwnershipFlag)
  723. {
  724. //
  725. // skip biplexed ports used by other processes
  726. //
  727. continue;
  728. }
  729. if ( ( pDevObj->fFlags & DEV_OBJ_RECEIVE_ACTIVE ) &&
  730. ( RasPortInfo.RI_LastError != PENDING ) )
  731. {
  732. //
  733. // recv frame API has completed
  734. //
  735. pDevObj->fFlags &= (~DEV_OBJ_RECEIVE_ACTIVE );
  736. if ( RasPortInfo.RI_LastError != ERROR_PORT_DISCONNECTED )
  737. {
  738. LPBYTE lpBuffer = LocalAlloc(LPTR,RasPortInfo.RI_BytesReceived);
  739. if ( lpBuffer == NULL )
  740. {
  741. DevStartClosing(pDevObj);
  742. continue;
  743. }
  744. memcpy( lpBuffer,
  745. pDevObj->pRasmanRecvBuffer,
  746. RasPortInfo.RI_BytesReceived );
  747. RasFreeBuffer(pDevObj->pRasmanRecvBuffer);
  748. pDevObj->pRasmanRecvBuffer = NULL;
  749. //
  750. // call the FSM handler
  751. //
  752. SvFrameReceived( pDevObj,
  753. lpBuffer,
  754. RasPortInfo.RI_BytesReceived,
  755. dwBucketIndex);
  756. LocalFree( lpBuffer );
  757. }
  758. if ( pDevObj->pRasmanRecvBuffer != NULL )
  759. {
  760. RasFreeBuffer(pDevObj->pRasmanRecvBuffer);
  761. pDevObj->pRasmanRecvBuffer = NULL;
  762. }
  763. }
  764. }
  765. LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
  766. }