[SHELL32] SHChangeNotify: Use tree for CDirectoryList (#6784)
[reactos.git] / drivers / network / 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
11 #include <afd.h>
12
13 NTSTATUS AfdEventError(
14 IN PVOID TdiEventContext,
15 IN NTSTATUS Status)
16 {
17 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
18
19 return STATUS_SUCCESS;
20 }
21
22
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)
31 {
32 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
33
34 return STATUS_SUCCESS;
35 }
36
37
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,
45 IN PVOID Tsdu,
46 OUT PIRP *IoRequestPacket)
47 {
48 PAFDFCB FCB = (PAFDFCB)TdiEventContext;
49 PVOID ReceiveBuffer;
50 PAFD_BUFFER Buffer;
51 KIRQL OldIrql;
52
53 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
54
55 AFD_DbgPrint(MID_TRACE, ("Receiving (%d) bytes on socket\n",
56 BytesAvailable));
57
58 ReceiveBuffer = ExAllocatePoolWithTag(NonPagedPool,
59 BytesAvailable,
60 TAG_AFD_DATA_BUFFER);
61
62 if (!ReceiveBuffer)
63 return STATUS_INSUFFICIENT_RESOURCES;
64
65 /*Buffer = (PAFD_BUFFER)ExAllocateFromNPagedLookasideList(
66 &BufferLookasideList);*/
67 Buffer = (PAFD_BUFFER)ExAllocatePoolWithTag(NonPagedPool,
68 sizeof(AFD_BUFFER),
69 TAG_AFD_DATA_BUFFER);
70
71 if (!Buffer) {
72 ExFreePoolWithTag(ReceiveBuffer, TAG_AFD_DATA_BUFFER);
73 return STATUS_INSUFFICIENT_RESOURCES;
74 }
75
76 /* Copy the data to a local buffer */
77 RtlCopyMemory(ReceiveBuffer, Tsdu, BytesAvailable);
78
79 Buffer->Buffer.len = BytesAvailable;
80 Buffer->Buffer.buf = ReceiveBuffer;
81 Buffer->Offset = 0;
82
83 KeAcquireSpinLock(&FCB->ReceiveQueueLock, &OldIrql);
84
85 InsertTailList( &FCB->ReceiveQueue, &Buffer->ListEntry );
86
87 TryToSatisfyRecvRequest( FCB, TRUE );
88
89 KeReleaseSpinLock(&FCB->ReceiveQueueLock, OldIrql);
90
91 *BytesTaken = BytesAvailable;
92
93 AFD_DbgPrint(MAX_TRACE, ("Leaving.\n"));
94
95 return STATUS_SUCCESS;
96 }
97
98
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,
106 IN PVOID Tsdu,
107 OUT PIRP *IoRequestPacket)
108 {
109 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
110
111 return STATUS_SUCCESS;
112 }
113
114
115 NTSTATUS ClientEventChainedReceive(
116 IN PVOID TdiEventContext,
117 IN CONNECTION_CONTEXT ConnectionContext,
118 IN ULONG ReceiveFlags,
119 IN ULONG ReceiveLength,
120 IN ULONG StartingOffset,
121 IN PMDL Tsdu,
122 IN PVOID TsduDescriptor)
123 {
124 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
125
126 return STATUS_SUCCESS;
127 }
128
129
130 NTSTATUS AfdEventReceiveDatagramHandler(
131 IN PVOID TdiEventContext,
132 IN LONG SourceAddressLength,
133 IN PVOID SourceAddress,
134 IN LONG OptionsLength,
135 IN PVOID Options,
136 IN ULONG ReceiveDatagramFlags,
137 IN ULONG BytesIndicated,
138 IN ULONG BytesAvailable,
139 OUT ULONG *BytesTaken,
140 IN PVOID Tsdu,
141 OUT PIRP *IoRequestPacket)
142 {
143 PAFDFCB FCB = (PAFDFCB)TdiEventContext;
144 PAFD_READ_REQUEST ReadRequest;
145 PVOID ReceiveBuffer;
146 PAFD_BUFFER Buffer;
147 PLIST_ENTRY Entry;
148 NTSTATUS Status;
149 KIRQL OldIrql;
150 ULONG Count;
151 BOOLEAN CompleteIrp;
152
153 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
154
155 AFD_DbgPrint(MID_TRACE, ("Receiving (%d) bytes from (0x%X).\n",
156 BytesAvailable, *(PULONG)SourceAddress));
157
158 ReceiveBuffer = ExAllocatePoolWithTag(NonPagedPool,
159 BytesAvailable,
160 TAG_AFD_DATA_BUFFER);
161
162 if (!ReceiveBuffer)
163 return STATUS_INSUFFICIENT_RESOURCES;
164
165 /*Buffer = (PAFD_BUFFER)ExAllocateFromNPagedLookasideList(
166 &BufferLookasideList);*/
167 Buffer = (PAFD_BUFFER)ExAllocatePoolWithTag(NonPagedPool,
168 sizeof(AFD_BUFFER),
169 TAG_AFD_DATA_BUFFER);
170
171 if (!Buffer) {
172 ExFreePoolWithTag(ReceiveBuffer, TAG_AFD_DATA_BUFFER);
173 return STATUS_INSUFFICIENT_RESOURCES;
174 }
175
176 /* Copy the data to a local buffer */
177 RtlCopyMemory(ReceiveBuffer, Tsdu, BytesAvailable);
178
179 Buffer->Buffer.len = BytesAvailable;
180 Buffer->Buffer.buf = ReceiveBuffer;
181 Buffer->Offset = 0;
182
183 ExInterlockedInsertTailList(&FCB->ReceiveQueue,
184 &Buffer->ListEntry,
185 &FCB->ReceiveQueueLock);
186
187 KeAcquireSpinLock(&FCB->ReceiveQueueLock, &OldIrql);
188
189 if (CompleteIrp = !IsListEmpty(&FCB->ReadRequestQueue)) {
190 AFD_DbgPrint(MAX_TRACE, ("Satisfying read request.\n"));
191
192 Entry = RemoveHeadList(&FCB->ReceiveQueue);
193 ReadRequest = CONTAINING_RECORD(Entry, AFD_READ_REQUEST, ListEntry);
194
195 Status = FillWSABuffers(FCB,
196 ReadRequest->RecvFromRequest->Buffers,
197 ReadRequest->RecvFromRequest->BufferCount,
198 &Count,
199 FALSE); /* Packet oriented */
200 ReadRequest->RecvFromReply->NumberOfBytesRecvd = Count;
201 ReadRequest->RecvFromReply->Status = NO_ERROR;
202
203 ReadRequest->Irp->IoStatus.Information = 0;
204 ReadRequest->Irp->IoStatus.Status = Status;
205 }
206
207 KeReleaseSpinLock(&FCB->ReceiveQueueLock, OldIrql);
208
209 if (CompleteIrp) {
210 AFD_DbgPrint(MAX_TRACE, ("Completing IRP at (0x%X).\n", ReadRequest->Irp));
211 IoCompleteRequest(ReadRequest->Irp, IO_NETWORK_INCREMENT);
212 *BytesTaken = BytesAvailable;
213 }
214
215 AFD_DbgPrint(MAX_TRACE, ("Leaving.\n"));
216
217 return STATUS_SUCCESS;
218 }
219
220
221 NTSTATUS AfdRegisterEventHandlers(
222 PAFDFCB FCB)
223 {
224 NTSTATUS Status;
225
226 assert(FCB->TdiAddressObject);
227
228 /* Report errors for all types of sockets */
229 Status = TdiSetEventHandler(FCB->TdiAddressObject,
230 TDI_EVENT_ERROR,
231 (PVOID)AfdEventError,
232 (PVOID)FCB);
233 if (!NT_SUCCESS(Status)) { return Status; }
234
235 switch (FCB->SocketType) {
236 case SOCK_STREAM:
237 Status = TdiSetEventHandler(FCB->TdiAddressObject,
238 TDI_EVENT_DISCONNECT,
239 (PVOID)AfdEventDisconnect,
240 (PVOID)FCB);
241 if (!NT_SUCCESS(Status)) { return Status; }
242
243 Status = TdiSetEventHandler(FCB->TdiAddressObject,
244 TDI_EVENT_RECEIVE,
245 (PVOID)AfdEventReceive,
246 (PVOID)FCB);
247 if (!NT_SUCCESS(Status)) { return Status; }
248
249 Status = TdiSetEventHandler(FCB->TdiAddressObject,
250 TDI_EVENT_RECEIVE_EXPEDITED,
251 (PVOID)ClientEventReceiveExpedited,
252 (PVOID)FCB);
253 if (!NT_SUCCESS(Status)) { return Status; }
254
255 Status = TdiSetEventHandler(FCB->TdiAddressObject,
256 TDI_EVENT_CHAINED_RECEIVE,
257 (PVOID)ClientEventChainedReceive,
258 (PVOID)FCB);
259 if (!NT_SUCCESS(Status)) { return Status; }
260 break;
261
262 case SOCK_DGRAM:
263 case SOCK_RAW:
264 Status = TdiSetEventHandler(FCB->TdiAddressObject,
265 TDI_EVENT_RECEIVE_DATAGRAM,
266 (PVOID)AfdEventReceiveDatagramHandler,
267 (PVOID)FCB);
268 if (!NT_SUCCESS(Status)) { return Status; }
269 }
270 return STATUS_SUCCESS;
271 }
272
273
274 NTSTATUS AfdDeregisterEventHandlers(
275 PAFDFCB FCB)
276 {
277 NTSTATUS Status;
278
279 Status = TdiSetEventHandler(FCB->TdiAddressObject,
280 TDI_EVENT_ERROR,
281 NULL,
282 NULL);
283 if (!NT_SUCCESS(Status)) { return Status; }
284
285 switch (FCB->SocketType) {
286 case SOCK_STREAM:
287 Status = TdiSetEventHandler(FCB->TdiAddressObject,
288 TDI_EVENT_DISCONNECT,
289 NULL,
290 NULL);
291 if (!NT_SUCCESS(Status)) { return Status; }
292
293 Status = TdiSetEventHandler(FCB->TdiAddressObject,
294 TDI_EVENT_RECEIVE,
295 NULL,
296 NULL);
297 if (!NT_SUCCESS(Status)) { return Status; }
298
299 Status = TdiSetEventHandler(FCB->TdiAddressObject,
300 TDI_EVENT_RECEIVE_EXPEDITED,
301 NULL,
302 NULL);
303 if (!NT_SUCCESS(Status)) { return Status; }
304
305 Status = TdiSetEventHandler(FCB->TdiAddressObject,
306 TDI_EVENT_CHAINED_RECEIVE,
307 NULL,
308 NULL);
309 if (!NT_SUCCESS(Status)) { return Status; }
310 break;
311
312 case SOCK_DGRAM:
313 case SOCK_RAW:
314 Status = TdiSetEventHandler(FCB->TdiAddressObject,
315 TDI_EVENT_RECEIVE_DATAGRAM,
316 NULL,
317 NULL);
318 if (!NT_SUCCESS(Status)) { return Status; }
319 }
320 return STATUS_SUCCESS;
321 }
322
323 /* EOF */