[NDISUIO]

- Build fixes

svn path=/branches/wlan-bringup/; revision=54849
This commit is contained in:
Cameron Gutman 2012-01-06 05:59:56 +00:00
parent ee6a082e17
commit f889faa935
11 changed files with 335 additions and 58 deletions

View file

@ -2,5 +2,6 @@
add_subdirectory(afd) add_subdirectory(afd)
add_subdirectory(dd) add_subdirectory(dd)
add_subdirectory(ndis) add_subdirectory(ndis)
add_subdirectory(ndisuio)
add_subdirectory(tcpip) add_subdirectory(tcpip)
add_subdirectory(tdi) add_subdirectory(tdi)

View file

@ -10,6 +10,9 @@
<directory name="ndis"> <directory name="ndis">
<xi:include href="ndis/ndis.rbuild" /> <xi:include href="ndis/ndis.rbuild" />
</directory> </directory>
<directory name="ndisuio">
<xi:include href="ndisuio/ndisuio.rbuild" />
</directory>
<directory name="tcpip"> <directory name="tcpip">
<xi:include href="tcpip/tcpip.rbuild" /> <xi:include href="tcpip/tcpip.rbuild" />
</directory> </directory>

View file

@ -2,6 +2,10 @@ add_definitions(
-DNDIS50 -DNDIS50
-D_NTDRIVER_) -D_NTDRIVER_)
include_directories(
BEFORE include
${REACTOS_SOURCE_DIR}/include/reactos/drivers/ndisuio)
list(APPEND SOURCE list(APPEND SOURCE
createclose.c createclose.c
ioctl.c ioctl.c

View file

@ -41,7 +41,6 @@ NduDispatchClose(PDEVICE_OBJECT DeviceObject,
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext; PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
PNDISUIO_OPEN_ENTRY OpenEntry = IrpSp->FileObject->FsContext2; PNDISUIO_OPEN_ENTRY OpenEntry = IrpSp->FileObject->FsContext2;
KIRQL OldIrql;
ASSERT(DeviceObject == GlobalDeviceObject); ASSERT(DeviceObject == GlobalDeviceObject);

View file

@ -11,7 +11,7 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
static
NTSTATUS NTSTATUS
WaitForBind(PIRP Irp, PIO_STACK_LOCATION IrpSp) WaitForBind(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {
@ -28,6 +28,7 @@ WaitForBind(PIRP Irp, PIO_STACK_LOCATION IrpSp)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static
NTSTATUS NTSTATUS
QueryBinding(PIRP Irp, PIO_STACK_LOCATION IrpSp) QueryBinding(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {
@ -96,6 +97,8 @@ QueryBinding(PIRP Irp, PIO_STACK_LOCATION IrpSp)
return Status; return Status;
} }
#if 0
static
NTSTATUS NTSTATUS
CancelPacketRead(PIRP Irp, PIO_STACK_LOCATION IrpSp) CancelPacketRead(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {
@ -129,13 +132,15 @@ CancelPacketRead(PIRP Irp, PIO_STACK_LOCATION IrpSp)
return Status; return Status;
} }
#endif
static
NTSTATUS NTSTATUS
SetAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp) SetAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {
PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext; PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
PNDISUIO_SET_OID SetOidRequest; PNDISUIO_SET_OID SetOidRequest;
NDIS_REQUEST NdisRequest; NDIS_REQUEST Request;
ULONG RequestLength; ULONG RequestLength;
NDIS_STATUS Status; NDIS_STATUS Status;
@ -143,18 +148,18 @@ SetAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp)
SetOidRequest = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; SetOidRequest = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
RequestLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength; RequestLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
if (QueryOidRequest && RequestLength >= sizeof(NDIS_OID)) if (SetOidRequest && RequestLength >= sizeof(NDIS_OID))
{ {
/* Setup the NDIS request */ /* Setup the NDIS request */
NdisRequest.RequestType = NdisRequestSetInformation; Request.RequestType = NdisRequestSetInformation;
NdisRequest.Oid = SetOidRequest->Oid; Request.DATA.SET_INFORMATION.Oid = SetOidRequest->Oid;
NdisRequest.InformationBuffer = SetOidRequest->Data; Request.DATA.SET_INFORMATION.InformationBuffer = SetOidRequest->Data;
NdisRequest.InformationBufferLength = RequestLength - sizeof(NDIS_OID); Request.DATA.SET_INFORMATION.InformationBufferLength = RequestLength - sizeof(NDIS_OID);
/* Dispatch the request */ /* Dispatch the request */
NdisRequest(&Status, NdisRequest(&Status,
AdapterContext->BindingHandle, AdapterContext->BindingHandle,
&NdisRequest); &Request);
/* Wait for the request */ /* Wait for the request */
if (Status == NDIS_STATUS_PENDING) if (Status == NDIS_STATUS_PENDING)
@ -168,7 +173,7 @@ SetAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp)
} }
/* Return the bytes read */ /* Return the bytes read */
if (NT_SUCCESS(Status)) Irp->IoStatus.Information = NdisRequest.BytesRead; if (NT_SUCCESS(Status)) Irp->IoStatus.Information = Request.DATA.SET_INFORMATION.BytesRead;
} }
else else
{ {
@ -183,12 +188,13 @@ SetAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp)
return Status; return Status;
} }
static
NTSTATUS NTSTATUS
QueryAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp) QueryAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {
PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext; PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
PNDISUIO_QUERY_OID QueryOidRequest; PNDISUIO_QUERY_OID QueryOidRequest;
NDIS_REQUEST NdisRequest; NDIS_REQUEST Request;
ULONG RequestLength; ULONG RequestLength;
NDIS_STATUS Status; NDIS_STATUS Status;
@ -199,15 +205,15 @@ QueryAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp)
if (QueryOidRequest && RequestLength >= sizeof(NDIS_OID)) if (QueryOidRequest && RequestLength >= sizeof(NDIS_OID))
{ {
/* Setup the NDIS request */ /* Setup the NDIS request */
NdisRequest.RequestType = NdisRequestQueryInformation; Request.RequestType = NdisRequestQueryInformation;
NdisRequest.Oid = QueryOidRequest->Oid; Request.DATA.QUERY_INFORMATION.Oid = QueryOidRequest->Oid;
NdisRequest.InformationBuffer = QueryOidRequest->Data; Request.DATA.QUERY_INFORMATION.InformationBuffer = QueryOidRequest->Data;
NdisRequest.InformationBufferLength = RequestLength - sizeof(NDIS_OID); Request.DATA.QUERY_INFORMATION.InformationBufferLength = RequestLength - sizeof(NDIS_OID);
/* Dispatch the request */ /* Dispatch the request */
NdisRequest(&Status, NdisRequest(&Status,
AdapterContext->BindingHandle, AdapterContext->BindingHandle,
&NdisRequest); &Request);
/* Wait for the request */ /* Wait for the request */
if (Status == NDIS_STATUS_PENDING) if (Status == NDIS_STATUS_PENDING)
@ -221,7 +227,7 @@ QueryAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp)
} }
/* Return the bytes written */ /* Return the bytes written */
if (NT_SUCCESS(Status)) Irp->IoStatus.Information = NdisRequest.BytesWritten; if (NT_SUCCESS(Status)) Irp->IoStatus.Information = Request.DATA.QUERY_INFORMATION.BytesWritten;
} }
else else
{ {
@ -236,6 +242,7 @@ QueryAdapterOid(PIRP Irp, PIO_STACK_LOCATION IrpSp)
return Status; return Status;
} }
static
NTSTATUS NTSTATUS
OpenDeviceReadWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp) OpenDeviceReadWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {
@ -307,7 +314,7 @@ OpenDeviceReadWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {
/* Remove the reference we added */ /* Remove the reference we added */
KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql); KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql);
DereferenceAdapterContext(AdapterContext, NULL); DereferenceAdapterContextWithOpenEntry(AdapterContext, NULL);
Status = STATUS_NO_MEMORY; Status = STATUS_NO_MEMORY;
} }
} }
@ -326,6 +333,8 @@ OpenDeviceReadWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp)
return Status; return Status;
} }
#if 0
static
NTSTATUS NTSTATUS
OpenDeviceWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp) OpenDeviceWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {
@ -404,6 +413,7 @@ OpenDeviceWrite(PIRP Irp, PIO_STACK_LOCATION IrpSp)
return Status; return Status;
} }
#endif
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -420,10 +430,10 @@ NduDispatchDeviceControl(PDEVICE_OBJECT DeviceObject,
{ {
case IOCTL_NDISUIO_OPEN_DEVICE: case IOCTL_NDISUIO_OPEN_DEVICE:
return OpenDeviceReadWrite(Irp, IrpSp); return OpenDeviceReadWrite(Irp, IrpSp);
#if 0
case IOCTL_NDISUIO_OPEN_WRITE_DEVICE: case IOCTL_NDISUIO_OPEN_WRITE_DEVICE:
return OpenDeviceWrite(Irp, IrpSp); return OpenDeviceWrite(Irp, IrpSp);
#endif
case IOCTL_NDISUIO_BIND_WAIT: case IOCTL_NDISUIO_BIND_WAIT:
return WaitForBind(Irp, IrpSp); return WaitForBind(Irp, IrpSp);
@ -461,8 +471,10 @@ NduDispatchDeviceControl(PDEVICE_OBJECT DeviceObject,
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
{ {
#if 0
case IOCTL_CANCEL_READ: case IOCTL_CANCEL_READ:
return CancelPacketRead(Irp, IrpSp); return CancelPacketRead(Irp, IrpSp);
#endif
case IOCTL_NDISUIO_QUERY_OID_VALUE: case IOCTL_NDISUIO_QUERY_OID_VALUE:
return QueryAdapterOid(Irp, IrpSp); return QueryAdapterOid(Irp, IrpSp);
@ -472,7 +484,7 @@ NduDispatchDeviceControl(PDEVICE_OBJECT DeviceObject,
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
break; return STATUS_NOT_IMPLEMENTED;
} }
} }
break; break;

View file

@ -13,12 +13,16 @@
PDEVICE_OBJECT GlobalDeviceObject; PDEVICE_OBJECT GlobalDeviceObject;
NDIS_HANDLE GlobalProtocolHandle; NDIS_HANDLE GlobalProtocolHandle;
KSPIN_LOCK GlobalAdapterListLock;
LIST_ENTRY GlobalAdapterList;
NDIS_HANDLE GlobalPacketPoolHandle;
NDIS_HANDLE GlobalBufferPoolHandle;
NDIS_STRING ProtocolName = RTL_CONSTANT_STRING(L"NDISUIO");
VOID NTAPI NduUnload(PDRIVER_OBJECT DriverObject) VOID NTAPI NduUnload(PDRIVER_OBJECT DriverObject)
{ {
IoDeleteDevice(GlobalDeviceObject); DPRINT1("NDISUIO: Unloaded\n");
DPRINT("NDISUIO: Unloaded\n");
} }
NTSTATUS NTSTATUS
@ -26,8 +30,10 @@ NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject, DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath) PUNICODE_STRING RegistryPath)
{ {
NTSTATUS Status; NDIS_STATUS Status;
NDIS_PROTOCOL_CHARACTERISTICS Chars; NDIS_PROTOCOL_CHARACTERISTICS Chars;
UNICODE_STRING NtDeviceName = RTL_CONSTANT_STRING(NDISUIO_DEVICE_NAME_NT);
UNICODE_STRING DosDeviceName = RTL_CONSTANT_STRING(NDISUIO_DEVICE_NAME_DOS);
/* Setup dispatch functions */ /* Setup dispatch functions */
DriverObject->MajorFunction[IRP_MJ_CREATE] = NduDispatchCreate; DriverObject->MajorFunction[IRP_MJ_CREATE] = NduDispatchCreate;
@ -37,12 +43,16 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
DriverObject->MajorFunction[IRP_MJ_WRITE] = NduDispatchWrite; DriverObject->MajorFunction[IRP_MJ_WRITE] = NduDispatchWrite;
DriverObject->DriverUnload = NduUnload; DriverObject->DriverUnload = NduUnload;
/* Setup global state */
InitializeListHead(&GlobalAdapterList);
KeInitializeSpinLock(&GlobalAdapterListLock);
/* Create the NDISUIO device object */ /* Create the NDISUIO device object */
Status = IoCreateDevice(DriverObject, Status = IoCreateDevice(DriverObject,
0, 0,
NULL, // FIXME &NtDeviceName,
NDISUIO_DEVICE_NAME,
FILE_DEVICE_SECURE_OPEN, FILE_DEVICE_SECURE_OPEN,
0,
FALSE, FALSE,
&GlobalDeviceObject); &GlobalDeviceObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -51,6 +61,41 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
return Status; return Status;
} }
/* Create a symbolic link into the DOS devices namespace */
Status = IoCreateSymbolicLink(&DosDeviceName, &NtDeviceName);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create symbolic link with status 0x%x\n", Status);
IoDeleteDevice(GlobalDeviceObject);
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 */ /* Register the protocol with NDIS */
RtlZeroMemory(&Chars, sizeof(Chars)); RtlZeroMemory(&Chars, sizeof(Chars));
Chars.MajorNdisVersion = NDIS_MAJOR_VERSION; Chars.MajorNdisVersion = NDIS_MAJOR_VERSION;
@ -62,14 +107,12 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
Chars.ResetCompleteHandler = NduResetComplete; Chars.ResetCompleteHandler = NduResetComplete;
Chars.RequestCompleteHandler = NduRequestComplete; Chars.RequestCompleteHandler = NduRequestComplete;
Chars.ReceiveHandler = NduReceive; Chars.ReceiveHandler = NduReceive;
Chars.ReceiveComplete = NduReceiveComplete; Chars.ReceiveCompleteHandler = NduReceiveComplete;
Chars.StatusHandler = NduStatus; Chars.StatusHandler = NduStatus;
Chars.StatusCompleteHandler = NduStatusComplete; Chars.StatusCompleteHandler = NduStatusComplete;
Chars.Name = NULL; //FIXME Chars.Name = ProtocolName;
Chars.ReceivePacketHandler = NULL; //NduReceivePacket
Chars.BindAdapterHandler = NduBindAdapter; Chars.BindAdapterHandler = NduBindAdapter;
Chars.UnbindAdapterHandler = NduUnbindAdapter; Chars.UnbindAdapterHandler = NduUnbindAdapter;
Chars.PnPEventHandler = NduPnPEvent;
NdisRegisterProtocol(&Status, NdisRegisterProtocol(&Status,
&GlobalProtocolHandle, &GlobalProtocolHandle,
@ -78,11 +121,14 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
if (Status != NDIS_STATUS_SUCCESS) if (Status != NDIS_STATUS_SUCCESS)
{ {
DPRINT1("Failed to register protocol with status 0x%x\n", Status); DPRINT1("Failed to register protocol with status 0x%x\n", Status);
NdisFreePacketPool(GlobalPacketPoolHandle);
NdisFreeBufferPool(GlobalBufferPoolHandle);
IoDeleteSymbolicLink(&DosDeviceName);
IoDeleteDevice(GlobalDeviceObject); IoDeleteDevice(GlobalDeviceObject);
return Status; return Status;
} }
DPRINT("NDISUIO: Loaded\n"); DPRINT1("NDISUIO: Loaded\n");
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -15,13 +15,14 @@ NDIS_STATUS
AllocateAndChainBuffer(PNDIS_PACKET Packet, PVOID Buffer, ULONG BufferSize, BOOLEAN Front) AllocateAndChainBuffer(PNDIS_PACKET Packet, PVOID Buffer, ULONG BufferSize, BOOLEAN Front)
{ {
NDIS_STATUS Status; NDIS_STATUS Status;
PNDIS_BUFFER NdisBuffer;
/* Allocate the NDIS buffer mapping the pool */ /* Allocate the NDIS buffer mapping the pool */
NdisAllocateBuffer(&Status, NdisAllocateBuffer(&Status,
&Buffer, &NdisBuffer,
GlobalBufferPoolHandle, GlobalBufferPoolHandle,
Buffer, Buffer,
Length); BufferSize);
if (Status != NDIS_STATUS_SUCCESS) if (Status != NDIS_STATUS_SUCCESS)
{ {
DPRINT1("No free buffer descriptors\n"); DPRINT1("No free buffer descriptors\n");
@ -31,12 +32,12 @@ AllocateAndChainBuffer(PNDIS_PACKET Packet, PVOID Buffer, ULONG BufferSize, BOOL
if (Front) if (Front)
{ {
/* Chain the buffer to front */ /* Chain the buffer to front */
NdisChainBufferAtFront(Packet, Buffer); NdisChainBufferAtFront(Packet, NdisBuffer);
} }
else else
{ {
/* Chain the buffer to back */ /* Chain the buffer to back */
NdisChainBufferAtBack(Packet, Buffer); NdisChainBufferAtBack(Packet, NdisBuffer);
} }
/* Return success */ /* Return success */

View file

@ -9,11 +9,16 @@
#include <wdm.h> #include <wdm.h>
#include <ndis.h> #include <ndis.h>
//#include <nuiouser.h> #include <nuiouser.h>
#include <ndistapi.h>
#include <ndisguid.h>
struct _NDISUIO_ADAPTER_CONTEXT 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
{ {
/* Asynchronous completion */ /* Asynchronous completion */
NDIS_STATUS AsyncStatus; NDIS_STATUS AsyncStatus;
@ -30,6 +35,9 @@ struct _NDISUIO_ADAPTER_CONTEXT
LIST_ENTRY PacketList; LIST_ENTRY PacketList;
KEVENT PacketReadEvent; KEVENT PacketReadEvent;
/* Device name */
UNICODE_STRING DeviceName;
/* Global list entry */ /* Global list entry */
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
@ -37,7 +45,7 @@ struct _NDISUIO_ADAPTER_CONTEXT
KSPIN_LOCK Spinlock; KSPIN_LOCK Spinlock;
} NDISUIO_ADAPTER_CONTEXT, *PNDISUIO_ADAPTER_CONTEXT; } NDISUIO_ADAPTER_CONTEXT, *PNDISUIO_ADAPTER_CONTEXT;
struct _NDISUIO_OPEN_ENTRY typedef struct _NDISUIO_OPEN_ENTRY
{ {
/* File object */ /* File object */
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
@ -49,7 +57,7 @@ struct _NDISUIO_OPEN_ENTRY
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
} NDISUIO_OPEN_ENTRY, *PNDISUIO_OPEN_ENTRY; } NDISUIO_OPEN_ENTRY, *PNDISUIO_OPEN_ENTRY;
struct _NDISUIO_PACKET_ENTRY typedef struct _NDISUIO_PACKET_ENTRY
{ {
/* Length of data at the end of the struct */ /* Length of data at the end of the struct */
ULONG PacketLength; ULONG PacketLength;
@ -62,7 +70,134 @@ struct _NDISUIO_PACKET_ENTRY
} NDISUIO_PACKET_ENTRY, *PNDISUIO_PACKET_ENTRY; } NDISUIO_PACKET_ENTRY, *PNDISUIO_PACKET_ENTRY;
/* NDIS version info */ /* NDIS version info */
#define NDIS_MAJOR_VERISON 5 #define NDIS_MAJOR_VERSION 5
#define NDIS_MINOR_VERSION 0 #define NDIS_MINOR_VERSION 0
/* createclose.c */
NTSTATUS
NTAPI
NduDispatchCreate(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
NTSTATUS
NTAPI
NduDispatchClose(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
/* ioctl.c */
NTSTATUS
NTAPI
NduDispatchDeviceControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
/* misc.c */
NDIS_STATUS
AllocateAndChainBuffer(PNDIS_PACKET Packet,
PVOID Buffer,
ULONG BufferSize,
BOOLEAN Front);
PNDIS_PACKET
CreatePacketFromPoolBuffer(PVOID Buffer,
ULONG BufferSize);
VOID
CleanupAndFreePacket(PNDIS_PACKET Packet,
BOOLEAN FreePool);
PNDISUIO_ADAPTER_CONTEXT
FindAdapterContextByName(PNDIS_STRING DeviceName);
VOID
ReferenceAdapterContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext);
VOID
DereferenceAdapterContextWithOpenEntry(PNDISUIO_ADAPTER_CONTEXT AdapterContext,
PNDISUIO_OPEN_ENTRY OpenEntry);
/* protocol.c */
VOID
NTAPI
NduOpenAdapterComplete(NDIS_HANDLE ProtocolBindingContext,
NDIS_STATUS Status,
NDIS_STATUS OpenStatus);
VOID
NTAPI
NduCloseAdapterComplete(NDIS_HANDLE ProtocolBindingContext,
NDIS_STATUS Status);
VOID
NTAPI
NduSendComplete(NDIS_HANDLE ProtocolBindingContext,
PNDIS_PACKET Packet,
NDIS_STATUS Status);
VOID
NTAPI
NduTransferDataComplete(NDIS_HANDLE ProtocolBindingContext,
PNDIS_PACKET Packet,
NDIS_STATUS Status,
UINT BytesTransferred);
VOID
NTAPI
NduResetComplete(NDIS_HANDLE ProtocolBindingContext,
NDIS_STATUS Status);
VOID
NTAPI
NduRequestComplete(NDIS_HANDLE ProtocolBindingContext,
PNDIS_REQUEST NdisRequest,
NDIS_STATUS Status);
NDIS_STATUS
NTAPI
NduReceive(NDIS_HANDLE ProtocolBindingContext,
NDIS_HANDLE MacReceiveContext,
PVOID HeaderBuffer,
UINT HeaderBufferSize,
PVOID LookAheadBuffer,
UINT LookaheadBufferSize,
UINT PacketSize);
VOID
NTAPI
NduReceiveComplete(NDIS_HANDLE ProtocolBindingContext);
VOID
NTAPI
NduStatus(NDIS_HANDLE ProtocolBindingContext,
NDIS_STATUS GeneralStatus,
PVOID StatusBuffer,
UINT StatusBufferSize);
VOID
NTAPI
NduStatusComplete(NDIS_HANDLE ProtocolBindingContext);
VOID
NTAPI
NduBindAdapter(PNDIS_STATUS Status,
NDIS_HANDLE BindContext,
PNDIS_STRING DeviceName,
PVOID SystemSpecific1,
PVOID SystemSpecific2);
VOID
NTAPI
NduUnbindAdapter(PNDIS_STATUS Status,
NDIS_HANDLE ProtocolBindingContext,
NDIS_HANDLE UnbindContext);
/* readwrite.c */
NTSTATUS
NTAPI
NduDispatchRead(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
NTSTATUS
NTAPI
NduDispatchWrite(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
#endif /* __NDISUIO_H */ #endif /* __NDISUIO_H */

View file

@ -113,10 +113,11 @@ NduReceive(NDIS_HANDLE ProtocolBindingContext,
UINT PacketSize) UINT PacketSize)
{ {
PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext; PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext;
PNDISUIO_PACKET_ENTRY PacketEntry;
PVOID PacketBuffer; PVOID PacketBuffer;
PNDIS_PACKET Packet; PNDIS_PACKET Packet;
NDIS_STATUS Status; NDIS_STATUS Status;
ULONG BytesTransferred; UINT BytesTransferred;
/* Allocate a buffer to hold the packet data and header */ /* Allocate a buffer to hold the packet data and header */
PacketBuffer = ExAllocatePool(NonPagedPool, PacketSize); PacketBuffer = ExAllocatePool(NonPagedPool, PacketSize);
@ -138,6 +139,7 @@ NduReceive(NDIS_HANDLE ProtocolBindingContext,
MacReceiveContext, MacReceiveContext,
0, 0,
PacketSize, PacketSize,
Packet,
&BytesTransferred); &BytesTransferred);
if (Status == NDIS_STATUS_PENDING) if (Status == NDIS_STATUS_PENDING)
{ {
@ -214,12 +216,14 @@ NduStatusComplete(NDIS_HANDLE ProtocolBindingContext)
/* FIXME: Implement status tracking */ /* FIXME: Implement status tracking */
} }
static
NDIS_STATUS NDIS_STATUS
UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext) UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext)
{ {
KIRQL OldIrql; KIRQL OldIrql;
PLIST_ENTRY CurrentOpenEntry; PLIST_ENTRY CurrentOpenEntry;
PNDISUIO_OPEN_ENTRY OpenEntry; PNDISUIO_OPEN_ENTRY OpenEntry;
NDIS_STATUS Status;
/* Remove the adapter context from the global list */ /* Remove the adapter context from the global list */
KeAcquireSpinLock(&GlobalAdapterListLock, &OldIrql); KeAcquireSpinLock(&GlobalAdapterListLock, &OldIrql);
@ -255,27 +259,29 @@ UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext)
ASSERT(AdapterContext->OpenCount == 0); ASSERT(AdapterContext->OpenCount == 0);
/* Send the close request */ /* Send the close request */
NdisCloseAdapter(Status, NdisCloseAdapter(&Status,
AdapterContext->BindingHandle); AdapterContext->BindingHandle);
/* Wait for a pending close */ /* Wait for a pending close */
if (*Status == NDIS_STATUS_PENDING) if (Status == NDIS_STATUS_PENDING)
{ {
KeWaitForSingleObject(&AdapterContext->AsyncEvent, KeWaitForSingleObject(&AdapterContext->AsyncEvent,
Executive, Executive,
KernelMode, KernelMode,
FALSE, FALSE,
NULL); NULL);
*Status = AdapterContext->AsyncStatus; Status = AdapterContext->AsyncStatus;
} }
/* Free the context */ /* Free the context */
ExFreePool(AdapterContext); ExFreePool(AdapterContext);
return Status;
} }
static
NDIS_STATUS NDIS_STATUS
BindAdapterByName(PNDIS_STRING DeviceName, PNDISUIO_ADAPTER_CONTEXT *Context) BindAdapterByName(PNDIS_STRING DeviceName)
{ {
NDIS_STATUS OpenErrorStatus; NDIS_STATUS OpenErrorStatus;
PNDISUIO_ADAPTER_CONTEXT AdapterContext; PNDISUIO_ADAPTER_CONTEXT AdapterContext;
@ -298,6 +304,17 @@ BindAdapterByName(PNDIS_STRING DeviceName, PNDISUIO_ADAPTER_CONTEXT *Context)
InitializeListHead(&AdapterContext->OpenEntryList); InitializeListHead(&AdapterContext->OpenEntryList);
AdapterContext->OpenCount = 0; AdapterContext->OpenCount = 0;
AdapterContext->DeviceName.Length =
AdapterContext->DeviceName.MaximumLength = DeviceName->Length;
AdapterContext->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceName->Length);
if (!AdapterContext->DeviceName.Buffer)
{
ExFreePool(AdapterContext);
return NDIS_STATUS_RESOURCES;
}
RtlCopyMemory(AdapterContext->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length);
/* Send the open request */ /* Send the open request */
NdisOpenAdapter(&Status, NdisOpenAdapter(&Status,
&OpenErrorStatus, &OpenErrorStatus,
@ -325,9 +342,9 @@ BindAdapterByName(PNDIS_STRING DeviceName, PNDISUIO_ADAPTER_CONTEXT *Context)
/* Check the final status */ /* Check the final status */
if (Status != NDIS_STATUS_SUCCESS) if (Status != NDIS_STATUS_SUCCESS)
{ {
DPRINT1("Failed to open adapter for bind with status 0x%x\n", *Status); DPRINT1("Failed to open adapter for bind with status 0x%x\n", Status);
ExFreePool(AdapterContext); ExFreePool(AdapterContext);
return; return Status;
} }
/* Add the adapter context to the global list */ /* Add the adapter context to the global list */
@ -335,8 +352,6 @@ BindAdapterByName(PNDIS_STRING DeviceName, PNDISUIO_ADAPTER_CONTEXT *Context)
&AdapterContext->ListEntry, &AdapterContext->ListEntry,
&GlobalAdapterListLock); &GlobalAdapterListLock);
/* Return the context */
*Context = AdapterContext;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -11,10 +11,12 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
static
VOID VOID
NTAPI NTAPI
ReadIrpCancel(PDEVICE_OBJECT DeviceObject, PIRP Irp) ReadIrpCancel(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{ {
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext; PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
PNDISUIO_PACKET_ENTRY PacketEntry; PNDISUIO_PACKET_ENTRY PacketEntry;
@ -22,7 +24,7 @@ ReadIrpCancel(PDEVICE_OBJECT DeviceObject, PIRP Irp)
IoReleaseCancelSpinLock(Irp->CancelIrql); IoReleaseCancelSpinLock(Irp->CancelIrql);
/* Indicate a 0-byte packet on the queue to cancel the read */ /* Indicate a 0-byte packet on the queue to cancel the read */
PacketEntry = ExAllocatePool(PagedPool, sizeof(NDISUIO_PACKET_ENTRY)); PacketEntry = ExAllocatePool(NonPagedPool, sizeof(NDISUIO_PACKET_ENTRY));
if (PacketEntry) if (PacketEntry)
{ {
PacketEntry->PacketLength = 0; PacketEntry->PacketLength = 0;
@ -131,7 +133,7 @@ NduDispatchRead(PDEVICE_OBJECT DeviceObject,
/* Copy the packet */ /* Copy the packet */
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
&PacketEntry->PacketBuffer[0], &PacketEntry->PacketData[0],
BytesCopied); BytesCopied);
/* Free the packet entry */ /* Free the packet entry */
@ -189,7 +191,7 @@ NduDispatchWrite(PDEVICE_OBJECT DeviceObject,
if (Status == NDIS_STATUS_SUCCESS) if (Status == NDIS_STATUS_SUCCESS)
BytesCopied = IrpSp->Parameters.Write.Length; BytesCopied = IrpSp->Parameters.Write.Length;
CleanupAndFreePacket(Packet); CleanupAndFreePacket(Packet, TRUE);
} }
else else
{ {

View file

@ -0,0 +1,59 @@
#ifndef __NUIOUSER_H
#define __NUIOUSER_H
/* Device names (NT and DOS style) */
#define NDISUIO_DEVICE_NAME_NT L"\\Device\\Ndisuio"
#define NDISUIO_DEVICE_NAME_DOS L"\\DosDevices\\Ndisuio"
/* Device name for user apps */
#define NDISUIO_DEVICE_NAME L"\\\\.\\\\Ndisuio"
/* Links a file handle with a bound NIC */
#define IOCTL_NDISUIO_OPEN_DEVICE \
CTL_CODE(FILE_DEVICE_NETWORK, 0x200, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* Queries an OID for the bound NIC */
#define IOCTL_NDISUIO_QUERY_OID_VALUE \
CTL_CODE(FILE_DEVICE_NETWORK, 0x201, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_NDISUIO_SET_ETHER_TYPE \
CTL_CODE(FILE_DEVICE_NETWORK, 0x202, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* Queries binding information during enumeration */
#define IOCTL_NDISUIO_QUERY_BINDING \
CTL_CODE(FILE_DEVICE_NETWORK, 0x203, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* Waits for any pending bindings */
#define IOCTL_NDISUIO_BIND_WAIT \
CTL_CODE(FILE_DEVICE_NETWORK, 0x204, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* Sets an OID for a bound NIC */
#define IOCTL_NDISUIO_SET_OID_VALUE \
CTL_CODE(FILE_DEVICE_NETWORK, 0x205, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* Passed as a parameter to IOCTL_NDISUIO_QUERY_OID_VALUE */
typedef struct _NDISUIO_QUERY_OID
{
NDIS_OID Oid;
UCHAR Data[sizeof(ULONG)];
} NDISUIO_QUERY_OID, *PNDISUIO_QUERY_OID;
/* Passed as a parameter to IOCTL_NDISUIO_SET_OID_VALUE */
typedef struct _NDISUIO_SET_OID
{
NDIS_OID Oid;
UCHAR Data[sizeof(ULONG)];
} NDISUIO_SET_OID, *PNDISUIO_SET_OID;
/* Passed as a parameter to IOCTL_NDISUIO_QUERY_BINDING */
typedef struct _NDISUIO_QUERY_BINDING
{
ULONG BindingIndex;
ULONG DeviceNameOffset;
ULONG DeviceNameLength;
ULONG DeviceDescrOffset;
ULONG DeviceDescrLength;
} NDISUIO_QUERY_BINDING, *PNDISUIO_QUERY_BINDING;
#endif