2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS library
4 * FILE: ndis/miniport.c
5 * PURPOSE: Routines used by NDIS miniport drivers
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Vizzini (vizzini@plasmic.com)
9 * CSH 01/08-2000 Created
10 * 20 Aug 2003 vizzini - DMA support
11 * 3 Oct 2003 vizzini - SendPackets support
19 * Define to 1 to get a debugger breakpoint at the end of NdisInitializeWrapper
20 * for each new miniport starting up
22 #define BREAK_ON_MINIPORT_INIT 0
25 * This has to be big enough to hold the results of querying the Route value
26 * from the Linkage key. Please re-code me to determine this dynamically.
28 #define ROUTE_DATA_SIZE 256
30 /* Number of media we know */
31 #define MEDIA_ARRAY_SIZE 15
33 static NDIS_MEDIUM MediaArray
[MEDIA_ARRAY_SIZE
] =
42 NdisMediumArcnet878_2
,
44 NdisMediumWirelessWan
,
52 /* global list and lock of Miniports NDIS has registered */
53 LIST_ENTRY MiniportListHead
;
54 KSPIN_LOCK MiniportListLock
;
56 /* global list and lock of adapters NDIS has registered */
57 LIST_ENTRY AdapterListHead
;
58 KSPIN_LOCK AdapterListLock
;
67 if ((DebugTraceLevel
& DEBUG_PACKET
) > 0) {
68 Length
= CopyPacketToBuffer(
74 DbgPrint("*** PACKET START ***");
76 for (i
= 0; i
< Length
; i
++) {
78 DbgPrint("\n%04X ", i
);
79 DbgPrint("%02X ", Buffer
[i
]);
82 DbgPrint("*** PACKET STOP ***\n");
90 UINT HeaderBufferSize
,
91 PVOID LookaheadBuffer
,
92 UINT LookaheadBufferSize
)
95 if ((DebugTraceLevel
& DEBUG_PACKET
) > 0) {
99 DbgPrint("*** RECEIVE PACKET START ***\n");
102 for (i
= 0; i
< HeaderBufferSize
; i
++) {
104 DbgPrint("\n%04X ", i
);
105 DbgPrint("%02X ", *p
++);
108 DbgPrint("\nFRAME:");
111 Length
= (LookaheadBufferSize
< 64)? LookaheadBufferSize
: 64;
112 for (i
= 0; i
< Length
; i
++) {
114 DbgPrint("\n%04X ", i
);
115 DbgPrint("%02X ", *p
++);
118 DbgPrint("\n*** RECEIVE PACKET STOP ***\n");
123 PNDIS_MINIPORT_WORK_ITEM
124 MiniGetFirstWorkItem(
125 PLOGICAL_ADAPTER Adapter
,
126 NDIS_WORK_ITEM_TYPE Type
)
128 PNDIS_MINIPORT_WORK_ITEM CurrentEntry
= Adapter
->WorkQueueHead
;
132 if (CurrentEntry
->WorkItemType
== Type
|| Type
== NdisMaxWorkItems
)
135 CurrentEntry
= (PNDIS_MINIPORT_WORK_ITEM
)CurrentEntry
->Link
.Next
;
143 PLOGICAL_ADAPTER Adapter
,
144 NDIS_WORK_ITEM_TYPE Type
)
146 BOOLEAN Busy
= FALSE
;
149 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
151 if (MiniGetFirstWorkItem(Adapter
, Type
))
155 else if (Type
== NdisWorkItemRequest
&& Adapter
->NdisMiniportBlock
.PendingRequest
)
159 else if (Type
== NdisWorkItemSend
&& Adapter
->NdisMiniportBlock
.FirstPendingPacket
)
163 else if (Type
== NdisWorkItemResetRequested
&&
164 Adapter
->NdisMiniportBlock
.ResetStatus
== NDIS_STATUS_PENDING
)
169 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
176 PLOGICAL_ADAPTER Adapter
,
177 NDIS_HANDLE MacReceiveContext
,
179 UINT HeaderBufferSize
,
180 PVOID LookaheadBuffer
,
181 UINT LookaheadBufferSize
,
184 * FUNCTION: Indicate received data to bound protocols
186 * Adapter = Pointer to logical adapter
187 * MacReceiveContext = MAC receive context handle
188 * HeaderBuffer = Pointer to header buffer
189 * HeaderBufferSize = Size of header buffer
190 * LookaheadBuffer = Pointer to lookahead buffer
191 * LookaheadBufferSize = Size of lookahead buffer
192 * PacketSize = Total size of received packet
196 PLIST_ENTRY CurrentEntry
;
197 PADAPTER_BINDING AdapterBinding
;
199 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called. Adapter (0x%X) HeaderBuffer (0x%X) "
200 "HeaderBufferSize (0x%X) LookaheadBuffer (0x%X) LookaheadBufferSize (0x%X).\n",
201 Adapter
, HeaderBuffer
, HeaderBufferSize
, LookaheadBuffer
, LookaheadBufferSize
));
203 MiniDisplayPacket2(HeaderBuffer
, HeaderBufferSize
, LookaheadBuffer
, LookaheadBufferSize
);
205 NDIS_DbgPrint(MAX_TRACE
, ("acquiring miniport block lock\n"));
206 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
208 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
209 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurrentEntry = %x\n", CurrentEntry
));
211 if (CurrentEntry
== &Adapter
->ProtocolListHead
)
213 NDIS_DbgPrint(MIN_TRACE
, ("WARNING: No upper protocol layer.\n"));
216 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
218 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
219 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterBinding = %x\n", AdapterBinding
));
223 ("XXX (%x) %x %x %x %x %x %x %x XXX\n",
224 *AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
,
225 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
233 /* call the receive handler */
234 (*AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
)(
235 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
243 CurrentEntry
= CurrentEntry
->Flink
;
246 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
248 NDIS_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
257 IN PNDIS_PACKET
*PacketsToReturn
,
258 IN UINT NumberOfPackets
)
260 * FUNCTION: Releases ownership of one or more packets
262 * PacketsToReturn = Pointer to an array of pointers to packet descriptors
263 * NumberOfPackets = Number of pointers in descriptor pointer array
267 PLOGICAL_ADAPTER Adapter
;
270 NDIS_DbgPrint(MID_TRACE
, ("Returning %d packets\n", NumberOfPackets
));
272 for (i
= 0; i
< NumberOfPackets
; i
++)
274 PacketsToReturn
[i
]->WrapperReserved
[0]--;
275 if (PacketsToReturn
[i
]->WrapperReserved
[0] == 0)
277 Adapter
= (PVOID
)(ULONG_PTR
)PacketsToReturn
[i
]->Reserved
[1];
279 NDIS_DbgPrint(MAX_TRACE
, ("Freeing packet %d (adapter = 0x%p)\n", i
, Adapter
));
281 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
282 Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ReturnPacketHandler(
283 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
285 KeLowerIrql(OldIrql
);
291 MiniIndicateReceivePacket(
292 IN NDIS_HANDLE MiniportAdapterHandle
,
293 IN PPNDIS_PACKET PacketArray
,
294 IN UINT NumberOfPackets
)
296 * FUNCTION: receives miniport packet array indications
298 * MiniportAdapterHandle: Miniport handle for the adapter
299 * PacketArray: pointer to a list of packet pointers to indicate
300 * NumberOfPackets: number of packets to indicate
304 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
305 PLIST_ENTRY CurrentEntry
;
306 PADAPTER_BINDING AdapterBinding
;
310 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
312 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
314 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
316 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
318 for (i
= 0; i
< NumberOfPackets
; i
++)
320 /* Store the indicating miniport in the packet */
321 PacketArray
[i
]->Reserved
[1] = (ULONG_PTR
)Adapter
;
323 if (AdapterBinding
->ProtocolBinding
->Chars
.ReceivePacketHandler
&&
324 NDIS_GET_PACKET_STATUS(PacketArray
[i
]) != NDIS_STATUS_RESOURCES
)
326 NDIS_DbgPrint(MID_TRACE
, ("Indicating packet to protocol's ReceivePacket handler\n"));
327 PacketArray
[i
]->WrapperReserved
[0] += (*AdapterBinding
->ProtocolBinding
->Chars
.ReceivePacketHandler
)(
328 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
330 NDIS_DbgPrint(MID_TRACE
, ("Protocol is holding %d references to the packet\n", PacketArray
[i
]->WrapperReserved
[0]));
334 UINT FirstBufferLength
, TotalBufferLength
, LookAheadSize
, HeaderSize
;
335 PNDIS_BUFFER NdisBuffer
;
336 PVOID NdisBufferVA
, LookAheadBuffer
;
338 NdisGetFirstBufferFromPacket(PacketArray
[i
],
344 HeaderSize
= NDIS_GET_PACKET_HEADER_SIZE(PacketArray
[i
]);
346 LookAheadSize
= TotalBufferLength
- HeaderSize
;
348 LookAheadBuffer
= ExAllocatePool(NonPagedPool
, LookAheadSize
);
349 if (!LookAheadBuffer
)
351 NDIS_DbgPrint(MIN_TRACE
, ("Failed to allocate lookahead buffer!\n"));
352 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
356 CopyBufferChainToBuffer(LookAheadBuffer
,
361 NDIS_DbgPrint(MID_TRACE
, ("Indicating packet to protocol's legacy Receive handler\n"));
362 (*AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
)(
363 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
364 AdapterBinding
->NdisOpenBlock
.MacHandle
,
369 TotalBufferLength
- HeaderSize
);
371 ExFreePool(LookAheadBuffer
);
375 CurrentEntry
= CurrentEntry
->Flink
;
378 /* Loop the packet array to get everything
379 * set up for return the packets to the miniport */
380 for (i
= 0; i
< NumberOfPackets
; i
++)
382 /* First, check the initial packet status */
383 if (NDIS_GET_PACKET_STATUS(PacketArray
[i
]) == NDIS_STATUS_RESOURCES
)
385 /* The miniport driver gets it back immediately so nothing to do here */
386 NDIS_DbgPrint(MID_TRACE
, ("Miniport needs the packet back immediately\n"));
390 /* Different behavior depending on whether it's serialized or not */
391 if (Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
393 /* We need to check the reference count */
394 if (PacketArray
[i
]->WrapperReserved
[0] == 0)
396 /* NOTE: Unlike serialized miniports, this is REQUIRED to be called for each
397 * packet received that can be reused immediately, it is not implied! */
398 Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ReturnPacketHandler(
399 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
401 NDIS_DbgPrint(MID_TRACE
, ("Packet has been returned to miniport (Deserialized)\n"));
405 /* Packet will be returned by the protocol's call to NdisReturnPackets */
406 NDIS_DbgPrint(MID_TRACE
, ("Packet will be returned to miniport later (Deserialized)\n"));
411 /* Check the reference count */
412 if (PacketArray
[i
]->WrapperReserved
[0] == 0)
414 /* NDIS_STATUS_SUCCESS means the miniport can have the packet back immediately */
415 NDIS_SET_PACKET_STATUS(PacketArray
[i
], NDIS_STATUS_SUCCESS
);
417 NDIS_DbgPrint(MID_TRACE
, ("Packet has been returned to miniport (Serialized)\n"));
421 /* NDIS_STATUS_PENDING means the miniport needs to wait for MiniportReturnPacket */
422 NDIS_SET_PACKET_STATUS(PacketArray
[i
], NDIS_STATUS_PENDING
);
424 NDIS_DbgPrint(MID_TRACE
, ("Packet will be returned to miniport later (Serialized)\n"));
429 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
434 IN NDIS_HANDLE MiniportAdapterHandle
,
435 IN NDIS_STATUS Status
,
436 IN BOOLEAN AddressingReset
)
438 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
439 PLIST_ENTRY CurrentEntry
;
440 PADAPTER_BINDING AdapterBinding
;
444 MiniDoAddressingReset(Adapter
);
446 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
447 NdisMIndicateStatusComplete(Adapter
);
449 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
451 if (Adapter
->NdisMiniportBlock
.ResetStatus
!= NDIS_STATUS_PENDING
)
453 KeBugCheckEx(BUGCODE_ID_DRIVER
,
454 (ULONG_PTR
)MiniportAdapterHandle
,
456 (ULONG_PTR
)AddressingReset
,
460 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
462 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
464 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
466 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
468 (*AdapterBinding
->ProtocolBinding
->Chars
.ResetCompleteHandler
)(
469 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
472 CurrentEntry
= CurrentEntry
->Flink
;
475 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
480 IN NDIS_HANDLE MiniportAdapterHandle
,
481 IN NDIS_STATUS Status
)
483 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
484 PNDIS_REQUEST Request
;
485 PNDIS_REQUEST_MAC_BLOCK MacBlock
;
488 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
490 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
492 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
493 Request
= Adapter
->NdisMiniportBlock
.PendingRequest
;
494 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
496 MacBlock
= (PNDIS_REQUEST_MAC_BLOCK
)Request
->MacReserved
;
498 /* We may or may not be doing this request on behalf of an adapter binding */
499 if (MacBlock
->Binding
!= NULL
)
501 /* We are, so invoke its request complete handler */
502 if (MacBlock
->Binding
->RequestCompleteHandler
!= NULL
)
504 (*MacBlock
->Binding
->RequestCompleteHandler
)(
505 MacBlock
->Binding
->ProtocolBindingContext
,
512 /* We are doing this internally, so we'll signal this event we've stashed in the MacBlock */
513 ASSERT(MacBlock
->Unknown1
!= NULL
);
514 ASSERT(MacBlock
->Unknown3
== NULL
);
515 MacBlock
->Unknown3
= (PVOID
)Status
;
516 KeSetEvent(MacBlock
->Unknown1
, IO_NO_INCREMENT
, FALSE
);
519 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
520 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
521 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
522 KeLowerIrql(OldIrql
);
524 MiniWorkItemComplete(Adapter
, NdisWorkItemRequest
);
529 IN NDIS_HANDLE MiniportAdapterHandle
,
530 IN PNDIS_PACKET Packet
,
531 IN NDIS_STATUS Status
)
533 * FUNCTION: Forwards a message to the initiating protocol saying
534 * that a packet was handled
536 * NdisAdapterHandle = Handle input to MiniportInitialize
537 * Packet = Pointer to NDIS packet that was sent
538 * Status = Status of send operation
541 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
542 PADAPTER_BINDING AdapterBinding
;
544 PSCATTER_GATHER_LIST SGList
;
546 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
548 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
550 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
552 if (Adapter
->NdisMiniportBlock
.ScatterGatherListSize
!= 0)
554 NDIS_DbgPrint(MAX_TRACE
, ("Freeing Scatter/Gather list\n"));
556 SGList
= NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
557 ScatterGatherListPacketInfo
);
559 Adapter
->NdisMiniportBlock
.SystemAdapterObject
->
560 DmaOperations
->PutScatterGatherList(
561 Adapter
->NdisMiniportBlock
.SystemAdapterObject
,
565 NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
566 ScatterGatherListPacketInfo
) = NULL
;
569 (*AdapterBinding
->ProtocolBinding
->Chars
.SendCompleteHandler
)(
570 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
574 KeLowerIrql(OldIrql
);
576 MiniWorkItemComplete(Adapter
, NdisWorkItemSend
);
581 MiniSendResourcesAvailable(
582 IN NDIS_HANDLE MiniportAdapterHandle
)
584 /* Run the work if anything is waiting */
585 MiniWorkItemComplete((PLOGICAL_ADAPTER
)MiniportAdapterHandle
, NdisWorkItemSend
);
590 MiniTransferDataComplete(
591 IN NDIS_HANDLE MiniportAdapterHandle
,
592 IN PNDIS_PACKET Packet
,
593 IN NDIS_STATUS Status
,
594 IN UINT BytesTransferred
)
596 PADAPTER_BINDING AdapterBinding
;
599 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
601 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
603 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
604 (*AdapterBinding
->ProtocolBinding
->Chars
.TransferDataCompleteHandler
)(
605 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
609 KeLowerIrql(OldIrql
);
614 MiniAdapterHasAddress(
615 PLOGICAL_ADAPTER Adapter
,
618 * FUNCTION: Determines whether a packet has the same destination address as an adapter
620 * Adapter = Pointer to logical adapter object
621 * Packet = Pointer to NDIS packet
623 * TRUE if the destination address is that of the adapter, FALSE if not
629 PNDIS_BUFFER NdisBuffer
;
632 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
637 NDIS_DbgPrint(MIN_TRACE
, ("Adapter object was null\n"));
643 NDIS_DbgPrint(MIN_TRACE
, ("Packet was null\n"));
648 NdisQueryPacket(Packet
, NULL
, NULL
, &NdisBuffer
, NULL
);
652 NDIS_DbgPrint(MIN_TRACE
, ("Packet contains no buffers.\n"));
656 NdisQueryBuffer(NdisBuffer
, (PVOID
)&Start2
, &BufferLength
);
658 /* FIXME: Should handle fragmented packets */
660 switch (Adapter
->NdisMiniportBlock
.MediaType
)
662 case NdisMedium802_3
:
663 Length
= ETH_LENGTH_OF_ADDRESS
;
664 /* Destination address is the first field */
668 NDIS_DbgPrint(MIN_TRACE
, ("Adapter has unsupported media type (0x%X).\n", Adapter
->NdisMiniportBlock
.MediaType
));
672 if (BufferLength
< Length
)
674 NDIS_DbgPrint(MIN_TRACE
, ("Buffer is too small.\n"));
678 Start1
= (PUCHAR
)&Adapter
->Address
;
679 NDIS_DbgPrint(MAX_TRACE
, ("packet address: %x:%x:%x:%x:%x:%x adapter address: %x:%x:%x:%x:%x:%x\n",
680 *((char *)Start1
), *(((char *)Start1
)+1), *(((char *)Start1
)+2), *(((char *)Start1
)+3), *(((char *)Start1
)+4), *(((char *)Start1
)+5),
681 *((char *)Start2
), *(((char *)Start2
)+1), *(((char *)Start2
)+2), *(((char *)Start2
)+3), *(((char *)Start2
)+4), *(((char *)Start2
)+5)));
683 return (RtlCompareMemory((PVOID
)Start1
, (PVOID
)Start2
, Length
) == Length
);
689 PNDIS_STRING AdapterName
)
691 * FUNCTION: Finds an adapter object by name
693 * AdapterName = Pointer to name of adapter
695 * Pointer to logical adapter object, or NULL if none was found.
696 * If found, the adapter is referenced for the caller. The caller
697 * is responsible for dereferencing after use
701 PLIST_ENTRY CurrentEntry
;
702 PLOGICAL_ADAPTER Adapter
= 0;
706 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
708 if(IsListEmpty(&AdapterListHead
))
710 NDIS_DbgPrint(MIN_TRACE
, ("No registered miniports for protocol to bind to\n"));
714 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterName = %wZ\n", AdapterName
));
716 KeAcquireSpinLock(&AdapterListLock
, &OldIrql
);
718 CurrentEntry
= AdapterListHead
.Flink
;
720 while (CurrentEntry
!= &AdapterListHead
)
722 Adapter
= CONTAINING_RECORD(CurrentEntry
, LOGICAL_ADAPTER
, ListEntry
);
726 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Examining adapter 0x%lx\n", Adapter
));
728 /* We're technically not allowed to call this above PASSIVE_LEVEL, but it doesn't break
729 * right now and I'd rather use a working API than reimplement it here */
730 if (RtlCompareUnicodeString(AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
, TRUE
) == 0)
736 CurrentEntry
= CurrentEntry
->Flink
;
739 KeReleaseSpinLock(&AdapterListLock
, OldIrql
);
743 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Leaving. Adapter found at 0x%x\n", Adapter
));
747 NDIS_DbgPrint(MIN_TRACE
, ("Leaving (adapter not found for %wZ).\n", AdapterName
));
755 PLOGICAL_ADAPTER Adapter
,
761 NDIS_STATUS NdisStatus
;
762 PNDIS_REQUEST NdisRequest
;
764 PNDIS_REQUEST_MAC_BLOCK MacBlock
;
766 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
768 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
770 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
771 return NDIS_STATUS_RESOURCES
;
774 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
776 NdisRequest
->RequestType
= NdisRequestSetInformation
;
777 NdisRequest
->DATA
.SET_INFORMATION
.Oid
= Oid
;
778 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
= Buffer
;
779 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
= Size
;
781 /* We'll need to give the completion routine some way of letting us know
782 * when it's finished. We'll stash a pointer to an event in the MacBlock */
783 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
784 MacBlock
= (PNDIS_REQUEST_MAC_BLOCK
)NdisRequest
->MacReserved
;
785 MacBlock
->Unknown1
= &Event
;
787 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
789 if (NdisStatus
== NDIS_STATUS_PENDING
)
791 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
792 NdisStatus
= (NDIS_STATUS
)MacBlock
->Unknown3
;
795 *BytesRead
= NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
;
797 ExFreePool(NdisRequest
);
803 MiniQueryInformation(
804 PLOGICAL_ADAPTER Adapter
,
810 * FUNCTION: Queries a logical adapter for properties
812 * Adapter = Pointer to the logical adapter object to query
813 * Oid = Specifies the Object ID to query for
814 * Size = Size of the passed buffer
815 * Buffer = Buffer for the output
816 * BytesWritten = Address of buffer to place number of bytes written
818 * Status of operation
821 NDIS_STATUS NdisStatus
;
822 PNDIS_REQUEST NdisRequest
;
824 PNDIS_REQUEST_MAC_BLOCK MacBlock
;
826 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
828 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
830 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
831 return NDIS_STATUS_RESOURCES
;
834 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
836 NdisRequest
->RequestType
= NdisRequestQueryInformation
;
837 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
= Oid
;
838 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
= Buffer
;
839 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
= Size
;
841 /* We'll need to give the completion routine some way of letting us know
842 * when it's finished. We'll stash a pointer to an event in the MacBlock */
843 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
844 MacBlock
= (PNDIS_REQUEST_MAC_BLOCK
)NdisRequest
->MacReserved
;
845 MacBlock
->Unknown1
= &Event
;
847 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
849 if (NdisStatus
== NDIS_STATUS_PENDING
)
851 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
852 NdisStatus
= (NDIS_STATUS
)MacBlock
->Unknown3
;
855 *BytesWritten
= NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
;
857 ExFreePool(NdisRequest
);
863 MiniCheckForHang( PLOGICAL_ADAPTER Adapter
)
865 * FUNCTION: Checks to see if the miniport is hung
867 * Adapter = Pointer to the logical adapter object
869 * TRUE if the miniport is hung
870 * FALSE if the miniport is not hung
876 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
877 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)
878 Ret
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)(
879 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
);
880 KeLowerIrql(OldIrql
);
886 MiniDoAddressingReset(PLOGICAL_ADAPTER Adapter
)
890 MiniSetInformation(Adapter
,
891 OID_GEN_CURRENT_LOOKAHEAD
,
893 &Adapter
->NdisMiniportBlock
.CurrentLookahead
,
896 /* FIXME: Set more stuff */
901 PLOGICAL_ADAPTER Adapter
)
903 * FUNCTION: Resets the miniport
905 * Adapter = Pointer to the logical adapter object
907 * Status of the operation
912 BOOLEAN AddressingReset
= TRUE
;
914 if (MiniIsBusy(Adapter
, NdisWorkItemResetRequested
)) {
915 MiniQueueWorkItem(Adapter
, NdisWorkItemResetRequested
, NULL
, FALSE
);
916 return NDIS_STATUS_PENDING
;
919 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
920 NdisMIndicateStatusComplete(Adapter
);
922 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
923 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
924 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
927 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
928 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
929 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
931 KeLowerIrql(OldIrql
);
933 if (Status
!= NDIS_STATUS_PENDING
) {
935 MiniDoAddressingReset(Adapter
);
937 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
938 NdisMIndicateStatusComplete(Adapter
);
940 MiniWorkItemComplete(Adapter
, NdisWorkItemResetRequested
);
949 PVOID DeferredContext
,
950 PVOID SystemArgument1
,
951 PVOID SystemArgument2
)
953 PLOGICAL_ADAPTER Adapter
= DeferredContext
;
955 if (MiniCheckForHang(Adapter
)) {
956 NDIS_DbgPrint(MIN_TRACE
, ("Miniport detected adapter hang\n"));
962 MiniWorkItemComplete(
963 PLOGICAL_ADAPTER Adapter
,
964 NDIS_WORK_ITEM_TYPE WorkItemType
)
966 PIO_WORKITEM IoWorkItem
;
968 /* Check if there's anything queued to run after this work item */
969 if (!MiniIsBusy(Adapter
, WorkItemType
))
972 /* There is, so fire the worker */
973 IoWorkItem
= IoAllocateWorkItem(Adapter
->NdisMiniportBlock
.DeviceObject
);
975 IoQueueWorkItem(IoWorkItem
, MiniportWorker
, DelayedWorkQueue
, IoWorkItem
);
981 PLOGICAL_ADAPTER Adapter
,
982 NDIS_WORK_ITEM_TYPE WorkItemType
,
983 PVOID WorkItemContext
,
986 * FUNCTION: Queues a work item for execution at a later time
988 * Adapter = Pointer to the logical adapter object to queue work item on
989 * WorkItemType = Type of work item to queue
990 * WorkItemContext = Pointer to context information for work item
992 * Status of operation
995 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
998 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1002 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1005 if (WorkItemType
== NdisWorkItemSend
)
1007 NDIS_DbgPrint(MIN_TRACE
, ("Requeuing failed packet (%x).\n", WorkItemContext
));
1008 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= WorkItemContext
;
1012 //This should never happen
1018 MiniportWorkItem
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_MINIPORT_WORK_ITEM
));
1019 if (!MiniportWorkItem
)
1021 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1022 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1026 MiniportWorkItem
->WorkItemType
= WorkItemType
;
1027 MiniportWorkItem
->WorkItemContext
= WorkItemContext
;
1029 /* safe due to adapter lock held */
1030 MiniportWorkItem
->Link
.Next
= NULL
;
1031 if (!Adapter
->WorkQueueHead
)
1033 Adapter
->WorkQueueHead
= MiniportWorkItem
;
1034 Adapter
->WorkQueueTail
= MiniportWorkItem
;
1038 Adapter
->WorkQueueTail
->Link
.Next
= (PSINGLE_LIST_ENTRY
)MiniportWorkItem
;
1039 Adapter
->WorkQueueTail
= MiniportWorkItem
;
1043 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1048 MiniDequeueWorkItem(
1049 PLOGICAL_ADAPTER Adapter
,
1050 NDIS_WORK_ITEM_TYPE
*WorkItemType
,
1051 PVOID
*WorkItemContext
)
1053 * FUNCTION: Dequeues a work item from the work queue of a logical adapter
1055 * Adapter = Pointer to the logical adapter object to dequeue work item from
1056 * AdapterBinding = Address of buffer for adapter binding for this request
1057 * WorkItemType = Address of buffer for work item type
1058 * WorkItemContext = Address of buffer for pointer to context information
1060 * Adapter lock must be held when called
1062 * Status of operation
1065 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
1066 PNDIS_PACKET Packet
;
1068 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1070 MiniportWorkItem
= Adapter
->WorkQueueHead
;
1072 if ((Packet
= Adapter
->NdisMiniportBlock
.FirstPendingPacket
))
1074 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= NULL
;
1076 *WorkItemType
= NdisWorkItemSend
;
1077 *WorkItemContext
= Packet
;
1079 return NDIS_STATUS_SUCCESS
;
1081 else if (MiniportWorkItem
)
1083 /* safe due to adapter lock held */
1084 Adapter
->WorkQueueHead
= (PNDIS_MINIPORT_WORK_ITEM
)MiniportWorkItem
->Link
.Next
;
1086 if (MiniportWorkItem
== Adapter
->WorkQueueTail
)
1087 Adapter
->WorkQueueTail
= NULL
;
1089 *WorkItemType
= MiniportWorkItem
->WorkItemType
;
1090 *WorkItemContext
= MiniportWorkItem
->WorkItemContext
;
1092 ExFreePool(MiniportWorkItem
);
1094 return NDIS_STATUS_SUCCESS
;
1098 NDIS_DbgPrint(MIN_TRACE
, ("No work item to dequeue\n"));
1100 return NDIS_STATUS_FAILURE
;
1106 PLOGICAL_ADAPTER Adapter
,
1107 PNDIS_REQUEST NdisRequest
)
1109 * FUNCTION: Sends a request to a miniport
1111 * AdapterBinding = Pointer to binding used in the request
1112 * NdisRequest = Pointer to NDIS request structure describing request
1114 * Status of operation
1119 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1121 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1123 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1124 Adapter
->NdisMiniportBlock
.PendingRequest
= NdisRequest
;
1125 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1127 if (!Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)
1129 switch (NdisRequest
->RequestType
)
1131 case NdisRequestQueryInformation
:
1132 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.QueryInformationHandler
)(
1133 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1134 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
,
1135 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
,
1136 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
,
1137 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
,
1138 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesNeeded
);
1141 case NdisRequestSetInformation
:
1142 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SetInformationHandler
)(
1143 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1144 NdisRequest
->DATA
.SET_INFORMATION
.Oid
,
1145 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
,
1146 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
,
1147 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
,
1148 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesNeeded
);
1152 NDIS_DbgPrint(MIN_TRACE
, ("Bad request type\n"));
1153 Status
= NDIS_STATUS_FAILURE
;
1158 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)(
1159 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1164 if (Status
!= NDIS_STATUS_PENDING
) {
1165 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1166 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
1167 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1170 KeLowerIrql(OldIrql
);
1172 if (Status
!= NDIS_STATUS_PENDING
) {
1173 MiniWorkItemComplete(Adapter
, NdisWorkItemRequest
);
1182 #undef NdisMSetInformationComplete
1185 NdisMSetInformationComplete(
1186 IN NDIS_HANDLE MiniportAdapterHandle
,
1187 IN NDIS_STATUS Status
)
1189 PLOGICAL_ADAPTER Adapter
=
1190 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
1193 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1194 if (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)
1195 (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)(MiniportAdapterHandle
, Status
);
1196 KeLowerIrql(OldIrql
);
1202 #undef NdisMQueryInformationComplete
1205 NdisMQueryInformationComplete(
1206 IN NDIS_HANDLE MiniportAdapterHandle
,
1207 IN NDIS_STATUS Status
)
1209 PLOGICAL_ADAPTER Adapter
=
1210 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
1213 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1214 if( Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)
1215 (Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)(MiniportAdapterHandle
, Status
);
1216 KeLowerIrql(OldIrql
);
1221 MiniportWorker(IN PDEVICE_OBJECT DeviceObject
, IN PVOID Context
)
1223 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
1224 KIRQL OldIrql
, RaiseOldIrql
;
1225 NDIS_STATUS NdisStatus
;
1226 PVOID WorkItemContext
;
1227 NDIS_WORK_ITEM_TYPE WorkItemType
;
1228 BOOLEAN AddressingReset
;
1230 IoFreeWorkItem((PIO_WORKITEM
)Context
);
1232 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1236 (Adapter
, &WorkItemType
, &WorkItemContext
);
1238 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1240 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1242 switch (WorkItemType
)
1244 case NdisWorkItemSend
:
1246 * called by ProSend when protocols want to send packets to the miniport
1249 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
1251 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1253 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1254 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1255 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1256 NdisStatus
= NDIS_STATUS_PENDING
;
1260 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
1261 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1263 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1264 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1265 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1267 KeLowerIrql(RaiseOldIrql
);
1269 NdisStatus
= NDIS_GET_PACKET_STATUS((PNDIS_PACKET
)WorkItemContext
);
1270 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1271 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1278 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1280 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1281 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1282 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1283 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1284 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1288 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
1289 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1290 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1291 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1292 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1293 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1294 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1295 KeLowerIrql(RaiseOldIrql
);
1296 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1297 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1303 if( NdisStatus
!= NDIS_STATUS_PENDING
) {
1305 ( Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1309 case NdisWorkItemSendLoopback
:
1311 * called by ProSend when protocols want to send loopback packets
1313 /* XXX atm ProIndicatePacket sends a packet up via the loopback adapter only */
1314 NdisStatus
= ProIndicatePacket(Adapter
, (PNDIS_PACKET
)WorkItemContext
);
1316 if( NdisStatus
!= NDIS_STATUS_PENDING
)
1317 MiniSendComplete((NDIS_HANDLE
)Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1320 case NdisWorkItemReturnPackets
:
1323 case NdisWorkItemResetRequested
:
1324 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
1325 NdisMIndicateStatusComplete(Adapter
);
1327 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1328 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
1329 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1332 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1333 Adapter
->NdisMiniportBlock
.ResetStatus
= NdisStatus
;
1334 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1336 KeLowerIrql(OldIrql
);
1338 if (NdisStatus
!= NDIS_STATUS_PENDING
)
1339 MiniResetComplete(Adapter
, NdisStatus
, AddressingReset
);
1342 case NdisWorkItemResetInProgress
:
1345 case NdisWorkItemMiniportCallback
:
1348 case NdisWorkItemRequest
:
1349 NdisStatus
= MiniDoRequest(Adapter
, (PNDIS_REQUEST
)WorkItemContext
);
1351 if (NdisStatus
== NDIS_STATUS_PENDING
)
1354 Adapter
->NdisMiniportBlock
.PendingRequest
= (PNDIS_REQUEST
)WorkItemContext
;
1355 switch (((PNDIS_REQUEST
)WorkItemContext
)->RequestType
)
1357 case NdisRequestQueryInformation
:
1358 NdisMQueryInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1361 case NdisRequestSetInformation
:
1362 NdisMSetInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1366 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS request type.\n"));
1369 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
1373 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS work item type (%d).\n", WorkItemType
));
1383 IN NDIS_HANDLE MiniportHandle
,
1384 IN NDIS_STATUS GeneralStatus
,
1385 IN PVOID StatusBuffer
,
1386 IN UINT StatusBufferSize
)
1388 PLOGICAL_ADAPTER Adapter
= MiniportHandle
;
1389 PLIST_ENTRY CurrentEntry
;
1390 PADAPTER_BINDING AdapterBinding
;
1393 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1395 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1397 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1399 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1401 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusHandler
)(
1402 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
1407 CurrentEntry
= CurrentEntry
->Flink
;
1410 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1416 IN NDIS_HANDLE MiniportAdapterHandle
)
1418 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1419 PLIST_ENTRY CurrentEntry
;
1420 PADAPTER_BINDING AdapterBinding
;
1423 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1425 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1427 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1429 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1431 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusCompleteHandler
)(
1432 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
);
1434 CurrentEntry
= CurrentEntry
->Flink
;
1437 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1446 IN NDIS_HANDLE LogHandle
)
1448 PNDIS_LOG Log
= (PNDIS_LOG
)LogHandle
;
1449 PNDIS_MINIPORT_BLOCK Miniport
= Log
->Miniport
;
1452 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1454 KeAcquireSpinLock(&(Miniport
)->Lock
, &OldIrql
);
1455 Miniport
->Log
= NULL
;
1456 KeReleaseSpinLock(&(Miniport
)->Lock
, OldIrql
);
1467 IN NDIS_HANDLE MiniportAdapterHandle
,
1469 OUT PNDIS_HANDLE LogHandle
)
1471 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1475 NDIS_DbgPrint(MAX_TRACE
, ("called: MiniportAdapterHandle 0x%x, Size %ld\n", MiniportAdapterHandle
, Size
));
1477 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1479 if (Adapter
->NdisMiniportBlock
.Log
)
1482 return NDIS_STATUS_FAILURE
;
1485 Log
= ExAllocatePool(NonPagedPool
, Size
+ sizeof(NDIS_LOG
));
1489 return NDIS_STATUS_RESOURCES
;
1492 Adapter
->NdisMiniportBlock
.Log
= Log
;
1494 KeInitializeSpinLock(&Log
->LogLock
);
1496 Log
->Miniport
= &Adapter
->NdisMiniportBlock
;
1497 Log
->TotalSize
= Size
;
1498 Log
->CurrentSize
= 0;
1505 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1507 return NDIS_STATUS_SUCCESS
;
1515 NdisMDeregisterAdapterShutdownHandler(
1516 IN NDIS_HANDLE MiniportHandle
)
1518 * FUNCTION: de-registers a shutdown handler
1519 * ARGUMENTS: MiniportHandle: Handle passed into MiniportInitialize
1522 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1524 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1526 if(Adapter
->BugcheckContext
->ShutdownHandler
) {
1527 KeDeregisterBugCheckCallback(Adapter
->BugcheckContext
->CallbackRecord
);
1528 IoUnregisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1538 IN NDIS_HANDLE LogHandle
)
1540 PNDIS_LOG Log
= (PNDIS_LOG
) LogHandle
;
1543 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1546 KeAcquireSpinLock(&Log
->LogLock
, &OldIrql
);
1548 /* Set buffers size */
1549 Log
->CurrentSize
= 0;
1554 KeReleaseSpinLock(&Log
->LogLock
, OldIrql
);
1560 #undef NdisMIndicateStatus
1563 NdisMIndicateStatus(
1564 IN NDIS_HANDLE MiniportAdapterHandle
,
1565 IN NDIS_STATUS GeneralStatus
,
1566 IN PVOID StatusBuffer
,
1567 IN UINT StatusBufferSize
)
1569 MiniStatus(MiniportAdapterHandle
, GeneralStatus
, StatusBuffer
, StatusBufferSize
);
1575 #undef NdisMIndicateStatusComplete
1578 NdisMIndicateStatusComplete(
1579 IN NDIS_HANDLE MiniportAdapterHandle
)
1581 MiniStatusComplete(MiniportAdapterHandle
);
1589 NdisInitializeWrapper(
1590 OUT PNDIS_HANDLE NdisWrapperHandle
,
1591 IN PVOID SystemSpecific1
,
1592 IN PVOID SystemSpecific2
,
1593 IN PVOID SystemSpecific3
)
1595 * FUNCTION: Notifies the NDIS library that a new miniport is initializing
1597 * NdisWrapperHandle = Address of buffer to place NDIS wrapper handle
1598 * SystemSpecific1 = Pointer to the driver's driver object
1599 * SystemSpecific2 = Pointer to the driver's registry path
1600 * SystemSpecific3 = Always NULL
1602 * - SystemSpecific2 goes invalid so we copy it
1605 PNDIS_M_DRIVER_BLOCK Miniport
;
1606 PUNICODE_STRING RegistryPath
;
1607 WCHAR
*RegistryBuffer
;
1609 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1611 ASSERT(NdisWrapperHandle
);
1613 *NdisWrapperHandle
= NULL
;
1615 #if BREAK_ON_MINIPORT_INIT
1619 Miniport
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DRIVER_BLOCK
));
1623 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1627 RtlZeroMemory(Miniport
, sizeof(NDIS_M_DRIVER_BLOCK
));
1629 KeInitializeSpinLock(&Miniport
->Lock
);
1631 Miniport
->DriverObject
= (PDRIVER_OBJECT
)SystemSpecific1
;
1633 /* set the miniport's driver registry path */
1634 RegistryPath
= ExAllocatePool(PagedPool
, sizeof(UNICODE_STRING
));
1637 ExFreePool(Miniport
);
1638 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1642 RegistryPath
->Length
= ((PUNICODE_STRING
)SystemSpecific2
)->Length
;
1643 RegistryPath
->MaximumLength
= RegistryPath
->Length
+ sizeof(WCHAR
); /* room for 0-term */
1645 RegistryBuffer
= ExAllocatePool(PagedPool
, RegistryPath
->MaximumLength
);
1648 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1649 ExFreePool(Miniport
);
1650 ExFreePool(RegistryPath
);
1654 RtlCopyMemory(RegistryBuffer
, ((PUNICODE_STRING
)SystemSpecific2
)->Buffer
, RegistryPath
->Length
);
1655 RegistryBuffer
[RegistryPath
->Length
/sizeof(WCHAR
)] = 0;
1657 RegistryPath
->Buffer
= RegistryBuffer
;
1658 Miniport
->RegistryPath
= RegistryPath
;
1660 InitializeListHead(&Miniport
->DeviceList
);
1662 /* Put miniport in global miniport list */
1663 ExInterlockedInsertTailList(&MiniportListHead
, &Miniport
->ListEntry
, &MiniportListLock
);
1665 *NdisWrapperHandle
= Miniport
;
1668 VOID NTAPI
NdisIBugcheckCallback(
1672 * FUNCTION: Internal callback for handling bugchecks - calls adapter's shutdown handler
1674 * Buffer: Pointer to a bugcheck callback context
1678 PMINIPORT_BUGCHECK_CONTEXT Context
= (PMINIPORT_BUGCHECK_CONTEXT
)Buffer
;
1679 ADAPTER_SHUTDOWN_HANDLER sh
= (ADAPTER_SHUTDOWN_HANDLER
)Context
->ShutdownHandler
;
1681 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1684 sh(Context
->DriverContext
);
1692 NdisMRegisterAdapterShutdownHandler(
1693 IN NDIS_HANDLE MiniportHandle
,
1694 IN PVOID ShutdownContext
,
1695 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
1697 * FUNCTION: Register a shutdown handler for an adapter
1699 * MiniportHandle: Handle originally passed into MiniportInitialize
1700 * ShutdownContext: Pre-initialized bugcheck context
1701 * ShutdownHandler: Function to call to handle the bugcheck
1703 * - I'm not sure about ShutdownContext
1706 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1707 PMINIPORT_BUGCHECK_CONTEXT BugcheckContext
;
1709 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1711 if (Adapter
->BugcheckContext
!= NULL
)
1713 NDIS_DbgPrint(MIN_TRACE
, ("Attempted to register again for a shutdown callback\n"));
1717 BugcheckContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_BUGCHECK_CONTEXT
));
1718 if(!BugcheckContext
)
1720 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1724 BugcheckContext
->ShutdownHandler
= ShutdownHandler
;
1725 BugcheckContext
->DriverContext
= ShutdownContext
;
1727 BugcheckContext
->CallbackRecord
= ExAllocatePool(NonPagedPool
, sizeof(KBUGCHECK_CALLBACK_RECORD
));
1728 if (!BugcheckContext
->CallbackRecord
) {
1729 ExFreePool(BugcheckContext
);
1733 Adapter
->BugcheckContext
= BugcheckContext
;
1735 KeInitializeCallbackRecord(BugcheckContext
->CallbackRecord
);
1737 KeRegisterBugCheckCallback(BugcheckContext
->CallbackRecord
, NdisIBugcheckCallback
,
1738 BugcheckContext
, sizeof(*BugcheckContext
), (PUCHAR
)"Ndis Miniport");
1740 IoRegisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1745 PLOGICAL_ADAPTER Adapter
,
1746 NDIS_OID AddressOID
)
1748 * FUNCTION: Queries miniport for information
1750 * Adapter = Pointer to logical adapter
1751 * AddressOID = OID to use to query for current address
1753 * Status of operation
1757 NDIS_STATUS NdisStatus
;
1759 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1761 /* Get MAC options for adapter */
1762 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAC_OPTIONS
, sizeof(UINT
),
1763 &Adapter
->NdisMiniportBlock
.MacOptions
,
1766 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1768 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAC_OPTIONS failed. NdisStatus (0x%X).\n", NdisStatus
));
1772 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MacOptions (0x%X).\n", Adapter
->NdisMiniportBlock
.MacOptions
));
1774 /* Get current hardware address of adapter */
1775 NdisStatus
= MiniQueryInformation(Adapter
, AddressOID
, Adapter
->AddressLength
,
1776 &Adapter
->Address
, &BytesWritten
);
1778 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1780 NDIS_DbgPrint(MIN_TRACE
, ("Address OID (0x%X) failed. NdisStatus (0x%X).\n", AddressOID
, NdisStatus
));
1788 PUCHAR A
= (PUCHAR
)&Adapter
->Address
.Type
.Medium802_3
;
1790 NDIS_DbgPrint(MAX_TRACE
, ("Adapter address is (%02X %02X %02X %02X %02X %02X).\n", A
[0], A
[1], A
[2], A
[3], A
[4], A
[5]));
1794 /* Get maximum lookahead buffer size of adapter */
1795 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_LOOKAHEAD
, sizeof(ULONG
),
1796 &Adapter
->NdisMiniportBlock
.MaximumLookahead
, &BytesWritten
);
1798 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1800 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1804 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MaxLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.MaximumLookahead
));
1806 /* Get current lookahead buffer size of adapter */
1807 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_CURRENT_LOOKAHEAD
, sizeof(ULONG
),
1808 &Adapter
->NdisMiniportBlock
.CurrentLookahead
, &BytesWritten
);
1810 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1812 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_CURRENT_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1816 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_SEND_PACKETS
, sizeof(ULONG
),
1817 &Adapter
->NdisMiniportBlock
.MaxSendPackets
, &BytesWritten
);
1819 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1821 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_SEND_PACKETS failed. NdisStatus (0x%X).\n", NdisStatus
));
1823 /* Set it to 1 if it fails because some drivers don't support this (?)*/
1824 Adapter
->NdisMiniportBlock
.MaxSendPackets
= 1;
1827 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.CurrentLookahead
));
1829 return STATUS_SUCCESS
;
1834 NdisIForwardIrpAndWaitCompletionRoutine(
1839 PKEVENT Event
= Context
;
1841 if (Irp
->PendingReturned
)
1842 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
1844 return STATUS_MORE_PROCESSING_REQUIRED
;
1849 NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter
, PIRP Irp
)
1854 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1855 IoCopyCurrentIrpStackLocationToNext(Irp
);
1856 IoSetCompletionRoutine(Irp
, NdisIForwardIrpAndWaitCompletionRoutine
, &Event
,
1858 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
1859 if (Status
== STATUS_PENDING
)
1861 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1862 Status
= Irp
->IoStatus
.Status
;
1870 IN PDEVICE_OBJECT DeviceObject
,
1873 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1874 Irp
->IoStatus
.Information
= 0;
1876 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1878 return STATUS_SUCCESS
;
1883 NdisIPnPStartDevice(
1884 IN PDEVICE_OBJECT DeviceObject
,
1887 * FUNCTION: Handle the PnP start device event
1889 * DeviceObejct = Functional Device Object
1890 * Irp = IRP_MN_START_DEVICE I/O request packet
1892 * Status of operation
1895 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
1896 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1897 NDIS_WRAPPER_CONTEXT WrapperContext
;
1898 NDIS_STATUS NdisStatus
;
1899 NDIS_STATUS OpenErrorStatus
;
1901 UINT SelectedMediumIndex
= 0;
1902 NDIS_OID AddressOID
;
1903 BOOLEAN Success
= FALSE
;
1904 ULONG ResourceCount
;
1905 ULONG ResourceListSize
;
1906 UNICODE_STRING ParamName
;
1907 PNDIS_CONFIGURATION_PARAMETER ConfigParam
;
1908 NDIS_HANDLE ConfigHandle
;
1910 LARGE_INTEGER Timeout
;
1911 UINT MaxMulticastAddresses
;
1913 PLIST_ENTRY CurrentEntry
;
1914 PPROTOCOL_BINDING ProtocolBinding
;
1917 * Prepare wrapper context used by HW and configuration routines.
1920 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Start Device %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
1922 NDIS_DbgPrint(MAX_TRACE
, ("Inserting adapter 0x%x into adapter list\n", Adapter
));
1924 /* Put adapter in global adapter list */
1925 ExInterlockedInsertTailList(&AdapterListHead
, &Adapter
->ListEntry
, &AdapterListLock
);
1927 Status
= IoOpenDeviceRegistryKey(
1928 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
, PLUGPLAY_REGKEY_DRIVER
,
1929 KEY_ALL_ACCESS
, &WrapperContext
.RegistryHandle
);
1930 if (!NT_SUCCESS(Status
))
1932 NDIS_DbgPrint(MIN_TRACE
,("failed to open adapter-specific reg key\n"));
1933 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1937 NDIS_DbgPrint(MAX_TRACE
, ("opened device reg key\n"));
1939 WrapperContext
.DeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
1942 * Store the adapter resources used by HW routines such as
1943 * NdisMQueryAdapterResources.
1946 if (Stack
->Parameters
.StartDevice
.AllocatedResources
!= NULL
)
1948 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResources
->List
[0].
1949 PartialResourceList
.Count
;
1951 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1952 PartialDescriptors
[ResourceCount
]);
1954 Adapter
->NdisMiniportBlock
.AllocatedResources
=
1955 ExAllocatePool(PagedPool
, ResourceListSize
);
1956 if (Adapter
->NdisMiniportBlock
.AllocatedResources
== NULL
)
1958 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1959 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1960 return STATUS_INSUFFICIENT_RESOURCES
;
1963 Adapter
->NdisMiniportBlock
.Resources
=
1964 ExAllocatePool(PagedPool
, ResourceListSize
);
1965 if (!Adapter
->NdisMiniportBlock
.Resources
)
1967 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1968 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1969 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1970 return STATUS_INSUFFICIENT_RESOURCES
;
1973 RtlCopyMemory(Adapter
->NdisMiniportBlock
.Resources
,
1974 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1977 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResources
,
1978 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1982 if (Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
!= NULL
)
1984 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
->List
[0].
1985 PartialResourceList
.Count
;
1987 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1988 PartialDescriptors
[ResourceCount
]);
1990 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
=
1991 ExAllocatePool(PagedPool
, ResourceListSize
);
1992 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
== NULL
)
1994 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1995 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1996 return STATUS_INSUFFICIENT_RESOURCES
;
1999 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
,
2000 Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
,
2005 * Store the Bus Type, Bus Number and Slot information. It's used by
2006 * the hardware routines then.
2009 NdisOpenConfiguration(&NdisStatus
, &ConfigHandle
, (NDIS_HANDLE
)&WrapperContext
);
2010 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2012 NDIS_DbgPrint(MIN_TRACE
, ("Failed to open configuration key\n"));
2013 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2017 Size
= sizeof(ULONG
);
2018 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
2019 DevicePropertyLegacyBusType
, Size
,
2020 &Adapter
->NdisMiniportBlock
.BusType
, &Size
);
2021 if (!NT_SUCCESS(Status
) || (INTERFACE_TYPE
)Adapter
->NdisMiniportBlock
.BusType
== InterfaceTypeUndefined
)
2023 NdisInitUnicodeString(&ParamName
, L
"BusType");
2024 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
2025 &ParamName
, NdisParameterInteger
);
2026 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
2027 Adapter
->NdisMiniportBlock
.BusType
= ConfigParam
->ParameterData
.IntegerData
;
2029 Adapter
->NdisMiniportBlock
.BusType
= Isa
;
2032 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
2033 DevicePropertyBusNumber
, Size
,
2034 &Adapter
->NdisMiniportBlock
.BusNumber
, &Size
);
2035 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.BusNumber
== 0xFFFFFFF0)
2037 NdisInitUnicodeString(&ParamName
, L
"BusNumber");
2038 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
2039 &ParamName
, NdisParameterInteger
);
2040 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
2041 Adapter
->NdisMiniportBlock
.BusNumber
= ConfigParam
->ParameterData
.IntegerData
;
2043 Adapter
->NdisMiniportBlock
.BusNumber
= 0;
2045 WrapperContext
.BusNumber
= Adapter
->NdisMiniportBlock
.BusNumber
;
2047 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
2048 DevicePropertyAddress
, Size
,
2049 &Adapter
->NdisMiniportBlock
.SlotNumber
, &Size
);
2050 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.SlotNumber
== (NDIS_INTERFACE_TYPE
)-1)
2052 NdisInitUnicodeString(&ParamName
, L
"SlotNumber");
2053 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
2054 &ParamName
, NdisParameterInteger
);
2055 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
2056 Adapter
->NdisMiniportBlock
.SlotNumber
= ConfigParam
->ParameterData
.IntegerData
;
2058 Adapter
->NdisMiniportBlock
.SlotNumber
= 0;
2062 /* Convert slotnumber to PCI_SLOT_NUMBER */
2063 ULONG PciSlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
2064 PCI_SLOT_NUMBER SlotNumber
;
2066 SlotNumber
.u
.AsULONG
= 0;
2067 SlotNumber
.u
.bits
.DeviceNumber
= (PciSlotNumber
>> 16) & 0xFFFF;
2068 SlotNumber
.u
.bits
.FunctionNumber
= PciSlotNumber
& 0xFFFF;
2070 Adapter
->NdisMiniportBlock
.SlotNumber
= SlotNumber
.u
.AsULONG
;
2072 WrapperContext
.SlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
2074 NdisCloseConfiguration(ConfigHandle
);
2076 /* Set handlers (some NDIS macros require these) */
2077 Adapter
->NdisMiniportBlock
.EthRxCompleteHandler
= EthFilterDprIndicateReceiveComplete
;
2078 Adapter
->NdisMiniportBlock
.EthRxIndicateHandler
= EthFilterDprIndicateReceive
;
2079 Adapter
->NdisMiniportBlock
.SendCompleteHandler
= MiniSendComplete
;
2080 Adapter
->NdisMiniportBlock
.SendResourcesHandler
= MiniSendResourcesAvailable
;
2081 Adapter
->NdisMiniportBlock
.ResetCompleteHandler
= MiniResetComplete
;
2082 Adapter
->NdisMiniportBlock
.TDCompleteHandler
= MiniTransferDataComplete
;
2083 Adapter
->NdisMiniportBlock
.PacketIndicateHandler
= MiniIndicateReceivePacket
;
2084 Adapter
->NdisMiniportBlock
.StatusHandler
= MiniStatus
;
2085 Adapter
->NdisMiniportBlock
.StatusCompleteHandler
= MiniStatusComplete
;
2086 Adapter
->NdisMiniportBlock
.SendPacketsHandler
= ProSendPackets
;
2087 Adapter
->NdisMiniportBlock
.QueryCompleteHandler
= MiniRequestComplete
;
2088 Adapter
->NdisMiniportBlock
.SetCompleteHandler
= MiniRequestComplete
;
2091 * Call MiniportInitialize.
2094 NDIS_DbgPrint(MID_TRACE
, ("calling MiniportInitialize\n"));
2095 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.InitializeHandler
)(
2096 &OpenErrorStatus
, &SelectedMediumIndex
, &MediaArray
[0],
2097 MEDIA_ARRAY_SIZE
, Adapter
, (NDIS_HANDLE
)&WrapperContext
);
2099 ZwClose(WrapperContext
.RegistryHandle
);
2101 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2103 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() failed for an adapter.\n"));
2104 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2105 if (Adapter
->NdisMiniportBlock
.Interrupt
)
2107 KeBugCheckEx(BUGCODE_ID_DRIVER
,
2109 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.Interrupt
,
2110 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.TimerQueue
,
2113 if (Adapter
->NdisMiniportBlock
.TimerQueue
)
2115 KeBugCheckEx(BUGCODE_ID_DRIVER
,
2117 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.Interrupt
,
2118 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.TimerQueue
,
2124 if (SelectedMediumIndex
>= MEDIA_ARRAY_SIZE
)
2126 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() selected a bad index\n"));
2127 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2128 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
2131 Adapter
->NdisMiniportBlock
.MediaType
= MediaArray
[SelectedMediumIndex
];
2133 switch (Adapter
->NdisMiniportBlock
.MediaType
)
2135 case NdisMedium802_3
:
2136 Adapter
->MediumHeaderSize
= 14; /* XXX figure out what to do about LLC */
2137 AddressOID
= OID_802_3_CURRENT_ADDRESS
;
2138 Adapter
->AddressLength
= ETH_LENGTH_OF_ADDRESS
;
2139 NdisStatus
= DoQueries(Adapter
, AddressOID
);
2140 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
2142 NdisStatus
= MiniQueryInformation(Adapter
, OID_802_3_MAXIMUM_LIST_SIZE
, sizeof(UINT
),
2143 &MaxMulticastAddresses
, &BytesWritten
);
2145 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2147 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2148 NDIS_DbgPrint(MIN_TRACE
, ("MiniQueryInformation failed (%x)\n", NdisStatus
));
2152 Success
= EthCreateFilter(MaxMulticastAddresses
,
2153 Adapter
->Address
.Type
.Medium802_3
,
2154 &Adapter
->NdisMiniportBlock
.EthDB
);
2156 ((PETHI_FILTER
)Adapter
->NdisMiniportBlock
.EthDB
)->Miniport
= (PNDIS_MINIPORT_BLOCK
)Adapter
;
2158 NdisStatus
= NDIS_STATUS_RESOURCES
;
2163 /* FIXME: Support other types of media */
2164 NDIS_DbgPrint(MIN_TRACE
, ("error: unsupported media\n"));
2166 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2167 return STATUS_UNSUCCESSFUL
;
2170 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2172 NDIS_DbgPrint(MIN_TRACE
, ("couldn't create filter (%x)\n", NdisStatus
));
2176 /* Check for a hang every two seconds if it wasn't set in MiniportInitialize */
2177 if (Adapter
->NdisMiniportBlock
.CheckForHangSeconds
== 0)
2178 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= 2;
2180 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
2181 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStarted
;
2183 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, TRUE
);
2185 Timeout
.QuadPart
= Int32x32To64(Adapter
->NdisMiniportBlock
.CheckForHangSeconds
, -1000000);
2186 KeSetTimerEx(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
, Timeout
,
2187 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
* 1000,
2188 &Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
);
2190 /* Put adapter in adapter list for this miniport */
2191 ExInterlockedInsertTailList(&Adapter
->NdisMiniportBlock
.DriverHandle
->DeviceList
, &Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
2193 /* Refresh bindings for all protocols */
2194 CurrentEntry
= ProtocolListHead
.Flink
;
2195 while (CurrentEntry
!= &ProtocolListHead
)
2197 ProtocolBinding
= CONTAINING_RECORD(CurrentEntry
, PROTOCOL_BINDING
, ListEntry
);
2199 ndisBindMiniportsToProtocol(&NdisStatus
, ProtocolBinding
);
2201 CurrentEntry
= CurrentEntry
->Flink
;
2204 return STATUS_SUCCESS
;
2210 IN PDEVICE_OBJECT DeviceObject
,
2213 * FUNCTION: Handle the PnP stop device event
2215 * DeviceObejct = Functional Device Object
2216 * Irp = IRP_MN_STOP_DEVICE I/O request packet
2218 * Status of operation
2221 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2223 /* Remove adapter from adapter list for this miniport */
2224 ExInterlockedRemoveEntryList(&Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
2226 /* Remove adapter from global adapter list */
2227 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
2229 KeCancelTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2231 /* Set this here so MiniportISR will be forced to run for interrupts generated in MiniportHalt */
2232 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
2233 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStopped
;
2235 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.HaltHandler
)(Adapter
);
2237 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, FALSE
);
2239 if (Adapter
->NdisMiniportBlock
.AllocatedResources
)
2241 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
2242 Adapter
->NdisMiniportBlock
.AllocatedResources
= NULL
;
2244 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
)
2246 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
);
2247 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
= NULL
;
2250 if (Adapter
->NdisMiniportBlock
.Resources
)
2252 ExFreePool(Adapter
->NdisMiniportBlock
.Resources
);
2253 Adapter
->NdisMiniportBlock
.Resources
= NULL
;
2256 if (Adapter
->NdisMiniportBlock
.EthDB
)
2258 EthDeleteFilter(Adapter
->NdisMiniportBlock
.EthDB
);
2259 Adapter
->NdisMiniportBlock
.EthDB
= NULL
;
2262 return STATUS_SUCCESS
;
2268 IN PDEVICE_OBJECT DeviceObject
,
2271 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
2272 PMINIPORT_BUGCHECK_CONTEXT Context
= Adapter
->BugcheckContext
;
2273 ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
= Context
->ShutdownHandler
;
2275 ASSERT(ShutdownHandler
);
2277 ShutdownHandler(Context
->DriverContext
);
2279 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2280 Irp
->IoStatus
.Information
= 0;
2282 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2284 return STATUS_SUCCESS
;
2289 NdisIDeviceIoControl(
2290 IN PDEVICE_OBJECT DeviceObject
,
2293 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2294 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2295 NDIS_STATUS Status
= STATUS_NOT_SUPPORTED
;
2298 Irp
->IoStatus
.Information
= 0;
2302 switch (Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
2304 case IOCTL_NDIS_QUERY_GLOBAL_STATS
:
2305 Status
= MiniQueryInformation(Adapter
,
2306 *(PNDIS_OID
)Irp
->AssociatedIrp
.SystemBuffer
,
2307 Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
,
2308 MmGetSystemAddressForMdl(Irp
->MdlAddress
),
2310 Irp
->IoStatus
.Information
= Written
;
2318 if (Status
!= NDIS_STATUS_PENDING
)
2320 Irp
->IoStatus
.Status
= Status
;
2321 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2324 IoMarkIrpPending(Irp
);
2332 IN PDEVICE_OBJECT DeviceObject
,
2335 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2336 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2339 switch (Stack
->MinorFunction
)
2341 case IRP_MN_START_DEVICE
:
2342 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2343 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2345 Status
= NdisIPnPStartDevice(DeviceObject
, Irp
);
2348 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed device start\n"));
2349 Irp
->IoStatus
.Status
= Status
;
2350 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2353 case IRP_MN_STOP_DEVICE
:
2354 Status
= NdisIPnPStopDevice(DeviceObject
, Irp
);
2355 if (!NT_SUCCESS(Status
))
2356 NDIS_DbgPrint(MIN_TRACE
, ("WARNING: Ignoring halt device failure! Passing the IRP down anyway\n"));
2357 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2360 case IRP_MN_QUERY_REMOVE_DEVICE
:
2361 case IRP_MN_QUERY_STOP_DEVICE
:
2362 Status
= NdisIPnPQueryStopDevice(DeviceObject
, Irp
);
2363 Irp
->IoStatus
.Status
= Status
;
2364 if (Status
!= STATUS_SUCCESS
)
2366 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2367 NDIS_DbgPrint(MIN_TRACE
, ("Failing miniport halt request\n"));
2372 case IRP_MN_CANCEL_REMOVE_DEVICE
:
2373 case IRP_MN_CANCEL_STOP_DEVICE
:
2374 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2375 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2377 Status
= NdisIPnPCancelStopDevice(DeviceObject
, Irp
);
2381 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed cancel stop/remove request\n"));
2383 Irp
->IoStatus
.Status
= Status
;
2384 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2387 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
2388 Status
= NDIS_STATUS_SUCCESS
;
2389 Irp
->IoStatus
.Status
= Status
;
2390 Irp
->IoStatus
.Information
|= Adapter
->NdisMiniportBlock
.PnPFlags
;
2397 IoSkipCurrentIrpStackLocation(Irp
);
2398 return IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
2404 _In_ PDEVICE_OBJECT DeviceObject
,
2407 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
2409 PoStartNextPowerIrp(Irp
);
2410 IoSkipCurrentIrpStackLocation(Irp
);
2411 return PoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
2417 IN PDRIVER_OBJECT DriverObject
,
2418 IN PDEVICE_OBJECT PhysicalDeviceObject
)
2420 * FUNCTION: Create a device for an adapter found using PnP
2422 * DriverObject = Pointer to the miniport driver object
2423 * PhysicalDeviceObject = Pointer to the PDO for our adapter
2426 static const WCHAR ClassKeyName
[] = {'C','l','a','s','s','\\'};
2427 static const WCHAR LinkageKeyName
[] = {'\\','L','i','n','k','a','g','e',0};
2428 PNDIS_M_DRIVER_BLOCK Miniport
;
2429 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2430 WCHAR
*LinkageKeyBuffer
;
2431 ULONG DriverKeyLength
;
2432 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
2433 UNICODE_STRING ExportName
;
2434 PDEVICE_OBJECT DeviceObject
;
2435 PLOGICAL_ADAPTER Adapter
;
2439 * Gain the access to the miniport data structure first.
2442 MiniportPtr
= IoGetDriverObjectExtension(DriverObject
, (PVOID
)'NMID');
2443 if (MiniportPtr
== NULL
)
2445 NDIS_DbgPrint(MIN_TRACE
, ("Can't get driver object extension.\n"));
2446 return NDIS_STATUS_FAILURE
;
2448 Miniport
= *MiniportPtr
;
2451 * Get name of the Linkage registry key for our adapter. It's located under
2452 * the driver key for our driver and so we have basicly two ways to do it.
2453 * Either we can use IoOpenDriverRegistryKey or compose it using information
2454 * gathered by IoGetDeviceProperty. I choosed the second because
2455 * IoOpenDriverRegistryKey wasn't implemented at the time of writing.
2458 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2459 0, NULL
, &DriverKeyLength
);
2460 if (Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
&& Status
!= STATUS_SUCCESS
)
2462 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key length.\n"));
2466 LinkageKeyBuffer
= ExAllocatePool(PagedPool
, DriverKeyLength
+
2467 sizeof(ClassKeyName
) + sizeof(LinkageKeyName
));
2468 if (LinkageKeyBuffer
== NULL
)
2470 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate memory for driver key name.\n"));
2471 return STATUS_INSUFFICIENT_RESOURCES
;
2474 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2475 DriverKeyLength
, LinkageKeyBuffer
+
2476 (sizeof(ClassKeyName
) / sizeof(WCHAR
)),
2478 if (!NT_SUCCESS(Status
))
2480 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key.\n"));
2481 ExFreePool(LinkageKeyBuffer
);
2485 /* Compose the linkage key name. */
2486 RtlCopyMemory(LinkageKeyBuffer
, ClassKeyName
, sizeof(ClassKeyName
));
2487 RtlCopyMemory(LinkageKeyBuffer
+ ((sizeof(ClassKeyName
) + DriverKeyLength
) /
2488 sizeof(WCHAR
)) - 1, LinkageKeyName
, sizeof(LinkageKeyName
));
2490 NDIS_DbgPrint(DEBUG_MINIPORT
, ("LinkageKey: %S.\n", LinkageKeyBuffer
));
2493 * Now open the linkage key and read the "Export" and "RootDevice" values
2494 * which contains device name and root service respectively.
2497 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
2498 RtlInitUnicodeString(&ExportName
, NULL
);
2499 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
| RTL_QUERY_REGISTRY_DIRECT
;
2500 QueryTable
[0].Name
= L
"Export";
2501 QueryTable
[0].EntryContext
= &ExportName
;
2503 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
, LinkageKeyBuffer
,
2504 QueryTable
, NULL
, NULL
);
2505 ExFreePool(LinkageKeyBuffer
);
2506 if (!NT_SUCCESS(Status
))
2508 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport device name. (%x)\n", Status
));
2513 * Create the device object.
2516 NDIS_DbgPrint(MAX_TRACE
, ("creating device %wZ\n", &ExportName
));
2518 Status
= IoCreateDevice(Miniport
->DriverObject
, sizeof(LOGICAL_ADAPTER
),
2519 &ExportName
, FILE_DEVICE_PHYSICAL_NETCARD
,
2520 0, FALSE
, &DeviceObject
);
2521 if (!NT_SUCCESS(Status
))
2523 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device object.\n"));
2524 RtlFreeUnicodeString(&ExportName
);
2529 * Initialize the adapter structure.
2532 Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2533 KeInitializeSpinLock(&Adapter
->NdisMiniportBlock
.Lock
);
2534 InitializeListHead(&Adapter
->ProtocolListHead
);
2536 Status
= IoRegisterDeviceInterface(PhysicalDeviceObject
,
2537 &GUID_DEVINTERFACE_NET
,
2539 &Adapter
->NdisMiniportBlock
.SymbolicLinkName
);
2541 if (!NT_SUCCESS(Status
))
2543 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device interface.\n"));
2544 IoDeleteDevice(DeviceObject
);
2545 RtlFreeUnicodeString(&ExportName
);
2549 Adapter
->NdisMiniportBlock
.DriverHandle
= Miniport
;
2550 Adapter
->NdisMiniportBlock
.MiniportName
= ExportName
;
2551 Adapter
->NdisMiniportBlock
.DeviceObject
= DeviceObject
;
2552 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
= PhysicalDeviceObject
;
2553 Adapter
->NdisMiniportBlock
.NextDeviceObject
=
2554 IoAttachDeviceToDeviceStack(Adapter
->NdisMiniportBlock
.DeviceObject
,
2555 PhysicalDeviceObject
);
2557 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= 0;
2558 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceAdded
;
2560 KeInitializeTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2561 KeInitializeDpc(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
, MiniportHangDpc
, Adapter
);
2563 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
2565 return STATUS_SUCCESS
;
2570 NdisGenericIrpHandler(
2571 IN PDEVICE_OBJECT DeviceObject
,
2574 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
2576 /* Use the characteristics to classify the device */
2577 if (DeviceObject
->DeviceType
== FILE_DEVICE_PHYSICAL_NETCARD
)
2579 if ((IrpSp
->MajorFunction
== IRP_MJ_CREATE
) ||
2580 (IrpSp
->MajorFunction
== IRP_MJ_CLOSE
))
2582 return NdisICreateClose(DeviceObject
, Irp
);
2584 else if (IrpSp
->MajorFunction
== IRP_MJ_PNP
)
2586 return NdisIDispatchPnp(DeviceObject
, Irp
);
2588 else if (IrpSp
->MajorFunction
== IRP_MJ_SHUTDOWN
)
2590 return NdisIShutdown(DeviceObject
, Irp
);
2592 else if (IrpSp
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
)
2594 return NdisIDeviceIoControl(DeviceObject
, Irp
);
2596 else if (IrpSp
->MajorFunction
== IRP_MJ_POWER
)
2598 return NdisIPower(DeviceObject
, Irp
);
2600 NDIS_DbgPrint(MIN_TRACE
, ("Unexpected IRP MajorFunction 0x%x\n", IrpSp
->MajorFunction
));
2603 else if (DeviceObject
->DeviceType
== FILE_DEVICE_NETWORK
)
2605 PNDIS_M_DEVICE_BLOCK DeviceBlock
= DeviceObject
->DeviceExtension
;
2607 ASSERT(DeviceBlock
->DeviceObject
== DeviceObject
);
2609 if (DeviceBlock
->MajorFunction
[IrpSp
->MajorFunction
] != NULL
)
2611 return DeviceBlock
->MajorFunction
[IrpSp
->MajorFunction
](DeviceObject
, Irp
);
2619 Irp
->IoStatus
.Status
= STATUS_INVALID_DEVICE_REQUEST
;
2620 Irp
->IoStatus
.Information
= 0;
2622 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2624 return STATUS_INVALID_DEVICE_REQUEST
;
2632 NdisMRegisterMiniport(
2633 IN NDIS_HANDLE NdisWrapperHandle
,
2634 IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics
,
2635 IN UINT CharacteristicsLength
)
2637 * FUNCTION: Registers a miniport's MiniportXxx entry points with the NDIS library
2639 * NdisWrapperHandle = Pointer to handle returned by NdisMInitializeWrapper
2640 * MiniportCharacteristics = Pointer to a buffer with miniport characteristics
2641 * CharacteristicsLength = Number of bytes in characteristics buffer
2643 * Status of operation
2647 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2648 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2652 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2654 switch (MiniportCharacteristics
->MajorNdisVersion
)
2657 MinSize
= sizeof(NDIS30_MINIPORT_CHARACTERISTICS
);
2661 MinSize
= sizeof(NDIS40_MINIPORT_CHARACTERISTICS
);
2665 switch (MiniportCharacteristics
->MinorNdisVersion
)
2668 MinSize
= sizeof(NDIS50_MINIPORT_CHARACTERISTICS
);
2672 MinSize
= sizeof(NDIS51_MINIPORT_CHARACTERISTICS
);
2676 NDIS_DbgPrint(MIN_TRACE
, ("Bad 5.x minor characteristics version.\n"));
2677 return NDIS_STATUS_BAD_VERSION
;
2682 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics version.\n"));
2683 return NDIS_STATUS_BAD_VERSION
;
2686 NDIS_DbgPrint(MID_TRACE
, ("Initializing an NDIS %u.%u miniport\n",
2687 MiniportCharacteristics
->MajorNdisVersion
,
2688 MiniportCharacteristics
->MinorNdisVersion
));
2690 if (CharacteristicsLength
< MinSize
)
2692 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics length.\n"));
2693 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2696 /* Check if mandatory MiniportXxx functions are specified */
2697 if ((!MiniportCharacteristics
->HaltHandler
) ||
2698 (!MiniportCharacteristics
->InitializeHandler
)||
2699 (!MiniportCharacteristics
->ResetHandler
))
2701 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics.\n"));
2702 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2705 if (MiniportCharacteristics
->MajorNdisVersion
< 0x05)
2707 if ((!MiniportCharacteristics
->QueryInformationHandler
) ||
2708 (!MiniportCharacteristics
->SetInformationHandler
))
2710 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2711 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2716 if (((!MiniportCharacteristics
->QueryInformationHandler
) ||
2717 (!MiniportCharacteristics
->SetInformationHandler
)) &&
2718 (!MiniportCharacteristics
->CoRequestHandler
))
2720 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2721 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2725 if (MiniportCharacteristics
->MajorNdisVersion
== 0x03)
2727 if (!MiniportCharacteristics
->SendHandler
)
2729 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 3.0)\n"));
2730 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2733 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x04)
2736 if ((!MiniportCharacteristics
->SendHandler
) &&
2737 (!MiniportCharacteristics
->SendPacketsHandler
))
2739 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 4.0)\n"));
2740 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2743 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x05)
2745 /* TODO: Add more checks here */
2747 if ((!MiniportCharacteristics
->SendHandler
) &&
2748 (!MiniportCharacteristics
->SendPacketsHandler
) &&
2749 (!MiniportCharacteristics
->CoSendPacketsHandler
))
2751 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 5.0)\n"));
2752 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2756 RtlCopyMemory(&Miniport
->MiniportCharacteristics
, MiniportCharacteristics
, MinSize
);
2759 * NOTE: This is VERY unoptimal! Should we store the NDIS_M_DRIVER_BLOCK
2760 * structure in the driver extension or what?
2763 Status
= IoAllocateDriverObjectExtension(Miniport
->DriverObject
, (PVOID
)'NMID',
2764 sizeof(PNDIS_M_DRIVER_BLOCK
), (PVOID
*)&MiniportPtr
);
2765 if (!NT_SUCCESS(Status
))
2767 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate driver object extension.\n"));
2768 return NDIS_STATUS_RESOURCES
;
2771 *MiniportPtr
= Miniport
;
2773 /* We have to register for all of these so handler registered in NdisMRegisterDevice work */
2774 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
2776 Miniport
->DriverObject
->MajorFunction
[i
] = NdisGenericIrpHandler
;
2779 Miniport
->DriverObject
->DriverExtension
->AddDevice
= NdisIAddDevice
;
2781 return NDIS_STATUS_SUCCESS
;
2787 #undef NdisMResetComplete
2791 IN NDIS_HANDLE MiniportAdapterHandle
,
2792 IN NDIS_STATUS Status
,
2793 IN BOOLEAN AddressingReset
)
2795 MiniResetComplete(MiniportAdapterHandle
, Status
, AddressingReset
);
2801 #undef NdisMSendComplete
2805 IN NDIS_HANDLE MiniportAdapterHandle
,
2806 IN PNDIS_PACKET Packet
,
2807 IN NDIS_STATUS Status
)
2809 * FUNCTION: Forwards a message to the initiating protocol saying
2810 * that a packet was handled
2812 * NdisAdapterHandle = Handle input to MiniportInitialize
2813 * Packet = Pointer to NDIS packet that was sent
2814 * Status = Status of send operation
2817 MiniSendComplete(MiniportAdapterHandle
, Packet
, Status
);
2823 #undef NdisMSendResourcesAvailable
2826 NdisMSendResourcesAvailable(
2827 IN NDIS_HANDLE MiniportAdapterHandle
)
2829 MiniSendResourcesAvailable(MiniportAdapterHandle
);
2835 #undef NdisMTransferDataComplete
2838 NdisMTransferDataComplete(
2839 IN NDIS_HANDLE MiniportAdapterHandle
,
2840 IN PNDIS_PACKET Packet
,
2841 IN NDIS_STATUS Status
,
2842 IN UINT BytesTransferred
)
2844 MiniTransferDataComplete(MiniportAdapterHandle
, Packet
, Status
, BytesTransferred
);
2850 #undef NdisMSetAttributes
2854 IN NDIS_HANDLE MiniportAdapterHandle
,
2855 IN NDIS_HANDLE MiniportAdapterContext
,
2856 IN BOOLEAN BusMaster
,
2857 IN NDIS_INTERFACE_TYPE AdapterType
)
2859 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2861 * MiniportAdapterHandle = Handle input to MiniportInitialize
2862 * MiniportAdapterContext = Pointer to context information
2863 * BusMaster = Specifies TRUE if the caller's NIC is a busmaster DMA device
2864 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2867 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2868 NdisMSetAttributesEx(MiniportAdapterHandle
, MiniportAdapterContext
, 0,
2869 BusMaster
? NDIS_ATTRIBUTE_BUS_MASTER
: 0,
2878 NdisMSetAttributesEx(
2879 IN NDIS_HANDLE MiniportAdapterHandle
,
2880 IN NDIS_HANDLE MiniportAdapterContext
,
2881 IN UINT CheckForHangTimeInSeconds OPTIONAL
,
2882 IN ULONG AttributeFlags
,
2883 IN NDIS_INTERFACE_TYPE AdapterType
)
2885 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2887 * MiniportAdapterHandle = Handle input to MiniportInitialize
2888 * MiniportAdapterContext = Pointer to context information
2889 * CheckForHangTimeInSeconds = Specifies interval in seconds at which
2890 * MiniportCheckForHang should be called
2891 * AttributeFlags = Bitmask that indicates specific attributes
2892 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2895 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(MiniportAdapterHandle
);
2897 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2899 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
= MiniportAdapterContext
;
2900 Adapter
->NdisMiniportBlock
.Flags
= AttributeFlags
;
2901 Adapter
->NdisMiniportBlock
.AdapterType
= AdapterType
;
2902 if (CheckForHangTimeInSeconds
> 0)
2903 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= CheckForHangTimeInSeconds
;
2904 if (AttributeFlags
& NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER
)
2905 NDIS_DbgPrint(MIN_TRACE
, ("Intermediate drivers not supported yet.\n"));
2907 NDIS_DbgPrint(MID_TRACE
, ("Miniport attribute flags: 0x%x\n", AttributeFlags
));
2909 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
)
2911 NDIS_DbgPrint(MAX_TRACE
, ("Miniport set AdapterShutdownHandler in MiniportCharacteristics\n"));
2912 NdisMRegisterAdapterShutdownHandler(Adapter
,
2913 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
2914 Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
);
2924 IN ULONG MicrosecondsToSleep
)
2926 * FUNCTION: delay the thread's execution for MicrosecondsToSleep
2928 * MicrosecondsToSleep: duh...
2930 * - Because this is a blocking call, current IRQL must be < DISPATCH_LEVEL
2934 LARGE_INTEGER DueTime
;
2938 DueTime
.QuadPart
= (-1) * 10 * MicrosecondsToSleep
;
2940 KeInitializeTimer(&Timer
);
2941 KeSetTimer(&Timer
, DueTime
, 0);
2942 KeWaitForSingleObject(&Timer
, Executive
, KernelMode
, FALSE
, 0);
2950 NdisMSynchronizeWithInterrupt(
2951 IN PNDIS_MINIPORT_INTERRUPT Interrupt
,
2952 IN PVOID SynchronizeFunction
,
2953 IN PVOID SynchronizeContext
)
2955 return(KeSynchronizeExecution(Interrupt
->InterruptObject
,
2956 (PKSYNCHRONIZE_ROUTINE
)SynchronizeFunction
,
2957 SynchronizeContext
));
2966 IN NDIS_HANDLE LogHandle
,
2968 IN UINT LogBufferSize
)
2970 PUCHAR Buffer
= LogBuffer
;
2974 for (i
= 0; i
< LogBufferSize
; i
+= 16)
2976 DbgPrint("%08x |", i
);
2977 for (j
= 0; j
< 16; j
++)
2980 if (idx
< LogBufferSize
)
2981 DbgPrint(" %02x", Buffer
[idx
]);
2986 for (j
= 0; j
< 16; j
++)
2989 if (idx
== LogBufferSize
)
2991 if (Buffer
[idx
] >= ' ') /* FIXME: not portable! replace by if (isprint(Buffer[idx])) ? */
2992 DbgPrint("%c", Buffer
[idx
]);
2999 return NDIS_STATUS_FAILURE
;
3007 NdisTerminateWrapper(
3008 IN NDIS_HANDLE NdisWrapperHandle
,
3009 IN PVOID SystemSpecific
)
3011 * FUNCTION: Releases resources allocated by a call to NdisInitializeWrapper
3013 * NdisWrapperHandle = Handle returned by NdisInitializeWrapper (NDIS_M_DRIVER_BLOCK)
3014 * SystemSpecific = Always NULL
3017 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
3019 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3021 ExFreePool(Miniport
->RegistryPath
->Buffer
);
3022 ExFreePool(Miniport
->RegistryPath
);
3023 ExInterlockedRemoveEntryList(&Miniport
->ListEntry
, &MiniportListLock
);
3024 ExFreePool(Miniport
);
3033 NdisMQueryAdapterInstanceName(
3034 OUT PNDIS_STRING AdapterInstanceName
,
3035 IN NDIS_HANDLE MiniportAdapterHandle
)
3043 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
3044 UNICODE_STRING AdapterName
;
3046 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3048 AdapterName
.Length
= 0;
3049 AdapterName
.MaximumLength
= Adapter
->NdisMiniportBlock
.MiniportName
.MaximumLength
;
3050 AdapterName
.Buffer
= ExAllocatePool(PagedPool
, AdapterName
.MaximumLength
);
3051 if (!AdapterName
.Buffer
) {
3052 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
3053 return NDIS_STATUS_RESOURCES
;
3056 RtlCopyUnicodeString(&AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
);
3058 *AdapterInstanceName
= AdapterName
;
3060 return NDIS_STATUS_SUCCESS
;
3068 NdisDeregisterAdapterShutdownHandler(
3069 IN NDIS_HANDLE NdisAdapterHandle
)
3077 NdisMDeregisterAdapterShutdownHandler(NdisAdapterHandle
);
3086 NdisRegisterAdapterShutdownHandler(
3087 IN NDIS_HANDLE NdisAdapterHandle
,
3088 IN PVOID ShutdownContext
,
3089 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
3097 NdisMRegisterAdapterShutdownHandler(NdisAdapterHandle
,
3107 NdisMGetDeviceProperty(
3108 IN NDIS_HANDLE MiniportAdapterHandle
,
3109 IN OUT PDEVICE_OBJECT
*PhysicalDeviceObject OPTIONAL
,
3110 IN OUT PDEVICE_OBJECT
*FunctionalDeviceObject OPTIONAL
,
3111 IN OUT PDEVICE_OBJECT
*NextDeviceObject OPTIONAL
,
3112 IN OUT PCM_RESOURCE_LIST
*AllocatedResources OPTIONAL
,
3113 IN OUT PCM_RESOURCE_LIST
*AllocatedResourcesTranslated OPTIONAL
)
3121 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
3123 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
3125 if (PhysicalDeviceObject
!= NULL
)
3126 *PhysicalDeviceObject
= Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
;
3128 if (FunctionalDeviceObject
!= NULL
)
3129 *FunctionalDeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
3131 if (NextDeviceObject
!= NULL
)
3132 *NextDeviceObject
= Adapter
->NdisMiniportBlock
.NextDeviceObject
;
3134 if (AllocatedResources
!= NULL
)
3135 *AllocatedResources
= Adapter
->NdisMiniportBlock
.AllocatedResources
;
3137 if (AllocatedResourcesTranslated
!= NULL
)
3138 *AllocatedResourcesTranslated
= Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
;
3146 NdisMRegisterUnloadHandler(
3147 IN NDIS_HANDLE NdisWrapperHandle
,
3148 IN PDRIVER_UNLOAD UnloadHandler
)
3156 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
3158 NDIS_DbgPrint(MAX_TRACE
, ("Miniport registered unload handler\n"));
3160 DriverBlock
->DriverObject
->DriverUnload
= UnloadHandler
;
3168 NdisMRegisterDevice(
3169 IN NDIS_HANDLE NdisWrapperHandle
,
3170 IN PNDIS_STRING DeviceName
,
3171 IN PNDIS_STRING SymbolicName
,
3172 IN PDRIVER_DISPATCH MajorFunctions
[],
3173 OUT PDEVICE_OBJECT
*pDeviceObject
,
3174 OUT NDIS_HANDLE
*NdisDeviceHandle
)
3182 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
3183 PNDIS_M_DEVICE_BLOCK DeviceBlock
;
3184 PDEVICE_OBJECT DeviceObject
;
3188 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
3190 Status
= IoCreateDevice(DriverBlock
->DriverObject
,
3191 sizeof(NDIS_M_DEVICE_BLOCK
),
3193 FILE_DEVICE_NETWORK
,
3198 if (!NT_SUCCESS(Status
))
3200 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateDevice failed (%x)\n", Status
));
3204 Status
= IoCreateSymbolicLink(SymbolicName
, DeviceName
);
3206 if (!NT_SUCCESS(Status
))
3208 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateSymbolicLink failed (%x)\n", Status
));
3209 IoDeleteDevice(DeviceObject
);
3213 DeviceBlock
= DeviceObject
->DeviceExtension
;
3217 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
3218 IoDeleteDevice(DeviceObject
);
3219 IoDeleteSymbolicLink(SymbolicName
);
3220 return NDIS_STATUS_RESOURCES
;
3223 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
3224 DeviceBlock
->MajorFunction
[i
] = MajorFunctions
[i
];
3226 DeviceBlock
->DeviceObject
= DeviceObject
;
3227 DeviceBlock
->SymbolicName
= SymbolicName
;
3229 *pDeviceObject
= DeviceObject
;
3230 *NdisDeviceHandle
= DeviceBlock
;
3232 return NDIS_STATUS_SUCCESS
;
3240 NdisMDeregisterDevice(
3241 IN NDIS_HANDLE NdisDeviceHandle
)
3249 PNDIS_M_DEVICE_BLOCK DeviceBlock
= NdisDeviceHandle
;
3251 IoDeleteDevice(DeviceBlock
->DeviceObject
);
3253 IoDeleteSymbolicLink(DeviceBlock
->SymbolicName
);
3255 return NDIS_STATUS_SUCCESS
;
3263 NdisQueryAdapterInstanceName(
3264 OUT PNDIS_STRING AdapterInstanceName
,
3265 IN NDIS_HANDLE NdisBindingHandle
)
3273 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3274 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3276 return NdisMQueryAdapterInstanceName(AdapterInstanceName
,
3285 NdisCompletePnPEvent(
3286 IN NDIS_STATUS Status
,
3287 IN NDIS_HANDLE NdisBindingHandle
,
3288 IN PNET_PNP_EVENT NetPnPEvent
)
3296 PIRP Irp
= (PIRP
)NetPnPEvent
->NdisReserved
[0];
3297 PLIST_ENTRY CurrentEntry
= (PLIST_ENTRY
)NetPnPEvent
->NdisReserved
[1];
3298 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3299 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3300 NDIS_STATUS NdisStatus
;
3302 if (Status
!= NDIS_STATUS_SUCCESS
)
3304 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3305 ExFreePool(NetPnPEvent
);
3306 Irp
->IoStatus
.Status
= Status
;
3307 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3311 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
3313 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
3315 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.PnPEventHandler
)(
3316 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
3319 if (NdisStatus
== NDIS_STATUS_PENDING
)
3321 NetPnPEvent
->NdisReserved
[1] = (ULONG_PTR
)CurrentEntry
->Flink
;
3324 else if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
3326 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3327 ExFreePool(NetPnPEvent
);
3328 Irp
->IoStatus
.Status
= NdisStatus
;
3329 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3333 CurrentEntry
= CurrentEntry
->Flink
;
3336 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3337 ExFreePool(NetPnPEvent
);
3339 Irp
->IoStatus
.Status
= NDIS_STATUS_SUCCESS
;
3340 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3348 NdisCancelSendPackets(
3349 IN NDIS_HANDLE NdisBindingHandle
,
3352 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3353 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3355 NDIS_DbgPrint(MAX_TRACE
, ("Called for ID %x.\n", CancelId
));
3357 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)
3359 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)(
3360 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
3371 NdisIMGetBindingContext(
3372 IN NDIS_HANDLE NdisBindingHandle
)
3380 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3381 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3383 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3385 return Adapter
->NdisMiniportBlock
.DeviceContext
;
3394 NdisIMGetDeviceContext(
3395 IN NDIS_HANDLE MiniportAdapterHandle
)
3403 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
3405 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3407 return Adapter
->NdisMiniportBlock
.DeviceContext
;