2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver
5 * PURPOSE: TDI event handlers
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/09-2000 Created
13 NTSTATUS
AfdEventError(
14 IN PVOID TdiEventContext
,
17 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
19 return STATUS_SUCCESS
;
23 NTSTATUS
AfdEventDisconnect(
24 IN PVOID TdiEventContext
,
25 IN CONNECTION_CONTEXT ConnectionContext
,
26 IN LONG DisconnectDataLength
,
27 IN PVOID DisconnectData
,
28 IN LONG DisconnectInformationLength
,
29 IN PVOID DisconnectInformation
,
30 IN ULONG DisconnectFlags
)
32 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
34 return STATUS_SUCCESS
;
38 NTSTATUS
AfdEventReceive(
39 IN PVOID TdiEventContext
,
40 IN CONNECTION_CONTEXT ConnectionContext
,
41 IN ULONG ReceiveFlags
,
42 IN ULONG BytesIndicated
,
43 IN ULONG BytesAvailable
,
44 OUT ULONG
*BytesTaken
,
46 OUT PIRP
*IoRequestPacket
)
48 PAFDFCB FCB
= (PAFDFCB
)TdiEventContext
;
53 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
55 AFD_DbgPrint(MID_TRACE
, ("Receiving (%d) bytes on socket\n",
58 ReceiveBuffer
= ExAllocatePoolWithTag(NonPagedPool
,
63 return STATUS_INSUFFICIENT_RESOURCES
;
65 /*Buffer = (PAFD_BUFFER)ExAllocateFromNPagedLookasideList(
66 &BufferLookasideList);*/
67 Buffer
= (PAFD_BUFFER
)ExAllocatePoolWithTag(NonPagedPool
,
72 ExFreePoolWithTag(ReceiveBuffer
, TAG_AFD_DATA_BUFFER
);
73 return STATUS_INSUFFICIENT_RESOURCES
;
76 /* Copy the data to a local buffer */
77 RtlCopyMemory(ReceiveBuffer
, Tsdu
, BytesAvailable
);
79 Buffer
->Buffer
.len
= BytesAvailable
;
80 Buffer
->Buffer
.buf
= ReceiveBuffer
;
83 KeAcquireSpinLock(&FCB
->ReceiveQueueLock
, &OldIrql
);
85 InsertTailList( &FCB
->ReceiveQueue
, &Buffer
->ListEntry
);
87 TryToSatisfyRecvRequest( FCB
, TRUE
);
89 KeReleaseSpinLock(&FCB
->ReceiveQueueLock
, OldIrql
);
91 *BytesTaken
= BytesAvailable
;
93 AFD_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
95 return STATUS_SUCCESS
;
99 TDI_STATUS
ClientEventReceiveExpedited(
100 IN PVOID TdiEventContext
,
101 IN CONNECTION_CONTEXT ConnectionContext
,
102 IN ULONG ReceiveFlags
,
103 IN ULONG BytesIndicated
,
104 IN ULONG BytesAvailable
,
105 OUT ULONG
*BytesTaken
,
107 OUT PIRP
*IoRequestPacket
)
109 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
111 return STATUS_SUCCESS
;
115 NTSTATUS
ClientEventChainedReceive(
116 IN PVOID TdiEventContext
,
117 IN CONNECTION_CONTEXT ConnectionContext
,
118 IN ULONG ReceiveFlags
,
119 IN ULONG ReceiveLength
,
120 IN ULONG StartingOffset
,
122 IN PVOID TsduDescriptor
)
124 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
126 return STATUS_SUCCESS
;
130 NTSTATUS
AfdEventReceiveDatagramHandler(
131 IN PVOID TdiEventContext
,
132 IN LONG SourceAddressLength
,
133 IN PVOID SourceAddress
,
134 IN LONG OptionsLength
,
136 IN ULONG ReceiveDatagramFlags
,
137 IN ULONG BytesIndicated
,
138 IN ULONG BytesAvailable
,
139 OUT ULONG
*BytesTaken
,
141 OUT PIRP
*IoRequestPacket
)
143 PAFDFCB FCB
= (PAFDFCB
)TdiEventContext
;
144 PAFD_READ_REQUEST ReadRequest
;
153 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
155 AFD_DbgPrint(MID_TRACE
, ("Receiving (%d) bytes from (0x%X).\n",
156 BytesAvailable
, *(PULONG
)SourceAddress
));
158 ReceiveBuffer
= ExAllocatePoolWithTag(NonPagedPool
,
160 TAG_AFD_DATA_BUFFER
);
163 return STATUS_INSUFFICIENT_RESOURCES
;
165 /*Buffer = (PAFD_BUFFER)ExAllocateFromNPagedLookasideList(
166 &BufferLookasideList);*/
167 Buffer
= (PAFD_BUFFER
)ExAllocatePoolWithTag(NonPagedPool
,
169 TAG_AFD_DATA_BUFFER
);
172 ExFreePoolWithTag(ReceiveBuffer
, TAG_AFD_DATA_BUFFER
);
173 return STATUS_INSUFFICIENT_RESOURCES
;
176 /* Copy the data to a local buffer */
177 RtlCopyMemory(ReceiveBuffer
, Tsdu
, BytesAvailable
);
179 Buffer
->Buffer
.len
= BytesAvailable
;
180 Buffer
->Buffer
.buf
= ReceiveBuffer
;
183 ExInterlockedInsertTailList(&FCB
->ReceiveQueue
,
185 &FCB
->ReceiveQueueLock
);
187 KeAcquireSpinLock(&FCB
->ReceiveQueueLock
, &OldIrql
);
189 if (CompleteIrp
= !IsListEmpty(&FCB
->ReadRequestQueue
)) {
190 AFD_DbgPrint(MAX_TRACE
, ("Satisfying read request.\n"));
192 Entry
= RemoveHeadList(&FCB
->ReceiveQueue
);
193 ReadRequest
= CONTAINING_RECORD(Entry
, AFD_READ_REQUEST
, ListEntry
);
195 Status
= FillWSABuffers(FCB
,
196 ReadRequest
->RecvFromRequest
->Buffers
,
197 ReadRequest
->RecvFromRequest
->BufferCount
,
199 FALSE
); /* Packet oriented */
200 ReadRequest
->RecvFromReply
->NumberOfBytesRecvd
= Count
;
201 ReadRequest
->RecvFromReply
->Status
= NO_ERROR
;
203 ReadRequest
->Irp
->IoStatus
.Information
= 0;
204 ReadRequest
->Irp
->IoStatus
.Status
= Status
;
207 KeReleaseSpinLock(&FCB
->ReceiveQueueLock
, OldIrql
);
210 AFD_DbgPrint(MAX_TRACE
, ("Completing IRP at (0x%X).\n", ReadRequest
->Irp
));
211 IoCompleteRequest(ReadRequest
->Irp
, IO_NETWORK_INCREMENT
);
212 *BytesTaken
= BytesAvailable
;
215 AFD_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
217 return STATUS_SUCCESS
;
221 NTSTATUS
AfdRegisterEventHandlers(
226 assert(FCB
->TdiAddressObject
);
228 /* Report errors for all types of sockets */
229 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
231 (PVOID
)AfdEventError
,
233 if (!NT_SUCCESS(Status
)) { return Status
; }
235 switch (FCB
->SocketType
) {
237 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
238 TDI_EVENT_DISCONNECT
,
239 (PVOID
)AfdEventDisconnect
,
241 if (!NT_SUCCESS(Status
)) { return Status
; }
243 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
245 (PVOID
)AfdEventReceive
,
247 if (!NT_SUCCESS(Status
)) { return Status
; }
249 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
250 TDI_EVENT_RECEIVE_EXPEDITED
,
251 (PVOID
)ClientEventReceiveExpedited
,
253 if (!NT_SUCCESS(Status
)) { return Status
; }
255 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
256 TDI_EVENT_CHAINED_RECEIVE
,
257 (PVOID
)ClientEventChainedReceive
,
259 if (!NT_SUCCESS(Status
)) { return Status
; }
264 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
265 TDI_EVENT_RECEIVE_DATAGRAM
,
266 (PVOID
)AfdEventReceiveDatagramHandler
,
268 if (!NT_SUCCESS(Status
)) { return Status
; }
270 return STATUS_SUCCESS
;
274 NTSTATUS
AfdDeregisterEventHandlers(
279 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
283 if (!NT_SUCCESS(Status
)) { return Status
; }
285 switch (FCB
->SocketType
) {
287 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
288 TDI_EVENT_DISCONNECT
,
291 if (!NT_SUCCESS(Status
)) { return Status
; }
293 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
297 if (!NT_SUCCESS(Status
)) { return Status
; }
299 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
300 TDI_EVENT_RECEIVE_EXPEDITED
,
303 if (!NT_SUCCESS(Status
)) { return Status
; }
305 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
306 TDI_EVENT_CHAINED_RECEIVE
,
309 if (!NT_SUCCESS(Status
)) { return Status
; }
314 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
315 TDI_EVENT_RECEIVE_DATAGRAM
,
318 if (!NT_SUCCESS(Status
)) { return Status
; }
320 return STATUS_SUCCESS
;