mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
- Merge aicom-network-fixes up to r37556
svn path=/trunk/; revision=37559
This commit is contained in:
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -1063,13 +1063,3 @@ NdisScheduleWorkItem(
|
||||
ExQueueWorkItem(pntWorkItem, CriticalWorkQueue);
|
||||
return NDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
NdisReEnumerateProtocolBindings(IN NDIS_HANDLE NdisProtocolHandle)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user