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.

1499 lines
43 KiB

  1. /*++
  2. Copyright(c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. brdgprot.c
  5. Abstract:
  6. Ethernet MAC level bridge.
  7. Protocol section
  8. Author:
  9. Mark Aiken
  10. (original bridge by Jameel Hyder)
  11. Environment:
  12. Kernel mode driver
  13. Revision History:
  14. Sept 1999 - Original version
  15. Feb 2000 - Overhaul
  16. --*/
  17. #pragma warning( push, 3 )
  18. #include <ndis.h>
  19. #pragma warning( pop )
  20. #include <netevent.h>
  21. #include "bridge.h"
  22. #include "brdgprot.h"
  23. #include "brdgmini.h"
  24. #include "brdgfwd.h"
  25. #include "brdgtbl.h"
  26. #include "brdgbuf.h"
  27. #include "brdgctl.h"
  28. #include "brdgsta.h"
  29. #include "brdgcomp.h"
  30. // ===========================================================================
  31. //
  32. // GLOBALS
  33. //
  34. // ===========================================================================
  35. // NDIS handle for our identity as a protocol
  36. NDIS_HANDLE gProtHandle = NULL;
  37. NDIS_MEDIUM gMediumArray[1] =
  38. {
  39. NdisMedium802_3 // Ethernet only, can add other media later
  40. };
  41. // The adapter list and associated lock
  42. PADAPT gAdapterList = {0};
  43. NDIS_RW_LOCK gAdapterListLock;
  44. // Whether we have called the miniport sections BindsComplete() function yet
  45. // 0 == no, 1 == yes
  46. LONG gHaveInitedMiniport = 0L;
  47. // A lock for all the adapters' link speed and media connect characteristics
  48. NDIS_RW_LOCK gAdapterCharacteristicsLock;
  49. // Number of adapters. Doesn't change if a lock is held on gAdapterListLock
  50. ULONG gNumAdapters = 0L;
  51. // Name of the registry value that forces an adapter into compatibility mode
  52. NDIS_STRING gForceCompatValueName = NDIS_STRING_CONST("ForceCompatibilityMode");
  53. #if DBG
  54. // Boolean to force all adapters into compatibility mode
  55. BOOLEAN gAllAdaptersCompat = FALSE;
  56. const PWCHAR gForceAllCompatPropertyName = L"ForceAllToCompatibilityMode";
  57. #endif
  58. // ===========================================================================
  59. //
  60. // PRIVATE PROTOTYPES
  61. //
  62. // ===========================================================================
  63. VOID
  64. BrdgProtOpenAdapterComplete(
  65. IN NDIS_HANDLE ProtocolBindingContext,
  66. IN NDIS_STATUS Status,
  67. IN NDIS_STATUS OpenErrorStatus
  68. );
  69. VOID
  70. BrdgProtCloseAdapterComplete(
  71. IN NDIS_HANDLE ProtocolBindingContext,
  72. IN NDIS_STATUS Status
  73. );
  74. VOID
  75. BrdgProtStatus(
  76. IN NDIS_HANDLE ProtocolBindingContext,
  77. IN NDIS_STATUS GeneralStatus,
  78. IN PVOID StatusBuffer,
  79. IN UINT StatusBufferSize
  80. );
  81. VOID
  82. BrdgProtStatusComplete(
  83. IN NDIS_HANDLE ProtocolBindingContext
  84. );
  85. VOID
  86. BrdgProtReceiveComplete(
  87. IN NDIS_HANDLE ProtocolBindingContext
  88. );
  89. VOID
  90. BrdgProtBindAdapter(
  91. OUT PNDIS_STATUS Status,
  92. IN NDIS_HANDLE BindContext,
  93. IN PNDIS_STRING DeviceName,
  94. IN PVOID SystemSpecific1,
  95. IN PVOID SystemSpecific2
  96. );
  97. VOID
  98. BrdgProtUnbindAdapter(
  99. OUT PNDIS_STATUS pStatus,
  100. IN NDIS_HANDLE ProtocolBindingContext,
  101. IN NDIS_HANDLE UnbindContext
  102. );
  103. NDIS_STATUS
  104. BrdgProtPnPEvent(
  105. IN NDIS_HANDLE ProtocolBindingContext,
  106. IN PNET_PNP_EVENT NetPnPEvent
  107. );
  108. VOID
  109. BrdgProtUnload(VOID);
  110. UINT
  111. BrdgProtCoReceive(
  112. IN NDIS_HANDLE ProtocolBindingContext,
  113. IN NDIS_HANDLE ProtocolVcContext,
  114. IN PNDIS_PACKET Packet
  115. );
  116. // ===========================================================================
  117. //
  118. // INLINES / MACROS
  119. //
  120. // ===========================================================================
  121. //
  122. // Signals the queue-draining threads that there has been a change in the
  123. // adapter list
  124. //
  125. __forceinline
  126. VOID
  127. BrdgProtSignalAdapterListChange()
  128. {
  129. INT i;
  130. for( i = 0; i < KeNumberProcessors; i++ )
  131. {
  132. KeSetEvent( &gThreadsCheckAdapters[i], EVENT_INCREMENT, FALSE );
  133. }
  134. }
  135. //
  136. // Writes an entry to the event log that indicates an error on a specific
  137. // adapter.
  138. //
  139. // Can be used after we have successfully retrieved the adapter's friendly name.
  140. //
  141. __inline
  142. VOID
  143. BrdgProtLogAdapterErrorFriendly(
  144. IN NDIS_STATUS ErrorCode,
  145. IN PADAPT pAdapt,
  146. IN NDIS_STATUS ErrorStatus
  147. )
  148. {
  149. PWCHAR StringPtr = pAdapt->DeviceDesc.Buffer;
  150. NdisWriteEventLogEntry( gDriverObject, ErrorCode, 0, 1, &StringPtr, sizeof(NDIS_STATUS), &ErrorStatus );
  151. }
  152. //
  153. // Writes an entry to the event log that indicates an error on a specific
  154. // adapter.
  155. //
  156. // Reports the adapter's device name, so can be used before we have successfully retrieved
  157. // the adapter's friendly name.
  158. //
  159. __inline
  160. VOID
  161. BrdgProtLogAdapterError(
  162. IN NDIS_STATUS ErrorCode,
  163. IN PADAPT pAdapt,
  164. IN NDIS_STATUS ErrorStatus
  165. )
  166. {
  167. PWCHAR StringPtr = pAdapt->DeviceName.Buffer;
  168. NdisWriteEventLogEntry( gDriverObject, ErrorCode, 0, 1, &StringPtr, sizeof(NDIS_STATUS), &ErrorStatus );
  169. }
  170. // Removes all references to an adapter from our various tables
  171. __forceinline
  172. VOID
  173. BrdgProtScrubAdapter(
  174. IN PADAPT pAdapt
  175. )
  176. {
  177. BrdgTblScrubAdapter( pAdapt );
  178. BrdgCompScrubAdapter( pAdapt );
  179. }
  180. // Returns the number of adapters that are currently bridged.
  181. ULONG
  182. BrdgProtGetAdapterCount()
  183. {
  184. return gNumAdapters;
  185. }
  186. // ===========================================================================
  187. //
  188. // PUBLIC FUNCTIONS
  189. //
  190. // ===========================================================================
  191. NTSTATUS
  192. BrdgProtDriverInit()
  193. /*++
  194. Routine Description:
  195. Initialization routine for the protocol section.
  196. Must be called at PASSIVE level because we call NdisRegisterProtocol().
  197. Arguments:
  198. None
  199. Return Value:
  200. STATUS_SUCCESS to continue initialization or an error
  201. code to abort driver startup
  202. --*/
  203. {
  204. NDIS_PROTOCOL_CHARACTERISTICS ProtChars;
  205. NDIS_STATUS NdisStatus;
  206. NDIS_STRING Name;
  207. SAFEASSERT(CURRENT_IRQL == PASSIVE_LEVEL);
  208. // Initialize locks
  209. NdisInitializeReadWriteLock( &gAdapterListLock );
  210. NdisInitializeReadWriteLock( &gAdapterCharacteristicsLock );
  211. //
  212. // Register the protocol.
  213. //
  214. NdisZeroMemory(&ProtChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  215. ProtChars.MajorNdisVersion = 5;
  216. ProtChars.MinorNdisVersion = 0;
  217. //
  218. // Make sure the protocol-name matches the service-name under which this protocol is installed.
  219. // This is needed to ensure that NDIS can correctly determine the binding and call us to bind
  220. // to miniports below.
  221. //
  222. NdisInitUnicodeString(&Name, PROTOCOL_NAME);
  223. ProtChars.Name = Name;
  224. ProtChars.OpenAdapterCompleteHandler = BrdgProtOpenAdapterComplete;
  225. ProtChars.CloseAdapterCompleteHandler = BrdgProtCloseAdapterComplete;
  226. ProtChars.RequestCompleteHandler = BrdgProtRequestComplete;
  227. ProtChars.ReceiveCompleteHandler = BrdgProtReceiveComplete;
  228. ProtChars.StatusHandler = BrdgProtStatus;
  229. ProtChars.StatusCompleteHandler = BrdgProtStatusComplete;
  230. ProtChars.BindAdapterHandler = BrdgProtBindAdapter;
  231. ProtChars.UnbindAdapterHandler = BrdgProtUnbindAdapter;
  232. ProtChars.PnPEventHandler = BrdgProtPnPEvent;
  233. ProtChars.UnloadHandler = BrdgProtUnload;
  234. ProtChars.CoReceivePacketHandler = BrdgProtCoReceive;
  235. //
  236. // These entry points are provided by the forwarding engine
  237. //
  238. ProtChars.ReceiveHandler = BrdgFwdReceive;
  239. ProtChars.TransferDataCompleteHandler = BrdgFwdTransferComplete;
  240. ProtChars.ReceivePacketHandler = BrdgFwdReceivePacket;
  241. ProtChars.SendCompleteHandler = BrdgFwdSendComplete;
  242. // Register ourselves
  243. NdisRegisterProtocol(&NdisStatus,
  244. &gProtHandle,
  245. &ProtChars,
  246. sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  247. if (NdisStatus != NDIS_STATUS_SUCCESS)
  248. {
  249. // This is a fatal error. Log it.
  250. NdisWriteEventLogEntry( gDriverObject, EVENT_BRIDGE_PROTOCOL_REGISTER_FAILED, 0, 0, NULL,
  251. sizeof(NDIS_STATUS), &NdisStatus );
  252. DBGPRINT(PROT, ("Failed to register the protocol driver with NDIS: %08x\n", NdisStatus));
  253. return STATUS_UNSUCCESSFUL;
  254. }
  255. #if DBG
  256. {
  257. NTSTATUS Status;
  258. ULONG Value;
  259. // Check if we're supposed to force all adapters into compat mode
  260. Status = BrdgReadRegDWord( &gRegistryPath, gForceAllCompatPropertyName, &Value );
  261. if( (Status == STATUS_SUCCESS) && (Value != 0L) )
  262. {
  263. DBGPRINT(COMPAT, ("FORCING ALL ADAPTERS TO COMPATIBILITY MODE!\n"));
  264. gAllAdaptersCompat = TRUE;
  265. }
  266. }
  267. #endif
  268. return STATUS_SUCCESS;
  269. }
  270. VOID
  271. BrdgProtRequestComplete(
  272. IN NDIS_HANDLE ProtocolBindingContext,
  273. IN PNDIS_REQUEST NdisRequest,
  274. IN NDIS_STATUS Status
  275. )
  276. /*++
  277. Routine Description:
  278. Completion handler for the previously posted request.
  279. Arguments:
  280. ProtocolBindingContext Pointer to the adapter structure
  281. NdisRequest The posted request (this should actually
  282. be a pointer to an NDIS_REQUEST_BETTER
  283. structure)
  284. Status Completion status
  285. Return Value:
  286. None
  287. --*/
  288. {
  289. PNDIS_REQUEST_BETTER pRequest = (PNDIS_REQUEST_BETTER)NdisRequest;
  290. // Communicate final status to blocked caller
  291. pRequest->Status = Status;
  292. //
  293. // Call the completion function if there is one.
  294. // Having a completion function and blocking against the
  295. // event are mutually exclusive, not least because the
  296. // completion function may free the memory block
  297. // holding the event.
  298. //
  299. if( pRequest->pFunc != NULL )
  300. {
  301. (*pRequest->pFunc)(pRequest, pRequest->FuncArg);
  302. }
  303. else
  304. {
  305. NdisSetEvent( &pRequest->Event );
  306. }
  307. }
  308. NDIS_STATUS
  309. BrdgProtDoRequest(
  310. NDIS_HANDLE BindingHandle,
  311. BOOLEAN bSet,
  312. NDIS_OID Oid,
  313. PVOID pBuffer,
  314. UINT BufferSize
  315. )
  316. /*++
  317. Routine Description:
  318. Calls NdisRequest to retrieve or set information from an underlying NIC,
  319. and blocks until the call completes.
  320. Must be called at PASSIVE level because we wait on an event.
  321. Arguments:
  322. BindingHandle Handle to the NIC
  323. bSet TRUE == set info, FALSE == query info
  324. Oid Request code
  325. pBuffer Output buffer
  326. BufferSize Size of output buffer
  327. Return Value:
  328. Status of the request
  329. --*/
  330. {
  331. NDIS_STATUS Status;
  332. NDIS_REQUEST_BETTER Request;
  333. SAFEASSERT(CURRENT_IRQL == PASSIVE_LEVEL);
  334. Request.Request.RequestType = bSet ? NdisRequestSetInformation : NdisRequestQueryInformation;
  335. Request.Request.DATA.QUERY_INFORMATION.Oid = Oid ;
  336. Request.Request.DATA.QUERY_INFORMATION.InformationBuffer = pBuffer;
  337. Request.Request.DATA.QUERY_INFORMATION.InformationBufferLength = BufferSize;
  338. NdisInitializeEvent( &Request.Event );
  339. NdisResetEvent( &Request.Event );
  340. Request.pFunc = NULL;
  341. Request.FuncArg = NULL;
  342. NdisRequest( &Status, BindingHandle, &Request.Request);
  343. if ( Status == NDIS_STATUS_PENDING )
  344. {
  345. NdisWaitEvent( &Request.Event, 0 /*Wait forever*/ );
  346. Status = Request.Status;
  347. }
  348. return Status;
  349. }
  350. VOID
  351. BrdgProtCleanup()
  352. /*++
  353. Routine Description:
  354. Called during driver unload to do an orderly shutdown
  355. This function is guaranteed to be called exactly once
  356. Arguments:
  357. None
  358. Return Value:
  359. None
  360. --*/
  361. {
  362. NDIS_STATUS NdisStatus;
  363. // Deregister ourselves as a protocol. This will cause calls to BrdgProtUnbindAdapter
  364. // for all open adapters.
  365. if (gProtHandle != NULL)
  366. {
  367. NDIS_HANDLE TmpHandle = gProtHandle;
  368. gProtHandle = NULL;
  369. NdisDeregisterProtocol(&NdisStatus, TmpHandle);
  370. SAFEASSERT( NdisStatus == NDIS_STATUS_SUCCESS );
  371. }
  372. }
  373. // ===========================================================================
  374. //
  375. // PRIVATE FUNCTIONS
  376. //
  377. // ===========================================================================
  378. VOID
  379. BrdgProtUnload(VOID)
  380. {
  381. SAFEASSERT(CURRENT_IRQL == PASSIVE_LEVEL);
  382. BrdgShutdown();
  383. }
  384. NDIS_STATUS
  385. BrdgProtCompleteBindAdapter(
  386. IN PADAPT pAdapt
  387. )
  388. /*++
  389. Routine Description:
  390. Called by BrdgProtOpenAdapterComplete to complete the process of binding
  391. to an underlying NIC
  392. Must be called at < DISPATCH_LEVEL because we call BrdgMiniInstantiateMiniport().
  393. Arguments:
  394. pAdapt The adapter to finish setting up
  395. Return Value:
  396. Status of the operation. If the return code is != NDIS_STATUS_SUCCESS, the binding
  397. is aborted and this adapter is not used again. Any error must be logged since it
  398. causes us to fail to bind to an adapter.
  399. --*/
  400. {
  401. NDIS_STATUS Status;
  402. LOCK_STATE LockState;
  403. SAFEASSERT(CURRENT_IRQL < DISPATCH_LEVEL);
  404. //
  405. // Query the adapter's friendly name.
  406. //
  407. Status = NdisQueryAdapterInstanceName(&pAdapt->DeviceDesc, pAdapt->BindingHandle);
  408. if( Status != NDIS_STATUS_SUCCESS )
  409. {
  410. // We failed.
  411. BrdgProtLogAdapterError( EVENT_BRIDGE_ADAPTER_NAME_QUERY_FAILED, pAdapt, Status );
  412. DBGPRINT(PROT, ("Failed to get an adapter's friendly name: %08x\n", Status));
  413. return Status;
  414. }
  415. //
  416. // Get the adapter's media state (connected / disconnected)
  417. //
  418. Status = BrdgProtDoRequest( pAdapt->BindingHandle, FALSE/*Query*/, OID_GEN_MEDIA_CONNECT_STATUS,
  419. &pAdapt->MediaState, sizeof(pAdapt->MediaState) );
  420. if( Status != NDIS_STATUS_SUCCESS )
  421. {
  422. // Some old crummy drivers don't support this OID
  423. pAdapt->MediaState = NdisMediaStateConnected;
  424. }
  425. //
  426. // Get the adapter's link speed
  427. //
  428. Status = BrdgProtDoRequest( pAdapt->BindingHandle, FALSE/*Query*/, OID_GEN_LINK_SPEED,
  429. &pAdapt->LinkSpeed, sizeof(pAdapt->LinkSpeed) );
  430. if( Status != NDIS_STATUS_SUCCESS )
  431. {
  432. BrdgProtLogAdapterErrorFriendly( EVENT_BRIDGE_ADAPTER_LINK_SPEED_QUERY_FAILED, pAdapt, Status );
  433. DBGPRINT(PROT, ("Couldn't get an adapter's link speed: %08x\n", Status));
  434. return Status;
  435. }
  436. //
  437. // Get the adapter's MAC address
  438. //
  439. Status = BrdgProtDoRequest( pAdapt->BindingHandle, FALSE/*Query*/, OID_802_3_PERMANENT_ADDRESS,
  440. &pAdapt->MACAddr, sizeof(pAdapt->MACAddr) );
  441. if( Status != NDIS_STATUS_SUCCESS )
  442. {
  443. BrdgProtLogAdapterErrorFriendly( EVENT_BRIDGE_ADAPTER_MAC_ADDR_QUERY_FAILED, pAdapt, Status );
  444. DBGPRINT(PROT, ("Couldn't get an adapter's MAC address: %08x\n", Status));
  445. return Status;
  446. }
  447. //
  448. // Get the adapter's physical medium
  449. //
  450. Status = BrdgProtDoRequest( pAdapt->BindingHandle, FALSE/*Query*/, OID_GEN_PHYSICAL_MEDIUM,
  451. &pAdapt->PhysicalMedium, sizeof(pAdapt->PhysicalMedium) );
  452. if( Status != NDIS_STATUS_SUCCESS )
  453. {
  454. // Most drivers don't actually support OID_GEN_PHYSICAL_MEDIUM yet. Fall back on
  455. // NO_MEDIUM when the driver can't report anything.
  456. pAdapt->PhysicalMedium = BRIDGE_NO_MEDIUM;
  457. }
  458. //
  459. // Give the miniport section a look at this adapter so it can set its MAC address
  460. //
  461. BrdgMiniInitFromAdapter( pAdapt );
  462. //
  463. // If pAdapt->bCompatibilityMode is already TRUE, it means that we found a reg
  464. // key during the initial bind phase that forces this adapter to compatibility mode
  465. // or that we force all adapters into compatibility mode.
  466. //
  467. if( !pAdapt->bCompatibilityMode )
  468. {
  469. ULONG Filter = NDIS_PACKET_TYPE_PROMISCUOUS;
  470. // Attempt to put the adapter into promiscuous receive mode. If it fails this OID,
  471. // we put the adapter into compatibility mode
  472. if( BrdgProtDoRequest( pAdapt->BindingHandle, TRUE/*Set*/, OID_GEN_CURRENT_PACKET_FILTER,
  473. &Filter, sizeof(Filter) ) != NDIS_STATUS_SUCCESS )
  474. {
  475. // The adapter doesn't seem to be able to do promiscuous mode. Put it in
  476. // compatibility mode.
  477. DBGPRINT(PROT, ("Adapter %p failed to go promiscuous; putting it in COMPATIBILITY MODE\n", pAdapt));
  478. pAdapt->bCompatibilityMode = TRUE;
  479. }
  480. else
  481. {
  482. // Set the filter back to nothing for now
  483. Filter = 0L;
  484. BrdgProtDoRequest( pAdapt->BindingHandle, TRUE/*Set*/, OID_GEN_CURRENT_PACKET_FILTER, &Filter, sizeof(Filter) );
  485. }
  486. }
  487. // If the STA isn't active, make this adapter live now.
  488. if( gDisableSTA )
  489. {
  490. pAdapt->State = Forwarding;
  491. // Put the adapter into its initial state
  492. BrdgProtDoAdapterStateChange( pAdapt );
  493. }
  494. // Else we initialize the adapter's STA functions below
  495. //
  496. // Link the adapter into the queue
  497. //
  498. NdisAcquireReadWriteLock( &gAdapterListLock, TRUE /* Write access */, &LockState );
  499. pAdapt->Next = gAdapterList;
  500. gAdapterList = pAdapt;
  501. gNumAdapters++;
  502. // Must update this inside the write lock on the adapter list
  503. if( pAdapt->bCompatibilityMode )
  504. {
  505. gCompatAdaptersExist = TRUE;
  506. }
  507. NdisReleaseReadWriteLock( &gAdapterListLock, &LockState );
  508. if (g_fIsTcpIpLoaded == TRUE)
  509. {
  510. // Inform the 1394 miniport that tcpip has been loaded
  511. BrdgSetMiniportsToBridgeMode(pAdapt, TRUE);
  512. }
  513. if( ! gDisableSTA )
  514. {
  515. //
  516. // Let the STA section initialize this adapter. This has to be done after the adapter
  517. // has been linked into the global list.
  518. //
  519. BrdgSTAInitializeAdapter( pAdapt );
  520. }
  521. // Tell the draining threads to take notice of the new adapter
  522. BrdgProtSignalAdapterListChange();
  523. // Update the miniport's idea of our virtual media state and link speed
  524. BrdgMiniUpdateCharacteristics( TRUE /*Is a connectivity change*/ );
  525. // Tell user-mode code about the new adapter
  526. BrdgCtlNotifyAdapterChange( pAdapt, BrdgNotifyAddAdapter );
  527. // If we haven't yet called the miniport's InstantiateMiniport() function, do it now, since we have
  528. // at least one adapter in the list
  529. if( InterlockedCompareExchange(&gHaveInitedMiniport, 1L, 0L) == 0L )
  530. {
  531. // Miniport wasn't previously initialized
  532. BrdgMiniInstantiateMiniport();
  533. }
  534. // We're all done, so let people use the adapter
  535. pAdapt->bResetting = FALSE;
  536. DBGPRINT(PROT, ("BOUND SUCCESSFULLY to adapter %ws\n", pAdapt->DeviceDesc.Buffer));
  537. return NDIS_STATUS_SUCCESS;
  538. }
  539. VOID
  540. BrdgProtBindAdapter(
  541. OUT PNDIS_STATUS Status,
  542. IN NDIS_HANDLE BindContext,
  543. IN PNDIS_STRING DeviceName,
  544. IN PVOID SystemSpecific1,
  545. IN PVOID SystemSpecific2
  546. )
  547. /*++
  548. Routine Description:
  549. Called by NDIS to bind to a miniport below.
  550. Must be called at PASSIVE_LEVEL because we call NdisOpenAdapter().
  551. Arguments:
  552. Status - Return status of bind here.
  553. BindContext - Can be passed to NdisCompleteBindAdapter if this call is pended.
  554. DeviceName - Device name to bind to. This is passed to NdisOpenAdapter.
  555. SystemSpecific1 - Can be passed to NdisOpenProtocolConfiguration to read per-binding information
  556. SystemSpecific2 - Unused for NDIS 5.0.
  557. Return Value:
  558. NDIS_STATUS_PENDING if this call is pended. In this case call NdisCompleteBindAdapter to complete.
  559. Anything else completes this call synchronously
  560. --*/
  561. {
  562. PADAPT pAdapt = NULL;
  563. NDIS_STATUS Sts;
  564. UINT MediumIndex;
  565. LONG AdaptSize;
  566. NDIS_HANDLE ConfigHandle;
  567. SAFEASSERT(CURRENT_IRQL == PASSIVE_LEVEL);
  568. // Don't do any new binds if we're shutting down
  569. if( gShuttingDown )
  570. {
  571. DBGPRINT(PROT, ("REFUSING to bind to new adapter during shutdown!\n"));
  572. *Status = NDIS_STATUS_NOT_ACCEPTED;
  573. return;
  574. }
  575. // Make sure we're not being asked to bind to ourselves!
  576. if( BrdgMiniIsBridgeDeviceName(DeviceName) )
  577. {
  578. DBGPRINT(PROT, ("REFUSING to bind to SELF!\n"));
  579. *Status = NDIS_STATUS_NOT_ACCEPTED;
  580. return;
  581. }
  582. //
  583. // Allocate memory for the Adapter structure.
  584. //
  585. AdaptSize = sizeof(ADAPT) + DeviceName->MaximumLength;
  586. NdisAllocateMemoryWithTag(&pAdapt, AdaptSize, 'gdrB');
  587. if (pAdapt == NULL)
  588. {
  589. *Status = NDIS_STATUS_RESOURCES;
  590. return;
  591. }
  592. //
  593. // Initialize the adapter structure
  594. //
  595. NdisZeroMemory(pAdapt, AdaptSize);
  596. pAdapt->AdaptSize = AdaptSize;
  597. pAdapt->DeviceName.Buffer = (WCHAR *)((PUCHAR)pAdapt + sizeof(ADAPT));
  598. pAdapt->DeviceName.MaximumLength = DeviceName->MaximumLength;
  599. pAdapt->DeviceName.Length = DeviceName->Length;
  600. NdisMoveMemory(pAdapt->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length);
  601. NdisInitializeEvent( &pAdapt->Event );
  602. NdisResetEvent( &pAdapt->Event );
  603. NdisAllocateSpinLock( &pAdapt->QueueLock );
  604. BrdgInitializeSingleList( &pAdapt->Queue );
  605. pAdapt->bServiceInProgress = FALSE;
  606. pAdapt->bSTAInited = FALSE;
  607. // Start out with this TRUE so no one can use the adapter until we're done
  608. // initializing it
  609. pAdapt->bResetting = TRUE;
  610. // Zero out statistics
  611. pAdapt->SentFrames.LowPart = pAdapt->SentFrames.HighPart = 0L;
  612. pAdapt->SentBytes.LowPart = pAdapt->SentBytes.HighPart = 0L;
  613. pAdapt->SentLocalFrames.LowPart = pAdapt->SentLocalFrames.HighPart = 0L;
  614. pAdapt->SentLocalBytes.LowPart = pAdapt->SentLocalBytes.HighPart = 0L;
  615. pAdapt->ReceivedFrames.LowPart = pAdapt->ReceivedFrames.HighPart = 0L;
  616. pAdapt->ReceivedBytes.LowPart = pAdapt->ReceivedBytes.HighPart = 0L;
  617. // The adapter starts off disabled
  618. pAdapt->State = Disabled;
  619. // Initialize quota information
  620. BrdgBufInitializeQuota( &pAdapt->Quota );
  621. BrdgInitializeWaitRef( &pAdapt->Refcount, FALSE );
  622. BrdgInitializeWaitRef( &pAdapt->QueueRefcount, FALSE );
  623. KeInitializeEvent( &pAdapt->QueueEvent, SynchronizationEvent, FALSE );
  624. pAdapt->bCompatibilityMode = FALSE;
  625. #if DBG
  626. if( gAllAdaptersCompat )
  627. {
  628. pAdapt->bCompatibilityMode = TRUE;
  629. }
  630. else
  631. {
  632. #endif
  633. // Check if a registry entry forces this adapter to compatibility mode
  634. NdisOpenProtocolConfiguration( Status, &ConfigHandle, SystemSpecific1);
  635. if( *Status == NDIS_STATUS_SUCCESS )
  636. {
  637. PNDIS_CONFIGURATION_PARAMETER pncp;
  638. NdisReadConfiguration( Status, &pncp, ConfigHandle, &gForceCompatValueName, NdisParameterHexInteger );
  639. if( (*Status == NDIS_STATUS_SUCCESS) && (pncp->ParameterData.IntegerData != 0L ) )
  640. {
  641. DBGPRINT(PROT, ("Forcing adapter into COMPATIBILITY MODE as per registry entry\n"));
  642. pAdapt->bCompatibilityMode = TRUE;
  643. }
  644. NdisCloseConfiguration( ConfigHandle );
  645. }
  646. else
  647. {
  648. DBGPRINT(PROT, ("Failed to open protocol configuration for an adapter: %8x\n", *Status));
  649. }
  650. #if DBG
  651. }
  652. #endif
  653. //
  654. // Now open the adapter below
  655. //
  656. NdisOpenAdapter(Status,
  657. &Sts,
  658. &pAdapt->BindingHandle,
  659. &MediumIndex,
  660. gMediumArray,
  661. sizeof(gMediumArray)/sizeof(NDIS_MEDIUM),
  662. gProtHandle,
  663. pAdapt,
  664. DeviceName,
  665. 0,
  666. NULL);
  667. if ( *Status == NDIS_STATUS_PENDING )
  668. {
  669. // The bind will complete later in BrdgProtOpenAdapterComplete
  670. }
  671. else
  672. {
  673. // Complete the bind right away
  674. BrdgProtOpenAdapterComplete( (NDIS_HANDLE)pAdapt, *Status, *Status );
  675. }
  676. }
  677. VOID
  678. BrdgProtOpenAdapterComplete(
  679. IN NDIS_HANDLE ProtocolBindingContext,
  680. IN NDIS_STATUS Status,
  681. IN NDIS_STATUS OpenErrorStatus
  682. )
  683. /*++
  684. Routine Description:
  685. Completion routine for NdisOpenAdapter issued from within the BrdgProtBindAdapter. Simply
  686. unblock the caller.
  687. Must be called at PASSIVE_LEVEL because we wait on an event.
  688. Arguments:
  689. ProtocolBindingContext Pointer to the adapter
  690. Status Status of the NdisOpenAdapter call
  691. OpenErrorStatus Secondary status(ignored by us).
  692. Return Value:
  693. None
  694. --*/
  695. {
  696. PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
  697. SAFEASSERT(CURRENT_IRQL == PASSIVE_LEVEL);
  698. if( Status != NDIS_STATUS_SUCCESS )
  699. {
  700. // Log this error since it means we can't use the adapter.
  701. BrdgProtLogAdapterError( EVENT_BRIDGE_ADAPTER_BIND_FAILED, pAdapt, Status );
  702. DBGPRINT(PROT, ("BIND FAILURE: Failed to open adapter: %08x, %08x\n", Status, OpenErrorStatus));
  703. NdisFreeMemory( pAdapt, pAdapt->AdaptSize, 0 );
  704. }
  705. else
  706. {
  707. // BrdgProtCompleteBindAdapter must log any fatal errors
  708. Status = BrdgProtCompleteBindAdapter( pAdapt );
  709. if( Status != NDIS_STATUS_SUCCESS )
  710. {
  711. DBGPRINT(PROT, ("BIND FAILURE: Couldn't complete adapter initialization: %08x\n", Status));
  712. BrdgSetMiniportsToBridgeMode (pAdapt, FALSE); // Turn bridge mode off on pAdapt
  713. NdisCloseAdapter( &Status, pAdapt->BindingHandle );
  714. if ( Status == NDIS_STATUS_PENDING )
  715. {
  716. NdisWaitEvent( &pAdapt->Event, 0/*Wait forever*/ );
  717. }
  718. NdisFreeMemory( pAdapt, pAdapt->AdaptSize, 0 );
  719. }
  720. }
  721. }
  722. VOID
  723. BrdgProtUnbindAdapter(
  724. OUT PNDIS_STATUS pStatus,
  725. IN NDIS_HANDLE ProtocolBindingContext,
  726. IN NDIS_HANDLE UnbindContext
  727. )
  728. /*++
  729. Routine Description:
  730. Called by NDIS when we are required to unbind to the adapter below.
  731. Must be called at PASSIVE_LEVEL because we wait on an event
  732. Arguments:
  733. pStatus Placeholder for return status
  734. ProtocolBindingContext Pointer to the adapter structure
  735. UnbindContext Context for NdisUnbindComplete() if this pends
  736. Return Value:
  737. None
  738. --*/
  739. {
  740. PADAPT *pTmp, pAnAdapt, pAdapt =(PADAPT)ProtocolBindingContext;
  741. LOCK_STATE LockState;
  742. ULONG Filter;
  743. BOOLEAN bFound = FALSE, bCompatAdaptersExist;
  744. SAFEASSERT(CURRENT_IRQL == PASSIVE_LEVEL);
  745. DBGPRINT(PROT, ("UNBINDING Adapter %p :\n", pAdapt));
  746. DBGPRINT(PROT, ("%ws\n", pAdapt->DeviceDesc.Buffer));
  747. // Set the Underlying miniports to Off
  748. BrdgSetMiniportsToBridgeMode(pAdapt,FALSE);
  749. // Shut off all packet reception as the first order of business
  750. Filter = 0L;
  751. BrdgProtDoRequest( pAdapt->BindingHandle, TRUE/*Set*/, OID_GEN_CURRENT_PACKET_FILTER,
  752. &Filter, sizeof(Filter) );
  753. // Take this adapter out of the queue
  754. NdisAcquireReadWriteLock( &gAdapterListLock, TRUE /* Write access */, &LockState );
  755. for (pTmp = &gAdapterList; *pTmp != NULL; pTmp = &(*pTmp)->Next)
  756. {
  757. if (*pTmp == pAdapt)
  758. {
  759. *pTmp = pAdapt->Next;
  760. bFound = TRUE;
  761. break;
  762. }
  763. }
  764. gNumAdapters--;
  765. SAFEASSERT ( bFound );
  766. // Find out if there are any compat-mode adapters left
  767. bCompatAdaptersExist = FALSE;
  768. for( pAnAdapt = gAdapterList; pAnAdapt != NULL; pAnAdapt = pAnAdapt->Next)
  769. {
  770. if( pAnAdapt->bCompatibilityMode )
  771. {
  772. bCompatAdaptersExist = TRUE;
  773. }
  774. }
  775. // Must update this inside the write lock
  776. gCompatAdaptersExist = bCompatAdaptersExist;
  777. NdisReleaseReadWriteLock( &gAdapterListLock, &LockState );
  778. //
  779. // Now no code will attempt to target this adapter for floods.
  780. //
  781. // Scrub this adapter from our tables so no one will attempt to target it.
  782. BrdgProtScrubAdapter( pAdapt );
  783. // Stop packet forwarding on this adapter
  784. if( gDisableSTA )
  785. {
  786. pAdapt->State = Disabled;
  787. }
  788. else
  789. {
  790. // Have the STA shut down its operations on this adapter
  791. BrdgSTAShutdownAdapter( pAdapt );
  792. }
  793. //
  794. // Prevent new packets from being processed on this adapter
  795. //
  796. BrdgBlockWaitRef( &pAdapt->Refcount );
  797. //
  798. // Wait for this adapter's queue to be drained by the worker threads.
  799. //
  800. BrdgShutdownWaitRefOnce( &pAdapt->QueueRefcount );
  801. //
  802. // Signal the change in adapter list to the queue-draining threads.
  803. // This will remove this adapter from the threads' list of queues they block against.
  804. //
  805. BrdgProtSignalAdapterListChange();
  806. //
  807. // Must wait for adapter refcount to go to zero before closing down the adapter.
  808. // This doesn't mean all requests have completed, just that none of our code is
  809. // holding this adapter's pointer anymore.
  810. //
  811. // Our receive functions bump up the refcount while they're processing an
  812. // inbound packet, so when the refcount drops to zero we should also have completed
  813. // any in-progress handling of received packets.
  814. //
  815. // The queue-draining threads also increment the refcount for adapters they are
  816. // using, so this wait is our guarantee that all threads have stopped using this
  817. // adapter as well.
  818. //
  819. BrdgShutdownWaitRefOnce( &pAdapt->Refcount );
  820. SAFEASSERT( pAdapt->Refcount.Refcount == 0L );
  821. //
  822. // Close this binding. This will pend till all NDIS requests in progress are
  823. // completed.
  824. //
  825. NdisResetEvent( &pAdapt->Event );
  826. NdisCloseAdapter( pStatus, pAdapt->BindingHandle );
  827. if ( *pStatus == NDIS_STATUS_PENDING )
  828. {
  829. NdisWaitEvent( &pAdapt->Event, 0 /*Wait forever*/ );
  830. }
  831. // Tell user-mode code the adapter left (this call should not attempt to read from
  832. // pAdapt)
  833. BrdgCtlNotifyAdapterChange( pAdapt, BrdgNotifyRemoveAdapter );
  834. // Free adapter resources
  835. if (pAdapt->DeviceDesc.Buffer != NULL)
  836. {
  837. NdisFreeMemory(pAdapt->DeviceDesc.Buffer, pAdapt->DeviceDesc.MaximumLength, 0);
  838. }
  839. NdisFreeMemory(pAdapt, pAdapt->AdaptSize, 0);
  840. DBGPRINT(PROT, ("Unbind complete.\n"));
  841. // Have the miniport update in light of the missing adapter
  842. BrdgMiniUpdateCharacteristics( TRUE /*Is a connectivity change*/ );
  843. *pStatus = NDIS_STATUS_SUCCESS;
  844. }
  845. VOID
  846. BrdgProtDoAdapterStateChange(
  847. IN PADAPT pAdapt
  848. )
  849. /*++
  850. Routine Description:
  851. Adjusts an adapter's packet filter and multicast list based on its current state.
  852. If the adapter is Forwarding or Learning, the adapter is put in promiscuous mode so
  853. all packets are received.
  854. If the adapter is Blocking or Listening, the adapter is set to receive only the STA
  855. multicast packets.
  856. Errors are logged since this is a vital operation
  857. Arguments:
  858. pAdapt The adapter
  859. Return Value:
  860. Status code of the operation
  861. --*/
  862. {
  863. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  864. ULONG Filter;
  865. PORT_STATE State = pAdapt->State; // Freeze this value
  866. BOOLEAN bReceiveAllMode = (BOOLEAN)((State == Forwarding) || (State == Learning));
  867. if( ! bReceiveAllMode )
  868. {
  869. //
  870. // Even if we're not forwarding packets off this interface, we still need to listen
  871. // for Spanning Tree Algorithm traffic
  872. //
  873. Status = BrdgProtDoRequest( pAdapt->BindingHandle, TRUE/*Set*/, OID_802_3_MULTICAST_LIST,
  874. STA_MAC_ADDR, sizeof(STA_MAC_ADDR) );
  875. if( Status != NDIS_STATUS_SUCCESS )
  876. {
  877. BrdgProtLogAdapterErrorFriendly( EVENT_BRIDGE_ADAPTER_FILTER_FAILED, pAdapt, Status );
  878. DBGPRINT(PROT, ("Failed to set adapter %p's multicast list: %08x\n", pAdapt, Status));
  879. return;
  880. }
  881. }
  882. // Now set the packet filter appropriately
  883. if( pAdapt->bCompatibilityMode )
  884. {
  885. //
  886. // Compatibility adapters can't do promiscuous properly. Our compatibility
  887. // code relies only on them receiving traffic unicast to this machine, as
  888. // well as all broadcast and multicast traffic.
  889. //
  890. Filter = bReceiveAllMode ? NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_MULTICAST | NDIS_PACKET_TYPE_ALL_MULTICAST : NDIS_PACKET_TYPE_MULTICAST;
  891. }
  892. else
  893. {
  894. Filter = bReceiveAllMode ? NDIS_PACKET_TYPE_PROMISCUOUS : NDIS_PACKET_TYPE_MULTICAST;
  895. }
  896. Status = BrdgProtDoRequest( pAdapt->BindingHandle, TRUE/*Set*/, OID_GEN_CURRENT_PACKET_FILTER,
  897. &Filter, sizeof(Filter) );
  898. if( Status != NDIS_STATUS_SUCCESS )
  899. {
  900. BrdgProtLogAdapterErrorFriendly( EVENT_BRIDGE_ADAPTER_FILTER_FAILED, pAdapt, Status );
  901. DBGPRINT(PROT, ("Failed to set adapter %p's packet filter: %08x\n", pAdapt, Status));
  902. }
  903. // Tell the miniport about the change so it can change the bridge's characteristics if it wants.
  904. BrdgMiniUpdateCharacteristics( FALSE /*Not a physical connectivity change*/ );
  905. }
  906. VOID
  907. BrdgProtCloseAdapterComplete(
  908. IN NDIS_HANDLE ProtocolBindingContext,
  909. IN NDIS_STATUS Status
  910. )
  911. /*++
  912. Routine Description:
  913. Completion for the CloseAdapter call. Just unblocks waiting code
  914. Arguments:
  915. ProtocolBindingContext Pointer to the adapter structure
  916. Status Completion status
  917. Return Value:
  918. None.
  919. --*/
  920. {
  921. PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
  922. NdisSetEvent( &pAdapt->Event );
  923. }
  924. VOID
  925. BrdgProtReceiveComplete(
  926. IN NDIS_HANDLE ProtocolBindingContext
  927. )
  928. /*++
  929. Routine Description:
  930. Called by the adapter below us when it is done indicating a batch of received buffers.
  931. Arguments:
  932. ProtocolBindingContext Pointer to our adapter structure.
  933. Return Value:
  934. None
  935. --*/
  936. {
  937. //
  938. // Nothing to do here
  939. //
  940. }
  941. VOID
  942. BrdgProtStatus(
  943. IN NDIS_HANDLE ProtocolBindingContext,
  944. IN NDIS_STATUS GeneralStatus,
  945. IN PVOID StatusBuffer,
  946. IN UINT StatusBufferSize
  947. )
  948. /*++
  949. Routine Description:
  950. Handles status indications from underlying adapters
  951. Arguments:
  952. ProtocolBindingContext Pointer to the adapter structure
  953. GeneralStatus Status code
  954. StatusBuffer Status buffer
  955. StatusBufferSize Size of the status buffer
  956. Return Value:
  957. None
  958. --*/
  959. {
  960. PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
  961. switch( GeneralStatus )
  962. {
  963. case NDIS_STATUS_MEDIA_DISCONNECT:
  964. case NDIS_STATUS_MEDIA_CONNECT:
  965. {
  966. if( pAdapt != NULL )
  967. {
  968. LOCK_STATE LockState;
  969. ULONG MediaState = (GeneralStatus == NDIS_STATUS_MEDIA_CONNECT) ?
  970. NdisMediaStateConnected :
  971. NdisMediaStateDisconnected;
  972. if( GeneralStatus == NDIS_STATUS_MEDIA_DISCONNECT )
  973. {
  974. // Scrub the disconnected adapter from our tables. We will
  975. // have to relearn its hosts
  976. BrdgProtScrubAdapter( pAdapt );
  977. }
  978. if( ! gDisableSTA )
  979. {
  980. // The STA needs to know when adapters connect and disconnect
  981. if( MediaState == NdisMediaStateConnected )
  982. {
  983. BrdgSTAEnableAdapter( pAdapt );
  984. }
  985. else
  986. {
  987. BrdgSTADisableAdapter( pAdapt );
  988. }
  989. }
  990. // A global lock is used for adapter characteristics, since they must be read
  991. // all at once by the miniport
  992. NdisAcquireReadWriteLock( &gAdapterCharacteristicsLock, TRUE /*Write access*/, &LockState );
  993. pAdapt->MediaState = MediaState;
  994. NdisReleaseReadWriteLock( &gAdapterCharacteristicsLock, &LockState );
  995. // See if this makes any difference to our overall state
  996. BrdgMiniUpdateCharacteristics( TRUE /*Is a connectivity change*/ );
  997. // Tell user-mode code that the adapter media state changed
  998. BrdgCtlNotifyAdapterChange( pAdapt, BrdgNotifyMediaStateChange );
  999. }
  1000. else
  1001. {
  1002. DBGPRINT(PROT, ("BrdgProtStatus called for link status with NULL adapter!\n"));
  1003. }
  1004. }
  1005. break;
  1006. case NDIS_STATUS_LINK_SPEED_CHANGE:
  1007. {
  1008. if( (pAdapt != NULL) &&
  1009. (StatusBuffer != NULL) &&
  1010. (StatusBufferSize >= sizeof(ULONG)) )
  1011. {
  1012. LOCK_STATE LockState;
  1013. // A global lock is used for adapter characteristics, since they must be read
  1014. // all at once by the miniport
  1015. NdisAcquireReadWriteLock( &gAdapterCharacteristicsLock, TRUE /*Write access*/, &LockState );
  1016. pAdapt->LinkSpeed = *((ULONG*)StatusBuffer);
  1017. NdisReleaseReadWriteLock( &gAdapterCharacteristicsLock, &LockState );
  1018. if( ! gDisableSTA )
  1019. {
  1020. // Tell the STA about the change so it can tweak the cost of this link
  1021. BrdgSTAUpdateAdapterCost( pAdapt, *((ULONG*)StatusBuffer) );
  1022. }
  1023. // See if this makes any difference to our overall state
  1024. BrdgMiniUpdateCharacteristics( FALSE /*Not a connectivity change*/ );
  1025. // Tell user-mode code that the adapter speed changed
  1026. BrdgCtlNotifyAdapterChange( pAdapt, BrdgNotifyLinkSpeedChange );
  1027. }
  1028. else
  1029. {
  1030. DBGPRINT(PROT, ("BrdgProtStatus called for link speed with bad params!\n"));
  1031. }
  1032. }
  1033. break;
  1034. case NDIS_STATUS_RESET_START:
  1035. {
  1036. DBGPRINT(PROT, ("Adapter %p RESET START\n", pAdapt));
  1037. pAdapt->bResetting = TRUE;
  1038. }
  1039. break;
  1040. case NDIS_STATUS_RESET_END:
  1041. {
  1042. DBGPRINT(PROT, ("Adapter %p RESET END\n", pAdapt));
  1043. pAdapt->bResetting = FALSE;
  1044. }
  1045. break;
  1046. default:
  1047. {
  1048. DBGPRINT(PROT, ("Unhandled status indication: %08x\n", GeneralStatus));
  1049. }
  1050. break;
  1051. }
  1052. }
  1053. VOID
  1054. BrdgProtStatusComplete(
  1055. IN NDIS_HANDLE ProtocolBindingContext
  1056. )
  1057. /*++
  1058. Routine Description:
  1059. NDIS entry point called when a status indication completes.
  1060. We do nothing in response to this.
  1061. Arguments:
  1062. ProtocolBindingContext The adapter involved
  1063. Return Value:
  1064. None
  1065. --*/
  1066. {
  1067. //
  1068. // Nothing to do here
  1069. //
  1070. }
  1071. VOID
  1072. BrdgProtInstantiateMiniport(
  1073. IN PVOID unused
  1074. )
  1075. /*++
  1076. Routine Description:
  1077. Deferrable function to call BrdgMiniInstantiateMiniport(), which must run
  1078. at low IRQL
  1079. Must run at < DISPATCH_LEVEL
  1080. Arguments:
  1081. unused Unused
  1082. Return Value:
  1083. None
  1084. --*/
  1085. {
  1086. SAFEASSERT(CURRENT_IRQL < DISPATCH_LEVEL);
  1087. BrdgMiniInstantiateMiniport();
  1088. }
  1089. NDIS_STATUS
  1090. BrdgProtPnPEvent(
  1091. IN NDIS_HANDLE ProtocolBindingContext,
  1092. IN PNET_PNP_EVENT NetPnPEvent
  1093. )
  1094. /*++
  1095. Routine Description:
  1096. NDIS entry point called to indicate a PnP event to us
  1097. Arguments:
  1098. ProtocolBindingContext The adapter involved
  1099. NetPnPEvent The event
  1100. Return Value:
  1101. Our status code in response to the event (should be NDIS_STATUS_SUCCESS or
  1102. NDIS_STATUS_UNSUPPORTED)
  1103. --*/
  1104. {
  1105. PADAPT pAdapt = (PADAPT)ProtocolBindingContext;
  1106. switch( NetPnPEvent->NetEvent )
  1107. {
  1108. case NetEventBindsComplete:
  1109. case NetEventSetPower:
  1110. case NetEventQueryPower:
  1111. case NetEventCancelRemoveDevice:
  1112. case NetEventBindList:
  1113. case NetEventQueryRemoveDevice:
  1114. case NetEventPnPCapabilities:
  1115. {
  1116. return NDIS_STATUS_SUCCESS;
  1117. }
  1118. break;
  1119. case NetEventReconfigure:
  1120. {
  1121. if( pAdapt == NULL )
  1122. {
  1123. NDIS_HANDLE MiniportHandle;
  1124. //
  1125. // A NetEventReconfigure event with a NULL binding context is either a
  1126. // global indication of config changes or a signal from NDIS to restart
  1127. // our miniport (for example, if it got disabled and then re-enabled).
  1128. //
  1129. // We're only interested in the case of a signal to restart our miniport.
  1130. // We'll assume this can only happen after we have initialized it the
  1131. // first time around.
  1132. //
  1133. // This is wierd, I know.
  1134. //
  1135. MiniportHandle = BrdgMiniAcquireMiniport();
  1136. if( gHaveInitedMiniport && (MiniportHandle == NULL) )
  1137. {
  1138. // Our miniport isn't initialized. Fire it up again.
  1139. // We can't do this at the high IRQL we're currently at, so defer the function.
  1140. DBGPRINT(PROT, ("Restarting miniport in response to NULL NetEventReconfigure signal\n"));
  1141. BrdgDeferFunction( BrdgProtInstantiateMiniport, NULL );
  1142. }
  1143. if( MiniportHandle != NULL )
  1144. {
  1145. BrdgMiniReleaseMiniport();
  1146. }
  1147. }
  1148. return NDIS_STATUS_SUCCESS;
  1149. }
  1150. break;
  1151. }
  1152. DBGPRINT(PROT, ("Unsupported PnP Code: %i\n", NetPnPEvent->NetEvent));
  1153. return NDIS_STATUS_NOT_SUPPORTED;
  1154. }
  1155. UINT
  1156. BrdgProtCoReceive(
  1157. IN NDIS_HANDLE ProtocolBindingContext,
  1158. IN NDIS_HANDLE ProtocolVcContext,
  1159. IN PNDIS_PACKET Packet
  1160. )
  1161. /*++
  1162. Routine Description:
  1163. NDIS entry point called to indicate packets that are being sent
  1164. on the Co-Ndis path.
  1165. Arguments:
  1166. Return Value:
  1167. Return 0 as this is a do-nothing function
  1168. --*/
  1169. {
  1170. return 0;
  1171. }