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)
8 * CSH 01/08-2000 Created
16 LIST_ENTRY ProtocolListHead
;
17 KSPIN_LOCK ProtocolListLock
;
24 NdisCompleteBindAdapter(
25 IN NDIS_HANDLE BindAdapterContext
,
26 IN NDIS_STATUS Status
,
27 IN NDIS_STATUS OpenStatus
)
29 * FUNCTION: Indicates a packet to bound protocols
31 * Adapter = Pointer to logical adapter
32 * Packet = Pointer to packet to indicate
38 * XXX partially-implemented!
40 * need to handle error conditions, and i'm not sure this is even what this func should do.
41 * be sure to fix NdisRegisterProtocol before fixing this, though.
44 PROTOCOL_BINDING
*Protocol
= (PROTOCOL_BINDING
*)BindAdapterContext
;
46 /* Put protocol binding struct on global list */
47 ExInterlockedInsertTailList(&ProtocolListHead
, &Protocol
->ListEntry
, &ProtocolListLock
);
53 PLOGICAL_ADAPTER Adapter
,
56 * FUNCTION: Indicates a packet to bound protocols
58 * Adapter = Pointer to logical adapter
59 * Packet = Pointer to packet to indicate
68 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
71 MiniDisplayPacket(Packet
);
74 NdisQueryPacket(Packet
, NULL
, NULL
, NULL
, &Total
);
76 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
78 Adapter
->LoopPacket
= Packet
;
80 Length
= CopyPacketToBuffer(
81 Adapter
->LookaheadBuffer
,
84 Adapter
->CurLookaheadLength
);
86 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
88 if (Length
> Adapter
->MediumHeaderSize
) {
89 MiniIndicateData(Adapter
,
91 Adapter
->LookaheadBuffer
,
92 Adapter
->MediumHeaderSize
,
93 &Adapter
->LookaheadBuffer
[Adapter
->MediumHeaderSize
],
94 Length
- Adapter
->MediumHeaderSize
,
95 Total
- Adapter
->MediumHeaderSize
);
97 MiniIndicateData(Adapter
,
99 Adapter
->LookaheadBuffer
,
100 Adapter
->MediumHeaderSize
,
106 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
108 Adapter
->LoopPacket
= NULL
;
110 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
112 return STATUS_SUCCESS
;
118 IN NDIS_HANDLE MacBindingHandle
,
119 IN PNDIS_REQUEST NdisRequest
)
121 * FUNCTION: Forwards a request to an NDIS miniport
123 * MacBindingHandle = Adapter binding handle
124 * NdisRequest = Pointer to request to perform
126 * Status of operation
131 NDIS_STATUS NdisStatus
;
132 PADAPTER_BINDING AdapterBinding
= GET_ADAPTER_BINDING(MacBindingHandle
);
133 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
135 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
137 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
138 Queue
= Adapter
->MiniportBusy
;
140 MiniQueueWorkItem(Adapter
,
143 (NDIS_HANDLE
)AdapterBinding
);
145 Adapter
->MiniportBusy
= TRUE
;
147 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
150 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
151 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
152 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
153 Adapter
->MiniportBusy
= FALSE
;
154 if (Adapter
->WorkQueueHead
)
155 KeInsertQueueDpc(&Adapter
->MiniportDpc
, NULL
, NULL
);
156 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
157 KeLowerIrql(OldIrql
);
159 NdisStatus
= NDIS_STATUS_PENDING
;
167 IN NDIS_HANDLE MacBindingHandle
)
171 return NDIS_STATUS_FAILURE
;
177 IN NDIS_HANDLE MacBindingHandle
,
178 IN PNDIS_PACKET Packet
)
180 * FUNCTION: Forwards a request to send a packet to an NDIS miniport
182 * MacBindingHandle = Adapter binding handle
183 * Packet = Pointer to NDIS packet descriptor
188 NDIS_STATUS NdisStatus
;
189 PADAPTER_BINDING AdapterBinding
= GET_ADAPTER_BINDING(MacBindingHandle
);
190 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
192 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
194 /* FIXME: Should queue packet if miniport returns NDIS_STATUS_RESOURCES */
196 Packet
->Reserved
[0] = (ULONG_PTR
)MacBindingHandle
;
198 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
199 Queue
= Adapter
->MiniportBusy
;
201 /* We may have to loop this packet if miniport cannot */
202 if (Adapter
->NdisMiniportBlock
.MacOptions
& NDIS_MAC_OPTION_NO_LOOPBACK
) {
203 if (MiniAdapterHasAddress(Adapter
, Packet
)) {
204 /* Do software loopback because miniport does not support it */
206 NDIS_DbgPrint(MIN_TRACE
, ("Looping packet.\n"));
210 /* FIXME: Packets should properbly be queued directly on the adapter instead */
212 MiniQueueWorkItem(Adapter
,
213 NdisWorkItemSendLoopback
,
215 (NDIS_HANDLE
)AdapterBinding
);
217 Adapter
->MiniportBusy
= TRUE
;
219 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
222 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
223 NdisStatus
= ProIndicatePacket(Adapter
, Packet
);
224 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
225 Adapter
->MiniportBusy
= FALSE
;
226 if (Adapter
->WorkQueueHead
)
227 KeInsertQueueDpc(&Adapter
->MiniportDpc
, NULL
, NULL
);
228 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
229 KeLowerIrql(OldIrql
);
232 return NDIS_STATUS_PENDING
;
239 /* FIXME: Packets should properbly be queued directly on the adapter instead */
241 MiniQueueWorkItem(Adapter
,
244 (NDIS_HANDLE
)AdapterBinding
);
246 Adapter
->MiniportBusy
= TRUE
;
248 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
251 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
252 NdisStatus
= (*Adapter
->Miniport
->Chars
.u1
.SendHandler
)(
253 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
256 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
257 Adapter
->MiniportBusy
= FALSE
;
258 if (Adapter
->WorkQueueHead
)
259 KeInsertQueueDpc(&Adapter
->MiniportDpc
, NULL
, NULL
);
260 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
261 KeLowerIrql(OldIrql
);
263 NdisStatus
= NDIS_STATUS_PENDING
;
271 IN NDIS_HANDLE NdisBindingHandle
,
272 IN PPNDIS_PACKET PacketArray
,
273 IN UINT NumberOfPackets
)
281 IN NDIS_HANDLE MacBindingHandle
,
282 IN NDIS_HANDLE MacReceiveContext
,
284 IN UINT BytesToTransfer
,
285 IN OUT PNDIS_PACKET Packet
,
286 OUT PUINT BytesTransferred
)
288 * FUNCTION: Forwards a request to copy received data into a protocol-supplied packet
290 * MacBindingHandle = Adapter binding handle
291 * MacReceiveContext = MAC receive context
292 * ByteOffset = Offset in packet to place data
293 * BytesToTransfer = Number of bytes to copy into packet
294 * Packet = Pointer to NDIS packet descriptor
295 * BytesTransferred = Address of buffer to place number of bytes copied
298 PADAPTER_BINDING AdapterBinding
= GET_ADAPTER_BINDING(MacBindingHandle
);
299 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
301 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
303 /* FIXME: Interrupts must be disabled for adapter */
305 if (Packet
== Adapter
->LoopPacket
) {
306 /* NDIS is responsible for looping this packet */
307 NdisCopyFromPacketToPacket(Packet
,
313 return NDIS_STATUS_SUCCESS
;
316 return (*Adapter
->Miniport
->Chars
.u2
.TransferDataHandler
)(
319 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
333 OUT PNDIS_STATUS Status
,
334 IN NDIS_HANDLE NdisBindingHandle
)
336 * FUNCTION: Closes an adapter opened with NdisOpenAdapter
338 * Status = Address of buffer for status information
339 * NdisBindingHandle = Handle returned by NdisOpenAdapter
343 PADAPTER_BINDING AdapterBinding
= GET_ADAPTER_BINDING(NdisBindingHandle
);
345 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
347 /* Remove from protocol's bound adapters list */
348 KeAcquireSpinLock(&AdapterBinding
->ProtocolBinding
->Lock
, &OldIrql
);
349 RemoveEntryList(&AdapterBinding
->ProtocolListEntry
);
350 KeReleaseSpinLock(&AdapterBinding
->ProtocolBinding
->Lock
, OldIrql
);
352 /* Remove protocol from adapter's bound protocols list */
353 KeAcquireSpinLock(&AdapterBinding
->Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
354 RemoveEntryList(&AdapterBinding
->AdapterListEntry
);
355 KeReleaseSpinLock(&AdapterBinding
->Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
357 ExFreePool(AdapterBinding
);
359 *Status
= NDIS_STATUS_SUCCESS
;
368 NdisDeregisterProtocol(
369 OUT PNDIS_STATUS Status
,
370 IN NDIS_HANDLE NdisProtocolHandle
)
372 * FUNCTION: Releases the resources allocated by NdisRegisterProtocol
374 * Status = Address of buffer for status information
375 * NdisProtocolHandle = Handle returned by NdisRegisterProtocol
379 PPROTOCOL_BINDING Protocol
= GET_PROTOCOL_BINDING(NdisProtocolHandle
);
381 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
383 /* FIXME: Make sure no adapter bindings exist */
385 /* Remove protocol from global list */
386 KeAcquireSpinLock(&ProtocolListLock
, &OldIrql
);
387 RemoveEntryList(&Protocol
->ListEntry
);
388 KeReleaseSpinLock(&ProtocolListLock
, OldIrql
);
390 ExFreePool(Protocol
);
392 *Status
= NDIS_STATUS_SUCCESS
;
402 OUT PNDIS_STATUS Status
,
403 OUT PNDIS_STATUS OpenErrorStatus
,
404 OUT PNDIS_HANDLE NdisBindingHandle
,
405 OUT PUINT SelectedMediumIndex
,
406 IN PNDIS_MEDIUM MediumArray
,
407 IN UINT MediumArraySize
,
408 IN NDIS_HANDLE NdisProtocolHandle
,
409 IN NDIS_HANDLE ProtocolBindingContext
,
410 IN PNDIS_STRING AdapterName
,
412 IN PSTRING AddressingInformation OPTIONAL
)
414 * FUNCTION: Opens an adapter for communication
416 * Status = Address of buffer for status information
417 * OpenErrorStatus = Address of buffer for secondary error code
418 * NdisBindingHandle = Address of buffer for adapter binding handle
419 * SelectedMediumIndex = Address of buffer for selected medium
420 * MediumArray = Pointer to an array of NDIS_MEDIUMs called can support
421 * MediumArraySize = Number of elements in MediumArray
422 * NdisProtocolHandle = Handle returned by NdisRegisterProtocol
423 * ProtocolBindingContext = Pointer to caller suplied context area
424 * AdapterName = Pointer to buffer with name of adapter
425 * OpenOptions = Bitmask with flags passed to next-lower driver
426 * AddressingInformation = Optional pointer to buffer with NIC specific information
431 PLOGICAL_ADAPTER Adapter
;
432 PADAPTER_BINDING AdapterBinding
;
433 PPROTOCOL_BINDING Protocol
= GET_PROTOCOL_BINDING(NdisProtocolHandle
);
435 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
437 Adapter
= MiniLocateDevice(AdapterName
);
439 NDIS_DbgPrint(MIN_TRACE
, ("Adapter not found.\n"));
440 *Status
= NDIS_STATUS_ADAPTER_NOT_FOUND
;
444 /* Find the media type in the list provided by the protocol driver */
446 for (i
= 0; i
< MediumArraySize
; i
++) {
447 if (Adapter
->NdisMiniportBlock
.MediaType
== MediumArray
[i
]) {
448 *SelectedMediumIndex
= i
;
455 NDIS_DbgPrint(MIN_TRACE
, ("Medium is not supported.\n"));
456 *Status
= NDIS_STATUS_UNSUPPORTED_MEDIA
;
460 AdapterBinding
= ExAllocatePool(NonPagedPool
, sizeof(ADAPTER_BINDING
));
461 if (!AdapterBinding
) {
462 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
463 *Status
= NDIS_STATUS_RESOURCES
;
467 RtlZeroMemory(AdapterBinding
, sizeof(ADAPTER_BINDING
));
469 AdapterBinding
->ProtocolBinding
= Protocol
;
470 AdapterBinding
->Adapter
= Adapter
;
471 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
= ProtocolBindingContext
;
473 /* Set fields required by some NDIS macros */
474 AdapterBinding
->NdisOpenBlock
.MacBindingHandle
= (NDIS_HANDLE
)AdapterBinding
;
476 /* Set handlers (some NDIS macros require these) */
478 AdapterBinding
->NdisOpenBlock
.RequestHandler
= ProRequest
;
479 AdapterBinding
->NdisOpenBlock
.ResetHandler
= ProReset
;
480 AdapterBinding
->NdisOpenBlock
.u1
.SendHandler
= ProSend
;
481 AdapterBinding
->NdisOpenBlock
.SendPacketsHandler
= ProSendPackets
;
482 AdapterBinding
->NdisOpenBlock
.TransferDataHandler
= ProTransferData
;
485 /* XXX this looks fishy */
486 /* OK, this really *is* fishy - it bugchecks */
487 /* Put on protocol's bound adapters list */
488 ExInterlockedInsertTailList(&Protocol
->AdapterListHead
,
489 &AdapterBinding
->ProtocolListEntry
,
492 /* XXX so does this */
493 /* Put protocol on adapter's bound protocols list */
494 ExInterlockedInsertTailList(&Adapter
->ProtocolListHead
,
495 &AdapterBinding
->AdapterListEntry
,
496 &Adapter
->NdisMiniportBlock
.Lock
);
498 *NdisBindingHandle
= (NDIS_HANDLE
)AdapterBinding
;
500 *Status
= NDIS_STATUS_SUCCESS
;
509 NdisRegisterProtocol(
510 OUT PNDIS_STATUS Status
,
511 OUT PNDIS_HANDLE NdisProtocolHandle
,
512 IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics
,
513 IN UINT CharacteristicsLength
)
515 * FUNCTION: Registers an NDIS driver's ProtocolXxx entry points
517 * Status = Address of buffer for status information
518 * NdisProtocolHandle = Address of buffer for handle used to identify the driver
519 * ProtocolCharacteristics = Pointer to NDIS_PROTOCOL_CHARACTERISTICS structure
520 * CharacteristicsLength = Size of structure which ProtocolCharacteristics targets
522 * break this function up
523 * make this thing able to handle >1 protocol
526 PPROTOCOL_BINDING Protocol
;
529 HANDLE DriverKeyHandle
= NULL
;
530 PKEY_VALUE_PARTIAL_INFORMATION KeyInformation
= NULL
;
533 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
535 switch (ProtocolCharacteristics
->MajorNdisVersion
) {
536 case 0x03: /* we don't really want to support ndis3 drivers - so we complainf or now */
537 NDIS_DbgPrint(MID_TRACE
, ("Ndis 3 protocol attempting to register\n"));
538 MinSize
= sizeof(NDIS30_PROTOCOL_CHARACTERISTICS_S
);
542 MinSize
= sizeof(NDIS40_PROTOCOL_CHARACTERISTICS_S
);
546 MinSize
= sizeof(NDIS50_PROTOCOL_CHARACTERISTICS_S
);
550 *Status
= NDIS_STATUS_BAD_VERSION
;
551 NDIS_DbgPrint(MIN_TRACE
, ("Incorrect characteristics size\n"));
555 if (CharacteristicsLength
< MinSize
) {
556 NDIS_DbgPrint(DEBUG_PROTOCOL
, ("Bad protocol characteristics.\n"));
557 *Status
= NDIS_STATUS_BAD_CHARACTERISTICS
;
561 Protocol
= ExAllocatePool(NonPagedPool
, sizeof(PROTOCOL_BINDING
));
563 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
564 *Status
= NDIS_STATUS_RESOURCES
;
568 RtlZeroMemory(Protocol
, sizeof(PROTOCOL_BINDING
));
569 RtlCopyMemory(&Protocol
->Chars
, ProtocolCharacteristics
, MinSize
);
571 NtStatus
= RtlUpcaseUnicodeString(&Protocol
->Chars
.Name
,
572 &ProtocolCharacteristics
->Name
,
574 if (!NT_SUCCESS(NtStatus
)) {
575 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
576 ExFreePool(Protocol
);
577 *Status
= NDIS_STATUS_RESOURCES
;
581 KeInitializeSpinLock(&Protocol
->Lock
);
583 Protocol
->RefCount
= 1;
585 InitializeListHead(&Protocol
->AdapterListHead
);
588 * bind the adapter to all of its miniports
591 * get list of devices from Bind key
592 * call BindAdapterHandler for each
595 OBJECT_ATTRIBUTES ObjectAttributes
;
596 UNICODE_STRING RegistryPath
;
597 WCHAR
*RegistryPathStr
;
599 #define SERVICES_KEY L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
600 #define LINKAGE_KEY L"\\Linkage"
602 RegistryPathStr
= ExAllocatePool(PagedPool
,
603 sizeof(SERVICES_KEY
) + ProtocolCharacteristics
->Name
.Length
+ sizeof(LINKAGE_KEY
));
606 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
607 ExFreePool(Protocol
);
608 *Status
= NDIS_STATUS_RESOURCES
;
612 wcscpy(RegistryPathStr
, SERVICES_KEY
);
613 wcsncat(RegistryPathStr
, ((WCHAR
*)ProtocolCharacteristics
->Name
.Buffer
),
614 ProtocolCharacteristics
->Name
.Length
/ sizeof(WCHAR
));
615 RegistryPathStr
[wcslen(SERVICES_KEY
)+ProtocolCharacteristics
->Name
.Length
/sizeof(WCHAR
)] = 0;
616 wcscat(RegistryPathStr
, LINKAGE_KEY
);
618 RtlInitUnicodeString(&RegistryPath
, RegistryPathStr
);
619 NDIS_DbgPrint(MAX_TRACE
, ("Opening configuration key: %wZ\n", &RegistryPath
));
621 InitializeObjectAttributes(&ObjectAttributes
, &RegistryPath
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
622 NtStatus
= ZwOpenKey(&DriverKeyHandle
, KEY_READ
, &ObjectAttributes
);
624 ExFreePool(RegistryPathStr
);
626 if(!NT_SUCCESS(NtStatus
))
628 NDIS_DbgPrint(MID_TRACE
, ("Unable to open protocol configuration\n"));
629 ExFreePool(Protocol
);
630 *Status
= NDIS_STATUS_FAILURE
;
635 NDIS_DbgPrint(MAX_TRACE
, ("Successfully opened the registry configuration\n"));
638 UNICODE_STRING ValueName
;
641 RtlInitUnicodeString(&ValueName
, L
"Bind");
643 NtStatus
= ZwQueryValueKey(DriverKeyHandle
, &ValueName
, KeyValuePartialInformation
, NULL
, 0, &ResultLength
);
644 if(NtStatus
!= STATUS_BUFFER_OVERFLOW
&& NtStatus
!= STATUS_BUFFER_TOO_SMALL
)
646 NDIS_DbgPrint(MID_TRACE
, ("Unable to query the Bind value for size\n"));
647 ZwClose(DriverKeyHandle
);
648 ExFreePool(Protocol
);
649 *Status
= NDIS_STATUS_FAILURE
;
653 KeyInformation
= ExAllocatePool(PagedPool
, sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + ResultLength
);
656 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
657 ZwClose(DriverKeyHandle
);
658 ExFreePool(Protocol
);
659 *Status
= NDIS_STATUS_FAILURE
;
663 NtStatus
= ZwQueryValueKey(DriverKeyHandle
, &ValueName
, KeyValuePartialInformation
, KeyInformation
,
664 sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + ResultLength
, &ResultLength
);
666 if(!NT_SUCCESS(NtStatus
))
668 NDIS_DbgPrint(MIN_TRACE
, ("Unable to query the Bind value\n"));
669 ZwClose(DriverKeyHandle
);
670 ExFreePool(KeyInformation
);
671 ExFreePool(Protocol
);
672 *Status
= NDIS_STATUS_FAILURE
;
678 while((KeyInformation
->Data
)[DataOffset
])
680 /* BindContext is for tracking pending binding operations */
681 VOID
*BindContext
= 0;
682 NDIS_STRING DeviceName
;
683 NDIS_STRING RegistryPath
;
684 WCHAR
*RegistryPathStr
= NULL
;
685 ULONG PathLength
= 0;
687 RtlInitUnicodeString(&DeviceName
, (WCHAR
*)KeyInformation
->Data
); /* we know this is 0-term */
690 * RegistryPath should be:
691 * \Registry\Machine\System\CurrentControlSet\Services\Nic1\Parameters\Tcpip
693 * This is constructed as follows:
694 * SERVICES_KEY + extracted device name + Protocol name from characteristics
696 #define PARAMETERS_KEY L"\\Parameters\\"
698 PathLength
= sizeof(SERVICES_KEY
) + /* \Registry\Machine\System\CurrentControlSet\Services\ */
699 wcslen( ((WCHAR
*)KeyInformation
->Data
)+8 ) * sizeof(WCHAR
) + /* Adapter1 (extracted from \Device\Adapter1) */
700 sizeof(PARAMETERS_KEY
) + /* \Parameters\ */
701 ProtocolCharacteristics
->Name
.Length
; /* Tcpip */
703 RegistryPathStr
= ExAllocatePool(PagedPool
, PathLength
);
706 NDIS_DbgPrint(MIN_TRACE
, ("insufficient resources.\n"));
707 ExFreePool(KeyInformation
);
708 ExFreePool(Protocol
);
709 *Status
= NDIS_STATUS_RESOURCES
;
713 wcscpy(RegistryPathStr
, SERVICES_KEY
);
714 wcscat(RegistryPathStr
, (((WCHAR
*)(KeyInformation
->Data
)) +8 ));
715 wcscat(RegistryPathStr
, PARAMETERS_KEY
);
716 wcsncat(RegistryPathStr
, ProtocolCharacteristics
->Name
.Buffer
, ProtocolCharacteristics
->Name
.Length
/ sizeof(WCHAR
) );
718 RegistryPathStr
[PathLength
/sizeof(WCHAR
) - 1] = 0;
720 RtlInitUnicodeString(&RegistryPath
, RegistryPathStr
);
722 NDIS_DbgPrint(MAX_TRACE
, ("Calling protocol's BindAdapter handler with DeviceName %wZ and RegistryPath %wZ\n",
723 &DeviceName
, &RegistryPath
));
725 /* XXX SD must do something with bind context */
727 BIND_HANDLER BindHandler
= ProtocolCharacteristics
->BindAdapterHandler
;
729 BindHandler(Status
, BindContext
, &DeviceName
, &RegistryPath
, 0);
731 NDIS_DbgPrint(MID_TRACE
, ("No protocol bind handler specified\n"));
734 (*(Protocol->Chars.BindAdapterHandler))(Status, BindContext, &DeviceName, &RegistryPath, 0);
737 if(*Status
== NDIS_STATUS_SUCCESS
)
739 /* Put protocol binding struct on global list */
740 ExInterlockedInsertTailList(&ProtocolListHead
, &Protocol
->ListEntry
, &ProtocolListLock
);
743 else if(*Status != NDIS_STATUS_PENDING)
749 DataOffset
+= wcslen((WCHAR
*)KeyInformation
->Data
);
752 *NdisProtocolHandle
= Protocol
;
753 *Status
= NDIS_STATUS_SUCCESS
;
763 OUT PNDIS_STATUS Status
,
764 IN NDIS_HANDLE NdisBindingHandle
,
765 IN PNDIS_REQUEST NdisRequest
)
767 * FUNCTION: Forwards a request to an NDIS driver
769 * Status = Address of buffer for status information
770 * NdisBindingHandle = Adapter binding handle
771 * NdisRequest = Pointer to request to perform
774 *Status
= ProRequest(NdisBindingHandle
, NdisRequest
);
784 OUT PNDIS_STATUS Status
,
785 IN NDIS_HANDLE NdisBindingHandle
)
787 *Status
= ProReset(NdisBindingHandle
);
797 OUT PNDIS_STATUS Status
,
798 IN NDIS_HANDLE NdisBindingHandle
,
799 IN PNDIS_PACKET Packet
)
801 * FUNCTION: Forwards a request to send a packet
803 * Status = Address of buffer for status information
804 * NdisBindingHandle = Adapter binding handle
805 * Packet = Pointer to NDIS packet descriptor
808 *Status
= ProSend(NdisBindingHandle
, Packet
);
818 IN NDIS_HANDLE NdisBindingHandle
,
819 IN PPNDIS_PACKET PacketArray
,
820 IN UINT NumberOfPackets
)
822 ProSendPackets(NdisBindingHandle
, PacketArray
, NumberOfPackets
);
832 OUT PNDIS_STATUS Status
,
833 IN NDIS_HANDLE NdisBindingHandle
,
834 IN NDIS_HANDLE MacReceiveContext
,
836 IN UINT BytesToTransfer
,
837 IN OUT PNDIS_PACKET Packet
,
838 OUT PUINT BytesTransferred
)
840 * FUNCTION: Forwards a request to copy received data into a protocol-supplied packet
842 * Status = Address of buffer for status information
843 * NdisBindingHandle = Adapter binding handle
844 * MacReceiveContext = MAC receive context
845 * ByteOffset = Offset in packet to place data
846 * BytesToTransfer = Number of bytes to copy into packet
847 * Packet = Pointer to NDIS packet descriptor
848 * BytesTransferred = Address of buffer to place number of bytes copied
851 *Status
= ProTransferData(NdisBindingHandle
,