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
12 NTSTATUS
AfdEventError(
13 IN PVOID TdiEventContext
,
16 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
18 return STATUS_SUCCESS
;
22 NTSTATUS
AfdEventDisconnect(
23 IN PVOID TdiEventContext
,
24 IN CONNECTION_CONTEXT ConnectionContext
,
25 IN LONG DisconnectDataLength
,
26 IN PVOID DisconnectData
,
27 IN LONG DisconnectInformationLength
,
28 IN PVOID DisconnectInformation
,
29 IN ULONG DisconnectFlags
)
31 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
33 return STATUS_SUCCESS
;
37 NTSTATUS
AfdEventReceive(
38 IN PVOID TdiEventContext
,
39 IN CONNECTION_CONTEXT ConnectionContext
,
40 IN ULONG ReceiveFlags
,
41 IN ULONG BytesIndicated
,
42 IN ULONG BytesAvailable
,
43 OUT ULONG
*BytesTaken
,
45 OUT PIRP
*IoRequestPacket
)
47 PAFDFCB FCB
= (PAFDFCB
)TdiEventContext
;
52 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
54 AFD_DbgPrint(MID_TRACE
, ("Receiving (%d) bytes on socket\n",
57 ReceiveBuffer
= ExAllocatePool(NonPagedPool
, BytesAvailable
);
59 return STATUS_INSUFFICIENT_RESOURCES
;
61 /*Buffer = (PAFD_BUFFER)ExAllocateFromNPagedLookasideList(
62 &BufferLookasideList);*/
63 Buffer
= (PAFD_BUFFER
)ExAllocatePool(NonPagedPool
, sizeof(AFD_BUFFER
));
65 ExFreePool(ReceiveBuffer
);
66 return STATUS_INSUFFICIENT_RESOURCES
;
69 /* Copy the data to a local buffer */
70 RtlCopyMemory(ReceiveBuffer
, Tsdu
, BytesAvailable
);
72 Buffer
->Buffer
.len
= BytesAvailable
;
73 Buffer
->Buffer
.buf
= ReceiveBuffer
;
76 KeAcquireSpinLock(&FCB
->ReceiveQueueLock
, &OldIrql
);
78 InsertTailList( &FCB
->ReceiveQueue
, &Buffer
->ListEntry
);
80 TryToSatisfyRecvRequest( FCB
, TRUE
);
82 KeReleaseSpinLock(&FCB
->ReceiveQueueLock
, OldIrql
);
84 *BytesTaken
= BytesAvailable
;
86 AFD_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
88 return STATUS_SUCCESS
;
92 TDI_STATUS
ClientEventReceiveExpedited(
93 IN PVOID TdiEventContext
,
94 IN CONNECTION_CONTEXT ConnectionContext
,
95 IN ULONG ReceiveFlags
,
96 IN ULONG BytesIndicated
,
97 IN ULONG BytesAvailable
,
98 OUT ULONG
*BytesTaken
,
100 OUT PIRP
*IoRequestPacket
)
102 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
104 return STATUS_SUCCESS
;
108 NTSTATUS
ClientEventChainedReceive(
109 IN PVOID TdiEventContext
,
110 IN CONNECTION_CONTEXT ConnectionContext
,
111 IN ULONG ReceiveFlags
,
112 IN ULONG ReceiveLength
,
113 IN ULONG StartingOffset
,
115 IN PVOID TsduDescriptor
)
117 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
119 return STATUS_SUCCESS
;
123 NTSTATUS
AfdEventReceiveDatagramHandler(
124 IN PVOID TdiEventContext
,
125 IN LONG SourceAddressLength
,
126 IN PVOID SourceAddress
,
127 IN LONG OptionsLength
,
129 IN ULONG ReceiveDatagramFlags
,
130 IN ULONG BytesIndicated
,
131 IN ULONG BytesAvailable
,
132 OUT ULONG
*BytesTaken
,
134 OUT PIRP
*IoRequestPacket
)
136 PAFDFCB FCB
= (PAFDFCB
)TdiEventContext
;
137 PAFD_READ_REQUEST ReadRequest
;
146 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
148 AFD_DbgPrint(MID_TRACE
, ("Receiving (%d) bytes from (0x%X).\n",
149 BytesAvailable
, *(PULONG
)SourceAddress
));
151 ReceiveBuffer
= ExAllocatePool(NonPagedPool
, BytesAvailable
);
153 return STATUS_INSUFFICIENT_RESOURCES
;
155 /*Buffer = (PAFD_BUFFER)ExAllocateFromNPagedLookasideList(
156 &BufferLookasideList);*/
157 Buffer
= (PAFD_BUFFER
)ExAllocatePool(NonPagedPool
, sizeof(AFD_BUFFER
));
159 ExFreePool(ReceiveBuffer
);
160 return STATUS_INSUFFICIENT_RESOURCES
;
163 /* Copy the data to a local buffer */
164 RtlCopyMemory(ReceiveBuffer
, Tsdu
, BytesAvailable
);
166 Buffer
->Buffer
.len
= BytesAvailable
;
167 Buffer
->Buffer
.buf
= ReceiveBuffer
;
170 ExInterlockedInsertTailList(&FCB
->ReceiveQueue
,
172 &FCB
->ReceiveQueueLock
);
174 KeAcquireSpinLock(&FCB
->ReceiveQueueLock
, &OldIrql
);
176 if (CompleteIrp
= !IsListEmpty(&FCB
->ReadRequestQueue
)) {
177 AFD_DbgPrint(MAX_TRACE
, ("Satisfying read request.\n"));
179 Entry
= RemoveHeadList(&FCB
->ReceiveQueue
);
180 ReadRequest
= CONTAINING_RECORD(Entry
, AFD_READ_REQUEST
, ListEntry
);
182 Status
= FillWSABuffers(FCB
,
183 ReadRequest
->RecvFromRequest
->Buffers
,
184 ReadRequest
->RecvFromRequest
->BufferCount
,
186 FALSE
); /* Packet oriented */
187 ReadRequest
->RecvFromReply
->NumberOfBytesRecvd
= Count
;
188 ReadRequest
->RecvFromReply
->Status
= NO_ERROR
;
190 ReadRequest
->Irp
->IoStatus
.Information
= 0;
191 ReadRequest
->Irp
->IoStatus
.Status
= Status
;
194 KeReleaseSpinLock(&FCB
->ReceiveQueueLock
, OldIrql
);
197 AFD_DbgPrint(MAX_TRACE
, ("Completing IRP at (0x%X).\n", ReadRequest
->Irp
));
198 IoCompleteRequest(ReadRequest
->Irp
, IO_NETWORK_INCREMENT
);
199 *BytesTaken
= BytesAvailable
;
202 AFD_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
204 return STATUS_SUCCESS
;
208 NTSTATUS
AfdRegisterEventHandlers(
213 assert(FCB
->TdiAddressObject
);
215 /* Report errors for all types of sockets */
216 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
218 (PVOID
)AfdEventError
,
220 if (!NT_SUCCESS(Status
)) { return Status
; }
222 switch (FCB
->SocketType
) {
224 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
225 TDI_EVENT_DISCONNECT
,
226 (PVOID
)AfdEventDisconnect
,
228 if (!NT_SUCCESS(Status
)) { return Status
; }
230 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
232 (PVOID
)AfdEventReceive
,
234 if (!NT_SUCCESS(Status
)) { return Status
; }
236 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
237 TDI_EVENT_RECEIVE_EXPEDITED
,
238 (PVOID
)ClientEventReceiveExpedited
,
240 if (!NT_SUCCESS(Status
)) { return Status
; }
242 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
243 TDI_EVENT_CHAINED_RECEIVE
,
244 (PVOID
)ClientEventChainedReceive
,
246 if (!NT_SUCCESS(Status
)) { return Status
; }
251 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
252 TDI_EVENT_RECEIVE_DATAGRAM
,
253 (PVOID
)AfdEventReceiveDatagramHandler
,
255 if (!NT_SUCCESS(Status
)) { return Status
; }
257 return STATUS_SUCCESS
;
261 NTSTATUS
AfdDeregisterEventHandlers(
266 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
270 if (!NT_SUCCESS(Status
)) { return Status
; }
272 switch (FCB
->SocketType
) {
274 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
275 TDI_EVENT_DISCONNECT
,
278 if (!NT_SUCCESS(Status
)) { return Status
; }
280 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
284 if (!NT_SUCCESS(Status
)) { return Status
; }
286 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
287 TDI_EVENT_RECEIVE_EXPEDITED
,
290 if (!NT_SUCCESS(Status
)) { return Status
; }
292 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
293 TDI_EVENT_CHAINED_RECEIVE
,
296 if (!NT_SUCCESS(Status
)) { return Status
; }
301 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
302 TDI_EVENT_RECEIVE_DATAGRAM
,
305 if (!NT_SUCCESS(Status
)) { return Status
; }
307 return STATUS_SUCCESS
;