2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS User I/O driver
5 * PURPOSE: Handles IRP_MJ_READ and IRP_MJ_WRITE
6 * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
16 NduDispatchRead(PDEVICE_OBJECT DeviceObject
,
19 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
20 PNDISUIO_ADAPTER_CONTEXT AdapterContext
= IrpSp
->FileObject
->FsContext
;
21 PNDISUIO_OPEN_ENTRY OpenEntry
= IrpSp
->FileObject
->FsContext2
;
24 PLIST_ENTRY ListEntry
;
25 PNDISUIO_PACKET_ENTRY PacketEntry
= NULL
;
26 ULONG BytesCopied
= 0;
28 ASSERT(DeviceObject
== GlobalDeviceObject
);
30 if (OpenEntry
->WriteOnly
)
32 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
33 Irp
->IoStatus
.Information
= 0;
34 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
36 return STATUS_INVALID_PARAMETER
;
41 KeAcquireSpinLock(&AdapterContext
->Spinlock
, &OldIrql
);
43 /* Check if we have a packet */
44 if (IsListEmpty(&AdapterContext
->PacketList
))
46 KeReleaseSpinLock(&AdapterContext
->Spinlock
, OldIrql
);
48 /* Wait for a packet (in the context of the calling user thread) */
49 Status
= KeWaitForSingleObject(&AdapterContext
->PacketReadEvent
,
54 if (Status
!= STATUS_SUCCESS
)
59 /* Remove the first packet in the list */
60 ListEntry
= RemoveHeadList(&AdapterContext
->PacketList
);
61 PacketEntry
= CONTAINING_RECORD(ListEntry
, NDISUIO_PACKET_ENTRY
, ListEntry
);
63 /* Release the adapter lock */
64 KeReleaseSpinLock(&AdapterContext
->Spinlock
, OldIrql
);
66 /* And we're done with this loop */
67 Status
= STATUS_SUCCESS
;
72 /* Check if we got a packet */
73 if (PacketEntry
!= NULL
)
75 /* Find the right amount of bytes to copy */
76 BytesCopied
= PacketEntry
->PacketLength
;
77 if (BytesCopied
> IrpSp
->Parameters
.Read
.Length
)
78 BytesCopied
= IrpSp
->Parameters
.Read
.Length
;
81 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
,
82 &PacketEntry
->PacketBuffer
[0],
85 /* Free the packet entry */
86 ExFreePool(PacketEntry
);
90 /* Something failed */
94 /* Complete the IRP */
95 Irp
->IoStatus
.Status
= Status
;
96 Irp
->IoStatus
.Information
= BytesCopied
;
97 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
104 NduDispatchWrite(PDEVICE_OBJECT DeviceObject
,
107 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
108 PNDISUIO_ADAPTER_CONTEXT AdapterContext
= IrpSp
->FileObject
->FsContext
;
111 ULONG BytesCopied
= 0;
113 ASSERT(DeviceObject
== GlobalDeviceObject
);
115 /* Create a packet and buffer descriptor for this user buffer */
116 Packet
= CreatePacketFromPoolBuffer(Irp
->AssociatedIrp
.SystemBuffer
,
117 IrpSp
->Parameters
.Write
.Length
);
120 /* Send it via NDIS */
122 AdapterContext
->BindingHandle
,
125 /* Wait for the send */
126 if (Status
== NDIS_STATUS_PENDING
)
128 KeWaitForSingleObject(&AdapterContext
->AsyncEvent
,
133 Status
= AdapterContext
->AsyncStatus
;
136 /* Check if it succeeded */
137 if (Status
== NDIS_STATUS_SUCCESS
)
138 BytesCopied
= IrpSp
->Parameters
.Write
.Length
;
140 CleanupAndFreePacket(Packet
);
145 Status
= STATUS_NO_MEMORY
;
148 /* Complete the IRP */
149 Irp
->IoStatus
.Status
= Status
;
150 Irp
->IoStatus
.Information
= BytesCopied
;
151 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);