Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4387 lines
127 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. requestm.c
  5. Abstract:
  6. NDIS miniport request routines.
  7. Author:
  8. Sean Selitrennikoff (SeanSe) 05-Oct-93
  9. Jameel Hyder (JameelH) Re-organization 01-Jun-95
  10. Environment:
  11. Kernel mode, FSD
  12. Revision History:
  13. --*/
  14. #include <precomp.h>
  15. #pragma hdrstop
  16. //
  17. // Define the module number for debug code.
  18. //
  19. #define MODULE_NUMBER MODULE_REQUESTM
  20. NDIS_STATUS
  21. ndisMRequest(
  22. IN NDIS_HANDLE NdisBindingHandle,
  23. IN PNDIS_REQUEST NdisRequest
  24. )
  25. /*++
  26. Routine Description:
  27. Arguments:
  28. Return Value:
  29. --*/
  30. {
  31. PNDIS_OPEN_BLOCK Open = (PNDIS_OPEN_BLOCK)NdisBindingHandle;
  32. PNDIS_MINIPORT_BLOCK Miniport = Open->MiniportHandle;
  33. PNDIS_REQUEST_RESERVED ReqRsvd = PNDIS_RESERVED_FROM_PNDIS_REQUEST(NdisRequest);
  34. KIRQL OldIrql;
  35. NDIS_STATUS Status;
  36. BOOLEAN rc;
  37. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  38. ("==>ndisMRequest\n"));
  39. do
  40. {
  41. NDIS_ACQUIRE_MINIPORT_SPIN_LOCK(Miniport, &OldIrql);
  42. SET_INTERNAL_REQUEST(NdisRequest, Open, 0);
  43. PNDIS_RESERVED_FROM_PNDIS_REQUEST(NdisRequest)->Context = NULL;
  44. //
  45. // Get protocol-options
  46. //
  47. if ((NdisRequest->RequestType == NdisRequestSetInformation) &&
  48. (NdisRequest->DATA.SET_INFORMATION.Oid == OID_GEN_PROTOCOL_OPTIONS) &&
  49. (NdisRequest->DATA.SET_INFORMATION.InformationBuffer != NULL))
  50. {
  51. PULONG ProtocolOptions;
  52. ProtocolOptions = (PULONG)(NdisRequest->DATA.SET_INFORMATION.InformationBuffer);
  53. if (*ProtocolOptions & NDIS_PROT_OPTION_NO_RSVD_ON_RCVPKT)
  54. {
  55. *ProtocolOptions &= ~NDIS_PROT_OPTION_NO_RSVD_ON_RCVPKT;
  56. Open->Flags |= fMINIPORT_OPEN_NO_PROT_RSVD;
  57. }
  58. if ((*ProtocolOptions & NDIS_PROT_OPTION_NO_LOOPBACK) &&
  59. (Miniport->MacOptions & NDIS_MAC_OPTION_NO_LOOPBACK))
  60. {
  61. *ProtocolOptions &= ~fMINIPORT_OPEN_NO_LOOPBACK;
  62. Open->Flags |= fMINIPORT_OPEN_NO_LOOPBACK;
  63. }
  64. }
  65. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  66. ("ndisMRequest: Queueing request 0x%x\n", NdisRequest));
  67. //
  68. // Place the new request on the pending queue.
  69. //
  70. if (!(rc = ndisMQueueRequest(Miniport, NdisRequest)))
  71. {
  72. Status = NDIS_STATUS_INVALID_DEVICE_REQUEST;
  73. break;
  74. }
  75. if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_DESERIALIZE))
  76. {
  77. ndisMDoRequests(Miniport);
  78. }
  79. else
  80. {
  81. BOOLEAN LocalLock;
  82. LOCK_MINIPORT(Miniport, LocalLock);
  83. NDISM_QUEUE_WORK_ITEM(Miniport, NdisWorkItemRequest, NULL);
  84. if (LocalLock)
  85. {
  86. NDISM_PROCESS_DEFERRED(Miniport);
  87. }
  88. UNLOCK_MINIPORT(Miniport, LocalLock);
  89. }
  90. Status = NDIS_STATUS_PENDING;
  91. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  92. ("<==ndisMRequest: NDIS_STATUS_PENDING\n"));
  93. } while (FALSE);
  94. NDIS_RELEASE_MINIPORT_SPIN_LOCK(Miniport, OldIrql);
  95. return Status;
  96. }
  97. NDIS_STATUS
  98. ndisMRequestX(
  99. IN NDIS_HANDLE NdisBindingHandle,
  100. IN PNDIS_REQUEST NdisRequest
  101. )
  102. /*++
  103. Routine Description:
  104. Arguments:
  105. Return Value:
  106. --*/
  107. {
  108. PNDIS_OPEN_BLOCK Open = (PNDIS_OPEN_BLOCK)NdisBindingHandle;
  109. PNDIS_MINIPORT_BLOCK Miniport;
  110. PNDIS_DEFERRED_REQUEST_WORKITEM DeferredRequestWorkItem = NULL;
  111. NDIS_STATUS Status;
  112. PVOID Caller, CallersCaller;
  113. //
  114. // We save the address of the caller in the pool header, for debugging.
  115. //
  116. RtlGetCallersAddress(&Caller, &CallersCaller);
  117. do
  118. {
  119. DeferredRequestWorkItem = ALLOC_FROM_POOL(sizeof(NDIS_DEFERRED_REQUEST_WORKITEM), NDIS_TAG_WORK_ITEM);
  120. if (DeferredRequestWorkItem == NULL)
  121. {
  122. Status = NDIS_STATUS_RESOURCES;
  123. break;
  124. }
  125. ZeroMemory(DeferredRequestWorkItem, sizeof(NDIS_DEFERRED_REQUEST_WORKITEM));
  126. if (ndisReferenceOpenByHandle(Open, TRUE))
  127. {
  128. Miniport = Open->MiniportHandle;
  129. }
  130. else
  131. {
  132. #if DBG
  133. DbgPrint("ndisMRequestX: Receiving requests %p after closing Open %p.\n", NdisRequest, Open);
  134. DbgBreakPoint();
  135. #endif
  136. FREE_POOL(DeferredRequestWorkItem);
  137. Status = NDIS_STATUS_CLOSING;
  138. break;
  139. }
  140. //
  141. // Queue this to a work-item
  142. //
  143. DeferredRequestWorkItem->Caller = Caller;
  144. DeferredRequestWorkItem->CallersCaller = CallersCaller;
  145. DeferredRequestWorkItem->Request = NdisRequest;
  146. DeferredRequestWorkItem->Open = Open;
  147. DeferredRequestWorkItem->Oid = NdisRequest->DATA.QUERY_INFORMATION.Oid;
  148. DeferredRequestWorkItem->InformationBuffer = NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer;
  149. SET_INTERNAL_REQUEST(NdisRequest, Open, 0);
  150. DeferredRequestWorkItem->WorkItem.Context = (PVOID)DeferredRequestWorkItem;
  151. DeferredRequestWorkItem->WorkItem.Routine = (NDIS_PROC)ndisMRundownRequests;
  152. INITIALIZE_WORK_ITEM((WORK_QUEUE_ITEM *)&DeferredRequestWorkItem->WorkItem.WrapperReserved[0],
  153. (PWORKER_THREAD_ROUTINE)ndisMRundownRequests,
  154. DeferredRequestWorkItem);
  155. QUEUE_WORK_ITEM((WORK_QUEUE_ITEM *)&DeferredRequestWorkItem->WorkItem.WrapperReserved[0], CriticalWorkQueue);
  156. Status = NDIS_STATUS_PENDING;
  157. } while (FALSE);
  158. return(Status);
  159. }
  160. VOID
  161. ndisMRundownRequests(
  162. IN PNDIS_WORK_ITEM pWorkItem
  163. )
  164. /*++
  165. Routine Description:
  166. Call ndisMDoRequests deferred
  167. Arguments:
  168. Return Value:
  169. --*/
  170. {
  171. PNDIS_DEFERRED_REQUEST_WORKITEM DeferredRequestWorkItem = (PNDIS_DEFERRED_REQUEST_WORKITEM)pWorkItem->Context;
  172. PNDIS_REQUEST Request;
  173. PNDIS_OPEN_BLOCK Open = DeferredRequestWorkItem->Open;
  174. PNDIS_MINIPORT_BLOCK Miniport;
  175. NDIS_STATUS Status;
  176. UINT OpenRef;
  177. KIRQL OldIrql;
  178. if(ndisReferenceOpenByHandle(Open, FALSE))
  179. {
  180. Miniport = Open->MiniportHandle;
  181. }
  182. else
  183. {
  184. //
  185. // where did the open go?
  186. //
  187. DbgPrint("Ndis: ndisMRundownRequests Open is gone. DeferredRequestWorkItem %p\n", DeferredRequestWorkItem );
  188. DbgBreakPoint();
  189. return;
  190. }
  191. Request = DeferredRequestWorkItem->Request;
  192. ASSERT(MINIPORT_TEST_FLAG(Miniport, fMINIPORT_DESERIALIZE));
  193. Status = ndisMRequest(Open, Request);
  194. if (Status != NDIS_STATUS_PENDING)
  195. {
  196. PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Flags |= REQST_COMPLETED;
  197. (Open->RequestCompleteHandler)(Open->ProtocolBindingContext,
  198. Request,
  199. Status);
  200. }
  201. NDIS_ACQUIRE_MINIPORT_SPIN_LOCK(Miniport, &OldIrql);
  202. //
  203. // we have an extra ref because we called both ndisReferenceOpenByHandle
  204. // and SET_INTERNAL_REQUEST in ndisRequestX
  205. //
  206. M_OPEN_DECREMENT_REF_INTERLOCKED(Open, OpenRef);
  207. ASSERT(OpenRef > 0);
  208. ndisMDereferenceOpen(Open);
  209. NDIS_RELEASE_MINIPORT_SPIN_LOCK(Miniport, OldIrql);
  210. FREE_POOL(DeferredRequestWorkItem);
  211. }
  212. LONG
  213. ndisMDoMiniportOp(
  214. IN PNDIS_MINIPORT_BLOCK Miniport,
  215. IN BOOLEAN Query,
  216. IN ULONG Oid,
  217. IN PVOID Buf,
  218. IN LONG BufSize,
  219. IN LONG ErrorCodesToReturn,
  220. IN BOOLEAN fMandatory
  221. )
  222. /*++
  223. Routine Description:
  224. Query the miniport with the information supplied. If this is not an optional operation
  225. then the miniport will be halted if a failure occurs and an error code returned.
  226. THIS IS THE ONLY PLACE CERTAIN QUERIES HAPPEN DOWN TO THE MINIPORT. THESE ARE THEN
  227. CACHED AND SUBSEQUENT QUERIES ARE TRAPPED AND RESPONDED FROM HERE.
  228. Arguments:
  229. Miniport - Pointer to the Miniport.
  230. Query - TRUE if this is a query. FALSE if this is a set operation.
  231. Oid - NDIS OID to send to the miniport.
  232. Buf - Buffer for the operation.
  233. BufSize - Size of the buffer.
  234. ErrorCodesToReturn - If a system call failed the request then return the given error code.
  235. If the miniport failed it then return error code plus 1.
  236. Return Value:
  237. None.
  238. --*/
  239. {
  240. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  241. LONG ErrorCode = 0;
  242. BOOLEAN Set = !Query;
  243. NDIS_REQUEST Request;
  244. PNDIS_COREQ_RESERVED CoReqRsvd;
  245. PNDIS_REQUEST_RESERVED ReqRsvd;
  246. ZeroMemory(&Request, sizeof(NDIS_REQUEST));
  247. CoReqRsvd = PNDIS_COREQ_RESERVED_FROM_REQUEST(&Request);
  248. ReqRsvd = PNDIS_RESERVED_FROM_PNDIS_REQUEST(&Request);
  249. if (Query)
  250. {
  251. Request.RequestType = NdisRequestQueryInformation;
  252. }
  253. else
  254. {
  255. Request.RequestType = NdisRequestSetInformation;
  256. }
  257. Request.DATA.QUERY_INFORMATION.Oid = Oid;
  258. Request.DATA.QUERY_INFORMATION.InformationBuffer = Buf;
  259. Request.DATA.QUERY_INFORMATION.InformationBufferLength = BufSize;
  260. if (fMandatory)
  261. {
  262. ReqRsvd->Flags = REQST_MANDATORY;
  263. }
  264. NdisStatus = ndisQuerySetMiniport(Miniport,
  265. NULL,
  266. Set,
  267. &Request,
  268. 0);
  269. if (NdisStatus != NDIS_STATUS_SUCCESS)
  270. {
  271. //
  272. // Return the error code back to the caller.
  273. //
  274. ErrorCode = (NdisStatus == -1) ? ErrorCodesToReturn : ErrorCodesToReturn + 1;
  275. }
  276. return(ErrorCode);
  277. }
  278. VOID
  279. FASTCALL
  280. ndisMDoRequests(
  281. IN PNDIS_MINIPORT_BLOCK Miniport
  282. )
  283. /*++
  284. Routine Description:
  285. Submits a request to the mini-port.
  286. Arguments:
  287. Miniport - Miniport to send to.
  288. Return Value:
  289. TRUE if we need to place the work item back on the queue to process later.
  290. FALSE if we are done with the work item.
  291. Comments:
  292. Called at DPC level with Miniport's SpinLock held.
  293. --*/
  294. {
  295. NDIS_STATUS Status;
  296. PNDIS_REQUEST NdisRequest;
  297. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  298. ("==>ndisMDoRequests\n"));
  299. ASSERT_MINIPORT_LOCKED(Miniport);
  300. //
  301. // Do we have a request in progress?
  302. //
  303. while (((NdisRequest = Miniport->PendingRequest) != NULL) &&
  304. !MINIPORT_TEST_FLAG(Miniport, fMINIPORT_PROCESSING_REQUEST))
  305. {
  306. UINT MulticastAddresses;
  307. ULONG PacketFilter;
  308. BOOLEAN DoMove;
  309. PVOID MoveSource;
  310. UINT MoveBytes;
  311. ULONG GenericULong;
  312. //
  313. // Set defaults.
  314. //
  315. DoMove = TRUE;
  316. Status = NDIS_STATUS_SUCCESS;
  317. //
  318. // Process first request
  319. //
  320. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  321. ("ndisMDoRequests: Processing Request 0x%x, Oid 0x%x\n", NdisRequest, NdisRequest->DATA.QUERY_INFORMATION.Oid));
  322. //
  323. // Clear the timeout flag.
  324. //
  325. MINIPORT_CLEAR_FLAG(Miniport, fMINIPORT_REQUEST_TIMEOUT);
  326. Miniport->CFHangXTicks = 0;
  327. //
  328. // Make it known that we are processing a request
  329. //
  330. MINIPORT_SET_FLAG(Miniport, fMINIPORT_PROCESSING_REQUEST);
  331. //
  332. // Submit to mini-port
  333. //
  334. switch (NdisRequest->RequestType)
  335. {
  336. case NdisRequestQueryInformation:
  337. Status = ndisMQueryInformation(Miniport, NdisRequest);
  338. break;
  339. case NdisRequestSetInformation:
  340. Status = ndisMSetInformation(Miniport, NdisRequest);
  341. break;
  342. case NdisRequestQueryStatistics:
  343. MoveSource = &GenericULong;
  344. MoveBytes = sizeof(GenericULong);
  345. //
  346. // We intercept some calls
  347. //
  348. switch (NdisRequest->DATA.QUERY_INFORMATION.Oid)
  349. {
  350. case OID_GEN_CURRENT_PACKET_FILTER:
  351. switch (Miniport->MediaType)
  352. {
  353. case NdisMedium802_3:
  354. PacketFilter = ETH_QUERY_FILTER_CLASSES(Miniport->EthDB);
  355. break;
  356. case NdisMedium802_5:
  357. PacketFilter = TR_QUERY_FILTER_CLASSES(Miniport->TrDB);
  358. break;
  359. case NdisMediumFddi:
  360. PacketFilter = FDDI_QUERY_FILTER_CLASSES(Miniport->FddiDB);
  361. break;
  362. #if ARCNET
  363. case NdisMediumArcnet878_2:
  364. PacketFilter = ARC_QUERY_FILTER_CLASSES(Miniport->ArcDB);
  365. PacketFilter |= ETH_QUERY_FILTER_CLASSES(Miniport->EthDB);
  366. break;
  367. #endif
  368. }
  369. GenericULong = (ULONG)(PacketFilter);
  370. break;
  371. case OID_GEN_MEDIA_IN_USE:
  372. case OID_GEN_MEDIA_SUPPORTED:
  373. MoveSource = &Miniport->MediaType;
  374. MoveBytes = sizeof(NDIS_MEDIUM);
  375. break;
  376. case OID_GEN_CURRENT_LOOKAHEAD:
  377. GenericULong = (ULONG)(Miniport->CurrentLookahead);
  378. break;
  379. case OID_GEN_MAXIMUM_LOOKAHEAD:
  380. GenericULong = (ULONG)(Miniport->MaximumLookahead);
  381. break;
  382. case OID_PNP_WAKE_UP_PATTERN_LIST:
  383. DoMove = FALSE;
  384. MINIPORT_QUERY_INFO(Miniport, NdisRequest, &Status);
  385. if (Status == NDIS_STATUS_NOT_SUPPORTED)
  386. {
  387. //
  388. // get it from ndis
  389. //
  390. Status = ndisMQueryWakeUpPatternList(Miniport, NdisRequest);
  391. }
  392. break;
  393. case OID_PNP_CAPABILITIES:
  394. DoMove = FALSE;
  395. MINIPORT_QUERY_INFO(Miniport, NdisRequest, &Status);
  396. if ((Status == NDIS_STATUS_SUCCESS) &&
  397. !(MINIPORT_TEST_FLAG(Miniport, fMINIPORT_INTERMEDIATE_DRIVER)))
  398. {
  399. ((PNDIS_PNP_CAPABILITIES)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer)->Flags = Miniport->PMCapabilities.Flags;
  400. }
  401. break;
  402. case OID_GEN_MAC_OPTIONS:
  403. DoMove = FALSE;
  404. MINIPORT_QUERY_INFO(Miniport, NdisRequest, &Status);
  405. if (Status == NDIS_STATUS_SUCCESS)
  406. {
  407. *((PULONG)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer) |= (Miniport->MacOptions & NDIS_MAC_OPTION_SUPPORTS_MAC_ADDRESS_OVERWRITE);
  408. }
  409. break;
  410. case OID_802_3_MULTICAST_LIST:
  411. case OID_802_3_MAXIMUM_LIST_SIZE:
  412. if (Miniport->MediaType != NdisMedium802_3)
  413. {
  414. Status = NDIS_STATUS_INVALID_OID;
  415. MoveBytes = 0;
  416. break;
  417. }
  418. switch (NdisRequest->DATA.QUERY_INFORMATION.Oid)
  419. {
  420. case OID_802_3_MULTICAST_LIST:
  421. EthQueryGlobalFilterAddresses(&Status,
  422. Miniport->EthDB,
  423. NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
  424. &MulticastAddresses,
  425. NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer);
  426. //
  427. // Did we fail?
  428. //
  429. if (NDIS_STATUS_SUCCESS != Status)
  430. {
  431. NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = ETH_LENGTH_OF_ADDRESS * ETH_NUMBER_OF_GLOBAL_FILTER_ADDRESSES(Miniport->EthDB);
  432. Status = NDIS_STATUS_INVALID_LENGTH;
  433. }
  434. else
  435. {
  436. NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = MulticastAddresses * ETH_LENGTH_OF_ADDRESS;
  437. }
  438. DoMove = FALSE;
  439. break;
  440. case OID_802_3_MAXIMUM_LIST_SIZE:
  441. GenericULong = Miniport->MaximumLongAddresses;
  442. break;
  443. }
  444. break;
  445. case OID_802_5_CURRENT_FUNCTIONAL:
  446. case OID_802_5_CURRENT_GROUP:
  447. if (Miniport->MediaType != NdisMedium802_5)
  448. {
  449. Status = NDIS_STATUS_INVALID_OID;
  450. MoveBytes = 0;
  451. break;
  452. }
  453. switch (NdisRequest->DATA.QUERY_INFORMATION.Oid)
  454. {
  455. case OID_802_5_CURRENT_FUNCTIONAL:
  456. GenericULong = BYTE_SWAP_ULONG(TR_QUERY_FILTER_ADDRESSES(Miniport->TrDB));
  457. break;
  458. case OID_802_5_CURRENT_GROUP:
  459. GenericULong = BYTE_SWAP_ULONG(TR_QUERY_FILTER_GROUP(Miniport->TrDB));
  460. break;
  461. }
  462. break;
  463. case OID_FDDI_LONG_MULTICAST_LIST:
  464. case OID_FDDI_LONG_MAX_LIST_SIZE:
  465. case OID_FDDI_SHORT_MULTICAST_LIST:
  466. case OID_FDDI_SHORT_MAX_LIST_SIZE:
  467. if (Miniport->MediaType != NdisMediumFddi)
  468. {
  469. Status = NDIS_STATUS_INVALID_OID;
  470. MoveBytes = 0;
  471. break;
  472. }
  473. switch (NdisRequest->DATA.QUERY_INFORMATION.Oid)
  474. {
  475. case OID_FDDI_LONG_MULTICAST_LIST:
  476. FddiQueryGlobalFilterLongAddresses(&Status,
  477. Miniport->FddiDB,
  478. NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
  479. &MulticastAddresses,
  480. NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer);
  481. //
  482. // Did we fail?
  483. //
  484. if (NDIS_STATUS_SUCCESS != Status)
  485. {
  486. NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded =
  487. FDDI_LENGTH_OF_LONG_ADDRESS * FDDI_NUMBER_OF_GLOBAL_FILTER_LONG_ADDRESSES(Miniport->FddiDB);
  488. Status = NDIS_STATUS_INVALID_LENGTH;
  489. }
  490. else
  491. {
  492. NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = FDDI_LENGTH_OF_LONG_ADDRESS * MulticastAddresses;
  493. }
  494. DoMove = FALSE;
  495. break;
  496. case OID_FDDI_LONG_MAX_LIST_SIZE:
  497. GenericULong = Miniport->MaximumLongAddresses;
  498. break;
  499. case OID_FDDI_SHORT_MULTICAST_LIST:
  500. FddiQueryGlobalFilterShortAddresses(&Status,
  501. Miniport->FddiDB,
  502. NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
  503. &MulticastAddresses,
  504. NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer);
  505. //
  506. // Did we fail ?
  507. //
  508. if (NDIS_STATUS_SUCCESS != Status)
  509. {
  510. NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded =
  511. FDDI_LENGTH_OF_LONG_ADDRESS * FDDI_NUMBER_OF_GLOBAL_FILTER_SHORT_ADDRESSES(Miniport->FddiDB);
  512. Status = NDIS_STATUS_INVALID_LENGTH;
  513. }
  514. else
  515. {
  516. NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = FDDI_LENGTH_OF_SHORT_ADDRESS * MulticastAddresses;
  517. }
  518. DoMove = FALSE;
  519. break;
  520. case OID_FDDI_SHORT_MAX_LIST_SIZE:
  521. GenericULong = Miniport->MaximumShortAddresses;
  522. break;
  523. }
  524. break;
  525. default:
  526. DoMove = FALSE;
  527. MINIPORT_QUERY_INFO(Miniport, NdisRequest, &Status);
  528. break;
  529. }
  530. if (DoMove)
  531. {
  532. //
  533. // This was an intercepted request. Finish it off
  534. //
  535. if (Status == NDIS_STATUS_SUCCESS)
  536. {
  537. if (MoveBytes >
  538. NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength)
  539. {
  540. //
  541. // Not enough room in InformationBuffer. Punt
  542. //
  543. NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = MoveBytes;
  544. Status = NDIS_STATUS_INVALID_LENGTH;
  545. }
  546. else
  547. {
  548. //
  549. // Copy result into InformationBuffer
  550. //
  551. NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = MoveBytes;
  552. if ((MoveBytes > 0) &&
  553. (MoveSource != NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer))
  554. {
  555. MoveMemory(NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
  556. MoveSource,
  557. MoveBytes);
  558. }
  559. }
  560. }
  561. else
  562. {
  563. NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = MoveBytes;
  564. }
  565. }
  566. break;
  567. }
  568. //
  569. // Did the request pend? If so then there is nothing more to do.
  570. //
  571. if ((Status == NDIS_STATUS_PENDING) &&
  572. MINIPORT_TEST_FLAG(Miniport, fMINIPORT_PROCESSING_REQUEST))
  573. {
  574. //
  575. // Still outstanding
  576. //
  577. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  578. ("Request pending, exit do requests\n"));
  579. break;
  580. }
  581. //
  582. // Complete request
  583. //
  584. if (Status != NDIS_STATUS_PENDING)
  585. {
  586. switch (NdisRequest->RequestType)
  587. {
  588. case NdisRequestQueryStatistics:
  589. case NdisRequestQueryInformation:
  590. ndisMSyncQueryInformationComplete(Miniport, Status);
  591. break;
  592. case NdisRequestSetInformation:
  593. ndisMSyncSetInformationComplete(Miniport, Status);
  594. break;
  595. }
  596. }
  597. }
  598. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  599. ("<==ndisMDoRequests\n"));
  600. }
  601. NDIS_STATUS
  602. ndisMSetInformation(
  603. IN PNDIS_MINIPORT_BLOCK Miniport,
  604. IN PNDIS_REQUEST Request
  605. )
  606. /*++
  607. Routine Description:
  608. Arguments:
  609. Return Value:
  610. Note: Called at DPC with Miniport's lock held.
  611. --*/
  612. {
  613. NDIS_STATUS Status;
  614. POID_SETINFO_HANDLER pOidSH;
  615. BOOLEAN Intercept = FALSE;
  616. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  617. ("==>ndisMSetInformaiton\n"));
  618. if (PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open != NULL)
  619. {
  620. //
  621. // Process the binding's request.
  622. //
  623. for (pOidSH = ndisMSetInfoHandlers; pOidSH->Oid != 0; pOidSH++)
  624. {
  625. if (pOidSH->Oid == Request->DATA.SET_INFORMATION.Oid)
  626. {
  627. Intercept = TRUE;
  628. Status = (*pOidSH->SetInfoHandler)(Miniport, Request);
  629. break;
  630. }
  631. }
  632. }
  633. if (!Intercept)
  634. {
  635. //
  636. // Either we are not intercepting this request or it is an internal request
  637. //
  638. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  639. ("ndisMSetInformaiton: Request not intercepted by NDIS\n"));
  640. MINIPORT_SET_INFO(Miniport,
  641. Request,
  642. &Status);
  643. }
  644. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  645. ("<==ndisMSetInformaiton: 0x%x\n", Status));
  646. return(Status);
  647. }
  648. VOID
  649. NdisMSetInformationComplete(
  650. IN NDIS_HANDLE MiniportAdapterHandle,
  651. IN NDIS_STATUS Status
  652. )
  653. /*++
  654. Routine Description:
  655. This function indicates the completion of a set information operation.
  656. Arguments:
  657. MiniportAdapterHandle - points to the adapter block.
  658. Status - Status of the operation
  659. Return Value:
  660. None.
  661. --*/
  662. {
  663. PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK)MiniportAdapterHandle;
  664. KIRQL OldIrql;
  665. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  666. ("==>NdisMSetInformationComplete\n"));
  667. ASSERT_MINIPORT_LOCKED(Miniport);
  668. //
  669. // If we don't have a request to complete assume it was
  670. // aborted via the reset handler.
  671. //
  672. if (!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_PROCESSING_REQUEST))
  673. {
  674. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  675. ("NdisMSetInformationComplete: No request to process\n"));
  676. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  677. ("<==NdisMSetInformationComplete\n"));
  678. return;
  679. }
  680. NDIS_ACQUIRE_MINIPORT_SPIN_LOCK(Miniport, &OldIrql);
  681. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  682. ("Enter set information complete\n"));
  683. //
  684. // Process the actual set information complete.
  685. //
  686. ndisMSyncSetInformationComplete(Miniport, Status);
  687. //
  688. // Are there more requests pending?
  689. //
  690. if (Miniport->PendingRequest != NULL)
  691. {
  692. NDISM_QUEUE_WORK_ITEM(Miniport, NdisWorkItemRequest, NULL);
  693. }
  694. NDIS_RELEASE_MINIPORT_SPIN_LOCK(Miniport, OldIrql);
  695. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  696. ("<==NdisMSetInformationComplete\n"));
  697. }
  698. VOID
  699. FASTCALL
  700. ndisMSyncSetInformationComplete(
  701. IN PNDIS_MINIPORT_BLOCK Miniport,
  702. IN NDIS_STATUS Status
  703. )
  704. /*++
  705. Routine Description:
  706. This routine will process a set information complete. This is only
  707. called from the wrapper. The difference is that this routine will not
  708. call ndisMProcessDeferred() after processing the completion of the set.
  709. Arguments:
  710. Miniport
  711. Status
  712. Return Value:
  713. None
  714. Comments:
  715. Called at DPC with Miniport's SpinLock held.
  716. --*/
  717. {
  718. PNDIS_REQUEST Request;
  719. PNDIS_REQUEST_RESERVED ReqRsvd;
  720. PNDIS_OPEN_BLOCK Open;
  721. KIRQL OldIrql;
  722. BOOLEAN FreeRequest;
  723. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  724. ("==>ndisMSyncSetInformationComplete\n"));
  725. //
  726. // Clear the timeout flag and the request_in_process flag.
  727. //
  728. MINIPORT_CLEAR_FLAG(Miniport, (fMINIPORT_REQUEST_TIMEOUT | fMINIPORT_PROCESSING_REQUEST));
  729. Miniport->CFHangXTicks = 0;
  730. //
  731. // Get a pointer to the request that we are completeing.
  732. // And clear out the request in-progress pointer.
  733. //
  734. Request = Miniport->PendingRequest;
  735. ASSERT(Request != NULL);
  736. ReqRsvd = PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request);
  737. Miniport->PendingRequest = ReqRsvd->Next;
  738. //
  739. // save the request for debugging purpose
  740. //
  741. Miniport->LastRequest = Request;
  742. FreeRequest = ((ReqRsvd->Flags & REQST_FREE_REQUEST) == REQST_FREE_REQUEST);
  743. ReqRsvd->Flags |= REQST_COMPLETED;
  744. Open = ReqRsvd->Open;
  745. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  746. ("ndisMSyncSetInformationComplete: Request 0x%x, Oid 0x%x\n",
  747. Request, Request->DATA.SET_INFORMATION.Oid));
  748. RESTORE_REQUEST_BUF(Miniport, Request);
  749. //
  750. // Free the multicast buffer, if any
  751. //
  752. switch (Request->DATA.SET_INFORMATION.Oid)
  753. {
  754. case OID_802_3_MULTICAST_LIST:
  755. case OID_FDDI_LONG_MULTICAST_LIST:
  756. case OID_FDDI_SHORT_MULTICAST_LIST:
  757. if (Miniport->SetMCastBuffer != NULL)
  758. {
  759. FREE_POOL(Miniport->SetMCastBuffer);
  760. Miniport->SetMCastBuffer = NULL;
  761. }
  762. break;
  763. case OID_802_3_CURRENT_ADDRESS:
  764. case OID_802_5_CURRENT_ADDRESS:
  765. case OID_FDDI_LONG_CURRENT_ADDR:
  766. case OID_FDDI_SHORT_CURRENT_ADDR:
  767. if (Status == NDIS_STATUS_SUCCESS)
  768. {
  769. //
  770. // The current layer-2 address has changed. Make the filters understand that
  771. //
  772. }
  773. break;
  774. }
  775. //
  776. // Get a pointer to the open that made the request.
  777. // for internal requests this will be NULL.
  778. //
  779. // Do we need to indicate this request to the protocol?
  780. // We do if it's not an internal request.
  781. //
  782. if (Open != NULL)
  783. {
  784. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  785. ("Open 0x%x\n", Open));
  786. //
  787. // Do any necessary post processing for the request.
  788. //
  789. ndisMRequestSetInformationPost(Miniport, Request, Status);
  790. if (ReqRsvd->Flags & REQST_LAST_RESTORE)
  791. {
  792. MINIPORT_CLEAR_FLAG(Miniport, fMINIPORT_RESTORING_FILTERS);
  793. }
  794. //
  795. // Don't complete internal requests
  796. //
  797. if (!FreeRequest)
  798. {
  799. //
  800. // Indicate to Protocol;
  801. //
  802. NDIS_RELEASE_MINIPORT_SPIN_LOCK_DPC(Miniport);
  803. (Open->RequestCompleteHandler)(Open->ProtocolBindingContext,
  804. Request,
  805. Status);
  806. NDIS_ACQUIRE_MINIPORT_SPIN_LOCK_DPC(Miniport);
  807. }
  808. //
  809. // Dereference the open.
  810. //
  811. DBGPRINT(DBG_COMP_OPENREF, DBG_LEVEL_INFO,
  812. ("- Open 0x%x Reference 0x%x\n", Open, Open->References));
  813. ndisMDereferenceOpen(Open);
  814. if (FreeRequest)
  815. {
  816. //
  817. // Free the request.
  818. //
  819. ndisMFreeInternalRequest(Request);
  820. }
  821. }
  822. else
  823. {
  824. PNDIS_COREQ_RESERVED CoReqRsvd;
  825. //
  826. // The CoReqRsvd portion of the request contains ndis only information about the request.
  827. //
  828. CoReqRsvd = PNDIS_COREQ_RESERVED_FROM_REQUEST(Request);
  829. CoReqRsvd->Status = Status;
  830. //
  831. // Internal requests are only used for restoring filter settings
  832. // in the set information path. this means that no post processing
  833. // needs to be done.
  834. //
  835. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  836. ("Completeing internal request\n"));
  837. //
  838. // Is there a reset in progress?
  839. //
  840. if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_RESET_IN_PROGRESS))
  841. {
  842. //
  843. // If this is the last request then complete the reset
  844. // but only if the request is to restore filter
  845. // otherwise, this is a request that is getting aborted
  846. // or completed in the context of a reset
  847. //
  848. if ((NULL == Miniport->PendingRequest) &&
  849. (ReqRsvd->Flags & REQST_LAST_RESTORE))
  850. {
  851. ASSERT(NDIS_STATUS_SUCCESS == Status);
  852. //
  853. // Now clear out the reset in progress stuff.
  854. //
  855. ndisMResetCompleteStage2(Miniport);
  856. }
  857. }
  858. else
  859. {
  860. //
  861. // What if one of these requests fails???? We should probably halt
  862. // the driver sine this is a fatal error as far as the bindings
  863. // are concerned.
  864. //
  865. if (ReqRsvd->Flags & REQST_MANDATORY)
  866. {
  867. ASSERT(NDIS_STATUS_SUCCESS == Status);
  868. }
  869. }
  870. if ((ReqRsvd->Flags & REQST_LAST_RESTORE) == REQST_LAST_RESTORE)
  871. {
  872. MINIPORT_CLEAR_FLAG(Miniport, fMINIPORT_RESTORING_FILTERS);
  873. }
  874. if ((ReqRsvd->Flags & REQST_SIGNAL_EVENT) == REQST_SIGNAL_EVENT)
  875. {
  876. SET_EVENT(&CoReqRsvd->Event);
  877. }
  878. else if (FreeRequest)
  879. {
  880. //
  881. // Free the request.
  882. //
  883. ndisMFreeInternalRequest(Request);
  884. }
  885. }
  886. //
  887. // if we are removing the miniport, we have to signal an event
  888. // when all requests are completed
  889. //
  890. if (Miniport->PendingRequest == NULL)
  891. {
  892. if (Miniport->AllRequestsCompletedEvent)
  893. SET_EVENT(Miniport->AllRequestsCompletedEvent);
  894. }
  895. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  896. ("<==ndisMSyncSetInformationComplete\n"));
  897. }
  898. VOID
  899. ndisMRequestSetInformationPost(
  900. IN PNDIS_MINIPORT_BLOCK Miniport,
  901. IN PNDIS_REQUEST Request,
  902. IN NDIS_STATUS Status
  903. )
  904. /*++
  905. Routine Description:
  906. This routine will do any necessary post processing for ndis requests
  907. of the set information type.
  908. Arguments:
  909. Miniport - Pointer to the miniport block.
  910. Request - Pointer to the request to process.
  911. Return Value:
  912. None.
  913. --*/
  914. {
  915. PNDIS_REQUEST_RESERVED ReqRsvd;
  916. PNDIS_OPEN_BLOCK Open;
  917. PNDIS_PACKET_PATTERN_ENTRY pPacketPattern;
  918. PNDIS_COREQ_RESERVED CoReqRsvd;
  919. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  920. ("==>ndisMRequestSetInformationPost\n"));
  921. //
  922. // Get the reserved information for the request.
  923. //
  924. ReqRsvd = PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request);
  925. Open = ReqRsvd->Open;
  926. switch (Request->DATA.SET_INFORMATION.Oid)
  927. {
  928. case OID_GEN_CURRENT_PACKET_FILTER:
  929. if ((NDIS_STATUS_SUCCESS != Status) && (Open != NULL))
  930. {
  931. //
  932. // The request was completed with something besides
  933. // NDIS_STATUS_SUCCESS (and of course NDIS_STATUS_PENDING).
  934. // Return the packete filter to the original state.
  935. //
  936. switch (Miniport->MediaType)
  937. {
  938. case NdisMedium802_3:
  939. if (!MINIPORT_TEST_FLAG(Open, fMINIPORT_OPEN_CLOSING))
  940. {
  941. XUndoFilterAdjust(Miniport->EthDB, Open->FilterHandle);
  942. }
  943. break;
  944. case NdisMedium802_5:
  945. if (!MINIPORT_TEST_FLAG(Open, fMINIPORT_OPEN_CLOSING))
  946. {
  947. XUndoFilterAdjust(Miniport->TrDB, Open->FilterHandle);
  948. }
  949. break;
  950. case NdisMediumFddi:
  951. if (!MINIPORT_TEST_FLAG(Open, fMINIPORT_OPEN_CLOSING))
  952. {
  953. XUndoFilterAdjust(Miniport->FddiDB, Open->FilterHandle);
  954. }
  955. break;
  956. #if ARCNET
  957. case NdisMediumArcnet878_2:
  958. if (!MINIPORT_TEST_FLAG(Open, fMINIPORT_OPEN_CLOSING))
  959. {
  960. if (MINIPORT_TEST_FLAG(ReqRsvd->Open, fMINIPORT_OPEN_USING_ETH_ENCAPSULATION))
  961. {
  962. XUndoFilterAdjust(Miniport->EthDB, ReqRsvd->Open->FilterHandle);
  963. }
  964. else
  965. {
  966. arcUndoFilterAdjust(Miniport->ArcDB, ReqRsvd->Open->FilterHandle);
  967. }
  968. }
  969. break;
  970. #endif
  971. }
  972. }
  973. //
  974. // check to see how many opens have non zero packet filters
  975. //
  976. if (Miniport->MediaType == NdisMedium802_3)
  977. {
  978. PETH_BINDING_INFO OpenFilter;
  979. PETH_BINDING_INFO ActiveOpenFilter = NULL;
  980. ULONG NumActiveOpens = 0;
  981. for (OpenFilter = Miniport->EthDB->OpenList;
  982. (OpenFilter != NULL) && (NumActiveOpens <= 1);
  983. OpenFilter = OpenFilter->NextOpen)
  984. {
  985. if (OpenFilter->PacketFilters != 0)
  986. {
  987. NumActiveOpens++;
  988. ActiveOpenFilter = OpenFilter;
  989. }
  990. }
  991. if (NumActiveOpens == 1)
  992. {
  993. Miniport->EthDB->SingleActiveOpen = ActiveOpenFilter;
  994. }
  995. else
  996. {
  997. Miniport->EthDB->SingleActiveOpen = NULL;
  998. }
  999. ndisUpdateCheckForLoopbackFlag(Miniport);
  1000. }
  1001. break;
  1002. case OID_GEN_CURRENT_LOOKAHEAD:
  1003. //
  1004. // If we succeeded then update the binding information.
  1005. //
  1006. if (NDIS_STATUS_SUCCESS == Status)
  1007. {
  1008. Miniport->CurrentLookahead = *(UNALIGNED ULONG *)(Request->DATA.SET_INFORMATION.InformationBuffer);
  1009. Open->CurrentLookahead = (USHORT)Miniport->CurrentLookahead;
  1010. Request->DATA.SET_INFORMATION.BytesRead = 4;
  1011. }
  1012. break;
  1013. case OID_802_3_MULTICAST_LIST:
  1014. if (Miniport->MediaType == NdisMedium802_3)
  1015. {
  1016. ethCompleteChangeFilterAddresses(Miniport->EthDB, Status, NULL, FALSE);
  1017. }
  1018. if (Status == NDIS_STATUS_SUCCESS)
  1019. {
  1020. Request->DATA.SET_INFORMATION.BytesRead = Request->DATA.SET_INFORMATION.InformationBufferLength;
  1021. }
  1022. break;
  1023. case OID_802_5_CURRENT_FUNCTIONAL:
  1024. if ((Miniport->MediaType == NdisMedium802_5) &&
  1025. (Status != NDIS_STATUS_SUCCESS) &&
  1026. (Open != NULL) &&
  1027. !MINIPORT_TEST_FLAG(Open, fMINIPORT_OPEN_CLOSING))
  1028. {
  1029. trUndoChangeFunctionalAddress(Miniport->TrDB, Open->FilterHandle);
  1030. }
  1031. break;
  1032. case OID_802_5_CURRENT_GROUP:
  1033. if ((Miniport->MediaType == NdisMedium802_5) &&
  1034. (Status != NDIS_STATUS_SUCCESS) &&
  1035. (Open != NULL) &&
  1036. !MINIPORT_TEST_FLAG(Open, fMINIPORT_OPEN_CLOSING))
  1037. {
  1038. trUndoChangeGroupAddress(Miniport->TrDB, Open->FilterHandle);
  1039. }
  1040. break;
  1041. case OID_FDDI_LONG_MULTICAST_LIST:
  1042. if (Miniport->MediaType == NdisMediumFddi)
  1043. {
  1044. fddiCompleteChangeFilterLongAddresses(Miniport->FddiDB, Status);
  1045. }
  1046. if (Status == NDIS_STATUS_SUCCESS)
  1047. {
  1048. Request->DATA.SET_INFORMATION.BytesRead = Request->DATA.SET_INFORMATION.InformationBufferLength;
  1049. }
  1050. break;
  1051. case OID_FDDI_SHORT_MULTICAST_LIST:
  1052. if (Miniport->MediaType == NdisMediumFddi)
  1053. {
  1054. fddiCompleteChangeFilterShortAddresses(Miniport->FddiDB, Status);
  1055. }
  1056. if (Status == NDIS_STATUS_SUCCESS)
  1057. {
  1058. Request->DATA.SET_INFORMATION.BytesRead = Request->DATA.SET_INFORMATION.InformationBufferLength;
  1059. }
  1060. break;
  1061. case OID_PNP_ADD_WAKE_UP_PATTERN:
  1062. //
  1063. // Get the packet pattern that was completed.
  1064. //
  1065. pPacketPattern = ReqRsvd->Context;
  1066. if (NDIS_STATUS_SUCCESS == Status)
  1067. {
  1068. //
  1069. // Add the packet pattern to the miniport's list.
  1070. //
  1071. PushEntryList(&Miniport->PatternList, &pPacketPattern->Link);
  1072. }
  1073. else
  1074. {
  1075. //
  1076. // Free up the packet pattern that NDIS allocated and fail
  1077. // the request.
  1078. //
  1079. if (pPacketPattern != NULL)
  1080. {
  1081. FREE_POOL(pPacketPattern);
  1082. }
  1083. }
  1084. break;
  1085. case OID_PNP_REMOVE_WAKE_UP_PATTERN:
  1086. //
  1087. // If the miniport succeeded in removing the pattern then
  1088. // we need to find it and remove it from our list.
  1089. //
  1090. if (NDIS_STATUS_SUCCESS == Status)
  1091. {
  1092. PSINGLE_LIST_ENTRY Link;
  1093. PSINGLE_LIST_ENTRY PrevLink;
  1094. PNDIS_PACKET_PATTERN_ENTRY pPatternEntry;
  1095. PNDIS_REQUEST_RESERVED ReqRsvd = PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request);
  1096. PNDIS_PM_PACKET_PATTERN pNdisPacketPattern;
  1097. //
  1098. // Walk the current list of packet patterns.
  1099. //
  1100. for (PrevLink = NULL, Link = Miniport->PatternList.Next;
  1101. Link != NULL;
  1102. PrevLink = Link, Link = Link->Next)
  1103. {
  1104. //
  1105. // Get a pointer to the pattern entry that the Link represents.
  1106. //
  1107. pPatternEntry = CONTAINING_RECORD(Link, NDIS_PACKET_PATTERN_ENTRY, Link);
  1108. //
  1109. // Do the opens match?
  1110. //
  1111. if (pPatternEntry->Open == ReqRsvd->Open)
  1112. {
  1113. //
  1114. // Get a pointer to the packet pattern that the transport
  1115. // wants to remove.
  1116. //
  1117. pNdisPacketPattern = Request->DATA.SET_INFORMATION.InformationBuffer;
  1118. //
  1119. // Make sure that the size of the passed in pattern is the
  1120. // same size as the pattern we are going to compare it with.
  1121. //
  1122. if ((pNdisPacketPattern->PatternSize != pPatternEntry->Pattern.PatternSize) ||
  1123. (pNdisPacketPattern->MaskSize != pPatternEntry->Pattern.MaskSize))
  1124. {
  1125. //
  1126. // Since the sizes don't match the compare below will fail.
  1127. //
  1128. continue;
  1129. }
  1130. //
  1131. // Now we need to match the actual pattern that was
  1132. // passed to us.
  1133. //
  1134. if (NdisEqualMemory(
  1135. Request->DATA.SET_INFORMATION.InformationBuffer,
  1136. &pPatternEntry->Pattern,
  1137. Request->DATA.SET_INFORMATION.InformationBufferLength))
  1138. {
  1139. //
  1140. // Remove the packet pattern.
  1141. //
  1142. if (NULL == PrevLink)
  1143. {
  1144. Miniport->PatternList.Next = Link->Next;
  1145. }
  1146. else
  1147. {
  1148. PrevLink->Next = Link->Next;
  1149. }
  1150. //
  1151. // Free the memory taken by the pattern.
  1152. //
  1153. FREE_POOL(pPatternEntry);
  1154. break;
  1155. }
  1156. }
  1157. }
  1158. }
  1159. break;
  1160. case OID_PNP_QUERY_POWER:
  1161. //
  1162. // The CoReqRsvd portion of the request contains ndis only
  1163. // information about the request.
  1164. //
  1165. CoReqRsvd = PNDIS_COREQ_RESERVED_FROM_REQUEST(Request);
  1166. //
  1167. // Save the status that the miniport returned.
  1168. //
  1169. CoReqRsvd->Status = Status;
  1170. break;
  1171. }
  1172. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1173. ("<==ndisMRequestSetInformationPost\n"));
  1174. }
  1175. NDIS_STATUS
  1176. FASTCALL
  1177. ndisMSetProtocolOptions(
  1178. IN PNDIS_MINIPORT_BLOCK Miniport,
  1179. IN PNDIS_REQUEST Request
  1180. )
  1181. /*++
  1182. Routine Description:
  1183. Arguments:
  1184. Return Value:
  1185. --*/
  1186. {
  1187. NDIS_STATUS Status;
  1188. VERIFY_SET_PARAMETERS(Request, sizeof(ULONG), Status);
  1189. if (Status == NDIS_STATUS_SUCCESS)
  1190. {
  1191. *(UNALIGNED ULONG *)(&PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open->ProtocolOptions) =
  1192. *(UNALIGNED ULONG *)(Request->DATA.SET_INFORMATION.InformationBuffer);
  1193. Request->DATA.SET_INFORMATION.BytesRead = sizeof(ULONG);
  1194. Status = NDIS_STATUS_SUCCESS;
  1195. }
  1196. return(Status);
  1197. }
  1198. NDIS_STATUS
  1199. FASTCALL
  1200. ndisMSetPacketFilter(
  1201. IN PNDIS_MINIPORT_BLOCK Miniport,
  1202. IN PNDIS_REQUEST Request
  1203. )
  1204. /*++
  1205. Routine Description:
  1206. This routine will process two types of set packet filter requests.
  1207. The first one is for when a reset happens. We simply take the
  1208. packet filter setting that is in the request and send it to the adapter.
  1209. The second is when a protocol sets the packet filter, for this we need
  1210. to update the filter library and then send it down to the adapter.
  1211. Arguments:
  1212. Return Value:
  1213. Note:
  1214. Called at DPC with Miniport's lock held.
  1215. --*/
  1216. {
  1217. NDIS_STATUS Status;
  1218. ULONG PacketFilter;
  1219. PNDIS_OPEN_BLOCK Open;
  1220. PNDIS_REQUEST_RESERVED ReqRsvd;
  1221. KIRQL OldIrql;
  1222. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1223. ("==>ndisMSetPacketFilter\n"));
  1224. //
  1225. // Verify the information buffer length that was sent in.
  1226. //
  1227. VERIFY_SET_PARAMETERS(Request, sizeof(PacketFilter), Status);
  1228. if (Status != NDIS_STATUS_SUCCESS)
  1229. {
  1230. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1231. ("<==ndisMSetPacketFilter: 0x%x\n", Status));
  1232. return(Status);
  1233. }
  1234. //
  1235. // Now call the filter package to set the
  1236. // packet filter.
  1237. //
  1238. PacketFilter = *(UNALIGNED ULONG *)(Request->DATA.SET_INFORMATION.InformationBuffer);
  1239. //
  1240. // Get a pointer to the reserved information of the request.
  1241. //
  1242. ReqRsvd = PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request);
  1243. Open = ReqRsvd->Open;
  1244. //
  1245. // If this request is because of an open that is closing then we
  1246. // have already adjusted the filter settings and we just need to
  1247. // make sure that the adapter has the new settings.
  1248. //
  1249. if (MINIPORT_TEST_FLAG(Open, fMINIPORT_OPEN_CLOSING))
  1250. {
  1251. //
  1252. // By setting the Status to NDIS_STATUS_PENDING we will call
  1253. // down to the miniport's SetInformationHandler below.
  1254. //
  1255. Status = NDIS_STATUS_PENDING;
  1256. }
  1257. else
  1258. {
  1259. switch (Miniport->MediaType)
  1260. {
  1261. case NdisMedium802_3:
  1262. Status = XFilterAdjust(Miniport->EthDB,
  1263. Open->FilterHandle,
  1264. PacketFilter,
  1265. TRUE);
  1266. //
  1267. // Do this here in anticipation that we
  1268. // need to call down to the miniport
  1269. // driver.
  1270. //
  1271. PacketFilter = ETH_QUERY_FILTER_CLASSES(Miniport->EthDB);
  1272. break;
  1273. case NdisMedium802_5:
  1274. Status = XFilterAdjust(Miniport->TrDB,
  1275. Open->FilterHandle,
  1276. PacketFilter,
  1277. TRUE);
  1278. //
  1279. // Do this here in anticipation that we
  1280. // need to call down to the miniport
  1281. // driver.
  1282. //
  1283. PacketFilter = TR_QUERY_FILTER_CLASSES(Miniport->TrDB);
  1284. break;
  1285. case NdisMediumFddi:
  1286. Status = XFilterAdjust(Miniport->FddiDB,
  1287. Open->FilterHandle,
  1288. PacketFilter,
  1289. TRUE);
  1290. //
  1291. // Do this here in anticipation that we
  1292. // need to call down to the miniport
  1293. // driver.
  1294. //
  1295. PacketFilter = FDDI_QUERY_FILTER_CLASSES(Miniport->FddiDB);
  1296. break;
  1297. #if ARCNET
  1298. case NdisMediumArcnet878_2:
  1299. if (MINIPORT_TEST_FLAG(Open, fMINIPORT_OPEN_USING_ETH_ENCAPSULATION))
  1300. {
  1301. Status = XFilterAdjust(Miniport->EthDB,
  1302. Open->FilterHandle,
  1303. PacketFilter,
  1304. TRUE);
  1305. }
  1306. else
  1307. {
  1308. Status = ArcFilterAdjust(Miniport->ArcDB,
  1309. Open->FilterHandle,
  1310. Request,
  1311. PacketFilter,
  1312. TRUE);
  1313. }
  1314. //
  1315. // Do this here in anticipation that we
  1316. // need to call down to the miniport
  1317. // driver.
  1318. //
  1319. PacketFilter = ARC_QUERY_FILTER_CLASSES(Miniport->ArcDB);
  1320. PacketFilter |= ETH_QUERY_FILTER_CLASSES(Miniport->EthDB);
  1321. if (MINIPORT_TEST_FLAG(Miniport,
  1322. fMINIPORT_ARCNET_BROADCAST_SET) ||
  1323. (PacketFilter & NDIS_PACKET_TYPE_MULTICAST))
  1324. {
  1325. PacketFilter &= ~NDIS_PACKET_TYPE_MULTICAST;
  1326. PacketFilter |= NDIS_PACKET_TYPE_BROADCAST;
  1327. }
  1328. break;
  1329. #endif
  1330. default:
  1331. break;
  1332. }
  1333. }
  1334. //
  1335. // If this was a request to turn p-mode/l-only on/off then mark things appropriately
  1336. //
  1337. if (Open != NULL)
  1338. {
  1339. PULONG Filter = (PULONG)(Request->DATA.SET_INFORMATION.InformationBuffer);
  1340. if (*Filter & (NDIS_PACKET_TYPE_PROMISCUOUS | NDIS_PACKET_TYPE_ALL_LOCAL))
  1341. {
  1342. if ((Open->Flags & fMINIPORT_OPEN_PMODE) == 0)
  1343. {
  1344. Open->Flags |= fMINIPORT_OPEN_PMODE;
  1345. Miniport->PmodeOpens ++;
  1346. NDIS_CHECK_PMODE_OPEN_REF(Miniport);
  1347. ndisUpdateCheckForLoopbackFlag(Miniport);
  1348. }
  1349. if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_IS_CO))
  1350. {
  1351. *Filter &= ~(NDIS_PACKET_TYPE_PROMISCUOUS | NDIS_PACKET_TYPE_ALL_LOCAL);
  1352. }
  1353. }
  1354. else
  1355. {
  1356. if (Open->Flags & fMINIPORT_OPEN_PMODE)
  1357. {
  1358. Open->Flags &= ~fMINIPORT_OPEN_PMODE;
  1359. Miniport->PmodeOpens --;
  1360. NDIS_CHECK_PMODE_OPEN_REF(Miniport);
  1361. ndisUpdateCheckForLoopbackFlag(Miniport);
  1362. }
  1363. }
  1364. }
  1365. //
  1366. // If the local-only bit is set and the miniport is doing it's own
  1367. // loop back then we need to make sure that we loop back non-self
  1368. // directed packets that are sent out on the pipe.
  1369. //
  1370. if ((PacketFilter & NDIS_PACKET_TYPE_ALL_LOCAL) &&
  1371. (Miniport->MacOptions & NDIS_MAC_OPTION_NO_LOOPBACK) == 0)
  1372. {
  1373. MINIPORT_SET_FLAG(Miniport, fMINIPORT_SEND_LOOPBACK_DIRECTED);
  1374. }
  1375. else
  1376. {
  1377. MINIPORT_CLEAR_FLAG(Miniport, fMINIPORT_SEND_LOOPBACK_DIRECTED);
  1378. }
  1379. //
  1380. // If the filter library returns NDIS_STATUS_PENDING from
  1381. // the XxxFitlerAdjust() then we need to call down to the
  1382. // miniport driver. Other wise this will have succeeded.
  1383. //
  1384. if (NDIS_STATUS_PENDING == Status)
  1385. {
  1386. //
  1387. // Save the current global packet filter in a buffer that will stick around.
  1388. // Remove the ALL_LOCAL bit since miniport does not understand this (and does
  1389. // not need to).
  1390. //
  1391. Miniport->RequestBuffer = (PacketFilter & ~NDIS_PACKET_TYPE_ALL_LOCAL);
  1392. //
  1393. // Call the miniport driver. Save the request parms and restore on completion
  1394. //
  1395. SAVE_REQUEST_BUF(Miniport, Request, &Miniport->RequestBuffer, sizeof(PacketFilter));
  1396. MINIPORT_SET_INFO(Miniport,
  1397. Request,
  1398. &Status);
  1399. }
  1400. //
  1401. // If we have success then set the Bytes read in the original request.
  1402. //
  1403. if (Status != NDIS_STATUS_PENDING)
  1404. {
  1405. RESTORE_REQUEST_BUF(Miniport, Request);
  1406. if (NDIS_STATUS_SUCCESS == Status)
  1407. {
  1408. Request->DATA.SET_INFORMATION.BytesRead = 4;
  1409. }
  1410. else
  1411. {
  1412. Request->DATA.SET_INFORMATION.BytesRead = 0;
  1413. Request->DATA.SET_INFORMATION.BytesNeeded = 0;
  1414. }
  1415. }
  1416. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1417. ("<==ndisMSetPacketFilter: 0x%x\n", Status));
  1418. return(Status);
  1419. }
  1420. NDIS_STATUS
  1421. FASTCALL
  1422. ndisMSetCurrentLookahead(
  1423. IN PNDIS_MINIPORT_BLOCK Miniport,
  1424. IN PNDIS_REQUEST Request
  1425. )
  1426. /*++
  1427. Routine Description:
  1428. Arguments:
  1429. Return Value:
  1430. --*/
  1431. {
  1432. UINT Lookahead;
  1433. ULONG CurrentMax;
  1434. PNDIS_OPEN_BLOCK CurrentOpen;
  1435. NDIS_STATUS Status;
  1436. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1437. ("==>ndisMSetCurrentLookahead\n"));
  1438. //
  1439. // Verify length of the information buffer.
  1440. //
  1441. VERIFY_SET_PARAMETERS(Request, sizeof(Lookahead), Status);
  1442. if (Status != NDIS_STATUS_SUCCESS)
  1443. {
  1444. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1445. ("<==ndisMSetCurrentLookahead: 0x%x\n", Status));
  1446. return(Status);
  1447. }
  1448. //
  1449. // Put the lookahead that the binding requests into a
  1450. // buffer we can use...
  1451. //
  1452. Lookahead = *(UNALIGNED UINT *)(Request->DATA.SET_INFORMATION.InformationBuffer);
  1453. //
  1454. // Verify that the lookahead is within boundaries...
  1455. //
  1456. if (Lookahead > Miniport->MaximumLookahead)
  1457. {
  1458. Request->DATA.SET_INFORMATION.BytesRead = 0;
  1459. Request->DATA.SET_INFORMATION.BytesNeeded = 0;
  1460. Status = NDIS_STATUS_INVALID_LENGTH;
  1461. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1462. ("<==ndisMSetCurrentLookahead: 0x%x\n", Status));
  1463. return(Status);
  1464. }
  1465. //
  1466. // Find the maximum lookahead between all opens that
  1467. // are bound to the miniport driver.
  1468. //
  1469. for (CurrentOpen = Miniport->OpenQueue, CurrentMax = 0;
  1470. CurrentOpen != NULL;
  1471. CurrentOpen = CurrentOpen->MiniportNextOpen)
  1472. {
  1473. if (CurrentOpen->CurrentLookahead > CurrentMax)
  1474. {
  1475. CurrentMax = CurrentOpen->CurrentLookahead;
  1476. }
  1477. }
  1478. //
  1479. // Figure in the new lookahead.
  1480. //
  1481. if (Lookahead > CurrentMax)
  1482. {
  1483. CurrentMax = Lookahead;
  1484. }
  1485. //
  1486. // Adjust the current max lookahead if needed.
  1487. //
  1488. if (CurrentMax == 0)
  1489. {
  1490. CurrentMax = Miniport->MaximumLookahead;
  1491. }
  1492. //
  1493. // Set the default status.
  1494. //
  1495. Status = NDIS_STATUS_SUCCESS;
  1496. //
  1497. // Do we need to call the miniport driver with the
  1498. // new max lookahead?
  1499. //
  1500. if (Miniport->CurrentLookahead != CurrentMax)
  1501. {
  1502. //
  1503. // Save the new lookahead value in a buffer
  1504. // that will stick around.
  1505. //
  1506. Miniport->RequestBuffer = CurrentMax;
  1507. //
  1508. // Send it to the driver.
  1509. //
  1510. SAVE_REQUEST_BUF(Miniport, Request, &Miniport->RequestBuffer, sizeof(CurrentMax));
  1511. MINIPORT_SET_INFO(Miniport,
  1512. Request,
  1513. &Status);
  1514. }
  1515. //
  1516. // If we succeeded then update the binding information.
  1517. //
  1518. if (Status != NDIS_STATUS_PENDING)
  1519. {
  1520. RESTORE_REQUEST_BUF(Miniport, Request);
  1521. if (NDIS_STATUS_SUCCESS == Status)
  1522. {
  1523. PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open->CurrentLookahead = (USHORT)Lookahead;
  1524. Request->DATA.SET_INFORMATION.BytesRead = sizeof(Lookahead);
  1525. Miniport->CurrentLookahead = CurrentMax;
  1526. }
  1527. else
  1528. {
  1529. Request->DATA.SET_INFORMATION.BytesRead = 0;
  1530. Request->DATA.SET_INFORMATION.BytesNeeded = 0;
  1531. }
  1532. }
  1533. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1534. ("<==ndisMSetCurrentLookahead: 0x%x\n", Status));
  1535. return(Status);
  1536. }
  1537. NDIS_STATUS
  1538. FASTCALL
  1539. ndisMSetAddWakeUpPattern(
  1540. IN PNDIS_MINIPORT_BLOCK Miniport,
  1541. IN PNDIS_REQUEST Request
  1542. )
  1543. /*++
  1544. Routine Description:
  1545. This routine will add a packet pattern to a miniports list to be used for
  1546. remote wake-up.
  1547. Arguments:
  1548. Miniport - Pointer to the adapter's miniport block.
  1549. Request - Pointer to the request.
  1550. Return Value:
  1551. NDIS_STATUS_SUCCESS if the packet pattern was successfully added.
  1552. NDIS_STATUS_PENDING if the request will complete asynchronously.
  1553. --*/
  1554. {
  1555. PNDIS_PACKET_PATTERN_ENTRY pPacketEntry;
  1556. ULONG cbSize;
  1557. PNDIS_REQUEST_RESERVED ReqRsvd = PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request);
  1558. NDIS_STATUS Status;
  1559. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1560. ("==>ndisMSetAddWakeUpPattern\n"));
  1561. //
  1562. // Verify the size of the information buffer.
  1563. //
  1564. VERIFY_SET_PARAMETERS(Request, sizeof(NDIS_PM_PACKET_PATTERN), Status);
  1565. if (NDIS_STATUS_SUCCESS == Status)
  1566. {
  1567. //
  1568. // Allocate an NDIS_PACKET_PATTERN_ENTRY to store the new pattern.
  1569. //
  1570. cbSize = (sizeof(NDIS_PACKET_PATTERN_ENTRY) -
  1571. sizeof(NDIS_PM_PACKET_PATTERN)) +
  1572. Request->DATA.SET_INFORMATION.InformationBufferLength;
  1573. pPacketEntry = ALLOC_FROM_POOL(cbSize, NDIS_TAG_PKT_PATTERN);
  1574. if (NULL != pPacketEntry)
  1575. {
  1576. //
  1577. // Copy the request information to the pattern entry.
  1578. //
  1579. MoveMemory(&pPacketEntry->Pattern,
  1580. Request->DATA.SET_INFORMATION.InformationBuffer,
  1581. Request->DATA.SET_INFORMATION.InformationBufferLength);
  1582. //
  1583. // Save the open with the pattern entry.
  1584. //
  1585. pPacketEntry->Open = ReqRsvd->Open;
  1586. //
  1587. // Save the packet entry with the request.
  1588. //
  1589. ReqRsvd->Context = pPacketEntry;
  1590. //
  1591. // Call the miniport driver.
  1592. //
  1593. MINIPORT_SET_INFO(Miniport,
  1594. Request,
  1595. &Status);
  1596. }
  1597. else
  1598. {
  1599. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_ERR,
  1600. ("ndisMSetAddWakeUpPattern: Unable to allocate memory for internal data structure\n"));
  1601. ReqRsvd->Context = NULL;
  1602. Status = NDIS_STATUS_RESOURCES;
  1603. }
  1604. }
  1605. else
  1606. {
  1607. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_ERR,
  1608. ("ndisMSetAddWakeupPattern: Invalid request size\n"));
  1609. }
  1610. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1611. ("<==ndisMSetAddWakeUpPattern\n"));
  1612. return(Status);
  1613. }
  1614. NDIS_STATUS
  1615. FASTCALL
  1616. ndisMSetRemoveWakeUpPattern(
  1617. IN PNDIS_MINIPORT_BLOCK Miniport,
  1618. IN PNDIS_REQUEST Request
  1619. )
  1620. /*++
  1621. Routine Description:
  1622. This routine will remove a packet pattern from a miniports list so that the
  1623. adapter will no longer generate wake-up events for it.
  1624. Arguments:
  1625. Miniport - Pointer to the adapter's miniport block.
  1626. Request - Pointer to the request.
  1627. Return Value:
  1628. NDIS_STATUS_SUCCESS if the packet pattern was successfully added.
  1629. NDIS_STATUS_PENDING if the request will complete asynchronously.
  1630. --*/
  1631. {
  1632. NDIS_STATUS Status;
  1633. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1634. ("==>ndisMSetRemoveWakeUpPattern\n"));
  1635. //
  1636. // Verify the size of the information buffer.
  1637. //
  1638. VERIFY_SET_PARAMETERS(Request, sizeof(NDIS_PM_PACKET_PATTERN), Status);
  1639. if (NDIS_STATUS_SUCCESS == Status)
  1640. {
  1641. //
  1642. // Call the miniport driver.
  1643. //
  1644. MINIPORT_SET_INFO(Miniport,
  1645. Request,
  1646. &Status);
  1647. }
  1648. else
  1649. {
  1650. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_ERR,
  1651. ("ndisMSetRemoveWakeUpPattern: Invalid request size\n"));
  1652. }
  1653. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1654. ("<==ndisMSetRemoveWakeUpPattern\n"));
  1655. return(Status);
  1656. }
  1657. NDIS_STATUS
  1658. FASTCALL
  1659. ndisMSetEnableWakeUp(
  1660. IN PNDIS_MINIPORT_BLOCK Miniport,
  1661. IN PNDIS_REQUEST Request
  1662. )
  1663. /*++
  1664. Routine Description:
  1665. This routine will set the wake-up bits for the open and or the with the
  1666. other opens. If this is different from what is already set on the miniport
  1667. then it will pass the new bits to the miniport.
  1668. Arguments:
  1669. Miniport - Pointer to the adapter's miniport block.
  1670. Request - Pointer to the request.
  1671. Return Value:
  1672. --*/
  1673. {
  1674. NDIS_STATUS Status;
  1675. PNDIS_REQUEST_RESERVED ReqRsvd = PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request);
  1676. PNDIS_OPEN_BLOCK tmpOpen;
  1677. PULONG pEnableWakeUp;
  1678. ULONG newWakeUpEnable;
  1679. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1680. ("==>ndisMSetEnableWakeUp\n"));
  1681. //
  1682. // Verify the request's information buffer.
  1683. //
  1684. VERIFY_SET_PARAMETERS(Request, sizeof(ULONG), Status);
  1685. if (NDIS_STATUS_SUCCESS == Status)
  1686. {
  1687. //
  1688. // Get a PULONG to the information buffer.
  1689. //
  1690. pEnableWakeUp = (PULONG)Request->DATA.QUERY_INFORMATION.InformationBuffer;
  1691. //
  1692. // Save the new wake-up enables with the open.
  1693. //
  1694. ReqRsvd->Open->WakeUpEnable = *pEnableWakeUp;
  1695. //
  1696. // preserve the state of NDIS_PNP_WAKE_UP_MAGIC_PACKET and NDIS_PNP_WAKE_UP_LINK_CHANGE flag
  1697. //
  1698. newWakeUpEnable = Miniport->WakeUpEnable & (NDIS_PNP_WAKE_UP_MAGIC_PACKET | NDIS_PNP_WAKE_UP_LINK_CHANGE);
  1699. //
  1700. // Get the new bitwise or of the wake-up bits.
  1701. //
  1702. for (tmpOpen = Miniport->OpenQueue;
  1703. tmpOpen != NULL;
  1704. tmpOpen = tmpOpen->MiniportNextOpen)
  1705. {
  1706. newWakeUpEnable |= tmpOpen->WakeUpEnable;
  1707. }
  1708. //
  1709. // Save the combination of all opens options with the miniport.
  1710. //
  1711. Miniport->WakeUpEnable = newWakeUpEnable;
  1712. //
  1713. // if this is an IM driver, give it a chance to send the OID down to the physical device
  1714. //
  1715. if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_INTERMEDIATE_DRIVER))
  1716. {
  1717. MINIPORT_SET_INFO(Miniport,
  1718. Request,
  1719. &Status);
  1720. }
  1721. }
  1722. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1723. ("<==ndisMSetEnableWakeUp\n"));
  1724. return(Status);
  1725. }
  1726. NDIS_STATUS
  1727. ndisMQueryInformation(
  1728. IN PNDIS_MINIPORT_BLOCK Miniport,
  1729. IN PNDIS_REQUEST Request
  1730. )
  1731. /*++
  1732. Routine Description:
  1733. Arguments:
  1734. Return Value:
  1735. --*/
  1736. {
  1737. NDIS_STATUS Status;
  1738. PULONG pulBuffer;
  1739. PNDIS_OPEN_BLOCK Open;
  1740. ULONG Generic;
  1741. //
  1742. // If there is no open associated with the request then it is an internal request
  1743. // and we just send it down to the adapter.
  1744. //
  1745. Open = PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open;
  1746. if (Open == NULL)
  1747. {
  1748. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1749. ("ndisMQueryInformation: Internal request calling to the miniport directly\n"));
  1750. MINIPORT_QUERY_INFO(Miniport, Request, &Status);
  1751. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1752. ("<==ndisMQueryInformaiton: 0x%x\n", Status));
  1753. return(Status);
  1754. }
  1755. //
  1756. // Copy the request information into temporary storage.
  1757. //
  1758. pulBuffer = Request->DATA.QUERY_INFORMATION.InformationBuffer;
  1759. //
  1760. // increase the request time out for some requests
  1761. //
  1762. if ((Request->DATA.QUERY_INFORMATION.Oid == OID_GEN_MEDIA_CONNECT_STATUS) ||
  1763. (Request->DATA.QUERY_INFORMATION.Oid == OID_GEN_LINK_SPEED))
  1764. {
  1765. Miniport->CFHangXTicks = 2;
  1766. }
  1767. //
  1768. // We intercept some calls.
  1769. //
  1770. switch (Request->DATA.QUERY_INFORMATION.Oid)
  1771. {
  1772. case OID_GEN_CURRENT_PACKET_FILTER:
  1773. Status = ndisMQueryCurrentPacketFilter(Miniport, Request);
  1774. break;
  1775. case OID_GEN_MEDIA_IN_USE:
  1776. case OID_GEN_MEDIA_SUPPORTED:
  1777. Status = ndisMQueryMediaSupported(Miniport, Request);
  1778. break;
  1779. case OID_GEN_CURRENT_LOOKAHEAD:
  1780. VERIFY_QUERY_PARAMETERS(Request,
  1781. sizeof(Open->CurrentLookahead),
  1782. Status);
  1783. if (NDIS_STATUS_SUCCESS == Status)
  1784. {
  1785. *pulBuffer = Open->CurrentLookahead;
  1786. Request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(Open->CurrentLookahead);
  1787. }
  1788. break;
  1789. case OID_GEN_MAXIMUM_LOOKAHEAD:
  1790. VERIFY_QUERY_PARAMETERS(Request,
  1791. sizeof(Miniport->MaximumLookahead),
  1792. Status);
  1793. if (NDIS_STATUS_SUCCESS == Status)
  1794. {
  1795. *pulBuffer = Miniport->MaximumLookahead;
  1796. Request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(Miniport->MaximumLookahead);
  1797. }
  1798. break;
  1799. case OID_802_3_MULTICAST_LIST:
  1800. Status = ndisMQueryEthernetMulticastList(Miniport, Request);
  1801. break;
  1802. case OID_802_3_MAXIMUM_LIST_SIZE:
  1803. VERIFY_QUERY_PARAMETERS(Request,
  1804. sizeof(Miniport->MaximumLongAddresses),
  1805. Status);
  1806. if (NDIS_STATUS_SUCCESS == Status)
  1807. {
  1808. *pulBuffer = Miniport->MaximumLongAddresses;
  1809. Request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(Miniport->MaximumLongAddresses);
  1810. }
  1811. break;
  1812. case OID_802_5_CURRENT_FUNCTIONAL:
  1813. VERIFY_QUERY_PARAMETERS(Request,
  1814. sizeof(*pulBuffer),
  1815. Status);
  1816. if (NDIS_STATUS_SUCCESS == Status)
  1817. {
  1818. Generic = TR_QUERY_FILTER_BINDING_ADDRESS(Miniport->TrDB,
  1819. Open->FilterHandle);
  1820. *pulBuffer = BYTE_SWAP_ULONG(Generic);
  1821. Request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(*pulBuffer);
  1822. }
  1823. break;
  1824. case OID_802_5_CURRENT_GROUP:
  1825. VERIFY_QUERY_PARAMETERS(Request,
  1826. sizeof(*pulBuffer),
  1827. Status);
  1828. if (NDIS_STATUS_SUCCESS == Status)
  1829. {
  1830. *pulBuffer = BYTE_SWAP_ULONG(TR_QUERY_FILTER_GROUP(Miniport->TrDB));
  1831. Request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(*pulBuffer);
  1832. }
  1833. break;
  1834. case OID_FDDI_LONG_MULTICAST_LIST:
  1835. Status = ndisMQueryLongMulticastList(Miniport, Request);
  1836. break;
  1837. case OID_FDDI_LONG_MAX_LIST_SIZE:
  1838. VERIFY_QUERY_PARAMETERS(Request,
  1839. sizeof(*pulBuffer),
  1840. Status);
  1841. if (Status == NDIS_STATUS_SUCCESS)
  1842. {
  1843. *pulBuffer = Miniport->MaximumLongAddresses;
  1844. Request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(*pulBuffer);
  1845. }
  1846. break;
  1847. case OID_FDDI_SHORT_MULTICAST_LIST:
  1848. Status = ndisMQueryShortMulticastList(Miniport, Request);
  1849. break;
  1850. case OID_FDDI_SHORT_MAX_LIST_SIZE:
  1851. VERIFY_QUERY_PARAMETERS(Request,
  1852. sizeof(Miniport->MaximumShortAddresses),
  1853. Status);
  1854. if (NDIS_STATUS_SUCCESS == Status)
  1855. {
  1856. *pulBuffer = Miniport->MaximumShortAddresses;
  1857. Request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(Miniport->MaximumShortAddresses);
  1858. }
  1859. break;
  1860. case OID_GEN_MAXIMUM_FRAME_SIZE:
  1861. Status = ndisMQueryMaximumFrameSize(Miniport, Request);
  1862. break;
  1863. case OID_GEN_MAXIMUM_TOTAL_SIZE:
  1864. Status = ndisMQueryMaximumTotalSize(Miniport, Request);
  1865. break;
  1866. case OID_802_3_PERMANENT_ADDRESS:
  1867. case OID_802_3_CURRENT_ADDRESS:
  1868. Status = ndisMQueryNetworkAddress(Miniport, Request);
  1869. break;
  1870. case OID_PNP_WAKE_UP_PATTERN_LIST:
  1871. Status = ndisMQueryWakeUpPatternList(Miniport, Request);
  1872. break;
  1873. case OID_PNP_ENABLE_WAKE_UP:
  1874. Status = ndisMQueryEnableWakeUp(Miniport, Request);
  1875. break;
  1876. case OID_GEN_FRIENDLY_NAME:
  1877. Status = NDIS_STATUS_BUFFER_TOO_SHORT;
  1878. if (Request->DATA.QUERY_INFORMATION.InformationBufferLength >= (Miniport->pAdapterInstanceName->Length + sizeof(WCHAR)))
  1879. {
  1880. PUCHAR p = Request->DATA.QUERY_INFORMATION.InformationBuffer;
  1881. NdisMoveMemory(p,
  1882. Miniport->pAdapterInstanceName->Buffer,
  1883. Miniport->pAdapterInstanceName->Length);
  1884. *(PWCHAR)(p + Miniport->pAdapterInstanceName->Length) = 0;
  1885. Request->DATA.QUERY_INFORMATION.BytesWritten =
  1886. Request->DATA.QUERY_INFORMATION.BytesNeeded = Miniport->pAdapterInstanceName->Length + sizeof(WCHAR);
  1887. Status = NDIS_STATUS_SUCCESS;
  1888. }
  1889. break;
  1890. default:
  1891. //
  1892. // We don't filter this request, just pass it down to the driver.
  1893. //
  1894. MINIPORT_QUERY_INFO(Miniport, Request, &Status);
  1895. break;
  1896. }
  1897. return(Status);
  1898. }
  1899. VOID
  1900. FASTCALL
  1901. ndisMSyncQueryInformationComplete(
  1902. IN PNDIS_MINIPORT_BLOCK Miniport,
  1903. IN NDIS_STATUS Status
  1904. )
  1905. /*++
  1906. Routine Description:
  1907. This routine will process a query information complete. This is only
  1908. called from the wrapper. The difference is that this routine will not
  1909. call ndisMProcessDeferred() after processing the completion of the query.
  1910. Arguments:
  1911. Return Value:
  1912. --*/
  1913. {
  1914. PNDIS_REQUEST Request;
  1915. PNDIS_OPEN_BLOCK Open;
  1916. PNDIS_REQUEST_RESERVED ReqRsvd;
  1917. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1918. ("==>ndisMSyncQueryInformationComplete\n"));
  1919. //
  1920. // Clear the timeout flag and the request_in_process flag.
  1921. //
  1922. MINIPORT_CLEAR_FLAG(Miniport, (fMINIPORT_REQUEST_TIMEOUT | fMINIPORT_PROCESSING_REQUEST));
  1923. Miniport->CFHangXTicks = 0;
  1924. //
  1925. // Remove the request.
  1926. //
  1927. Request = Miniport->PendingRequest;
  1928. ASSERT(Request != NULL);
  1929. ReqRsvd = PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request);
  1930. Miniport->PendingRequest = ReqRsvd->Next;
  1931. ReqRsvd->Flags |= REQST_COMPLETED;
  1932. Open = ReqRsvd->Open;
  1933. ASSERT ((ReqRsvd->Flags & REQST_LAST_RESTORE) != REQST_LAST_RESTORE);
  1934. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1935. ("ndisMSyncQueryInformaitonComplete: Request 0x%x, Oid 0x%x\n", Request, Request->DATA.QUERY_INFORMATION.Oid));
  1936. //
  1937. // Was this an internal request?
  1938. //
  1939. if (Open != NULL)
  1940. {
  1941. //
  1942. // Do any necessary post-processing on the query.
  1943. //
  1944. if (Request->DATA.QUERY_INFORMATION.Oid == OID_GEN_SUPPORTED_LIST)
  1945. {
  1946. //
  1947. // Was this a query for the size of the list?
  1948. //
  1949. if (NDIS_STATUS_SUCCESS == Status)
  1950. {
  1951. //
  1952. // Filter out the statistics oids.
  1953. //
  1954. // ndisMFilterOutStatisticsOids(Miniport, Request);
  1955. }
  1956. else
  1957. {
  1958. if ((NULL == Request->DATA.QUERY_INFORMATION.InformationBuffer) ||
  1959. (0 == Request->DATA.QUERY_INFORMATION.InformationBufferLength))
  1960. {
  1961. #if ARCNET
  1962. //
  1963. // If this is ARCnet running encapsulated ethernet then
  1964. // we need to add a couple of OIDs to be safe.
  1965. //
  1966. if ((Miniport->MediaType == NdisMediumArcnet878_2) &&
  1967. MINIPORT_TEST_FLAG(PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open,
  1968. fMINIPORT_OPEN_USING_ETH_ENCAPSULATION))
  1969. {
  1970. Request->DATA.QUERY_INFORMATION.BytesNeeded += (ARC_NUMBER_OF_EXTRA_OIDS * sizeof(NDIS_OID));
  1971. }
  1972. #endif
  1973. }
  1974. Request->DATA.QUERY_INFORMATION.BytesWritten = 0;
  1975. }
  1976. }
  1977. else if (Request->DATA.QUERY_INFORMATION.Oid == OID_PNP_CAPABILITIES)
  1978. {
  1979. if ((Status == NDIS_STATUS_SUCCESS) &&
  1980. !(MINIPORT_TEST_FLAG(Miniport, fMINIPORT_INTERMEDIATE_DRIVER)))
  1981. {
  1982. //
  1983. // setup the WOL flag
  1984. //
  1985. ((PNDIS_PNP_CAPABILITIES)Request->DATA.QUERY_INFORMATION.InformationBuffer)->Flags = Miniport->PMCapabilities.Flags;
  1986. }
  1987. }
  1988. else if (Request->DATA.QUERY_INFORMATION.Oid == OID_GEN_MAC_OPTIONS)
  1989. {
  1990. if (Status == NDIS_STATUS_SUCCESS)
  1991. {
  1992. *((PULONG)Request->DATA.QUERY_INFORMATION.InformationBuffer) |= (Miniport->MacOptions & NDIS_MAC_OPTION_SUPPORTS_MAC_ADDRESS_OVERWRITE);
  1993. }
  1994. }
  1995. //
  1996. // Indicate to Protocol;
  1997. //
  1998. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  1999. ("Open 0x%x\n", Open));
  2000. NDIS_RELEASE_MINIPORT_SPIN_LOCK_DPC(Miniport);
  2001. (Open->RequestCompleteHandler)(Open->ProtocolBindingContext,
  2002. Request,
  2003. Status);
  2004. NDIS_ACQUIRE_MINIPORT_SPIN_LOCK_DPC(Miniport);
  2005. ndisMDereferenceOpen(Open);
  2006. }
  2007. else
  2008. {
  2009. PNDIS_COREQ_RESERVED CoReqRsvd;
  2010. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2011. ("Completing Internal Request\n"));
  2012. //
  2013. // The CoReqRsvd portion of the request contains ndis only
  2014. // information about the request.
  2015. //
  2016. CoReqRsvd = PNDIS_COREQ_RESERVED_FROM_REQUEST(Request);
  2017. CoReqRsvd->Status = Status;
  2018. //
  2019. // Do post processing for media-connect query
  2020. //
  2021. if ((Miniport->MediaRequest == Request) && (Status == NDIS_STATUS_SUCCESS))
  2022. {
  2023. BOOLEAN NowConnected = (*(PULONG)(Request->DATA.QUERY_INFORMATION.InformationBuffer) == NdisMediaStateConnected);
  2024. ASSERT (Request->DATA.QUERY_INFORMATION.Oid == OID_GEN_MEDIA_CONNECT_STATUS);
  2025. if (NowConnected ^ MINIPORT_TEST_FLAGS(Miniport, fMINIPORT_MEDIA_CONNECTED))
  2026. {
  2027. NDIS_RELEASE_MINIPORT_SPIN_LOCK_DPC(Miniport);
  2028. NdisMIndicateStatus(Miniport,
  2029. NowConnected ?
  2030. NDIS_STATUS_MEDIA_CONNECT : NDIS_STATUS_MEDIA_DISCONNECT,
  2031. INTERNAL_INDICATION_BUFFER,
  2032. INTERNAL_INDICATION_SIZE);
  2033. NdisMIndicateStatusComplete(Miniport);
  2034. NDIS_ACQUIRE_MINIPORT_SPIN_LOCK_DPC(Miniport);
  2035. }
  2036. }
  2037. //
  2038. // Do we need to signal anyone?
  2039. //
  2040. if ((ReqRsvd->Flags & REQST_SIGNAL_EVENT) == REQST_SIGNAL_EVENT)
  2041. {
  2042. SET_EVENT(&CoReqRsvd->Event);
  2043. }
  2044. else if ((ReqRsvd->Flags & REQST_FREE_REQUEST) == REQST_FREE_REQUEST)
  2045. {
  2046. ndisMFreeInternalRequest(Request);
  2047. }
  2048. }
  2049. //
  2050. // if we are removing the miniport, we have to signal an event
  2051. // when all requests are completed
  2052. //
  2053. if (Miniport->PendingRequest == NULL)
  2054. {
  2055. if (Miniport->AllRequestsCompletedEvent)
  2056. SET_EVENT(Miniport->AllRequestsCompletedEvent);
  2057. }
  2058. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2059. ("<==ndisMSyncQueryInformationComplete\n"));
  2060. }
  2061. VOID
  2062. NdisMQueryInformationComplete(
  2063. IN NDIS_HANDLE MiniportAdapterHandle,
  2064. IN NDIS_STATUS Status
  2065. )
  2066. /*++
  2067. Routine Description:
  2068. This function indicates the completion of a query information operation.
  2069. Arguments:
  2070. MiniportAdapterHandle - points to the adapter block.
  2071. Status - Status of the operation
  2072. Return Value:
  2073. None.
  2074. --*/
  2075. {
  2076. PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK)MiniportAdapterHandle;
  2077. KIRQL OldIrql;
  2078. ASSERT_MINIPORT_LOCKED(Miniport);
  2079. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2080. ("==>ndisMQueryInformationComplete\n"));
  2081. //
  2082. // If there is no request then we assume this is a complete that was
  2083. // aborted due to the heart-beat.
  2084. //
  2085. if (!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_PROCESSING_REQUEST))
  2086. {
  2087. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2088. ("ndisMQueryInformationComplete: No request to complete\n"));
  2089. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2090. ("<==ndisMQueryInformationComplete\n"));
  2091. return;
  2092. }
  2093. NDIS_ACQUIRE_MINIPORT_SPIN_LOCK(Miniport, &OldIrql);
  2094. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2095. ("Enter query information complete\n"));
  2096. //
  2097. // Do the actual processing of the query information complete.
  2098. //
  2099. ndisMSyncQueryInformationComplete(Miniport, Status);
  2100. //
  2101. // Are there more requests pending?
  2102. //
  2103. if (Miniport->PendingRequest != NULL)
  2104. {
  2105. NDISM_QUEUE_WORK_ITEM(Miniport, NdisWorkItemRequest, NULL);
  2106. }
  2107. NDIS_RELEASE_MINIPORT_SPIN_LOCK(Miniport, OldIrql);
  2108. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2109. ("<==ndisMQueryInformationComplete\n"));
  2110. }
  2111. NDIS_STATUS
  2112. FASTCALL
  2113. ndisMQueryCurrentPacketFilter(
  2114. IN PNDIS_MINIPORT_BLOCK Miniport,
  2115. IN PNDIS_REQUEST Request
  2116. )
  2117. /*++
  2118. Routine Description:
  2119. Arguments:
  2120. Return Value:
  2121. --*/
  2122. {
  2123. ULONG PacketFilter;
  2124. NDIS_HANDLE FilterHandle;
  2125. NDIS_STATUS Status;
  2126. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2127. ("==>ndisMQueryCurrentPacketFilter\n"));
  2128. //
  2129. // Verify the buffer that was passed to us.
  2130. //
  2131. VERIFY_QUERY_PARAMETERS(Request, sizeof(PacketFilter), Status);
  2132. if (Status != NDIS_STATUS_SUCCESS)
  2133. {
  2134. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2135. ("<==ndisMQueryCurrentPacketFilter: 0x%x\n", Status));
  2136. return(Status);
  2137. }
  2138. //
  2139. // Get the filter handle from the open block.
  2140. //
  2141. FilterHandle = PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open->FilterHandle;
  2142. //
  2143. // Get the packet filter from the filter library.
  2144. //
  2145. switch (Miniport->MediaType)
  2146. {
  2147. case NdisMedium802_3:
  2148. PacketFilter = ETH_QUERY_PACKET_FILTER(Miniport->EthDB, FilterHandle);
  2149. break;
  2150. case NdisMedium802_5:
  2151. PacketFilter = TR_QUERY_PACKET_FILTER(Miniport->TrDB, FilterHandle);
  2152. break;
  2153. case NdisMediumFddi:
  2154. PacketFilter = FDDI_QUERY_PACKET_FILTER(Miniport->FddiDB, FilterHandle);
  2155. break;
  2156. #if ARCNET
  2157. case NdisMediumArcnet878_2:
  2158. if (MINIPORT_TEST_FLAG(
  2159. PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open,
  2160. fMINIPORT_OPEN_USING_ETH_ENCAPSULATION))
  2161. {
  2162. PacketFilter = ETH_QUERY_PACKET_FILTER(Miniport->EthDB, FilterHandle);
  2163. }
  2164. else
  2165. {
  2166. PacketFilter = ARC_QUERY_PACKET_FILTER(Miniport->ArcDB, FilterHandle);
  2167. }
  2168. break;
  2169. #endif
  2170. }
  2171. //
  2172. // Place the packet filter in the buffer that was passed in.
  2173. //
  2174. *(UNALIGNED ULONG *)(Request->DATA.QUERY_INFORMATION.InformationBuffer) = PacketFilter;
  2175. Request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(PacketFilter);
  2176. Status = NDIS_STATUS_SUCCESS;
  2177. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2178. ("<==ndisMQueryCurrentPacketFilter: 0x%x\n", Status));
  2179. return(Status);
  2180. }
  2181. NDIS_STATUS
  2182. FASTCALL
  2183. ndisMQueryMediaSupported(
  2184. IN PNDIS_MINIPORT_BLOCK Miniport,
  2185. IN PNDIS_REQUEST Request
  2186. )
  2187. /*++
  2188. Routine Description:
  2189. Arguments:
  2190. Return Value:
  2191. --*/
  2192. {
  2193. ULONG MediaType;
  2194. NDIS_STATUS Status;
  2195. //
  2196. // Verify the size of the buffer that was passed in by the binding.
  2197. //
  2198. VERIFY_QUERY_PARAMETERS(Request, sizeof(MediaType), Status);
  2199. if (Status != NDIS_STATUS_SUCCESS)
  2200. {
  2201. return(Status);
  2202. }
  2203. //
  2204. // Default the media type to what the miniport knows it is.
  2205. //
  2206. MediaType = (ULONG)Miniport->MediaType;
  2207. #if ARCNET
  2208. //
  2209. // If we are doing ethernet encapsulation then lie.
  2210. //
  2211. if ((NdisMediumArcnet878_2 == Miniport->MediaType) &&
  2212. MINIPORT_TEST_FLAG(PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open,
  2213. fMINIPORT_OPEN_USING_ETH_ENCAPSULATION))
  2214. {
  2215. //
  2216. // Tell the binding that we are ethernet.
  2217. //
  2218. MediaType = (ULONG)NdisMedium802_3;
  2219. }
  2220. #endif
  2221. //
  2222. // Save it in the request.
  2223. //
  2224. *(UNALIGNED ULONG *)(Request->DATA.QUERY_INFORMATION.InformationBuffer) = MediaType;
  2225. Request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(MediaType);
  2226. return(NDIS_STATUS_SUCCESS);
  2227. }
  2228. NDIS_STATUS
  2229. FASTCALL
  2230. ndisMQueryEthernetMulticastList(
  2231. IN PNDIS_MINIPORT_BLOCK Miniport,
  2232. IN PNDIS_REQUEST Request
  2233. )
  2234. /*++
  2235. Routine Description:
  2236. Arguments:
  2237. Return Value:
  2238. --*/
  2239. {
  2240. NDIS_STATUS Status;
  2241. UINT NumberOfAddresses;
  2242. //
  2243. // call the filter library to get the list of multicast
  2244. // addresses for this open
  2245. //
  2246. EthQueryOpenFilterAddresses(&Status,
  2247. Miniport->EthDB,
  2248. PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open->FilterHandle,
  2249. Request->DATA.QUERY_INFORMATION.InformationBufferLength,
  2250. &NumberOfAddresses,
  2251. Request->DATA.QUERY_INFORMATION.InformationBuffer);
  2252. //
  2253. // If the library returned NDIS_STATUS_FAILURE then the buffer
  2254. // was not big enough. So call back down to determine how
  2255. // much buffer space we need.
  2256. //
  2257. if (NDIS_STATUS_FAILURE == Status)
  2258. {
  2259. Request->DATA.QUERY_INFORMATION.BytesNeeded =
  2260. ETH_LENGTH_OF_ADDRESS *
  2261. EthNumberOfOpenFilterAddresses(
  2262. Miniport->EthDB,
  2263. PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open->FilterHandle);
  2264. Request->DATA.QUERY_INFORMATION.BytesWritten = 0;
  2265. Status = NDIS_STATUS_INVALID_LENGTH;
  2266. }
  2267. else
  2268. {
  2269. Request->DATA.QUERY_INFORMATION.BytesNeeded = 0;
  2270. Request->DATA.QUERY_INFORMATION.BytesWritten = NumberOfAddresses * ETH_LENGTH_OF_ADDRESS;
  2271. }
  2272. return(Status);
  2273. }
  2274. NDIS_STATUS
  2275. FASTCALL
  2276. ndisMQueryLongMulticastList(
  2277. IN PNDIS_MINIPORT_BLOCK Miniport,
  2278. IN PNDIS_REQUEST Request
  2279. )
  2280. /*++
  2281. Routine Description:
  2282. Arguments:
  2283. Return Value:
  2284. --*/
  2285. {
  2286. NDIS_STATUS Status;
  2287. UINT NumberOfAddresses;
  2288. //
  2289. // Call the filter library to get the list of long
  2290. // multicast address for this open.
  2291. //
  2292. FddiQueryOpenFilterLongAddresses(&Status,
  2293. Miniport->FddiDB,
  2294. PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open->FilterHandle,
  2295. Request->DATA.QUERY_INFORMATION.InformationBufferLength,
  2296. &NumberOfAddresses,
  2297. Request->DATA.QUERY_INFORMATION.InformationBuffer);
  2298. //
  2299. // If the library returned NDIS_STATUS_FAILURE then the buffer
  2300. // was not big enough. So call back down to determine how
  2301. // much buffer space we need.
  2302. //
  2303. if (NDIS_STATUS_FAILURE == Status)
  2304. {
  2305. Request->DATA.QUERY_INFORMATION.BytesNeeded =
  2306. FDDI_LENGTH_OF_LONG_ADDRESS *
  2307. FddiNumberOfOpenFilterLongAddresses(
  2308. Miniport->FddiDB,
  2309. PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open->FilterHandle);
  2310. Request->DATA.QUERY_INFORMATION.BytesWritten = 0;
  2311. Status = NDIS_STATUS_INVALID_LENGTH;
  2312. }
  2313. else
  2314. {
  2315. Request->DATA.QUERY_INFORMATION.BytesNeeded = 0;
  2316. Request->DATA.QUERY_INFORMATION.BytesWritten = NumberOfAddresses * FDDI_LENGTH_OF_LONG_ADDRESS;
  2317. }
  2318. return(Status);
  2319. }
  2320. NDIS_STATUS
  2321. FASTCALL
  2322. ndisMQueryShortMulticastList(
  2323. IN PNDIS_MINIPORT_BLOCK Miniport,
  2324. IN PNDIS_REQUEST Request
  2325. )
  2326. /*++
  2327. Routine Description:
  2328. Arguments:
  2329. Return Value:
  2330. --*/
  2331. {
  2332. NDIS_STATUS Status;
  2333. UINT NumberOfAddresses;
  2334. //
  2335. // Call the filter library to get the list of long
  2336. // multicast address for this open.
  2337. //
  2338. FddiQueryOpenFilterShortAddresses(&Status,
  2339. Miniport->FddiDB,
  2340. PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open->FilterHandle,
  2341. Request->DATA.QUERY_INFORMATION.InformationBufferLength,
  2342. &NumberOfAddresses,
  2343. Request->DATA.QUERY_INFORMATION.InformationBuffer);
  2344. //
  2345. // If the library returned NDIS_STATUS_FAILURE then the buffer
  2346. // was not big enough. So call back down to determine how
  2347. // much buffer space we need.
  2348. //
  2349. if (NDIS_STATUS_FAILURE == Status)
  2350. {
  2351. Request->DATA.QUERY_INFORMATION.BytesNeeded =
  2352. FDDI_LENGTH_OF_SHORT_ADDRESS *
  2353. FddiNumberOfOpenFilterShortAddresses(
  2354. Miniport->FddiDB,
  2355. PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open->FilterHandle);
  2356. Request->DATA.QUERY_INFORMATION.BytesWritten = 0;
  2357. Status = NDIS_STATUS_INVALID_LENGTH;
  2358. }
  2359. else
  2360. {
  2361. Request->DATA.QUERY_INFORMATION.BytesNeeded = 0;
  2362. Request->DATA.QUERY_INFORMATION.BytesWritten = NumberOfAddresses * FDDI_LENGTH_OF_SHORT_ADDRESS;
  2363. }
  2364. return(Status);
  2365. }
  2366. NDIS_STATUS
  2367. FASTCALL
  2368. ndisMQueryMaximumFrameSize(
  2369. IN PNDIS_MINIPORT_BLOCK Miniport,
  2370. IN PNDIS_REQUEST Request
  2371. )
  2372. /*++
  2373. Routine Description:
  2374. Arguments:
  2375. Return Value:
  2376. --*/
  2377. {
  2378. NDIS_STATUS Status;
  2379. PULONG pulBuffer = Request->DATA.QUERY_INFORMATION.InformationBuffer;
  2380. VERIFY_QUERY_PARAMETERS(Request, sizeof(*pulBuffer), Status);
  2381. if (Status != NDIS_STATUS_SUCCESS)
  2382. {
  2383. return(Status);
  2384. }
  2385. #if ARCNET
  2386. //
  2387. // Is this ARCnet using encapsulated ethernet?
  2388. //
  2389. if (Miniport->MediaType == NdisMediumArcnet878_2)
  2390. {
  2391. if (MINIPORT_TEST_FLAG(
  2392. PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open,
  2393. fMINIPORT_OPEN_USING_ETH_ENCAPSULATION))
  2394. {
  2395. //
  2396. // 504 - 14 (ethernet header) == 490.
  2397. //
  2398. *pulBuffer = ARC_MAX_FRAME_SIZE - 14;
  2399. Request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(*pulBuffer);
  2400. return(NDIS_STATUS_SUCCESS);
  2401. }
  2402. }
  2403. #endif
  2404. //
  2405. // Call the miniport for the information.
  2406. //
  2407. MINIPORT_QUERY_INFO(Miniport, Request, &Status);
  2408. return(Status);
  2409. }
  2410. NDIS_STATUS
  2411. FASTCALL
  2412. ndisMQueryMaximumTotalSize(
  2413. IN PNDIS_MINIPORT_BLOCK Miniport,
  2414. IN PNDIS_REQUEST Request
  2415. )
  2416. /*++
  2417. Routine Description:
  2418. Arguments:
  2419. Return Value:
  2420. --*/
  2421. {
  2422. NDIS_STATUS Status;
  2423. PULONG pulBuffer = Request->DATA.QUERY_INFORMATION.InformationBuffer;
  2424. VERIFY_QUERY_PARAMETERS(Request, sizeof(*pulBuffer), Status);
  2425. if (Status != NDIS_STATUS_SUCCESS)
  2426. {
  2427. return(Status);
  2428. }
  2429. #if ARCNET
  2430. //
  2431. // Is this ARCnet using encapsulated ethernet?
  2432. //
  2433. if (Miniport->MediaType == NdisMediumArcnet878_2)
  2434. {
  2435. if (MINIPORT_TEST_FLAG(
  2436. PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open,
  2437. fMINIPORT_OPEN_USING_ETH_ENCAPSULATION))
  2438. {
  2439. *pulBuffer = ARC_MAX_FRAME_SIZE;
  2440. Request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(*pulBuffer);
  2441. return(NDIS_STATUS_SUCCESS);
  2442. }
  2443. }
  2444. #endif
  2445. //
  2446. // Call the miniport for the information.
  2447. //
  2448. MINIPORT_QUERY_INFO(Miniport, Request, &Status);
  2449. return(Status);
  2450. }
  2451. NDIS_STATUS
  2452. FASTCALL
  2453. ndisMQueryNetworkAddress(
  2454. IN PNDIS_MINIPORT_BLOCK Miniport,
  2455. IN PNDIS_REQUEST Request
  2456. )
  2457. /*++
  2458. Routine Description:
  2459. Arguments:
  2460. Return Value:
  2461. --*/
  2462. {
  2463. NDIS_STATUS Status;
  2464. UCHAR Address[ETH_LENGTH_OF_ADDRESS];
  2465. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2466. ("==>ndisMQueryNetworkAddress\n"));
  2467. VERIFY_QUERY_PARAMETERS(Request, ETH_LENGTH_OF_ADDRESS, Status);
  2468. if (Status != NDIS_STATUS_SUCCESS)
  2469. {
  2470. return(Status);
  2471. }
  2472. #if ARCNET
  2473. //
  2474. // Is this ARCnet using encapsulated ethernet?
  2475. //
  2476. if (Miniport->MediaType == NdisMediumArcnet878_2)
  2477. {
  2478. if (MINIPORT_TEST_FLAG(
  2479. PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open,
  2480. fMINIPORT_OPEN_USING_ETH_ENCAPSULATION))
  2481. {
  2482. //
  2483. // Arcnet-to-ethernet conversion.
  2484. //
  2485. ZeroMemory(Address, ETH_LENGTH_OF_ADDRESS);
  2486. Address[5] = Miniport->ArcnetAddress;
  2487. ETH_COPY_NETWORK_ADDRESS(Request->DATA.QUERY_INFORMATION.InformationBuffer, Address);
  2488. Request->DATA.QUERY_INFORMATION.BytesWritten = ETH_LENGTH_OF_ADDRESS;
  2489. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2490. ("<==ndisMQueryNetworkAddress\n"));
  2491. return(NDIS_STATUS_SUCCESS);
  2492. }
  2493. }
  2494. #endif
  2495. //
  2496. // Call the miniport for the information.
  2497. //
  2498. MINIPORT_QUERY_INFO(Miniport, Request, &Status);
  2499. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2500. ("<==ndisMQueryNetworkAddress\n"));
  2501. return(Status);
  2502. }
  2503. NDIS_STATUS
  2504. FASTCALL
  2505. ndisMQueryWakeUpPatternList(
  2506. IN PNDIS_MINIPORT_BLOCK Miniport,
  2507. IN PNDIS_REQUEST Request
  2508. )
  2509. /*++
  2510. Routine Description:
  2511. This routinen is executed when a client requests the list of wake-up
  2512. patterns that are set on a given open.
  2513. Arguments:
  2514. Miniport - Pointer to the miniport block of the adapter.
  2515. Request - Pointer to the request.
  2516. Return Value:
  2517. NDIS_STATUS_SUCCESS if the request is successful.
  2518. NDIS_STATUS_PENDING if the request will complete asynchronously.
  2519. NDIS_STATUS_FAILURE if we are unable to complete the request.
  2520. --*/
  2521. {
  2522. PNDIS_REQUEST_RESERVED ReqRsvd = PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request);
  2523. PNDIS_OPEN_BLOCK Open = ReqRsvd->Open;
  2524. PSINGLE_LIST_ENTRY Link;
  2525. PNDIS_PACKET_PATTERN_ENTRY pPatternEntry;
  2526. ULONG SizeNeeded = 0;
  2527. NDIS_STATUS Status;
  2528. PUCHAR Buffer;
  2529. NDIS_REQUEST_TYPE RequestType = Request->RequestType;
  2530. ULONG BytesWritten = 0;
  2531. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2532. ("==>ndisMQueryWakeUpPatternList\n"));
  2533. //
  2534. // Go through the pattern list and determine the size of the buffer
  2535. // that is needed for the query.
  2536. //
  2537. for (Link = Miniport->PatternList.Next; Link != NULL; Link = Link->Next)
  2538. {
  2539. //
  2540. // Get a pointer to the pattern.
  2541. //
  2542. pPatternEntry = CONTAINING_RECORD(
  2543. Link,
  2544. NDIS_PACKET_PATTERN_ENTRY,
  2545. Link);
  2546. //
  2547. // Is this pattern for the correct open block? or is the request
  2548. // for global statistics?
  2549. //
  2550. if ((pPatternEntry->Open == Open) ||
  2551. (RequestType == NdisRequestQueryStatistics))
  2552. {
  2553. //
  2554. // Add the size of the pattern to the total size.
  2555. //
  2556. SizeNeeded += (sizeof(NDIS_PM_PACKET_PATTERN) +
  2557. pPatternEntry->Pattern.MaskSize +
  2558. pPatternEntry->Pattern.PatternSize);
  2559. }
  2560. }
  2561. //
  2562. // Verify the buffer that was passed us.
  2563. //
  2564. VERIFY_QUERY_PARAMETERS(Request, SizeNeeded, Status);
  2565. if (NDIS_STATUS_SUCCESS == Status)
  2566. {
  2567. //
  2568. // Get a temp pointer to the InformationBuffer.
  2569. //
  2570. Buffer = Request->DATA.QUERY_INFORMATION.InformationBuffer;
  2571. //
  2572. // Loop through again and copy the patterns into the information
  2573. // buffer.
  2574. //
  2575. for (Link = Miniport->PatternList.Next; Link != NULL; Link = Link->Next)
  2576. {
  2577. //
  2578. // Get a pointer to the pattern.
  2579. //
  2580. pPatternEntry = CONTAINING_RECORD(
  2581. Link,
  2582. NDIS_PACKET_PATTERN_ENTRY,
  2583. Link);
  2584. //
  2585. // Is this pattern for the correct open block? or is the request
  2586. // for global statistics?
  2587. //
  2588. if ((pPatternEntry->Open == Open) ||
  2589. (RequestType == NdisRequestQueryStatistics))
  2590. {
  2591. //
  2592. // Get the size of the pattern that needs to be copied.
  2593. //
  2594. SizeNeeded = (sizeof(NDIS_PM_PACKET_PATTERN) +
  2595. pPatternEntry->Pattern.MaskSize +
  2596. pPatternEntry->Pattern.PatternSize);
  2597. //
  2598. // Copy the packet pattern to the buffer.
  2599. //
  2600. NdisMoveMemory(Buffer, &pPatternEntry->Pattern, SizeNeeded);
  2601. //
  2602. // Increment the Buffer to the place to start copying next.
  2603. //
  2604. Buffer += SizeNeeded;
  2605. BytesWritten += SizeNeeded;
  2606. }
  2607. }
  2608. }
  2609. Request->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten;
  2610. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2611. ("<==ndisMQueryWakeUpPatternList\n"));
  2612. return(Status);
  2613. }
  2614. NDIS_STATUS
  2615. FASTCALL
  2616. ndisMQueryEnableWakeUp(
  2617. IN PNDIS_MINIPORT_BLOCK Miniport,
  2618. IN PNDIS_REQUEST Request
  2619. )
  2620. /*++
  2621. Routine Description:
  2622. This routine will process the query information for the
  2623. OID_PNP_ENABLE_WAKE_UP. This is a bit mask that defines what will generate
  2624. a wake-up event. This is set on an open basis but when it's passed down
  2625. to the miniport it is the bit wise or of all opens on the miniport.
  2626. Arguments:
  2627. Miniport - Pointer to the adapter's miniport block.
  2628. Request - Pointer to the request block describing the OID.
  2629. Return Value:
  2630. NDIS_STATUS_SUCCESS if the set is successful.
  2631. --*/
  2632. {
  2633. PNDIS_REQUEST_RESERVED ReqRsvd = PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request);
  2634. NDIS_STATUS Status;
  2635. PULONG pEnableWakeUp;
  2636. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2637. ("==>ndisMQueryEnableWakeUp\n"));
  2638. //
  2639. // Verify that we have enough room in the information buffer.
  2640. //
  2641. VERIFY_QUERY_PARAMETERS(Request, sizeof(ULONG), Status);
  2642. if (NDIS_STATUS_SUCCESS == Status)
  2643. {
  2644. //
  2645. // Get a pointer to the information buffer as a PULONG.
  2646. //
  2647. pEnableWakeUp = (PULONG)Request->DATA.QUERY_INFORMATION.InformationBuffer;
  2648. //
  2649. // Store the currently enabled wake-up's with the request buffer.
  2650. //
  2651. *pEnableWakeUp = ReqRsvd->Open->WakeUpEnable;
  2652. //
  2653. // Finish the request.
  2654. //
  2655. Request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(ULONG);
  2656. Request->DATA.QUERY_INFORMATION.BytesNeeded = 0;
  2657. }
  2658. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  2659. ("<==ndisMQueryEnableWakeUp\n"));
  2660. return(Status);
  2661. }
  2662. VOID
  2663. FASTCALL
  2664. ndisMRestoreFilterSettings(
  2665. IN PNDIS_MINIPORT_BLOCK Miniport,
  2666. IN PNDIS_OPEN_BLOCK Open OPTIONAL,
  2667. IN BOOLEAN fReset
  2668. )
  2669. /*++
  2670. Routine Description:
  2671. This routine will build request's to send down to the driver to
  2672. restore the filter settings. we have free run of the request queue
  2673. since we just reset it.
  2674. Arguments:
  2675. Miniport
  2676. Open: Optional. set when the restore is the result of an adapter getting closed
  2677. fReset: flag to specify if we are restoreing filters as a result of resetting the adapter
  2678. Return Value:
  2679. None
  2680. Comments:
  2681. called with Miniport's Spinlock held.
  2682. --*/
  2683. {
  2684. PNDIS_REQUEST LastRequest = NULL, Request = NULL;
  2685. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  2686. ULONG PacketFilter;
  2687. UINT NumberOfAddresses;
  2688. UINT FunctionalAddress;
  2689. UINT GroupAddress;
  2690. BOOLEAN fSetPacketFilter = TRUE;
  2691. do
  2692. {
  2693. //
  2694. // Get the packet filter for the media type.
  2695. //
  2696. switch (Miniport->MediaType)
  2697. {
  2698. case NdisMedium802_3:
  2699. PacketFilter = ETH_QUERY_FILTER_CLASSES(Miniport->EthDB);
  2700. break;
  2701. case NdisMedium802_5:
  2702. PacketFilter = TR_QUERY_FILTER_CLASSES(Miniport->TrDB);
  2703. break;
  2704. case NdisMediumFddi:
  2705. PacketFilter = FDDI_QUERY_FILTER_CLASSES(Miniport->FddiDB);
  2706. break;
  2707. #if ARCNET
  2708. case NdisMediumArcnet878_2:
  2709. PacketFilter = ARC_QUERY_FILTER_CLASSES(Miniport->ArcDB);
  2710. PacketFilter |= ETH_QUERY_FILTER_CLASSES(Miniport->EthDB);
  2711. if (MINIPORT_TEST_FLAG(
  2712. Miniport,
  2713. fMINIPORT_ARCNET_BROADCAST_SET) ||
  2714. (PacketFilter & NDIS_PACKET_TYPE_MULTICAST))
  2715. {
  2716. PacketFilter &= ~NDIS_PACKET_TYPE_MULTICAST;
  2717. PacketFilter |= NDIS_PACKET_TYPE_BROADCAST;
  2718. }
  2719. break;
  2720. #endif
  2721. default:
  2722. fSetPacketFilter = FALSE;
  2723. break;
  2724. }
  2725. //
  2726. // If the media in question needs it then set the packet filter.
  2727. //
  2728. if (fSetPacketFilter)
  2729. {
  2730. //
  2731. // Allocate a request to restore the packet filter.
  2732. //
  2733. Status = ndisMAllocateRequest(&Request,
  2734. OID_GEN_CURRENT_PACKET_FILTER,
  2735. &PacketFilter,
  2736. sizeof(PacketFilter));
  2737. if (Status != NDIS_STATUS_SUCCESS)
  2738. {
  2739. break;
  2740. }
  2741. SET_INTERNAL_REQUEST(Request, Open, REQST_FREE_REQUEST);
  2742. LastRequest = Request;
  2743. ndisMQueueRequest(Miniport, Request);
  2744. }
  2745. //
  2746. // Now build media dependant requests.
  2747. //
  2748. switch (Miniport->MediaType)
  2749. {
  2750. case NdisMedium802_3:
  2751. ///
  2752. // For ethernet we need to restore the multicast address list.
  2753. ///
  2754. //
  2755. // Get a list of all the multicast address that need
  2756. // to be set.
  2757. //
  2758. NumberOfAddresses = ethNumberOfGlobalAddresses(Miniport->EthDB);
  2759. //
  2760. // Allocate a request to restore the multicast address list.
  2761. //
  2762. Status = ndisMAllocateRequest(&Request,
  2763. OID_802_3_MULTICAST_LIST,
  2764. NULL,
  2765. NumberOfAddresses * ETH_LENGTH_OF_ADDRESS);
  2766. if (Status != NDIS_STATUS_SUCCESS)
  2767. {
  2768. break;
  2769. }
  2770. EthQueryGlobalFilterAddresses(&Status,
  2771. Miniport->EthDB,
  2772. NumberOfAddresses * ETH_LENGTH_OF_ADDRESS,
  2773. &NumberOfAddresses,
  2774. (PVOID)(Request + 1));
  2775. //
  2776. // Does the internal request have an open associated with it?
  2777. //
  2778. SET_INTERNAL_REQUEST(Request, Open, REQST_FREE_REQUEST);
  2779. LastRequest = Request;
  2780. ndisMQueueRequest(Miniport, Request);
  2781. break;
  2782. case NdisMedium802_5:
  2783. ///
  2784. // For token ring we need to restore the functional address
  2785. // and the group address.
  2786. ///
  2787. //
  2788. // Get the current functional address from the filter
  2789. // library.
  2790. //
  2791. FunctionalAddress = BYTE_SWAP_ULONG(TR_QUERY_FILTER_ADDRESSES(Miniport->TrDB));
  2792. //
  2793. // Allocate a request to restore the functional address.
  2794. //
  2795. Status = ndisMAllocateRequest(&Request,
  2796. OID_802_5_CURRENT_FUNCTIONAL,
  2797. &FunctionalAddress,
  2798. sizeof(FunctionalAddress));
  2799. if (Status != NDIS_STATUS_SUCCESS)
  2800. {
  2801. break;
  2802. }
  2803. //
  2804. // Does the internal request have an open associated with it?
  2805. //
  2806. SET_INTERNAL_REQUEST(Request, Open, REQST_FREE_REQUEST);
  2807. LastRequest = Request;
  2808. ndisMQueueRequest(Miniport, Request);
  2809. //
  2810. // Get the current group address from the filter library.
  2811. //
  2812. GroupAddress = BYTE_SWAP_ULONG(TR_QUERY_FILTER_GROUP(Miniport->TrDB));
  2813. //
  2814. // Allocate a request to restore the group address.
  2815. //
  2816. Status = ndisMAllocateRequest(&Request,
  2817. OID_802_5_CURRENT_GROUP,
  2818. &GroupAddress,
  2819. sizeof(GroupAddress));
  2820. if (Status != NDIS_STATUS_SUCCESS)
  2821. {
  2822. break;
  2823. }
  2824. //
  2825. // Does the internal request have an open associated with it?
  2826. //
  2827. SET_INTERNAL_REQUEST(Request, Open, REQST_FREE_REQUEST);
  2828. LastRequest = Request;
  2829. ndisMQueueRequest(Miniport, Request);
  2830. break;
  2831. case NdisMediumFddi:
  2832. //
  2833. // For FDDI we need to restore the long multicast address
  2834. // list and the short multicast address list.
  2835. //
  2836. //
  2837. // Get the number of multicast addresses and the list
  2838. // of multicast addresses to send to the miniport driver.
  2839. //
  2840. NumberOfAddresses = fddiNumberOfLongGlobalAddresses(Miniport->FddiDB);
  2841. //
  2842. // Allocate a request to restore the long multicast address list.
  2843. //
  2844. Status = ndisMAllocateRequest(&Request,
  2845. OID_FDDI_LONG_MULTICAST_LIST,
  2846. NULL,
  2847. NumberOfAddresses * FDDI_LENGTH_OF_LONG_ADDRESS);
  2848. if (Status != NDIS_STATUS_SUCCESS)
  2849. {
  2850. break;
  2851. }
  2852. FddiQueryGlobalFilterLongAddresses(&Status,
  2853. Miniport->FddiDB,
  2854. NumberOfAddresses * FDDI_LENGTH_OF_LONG_ADDRESS,
  2855. &NumberOfAddresses,
  2856. (PVOID)(Request + 1));
  2857. //
  2858. // Does the internal request have an open associated with it?
  2859. //
  2860. SET_INTERNAL_REQUEST(Request, Open, REQST_FREE_REQUEST);
  2861. LastRequest = Request;
  2862. ndisMQueueRequest(Miniport, Request);
  2863. //
  2864. // Get the number of multicast addresses and the list
  2865. // of multicast addresses to send to the miniport driver.
  2866. //
  2867. NumberOfAddresses = fddiNumberOfShortGlobalAddresses(Miniport->FddiDB);
  2868. //
  2869. // Allocate a request to restore the short multicast address list.
  2870. //
  2871. if (FDDI_FILTER_SUPPORTS_SHORT_ADDR(Miniport->FddiDB))
  2872. {
  2873. Status = ndisMAllocateRequest(&Request,
  2874. OID_FDDI_SHORT_MULTICAST_LIST,
  2875. NULL,
  2876. NumberOfAddresses * FDDI_LENGTH_OF_SHORT_ADDRESS);
  2877. if (Status != NDIS_STATUS_SUCCESS)
  2878. {
  2879. break;
  2880. }
  2881. FddiQueryGlobalFilterShortAddresses(&Status,
  2882. Miniport->FddiDB,
  2883. NumberOfAddresses * FDDI_LENGTH_OF_SHORT_ADDRESS,
  2884. &NumberOfAddresses,
  2885. (PVOID)(Request + 1));
  2886. //
  2887. // Does the internal request have an open associated with it?
  2888. //
  2889. SET_INTERNAL_REQUEST(Request, Open, REQST_FREE_REQUEST);
  2890. LastRequest = Request;
  2891. ndisMQueueRequest(Miniport, Request);
  2892. }
  2893. break;
  2894. #if ARCNET
  2895. case NdisMediumArcnet878_2:
  2896. //
  2897. // Only the packet filter is restored for arcnet and
  2898. // that was done above.
  2899. //
  2900. Status = NDIS_STATUS_SUCCESS;
  2901. break;
  2902. #endif
  2903. }
  2904. if (NDIS_STATUS_SUCCESS != Status)
  2905. {
  2906. break;
  2907. }
  2908. //
  2909. // Do we need to update the miniports enabled wake-up states?
  2910. // Or remove any packet patterns?
  2911. //
  2912. {
  2913. PNDIS_OPEN_BLOCK tmpOpen;
  2914. ULONG newWakeUpEnable;
  2915. PSINGLE_LIST_ENTRY Link;
  2916. PNDIS_PACKET_PATTERN_ENTRY pPatternEntry;
  2917. //
  2918. // preserve the state of NDIS_PNP_WAKE_UP_MAGIC_PACKET and NDIS_PNP_WAKE_UP_LINK_CHANGE flag
  2919. //
  2920. newWakeUpEnable = Miniport->WakeUpEnable & (NDIS_PNP_WAKE_UP_MAGIC_PACKET | NDIS_PNP_WAKE_UP_LINK_CHANGE);
  2921. //
  2922. // If we are restoring the filter settings for a NdisCloseAdapter and not a reset
  2923. // then we need to remove the packet patterns that were added by the open.
  2924. //
  2925. if (!fReset && (Open != NULL))
  2926. {
  2927. //
  2928. // Find any packet patterns that were added for the open.
  2929. // Build and queue a request to remove these.
  2930. //
  2931. for (Link = Miniport->PatternList.Next;
  2932. Link != NULL;
  2933. Link = Link->Next)
  2934. {
  2935. //
  2936. // Get a pointer to the pattern entry.
  2937. //
  2938. pPatternEntry = CONTAINING_RECORD(Link,
  2939. NDIS_PACKET_PATTERN_ENTRY,
  2940. Link);
  2941. //
  2942. // Does this pattern belong to the open?
  2943. //
  2944. if (pPatternEntry->Open == Open)
  2945. {
  2946. //
  2947. // Build a request to remove it.
  2948. //
  2949. Status = ndisMAllocateRequest(&Request,
  2950. OID_PNP_REMOVE_WAKE_UP_PATTERN,
  2951. &pPatternEntry->Pattern,
  2952. sizeof(NDIS_PM_PACKET_PATTERN) +
  2953. pPatternEntry->Pattern.MaskSize +
  2954. pPatternEntry->Pattern.PatternSize);
  2955. if (NDIS_STATUS_SUCCESS != Status)
  2956. {
  2957. break;
  2958. }
  2959. SET_INTERNAL_REQUEST(Request, Open, REQST_FREE_REQUEST);
  2960. ndisMQueueRequest(Miniport, Request);
  2961. }
  2962. }
  2963. }
  2964. else
  2965. {
  2966. //
  2967. // This routine was called for a reset. Walk the open queue and
  2968. // re-add the packet patterns.
  2969. //
  2970. //
  2971. // Find any packet patterns that were added for the open.
  2972. // Build and queue a request to remove these.
  2973. //
  2974. for (Link = Miniport->PatternList.Next;
  2975. Link != NULL;
  2976. Link = Link->Next)
  2977. {
  2978. //
  2979. // Get a pointer to the pattern entry.
  2980. //
  2981. pPatternEntry = CONTAINING_RECORD(
  2982. Link,
  2983. NDIS_PACKET_PATTERN_ENTRY,
  2984. Link);
  2985. //
  2986. // Build a request to remove it.
  2987. //
  2988. Status = ndisMAllocateRequest(&Request,
  2989. OID_PNP_ADD_WAKE_UP_PATTERN,
  2990. &pPatternEntry->Pattern,
  2991. sizeof(NDIS_PM_PACKET_PATTERN) +
  2992. pPatternEntry->Pattern.MaskSize +
  2993. pPatternEntry->Pattern.PatternSize);
  2994. if (NDIS_STATUS_SUCCESS != Status)
  2995. {
  2996. break;
  2997. }
  2998. SET_INTERNAL_REQUEST(Request, Open, REQST_FREE_REQUEST);
  2999. LastRequest = Request;
  3000. ndisMQueueRequest(Miniport, Request);
  3001. }
  3002. }
  3003. if (NDIS_STATUS_SUCCESS != Status)
  3004. {
  3005. break;
  3006. }
  3007. //
  3008. // Determine the wake-up enable bits.
  3009. //
  3010. for (tmpOpen = Miniport->OpenQueue;
  3011. tmpOpen != NULL;
  3012. tmpOpen = tmpOpen->MiniportNextOpen)
  3013. {
  3014. //
  3015. // If the Open is being closed then we don't want to include
  3016. // it's wake-up bits. If the adapter is being reset then
  3017. // Open will be NULL and we will get all of the open's wake-up
  3018. // bits.
  3019. //
  3020. if (Open != tmpOpen)
  3021. {
  3022. newWakeUpEnable |= tmpOpen->WakeUpEnable;
  3023. }
  3024. }
  3025. //
  3026. // Is this different that what is currently set on the adapter?
  3027. //
  3028. if (newWakeUpEnable != Miniport->WakeUpEnable)
  3029. {
  3030. //
  3031. // Allocate a request and queue it up!
  3032. //
  3033. Status = ndisMAllocateRequest(&Request,
  3034. OID_PNP_ENABLE_WAKE_UP,
  3035. &newWakeUpEnable,
  3036. sizeof(newWakeUpEnable));
  3037. if (NDIS_STATUS_SUCCESS != Status)
  3038. {
  3039. break;
  3040. }
  3041. //
  3042. // Does the internal request have an open associated with it?
  3043. //
  3044. SET_INTERNAL_REQUEST(Request, Open, REQST_FREE_REQUEST);
  3045. LastRequest = Request;
  3046. ndisMQueueRequest(Miniport, Request);
  3047. }
  3048. }
  3049. } while (FALSE);
  3050. //
  3051. // Mark the last request that was queued as the last request needed to restore the filter.
  3052. //
  3053. if (fReset && (LastRequest != NULL))
  3054. {
  3055. PNDIS_RESERVED_FROM_PNDIS_REQUEST(LastRequest)->Flags |= REQST_LAST_RESTORE;
  3056. MINIPORT_SET_FLAG(Miniport, fMINIPORT_RESTORING_FILTERS);
  3057. }
  3058. if (NULL != Miniport->PendingRequest)
  3059. {
  3060. NDISM_QUEUE_WORK_ITEM(Miniport, NdisWorkItemRequest, NULL);
  3061. }
  3062. }
  3063. VOID
  3064. ndisMPollMediaState(
  3065. IN PNDIS_MINIPORT_BLOCK Miniport
  3066. )
  3067. /*++
  3068. Routine Description:
  3069. Polls the media connect state for miniports that need to be polled.
  3070. Arguments:
  3071. Miniport Pointer to the miniport block
  3072. Return Value:
  3073. None.
  3074. Comments:
  3075. called at DPC with Miniport's SpinLock held.
  3076. --*/
  3077. {
  3078. PNDIS_REQUEST_RESERVED ReqRsvd;
  3079. ASSERT(Miniport->MediaRequest != NULL);
  3080. //
  3081. // Make sure the previously queued internal request is complete
  3082. //
  3083. ReqRsvd = PNDIS_RESERVED_FROM_PNDIS_REQUEST(Miniport->MediaRequest);
  3084. if ((ReqRsvd->Flags & REQST_COMPLETED) &&
  3085. (Miniport->PnPDeviceState == NdisPnPDeviceStarted))
  3086. {
  3087. SET_INTERNAL_REQUEST_NULL_OPEN(Miniport->MediaRequest, 0);
  3088. ndisMQueueRequest(Miniport, Miniport->MediaRequest);
  3089. if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_DESERIALIZE))
  3090. {
  3091. ndisMDoRequests(Miniport);
  3092. }
  3093. else
  3094. {
  3095. NDISM_QUEUE_WORK_ITEM(Miniport, NdisWorkItemRequest, NULL);
  3096. }
  3097. }
  3098. }
  3099. BOOLEAN
  3100. FASTCALL
  3101. ndisMQueueRequest(
  3102. IN PNDIS_MINIPORT_BLOCK Miniport,
  3103. IN PNDIS_REQUEST Request
  3104. )
  3105. /*++
  3106. Routine Description:
  3107. checks to make sure the request is not already queued on miniport
  3108. and if it is not, it queues the request on miniport's PendingRequest queue.
  3109. Arguments:
  3110. Miniport
  3111. Request
  3112. Return Value:
  3113. TRUE if the request was successfully queued on the miniport
  3114. FALSE is the request is already queued.
  3115. Comments:
  3116. called at DPC with Miniport's SpinLock held.
  3117. --*/
  3118. {
  3119. PNDIS_REQUEST *ppReq;
  3120. BOOLEAN rc;
  3121. PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Next = NULL;
  3122. for (ppReq = &Miniport->PendingRequest;
  3123. *ppReq != NULL;
  3124. NOTHING)
  3125. {
  3126. ASSERT (*ppReq != Request);
  3127. if (*ppReq == Request)
  3128. {
  3129. break;
  3130. }
  3131. ppReq = &(PNDIS_RESERVED_FROM_PNDIS_REQUEST(*ppReq))->Next;
  3132. }
  3133. if (*ppReq != Request)
  3134. {
  3135. *ppReq = Request;
  3136. rc = TRUE;
  3137. }
  3138. else
  3139. {
  3140. rc = FALSE;
  3141. }
  3142. return(rc);
  3143. }
  3144. NDIS_STATUS
  3145. ndisMAllocateRequest(
  3146. OUT PNDIS_REQUEST * pRequest,
  3147. IN NDIS_OID Oid,
  3148. IN PVOID Buffer OPTIONAL,
  3149. IN ULONG BufferLength
  3150. )
  3151. /*++
  3152. Routine Description:
  3153. This routine will allocate a request to be used as an internal request.
  3154. Arguments:
  3155. Request - Will contain a pointer to the new request on exit.
  3156. RequestType - Type of ndis request.
  3157. Oid - Request identifier.
  3158. Buffer - Pointer to the buffer for the request.
  3159. BufferLength- Length of the buffer.
  3160. Return Value:
  3161. NDIS_STATUS_SUCCESS if the request allocation succeeded.
  3162. NDIS_STATUS_FAILURE otherwise.
  3163. --*/
  3164. {
  3165. PNDIS_REQUEST Request;
  3166. //
  3167. // Allocate the request structure.
  3168. //
  3169. Request = (PNDIS_REQUEST)ALLOC_FROM_POOL(sizeof(NDIS_REQUEST) + BufferLength,
  3170. NDIS_TAG_Q_REQ);
  3171. if (NULL == Request)
  3172. {
  3173. *pRequest = NULL;
  3174. return(NDIS_STATUS_RESOURCES);
  3175. }
  3176. //
  3177. // Zero out the request.
  3178. //
  3179. ZeroMemory(Request, sizeof(NDIS_REQUEST) + BufferLength);
  3180. INITIALIZE_EVENT(&(PNDIS_COREQ_RESERVED_FROM_REQUEST(Request)->Event));
  3181. Request->RequestType = NdisRequestSetInformation;
  3182. //
  3183. // Copy the buffer that was passed to us into the new buffer.
  3184. //
  3185. Request->DATA.SET_INFORMATION.Oid = Oid;
  3186. Request->DATA.SET_INFORMATION.InformationBuffer = Request + 1;
  3187. Request->DATA.SET_INFORMATION.InformationBufferLength = BufferLength;
  3188. if (Buffer != NULL)
  3189. {
  3190. MoveMemory(Request + 1, Buffer, BufferLength);
  3191. }
  3192. //
  3193. // Give it back to the caller.
  3194. //
  3195. *pRequest = Request;
  3196. return(NDIS_STATUS_SUCCESS);
  3197. }
  3198. NDIS_STATUS
  3199. FASTCALL
  3200. ndisMDispatchRequest(
  3201. IN PNDIS_MINIPORT_BLOCK Miniport,
  3202. IN PNDIS_REQUEST Request,
  3203. IN BOOLEAN fQuery
  3204. )
  3205. /*++
  3206. Routine Description:
  3207. all requests directed to drivers go through this function. except those made
  3208. to NdisCoRequest.
  3209. Arguments:
  3210. Return Value:
  3211. Note:
  3212. Called at DPC with Miniport's lock held.
  3213. --*/
  3214. {
  3215. PNDIS_OPEN_BLOCK Open;
  3216. NDIS_STATUS Status;
  3217. KIRQL OldIrql;
  3218. do
  3219. {
  3220. //
  3221. // for deserialized drivers, if the device has been handed a reset and the reset call
  3222. // has not come back or completed, then abort this request
  3223. //
  3224. if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_DESERIALIZE))
  3225. {
  3226. if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_CALLING_RESET))
  3227. {
  3228. Status = NDIS_STATUS_RESET_IN_PROGRESS;
  3229. break;
  3230. }
  3231. }
  3232. //
  3233. // if the device is sleep or about to sleep, block all user mode requests except the power ones
  3234. //
  3235. if ((Request->RequestType == NdisRequestQueryStatistics) &&
  3236. ((MINIPORT_PNP_TEST_FLAG(Miniport, fMINIPORT_SYSTEM_SLEEPING)) ||
  3237. (Miniport->CurrentDevicePowerState > PowerDeviceD0)))
  3238. {
  3239. Status = STATUS_DEVICE_POWERED_OFF;
  3240. break;
  3241. }
  3242. if ((MINIPORT_PNP_TEST_FLAG(Miniport, fMINIPORT_DEVICE_FAILED | fMINIPORT_REJECT_REQUESTS)) ||
  3243. ((Miniport->CurrentDevicePowerState > PowerDeviceD0) && (Request->DATA.SET_INFORMATION.Oid != OID_PNP_SET_POWER)))
  3244. {
  3245. Status = fQuery ? NDIS_STATUS_FAILURE : NDIS_STATUS_SUCCESS;
  3246. break;
  3247. }
  3248. //
  3249. // Satisfy this request right away
  3250. //
  3251. if ((Request->RequestType == NdisRequestSetInformation) &&
  3252. (Request->DATA.QUERY_INFORMATION.Oid == OID_GEN_INIT_TIME_MS))
  3253. {
  3254. PULONG InitTime = (PULONG)(Request->DATA.SET_INFORMATION.InformationBuffer);
  3255. *InitTime = Miniport->InitTimeMs;
  3256. Request->DATA.QUERY_INFORMATION.BytesWritten = sizeof(ULONG);
  3257. Request->DATA.QUERY_INFORMATION.BytesNeeded = sizeof(ULONG);
  3258. Status = NDIS_STATUS_SUCCESS;
  3259. break;
  3260. }
  3261. //
  3262. // If this was a request to turn p-mode/l-only on/off then mark things appropriately
  3263. // This should be moved to completion handler for this OID
  3264. //
  3265. if ((Request->RequestType == NdisRequestSetInformation) &&
  3266. (Request->DATA.SET_INFORMATION.Oid == OID_GEN_CURRENT_PACKET_FILTER))
  3267. {
  3268. PULONG Filter = (PULONG)(Request->DATA.SET_INFORMATION.InformationBuffer);
  3269. if ((Open = PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open) != NULL)
  3270. {
  3271. if (*Filter & (NDIS_PACKET_TYPE_PROMISCUOUS | NDIS_PACKET_TYPE_ALL_LOCAL))
  3272. {
  3273. if ((Open->Flags & fMINIPORT_OPEN_PMODE) == 0)
  3274. {
  3275. Open->Flags |= fMINIPORT_OPEN_PMODE;
  3276. Miniport->PmodeOpens ++;
  3277. NDIS_CHECK_PMODE_OPEN_REF(Miniport);
  3278. ndisUpdateCheckForLoopbackFlag(Miniport);
  3279. }
  3280. }
  3281. else
  3282. {
  3283. if (Open->Flags & fMINIPORT_OPEN_PMODE)
  3284. {
  3285. Open->Flags &= ~fMINIPORT_OPEN_PMODE;
  3286. Miniport->PmodeOpens --;
  3287. NDIS_CHECK_PMODE_OPEN_REF(Miniport);
  3288. ndisUpdateCheckForLoopbackFlag(Miniport);
  3289. }
  3290. }
  3291. }
  3292. //
  3293. // Remove the ALL_LOCAL bit since miniport does not understand this (and does
  3294. // not need to).
  3295. //
  3296. *Filter &= ~NDIS_PACKET_TYPE_ALL_LOCAL;
  3297. }
  3298. if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_DESERIALIZE))
  3299. {
  3300. Miniport->RequestCount++;
  3301. }
  3302. NDIS_RELEASE_MINIPORT_SPIN_LOCK_DPC(Miniport);
  3303. //
  3304. // check to see if we need the get the protocol mutex
  3305. if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_IS_CO))
  3306. {
  3307. PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Flags |= REQST_DOWNLEVEL;
  3308. Status = (Miniport)->DriverHandle->MiniportCharacteristics.CoRequestHandler(
  3309. (Miniport)->MiniportAdapterContext,
  3310. NULL,
  3311. (Request));
  3312. }
  3313. else
  3314. {
  3315. if (fQuery)
  3316. {
  3317. Status = (Miniport->DriverHandle->MiniportCharacteristics.QueryInformationHandler)(
  3318. Miniport->MiniportAdapterContext,
  3319. Request->DATA.QUERY_INFORMATION.Oid,
  3320. Request->DATA.QUERY_INFORMATION.InformationBuffer,
  3321. Request->DATA.QUERY_INFORMATION.InformationBufferLength,
  3322. &Request->DATA.QUERY_INFORMATION.BytesWritten,
  3323. &Request->DATA.QUERY_INFORMATION.BytesNeeded);
  3324. }
  3325. else
  3326. {
  3327. Status = (Miniport->DriverHandle->MiniportCharacteristics.SetInformationHandler)(
  3328. Miniport->MiniportAdapterContext,
  3329. Request->DATA.SET_INFORMATION.Oid,
  3330. Request->DATA.SET_INFORMATION.InformationBuffer,
  3331. Request->DATA.SET_INFORMATION.InformationBufferLength,
  3332. &Request->DATA.SET_INFORMATION.BytesRead,
  3333. &Request->DATA.SET_INFORMATION.BytesNeeded);
  3334. }
  3335. }
  3336. NDIS_ACQUIRE_MINIPORT_SPIN_LOCK_DPC(Miniport);
  3337. if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_DESERIALIZE))
  3338. {
  3339. Miniport->RequestCount--;
  3340. }
  3341. } while (FALSE);
  3342. return(Status);
  3343. }
  3344. NDIS_STATUS
  3345. ndisMFilterOutStatisticsOids(
  3346. IN PNDIS_MINIPORT_BLOCK Miniport,
  3347. IN PNDIS_REQUEST Request
  3348. )
  3349. /*++
  3350. Routine Description:
  3351. This routine will filter out any statistics OIDs.
  3352. Arguments:
  3353. Return Value:
  3354. --*/
  3355. {
  3356. ULONG c;
  3357. PNDIS_OID OidList;
  3358. ULONG TotalOids;
  3359. ULONG CurrentDestOid;
  3360. //
  3361. // Initialize some temp variables.
  3362. //
  3363. OidList = Request->DATA.QUERY_INFORMATION.InformationBuffer;
  3364. TotalOids = Request->DATA.QUERY_INFORMATION.BytesWritten / sizeof(NDIS_OID);
  3365. //
  3366. // Copy the information OIDs to the buffer that
  3367. // was passed with the original request.
  3368. //
  3369. for (c = 0, CurrentDestOid = 0; c < TotalOids; c++)
  3370. {
  3371. //
  3372. // Is this a statistic Oid?
  3373. //
  3374. if ((OidList[c] & 0x00FF0000) != 0x00020000)
  3375. {
  3376. OidList[CurrentDestOid++] = OidList[c];
  3377. }
  3378. }
  3379. #if ARCNET
  3380. //
  3381. // If ARCnet then do the filtering.
  3382. //
  3383. if ((Miniport->MediaType == NdisMediumArcnet878_2) &&
  3384. MINIPORT_TEST_FLAG(
  3385. PNDIS_RESERVED_FROM_PNDIS_REQUEST(Request)->Open,
  3386. fMINIPORT_OPEN_USING_ETH_ENCAPSULATION))
  3387. {
  3388. ArcConvertOidListToEthernet(OidList, &CurrentDestOid);
  3389. }
  3390. #endif
  3391. //
  3392. // Save the amount of data that was kept.
  3393. //
  3394. Request->DATA.QUERY_INFORMATION.BytesWritten = CurrentDestOid * sizeof(NDIS_OID);
  3395. return(NDIS_STATUS_SUCCESS);
  3396. }
  3397. BOOLEAN
  3398. FASTCALL
  3399. ndisMCreateDummyFilters(
  3400. IN PNDIS_MINIPORT_BLOCK Miniport
  3401. )
  3402. /*++
  3403. Routine Description:
  3404. Creates the bogus filter packages during initialization.
  3405. Arguments:
  3406. Miniport - Pointer to the Miniport.
  3407. Return Value:
  3408. None.
  3409. --*/
  3410. {
  3411. UCHAR Address[6];
  3412. if (!EthCreateFilter(1,
  3413. Address,
  3414. &Miniport->EthDB) ||
  3415. !FddiCreateFilter(1,
  3416. 1,
  3417. Address,
  3418. Address,
  3419. &Miniport->FddiDB)||
  3420. #if ARCNET
  3421. !ArcCreateFilter(Miniport,
  3422. Address[0],
  3423. &Miniport->ArcDB) ||
  3424. #endif
  3425. !TrCreateFilter(Address,
  3426. &Miniport->TrDB))
  3427. {
  3428. if (Miniport->EthDB != NULL)
  3429. {
  3430. EthDeleteFilter(Miniport->EthDB);
  3431. Miniport->EthDB = NULL;
  3432. }
  3433. if (Miniport->TrDB != NULL)
  3434. {
  3435. TrDeleteFilter(Miniport->TrDB);
  3436. Miniport->TrDB = NULL;
  3437. }
  3438. if (Miniport->FddiDB != NULL)
  3439. {
  3440. FddiDeleteFilter(Miniport->FddiDB);
  3441. Miniport->FddiDB = NULL;
  3442. }
  3443. #if ARCNET
  3444. if (Miniport->ArcDB != NULL)
  3445. {
  3446. ArcDeleteFilter(Miniport->ArcDB);
  3447. Miniport->ArcDB = NULL;
  3448. }
  3449. #endif
  3450. return(FALSE);
  3451. }
  3452. Miniport->LockHandler = DummyFilterLockHandler;
  3453. Miniport->EthDB->Miniport = Miniport;
  3454. Miniport->FddiDB->Miniport = Miniport;
  3455. Miniport->TrDB->Miniport = Miniport;
  3456. #if ARCNET
  3457. Miniport->ArcDB->Miniport = Miniport;
  3458. #endif
  3459. return(TRUE);
  3460. }
  3461. VOID
  3462. FASTCALL
  3463. ndisMAdjustFilters(
  3464. IN PNDIS_MINIPORT_BLOCK Miniport,
  3465. IN PFILTERDBS FilterDB
  3466. )
  3467. /*++
  3468. Routine Description:
  3469. Replace the dummy filters by real ones.
  3470. Arguments:
  3471. Miniport - Pointer to the Miniport.
  3472. FilterDB - New valid filters
  3473. Return Value:
  3474. None.
  3475. --*/
  3476. {
  3477. ASSERT(Miniport->EthDB == NULL);
  3478. ASSERT(Miniport->TrDB == NULL);
  3479. ASSERT(Miniport->FddiDB == NULL);
  3480. #if ARCNET
  3481. ASSERT(Miniport->ArcDB == NULL);
  3482. #endif
  3483. Miniport->EthDB = FilterDB->EthDB;
  3484. Miniport->TrDB = FilterDB->TrDB;
  3485. Miniport->FddiDB = FilterDB->FddiDB;
  3486. #if ARCNET
  3487. Miniport->ArcDB = FilterDB->ArcDB;
  3488. #endif
  3489. }
  3490. VOID
  3491. ndisMNotifyMachineName(
  3492. IN PNDIS_MINIPORT_BLOCK Miniport,
  3493. IN PNDIS_STRING MachineName OPTIONAL
  3494. )
  3495. /*++
  3496. Routine Description:
  3497. Send an OID_GEN_MACHINE_NAME to notify the miniport of this machine's name.
  3498. If MachineName is supplied to this routine, use it. Otherwise, read it from
  3499. the registry.
  3500. Arguments:
  3501. Miniport - Pointer to the Miniport.
  3502. MachineName - if specified, the name to be sent to the miniport.
  3503. Return Value:
  3504. None.
  3505. --*/
  3506. {
  3507. NDIS_STRING RequestMachineName;
  3508. NDIS_STRING HostNameKey;
  3509. NTSTATUS NtStatus;
  3510. LONG ErrorCode;
  3511. RTL_QUERY_REGISTRY_TABLE QueryTable[2];
  3512. PUCHAR HostNameBuffer;
  3513. HostNameKey.Buffer = NULL;
  3514. HostNameBuffer = NULL;
  3515. do
  3516. {
  3517. if (MachineName == NULL)
  3518. {
  3519. ZeroMemory(QueryTable, sizeof(QueryTable));
  3520. ZeroMemory(&HostNameKey, sizeof(HostNameKey));
  3521. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT|
  3522. RTL_QUERY_REGISTRY_REQUIRED;
  3523. QueryTable[0].Name = L"HostName";
  3524. QueryTable[0].EntryContext = &HostNameKey;
  3525. QueryTable[0].DefaultType = REG_NONE;
  3526. QueryTable[1].Name = NULL;
  3527. NtStatus = RtlQueryRegistryValues(
  3528. RTL_REGISTRY_SERVICES,
  3529. L"\\Tcpip\\Parameters",
  3530. &QueryTable[0],
  3531. NULL, // Context
  3532. NULL // Environment
  3533. );
  3534. if (!NT_SUCCESS(NtStatus))
  3535. {
  3536. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_ERR,
  3537. ("ndisMNotifyMachineName: Miniport %p, registry query for %ws failed, Status %x\n",
  3538. Miniport, QueryTable[0].Name, NtStatus));
  3539. break;
  3540. }
  3541. }
  3542. else
  3543. {
  3544. HostNameKey = *MachineName;
  3545. }
  3546. ASSERT(HostNameKey.MaximumLength >= HostNameKey.Length);
  3547. //
  3548. // Copy the name into non-paged memory since the OID
  3549. // will be sent to the miniport at raised IRQL.
  3550. //
  3551. HostNameBuffer = ALLOC_FROM_POOL(HostNameKey.MaximumLength, NDIS_TAG_NAME_BUF);
  3552. if (HostNameBuffer == NULL)
  3553. {
  3554. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_ERR,
  3555. ("ndisMNotifyMachineName: Miniport %p, failed to alloc %d bytes\n",
  3556. Miniport, HostNameKey.MaximumLength));
  3557. break;
  3558. }
  3559. ZeroMemory(HostNameBuffer, HostNameKey.MaximumLength);
  3560. NdisMoveMemory(HostNameBuffer, HostNameKey.Buffer, HostNameKey.Length);
  3561. ErrorCode = ndisMDoMiniportOp(Miniport,
  3562. FALSE,
  3563. OID_GEN_MACHINE_NAME,
  3564. HostNameBuffer,
  3565. HostNameKey.Length,
  3566. 0x77,
  3567. FALSE);
  3568. }
  3569. while (FALSE);
  3570. if (MachineName == NULL)
  3571. {
  3572. if (HostNameKey.Buffer != NULL)
  3573. {
  3574. ExFreePool(HostNameKey.Buffer);
  3575. }
  3576. }
  3577. if (HostNameBuffer != NULL)
  3578. {
  3579. FREE_POOL(HostNameBuffer);
  3580. }
  3581. }
  3582. VOID
  3583. ndisUpdateCheckForLoopbackFlag(
  3584. IN PNDIS_MINIPORT_BLOCK Miniport
  3585. )
  3586. {
  3587. if (Miniport->EthDB && Miniport->EthDB->SingleActiveOpen)
  3588. {
  3589. MINIPORT_CLEAR_FLAG(Miniport, fMINIPORT_CHECK_FOR_LOOPBACK);
  3590. }
  3591. else
  3592. {
  3593. if ((Miniport->PmodeOpens > 0) && (Miniport->NumOpens > 1))
  3594. {
  3595. MINIPORT_SET_FLAG(Miniport, fMINIPORT_CHECK_FOR_LOOPBACK);
  3596. }
  3597. else
  3598. {
  3599. MINIPORT_CLEAR_FLAG(Miniport, fMINIPORT_CHECK_FOR_LOOPBACK);
  3600. }
  3601. }
  3602. }