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
14 NTSTATUS
DispPrepareIrpForCancel(
15 PTRANSPORT_CONTEXT Context
,
17 PDRIVER_CANCEL CancelRoutine
)
19 * FUNCTION: Prepare an IRP for cancellation
21 * Context = Pointer to context information
22 * Irp = Pointer to an I/O request packet
23 * CancelRoutine = Routine to be called when I/O request is cancelled
30 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
32 IoAcquireCancelSpinLock(&OldIrql
);
35 IoMarkIrpPending(Irp
);
36 IoSetCancelRoutine(Irp
, CancelRoutine
);
37 IoReleaseCancelSpinLock(OldIrql
);
39 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
41 return STATUS_SUCCESS
;
44 /* IRP has already been cancelled */
46 IoReleaseCancelSpinLock(OldIrql
);
48 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
49 Irp
->IoStatus
.Information
= 0;
51 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
53 return IRPFinish(Irp
, STATUS_CANCELLED
);
57 VOID
DispCancelComplete(
60 * FUNCTION: Completes a cancel request
62 * Context = Pointer to context information (FILE_OBJECT)
66 PFILE_OBJECT FileObject
;
67 PTRANSPORT_CONTEXT TranContext
;
69 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
71 FileObject
= (PFILE_OBJECT
)Context
;
72 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
74 IoAcquireCancelSpinLock(&OldIrql
);
76 TI_DbgPrint(DEBUG_IRP
, ("Setting TranContext->CleanupEvent to signaled.\n"));
77 /* Set the cleanup event */
78 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
80 IoReleaseCancelSpinLock(OldIrql
);
82 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
86 VOID
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 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
184 if (Irp
->Cancel
|| TranContext
->CancelIrps
) {
185 /* The IRP has been cancelled */
187 TI_DbgPrint(DEBUG_IRP
, ("IRP is cancelled.\n"));
189 Status
= STATUS_CANCELLED
;
193 IoReleaseCancelSpinLock(OldIrql
);
195 Irp
->IoStatus
.Status
= Status
;
196 Irp
->IoStatus
.Information
= Count
;
198 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
199 Irp
->IoStatus
.Status
));
200 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
201 Irp
->IoStatus
.Information
));
202 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
204 IRPFinish(Irp
, Irp
->IoStatus
.Status
);
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
415 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
416 PTRANSPORT_CONTEXT TranContext
;
417 PIO_STACK_LOCATION IrpSp
;
419 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
421 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
422 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
424 TranContext
= IrpSp
->FileObject
->FsContext
;
426 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
427 return STATUS_INVALID_CONNECTION
;
430 switch (Parameters
->QueryType
)
432 case TDI_QUERY_ADDRESS_INFO
:
434 PTDI_ADDRESS_INFO AddressInfo
;
435 PADDRESS_FILE AddrFile
;
436 PTA_IP_ADDRESS Address
;
438 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
440 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
441 case TDI_TRANSPORT_ADDRESS_FILE
:
442 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
445 case TDI_CONNECTION_FILE
:
446 AddrFile
= ((PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
)->AddressFile
;
450 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
451 return STATUS_INVALID_PARAMETER
;
455 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
456 return STATUS_INVALID_PARAMETER
;
459 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
460 (sizeof(TDI_ADDRESS_INFO
) + sizeof(TDI_ADDRESS_IP
))) {
461 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
462 return STATUS_BUFFER_OVERFLOW
;
465 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
466 Address
->TAAddressCount
= 1;
467 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
468 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
469 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
470 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->ADE
->Address
->Address
.IPv4Address
;
472 &Address
->Address
[0].Address
[0].sin_zero
,
473 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
475 return STATUS_SUCCESS
;
479 return STATUS_NOT_IMPLEMENTED
;
483 NTSTATUS
DispTdiListen(
486 * FUNCTION: TDI_LISTEN handler
488 * Irp = Pointer to an I/O request packet
490 * Status of operation
493 PCONNECTION_ENDPOINT Connection
;
494 PTDI_REQUEST_KERNEL Parameters
;
495 PTRANSPORT_CONTEXT TranContext
;
496 PIO_STACK_LOCATION IrpSp
;
497 PTDI_REQUEST Request
;
500 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
502 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
504 /* Get associated connection endpoint file object. Quit if none exists */
506 TranContext
= IrpSp
->FileObject
->FsContext
;
507 if (TranContext
== NULL
)
509 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
510 return STATUS_INVALID_CONNECTION
;
513 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
514 if (Connection
== NULL
)
516 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
517 return STATUS_INVALID_CONNECTION
;
520 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
522 Status
= TCPListen( Request
->Handle
.ConnectionContext
, 1024 /* BACKLOG */,
523 DispDataRequestComplete
,
530 NTSTATUS
DispTdiQueryInformation(
531 PDEVICE_OBJECT DeviceObject
,
534 * FUNCTION: TDI_QUERY_INFORMATION handler
536 * DeviceObject = Pointer to device object structure
537 * Irp = Pointer to an I/O request packet
539 * Status of operation
542 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
543 PTRANSPORT_CONTEXT TranContext
;
544 PIO_STACK_LOCATION IrpSp
;
546 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
548 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
549 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
551 TranContext
= IrpSp
->FileObject
->FsContext
;
553 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
554 return STATUS_INVALID_CONNECTION
;
557 switch (Parameters
->QueryType
)
559 case TDI_QUERY_ADDRESS_INFO
:
561 PTDI_ADDRESS_INFO AddressInfo
;
562 PADDRESS_FILE AddrFile
;
563 PTA_IP_ADDRESS Address
;
565 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
567 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
568 case TDI_TRANSPORT_ADDRESS_FILE
:
569 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
572 case TDI_CONNECTION_FILE
:
573 AddrFile
= ((PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
)->AddressFile
;
577 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
578 return STATUS_INVALID_PARAMETER
;
582 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
583 return STATUS_INVALID_PARAMETER
;
586 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
587 (sizeof(TDI_ADDRESS_INFO
) + sizeof(TDI_ADDRESS_IP
))) {
588 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
589 return STATUS_BUFFER_OVERFLOW
;
592 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
593 Address
->TAAddressCount
= 1;
594 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
595 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
596 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
597 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->ADE
->Address
->Address
.IPv4Address
;
599 &Address
->Address
[0].Address
[0].sin_zero
,
600 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
602 return STATUS_SUCCESS
;
606 return STATUS_NOT_IMPLEMENTED
;
610 NTSTATUS
DispTdiReceive(
613 * FUNCTION: TDI_RECEIVE handler
615 * Irp = Pointer to an I/O request packet
617 * Status of operation
620 PIO_STACK_LOCATION IrpSp
;
621 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
622 PTRANSPORT_CONTEXT TranContext
;
626 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
628 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
629 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
631 TranContext
= IrpSp
->FileObject
->FsContext
;
632 if (TranContext
== NULL
)
634 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
635 return STATUS_INVALID_CONNECTION
;
638 if (TranContext
->Handle
.ConnectionContext
== NULL
)
640 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
641 return STATUS_INVALID_CONNECTION
;
644 /* Initialize a receive request */
645 Status
= DispPrepareIrpForCancel(
646 IrpSp
->FileObject
->FsContext
,
648 (PDRIVER_CANCEL
)DispCancelRequest
);
649 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
650 if (NT_SUCCESS(Status
))
652 Status
= TCPReceiveData(
653 TranContext
->Handle
.ConnectionContext
,
654 (PNDIS_BUFFER
)Irp
->MdlAddress
,
655 ReceiveInfo
->ReceiveLength
,
657 ReceiveInfo
->ReceiveFlags
,
658 DispDataRequestComplete
,
660 if (Status
!= STATUS_PENDING
)
663 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
667 if (Status
!= STATUS_PENDING
)
669 IrpSp
->Control
&= ~SL_PENDING_RETURNED
;
672 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
678 NTSTATUS
DispTdiReceiveDatagram(
681 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
683 * Irp = Pointer to an I/O request packet
685 * Status of operation
688 PIO_STACK_LOCATION IrpSp
;
689 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
690 PTRANSPORT_CONTEXT TranContext
;
695 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
697 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
698 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
700 TranContext
= IrpSp
->FileObject
->FsContext
;
701 if (TranContext
== NULL
)
703 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
704 return STATUS_INVALID_ADDRESS
;
707 /* Initialize a receive request */
708 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
709 Request
.RequestNotifyObject
= DispDataRequestComplete
;
710 Request
.RequestContext
= Irp
;
711 Status
= DispPrepareIrpForCancel(
712 IrpSp
->FileObject
->FsContext
,
714 (PDRIVER_CANCEL
)DispCancelRequest
);
715 if (NT_SUCCESS(Status
))
720 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
724 Status
= UDPReceiveDatagram(
725 Request
.Handle
.AddressHandle
,
726 DgramInfo
->ReceiveDatagramInformation
,
728 DgramInfo
->ReceiveLength
,
729 DgramInfo
->ReceiveFlags
,
730 DgramInfo
->ReturnDatagramInformation
,
732 if (Status
!= STATUS_PENDING
)
734 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
738 if (Status
!= STATUS_PENDING
)
740 IrpSp
->Control
&= ~SL_PENDING_RETURNED
;
743 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
749 NTSTATUS
DispTdiSend(
752 * FUNCTION: TDI_SEND handler
754 * Irp = Pointer to an I/O request packet
756 * Status of operation
759 PIO_STACK_LOCATION IrpSp
;
760 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
761 PTRANSPORT_CONTEXT TranContext
;
765 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
767 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
768 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
770 TranContext
= IrpSp
->FileObject
->FsContext
;
771 if (TranContext
== NULL
)
773 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
774 return STATUS_INVALID_CONNECTION
;
777 if (TranContext
->Handle
.ConnectionContext
== NULL
)
779 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
780 return STATUS_INVALID_CONNECTION
;
783 Status
= DispPrepareIrpForCancel(
784 IrpSp
->FileObject
->FsContext
,
786 (PDRIVER_CANCEL
)DispCancelRequest
);
787 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
788 if (NT_SUCCESS(Status
))
793 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
795 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
796 Status
= TCPSendData(
797 TranContext
->Handle
.ConnectionContext
,
799 ReceiveInfo
->ReceiveLength
,
801 ReceiveInfo
->ReceiveFlags
);
802 if (Status
!= STATUS_PENDING
)
804 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
808 if (Status
!= STATUS_PENDING
)
810 IrpSp
->Control
&= ~SL_PENDING_RETURNED
;
813 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
819 NTSTATUS
DispTdiSendDatagram(
822 * FUNCTION: TDI_SEND_DATAGRAM handler
824 * Irp = Pointer to an I/O request packet
826 * Status of operation
829 PIO_STACK_LOCATION IrpSp
;
831 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
832 PTRANSPORT_CONTEXT TranContext
;
835 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
837 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
838 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
839 TranContext
= IrpSp
->FileObject
->FsContext
;
841 /* Initialize a send request */
842 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
843 Request
.RequestNotifyObject
= DispDataRequestComplete
;
844 Request
.RequestContext
= Irp
;
846 Status
= DispPrepareIrpForCancel(
847 IrpSp
->FileObject
->FsContext
,
849 (PDRIVER_CANCEL
)DispCancelRequest
);
850 if (NT_SUCCESS(Status
)) {
854 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
856 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
860 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
861 must be of type PTDI_ADDRESS_IP */
862 TI_DbgPrint(MID_TRACE
,
863 ("About to call send routine %x\n",
864 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
866 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
867 Request
.Handle
.AddressHandle
,
868 DgramInfo
->SendDatagramInformation
,
871 &Irp
->IoStatus
.Information
);
873 if (Status
!= STATUS_PENDING
) {
874 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
875 /* Return STATUS_PENDING because DispPrepareIrpForCancel
876 marks Irp as pending */
877 Status
= STATUS_PENDING
;
881 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
887 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
889 * FUNCTION: TDI_SET_EVENT_HANDER handler
891 * Irp = Pointer to a I/O request packet
893 * Status of operation
896 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
897 PTRANSPORT_CONTEXT TranContext
;
898 PIO_STACK_LOCATION IrpSp
;
899 PADDRESS_FILE AddrFile
;
903 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
905 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
907 /* Get associated address file object. Quit if none exists */
909 TranContext
= IrpSp
->FileObject
->FsContext
;
911 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
912 return STATUS_INVALID_PARAMETER
;
915 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
917 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
918 return STATUS_INVALID_PARAMETER
;
921 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
922 Status
= STATUS_SUCCESS
;
924 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
926 /* Set the event handler. if an event handler is associated with
927 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
928 If an event handler is not used it's flag is FALSE */
929 switch (Parameters
->EventType
) {
930 case TDI_EVENT_CONNECT
:
931 if (!Parameters
->EventHandler
) {
932 AddrFile
->ConnectHandlerContext
= NULL
;
933 AddrFile
->RegisteredConnectHandler
= FALSE
;
935 AddrFile
->ConnectHandler
=
936 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
937 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
938 AddrFile
->RegisteredConnectHandler
= TRUE
;
942 case TDI_EVENT_DISCONNECT
:
943 if (!Parameters
->EventHandler
) {
944 AddrFile
->DisconnectHandlerContext
= NULL
;
945 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
947 AddrFile
->DisconnectHandler
=
948 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
949 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
950 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
954 case TDI_EVENT_ERROR
:
955 if (Parameters
->EventHandler
== NULL
) {
956 AddrFile
->ErrorHandlerContext
= NULL
;
957 AddrFile
->RegisteredErrorHandler
= FALSE
;
959 AddrFile
->ErrorHandler
=
960 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
961 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
962 AddrFile
->RegisteredErrorHandler
= TRUE
;
966 case TDI_EVENT_RECEIVE
:
967 if (Parameters
->EventHandler
== NULL
) {
968 AddrFile
->ReceiveHandlerContext
= NULL
;
969 AddrFile
->RegisteredReceiveHandler
= FALSE
;
971 AddrFile
->ReceiveHandler
=
972 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
973 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
974 AddrFile
->RegisteredReceiveHandler
= TRUE
;
978 case TDI_EVENT_RECEIVE_DATAGRAM
:
979 if (Parameters
->EventHandler
== NULL
) {
980 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
981 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
983 AddrFile
->ReceiveDatagramHandler
=
984 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
985 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
986 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
990 case TDI_EVENT_RECEIVE_EXPEDITED
:
991 if (Parameters
->EventHandler
== NULL
) {
992 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
993 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
995 AddrFile
->ExpeditedReceiveHandler
=
996 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
997 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
998 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1002 case TDI_EVENT_CHAINED_RECEIVE
:
1003 if (Parameters
->EventHandler
== NULL
) {
1004 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1005 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1007 AddrFile
->ChainedReceiveHandler
=
1008 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1009 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1010 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1014 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1015 if (Parameters
->EventHandler
== NULL
) {
1016 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1017 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1019 AddrFile
->ChainedReceiveDatagramHandler
=
1020 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1021 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1022 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1026 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1027 if (Parameters
->EventHandler
== NULL
) {
1028 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1029 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1031 AddrFile
->ChainedReceiveExpeditedHandler
=
1032 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1033 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1034 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1039 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1040 Parameters
->EventType
));
1042 Status
= STATUS_INVALID_PARAMETER
;
1045 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1051 NTSTATUS
DispTdiSetInformation(
1054 * FUNCTION: TDI_SET_INFORMATION handler
1056 * Irp = Pointer to an I/O request packet
1058 * Status of operation
1061 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1063 return STATUS_NOT_IMPLEMENTED
;
1067 VOID
DispTdiQueryInformationExComplete(
1072 * FUNCTION: Completes a TDI QueryInformationEx request
1074 * Context = Pointer to the IRP for the request
1075 * Status = TDI status of the request
1076 * ByteCount = Number of bytes returned in output buffer
1079 PTI_QUERY_CONTEXT QueryContext
;
1082 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1083 if (NT_SUCCESS(Status
)) {
1084 Count
= CopyBufferToBufferChain(
1085 QueryContext
->InputMdl
,
1086 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1087 (PUCHAR
)&QueryContext
->QueryInfo
.Context
,
1091 MmUnlockPages(QueryContext
->InputMdl
);
1092 IoFreeMdl(QueryContext
->InputMdl
);
1093 MmUnlockPages(QueryContext
->OutputMdl
);
1094 IoFreeMdl(QueryContext
->OutputMdl
);
1096 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1097 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1099 ExFreePool(QueryContext
);
1103 NTSTATUS
DispTdiQueryInformationEx(
1105 PIO_STACK_LOCATION IrpSp
)
1107 * FUNCTION: TDI QueryInformationEx handler
1109 * Irp = Pointer to I/O request packet
1110 * IrpSp = Pointer to current stack location of Irp
1112 * Status of operation
1115 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1116 PTRANSPORT_CONTEXT TranContext
;
1117 PTI_QUERY_CONTEXT QueryContext
;
1119 TDI_REQUEST Request
;
1121 UINT InputBufferLength
;
1122 UINT OutputBufferLength
;
1123 BOOLEAN InputMdlLocked
= FALSE
;
1124 BOOLEAN OutputMdlLocked
= FALSE
;
1125 PMDL InputMdl
= NULL
;
1126 PMDL OutputMdl
= NULL
;
1127 NTSTATUS Status
= STATUS_SUCCESS
;
1129 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1131 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1133 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1134 case TDI_TRANSPORT_ADDRESS_FILE
:
1135 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1138 case TDI_CONNECTION_FILE
:
1139 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1142 case TDI_CONTROL_CHANNEL_FILE
:
1143 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1147 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1148 return STATUS_INVALID_PARAMETER
;
1151 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1152 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1154 /* Validate parameters */
1155 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1156 (OutputBufferLength
!= 0)) {
1158 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1159 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1160 OutputBuffer
= Irp
->UserBuffer
;
1162 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1167 InputMdl
= IoAllocateMdl(InputBuffer
,
1168 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1171 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1172 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1174 if (InputMdl
&& OutputMdl
) {
1176 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1179 InputMdlLocked
= TRUE
;
1181 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1184 OutputMdlLocked
= TRUE
;
1186 RtlCopyMemory(&QueryContext
->QueryInfo
,
1187 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1190 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1192 } except(EXCEPTION_EXECUTE_HANDLER
) {
1193 Status
= GetExceptionCode();
1196 if (NT_SUCCESS(Status
)) {
1197 Size
= MmGetMdlByteCount(OutputMdl
);
1199 QueryContext
->Irp
= Irp
;
1200 QueryContext
->InputMdl
= InputMdl
;
1201 QueryContext
->OutputMdl
= OutputMdl
;
1203 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1204 Request
.RequestContext
= QueryContext
;
1205 Status
= InfoTdiQueryInformationEx(&Request
,
1206 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1207 &Size
, &QueryContext
->QueryInfo
.Context
);
1208 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1210 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1215 /* An error occurred if we get here */
1219 MmUnlockPages(InputMdl
);
1220 IoFreeMdl(InputMdl
);
1224 if (OutputMdlLocked
)
1225 MmUnlockPages(OutputMdl
);
1226 IoFreeMdl(OutputMdl
);
1229 ExFreePool(QueryContext
);
1231 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1233 Status
= STATUS_INVALID_PARAMETER
;
1235 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1241 NTSTATUS
DispTdiSetInformationEx(
1243 PIO_STACK_LOCATION IrpSp
)
1245 * FUNCTION: TDI SetInformationEx handler
1247 * Irp = Pointer to I/O request packet
1248 * IrpSp = Pointer to current stack location of Irp
1250 * Status of operation
1253 PTRANSPORT_CONTEXT TranContext
;
1254 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1255 TDI_REQUEST Request
;
1259 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1261 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1262 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1264 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1265 case TDI_TRANSPORT_ADDRESS_FILE
:
1266 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1269 case TDI_CONNECTION_FILE
:
1270 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1273 case TDI_CONTROL_CHANNEL_FILE
:
1274 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1278 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1279 Irp
->IoStatus
.Information
= 0;
1281 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1283 return IRPFinish(Irp
, STATUS_INVALID_PARAMETER
);
1286 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1287 if (NT_SUCCESS(Status
)) {
1288 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1289 Request
.RequestContext
= Irp
;
1291 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1292 &Info
->Buffer
, Info
->BufferSize
);
1294 if (Status
!= STATUS_PENDING
) {
1295 IoAcquireCancelSpinLock(&OldIrql
);
1296 IoSetCancelRoutine(Irp
, NULL
);
1297 IoReleaseCancelSpinLock(OldIrql
);