Windows NT 4.0 source code leak
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.

1378 lines
39 KiB

4 years ago
  1. #include <ndis.h>
  2. #include <efilter.h>
  3. #include <tfilter.h>
  4. #include <ffilter.h>
  5. #include "debug.h"
  6. #include "loop.h"
  7. #if DBG
  8. extern LONG LoopDebugLevel = DBG_LEVEL_FATAL;
  9. extern LONG LoopDebugComponent = DBG_COMP_ALL;
  10. #endif
  11. NDIS_STATUS
  12. LoopAddAdapter(
  13. IN NDIS_HANDLE MacAdapterContext,
  14. IN NDIS_HANDLE ConfigurationHandle,
  15. IN PNDIS_STRING AdapterName
  16. );
  17. NDIS_STATUS
  18. LoopCloseAdapter(
  19. IN NDIS_HANDLE MacBindingHandle
  20. );
  21. NDIS_STATUS
  22. LoopOpenAdapter(
  23. OUT PNDIS_STATUS OpenErrorStatus,
  24. OUT NDIS_HANDLE *MacBindingHandle,
  25. OUT PUINT SelectedMediumIndex,
  26. IN PNDIS_MEDIUM MediumArray,
  27. IN UINT MediumArraySize,
  28. IN NDIS_HANDLE NdisBindingContext,
  29. IN NDIS_HANDLE MacAdapterContext,
  30. IN UINT OpenOptions,
  31. IN PSTRING AddressingOptions OPTIONAL
  32. );
  33. VOID
  34. LoopRemoveAdapter(
  35. IN NDIS_HANDLE MacAdapterContext
  36. );
  37. NDIS_STATUS
  38. LoopReset(
  39. IN NDIS_HANDLE MacBindingHandle
  40. );
  41. NDIS_STATUS
  42. LoopTransferData(
  43. IN NDIS_HANDLE MacBindingHandle,
  44. IN NDIS_HANDLE MacReceiveContext,
  45. IN UINT ByteOffset,
  46. IN UINT BytesToTransfer,
  47. OUT PNDIS_PACKET Packet,
  48. OUT PUINT BytesTransferred
  49. );
  50. VOID
  51. LoopUnload(
  52. IN NDIS_HANDLE MacMacContext
  53. );
  54. STATIC
  55. NDIS_STATUS
  56. LoopRegisterAdapter(
  57. IN NDIS_HANDLE LoopMacHandle,
  58. IN PNDIS_STRING AdapterName,
  59. IN NDIS_MEDIUM AdapterMedium,
  60. IN PVOID NetAddress,
  61. IN NDIS_HANDLE ConfigurationHandle
  62. );
  63. STATIC
  64. NDIS_STATUS
  65. LoopChangeFilter(
  66. IN UINT OldFilterClasses,
  67. IN UINT NewFilterClasses,
  68. IN NDIS_HANDLE MacBindingHandle,
  69. IN PNDIS_REQUEST NdisRequest,
  70. IN BOOLEAN Set
  71. );
  72. STATIC
  73. VOID
  74. LoopCloseAction(
  75. IN NDIS_HANDLE MacBindingHandle
  76. );
  77. STATIC
  78. NDIS_STATUS
  79. LoopEthChangeAddress(
  80. IN UINT OldFilterCount,
  81. IN CHAR OldAddresses[][ETH_LENGTH_OF_ADDRESS],
  82. IN UINT NewFilterCouunt,
  83. IN CHAR NewAddresses[][ETH_LENGTH_OF_ADDRESS],
  84. IN NDIS_HANDLE MacBindingHandle,
  85. IN PNDIS_REQUEST NdisRequest,
  86. IN BOOLEAN Set
  87. );
  88. STATIC
  89. NDIS_STATUS
  90. LoopTrChangeAddress(
  91. IN TR_FUNCTIONAL_ADDRESS OldFunctionalAddresses,
  92. IN TR_FUNCTIONAL_ADDRESS NewFunctionalAddresses,
  93. IN NDIS_HANDLE MacBindingHandle,
  94. IN PNDIS_REQUEST NdisRequest,
  95. IN BOOLEAN Set
  96. );
  97. STATIC
  98. NDIS_STATUS
  99. LoopFddiChangeAddress(
  100. IN UINT OldLongAddressCount,
  101. IN CHAR OldLongAddresses[][FDDI_LENGTH_OF_LONG_ADDRESS],
  102. IN UINT NewLongAddressCouunt,
  103. IN CHAR NewLongAddresses[][FDDI_LENGTH_OF_LONG_ADDRESS],
  104. IN UINT OldShortAddressCount,
  105. IN CHAR OldShortAddresses[][FDDI_LENGTH_OF_SHORT_ADDRESS],
  106. IN UINT NewShortAddressCouunt,
  107. IN CHAR NewShortAddresses[][FDDI_LENGTH_OF_SHORT_ADDRESS],
  108. IN NDIS_HANDLE MacBindingHandle,
  109. IN PNDIS_REQUEST NdisRequest,
  110. IN BOOLEAN Set
  111. );
  112. STATIC NDIS_HANDLE LoopWrapperHandle;
  113. STATIC NDIS_HANDLE LoopMacHandle;
  114. // !! need to verify filters !!
  115. #define PACKET_FILTER_802_3 0xF07F
  116. #define PACKET_FILTER_802_5 0xF07F
  117. #define PACKET_FILTER_DIX 0xF07F
  118. #define PACKET_FILTER_FDDI 0xF07F
  119. #define PACKET_FILTER_LTALK 0x8009
  120. #define PACKET_FILTER_ARCNET 0x8009
  121. static const NDIS_PHYSICAL_ADDRESS physicalConst = NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);
  122. NTSTATUS
  123. DriverEntry(
  124. IN PDRIVER_OBJECT DriverObject,
  125. IN PUNICODE_STRING RegistryPath
  126. )
  127. {
  128. NDIS_STATUS Status;
  129. NDIS_MAC_CHARACTERISTICS LoopChar;
  130. NDIS_STRING MacName = NDIS_STRING_CONST("LoopBack");
  131. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO, (" --> DriverEntry\n"));
  132. NdisInitializeWrapper(
  133. &LoopWrapperHandle,
  134. DriverObject,
  135. RegistryPath,
  136. NULL
  137. );
  138. LoopChar.MajorNdisVersion = LOOP_NDIS_MAJOR_VERSION;
  139. LoopChar.MinorNdisVersion = LOOP_NDIS_MINOR_VERSION;
  140. LoopChar.OpenAdapterHandler = LoopOpenAdapter;
  141. LoopChar.CloseAdapterHandler = LoopCloseAdapter;
  142. LoopChar.RequestHandler = LoopRequest;
  143. LoopChar.SendHandler = LoopSend;
  144. LoopChar.TransferDataHandler = LoopTransferData;
  145. LoopChar.ResetHandler = LoopReset;
  146. LoopChar.UnloadMacHandler = LoopUnload;
  147. LoopChar.QueryGlobalStatisticsHandler = LoopQueryGlobalStats;
  148. LoopChar.AddAdapterHandler = LoopAddAdapter;
  149. LoopChar.RemoveAdapterHandler = LoopRemoveAdapter;
  150. LoopChar.Name = MacName;
  151. NdisRegisterMac(
  152. &Status,
  153. &LoopMacHandle,
  154. LoopWrapperHandle,
  155. NULL,
  156. &LoopChar,
  157. sizeof(LoopChar)
  158. );
  159. if (Status == NDIS_STATUS_SUCCESS)
  160. return STATUS_SUCCESS;
  161. // Can only get here if something went wrong registering the MAC or
  162. // all of the adapters
  163. NdisTerminateWrapper(LoopWrapperHandle, DriverObject);
  164. return STATUS_UNSUCCESSFUL;
  165. }
  166. NDIS_STATUS
  167. LoopAddAdapter(
  168. IN NDIS_HANDLE MacAdapterContext,
  169. IN NDIS_HANDLE ConfigurationHandle,
  170. IN PNDIS_STRING AdapterName
  171. )
  172. {
  173. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  174. NDIS_HANDLE ConfigHandle;
  175. PNDIS_CONFIGURATION_PARAMETER Parameter;
  176. NDIS_STRING MediumKey = NDIS_STRING_CONST("Medium");
  177. PUCHAR NetAddressBuffer[6];
  178. PVOID NetAddress;
  179. UINT Length;
  180. NDIS_MEDIUM AdapterMedium;
  181. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO, (" --> LoopAddAdapter\n"));
  182. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO, ("Reading Config Info\n"));
  183. // configuration info present, let's get it
  184. NdisOpenConfiguration(
  185. &Status,
  186. &ConfigHandle,
  187. ConfigurationHandle
  188. );
  189. if (Status != NDIS_STATUS_SUCCESS) {
  190. // would like to log this, but adapter not registered yet
  191. DBGPRINT(DBG_COMP_REGISTRY, DBG_LEVEL_FATAL,
  192. ("Unable to open configuration database!\n"));
  193. return Status;
  194. }
  195. NdisReadConfiguration(
  196. &Status,
  197. &Parameter,
  198. ConfigHandle,
  199. &MediumKey,
  200. NdisParameterInteger
  201. );
  202. AdapterMedium = (NDIS_MEDIUM)Parameter->ParameterData.IntegerData;
  203. if ((Status != NDIS_STATUS_SUCCESS) ||
  204. !((AdapterMedium == NdisMedium802_3) ||
  205. (AdapterMedium == NdisMedium802_5) ||
  206. (AdapterMedium == NdisMediumFddi) ||
  207. (AdapterMedium == NdisMediumLocalTalk) ||
  208. (AdapterMedium == NdisMediumArcnet878_2))) {
  209. // would like to log this, but adapter not registered yet
  210. DBGPRINT(DBG_COMP_REGISTRY, DBG_LEVEL_FATAL,
  211. ("Unable to find 'Medium' keyword or invalid value!\n"));
  212. NdisCloseConfiguration(ConfigHandle);
  213. return Status;
  214. }
  215. NdisReadNetworkAddress(
  216. &Status,
  217. &NetAddress,
  218. &Length,
  219. ConfigHandle
  220. );
  221. if (Status == NDIS_STATUS_SUCCESS) {
  222. // verify the address is appropriate for the specific media and
  223. // ensure that the locally administered address bit is set
  224. switch (AdapterMedium) {
  225. case NdisMedium802_3:
  226. if ((Length != ETH_LENGTH_OF_ADDRESS) ||
  227. ETH_IS_MULTICAST(NetAddress) ||
  228. !(((PUCHAR)NetAddress)[0] & 0x02)) { // U/L bit
  229. Length = 0;
  230. }
  231. break;
  232. case NdisMedium802_5:
  233. if ((Length != TR_LENGTH_OF_ADDRESS) ||
  234. (((PUCHAR)NetAddress)[0] & 0x80) || // I/G bit
  235. !(((PUCHAR)NetAddress)[0] & 0x40)) { // U/L bit
  236. Length = 0;
  237. }
  238. break;
  239. case NdisMediumFddi:
  240. if ((Length != FDDI_LENGTH_OF_LONG_ADDRESS) ||
  241. (((PUCHAR)NetAddress)[0] & 0x01) || // I/G bit
  242. !(((PUCHAR)NetAddress)[0] & 0x02)) { // U/L bit
  243. Length = 0;
  244. }
  245. break;
  246. case NdisMediumLocalTalk:
  247. if ((Length != 1) || LOOP_LT_IS_BROADCAST(*(PUCHAR)NetAddress)) {
  248. Length = 0;
  249. }
  250. break;
  251. case NdisMediumArcnet878_2:
  252. if ((Length != 1) || LOOP_ARC_IS_BROADCAST(*(PUCHAR)NetAddress)) {
  253. Length = 0;
  254. }
  255. break;
  256. }
  257. if (Length == 0) {
  258. DBGPRINT(DBG_COMP_REGISTRY, DBG_LEVEL_FATAL,
  259. ("Invalid NetAddress in registry!\n"));
  260. NdisCloseConfiguration(ConfigHandle);
  261. return NDIS_STATUS_FAILURE;
  262. }
  263. // have to save away the address as the info may be gone
  264. // when we close the registry. we assume the length will
  265. // be 6 bytes max
  266. NdisMoveMemory(
  267. NetAddressBuffer,
  268. NetAddress,
  269. Length
  270. );
  271. NetAddress = (PVOID)NetAddressBuffer;
  272. }
  273. else
  274. NetAddress = NULL;
  275. NdisCloseConfiguration(ConfigHandle);
  276. Status = LoopRegisterAdapter(
  277. LoopMacHandle,
  278. AdapterName,
  279. AdapterMedium,
  280. NetAddress,
  281. ConfigurationHandle
  282. );
  283. return Status;
  284. }
  285. NDIS_STATUS
  286. LoopCloseAdapter(
  287. IN NDIS_HANDLE MacBindingHandle
  288. )
  289. {
  290. PLOOP_ADAPTER Adapter;
  291. PLOOP_OPEN Open;
  292. NDIS_STATUS StatusToReturn;
  293. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO, (" --> LoopCloseAdapter\n"));
  294. Adapter = PLOOP_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
  295. NdisAcquireSpinLock(&Adapter->Lock);
  296. Adapter->References++;
  297. Open = PLOOP_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
  298. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO,
  299. ("Closing Open %lx, reference count = %ld\n",Open,Open->References));
  300. if (!Open->BindingClosing) {
  301. Open->BindingClosing = TRUE;
  302. RemoveEntryList(&Open->OpenList);
  303. Adapter->OpenCount--;
  304. Adapter->References--;
  305. //
  306. // shouldn't be called unless there isn't anything running in the
  307. // binding. if there is we're hosed.
  308. //
  309. switch (Adapter->Medium) {
  310. case NdisMedium802_3:
  311. case NdisMediumDix:
  312. StatusToReturn = EthDeleteFilterOpenAdapter(
  313. Adapter->Filter.Eth,
  314. Open->NdisFilterHandle,
  315. NULL
  316. );
  317. // needs to handle pending delete, but should be ok
  318. // since our close action routine doesn't pend
  319. break;
  320. case NdisMedium802_5:
  321. StatusToReturn = TrDeleteFilterOpenAdapter(
  322. Adapter->Filter.Tr,
  323. Open->NdisFilterHandle,
  324. NULL
  325. );
  326. // needs to handle pending delete, but should be ok
  327. // since our close action routine doesn't pend
  328. break;
  329. case NdisMediumFddi:
  330. StatusToReturn = FddiDeleteFilterOpenAdapter(
  331. Adapter->Filter.Fddi,
  332. Open->NdisFilterHandle,
  333. NULL
  334. );
  335. // needs to handle pending delete, but should be ok
  336. // since our close action routine doesn't pend
  337. break;
  338. case NdisMediumLocalTalk:
  339. case NdisMediumArcnet878_2:
  340. break;
  341. default:
  342. ASSERT(FALSE);
  343. break;
  344. }
  345. NdisFreeMemory(
  346. Open,
  347. sizeof(LOOP_OPEN),
  348. 0
  349. );
  350. StatusToReturn = NDIS_STATUS_SUCCESS;
  351. }
  352. else
  353. StatusToReturn = NDIS_STATUS_CLOSING;
  354. Adapter->References--;
  355. NdisReleaseSpinLock(&Adapter->Lock);
  356. return StatusToReturn;
  357. }
  358. NDIS_STATUS
  359. LoopOpenAdapter(
  360. OUT PNDIS_STATUS OpenErrorStatus,
  361. OUT NDIS_HANDLE *MacBindingHandle,
  362. OUT PUINT SelectedMediumIndex,
  363. IN PNDIS_MEDIUM MediumArray,
  364. IN UINT MediumArraySize,
  365. IN NDIS_HANDLE NdisBindingContext,
  366. IN NDIS_HANDLE MacAdapterContext,
  367. IN UINT OpenOptions,
  368. IN PSTRING AddressingOptions OPTIONAL
  369. )
  370. {
  371. PLOOP_ADAPTER Adapter = PLOOP_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext);
  372. PLOOP_OPEN NewOpen;
  373. NDIS_STATUS StatusToReturn;
  374. UINT i;
  375. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO, (" --> LoopOpenAdapter\n"));
  376. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO,
  377. ("Opening binding for Adapter %lx\n",Adapter));
  378. for (i=0;i < MediumArraySize; i++) {
  379. if (MediumArray[i] == Adapter->Medium)
  380. break;
  381. }
  382. if (i == MediumArraySize)
  383. return NDIS_STATUS_UNSUPPORTED_MEDIA;
  384. *SelectedMediumIndex = i;
  385. NdisAcquireSpinLock(&Adapter->Lock);
  386. Adapter->References++;
  387. NdisAllocateMemory(
  388. (PVOID)&NewOpen,
  389. sizeof(LOOP_OPEN),
  390. 0,
  391. physicalConst
  392. );
  393. if (NewOpen != NULL) {
  394. //
  395. // Setup new Open Binding struct
  396. //
  397. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO, ("new Open = %lx\n",NewOpen));
  398. NdisZeroMemory(
  399. NewOpen,
  400. sizeof(LOOP_OPEN)
  401. );
  402. switch (Adapter->Medium) {
  403. case NdisMedium802_3:
  404. case NdisMediumDix:
  405. StatusToReturn = (NDIS_STATUS)EthNoteFilterOpenAdapter(
  406. Adapter->Filter.Eth,
  407. NewOpen,
  408. NdisBindingContext,
  409. &NewOpen->NdisFilterHandle
  410. );
  411. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO, ("new EthFilter Open = %lx\n",NewOpen->NdisFilterHandle));
  412. break;
  413. case NdisMedium802_5:
  414. StatusToReturn = (NDIS_STATUS)TrNoteFilterOpenAdapter(
  415. Adapter->Filter.Tr,
  416. NewOpen,
  417. NdisBindingContext,
  418. &NewOpen->NdisFilterHandle
  419. );
  420. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO, ("new TrFilter Open = %lx\n",NewOpen->NdisFilterHandle));
  421. break;
  422. case NdisMediumFddi:
  423. StatusToReturn = (NDIS_STATUS)FddiNoteFilterOpenAdapter(
  424. Adapter->Filter.Fddi,
  425. NewOpen,
  426. NdisBindingContext,
  427. &NewOpen->NdisFilterHandle
  428. );
  429. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO, ("new FddiFilter Open = %lx\n",NewOpen->NdisFilterHandle));
  430. break;
  431. default:
  432. StatusToReturn = (NDIS_STATUS)TRUE;
  433. break;
  434. }
  435. if (!StatusToReturn) {
  436. DBGPRINT(DBG_COMP_MEMORY, DBG_LEVEL_ERR,
  437. ("unable to create filter for binding %lx\n",NewOpen));
  438. NdisWriteErrorLogEntry(
  439. Adapter->NdisAdapterHandle,
  440. NDIS_ERROR_CODE_OUT_OF_RESOURCES,
  441. 0
  442. );
  443. NdisFreeMemory(
  444. NewOpen,
  445. sizeof(LOOP_OPEN),
  446. 0);
  447. Adapter->References--;
  448. NdisReleaseSpinLock(&Adapter->Lock);
  449. return NDIS_STATUS_FAILURE;
  450. }
  451. *MacBindingHandle = BINDING_HANDLE_FROM_PLOOP_OPEN(NewOpen);
  452. InitializeListHead(&NewOpen->OpenList);
  453. NewOpen->BindingClosing = FALSE;
  454. NewOpen->Flags = 0;
  455. NewOpen->NdisBindingContext = NdisBindingContext;
  456. NewOpen->OwningLoop = Adapter;
  457. NewOpen->References = 1;
  458. NewOpen->CurrentLookAhead = LOOP_MAX_LOOKAHEAD;
  459. NewOpen->CurrentPacketFilter = 0;
  460. //
  461. // Add the binding to the owning adapter
  462. //
  463. InsertTailList(&Adapter->OpenBindings,&NewOpen->OpenList);
  464. Adapter->OpenCount++;
  465. Adapter->References++;
  466. Adapter->MaxLookAhead = LOOP_MAX_LOOKAHEAD;
  467. StatusToReturn = NDIS_STATUS_SUCCESS;
  468. }
  469. else {
  470. DBGPRINT(DBG_COMP_MEMORY, DBG_LEVEL_ERR,
  471. ("unable to allocate binding struct for adapter %lx\n",Adapter));
  472. NdisWriteErrorLogEntry(
  473. Adapter->NdisAdapterHandle,
  474. NDIS_ERROR_CODE_OUT_OF_RESOURCES,
  475. 0
  476. );
  477. StatusToReturn = NDIS_STATUS_RESOURCES;
  478. }
  479. Adapter->References--;
  480. NdisReleaseSpinLock(&Adapter->Lock);
  481. return StatusToReturn;
  482. }
  483. VOID
  484. LoopRemoveAdapter(
  485. IN NDIS_HANDLE MacAdapterContext
  486. )
  487. //
  488. // All bindings should be closed before this gets called
  489. //
  490. {
  491. PLOOP_ADAPTER Adapter = PLOOP_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext);
  492. BOOLEAN TimerCancel;
  493. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO, (" --> LoopRemoveAdapter\n"));
  494. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO,
  495. ("Removing adapter %lx\n",Adapter));
  496. NdisCancelTimer(&Adapter->LoopTimer,&TimerCancel);
  497. switch (Adapter->Medium) {
  498. case NdisMedium802_3:
  499. case NdisMediumDix:
  500. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO,
  501. ("deleting EthFilter %lx\n",Adapter->Filter.Eth));
  502. EthDeleteFilter(Adapter->Filter.Eth);
  503. break;
  504. case NdisMedium802_5:
  505. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO,
  506. ("deleting TrFilter %lx\n",Adapter->Filter.Tr));
  507. TrDeleteFilter(Adapter->Filter.Tr);
  508. break;
  509. case NdisMediumFddi:
  510. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO,
  511. ("deleting FddiFilter %lx\n",Adapter->Filter.Fddi));
  512. FddiDeleteFilter(Adapter->Filter.Fddi);
  513. break;
  514. default:
  515. break;
  516. }
  517. NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
  518. NdisFreeSpinLock(&Adapter->Lock);
  519. NdisFreeMemory(
  520. Adapter->DeviceName.Buffer,
  521. Adapter->DeviceNameLength,
  522. 0
  523. );
  524. NdisFreeMemory(
  525. Adapter,
  526. sizeof(LOOP_ADAPTER),
  527. 0
  528. );
  529. }
  530. NDIS_STATUS
  531. LoopReset(
  532. IN NDIS_HANDLE MacBindingHandle
  533. )
  534. {
  535. PLOOP_ADAPTER Adapter = PLOOP_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
  536. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  537. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO, (" --> LoopReset\n"));
  538. NdisAcquireSpinLock(&Adapter->Lock);
  539. Adapter->References++;
  540. if (!Adapter->ResetInProgress) {
  541. PLOOP_OPEN Open = PLOOP_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
  542. if (!Open->BindingClosing) {
  543. Open->References++;
  544. //
  545. // notify all bindings of beginning of reset
  546. //
  547. {
  548. PLOOP_OPEN Open;
  549. PLIST_ENTRY CurrentLink;
  550. CurrentLink = Adapter->OpenBindings.Flink;
  551. while(CurrentLink != &Adapter->OpenBindings) {
  552. Open = CONTAINING_RECORD(
  553. CurrentLink,
  554. LOOP_OPEN,
  555. OpenList
  556. );
  557. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO,
  558. ("Signaling reset start to binding %lx\n",Open));
  559. if (Open->BindingClosing) {
  560. CurrentLink = CurrentLink->Flink;
  561. continue;
  562. }
  563. Open->References++;
  564. NdisReleaseSpinLock(&Adapter->Lock);
  565. NdisIndicateStatus(
  566. Open->NdisBindingContext,
  567. NDIS_STATUS_RESET_START,
  568. NULL,
  569. 0
  570. );
  571. NdisAcquireSpinLock(&Adapter->Lock);
  572. Open->References--;
  573. CurrentLink = CurrentLink->Flink;
  574. }
  575. }
  576. Adapter->ResetInProgress = TRUE;
  577. //
  578. // Loop through the loopback queue and abort any pending sends
  579. //
  580. {
  581. PNDIS_PACKET AbortPacket;
  582. PLOOP_PACKET_RESERVED Reserved;
  583. PLOOP_OPEN Open;
  584. while (Adapter->Loopback != NULL) {
  585. AbortPacket = Adapter->Loopback;
  586. Reserved = PLOOP_RESERVED_FROM_PACKET(AbortPacket);
  587. Adapter->Loopback = Reserved->Next;
  588. Open = PLOOP_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle);
  589. NdisReleaseSpinLock(&Adapter->Lock);
  590. NdisCompleteSend(
  591. Open->NdisBindingContext,
  592. AbortPacket,
  593. NDIS_STATUS_REQUEST_ABORTED
  594. );
  595. NdisAcquireSpinLock(&Adapter->Lock);
  596. Open->References--;
  597. }
  598. Adapter->CurrentLoopback = NULL;
  599. Adapter->LastLoopback = NULL;
  600. }
  601. //
  602. // notify all bindings of reset end
  603. //
  604. {
  605. PLOOP_OPEN Open;
  606. PLIST_ENTRY CurrentLink;
  607. CurrentLink = Adapter->OpenBindings.Flink;
  608. while(CurrentLink != &Adapter->OpenBindings) {
  609. Open = CONTAINING_RECORD(
  610. CurrentLink,
  611. LOOP_OPEN,
  612. OpenList
  613. );
  614. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
  615. ("Signaling reset end to binding %lx\n",Open));
  616. if (Open->BindingClosing) {
  617. CurrentLink = CurrentLink->Flink;
  618. continue;
  619. }
  620. Open->References++;
  621. NdisReleaseSpinLock(&Adapter->Lock);
  622. NdisIndicateStatus(
  623. Open->NdisBindingContext,
  624. NDIS_STATUS_RESET_END,
  625. NULL,
  626. 0
  627. );
  628. NdisAcquireSpinLock(&Adapter->Lock);
  629. Open->References--;
  630. CurrentLink = CurrentLink->Flink;
  631. }
  632. }
  633. Open->References--;
  634. Adapter->ResetInProgress = FALSE;
  635. }
  636. else
  637. Status = NDIS_STATUS_CLOSING;
  638. }
  639. else
  640. Status = NDIS_STATUS_RESET_IN_PROGRESS;
  641. Adapter->References--;
  642. NdisReleaseSpinLock(&Adapter->Lock);
  643. return Status;
  644. }
  645. NDIS_STATUS
  646. LoopTransferData(
  647. IN NDIS_HANDLE MacBindingHandle,
  648. IN NDIS_HANDLE MacReceiveContext,
  649. IN UINT ByteOffset,
  650. IN UINT BytesToTransfer,
  651. OUT PNDIS_PACKET Packet,
  652. OUT PUINT BytesTransferred
  653. )
  654. {
  655. PLOOP_ADAPTER Adapter = PLOOP_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
  656. NDIS_STATUS StatusToReturn;
  657. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO, (" --> LoopTransferData\n"));
  658. NdisAcquireSpinLock(&Adapter->Lock);
  659. Adapter->References++;
  660. if (!Adapter->ResetInProgress) {
  661. PLOOP_OPEN Open = PLOOP_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
  662. if (!Open->BindingClosing) {
  663. Open->References++;
  664. NdisReleaseSpinLock(&Adapter->Lock);
  665. if (MacReceiveContext == NULL) {
  666. NdisCopyFromPacketToPacket(
  667. Packet,
  668. 0,
  669. BytesToTransfer,
  670. Adapter->CurrentLoopback,
  671. ByteOffset+(PLOOP_RESERVED_FROM_PACKET(Adapter->CurrentLoopback)->HeaderLength),
  672. BytesTransferred
  673. );
  674. StatusToReturn = NDIS_STATUS_SUCCESS;
  675. }
  676. else {
  677. //
  678. // shouldn't get here as we never pass a non-NULL receive context
  679. //
  680. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_FATAL,
  681. ("transfer data failed! passed a receive context of %lx\n",MacReceiveContext));
  682. StatusToReturn = NDIS_STATUS_FAILURE;
  683. }
  684. NdisAcquireSpinLock(&Adapter->Lock);
  685. Open->References--;
  686. }
  687. else
  688. StatusToReturn = NDIS_STATUS_REQUEST_ABORTED;
  689. }
  690. else
  691. StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;
  692. Adapter->References--;
  693. NdisReleaseSpinLock(&Adapter->Lock);
  694. return StatusToReturn;
  695. }
  696. VOID
  697. LoopUnload(
  698. IN NDIS_HANDLE MacMacContext
  699. )
  700. {
  701. NDIS_STATUS Status;
  702. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO, (" --> LoopUnload\n"));
  703. NdisDeregisterMac(
  704. &Status,
  705. LoopMacHandle
  706. );
  707. NdisTerminateWrapper(
  708. LoopWrapperHandle,
  709. NULL
  710. );
  711. }
  712. STATIC
  713. NDIS_STATUS
  714. LoopRegisterAdapter(
  715. IN NDIS_HANDLE LoopMacHandle,
  716. IN PNDIS_STRING AdapterName,
  717. IN NDIS_MEDIUM AdapterMedium,
  718. IN PVOID NetAddress,
  719. IN NDIS_HANDLE ConfigurationHandle
  720. )
  721. {
  722. static const MEDIA_INFO MediaParams[] = {
  723. /* NdisMedium802_3 */ { 1500, 14, PACKET_FILTER_802_3, 100000},
  724. /* NdisMedium802_5 */ { 4082, 14, PACKET_FILTER_802_5, 40000},
  725. /* NdisMediumFddi */ { 4486, 13, PACKET_FILTER_FDDI, 1000000},
  726. /* NdisMediumWan */ { 0, 0, 0, 0},
  727. /* NdisMediumLocalTalk */ { 600, 3, PACKET_FILTER_LTALK, 2300},
  728. /* NdisMediumDix */ { 1500, 14, PACKET_FILTER_DIX, 100000},
  729. /* NdisMediumArcnetRaw */ { 1512, 3, PACKET_FILTER_ARCNET, 25000},
  730. /* NdisMediumArcnet878_2 */ {1512, 3, PACKET_FILTER_ARCNET, 25000} };
  731. //
  732. // Pointer to the adapter
  733. //
  734. PLOOP_ADAPTER Adapter;
  735. //
  736. // status of various NDIS calls
  737. //
  738. NDIS_STATUS Status;
  739. //
  740. // info for registering the adapter
  741. //
  742. NDIS_ADAPTER_INFORMATION AdapterInfo;
  743. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO, (" --> LoopRegisterAdapter\n"));
  744. //
  745. // allocate the adapter block
  746. //
  747. NdisAllocateMemory(
  748. (PVOID)&Adapter,
  749. sizeof(LOOP_ADAPTER),
  750. 0,
  751. physicalConst
  752. );
  753. if (Adapter != NULL) {
  754. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO, ("new Adapter = %lx\n",Adapter));
  755. NdisZeroMemory(
  756. Adapter,
  757. sizeof(LOOP_ADAPTER)
  758. );
  759. Adapter->NdisMacHandle = LoopMacHandle;
  760. //
  761. // allocate memory for the name of the device
  762. //
  763. NdisAllocateMemory(
  764. (PVOID)&Adapter->DeviceName.Buffer,
  765. AdapterName->Length+2,
  766. 0,
  767. physicalConst
  768. );
  769. if (Adapter->DeviceName.Buffer != NULL) {
  770. Adapter->DeviceNameLength = AdapterName->Length+2;
  771. Adapter->DeviceName.MaximumLength = AdapterName->Length+2;
  772. NdisZeroMemory(
  773. Adapter->DeviceName.Buffer,
  774. AdapterName->Length+2
  775. );
  776. #ifdef NDIS_NT
  777. RtlCopyUnicodeString(
  778. &Adapter->DeviceName,
  779. AdapterName
  780. );
  781. #else
  782. #error Need to copy a NDIS_STRING.
  783. #endif
  784. //
  785. // set up the AdapterInfo structure
  786. //
  787. NdisZeroMemory(
  788. &AdapterInfo,
  789. sizeof(NDIS_ADAPTER_INFORMATION)
  790. );
  791. AdapterInfo.DmaChannel = 0;
  792. AdapterInfo.Master = FALSE;
  793. AdapterInfo.Dma32BitAddresses = FALSE;
  794. AdapterInfo.AdapterType = NdisInterfaceInternal;
  795. AdapterInfo.PhysicalMapRegistersNeeded = 0;
  796. AdapterInfo.MaximumPhysicalMapping = 0;
  797. AdapterInfo.NumberOfPortDescriptors = 0;
  798. if ((Status = NdisRegisterAdapter(
  799. &Adapter->NdisAdapterHandle,
  800. Adapter->NdisMacHandle,
  801. Adapter,
  802. ConfigurationHandle,
  803. AdapterName,
  804. &AdapterInfo
  805. )) == NDIS_STATUS_SUCCESS) {
  806. InitializeListHead(&Adapter->OpenBindings);
  807. Adapter->OpenCount = 0;
  808. NdisAllocateSpinLock(&Adapter->Lock);
  809. Adapter->InTimerProc = FALSE;
  810. Adapter->TimerSet = FALSE;
  811. Adapter->References = 1;
  812. Adapter->Loopback = NULL;
  813. Adapter->LastLoopback = NULL;
  814. Adapter->CurrentLoopback = NULL;
  815. NdisZeroMemory(
  816. &Adapter->LoopBuffer,
  817. LOOP_MAX_LOOKAHEAD
  818. );
  819. Adapter->ResetInProgress = FALSE;
  820. Adapter->MaxLookAhead = 0;
  821. Adapter->Medium = AdapterMedium;
  822. Adapter->MediumLinkSpeed = MediaParams[(UINT)AdapterMedium].LinkSpeed;
  823. Adapter->MediumMinPacketLen = MediaParams[(UINT)AdapterMedium].MacHeaderLen;
  824. Adapter->MediumMaxPacketLen = MediaParams[(UINT)AdapterMedium].MacHeaderLen+
  825. MediaParams[(UINT)AdapterMedium].MaxFrameLen;
  826. Adapter->MediumMacHeaderLen = MediaParams[(UINT)AdapterMedium].MacHeaderLen;
  827. Adapter->MediumMaxFrameLen = MediaParams[(UINT)AdapterMedium].MaxFrameLen;
  828. Adapter->MediumPacketFilters = MediaParams[(UINT)AdapterMedium].PacketFilters;
  829. switch (AdapterMedium) {
  830. case NdisMedium802_3:
  831. case NdisMediumDix:
  832. NdisMoveMemory(
  833. (PVOID)&Adapter->PermanentAddress,
  834. LOOP_ETH_CARD_ADDRESS,
  835. ETH_LENGTH_OF_ADDRESS
  836. );
  837. if (NetAddress != NULL) {
  838. NdisMoveMemory(
  839. (PVOID)&Adapter->CurrentAddress,
  840. NetAddress,
  841. ETH_LENGTH_OF_ADDRESS
  842. );
  843. }
  844. else {
  845. NdisMoveMemory(
  846. (PVOID)&Adapter->CurrentAddress,
  847. LOOP_ETH_CARD_ADDRESS,
  848. ETH_LENGTH_OF_ADDRESS
  849. );
  850. }
  851. Status = (NDIS_STATUS)EthCreateFilter(
  852. LOOP_ETH_MAX_MULTICAST_ADDRESS,
  853. LoopEthChangeAddress,
  854. LoopChangeFilter,
  855. LoopCloseAction,
  856. Adapter->CurrentAddress,
  857. &Adapter->Lock,
  858. &Adapter->Filter.Eth
  859. );
  860. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
  861. ("new EthFilter = %lx\n",Adapter->Filter.Eth));
  862. break;
  863. case NdisMedium802_5:
  864. NdisMoveMemory(
  865. (PVOID)&Adapter->PermanentAddress,
  866. LOOP_TR_CARD_ADDRESS,
  867. TR_LENGTH_OF_ADDRESS
  868. );
  869. if (NetAddress != NULL) {
  870. NdisMoveMemory(
  871. (PVOID)&Adapter->CurrentAddress,
  872. NetAddress,
  873. TR_LENGTH_OF_ADDRESS
  874. );
  875. }
  876. else {
  877. NdisMoveMemory(
  878. (PVOID)&Adapter->CurrentAddress,
  879. LOOP_TR_CARD_ADDRESS,
  880. TR_LENGTH_OF_ADDRESS
  881. );
  882. }
  883. Status = (NDIS_STATUS)TrCreateFilter(
  884. LoopTrChangeAddress,
  885. LoopTrChangeAddress,
  886. LoopChangeFilter,
  887. LoopCloseAction,
  888. Adapter->CurrentAddress,
  889. &Adapter->Lock,
  890. &Adapter->Filter.Tr
  891. );
  892. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
  893. ("new TrFilter = %lx\n",Adapter->Filter.Tr));
  894. break;
  895. case NdisMediumFddi:
  896. // the short address will simply be the first 2
  897. // bytes of the long address
  898. NdisMoveMemory(
  899. (PVOID)&Adapter->PermanentAddress,
  900. LOOP_FDDI_CARD_ADDRESS,
  901. FDDI_LENGTH_OF_LONG_ADDRESS
  902. );
  903. if (NetAddress != NULL) {
  904. NdisMoveMemory(
  905. (PVOID)&Adapter->CurrentAddress,
  906. NetAddress,
  907. FDDI_LENGTH_OF_LONG_ADDRESS
  908. );
  909. }
  910. else {
  911. NdisMoveMemory(
  912. (PVOID)&Adapter->CurrentAddress,
  913. LOOP_FDDI_CARD_ADDRESS,
  914. FDDI_LENGTH_OF_LONG_ADDRESS
  915. );
  916. }
  917. Status = (NDIS_STATUS)FddiCreateFilter(
  918. LOOP_FDDI_MAX_MULTICAST_LONG,
  919. LOOP_FDDI_MAX_MULTICAST_SHORT,
  920. LoopFddiChangeAddress,
  921. LoopChangeFilter,
  922. LoopCloseAction,
  923. Adapter->CurrentAddress,
  924. Adapter->CurrentAddress,
  925. &Adapter->Lock,
  926. &Adapter->Filter.Fddi
  927. );
  928. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
  929. ("new FddiFilter = %lx\n",Adapter->Filter.Fddi));
  930. break;
  931. case NdisMediumLocalTalk:
  932. Adapter->PermanentAddress[0] = LOOP_LTALK_CARD_ADDRESS;
  933. if (NetAddress != NULL)
  934. Adapter->CurrentAddress[0] = ((PUCHAR)NetAddress)[0];
  935. else
  936. Adapter->CurrentAddress[0] = LOOP_LTALK_CARD_ADDRESS;
  937. // dumb line to satisfy the following status check
  938. Status = (NDIS_STATUS)TRUE;
  939. break;
  940. case NdisMediumArcnet878_2:
  941. Adapter->PermanentAddress[0] = LOOP_ARC_CARD_ADDRESS;
  942. if (NetAddress != NULL)
  943. Adapter->CurrentAddress[0] = ((PUCHAR)NetAddress)[0];
  944. else
  945. Adapter->CurrentAddress[0] = LOOP_ARC_CARD_ADDRESS;
  946. // dumb line to satisfy the following status check
  947. Status = (NDIS_STATUS)TRUE;
  948. break;
  949. default:
  950. // shouldn't get here...
  951. ASSERTMSG("LoopRegisterAdapter: received invalid medium\n",FALSE);
  952. break;
  953. }
  954. if (!Status) {
  955. DBGPRINT(DBG_COMP_MEMORY,DBG_LEVEL_FATAL,
  956. ("%wS: Unable to configure media specific information\n",AdapterName));
  957. NdisWriteErrorLogEntry(
  958. Adapter->NdisAdapterHandle,
  959. NDIS_ERROR_CODE_DRIVER_FAILURE,
  960. 0
  961. );
  962. NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
  963. NdisFreeSpinLock(&Adapter->Lock);
  964. NdisFreeMemory(
  965. Adapter->DeviceName.Buffer,
  966. Adapter->DeviceNameLength,
  967. 0
  968. );
  969. NdisFreeMemory(
  970. Adapter,
  971. sizeof(LOOP_ADAPTER),
  972. 0
  973. );
  974. return NDIS_STATUS_FAILURE;
  975. }
  976. NdisInitializeTimer(
  977. &(Adapter->LoopTimer),
  978. LoopTimerProc,
  979. (PVOID)Adapter
  980. );
  981. NdisZeroMemory(
  982. &Adapter->GeneralMandatory,
  983. GM_ARRAY_SIZE * sizeof(ULONG)
  984. );
  985. return NDIS_STATUS_SUCCESS;
  986. }
  987. else {
  988. //
  989. // NdisRegisterAdapter failed
  990. //
  991. DBGPRINT(DBG_COMP_MEMORY,DBG_LEVEL_FATAL,
  992. ("%wS: Unable to register adapter, Error = %x\n",AdapterName,Status));
  993. NdisFreeMemory(
  994. Adapter->DeviceName.Buffer,
  995. Adapter->DeviceNameLength,
  996. 0
  997. );
  998. NdisFreeMemory(
  999. Adapter,
  1000. sizeof(LOOP_ADAPTER),
  1001. 0
  1002. );
  1003. return Status;
  1004. }
  1005. }
  1006. else {
  1007. //
  1008. // failed to allocate device name
  1009. //
  1010. DBGPRINT(DBG_COMP_MEMORY,DBG_LEVEL_FATAL,
  1011. ("%wS: Unable to allocate the device name\n",AdapterName));
  1012. NdisFreeMemory(
  1013. Adapter,
  1014. sizeof(LOOP_ADAPTER),
  1015. 0
  1016. );
  1017. return NDIS_STATUS_RESOURCES;
  1018. }
  1019. }
  1020. else {
  1021. //
  1022. // failed to allocate Adapter object
  1023. //
  1024. DBGPRINT(DBG_COMP_MEMORY,DBG_LEVEL_FATAL,
  1025. ("%wS: Unable to allocate the adapter object\n",AdapterName));
  1026. return NDIS_STATUS_RESOURCES;
  1027. }
  1028. }
  1029. STATIC
  1030. NDIS_STATUS
  1031. LoopChangeFilter(
  1032. IN UINT OldFilterClasses,
  1033. IN UINT NewFilterClasses,
  1034. IN NDIS_HANDLE MacBindingHandle,
  1035. IN PNDIS_REQUEST NdisRequest,
  1036. IN BOOLEAN Set
  1037. )
  1038. {
  1039. PLOOP_ADAPTER Adapter = PLOOP_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
  1040. NDIS_STATUS StatusToReturn;
  1041. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO, (" --> LoopChangeFilter\n"));
  1042. if (!Adapter->ResetInProgress)
  1043. StatusToReturn = NDIS_STATUS_SUCCESS;
  1044. else
  1045. StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;
  1046. return StatusToReturn;
  1047. }
  1048. STATIC
  1049. VOID
  1050. LoopCloseAction(
  1051. IN NDIS_HANDLE MacBindingHandle
  1052. )
  1053. {
  1054. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO, (" --> LoopCloseAction\n"));
  1055. PLOOP_OPEN_FROM_BINDING_HANDLE(MacBindingHandle)->References--;
  1056. }
  1057. STATIC
  1058. NDIS_STATUS
  1059. LoopEthChangeAddress(
  1060. IN UINT OldFilterCount,
  1061. IN CHAR OldAddresses[][ETH_LENGTH_OF_ADDRESS],
  1062. IN UINT NewFilterCouunt,
  1063. IN CHAR NewAddresses[][ETH_LENGTH_OF_ADDRESS],
  1064. IN NDIS_HANDLE MacBindingHandle,
  1065. IN PNDIS_REQUEST NdisRequest,
  1066. IN BOOLEAN Set
  1067. )
  1068. {
  1069. PLOOP_ADAPTER Adapter = PLOOP_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
  1070. NDIS_STATUS StatusToReturn;
  1071. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO, (" --> LoopEthChangeAddress\n"));
  1072. if (!Adapter->ResetInProgress)
  1073. StatusToReturn = NDIS_STATUS_SUCCESS;
  1074. else
  1075. StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;
  1076. return StatusToReturn;
  1077. }
  1078. STATIC
  1079. NDIS_STATUS
  1080. LoopTrChangeAddress(
  1081. IN TR_FUNCTIONAL_ADDRESS OldFunctionalAddresses,
  1082. IN TR_FUNCTIONAL_ADDRESS NewFunctionalAddresses,
  1083. IN NDIS_HANDLE MacBindingHandle,
  1084. IN PNDIS_REQUEST NdisRequest,
  1085. IN BOOLEAN Set
  1086. )
  1087. {
  1088. PLOOP_ADAPTER Adapter = PLOOP_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
  1089. NDIS_STATUS StatusToReturn;
  1090. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO, (" --> LoopTrChangeAddress\n"));
  1091. if (!Adapter->ResetInProgress)
  1092. StatusToReturn = NDIS_STATUS_SUCCESS;
  1093. else
  1094. StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;
  1095. return StatusToReturn;
  1096. }
  1097. STATIC
  1098. NDIS_STATUS
  1099. LoopFddiChangeAddress(
  1100. IN UINT OldLongAddressCount,
  1101. IN CHAR OldLongAddresses[][FDDI_LENGTH_OF_LONG_ADDRESS],
  1102. IN UINT NewLongAddressCouunt,
  1103. IN CHAR NewLongAddresses[][FDDI_LENGTH_OF_LONG_ADDRESS],
  1104. IN UINT OldShortAddressCount,
  1105. IN CHAR OldShortAddresses[][FDDI_LENGTH_OF_SHORT_ADDRESS],
  1106. IN UINT NewShortAddressCouunt,
  1107. IN CHAR NewShortAddresses[][FDDI_LENGTH_OF_SHORT_ADDRESS],
  1108. IN NDIS_HANDLE MacBindingHandle,
  1109. IN PNDIS_REQUEST NdisRequest,
  1110. IN BOOLEAN Set
  1111. )
  1112. {
  1113. PLOOP_ADAPTER Adapter = PLOOP_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
  1114. NDIS_STATUS StatusToReturn;
  1115. DBGPRINT(DBG_COMP_MISC, DBG_LEVEL_INFO, (" --> LoopFddiChangeAddress\n"));
  1116. if (!Adapter->ResetInProgress)
  1117. StatusToReturn = NDIS_STATUS_SUCCESS;
  1118. else
  1119. StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;
  1120. return StatusToReturn;
  1121. }