[NDISUIO]

- Fix a race condition during adapter context destruction
- Add missing IRP completion in IRP_MJ_READ and IRP_MJ_WRITE handlers
- Create an adapter context in response to PnP events

svn path=/branches/wlan-bringup/; revision=54816
This commit is contained in:
Cameron Gutman 2012-01-03 16:08:24 +00:00
parent 80c1df8be2
commit 93d3b91947
3 changed files with 28 additions and 21 deletions

View file

@ -126,6 +126,7 @@ OpenDeviceReadWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp)
NTSTATUS Status; NTSTATUS Status;
PNDISUIO_ADAPTER_CONTEXT AdapterContext; PNDISUIO_ADAPTER_CONTEXT AdapterContext;
PNDISUIO_OPEN_ENTRY OpenEntry; PNDISUIO_OPEN_ENTRY OpenEntry;
KIRQL OldIrql;
NameLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength; NameLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
if (NameLength != 0) if (NameLength != 0)
@ -135,16 +136,17 @@ OpenDeviceReadWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp)
/* Check if this already has a context */ /* Check if this already has a context */
AdapterContext = FindAdapterContextByName(&DeviceName); AdapterContext = FindAdapterContextByName(&DeviceName);
if (AdapterContext == NULL) if (AdapterContext != NULL)
{ {
/* Create a new context */ /* Reference the adapter context */
Status = BindAdapterByName(&DeviceName, &AdapterContext); KeAcquireSpinLock(&AdapterContext->Spinlock, &OldIrql);
ReferenceAdapterContext(AdapterContext);
Status = STATUS_SUCCESS;
} }
else else
{ {
/* Reference the existing context */ /* Invalid device name */
ReferenceAdapterContext(AdapterContext, FALSE); Status = STATUS_INVALID_PARAMETER;
Status = STATUS_SUCCESS;
} }
/* Check that the bind succeeded */ /* Check that the bind succeeded */
@ -161,24 +163,25 @@ OpenDeviceReadWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp)
FileObject->FsContext2 = OpenEntry; FileObject->FsContext2 = OpenEntry;
/* Add it to the adapter's list */ /* Add it to the adapter's list */
ExInterlockedInsertTailList(&AdapterContext->OpenEntryList, InsertTailList(&AdapterContext->OpenEntryList,
&OpenEntry->ListEntry, &OpenEntry->ListEntry);
&AdapterContext->Spinlock);
/* Success */ /* Success */
KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql);
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
else else
{ {
/* Remove the reference we added */ /* Remove the reference we added */
KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql);
DereferenceAdapterContext(AdapterContext, NULL); DereferenceAdapterContext(AdapterContext, NULL);
Status = STATUS_NO_MEMORY; Status = STATUS_NO_MEMORY;
} }
} }
} }
else else
{ {
/* Invalid device name */
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
} }

View file

@ -135,6 +135,11 @@ UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext)
PLIST_ENTRY CurrentOpenEntry; PLIST_ENTRY CurrentOpenEntry;
PNDISUIO_OPEN_ENTRY OpenEntry; PNDISUIO_OPEN_ENTRY OpenEntry;
/* Remove the adapter context from the global list */
KeAcquireSpinLock(&GlobalAdapterListLock, &OldIrql);
RemoveEntryList(&AdapterContext->ListEntry);
KeReleaseSpinLock(&GlobalAdapterListLock, OldIrql);
/* Invalidate all handles to this adapter */ /* Invalidate all handles to this adapter */
CurrentOpenEntry = AdapterContext->OpenEntryList.Flink; CurrentOpenEntry = AdapterContext->OpenEntryList.Flink;
while (CurrentOpenEntry != &AdapterContext->OpenEntryList) while (CurrentOpenEntry != &AdapterContext->OpenEntryList)
@ -163,11 +168,6 @@ UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext)
/* If this fails, we have a refcount mismatch somewhere */ /* If this fails, we have a refcount mismatch somewhere */
ASSERT(AdapterContext->OpenCount == 0); ASSERT(AdapterContext->OpenCount == 0);
/* Remove the adapter context from the global list */
KeAcquireSpinLock(&GlobalAdapterListLock, &OldIrql);
RemoveEntryList(&AdapterContext->ListEntry);
KeReleaseSpinLock(&GlobalAdapterListLock, OldIrql);
/* Send the close request */ /* Send the close request */
NdisCloseAdapter(Status, NdisCloseAdapter(Status,
AdapterContext->BindingHandle); AdapterContext->BindingHandle);
@ -209,7 +209,7 @@ BindAdapterByName(PNDIS_STRING DeviceName, PNDISUIO_ADAPTER_CONTEXT *Context)
KeInitializeSpinLock(&AdapterContext->Spinlock); KeInitializeSpinLock(&AdapterContext->Spinlock);
InitializeListHead(&AdapterContext->PacketList); InitializeListHead(&AdapterContext->PacketList);
InitializeListHead(&AdapterContext->OpenEntryList); InitializeListHead(&AdapterContext->OpenEntryList);
AdapterContext->OpenCount = 1; AdapterContext->OpenCount = 0;
/* Send the open request */ /* Send the open request */
NdisOpenAdapter(&Status, NdisOpenAdapter(&Status,
@ -261,8 +261,8 @@ NduBindAdapter(PNDIS_STATUS Status,
PVOID SystemSpecific1, PVOID SystemSpecific1,
PVOID SystemSpecific2) PVOID SystemSpecific2)
{ {
/* We don't bind like this */ /* Use our helper function to create a context for this adapter */
*Status = NDIS_STATUS_SUCCESS; *Status = BindAdapterByName(DeviceName);
} }
VOID VOID

View file

@ -22,6 +22,8 @@ NduDispatchRead(PDEVICE_OBJECT DeviceObject,
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
} }
@ -36,5 +38,7 @@ NduDispatchWrite(PDEVICE_OBJECT DeviceObject,
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
} }