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
= ExAllocatePool(NonPagedPool
, BytesAvailable
);
60 return STATUS_INSUFFICIENT_RESOURCES
;
62 /*Buffer = (PAFD_BUFFER)ExAllocateFromNPagedLookasideList(
63 &BufferLookasideList);*/
64 Buffer
= (PAFD_BUFFER
)ExAllocatePool(NonPagedPool
, sizeof(AFD_BUFFER
));
66 ExFreePool(ReceiveBuffer
);
67 return STATUS_INSUFFICIENT_RESOURCES
;
70 /* Copy the data to a local buffer */
71 RtlCopyMemory(ReceiveBuffer
, Tsdu
, BytesAvailable
);
73 Buffer
->Buffer
.len
= BytesAvailable
;
74 Buffer
->Buffer
.buf
= ReceiveBuffer
;
77 KeAcquireSpinLock(&FCB
->ReceiveQueueLock
, &OldIrql
);
79 InsertTailList( &FCB
->ReceiveQueue
, &Buffer
->ListEntry
);
81 TryToSatisfyRecvRequest( FCB
, TRUE
);
83 KeReleaseSpinLock(&FCB
->ReceiveQueueLock
, OldIrql
);
85 *BytesTaken
= BytesAvailable
;
87 AFD_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
89 return STATUS_SUCCESS
;
93 TDI_STATUS
ClientEventReceiveExpedited(
94 IN PVOID TdiEventContext
,
95 IN CONNECTION_CONTEXT ConnectionContext
,
96 IN ULONG ReceiveFlags
,
97 IN ULONG BytesIndicated
,
98 IN ULONG BytesAvailable
,
99 OUT ULONG
*BytesTaken
,
101 OUT PIRP
*IoRequestPacket
)
103 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
105 return STATUS_SUCCESS
;
109 NTSTATUS
ClientEventChainedReceive(
110 IN PVOID TdiEventContext
,
111 IN CONNECTION_CONTEXT ConnectionContext
,
112 IN ULONG ReceiveFlags
,
113 IN ULONG ReceiveLength
,
114 IN ULONG StartingOffset
,
116 IN PVOID TsduDescriptor
)
118 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
120 return STATUS_SUCCESS
;
124 NTSTATUS
AfdEventReceiveDatagramHandler(
125 IN PVOID TdiEventContext
,
126 IN LONG SourceAddressLength
,
127 IN PVOID SourceAddress
,
128 IN LONG OptionsLength
,
130 IN ULONG ReceiveDatagramFlags
,
131 IN ULONG BytesIndicated
,
132 IN ULONG BytesAvailable
,
133 OUT ULONG
*BytesTaken
,
135 OUT PIRP
*IoRequestPacket
)
137 PAFDFCB FCB
= (PAFDFCB
)TdiEventContext
;
138 PAFD_READ_REQUEST ReadRequest
;
147 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
149 AFD_DbgPrint(MID_TRACE
, ("Receiving (%d) bytes from (0x%X).\n",
150 BytesAvailable
, *(PULONG
)SourceAddress
));
152 ReceiveBuffer
= ExAllocatePool(NonPagedPool
, BytesAvailable
);
154 return STATUS_INSUFFICIENT_RESOURCES
;
156 /*Buffer = (PAFD_BUFFER)ExAllocateFromNPagedLookasideList(
157 &BufferLookasideList);*/
158 Buffer
= (PAFD_BUFFER
)ExAllocatePool(NonPagedPool
, sizeof(AFD_BUFFER
));
160 ExFreePool(ReceiveBuffer
);
161 return STATUS_INSUFFICIENT_RESOURCES
;
164 /* Copy the data to a local buffer */
165 RtlCopyMemory(ReceiveBuffer
, Tsdu
, BytesAvailable
);
167 Buffer
->Buffer
.len
= BytesAvailable
;
168 Buffer
->Buffer
.buf
= ReceiveBuffer
;
171 ExInterlockedInsertTailList(&FCB
->ReceiveQueue
,
173 &FCB
->ReceiveQueueLock
);
175 KeAcquireSpinLock(&FCB
->ReceiveQueueLock
, &OldIrql
);
177 if (CompleteIrp
= !IsListEmpty(&FCB
->ReadRequestQueue
)) {
178 AFD_DbgPrint(MAX_TRACE
, ("Satisfying read request.\n"));
180 Entry
= RemoveHeadList(&FCB
->ReceiveQueue
);
181 ReadRequest
= CONTAINING_RECORD(Entry
, AFD_READ_REQUEST
, ListEntry
);
183 Status
= FillWSABuffers(FCB
,
184 ReadRequest
->RecvFromRequest
->Buffers
,
185 ReadRequest
->RecvFromRequest
->BufferCount
,
187 FALSE
); /* Packet oriented */
188 ReadRequest
->RecvFromReply
->NumberOfBytesRecvd
= Count
;
189 ReadRequest
->RecvFromReply
->Status
= NO_ERROR
;
191 ReadRequest
->Irp
->IoStatus
.Information
= 0;
192 ReadRequest
->Irp
->IoStatus
.Status
= Status
;
195 KeReleaseSpinLock(&FCB
->ReceiveQueueLock
, OldIrql
);
198 AFD_DbgPrint(MAX_TRACE
, ("Completing IRP at (0x%X).\n", ReadRequest
->Irp
));
199 IoCompleteRequest(ReadRequest
->Irp
, IO_NETWORK_INCREMENT
);
200 *BytesTaken
= BytesAvailable
;
203 AFD_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
205 return STATUS_SUCCESS
;
209 NTSTATUS
AfdRegisterEventHandlers(
214 assert(FCB
->TdiAddressObject
);
216 /* Report errors for all types of sockets */
217 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
219 (PVOID
)AfdEventError
,
221 if (!NT_SUCCESS(Status
)) { return Status
; }
223 switch (FCB
->SocketType
) {
225 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
226 TDI_EVENT_DISCONNECT
,
227 (PVOID
)AfdEventDisconnect
,
229 if (!NT_SUCCESS(Status
)) { return Status
; }
231 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
233 (PVOID
)AfdEventReceive
,
235 if (!NT_SUCCESS(Status
)) { return Status
; }
237 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
238 TDI_EVENT_RECEIVE_EXPEDITED
,
239 (PVOID
)ClientEventReceiveExpedited
,
241 if (!NT_SUCCESS(Status
)) { return Status
; }
243 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
244 TDI_EVENT_CHAINED_RECEIVE
,
245 (PVOID
)ClientEventChainedReceive
,
247 if (!NT_SUCCESS(Status
)) { return Status
; }
252 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
253 TDI_EVENT_RECEIVE_DATAGRAM
,
254 (PVOID
)AfdEventReceiveDatagramHandler
,
256 if (!NT_SUCCESS(Status
)) { return Status
; }
258 return STATUS_SUCCESS
;
262 NTSTATUS
AfdDeregisterEventHandlers(
267 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
271 if (!NT_SUCCESS(Status
)) { return Status
; }
273 switch (FCB
->SocketType
) {
275 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
276 TDI_EVENT_DISCONNECT
,
279 if (!NT_SUCCESS(Status
)) { return Status
; }
281 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
285 if (!NT_SUCCESS(Status
)) { return Status
; }
287 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
288 TDI_EVENT_RECEIVE_EXPEDITED
,
291 if (!NT_SUCCESS(Status
)) { return Status
; }
293 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
294 TDI_EVENT_CHAINED_RECEIVE
,
297 if (!NT_SUCCESS(Status
)) { return Status
; }
302 Status
= TdiSetEventHandler(FCB
->TdiAddressObject
,
303 TDI_EVENT_RECEIVE_DATAGRAM
,
306 if (!NT_SUCCESS(Status
)) { return Status
; }
308 return STATUS_SUCCESS
;