diff --git a/reactos/drivers/network/afd/afd/info.c b/reactos/drivers/network/afd/afd/info.c index 12c76aa3599..997031ea673 100644 --- a/reactos/drivers/network/afd/afd/info.c +++ b/reactos/drivers/network/afd/afd/info.c @@ -110,7 +110,7 @@ AfdGetSockOrPeerName( PDEVICE_OBJECT DeviceObject, PIRP Irp, TDI_QUERY_ADDRESS_INFO, Mdl ); } else { - if( FCB->Connection.Object == NULL ) { + if( FCB->Connection.Object == NULL || (FCB->State != SOCKET_STATE_BOUND && FCB->State != SOCKET_STATE_CONNECTED) ) { return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER, Irp, 0, NULL ); } diff --git a/reactos/drivers/network/dd/pcnet/requests.c b/reactos/drivers/network/dd/pcnet/requests.c index 0636bbe6c12..fbc87b1690e 100644 --- a/reactos/drivers/network/dd/pcnet/requests.c +++ b/reactos/drivers/network/dd/pcnet/requests.c @@ -352,9 +352,9 @@ MiniportQueryInformation( { if (CopySize > InformationBufferLength) { - *BytesNeeded = (CopySize - InformationBufferLength); + *BytesNeeded = CopySize; *BytesWritten = 0; - Status = NDIS_STATUS_BUFFER_TOO_SHORT; + Status = NDIS_STATUS_INVALID_LENGTH; } else { @@ -363,6 +363,11 @@ MiniportQueryInformation( *BytesNeeded = CopySize; } } + else + { + *BytesWritten = 0; + *BytesNeeded = 0; + } NdisDprReleaseSpinLock(&Adapter->Lock); @@ -417,7 +422,7 @@ MiniportSetInformation( if (InformationBufferLength < sizeof(ULONG)) { *BytesRead = 0; - *BytesNeeded = sizeof(ULONG) - InformationBufferLength; + *BytesNeeded = sizeof(ULONG); Status = NDIS_STATUS_INVALID_LENGTH; break; } @@ -434,7 +439,7 @@ MiniportSetInformation( NDIS_PACKET_TYPE_SOURCE_ROUTING) ) { - *BytesRead = 4; + *BytesRead = sizeof(ULONG); *BytesNeeded = 0; Status = NDIS_STATUS_NOT_SUPPORTED; break; @@ -453,7 +458,7 @@ MiniportSetInformation( if (InformationBufferLength < sizeof(ULONG)) { *BytesRead = 0; - *BytesNeeded = sizeof(ULONG) - InformationBufferLength; + *BytesNeeded = sizeof(ULONG); Status = NDIS_STATUS_INVALID_LENGTH; break; } @@ -461,7 +466,7 @@ MiniportSetInformation( NdisMoveMemory(&GenericULONG, InformationBuffer, sizeof(ULONG)); if (GenericULONG > 1500) - Status = NDIS_STATUS_INVALID_LENGTH; + Status = NDIS_STATUS_INVALID_DATA; else Adapter->CurrentLookaheadSize = GenericULONG; @@ -474,7 +479,7 @@ MiniportSetInformation( if ((InformationBufferLength % 6) != 0) { *BytesRead = 0; - *BytesNeeded = 0; + *BytesNeeded = InformationBufferLength + (InformationBufferLength % 6); Status = NDIS_STATUS_INVALID_LENGTH; break; } diff --git a/reactos/drivers/network/ndis/include/miniport.h b/reactos/drivers/network/ndis/include/miniport.h index 2302ddbde16..f20f97fad8e 100644 --- a/reactos/drivers/network/ndis/include/miniport.h +++ b/reactos/drivers/network/ndis/include/miniport.h @@ -75,7 +75,6 @@ typedef struct _NDIS_WRAPPER_CONTEXT { typedef struct _LOGICAL_ADAPTER { NDIS_MINIPORT_BLOCK NdisMiniportBlock; /* NDIS defined fields */ - BOOLEAN MiniportBusy; /* A MiniportXxx routine is executing */ PNDIS_MINIPORT_WORK_ITEM WorkQueueHead; /* Head of work queue */ PNDIS_MINIPORT_WORK_ITEM WorkQueueTail; /* Tail of work queue */ LIST_ENTRY ListEntry; /* Entry on global list */ @@ -84,8 +83,6 @@ typedef struct _LOGICAL_ADAPTER ULONG MediumHeaderSize; /* Size of medium header */ HARDWARE_ADDRESS Address; /* Hardware address of adapter */ ULONG AddressLength; /* Length of hardware address */ - PUCHAR LookaheadBuffer; /* Pointer to lookahead buffer */ - ULONG LookaheadLength; /* Length of lookahead buffer */ PMINIPORT_BUGCHECK_CONTEXT BugcheckContext; /* Adapter's shutdown handler */ } LOGICAL_ADAPTER, *PLOGICAL_ADAPTER; @@ -130,12 +127,13 @@ MiniQueryInformation( PVOID Buffer, PULONG BytesWritten); -NDIS_STATUS +VOID FASTCALL MiniQueueWorkItem( PLOGICAL_ADAPTER Adapter, NDIS_WORK_ITEM_TYPE WorkItemType, - PVOID WorkItemContext); + PVOID WorkItemContext, + BOOLEAN Top); NDIS_STATUS FASTCALL @@ -161,7 +159,9 @@ NdisStartDevices(); VOID NTAPI -MiniportWorker(IN PVOID WorkItem); +MiniportWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID WorkItem); VOID NTAPI MiniSendComplete( diff --git a/reactos/drivers/network/ndis/ndis/config.c b/reactos/drivers/network/ndis/ndis/config.c index 720575619c2..b5fed4455e3 100644 --- a/reactos/drivers/network/ndis/ndis/config.c +++ b/reactos/drivers/network/ndis/ndis/config.c @@ -139,7 +139,7 @@ NdisCloseConfiguration( while(!IsListEmpty(&ConfigurationContext->ResourceListHead)) { - Resource = (PMINIPORT_RESOURCE)RemoveTailList(&ConfigurationContext->ResourceListHead); + Resource = (PMINIPORT_RESOURCE)ExInterlockedRemoveHeadList(&ConfigurationContext->ResourceListHead, &ConfigurationContext->ResourceLock); if(Resource->ResourceType == MINIPORT_RESOURCE_TYPE_MEMORY) { NDIS_DbgPrint(MAX_TRACE,("freeing 0x%x\n", Resource->Resource)); diff --git a/reactos/drivers/network/ndis/ndis/io.c b/reactos/drivers/network/ndis/ndis/io.c index e5effbd245c..f63a27e03a3 100644 --- a/reactos/drivers/network/ndis/ndis/io.c +++ b/reactos/drivers/network/ndis/ndis/io.c @@ -55,26 +55,27 @@ BOOLEAN NTAPI ServiceRoutine( * FUNCTION: Interrupt service routine * ARGUMENTS: * Interrupt = Pointer to interrupt object - * ServiceContext = Pointer to context information (LOGICAL_ADAPTER) + * ServiceContext = Pointer to context information (PNDIS_MINIPORT_INTERRUPT) * RETURNS * TRUE if a miniport controlled device generated the interrupt */ { BOOLEAN InterruptRecognized = FALSE; BOOLEAN QueueMiniportHandleInterrupt = FALSE; - PLOGICAL_ADAPTER Adapter = ServiceContext; + PNDIS_MINIPORT_INTERRUPT NdisInterrupt = ServiceContext; + PNDIS_MINIPORT_BLOCK NdisMiniportBlock = NdisInterrupt->Miniport; - NDIS_DbgPrint(MAX_TRACE, ("Called. Adapter (0x%X)\n", Adapter)); + NDIS_DbgPrint(MAX_TRACE, ("Called. Interrupt (0x%X)\n", NdisInterrupt)); - if (Adapter->NdisMiniportBlock.Interrupt->IsrRequested) { - (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.ISRHandler)( + if (NdisInterrupt->IsrRequested) { + (*NdisMiniportBlock->DriverHandle->MiniportCharacteristics.ISRHandler)( &InterruptRecognized, &QueueMiniportHandleInterrupt, - Adapter->NdisMiniportBlock.MiniportAdapterContext); + NdisMiniportBlock->MiniportAdapterContext); - } else if (Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.DisableInterruptHandler) { - (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.DisableInterruptHandler)( - Adapter->NdisMiniportBlock.MiniportAdapterContext); + } else if (NdisMiniportBlock->DriverHandle->MiniportCharacteristics.DisableInterruptHandler) { + (*NdisMiniportBlock->DriverHandle->MiniportCharacteristics.DisableInterruptHandler)( + NdisMiniportBlock->MiniportAdapterContext); QueueMiniportHandleInterrupt = TRUE; InterruptRecognized = TRUE; } @@ -83,7 +84,7 @@ BOOLEAN NTAPI ServiceRoutine( if (QueueMiniportHandleInterrupt) { NDIS_DbgPrint(MAX_TRACE, ("Queuing DPC.\n")); - KeInsertQueueDpc(&Adapter->NdisMiniportBlock.Interrupt->InterruptDpc, NULL, NULL); + KeInsertQueueDpc(&NdisInterrupt->InterruptDpc, NULL, NULL); } NDIS_DbgPrint(MAX_TRACE, ("Leaving.\n")); @@ -550,6 +551,10 @@ NdisMDeregisterInterrupt( { NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); IoDisconnectInterrupt(Interrupt->InterruptObject); + Interrupt->Miniport->RegisteredInterrupts--; + + if (Interrupt->Miniport->Interrupt == Interrupt) + Interrupt->Miniport->Interrupt = NULL; } @@ -777,8 +782,7 @@ NdisMRegisterInterrupt( Interrupt->SharedInterrupt = SharedInterrupt; Interrupt->IsrRequested = RequestIsr; - - Adapter->NdisMiniportBlock.Interrupt = Interrupt; + Interrupt->Miniport = &Adapter->NdisMiniportBlock; MappedIRQ = HalGetInterruptVector(Adapter->NdisMiniportBlock.BusType, Adapter->NdisMiniportBlock.BusNumber, InterruptLevel, InterruptVector, &DIrql, @@ -786,13 +790,16 @@ NdisMRegisterInterrupt( NDIS_DbgPrint(MAX_TRACE, ("Connecting to interrupt vector (0x%X) Affinity (0x%X).\n", MappedIRQ, Affinity)); - Status = IoConnectInterrupt(&Interrupt->InterruptObject, ServiceRoutine, Adapter, &Interrupt->DpcCountLock, MappedIRQ, + Status = IoConnectInterrupt(&Interrupt->InterruptObject, ServiceRoutine, Interrupt, &Interrupt->DpcCountLock, MappedIRQ, DIrql, DIrql, InterruptMode, SharedInterrupt, Affinity, FALSE); NDIS_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X).\n", Status)); - if (NT_SUCCESS(Status)) - return NDIS_STATUS_SUCCESS; + if (NT_SUCCESS(Status)) { + Adapter->NdisMiniportBlock.Interrupt = Interrupt; + Adapter->NdisMiniportBlock.RegisteredInterrupts++; + return NDIS_STATUS_SUCCESS; + } if (Status == STATUS_INSUFFICIENT_RESOURCES) { diff --git a/reactos/drivers/network/ndis/ndis/miniport.c b/reactos/drivers/network/ndis/ndis/miniport.c index 0f300d812ce..a5a1695ed86 100644 --- a/reactos/drivers/network/ndis/ndis/miniport.c +++ b/reactos/drivers/network/ndis/ndis/miniport.c @@ -286,8 +286,6 @@ MiniResetComplete( CurrentEntry = CurrentEntry->Flink; } - Adapter->MiniportBusy = FALSE; - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); } @@ -299,7 +297,6 @@ MiniRequestComplete( IN PNDIS_REQUEST Request, IN NDIS_STATUS Status) { - PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle; PNDIS_REQUEST_MAC_BLOCK MacBlock = (PNDIS_REQUEST_MAC_BLOCK)Request->MacReserved; KIRQL OldIrql; @@ -312,9 +309,6 @@ MiniRequestComplete( Request, Status); } - KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); - Adapter->MiniportBusy = FALSE; - KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); KeLowerIrql(OldIrql); } @@ -332,7 +326,6 @@ MiniSendComplete( * Status = Status of send operation */ { - PLOGICAL_ADAPTER Adapter = MiniportAdapterHandle; PADAPTER_BINDING AdapterBinding; KIRQL OldIrql; @@ -345,9 +338,6 @@ MiniSendComplete( AdapterBinding->NdisOpenBlock.ProtocolBindingContext, Packet, Status); - KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); - Adapter->MiniportBusy = FALSE; - KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); KeLowerIrql(OldIrql); } @@ -369,7 +359,6 @@ MiniTransferDataComplete( IN NDIS_STATUS Status, IN UINT BytesTransferred) { - PLOGICAL_ADAPTER Adapter = MiniportAdapterHandle; PADAPTER_BINDING AdapterBinding; KIRQL OldIrql; @@ -382,9 +371,6 @@ MiniTransferDataComplete( AdapterBinding->NdisOpenBlock.ProtocolBindingContext, Packet, Status); - KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); - Adapter->MiniportBusy = FALSE; - KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); KeLowerIrql(OldIrql); } @@ -614,13 +600,6 @@ MiniReset( NDIS_STATUS Status; KIRQL OldIrql; - if (Adapter->MiniportBusy) { - KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); - MiniQueueWorkItem(Adapter, NdisWorkItemResetRequested, NULL); - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); - return NDIS_STATUS_PENDING; - } - NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_START, NULL, 0); NdisMIndicateStatusComplete(Adapter); @@ -633,10 +612,6 @@ MiniReset( if (Status != NDIS_STATUS_PENDING) { NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_END, NULL, 0); NdisMIndicateStatusComplete(Adapter); - } else { - KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); - Adapter->MiniportBusy = TRUE; - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); } return Status; @@ -662,72 +637,76 @@ MiniportHangDpc( } -NDIS_STATUS +VOID FASTCALL MiniQueueWorkItem( PLOGICAL_ADAPTER Adapter, NDIS_WORK_ITEM_TYPE WorkItemType, - PVOID WorkItemContext) + PVOID WorkItemContext, + BOOLEAN Top) /* * FUNCTION: Queues a work item for execution at a later time * ARGUMENTS: * Adapter = Pointer to the logical adapter object to queue work item on * WorkItemType = Type of work item to queue * WorkItemContext = Pointer to context information for work item - * NOTES: - * Adapter lock must be held when called * RETURNS: * Status of operation */ { PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem; - PNDIS_WORK_ITEM NdisWorkItem; - PWORK_QUEUE_ITEM WorkQueueItem; + PIO_WORKITEM IoWorkItem; + KIRQL OldIrql; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); ASSERT(Adapter); - ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); - MiniportWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_MINIPORT_WORK_ITEM)); - if (!MiniportWorkItem) + KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); + if (Top) { - NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); - return NDIS_STATUS_RESOURCES; - } - - NdisWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_WORK_ITEM)); - if (!NdisWorkItem) - { - ExFreePool(MiniportWorkItem); - return NDIS_STATUS_RESOURCES; - } - - MiniportWorkItem->WorkItemType = WorkItemType; - MiniportWorkItem->WorkItemContext = WorkItemContext; - - /* safe due to adapter lock held */ - MiniportWorkItem->Link.Next = NULL; - if (!Adapter->WorkQueueHead) - { - Adapter->WorkQueueHead = MiniportWorkItem; - Adapter->WorkQueueTail = MiniportWorkItem; + if (WorkItemType == NdisWorkItemSend) + { + Adapter->NdisMiniportBlock.FirstPendingPacket = WorkItemContext; + } + else + { + //This should never happen + ASSERT(FALSE); + } } else { - Adapter->WorkQueueTail->Link.Next = (PSINGLE_LIST_ENTRY)MiniportWorkItem; - Adapter->WorkQueueTail = MiniportWorkItem; + MiniportWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_MINIPORT_WORK_ITEM)); + if (!MiniportWorkItem) + { + KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); + NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); + return; + } + + MiniportWorkItem->WorkItemType = WorkItemType; + MiniportWorkItem->WorkItemContext = WorkItemContext; + + /* safe due to adapter lock held */ + MiniportWorkItem->Link.Next = NULL; + if (!Adapter->WorkQueueHead) + { + Adapter->WorkQueueHead = MiniportWorkItem; + Adapter->WorkQueueTail = MiniportWorkItem; + } + else + { + Adapter->WorkQueueTail->Link.Next = (PSINGLE_LIST_ENTRY)MiniportWorkItem; + Adapter->WorkQueueTail = MiniportWorkItem; + } } - WorkQueueItem = (PWORK_QUEUE_ITEM)NdisWorkItem->WrapperReserved; + IoWorkItem = IoAllocateWorkItem(Adapter->NdisMiniportBlock.DeviceObject); + if (IoWorkItem) + IoQueueWorkItem(IoWorkItem, MiniportWorker, CriticalWorkQueue, IoWorkItem); - NdisWorkItem->Context = Adapter; - - ExInitializeWorkItem(WorkQueueItem, MiniportWorker, NdisWorkItem); - - ExQueueWorkItem(WorkQueueItem, CriticalWorkQueue); - - return NDIS_STATUS_SUCCESS; + KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); } @@ -751,26 +730,22 @@ MiniDequeueWorkItem( */ { PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem; - PNDIS_WORK_ITEM NdisWorkItem; - PWORK_QUEUE_ITEM WorkQueueItem; - + PNDIS_PACKET Packet; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - if (Adapter->MiniportBusy) { - NDIS_DbgPrint(MID_TRACE, ("Waiting for miniport to become free.\n")); - NdisWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_WORK_ITEM)); - if (!NdisWorkItem) return NDIS_STATUS_RESOURCES; - WorkQueueItem = (PWORK_QUEUE_ITEM)NdisWorkItem->WrapperReserved; - NdisWorkItem->Context = Adapter; - ExInitializeWorkItem(WorkQueueItem, MiniportWorker, NdisWorkItem); - ExQueueWorkItem(WorkQueueItem, CriticalWorkQueue); - return NDIS_STATUS_FAILURE; - } - MiniportWorkItem = Adapter->WorkQueueHead; - if (MiniportWorkItem) + if ((Packet = Adapter->NdisMiniportBlock.FirstPendingPacket)) + { + Adapter->NdisMiniportBlock.FirstPendingPacket = NULL; + + *WorkItemType = NdisWorkItemSend; + *WorkItemContext = Packet; + + return NDIS_STATUS_SUCCESS; + } + else if (MiniportWorkItem) { /* safe due to adapter lock held */ Adapter->WorkQueueHead = (PNDIS_MINIPORT_WORK_ITEM)MiniportWorkItem->Link.Next; @@ -783,12 +758,12 @@ MiniDequeueWorkItem( ExFreePool(MiniportWorkItem); - Adapter->MiniportBusy = TRUE; - return NDIS_STATUS_SUCCESS; } - - return NDIS_STATUS_FAILURE; + else + { + return NDIS_STATUS_FAILURE; + } } @@ -809,8 +784,6 @@ MiniDoRequest( KIRQL OldIrql; NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n")); - Adapter->NdisMiniportBlock.MediaRequest = NdisRequest; - KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); switch (NdisRequest->RequestType) { @@ -838,16 +811,31 @@ MiniDoRequest( Status = NDIS_STATUS_FAILURE; } - if (Status == NDIS_STATUS_PENDING) { - KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); - Adapter->MiniportBusy = TRUE; - KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); - } - KeLowerIrql(OldIrql); return Status; } + +/* + * @implemented + */ +#undef NdisMSetInformationComplete +VOID +EXPORT +NdisMSetInformationComplete( + IN NDIS_HANDLE MiniportAdapterHandle, + IN NDIS_STATUS Status) +{ + PLOGICAL_ADAPTER Adapter = + (PLOGICAL_ADAPTER)MiniportAdapterHandle; + KIRQL OldIrql; + ASSERT(Adapter); + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + if (Adapter->NdisMiniportBlock.SetCompleteHandler) + (Adapter->NdisMiniportBlock.SetCompleteHandler)(MiniportAdapterHandle, Status); + KeLowerIrql(OldIrql); +} + /* * @implemented @@ -866,22 +854,22 @@ NdisMQueryInformationComplete( KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); if( Adapter->NdisMiniportBlock.QueryCompleteHandler ) (Adapter->NdisMiniportBlock.QueryCompleteHandler)(MiniportAdapterHandle, Status); - KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); - Adapter->MiniportBusy = FALSE; - KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); KeLowerIrql(OldIrql); } -VOID NTAPI MiniportWorker(IN PVOID WorkItem) +VOID +NTAPI +MiniportWorker(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context) { - PNDIS_WORK_ITEM NdisWorkItem = WorkItem; - PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(NdisWorkItem->Context); + PLOGICAL_ADAPTER Adapter = DeviceObject->DeviceExtension; KIRQL OldIrql, RaiseOldIrql; NDIS_STATUS NdisStatus; PVOID WorkItemContext; NDIS_WORK_ITEM_TYPE WorkItemType; BOOLEAN AddressingReset; + IoFreeWorkItem((PIO_WORKITEM)Context); + KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); NdisStatus = @@ -898,9 +886,7 @@ VOID NTAPI MiniportWorker(IN PVOID WorkItem) /* * called by ProSend when protocols want to send packets to the miniport */ -#ifdef DBG - MiniDisplayPacket((PNDIS_PACKET)WorkItemContext); -#endif + if(Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler) { if(Adapter->NdisMiniportBlock.Flags & NDIS_ATTRIBUTE_DESERIALIZE) @@ -923,9 +909,7 @@ VOID NTAPI MiniportWorker(IN PVOID WorkItem) NdisStatus = NDIS_GET_PACKET_STATUS((PNDIS_PACKET)WorkItemContext); if( NdisStatus == NDIS_STATUS_RESOURCES ) { - KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); - MiniQueueWorkItem(Adapter, WorkItemType, WorkItemContext); - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); + MiniQueueWorkItem(Adapter, WorkItemType, WorkItemContext, TRUE); break; } } @@ -949,9 +933,7 @@ VOID NTAPI MiniportWorker(IN PVOID WorkItem) NDIS_DbgPrint(MAX_TRACE, ("back from miniport's send handler\n")); KeLowerIrql(RaiseOldIrql); if( NdisStatus == NDIS_STATUS_RESOURCES ) { - KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); - MiniQueueWorkItem(Adapter, WorkItemType, WorkItemContext); - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); + MiniQueueWorkItem(Adapter, WorkItemType, WorkItemContext, TRUE); break; } } @@ -1028,14 +1010,6 @@ VOID NTAPI MiniportWorker(IN PVOID WorkItem) break; } } - - if( NdisStatus != NDIS_STATUS_PENDING ) { - KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); - Adapter->MiniportBusy = FALSE; - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); - } - - ExFreePool(WorkItem); } @@ -1434,15 +1408,6 @@ DoQueries( NDIS_DbgPrint(DEBUG_MINIPORT, ("CurLookaheadLength (0x%X).\n", Adapter->NdisMiniportBlock.CurrentLookahead)); - if (Adapter->NdisMiniportBlock.MaximumLookahead != 0) - { - Adapter->LookaheadLength = Adapter->NdisMiniportBlock.MaximumLookahead + Adapter->MediumHeaderSize; - Adapter->LookaheadBuffer = ExAllocatePool(NonPagedPool, Adapter->LookaheadLength); - - if (!Adapter->LookaheadBuffer) - return NDIS_STATUS_RESOURCES; - } - return STATUS_SUCCESS; } @@ -1721,12 +1686,6 @@ NdisIPnPStartDevice( if (NdisStatus != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MAX_TRACE, ("couldn't create filter (%x)\n", NdisStatus)); - if (Adapter->LookaheadBuffer) - { - ExFreePool(Adapter->LookaheadBuffer); - Adapter->LookaheadBuffer = NULL; - } - ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock ); return NdisStatus; } @@ -1764,27 +1723,17 @@ NdisIPnPStopDevice( */ { PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)DeviceObject->DeviceExtension; - KIRQL OldIrql; /* Remove adapter from adapter list for this miniport */ - KeAcquireSpinLock(&Adapter->NdisMiniportBlock.DriverHandle->Lock, &OldIrql); - RemoveEntryList(&Adapter->MiniportListEntry); - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.DriverHandle->Lock, OldIrql); + ExInterlockedRemoveEntryList(&Adapter->MiniportListEntry, &Adapter->NdisMiniportBlock.DriverHandle->Lock); /* Remove adapter from global adapter list */ - KeAcquireSpinLock(&AdapterListLock, &OldIrql); - RemoveEntryList(&Adapter->ListEntry); - KeReleaseSpinLock(&AdapterListLock, OldIrql); + ExInterlockedRemoveEntryList(&Adapter->ListEntry, &AdapterListLock); KeCancelTimer(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Timer); (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.HaltHandler)(Adapter); - if (Adapter->LookaheadBuffer) - { - ExFreePool(Adapter->LookaheadBuffer); - Adapter->LookaheadBuffer = NULL; - } if (Adapter->NdisMiniportBlock.AllocatedResources) { ExFreePool(Adapter->NdisMiniportBlock.AllocatedResources); @@ -2190,29 +2139,6 @@ NdisMTransferDataComplete( MiniTransferDataComplete(MiniportAdapterHandle, Packet, Status, BytesTransferred); } - -/* - * @implemented - */ -#undef NdisMSetInformationComplete -VOID -EXPORT -NdisMSetInformationComplete( - IN NDIS_HANDLE MiniportAdapterHandle, - IN NDIS_STATUS Status) -{ - PLOGICAL_ADAPTER Adapter = - (PLOGICAL_ADAPTER)MiniportAdapterHandle; - KIRQL OldIrql; - ASSERT(Adapter); - KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); - (Adapter->NdisMiniportBlock.SetCompleteHandler)(MiniportAdapterHandle, Status); - KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); - Adapter->MiniportBusy = FALSE; - KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); - KeLowerIrql(OldIrql); -} - /* * @implemented @@ -2385,6 +2311,7 @@ NdisTerminateWrapper( ExFreePool(Miniport->RegistryPath->Buffer); ExFreePool(Miniport->RegistryPath); + ExInterlockedRemoveEntryList(&Miniport->ListEntry, &MiniportListLock); ExFreePool(Miniport); } diff --git a/reactos/drivers/network/ndis/ndis/protocol.c b/reactos/drivers/network/ndis/ndis/protocol.c index 9121f8f1d1f..dbdc2512084 100644 --- a/reactos/drivers/network/ndis/ndis/protocol.c +++ b/reactos/drivers/network/ndis/ndis/protocol.c @@ -20,6 +20,8 @@ LIST_ENTRY ProtocolListHead; KSPIN_LOCK ProtocolListLock; +#define WORKER_TEST 0 + /* * @implemented @@ -68,6 +70,7 @@ ProIndicatePacket( UINT BufferedLength; UINT PacketLength; KIRQL OldIrql; + PUCHAR LookaheadBuffer; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); @@ -75,36 +78,34 @@ ProIndicatePacket( MiniDisplayPacket(Packet); #endif + LookaheadBuffer = ExAllocatePool(NonPagedPool, Adapter->NdisMiniportBlock.CurrentLookahead + Adapter->MediumHeaderSize); + if (!LookaheadBuffer) + return NDIS_STATUS_RESOURCES; + NdisQueryPacket(Packet, NULL, NULL, NULL, &PacketLength); NDIS_DbgPrint(MAX_TRACE, ("acquiring miniport block lock\n")); KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); { - Adapter->NdisMiniportBlock.IndicatedPacket[KeGetCurrentProcessorNumber()] = Packet; - BufferedLength = CopyPacketToBuffer(Adapter->LookaheadBuffer, Packet, 0, Adapter->NdisMiniportBlock.CurrentLookahead); + BufferedLength = CopyPacketToBuffer(LookaheadBuffer, Packet, 0, Adapter->NdisMiniportBlock.CurrentLookahead); } KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); if (BufferedLength > Adapter->MediumHeaderSize) { /* XXX Change this to call SendPackets so we don't have to duplicate this wacky logic */ - MiniIndicateData(Adapter, NULL, Adapter->LookaheadBuffer, Adapter->MediumHeaderSize, - &Adapter->LookaheadBuffer[Adapter->MediumHeaderSize], BufferedLength - Adapter->MediumHeaderSize, + MiniIndicateData(Adapter, NULL, LookaheadBuffer, Adapter->MediumHeaderSize, + &LookaheadBuffer[Adapter->MediumHeaderSize], BufferedLength - Adapter->MediumHeaderSize, PacketLength - Adapter->MediumHeaderSize); } else { - MiniIndicateData(Adapter, NULL, Adapter->LookaheadBuffer, Adapter->MediumHeaderSize, NULL, 0, 0); + MiniIndicateData(Adapter, NULL, LookaheadBuffer, Adapter->MediumHeaderSize, NULL, 0, 0); } - NDIS_DbgPrint(MAX_TRACE, ("acquiring miniport block lock\n")); - KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); - { - Adapter->NdisMiniportBlock.IndicatedPacket[KeGetCurrentProcessorNumber()] = NULL; - } - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); + ExFreePool(LookaheadBuffer); - return STATUS_SUCCESS; + return NDIS_STATUS_SUCCESS; } @@ -121,7 +122,6 @@ ProRequest( * Status of operation */ { - KIRQL OldIrql; PADAPTER_BINDING AdapterBinding; PLOGICAL_ADAPTER Adapter; PNDIS_REQUEST_MAC_BLOCK MacBlock = (PNDIS_REQUEST_MAC_BLOCK)NdisRequest->MacReserved; @@ -136,21 +136,12 @@ ProRequest( MacBlock->Binding = &AdapterBinding->NdisOpenBlock; - /* - * If the miniport is already busy, queue a workitem - */ - NDIS_DbgPrint(MAX_TRACE, ("acquiring miniport block lock\n")); - KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); - { - if (Adapter->MiniportBusy) { - MiniQueueWorkItem(Adapter, NdisWorkItemRequest, (PVOID)NdisRequest); - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); - return NDIS_STATUS_PENDING; - } - } - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); - +#if WORKER_TEST + MiniQueueWorkItem(Adapter, NdisWorkItemRequest, NdisRequest, FALSE); + return NDIS_STATUS_PENDING; +#else return MiniDoRequest(Adapter, NdisRequest); +#endif } @@ -163,6 +154,74 @@ ProReset( return NDIS_STATUS_FAILURE; } +NDIS_STATUS +proSendPacketToMiniport(PLOGICAL_ADAPTER Adapter, PNDIS_PACKET Packet) +{ +#if WORKER_TEST + MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet, FALSE); + return NDIS_STATUS_PENDING; +#else + KIRQL RaiseOldIrql; + NDIS_STATUS NdisStatus; + + if(Adapter->NdisMiniportBlock.FirstPendingPacket) { + MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet, FALSE); + return NDIS_STATUS_PENDING; + } + + if(Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler) + { + if(Adapter->NdisMiniportBlock.Flags & NDIS_ATTRIBUTE_DESERIALIZE) + { + NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's SendPackets handler\n")); + (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler)( + Adapter->NdisMiniportBlock.MiniportAdapterContext, &Packet, 1); + NdisStatus = NDIS_GET_PACKET_STATUS(Packet); + } else { + /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */ + KeRaiseIrql(DISPATCH_LEVEL, &RaiseOldIrql); + { + NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's SendPackets handler\n")); + (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler)( + Adapter->NdisMiniportBlock.MiniportAdapterContext, &Packet, 1); + } + KeLowerIrql(RaiseOldIrql); + + NdisStatus = NDIS_GET_PACKET_STATUS(Packet); + if (NdisStatus == NDIS_STATUS_RESOURCES) { + MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet, TRUE); + NdisStatus = NDIS_STATUS_PENDING; + } + } + + return NdisStatus; + } else { + if(Adapter->NdisMiniportBlock.Flags & NDIS_ATTRIBUTE_DESERIALIZE) + { + NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's Send handler\n")); + NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendHandler)( + Adapter->NdisMiniportBlock.MiniportAdapterContext, Packet, 0); + NDIS_DbgPrint(MAX_TRACE, ("back from miniport's send handler\n")); + } else { + /* Send is called at DISPATCH_LEVEL for all serialized miniports */ + KeRaiseIrql(DISPATCH_LEVEL, &RaiseOldIrql); + NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's Send handler\n")); + NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendHandler)( + Adapter->NdisMiniportBlock.MiniportAdapterContext, Packet, 0); + NDIS_DbgPrint(MAX_TRACE, ("back from miniport's send handler\n")); + KeLowerIrql(RaiseOldIrql); + + if (NdisStatus == NDIS_STATUS_RESOURCES) { + MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet, TRUE); + NdisStatus = NDIS_STATUS_PENDING; + } + } + + return NdisStatus; + } +#endif +} + NDIS_STATUS NTAPI ProSend( @@ -176,15 +235,10 @@ ProSend( * RETURNS: * NDIS_STATUS_SUCCESS if the packet was successfully sent * NDIS_STATUS_PENDING if the miniport was busy or a serialized miniport returned NDIS_STATUS_RESOURCES - * NOTES: - * TODO: - * - Break this up */ { - KIRQL SpinOldIrql, RaiseOldIrql; PADAPTER_BINDING AdapterBinding; PLOGICAL_ADAPTER Adapter; - NDIS_STATUS NdisStatus; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); @@ -210,83 +264,18 @@ ProSend( * this is a loopback frame. */ - KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &SpinOldIrql); - if ((Adapter->NdisMiniportBlock.MacOptions & NDIS_MAC_OPTION_NO_LOOPBACK) && MiniAdapterHasAddress(Adapter, Packet)) { - if(Adapter->MiniportBusy) { - MiniQueueWorkItem(Adapter, NdisWorkItemSendLoopback, Packet); - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, SpinOldIrql); - return NDIS_STATUS_PENDING; - } - - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, SpinOldIrql); - +#if WORKER_TEST + MiniQueueWorkItem(Adapter, NdisWorkItemSendLoopback, Packet, FALSE); + return NDIS_STATUS_PENDING; +#else return ProIndicatePacket(Adapter, Packet); +#endif } else { - if(Adapter->MiniportBusy) { - MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet); - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, SpinOldIrql); - return NDIS_STATUS_PENDING; - } - - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, SpinOldIrql); - - if(Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler) - { - if(Adapter->NdisMiniportBlock.Flags & NDIS_ATTRIBUTE_DESERIALIZE) - { - NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's SendPackets handler\n")); - (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler)( - Adapter->NdisMiniportBlock.MiniportAdapterContext, &Packet, 1); - NdisStatus = NDIS_GET_PACKET_STATUS(Packet); - } else { - /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */ - KeRaiseIrql(DISPATCH_LEVEL, &RaiseOldIrql); - { - NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's SendPackets handler\n")); - (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler)( - Adapter->NdisMiniportBlock.MiniportAdapterContext, &Packet, 1); - } - KeLowerIrql(RaiseOldIrql); - - NdisStatus = NDIS_GET_PACKET_STATUS(Packet); - if( NdisStatus == NDIS_STATUS_RESOURCES ) { - KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &SpinOldIrql); - MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet); - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, SpinOldIrql); - NdisStatus = NDIS_STATUS_PENDING; - } - } - - return NdisStatus; - } else { - if(Adapter->NdisMiniportBlock.Flags & NDIS_ATTRIBUTE_DESERIALIZE) - { - NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's Send handler\n")); - NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendHandler)( - Adapter->NdisMiniportBlock.MiniportAdapterContext, Packet, 0); - NDIS_DbgPrint(MAX_TRACE, ("back from miniport's send handler\n")); - } else { - /* Send is called at DISPATCH_LEVEL for all serialized miniports */ - KeRaiseIrql(DISPATCH_LEVEL, &RaiseOldIrql); - NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's Send handler\n")); - NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendHandler)( - Adapter->NdisMiniportBlock.MiniportAdapterContext, Packet, 0); - NDIS_DbgPrint(MAX_TRACE, ("back from miniport's send handler\n")); - KeLowerIrql(RaiseOldIrql); - if( NdisStatus == NDIS_STATUS_RESOURCES ) { - KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &SpinOldIrql); - MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet); - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, SpinOldIrql); - NdisStatus = NDIS_STATUS_PENDING; - } - } - - return NdisStatus; - } - } + return proSendPacketToMiniport(Adapter, Packet); + } } @@ -432,21 +421,15 @@ NdisCloseAdapter( * NdisBindingHandle = Handle returned by NdisOpenAdapter */ { - KIRQL OldIrql; PADAPTER_BINDING AdapterBinding = GET_ADAPTER_BINDING(NdisBindingHandle); NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); /* Remove from protocol's bound adapters list */ - KeAcquireSpinLock(&AdapterBinding->ProtocolBinding->Lock, &OldIrql); - RemoveEntryList(&AdapterBinding->ProtocolListEntry); - KeReleaseSpinLock(&AdapterBinding->ProtocolBinding->Lock, OldIrql); + ExInterlockedRemoveEntryList(&AdapterBinding->ProtocolListEntry, &AdapterBinding->ProtocolBinding->Lock); /* Remove protocol from adapter's bound protocols list */ - NDIS_DbgPrint(MAX_TRACE, ("acquiring miniport block lock\n")); - KeAcquireSpinLock(&AdapterBinding->Adapter->NdisMiniportBlock.Lock, &OldIrql); - RemoveEntryList(&AdapterBinding->AdapterListEntry); - KeReleaseSpinLock(&AdapterBinding->Adapter->NdisMiniportBlock.Lock, OldIrql); + ExInterlockedRemoveEntryList(&AdapterBinding->AdapterListEntry, &AdapterBinding->Adapter->NdisMiniportBlock.Lock); ExFreePool(AdapterBinding); @@ -469,7 +452,6 @@ NdisDeregisterProtocol( * NdisProtocolHandle = Handle returned by NdisRegisterProtocol */ { - KIRQL OldIrql; PPROTOCOL_BINDING Protocol = GET_PROTOCOL_BINDING(NdisProtocolHandle); NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); @@ -477,9 +459,7 @@ NdisDeregisterProtocol( /* FIXME: Make sure no adapter bindings exist */ /* Remove protocol from global list */ - KeAcquireSpinLock(&ProtocolListLock, &OldIrql); - RemoveEntryList(&Protocol->ListEntry); - KeReleaseSpinLock(&ProtocolListLock, OldIrql); + ExInterlockedRemoveEntryList(&Protocol->ListEntry, &ProtocolListLock); ExFreePool(Protocol); @@ -592,14 +572,9 @@ NdisOpenAdapter( AdapterBinding->NdisOpenBlock.RequestCompleteHandler = Protocol->Chars.RequestCompleteHandler; -#if 0 - /* XXX this looks fishy */ - /* OK, this really *is* fishy - it bugchecks */ /* Put on protocol's bound adapters list */ ExInterlockedInsertTailList(&Protocol->AdapterListHead, &AdapterBinding->ProtocolListEntry, &Protocol->Lock); -#endif - /* XXX so does this */ /* Put protocol on adapter's bound protocols list */ NDIS_DbgPrint(MAX_TRACE, ("acquiring miniport block lock\n")); ExInterlockedInsertTailList(&Adapter->ProtocolListHead, &AdapterBinding->AdapterListEntry, &Adapter->NdisMiniportBlock.Lock); @@ -609,6 +584,152 @@ NdisOpenAdapter( *Status = NDIS_STATUS_SUCCESS; } +VOID +NTAPI +ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics) +{ + /* + * bind the protocol to all of its miniports + * + * open registry path + * get list of devices from Bind key + * call BindAdapterHandler for each + */ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING RegistryPath; + WCHAR *RegistryPathStr; + NTSTATUS NtStatus; + WCHAR *DataPtr; + HANDLE DriverKeyHandle = NULL; + PKEY_VALUE_PARTIAL_INFORMATION KeyInformation = NULL; + + RegistryPathStr = ExAllocatePoolWithTag(PagedPool, sizeof(SERVICES_KEY) + ProtocolCharacteristics->Name.Length + sizeof(LINKAGE_KEY), NDIS_TAG + __LINE__); + if(!RegistryPathStr) + { + NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); + *Status = NDIS_STATUS_RESOURCES; + return; + } + + wcscpy(RegistryPathStr, SERVICES_KEY); + wcsncat(RegistryPathStr, ((WCHAR *)ProtocolCharacteristics->Name.Buffer), ProtocolCharacteristics->Name.Length / sizeof(WCHAR)); + RegistryPathStr[wcslen(SERVICES_KEY)+ProtocolCharacteristics->Name.Length/sizeof(WCHAR)] = 0; + wcscat(RegistryPathStr, LINKAGE_KEY); + + RtlInitUnicodeString(&RegistryPath, RegistryPathStr); + NDIS_DbgPrint(MAX_TRACE, ("Opening configuration key: %wZ\n", &RegistryPath)); + + InitializeObjectAttributes(&ObjectAttributes, &RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL); + NtStatus = ZwOpenKey(&DriverKeyHandle, KEY_READ, &ObjectAttributes); + + ExFreePool(RegistryPathStr); + + if(!NT_SUCCESS(NtStatus)) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to open protocol configuration\n")); + *Status = NDIS_STATUS_FAILURE; + return; + } + + NDIS_DbgPrint(MAX_TRACE, ("Successfully opened the registry configuration\n")); + + { + UNICODE_STRING ValueName; + ULONG ResultLength; + + RtlInitUnicodeString(&ValueName, L"Bind"); + + NtStatus = ZwQueryValueKey(DriverKeyHandle, &ValueName, KeyValuePartialInformation, NULL, 0, &ResultLength); + if(NtStatus != STATUS_BUFFER_OVERFLOW && NtStatus != STATUS_BUFFER_TOO_SMALL && NtStatus != STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to query the Bind value for size\n")); + ZwClose(DriverKeyHandle); + *Status = NDIS_STATUS_FAILURE; + return; + } + + KeyInformation = ExAllocatePoolWithTag(PagedPool, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + ResultLength, NDIS_TAG + __LINE__); + if(!KeyInformation) + { + NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); + ZwClose(DriverKeyHandle); + *Status = NDIS_STATUS_FAILURE; + return; + } + + NtStatus = ZwQueryValueKey(DriverKeyHandle, &ValueName, KeyValuePartialInformation, KeyInformation, + sizeof(KEY_VALUE_PARTIAL_INFORMATION) + ResultLength, &ResultLength); + + ZwClose(DriverKeyHandle); + + if(!NT_SUCCESS(NtStatus)) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to query the Bind value\n")); + ExFreePool(KeyInformation); + *Status = NDIS_STATUS_FAILURE; + return; + } + } + + for (DataPtr = (WCHAR *)KeyInformation->Data; + *DataPtr != 0; + DataPtr += wcslen(DataPtr) + 1) + { + /* BindContext is for tracking pending binding operations */ + VOID *BindContext = 0; + NDIS_STRING DeviceName; + NDIS_STRING RegistryPath; + WCHAR *RegistryPathStr = NULL; + ULONG PathLength = 0; + + RtlInitUnicodeString(&DeviceName, DataPtr); /* we know this is 0-term */ + + /* + * RegistryPath should be: + * \Registry\Machine\System\CurrentControlSet\Services\Nic1\Parameters\Tcpip + * + * This is constructed as follows: + * SERVICES_KEY + extracted device name + Protocol name from characteristics + */ + + PathLength = sizeof(SERVICES_KEY) + /* \Registry\Machine\System\CurrentControlSet\Services\ */ + wcslen( DataPtr + 8 ) * sizeof(WCHAR) + /* Adapter1 (extracted from \Device\Adapter1) */ + sizeof(PARAMETERS_KEY) + /* \Parameters\ */ + ProtocolCharacteristics->Name.Length + sizeof(WCHAR); /* Tcpip */ + + RegistryPathStr = ExAllocatePool(PagedPool, PathLength); + if(!RegistryPathStr) + { + NDIS_DbgPrint(MIN_TRACE, ("insufficient resources.\n")); + ExFreePool(KeyInformation); + *Status = NDIS_STATUS_RESOURCES; + return; + } + + wcscpy(RegistryPathStr, SERVICES_KEY); + wcscat(RegistryPathStr, DataPtr + 8 ); + wcscat(RegistryPathStr, PARAMETERS_KEY); + wcsncat(RegistryPathStr, ProtocolCharacteristics->Name.Buffer, ProtocolCharacteristics->Name.Length / sizeof(WCHAR) ); + + RegistryPathStr[PathLength/sizeof(WCHAR) - 1] = 0; + + RtlInitUnicodeString(&RegistryPath, RegistryPathStr); + + NDIS_DbgPrint(MAX_TRACE, ("Calling protocol's BindAdapter handler with DeviceName %wZ and RegistryPath %wZ\n", + &DeviceName, &RegistryPath)); + + { + BIND_HANDLER BindHandler = ProtocolCharacteristics->BindAdapterHandler; + if(BindHandler) + BindHandler(Status, BindContext, &DeviceName, &RegistryPath, 0); + else + NDIS_DbgPrint(MID_TRACE, ("No protocol bind handler specified\n")); + } + } + + *Status = NDIS_STATUS_SUCCESS; + ExFreePool(KeyInformation); +} /* * @implemented @@ -640,9 +761,6 @@ NdisRegisterProtocol( PPROTOCOL_BINDING Protocol; NTSTATUS NtStatus; UINT MinSize; - HANDLE DriverKeyHandle = NULL; - PKEY_VALUE_PARTIAL_INFORMATION KeyInformation = NULL; - WCHAR *DataPtr; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); @@ -703,172 +821,19 @@ NdisRegisterProtocol( InitializeListHead(&Protocol->AdapterListHead); - /* - * bind the protocol to all of its miniports - * - * open registry path - * get list of devices from Bind key - * call BindAdapterHandler for each - */ - { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING RegistryPath; - WCHAR *RegistryPathStr; + /* We must set this before the call to ndisBindMiniportsToProtocol because the protocol's + * BindAdapter handler might need it */ - RegistryPathStr = ExAllocatePoolWithTag(PagedPool, sizeof(SERVICES_KEY) + ProtocolCharacteristics->Name.Length + sizeof(LINKAGE_KEY), NDIS_TAG + __LINE__); - if(!RegistryPathStr) - { - NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); - ExFreePool(Protocol); - *Status = NDIS_STATUS_RESOURCES; - return; - } + *NdisProtocolHandle = Protocol; - wcscpy(RegistryPathStr, SERVICES_KEY); - wcsncat(RegistryPathStr, ((WCHAR *)ProtocolCharacteristics->Name.Buffer), ProtocolCharacteristics->Name.Length / sizeof(WCHAR)); - RegistryPathStr[wcslen(SERVICES_KEY)+ProtocolCharacteristics->Name.Length/sizeof(WCHAR)] = 0; - wcscat(RegistryPathStr, LINKAGE_KEY); + ndisBindMiniportsToProtocol(Status, &Protocol->Chars); - RtlInitUnicodeString(&RegistryPath, RegistryPathStr); - NDIS_DbgPrint(MAX_TRACE, ("Opening configuration key: %wZ\n", &RegistryPath)); - - InitializeObjectAttributes(&ObjectAttributes, &RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL); - NtStatus = ZwOpenKey(&DriverKeyHandle, KEY_READ, &ObjectAttributes); - - ExFreePool(RegistryPathStr); - - if(!NT_SUCCESS(NtStatus)) - { - NDIS_DbgPrint(MIN_TRACE, ("Unable to open protocol configuration\n")); - ExFreePool(Protocol); - *Status = NDIS_STATUS_FAILURE; - return; - } + if (*Status == NDIS_STATUS_SUCCESS) { + ExInterlockedInsertTailList(&ProtocolListHead, &Protocol->ListEntry, &ProtocolListLock); + } else { + ExFreePool(Protocol); + *NdisProtocolHandle = NULL; } - - NDIS_DbgPrint(MAX_TRACE, ("Successfully opened the registry configuration\n")); - - { - UNICODE_STRING ValueName; - ULONG ResultLength; - - RtlInitUnicodeString(&ValueName, L"Bind"); - - NtStatus = ZwQueryValueKey(DriverKeyHandle, &ValueName, KeyValuePartialInformation, NULL, 0, &ResultLength); - if(NtStatus != STATUS_BUFFER_OVERFLOW && NtStatus != STATUS_BUFFER_TOO_SMALL && NtStatus != STATUS_SUCCESS) - { - NDIS_DbgPrint(MIN_TRACE, ("Unable to query the Bind value for size\n")); - ZwClose(DriverKeyHandle); - ExFreePool(Protocol); - *Status = NDIS_STATUS_FAILURE; - return; - } - - KeyInformation = ExAllocatePoolWithTag(PagedPool, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + ResultLength, NDIS_TAG + __LINE__); - if(!KeyInformation) - { - NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); - ZwClose(DriverKeyHandle); - ExFreePool(Protocol); - *Status = NDIS_STATUS_FAILURE; - return; - } - - NtStatus = ZwQueryValueKey(DriverKeyHandle, &ValueName, KeyValuePartialInformation, KeyInformation, - sizeof(KEY_VALUE_PARTIAL_INFORMATION) + ResultLength, &ResultLength); - - ZwClose(DriverKeyHandle); - - if(!NT_SUCCESS(NtStatus)) - { - NDIS_DbgPrint(MIN_TRACE, ("Unable to query the Bind value\n")); - ExFreePool(KeyInformation); - ExFreePool(Protocol); - *Status = NDIS_STATUS_FAILURE; - return; - } - } - - for (DataPtr = (WCHAR *)KeyInformation->Data; - *DataPtr != 0; - DataPtr += wcslen(DataPtr) + 1) - { - /* BindContext is for tracking pending binding operations */ - VOID *BindContext = 0; - NDIS_STRING DeviceName; - NDIS_STRING RegistryPath; - WCHAR *RegistryPathStr = NULL; - ULONG PathLength = 0; - - RtlInitUnicodeString(&DeviceName, DataPtr); /* we know this is 0-term */ - - /* - * RegistryPath should be: - * \Registry\Machine\System\CurrentControlSet\Services\Nic1\Parameters\Tcpip - * - * This is constructed as follows: - * SERVICES_KEY + extracted device name + Protocol name from characteristics - */ - - PathLength = sizeof(SERVICES_KEY) + /* \Registry\Machine\System\CurrentControlSet\Services\ */ - wcslen( DataPtr + 8 ) * sizeof(WCHAR) + /* Adapter1 (extracted from \Device\Adapter1) */ - sizeof(PARAMETERS_KEY) + /* \Parameters\ */ - ProtocolCharacteristics->Name.Length + sizeof(WCHAR); /* Tcpip */ - - RegistryPathStr = ExAllocatePool(PagedPool, PathLength); - if(!RegistryPathStr) - { - NDIS_DbgPrint(MIN_TRACE, ("insufficient resources.\n")); - ExFreePool(KeyInformation); - ExFreePool(Protocol); - *Status = NDIS_STATUS_RESOURCES; - return; - } - - wcscpy(RegistryPathStr, SERVICES_KEY); - wcscat(RegistryPathStr, DataPtr + 8 ); - wcscat(RegistryPathStr, PARAMETERS_KEY); - wcsncat(RegistryPathStr, ProtocolCharacteristics->Name.Buffer, ProtocolCharacteristics->Name.Length / sizeof(WCHAR) ); - - RegistryPathStr[PathLength/sizeof(WCHAR) - 1] = 0; - - RtlInitUnicodeString(&RegistryPath, RegistryPathStr); - - NDIS_DbgPrint(MAX_TRACE, ("Calling protocol's BindAdapter handler with DeviceName %wZ and RegistryPath %wZ\n", - &DeviceName, &RegistryPath)); - - /* XXX SD must do something with bind context */ - *NdisProtocolHandle = Protocol; - - { - BIND_HANDLER BindHandler = ProtocolCharacteristics->BindAdapterHandler; - if(BindHandler) - BindHandler(Status, BindContext, &DeviceName, &RegistryPath, 0); - else - NDIS_DbgPrint(MID_TRACE, ("No protocol bind handler specified\n")); - } - - /* - (*(Protocol->Chars.BindAdapterHandler))(Status, BindContext, &DeviceName, &RegistryPath, 0); - */ - - if(*Status == NDIS_STATUS_SUCCESS) - { - /* Put protocol binding struct on global list */ - ExInterlockedInsertTailList(&ProtocolListHead, &Protocol->ListEntry, &ProtocolListLock); - } - else if(*Status != NDIS_STATUS_PENDING) - { - NDIS_DbgPrint(MIN_TRACE, ("ProtocolBindAdapter failed with status 0x%x\n", *Status)); - ExFreePool(Protocol); - ExFreePool(KeyInformation); - *NdisProtocolHandle = NULL; - return; - } - } - - ExFreePool(KeyInformation); - *Status = NDIS_STATUS_SUCCESS; } @@ -977,4 +942,17 @@ NdisTransferData( BytesTransferred); } +/* + * @implemented + */ +VOID +NTAPI +NdisReEnumerateProtocolBindings(IN NDIS_HANDLE NdisProtocolHandle) +{ + PPROTOCOL_BINDING Protocol = NdisProtocolHandle; + NDIS_STATUS NdisStatus; + + ndisBindMiniportsToProtocol(&NdisStatus, &Protocol->Chars); +} + /* EOF */ diff --git a/reactos/drivers/network/ndis/ndis/stubs.c b/reactos/drivers/network/ndis/ndis/stubs.c index 8df99d38cbb..df275c803c2 100644 --- a/reactos/drivers/network/ndis/ndis/stubs.c +++ b/reactos/drivers/network/ndis/ndis/stubs.c @@ -1063,13 +1063,3 @@ NdisScheduleWorkItem( ExQueueWorkItem(pntWorkItem, CriticalWorkQueue); return NDIS_STATUS_SUCCESS; } - -/* - * @unimplemented - */ -VOID -NTAPI -NdisReEnumerateProtocolBindings(IN NDIS_HANDLE NdisProtocolHandle) -{ - UNIMPLEMENTED; -} diff --git a/reactos/lib/drivers/ip/network/loopback.c b/reactos/lib/drivers/ip/network/loopback.c index acb227ddef5..c95ee89a1b4 100644 --- a/reactos/lib/drivers/ip/network/loopback.c +++ b/reactos/lib/drivers/ip/network/loopback.c @@ -22,7 +22,6 @@ typedef struct _LAN_WQ_ITEM { KSPIN_LOCK LoopWorkLock; LIST_ENTRY LoopWorkList; WORK_QUEUE_ITEM LoopWorkItem; -BOOLEAN LoopReceiveWorkerBusy = FALSE; VOID STDCALL LoopReceiveWorker( PVOID Context ) { PLIST_ENTRY ListEntry; @@ -35,46 +34,43 @@ VOID STDCALL LoopReceiveWorker( PVOID Context ) { TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); - while( (ListEntry = - ExInterlockedRemoveHeadList( &LoopWorkList, &LoopWorkLock )) ) { - WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry); + ListEntry = ExInterlockedRemoveHeadList( &LoopWorkList, &LoopWorkLock ); + WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry); - TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem)); + TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem)); - Packet = WorkItem->Packet; - Adapter = WorkItem->Adapter; - BytesTransferred = WorkItem->BytesTransferred; + Packet = WorkItem->Packet; + Adapter = WorkItem->Adapter; + BytesTransferred = WorkItem->BytesTransferred; - ExFreePool( WorkItem ); + ExFreePool( WorkItem ); - IPPacket.NdisPacket = Packet; + IPPacket.NdisPacket = Packet; - TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x Trans %x\n", - Packet, Adapter, BytesTransferred)); + TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x Trans %x\n", + Packet, Adapter, BytesTransferred)); - NdisGetFirstBufferFromPacket(Packet, - &NdisBuffer, - &IPPacket.Header, - &IPPacket.ContigSize, - &IPPacket.TotalSize); + NdisGetFirstBufferFromPacket(Packet, + &NdisBuffer, + &IPPacket.Header, + &IPPacket.ContigSize, + &IPPacket.TotalSize); - IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred; - /* Determine which upper layer protocol that should receive - this packet and pass it to the correct receive handler */ + IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred; + /* Determine which upper layer protocol that should receive + this packet and pass it to the correct receive handler */ - TI_DbgPrint(MID_TRACE, - ("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n", - IPPacket.ContigSize, IPPacket.TotalSize, - BytesTransferred)); + TI_DbgPrint(MID_TRACE, + ("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n", + IPPacket.ContigSize, IPPacket.TotalSize, + BytesTransferred)); - IPPacket.Position = 0; + IPPacket.Position = 0; - IPReceive(Loopback, &IPPacket); + IPReceive(Loopback, &IPPacket); - FreeNdisPacket( Packet ); - } + FreeNdisPacket( Packet ); TI_DbgPrint(DEBUG_DATALINK, ("Leaving\n")); - LoopReceiveWorkerBusy = FALSE; } VOID LoopSubmitReceiveWork( @@ -84,34 +80,19 @@ VOID LoopSubmitReceiveWork( UINT BytesTransferred) { PLAN_WQ_ITEM WQItem; PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext; - KIRQL OldIrql; - - TcpipAcquireSpinLock( &LoopWorkLock, &OldIrql ); WQItem = ExAllocatePool( NonPagedPool, sizeof(LAN_WQ_ITEM) ); - if( !WQItem ) { - TcpipReleaseSpinLock( &LoopWorkLock, OldIrql ); - return; - } + if( !WQItem ) return; WQItem->Packet = Packet; WQItem->Adapter = Adapter; WQItem->BytesTransferred = BytesTransferred; - InsertTailList( &LoopWorkList, &WQItem->ListEntry ); + ExInterlockedInsertTailList( &LoopWorkList, &WQItem->ListEntry, &LoopWorkLock ); TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x BytesTrans %x\n", Packet, Adapter, BytesTransferred)); - if( !LoopReceiveWorkerBusy ) { - LoopReceiveWorkerBusy = TRUE; - ExQueueWorkItem( &LoopWorkItem, CriticalWorkQueue ); - TI_DbgPrint(DEBUG_DATALINK, - ("Work item inserted %x %x\n", &LoopWorkItem, WQItem)); - } else { - TI_DbgPrint(DEBUG_DATALINK, - ("LOOP WORKER BUSY %x %x\n", &LoopWorkItem, WQItem)); - } - TcpipReleaseSpinLock( &LoopWorkLock, OldIrql ); + ExQueueWorkItem( &LoopWorkItem, CriticalWorkQueue ); } VOID LoopTransmit( diff --git a/reactos/lib/drivers/ip/transport/datagram/datagram.c b/reactos/lib/drivers/ip/transport/datagram/datagram.c index 8f4d81ba1ba..303b755d86e 100644 --- a/reactos/lib/drivers/ip/transport/datagram/datagram.c +++ b/reactos/lib/drivers/ip/transport/datagram/datagram.c @@ -16,10 +16,13 @@ VOID DGRemoveIRP( { PLIST_ENTRY ListEntry; PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; + KIRQL OldIrql; TI_DbgPrint(MAX_TRACE, ("Called (Cancel IRP %08x for file %08x).\n", Irp, AddrFile)); + KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + for( ListEntry = AddrFile->ReceiveQueue.Flink; ListEntry != &AddrFile->ReceiveQueue; ListEntry = ListEntry->Flink ) @@ -37,6 +40,8 @@ VOID DGRemoveIRP( } } + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + TI_DbgPrint(MAX_TRACE, ("Done.\n")); }