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 FCB
->PollStatus
[FD_WRITE_BIT
] = STATUS_SUCCESS
;
318 PollReeval( FCB
->DeviceExt
, FCB
->FileObject
);
321 if( !NT_SUCCESS(Status
) ) {
322 if( FCB
->TdiDeviceName
.Buffer
) ExFreePool( FCB
->TdiDeviceName
.Buffer
);
324 FileObject
->FsContext
= NULL
;
327 Irp
->IoStatus
.Status
= Status
;
328 IoCompleteRequest( Irp
, IO_NETWORK_INCREMENT
);
333 static NTSTATUS NTAPI
334 AfdCleanupSocket(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
335 PIO_STACK_LOCATION IrpSp
)
337 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
338 PAFD_FCB FCB
= FileObject
->FsContext
;
339 PLIST_ENTRY CurrentEntry
, NextEntry
;
343 if( !SocketAcquireStateLock( FCB
) ) return LostSocket(Irp
);
345 for (Function
= 0; Function
< MAX_FUNCTIONS
; Function
++)
347 CurrentEntry
= FCB
->PendingIrpList
[Function
].Flink
;
348 while (CurrentEntry
!= &FCB
->PendingIrpList
[Function
])
350 NextEntry
= CurrentEntry
->Flink
;
351 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
353 /* The cancel routine will remove the IRP from the list */
354 IoCancelIrp(CurrentIrp
);
356 CurrentEntry
= NextEntry
;
360 KillSelectsForFCB( FCB
->DeviceExt
, FileObject
, FALSE
);
362 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
365 static NTSTATUS NTAPI
366 AfdCloseSocket(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
367 PIO_STACK_LOCATION IrpSp
)
369 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
370 PAFD_FCB FCB
= FileObject
->FsContext
;
372 PAFD_IN_FLIGHT_REQUEST InFlightRequest
[IN_FLIGHT_REQUESTS
];
374 AFD_DbgPrint(MID_TRACE
,
375 ("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
));
377 if( !SocketAcquireStateLock( FCB
) ) return STATUS_FILE_CLOSED
;
379 FCB
->State
= SOCKET_STATE_CLOSED
;
380 FCB
->PollState
= AFD_EVENT_CLOSE
;
381 FCB
->PollStatus
[FD_CLOSE_BIT
] = STATUS_SUCCESS
; //I think we can return success here
382 PollReeval( FCB
->DeviceExt
, FCB
->FileObject
);
384 InFlightRequest
[0] = &FCB
->ListenIrp
;
385 InFlightRequest
[1] = &FCB
->ReceiveIrp
;
386 InFlightRequest
[2] = &FCB
->SendIrp
;
387 InFlightRequest
[3] = &FCB
->ConnectIrp
;
389 /* Cancel our pending requests */
390 for( i
= 0; i
< IN_FLIGHT_REQUESTS
; i
++ ) {
391 if( InFlightRequest
[i
]->InFlightRequest
) {
392 AFD_DbgPrint(MID_TRACE
,("Cancelling in flight irp %d (%x)\n",
393 i
, InFlightRequest
[i
]->InFlightRequest
));
394 IoCancelIrp(InFlightRequest
[i
]->InFlightRequest
);
398 KillSelectsForFCB( FCB
->DeviceExt
, FileObject
, FALSE
);
400 SocketStateUnlock( FCB
);
402 if( FCB
->EventSelect
)
403 ObDereferenceObject( FCB
->EventSelect
);
406 ExFreePool( FCB
->Context
);
408 if( FCB
->Recv
.Window
)
409 ExFreePool( FCB
->Recv
.Window
);
411 if( FCB
->Send
.Window
)
412 ExFreePool( FCB
->Send
.Window
);
414 if( FCB
->AddressFrom
)
415 ExFreePool( FCB
->AddressFrom
);
417 if( FCB
->ConnectInfo
)
418 ExFreePool( FCB
->ConnectInfo
);
420 if( FCB
->ConnectData
)
421 ExFreePool( FCB
->ConnectData
);
423 if( FCB
->DisconnectData
)
424 ExFreePool( FCB
->DisconnectData
);
426 if( FCB
->ConnectOptions
)
427 ExFreePool( FCB
->ConnectOptions
);
429 if( FCB
->DisconnectOptions
)
430 ExFreePool( FCB
->DisconnectOptions
);
432 if( FCB
->LocalAddress
)
433 ExFreePool( FCB
->LocalAddress
);
435 if( FCB
->RemoteAddress
)
436 ExFreePool( FCB
->RemoteAddress
);
438 if( FCB
->Connection
.Object
)
439 ObDereferenceObject(FCB
->Connection
.Object
);
441 if( FCB
->AddressFile
.Object
)
442 ObDereferenceObject(FCB
->AddressFile
.Object
);
444 if( FCB
->AddressFile
.Handle
!= INVALID_HANDLE_VALUE
)
446 if (ZwClose(FCB
->AddressFile
.Handle
) == STATUS_INVALID_HANDLE
)
448 DbgPrint("INVALID ADDRESS FILE HANDLE VALUE: %x %x\n", FCB
->AddressFile
.Handle
, FCB
->AddressFile
.Object
);
452 if( FCB
->Connection
.Handle
!= INVALID_HANDLE_VALUE
)
454 if (ZwClose(FCB
->Connection
.Handle
) == STATUS_INVALID_HANDLE
)
456 DbgPrint("INVALID CONNECTION HANDLE VALUE: %x %x\n", FCB
->Connection
.Handle
, FCB
->Connection
.Object
);
460 if( FCB
->TdiDeviceName
.Buffer
)
461 ExFreePool(FCB
->TdiDeviceName
.Buffer
);
465 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
466 Irp
->IoStatus
.Information
= 0;
467 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
469 AFD_DbgPrint(MID_TRACE
, ("Returning success.\n"));
471 return STATUS_SUCCESS
;
474 static NTSTATUS NTAPI
475 AfdDisconnect(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
476 PIO_STACK_LOCATION IrpSp
) {
477 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
478 PAFD_FCB FCB
= FileObject
->FsContext
;
479 PAFD_DISCONNECT_INFO DisReq
;
480 IO_STATUS_BLOCK Iosb
;
481 PTDI_CONNECTION_INFORMATION ConnectionReturnInfo
;
482 NTSTATUS Status
= STATUS_SUCCESS
;
485 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
487 if( !(DisReq
= LockRequest( Irp
, IrpSp
)) )
488 return UnlockAndMaybeComplete( FCB
, STATUS_NO_MEMORY
,
491 if (!(FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
))
493 if( !FCB
->ConnectInfo
)
494 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
,
497 ASSERT(FCB
->RemoteAddress
);
499 Status
= TdiBuildNullConnectionInfo
500 ( &ConnectionReturnInfo
, FCB
->RemoteAddress
->Address
[0].AddressType
);
502 if( !NT_SUCCESS(Status
) )
503 return UnlockAndMaybeComplete( FCB
, Status
,
506 if( DisReq
->DisconnectType
& AFD_DISCONNECT_SEND
)
507 Flags
|= TDI_DISCONNECT_RELEASE
;
508 if( DisReq
->DisconnectType
& AFD_DISCONNECT_RECV
||
509 DisReq
->DisconnectType
& AFD_DISCONNECT_ABORT
)
510 Flags
|= TDI_DISCONNECT_ABORT
;
512 FCB
->ConnectInfo
->UserData
= FCB
->DisconnectData
;
513 FCB
->ConnectInfo
->UserDataLength
= FCB
->DisconnectDataSize
;
514 FCB
->ConnectInfo
->Options
= FCB
->DisconnectOptions
;
515 FCB
->ConnectInfo
->OptionsLength
= FCB
->DisconnectOptionsSize
;
517 Status
= TdiDisconnect( FCB
->Connection
.Object
,
524 ConnectionReturnInfo
);
526 if (NT_SUCCESS(Status
)) {
527 FCB
->FilledDisconnectData
= MIN(FCB
->DisconnectDataSize
, ConnectionReturnInfo
->UserDataLength
);
528 if (FCB
->FilledDisconnectData
)
530 RtlCopyMemory(FCB
->DisconnectData
,
531 ConnectionReturnInfo
->UserData
,
532 FCB
->FilledDisconnectData
);
535 FCB
->FilledDisconnectOptions
= MIN(FCB
->DisconnectOptionsSize
, ConnectionReturnInfo
->OptionsLength
);
536 if (FCB
->FilledDisconnectOptions
)
538 RtlCopyMemory(FCB
->DisconnectOptions
,
539 ConnectionReturnInfo
->Options
,
540 FCB
->FilledDisconnectOptions
);
544 ExFreePool( ConnectionReturnInfo
);
546 FCB
->PollState
|= AFD_EVENT_DISCONNECT
;
547 FCB
->PollStatus
[FD_CLOSE_BIT
] = STATUS_SUCCESS
;
548 PollReeval( FCB
->DeviceExt
, FCB
->FileObject
);
550 Status
= STATUS_INVALID_PARAMETER
;
552 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );
555 static NTSTATUS NTAPI
556 AfdDispatch(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
558 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
559 NTSTATUS Status
= STATUS_NOT_IMPLEMENTED
;
561 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
564 AFD_DbgPrint(MID_TRACE
,("AfdDispatch: %d\n", IrpSp
->MajorFunction
));
565 if( IrpSp
->MajorFunction
!= IRP_MJ_CREATE
) {
566 AFD_DbgPrint(MID_TRACE
,("FO %x, IrpSp->FO %x\n",
567 FileObject
, IrpSp
->FileObject
));
568 ASSERT(FileObject
== IrpSp
->FileObject
);
571 Irp
->IoStatus
.Information
= 0;
573 switch(IrpSp
->MajorFunction
)
575 /* opening and closing handles to the device */
577 /* Mostly borrowed from the named pipe file system */
578 return AfdCreateSocket(DeviceObject
, Irp
, IrpSp
);
581 /* Ditto the borrowing */
582 return AfdCloseSocket(DeviceObject
, Irp
, IrpSp
);
585 return AfdCleanupSocket(DeviceObject
, Irp
, IrpSp
);
589 return AfdConnectedSocketWriteData( DeviceObject
, Irp
, IrpSp
, TRUE
);
593 return AfdConnectedSocketReadData( DeviceObject
, Irp
, IrpSp
, TRUE
);
595 case IRP_MJ_DEVICE_CONTROL
:
597 switch( IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
599 return AfdBindSocket( DeviceObject
, Irp
, IrpSp
);
601 case IOCTL_AFD_CONNECT
:
602 return AfdStreamSocketConnect( DeviceObject
, Irp
, IrpSp
);
604 case IOCTL_AFD_START_LISTEN
:
605 return AfdListenSocket( DeviceObject
, Irp
, IrpSp
);
608 return AfdConnectedSocketReadData( DeviceObject
, Irp
, IrpSp
,
611 case IOCTL_AFD_SELECT
:
612 return AfdSelect( DeviceObject
, Irp
, IrpSp
);
614 case IOCTL_AFD_EVENT_SELECT
:
615 return AfdEventSelect( DeviceObject
, Irp
, IrpSp
);
617 case IOCTL_AFD_ENUM_NETWORK_EVENTS
:
618 return AfdEnumEvents( DeviceObject
, Irp
, IrpSp
);
620 case IOCTL_AFD_RECV_DATAGRAM
:
621 return AfdPacketSocketReadData( DeviceObject
, Irp
, IrpSp
);
624 return AfdConnectedSocketWriteData( DeviceObject
, Irp
, IrpSp
,
627 case IOCTL_AFD_SEND_DATAGRAM
:
628 return AfdPacketSocketWriteData( DeviceObject
, Irp
, IrpSp
);
630 case IOCTL_AFD_GET_INFO
:
631 return AfdGetInfo( DeviceObject
, Irp
, IrpSp
);
633 case IOCTL_AFD_SET_INFO
:
634 return AfdSetInfo( DeviceObject
, Irp
, IrpSp
);
636 case IOCTL_AFD_GET_CONTEXT_SIZE
:
637 return AfdGetContextSize( DeviceObject
, Irp
, IrpSp
);
639 case IOCTL_AFD_GET_CONTEXT
:
640 return AfdGetContext( DeviceObject
, Irp
, IrpSp
);
642 case IOCTL_AFD_SET_CONTEXT
:
643 return AfdSetContext( DeviceObject
, Irp
, IrpSp
);
645 case IOCTL_AFD_WAIT_FOR_LISTEN
:
646 return AfdWaitForListen( DeviceObject
, Irp
, IrpSp
);
648 case IOCTL_AFD_ACCEPT
:
649 return AfdAccept( DeviceObject
, Irp
, IrpSp
);
651 case IOCTL_AFD_DISCONNECT
:
652 return AfdDisconnect( DeviceObject
, Irp
, IrpSp
);
654 case IOCTL_AFD_GET_SOCK_NAME
:
655 return AfdGetSockName( DeviceObject
, Irp
, IrpSp
);
657 case IOCTL_AFD_GET_PEER_NAME
:
658 return AfdGetPeerName( DeviceObject
, Irp
, IrpSp
);
660 case IOCTL_AFD_GET_CONNECT_DATA
:
661 return AfdGetConnectData(DeviceObject
, Irp
, IrpSp
);
663 case IOCTL_AFD_SET_CONNECT_DATA
:
664 return AfdSetConnectData(DeviceObject
, Irp
, IrpSp
);
666 case IOCTL_AFD_SET_DISCONNECT_DATA
:
667 return AfdSetDisconnectData(DeviceObject
, Irp
, IrpSp
);
669 case IOCTL_AFD_GET_DISCONNECT_DATA
:
670 return AfdGetDisconnectData(DeviceObject
, Irp
, IrpSp
);
672 case IOCTL_AFD_SET_CONNECT_DATA_SIZE
:
673 return AfdSetConnectDataSize(DeviceObject
, Irp
, IrpSp
);
675 case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE
:
676 return AfdSetDisconnectDataSize(DeviceObject
, Irp
, IrpSp
);
678 case IOCTL_AFD_SET_CONNECT_OPTIONS
:
679 return AfdSetConnectOptions(DeviceObject
, Irp
, IrpSp
);
681 case IOCTL_AFD_SET_DISCONNECT_OPTIONS
:
682 return AfdSetDisconnectOptions(DeviceObject
, Irp
, IrpSp
);
684 case IOCTL_AFD_GET_CONNECT_OPTIONS
:
685 return AfdGetConnectOptions(DeviceObject
, Irp
, IrpSp
);
687 case IOCTL_AFD_GET_DISCONNECT_OPTIONS
:
688 return AfdGetDisconnectOptions(DeviceObject
, Irp
, IrpSp
);
690 case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE
:
691 return AfdSetConnectOptionsSize(DeviceObject
, Irp
, IrpSp
);
693 case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE
:
694 return AfdSetDisconnectOptionsSize(DeviceObject
, Irp
, IrpSp
);
696 case IOCTL_AFD_GET_TDI_HANDLES
:
697 DbgPrint("IOCTL_AFD_GET_TDI_HANDLES is UNIMPLEMENTED!\n");
700 case IOCTL_AFD_DEFER_ACCEPT
:
701 DbgPrint("IOCTL_AFD_DEFER_ACCEPT is UNIMPLEMENTED!\n");
704 case IOCTL_AFD_GET_PENDING_CONNECT_DATA
:
705 DbgPrint("IOCTL_AFD_GET_PENDING_CONNECT_DATA is UNIMPLEMENTED!\n");
708 case IOCTL_AFD_VALIDATE_GROUP
:
709 DbgPrint("IOCTL_AFD_VALIDATE_GROUP is UNIMPLEMENTED!\n");
713 Status
= STATUS_NOT_SUPPORTED
;
714 DbgPrint("Unknown IOCTL (0x%x)\n",
715 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
);
721 /* unsupported operations */
724 Status
= STATUS_NOT_IMPLEMENTED
;
725 AFD_DbgPrint(MIN_TRACE
,
726 ("Irp: Unknown Major code was %x\n",
727 IrpSp
->MajorFunction
));
732 AFD_DbgPrint(MID_TRACE
, ("Returning %x\n", Status
));
733 Irp
->IoStatus
.Status
= Status
;
734 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
740 AfdCancelHandler(PDEVICE_OBJECT DeviceObject
,
743 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
744 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
745 PAFD_FCB FCB
= FileObject
->FsContext
;
747 PAFD_RECV_INFO RecvReq
;
748 PAFD_SEND_INFO SendReq
;
749 PLIST_ENTRY CurrentEntry
;
751 PAFD_DEVICE_EXTENSION DeviceExt
= DeviceObject
->DeviceExtension
;
753 PAFD_ACTIVE_POLL Poll
;
754 PAFD_POLL_INFO PollReq
;
756 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
758 if (!SocketAcquireStateLock(FCB
))
761 ASSERT(IrpSp
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
);
763 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
)
766 RecvReq
= IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
767 UnlockBuffers(RecvReq
->BufferArray
, RecvReq
->BufferCount
, FALSE
);
770 case IOCTL_AFD_RECV_DATAGRAM
:
771 Function
= FUNCTION_RECV
;
775 SendReq
= IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
776 UnlockBuffers(SendReq
->BufferArray
, SendReq
->BufferCount
, FALSE
);
779 case IOCTL_AFD_SEND_DATAGRAM
:
780 Function
= FUNCTION_SEND
;
783 case IOCTL_AFD_CONNECT
:
784 Function
= FUNCTION_CONNECT
;
787 case IOCTL_AFD_WAIT_FOR_LISTEN
:
788 Function
= FUNCTION_PREACCEPT
;
791 case IOCTL_AFD_SELECT
:
792 KeAcquireSpinLock(&DeviceExt
->Lock
, &OldIrql
);
794 CurrentEntry
= DeviceExt
->Polls
.Flink
;
795 while (CurrentEntry
!= &DeviceExt
->Polls
)
797 Poll
= CONTAINING_RECORD(CurrentEntry
, AFD_ACTIVE_POLL
, ListEntry
);
798 CurrentIrp
= Poll
->Irp
;
799 PollReq
= CurrentIrp
->AssociatedIrp
.SystemBuffer
;
801 if (CurrentIrp
== Irp
)
803 ZeroEvents(PollReq
->Handles
, PollReq
->HandleCount
);
804 SignalSocket(Poll
, NULL
, PollReq
, STATUS_CANCELLED
);
809 CurrentEntry
= CurrentEntry
->Flink
;
813 KeReleaseSpinLock(&DeviceExt
->Lock
, OldIrql
);
815 /* IRP already completed by SignalSocket */
816 SocketStateUnlock(FCB
);
821 UnlockAndMaybeComplete(FCB
, STATUS_CANCELLED
, Irp
, 0);
825 CurrentEntry
= FCB
->PendingIrpList
[Function
].Flink
;
826 while (CurrentEntry
!= &FCB
->PendingIrpList
[Function
])
828 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
830 if (CurrentIrp
== Irp
)
832 RemoveEntryList(CurrentEntry
);
837 CurrentEntry
= CurrentEntry
->Flink
;
841 UnlockAndMaybeComplete(FCB
, STATUS_CANCELLED
, Irp
, 0);
845 AfdUnload(PDRIVER_OBJECT DriverObject
)
850 DriverEntry(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
852 PDEVICE_OBJECT DeviceObject
;
853 UNICODE_STRING wstrDeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\Afd");
854 PAFD_DEVICE_EXTENSION DeviceExt
;
857 /* register driver routines */
858 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = AfdDispatch
;
859 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = AfdDispatch
;
860 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = AfdDispatch
;
861 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = AfdDispatch
;
862 DriverObject
->MajorFunction
[IRP_MJ_READ
] = AfdDispatch
;
863 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = AfdDispatch
;
864 DriverObject
->DriverUnload
= AfdUnload
;
866 Status
= IoCreateDevice
868 sizeof(AFD_DEVICE_EXTENSION
),
870 FILE_DEVICE_NAMED_PIPE
,
876 if(!NT_SUCCESS(Status
))
881 DeviceExt
= DeviceObject
->DeviceExtension
;
882 KeInitializeSpinLock( &DeviceExt
->Lock
);
883 InitializeListHead( &DeviceExt
->Polls
);
885 AFD_DbgPrint(MID_TRACE
,("Device created: object %x ext %x\n",
886 DeviceObject
, DeviceExt
));