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 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
51 if (FCB
->DisconnectOptionsSize
== 0)
53 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
54 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
= LockRequest(Irp
, IrpSp
, FALSE
, NULL
);
76 UINT DisconnectOptionsSize
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
78 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
80 if (!DisconnectOptions
)
81 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
83 if (FCB
->DisconnectOptions
)
85 ExFreePool(FCB
->DisconnectOptions
);
86 FCB
->DisconnectOptions
= NULL
;
87 FCB
->DisconnectOptionsSize
= 0;
88 FCB
->FilledDisconnectOptions
= 0;
91 FCB
->DisconnectOptions
= ExAllocatePool(PagedPool
, DisconnectOptionsSize
);
92 if (!FCB
->DisconnectOptions
)
93 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
95 RtlCopyMemory(FCB
->DisconnectOptions
,
97 DisconnectOptionsSize
);
99 FCB
->DisconnectOptionsSize
= DisconnectOptionsSize
;
101 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
106 AfdSetDisconnectOptionsSize(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
107 PIO_STACK_LOCATION IrpSp
)
109 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
110 PAFD_FCB FCB
= FileObject
->FsContext
;
111 PUINT DisconnectOptionsSize
= LockRequest(Irp
, IrpSp
, FALSE
, NULL
);
112 UINT BufferSize
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
114 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
116 if (!DisconnectOptionsSize
)
117 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
119 if (BufferSize
< sizeof(UINT
))
121 AFD_DbgPrint(MIN_TRACE
,("Buffer too small\n"));
122 return UnlockAndMaybeComplete(FCB
, STATUS_BUFFER_TOO_SMALL
, Irp
, 0);
125 if (FCB
->DisconnectOptions
)
127 ExFreePool(FCB
->DisconnectOptions
);
128 FCB
->DisconnectOptionsSize
= 0;
129 FCB
->FilledDisconnectOptions
= 0;
132 FCB
->DisconnectOptions
= ExAllocatePool(PagedPool
, *DisconnectOptionsSize
);
133 if (!FCB
->DisconnectOptions
) return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
135 FCB
->DisconnectOptionsSize
= *DisconnectOptionsSize
;
137 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
141 AfdGetDisconnectData(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
142 PIO_STACK_LOCATION IrpSp
)
144 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
145 PAFD_FCB FCB
= FileObject
->FsContext
;
146 UINT BufferSize
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
148 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
150 if (FCB
->DisconnectDataSize
== 0)
152 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
153 return UnlockAndMaybeComplete(FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0);
156 ASSERT(FCB
->DisconnectData
);
158 if (FCB
->FilledDisconnectData
< BufferSize
)
159 BufferSize
= FCB
->FilledDisconnectData
;
161 RtlCopyMemory(Irp
->UserBuffer
,
165 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, BufferSize
);
170 AfdSetDisconnectData(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
171 PIO_STACK_LOCATION IrpSp
)
173 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
174 PAFD_FCB FCB
= FileObject
->FsContext
;
175 PVOID DisconnectData
= LockRequest(Irp
, IrpSp
, FALSE
, NULL
);
176 UINT DisconnectDataSize
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
178 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
181 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
183 if (FCB
->DisconnectData
)
185 ExFreePool(FCB
->DisconnectData
);
186 FCB
->DisconnectData
= NULL
;
187 FCB
->DisconnectDataSize
= 0;
188 FCB
->FilledDisconnectData
= 0;
191 FCB
->DisconnectData
= ExAllocatePool(PagedPool
, DisconnectDataSize
);
192 if (!FCB
->DisconnectData
)
193 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
195 RtlCopyMemory(FCB
->DisconnectData
,
199 FCB
->DisconnectDataSize
= DisconnectDataSize
;
201 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
206 AfdSetDisconnectDataSize(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
207 PIO_STACK_LOCATION IrpSp
)
209 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
210 PAFD_FCB FCB
= FileObject
->FsContext
;
211 PUINT DisconnectDataSize
= LockRequest(Irp
, IrpSp
, FALSE
, NULL
);
212 UINT BufferSize
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
214 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
216 if (!DisconnectDataSize
)
217 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
219 if (BufferSize
< sizeof(UINT
))
221 AFD_DbgPrint(MIN_TRACE
,("Buffer too small\n"));
222 return UnlockAndMaybeComplete(FCB
, STATUS_BUFFER_TOO_SMALL
, Irp
, 0);
225 if (FCB
->DisconnectData
)
227 ExFreePool(FCB
->DisconnectData
);
228 FCB
->DisconnectDataSize
= 0;
229 FCB
->FilledDisconnectData
= 0;
232 FCB
->DisconnectData
= ExAllocatePool(PagedPool
, *DisconnectDataSize
);
233 if (!FCB
->DisconnectData
)
234 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
236 FCB
->DisconnectDataSize
= *DisconnectDataSize
;
238 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
241 static NTSTATUS NTAPI
242 AfdGetTdiHandles(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
243 PIO_STACK_LOCATION IrpSp
)
245 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
246 PAFD_FCB FCB
= FileObject
->FsContext
;
247 PULONG HandleFlags
= LockRequest(Irp
, IrpSp
, TRUE
, NULL
);
248 PAFD_TDI_HANDLE_DATA HandleData
= Irp
->UserBuffer
;
250 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
253 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
255 if (IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(ULONG
) ||
256 IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(*HandleData
))
258 AFD_DbgPrint(MIN_TRACE
,("Buffer too small\n"));
259 return UnlockAndMaybeComplete(FCB
, STATUS_BUFFER_TOO_SMALL
, Irp
, 0);
262 if ((*HandleFlags
) & AFD_ADDRESS_HANDLE
)
263 HandleData
->TdiAddressHandle
= FCB
->AddressFile
.Handle
;
265 if ((*HandleFlags
) & AFD_CONNECTION_HANDLE
)
266 HandleData
->TdiConnectionHandle
= FCB
->Connection
.Handle
;
268 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
271 static NTSTATUS NTAPI
272 AfdCreateSocket(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
273 PIO_STACK_LOCATION IrpSp
) {
275 PFILE_OBJECT FileObject
;
276 PAFD_DEVICE_EXTENSION DeviceExt
;
277 PFILE_FULL_EA_INFORMATION EaInfo
;
278 PAFD_CREATE_PACKET ConnectInfo
= NULL
;
280 PWCHAR EaInfoValue
= NULL
;
283 NTSTATUS Status
= STATUS_SUCCESS
;
285 AFD_DbgPrint(MID_TRACE
,("AfdCreate(DeviceObject %p Irp %p)\n",
288 DeviceExt
= DeviceObject
->DeviceExtension
;
289 FileObject
= IrpSp
->FileObject
;
290 //Disposition = (IrpSp->Parameters.Create.Options >> 24) & 0xff;
292 Irp
->IoStatus
.Information
= 0;
294 EaInfo
= Irp
->AssociatedIrp
.SystemBuffer
;
297 ConnectInfo
= (PAFD_CREATE_PACKET
)(EaInfo
->EaName
+ EaInfo
->EaNameLength
+ 1);
298 EaInfoValue
= (PWCHAR
)(((PCHAR
)ConnectInfo
) + sizeof(AFD_CREATE_PACKET
));
300 //EaLength = sizeof(FILE_FULL_EA_INFORMATION) + EaInfo->EaNameLength + EaInfo->EaValueLength;
302 AFD_DbgPrint(MID_TRACE
,("EaInfo: %x, EaInfoValue: %x\n",
303 EaInfo
, EaInfoValue
));
306 AFD_DbgPrint(MID_TRACE
,("About to allocate the new FCB\n"));
308 FCB
= ExAllocatePool(NonPagedPool
, sizeof(AFD_FCB
));
310 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
311 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
312 return STATUS_NO_MEMORY
;
315 AFD_DbgPrint(MID_TRACE
,("Initializing the new FCB @ %x (FileObject %x Flags %x)\n",
316 FCB
, FileObject
, ConnectInfo
? ConnectInfo
->EndpointFlags
: 0));
318 RtlZeroMemory( FCB
, sizeof( *FCB
) );
320 FCB
->Flags
= ConnectInfo
? ConnectInfo
->EndpointFlags
: 0;
321 FCB
->GroupID
= ConnectInfo
? ConnectInfo
->GroupID
: 0;
322 FCB
->GroupType
= 0; /* FIXME */
323 FCB
->State
= SOCKET_STATE_CREATED
;
324 FCB
->FileObject
= FileObject
;
325 FCB
->DeviceExt
= DeviceExt
;
326 FCB
->AddressFile
.Handle
= INVALID_HANDLE_VALUE
;
327 FCB
->Connection
.Handle
= INVALID_HANDLE_VALUE
;
329 KeInitializeMutex( &FCB
->Mutex
, 0 );
331 for( i
= 0; i
< MAX_FUNCTIONS
; i
++ ) {
332 InitializeListHead( &FCB
->PendingIrpList
[i
] );
335 InitializeListHead( &FCB
->DatagramList
);
336 InitializeListHead( &FCB
->PendingConnections
);
338 AFD_DbgPrint(MID_TRACE
,("%x: Checking command channel\n", FCB
));
341 FCB
->TdiDeviceName
.Length
= ConnectInfo
->SizeOfTransportName
;
342 FCB
->TdiDeviceName
.MaximumLength
= FCB
->TdiDeviceName
.Length
;
343 FCB
->TdiDeviceName
.Buffer
=
344 ExAllocatePool( NonPagedPool
, FCB
->TdiDeviceName
.Length
);
346 if( !FCB
->TdiDeviceName
.Buffer
) {
348 AFD_DbgPrint(MID_TRACE
,("Could not copy target string\n"));
349 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
350 IoCompleteRequest( Irp
, IO_NETWORK_INCREMENT
);
351 return STATUS_NO_MEMORY
;
354 RtlCopyMemory( FCB
->TdiDeviceName
.Buffer
,
355 ConnectInfo
->TransportName
,
356 FCB
->TdiDeviceName
.Length
);
358 AFD_DbgPrint(MID_TRACE
,("Success: %s %wZ\n",
359 EaInfo
->EaName
, &FCB
->TdiDeviceName
));
361 AFD_DbgPrint(MID_TRACE
,("Success: Control connection\n"));
364 FileObject
->FsContext
= FCB
;
366 /* It seems that UDP sockets are writable from inception */
367 if( FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
) {
368 AFD_DbgPrint(MID_TRACE
,("Packet oriented socket\n"));
370 /* A datagram socket is always sendable */
371 FCB
->PollState
|= AFD_EVENT_SEND
;
372 FCB
->PollStatus
[FD_WRITE_BIT
] = STATUS_SUCCESS
;
373 PollReeval( FCB
->DeviceExt
, FCB
->FileObject
);
376 if( !NT_SUCCESS(Status
) ) {
377 if( FCB
->TdiDeviceName
.Buffer
) ExFreePool( FCB
->TdiDeviceName
.Buffer
);
379 FileObject
->FsContext
= NULL
;
382 Irp
->IoStatus
.Status
= Status
;
383 IoCompleteRequest( Irp
, IO_NETWORK_INCREMENT
);
388 static NTSTATUS NTAPI
389 AfdCleanupSocket(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
390 PIO_STACK_LOCATION IrpSp
)
392 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
393 PAFD_FCB FCB
= FileObject
->FsContext
;
394 PLIST_ENTRY CurrentEntry
, NextEntry
;
398 if( !SocketAcquireStateLock( FCB
) ) return LostSocket(Irp
);
400 for (Function
= 0; Function
< MAX_FUNCTIONS
; Function
++)
402 CurrentEntry
= FCB
->PendingIrpList
[Function
].Flink
;
403 while (CurrentEntry
!= &FCB
->PendingIrpList
[Function
])
405 NextEntry
= CurrentEntry
->Flink
;
406 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
408 /* The cancel routine will remove the IRP from the list */
409 IoCancelIrp(CurrentIrp
);
411 CurrentEntry
= NextEntry
;
415 KillSelectsForFCB( FCB
->DeviceExt
, FileObject
, FALSE
);
417 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
420 static NTSTATUS NTAPI
421 AfdCloseSocket(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
422 PIO_STACK_LOCATION IrpSp
)
424 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
425 PAFD_FCB FCB
= FileObject
->FsContext
;
427 PAFD_IN_FLIGHT_REQUEST InFlightRequest
[IN_FLIGHT_REQUESTS
];
428 PAFD_TDI_OBJECT_QELT Qelt
;
429 PLIST_ENTRY QeltEntry
;
432 AFD_DbgPrint(MID_TRACE
,("AfdClose(DeviceObject %p Irp %p)\n",
435 if( !SocketAcquireStateLock( FCB
) ) return STATUS_FILE_CLOSED
;
437 FCB
->State
= SOCKET_STATE_CLOSED
;
439 InFlightRequest
[0] = &FCB
->ListenIrp
;
440 InFlightRequest
[1] = &FCB
->ReceiveIrp
;
441 InFlightRequest
[2] = &FCB
->SendIrp
;
442 InFlightRequest
[3] = &FCB
->ConnectIrp
;
443 InFlightRequest
[4] = &FCB
->DisconnectIrp
;
445 /* Cancel our pending requests */
446 for( i
= 0; i
< IN_FLIGHT_REQUESTS
; i
++ ) {
447 if( InFlightRequest
[i
]->InFlightRequest
) {
448 AFD_DbgPrint(MID_TRACE
,("Cancelling in flight irp %d (%x)\n",
449 i
, InFlightRequest
[i
]->InFlightRequest
));
450 IoCancelIrp(InFlightRequest
[i
]->InFlightRequest
);
454 KillSelectsForFCB( FCB
->DeviceExt
, FileObject
, FALSE
);
456 ASSERT(IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_CONNECT
]));
457 ASSERT(IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]));
458 ASSERT(IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_RECV
]));
459 ASSERT(IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_PREACCEPT
]));
460 ASSERT(IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]));
462 while (!IsListEmpty(&FCB
->PendingConnections
))
464 QeltEntry
= RemoveHeadList(&FCB
->PendingConnections
);
465 Qelt
= CONTAINING_RECORD(QeltEntry
, AFD_TDI_OBJECT_QELT
, ListEntry
);
467 /* We have to close all pending connections or the listen won't get closed */
468 TdiDisassociateAddressFile(Qelt
->Object
.Object
);
469 ObDereferenceObject(Qelt
->Object
.Object
);
470 ZwClose(Qelt
->Object
.Handle
);
475 SocketStateUnlock( FCB
);
477 if( FCB
->EventSelect
)
478 ObDereferenceObject( FCB
->EventSelect
);
481 ExFreePool( FCB
->Context
);
483 if( FCB
->Recv
.Window
)
484 ExFreePool( FCB
->Recv
.Window
);
486 if( FCB
->Send
.Window
)
487 ExFreePool( FCB
->Send
.Window
);
489 if( FCB
->AddressFrom
)
490 ExFreePool( FCB
->AddressFrom
);
492 if( FCB
->ConnectCallInfo
)
493 ExFreePool( FCB
->ConnectCallInfo
);
495 if( FCB
->ConnectReturnInfo
)
496 ExFreePool( FCB
->ConnectReturnInfo
);
498 if( FCB
->ConnectData
)
499 ExFreePool( FCB
->ConnectData
);
501 if( FCB
->DisconnectData
)
502 ExFreePool( FCB
->DisconnectData
);
504 if( FCB
->ConnectOptions
)
505 ExFreePool( FCB
->ConnectOptions
);
507 if( FCB
->DisconnectOptions
)
508 ExFreePool( FCB
->DisconnectOptions
);
510 if( FCB
->LocalAddress
)
511 ExFreePool( FCB
->LocalAddress
);
513 if( FCB
->RemoteAddress
)
514 ExFreePool( FCB
->RemoteAddress
);
516 if( FCB
->Connection
.Object
)
518 TdiDisassociateAddressFile(FCB
->Connection
.Object
);
519 ObDereferenceObject(FCB
->Connection
.Object
);
522 if( FCB
->AddressFile
.Object
)
523 ObDereferenceObject(FCB
->AddressFile
.Object
);
525 if( FCB
->AddressFile
.Handle
!= INVALID_HANDLE_VALUE
)
527 if (ZwClose(FCB
->AddressFile
.Handle
) == STATUS_INVALID_HANDLE
)
529 DbgPrint("INVALID ADDRESS FILE HANDLE VALUE: %x %x\n", FCB
->AddressFile
.Handle
, FCB
->AddressFile
.Object
);
533 if( FCB
->Connection
.Handle
!= INVALID_HANDLE_VALUE
)
535 if (ZwClose(FCB
->Connection
.Handle
) == STATUS_INVALID_HANDLE
)
537 DbgPrint("INVALID CONNECTION HANDLE VALUE: %x %x\n", FCB
->Connection
.Handle
, FCB
->Connection
.Object
);
541 if( FCB
->TdiDeviceName
.Buffer
)
542 ExFreePool(FCB
->TdiDeviceName
.Buffer
);
546 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
547 Irp
->IoStatus
.Information
= 0;
548 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
550 AFD_DbgPrint(MID_TRACE
, ("Returning success.\n"));
552 return STATUS_SUCCESS
;
558 DisconnectComplete(PDEVICE_OBJECT DeviceObject
,
562 PAFD_FCB FCB
= Context
;
564 PLIST_ENTRY CurrentEntry
;
566 if (!SocketAcquireStateLock(FCB
))
567 return STATUS_FILE_CLOSED
;
569 ASSERT(FCB
->DisconnectIrp
.InFlightRequest
== Irp
);
570 FCB
->DisconnectIrp
.InFlightRequest
= NULL
;
572 ASSERT(FCB
->DisconnectPending
);
573 ASSERT((IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]) && !FCB
->SendIrp
.InFlightRequest
) ||
574 (FCB
->DisconnectFlags
& TDI_DISCONNECT_ABORT
));
576 if (NT_SUCCESS(Irp
->IoStatus
.Status
) && (FCB
->DisconnectFlags
& TDI_DISCONNECT_RELEASE
))
578 FCB
->FilledDisconnectData
= MIN(FCB
->DisconnectDataSize
, FCB
->ConnectReturnInfo
->UserDataLength
);
579 if (FCB
->FilledDisconnectData
)
581 RtlCopyMemory(FCB
->DisconnectData
,
582 FCB
->ConnectReturnInfo
->UserData
,
583 FCB
->FilledDisconnectData
);
586 FCB
->FilledDisconnectOptions
= MIN(FCB
->DisconnectOptionsSize
, FCB
->ConnectReturnInfo
->OptionsLength
);
587 if (FCB
->FilledDisconnectOptions
)
589 RtlCopyMemory(FCB
->DisconnectOptions
,
590 FCB
->ConnectReturnInfo
->Options
,
591 FCB
->FilledDisconnectOptions
);
595 FCB
->DisconnectPending
= FALSE
;
597 while (!IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]))
599 CurrentEntry
= RemoveHeadList(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]);
600 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
601 CurrentIrp
->IoStatus
.Status
= Irp
->IoStatus
.Status
;
602 CurrentIrp
->IoStatus
.Information
= 0;
603 UnlockRequest(CurrentIrp
, IoGetCurrentIrpStackLocation(CurrentIrp
));
604 (void)IoSetCancelRoutine(CurrentIrp
, NULL
);
605 IoCompleteRequest(CurrentIrp
, IO_NETWORK_INCREMENT
);
608 if (!(FCB
->DisconnectFlags
& TDI_DISCONNECT_RELEASE
))
610 /* Signal complete connection closure immediately */
611 FCB
->PollState
|= AFD_EVENT_ABORT
;
612 FCB
->PollStatus
[FD_CLOSE_BIT
] = Irp
->IoStatus
.Status
;
613 FCB
->LastReceiveStatus
= STATUS_FILE_CLOSED
;
614 PollReeval(FCB
->DeviceExt
, FCB
->FileObject
);
617 SocketStateUnlock(FCB
);
619 return Irp
->IoStatus
.Status
;
624 DoDisconnect(PAFD_FCB FCB
)
628 ASSERT(FCB
->DisconnectPending
);
629 ASSERT((IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]) && !FCB
->SendIrp
.InFlightRequest
) ||
630 (FCB
->DisconnectFlags
& TDI_DISCONNECT_ABORT
));
632 if (FCB
->DisconnectIrp
.InFlightRequest
)
634 return STATUS_PENDING
;
637 FCB
->ConnectCallInfo
->UserData
= FCB
->DisconnectData
;
638 FCB
->ConnectCallInfo
->UserDataLength
= FCB
->DisconnectDataSize
;
639 FCB
->ConnectCallInfo
->Options
= FCB
->DisconnectOptions
;
640 FCB
->ConnectCallInfo
->OptionsLength
= FCB
->DisconnectOptionsSize
;
642 Status
= TdiDisconnect(&FCB
->DisconnectIrp
.InFlightRequest
,
643 FCB
->Connection
.Object
,
644 &FCB
->DisconnectTimeout
,
645 FCB
->DisconnectFlags
,
646 &FCB
->DisconnectIrp
.Iosb
,
649 FCB
->ConnectCallInfo
,
650 FCB
->ConnectReturnInfo
);
651 if (Status
!= STATUS_PENDING
)
653 FCB
->DisconnectPending
= FALSE
;
660 RetryDisconnectCompletion(PAFD_FCB FCB
)
662 ASSERT(FCB
->RemoteAddress
);
664 if (IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]) && !FCB
->SendIrp
.InFlightRequest
&& FCB
->DisconnectPending
)
666 /* Sends are done; fire off a TDI_DISCONNECT request */
671 static NTSTATUS NTAPI
672 AfdDisconnect(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
673 PIO_STACK_LOCATION IrpSp
) {
674 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
675 PAFD_FCB FCB
= FileObject
->FsContext
;
676 PAFD_DISCONNECT_INFO DisReq
;
677 NTSTATUS Status
= STATUS_SUCCESS
;
679 PLIST_ENTRY CurrentEntry
;
682 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
684 if (!(DisReq
= LockRequest(Irp
, IrpSp
, FALSE
, NULL
)))
685 return UnlockAndMaybeComplete( FCB
, STATUS_NO_MEMORY
,
688 /* Send direction only */
689 if ((DisReq
->DisconnectType
& AFD_DISCONNECT_SEND
) &&
690 !(DisReq
->DisconnectType
& AFD_DISCONNECT_RECV
))
692 /* Perform a controlled disconnect */
693 Flags
= TDI_DISCONNECT_RELEASE
;
695 /* Receive direction or both */
698 /* Mark that we can't issue another receive request */
699 FCB
->TdiReceiveClosed
= TRUE
;
701 /* Try to cancel a pending TDI receive IRP if there was one in progress */
702 if (FCB
->ReceiveIrp
.InFlightRequest
)
703 IoCancelIrp(FCB
->ReceiveIrp
.InFlightRequest
);
705 /* Discard any pending data */
706 FCB
->Recv
.Content
= 0;
707 FCB
->Recv
.BytesUsed
= 0;
709 /* Mark us as overread to complete future reads with an error */
710 FCB
->Overread
= TRUE
;
712 /* Set a successful receive status to indicate a shutdown on overread */
713 FCB
->LastReceiveStatus
= STATUS_SUCCESS
;
715 /* Clear the receive event */
716 FCB
->PollState
&= ~AFD_EVENT_RECEIVE
;
718 /* Receive direction only */
719 if ((DisReq
->DisconnectType
& AFD_DISCONNECT_RECV
) &&
720 !(DisReq
->DisconnectType
& AFD_DISCONNECT_SEND
))
722 /* No need to tell the transport driver for receive direction only */
723 return UnlockAndMaybeComplete( FCB
, STATUS_SUCCESS
, Irp
, 0 );
727 /* Perform an abortive disconnect */
728 Flags
= TDI_DISCONNECT_ABORT
;
732 if (!(FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
))
734 if (!FCB
->ConnectCallInfo
)
736 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
737 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
,
741 if (FCB
->DisconnectPending
)
743 if (FCB
->DisconnectIrp
.InFlightRequest
)
745 IoCancelIrp(FCB
->DisconnectIrp
.InFlightRequest
);
746 ASSERT(!FCB
->DisconnectIrp
.InFlightRequest
);
750 while (!IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]))
752 CurrentEntry
= RemoveHeadList(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]);
753 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
754 CurrentIrp
->IoStatus
.Status
= STATUS_CANCELLED
;
755 CurrentIrp
->IoStatus
.Information
= 0;
756 UnlockRequest(CurrentIrp
, IoGetCurrentIrpStackLocation(CurrentIrp
));
757 (void)IoSetCancelRoutine(CurrentIrp
, NULL
);
758 IoCompleteRequest(CurrentIrp
, IO_NETWORK_INCREMENT
);
763 FCB
->DisconnectFlags
= Flags
;
764 FCB
->DisconnectTimeout
= DisReq
->Timeout
;
765 FCB
->DisconnectPending
= TRUE
;
766 FCB
->SendClosed
= TRUE
;
767 FCB
->PollState
&= ~AFD_EVENT_SEND
;
769 Status
= QueueUserModeIrp(FCB
, Irp
, FUNCTION_DISCONNECT
);
770 if (Status
== STATUS_PENDING
)
772 if ((IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]) && !FCB
->SendIrp
.InFlightRequest
) ||
773 (FCB
->DisconnectFlags
& TDI_DISCONNECT_ABORT
))
775 /* Go ahead and execute the disconnect because we're ready for it */
776 Status
= DoDisconnect(FCB
);
779 if (Status
!= STATUS_PENDING
)
780 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
783 if (Status
== STATUS_PENDING
)
785 SocketStateUnlock(FCB
);
792 if (!(Flags
& TDI_DISCONNECT_RELEASE
))
794 if (!FCB
->RemoteAddress
)
796 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
797 return UnlockAndMaybeComplete(FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0);
800 ExFreePool(FCB
->RemoteAddress
);
802 FCB
->RemoteAddress
= NULL
;
805 FCB
->PollState
&= ~AFD_EVENT_SEND
;
806 FCB
->SendClosed
= TRUE
;
809 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );
812 static NTSTATUS NTAPI
813 AfdDispatch(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
815 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
816 NTSTATUS Status
= STATUS_NOT_IMPLEMENTED
;
818 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
821 AFD_DbgPrint(MID_TRACE
,("AfdDispatch: %d\n", IrpSp
->MajorFunction
));
822 if( IrpSp
->MajorFunction
!= IRP_MJ_CREATE
) {
823 AFD_DbgPrint(MID_TRACE
,("FO %x, IrpSp->FO %x\n",
824 FileObject
, IrpSp
->FileObject
));
825 ASSERT(FileObject
== IrpSp
->FileObject
);
828 Irp
->IoStatus
.Information
= 0;
830 switch(IrpSp
->MajorFunction
)
832 /* opening and closing handles to the device */
834 /* Mostly borrowed from the named pipe file system */
835 return AfdCreateSocket(DeviceObject
, Irp
, IrpSp
);
838 /* Ditto the borrowing */
839 return AfdCloseSocket(DeviceObject
, Irp
, IrpSp
);
842 return AfdCleanupSocket(DeviceObject
, Irp
, IrpSp
);
846 return AfdConnectedSocketWriteData( DeviceObject
, Irp
, IrpSp
, TRUE
);
850 return AfdConnectedSocketReadData( DeviceObject
, Irp
, IrpSp
, TRUE
);
852 case IRP_MJ_DEVICE_CONTROL
:
854 switch( IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
856 return AfdBindSocket( DeviceObject
, Irp
, IrpSp
);
858 case IOCTL_AFD_CONNECT
:
859 return AfdStreamSocketConnect( DeviceObject
, Irp
, IrpSp
);
861 case IOCTL_AFD_START_LISTEN
:
862 return AfdListenSocket( DeviceObject
, Irp
, IrpSp
);
865 return AfdConnectedSocketReadData( DeviceObject
, Irp
, IrpSp
,
868 case IOCTL_AFD_SELECT
:
869 return AfdSelect( DeviceObject
, Irp
, IrpSp
);
871 case IOCTL_AFD_EVENT_SELECT
:
872 return AfdEventSelect( DeviceObject
, Irp
, IrpSp
);
874 case IOCTL_AFD_ENUM_NETWORK_EVENTS
:
875 return AfdEnumEvents( DeviceObject
, Irp
, IrpSp
);
877 case IOCTL_AFD_RECV_DATAGRAM
:
878 return AfdPacketSocketReadData( DeviceObject
, Irp
, IrpSp
);
881 return AfdConnectedSocketWriteData( DeviceObject
, Irp
, IrpSp
,
884 case IOCTL_AFD_SEND_DATAGRAM
:
885 return AfdPacketSocketWriteData( DeviceObject
, Irp
, IrpSp
);
887 case IOCTL_AFD_GET_INFO
:
888 return AfdGetInfo( DeviceObject
, Irp
, IrpSp
);
890 case IOCTL_AFD_SET_INFO
:
891 return AfdSetInfo( DeviceObject
, Irp
, IrpSp
);
893 case IOCTL_AFD_GET_CONTEXT_SIZE
:
894 return AfdGetContextSize( DeviceObject
, Irp
, IrpSp
);
896 case IOCTL_AFD_GET_CONTEXT
:
897 return AfdGetContext( DeviceObject
, Irp
, IrpSp
);
899 case IOCTL_AFD_SET_CONTEXT
:
900 return AfdSetContext( DeviceObject
, Irp
, IrpSp
);
902 case IOCTL_AFD_WAIT_FOR_LISTEN
:
903 return AfdWaitForListen( DeviceObject
, Irp
, IrpSp
);
905 case IOCTL_AFD_ACCEPT
:
906 return AfdAccept( DeviceObject
, Irp
, IrpSp
);
908 case IOCTL_AFD_DISCONNECT
:
909 return AfdDisconnect( DeviceObject
, Irp
, IrpSp
);
911 case IOCTL_AFD_GET_SOCK_NAME
:
912 return AfdGetSockName( DeviceObject
, Irp
, IrpSp
);
914 case IOCTL_AFD_GET_PEER_NAME
:
915 return AfdGetPeerName( DeviceObject
, Irp
, IrpSp
);
917 case IOCTL_AFD_GET_CONNECT_DATA
:
918 return AfdGetConnectData(DeviceObject
, Irp
, IrpSp
);
920 case IOCTL_AFD_SET_CONNECT_DATA
:
921 return AfdSetConnectData(DeviceObject
, Irp
, IrpSp
);
923 case IOCTL_AFD_SET_DISCONNECT_DATA
:
924 return AfdSetDisconnectData(DeviceObject
, Irp
, IrpSp
);
926 case IOCTL_AFD_GET_DISCONNECT_DATA
:
927 return AfdGetDisconnectData(DeviceObject
, Irp
, IrpSp
);
929 case IOCTL_AFD_SET_CONNECT_DATA_SIZE
:
930 return AfdSetConnectDataSize(DeviceObject
, Irp
, IrpSp
);
932 case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE
:
933 return AfdSetDisconnectDataSize(DeviceObject
, Irp
, IrpSp
);
935 case IOCTL_AFD_SET_CONNECT_OPTIONS
:
936 return AfdSetConnectOptions(DeviceObject
, Irp
, IrpSp
);
938 case IOCTL_AFD_SET_DISCONNECT_OPTIONS
:
939 return AfdSetDisconnectOptions(DeviceObject
, Irp
, IrpSp
);
941 case IOCTL_AFD_GET_CONNECT_OPTIONS
:
942 return AfdGetConnectOptions(DeviceObject
, Irp
, IrpSp
);
944 case IOCTL_AFD_GET_DISCONNECT_OPTIONS
:
945 return AfdGetDisconnectOptions(DeviceObject
, Irp
, IrpSp
);
947 case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE
:
948 return AfdSetConnectOptionsSize(DeviceObject
, Irp
, IrpSp
);
950 case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE
:
951 return AfdSetDisconnectOptionsSize(DeviceObject
, Irp
, IrpSp
);
953 case IOCTL_AFD_GET_TDI_HANDLES
:
954 return AfdGetTdiHandles(DeviceObject
, Irp
, IrpSp
);
956 case IOCTL_AFD_DEFER_ACCEPT
:
957 DbgPrint("IOCTL_AFD_DEFER_ACCEPT is UNIMPLEMENTED!\n");
960 case IOCTL_AFD_GET_PENDING_CONNECT_DATA
:
961 DbgPrint("IOCTL_AFD_GET_PENDING_CONNECT_DATA is UNIMPLEMENTED!\n");
964 case IOCTL_AFD_VALIDATE_GROUP
:
965 DbgPrint("IOCTL_AFD_VALIDATE_GROUP is UNIMPLEMENTED!\n");
969 Status
= STATUS_NOT_SUPPORTED
;
970 DbgPrint("Unknown IOCTL (0x%x)\n",
971 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
);
977 /* unsupported operations */
980 Status
= STATUS_NOT_IMPLEMENTED
;
981 AFD_DbgPrint(MIN_TRACE
,
982 ("Irp: Unknown Major code was %x\n",
983 IrpSp
->MajorFunction
));
988 AFD_DbgPrint(MID_TRACE
, ("Returning %x\n", Status
));
989 Irp
->IoStatus
.Status
= Status
;
990 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
995 BOOLEAN
CheckUnlockExtraBuffers(PAFD_FCB FCB
, PIO_STACK_LOCATION IrpSp
)
997 if (FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
)
999 if (IrpSp
->MajorFunction
== IRP_MJ_READ
|| IrpSp
->MajorFunction
== IRP_MJ_WRITE
)
1001 /* read()/write() call - no extra buffers */
1004 else if (IrpSp
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
)
1006 if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_RECV_DATAGRAM
)
1008 /* recvfrom() call - extra buffers */
1011 else if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_RECV
)
1013 /* recv() call - no extra buffers */
1016 else if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SEND
||
1017 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SEND_DATAGRAM
)
1019 /* send()/sendto() call - no extra buffers */
1031 /* Unknown IRP_MJ code */
1038 /* Connection-oriented never has extra buffers */
1044 CleanupPendingIrp(PAFD_FCB FCB
, PIRP Irp
, PIO_STACK_LOCATION IrpSp
, PAFD_ACTIVE_POLL Poll
)
1046 PAFD_RECV_INFO RecvReq
;
1047 PAFD_SEND_INFO SendReq
;
1048 PAFD_POLL_INFO PollReq
;
1050 if (IrpSp
->MajorFunction
== IRP_MJ_READ
)
1052 RecvReq
= GetLockedData(Irp
, IrpSp
);
1053 UnlockBuffers(RecvReq
->BufferArray
, RecvReq
->BufferCount
, CheckUnlockExtraBuffers(FCB
, IrpSp
));
1055 else if (IrpSp
->MajorFunction
== IRP_MJ_WRITE
)
1057 SendReq
= GetLockedData(Irp
, IrpSp
);
1058 UnlockBuffers(SendReq
->BufferArray
, SendReq
->BufferCount
, CheckUnlockExtraBuffers(FCB
, IrpSp
));
1062 ASSERT(IrpSp
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
);
1064 if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_RECV
)
1066 RecvReq
= GetLockedData(Irp
, IrpSp
);
1067 UnlockBuffers(RecvReq
->BufferArray
, RecvReq
->BufferCount
, CheckUnlockExtraBuffers(FCB
, IrpSp
));
1069 else if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SEND
)
1071 SendReq
= GetLockedData(Irp
, IrpSp
);
1072 UnlockBuffers(SendReq
->BufferArray
, SendReq
->BufferCount
, CheckUnlockExtraBuffers(FCB
, IrpSp
));
1074 else if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SELECT
)
1078 PollReq
= Irp
->AssociatedIrp
.SystemBuffer
;
1079 ZeroEvents(PollReq
->Handles
, PollReq
->HandleCount
);
1080 SignalSocket(Poll
, NULL
, PollReq
, STATUS_CANCELLED
);
1086 AfdCancelHandler(PDEVICE_OBJECT DeviceObject
,
1089 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1090 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
1091 PAFD_FCB FCB
= FileObject
->FsContext
;
1092 ULONG Function
, IoctlCode
;
1094 PLIST_ENTRY CurrentEntry
;
1095 PAFD_DEVICE_EXTENSION DeviceExt
= DeviceObject
->DeviceExtension
;
1097 PAFD_ACTIVE_POLL Poll
;
1099 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
1101 if (!SocketAcquireStateLock(FCB
))
1104 switch (IrpSp
->MajorFunction
)
1106 case IRP_MJ_DEVICE_CONTROL
:
1107 IoctlCode
= IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
;
1111 IoctlCode
= IOCTL_AFD_RECV
;
1115 IoctlCode
= IOCTL_AFD_SEND
;
1120 SocketStateUnlock(FCB
);
1126 case IOCTL_AFD_RECV
:
1127 case IOCTL_AFD_RECV_DATAGRAM
:
1128 Function
= FUNCTION_RECV
;
1131 case IOCTL_AFD_SEND
:
1132 case IOCTL_AFD_SEND_DATAGRAM
:
1133 Function
= FUNCTION_SEND
;
1136 case IOCTL_AFD_CONNECT
:
1137 Function
= FUNCTION_CONNECT
;
1140 case IOCTL_AFD_WAIT_FOR_LISTEN
:
1141 Function
= FUNCTION_PREACCEPT
;
1144 case IOCTL_AFD_SELECT
:
1145 KeAcquireSpinLock(&DeviceExt
->Lock
, &OldIrql
);
1147 CurrentEntry
= DeviceExt
->Polls
.Flink
;
1148 while (CurrentEntry
!= &DeviceExt
->Polls
)
1150 Poll
= CONTAINING_RECORD(CurrentEntry
, AFD_ACTIVE_POLL
, ListEntry
);
1152 if (Irp
== Poll
->Irp
)
1154 CleanupPendingIrp(FCB
, Irp
, IrpSp
, Poll
);
1155 KeReleaseSpinLock(&DeviceExt
->Lock
, OldIrql
);
1156 SocketStateUnlock(FCB
);
1161 CurrentEntry
= CurrentEntry
->Flink
;
1165 KeReleaseSpinLock(&DeviceExt
->Lock
, OldIrql
);
1167 SocketStateUnlock(FCB
);
1169 DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (IOCTL_AFD_SELECT)\n");
1172 case IOCTL_AFD_DISCONNECT
:
1173 Function
= FUNCTION_DISCONNECT
;
1178 UnlockAndMaybeComplete(FCB
, STATUS_CANCELLED
, Irp
, 0);
1182 CurrentEntry
= FCB
->PendingIrpList
[Function
].Flink
;
1183 while (CurrentEntry
!= &FCB
->PendingIrpList
[Function
])
1185 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
1187 if (CurrentIrp
== Irp
)
1189 RemoveEntryList(CurrentEntry
);
1190 CleanupPendingIrp(FCB
, Irp
, IrpSp
, NULL
);
1191 UnlockAndMaybeComplete(FCB
, STATUS_CANCELLED
, Irp
, 0);
1196 CurrentEntry
= CurrentEntry
->Flink
;
1200 SocketStateUnlock(FCB
);
1202 DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (Function: %d)\n", Function
);
1206 AfdUnload(PDRIVER_OBJECT DriverObject
)
1211 DriverEntry(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
1213 PDEVICE_OBJECT DeviceObject
;
1214 UNICODE_STRING wstrDeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\Afd");
1215 PAFD_DEVICE_EXTENSION DeviceExt
;
1218 /* register driver routines */
1219 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = AfdDispatch
;
1220 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = AfdDispatch
;
1221 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = AfdDispatch
;
1222 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = AfdDispatch
;
1223 DriverObject
->MajorFunction
[IRP_MJ_READ
] = AfdDispatch
;
1224 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = AfdDispatch
;
1225 DriverObject
->DriverUnload
= AfdUnload
;
1227 Status
= IoCreateDevice(DriverObject
,
1228 sizeof(AFD_DEVICE_EXTENSION
),
1230 FILE_DEVICE_NAMED_PIPE
,
1236 if (!NT_SUCCESS(Status
))
1241 DeviceExt
= DeviceObject
->DeviceExtension
;
1242 KeInitializeSpinLock( &DeviceExt
->Lock
);
1243 InitializeListHead( &DeviceExt
->Polls
);
1245 AFD_DbgPrint(MID_TRACE
,("Device created: object %x ext %x\n",
1246 DeviceObject
, DeviceExt
));