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)
19 /* See debug.h for debug/trace constants */
20 //DWORD DebugTraceLevel = DEBUG_ULTRA;
21 DWORD DebugTraceLevel
= MIN_TRACE
;
25 void OskitDumpBuffer( PCHAR Data
, UINT Len
) {
28 for( i
= 0; i
< Len
; i
++ ) {
29 if( i
&& !(i
& 0xf) ) DbgPrint( "\n" );
30 if( !(i
& 0xf) ) DbgPrint( "%08x: ", (UINT
)(Data
+ i
) );
31 DbgPrint( " %02x", Data
[i
] & 0xff );
39 DriverEntry(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
);
42 AfdGetDisconnectOptions(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
43 PIO_STACK_LOCATION IrpSp
)
45 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
46 PAFD_FCB FCB
= FileObject
->FsContext
;
47 UINT BufferSize
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
49 UNREFERENCED_PARAMETER(DeviceObject
);
51 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
53 if (FCB
->DisconnectOptionsSize
== 0)
55 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
56 return UnlockAndMaybeComplete(FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0);
59 ASSERT(FCB
->DisconnectOptions
);
61 if (FCB
->FilledDisconnectOptions
< BufferSize
) BufferSize
= FCB
->FilledDisconnectOptions
;
63 RtlCopyMemory(Irp
->UserBuffer
,
64 FCB
->DisconnectOptions
,
67 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, BufferSize
);
72 AfdSetDisconnectOptions(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
73 PIO_STACK_LOCATION IrpSp
)
75 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
76 PAFD_FCB FCB
= FileObject
->FsContext
;
77 PVOID DisconnectOptions
= LockRequest(Irp
, IrpSp
, FALSE
, NULL
);
78 UINT DisconnectOptionsSize
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
80 UNREFERENCED_PARAMETER(DeviceObject
);
82 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
84 if (!DisconnectOptions
)
85 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
87 if (FCB
->DisconnectOptions
)
89 ExFreePool(FCB
->DisconnectOptions
);
90 FCB
->DisconnectOptions
= NULL
;
91 FCB
->DisconnectOptionsSize
= 0;
92 FCB
->FilledDisconnectOptions
= 0;
95 FCB
->DisconnectOptions
= ExAllocatePool(PagedPool
, DisconnectOptionsSize
);
96 if (!FCB
->DisconnectOptions
)
97 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
99 RtlCopyMemory(FCB
->DisconnectOptions
,
101 DisconnectOptionsSize
);
103 FCB
->DisconnectOptionsSize
= DisconnectOptionsSize
;
105 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
110 AfdSetDisconnectOptionsSize(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
111 PIO_STACK_LOCATION IrpSp
)
113 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
114 PAFD_FCB FCB
= FileObject
->FsContext
;
115 PUINT DisconnectOptionsSize
= LockRequest(Irp
, IrpSp
, FALSE
, NULL
);
116 UINT BufferSize
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
118 UNREFERENCED_PARAMETER(DeviceObject
);
120 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
122 if (!DisconnectOptionsSize
)
123 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
125 if (BufferSize
< sizeof(UINT
))
127 AFD_DbgPrint(MIN_TRACE
,("Buffer too small\n"));
128 return UnlockAndMaybeComplete(FCB
, STATUS_BUFFER_TOO_SMALL
, Irp
, 0);
131 if (FCB
->DisconnectOptions
)
133 ExFreePool(FCB
->DisconnectOptions
);
134 FCB
->DisconnectOptionsSize
= 0;
135 FCB
->FilledDisconnectOptions
= 0;
138 FCB
->DisconnectOptions
= ExAllocatePool(PagedPool
, *DisconnectOptionsSize
);
139 if (!FCB
->DisconnectOptions
) return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
141 FCB
->DisconnectOptionsSize
= *DisconnectOptionsSize
;
143 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
147 AfdGetDisconnectData(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
148 PIO_STACK_LOCATION IrpSp
)
150 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
151 PAFD_FCB FCB
= FileObject
->FsContext
;
152 UINT BufferSize
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
154 UNREFERENCED_PARAMETER(DeviceObject
);
156 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
158 if (FCB
->DisconnectDataSize
== 0)
160 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
161 return UnlockAndMaybeComplete(FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0);
164 ASSERT(FCB
->DisconnectData
);
166 if (FCB
->FilledDisconnectData
< BufferSize
)
167 BufferSize
= FCB
->FilledDisconnectData
;
169 RtlCopyMemory(Irp
->UserBuffer
,
173 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, BufferSize
);
178 AfdSetDisconnectData(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
179 PIO_STACK_LOCATION IrpSp
)
181 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
182 PAFD_FCB FCB
= FileObject
->FsContext
;
183 PVOID DisconnectData
= LockRequest(Irp
, IrpSp
, FALSE
, NULL
);
184 UINT DisconnectDataSize
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
186 UNREFERENCED_PARAMETER(DeviceObject
);
188 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
191 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
193 if (FCB
->DisconnectData
)
195 ExFreePool(FCB
->DisconnectData
);
196 FCB
->DisconnectData
= NULL
;
197 FCB
->DisconnectDataSize
= 0;
198 FCB
->FilledDisconnectData
= 0;
201 FCB
->DisconnectData
= ExAllocatePool(PagedPool
, DisconnectDataSize
);
202 if (!FCB
->DisconnectData
)
203 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
205 RtlCopyMemory(FCB
->DisconnectData
,
209 FCB
->DisconnectDataSize
= DisconnectDataSize
;
211 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
216 AfdSetDisconnectDataSize(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
217 PIO_STACK_LOCATION IrpSp
)
219 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
220 PAFD_FCB FCB
= FileObject
->FsContext
;
221 PUINT DisconnectDataSize
= LockRequest(Irp
, IrpSp
, FALSE
, NULL
);
222 UINT BufferSize
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
224 UNREFERENCED_PARAMETER(DeviceObject
);
226 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
228 if (!DisconnectDataSize
)
229 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
231 if (BufferSize
< sizeof(UINT
))
233 AFD_DbgPrint(MIN_TRACE
,("Buffer too small\n"));
234 return UnlockAndMaybeComplete(FCB
, STATUS_BUFFER_TOO_SMALL
, Irp
, 0);
237 if (FCB
->DisconnectData
)
239 ExFreePool(FCB
->DisconnectData
);
240 FCB
->DisconnectDataSize
= 0;
241 FCB
->FilledDisconnectData
= 0;
244 FCB
->DisconnectData
= ExAllocatePool(PagedPool
, *DisconnectDataSize
);
245 if (!FCB
->DisconnectData
)
246 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
248 FCB
->DisconnectDataSize
= *DisconnectDataSize
;
250 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
253 static NTSTATUS NTAPI
254 AfdGetTdiHandles(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
255 PIO_STACK_LOCATION IrpSp
)
257 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
258 PAFD_FCB FCB
= FileObject
->FsContext
;
259 PULONG HandleFlags
= LockRequest(Irp
, IrpSp
, TRUE
, NULL
);
260 PAFD_TDI_HANDLE_DATA HandleData
= Irp
->UserBuffer
;
262 UNREFERENCED_PARAMETER(DeviceObject
);
264 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
267 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
269 if (IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(ULONG
) ||
270 IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(*HandleData
))
272 AFD_DbgPrint(MIN_TRACE
,("Buffer too small\n"));
273 return UnlockAndMaybeComplete(FCB
, STATUS_BUFFER_TOO_SMALL
, Irp
, 0);
276 if ((*HandleFlags
) & AFD_ADDRESS_HANDLE
)
277 HandleData
->TdiAddressHandle
= FCB
->AddressFile
.Handle
;
279 if ((*HandleFlags
) & AFD_CONNECTION_HANDLE
)
280 HandleData
->TdiConnectionHandle
= FCB
->Connection
.Handle
;
282 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
285 static NTSTATUS NTAPI
286 AfdCreateSocket(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
287 PIO_STACK_LOCATION IrpSp
) {
289 PFILE_OBJECT FileObject
;
290 PAFD_DEVICE_EXTENSION DeviceExt
;
291 PFILE_FULL_EA_INFORMATION EaInfo
;
292 PAFD_CREATE_PACKET ConnectInfo
= NULL
;
294 PWCHAR EaInfoValue
= NULL
;
297 NTSTATUS Status
= STATUS_SUCCESS
;
299 AFD_DbgPrint(MID_TRACE
,("AfdCreate(DeviceObject %p Irp %p)\n",
302 DeviceExt
= DeviceObject
->DeviceExtension
;
303 FileObject
= IrpSp
->FileObject
;
304 //Disposition = (IrpSp->Parameters.Create.Options >> 24) & 0xff;
306 Irp
->IoStatus
.Information
= 0;
308 EaInfo
= Irp
->AssociatedIrp
.SystemBuffer
;
311 ConnectInfo
= (PAFD_CREATE_PACKET
)(EaInfo
->EaName
+ EaInfo
->EaNameLength
+ 1);
312 EaInfoValue
= (PWCHAR
)(((PCHAR
)ConnectInfo
) + sizeof(AFD_CREATE_PACKET
));
314 //EaLength = sizeof(FILE_FULL_EA_INFORMATION) + EaInfo->EaNameLength + EaInfo->EaValueLength;
316 AFD_DbgPrint(MID_TRACE
,("EaInfo: %p, EaInfoValue: %p\n",
317 EaInfo
, EaInfoValue
));
320 AFD_DbgPrint(MID_TRACE
,("About to allocate the new FCB\n"));
322 FCB
= ExAllocatePool(NonPagedPool
, sizeof(AFD_FCB
));
324 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
325 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
326 return STATUS_NO_MEMORY
;
329 AFD_DbgPrint(MID_TRACE
,("Initializing the new FCB @ %p (FileObject %p Flags %x)\n",
330 FCB
, FileObject
, ConnectInfo
? ConnectInfo
->EndpointFlags
: 0));
332 RtlZeroMemory( FCB
, sizeof( *FCB
) );
334 FCB
->Flags
= ConnectInfo
? ConnectInfo
->EndpointFlags
: 0;
335 FCB
->GroupID
= ConnectInfo
? ConnectInfo
->GroupID
: 0;
336 FCB
->GroupType
= 0; /* FIXME */
337 FCB
->State
= SOCKET_STATE_CREATED
;
338 FCB
->FileObject
= FileObject
;
339 FCB
->DeviceExt
= DeviceExt
;
340 FCB
->AddressFile
.Handle
= INVALID_HANDLE_VALUE
;
341 FCB
->Connection
.Handle
= INVALID_HANDLE_VALUE
;
343 KeInitializeMutex( &FCB
->Mutex
, 0 );
345 for( i
= 0; i
< MAX_FUNCTIONS
; i
++ ) {
346 InitializeListHead( &FCB
->PendingIrpList
[i
] );
349 InitializeListHead( &FCB
->DatagramList
);
350 InitializeListHead( &FCB
->PendingConnections
);
352 AFD_DbgPrint(MID_TRACE
,("%p: Checking command channel\n", FCB
));
355 FCB
->TdiDeviceName
.Length
= ConnectInfo
->SizeOfTransportName
;
356 FCB
->TdiDeviceName
.MaximumLength
= FCB
->TdiDeviceName
.Length
;
357 FCB
->TdiDeviceName
.Buffer
=
358 ExAllocatePool( NonPagedPool
, FCB
->TdiDeviceName
.Length
);
360 if( !FCB
->TdiDeviceName
.Buffer
) {
362 AFD_DbgPrint(MID_TRACE
,("Could not copy target string\n"));
363 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
364 IoCompleteRequest( Irp
, IO_NETWORK_INCREMENT
);
365 return STATUS_NO_MEMORY
;
368 RtlCopyMemory( FCB
->TdiDeviceName
.Buffer
,
369 ConnectInfo
->TransportName
,
370 FCB
->TdiDeviceName
.Length
);
372 AFD_DbgPrint(MID_TRACE
,("Success: %s %wZ\n",
373 EaInfo
->EaName
, &FCB
->TdiDeviceName
));
375 AFD_DbgPrint(MID_TRACE
,("Success: Control connection\n"));
378 FileObject
->FsContext
= FCB
;
380 /* It seems that UDP sockets are writable from inception */
381 if( FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
) {
382 AFD_DbgPrint(MID_TRACE
,("Packet oriented socket\n"));
384 /* A datagram socket is always sendable */
385 FCB
->PollState
|= AFD_EVENT_SEND
;
386 FCB
->PollStatus
[FD_WRITE_BIT
] = STATUS_SUCCESS
;
387 PollReeval( FCB
->DeviceExt
, FCB
->FileObject
);
390 if( !NT_SUCCESS(Status
) ) {
391 if( FCB
->TdiDeviceName
.Buffer
) ExFreePool( FCB
->TdiDeviceName
.Buffer
);
393 FileObject
->FsContext
= NULL
;
396 Irp
->IoStatus
.Status
= Status
;
397 IoCompleteRequest( Irp
, IO_NETWORK_INCREMENT
);
402 static NTSTATUS NTAPI
403 AfdCleanupSocket(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
404 PIO_STACK_LOCATION IrpSp
)
406 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
407 PAFD_FCB FCB
= FileObject
->FsContext
;
408 PLIST_ENTRY CurrentEntry
, NextEntry
;
412 UNREFERENCED_PARAMETER(DeviceObject
);
414 if( !SocketAcquireStateLock( FCB
) ) return LostSocket(Irp
);
416 for (Function
= 0; Function
< MAX_FUNCTIONS
; Function
++)
418 CurrentEntry
= FCB
->PendingIrpList
[Function
].Flink
;
419 while (CurrentEntry
!= &FCB
->PendingIrpList
[Function
])
421 NextEntry
= CurrentEntry
->Flink
;
422 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
424 /* The cancel routine will remove the IRP from the list */
425 IoCancelIrp(CurrentIrp
);
427 CurrentEntry
= NextEntry
;
431 KillSelectsForFCB( FCB
->DeviceExt
, FileObject
, FALSE
);
433 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
436 static NTSTATUS NTAPI
437 AfdCloseSocket(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
438 PIO_STACK_LOCATION IrpSp
)
440 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
441 PAFD_FCB FCB
= FileObject
->FsContext
;
443 PAFD_IN_FLIGHT_REQUEST InFlightRequest
[IN_FLIGHT_REQUESTS
];
444 PAFD_TDI_OBJECT_QELT Qelt
;
445 PLIST_ENTRY QeltEntry
;
448 AFD_DbgPrint(MID_TRACE
,("AfdClose(DeviceObject %p Irp %p)\n",
451 if( !SocketAcquireStateLock( FCB
) ) return STATUS_FILE_CLOSED
;
453 FCB
->State
= SOCKET_STATE_CLOSED
;
455 InFlightRequest
[0] = &FCB
->ListenIrp
;
456 InFlightRequest
[1] = &FCB
->ReceiveIrp
;
457 InFlightRequest
[2] = &FCB
->SendIrp
;
458 InFlightRequest
[3] = &FCB
->ConnectIrp
;
459 InFlightRequest
[4] = &FCB
->DisconnectIrp
;
461 /* Cancel our pending requests */
462 for( i
= 0; i
< IN_FLIGHT_REQUESTS
; i
++ ) {
463 if( InFlightRequest
[i
]->InFlightRequest
) {
464 AFD_DbgPrint(MID_TRACE
,("Cancelling in flight irp %u (%p)\n",
465 i
, InFlightRequest
[i
]->InFlightRequest
));
466 IoCancelIrp(InFlightRequest
[i
]->InFlightRequest
);
470 KillSelectsForFCB( FCB
->DeviceExt
, FileObject
, FALSE
);
472 ASSERT(IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_CONNECT
]));
473 ASSERT(IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]));
474 ASSERT(IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_RECV
]));
475 ASSERT(IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_PREACCEPT
]));
476 ASSERT(IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]));
478 while (!IsListEmpty(&FCB
->PendingConnections
))
480 QeltEntry
= RemoveHeadList(&FCB
->PendingConnections
);
481 Qelt
= CONTAINING_RECORD(QeltEntry
, AFD_TDI_OBJECT_QELT
, ListEntry
);
483 /* We have to close all pending connections or the listen won't get closed */
484 TdiDisassociateAddressFile(Qelt
->Object
.Object
);
485 ObDereferenceObject(Qelt
->Object
.Object
);
486 ZwClose(Qelt
->Object
.Handle
);
491 SocketStateUnlock( FCB
);
493 if( FCB
->EventSelect
)
494 ObDereferenceObject( FCB
->EventSelect
);
497 ExFreePool( FCB
->Context
);
499 if( FCB
->Recv
.Window
)
500 ExFreePool( FCB
->Recv
.Window
);
502 if( FCB
->Send
.Window
)
503 ExFreePool( FCB
->Send
.Window
);
505 if( FCB
->AddressFrom
)
506 ExFreePool( FCB
->AddressFrom
);
508 if( FCB
->ConnectCallInfo
)
509 ExFreePool( FCB
->ConnectCallInfo
);
511 if( FCB
->ConnectReturnInfo
)
512 ExFreePool( FCB
->ConnectReturnInfo
);
514 if( FCB
->ConnectData
)
515 ExFreePool( FCB
->ConnectData
);
517 if( FCB
->DisconnectData
)
518 ExFreePool( FCB
->DisconnectData
);
520 if( FCB
->ConnectOptions
)
521 ExFreePool( FCB
->ConnectOptions
);
523 if( FCB
->DisconnectOptions
)
524 ExFreePool( FCB
->DisconnectOptions
);
526 if( FCB
->LocalAddress
)
527 ExFreePool( FCB
->LocalAddress
);
529 if( FCB
->RemoteAddress
)
530 ExFreePool( FCB
->RemoteAddress
);
532 if( FCB
->Connection
.Object
)
534 TdiDisassociateAddressFile(FCB
->Connection
.Object
);
535 ObDereferenceObject(FCB
->Connection
.Object
);
538 if( FCB
->AddressFile
.Object
)
539 ObDereferenceObject(FCB
->AddressFile
.Object
);
541 if( FCB
->AddressFile
.Handle
!= INVALID_HANDLE_VALUE
)
543 if (ZwClose(FCB
->AddressFile
.Handle
) == STATUS_INVALID_HANDLE
)
545 DbgPrint("INVALID ADDRESS FILE HANDLE VALUE: %p %p\n", FCB
->AddressFile
.Handle
, FCB
->AddressFile
.Object
);
549 if( FCB
->Connection
.Handle
!= INVALID_HANDLE_VALUE
)
551 if (ZwClose(FCB
->Connection
.Handle
) == STATUS_INVALID_HANDLE
)
553 DbgPrint("INVALID CONNECTION HANDLE VALUE: %p %p\n", FCB
->Connection
.Handle
, FCB
->Connection
.Object
);
557 if( FCB
->TdiDeviceName
.Buffer
)
558 ExFreePool(FCB
->TdiDeviceName
.Buffer
);
562 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
563 Irp
->IoStatus
.Information
= 0;
564 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
566 AFD_DbgPrint(MID_TRACE
, ("Returning success.\n"));
568 return STATUS_SUCCESS
;
571 static IO_COMPLETION_ROUTINE DisconnectComplete
;
575 DisconnectComplete(PDEVICE_OBJECT DeviceObject
,
579 PAFD_FCB FCB
= Context
;
581 PLIST_ENTRY CurrentEntry
;
583 UNREFERENCED_PARAMETER(DeviceObject
);
585 if (!SocketAcquireStateLock(FCB
))
586 return STATUS_FILE_CLOSED
;
588 ASSERT(FCB
->DisconnectIrp
.InFlightRequest
== Irp
);
589 FCB
->DisconnectIrp
.InFlightRequest
= NULL
;
591 ASSERT(FCB
->DisconnectPending
);
592 ASSERT((IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]) && !FCB
->SendIrp
.InFlightRequest
) ||
593 (FCB
->DisconnectFlags
& TDI_DISCONNECT_ABORT
));
595 if (NT_SUCCESS(Irp
->IoStatus
.Status
) && (FCB
->DisconnectFlags
& TDI_DISCONNECT_RELEASE
))
597 FCB
->FilledDisconnectData
= MIN(FCB
->DisconnectDataSize
, FCB
->ConnectReturnInfo
->UserDataLength
);
598 if (FCB
->FilledDisconnectData
)
600 RtlCopyMemory(FCB
->DisconnectData
,
601 FCB
->ConnectReturnInfo
->UserData
,
602 FCB
->FilledDisconnectData
);
605 FCB
->FilledDisconnectOptions
= MIN(FCB
->DisconnectOptionsSize
, FCB
->ConnectReturnInfo
->OptionsLength
);
606 if (FCB
->FilledDisconnectOptions
)
608 RtlCopyMemory(FCB
->DisconnectOptions
,
609 FCB
->ConnectReturnInfo
->Options
,
610 FCB
->FilledDisconnectOptions
);
614 FCB
->DisconnectPending
= FALSE
;
616 while (!IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]))
618 CurrentEntry
= RemoveHeadList(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]);
619 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
620 CurrentIrp
->IoStatus
.Status
= Irp
->IoStatus
.Status
;
621 CurrentIrp
->IoStatus
.Information
= 0;
622 UnlockRequest(CurrentIrp
, IoGetCurrentIrpStackLocation(CurrentIrp
));
623 (void)IoSetCancelRoutine(CurrentIrp
, NULL
);
624 IoCompleteRequest(CurrentIrp
, IO_NETWORK_INCREMENT
);
627 if (!(FCB
->DisconnectFlags
& TDI_DISCONNECT_RELEASE
))
629 /* Signal complete connection closure immediately */
630 FCB
->PollState
|= AFD_EVENT_ABORT
;
631 FCB
->PollStatus
[FD_CLOSE_BIT
] = Irp
->IoStatus
.Status
;
632 FCB
->LastReceiveStatus
= STATUS_FILE_CLOSED
;
633 PollReeval(FCB
->DeviceExt
, FCB
->FileObject
);
636 SocketStateUnlock(FCB
);
638 return Irp
->IoStatus
.Status
;
643 DoDisconnect(PAFD_FCB FCB
)
647 ASSERT(FCB
->DisconnectPending
);
648 ASSERT((IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]) && !FCB
->SendIrp
.InFlightRequest
) ||
649 (FCB
->DisconnectFlags
& TDI_DISCONNECT_ABORT
));
651 if (FCB
->DisconnectIrp
.InFlightRequest
)
653 return STATUS_PENDING
;
656 FCB
->ConnectCallInfo
->UserData
= FCB
->DisconnectData
;
657 FCB
->ConnectCallInfo
->UserDataLength
= FCB
->DisconnectDataSize
;
658 FCB
->ConnectCallInfo
->Options
= FCB
->DisconnectOptions
;
659 FCB
->ConnectCallInfo
->OptionsLength
= FCB
->DisconnectOptionsSize
;
661 Status
= TdiDisconnect(&FCB
->DisconnectIrp
.InFlightRequest
,
662 FCB
->Connection
.Object
,
663 &FCB
->DisconnectTimeout
,
664 FCB
->DisconnectFlags
,
665 &FCB
->DisconnectIrp
.Iosb
,
668 FCB
->ConnectCallInfo
,
669 FCB
->ConnectReturnInfo
);
670 if (Status
!= STATUS_PENDING
)
672 FCB
->DisconnectPending
= FALSE
;
679 RetryDisconnectCompletion(PAFD_FCB FCB
)
681 ASSERT(FCB
->RemoteAddress
);
683 if (IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]) && !FCB
->SendIrp
.InFlightRequest
&& FCB
->DisconnectPending
)
685 /* Sends are done; fire off a TDI_DISCONNECT request */
690 static NTSTATUS NTAPI
691 AfdDisconnect(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
692 PIO_STACK_LOCATION IrpSp
) {
693 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
694 PAFD_FCB FCB
= FileObject
->FsContext
;
695 PAFD_DISCONNECT_INFO DisReq
;
696 NTSTATUS Status
= STATUS_SUCCESS
;
698 PLIST_ENTRY CurrentEntry
;
701 UNREFERENCED_PARAMETER(DeviceObject
);
703 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
705 if (!(DisReq
= LockRequest(Irp
, IrpSp
, FALSE
, NULL
)))
706 return UnlockAndMaybeComplete( FCB
, STATUS_NO_MEMORY
,
709 /* Send direction only */
710 if ((DisReq
->DisconnectType
& AFD_DISCONNECT_SEND
) &&
711 !(DisReq
->DisconnectType
& AFD_DISCONNECT_RECV
))
713 /* Perform a controlled disconnect */
714 Flags
= TDI_DISCONNECT_RELEASE
;
716 /* Receive direction or both */
719 /* Mark that we can't issue another receive request */
720 FCB
->TdiReceiveClosed
= TRUE
;
722 /* Try to cancel a pending TDI receive IRP if there was one in progress */
723 if (FCB
->ReceiveIrp
.InFlightRequest
)
724 IoCancelIrp(FCB
->ReceiveIrp
.InFlightRequest
);
726 /* Discard any pending data */
727 FCB
->Recv
.Content
= 0;
728 FCB
->Recv
.BytesUsed
= 0;
730 /* Mark us as overread to complete future reads with an error */
731 FCB
->Overread
= TRUE
;
733 /* Set a successful receive status to indicate a shutdown on overread */
734 FCB
->LastReceiveStatus
= STATUS_SUCCESS
;
736 /* Clear the receive event */
737 FCB
->PollState
&= ~AFD_EVENT_RECEIVE
;
739 /* Receive direction only */
740 if ((DisReq
->DisconnectType
& AFD_DISCONNECT_RECV
) &&
741 !(DisReq
->DisconnectType
& AFD_DISCONNECT_SEND
))
743 /* No need to tell the transport driver for receive direction only */
744 return UnlockAndMaybeComplete( FCB
, STATUS_SUCCESS
, Irp
, 0 );
748 /* Perform an abortive disconnect */
749 Flags
= TDI_DISCONNECT_ABORT
;
753 if (!(FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
))
755 if (!FCB
->ConnectCallInfo
)
757 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
758 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
,
762 if (FCB
->DisconnectPending
)
764 if (FCB
->DisconnectIrp
.InFlightRequest
)
766 IoCancelIrp(FCB
->DisconnectIrp
.InFlightRequest
);
767 ASSERT(!FCB
->DisconnectIrp
.InFlightRequest
);
771 while (!IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]))
773 CurrentEntry
= RemoveHeadList(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]);
774 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
775 CurrentIrp
->IoStatus
.Status
= STATUS_CANCELLED
;
776 CurrentIrp
->IoStatus
.Information
= 0;
777 UnlockRequest(CurrentIrp
, IoGetCurrentIrpStackLocation(CurrentIrp
));
778 (void)IoSetCancelRoutine(CurrentIrp
, NULL
);
779 IoCompleteRequest(CurrentIrp
, IO_NETWORK_INCREMENT
);
784 FCB
->DisconnectFlags
= Flags
;
785 FCB
->DisconnectTimeout
= DisReq
->Timeout
;
786 FCB
->DisconnectPending
= TRUE
;
787 FCB
->SendClosed
= TRUE
;
788 FCB
->PollState
&= ~AFD_EVENT_SEND
;
790 Status
= QueueUserModeIrp(FCB
, Irp
, FUNCTION_DISCONNECT
);
791 if (Status
== STATUS_PENDING
)
793 if ((IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]) && !FCB
->SendIrp
.InFlightRequest
) ||
794 (FCB
->DisconnectFlags
& TDI_DISCONNECT_ABORT
))
796 /* Go ahead and execute the disconnect because we're ready for it */
797 Status
= DoDisconnect(FCB
);
800 if (Status
!= STATUS_PENDING
)
801 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
804 if (Status
== STATUS_PENDING
)
806 SocketStateUnlock(FCB
);
813 if (!(Flags
& TDI_DISCONNECT_RELEASE
))
815 if (!FCB
->RemoteAddress
)
817 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
818 return UnlockAndMaybeComplete(FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0);
821 ExFreePool(FCB
->RemoteAddress
);
823 FCB
->RemoteAddress
= NULL
;
826 FCB
->PollState
&= ~AFD_EVENT_SEND
;
827 FCB
->SendClosed
= TRUE
;
830 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );
833 static DRIVER_DISPATCH AfdDispatch
;
834 static NTSTATUS NTAPI
835 AfdDispatch(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
837 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
838 NTSTATUS Status
= STATUS_NOT_IMPLEMENTED
;
840 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
843 AFD_DbgPrint(MID_TRACE
,("AfdDispatch: %u\n", IrpSp
->MajorFunction
));
844 if( IrpSp
->MajorFunction
!= IRP_MJ_CREATE
) {
845 AFD_DbgPrint(MID_TRACE
,("FO %p, IrpSp->FO %p\n",
846 FileObject
, IrpSp
->FileObject
));
847 ASSERT(FileObject
== IrpSp
->FileObject
);
850 Irp
->IoStatus
.Information
= 0;
852 switch(IrpSp
->MajorFunction
)
854 /* opening and closing handles to the device */
856 /* Mostly borrowed from the named pipe file system */
857 return AfdCreateSocket(DeviceObject
, Irp
, IrpSp
);
860 /* Ditto the borrowing */
861 return AfdCloseSocket(DeviceObject
, Irp
, IrpSp
);
864 return AfdCleanupSocket(DeviceObject
, Irp
, IrpSp
);
868 return AfdConnectedSocketWriteData( DeviceObject
, Irp
, IrpSp
, TRUE
);
872 return AfdConnectedSocketReadData( DeviceObject
, Irp
, IrpSp
, TRUE
);
874 case IRP_MJ_DEVICE_CONTROL
:
876 switch( IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
878 return AfdBindSocket( DeviceObject
, Irp
, IrpSp
);
880 case IOCTL_AFD_CONNECT
:
881 return AfdStreamSocketConnect( DeviceObject
, Irp
, IrpSp
);
883 case IOCTL_AFD_START_LISTEN
:
884 return AfdListenSocket( DeviceObject
, Irp
, IrpSp
);
887 return AfdConnectedSocketReadData( DeviceObject
, Irp
, IrpSp
,
890 case IOCTL_AFD_SELECT
:
891 return AfdSelect( DeviceObject
, Irp
, IrpSp
);
893 case IOCTL_AFD_EVENT_SELECT
:
894 return AfdEventSelect( DeviceObject
, Irp
, IrpSp
);
896 case IOCTL_AFD_ENUM_NETWORK_EVENTS
:
897 return AfdEnumEvents( DeviceObject
, Irp
, IrpSp
);
899 case IOCTL_AFD_RECV_DATAGRAM
:
900 return AfdPacketSocketReadData( DeviceObject
, Irp
, IrpSp
);
903 return AfdConnectedSocketWriteData( DeviceObject
, Irp
, IrpSp
,
906 case IOCTL_AFD_SEND_DATAGRAM
:
907 return AfdPacketSocketWriteData( DeviceObject
, Irp
, IrpSp
);
909 case IOCTL_AFD_GET_INFO
:
910 return AfdGetInfo( DeviceObject
, Irp
, IrpSp
);
912 case IOCTL_AFD_SET_INFO
:
913 return AfdSetInfo( DeviceObject
, Irp
, IrpSp
);
915 case IOCTL_AFD_GET_CONTEXT_SIZE
:
916 return AfdGetContextSize( DeviceObject
, Irp
, IrpSp
);
918 case IOCTL_AFD_GET_CONTEXT
:
919 return AfdGetContext( DeviceObject
, Irp
, IrpSp
);
921 case IOCTL_AFD_SET_CONTEXT
:
922 return AfdSetContext( DeviceObject
, Irp
, IrpSp
);
924 case IOCTL_AFD_WAIT_FOR_LISTEN
:
925 return AfdWaitForListen( DeviceObject
, Irp
, IrpSp
);
927 case IOCTL_AFD_ACCEPT
:
928 return AfdAccept( DeviceObject
, Irp
, IrpSp
);
930 case IOCTL_AFD_DISCONNECT
:
931 return AfdDisconnect( DeviceObject
, Irp
, IrpSp
);
933 case IOCTL_AFD_GET_SOCK_NAME
:
934 return AfdGetSockName( DeviceObject
, Irp
, IrpSp
);
936 case IOCTL_AFD_GET_PEER_NAME
:
937 return AfdGetPeerName( DeviceObject
, Irp
, IrpSp
);
939 case IOCTL_AFD_GET_CONNECT_DATA
:
940 return AfdGetConnectData(DeviceObject
, Irp
, IrpSp
);
942 case IOCTL_AFD_SET_CONNECT_DATA
:
943 return AfdSetConnectData(DeviceObject
, Irp
, IrpSp
);
945 case IOCTL_AFD_SET_DISCONNECT_DATA
:
946 return AfdSetDisconnectData(DeviceObject
, Irp
, IrpSp
);
948 case IOCTL_AFD_GET_DISCONNECT_DATA
:
949 return AfdGetDisconnectData(DeviceObject
, Irp
, IrpSp
);
951 case IOCTL_AFD_SET_CONNECT_DATA_SIZE
:
952 return AfdSetConnectDataSize(DeviceObject
, Irp
, IrpSp
);
954 case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE
:
955 return AfdSetDisconnectDataSize(DeviceObject
, Irp
, IrpSp
);
957 case IOCTL_AFD_SET_CONNECT_OPTIONS
:
958 return AfdSetConnectOptions(DeviceObject
, Irp
, IrpSp
);
960 case IOCTL_AFD_SET_DISCONNECT_OPTIONS
:
961 return AfdSetDisconnectOptions(DeviceObject
, Irp
, IrpSp
);
963 case IOCTL_AFD_GET_CONNECT_OPTIONS
:
964 return AfdGetConnectOptions(DeviceObject
, Irp
, IrpSp
);
966 case IOCTL_AFD_GET_DISCONNECT_OPTIONS
:
967 return AfdGetDisconnectOptions(DeviceObject
, Irp
, IrpSp
);
969 case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE
:
970 return AfdSetConnectOptionsSize(DeviceObject
, Irp
, IrpSp
);
972 case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE
:
973 return AfdSetDisconnectOptionsSize(DeviceObject
, Irp
, IrpSp
);
975 case IOCTL_AFD_GET_TDI_HANDLES
:
976 return AfdGetTdiHandles(DeviceObject
, Irp
, IrpSp
);
978 case IOCTL_AFD_DEFER_ACCEPT
:
979 DbgPrint("IOCTL_AFD_DEFER_ACCEPT is UNIMPLEMENTED!\n");
982 case IOCTL_AFD_GET_PENDING_CONNECT_DATA
:
983 DbgPrint("IOCTL_AFD_GET_PENDING_CONNECT_DATA is UNIMPLEMENTED!\n");
986 case IOCTL_AFD_VALIDATE_GROUP
:
987 DbgPrint("IOCTL_AFD_VALIDATE_GROUP is UNIMPLEMENTED!\n");
991 Status
= STATUS_NOT_SUPPORTED
;
992 DbgPrint("Unknown IOCTL (0x%x)\n",
993 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
);
999 /* unsupported operations */
1002 Status
= STATUS_NOT_IMPLEMENTED
;
1003 AFD_DbgPrint(MIN_TRACE
,
1004 ("Irp: Unknown Major code was %x\n",
1005 IrpSp
->MajorFunction
));
1010 AFD_DbgPrint(MID_TRACE
, ("Returning %x\n", Status
));
1011 Irp
->IoStatus
.Status
= Status
;
1012 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1017 BOOLEAN
CheckUnlockExtraBuffers(PAFD_FCB FCB
, PIO_STACK_LOCATION IrpSp
)
1019 if (FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
)
1021 if (IrpSp
->MajorFunction
== IRP_MJ_READ
|| IrpSp
->MajorFunction
== IRP_MJ_WRITE
)
1023 /* read()/write() call - no extra buffers */
1026 else if (IrpSp
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
)
1028 if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_RECV_DATAGRAM
)
1030 /* recvfrom() call - extra buffers */
1033 else if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_RECV
)
1035 /* recv() call - no extra buffers */
1038 else if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SEND
||
1039 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SEND_DATAGRAM
)
1041 /* send()/sendto() call - no extra buffers */
1053 /* Unknown IRP_MJ code */
1060 /* Connection-oriented never has extra buffers */
1066 CleanupPendingIrp(PAFD_FCB FCB
, PIRP Irp
, PIO_STACK_LOCATION IrpSp
, PAFD_ACTIVE_POLL Poll
)
1068 PAFD_RECV_INFO RecvReq
;
1069 PAFD_SEND_INFO SendReq
;
1070 PAFD_POLL_INFO PollReq
;
1072 if (IrpSp
->MajorFunction
== IRP_MJ_READ
)
1074 RecvReq
= GetLockedData(Irp
, IrpSp
);
1075 UnlockBuffers(RecvReq
->BufferArray
, RecvReq
->BufferCount
, CheckUnlockExtraBuffers(FCB
, IrpSp
));
1077 else if (IrpSp
->MajorFunction
== IRP_MJ_WRITE
)
1079 SendReq
= GetLockedData(Irp
, IrpSp
);
1080 UnlockBuffers(SendReq
->BufferArray
, SendReq
->BufferCount
, CheckUnlockExtraBuffers(FCB
, IrpSp
));
1084 ASSERT(IrpSp
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
);
1086 if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_RECV
)
1088 RecvReq
= GetLockedData(Irp
, IrpSp
);
1089 UnlockBuffers(RecvReq
->BufferArray
, RecvReq
->BufferCount
, CheckUnlockExtraBuffers(FCB
, IrpSp
));
1091 else if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SEND
)
1093 SendReq
= GetLockedData(Irp
, IrpSp
);
1094 UnlockBuffers(SendReq
->BufferArray
, SendReq
->BufferCount
, CheckUnlockExtraBuffers(FCB
, IrpSp
));
1096 else if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SELECT
)
1100 PollReq
= Irp
->AssociatedIrp
.SystemBuffer
;
1101 ZeroEvents(PollReq
->Handles
, PollReq
->HandleCount
);
1102 SignalSocket(Poll
, NULL
, PollReq
, STATUS_CANCELLED
);
1109 AfdCancelHandler(PDEVICE_OBJECT DeviceObject
,
1112 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1113 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
1114 PAFD_FCB FCB
= FileObject
->FsContext
;
1115 ULONG Function
, IoctlCode
;
1117 PLIST_ENTRY CurrentEntry
;
1118 PAFD_DEVICE_EXTENSION DeviceExt
= DeviceObject
->DeviceExtension
;
1120 PAFD_ACTIVE_POLL Poll
;
1122 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
1124 if (!SocketAcquireStateLock(FCB
))
1127 switch (IrpSp
->MajorFunction
)
1129 case IRP_MJ_DEVICE_CONTROL
:
1130 IoctlCode
= IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
;
1134 IoctlCode
= IOCTL_AFD_RECV
;
1138 IoctlCode
= IOCTL_AFD_SEND
;
1143 SocketStateUnlock(FCB
);
1149 case IOCTL_AFD_RECV
:
1150 case IOCTL_AFD_RECV_DATAGRAM
:
1151 Function
= FUNCTION_RECV
;
1154 case IOCTL_AFD_SEND
:
1155 case IOCTL_AFD_SEND_DATAGRAM
:
1156 Function
= FUNCTION_SEND
;
1159 case IOCTL_AFD_CONNECT
:
1160 Function
= FUNCTION_CONNECT
;
1163 case IOCTL_AFD_WAIT_FOR_LISTEN
:
1164 Function
= FUNCTION_PREACCEPT
;
1167 case IOCTL_AFD_SELECT
:
1168 KeAcquireSpinLock(&DeviceExt
->Lock
, &OldIrql
);
1170 CurrentEntry
= DeviceExt
->Polls
.Flink
;
1171 while (CurrentEntry
!= &DeviceExt
->Polls
)
1173 Poll
= CONTAINING_RECORD(CurrentEntry
, AFD_ACTIVE_POLL
, ListEntry
);
1175 if (Irp
== Poll
->Irp
)
1177 CleanupPendingIrp(FCB
, Irp
, IrpSp
, Poll
);
1178 KeReleaseSpinLock(&DeviceExt
->Lock
, OldIrql
);
1179 SocketStateUnlock(FCB
);
1184 CurrentEntry
= CurrentEntry
->Flink
;
1188 KeReleaseSpinLock(&DeviceExt
->Lock
, OldIrql
);
1190 SocketStateUnlock(FCB
);
1192 DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (IOCTL_AFD_SELECT)\n");
1195 case IOCTL_AFD_DISCONNECT
:
1196 Function
= FUNCTION_DISCONNECT
;
1201 UnlockAndMaybeComplete(FCB
, STATUS_CANCELLED
, Irp
, 0);
1205 CurrentEntry
= FCB
->PendingIrpList
[Function
].Flink
;
1206 while (CurrentEntry
!= &FCB
->PendingIrpList
[Function
])
1208 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
1210 if (CurrentIrp
== Irp
)
1212 RemoveEntryList(CurrentEntry
);
1213 CleanupPendingIrp(FCB
, Irp
, IrpSp
, NULL
);
1214 UnlockAndMaybeComplete(FCB
, STATUS_CANCELLED
, Irp
, 0);
1219 CurrentEntry
= CurrentEntry
->Flink
;
1223 SocketStateUnlock(FCB
);
1225 DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (Function: %u)\n", Function
);
1228 static DRIVER_UNLOAD AfdUnload
;
1230 AfdUnload(PDRIVER_OBJECT DriverObject
)
1232 UNREFERENCED_PARAMETER(DriverObject
);
1236 DriverEntry(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
1238 PDEVICE_OBJECT DeviceObject
;
1239 UNICODE_STRING wstrDeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\Afd");
1240 PAFD_DEVICE_EXTENSION DeviceExt
;
1243 UNREFERENCED_PARAMETER(RegistryPath
);
1244 /* register driver routines */
1245 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = AfdDispatch
;
1246 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = AfdDispatch
;
1247 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = AfdDispatch
;
1248 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = AfdDispatch
;
1249 DriverObject
->MajorFunction
[IRP_MJ_READ
] = AfdDispatch
;
1250 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = AfdDispatch
;
1251 DriverObject
->DriverUnload
= AfdUnload
;
1253 Status
= IoCreateDevice(DriverObject
,
1254 sizeof(AFD_DEVICE_EXTENSION
),
1256 FILE_DEVICE_NAMED_PIPE
,
1262 if (!NT_SUCCESS(Status
))
1267 DeviceExt
= DeviceObject
->DeviceExtension
;
1268 KeInitializeSpinLock( &DeviceExt
->Lock
);
1269 InitializeListHead( &DeviceExt
->Polls
);
1271 AFD_DbgPrint(MID_TRACE
,("Device created: object %p ext %p\n",
1272 DeviceObject
, DeviceExt
));