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)
10 * Suggestions: Uniform naming (AfdXxx)
16 #include "tdi_proto.h"
22 /* See debug.h for debug/trace constants */
23 //DWORD DebugTraceLevel = DEBUG_ULTRA;
24 DWORD DebugTraceLevel
= 0;
28 void OskitDumpBuffer( PCHAR Data
, UINT Len
) {
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 );
42 DriverEntry(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
);
45 AfdGetDisconnectOptions(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
46 PIO_STACK_LOCATION IrpSp
)
48 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
49 PAFD_FCB FCB
= FileObject
->FsContext
;
50 UINT BufferSize
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
52 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
54 if (FCB
->DisconnectOptionsSize
== 0)
55 return UnlockAndMaybeComplete(FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0);
57 ASSERT(FCB
->DisconnectOptions
);
59 if (FCB
->FilledDisconnectOptions
< BufferSize
) BufferSize
= FCB
->FilledDisconnectOptions
;
61 RtlCopyMemory(Irp
->UserBuffer
,
62 FCB
->DisconnectOptions
,
65 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, BufferSize
);
70 AfdSetDisconnectOptions(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
71 PIO_STACK_LOCATION IrpSp
)
73 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
74 PAFD_FCB FCB
= FileObject
->FsContext
;
75 PVOID DisconnectOptions
= IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
76 UINT DisconnectOptionsSize
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
78 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
80 if (FCB
->DisconnectOptions
)
82 ExFreePool(FCB
->DisconnectOptions
);
83 FCB
->DisconnectOptions
= NULL
;
84 FCB
->DisconnectOptionsSize
= 0;
85 FCB
->FilledDisconnectOptions
= 0;
88 FCB
->DisconnectOptions
= ExAllocatePool(PagedPool
, DisconnectOptionsSize
);
89 if (!FCB
->DisconnectOptions
) return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
91 RtlCopyMemory(FCB
->DisconnectOptions
,
93 DisconnectOptionsSize
);
95 FCB
->DisconnectOptionsSize
= DisconnectOptionsSize
;
97 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
102 AfdSetDisconnectOptionsSize(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
103 PIO_STACK_LOCATION IrpSp
)
105 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
106 PAFD_FCB FCB
= FileObject
->FsContext
;
107 PUINT DisconnectOptionsSize
= IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
108 UINT BufferSize
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
110 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
112 if (BufferSize
< sizeof(UINT
))
113 return UnlockAndMaybeComplete(FCB
, STATUS_BUFFER_TOO_SMALL
, Irp
, 0);
115 if (FCB
->DisconnectOptions
)
117 ExFreePool(FCB
->DisconnectOptions
);
118 FCB
->DisconnectOptionsSize
= 0;
119 FCB
->FilledDisconnectOptions
= 0;
122 FCB
->DisconnectOptions
= ExAllocatePool(PagedPool
, *DisconnectOptionsSize
);
123 if (!FCB
->DisconnectOptions
) return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
125 FCB
->DisconnectOptionsSize
= *DisconnectOptionsSize
;
127 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
131 AfdGetDisconnectData(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
132 PIO_STACK_LOCATION IrpSp
)
134 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
135 PAFD_FCB FCB
= FileObject
->FsContext
;
136 UINT BufferSize
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
138 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
140 if (FCB
->DisconnectDataSize
== 0)
141 return UnlockAndMaybeComplete(FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0);
143 ASSERT(FCB
->DisconnectData
);
145 if (FCB
->FilledDisconnectData
< BufferSize
) BufferSize
= FCB
->FilledDisconnectData
;
147 RtlCopyMemory(Irp
->UserBuffer
,
151 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, BufferSize
);
156 AfdSetDisconnectData(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
157 PIO_STACK_LOCATION IrpSp
)
159 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
160 PAFD_FCB FCB
= FileObject
->FsContext
;
161 PVOID DisconnectData
= IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
162 UINT DisconnectDataSize
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
164 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
166 if (FCB
->DisconnectData
)
168 ExFreePool(FCB
->DisconnectData
);
169 FCB
->DisconnectData
= NULL
;
170 FCB
->DisconnectDataSize
= 0;
171 FCB
->FilledDisconnectData
= 0;
174 FCB
->DisconnectData
= ExAllocatePool(PagedPool
, DisconnectDataSize
);
175 if (!FCB
->DisconnectData
) return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
177 RtlCopyMemory(FCB
->DisconnectData
,
181 FCB
->DisconnectDataSize
= DisconnectDataSize
;
183 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
188 AfdSetDisconnectDataSize(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
189 PIO_STACK_LOCATION IrpSp
)
191 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
192 PAFD_FCB FCB
= FileObject
->FsContext
;
193 PUINT DisconnectDataSize
= IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
194 UINT BufferSize
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
196 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
198 if (BufferSize
< sizeof(UINT
))
199 return UnlockAndMaybeComplete(FCB
, STATUS_BUFFER_TOO_SMALL
, Irp
, 0);
201 if (FCB
->DisconnectData
)
203 ExFreePool(FCB
->DisconnectData
);
204 FCB
->DisconnectDataSize
= 0;
205 FCB
->FilledDisconnectData
= 0;
208 FCB
->DisconnectData
= ExAllocatePool(PagedPool
, *DisconnectDataSize
);
209 if (!FCB
->DisconnectData
) return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
211 FCB
->DisconnectDataSize
= *DisconnectDataSize
;
213 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
216 static NTSTATUS NTAPI
217 AfdCreateSocket(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
218 PIO_STACK_LOCATION IrpSp
) {
220 PFILE_OBJECT FileObject
;
221 PAFD_DEVICE_EXTENSION DeviceExt
;
222 PFILE_FULL_EA_INFORMATION EaInfo
;
223 PAFD_CREATE_PACKET ConnectInfo
= NULL
;
225 PWCHAR EaInfoValue
= NULL
;
227 NTSTATUS Status
= STATUS_SUCCESS
;
229 AFD_DbgPrint(MID_TRACE
,
230 ("AfdCreate(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
));
232 DeviceExt
= DeviceObject
->DeviceExtension
;
233 FileObject
= IrpSp
->FileObject
;
234 Disposition
= (IrpSp
->Parameters
.Create
.Options
>> 24) & 0xff;
236 Irp
->IoStatus
.Information
= 0;
238 EaInfo
= Irp
->AssociatedIrp
.SystemBuffer
;
241 ConnectInfo
= (PAFD_CREATE_PACKET
)(EaInfo
->EaName
+ EaInfo
->EaNameLength
+ 1);
242 EaInfoValue
= (PWCHAR
)(((PCHAR
)ConnectInfo
) + sizeof(AFD_CREATE_PACKET
));
244 EaLength
= sizeof(FILE_FULL_EA_INFORMATION
) +
245 EaInfo
->EaNameLength
+
246 EaInfo
->EaValueLength
;
248 AFD_DbgPrint(MID_TRACE
,("EaInfo: %x, EaInfoValue: %x\n",
249 EaInfo
, EaInfoValue
));
252 AFD_DbgPrint(MID_TRACE
,("About to allocate the new FCB\n"));
254 FCB
= ExAllocatePool(NonPagedPool
, sizeof(AFD_FCB
));
256 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
257 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
258 return STATUS_NO_MEMORY
;
261 AFD_DbgPrint(MID_TRACE
,("Initializing the new FCB @ %x (FileObject %x Flags %x)\n", FCB
, FileObject
, ConnectInfo
? ConnectInfo
->EndpointFlags
: 0));
263 RtlZeroMemory( FCB
, sizeof( *FCB
) );
265 FCB
->Flags
= ConnectInfo
? ConnectInfo
->EndpointFlags
: 0;
266 FCB
->GroupID
= ConnectInfo
? ConnectInfo
->GroupID
: 0;
267 FCB
->GroupType
= 0; /* FIXME */
268 FCB
->State
= SOCKET_STATE_CREATED
;
269 FCB
->FileObject
= FileObject
;
270 FCB
->DeviceExt
= DeviceExt
;
271 FCB
->AddressFile
.Handle
= INVALID_HANDLE_VALUE
;
272 FCB
->Connection
.Handle
= INVALID_HANDLE_VALUE
;
274 KeInitializeMutex( &FCB
->Mutex
, 0 );
276 for( i
= 0; i
< MAX_FUNCTIONS
; i
++ ) {
277 InitializeListHead( &FCB
->PendingIrpList
[i
] );
280 InitializeListHead( &FCB
->DatagramList
);
281 InitializeListHead( &FCB
->PendingConnections
);
283 AFD_DbgPrint(MID_TRACE
,("%x: Checking command channel\n", FCB
));
286 FCB
->TdiDeviceName
.Length
= ConnectInfo
->SizeOfTransportName
;
287 FCB
->TdiDeviceName
.MaximumLength
= FCB
->TdiDeviceName
.Length
;
288 FCB
->TdiDeviceName
.Buffer
=
289 ExAllocatePool( NonPagedPool
, FCB
->TdiDeviceName
.Length
);
291 if( !FCB
->TdiDeviceName
.Buffer
) {
293 AFD_DbgPrint(MID_TRACE
,("Could not copy target string\n"));
294 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
295 IoCompleteRequest( Irp
, IO_NETWORK_INCREMENT
);
296 return STATUS_NO_MEMORY
;
299 RtlCopyMemory( FCB
->TdiDeviceName
.Buffer
,
300 ConnectInfo
->TransportName
,
301 FCB
->TdiDeviceName
.Length
);
303 AFD_DbgPrint(MID_TRACE
,("Success: %s %wZ\n",
304 EaInfo
->EaName
, &FCB
->TdiDeviceName
));
306 AFD_DbgPrint(MID_TRACE
,("Success: Control connection\n"));
309 FileObject
->FsContext
= FCB
;
311 /* It seems that UDP sockets are writable from inception */
312 if( FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
) {
313 AFD_DbgPrint(MID_TRACE
,("Packet oriented socket\n"));
315 /* A datagram socket is always sendable */
316 FCB
->PollState
|= AFD_EVENT_SEND
;
317 PollReeval( FCB
->DeviceExt
, FCB
->FileObject
);
320 if( !NT_SUCCESS(Status
) ) {
321 if( FCB
->TdiDeviceName
.Buffer
) ExFreePool( FCB
->TdiDeviceName
.Buffer
);
323 FileObject
->FsContext
= NULL
;
326 Irp
->IoStatus
.Status
= Status
;
327 IoCompleteRequest( Irp
, IO_NETWORK_INCREMENT
);
332 static NTSTATUS NTAPI
333 AfdCleanupSocket(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
334 PIO_STACK_LOCATION IrpSp
)
336 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
337 PAFD_FCB FCB
= FileObject
->FsContext
;
338 PLIST_ENTRY CurrentEntry
, NextEntry
;
342 if( !SocketAcquireStateLock( FCB
) ) return LostSocket(Irp
);
344 for (Function
= 0; Function
< MAX_FUNCTIONS
; Function
++)
346 CurrentEntry
= FCB
->PendingIrpList
[Function
].Flink
;
347 while (CurrentEntry
!= &FCB
->PendingIrpList
[Function
])
349 NextEntry
= CurrentEntry
->Flink
;
350 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
352 /* The cancel routine will remove the IRP from the list */
353 IoCancelIrp(CurrentIrp
);
355 CurrentEntry
= NextEntry
;
359 KillSelectsForFCB( FCB
->DeviceExt
, FileObject
, FALSE
);
361 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
364 static NTSTATUS NTAPI
365 AfdCloseSocket(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
366 PIO_STACK_LOCATION IrpSp
)
368 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
369 PAFD_FCB FCB
= FileObject
->FsContext
;
371 PAFD_IN_FLIGHT_REQUEST InFlightRequest
[IN_FLIGHT_REQUESTS
];
373 AFD_DbgPrint(MID_TRACE
,
374 ("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
));
376 if( !SocketAcquireStateLock( FCB
) ) return STATUS_FILE_CLOSED
;
378 FCB
->State
= SOCKET_STATE_CLOSED
;
379 FCB
->PollState
= AFD_EVENT_CLOSE
;
380 PollReeval( FCB
->DeviceExt
, FCB
->FileObject
);
382 InFlightRequest
[0] = &FCB
->ListenIrp
;
383 InFlightRequest
[1] = &FCB
->ReceiveIrp
;
384 InFlightRequest
[2] = &FCB
->SendIrp
;
385 InFlightRequest
[3] = &FCB
->ConnectIrp
;
387 /* Cancel our pending requests */
388 for( i
= 0; i
< IN_FLIGHT_REQUESTS
; i
++ ) {
389 if( InFlightRequest
[i
]->InFlightRequest
) {
390 AFD_DbgPrint(MID_TRACE
,("Cancelling in flight irp %d (%x)\n",
391 i
, InFlightRequest
[i
]->InFlightRequest
));
392 IoCancelIrp(InFlightRequest
[i
]->InFlightRequest
);
396 KillSelectsForFCB( FCB
->DeviceExt
, FileObject
, FALSE
);
398 SocketStateUnlock( FCB
);
400 if( FCB
->EventSelect
)
401 ObDereferenceObject( FCB
->EventSelect
);
404 ExFreePool( FCB
->Context
);
406 if( FCB
->Recv
.Window
)
407 ExFreePool( FCB
->Recv
.Window
);
409 if( FCB
->Send
.Window
)
410 ExFreePool( FCB
->Send
.Window
);
412 if( FCB
->AddressFrom
)
413 ExFreePool( FCB
->AddressFrom
);
415 if( FCB
->ConnectInfo
)
416 ExFreePool( FCB
->ConnectInfo
);
418 if( FCB
->ConnectData
)
419 ExFreePool( FCB
->ConnectData
);
421 if( FCB
->DisconnectData
)
422 ExFreePool( FCB
->DisconnectData
);
424 if( FCB
->ConnectOptions
)
425 ExFreePool( FCB
->ConnectOptions
);
427 if( FCB
->DisconnectOptions
)
428 ExFreePool( FCB
->DisconnectOptions
);
430 if( FCB
->LocalAddress
)
431 ExFreePool( FCB
->LocalAddress
);
433 if( FCB
->RemoteAddress
)
434 ExFreePool( FCB
->RemoteAddress
);
436 if( FCB
->Connection
.Object
)
437 ObDereferenceObject(FCB
->Connection
.Object
);
439 if( FCB
->AddressFile
.Object
)
440 ObDereferenceObject(FCB
->AddressFile
.Object
);
442 if( FCB
->AddressFile
.Handle
!= INVALID_HANDLE_VALUE
)
444 if (ZwClose(FCB
->AddressFile
.Handle
) == STATUS_INVALID_HANDLE
)
446 DbgPrint("INVALID ADDRESS FILE HANDLE VALUE: %x %x\n", FCB
->AddressFile
.Handle
, FCB
->AddressFile
.Object
);
450 if( FCB
->Connection
.Handle
!= INVALID_HANDLE_VALUE
)
452 if (ZwClose(FCB
->Connection
.Handle
) == STATUS_INVALID_HANDLE
)
454 DbgPrint("INVALID CONNECTION HANDLE VALUE: %x %x\n", FCB
->Connection
.Handle
, FCB
->Connection
.Object
);
458 if( FCB
->TdiDeviceName
.Buffer
)
459 ExFreePool(FCB
->TdiDeviceName
.Buffer
);
463 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
464 Irp
->IoStatus
.Information
= 0;
465 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
467 AFD_DbgPrint(MID_TRACE
, ("Returning success.\n"));
469 return STATUS_SUCCESS
;
472 static NTSTATUS NTAPI
473 AfdDisconnect(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
474 PIO_STACK_LOCATION IrpSp
) {
475 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
476 PAFD_FCB FCB
= FileObject
->FsContext
;
477 PAFD_DISCONNECT_INFO DisReq
;
478 IO_STATUS_BLOCK Iosb
;
479 PTDI_CONNECTION_INFORMATION ConnectionReturnInfo
;
480 NTSTATUS Status
= STATUS_SUCCESS
;
483 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
485 if( !(DisReq
= LockRequest( Irp
, IrpSp
)) )
486 return UnlockAndMaybeComplete( FCB
, STATUS_NO_MEMORY
,
489 if (!(FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
))
491 if( !FCB
->ConnectInfo
)
492 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
,
495 ASSERT(FCB
->RemoteAddress
);
497 Status
= TdiBuildNullConnectionInfo
498 ( &ConnectionReturnInfo
, FCB
->RemoteAddress
->Address
[0].AddressType
);
500 if( !NT_SUCCESS(Status
) )
501 return UnlockAndMaybeComplete( FCB
, Status
,
504 if( DisReq
->DisconnectType
& AFD_DISCONNECT_SEND
)
505 Flags
|= TDI_DISCONNECT_RELEASE
;
506 if( DisReq
->DisconnectType
& AFD_DISCONNECT_RECV
||
507 DisReq
->DisconnectType
& AFD_DISCONNECT_ABORT
)
508 Flags
|= TDI_DISCONNECT_ABORT
;
510 FCB
->ConnectInfo
->UserData
= FCB
->DisconnectData
;
511 FCB
->ConnectInfo
->UserDataLength
= FCB
->DisconnectDataSize
;
512 FCB
->ConnectInfo
->Options
= FCB
->DisconnectOptions
;
513 FCB
->ConnectInfo
->OptionsLength
= FCB
->DisconnectOptionsSize
;
515 Status
= TdiDisconnect( FCB
->Connection
.Object
,
522 ConnectionReturnInfo
);
524 if (NT_SUCCESS(Status
)) {
525 FCB
->FilledDisconnectData
= MIN(FCB
->DisconnectDataSize
, ConnectionReturnInfo
->UserDataLength
);
526 if (FCB
->FilledDisconnectData
)
528 RtlCopyMemory(FCB
->DisconnectData
,
529 ConnectionReturnInfo
->UserData
,
530 FCB
->FilledDisconnectData
);
533 FCB
->FilledDisconnectOptions
= MIN(FCB
->DisconnectOptionsSize
, ConnectionReturnInfo
->OptionsLength
);
534 if (FCB
->FilledDisconnectOptions
)
536 RtlCopyMemory(FCB
->DisconnectOptions
,
537 ConnectionReturnInfo
->Options
,
538 FCB
->FilledDisconnectOptions
);
542 ExFreePool( ConnectionReturnInfo
);
544 FCB
->PollState
|= AFD_EVENT_DISCONNECT
;
545 PollReeval( FCB
->DeviceExt
, FCB
->FileObject
);
547 Status
= STATUS_INVALID_PARAMETER
;
549 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );
552 static NTSTATUS NTAPI
553 AfdDispatch(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
555 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
556 NTSTATUS Status
= STATUS_NOT_IMPLEMENTED
;
558 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
561 AFD_DbgPrint(MID_TRACE
,("AfdDispatch: %d\n", IrpSp
->MajorFunction
));
562 if( IrpSp
->MajorFunction
!= IRP_MJ_CREATE
) {
563 AFD_DbgPrint(MID_TRACE
,("FO %x, IrpSp->FO %x\n",
564 FileObject
, IrpSp
->FileObject
));
565 ASSERT(FileObject
== IrpSp
->FileObject
);
568 Irp
->IoStatus
.Information
= 0;
570 switch(IrpSp
->MajorFunction
)
572 /* opening and closing handles to the device */
574 /* Mostly borrowed from the named pipe file system */
575 return AfdCreateSocket(DeviceObject
, Irp
, IrpSp
);
578 /* Ditto the borrowing */
579 return AfdCloseSocket(DeviceObject
, Irp
, IrpSp
);
582 return AfdCleanupSocket(DeviceObject
, Irp
, IrpSp
);
586 return AfdConnectedSocketWriteData( DeviceObject
, Irp
, IrpSp
, TRUE
);
590 return AfdConnectedSocketReadData( DeviceObject
, Irp
, IrpSp
, TRUE
);
592 case IRP_MJ_DEVICE_CONTROL
:
594 switch( IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
596 return AfdBindSocket( DeviceObject
, Irp
, IrpSp
);
598 case IOCTL_AFD_CONNECT
:
599 return AfdStreamSocketConnect( DeviceObject
, Irp
, IrpSp
);
601 case IOCTL_AFD_START_LISTEN
:
602 return AfdListenSocket( DeviceObject
, Irp
, IrpSp
);
605 return AfdConnectedSocketReadData( DeviceObject
, Irp
, IrpSp
,
608 case IOCTL_AFD_SELECT
:
609 return AfdSelect( DeviceObject
, Irp
, IrpSp
);
611 case IOCTL_AFD_EVENT_SELECT
:
612 return AfdEventSelect( DeviceObject
, Irp
, IrpSp
);
614 case IOCTL_AFD_ENUM_NETWORK_EVENTS
:
615 return AfdEnumEvents( DeviceObject
, Irp
, IrpSp
);
617 case IOCTL_AFD_RECV_DATAGRAM
:
618 return AfdPacketSocketReadData( DeviceObject
, Irp
, IrpSp
);
621 return AfdConnectedSocketWriteData( DeviceObject
, Irp
, IrpSp
,
624 case IOCTL_AFD_SEND_DATAGRAM
:
625 return AfdPacketSocketWriteData( DeviceObject
, Irp
, IrpSp
);
627 case IOCTL_AFD_GET_INFO
:
628 return AfdGetInfo( DeviceObject
, Irp
, IrpSp
);
630 case IOCTL_AFD_SET_INFO
:
631 return AfdSetInfo( DeviceObject
, Irp
, IrpSp
);
633 case IOCTL_AFD_GET_CONTEXT_SIZE
:
634 return AfdGetContextSize( DeviceObject
, Irp
, IrpSp
);
636 case IOCTL_AFD_GET_CONTEXT
:
637 return AfdGetContext( DeviceObject
, Irp
, IrpSp
);
639 case IOCTL_AFD_SET_CONTEXT
:
640 return AfdSetContext( DeviceObject
, Irp
, IrpSp
);
642 case IOCTL_AFD_WAIT_FOR_LISTEN
:
643 return AfdWaitForListen( DeviceObject
, Irp
, IrpSp
);
645 case IOCTL_AFD_ACCEPT
:
646 return AfdAccept( DeviceObject
, Irp
, IrpSp
);
648 case IOCTL_AFD_DISCONNECT
:
649 return AfdDisconnect( DeviceObject
, Irp
, IrpSp
);
651 case IOCTL_AFD_GET_SOCK_NAME
:
652 return AfdGetSockName( DeviceObject
, Irp
, IrpSp
);
654 case IOCTL_AFD_GET_PEER_NAME
:
655 return AfdGetPeerName( DeviceObject
, Irp
, IrpSp
);
657 case IOCTL_AFD_GET_CONNECT_DATA
:
658 return AfdGetConnectData(DeviceObject
, Irp
, IrpSp
);
660 case IOCTL_AFD_SET_CONNECT_DATA
:
661 return AfdSetConnectData(DeviceObject
, Irp
, IrpSp
);
663 case IOCTL_AFD_SET_DISCONNECT_DATA
:
664 return AfdSetDisconnectData(DeviceObject
, Irp
, IrpSp
);
666 case IOCTL_AFD_GET_DISCONNECT_DATA
:
667 return AfdGetDisconnectData(DeviceObject
, Irp
, IrpSp
);
669 case IOCTL_AFD_SET_CONNECT_DATA_SIZE
:
670 return AfdSetConnectDataSize(DeviceObject
, Irp
, IrpSp
);
672 case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE
:
673 return AfdSetDisconnectDataSize(DeviceObject
, Irp
, IrpSp
);
675 case IOCTL_AFD_SET_CONNECT_OPTIONS
:
676 return AfdSetConnectOptions(DeviceObject
, Irp
, IrpSp
);
678 case IOCTL_AFD_SET_DISCONNECT_OPTIONS
:
679 return AfdSetDisconnectOptions(DeviceObject
, Irp
, IrpSp
);
681 case IOCTL_AFD_GET_CONNECT_OPTIONS
:
682 return AfdGetConnectOptions(DeviceObject
, Irp
, IrpSp
);
684 case IOCTL_AFD_GET_DISCONNECT_OPTIONS
:
685 return AfdGetDisconnectOptions(DeviceObject
, Irp
, IrpSp
);
687 case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE
:
688 return AfdSetConnectOptionsSize(DeviceObject
, Irp
, IrpSp
);
690 case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE
:
691 return AfdSetDisconnectOptionsSize(DeviceObject
, Irp
, IrpSp
);
693 case IOCTL_AFD_GET_TDI_HANDLES
:
694 DbgPrint("IOCTL_AFD_GET_TDI_HANDLES is UNIMPLEMENTED!\n");
697 case IOCTL_AFD_DEFER_ACCEPT
:
698 DbgPrint("IOCTL_AFD_DEFER_ACCEPT is UNIMPLEMENTED!\n");
701 case IOCTL_AFD_GET_PENDING_CONNECT_DATA
:
702 DbgPrint("IOCTL_AFD_GET_PENDING_CONNECT_DATA is UNIMPLEMENTED!\n");
705 case IOCTL_AFD_VALIDATE_GROUP
:
706 DbgPrint("IOCTL_AFD_VALIDATE_GROUP is UNIMPLEMENTED!\n");
710 Status
= STATUS_NOT_SUPPORTED
;
711 DbgPrint("Unknown IOCTL (0x%x)\n",
712 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
);
718 /* unsupported operations */
721 Status
= STATUS_NOT_IMPLEMENTED
;
722 AFD_DbgPrint(MIN_TRACE
,
723 ("Irp: Unknown Major code was %x\n",
724 IrpSp
->MajorFunction
));
729 AFD_DbgPrint(MID_TRACE
, ("Returning %x\n", Status
));
730 Irp
->IoStatus
.Status
= Status
;
731 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
737 AfdCancelHandler(PDEVICE_OBJECT DeviceObject
,
740 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
741 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
742 PAFD_FCB FCB
= FileObject
->FsContext
;
744 PAFD_RECV_INFO RecvReq
;
745 PAFD_SEND_INFO SendReq
;
746 PLIST_ENTRY CurrentEntry
;
748 PAFD_DEVICE_EXTENSION DeviceExt
= DeviceObject
->DeviceExtension
;
750 PAFD_ACTIVE_POLL Poll
;
751 PAFD_POLL_INFO PollReq
;
753 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
755 if (!SocketAcquireStateLock(FCB
))
758 ASSERT(IrpSp
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
);
760 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
)
763 RecvReq
= IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
764 UnlockBuffers(RecvReq
->BufferArray
, RecvReq
->BufferCount
, FALSE
);
767 case IOCTL_AFD_RECV_DATAGRAM
:
768 Function
= FUNCTION_RECV
;
772 SendReq
= IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
773 UnlockBuffers(SendReq
->BufferArray
, SendReq
->BufferCount
, FALSE
);
776 case IOCTL_AFD_SEND_DATAGRAM
:
777 Function
= FUNCTION_SEND
;
780 case IOCTL_AFD_CONNECT
:
781 Function
= FUNCTION_CONNECT
;
784 case IOCTL_AFD_WAIT_FOR_LISTEN
:
785 Function
= FUNCTION_PREACCEPT
;
788 case IOCTL_AFD_SELECT
:
789 KeAcquireSpinLock(&DeviceExt
->Lock
, &OldIrql
);
791 CurrentEntry
= DeviceExt
->Polls
.Flink
;
792 while (CurrentEntry
!= &DeviceExt
->Polls
)
794 Poll
= CONTAINING_RECORD(CurrentEntry
, AFD_ACTIVE_POLL
, ListEntry
);
795 CurrentIrp
= Poll
->Irp
;
796 PollReq
= CurrentIrp
->AssociatedIrp
.SystemBuffer
;
798 if (CurrentIrp
== Irp
)
800 ZeroEvents(PollReq
->Handles
, PollReq
->HandleCount
);
801 SignalSocket(Poll
, NULL
, PollReq
, STATUS_CANCELLED
);
806 CurrentEntry
= CurrentEntry
->Flink
;
810 KeReleaseSpinLock(&DeviceExt
->Lock
, OldIrql
);
812 /* IRP already completed by SignalSocket */
813 SocketStateUnlock(FCB
);
818 UnlockAndMaybeComplete(FCB
, STATUS_CANCELLED
, Irp
, 0);
822 CurrentEntry
= FCB
->PendingIrpList
[Function
].Flink
;
823 while (CurrentEntry
!= &FCB
->PendingIrpList
[Function
])
825 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
827 if (CurrentIrp
== Irp
)
829 RemoveEntryList(CurrentEntry
);
834 CurrentEntry
= CurrentEntry
->Flink
;
838 UnlockAndMaybeComplete(FCB
, STATUS_CANCELLED
, Irp
, 0);
842 AfdUnload(PDRIVER_OBJECT DriverObject
)
847 DriverEntry(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
849 PDEVICE_OBJECT DeviceObject
;
850 UNICODE_STRING wstrDeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\Afd");
851 PAFD_DEVICE_EXTENSION DeviceExt
;
854 /* register driver routines */
855 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = AfdDispatch
;
856 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = AfdDispatch
;
857 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = AfdDispatch
;
858 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = AfdDispatch
;
859 DriverObject
->MajorFunction
[IRP_MJ_READ
] = AfdDispatch
;
860 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = AfdDispatch
;
861 DriverObject
->DriverUnload
= AfdUnload
;
863 Status
= IoCreateDevice
865 sizeof(AFD_DEVICE_EXTENSION
),
867 FILE_DEVICE_NAMED_PIPE
,
873 if(!NT_SUCCESS(Status
))
878 DeviceExt
= DeviceObject
->DeviceExtension
;
879 KeInitializeSpinLock( &DeviceExt
->Lock
);
880 InitializeListHead( &DeviceExt
->Polls
);
882 AFD_DbgPrint(MID_TRACE
,("Device created: object %x ext %x\n",
883 DeviceObject
, DeviceExt
));