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
);
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
) return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
94 RtlCopyMemory(FCB
->DisconnectOptions
,
96 DisconnectOptionsSize
);
98 FCB
->DisconnectOptionsSize
= DisconnectOptionsSize
;
100 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
105 AfdSetDisconnectOptionsSize(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
106 PIO_STACK_LOCATION IrpSp
)
108 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
109 PAFD_FCB FCB
= FileObject
->FsContext
;
110 PUINT DisconnectOptionsSize
= LockRequest(Irp
, IrpSp
);
111 UINT BufferSize
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
113 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
115 if (!DisconnectOptionsSize
)
116 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
118 if (BufferSize
< sizeof(UINT
))
120 AFD_DbgPrint(MIN_TRACE
,("Buffer too small\n"));
121 return UnlockAndMaybeComplete(FCB
, STATUS_BUFFER_TOO_SMALL
, Irp
, 0);
124 if (FCB
->DisconnectOptions
)
126 ExFreePool(FCB
->DisconnectOptions
);
127 FCB
->DisconnectOptionsSize
= 0;
128 FCB
->FilledDisconnectOptions
= 0;
131 FCB
->DisconnectOptions
= ExAllocatePool(PagedPool
, *DisconnectOptionsSize
);
132 if (!FCB
->DisconnectOptions
) return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
134 FCB
->DisconnectOptionsSize
= *DisconnectOptionsSize
;
136 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
140 AfdGetDisconnectData(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
141 PIO_STACK_LOCATION IrpSp
)
143 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
144 PAFD_FCB FCB
= FileObject
->FsContext
;
145 UINT BufferSize
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
147 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
149 if (FCB
->DisconnectDataSize
== 0)
151 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
152 return UnlockAndMaybeComplete(FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0);
155 ASSERT(FCB
->DisconnectData
);
157 if (FCB
->FilledDisconnectData
< BufferSize
) BufferSize
= FCB
->FilledDisconnectData
;
159 RtlCopyMemory(Irp
->UserBuffer
,
163 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, BufferSize
);
168 AfdSetDisconnectData(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
169 PIO_STACK_LOCATION IrpSp
)
171 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
172 PAFD_FCB FCB
= FileObject
->FsContext
;
173 PVOID DisconnectData
= LockRequest(Irp
, IrpSp
);
174 UINT DisconnectDataSize
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
176 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
179 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
181 if (FCB
->DisconnectData
)
183 ExFreePool(FCB
->DisconnectData
);
184 FCB
->DisconnectData
= NULL
;
185 FCB
->DisconnectDataSize
= 0;
186 FCB
->FilledDisconnectData
= 0;
189 FCB
->DisconnectData
= ExAllocatePool(PagedPool
, DisconnectDataSize
);
190 if (!FCB
->DisconnectData
) return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
192 RtlCopyMemory(FCB
->DisconnectData
,
196 FCB
->DisconnectDataSize
= DisconnectDataSize
;
198 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
203 AfdSetDisconnectDataSize(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
204 PIO_STACK_LOCATION IrpSp
)
206 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
207 PAFD_FCB FCB
= FileObject
->FsContext
;
208 PUINT DisconnectDataSize
= LockRequest(Irp
, IrpSp
);
209 UINT BufferSize
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
211 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
213 if (!DisconnectDataSize
)
214 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
216 if (BufferSize
< sizeof(UINT
))
218 AFD_DbgPrint(MIN_TRACE
,("Buffer too small\n"));
219 return UnlockAndMaybeComplete(FCB
, STATUS_BUFFER_TOO_SMALL
, Irp
, 0);
222 if (FCB
->DisconnectData
)
224 ExFreePool(FCB
->DisconnectData
);
225 FCB
->DisconnectDataSize
= 0;
226 FCB
->FilledDisconnectData
= 0;
229 FCB
->DisconnectData
= ExAllocatePool(PagedPool
, *DisconnectDataSize
);
230 if (!FCB
->DisconnectData
) return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
232 FCB
->DisconnectDataSize
= *DisconnectDataSize
;
234 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
237 static NTSTATUS NTAPI
238 AfdGetTdiHandles(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
239 PIO_STACK_LOCATION IrpSp
)
241 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
242 PAFD_FCB FCB
= FileObject
->FsContext
;
243 PULONG HandleFlags
= LockRequest(Irp
, IrpSp
);
244 PAFD_TDI_HANDLE_DATA HandleData
= Irp
->UserBuffer
;
246 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
249 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
251 if (IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(ULONG
) ||
252 IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(*HandleData
))
254 AFD_DbgPrint(MIN_TRACE
,("Buffer too small\n"));
255 return UnlockAndMaybeComplete(FCB
, STATUS_BUFFER_TOO_SMALL
, Irp
, 0);
258 if ((*HandleFlags
) & AFD_ADDRESS_HANDLE
)
259 HandleData
->TdiAddressHandle
= FCB
->AddressFile
.Handle
;
261 if ((*HandleFlags
) & AFD_CONNECTION_HANDLE
)
262 HandleData
->TdiConnectionHandle
= FCB
->Connection
.Handle
;
264 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
267 static NTSTATUS NTAPI
268 AfdCreateSocket(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
269 PIO_STACK_LOCATION IrpSp
) {
271 PFILE_OBJECT FileObject
;
272 PAFD_DEVICE_EXTENSION DeviceExt
;
273 PFILE_FULL_EA_INFORMATION EaInfo
;
274 PAFD_CREATE_PACKET ConnectInfo
= NULL
;
276 PWCHAR EaInfoValue
= NULL
;
279 NTSTATUS Status
= STATUS_SUCCESS
;
281 AFD_DbgPrint(MID_TRACE
,
282 ("AfdCreate(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
));
284 DeviceExt
= DeviceObject
->DeviceExtension
;
285 FileObject
= IrpSp
->FileObject
;
286 //Disposition = (IrpSp->Parameters.Create.Options >> 24) & 0xff;
288 Irp
->IoStatus
.Information
= 0;
290 EaInfo
= Irp
->AssociatedIrp
.SystemBuffer
;
293 ConnectInfo
= (PAFD_CREATE_PACKET
)(EaInfo
->EaName
+ EaInfo
->EaNameLength
+ 1);
294 EaInfoValue
= (PWCHAR
)(((PCHAR
)ConnectInfo
) + sizeof(AFD_CREATE_PACKET
));
296 //EaLength = sizeof(FILE_FULL_EA_INFORMATION) + EaInfo->EaNameLength + EaInfo->EaValueLength;
298 AFD_DbgPrint(MID_TRACE
,("EaInfo: %x, EaInfoValue: %x\n",
299 EaInfo
, EaInfoValue
));
302 AFD_DbgPrint(MID_TRACE
,("About to allocate the new FCB\n"));
304 FCB
= ExAllocatePool(NonPagedPool
, sizeof(AFD_FCB
));
306 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
307 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
308 return STATUS_NO_MEMORY
;
311 AFD_DbgPrint(MID_TRACE
,("Initializing the new FCB @ %x (FileObject %x Flags %x)\n", FCB
, FileObject
, ConnectInfo
? ConnectInfo
->EndpointFlags
: 0));
313 RtlZeroMemory( FCB
, sizeof( *FCB
) );
315 FCB
->Flags
= ConnectInfo
? ConnectInfo
->EndpointFlags
: 0;
316 FCB
->GroupID
= ConnectInfo
? ConnectInfo
->GroupID
: 0;
317 FCB
->GroupType
= 0; /* FIXME */
318 FCB
->State
= SOCKET_STATE_CREATED
;
319 FCB
->FileObject
= FileObject
;
320 FCB
->DeviceExt
= DeviceExt
;
321 FCB
->AddressFile
.Handle
= INVALID_HANDLE_VALUE
;
322 FCB
->Connection
.Handle
= INVALID_HANDLE_VALUE
;
324 KeInitializeMutex( &FCB
->Mutex
, 0 );
326 for( i
= 0; i
< MAX_FUNCTIONS
; i
++ ) {
327 InitializeListHead( &FCB
->PendingIrpList
[i
] );
330 InitializeListHead( &FCB
->DatagramList
);
331 InitializeListHead( &FCB
->PendingConnections
);
333 AFD_DbgPrint(MID_TRACE
,("%x: Checking command channel\n", FCB
));
336 FCB
->TdiDeviceName
.Length
= ConnectInfo
->SizeOfTransportName
;
337 FCB
->TdiDeviceName
.MaximumLength
= FCB
->TdiDeviceName
.Length
;
338 FCB
->TdiDeviceName
.Buffer
=
339 ExAllocatePool( NonPagedPool
, FCB
->TdiDeviceName
.Length
);
341 if( !FCB
->TdiDeviceName
.Buffer
) {
343 AFD_DbgPrint(MID_TRACE
,("Could not copy target string\n"));
344 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
345 IoCompleteRequest( Irp
, IO_NETWORK_INCREMENT
);
346 return STATUS_NO_MEMORY
;
349 RtlCopyMemory( FCB
->TdiDeviceName
.Buffer
,
350 ConnectInfo
->TransportName
,
351 FCB
->TdiDeviceName
.Length
);
353 AFD_DbgPrint(MID_TRACE
,("Success: %s %wZ\n",
354 EaInfo
->EaName
, &FCB
->TdiDeviceName
));
356 AFD_DbgPrint(MID_TRACE
,("Success: Control connection\n"));
359 FileObject
->FsContext
= FCB
;
361 /* It seems that UDP sockets are writable from inception */
362 if( FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
) {
363 AFD_DbgPrint(MID_TRACE
,("Packet oriented socket\n"));
365 /* A datagram socket is always sendable */
366 FCB
->PollState
|= AFD_EVENT_SEND
;
367 FCB
->PollStatus
[FD_WRITE_BIT
] = STATUS_SUCCESS
;
368 PollReeval( FCB
->DeviceExt
, FCB
->FileObject
);
371 if( !NT_SUCCESS(Status
) ) {
372 if( FCB
->TdiDeviceName
.Buffer
) ExFreePool( FCB
->TdiDeviceName
.Buffer
);
374 FileObject
->FsContext
= NULL
;
377 Irp
->IoStatus
.Status
= Status
;
378 IoCompleteRequest( Irp
, IO_NETWORK_INCREMENT
);
383 static NTSTATUS NTAPI
384 AfdCleanupSocket(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
385 PIO_STACK_LOCATION IrpSp
)
387 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
388 PAFD_FCB FCB
= FileObject
->FsContext
;
389 PLIST_ENTRY CurrentEntry
, NextEntry
;
393 if( !SocketAcquireStateLock( FCB
) ) return LostSocket(Irp
);
395 for (Function
= 0; Function
< MAX_FUNCTIONS
; Function
++)
397 CurrentEntry
= FCB
->PendingIrpList
[Function
].Flink
;
398 while (CurrentEntry
!= &FCB
->PendingIrpList
[Function
])
400 NextEntry
= CurrentEntry
->Flink
;
401 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
403 /* The cancel routine will remove the IRP from the list */
404 IoCancelIrp(CurrentIrp
);
406 CurrentEntry
= NextEntry
;
410 KillSelectsForFCB( FCB
->DeviceExt
, FileObject
, FALSE
);
412 return UnlockAndMaybeComplete(FCB
, STATUS_SUCCESS
, Irp
, 0);
415 static NTSTATUS NTAPI
416 AfdCloseSocket(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
417 PIO_STACK_LOCATION IrpSp
)
419 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
420 PAFD_FCB FCB
= FileObject
->FsContext
;
422 PAFD_IN_FLIGHT_REQUEST InFlightRequest
[IN_FLIGHT_REQUESTS
];
423 PAFD_TDI_OBJECT_QELT Qelt
;
424 PLIST_ENTRY QeltEntry
;
427 AFD_DbgPrint(MID_TRACE
,
428 ("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
));
430 if( !SocketAcquireStateLock( FCB
) ) return STATUS_FILE_CLOSED
;
432 FCB
->State
= SOCKET_STATE_CLOSED
;
434 InFlightRequest
[0] = &FCB
->ListenIrp
;
435 InFlightRequest
[1] = &FCB
->ReceiveIrp
;
436 InFlightRequest
[2] = &FCB
->SendIrp
;
437 InFlightRequest
[3] = &FCB
->ConnectIrp
;
438 InFlightRequest
[4] = &FCB
->DisconnectIrp
;
440 /* Cancel our pending requests */
441 for( i
= 0; i
< IN_FLIGHT_REQUESTS
; i
++ ) {
442 if( InFlightRequest
[i
]->InFlightRequest
) {
443 AFD_DbgPrint(MID_TRACE
,("Cancelling in flight irp %d (%x)\n",
444 i
, InFlightRequest
[i
]->InFlightRequest
));
445 IoCancelIrp(InFlightRequest
[i
]->InFlightRequest
);
449 KillSelectsForFCB( FCB
->DeviceExt
, FileObject
, FALSE
);
451 ASSERT(IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_CONNECT
]));
452 ASSERT(IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]));
453 ASSERT(IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_RECV
]));
454 ASSERT(IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_PREACCEPT
]));
455 ASSERT(IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]));
457 while (!IsListEmpty(&FCB
->PendingConnections
))
459 QeltEntry
= RemoveHeadList(&FCB
->PendingConnections
);
460 Qelt
= CONTAINING_RECORD(QeltEntry
, AFD_TDI_OBJECT_QELT
, ListEntry
);
462 /* We have to close all pending connections or the listen won't get closed */
463 TdiDisassociateAddressFile(Qelt
->Object
.Object
);
464 ObDereferenceObject(Qelt
->Object
.Object
);
465 ZwClose(Qelt
->Object
.Handle
);
470 SocketStateUnlock( FCB
);
472 if( FCB
->EventSelect
)
473 ObDereferenceObject( FCB
->EventSelect
);
476 ExFreePool( FCB
->Context
);
478 if( FCB
->Recv
.Window
)
479 ExFreePool( FCB
->Recv
.Window
);
481 if( FCB
->Send
.Window
)
482 ExFreePool( FCB
->Send
.Window
);
484 if( FCB
->AddressFrom
)
485 ExFreePool( FCB
->AddressFrom
);
487 if( FCB
->ConnectCallInfo
)
488 ExFreePool( FCB
->ConnectCallInfo
);
490 if( FCB
->ConnectReturnInfo
)
491 ExFreePool( FCB
->ConnectReturnInfo
);
493 if( FCB
->ConnectData
)
494 ExFreePool( FCB
->ConnectData
);
496 if( FCB
->DisconnectData
)
497 ExFreePool( FCB
->DisconnectData
);
499 if( FCB
->ConnectOptions
)
500 ExFreePool( FCB
->ConnectOptions
);
502 if( FCB
->DisconnectOptions
)
503 ExFreePool( FCB
->DisconnectOptions
);
505 if( FCB
->LocalAddress
)
506 ExFreePool( FCB
->LocalAddress
);
508 if( FCB
->RemoteAddress
)
509 ExFreePool( FCB
->RemoteAddress
);
511 if( FCB
->Connection
.Object
)
513 TdiDisassociateAddressFile(FCB
->Connection
.Object
);
514 ObDereferenceObject(FCB
->Connection
.Object
);
517 if( FCB
->AddressFile
.Object
)
518 ObDereferenceObject(FCB
->AddressFile
.Object
);
520 if( FCB
->AddressFile
.Handle
!= INVALID_HANDLE_VALUE
)
522 if (ZwClose(FCB
->AddressFile
.Handle
) == STATUS_INVALID_HANDLE
)
524 DbgPrint("INVALID ADDRESS FILE HANDLE VALUE: %x %x\n", FCB
->AddressFile
.Handle
, FCB
->AddressFile
.Object
);
528 if( FCB
->Connection
.Handle
!= INVALID_HANDLE_VALUE
)
530 if (ZwClose(FCB
->Connection
.Handle
) == STATUS_INVALID_HANDLE
)
532 DbgPrint("INVALID CONNECTION HANDLE VALUE: %x %x\n", FCB
->Connection
.Handle
, FCB
->Connection
.Object
);
536 if( FCB
->TdiDeviceName
.Buffer
)
537 ExFreePool(FCB
->TdiDeviceName
.Buffer
);
541 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
542 Irp
->IoStatus
.Information
= 0;
543 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
545 AFD_DbgPrint(MID_TRACE
, ("Returning success.\n"));
547 return STATUS_SUCCESS
;
553 DisconnectComplete(PDEVICE_OBJECT DeviceObject
,
557 PAFD_FCB FCB
= Context
;
559 PLIST_ENTRY CurrentEntry
;
561 if( !SocketAcquireStateLock( FCB
) )
562 return STATUS_FILE_CLOSED
;
564 ASSERT(FCB
->DisconnectIrp
.InFlightRequest
== Irp
);
565 FCB
->DisconnectIrp
.InFlightRequest
= NULL
;
567 ASSERT(FCB
->DisconnectPending
);
568 ASSERT((IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]) && !FCB
->SendIrp
.InFlightRequest
) ||
569 (FCB
->DisconnectFlags
& TDI_DISCONNECT_ABORT
));
571 if (NT_SUCCESS(Irp
->IoStatus
.Status
) && (FCB
->DisconnectFlags
& TDI_DISCONNECT_RELEASE
))
573 FCB
->FilledDisconnectData
= MIN(FCB
->DisconnectDataSize
, FCB
->ConnectReturnInfo
->UserDataLength
);
574 if (FCB
->FilledDisconnectData
)
576 RtlCopyMemory(FCB
->DisconnectData
,
577 FCB
->ConnectReturnInfo
->UserData
,
578 FCB
->FilledDisconnectData
);
581 FCB
->FilledDisconnectOptions
= MIN(FCB
->DisconnectOptionsSize
, FCB
->ConnectReturnInfo
->OptionsLength
);
582 if (FCB
->FilledDisconnectOptions
)
584 RtlCopyMemory(FCB
->DisconnectOptions
,
585 FCB
->ConnectReturnInfo
->Options
,
586 FCB
->FilledDisconnectOptions
);
590 FCB
->DisconnectPending
= FALSE
;
592 while (!IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]))
594 CurrentEntry
= RemoveHeadList(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]);
595 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
596 CurrentIrp
->IoStatus
.Status
= Irp
->IoStatus
.Status
;
597 CurrentIrp
->IoStatus
.Information
= 0;
598 UnlockRequest(CurrentIrp
, IoGetCurrentIrpStackLocation(CurrentIrp
));
599 (void)IoSetCancelRoutine(CurrentIrp
, NULL
);
600 IoCompleteRequest(CurrentIrp
, IO_NETWORK_INCREMENT
);
603 if (!(FCB
->DisconnectFlags
& TDI_DISCONNECT_RELEASE
))
605 /* Signal complete connection closure immediately */
606 FCB
->PollState
|= AFD_EVENT_ABORT
;
607 FCB
->PollStatus
[FD_CLOSE_BIT
] = Irp
->IoStatus
.Status
;
608 PollReeval(FCB
->DeviceExt
, FCB
->FileObject
);
611 SocketStateUnlock(FCB
);
613 return Irp
->IoStatus
.Status
;
618 DoDisconnect(PAFD_FCB FCB
)
622 ASSERT(FCB
->DisconnectPending
);
623 ASSERT((IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]) && !FCB
->SendIrp
.InFlightRequest
) ||
624 (FCB
->DisconnectFlags
& TDI_DISCONNECT_ABORT
));
626 if (FCB
->DisconnectIrp
.InFlightRequest
)
628 return STATUS_PENDING
;
631 FCB
->ConnectCallInfo
->UserData
= FCB
->DisconnectData
;
632 FCB
->ConnectCallInfo
->UserDataLength
= FCB
->DisconnectDataSize
;
633 FCB
->ConnectCallInfo
->Options
= FCB
->DisconnectOptions
;
634 FCB
->ConnectCallInfo
->OptionsLength
= FCB
->DisconnectOptionsSize
;
636 Status
= TdiDisconnect(&FCB
->DisconnectIrp
.InFlightRequest
,
637 FCB
->Connection
.Object
,
638 &FCB
->DisconnectTimeout
,
639 FCB
->DisconnectFlags
,
640 &FCB
->DisconnectIrp
.Iosb
,
643 FCB
->ConnectCallInfo
,
644 FCB
->ConnectReturnInfo
);
645 if (Status
!= STATUS_PENDING
)
647 FCB
->DisconnectPending
= FALSE
;
654 RetryDisconnectCompletion(PAFD_FCB FCB
)
656 ASSERT(FCB
->RemoteAddress
);
658 if (IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]) && !FCB
->SendIrp
.InFlightRequest
&& FCB
->DisconnectPending
)
660 /* Sends are done; fire off a TDI_DISCONNECT request */
665 static NTSTATUS NTAPI
666 AfdDisconnect(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
667 PIO_STACK_LOCATION IrpSp
) {
668 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
669 PAFD_FCB FCB
= FileObject
->FsContext
;
670 PAFD_DISCONNECT_INFO DisReq
;
671 NTSTATUS Status
= STATUS_SUCCESS
;
673 PLIST_ENTRY CurrentEntry
;
676 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
678 if( !(DisReq
= LockRequest( Irp
, IrpSp
)) )
679 return UnlockAndMaybeComplete( FCB
, STATUS_NO_MEMORY
,
682 /* Send direction only */
683 if ((DisReq
->DisconnectType
& AFD_DISCONNECT_SEND
) &&
684 !(DisReq
->DisconnectType
& AFD_DISCONNECT_RECV
))
686 /* Perform a controlled disconnect */
687 Flags
= TDI_DISCONNECT_RELEASE
;
689 /* Receive direction or both */
692 /* Mark that we can't issue another receive request */
693 FCB
->TdiReceiveClosed
= TRUE
;
695 /* Try to cancel a pending TDI receive IRP if there was one in progress */
696 if (FCB
->ReceiveIrp
.InFlightRequest
)
697 IoCancelIrp(FCB
->ReceiveIrp
.InFlightRequest
);
699 /* Discard any pending data */
700 FCB
->Recv
.Content
= 0;
701 FCB
->Recv
.BytesUsed
= 0;
703 /* Mark us as overread to complete future reads with an error */
704 FCB
->Overread
= TRUE
;
706 /* Set a successful close status to indicate a shutdown on overread */
707 FCB
->PollStatus
[FD_CLOSE_BIT
] = STATUS_SUCCESS
;
709 /* Clear the receive event */
710 FCB
->PollState
&= ~AFD_EVENT_RECEIVE
;
712 /* Receive direction only */
713 if ((DisReq
->DisconnectType
& AFD_DISCONNECT_RECV
) &&
714 !(DisReq
->DisconnectType
& AFD_DISCONNECT_SEND
))
716 /* No need to tell the transport driver for receive direction only */
717 return UnlockAndMaybeComplete( FCB
, STATUS_SUCCESS
, Irp
, 0 );
721 /* Perform an abortive disconnect */
722 Flags
= TDI_DISCONNECT_ABORT
;
726 if (!(FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
))
728 if( !FCB
->ConnectCallInfo
)
730 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
731 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
,
735 if (FCB
->DisconnectPending
)
737 if (FCB
->DisconnectIrp
.InFlightRequest
)
739 IoCancelIrp(FCB
->DisconnectIrp
.InFlightRequest
);
740 ASSERT(!FCB
->DisconnectIrp
.InFlightRequest
);
744 while (!IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]))
746 CurrentEntry
= RemoveHeadList(&FCB
->PendingIrpList
[FUNCTION_DISCONNECT
]);
747 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
748 CurrentIrp
->IoStatus
.Status
= STATUS_CANCELLED
;
749 CurrentIrp
->IoStatus
.Information
= 0;
750 UnlockRequest(CurrentIrp
, IoGetCurrentIrpStackLocation(CurrentIrp
));
751 (void)IoSetCancelRoutine(CurrentIrp
, NULL
);
752 IoCompleteRequest(CurrentIrp
, IO_NETWORK_INCREMENT
);
757 FCB
->DisconnectFlags
= Flags
;
758 FCB
->DisconnectTimeout
= DisReq
->Timeout
;
759 FCB
->DisconnectPending
= TRUE
;
760 FCB
->SendClosed
= TRUE
;
761 FCB
->PollState
&= ~AFD_EVENT_SEND
;
763 Status
= QueueUserModeIrp(FCB
, Irp
, FUNCTION_DISCONNECT
);
764 if (Status
== STATUS_PENDING
)
766 if ((IsListEmpty(&FCB
->PendingIrpList
[FUNCTION_SEND
]) && !FCB
->SendIrp
.InFlightRequest
) ||
767 (FCB
->DisconnectFlags
& TDI_DISCONNECT_ABORT
))
769 /* Go ahead and execute the disconnect because we're ready for it */
770 Status
= DoDisconnect(FCB
);
773 if (Status
!= STATUS_PENDING
)
774 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
777 if (Status
== STATUS_PENDING
)
779 SocketStateUnlock(FCB
);
786 if (!(Flags
& TDI_DISCONNECT_RELEASE
))
788 if (!FCB
->RemoteAddress
)
790 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
791 return UnlockAndMaybeComplete(FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0);
794 ExFreePool(FCB
->RemoteAddress
);
796 FCB
->RemoteAddress
= NULL
;
799 FCB
->PollState
&= ~AFD_EVENT_SEND
;
800 FCB
->SendClosed
= TRUE
;
803 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );
806 static NTSTATUS NTAPI
807 AfdDispatch(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
809 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
810 NTSTATUS Status
= STATUS_NOT_IMPLEMENTED
;
812 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
815 AFD_DbgPrint(MID_TRACE
,("AfdDispatch: %d\n", IrpSp
->MajorFunction
));
816 if( IrpSp
->MajorFunction
!= IRP_MJ_CREATE
) {
817 AFD_DbgPrint(MID_TRACE
,("FO %x, IrpSp->FO %x\n",
818 FileObject
, IrpSp
->FileObject
));
819 ASSERT(FileObject
== IrpSp
->FileObject
);
822 Irp
->IoStatus
.Information
= 0;
824 switch(IrpSp
->MajorFunction
)
826 /* opening and closing handles to the device */
828 /* Mostly borrowed from the named pipe file system */
829 return AfdCreateSocket(DeviceObject
, Irp
, IrpSp
);
832 /* Ditto the borrowing */
833 return AfdCloseSocket(DeviceObject
, Irp
, IrpSp
);
836 return AfdCleanupSocket(DeviceObject
, Irp
, IrpSp
);
840 return AfdConnectedSocketWriteData( DeviceObject
, Irp
, IrpSp
, TRUE
);
844 return AfdConnectedSocketReadData( DeviceObject
, Irp
, IrpSp
, TRUE
);
846 case IRP_MJ_DEVICE_CONTROL
:
848 switch( IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
850 return AfdBindSocket( DeviceObject
, Irp
, IrpSp
);
852 case IOCTL_AFD_CONNECT
:
853 return AfdStreamSocketConnect( DeviceObject
, Irp
, IrpSp
);
855 case IOCTL_AFD_START_LISTEN
:
856 return AfdListenSocket( DeviceObject
, Irp
, IrpSp
);
859 return AfdConnectedSocketReadData( DeviceObject
, Irp
, IrpSp
,
862 case IOCTL_AFD_SELECT
:
863 return AfdSelect( DeviceObject
, Irp
, IrpSp
);
865 case IOCTL_AFD_EVENT_SELECT
:
866 return AfdEventSelect( DeviceObject
, Irp
, IrpSp
);
868 case IOCTL_AFD_ENUM_NETWORK_EVENTS
:
869 return AfdEnumEvents( DeviceObject
, Irp
, IrpSp
);
871 case IOCTL_AFD_RECV_DATAGRAM
:
872 return AfdPacketSocketReadData( DeviceObject
, Irp
, IrpSp
);
875 return AfdConnectedSocketWriteData( DeviceObject
, Irp
, IrpSp
,
878 case IOCTL_AFD_SEND_DATAGRAM
:
879 return AfdPacketSocketWriteData( DeviceObject
, Irp
, IrpSp
);
881 case IOCTL_AFD_GET_INFO
:
882 return AfdGetInfo( DeviceObject
, Irp
, IrpSp
);
884 case IOCTL_AFD_SET_INFO
:
885 return AfdSetInfo( DeviceObject
, Irp
, IrpSp
);
887 case IOCTL_AFD_GET_CONTEXT_SIZE
:
888 return AfdGetContextSize( DeviceObject
, Irp
, IrpSp
);
890 case IOCTL_AFD_GET_CONTEXT
:
891 return AfdGetContext( DeviceObject
, Irp
, IrpSp
);
893 case IOCTL_AFD_SET_CONTEXT
:
894 return AfdSetContext( DeviceObject
, Irp
, IrpSp
);
896 case IOCTL_AFD_WAIT_FOR_LISTEN
:
897 return AfdWaitForListen( DeviceObject
, Irp
, IrpSp
);
899 case IOCTL_AFD_ACCEPT
:
900 return AfdAccept( DeviceObject
, Irp
, IrpSp
);
902 case IOCTL_AFD_DISCONNECT
:
903 return AfdDisconnect( DeviceObject
, Irp
, IrpSp
);
905 case IOCTL_AFD_GET_SOCK_NAME
:
906 return AfdGetSockName( DeviceObject
, Irp
, IrpSp
);
908 case IOCTL_AFD_GET_PEER_NAME
:
909 return AfdGetPeerName( DeviceObject
, Irp
, IrpSp
);
911 case IOCTL_AFD_GET_CONNECT_DATA
:
912 return AfdGetConnectData(DeviceObject
, Irp
, IrpSp
);
914 case IOCTL_AFD_SET_CONNECT_DATA
:
915 return AfdSetConnectData(DeviceObject
, Irp
, IrpSp
);
917 case IOCTL_AFD_SET_DISCONNECT_DATA
:
918 return AfdSetDisconnectData(DeviceObject
, Irp
, IrpSp
);
920 case IOCTL_AFD_GET_DISCONNECT_DATA
:
921 return AfdGetDisconnectData(DeviceObject
, Irp
, IrpSp
);
923 case IOCTL_AFD_SET_CONNECT_DATA_SIZE
:
924 return AfdSetConnectDataSize(DeviceObject
, Irp
, IrpSp
);
926 case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE
:
927 return AfdSetDisconnectDataSize(DeviceObject
, Irp
, IrpSp
);
929 case IOCTL_AFD_SET_CONNECT_OPTIONS
:
930 return AfdSetConnectOptions(DeviceObject
, Irp
, IrpSp
);
932 case IOCTL_AFD_SET_DISCONNECT_OPTIONS
:
933 return AfdSetDisconnectOptions(DeviceObject
, Irp
, IrpSp
);
935 case IOCTL_AFD_GET_CONNECT_OPTIONS
:
936 return AfdGetConnectOptions(DeviceObject
, Irp
, IrpSp
);
938 case IOCTL_AFD_GET_DISCONNECT_OPTIONS
:
939 return AfdGetDisconnectOptions(DeviceObject
, Irp
, IrpSp
);
941 case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE
:
942 return AfdSetConnectOptionsSize(DeviceObject
, Irp
, IrpSp
);
944 case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE
:
945 return AfdSetDisconnectOptionsSize(DeviceObject
, Irp
, IrpSp
);
947 case IOCTL_AFD_GET_TDI_HANDLES
:
948 return AfdGetTdiHandles(DeviceObject
, Irp
, IrpSp
);
950 case IOCTL_AFD_DEFER_ACCEPT
:
951 DbgPrint("IOCTL_AFD_DEFER_ACCEPT is UNIMPLEMENTED!\n");
954 case IOCTL_AFD_GET_PENDING_CONNECT_DATA
:
955 DbgPrint("IOCTL_AFD_GET_PENDING_CONNECT_DATA is UNIMPLEMENTED!\n");
958 case IOCTL_AFD_VALIDATE_GROUP
:
959 DbgPrint("IOCTL_AFD_VALIDATE_GROUP is UNIMPLEMENTED!\n");
963 Status
= STATUS_NOT_SUPPORTED
;
964 DbgPrint("Unknown IOCTL (0x%x)\n",
965 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
);
971 /* unsupported operations */
974 Status
= STATUS_NOT_IMPLEMENTED
;
975 AFD_DbgPrint(MIN_TRACE
,
976 ("Irp: Unknown Major code was %x\n",
977 IrpSp
->MajorFunction
));
982 AFD_DbgPrint(MID_TRACE
, ("Returning %x\n", Status
));
983 Irp
->IoStatus
.Status
= Status
;
984 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
989 BOOLEAN
CheckUnlockExtraBuffers(PAFD_FCB FCB
, PIO_STACK_LOCATION IrpSp
)
991 if (FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
)
993 if (IrpSp
->MajorFunction
== IRP_MJ_READ
|| IrpSp
->MajorFunction
== IRP_MJ_WRITE
)
995 /* read()/write() call - no extra buffers */
998 else if (IrpSp
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
)
1000 if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_RECV_DATAGRAM
)
1002 /* recvfrom() call - extra buffers */
1005 else if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_RECV
)
1007 /* recv() call - no extra buffers */
1010 else if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SEND
||
1011 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SEND_DATAGRAM
)
1013 /* send()/sendto() call - no extra buffers */
1025 /* Unknown IRP_MJ code */
1032 /* Connection-oriented never has extra buffers */
1038 CleanupPendingIrp(PAFD_FCB FCB
, PIRP Irp
, PIO_STACK_LOCATION IrpSp
, PAFD_ACTIVE_POLL Poll
)
1040 PAFD_RECV_INFO RecvReq
;
1041 PAFD_SEND_INFO SendReq
;
1042 PAFD_POLL_INFO PollReq
;
1044 if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_RECV
||
1045 IrpSp
->MajorFunction
== IRP_MJ_READ
)
1047 RecvReq
= GetLockedData(Irp
, IrpSp
);
1048 UnlockBuffers(RecvReq
->BufferArray
, RecvReq
->BufferCount
, CheckUnlockExtraBuffers(FCB
, IrpSp
));
1050 else if ((IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SEND
||
1051 IrpSp
->MajorFunction
== IRP_MJ_WRITE
))
1053 SendReq
= GetLockedData(Irp
, IrpSp
);
1054 UnlockBuffers(SendReq
->BufferArray
, SendReq
->BufferCount
, CheckUnlockExtraBuffers(FCB
, IrpSp
));
1056 else if (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_AFD_SELECT
)
1058 PollReq
= Irp
->AssociatedIrp
.SystemBuffer
;
1059 ZeroEvents(PollReq
->Handles
, PollReq
->HandleCount
);
1060 SignalSocket(Poll
, NULL
, PollReq
, STATUS_CANCELLED
);
1065 AfdCancelHandler(PDEVICE_OBJECT DeviceObject
,
1068 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1069 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
1070 PAFD_FCB FCB
= FileObject
->FsContext
;
1071 ULONG Function
, IoctlCode
;
1073 PLIST_ENTRY CurrentEntry
;
1074 PAFD_DEVICE_EXTENSION DeviceExt
= DeviceObject
->DeviceExtension
;
1076 PAFD_ACTIVE_POLL Poll
;
1078 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
1080 if (!SocketAcquireStateLock(FCB
))
1083 switch (IrpSp
->MajorFunction
)
1085 case IRP_MJ_DEVICE_CONTROL
:
1086 IoctlCode
= IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
;
1090 IoctlCode
= IOCTL_AFD_RECV
;
1094 IoctlCode
= IOCTL_AFD_SEND
;
1099 SocketStateUnlock(FCB
);
1105 case IOCTL_AFD_RECV
:
1106 case IOCTL_AFD_RECV_DATAGRAM
:
1107 Function
= FUNCTION_RECV
;
1110 case IOCTL_AFD_SEND
:
1111 case IOCTL_AFD_SEND_DATAGRAM
:
1112 Function
= FUNCTION_SEND
;
1115 case IOCTL_AFD_CONNECT
:
1116 Function
= FUNCTION_CONNECT
;
1119 case IOCTL_AFD_WAIT_FOR_LISTEN
:
1120 Function
= FUNCTION_PREACCEPT
;
1123 case IOCTL_AFD_SELECT
:
1124 KeAcquireSpinLock(&DeviceExt
->Lock
, &OldIrql
);
1126 CurrentEntry
= DeviceExt
->Polls
.Flink
;
1127 while (CurrentEntry
!= &DeviceExt
->Polls
)
1129 Poll
= CONTAINING_RECORD(CurrentEntry
, AFD_ACTIVE_POLL
, ListEntry
);
1131 if (Irp
== Poll
->Irp
)
1133 CleanupPendingIrp(FCB
, Irp
, IrpSp
, Poll
);
1134 KeReleaseSpinLock(&DeviceExt
->Lock
, OldIrql
);
1135 SocketStateUnlock(FCB
);
1140 CurrentEntry
= CurrentEntry
->Flink
;
1144 KeReleaseSpinLock(&DeviceExt
->Lock
, OldIrql
);
1146 SocketStateUnlock(FCB
);
1148 DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (IOCTL_AFD_SELECT)\n");
1151 case IOCTL_AFD_DISCONNECT
:
1152 Function
= FUNCTION_DISCONNECT
;
1157 UnlockAndMaybeComplete(FCB
, STATUS_CANCELLED
, Irp
, 0);
1161 CurrentEntry
= FCB
->PendingIrpList
[Function
].Flink
;
1162 while (CurrentEntry
!= &FCB
->PendingIrpList
[Function
])
1164 CurrentIrp
= CONTAINING_RECORD(CurrentEntry
, IRP
, Tail
.Overlay
.ListEntry
);
1166 if (CurrentIrp
== Irp
)
1168 RemoveEntryList(CurrentEntry
);
1169 CleanupPendingIrp(FCB
, Irp
, IrpSp
, NULL
);
1170 UnlockAndMaybeComplete(FCB
, STATUS_CANCELLED
, Irp
, 0);
1175 CurrentEntry
= CurrentEntry
->Flink
;
1179 SocketStateUnlock(FCB
);
1181 DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (Function: %d)\n", Function
);
1185 AfdUnload(PDRIVER_OBJECT DriverObject
)
1190 DriverEntry(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
1192 PDEVICE_OBJECT DeviceObject
;
1193 UNICODE_STRING wstrDeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\Afd");
1194 PAFD_DEVICE_EXTENSION DeviceExt
;
1197 /* register driver routines */
1198 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = AfdDispatch
;
1199 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = AfdDispatch
;
1200 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = AfdDispatch
;
1201 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = AfdDispatch
;
1202 DriverObject
->MajorFunction
[IRP_MJ_READ
] = AfdDispatch
;
1203 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = AfdDispatch
;
1204 DriverObject
->DriverUnload
= AfdUnload
;
1206 Status
= IoCreateDevice
1208 sizeof(AFD_DEVICE_EXTENSION
),
1210 FILE_DEVICE_NAMED_PIPE
,
1216 if(!NT_SUCCESS(Status
))
1221 DeviceExt
= DeviceObject
->DeviceExtension
;
1222 KeInitializeSpinLock( &DeviceExt
->Lock
);
1223 InitializeListHead( &DeviceExt
->Polls
);
1225 AFD_DbgPrint(MID_TRACE
,("Device created: object %x ext %x\n",
1226 DeviceObject
, DeviceExt
));