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.

1508 lines
40 KiB

  1. /*******************************************************************/
  2. /* Copyright(c) 1992 Microsoft Corporation */
  3. /*******************************************************************/
  4. //***
  5. //
  6. // Filename: ppphand.c
  7. //
  8. // Description: This module contains the procedures for the
  9. // supervisor's procedure-driven state machine
  10. // that handle PPP events.
  11. //
  12. // Author: Stefan Solomon (stefans) May 26, 1992.
  13. //
  14. //***
  15. #include "ddm.h"
  16. #include "timer.h"
  17. #include "handlers.h"
  18. #include "objects.h"
  19. #include "util.h"
  20. #include "routerif.h"
  21. #include <raserror.h>
  22. #include <rasppp.h>
  23. #include <ddmif.h>
  24. #include <serial.h>
  25. #include "rasmanif.h"
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <memory.h>
  29. //
  30. // This lives in rasapi32.dll
  31. //
  32. DWORD
  33. DDMGetPppParameters(
  34. LPWSTR lpwsPhonebookName,
  35. LPWSTR lpwsPhonebookEntry,
  36. CHAR * szzPppParameters
  37. );
  38. //***
  39. //
  40. // Function: SvPppSendInterfaceInfo
  41. //
  42. // Description: Ppp engine wants to get the interface handles for this
  43. // connection.
  44. //
  45. VOID
  46. SvPppSendInterfaceInfo(
  47. IN PDEVICE_OBJECT pDeviceObj
  48. )
  49. {
  50. ROUTER_INTERFACE_OBJECT * pIfObject;
  51. PPP_INTERFACE_INFO PppInterfaceInfo;
  52. DWORD dwXportIndex;
  53. PCONNECTION_OBJECT pConnObj;
  54. DDM_PRINT(gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  55. "SvPppSendInterfaceHandles: Entered, hPort=%d",pDeviceObj->hPort);
  56. ZeroMemory( &PppInterfaceInfo, sizeof( PppInterfaceInfo ) );
  57. if ( ( pConnObj = ConnObjGetPointer( pDeviceObj->hConnection ) ) == NULL )
  58. {
  59. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM, "No ConnObj" );
  60. return;
  61. }
  62. EnterCriticalSection( &(gblpInterfaceTable->CriticalSection) );
  63. if ( ( pIfObject = IfObjectGetPointer( pConnObj->hDIMInterface ) ) == NULL )
  64. {
  65. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM, "No IfObject" );
  66. LeaveCriticalSection( &(gblpInterfaceTable->CriticalSection) );
  67. return;
  68. }
  69. //
  70. // Get handles to this interface for each transport and notify PPP.
  71. //
  72. for ( dwXportIndex = 0;
  73. dwXportIndex < gblDDMConfigInfo.dwNumRouterManagers;
  74. dwXportIndex++ )
  75. {
  76. switch( gblRouterManagers[dwXportIndex].DdmRouterIf.dwProtocolId )
  77. {
  78. case PID_IPX:
  79. if (pIfObject->Transport[dwXportIndex].fState & RITRANSPORT_ENABLED)
  80. {
  81. PppInterfaceInfo.hIPXInterface =
  82. pIfObject->Transport[dwXportIndex].hInterface;
  83. }
  84. else
  85. {
  86. PppInterfaceInfo.hIPXInterface = INVALID_HANDLE_VALUE;
  87. }
  88. break;
  89. case PID_IP:
  90. if (pIfObject->Transport[dwXportIndex].fState & RITRANSPORT_ENABLED)
  91. {
  92. PppInterfaceInfo.hIPInterface =
  93. pIfObject->Transport[dwXportIndex].hInterface;
  94. CopyMemory( PppInterfaceInfo.szzParameters,
  95. pIfObject->PppInterfaceInfo.szzParameters,
  96. sizeof( PppInterfaceInfo.szzParameters ) );
  97. }
  98. else
  99. {
  100. PppInterfaceInfo.hIPInterface = INVALID_HANDLE_VALUE;
  101. }
  102. break;
  103. default:
  104. break;
  105. }
  106. }
  107. PppInterfaceInfo.IfType = pIfObject->IfType;
  108. LeaveCriticalSection( &(gblpInterfaceTable->CriticalSection) );
  109. PppDdmSendInterfaceInfo( pDeviceObj->hConnection, &PppInterfaceInfo );
  110. }
  111. //***
  112. //
  113. // Function: SvPppUserOK
  114. //
  115. // Description: User has passed security verification and entered the
  116. // configuration conversation phase. Stops auth timer and
  117. // logs the user.
  118. //
  119. //***
  120. VOID
  121. SvPppUserOK(
  122. IN PDEVICE_OBJECT pDeviceObj,
  123. IN PPPDDM_AUTH_RESULT * pAuthResult
  124. )
  125. {
  126. LPWSTR lpstrAudit[2];
  127. ROUTER_INTERFACE_OBJECT * pIfObject;
  128. PCONNECTION_OBJECT pConnObj;
  129. DWORD dwRetCode = NO_ERROR;
  130. WCHAR wchUserName[UNLEN+1];
  131. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  132. "SvPppUserOK: Entered, hPort=%d", pDeviceObj->hPort);
  133. if ( pDeviceObj->DeviceState != DEV_OBJ_AUTH_IS_ACTIVE )
  134. {
  135. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM, "Auth not started" );
  136. return;
  137. }
  138. //
  139. // Stop authentication timer
  140. //
  141. TimerQRemove( (HANDLE)pDeviceObj->hPort, SvAuthTimeout );
  142. if ( strlen( pAuthResult->szUserName ) > 0 )
  143. {
  144. MultiByteToWideChar( CP_ACP,
  145. 0,
  146. pAuthResult->szUserName,
  147. -1,
  148. wchUserName,
  149. UNLEN+1 );
  150. }
  151. else
  152. {
  153. wcscpy( wchUserName, gblpszUnknown );
  154. }
  155. //
  156. // Check to see if the username and domain are the same if the 3rd party
  157. // security DLL is installed..
  158. //
  159. if ( ( gblDDMConfigInfo.lpfnRasBeginSecurityDialog != NULL ) &&
  160. ( gblDDMConfigInfo.lpfnRasEndSecurityDialog != NULL ) &&
  161. ( pDeviceObj->fFlags & DEV_OBJ_SECURITY_DLL_USED ) )
  162. {
  163. //
  164. // If there is no match then hangup the line
  165. //
  166. if ( _wcsicmp( pDeviceObj->wchUserName, wchUserName ) != 0 )
  167. {
  168. lpstrAudit[0] = pDeviceObj->wchUserName;
  169. lpstrAudit[1] = wchUserName;
  170. DDMLogWarning( ROUTERLOG_AUTH_DIFFUSER_FAILURE, 2, lpstrAudit );
  171. PppDdmStop( pDeviceObj->hPort, ERROR_ACCESS_DENIED );
  172. return;
  173. }
  174. }
  175. //
  176. // copy the user name
  177. //
  178. wcscpy( pDeviceObj->wchUserName, wchUserName );
  179. //
  180. // copy the domain name
  181. //
  182. MultiByteToWideChar( CP_ACP,
  183. 0,
  184. pAuthResult->szLogonDomain,
  185. -1,
  186. pDeviceObj->wchDomainName,
  187. DNLEN+1 );
  188. //
  189. // copy the advanced server flag
  190. //
  191. if ( pAuthResult->fAdvancedServer )
  192. {
  193. pDeviceObj->fFlags |= DEV_OBJ_IS_ADVANCED_SERVER;
  194. }
  195. EnterCriticalSection( &(gblpInterfaceTable->CriticalSection) );
  196. do
  197. {
  198. //
  199. // Check to see if there are any non-client intefaces with this
  200. // name.
  201. //
  202. pIfObject = IfObjectGetPointerByName( pDeviceObj->wchUserName, FALSE );
  203. if ( pIfObject == (ROUTER_INTERFACE_OBJECT *)NULL )
  204. {
  205. //
  206. // If this is a client dialing in and clients are not allowed
  207. // to dialin to this port, then disconnect them.
  208. //
  209. if ( !( pDeviceObj->fFlags & DEV_OBJ_ALLOW_CLIENTS ) )
  210. {
  211. dwRetCode = ERROR_NOT_CLIENT_PORT;
  212. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  213. "A client tried to connect on a router only port=%d",
  214. pDeviceObj->hPort);
  215. break;
  216. }
  217. }
  218. else
  219. {
  220. //
  221. // If a call came in for an interface that is not dynamic
  222. // then do not accept the line
  223. //
  224. if ( ( pIfObject->IfType == ROUTER_IF_TYPE_DEDICATED ) ||
  225. ( pIfObject->IfType == ROUTER_IF_TYPE_INTERNAL ) )
  226. {
  227. //
  228. // Notify PPP not to accept the connection
  229. //
  230. dwRetCode = ERROR_ALREADY_CONNECTED;
  231. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  232. "The interface %ws is already connected port=%d",
  233. pIfObject->lpwsInterfaceName, pDeviceObj->hPort );
  234. break;
  235. }
  236. //
  237. // Allow the connection only if the interface is enabled
  238. //
  239. if ( !( pIfObject->fFlags & IFFLAG_ENABLED ) )
  240. {
  241. dwRetCode = ERROR_INTERFACE_DISABLED;
  242. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  243. "The interface %ws is disabled",
  244. pIfObject->lpwsInterfaceName );
  245. break;
  246. }
  247. if ( !( pDeviceObj->fFlags & DEV_OBJ_ALLOW_ROUTERS ) )
  248. {
  249. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  250. "A router tried to connect on a client only port=%d",
  251. pDeviceObj->hPort);
  252. dwRetCode = ERROR_NOT_ROUTER_PORT;
  253. break;
  254. }
  255. //
  256. // Set current usage in rasman to ROUTER
  257. //
  258. RasSetRouterUsage( pDeviceObj->hPort, TRUE );
  259. }
  260. } while( FALSE );
  261. LeaveCriticalSection( &(gblpInterfaceTable->CriticalSection) );
  262. if ( dwRetCode != NO_ERROR )
  263. {
  264. LPWSTR lpstrAudit[2];
  265. lpstrAudit[0] = pDeviceObj->wchUserName;
  266. lpstrAudit[1] = pDeviceObj->wchPortName;
  267. DDMLogWarningString( ROUTERLOG_CONNECTION_ATTEMPT_FAILURE,
  268. 2,
  269. lpstrAudit,
  270. dwRetCode,
  271. 2 );
  272. PppDdmStop( pDeviceObj->hPort, dwRetCode );
  273. }
  274. return;
  275. }
  276. //***
  277. //
  278. // Function: SvPppNewLinkOrBundle
  279. //
  280. // Description: User has passed security verification and entered the
  281. // configuration conversation phase. Stops auth timer and
  282. // logs the user.
  283. //
  284. //***
  285. VOID
  286. SvPppNewLinkOrBundle(
  287. IN PDEVICE_OBJECT pDeviceObj,
  288. IN BOOL fNewBundle,
  289. IN PBYTE pClientInterface
  290. )
  291. {
  292. LPWSTR lpstrAudit[2];
  293. ROUTER_INTERFACE_OBJECT * pIfObject;
  294. PCONNECTION_OBJECT pConnObj;
  295. DWORD dwRetCode = NO_ERROR;
  296. WCHAR wchUserName[UNLEN+1];
  297. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  298. "SvPppNewLinkOrBundle: Entered, hPort=%d", pDeviceObj->hPort);
  299. if ( pDeviceObj->DeviceState != DEV_OBJ_AUTH_IS_ACTIVE )
  300. {
  301. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM, "Auth not started" );
  302. return;
  303. }
  304. //
  305. // Get handle to the connection or bundle for this link
  306. //
  307. if ( ( dwRetCode = RasPortGetBundle( NULL, pDeviceObj->hPort,
  308. &(pDeviceObj->hConnection) ) ) != NO_ERROR )
  309. {
  310. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  311. "RasPortGetBundle failed: %d", dwRetCode );
  312. PppDdmStop( pDeviceObj->hPort, dwRetCode );
  313. return;
  314. }
  315. //
  316. // Allocate a connection object if it does not exist yet
  317. //
  318. pConnObj = ConnObjGetPointer( pDeviceObj->hConnection );
  319. if ( pConnObj == (CONNECTION_OBJECT *)NULL )
  320. {
  321. pConnObj = ConnObjAllocateAndInit( INVALID_HANDLE_VALUE,
  322. pDeviceObj->hConnection );
  323. if ( pConnObj == (CONNECTION_OBJECT *)NULL )
  324. {
  325. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  326. "ConnObjAllocateAndInit failed" );
  327. PppDdmStop( pDeviceObj->hPort, ERROR_NOT_ENOUGH_MEMORY );
  328. return;
  329. }
  330. pConnObj->fFlags = CONN_OBJ_IS_PPP;
  331. pConnObj->hPort = pDeviceObj->hPort;
  332. wcscpy( pConnObj->wchInterfaceName, pDeviceObj->wchUserName );
  333. //
  334. // copy the user name
  335. //
  336. wcscpy( pConnObj->wchUserName, pDeviceObj->wchUserName );
  337. //
  338. // copy the domain name
  339. //
  340. wcscpy( pConnObj->wchDomainName, pDeviceObj->wchDomainName );
  341. //
  342. // If it is a router, check to see if we have an interface for this
  343. // router, otherwise reject this connection.
  344. //
  345. EnterCriticalSection( &(gblpInterfaceTable->CriticalSection) );
  346. do
  347. {
  348. //
  349. // Check to see if there are any non-client intefaces with this
  350. // name.
  351. //
  352. pIfObject = IfObjectGetPointerByName( pConnObj->wchInterfaceName,
  353. FALSE );
  354. //
  355. // We do not have this interface in our database so assume that
  356. // this is a client so we need to create and interface and add it
  357. // to all the router managers. Also if this interface exists but
  358. // is for a client we need to add this interface again.
  359. //
  360. if ( pIfObject == (ROUTER_INTERFACE_OBJECT *)NULL )
  361. {
  362. pIfObject = IfObjectAllocateAndInit(
  363. pConnObj->wchUserName,
  364. RISTATE_CONNECTING,
  365. ROUTER_IF_TYPE_CLIENT,
  366. pConnObj->hConnection,
  367. TRUE,
  368. 0,
  369. 0,
  370. NULL );
  371. if ( pIfObject == (ROUTER_INTERFACE_OBJECT *)NULL )
  372. {
  373. //
  374. // Error log this and stop the connection.
  375. //
  376. dwRetCode = GetLastError();
  377. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  378. "IfObjectAllocateAndInit failed: %d", dwRetCode);
  379. break;
  380. }
  381. //
  382. // Add interfaces to router managers, insert in table now
  383. // because of the table lookup within the InterfaceEnabled
  384. // call made in the context of AddInterface.
  385. //
  386. dwRetCode = IfObjectInsertInTable( pIfObject );
  387. if ( dwRetCode != NO_ERROR )
  388. {
  389. LOCAL_FREE( pIfObject );
  390. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  391. "IfObjectInsertInTable failed: %d", dwRetCode );
  392. break;
  393. }
  394. dwRetCode = IfObjectAddClientInterface( pIfObject,
  395. pClientInterface );
  396. if ( dwRetCode != NO_ERROR )
  397. {
  398. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  399. "IfObjectAddClientInterface failed: %d",
  400. dwRetCode );
  401. IfObjectRemove( pIfObject->hDIMInterface );
  402. break;
  403. }
  404. }
  405. else
  406. {
  407. //
  408. // If the interface is already connecting or connected
  409. // and this is a new bundle then we need to reject this
  410. // connection.
  411. //
  412. if ( pIfObject->State != RISTATE_DISCONNECTED )
  413. {
  414. //
  415. // Notify PPP not to accept the connection
  416. //
  417. dwRetCode = ERROR_ALREADY_CONNECTED;
  418. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  419. "The interface %ws is already connected port=%d",
  420. pIfObject->lpwsInterfaceName, pDeviceObj->hPort );
  421. break;
  422. }
  423. }
  424. ConnObjInsertInTable( pConnObj );
  425. pIfObject->State = RISTATE_CONNECTING;
  426. pConnObj->hDIMInterface = pIfObject->hDIMInterface;
  427. pConnObj->InterfaceType = pIfObject->IfType;
  428. } while( FALSE );
  429. LeaveCriticalSection( &(gblpInterfaceTable->CriticalSection) );
  430. if ( dwRetCode != NO_ERROR )
  431. {
  432. PppDdmStop( pDeviceObj->hPort, dwRetCode );
  433. LOCAL_FREE( pConnObj );
  434. return;
  435. }
  436. }
  437. //
  438. // Since this is a new bundle also send the interface handles
  439. //
  440. if ( fNewBundle )
  441. {
  442. SvPppSendInterfaceInfo( pDeviceObj );
  443. }
  444. //
  445. // Add this link to the connection block.
  446. //
  447. if ( ( dwRetCode = ConnObjAddLink( pConnObj, pDeviceObj ) ) != NO_ERROR )
  448. {
  449. PppDdmStop( pDeviceObj->hPort, ERROR_NOT_ENOUGH_MEMORY );
  450. DDMLogError( ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, dwRetCode );
  451. return;
  452. }
  453. }
  454. //***
  455. //
  456. // Function: SvPppFailure
  457. //
  458. // Descr: Ppp will let us know of any failure while active on a port.
  459. // An error message is sent to us and we merely log it and
  460. // disconnect the port.
  461. //
  462. //***
  463. VOID
  464. SvPppFailure(
  465. IN PDEVICE_OBJECT pDeviceObj,
  466. IN PPPDDM_FAILURE *afp
  467. )
  468. {
  469. LPWSTR auditstrp[3];
  470. WCHAR wchErrorString[256+1];
  471. WCHAR wchUserName[UNLEN+DNLEN+1];
  472. WCHAR wchDomainName[DNLEN+1];
  473. DWORD dwRetCode;
  474. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  475. "SvPppFailure: Entered, hPort=%d, Error=%d",
  476. pDeviceObj->hPort, afp->dwError );
  477. //
  478. // Was this a failure for a BAP callback?
  479. //
  480. if ( pDeviceObj->fFlags & DEV_OBJ_BAP_CALLBACK )
  481. {
  482. PppDdmBapCallbackResult( pDeviceObj->hBapConnection, afp->dwError );
  483. pDeviceObj->fFlags &= ~DEV_OBJ_BAP_CALLBACK;
  484. }
  485. if ( afp->szUserName[0] != (CHAR)NULL )
  486. {
  487. MultiByteToWideChar( CP_ACP, 0, afp->szUserName, -1, wchUserName, UNLEN+1 );
  488. }
  489. else
  490. {
  491. wcscpy( wchUserName, gblpszUnknown );
  492. }
  493. //
  494. // We ignore the DeviceState here because a Ppp failure can occur at
  495. // any time during the connection.
  496. //
  497. switch( afp->dwError )
  498. {
  499. case ERROR_AUTHENTICATION_FAILURE:
  500. auditstrp[0] = wchUserName;
  501. auditstrp[1] = pDeviceObj->wchPortName;
  502. DDMLogWarning( ROUTERLOG_AUTH_FAILURE,2,auditstrp );
  503. break;
  504. case ERROR_PASSWD_EXPIRED:
  505. MultiByteToWideChar( CP_ACP, 0, afp->szLogonDomain, -1, wchDomainName, DNLEN+1 );
  506. auditstrp[0] = wchDomainName;
  507. auditstrp[1] = wchUserName;
  508. auditstrp[2] = pDeviceObj->wchPortName;
  509. DDMLogWarning( ROUTERLOG_PASSWORD_EXPIRED, 3, auditstrp );
  510. break;
  511. case ERROR_ACCT_EXPIRED:
  512. case ERROR_ACCOUNT_EXPIRED:
  513. MultiByteToWideChar( CP_ACP, 0, afp->szLogonDomain, -1, wchDomainName, DNLEN+1 );
  514. auditstrp[0] = wchDomainName;
  515. auditstrp[1] = wchUserName;
  516. auditstrp[2] = pDeviceObj->wchPortName;
  517. DDMLogWarning( ROUTERLOG_ACCT_EXPIRED, 3, auditstrp );
  518. break;
  519. case ERROR_NO_DIALIN_PERMISSION:
  520. MultiByteToWideChar( CP_ACP, 0, afp->szLogonDomain, -1, wchDomainName, DNLEN+1 );
  521. auditstrp[0] = wchDomainName;
  522. auditstrp[1] = wchUserName;
  523. auditstrp[2] = pDeviceObj->wchPortName;
  524. DDMLogWarning( ROUTERLOG_NO_DIALIN_PRIVILEGE, 3, auditstrp );
  525. break;
  526. case ERROR_REQ_NOT_ACCEP:
  527. auditstrp[0] = pDeviceObj->wchPortName;
  528. DDMLogWarning( ROUTERLOG_LICENSE_LIMIT_EXCEEDED, 1, auditstrp );
  529. break;
  530. case ERROR_BAP_DISCONNECTED:
  531. case ERROR_BAP_REQUIRED:
  532. auditstrp[0] = wchUserName;
  533. auditstrp[1] = pDeviceObj->wchPortName;
  534. DDMLogWarningString( ROUTERLOG_BAP_DISCONNECT, 2, auditstrp,
  535. afp->dwError, 2 );
  536. break;
  537. case ERROR_PORT_NOT_CONNECTED:
  538. case ERROR_PPP_TIMEOUT:
  539. case ERROR_PPP_LCP_TERMINATED:
  540. case ERROR_NOT_CONNECTED:
  541. //
  542. // Ignore this error
  543. //
  544. break;
  545. case ERROR_PPP_NOT_CONVERGING:
  546. default:
  547. if ( afp->szUserName[0] != (CHAR)NULL )
  548. {
  549. if ( afp->szLogonDomain[0] != (CHAR)NULL )
  550. {
  551. MultiByteToWideChar(CP_ACP,0,afp->szLogonDomain,-1,wchUserName,UNLEN+1);
  552. wcscat( wchUserName, L"\\" );
  553. MultiByteToWideChar(CP_ACP,0,afp->szUserName,-1,wchDomainName,DNLEN+1);
  554. wcscat( wchUserName, wchDomainName );
  555. }
  556. else
  557. {
  558. MultiByteToWideChar(CP_ACP,0,afp->szUserName,-1,wchUserName,UNLEN+1);
  559. }
  560. }
  561. else if ( pDeviceObj->wchUserName[0] != (WCHAR)NULL )
  562. {
  563. if ( pDeviceObj->wchDomainName[0] != (WCHAR)NULL )
  564. {
  565. wcscpy( wchUserName, pDeviceObj->wchDomainName );
  566. wcscat( wchUserName, L"\\" );
  567. wcscat( wchUserName, pDeviceObj->wchUserName );
  568. }
  569. else
  570. {
  571. wcscpy( wchUserName, pDeviceObj->wchUserName );
  572. }
  573. }
  574. else
  575. {
  576. wcscpy( wchUserName, gblpszUnknown );
  577. }
  578. auditstrp[0] = pDeviceObj->wchPortName;
  579. auditstrp[1] = wchUserName;
  580. DDMLogErrorString(ROUTERLOG_PPP_FAILURE, 2, auditstrp, afp->dwError, 2);
  581. break;
  582. }
  583. }
  584. //***
  585. //
  586. // Function: SvPppCallbackRequest
  587. //
  588. // Description:
  589. //
  590. //***
  591. VOID
  592. SvPppCallbackRequest(
  593. IN PDEVICE_OBJECT pDeviceObj,
  594. IN PPPDDM_CALLBACK_REQUEST *cbrp
  595. )
  596. {
  597. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  598. "SvPppCallbackRequest: Entered, hPort = %d\n",pDeviceObj->hPort);
  599. //
  600. // check the state
  601. //
  602. if (pDeviceObj->DeviceState != DEV_OBJ_AUTH_IS_ACTIVE)
  603. {
  604. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM, "Auth not started" );
  605. return;
  606. }
  607. TimerQRemove( (HANDLE)pDeviceObj->hPort, SvAuthTimeout );
  608. //
  609. // copy relevant fields in our dcb
  610. //
  611. if (cbrp->fUseCallbackDelay)
  612. {
  613. pDeviceObj->dwCallbackDelay = cbrp->dwCallbackDelay;
  614. }
  615. else
  616. {
  617. pDeviceObj->dwCallbackDelay = gblDDMConfigInfo.dwCallbackTime;
  618. }
  619. MultiByteToWideChar( CP_ACP,
  620. 0,
  621. cbrp->szCallbackNumber,
  622. -1,
  623. pDeviceObj->wchCallbackNumber,
  624. MAX_PHONE_NUMBER_LEN + 1 );
  625. //
  626. // Disconnect the line and change the state
  627. //
  628. pDeviceObj->DeviceState = DEV_OBJ_CALLBACK_DISCONNECTING;
  629. //
  630. // Wait to enable the client to get the message
  631. //
  632. TimerQRemove( (HANDLE)pDeviceObj->hPort, SvDiscTimeout );
  633. TimerQInsert( (HANDLE)pDeviceObj->hPort,
  634. DISC_TIMEOUT_CALLBACK, SvDiscTimeout );
  635. }
  636. //***
  637. //
  638. // Function: SvPppDone
  639. //
  640. // Description: Activates all allocated bindings.
  641. //
  642. //***
  643. VOID
  644. SvPppDone(
  645. IN PDEVICE_OBJECT pDeviceObj,
  646. IN PPP_PROJECTION_RESULT *pProjectionResult
  647. )
  648. {
  649. LPWSTR lpstrAudit[3];
  650. DWORD dwRetCode;
  651. DWORD dwNumActivatedProjections = 0;
  652. ROUTER_INTERFACE_OBJECT * pIfObject;
  653. CONNECTION_OBJECT * pConnObj;
  654. WCHAR wchFullUserName[UNLEN+DNLEN+2];
  655. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  656. "SvPppDone: Entered, hPort=%d", pDeviceObj->hPort);
  657. //
  658. // If we are not authenicating and not been authenticated then we ignore
  659. // this message.
  660. //
  661. if ( ( pDeviceObj->DeviceState != DEV_OBJ_AUTH_IS_ACTIVE ) &&
  662. ( pDeviceObj->DeviceState != DEV_OBJ_ACTIVE ) )
  663. {
  664. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  665. "We are not authenicating and not been authenticated" );
  666. return;
  667. }
  668. //
  669. // Get pointer to connection object. If we cannot find it that means we
  670. // have gotten a PPP message for a device who's connection does not exist.
  671. // Simply ignore it.
  672. //
  673. if ( ( pConnObj = ConnObjGetPointer( pDeviceObj->hConnection ) ) == NULL )
  674. {
  675. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM, "No ConnObj" );
  676. return;
  677. }
  678. //
  679. // If we are getting a projection info structure again, we just update it
  680. // and return.
  681. //
  682. if ( pDeviceObj->DeviceState == DEV_OBJ_ACTIVE )
  683. {
  684. pConnObj->PppProjectionResult = *pProjectionResult;
  685. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  686. "Updated projection info structure" );
  687. return;
  688. }
  689. if ( pConnObj->wchDomainName[0] != TEXT('\0') )
  690. {
  691. wcscpy( wchFullUserName, pConnObj->wchDomainName );
  692. wcscat( wchFullUserName, TEXT("\\") );
  693. wcscat( wchFullUserName, pConnObj->wchUserName );
  694. }
  695. else
  696. {
  697. wcscpy( wchFullUserName, pConnObj->wchUserName );
  698. }
  699. lpstrAudit[0] = wchFullUserName;
  700. lpstrAudit[1] = pDeviceObj->wchPortName;
  701. //
  702. // If we have not yet been notifyied of projections for this connection.
  703. //
  704. if ( !(pConnObj->fFlags & CONN_OBJ_PROJECTIONS_NOTIFIED) )
  705. {
  706. if ( pProjectionResult->ip.dwError == NO_ERROR )
  707. {
  708. dwNumActivatedProjections++;
  709. }
  710. if ( pProjectionResult->ipx.dwError == NO_ERROR )
  711. {
  712. dwNumActivatedProjections++;
  713. }
  714. if ( pProjectionResult->at.dwError == NO_ERROR )
  715. {
  716. dwNumActivatedProjections++;
  717. }
  718. //
  719. // We couldn't activate any projection due to some error error log
  720. // and bring the link down
  721. //
  722. if ( dwNumActivatedProjections == 0 )
  723. {
  724. DDMLogError(ROUTERLOG_AUTH_NO_PROJECTIONS, 2, lpstrAudit, NO_ERROR);
  725. PppDdmStop( pDeviceObj->hPort, NO_ERROR );
  726. return;
  727. }
  728. else
  729. {
  730. //
  731. // Even though NBF was removed from the product, we can
  732. // still get the computer namefrom the nbf projection result
  733. // (PPP Engine dummied it in there).
  734. //
  735. // If the computer name ends with 0x03, that tells us
  736. // the messenger service is running on the remote computer.
  737. //
  738. pConnObj->fFlags &= ~CONN_OBJ_MESSENGER_PRESENT;
  739. pConnObj->bComputerName[0] = (CHAR)NULL;
  740. if ( pProjectionResult->nbf.wszWksta[0] != (WCHAR)NULL )
  741. {
  742. WideCharToMultiByte(
  743. CP_ACP,
  744. 0,
  745. pProjectionResult->nbf.wszWksta,
  746. -1,
  747. pConnObj->bComputerName,
  748. sizeof( pConnObj->bComputerName ),
  749. NULL,
  750. NULL );
  751. if (pConnObj->bComputerName[NCBNAMSZ-1] == (WCHAR) 0x03)
  752. {
  753. pConnObj->fFlags |= CONN_OBJ_MESSENGER_PRESENT;
  754. }
  755. pConnObj->bComputerName[NCBNAMSZ-1] = (WCHAR)NULL;
  756. }
  757. }
  758. //
  759. // Projections Activated OK
  760. //
  761. pConnObj->PppProjectionResult = *pProjectionResult;
  762. pConnObj->fFlags |= CONN_OBJ_PROJECTIONS_NOTIFIED;
  763. //
  764. // Set this interface to connected if it is not already connected
  765. //
  766. dwRetCode = IfObjectConnected(
  767. pConnObj->hDIMInterface,
  768. pConnObj->hConnection,
  769. &(pConnObj->PppProjectionResult) );
  770. //
  771. // If the interface does not exist anymore bring down this connection
  772. //
  773. if ( dwRetCode != NO_ERROR )
  774. {
  775. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  776. "Interface does not exist anymore" );
  777. PppDdmStop( pDeviceObj->hPort, NO_ERROR );
  778. ConnObjDisconnect( pConnObj );
  779. return;
  780. }
  781. GetSystemTimeAsFileTime( (FILETIME*)&(pConnObj->qwActiveTime) );
  782. if ( !AcceptNewConnection( pDeviceObj, pConnObj ) )
  783. {
  784. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  785. "ERROR_ACCESS_DENIED" );
  786. PppDdmStop( pDeviceObj->hPort, ERROR_ACCESS_DENIED );
  787. ConnObjDisconnect( pConnObj );
  788. return;
  789. }
  790. }
  791. if ( !AcceptNewLink( pDeviceObj, pConnObj ) )
  792. {
  793. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  794. "ERROR_ACCESS_DENIED" );
  795. PppDdmStop( pDeviceObj->hPort, ERROR_ACCESS_DENIED );
  796. return;
  797. }
  798. //
  799. // Reduce the media count for this device
  800. //
  801. if ( !(pDeviceObj->fFlags & DEV_OBJ_MARKED_AS_INUSE) )
  802. {
  803. if ( pDeviceObj->fFlags & DEV_OBJ_ALLOW_ROUTERS )
  804. {
  805. MediaObjRemoveFromTable( pDeviceObj->wchDeviceType );
  806. }
  807. pDeviceObj->fFlags |= DEV_OBJ_MARKED_AS_INUSE;
  808. gblDeviceTable.NumDevicesInUse++;
  809. //
  810. // Possibly need to notify the router managers of unreachability
  811. //
  812. EnterCriticalSection( &(gblpInterfaceTable->CriticalSection) );
  813. IfObjectNotifyAllOfReachabilityChange( FALSE,
  814. INTERFACE_OUT_OF_RESOURCES );
  815. LeaveCriticalSection( &(gblpInterfaceTable->CriticalSection) );
  816. }
  817. //
  818. // log authentication success, 18 is MSPPC
  819. //
  820. if ( ( pConnObj->PppProjectionResult.ccp.dwSendProtocol == 18 ) &&
  821. ( pConnObj->PppProjectionResult.ccp.dwReceiveProtocol == 18 ) )
  822. {
  823. if ( ( pConnObj->PppProjectionResult.ccp.dwReceiveProtocolData &
  824. ( MSTYPE_ENCRYPTION_40 |
  825. MSTYPE_ENCRYPTION_40F |
  826. MSTYPE_ENCRYPTION_56 |
  827. MSTYPE_ENCRYPTION_128 ) ) &&
  828. ( pConnObj->PppProjectionResult.ccp.dwSendProtocolData &
  829. ( MSTYPE_ENCRYPTION_40 |
  830. MSTYPE_ENCRYPTION_40F |
  831. MSTYPE_ENCRYPTION_56 |
  832. MSTYPE_ENCRYPTION_128 ) ) )
  833. {
  834. if ( ( pConnObj->PppProjectionResult.ccp.dwSendProtocolData &
  835. MSTYPE_ENCRYPTION_128 ) &&
  836. ( pConnObj->PppProjectionResult.ccp.dwReceiveProtocolData &
  837. MSTYPE_ENCRYPTION_128 ) )
  838. {
  839. DDMLogInformation(ROUTERLOG_AUTH_SUCCESS_STRONG_ENCRYPTION,2,
  840. lpstrAudit);
  841. }
  842. else
  843. {
  844. DDMLogInformation(ROUTERLOG_AUTH_SUCCESS_ENCRYPTION,2,
  845. lpstrAudit);
  846. }
  847. }
  848. else
  849. {
  850. DDMLogInformation( ROUTERLOG_AUTH_SUCCESS, 2, lpstrAudit );
  851. }
  852. if(pProjectionResult->ip.dwError == ERROR_SUCCESS)
  853. {
  854. WCHAR *pszIpAddress =
  855. GetIpAddress(pProjectionResult->ip.dwRemoteAddress);
  856. if(NULL != pszIpAddress)
  857. {
  858. lpstrAudit[2] = pszIpAddress;
  859. DDMLogInformation(ROUTERLOG_IP_USER_CONNECTED, 3, lpstrAudit);
  860. LocalFree(pszIpAddress);
  861. }
  862. }
  863. }
  864. else
  865. {
  866. DDMLogInformation( ROUTERLOG_AUTH_SUCCESS, 2, lpstrAudit );
  867. if(pProjectionResult->ip.dwError == ERROR_SUCCESS)
  868. {
  869. WCHAR *pszIpAddress = GetIpAddress(
  870. pProjectionResult->ip.dwRemoteAddress);
  871. if(NULL != pszIpAddress)
  872. {
  873. lpstrAudit[2] = pszIpAddress;
  874. DDMLogInformation(ROUTERLOG_IP_USER_CONNECTED, 3, lpstrAudit);
  875. LocalFree(pszIpAddress);
  876. }
  877. }
  878. }
  879. //
  880. // and finaly go to ACTIVE state
  881. //
  882. pDeviceObj->DeviceState = DEV_OBJ_ACTIVE;
  883. pDeviceObj->dwTotalNumberOfCalls++;
  884. pDeviceObj->fFlags |= DEV_OBJ_PPP_IS_ACTIVE;
  885. //
  886. // and initialize the active time
  887. //
  888. GetSystemTimeAsFileTime( (FILETIME*)&(pDeviceObj->qwActiveTime) );
  889. //
  890. // Was this a connection for a BAP callback?
  891. //
  892. if ( pDeviceObj->fFlags & DEV_OBJ_BAP_CALLBACK )
  893. {
  894. PppDdmBapCallbackResult( pDeviceObj->hBapConnection, NO_ERROR );
  895. pDeviceObj->fFlags &= ~DEV_OBJ_BAP_CALLBACK;
  896. }
  897. return;
  898. }
  899. //**
  900. //
  901. // Call: SvAddLinkToConnection
  902. //
  903. // Returns: NO_ERROR - Success
  904. // Non-zero returns - Failure
  905. //
  906. // Description: Called to actually add a new link that BAP has brought up.
  907. //
  908. VOID
  909. SvAddLinkToConnection(
  910. IN PDEVICE_OBJECT pDeviceObj,
  911. IN HRASCONN hRasConn
  912. )
  913. {
  914. CONNECTION_OBJECT * pConnObj;
  915. DWORD dwRetCode;
  916. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  917. "SvAddLinkToConnection: Entered, hPort=%d", pDeviceObj->hPort );
  918. //
  919. // Set this port to be notified by rasapi32 on disconnect.
  920. //
  921. dwRetCode = RasConnectionNotification(
  922. hRasConn,
  923. gblSupervisorEvents[NUM_DDM_EVENTS
  924. + (gblDeviceTable.NumDeviceBuckets*2)
  925. + DeviceObjHashPortToBucket(pDeviceObj->hPort)],
  926. RASCN_Disconnection );
  927. if ( dwRetCode != NO_ERROR )
  928. {
  929. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  930. "RasConnectionNotification failed: %d", dwRetCode );
  931. return;
  932. }
  933. //
  934. // Get the HCONN bundle handle for this port
  935. //
  936. if ( RasPortGetBundle( NULL,
  937. pDeviceObj->hPort,
  938. &(pDeviceObj->hConnection) ) )
  939. {
  940. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  941. "RasPortGetBundle failed" );
  942. return;
  943. }
  944. if ( ( pConnObj = ConnObjGetPointer( pDeviceObj->hConnection ) ) == NULL )
  945. {
  946. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM, "No ConnObj" );
  947. return;
  948. }
  949. if ( ( dwRetCode = ConnObjAddLink( pConnObj, pDeviceObj ) ) != NO_ERROR )
  950. {
  951. DDMLogError( ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, dwRetCode );
  952. return;
  953. }
  954. //
  955. // Reduce the media count for this device
  956. //
  957. if ( !(pDeviceObj->fFlags & DEV_OBJ_MARKED_AS_INUSE) )
  958. {
  959. if ( pDeviceObj->fFlags & DEV_OBJ_ALLOW_ROUTERS )
  960. {
  961. MediaObjRemoveFromTable( pDeviceObj->wchDeviceType );
  962. }
  963. pDeviceObj->fFlags |= DEV_OBJ_MARKED_AS_INUSE;
  964. gblDeviceTable.NumDevicesInUse++;
  965. //
  966. // Possibly need to notify the router managers of unreachability
  967. //
  968. IfObjectNotifyAllOfReachabilityChange(FALSE,INTERFACE_OUT_OF_RESOURCES);
  969. }
  970. pDeviceObj->fFlags |= DEV_OBJ_OPENED_FOR_DIALOUT;
  971. pDeviceObj->hRasConn = hRasConn;
  972. if ( pConnObj->InterfaceType == ROUTER_IF_TYPE_FULL_ROUTER )
  973. {
  974. RasSetRouterUsage( pDeviceObj->hPort, TRUE );
  975. }
  976. }
  977. //**
  978. //
  979. // Call: SvDoBapCallbackRequest
  980. //
  981. // Returns: NO_ERROR - Success
  982. // Non-zero returns - Failure
  983. //
  984. // Description: Called by BAP to initiate a callback to the remote peer
  985. //
  986. VOID
  987. SvDoBapCallbackRequest(
  988. IN PDEVICE_OBJECT pDevObj,
  989. IN HCONN hConnection,
  990. IN CHAR * szCallbackNumber
  991. )
  992. {
  993. DWORD dwRetCode;
  994. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  995. "SvDoBapCallbackRequest: Entered, hPort=%d", pDevObj->hPort );
  996. //
  997. // Check to see if the device is available
  998. //
  999. if ( ( pDevObj->DeviceState != DEV_OBJ_LISTENING ) ||
  1000. ( pDevObj->fFlags & DEV_OBJ_OPENED_FOR_DIALOUT ) )
  1001. {
  1002. DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
  1003. "Device not available" );
  1004. PppDdmBapCallbackResult( hConnection, ERROR_PORT_NOT_AVAILABLE );
  1005. return;
  1006. }
  1007. pDevObj->fFlags |= DEV_OBJ_IS_PPP;
  1008. pDevObj->DeviceState = DEV_OBJ_CALLBACK_DISCONNECTING;
  1009. MultiByteToWideChar( CP_ACP,
  1010. 0,
  1011. szCallbackNumber,
  1012. -1,
  1013. pDevObj->wchCallbackNumber,
  1014. MAX_PHONE_NUMBER_LEN + 1 );
  1015. pDevObj->dwCallbackDelay = 10;
  1016. pDevObj->hBapConnection = hConnection;
  1017. pDevObj->fFlags |= DEV_OBJ_BAP_CALLBACK;
  1018. RmDisconnect( pDevObj );
  1019. }
  1020. //***
  1021. //
  1022. // Function: PppEventHandler
  1023. //
  1024. // Description: receives the ppp messages and invokes the apropriate
  1025. // procedures in fsm.
  1026. //
  1027. //***
  1028. VOID
  1029. PppEventHandler(
  1030. VOID
  1031. )
  1032. {
  1033. PPP_MESSAGE PppMsg;
  1034. PDEVICE_OBJECT pDevObj;
  1035. PCONNECTION_OBJECT pConnObj;
  1036. //
  1037. // loop to get all messages
  1038. //
  1039. while( ServerReceiveMessage( MESSAGEQ_ID_PPP, (BYTE *)&PppMsg) )
  1040. {
  1041. EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
  1042. if ( PppMsg.dwMsgId == PPPDDMMSG_PnPNotification )
  1043. {
  1044. //
  1045. // Port add/removal/change usage or protocol addition/removal
  1046. // notifications.
  1047. //
  1048. DWORD dwPnPEvent =
  1049. PppMsg.ExtraInfo.DdmPnPNotification.PnPNotification.dwEvent;
  1050. RASMAN_PORT * pRasmanPort =
  1051. &(PppMsg.ExtraInfo.DdmPnPNotification.PnPNotification.RasPort);
  1052. switch( dwPnPEvent )
  1053. {
  1054. case PNPNOTIFEVENT_CREATE:
  1055. if(pRasmanPort->P_ConfiguredUsage &
  1056. (CALL_IN | CALL_ROUTER | CALL_OUTBOUND_ROUTER))
  1057. {
  1058. DeviceObjAdd( pRasmanPort );
  1059. }
  1060. break;
  1061. case PNPNOTIFEVENT_REMOVE:
  1062. DeviceObjRemove( pRasmanPort );
  1063. break;
  1064. case PNPNOTIFEVENT_USAGE:
  1065. DeviceObjUsageChange( pRasmanPort );
  1066. break;
  1067. }
  1068. LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
  1069. continue;
  1070. }
  1071. else
  1072. {
  1073. //
  1074. // Otherwise identify the port for which this event is received.
  1075. //
  1076. if ( ( pDevObj = DeviceObjGetPointer( PppMsg.hPort ) ) == NULL )
  1077. {
  1078. RTASSERT( pDevObj != NULL );
  1079. LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
  1080. continue;
  1081. }
  1082. }
  1083. //
  1084. // action on the message type
  1085. //
  1086. switch( PppMsg.dwMsgId )
  1087. {
  1088. case PPPDDMMSG_BapCallbackRequest:
  1089. SvDoBapCallbackRequest(
  1090. pDevObj,
  1091. PppMsg.ExtraInfo.BapCallbackRequest.hConnection,
  1092. PppMsg.ExtraInfo.BapCallbackRequest.szCallbackNumber );
  1093. break;
  1094. case PPPDDMMSG_PppDone:
  1095. pDevObj->fFlags &= (~DEV_OBJ_AUTH_ACTIVE);
  1096. SvPppDone(pDevObj, &PppMsg.ExtraInfo.ProjectionResult);
  1097. break;
  1098. case PPPDDMMSG_CallbackRequest:
  1099. SvPppCallbackRequest(pDevObj,&PppMsg.ExtraInfo.CallbackRequest);
  1100. break;
  1101. case PPPDDMMSG_Authenticated:
  1102. SvPppUserOK(pDevObj, &PppMsg.ExtraInfo.AuthResult);
  1103. break;
  1104. case PPPDDMMSG_NewLink:
  1105. SvPppNewLinkOrBundle( pDevObj, FALSE, NULL );
  1106. break;
  1107. case PPPDDMMSG_NewBundle:
  1108. SvPppNewLinkOrBundle(
  1109. pDevObj,
  1110. TRUE,
  1111. PppMsg.ExtraInfo.DdmNewBundle.pClientInterface );
  1112. if ( PppMsg.ExtraInfo.DdmNewBundle.pClientInterface != NULL )
  1113. {
  1114. MprInfoDelete( PppMsg.ExtraInfo.DdmNewBundle.pClientInterface );
  1115. }
  1116. break;
  1117. case PPPDDMMSG_PppFailure:
  1118. pDevObj->fFlags &= (~DEV_OBJ_AUTH_ACTIVE);
  1119. switch( PppMsg.ExtraInfo.DdmFailure.dwError )
  1120. {
  1121. case NO_ERROR:
  1122. case ERROR_IDLE_DISCONNECTED:
  1123. case ERROR_PPP_SESSION_TIMEOUT:
  1124. break;
  1125. default:
  1126. SvPppFailure( pDevObj, &PppMsg.ExtraInfo.DdmFailure );
  1127. }
  1128. PppDdmStop( pDevObj->hPort, PppMsg.ExtraInfo.DdmFailure.dwError );
  1129. break;
  1130. case PPPDDMMSG_Stopped:
  1131. if ( ( pDevObj->DeviceState != DEV_OBJ_CLOSING ) &&
  1132. ( pDevObj->DeviceState != DEV_OBJ_LISTENING ) )
  1133. {
  1134. DevStartClosing( pDevObj );
  1135. }
  1136. break;
  1137. case PPPDDMMSG_PortCleanedUp:
  1138. if ( pDevObj->DeviceState != DEV_OBJ_LISTENING )
  1139. {
  1140. pDevObj->fFlags &= (~DEV_OBJ_PPP_IS_ACTIVE);
  1141. if ( pDevObj->DeviceState != DEV_OBJ_CLOSING )
  1142. {
  1143. DevStartClosing( pDevObj );
  1144. }
  1145. else
  1146. {
  1147. DevCloseComplete( pDevObj );
  1148. }
  1149. }
  1150. break;
  1151. case PPPDDMMSG_NewBapLinkUp:
  1152. SvAddLinkToConnection( pDevObj,
  1153. PppMsg.ExtraInfo.BapNewLinkUp.hRasConn );
  1154. break;
  1155. default:
  1156. RTASSERT(FALSE);
  1157. break;
  1158. }
  1159. LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
  1160. }
  1161. }