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");
124 PNDIS_MINIPORT_WORK_ITEM
125 MiniGetFirstWorkItem(
126 PLOGICAL_ADAPTER Adapter
,
127 NDIS_WORK_ITEM_TYPE Type
)
129 PNDIS_MINIPORT_WORK_ITEM CurrentEntry
= Adapter
->WorkQueueHead
;
133 if (CurrentEntry
->WorkItemType
== Type
)
136 CurrentEntry
= (PNDIS_MINIPORT_WORK_ITEM
)CurrentEntry
->Link
.Next
;
144 PLOGICAL_ADAPTER Adapter
,
145 NDIS_WORK_ITEM_TYPE Type
)
147 BOOLEAN Busy
= FALSE
;
150 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
152 if (Type
== NdisWorkItemRequest
&&
153 (Adapter
->NdisMiniportBlock
.PendingRequest
|| MiniGetFirstWorkItem(Adapter
, NdisWorkItemRequest
)))
157 else if (Type
== NdisWorkItemSend
&&
158 (Adapter
->NdisMiniportBlock
.FirstPendingPacket
|| MiniGetFirstWorkItem(Adapter
, NdisWorkItemSend
)))
162 else if (Type
== NdisWorkItemResetRequested
&&
163 (Adapter
->NdisMiniportBlock
.ResetStatus
== NDIS_STATUS_PENDING
|| MiniGetFirstWorkItem(Adapter
, NdisWorkItemResetRequested
)))
168 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(DEBUG_MINIPORT
, ("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"));
253 MiniIndicateReceivePacket(
254 IN NDIS_HANDLE MiniportAdapterHandle
,
255 IN PPNDIS_PACKET PacketArray
,
256 IN UINT NumberOfPackets
)
258 * FUNCTION: receives miniport packet array indications
260 * MiniportAdapterHandle: Miniport handle for the adapter
261 * PacketArray: pointer to a list of packet pointers to indicate
262 * NumberOfPackets: number of packets to indicate
266 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
267 PLIST_ENTRY CurrentEntry
;
268 PADAPTER_BINDING AdapterBinding
;
272 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
274 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
276 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
278 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
280 if (AdapterBinding
->ProtocolBinding
->Chars
.ReceivePacketHandler
)
282 for (i
= 0; i
< NumberOfPackets
; i
++)
284 (*AdapterBinding
->ProtocolBinding
->Chars
.ReceivePacketHandler
)(
285 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
291 for (i
= 0; i
< NumberOfPackets
; i
++)
293 UINT FirstBufferLength
, TotalBufferLength
, LookAheadSize
, HeaderSize
;
294 PNDIS_BUFFER NdisBuffer
;
295 PVOID NdisBufferVA
, LookAheadBuffer
;
296 NDIS_STATUS NdisStatus
;
299 NdisGetFirstBufferFromPacket(PacketArray
[i
],
305 HeaderSize
= NDIS_GET_PACKET_HEADER_SIZE(PacketArray
[i
]);
307 if (Adapter
->NdisMiniportBlock
.CurrentLookahead
< (TotalBufferLength
- HeaderSize
))
309 LookAheadSize
= Adapter
->NdisMiniportBlock
.CurrentLookahead
;
313 LookAheadSize
= TotalBufferLength
- HeaderSize
;
317 LookAheadBuffer
= ExAllocatePool(NonPagedPool
, LookAheadSize
);
318 if (!LookAheadBuffer
)
320 NDIS_DbgPrint(MIN_TRACE
, ("Failed to allocate lookahead buffer!\n"));
324 CopyBufferChainToBuffer(LookAheadBuffer
,
329 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
)(
330 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
331 AdapterBinding
->NdisOpenBlock
.MacHandle
,
336 TotalBufferLength
- HeaderSize
);
338 NDIS_SET_PACKET_STATUS(PacketArray
[i
], NdisStatus
);
340 ExFreePool(LookAheadBuffer
);
344 CurrentEntry
= CurrentEntry
->Flink
;
347 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
353 IN NDIS_HANDLE MiniportAdapterHandle
,
354 IN NDIS_STATUS Status
,
355 IN BOOLEAN AddressingReset
)
357 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
358 PLIST_ENTRY CurrentEntry
;
359 PADAPTER_BINDING AdapterBinding
;
362 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
363 NdisMIndicateStatusComplete(Adapter
);
365 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
367 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
369 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
371 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
373 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
375 (*AdapterBinding
->ProtocolBinding
->Chars
.ResetCompleteHandler
)(
376 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
379 CurrentEntry
= CurrentEntry
->Flink
;
382 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
387 IN NDIS_HANDLE MiniportAdapterHandle
,
388 IN NDIS_STATUS Status
)
390 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
391 PNDIS_REQUEST Request
;
392 PNDIS_REQUEST_MAC_BLOCK MacBlock
;
395 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
397 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
399 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
400 Request
= Adapter
->NdisMiniportBlock
.PendingRequest
;
401 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
403 MacBlock
= (PNDIS_REQUEST_MAC_BLOCK
)Request
->MacReserved
;
405 if( MacBlock
->Binding
->RequestCompleteHandler
) {
406 (*MacBlock
->Binding
->RequestCompleteHandler
)(
407 MacBlock
->Binding
->ProtocolBindingContext
,
412 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
413 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
414 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
416 KeLowerIrql(OldIrql
);
421 IN NDIS_HANDLE MiniportAdapterHandle
,
422 IN PNDIS_PACKET Packet
,
423 IN NDIS_STATUS Status
)
425 * FUNCTION: Forwards a message to the initiating protocol saying
426 * that a packet was handled
428 * NdisAdapterHandle = Handle input to MiniportInitialize
429 * Packet = Pointer to NDIS packet that was sent
430 * Status = Status of send operation
433 PADAPTER_BINDING AdapterBinding
;
436 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
438 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
440 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
441 (*AdapterBinding
->ProtocolBinding
->Chars
.SendCompleteHandler
)(
442 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
445 KeLowerIrql(OldIrql
);
450 MiniSendResourcesAvailable(
451 IN NDIS_HANDLE MiniportAdapterHandle
)
460 MiniTransferDataComplete(
461 IN NDIS_HANDLE MiniportAdapterHandle
,
462 IN PNDIS_PACKET Packet
,
463 IN NDIS_STATUS Status
,
464 IN UINT BytesTransferred
)
466 PADAPTER_BINDING AdapterBinding
;
469 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
471 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
473 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
474 (*AdapterBinding
->ProtocolBinding
->Chars
.TransferDataCompleteHandler
)(
475 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
479 KeLowerIrql(OldIrql
);
484 MiniAdapterHasAddress(
485 PLOGICAL_ADAPTER Adapter
,
488 * FUNCTION: Determines whether a packet has the same destination address as an adapter
490 * Adapter = Pointer to logical adapter object
491 * Packet = Pointer to NDIS packet
493 * TRUE if the destination address is that of the adapter, FALSE if not
499 PNDIS_BUFFER NdisBuffer
;
502 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
507 NDIS_DbgPrint(MID_TRACE
, ("Adapter object was null\n"));
513 NDIS_DbgPrint(MID_TRACE
, ("Packet was null\n"));
518 NdisQueryPacket(Packet
, NULL
, NULL
, &NdisBuffer
, NULL
);
522 NDIS_DbgPrint(MID_TRACE
, ("Packet contains no buffers.\n"));
526 NdisQueryBuffer(NdisBuffer
, (PVOID
)&Start2
, &BufferLength
);
528 /* FIXME: Should handle fragmented packets */
530 switch (Adapter
->NdisMiniportBlock
.MediaType
)
532 case NdisMedium802_3
:
533 Length
= ETH_LENGTH_OF_ADDRESS
;
534 /* Destination address is the first field */
538 NDIS_DbgPrint(MIN_TRACE
, ("Adapter has unsupported media type (0x%X).\n", Adapter
->NdisMiniportBlock
.MediaType
));
542 if (BufferLength
< Length
)
544 NDIS_DbgPrint(MID_TRACE
, ("Buffer is too small.\n"));
548 Start1
= (PUCHAR
)&Adapter
->Address
;
549 NDIS_DbgPrint(MAX_TRACE
, ("packet address: %x:%x:%x:%x:%x:%x adapter address: %x:%x:%x:%x:%x:%x\n",
550 *((char *)Start1
), *(((char *)Start1
)+1), *(((char *)Start1
)+2), *(((char *)Start1
)+3), *(((char *)Start1
)+4), *(((char *)Start1
)+5),
551 *((char *)Start2
), *(((char *)Start2
)+1), *(((char *)Start2
)+2), *(((char *)Start2
)+3), *(((char *)Start2
)+4), *(((char *)Start2
)+5))
554 return (RtlCompareMemory((PVOID
)Start1
, (PVOID
)Start2
, Length
) == Length
);
560 PNDIS_STRING AdapterName
)
562 * FUNCTION: Finds an adapter object by name
564 * AdapterName = Pointer to name of adapter
566 * Pointer to logical adapter object, or NULL if none was found.
567 * If found, the adapter is referenced for the caller. The caller
568 * is responsible for dereferencing after use
572 PLIST_ENTRY CurrentEntry
;
573 PLOGICAL_ADAPTER Adapter
= 0;
577 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
579 if(IsListEmpty(&AdapterListHead
))
581 NDIS_DbgPrint(DEBUG_MINIPORT
, ("No registered miniports for protocol to bind to\n"));
585 KeAcquireSpinLock(&AdapterListLock
, &OldIrql
);
587 CurrentEntry
= AdapterListHead
.Flink
;
589 while (CurrentEntry
!= &AdapterListHead
)
591 Adapter
= CONTAINING_RECORD(CurrentEntry
, LOGICAL_ADAPTER
, ListEntry
);
595 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Examining adapter 0x%lx\n", Adapter
));
596 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterName = %wZ\n", AdapterName
));
597 NDIS_DbgPrint(DEBUG_MINIPORT
, ("DeviceName = %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
599 if (RtlCompareUnicodeString(AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
, TRUE
) == 0)
605 CurrentEntry
= CurrentEntry
->Flink
;
608 KeReleaseSpinLock(&AdapterListLock
, OldIrql
);
612 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Leaving. Adapter found at 0x%x\n", Adapter
));
616 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Leaving (adapter not found).\n"));
624 MiniQueryInformation(
625 PLOGICAL_ADAPTER Adapter
,
631 * FUNCTION: Queries a logical adapter for properties
633 * Adapter = Pointer to the logical adapter object to query
634 * Oid = Specifies the Object ID to query for
635 * Size = Size of the passed buffer
636 * Buffer = Buffer for the output
637 * BytesWritten = Address of buffer to place number of bytes written
639 * If the specified buffer is too small, a new buffer is allocated,
640 * and the query is attempted again
642 * Status of operation
644 * Is there any way to use the buffer provided by the protocol?
647 NDIS_STATUS NdisStatus
;
651 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
653 /* call the miniport's queryinfo handler */
654 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
655 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.QueryInformationHandler
)(
656 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
662 KeLowerIrql(OldIrql
);
664 /* FIXME: Wait in pending case! */
670 MiniCheckForHang( PLOGICAL_ADAPTER Adapter
)
672 * FUNCTION: Checks to see if the miniport is hung
674 * Adapter = Pointer to the logical adapter object
676 * TRUE if the miniport is hung
677 * FALSE if the miniport is not hung
683 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
684 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)
685 Ret
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)(
686 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
);
687 KeLowerIrql(OldIrql
);
694 PLOGICAL_ADAPTER Adapter
,
695 PBOOLEAN AddressingReset
)
697 * FUNCTION: Resets the miniport
699 * Adapter = Pointer to the logical adapter object
700 * AddressingReset = Set to TRUE if we need to call MiniportSetInformation later
702 * Status of the operation
708 if (MiniIsBusy(Adapter
, NdisWorkItemResetRequested
)) {
709 MiniQueueWorkItem(Adapter
, NdisWorkItemResetRequested
, NULL
, FALSE
);
710 return NDIS_STATUS_PENDING
;
713 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
714 NdisMIndicateStatusComplete(Adapter
);
716 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
717 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
718 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
721 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
722 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
723 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
725 KeLowerIrql(OldIrql
);
727 if (Status
!= NDIS_STATUS_PENDING
) {
728 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
729 NdisMIndicateStatusComplete(Adapter
);
738 PVOID DeferredContext
,
739 PVOID SystemArgument1
,
740 PVOID SystemArgument2
)
742 PLOGICAL_ADAPTER Adapter
= DeferredContext
;
743 BOOLEAN AddressingReset
= FALSE
;
746 if (MiniCheckForHang(Adapter
)) {
747 NDIS_DbgPrint(MIN_TRACE
, ("Miniport detected adapter hang\n"));
748 MiniReset(Adapter
, &AddressingReset
);
751 /* FIXME: We should call MiniportSetInformation if AddressingReset is TRUE */
758 PLOGICAL_ADAPTER Adapter
,
759 NDIS_WORK_ITEM_TYPE WorkItemType
,
760 PVOID WorkItemContext
,
763 * FUNCTION: Queues a work item for execution at a later time
765 * Adapter = Pointer to the logical adapter object to queue work item on
766 * WorkItemType = Type of work item to queue
767 * WorkItemContext = Pointer to context information for work item
769 * Status of operation
772 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
773 PIO_WORKITEM IoWorkItem
;
776 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
780 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
783 if (WorkItemType
== NdisWorkItemSend
)
785 NDIS_DbgPrint(MIN_TRACE
, ("Requeuing failed packet (%x).\n", WorkItemContext
));
786 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= WorkItemContext
;
790 //This should never happen
796 MiniportWorkItem
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_MINIPORT_WORK_ITEM
));
797 if (!MiniportWorkItem
)
799 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
800 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
804 MiniportWorkItem
->WorkItemType
= WorkItemType
;
805 MiniportWorkItem
->WorkItemContext
= WorkItemContext
;
807 /* safe due to adapter lock held */
808 MiniportWorkItem
->Link
.Next
= NULL
;
809 if (!Adapter
->WorkQueueHead
)
811 Adapter
->WorkQueueHead
= MiniportWorkItem
;
812 Adapter
->WorkQueueTail
= MiniportWorkItem
;
816 Adapter
->WorkQueueTail
->Link
.Next
= (PSINGLE_LIST_ENTRY
)MiniportWorkItem
;
817 Adapter
->WorkQueueTail
= MiniportWorkItem
;
821 IoWorkItem
= IoAllocateWorkItem(Adapter
->NdisMiniportBlock
.DeviceObject
);
823 IoQueueWorkItem(IoWorkItem
, MiniportWorker
, DelayedWorkQueue
, IoWorkItem
);
825 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
832 PLOGICAL_ADAPTER Adapter
,
833 NDIS_WORK_ITEM_TYPE
*WorkItemType
,
834 PVOID
*WorkItemContext
)
836 * FUNCTION: Dequeues a work item from the work queue of a logical adapter
838 * Adapter = Pointer to the logical adapter object to dequeue work item from
839 * AdapterBinding = Address of buffer for adapter binding for this request
840 * WorkItemType = Address of buffer for work item type
841 * WorkItemContext = Address of buffer for pointer to context information
843 * Adapter lock must be held when called
845 * Status of operation
848 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
851 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
853 MiniportWorkItem
= Adapter
->WorkQueueHead
;
855 if ((Packet
= Adapter
->NdisMiniportBlock
.FirstPendingPacket
))
857 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= NULL
;
859 *WorkItemType
= NdisWorkItemSend
;
860 *WorkItemContext
= Packet
;
862 return NDIS_STATUS_SUCCESS
;
864 else if (MiniportWorkItem
)
866 /* safe due to adapter lock held */
867 Adapter
->WorkQueueHead
= (PNDIS_MINIPORT_WORK_ITEM
)MiniportWorkItem
->Link
.Next
;
869 if (MiniportWorkItem
== Adapter
->WorkQueueTail
)
870 Adapter
->WorkQueueTail
= NULL
;
872 *WorkItemType
= MiniportWorkItem
->WorkItemType
;
873 *WorkItemContext
= MiniportWorkItem
->WorkItemContext
;
875 ExFreePool(MiniportWorkItem
);
877 return NDIS_STATUS_SUCCESS
;
881 return NDIS_STATUS_FAILURE
;
888 PLOGICAL_ADAPTER Adapter
,
889 PNDIS_REQUEST NdisRequest
)
891 * FUNCTION: Sends a request to a miniport
893 * AdapterBinding = Pointer to binding used in the request
894 * NdisRequest = Pointer to NDIS request structure describing request
896 * Status of operation
901 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
903 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
905 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
906 Adapter
->NdisMiniportBlock
.PendingRequest
= NdisRequest
;
907 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
909 switch (NdisRequest
->RequestType
)
911 case NdisRequestQueryInformation
:
912 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.QueryInformationHandler
)(
913 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
914 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
,
915 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
,
916 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
,
917 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
,
918 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesNeeded
);
921 case NdisRequestSetInformation
:
922 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SetInformationHandler
)(
923 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
924 NdisRequest
->DATA
.SET_INFORMATION
.Oid
,
925 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
,
926 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
,
927 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
,
928 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesNeeded
);
932 Status
= NDIS_STATUS_FAILURE
;
935 if (Status
!= NDIS_STATUS_PENDING
) {
936 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
937 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
938 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
941 KeLowerIrql(OldIrql
);
949 #undef NdisMSetInformationComplete
952 NdisMSetInformationComplete(
953 IN NDIS_HANDLE MiniportAdapterHandle
,
954 IN NDIS_STATUS Status
)
956 PLOGICAL_ADAPTER Adapter
=
957 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
960 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
961 if (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)
962 (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)(MiniportAdapterHandle
, Status
);
963 KeLowerIrql(OldIrql
);
970 #undef NdisMQueryInformationComplete
973 NdisMQueryInformationComplete(
974 IN NDIS_HANDLE MiniportAdapterHandle
,
975 IN NDIS_STATUS Status
)
977 PLOGICAL_ADAPTER Adapter
=
978 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
981 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
982 if( Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)
983 (Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)(MiniportAdapterHandle
, Status
);
984 KeLowerIrql(OldIrql
);
989 MiniportWorker(IN PDEVICE_OBJECT DeviceObject
, IN PVOID Context
)
991 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
992 KIRQL OldIrql
, RaiseOldIrql
;
993 NDIS_STATUS NdisStatus
;
994 PVOID WorkItemContext
;
995 NDIS_WORK_ITEM_TYPE WorkItemType
;
996 BOOLEAN AddressingReset
;
998 IoFreeWorkItem((PIO_WORKITEM
)Context
);
1000 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1004 (Adapter
, &WorkItemType
, &WorkItemContext
);
1006 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1008 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1010 switch (WorkItemType
)
1012 case NdisWorkItemSend
:
1014 * called by ProSend when protocols want to send packets to the miniport
1017 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
1019 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1021 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1022 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1023 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1024 NdisStatus
= NDIS_STATUS_PENDING
;
1028 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
1029 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1031 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1032 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1033 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1035 KeLowerIrql(RaiseOldIrql
);
1037 NdisStatus
= NDIS_GET_PACKET_STATUS((PNDIS_PACKET
)WorkItemContext
);
1038 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1039 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1046 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1048 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1049 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1050 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1051 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1052 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1056 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
1057 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1058 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1059 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1060 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1061 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1062 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1063 KeLowerIrql(RaiseOldIrql
);
1064 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1065 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1071 if( NdisStatus
!= NDIS_STATUS_PENDING
) {
1073 ( Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1077 case NdisWorkItemSendLoopback
:
1079 * called by ProSend when protocols want to send loopback packets
1081 /* XXX atm ProIndicatePacket sends a packet up via the loopback adapter only */
1082 NdisStatus
= ProIndicatePacket(Adapter
, (PNDIS_PACKET
)WorkItemContext
);
1084 if( NdisStatus
!= NDIS_STATUS_PENDING
)
1085 MiniSendComplete((NDIS_HANDLE
)Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1088 case NdisWorkItemReturnPackets
:
1091 case NdisWorkItemResetRequested
:
1092 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
1093 NdisMIndicateStatusComplete(Adapter
);
1095 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1096 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
1097 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1100 if (NdisStatus
== NDIS_STATUS_PENDING
)
1102 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1103 Adapter
->NdisMiniportBlock
.ResetStatus
= NDIS_STATUS_PENDING
;
1104 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1107 KeLowerIrql(OldIrql
);
1109 if (NdisStatus
!= NDIS_STATUS_PENDING
)
1110 MiniResetComplete(Adapter
, NdisStatus
, AddressingReset
);
1113 case NdisWorkItemResetInProgress
:
1116 case NdisWorkItemMiniportCallback
:
1119 case NdisWorkItemRequest
:
1120 NdisStatus
= MiniDoRequest(Adapter
, (PNDIS_REQUEST
)WorkItemContext
);
1122 if (NdisStatus
== NDIS_STATUS_PENDING
)
1125 switch (((PNDIS_REQUEST
)WorkItemContext
)->RequestType
)
1127 case NdisRequestQueryInformation
:
1128 NdisMQueryInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1131 case NdisRequestSetInformation
:
1132 NdisMSetInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1136 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS request type.\n"));
1142 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS work item type (%d).\n", WorkItemType
));
1153 IN NDIS_HANDLE MiniportHandle
,
1154 IN NDIS_STATUS GeneralStatus
,
1155 IN PVOID StatusBuffer
,
1156 IN UINT StatusBufferSize
)
1158 PLOGICAL_ADAPTER Adapter
= MiniportHandle
;
1159 PLIST_ENTRY CurrentEntry
;
1160 PADAPTER_BINDING AdapterBinding
;
1163 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1165 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1167 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1169 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1171 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusHandler
)(
1172 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
1177 CurrentEntry
= CurrentEntry
->Flink
;
1180 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1187 IN NDIS_HANDLE MiniportAdapterHandle
)
1189 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1190 PLIST_ENTRY CurrentEntry
;
1191 PADAPTER_BINDING AdapterBinding
;
1194 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1196 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1198 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1200 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1202 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusCompleteHandler
)(
1203 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
);
1205 CurrentEntry
= CurrentEntry
->Flink
;
1208 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1218 IN NDIS_HANDLE LogHandle
)
1220 PNDIS_LOG Log
= (PNDIS_LOG
)LogHandle
;
1221 PNDIS_MINIPORT_BLOCK Miniport
= Log
->Miniport
;
1224 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1226 KeAcquireSpinLock(&(Miniport
)->Lock
, &OldIrql
);
1227 Miniport
->Log
= NULL
;
1228 KeReleaseSpinLock(&(Miniport
)->Lock
, OldIrql
);
1239 IN NDIS_HANDLE MiniportAdapterHandle
,
1241 OUT PNDIS_HANDLE LogHandle
)
1243 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1247 NDIS_DbgPrint(MAX_TRACE
, ("called: MiniportAdapterHandle 0x%x, Size %ld\n", MiniportAdapterHandle
, Size
));
1249 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1251 if (Adapter
->NdisMiniportBlock
.Log
)
1254 return NDIS_STATUS_FAILURE
;
1257 Log
= ExAllocatePool(NonPagedPool
, Size
+ sizeof(NDIS_LOG
));
1261 return NDIS_STATUS_RESOURCES
;
1264 Adapter
->NdisMiniportBlock
.Log
= Log
;
1266 KeInitializeSpinLock(&Log
->LogLock
);
1268 Log
->Miniport
= &Adapter
->NdisMiniportBlock
;
1269 Log
->TotalSize
= Size
;
1270 Log
->CurrentSize
= 0;
1277 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1279 return NDIS_STATUS_SUCCESS
;
1287 NdisMDeregisterAdapterShutdownHandler(
1288 IN NDIS_HANDLE MiniportHandle
)
1290 * FUNCTION: de-registers a shutdown handler
1291 * ARGUMENTS: MiniportHandle: Handle passed into MiniportInitialize
1294 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1296 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1298 if(Adapter
->BugcheckContext
->ShutdownHandler
) {
1299 KeDeregisterBugCheckCallback(Adapter
->BugcheckContext
->CallbackRecord
);
1300 IoUnregisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1310 IN NDIS_HANDLE LogHandle
)
1312 PNDIS_LOG Log
= (PNDIS_LOG
) LogHandle
;
1315 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1318 KeAcquireSpinLock(&Log
->LogLock
, &OldIrql
);
1320 /* Set buffers size */
1321 Log
->CurrentSize
= 0;
1326 KeReleaseSpinLock(&Log
->LogLock
, OldIrql
);
1332 #undef NdisMIndicateStatus
1335 NdisMIndicateStatus(
1336 IN NDIS_HANDLE MiniportAdapterHandle
,
1337 IN NDIS_STATUS GeneralStatus
,
1338 IN PVOID StatusBuffer
,
1339 IN UINT StatusBufferSize
)
1341 MiniStatus(MiniportAdapterHandle
, GeneralStatus
, StatusBuffer
, StatusBufferSize
);
1347 #undef NdisMIndicateStatusComplete
1350 NdisMIndicateStatusComplete(
1351 IN NDIS_HANDLE MiniportAdapterHandle
)
1353 MiniStatusComplete(MiniportAdapterHandle
);
1362 NdisInitializeWrapper(
1363 OUT PNDIS_HANDLE NdisWrapperHandle
,
1364 IN PVOID SystemSpecific1
,
1365 IN PVOID SystemSpecific2
,
1366 IN PVOID SystemSpecific3
)
1368 * FUNCTION: Notifies the NDIS library that a new miniport is initializing
1370 * NdisWrapperHandle = Address of buffer to place NDIS wrapper handle
1371 * SystemSpecific1 = Pointer to the driver's driver object
1372 * SystemSpecific2 = Pointer to the driver's registry path
1373 * SystemSpecific3 = Always NULL
1375 * - SystemSpecific2 goes invalid so we copy it
1378 PNDIS_M_DRIVER_BLOCK Miniport
;
1379 PUNICODE_STRING RegistryPath
;
1380 WCHAR
*RegistryBuffer
;
1382 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1384 ASSERT(NdisWrapperHandle
);
1386 *NdisWrapperHandle
= NULL
;
1388 #if BREAK_ON_MINIPORT_INIT
1389 __asm__ ("int $3\n");
1392 Miniport
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DRIVER_BLOCK
));
1396 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1400 RtlZeroMemory(Miniport
, sizeof(NDIS_M_DRIVER_BLOCK
));
1402 KeInitializeSpinLock(&Miniport
->Lock
);
1404 Miniport
->DriverObject
= (PDRIVER_OBJECT
)SystemSpecific1
;
1406 /* set the miniport's driver registry path */
1407 RegistryPath
= ExAllocatePool(PagedPool
, sizeof(UNICODE_STRING
));
1410 ExFreePool(Miniport
);
1411 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1415 RegistryPath
->Length
= ((PUNICODE_STRING
)SystemSpecific2
)->Length
;
1416 RegistryPath
->MaximumLength
= RegistryPath
->Length
+ sizeof(WCHAR
); /* room for 0-term */
1418 RegistryBuffer
= ExAllocatePool(PagedPool
, RegistryPath
->MaximumLength
);
1421 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1422 ExFreePool(Miniport
);
1423 ExFreePool(RegistryPath
);
1427 RtlCopyMemory(RegistryBuffer
, ((PUNICODE_STRING
)SystemSpecific2
)->Buffer
, RegistryPath
->Length
);
1428 RegistryBuffer
[RegistryPath
->Length
/sizeof(WCHAR
)] = 0;
1430 RegistryPath
->Buffer
= RegistryBuffer
;
1431 Miniport
->RegistryPath
= RegistryPath
;
1433 InitializeListHead(&Miniport
->DeviceList
);
1435 /* Put miniport in global miniport list */
1436 ExInterlockedInsertTailList(&MiniportListHead
, &Miniport
->ListEntry
, &MiniportListLock
);
1438 *NdisWrapperHandle
= Miniport
;
1442 VOID NTAPI
NdisIBugcheckCallback(
1446 * FUNCTION: Internal callback for handling bugchecks - calls adapter's shutdown handler
1448 * Buffer: Pointer to a bugcheck callback context
1452 PMINIPORT_BUGCHECK_CONTEXT Context
= (PMINIPORT_BUGCHECK_CONTEXT
)Buffer
;
1453 ADAPTER_SHUTDOWN_HANDLER sh
= (ADAPTER_SHUTDOWN_HANDLER
)Context
->ShutdownHandler
;
1455 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1458 sh(Context
->DriverContext
);
1467 NdisMRegisterAdapterShutdownHandler(
1468 IN NDIS_HANDLE MiniportHandle
,
1469 IN PVOID ShutdownContext
,
1470 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
1472 * FUNCTION: Register a shutdown handler for an adapter
1474 * MiniportHandle: Handle originally passed into MiniportInitialize
1475 * ShutdownContext: Pre-initialized bugcheck context
1476 * ShutdownHandler: Function to call to handle the bugcheck
1478 * - I'm not sure about ShutdownContext
1481 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1482 PMINIPORT_BUGCHECK_CONTEXT BugcheckContext
;
1484 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1486 BugcheckContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_BUGCHECK_CONTEXT
));
1487 if(!BugcheckContext
)
1489 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1493 BugcheckContext
->ShutdownHandler
= ShutdownHandler
;
1494 BugcheckContext
->DriverContext
= ShutdownContext
;
1496 BugcheckContext
->CallbackRecord
= ExAllocatePool(NonPagedPool
, sizeof(KBUGCHECK_CALLBACK_RECORD
));
1497 if (!BugcheckContext
->CallbackRecord
) {
1498 ExFreePool(BugcheckContext
);
1502 Adapter
->BugcheckContext
= BugcheckContext
;
1504 KeInitializeCallbackRecord(BugcheckContext
->CallbackRecord
);
1506 KeRegisterBugCheckCallback(BugcheckContext
->CallbackRecord
, NdisIBugcheckCallback
,
1507 BugcheckContext
, sizeof(BugcheckContext
), (PUCHAR
)"Ndis Miniport");
1509 IoRegisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1515 PLOGICAL_ADAPTER Adapter
,
1516 NDIS_OID AddressOID
)
1518 * FUNCTION: Queries miniport for information
1520 * Adapter = Pointer to logical adapter
1521 * AddressOID = OID to use to query for current address
1523 * Status of operation
1527 NDIS_STATUS NdisStatus
;
1529 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1531 /* Get MAC options for adapter */
1532 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAC_OPTIONS
, sizeof(UINT
),
1533 &Adapter
->NdisMiniportBlock
.MacOptions
,
1536 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1538 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAC_OPTIONS failed. NdisStatus (0x%X).\n", NdisStatus
));
1542 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MacOptions (0x%X).\n", Adapter
->NdisMiniportBlock
.MacOptions
));
1544 /* Get current hardware address of adapter */
1545 NdisStatus
= MiniQueryInformation(Adapter
, AddressOID
, Adapter
->AddressLength
,
1546 &Adapter
->Address
, &BytesWritten
);
1548 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1550 NDIS_DbgPrint(MIN_TRACE
, ("Address OID (0x%X) failed. NdisStatus (0x%X).\n", AddressOID
, NdisStatus
));
1558 PUCHAR A
= (PUCHAR
)&Adapter
->Address
.Type
.Medium802_3
;
1560 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]));
1564 /* Get maximum lookahead buffer size of adapter */
1565 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_LOOKAHEAD
, sizeof(ULONG
),
1566 &Adapter
->NdisMiniportBlock
.MaximumLookahead
, &BytesWritten
);
1568 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1570 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1574 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MaxLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.MaximumLookahead
));
1576 /* Get current lookahead buffer size of adapter */
1577 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_CURRENT_LOOKAHEAD
, sizeof(ULONG
),
1578 &Adapter
->NdisMiniportBlock
.CurrentLookahead
, &BytesWritten
);
1580 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1582 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_CURRENT_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1586 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_SEND_PACKETS
, sizeof(ULONG
),
1587 &Adapter
->NdisMiniportBlock
.MaxSendPackets
, &BytesWritten
);
1589 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1591 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_SEND_PACKETS failed. NdisStatus (0x%X).\n", NdisStatus
));
1593 /* Set it to 1 if it fails because some drivers don't support this (?)*/
1594 Adapter
->NdisMiniportBlock
.MaxSendPackets
= 1;
1597 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.CurrentLookahead
));
1599 return STATUS_SUCCESS
;
1605 NdisIForwardIrpAndWaitCompletionRoutine(
1610 PKEVENT Event
= Context
;
1612 if (Irp
->PendingReturned
)
1613 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
1615 return STATUS_MORE_PROCESSING_REQUIRED
;
1621 NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter
, PIRP Irp
)
1626 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1627 IoCopyCurrentIrpStackLocationToNext(Irp
);
1628 IoSetCompletionRoutine(Irp
, NdisIForwardIrpAndWaitCompletionRoutine
, &Event
,
1630 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
1631 if (Status
== STATUS_PENDING
)
1633 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1634 Status
= Irp
->IoStatus
.Status
;
1642 NdisIPnPStartDevice(
1643 IN PDEVICE_OBJECT DeviceObject
,
1646 * FUNCTION: Handle the PnP start device event
1648 * DeviceObejct = Functional Device Object
1649 * Irp = IRP_MN_START_DEVICE I/O request packet
1651 * Status of operation
1654 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
1655 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1656 NDIS_WRAPPER_CONTEXT WrapperContext
;
1657 NDIS_STATUS NdisStatus
;
1658 NDIS_STATUS OpenErrorStatus
;
1660 UINT SelectedMediumIndex
= 0;
1661 NDIS_OID AddressOID
;
1662 BOOLEAN Success
= FALSE
;
1663 ULONG ResourceCount
;
1664 ULONG ResourceListSize
;
1665 UNICODE_STRING ParamName
;
1666 PNDIS_CONFIGURATION_PARAMETER ConfigParam
;
1667 NDIS_HANDLE ConfigHandle
;
1669 LARGE_INTEGER Timeout
;
1670 UINT MaxMulticastAddresses
;
1674 * Prepare wrapper context used by HW and configuration routines.
1677 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Start Device %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
1679 NDIS_DbgPrint(MAX_TRACE
, ("Inserting adapter 0x%x into adapter list\n", Adapter
));
1681 /* Put adapter in global adapter list */
1682 ExInterlockedInsertTailList(&AdapterListHead
, &Adapter
->ListEntry
, &AdapterListLock
);
1684 Status
= IoOpenDeviceRegistryKey(
1685 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
, PLUGPLAY_REGKEY_DRIVER
,
1686 KEY_ALL_ACCESS
, &WrapperContext
.RegistryHandle
);
1687 if (!NT_SUCCESS(Status
))
1689 NDIS_DbgPrint(MIN_TRACE
,("failed to open adapter-specific reg key\n"));
1690 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1694 NDIS_DbgPrint(MAX_TRACE
, ("opened device reg key\n"));
1696 WrapperContext
.DeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
1699 * Store the adapter resources used by HW routines such as
1700 * NdisMQueryAdapterResources.
1703 if (Stack
->Parameters
.StartDevice
.AllocatedResources
!= NULL
)
1705 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResources
->List
[0].
1706 PartialResourceList
.Count
;
1708 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1709 PartialDescriptors
[ResourceCount
]);
1711 Adapter
->NdisMiniportBlock
.AllocatedResources
=
1712 ExAllocatePool(PagedPool
, ResourceListSize
);
1713 if (Adapter
->NdisMiniportBlock
.AllocatedResources
== NULL
)
1715 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1716 return STATUS_INSUFFICIENT_RESOURCES
;
1719 Adapter
->NdisMiniportBlock
.Resources
=
1720 ExAllocatePool(PagedPool
, ResourceListSize
);
1721 if (!Adapter
->NdisMiniportBlock
.Resources
)
1723 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1724 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1725 return STATUS_INSUFFICIENT_RESOURCES
;
1728 RtlCopyMemory(Adapter
->NdisMiniportBlock
.Resources
,
1729 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1732 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResources
,
1733 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1737 if (Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
!= NULL
)
1739 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
->List
[0].
1740 PartialResourceList
.Count
;
1742 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1743 PartialDescriptors
[ResourceCount
]);
1745 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
=
1746 ExAllocatePool(PagedPool
, ResourceListSize
);
1747 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
== NULL
)
1749 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1750 return STATUS_INSUFFICIENT_RESOURCES
;
1753 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
,
1754 Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
,
1759 * Store the Bus Type, Bus Number and Slot information. It's used by
1760 * the hardware routines then.
1763 NdisOpenConfiguration(&NdisStatus
, &ConfigHandle
, (NDIS_HANDLE
)&WrapperContext
);
1765 Size
= sizeof(ULONG
);
1766 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1767 DevicePropertyLegacyBusType
, Size
,
1768 &Adapter
->NdisMiniportBlock
.BusType
, &Size
);
1769 if (!NT_SUCCESS(Status
) || (INTERFACE_TYPE
)Adapter
->NdisMiniportBlock
.BusType
== InterfaceTypeUndefined
)
1771 NdisInitUnicodeString(&ParamName
, L
"BusType");
1772 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1773 &ParamName
, NdisParameterInteger
);
1774 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1775 Adapter
->NdisMiniportBlock
.BusType
= ConfigParam
->ParameterData
.IntegerData
;
1777 Adapter
->NdisMiniportBlock
.BusType
= Isa
;
1780 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1781 DevicePropertyBusNumber
, Size
,
1782 &Adapter
->NdisMiniportBlock
.BusNumber
, &Size
);
1783 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.BusNumber
== 0xFFFFFFF0)
1785 NdisInitUnicodeString(&ParamName
, L
"BusNumber");
1786 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1787 &ParamName
, NdisParameterInteger
);
1788 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1789 Adapter
->NdisMiniportBlock
.BusNumber
= ConfigParam
->ParameterData
.IntegerData
;
1791 Adapter
->NdisMiniportBlock
.BusNumber
= 0;
1793 WrapperContext
.BusNumber
= Adapter
->NdisMiniportBlock
.BusNumber
;
1795 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1796 DevicePropertyAddress
, Size
,
1797 &Adapter
->NdisMiniportBlock
.SlotNumber
, &Size
);
1798 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.SlotNumber
== (NDIS_INTERFACE_TYPE
)-1)
1800 NdisInitUnicodeString(&ParamName
, L
"SlotNumber");
1801 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1802 &ParamName
, NdisParameterInteger
);
1803 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1804 Adapter
->NdisMiniportBlock
.SlotNumber
= ConfigParam
->ParameterData
.IntegerData
;
1806 Adapter
->NdisMiniportBlock
.SlotNumber
= 0;
1810 /* Convert slotnumber to PCI_SLOT_NUMBER */
1811 ULONG PciSlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1812 PCI_SLOT_NUMBER SlotNumber
;
1814 SlotNumber
.u
.AsULONG
= 0;
1815 SlotNumber
.u
.bits
.DeviceNumber
= (PciSlotNumber
>> 16) & 0xFFFF;
1816 SlotNumber
.u
.bits
.FunctionNumber
= PciSlotNumber
& 0xFFFF;
1818 Adapter
->NdisMiniportBlock
.SlotNumber
= SlotNumber
.u
.AsULONG
;
1820 WrapperContext
.SlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1822 NdisCloseConfiguration(ConfigHandle
);
1824 /* Set handlers (some NDIS macros require these) */
1825 Adapter
->NdisMiniportBlock
.EthRxCompleteHandler
= EthFilterDprIndicateReceiveComplete
;
1826 Adapter
->NdisMiniportBlock
.EthRxIndicateHandler
= EthFilterDprIndicateReceive
;
1827 Adapter
->NdisMiniportBlock
.SendCompleteHandler
= MiniSendComplete
;
1828 Adapter
->NdisMiniportBlock
.SendResourcesHandler
= MiniSendResourcesAvailable
;
1829 Adapter
->NdisMiniportBlock
.ResetCompleteHandler
= MiniResetComplete
;
1830 Adapter
->NdisMiniportBlock
.TDCompleteHandler
= MiniTransferDataComplete
;
1831 Adapter
->NdisMiniportBlock
.PacketIndicateHandler
= MiniIndicateReceivePacket
;
1832 Adapter
->NdisMiniportBlock
.StatusHandler
= MiniStatus
;
1833 Adapter
->NdisMiniportBlock
.StatusCompleteHandler
= MiniStatusComplete
;
1834 Adapter
->NdisMiniportBlock
.SendPacketsHandler
= ProSendPackets
;
1835 Adapter
->NdisMiniportBlock
.QueryCompleteHandler
= MiniRequestComplete
;
1836 Adapter
->NdisMiniportBlock
.SetCompleteHandler
= MiniRequestComplete
;
1839 * Call MiniportInitialize.
1842 NDIS_DbgPrint(MID_TRACE
, ("calling MiniportInitialize\n"));
1843 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.InitializeHandler
)(
1844 &OpenErrorStatus
, &SelectedMediumIndex
, &MediaArray
[0],
1845 MEDIA_ARRAY_SIZE
, Adapter
, (NDIS_HANDLE
)&WrapperContext
);
1847 ZwClose(WrapperContext
.RegistryHandle
);
1849 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1851 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() failed for an adapter.\n"));
1852 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1856 if (SelectedMediumIndex
>= MEDIA_ARRAY_SIZE
)
1858 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() failed for an adapter\n"));
1859 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1860 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
1863 Adapter
->NdisMiniportBlock
.MediaType
= MediaArray
[SelectedMediumIndex
];
1865 switch (Adapter
->NdisMiniportBlock
.MediaType
)
1867 case NdisMedium802_3
:
1868 Adapter
->MediumHeaderSize
= 14; /* XXX figure out what to do about LLC */
1869 AddressOID
= OID_802_3_CURRENT_ADDRESS
;
1870 Adapter
->AddressLength
= ETH_LENGTH_OF_ADDRESS
;
1871 NdisStatus
= DoQueries(Adapter
, AddressOID
);
1872 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1874 NdisStatus
= MiniQueryInformation(Adapter
, OID_802_3_MAXIMUM_LIST_SIZE
, sizeof(UINT
),
1875 &MaxMulticastAddresses
, &BytesWritten
);
1877 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1879 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1880 NDIS_DbgPrint(MAX_TRACE
, ("MiniQueryInformation failed (%x)\n", NdisStatus
));
1884 Success
= EthCreateFilter(MaxMulticastAddresses
,
1885 Adapter
->Address
.Type
.Medium802_3
,
1886 &Adapter
->NdisMiniportBlock
.EthDB
);
1888 ((PETHI_FILTER
)Adapter
->NdisMiniportBlock
.EthDB
)->Miniport
= (PNDIS_MINIPORT_BLOCK
)Adapter
;
1890 NdisStatus
= NDIS_STATUS_RESOURCES
;
1895 /* FIXME: Support other types of media */
1896 NDIS_DbgPrint(MIN_TRACE
, ("error: unsupported media\n"));
1898 /* FIXME - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); */
1899 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1900 return STATUS_UNSUCCESSFUL
;
1903 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1905 NDIS_DbgPrint(MAX_TRACE
, ("couldn't create filter (%x)\n", NdisStatus
));
1909 /* Check for a hang every two seconds if it wasn't set in MiniportInitialize */
1910 if (Adapter
->NdisMiniportBlock
.CheckForHangSeconds
== 0)
1911 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= 2;
1913 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
1914 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStarted
;
1916 Timeout
.QuadPart
= Int32x32To64(Adapter
->NdisMiniportBlock
.CheckForHangSeconds
, -1000000);
1917 KeSetTimerEx(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
, Timeout
,
1918 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
* 1000,
1919 &Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
);
1921 /* Put adapter in adapter list for this miniport */
1922 ExInterlockedInsertTailList(&Adapter
->NdisMiniportBlock
.DriverHandle
->DeviceList
, &Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
1924 return STATUS_SUCCESS
;
1931 IN PDEVICE_OBJECT DeviceObject
,
1934 * FUNCTION: Handle the PnP stop device event
1936 * DeviceObejct = Functional Device Object
1937 * Irp = IRP_MN_STOP_DEVICE I/O request packet
1939 * Status of operation
1942 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1944 /* Remove adapter from adapter list for this miniport */
1945 ExInterlockedRemoveEntryList(&Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
1947 /* Remove adapter from global adapter list */
1948 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1950 KeCancelTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
1952 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.HaltHandler
)(Adapter
);
1954 if (Adapter
->NdisMiniportBlock
.AllocatedResources
)
1956 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1957 Adapter
->NdisMiniportBlock
.AllocatedResources
= NULL
;
1959 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
)
1961 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
);
1962 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
= NULL
;
1965 if (Adapter
->NdisMiniportBlock
.Resources
)
1967 ExFreePool(Adapter
->NdisMiniportBlock
.Resources
);
1968 Adapter
->NdisMiniportBlock
.Resources
= NULL
;
1971 if (Adapter
->NdisMiniportBlock
.EthDB
)
1973 EthDeleteFilter(Adapter
->NdisMiniportBlock
.EthDB
);
1974 Adapter
->NdisMiniportBlock
.EthDB
= NULL
;
1977 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
1978 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStopped
;
1980 return STATUS_SUCCESS
;
1986 IN PDEVICE_OBJECT DeviceObject
,
1989 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
1990 PMINIPORT_BUGCHECK_CONTEXT Context
= Adapter
->BugcheckContext
;
1991 ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
= Context
->ShutdownHandler
;
1993 ASSERT(ShutdownHandler
);
1995 ShutdownHandler(Context
->DriverContext
);
1997 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1998 Irp
->IoStatus
.Information
= 0;
2000 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2002 return STATUS_SUCCESS
;
2007 NdisIDeviceIoControl(
2008 IN PDEVICE_OBJECT DeviceObject
,
2011 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2012 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2013 NDIS_STATUS Status
= STATUS_NOT_SUPPORTED
;
2015 Irp
->IoStatus
.Information
= 0;
2019 switch (Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
2021 case IOCTL_NDIS_QUERY_GLOBAL_STATS
:
2022 Status
= MiniQueryInformation(Adapter
,
2023 (NDIS_OID
)Irp
->AssociatedIrp
.SystemBuffer
,
2024 Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
,
2025 MmGetSystemAddressForMdl(Irp
->MdlAddress
),
2026 &Irp
->IoStatus
.Information
);
2034 if (Status
!= NDIS_STATUS_PENDING
)
2036 Irp
->IoStatus
.Status
= Status
;
2037 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2040 IoMarkIrpPending(Irp
);
2049 IN PDEVICE_OBJECT DeviceObject
,
2052 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2053 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2056 switch (Stack
->MinorFunction
)
2058 case IRP_MN_START_DEVICE
:
2059 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2060 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2062 Status
= NdisIPnPStartDevice(DeviceObject
, Irp
);
2064 Irp
->IoStatus
.Status
= Status
;
2065 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2068 case IRP_MN_STOP_DEVICE
:
2069 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2070 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2072 Status
= NdisIPnPStopDevice(DeviceObject
, Irp
);
2074 Irp
->IoStatus
.Status
= Status
;
2075 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2078 case IRP_MN_QUERY_REMOVE_DEVICE
:
2079 case IRP_MN_QUERY_STOP_DEVICE
:
2080 Status
= NdisIPnPQueryStopDevice(DeviceObject
, Irp
);
2081 Irp
->IoStatus
.Status
= Status
;
2082 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2085 case IRP_MN_CANCEL_REMOVE_DEVICE
:
2086 case IRP_MN_CANCEL_STOP_DEVICE
:
2087 Status
= NdisIPnPCancelStopDevice(DeviceObject
, Irp
);
2088 Irp
->IoStatus
.Status
= Status
;
2089 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2093 IoSkipCurrentIrpStackLocation(Irp
);
2094 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
2105 IN PDRIVER_OBJECT DriverObject
,
2106 IN PDEVICE_OBJECT PhysicalDeviceObject
)
2108 * FUNCTION: Create a device for an adapter found using PnP
2110 * DriverObject = Pointer to the miniport driver object
2111 * PhysicalDeviceObject = Pointer to the PDO for our adapter
2114 static const WCHAR ClassKeyName
[] = {'C','l','a','s','s','\\'};
2115 static const WCHAR LinkageKeyName
[] = {'\\','L','i','n','k','a','g','e',0};
2116 PNDIS_M_DRIVER_BLOCK Miniport
;
2117 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2118 WCHAR
*LinkageKeyBuffer
;
2119 ULONG DriverKeyLength
;
2120 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
2121 UNICODE_STRING ExportName
;
2122 PDEVICE_OBJECT DeviceObject
;
2123 PLOGICAL_ADAPTER Adapter
;
2127 * Gain the access to the miniport data structure first.
2130 MiniportPtr
= IoGetDriverObjectExtension(DriverObject
, (PVOID
)TAG('D','I','M','N'));
2131 if (MiniportPtr
== NULL
)
2133 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get driver object extension.\n"));
2134 return STATUS_UNSUCCESSFUL
;
2136 Miniport
= *MiniportPtr
;
2139 * Get name of the Linkage registry key for our adapter. It's located under
2140 * the driver key for our driver and so we have basicly two ways to do it.
2141 * Either we can use IoOpenDriverRegistryKey or compose it using information
2142 * gathered by IoGetDeviceProperty. I choosed the second because
2143 * IoOpenDriverRegistryKey wasn't implemented at the time of writing.
2146 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2147 0, NULL
, &DriverKeyLength
);
2148 if (Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
&& Status
!= STATUS_SUCCESS
)
2150 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get miniport driver key length.\n"));
2154 LinkageKeyBuffer
= ExAllocatePool(PagedPool
, DriverKeyLength
+
2155 sizeof(ClassKeyName
) + sizeof(LinkageKeyName
));
2156 if (LinkageKeyBuffer
== NULL
)
2158 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't allocate memory for driver key name.\n"));
2159 return STATUS_INSUFFICIENT_RESOURCES
;
2162 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2163 DriverKeyLength
, LinkageKeyBuffer
+
2164 (sizeof(ClassKeyName
) / sizeof(WCHAR
)),
2166 if (!NT_SUCCESS(Status
))
2168 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get miniport driver key.\n"));
2169 ExFreePool(LinkageKeyBuffer
);
2173 /* Compose the linkage key name. */
2174 RtlCopyMemory(LinkageKeyBuffer
, ClassKeyName
, sizeof(ClassKeyName
));
2175 RtlCopyMemory(LinkageKeyBuffer
+ ((sizeof(ClassKeyName
) + DriverKeyLength
) /
2176 sizeof(WCHAR
)) - 1, LinkageKeyName
, sizeof(LinkageKeyName
));
2178 NDIS_DbgPrint(DEBUG_MINIPORT
, ("LinkageKey: %S.\n", LinkageKeyBuffer
));
2181 * Now open the linkage key and read the "Export" and "RootDevice" values
2182 * which contains device name and root service respectively.
2185 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
2186 RtlInitUnicodeString(&ExportName
, NULL
);
2187 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
| RTL_QUERY_REGISTRY_DIRECT
;
2188 QueryTable
[0].Name
= L
"Export";
2189 QueryTable
[0].EntryContext
= &ExportName
;
2191 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
, LinkageKeyBuffer
,
2192 QueryTable
, NULL
, NULL
);
2193 ExFreePool(LinkageKeyBuffer
);
2194 if (!NT_SUCCESS(Status
))
2196 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get miniport device name. (%x)\n", Status
));
2201 * Create the device object.
2204 NDIS_DbgPrint(MAX_TRACE
, ("creating device %wZ\n", &ExportName
));
2206 Status
= IoCreateDevice(Miniport
->DriverObject
, sizeof(LOGICAL_ADAPTER
),
2207 &ExportName
, FILE_DEVICE_PHYSICAL_NETCARD
,
2208 0, FALSE
, &DeviceObject
);
2209 if (!NT_SUCCESS(Status
))
2211 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device object.\n"));
2212 RtlFreeUnicodeString(&ExportName
);
2217 * Initialize the adapter structure.
2220 Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2221 KeInitializeSpinLock(&Adapter
->NdisMiniportBlock
.Lock
);
2222 InitializeListHead(&Adapter
->ProtocolListHead
);
2223 Adapter
->NdisMiniportBlock
.DriverHandle
= Miniport
;
2225 Adapter
->NdisMiniportBlock
.MiniportName
= ExportName
;
2227 Adapter
->NdisMiniportBlock
.DeviceObject
= DeviceObject
;
2228 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
= PhysicalDeviceObject
;
2229 Adapter
->NdisMiniportBlock
.NextDeviceObject
=
2230 IoAttachDeviceToDeviceStack(Adapter
->NdisMiniportBlock
.DeviceObject
,
2231 PhysicalDeviceObject
);
2233 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= 0;
2234 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceAdded
;
2236 KeInitializeTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2237 KeInitializeDpc(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
, MiniportHangDpc
, Adapter
);
2239 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
2241 return STATUS_SUCCESS
;
2250 NdisMRegisterMiniport(
2251 IN NDIS_HANDLE NdisWrapperHandle
,
2252 IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics
,
2253 IN UINT CharacteristicsLength
)
2255 * FUNCTION: Registers a miniport's MiniportXxx entry points with the NDIS library
2257 * NdisWrapperHandle = Pointer to handle returned by NdisMInitializeWrapper
2258 * MiniportCharacteristics = Pointer to a buffer with miniport characteristics
2259 * CharacteristicsLength = Number of bytes in characteristics buffer
2261 * Status of operation
2265 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2266 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2269 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2271 switch (MiniportCharacteristics
->MajorNdisVersion
)
2274 MinSize
= sizeof(NDIS30_MINIPORT_CHARACTERISTICS
);
2278 MinSize
= sizeof(NDIS40_MINIPORT_CHARACTERISTICS
);
2282 MinSize
= sizeof(NDIS50_MINIPORT_CHARACTERISTICS
);
2286 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics version.\n"));
2287 return NDIS_STATUS_BAD_VERSION
;
2290 NDIS_DbgPrint(MIN_TRACE
, ("Initializing an NDIS %u.%u miniport\n",
2291 MiniportCharacteristics
->MajorNdisVersion
,
2292 MiniportCharacteristics
->MinorNdisVersion
));
2294 if (CharacteristicsLength
< MinSize
)
2296 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics length.\n"));
2297 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2300 /* Check if mandatory MiniportXxx functions are specified */
2301 if ((!MiniportCharacteristics
->HaltHandler
) ||
2302 (!MiniportCharacteristics
->InitializeHandler
)||
2303 (!MiniportCharacteristics
->QueryInformationHandler
) ||
2304 (!MiniportCharacteristics
->ResetHandler
) ||
2305 (!MiniportCharacteristics
->SetInformationHandler
))
2307 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics.\n"));
2308 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2311 if (MiniportCharacteristics
->MajorNdisVersion
== 0x03)
2313 if (!MiniportCharacteristics
->SendHandler
)
2315 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 3.0)\n"));
2316 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2319 else if (MiniportCharacteristics
->MajorNdisVersion
>= 0x04)
2322 if ((!MiniportCharacteristics
->SendHandler
) &&
2323 (!MiniportCharacteristics
->SendPacketsHandler
))
2325 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 4.0)\n"));
2326 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2330 /* TODO: verify NDIS5 and NDIS5.1 */
2332 RtlCopyMemory(&Miniport
->MiniportCharacteristics
, MiniportCharacteristics
, MinSize
);
2335 * NOTE: This is VERY unoptimal! Should we store the NDIS_M_DRIVER_BLOCK
2336 * structure in the driver extension or what?
2339 Status
= IoAllocateDriverObjectExtension(Miniport
->DriverObject
, (PVOID
)TAG('D','I','M','N'),
2340 sizeof(PNDIS_M_DRIVER_BLOCK
), (PVOID
*)&MiniportPtr
);
2341 if (!NT_SUCCESS(Status
))
2343 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't allocate driver object extension.\n"));
2344 return NDIS_STATUS_RESOURCES
;
2347 *MiniportPtr
= Miniport
;
2349 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
2350 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = NdisIShutdown
;
2351 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = NdisIDeviceIoControl
;
2352 Miniport
->DriverObject
->DriverExtension
->AddDevice
= NdisIAddDevice
;
2354 return NDIS_STATUS_SUCCESS
;
2361 #undef NdisMResetComplete
2365 IN NDIS_HANDLE MiniportAdapterHandle
,
2366 IN NDIS_STATUS Status
,
2367 IN BOOLEAN AddressingReset
)
2369 MiniResetComplete(MiniportAdapterHandle
, Status
, AddressingReset
);
2376 #undef NdisMSendComplete
2380 IN NDIS_HANDLE MiniportAdapterHandle
,
2381 IN PNDIS_PACKET Packet
,
2382 IN NDIS_STATUS Status
)
2384 * FUNCTION: Forwards a message to the initiating protocol saying
2385 * that a packet was handled
2387 * NdisAdapterHandle = Handle input to MiniportInitialize
2388 * Packet = Pointer to NDIS packet that was sent
2389 * Status = Status of send operation
2392 MiniSendComplete(MiniportAdapterHandle
, Packet
, Status
);
2399 #undef NdisMSendResourcesAvailable
2402 NdisMSendResourcesAvailable(
2403 IN NDIS_HANDLE MiniportAdapterHandle
)
2405 MiniSendResourcesAvailable(MiniportAdapterHandle
);
2412 #undef NdisMTransferDataComplete
2415 NdisMTransferDataComplete(
2416 IN NDIS_HANDLE MiniportAdapterHandle
,
2417 IN PNDIS_PACKET Packet
,
2418 IN NDIS_STATUS Status
,
2419 IN UINT BytesTransferred
)
2421 MiniTransferDataComplete(MiniportAdapterHandle
, Packet
, Status
, BytesTransferred
);
2428 #undef NdisMSetAttributes
2432 IN NDIS_HANDLE MiniportAdapterHandle
,
2433 IN NDIS_HANDLE MiniportAdapterContext
,
2434 IN BOOLEAN BusMaster
,
2435 IN NDIS_INTERFACE_TYPE AdapterType
)
2437 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2439 * MiniportAdapterHandle = Handle input to MiniportInitialize
2440 * MiniportAdapterContext = Pointer to context information
2441 * BusMaster = Specifies TRUE if the caller's NIC is a busmaster DMA device
2442 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2445 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2446 NdisMSetAttributesEx(MiniportAdapterHandle
, MiniportAdapterContext
, 0,
2447 BusMaster
? NDIS_ATTRIBUTE_BUS_MASTER
: 0,
2457 NdisMSetAttributesEx(
2458 IN NDIS_HANDLE MiniportAdapterHandle
,
2459 IN NDIS_HANDLE MiniportAdapterContext
,
2460 IN UINT CheckForHangTimeInSeconds OPTIONAL
,
2461 IN ULONG AttributeFlags
,
2462 IN NDIS_INTERFACE_TYPE AdapterType
)
2464 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2466 * MiniportAdapterHandle = Handle input to MiniportInitialize
2467 * MiniportAdapterContext = Pointer to context information
2468 * CheckForHangTimeInSeconds = Specifies interval in seconds at which
2469 * MiniportCheckForHang should be called
2470 * AttributeFlags = Bitmask that indicates specific attributes
2471 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2474 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(MiniportAdapterHandle
);
2476 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2478 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
= MiniportAdapterContext
;
2479 Adapter
->NdisMiniportBlock
.Flags
= AttributeFlags
;
2480 Adapter
->NdisMiniportBlock
.AdapterType
= AdapterType
;
2481 if (CheckForHangTimeInSeconds
> 0)
2482 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= CheckForHangTimeInSeconds
;
2483 if (AttributeFlags
& NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER
)
2484 NDIS_DbgPrint(MAX_TRACE
, ("Intermediate drivers not supported yet.\n"));
2494 IN ULONG MicrosecondsToSleep
)
2496 * FUNCTION: delay the thread's execution for MicrosecondsToSleep
2498 * MicrosecondsToSleep: duh...
2500 * - Because this is a blocking call, current IRQL must be < DISPATCH_LEVEL
2504 LARGE_INTEGER DueTime
;
2508 DueTime
.QuadPart
= (-1) * 10 * MicrosecondsToSleep
;
2510 KeInitializeTimer(&Timer
);
2511 KeSetTimer(&Timer
, DueTime
, 0);
2512 KeWaitForSingleObject(&Timer
, Executive
, KernelMode
, FALSE
, 0);
2521 NdisMSynchronizeWithInterrupt(
2522 IN PNDIS_MINIPORT_INTERRUPT Interrupt
,
2523 IN PVOID SynchronizeFunction
,
2524 IN PVOID SynchronizeContext
)
2526 return(KeSynchronizeExecution(Interrupt
->InterruptObject
,
2527 (PKSYNCHRONIZE_ROUTINE
)SynchronizeFunction
,
2528 SynchronizeContext
));
2538 IN NDIS_HANDLE LogHandle
,
2540 IN UINT LogBufferSize
)
2542 PUCHAR Buffer
= LogBuffer
;
2546 for (i
= 0; i
< LogBufferSize
; i
+= 16)
2548 DbgPrint("%08x |", i
);
2549 for (j
= 0; j
< 16; j
++)
2552 if (idx
< LogBufferSize
)
2553 DbgPrint(" %02x", Buffer
[idx
]);
2558 for (j
= 0; j
< 16; j
++)
2561 if (idx
== LogBufferSize
)
2563 if (Buffer
[idx
] >= ' ') /* FIXME: not portable! replace by if (isprint(Buffer[idx])) ? */
2564 DbgPrint("%c", Buffer
[idx
]);
2571 return NDIS_STATUS_FAILURE
;
2580 NdisTerminateWrapper(
2581 IN NDIS_HANDLE NdisWrapperHandle
,
2582 IN PVOID SystemSpecific
)
2584 * FUNCTION: Releases resources allocated by a call to NdisInitializeWrapper
2586 * NdisWrapperHandle = Handle returned by NdisInitializeWrapper (NDIS_M_DRIVER_BLOCK)
2587 * SystemSpecific = Always NULL
2590 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2592 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2594 ExFreePool(Miniport
->RegistryPath
->Buffer
);
2595 ExFreePool(Miniport
->RegistryPath
);
2596 ExInterlockedRemoveEntryList(&Miniport
->ListEntry
, &MiniportListLock
);
2597 ExFreePool(Miniport
);
2606 NdisMQueryAdapterInstanceName(
2607 OUT PNDIS_STRING AdapterInstanceName
,
2608 IN NDIS_HANDLE MiniportAdapterHandle
)
2616 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
2617 UNICODE_STRING AdapterName
;
2619 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2621 AdapterName
.Length
= 0;
2622 AdapterName
.MaximumLength
= Adapter
->NdisMiniportBlock
.MiniportName
.MaximumLength
;
2623 AdapterName
.Buffer
= ExAllocatePool(PagedPool
, AdapterName
.MaximumLength
);
2624 if (!AdapterName
.Buffer
)
2625 return NDIS_STATUS_RESOURCES
;
2627 RtlCopyUnicodeString(&AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
);
2629 *AdapterInstanceName
= AdapterName
;
2631 return NDIS_STATUS_SUCCESS
;
2639 NdisDeregisterAdapterShutdownHandler(
2640 IN NDIS_HANDLE NdisAdapterHandle
)
2648 NdisMDeregisterAdapterShutdownHandler(NdisAdapterHandle
);
2657 NdisRegisterAdapterShutdownHandler(
2658 IN NDIS_HANDLE NdisAdapterHandle
,
2659 IN PVOID ShutdownContext
,
2660 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
2668 NdisMRegisterAdapterShutdownHandler(NdisAdapterHandle
,
2678 NdisMGetDeviceProperty(
2679 IN NDIS_HANDLE MiniportAdapterHandle
,
2680 IN OUT PDEVICE_OBJECT
*PhysicalDeviceObject OPTIONAL
,
2681 IN OUT PDEVICE_OBJECT
*FunctionalDeviceObject OPTIONAL
,
2682 IN OUT PDEVICE_OBJECT
*NextDeviceObject OPTIONAL
,
2683 IN OUT PCM_RESOURCE_LIST
*AllocatedResources OPTIONAL
,
2684 IN OUT PCM_RESOURCE_LIST
*AllocatedResourcesTranslated OPTIONAL
)
2692 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
2694 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2696 if (PhysicalDeviceObject
!= NULL
)
2697 *PhysicalDeviceObject
= Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
;
2699 if (FunctionalDeviceObject
!= NULL
)
2700 *FunctionalDeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
2702 if (NextDeviceObject
!= NULL
)
2703 *NextDeviceObject
= Adapter
->NdisMiniportBlock
.NextDeviceObject
;
2705 if (AllocatedResources
!= NULL
)
2706 *AllocatedResources
= Adapter
->NdisMiniportBlock
.AllocatedResources
;
2708 if (AllocatedResourcesTranslated
!= NULL
)
2709 *AllocatedResourcesTranslated
= Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
;
2717 NdisMRegisterUnloadHandler(
2718 IN NDIS_HANDLE NdisWrapperHandle
,
2719 IN PDRIVER_UNLOAD UnloadHandler
)
2727 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2729 NDIS_DbgPrint(MAX_TRACE
, ("Miniport registered unload handler\n"));
2731 DriverBlock
->DriverObject
->DriverUnload
= UnloadHandler
;
2739 NdisMRegisterDevice(
2740 IN NDIS_HANDLE NdisWrapperHandle
,
2741 IN PNDIS_STRING DeviceName
,
2742 IN PNDIS_STRING SymbolicName
,
2743 IN PDRIVER_DISPATCH MajorFunctions
[],
2744 OUT PDEVICE_OBJECT
*pDeviceObject
,
2745 OUT NDIS_HANDLE
*NdisDeviceHandle
)
2753 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2754 PNDIS_M_DEVICE_BLOCK DeviceBlock
;
2755 PDEVICE_OBJECT DeviceObject
;
2759 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2761 Status
= IoCreateDevice(DriverBlock
->DriverObject
,
2762 0, /* This space is reserved for us. Should we use it? */
2764 FILE_DEVICE_NETWORK
,
2769 if (!NT_SUCCESS(Status
))
2774 Status
= IoCreateSymbolicLink(SymbolicName
, DeviceName
);
2776 if (!NT_SUCCESS(Status
))
2778 IoDeleteDevice(DeviceObject
);
2782 DeviceBlock
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DEVICE_BLOCK
));
2786 IoDeleteDevice(DeviceObject
);
2787 IoDeleteSymbolicLink(SymbolicName
);
2788 return NDIS_STATUS_RESOURCES
;
2791 for (i
= 0; i
< IRP_MJ_MAXIMUM_FUNCTION
; i
++)
2792 DriverBlock
->DriverObject
->MajorFunction
[i
] = MajorFunctions
[i
];
2794 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
2795 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = NdisIShutdown
;
2796 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = NdisIDeviceIoControl
;
2798 DeviceBlock
->DeviceObject
= DeviceObject
;
2799 DeviceBlock
->SymbolicName
= SymbolicName
;
2801 *pDeviceObject
= DeviceObject
;
2802 *NdisDeviceHandle
= DeviceBlock
;
2804 return NDIS_STATUS_SUCCESS
;
2812 NdisMDeregisterDevice(
2813 IN NDIS_HANDLE NdisDeviceHandle
)
2821 PNDIS_M_DEVICE_BLOCK DeviceBlock
= NdisDeviceHandle
;
2823 IoDeleteDevice(DeviceBlock
->DeviceObject
);
2825 IoDeleteSymbolicLink(DeviceBlock
->SymbolicName
);
2827 ExFreePool(DeviceBlock
);
2829 return NDIS_STATUS_SUCCESS
;
2837 NdisQueryAdapterInstanceName(
2838 OUT PNDIS_STRING AdapterInstanceName
,
2839 IN NDIS_HANDLE NdisBindingHandle
)
2847 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
2848 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
2850 return NdisMQueryAdapterInstanceName(AdapterInstanceName
,
2859 NdisCompletePnPEvent(
2860 IN NDIS_STATUS Status
,
2861 IN NDIS_HANDLE NdisBindingHandle
,
2862 IN PNET_PNP_EVENT NetPnPEvent
)
2870 PIRP Irp
= (PIRP
)NetPnPEvent
->NdisReserved
[0];
2871 PLIST_ENTRY CurrentEntry
= (PLIST_ENTRY
)NetPnPEvent
->NdisReserved
[1];
2872 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
2873 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
2874 NDIS_STATUS NdisStatus
;
2876 if (Status
!= NDIS_STATUS_SUCCESS
)
2878 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
2879 ExFreePool(NetPnPEvent
);
2880 Irp
->IoStatus
.Status
= Status
;
2881 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2885 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
2887 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
2889 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.PnPEventHandler
)(
2890 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
2893 if (NdisStatus
== NDIS_STATUS_PENDING
)
2895 NetPnPEvent
->NdisReserved
[1] = (ULONG_PTR
)CurrentEntry
->Flink
;
2898 else if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2900 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
2901 ExFreePool(NetPnPEvent
);
2902 Irp
->IoStatus
.Status
= NdisStatus
;
2903 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2907 CurrentEntry
= CurrentEntry
->Flink
;
2910 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
2911 ExFreePool(NetPnPEvent
);
2913 Irp
->IoStatus
.Status
= NDIS_STATUS_SUCCESS
;
2914 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);