2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS library
4 * FILE: ndis/protocol.c
5 * PURPOSE: Routines used by NDIS protocol drivers
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Vizzini (vizzini@plasmic.com)
9 * CSH 01/08-2000 Created
10 * 09-13-2003 Vizzini Updates for SendPackets support
15 #define SERVICES_KEY L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
16 #define LINKAGE_KEY L"\\Linkage"
17 #define PARAMETERS_KEY L"\\Parameters\\"
19 LIST_ENTRY ProtocolListHead
;
20 KSPIN_LOCK ProtocolListLock
;
24 typedef struct _DMA_CONTEXT
{
25 PLOGICAL_ADAPTER Adapter
;
27 } DMA_CONTEXT
, *PDMA_CONTEXT
;
31 NET_PNP_EVENT_CODE EventCode
,
33 ULONG EventBufferLength
)
35 PNET_PNP_EVENT PnPEvent
;
37 PnPEvent
= ExAllocatePool(PagedPool
, sizeof(NET_PNP_EVENT
));
39 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
43 RtlZeroMemory(PnPEvent
, sizeof(NET_PNP_EVENT
));
45 PnPEvent
->NetEvent
= EventCode
;
47 if (EventBuffer
!= NULL
)
49 PnPEvent
->Buffer
= ExAllocatePool(PagedPool
, EventBufferLength
);
50 if (!PnPEvent
->Buffer
)
52 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
57 PnPEvent
->BufferLength
= EventBufferLength
;
59 RtlCopyMemory(PnPEvent
->Buffer
, EventBuffer
, PnPEvent
->BufferLength
);
66 ProSendAndFreePnPEvent(
67 PLOGICAL_ADAPTER Adapter
,
68 PNET_PNP_EVENT PnPEvent
,
71 PLIST_ENTRY CurrentEntry
;
73 PADAPTER_BINDING AdapterBinding
;
75 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
77 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
79 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
81 Status
= (*AdapterBinding
->ProtocolBinding
->Chars
.PnPEventHandler
)(
82 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
85 if (Status
== NDIS_STATUS_PENDING
)
87 IoMarkIrpPending(Irp
);
88 /* Yes, I know this is stupid */
89 PnPEvent
->NdisReserved
[0] = (ULONG_PTR
)Irp
;
90 PnPEvent
->NdisReserved
[1] = (ULONG_PTR
)CurrentEntry
->Flink
;
91 return NDIS_STATUS_PENDING
;
93 else if (Status
!= NDIS_STATUS_SUCCESS
)
95 if (PnPEvent
->Buffer
) ExFreePool(PnPEvent
->Buffer
);
100 CurrentEntry
= CurrentEntry
->Flink
;
103 if (PnPEvent
->Buffer
) ExFreePool(PnPEvent
->Buffer
);
104 ExFreePool(PnPEvent
);
106 return NDIS_STATUS_SUCCESS
;
112 IN PDEVICE_OBJECT DeviceObject
,
115 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
116 PNET_PNP_EVENT PnPEvent
;
117 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
119 ASSERT(Stack
->Parameters
.Power
.Type
== DevicePowerState
);
121 PnPEvent
= ProSetupPnPEvent(NetEventSetPower
, &Stack
->Parameters
.Power
.State
, sizeof(NDIS_DEVICE_POWER_STATE
));
123 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
124 return NDIS_STATUS_RESOURCES
;
127 return ProSendAndFreePnPEvent(Adapter
, PnPEvent
, Irp
);
133 IN PDEVICE_OBJECT DeviceObject
,
136 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
137 PNET_PNP_EVENT PnPEvent
;
138 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
140 ASSERT(Stack
->Parameters
.Power
.Type
== DevicePowerState
);
142 PnPEvent
= ProSetupPnPEvent(NetEventQueryPower
, &Stack
->Parameters
.Power
.State
, sizeof(NDIS_DEVICE_POWER_STATE
));
144 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
145 return NDIS_STATUS_RESOURCES
;
148 return ProSendAndFreePnPEvent(Adapter
, PnPEvent
, Irp
);
154 NdisIPnPQueryStopDevice(
155 IN PDEVICE_OBJECT DeviceObject
,
158 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
159 PNET_PNP_EVENT PnPEvent
;
161 PnPEvent
= ProSetupPnPEvent(NetEventQueryRemoveDevice
, NULL
, 0);
163 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
164 return NDIS_STATUS_RESOURCES
;
167 return ProSendAndFreePnPEvent(Adapter
, PnPEvent
, Irp
);
172 NdisIPnPCancelStopDevice(
173 IN PDEVICE_OBJECT DeviceObject
,
176 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
177 PNET_PNP_EVENT PnPEvent
;
179 PnPEvent
= ProSetupPnPEvent(NetEventCancelRemoveDevice
, NULL
, 0);
181 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
182 return NDIS_STATUS_RESOURCES
;
185 return ProSendAndFreePnPEvent(Adapter
, PnPEvent
, Irp
);
193 NdisCompleteBindAdapter(
194 IN NDIS_HANDLE BindAdapterContext
,
195 IN NDIS_STATUS Status
,
196 IN NDIS_STATUS OpenStatus
)
198 * FUNCTION: Indicates a packet to bound protocols
200 * Adapter = Pointer to logical adapter
201 * Packet = Pointer to packet to indicate
203 * Status of operation
205 * - FIXME: partially-implemented
208 PROTOCOL_BINDING
*Protocol
= (PROTOCOL_BINDING
*)BindAdapterContext
;
210 if (!NT_SUCCESS(Status
)) {
211 NDIS_DbgPrint(MIN_TRACE
, ("Binding failed (%x)\n", Status
));
215 /* Put protocol binding struct on global list */
216 ExInterlockedInsertTailList(&ProtocolListHead
, &Protocol
->ListEntry
, &ProtocolListLock
);
224 NdisCompleteUnbindAdapter(
225 IN NDIS_HANDLE UnbindAdapterContext
,
226 IN NDIS_STATUS Status
)
228 /* We probably need to do more here but for now we just do
229 * the opposite of what NdisCompleteBindAdapter does
232 PROTOCOL_BINDING
*Protocol
= (PROTOCOL_BINDING
*)UnbindAdapterContext
;
234 if (!NT_SUCCESS(Status
)) {
235 NDIS_DbgPrint(MIN_TRACE
, ("Unbinding failed (%x)\n", Status
));
239 ExInterlockedRemoveEntryList(&Protocol
->ListEntry
, &ProtocolListLock
);
244 PLOGICAL_ADAPTER Adapter
,
247 * FUNCTION: Indicates a packet to bound protocols
249 * Adapter = Pointer to logical adapter
250 * Packet = Pointer to packet to indicate
252 * STATUS_SUCCESS in all cases
254 * - XXX ATM, this only handles loopback packets - is that its designed function?
260 PUCHAR LookaheadBuffer
;
262 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
265 MiniDisplayPacket(Packet
);
268 NdisQueryPacket(Packet
, NULL
, NULL
, NULL
, &PacketLength
);
270 LookaheadBuffer
= ExAllocatePool(NonPagedPool
, PacketLength
);
271 if (!LookaheadBuffer
) {
272 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
273 return NDIS_STATUS_RESOURCES
;
276 NDIS_DbgPrint(MAX_TRACE
, ("acquiring miniport block lock\n"));
277 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
279 BufferedLength
= CopyPacketToBuffer(LookaheadBuffer
, Packet
, 0, PacketLength
);
280 Adapter
->NdisMiniportBlock
.IndicatedPacket
[KeGetCurrentProcessorNumber()] = Packet
;
282 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
284 if (BufferedLength
> Adapter
->MediumHeaderSize
)
286 /* XXX Change this to call SendPackets so we don't have to duplicate this wacky logic */
287 MiniIndicateData(Adapter
, NULL
, LookaheadBuffer
, Adapter
->MediumHeaderSize
,
288 &LookaheadBuffer
[Adapter
->MediumHeaderSize
], BufferedLength
- Adapter
->MediumHeaderSize
,
289 PacketLength
- Adapter
->MediumHeaderSize
);
293 MiniIndicateData(Adapter
, NULL
, LookaheadBuffer
, Adapter
->MediumHeaderSize
, NULL
, 0, 0);
296 ExFreePool(LookaheadBuffer
);
298 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
300 Adapter
->NdisMiniportBlock
.IndicatedPacket
[KeGetCurrentProcessorNumber()] = NULL
;
302 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
304 return NDIS_STATUS_SUCCESS
;
309 IN NDIS_HANDLE MacBindingHandle
,
310 IN PNDIS_REQUEST NdisRequest
)
312 * FUNCTION: Forwards a request to an NDIS miniport
314 * MacBindingHandle = Adapter binding handle
315 * NdisRequest = Pointer to request to perform
317 * Status of operation
320 PADAPTER_BINDING AdapterBinding
;
321 PLOGICAL_ADAPTER Adapter
;
322 PNDIS_REQUEST_MAC_BLOCK MacBlock
= (PNDIS_REQUEST_MAC_BLOCK
)NdisRequest
->MacReserved
;
324 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
326 ASSERT(MacBindingHandle
);
327 AdapterBinding
= GET_ADAPTER_BINDING(MacBindingHandle
);
329 ASSERT(AdapterBinding
->Adapter
);
330 Adapter
= AdapterBinding
->Adapter
;
332 MacBlock
->Binding
= &AdapterBinding
->NdisOpenBlock
;
335 MiniQueueWorkItem(Adapter
, NdisWorkItemRequest
, NdisRequest
, FALSE
);
336 return NDIS_STATUS_PENDING
;
338 if (MiniIsBusy(Adapter
, NdisWorkItemRequest
)) {
339 MiniQueueWorkItem(Adapter
, NdisWorkItemRequest
, NdisRequest
, FALSE
);
340 return NDIS_STATUS_PENDING
;
343 return MiniDoRequest(Adapter
, NdisRequest
);
350 IN NDIS_HANDLE MacBindingHandle
)
352 PADAPTER_BINDING AdapterBinding
= MacBindingHandle
;
354 /* FIXME: Wait for all packets to be sent */
356 return MiniReset(AdapterBinding
->Adapter
);
360 ScatterGatherSendPacket(
361 IN PDEVICE_OBJECT DeviceObject
,
363 IN PSCATTER_GATHER_LIST ScatterGather
,
366 PDMA_CONTEXT DmaContext
= Context
;
367 PLOGICAL_ADAPTER Adapter
= DmaContext
->Adapter
;
368 PNDIS_PACKET Packet
= DmaContext
->Packet
;
371 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
373 NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
374 ScatterGatherListPacketInfo
) = ScatterGather
;
376 Status
= proSendPacketToMiniport(Adapter
, Packet
);
378 if (Status
!= NDIS_STATUS_PENDING
) {
379 NDIS_DbgPrint(MAX_TRACE
, ("Completing packet.\n"));
380 MiniSendComplete(Adapter
,
385 ExFreePool(DmaContext
);
389 proSendPacketToMiniport(PLOGICAL_ADAPTER Adapter
, PNDIS_PACKET Packet
)
392 MiniQueueWorkItem(Adapter
, NdisWorkItemSend
, Packet
, FALSE
);
393 return NDIS_STATUS_PENDING
;
396 NDIS_STATUS NdisStatus
;
398 if(MiniIsBusy(Adapter
, NdisWorkItemSend
)) {
399 MiniQueueWorkItem(Adapter
, NdisWorkItemSend
, Packet
, FALSE
);
400 return NDIS_STATUS_PENDING
;
403 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
405 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
407 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
408 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
409 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, &Packet
, 1);
410 NdisStatus
= NDIS_STATUS_PENDING
;
412 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
413 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
415 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
416 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
417 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, &Packet
, 1);
419 KeLowerIrql(RaiseOldIrql
);
421 NdisStatus
= NDIS_GET_PACKET_STATUS(Packet
);
422 if (NdisStatus
== NDIS_STATUS_RESOURCES
) {
423 MiniQueueWorkItem(Adapter
, NdisWorkItemSend
, Packet
, TRUE
);
424 NdisStatus
= NDIS_STATUS_PENDING
;
428 if (NdisStatus
!= NDIS_STATUS_PENDING
) {
429 MiniWorkItemComplete(Adapter
, NdisWorkItemSend
);
434 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
436 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
437 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
438 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, Packet
, Packet
->Private
.Flags
);
439 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
441 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
442 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
443 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
444 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
445 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, Packet
, Packet
->Private
.Flags
);
446 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
447 KeLowerIrql(RaiseOldIrql
);
449 if (NdisStatus
== NDIS_STATUS_RESOURCES
) {
450 MiniQueueWorkItem(Adapter
, NdisWorkItemSend
, Packet
, TRUE
);
451 NdisStatus
= NDIS_STATUS_PENDING
;
455 if (NdisStatus
!= NDIS_STATUS_PENDING
) {
456 MiniWorkItemComplete(Adapter
, NdisWorkItemSend
);
466 IN NDIS_HANDLE MacBindingHandle
,
467 IN PNDIS_PACKET Packet
)
469 * FUNCTION: Forwards a request to send a packet to an NDIS miniport
471 * MacBindingHandle = Adapter binding handle
472 * Packet = Pointer to NDIS packet descriptor
474 * NDIS_STATUS_SUCCESS if the packet was successfully sent
475 * NDIS_STATUS_PENDING if the miniport was busy or a serialized miniport returned NDIS_STATUS_RESOURCES
478 PADAPTER_BINDING AdapterBinding
;
479 PLOGICAL_ADAPTER Adapter
;
480 PNDIS_BUFFER NdisBuffer
;
481 PDMA_CONTEXT Context
;
482 NDIS_STATUS NdisStatus
;
486 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
488 ASSERT(MacBindingHandle
);
489 AdapterBinding
= GET_ADAPTER_BINDING(MacBindingHandle
);
491 ASSERT(AdapterBinding
);
492 Adapter
= AdapterBinding
->Adapter
;
496 /* if the following is not true, KeRaiseIrql() below will break */
497 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL
);
499 /* XXX what is this crazy black magic? */
500 Packet
->Reserved
[1] = (ULONG_PTR
)MacBindingHandle
;
503 * Test the packet to see if it is a MAC loopback.
505 * We may have to loop this packet if miniport cannot.
506 * If dest MAC address of packet == MAC address of adapter,
507 * this is a loopback frame.
510 if ((Adapter
->NdisMiniportBlock
.MacOptions
& NDIS_MAC_OPTION_NO_LOOPBACK
) &&
511 MiniAdapterHasAddress(Adapter
, Packet
))
514 MiniQueueWorkItem(Adapter
, NdisWorkItemSendLoopback
, Packet
, FALSE
);
515 return NDIS_STATUS_PENDING
;
517 return ProIndicatePacket(Adapter
, Packet
);
520 if (Adapter
->NdisMiniportBlock
.ScatterGatherListSize
!= 0)
522 NDIS_DbgPrint(MID_TRACE
, ("Using Scatter/Gather DMA\n"));
524 NdisQueryPacket(Packet
,
530 Context
= ExAllocatePool(NonPagedPool
, sizeof(DMA_CONTEXT
));
532 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
533 return NDIS_STATUS_RESOURCES
;
536 Context
->Adapter
= Adapter
;
537 Context
->Packet
= Packet
;
539 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
541 KeFlushIoBuffers(NdisBuffer
, FALSE
, TRUE
);
543 NdisStatus
= Adapter
->NdisMiniportBlock
.SystemAdapterObject
->DmaOperations
->GetScatterGatherList(
544 Adapter
->NdisMiniportBlock
.SystemAdapterObject
,
545 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
547 MmGetMdlVirtualAddress(NdisBuffer
),
549 ScatterGatherSendPacket
,
553 KeLowerIrql(OldIrql
);
555 if (!NT_SUCCESS(NdisStatus
)) {
556 NDIS_DbgPrint(MIN_TRACE
, ("GetScatterGatherList failed! (%x)\n", NdisStatus
));
560 return NDIS_STATUS_PENDING
;
564 return proSendPacketToMiniport(Adapter
, Packet
);
570 IN NDIS_HANDLE NdisBindingHandle
,
571 IN PPNDIS_PACKET PacketArray
,
572 IN UINT NumberOfPackets
)
574 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
575 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
577 NDIS_STATUS NdisStatus
;
580 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
582 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
584 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
585 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, PacketArray
, NumberOfPackets
);
589 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
590 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
591 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
592 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, PacketArray
, NumberOfPackets
);
593 KeLowerIrql(RaiseOldIrql
);
594 for (i
= 0; i
< NumberOfPackets
; i
++)
596 NdisStatus
= NDIS_GET_PACKET_STATUS(PacketArray
[i
]);
597 if (NdisStatus
!= NDIS_STATUS_PENDING
)
598 MiniSendComplete(Adapter
, PacketArray
[i
], NdisStatus
);
604 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
606 for (i
= 0; i
< NumberOfPackets
; i
++)
608 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
609 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, PacketArray
[i
], PacketArray
[i
]->Private
.Flags
);
610 if (NdisStatus
!= NDIS_STATUS_PENDING
)
611 MiniSendComplete(Adapter
, PacketArray
[i
], NdisStatus
);
616 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
617 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
618 for (i
= 0; i
< NumberOfPackets
; i
++)
620 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
621 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, PacketArray
[i
], PacketArray
[i
]->Private
.Flags
);
622 if (NdisStatus
!= NDIS_STATUS_PENDING
)
623 MiniSendComplete(Adapter
, PacketArray
[i
], NdisStatus
);
625 KeLowerIrql(RaiseOldIrql
);
632 IN NDIS_HANDLE MacBindingHandle
,
633 IN NDIS_HANDLE MacReceiveContext
,
635 IN UINT BytesToTransfer
,
636 IN OUT PNDIS_PACKET Packet
,
637 OUT PUINT BytesTransferred
)
639 * FUNCTION: Forwards a request to copy received data into a protocol-supplied packet
641 * MacBindingHandle = Adapter binding handle
642 * MacReceiveContext = MAC receive context
643 * ByteOffset = Offset in packet to place data
644 * BytesToTransfer = Number of bytes to copy into packet
645 * Packet = Pointer to NDIS packet descriptor
646 * BytesTransferred = Address of buffer to place number of bytes copied
649 PADAPTER_BINDING AdapterBinding
= GET_ADAPTER_BINDING(MacBindingHandle
);
650 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
654 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
656 /* FIXME: Interrupts must be disabled for adapter */
657 /* XXX sd - why is that true? */
659 if (Adapter
->NdisMiniportBlock
.IndicatedPacket
[KeGetCurrentProcessorNumber()]) {
660 NDIS_DbgPrint(MAX_TRACE
, ("LoopPacket\n"));
661 /* NDIS is responsible for looping this packet */
662 NdisCopyFromPacketToPacket(Packet
,
663 ByteOffset
+ Adapter
->MediumHeaderSize
,
664 BytesToTransfer
+ Adapter
->MediumHeaderSize
,
665 Adapter
->NdisMiniportBlock
.IndicatedPacket
[KeGetCurrentProcessorNumber()],
668 return NDIS_STATUS_SUCCESS
;
671 ASSERT(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.TransferDataHandler
);
673 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
675 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.TransferDataHandler
)(
678 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
683 KeLowerIrql(OldIrql
);
696 OUT PNDIS_STATUS Status
,
697 IN NDIS_HANDLE NdisBindingHandle
)
699 * FUNCTION: Closes an adapter opened with NdisOpenAdapter
701 * Status = Address of buffer for status information
702 * NdisBindingHandle = Handle returned by NdisOpenAdapter
705 PADAPTER_BINDING AdapterBinding
= GET_ADAPTER_BINDING(NdisBindingHandle
);
707 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
709 /* Remove from protocol's bound adapters list */
710 ExInterlockedRemoveEntryList(&AdapterBinding
->ProtocolListEntry
, &AdapterBinding
->ProtocolBinding
->Lock
);
712 /* Remove protocol from adapter's bound protocols list */
713 ExInterlockedRemoveEntryList(&AdapterBinding
->AdapterListEntry
, &AdapterBinding
->Adapter
->NdisMiniportBlock
.Lock
);
715 ExFreePool(AdapterBinding
);
717 *Status
= NDIS_STATUS_SUCCESS
;
726 NdisDeregisterProtocol(
727 OUT PNDIS_STATUS Status
,
728 IN NDIS_HANDLE NdisProtocolHandle
)
730 * FUNCTION: Releases the resources allocated by NdisRegisterProtocol
732 * Status = Address of buffer for status information
733 * NdisProtocolHandle = Handle returned by NdisRegisterProtocol
736 PPROTOCOL_BINDING Protocol
= GET_PROTOCOL_BINDING(NdisProtocolHandle
);
738 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
740 /* FIXME: Make sure no adapter bindings exist */
742 /* Remove protocol from global list */
743 ExInterlockedRemoveEntryList(&Protocol
->ListEntry
, &ProtocolListLock
);
745 ExFreePool(Protocol
);
747 *Status
= NDIS_STATUS_SUCCESS
;
757 OUT PNDIS_STATUS Status
,
758 OUT PNDIS_STATUS OpenErrorStatus
,
759 OUT PNDIS_HANDLE NdisBindingHandle
,
760 OUT PUINT SelectedMediumIndex
,
761 IN PNDIS_MEDIUM MediumArray
,
762 IN UINT MediumArraySize
,
763 IN NDIS_HANDLE NdisProtocolHandle
,
764 IN NDIS_HANDLE ProtocolBindingContext
,
765 IN PNDIS_STRING AdapterName
,
767 IN PSTRING AddressingInformation OPTIONAL
)
769 * FUNCTION: Opens an adapter for communication
771 * Status = Address of buffer for status information
772 * OpenErrorStatus = Address of buffer for secondary error code
773 * NdisBindingHandle = Address of buffer for adapter binding handle
774 * SelectedMediumIndex = Address of buffer for selected medium
775 * MediumArray = Pointer to an array of NDIS_MEDIUMs called can support
776 * MediumArraySize = Number of elements in MediumArray
777 * NdisProtocolHandle = Handle returned by NdisRegisterProtocol
778 * ProtocolBindingContext = Pointer to caller suplied context area
779 * AdapterName = Pointer to buffer with name of adapter
780 * OpenOptions = Bitmask with flags passed to next-lower driver
781 * AddressingInformation = Optional pointer to buffer with NIC specific information
786 PLOGICAL_ADAPTER Adapter
;
787 PADAPTER_BINDING AdapterBinding
;
788 PPROTOCOL_BINDING Protocol
= GET_PROTOCOL_BINDING(NdisProtocolHandle
);
790 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
792 if(!NdisProtocolHandle
)
794 NDIS_DbgPrint(MIN_TRACE
, ("NdisProtocolHandle is NULL\n"));
795 *OpenErrorStatus
= *Status
= NDIS_STATUS_FAILURE
;
799 Adapter
= MiniLocateDevice(AdapterName
);
802 NDIS_DbgPrint(MIN_TRACE
, ("Adapter not found.\n"));
803 *Status
= NDIS_STATUS_ADAPTER_NOT_FOUND
;
807 /* Find the media type in the list provided by the protocol driver */
809 for (i
= 0; i
< MediumArraySize
; i
++)
811 if (Adapter
->NdisMiniportBlock
.MediaType
== MediumArray
[i
])
813 *SelectedMediumIndex
= i
;
821 NDIS_DbgPrint(MIN_TRACE
, ("Medium is not supported.\n"));
822 *Status
= NDIS_STATUS_UNSUPPORTED_MEDIA
;
826 /* Now that we have confirmed that the adapter can be opened, create a binding */
828 AdapterBinding
= ExAllocatePool(NonPagedPool
, sizeof(ADAPTER_BINDING
));
831 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
832 *Status
= NDIS_STATUS_RESOURCES
;
836 RtlZeroMemory(AdapterBinding
, sizeof(ADAPTER_BINDING
));
838 AdapterBinding
->ProtocolBinding
= Protocol
;
839 AdapterBinding
->Adapter
= Adapter
;
840 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
= ProtocolBindingContext
;
842 /* Set fields required by some NDIS macros */
843 AdapterBinding
->NdisOpenBlock
.BindingHandle
= (NDIS_HANDLE
)AdapterBinding
;
845 /* Set handlers (some NDIS macros require these) */
847 AdapterBinding
->NdisOpenBlock
.RequestHandler
= ProRequest
;
848 AdapterBinding
->NdisOpenBlock
.ResetHandler
= ProReset
;
849 AdapterBinding
->NdisOpenBlock
.SendHandler
= ProSend
;
850 AdapterBinding
->NdisOpenBlock
.SendPacketsHandler
= ProSendPackets
;
851 AdapterBinding
->NdisOpenBlock
.TransferDataHandler
= ProTransferData
;
853 AdapterBinding
->NdisOpenBlock
.RequestCompleteHandler
=
854 Protocol
->Chars
.RequestCompleteHandler
;
856 /* Put on protocol's bound adapters list */
857 ExInterlockedInsertTailList(&Protocol
->AdapterListHead
, &AdapterBinding
->ProtocolListEntry
, &Protocol
->Lock
);
859 /* Put protocol on adapter's bound protocols list */
860 NDIS_DbgPrint(MAX_TRACE
, ("acquiring miniport block lock\n"));
861 ExInterlockedInsertTailList(&Adapter
->ProtocolListHead
, &AdapterBinding
->AdapterListEntry
, &Adapter
->NdisMiniportBlock
.Lock
);
863 *NdisBindingHandle
= (NDIS_HANDLE
)AdapterBinding
;
865 *Status
= NDIS_STATUS_SUCCESS
;
870 LocateAdapterBindingByName(IN PPROTOCOL_BINDING ProtocolBinding
, IN PNDIS_STRING AdapterName
)
872 PLIST_ENTRY CurrentEntry
;
873 PADAPTER_BINDING AdapterBinding
;
876 KeAcquireSpinLock(&ProtocolBinding
->Lock
, &OldIrql
);
878 CurrentEntry
= ProtocolBinding
->AdapterListHead
.Flink
;
880 while (CurrentEntry
!= &ProtocolBinding
->AdapterListHead
)
882 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, ProtocolListEntry
);
884 if (RtlCompareUnicodeString(AdapterName
, &AdapterBinding
->Adapter
->NdisMiniportBlock
.MiniportName
, TRUE
) == 0)
886 KeReleaseSpinLock(&ProtocolBinding
->Lock
, OldIrql
);
887 return AdapterBinding
;
890 CurrentEntry
= CurrentEntry
->Flink
;
893 KeReleaseSpinLock(&ProtocolBinding
->Lock
, OldIrql
);
900 ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status
, IN PPROTOCOL_BINDING Protocol
)
903 * bind the protocol to all of its miniports
906 * get list of devices from Bind key
907 * call BindAdapterHandler for each
909 OBJECT_ATTRIBUTES ObjectAttributes
;
910 UNICODE_STRING RegistryPath
;
911 WCHAR
*RegistryPathStr
, *DataPtr
= NULL
;
913 HANDLE DriverKeyHandle
= NULL
;
914 PKEY_VALUE_PARTIAL_INFORMATION KeyInformation
= NULL
;
915 PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics
= &Protocol
->Chars
;
916 UNICODE_STRING ValueName
;
918 PLIST_ENTRY CurrentEntry
= NULL
;
920 RegistryPathStr
= ExAllocatePoolWithTag(PagedPool
, sizeof(SERVICES_KEY
) + ProtocolCharacteristics
->Name
.Length
+ sizeof(LINKAGE_KEY
), NDIS_TAG
+ __LINE__
);
923 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
924 *Status
= NDIS_STATUS_RESOURCES
;
928 wcscpy(RegistryPathStr
, SERVICES_KEY
);
929 wcsncat(RegistryPathStr
, ((WCHAR
*)ProtocolCharacteristics
->Name
.Buffer
), ProtocolCharacteristics
->Name
.Length
/ sizeof(WCHAR
));
930 RegistryPathStr
[wcslen(SERVICES_KEY
)+ProtocolCharacteristics
->Name
.Length
/sizeof(WCHAR
)] = 0;
931 wcscat(RegistryPathStr
, LINKAGE_KEY
);
933 RtlInitUnicodeString(&RegistryPath
, RegistryPathStr
);
934 NDIS_DbgPrint(MAX_TRACE
, ("Opening configuration key: %wZ\n", &RegistryPath
));
936 InitializeObjectAttributes(&ObjectAttributes
, &RegistryPath
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
937 NtStatus
= ZwOpenKey(&DriverKeyHandle
, KEY_READ
, &ObjectAttributes
);
939 ExFreePool(RegistryPathStr
);
941 if(NT_SUCCESS(NtStatus
))
943 NDIS_DbgPrint(MAX_TRACE
, ("Successfully opened the registry configuration\n"));
945 RtlInitUnicodeString(&ValueName
, L
"Bind");
947 NtStatus
= ZwQueryValueKey(DriverKeyHandle
, &ValueName
, KeyValuePartialInformation
, NULL
, 0, &ResultLength
);
948 if(NtStatus
!= STATUS_BUFFER_OVERFLOW
&& NtStatus
!= STATUS_BUFFER_TOO_SMALL
&& NtStatus
!= STATUS_SUCCESS
)
950 NDIS_DbgPrint(MIN_TRACE
, ("Unable to query the Bind value for size\n"));
951 ZwClose(DriverKeyHandle
);
955 KeyInformation
= ExAllocatePoolWithTag(PagedPool
, sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + ResultLength
, NDIS_TAG
+ __LINE__
);
958 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
959 ZwClose(DriverKeyHandle
);
960 NtStatus
= STATUS_NO_MEMORY
;
964 NtStatus
= ZwQueryValueKey(DriverKeyHandle
, &ValueName
, KeyValuePartialInformation
, KeyInformation
,
965 sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + ResultLength
, &ResultLength
);
967 ZwClose(DriverKeyHandle
);
969 if(!NT_SUCCESS(NtStatus
))
971 NDIS_DbgPrint(MIN_TRACE
, ("Unable to query the Bind value\n"));
972 ExFreePool(KeyInformation
);
973 KeyInformation
= NULL
;
979 if (!NT_SUCCESS(NtStatus
))
981 NDIS_DbgPrint(MIN_TRACE
, ("Performing global bind for protocol '%wZ'\n", &ProtocolCharacteristics
->Name
));
982 KeyInformation
= NULL
;
984 CurrentEntry
= AdapterListHead
.Flink
;
988 NDIS_DbgPrint(MIN_TRACE
, ("Performing standard bind for protocol '%wZ'\n", &ProtocolCharacteristics
->Name
));
990 DataPtr
= (WCHAR
*)KeyInformation
->Data
;
993 /* Assume success for now */
994 *Status
= NDIS_STATUS_SUCCESS
;
998 /* BindContext is for tracking pending binding operations */
999 VOID
*BindContext
= 0;
1000 NDIS_STRING DeviceName
;
1001 NDIS_STRING RegistryPath
;
1002 WCHAR
*RegistryPathStr
= NULL
;
1003 ULONG PathLength
= 0;
1004 PLOGICAL_ADAPTER Adapter
;
1008 /* Parse the REG_MULTI_SZ entry for device names */
1012 RtlInitUnicodeString(&DeviceName
, DataPtr
);
1016 /* Use the device name from the global adapter list */
1017 if (CurrentEntry
== &AdapterListHead
)
1020 Adapter
= CONTAINING_RECORD(CurrentEntry
, LOGICAL_ADAPTER
, ListEntry
);
1022 DeviceName
= Adapter
->NdisMiniportBlock
.MiniportName
;
1025 /* Make sure the adapter has started */
1026 if (!MiniLocateDevice(&DeviceName
))
1028 /* It wasn't in the global miniport list, so skip the bind entry */
1032 /* Make sure this device isn't already bound to this protocol */
1033 if (LocateAdapterBindingByName(Protocol
, &DeviceName
))
1035 /* It was already in this protocol's bound adapter list, so skip the bind entry */
1040 * RegistryPath should be:
1041 * \Registry\Machine\System\CurrentControlSet\Services\Nic1\Parameters\Tcpip
1043 * This is constructed as follows:
1044 * SERVICES_KEY + extracted device name + Protocol name from characteristics
1047 PathLength
= sizeof(SERVICES_KEY
) + /* \Registry\Machine\System\CurrentControlSet\Services\ */
1048 wcslen( DeviceName
.Buffer
+ 8 ) * sizeof(WCHAR
) + /* Adapter1 (extracted from \Device\Adapter1) */
1049 sizeof(PARAMETERS_KEY
) + /* \Parameters\ */
1050 ProtocolCharacteristics
->Name
.Length
+ sizeof(WCHAR
); /* Tcpip */
1052 RegistryPathStr
= ExAllocatePool(PagedPool
, PathLength
);
1053 if(!RegistryPathStr
)
1055 NDIS_DbgPrint(MIN_TRACE
, ("insufficient resources.\n"));
1056 *Status
= NDIS_STATUS_RESOURCES
;
1060 wcscpy(RegistryPathStr
, SERVICES_KEY
);
1061 wcscat(RegistryPathStr
, DeviceName
.Buffer
+ 8 );
1062 wcscat(RegistryPathStr
, PARAMETERS_KEY
);
1063 wcsncat(RegistryPathStr
, ProtocolCharacteristics
->Name
.Buffer
, ProtocolCharacteristics
->Name
.Length
/ sizeof(WCHAR
) );
1065 RegistryPathStr
[PathLength
/sizeof(WCHAR
) - 1] = 0;
1067 RtlInitUnicodeString(&RegistryPath
, RegistryPathStr
);
1069 NDIS_DbgPrint(MAX_TRACE
, ("Calling protocol's BindAdapter handler with DeviceName %wZ and RegistryPath %wZ\n",
1070 &DeviceName
, &RegistryPath
));
1073 BIND_HANDLER BindHandler
= ProtocolCharacteristics
->BindAdapterHandler
;
1076 BindHandler(Status
, BindContext
, &DeviceName
, &RegistryPath
, 0);
1077 NDIS_DbgPrint(MIN_TRACE
, ("%wZ's BindAdapter handler returned 0x%x for %wZ\n", &ProtocolCharacteristics
->Name
, *Status
, &DeviceName
));
1080 NDIS_DbgPrint(MIN_TRACE
, ("No protocol bind handler specified\n"));
1086 /* Advance to the next adapter in the REG_MULTI_SZ */
1087 DataPtr
+= (DeviceName
.Length
/ sizeof(WCHAR
)) + 1;
1091 /* Advance to the next adapter in the global list */
1092 CurrentEntry
= CurrentEntry
->Flink
;
1098 ExFreePool(KeyInformation
);
1107 NdisRegisterProtocol(
1108 OUT PNDIS_STATUS Status
,
1109 OUT PNDIS_HANDLE NdisProtocolHandle
,
1110 IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics
,
1111 IN UINT CharacteristicsLength
)
1113 * FUNCTION: Registers an NDIS driver's ProtocolXxx entry points
1115 * Status = Address of buffer for status information
1116 * NdisProtocolHandle = Address of buffer for handle used to identify the driver
1117 * ProtocolCharacteristics = Pointer to NDIS_PROTOCOL_CHARACTERISTICS structure
1118 * CharacteristicsLength = Size of structure which ProtocolCharacteristics targets
1120 * - you *must* set NdisProtocolHandle before doing anything that could wind up
1121 * getting BindAdapterHandler, as it will probably call OpenAdapter with this handle
1122 * - the above implies that the initialization of the protocol block must be complete
1125 * - break this function up - probably do a 'ndisRefreshProtocolBindings' function
1126 * - make this thing able to handle >1 protocol
1129 PPROTOCOL_BINDING Protocol
;
1132 PNET_PNP_EVENT PnPEvent
;
1134 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1136 *NdisProtocolHandle
= NULL
;
1138 /* first validate the PROTOCOL_CHARACTERISTICS */
1139 switch (ProtocolCharacteristics
->MajorNdisVersion
)
1142 /* we don't really want to support ndis3 drivers - so we complain for now */
1143 NDIS_DbgPrint(MID_TRACE
, ("NDIS 3 protocol attempting to register\n"));
1144 MinSize
= sizeof(NDIS30_PROTOCOL_CHARACTERISTICS
);
1148 MinSize
= sizeof(NDIS40_PROTOCOL_CHARACTERISTICS
);
1152 MinSize
= sizeof(NDIS50_PROTOCOL_CHARACTERISTICS
);
1156 *Status
= NDIS_STATUS_BAD_VERSION
;
1157 NDIS_DbgPrint(MIN_TRACE
, ("Incorrect characteristics size\n"));
1161 if (CharacteristicsLength
< MinSize
)
1163 NDIS_DbgPrint(MIN_TRACE
, ("Bad protocol characteristics.\n"));
1164 *Status
= NDIS_STATUS_BAD_CHARACTERISTICS
;
1168 /* set up the protocol block */
1169 Protocol
= ExAllocatePool(NonPagedPool
, sizeof(PROTOCOL_BINDING
));
1172 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1173 *Status
= NDIS_STATUS_RESOURCES
;
1177 RtlZeroMemory(Protocol
, sizeof(PROTOCOL_BINDING
));
1178 RtlCopyMemory(&Protocol
->Chars
, ProtocolCharacteristics
, MinSize
);
1180 NtStatus
= RtlUpcaseUnicodeString(&Protocol
->Chars
.Name
, &ProtocolCharacteristics
->Name
, TRUE
);
1181 if (!NT_SUCCESS(NtStatus
))
1183 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1184 ExFreePool(Protocol
);
1185 *Status
= NDIS_STATUS_RESOURCES
;
1189 KeInitializeSpinLock(&Protocol
->Lock
);
1191 InitializeListHead(&Protocol
->AdapterListHead
);
1193 /* We must set this before the call to ndisBindMiniportsToProtocol because the protocol's
1194 * BindAdapter handler might need it */
1196 *NdisProtocolHandle
= Protocol
;
1198 ndisBindMiniportsToProtocol(Status
, Protocol
);
1200 /* Should we only send this if ndisBindMiniportsToProtocol succeeds? */
1201 PnPEvent
= ProSetupPnPEvent(NetEventBindsComplete
, NULL
, 0);
1204 if (Protocol
->Chars
.PnPEventHandler
)
1206 /* We call this with a NULL binding context because it affects all bindings */
1207 NtStatus
= (*Protocol
->Chars
.PnPEventHandler
)(NULL
,
1210 /* FIXME: We don't support this yet */
1211 ASSERT(NtStatus
!= NDIS_STATUS_PENDING
);
1214 ExFreePool(PnPEvent
);
1217 if (*Status
== NDIS_STATUS_SUCCESS
) {
1218 ExInterlockedInsertTailList(&ProtocolListHead
, &Protocol
->ListEntry
, &ProtocolListLock
);
1220 NDIS_DbgPrint(MIN_TRACE
, ("Binding failed (%x)\n", *Status
));
1221 ExFreePool(Protocol
);
1222 *NdisProtocolHandle
= NULL
;
1232 OUT PNDIS_STATUS Status
,
1233 IN NDIS_HANDLE NdisBindingHandle
,
1234 IN PNDIS_REQUEST NdisRequest
)
1236 * FUNCTION: Forwards a request to an NDIS driver
1238 * Status = Address of buffer for status information
1239 * NdisBindingHandle = Adapter binding handle
1240 * NdisRequest = Pointer to request to perform
1243 *Status
= ProRequest(NdisBindingHandle
, NdisRequest
);
1252 OUT PNDIS_STATUS Status
,
1253 IN NDIS_HANDLE NdisBindingHandle
)
1255 *Status
= ProReset(NdisBindingHandle
);
1265 OUT PNDIS_STATUS Status
,
1266 IN NDIS_HANDLE NdisBindingHandle
,
1267 IN PNDIS_PACKET Packet
)
1269 * FUNCTION: Forwards a request to send a packet
1271 * Status = Address of buffer for status information
1272 * NdisBindingHandle = Adapter binding handle
1273 * Packet = Pointer to NDIS packet descriptor
1276 *Status
= ProSend(NdisBindingHandle
, Packet
);
1282 #undef NdisSendPackets
1286 IN NDIS_HANDLE NdisBindingHandle
,
1287 IN PPNDIS_PACKET PacketArray
,
1288 IN UINT NumberOfPackets
)
1290 ProSendPackets(NdisBindingHandle
, PacketArray
, NumberOfPackets
);
1296 #undef NdisTransferData
1300 OUT PNDIS_STATUS Status
,
1301 IN NDIS_HANDLE NdisBindingHandle
,
1302 IN NDIS_HANDLE MacReceiveContext
,
1304 IN UINT BytesToTransfer
,
1305 IN OUT PNDIS_PACKET Packet
,
1306 OUT PUINT BytesTransferred
)
1308 * FUNCTION: Forwards a request to copy received data into a protocol-supplied packet
1310 * Status = Address of buffer for status information
1311 * NdisBindingHandle = Adapter binding handle
1312 * MacReceiveContext = MAC receive context
1313 * ByteOffset = Offset in packet to place data
1314 * BytesToTransfer = Number of bytes to copy into packet
1315 * Packet = Pointer to NDIS packet descriptor
1316 * BytesTransferred = Address of buffer to place number of bytes copied
1319 *Status
= ProTransferData(NdisBindingHandle
,
1332 NdisReEnumerateProtocolBindings(IN NDIS_HANDLE NdisProtocolHandle
)
1334 NDIS_STATUS NdisStatus
;
1336 ndisBindMiniportsToProtocol(&NdisStatus
, NdisProtocolHandle
);
1345 NdisGetDriverHandle(
1346 IN PNDIS_HANDLE NdisBindingHandle
,
1347 OUT PNDIS_HANDLE NdisDriverHandle
)
1355 PADAPTER_BINDING Binding
= (PADAPTER_BINDING
)NdisBindingHandle
;
1359 NDIS_DbgPrint(MIN_TRACE
, ("Bad binding handle\n"));
1360 *NdisDriverHandle
= NULL
;
1364 *NdisDriverHandle
= Binding
->Adapter
->NdisMiniportBlock
.DriverHandle
;