3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS TCP/IP protocol driver
5 * FILE: tcpip/dispatch.h
6 * PURPOSE: TDI dispatch routines
7 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 * CSH 01/08-2000 Created
10 * TODO: Validate device object in all dispatch routines
16 NTSTATUS
DispPrepareIrpForCancel(
17 PTRANSPORT_CONTEXT Context
,
19 PDRIVER_CANCEL CancelRoutine
)
21 * FUNCTION: Prepare an IRP for cancellation
23 * Context = Pointer to context information
24 * Irp = Pointer to an I/O request packet
25 * CancelRoutine = Routine to be called when I/O request is cancelled
32 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
34 IoAcquireCancelSpinLock(&OldIrql
);
37 IoMarkIrpPending(Irp
);
38 IoSetCancelRoutine(Irp
, CancelRoutine
);
39 IoReleaseCancelSpinLock(OldIrql
);
41 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
43 return STATUS_SUCCESS
;
46 /* IRP has already been cancelled */
48 IoReleaseCancelSpinLock(OldIrql
);
50 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
51 Irp
->IoStatus
.Information
= 0;
53 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
55 return IRPFinish(Irp
, STATUS_CANCELLED
);
59 VOID
DispCancelComplete(
62 * FUNCTION: Completes a cancel request
64 * Context = Pointer to context information (FILE_OBJECT)
68 PFILE_OBJECT FileObject
;
69 PTRANSPORT_CONTEXT TranContext
;
71 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
73 FileObject
= (PFILE_OBJECT
)Context
;
74 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
76 /* Set the cleanup event */
77 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
79 /* We are expected to release the cancel spin lock */
80 IoReleaseCancelSpinLock(OldIrql
);
82 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
86 VOID DDKAPI
DispCancelRequest(
87 PDEVICE_OBJECT Device
,
90 * FUNCTION: Cancels an IRP
92 * Device = Pointer to device object
93 * Irp = Pointer to an I/O request packet
96 PIO_STACK_LOCATION IrpSp
;
97 PTRANSPORT_CONTEXT TranContext
;
98 PFILE_OBJECT FileObject
;
100 NTSTATUS Status
= STATUS_SUCCESS
;
102 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
104 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
105 FileObject
= IrpSp
->FileObject
;
106 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
107 MinorFunction
= IrpSp
->MinorFunction
;
109 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
113 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
116 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
118 /* Try canceling the request */
119 switch(MinorFunction
) {
122 /* FIXME: Close connection */
125 case TDI_SEND_DATAGRAM
:
126 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
127 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
131 /*DGCancelSendRequest(TranContext->Handle.AddressHandle, Irp);*/
134 case TDI_RECEIVE_DATAGRAM
:
135 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
136 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
140 /*DGCancelReceiveRequest(TranContext->Handle.AddressHandle, Irp);*/
144 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
148 if (Status
!= STATUS_PENDING
)
149 DispCancelComplete(FileObject
);
151 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
154 VOID
DispDataRequestComplete(
159 * FUNCTION: Completes a send/receive IRP
161 * Context = Pointer to context information (IRP)
162 * Status = Status of the request
163 * Count = Number of bytes sent or received
167 PIO_STACK_LOCATION IrpSp
;
168 PTRANSPORT_CONTEXT TranContext
;
171 TI_DbgPrint(DEBUG_IRP
, ("Called for irp %x (%x, %d).\n",
172 Context
, Status
, Count
));
175 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
176 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
178 IoAcquireCancelSpinLock(&OldIrql
);
180 IoSetCancelRoutine(Irp
, NULL
);
182 if (Irp
->Cancel
|| TranContext
->CancelIrps
) {
183 /* The IRP has been cancelled */
185 TI_DbgPrint(DEBUG_IRP
, ("IRP is cancelled.\n"));
187 Status
= STATUS_CANCELLED
;
191 IoReleaseCancelSpinLock(OldIrql
);
193 Irp
->IoStatus
.Status
= Status
;
194 Irp
->IoStatus
.Information
= Count
;
196 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
197 Irp
->IoStatus
.Status
));
198 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
199 Irp
->IoStatus
.Information
));
200 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
202 IRPFinish(Irp
, Irp
->IoStatus
.Status
);
204 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
208 NTSTATUS
DispTdiAccept(
211 * FUNCTION: TDI_ACCEPT handler
213 * Irp = Pointer to an I/O request packet
215 * Status of operation
218 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
220 return STATUS_NOT_IMPLEMENTED
;
224 NTSTATUS
DispTdiAssociateAddress(
227 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
229 * Irp = Pointer to an I/O request packet
231 * Status of operation
234 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
235 PTRANSPORT_CONTEXT TranContext
;
236 PIO_STACK_LOCATION IrpSp
;
237 PCONNECTION_ENDPOINT Connection
;
238 PFILE_OBJECT FileObject
;
239 PADDRESS_FILE AddrFile
= NULL
;
242 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
244 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
246 /* Get associated connection endpoint file object. Quit if none exists */
248 TranContext
= IrpSp
->FileObject
->FsContext
;
250 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
251 return STATUS_INVALID_PARAMETER
;
254 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
256 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
257 return STATUS_INVALID_PARAMETER
;
260 if (Connection
->AddressFile
) {
261 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
262 return STATUS_INVALID_PARAMETER
;
265 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
267 Status
= ObReferenceObjectByHandle(
268 Parameters
->AddressHandle
,
274 if (!NT_SUCCESS(Status
)) {
275 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X).\n",
276 Parameters
->AddressHandle
));
277 return STATUS_INVALID_PARAMETER
;
280 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
281 ObDereferenceObject(FileObject
);
282 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
283 FileObject
->FsContext2
));
284 return STATUS_INVALID_PARAMETER
;
287 /* Get associated address file object. Quit if none exists */
289 TranContext
= FileObject
->FsContext
;
291 ObDereferenceObject(FileObject
);
292 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
293 return STATUS_INVALID_PARAMETER
;
296 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
298 ObDereferenceObject(FileObject
);
299 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
300 return STATUS_INVALID_PARAMETER
;
303 Connection
->AddressFile
= AddrFile
;
305 /* Add connection endpoint to the address file */
306 AddrFile
->Connection
= Connection
;
308 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
309 ObDereferenceObject(FileObject
);
315 NTSTATUS
DispTdiConnect(
318 * FUNCTION: TDI_CONNECT handler
320 * Irp = Pointer to an I/O request packet
322 * Status of operation
325 PCONNECTION_ENDPOINT Connection
;
326 PTDI_REQUEST_KERNEL Parameters
;
327 PTRANSPORT_CONTEXT TranContext
;
328 PIO_STACK_LOCATION IrpSp
;
331 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
333 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
335 /* Get associated connection endpoint file object. Quit if none exists */
337 TranContext
= IrpSp
->FileObject
->FsContext
;
339 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
340 return STATUS_INVALID_CONNECTION
;
343 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
345 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
346 return STATUS_INVALID_CONNECTION
;
349 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
352 TranContext
->Handle
.ConnectionContext
,
353 Parameters
->RequestConnectionInformation
,
354 Parameters
->ReturnConnectionInformation
,
355 DispDataRequestComplete
,
358 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
364 NTSTATUS
DispTdiDisassociateAddress(
367 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
369 * Irp = Pointer to an I/O request packet
371 * Status of operation
374 PCONNECTION_ENDPOINT Connection
;
375 PTRANSPORT_CONTEXT TranContext
;
376 PIO_STACK_LOCATION IrpSp
;
378 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
380 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
382 /* Get associated connection endpoint file object. Quit if none exists */
384 TranContext
= IrpSp
->FileObject
->FsContext
;
386 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
387 return STATUS_INVALID_PARAMETER
;
390 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
392 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
393 return STATUS_INVALID_PARAMETER
;
396 if (!Connection
->AddressFile
) {
397 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
398 return STATUS_INVALID_PARAMETER
;
401 return STATUS_SUCCESS
;
405 NTSTATUS
DispTdiDisconnect(
408 * FUNCTION: TDI_DISCONNECT handler
410 * Irp = Pointer to an I/O request packet
412 * Status of operation
416 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
417 PCONNECTION_ENDPOINT Connection
;
418 PTRANSPORT_CONTEXT TranContext
;
419 PIO_STACK_LOCATION IrpSp
;
421 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
423 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
424 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
426 /* Get associated connection endpoint file object. Quit if none exists */
428 TranContext
= IrpSp
->FileObject
->FsContext
;
430 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
431 return STATUS_INVALID_CONNECTION
;
434 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
436 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
437 return STATUS_INVALID_CONNECTION
;
440 Status
= TCPDisconnect(
441 TranContext
->Handle
.ConnectionContext
,
442 DisReq
->RequestFlags
,
443 DisReq
->RequestConnectionInformation
,
444 DisReq
->ReturnConnectionInformation
,
445 DispDataRequestComplete
,
448 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
454 NTSTATUS
DispTdiListen(
457 * FUNCTION: TDI_LISTEN handler
459 * Irp = Pointer to an I/O request packet
461 * Status of operation
464 PCONNECTION_ENDPOINT Connection
;
465 PTDI_REQUEST_KERNEL Parameters
;
466 PTRANSPORT_CONTEXT TranContext
;
467 PIO_STACK_LOCATION IrpSp
;
470 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
472 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
474 /* Get associated connection endpoint file object. Quit if none exists */
476 TranContext
= IrpSp
->FileObject
->FsContext
;
477 if (TranContext
== NULL
)
479 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
480 return STATUS_INVALID_CONNECTION
;
483 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
484 if (Connection
== NULL
)
486 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
487 return STATUS_INVALID_CONNECTION
;
490 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
492 Status
= TCPListen( Connection
, 1024 /* BACKLOG */,
493 DispDataRequestComplete
,
500 NTSTATUS
DispTdiQueryInformation(
501 PDEVICE_OBJECT DeviceObject
,
504 * FUNCTION: TDI_QUERY_INFORMATION handler
506 * DeviceObject = Pointer to device object structure
507 * Irp = Pointer to an I/O request packet
509 * Status of operation
512 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
513 PTRANSPORT_CONTEXT TranContext
;
514 PIO_STACK_LOCATION IrpSp
;
516 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
518 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
519 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
521 TranContext
= IrpSp
->FileObject
->FsContext
;
523 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
524 return STATUS_INVALID_CONNECTION
;
527 switch (Parameters
->QueryType
)
529 case TDI_QUERY_ADDRESS_INFO
:
531 PTDI_ADDRESS_INFO AddressInfo
;
532 PADDRESS_FILE AddrFile
;
533 PTA_IP_ADDRESS Address
;
535 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
537 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
538 case TDI_TRANSPORT_ADDRESS_FILE
:
539 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
542 case TDI_CONNECTION_FILE
:
543 AddrFile
= ((PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
)->AddressFile
;
547 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
548 return STATUS_INVALID_PARAMETER
;
552 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
553 return STATUS_INVALID_PARAMETER
;
556 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
557 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
558 sizeof(TDI_ADDRESS_IP
))) {
559 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
560 return STATUS_BUFFER_OVERFLOW
;
563 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
564 Address
->TAAddressCount
= 1;
565 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
566 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
567 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
568 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->Address
.Address
.IPv4Address
;
570 &Address
->Address
[0].Address
[0].sin_zero
,
571 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
573 return STATUS_SUCCESS
;
577 return STATUS_NOT_IMPLEMENTED
;
581 NTSTATUS
DispTdiReceive(
584 * FUNCTION: TDI_RECEIVE handler
586 * Irp = Pointer to an I/O request packet
588 * Status of operation
591 PIO_STACK_LOCATION IrpSp
;
592 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
593 PTRANSPORT_CONTEXT TranContext
;
597 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
599 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
600 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
602 TranContext
= IrpSp
->FileObject
->FsContext
;
603 if (TranContext
== NULL
)
605 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
606 return STATUS_INVALID_CONNECTION
;
609 if (TranContext
->Handle
.ConnectionContext
== NULL
)
611 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
612 return STATUS_INVALID_CONNECTION
;
615 /* Initialize a receive request */
616 Status
= DispPrepareIrpForCancel
617 (TranContext
->Handle
.ConnectionContext
,
619 (PDRIVER_CANCEL
)DispCancelRequest
);
621 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
622 if (NT_SUCCESS(Status
))
624 Status
= TCPReceiveData(
625 TranContext
->Handle
.ConnectionContext
,
626 (PNDIS_BUFFER
)Irp
->MdlAddress
,
627 ReceiveInfo
->ReceiveLength
,
629 ReceiveInfo
->ReceiveFlags
,
630 DispDataRequestComplete
,
632 if (Status
!= STATUS_PENDING
)
634 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
636 IoMarkIrpPending(Irp
);
639 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
645 NTSTATUS
DispTdiReceiveDatagram(
648 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
650 * Irp = Pointer to an I/O request packet
652 * Status of operation
655 PIO_STACK_LOCATION IrpSp
;
656 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
657 PTRANSPORT_CONTEXT TranContext
;
662 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
664 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
665 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
667 TranContext
= IrpSp
->FileObject
->FsContext
;
668 if (TranContext
== NULL
)
670 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
671 return STATUS_INVALID_ADDRESS
;
674 /* Initialize a receive request */
675 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
676 Request
.RequestNotifyObject
= DispDataRequestComplete
;
677 Request
.RequestContext
= Irp
;
679 Status
= DispPrepareIrpForCancel(
680 IrpSp
->FileObject
->FsContext
,
682 (PDRIVER_CANCEL
)DispCancelRequest
);
684 if (NT_SUCCESS(Status
))
689 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
693 Status
= UDPReceiveDatagram(
694 Request
.Handle
.AddressHandle
,
695 DgramInfo
->ReceiveDatagramInformation
->RemoteAddress
,
697 DgramInfo
->ReceiveLength
,
698 DgramInfo
->ReceiveFlags
,
699 DgramInfo
->ReturnDatagramInformation
->RemoteAddress
,
701 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
703 if (Status
!= STATUS_PENDING
) {
704 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
706 IoMarkIrpPending(Irp
);
709 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
715 NTSTATUS
DispTdiSend(
718 * FUNCTION: TDI_SEND handler
720 * Irp = Pointer to an I/O request packet
722 * Status of operation
725 PIO_STACK_LOCATION IrpSp
;
726 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
727 PTRANSPORT_CONTEXT TranContext
;
731 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
733 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
734 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
736 TranContext
= IrpSp
->FileObject
->FsContext
;
737 if (TranContext
== NULL
)
739 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
740 return STATUS_INVALID_CONNECTION
;
743 if (TranContext
->Handle
.ConnectionContext
== NULL
)
745 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
746 return STATUS_INVALID_CONNECTION
;
749 Status
= DispPrepareIrpForCancel(
750 IrpSp
->FileObject
->FsContext
,
752 (PDRIVER_CANCEL
)DispCancelRequest
);
754 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
755 if (NT_SUCCESS(Status
))
760 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
762 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
763 Status
= TCPSendData(
764 TranContext
->Handle
.ConnectionContext
,
766 ReceiveInfo
->ReceiveLength
,
768 ReceiveInfo
->ReceiveFlags
);
769 if (Status
!= STATUS_PENDING
)
771 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
773 IoMarkIrpPending( Irp
);
776 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
782 NTSTATUS
DispTdiSendDatagram(
785 * FUNCTION: TDI_SEND_DATAGRAM handler
787 * Irp = Pointer to an I/O request packet
789 * Status of operation
792 PIO_STACK_LOCATION IrpSp
;
794 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
795 PTRANSPORT_CONTEXT TranContext
;
798 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
800 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
801 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
802 TranContext
= IrpSp
->FileObject
->FsContext
;
804 /* Initialize a send request */
805 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
806 Request
.RequestNotifyObject
= DispDataRequestComplete
;
807 Request
.RequestContext
= Irp
;
809 Status
= DispPrepareIrpForCancel(
810 IrpSp
->FileObject
->FsContext
,
812 (PDRIVER_CANCEL
)DispCancelRequest
);
814 if (NT_SUCCESS(Status
)) {
818 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
820 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
824 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
825 must be of type PTDI_ADDRESS_IP */
826 TI_DbgPrint(MID_TRACE
,
827 ("About to call send routine %x\n",
828 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
830 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
831 Request
.Handle
.AddressHandle
,
832 DgramInfo
->SendDatagramInformation
,
835 &Irp
->IoStatus
.Information
);
837 if (Status
!= STATUS_PENDING
) {
838 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
839 /* Return STATUS_PENDING because DispPrepareIrpForCancel
840 marks Irp as pending */
841 Status
= STATUS_PENDING
;
843 IoMarkIrpPending( Irp
);
846 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
852 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
854 * FUNCTION: TDI_SET_EVENT_HANDER handler
856 * Irp = Pointer to a I/O request packet
858 * Status of operation
861 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
862 PTRANSPORT_CONTEXT TranContext
;
863 PIO_STACK_LOCATION IrpSp
;
864 PADDRESS_FILE AddrFile
;
868 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
870 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
872 /* Get associated address file object. Quit if none exists */
874 TranContext
= IrpSp
->FileObject
->FsContext
;
876 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
877 return STATUS_INVALID_PARAMETER
;
880 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
882 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
883 return STATUS_INVALID_PARAMETER
;
886 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
887 Status
= STATUS_SUCCESS
;
889 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
891 /* Set the event handler. if an event handler is associated with
892 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
893 If an event handler is not used it's flag is FALSE */
894 switch (Parameters
->EventType
) {
895 case TDI_EVENT_CONNECT
:
896 if (!Parameters
->EventHandler
) {
897 AddrFile
->ConnectHandlerContext
= NULL
;
898 AddrFile
->RegisteredConnectHandler
= FALSE
;
900 AddrFile
->ConnectHandler
=
901 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
902 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
903 AddrFile
->RegisteredConnectHandler
= TRUE
;
907 case TDI_EVENT_DISCONNECT
:
908 if (!Parameters
->EventHandler
) {
909 AddrFile
->DisconnectHandlerContext
= NULL
;
910 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
912 AddrFile
->DisconnectHandler
=
913 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
914 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
915 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
919 case TDI_EVENT_ERROR
:
920 if (Parameters
->EventHandler
== NULL
) {
921 AddrFile
->ErrorHandlerContext
= NULL
;
922 AddrFile
->RegisteredErrorHandler
= FALSE
;
924 AddrFile
->ErrorHandler
=
925 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
926 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
927 AddrFile
->RegisteredErrorHandler
= TRUE
;
931 case TDI_EVENT_RECEIVE
:
932 if (Parameters
->EventHandler
== NULL
) {
933 AddrFile
->ReceiveHandlerContext
= NULL
;
934 AddrFile
->RegisteredReceiveHandler
= FALSE
;
936 AddrFile
->ReceiveHandler
=
937 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
938 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
939 AddrFile
->RegisteredReceiveHandler
= TRUE
;
943 case TDI_EVENT_RECEIVE_DATAGRAM
:
944 if (Parameters
->EventHandler
== NULL
) {
945 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
946 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
948 AddrFile
->ReceiveDatagramHandler
=
949 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
950 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
951 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
955 case TDI_EVENT_RECEIVE_EXPEDITED
:
956 if (Parameters
->EventHandler
== NULL
) {
957 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
958 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
960 AddrFile
->ExpeditedReceiveHandler
=
961 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
962 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
963 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
967 case TDI_EVENT_CHAINED_RECEIVE
:
968 if (Parameters
->EventHandler
== NULL
) {
969 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
970 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
972 AddrFile
->ChainedReceiveHandler
=
973 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
974 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
975 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
979 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
980 if (Parameters
->EventHandler
== NULL
) {
981 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
982 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
984 AddrFile
->ChainedReceiveDatagramHandler
=
985 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
986 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
987 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
991 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
992 if (Parameters
->EventHandler
== NULL
) {
993 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
994 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
996 AddrFile
->ChainedReceiveExpeditedHandler
=
997 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
998 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
999 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1004 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1005 Parameters
->EventType
));
1007 Status
= STATUS_INVALID_PARAMETER
;
1010 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1016 NTSTATUS
DispTdiSetInformation(
1019 * FUNCTION: TDI_SET_INFORMATION handler
1021 * Irp = Pointer to an I/O request packet
1023 * Status of operation
1026 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1028 return STATUS_NOT_IMPLEMENTED
;
1032 VOID
DispTdiQueryInformationExComplete(
1037 * FUNCTION: Completes a TDI QueryInformationEx request
1039 * Context = Pointer to the IRP for the request
1040 * Status = TDI status of the request
1041 * ByteCount = Number of bytes returned in output buffer
1044 PTI_QUERY_CONTEXT QueryContext
;
1047 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1048 if (NT_SUCCESS(Status
)) {
1049 Count
= CopyBufferToBufferChain(
1050 QueryContext
->InputMdl
,
1051 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1052 (PUCHAR
)&QueryContext
->QueryInfo
.Context
,
1056 MmUnlockPages(QueryContext
->InputMdl
);
1057 IoFreeMdl(QueryContext
->InputMdl
);
1058 if( QueryContext
->OutputMdl
) {
1059 MmUnlockPages(QueryContext
->OutputMdl
);
1060 IoFreeMdl(QueryContext
->OutputMdl
);
1063 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1064 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1066 ExFreePool(QueryContext
);
1070 NTSTATUS
DispTdiQueryInformationEx(
1072 PIO_STACK_LOCATION IrpSp
)
1074 * FUNCTION: TDI QueryInformationEx handler
1076 * Irp = Pointer to I/O request packet
1077 * IrpSp = Pointer to current stack location of Irp
1079 * Status of operation
1082 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1083 PTRANSPORT_CONTEXT TranContext
;
1084 PTI_QUERY_CONTEXT QueryContext
;
1086 TDI_REQUEST Request
;
1088 UINT InputBufferLength
;
1089 UINT OutputBufferLength
;
1090 BOOLEAN InputMdlLocked
= FALSE
;
1091 BOOLEAN OutputMdlLocked
= FALSE
;
1092 PMDL InputMdl
= NULL
;
1093 PMDL OutputMdl
= NULL
;
1094 NTSTATUS Status
= STATUS_SUCCESS
;
1096 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1098 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1100 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1101 case TDI_TRANSPORT_ADDRESS_FILE
:
1102 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1105 case TDI_CONNECTION_FILE
:
1106 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1109 case TDI_CONTROL_CHANNEL_FILE
:
1110 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1114 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1115 return STATUS_INVALID_PARAMETER
;
1118 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1119 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1121 /* Validate parameters */
1122 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1123 (OutputBufferLength
!= 0)) {
1125 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1126 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1127 OutputBuffer
= Irp
->UserBuffer
;
1129 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1132 InputMdl
= IoAllocateMdl(InputBuffer
,
1133 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1136 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1137 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1139 if (InputMdl
&& OutputMdl
) {
1141 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1144 InputMdlLocked
= TRUE
;
1146 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1149 OutputMdlLocked
= TRUE
;
1151 RtlCopyMemory(&QueryContext
->QueryInfo
,
1152 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1154 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1156 Status
= _SEH_GetExceptionCode();
1159 if (NT_SUCCESS(Status
)) {
1160 Size
= MmGetMdlByteCount(OutputMdl
);
1162 QueryContext
->Irp
= Irp
;
1163 QueryContext
->InputMdl
= InputMdl
;
1164 QueryContext
->OutputMdl
= OutputMdl
;
1166 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1167 Request
.RequestContext
= QueryContext
;
1168 Status
= InfoTdiQueryInformationEx(&Request
,
1169 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1170 &Size
, &QueryContext
->QueryInfo
.Context
);
1171 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1173 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1178 /* An error occurred if we get here */
1182 MmUnlockPages(InputMdl
);
1183 IoFreeMdl(InputMdl
);
1187 if (OutputMdlLocked
)
1188 MmUnlockPages(OutputMdl
);
1189 IoFreeMdl(OutputMdl
);
1192 ExFreePool(QueryContext
);
1194 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1195 } else if( InputBufferLength
==
1196 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1197 /* Handle the case where the user is probing the buffer for length */
1198 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1199 InputBufferLength
, OutputBufferLength
));
1200 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1201 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1205 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1206 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1209 InputMdl
= IoAllocateMdl(InputBuffer
,
1210 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1213 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1216 InputMdlLocked
= TRUE
;
1217 Status
= STATUS_SUCCESS
;
1219 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1220 Status
= _SEH_GetExceptionCode();
1223 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1224 if( InputMdl
) IoFreeMdl( InputMdl
);
1225 ExFreePool(QueryContext
);
1229 RtlCopyMemory(&QueryContext
->QueryInfo
,
1230 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1232 QueryContext
->Irp
= Irp
;
1233 QueryContext
->InputMdl
= InputMdl
;
1234 QueryContext
->OutputMdl
= NULL
;
1236 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1237 Request
.RequestContext
= QueryContext
;
1238 Status
= InfoTdiQueryInformationEx(&Request
,
1239 &QueryContext
->QueryInfo
.ID
,
1242 &QueryContext
->QueryInfo
.Context
);
1243 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1244 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1245 } else Status
= STATUS_INVALID_PARAMETER
;
1247 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1253 NTSTATUS
DispTdiSetInformationEx(
1255 PIO_STACK_LOCATION IrpSp
)
1257 * FUNCTION: TDI SetInformationEx handler
1259 * Irp = Pointer to I/O request packet
1260 * IrpSp = Pointer to current stack location of Irp
1262 * Status of operation
1265 PTRANSPORT_CONTEXT TranContext
;
1266 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1267 TDI_REQUEST Request
;
1271 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1273 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1274 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1276 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1277 case TDI_TRANSPORT_ADDRESS_FILE
:
1278 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1281 case TDI_CONNECTION_FILE
:
1282 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1285 case TDI_CONTROL_CHANNEL_FILE
:
1286 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1290 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1291 Irp
->IoStatus
.Information
= 0;
1293 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1295 return IRPFinish(Irp
, STATUS_INVALID_PARAMETER
);
1298 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1299 if (NT_SUCCESS(Status
)) {
1300 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1301 Request
.RequestContext
= Irp
;
1303 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1304 &Info
->Buffer
, Info
->BufferSize
);
1306 if (Status
!= STATUS_PENDING
) {
1307 IoAcquireCancelSpinLock(&OldIrql
);
1308 IoSetCancelRoutine(Irp
, NULL
);
1309 IoReleaseCancelSpinLock(OldIrql
);