2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: tcpip/dispatch.h
5 * PURPOSE: TDI dispatch routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/08-2000 Created
9 * TODO: Validate device object in all dispatch routines
18 NTSTATUS
DispPrepareIrpForCancel(
19 PTRANSPORT_CONTEXT Context
,
21 PDRIVER_CANCEL CancelRoutine
)
23 * FUNCTION: Prepare an IRP for cancellation
25 * Context = Pointer to context information
26 * Irp = Pointer to an I/O request packet
27 * CancelRoutine = Routine to be called when I/O request is cancelled
34 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
36 IoAcquireCancelSpinLock(&OldIrql
);
39 IoMarkIrpPending(Irp
);
40 IoSetCancelRoutine(Irp
, CancelRoutine
);
42 IoReleaseCancelSpinLock(OldIrql
);
44 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
46 return STATUS_SUCCESS
;
49 /* IRP has already been cancelled */
51 IoReleaseCancelSpinLock(OldIrql
);
53 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
54 Irp
->IoStatus
.Information
= 0;
56 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
58 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
60 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
62 return STATUS_CANCELLED
;
66 VOID
DispCancelComplete(
69 * FUNCTION: Completes a cancel request
71 * Context = Pointer to context information (FILE_OBJECT)
75 PFILE_OBJECT FileObject
;
76 PTRANSPORT_CONTEXT TranContext
;
78 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
80 FileObject
= (PFILE_OBJECT
)Context
;
81 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
83 IoAcquireCancelSpinLock(&OldIrql
);
85 /* Remove the reference taken by the cancel routine */
86 TranContext
->RefCount
--;
88 if (TranContext
->RefCount
== 0) {
89 TI_DbgPrint(DEBUG_IRP
, ("Setting TranContext->CleanupEvent to signaled.\n"));
90 /* Set the cleanup event */
91 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
94 TI_DbgPrint(DEBUG_REFCOUNT
, ("TranContext->RefCount (%d).\n", TranContext
->RefCount
));
96 IoReleaseCancelSpinLock(OldIrql
);
98 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
102 VOID
DispCancelRequest(
103 PDEVICE_OBJECT Device
,
106 * FUNCTION: Cancels an IRP
108 * Device = Pointer to device object
109 * Irp = Pointer to an I/O request packet
112 PIO_STACK_LOCATION IrpSp
;
113 PTRANSPORT_CONTEXT TranContext
;
114 PFILE_OBJECT FileObject
;
116 NTSTATUS Status
= STATUS_SUCCESS
;
118 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
120 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
121 FileObject
= IrpSp
->FileObject
;
122 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
123 MinorFunction
= IrpSp
->MinorFunction
;
125 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
129 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
132 /* Increase reference count to prevent accidential closure
133 of the object while inside the cancel routine */
134 TranContext
->RefCount
++;
136 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
138 /* Try canceling the request */
139 switch(MinorFunction
) {
143 /* FIXME: Close connection */
146 case TDI_SEND_DATAGRAM
:
147 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
148 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
152 DGCancelSendRequest(TranContext
->Handle
.AddressHandle
, Irp
);
155 case TDI_RECEIVE_DATAGRAM
:
156 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
157 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
161 DGCancelReceiveRequest(TranContext
->Handle
.AddressHandle
, Irp
);
165 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
169 if (Status
!= STATUS_PENDING
)
170 DispCancelComplete(FileObject
);
172 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
176 VOID
DispDataRequestComplete(
181 * FUNCTION: Completes a send/receive IRP
183 * Context = Pointer to context information (IRP)
184 * Status = Status of the request
185 * Count = Number of bytes sent or received
189 PIO_STACK_LOCATION IrpSp
;
190 PTRANSPORT_CONTEXT TranContext
;
193 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
196 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
197 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
199 IoAcquireCancelSpinLock(&OldIrql
);
201 IoSetCancelRoutine(Irp
, NULL
);
202 TranContext
->RefCount
--;
203 TI_DbgPrint(DEBUG_REFCOUNT
, ("TranContext->RefCount (%d).\n", TranContext
->RefCount
));
204 if (TranContext
->RefCount
== 0) {
205 TI_DbgPrint(DEBUG_IRP
, ("Setting TranContext->CleanupEvent to signaled.\n"));
207 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
210 if (Irp
->Cancel
|| TranContext
->CancelIrps
) {
211 /* The IRP has been cancelled */
213 TI_DbgPrint(DEBUG_IRP
, ("IRP is cancelled.\n"));
215 Status
= STATUS_CANCELLED
;
219 IoReleaseCancelSpinLock(OldIrql
);
221 Irp
->IoStatus
.Status
= Status
;
222 Irp
->IoStatus
.Information
= Count
;
224 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
226 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
230 NTSTATUS
DispTdiAccept(
233 * FUNCTION: TDI_ACCEPT handler
235 * Irp = Pointer to an I/O request packet
237 * Status of operation
240 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
242 return STATUS_NOT_IMPLEMENTED
;
246 NTSTATUS
DispTdiAssociateAddress(
249 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
251 * Irp = Pointer to an I/O request packet
253 * Status of operation
256 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
257 PTRANSPORT_CONTEXT TranContext
;
258 PIO_STACK_LOCATION IrpSp
;
259 PCONNECTION_ENDPOINT Connection
;
260 PFILE_OBJECT FileObject
;
261 PADDRESS_FILE AddrFile
;
264 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
266 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
268 /* Get associated connection endpoint file object. Quit if none exists */
270 TranContext
= IrpSp
->FileObject
->FsContext
;
272 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
273 return STATUS_INVALID_PARAMETER
;
276 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
278 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
279 return STATUS_INVALID_PARAMETER
;
282 if (Connection
->AddressFile
) {
283 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
284 return STATUS_INVALID_PARAMETER
;
287 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
289 Status
= ObReferenceObjectByHandle(
290 Parameters
->AddressHandle
,
296 if (!NT_SUCCESS(Status
)) {
297 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X).\n",
298 Parameters
->AddressHandle
));
299 return STATUS_INVALID_PARAMETER
;
302 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
303 ObDereferenceObject(FileObject
);
304 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
305 FileObject
->FsContext2
));
306 return STATUS_INVALID_PARAMETER
;
309 /* Get associated address file object. Quit if none exists */
311 TranContext
= FileObject
->FsContext
;
313 ObDereferenceObject(FileObject
);
314 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
315 return STATUS_INVALID_PARAMETER
;
318 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
320 ObDereferenceObject(FileObject
);
321 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
322 return STATUS_INVALID_PARAMETER
;
325 /* The connection endpoint references the address file object */
326 ReferenceObject(AddrFile
);
327 Connection
->AddressFile
= AddrFile
;
329 /* Add connection endpoint to the address file */
330 AddrFile
->Connection
= Connection
;
332 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
333 ObDereferenceObject(FileObject
);
335 return STATUS_SUCCESS
;
339 NTSTATUS
DispTdiConnect(
342 * FUNCTION: TDI_CONNECT handler
344 * Irp = Pointer to an I/O request packet
346 * Status of operation
349 PCONNECTION_ENDPOINT Connection
;
350 PTDI_REQUEST_KERNEL Parameters
;
351 PTRANSPORT_CONTEXT TranContext
;
352 PIO_STACK_LOCATION IrpSp
;
356 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
358 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
360 /* Get associated connection endpoint file object. Quit if none exists */
362 TranContext
= IrpSp
->FileObject
->FsContext
;
364 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
365 return STATUS_INVALID_CONNECTION
;
368 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
370 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
371 return STATUS_INVALID_CONNECTION
;
374 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
376 /* Initialize a connect request */
377 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
378 Request
.RequestNotifyObject
= DispDataRequestComplete
;
379 Request
.RequestContext
= Irp
;
383 Parameters
->RequestConnectionInformation
,
384 Parameters
->ReturnConnectionInformation
);
390 NTSTATUS
DispTdiDisassociateAddress(
393 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
395 * Irp = Pointer to an I/O request packet
397 * Status of operation
400 PCONNECTION_ENDPOINT Connection
;
401 PTRANSPORT_CONTEXT TranContext
;
402 PIO_STACK_LOCATION IrpSp
;
405 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
407 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
409 /* Get associated connection endpoint file object. Quit if none exists */
411 TranContext
= IrpSp
->FileObject
->FsContext
;
413 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
414 return STATUS_INVALID_PARAMETER
;
417 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
419 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
420 return STATUS_INVALID_PARAMETER
;
423 if (!Connection
->AddressFile
) {
424 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
425 return STATUS_INVALID_PARAMETER
;
428 /* Remove the reference put on the address file object */
429 KeAcquireSpinLock(&Connection
->Lock
, &OldIrql
);
430 DereferenceObject(Connection
->AddressFile
);
431 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
433 return STATUS_SUCCESS
;
437 NTSTATUS
DispTdiDisconnect(
440 * FUNCTION: TDI_DISCONNECT handler
442 * Irp = Pointer to an I/O request packet
444 * Status of operation
447 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
448 PTRANSPORT_CONTEXT TranContext
;
449 PIO_STACK_LOCATION IrpSp
;
451 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
453 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
454 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
456 TranContext
= IrpSp
->FileObject
->FsContext
;
458 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
459 return STATUS_INVALID_CONNECTION
;
462 switch (Parameters
->QueryType
)
464 case TDI_QUERY_ADDRESS_INFO
:
466 PTDI_ADDRESS_INFO AddressInfo
;
467 PADDRESS_FILE AddrFile
;
468 PTA_IP_ADDRESS Address
;
470 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
472 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
473 case TDI_TRANSPORT_ADDRESS_FILE
:
474 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
477 case TDI_CONNECTION_FILE
:
478 AddrFile
= ((PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
)->AddressFile
;
482 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
483 return STATUS_INVALID_PARAMETER
;
487 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
488 return STATUS_INVALID_PARAMETER
;
491 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
492 (sizeof(TDI_ADDRESS_INFO
) + sizeof(TDI_ADDRESS_IP
))) {
493 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
494 return STATUS_BUFFER_OVERFLOW
;
497 /* FIXME: Is this count really the one we should return? */
498 AddressInfo
->ActivityCount
= AddrFile
->RefCount
;
500 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
501 Address
->TAAddressCount
= 1;
502 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
503 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
504 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
505 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->ADE
->Address
->Address
.IPv4Address
;
507 &Address
->Address
[0].Address
[0].sin_zero
,
508 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
510 return STATUS_SUCCESS
;
514 return STATUS_NOT_IMPLEMENTED
;
518 NTSTATUS
DispTdiListen(
521 * FUNCTION: TDI_LISTEN handler
523 * Irp = Pointer to an I/O request packet
525 * Status of operation
528 PCONNECTION_ENDPOINT Connection
;
529 PTDI_REQUEST_KERNEL Parameters
;
530 PTRANSPORT_CONTEXT TranContext
;
531 PIO_STACK_LOCATION IrpSp
;
535 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
537 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
539 /* Get associated connection endpoint file object. Quit if none exists */
541 TranContext
= IrpSp
->FileObject
->FsContext
;
543 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
544 return STATUS_INVALID_CONNECTION
;
547 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
549 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
550 return STATUS_INVALID_CONNECTION
;
553 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
555 /* Initialize a connect request */
556 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
557 Request
.RequestNotifyObject
= DispDataRequestComplete
;
558 Request
.RequestContext
= Irp
;
562 Parameters
->RequestConnectionInformation
,
563 Parameters
->ReturnConnectionInformation
);
569 NTSTATUS
DispTdiQueryInformation(
570 PDEVICE_OBJECT DeviceObject
,
573 * FUNCTION: TDI_QUERY_INFORMATION handler
575 * DeviceObject = Pointer to device object structure
576 * Irp = Pointer to an I/O request packet
578 * Status of operation
581 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
583 return STATUS_NOT_IMPLEMENTED
;
587 NTSTATUS
DispTdiReceive(
590 * FUNCTION: TDI_RECEIVE handler
592 * Irp = Pointer to an I/O request packet
594 * Status of operation
597 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
599 return STATUS_NOT_IMPLEMENTED
;
603 NTSTATUS
DispTdiReceiveDatagram(
606 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
608 * Irp = Pointer to an I/O request packet
610 * Status of operation
613 PIO_STACK_LOCATION IrpSp
;
614 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
615 PTRANSPORT_CONTEXT TranContext
;
620 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
622 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
623 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
625 TranContext
= IrpSp
->FileObject
->FsContext
;
626 /* Initialize a receive request */
627 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
628 Request
.RequestNotifyObject
= DispDataRequestComplete
;
629 Request
.RequestContext
= Irp
;
630 Status
= DispPrepareIrpForCancel(
631 IrpSp
->FileObject
->FsContext
,
633 (PDRIVER_CANCEL
)DispCancelRequest
);
634 if (NT_SUCCESS(Status
)) {
635 Status
= UDPReceiveDatagram(
637 DgramInfo
->ReceiveDatagramInformation
,
638 (PNDIS_BUFFER
)Irp
->MdlAddress
,
639 DgramInfo
->ReceiveLength
,
640 DgramInfo
->ReceiveFlags
,
641 DgramInfo
->ReturnDatagramInformation
,
643 if (Status
!= STATUS_PENDING
) {
644 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
645 /* Return STATUS_PENDING because DispPrepareIrpForCancel marks
646 the Irp as pending */
647 Status
= STATUS_PENDING
;
651 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
657 NTSTATUS
DispTdiSend(
660 * FUNCTION: TDI_SEND handler
662 * Irp = Pointer to an I/O request packet
664 * Status of operation
667 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
669 return STATUS_NOT_IMPLEMENTED
;
673 NTSTATUS
DispTdiSendDatagram(
676 * FUNCTION: TDI_SEND_DATAGRAM handler
678 * Irp = Pointer to an I/O request packet
680 * Status of operation
683 PIO_STACK_LOCATION IrpSp
;
685 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
686 PTRANSPORT_CONTEXT TranContext
;
689 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
691 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
692 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
693 TranContext
= IrpSp
->FileObject
->FsContext
;
695 /* Initialize a send request */
696 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
697 Request
.RequestNotifyObject
= DispDataRequestComplete
;
698 Request
.RequestContext
= Irp
;
700 Status
= DispPrepareIrpForCancel(
701 IrpSp
->FileObject
->FsContext
,
703 (PDRIVER_CANCEL
)DispCancelRequest
);
704 if (NT_SUCCESS(Status
)) {
706 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
707 must be of type PTDI_ADDRESS_IP */
709 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
710 &Request
, DgramInfo
->SendDatagramInformation
,
711 (PNDIS_BUFFER
)Irp
->MdlAddress
, DgramInfo
->SendLength
);
712 if (Status
!= STATUS_PENDING
) {
713 DispDataRequestComplete(Irp
, Status
, 0);
714 /* Return STATUS_PENDING because DispPrepareIrpForCancel
715 marks Irp as pending */
716 Status
= STATUS_PENDING
;
720 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
726 NTSTATUS
DispTdiSetEventHandler(
729 * FUNCTION: TDI_SET_EVENT_HANDER handler
731 * Irp = Pointer to a I/O request packet
733 * Status of operation
736 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
737 PTRANSPORT_CONTEXT TranContext
;
738 PIO_STACK_LOCATION IrpSp
;
739 PADDRESS_FILE AddrFile
;
743 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
745 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
747 /* Get associated address file object. Quit if none exists */
749 TranContext
= IrpSp
->FileObject
->FsContext
;
751 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
752 return STATUS_INVALID_PARAMETER
;
755 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
757 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
758 return STATUS_INVALID_PARAMETER
;
761 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
762 Status
= STATUS_SUCCESS
;
764 KeAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
766 /* Set the event handler. if an event handler is associated with
767 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
768 If an event handler is not used it's flag is FALSE */
769 switch (Parameters
->EventType
) {
770 case TDI_EVENT_CONNECT
:
771 if (!Parameters
->EventHandler
) {
772 AddrFile
->ConnectHandlerContext
= NULL
;
773 AddrFile
->RegisteredConnectHandler
= FALSE
;
775 AddrFile
->ConnectHandler
=
776 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
777 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
778 AddrFile
->RegisteredConnectHandler
= TRUE
;
782 case TDI_EVENT_DISCONNECT
:
783 if (!Parameters
->EventHandler
) {
784 AddrFile
->DisconnectHandlerContext
= NULL
;
785 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
787 AddrFile
->DisconnectHandler
=
788 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
789 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
790 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
794 case TDI_EVENT_ERROR
:
795 if (Parameters
->EventHandler
== NULL
) {
796 AddrFile
->ErrorHandlerContext
= NULL
;
797 AddrFile
->RegisteredErrorHandler
= FALSE
;
799 AddrFile
->ErrorHandler
=
800 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
801 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
802 AddrFile
->RegisteredErrorHandler
= TRUE
;
806 case TDI_EVENT_RECEIVE
:
807 if (Parameters
->EventHandler
== NULL
) {
808 AddrFile
->ReceiveHandlerContext
= NULL
;
809 AddrFile
->RegisteredReceiveHandler
= FALSE
;
811 AddrFile
->ReceiveHandler
=
812 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
813 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
814 AddrFile
->RegisteredReceiveHandler
= TRUE
;
818 case TDI_EVENT_RECEIVE_DATAGRAM
:
819 if (Parameters
->EventHandler
== NULL
) {
820 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
821 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
823 AddrFile
->ReceiveDatagramHandler
=
824 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
825 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
826 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
830 case TDI_EVENT_RECEIVE_EXPEDITED
:
831 if (Parameters
->EventHandler
== NULL
) {
832 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
833 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
835 AddrFile
->ExpeditedReceiveHandler
=
836 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
837 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
838 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
842 case TDI_EVENT_CHAINED_RECEIVE
:
843 if (Parameters
->EventHandler
== NULL
) {
844 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
845 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
847 AddrFile
->ChainedReceiveHandler
=
848 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
849 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
850 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
854 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
855 if (Parameters
->EventHandler
== NULL
) {
856 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
857 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
859 AddrFile
->ChainedReceiveDatagramHandler
=
860 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
861 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
862 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
866 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
867 if (Parameters
->EventHandler
== NULL
) {
868 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
869 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
871 AddrFile
->ChainedReceiveExpeditedHandler
=
872 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
873 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
874 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
879 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
880 Parameters
->EventType
));
882 Status
= STATUS_INVALID_PARAMETER
;
885 KeReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
891 NTSTATUS
DispTdiSetInformation(
894 * FUNCTION: TDI_SET_INFORMATION handler
896 * Irp = Pointer to an I/O request packet
898 * Status of operation
901 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
903 return STATUS_NOT_IMPLEMENTED
;
907 VOID
DispTdiQueryInformationExComplete(
912 * FUNCTION: Completes a TDI QueryInformationEx request
914 * Context = Pointer to the IRP for the request
915 * Status = TDI status of the request
916 * ByteCount = Number of bytes returned in output buffer
919 PTI_QUERY_CONTEXT QueryContext
;
922 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
923 if (NT_SUCCESS(Status
)) {
924 Count
= CopyBufferToBufferChain(
925 QueryContext
->InputMdl
,
926 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
927 (PUCHAR
)&QueryContext
->QueryInfo
.Context
,
931 MmUnlockPages(QueryContext
->InputMdl
);
932 IoFreeMdl(QueryContext
->InputMdl
);
933 MmUnlockPages(QueryContext
->OutputMdl
);
934 IoFreeMdl(QueryContext
->OutputMdl
);
936 QueryContext
->Irp
->IoStatus
.Information
= Count
;
937 QueryContext
->Irp
->IoStatus
.Status
= Status
;
939 ExFreePool(QueryContext
);
943 NTSTATUS
DispTdiQueryInformationEx(
945 PIO_STACK_LOCATION IrpSp
)
947 * FUNCTION: TDI QueryInformationEx handler
949 * Irp = Pointer to I/O request packet
950 * IrpSp = Pointer to current stack location of Irp
952 * Status of operation
955 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
956 PTRANSPORT_CONTEXT TranContext
;
957 PTI_QUERY_CONTEXT QueryContext
;
961 UINT InputBufferLength
;
962 UINT OutputBufferLength
;
963 BOOLEAN InputMdlLocked
= FALSE
;
964 BOOLEAN OutputMdlLocked
= FALSE
;
965 PMDL InputMdl
= NULL
;
966 PMDL OutputMdl
= NULL
;
967 NTSTATUS Status
= STATUS_SUCCESS
;
969 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
971 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
973 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
974 case TDI_TRANSPORT_ADDRESS_FILE
:
975 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
978 case TDI_CONNECTION_FILE
:
979 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
982 case TDI_CONTROL_CHANNEL_FILE
:
983 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
987 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
988 return STATUS_INVALID_PARAMETER
;
991 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
992 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
994 /* Validate parameters */
995 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
996 (OutputBufferLength
!= 0)) {
998 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
999 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1000 OutputBuffer
= Irp
->UserBuffer
;
1002 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1007 InputMdl
= IoAllocateMdl(InputBuffer
,
1008 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1011 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1012 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1014 if (InputMdl
&& OutputMdl
) {
1016 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1019 InputMdlLocked
= TRUE
;
1021 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1024 OutputMdlLocked
= TRUE
;
1026 RtlCopyMemory(&QueryContext
->QueryInfo
,
1027 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1030 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1032 } except(EXCEPTION_EXECUTE_HANDLER
) {
1033 Status
= GetExceptionCode();
1036 if (NT_SUCCESS(Status
)) {
1037 Size
= MmGetMdlByteCount(OutputMdl
);
1039 QueryContext
->Irp
= Irp
;
1040 QueryContext
->InputMdl
= InputMdl
;
1041 QueryContext
->OutputMdl
= OutputMdl
;
1043 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1044 Request
.RequestContext
= QueryContext
;
1045 Status
= InfoTdiQueryInformationEx(&Request
,
1046 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1047 &Size
, &QueryContext
->QueryInfo
.Context
);
1048 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1050 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1055 /* An error occurred if we get here */
1059 MmUnlockPages(InputMdl
);
1060 IoFreeMdl(InputMdl
);
1064 if (OutputMdlLocked
)
1065 MmUnlockPages(OutputMdl
);
1066 IoFreeMdl(OutputMdl
);
1069 ExFreePool(QueryContext
);
1071 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1073 Status
= STATUS_INVALID_PARAMETER
;
1075 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1081 NTSTATUS
DispTdiSetInformationEx(
1083 PIO_STACK_LOCATION IrpSp
)
1085 * FUNCTION: TDI SetInformationEx handler
1087 * Irp = Pointer to I/O request packet
1088 * IrpSp = Pointer to current stack location of Irp
1090 * Status of operation
1093 PTRANSPORT_CONTEXT TranContext
;
1094 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1095 TDI_REQUEST Request
;
1099 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1101 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1102 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1104 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1105 case TDI_TRANSPORT_ADDRESS_FILE
:
1106 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1109 case TDI_CONNECTION_FILE
:
1110 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1113 case TDI_CONTROL_CHANNEL_FILE
:
1114 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1118 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1119 Irp
->IoStatus
.Information
= 0;
1121 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1123 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
1125 return STATUS_INVALID_PARAMETER
;
1128 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1129 if (NT_SUCCESS(Status
)) {
1130 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1131 Request
.RequestContext
= Irp
;
1133 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1134 &Info
->Buffer
, Info
->BufferSize
);
1136 if (Status
!= STATUS_PENDING
) {
1137 IoAcquireCancelSpinLock(&OldIrql
);
1138 IoSetCancelRoutine(Irp
, NULL
);
1139 IoReleaseCancelSpinLock(OldIrql
);