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
, "INDICATE");
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 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
400 if(MiniIsBusy(Adapter
, NdisWorkItemSend
)) {
401 NDIS_DbgPrint(MID_TRACE
, ("Busy: NdisWorkItemSend.\n"));
403 MiniQueueWorkItem(Adapter
, NdisWorkItemSend
, Packet
, FALSE
);
404 return NDIS_STATUS_PENDING
;
408 MiniDisplayPacket(Packet
, "SEND");
411 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
413 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
415 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
416 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
417 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, &Packet
, 1);
418 NdisStatus
= NDIS_STATUS_PENDING
;
420 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
421 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
423 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
424 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
425 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, &Packet
, 1);
427 KeLowerIrql(RaiseOldIrql
);
429 NdisStatus
= NDIS_GET_PACKET_STATUS(Packet
);
430 if (NdisStatus
== NDIS_STATUS_RESOURCES
) {
431 MiniQueueWorkItem(Adapter
, NdisWorkItemSend
, Packet
, TRUE
);
432 NdisStatus
= NDIS_STATUS_PENDING
;
436 if (NdisStatus
!= NDIS_STATUS_PENDING
) {
437 MiniWorkItemComplete(Adapter
, NdisWorkItemSend
);
442 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
444 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
445 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
446 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, Packet
, Packet
->Private
.Flags
);
447 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
449 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
450 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
451 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
452 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
453 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, Packet
, Packet
->Private
.Flags
);
454 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
455 KeLowerIrql(RaiseOldIrql
);
457 if (NdisStatus
== NDIS_STATUS_RESOURCES
) {
458 MiniQueueWorkItem(Adapter
, NdisWorkItemSend
, Packet
, TRUE
);
459 NdisStatus
= NDIS_STATUS_PENDING
;
463 if (NdisStatus
!= NDIS_STATUS_PENDING
) {
464 MiniWorkItemComplete(Adapter
, NdisWorkItemSend
);
474 IN NDIS_HANDLE MacBindingHandle
,
475 IN PNDIS_PACKET Packet
)
477 * FUNCTION: Forwards a request to send a packet to an NDIS miniport
479 * MacBindingHandle = Adapter binding handle
480 * Packet = Pointer to NDIS packet descriptor
482 * NDIS_STATUS_SUCCESS if the packet was successfully sent
483 * NDIS_STATUS_PENDING if the miniport was busy or a serialized miniport returned NDIS_STATUS_RESOURCES
486 PADAPTER_BINDING AdapterBinding
;
487 PLOGICAL_ADAPTER Adapter
;
488 PNDIS_BUFFER NdisBuffer
;
489 PDMA_CONTEXT Context
;
490 NDIS_STATUS NdisStatus
;
494 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
496 ASSERT(MacBindingHandle
);
497 AdapterBinding
= GET_ADAPTER_BINDING(MacBindingHandle
);
499 ASSERT(AdapterBinding
);
500 Adapter
= AdapterBinding
->Adapter
;
504 /* if the following is not true, KeRaiseIrql() below will break */
505 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL
);
507 /* XXX what is this crazy black magic? */
508 Packet
->Reserved
[1] = (ULONG_PTR
)MacBindingHandle
;
511 * Test the packet to see if it is a MAC loopback.
513 * We may have to loop this packet if miniport cannot.
514 * If dest MAC address of packet == MAC address of adapter,
515 * this is a loopback frame.
518 if ((Adapter
->NdisMiniportBlock
.MacOptions
& NDIS_MAC_OPTION_NO_LOOPBACK
) &&
519 MiniAdapterHasAddress(Adapter
, Packet
))
522 MiniQueueWorkItem(Adapter
, NdisWorkItemSendLoopback
, Packet
, FALSE
);
523 return NDIS_STATUS_PENDING
;
525 return ProIndicatePacket(Adapter
, Packet
);
528 if (Adapter
->NdisMiniportBlock
.ScatterGatherListSize
!= 0)
530 NDIS_DbgPrint(MID_TRACE
, ("Using Scatter/Gather DMA\n"));
532 NdisQueryPacket(Packet
,
538 Context
= ExAllocatePool(NonPagedPool
, sizeof(DMA_CONTEXT
));
540 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
541 return NDIS_STATUS_RESOURCES
;
544 Context
->Adapter
= Adapter
;
545 Context
->Packet
= Packet
;
547 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
549 KeFlushIoBuffers(NdisBuffer
, FALSE
, TRUE
);
551 NdisStatus
= Adapter
->NdisMiniportBlock
.SystemAdapterObject
->DmaOperations
->GetScatterGatherList(
552 Adapter
->NdisMiniportBlock
.SystemAdapterObject
,
553 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
555 MmGetMdlVirtualAddress(NdisBuffer
),
557 ScatterGatherSendPacket
,
561 KeLowerIrql(OldIrql
);
563 if (!NT_SUCCESS(NdisStatus
)) {
564 NDIS_DbgPrint(MIN_TRACE
, ("GetScatterGatherList failed! (%x)\n", NdisStatus
));
568 return NDIS_STATUS_PENDING
;
572 return proSendPacketToMiniport(Adapter
, Packet
);
578 IN NDIS_HANDLE NdisBindingHandle
,
579 IN PPNDIS_PACKET PacketArray
,
580 IN UINT NumberOfPackets
)
582 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
583 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
585 NDIS_STATUS NdisStatus
;
588 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
590 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
592 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
593 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, PacketArray
, NumberOfPackets
);
597 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
598 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
599 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
600 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, PacketArray
, NumberOfPackets
);
601 KeLowerIrql(RaiseOldIrql
);
602 for (i
= 0; i
< NumberOfPackets
; i
++)
604 NdisStatus
= NDIS_GET_PACKET_STATUS(PacketArray
[i
]);
605 if (NdisStatus
!= NDIS_STATUS_PENDING
)
606 MiniSendComplete(Adapter
, PacketArray
[i
], NdisStatus
);
612 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
614 for (i
= 0; i
< NumberOfPackets
; i
++)
616 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
617 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, PacketArray
[i
], PacketArray
[i
]->Private
.Flags
);
618 if (NdisStatus
!= NDIS_STATUS_PENDING
)
619 MiniSendComplete(Adapter
, PacketArray
[i
], NdisStatus
);
624 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
625 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
626 for (i
= 0; i
< NumberOfPackets
; i
++)
628 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
629 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, PacketArray
[i
], PacketArray
[i
]->Private
.Flags
);
630 if (NdisStatus
!= NDIS_STATUS_PENDING
)
631 MiniSendComplete(Adapter
, PacketArray
[i
], NdisStatus
);
633 KeLowerIrql(RaiseOldIrql
);
640 IN NDIS_HANDLE MacBindingHandle
,
641 IN NDIS_HANDLE MacReceiveContext
,
643 IN UINT BytesToTransfer
,
644 IN OUT PNDIS_PACKET Packet
,
645 OUT PUINT BytesTransferred
)
647 * FUNCTION: Forwards a request to copy received data into a protocol-supplied packet
649 * MacBindingHandle = Adapter binding handle
650 * MacReceiveContext = MAC receive context
651 * ByteOffset = Offset in packet to place data
652 * BytesToTransfer = Number of bytes to copy into packet
653 * Packet = Pointer to NDIS packet descriptor
654 * BytesTransferred = Address of buffer to place number of bytes copied
657 PADAPTER_BINDING AdapterBinding
= GET_ADAPTER_BINDING(MacBindingHandle
);
658 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
662 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
664 /* FIXME: Interrupts must be disabled for adapter */
665 /* XXX sd - why is that true? */
667 if (Adapter
->NdisMiniportBlock
.IndicatedPacket
[KeGetCurrentProcessorNumber()]) {
668 NDIS_DbgPrint(MAX_TRACE
, ("LoopPacket\n"));
669 /* NDIS is responsible for looping this packet */
670 NdisCopyFromPacketToPacket(Packet
,
671 ByteOffset
+ Adapter
->MediumHeaderSize
,
672 BytesToTransfer
+ Adapter
->MediumHeaderSize
,
673 Adapter
->NdisMiniportBlock
.IndicatedPacket
[KeGetCurrentProcessorNumber()],
676 return NDIS_STATUS_SUCCESS
;
679 ASSERT(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.TransferDataHandler
);
681 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
683 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.TransferDataHandler
)(
686 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
691 KeLowerIrql(OldIrql
);
704 OUT PNDIS_STATUS Status
,
705 IN NDIS_HANDLE NdisBindingHandle
)
707 * FUNCTION: Closes an adapter opened with NdisOpenAdapter
709 * Status = Address of buffer for status information
710 * NdisBindingHandle = Handle returned by NdisOpenAdapter
713 PADAPTER_BINDING AdapterBinding
= GET_ADAPTER_BINDING(NdisBindingHandle
);
715 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
717 /* Remove from protocol's bound adapters list */
718 ExInterlockedRemoveEntryList(&AdapterBinding
->ProtocolListEntry
, &AdapterBinding
->ProtocolBinding
->Lock
);
720 /* Remove protocol from adapter's bound protocols list */
721 ExInterlockedRemoveEntryList(&AdapterBinding
->AdapterListEntry
, &AdapterBinding
->Adapter
->NdisMiniportBlock
.Lock
);
723 ExFreePool(AdapterBinding
);
725 *Status
= NDIS_STATUS_SUCCESS
;
734 NdisDeregisterProtocol(
735 OUT PNDIS_STATUS Status
,
736 IN NDIS_HANDLE NdisProtocolHandle
)
738 * FUNCTION: Releases the resources allocated by NdisRegisterProtocol
740 * Status = Address of buffer for status information
741 * NdisProtocolHandle = Handle returned by NdisRegisterProtocol
744 PPROTOCOL_BINDING Protocol
= GET_PROTOCOL_BINDING(NdisProtocolHandle
);
746 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
748 /* FIXME: Make sure no adapter bindings exist */
750 /* Remove protocol from global list */
751 ExInterlockedRemoveEntryList(&Protocol
->ListEntry
, &ProtocolListLock
);
753 ExFreePool(Protocol
);
755 *Status
= NDIS_STATUS_SUCCESS
;
765 OUT PNDIS_STATUS Status
,
766 OUT PNDIS_STATUS OpenErrorStatus
,
767 OUT PNDIS_HANDLE NdisBindingHandle
,
768 OUT PUINT SelectedMediumIndex
,
769 IN PNDIS_MEDIUM MediumArray
,
770 IN UINT MediumArraySize
,
771 IN NDIS_HANDLE NdisProtocolHandle
,
772 IN NDIS_HANDLE ProtocolBindingContext
,
773 IN PNDIS_STRING AdapterName
,
775 IN PSTRING AddressingInformation OPTIONAL
)
777 * FUNCTION: Opens an adapter for communication
779 * Status = Address of buffer for status information
780 * OpenErrorStatus = Address of buffer for secondary error code
781 * NdisBindingHandle = Address of buffer for adapter binding handle
782 * SelectedMediumIndex = Address of buffer for selected medium
783 * MediumArray = Pointer to an array of NDIS_MEDIUMs called can support
784 * MediumArraySize = Number of elements in MediumArray
785 * NdisProtocolHandle = Handle returned by NdisRegisterProtocol
786 * ProtocolBindingContext = Pointer to caller supplied context area
787 * AdapterName = Pointer to buffer with name of adapter
788 * OpenOptions = Bitmask with flags passed to next-lower driver
789 * AddressingInformation = Optional pointer to buffer with NIC specific information
794 PLOGICAL_ADAPTER Adapter
;
795 PADAPTER_BINDING AdapterBinding
;
796 PPROTOCOL_BINDING Protocol
= GET_PROTOCOL_BINDING(NdisProtocolHandle
);
798 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
800 if(!NdisProtocolHandle
)
802 NDIS_DbgPrint(MIN_TRACE
, ("NdisProtocolHandle is NULL\n"));
803 *OpenErrorStatus
= *Status
= NDIS_STATUS_FAILURE
;
807 Adapter
= MiniLocateDevice(AdapterName
);
810 NDIS_DbgPrint(MIN_TRACE
, ("Adapter not found.\n"));
811 *Status
= NDIS_STATUS_ADAPTER_NOT_FOUND
;
815 /* Find the media type in the list provided by the protocol driver */
817 for (i
= 0; i
< MediumArraySize
; i
++)
819 if (Adapter
->NdisMiniportBlock
.MediaType
== MediumArray
[i
])
821 *SelectedMediumIndex
= i
;
829 NDIS_DbgPrint(MIN_TRACE
, ("Medium is not supported.\n"));
830 *Status
= NDIS_STATUS_UNSUPPORTED_MEDIA
;
834 /* Now that we have confirmed that the adapter can be opened, create a binding */
836 AdapterBinding
= ExAllocatePool(NonPagedPool
, sizeof(ADAPTER_BINDING
));
839 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
840 *Status
= NDIS_STATUS_RESOURCES
;
844 RtlZeroMemory(AdapterBinding
, sizeof(ADAPTER_BINDING
));
846 AdapterBinding
->ProtocolBinding
= Protocol
;
847 AdapterBinding
->Adapter
= Adapter
;
848 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
= ProtocolBindingContext
;
850 /* Set fields required by some NDIS macros */
851 AdapterBinding
->NdisOpenBlock
.BindingHandle
= (NDIS_HANDLE
)AdapterBinding
;
853 /* Set handlers (some NDIS macros require these) */
855 AdapterBinding
->NdisOpenBlock
.RequestHandler
= ProRequest
;
856 AdapterBinding
->NdisOpenBlock
.ResetHandler
= ProReset
;
857 AdapterBinding
->NdisOpenBlock
.SendHandler
= ProSend
;
858 AdapterBinding
->NdisOpenBlock
.SendPacketsHandler
= ProSendPackets
;
859 AdapterBinding
->NdisOpenBlock
.TransferDataHandler
= ProTransferData
;
861 AdapterBinding
->NdisOpenBlock
.RequestCompleteHandler
=
862 Protocol
->Chars
.RequestCompleteHandler
;
864 /* Put on protocol's bound adapters list */
865 ExInterlockedInsertTailList(&Protocol
->AdapterListHead
, &AdapterBinding
->ProtocolListEntry
, &Protocol
->Lock
);
867 /* Put protocol on adapter's bound protocols list */
868 NDIS_DbgPrint(MAX_TRACE
, ("acquiring miniport block lock\n"));
869 ExInterlockedInsertTailList(&Adapter
->ProtocolListHead
, &AdapterBinding
->AdapterListEntry
, &Adapter
->NdisMiniportBlock
.Lock
);
871 *NdisBindingHandle
= (NDIS_HANDLE
)AdapterBinding
;
873 *Status
= NDIS_STATUS_SUCCESS
;
878 LocateAdapterBindingByName(IN PPROTOCOL_BINDING ProtocolBinding
, IN PNDIS_STRING AdapterName
)
880 PLIST_ENTRY CurrentEntry
;
881 PADAPTER_BINDING AdapterBinding
;
884 KeAcquireSpinLock(&ProtocolBinding
->Lock
, &OldIrql
);
886 CurrentEntry
= ProtocolBinding
->AdapterListHead
.Flink
;
888 while (CurrentEntry
!= &ProtocolBinding
->AdapterListHead
)
890 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, ProtocolListEntry
);
892 if (RtlCompareUnicodeString(AdapterName
, &AdapterBinding
->Adapter
->NdisMiniportBlock
.MiniportName
, TRUE
) == 0)
894 KeReleaseSpinLock(&ProtocolBinding
->Lock
, OldIrql
);
895 return AdapterBinding
;
898 CurrentEntry
= CurrentEntry
->Flink
;
901 KeReleaseSpinLock(&ProtocolBinding
->Lock
, OldIrql
);
908 ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status
, IN PPROTOCOL_BINDING Protocol
)
911 * bind the protocol to all of its miniports
914 * get list of devices from Bind key
915 * call BindAdapterHandler for each
917 OBJECT_ATTRIBUTES ObjectAttributes
;
918 UNICODE_STRING RegistryPath
;
919 WCHAR
*RegistryPathStr
, *DataPtr
= NULL
;
921 HANDLE DriverKeyHandle
= NULL
;
922 PKEY_VALUE_PARTIAL_INFORMATION KeyInformation
= NULL
;
923 PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics
= &Protocol
->Chars
;
924 UNICODE_STRING ValueName
;
926 PLIST_ENTRY CurrentEntry
= NULL
;
928 RegistryPathStr
= ExAllocatePoolWithTag(PagedPool
, sizeof(SERVICES_KEY
) + ProtocolCharacteristics
->Name
.Length
+ sizeof(LINKAGE_KEY
), NDIS_TAG
+ __LINE__
);
931 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
932 *Status
= NDIS_STATUS_RESOURCES
;
936 wcscpy(RegistryPathStr
, SERVICES_KEY
);
937 wcsncat(RegistryPathStr
, ((WCHAR
*)ProtocolCharacteristics
->Name
.Buffer
), ProtocolCharacteristics
->Name
.Length
/ sizeof(WCHAR
));
938 RegistryPathStr
[wcslen(SERVICES_KEY
)+ProtocolCharacteristics
->Name
.Length
/sizeof(WCHAR
)] = 0;
939 wcscat(RegistryPathStr
, LINKAGE_KEY
);
941 RtlInitUnicodeString(&RegistryPath
, RegistryPathStr
);
942 NDIS_DbgPrint(MAX_TRACE
, ("Opening configuration key: %wZ\n", &RegistryPath
));
944 InitializeObjectAttributes(&ObjectAttributes
, &RegistryPath
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
945 NtStatus
= ZwOpenKey(&DriverKeyHandle
, KEY_READ
, &ObjectAttributes
);
947 ExFreePool(RegistryPathStr
);
949 if(NT_SUCCESS(NtStatus
))
951 NDIS_DbgPrint(MAX_TRACE
, ("Successfully opened the registry configuration\n"));
953 RtlInitUnicodeString(&ValueName
, L
"Bind");
955 NtStatus
= ZwQueryValueKey(DriverKeyHandle
, &ValueName
, KeyValuePartialInformation
, NULL
, 0, &ResultLength
);
956 if(NtStatus
!= STATUS_BUFFER_OVERFLOW
&& NtStatus
!= STATUS_BUFFER_TOO_SMALL
&& NtStatus
!= STATUS_SUCCESS
)
958 NDIS_DbgPrint(MIN_TRACE
, ("Unable to query the Bind value for size\n"));
959 ZwClose(DriverKeyHandle
);
963 KeyInformation
= ExAllocatePoolWithTag(PagedPool
, sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + ResultLength
, NDIS_TAG
+ __LINE__
);
966 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
967 ZwClose(DriverKeyHandle
);
968 NtStatus
= STATUS_NO_MEMORY
;
972 NtStatus
= ZwQueryValueKey(DriverKeyHandle
, &ValueName
, KeyValuePartialInformation
, KeyInformation
,
973 sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + ResultLength
, &ResultLength
);
975 ZwClose(DriverKeyHandle
);
977 if(!NT_SUCCESS(NtStatus
))
979 NDIS_DbgPrint(MIN_TRACE
, ("Unable to query the Bind value\n"));
980 ExFreePool(KeyInformation
);
981 KeyInformation
= NULL
;
987 if (!NT_SUCCESS(NtStatus
))
989 NDIS_DbgPrint(MID_TRACE
, ("Performing global bind for protocol '%wZ'\n", &ProtocolCharacteristics
->Name
));
990 KeyInformation
= NULL
;
992 CurrentEntry
= AdapterListHead
.Flink
;
996 NDIS_DbgPrint(MID_TRACE
, ("Performing standard bind for protocol '%wZ'\n", &ProtocolCharacteristics
->Name
));
998 DataPtr
= (WCHAR
*)KeyInformation
->Data
;
1001 /* Assume success for now */
1002 *Status
= NDIS_STATUS_SUCCESS
;
1006 /* BindContext is for tracking pending binding operations */
1007 VOID
*BindContext
= 0;
1008 NDIS_STRING DeviceName
;
1009 NDIS_STRING RegistryPath
;
1010 WCHAR
*RegistryPathStr
= NULL
;
1011 ULONG PathLength
= 0;
1012 PLOGICAL_ADAPTER Adapter
;
1016 /* Parse the REG_MULTI_SZ entry for device names */
1020 RtlInitUnicodeString(&DeviceName
, DataPtr
);
1024 /* Use the device name from the global adapter list */
1025 if (CurrentEntry
== &AdapterListHead
)
1028 Adapter
= CONTAINING_RECORD(CurrentEntry
, LOGICAL_ADAPTER
, ListEntry
);
1030 DeviceName
= Adapter
->NdisMiniportBlock
.MiniportName
;
1033 /* Make sure the adapter has started */
1034 if (!MiniLocateDevice(&DeviceName
))
1036 /* It wasn't in the global miniport list, so skip the bind entry */
1040 /* Make sure this device isn't already bound to this protocol */
1041 if (LocateAdapterBindingByName(Protocol
, &DeviceName
))
1043 /* It was already in this protocol's bound adapter list, so skip the bind entry */
1048 * RegistryPath should be:
1049 * \Registry\Machine\System\CurrentControlSet\Services\Nic1\Parameters\Tcpip
1051 * This is constructed as follows:
1052 * SERVICES_KEY + extracted device name + Protocol name from characteristics
1055 PathLength
= sizeof(SERVICES_KEY
) + /* \Registry\Machine\System\CurrentControlSet\Services\ */
1056 wcslen( DeviceName
.Buffer
+ 8 ) * sizeof(WCHAR
) + /* Adapter1 (extracted from \Device\Adapter1) */
1057 sizeof(PARAMETERS_KEY
) + /* \Parameters\ */
1058 ProtocolCharacteristics
->Name
.Length
+ sizeof(WCHAR
); /* Tcpip */
1060 RegistryPathStr
= ExAllocatePool(PagedPool
, PathLength
);
1061 if(!RegistryPathStr
)
1063 NDIS_DbgPrint(MIN_TRACE
, ("insufficient resources.\n"));
1064 *Status
= NDIS_STATUS_RESOURCES
;
1068 wcscpy(RegistryPathStr
, SERVICES_KEY
);
1069 wcscat(RegistryPathStr
, DeviceName
.Buffer
+ 8 );
1070 wcscat(RegistryPathStr
, PARAMETERS_KEY
);
1071 wcsncat(RegistryPathStr
, ProtocolCharacteristics
->Name
.Buffer
, ProtocolCharacteristics
->Name
.Length
/ sizeof(WCHAR
) );
1073 RegistryPathStr
[PathLength
/sizeof(WCHAR
) - 1] = 0;
1075 RtlInitUnicodeString(&RegistryPath
, RegistryPathStr
);
1077 NDIS_DbgPrint(MAX_TRACE
, ("Calling protocol's BindAdapter handler with DeviceName %wZ and RegistryPath %wZ\n",
1078 &DeviceName
, &RegistryPath
));
1081 BIND_HANDLER BindHandler
= ProtocolCharacteristics
->BindAdapterHandler
;
1084 BindHandler(Status
, BindContext
, &DeviceName
, &RegistryPath
, 0);
1085 NDIS_DbgPrint(MID_TRACE
, ("%wZ's BindAdapter handler returned 0x%x for %wZ\n", &ProtocolCharacteristics
->Name
, *Status
, &DeviceName
));
1088 NDIS_DbgPrint(MID_TRACE
, ("No protocol bind handler specified\n"));
1094 /* Advance to the next adapter in the REG_MULTI_SZ */
1095 DataPtr
+= (DeviceName
.Length
/ sizeof(WCHAR
)) + 1;
1099 /* Advance to the next adapter in the global list */
1100 CurrentEntry
= CurrentEntry
->Flink
;
1106 ExFreePool(KeyInformation
);
1115 NdisRegisterProtocol(
1116 OUT PNDIS_STATUS Status
,
1117 OUT PNDIS_HANDLE NdisProtocolHandle
,
1118 IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics
,
1119 IN UINT CharacteristicsLength
)
1121 * FUNCTION: Registers an NDIS driver's ProtocolXxx entry points
1123 * Status = Address of buffer for status information
1124 * NdisProtocolHandle = Address of buffer for handle used to identify the driver
1125 * ProtocolCharacteristics = Pointer to NDIS_PROTOCOL_CHARACTERISTICS structure
1126 * CharacteristicsLength = Size of structure which ProtocolCharacteristics targets
1128 * - you *must* set NdisProtocolHandle before doing anything that could wind up
1129 * getting BindAdapterHandler, as it will probably call OpenAdapter with this handle
1130 * - the above implies that the initialization of the protocol block must be complete
1133 * - break this function up - probably do a 'ndisRefreshProtocolBindings' function
1134 * - make this thing able to handle >1 protocol
1137 PPROTOCOL_BINDING Protocol
;
1140 PNET_PNP_EVENT PnPEvent
;
1142 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1144 *NdisProtocolHandle
= NULL
;
1146 /* first validate the PROTOCOL_CHARACTERISTICS */
1147 switch (ProtocolCharacteristics
->MajorNdisVersion
)
1150 /* we don't really want to support ndis3 drivers - so we complain for now */
1151 NDIS_DbgPrint(MID_TRACE
, ("NDIS 3 protocol attempting to register\n"));
1152 MinSize
= sizeof(NDIS30_PROTOCOL_CHARACTERISTICS
);
1156 MinSize
= sizeof(NDIS40_PROTOCOL_CHARACTERISTICS
);
1160 MinSize
= sizeof(NDIS50_PROTOCOL_CHARACTERISTICS
);
1164 *Status
= NDIS_STATUS_BAD_VERSION
;
1165 NDIS_DbgPrint(MIN_TRACE
, ("Incorrect characteristics size\n"));
1169 if (CharacteristicsLength
< MinSize
)
1171 NDIS_DbgPrint(MIN_TRACE
, ("Bad protocol characteristics.\n"));
1172 *Status
= NDIS_STATUS_BAD_CHARACTERISTICS
;
1176 /* set up the protocol block */
1177 Protocol
= ExAllocatePool(NonPagedPool
, sizeof(PROTOCOL_BINDING
));
1180 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1181 *Status
= NDIS_STATUS_RESOURCES
;
1185 RtlZeroMemory(Protocol
, sizeof(PROTOCOL_BINDING
));
1186 RtlCopyMemory(&Protocol
->Chars
, ProtocolCharacteristics
, MinSize
);
1188 NtStatus
= RtlUpcaseUnicodeString(&Protocol
->Chars
.Name
, &ProtocolCharacteristics
->Name
, TRUE
);
1189 if (!NT_SUCCESS(NtStatus
))
1191 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1192 ExFreePool(Protocol
);
1193 *Status
= NDIS_STATUS_RESOURCES
;
1197 KeInitializeSpinLock(&Protocol
->Lock
);
1199 InitializeListHead(&Protocol
->AdapterListHead
);
1201 /* We must set this before the call to ndisBindMiniportsToProtocol because the protocol's
1202 * BindAdapter handler might need it */
1204 *NdisProtocolHandle
= Protocol
;
1206 ndisBindMiniportsToProtocol(Status
, Protocol
);
1208 /* Should we only send this if ndisBindMiniportsToProtocol succeeds? */
1209 PnPEvent
= ProSetupPnPEvent(NetEventBindsComplete
, NULL
, 0);
1212 if (Protocol
->Chars
.PnPEventHandler
)
1214 /* We call this with a NULL binding context because it affects all bindings */
1215 NtStatus
= (*Protocol
->Chars
.PnPEventHandler
)(NULL
,
1218 /* FIXME: We don't support this yet */
1219 ASSERT(NtStatus
!= NDIS_STATUS_PENDING
);
1222 ExFreePool(PnPEvent
);
1225 if (*Status
== NDIS_STATUS_SUCCESS
) {
1226 ExInterlockedInsertTailList(&ProtocolListHead
, &Protocol
->ListEntry
, &ProtocolListLock
);
1228 NDIS_DbgPrint(MIN_TRACE
, ("Binding failed (%x)\n", *Status
));
1229 ExFreePool(Protocol
);
1230 *NdisProtocolHandle
= NULL
;
1240 OUT PNDIS_STATUS Status
,
1241 IN NDIS_HANDLE NdisBindingHandle
,
1242 IN PNDIS_REQUEST NdisRequest
)
1244 * FUNCTION: Forwards a request to an NDIS driver
1246 * Status = Address of buffer for status information
1247 * NdisBindingHandle = Adapter binding handle
1248 * NdisRequest = Pointer to request to perform
1251 *Status
= ProRequest(NdisBindingHandle
, NdisRequest
);
1260 OUT PNDIS_STATUS Status
,
1261 IN NDIS_HANDLE NdisBindingHandle
)
1263 *Status
= ProReset(NdisBindingHandle
);
1273 OUT PNDIS_STATUS Status
,
1274 IN NDIS_HANDLE NdisBindingHandle
,
1275 IN PNDIS_PACKET Packet
)
1277 * FUNCTION: Forwards a request to send a packet
1279 * Status = Address of buffer for status information
1280 * NdisBindingHandle = Adapter binding handle
1281 * Packet = Pointer to NDIS packet descriptor
1284 *Status
= ProSend(NdisBindingHandle
, Packet
);
1290 #undef NdisSendPackets
1294 IN NDIS_HANDLE NdisBindingHandle
,
1295 IN PPNDIS_PACKET PacketArray
,
1296 IN UINT NumberOfPackets
)
1298 ProSendPackets(NdisBindingHandle
, PacketArray
, NumberOfPackets
);
1304 #undef NdisTransferData
1308 OUT PNDIS_STATUS Status
,
1309 IN NDIS_HANDLE NdisBindingHandle
,
1310 IN NDIS_HANDLE MacReceiveContext
,
1312 IN UINT BytesToTransfer
,
1313 IN OUT PNDIS_PACKET Packet
,
1314 OUT PUINT BytesTransferred
)
1316 * FUNCTION: Forwards a request to copy received data into a protocol-supplied packet
1318 * Status = Address of buffer for status information
1319 * NdisBindingHandle = Adapter binding handle
1320 * MacReceiveContext = MAC receive context
1321 * ByteOffset = Offset in packet to place data
1322 * BytesToTransfer = Number of bytes to copy into packet
1323 * Packet = Pointer to NDIS packet descriptor
1324 * BytesTransferred = Address of buffer to place number of bytes copied
1327 *Status
= ProTransferData(NdisBindingHandle
,
1340 NdisReEnumerateProtocolBindings(IN NDIS_HANDLE NdisProtocolHandle
)
1342 NDIS_STATUS NdisStatus
;
1344 ndisBindMiniportsToProtocol(&NdisStatus
, NdisProtocolHandle
);
1353 NdisGetDriverHandle(
1354 IN PNDIS_HANDLE NdisBindingHandle
,
1355 OUT PNDIS_HANDLE NdisDriverHandle
)
1363 PADAPTER_BINDING Binding
= (PADAPTER_BINDING
)NdisBindingHandle
;
1367 NDIS_DbgPrint(MIN_TRACE
, ("Bad binding handle\n"));
1368 *NdisDriverHandle
= NULL
;
1372 *NdisDriverHandle
= Binding
->Adapter
->NdisMiniportBlock
.DriverHandle
;