Add "#pragma code_page(...)" again to fix compilation.
[reactos.git] / reactos / drivers / network / afd / afd / main.c
1 /* $Id$
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/net/afd/afd/main.c
5 * PURPOSE: Ancillary functions driver
6 * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
7 * UPDATE HISTORY:
8 * 20040630 Created
9 *
10 * Suggestions: Uniform naming (AfdXxx)
11 */
12
13 /* INCLUDES */
14
15 #include "afd.h"
16 #include "tdi_proto.h"
17 #include "tdiconn.h"
18 #include "debug.h"
19
20 #if DBG
21
22 /* See debug.h for debug/trace constants */
23 //DWORD DebugTraceLevel = DEBUG_ULTRA;
24 DWORD DebugTraceLevel = 0;
25
26 #endif /* DBG */
27
28 void OskitDumpBuffer( PCHAR Data, UINT Len ) {
29 unsigned int i;
30
31 for( i = 0; i < Len; i++ ) {
32 if( i && !(i & 0xf) ) DbgPrint( "\n" );
33 if( !(i & 0xf) ) DbgPrint( "%08x: ", (UINT)(Data + i) );
34 DbgPrint( " %02x", Data[i] & 0xff );
35 }
36 DbgPrint("\n");
37 }
38
39 /* FUNCTIONS */
40
41 NTSTATUS NTAPI
42 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
43
44 static NTSTATUS NTAPI
45 AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
46 PIO_STACK_LOCATION IrpSp) {
47 PAFD_FCB FCB;
48 PFILE_OBJECT FileObject;
49 PAFD_DEVICE_EXTENSION DeviceExt;
50 PFILE_FULL_EA_INFORMATION EaInfo;
51 PAFD_CREATE_PACKET ConnectInfo = NULL;
52 ULONG EaLength;
53 PWCHAR EaInfoValue = NULL;
54 UINT Disposition, i;
55 NTSTATUS Status = STATUS_SUCCESS;
56
57 AFD_DbgPrint(MID_TRACE,
58 ("AfdCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp));
59
60 DeviceExt = DeviceObject->DeviceExtension;
61 FileObject = IrpSp->FileObject;
62 Disposition = (IrpSp->Parameters.Create.Options >> 24) & 0xff;
63
64 Irp->IoStatus.Information = 0;
65
66 EaInfo = Irp->AssociatedIrp.SystemBuffer;
67
68 if( EaInfo ) {
69 ConnectInfo = (PAFD_CREATE_PACKET)(EaInfo->EaName + EaInfo->EaNameLength + 1);
70 EaInfoValue = (PWCHAR)(((PCHAR)ConnectInfo) + sizeof(AFD_CREATE_PACKET));
71
72 EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
73 EaInfo->EaNameLength +
74 EaInfo->EaValueLength;
75
76 AFD_DbgPrint(MID_TRACE,("EaInfo: %x, EaInfoValue: %x\n",
77 EaInfo, EaInfoValue));
78 }
79
80 AFD_DbgPrint(MID_TRACE,("About to allocate the new FCB\n"));
81
82 FCB = ExAllocatePool(NonPagedPool, sizeof(AFD_FCB));
83 if( FCB == NULL ) {
84 Irp->IoStatus.Status = STATUS_NO_MEMORY;
85 IoCompleteRequest(Irp, IO_NO_INCREMENT);
86 return STATUS_NO_MEMORY;
87 }
88
89 AFD_DbgPrint(MID_TRACE,("Initializing the new FCB @ %x (FileObject %x Flags %x)\n", FCB, FileObject, ConnectInfo ? ConnectInfo->EndpointFlags : 0));
90
91 RtlZeroMemory( FCB, sizeof( *FCB ) );
92
93 FCB->Flags = ConnectInfo ? ConnectInfo->EndpointFlags : 0;
94 FCB->GroupID = ConnectInfo ? ConnectInfo->GroupID : 0;
95 FCB->GroupType = 0; /* FIXME */
96 FCB->State = SOCKET_STATE_CREATED;
97 FCB->FileObject = FileObject;
98 FCB->DeviceExt = DeviceExt;
99 FCB->Recv.Size = DEFAULT_RECEIVE_WINDOW_SIZE;
100 FCB->Send.Size = DEFAULT_SEND_WINDOW_SIZE;
101 FCB->AddressFile.Handle = INVALID_HANDLE_VALUE;
102 FCB->Connection.Handle = INVALID_HANDLE_VALUE;
103
104 KeInitializeSpinLock( &FCB->SpinLock );
105 ExInitializeFastMutex( &FCB->Mutex );
106 KeInitializeEvent( &FCB->StateLockedEvent, NotificationEvent, FALSE );
107
108 for( i = 0; i < MAX_FUNCTIONS; i++ ) {
109 InitializeListHead( &FCB->PendingIrpList[i] );
110 }
111
112 InitializeListHead( &FCB->DatagramList );
113 InitializeListHead( &FCB->PendingConnections );
114
115 AFD_DbgPrint(MID_TRACE,("%x: Checking command channel\n", FCB));
116
117 if( ConnectInfo ) {
118 FCB->TdiDeviceName.Length = ConnectInfo->SizeOfTransportName;
119 FCB->TdiDeviceName.MaximumLength = FCB->TdiDeviceName.Length;
120 FCB->TdiDeviceName.Buffer =
121 ExAllocatePool( NonPagedPool, FCB->TdiDeviceName.Length );
122
123 if( !FCB->TdiDeviceName.Buffer ) {
124 ExFreePool(FCB);
125 AFD_DbgPrint(MID_TRACE,("Could not copy target string\n"));
126 Irp->IoStatus.Status = STATUS_NO_MEMORY;
127 IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
128 return STATUS_NO_MEMORY;
129 }
130
131 RtlCopyMemory( FCB->TdiDeviceName.Buffer,
132 ConnectInfo->TransportName,
133 FCB->TdiDeviceName.Length );
134
135 AFD_DbgPrint(MID_TRACE,("Success: %s %wZ\n",
136 EaInfo->EaName, &FCB->TdiDeviceName));
137 } else {
138 AFD_DbgPrint(MID_TRACE,("Success: Control connection\n"));
139 }
140
141 FileObject->FsContext = FCB;
142
143 /* It seems that UDP sockets are writable from inception */
144 if( FCB->Flags & SGID_CONNECTIONLESS ) {
145 AFD_DbgPrint(MID_TRACE,("Packet oriented socket\n"));
146 /* Allocate our backup buffer */
147 FCB->Recv.Window = ExAllocatePool( NonPagedPool, FCB->Recv.Size );
148 if( !FCB->Recv.Window ) Status = STATUS_NO_MEMORY;
149 if( NT_SUCCESS(Status) )
150 {
151 FCB->Send.Window = ExAllocatePool( NonPagedPool, FCB->Send.Size );
152 if( !FCB->Send.Window ) {
153 if( FCB->Recv.Window ) ExFreePool( FCB->Recv.Window );
154 Status = STATUS_NO_MEMORY;
155 }
156 }
157 /* A datagram socket is always sendable */
158 FCB->PollState |= AFD_EVENT_SEND;
159 PollReeval( FCB->DeviceExt, FCB->FileObject );
160 }
161
162 if( !NT_SUCCESS(Status) ) {
163 if( FCB->TdiDeviceName.Buffer ) ExFreePool( FCB->TdiDeviceName.Buffer );
164 ExFreePool( FCB );
165 FileObject->FsContext = NULL;
166 }
167
168 Irp->IoStatus.Status = Status;
169 IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
170
171 return Status;
172 }
173
174 static NTSTATUS NTAPI
175 AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
176 PIO_STACK_LOCATION IrpSp)
177 {
178 PFILE_OBJECT FileObject = IrpSp->FileObject;
179 PAFD_FCB FCB = FileObject->FsContext;
180 UINT i;
181 PAFD_IN_FLIGHT_REQUEST InFlightRequest[IN_FLIGHT_REQUESTS];
182
183 AFD_DbgPrint(MID_TRACE,
184 ("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp));
185
186 if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED;
187
188 FCB->State = SOCKET_STATE_CLOSED;
189 FCB->PollState = AFD_EVENT_CLOSE;
190 PollReeval( FCB->DeviceExt, FCB->FileObject );
191
192 InFlightRequest[0] = &FCB->ListenIrp;
193 InFlightRequest[1] = &FCB->ReceiveIrp;
194 InFlightRequest[2] = &FCB->SendIrp;
195 InFlightRequest[3] = &FCB->ConnectIrp;
196
197 /* Cancel our pending requests */
198 for( i = 0; i < IN_FLIGHT_REQUESTS; i++ ) {
199 if( InFlightRequest[i]->InFlightRequest ) {
200 AFD_DbgPrint(MID_TRACE,("Cancelling in flight irp %d (%x)\n",
201 i, InFlightRequest[i]->InFlightRequest));
202 IoCancelIrp(InFlightRequest[i]->InFlightRequest);
203 }
204 }
205
206 KillSelectsForFCB( FCB->DeviceExt, FileObject, FALSE );
207
208 SocketStateUnlock( FCB );
209
210 if( FCB->EventSelect )
211 ObDereferenceObject( FCB->EventSelect );
212
213 if( FCB->Context )
214 ExFreePool( FCB->Context );
215
216 if( FCB->Recv.Window )
217 ExFreePool( FCB->Recv.Window );
218
219 if( FCB->Send.Window )
220 ExFreePool( FCB->Send.Window );
221
222 if( FCB->AddressFrom )
223 ExFreePool( FCB->AddressFrom );
224
225 if( FCB->LocalAddress )
226 ExFreePool( FCB->LocalAddress );
227
228 if( FCB->RemoteAddress )
229 ExFreePool( FCB->RemoteAddress );
230
231 if( FCB->Connection.Object )
232 ObDereferenceObject(FCB->Connection.Object);
233
234 if( FCB->AddressFile.Object )
235 ObDereferenceObject(FCB->AddressFile.Object);
236
237 if( FCB->AddressFile.Handle != INVALID_HANDLE_VALUE )
238 {
239 if (ZwClose(FCB->AddressFile.Handle) == STATUS_INVALID_HANDLE)
240 {
241 DbgPrint("INVALID ADDRESS FILE HANDLE VALUE: %x %x\n", FCB->AddressFile.Handle, FCB->AddressFile.Object);
242 }
243 }
244
245 if( FCB->Connection.Handle != INVALID_HANDLE_VALUE )
246 {
247 if (ZwClose(FCB->Connection.Handle) == STATUS_INVALID_HANDLE)
248 {
249 DbgPrint("INVALID CONNECTION HANDLE VALUE: %x %x\n", FCB->Connection.Handle, FCB->Connection.Object);
250 }
251 }
252
253 if( FCB->TdiDeviceName.Buffer )
254 ExFreePool(FCB->TdiDeviceName.Buffer);
255
256 ExFreePool(FCB);
257
258 Irp->IoStatus.Status = STATUS_SUCCESS;
259 Irp->IoStatus.Information = 0;
260 IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
261
262 AFD_DbgPrint(MID_TRACE, ("Returning success.\n"));
263
264 return STATUS_SUCCESS;
265 }
266
267 static NTSTATUS NTAPI
268 AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
269 PIO_STACK_LOCATION IrpSp) {
270 PFILE_OBJECT FileObject = IrpSp->FileObject;
271 PAFD_FCB FCB = FileObject->FsContext;
272 PAFD_DISCONNECT_INFO DisReq;
273 IO_STATUS_BLOCK Iosb;
274 PTDI_CONNECTION_INFORMATION ConnInfo;
275 NTSTATUS Status;
276 USHORT Flags = 0;
277
278 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
279
280 if( !(DisReq = LockRequest( Irp, IrpSp )) )
281 return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
282 Irp, 0 );
283
284 if (NULL == FCB->RemoteAddress)
285 {
286 ConnInfo = NULL;
287 }
288 else
289 {
290 Status = TdiBuildNullConnectionInfo
291 ( &ConnInfo, FCB->RemoteAddress->Address[0].AddressType );
292
293 if( !NT_SUCCESS(Status) || !ConnInfo )
294 return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
295 Irp, 0 );
296 }
297
298 if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
299 Flags |= TDI_DISCONNECT_RELEASE;
300 if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
301 DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
302 Flags |= TDI_DISCONNECT_ABORT;
303
304 Status = TdiDisconnect( FCB->Connection.Object,
305 &DisReq->Timeout,
306 Flags,
307 &Iosb,
308 NULL,
309 NULL,
310 FCB->AddressFrom,
311 ConnInfo);
312
313 if (ConnInfo) ExFreePool( ConnInfo );
314
315 FCB->PollState |= AFD_EVENT_DISCONNECT;
316 PollReeval( FCB->DeviceExt, FCB->FileObject );
317
318 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
319 }
320
321 static NTSTATUS NTAPI
322 AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
323 {
324 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
325 NTSTATUS Status = STATUS_SUCCESS;
326 #if DBG
327 PFILE_OBJECT FileObject = IrpSp->FileObject;
328 #endif
329
330 AFD_DbgPrint(MID_TRACE,("AfdDispatch: %d\n", IrpSp->MajorFunction));
331 if( IrpSp->MajorFunction != IRP_MJ_CREATE) {
332 AFD_DbgPrint(MID_TRACE,("FO %x, IrpSp->FO %x\n",
333 FileObject, IrpSp->FileObject));
334 ASSERT(FileObject == IrpSp->FileObject);
335 }
336
337 Irp->IoStatus.Information = 0;
338
339 switch(IrpSp->MajorFunction)
340 {
341 /* opening and closing handles to the device */
342 case IRP_MJ_CREATE:
343 /* Mostly borrowed from the named pipe file system */
344 return AfdCreateSocket(DeviceObject, Irp, IrpSp);
345
346 case IRP_MJ_CLOSE:
347 /* Ditto the borrowing */
348 return AfdCloseSocket(DeviceObject, Irp, IrpSp);
349
350 /* write data */
351 case IRP_MJ_WRITE:
352 return AfdConnectedSocketWriteData( DeviceObject, Irp, IrpSp, TRUE );
353
354 /* read data */
355 case IRP_MJ_READ:
356 return AfdConnectedSocketReadData( DeviceObject, Irp, IrpSp, TRUE );
357
358 case IRP_MJ_DEVICE_CONTROL:
359 {
360 switch( IrpSp->Parameters.DeviceIoControl.IoControlCode ) {
361 case IOCTL_AFD_BIND:
362 return AfdBindSocket( DeviceObject, Irp, IrpSp );
363
364 case IOCTL_AFD_CONNECT:
365 return AfdStreamSocketConnect( DeviceObject, Irp, IrpSp );
366
367 case IOCTL_AFD_START_LISTEN:
368 return AfdListenSocket( DeviceObject, Irp, IrpSp );
369
370 case IOCTL_AFD_RECV:
371 return AfdConnectedSocketReadData( DeviceObject, Irp, IrpSp,
372 FALSE );
373
374 case IOCTL_AFD_SELECT:
375 return AfdSelect( DeviceObject, Irp, IrpSp );
376
377 case IOCTL_AFD_EVENT_SELECT:
378 return AfdEventSelect( DeviceObject, Irp, IrpSp );
379
380 case IOCTL_AFD_ENUM_NETWORK_EVENTS:
381 return AfdEnumEvents( DeviceObject, Irp, IrpSp );
382
383 case IOCTL_AFD_RECV_DATAGRAM:
384 return AfdPacketSocketReadData( DeviceObject, Irp, IrpSp );
385
386 case IOCTL_AFD_SEND:
387 return AfdConnectedSocketWriteData( DeviceObject, Irp, IrpSp,
388 FALSE );
389
390 case IOCTL_AFD_SEND_DATAGRAM:
391 return AfdPacketSocketWriteData( DeviceObject, Irp, IrpSp );
392
393 case IOCTL_AFD_GET_INFO:
394 return AfdGetInfo( DeviceObject, Irp, IrpSp );
395
396 case IOCTL_AFD_SET_INFO:
397 return AfdSetInfo( DeviceObject, Irp, IrpSp );
398
399 case IOCTL_AFD_GET_CONTEXT:
400 return AfdGetContext( DeviceObject, Irp, IrpSp );
401
402 case IOCTL_AFD_SET_CONTEXT:
403 return AfdSetContext( DeviceObject, Irp, IrpSp );
404
405 case IOCTL_AFD_WAIT_FOR_LISTEN:
406 return AfdWaitForListen( DeviceObject, Irp, IrpSp );
407
408 case IOCTL_AFD_ACCEPT:
409 return AfdAccept( DeviceObject, Irp, IrpSp );
410
411 case IOCTL_AFD_DISCONNECT:
412 return AfdDisconnect( DeviceObject, Irp, IrpSp );
413
414 case IOCTL_AFD_GET_SOCK_NAME:
415 return AfdGetSockName( DeviceObject, Irp, IrpSp );
416
417 case IOCTL_AFD_GET_PEER_NAME:
418 return AfdGetPeerName( DeviceObject, Irp, IrpSp );
419
420 case IOCTL_AFD_GET_TDI_HANDLES:
421 AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_GET_TDI_HANDLES\n"));
422 break;
423
424 case IOCTL_AFD_SET_CONNECT_DATA:
425 AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_CONNECT_DATA\n"));
426 break;
427
428 case IOCTL_AFD_SET_CONNECT_OPTIONS:
429 AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_CONNECT_OPTIONS\n"));
430 break;
431
432 case IOCTL_AFD_SET_DISCONNECT_DATA:
433 AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_DISCONNECT_DATA\n"));
434 break;
435
436 case IOCTL_AFD_SET_DISCONNECT_OPTIONS:
437 AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_DISCONNECT_OPTIONS\n"));
438 break;
439
440 case IOCTL_AFD_GET_CONNECT_DATA:
441 AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_GET_CONNECT_DATA\n"));
442 break;
443
444 case IOCTL_AFD_GET_CONNECT_OPTIONS:
445 AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_GET_CONNECT_OPTIONS\n"));
446 break;
447
448 case IOCTL_AFD_GET_DISCONNECT_DATA:
449 AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_GET_DISCONNECT_DATA\n"));
450 break;
451
452 case IOCTL_AFD_GET_DISCONNECT_OPTIONS:
453 AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_GET_DISCONNECT_OPTIONS\n"));
454 break;
455
456 case IOCTL_AFD_SET_CONNECT_DATA_SIZE:
457 AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_CONNECT_DATA_SIZE\n"));
458 break;
459
460 case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE:
461 AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE\n"));
462 break;
463
464 case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE:
465 AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_DISCONNECT_DATA_SIZE\n"));
466 break;
467
468 case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE:
469 AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE\n"));
470 break;
471
472 case IOCTL_AFD_DEFER_ACCEPT:
473 AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_DEFER_ACCEPT\n"));
474 break;
475
476 case IOCTL_AFD_GET_PENDING_CONNECT_DATA:
477 AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_GET_PENDING_CONNECT_DATA\n"));
478 break;
479
480 default:
481 Status = STATUS_NOT_IMPLEMENTED;
482 AFD_DbgPrint(MIN_TRACE, ("Unknown IOCTL (0x%x)\n",
483 IrpSp->Parameters.DeviceIoControl.
484 IoControlCode));
485 break;
486 }
487 break;
488 }
489
490 /* unsupported operations */
491 default:
492 {
493 Status = STATUS_NOT_IMPLEMENTED;
494 AFD_DbgPrint(MIN_TRACE,
495 ("Irp: Unknown Major code was %x\n",
496 IrpSp->MajorFunction));
497 break;
498 }
499 }
500
501 AFD_DbgPrint(MID_TRACE, ("Returning %x\n", Status));
502 Irp->IoStatus.Status = Status;
503 IoCompleteRequest(Irp, IO_NO_INCREMENT);
504
505 return (Status);
506 }
507
508 VOID NTAPI
509 AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
510 PIRP Irp)
511 {
512 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
513 PFILE_OBJECT FileObject = IrpSp->FileObject;
514 PAFD_FCB FCB = FileObject->FsContext;
515 UINT Function;
516 PAFD_RECV_INFO RecvReq;
517 PAFD_SEND_INFO SendReq;
518 PLIST_ENTRY CurrentEntry;
519 PIRP CurrentIrp;
520 PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
521 KIRQL OldIrql;
522 PAFD_ACTIVE_POLL Poll;
523 PAFD_POLL_INFO PollReq;
524
525 IoReleaseCancelSpinLock(Irp->CancelIrql);
526
527 if (!SocketAcquireStateLock(FCB))
528 return;
529
530 ASSERT(IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL);
531
532 switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
533 {
534 case IOCTL_AFD_RECV:
535 RecvReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
536 UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
537 /* Fall through */
538
539 case IOCTL_AFD_RECV_DATAGRAM:
540 Function = FUNCTION_RECV;
541 break;
542
543 case IOCTL_AFD_SEND:
544 SendReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
545 UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
546 /* Fall through */
547
548 case IOCTL_AFD_SEND_DATAGRAM:
549 Function = FUNCTION_SEND;
550 break;
551
552 case IOCTL_AFD_CONNECT:
553 Function = FUNCTION_CONNECT;
554 break;
555
556 case IOCTL_AFD_WAIT_FOR_LISTEN:
557 Function = FUNCTION_PREACCEPT;
558 break;
559
560 case IOCTL_AFD_SELECT:
561 KeAcquireSpinLock(&DeviceExt->Lock, &OldIrql);
562
563 CurrentEntry = DeviceExt->Polls.Flink;
564 while (CurrentEntry != &DeviceExt->Polls)
565 {
566 Poll = CONTAINING_RECORD(CurrentEntry, AFD_ACTIVE_POLL, ListEntry);
567 CurrentIrp = Poll->Irp;
568 PollReq = CurrentIrp->AssociatedIrp.SystemBuffer;
569
570 if (CurrentIrp == Irp)
571 {
572 ZeroEvents(PollReq->Handles, PollReq->HandleCount);
573 SignalSocket(Poll, NULL, PollReq, STATUS_CANCELLED);
574 break;
575 }
576 else
577 {
578 CurrentEntry = CurrentEntry->Flink;
579 }
580 }
581
582 KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
583
584 /* IRP already completed by SignalSocket */
585 SocketStateUnlock(FCB);
586 return;
587
588 default:
589 ASSERT(FALSE);
590 UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0);
591 return;
592 }
593
594 CurrentEntry = FCB->PendingIrpList[Function].Flink;
595 while (CurrentEntry != &FCB->PendingIrpList[Function])
596 {
597 CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry);
598
599 if (CurrentIrp == Irp)
600 {
601 RemoveEntryList(CurrentEntry);
602 break;
603 }
604 else
605 {
606 CurrentEntry = CurrentEntry->Flink;
607 }
608 }
609
610 UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0);
611 }
612
613 static VOID NTAPI
614 AfdUnload(PDRIVER_OBJECT DriverObject)
615 {
616 }
617
618 NTSTATUS NTAPI
619 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
620 {
621 PDEVICE_OBJECT DeviceObject;
622 UNICODE_STRING wstrDeviceName = RTL_CONSTANT_STRING(L"\\Device\\Afd");
623 PAFD_DEVICE_EXTENSION DeviceExt;
624 NTSTATUS Status;
625
626 /* register driver routines */
627 DriverObject->MajorFunction[IRP_MJ_CLOSE] = AfdDispatch;
628 DriverObject->MajorFunction[IRP_MJ_CREATE] = AfdDispatch;
629 DriverObject->MajorFunction[IRP_MJ_WRITE] = AfdDispatch;
630 DriverObject->MajorFunction[IRP_MJ_READ] = AfdDispatch;
631 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AfdDispatch;
632 DriverObject->DriverUnload = AfdUnload;
633
634 Status = IoCreateDevice
635 ( DriverObject,
636 sizeof(AFD_DEVICE_EXTENSION),
637 &wstrDeviceName,
638 FILE_DEVICE_NAMED_PIPE,
639 0,
640 FALSE,
641 &DeviceObject );
642
643 /* failure */
644 if(!NT_SUCCESS(Status))
645 {
646 return (Status);
647 }
648
649 DeviceExt = DeviceObject->DeviceExtension;
650 KeInitializeSpinLock( &DeviceExt->Lock );
651 InitializeListHead( &DeviceExt->Polls );
652
653 AFD_DbgPrint(MID_TRACE,("Device created: object %x ext %x\n",
654 DeviceObject, DeviceExt));
655
656 return (Status);
657 }
658
659 /* EOF */