425df8b71d18d502fd180b7e3529d75341538453
[reactos.git] / reactos / drivers / net / afd / afd / event.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver
4 * FILE: afd/event.c
5 * PURPOSE: TDI event handlers
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * REVISIONS:
8 * CSH 01/09-2000 Created
9 */
10 #include <afd.h>
11
12 NTSTATUS AfdEventError(
13 IN PVOID TdiEventContext,
14 IN NTSTATUS Status)
15 {
16 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
17
18 return STATUS_SUCCESS;
19 }
20
21
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)
30 {
31 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
32
33 return STATUS_SUCCESS;
34 }
35
36
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,
44 IN PVOID Tsdu,
45 OUT PIRP *IoRequestPacket)
46 {
47 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
48
49 return STATUS_SUCCESS;
50 }
51
52
53 TDI_STATUS ClientEventReceiveExpedited(
54 IN PVOID TdiEventContext,
55 IN CONNECTION_CONTEXT ConnectionContext,
56 IN ULONG ReceiveFlags,
57 IN ULONG BytesIndicated,
58 IN ULONG BytesAvailable,
59 OUT ULONG *BytesTaken,
60 IN PVOID Tsdu,
61 OUT PIRP *IoRequestPacket)
62 {
63 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
64
65 return STATUS_SUCCESS;
66 }
67
68
69 NTSTATUS ClientEventChainedReceive(
70 IN PVOID TdiEventContext,
71 IN CONNECTION_CONTEXT ConnectionContext,
72 IN ULONG ReceiveFlags,
73 IN ULONG ReceiveLength,
74 IN ULONG StartingOffset,
75 IN PMDL Tsdu,
76 IN PVOID TsduDescriptor)
77 {
78 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
79
80 return STATUS_SUCCESS;
81 }
82
83
84 NTSTATUS AfdEventReceiveDatagramHandler(
85 IN PVOID TdiEventContext,
86 IN LONG SourceAddressLength,
87 IN PVOID SourceAddress,
88 IN LONG OptionsLength,
89 IN PVOID Options,
90 IN ULONG ReceiveDatagramFlags,
91 IN ULONG BytesIndicated,
92 IN ULONG BytesAvailable,
93 OUT ULONG *BytesTaken,
94 IN PVOID Tsdu,
95 OUT PIRP *IoRequestPacket)
96 {
97 PAFDFCB FCB = (PAFDFCB)TdiEventContext;
98 PAFD_READ_REQUEST ReadRequest;
99 PVOID ReceiveBuffer;
100 PAFD_BUFFER Buffer;
101 PLIST_ENTRY Entry;
102 NTSTATUS Status;
103 KIRQL OldIrql;
104
105 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
106
107 AFD_DbgPrint(MID_TRACE, ("Receiving (%d) bytes from (0x%X).\n",
108 BytesAvailable, *(PULONG)SourceAddress));
109
110 ReceiveBuffer = ExAllocatePool(NonPagedPool, BytesAvailable);
111 if (!ReceiveBuffer) {
112 return STATUS_INSUFFICIENT_RESOURCES;
113 }
114
115 /*Buffer = (PAFD_BUFFER)ExAllocateFromNPagedLookasideList(
116 &BufferLookasideList);*/
117 Buffer = (PAFD_BUFFER)ExAllocatePool(NonPagedPool, sizeof(AFD_BUFFER));
118 if (!Buffer) {
119 ExFreePool(ReceiveBuffer);
120 return STATUS_INSUFFICIENT_RESOURCES;
121 }
122
123 /* Copy the data to a local buffer */
124 RtlCopyMemory(ReceiveBuffer, Tsdu, BytesAvailable);
125
126 Buffer->Buffer.len = BytesAvailable;
127 Buffer->Buffer.buf = ReceiveBuffer;
128
129 ExInterlockedInsertTailList(
130 &FCB->ReceiveQueue,
131 &Buffer->ListEntry,
132 &FCB->ReceiveQueueLock);
133
134 KeAcquireSpinLock(&FCB->ReadRequestQueueLock, &OldIrql);
135
136 if (!IsListEmpty(&FCB->ReadRequestQueue)) {
137 Entry = RemoveHeadList(&FCB->ReceiveQueue);
138 ReadRequest = CONTAINING_RECORD(Entry, AFD_READ_REQUEST, ListEntry);
139
140 Status = FillWSABuffers(
141 FCB,
142 ReadRequest->RecvFromRequest->Buffers,
143 ReadRequest->RecvFromRequest->BufferCount,
144 &ReadRequest->RecvFromReply->NumberOfBytesRecvd);
145 ReadRequest->RecvFromReply->Status = NO_ERROR;
146
147 ReadRequest->Irp->IoStatus.Information = 0;
148 ReadRequest->Irp->IoStatus.Status = Status;
149 IoCompleteRequest(ReadRequest->Irp, IO_NETWORK_INCREMENT);
150 }
151
152 KeReleaseSpinLock(&FCB->ReadRequestQueueLock, OldIrql);
153
154 *BytesTaken = BytesAvailable;
155
156 AFD_DbgPrint(MAX_TRACE, ("Leaving.\n"));
157
158 return STATUS_SUCCESS;
159 }
160
161
162 NTSTATUS AfdRegisterEventHandlers(
163 PAFDFCB FCB)
164 {
165 NTSTATUS Status;
166
167 assert(FCB->TdiAddressObject);
168
169 /* Report errors for all types of sockets */
170 Status = TdiSetEventHandler(FCB->TdiAddressObject,
171 TDI_EVENT_ERROR,
172 (PVOID)AfdEventError,
173 (PVOID)FCB);
174 if (!NT_SUCCESS(Status)) { return Status; }
175
176 switch (FCB->SocketType) {
177 case SOCK_STREAM:
178 Status = TdiSetEventHandler(FCB->TdiAddressObject,
179 TDI_EVENT_DISCONNECT,
180 (PVOID)AfdEventDisconnect,
181 (PVOID)FCB);
182 if (!NT_SUCCESS(Status)) { return Status; }
183
184 Status = TdiSetEventHandler(FCB->TdiAddressObject,
185 TDI_EVENT_RECEIVE,
186 (PVOID)AfdEventReceive,
187 (PVOID)FCB);
188 if (!NT_SUCCESS(Status)) { return Status; }
189
190 Status = TdiSetEventHandler(FCB->TdiAddressObject,
191 TDI_EVENT_RECEIVE_EXPEDITED,
192 (PVOID)ClientEventReceiveExpedited,
193 (PVOID)FCB);
194 if (!NT_SUCCESS(Status)) { return Status; }
195
196 Status = TdiSetEventHandler(FCB->TdiAddressObject,
197 TDI_EVENT_CHAINED_RECEIVE,
198 (PVOID)ClientEventChainedReceive,
199 (PVOID)FCB);
200 if (!NT_SUCCESS(Status)) { return Status; }
201 break;
202
203 case SOCK_DGRAM:
204 case SOCK_RAW:
205 Status = TdiSetEventHandler(FCB->TdiAddressObject,
206 TDI_EVENT_RECEIVE_DATAGRAM,
207 (PVOID)AfdEventReceiveDatagramHandler,
208 (PVOID)FCB);
209 if (!NT_SUCCESS(Status)) { return Status; }
210 }
211 return STATUS_SUCCESS;
212 }
213
214
215 NTSTATUS AfdDeregisterEventHandlers(
216 PAFDFCB FCB)
217 {
218 NTSTATUS Status;
219
220 Status = TdiSetEventHandler(FCB->TdiAddressObject,
221 TDI_EVENT_ERROR,
222 NULL,
223 NULL);
224 if (!NT_SUCCESS(Status)) { return Status; }
225
226 switch (FCB->SocketType) {
227 case SOCK_STREAM:
228 Status = TdiSetEventHandler(FCB->TdiAddressObject,
229 TDI_EVENT_DISCONNECT,
230 NULL,
231 NULL);
232 if (!NT_SUCCESS(Status)) { return Status; }
233
234 Status = TdiSetEventHandler(FCB->TdiAddressObject,
235 TDI_EVENT_RECEIVE,
236 NULL,
237 NULL);
238 if (!NT_SUCCESS(Status)) { return Status; }
239
240 Status = TdiSetEventHandler(FCB->TdiAddressObject,
241 TDI_EVENT_RECEIVE_EXPEDITED,
242 NULL,
243 NULL);
244 if (!NT_SUCCESS(Status)) { return Status; }
245
246 Status = TdiSetEventHandler(FCB->TdiAddressObject,
247 TDI_EVENT_CHAINED_RECEIVE,
248 NULL,
249 NULL);
250 if (!NT_SUCCESS(Status)) { return Status; }
251 break;
252
253 case SOCK_DGRAM:
254 case SOCK_RAW:
255 Status = TdiSetEventHandler(FCB->TdiAddressObject,
256 TDI_EVENT_RECEIVE_DATAGRAM,
257 NULL,
258 NULL);
259 if (!NT_SUCCESS(Status)) { return Status; }
260 }
261 return STATUS_SUCCESS;
262 }
263
264
265 /* EOF */