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.

4088 lines
98 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. wanarp\adapter.c
  5. Abstract:
  6. The file contains the section interface of WANARP to the TCP/IP stack
  7. that is involved with Binding Notification and Querying/Setting
  8. information for interfaces
  9. Revision History:
  10. AmritanR
  11. --*/
  12. #define __FILE_SIG__ ADAPTER_SIG
  13. #include "inc.h"
  14. #pragma hdrstop
  15. NDIS_HANDLE g_nhUnbindContext;
  16. NDIS_HANDLE g_nhBindContext;
  17. NDIS_STATUS g_nsStatus = 0;
  18. NDIS_STATUS g_nsError = 0;
  19. BOOLEAN g_bRemovalInProgress;
  20. WORK_QUEUE_ITEM g_wqiWorkItem;
  21. WORK_QUEUE_ITEM g_wqiNdisWorkItem;
  22. const GUID ServerInterfaceGuid = {0x6e06f030, 0x7526, 0x11d2, {0xba, 0xf4, 0x00, 0x60, 0x08, 0x15, 0xa4, 0xbd}};
  23. extern
  24. VOID
  25. IPDelayedNdisReEnumerateBindings(
  26. CTEEvent *Event,
  27. PVOID Context
  28. );
  29. BOOLEAN
  30. IsBindingPresent(
  31. IN GUID *pGuid
  32. );
  33. VOID
  34. WanNdisBindAdapter(
  35. PNDIS_STATUS pnsRetStatus,
  36. NDIS_HANDLE nhBindContext,
  37. PNDIS_STRING nsAdapterName,
  38. PVOID pvSystemSpecific1,
  39. PVOID pvSystemSpecific2
  40. )
  41. {
  42. RtAssert(FALSE);
  43. }
  44. INT
  45. WanIpBindAdapter(
  46. IN PNDIS_STATUS pnsRetStatus,
  47. IN NDIS_HANDLE nhBindContext,
  48. IN PNDIS_STRING pnsAdapterName,
  49. IN PVOID pvSS1,
  50. IN PVOID pvSS2
  51. )
  52. /*++
  53. Routine Description:
  54. Called by IP to bind an adapter. We open the binding and then do
  55. all the other work in complete handler
  56. Locks:
  57. The routine acquires the global adapter list lock, so it is not
  58. PAGEABLE.
  59. Arguments:
  60. Return Value:
  61. --*/
  62. {
  63. NDIS_STATUS nsStatus;
  64. KIRQL kiIrql;
  65. LONG lResult;
  66. #if DBG
  67. ANSI_STRING asTempAnsiString;
  68. #endif
  69. TraceEnter(ADPT, "WanIpBindAdapter");
  70. //
  71. // Serialize Bind, Unbind code
  72. //
  73. WanpAcquireResource(&g_wrBindMutex);
  74. RtAcquireSpinLock(&g_rlStateLock,
  75. &kiIrql);
  76. //
  77. // See if we have already received a BIND call or are in the process
  78. // of servicing a bind
  79. //
  80. if(g_lBindRcvd isnot 0)
  81. {
  82. //
  83. // We have already received a bind call
  84. //
  85. RtAssert(g_lBindRcvd is 1);
  86. RtReleaseSpinLock(&g_rlStateLock,
  87. kiIrql);
  88. WanpReleaseResource(&g_wrBindMutex);
  89. Trace(ADPT,ERROR,
  90. ("WanIpBindAdapter: Duplicate bind call\n"));
  91. *pnsRetStatus = NDIS_STATUS_SUCCESS;
  92. TraceLeave(ADPT, "WanIpBindAdapter");
  93. return FALSE;
  94. }
  95. //
  96. // Set BindRcvd to 1 so that we dont service any binds till we
  97. // get done
  98. //
  99. g_lBindRcvd = 1;
  100. RtReleaseSpinLock(&g_rlStateLock,
  101. kiIrql);
  102. Trace(ADPT, INFO,
  103. ("WanIpBindAdapter: IP called to bind to adapter %S\n",
  104. pnsAdapterName->Buffer));
  105. //
  106. // We need to open this adapter as our NDISWAN binding
  107. //
  108. g_nhBindContext = nhBindContext;
  109. nsStatus = WanpOpenNdisWan(pnsAdapterName,
  110. (PNDIS_STRING)pvSS1);
  111. if((nsStatus isnot NDIS_STATUS_SUCCESS) and
  112. (nsStatus isnot NDIS_STATUS_PENDING))
  113. {
  114. RtAcquireSpinLock(&g_rlStateLock,
  115. &kiIrql);
  116. g_lBindRcvd = 0;
  117. RtReleaseSpinLock(&g_rlStateLock,
  118. kiIrql);
  119. Trace(ADPT, ERROR,
  120. ("WanIpBindAdapter: Error %x opening NDISWAN on %S\n",
  121. nsStatus,
  122. pnsAdapterName->Buffer));
  123. }
  124. *pnsRetStatus = nsStatus;
  125. //
  126. // At this point we are done. If the operation finished synchronously
  127. // then our OpenAdapterComplete handler has already been called
  128. // Otherwise stuff will happen later
  129. //
  130. TraceLeave(ADPT, "WanIpBindAdapter");
  131. return TRUE;
  132. }
  133. #pragma alloc_text(PAGE, WanpOpenNdisWan)
  134. NDIS_STATUS
  135. WanpOpenNdisWan(
  136. PNDIS_STRING pnsAdapterName,
  137. PNDIS_STRING pnsSystemSpecific1
  138. )
  139. /*++
  140. Routine Description:
  141. This routine opens the ndiswan adapter. It also stores the SS1 string
  142. in a global for use by the completion routine
  143. Locks:
  144. Called with the g_wrBindMutex held exclusively
  145. Arguments:
  146. pusBindName Name of the bindings
  147. pnsSystemSpecific1 The SS1 passed in the bind call from IP
  148. Return Value:
  149. --*/
  150. {
  151. NDIS_STATUS nsStatus, nsError;
  152. UINT i;
  153. NDIS_MEDIUM MediaArray[] = {NdisMediumWan};
  154. PWCHAR pwcNameBuffer, pwcStringBuffer;
  155. PBYTE pbyBuffer;
  156. PAGED_CODE();
  157. TraceEnter(ADPT,"OpenNdiswan");
  158. //
  159. // Save a copy of the NDIS binding name
  160. // Increase the length by 1 so that we can NULL terminate it for
  161. // easy printing
  162. //
  163. pnsAdapterName->Length += sizeof(WCHAR);
  164. g_usNdiswanBindName.Buffer = RtAllocate(NonPagedPool,
  165. pnsAdapterName->Length,
  166. WAN_STRING_TAG);
  167. if(g_usNdiswanBindName.Buffer is NULL)
  168. {
  169. Trace(GLOBAL, ERROR,
  170. ("OpenNdiswan: Unable to allocate %d bytes\n",
  171. pnsAdapterName->Length));
  172. g_nhBindContext = NULL;
  173. WanpReleaseResource(&g_wrBindMutex);
  174. return STATUS_INSUFFICIENT_RESOURCES;
  175. }
  176. g_usNdiswanBindName.MaximumLength = pnsAdapterName->Length;
  177. RtlUpcaseUnicodeString(&g_usNdiswanBindName,
  178. pnsAdapterName,
  179. FALSE);
  180. pnsAdapterName->Length -= sizeof(WCHAR);
  181. g_usNdiswanBindName.Length -= sizeof(WCHAR);
  182. //
  183. // NULL terminate
  184. //
  185. g_usNdiswanBindName.Buffer[g_usNdiswanBindName.MaximumLength/sizeof(WCHAR) - 1] = UNICODE_NULL;
  186. //
  187. // Save a copy of SS1
  188. //
  189. pwcStringBuffer = RtAllocate(NonPagedPool,
  190. pnsSystemSpecific1->MaximumLength,
  191. WAN_STRING_TAG);
  192. if(pwcStringBuffer is NULL)
  193. {
  194. RtFree(g_usNdiswanBindName.Buffer);
  195. g_usNdiswanBindName.Buffer = NULL;
  196. g_usNdiswanBindName.MaximumLength = 0;
  197. g_usNdiswanBindName.Length = 0;
  198. g_nhBindContext = NULL;
  199. WanpReleaseResource(&g_wrBindMutex);
  200. return NDIS_STATUS_RESOURCES;
  201. }
  202. RtlZeroMemory(pwcStringBuffer,
  203. pnsSystemSpecific1->MaximumLength);
  204. //
  205. // Save a copy of the SS1 string
  206. //
  207. g_nsSystemSpecific1.MaximumLength = pnsSystemSpecific1->MaximumLength;
  208. g_nsSystemSpecific1.Length = pnsSystemSpecific1->Length;
  209. g_nsSystemSpecific1.Buffer = pwcStringBuffer;
  210. RtlCopyMemory(g_nsSystemSpecific1.Buffer,
  211. pnsSystemSpecific1->Buffer,
  212. pnsSystemSpecific1->Length);
  213. //
  214. // Open the NDIS adapter.
  215. //
  216. Trace(ADPT, INFO,
  217. ("OpenNdiswan: Opening %S\n", g_usNdiswanBindName.Buffer));
  218. //
  219. // Medium index
  220. //
  221. i = 0;
  222. #define MAX_MEDIA 1
  223. NdisOpenAdapter(&nsStatus,
  224. &nsError,
  225. &g_nhNdiswanBinding,
  226. &i,
  227. MediaArray,
  228. MAX_MEDIA,
  229. g_nhWanarpProtoHandle,
  230. (NDIS_HANDLE)0x0CABB1E5,
  231. pnsAdapterName,
  232. 0,
  233. NULL);
  234. #undef MAX_MEDIA
  235. if(nsStatus isnot NDIS_STATUS_PENDING)
  236. {
  237. //
  238. // we always return PENDING to NDIS because we need to
  239. // do a switch to system thread when we are done setting OIDS to
  240. // NDISWAN. So call out completion routine here
  241. //
  242. WanNdisOpenAdapterComplete((NDIS_HANDLE)0x0CABB1E5,
  243. nsStatus,
  244. nsError);
  245. nsStatus = NDIS_STATUS_PENDING;
  246. }
  247. TraceLeave(ADPT, "OpenNdiswan");
  248. return nsStatus;
  249. }
  250. #pragma alloc_text (PAGE, WanNdisOpenAdapterComplete)
  251. VOID
  252. WanNdisOpenAdapterComplete(
  253. NDIS_HANDLE nhHandle,
  254. NDIS_STATUS nsStatus,
  255. NDIS_STATUS nsError
  256. )
  257. /*++
  258. Routine Description:
  259. Completion routine called by NDIS when it is done opening the NDISWAN
  260. binding
  261. If the open was successful, we start the train of requests
  262. Locks:
  263. Called either synchronously or off a worker thread with the g_wrBindMutex
  264. This routine needs to release the resource and set g_lBindRcvd
  265. Arguments:
  266. nhHandle
  267. nsStatus
  268. nsError
  269. Return Value:
  270. None
  271. --*/
  272. {
  273. NDIS_STATUS nsResult;
  274. BYTE rgbyProtocolId[ARP_802_ADDR_LENGTH] = {0x80,
  275. 0x00,
  276. 0x00,
  277. 0x00,
  278. 0x08,
  279. 0x00};
  280. PWANARP_NDIS_REQUEST_CONTEXT pRequestContext;
  281. TraceEnter(ADPT,"NdisOpenAdapterComplete");
  282. PAGED_CODE();
  283. RtAssert(nhHandle is (NDIS_HANDLE)0x0CABB1E5);
  284. //
  285. // If we couldnt open the NDIS wan binding, free all the resources
  286. // and return
  287. //
  288. if(nsStatus isnot NDIS_STATUS_SUCCESS)
  289. {
  290. Trace(ADPT, ERROR,
  291. ("OpenAdapterComplete: Status %x\n", nsStatus));
  292. RtAssert(g_nhBindContext isnot NULL);
  293. NdisCompleteBindAdapter(g_nhBindContext,
  294. nsStatus,
  295. nsError);
  296. g_nhBindContext = NULL;
  297. WanpFreeBindResourcesAndReleaseLock();
  298. return;
  299. }
  300. //
  301. // From here on, the NDISWAN adapter is opened, so to cleanup resources
  302. // we must call CloseNdisWan()
  303. //
  304. pRequestContext = RtAllocate(NonPagedPool,
  305. sizeof(WANARP_NDIS_REQUEST_CONTEXT),
  306. WAN_REQUEST_TAG);
  307. if(pRequestContext is NULL)
  308. {
  309. RtAssert(g_nhBindContext isnot NULL);
  310. #if 0
  311. NdisCompleteBindAdapter(g_nhBindContext,
  312. nsStatus,
  313. nsError);
  314. g_nhBindContext = NULL;
  315. #endif
  316. g_nsStatus = g_nsError = NDIS_STATUS_RESOURCES;
  317. ExInitializeWorkItem(&g_wqiNdisWorkItem,
  318. WanpCloseNdisWan,
  319. NULL);
  320. ExQueueWorkItem(&g_wqiNdisWorkItem,
  321. DelayedWorkQueue);
  322. // WanpCloseNdisWan(NULL);
  323. Trace(ADPT, ERROR,
  324. ("NdisOpenAdapterComplete: Couldnt allocate memory for request context\n"));
  325. return;
  326. }
  327. //
  328. // Set protocol type
  329. //
  330. RtlCopyMemory(pRequestContext->rgbyProtocolId,
  331. rgbyProtocolId,
  332. sizeof(rgbyProtocolId));
  333. nsResult = WanpDoNdisRequest(NdisRequestSetInformation,
  334. OID_WAN_PROTOCOL_TYPE,
  335. pRequestContext->rgbyProtocolId,
  336. sizeof(pRequestContext->rgbyProtocolId),
  337. pRequestContext,
  338. WanpSetProtocolTypeComplete);
  339. if(nsResult isnot NDIS_STATUS_PENDING)
  340. {
  341. //
  342. // No need to call the completion routine, since DoNdisRequest
  343. // always calls it
  344. //
  345. Trace(ADPT, ERROR,
  346. ("NdisOpenAdapterComplete: %x from OID_WAN_PROTOCOL_TYPE\n",
  347. nsResult));
  348. }
  349. TraceLeave(ADPT,"NdisOpenAdapterComplete");
  350. }
  351. VOID
  352. WanpSetProtocolTypeComplete(
  353. NDIS_HANDLE nhHandle,
  354. struct _WANARP_NDIS_REQUEST_CONTEXT *pRequestContext,
  355. NDIS_STATUS nsStatus
  356. )
  357. /*++
  358. Routine Description:
  359. Completion handler called when we are done with setting
  360. OID_WAN_PROTOCOL_TYPE
  361. Locks:
  362. None
  363. Arguments:
  364. nhHandle Binding for the adapter to which the request was sent
  365. pRequestContext Pointer to the request context
  366. nsStatus Result of the request
  367. Return Value:
  368. None
  369. --*/
  370. {
  371. NDIS_STATUS nsResult;
  372. TraceEnter(ADPT,"SetProtocolTypeComplete");
  373. if(nsStatus isnot NDIS_STATUS_SUCCESS)
  374. {
  375. Trace(ADPT, ERROR,
  376. ("SetProtocolTypeComplete: Status %x\n", nsStatus));
  377. WanpLastOidComplete(nhHandle,
  378. pRequestContext,
  379. nsStatus);
  380. return;
  381. }
  382. //
  383. // Set lookahead size
  384. //
  385. pRequestContext->ulLookahead = WANARP_LOOKAHEAD_SIZE;
  386. nsResult = WanpDoNdisRequest(NdisRequestSetInformation,
  387. OID_GEN_CURRENT_LOOKAHEAD,
  388. &(pRequestContext->ulLookahead),
  389. sizeof(pRequestContext->ulLookahead),
  390. pRequestContext,
  391. WanpSetLookaheadComplete);
  392. if(nsResult isnot NDIS_STATUS_PENDING)
  393. {
  394. Trace(ADPT, ERROR,
  395. ("SetProtocolTypeComplete: %x from OID_GEN_CURRENT_LOOKAHEAD\n",
  396. nsResult));
  397. }
  398. TraceLeave(ADPT,"SetProtocolTypeComplete");
  399. }
  400. VOID
  401. WanpSetLookaheadComplete(
  402. NDIS_HANDLE nhHandle,
  403. struct _WANARP_NDIS_REQUEST_CONTEXT *pRequestContext,
  404. NDIS_STATUS nsStatus
  405. )
  406. /*++
  407. Routine Description:
  408. Completion handler called when we are done with setting
  409. OID_GEN_CURRENT_LOOKAHEAD
  410. Locks:
  411. None
  412. Arguments:
  413. nhHandle Binding for the adapter to which the request was sent
  414. pRequestContext Pointer to the request context
  415. nsStatus Result of the request
  416. Return Value:
  417. None
  418. --*/
  419. {
  420. NDIS_STATUS nsResult;
  421. TraceEnter(ADPT,"SetLookaheadComplete");
  422. if(nsStatus isnot NDIS_STATUS_SUCCESS)
  423. {
  424. Trace(ADPT, ERROR,
  425. ("SetLookaheadComplete: Status %x\n", nsStatus));
  426. WanpLastOidComplete(nhHandle,
  427. pRequestContext,
  428. nsStatus);
  429. return;
  430. }
  431. //
  432. // Set packet filters
  433. //
  434. pRequestContext->ulPacketFilter =
  435. NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_DIRECTED;
  436. nsResult = WanpDoNdisRequest(NdisRequestSetInformation,
  437. OID_GEN_CURRENT_PACKET_FILTER,
  438. &(pRequestContext->ulPacketFilter),
  439. sizeof(pRequestContext->ulPacketFilter),
  440. pRequestContext,
  441. WanpSetPacketFilterComplete);
  442. if(nsResult isnot NDIS_STATUS_PENDING)
  443. {
  444. Trace(ADPT, ERROR,
  445. ("SetLookaheadComplete: %x from OID_GEN_CURRENT_PACKET_FILTER\n",
  446. nsResult));
  447. }
  448. TraceLeave(ADPT,"SetLookaheadComplete");
  449. }
  450. VOID
  451. WanpSetPacketFilterComplete(
  452. NDIS_HANDLE nhHandle,
  453. struct _WANARP_NDIS_REQUEST_CONTEXT *pRequestContext,
  454. NDIS_STATUS nsStatus
  455. )
  456. /*++
  457. Routine Description:
  458. Completion handler called when we are done with setting
  459. OID_GEN_CURRENT_PACKET_FILTER
  460. Locks:
  461. None
  462. Arguments:
  463. nhHandle Binding for the adapter to which the request was sent
  464. pRequestContext Pointer to the request context
  465. nsStatus Result of the request
  466. Return Value:
  467. None
  468. --*/
  469. {
  470. NDIS_STATUS nsResult;
  471. BYTE byHeaderSize;
  472. TraceEnter(ADPT,"SetPacketFilterComplete");
  473. if(nsStatus isnot NDIS_STATUS_SUCCESS)
  474. {
  475. Trace(ADPT, ERROR,
  476. ("SetPacketFilterComplete: Status %x\n", nsStatus));
  477. WanpLastOidComplete(nhHandle,
  478. pRequestContext,
  479. nsStatus);
  480. return;
  481. }
  482. //
  483. // Set packet filters
  484. //
  485. pRequestContext->TransportHeaderOffset.ProtocolType =
  486. NDIS_PROTOCOL_ID_TCP_IP;
  487. pRequestContext->TransportHeaderOffset.HeaderOffset =
  488. (USHORT)sizeof(ETH_HEADER);
  489. nsResult = WanpDoNdisRequest(NdisRequestSetInformation,
  490. OID_GEN_TRANSPORT_HEADER_OFFSET,
  491. &(pRequestContext->TransportHeaderOffset),
  492. sizeof(pRequestContext->TransportHeaderOffset),
  493. pRequestContext,
  494. WanpLastOidComplete);
  495. if(nsResult isnot NDIS_STATUS_PENDING)
  496. {
  497. Trace(ADPT, ERROR,
  498. ("SetPacketFilterComplete: %x from OID_GEN_TRANSPORT_HEADER_OFFSET\n",
  499. nsResult));
  500. }
  501. TraceLeave(ADPT,"SetPacketFilterComplete");
  502. }
  503. VOID
  504. WanpLastOidComplete(
  505. NDIS_HANDLE nhHandle,
  506. struct _WANARP_NDIS_REQUEST_CONTEXT *pRequestContext,
  507. NDIS_STATUS nsStatus
  508. )
  509. /*++
  510. Routine Description:
  511. Completion handler called when we are done with setting the last OID
  512. Currently that is OID_GEN_TRANSPORT_HEADER_OFFSET,
  513. If everything went, well we initialize our adapters
  514. Locks:
  515. None
  516. Arguments:
  517. nhHandle Binding for the adapter to which the request was sent
  518. pRequestContext Pointer to the request context
  519. nsStatus Result of the request
  520. Return Value:
  521. None
  522. --*/
  523. {
  524. NDIS_STATUS nsResult;
  525. TraceEnter(ADPT,"LastOidComplete");
  526. RtFree(pRequestContext);
  527. RtAssert(g_wrBindMutex.lWaitCount >= 1);
  528. if(nsStatus isnot STATUS_SUCCESS)
  529. {
  530. RtAssert(g_nhBindContext isnot NULL);
  531. #if 0
  532. //
  533. // BindContext being NON-NULL means we are being called
  534. // asynchronously, hence call NdisCompleteBindAdapter
  535. //
  536. NdisCompleteBindAdapter(g_nhBindContext,
  537. nsStatus,
  538. nsStatus);
  539. g_nhBindContext = NULL;
  540. #endif
  541. Trace(ADPT, ERROR,
  542. ("LastOidComplete: Status %x\n", nsStatus));
  543. g_nsStatus = g_nsError = nsStatus;
  544. ExInitializeWorkItem(&g_wqiNdisWorkItem,
  545. WanpCloseNdisWan,
  546. NULL);
  547. ExQueueWorkItem(&g_wqiNdisWorkItem,
  548. DelayedWorkQueue);
  549. // WanpCloseNdisWan(NULL);
  550. return;
  551. }
  552. //
  553. // This needs to be put in when the multiple adapters stuff is done
  554. //
  555. //
  556. // The OpenNdiswan call would have setup the system specific
  557. // Since the WanpInitializeAdapters must be called at PASSIVE, we
  558. // fire of a work item here to call the function.
  559. //
  560. ExInitializeWorkItem(&g_wqiWorkItem,
  561. WanpInitializeAdapters,
  562. NULL);
  563. ExQueueWorkItem(&g_wqiWorkItem,
  564. DelayedWorkQueue);
  565. //
  566. // Dont release the mutex here
  567. //
  568. TraceLeave(ADPT,"LastOidComplete");
  569. }
  570. //
  571. // When this is used, remember NOT to use NdisUnbindAdapter as a clean
  572. // up routine because of the way the resource is held
  573. //
  574. #pragma alloc_text(PAGE, WanpInitializeAdapters)
  575. NTSTATUS
  576. WanpInitializeAdapters(
  577. PVOID pvContext
  578. )
  579. /*++
  580. Routine Description:
  581. This routine uses the stored SS1 and opens the IP config for the
  582. binding. It then loops through the multi_sz and creates one adapter
  583. for every sz.
  584. Locks:
  585. Called with the bind mutex held.
  586. This function releases the mutex
  587. Arguments:
  588. None
  589. Return Value:
  590. --*/
  591. {
  592. NDIS_STRING IPConfigName = NDIS_STRING_CONST("IPConfig");
  593. NDIS_STATUS nsStatus;
  594. NDIS_HANDLE nhConfigHandle;
  595. USHORT i;
  596. PADAPTER pNewAdapter;
  597. NTSTATUS nStatus, nReturnStatus;
  598. PWCHAR pwszDeviceBuffer;
  599. PNDIS_CONFIGURATION_PARAMETER pParam;
  600. TraceEnter(ADPT, "InitializeAdapters");
  601. PAGED_CODE();
  602. UNREFERENCED_PARAMETER(pvContext);
  603. RtAssert(g_nhBindContext isnot NULL);
  604. do
  605. {
  606. //
  607. // Open the key for this "adapter"
  608. //
  609. NdisOpenProtocolConfiguration(&nsStatus,
  610. &nhConfigHandle,
  611. &g_nsSystemSpecific1);
  612. if(nsStatus isnot NDIS_STATUS_SUCCESS)
  613. {
  614. Trace(ADPT, ERROR,
  615. ("InitializeAdapters: Unable to Open Protocol Config %x\n",
  616. nsStatus));
  617. break;
  618. }
  619. //
  620. // Read in the IPConfig string. If this is not present,
  621. // fail this call.
  622. //
  623. NdisReadConfiguration(&nsStatus,
  624. &pParam,
  625. nhConfigHandle,
  626. &IPConfigName,
  627. NdisParameterMultiString);
  628. if((nsStatus isnot NDIS_STATUS_SUCCESS) or
  629. (pParam->ParameterType isnot NdisParameterMultiString))
  630. {
  631. Trace(ADPT, ERROR,
  632. ("InitializeAdapters: Unable to read IPConfig. Status %x \n",
  633. nsStatus));
  634. NdisCloseConfiguration(nhConfigHandle);
  635. nsStatus = STATUS_UNSUCCESSFUL;
  636. break;
  637. }
  638. //
  639. // Allocate memory for the max length device name - used later
  640. //
  641. pwszDeviceBuffer =
  642. RtAllocate(NonPagedPool,
  643. (WANARP_MAX_DEVICE_NAME_LEN + 1) * sizeof(WCHAR),
  644. WAN_STRING_TAG);
  645. if(pwszDeviceBuffer is NULL)
  646. {
  647. NdisCloseConfiguration(nhConfigHandle);
  648. Trace(ADPT, ERROR,
  649. ("InitializeAdapters: Couldnt alloc %d bytes for dev name\n",
  650. (WANARP_MAX_DEVICE_NAME_LEN + 1) * sizeof(WCHAR)));
  651. nsStatus = STATUS_INSUFFICIENT_RESOURCES;
  652. break;
  653. }
  654. }while(FALSE);
  655. if(nsStatus isnot STATUS_SUCCESS)
  656. {
  657. //
  658. // Tell NDIS that the bind is done but it failed
  659. //
  660. g_nsStatus = g_nsError = nsStatus;
  661. #if 0
  662. NdisCompleteBindAdapter(g_nhBindContext,
  663. nsStatus,
  664. nsStatus);
  665. g_nhBindContext = NULL;
  666. #endif
  667. WanpCloseNdisWan(NULL);
  668. TraceLeave(ADPT, "InitializeAdapters");
  669. return nsStatus;
  670. }
  671. //
  672. // Now walk through the each of the string
  673. // Since the string must end with two \0's we only walk Len/2 - 1
  674. //
  675. i = 0;
  676. nReturnStatus = STATUS_UNSUCCESSFUL;
  677. RtAssert((pParam->ParameterData.StringData.Length % sizeof(WCHAR)) is 0);
  678. //
  679. // The IPConfigString is a MULTI_SZ with each SZ being the relative key
  680. // for an interfaces IP configuration. It is thus something like
  681. // TCPIP\PARAMETERS\INTERFACES\<device_name>
  682. // Being a MULTI_SZ it is terminated by 2 NULL characters. So we
  683. // walk till the last but one character while parsing out the SZ from
  684. // the multi_sz
  685. //
  686. while(i < (pParam->ParameterData.StringData.Length/sizeof(WCHAR)) - 1)
  687. {
  688. USHORT j, usConfigLen, usDevLen;
  689. UNICODE_STRING usTempString, usUpcaseString, usDevString;
  690. GUID Guid;
  691. if(pParam->ParameterData.StringData.Buffer[i] is UNICODE_NULL)
  692. {
  693. if(pParam->ParameterData.StringData.Buffer[i + 1] is UNICODE_NULL)
  694. {
  695. //
  696. // Two nulls - end of string
  697. //
  698. break;
  699. }
  700. //
  701. // only one null, just move on to the next character
  702. //
  703. i++;
  704. continue;
  705. }
  706. RtAssert(pParam->ParameterData.StringData.Buffer[i] isnot UNICODE_NULL);
  707. //
  708. // Now i points to the start of an SZ. Figure out the length of this
  709. //
  710. usConfigLen =
  711. (USHORT)wcslen(&(pParam->ParameterData.StringData.Buffer[i]));
  712. //
  713. // Make usTempString point to this config. Also increase
  714. // the size by one so one can print this nicely
  715. //
  716. usTempString.MaximumLength = (usConfigLen + 1) * sizeof(WCHAR);
  717. usTempString.Length = (usConfigLen + 1) * sizeof(WCHAR);
  718. usTempString.Buffer = &(pParam->ParameterData.StringData.Buffer[i]);
  719. usUpcaseString.Buffer = RtAllocate(NonPagedPool,
  720. usTempString.MaximumLength,
  721. WAN_STRING_TAG);
  722. if(usUpcaseString.Buffer is NULL)
  723. {
  724. Trace(ADPT, ERROR,
  725. ("InitializeAdapters: Unable to allocate %d bytes\n",
  726. usTempString.MaximumLength));
  727. usUpcaseString.MaximumLength = 0;
  728. usUpcaseString.Length = 0;
  729. i += usConfigLen;
  730. continue;
  731. }
  732. usUpcaseString.MaximumLength = usTempString.MaximumLength;
  733. RtlUpcaseUnicodeString(&usUpcaseString,
  734. &usTempString,
  735. FALSE);
  736. //
  737. // Set the last wchar to null
  738. //
  739. usUpcaseString.Buffer[usConfigLen] = UNICODE_NULL;
  740. //
  741. // Set the length back to what it was
  742. //
  743. usUpcaseString.Length -= sizeof(WCHAR);
  744. RtAssert((usUpcaseString.Length % sizeof(WCHAR)) is 0);
  745. //
  746. // The device name is the last thing in the '\' separated path.
  747. // So walk the SZ backwards looking for '\'
  748. // NOTE one could use wcsrchr, but it would be inefficient since
  749. // it doesnt know the end of the buffer
  750. //
  751. for(j = usUpcaseString.Length/sizeof(WCHAR) - 1;
  752. j >= 0;
  753. j--)
  754. {
  755. if(usUpcaseString.Buffer[j] is L'\\')
  756. {
  757. break;
  758. }
  759. }
  760. //
  761. // So at this point j is the index to the last '\'
  762. //
  763. //
  764. // First off, make this a GUID
  765. //
  766. nStatus = ConvertStringToGuid(&(usUpcaseString.Buffer[j + 1]),
  767. wcslen(&(usUpcaseString.Buffer[j + 1])) * sizeof(WCHAR),
  768. &Guid);
  769. if(nStatus isnot STATUS_SUCCESS)
  770. {
  771. //
  772. // Hmm - not a GUID?
  773. //
  774. Trace(ADPT, ERROR,
  775. ("InitializeAdapters: String %S is not a GUID\n",
  776. &(usUpcaseString.Buffer[j + 1])));
  777. //
  778. // Free the upcase string and move to the next SZ in IPConfig
  779. //
  780. RtFree(usUpcaseString.Buffer);
  781. usUpcaseString.Buffer = NULL;
  782. usUpcaseString.MaximumLength = 0;
  783. usUpcaseString.Length = 0;
  784. i += usConfigLen;
  785. continue;
  786. }
  787. //
  788. // Make sure this binding is not present
  789. //
  790. if(IsBindingPresent(&Guid))
  791. {
  792. Trace(ADPT, WARN,
  793. ("InitializeAdapters: %S already present\n",
  794. &(usUpcaseString.Buffer[j + 1])));
  795. //
  796. // Free the upcase string and move to the next SZ in IPConfig
  797. //
  798. RtFree(usUpcaseString.Buffer);
  799. usUpcaseString.Buffer = NULL;
  800. usUpcaseString.MaximumLength = 0;
  801. usUpcaseString.Length = 0;
  802. i += usConfigLen;
  803. continue;
  804. }
  805. //
  806. // We need to tack on a \DEVICE in front of Guid string
  807. //
  808. usDevLen = wcslen(TCPIP_IF_PREFIX) +
  809. wcslen(&(usUpcaseString.Buffer[j]));
  810. //
  811. // make sure we can fit in the space we have allocated
  812. //
  813. RtAssert(usDevLen <= WANARP_MAX_DEVICE_NAME_LEN);
  814. pwszDeviceBuffer[usDevLen] = UNICODE_NULL;
  815. usDevString.MaximumLength = usDevLen * sizeof(WCHAR);
  816. usDevString.Length = usDevLen * sizeof(WCHAR);
  817. usDevString.Buffer = pwszDeviceBuffer;
  818. //
  819. // Copy over the \Device part
  820. //
  821. RtlCopyMemory(pwszDeviceBuffer,
  822. TCPIP_IF_PREFIX,
  823. wcslen(TCPIP_IF_PREFIX) * sizeof(WCHAR));
  824. //
  825. // Cat the \<Name> part
  826. //
  827. RtlCopyMemory(&(pwszDeviceBuffer[wcslen(TCPIP_IF_PREFIX)]),
  828. &usUpcaseString.Buffer[j],
  829. wcslen(&(usUpcaseString.Buffer[j])) * sizeof(WCHAR));
  830. //
  831. // Create an adapter with this name and config
  832. //
  833. pNewAdapter = NULL;
  834. Trace(ADPT, INFO,
  835. ("InitializeAdapters: Calling create adapter for %S %S\n",
  836. usUpcaseString.Buffer,
  837. usDevString.Buffer));
  838. nStatus = WanpCreateAdapter(&Guid,
  839. &usUpcaseString,
  840. &usDevString,
  841. &pNewAdapter);
  842. if(nStatus isnot STATUS_SUCCESS)
  843. {
  844. Trace(ADPT, ERROR,
  845. ("InitializeAdapters: Err %x creating adapter for %S (%S)\n",
  846. nStatus,
  847. usUpcaseString.Buffer,
  848. pwszDeviceBuffer));
  849. }
  850. else
  851. {
  852. //
  853. // If even one succeeds, we return success
  854. //
  855. nReturnStatus = STATUS_SUCCESS;
  856. }
  857. //
  858. // Done with the upcased string
  859. //
  860. RtFree(usUpcaseString.Buffer);
  861. usUpcaseString.Buffer = NULL;
  862. usUpcaseString.MaximumLength = 0;
  863. usUpcaseString.Length = 0;
  864. //
  865. // Go to the next SZ in the MULTI_SZ
  866. //
  867. i += usConfigLen;
  868. }
  869. NdisCloseConfiguration(nhConfigHandle);
  870. RtFree(pwszDeviceBuffer);
  871. NdisCompleteBindAdapter(g_nhBindContext,
  872. nReturnStatus,
  873. nReturnStatus);
  874. g_nhBindContext = NULL;
  875. if(nReturnStatus isnot STATUS_SUCCESS)
  876. {
  877. WanpCloseNdisWan(NULL);
  878. }
  879. else
  880. {
  881. g_lBindRcvd = 1;
  882. WanpReleaseResource(&g_wrBindMutex);
  883. }
  884. TraceLeave(ADPT, "InitializeAdapters");
  885. return nReturnStatus;
  886. }
  887. NTSTATUS
  888. WanpCreateAdapter(
  889. IN GUID *pAdapterGuid,
  890. IN PUNICODE_STRING pusConfigName,
  891. IN PUNICODE_STRING pusDeviceName,
  892. OUT ADAPTER **ppNewAdapter
  893. )
  894. /*++
  895. Routine Description:
  896. Creates and initializes an ADAPTER structure
  897. If this is the first adapter, it is used as the server adapter.
  898. For that case, it also creates and initializes the server interface.
  899. The server adapter is added to IP
  900. Locks:
  901. Called at passive, however it acquires the adapter list lock since it
  902. sets g_pServerAdapter/Interface
  903. Arguments:
  904. pusConfigName Name of config key
  905. pusDeviceName The device name for the adapter
  906. ppNewAdapter Pointer to storage for the pointer to newly created adapter
  907. Return Value:
  908. STATUS_SUCCESS
  909. STATUS_INSUFFICIENT_RESOURCES
  910. --*/
  911. {
  912. ULONG ulSize;
  913. PVOID pvBuffer;
  914. PADAPTER pAdapter;
  915. USHORT i;
  916. NTSTATUS nStatus;
  917. KIRQL kiIrql;
  918. PASSIVE_ENTRY();
  919. TraceEnter(ADPT, "CreateAdapter");
  920. Trace(ADPT, TRACE,
  921. ("CreateAdapter: \n\t%S\n\t%S\n",
  922. pusConfigName->Buffer,
  923. pusDeviceName->Buffer));
  924. *ppNewAdapter = NULL;
  925. //
  926. // The size that one needs is the size of the adapter + the length of the
  927. // name. Add a WCHAR to get a easily printtable string.
  928. // Align everything on a 4 byte boundary
  929. //
  930. ulSize = ALIGN_UP(sizeof(ADAPTER), ULONG) +
  931. ALIGN_UP((pusConfigName->Length + sizeof(WCHAR)), ULONG) +
  932. ALIGN_UP((pusDeviceName->Length + sizeof(WCHAR)), ULONG);
  933. #if DBG
  934. //
  935. // For debug code we also store the adapter name in ANSI
  936. // We use 2 * sizeof(CHAR) because RtlUnicodeToAnsiString needs
  937. // MaximumLength + 1
  938. //
  939. ulSize += pusDeviceName->Length/sizeof(WCHAR) + (2 * sizeof(CHAR));
  940. #endif
  941. pAdapter = RtAllocate(NonPagedPool,
  942. ulSize,
  943. WAN_ADAPTER_TAG);
  944. if(pAdapter is NULL)
  945. {
  946. Trace(ADPT, ERROR,
  947. ("CreateAdapter: Failed to allocate memory\n"));
  948. TraceLeave(ADPT, "CreateAdapter");
  949. return STATUS_INSUFFICIENT_RESOURCES;
  950. }
  951. //
  952. // Clear all the fields out
  953. //
  954. RtlZeroMemory(pAdapter,
  955. ulSize);
  956. //
  957. // The config name buffer starts at the end of the adapter structure.
  958. //
  959. pvBuffer = (PVOID)((ULONG_PTR)pAdapter + sizeof(ADAPTER));
  960. //
  961. // We DWORD align it for better compare/copy
  962. //
  963. pvBuffer = ALIGN_UP_POINTER(pvBuffer, ULONG);
  964. pAdapter->usConfigKey.Length = pusConfigName->Length;
  965. pAdapter->usConfigKey.MaximumLength = pusConfigName->Length;
  966. pAdapter->usConfigKey.Buffer = (PWCHAR)pvBuffer;
  967. RtlCopyMemory(pAdapter->usConfigKey.Buffer,
  968. pusConfigName->Buffer,
  969. pusConfigName->Length);
  970. //
  971. // The device name comes after this
  972. //
  973. pvBuffer = (PVOID)((ULONG_PTR)pvBuffer +
  974. pusConfigName->Length +
  975. sizeof(WCHAR));
  976. pvBuffer = ALIGN_UP_POINTER(pvBuffer, ULONG);
  977. pAdapter->usDeviceNameW.Length = pusDeviceName->Length;
  978. pAdapter->usDeviceNameW.MaximumLength = pusDeviceName->Length;
  979. pAdapter->usDeviceNameW.Buffer = (PWCHAR)pvBuffer;
  980. RtlCopyMemory(pAdapter->usDeviceNameW.Buffer,
  981. pusDeviceName->Buffer,
  982. pusDeviceName->Length);
  983. #if DBG
  984. //
  985. // The debug string comes after the UNICODE device name buffer
  986. //
  987. pvBuffer = (PVOID)((ULONG_PTR)pvBuffer +
  988. pusDeviceName->Length +
  989. sizeof(WCHAR));
  990. pvBuffer = ALIGN_UP_POINTER(pvBuffer, ULONG);
  991. pAdapter->asDeviceNameA.Buffer = (PCHAR)pvBuffer;
  992. //
  993. // Apparently, the unicode to ansi function wants length + 1
  994. //
  995. pAdapter->asDeviceNameA.MaximumLength = pusDeviceName->Length/sizeof(WCHAR) + 1;
  996. RtlUnicodeStringToAnsiString(&pAdapter->asDeviceNameA,
  997. &pAdapter->usDeviceNameW,
  998. FALSE);
  999. #endif // DBG
  1000. //
  1001. // Structure copy
  1002. //
  1003. pAdapter->Guid = *pAdapterGuid;
  1004. //
  1005. // Must be set to INVALID so that GetEntityList can work
  1006. //
  1007. pAdapter->dwATInstance = INVALID_ENTITY_INSTANCE;
  1008. pAdapter->dwIfInstance = INVALID_ENTITY_INSTANCE;
  1009. //
  1010. // Set the state
  1011. //
  1012. pAdapter->byState = AS_FREE;
  1013. //
  1014. // This hardware index is needed to generate the Unique ID that
  1015. // DHCP uses.
  1016. // NOTE - we dont have an index so all hardware addrs will be the same
  1017. //
  1018. BuildHardwareAddrFromIndex(pAdapter->rgbyHardwareAddr,
  1019. pAdapter->dwAdapterIndex);
  1020. //
  1021. // Initialize the lock for the adapter
  1022. //
  1023. RtInitializeSpinLock(&(pAdapter->rlLock));
  1024. InitializeListHead(&(pAdapter->lePendingPktList));
  1025. InitializeListHead(&(pAdapter->lePendingHdrList));
  1026. InitializeListHead(&(pAdapter->leEventList));
  1027. //
  1028. // Set the Refcount to 1 because it will either lie on some list
  1029. // or be pointed to by g_pServerAdapter
  1030. //
  1031. InitAdapterRefCount(pAdapter);
  1032. if(g_pServerAdapter is NULL)
  1033. {
  1034. PUMODE_INTERFACE pInterface;
  1035. //
  1036. // We use the first adapter adapter as the server adapter
  1037. // We also create the server interface right here
  1038. //
  1039. RtAssert(g_pServerInterface is NULL);
  1040. pInterface = RtAllocate(NonPagedPool,
  1041. sizeof(UMODE_INTERFACE),
  1042. WAN_INTERFACE_TAG);
  1043. if(pInterface is NULL)
  1044. {
  1045. Trace(ADPT, ERROR,
  1046. ("CreateAdapter: Couldnt allocate %d bytes for server i/f\n",
  1047. sizeof(UMODE_INTERFACE)));
  1048. RtFree(pAdapter);
  1049. *ppNewAdapter = NULL;
  1050. return STATUS_INSUFFICIENT_RESOURCES;
  1051. }
  1052. RtlZeroMemory(pInterface,
  1053. sizeof(UMODE_INTERFACE));
  1054. //
  1055. // Get an index from IP
  1056. // If this fails, it sets the value to INVALID_IF_INDEX
  1057. //
  1058. nStatus = WanpGetNewIndex(&(pInterface->dwRsvdAdapterIndex));
  1059. if(nStatus isnot STATUS_SUCCESS)
  1060. {
  1061. Trace(ADPT, ERROR,
  1062. ("CreateAdapter: Couldnt get index for server interface\n"));
  1063. RtFree(pAdapter);
  1064. RtFree(pInterface);
  1065. *ppNewAdapter = NULL;
  1066. return STATUS_INSUFFICIENT_RESOURCES;
  1067. }
  1068. Trace(ADPT, TRACE,
  1069. ("CreateAdapter: Server Index is %d\n",
  1070. pInterface->dwRsvdAdapterIndex));
  1071. RtInitializeSpinLock(&(pInterface->rlLock));
  1072. InitInterfaceRefCount(pInterface);
  1073. pInterface->dwIfIndex = INVALID_IF_INDEX;
  1074. pInterface->dwAdminState = IF_ADMIN_STATUS_UP;
  1075. pInterface->duUsage = DU_CALLIN;
  1076. //
  1077. // Structure copy
  1078. //
  1079. pInterface->Guid = ServerInterfaceGuid;
  1080. EnterWriter(&g_rwlAdapterLock,
  1081. &kiIrql);
  1082. pAdapter->byState = AS_FREE;
  1083. pInterface->dwOperState = IF_OPER_STATUS_DISCONNECTED;
  1084. pInterface->dwLastChange = GetTimeTicks();
  1085. //
  1086. // We dont cross ref the structures here. That is done
  1087. // we have added the server interface to IP.
  1088. //
  1089. g_pServerAdapter = pAdapter;
  1090. g_pServerInterface = pInterface;
  1091. ExitWriter(&g_rwlAdapterLock,
  1092. kiIrql);
  1093. Trace(ADPT, INFO,
  1094. ("CreateAdapter: %S is server adapter\n",
  1095. pAdapter->usDeviceNameW.Buffer));
  1096. }
  1097. else
  1098. {
  1099. EnterWriter(&g_rwlAdapterLock,
  1100. &kiIrql);
  1101. InsertHeadList(&g_leFreeAdapterList,
  1102. &(pAdapter->leAdapterLink));
  1103. g_ulNumFreeAdapters++;
  1104. ExitWriter(&g_rwlAdapterLock,
  1105. kiIrql);
  1106. }
  1107. InterlockedIncrement(&g_ulNumAdapters);
  1108. *ppNewAdapter = pAdapter;
  1109. TraceLeave(ADPT, "CreateAdapter");
  1110. return STATUS_SUCCESS;
  1111. }
  1112. #pragma alloc_text(PAGE, WanNdisUnbindAdapter)
  1113. VOID
  1114. WanNdisUnbindAdapter(
  1115. PNDIS_STATUS pnsRetStatus,
  1116. NDIS_HANDLE nhProtocolContext,
  1117. NDIS_HANDLE nhUnbindContext
  1118. )
  1119. /*++
  1120. Routine Description:
  1121. Called by NDIS to unbind an open adapter. Since we only open one adapter
  1122. we get this only once.
  1123. Locks:
  1124. The function acquires the g_wrBindMutex. This is released in
  1125. WanpFreeBindResourcesAndReleaseLock
  1126. Arguments:
  1127. pnsRetStatus
  1128. nhProtocolContext
  1129. nhUnbindContext
  1130. Return Value:
  1131. NDIS_STATUS_PENDING
  1132. --*/
  1133. {
  1134. NDIS_STATUS nsStatus;
  1135. TraceEnter(ADPT,"NdisUnbindAdapter");
  1136. PAGED_CODE();
  1137. RtAssert(nhProtocolContext is (NDIS_HANDLE)0x0CABB1E5);
  1138. //
  1139. // Get into the critical section
  1140. //
  1141. WanpAcquireResource(&g_wrBindMutex);
  1142. //
  1143. // Mark all the adapters as down so that we dont process anything
  1144. // from IP on them
  1145. //
  1146. //
  1147. // Close the adapter if we havent already done so.
  1148. // This will stop us getting stuff from NDISWAN
  1149. //
  1150. if(g_nhNdiswanBinding isnot NULL)
  1151. {
  1152. g_nhUnbindContext = nhUnbindContext;
  1153. WanpCloseNdisWan(NULL);
  1154. //
  1155. // If we call CloseNdisWan then we DONT release the resource here.
  1156. // It is released by CloseAdapterComplete
  1157. //
  1158. *pnsRetStatus = NDIS_STATUS_PENDING;
  1159. }
  1160. else
  1161. {
  1162. WanpReleaseResource(&g_wrBindMutex);
  1163. *pnsRetStatus = NDIS_STATUS_SUCCESS;
  1164. }
  1165. TraceLeave(ADPT, "NdisUnbindAdapter");
  1166. }
  1167. VOID
  1168. WanpCloseNdisWan(
  1169. PVOID pvContext
  1170. )
  1171. /*++
  1172. Routine Description:
  1173. This function cleans all the resources of an open adapter
  1174. Locks:
  1175. The function is called with the g_wrBindMutex held.
  1176. Arguments:
  1177. None
  1178. Return Value:
  1179. None
  1180. --*/
  1181. {
  1182. NDIS_STATUS nsStatus;
  1183. TraceEnter(ADPT, "WanpCloseNdisWan");
  1184. RtAssert(g_nhNdiswanBinding isnot NULL);
  1185. RtAssert(g_wrBindMutex.lWaitCount >= 1);
  1186. NdisCloseAdapter(&nsStatus,
  1187. g_nhNdiswanBinding);
  1188. g_nhNdiswanBinding = NULL;
  1189. //
  1190. // If our completion routine will not be called, do it here
  1191. //
  1192. if(nsStatus isnot NDIS_STATUS_PENDING)
  1193. {
  1194. WanNdisCloseAdapterComplete((NDIS_HANDLE)0x0CABB1E5,
  1195. nsStatus);
  1196. }
  1197. //
  1198. // We DONT release the resource here. It is released by
  1199. // CloseAdapterComplete
  1200. //
  1201. TraceLeave(ADPT, "WanpCloseNdisWan");
  1202. return;
  1203. }
  1204. #pragma alloc_text(PAGE, WanNdisCloseAdapterComplete)
  1205. VOID
  1206. WanNdisCloseAdapterComplete(
  1207. NDIS_HANDLE nhBindHandle,
  1208. NDIS_STATUS nsStatus
  1209. )
  1210. /*++
  1211. Routine Description:
  1212. Called by NDIS when it is done closing the NDISWAN adapter
  1213. The close adapter can be done either because we failed somewhere (after
  1214. successfully opening our adapter) and in the process of cleanup are
  1215. closing our adapter (in which case the unbind context will be null) or
  1216. because we got an unbind and were cleaning up all adapter related stuff
  1217. Locks:
  1218. Called the g_wrBindMutex held.
  1219. The resource was acquired either in the Unbind handler or was acquired
  1220. before the failure code was called
  1221. Arguments:
  1222. nhBindHandle
  1223. nsStatus
  1224. Return Value:
  1225. None
  1226. --*/
  1227. {
  1228. KIRQL kiIrql;
  1229. NDIS_HANDLE nhUnbind;
  1230. NDIS_HANDLE nhBind;
  1231. NDIS_STATUS tnsStatus, tnsError;
  1232. TraceEnter(ADPT, "NdisCloseAdapterComplete");
  1233. PAGED_CODE();
  1234. nhUnbind = g_nhUnbindContext;
  1235. nhBind = g_nhBindContext;
  1236. tnsStatus = g_nsStatus;
  1237. tnsError = g_nsError;
  1238. RtAssert(g_wrBindMutex.lWaitCount >= 1);
  1239. g_nhUnbindContext = NULL;
  1240. g_nhBindContext = NULL;
  1241. WanpFreeBindResourcesAndReleaseLock();
  1242. if(nhBind isnot NULL)
  1243. {
  1244. RtAssert(nhUnbind == NULL);
  1245. //
  1246. // Tell NDIS that the bind is done but it failed
  1247. //
  1248. NdisCompleteBindAdapter(nhBind,
  1249. tnsStatus,
  1250. tnsError);
  1251. }
  1252. //
  1253. // If this is being triggered from an unbind..
  1254. //
  1255. if(nhUnbind isnot NULL)
  1256. {
  1257. RtAssert(nhBind == NULL);
  1258. NdisCompleteUnbindAdapter(nhUnbind,
  1259. NDIS_STATUS_SUCCESS);
  1260. }
  1261. }
  1262. VOID
  1263. WanpFreeBindResourcesAndReleaseLock(
  1264. VOID
  1265. )
  1266. {
  1267. RtAssert(g_wrBindMutex.lWaitCount >= 1);
  1268. RtFree(g_usNdiswanBindName.Buffer);
  1269. g_usNdiswanBindName.Buffer = NULL;
  1270. RtFree(g_nsSystemSpecific1.Buffer);
  1271. g_nsSystemSpecific1.Buffer = NULL;
  1272. WanpRemoveAllAdapters();
  1273. //
  1274. // There could be turds in the connection table if this was not
  1275. // a clean shutdown
  1276. //
  1277. WanpRemoveAllConnections();
  1278. //
  1279. // Done, set the global event
  1280. //
  1281. KeSetEvent(&g_keCloseEvent,
  1282. 0,
  1283. FALSE);
  1284. //
  1285. // Finally done, set g_lBindRcvd and release the resource
  1286. //
  1287. g_lBindRcvd = 0;
  1288. WanpReleaseResource(&g_wrBindMutex);
  1289. PASSIVE_EXIT();
  1290. }
  1291. PADAPTER
  1292. WanpFindAdapterToMap(
  1293. IN DIAL_USAGE duUsage,
  1294. OUT PKIRQL pkiIrql,
  1295. IN DWORD dwAdapterIndex,
  1296. IN PUNICODE_STRING pusNewIfName
  1297. )
  1298. /*++
  1299. Routine Description:
  1300. Finds a free adapter to map to an interface.
  1301. The adapter, if found is locked and referenced. Its state is set to
  1302. AS_MAPPING and it is put on the mapped list.
  1303. Locks:
  1304. Must be called at PASSIVE
  1305. Acquires g_rwlAdapterLock as WRITER
  1306. If it returns a mapped adapter, then the function returns at DPC and
  1307. the original IRQL is in pkiIrql
  1308. Arguments:
  1309. duUsage The usage for which the adapter needs to be found
  1310. pkiIrql
  1311. dwAdapterIndex
  1312. pusNewIfName
  1313. Return Value:
  1314. Pointer to adapter if successful
  1315. --*/
  1316. {
  1317. PADAPTER pAdapter;
  1318. KIRQL kiIrql;
  1319. PLIST_ENTRY pleNode;
  1320. NTSTATUS nStatus;
  1321. KEVENT keChangeEvent;
  1322. WAN_EVENT_NODE TempEvent;
  1323. //
  1324. // Find a free adapter
  1325. //
  1326. EnterWriter(&g_rwlAdapterLock,
  1327. &kiIrql);
  1328. if(duUsage is DU_CALLIN)
  1329. {
  1330. if(g_pServerAdapter is NULL)
  1331. {
  1332. Trace(CONN, ERROR,
  1333. ("FindAdapterToMap: No server adapter\n"));
  1334. ExitWriter(&g_rwlAdapterLock,
  1335. kiIrql);
  1336. return NULL;
  1337. }
  1338. RtAssert(g_pServerInterface);
  1339. //
  1340. // Lock out the adapter
  1341. //
  1342. RtAcquireSpinLockAtDpcLevel(&(g_pServerAdapter->rlLock));
  1343. //
  1344. // Reference it because we are going to return it. Also we need the
  1345. // reference when we let go of the lock if we need to wait
  1346. //
  1347. ReferenceAdapter(g_pServerAdapter);
  1348. //
  1349. // See if the adapter has been added to IP
  1350. // rasiphlp has to call us to map the server adapter before
  1351. // doing a line up
  1352. //
  1353. if(g_pServerAdapter->byState isnot AS_MAPPED)
  1354. {
  1355. RtAssert(g_pServerAdapter->byState is AS_ADDING);
  1356. if(g_pServerAdapter->byState is AS_ADDING)
  1357. {
  1358. KeInitializeEvent(&(TempEvent.keEvent),
  1359. SynchronizationEvent,
  1360. FALSE);
  1361. InsertTailList(&(g_pServerAdapter->leEventList),
  1362. &(TempEvent.leEventLink));
  1363. //
  1364. // Let go of the lock and wait on the event
  1365. //
  1366. RtReleaseSpinLockFromDpcLevel(&(g_pServerAdapter->rlLock));
  1367. ExitWriter(&g_rwlAdapterLock,
  1368. kiIrql);
  1369. nStatus = KeWaitForSingleObject(&(TempEvent.keEvent),
  1370. Executive,
  1371. KernelMode,
  1372. FALSE,
  1373. NULL);
  1374. RtAssert(nStatus is STATUS_SUCCESS);
  1375. EnterWriter(&g_rwlAdapterLock,
  1376. &kiIrql);
  1377. RtAcquireSpinLockAtDpcLevel(&(g_pServerAdapter->rlLock));
  1378. RemoveEntryList(&(TempEvent.leEventLink));
  1379. }
  1380. }
  1381. if(g_pServerAdapter->byState isnot AS_MAPPED)
  1382. {
  1383. PADAPTER pTempAdapter;
  1384. //
  1385. // Couldnt add the adapter because of some reason,
  1386. //
  1387. pTempAdapter = g_pServerAdapter;
  1388. Trace(CONN, ERROR,
  1389. ("FindAdapterToMap: Unable to get mapped server adapter\n"));
  1390. RtReleaseSpinLockFromDpcLevel(&(g_pServerAdapter->rlLock));
  1391. ExitWriter(&g_rwlAdapterLock,
  1392. kiIrql);
  1393. DereferenceAdapter(pTempAdapter);
  1394. return NULL;
  1395. }
  1396. RtAssert(g_pServerAdapter->byState is AS_MAPPED);
  1397. ExitWriterFromDpcLevel(&g_rwlAdapterLock);
  1398. *pkiIrql = kiIrql;
  1399. return g_pServerAdapter;
  1400. }
  1401. //
  1402. // Non dial in case. First try and see if there is an adapter with the
  1403. // index we want already added to IP
  1404. //
  1405. pAdapter = NULL;
  1406. for(pleNode = g_leAddedAdapterList.Flink;
  1407. pleNode isnot &g_leAddedAdapterList;
  1408. pleNode = pleNode->Flink)
  1409. {
  1410. PADAPTER pTempAdapter;
  1411. pTempAdapter = CONTAINING_RECORD(pleNode,
  1412. ADAPTER,
  1413. leAdapterLink);
  1414. RtAssert(pTempAdapter->byState is AS_ADDED);
  1415. if(pTempAdapter->dwAdapterIndex is dwAdapterIndex)
  1416. {
  1417. RemoveEntryList(&(pTempAdapter->leAdapterLink));
  1418. g_ulNumAddedAdapters--;
  1419. pAdapter = pTempAdapter;
  1420. break;
  1421. }
  1422. }
  1423. if(pAdapter isnot NULL)
  1424. {
  1425. //
  1426. // So we found an added adapter (it has been removed from the
  1427. // added adapter list). Add it to the mapped list
  1428. //
  1429. InsertTailList(&g_leMappedAdapterList,
  1430. &(pAdapter->leAdapterLink));
  1431. g_ulNumMappedAdapters++;
  1432. RtAcquireSpinLockAtDpcLevel(&(pAdapter->rlLock));
  1433. ExitWriterFromDpcLevel(&g_rwlAdapterLock);
  1434. ReferenceAdapter(pAdapter);
  1435. pAdapter->byState = AS_MAPPING;
  1436. *pkiIrql = kiIrql;
  1437. #if DBG
  1438. Trace(CONN, INFO,
  1439. ("FindAdapterToMap: Found %s already added\n",
  1440. pAdapter->asDeviceNameA.Buffer));
  1441. #endif
  1442. return pAdapter;
  1443. }
  1444. //
  1445. // Didnt find an added adapter
  1446. // See if the adapter is on the change list. We want to wait for this
  1447. // because IP doesnt like to have to interfaces with the same index, even
  1448. // if one is in the process of being removed
  1449. //
  1450. for(pleNode = g_leChangeAdapterList.Flink;
  1451. pleNode isnot &g_leChangeAdapterList;
  1452. pleNode = pleNode->Flink)
  1453. {
  1454. PADAPTER pTempAdapter;
  1455. pTempAdapter = CONTAINING_RECORD(pleNode,
  1456. ADAPTER,
  1457. leAdapterLink);
  1458. if(pTempAdapter->dwAdapterIndex is dwAdapterIndex)
  1459. {
  1460. //
  1461. // Wait for the change to complete
  1462. //
  1463. KeInitializeEvent(&(TempEvent.keEvent),
  1464. SynchronizationEvent,
  1465. FALSE);
  1466. RtAcquireSpinLockAtDpcLevel(&(pTempAdapter->rlLock));
  1467. InsertTailList(&(pTempAdapter->leEventList),
  1468. &(TempEvent.leEventLink));
  1469. //
  1470. // Reference the adapter, let go of the lock and wait on the event
  1471. //
  1472. ReferenceAdapter(pTempAdapter);
  1473. RtReleaseSpinLockFromDpcLevel(&(pTempAdapter->rlLock));
  1474. ExitWriter(&g_rwlAdapterLock,
  1475. kiIrql);
  1476. nStatus = KeWaitForSingleObject(&(TempEvent.keEvent),
  1477. Executive,
  1478. KernelMode,
  1479. FALSE,
  1480. NULL);
  1481. RtAssert(nStatus is STATUS_SUCCESS);
  1482. EnterWriter(&g_rwlAdapterLock,
  1483. &kiIrql);
  1484. RtAcquireSpinLockAtDpcLevel(&(pTempAdapter->rlLock));
  1485. RemoveEntryList(&(TempEvent.leEventLink));
  1486. RtReleaseSpinLockFromDpcLevel(&(pTempAdapter->rlLock));
  1487. DereferenceAdapter(pTempAdapter);
  1488. break;
  1489. }
  1490. }
  1491. if(!IsListEmpty(&g_leFreeAdapterList))
  1492. {
  1493. pleNode = RemoveHeadList(&g_leFreeAdapterList);
  1494. pAdapter = CONTAINING_RECORD(pleNode,
  1495. ADAPTER,
  1496. leAdapterLink);
  1497. g_ulNumFreeAdapters--;
  1498. #if DBG
  1499. Trace(CONN, INFO,
  1500. ("FindAdapterToMap: Found free adapter %s\n",
  1501. pAdapter->asDeviceNameA.Buffer));
  1502. #endif // DBG
  1503. }
  1504. else
  1505. {
  1506. //
  1507. // Couldnt find an adapter. That is bad
  1508. // TODO - if the added adapter list is not empty, we could call
  1509. // RemoveSomeAddedAdapter... at this point
  1510. //
  1511. Trace(ADPT, ERROR,
  1512. ("FindAdapterToMap: Couldnt find free adapter\n"));
  1513. ExitWriter(&g_rwlAdapterLock,
  1514. kiIrql);
  1515. return NULL;
  1516. }
  1517. //
  1518. // Lock and refcount the adapter.
  1519. //
  1520. RtAcquireSpinLockAtDpcLevel(&(pAdapter->rlLock));
  1521. ReferenceAdapter(pAdapter);
  1522. //
  1523. // The adapter better not be mapped
  1524. //
  1525. RtAssert(pAdapter->pInterface is NULL);
  1526. RtAssert(pAdapter->byState is AS_FREE);
  1527. //
  1528. // Set the state to ADDING
  1529. //
  1530. pAdapter->byState = AS_ADDING;
  1531. //
  1532. // Since we are changing the state, no one else should be also
  1533. // changing the state
  1534. //
  1535. RtAssert(pAdapter->pkeChangeEvent is NULL);
  1536. KeInitializeEvent(&keChangeEvent,
  1537. SynchronizationEvent,
  1538. FALSE);
  1539. pAdapter->pkeChangeEvent = &keChangeEvent;
  1540. //
  1541. // Insert into the change list
  1542. //
  1543. InsertTailList(&g_leChangeAdapterList,
  1544. &(pAdapter->leAdapterLink));
  1545. RtReleaseSpinLockFromDpcLevel(&(pAdapter->rlLock));
  1546. ExitWriter(&g_rwlAdapterLock,
  1547. kiIrql);
  1548. //
  1549. // Add the adapter to IP
  1550. //
  1551. nStatus = WanpAddAdapterToIp(pAdapter,
  1552. FALSE,
  1553. dwAdapterIndex,
  1554. pusNewIfName,
  1555. IF_TYPE_PPP,
  1556. IF_ACCESS_POINTTOPOINT,
  1557. IF_CONNECTION_DEMAND);
  1558. if(nStatus isnot STATUS_SUCCESS)
  1559. {
  1560. Trace(ADPT, ERROR,
  1561. ("FindAdapterToMap: %x adding %x to IP\n",
  1562. nStatus, pAdapter));
  1563. EnterWriter(&g_rwlAdapterLock,
  1564. &kiIrql);
  1565. RtAcquireSpinLockAtDpcLevel(&(pAdapter->rlLock));
  1566. #if DBG
  1567. RtAssert(IsEntryOnList(&g_leChangeAdapterList,
  1568. &(pAdapter->leAdapterLink)));
  1569. #endif
  1570. pAdapter->pkeChangeEvent = NULL;
  1571. RemoveEntryList(&(pAdapter->leAdapterLink));
  1572. pAdapter->byState = AS_FREE;
  1573. InsertTailList(&g_leFreeAdapterList,
  1574. &(pAdapter->leAdapterLink));
  1575. g_ulNumFreeAdapters++;
  1576. //
  1577. // If anyone is waiting on a state change, notify them
  1578. //
  1579. for(pleNode = pAdapter->leEventList.Flink;
  1580. pleNode isnot &(pAdapter->leEventList);
  1581. pleNode = pleNode->Flink)
  1582. {
  1583. PWAN_EVENT_NODE pTempEvent;
  1584. pTempEvent = CONTAINING_RECORD(pleNode,
  1585. WAN_EVENT_NODE,
  1586. leEventLink);
  1587. KeSetEvent(&(pTempEvent->keEvent),
  1588. 0,
  1589. FALSE);
  1590. }
  1591. RtReleaseSpinLockFromDpcLevel(&(pAdapter->rlLock));
  1592. ExitWriter(&g_rwlAdapterLock,
  1593. kiIrql);
  1594. DereferenceAdapter(pAdapter);
  1595. return NULL;
  1596. }
  1597. //
  1598. // Wait till the OpenAdapter is called
  1599. //
  1600. nStatus = KeWaitForSingleObject(&keChangeEvent,
  1601. Executive,
  1602. KernelMode,
  1603. FALSE,
  1604. NULL);
  1605. RtAssert(nStatus is STATUS_SUCCESS);
  1606. Trace(ADPT, TRACE,
  1607. ("FindAdapterToMap: IPAddInterface succeeded for adapter %w\n",
  1608. pAdapter->usDeviceNameW.Buffer));
  1609. //
  1610. // Lock the adapter, insert into the added list
  1611. //
  1612. EnterWriter(&g_rwlAdapterLock,
  1613. &kiIrql);
  1614. RtAcquireSpinLockAtDpcLevel(&(pAdapter->rlLock));
  1615. #if DBG
  1616. RtAssert(IsEntryOnList(&g_leChangeAdapterList,
  1617. &(pAdapter->leAdapterLink)));
  1618. #endif
  1619. RemoveEntryList(&(pAdapter->leAdapterLink));
  1620. pAdapter->pkeChangeEvent = NULL;
  1621. InsertHeadList(&g_leMappedAdapterList,
  1622. &(pAdapter->leAdapterLink));
  1623. g_ulNumMappedAdapters++;
  1624. //
  1625. // If anyone is waiting on a state change, notify them
  1626. //
  1627. for(pleNode = pAdapter->leEventList.Flink;
  1628. pleNode isnot &(pAdapter->leEventList);
  1629. pleNode = pleNode->Flink)
  1630. {
  1631. PWAN_EVENT_NODE pTempEvent;
  1632. pTempEvent = CONTAINING_RECORD(pleNode,
  1633. WAN_EVENT_NODE,
  1634. leEventLink);
  1635. KeSetEvent(&(pTempEvent->keEvent),
  1636. 0,
  1637. FALSE);
  1638. }
  1639. ExitWriterFromDpcLevel(&g_rwlAdapterLock);
  1640. *pkiIrql = kiIrql;
  1641. return pAdapter;
  1642. }
  1643. NTSTATUS
  1644. WanpAddAdapterToIp(
  1645. IN PADAPTER pAdapter,
  1646. IN BOOLEAN bServerAdapter,
  1647. IN DWORD dwAdapterIndex, OPTIONAL
  1648. IN PUNICODE_STRING pusNewIfName, OPTIONAL
  1649. IN DWORD dwMediaType,
  1650. IN BYTE byAccessType,
  1651. IN BYTE byConnectionType
  1652. )
  1653. /*++
  1654. Routine Description:
  1655. This routine adds the interface to IP
  1656. Locks:
  1657. MUST BE CALLED AT PASSIVE, but acquires a spinlock so cant be paged out
  1658. Arguments:
  1659. pAdapter The adapter to add
  1660. bServerAdapter Set to TRUE if this is a server adapter
  1661. dwAdapterIndex
  1662. pusNewIfName
  1663. Return Value:
  1664. STATUS_SUCCESS
  1665. --*/
  1666. {
  1667. LLIPBindInfo BindInfo;
  1668. IP_STATUS IPStatus;
  1669. UNICODE_STRING usName;
  1670. NTSTATUS nStatus;
  1671. KIRQL kiIrql;
  1672. PASSIVE_ENTRY();
  1673. TraceEnter(ADPT, "AddAdapterToIp");
  1674. RtlZeroMemory(&BindInfo, sizeof(LLIPBindInfo));
  1675. BindInfo.lip_context = pAdapter;
  1676. BindInfo.lip_mss = WANARP_DEFAULT_MTU;
  1677. BindInfo.lip_speed = WANARP_DEFAULT_SPEED;
  1678. BindInfo.lip_txspace = sizeof(ETH_HEADER);
  1679. BindInfo.lip_transmit = WanIpTransmit;
  1680. BindInfo.lip_transfer = WanIpTransferData;
  1681. BindInfo.lip_returnPkt = WanIpReturnPacket;
  1682. BindInfo.lip_close = WanIpCloseAdapter;
  1683. BindInfo.lip_addaddr = WanIpAddAddress;
  1684. BindInfo.lip_deladdr = WanIpDeleteAddress;
  1685. BindInfo.lip_invalidate = WanIpInvalidateRce;
  1686. BindInfo.lip_open = WanIpOpenAdapter;
  1687. BindInfo.lip_qinfo = WanIpQueryInfo;
  1688. BindInfo.lip_setinfo = WanIpSetInfo;
  1689. BindInfo.lip_getelist = WanIpGetEntityList;
  1690. BindInfo.lip_flags = LIP_COPY_FLAG;
  1691. if(bServerAdapter)
  1692. {
  1693. BindInfo.lip_flags |= (LIP_P2MP_FLAG | LIP_NOLINKBCST_FLAG);
  1694. BindInfo.lip_closelink = WanIpCloseLink;
  1695. }
  1696. else
  1697. {
  1698. BindInfo.lip_flags |= (LIP_P2P_FLAG | LIP_NOIPADDR_FLAG);
  1699. }
  1700. BindInfo.lip_addrlen = ARP_802_ADDR_LENGTH;
  1701. BindInfo.lip_addr = pAdapter->rgbyHardwareAddr;
  1702. BindInfo.lip_OffloadFlags = 0;
  1703. BindInfo.lip_dowakeupptrn = NULL;
  1704. BindInfo.lip_pnpcomplete = NULL;
  1705. BindInfo.lip_arpflushate = NULL;
  1706. BindInfo.lip_arpflushallate = NULL;
  1707. BindInfo.lip_setndisrequest = WanIpSetRequest;
  1708. RtlInitUnicodeString(&usName,
  1709. pAdapter->usConfigKey.Buffer);
  1710. #if DBG
  1711. //
  1712. // Only set while adding or deleting the interface, which is serialized
  1713. //
  1714. pAdapter->dwRequestedIndex = dwAdapterIndex;
  1715. #endif
  1716. IPStatus = g_pfnIpAddInterface(&(pAdapter->usDeviceNameW),
  1717. pusNewIfName,
  1718. &(pAdapter->usConfigKey),
  1719. NULL,
  1720. pAdapter,
  1721. WanIpDynamicRegister,
  1722. &BindInfo,
  1723. dwAdapterIndex,
  1724. dwMediaType,
  1725. byAccessType,
  1726. byConnectionType);
  1727. if(IPStatus isnot IP_SUCCESS)
  1728. {
  1729. Trace(ADPT, ERROR,
  1730. ("AddAdapterToIp: IPAddInterface failed for adapter %w\n",
  1731. pAdapter->usDeviceNameW.Buffer));
  1732. TraceLeave(ADPT, "AddAdapterToIp");
  1733. return STATUS_UNSUCCESSFUL;
  1734. }
  1735. TraceLeave(ADPT, "AddAdapterToIp");
  1736. return STATUS_SUCCESS;
  1737. }
  1738. VOID
  1739. WanIpOpenAdapter(
  1740. IN PVOID pvContext
  1741. )
  1742. /*++
  1743. Routine Description:
  1744. Called by IP when the adapter from its IPAddInterface() call
  1745. Locks:
  1746. Arguments:
  1747. pvContext Pointer to the ADAPTER structure
  1748. Return Value:
  1749. None
  1750. --*/
  1751. {
  1752. PADAPTER pAdapter;
  1753. KIRQL kiIrql;
  1754. PLIST_ENTRY pleNode;
  1755. TraceEnter(ADPT, "WanOpenAdapter");
  1756. pAdapter = (PADAPTER)pvContext;
  1757. RtAcquireSpinLock(&(pAdapter->rlLock),
  1758. &kiIrql);
  1759. //
  1760. // Set the state to added
  1761. //
  1762. pAdapter->byState = AS_ADDED;
  1763. //
  1764. // One reference for the fact that we added the adapter to IP
  1765. //
  1766. ReferenceAdapter(pAdapter);
  1767. //
  1768. // Wake up the thread that caused this
  1769. //
  1770. RtAssert(pAdapter->pkeChangeEvent);
  1771. KeSetEvent(pAdapter->pkeChangeEvent,
  1772. 0,
  1773. FALSE);
  1774. RtReleaseSpinLock(&(pAdapter->rlLock),
  1775. kiIrql);
  1776. TraceLeave(ADPT, "WanOpenAdapter");
  1777. }
  1778. VOID
  1779. WanpUnmapAdapter(
  1780. PADAPTER pAdapter
  1781. )
  1782. /*++
  1783. Routine Description:
  1784. This function moves an adapter from the mapped list and puts it on
  1785. the free list
  1786. Locks:
  1787. Called with no locks held, but not necessarily at PASSIVE.
  1788. The adapter and adapter list locks are acquired
  1789. Arguments:
  1790. pAdapter
  1791. Return Value:
  1792. None
  1793. --*/
  1794. {
  1795. KIRQL kiIrql;
  1796. EnterWriter(&g_rwlAdapterLock,
  1797. &kiIrql);
  1798. #if DBG
  1799. //
  1800. // Make sure the adapter is on the mapped list
  1801. //
  1802. RtAssert(IsEntryOnList(&g_leMappedAdapterList,
  1803. &(pAdapter->leAdapterLink)));
  1804. #endif
  1805. RtAcquireSpinLockAtDpcLevel(&(pAdapter->rlLock));
  1806. RemoveEntryList(&(pAdapter->leAdapterLink));
  1807. g_ulNumMappedAdapters--;
  1808. InsertHeadList(&g_leAddedAdapterList,
  1809. &(pAdapter->leAdapterLink));
  1810. g_ulNumAddedAdapters++;
  1811. pAdapter->byState = AS_ADDED;
  1812. pAdapter->pInterface = NULL;
  1813. RtReleaseSpinLockFromDpcLevel(&(pAdapter->rlLock));
  1814. //
  1815. // Queue a work item if there is none queued, and we are not
  1816. // shutting down
  1817. //
  1818. RtAcquireSpinLockAtDpcLevel(&g_rlStateLock);
  1819. if((g_bRemovalInProgress isnot TRUE) and
  1820. (g_dwDriverState is DRIVER_STARTED))
  1821. {
  1822. g_bRemovalInProgress = TRUE;
  1823. ExInitializeWorkItem(&g_wqiWorkItem,
  1824. WanpRemoveSomeAddedAdaptersFromIp,
  1825. (PVOID)FALSE);
  1826. ExQueueWorkItem(&g_wqiWorkItem,
  1827. DelayedWorkQueue);
  1828. }
  1829. RtReleaseSpinLockFromDpcLevel(&g_rlStateLock);
  1830. ExitWriter(&g_rwlAdapterLock,
  1831. kiIrql);
  1832. return;
  1833. }
  1834. VOID
  1835. WanpRemoveSomeAddedAdaptersFromIp(
  1836. PVOID pvContext
  1837. )
  1838. /*++
  1839. Routine Description:
  1840. We queue this function to a work item to delete adapter(s) from IP when
  1841. the connection is torn down. Unlike the next function, this
  1842. (i) only removes added (but unmapped) adapters and
  1843. (ii) removes the adapters one at a time.
  1844. This allows another connection to move an adapter from the added list
  1845. to the free list while we are deleting another adapter from IP
  1846. Locks:
  1847. Must be called at passive
  1848. Acquires the adapter list lock as WRITER and the lock for each adapter
  1849. Arguments:
  1850. pvContext
  1851. Return Value:
  1852. None
  1853. --*/
  1854. {
  1855. PADAPTER pAdapter;
  1856. KIRQL kiIrql;
  1857. PLIST_ENTRY pleNode;
  1858. NTSTATUS nStatus;
  1859. KEVENT keChangeEvent;
  1860. PASSIVE_ENTRY();
  1861. UNREFERENCED_PARAMETER(pvContext);
  1862. KeInitializeEvent(&keChangeEvent,
  1863. SynchronizationEvent,
  1864. FALSE);
  1865. EnterWriter(&g_rwlAdapterLock,
  1866. &kiIrql);
  1867. while(!IsListEmpty(&g_leAddedAdapterList))
  1868. {
  1869. pleNode = RemoveHeadList(&g_leAddedAdapterList);
  1870. g_ulNumAddedAdapters--;
  1871. pAdapter = CONTAINING_RECORD(pleNode,
  1872. ADAPTER,
  1873. leAdapterLink);
  1874. RtAcquireSpinLockAtDpcLevel(&(pAdapter->rlLock));
  1875. pAdapter->byState = AS_REMOVING;
  1876. //
  1877. // Since we are changing the state, no one else should be also
  1878. // changing the state
  1879. //
  1880. RtAssert(pAdapter->pkeChangeEvent is NULL);
  1881. pAdapter->pkeChangeEvent = &keChangeEvent;
  1882. //
  1883. // Insert it into the change list
  1884. //
  1885. InsertHeadList(&g_leChangeAdapterList,
  1886. &(pAdapter->leAdapterLink));
  1887. RtReleaseSpinLockFromDpcLevel(&(pAdapter->rlLock));
  1888. ExitWriter(&g_rwlAdapterLock,
  1889. kiIrql);
  1890. //
  1891. // Delete from IP but dont clear the index
  1892. //
  1893. g_pfnIpDeleteInterface(pAdapter->pvIpContext,
  1894. FALSE);
  1895. //
  1896. // Wait till the CloseAdapter completes
  1897. //
  1898. nStatus = KeWaitForSingleObject(&keChangeEvent,
  1899. Executive,
  1900. KernelMode,
  1901. FALSE,
  1902. NULL);
  1903. RtAssert(nStatus is STATUS_SUCCESS);
  1904. Trace(ADPT, INFO,
  1905. ("RemoveSomeAddedAdaptersFromIp: Removed %S from Ip\n",
  1906. pAdapter->usDeviceNameW.Buffer));
  1907. //
  1908. // Remove from the change list and put on the free list
  1909. //
  1910. EnterWriter(&g_rwlAdapterLock,
  1911. &kiIrql);
  1912. RtAcquireSpinLockAtDpcLevel(&(pAdapter->rlLock));
  1913. #if DBG
  1914. RtAssert(IsEntryOnList(&g_leChangeAdapterList,
  1915. &(pAdapter->leAdapterLink)));
  1916. #endif
  1917. RemoveEntryList(&(pAdapter->leAdapterLink));
  1918. pAdapter->byState = AS_FREE;
  1919. pAdapter->pkeChangeEvent = NULL;
  1920. InsertHeadList(&g_leFreeAdapterList,
  1921. &(pAdapter->leAdapterLink));
  1922. g_ulNumFreeAdapters++;
  1923. //
  1924. // If anyone is waiting on a state change, notify them
  1925. //
  1926. for(pleNode = pAdapter->leEventList.Flink;
  1927. pleNode isnot &(pAdapter->leEventList);
  1928. pleNode = pleNode->Flink)
  1929. {
  1930. PWAN_EVENT_NODE pTempEvent;
  1931. pTempEvent = CONTAINING_RECORD(pleNode,
  1932. WAN_EVENT_NODE,
  1933. leEventLink);
  1934. KeSetEvent(&(pTempEvent->keEvent),
  1935. 0,
  1936. FALSE);
  1937. }
  1938. RtReleaseSpinLockFromDpcLevel(&(pAdapter->rlLock));
  1939. }
  1940. //
  1941. // We are done with the APC
  1942. //
  1943. g_bRemovalInProgress = FALSE;
  1944. ExitWriter(&g_rwlAdapterLock,
  1945. kiIrql);
  1946. return;
  1947. }
  1948. VOID
  1949. WanpRemoveAllAdaptersFromIp(
  1950. VOID
  1951. )
  1952. /*++
  1953. Routine Description:
  1954. This is a cleanup function called to remove all adapters (added and
  1955. mapped) from IP.
  1956. Locks:
  1957. Acquired the g_rwlAdapterLock as WRITER
  1958. Also acquire each adapter's lock when changing state
  1959. Arguments:
  1960. None
  1961. Return Value:
  1962. None
  1963. --*/
  1964. {
  1965. PADAPTER pAdapter;
  1966. KIRQL kiIrql;
  1967. LIST_ENTRY leTempHead, *pleNode;
  1968. NTSTATUS nStatus;
  1969. KEVENT keChangeEvent;
  1970. WAN_EVENT_NODE TempEvent;
  1971. PASSIVE_ENTRY();
  1972. KeInitializeEvent(&keChangeEvent,
  1973. SynchronizationEvent,
  1974. FALSE);
  1975. KeInitializeEvent(&(TempEvent.keEvent),
  1976. SynchronizationEvent,
  1977. FALSE);
  1978. InitializeListHead(&leTempHead);
  1979. EnterWriter(&g_rwlAdapterLock,
  1980. &kiIrql);
  1981. //
  1982. // First wait on any adapter in the change list to get out
  1983. // of the change state. Once that is done it is either added to ip
  1984. // or not, and we can deal with those two cases. This is to handle
  1985. // the case where we get an unbind in the middle of a status indication
  1986. //
  1987. while(!IsListEmpty(&g_leChangeAdapterList))
  1988. {
  1989. pleNode = g_leChangeAdapterList.Flink;
  1990. pAdapter = CONTAINING_RECORD(pleNode,
  1991. ADAPTER,
  1992. leAdapterLink);
  1993. RtAcquireSpinLockAtDpcLevel(&(pAdapter->rlLock));
  1994. InsertTailList(&(pAdapter->leEventList),
  1995. &(TempEvent.leEventLink));
  1996. ReferenceAdapter(pAdapter);
  1997. RtReleaseSpinLockFromDpcLevel(&(pAdapter->rlLock));
  1998. ExitWriter(&g_rwlAdapterLock,
  1999. kiIrql);
  2000. nStatus = KeWaitForSingleObject(&(TempEvent.keEvent),
  2001. Executive,
  2002. KernelMode,
  2003. FALSE,
  2004. NULL);
  2005. RtAssert(nStatus is STATUS_SUCCESS);
  2006. EnterWriter(&g_rwlAdapterLock,
  2007. &kiIrql);
  2008. #if DBG
  2009. RtAssert(!IsEntryOnList(&g_leChangeAdapterList,
  2010. &(pAdapter->leAdapterLink)));
  2011. #endif
  2012. RtAcquireSpinLockAtDpcLevel(&(pAdapter->rlLock));
  2013. RemoveEntryList(&(TempEvent.leEventLink));
  2014. DereferenceAdapter(pAdapter);
  2015. RtReleaseSpinLockFromDpcLevel(&(pAdapter->rlLock));
  2016. }
  2017. //
  2018. // Set the state of all the adapters to removing...
  2019. //
  2020. while(!IsListEmpty(&g_leMappedAdapterList))
  2021. {
  2022. pleNode = RemoveHeadList(&g_leMappedAdapterList);
  2023. g_ulNumMappedAdapters--;
  2024. pAdapter = CONTAINING_RECORD(pleNode,
  2025. ADAPTER,
  2026. leAdapterLink);
  2027. RtAcquireSpinLockAtDpcLevel(&(pAdapter->rlLock));
  2028. pAdapter->byState = AS_REMOVING;
  2029. InsertHeadList(&leTempHead,
  2030. pleNode);
  2031. RtReleaseSpinLockFromDpcLevel(&(pAdapter->rlLock));
  2032. }
  2033. RtAssert(IsListEmpty(&g_leMappedAdapterList));
  2034. while(!IsListEmpty(&g_leAddedAdapterList))
  2035. {
  2036. pleNode = RemoveHeadList(&g_leAddedAdapterList);
  2037. g_ulNumAddedAdapters--;
  2038. pAdapter = CONTAINING_RECORD(pleNode,
  2039. ADAPTER,
  2040. leAdapterLink);
  2041. RtAcquireSpinLockAtDpcLevel(&(pAdapter->rlLock));
  2042. pAdapter->byState = AS_REMOVING;
  2043. InsertHeadList(&leTempHead,
  2044. pleNode);
  2045. RtReleaseSpinLockFromDpcLevel(&(pAdapter->rlLock));
  2046. }
  2047. RtAssert(IsListEmpty(&g_leAddedAdapterList));
  2048. ExitWriter(&g_rwlAdapterLock,
  2049. kiIrql);
  2050. //
  2051. // No go through the list of adapters to remove from IP
  2052. //
  2053. while(!IsListEmpty(&leTempHead))
  2054. {
  2055. pleNode = RemoveHeadList(&leTempHead);
  2056. pAdapter = CONTAINING_RECORD(pleNode,
  2057. ADAPTER,
  2058. leAdapterLink);
  2059. EnterWriter(&g_rwlAdapterLock,
  2060. &kiIrql);
  2061. RtAcquireSpinLockAtDpcLevel(&(pAdapter->rlLock));
  2062. //
  2063. // Since we are changing the state, no one else should be also
  2064. // changing the state
  2065. //
  2066. RtAssert(pAdapter->pkeChangeEvent is NULL);
  2067. pAdapter->pkeChangeEvent = &keChangeEvent;
  2068. //
  2069. // Insert it into the change list
  2070. //
  2071. InsertHeadList(&g_leChangeAdapterList,
  2072. &(pAdapter->leAdapterLink));
  2073. RtReleaseSpinLockFromDpcLevel(&(pAdapter->rlLock));
  2074. ExitWriter(&g_rwlAdapterLock,
  2075. kiIrql);
  2076. //
  2077. // Delete from IP but dont clear the index
  2078. //
  2079. g_pfnIpDeleteInterface(pAdapter->pvIpContext,
  2080. FALSE);
  2081. //
  2082. // Wait till the CloseAdapter completes
  2083. //
  2084. nStatus = KeWaitForSingleObject(&keChangeEvent,
  2085. Executive,
  2086. KernelMode,
  2087. FALSE,
  2088. NULL);
  2089. RtAssert(nStatus is STATUS_SUCCESS);
  2090. Trace(ADPT, INFO,
  2091. ("RemoveAllAdaptersFromIp: Removed %S from Ip\n",
  2092. pAdapter->usDeviceNameW.Buffer));
  2093. //
  2094. // Remove from the change list and put on the free list
  2095. //
  2096. EnterWriter(&g_rwlAdapterLock,
  2097. &kiIrql);
  2098. #if DBG
  2099. RtAssert(IsEntryOnList(&g_leChangeAdapterList,
  2100. &(pAdapter->leAdapterLink)));
  2101. #endif
  2102. RtAcquireSpinLockAtDpcLevel(&(pAdapter->rlLock));
  2103. RemoveEntryList(&(pAdapter->leAdapterLink));
  2104. pAdapter->byState = AS_FREE;
  2105. pAdapter->pkeChangeEvent = NULL;
  2106. InsertHeadList(&g_leFreeAdapterList,
  2107. &(pAdapter->leAdapterLink));
  2108. g_ulNumFreeAdapters++;
  2109. //
  2110. // If anyone is waiting on a state change, notify them
  2111. //
  2112. for(pleNode = pAdapter->leEventList.Flink;
  2113. pleNode isnot &(pAdapter->leEventList);
  2114. pleNode = pleNode->Flink)
  2115. {
  2116. PWAN_EVENT_NODE pTempEvent;
  2117. pTempEvent = CONTAINING_RECORD(pleNode,
  2118. WAN_EVENT_NODE,
  2119. leEventLink);
  2120. KeSetEvent(&(pTempEvent->keEvent),
  2121. 0,
  2122. FALSE);
  2123. }
  2124. RtReleaseSpinLockFromDpcLevel(&(pAdapter->rlLock));
  2125. ExitWriter(&g_rwlAdapterLock,
  2126. kiIrql);
  2127. }
  2128. //
  2129. // The write is atomic so we dont need to
  2130. // acquire a lock
  2131. //
  2132. g_bRemovalInProgress = FALSE;
  2133. return;
  2134. }
  2135. VOID
  2136. WanIpCloseAdapter(
  2137. IN PVOID pvContext
  2138. )
  2139. /*++
  2140. Routine Description:
  2141. Called by IP when it wants to close an adapter. Currently this is done
  2142. from CloseNets() and IPDelInterface().
  2143. Locks:
  2144. Acquires the adapter lock
  2145. Arguments:
  2146. pvContext Pointer to the ADAPTER
  2147. Return Value:
  2148. None
  2149. --*/
  2150. {
  2151. PADAPTER pAdapter;
  2152. KIRQL kiIrql;
  2153. PLIST_ENTRY pleNode;
  2154. TraceEnter(ADPT, "IpCloseAdapter");
  2155. pAdapter = (PADAPTER)pvContext;
  2156. RtAcquireSpinLock(&(pAdapter->rlLock),
  2157. &kiIrql);
  2158. pAdapter->pvIpContext = NULL;
  2159. //
  2160. // Wake up the thread that caused this
  2161. //
  2162. RtAssert(pAdapter->pkeChangeEvent);
  2163. KeSetEvent(pAdapter->pkeChangeEvent,
  2164. 0,
  2165. FALSE);
  2166. RtReleaseSpinLock(&(pAdapter->rlLock),
  2167. kiIrql);
  2168. DereferenceAdapter(pAdapter);
  2169. TraceLeave(ADPT, "IpCloseAdapter");
  2170. }
  2171. VOID
  2172. WanpRemoveAllAdapters(
  2173. VOID
  2174. )
  2175. /*++
  2176. Routine Description:
  2177. Locks:
  2178. Arguments:
  2179. Return Value:
  2180. --*/
  2181. {
  2182. LIST_ENTRY leTempHead, *pleNode;
  2183. KIRQL kiIrql;
  2184. NTSTATUS nStatus;
  2185. TraceEnter(ADPT, "RemoveAllAdapters");
  2186. //
  2187. // We can have mapped adapters.
  2188. //
  2189. //RtAssert(IsListEmpty(&g_leMappedAdapterList));
  2190. //
  2191. // Just call RemoveAllAdaptersFromIp()
  2192. //
  2193. WanpRemoveAllAdaptersFromIp();
  2194. //
  2195. // At this point the movement from one list to another is frozen
  2196. // because we dont accept LinkUp's from Ndiswan
  2197. //
  2198. RtAssert(IsListEmpty(&g_leAddedAdapterList));
  2199. //RtAssert(IsListEmpty(&g_leMappedAdapterList));
  2200. //RtAssert(IsListEmpty(&g_leChangeAdapterList));
  2201. EnterWriter(&g_rwlAdapterLock,
  2202. &kiIrql);
  2203. //
  2204. // First clean out the free adapters
  2205. //
  2206. while(!IsListEmpty(&g_leFreeAdapterList))
  2207. {
  2208. PADAPTER pAdapterTmp;
  2209. pleNode = RemoveHeadList(&g_leFreeAdapterList);
  2210. g_ulNumFreeAdapters--;
  2211. pAdapterTmp = CONTAINING_RECORD(pleNode,
  2212. ADAPTER,
  2213. leAdapterLink);
  2214. RtAcquireSpinLockAtDpcLevel(&(pAdapterTmp->rlLock));
  2215. RtAssert(pAdapterTmp->byState is AS_FREE);
  2216. pAdapterTmp->byState = 0xFF;
  2217. RtReleaseSpinLockFromDpcLevel(&(pAdapterTmp->rlLock));
  2218. DereferenceAdapter(pAdapterTmp);
  2219. }
  2220. //
  2221. // At the end of this, also remove the server adapter
  2222. //
  2223. if(g_pServerAdapter)
  2224. {
  2225. PADAPTER pAdapter;
  2226. PUMODE_INTERFACE pInterface;
  2227. BOOLEAN bCrossRefed;
  2228. RtAcquireSpinLockAtDpcLevel(&(g_pServerAdapter->rlLock));
  2229. RtAcquireSpinLockAtDpcLevel(&(g_pServerInterface->rlLock));
  2230. pAdapter = g_pServerAdapter;
  2231. pInterface = g_pServerInterface;
  2232. if(g_pServerAdapter->byState is AS_MAPPED)
  2233. {
  2234. RtAssert(g_pServerAdapter->pInterface is g_pServerInterface);
  2235. RtAssert(g_pServerInterface->pAdapter is g_pServerAdapter);
  2236. bCrossRefed = TRUE;
  2237. }
  2238. else
  2239. {
  2240. RtAssert(g_pServerAdapter->pInterface is NULL);
  2241. RtAssert(g_pServerInterface->pAdapter is NULL);
  2242. RtAssert(g_pServerAdapter->byState is AS_FREE);
  2243. bCrossRefed = FALSE;
  2244. }
  2245. //
  2246. // Remove the global pointers
  2247. //
  2248. g_pServerInterface = NULL;
  2249. g_pServerAdapter = NULL;
  2250. //
  2251. // Remove the mapping from interface
  2252. //
  2253. pInterface->pAdapter = NULL;
  2254. pAdapter->pInterface = NULL;
  2255. pAdapter->byState = AS_REMOVING;
  2256. RtReleaseSpinLockFromDpcLevel(&(pInterface->rlLock));
  2257. if(bCrossRefed)
  2258. {
  2259. //
  2260. // Deref because the cross mapping is removed
  2261. //
  2262. DereferenceAdapter(pAdapter);
  2263. DereferenceInterface(pInterface);
  2264. }
  2265. if(pAdapter->pvIpContext)
  2266. {
  2267. KEVENT keChangeEvent;
  2268. KeInitializeEvent(&keChangeEvent,
  2269. SynchronizationEvent,
  2270. FALSE);
  2271. //
  2272. // Since we are changing the state, no one else should be also
  2273. // changing the state
  2274. //
  2275. RtAssert(pAdapter->pkeChangeEvent is NULL);
  2276. pAdapter->pkeChangeEvent = &keChangeEvent;
  2277. RtReleaseSpinLockFromDpcLevel(&(pAdapter->rlLock));
  2278. ExitWriter(&g_rwlAdapterLock,
  2279. kiIrql);
  2280. //
  2281. // Delete from IP, but dont clear the index
  2282. //
  2283. g_pfnIpDeleteInterface(pAdapter->pvIpContext,
  2284. FALSE);
  2285. nStatus = KeWaitForSingleObject(&keChangeEvent,
  2286. Executive,
  2287. KernelMode,
  2288. FALSE,
  2289. NULL);
  2290. RtAssert(nStatus is STATUS_SUCCESS);
  2291. Trace(ADPT, INFO,
  2292. ("RemoveAllAdapters: Removed %S (server adapter) from Ip\n",
  2293. pAdapter->usDeviceNameW.Buffer));
  2294. EnterWriter(&g_rwlAdapterLock,
  2295. &kiIrql);
  2296. RtAcquireSpinLockAtDpcLevel(&(pAdapter->rlLock));
  2297. pAdapter->byState = AS_FREE;
  2298. pAdapter->pkeChangeEvent = NULL;
  2299. //
  2300. // If anyone is waiting on a state change, notify them
  2301. //
  2302. for(pleNode = pAdapter->leEventList.Flink;
  2303. pleNode isnot &(pAdapter->leEventList);
  2304. pleNode = pleNode->Flink)
  2305. {
  2306. PWAN_EVENT_NODE pTempEvent;
  2307. pTempEvent = CONTAINING_RECORD(pleNode,
  2308. WAN_EVENT_NODE,
  2309. leEventLink);
  2310. KeSetEvent(&(pTempEvent->keEvent),
  2311. 0,
  2312. FALSE);
  2313. }
  2314. RtReleaseSpinLockFromDpcLevel(&(pAdapter->rlLock));
  2315. } else {
  2316. RtReleaseSpinLockFromDpcLevel(&(pAdapter->rlLock));
  2317. }
  2318. //
  2319. // Deref because the global pointers are null
  2320. //
  2321. DereferenceAdapter(pAdapter);
  2322. DereferenceInterface(pInterface);
  2323. }
  2324. ExitWriter(&g_rwlAdapterLock,
  2325. kiIrql);
  2326. TraceLeave(ADPT, "RemoveAllAdapters");
  2327. }
  2328. INT
  2329. WanIpDynamicRegister(
  2330. IN PNDIS_STRING InterfaceName,
  2331. IN PVOID pvIpInterfaceContext,
  2332. IN struct _IP_HANDLERS * IpHandlers,
  2333. IN struct LLIPBindInfo * ARPBindInfo,
  2334. IN UINT uiInterfaceNumber
  2335. )
  2336. {
  2337. PADAPTER pAdapter;
  2338. KIRQL irql;
  2339. TraceEnter(ADPT, "IpDynamicRegister");
  2340. pAdapter = (PADAPTER)(ARPBindInfo->lip_context);
  2341. RtAcquireSpinLock(&(pAdapter->rlLock),
  2342. &irql);
  2343. #if DBG
  2344. Trace(ADPT, INFO,
  2345. ("IpDynamicRegister: IP called out to dynamically register %s\n",
  2346. pAdapter->asDeviceNameA.Buffer));
  2347. #endif
  2348. pAdapter->pvIpContext = pvIpInterfaceContext;
  2349. pAdapter->dwAdapterIndex = uiInterfaceNumber;
  2350. #if DBG
  2351. RtAssert(pAdapter->dwAdapterIndex is pAdapter->dwRequestedIndex);
  2352. #endif
  2353. if(g_pfnIpRcv is NULL)
  2354. {
  2355. g_pfnIpRcv = IpHandlers->IpRcvHandler;
  2356. g_pfnIpRcvComplete = IpHandlers->IpRcvCompleteHandler;
  2357. g_pfnIpSendComplete = IpHandlers->IpTxCompleteHandler;
  2358. g_pfnIpTDComplete = IpHandlers->IpTransferCompleteHandler;
  2359. g_pfnIpStatus = IpHandlers->IpStatusHandler;
  2360. g_pfnIpRcvPkt = IpHandlers->IpRcvPktHandler;
  2361. g_pfnIpPnp = IpHandlers->IpPnPHandler;
  2362. }
  2363. RtReleaseSpinLock(&(pAdapter->rlLock),
  2364. irql);
  2365. TraceLeave(ADPT, "IpDynamicRegister");
  2366. return TRUE;
  2367. }
  2368. NDIS_STATUS
  2369. WanpDoNdisRequest(
  2370. IN NDIS_REQUEST_TYPE RequestType,
  2371. IN NDIS_OID Oid,
  2372. IN PVOID pvInfo,
  2373. IN UINT uiInBufferLen,
  2374. IN PWANARP_NDIS_REQUEST_CONTEXT pRequestContext,
  2375. IN PFNWANARP_REQUEST_COMPLETION_HANDLER pfnCompletionHandler OPTIONAL
  2376. )
  2377. /*++
  2378. Routine Description:
  2379. Wrapper for the NdisRequest call. We create a request context and submit
  2380. the call to NDIS. If it returns synchronously, we fake asynchronous
  2381. behaviour by call the completion routine.
  2382. Locks:
  2383. None. The ndiswan binding must be valid for the duration of the call
  2384. Arguments:
  2385. RequestType Type of NDIS request
  2386. Oid Ndis OID to set or get
  2387. pvInfo Opaque OID specific info
  2388. pRequestContext A context for this request
  2389. pfnCompletionHandler Completion handler for this request
  2390. Return Value:
  2391. STATUS_INVALID_PARAMETER
  2392. NDIS_STATUS_RESOURCES
  2393. NDIS_STATUS_PENDING
  2394. other error
  2395. --*/
  2396. {
  2397. PNDIS_REQUEST pRequest;
  2398. NDIS_STATUS nsStatus;
  2399. if((RequestType isnot NdisRequestSetInformation) and
  2400. (RequestType isnot NdisRequestQueryInformation))
  2401. {
  2402. return STATUS_INVALID_PARAMETER;
  2403. }
  2404. pRequestContext->pfnCompletionRoutine = pfnCompletionHandler;
  2405. pRequest = &(pRequestContext->NdisRequest);
  2406. pRequest->RequestType = RequestType;
  2407. if(RequestType is NdisRequestSetInformation)
  2408. {
  2409. pRequest->DATA.SET_INFORMATION.Oid = Oid;
  2410. pRequest->DATA.SET_INFORMATION.InformationBuffer = pvInfo;
  2411. pRequest->DATA.SET_INFORMATION.InformationBufferLength = uiInBufferLen;
  2412. }
  2413. else
  2414. {
  2415. pRequest->DATA.QUERY_INFORMATION.Oid = Oid;
  2416. pRequest->DATA.QUERY_INFORMATION.InformationBuffer = pvInfo;
  2417. pRequest->DATA.QUERY_INFORMATION.InformationBufferLength = uiInBufferLen;
  2418. }
  2419. //
  2420. // Submit the request.
  2421. //
  2422. NdisRequest(&nsStatus,
  2423. g_nhNdiswanBinding,
  2424. pRequest);
  2425. if(nsStatus isnot NDIS_STATUS_PENDING)
  2426. {
  2427. //
  2428. // If it finished synchronously, call the handler
  2429. //
  2430. if(pfnCompletionHandler)
  2431. {
  2432. (pfnCompletionHandler)(g_nhNdiswanBinding,
  2433. pRequestContext,
  2434. nsStatus);
  2435. }
  2436. if(nsStatus is NDIS_STATUS_SUCCESS)
  2437. {
  2438. //
  2439. // Always make this look asynchronous
  2440. //
  2441. nsStatus = NDIS_STATUS_PENDING;
  2442. }
  2443. }
  2444. return nsStatus;
  2445. }
  2446. VOID
  2447. WanNdisRequestComplete(
  2448. IN NDIS_HANDLE nhHandle,
  2449. IN PNDIS_REQUEST pRequest,
  2450. IN NDIS_STATUS nsStatus
  2451. )
  2452. /*++
  2453. Routine Description:
  2454. Handler called by NDIS when it is done processing our request
  2455. Locks:
  2456. None
  2457. Arguments:
  2458. nhHandle NdisHandle of the adapter to which the request was submitted
  2459. pRequest The original request
  2460. nsStatus The status returned by the adapter
  2461. Return Value:
  2462. None
  2463. --*/
  2464. {
  2465. PWANARP_NDIS_REQUEST_CONTEXT pRequestContext;
  2466. //
  2467. // Get a pointer to the context
  2468. //
  2469. pRequestContext = CONTAINING_RECORD(pRequest,
  2470. WANARP_NDIS_REQUEST_CONTEXT,
  2471. NdisRequest);
  2472. if(pRequestContext->pfnCompletionRoutine is NULL)
  2473. {
  2474. //
  2475. // No more handlers to call, we are done
  2476. //
  2477. RtFree(pRequestContext);
  2478. return;
  2479. }
  2480. //
  2481. // If the request is OID_GEN_TRANSPORT_HEADER_OFFSET, ignore the error
  2482. //
  2483. RtAssert(pRequest is &(pRequestContext->NdisRequest));
  2484. if((pRequest->RequestType is NdisRequestSetInformation) and
  2485. (pRequest->DATA.SET_INFORMATION.Oid is OID_GEN_TRANSPORT_HEADER_OFFSET))
  2486. {
  2487. nsStatus = NDIS_STATUS_SUCCESS;
  2488. }
  2489. //
  2490. // Call the request complete handler
  2491. //
  2492. (pRequestContext->pfnCompletionRoutine)(nhHandle,
  2493. pRequestContext,
  2494. nsStatus);
  2495. }
  2496. PUMODE_INTERFACE
  2497. WanpFindInterfaceGivenIndex(
  2498. DWORD dwIfIndex
  2499. )
  2500. {
  2501. PLIST_ENTRY pleNode;
  2502. PUMODE_INTERFACE pIf;
  2503. for(pleNode = g_leIfList.Flink;
  2504. pleNode isnot &g_leIfList;
  2505. pleNode = pleNode->Flink)
  2506. {
  2507. pIf = CONTAINING_RECORD(pleNode,
  2508. UMODE_INTERFACE,
  2509. leIfLink);
  2510. if(pIf->dwIfIndex is dwIfIndex)
  2511. {
  2512. RtAcquireSpinLockAtDpcLevel(&(pIf->rlLock));
  2513. ReferenceInterface(pIf);
  2514. return pIf;
  2515. }
  2516. }
  2517. return NULL;
  2518. }
  2519. VOID
  2520. WanpDeleteAdapter(
  2521. IN PADAPTER pAdapter
  2522. )
  2523. {
  2524. #if DBG
  2525. Trace(ADPT, TRACE,
  2526. ("DeleteAdapter: Deleting %x %s\n",
  2527. pAdapter, pAdapter->asDeviceNameA.Buffer));
  2528. #else
  2529. Trace(ADPT, TRACE,
  2530. ("DeleteAdapter: Deleting %x\n",
  2531. pAdapter));
  2532. #endif
  2533. InterlockedDecrement(&g_ulNumAdapters);
  2534. RtFree(pAdapter);
  2535. }
  2536. NDIS_STATUS
  2537. WanNdisIpPnPEventHandler(
  2538. IN PNET_PNP_EVENT pNetPnPEvent
  2539. )
  2540. {
  2541. PWANARP_RECONFIGURE_INFO pInfo;
  2542. NTSTATUS nStatus = NDIS_STATUS_FAILURE;
  2543. RtAssert(pNetPnPEvent->NetEvent is NetEventReconfigure);
  2544. pInfo = (PWANARP_RECONFIGURE_INFO) pNetPnPEvent->Buffer;
  2545. switch (pInfo->wrcOperation)
  2546. {
  2547. case WRC_TCP_WINDOW_SIZE_UPDATE:
  2548. {
  2549. PLIST_ENTRY pleNode;
  2550. KIRQL kirql;
  2551. PADAPTER pAdapter=NULL;
  2552. RtAssert(pInfo->ulNumInterfaces is 1);
  2553. if(pInfo->ulNumInterfaces isnot 1)
  2554. {
  2555. break;
  2556. }
  2557. EnterReader(&g_rwlAdapterLock, &kirql);
  2558. for(pleNode = g_leMappedAdapterList.Flink;
  2559. pleNode != &g_leMappedAdapterList;
  2560. pleNode = pleNode->Flink)
  2561. {
  2562. pAdapter = CONTAINING_RECORD(pleNode, ADAPTER, leAdapterLink);
  2563. if(IsEqualGUID(&(pAdapter->Guid),
  2564. &pInfo->rgInterfaces[0]))
  2565. {
  2566. break;
  2567. }
  2568. }
  2569. if ((pleNode is &g_leMappedAdapterList) || pAdapter==NULL)
  2570. {
  2571. ExitReader(&g_rwlAdapterLock, kirql);
  2572. break;
  2573. }
  2574. if( (pAdapter->byState is AS_MAPPED)
  2575. && (pAdapter->pInterface)
  2576. && (pAdapter->pInterface->duUsage is DU_CALLOUT))
  2577. {
  2578. NET_PNP_EVENT pnpEvent;
  2579. IP_PNP_RECONFIG_REQUEST Request;
  2580. RtlZeroMemory(&pnpEvent, sizeof(pnpEvent));
  2581. RtlZeroMemory(&Request, sizeof(Request));
  2582. Request.version = IP_PNP_RECONFIG_VERSION;
  2583. Request.Flags = IP_PNP_FLAG_INTERFACE_TCP_PARAMETER_UPDATE;
  2584. pnpEvent.NetEvent = NetEventReconfigure;
  2585. pnpEvent.Buffer = &Request;
  2586. pnpEvent.BufferLength = sizeof(Request);
  2587. ReferenceAdapter(pAdapter);
  2588. ExitReader(&g_rwlAdapterLock, kirql);
  2589. nStatus = g_pfnIpPnp(pAdapter->pvIpContext,
  2590. &pnpEvent);
  2591. DereferenceAdapter(pAdapter);
  2592. }
  2593. else
  2594. {
  2595. ExitReader(&g_rwlAdapterLock, kirql);
  2596. }
  2597. break;
  2598. }
  2599. default:
  2600. {
  2601. RtAssert(FALSE);
  2602. nStatus = NDIS_STATUS_NOT_RECOGNIZED;
  2603. break;
  2604. }
  2605. }
  2606. return nStatus;
  2607. }
  2608. //
  2609. // Misc ndis interface functions
  2610. //
  2611. NDIS_STATUS
  2612. WanNdisPnPEvent(
  2613. IN NDIS_HANDLE nhProtocolBindingContext,
  2614. IN PNET_PNP_EVENT pNetPnPEvent
  2615. )
  2616. {
  2617. ULONG ulNumGuids, i;
  2618. NTSTATUS nStatus, nRetStatus;
  2619. PWANARP_RECONFIGURE_INFO pInfo;
  2620. TraceEnter(ADPT, "NdisPnPEvent");
  2621. if(nhProtocolBindingContext isnot (NDIS_HANDLE)0x0CABB1E5)
  2622. {
  2623. return NDIS_STATUS_NOT_RECOGNIZED;
  2624. }
  2625. if(pNetPnPEvent->NetEvent isnot NetEventReconfigure)
  2626. {
  2627. return NDIS_STATUS_SUCCESS;
  2628. }
  2629. pInfo = (PWANARP_RECONFIGURE_INFO)(pNetPnPEvent->Buffer);
  2630. if(pNetPnPEvent->BufferLength < FIELD_OFFSET(WANARP_RECONFIGURE_INFO, rgInterfaces))
  2631. {
  2632. return NDIS_STATUS_BUFFER_TOO_SHORT;
  2633. }
  2634. pInfo = (PWANARP_RECONFIGURE_INFO)(pNetPnPEvent->Buffer);
  2635. if(pInfo->wrcOperation isnot WRC_ADD_INTERFACES)
  2636. {
  2637. nStatus = WanNdisIpPnPEventHandler(pNetPnPEvent);
  2638. return nStatus;
  2639. }
  2640. //
  2641. // Make sure the length and matches with whats in the info
  2642. //
  2643. ulNumGuids = pNetPnPEvent->BufferLength -
  2644. FIELD_OFFSET(WANARP_RECONFIGURE_INFO, rgInterfaces);
  2645. ulNumGuids /= sizeof(GUID);
  2646. if(ulNumGuids < pInfo->ulNumInterfaces)
  2647. {
  2648. return STATUS_INVALID_PARAMETER;
  2649. }
  2650. //
  2651. // Now go through each guid, and if it isnt present, add it
  2652. // If we get a list of only duplicates, return SUCCESS (334575)
  2653. //
  2654. nRetStatus = STATUS_SUCCESS;
  2655. for(i = 0; i < pInfo->ulNumInterfaces; i++)
  2656. {
  2657. WCHAR rgwcDeviceBuffer[GUID_STR_LEN + 7 + 2];
  2658. WCHAR rgwcConfigBuffer[GUID_STR_LEN + 29 + 2];
  2659. PADAPTER pNewAdapter;
  2660. UNICODE_STRING usDevice;
  2661. UNICODE_STRING usConfig;
  2662. if(IsBindingPresent(&(pInfo->rgInterfaces[i])))
  2663. {
  2664. continue;
  2665. }
  2666. RtlZeroMemory(rgwcDeviceBuffer,
  2667. sizeof(rgwcDeviceBuffer));
  2668. RtlZeroMemory(rgwcConfigBuffer,
  2669. sizeof(rgwcConfigBuffer));
  2670. //
  2671. // Make sure no problems with people changing the string
  2672. //
  2673. RtAssert(((wcslen(TCPIP_IF_PREFIX) + 1 + GUID_STR_LEN) * sizeof(WCHAR)) < sizeof(rgwcDeviceBuffer));
  2674. RtAssert(((wcslen(TCPIP_REG_PREFIX) + 1 + GUID_STR_LEN) * sizeof(WCHAR)) < sizeof(rgwcConfigBuffer));
  2675. //
  2676. // Copy over the \Device part
  2677. //
  2678. RtlCopyMemory(rgwcDeviceBuffer,
  2679. TCPIP_IF_PREFIX,
  2680. wcslen(TCPIP_IF_PREFIX) * sizeof(WCHAR));
  2681. //
  2682. // Tack on a '\'
  2683. //
  2684. rgwcDeviceBuffer[wcslen(TCPIP_IF_PREFIX)] = L'\\';
  2685. //
  2686. // Convert the guid to a string. Just pass the buffer starting
  2687. // after the '\' we just catted. The conversion function returns
  2688. // an upcase string - so thats good.
  2689. //
  2690. ConvertGuidToString(&(pInfo->rgInterfaces[i]),
  2691. &(rgwcDeviceBuffer[wcslen(TCPIP_IF_PREFIX) + 1]));
  2692. //
  2693. // Create the config
  2694. //
  2695. RtlCopyMemory(rgwcConfigBuffer,
  2696. TCPIP_REG_PREFIX,
  2697. wcslen(TCPIP_REG_PREFIX) * sizeof(WCHAR));
  2698. //
  2699. // Put the device guid at the end
  2700. //
  2701. ConvertGuidToString(&(pInfo->rgInterfaces[i]),
  2702. &(rgwcConfigBuffer[wcslen(TCPIP_REG_PREFIX)]));
  2703. //
  2704. // Set up the strings
  2705. //
  2706. usDevice.Length = wcslen(rgwcDeviceBuffer) * sizeof(WCHAR);
  2707. usDevice.MaximumLength = usDevice.Length;
  2708. usDevice.Buffer = rgwcDeviceBuffer;
  2709. usConfig.Length = wcslen(rgwcConfigBuffer) * sizeof(WCHAR);
  2710. usConfig.MaximumLength = usConfig.Length;
  2711. usConfig.Buffer = rgwcConfigBuffer;
  2712. //
  2713. // Create an adapter with this name and config
  2714. //
  2715. pNewAdapter = NULL;
  2716. Trace(ADPT, INFO,
  2717. ("NdisPnPEvent: Calling create adapter for %S %S\n",
  2718. usConfig.Buffer,
  2719. usDevice.Buffer));
  2720. nStatus = WanpCreateAdapter(&(pInfo->rgInterfaces[i]),
  2721. &usConfig,
  2722. &usDevice,
  2723. &pNewAdapter);
  2724. if(nStatus isnot STATUS_SUCCESS)
  2725. {
  2726. Trace(ADPT, ERROR,
  2727. ("NdisPnPEvent: Err %x creating adapter for %S (%S)\n",
  2728. nStatus,
  2729. usConfig.Buffer,
  2730. usDevice.Buffer));
  2731. }
  2732. else
  2733. {
  2734. //
  2735. // If even one succeeds, we return success
  2736. //
  2737. nRetStatus = STATUS_SUCCESS;
  2738. }
  2739. }
  2740. return nRetStatus;
  2741. }
  2742. VOID
  2743. WanNdisResetComplete(
  2744. NDIS_HANDLE Handle,
  2745. NDIS_STATUS Status
  2746. )
  2747. {
  2748. // We dont do anything here.
  2749. }
  2750. BOOLEAN
  2751. IsBindingPresent(
  2752. IN GUID *pGuid
  2753. )
  2754. /*++
  2755. Routine Description:
  2756. Code to catch duplicate bind notifications
  2757. Locks:
  2758. acquires adapter list lock
  2759. Arguments:
  2760. pGuid Guid of the adapter
  2761. Return Value:
  2762. NO_ERROR
  2763. --*/
  2764. {
  2765. BOOLEAN bFound;
  2766. PADAPTER pAdapter;
  2767. PLIST_ENTRY pleNode;
  2768. KIRQL kiIrql;
  2769. EnterReader(&g_rwlAdapterLock, &kiIrql);
  2770. for(pleNode = g_leAddedAdapterList.Flink;
  2771. pleNode != &g_leAddedAdapterList;
  2772. pleNode = pleNode->Flink)
  2773. {
  2774. pAdapter = CONTAINING_RECORD(pleNode, ADAPTER, leAdapterLink);
  2775. if(IsEqualGUID(&(pAdapter->Guid),
  2776. pGuid))
  2777. {
  2778. ExitReader(&g_rwlAdapterLock, kiIrql);
  2779. return TRUE;
  2780. }
  2781. }
  2782. for(pleNode = g_leMappedAdapterList.Flink;
  2783. pleNode != &g_leMappedAdapterList;
  2784. pleNode = pleNode->Flink)
  2785. {
  2786. pAdapter = CONTAINING_RECORD(pleNode, ADAPTER, leAdapterLink);
  2787. if(IsEqualGUID(&(pAdapter->Guid),
  2788. pGuid))
  2789. {
  2790. ExitReader(&g_rwlAdapterLock, kiIrql);
  2791. return TRUE;
  2792. }
  2793. }
  2794. for(pleNode = g_leFreeAdapterList.Flink;
  2795. pleNode != &g_leFreeAdapterList;
  2796. pleNode = pleNode->Flink)
  2797. {
  2798. pAdapter = CONTAINING_RECORD(pleNode, ADAPTER, leAdapterLink);
  2799. if(IsEqualGUID(&(pAdapter->Guid),
  2800. pGuid))
  2801. {
  2802. ExitReader(&g_rwlAdapterLock, kiIrql);
  2803. return TRUE;
  2804. }
  2805. }
  2806. for(pleNode = g_leChangeAdapterList.Flink;
  2807. pleNode != &g_leChangeAdapterList;
  2808. pleNode = pleNode->Flink)
  2809. {
  2810. pAdapter = CONTAINING_RECORD(pleNode, ADAPTER, leAdapterLink);
  2811. if(IsEqualGUID(&(pAdapter->Guid),
  2812. pGuid))
  2813. {
  2814. ExitReader(&g_rwlAdapterLock, kiIrql);
  2815. return TRUE;
  2816. }
  2817. }
  2818. if(g_pServerAdapter)
  2819. {
  2820. if(IsEqualGUID(&(g_pServerAdapter->Guid),
  2821. pGuid))
  2822. {
  2823. ExitReader(&g_rwlAdapterLock, kiIrql);
  2824. return TRUE;
  2825. }
  2826. }
  2827. ExitReader(&g_rwlAdapterLock, kiIrql);
  2828. return FALSE;
  2829. }