From 93d3b91947258ece499d9489a3f7df0fea346116 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 3 Jan 2012 16:08:24 +0000 Subject: [PATCH] [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 --- drivers/network/ndisuio/ioctl.c | 23 +++++++++++++---------- drivers/network/ndisuio/protocol.c | 16 ++++++++-------- drivers/network/ndisuio/readwrite.c | 10 +++++++--- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/drivers/network/ndisuio/ioctl.c b/drivers/network/ndisuio/ioctl.c index 25fb18be2fc..91665eb3951 100644 --- a/drivers/network/ndisuio/ioctl.c +++ b/drivers/network/ndisuio/ioctl.c @@ -126,6 +126,7 @@ OpenDeviceReadWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp) NTSTATUS Status; PNDISUIO_ADAPTER_CONTEXT AdapterContext; PNDISUIO_OPEN_ENTRY OpenEntry; + KIRQL OldIrql; NameLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength; if (NameLength != 0) @@ -135,16 +136,17 @@ OpenDeviceReadWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp) /* Check if this already has a context */ AdapterContext = FindAdapterContextByName(&DeviceName); - if (AdapterContext == NULL) + if (AdapterContext != NULL) { - /* Create a new context */ - Status = BindAdapterByName(&DeviceName, &AdapterContext); + /* Reference the adapter context */ + KeAcquireSpinLock(&AdapterContext->Spinlock, &OldIrql); + ReferenceAdapterContext(AdapterContext); + Status = STATUS_SUCCESS; } else { - /* Reference the existing context */ - ReferenceAdapterContext(AdapterContext, FALSE); - Status = STATUS_SUCCESS; + /* Invalid device name */ + Status = STATUS_INVALID_PARAMETER; } /* Check that the bind succeeded */ @@ -161,24 +163,25 @@ OpenDeviceReadWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp) FileObject->FsContext2 = OpenEntry; /* Add it to the adapter's list */ - ExInterlockedInsertTailList(&AdapterContext->OpenEntryList, - &OpenEntry->ListEntry, - &AdapterContext->Spinlock); + InsertTailList(&AdapterContext->OpenEntryList, + &OpenEntry->ListEntry); /* Success */ + KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql); Status = STATUS_SUCCESS; } else { /* Remove the reference we added */ + KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql); DereferenceAdapterContext(AdapterContext, NULL); - Status = STATUS_NO_MEMORY; } } } else { + /* Invalid device name */ Status = STATUS_INVALID_PARAMETER; } diff --git a/drivers/network/ndisuio/protocol.c b/drivers/network/ndisuio/protocol.c index a50c83ee8fb..f95cf63e918 100644 --- a/drivers/network/ndisuio/protocol.c +++ b/drivers/network/ndisuio/protocol.c @@ -135,6 +135,11 @@ UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext) PLIST_ENTRY CurrentOpenEntry; 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 */ CurrentOpenEntry = AdapterContext->OpenEntryList.Flink; while (CurrentOpenEntry != &AdapterContext->OpenEntryList) @@ -163,11 +168,6 @@ UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext) /* If this fails, we have a refcount mismatch somewhere */ 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 */ NdisCloseAdapter(Status, AdapterContext->BindingHandle); @@ -209,7 +209,7 @@ BindAdapterByName(PNDIS_STRING DeviceName, PNDISUIO_ADAPTER_CONTEXT *Context) KeInitializeSpinLock(&AdapterContext->Spinlock); InitializeListHead(&AdapterContext->PacketList); InitializeListHead(&AdapterContext->OpenEntryList); - AdapterContext->OpenCount = 1; + AdapterContext->OpenCount = 0; /* Send the open request */ NdisOpenAdapter(&Status, @@ -261,8 +261,8 @@ NduBindAdapter(PNDIS_STATUS Status, PVOID SystemSpecific1, PVOID SystemSpecific2) { - /* We don't bind like this */ - *Status = NDIS_STATUS_SUCCESS; + /* Use our helper function to create a context for this adapter */ + *Status = BindAdapterByName(DeviceName); } VOID diff --git a/drivers/network/ndisuio/readwrite.c b/drivers/network/ndisuio/readwrite.c index a37872bd045..d726ef06213 100644 --- a/drivers/network/ndisuio/readwrite.c +++ b/drivers/network/ndisuio/readwrite.c @@ -17,11 +17,13 @@ NduDispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) { ASSERT(DeviceObject == GlobalDeviceObject); - + /* FIXME: Not implemented */ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Information = 0; - + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; } @@ -35,6 +37,8 @@ NduDispatchWrite(PDEVICE_OBJECT DeviceObject, /* FIXME: Not implemented */ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Information = 0; - + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; } \ No newline at end of file -- 2.17.1