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,