Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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