Source code of Windows XP (NT5)
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.

1019 lines
26 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. {
  294. //
  295. // Change RASMAN state to CONNECTED from LISTENCOMPLETE and signal
  296. // RmEventHandler
  297. //
  298. if ( RasPortConnectComplete(pDeviceObj->hPort) != NO_ERROR )
  299. {
  300. DevStartClosing(pDeviceObj);
  301. return;
  302. }
  303. SetEvent( gblSupervisorEvents[NUM_DDM_EVENTS+dwBucketIndex] );
  304. }
  305. else
  306. {
  307. // Otherwise call the security dll ordinal to begin the 3rd party
  308. // security dialog with the client
  309. dwLength = 1500;
  310. dwRetCode = RasGetBuffer((CHAR**)&pDeviceObj->pRasmanSendBuffer,
  311. &dwLength );
  312. if ( dwRetCode != NO_ERROR )
  313. {
  314. auditstrp[0] = pDeviceObj->wchPortName;
  315. DDMLogErrorString( ROUTERLOG_CANT_RECEIVE_BYTES, 1, auditstrp,
  316. dwRetCode, 1);
  317. DevStartClosing(pDeviceObj);
  318. return;
  319. }
  320. //
  321. // Make sure that this device type supports raw mode.
  322. //
  323. if ( RasPortSend( pDeviceObj->hPort,
  324. (CHAR*)pDeviceObj->pRasmanSendBuffer,
  325. 0 ) != NO_ERROR )
  326. {
  327. RasFreeBuffer( pDeviceObj->pRasmanSendBuffer );
  328. pDeviceObj->pRasmanSendBuffer = NULL;
  329. //
  330. // Change RASMAN state to CONNECTED from LISTENCOMPLETE and signal
  331. // RmEventHandler
  332. //
  333. if ( RasPortConnectComplete( pDeviceObj->hPort ) != NO_ERROR )
  334. {
  335. DevStartClosing(pDeviceObj);
  336. return;
  337. }
  338. SetEvent( gblSupervisorEvents[NUM_DDM_EVENTS+dwBucketIndex] );
  339. return;
  340. }
  341. dwRetCode = (*gblDDMConfigInfo.lpfnRasBeginSecurityDialog)(
  342. pDeviceObj->hPort,
  343. pDeviceObj->pRasmanSendBuffer ,
  344. dwLength,
  345. pDeviceObj->pRasmanRecvBuffer,
  346. pDeviceObj->dwRecvBufferLen,
  347. RasSecurityDialogComplete );
  348. if ( dwRetCode != NO_ERROR )
  349. {
  350. //
  351. // Audit failure due to error and hangup the line
  352. //
  353. auditstrp[0] = pDeviceObj->wchPortName;
  354. DDMLogErrorString( ROUTERLOG_SEC_AUTH_INTERNAL_ERROR,1,auditstrp,
  355. dwRetCode, 1);
  356. DevStartClosing(pDeviceObj);
  357. return;
  358. }
  359. else
  360. {
  361. pDeviceObj->SecurityState = DEV_OBJ_SECURITY_DIALOG_ACTIVE;
  362. pDeviceObj->fFlags |= DEV_OBJ_SECURITY_DLL_USED;
  363. //
  364. // Start timer for 3rd party security
  365. //
  366. TimerQRemove( (HANDLE)pDeviceObj->hPort, SvSecurityTimeout );
  367. TimerQInsert( (HANDLE)pDeviceObj->hPort,
  368. gblDDMConfigInfo.dwSecurityTime,
  369. SvSecurityTimeout);
  370. }
  371. }
  372. return;
  373. }
  374. //
  375. //*** Array of previous connection state/ current connection state
  376. // used to select the Ras Manager signaled event handler
  377. //
  378. typedef VOID (* RMEVHDLR)(PDEVICE_OBJECT);
  379. typedef struct _RMEHNODE
  380. {
  381. RASMAN_STATE previous_state;
  382. RASMAN_STATE current_state;
  383. RMEVHDLR rmevhandler;
  384. } RMEHNODE, *PRMEHNODE;
  385. RMEHNODE rmehtab[] =
  386. {
  387. // Transition
  388. // Previous --> Current
  389. { CONNECTING, CONNECTED, SvDevConnected },
  390. { LISTENING, LISTENCOMPLETED, SvDevListenComplete },
  391. { LISTENCOMPLETED, CONNECTED, SvDevConnected },
  392. { LISTENCOMPLETED, DISCONNECTED, SvDevDisconnected },
  393. { LISTENING, DISCONNECTED, SvDevDisconnected },
  394. { CONNECTED, DISCONNECTED, SvDevDisconnected },
  395. { DISCONNECTING, DISCONNECTED, SvDevDisconnected },
  396. { CONNECTED, CONNECTING, SvDevDisconnected },
  397. { 0xffff, 0xffff, NULL }// Table Guard
  398. };
  399. VOID
  400. RmEventHandler(
  401. DWORD dwEventIndex
  402. )
  403. {
  404. RASMAN_INFO RasPortInfo;
  405. PDEVICE_OBJECT pDevObj;
  406. PRMEHNODE ehnp;
  407. DWORD dwRetCode;
  408. DWORD dwBucketIndex = dwEventIndex - NUM_DDM_EVENTS;
  409. EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
  410. //
  411. // for each port in this bucket
  412. //
  413. for ( pDevObj = gblDeviceTable.DeviceBucket[dwBucketIndex];
  414. pDevObj != (DEVICE_OBJECT *)NULL;
  415. pDevObj = pDevObj->pNext )
  416. {
  417. //
  418. // get the port state
  419. //
  420. dwRetCode = RasGetInfo( NULL, pDevObj->hPort, &RasPortInfo );
  421. if ( dwRetCode != NO_ERROR )
  422. {
  423. SetLastError( dwRetCode );
  424. DDMTRACE3( "RasGetInfo( 0x%x, 0x%x ) = %d",
  425. pDevObj->hPort, &RasPortInfo, dwRetCode );
  426. //
  427. // Assume the the port is disconnected
  428. //
  429. pDevObj->ConnectionState = DISCONNECTED;
  430. SvDevDisconnected( pDevObj );
  431. continue;
  432. }
  433. //
  434. // check if we own the port now
  435. //
  436. if (!RasPortInfo.RI_OwnershipFlag)
  437. {
  438. //
  439. // skip biplexed ports used by other processes
  440. //
  441. continue;
  442. }
  443. //
  444. // switch on our private connection state
  445. //
  446. switch (pDevObj->ConnectionState)
  447. {
  448. case CONNECTING:
  449. if (RasPortInfo.RI_ConnState == CONNECTING)
  450. {
  451. switch (RasPortInfo.RI_LastError)
  452. {
  453. case SUCCESS:
  454. RasPortConnectComplete(pDevObj->hPort);
  455. //
  456. // force current state to connected.
  457. //
  458. RasPortInfo.RI_ConnState = CONNECTED;
  459. break;
  460. case PENDING:
  461. //
  462. // no action
  463. //
  464. break;
  465. default:
  466. //
  467. // error occured -> force state to disconnecting
  468. //
  469. pDevObj->ConnectionState = DISCONNECTING;
  470. DDM_PRINT(
  471. gblDDMConfigInfo.dwTraceId,
  472. TRACE_FSM,
  473. "RmEventHandler: RI_LastError indicates error when");
  474. DDM_PRINT(
  475. gblDDMConfigInfo.dwTraceId,
  476. TRACE_FSM,
  477. " CONNECTING on port %d !!!\n", pDevObj->hPort );
  478. DDM_PRINT(
  479. gblDDMConfigInfo.dwTraceId,
  480. TRACE_FSM,
  481. "RmEventHandler:RasPortDisconnect posted on port%d\n",
  482. pDevObj->hPort);
  483. if ( pDevObj->DeviceState == DEV_OBJ_CALLBACK_CONNECTING )
  484. {
  485. LPWSTR Parms[3];
  486. WCHAR wchFullUserName[UNLEN+DNLEN+2];
  487. if ( pDevObj->wchDomainName[0] != TEXT('\0') )
  488. {
  489. wcscpy( wchFullUserName, pDevObj->wchDomainName);
  490. wcscat( wchFullUserName, TEXT("\\") );
  491. wcscat( wchFullUserName, pDevObj->wchUserName );
  492. }
  493. else
  494. {
  495. wcscpy( wchFullUserName, pDevObj->wchUserName );
  496. }
  497. Parms[0] = wchFullUserName;
  498. Parms[1] = pDevObj->wchPortName;
  499. Parms[2] = pDevObj->wchCallbackNumber;
  500. DDMLogErrorString(ROUTERLOG_CALLBACK_FAILURE, 3, Parms,
  501. RasPortInfo.RI_LastError, 3 );
  502. }
  503. dwRetCode = RasPortDisconnect(
  504. pDevObj->hPort,
  505. gblSupervisorEvents[NUM_DDM_EVENTS +
  506. dwBucketIndex ] );
  507. RTASSERT((dwRetCode == PENDING) || (dwRetCode == SUCCESS));
  508. break;
  509. }
  510. }
  511. break;
  512. case LISTENING:
  513. if (RasPortInfo.RI_ConnState != LISTENING)
  514. {
  515. break;
  516. }
  517. switch (RasPortInfo.RI_LastError)
  518. {
  519. case PENDING:
  520. //
  521. // no action
  522. //
  523. break;
  524. default:
  525. //
  526. // error occured -> force state to disconnecting
  527. //
  528. pDevObj->ConnectionState = DISCONNECTING;
  529. DDM_PRINT(
  530. gblDDMConfigInfo.dwTraceId,
  531. TRACE_FSM,
  532. "RmEventHandler: RI_LastError indicates error %d when",
  533. RasPortInfo.RI_LastError );
  534. DDM_PRINT(
  535. gblDDMConfigInfo.dwTraceId,
  536. TRACE_FSM,
  537. " LISTENING on port %d !!!\n", pDevObj->hPort );
  538. DDM_PRINT(
  539. gblDDMConfigInfo.dwTraceId,
  540. TRACE_FSM,
  541. "RmEventHandler:RasPortDisconnect posted on port%d\n",
  542. pDevObj->hPort);
  543. dwRetCode = RasPortDisconnect(
  544. pDevObj->hPort,
  545. gblSupervisorEvents[NUM_DDM_EVENTS +
  546. dwBucketIndex ] );
  547. RTASSERT((dwRetCode == PENDING) || (dwRetCode == SUCCESS));
  548. break;
  549. }
  550. break;
  551. default:
  552. break;
  553. }
  554. //
  555. // try to find the table element with the matching previous and
  556. // current connection states
  557. //
  558. for (ehnp=rmehtab; ehnp->rmevhandler != NULL; ehnp++)
  559. {
  560. if ((ehnp->previous_state == pDevObj->ConnectionState) &&
  561. (ehnp->current_state == RasPortInfo.RI_ConnState))
  562. {
  563. //
  564. //*** Match ***
  565. //
  566. DDM_PRINT(
  567. gblDDMConfigInfo.dwTraceId,
  568. TRACE_FSM,
  569. "Rasman state change received from port %d, %d->%d",
  570. pDevObj->hPort, ehnp->previous_state, ehnp->current_state );
  571. //
  572. // change the dcb conn state (previous state) with the
  573. // current state
  574. //
  575. pDevObj->ConnectionState = RasPortInfo.RI_ConnState;
  576. //
  577. // invoke the handler
  578. //
  579. (*ehnp->rmevhandler)(pDevObj);
  580. break;
  581. }
  582. }
  583. }
  584. LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
  585. }
  586. //***
  587. //
  588. // Function: SvFrameReceived
  589. //
  590. // Descr: starts authentication
  591. //
  592. //***
  593. VOID
  594. SvFrameReceived(
  595. IN PDEVICE_OBJECT pDeviceObj,
  596. IN CHAR *framep, // pointer to the received frame
  597. IN DWORD framelen,
  598. IN DWORD dwBucketIndex
  599. )
  600. {
  601. DWORD dwRetCode;
  602. DWORD FrameType;
  603. LPWSTR portnamep;
  604. PCONNECTION_OBJECT pConnObj;
  605. BYTE RecvBuffer[1500];
  606. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  607. "SvFrameReceived: Entered, hPort: %d", pDeviceObj->hPort);
  608. if ( framelen > sizeof( RecvBuffer ) )
  609. {
  610. DDMTRACE2( "Illegal frame length of %d received for port %d",
  611. framelen, pDeviceObj->hPort );
  612. RTASSERT( FALSE );
  613. //
  614. // Frame length is illegal so truncate it
  615. //
  616. framelen = sizeof( RecvBuffer );
  617. }
  618. memcpy( RecvBuffer, framep, framelen);
  619. switch (pDeviceObj->DeviceState)
  620. {
  621. case DEV_OBJ_RECEIVING_FRAME:
  622. if ( !DDMRecognizeFrame( RecvBuffer, (WORD)framelen, &FrameType) )
  623. {
  624. portnamep = pDeviceObj->wchPortName;
  625. DDMLogError(ROUTERLOG_UNRECOGNIZABLE_FRAME_RECVD, 1, &portnamep, 0);
  626. DevStartClosing(pDeviceObj);
  627. return;
  628. }
  629. //
  630. // check first with our authentication module
  631. //
  632. switch( FrameType )
  633. {
  634. case PPP_LCP_PROTOCOL:
  635. pDeviceObj->fFlags |= DEV_OBJ_IS_PPP;
  636. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  637. "SvFrameReceived: PPP frame on port %d",
  638. pDeviceObj->hPort);
  639. dwRetCode = PppDdmStart( pDeviceObj->hPort,
  640. pDeviceObj->wchPortName,
  641. RecvBuffer,
  642. framelen,
  643. gblDDMConfigInfo.dwAuthenticateRetries
  644. );
  645. if ( dwRetCode != NO_ERROR )
  646. {
  647. portnamep = pDeviceObj->wchPortName;
  648. DDMLogErrorString( ROUTERLOG_CANT_START_PPP, 1, &portnamep,
  649. dwRetCode,1);
  650. DevStartClosing(pDeviceObj);
  651. return;
  652. }
  653. break;
  654. case APPLETALK:
  655. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  656. "SvFrameReceived: protocol not supported! %d",
  657. pDeviceObj->hPort);
  658. RTASSERT( FALSE );
  659. break;
  660. default:
  661. break;
  662. }
  663. //
  664. // auth has started OK. Update state
  665. // start auth timer
  666. //
  667. pDeviceObj->DeviceState = DEV_OBJ_AUTH_IS_ACTIVE;
  668. pDeviceObj->fFlags |= DEV_OBJ_AUTH_ACTIVE;
  669. break;
  670. case DEV_OBJ_CLOSING:
  671. DevCloseComplete(pDeviceObj);
  672. break;
  673. default:
  674. break;
  675. }
  676. }
  677. //***
  678. //
  679. // Function: RmRecvFrameEventHandler
  680. //
  681. // Description: Scans the set of opened ports and detects the ports where
  682. // RasPortReceive has completed. Invokes the FSM handling
  683. // procedure for each detected port and frees the receive
  684. // buffer.
  685. //
  686. //***
  687. VOID
  688. RmRecvFrameEventHandler(
  689. DWORD dwEventIndex
  690. )
  691. {
  692. PDEVICE_OBJECT pDevObj;
  693. RASMAN_INFO RasPortInfo;
  694. DWORD dwRetCode;
  695. DWORD dwBucketIndex = dwEventIndex
  696. - NUM_DDM_EVENTS
  697. - gblDeviceTable.NumDeviceBuckets;
  698. EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
  699. //
  700. // for each port in this bucket
  701. //
  702. for ( pDevObj = gblDeviceTable.DeviceBucket[dwBucketIndex];
  703. pDevObj != (DEVICE_OBJECT *)NULL;
  704. pDevObj = pDevObj->pNext )
  705. {
  706. //
  707. // get the port state
  708. //
  709. dwRetCode = RasGetInfo( NULL, pDevObj->hPort, &RasPortInfo );
  710. if ( dwRetCode != NO_ERROR )
  711. {
  712. //
  713. // Assume port is disconncted, so clean up
  714. //
  715. DevStartClosing(pDevObj);
  716. continue;
  717. }
  718. //
  719. // check if we own the port now
  720. //
  721. if (!RasPortInfo.RI_OwnershipFlag)
  722. {
  723. //
  724. // skip biplexed ports used by other processes
  725. //
  726. continue;
  727. }
  728. if ( ( pDevObj->fFlags & DEV_OBJ_RECEIVE_ACTIVE ) &&
  729. ( RasPortInfo.RI_LastError != PENDING ) )
  730. {
  731. //
  732. // recv frame API has completed
  733. //
  734. pDevObj->fFlags &= (~DEV_OBJ_RECEIVE_ACTIVE );
  735. if ( RasPortInfo.RI_LastError != ERROR_PORT_DISCONNECTED )
  736. {
  737. LPBYTE lpBuffer = LocalAlloc(LPTR,RasPortInfo.RI_BytesReceived);
  738. if ( lpBuffer == NULL )
  739. {
  740. DevStartClosing(pDevObj);
  741. continue;
  742. }
  743. memcpy( lpBuffer,
  744. pDevObj->pRasmanRecvBuffer,
  745. RasPortInfo.RI_BytesReceived );
  746. RasFreeBuffer(pDevObj->pRasmanRecvBuffer);
  747. pDevObj->pRasmanRecvBuffer = NULL;
  748. //
  749. // call the FSM handler
  750. //
  751. SvFrameReceived( pDevObj,
  752. lpBuffer,
  753. RasPortInfo.RI_BytesReceived,
  754. dwBucketIndex);
  755. LocalFree( lpBuffer );
  756. }
  757. if ( pDevObj->pRasmanRecvBuffer != NULL )
  758. {
  759. RasFreeBuffer(pDevObj->pRasmanRecvBuffer);
  760. pDevObj->pRasmanRecvBuffer = NULL;
  761. }
  762. }
  763. }
  764. LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
  765. }