Author: cgutman Date: Tue Jan 3 18:12:29 2012 New Revision: 54819
URL: http://svn.reactos.org/svn/reactos?rev=54819&view=rev Log: [NDISUIO] - Handle IOCTL_NDISUIO_OPEN_WRITE_DEVICE and IOCTL_NDISUIO_OPEN_DEVICE properly with regard to current open handles - Check that we have read permissions (opened by IOCTL_NDISUIO_OPEN_DEVICE) before allowing queries or reads
Modified: branches/wlan-bringup/drivers/network/ndisuio/ioctl.c branches/wlan-bringup/drivers/network/ndisuio/ndisuio.h branches/wlan-bringup/drivers/network/ndisuio/readwrite.c
Modified: branches/wlan-bringup/drivers/network/ndisuio/ioctl.c URL: http://svn.reactos.org/svn/reactos/branches/wlan-bringup/drivers/network/ndi... ============================================================================== --- branches/wlan-bringup/drivers/network/ndisuio/ioctl.c [iso-8859-1] (original) +++ branches/wlan-bringup/drivers/network/ndisuio/ioctl.c [iso-8859-1] Tue Jan 3 18:12:29 2012 @@ -174,8 +174,19 @@ { /* Reference the adapter context */ KeAcquireSpinLock(&AdapterContext->Spinlock, &OldIrql); - ReferenceAdapterContext(AdapterContext); - Status = STATUS_SUCCESS; + if (AdapterContext->OpenCount != 0) + { + /* An open for read-write is exclusive, + * so we can't have any other open handles */ + KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql); + Status = STATUS_INVALID_PARAMETER; + } + else + { + /* Add a reference */ + ReferenceAdapterContext(AdapterContext); + Status = STATUS_SUCCESS; + } } else { @@ -191,6 +202,9 @@ { /* Set the file object pointer */ OpenEntry->FileObject = FileObject; + + /* Set the permissions */ + OpenEntry->WriteOnly = FALSE;
/* Associate this FO with the adapter */ FileObject->FsContext = AdapterContext; @@ -230,8 +244,80 @@ NTSTATUS OpenDeviceWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp) { - /* FIXME: Handle this correctly */ - return OpenDeviceReadWrite(Irp, IrpSp); + PFILE_OBJECT FileObject = IrpSp->FileObject; + UNICODE_STRING DeviceName; + ULONG NameLength; + NTSTATUS Status; + PNDISUIO_ADAPTER_CONTEXT AdapterContext; + PNDISUIO_OPEN_ENTRY OpenEntry; + KIRQL OldIrql; + + NameLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength; + if (NameLength != 0) + { + DeviceName.MaximumLength = DeviceName.Length = NameLength; + DeviceName.Buffer = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + + /* Check if this already has a context */ + AdapterContext = FindAdapterContextByName(&DeviceName); + if (AdapterContext != NULL) + { + /* Reference the adapter context */ + KeAcquireSpinLock(&AdapterContext->Spinlock, &OldIrql); + ReferenceAdapterContext(AdapterContext); + Status = STATUS_SUCCESS; + } + else + { + /* Invalid device name */ + Status = STATUS_INVALID_PARAMETER; + } + + /* Check that the bind succeeded */ + if (NT_SUCCESS(Status)) + { + OpenEntry = ExAllocatePool(NonPagedPool, sizeof(*OpenEntry)); + if (OpenEntry) + { + /* Set the file object pointer */ + OpenEntry->FileObject = FileObject; + + /* Associate this FO with the adapter */ + FileObject->FsContext = AdapterContext; + FileObject->FsContext2 = OpenEntry; + + /* Set permissions */ + OpenEntry->WriteOnly = TRUE; + + /* Add it to the adapter's list */ + 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; + } + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; }
NTSTATUS @@ -240,6 +326,7 @@ PIRP Irp) { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + PNDISUIO_OPEN_ENTRY OpenEntry;
ASSERT(DeviceObject == GlobalDeviceObject);
@@ -263,24 +350,39 @@ return STATUS_INVALID_PARAMETER; }
- /* Now handle other IOCTLs */ + /* Now handle write IOCTLs */ switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) { - case IOCTL_CANCEL_READ: - return CancelPacketRead(Irp, IrpSp); - - case IOCTL_NDISUIO_QUERY_OID_VALUE: - return QueryAdapterOid(Irp, IrpSp); - case IOCTL_NDISUIO_SET_OID_VALUE: return SetAdapterOid(Irp, IrpSp);
default: - DPRINT1("Unimplemented\n"); - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - break; + /* Check that we have read permissions */ + OpenEntry = IrpSp->FileObject->FsContext2; + if (OpenEntry->WriteOnly) + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_INVALID_PARAMETER; + } + + switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_CANCEL_READ: + return CancelPacketRead(Irp, IrpSp); + + case IOCTL_NDISUIO_QUERY_OID_VALUE: + return QueryAdapterOid(Irp, IrpSp); + + default: + DPRINT1("Unimplemented\n"); + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + break; + } } break; }
Modified: branches/wlan-bringup/drivers/network/ndisuio/ndisuio.h URL: http://svn.reactos.org/svn/reactos/branches/wlan-bringup/drivers/network/ndi... ============================================================================== --- branches/wlan-bringup/drivers/network/ndisuio/ndisuio.h [iso-8859-1] (original) +++ branches/wlan-bringup/drivers/network/ndisuio/ndisuio.h [iso-8859-1] Tue Jan 3 18:12:29 2012 @@ -42,9 +42,24 @@ /* File object */ PFILE_OBJECT FileObject;
+ /* Tracks how this adapter was opened (write-only or read-write) */ + BOOLEAN WriteOnly; + /* List entry */ LIST_ENTRY ListEntry; } NDISUIO_OPEN_ENTRY, *PNDISUIO_OPEN_ENTRY; + +struct _NDISUIO_PACKET_ENTRY +{ + /* Length of data at the end of the struct */ + ULONG PacketLength; + + /* Entry on the packet list */ + LIST_ENTRY ListEntry; + + /* Packet data */ + UCHAR PacketData[1]; +} NDISUIO_PACKET_ENTRY, *PNDISUIO_PACKET_ENTRY;
/* NDIS version info */ #define NDIS_MAJOR_VERISON 5
Modified: branches/wlan-bringup/drivers/network/ndisuio/readwrite.c URL: http://svn.reactos.org/svn/reactos/branches/wlan-bringup/drivers/network/ndi... ============================================================================== --- branches/wlan-bringup/drivers/network/ndisuio/readwrite.c [iso-8859-1] (original) +++ branches/wlan-bringup/drivers/network/ndisuio/readwrite.c [iso-8859-1] Tue Jan 3 18:12:29 2012 @@ -18,6 +18,7 @@ { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext; + PNDISUIO_OPEN_ENTRY OpenEntry = IrpSp->FileObject->FsContext2; KIRQL OldIrql; NTSTATUS Status; PLIST_ENTRY ListEntry; @@ -25,6 +26,15 @@ ULONG BytesCopied = 0;
ASSERT(DeviceObject == GlobalDeviceObject); + + if (OpenEntry->WriteOnly) + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_INVALID_PARAMETER; + }
while (TRUE) {