2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS library
4 * FILE: ndis/miniport.c
5 * PURPOSE: Routines used by NDIS miniport drivers
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Vizzini (vizzini@plasmic.com)
9 * CSH 01/08-2000 Created
10 * 20 Aug 2003 vizzini - DMA support
11 * 3 Oct 2003 vizzini - SendPackets support
19 #undef NdisMSendComplete
23 IN NDIS_HANDLE MiniportAdapterHandle
,
24 IN PNDIS_PACKET Packet
,
25 IN NDIS_STATUS Status
);
27 /* Root of the scm database */
28 #define SERVICES_ROOT L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
31 * Define to 1 to get a debugger breakpoint at the end of NdisInitializeWrapper
32 * for each new miniport starting up
34 #define BREAK_ON_MINIPORT_INIT 0
37 * This has to be big enough to hold the results of querying the Route value
38 * from the Linkage key. Please re-code me to determine this dynamically.
40 #define ROUTE_DATA_SIZE 256
42 /* Number of media we know */
43 #define MEDIA_ARRAY_SIZE 15
45 static NDIS_MEDIUM MediaArray
[MEDIA_ARRAY_SIZE
] =
54 NdisMediumArcnet878_2
,
56 NdisMediumWirelessWan
,
64 /* global list and lock of Miniports NDIS has registered */
65 LIST_ENTRY MiniportListHead
;
66 KSPIN_LOCK MiniportListLock
;
68 /* global list and lock of adapters NDIS has registered */
69 LIST_ENTRY AdapterListHead
;
70 KSPIN_LOCK AdapterListLock
;
79 if ((DebugTraceLevel
& DEBUG_PACKET
) > 0) {
80 Length
= CopyPacketToBuffer(
86 DbgPrint("*** PACKET START ***");
88 for (i
= 0; i
< Length
; i
++) {
90 DbgPrint("\n%04X ", i
);
91 DbgPrint("%02X ", Buffer
[i
]);
94 DbgPrint("*** PACKET STOP ***\n");
102 UINT HeaderBufferSize
,
103 PVOID LookaheadBuffer
,
104 UINT LookaheadBufferSize
)
107 if ((DebugTraceLevel
& DEBUG_PACKET
) > 0) {
111 DbgPrint("*** RECEIVE PACKET START ***\n");
114 for (i
= 0; i
< HeaderBufferSize
; i
++) {
116 DbgPrint("\n%04X ", i
);
117 DbgPrint("%02X ", *p
++);
120 DbgPrint("\nFRAME:");
123 Length
= (LookaheadBufferSize
< 64)? LookaheadBufferSize
: 64;
124 for (i
= 0; i
< Length
; i
++) {
126 DbgPrint("\n%04X ", i
);
127 DbgPrint("%02X ", *p
++);
130 DbgPrint("\n*** RECEIVE PACKET STOP ***\n");
135 PNDIS_MINIPORT_WORK_ITEM
136 MiniGetFirstWorkItem(
137 PLOGICAL_ADAPTER Adapter
,
138 NDIS_WORK_ITEM_TYPE Type
)
140 PNDIS_MINIPORT_WORK_ITEM CurrentEntry
= Adapter
->WorkQueueHead
;
144 if (CurrentEntry
->WorkItemType
== Type
)
147 CurrentEntry
= (PNDIS_MINIPORT_WORK_ITEM
)CurrentEntry
->Link
.Next
;
155 PLOGICAL_ADAPTER Adapter
,
156 NDIS_WORK_ITEM_TYPE Type
)
158 BOOLEAN Busy
= FALSE
;
161 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
163 if (Type
== NdisWorkItemRequest
&&
164 (Adapter
->NdisMiniportBlock
.PendingRequest
|| MiniGetFirstWorkItem(Adapter
, NdisWorkItemRequest
)))
168 else if (Type
== NdisWorkItemSend
&&
169 (Adapter
->NdisMiniportBlock
.FirstPendingPacket
|| MiniGetFirstWorkItem(Adapter
, NdisWorkItemSend
)))
173 else if (Type
== NdisWorkItemResetRequested
&&
174 (Adapter
->NdisMiniportBlock
.ResetStatus
== NDIS_STATUS_PENDING
|| MiniGetFirstWorkItem(Adapter
, NdisWorkItemResetRequested
)))
179 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
187 PLOGICAL_ADAPTER Adapter
,
188 NDIS_HANDLE MacReceiveContext
,
190 UINT HeaderBufferSize
,
191 PVOID LookaheadBuffer
,
192 UINT LookaheadBufferSize
,
195 * FUNCTION: Indicate received data to bound protocols
197 * Adapter = Pointer to logical adapter
198 * MacReceiveContext = MAC receive context handle
199 * HeaderBuffer = Pointer to header buffer
200 * HeaderBufferSize = Size of header buffer
201 * LookaheadBuffer = Pointer to lookahead buffer
202 * LookaheadBufferSize = Size of lookahead buffer
203 * PacketSize = Total size of received packet
207 PLIST_ENTRY CurrentEntry
;
208 PADAPTER_BINDING AdapterBinding
;
210 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called. Adapter (0x%X) HeaderBuffer (0x%X) "
211 "HeaderBufferSize (0x%X) LookaheadBuffer (0x%X) LookaheadBufferSize (0x%X).\n",
212 Adapter
, HeaderBuffer
, HeaderBufferSize
, LookaheadBuffer
, LookaheadBufferSize
));
214 MiniDisplayPacket2(HeaderBuffer
, HeaderBufferSize
, LookaheadBuffer
, LookaheadBufferSize
);
216 NDIS_DbgPrint(MAX_TRACE
, ("acquiring miniport block lock\n"));
217 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
219 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
220 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurrentEntry = %x\n", CurrentEntry
));
222 if (CurrentEntry
== &Adapter
->ProtocolListHead
)
224 NDIS_DbgPrint(DEBUG_MINIPORT
, ("WARNING: No upper protocol layer.\n"));
227 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
229 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
230 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterBinding = %x\n", AdapterBinding
));
234 ("XXX (%x) %x %x %x %x %x %x %x XXX\n",
235 *AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
,
236 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
244 /* call the receive handler */
245 (*AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
)(
246 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
254 CurrentEntry
= CurrentEntry
->Flink
;
257 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
259 NDIS_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
264 MiniIndicateReceivePacket(
265 IN NDIS_HANDLE MiniportAdapterHandle
,
266 IN PPNDIS_PACKET PacketArray
,
267 IN UINT NumberOfPackets
)
269 * FUNCTION: receives miniport packet array indications
271 * MiniportAdapterHandle: Miniport handle for the adapter
272 * PacketArray: pointer to a list of packet pointers to indicate
273 * NumberOfPackets: number of packets to indicate
277 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
278 PLIST_ENTRY CurrentEntry
;
279 PADAPTER_BINDING AdapterBinding
;
283 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
285 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
287 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
289 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
291 if (AdapterBinding
->ProtocolBinding
->Chars
.ReceivePacketHandler
)
293 for (i
= 0; i
< NumberOfPackets
; i
++)
295 (*AdapterBinding
->ProtocolBinding
->Chars
.ReceivePacketHandler
)(
296 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
302 for (i
= 0; i
< NumberOfPackets
; i
++)
304 UINT FirstBufferLength
, TotalBufferLength
, LookAheadSize
, HeaderSize
;
305 PNDIS_BUFFER NdisBuffer
;
306 PVOID NdisBufferVA
, LookAheadBuffer
;
307 NDIS_STATUS NdisStatus
;
310 NdisGetFirstBufferFromPacket(PacketArray
[i
],
316 HeaderSize
= NDIS_GET_PACKET_HEADER_SIZE(PacketArray
[i
]);
318 if (Adapter
->NdisMiniportBlock
.CurrentLookahead
< (TotalBufferLength
- HeaderSize
))
320 LookAheadSize
= Adapter
->NdisMiniportBlock
.CurrentLookahead
;
324 LookAheadSize
= TotalBufferLength
- HeaderSize
;
328 LookAheadBuffer
= ExAllocatePool(NonPagedPool
, LookAheadSize
);
329 if (!LookAheadBuffer
)
331 NDIS_DbgPrint(MIN_TRACE
, ("Failed to allocate lookahead buffer!\n"));
335 CopyBufferChainToBuffer(LookAheadBuffer
,
340 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
)(
341 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
342 AdapterBinding
->NdisOpenBlock
.MacHandle
,
347 TotalBufferLength
- HeaderSize
);
349 NDIS_SET_PACKET_STATUS(PacketArray
[i
], NdisStatus
);
351 ExFreePool(LookAheadBuffer
);
355 CurrentEntry
= CurrentEntry
->Flink
;
358 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
364 IN NDIS_HANDLE MiniportAdapterHandle
,
365 IN NDIS_STATUS Status
,
366 IN BOOLEAN AddressingReset
)
368 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
369 PLIST_ENTRY CurrentEntry
;
370 PADAPTER_BINDING AdapterBinding
;
373 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
374 NdisMIndicateStatusComplete(Adapter
);
376 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
378 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
380 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
382 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
384 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
386 (*AdapterBinding
->ProtocolBinding
->Chars
.ResetCompleteHandler
)(
387 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
390 CurrentEntry
= CurrentEntry
->Flink
;
393 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
398 IN NDIS_HANDLE MiniportAdapterHandle
,
399 IN NDIS_STATUS Status
)
401 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
402 PNDIS_REQUEST Request
;
403 PNDIS_REQUEST_MAC_BLOCK MacBlock
;
406 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
408 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
410 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
411 Request
= Adapter
->NdisMiniportBlock
.PendingRequest
;
412 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
414 MacBlock
= (PNDIS_REQUEST_MAC_BLOCK
)Request
->MacReserved
;
416 if( MacBlock
->Binding
->RequestCompleteHandler
) {
417 (*MacBlock
->Binding
->RequestCompleteHandler
)(
418 MacBlock
->Binding
->ProtocolBindingContext
,
423 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
424 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
425 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
427 KeLowerIrql(OldIrql
);
432 IN NDIS_HANDLE MiniportAdapterHandle
,
433 IN PNDIS_PACKET Packet
,
434 IN NDIS_STATUS Status
)
436 * FUNCTION: Forwards a message to the initiating protocol saying
437 * that a packet was handled
439 * NdisAdapterHandle = Handle input to MiniportInitialize
440 * Packet = Pointer to NDIS packet that was sent
441 * Status = Status of send operation
444 PADAPTER_BINDING AdapterBinding
;
447 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
449 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
451 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
452 (*AdapterBinding
->ProtocolBinding
->Chars
.SendCompleteHandler
)(
453 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
456 KeLowerIrql(OldIrql
);
461 MiniSendResourcesAvailable(
462 IN NDIS_HANDLE MiniportAdapterHandle
)
471 MiniTransferDataComplete(
472 IN NDIS_HANDLE MiniportAdapterHandle
,
473 IN PNDIS_PACKET Packet
,
474 IN NDIS_STATUS Status
,
475 IN UINT BytesTransferred
)
477 PADAPTER_BINDING AdapterBinding
;
480 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
482 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
484 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
485 (*AdapterBinding
->ProtocolBinding
->Chars
.TransferDataCompleteHandler
)(
486 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
490 KeLowerIrql(OldIrql
);
495 MiniAdapterHasAddress(
496 PLOGICAL_ADAPTER Adapter
,
499 * FUNCTION: Determines whether a packet has the same destination address as an adapter
501 * Adapter = Pointer to logical adapter object
502 * Packet = Pointer to NDIS packet
504 * TRUE if the destination address is that of the adapter, FALSE if not
510 PNDIS_BUFFER NdisBuffer
;
513 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
518 NDIS_DbgPrint(MID_TRACE
, ("Adapter object was null\n"));
524 NDIS_DbgPrint(MID_TRACE
, ("Packet was null\n"));
529 NdisQueryPacket(Packet
, NULL
, NULL
, &NdisBuffer
, NULL
);
533 NDIS_DbgPrint(MID_TRACE
, ("Packet contains no buffers.\n"));
537 NdisQueryBuffer(NdisBuffer
, (PVOID
)&Start2
, &BufferLength
);
539 /* FIXME: Should handle fragmented packets */
541 switch (Adapter
->NdisMiniportBlock
.MediaType
)
543 case NdisMedium802_3
:
544 Length
= ETH_LENGTH_OF_ADDRESS
;
545 /* Destination address is the first field */
549 NDIS_DbgPrint(MIN_TRACE
, ("Adapter has unsupported media type (0x%X).\n", Adapter
->NdisMiniportBlock
.MediaType
));
553 if (BufferLength
< Length
)
555 NDIS_DbgPrint(MID_TRACE
, ("Buffer is too small.\n"));
559 Start1
= (PUCHAR
)&Adapter
->Address
;
560 NDIS_DbgPrint(MAX_TRACE
, ("packet address: %x:%x:%x:%x:%x:%x adapter address: %x:%x:%x:%x:%x:%x\n",
561 *((char *)Start1
), *(((char *)Start1
)+1), *(((char *)Start1
)+2), *(((char *)Start1
)+3), *(((char *)Start1
)+4), *(((char *)Start1
)+5),
562 *((char *)Start2
), *(((char *)Start2
)+1), *(((char *)Start2
)+2), *(((char *)Start2
)+3), *(((char *)Start2
)+4), *(((char *)Start2
)+5))
565 return (RtlCompareMemory((PVOID
)Start1
, (PVOID
)Start2
, Length
) == Length
);
571 PNDIS_STRING AdapterName
)
573 * FUNCTION: Finds an adapter object by name
575 * AdapterName = Pointer to name of adapter
577 * Pointer to logical adapter object, or NULL if none was found.
578 * If found, the adapter is referenced for the caller. The caller
579 * is responsible for dereferencing after use
583 PLIST_ENTRY CurrentEntry
;
584 PLOGICAL_ADAPTER Adapter
= 0;
588 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
590 if(IsListEmpty(&AdapterListHead
))
592 NDIS_DbgPrint(DEBUG_MINIPORT
, ("No registered miniports for protocol to bind to\n"));
596 KeAcquireSpinLock(&AdapterListLock
, &OldIrql
);
598 CurrentEntry
= AdapterListHead
.Flink
;
600 while (CurrentEntry
!= &AdapterListHead
)
602 Adapter
= CONTAINING_RECORD(CurrentEntry
, LOGICAL_ADAPTER
, ListEntry
);
606 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Examining adapter 0x%lx\n", Adapter
));
607 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterName = %wZ\n", AdapterName
));
608 NDIS_DbgPrint(DEBUG_MINIPORT
, ("DeviceName = %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
610 if (RtlCompareUnicodeString(AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
, TRUE
) == 0)
616 CurrentEntry
= CurrentEntry
->Flink
;
619 KeReleaseSpinLock(&AdapterListLock
, OldIrql
);
623 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Leaving. Adapter found at 0x%x\n", Adapter
));
627 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Leaving (adapter not found).\n"));
635 MiniQueryInformation(
636 PLOGICAL_ADAPTER Adapter
,
642 * FUNCTION: Queries a logical adapter for properties
644 * Adapter = Pointer to the logical adapter object to query
645 * Oid = Specifies the Object ID to query for
646 * Size = Size of the passed buffer
647 * Buffer = Buffer for the output
648 * BytesWritten = Address of buffer to place number of bytes written
650 * If the specified buffer is too small, a new buffer is allocated,
651 * and the query is attempted again
653 * Status of operation
655 * Is there any way to use the buffer provided by the protocol?
658 NDIS_STATUS NdisStatus
;
662 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
664 /* call the miniport's queryinfo handler */
665 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
666 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.QueryInformationHandler
)(
667 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
673 KeLowerIrql(OldIrql
);
675 /* FIXME: Wait in pending case! */
681 MiniCheckForHang( PLOGICAL_ADAPTER Adapter
)
683 * FUNCTION: Checks to see if the miniport is hung
685 * Adapter = Pointer to the logical adapter object
687 * TRUE if the miniport is hung
688 * FALSE if the miniport is not hung
694 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
695 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)
696 Ret
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)(
697 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
);
698 KeLowerIrql(OldIrql
);
705 PLOGICAL_ADAPTER Adapter
,
706 PBOOLEAN AddressingReset
)
708 * FUNCTION: Resets the miniport
710 * Adapter = Pointer to the logical adapter object
711 * AddressingReset = Set to TRUE if we need to call MiniportSetInformation later
713 * Status of the operation
719 if (MiniIsBusy(Adapter
, NdisWorkItemResetRequested
)) {
720 MiniQueueWorkItem(Adapter
, NdisWorkItemResetRequested
, NULL
, FALSE
);
721 return NDIS_STATUS_PENDING
;
724 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
725 NdisMIndicateStatusComplete(Adapter
);
727 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
728 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
729 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
732 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
733 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
734 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
736 KeLowerIrql(OldIrql
);
738 if (Status
!= NDIS_STATUS_PENDING
) {
739 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
740 NdisMIndicateStatusComplete(Adapter
);
749 PVOID DeferredContext
,
750 PVOID SystemArgument1
,
751 PVOID SystemArgument2
)
753 PLOGICAL_ADAPTER Adapter
= DeferredContext
;
754 BOOLEAN AddressingReset
= FALSE
;
757 if (MiniCheckForHang(Adapter
)) {
758 NDIS_DbgPrint(MIN_TRACE
, ("Miniport detected adapter hang\n"));
759 MiniReset(Adapter
, &AddressingReset
);
762 /* FIXME: We should call MiniportSetInformation if AddressingReset is TRUE */
769 PLOGICAL_ADAPTER Adapter
,
770 NDIS_WORK_ITEM_TYPE WorkItemType
,
771 PVOID WorkItemContext
,
774 * FUNCTION: Queues a work item for execution at a later time
776 * Adapter = Pointer to the logical adapter object to queue work item on
777 * WorkItemType = Type of work item to queue
778 * WorkItemContext = Pointer to context information for work item
780 * Status of operation
783 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
784 PIO_WORKITEM IoWorkItem
;
787 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
791 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
794 if (WorkItemType
== NdisWorkItemSend
)
796 NDIS_DbgPrint(MIN_TRACE
, ("Requeuing failed packet (%x).\n", WorkItemContext
));
797 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= WorkItemContext
;
801 //This should never happen
807 MiniportWorkItem
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_MINIPORT_WORK_ITEM
));
808 if (!MiniportWorkItem
)
810 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
811 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
815 MiniportWorkItem
->WorkItemType
= WorkItemType
;
816 MiniportWorkItem
->WorkItemContext
= WorkItemContext
;
818 /* safe due to adapter lock held */
819 MiniportWorkItem
->Link
.Next
= NULL
;
820 if (!Adapter
->WorkQueueHead
)
822 Adapter
->WorkQueueHead
= MiniportWorkItem
;
823 Adapter
->WorkQueueTail
= MiniportWorkItem
;
827 Adapter
->WorkQueueTail
->Link
.Next
= (PSINGLE_LIST_ENTRY
)MiniportWorkItem
;
828 Adapter
->WorkQueueTail
= MiniportWorkItem
;
832 IoWorkItem
= IoAllocateWorkItem(Adapter
->NdisMiniportBlock
.DeviceObject
);
834 IoQueueWorkItem(IoWorkItem
, MiniportWorker
, DelayedWorkQueue
, IoWorkItem
);
836 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
843 PLOGICAL_ADAPTER Adapter
,
844 NDIS_WORK_ITEM_TYPE
*WorkItemType
,
845 PVOID
*WorkItemContext
)
847 * FUNCTION: Dequeues a work item from the work queue of a logical adapter
849 * Adapter = Pointer to the logical adapter object to dequeue work item from
850 * AdapterBinding = Address of buffer for adapter binding for this request
851 * WorkItemType = Address of buffer for work item type
852 * WorkItemContext = Address of buffer for pointer to context information
854 * Adapter lock must be held when called
856 * Status of operation
859 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
862 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
864 MiniportWorkItem
= Adapter
->WorkQueueHead
;
866 if ((Packet
= Adapter
->NdisMiniportBlock
.FirstPendingPacket
))
868 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= NULL
;
870 *WorkItemType
= NdisWorkItemSend
;
871 *WorkItemContext
= Packet
;
873 return NDIS_STATUS_SUCCESS
;
875 else if (MiniportWorkItem
)
877 /* safe due to adapter lock held */
878 Adapter
->WorkQueueHead
= (PNDIS_MINIPORT_WORK_ITEM
)MiniportWorkItem
->Link
.Next
;
880 if (MiniportWorkItem
== Adapter
->WorkQueueTail
)
881 Adapter
->WorkQueueTail
= NULL
;
883 *WorkItemType
= MiniportWorkItem
->WorkItemType
;
884 *WorkItemContext
= MiniportWorkItem
->WorkItemContext
;
886 ExFreePool(MiniportWorkItem
);
888 return NDIS_STATUS_SUCCESS
;
892 return NDIS_STATUS_FAILURE
;
899 PLOGICAL_ADAPTER Adapter
,
900 PNDIS_REQUEST NdisRequest
)
902 * FUNCTION: Sends a request to a miniport
904 * AdapterBinding = Pointer to binding used in the request
905 * NdisRequest = Pointer to NDIS request structure describing request
907 * Status of operation
912 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
914 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
916 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
917 Adapter
->NdisMiniportBlock
.PendingRequest
= NdisRequest
;
918 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
920 switch (NdisRequest
->RequestType
)
922 case NdisRequestQueryInformation
:
923 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.QueryInformationHandler
)(
924 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
925 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
,
926 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
,
927 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
,
928 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
,
929 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesNeeded
);
932 case NdisRequestSetInformation
:
933 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SetInformationHandler
)(
934 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
935 NdisRequest
->DATA
.SET_INFORMATION
.Oid
,
936 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
,
937 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
,
938 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
,
939 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesNeeded
);
943 Status
= NDIS_STATUS_FAILURE
;
946 if (Status
!= NDIS_STATUS_PENDING
) {
947 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
948 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
949 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
952 KeLowerIrql(OldIrql
);
960 #undef NdisMSetInformationComplete
963 NdisMSetInformationComplete(
964 IN NDIS_HANDLE MiniportAdapterHandle
,
965 IN NDIS_STATUS Status
)
967 PLOGICAL_ADAPTER Adapter
=
968 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
971 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
972 if (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)
973 (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)(MiniportAdapterHandle
, Status
);
974 KeLowerIrql(OldIrql
);
981 #undef NdisMQueryInformationComplete
984 NdisMQueryInformationComplete(
985 IN NDIS_HANDLE MiniportAdapterHandle
,
986 IN NDIS_STATUS Status
)
988 PLOGICAL_ADAPTER Adapter
=
989 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
992 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
993 if( Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)
994 (Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)(MiniportAdapterHandle
, Status
);
995 KeLowerIrql(OldIrql
);
1000 MiniportWorker(IN PDEVICE_OBJECT DeviceObject
, IN PVOID Context
)
1002 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
1003 KIRQL OldIrql
, RaiseOldIrql
;
1004 NDIS_STATUS NdisStatus
;
1005 PVOID WorkItemContext
;
1006 NDIS_WORK_ITEM_TYPE WorkItemType
;
1007 BOOLEAN AddressingReset
;
1009 IoFreeWorkItem((PIO_WORKITEM
)Context
);
1011 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1015 (Adapter
, &WorkItemType
, &WorkItemContext
);
1017 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1019 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1021 switch (WorkItemType
)
1023 case NdisWorkItemSend
:
1025 * called by ProSend when protocols want to send packets to the miniport
1028 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
1030 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1032 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1033 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1034 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1035 NdisStatus
= NDIS_STATUS_PENDING
;
1039 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
1040 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1042 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1043 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1044 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1046 KeLowerIrql(RaiseOldIrql
);
1048 NdisStatus
= NDIS_GET_PACKET_STATUS((PNDIS_PACKET
)WorkItemContext
);
1049 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1050 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1057 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1059 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1060 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1061 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1062 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1063 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1067 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
1068 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1069 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1070 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1071 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1072 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1073 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1074 KeLowerIrql(RaiseOldIrql
);
1075 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1076 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1082 if( NdisStatus
!= NDIS_STATUS_PENDING
) {
1084 ( Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1088 case NdisWorkItemSendLoopback
:
1090 * called by ProSend when protocols want to send loopback packets
1092 /* XXX atm ProIndicatePacket sends a packet up via the loopback adapter only */
1093 NdisStatus
= ProIndicatePacket(Adapter
, (PNDIS_PACKET
)WorkItemContext
);
1095 if( NdisStatus
!= NDIS_STATUS_PENDING
)
1096 MiniSendComplete((NDIS_HANDLE
)Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1099 case NdisWorkItemReturnPackets
:
1102 case NdisWorkItemResetRequested
:
1103 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
1104 NdisMIndicateStatusComplete(Adapter
);
1106 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1107 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
1108 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1111 if (NdisStatus
== NDIS_STATUS_PENDING
)
1113 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1114 Adapter
->NdisMiniportBlock
.ResetStatus
= NDIS_STATUS_PENDING
;
1115 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1118 KeLowerIrql(OldIrql
);
1120 if (NdisStatus
!= NDIS_STATUS_PENDING
)
1121 MiniResetComplete(Adapter
, NdisStatus
, AddressingReset
);
1124 case NdisWorkItemResetInProgress
:
1127 case NdisWorkItemMiniportCallback
:
1130 case NdisWorkItemRequest
:
1131 NdisStatus
= MiniDoRequest(Adapter
, (PNDIS_REQUEST
)WorkItemContext
);
1133 if (NdisStatus
== NDIS_STATUS_PENDING
)
1136 switch (((PNDIS_REQUEST
)WorkItemContext
)->RequestType
)
1138 case NdisRequestQueryInformation
:
1139 NdisMQueryInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1142 case NdisRequestSetInformation
:
1143 NdisMSetInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1147 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS request type.\n"));
1153 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS work item type (%d).\n", WorkItemType
));
1164 IN NDIS_HANDLE MiniportHandle
,
1165 IN NDIS_STATUS GeneralStatus
,
1166 IN PVOID StatusBuffer
,
1167 IN UINT StatusBufferSize
)
1169 PLOGICAL_ADAPTER Adapter
= MiniportHandle
;
1170 PLIST_ENTRY CurrentEntry
;
1171 PADAPTER_BINDING AdapterBinding
;
1174 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1176 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1178 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1180 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1182 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusHandler
)(
1183 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
1188 CurrentEntry
= CurrentEntry
->Flink
;
1191 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1198 IN NDIS_HANDLE MiniportAdapterHandle
)
1200 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1201 PLIST_ENTRY CurrentEntry
;
1202 PADAPTER_BINDING AdapterBinding
;
1205 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1207 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1209 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1211 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1213 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusCompleteHandler
)(
1214 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
);
1216 CurrentEntry
= CurrentEntry
->Flink
;
1219 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1229 IN NDIS_HANDLE LogHandle
)
1231 PNDIS_LOG Log
= (PNDIS_LOG
)LogHandle
;
1232 PNDIS_MINIPORT_BLOCK Miniport
= Log
->Miniport
;
1235 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1237 KeAcquireSpinLock(&(Miniport
)->Lock
, &OldIrql
);
1238 Miniport
->Log
= NULL
;
1239 KeReleaseSpinLock(&(Miniport
)->Lock
, OldIrql
);
1250 IN NDIS_HANDLE MiniportAdapterHandle
,
1252 OUT PNDIS_HANDLE LogHandle
)
1254 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1258 NDIS_DbgPrint(MAX_TRACE
, ("called: MiniportAdapterHandle 0x%x, Size %ld\n", MiniportAdapterHandle
, Size
));
1260 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1262 if (Adapter
->NdisMiniportBlock
.Log
)
1265 return NDIS_STATUS_FAILURE
;
1268 Log
= ExAllocatePool(NonPagedPool
, Size
+ sizeof(NDIS_LOG
));
1272 return NDIS_STATUS_RESOURCES
;
1275 Adapter
->NdisMiniportBlock
.Log
= Log
;
1277 KeInitializeSpinLock(&Log
->LogLock
);
1279 Log
->Miniport
= &Adapter
->NdisMiniportBlock
;
1280 Log
->TotalSize
= Size
;
1281 Log
->CurrentSize
= 0;
1288 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1290 return NDIS_STATUS_SUCCESS
;
1298 NdisMDeregisterAdapterShutdownHandler(
1299 IN NDIS_HANDLE MiniportHandle
)
1301 * FUNCTION: de-registers a shutdown handler
1302 * ARGUMENTS: MiniportHandle: Handle passed into MiniportInitialize
1305 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1307 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1309 if(Adapter
->BugcheckContext
->ShutdownHandler
) {
1310 KeDeregisterBugCheckCallback(Adapter
->BugcheckContext
->CallbackRecord
);
1311 IoUnregisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1321 IN NDIS_HANDLE LogHandle
)
1323 PNDIS_LOG Log
= (PNDIS_LOG
) LogHandle
;
1326 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1329 KeAcquireSpinLock(&Log
->LogLock
, &OldIrql
);
1331 /* Set buffers size */
1332 Log
->CurrentSize
= 0;
1337 KeReleaseSpinLock(&Log
->LogLock
, OldIrql
);
1343 #undef NdisMIndicateStatus
1346 NdisMIndicateStatus(
1347 IN NDIS_HANDLE MiniportAdapterHandle
,
1348 IN NDIS_STATUS GeneralStatus
,
1349 IN PVOID StatusBuffer
,
1350 IN UINT StatusBufferSize
)
1352 MiniStatus(MiniportAdapterHandle
, GeneralStatus
, StatusBuffer
, StatusBufferSize
);
1358 #undef NdisMIndicateStatusComplete
1361 NdisMIndicateStatusComplete(
1362 IN NDIS_HANDLE MiniportAdapterHandle
)
1364 MiniStatusComplete(MiniportAdapterHandle
);
1373 NdisInitializeWrapper(
1374 OUT PNDIS_HANDLE NdisWrapperHandle
,
1375 IN PVOID SystemSpecific1
,
1376 IN PVOID SystemSpecific2
,
1377 IN PVOID SystemSpecific3
)
1379 * FUNCTION: Notifies the NDIS library that a new miniport is initializing
1381 * NdisWrapperHandle = Address of buffer to place NDIS wrapper handle
1382 * SystemSpecific1 = Pointer to the driver's driver object
1383 * SystemSpecific2 = Pointer to the driver's registry path
1384 * SystemSpecific3 = Always NULL
1386 * - SystemSpecific2 goes invalid so we copy it
1389 PNDIS_M_DRIVER_BLOCK Miniport
;
1390 PUNICODE_STRING RegistryPath
;
1391 WCHAR
*RegistryBuffer
;
1393 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1395 ASSERT(NdisWrapperHandle
);
1397 *NdisWrapperHandle
= NULL
;
1399 #if BREAK_ON_MINIPORT_INIT
1400 __asm__ ("int $3\n");
1403 Miniport
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DRIVER_BLOCK
));
1407 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1411 RtlZeroMemory(Miniport
, sizeof(NDIS_M_DRIVER_BLOCK
));
1413 KeInitializeSpinLock(&Miniport
->Lock
);
1415 Miniport
->DriverObject
= (PDRIVER_OBJECT
)SystemSpecific1
;
1417 /* set the miniport's driver registry path */
1418 RegistryPath
= ExAllocatePool(PagedPool
, sizeof(UNICODE_STRING
));
1421 ExFreePool(Miniport
);
1422 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1426 RegistryPath
->Length
= ((PUNICODE_STRING
)SystemSpecific2
)->Length
;
1427 RegistryPath
->MaximumLength
= RegistryPath
->Length
+ sizeof(WCHAR
); /* room for 0-term */
1429 RegistryBuffer
= ExAllocatePool(PagedPool
, RegistryPath
->MaximumLength
);
1432 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1433 ExFreePool(Miniport
);
1434 ExFreePool(RegistryPath
);
1438 RtlCopyMemory(RegistryBuffer
, ((PUNICODE_STRING
)SystemSpecific2
)->Buffer
, RegistryPath
->Length
);
1439 RegistryBuffer
[RegistryPath
->Length
/sizeof(WCHAR
)] = 0;
1441 RegistryPath
->Buffer
= RegistryBuffer
;
1442 Miniport
->RegistryPath
= RegistryPath
;
1444 InitializeListHead(&Miniport
->DeviceList
);
1446 /* Put miniport in global miniport list */
1447 ExInterlockedInsertTailList(&MiniportListHead
, &Miniport
->ListEntry
, &MiniportListLock
);
1449 *NdisWrapperHandle
= Miniport
;
1453 VOID NTAPI
NdisIBugcheckCallback(
1457 * FUNCTION: Internal callback for handling bugchecks - calls adapter's shutdown handler
1459 * Buffer: Pointer to a bugcheck callback context
1463 PMINIPORT_BUGCHECK_CONTEXT Context
= (PMINIPORT_BUGCHECK_CONTEXT
)Buffer
;
1464 ADAPTER_SHUTDOWN_HANDLER sh
= (ADAPTER_SHUTDOWN_HANDLER
)Context
->ShutdownHandler
;
1466 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1469 sh(Context
->DriverContext
);
1478 NdisMRegisterAdapterShutdownHandler(
1479 IN NDIS_HANDLE MiniportHandle
,
1480 IN PVOID ShutdownContext
,
1481 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
1483 * FUNCTION: Register a shutdown handler for an adapter
1485 * MiniportHandle: Handle originally passed into MiniportInitialize
1486 * ShutdownContext: Pre-initialized bugcheck context
1487 * ShutdownHandler: Function to call to handle the bugcheck
1489 * - I'm not sure about ShutdownContext
1492 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1493 PMINIPORT_BUGCHECK_CONTEXT BugcheckContext
;
1495 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1497 BugcheckContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_BUGCHECK_CONTEXT
));
1498 if(!BugcheckContext
)
1500 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1504 BugcheckContext
->ShutdownHandler
= ShutdownHandler
;
1505 BugcheckContext
->DriverContext
= ShutdownContext
;
1507 BugcheckContext
->CallbackRecord
= ExAllocatePool(NonPagedPool
, sizeof(KBUGCHECK_CALLBACK_RECORD
));
1508 if (!BugcheckContext
->CallbackRecord
) {
1509 ExFreePool(BugcheckContext
);
1513 Adapter
->BugcheckContext
= BugcheckContext
;
1515 KeInitializeCallbackRecord(BugcheckContext
->CallbackRecord
);
1517 KeRegisterBugCheckCallback(BugcheckContext
->CallbackRecord
, NdisIBugcheckCallback
,
1518 BugcheckContext
, sizeof(BugcheckContext
), (PUCHAR
)"Ndis Miniport");
1520 IoRegisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1526 PLOGICAL_ADAPTER Adapter
,
1527 NDIS_OID AddressOID
)
1529 * FUNCTION: Queries miniport for information
1531 * Adapter = Pointer to logical adapter
1532 * AddressOID = OID to use to query for current address
1534 * Status of operation
1538 NDIS_STATUS NdisStatus
;
1540 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1542 /* Get MAC options for adapter */
1543 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAC_OPTIONS
, sizeof(UINT
),
1544 &Adapter
->NdisMiniportBlock
.MacOptions
,
1547 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1549 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAC_OPTIONS failed. NdisStatus (0x%X).\n", NdisStatus
));
1553 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MacOptions (0x%X).\n", Adapter
->NdisMiniportBlock
.MacOptions
));
1555 /* Get current hardware address of adapter */
1556 NdisStatus
= MiniQueryInformation(Adapter
, AddressOID
, Adapter
->AddressLength
,
1557 &Adapter
->Address
, &BytesWritten
);
1559 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1561 NDIS_DbgPrint(MIN_TRACE
, ("Address OID (0x%X) failed. NdisStatus (0x%X).\n", AddressOID
, NdisStatus
));
1569 PUCHAR A
= (PUCHAR
)&Adapter
->Address
.Type
.Medium802_3
;
1571 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]));
1575 /* Get maximum lookahead buffer size of adapter */
1576 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_LOOKAHEAD
, sizeof(ULONG
),
1577 &Adapter
->NdisMiniportBlock
.MaximumLookahead
, &BytesWritten
);
1579 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1581 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1585 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MaxLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.MaximumLookahead
));
1587 /* Get current lookahead buffer size of adapter */
1588 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_CURRENT_LOOKAHEAD
, sizeof(ULONG
),
1589 &Adapter
->NdisMiniportBlock
.CurrentLookahead
, &BytesWritten
);
1591 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1593 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_CURRENT_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1597 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_SEND_PACKETS
, sizeof(ULONG
),
1598 &Adapter
->NdisMiniportBlock
.MaxSendPackets
, &BytesWritten
);
1600 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1602 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_SEND_PACKETS failed. NdisStatus (0x%X).\n", NdisStatus
));
1604 /* Set it to 1 if it fails because some drivers don't support this (?)*/
1605 Adapter
->NdisMiniportBlock
.MaxSendPackets
= 1;
1608 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.CurrentLookahead
));
1610 return STATUS_SUCCESS
;
1616 NdisIForwardIrpAndWaitCompletionRoutine(
1621 PKEVENT Event
= Context
;
1623 if (Irp
->PendingReturned
)
1624 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
1626 return STATUS_MORE_PROCESSING_REQUIRED
;
1632 NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter
, PIRP Irp
)
1637 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1638 IoCopyCurrentIrpStackLocationToNext(Irp
);
1639 IoSetCompletionRoutine(Irp
, NdisIForwardIrpAndWaitCompletionRoutine
, &Event
,
1641 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
1642 if (Status
== STATUS_PENDING
)
1644 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1645 Status
= Irp
->IoStatus
.Status
;
1653 NdisIPnPStartDevice(
1654 IN PDEVICE_OBJECT DeviceObject
,
1657 * FUNCTION: Handle the PnP start device event
1659 * DeviceObejct = Functional Device Object
1660 * Irp = IRP_MN_START_DEVICE I/O request packet
1662 * Status of operation
1665 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
1666 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1667 NDIS_WRAPPER_CONTEXT WrapperContext
;
1668 NDIS_STATUS NdisStatus
;
1669 NDIS_STATUS OpenErrorStatus
;
1671 UINT SelectedMediumIndex
= 0;
1672 NDIS_OID AddressOID
;
1673 BOOLEAN Success
= FALSE
;
1674 ULONG ResourceCount
;
1675 ULONG ResourceListSize
;
1676 UNICODE_STRING ParamName
;
1677 PNDIS_CONFIGURATION_PARAMETER ConfigParam
;
1678 NDIS_HANDLE ConfigHandle
;
1680 LARGE_INTEGER Timeout
;
1681 UINT MaxMulticastAddresses
;
1685 * Prepare wrapper context used by HW and configuration routines.
1688 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Start Device %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
1690 NDIS_DbgPrint(MAX_TRACE
, ("Inserting adapter 0x%x into adapter list\n", Adapter
));
1692 /* Put adapter in global adapter list */
1693 ExInterlockedInsertTailList(&AdapterListHead
, &Adapter
->ListEntry
, &AdapterListLock
);
1695 Status
= IoOpenDeviceRegistryKey(
1696 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
, PLUGPLAY_REGKEY_DRIVER
,
1697 KEY_ALL_ACCESS
, &WrapperContext
.RegistryHandle
);
1698 if (!NT_SUCCESS(Status
))
1700 NDIS_DbgPrint(MIN_TRACE
,("failed to open adapter-specific reg key\n"));
1701 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1705 NDIS_DbgPrint(MAX_TRACE
, ("opened device reg key\n"));
1707 WrapperContext
.DeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
1710 * Store the adapter resources used by HW routines such as
1711 * NdisMQueryAdapterResources.
1714 if (Stack
->Parameters
.StartDevice
.AllocatedResources
!= NULL
)
1716 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResources
->List
[0].
1717 PartialResourceList
.Count
;
1719 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1720 PartialDescriptors
[ResourceCount
]);
1722 Adapter
->NdisMiniportBlock
.AllocatedResources
=
1723 ExAllocatePool(PagedPool
, ResourceListSize
);
1724 if (Adapter
->NdisMiniportBlock
.AllocatedResources
== NULL
)
1726 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1727 return STATUS_INSUFFICIENT_RESOURCES
;
1730 Adapter
->NdisMiniportBlock
.Resources
=
1731 ExAllocatePool(PagedPool
, ResourceListSize
);
1732 if (!Adapter
->NdisMiniportBlock
.Resources
)
1734 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1735 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1736 return STATUS_INSUFFICIENT_RESOURCES
;
1739 RtlCopyMemory(Adapter
->NdisMiniportBlock
.Resources
,
1740 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1743 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResources
,
1744 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1748 if (Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
!= NULL
)
1750 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
->List
[0].
1751 PartialResourceList
.Count
;
1753 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1754 PartialDescriptors
[ResourceCount
]);
1756 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
=
1757 ExAllocatePool(PagedPool
, ResourceListSize
);
1758 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
== NULL
)
1760 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1761 return STATUS_INSUFFICIENT_RESOURCES
;
1764 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
,
1765 Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
,
1770 * Store the Bus Type, Bus Number and Slot information. It's used by
1771 * the hardware routines then.
1774 NdisOpenConfiguration(&NdisStatus
, &ConfigHandle
, (NDIS_HANDLE
)&WrapperContext
);
1776 Size
= sizeof(ULONG
);
1777 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1778 DevicePropertyLegacyBusType
, Size
,
1779 &Adapter
->NdisMiniportBlock
.BusType
, &Size
);
1780 if (!NT_SUCCESS(Status
) || (INTERFACE_TYPE
)Adapter
->NdisMiniportBlock
.BusType
== InterfaceTypeUndefined
)
1782 NdisInitUnicodeString(&ParamName
, L
"BusType");
1783 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1784 &ParamName
, NdisParameterInteger
);
1785 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1786 Adapter
->NdisMiniportBlock
.BusType
= ConfigParam
->ParameterData
.IntegerData
;
1788 Adapter
->NdisMiniportBlock
.BusType
= Isa
;
1791 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1792 DevicePropertyBusNumber
, Size
,
1793 &Adapter
->NdisMiniportBlock
.BusNumber
, &Size
);
1794 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.BusNumber
== 0xFFFFFFF0)
1796 NdisInitUnicodeString(&ParamName
, L
"BusNumber");
1797 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1798 &ParamName
, NdisParameterInteger
);
1799 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1800 Adapter
->NdisMiniportBlock
.BusNumber
= ConfigParam
->ParameterData
.IntegerData
;
1802 Adapter
->NdisMiniportBlock
.BusNumber
= 0;
1804 WrapperContext
.BusNumber
= Adapter
->NdisMiniportBlock
.BusNumber
;
1806 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1807 DevicePropertyAddress
, Size
,
1808 &Adapter
->NdisMiniportBlock
.SlotNumber
, &Size
);
1809 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.SlotNumber
== (NDIS_INTERFACE_TYPE
)-1)
1811 NdisInitUnicodeString(&ParamName
, L
"SlotNumber");
1812 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1813 &ParamName
, NdisParameterInteger
);
1814 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1815 Adapter
->NdisMiniportBlock
.SlotNumber
= ConfigParam
->ParameterData
.IntegerData
;
1817 Adapter
->NdisMiniportBlock
.SlotNumber
= 0;
1821 /* Convert slotnumber to PCI_SLOT_NUMBER */
1822 ULONG PciSlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1823 PCI_SLOT_NUMBER SlotNumber
;
1825 SlotNumber
.u
.AsULONG
= 0;
1826 SlotNumber
.u
.bits
.DeviceNumber
= (PciSlotNumber
>> 16) & 0xFFFF;
1827 SlotNumber
.u
.bits
.FunctionNumber
= PciSlotNumber
& 0xFFFF;
1829 Adapter
->NdisMiniportBlock
.SlotNumber
= SlotNumber
.u
.AsULONG
;
1831 NdisCloseConfiguration(ConfigHandle
);
1833 /* Set handlers (some NDIS macros require these) */
1834 Adapter
->NdisMiniportBlock
.EthRxCompleteHandler
= EthFilterDprIndicateReceiveComplete
;
1835 Adapter
->NdisMiniportBlock
.EthRxIndicateHandler
= EthFilterDprIndicateReceive
;
1836 Adapter
->NdisMiniportBlock
.SendCompleteHandler
= MiniSendComplete
;
1837 Adapter
->NdisMiniportBlock
.SendResourcesHandler
= MiniSendResourcesAvailable
;
1838 Adapter
->NdisMiniportBlock
.ResetCompleteHandler
= MiniResetComplete
;
1839 Adapter
->NdisMiniportBlock
.TDCompleteHandler
= MiniTransferDataComplete
;
1840 Adapter
->NdisMiniportBlock
.PacketIndicateHandler
= MiniIndicateReceivePacket
;
1841 Adapter
->NdisMiniportBlock
.StatusHandler
= MiniStatus
;
1842 Adapter
->NdisMiniportBlock
.StatusCompleteHandler
= MiniStatusComplete
;
1843 Adapter
->NdisMiniportBlock
.SendPacketsHandler
= ProSendPackets
;
1844 Adapter
->NdisMiniportBlock
.QueryCompleteHandler
= MiniRequestComplete
;
1845 Adapter
->NdisMiniportBlock
.SetCompleteHandler
= MiniRequestComplete
;
1848 * Call MiniportInitialize.
1851 NDIS_DbgPrint(MID_TRACE
, ("calling MiniportInitialize\n"));
1852 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.InitializeHandler
)(
1853 &OpenErrorStatus
, &SelectedMediumIndex
, &MediaArray
[0],
1854 MEDIA_ARRAY_SIZE
, Adapter
, (NDIS_HANDLE
)&WrapperContext
);
1856 ZwClose(WrapperContext
.RegistryHandle
);
1858 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1860 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() failed for an adapter.\n"));
1861 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1865 if (SelectedMediumIndex
>= MEDIA_ARRAY_SIZE
)
1867 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() failed for an adapter\n"));
1868 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1869 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
1872 Adapter
->NdisMiniportBlock
.MediaType
= MediaArray
[SelectedMediumIndex
];
1874 switch (Adapter
->NdisMiniportBlock
.MediaType
)
1876 case NdisMedium802_3
:
1877 Adapter
->MediumHeaderSize
= 14; /* XXX figure out what to do about LLC */
1878 AddressOID
= OID_802_3_CURRENT_ADDRESS
;
1879 Adapter
->AddressLength
= ETH_LENGTH_OF_ADDRESS
;
1880 NdisStatus
= DoQueries(Adapter
, AddressOID
);
1881 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1883 NdisStatus
= MiniQueryInformation(Adapter
, OID_802_3_MAXIMUM_LIST_SIZE
, sizeof(UINT
),
1884 &MaxMulticastAddresses
, &BytesWritten
);
1886 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1888 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1889 NDIS_DbgPrint(MAX_TRACE
, ("MiniQueryInformation failed (%x)\n", NdisStatus
));
1893 Success
= EthCreateFilter(MaxMulticastAddresses
,
1894 Adapter
->Address
.Type
.Medium802_3
,
1895 &Adapter
->NdisMiniportBlock
.EthDB
);
1897 ((PETHI_FILTER
)Adapter
->NdisMiniportBlock
.EthDB
)->Miniport
= (PNDIS_MINIPORT_BLOCK
)Adapter
;
1899 NdisStatus
= NDIS_STATUS_RESOURCES
;
1904 /* FIXME: Support other types of media */
1905 NDIS_DbgPrint(MIN_TRACE
, ("error: unsupported media\n"));
1907 /* FIXME - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); */
1908 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1909 return STATUS_UNSUCCESSFUL
;
1912 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1914 NDIS_DbgPrint(MAX_TRACE
, ("couldn't create filter (%x)\n", NdisStatus
));
1918 /* Check for a hang every two seconds if it wasn't set in MiniportInitialize */
1919 if (Adapter
->NdisMiniportBlock
.CheckForHangSeconds
== 0)
1920 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= 2;
1922 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
1923 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStarted
;
1925 Timeout
.QuadPart
= Int32x32To64(Adapter
->NdisMiniportBlock
.CheckForHangSeconds
, -1000000);
1926 KeSetTimerEx(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
, Timeout
,
1927 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
* 1000,
1928 &Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
);
1930 /* Put adapter in adapter list for this miniport */
1931 ExInterlockedInsertTailList(&Adapter
->NdisMiniportBlock
.DriverHandle
->DeviceList
, &Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
1933 return STATUS_SUCCESS
;
1940 IN PDEVICE_OBJECT DeviceObject
,
1943 * FUNCTION: Handle the PnP stop device event
1945 * DeviceObejct = Functional Device Object
1946 * Irp = IRP_MN_STOP_DEVICE I/O request packet
1948 * Status of operation
1951 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1953 /* Remove adapter from adapter list for this miniport */
1954 ExInterlockedRemoveEntryList(&Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
1956 /* Remove adapter from global adapter list */
1957 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1959 KeCancelTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
1961 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.HaltHandler
)(Adapter
);
1963 if (Adapter
->NdisMiniportBlock
.AllocatedResources
)
1965 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1966 Adapter
->NdisMiniportBlock
.AllocatedResources
= NULL
;
1968 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
)
1970 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
);
1971 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
= NULL
;
1974 if (Adapter
->NdisMiniportBlock
.Resources
)
1976 ExFreePool(Adapter
->NdisMiniportBlock
.Resources
);
1977 Adapter
->NdisMiniportBlock
.Resources
= NULL
;
1980 if (Adapter
->NdisMiniportBlock
.EthDB
)
1982 EthDeleteFilter(Adapter
->NdisMiniportBlock
.EthDB
);
1983 Adapter
->NdisMiniportBlock
.EthDB
= NULL
;
1986 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
1987 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStopped
;
1989 return STATUS_SUCCESS
;
1995 IN PDEVICE_OBJECT DeviceObject
,
1998 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
1999 PMINIPORT_BUGCHECK_CONTEXT Context
= Adapter
->BugcheckContext
;
2000 ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
= Context
->ShutdownHandler
;
2002 ASSERT(ShutdownHandler
);
2004 ShutdownHandler(Context
->DriverContext
);
2006 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2007 Irp
->IoStatus
.Information
= 0;
2009 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2011 return STATUS_SUCCESS
;
2016 NdisIDeviceIoControl(
2017 IN PDEVICE_OBJECT DeviceObject
,
2020 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2021 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2022 NDIS_STATUS Status
= STATUS_NOT_SUPPORTED
;
2024 Irp
->IoStatus
.Information
= 0;
2028 switch (Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
2030 case IOCTL_NDIS_QUERY_GLOBAL_STATS
:
2031 Status
= MiniQueryInformation(Adapter
,
2032 (NDIS_OID
)Irp
->AssociatedIrp
.SystemBuffer
,
2033 Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
,
2034 MmGetSystemAddressForMdl(Irp
->MdlAddress
),
2035 &Irp
->IoStatus
.Information
);
2043 if (Status
!= NDIS_STATUS_PENDING
)
2045 Irp
->IoStatus
.Status
= Status
;
2046 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2049 IoMarkIrpPending(Irp
);
2058 IN PDEVICE_OBJECT DeviceObject
,
2061 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2062 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2065 switch (Stack
->MinorFunction
)
2067 case IRP_MN_START_DEVICE
:
2068 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2069 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2071 Status
= NdisIPnPStartDevice(DeviceObject
, Irp
);
2073 Irp
->IoStatus
.Status
= Status
;
2074 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2077 case IRP_MN_STOP_DEVICE
:
2078 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2079 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2081 Status
= NdisIPnPStopDevice(DeviceObject
, Irp
);
2083 Irp
->IoStatus
.Status
= Status
;
2084 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2087 case IRP_MN_QUERY_REMOVE_DEVICE
:
2088 case IRP_MN_QUERY_STOP_DEVICE
:
2089 Status
= NdisIPnPQueryStopDevice(DeviceObject
, Irp
);
2090 Irp
->IoStatus
.Status
= Status
;
2091 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2094 case IRP_MN_CANCEL_REMOVE_DEVICE
:
2095 case IRP_MN_CANCEL_STOP_DEVICE
:
2096 Status
= NdisIPnPCancelStopDevice(DeviceObject
, Irp
);
2097 Irp
->IoStatus
.Status
= Status
;
2098 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2102 IoSkipCurrentIrpStackLocation(Irp
);
2103 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
2114 IN PDRIVER_OBJECT DriverObject
,
2115 IN PDEVICE_OBJECT PhysicalDeviceObject
)
2117 * FUNCTION: Create a device for an adapter found using PnP
2119 * DriverObject = Pointer to the miniport driver object
2120 * PhysicalDeviceObject = Pointer to the PDO for our adapter
2123 static const WCHAR ClassKeyName
[] = {'C','l','a','s','s','\\'};
2124 static const WCHAR LinkageKeyName
[] = {'\\','L','i','n','k','a','g','e',0};
2125 PNDIS_M_DRIVER_BLOCK Miniport
;
2126 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2127 WCHAR
*LinkageKeyBuffer
;
2128 ULONG DriverKeyLength
;
2129 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
2130 UNICODE_STRING ExportName
;
2131 PDEVICE_OBJECT DeviceObject
;
2132 PLOGICAL_ADAPTER Adapter
;
2136 * Gain the access to the miniport data structure first.
2139 MiniportPtr
= IoGetDriverObjectExtension(DriverObject
, (PVOID
)TAG('D','I','M','N'));
2140 if (MiniportPtr
== NULL
)
2142 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get driver object extension.\n"));
2143 return STATUS_UNSUCCESSFUL
;
2145 Miniport
= *MiniportPtr
;
2148 * Get name of the Linkage registry key for our adapter. It's located under
2149 * the driver key for our driver and so we have basicly two ways to do it.
2150 * Either we can use IoOpenDriverRegistryKey or compose it using information
2151 * gathered by IoGetDeviceProperty. I choosed the second because
2152 * IoOpenDriverRegistryKey wasn't implemented at the time of writing.
2155 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2156 0, NULL
, &DriverKeyLength
);
2157 if (Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
&& Status
!= STATUS_SUCCESS
)
2159 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get miniport driver key length.\n"));
2163 LinkageKeyBuffer
= ExAllocatePool(PagedPool
, DriverKeyLength
+
2164 sizeof(ClassKeyName
) + sizeof(LinkageKeyName
));
2165 if (LinkageKeyBuffer
== NULL
)
2167 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't allocate memory for driver key name.\n"));
2168 return STATUS_INSUFFICIENT_RESOURCES
;
2171 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2172 DriverKeyLength
, LinkageKeyBuffer
+
2173 (sizeof(ClassKeyName
) / sizeof(WCHAR
)),
2175 if (!NT_SUCCESS(Status
))
2177 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get miniport driver key.\n"));
2178 ExFreePool(LinkageKeyBuffer
);
2182 /* Compose the linkage key name. */
2183 RtlCopyMemory(LinkageKeyBuffer
, ClassKeyName
, sizeof(ClassKeyName
));
2184 RtlCopyMemory(LinkageKeyBuffer
+ ((sizeof(ClassKeyName
) + DriverKeyLength
) /
2185 sizeof(WCHAR
)) - 1, LinkageKeyName
, sizeof(LinkageKeyName
));
2187 NDIS_DbgPrint(DEBUG_MINIPORT
, ("LinkageKey: %S.\n", LinkageKeyBuffer
));
2190 * Now open the linkage key and read the "Export" and "RootDevice" values
2191 * which contains device name and root service respectively.
2194 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
2195 RtlInitUnicodeString(&ExportName
, NULL
);
2196 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
| RTL_QUERY_REGISTRY_DIRECT
;
2197 QueryTable
[0].Name
= L
"Export";
2198 QueryTable
[0].EntryContext
= &ExportName
;
2200 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
, LinkageKeyBuffer
,
2201 QueryTable
, NULL
, NULL
);
2202 ExFreePool(LinkageKeyBuffer
);
2203 if (!NT_SUCCESS(Status
))
2205 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get miniport device name. (%x)\n", Status
));
2210 * Create the device object.
2213 NDIS_DbgPrint(MAX_TRACE
, ("creating device %wZ\n", &ExportName
));
2215 Status
= IoCreateDevice(Miniport
->DriverObject
, sizeof(LOGICAL_ADAPTER
),
2216 &ExportName
, FILE_DEVICE_PHYSICAL_NETCARD
,
2217 0, FALSE
, &DeviceObject
);
2218 if (!NT_SUCCESS(Status
))
2220 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device object.\n"));
2221 RtlFreeUnicodeString(&ExportName
);
2226 * Initialize the adapter structure.
2229 Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2230 KeInitializeSpinLock(&Adapter
->NdisMiniportBlock
.Lock
);
2231 InitializeListHead(&Adapter
->ProtocolListHead
);
2232 Adapter
->NdisMiniportBlock
.DriverHandle
= Miniport
;
2234 Adapter
->NdisMiniportBlock
.MiniportName
= ExportName
;
2236 Adapter
->NdisMiniportBlock
.DeviceObject
= DeviceObject
;
2237 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
= PhysicalDeviceObject
;
2238 Adapter
->NdisMiniportBlock
.NextDeviceObject
=
2239 IoAttachDeviceToDeviceStack(Adapter
->NdisMiniportBlock
.DeviceObject
,
2240 PhysicalDeviceObject
);
2242 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= 0;
2243 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceAdded
;
2245 KeInitializeTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2246 KeInitializeDpc(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
, MiniportHangDpc
, Adapter
);
2248 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
2250 return STATUS_SUCCESS
;
2259 NdisMRegisterMiniport(
2260 IN NDIS_HANDLE NdisWrapperHandle
,
2261 IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics
,
2262 IN UINT CharacteristicsLength
)
2264 * FUNCTION: Registers a miniport's MiniportXxx entry points with the NDIS library
2266 * NdisWrapperHandle = Pointer to handle returned by NdisMInitializeWrapper
2267 * MiniportCharacteristics = Pointer to a buffer with miniport characteristics
2268 * CharacteristicsLength = Number of bytes in characteristics buffer
2270 * Status of operation
2274 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2275 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2278 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2280 switch (MiniportCharacteristics
->MajorNdisVersion
)
2283 MinSize
= sizeof(NDIS30_MINIPORT_CHARACTERISTICS
);
2287 MinSize
= sizeof(NDIS40_MINIPORT_CHARACTERISTICS
);
2291 MinSize
= sizeof(NDIS50_MINIPORT_CHARACTERISTICS
);
2295 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Bad miniport characteristics version.\n"));
2296 return NDIS_STATUS_BAD_VERSION
;
2299 if (CharacteristicsLength
< MinSize
)
2301 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Bad miniport characteristics.\n"));
2302 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2305 /* Check if mandatory MiniportXxx functions are specified */
2306 if ((!MiniportCharacteristics
->HaltHandler
) ||
2307 (!MiniportCharacteristics
->InitializeHandler
)||
2308 (!MiniportCharacteristics
->QueryInformationHandler
) ||
2309 (!MiniportCharacteristics
->ResetHandler
) ||
2310 (!MiniportCharacteristics
->SetInformationHandler
))
2312 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Bad miniport characteristics.\n"));
2313 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2316 if (MiniportCharacteristics
->MajorNdisVersion
== 0x03)
2318 if (!MiniportCharacteristics
->SendHandler
)
2320 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Bad miniport characteristics.\n"));
2321 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2324 else if (MiniportCharacteristics
->MajorNdisVersion
>= 0x04)
2327 if ((!MiniportCharacteristics
->SendHandler
) &&
2328 (!MiniportCharacteristics
->SendPacketsHandler
))
2330 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Bad miniport characteristics.\n"));
2331 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2335 /* TODO: verify NDIS5 and NDIS5.1 */
2337 RtlCopyMemory(&Miniport
->MiniportCharacteristics
, MiniportCharacteristics
, MinSize
);
2340 * NOTE: This is VERY unoptimal! Should we store the NDIS_M_DRIVER_BLOCK
2341 * structure in the driver extension or what?
2344 Status
= IoAllocateDriverObjectExtension(Miniport
->DriverObject
, (PVOID
)TAG('D','I','M','N'),
2345 sizeof(PNDIS_M_DRIVER_BLOCK
), (PVOID
*)&MiniportPtr
);
2346 if (!NT_SUCCESS(Status
))
2348 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't allocate driver object extension.\n"));
2349 return NDIS_STATUS_RESOURCES
;
2352 *MiniportPtr
= Miniport
;
2354 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
2355 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = NdisIShutdown
;
2356 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = NdisIDeviceIoControl
;
2357 Miniport
->DriverObject
->DriverExtension
->AddDevice
= NdisIAddDevice
;
2359 return NDIS_STATUS_SUCCESS
;
2366 #undef NdisMResetComplete
2370 IN NDIS_HANDLE MiniportAdapterHandle
,
2371 IN NDIS_STATUS Status
,
2372 IN BOOLEAN AddressingReset
)
2374 MiniResetComplete(MiniportAdapterHandle
, Status
, AddressingReset
);
2381 #undef NdisMSendComplete
2385 IN NDIS_HANDLE MiniportAdapterHandle
,
2386 IN PNDIS_PACKET Packet
,
2387 IN NDIS_STATUS Status
)
2389 * FUNCTION: Forwards a message to the initiating protocol saying
2390 * that a packet was handled
2392 * NdisAdapterHandle = Handle input to MiniportInitialize
2393 * Packet = Pointer to NDIS packet that was sent
2394 * Status = Status of send operation
2397 MiniSendComplete(MiniportAdapterHandle
, Packet
, Status
);
2404 #undef NdisMSendResourcesAvailable
2407 NdisMSendResourcesAvailable(
2408 IN NDIS_HANDLE MiniportAdapterHandle
)
2410 MiniSendResourcesAvailable(MiniportAdapterHandle
);
2417 #undef NdisMTransferDataComplete
2420 NdisMTransferDataComplete(
2421 IN NDIS_HANDLE MiniportAdapterHandle
,
2422 IN PNDIS_PACKET Packet
,
2423 IN NDIS_STATUS Status
,
2424 IN UINT BytesTransferred
)
2426 MiniTransferDataComplete(MiniportAdapterHandle
, Packet
, Status
, BytesTransferred
);
2433 #undef NdisMSetAttributes
2437 IN NDIS_HANDLE MiniportAdapterHandle
,
2438 IN NDIS_HANDLE MiniportAdapterContext
,
2439 IN BOOLEAN BusMaster
,
2440 IN NDIS_INTERFACE_TYPE AdapterType
)
2442 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2444 * MiniportAdapterHandle = Handle input to MiniportInitialize
2445 * MiniportAdapterContext = Pointer to context information
2446 * BusMaster = Specifies TRUE if the caller's NIC is a busmaster DMA device
2447 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2450 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2451 NdisMSetAttributesEx(MiniportAdapterHandle
, MiniportAdapterContext
, 0,
2452 BusMaster
? NDIS_ATTRIBUTE_BUS_MASTER
: 0,
2462 NdisMSetAttributesEx(
2463 IN NDIS_HANDLE MiniportAdapterHandle
,
2464 IN NDIS_HANDLE MiniportAdapterContext
,
2465 IN UINT CheckForHangTimeInSeconds OPTIONAL
,
2466 IN ULONG AttributeFlags
,
2467 IN NDIS_INTERFACE_TYPE AdapterType
)
2469 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2471 * MiniportAdapterHandle = Handle input to MiniportInitialize
2472 * MiniportAdapterContext = Pointer to context information
2473 * CheckForHangTimeInSeconds = Specifies interval in seconds at which
2474 * MiniportCheckForHang should be called
2475 * AttributeFlags = Bitmask that indicates specific attributes
2476 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2479 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(MiniportAdapterHandle
);
2481 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2483 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
= MiniportAdapterContext
;
2484 Adapter
->NdisMiniportBlock
.Flags
= AttributeFlags
;
2485 Adapter
->NdisMiniportBlock
.AdapterType
= AdapterType
;
2486 if (CheckForHangTimeInSeconds
> 0)
2487 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= CheckForHangTimeInSeconds
;
2488 if (AttributeFlags
& NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER
)
2489 NDIS_DbgPrint(MAX_TRACE
, ("Intermediate drivers not supported yet.\n"));
2499 IN ULONG MicrosecondsToSleep
)
2501 * FUNCTION: delay the thread's execution for MicrosecondsToSleep
2503 * MicrosecondsToSleep: duh...
2505 * - Because this is a blocking call, current IRQL must be < DISPATCH_LEVEL
2509 LARGE_INTEGER DueTime
;
2513 DueTime
.QuadPart
= (-1) * 10 * MicrosecondsToSleep
;
2515 KeInitializeTimer(&Timer
);
2516 KeSetTimer(&Timer
, DueTime
, 0);
2517 KeWaitForSingleObject(&Timer
, Executive
, KernelMode
, FALSE
, 0);
2526 NdisMSynchronizeWithInterrupt(
2527 IN PNDIS_MINIPORT_INTERRUPT Interrupt
,
2528 IN PVOID SynchronizeFunction
,
2529 IN PVOID SynchronizeContext
)
2531 return(KeSynchronizeExecution(Interrupt
->InterruptObject
,
2532 (PKSYNCHRONIZE_ROUTINE
)SynchronizeFunction
,
2533 SynchronizeContext
));
2543 IN NDIS_HANDLE LogHandle
,
2545 IN UINT LogBufferSize
)
2547 PUCHAR Buffer
= LogBuffer
;
2551 for (i
= 0; i
< LogBufferSize
; i
+= 16)
2553 DbgPrint("%08x |", i
);
2554 for (j
= 0; j
< 16; j
++)
2557 if (idx
< LogBufferSize
)
2558 DbgPrint(" %02x", Buffer
[idx
]);
2563 for (j
= 0; j
< 16; j
++)
2566 if (idx
== LogBufferSize
)
2568 if (Buffer
[idx
] >= ' ') /* FIXME: not portable! replace by if (isprint(Buffer[idx])) ? */
2569 DbgPrint("%c", Buffer
[idx
]);
2576 return NDIS_STATUS_FAILURE
;
2585 NdisTerminateWrapper(
2586 IN NDIS_HANDLE NdisWrapperHandle
,
2587 IN PVOID SystemSpecific
)
2589 * FUNCTION: Releases resources allocated by a call to NdisInitializeWrapper
2591 * NdisWrapperHandle = Handle returned by NdisInitializeWrapper (NDIS_M_DRIVER_BLOCK)
2592 * SystemSpecific = Always NULL
2595 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2597 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2599 ExFreePool(Miniport
->RegistryPath
->Buffer
);
2600 ExFreePool(Miniport
->RegistryPath
);
2601 ExInterlockedRemoveEntryList(&Miniport
->ListEntry
, &MiniportListLock
);
2602 ExFreePool(Miniport
);
2611 NdisMQueryAdapterInstanceName(
2612 OUT PNDIS_STRING AdapterInstanceName
,
2613 IN NDIS_HANDLE MiniportAdapterHandle
)
2621 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
2622 UNICODE_STRING AdapterName
;
2624 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2626 AdapterName
.Length
= 0;
2627 AdapterName
.MaximumLength
= Adapter
->NdisMiniportBlock
.MiniportName
.MaximumLength
;
2628 AdapterName
.Buffer
= ExAllocatePool(PagedPool
, AdapterName
.MaximumLength
);
2629 if (!AdapterName
.Buffer
)
2630 return NDIS_STATUS_RESOURCES
;
2632 RtlCopyUnicodeString(&AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
);
2634 *AdapterInstanceName
= AdapterName
;
2636 return NDIS_STATUS_SUCCESS
;
2644 NdisDeregisterAdapterShutdownHandler(
2645 IN NDIS_HANDLE NdisAdapterHandle
)
2653 NdisMDeregisterAdapterShutdownHandler(NdisAdapterHandle
);
2662 NdisRegisterAdapterShutdownHandler(
2663 IN NDIS_HANDLE NdisAdapterHandle
,
2664 IN PVOID ShutdownContext
,
2665 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
2673 NdisMRegisterAdapterShutdownHandler(NdisAdapterHandle
,
2683 NdisMGetDeviceProperty(
2684 IN NDIS_HANDLE MiniportAdapterHandle
,
2685 IN OUT PDEVICE_OBJECT
*PhysicalDeviceObject OPTIONAL
,
2686 IN OUT PDEVICE_OBJECT
*FunctionalDeviceObject OPTIONAL
,
2687 IN OUT PDEVICE_OBJECT
*NextDeviceObject OPTIONAL
,
2688 IN OUT PCM_RESOURCE_LIST
*AllocatedResources OPTIONAL
,
2689 IN OUT PCM_RESOURCE_LIST
*AllocatedResourcesTranslated OPTIONAL
)
2697 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
2699 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2701 if (PhysicalDeviceObject
!= NULL
)
2702 *PhysicalDeviceObject
= Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
;
2704 if (FunctionalDeviceObject
!= NULL
)
2705 *FunctionalDeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
2707 if (NextDeviceObject
!= NULL
)
2708 *NextDeviceObject
= Adapter
->NdisMiniportBlock
.NextDeviceObject
;
2710 if (AllocatedResources
!= NULL
)
2711 *AllocatedResources
= Adapter
->NdisMiniportBlock
.AllocatedResources
;
2713 if (AllocatedResourcesTranslated
!= NULL
)
2714 *AllocatedResourcesTranslated
= Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
;
2722 NdisMRegisterUnloadHandler(
2723 IN NDIS_HANDLE NdisWrapperHandle
,
2724 IN PDRIVER_UNLOAD UnloadHandler
)
2732 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2734 NDIS_DbgPrint(MAX_TRACE
, ("Miniport registered unload handler\n"));
2736 DriverBlock
->DriverObject
->DriverUnload
= UnloadHandler
;
2744 NdisMRegisterDevice(
2745 IN NDIS_HANDLE NdisWrapperHandle
,
2746 IN PNDIS_STRING DeviceName
,
2747 IN PNDIS_STRING SymbolicName
,
2748 IN PDRIVER_DISPATCH MajorFunctions
[],
2749 OUT PDEVICE_OBJECT
*pDeviceObject
,
2750 OUT NDIS_HANDLE
*NdisDeviceHandle
)
2758 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2759 PNDIS_M_DEVICE_BLOCK DeviceBlock
;
2760 PDEVICE_OBJECT DeviceObject
;
2764 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2766 Status
= IoCreateDevice(DriverBlock
->DriverObject
,
2767 0, /* This space is reserved for us. Should we use it? */
2769 FILE_DEVICE_NETWORK
,
2774 if (!NT_SUCCESS(Status
))
2779 Status
= IoCreateSymbolicLink(SymbolicName
, DeviceName
);
2781 if (!NT_SUCCESS(Status
))
2783 IoDeleteDevice(DeviceObject
);
2787 DeviceBlock
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DEVICE_BLOCK
));
2791 IoDeleteDevice(DeviceObject
);
2792 IoDeleteSymbolicLink(SymbolicName
);
2793 return NDIS_STATUS_RESOURCES
;
2796 for (i
= 0; i
< IRP_MJ_MAXIMUM_FUNCTION
; i
++)
2797 DriverBlock
->DriverObject
->MajorFunction
[i
] = MajorFunctions
[i
];
2799 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
2800 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = NdisIShutdown
;
2801 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = NdisIDeviceIoControl
;
2803 DeviceBlock
->DeviceObject
= DeviceObject
;
2804 DeviceBlock
->SymbolicName
= SymbolicName
;
2806 *pDeviceObject
= DeviceObject
;
2807 *NdisDeviceHandle
= DeviceBlock
;
2809 return NDIS_STATUS_SUCCESS
;
2817 NdisMDeregisterDevice(
2818 IN NDIS_HANDLE NdisDeviceHandle
)
2826 PNDIS_M_DEVICE_BLOCK DeviceBlock
= NdisDeviceHandle
;
2828 IoDeleteDevice(DeviceBlock
->DeviceObject
);
2830 IoDeleteSymbolicLink(DeviceBlock
->SymbolicName
);
2832 ExFreePool(DeviceBlock
);
2834 return NDIS_STATUS_SUCCESS
;
2842 NdisQueryAdapterInstanceName(
2843 OUT PNDIS_STRING AdapterInstanceName
,
2844 IN NDIS_HANDLE NdisBindingHandle
)
2852 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
2853 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
2855 return NdisMQueryAdapterInstanceName(AdapterInstanceName
,
2864 NdisCompletePnPEvent(
2865 IN NDIS_STATUS Status
,
2866 IN NDIS_HANDLE NdisBindingHandle
,
2867 IN PNET_PNP_EVENT NetPnPEvent
)
2875 PIRP Irp
= (PIRP
)NetPnPEvent
->NdisReserved
[0];
2876 PLIST_ENTRY CurrentEntry
= (PLIST_ENTRY
)NetPnPEvent
->NdisReserved
[1];
2877 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
2878 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
2879 NDIS_STATUS NdisStatus
;
2881 if (Status
!= NDIS_STATUS_SUCCESS
)
2883 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
2884 ExFreePool(NetPnPEvent
);
2885 Irp
->IoStatus
.Status
= Status
;
2886 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2890 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
2892 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
2894 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.PnPEventHandler
)(
2895 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
2898 if (NdisStatus
== NDIS_STATUS_PENDING
)
2900 NetPnPEvent
->NdisReserved
[1] = (ULONG_PTR
)CurrentEntry
->Flink
;
2903 else if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2905 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
2906 ExFreePool(NetPnPEvent
);
2907 Irp
->IoStatus
.Status
= NdisStatus
;
2908 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2912 CurrentEntry
= CurrentEntry
->Flink
;
2915 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
2916 ExFreePool(NetPnPEvent
);
2918 Irp
->IoStatus
.Status
= NDIS_STATUS_SUCCESS
;
2919 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);