- Merge aicom-network-fixes up to r37556

svn path=/trunk/; revision=37559
This commit is contained in:
Cameron Gutman
2008-11-22 17:02:56 +00:00
parent 07019b1508
commit 438ac1d7da
10 changed files with 430 additions and 537 deletions
+1 -1
View File
@@ -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 );
}
+12 -7
View File
@@ -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;
}
@@ -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(
+1 -1
View File
@@ -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));
+22 -15
View File
@@ -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)
{
+91 -164
View File
@@ -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);
}
+264 -286
View File
@@ -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 */
-10
View File
@@ -1063,13 +1063,3 @@ NdisScheduleWorkItem(
ExQueueWorkItem(pntWorkItem, CriticalWorkQueue);
return NDIS_STATUS_SUCCESS;
}
/*
* @unimplemented
*/
VOID
NTAPI
NdisReEnumerateProtocolBindings(IN NDIS_HANDLE NdisProtocolHandle)
{
UNIMPLEMENTED;
}
+28 -47
View File
@@ -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(
@@ -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"));
}