[NDISUIO]

- Handle IOCTL_NDISUIO_BIND_WAIT and IOCTL_NDISUIO_QUERY_BINDING

svn path=/branches/wlan-bringup/; revision=54821
This commit is contained in:
Cameron Gutman 2012-01-03 19:11:57 +00:00
parent 22b2ba722d
commit 7360d0e1fb

View file

@ -11,6 +11,90 @@
#define NDEBUG
#include <debug.h>
NTSTATUS
WaitForBind(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
/* I've seen several code samples that use this IOCTL but there's
* no official documentation on it. I'm just implementing it as a no-op
* right now because I don't see any reason we need it. We handle an open
* and bind just fine with IRP_MJ_CREATE and IOCTL_NDISUIO_OPEN_DEVICE */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
QueryBinding(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
PNDISUIO_ADAPTER_CONTEXT AdapterContext;
PNDISUIO_QUERY_BINDING QueryBinding = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
ULONG BindingLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
NTSTATUS Status;
PLIST_ENTRY CurrentEntry;
KIRQL OldIrql;
ULONG i;
ULONG BytesCopied = 0;
if (QueryBinding && BindingLength >= sizeof(NDISUIO_QUERY_BINDING))
{
KeAcquireSpinLock(&GlobalAdapterListLock, &OldIrql);
i = 0;
CurrentEntry = GlobalAdapterList.Flink;
while (CurrentEntry != &GlobalAdapterList)
{
if (i == QueryBinding->BindingIndex)
break;
i++;
CurrentEntry = CurrentEntry->Flink;
}
if (i == QueryBinding->BindingIndex)
{
AdapterContext = CONTAINING_RECORD(CurrentEntry, NDISUIO_ADAPTER_CONTEXT, ListEntry);
if (AdapterContext->DeviceName.Length <= QueryBinding->DeviceNameLength)
{
BytesCopied += AdapterContext->DeviceName.Length;
RtlCopyMemory((PUCHAR)QueryBinding + QueryBinding->DeviceNameOffset,
AdapterContext->DeviceName.Buffer,
BytesCopied);
QueryBinding->DeviceNameLength = AdapterContext->DeviceName.Length;
/* FIXME: Copy description too */
QueryBinding->DeviceDescrLength = 0;
/* Successful */
Status = STATUS_SUCCESS;
}
else
{
/* Not enough buffer space */
Status = STATUS_BUFFER_TOO_SMALL;
}
}
else
{
/* Invalid index */
Status = STATUS_INVALID_PARAMETER;
}
}
else
{
/* Invalid parameters */
Status = STATUS_INVALID_PARAMETER;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = BytesCopied;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS
CancelPacketRead(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
@ -338,6 +422,12 @@ NduDispatchDeviceControl(PDEVICE_OBJECT DeviceObject,
case IOCTL_NDISUIO_OPEN_WRITE_DEVICE:
return OpenDeviceWrite(Irp, IrpSp);
case IOCTL_NDISUIO_BIND_WAIT:
return WaitForBind(Irp, IrpSp);
case IOCTL_NDISUIO_QUERY_BINDING:
return QueryBinding(Irp, IrpSp);
default:
/* Fail if this file object has no adapter associated */