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
20 * Define to 1 to get a debugger breakpoint at the end of NdisInitializeWrapper
21 * for each new miniport starting up
23 #define BREAK_ON_MINIPORT_INIT 0
26 * This has to be big enough to hold the results of querying the Route value
27 * from the Linkage key. Please re-code me to determine this dynamically.
29 #define ROUTE_DATA_SIZE 256
31 /* Number of media we know */
32 #define MEDIA_ARRAY_SIZE 15
34 static NDIS_MEDIUM MediaArray
[MEDIA_ARRAY_SIZE
] =
43 NdisMediumArcnet878_2
,
45 NdisMediumWirelessWan
,
53 /* global list and lock of Miniports NDIS has registered */
54 LIST_ENTRY MiniportListHead
;
55 KSPIN_LOCK MiniportListLock
;
57 /* global list and lock of adapters NDIS has registered */
58 LIST_ENTRY AdapterListHead
;
59 KSPIN_LOCK AdapterListLock
;
68 if ((DebugTraceLevel
& DEBUG_PACKET
) > 0) {
69 Length
= CopyPacketToBuffer(
75 DbgPrint("*** PACKET START ***");
77 for (i
= 0; i
< Length
; i
++) {
79 DbgPrint("\n%04X ", i
);
80 DbgPrint("%02X ", Buffer
[i
]);
83 DbgPrint("*** PACKET STOP ***\n");
91 UINT HeaderBufferSize
,
92 PVOID LookaheadBuffer
,
93 UINT LookaheadBufferSize
)
96 if ((DebugTraceLevel
& DEBUG_PACKET
) > 0) {
100 DbgPrint("*** RECEIVE PACKET START ***\n");
103 for (i
= 0; i
< HeaderBufferSize
; i
++) {
105 DbgPrint("\n%04X ", i
);
106 DbgPrint("%02X ", *p
++);
109 DbgPrint("\nFRAME:");
112 Length
= (LookaheadBufferSize
< 64)? LookaheadBufferSize
: 64;
113 for (i
= 0; i
< Length
; i
++) {
115 DbgPrint("\n%04X ", i
);
116 DbgPrint("%02X ", *p
++);
119 DbgPrint("\n*** RECEIVE PACKET STOP ***\n");
127 PLOGICAL_ADAPTER Adapter
,
128 NDIS_HANDLE MacReceiveContext
,
130 UINT HeaderBufferSize
,
131 PVOID LookaheadBuffer
,
132 UINT LookaheadBufferSize
,
135 * FUNCTION: Indicate received data to bound protocols
137 * Adapter = Pointer to logical adapter
138 * MacReceiveContext = MAC receive context handle
139 * HeaderBuffer = Pointer to header buffer
140 * HeaderBufferSize = Size of header buffer
141 * LookaheadBuffer = Pointer to lookahead buffer
142 * LookaheadBufferSize = Size of lookahead buffer
143 * PacketSize = Total size of received packet
147 PLIST_ENTRY CurrentEntry
;
148 PADAPTER_BINDING AdapterBinding
;
150 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called. Adapter (0x%X) HeaderBuffer (0x%X) "
151 "HeaderBufferSize (0x%X) LookaheadBuffer (0x%X) LookaheadBufferSize (0x%X).\n",
152 Adapter
, HeaderBuffer
, HeaderBufferSize
, LookaheadBuffer
, LookaheadBufferSize
));
154 MiniDisplayPacket2(HeaderBuffer
, HeaderBufferSize
, LookaheadBuffer
, LookaheadBufferSize
);
156 NDIS_DbgPrint(MAX_TRACE
, ("acquiring miniport block lock\n"));
157 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
159 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
160 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurrentEntry = %x\n", CurrentEntry
));
162 if (CurrentEntry
== &Adapter
->ProtocolListHead
)
164 NDIS_DbgPrint(MIN_TRACE
, ("WARNING: No upper protocol layer.\n"));
167 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
169 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
170 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterBinding = %x\n", AdapterBinding
));
174 ("XXX (%x) %x %x %x %x %x %x %x XXX\n",
175 *AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
,
176 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
184 /* call the receive handler */
185 (*AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
)(
186 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
194 CurrentEntry
= CurrentEntry
->Flink
;
197 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
199 NDIS_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
204 MiniIndicateReceivePacket(
205 IN NDIS_HANDLE MiniportAdapterHandle
,
206 IN PPNDIS_PACKET PacketArray
,
207 IN UINT NumberOfPackets
)
209 * FUNCTION: receives miniport packet array indications
211 * MiniportAdapterHandle: Miniport handle for the adapter
212 * PacketArray: pointer to a list of packet pointers to indicate
213 * NumberOfPackets: number of packets to indicate
217 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
218 PLIST_ENTRY CurrentEntry
;
219 PADAPTER_BINDING AdapterBinding
;
223 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
225 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
227 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
229 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
231 for (i
= 0; i
< NumberOfPackets
; i
++)
233 if (AdapterBinding
->ProtocolBinding
->Chars
.ReceivePacketHandler
&&
234 NDIS_GET_PACKET_STATUS(PacketArray
[i
]) != NDIS_STATUS_RESOURCES
)
236 (*AdapterBinding
->ProtocolBinding
->Chars
.ReceivePacketHandler
)(
237 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
242 UINT FirstBufferLength
, TotalBufferLength
, LookAheadSize
, HeaderSize
;
243 PNDIS_BUFFER NdisBuffer
;
244 PVOID NdisBufferVA
, LookAheadBuffer
;
245 NDIS_STATUS NdisStatus
;
248 NdisGetFirstBufferFromPacket(PacketArray
[i
],
254 HeaderSize
= NDIS_GET_PACKET_HEADER_SIZE(PacketArray
[i
]);
256 if (Adapter
->NdisMiniportBlock
.CurrentLookahead
< (TotalBufferLength
- HeaderSize
))
258 LookAheadSize
= Adapter
->NdisMiniportBlock
.CurrentLookahead
;
262 LookAheadSize
= TotalBufferLength
- HeaderSize
;
266 LookAheadBuffer
= ExAllocatePool(NonPagedPool
, LookAheadSize
);
267 if (!LookAheadBuffer
)
269 NDIS_DbgPrint(MIN_TRACE
, ("Failed to allocate lookahead buffer!\n"));
270 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
274 CopyBufferChainToBuffer(LookAheadBuffer
,
279 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
)(
280 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
281 AdapterBinding
->NdisOpenBlock
.MacHandle
,
286 TotalBufferLength
- HeaderSize
);
288 NDIS_SET_PACKET_STATUS(PacketArray
[i
], NdisStatus
);
290 ExFreePool(LookAheadBuffer
);
294 CurrentEntry
= CurrentEntry
->Flink
;
297 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
303 IN NDIS_HANDLE MiniportAdapterHandle
,
304 IN NDIS_STATUS Status
,
305 IN BOOLEAN AddressingReset
)
307 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
308 PLIST_ENTRY CurrentEntry
;
309 PADAPTER_BINDING AdapterBinding
;
312 MiniEndRequest(Adapter
, NdisWorkItemResetRequested
);
315 MiniDoAddressingReset(Adapter
);
317 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
318 NdisMIndicateStatusComplete(Adapter
);
320 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
322 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
324 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
326 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
328 (*AdapterBinding
->ProtocolBinding
->Chars
.ResetCompleteHandler
)(
329 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
332 CurrentEntry
= CurrentEntry
->Flink
;
335 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
340 IN NDIS_HANDLE MiniportAdapterHandle
,
341 IN NDIS_STATUS Status
)
343 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
344 PNDIS_REQUEST Request
;
345 PNDIS_REQUEST_MAC_BLOCK MacBlock
;
348 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
350 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
351 Request
= Adapter
->NdisMiniportBlock
.PendingRequest
;
352 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
354 MiniEndRequest(Adapter
, NdisWorkItemRequest
);
356 MacBlock
= (PNDIS_REQUEST_MAC_BLOCK
)Request
->MacReserved
;
358 if( MacBlock
->Binding
->RequestCompleteHandler
) {
359 (*MacBlock
->Binding
->RequestCompleteHandler
)(
360 MacBlock
->Binding
->ProtocolBindingContext
,
367 MiniIndicateComplete(
368 IN NDIS_HANDLE MiniportAdapterHandle
,
369 IN PNDIS_PACKET Packet
,
370 IN NDIS_STATUS Status
)
372 PADAPTER_BINDING AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
374 MiniEndRequest(MiniportAdapterHandle
, NdisWorkItemSendLoopback
);
376 (*AdapterBinding
->ProtocolBinding
->Chars
.SendCompleteHandler
)(
377 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
384 IN NDIS_HANDLE MiniportAdapterHandle
,
385 IN PNDIS_PACKET Packet
,
386 IN NDIS_STATUS Status
)
388 * FUNCTION: Forwards a message to the initiating protocol saying
389 * that a packet was handled
391 * NdisAdapterHandle = Handle input to MiniportInitialize
392 * Packet = Pointer to NDIS packet that was sent
393 * Status = Status of send operation
396 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
397 PADAPTER_BINDING AdapterBinding
;
399 PSCATTER_GATHER_LIST SGList
;
401 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
403 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
405 if (Adapter
->NdisMiniportBlock
.ScatterGatherListSize
!= 0)
407 NDIS_DbgPrint(MAX_TRACE
, ("Freeing Scatter/Gather list\n"));
409 SGList
= NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
410 ScatterGatherListPacketInfo
);
412 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
414 Adapter
->NdisMiniportBlock
.SystemAdapterObject
->
415 DmaOperations
->PutScatterGatherList(
416 Adapter
->NdisMiniportBlock
.SystemAdapterObject
,
420 KeLowerIrql(OldIrql
);
422 NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
423 ScatterGatherListPacketInfo
) = NULL
;
426 MiniEndRequest(Adapter
, NdisWorkItemSend
);
428 (*AdapterBinding
->ProtocolBinding
->Chars
.SendCompleteHandler
)(
429 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
435 SignalQueue(PLOGICAL_ADAPTER Adapter
)
437 PIO_WORKITEM WorkItem
= IoAllocateWorkItem(Adapter
->NdisMiniportBlock
.DeviceObject
);
440 if (!WorkItem
) return NDIS_STATUS_RESOURCES
;
442 IoQueueWorkItem(WorkItem
,
447 return NDIS_STATUS_SUCCESS
;
451 MiniSendResourcesAvailable(
452 IN NDIS_HANDLE MiniportAdapterHandle
)
454 SignalQueue(MiniportAdapterHandle
);
458 MiniTransferDataComplete(
459 IN NDIS_HANDLE MiniportAdapterHandle
,
460 IN PNDIS_PACKET Packet
,
461 IN NDIS_STATUS Status
,
462 IN UINT BytesTransferred
)
464 PADAPTER_BINDING AdapterBinding
;
466 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
468 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
470 (*AdapterBinding
->ProtocolBinding
->Chars
.TransferDataCompleteHandler
)(
471 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
479 MiniAdapterHasAddress(
480 PLOGICAL_ADAPTER Adapter
,
483 * FUNCTION: Determines whether a packet has the same destination address as an adapter
485 * Adapter = Pointer to logical adapter object
486 * Packet = Pointer to NDIS packet
488 * TRUE if the destination address is that of the adapter, FALSE if not
494 PNDIS_BUFFER NdisBuffer
;
497 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
502 NDIS_DbgPrint(MIN_TRACE
, ("Adapter object was null\n"));
508 NDIS_DbgPrint(MIN_TRACE
, ("Packet was null\n"));
513 NdisQueryPacket(Packet
, NULL
, NULL
, &NdisBuffer
, NULL
);
517 NDIS_DbgPrint(MIN_TRACE
, ("Packet contains no buffers.\n"));
521 NdisQueryBuffer(NdisBuffer
, (PVOID
)&Start2
, &BufferLength
);
523 /* FIXME: Should handle fragmented packets */
525 switch (Adapter
->NdisMiniportBlock
.MediaType
)
527 case NdisMedium802_3
:
528 Length
= ETH_LENGTH_OF_ADDRESS
;
529 /* Destination address is the first field */
533 NDIS_DbgPrint(MIN_TRACE
, ("Adapter has unsupported media type (0x%X).\n", Adapter
->NdisMiniportBlock
.MediaType
));
537 if (BufferLength
< Length
)
539 NDIS_DbgPrint(MIN_TRACE
, ("Buffer is too small.\n"));
543 Start1
= (PUCHAR
)&Adapter
->Address
;
544 NDIS_DbgPrint(MAX_TRACE
, ("packet address: %x:%x:%x:%x:%x:%x adapter address: %x:%x:%x:%x:%x:%x\n",
545 *((char *)Start1
), *(((char *)Start1
)+1), *(((char *)Start1
)+2), *(((char *)Start1
)+3), *(((char *)Start1
)+4), *(((char *)Start1
)+5),
546 *((char *)Start2
), *(((char *)Start2
)+1), *(((char *)Start2
)+2), *(((char *)Start2
)+3), *(((char *)Start2
)+4), *(((char *)Start2
)+5))
549 return (RtlCompareMemory((PVOID
)Start1
, (PVOID
)Start2
, Length
) == Length
);
555 PNDIS_STRING AdapterName
)
557 * FUNCTION: Finds an adapter object by name
559 * AdapterName = Pointer to name of adapter
561 * Pointer to logical adapter object, or NULL if none was found.
562 * If found, the adapter is referenced for the caller. The caller
563 * is responsible for dereferencing after use
567 PLIST_ENTRY CurrentEntry
;
568 PLOGICAL_ADAPTER Adapter
= 0;
572 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
574 KeAcquireSpinLock(&AdapterListLock
, &OldIrql
);
576 CurrentEntry
= AdapterListHead
.Flink
;
578 while (CurrentEntry
!= &AdapterListHead
)
580 Adapter
= CONTAINING_RECORD(CurrentEntry
, LOGICAL_ADAPTER
, ListEntry
);
584 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Examining adapter 0x%lx\n", Adapter
));
585 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterName = %wZ\n", AdapterName
));
586 NDIS_DbgPrint(DEBUG_MINIPORT
, ("DeviceName = %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
588 if (RtlCompareUnicodeString(AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
, TRUE
) == 0)
594 CurrentEntry
= CurrentEntry
->Flink
;
597 KeReleaseSpinLock(&AdapterListLock
, OldIrql
);
601 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Leaving. Adapter found at 0x%x\n", Adapter
));
605 NDIS_DbgPrint(MIN_TRACE
, ("Leaving (adapter not found for %wZ).\n", AdapterName
));
613 PLOGICAL_ADAPTER Adapter
,
619 NDIS_STATUS NdisStatus
;
620 PNDIS_REQUEST NdisRequest
;
622 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
624 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
626 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
627 return NDIS_STATUS_RESOURCES
;
630 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
632 NdisRequest
->RequestType
= NdisRequestSetInformation
;
633 NdisRequest
->DATA
.SET_INFORMATION
.Oid
= Oid
;
634 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
= Buffer
;
635 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
= Size
;
637 NdisStatus
= MiniBeginRequest(Adapter
, NdisWorkItemRequest
, NdisRequest
);
638 if (!NT_SUCCESS(NdisStatus
))
641 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
643 /* FIXME: Wait in pending case! */
644 if (NdisStatus
!= NDIS_STATUS_PENDING
)
645 MiniEndRequest(Adapter
, NdisWorkItemRequest
);
647 ASSERT(NdisStatus
!= NDIS_STATUS_PENDING
);
649 *BytesRead
= NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
;
651 ExFreePool(NdisRequest
);
657 MiniQueryInformation(
658 PLOGICAL_ADAPTER Adapter
,
664 * FUNCTION: Queries a logical adapter for properties
666 * Adapter = Pointer to the logical adapter object to query
667 * Oid = Specifies the Object ID to query for
668 * Size = Size of the passed buffer
669 * Buffer = Buffer for the output
670 * BytesWritten = Address of buffer to place number of bytes written
672 * Status of operation
675 NDIS_STATUS NdisStatus
;
676 PNDIS_REQUEST NdisRequest
;
678 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
680 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
682 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
683 return NDIS_STATUS_RESOURCES
;
686 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
688 NdisRequest
->RequestType
= NdisRequestQueryInformation
;
689 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
= Oid
;
690 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
= Buffer
;
691 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
= Size
;
693 NdisStatus
= MiniBeginRequest(Adapter
, NdisWorkItemRequest
, NdisRequest
);
694 if (!NT_SUCCESS(NdisStatus
))
697 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
699 /* FIXME: Wait in pending case! */
700 if (NdisStatus
!= NDIS_STATUS_PENDING
)
701 MiniEndRequest(Adapter
, NdisWorkItemRequest
);
703 ASSERT(NdisStatus
!= NDIS_STATUS_PENDING
);
705 *BytesWritten
= NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
;
707 ExFreePool(NdisRequest
);
713 MiniCheckForHang( PLOGICAL_ADAPTER Adapter
)
715 * FUNCTION: Checks to see if the miniport is hung
717 * Adapter = Pointer to the logical adapter object
719 * TRUE if the miniport is hung
720 * FALSE if the miniport is not hung
725 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)
726 Ret
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)(
727 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
);
733 MiniDoAddressingReset(PLOGICAL_ADAPTER Adapter
)
737 MiniSetInformation(Adapter
,
738 OID_GEN_CURRENT_LOOKAHEAD
,
740 &Adapter
->NdisMiniportBlock
.CurrentLookahead
,
743 /* FIXME: Set more stuff */
748 PLOGICAL_ADAPTER Adapter
)
750 * FUNCTION: Resets the miniport
752 * Adapter = Pointer to the logical adapter object
754 * Status of the operation
758 BOOLEAN AddressingReset
= TRUE
;
760 Status
= MiniBeginRequest(Adapter
, NdisWorkItemResetRequested
, NULL
);
761 if (!NT_SUCCESS(Status
))
764 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
765 NdisMIndicateStatusComplete(Adapter
);
767 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
768 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
771 if (Status
!= NDIS_STATUS_PENDING
) {
773 MiniDoAddressingReset(Adapter
);
775 MiniEndRequest(Adapter
, NdisWorkItemResetRequested
);
777 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
778 NdisMIndicateStatusComplete(Adapter
);
787 PVOID DeferredContext
,
788 PVOID SystemArgument1
,
789 PVOID SystemArgument2
)
791 PLOGICAL_ADAPTER Adapter
= DeferredContext
;
793 if (MiniCheckForHang(Adapter
)) {
794 NDIS_DbgPrint(MIN_TRACE
, ("Miniport detected adapter hang\n"));
801 PLOGICAL_ADAPTER Adapter
,
802 NDIS_WORK_ITEM_TYPE WorkItemType
,
803 PVOID WorkItemContext
)
807 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
808 PSINGLE_LIST_ENTRY CurrentEntry
;
810 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
812 QueueBusy
= (Adapter
->NdisMiniportBlock
.WorkQueue
[WorkItemType
].Next
!= NULL
);
814 MiniportWorkItem
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_MINIPORT_WORK_ITEM
));
815 if (!MiniportWorkItem
)
817 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
818 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
819 return NDIS_STATUS_RESOURCES
;
822 MiniportWorkItem
->WorkItemType
= WorkItemType
;
823 MiniportWorkItem
->WorkItemContext
= WorkItemContext
;
824 MiniportWorkItem
->Link
.Next
= NULL
;
826 CurrentEntry
= &Adapter
->NdisMiniportBlock
.WorkQueue
[WorkItemType
];
827 while (CurrentEntry
->Next
)
828 CurrentEntry
= CurrentEntry
->Next
;
830 CurrentEntry
->Next
= (PSINGLE_LIST_ENTRY
)MiniportWorkItem
;
832 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
835 NDIS_DbgPrint(MIN_TRACE
, ("Queue %d busy!\n", WorkItemType
));
837 return (QueueBusy
? NDIS_STATUS_PENDING
: NDIS_STATUS_SUCCESS
);
844 PLOGICAL_ADAPTER Adapter
,
845 NDIS_WORK_ITEM_TYPE WorkItemType
,
846 PVOID
*WorkItemContext
)
848 * FUNCTION: Dequeues a work item from the work queue of a logical adapter
850 * Adapter = Pointer to the logical adapter object to dequeue work item from
851 * AdapterBinding = Address of buffer for adapter binding for this request
852 * WorkItemType = Address of buffer for work item type
853 * WorkItemContext = Address of buffer for pointer to context information
855 * Adapter lock must be held when called
857 * Status of operation
860 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
863 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
865 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
866 MiniportWorkItem
= (PNDIS_MINIPORT_WORK_ITEM
)Adapter
->NdisMiniportBlock
.WorkQueue
[WorkItemType
].Next
;
867 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
869 if (MiniportWorkItem
)
871 /* This is VERY IMPORTANT! We dequeue the work item AFTER completion */
873 *WorkItemContext
= MiniportWorkItem
->WorkItemContext
;
875 return NDIS_STATUS_SUCCESS
;
879 return NDIS_STATUS_FAILURE
;
885 PLOGICAL_ADAPTER Adapter
,
886 NDIS_WORK_ITEM_TYPE WorkItemType
)
890 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
892 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
894 MiniportWorkItem
= (PNDIS_MINIPORT_WORK_ITEM
)Adapter
->NdisMiniportBlock
.WorkQueue
[WorkItemType
].Next
;
895 ASSERT(MiniportWorkItem
);
896 Adapter
->NdisMiniportBlock
.WorkQueue
[WorkItemType
].Next
= MiniportWorkItem
->Link
.Next
;
897 ExFreePool(MiniportWorkItem
);
899 QueueBusy
= (Adapter
->NdisMiniportBlock
.WorkQueue
[WorkItemType
].Next
!= NULL
);
900 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
903 SignalQueue(Adapter
);
909 PLOGICAL_ADAPTER Adapter
,
910 PNDIS_REQUEST NdisRequest
)
912 * FUNCTION: Sends a request to a miniport
914 * AdapterBinding = Pointer to binding used in the request
915 * NdisRequest = Pointer to NDIS request structure describing request
917 * Status of operation
923 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
925 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
926 Adapter
->NdisMiniportBlock
.PendingRequest
= NdisRequest
;
927 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
929 if (!Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)
931 switch (NdisRequest
->RequestType
)
933 case NdisRequestQueryInformation
:
934 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.QueryInformationHandler
)(
935 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
936 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
,
937 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
,
938 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
,
939 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
,
940 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesNeeded
);
943 case NdisRequestSetInformation
:
944 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SetInformationHandler
)(
945 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
946 NdisRequest
->DATA
.SET_INFORMATION
.Oid
,
947 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
,
948 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
,
949 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
,
950 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesNeeded
);
954 NDIS_DbgPrint(MIN_TRACE
, ("Bad request type\n"));
955 Status
= NDIS_STATUS_FAILURE
;
960 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)(
961 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
973 #undef NdisMSetInformationComplete
976 NdisMSetInformationComplete(
977 IN NDIS_HANDLE MiniportAdapterHandle
,
978 IN NDIS_STATUS Status
)
980 PLOGICAL_ADAPTER Adapter
=
981 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
983 (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)(MiniportAdapterHandle
, Status
);
985 MiniEndRequest(Adapter
, NdisWorkItemRequest
);
992 #undef NdisMQueryInformationComplete
995 NdisMQueryInformationComplete(
996 IN NDIS_HANDLE MiniportAdapterHandle
,
997 IN NDIS_STATUS Status
)
999 PLOGICAL_ADAPTER Adapter
=
1000 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
1002 (Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)(MiniportAdapterHandle
, Status
);
1004 MiniEndRequest(Adapter
, NdisWorkItemRequest
);
1009 MiniportWorker(IN PDEVICE_OBJECT DeviceObject
, IN PVOID Context
)
1011 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
1013 NDIS_STATUS NdisStatus
;
1014 PVOID WorkItemContext
;
1015 NDIS_WORK_ITEM_TYPE WorkItemType
;
1016 BOOLEAN AddressingReset
, NextQueue
;
1018 IoFreeWorkItem((PIO_WORKITEM
)Context
);
1020 for (WorkItemType
= 0; WorkItemType
< NUMBER_OF_WORK_ITEM_TYPES
; WorkItemType
++)
1023 while (!NextQueue
&& MiniDequeueWorkItem(Adapter
, WorkItemType
, &WorkItemContext
) == NDIS_STATUS_SUCCESS
)
1025 switch (WorkItemType
)
1027 case NdisWorkItemSend
:
1029 * called by ProSend when protocols want to send packets to the miniport
1032 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
1034 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1036 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1037 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1038 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1039 NdisStatus
= NDIS_STATUS_PENDING
;
1043 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
1044 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1046 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1047 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1048 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1050 KeLowerIrql(RaiseOldIrql
);
1052 NdisStatus
= NDIS_GET_PACKET_STATUS((PNDIS_PACKET
)WorkItemContext
);
1053 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1061 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1063 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1064 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1065 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1066 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1067 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1071 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
1072 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1073 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1074 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1075 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1076 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1077 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1078 KeLowerIrql(RaiseOldIrql
);
1079 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1086 if( NdisStatus
!= NDIS_STATUS_PENDING
) {
1088 ( Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1092 case NdisWorkItemSendLoopback
:
1094 * called by ProSend when protocols want to send loopback packets
1096 /* XXX atm ProIndicatePacket sends a packet up via the loopback adapter only */
1097 NdisStatus
= ProIndicatePacket(Adapter
, (PNDIS_PACKET
)WorkItemContext
);
1099 if( NdisStatus
!= NDIS_STATUS_PENDING
)
1100 MiniIndicateComplete((NDIS_HANDLE
)Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1103 case NdisWorkItemReturnPackets
:
1106 case NdisWorkItemResetRequested
:
1107 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
1108 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1111 if (NdisStatus
!= NDIS_STATUS_PENDING
)
1112 MiniResetComplete(Adapter
, NdisStatus
, AddressingReset
);
1115 case NdisWorkItemResetInProgress
:
1118 case NdisWorkItemMiniportCallback
:
1121 case NdisWorkItemRequest
:
1122 NdisStatus
= MiniDoRequest(Adapter
, (PNDIS_REQUEST
)WorkItemContext
);
1124 if (NdisStatus
== NDIS_STATUS_PENDING
)
1127 switch (((PNDIS_REQUEST
)WorkItemContext
)->RequestType
)
1129 case NdisRequestQueryInformation
:
1130 NdisMQueryInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1133 case NdisRequestSetInformation
:
1134 NdisMSetInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1138 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS request type.\n"));
1139 MiniEndRequest(Adapter
, NdisWorkItemRequest
);
1145 MiniEndRequest(Adapter
, WorkItemType
);
1146 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS work item type (%d).\n", WorkItemType
));
1158 IN NDIS_HANDLE MiniportHandle
,
1159 IN NDIS_STATUS GeneralStatus
,
1160 IN PVOID StatusBuffer
,
1161 IN UINT StatusBufferSize
)
1163 PLOGICAL_ADAPTER Adapter
= MiniportHandle
;
1164 PLIST_ENTRY CurrentEntry
;
1165 PADAPTER_BINDING AdapterBinding
;
1168 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1170 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1172 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1174 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1176 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusHandler
)(
1177 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
1182 CurrentEntry
= CurrentEntry
->Flink
;
1185 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1192 IN NDIS_HANDLE MiniportAdapterHandle
)
1194 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1195 PLIST_ENTRY CurrentEntry
;
1196 PADAPTER_BINDING AdapterBinding
;
1199 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1201 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1203 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1205 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1207 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusCompleteHandler
)(
1208 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
);
1210 CurrentEntry
= CurrentEntry
->Flink
;
1213 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1223 IN NDIS_HANDLE LogHandle
)
1225 PNDIS_LOG Log
= (PNDIS_LOG
)LogHandle
;
1226 PNDIS_MINIPORT_BLOCK Miniport
= Log
->Miniport
;
1229 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1231 KeAcquireSpinLock(&(Miniport
)->Lock
, &OldIrql
);
1232 Miniport
->Log
= NULL
;
1233 KeReleaseSpinLock(&(Miniport
)->Lock
, OldIrql
);
1244 IN NDIS_HANDLE MiniportAdapterHandle
,
1246 OUT PNDIS_HANDLE LogHandle
)
1248 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1252 NDIS_DbgPrint(MAX_TRACE
, ("called: MiniportAdapterHandle 0x%x, Size %ld\n", MiniportAdapterHandle
, Size
));
1254 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1256 if (Adapter
->NdisMiniportBlock
.Log
)
1259 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1260 return NDIS_STATUS_FAILURE
;
1263 Log
= ExAllocatePool(NonPagedPool
, Size
+ sizeof(NDIS_LOG
));
1267 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1268 return NDIS_STATUS_RESOURCES
;
1271 Adapter
->NdisMiniportBlock
.Log
= Log
;
1273 KeInitializeSpinLock(&Log
->LogLock
);
1275 Log
->Miniport
= &Adapter
->NdisMiniportBlock
;
1276 Log
->TotalSize
= Size
;
1277 Log
->CurrentSize
= 0;
1284 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1286 return NDIS_STATUS_SUCCESS
;
1294 NdisMDeregisterAdapterShutdownHandler(
1295 IN NDIS_HANDLE MiniportHandle
)
1297 * FUNCTION: de-registers a shutdown handler
1298 * ARGUMENTS: MiniportHandle: Handle passed into MiniportInitialize
1301 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1303 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1305 if(Adapter
->BugcheckContext
->ShutdownHandler
) {
1306 KeDeregisterBugCheckCallback(Adapter
->BugcheckContext
->CallbackRecord
);
1307 IoUnregisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1317 IN NDIS_HANDLE LogHandle
)
1319 PNDIS_LOG Log
= (PNDIS_LOG
) LogHandle
;
1322 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1325 KeAcquireSpinLock(&Log
->LogLock
, &OldIrql
);
1327 /* Set buffers size */
1328 Log
->CurrentSize
= 0;
1333 KeReleaseSpinLock(&Log
->LogLock
, OldIrql
);
1339 #undef NdisMIndicateStatus
1342 NdisMIndicateStatus(
1343 IN NDIS_HANDLE MiniportAdapterHandle
,
1344 IN NDIS_STATUS GeneralStatus
,
1345 IN PVOID StatusBuffer
,
1346 IN UINT StatusBufferSize
)
1348 MiniStatus(MiniportAdapterHandle
, GeneralStatus
, StatusBuffer
, StatusBufferSize
);
1354 #undef NdisMIndicateStatusComplete
1357 NdisMIndicateStatusComplete(
1358 IN NDIS_HANDLE MiniportAdapterHandle
)
1360 MiniStatusComplete(MiniportAdapterHandle
);
1369 NdisInitializeWrapper(
1370 OUT PNDIS_HANDLE NdisWrapperHandle
,
1371 IN PVOID SystemSpecific1
,
1372 IN PVOID SystemSpecific2
,
1373 IN PVOID SystemSpecific3
)
1375 * FUNCTION: Notifies the NDIS library that a new miniport is initializing
1377 * NdisWrapperHandle = Address of buffer to place NDIS wrapper handle
1378 * SystemSpecific1 = Pointer to the driver's driver object
1379 * SystemSpecific2 = Pointer to the driver's registry path
1380 * SystemSpecific3 = Always NULL
1382 * - SystemSpecific2 goes invalid so we copy it
1385 PNDIS_M_DRIVER_BLOCK Miniport
;
1386 PUNICODE_STRING RegistryPath
;
1387 WCHAR
*RegistryBuffer
;
1389 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1391 ASSERT(NdisWrapperHandle
);
1393 *NdisWrapperHandle
= NULL
;
1395 #if BREAK_ON_MINIPORT_INIT
1399 Miniport
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DRIVER_BLOCK
));
1403 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1407 RtlZeroMemory(Miniport
, sizeof(NDIS_M_DRIVER_BLOCK
));
1409 KeInitializeSpinLock(&Miniport
->Lock
);
1411 Miniport
->DriverObject
= (PDRIVER_OBJECT
)SystemSpecific1
;
1413 /* set the miniport's driver registry path */
1414 RegistryPath
= ExAllocatePool(PagedPool
, sizeof(UNICODE_STRING
));
1417 ExFreePool(Miniport
);
1418 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1422 RegistryPath
->Length
= ((PUNICODE_STRING
)SystemSpecific2
)->Length
;
1423 RegistryPath
->MaximumLength
= RegistryPath
->Length
+ sizeof(WCHAR
); /* room for 0-term */
1425 RegistryBuffer
= ExAllocatePool(PagedPool
, RegistryPath
->MaximumLength
);
1428 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1429 ExFreePool(Miniport
);
1430 ExFreePool(RegistryPath
);
1434 RtlCopyMemory(RegistryBuffer
, ((PUNICODE_STRING
)SystemSpecific2
)->Buffer
, RegistryPath
->Length
);
1435 RegistryBuffer
[RegistryPath
->Length
/sizeof(WCHAR
)] = 0;
1437 RegistryPath
->Buffer
= RegistryBuffer
;
1438 Miniport
->RegistryPath
= RegistryPath
;
1440 InitializeListHead(&Miniport
->DeviceList
);
1442 /* Put miniport in global miniport list */
1443 ExInterlockedInsertTailList(&MiniportListHead
, &Miniport
->ListEntry
, &MiniportListLock
);
1445 *NdisWrapperHandle
= Miniport
;
1449 VOID NTAPI
NdisIBugcheckCallback(
1453 * FUNCTION: Internal callback for handling bugchecks - calls adapter's shutdown handler
1455 * Buffer: Pointer to a bugcheck callback context
1459 PMINIPORT_BUGCHECK_CONTEXT Context
= (PMINIPORT_BUGCHECK_CONTEXT
)Buffer
;
1460 ADAPTER_SHUTDOWN_HANDLER sh
= (ADAPTER_SHUTDOWN_HANDLER
)Context
->ShutdownHandler
;
1462 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1465 sh(Context
->DriverContext
);
1474 NdisMRegisterAdapterShutdownHandler(
1475 IN NDIS_HANDLE MiniportHandle
,
1476 IN PVOID ShutdownContext
,
1477 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
1479 * FUNCTION: Register a shutdown handler for an adapter
1481 * MiniportHandle: Handle originally passed into MiniportInitialize
1482 * ShutdownContext: Pre-initialized bugcheck context
1483 * ShutdownHandler: Function to call to handle the bugcheck
1485 * - I'm not sure about ShutdownContext
1488 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1489 PMINIPORT_BUGCHECK_CONTEXT BugcheckContext
;
1491 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1493 BugcheckContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_BUGCHECK_CONTEXT
));
1494 if(!BugcheckContext
)
1496 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1500 BugcheckContext
->ShutdownHandler
= ShutdownHandler
;
1501 BugcheckContext
->DriverContext
= ShutdownContext
;
1503 BugcheckContext
->CallbackRecord
= ExAllocatePool(NonPagedPool
, sizeof(KBUGCHECK_CALLBACK_RECORD
));
1504 if (!BugcheckContext
->CallbackRecord
) {
1505 ExFreePool(BugcheckContext
);
1509 Adapter
->BugcheckContext
= BugcheckContext
;
1511 KeInitializeCallbackRecord(BugcheckContext
->CallbackRecord
);
1513 KeRegisterBugCheckCallback(BugcheckContext
->CallbackRecord
, NdisIBugcheckCallback
,
1514 BugcheckContext
, sizeof(*BugcheckContext
), (PUCHAR
)"Ndis Miniport");
1516 IoRegisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1522 PLOGICAL_ADAPTER Adapter
,
1523 NDIS_OID AddressOID
)
1525 * FUNCTION: Queries miniport for information
1527 * Adapter = Pointer to logical adapter
1528 * AddressOID = OID to use to query for current address
1530 * Status of operation
1534 NDIS_STATUS NdisStatus
;
1536 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1538 /* Get MAC options for adapter */
1539 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAC_OPTIONS
, sizeof(UINT
),
1540 &Adapter
->NdisMiniportBlock
.MacOptions
,
1543 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1545 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAC_OPTIONS failed. NdisStatus (0x%X).\n", NdisStatus
));
1549 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MacOptions (0x%X).\n", Adapter
->NdisMiniportBlock
.MacOptions
));
1551 /* Get current hardware address of adapter */
1552 NdisStatus
= MiniQueryInformation(Adapter
, AddressOID
, Adapter
->AddressLength
,
1553 &Adapter
->Address
, &BytesWritten
);
1555 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1557 NDIS_DbgPrint(MIN_TRACE
, ("Address OID (0x%X) failed. NdisStatus (0x%X).\n", AddressOID
, NdisStatus
));
1565 PUCHAR A
= (PUCHAR
)&Adapter
->Address
.Type
.Medium802_3
;
1567 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]));
1571 /* Get maximum lookahead buffer size of adapter */
1572 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_LOOKAHEAD
, sizeof(ULONG
),
1573 &Adapter
->NdisMiniportBlock
.MaximumLookahead
, &BytesWritten
);
1575 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1577 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1581 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MaxLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.MaximumLookahead
));
1583 /* Get current lookahead buffer size of adapter */
1584 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_CURRENT_LOOKAHEAD
, sizeof(ULONG
),
1585 &Adapter
->NdisMiniportBlock
.CurrentLookahead
, &BytesWritten
);
1587 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1589 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_CURRENT_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1593 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_SEND_PACKETS
, sizeof(ULONG
),
1594 &Adapter
->NdisMiniportBlock
.MaxSendPackets
, &BytesWritten
);
1596 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1598 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_SEND_PACKETS failed. NdisStatus (0x%X).\n", NdisStatus
));
1600 /* Set it to 1 if it fails because some drivers don't support this (?)*/
1601 Adapter
->NdisMiniportBlock
.MaxSendPackets
= 1;
1604 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.CurrentLookahead
));
1606 return STATUS_SUCCESS
;
1612 NdisIForwardIrpAndWaitCompletionRoutine(
1617 PKEVENT Event
= Context
;
1619 if (Irp
->PendingReturned
)
1620 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
1622 return STATUS_MORE_PROCESSING_REQUIRED
;
1628 NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter
, PIRP Irp
)
1633 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1634 IoCopyCurrentIrpStackLocationToNext(Irp
);
1635 IoSetCompletionRoutine(Irp
, NdisIForwardIrpAndWaitCompletionRoutine
, &Event
,
1637 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
1638 if (Status
== STATUS_PENDING
)
1640 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1641 Status
= Irp
->IoStatus
.Status
;
1649 NdisIPnPStartDevice(
1650 IN PDEVICE_OBJECT DeviceObject
,
1653 * FUNCTION: Handle the PnP start device event
1655 * DeviceObejct = Functional Device Object
1656 * Irp = IRP_MN_START_DEVICE I/O request packet
1658 * Status of operation
1661 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
1662 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1663 NDIS_WRAPPER_CONTEXT WrapperContext
;
1664 NDIS_STATUS NdisStatus
;
1665 NDIS_STATUS OpenErrorStatus
;
1667 UINT SelectedMediumIndex
= 0;
1668 NDIS_OID AddressOID
;
1669 BOOLEAN Success
= FALSE
;
1670 ULONG ResourceCount
;
1671 ULONG ResourceListSize
;
1672 UNICODE_STRING ParamName
;
1673 PNDIS_CONFIGURATION_PARAMETER ConfigParam
;
1674 NDIS_HANDLE ConfigHandle
;
1676 LARGE_INTEGER Timeout
;
1677 UINT MaxMulticastAddresses
;
1681 * Prepare wrapper context used by HW and configuration routines.
1684 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Start Device %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
1686 NDIS_DbgPrint(MAX_TRACE
, ("Inserting adapter 0x%x into adapter list\n", Adapter
));
1688 /* Put adapter in global adapter list */
1689 ExInterlockedInsertTailList(&AdapterListHead
, &Adapter
->ListEntry
, &AdapterListLock
);
1691 Status
= IoOpenDeviceRegistryKey(
1692 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
, PLUGPLAY_REGKEY_DRIVER
,
1693 KEY_ALL_ACCESS
, &WrapperContext
.RegistryHandle
);
1694 if (!NT_SUCCESS(Status
))
1696 NDIS_DbgPrint(MIN_TRACE
,("failed to open adapter-specific reg key\n"));
1697 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1701 NDIS_DbgPrint(MAX_TRACE
, ("opened device reg key\n"));
1703 WrapperContext
.DeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
1706 * Store the adapter resources used by HW routines such as
1707 * NdisMQueryAdapterResources.
1710 if (Stack
->Parameters
.StartDevice
.AllocatedResources
!= NULL
)
1712 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResources
->List
[0].
1713 PartialResourceList
.Count
;
1715 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1716 PartialDescriptors
[ResourceCount
]);
1718 Adapter
->NdisMiniportBlock
.AllocatedResources
=
1719 ExAllocatePool(PagedPool
, ResourceListSize
);
1720 if (Adapter
->NdisMiniportBlock
.AllocatedResources
== NULL
)
1722 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1723 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1724 return STATUS_INSUFFICIENT_RESOURCES
;
1727 Adapter
->NdisMiniportBlock
.Resources
=
1728 ExAllocatePool(PagedPool
, ResourceListSize
);
1729 if (!Adapter
->NdisMiniportBlock
.Resources
)
1731 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1732 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1733 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1734 return STATUS_INSUFFICIENT_RESOURCES
;
1737 RtlCopyMemory(Adapter
->NdisMiniportBlock
.Resources
,
1738 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1741 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResources
,
1742 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1746 if (Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
!= NULL
)
1748 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
->List
[0].
1749 PartialResourceList
.Count
;
1751 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1752 PartialDescriptors
[ResourceCount
]);
1754 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
=
1755 ExAllocatePool(PagedPool
, ResourceListSize
);
1756 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
== NULL
)
1758 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1759 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1760 return STATUS_INSUFFICIENT_RESOURCES
;
1763 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
,
1764 Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
,
1769 * Store the Bus Type, Bus Number and Slot information. It's used by
1770 * the hardware routines then.
1773 NdisOpenConfiguration(&NdisStatus
, &ConfigHandle
, (NDIS_HANDLE
)&WrapperContext
);
1774 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1776 NDIS_DbgPrint(MIN_TRACE
, ("Failed to open configuration key\n"));
1777 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1781 Size
= sizeof(ULONG
);
1782 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1783 DevicePropertyLegacyBusType
, Size
,
1784 &Adapter
->NdisMiniportBlock
.BusType
, &Size
);
1785 if (!NT_SUCCESS(Status
) || (INTERFACE_TYPE
)Adapter
->NdisMiniportBlock
.BusType
== InterfaceTypeUndefined
)
1787 NdisInitUnicodeString(&ParamName
, L
"BusType");
1788 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1789 &ParamName
, NdisParameterInteger
);
1790 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1791 Adapter
->NdisMiniportBlock
.BusType
= ConfigParam
->ParameterData
.IntegerData
;
1793 Adapter
->NdisMiniportBlock
.BusType
= Isa
;
1796 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1797 DevicePropertyBusNumber
, Size
,
1798 &Adapter
->NdisMiniportBlock
.BusNumber
, &Size
);
1799 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.BusNumber
== 0xFFFFFFF0)
1801 NdisInitUnicodeString(&ParamName
, L
"BusNumber");
1802 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1803 &ParamName
, NdisParameterInteger
);
1804 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1805 Adapter
->NdisMiniportBlock
.BusNumber
= ConfigParam
->ParameterData
.IntegerData
;
1807 Adapter
->NdisMiniportBlock
.BusNumber
= 0;
1809 WrapperContext
.BusNumber
= Adapter
->NdisMiniportBlock
.BusNumber
;
1811 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1812 DevicePropertyAddress
, Size
,
1813 &Adapter
->NdisMiniportBlock
.SlotNumber
, &Size
);
1814 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.SlotNumber
== (NDIS_INTERFACE_TYPE
)-1)
1816 NdisInitUnicodeString(&ParamName
, L
"SlotNumber");
1817 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1818 &ParamName
, NdisParameterInteger
);
1819 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1820 Adapter
->NdisMiniportBlock
.SlotNumber
= ConfigParam
->ParameterData
.IntegerData
;
1822 Adapter
->NdisMiniportBlock
.SlotNumber
= 0;
1826 /* Convert slotnumber to PCI_SLOT_NUMBER */
1827 ULONG PciSlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1828 PCI_SLOT_NUMBER SlotNumber
;
1830 SlotNumber
.u
.AsULONG
= 0;
1831 SlotNumber
.u
.bits
.DeviceNumber
= (PciSlotNumber
>> 16) & 0xFFFF;
1832 SlotNumber
.u
.bits
.FunctionNumber
= PciSlotNumber
& 0xFFFF;
1834 Adapter
->NdisMiniportBlock
.SlotNumber
= SlotNumber
.u
.AsULONG
;
1836 WrapperContext
.SlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1838 NdisCloseConfiguration(ConfigHandle
);
1840 /* Set handlers (some NDIS macros require these) */
1841 Adapter
->NdisMiniportBlock
.EthRxCompleteHandler
= EthFilterDprIndicateReceiveComplete
;
1842 Adapter
->NdisMiniportBlock
.EthRxIndicateHandler
= EthFilterDprIndicateReceive
;
1843 Adapter
->NdisMiniportBlock
.SendCompleteHandler
= MiniSendComplete
;
1844 Adapter
->NdisMiniportBlock
.SendResourcesHandler
= MiniSendResourcesAvailable
;
1845 Adapter
->NdisMiniportBlock
.ResetCompleteHandler
= MiniResetComplete
;
1846 Adapter
->NdisMiniportBlock
.TDCompleteHandler
= MiniTransferDataComplete
;
1847 Adapter
->NdisMiniportBlock
.PacketIndicateHandler
= MiniIndicateReceivePacket
;
1848 Adapter
->NdisMiniportBlock
.StatusHandler
= MiniStatus
;
1849 Adapter
->NdisMiniportBlock
.StatusCompleteHandler
= MiniStatusComplete
;
1850 Adapter
->NdisMiniportBlock
.SendPacketsHandler
= ProSendPackets
;
1851 Adapter
->NdisMiniportBlock
.QueryCompleteHandler
= MiniRequestComplete
;
1852 Adapter
->NdisMiniportBlock
.SetCompleteHandler
= MiniRequestComplete
;
1855 * Call MiniportInitialize.
1858 NDIS_DbgPrint(MID_TRACE
, ("calling MiniportInitialize\n"));
1859 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.InitializeHandler
)(
1860 &OpenErrorStatus
, &SelectedMediumIndex
, &MediaArray
[0],
1861 MEDIA_ARRAY_SIZE
, Adapter
, (NDIS_HANDLE
)&WrapperContext
);
1863 ZwClose(WrapperContext
.RegistryHandle
);
1865 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1867 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() failed for an adapter.\n"));
1868 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1872 if (SelectedMediumIndex
>= MEDIA_ARRAY_SIZE
)
1874 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() selected a bad index\n"));
1875 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1876 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
1879 Adapter
->NdisMiniportBlock
.MediaType
= MediaArray
[SelectedMediumIndex
];
1881 switch (Adapter
->NdisMiniportBlock
.MediaType
)
1883 case NdisMedium802_3
:
1884 Adapter
->MediumHeaderSize
= 14; /* XXX figure out what to do about LLC */
1885 AddressOID
= OID_802_3_CURRENT_ADDRESS
;
1886 Adapter
->AddressLength
= ETH_LENGTH_OF_ADDRESS
;
1887 NdisStatus
= DoQueries(Adapter
, AddressOID
);
1888 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1890 NdisStatus
= MiniQueryInformation(Adapter
, OID_802_3_MAXIMUM_LIST_SIZE
, sizeof(UINT
),
1891 &MaxMulticastAddresses
, &BytesWritten
);
1893 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1895 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1896 NDIS_DbgPrint(MIN_TRACE
, ("MiniQueryInformation failed (%x)\n", NdisStatus
));
1900 Success
= EthCreateFilter(MaxMulticastAddresses
,
1901 Adapter
->Address
.Type
.Medium802_3
,
1902 &Adapter
->NdisMiniportBlock
.EthDB
);
1904 ((PETHI_FILTER
)Adapter
->NdisMiniportBlock
.EthDB
)->Miniport
= (PNDIS_MINIPORT_BLOCK
)Adapter
;
1906 NdisStatus
= NDIS_STATUS_RESOURCES
;
1911 /* FIXME: Support other types of media */
1912 NDIS_DbgPrint(MIN_TRACE
, ("error: unsupported media\n"));
1914 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1915 return STATUS_UNSUCCESSFUL
;
1918 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1920 NDIS_DbgPrint(MIN_TRACE
, ("couldn't create filter (%x)\n", NdisStatus
));
1924 /* Check for a hang every two seconds if it wasn't set in MiniportInitialize */
1925 if (Adapter
->NdisMiniportBlock
.CheckForHangSeconds
== 0)
1926 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= 2;
1928 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
1929 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStarted
;
1931 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, TRUE
);
1933 Timeout
.QuadPart
= Int32x32To64(Adapter
->NdisMiniportBlock
.CheckForHangSeconds
, -1000000);
1934 KeSetTimerEx(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
, Timeout
,
1935 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
* 1000,
1936 &Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
);
1938 /* Put adapter in adapter list for this miniport */
1939 ExInterlockedInsertTailList(&Adapter
->NdisMiniportBlock
.DriverHandle
->DeviceList
, &Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
1941 return STATUS_SUCCESS
;
1948 IN PDEVICE_OBJECT DeviceObject
,
1951 * FUNCTION: Handle the PnP stop device event
1953 * DeviceObejct = Functional Device Object
1954 * Irp = IRP_MN_STOP_DEVICE I/O request packet
1956 * Status of operation
1959 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1961 /* Remove adapter from adapter list for this miniport */
1962 ExInterlockedRemoveEntryList(&Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
1964 /* Remove adapter from global adapter list */
1965 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1967 KeCancelTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
1969 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.HaltHandler
)(Adapter
);
1971 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, FALSE
);
1973 if (Adapter
->NdisMiniportBlock
.AllocatedResources
)
1975 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1976 Adapter
->NdisMiniportBlock
.AllocatedResources
= NULL
;
1978 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
)
1980 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
);
1981 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
= NULL
;
1984 if (Adapter
->NdisMiniportBlock
.Resources
)
1986 ExFreePool(Adapter
->NdisMiniportBlock
.Resources
);
1987 Adapter
->NdisMiniportBlock
.Resources
= NULL
;
1990 if (Adapter
->NdisMiniportBlock
.EthDB
)
1992 EthDeleteFilter(Adapter
->NdisMiniportBlock
.EthDB
);
1993 Adapter
->NdisMiniportBlock
.EthDB
= NULL
;
1996 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
1997 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStopped
;
1999 return STATUS_SUCCESS
;
2005 IN PDEVICE_OBJECT DeviceObject
,
2008 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
2009 PMINIPORT_BUGCHECK_CONTEXT Context
= Adapter
->BugcheckContext
;
2010 ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
= Context
->ShutdownHandler
;
2012 ASSERT(ShutdownHandler
);
2014 ShutdownHandler(Context
->DriverContext
);
2016 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2017 Irp
->IoStatus
.Information
= 0;
2019 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2021 return STATUS_SUCCESS
;
2026 NdisIDeviceIoControl(
2027 IN PDEVICE_OBJECT DeviceObject
,
2030 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2031 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2032 NDIS_STATUS Status
= STATUS_NOT_SUPPORTED
;
2034 Irp
->IoStatus
.Information
= 0;
2038 switch (Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
2040 case IOCTL_NDIS_QUERY_GLOBAL_STATS
:
2041 Status
= MiniQueryInformation(Adapter
,
2042 *(PNDIS_OID
)Irp
->AssociatedIrp
.SystemBuffer
,
2043 Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
,
2044 MmGetSystemAddressForMdl(Irp
->MdlAddress
),
2045 &Irp
->IoStatus
.Information
);
2053 if (Status
!= NDIS_STATUS_PENDING
)
2055 Irp
->IoStatus
.Status
= Status
;
2056 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2059 IoMarkIrpPending(Irp
);
2068 IN PDEVICE_OBJECT DeviceObject
,
2071 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2072 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2075 switch (Stack
->MinorFunction
)
2077 case IRP_MN_START_DEVICE
:
2078 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2079 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2081 Status
= NdisIPnPStartDevice(DeviceObject
, Irp
);
2084 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed device start\n"));
2085 Irp
->IoStatus
.Status
= Status
;
2086 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2089 case IRP_MN_STOP_DEVICE
:
2090 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2091 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2093 Status
= NdisIPnPStopDevice(DeviceObject
, Irp
);
2096 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed device stop\n"));
2097 Irp
->IoStatus
.Status
= Status
;
2098 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2101 case IRP_MN_QUERY_REMOVE_DEVICE
:
2102 case IRP_MN_QUERY_STOP_DEVICE
:
2103 Status
= NdisIPnPQueryStopDevice(DeviceObject
, Irp
);
2104 Irp
->IoStatus
.Status
= Status
;
2105 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2108 case IRP_MN_CANCEL_REMOVE_DEVICE
:
2109 case IRP_MN_CANCEL_STOP_DEVICE
:
2110 Status
= NdisIPnPCancelStopDevice(DeviceObject
, Irp
);
2111 Irp
->IoStatus
.Status
= Status
;
2112 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2115 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
2116 Status
= NDIS_STATUS_SUCCESS
;
2117 Irp
->IoStatus
.Status
= Status
;
2118 Irp
->IoStatus
.Information
|= Adapter
->NdisMiniportBlock
.PnPFlags
;
2119 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2123 IoSkipCurrentIrpStackLocation(Irp
);
2124 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
2135 IN PDRIVER_OBJECT DriverObject
,
2136 IN PDEVICE_OBJECT PhysicalDeviceObject
)
2138 * FUNCTION: Create a device for an adapter found using PnP
2140 * DriverObject = Pointer to the miniport driver object
2141 * PhysicalDeviceObject = Pointer to the PDO for our adapter
2144 static const WCHAR ClassKeyName
[] = {'C','l','a','s','s','\\'};
2145 static const WCHAR LinkageKeyName
[] = {'\\','L','i','n','k','a','g','e',0};
2146 PNDIS_M_DRIVER_BLOCK Miniport
;
2147 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2148 WCHAR
*LinkageKeyBuffer
;
2149 ULONG DriverKeyLength
;
2150 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
2151 UNICODE_STRING ExportName
;
2152 PDEVICE_OBJECT DeviceObject
;
2153 PLOGICAL_ADAPTER Adapter
;
2158 * Gain the access to the miniport data structure first.
2161 MiniportPtr
= IoGetDriverObjectExtension(DriverObject
, (PVOID
)'NMID');
2162 if (MiniportPtr
== NULL
)
2164 NDIS_DbgPrint(MIN_TRACE
, ("Can't get driver object extension.\n"));
2165 return NDIS_STATUS_FAILURE
;
2167 Miniport
= *MiniportPtr
;
2170 * Get name of the Linkage registry key for our adapter. It's located under
2171 * the driver key for our driver and so we have basicly two ways to do it.
2172 * Either we can use IoOpenDriverRegistryKey or compose it using information
2173 * gathered by IoGetDeviceProperty. I choosed the second because
2174 * IoOpenDriverRegistryKey wasn't implemented at the time of writing.
2177 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2178 0, NULL
, &DriverKeyLength
);
2179 if (Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
&& Status
!= STATUS_SUCCESS
)
2181 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key length.\n"));
2185 LinkageKeyBuffer
= ExAllocatePool(PagedPool
, DriverKeyLength
+
2186 sizeof(ClassKeyName
) + sizeof(LinkageKeyName
));
2187 if (LinkageKeyBuffer
== NULL
)
2189 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate memory for driver key name.\n"));
2190 return STATUS_INSUFFICIENT_RESOURCES
;
2193 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2194 DriverKeyLength
, LinkageKeyBuffer
+
2195 (sizeof(ClassKeyName
) / sizeof(WCHAR
)),
2197 if (!NT_SUCCESS(Status
))
2199 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key.\n"));
2200 ExFreePool(LinkageKeyBuffer
);
2204 /* Compose the linkage key name. */
2205 RtlCopyMemory(LinkageKeyBuffer
, ClassKeyName
, sizeof(ClassKeyName
));
2206 RtlCopyMemory(LinkageKeyBuffer
+ ((sizeof(ClassKeyName
) + DriverKeyLength
) /
2207 sizeof(WCHAR
)) - 1, LinkageKeyName
, sizeof(LinkageKeyName
));
2209 NDIS_DbgPrint(DEBUG_MINIPORT
, ("LinkageKey: %S.\n", LinkageKeyBuffer
));
2212 * Now open the linkage key and read the "Export" and "RootDevice" values
2213 * which contains device name and root service respectively.
2216 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
2217 RtlInitUnicodeString(&ExportName
, NULL
);
2218 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
| RTL_QUERY_REGISTRY_DIRECT
;
2219 QueryTable
[0].Name
= L
"Export";
2220 QueryTable
[0].EntryContext
= &ExportName
;
2222 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
, LinkageKeyBuffer
,
2223 QueryTable
, NULL
, NULL
);
2224 ExFreePool(LinkageKeyBuffer
);
2225 if (!NT_SUCCESS(Status
))
2227 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport device name. (%x)\n", Status
));
2232 * Create the device object.
2235 NDIS_DbgPrint(MAX_TRACE
, ("creating device %wZ\n", &ExportName
));
2237 Status
= IoCreateDevice(Miniport
->DriverObject
, sizeof(LOGICAL_ADAPTER
),
2238 &ExportName
, FILE_DEVICE_PHYSICAL_NETCARD
,
2239 0, FALSE
, &DeviceObject
);
2240 if (!NT_SUCCESS(Status
))
2242 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device object.\n"));
2243 RtlFreeUnicodeString(&ExportName
);
2248 * Initialize the adapter structure.
2251 Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2252 KeInitializeSpinLock(&Adapter
->NdisMiniportBlock
.Lock
);
2253 InitializeListHead(&Adapter
->ProtocolListHead
);
2255 Status
= IoRegisterDeviceInterface(PhysicalDeviceObject
,
2256 &GUID_DEVINTERFACE_NET
,
2258 &Adapter
->NdisMiniportBlock
.SymbolicLinkName
);
2260 if (!NT_SUCCESS(Status
))
2262 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device interface.\n"));
2263 IoDeleteDevice(DeviceObject
);
2264 RtlFreeUnicodeString(&ExportName
);
2268 Adapter
->NdisMiniportBlock
.DriverHandle
= Miniport
;
2269 Adapter
->NdisMiniportBlock
.MiniportName
= ExportName
;
2270 Adapter
->NdisMiniportBlock
.DeviceObject
= DeviceObject
;
2271 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
= PhysicalDeviceObject
;
2272 Adapter
->NdisMiniportBlock
.NextDeviceObject
=
2273 IoAttachDeviceToDeviceStack(Adapter
->NdisMiniportBlock
.DeviceObject
,
2274 PhysicalDeviceObject
);
2276 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= 0;
2277 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceAdded
;
2279 for (i
= 0; i
< NUMBER_OF_WORK_ITEM_TYPES
; i
++)
2280 Adapter
->NdisMiniportBlock
.WorkQueue
[i
].Next
= NULL
;
2282 KeInitializeTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2283 KeInitializeDpc(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
, MiniportHangDpc
, Adapter
);
2285 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
2287 return STATUS_SUCCESS
;
2296 NdisMRegisterMiniport(
2297 IN NDIS_HANDLE NdisWrapperHandle
,
2298 IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics
,
2299 IN UINT CharacteristicsLength
)
2301 * FUNCTION: Registers a miniport's MiniportXxx entry points with the NDIS library
2303 * NdisWrapperHandle = Pointer to handle returned by NdisMInitializeWrapper
2304 * MiniportCharacteristics = Pointer to a buffer with miniport characteristics
2305 * CharacteristicsLength = Number of bytes in characteristics buffer
2307 * Status of operation
2311 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2312 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2315 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2317 switch (MiniportCharacteristics
->MajorNdisVersion
)
2320 MinSize
= sizeof(NDIS30_MINIPORT_CHARACTERISTICS
);
2324 MinSize
= sizeof(NDIS40_MINIPORT_CHARACTERISTICS
);
2328 MinSize
= sizeof(NDIS50_MINIPORT_CHARACTERISTICS
);
2332 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics version.\n"));
2333 return NDIS_STATUS_BAD_VERSION
;
2336 NDIS_DbgPrint(MIN_TRACE
, ("Initializing an NDIS %u.%u miniport\n",
2337 MiniportCharacteristics
->MajorNdisVersion
,
2338 MiniportCharacteristics
->MinorNdisVersion
));
2340 if (CharacteristicsLength
< MinSize
)
2342 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics length.\n"));
2343 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2346 /* Check if mandatory MiniportXxx functions are specified */
2347 if ((!MiniportCharacteristics
->HaltHandler
) ||
2348 (!MiniportCharacteristics
->InitializeHandler
)||
2349 (!MiniportCharacteristics
->ResetHandler
))
2351 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics.\n"));
2352 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2355 if (MiniportCharacteristics
->MajorNdisVersion
< 0x05)
2357 if ((!MiniportCharacteristics
->QueryInformationHandler
) ||
2358 (!MiniportCharacteristics
->SetInformationHandler
))
2360 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2361 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2366 if (((!MiniportCharacteristics
->QueryInformationHandler
) ||
2367 (!MiniportCharacteristics
->SetInformationHandler
)) &&
2368 (!MiniportCharacteristics
->CoRequestHandler
))
2370 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2371 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2375 if (MiniportCharacteristics
->MajorNdisVersion
== 0x03)
2377 if (!MiniportCharacteristics
->SendHandler
)
2379 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 3.0)\n"));
2380 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2383 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x04)
2386 if ((!MiniportCharacteristics
->SendHandler
) &&
2387 (!MiniportCharacteristics
->SendPacketsHandler
))
2389 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 4.0)\n"));
2390 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2393 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x05)
2395 /* TODO: Add more checks here */
2397 if ((!MiniportCharacteristics
->SendHandler
) &&
2398 (!MiniportCharacteristics
->SendPacketsHandler
) &&
2399 (!MiniportCharacteristics
->CoSendPacketsHandler
))
2401 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 5.0)\n"));
2402 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2406 /* TODO: verify NDIS5 and NDIS5.1 */
2408 RtlCopyMemory(&Miniport
->MiniportCharacteristics
, MiniportCharacteristics
, MinSize
);
2411 * NOTE: This is VERY unoptimal! Should we store the NDIS_M_DRIVER_BLOCK
2412 * structure in the driver extension or what?
2415 Status
= IoAllocateDriverObjectExtension(Miniport
->DriverObject
, (PVOID
)'NMID',
2416 sizeof(PNDIS_M_DRIVER_BLOCK
), (PVOID
*)&MiniportPtr
);
2417 if (!NT_SUCCESS(Status
))
2419 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate driver object extension.\n"));
2420 return NDIS_STATUS_RESOURCES
;
2423 *MiniportPtr
= Miniport
;
2425 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
2426 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = NdisIShutdown
;
2427 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = NdisIDeviceIoControl
;
2428 Miniport
->DriverObject
->DriverExtension
->AddDevice
= NdisIAddDevice
;
2430 return NDIS_STATUS_SUCCESS
;
2437 #undef NdisMResetComplete
2441 IN NDIS_HANDLE MiniportAdapterHandle
,
2442 IN NDIS_STATUS Status
,
2443 IN BOOLEAN AddressingReset
)
2445 MiniResetComplete(MiniportAdapterHandle
, Status
, AddressingReset
);
2452 #undef NdisMSendComplete
2456 IN NDIS_HANDLE MiniportAdapterHandle
,
2457 IN PNDIS_PACKET Packet
,
2458 IN NDIS_STATUS Status
)
2460 * FUNCTION: Forwards a message to the initiating protocol saying
2461 * that a packet was handled
2463 * NdisAdapterHandle = Handle input to MiniportInitialize
2464 * Packet = Pointer to NDIS packet that was sent
2465 * Status = Status of send operation
2468 MiniSendComplete(MiniportAdapterHandle
, Packet
, Status
);
2475 #undef NdisMSendResourcesAvailable
2478 NdisMSendResourcesAvailable(
2479 IN NDIS_HANDLE MiniportAdapterHandle
)
2481 MiniSendResourcesAvailable(MiniportAdapterHandle
);
2488 #undef NdisMTransferDataComplete
2491 NdisMTransferDataComplete(
2492 IN NDIS_HANDLE MiniportAdapterHandle
,
2493 IN PNDIS_PACKET Packet
,
2494 IN NDIS_STATUS Status
,
2495 IN UINT BytesTransferred
)
2497 MiniTransferDataComplete(MiniportAdapterHandle
, Packet
, Status
, BytesTransferred
);
2504 #undef NdisMSetAttributes
2508 IN NDIS_HANDLE MiniportAdapterHandle
,
2509 IN NDIS_HANDLE MiniportAdapterContext
,
2510 IN BOOLEAN BusMaster
,
2511 IN NDIS_INTERFACE_TYPE AdapterType
)
2513 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2515 * MiniportAdapterHandle = Handle input to MiniportInitialize
2516 * MiniportAdapterContext = Pointer to context information
2517 * BusMaster = Specifies TRUE if the caller's NIC is a busmaster DMA device
2518 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2521 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2522 NdisMSetAttributesEx(MiniportAdapterHandle
, MiniportAdapterContext
, 0,
2523 BusMaster
? NDIS_ATTRIBUTE_BUS_MASTER
: 0,
2533 NdisMSetAttributesEx(
2534 IN NDIS_HANDLE MiniportAdapterHandle
,
2535 IN NDIS_HANDLE MiniportAdapterContext
,
2536 IN UINT CheckForHangTimeInSeconds OPTIONAL
,
2537 IN ULONG AttributeFlags
,
2538 IN NDIS_INTERFACE_TYPE AdapterType
)
2540 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2542 * MiniportAdapterHandle = Handle input to MiniportInitialize
2543 * MiniportAdapterContext = Pointer to context information
2544 * CheckForHangTimeInSeconds = Specifies interval in seconds at which
2545 * MiniportCheckForHang should be called
2546 * AttributeFlags = Bitmask that indicates specific attributes
2547 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2550 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(MiniportAdapterHandle
);
2552 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2554 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
= MiniportAdapterContext
;
2555 Adapter
->NdisMiniportBlock
.Flags
= AttributeFlags
;
2556 Adapter
->NdisMiniportBlock
.AdapterType
= AdapterType
;
2557 if (CheckForHangTimeInSeconds
> 0)
2558 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= CheckForHangTimeInSeconds
;
2559 if (AttributeFlags
& NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER
)
2560 NDIS_DbgPrint(MAX_TRACE
, ("Intermediate drivers not supported yet.\n"));
2563 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
)
2565 NDIS_DbgPrint(MAX_TRACE
, ("Miniport set AdapterShutdownHandler in MiniportCharacteristics\n"));
2566 NdisMRegisterAdapterShutdownHandler(Adapter
,
2567 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
2568 Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
);
2579 IN ULONG MicrosecondsToSleep
)
2581 * FUNCTION: delay the thread's execution for MicrosecondsToSleep
2583 * MicrosecondsToSleep: duh...
2585 * - Because this is a blocking call, current IRQL must be < DISPATCH_LEVEL
2589 LARGE_INTEGER DueTime
;
2593 DueTime
.QuadPart
= (-1) * 10 * MicrosecondsToSleep
;
2595 KeInitializeTimer(&Timer
);
2596 KeSetTimer(&Timer
, DueTime
, 0);
2597 KeWaitForSingleObject(&Timer
, Executive
, KernelMode
, FALSE
, 0);
2606 NdisMSynchronizeWithInterrupt(
2607 IN PNDIS_MINIPORT_INTERRUPT Interrupt
,
2608 IN PVOID SynchronizeFunction
,
2609 IN PVOID SynchronizeContext
)
2611 return(KeSynchronizeExecution(Interrupt
->InterruptObject
,
2612 (PKSYNCHRONIZE_ROUTINE
)SynchronizeFunction
,
2613 SynchronizeContext
));
2623 IN NDIS_HANDLE LogHandle
,
2625 IN UINT LogBufferSize
)
2627 PUCHAR Buffer
= LogBuffer
;
2631 for (i
= 0; i
< LogBufferSize
; i
+= 16)
2633 DbgPrint("%08x |", i
);
2634 for (j
= 0; j
< 16; j
++)
2637 if (idx
< LogBufferSize
)
2638 DbgPrint(" %02x", Buffer
[idx
]);
2643 for (j
= 0; j
< 16; j
++)
2646 if (idx
== LogBufferSize
)
2648 if (Buffer
[idx
] >= ' ') /* FIXME: not portable! replace by if (isprint(Buffer[idx])) ? */
2649 DbgPrint("%c", Buffer
[idx
]);
2656 return NDIS_STATUS_FAILURE
;
2665 NdisTerminateWrapper(
2666 IN NDIS_HANDLE NdisWrapperHandle
,
2667 IN PVOID SystemSpecific
)
2669 * FUNCTION: Releases resources allocated by a call to NdisInitializeWrapper
2671 * NdisWrapperHandle = Handle returned by NdisInitializeWrapper (NDIS_M_DRIVER_BLOCK)
2672 * SystemSpecific = Always NULL
2675 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2677 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2679 ExFreePool(Miniport
->RegistryPath
->Buffer
);
2680 ExFreePool(Miniport
->RegistryPath
);
2681 ExInterlockedRemoveEntryList(&Miniport
->ListEntry
, &MiniportListLock
);
2682 ExFreePool(Miniport
);
2691 NdisMQueryAdapterInstanceName(
2692 OUT PNDIS_STRING AdapterInstanceName
,
2693 IN NDIS_HANDLE MiniportAdapterHandle
)
2701 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
2702 UNICODE_STRING AdapterName
;
2704 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2706 AdapterName
.Length
= 0;
2707 AdapterName
.MaximumLength
= Adapter
->NdisMiniportBlock
.MiniportName
.MaximumLength
;
2708 AdapterName
.Buffer
= ExAllocatePool(PagedPool
, AdapterName
.MaximumLength
);
2709 if (!AdapterName
.Buffer
) {
2710 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
2711 return NDIS_STATUS_RESOURCES
;
2714 RtlCopyUnicodeString(&AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
);
2716 *AdapterInstanceName
= AdapterName
;
2718 return NDIS_STATUS_SUCCESS
;
2726 NdisDeregisterAdapterShutdownHandler(
2727 IN NDIS_HANDLE NdisAdapterHandle
)
2735 NdisMDeregisterAdapterShutdownHandler(NdisAdapterHandle
);
2744 NdisRegisterAdapterShutdownHandler(
2745 IN NDIS_HANDLE NdisAdapterHandle
,
2746 IN PVOID ShutdownContext
,
2747 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
2755 NdisMRegisterAdapterShutdownHandler(NdisAdapterHandle
,
2765 NdisMGetDeviceProperty(
2766 IN NDIS_HANDLE MiniportAdapterHandle
,
2767 IN OUT PDEVICE_OBJECT
*PhysicalDeviceObject OPTIONAL
,
2768 IN OUT PDEVICE_OBJECT
*FunctionalDeviceObject OPTIONAL
,
2769 IN OUT PDEVICE_OBJECT
*NextDeviceObject OPTIONAL
,
2770 IN OUT PCM_RESOURCE_LIST
*AllocatedResources OPTIONAL
,
2771 IN OUT PCM_RESOURCE_LIST
*AllocatedResourcesTranslated OPTIONAL
)
2779 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
2781 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2783 if (PhysicalDeviceObject
!= NULL
)
2784 *PhysicalDeviceObject
= Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
;
2786 if (FunctionalDeviceObject
!= NULL
)
2787 *FunctionalDeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
2789 if (NextDeviceObject
!= NULL
)
2790 *NextDeviceObject
= Adapter
->NdisMiniportBlock
.NextDeviceObject
;
2792 if (AllocatedResources
!= NULL
)
2793 *AllocatedResources
= Adapter
->NdisMiniportBlock
.AllocatedResources
;
2795 if (AllocatedResourcesTranslated
!= NULL
)
2796 *AllocatedResourcesTranslated
= Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
;
2804 NdisMRegisterUnloadHandler(
2805 IN NDIS_HANDLE NdisWrapperHandle
,
2806 IN PDRIVER_UNLOAD UnloadHandler
)
2814 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2816 NDIS_DbgPrint(MAX_TRACE
, ("Miniport registered unload handler\n"));
2818 DriverBlock
->DriverObject
->DriverUnload
= UnloadHandler
;
2826 NdisMRegisterDevice(
2827 IN NDIS_HANDLE NdisWrapperHandle
,
2828 IN PNDIS_STRING DeviceName
,
2829 IN PNDIS_STRING SymbolicName
,
2830 IN PDRIVER_DISPATCH MajorFunctions
[],
2831 OUT PDEVICE_OBJECT
*pDeviceObject
,
2832 OUT NDIS_HANDLE
*NdisDeviceHandle
)
2840 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2841 PNDIS_M_DEVICE_BLOCK DeviceBlock
;
2842 PDEVICE_OBJECT DeviceObject
;
2846 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2848 Status
= IoCreateDevice(DriverBlock
->DriverObject
,
2849 0, /* This space is reserved for us. Should we use it? */
2851 FILE_DEVICE_NETWORK
,
2856 if (!NT_SUCCESS(Status
))
2858 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateDevice failed (%x)\n", Status
));
2862 Status
= IoCreateSymbolicLink(SymbolicName
, DeviceName
);
2864 if (!NT_SUCCESS(Status
))
2866 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateSymbolicLink failed (%x)\n", Status
));
2867 IoDeleteDevice(DeviceObject
);
2871 DeviceBlock
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DEVICE_BLOCK
));
2875 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
2876 IoDeleteDevice(DeviceObject
);
2877 IoDeleteSymbolicLink(SymbolicName
);
2878 return NDIS_STATUS_RESOURCES
;
2881 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
2882 DriverBlock
->DriverObject
->MajorFunction
[i
] = MajorFunctions
[i
];
2884 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
2886 DeviceBlock
->DeviceObject
= DeviceObject
;
2887 DeviceBlock
->SymbolicName
= SymbolicName
;
2889 *pDeviceObject
= DeviceObject
;
2890 *NdisDeviceHandle
= DeviceBlock
;
2892 return NDIS_STATUS_SUCCESS
;
2900 NdisMDeregisterDevice(
2901 IN NDIS_HANDLE NdisDeviceHandle
)
2909 PNDIS_M_DEVICE_BLOCK DeviceBlock
= NdisDeviceHandle
;
2911 IoDeleteDevice(DeviceBlock
->DeviceObject
);
2913 IoDeleteSymbolicLink(DeviceBlock
->SymbolicName
);
2915 ExFreePool(DeviceBlock
);
2917 return NDIS_STATUS_SUCCESS
;
2925 NdisQueryAdapterInstanceName(
2926 OUT PNDIS_STRING AdapterInstanceName
,
2927 IN NDIS_HANDLE NdisBindingHandle
)
2935 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
2936 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
2938 return NdisMQueryAdapterInstanceName(AdapterInstanceName
,
2947 NdisCompletePnPEvent(
2948 IN NDIS_STATUS Status
,
2949 IN NDIS_HANDLE NdisBindingHandle
,
2950 IN PNET_PNP_EVENT NetPnPEvent
)
2958 PIRP Irp
= (PIRP
)NetPnPEvent
->NdisReserved
[0];
2959 PLIST_ENTRY CurrentEntry
= (PLIST_ENTRY
)NetPnPEvent
->NdisReserved
[1];
2960 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
2961 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
2962 NDIS_STATUS NdisStatus
;
2964 if (Status
!= NDIS_STATUS_SUCCESS
)
2966 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
2967 ExFreePool(NetPnPEvent
);
2968 Irp
->IoStatus
.Status
= Status
;
2969 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2973 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
2975 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
2977 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.PnPEventHandler
)(
2978 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
2981 if (NdisStatus
== NDIS_STATUS_PENDING
)
2983 NetPnPEvent
->NdisReserved
[1] = (ULONG_PTR
)CurrentEntry
->Flink
;
2986 else if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2988 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
2989 ExFreePool(NetPnPEvent
);
2990 Irp
->IoStatus
.Status
= NdisStatus
;
2991 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2995 CurrentEntry
= CurrentEntry
->Flink
;
2998 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
2999 ExFreePool(NetPnPEvent
);
3001 Irp
->IoStatus
.Status
= NDIS_STATUS_SUCCESS
;
3002 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3010 NdisCancelSendPackets(
3011 IN NDIS_HANDLE NdisBindingHandle
,
3014 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3015 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3017 NDIS_DbgPrint(MAX_TRACE
, ("Called for ID %x.\n", CancelId
));
3019 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)
3021 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)(
3022 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
3033 NdisIMGetBindingContext(
3034 IN NDIS_HANDLE NdisBindingHandle
)
3042 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3043 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3045 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3047 return Adapter
->NdisMiniportBlock
.DeviceContext
;
3056 NdisIMGetDeviceContext(
3057 IN NDIS_HANDLE MiniportAdapterHandle
)
3065 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
3067 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3069 return Adapter
->NdisMiniportBlock
.DeviceContext
;