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
,
667 FCB
->ConnectCallInfo
,
668 FCB
->ConnectReturnInfo
);
669 if (Status
!= STATUS_PENDING
)
671 FCB
->DisconnectPending
= FALSE
;
678 RetryDisconnectCompletion(PAFD_FCB FCB
)
680 ASSERT(FCB
->RemoteAddress
);
682 if (IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]) && !FCB
->SendIrp
.InFlightRequest
&& FCB
->DisconnectPending
)
684 /* Sends are done; fire off a TDI_DISCONNECT request */
689 static NTSTATUS NTAPI
690 AfdDisconnect(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
691 PIO_STACK_LOCATION IrpSp
) {
692 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
693 PAFD_FCB FCB
= FileObject
->FsContext
;
694 PAFD_DISCONNECT_INFO DisReq
;
695 NTSTATUS Status
= STATUS_SUCCESS
;
697 PLIST_ENTRY CurrentEntry
;
700 UNREFERENCED_PARAMETER(DeviceObject
);
702 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
704 if (!(DisReq
= LockRequest(Irp
, IrpSp
, FALSE
, NULL
)))
705 return UnlockAndMaybeComplete( FCB
, STATUS_NO_MEMORY
,
708 /* Send direction only */
709 if ((DisReq
->DisconnectType
& AFD_DISCONNECT_SEND
) &&
710 !(DisReq
->DisconnectType
& AFD_DISCONNECT_RECV
))
712 /* Perform a controlled disconnect */
713 Flags
= TDI_DISCONNECT_RELEASE
;
715 /* Receive direction or both */
718 /* Mark that we can't issue another receive request */
719 FCB
->TdiReceiveClosed
= TRUE
;
721 /* Try to cancel a pending TDI receive IRP if there was one in progress */
722 if (FCB
->ReceiveIrp
.InFlightRequest
)
723 IoCancelIrp(FCB
->ReceiveIrp
.InFlightRequest
);
725 /* Discard any pending data */
726 FCB
->Recv
.Content
= 0;
727 FCB
->Recv
.BytesUsed
= 0;
729 /* Mark us as overread to complete future reads with an error */
730 FCB
->Overread
= TRUE
;
732 /* Set a successful receive status to indicate a shutdown on overread */
733 FCB
->LastReceiveStatus
= STATUS_SUCCESS
;
735 /* Clear the receive event */
736 FCB
->PollState
&= ~AFD_EVENT_RECEIVE
;
738 /* Receive direction only */
739 if ((DisReq
->DisconnectType
& AFD_DISCONNECT_RECV
) &&
740 !(DisReq
->DisconnectType
& AFD_DISCONNECT_SEND
))
742 /* No need to tell the transport driver for receive direction only */
743 return UnlockAndMaybeComplete( FCB
, STATUS_SUCCESS
, Irp
, 0 );
747 /* Perform an abortive disconnect */
748 Flags
= TDI_DISCONNECT_ABORT
;
752 if (!(FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
))
754 if (!FCB
->ConnectCallInfo
)
756 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
757 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
,
761 if (FCB
->DisconnectPending
)
763 if (FCB
->DisconnectIrp
.InFlightRequest
)
765 IoCancelIrp(FCB
->DisconnectIrp
.InFlightRequest
);
766 ASSERT(!FCB
->DisconnectIrp
.InFlightRequest
);
770 while (!IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]))
772 CurrentEntry
= RemoveHeadList(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]);
773 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
774 CurrentIrp
->IoStatus
.Status
= STATUS_CANCELLED
;
775 CurrentIrp
->IoStatus
.Information
= 0;
776 UnlockRequest(CurrentIrp
, IoGetCurrentIrpStackLocation(CurrentIrp
));
777 (void)IoSetCancelRoutine(CurrentIrp
, NULL
);
778 IoCompleteRequest(CurrentIrp
, IO_NETWORK_INCREMENT
);
783 FCB
->DisconnectFlags
= Flags
;
784 FCB
->DisconnectTimeout
= DisReq
->Timeout
;
785 FCB
->DisconnectPending
= TRUE
;
786 FCB
->SendClosed
= TRUE
;
787 FCB
->PollState
&= ~AFD_EVENT_SEND
;
789 Status
= QueueUserModeIrp(FCB
, Irp
, FUNCTION_DISCONNECT
);
790 if (Status
== STATUS_PENDING
)
792 if ((IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]) && !FCB
->SendIrp
.InFlightRequest
) ||
793 (FCB
->DisconnectFlags
& TDI_DISCONNECT_ABORT
))
795 /* Go ahead and execute the disconnect because we're ready for it */
796 Status
= DoDisconnect(FCB
);
799 if (Status
!= STATUS_PENDING
)
800 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
803 if (Status
== STATUS_PENDING
)
805 SocketStateUnlock(FCB
);
812 if (!(Flags
& TDI_DISCONNECT_RELEASE
))
814 if (!FCB
->RemoteAddress
)
816 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
817 return UnlockAndMaybeComplete(FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0);
820 ExFreePool(FCB
->RemoteAddress
);
822 FCB
->RemoteAddress
= NULL
;
825 FCB
->PollState
&= ~AFD_EVENT_SEND
;
826 FCB
->SendClosed
= TRUE
;
829 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );
832 static DRIVER_DISPATCH AfdDispatch
;
833 static NTSTATUS NTAPI
834 AfdDispatch(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
836 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
837 NTSTATUS Status
= STATUS_NOT_IMPLEMENTED
;
839 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
842 AFD_DbgPrint(MID_TRACE
,("AfdDispatch: %u\n", IrpSp
->MajorFunction
));
843 if( IrpSp
->MajorFunction
!= IRP_MJ_CREATE
) {
844 AFD_DbgPrint(MID_TRACE
,("FO %p, IrpSp->FO %p\n",
845 FileObject
, IrpSp
->FileObject
));
846 ASSERT(FileObject
== IrpSp
->FileObject
);
849 Irp
->IoStatus
.Information
= 0;
851 switch(IrpSp
->MajorFunction
)
853 /* opening and closing handles to the device */
855 /* Mostly borrowed from the named pipe file system */
856 return AfdCreateSocket(DeviceObject
, Irp
, IrpSp
);
859 /* Ditto the borrowing */
860 return AfdCloseSocket(DeviceObject
, Irp
, IrpSp
);
863 return AfdCleanupSocket(DeviceObject
, Irp
, IrpSp
);
867 return AfdConnectedSocketWriteData( DeviceObject
, Irp
, IrpSp
, TRUE
);
871 return AfdConnectedSocketReadData( DeviceObject
, Irp
, IrpSp
, TRUE
);
873 case IRP_MJ_DEVICE_CONTROL
:
875 switch( IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
877 return AfdBindSocket( DeviceObject
, Irp
, IrpSp
);
879 case IOCTL_AFD_CONNECT
:
880 return AfdStreamSocketConnect( DeviceObject
, Irp
, IrpSp
);
882 case IOCTL_AFD_START_LISTEN
:
883 return AfdListenSocket( DeviceObject
, Irp
, IrpSp
);
886 return AfdConnectedSocketReadData( DeviceObject
, Irp
, IrpSp
,
889 case IOCTL_AFD_SELECT
:
890 return AfdSelect( DeviceObject
, Irp
, IrpSp
);
892 case IOCTL_AFD_EVENT_SELECT
:
893 return AfdEventSelect( DeviceObject
, Irp
, IrpSp
);
895 case IOCTL_AFD_ENUM_NETWORK_EVENTS
:
896 return AfdEnumEvents( DeviceObject
, Irp
, IrpSp
);
898 case IOCTL_AFD_RECV_DATAGRAM
:
899 return AfdPacketSocketReadData( DeviceObject
, Irp
, IrpSp
);
902 return AfdConnectedSocketWriteData( DeviceObject
, Irp
, IrpSp
,
905 case IOCTL_AFD_SEND_DATAGRAM
:
906 return AfdPacketSocketWriteData( DeviceObject
, Irp
, IrpSp
);
908 case IOCTL_AFD_GET_INFO
:
909 return AfdGetInfo( DeviceObject
, Irp
, IrpSp
);
911 case IOCTL_AFD_SET_INFO
:
912 return AfdSetInfo( DeviceObject
, Irp
, IrpSp
);
914 case IOCTL_AFD_GET_CONTEXT_SIZE
:
915 return AfdGetContextSize( DeviceObject
, Irp
, IrpSp
);
917 case IOCTL_AFD_GET_CONTEXT
:
918 return AfdGetContext( DeviceObject
, Irp
, IrpSp
);
920 case IOCTL_AFD_SET_CONTEXT
:
921 return AfdSetContext( DeviceObject
, Irp
, IrpSp
);
923 case IOCTL_AFD_WAIT_FOR_LISTEN
:
924 return AfdWaitForListen( DeviceObject
, Irp
, IrpSp
);
926 case IOCTL_AFD_ACCEPT
:
927 return AfdAccept( DeviceObject
, Irp
, IrpSp
);
929 case IOCTL_AFD_DISCONNECT
:
930 return AfdDisconnect( DeviceObject
, Irp
, IrpSp
);
932 case IOCTL_AFD_GET_SOCK_NAME
:
933 return AfdGetSockName( DeviceObject
, Irp
, IrpSp
);
935 case IOCTL_AFD_GET_PEER_NAME
:
936 return AfdGetPeerName( DeviceObject
, Irp
, IrpSp
);
938 case IOCTL_AFD_GET_CONNECT_DATA
:
939 return AfdGetConnectData(DeviceObject
, Irp
, IrpSp
);
941 case IOCTL_AFD_SET_CONNECT_DATA
:
942 return AfdSetConnectData(DeviceObject
, Irp
, IrpSp
);
944 case IOCTL_AFD_SET_DISCONNECT_DATA
:
945 return AfdSetDisconnectData(DeviceObject
, Irp
, IrpSp
);
947 case IOCTL_AFD_GET_DISCONNECT_DATA
:
948 return AfdGetDisconnectData(DeviceObject
, Irp
, IrpSp
);
950 case IOCTL_AFD_SET_CONNECT_DATA_SIZE
:
951 return AfdSetConnectDataSize(DeviceObject
, Irp
, IrpSp
);
953 case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE
:
954 return AfdSetDisconnectDataSize(DeviceObject
, Irp
, IrpSp
);
956 case IOCTL_AFD_SET_CONNECT_OPTIONS
:
957 return AfdSetConnectOptions(DeviceObject
, Irp
, IrpSp
);
959 case IOCTL_AFD_SET_DISCONNECT_OPTIONS
:
960 return AfdSetDisconnectOptions(DeviceObject
, Irp
, IrpSp
);
962 case IOCTL_AFD_GET_CONNECT_OPTIONS
:
963 return AfdGetConnectOptions(DeviceObject
, Irp
, IrpSp
);
965 case IOCTL_AFD_GET_DISCONNECT_OPTIONS
:
966 return AfdGetDisconnectOptions(DeviceObject
, Irp
, IrpSp
);
968 case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE
:
969 return AfdSetConnectOptionsSize(DeviceObject
, Irp
, IrpSp
);
971 case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE
:
972 return AfdSetDisconnectOptionsSize(DeviceObject
, Irp
, IrpSp
);
974 case IOCTL_AFD_GET_TDI_HANDLES
:
975 return AfdGetTdiHandles(DeviceObject
, Irp
, IrpSp
);
977 case IOCTL_AFD_DEFER_ACCEPT
:
978 DbgPrint("IOCTL_AFD_DEFER_ACCEPT is UNIMPLEMENTED!\n");
981 case IOCTL_AFD_GET_PENDING_CONNECT_DATA
:
982 DbgPrint("IOCTL_AFD_GET_PENDING_CONNECT_DATA is UNIMPLEMENTED!\n");
985 case IOCTL_AFD_VALIDATE_GROUP
:
986 DbgPrint("IOCTL_AFD_VALIDATE_GROUP is UNIMPLEMENTED!\n");
990 Status
= STATUS_NOT_SUPPORTED
;
991 DbgPrint("Unknown IOCTL (0x%x)\n",
992 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
);
998 /* unsupported operations */
1001 Status
= STATUS_NOT_IMPLEMENTED
;
1002 AFD_DbgPrint(MIN_TRACE
,
1003 ("Irp: Unknown Major code was %x\n",
1004 IrpSp
->MajorFunction
));
1009 AFD_DbgPrint(MID_TRACE
, ("Returning %x\n", Status
));
1010 Irp
->IoStatus
.Status
= Status
;
1011 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1016 BOOLEAN
CheckUnlockExtraBuffers(PAFD_FCB FCB
, PIO_STACK_LOCATION IrpSp
)
1018 if (FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
)
1020 if (IrpSp
->MajorFunction
== IRP_MJ_READ
|| IrpSp
->MajorFunction
== IRP_MJ_WRITE
)
1022 /* read()/write() call - no extra buffers */
1025 else if (IrpSp
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
)
1027 if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_RECV_DATAGRAM
)
1029 /* recvfrom() call - extra buffers */
1032 else if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_RECV
)
1034 /* recv() call - no extra buffers */
1037 else if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SEND
||
1038 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SEND_DATAGRAM
)
1040 /* send()/sendto() call - no extra buffers */
1052 /* Unknown IRP_MJ code */
1059 /* Connection-oriented never has extra buffers */
1065 CleanupPendingIrp(PAFD_FCB FCB
, PIRP Irp
, PIO_STACK_LOCATION IrpSp
, PAFD_ACTIVE_POLL Poll
)
1067 PAFD_RECV_INFO RecvReq
;
1068 PAFD_SEND_INFO SendReq
;
1069 PAFD_POLL_INFO PollReq
;
1071 if (IrpSp
->MajorFunction
== IRP_MJ_READ
)
1073 RecvReq
= GetLockedData(Irp
, IrpSp
);
1074 UnlockBuffers(RecvReq
->BufferArray
, RecvReq
->BufferCount
, CheckUnlockExtraBuffers(FCB
, IrpSp
));
1076 else if (IrpSp
->MajorFunction
== IRP_MJ_WRITE
)
1078 SendReq
= GetLockedData(Irp
, IrpSp
);
1079 UnlockBuffers(SendReq
->BufferArray
, SendReq
->BufferCount
, CheckUnlockExtraBuffers(FCB
, IrpSp
));
1083 ASSERT(IrpSp
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
);
1085 if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_RECV
)
1087 RecvReq
= GetLockedData(Irp
, IrpSp
);
1088 UnlockBuffers(RecvReq
->BufferArray
, RecvReq
->BufferCount
, CheckUnlockExtraBuffers(FCB
, IrpSp
));
1090 else if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SEND
)
1092 SendReq
= GetLockedData(Irp
, IrpSp
);
1093 UnlockBuffers(SendReq
->BufferArray
, SendReq
->BufferCount
, CheckUnlockExtraBuffers(FCB
, IrpSp
));
1095 else if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SELECT
)
1099 PollReq
= Irp
->AssociatedIrp
.SystemBuffer
;
1100 ZeroEvents(PollReq
->Handles
, PollReq
->HandleCount
);
1101 SignalSocket(Poll
, NULL
, PollReq
, STATUS_CANCELLED
);
1108 AfdCancelHandler(PDEVICE_OBJECT DeviceObject
,
1111 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1112 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
1113 PAFD_FCB FCB
= FileObject
->FsContext
;
1114 ULONG Function
, IoctlCode
;
1116 PLIST_ENTRY CurrentEntry
;
1117 PAFD_DEVICE_EXTENSION DeviceExt
= DeviceObject
->DeviceExtension
;
1119 PAFD_ACTIVE_POLL Poll
;
1121 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
1123 if (!SocketAcquireStateLock(FCB
))
1126 switch (IrpSp
->MajorFunction
)
1128 case IRP_MJ_DEVICE_CONTROL
:
1129 IoctlCode
= IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
;
1133 IoctlCode
= IOCTL_AFD_RECV
;
1137 IoctlCode
= IOCTL_AFD_SEND
;
1142 SocketStateUnlock(FCB
);
1148 case IOCTL_AFD_RECV
:
1149 case IOCTL_AFD_RECV_DATAGRAM
:
1150 Function
= FUNCTION_RECV
;
1153 case IOCTL_AFD_SEND
:
1154 case IOCTL_AFD_SEND_DATAGRAM
:
1155 Function
= FUNCTION_SEND
;
1158 case IOCTL_AFD_CONNECT
:
1159 Function
= FUNCTION_CONNECT
;
1162 case IOCTL_AFD_WAIT_FOR_LISTEN
:
1163 Function
= FUNCTION_PREACCEPT
;
1166 case IOCTL_AFD_SELECT
:
1167 KeAcquireSpinLock(&DeviceExt
->Lock
, &OldIrql
);
1169 CurrentEntry
= DeviceExt
->Polls
.Flink
;
1170 while (CurrentEntry
!= &DeviceExt
->Polls
)
1172 Poll
= CONTAINING_RECORD(CurrentEntry
, AFD_ACTIVE_POLL
, ListEntry
);
1174 if (Irp
== Poll
->Irp
)
1176 CleanupPendingIrp(FCB
, Irp
, IrpSp
, Poll
);
1177 KeReleaseSpinLock(&DeviceExt
->Lock
, OldIrql
);
1178 SocketStateUnlock(FCB
);
1183 CurrentEntry
= CurrentEntry
->Flink
;
1187 KeReleaseSpinLock(&DeviceExt
->Lock
, OldIrql
);
1189 SocketStateUnlock(FCB
);
1191 DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (IOCTL_AFD_SELECT)\n");
1194 case IOCTL_AFD_DISCONNECT
:
1195 Function
= FUNCTION_DISCONNECT
;
1200 UnlockAndMaybeComplete(FCB
, STATUS_CANCELLED
, Irp
, 0);
1204 CurrentEntry
= FCB
->PendingIrpList
[Function
].Flink
;
1205 while (CurrentEntry
!= &FCB
->PendingIrpList
[Function
])
1207 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
1209 if (CurrentIrp
== Irp
)
1211 RemoveEntryList(CurrentEntry
);
1212 CleanupPendingIrp(FCB
, Irp
, IrpSp
, NULL
);
1213 UnlockAndMaybeComplete(FCB
, STATUS_CANCELLED
, Irp
, 0);
1218 CurrentEntry
= CurrentEntry
->Flink
;
1222 SocketStateUnlock(FCB
);
1224 DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (Function: %u)\n", Function
);
1227 static DRIVER_UNLOAD AfdUnload
;
1229 AfdUnload(PDRIVER_OBJECT DriverObject
)
1231 UNREFERENCED_PARAMETER(DriverObject
);
1235 DriverEntry(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
1237 PDEVICE_OBJECT DeviceObject
;
1238 UNICODE_STRING wstrDeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\Afd");
1239 PAFD_DEVICE_EXTENSION DeviceExt
;
1242 UNREFERENCED_PARAMETER(RegistryPath
);
1243 /* register driver routines */
1244 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = AfdDispatch
;
1245 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = AfdDispatch
;
1246 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = AfdDispatch
;
1247 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = AfdDispatch
;
1248 DriverObject
->MajorFunction
[IRP_MJ_READ
] = AfdDispatch
;
1249 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = AfdDispatch
;
1250 DriverObject
->DriverUnload
= AfdUnload
;
1252 Status
= IoCreateDevice(DriverObject
,
1253 sizeof(AFD_DEVICE_EXTENSION
),
1255 FILE_DEVICE_NAMED_PIPE
,
1261 if (!NT_SUCCESS(Status
))
1266 DeviceExt
= DeviceObject
->DeviceExtension
;
1267 KeInitializeSpinLock( &DeviceExt
->Lock
);
1268 InitializeListHead( &DeviceExt
->Polls
);
1270 AFD_DbgPrint(MID_TRACE
,("Device created: object %p ext %p\n",
1271 DeviceObject
, DeviceExt
));