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
;
23 PLIST_ENTRY ListEntry
;
24 PNDISUIO_PACKET_ENTRY PacketEntry
= NULL
;
25 ULONG BytesCopied
= 0;
27 ASSERT(DeviceObject
== GlobalDeviceObject
);
31 KeAcquireSpinLock(&AdapterContext
->Spinlock
, &OldIrql
);
33 /* Check if we have a packet */
34 if (IsListEmpty(&AdapterContext
->PacketList
))
36 KeReleaseSpinLock(&AdapterContext
->Spinlock
, OldIrql
);
38 /* Wait for a packet (in the context of the calling user thread) */
39 Status
= KeWaitForSingleObject(&AdapterContext
->PacketReadEvent
,
44 if (Status
!= STATUS_SUCCESS
)
49 /* Remove the first packet in the list */
50 ListEntry
= RemoveHeadList(&AdapterContext
->PacketList
);
51 PacketEntry
= CONTAINING_RECORD(ListEntry
, NDISUIO_PACKET_ENTRY
, ListEntry
);
53 /* Release the adapter lock */
54 KeReleaseSpinLock(&AdapterContext
->Spinlock
, OldIrql
);
56 /* And we're done with this loop */
57 Status
= STATUS_SUCCESS
;
62 /* Check if we got a packet */
63 if (PacketEntry
!= NULL
)
65 /* Find the right amount of bytes to copy */
66 BytesCopied
= PacketEntry
->PacketLength
;
67 if (BytesCopied
> IrpSp
->Parameters
.Read
.Length
)
68 BytesCopied
= IrpSp
->Parameters
.Read
.Length
;
71 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
,
72 &PacketEntry
->PacketBuffer
[0],
75 /* Free the packet entry */
76 ExFreePool(PacketEntry
);
80 /* Something failed */
84 /* Complete the IRP */
85 Irp
->IoStatus
.Status
= Status
;
86 Irp
->IoStatus
.Information
= BytesCopied
;
87 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
94 NduDispatchWrite(PDEVICE_OBJECT DeviceObject
,
97 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
98 PNDISUIO_ADAPTER_CONTEXT AdapterContext
= IrpSp
->FileObject
->FsContext
;
101 ULONG BytesCopied
= 0;
103 ASSERT(DeviceObject
== GlobalDeviceObject
);
105 /* Create a packet and buffer descriptor for this user buffer */
106 Packet
= CreatePacketFromPoolBuffer(Irp
->AssociatedIrp
.SystemBuffer
,
107 IrpSp
->Parameters
.Write
.Length
);
110 /* Send it via NDIS */
112 AdapterContext
->BindingHandle
,
115 /* Wait for the send */
116 if (Status
== NDIS_STATUS_PENDING
)
118 KeWaitForSingleObject(&AdapterContext
->AsyncEvent
,
123 Status
= AdapterContext
->AsyncStatus
;
126 /* Check if it succeeded */
127 if (Status
== NDIS_STATUS_SUCCESS
)
128 BytesCopied
= IrpSp
->Parameters
.Write
.Length
;
130 CleanupAndFreePacket(Packet
);
135 Status
= STATUS_NO_MEMORY
;
138 /* Complete the IRP */
139 Irp
->IoStatus
.Status
= Status
;
140 Irp
->IoStatus
.Information
= BytesCopied
;
141 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);