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 if( MacBlock
->Binding
->RequestCompleteHandler
) {
499 (*MacBlock
->Binding
->RequestCompleteHandler
)(
500 MacBlock
->Binding
->ProtocolBindingContext
,
505 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
506 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
507 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
508 KeLowerIrql(OldIrql
);
510 MiniWorkItemComplete(Adapter
, NdisWorkItemRequest
);
515 IN NDIS_HANDLE MiniportAdapterHandle
,
516 IN PNDIS_PACKET Packet
,
517 IN NDIS_STATUS Status
)
519 * FUNCTION: Forwards a message to the initiating protocol saying
520 * that a packet was handled
522 * NdisAdapterHandle = Handle input to MiniportInitialize
523 * Packet = Pointer to NDIS packet that was sent
524 * Status = Status of send operation
527 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
528 PADAPTER_BINDING AdapterBinding
;
530 PSCATTER_GATHER_LIST SGList
;
532 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
534 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
536 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
538 if (Adapter
->NdisMiniportBlock
.ScatterGatherListSize
!= 0)
540 NDIS_DbgPrint(MAX_TRACE
, ("Freeing Scatter/Gather list\n"));
542 SGList
= NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
543 ScatterGatherListPacketInfo
);
545 Adapter
->NdisMiniportBlock
.SystemAdapterObject
->
546 DmaOperations
->PutScatterGatherList(
547 Adapter
->NdisMiniportBlock
.SystemAdapterObject
,
551 NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
552 ScatterGatherListPacketInfo
) = NULL
;
555 (*AdapterBinding
->ProtocolBinding
->Chars
.SendCompleteHandler
)(
556 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
560 KeLowerIrql(OldIrql
);
562 MiniWorkItemComplete(Adapter
, NdisWorkItemSend
);
567 MiniSendResourcesAvailable(
568 IN NDIS_HANDLE MiniportAdapterHandle
)
570 /* Run the work if anything is waiting */
571 MiniWorkItemComplete((PLOGICAL_ADAPTER
)MiniportAdapterHandle
, NdisWorkItemSend
);
576 MiniTransferDataComplete(
577 IN NDIS_HANDLE MiniportAdapterHandle
,
578 IN PNDIS_PACKET Packet
,
579 IN NDIS_STATUS Status
,
580 IN UINT BytesTransferred
)
582 PADAPTER_BINDING AdapterBinding
;
585 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
587 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
589 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
590 (*AdapterBinding
->ProtocolBinding
->Chars
.TransferDataCompleteHandler
)(
591 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
595 KeLowerIrql(OldIrql
);
600 MiniAdapterHasAddress(
601 PLOGICAL_ADAPTER Adapter
,
604 * FUNCTION: Determines whether a packet has the same destination address as an adapter
606 * Adapter = Pointer to logical adapter object
607 * Packet = Pointer to NDIS packet
609 * TRUE if the destination address is that of the adapter, FALSE if not
615 PNDIS_BUFFER NdisBuffer
;
618 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
623 NDIS_DbgPrint(MIN_TRACE
, ("Adapter object was null\n"));
629 NDIS_DbgPrint(MIN_TRACE
, ("Packet was null\n"));
634 NdisQueryPacket(Packet
, NULL
, NULL
, &NdisBuffer
, NULL
);
638 NDIS_DbgPrint(MIN_TRACE
, ("Packet contains no buffers.\n"));
642 NdisQueryBuffer(NdisBuffer
, (PVOID
)&Start2
, &BufferLength
);
644 /* FIXME: Should handle fragmented packets */
646 switch (Adapter
->NdisMiniportBlock
.MediaType
)
648 case NdisMedium802_3
:
649 Length
= ETH_LENGTH_OF_ADDRESS
;
650 /* Destination address is the first field */
654 NDIS_DbgPrint(MIN_TRACE
, ("Adapter has unsupported media type (0x%X).\n", Adapter
->NdisMiniportBlock
.MediaType
));
658 if (BufferLength
< Length
)
660 NDIS_DbgPrint(MIN_TRACE
, ("Buffer is too small.\n"));
664 Start1
= (PUCHAR
)&Adapter
->Address
;
665 NDIS_DbgPrint(MAX_TRACE
, ("packet address: %x:%x:%x:%x:%x:%x adapter address: %x:%x:%x:%x:%x:%x\n",
666 *((char *)Start1
), *(((char *)Start1
)+1), *(((char *)Start1
)+2), *(((char *)Start1
)+3), *(((char *)Start1
)+4), *(((char *)Start1
)+5),
667 *((char *)Start2
), *(((char *)Start2
)+1), *(((char *)Start2
)+2), *(((char *)Start2
)+3), *(((char *)Start2
)+4), *(((char *)Start2
)+5)));
669 return (RtlCompareMemory((PVOID
)Start1
, (PVOID
)Start2
, Length
) == Length
);
675 PNDIS_STRING AdapterName
)
677 * FUNCTION: Finds an adapter object by name
679 * AdapterName = Pointer to name of adapter
681 * Pointer to logical adapter object, or NULL if none was found.
682 * If found, the adapter is referenced for the caller. The caller
683 * is responsible for dereferencing after use
687 PLIST_ENTRY CurrentEntry
;
688 PLOGICAL_ADAPTER Adapter
= 0;
692 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
694 if(IsListEmpty(&AdapterListHead
))
696 NDIS_DbgPrint(MIN_TRACE
, ("No registered miniports for protocol to bind to\n"));
700 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterName = %wZ\n", AdapterName
));
702 KeAcquireSpinLock(&AdapterListLock
, &OldIrql
);
704 CurrentEntry
= AdapterListHead
.Flink
;
706 while (CurrentEntry
!= &AdapterListHead
)
708 Adapter
= CONTAINING_RECORD(CurrentEntry
, LOGICAL_ADAPTER
, ListEntry
);
712 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Examining adapter 0x%lx\n", Adapter
));
714 /* We're technically not allowed to call this above PASSIVE_LEVEL, but it doesn't break
715 * right now and I'd rather use a working API than reimplement it here */
716 if (RtlCompareUnicodeString(AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
, TRUE
) == 0)
722 CurrentEntry
= CurrentEntry
->Flink
;
725 KeReleaseSpinLock(&AdapterListLock
, OldIrql
);
729 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Leaving. Adapter found at 0x%x\n", Adapter
));
733 NDIS_DbgPrint(MIN_TRACE
, ("Leaving (adapter not found for %wZ).\n", AdapterName
));
741 PLOGICAL_ADAPTER Adapter
,
747 NDIS_STATUS NdisStatus
;
748 PNDIS_REQUEST NdisRequest
;
750 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
752 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
754 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
755 return NDIS_STATUS_RESOURCES
;
758 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
760 NdisRequest
->RequestType
= NdisRequestSetInformation
;
761 NdisRequest
->DATA
.SET_INFORMATION
.Oid
= Oid
;
762 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
= Buffer
;
763 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
= Size
;
765 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
767 /* FIXME: Wait in pending case! */
769 ASSERT(NdisStatus
!= NDIS_STATUS_PENDING
);
771 *BytesRead
= NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
;
773 ExFreePool(NdisRequest
);
779 MiniQueryInformation(
780 PLOGICAL_ADAPTER Adapter
,
786 * FUNCTION: Queries a logical adapter for properties
788 * Adapter = Pointer to the logical adapter object to query
789 * Oid = Specifies the Object ID to query for
790 * Size = Size of the passed buffer
791 * Buffer = Buffer for the output
792 * BytesWritten = Address of buffer to place number of bytes written
794 * Status of operation
797 NDIS_STATUS NdisStatus
;
798 PNDIS_REQUEST NdisRequest
;
800 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
802 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
804 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
805 return NDIS_STATUS_RESOURCES
;
808 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
810 NdisRequest
->RequestType
= NdisRequestQueryInformation
;
811 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
= Oid
;
812 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
= Buffer
;
813 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
= Size
;
815 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
817 /* FIXME: Wait in pending case! */
819 ASSERT(NdisStatus
!= NDIS_STATUS_PENDING
);
821 *BytesWritten
= NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
;
823 ExFreePool(NdisRequest
);
829 MiniCheckForHang( PLOGICAL_ADAPTER Adapter
)
831 * FUNCTION: Checks to see if the miniport is hung
833 * Adapter = Pointer to the logical adapter object
835 * TRUE if the miniport is hung
836 * FALSE if the miniport is not hung
842 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
843 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)
844 Ret
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)(
845 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
);
846 KeLowerIrql(OldIrql
);
852 MiniDoAddressingReset(PLOGICAL_ADAPTER Adapter
)
856 MiniSetInformation(Adapter
,
857 OID_GEN_CURRENT_LOOKAHEAD
,
859 &Adapter
->NdisMiniportBlock
.CurrentLookahead
,
862 /* FIXME: Set more stuff */
867 PLOGICAL_ADAPTER Adapter
)
869 * FUNCTION: Resets the miniport
871 * Adapter = Pointer to the logical adapter object
873 * Status of the operation
878 BOOLEAN AddressingReset
= TRUE
;
880 if (MiniIsBusy(Adapter
, NdisWorkItemResetRequested
)) {
881 MiniQueueWorkItem(Adapter
, NdisWorkItemResetRequested
, NULL
, FALSE
);
882 return NDIS_STATUS_PENDING
;
885 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
886 NdisMIndicateStatusComplete(Adapter
);
888 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
889 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
890 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
893 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
894 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
895 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
897 KeLowerIrql(OldIrql
);
899 if (Status
!= NDIS_STATUS_PENDING
) {
901 MiniDoAddressingReset(Adapter
);
903 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
904 NdisMIndicateStatusComplete(Adapter
);
906 MiniWorkItemComplete(Adapter
, NdisWorkItemResetRequested
);
915 PVOID DeferredContext
,
916 PVOID SystemArgument1
,
917 PVOID SystemArgument2
)
919 PLOGICAL_ADAPTER Adapter
= DeferredContext
;
921 if (MiniCheckForHang(Adapter
)) {
922 NDIS_DbgPrint(MIN_TRACE
, ("Miniport detected adapter hang\n"));
928 MiniWorkItemComplete(
929 PLOGICAL_ADAPTER Adapter
,
930 NDIS_WORK_ITEM_TYPE WorkItemType
)
932 PIO_WORKITEM IoWorkItem
;
934 /* Check if there's anything queued to run after this work item */
935 if (!MiniIsBusy(Adapter
, WorkItemType
))
938 /* There is, so fire the worker */
939 IoWorkItem
= IoAllocateWorkItem(Adapter
->NdisMiniportBlock
.DeviceObject
);
941 IoQueueWorkItem(IoWorkItem
, MiniportWorker
, DelayedWorkQueue
, IoWorkItem
);
947 PLOGICAL_ADAPTER Adapter
,
948 NDIS_WORK_ITEM_TYPE WorkItemType
,
949 PVOID WorkItemContext
,
952 * FUNCTION: Queues a work item for execution at a later time
954 * Adapter = Pointer to the logical adapter object to queue work item on
955 * WorkItemType = Type of work item to queue
956 * WorkItemContext = Pointer to context information for work item
958 * Status of operation
961 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
964 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
968 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
971 if (WorkItemType
== NdisWorkItemSend
)
973 NDIS_DbgPrint(MIN_TRACE
, ("Requeuing failed packet (%x).\n", WorkItemContext
));
974 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= WorkItemContext
;
978 //This should never happen
984 MiniportWorkItem
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_MINIPORT_WORK_ITEM
));
985 if (!MiniportWorkItem
)
987 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
988 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
992 MiniportWorkItem
->WorkItemType
= WorkItemType
;
993 MiniportWorkItem
->WorkItemContext
= WorkItemContext
;
995 /* safe due to adapter lock held */
996 MiniportWorkItem
->Link
.Next
= NULL
;
997 if (!Adapter
->WorkQueueHead
)
999 Adapter
->WorkQueueHead
= MiniportWorkItem
;
1000 Adapter
->WorkQueueTail
= MiniportWorkItem
;
1004 Adapter
->WorkQueueTail
->Link
.Next
= (PSINGLE_LIST_ENTRY
)MiniportWorkItem
;
1005 Adapter
->WorkQueueTail
= MiniportWorkItem
;
1009 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1014 MiniDequeueWorkItem(
1015 PLOGICAL_ADAPTER Adapter
,
1016 NDIS_WORK_ITEM_TYPE
*WorkItemType
,
1017 PVOID
*WorkItemContext
)
1019 * FUNCTION: Dequeues a work item from the work queue of a logical adapter
1021 * Adapter = Pointer to the logical adapter object to dequeue work item from
1022 * AdapterBinding = Address of buffer for adapter binding for this request
1023 * WorkItemType = Address of buffer for work item type
1024 * WorkItemContext = Address of buffer for pointer to context information
1026 * Adapter lock must be held when called
1028 * Status of operation
1031 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
1032 PNDIS_PACKET Packet
;
1034 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1036 MiniportWorkItem
= Adapter
->WorkQueueHead
;
1038 if ((Packet
= Adapter
->NdisMiniportBlock
.FirstPendingPacket
))
1040 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= NULL
;
1042 *WorkItemType
= NdisWorkItemSend
;
1043 *WorkItemContext
= Packet
;
1045 return NDIS_STATUS_SUCCESS
;
1047 else if (MiniportWorkItem
)
1049 /* safe due to adapter lock held */
1050 Adapter
->WorkQueueHead
= (PNDIS_MINIPORT_WORK_ITEM
)MiniportWorkItem
->Link
.Next
;
1052 if (MiniportWorkItem
== Adapter
->WorkQueueTail
)
1053 Adapter
->WorkQueueTail
= NULL
;
1055 *WorkItemType
= MiniportWorkItem
->WorkItemType
;
1056 *WorkItemContext
= MiniportWorkItem
->WorkItemContext
;
1058 ExFreePool(MiniportWorkItem
);
1060 return NDIS_STATUS_SUCCESS
;
1064 NDIS_DbgPrint(MIN_TRACE
, ("No work item to dequeue\n"));
1066 return NDIS_STATUS_FAILURE
;
1072 PLOGICAL_ADAPTER Adapter
,
1073 PNDIS_REQUEST NdisRequest
)
1075 * FUNCTION: Sends a request to a miniport
1077 * AdapterBinding = Pointer to binding used in the request
1078 * NdisRequest = Pointer to NDIS request structure describing request
1080 * Status of operation
1085 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1087 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1089 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1090 Adapter
->NdisMiniportBlock
.PendingRequest
= NdisRequest
;
1091 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1093 if (!Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)
1095 switch (NdisRequest
->RequestType
)
1097 case NdisRequestQueryInformation
:
1098 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.QueryInformationHandler
)(
1099 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1100 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
,
1101 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
,
1102 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
,
1103 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
,
1104 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesNeeded
);
1107 case NdisRequestSetInformation
:
1108 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SetInformationHandler
)(
1109 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1110 NdisRequest
->DATA
.SET_INFORMATION
.Oid
,
1111 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
,
1112 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
,
1113 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
,
1114 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesNeeded
);
1118 NDIS_DbgPrint(MIN_TRACE
, ("Bad request type\n"));
1119 Status
= NDIS_STATUS_FAILURE
;
1124 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)(
1125 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1130 if (Status
!= NDIS_STATUS_PENDING
) {
1131 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1132 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
1133 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1136 KeLowerIrql(OldIrql
);
1138 if (Status
!= NDIS_STATUS_PENDING
) {
1139 MiniWorkItemComplete(Adapter
, NdisWorkItemRequest
);
1148 #undef NdisMSetInformationComplete
1151 NdisMSetInformationComplete(
1152 IN NDIS_HANDLE MiniportAdapterHandle
,
1153 IN NDIS_STATUS Status
)
1155 PLOGICAL_ADAPTER Adapter
=
1156 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
1159 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1160 if (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)
1161 (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)(MiniportAdapterHandle
, Status
);
1162 KeLowerIrql(OldIrql
);
1168 #undef NdisMQueryInformationComplete
1171 NdisMQueryInformationComplete(
1172 IN NDIS_HANDLE MiniportAdapterHandle
,
1173 IN NDIS_STATUS Status
)
1175 PLOGICAL_ADAPTER Adapter
=
1176 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
1179 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1180 if( Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)
1181 (Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)(MiniportAdapterHandle
, Status
);
1182 KeLowerIrql(OldIrql
);
1187 MiniportWorker(IN PDEVICE_OBJECT DeviceObject
, IN PVOID Context
)
1189 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
1190 KIRQL OldIrql
, RaiseOldIrql
;
1191 NDIS_STATUS NdisStatus
;
1192 PVOID WorkItemContext
;
1193 NDIS_WORK_ITEM_TYPE WorkItemType
;
1194 BOOLEAN AddressingReset
;
1196 IoFreeWorkItem((PIO_WORKITEM
)Context
);
1198 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1202 (Adapter
, &WorkItemType
, &WorkItemContext
);
1204 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1206 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1208 switch (WorkItemType
)
1210 case NdisWorkItemSend
:
1212 * called by ProSend when protocols want to send packets to the miniport
1215 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
1217 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1219 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1220 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1221 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1222 NdisStatus
= NDIS_STATUS_PENDING
;
1226 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
1227 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1229 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1230 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1231 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1233 KeLowerIrql(RaiseOldIrql
);
1235 NdisStatus
= NDIS_GET_PACKET_STATUS((PNDIS_PACKET
)WorkItemContext
);
1236 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1237 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1244 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1246 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1247 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1248 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1249 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1250 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1254 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
1255 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1256 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1257 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1258 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1259 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1260 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1261 KeLowerIrql(RaiseOldIrql
);
1262 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1263 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1269 if( NdisStatus
!= NDIS_STATUS_PENDING
) {
1271 ( Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1275 case NdisWorkItemSendLoopback
:
1277 * called by ProSend when protocols want to send loopback packets
1279 /* XXX atm ProIndicatePacket sends a packet up via the loopback adapter only */
1280 NdisStatus
= ProIndicatePacket(Adapter
, (PNDIS_PACKET
)WorkItemContext
);
1282 if( NdisStatus
!= NDIS_STATUS_PENDING
)
1283 MiniSendComplete((NDIS_HANDLE
)Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1286 case NdisWorkItemReturnPackets
:
1289 case NdisWorkItemResetRequested
:
1290 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
1291 NdisMIndicateStatusComplete(Adapter
);
1293 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1294 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
1295 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1298 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1299 Adapter
->NdisMiniportBlock
.ResetStatus
= NdisStatus
;
1300 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1302 KeLowerIrql(OldIrql
);
1304 if (NdisStatus
!= NDIS_STATUS_PENDING
)
1305 MiniResetComplete(Adapter
, NdisStatus
, AddressingReset
);
1308 case NdisWorkItemResetInProgress
:
1311 case NdisWorkItemMiniportCallback
:
1314 case NdisWorkItemRequest
:
1315 NdisStatus
= MiniDoRequest(Adapter
, (PNDIS_REQUEST
)WorkItemContext
);
1317 if (NdisStatus
== NDIS_STATUS_PENDING
)
1320 switch (((PNDIS_REQUEST
)WorkItemContext
)->RequestType
)
1322 case NdisRequestQueryInformation
:
1323 NdisMQueryInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1326 case NdisRequestSetInformation
:
1327 NdisMSetInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1331 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS request type.\n"));
1337 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS work item type (%d).\n", WorkItemType
));
1347 IN NDIS_HANDLE MiniportHandle
,
1348 IN NDIS_STATUS GeneralStatus
,
1349 IN PVOID StatusBuffer
,
1350 IN UINT StatusBufferSize
)
1352 PLOGICAL_ADAPTER Adapter
= MiniportHandle
;
1353 PLIST_ENTRY CurrentEntry
;
1354 PADAPTER_BINDING AdapterBinding
;
1357 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1359 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1361 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1363 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1365 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusHandler
)(
1366 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
1371 CurrentEntry
= CurrentEntry
->Flink
;
1374 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1380 IN NDIS_HANDLE MiniportAdapterHandle
)
1382 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1383 PLIST_ENTRY CurrentEntry
;
1384 PADAPTER_BINDING AdapterBinding
;
1387 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1389 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1391 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1393 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1395 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusCompleteHandler
)(
1396 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
);
1398 CurrentEntry
= CurrentEntry
->Flink
;
1401 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1410 IN NDIS_HANDLE LogHandle
)
1412 PNDIS_LOG Log
= (PNDIS_LOG
)LogHandle
;
1413 PNDIS_MINIPORT_BLOCK Miniport
= Log
->Miniport
;
1416 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1418 KeAcquireSpinLock(&(Miniport
)->Lock
, &OldIrql
);
1419 Miniport
->Log
= NULL
;
1420 KeReleaseSpinLock(&(Miniport
)->Lock
, OldIrql
);
1431 IN NDIS_HANDLE MiniportAdapterHandle
,
1433 OUT PNDIS_HANDLE LogHandle
)
1435 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1439 NDIS_DbgPrint(MAX_TRACE
, ("called: MiniportAdapterHandle 0x%x, Size %ld\n", MiniportAdapterHandle
, Size
));
1441 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1443 if (Adapter
->NdisMiniportBlock
.Log
)
1446 return NDIS_STATUS_FAILURE
;
1449 Log
= ExAllocatePool(NonPagedPool
, Size
+ sizeof(NDIS_LOG
));
1453 return NDIS_STATUS_RESOURCES
;
1456 Adapter
->NdisMiniportBlock
.Log
= Log
;
1458 KeInitializeSpinLock(&Log
->LogLock
);
1460 Log
->Miniport
= &Adapter
->NdisMiniportBlock
;
1461 Log
->TotalSize
= Size
;
1462 Log
->CurrentSize
= 0;
1469 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1471 return NDIS_STATUS_SUCCESS
;
1479 NdisMDeregisterAdapterShutdownHandler(
1480 IN NDIS_HANDLE MiniportHandle
)
1482 * FUNCTION: de-registers a shutdown handler
1483 * ARGUMENTS: MiniportHandle: Handle passed into MiniportInitialize
1486 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1488 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1490 if(Adapter
->BugcheckContext
->ShutdownHandler
) {
1491 KeDeregisterBugCheckCallback(Adapter
->BugcheckContext
->CallbackRecord
);
1492 IoUnregisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1502 IN NDIS_HANDLE LogHandle
)
1504 PNDIS_LOG Log
= (PNDIS_LOG
) LogHandle
;
1507 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1510 KeAcquireSpinLock(&Log
->LogLock
, &OldIrql
);
1512 /* Set buffers size */
1513 Log
->CurrentSize
= 0;
1518 KeReleaseSpinLock(&Log
->LogLock
, OldIrql
);
1524 #undef NdisMIndicateStatus
1527 NdisMIndicateStatus(
1528 IN NDIS_HANDLE MiniportAdapterHandle
,
1529 IN NDIS_STATUS GeneralStatus
,
1530 IN PVOID StatusBuffer
,
1531 IN UINT StatusBufferSize
)
1533 MiniStatus(MiniportAdapterHandle
, GeneralStatus
, StatusBuffer
, StatusBufferSize
);
1539 #undef NdisMIndicateStatusComplete
1542 NdisMIndicateStatusComplete(
1543 IN NDIS_HANDLE MiniportAdapterHandle
)
1545 MiniStatusComplete(MiniportAdapterHandle
);
1553 NdisInitializeWrapper(
1554 OUT PNDIS_HANDLE NdisWrapperHandle
,
1555 IN PVOID SystemSpecific1
,
1556 IN PVOID SystemSpecific2
,
1557 IN PVOID SystemSpecific3
)
1559 * FUNCTION: Notifies the NDIS library that a new miniport is initializing
1561 * NdisWrapperHandle = Address of buffer to place NDIS wrapper handle
1562 * SystemSpecific1 = Pointer to the driver's driver object
1563 * SystemSpecific2 = Pointer to the driver's registry path
1564 * SystemSpecific3 = Always NULL
1566 * - SystemSpecific2 goes invalid so we copy it
1569 PNDIS_M_DRIVER_BLOCK Miniport
;
1570 PUNICODE_STRING RegistryPath
;
1571 WCHAR
*RegistryBuffer
;
1573 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1575 ASSERT(NdisWrapperHandle
);
1577 *NdisWrapperHandle
= NULL
;
1579 #if BREAK_ON_MINIPORT_INIT
1583 Miniport
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DRIVER_BLOCK
));
1587 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1591 RtlZeroMemory(Miniport
, sizeof(NDIS_M_DRIVER_BLOCK
));
1593 KeInitializeSpinLock(&Miniport
->Lock
);
1595 Miniport
->DriverObject
= (PDRIVER_OBJECT
)SystemSpecific1
;
1597 /* set the miniport's driver registry path */
1598 RegistryPath
= ExAllocatePool(PagedPool
, sizeof(UNICODE_STRING
));
1601 ExFreePool(Miniport
);
1602 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1606 RegistryPath
->Length
= ((PUNICODE_STRING
)SystemSpecific2
)->Length
;
1607 RegistryPath
->MaximumLength
= RegistryPath
->Length
+ sizeof(WCHAR
); /* room for 0-term */
1609 RegistryBuffer
= ExAllocatePool(PagedPool
, RegistryPath
->MaximumLength
);
1612 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1613 ExFreePool(Miniport
);
1614 ExFreePool(RegistryPath
);
1618 RtlCopyMemory(RegistryBuffer
, ((PUNICODE_STRING
)SystemSpecific2
)->Buffer
, RegistryPath
->Length
);
1619 RegistryBuffer
[RegistryPath
->Length
/sizeof(WCHAR
)] = 0;
1621 RegistryPath
->Buffer
= RegistryBuffer
;
1622 Miniport
->RegistryPath
= RegistryPath
;
1624 InitializeListHead(&Miniport
->DeviceList
);
1626 /* Put miniport in global miniport list */
1627 ExInterlockedInsertTailList(&MiniportListHead
, &Miniport
->ListEntry
, &MiniportListLock
);
1629 *NdisWrapperHandle
= Miniport
;
1632 VOID NTAPI
NdisIBugcheckCallback(
1636 * FUNCTION: Internal callback for handling bugchecks - calls adapter's shutdown handler
1638 * Buffer: Pointer to a bugcheck callback context
1642 PMINIPORT_BUGCHECK_CONTEXT Context
= (PMINIPORT_BUGCHECK_CONTEXT
)Buffer
;
1643 ADAPTER_SHUTDOWN_HANDLER sh
= (ADAPTER_SHUTDOWN_HANDLER
)Context
->ShutdownHandler
;
1645 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1648 sh(Context
->DriverContext
);
1656 NdisMRegisterAdapterShutdownHandler(
1657 IN NDIS_HANDLE MiniportHandle
,
1658 IN PVOID ShutdownContext
,
1659 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
1661 * FUNCTION: Register a shutdown handler for an adapter
1663 * MiniportHandle: Handle originally passed into MiniportInitialize
1664 * ShutdownContext: Pre-initialized bugcheck context
1665 * ShutdownHandler: Function to call to handle the bugcheck
1667 * - I'm not sure about ShutdownContext
1670 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1671 PMINIPORT_BUGCHECK_CONTEXT BugcheckContext
;
1673 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1675 BugcheckContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_BUGCHECK_CONTEXT
));
1676 if(!BugcheckContext
)
1678 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1682 BugcheckContext
->ShutdownHandler
= ShutdownHandler
;
1683 BugcheckContext
->DriverContext
= ShutdownContext
;
1685 BugcheckContext
->CallbackRecord
= ExAllocatePool(NonPagedPool
, sizeof(KBUGCHECK_CALLBACK_RECORD
));
1686 if (!BugcheckContext
->CallbackRecord
) {
1687 ExFreePool(BugcheckContext
);
1691 Adapter
->BugcheckContext
= BugcheckContext
;
1693 KeInitializeCallbackRecord(BugcheckContext
->CallbackRecord
);
1695 KeRegisterBugCheckCallback(BugcheckContext
->CallbackRecord
, NdisIBugcheckCallback
,
1696 BugcheckContext
, sizeof(*BugcheckContext
), (PUCHAR
)"Ndis Miniport");
1698 IoRegisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1703 PLOGICAL_ADAPTER Adapter
,
1704 NDIS_OID AddressOID
)
1706 * FUNCTION: Queries miniport for information
1708 * Adapter = Pointer to logical adapter
1709 * AddressOID = OID to use to query for current address
1711 * Status of operation
1715 NDIS_STATUS NdisStatus
;
1717 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1719 /* Get MAC options for adapter */
1720 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAC_OPTIONS
, sizeof(UINT
),
1721 &Adapter
->NdisMiniportBlock
.MacOptions
,
1724 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1726 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAC_OPTIONS failed. NdisStatus (0x%X).\n", NdisStatus
));
1730 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MacOptions (0x%X).\n", Adapter
->NdisMiniportBlock
.MacOptions
));
1732 /* Get current hardware address of adapter */
1733 NdisStatus
= MiniQueryInformation(Adapter
, AddressOID
, Adapter
->AddressLength
,
1734 &Adapter
->Address
, &BytesWritten
);
1736 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1738 NDIS_DbgPrint(MIN_TRACE
, ("Address OID (0x%X) failed. NdisStatus (0x%X).\n", AddressOID
, NdisStatus
));
1746 PUCHAR A
= (PUCHAR
)&Adapter
->Address
.Type
.Medium802_3
;
1748 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]));
1752 /* Get maximum lookahead buffer size of adapter */
1753 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_LOOKAHEAD
, sizeof(ULONG
),
1754 &Adapter
->NdisMiniportBlock
.MaximumLookahead
, &BytesWritten
);
1756 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1758 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1762 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MaxLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.MaximumLookahead
));
1764 /* Get current lookahead buffer size of adapter */
1765 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_CURRENT_LOOKAHEAD
, sizeof(ULONG
),
1766 &Adapter
->NdisMiniportBlock
.CurrentLookahead
, &BytesWritten
);
1768 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1770 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_CURRENT_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1774 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_SEND_PACKETS
, sizeof(ULONG
),
1775 &Adapter
->NdisMiniportBlock
.MaxSendPackets
, &BytesWritten
);
1777 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1779 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_SEND_PACKETS failed. NdisStatus (0x%X).\n", NdisStatus
));
1781 /* Set it to 1 if it fails because some drivers don't support this (?)*/
1782 Adapter
->NdisMiniportBlock
.MaxSendPackets
= 1;
1785 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.CurrentLookahead
));
1787 return STATUS_SUCCESS
;
1792 NdisIForwardIrpAndWaitCompletionRoutine(
1797 PKEVENT Event
= Context
;
1799 if (Irp
->PendingReturned
)
1800 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
1802 return STATUS_MORE_PROCESSING_REQUIRED
;
1807 NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter
, PIRP Irp
)
1812 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1813 IoCopyCurrentIrpStackLocationToNext(Irp
);
1814 IoSetCompletionRoutine(Irp
, NdisIForwardIrpAndWaitCompletionRoutine
, &Event
,
1816 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
1817 if (Status
== STATUS_PENDING
)
1819 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1820 Status
= Irp
->IoStatus
.Status
;
1828 IN PDEVICE_OBJECT DeviceObject
,
1831 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1832 Irp
->IoStatus
.Information
= 0;
1834 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1836 return STATUS_SUCCESS
;
1841 NdisIPnPStartDevice(
1842 IN PDEVICE_OBJECT DeviceObject
,
1845 * FUNCTION: Handle the PnP start device event
1847 * DeviceObejct = Functional Device Object
1848 * Irp = IRP_MN_START_DEVICE I/O request packet
1850 * Status of operation
1853 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
1854 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1855 NDIS_WRAPPER_CONTEXT WrapperContext
;
1856 NDIS_STATUS NdisStatus
;
1857 NDIS_STATUS OpenErrorStatus
;
1859 UINT SelectedMediumIndex
= 0;
1860 NDIS_OID AddressOID
;
1861 BOOLEAN Success
= FALSE
;
1862 ULONG ResourceCount
;
1863 ULONG ResourceListSize
;
1864 UNICODE_STRING ParamName
;
1865 PNDIS_CONFIGURATION_PARAMETER ConfigParam
;
1866 NDIS_HANDLE ConfigHandle
;
1868 LARGE_INTEGER Timeout
;
1869 UINT MaxMulticastAddresses
;
1871 PLIST_ENTRY CurrentEntry
;
1872 PPROTOCOL_BINDING ProtocolBinding
;
1875 * Prepare wrapper context used by HW and configuration routines.
1878 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Start Device %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
1880 NDIS_DbgPrint(MAX_TRACE
, ("Inserting adapter 0x%x into adapter list\n", Adapter
));
1882 /* Put adapter in global adapter list */
1883 ExInterlockedInsertTailList(&AdapterListHead
, &Adapter
->ListEntry
, &AdapterListLock
);
1885 Status
= IoOpenDeviceRegistryKey(
1886 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
, PLUGPLAY_REGKEY_DRIVER
,
1887 KEY_ALL_ACCESS
, &WrapperContext
.RegistryHandle
);
1888 if (!NT_SUCCESS(Status
))
1890 NDIS_DbgPrint(MIN_TRACE
,("failed to open adapter-specific reg key\n"));
1891 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1895 NDIS_DbgPrint(MAX_TRACE
, ("opened device reg key\n"));
1897 WrapperContext
.DeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
1900 * Store the adapter resources used by HW routines such as
1901 * NdisMQueryAdapterResources.
1904 if (Stack
->Parameters
.StartDevice
.AllocatedResources
!= NULL
)
1906 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResources
->List
[0].
1907 PartialResourceList
.Count
;
1909 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1910 PartialDescriptors
[ResourceCount
]);
1912 Adapter
->NdisMiniportBlock
.AllocatedResources
=
1913 ExAllocatePool(PagedPool
, ResourceListSize
);
1914 if (Adapter
->NdisMiniportBlock
.AllocatedResources
== NULL
)
1916 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1917 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1918 return STATUS_INSUFFICIENT_RESOURCES
;
1921 Adapter
->NdisMiniportBlock
.Resources
=
1922 ExAllocatePool(PagedPool
, ResourceListSize
);
1923 if (!Adapter
->NdisMiniportBlock
.Resources
)
1925 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1926 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1927 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1928 return STATUS_INSUFFICIENT_RESOURCES
;
1931 RtlCopyMemory(Adapter
->NdisMiniportBlock
.Resources
,
1932 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1935 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResources
,
1936 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1940 if (Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
!= NULL
)
1942 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
->List
[0].
1943 PartialResourceList
.Count
;
1945 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1946 PartialDescriptors
[ResourceCount
]);
1948 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
=
1949 ExAllocatePool(PagedPool
, ResourceListSize
);
1950 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
== NULL
)
1952 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1953 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1954 return STATUS_INSUFFICIENT_RESOURCES
;
1957 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
,
1958 Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
,
1963 * Store the Bus Type, Bus Number and Slot information. It's used by
1964 * the hardware routines then.
1967 NdisOpenConfiguration(&NdisStatus
, &ConfigHandle
, (NDIS_HANDLE
)&WrapperContext
);
1968 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1970 NDIS_DbgPrint(MIN_TRACE
, ("Failed to open configuration key\n"));
1971 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1975 Size
= sizeof(ULONG
);
1976 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1977 DevicePropertyLegacyBusType
, Size
,
1978 &Adapter
->NdisMiniportBlock
.BusType
, &Size
);
1979 if (!NT_SUCCESS(Status
) || (INTERFACE_TYPE
)Adapter
->NdisMiniportBlock
.BusType
== InterfaceTypeUndefined
)
1981 NdisInitUnicodeString(&ParamName
, L
"BusType");
1982 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1983 &ParamName
, NdisParameterInteger
);
1984 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1985 Adapter
->NdisMiniportBlock
.BusType
= ConfigParam
->ParameterData
.IntegerData
;
1987 Adapter
->NdisMiniportBlock
.BusType
= Isa
;
1990 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1991 DevicePropertyBusNumber
, Size
,
1992 &Adapter
->NdisMiniportBlock
.BusNumber
, &Size
);
1993 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.BusNumber
== 0xFFFFFFF0)
1995 NdisInitUnicodeString(&ParamName
, L
"BusNumber");
1996 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1997 &ParamName
, NdisParameterInteger
);
1998 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1999 Adapter
->NdisMiniportBlock
.BusNumber
= ConfigParam
->ParameterData
.IntegerData
;
2001 Adapter
->NdisMiniportBlock
.BusNumber
= 0;
2003 WrapperContext
.BusNumber
= Adapter
->NdisMiniportBlock
.BusNumber
;
2005 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
2006 DevicePropertyAddress
, Size
,
2007 &Adapter
->NdisMiniportBlock
.SlotNumber
, &Size
);
2008 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.SlotNumber
== (NDIS_INTERFACE_TYPE
)-1)
2010 NdisInitUnicodeString(&ParamName
, L
"SlotNumber");
2011 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
2012 &ParamName
, NdisParameterInteger
);
2013 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
2014 Adapter
->NdisMiniportBlock
.SlotNumber
= ConfigParam
->ParameterData
.IntegerData
;
2016 Adapter
->NdisMiniportBlock
.SlotNumber
= 0;
2020 /* Convert slotnumber to PCI_SLOT_NUMBER */
2021 ULONG PciSlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
2022 PCI_SLOT_NUMBER SlotNumber
;
2024 SlotNumber
.u
.AsULONG
= 0;
2025 SlotNumber
.u
.bits
.DeviceNumber
= (PciSlotNumber
>> 16) & 0xFFFF;
2026 SlotNumber
.u
.bits
.FunctionNumber
= PciSlotNumber
& 0xFFFF;
2028 Adapter
->NdisMiniportBlock
.SlotNumber
= SlotNumber
.u
.AsULONG
;
2030 WrapperContext
.SlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
2032 NdisCloseConfiguration(ConfigHandle
);
2034 /* Set handlers (some NDIS macros require these) */
2035 Adapter
->NdisMiniportBlock
.EthRxCompleteHandler
= EthFilterDprIndicateReceiveComplete
;
2036 Adapter
->NdisMiniportBlock
.EthRxIndicateHandler
= EthFilterDprIndicateReceive
;
2037 Adapter
->NdisMiniportBlock
.SendCompleteHandler
= MiniSendComplete
;
2038 Adapter
->NdisMiniportBlock
.SendResourcesHandler
= MiniSendResourcesAvailable
;
2039 Adapter
->NdisMiniportBlock
.ResetCompleteHandler
= MiniResetComplete
;
2040 Adapter
->NdisMiniportBlock
.TDCompleteHandler
= MiniTransferDataComplete
;
2041 Adapter
->NdisMiniportBlock
.PacketIndicateHandler
= MiniIndicateReceivePacket
;
2042 Adapter
->NdisMiniportBlock
.StatusHandler
= MiniStatus
;
2043 Adapter
->NdisMiniportBlock
.StatusCompleteHandler
= MiniStatusComplete
;
2044 Adapter
->NdisMiniportBlock
.SendPacketsHandler
= ProSendPackets
;
2045 Adapter
->NdisMiniportBlock
.QueryCompleteHandler
= MiniRequestComplete
;
2046 Adapter
->NdisMiniportBlock
.SetCompleteHandler
= MiniRequestComplete
;
2049 * Call MiniportInitialize.
2052 NDIS_DbgPrint(MID_TRACE
, ("calling MiniportInitialize\n"));
2053 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.InitializeHandler
)(
2054 &OpenErrorStatus
, &SelectedMediumIndex
, &MediaArray
[0],
2055 MEDIA_ARRAY_SIZE
, Adapter
, (NDIS_HANDLE
)&WrapperContext
);
2057 ZwClose(WrapperContext
.RegistryHandle
);
2059 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2061 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() failed for an adapter.\n"));
2062 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2063 if (Adapter
->NdisMiniportBlock
.Interrupt
)
2065 KeBugCheckEx(BUGCODE_ID_DRIVER
,
2067 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.Interrupt
,
2068 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.TimerQueue
,
2071 if (Adapter
->NdisMiniportBlock
.TimerQueue
)
2073 KeBugCheckEx(BUGCODE_ID_DRIVER
,
2075 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.Interrupt
,
2076 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.TimerQueue
,
2082 if (SelectedMediumIndex
>= MEDIA_ARRAY_SIZE
)
2084 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() selected a bad index\n"));
2085 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2086 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
2089 Adapter
->NdisMiniportBlock
.MediaType
= MediaArray
[SelectedMediumIndex
];
2091 switch (Adapter
->NdisMiniportBlock
.MediaType
)
2093 case NdisMedium802_3
:
2094 Adapter
->MediumHeaderSize
= 14; /* XXX figure out what to do about LLC */
2095 AddressOID
= OID_802_3_CURRENT_ADDRESS
;
2096 Adapter
->AddressLength
= ETH_LENGTH_OF_ADDRESS
;
2097 NdisStatus
= DoQueries(Adapter
, AddressOID
);
2098 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
2100 NdisStatus
= MiniQueryInformation(Adapter
, OID_802_3_MAXIMUM_LIST_SIZE
, sizeof(UINT
),
2101 &MaxMulticastAddresses
, &BytesWritten
);
2103 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2105 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2106 NDIS_DbgPrint(MIN_TRACE
, ("MiniQueryInformation failed (%x)\n", NdisStatus
));
2110 Success
= EthCreateFilter(MaxMulticastAddresses
,
2111 Adapter
->Address
.Type
.Medium802_3
,
2112 &Adapter
->NdisMiniportBlock
.EthDB
);
2114 ((PETHI_FILTER
)Adapter
->NdisMiniportBlock
.EthDB
)->Miniport
= (PNDIS_MINIPORT_BLOCK
)Adapter
;
2116 NdisStatus
= NDIS_STATUS_RESOURCES
;
2121 /* FIXME: Support other types of media */
2122 NDIS_DbgPrint(MIN_TRACE
, ("error: unsupported media\n"));
2124 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2125 return STATUS_UNSUCCESSFUL
;
2128 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2130 NDIS_DbgPrint(MIN_TRACE
, ("couldn't create filter (%x)\n", NdisStatus
));
2134 /* Check for a hang every two seconds if it wasn't set in MiniportInitialize */
2135 if (Adapter
->NdisMiniportBlock
.CheckForHangSeconds
== 0)
2136 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= 2;
2138 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
2139 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStarted
;
2141 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, TRUE
);
2143 Timeout
.QuadPart
= Int32x32To64(Adapter
->NdisMiniportBlock
.CheckForHangSeconds
, -1000000);
2144 KeSetTimerEx(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
, Timeout
,
2145 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
* 1000,
2146 &Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
);
2148 /* Put adapter in adapter list for this miniport */
2149 ExInterlockedInsertTailList(&Adapter
->NdisMiniportBlock
.DriverHandle
->DeviceList
, &Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
2151 /* Refresh bindings for all protocols */
2152 CurrentEntry
= ProtocolListHead
.Flink
;
2153 while (CurrentEntry
!= &ProtocolListHead
)
2155 ProtocolBinding
= CONTAINING_RECORD(CurrentEntry
, PROTOCOL_BINDING
, ListEntry
);
2157 ndisBindMiniportsToProtocol(&NdisStatus
, ProtocolBinding
);
2159 CurrentEntry
= CurrentEntry
->Flink
;
2162 return STATUS_SUCCESS
;
2168 IN PDEVICE_OBJECT DeviceObject
,
2171 * FUNCTION: Handle the PnP stop device event
2173 * DeviceObejct = Functional Device Object
2174 * Irp = IRP_MN_STOP_DEVICE I/O request packet
2176 * Status of operation
2179 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2181 /* Remove adapter from adapter list for this miniport */
2182 ExInterlockedRemoveEntryList(&Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
2184 /* Remove adapter from global adapter list */
2185 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
2187 KeCancelTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2189 /* Set this here so MiniportISR will be forced to run for interrupts generated in MiniportHalt */
2190 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
2191 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStopped
;
2193 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.HaltHandler
)(Adapter
);
2195 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, FALSE
);
2197 if (Adapter
->NdisMiniportBlock
.AllocatedResources
)
2199 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
2200 Adapter
->NdisMiniportBlock
.AllocatedResources
= NULL
;
2202 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
)
2204 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
);
2205 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
= NULL
;
2208 if (Adapter
->NdisMiniportBlock
.Resources
)
2210 ExFreePool(Adapter
->NdisMiniportBlock
.Resources
);
2211 Adapter
->NdisMiniportBlock
.Resources
= NULL
;
2214 if (Adapter
->NdisMiniportBlock
.EthDB
)
2216 EthDeleteFilter(Adapter
->NdisMiniportBlock
.EthDB
);
2217 Adapter
->NdisMiniportBlock
.EthDB
= NULL
;
2220 return STATUS_SUCCESS
;
2226 IN PDEVICE_OBJECT DeviceObject
,
2229 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
2230 PMINIPORT_BUGCHECK_CONTEXT Context
= Adapter
->BugcheckContext
;
2231 ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
= Context
->ShutdownHandler
;
2233 ASSERT(ShutdownHandler
);
2235 ShutdownHandler(Context
->DriverContext
);
2237 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2238 Irp
->IoStatus
.Information
= 0;
2240 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2242 return STATUS_SUCCESS
;
2247 NdisIDeviceIoControl(
2248 IN PDEVICE_OBJECT DeviceObject
,
2251 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2252 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2253 NDIS_STATUS Status
= STATUS_NOT_SUPPORTED
;
2256 Irp
->IoStatus
.Information
= 0;
2260 switch (Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
2262 case IOCTL_NDIS_QUERY_GLOBAL_STATS
:
2263 Status
= MiniQueryInformation(Adapter
,
2264 *(PNDIS_OID
)Irp
->AssociatedIrp
.SystemBuffer
,
2265 Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
,
2266 MmGetSystemAddressForMdl(Irp
->MdlAddress
),
2268 Irp
->IoStatus
.Information
= Written
;
2276 if (Status
!= NDIS_STATUS_PENDING
)
2278 Irp
->IoStatus
.Status
= Status
;
2279 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2282 IoMarkIrpPending(Irp
);
2290 IN PDEVICE_OBJECT DeviceObject
,
2293 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2294 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2297 switch (Stack
->MinorFunction
)
2299 case IRP_MN_START_DEVICE
:
2300 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2301 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2303 Status
= NdisIPnPStartDevice(DeviceObject
, Irp
);
2306 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed device start\n"));
2307 Irp
->IoStatus
.Status
= Status
;
2308 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2311 case IRP_MN_STOP_DEVICE
:
2312 Status
= NdisIPnPStopDevice(DeviceObject
, Irp
);
2313 if (!NT_SUCCESS(Status
))
2314 NDIS_DbgPrint(MIN_TRACE
, ("WARNING: Ignoring halt device failure! Passing the IRP down anyway\n"));
2315 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2318 case IRP_MN_QUERY_REMOVE_DEVICE
:
2319 case IRP_MN_QUERY_STOP_DEVICE
:
2320 Status
= NdisIPnPQueryStopDevice(DeviceObject
, Irp
);
2321 Irp
->IoStatus
.Status
= Status
;
2322 if (Status
!= STATUS_SUCCESS
)
2324 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2325 NDIS_DbgPrint(MIN_TRACE
, ("Failing miniport halt request\n"));
2330 case IRP_MN_CANCEL_REMOVE_DEVICE
:
2331 case IRP_MN_CANCEL_STOP_DEVICE
:
2332 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2333 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2335 Status
= NdisIPnPCancelStopDevice(DeviceObject
, Irp
);
2339 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed cancel stop/remove request\n"));
2341 Irp
->IoStatus
.Status
= Status
;
2342 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2345 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
2346 Status
= NDIS_STATUS_SUCCESS
;
2347 Irp
->IoStatus
.Status
= Status
;
2348 Irp
->IoStatus
.Information
|= Adapter
->NdisMiniportBlock
.PnPFlags
;
2355 IoSkipCurrentIrpStackLocation(Irp
);
2356 return IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
2362 IN PDRIVER_OBJECT DriverObject
,
2363 IN PDEVICE_OBJECT PhysicalDeviceObject
)
2365 * FUNCTION: Create a device for an adapter found using PnP
2367 * DriverObject = Pointer to the miniport driver object
2368 * PhysicalDeviceObject = Pointer to the PDO for our adapter
2371 static const WCHAR ClassKeyName
[] = {'C','l','a','s','s','\\'};
2372 static const WCHAR LinkageKeyName
[] = {'\\','L','i','n','k','a','g','e',0};
2373 PNDIS_M_DRIVER_BLOCK Miniport
;
2374 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2375 WCHAR
*LinkageKeyBuffer
;
2376 ULONG DriverKeyLength
;
2377 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
2378 UNICODE_STRING ExportName
;
2379 PDEVICE_OBJECT DeviceObject
;
2380 PLOGICAL_ADAPTER Adapter
;
2384 * Gain the access to the miniport data structure first.
2387 MiniportPtr
= IoGetDriverObjectExtension(DriverObject
, (PVOID
)'NMID');
2388 if (MiniportPtr
== NULL
)
2390 NDIS_DbgPrint(MIN_TRACE
, ("Can't get driver object extension.\n"));
2391 return NDIS_STATUS_FAILURE
;
2393 Miniport
= *MiniportPtr
;
2396 * Get name of the Linkage registry key for our adapter. It's located under
2397 * the driver key for our driver and so we have basicly two ways to do it.
2398 * Either we can use IoOpenDriverRegistryKey or compose it using information
2399 * gathered by IoGetDeviceProperty. I choosed the second because
2400 * IoOpenDriverRegistryKey wasn't implemented at the time of writing.
2403 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2404 0, NULL
, &DriverKeyLength
);
2405 if (Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
&& Status
!= STATUS_SUCCESS
)
2407 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key length.\n"));
2411 LinkageKeyBuffer
= ExAllocatePool(PagedPool
, DriverKeyLength
+
2412 sizeof(ClassKeyName
) + sizeof(LinkageKeyName
));
2413 if (LinkageKeyBuffer
== NULL
)
2415 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate memory for driver key name.\n"));
2416 return STATUS_INSUFFICIENT_RESOURCES
;
2419 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2420 DriverKeyLength
, LinkageKeyBuffer
+
2421 (sizeof(ClassKeyName
) / sizeof(WCHAR
)),
2423 if (!NT_SUCCESS(Status
))
2425 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key.\n"));
2426 ExFreePool(LinkageKeyBuffer
);
2430 /* Compose the linkage key name. */
2431 RtlCopyMemory(LinkageKeyBuffer
, ClassKeyName
, sizeof(ClassKeyName
));
2432 RtlCopyMemory(LinkageKeyBuffer
+ ((sizeof(ClassKeyName
) + DriverKeyLength
) /
2433 sizeof(WCHAR
)) - 1, LinkageKeyName
, sizeof(LinkageKeyName
));
2435 NDIS_DbgPrint(DEBUG_MINIPORT
, ("LinkageKey: %S.\n", LinkageKeyBuffer
));
2438 * Now open the linkage key and read the "Export" and "RootDevice" values
2439 * which contains device name and root service respectively.
2442 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
2443 RtlInitUnicodeString(&ExportName
, NULL
);
2444 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
| RTL_QUERY_REGISTRY_DIRECT
;
2445 QueryTable
[0].Name
= L
"Export";
2446 QueryTable
[0].EntryContext
= &ExportName
;
2448 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
, LinkageKeyBuffer
,
2449 QueryTable
, NULL
, NULL
);
2450 ExFreePool(LinkageKeyBuffer
);
2451 if (!NT_SUCCESS(Status
))
2453 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport device name. (%x)\n", Status
));
2458 * Create the device object.
2461 NDIS_DbgPrint(MAX_TRACE
, ("creating device %wZ\n", &ExportName
));
2463 Status
= IoCreateDevice(Miniport
->DriverObject
, sizeof(LOGICAL_ADAPTER
),
2464 &ExportName
, FILE_DEVICE_PHYSICAL_NETCARD
,
2465 0, FALSE
, &DeviceObject
);
2466 if (!NT_SUCCESS(Status
))
2468 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device object.\n"));
2469 RtlFreeUnicodeString(&ExportName
);
2474 * Initialize the adapter structure.
2477 Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2478 KeInitializeSpinLock(&Adapter
->NdisMiniportBlock
.Lock
);
2479 InitializeListHead(&Adapter
->ProtocolListHead
);
2481 Status
= IoRegisterDeviceInterface(PhysicalDeviceObject
,
2482 &GUID_DEVINTERFACE_NET
,
2484 &Adapter
->NdisMiniportBlock
.SymbolicLinkName
);
2486 if (!NT_SUCCESS(Status
))
2488 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device interface.\n"));
2489 IoDeleteDevice(DeviceObject
);
2490 RtlFreeUnicodeString(&ExportName
);
2494 Adapter
->NdisMiniportBlock
.DriverHandle
= Miniport
;
2495 Adapter
->NdisMiniportBlock
.MiniportName
= ExportName
;
2496 Adapter
->NdisMiniportBlock
.DeviceObject
= DeviceObject
;
2497 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
= PhysicalDeviceObject
;
2498 Adapter
->NdisMiniportBlock
.NextDeviceObject
=
2499 IoAttachDeviceToDeviceStack(Adapter
->NdisMiniportBlock
.DeviceObject
,
2500 PhysicalDeviceObject
);
2502 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= 0;
2503 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceAdded
;
2505 KeInitializeTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2506 KeInitializeDpc(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
, MiniportHangDpc
, Adapter
);
2508 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
2510 return STATUS_SUCCESS
;
2515 NdisGenericIrpHandler(
2516 IN PDEVICE_OBJECT DeviceObject
,
2519 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
2521 /* Use the characteristics to classify the device */
2522 if (DeviceObject
->DeviceType
== FILE_DEVICE_PHYSICAL_NETCARD
)
2524 if ((IrpSp
->MajorFunction
== IRP_MJ_CREATE
) ||
2525 (IrpSp
->MajorFunction
== IRP_MJ_CLOSE
))
2527 return NdisICreateClose(DeviceObject
, Irp
);
2529 else if (IrpSp
->MajorFunction
== IRP_MJ_PNP
)
2531 return NdisIDispatchPnp(DeviceObject
, Irp
);
2533 else if (IrpSp
->MajorFunction
== IRP_MJ_SHUTDOWN
)
2535 return NdisIShutdown(DeviceObject
, Irp
);
2537 else if (IrpSp
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
)
2539 return NdisIDeviceIoControl(DeviceObject
, Irp
);
2542 else if (DeviceObject
->DeviceType
== FILE_DEVICE_NETWORK
)
2544 PNDIS_M_DEVICE_BLOCK DeviceBlock
= DeviceObject
->DeviceExtension
;
2546 ASSERT(DeviceBlock
->DeviceObject
== DeviceObject
);
2548 if (DeviceBlock
->MajorFunction
[IrpSp
->MajorFunction
] != NULL
)
2550 return DeviceBlock
->MajorFunction
[IrpSp
->MajorFunction
](DeviceObject
, Irp
);
2558 Irp
->IoStatus
.Status
= STATUS_INVALID_DEVICE_REQUEST
;
2559 Irp
->IoStatus
.Information
= 0;
2561 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2563 return STATUS_INVALID_DEVICE_REQUEST
;
2571 NdisMRegisterMiniport(
2572 IN NDIS_HANDLE NdisWrapperHandle
,
2573 IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics
,
2574 IN UINT CharacteristicsLength
)
2576 * FUNCTION: Registers a miniport's MiniportXxx entry points with the NDIS library
2578 * NdisWrapperHandle = Pointer to handle returned by NdisMInitializeWrapper
2579 * MiniportCharacteristics = Pointer to a buffer with miniport characteristics
2580 * CharacteristicsLength = Number of bytes in characteristics buffer
2582 * Status of operation
2586 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2587 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2591 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2593 switch (MiniportCharacteristics
->MajorNdisVersion
)
2596 MinSize
= sizeof(NDIS30_MINIPORT_CHARACTERISTICS
);
2600 MinSize
= sizeof(NDIS40_MINIPORT_CHARACTERISTICS
);
2604 switch (MiniportCharacteristics
->MinorNdisVersion
)
2607 MinSize
= sizeof(NDIS50_MINIPORT_CHARACTERISTICS
);
2611 MinSize
= sizeof(NDIS51_MINIPORT_CHARACTERISTICS
);
2615 NDIS_DbgPrint(MIN_TRACE
, ("Bad 5.x minor characteristics version.\n"));
2616 return NDIS_STATUS_BAD_VERSION
;
2621 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics version.\n"));
2622 return NDIS_STATUS_BAD_VERSION
;
2625 NDIS_DbgPrint(MIN_TRACE
, ("Initializing an NDIS %u.%u miniport\n",
2626 MiniportCharacteristics
->MajorNdisVersion
,
2627 MiniportCharacteristics
->MinorNdisVersion
));
2629 if (CharacteristicsLength
< MinSize
)
2631 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics length.\n"));
2632 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2635 /* Check if mandatory MiniportXxx functions are specified */
2636 if ((!MiniportCharacteristics
->HaltHandler
) ||
2637 (!MiniportCharacteristics
->InitializeHandler
)||
2638 (!MiniportCharacteristics
->ResetHandler
))
2640 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics.\n"));
2641 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2644 if (MiniportCharacteristics
->MajorNdisVersion
< 0x05)
2646 if ((!MiniportCharacteristics
->QueryInformationHandler
) ||
2647 (!MiniportCharacteristics
->SetInformationHandler
))
2649 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2650 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2655 if (((!MiniportCharacteristics
->QueryInformationHandler
) ||
2656 (!MiniportCharacteristics
->SetInformationHandler
)) &&
2657 (!MiniportCharacteristics
->CoRequestHandler
))
2659 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2660 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2664 if (MiniportCharacteristics
->MajorNdisVersion
== 0x03)
2666 if (!MiniportCharacteristics
->SendHandler
)
2668 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 3.0)\n"));
2669 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2672 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x04)
2675 if ((!MiniportCharacteristics
->SendHandler
) &&
2676 (!MiniportCharacteristics
->SendPacketsHandler
))
2678 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 4.0)\n"));
2679 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2682 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x05)
2684 /* TODO: Add more checks here */
2686 if ((!MiniportCharacteristics
->SendHandler
) &&
2687 (!MiniportCharacteristics
->SendPacketsHandler
) &&
2688 (!MiniportCharacteristics
->CoSendPacketsHandler
))
2690 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 5.0)\n"));
2691 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2695 RtlCopyMemory(&Miniport
->MiniportCharacteristics
, MiniportCharacteristics
, MinSize
);
2698 * NOTE: This is VERY unoptimal! Should we store the NDIS_M_DRIVER_BLOCK
2699 * structure in the driver extension or what?
2702 Status
= IoAllocateDriverObjectExtension(Miniport
->DriverObject
, (PVOID
)'NMID',
2703 sizeof(PNDIS_M_DRIVER_BLOCK
), (PVOID
*)&MiniportPtr
);
2704 if (!NT_SUCCESS(Status
))
2706 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate driver object extension.\n"));
2707 return NDIS_STATUS_RESOURCES
;
2710 *MiniportPtr
= Miniport
;
2712 /* We have to register for all of these so handler registered in NdisMRegisterDevice work */
2713 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
2715 Miniport
->DriverObject
->MajorFunction
[i
] = NdisGenericIrpHandler
;
2718 Miniport
->DriverObject
->DriverExtension
->AddDevice
= NdisIAddDevice
;
2720 return NDIS_STATUS_SUCCESS
;
2726 #undef NdisMResetComplete
2730 IN NDIS_HANDLE MiniportAdapterHandle
,
2731 IN NDIS_STATUS Status
,
2732 IN BOOLEAN AddressingReset
)
2734 MiniResetComplete(MiniportAdapterHandle
, Status
, AddressingReset
);
2740 #undef NdisMSendComplete
2744 IN NDIS_HANDLE MiniportAdapterHandle
,
2745 IN PNDIS_PACKET Packet
,
2746 IN NDIS_STATUS Status
)
2748 * FUNCTION: Forwards a message to the initiating protocol saying
2749 * that a packet was handled
2751 * NdisAdapterHandle = Handle input to MiniportInitialize
2752 * Packet = Pointer to NDIS packet that was sent
2753 * Status = Status of send operation
2756 MiniSendComplete(MiniportAdapterHandle
, Packet
, Status
);
2762 #undef NdisMSendResourcesAvailable
2765 NdisMSendResourcesAvailable(
2766 IN NDIS_HANDLE MiniportAdapterHandle
)
2768 MiniSendResourcesAvailable(MiniportAdapterHandle
);
2774 #undef NdisMTransferDataComplete
2777 NdisMTransferDataComplete(
2778 IN NDIS_HANDLE MiniportAdapterHandle
,
2779 IN PNDIS_PACKET Packet
,
2780 IN NDIS_STATUS Status
,
2781 IN UINT BytesTransferred
)
2783 MiniTransferDataComplete(MiniportAdapterHandle
, Packet
, Status
, BytesTransferred
);
2789 #undef NdisMSetAttributes
2793 IN NDIS_HANDLE MiniportAdapterHandle
,
2794 IN NDIS_HANDLE MiniportAdapterContext
,
2795 IN BOOLEAN BusMaster
,
2796 IN NDIS_INTERFACE_TYPE AdapterType
)
2798 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2800 * MiniportAdapterHandle = Handle input to MiniportInitialize
2801 * MiniportAdapterContext = Pointer to context information
2802 * BusMaster = Specifies TRUE if the caller's NIC is a busmaster DMA device
2803 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2806 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2807 NdisMSetAttributesEx(MiniportAdapterHandle
, MiniportAdapterContext
, 0,
2808 BusMaster
? NDIS_ATTRIBUTE_BUS_MASTER
: 0,
2817 NdisMSetAttributesEx(
2818 IN NDIS_HANDLE MiniportAdapterHandle
,
2819 IN NDIS_HANDLE MiniportAdapterContext
,
2820 IN UINT CheckForHangTimeInSeconds OPTIONAL
,
2821 IN ULONG AttributeFlags
,
2822 IN NDIS_INTERFACE_TYPE AdapterType
)
2824 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2826 * MiniportAdapterHandle = Handle input to MiniportInitialize
2827 * MiniportAdapterContext = Pointer to context information
2828 * CheckForHangTimeInSeconds = Specifies interval in seconds at which
2829 * MiniportCheckForHang should be called
2830 * AttributeFlags = Bitmask that indicates specific attributes
2831 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2834 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(MiniportAdapterHandle
);
2836 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2838 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
= MiniportAdapterContext
;
2839 Adapter
->NdisMiniportBlock
.Flags
= AttributeFlags
;
2840 Adapter
->NdisMiniportBlock
.AdapterType
= AdapterType
;
2841 if (CheckForHangTimeInSeconds
> 0)
2842 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= CheckForHangTimeInSeconds
;
2843 if (AttributeFlags
& NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER
)
2844 NDIS_DbgPrint(MIN_TRACE
, ("Intermediate drivers not supported yet.\n"));
2846 NDIS_DbgPrint(MIN_TRACE
, ("Miniport attribute flags: 0x%x\n", AttributeFlags
));
2848 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
)
2850 NDIS_DbgPrint(MAX_TRACE
, ("Miniport set AdapterShutdownHandler in MiniportCharacteristics\n"));
2851 NdisMRegisterAdapterShutdownHandler(Adapter
,
2852 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
2853 Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
);
2863 IN ULONG MicrosecondsToSleep
)
2865 * FUNCTION: delay the thread's execution for MicrosecondsToSleep
2867 * MicrosecondsToSleep: duh...
2869 * - Because this is a blocking call, current IRQL must be < DISPATCH_LEVEL
2873 LARGE_INTEGER DueTime
;
2877 DueTime
.QuadPart
= (-1) * 10 * MicrosecondsToSleep
;
2879 KeInitializeTimer(&Timer
);
2880 KeSetTimer(&Timer
, DueTime
, 0);
2881 KeWaitForSingleObject(&Timer
, Executive
, KernelMode
, FALSE
, 0);
2889 NdisMSynchronizeWithInterrupt(
2890 IN PNDIS_MINIPORT_INTERRUPT Interrupt
,
2891 IN PVOID SynchronizeFunction
,
2892 IN PVOID SynchronizeContext
)
2894 return(KeSynchronizeExecution(Interrupt
->InterruptObject
,
2895 (PKSYNCHRONIZE_ROUTINE
)SynchronizeFunction
,
2896 SynchronizeContext
));
2905 IN NDIS_HANDLE LogHandle
,
2907 IN UINT LogBufferSize
)
2909 PUCHAR Buffer
= LogBuffer
;
2913 for (i
= 0; i
< LogBufferSize
; i
+= 16)
2915 DbgPrint("%08x |", i
);
2916 for (j
= 0; j
< 16; j
++)
2919 if (idx
< LogBufferSize
)
2920 DbgPrint(" %02x", Buffer
[idx
]);
2925 for (j
= 0; j
< 16; j
++)
2928 if (idx
== LogBufferSize
)
2930 if (Buffer
[idx
] >= ' ') /* FIXME: not portable! replace by if (isprint(Buffer[idx])) ? */
2931 DbgPrint("%c", Buffer
[idx
]);
2938 return NDIS_STATUS_FAILURE
;
2946 NdisTerminateWrapper(
2947 IN NDIS_HANDLE NdisWrapperHandle
,
2948 IN PVOID SystemSpecific
)
2950 * FUNCTION: Releases resources allocated by a call to NdisInitializeWrapper
2952 * NdisWrapperHandle = Handle returned by NdisInitializeWrapper (NDIS_M_DRIVER_BLOCK)
2953 * SystemSpecific = Always NULL
2956 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2958 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2960 ExFreePool(Miniport
->RegistryPath
->Buffer
);
2961 ExFreePool(Miniport
->RegistryPath
);
2962 ExInterlockedRemoveEntryList(&Miniport
->ListEntry
, &MiniportListLock
);
2963 ExFreePool(Miniport
);
2972 NdisMQueryAdapterInstanceName(
2973 OUT PNDIS_STRING AdapterInstanceName
,
2974 IN NDIS_HANDLE MiniportAdapterHandle
)
2982 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
2983 UNICODE_STRING AdapterName
;
2985 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2987 AdapterName
.Length
= 0;
2988 AdapterName
.MaximumLength
= Adapter
->NdisMiniportBlock
.MiniportName
.MaximumLength
;
2989 AdapterName
.Buffer
= ExAllocatePool(PagedPool
, AdapterName
.MaximumLength
);
2990 if (!AdapterName
.Buffer
) {
2991 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
2992 return NDIS_STATUS_RESOURCES
;
2995 RtlCopyUnicodeString(&AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
);
2997 *AdapterInstanceName
= AdapterName
;
2999 return NDIS_STATUS_SUCCESS
;
3007 NdisDeregisterAdapterShutdownHandler(
3008 IN NDIS_HANDLE NdisAdapterHandle
)
3016 NdisMDeregisterAdapterShutdownHandler(NdisAdapterHandle
);
3025 NdisRegisterAdapterShutdownHandler(
3026 IN NDIS_HANDLE NdisAdapterHandle
,
3027 IN PVOID ShutdownContext
,
3028 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
3036 NdisMRegisterAdapterShutdownHandler(NdisAdapterHandle
,
3046 NdisMGetDeviceProperty(
3047 IN NDIS_HANDLE MiniportAdapterHandle
,
3048 IN OUT PDEVICE_OBJECT
*PhysicalDeviceObject OPTIONAL
,
3049 IN OUT PDEVICE_OBJECT
*FunctionalDeviceObject OPTIONAL
,
3050 IN OUT PDEVICE_OBJECT
*NextDeviceObject OPTIONAL
,
3051 IN OUT PCM_RESOURCE_LIST
*AllocatedResources OPTIONAL
,
3052 IN OUT PCM_RESOURCE_LIST
*AllocatedResourcesTranslated OPTIONAL
)
3060 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
3062 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
3064 if (PhysicalDeviceObject
!= NULL
)
3065 *PhysicalDeviceObject
= Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
;
3067 if (FunctionalDeviceObject
!= NULL
)
3068 *FunctionalDeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
3070 if (NextDeviceObject
!= NULL
)
3071 *NextDeviceObject
= Adapter
->NdisMiniportBlock
.NextDeviceObject
;
3073 if (AllocatedResources
!= NULL
)
3074 *AllocatedResources
= Adapter
->NdisMiniportBlock
.AllocatedResources
;
3076 if (AllocatedResourcesTranslated
!= NULL
)
3077 *AllocatedResourcesTranslated
= Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
;
3085 NdisMRegisterUnloadHandler(
3086 IN NDIS_HANDLE NdisWrapperHandle
,
3087 IN PDRIVER_UNLOAD UnloadHandler
)
3095 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
3097 NDIS_DbgPrint(MAX_TRACE
, ("Miniport registered unload handler\n"));
3099 DriverBlock
->DriverObject
->DriverUnload
= UnloadHandler
;
3107 NdisMRegisterDevice(
3108 IN NDIS_HANDLE NdisWrapperHandle
,
3109 IN PNDIS_STRING DeviceName
,
3110 IN PNDIS_STRING SymbolicName
,
3111 IN PDRIVER_DISPATCH MajorFunctions
[],
3112 OUT PDEVICE_OBJECT
*pDeviceObject
,
3113 OUT NDIS_HANDLE
*NdisDeviceHandle
)
3121 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
3122 PNDIS_M_DEVICE_BLOCK DeviceBlock
;
3123 PDEVICE_OBJECT DeviceObject
;
3127 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
3129 Status
= IoCreateDevice(DriverBlock
->DriverObject
,
3130 sizeof(NDIS_M_DEVICE_BLOCK
),
3132 FILE_DEVICE_NETWORK
,
3137 if (!NT_SUCCESS(Status
))
3139 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateDevice failed (%x)\n", Status
));
3143 Status
= IoCreateSymbolicLink(SymbolicName
, DeviceName
);
3145 if (!NT_SUCCESS(Status
))
3147 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateSymbolicLink failed (%x)\n", Status
));
3148 IoDeleteDevice(DeviceObject
);
3152 DeviceBlock
= DeviceObject
->DeviceExtension
;
3156 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
3157 IoDeleteDevice(DeviceObject
);
3158 IoDeleteSymbolicLink(SymbolicName
);
3159 return NDIS_STATUS_RESOURCES
;
3162 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
3163 DeviceBlock
->MajorFunction
[i
] = MajorFunctions
[i
];
3165 DeviceBlock
->DeviceObject
= DeviceObject
;
3166 DeviceBlock
->SymbolicName
= SymbolicName
;
3168 *pDeviceObject
= DeviceObject
;
3169 *NdisDeviceHandle
= DeviceBlock
;
3171 return NDIS_STATUS_SUCCESS
;
3179 NdisMDeregisterDevice(
3180 IN NDIS_HANDLE NdisDeviceHandle
)
3188 PNDIS_M_DEVICE_BLOCK DeviceBlock
= NdisDeviceHandle
;
3190 IoDeleteDevice(DeviceBlock
->DeviceObject
);
3192 IoDeleteSymbolicLink(DeviceBlock
->SymbolicName
);
3194 return NDIS_STATUS_SUCCESS
;
3202 NdisQueryAdapterInstanceName(
3203 OUT PNDIS_STRING AdapterInstanceName
,
3204 IN NDIS_HANDLE NdisBindingHandle
)
3212 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3213 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3215 return NdisMQueryAdapterInstanceName(AdapterInstanceName
,
3224 NdisCompletePnPEvent(
3225 IN NDIS_STATUS Status
,
3226 IN NDIS_HANDLE NdisBindingHandle
,
3227 IN PNET_PNP_EVENT NetPnPEvent
)
3235 PIRP Irp
= (PIRP
)NetPnPEvent
->NdisReserved
[0];
3236 PLIST_ENTRY CurrentEntry
= (PLIST_ENTRY
)NetPnPEvent
->NdisReserved
[1];
3237 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3238 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3239 NDIS_STATUS NdisStatus
;
3241 if (Status
!= NDIS_STATUS_SUCCESS
)
3243 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3244 ExFreePool(NetPnPEvent
);
3245 Irp
->IoStatus
.Status
= Status
;
3246 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3250 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
3252 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
3254 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.PnPEventHandler
)(
3255 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
3258 if (NdisStatus
== NDIS_STATUS_PENDING
)
3260 NetPnPEvent
->NdisReserved
[1] = (ULONG_PTR
)CurrentEntry
->Flink
;
3263 else if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
3265 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3266 ExFreePool(NetPnPEvent
);
3267 Irp
->IoStatus
.Status
= NdisStatus
;
3268 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3272 CurrentEntry
= CurrentEntry
->Flink
;
3275 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3276 ExFreePool(NetPnPEvent
);
3278 Irp
->IoStatus
.Status
= NDIS_STATUS_SUCCESS
;
3279 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3287 NdisCancelSendPackets(
3288 IN NDIS_HANDLE NdisBindingHandle
,
3291 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3292 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3294 NDIS_DbgPrint(MAX_TRACE
, ("Called for ID %x.\n", CancelId
));
3296 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)
3298 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)(
3299 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
3310 NdisIMGetBindingContext(
3311 IN NDIS_HANDLE NdisBindingHandle
)
3319 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3320 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3322 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3324 return Adapter
->NdisMiniportBlock
.DeviceContext
;
3333 NdisIMGetDeviceContext(
3334 IN NDIS_HANDLE MiniportAdapterHandle
)
3342 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
3344 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3346 return Adapter
->NdisMiniportBlock
.DeviceContext
;