From d665699beea1e00756ab8c786ef6b1db2737f309 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 6 Jan 2012 19:43:15 +0000 Subject: [PATCH] [NDISUIO] - Bug fixes - Make the packet and buffer pools per adapter - Crashes during bind for some reason svn path=/branches/wlan-bringup/; revision=54855 --- boot/bootdata/packages/reactos.dff | 1 + drivers/network/ndisuio/main.c | 30 ----------- drivers/network/ndisuio/misc.c | 17 ++++-- drivers/network/ndisuio/ndisuio.h | 12 +++-- drivers/network/ndisuio/protocol.c | 80 +++++++++++++++++++++++++---- drivers/network/ndisuio/readwrite.c | 5 +- 6 files changed, 94 insertions(+), 51 deletions(-) diff --git a/boot/bootdata/packages/reactos.dff b/boot/bootdata/packages/reactos.dff index c68046d8e59..7bde2d9bc98 100644 --- a/boot/bootdata/packages/reactos.dff +++ b/boot/bootdata/packages/reactos.dff @@ -532,6 +532,7 @@ drivers\network\tcpip\tcpip.sys 2 drivers\network\tdi\tdi.sys 2 drivers\network\dd\ne2000\ne2000.sys 2 drivers\network\dd\pcnet\pcnet.sys 2 +drivers\network\ndisuio\ndisuio.sys 2 drivers\serial\serenum\serenum.sys 2 drivers\serial\serial\serial.sys 2 diff --git a/drivers/network/ndisuio/main.c b/drivers/network/ndisuio/main.c index 346be15af32..9b34926cd20 100644 --- a/drivers/network/ndisuio/main.c +++ b/drivers/network/ndisuio/main.c @@ -15,8 +15,6 @@ PDEVICE_OBJECT GlobalDeviceObject; NDIS_HANDLE GlobalProtocolHandle; KSPIN_LOCK GlobalAdapterListLock; LIST_ENTRY GlobalAdapterList; -NDIS_HANDLE GlobalPacketPoolHandle; -NDIS_HANDLE GlobalBufferPoolHandle; NDIS_STRING ProtocolName = RTL_CONSTANT_STRING(L"NDISUIO"); @@ -70,32 +68,6 @@ DriverEntry(PDRIVER_OBJECT DriverObject, return Status; } - /* Create the buffer pool */ - NdisAllocateBufferPool(&Status, - &GlobalBufferPoolHandle, - 100); - if (Status != NDIS_STATUS_SUCCESS) - { - DPRINT1("Failed to allocate buffer pool with status 0x%x\n", Status); - IoDeleteSymbolicLink(&DosDeviceName); - IoDeleteDevice(GlobalDeviceObject); - return Status; - } - - /* Create the packet pool */ - NdisAllocatePacketPool(&Status, - &GlobalPacketPoolHandle, - 50, - 0); - if (Status != NDIS_STATUS_SUCCESS) - { - DPRINT1("Failed to allocate packet pool with status 0x%x\n", Status); - NdisFreeBufferPool(GlobalBufferPoolHandle); - IoDeleteSymbolicLink(&DosDeviceName); - IoDeleteDevice(GlobalDeviceObject); - return Status; - } - /* Register the protocol with NDIS */ RtlZeroMemory(&Chars, sizeof(Chars)); Chars.MajorNdisVersion = NDIS_MAJOR_VERSION; @@ -121,8 +93,6 @@ DriverEntry(PDRIVER_OBJECT DriverObject, if (Status != NDIS_STATUS_SUCCESS) { DPRINT1("Failed to register protocol with status 0x%x\n", Status); - NdisFreePacketPool(GlobalPacketPoolHandle); - NdisFreeBufferPool(GlobalBufferPoolHandle); IoDeleteSymbolicLink(&DosDeviceName); IoDeleteDevice(GlobalDeviceObject); return Status; diff --git a/drivers/network/ndisuio/misc.c b/drivers/network/ndisuio/misc.c index b8a9c0aceb4..43552cb9fa0 100644 --- a/drivers/network/ndisuio/misc.c +++ b/drivers/network/ndisuio/misc.c @@ -12,7 +12,11 @@ #include NDIS_STATUS -AllocateAndChainBuffer(PNDIS_PACKET Packet, PVOID Buffer, ULONG BufferSize, BOOLEAN Front) +AllocateAndChainBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext, + PNDIS_PACKET Packet, + PVOID Buffer, + ULONG BufferSize, + BOOLEAN Front) { NDIS_STATUS Status; PNDIS_BUFFER NdisBuffer; @@ -20,7 +24,7 @@ AllocateAndChainBuffer(PNDIS_PACKET Packet, PVOID Buffer, ULONG BufferSize, BOOL /* Allocate the NDIS buffer mapping the pool */ NdisAllocateBuffer(&Status, &NdisBuffer, - GlobalBufferPoolHandle, + AdapterContext->BufferPoolHandle, Buffer, BufferSize); if (Status != NDIS_STATUS_SUCCESS) @@ -45,7 +49,9 @@ AllocateAndChainBuffer(PNDIS_PACKET Packet, PVOID Buffer, ULONG BufferSize, BOOL } PNDIS_PACKET -CreatePacketFromPoolBuffer(PVOID Buffer, ULONG BufferSize) +CreatePacketFromPoolBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext, + PVOID Buffer, + ULONG BufferSize) { PNDIS_PACKET Packet; NDIS_STATUS Status; @@ -53,7 +59,7 @@ CreatePacketFromPoolBuffer(PVOID Buffer, ULONG BufferSize) /* Allocate a packet descriptor */ NdisAllocatePacket(&Status, &Packet, - GlobalPacketPoolHandle); + AdapterContext->PacketPoolHandle); if (Status != NDIS_STATUS_SUCCESS) { DPRINT1("No free packet descriptors\n"); @@ -61,7 +67,8 @@ CreatePacketFromPoolBuffer(PVOID Buffer, ULONG BufferSize) } /* Use the helper to chain the buffer */ - Status = AllocateAndChainBuffer(Packet, Buffer, BufferSize, TRUE); + Status = AllocateAndChainBuffer(AdapterContext, Packet, + Buffer, BufferSize, TRUE); if (Status != NDIS_STATUS_SUCCESS) { NdisFreePacket(Packet); diff --git a/drivers/network/ndisuio/ndisuio.h b/drivers/network/ndisuio/ndisuio.h index 44d40681edd..c5976e5b1dc 100644 --- a/drivers/network/ndisuio/ndisuio.h +++ b/drivers/network/ndisuio/ndisuio.h @@ -15,8 +15,6 @@ extern PDEVICE_OBJECT GlobalDeviceObject; extern NDIS_HANDLE GlobalProtocolHandle; extern LIST_ENTRY GlobalAdapterList; extern KSPIN_LOCK GlobalAdapterListLock; -extern NDIS_HANDLE GlobalPacketPoolHandle; -extern NDIS_HANDLE GlobalBufferPoolHandle; typedef struct _NDISUIO_ADAPTER_CONTEXT { @@ -30,6 +28,10 @@ typedef struct _NDISUIO_ADAPTER_CONTEXT /* Reference count information */ ULONG OpenCount; LIST_ENTRY OpenEntryList; + + /* NDIS pools */ + NDIS_HANDLE PacketPoolHandle; + NDIS_HANDLE BufferPoolHandle; /* Receive packet list */ LIST_ENTRY PacketList; @@ -92,13 +94,15 @@ NduDispatchDeviceControl(PDEVICE_OBJECT DeviceObject, /* misc.c */ NDIS_STATUS -AllocateAndChainBuffer(PNDIS_PACKET Packet, +AllocateAndChainBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext, + PNDIS_PACKET Packet, PVOID Buffer, ULONG BufferSize, BOOLEAN Front); PNDIS_PACKET -CreatePacketFromPoolBuffer(PVOID Buffer, +CreatePacketFromPoolBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext, + PVOID Buffer, ULONG BufferSize); VOID diff --git a/drivers/network/ndisuio/protocol.c b/drivers/network/ndisuio/protocol.c index 9e043e6cf4f..5910207221d 100644 --- a/drivers/network/ndisuio/protocol.c +++ b/drivers/network/ndisuio/protocol.c @@ -8,7 +8,7 @@ #include "ndisuio.h" -#define NDEBUG +//#define NDEBUG #include PNDIS_MEDIUM SupportedMedia = {NdisMedium802_3}; @@ -119,13 +119,20 @@ NduReceive(NDIS_HANDLE ProtocolBindingContext, NDIS_STATUS Status; UINT BytesTransferred; + DPRINT("Received a %d byte packet on %wZ\n", PacketSize + HeaderBufferSize, &AdapterContext->DeviceName); + + /* Discard if nobody is waiting for it */ + if (AdapterContext->OpenCount == 0) + return NDIS_STATUS_NOT_ACCEPTED; + /* Allocate a buffer to hold the packet data and header */ PacketBuffer = ExAllocatePool(NonPagedPool, PacketSize); if (!PacketBuffer) return NDIS_STATUS_NOT_ACCEPTED; /* Allocate the packet descriptor and buffer */ - Packet = CreatePacketFromPoolBuffer((PUCHAR)PacketBuffer + HeaderBufferSize, + Packet = CreatePacketFromPoolBuffer(AdapterContext, + (PUCHAR)PacketBuffer + HeaderBufferSize, PacketSize); if (!Packet) { @@ -221,20 +228,28 @@ NDIS_STATUS UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext) { KIRQL OldIrql; - PLIST_ENTRY CurrentOpenEntry; + PLIST_ENTRY CurrentEntry; PNDISUIO_OPEN_ENTRY OpenEntry; + PNDISUIO_PACKET_ENTRY PacketEntry; NDIS_STATUS Status; + DPRINT("Unbinding adapter %wZ\n", &AdapterContext->DeviceName); + + /* FIXME: We don't do anything with outstanding reads */ + /* Remove the adapter context from the global list */ KeAcquireSpinLock(&GlobalAdapterListLock, &OldIrql); RemoveEntryList(&AdapterContext->ListEntry); KeReleaseSpinLock(&GlobalAdapterListLock, OldIrql); + + /* Free the device name string */ + RtlFreeUnicodeString(&AdapterContext->DeviceName); /* Invalidate all handles to this adapter */ - CurrentOpenEntry = AdapterContext->OpenEntryList.Flink; - while (CurrentOpenEntry != &AdapterContext->OpenEntryList) + CurrentEntry = AdapterContext->OpenEntryList.Flink; + while (CurrentEntry != &AdapterContext->OpenEntryList) { - OpenEntry = CONTAINING_RECORD(CurrentOpenEntry, NDISUIO_OPEN_ENTRY, ListEntry); + OpenEntry = CONTAINING_RECORD(CurrentEntry, NDISUIO_OPEN_ENTRY, ListEntry); /* Make sure the entry is sane */ ASSERT(OpenEntry->FileObject); @@ -249,7 +264,7 @@ UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext) OpenEntry->FileObject->FsContext2 = NULL; /* Move to the next entry */ - CurrentOpenEntry = CurrentOpenEntry->Flink; + CurrentEntry = CurrentEntry->Flink; /* Free the open entry */ ExFreePool(OpenEntry); @@ -258,6 +273,19 @@ UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext) /* If this fails, we have a refcount mismatch somewhere */ ASSERT(AdapterContext->OpenCount == 0); + /* Free all pending packet entries */ + CurrentEntry = AdapterContext->PacketList.Flink; + while (CurrentEntry != &AdapterContext->PacketList) + { + PacketEntry = CONTAINING_RECORD(CurrentEntry, NDISUIO_PACKET_ENTRY, ListEntry); + + /* Move to the next entry */ + CurrentEntry = CurrentEntry->Flink; + + /* Free the packet entry */ + ExFreePool(PacketEntry); + } + /* Send the close request */ NdisCloseAdapter(&Status, AdapterContext->BindingHandle); @@ -288,6 +316,8 @@ BindAdapterByName(PNDIS_STRING DeviceName) UINT SelectedMedium; NDIS_STATUS Status; + DPRINT("Binding adapter %wZ\n", &AdapterContext->DeviceName); + /* Allocate the adapter context */ AdapterContext = ExAllocatePool(NonPagedPool, sizeof(*AdapterContext)); if (!AdapterContext) @@ -313,15 +343,42 @@ BindAdapterByName(PNDIS_STRING DeviceName) return NDIS_STATUS_RESOURCES; } + /* Copy the device name into the adapter context */ RtlCopyMemory(AdapterContext->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length); - + + /* Create the buffer pool */ + NdisAllocateBufferPool(&Status, + &AdapterContext->BufferPoolHandle, + 50); + if (Status != NDIS_STATUS_SUCCESS) + { + DPRINT1("Failed to allocate buffer pool with status 0x%x\n", Status); + RtlFreeUnicodeString(&AdapterContext->DeviceName); + ExFreePool(AdapterContext); + return Status; + } + + /* Create the packet pool */ + NdisAllocatePacketPool(&Status, + &AdapterContext->PacketPoolHandle, + 25, + PROTOCOL_RESERVED_SIZE_IN_PACKET); + if (Status != NDIS_STATUS_SUCCESS) + { + DPRINT1("Failed to allocate packet pool with status 0x%x\n", Status); + NdisFreeBufferPool(AdapterContext->BufferPoolHandle); + RtlFreeUnicodeString(&AdapterContext->DeviceName); + ExFreePool(AdapterContext); + return Status; + } + /* Send the open request */ NdisOpenAdapter(&Status, &OpenErrorStatus, &AdapterContext->BindingHandle, &SelectedMedium, - SupportedMedia, - sizeof(SupportedMedia), + &SupportedMedia[0], + 1, GlobalProtocolHandle, AdapterContext, DeviceName, @@ -343,6 +400,9 @@ BindAdapterByName(PNDIS_STRING DeviceName) if (Status != NDIS_STATUS_SUCCESS) { DPRINT1("Failed to open adapter for bind with status 0x%x\n", Status); + NdisFreePacketPool(AdapterContext->PacketPoolHandle); + NdisFreeBufferPool(AdapterContext->BufferPoolHandle); + RtlFreeUnicodeString(&AdapterContext->DeviceName); ExFreePool(AdapterContext); return Status; } diff --git a/drivers/network/ndisuio/readwrite.c b/drivers/network/ndisuio/readwrite.c index d96111a0ae9..ceae632c156 100644 --- a/drivers/network/ndisuio/readwrite.c +++ b/drivers/network/ndisuio/readwrite.c @@ -167,7 +167,8 @@ NduDispatchWrite(PDEVICE_OBJECT DeviceObject, ASSERT(DeviceObject == GlobalDeviceObject); /* Create a packet and buffer descriptor for this user buffer */ - Packet = CreatePacketFromPoolBuffer(Irp->AssociatedIrp.SystemBuffer, + Packet = CreatePacketFromPoolBuffer(AdapterContext, + Irp->AssociatedIrp.SystemBuffer, IrpSp->Parameters.Write.Length); if (Packet) { @@ -191,7 +192,7 @@ NduDispatchWrite(PDEVICE_OBJECT DeviceObject, if (Status == NDIS_STATUS_SUCCESS) BytesCopied = IrpSp->Parameters.Write.Length; - CleanupAndFreePacket(Packet, TRUE); + CleanupAndFreePacket(Packet, FALSE); } else {