mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[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 svn path=/branches/wlan-bringup/; revision=54819
This commit is contained in:
parent
9e9a049290
commit
22b2ba722d
3 changed files with 143 additions and 16 deletions
|
@ -174,8 +174,19 @@ OpenDeviceReadWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
|||
{
|
||||
/* 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 @@ OpenDeviceReadWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
|||
{
|
||||
/* 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 @@ OpenDeviceReadWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
|||
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 @@ NduDispatchDeviceControl(PDEVICE_OBJECT DeviceObject,
|
|||
PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
PNDISUIO_OPEN_ENTRY OpenEntry;
|
||||
|
||||
ASSERT(DeviceObject == GlobalDeviceObject);
|
||||
|
||||
|
@ -263,24 +350,39 @@ NduDispatchDeviceControl(PDEVICE_OBJECT DeviceObject,
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -42,10 +42,25 @@ struct _NDISUIO_OPEN_ENTRY
|
|||
/* 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
|
||||
#define NDIS_MINOR_VERSION 0
|
||||
|
|
|
@ -18,6 +18,7 @@ NduDispatchRead(PDEVICE_OBJECT DeviceObject,
|
|||
{
|
||||
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;
|
||||
|
@ -26,6 +27,15 @@ NduDispatchRead(PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
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)
|
||||
{
|
||||
KeAcquireSpinLock(&AdapterContext->Spinlock, &OldIrql);
|
||||
|
|
Loading…
Reference in a new issue