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.

3020 lines
82 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1989 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: worker.c
  7. //
  8. // Description: This module contains code for the worker thread.
  9. //
  10. // History:
  11. // Nov 11,1993. NarenG Created original version.
  12. // Jan 09,1995 RamC Close hToken in ProcessLineDownWorker()
  13. // routine to release the RAS license.
  14. //
  15. // Tab Stop = 8
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h> // needed for winbase.h
  19. #include <windows.h> // Win32 base API's
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <wchar.h>
  23. #include <ntlsapi.h>
  24. #include <lmcons.h>
  25. #include <mprlog.h>
  26. #include <raserror.h>
  27. #include <mprerror.h>
  28. #include <rasman.h>
  29. #include <rtutils.h>
  30. #include <rasppp.h>
  31. #include <pppcp.h>
  32. #include <ppp.h>
  33. #include <smaction.h>
  34. #include <smevents.h>
  35. #include <receive.h>
  36. #include <auth.h>
  37. #include <callback.h>
  38. #include <init.h>
  39. #include <lcp.h>
  40. #include <timer.h>
  41. #include <util.h>
  42. #include <worker.h>
  43. #include <bap.h>
  44. #include <rassrvr.h>
  45. #define INCL_RASAUTHATTRIBUTES
  46. #define INCL_PWUTIL
  47. #include <ppputil.h>
  48. //**
  49. //
  50. // Call: WorkerThread
  51. //
  52. // Returns: NO_ERROR
  53. //
  54. // Description: This thread will wait for an item in the WorkItemQ and then
  55. // will process it. This will happen in a never-ending loop.
  56. //
  57. #if _MSC_FULL_VER >= 13008827
  58. #pragma warning(push)
  59. #pragma warning(disable:4715) // Not all control paths return (due to infinite loop)
  60. #endif
  61. DWORD
  62. WorkerThread(
  63. IN LPVOID pThreadParameter
  64. )
  65. {
  66. PCB_WORK_ITEM * pWorkItem = (PCB_WORK_ITEM*)NULL;
  67. DWORD dwTimeToSleepFor = INFINITE;
  68. HINSTANCE hInstance;
  69. HANDLE hEvents[3];
  70. DWORD dwSignaledEvent;
  71. DWORD dwTimeBeforeWait;
  72. DWORD dwTimeElapsed;
  73. BOOL fTimerQEmpty = TRUE;
  74. hEvents[0] = WorkItemQ.hEventNonEmpty;
  75. hEvents[1] = TimerQ.hEventNonEmpty;
  76. hEvents[2] = PppConfigInfo.hEventChangeNotification;
  77. RegNotifyChangeKeyValue( PppConfigInfo.hKeyPpp,
  78. TRUE,
  79. REG_NOTIFY_CHANGE_LAST_SET,
  80. PppConfigInfo.hEventChangeNotification,
  81. TRUE );
  82. for(;;)
  83. {
  84. dwTimeBeforeWait = GetCurrentTime();
  85. //
  86. // Wait for work to do
  87. //
  88. dwSignaledEvent = WaitForMultipleObjectsEx(
  89. 3,
  90. hEvents,
  91. FALSE,
  92. dwTimeToSleepFor,
  93. TRUE );
  94. switch( dwSignaledEvent )
  95. {
  96. case 0:
  97. //
  98. // Take Mutex around work event Q
  99. //
  100. EnterCriticalSection( &(WorkItemQ.CriticalSection) );
  101. //
  102. // Remove the first item
  103. //
  104. PPP_ASSERT( WorkItemQ.pQHead != (PCB_WORK_ITEM*)NULL );
  105. pWorkItem = WorkItemQ.pQHead;
  106. WorkItemQ.pQHead = pWorkItem->pNext;
  107. if ( WorkItemQ.pQHead == (PCB_WORK_ITEM*)NULL )
  108. {
  109. ResetEvent( WorkItemQ.hEventNonEmpty );
  110. WorkItemQ.pQTail = (PCB_WORK_ITEM *)NULL;
  111. }
  112. LeaveCriticalSection( &(WorkItemQ.CriticalSection) );
  113. pWorkItem->Process( pWorkItem );
  114. //
  115. // Zero out work item since it may have contained the password
  116. //
  117. ZeroMemory( pWorkItem, sizeof( PCB_WORK_ITEM ) );
  118. LOCAL_FREE( pWorkItem );
  119. break;
  120. case WAIT_TIMEOUT:
  121. TimerTick( &fTimerQEmpty );
  122. dwTimeToSleepFor = fTimerQEmpty ? INFINITE : 1000;
  123. continue;
  124. case 1:
  125. fTimerQEmpty = FALSE;
  126. break;
  127. case 2:
  128. //
  129. // Process change notification event
  130. //
  131. ProcessChangeNotification( NULL );
  132. RegNotifyChangeKeyValue(
  133. PppConfigInfo.hKeyPpp,
  134. TRUE,
  135. REG_NOTIFY_CHANGE_LAST_SET,
  136. PppConfigInfo.hEventChangeNotification,
  137. TRUE );
  138. break;
  139. case WAIT_IO_COMPLETION:
  140. break;
  141. default:
  142. PPP_ASSERT( FALSE );
  143. }
  144. if ( !fTimerQEmpty )
  145. {
  146. if ( dwTimeToSleepFor == INFINITE )
  147. {
  148. dwTimeToSleepFor = 1000;
  149. }
  150. else
  151. {
  152. //
  153. // We did not get a timeout but do we need to call the timer?
  154. // Has over a second passed since we called the TimerQTick?
  155. //
  156. dwTimeElapsed =
  157. ( GetCurrentTime() >= dwTimeBeforeWait )
  158. ? GetCurrentTime() - dwTimeBeforeWait
  159. : GetCurrentTime() + (0xFFFFFFFF - dwTimeBeforeWait);
  160. if ( dwTimeElapsed >= dwTimeToSleepFor )
  161. {
  162. TimerTick( &fTimerQEmpty );
  163. dwTimeToSleepFor = fTimerQEmpty ? INFINITE : 1000;
  164. }
  165. else
  166. {
  167. dwTimeToSleepFor -= dwTimeElapsed;
  168. }
  169. }
  170. }
  171. }
  172. return( NO_ERROR );
  173. }
  174. #if _MSC_FULL_VER >= 13008827
  175. #pragma warning(pop)
  176. #endif
  177. //**
  178. //
  179. // Call: ProcessLineUpWorker
  180. //
  181. // Returns: None
  182. //
  183. // Description: Will do the actual processing of the line up event.
  184. //
  185. //
  186. VOID
  187. ProcessLineUpWorker(
  188. IN PCB_WORK_ITEM * pWorkItem,
  189. IN BOOL fThisIsACallback
  190. )
  191. {
  192. DWORD dwRetCode;
  193. DWORD dwLength;
  194. DWORD dwComputerNameLen;
  195. DWORD dwIndex;
  196. PCB * pNewPcb = NULL;
  197. RASMAN_INFO RasmanInfo;
  198. DWORD dwError;
  199. BOOL fSuccess = FALSE;
  200. do
  201. {
  202. PppLog( 1, "Line up event occurred on port %d", pWorkItem->hPort );
  203. pNewPcb = GetPCBPointerFromhPort( pWorkItem->hPort );
  204. if ( NULL == pNewPcb )
  205. {
  206. //
  207. // Allocate and initialize pNewPcb
  208. //
  209. pNewPcb = (PCB *)LOCAL_ALLOC( LPTR, sizeof( PCB ) );
  210. if ( pNewPcb == (PCB *)NULL )
  211. {
  212. //
  213. // Tell the owner of the port that we failed to open it.
  214. //
  215. NotifyCallerOfFailureOnPort(
  216. pWorkItem->hPort,
  217. pWorkItem->fServer,
  218. GetLastError() );
  219. break;
  220. }
  221. }
  222. else
  223. {
  224. if (!( pNewPcb->fFlags & PCBFLAG_PORT_IN_LISTENING_STATE ))
  225. {
  226. PppLog( 1, "Line up on port %d without a line down!",
  227. pWorkItem->hPort );
  228. return;
  229. }
  230. //
  231. // We will put it back in the table later
  232. //
  233. RemovePcbFromTable( pNewPcb );
  234. }
  235. if ( !pWorkItem->fServer )
  236. {
  237. if ( !(pWorkItem->PppMsg.Start.ConfigInfo.dwConfigMask &
  238. ( PPPCFG_ProjectNbf
  239. | PPPCFG_ProjectIp
  240. | PPPCFG_ProjectIpx
  241. | PPPCFG_ProjectAt ) ) )
  242. {
  243. NotifyCallerOfFailureOnPort( pWorkItem->hPort,
  244. pWorkItem->fServer,
  245. ERROR_PPP_NO_PROTOCOLS_CONFIGURED);
  246. break;
  247. }
  248. }
  249. //
  250. // Get Rasman info for this port. We need this to get the devicetype
  251. // and BAP
  252. //
  253. dwError = RasGetInfo( NULL, pWorkItem->hPort, &RasmanInfo );
  254. if ( NO_ERROR != dwError )
  255. {
  256. PppLog(1,"RasGetInfo failed and returned returned %d", dwError);
  257. break;
  258. }
  259. pNewPcb->pSendBuf = (PPP_PACKET*)NULL;
  260. pNewPcb->hPort = pWorkItem->hPort;
  261. pNewPcb->pNext = (PCB*)NULL;
  262. pNewPcb->UId = 0;
  263. pNewPcb->dwPortId = GetNewPortOrBundleId();
  264. pNewPcb->RestartTimer = CalculateRestartTimer( pWorkItem->hPort );
  265. pNewPcb->PppPhase = PPP_LCP;
  266. pNewPcb->fFlags |= pWorkItem->fServer ? PCBFLAG_IS_SERVER:0;
  267. pNewPcb->fFlags |= fThisIsACallback
  268. ? PCBFLAG_THIS_IS_A_CALLBACK
  269. : 0;
  270. pNewPcb->pUserAttributes = NULL;
  271. pNewPcb->pAuthenticatorAttributes = NULL;
  272. pNewPcb->pAuthProtocolAttributes = NULL;
  273. pNewPcb->pAccountingAttributes = NULL;
  274. pNewPcb->dwOutstandingAuthRequestId = 0xFFFFFFFF;
  275. pNewPcb->dwDeviceType = RasmanInfo.RI_rdtDeviceType;
  276. GetSystemTimeAsFileTime( (FILETIME*)&(pNewPcb->qwActiveTime) );
  277. if ( NULL == pNewPcb->pBcb )
  278. {
  279. if ( ( dwRetCode = AllocateAndInitBcb( pNewPcb ) ) != NO_ERROR )
  280. {
  281. NotifyCallerOfFailureOnPort(
  282. pWorkItem->hPort,
  283. pWorkItem->fServer,
  284. dwRetCode );
  285. break;
  286. }
  287. }
  288. dwRetCode = RasPortGetBundle(NULL,
  289. pNewPcb->hPort,
  290. &(pNewPcb->pBcb->hConnection) );
  291. if ( dwRetCode != NO_ERROR )
  292. {
  293. NotifyCallerOfFailureOnPort(
  294. pWorkItem->hPort,
  295. pWorkItem->fServer,
  296. dwRetCode );
  297. break;
  298. }
  299. pNewPcb->pBcb->fFlags |= pWorkItem->fServer ? BCBFLAG_IS_SERVER:0;
  300. pNewPcb->pBcb->szRemoteUserName[0] = (CHAR)NULL;
  301. pNewPcb->pBcb->szRemoteDomain[0] = (CHAR)NULL;
  302. pNewPcb->pBcb->szOldPassword[0] = '\0';
  303. if ( pNewPcb->fFlags & PCBFLAG_IS_SERVER )
  304. {
  305. pNewPcb->dwEapTypeToBeUsed = 0xFFFFFFFF;
  306. pNewPcb->fCallbackPrivilege = RASPRIV_NoCallback;
  307. pNewPcb->pBcb->hTokenImpersonateUser= INVALID_HANDLE_VALUE;
  308. pNewPcb->dwAuthRetries = ( fThisIsACallback )
  309. ? 0
  310. : pWorkItem->PppMsg.DdmStart.dwAuthRetries;
  311. if ( fThisIsACallback )
  312. {
  313. strcpy( pNewPcb->szCallbackNumber,
  314. pWorkItem->PppMsg.CallbackDone.szCallbackNumber );
  315. }
  316. else
  317. {
  318. strcpy( pNewPcb->szPortName,
  319. pWorkItem->PppMsg.DdmStart.szPortName );
  320. PppLog( 1, "PortName: %s", pNewPcb->szPortName );
  321. }
  322. ZeroMemory( &(pNewPcb->ConfigInfo), sizeof( pNewPcb->ConfigInfo ) );
  323. ZeroMemory( &(pNewPcb->Luid), sizeof( LUID ) );
  324. pNewPcb->pBcb->szComputerName[0] = (CHAR)NULL;
  325. pNewPcb->ConfigInfo = PppConfigInfo.ServerConfigInfo;
  326. pNewPcb->dwAutoDisconnectTime = 0;
  327. pNewPcb->pBcb->szLocalUserName[0] = (CHAR)NULL;
  328. pNewPcb->pBcb->szLocalDomain[0] = (CHAR)NULL;
  329. pNewPcb->pBcb->szPassword[0] = (CHAR)NULL;
  330. pNewPcb->pBcb->fFlags |= BCBFLAG_CAN_ACCEPT_CALLS;
  331. pNewPcb->pBcb->BapCb.szServerPhoneNumber =
  332. LocalAlloc( LPTR, sizeof(CHAR) * (RAS_MaxCallbackNumber + 1) );
  333. if ( NULL == pNewPcb->pBcb->BapCb.szServerPhoneNumber )
  334. {
  335. dwRetCode = GetLastError();
  336. NotifyCallerOfFailureOnPort(
  337. pWorkItem->hPort,
  338. TRUE,
  339. dwRetCode );
  340. break;
  341. }
  342. pNewPcb->pBcb->BapCb.szClientPhoneNumber =
  343. LocalAlloc( LPTR, sizeof(CHAR) * (RAS_MaxCallbackNumber + 1) );
  344. if ( NULL == pNewPcb->pBcb->BapCb.szClientPhoneNumber )
  345. {
  346. dwRetCode = GetLastError();
  347. NotifyCallerOfFailureOnPort(
  348. pWorkItem->hPort,
  349. TRUE,
  350. dwRetCode );
  351. break;
  352. }
  353. if ( GetCpIndexFromProtocol( PPP_BACP_PROTOCOL ) == (DWORD)-1 )
  354. {
  355. PppConfigInfo.ServerConfigInfo.dwConfigMask &=
  356. ~PPPCFG_NegotiateBacp;
  357. }
  358. if ( PppConfigInfo.ServerConfigInfo.dwConfigMask &
  359. PPPCFG_NegotiateBacp)
  360. {
  361. //
  362. // We won't check for successful return from this function.
  363. // If it fails, szServerPhoneNumber will remain an empty string.
  364. //
  365. FGetOurPhoneNumberFromHPort(
  366. pNewPcb->hPort,
  367. pNewPcb->pBcb->BapCb.szServerPhoneNumber);
  368. }
  369. pNewPcb->pUserAttributes = GetUserAttributes( pNewPcb );
  370. }
  371. else
  372. {
  373. DWORD cbPassword;
  374. PBYTE pbPassword = NULL;
  375. pNewPcb->dwEapTypeToBeUsed = pWorkItem->PppMsg.Start.dwEapTypeId;
  376. pNewPcb->pBcb->hTokenImpersonateUser =
  377. pWorkItem->PppMsg.Start.hToken;
  378. pNewPcb->pBcb->pCustomAuthConnData =
  379. pWorkItem->PppMsg.Start.pCustomAuthConnData;
  380. pNewPcb->pBcb->pCustomAuthUserData =
  381. pWorkItem->PppMsg.Start.pCustomAuthUserData;
  382. //
  383. // EapUIData.pEapUIData is allocated by rasman and freed by engine.
  384. // raseap.c must not free it.
  385. //
  386. pNewPcb->pBcb->EapUIData =
  387. pWorkItem->PppMsg.Start.EapUIData;
  388. if (pWorkItem->PppMsg.Start.fLogon)
  389. {
  390. pNewPcb->pBcb->fFlags |= BCBFLAG_LOGON_USER_DATA;
  391. }
  392. if (pWorkItem->PppMsg.Start.fNonInteractive)
  393. {
  394. pNewPcb->fFlags |= PCBFLAG_NON_INTERACTIVE;
  395. }
  396. if (pWorkItem->PppMsg.Start.dwFlags & PPPFLAGS_DisableNetbt)
  397. {
  398. pNewPcb->fFlags |= PCBFLAG_DISABLE_NETBT;
  399. }
  400. //
  401. // We do this to get the sub entry index, which is required by BAP.
  402. // If this function fails, BAP will think that the sub entry is not
  403. // connected. BAP will not work correctly, but nothing very bad will
  404. // happen.
  405. //
  406. pNewPcb->dwSubEntryIndex = RasmanInfo.RI_SubEntry;
  407. pNewPcb->dwAuthRetries = 0;
  408. strcpy( pNewPcb->pBcb->szLocalUserName,
  409. pWorkItem->PppMsg.Start.szUserName );
  410. // DecodePw( pWorkItem->PppMsg.Start.chSeed, pWorkItem->PppMsg.Start.szPassword );
  411. // strcpy( pNewPcb->pBcb->szPassword,
  412. // pWorkItem->PppMsg.Start.szPassword );
  413. CopyMemory(&pNewPcb->pBcb->DBPassword,
  414. &pWorkItem->PppMsg.Start.DBPassword,
  415. sizeof(DATA_BLOB));
  416. ZeroMemory(&pWorkItem->PppMsg.Start.DBPassword,
  417. sizeof(DATA_BLOB));
  418. // EncodePw( pWorkItem->PppMsg.Start.chSeed, pWorkItem->PppMsg.Start.szPassword );
  419. // EncodePw( pNewPcb->pBcb->chSeed, pNewPcb->pBcb->szPassword );
  420. strcpy( pNewPcb->pBcb->szLocalDomain,
  421. pWorkItem->PppMsg.Start.szDomain );
  422. pNewPcb->Luid = pWorkItem->PppMsg.Start.Luid;
  423. pNewPcb->ConfigInfo = pWorkItem->PppMsg.Start.ConfigInfo;
  424. pNewPcb->dwAutoDisconnectTime
  425. = pWorkItem->PppMsg.Start.dwAutoDisconnectTime;
  426. //Set the LCPEchoTimeout here
  427. pNewPcb->dwLCPEchoTimeInterval = PppConfigInfo.dwLCPEchoTimeInterval; //Time interval between LCP echos
  428. pNewPcb->dwIdleBeforeEcho = PppConfigInfo.dwIdleBeforeEcho; //Idle time before the LCP echo begins
  429. pNewPcb->dwNumMissedEchosBeforeDisconnect = PppConfigInfo.dwNumMissedEchosBeforeDisconnect; //Num missed echos before disconnect
  430. CopyMemory( pNewPcb->pBcb->InterfaceInfo.szzParameters,
  431. pWorkItem->PppMsg.Start.szzParameters,
  432. sizeof( pNewPcb->pBcb->InterfaceInfo.szzParameters ));
  433. GetLocalComputerName( pNewPcb->pBcb->szComputerName );
  434. strcpy( pNewPcb->szPortName, pWorkItem->PppMsg.Start.szPortName );
  435. PppLog(1,"PortName: %s", pNewPcb->szPortName);
  436. PPP_ASSERT( NULL == pNewPcb->pBcb->szPhonebookPath );
  437. PPP_ASSERT( NULL == pNewPcb->pBcb->szEntryName );
  438. PPP_ASSERT( NULL == pNewPcb->pBcb->BapCb.szServerPhoneNumber );
  439. pNewPcb->pBcb->szPhonebookPath
  440. = pWorkItem->PppMsg.Start.pszPhonebookPath;
  441. pNewPcb->pBcb->szEntryName = pWorkItem->PppMsg.Start.pszEntryName;
  442. //
  443. // pszPhoneNumber will have the originally dialed number, even if
  444. // this is a callback.
  445. //
  446. pNewPcb->pBcb->BapCb.szServerPhoneNumber
  447. = pWorkItem->PppMsg.Start.pszPhoneNumber;
  448. RemoveNonNumerals(pNewPcb->pBcb->BapCb.szServerPhoneNumber);
  449. pNewPcb->pBcb->BapParams = pWorkItem->PppMsg.Start.BapParams;
  450. pNewPcb->pBcb->fFlags |= BCBFLAG_CAN_ACCEPT_CALLS;
  451. pNewPcb->pBcb->fFlags |= BCBFLAG_CAN_CALL;
  452. if ( pNewPcb->ConfigInfo.dwConfigMask & PPPCFG_NoCallback )
  453. {
  454. pNewPcb->pBcb->fFlags &= ~BCBFLAG_CAN_ACCEPT_CALLS;
  455. }
  456. if ( pWorkItem->PppMsg.Start.PppInterfaceInfo.IfType == (DWORD)-1 )
  457. {
  458. pNewPcb->pBcb->InterfaceInfo.IfType = (DWORD)-1;
  459. pNewPcb->pBcb->InterfaceInfo.hIPInterface= INVALID_HANDLE_VALUE;
  460. pNewPcb->pBcb->InterfaceInfo.hIPXInterface
  461. = INVALID_HANDLE_VALUE;
  462. }
  463. else
  464. {
  465. pNewPcb->pBcb->InterfaceInfo =
  466. pWorkItem->PppMsg.Start.PppInterfaceInfo;
  467. //
  468. // If we are a router dialing out and fRedialOnLinkFailure is
  469. // set that means that we are a persistent interface so set
  470. // Idle-Disconnect time to 0.
  471. //
  472. if ( pNewPcb->pBcb->InterfaceInfo.IfType
  473. == ROUTER_IF_TYPE_FULL_ROUTER )
  474. {
  475. if ( pWorkItem->PppMsg.Start.fRedialOnLinkFailure )
  476. {
  477. pNewPcb->dwAutoDisconnectTime = 0;
  478. }
  479. lstrcpy( pNewPcb->pBcb->szRemoteUserName,
  480. pNewPcb->pBcb->szEntryName );
  481. if (pNewPcb->ConfigInfo.dwConfigMask &
  482. PPPCFG_AuthenticatePeer)
  483. {
  484. pNewPcb->pUserAttributes = GetUserAttributes( pNewPcb );
  485. }
  486. }
  487. }
  488. if ( pNewPcb->pBcb->InterfaceInfo.IfType
  489. != ROUTER_IF_TYPE_FULL_ROUTER )
  490. {
  491. //
  492. // We want HKEY_CURRENT_USER to represent the logged on user,
  493. // not the service.
  494. //
  495. // What about the asynchronous RasDial case? Is it
  496. // possible that the process represented by dwPid is now gone?
  497. // Will it help if you use ImpersonateLoggedOnUser() to get
  498. // callback numbers?
  499. pNewPcb->pBcb->szTextualSid =
  500. TextualSidFromPid( pWorkItem->PppMsg.Start.dwPid );
  501. }
  502. if ( GetCpIndexFromProtocol( PPP_BACP_PROTOCOL ) == (DWORD)-1 )
  503. {
  504. pNewPcb->ConfigInfo.dwConfigMask &= ~PPPCFG_NegotiateBacp;
  505. }
  506. }
  507. PppLog( 2, "Starting PPP on link with IfType=0x%x,IPIf=0x%x,IPXIf=0x%x",
  508. pNewPcb->pBcb->InterfaceInfo.IfType,
  509. pNewPcb->pBcb->InterfaceInfo.hIPInterface,
  510. pNewPcb->pBcb->InterfaceInfo.hIPXInterface );
  511. //
  512. // Allocate bundle block for this port
  513. //
  514. dwLength = LCP_DEFAULT_MRU;
  515. dwRetCode = RasGetBuffer((CHAR**)&(pNewPcb->pSendBuf), &dwLength );
  516. if ( dwRetCode != NO_ERROR )
  517. {
  518. NotifyCallerOfFailure( pNewPcb, dwRetCode );
  519. break;
  520. }
  521. PppLog( 2, "RasGetBuffer returned %x for SendBuf", pNewPcb->pSendBuf);
  522. //
  523. // Initialize LCP and all the NCPs
  524. //
  525. pNewPcb->LcpCb.fConfigurable = TRUE;
  526. if ( !( FsmInit( pNewPcb, LCP_INDEX ) ) )
  527. {
  528. NotifyCallerOfFailure( pNewPcb, pNewPcb->LcpCb.dwError );
  529. break;
  530. }
  531. //
  532. // Ask RasMan to do RasPortReceive
  533. //
  534. dwRetCode = RasPppStarted( pNewPcb->hPort );
  535. if ( dwRetCode != NO_ERROR )
  536. {
  537. NotifyCallerOfFailure( pNewPcb, dwRetCode );
  538. break;
  539. }
  540. fSuccess = TRUE;
  541. //
  542. // Insert NewPcb into PCB hash table
  543. //
  544. dwIndex = HashPortToBucket( pWorkItem->hPort );
  545. PppLog( 2, "Inserting port in bucket # %d", dwIndex );
  546. pNewPcb->pNext = PcbTable.PcbBuckets[dwIndex].pPorts;
  547. PcbTable.PcbBuckets[dwIndex].pPorts = pNewPcb;
  548. //
  549. // Insert NewPcb's BCB into BCB hash table
  550. //
  551. dwIndex = HashPortToBucket( pNewPcb->pBcb->hConnection );
  552. PppLog( 2, "Inserting bundle in bucket # %d", dwIndex );
  553. pNewPcb->pBcb->pNext = PcbTable.BcbBuckets[dwIndex].pBundles;
  554. PcbTable.BcbBuckets[dwIndex].pBundles = pNewPcb->pBcb;
  555. //
  556. // Initialize the error as no response. If and when the first
  557. // REQ/ACK/NAK/REJ comes in we reset this to NO_ERROR
  558. //
  559. pNewPcb->LcpCb.dwError = ERROR_PPP_NO_RESPONSE;
  560. //
  561. // Start the LCP state machine.
  562. //
  563. FsmOpen( pNewPcb, LCP_INDEX );
  564. FsmUp( pNewPcb, LCP_INDEX );
  565. //
  566. // Start NegotiateTimer.
  567. //
  568. if ( PppConfigInfo.NegotiateTime > 0 )
  569. {
  570. InsertInTimerQ( pNewPcb->dwPortId,
  571. pNewPcb->hPort,
  572. 0,
  573. 0,
  574. FALSE,
  575. TIMER_EVENT_NEGOTIATETIME,
  576. PppConfigInfo.NegotiateTime );
  577. }
  578. //
  579. // If this is the server and this is not a callback line up, then we
  580. // receive the first frame in the call
  581. //
  582. if ( ( pNewPcb->fFlags & PCBFLAG_IS_SERVER ) && ( !fThisIsACallback ) )
  583. {
  584. PPP_PACKET * pPacket;
  585. if ( pNewPcb->LcpCb.dwError == ERROR_PPP_NO_RESPONSE )
  586. {
  587. pNewPcb->LcpCb.dwError = NO_ERROR;
  588. }
  589. //
  590. // Skip over the frame header and check if this is an LCP packet
  591. //
  592. pPacket=(PPP_PACKET*)(pWorkItem->PppMsg.DdmStart.achFirstFrame+12);
  593. if ( WireToHostFormat16( pPacket->Protocol ) == PPP_LCP_PROTOCOL )
  594. {
  595. ReceiveViaParser(
  596. pNewPcb,
  597. pPacket,
  598. pWorkItem->PppMsg.DdmStart.cbFirstFrame - 12 );
  599. }
  600. }
  601. }
  602. while ( FALSE );
  603. if ( !fSuccess )
  604. {
  605. if ( !pWorkItem->fServer )
  606. {
  607. if ( INVALID_HANDLE_VALUE != pWorkItem->PppMsg.Start.hToken )
  608. {
  609. CloseHandle( pWorkItem->PppMsg.Start.hToken );
  610. }
  611. LocalFree( pWorkItem->PppMsg.Start.pCustomAuthConnData );
  612. LocalFree( pWorkItem->PppMsg.Start.pCustomAuthUserData );
  613. LocalFree( pWorkItem->PppMsg.Start.EapUIData.pEapUIData );
  614. LocalFree( pWorkItem->PppMsg.Start.pszPhonebookPath );
  615. LocalFree( pWorkItem->PppMsg.Start.pszEntryName );
  616. LocalFree( pWorkItem->PppMsg.Start.pszPhoneNumber );
  617. if ( ( NULL != pNewPcb )
  618. && ( NULL != pNewPcb->pBcb ) )
  619. {
  620. //
  621. // Do not LocalFree or CloseHandle twice
  622. //
  623. pNewPcb->pBcb->hTokenImpersonateUser = INVALID_HANDLE_VALUE;
  624. pNewPcb->pBcb->pCustomAuthConnData = NULL;
  625. pNewPcb->pBcb->pCustomAuthUserData = NULL;
  626. pNewPcb->pBcb->EapUIData.pEapUIData = NULL;
  627. pNewPcb->pBcb->szPhonebookPath = NULL;
  628. pNewPcb->pBcb->szEntryName = NULL;
  629. pNewPcb->pBcb->BapCb.szServerPhoneNumber = NULL;
  630. }
  631. }
  632. if ( NULL != pNewPcb )
  633. {
  634. DeallocateAndRemoveBcbFromTable( pNewPcb->pBcb );
  635. if ( NULL != pNewPcb->pSendBuf )
  636. {
  637. RasFreeBuffer( (CHAR*)(pNewPcb->pSendBuf) );
  638. }
  639. LOCAL_FREE( pNewPcb );
  640. }
  641. }
  642. }
  643. //**
  644. //
  645. // Call: ProcessLineUp
  646. //
  647. // Returns: None
  648. //
  649. // Description: Called to process a line up event.
  650. //
  651. VOID
  652. ProcessLineUp(
  653. IN PCB_WORK_ITEM * pWorkItem
  654. )
  655. {
  656. ProcessLineUpWorker( pWorkItem,
  657. ( pWorkItem->fServer )
  658. ? FALSE
  659. : pWorkItem->PppMsg.Start.fThisIsACallback );
  660. }
  661. //**
  662. //
  663. // Call: ProcessPostLineDown
  664. //
  665. // Returns: None.
  666. //
  667. // Description: Handles Post Line Down cleanup only in the case accounting is setup.
  668. // see Whistler BUG:174822
  669. //
  670. VOID
  671. ProcessPostLineDown(
  672. IN PCB_WORK_ITEM * pWorkItem
  673. )
  674. {
  675. //This function will be always called as a result of
  676. //postlinedown message. So get the pcb from the work item directly.
  677. PCB * pPcb = (PCB *)pWorkItem->PppMsg.PostLineDown.pPcb;
  678. if ( pPcb == (PCB*)NULL )
  679. {
  680. PppLog( 1, "PostLineDown: PCB not found in post line down! Port = %d", pWorkItem->hPort );
  681. return;
  682. }
  683. PostLineDownWorker(pPcb);
  684. }
  685. VOID
  686. PostLineDownWorker(
  687. PCB * pPcb
  688. )
  689. {
  690. PppLog( 1, "Post line down event occurred on port %d", pPcb->hPort );
  691. if ( !( pPcb->fFlags & PCBFLAG_DOING_CALLBACK ) )
  692. {
  693. NotifyCaller( pPcb, PPPDDMMSG_PortCleanedUp, NULL );
  694. }
  695. else
  696. {
  697. if ( !(pPcb->fFlags & PCBFLAG_IS_SERVER ) )
  698. {
  699. //
  700. // If we get here and this flag is sent then we have not sent
  701. // the callback message to the client, hence we send it now.
  702. //
  703. NotifyCaller( pPcb, PPPMSG_Callback, NULL );
  704. }
  705. }
  706. if ( !(pPcb->fFlags & PCBFLAG_IS_SERVER )
  707. && !(pPcb->fFlags & PCBFLAG_STOPPED_MSG_SENT) )
  708. {
  709. DWORD dwError = 0;
  710. NotifyCaller( pPcb, PPPMSG_Stopped, &dwError );
  711. }
  712. if ( pPcb->fFlags & PCBFLAG_PORT_IN_LISTENING_STATE )
  713. {
  714. //
  715. // This flag is set in FListenForCall in bap.c
  716. //
  717. NotifyCallerOfFailure( pPcb, NO_ERROR );
  718. }
  719. LOCAL_FREE( pPcb );
  720. }
  721. //**
  722. //
  723. // Call: ProcessLineDownWorker
  724. //
  725. // Returns: None.
  726. //
  727. // Description: Handles a line down event. Will remove and deallocate all
  728. // resources associated with the port control block.
  729. //
  730. VOID
  731. ProcessLineDownWorker(
  732. IN PCB_WORK_ITEM * pWorkItem,
  733. BOOL * pfFinalStage
  734. )
  735. {
  736. DWORD dwIndex = HashPortToBucket( pWorkItem->hPort );
  737. PCB * pPcb = GetPCBPointerFromhPort( pWorkItem->hPort );
  738. LCPCB * pLcpCb;
  739. DWORD dwForIndex;
  740. DWORD dwErr;
  741. *pfFinalStage = TRUE;
  742. PppLog( 1, "Line down event occurred on port %d", pWorkItem->hPort );
  743. //
  744. // If the port is already deleted then simply return.
  745. //
  746. if ( pPcb == (PCB*)NULL )
  747. {
  748. PppLog( 1, "PCB not found for port %d!", pWorkItem->hPort );
  749. *pfFinalStage = FALSE;
  750. return;
  751. }
  752. //
  753. // pPcb->pBcb may be NULL if the pPcb was allocated in FListenForCall and it
  754. // did not go thru ProcessLineUpWorker or ProcessRasPortListenEvent,
  755. // which is impossible. I have seen this happen once, when before the
  756. // server had a chance to call back, I hung up the connection, and
  757. // ProcessStopPPP sent a line down to all ports.
  758. //
  759. if ( pPcb->pBcb == (BCB*)NULL )
  760. {
  761. RemovePcbFromTable( pPcb );
  762. NotifyCaller( pPcb, PPPDDMMSG_PortCleanedUp, NULL );
  763. *pfFinalStage = FALSE;
  764. return;
  765. }
  766. //
  767. // Remove PCB from table
  768. // Important Note: Not removing this at this point in time can cause
  769. // a lot of grief!
  770. RemovePcbFromTable( pPcb );
  771. //
  772. // Cancel outstanding receive
  773. //
  774. RasPortCancelReceive( pPcb->hPort );
  775. FsmDown( pPcb, LCP_INDEX );
  776. //
  777. // Remove Auto-Disconnect and high level timer event from the timer Q
  778. //
  779. RemoveFromTimerQ( pPcb->dwPortId,
  780. 0,
  781. 0,
  782. FALSE,
  783. TIMER_EVENT_NEGOTIATETIME );
  784. RemoveFromTimerQ( pPcb->dwPortId,
  785. 0,
  786. 0,
  787. FALSE,
  788. TIMER_EVENT_LCP_ECHO );
  789. RemoveFromTimerQ( pPcb->dwPortId,
  790. 0,
  791. 0,
  792. FALSE,
  793. TIMER_EVENT_HANGUP
  794. );
  795. RemoveFromTimerQ( pPcb->dwPortId,
  796. 0,
  797. 0,
  798. FALSE,
  799. TIMER_EVENT_AUTODISCONNECT
  800. );
  801. if ( pPcb->fFlags & PCBFLAG_IS_SERVER )
  802. {
  803. RemoveFromTimerQ( pPcb->dwPortId,
  804. 0,
  805. 0,
  806. FALSE,
  807. TIMER_EVENT_SESSION_TIMEOUT );
  808. }
  809. //
  810. // Make stop accounting call. Need to make this call before unbundling
  811. // because we need to send some mulitlink information.
  812. //
  813. if ( pPcb->pAccountingAttributes != NULL )
  814. {
  815. RemoveFromTimerQ( pPcb->dwPortId,
  816. 0,
  817. 0,
  818. FALSE,
  819. TIMER_EVENT_INTERIM_ACCOUNTING );
  820. MakeStopOrInterimAccountingCall( pPcb, FALSE );
  821. }
  822. if ( pPcb->fFlags & PCBFLAG_CONNECTION_LOGGED )
  823. {
  824. LPSTR lpsSubStringArray[5];
  825. lpsSubStringArray[0] = pPcb->pBcb->szEntryName;
  826. lpsSubStringArray[1] = pPcb->pBcb->szLocalUserName;
  827. lpsSubStringArray[2] = pPcb->szPortName;
  828. PppLogInformation(ROUTERLOG_DISCONNECTION_OCCURRED,3,lpsSubStringArray);
  829. }
  830. //
  831. // Close all CPs if this is the last port in the bundle if it is bundled,
  832. // or if it was not bundled.
  833. //
  834. if ( ( ( pPcb->fFlags & PCBFLAG_IS_BUNDLED ) &&
  835. ( pPcb->pBcb->dwLinkCount == 1 ) )
  836. ||
  837. ( !(pPcb->fFlags & PCBFLAG_IS_BUNDLED) ) )
  838. {
  839. for(dwIndex=LCP_INDEX+1;dwIndex<PppConfigInfo.NumberOfCPs;dwIndex++)
  840. {
  841. CPCB * pCpCb = GetPointerToCPCB( pPcb, dwIndex );
  842. if ( ( NULL != pCpCb )
  843. && ( pCpCb->fBeginCalled == TRUE ) )
  844. {
  845. if ( pCpCb->pWorkBuf != NULL )
  846. {
  847. (CpTable[dwIndex].CpInfo.RasCpEnd)( pCpCb->pWorkBuf );
  848. pCpCb->pWorkBuf = NULL;
  849. }
  850. pCpCb->fBeginCalled = FALSE;
  851. }
  852. }
  853. if ( pPcb->pBcb != NULL )
  854. {
  855. //
  856. // Take care of the RAS server policy on workstation
  857. //
  858. if ( pPcb->pBcb->fFlags & BCBFLAG_WKSTA_IN )
  859. {
  860. if ( pPcb->dwDeviceType & RDT_Tunnel )
  861. {
  862. PppConfigInfo.fFlags &= ~PPPCONFIG_FLAG_TUNNEL;
  863. }
  864. else if ( pPcb->dwDeviceType & RDT_Direct )
  865. {
  866. PppConfigInfo.fFlags &= ~PPPCONFIG_FLAG_DIRECT;
  867. }
  868. else
  869. {
  870. PppConfigInfo.fFlags &= ~PPPCONFIG_FLAG_DIALUP;
  871. }
  872. }
  873. DeallocateAndRemoveBcbFromTable( pPcb->pBcb );
  874. }
  875. }
  876. else if ( ( pPcb->fFlags & PCBFLAG_IS_BUNDLED ) &&
  877. ( pPcb->pBcb->dwLinkCount > 1 ) )
  878. {
  879. if ( pPcb->pBcb->fFlags & BCBFLAG_CAN_DO_BAP )
  880. {
  881. //
  882. // Reset the start time for the sample period. Now that the
  883. // bandwidth has changed, ndiswan shouldn't ask us to bring
  884. // links up or down based on what happened in the past.
  885. //
  886. BapSetPolicy( pPcb->pBcb );
  887. }
  888. pPcb->pBcb->dwLinkCount--;
  889. for ( dwForIndex = 0;
  890. dwForIndex < pPcb->pBcb->dwPpcbArraySize;
  891. dwForIndex++)
  892. {
  893. if ( pPcb->pBcb->ppPcb[dwForIndex] == pPcb )
  894. {
  895. pPcb->pBcb->ppPcb[dwForIndex] = NULL;
  896. break;
  897. }
  898. }
  899. if ( dwForIndex == pPcb->pBcb->dwPpcbArraySize )
  900. {
  901. PppLog( 1, "There is no back pointer to this PCB!!");
  902. }
  903. }
  904. //
  905. // Close the Aps.
  906. //
  907. pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  908. if ( pLcpCb != NULL)
  909. {
  910. dwIndex = GetCpIndexFromProtocol( pLcpCb->Local.Work.AP );
  911. if ( dwIndex != (DWORD)-1 )
  912. {
  913. ApStop( pPcb, dwIndex, TRUE );
  914. }
  915. dwIndex = GetCpIndexFromProtocol( pLcpCb->Remote.Work.AP );
  916. if ( dwIndex != (DWORD)-1 )
  917. {
  918. ApStop( pPcb, dwIndex, FALSE );
  919. }
  920. //
  921. // Close CBCP
  922. //
  923. dwIndex = GetCpIndexFromProtocol( PPP_CBCP_PROTOCOL );
  924. if ( dwIndex != (DWORD)-1 )
  925. {
  926. CbStop( pPcb, dwIndex );
  927. }
  928. //
  929. // Close LCP
  930. //
  931. (CpTable[LCP_INDEX].CpInfo.RasCpEnd)(pPcb->LcpCb.pWorkBuf);
  932. pPcb->LcpCb.pWorkBuf = NULL;
  933. }
  934. if ( pPcb->pSendBuf != (PPP_PACKET*)NULL )
  935. {
  936. RasFreeBuffer( (CHAR*)(pPcb->pSendBuf) );
  937. }
  938. if ( pPcb->pUserAttributes != NULL )
  939. {
  940. RasAuthAttributeDestroy( pPcb->pUserAttributes );
  941. pPcb->pUserAttributes = NULL;
  942. }
  943. if ( pPcb->pAuthenticatorAttributes != NULL )
  944. {
  945. PppConfigInfo.RasAuthProviderFreeAttributes(
  946. pPcb->pAuthenticatorAttributes );
  947. pPcb->pAuthenticatorAttributes = NULL;
  948. }
  949. //
  950. // Notify the server that the port is now cleaned up
  951. //
  952. // if accounting is turned on, do not notify the DDM that
  953. // we are done as yet. But do it in post clenup
  954. //moved to post line down
  955. /*
  956. if ( !( pPcb->fFlags & PCBFLAG_DOING_CALLBACK ) )
  957. {
  958. if (
  959. NotifyCaller( pPcb, PPPDDMMSG_PortCleanedUp, NULL );
  960. }
  961. else
  962. {
  963. if ( !(pPcb->fFlags & PCBFLAG_IS_SERVER ) )
  964. {
  965. //
  966. // If we get here and this flag is sent then we have not sent
  967. // the callback message to the client, hence we send it now.
  968. //
  969. NotifyCaller( pPcb, PPPMSG_Callback, NULL );
  970. }
  971. }
  972. */
  973. //
  974. // Send PPPMSG_Stopped to rasman, if we haven't already. If we get a
  975. // PPPEMSG_Stop and then a PPPEMSG_LineDown before we call ProcessClose,
  976. // rasman will never get a PPPMSG_Stopped. This is because pPcb will be
  977. // deallocated and gone by the time we call ProcessClose. Note that we
  978. // process a LineDown immediately and do not put it only at the end of
  979. // the worker queue.
  980. //
  981. // DDM is not affected because of PPPDDMMSG_PortCleanedUp above.
  982. //
  983. //
  984. // If should be OK to remove PCBFLAG_STOPPED_MSG_SENT. Most probably rasman
  985. // can gracefully handle 2 PPPMSG_Stopped's. However, we don't want to take
  986. // chances this close to shipping.
  987. // moved to post line down
  988. /*
  989. if ( !(pPcb->fFlags & PCBFLAG_IS_SERVER )
  990. && !(pPcb->fFlags & PCBFLAG_STOPPED_MSG_SENT) )
  991. {
  992. DWORD dwError = 0;
  993. NotifyCaller( pPcb, PPPMSG_Stopped, &dwError );
  994. }
  995. if ( pPcb->fFlags & PCBFLAG_PORT_IN_LISTENING_STATE )
  996. {
  997. //
  998. // This flag is set in FListenForCall in bap.c
  999. //
  1000. NotifyCallerOfFailure( pPcb, NO_ERROR );
  1001. }
  1002. LOCAL_FREE( pPcb );
  1003. */
  1004. //if there are accounting attributes,
  1005. if ( pPcb->pAccountingAttributes != NULL )
  1006. {
  1007. //do not call the post line down
  1008. //in ProcessLineDown but let the accounting thread send a message back to indicate that it is done
  1009. *pfFinalStage = FALSE;
  1010. }
  1011. }
  1012. //**
  1013. //
  1014. // Call: ProcessLineDown
  1015. //
  1016. // Returns: None.
  1017. //
  1018. // Description: Handles a line down event. Will remove and deallocate all
  1019. // resources associated with the port control block.
  1020. //
  1021. VOID
  1022. ProcessLineDown(
  1023. IN PCB_WORK_ITEM * pWorkItem
  1024. )
  1025. {
  1026. BOOL fFinalStage = TRUE; //tells us if we should call ProcessPostLineDown
  1027. //right here or let accounting thread call it.
  1028. PCB * pPcb = GetPCBPointerFromhPort( pWorkItem->hPort );
  1029. ProcessLineDownWorker( pWorkItem, &fFinalStage );
  1030. if ( fFinalStage )
  1031. {
  1032. PostLineDownWorker(pPcb);
  1033. }
  1034. }
  1035. //**
  1036. //
  1037. // Call: ProcessClose
  1038. //
  1039. // Returns: None
  1040. //
  1041. // Description: Will process an admin close event. Basically close the PPP
  1042. // connection.
  1043. //
  1044. VOID
  1045. ProcessClose(
  1046. IN PCB_WORK_ITEM * pWorkItem
  1047. )
  1048. {
  1049. DWORD dwIndex;
  1050. PCB * pPcb = GetPCBPointerFromhPort( pWorkItem->hPort );
  1051. if ( pPcb == (PCB*)NULL )
  1052. {
  1053. return;
  1054. }
  1055. if ( (!( pPcb->fFlags & PCBFLAG_IS_BUNDLED )) ||
  1056. ( ( pPcb->fFlags & PCBFLAG_IS_BUNDLED ) &&
  1057. ( pPcb->pBcb->dwLinkCount == 1 ) ) )
  1058. {
  1059. for (dwIndex = LCP_INDEX+1;
  1060. dwIndex < PppConfigInfo.NumberOfCPs;
  1061. dwIndex++)
  1062. {
  1063. CPCB * pCpCb = GetPointerToCPCB( pPcb, dwIndex );
  1064. if ( ( NULL != pCpCb ) &&
  1065. ( pCpCb->fConfigurable == TRUE ) &&
  1066. ( pCpCb->pWorkBuf != NULL ) &&
  1067. ( CpTable[dwIndex].CpInfo.RasCpPreDisconnectCleanup != NULL ) )
  1068. {
  1069. (CpTable[dwIndex].CpInfo.RasCpPreDisconnectCleanup)(
  1070. pCpCb->pWorkBuf );
  1071. }
  1072. }
  1073. }
  1074. if ( pPcb->LcpCb.dwError == NO_ERROR )
  1075. {
  1076. pPcb->LcpCb.dwError = pWorkItem->PppMsg.PppStop.dwStopReason;
  1077. }
  1078. FsmClose( pPcb, LCP_INDEX );
  1079. }
  1080. //**
  1081. //
  1082. // Call: ProcessReceive
  1083. //
  1084. // Returns: None
  1085. //
  1086. // Description: Will handle a PPP packet that was received.
  1087. //
  1088. VOID
  1089. ProcessReceive(
  1090. IN PCB_WORK_ITEM * pWorkItem
  1091. )
  1092. {
  1093. PCB * pPcb = GetPCBPointerFromhPort( pWorkItem->hPort );
  1094. if ( pPcb == (PCB*)NULL )
  1095. return;
  1096. ReceiveViaParser( pPcb, pWorkItem->pPacketBuf, pWorkItem->PacketLen );
  1097. LOCAL_FREE( pWorkItem->pPacketBuf );
  1098. }
  1099. //**
  1100. //
  1101. // Call: ProcessThresholdEvent
  1102. //
  1103. // Returns: None
  1104. //
  1105. // Description: Will handle a BAP threshold event (Add-Link or Drop-Link)
  1106. //
  1107. VOID
  1108. ProcessThresholdEvent(
  1109. IN PCB_WORK_ITEM * pWorkItem
  1110. )
  1111. {
  1112. BCB * pBcb = GetBCBPointerFromhConnection( pWorkItem->hConnection );
  1113. if ( pBcb == NULL )
  1114. {
  1115. BapTrace( "HCONN %d has no port", pWorkItem->hConnection );
  1116. return;
  1117. }
  1118. if ( pWorkItem->PppMsg.BapEvent.fAdd )
  1119. {
  1120. BapEventAddLink( pBcb );
  1121. }
  1122. else
  1123. {
  1124. BapEventDropLink( pBcb );
  1125. }
  1126. BapSetPolicy( pBcb );
  1127. }
  1128. //**
  1129. //
  1130. // Call: ProcessCallResult
  1131. //
  1132. // Returns: None
  1133. //
  1134. // Description: Will handle the result of a BAP call attempt (Success or Failure)
  1135. //
  1136. VOID
  1137. ProcessCallResult(
  1138. IN PCB_WORK_ITEM * pWorkItem
  1139. )
  1140. {
  1141. PCB * pPcb;
  1142. BCB * pBcb = GetBCBPointerFromhConnection(pWorkItem->hConnection);
  1143. DWORD dwErr;
  1144. if ( pBcb == NULL )
  1145. {
  1146. BapTrace( "HCONN 0x%x has no port", pWorkItem->hConnection );
  1147. dwErr = RasHangUp( pWorkItem->PppMsg.BapCallResult.hRasConn );
  1148. if (0 != dwErr)
  1149. {
  1150. BapTrace("RasHangup failed and returned %d", dwErr);
  1151. }
  1152. return;
  1153. }
  1154. PPP_ASSERT( BAP_STATE_CALLING == pBcb->BapCb.BapState );
  1155. BapEventCallResult( pBcb, &(pWorkItem->PppMsg.BapCallResult) );
  1156. }
  1157. //**
  1158. //
  1159. // Call: ProcessRasPortListenEvent
  1160. //
  1161. // Returns: None
  1162. //
  1163. // Description: Will handle a RasPortListen event (when the client is trying to
  1164. // accept a call).
  1165. //
  1166. VOID
  1167. ProcessRasPortListenEvent(
  1168. IN PCB_WORK_ITEM * pWorkItem
  1169. )
  1170. {
  1171. RASMAN_INFO RasmanInfo;
  1172. RASMAN_PPPFEATURES RasmanPppFeatures;
  1173. DWORD dwErr;
  1174. PCB * pPcb = NULL;
  1175. BCB * pBcb = NULL;
  1176. PCB * pPcbSibling;
  1177. CHAR szPassword[PWLEN+1];
  1178. ZeroMemory( &RasmanPppFeatures, sizeof(RasmanPppFeatures) );
  1179. RasmanPppFeatures.ACCM = 0xFFFFFFFF;
  1180. pPcb = GetPCBPointerFromhPort( pWorkItem->hPort );
  1181. if ( NULL == pPcb )
  1182. {
  1183. BapTrace( "Couldn't get the PCB for hPort %d", pWorkItem->hPort );
  1184. dwErr = ERROR_PORT_NOT_FOUND;
  1185. goto LDone;
  1186. }
  1187. //
  1188. // We can't just use pPcb->pBcb because TryToBundleWithAnotherLink(), etc
  1189. // have not yet been called. pPcb->hConnection was set in FListenForCall()
  1190. //
  1191. pBcb = GetBCBPointerFromhConnection( pPcb->hConnection );
  1192. if ( NULL == pBcb )
  1193. {
  1194. BapTrace( "Couldn't get the BCB for HCONN 0x%x", pPcb->hConnection );
  1195. dwErr = ERROR_BUNDLE_NOT_FOUND;
  1196. goto LDone;
  1197. }
  1198. BapTrace( "ProcessRasPortListenEvent on HCONN 0x%x", pBcb->hConnection );
  1199. dwErr = RasGetInfo(NULL, pPcb->hPort, &RasmanInfo );
  1200. if ( NO_ERROR == dwErr )
  1201. {
  1202. dwErr = RasmanInfo.RI_LastError;
  1203. }
  1204. if ( NO_ERROR != dwErr )
  1205. {
  1206. DWORD dwErrT;
  1207. BapTrace( "RasGetInfo on hPort %d returned error %d%s",
  1208. pPcb->hPort, dwErr,
  1209. dwErr == ERROR_REQUEST_TIMEOUT ? " (ERROR_REQUEST_TIMEOUT)" : "" );
  1210. if(0 == (RasmanInfo.RI_CurrentUsage & CALL_IN))
  1211. {
  1212. //
  1213. // Disconnect the port that was listening.
  1214. //
  1215. dwErrT = RasPortDisconnect(pPcb->hPort, INVALID_HANDLE_VALUE);
  1216. BapTrace("RasPortDisconnect returned %d", dwErrT);
  1217. }
  1218. //
  1219. // Close the port.
  1220. //
  1221. dwErrT = RasPortClose(pPcb->hPort);
  1222. BapTrace("RasPortDisconnect returned %d", dwErrT);
  1223. goto LDone;
  1224. }
  1225. if ( LISTENCOMPLETED == RasmanInfo.RI_ConnState )
  1226. {
  1227. DWORD cbPassword;
  1228. PBYTE pbPassword = NULL;
  1229. dwErr = RasPortConnectComplete( pPcb->hPort );
  1230. if ( NO_ERROR != dwErr )
  1231. {
  1232. BapTrace( "RasPortConnectComplete on hPort %d returned error %d",
  1233. pPcb->hPort, dwErr );
  1234. goto LDone;
  1235. }
  1236. dwErr = RasPortSetFraming( pPcb->hPort, PPP, &RasmanPppFeatures,
  1237. &RasmanPppFeatures );
  1238. if ( NO_ERROR != dwErr )
  1239. {
  1240. BapTrace( "RasPortSetFraming on hPort %d returned error %d",
  1241. pPcb->hPort, dwErr );
  1242. goto LDone;
  1243. }
  1244. pPcbSibling = GetPCBPointerFromBCB( pBcb );
  1245. if ( NULL == pPcbSibling )
  1246. {
  1247. BapTrace( "Couldn't get a PCB for HCONN 0x%x", pPcb->hConnection );
  1248. dwErr = !NO_ERROR;
  1249. goto LDone;
  1250. }
  1251. // DecodePw( pPcbSibling->pBcb->chSeed, pPcbSibling->pBcb->szPassword );
  1252. dwErr = DecodePassword(&pPcbSibling->pBcb->DBPassword,
  1253. &cbPassword, &pbPassword);
  1254. if(NO_ERROR != dwErr)
  1255. {
  1256. BapTrace("DecodePassword failed. 0x%x", dwErr);
  1257. goto LDone;
  1258. }
  1259. *szPassword = '\0';
  1260. CopyMemory(szPassword, pbPassword, cbPassword);
  1261. RtlSecureZeroMemory(pbPassword, cbPassword);
  1262. LocalFree(pbPassword);
  1263. // EncodePw( pPcbSibling->pBcb->chSeed, pPcbSibling->pBcb->szPassword );
  1264. if ( NULL != pPcbSibling->pBcb->pCustomAuthConnData )
  1265. {
  1266. dwErr = RasSetRasdialInfo(
  1267. pPcb->hPort,
  1268. pPcbSibling->pBcb->szPhonebookPath,
  1269. pPcbSibling->pBcb->szEntryName,
  1270. pPcbSibling->pBcb->BapCb.szServerPhoneNumber,
  1271. pPcbSibling->pBcb->pCustomAuthConnData->cbCustomAuthData,
  1272. pPcbSibling->pBcb->pCustomAuthConnData->abCustomAuthData );
  1273. if ( NO_ERROR != dwErr )
  1274. {
  1275. BapTrace( "RasSetRasDialInfo failed. dwErr = %d", dwErr );
  1276. goto LDone;
  1277. }
  1278. }
  1279. if ( NULL != pPcbSibling->pBcb->pCustomAuthUserData )
  1280. {
  1281. RASEAPINFO RasEapInfo;
  1282. RasEapInfo.dwSizeofEapInfo =
  1283. pPcbSibling->pBcb->pCustomAuthUserData->cbCustomAuthData;
  1284. RasEapInfo.pbEapInfo =
  1285. pPcbSibling->pBcb->pCustomAuthUserData->abCustomAuthData;
  1286. dwErr = RasSetEapLogonInfo(
  1287. pPcb->hPort,
  1288. FALSE /* fLogon */,
  1289. &RasEapInfo );
  1290. if ( NO_ERROR != dwErr )
  1291. {
  1292. BapTrace( "RasSetEapLogonInfo failed. dwErr = %d", dwErr );
  1293. goto LDone;
  1294. }
  1295. }
  1296. // This function returns before any LCP packet is exchanged.
  1297. dwErr = RasPppStart(
  1298. pPcb->hPort,
  1299. pPcb->szPortName,
  1300. pPcbSibling->pBcb->szLocalUserName,
  1301. szPassword,
  1302. pPcbSibling->pBcb->szLocalDomain,
  1303. &(pPcbSibling->Luid),
  1304. &(pPcbSibling->ConfigInfo),
  1305. &(pBcb->InterfaceInfo),
  1306. pBcb->InterfaceInfo.szzParameters,
  1307. FALSE /* fThisIsACallback */,
  1308. INVALID_HANDLE_VALUE,
  1309. pPcbSibling->dwAutoDisconnectTime,
  1310. FALSE /* fRedialOnLinkFailure */,
  1311. &(pPcbSibling->pBcb->BapParams),
  1312. TRUE /* fNonInteractive */,
  1313. pPcbSibling->dwEapTypeToBeUsed,
  1314. (pPcbSibling->fFlags & PCBFLAG_DISABLE_NETBT) ?
  1315. PPPFLAGS_DisableNetbt : 0
  1316. );
  1317. if ( NO_ERROR != dwErr )
  1318. {
  1319. BapTrace( "RasPppStart failed. dwErr = %d", dwErr );
  1320. goto LDone;
  1321. }
  1322. BapTrace( "RasPppStart called successfully for hPort %d on HCONN 0x%x",
  1323. pPcb->hPort, pBcb->hConnection );
  1324. {
  1325. CHAR* apsz[3];
  1326. apsz[0] = pPcbSibling->pBcb->szEntryName;
  1327. apsz[1] = pPcbSibling->pBcb->szLocalUserName;
  1328. apsz[2] = pPcb->szPortName;
  1329. PppLogInformation(ROUTERLOG_BAP_SERVER_CONNECTED, 3, apsz);
  1330. }
  1331. }
  1332. LDone:
  1333. RtlSecureZeroMemory(szPassword, PWLEN + 1);
  1334. if (NULL != pBcb)
  1335. {
  1336. pBcb->fFlags &= ~BCBFLAG_LISTENING;
  1337. pBcb->BapCb.BapState = BAP_STATE_INITIAL;
  1338. BapTrace("BAP state change to %s on HCONN 0x%x",
  1339. SzBapStateName[BAP_STATE_INITIAL], pBcb->hConnection);
  1340. }
  1341. if (NO_ERROR != dwErr && NULL != pPcb)
  1342. {
  1343. NotifyCallerOfFailure( pPcb, NO_ERROR );
  1344. RemovePcbFromTable( pPcb );
  1345. LOCAL_FREE( pPcb );
  1346. }
  1347. }
  1348. //**
  1349. //
  1350. // Call: ProcessTimeout
  1351. //
  1352. // Returns: None
  1353. //
  1354. // Description: Will process a timeout event.
  1355. //
  1356. VOID
  1357. ProcessTimeout(
  1358. IN PCB_WORK_ITEM * pWorkItem
  1359. )
  1360. {
  1361. DWORD dwRetCode;
  1362. DWORD dwIndex;
  1363. CPCB * pCpCb;
  1364. BCB * pBcb;
  1365. PCB * pPcb;
  1366. if ( pWorkItem->Protocol == PPP_BAP_PROTOCOL )
  1367. {
  1368. //
  1369. // The hPort in pWorkItem is actually an hConnection
  1370. //
  1371. pBcb = GetBCBPointerFromhConnection( pWorkItem->hPort );
  1372. if (pBcb != NULL)
  1373. {
  1374. BapEventTimeout( pBcb, pWorkItem->Id );
  1375. }
  1376. return;
  1377. }
  1378. pPcb = GetPCBPointerFromhPort( pWorkItem->hPort );
  1379. if ( ( pPcb == (PCB*)NULL )
  1380. || ( pWorkItem->dwPortId != pPcb->dwPortId ) )
  1381. {
  1382. return;
  1383. }
  1384. switch( pWorkItem->TimerEventType )
  1385. {
  1386. case TIMER_EVENT_TIMEOUT:
  1387. FsmTimeout( pPcb,
  1388. GetCpIndexFromProtocol( pWorkItem->Protocol ),
  1389. pWorkItem->Id,
  1390. pWorkItem->fAuthenticator );
  1391. break;
  1392. case TIMER_EVENT_AUTODISCONNECT:
  1393. //
  1394. // Check to see if this timeout workitem is for AutoDisconnect.
  1395. //
  1396. CheckCpsForInactivity( pPcb, TIMER_EVENT_AUTODISCONNECT );
  1397. break;
  1398. case TIMER_EVENT_HANGUP:
  1399. //
  1400. // Hangup the line
  1401. //
  1402. FsmThisLayerFinished( pPcb, LCP_INDEX, FALSE );
  1403. break;
  1404. case TIMER_EVENT_NEGOTIATETIME:
  1405. //
  1406. // Notify caller that callback has timed out. We don't do anything for
  1407. // the client since it may be in interactive mode and may take much
  1408. // longer, besides, the user can allways cancel out.
  1409. //
  1410. if ( pPcb->fFlags & PCBFLAG_IS_SERVER )
  1411. {
  1412. if ( pPcb->PppPhase != PPP_NCP )
  1413. {
  1414. pPcb->LcpCb.dwError = ERROR_PPP_TIMEOUT;
  1415. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1416. break;
  1417. }
  1418. //
  1419. // Check to see if all CPs are done or only IPXCP is remaining
  1420. //
  1421. for ( dwIndex = LCP_INDEX+1;
  1422. dwIndex < PppConfigInfo.NumberOfCPs;
  1423. dwIndex++)
  1424. {
  1425. pCpCb = GetPointerToCPCB( pPcb, dwIndex );
  1426. if ( pCpCb->fConfigurable )
  1427. {
  1428. if ( pCpCb->NcpPhase == NCP_CONFIGURING )
  1429. {
  1430. if ( CpTable[dwIndex].CpInfo.Protocol ==
  1431. PPP_IPXCP_PROTOCOL )
  1432. {
  1433. //
  1434. // If we are only waiting for IPXWAN to complete
  1435. //
  1436. if ( pCpCb->State == FSM_OPENED )
  1437. {
  1438. continue;
  1439. }
  1440. }
  1441. pPcb->LcpCb.dwError = ERROR_PPP_TIMEOUT;
  1442. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1443. return;
  1444. }
  1445. }
  1446. }
  1447. dwIndex = GetCpIndexFromProtocol( PPP_IPXCP_PROTOCOL );
  1448. if ( dwIndex == (DWORD)-1 )
  1449. {
  1450. //
  1451. // No IPXCP installed in system
  1452. //
  1453. break;
  1454. }
  1455. pCpCb = GetPointerToCPCB( pPcb, dwIndex );
  1456. //
  1457. // We are waiting for IPXWAN so simply complete it with failure
  1458. //
  1459. if ( ( pCpCb->State == FSM_OPENED ) &&
  1460. ( pCpCb->NcpPhase == NCP_CONFIGURING ) )
  1461. {
  1462. PppLog( 2,
  1463. "Closing down IPXCP since completion routine not called");
  1464. pCpCb = GetPointerToCPCB( pPcb, dwIndex );
  1465. pCpCb->dwError = ERROR_PPP_NOT_CONVERGING;
  1466. NotifyCallerOfFailure( pPcb, pCpCb->dwError );
  1467. }
  1468. }
  1469. else
  1470. {
  1471. if ( ( pPcb->pBcb->InterfaceInfo.IfType ==
  1472. ROUTER_IF_TYPE_FULL_ROUTER )
  1473. || ( pPcb->fFlags & PCBFLAG_NON_INTERACTIVE ) )
  1474. {
  1475. //
  1476. // If we are a router dialing out, then we are in
  1477. // non-interactive mode and hence this timeout should bring
  1478. // down the link
  1479. //
  1480. pPcb->LcpCb.dwError = ERROR_PPP_TIMEOUT;
  1481. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1482. }
  1483. }
  1484. break;
  1485. case TIMER_EVENT_SESSION_TIMEOUT:
  1486. if ( pWorkItem->dwPortId == pPcb->dwPortId )
  1487. {
  1488. pPcb->LcpCb.dwError = ERROR_PPP_SESSION_TIMEOUT;
  1489. if(pPcb->pBcb->fFlags & BCBFLAG_QUARANTINE_TIMEOUT)
  1490. {
  1491. pPcb->fFlags |= PCBFLAG_QUARANTINE_TIMEOUT;
  1492. }
  1493. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1494. }
  1495. break;
  1496. case TIMER_EVENT_FAV_PEER_TIMEOUT:
  1497. //
  1498. // Drop the line if it isn't the last one in the bundle
  1499. //
  1500. if ( pPcb->pBcb->dwLinkCount > 1 &&
  1501. pWorkItem->dwPortId == pPcb->dwPortId)
  1502. {
  1503. //
  1504. // We compare dwPortId just to make sure that this is not a new
  1505. // pPcb with the same hPort. dwPortId is never recycled, but hPort
  1506. // is.
  1507. //
  1508. CHAR* psz[3];
  1509. if (!(pPcb->fFlags & PCBFLAG_IS_SERVER))
  1510. {
  1511. psz[0] = pPcb->pBcb->szEntryName;
  1512. psz[1] = pPcb->pBcb->szLocalUserName;
  1513. psz[2] = pPcb->szPortName;
  1514. PppLogInformation(ROUTERLOG_BAP_DISCONNECTED, 3, psz);
  1515. }
  1516. BapTrace( "Forcibly disconnecting hPort %d: Favored peer failed "
  1517. "to do so",
  1518. pPcb->hPort);
  1519. pPcb->LcpCb.dwError = ERROR_BAP_DISCONNECTED;
  1520. FsmClose( pPcb, LCP_INDEX );
  1521. }
  1522. break;
  1523. case TIMER_EVENT_INTERIM_ACCOUNTING:
  1524. {
  1525. RAS_AUTH_ATTRIBUTE * pAttributes = NULL;
  1526. RAS_AUTH_ATTRIBUTE * pAttribute = NULL;
  1527. MakeStopOrInterimAccountingCall( pPcb, TRUE );
  1528. if ( pPcb->pAuthProtocolAttributes != NULL )
  1529. {
  1530. pAttributes = pPcb->pAuthProtocolAttributes;
  1531. }
  1532. else if ( pPcb->pAuthenticatorAttributes != NULL )
  1533. {
  1534. pAttributes = pPcb->pAuthenticatorAttributes;
  1535. }
  1536. pAttribute = RasAuthAttributeGet(raatAcctInterimInterval,
  1537. pAttributes);
  1538. if ( pAttribute != NULL )
  1539. {
  1540. DWORD dwInterimInterval = PtrToUlong(pAttribute->Value);
  1541. if ( dwInterimInterval < 60 )
  1542. {
  1543. dwInterimInterval = 60;
  1544. }
  1545. InsertInTimerQ(
  1546. pPcb->dwPortId,
  1547. pPcb->hPort,
  1548. 0,
  1549. 0,
  1550. FALSE,
  1551. TIMER_EVENT_INTERIM_ACCOUNTING,
  1552. dwInterimInterval );
  1553. }
  1554. }
  1555. break;
  1556. case TIMER_EVENT_LCP_ECHO:
  1557. {
  1558. //
  1559. // Check to see if this timeout workitem is for AutoDisconnect.
  1560. //
  1561. CheckCpsForInactivity( pPcb, TIMER_EVENT_LCP_ECHO );
  1562. }
  1563. break;
  1564. default:
  1565. break;
  1566. }
  1567. }
  1568. //**
  1569. //
  1570. // Call: ProcessRetryPassword
  1571. //
  1572. // Returns: None
  1573. //
  1574. // Description:
  1575. //
  1576. VOID
  1577. ProcessRetryPassword(
  1578. IN PCB_WORK_ITEM * pWorkItem
  1579. )
  1580. {
  1581. PPPAP_INPUT PppApInput;
  1582. PCB * pPcb = GetPCBPointerFromhPort( pWorkItem->hPort );
  1583. LCPCB * pLcpCb;
  1584. DWORD cbPassword;
  1585. PBYTE pbPassword = NULL;
  1586. DWORD dwRetCode = NO_ERROR;
  1587. if ( pPcb == (PCB*)NULL )
  1588. {
  1589. return;
  1590. }
  1591. if ( pPcb->PppPhase != PPP_AP )
  1592. {
  1593. return;
  1594. }
  1595. RtlSecureZeroMemory( pPcb->pBcb->szPassword, sizeof( pPcb->pBcb->szPassword ) );
  1596. strcpy( pPcb->pBcb->szLocalUserName, pWorkItem->PppMsg.Retry.szUserName );
  1597. // DecodePw( pWorkItem->PppMsg.Retry.chSeed, pWorkItem->PppMsg.Retry.szPassword );
  1598. dwRetCode = DecodePassword(&pWorkItem->PppMsg.Retry.DBPassword,
  1599. &cbPassword, &pbPassword);
  1600. if(NO_ERROR != dwRetCode)
  1601. {
  1602. goto done;
  1603. }
  1604. // strcpy( pPcb->pBcb->szPassword, pWorkItem->PppMsg.Retry.szPassword );
  1605. FreePassword(&pPcb->pBcb->DBPassword);
  1606. CopyMemory(&pPcb->pBcb->DBPassword,
  1607. &pWorkItem->PppMsg.Retry.DBPassword,
  1608. sizeof(DATA_BLOB));
  1609. // EncodePw( pWorkItem->PppMsg.Retry.chSeed, pWorkItem->PppMsg.Retry.szPassword );
  1610. strcpy( pPcb->pBcb->szLocalDomain, pWorkItem->PppMsg.Retry.szDomain );
  1611. PppApInput.pszUserName = pPcb->pBcb->szLocalUserName;
  1612. PppApInput.pszPassword = pbPassword;
  1613. PppApInput.pszDomain = pPcb->pBcb->szLocalDomain;
  1614. //
  1615. // Under the current scheme this should always be "" at this point but
  1616. // handle it like it a regular password for robustness.
  1617. //
  1618. // DecodePw( pPcb->pBcb->chSeed, pPcb->pBcb->szOldPassword );
  1619. PppApInput.pszOldPassword = pPcb->pBcb->szOldPassword;
  1620. pLcpCb = (LCPCB *)(pPcb->LcpCb.pWorkBuf);
  1621. ApWork( pPcb,
  1622. GetCpIndexFromProtocol( pLcpCb->Remote.Work.AP ),
  1623. NULL,
  1624. &PppApInput,
  1625. FALSE );
  1626. done:
  1627. RtlSecureZeroMemory(pbPassword, cbPassword);
  1628. LocalFree(pbPassword);
  1629. //
  1630. // Encrypt the password
  1631. //
  1632. // EncodePw( pPcb->pBcb->chSeed, pPcb->pBcb->szPassword );
  1633. // EncodePw( pPcb->pBcb->chSeed, pPcb->pBcb->szOldPassword );
  1634. }
  1635. //**
  1636. //
  1637. // Call: ProcessChangePassword
  1638. //
  1639. // Returns: None
  1640. //
  1641. // Description:
  1642. //
  1643. VOID
  1644. ProcessChangePassword(
  1645. IN PCB_WORK_ITEM * pWorkItem
  1646. )
  1647. {
  1648. PPPAP_INPUT PppApInput;
  1649. PCB * pPcb = GetPCBPointerFromhPort( pWorkItem->hPort );
  1650. CPCB * pCpCb;
  1651. LCPCB * pLcpCb;
  1652. DWORD cbOldPassword, cbNewPassword;
  1653. PBYTE pbOldPassword = NULL, pbNewPassword = NULL;
  1654. DWORD dwRetCode = NO_ERROR;
  1655. if ( pPcb == (PCB*)NULL )
  1656. {
  1657. return;
  1658. }
  1659. if ( pPcb->PppPhase != PPP_AP )
  1660. {
  1661. return;
  1662. }
  1663. ZeroMemory( pPcb->pBcb->szLocalUserName,
  1664. sizeof( pPcb->pBcb->szLocalUserName ) );
  1665. strcpy(pPcb->pBcb->szLocalUserName, pWorkItem->PppMsg.ChangePw.szUserName);
  1666. // DecodePw( pWorkItem->PppMsg.ChangePw.chSeed, pWorkItem->PppMsg.ChangePw.szNewPassword );
  1667. // RtlSecureZeroMemory( pPcb->pBcb->szPassword, sizeof( pPcb->pBcb->szPassword ) );
  1668. dwRetCode = DecodePassword(&pWorkItem->PppMsg.ChangePw.DBPassword,
  1669. &cbNewPassword, &pbNewPassword);
  1670. if(dwRetCode != NO_ERROR)
  1671. {
  1672. goto done;
  1673. }
  1674. dwRetCode = DecodePassword(&pWorkItem->PppMsg.ChangePw.DBOldPassword,
  1675. &cbOldPassword, &pbOldPassword);
  1676. if(dwRetCode != NO_ERROR)
  1677. {
  1678. goto done;
  1679. }
  1680. FreePassword(&pPcb->pBcb->DBPassword);
  1681. CopyMemory(&pPcb->pBcb->DBPassword,
  1682. &pWorkItem->PppMsg.ChangePw.DBPassword,
  1683. sizeof(DATA_BLOB));
  1684. ZeroMemory(&pWorkItem->PppMsg.ChangePw.DBPassword,
  1685. sizeof(DATA_BLOB));
  1686. FreePassword(&pPcb->pBcb->DBOldPassword);
  1687. CopyMemory(&pPcb->pBcb->DBOldPassword,
  1688. &pWorkItem->PppMsg.ChangePw.DBOldPassword,
  1689. sizeof(DATA_BLOB));
  1690. ZeroMemory(&pWorkItem->PppMsg.ChangePw.DBOldPassword,
  1691. sizeof(DATA_BLOB));
  1692. // strcpy(pPcb->pBcb->szOldPassword, pWorkItem->PppMsg.ChangePw.szOldPassword);
  1693. // EncodePw( pWorkItem->PppMsg.ChangePw.chSeed, pWorkItem->PppMsg.ChangePw.szOldPassword );
  1694. PppApInput.pszUserName = pPcb->pBcb->szLocalUserName;
  1695. PppApInput.pszPassword = pbNewPassword;
  1696. PppApInput.pszDomain = pPcb->pBcb->szLocalDomain;
  1697. PppApInput.pszOldPassword = pbOldPassword;
  1698. pLcpCb = (LCPCB *)(pPcb->LcpCb.pWorkBuf);
  1699. ApWork( pPcb,
  1700. GetCpIndexFromProtocol( pLcpCb->Remote.Work.AP ),
  1701. NULL,
  1702. &PppApInput,
  1703. FALSE );
  1704. done:
  1705. RtlSecureZeroMemory(pbNewPassword, cbNewPassword);
  1706. RtlSecureZeroMemory(pbOldPassword, cbOldPassword);
  1707. LocalFree(pbNewPassword);
  1708. LocalFree(pbOldPassword);
  1709. //
  1710. // Encrypt the passwords
  1711. //
  1712. // EncodePw( pPcb->pBcb->chSeed, pPcb->pBcb->szPassword );
  1713. // EncodePw( pPcb->pBcb->chSeed, pPcb->pBcb->szOldPassword );
  1714. }
  1715. //**
  1716. //
  1717. // Call: ProcessGetCallbackNumberFromUser
  1718. //
  1719. // Returns: None
  1720. //
  1721. // Description: Will process the event of the user passing down the
  1722. // "Set by caller" number
  1723. //
  1724. VOID
  1725. ProcessGetCallbackNumberFromUser(
  1726. IN PCB_WORK_ITEM * pWorkItem
  1727. )
  1728. {
  1729. PPPCB_INPUT PppCbInput;
  1730. PCB * pPcb = GetPCBPointerFromhPort( pWorkItem->hPort );
  1731. if ( pPcb == (PCB*)NULL )
  1732. {
  1733. return;
  1734. }
  1735. if ( pPcb->PppPhase != PPP_NEGOTIATING_CALLBACK )
  1736. {
  1737. return;
  1738. }
  1739. ZeroMemory( &PppCbInput, sizeof( PppCbInput ) );
  1740. strcpy( pPcb->szCallbackNumber,
  1741. pWorkItem->PppMsg.Callback.szCallbackNumber );
  1742. PppCbInput.pszCallbackNumber = pPcb->szCallbackNumber;
  1743. CbWork( pPcb, GetCpIndexFromProtocol(PPP_CBCP_PROTOCOL),NULL,&PppCbInput);
  1744. }
  1745. //**
  1746. //
  1747. // Call: ProcessCallbackDone
  1748. //
  1749. // Returns: None
  1750. //
  1751. // Description: Will process the event of callback compeletion
  1752. // "Set by caller" number
  1753. VOID
  1754. ProcessCallbackDone(
  1755. IN PCB_WORK_ITEM * pWorkItem
  1756. )
  1757. {
  1758. ProcessLineUpWorker( pWorkItem, TRUE );
  1759. }
  1760. //**
  1761. //
  1762. // Call: ProcessStopPPP
  1763. //
  1764. // Returns: None
  1765. //
  1766. // Description: Will simply set the events whose handle is in hPipe
  1767. //
  1768. VOID
  1769. ProcessStopPPP(
  1770. IN PCB_WORK_ITEM * pWorkItem
  1771. )
  1772. {
  1773. PRAS_OVERLAPPED pOverlapped;
  1774. HINSTANCE hInstance;
  1775. PCB * pPcbWalker;
  1776. DWORD dwIndex;
  1777. PCB_WORK_ITEM WorkItem;
  1778. HANDLE hEvent;
  1779. //
  1780. // Insert line down events for all ports
  1781. //
  1782. for ( dwIndex = 0; dwIndex < PcbTable.NumPcbBuckets; dwIndex++ )
  1783. {
  1784. RTASSERT( NULL == PcbTable.PcbBuckets[dwIndex].pPorts );
  1785. }
  1786. hInstance = LoadLibrary("rasppp.dll");
  1787. if (hInstance == NULL)
  1788. {
  1789. return;
  1790. }
  1791. PppLog( 2, "All clients disconnected PPP-Stopped" );
  1792. hEvent = pWorkItem->hEvent;
  1793. //
  1794. // PPPCleanUp() needs to be called before PostQueued...(). Otherwise,
  1795. // Rasman may call StartPPP() and there will be a race condition.
  1796. // Specifically, between ReadRegistryInfo and PPPCleanUp, both of which
  1797. // access CpTable.
  1798. //
  1799. PPPCleanUp();
  1800. pOverlapped = malloc(sizeof(RAS_OVERLAPPED));
  1801. if (NULL == pOverlapped)
  1802. {
  1803. return;
  1804. }
  1805. pOverlapped->RO_EventType = OVEVT_RASMAN_FINAL_CLOSE;
  1806. if ( !PostQueuedCompletionStatus( hEvent, 0, 0, (LPOVERLAPPED) pOverlapped ) )
  1807. {
  1808. free( pOverlapped );
  1809. }
  1810. FreeLibraryAndExitThread( hInstance, NO_ERROR );
  1811. }
  1812. //**
  1813. //
  1814. // Call: ProcessInterfaceInfo
  1815. //
  1816. // Returns: None
  1817. //
  1818. // Description: Processes the information interface information received from
  1819. // DDM
  1820. //
  1821. VOID
  1822. ProcessInterfaceInfo(
  1823. IN PCB_WORK_ITEM * pWorkItem
  1824. )
  1825. {
  1826. DWORD dwRetCode;
  1827. DWORD dwIndex;
  1828. NCP_PHASE dwNcpState;
  1829. HPORT hPort;
  1830. PCB * pPcb = NULL;
  1831. CPCB * pCpCb;
  1832. dwRetCode = RasBundleGetPort(NULL, pWorkItem->hConnection, &hPort );
  1833. if ( dwRetCode != NO_ERROR )
  1834. {
  1835. return;
  1836. }
  1837. if ( ( pPcb = GetPCBPointerFromhPort( hPort ) ) == NULL )
  1838. {
  1839. return;
  1840. }
  1841. pCpCb = GetPointerToCPCB( pPcb, LCP_INDEX );
  1842. PPP_ASSERT( NULL != pCpCb );
  1843. if ( FSM_OPENED != pCpCb->State )
  1844. {
  1845. return;
  1846. }
  1847. pPcb->PppPhase = PPP_NCP;
  1848. pPcb->pBcb->InterfaceInfo = pWorkItem->PppMsg.InterfaceInfo;
  1849. if ( ROUTER_IF_TYPE_FULL_ROUTER == pPcb->pBcb->InterfaceInfo.IfType )
  1850. {
  1851. if ( NULL == pPcb->pBcb->szPhonebookPath )
  1852. {
  1853. dwRetCode = GetRouterPhoneBook( &(pPcb->pBcb->szPhonebookPath) );
  1854. if ( dwRetCode != NO_ERROR )
  1855. {
  1856. pPcb->LcpCb.dwError = dwRetCode;
  1857. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1858. return;
  1859. }
  1860. }
  1861. if ( NULL == pPcb->pBcb->szEntryName )
  1862. {
  1863. pPcb->pBcb->szEntryName =
  1864. LocalAlloc( LPTR, (lstrlen(pPcb->pBcb->szRemoteUserName)+1) *
  1865. sizeof(CHAR));
  1866. if ( NULL == pPcb->pBcb->szEntryName )
  1867. {
  1868. pPcb->LcpCb.dwError = GetLastError();
  1869. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1870. return;
  1871. }
  1872. lstrcpy( pPcb->pBcb->szEntryName, pPcb->pBcb->szRemoteUserName );
  1873. }
  1874. //
  1875. // Even if an error occurs, we don't have to free the alloc'd strings.
  1876. // They will be freed when pPcb is freed.
  1877. //
  1878. }
  1879. //
  1880. // If we are not bundled.
  1881. //
  1882. if ( !(pPcb->fFlags & PCBFLAG_IS_BUNDLED) )
  1883. {
  1884. dwRetCode = InitializeNCPs( pPcb, pPcb->ConfigInfo.dwConfigMask );
  1885. if ( dwRetCode != NO_ERROR )
  1886. {
  1887. pPcb->LcpCb.dwError = dwRetCode;
  1888. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1889. return;
  1890. }
  1891. //
  1892. // Start negotiating the NCPs
  1893. //
  1894. StartNegotiatingNCPs( pPcb );
  1895. return;
  1896. }
  1897. //
  1898. // If we are bundled.
  1899. // If negotiation has not started then start it, otherwise wait for it to
  1900. // finish.
  1901. //
  1902. dwNcpState = QueryBundleNCPState( pPcb );
  1903. switch ( dwNcpState )
  1904. {
  1905. case NCP_UP:
  1906. NotifyCallerOfBundledProjection( pPcb );
  1907. RemoveFromTimerQ( pPcb->dwPortId,
  1908. 0,
  1909. 0,
  1910. FALSE,
  1911. TIMER_EVENT_NEGOTIATETIME );
  1912. StartAutoDisconnectForPort( pPcb );
  1913. StartLCPEchoForPort ( pPcb );
  1914. break;
  1915. case NCP_CONFIGURING:
  1916. PppLog( 2, "Bundle NCPs not done for port %d, wait", pPcb->hPort );
  1917. break;
  1918. case NCP_DOWN:
  1919. pPcb->LcpCb.dwError = ERROR_PPP_NO_PROTOCOLS_CONFIGURED;
  1920. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1921. break;
  1922. case NCP_DEAD:
  1923. dwRetCode = InitializeNCPs( pPcb, pPcb->ConfigInfo.dwConfigMask );
  1924. if ( dwRetCode != NO_ERROR )
  1925. {
  1926. pPcb->LcpCb.dwError = dwRetCode;
  1927. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1928. return;
  1929. }
  1930. //
  1931. // Start NCPs for the bundle.
  1932. //
  1933. StartNegotiatingNCPs( pPcb );
  1934. break;
  1935. }
  1936. }
  1937. //**
  1938. //
  1939. // Call: ProcessAuthInfo
  1940. //
  1941. // Returns: None
  1942. //
  1943. // Description: Processes the information returned by the back-end
  1944. // authentication module
  1945. //
  1946. VOID
  1947. ProcessAuthInfo(
  1948. IN PCB_WORK_ITEM * pWorkItem
  1949. )
  1950. {
  1951. PCB * pPcb = GetPCBPointerFromhPort( pWorkItem->hPort );
  1952. LCPCB * pLcpCb = NULL;
  1953. DWORD CpIndex;
  1954. PPPAP_INPUT PppApInput;
  1955. DWORD dwRetCode;
  1956. //
  1957. // If we couldn't find the PCB because the port is disconnected
  1958. //
  1959. if ( pPcb == NULL )
  1960. {
  1961. if ( pWorkItem->PppMsg.AuthInfo.pOutAttributes != NULL )
  1962. {
  1963. PppConfigInfo.RasAuthProviderFreeAttributes(
  1964. pWorkItem->PppMsg.AuthInfo.pOutAttributes );
  1965. }
  1966. return;
  1967. }
  1968. pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  1969. //
  1970. // If this is a different instance of this port, ie port was disconnected
  1971. // and reconnected.
  1972. //
  1973. if ( pPcb->dwPortId != pWorkItem->dwPortId )
  1974. {
  1975. if ( pWorkItem->PppMsg.AuthInfo.pOutAttributes != NULL )
  1976. {
  1977. PppConfigInfo.RasAuthProviderFreeAttributes(
  1978. pWorkItem->PppMsg.AuthInfo.pOutAttributes );
  1979. }
  1980. return;
  1981. }
  1982. CpIndex = GetCpIndexFromProtocol( pWorkItem->Protocol );
  1983. //
  1984. // If we renegotiated a different authentication protocol
  1985. //
  1986. if ( CpIndex != GetCpIndexFromProtocol( pLcpCb->Local.Work.AP ) )
  1987. {
  1988. PppConfigInfo.RasAuthProviderFreeAttributes(
  1989. pWorkItem->PppMsg.AuthInfo.pOutAttributes );
  1990. return;
  1991. }
  1992. //
  1993. // If the id of this request doesn't match
  1994. //
  1995. if ( pWorkItem->PppMsg.AuthInfo.dwId != pPcb->dwOutstandingAuthRequestId )
  1996. {
  1997. if ( pWorkItem->PppMsg.AuthInfo.pOutAttributes != NULL )
  1998. {
  1999. PppConfigInfo.RasAuthProviderFreeAttributes(
  2000. pWorkItem->PppMsg.AuthInfo.pOutAttributes );
  2001. }
  2002. return;
  2003. }
  2004. if ( 0 == pLcpCb->Local.Work.AP )
  2005. {
  2006. do
  2007. {
  2008. dwRetCode = NO_ERROR;
  2009. if ( NO_ERROR != pWorkItem->PppMsg.AuthInfo.dwError )
  2010. {
  2011. dwRetCode = pWorkItem->PppMsg.AuthInfo.dwError;
  2012. break;
  2013. }
  2014. if ( NO_ERROR != pWorkItem->PppMsg.AuthInfo.dwResultCode )
  2015. {
  2016. dwRetCode = pWorkItem->PppMsg.AuthInfo.dwResultCode;
  2017. break;
  2018. }
  2019. pPcb->pAuthenticatorAttributes =
  2020. pWorkItem->PppMsg.AuthInfo.pOutAttributes;
  2021. //
  2022. // Set all the user connection parameters authorized by the
  2023. // back-end authenticator
  2024. //
  2025. dwRetCode = SetUserAuthorizedAttributes(
  2026. pPcb,
  2027. pPcb->pAuthenticatorAttributes,
  2028. TRUE,
  2029. NULL,
  2030. NULL );
  2031. if ( dwRetCode != NO_ERROR )
  2032. {
  2033. break;
  2034. }
  2035. FsmThisLayerUp( pPcb, CpIndex );
  2036. }
  2037. while ( FALSE );
  2038. if ( NO_ERROR != dwRetCode )
  2039. {
  2040. pPcb->LcpCb.dwError = dwRetCode;
  2041. NotifyCallerOfFailure( pPcb, dwRetCode );
  2042. if ( pWorkItem->PppMsg.AuthInfo.pOutAttributes != NULL )
  2043. {
  2044. PppConfigInfo.RasAuthProviderFreeAttributes(
  2045. pWorkItem->PppMsg.AuthInfo.pOutAttributes );
  2046. }
  2047. }
  2048. return;
  2049. }
  2050. //
  2051. // If this authenticator is not configurable
  2052. //
  2053. if ( !pPcb->AuthenticatorCb.fConfigurable )
  2054. {
  2055. if ( pWorkItem->PppMsg.AuthInfo.pOutAttributes != NULL )
  2056. {
  2057. PppConfigInfo.RasAuthProviderFreeAttributes(
  2058. pWorkItem->PppMsg.AuthInfo.pOutAttributes );
  2059. }
  2060. return;
  2061. }
  2062. //
  2063. // Free previously allocated attributes if any.
  2064. //
  2065. if ( pPcb->pAuthenticatorAttributes != NULL )
  2066. {
  2067. PppConfigInfo.RasAuthProviderFreeAttributes(
  2068. pPcb->pAuthenticatorAttributes );
  2069. pPcb->pAuthenticatorAttributes = NULL;
  2070. }
  2071. ZeroMemory( &PppApInput, sizeof( PppApInput ) );
  2072. PppApInput.dwAuthResultCode = pWorkItem->PppMsg.AuthInfo.dwResultCode;
  2073. PppApInput.dwAuthError = pWorkItem->PppMsg.AuthInfo.dwError;
  2074. PppApInput.fAuthenticationComplete = TRUE;
  2075. pPcb->pAuthenticatorAttributes =
  2076. pWorkItem->PppMsg.AuthInfo.pOutAttributes;
  2077. PppApInput.pAttributesFromAuthenticator =
  2078. pWorkItem->PppMsg.AuthInfo.pOutAttributes;
  2079. ApWork( pPcb, CpIndex, NULL, &PppApInput, TRUE );
  2080. }
  2081. //**
  2082. //
  2083. // Call: ProcessDhcpInform
  2084. //
  2085. // Returns: None
  2086. //
  2087. // Description: Processes the information returned by the call to
  2088. // DhcpRequestOptions
  2089. //
  2090. VOID
  2091. ProcessDhcpInform(
  2092. IN PCB_WORK_ITEM * pWorkItem
  2093. )
  2094. {
  2095. DWORD dwErr;
  2096. PCB* pPcb;
  2097. HPORT hPort;
  2098. DWORD IPCPIndex;
  2099. CPCB* pCpCb;
  2100. BOOL fFree = TRUE;
  2101. PppLog( 2, "ProcessDhcpInform" );
  2102. dwErr = RasBundleGetPort(NULL, pWorkItem->hConnection, &hPort );
  2103. if ( dwErr != NO_ERROR )
  2104. {
  2105. PppLog( 2, "RasBundleGetPort(%d) failed: %d",
  2106. pWorkItem->hConnection, dwErr );
  2107. goto LDone;
  2108. }
  2109. if ( ( pPcb = GetPCBPointerFromhPort( hPort ) ) == NULL )
  2110. {
  2111. PppLog( 2, "GetPCBPointerFromhPort(%d) failed", hPort );
  2112. goto LDone;
  2113. }
  2114. IPCPIndex = GetCpIndexFromProtocol( PPP_IPCP_PROTOCOL );
  2115. if ( IPCPIndex == (DWORD)-1 )
  2116. {
  2117. PppLog( 2, "GetCpIndexFromProtocol(IPCP) failed" );
  2118. goto LDone;
  2119. }
  2120. pCpCb = GetPointerToCPCB( pPcb, IPCPIndex );
  2121. if ( NULL == pCpCb )
  2122. {
  2123. PppLog( 2, "GetPointerToCPCB(IPCP) failed" );
  2124. goto LDone;
  2125. }
  2126. if ( PppConfigInfo.RasIpcpDhcpInform != NULL )
  2127. {
  2128. dwErr = PppConfigInfo.RasIpcpDhcpInform(
  2129. pCpCb->pWorkBuf,
  2130. &(pWorkItem->PppMsg.DhcpInform) );
  2131. if ( NO_ERROR == dwErr )
  2132. {
  2133. fFree = FALSE;
  2134. }
  2135. }
  2136. LDone:
  2137. LocalFree(pWorkItem->PppMsg.DhcpInform.wszDevice);
  2138. LocalFree(pWorkItem->PppMsg.DhcpInform.szDomainName);
  2139. if (fFree)
  2140. {
  2141. LocalFree(pWorkItem->PppMsg.DhcpInform.pdwDNSAddresses);
  2142. }
  2143. }
  2144. //**
  2145. //
  2146. // Call: ProcessIpAddressLeaseExpired
  2147. //
  2148. // Returns: None
  2149. //
  2150. // Description: Processes the expiry of the lease of an Ip address from a
  2151. // Dhcp server.
  2152. //
  2153. VOID
  2154. ProcessIpAddressLeaseExpired(
  2155. IN PCB_WORK_ITEM * pWorkItem
  2156. )
  2157. {
  2158. PppLog( 2, "ProcessIpAddressLeaseExpired" );
  2159. if ( PppConfigInfo.RasIphlpDhcpCallback != NULL )
  2160. {
  2161. PppConfigInfo.RasIphlpDhcpCallback(
  2162. pWorkItem->PppMsg.IpAddressLeaseExpired.nboIpAddr );
  2163. }
  2164. }
  2165. //**
  2166. //
  2167. // Call: ProcessEapUIData
  2168. //
  2169. // Returns: None
  2170. //
  2171. // Description:
  2172. //
  2173. VOID
  2174. ProcessEapUIData(
  2175. IN PCB_WORK_ITEM * pWorkItem
  2176. )
  2177. {
  2178. PPPAP_INPUT PppApInput;
  2179. PCB * pPcb = GetPCBPointerFromhPort( pWorkItem->hPort );
  2180. LCPCB * pLcpCb;
  2181. if ( pPcb == (PCB*)NULL )
  2182. {
  2183. return;
  2184. }
  2185. if ( pPcb->PppPhase != PPP_AP )
  2186. {
  2187. return;
  2188. }
  2189. pLcpCb = (LCPCB *)(pPcb->LcpCb.pWorkBuf);
  2190. ZeroMemory( &PppApInput, sizeof( PppApInput ) );
  2191. PppApInput.fEapUIDataReceived = TRUE;
  2192. PppApInput.EapUIData = pWorkItem->PppMsg.EapUIData;
  2193. ApWork( pPcb,
  2194. GetCpIndexFromProtocol( pLcpCb->Remote.Work.AP ),
  2195. NULL,
  2196. &PppApInput,
  2197. FALSE );
  2198. //
  2199. // EapUIData.pEapUIData is allocated by rasman and freed by engine.
  2200. // raseap.c must not free it.
  2201. //
  2202. LocalFree( pWorkItem->PppMsg.EapUIData.pEapUIData );
  2203. }
  2204. //**
  2205. //
  2206. // Call: ProcessChangeNotification
  2207. //
  2208. // Returns: NO_ERROR - Success
  2209. // Non-zero returns - Failure
  2210. //
  2211. // Description: Will be called whenever there is a change in configuration
  2212. // that has to be picked up
  2213. //
  2214. VOID
  2215. ProcessChangeNotification(
  2216. IN PCB_WORK_ITEM * pWorkItem
  2217. )
  2218. {
  2219. DWORD dwIndex;
  2220. DWORD dwRetCode;
  2221. DWORD cTotalNumProtocols;
  2222. PppLog( 2, "Processing change notification event" );
  2223. //
  2224. // Re-read all the ppp key values
  2225. //
  2226. ReadPPPKeyValues( PppConfigInfo.hKeyPpp );
  2227. LoadParserDll( PppConfigInfo.hKeyPpp );
  2228. //
  2229. // Walk thru the CP table and invoke the change notification method
  2230. // for each one.
  2231. //
  2232. cTotalNumProtocols = PppConfigInfo.NumberOfCPs + PppConfigInfo.NumberOfAPs;
  2233. for ( dwIndex = 0; dwIndex < cTotalNumProtocols; dwIndex++ )
  2234. {
  2235. if ( ( CpTable[dwIndex].fFlags & PPPCP_FLAG_AVAILABLE ) &&
  2236. ( CpTable[dwIndex].CpInfo.RasCpChangeNotification != NULL ) )
  2237. {
  2238. dwRetCode = CpTable[dwIndex].CpInfo.RasCpChangeNotification();
  2239. if ( dwRetCode != NO_ERROR )
  2240. {
  2241. PppLog( 2,
  2242. "ChangeNotification for Protocol 0x%x failed, error=%d",
  2243. CpTable[dwIndex].CpInfo.Protocol, dwRetCode );
  2244. }
  2245. }
  2246. }
  2247. }
  2248. //**
  2249. //
  2250. // Call: ProcessProtocolEvent
  2251. //
  2252. // Returns: None
  2253. //
  2254. // Description: Will be called whenever a protocol is installed or uninstalled.
  2255. //
  2256. VOID
  2257. ProcessProtocolEvent(
  2258. IN PCB_WORK_ITEM * pWorkItem
  2259. )
  2260. {
  2261. DWORD dwIndex;
  2262. DWORD dwProtocol;
  2263. DWORD cTotalNumProtocols;
  2264. CHAR* szSubKey;
  2265. CHAR* SubStringArray[2];
  2266. DWORD dwError;
  2267. PppLog( 2, "Processing protocol event" );
  2268. //
  2269. // Ignore any message other than one saying that a protocol was installed.
  2270. //
  2271. if ( pWorkItem->PppMsg.ProtocolEvent.ulFlags != RASMAN_PROTOCOL_ADDED )
  2272. {
  2273. if ( ( pWorkItem->PppMsg.ProtocolEvent.ulFlags ==
  2274. RASMAN_PROTOCOL_REMOVED )
  2275. && ( pWorkItem->PppMsg.ProtocolEvent.usProtocolType == IP ) )
  2276. {
  2277. //
  2278. // NT5 Bug 398226. When PSched is installed/uninstalled, IP is
  2279. // unbound from wanarp so that PSched can be bound/unbound between
  2280. // IP and wanarp. The server adapter needs to be mapped again.
  2281. //
  2282. RasSrvrAdapterUnmapped();
  2283. }
  2284. return;
  2285. }
  2286. switch ( pWorkItem->PppMsg.ProtocolEvent.usProtocolType )
  2287. {
  2288. case IP:
  2289. dwProtocol = PPP_IPCP_PROTOCOL;
  2290. PppLog( 2, "Adding IP" );
  2291. break;
  2292. case IPX:
  2293. dwProtocol = PPP_IPXCP_PROTOCOL;
  2294. PppLog( 2, "Adding IPX" );
  2295. break;
  2296. case ASYBEUI:
  2297. dwProtocol = PPP_NBFCP_PROTOCOL;
  2298. PppLog( 2, "Adding ASYBEUI" );
  2299. break;
  2300. case APPLETALK:
  2301. dwProtocol = PPP_ATCP_PROTOCOL;
  2302. PppLog( 2, "Adding APPLETALK" );
  2303. break;
  2304. default:
  2305. return;
  2306. }
  2307. cTotalNumProtocols = PppConfigInfo.NumberOfCPs + PppConfigInfo.NumberOfAPs;
  2308. for ( dwIndex = 0; dwIndex < cTotalNumProtocols; dwIndex++ )
  2309. {
  2310. if ( dwProtocol == CpTable[dwIndex].CpInfo.Protocol )
  2311. {
  2312. if ( !( CpTable[dwIndex].fFlags & PPPCP_FLAG_INIT_CALLED )
  2313. && CpTable[dwIndex].CpInfo.RasCpInit )
  2314. {
  2315. PppLog( 1, "RasCpInit(%x, TRUE)", dwProtocol );
  2316. dwError = CpTable[dwIndex].CpInfo.RasCpInit(
  2317. TRUE /* fInitialize */ );
  2318. CpTable[dwIndex].fFlags |= PPPCP_FLAG_INIT_CALLED;
  2319. if ( NO_ERROR != dwError )
  2320. {
  2321. SubStringArray[0] = CpTable[dwIndex].CpInfo.SzProtocolName;
  2322. SubStringArray[1] = "(unknown)";
  2323. PppLogErrorString(
  2324. ROUTERLOG_PPPCP_INIT_ERROR,
  2325. 2,
  2326. SubStringArray,
  2327. dwError,
  2328. 2 );
  2329. PppLog(
  2330. 1,
  2331. "RasCpInit(TRUE) for protocol 0x%x returned error %d",
  2332. dwProtocol, dwError );
  2333. }
  2334. else
  2335. {
  2336. CpTable[dwIndex].fFlags |= PPPCP_FLAG_AVAILABLE;
  2337. }
  2338. }
  2339. return;
  2340. }
  2341. }
  2342. }
  2343. VOID
  2344. ProcessRemoveQuarantine(
  2345. IN PCB_WORK_ITEM *pWorkItem
  2346. )
  2347. {
  2348. BCB *pBcb = GetBCBPointerFromhConnection( pWorkItem->hConnection );
  2349. DWORD dwForIndex;
  2350. PCB *pPcb;
  2351. //
  2352. // If we had added quarantine session timeouts for ports on this
  2353. // bundle, remove the quarantine session timeout and add the
  2354. // regular session timeout
  2355. //
  2356. if( (NULL != pBcb)
  2357. && (pBcb->fFlags & BCBFLAG_QUARANTINE_TIMEOUT))
  2358. {
  2359. for (dwForIndex = 0;
  2360. dwForIndex < pBcb->dwPpcbArraySize;
  2361. dwForIndex++)
  2362. {
  2363. pPcb = pBcb->ppPcb[dwForIndex];
  2364. if ( NULL == pPcb )
  2365. {
  2366. continue;
  2367. }
  2368. //
  2369. // Remove any previous session-disconnect time item from the
  2370. // queue if there was one.
  2371. //
  2372. PppLog(2,
  2373. "ProcessRemoveQuarantine: removing quarantine-session-timer");
  2374. RemoveFromTimerQ( pPcb->dwPortId,
  2375. 0,
  2376. 0,
  2377. FALSE,
  2378. TIMER_EVENT_SESSION_TIMEOUT );
  2379. if(pPcb->dwSessionTimeout > 0)
  2380. {
  2381. PppLog(2,
  2382. "ProcessRemoveQuarantine: adding session timeout %d",
  2383. pPcb->dwSessionTimeout);
  2384. InsertInTimerQ( pPcb->dwPortId,
  2385. pPcb->hPort,
  2386. 0,
  2387. 0,
  2388. FALSE,
  2389. TIMER_EVENT_SESSION_TIMEOUT,
  2390. pPcb->dwSessionTimeout );
  2391. }
  2392. }
  2393. pBcb->fFlags &= ~BCBFLAG_QUARANTINE_TIMEOUT;
  2394. }
  2395. return;
  2396. }
  2397. VOID
  2398. ProcessResumeFromHibernate(
  2399. IN PCB_WORK_ITEM *pWorkItem
  2400. )
  2401. {
  2402. PppConfigInfo.fFlags |= PPPCONFIG_FLAG_RESUME;
  2403. }