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
);
206 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
210 NTSTATUS
DispTdiAccept(
213 * FUNCTION: TDI_ACCEPT handler
215 * Irp = Pointer to an I/O request packet
217 * Status of operation
220 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
222 return STATUS_NOT_IMPLEMENTED
;
226 NTSTATUS
DispTdiAssociateAddress(
229 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
231 * Irp = Pointer to an I/O request packet
233 * Status of operation
236 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
237 PTRANSPORT_CONTEXT TranContext
;
238 PIO_STACK_LOCATION IrpSp
;
239 PCONNECTION_ENDPOINT Connection
;
240 PFILE_OBJECT FileObject
;
241 PADDRESS_FILE AddrFile
= NULL
;
244 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
246 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
248 /* Get associated connection endpoint file object. Quit if none exists */
250 TranContext
= IrpSp
->FileObject
->FsContext
;
252 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
253 return STATUS_INVALID_PARAMETER
;
256 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
258 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
259 return STATUS_INVALID_PARAMETER
;
262 if (Connection
->AddressFile
) {
263 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
264 return STATUS_INVALID_PARAMETER
;
267 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
269 Status
= ObReferenceObjectByHandle(
270 Parameters
->AddressHandle
,
276 if (!NT_SUCCESS(Status
)) {
277 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X).\n",
278 Parameters
->AddressHandle
));
279 return STATUS_INVALID_PARAMETER
;
282 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
283 ObDereferenceObject(FileObject
);
284 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
285 FileObject
->FsContext2
));
286 return STATUS_INVALID_PARAMETER
;
289 /* Get associated address file object. Quit if none exists */
291 TranContext
= FileObject
->FsContext
;
293 ObDereferenceObject(FileObject
);
294 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
295 return STATUS_INVALID_PARAMETER
;
298 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
300 ObDereferenceObject(FileObject
);
301 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
302 return STATUS_INVALID_PARAMETER
;
305 Connection
->AddressFile
= AddrFile
;
307 /* Add connection endpoint to the address file */
308 AddrFile
->Connection
= Connection
;
310 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
311 ObDereferenceObject(FileObject
);
317 NTSTATUS
DispTdiConnect(
320 * FUNCTION: TDI_CONNECT handler
322 * Irp = Pointer to an I/O request packet
324 * Status of operation
327 PCONNECTION_ENDPOINT Connection
;
328 PTDI_REQUEST_KERNEL Parameters
;
329 PTRANSPORT_CONTEXT TranContext
;
330 PIO_STACK_LOCATION IrpSp
;
333 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
335 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
337 /* Get associated connection endpoint file object. Quit if none exists */
339 TranContext
= IrpSp
->FileObject
->FsContext
;
341 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
342 return STATUS_INVALID_CONNECTION
;
345 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
347 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
348 return STATUS_INVALID_CONNECTION
;
351 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
354 TranContext
->Handle
.ConnectionContext
,
355 Parameters
->RequestConnectionInformation
,
356 Parameters
->ReturnConnectionInformation
,
357 DispDataRequestComplete
,
360 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
366 NTSTATUS
DispTdiDisassociateAddress(
369 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
371 * Irp = Pointer to an I/O request packet
373 * Status of operation
376 PCONNECTION_ENDPOINT Connection
;
377 PTRANSPORT_CONTEXT TranContext
;
378 PIO_STACK_LOCATION IrpSp
;
380 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
382 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
384 /* Get associated connection endpoint file object. Quit if none exists */
386 TranContext
= IrpSp
->FileObject
->FsContext
;
388 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
389 return STATUS_INVALID_PARAMETER
;
392 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
394 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
395 return STATUS_INVALID_PARAMETER
;
398 if (!Connection
->AddressFile
) {
399 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
400 return STATUS_INVALID_PARAMETER
;
403 return STATUS_SUCCESS
;
407 NTSTATUS
DispTdiDisconnect(
410 * FUNCTION: TDI_DISCONNECT handler
412 * Irp = Pointer to an I/O request packet
414 * Status of operation
417 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
418 PTRANSPORT_CONTEXT TranContext
;
419 PIO_STACK_LOCATION IrpSp
;
421 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
423 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
424 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
426 TranContext
= IrpSp
->FileObject
->FsContext
;
428 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
429 return STATUS_INVALID_CONNECTION
;
432 switch (Parameters
->QueryType
)
434 case TDI_QUERY_ADDRESS_INFO
:
436 PTDI_ADDRESS_INFO AddressInfo
;
437 PADDRESS_FILE AddrFile
;
438 PTA_IP_ADDRESS Address
;
440 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
442 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
443 case TDI_TRANSPORT_ADDRESS_FILE
:
444 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
447 case TDI_CONNECTION_FILE
:
448 AddrFile
= ((PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
)->AddressFile
;
452 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
453 return STATUS_INVALID_PARAMETER
;
457 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
458 return STATUS_INVALID_PARAMETER
;
461 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
462 (sizeof(TDI_ADDRESS_INFO
) + sizeof(TDI_ADDRESS_IP
))) {
463 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
464 return STATUS_BUFFER_OVERFLOW
;
467 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
468 Address
->TAAddressCount
= 1;
469 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
470 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
471 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
472 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->Address
.Address
.IPv4Address
;
474 &Address
->Address
[0].Address
[0].sin_zero
,
475 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
477 return STATUS_SUCCESS
;
481 return STATUS_NOT_IMPLEMENTED
;
485 NTSTATUS
DispTdiListen(
488 * FUNCTION: TDI_LISTEN handler
490 * Irp = Pointer to an I/O request packet
492 * Status of operation
495 PCONNECTION_ENDPOINT Connection
;
496 PTDI_REQUEST_KERNEL Parameters
;
497 PTRANSPORT_CONTEXT TranContext
;
498 PIO_STACK_LOCATION IrpSp
;
501 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
503 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
505 /* Get associated connection endpoint file object. Quit if none exists */
507 TranContext
= IrpSp
->FileObject
->FsContext
;
508 if (TranContext
== NULL
)
510 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
511 return STATUS_INVALID_CONNECTION
;
514 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
515 if (Connection
== NULL
)
517 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
518 return STATUS_INVALID_CONNECTION
;
521 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
523 Status
= TCPListen( Connection
, 1024 /* BACKLOG */,
524 DispDataRequestComplete
,
531 NTSTATUS
DispTdiQueryInformation(
532 PDEVICE_OBJECT DeviceObject
,
535 * FUNCTION: TDI_QUERY_INFORMATION handler
537 * DeviceObject = Pointer to device object structure
538 * Irp = Pointer to an I/O request packet
540 * Status of operation
543 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
544 PTRANSPORT_CONTEXT TranContext
;
545 PIO_STACK_LOCATION IrpSp
;
547 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
549 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
550 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
552 TranContext
= IrpSp
->FileObject
->FsContext
;
554 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
555 return STATUS_INVALID_CONNECTION
;
558 switch (Parameters
->QueryType
)
560 case TDI_QUERY_ADDRESS_INFO
:
562 PTDI_ADDRESS_INFO AddressInfo
;
563 PADDRESS_FILE AddrFile
;
564 PTA_IP_ADDRESS Address
;
566 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
568 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
569 case TDI_TRANSPORT_ADDRESS_FILE
:
570 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
573 case TDI_CONNECTION_FILE
:
574 AddrFile
= ((PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
)->AddressFile
;
578 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
579 return STATUS_INVALID_PARAMETER
;
583 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
584 return STATUS_INVALID_PARAMETER
;
587 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
588 (sizeof(TDI_ADDRESS_INFO
) + sizeof(TDI_ADDRESS_IP
))) {
589 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
590 return STATUS_BUFFER_OVERFLOW
;
593 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
594 Address
->TAAddressCount
= 1;
595 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
596 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
597 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
598 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->Address
.Address
.IPv4Address
;
600 &Address
->Address
[0].Address
[0].sin_zero
,
601 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
603 return STATUS_SUCCESS
;
607 return STATUS_NOT_IMPLEMENTED
;
611 NTSTATUS
DispTdiReceive(
614 * FUNCTION: TDI_RECEIVE handler
616 * Irp = Pointer to an I/O request packet
618 * Status of operation
621 PIO_STACK_LOCATION IrpSp
;
622 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
623 PTRANSPORT_CONTEXT TranContext
;
627 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
629 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
630 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
632 TranContext
= IrpSp
->FileObject
->FsContext
;
633 if (TranContext
== NULL
)
635 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
636 return STATUS_INVALID_CONNECTION
;
639 if (TranContext
->Handle
.ConnectionContext
== NULL
)
641 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
642 return STATUS_INVALID_CONNECTION
;
645 /* Initialize a receive request */
646 Status
= DispPrepareIrpForCancel
647 (TranContext
->Handle
.ConnectionContext
,
649 (PDRIVER_CANCEL
)TCPCancelReceiveRequest
);
651 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
652 if (NT_SUCCESS(Status
))
654 Status
= TCPReceiveData(
655 TranContext
->Handle
.ConnectionContext
,
656 (PNDIS_BUFFER
)Irp
->MdlAddress
,
657 ReceiveInfo
->ReceiveLength
,
659 ReceiveInfo
->ReceiveFlags
,
660 DispDataRequestComplete
,
662 if (Status
!= STATUS_PENDING
)
664 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
668 if (Status
!= STATUS_PENDING
)
670 IrpSp
->Control
&= ~SL_PENDING_RETURNED
;
673 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
679 NTSTATUS
DispTdiReceiveDatagram(
682 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
684 * Irp = Pointer to an I/O request packet
686 * Status of operation
689 PIO_STACK_LOCATION IrpSp
;
690 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
691 PTRANSPORT_CONTEXT TranContext
;
696 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
698 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
699 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
701 TranContext
= IrpSp
->FileObject
->FsContext
;
702 if (TranContext
== NULL
)
704 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
705 return STATUS_INVALID_ADDRESS
;
708 /* Initialize a receive request */
709 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
710 Request
.RequestNotifyObject
= DispDataRequestComplete
;
711 Request
.RequestContext
= Irp
;
713 Status
= DispPrepareIrpForCancel(
714 IrpSp
->FileObject
->FsContext
,
716 (PDRIVER_CANCEL
)DispCancelRequest
);
718 if (NT_SUCCESS(Status
))
723 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
727 Status
= UDPReceiveDatagram(
728 Request
.Handle
.AddressHandle
,
729 DgramInfo
->ReceiveDatagramInformation
->RemoteAddress
,
731 DgramInfo
->ReceiveLength
,
732 DgramInfo
->ReceiveFlags
,
733 DgramInfo
->ReturnDatagramInformation
->RemoteAddress
,
735 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
737 if (Status
!= STATUS_PENDING
)
739 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
743 if (Status
!= STATUS_PENDING
)
745 IrpSp
->Control
&= ~SL_PENDING_RETURNED
;
748 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
754 NTSTATUS
DispTdiSend(
757 * FUNCTION: TDI_SEND handler
759 * Irp = Pointer to an I/O request packet
761 * Status of operation
764 PIO_STACK_LOCATION IrpSp
;
765 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
766 PTRANSPORT_CONTEXT TranContext
;
770 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
772 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
773 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
775 TranContext
= IrpSp
->FileObject
->FsContext
;
776 if (TranContext
== NULL
)
778 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
779 return STATUS_INVALID_CONNECTION
;
782 if (TranContext
->Handle
.ConnectionContext
== NULL
)
784 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
785 return STATUS_INVALID_CONNECTION
;
788 Status
= DispPrepareIrpForCancel(
789 IrpSp
->FileObject
->FsContext
,
791 (PDRIVER_CANCEL
)DispCancelRequest
);
793 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
794 if (NT_SUCCESS(Status
))
799 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
801 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
802 Status
= TCPSendData(
803 TranContext
->Handle
.ConnectionContext
,
805 ReceiveInfo
->ReceiveLength
,
807 ReceiveInfo
->ReceiveFlags
);
808 if (Status
!= STATUS_PENDING
)
810 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
814 if (Status
!= STATUS_PENDING
)
816 IrpSp
->Control
&= ~SL_PENDING_RETURNED
;
819 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
825 NTSTATUS
DispTdiSendDatagram(
828 * FUNCTION: TDI_SEND_DATAGRAM handler
830 * Irp = Pointer to an I/O request packet
832 * Status of operation
835 PIO_STACK_LOCATION IrpSp
;
837 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
838 PTRANSPORT_CONTEXT TranContext
;
841 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
843 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
844 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
845 TranContext
= IrpSp
->FileObject
->FsContext
;
847 /* Initialize a send request */
848 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
849 Request
.RequestNotifyObject
= DispDataRequestComplete
;
850 Request
.RequestContext
= Irp
;
852 Status
= DispPrepareIrpForCancel(
853 IrpSp
->FileObject
->FsContext
,
855 (PDRIVER_CANCEL
)DispCancelRequest
);
857 if (NT_SUCCESS(Status
)) {
861 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
863 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
867 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
868 must be of type PTDI_ADDRESS_IP */
869 TI_DbgPrint(MID_TRACE
,
870 ("About to call send routine %x\n",
871 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
873 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
874 Request
.Handle
.AddressHandle
,
875 DgramInfo
->SendDatagramInformation
,
878 &Irp
->IoStatus
.Information
);
880 if (Status
!= STATUS_PENDING
) {
881 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
882 /* Return STATUS_PENDING because DispPrepareIrpForCancel
883 marks Irp as pending */
884 Status
= STATUS_PENDING
;
888 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
894 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
896 * FUNCTION: TDI_SET_EVENT_HANDER handler
898 * Irp = Pointer to a I/O request packet
900 * Status of operation
903 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
904 PTRANSPORT_CONTEXT TranContext
;
905 PIO_STACK_LOCATION IrpSp
;
906 PADDRESS_FILE AddrFile
;
910 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
912 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
914 /* Get associated address file object. Quit if none exists */
916 TranContext
= IrpSp
->FileObject
->FsContext
;
918 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
919 return STATUS_INVALID_PARAMETER
;
922 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
924 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
925 return STATUS_INVALID_PARAMETER
;
928 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
929 Status
= STATUS_SUCCESS
;
931 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
933 /* Set the event handler. if an event handler is associated with
934 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
935 If an event handler is not used it's flag is FALSE */
936 switch (Parameters
->EventType
) {
937 case TDI_EVENT_CONNECT
:
938 if (!Parameters
->EventHandler
) {
939 AddrFile
->ConnectHandlerContext
= NULL
;
940 AddrFile
->RegisteredConnectHandler
= FALSE
;
942 AddrFile
->ConnectHandler
=
943 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
944 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
945 AddrFile
->RegisteredConnectHandler
= TRUE
;
949 case TDI_EVENT_DISCONNECT
:
950 if (!Parameters
->EventHandler
) {
951 AddrFile
->DisconnectHandlerContext
= NULL
;
952 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
954 AddrFile
->DisconnectHandler
=
955 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
956 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
957 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
961 case TDI_EVENT_ERROR
:
962 if (Parameters
->EventHandler
== NULL
) {
963 AddrFile
->ErrorHandlerContext
= NULL
;
964 AddrFile
->RegisteredErrorHandler
= FALSE
;
966 AddrFile
->ErrorHandler
=
967 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
968 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
969 AddrFile
->RegisteredErrorHandler
= TRUE
;
973 case TDI_EVENT_RECEIVE
:
974 if (Parameters
->EventHandler
== NULL
) {
975 AddrFile
->ReceiveHandlerContext
= NULL
;
976 AddrFile
->RegisteredReceiveHandler
= FALSE
;
978 AddrFile
->ReceiveHandler
=
979 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
980 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
981 AddrFile
->RegisteredReceiveHandler
= TRUE
;
985 case TDI_EVENT_RECEIVE_DATAGRAM
:
986 if (Parameters
->EventHandler
== NULL
) {
987 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
988 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
990 AddrFile
->ReceiveDatagramHandler
=
991 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
992 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
993 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
997 case TDI_EVENT_RECEIVE_EXPEDITED
:
998 if (Parameters
->EventHandler
== NULL
) {
999 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1000 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1002 AddrFile
->ExpeditedReceiveHandler
=
1003 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1004 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1005 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1009 case TDI_EVENT_CHAINED_RECEIVE
:
1010 if (Parameters
->EventHandler
== NULL
) {
1011 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1012 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1014 AddrFile
->ChainedReceiveHandler
=
1015 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1016 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1017 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1021 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1022 if (Parameters
->EventHandler
== NULL
) {
1023 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1024 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1026 AddrFile
->ChainedReceiveDatagramHandler
=
1027 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1028 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1029 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1033 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1034 if (Parameters
->EventHandler
== NULL
) {
1035 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1036 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1038 AddrFile
->ChainedReceiveExpeditedHandler
=
1039 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1040 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1041 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1046 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1047 Parameters
->EventType
));
1049 Status
= STATUS_INVALID_PARAMETER
;
1052 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1058 NTSTATUS
DispTdiSetInformation(
1061 * FUNCTION: TDI_SET_INFORMATION handler
1063 * Irp = Pointer to an I/O request packet
1065 * Status of operation
1068 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1070 return STATUS_NOT_IMPLEMENTED
;
1074 VOID
DispTdiQueryInformationExComplete(
1079 * FUNCTION: Completes a TDI QueryInformationEx request
1081 * Context = Pointer to the IRP for the request
1082 * Status = TDI status of the request
1083 * ByteCount = Number of bytes returned in output buffer
1086 PTI_QUERY_CONTEXT QueryContext
;
1089 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1090 if (NT_SUCCESS(Status
)) {
1091 Count
= CopyBufferToBufferChain(
1092 QueryContext
->InputMdl
,
1093 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1094 (PUCHAR
)&QueryContext
->QueryInfo
.Context
,
1098 MmUnlockPages(QueryContext
->InputMdl
);
1099 IoFreeMdl(QueryContext
->InputMdl
);
1100 if( QueryContext
->OutputMdl
) {
1101 MmUnlockPages(QueryContext
->OutputMdl
);
1102 IoFreeMdl(QueryContext
->OutputMdl
);
1105 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1106 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1108 ExFreePool(QueryContext
);
1112 NTSTATUS
DispTdiQueryInformationEx(
1114 PIO_STACK_LOCATION IrpSp
)
1116 * FUNCTION: TDI QueryInformationEx handler
1118 * Irp = Pointer to I/O request packet
1119 * IrpSp = Pointer to current stack location of Irp
1121 * Status of operation
1124 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1125 PTRANSPORT_CONTEXT TranContext
;
1126 PTI_QUERY_CONTEXT QueryContext
;
1128 TDI_REQUEST Request
;
1130 UINT InputBufferLength
;
1131 UINT OutputBufferLength
;
1132 BOOLEAN InputMdlLocked
= FALSE
;
1133 BOOLEAN OutputMdlLocked
= FALSE
;
1134 PMDL InputMdl
= NULL
;
1135 PMDL OutputMdl
= NULL
;
1136 NTSTATUS Status
= STATUS_SUCCESS
;
1138 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1140 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1142 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1143 case TDI_TRANSPORT_ADDRESS_FILE
:
1144 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1147 case TDI_CONNECTION_FILE
:
1148 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1151 case TDI_CONTROL_CHANNEL_FILE
:
1152 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1156 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1157 return STATUS_INVALID_PARAMETER
;
1160 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1161 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1163 /* Validate parameters */
1164 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1165 (OutputBufferLength
!= 0)) {
1167 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1168 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1169 OutputBuffer
= Irp
->UserBuffer
;
1171 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1174 InputMdl
= IoAllocateMdl(InputBuffer
,
1175 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1178 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1179 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1181 if (InputMdl
&& OutputMdl
) {
1183 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1186 InputMdlLocked
= TRUE
;
1188 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1191 OutputMdlLocked
= TRUE
;
1193 RtlCopyMemory(&QueryContext
->QueryInfo
,
1194 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1196 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1198 Status
= _SEH_GetExceptionCode();
1201 if (NT_SUCCESS(Status
)) {
1202 Size
= MmGetMdlByteCount(OutputMdl
);
1204 QueryContext
->Irp
= Irp
;
1205 QueryContext
->InputMdl
= InputMdl
;
1206 QueryContext
->OutputMdl
= OutputMdl
;
1208 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1209 Request
.RequestContext
= QueryContext
;
1210 Status
= InfoTdiQueryInformationEx(&Request
,
1211 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1212 &Size
, &QueryContext
->QueryInfo
.Context
);
1213 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1215 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1220 /* An error occurred if we get here */
1224 MmUnlockPages(InputMdl
);
1225 IoFreeMdl(InputMdl
);
1229 if (OutputMdlLocked
)
1230 MmUnlockPages(OutputMdl
);
1231 IoFreeMdl(OutputMdl
);
1234 ExFreePool(QueryContext
);
1236 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1237 } else if( InputBufferLength
==
1238 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1239 /* Handle the case where the user is probing the buffer for length */
1240 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1241 InputBufferLength
, OutputBufferLength
));
1242 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1243 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1247 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1248 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1251 InputMdl
= IoAllocateMdl(InputBuffer
,
1252 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1255 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1258 InputMdlLocked
= TRUE
;
1259 Status
= STATUS_SUCCESS
;
1261 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1262 Status
= _SEH_GetExceptionCode();
1265 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1266 if( InputMdl
) IoFreeMdl( InputMdl
);
1267 ExFreePool(QueryContext
);
1271 RtlCopyMemory(&QueryContext
->QueryInfo
,
1272 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1274 QueryContext
->Irp
= Irp
;
1275 QueryContext
->InputMdl
= InputMdl
;
1276 QueryContext
->OutputMdl
= NULL
;
1278 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1279 Request
.RequestContext
= QueryContext
;
1280 Status
= InfoTdiQueryInformationEx(&Request
,
1281 &QueryContext
->QueryInfo
.ID
,
1284 &QueryContext
->QueryInfo
.Context
);
1285 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1286 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1287 } else Status
= STATUS_INVALID_PARAMETER
;
1289 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1295 NTSTATUS
DispTdiSetInformationEx(
1297 PIO_STACK_LOCATION IrpSp
)
1299 * FUNCTION: TDI SetInformationEx handler
1301 * Irp = Pointer to I/O request packet
1302 * IrpSp = Pointer to current stack location of Irp
1304 * Status of operation
1307 PTRANSPORT_CONTEXT TranContext
;
1308 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1309 TDI_REQUEST Request
;
1313 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1315 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1316 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1318 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1319 case TDI_TRANSPORT_ADDRESS_FILE
:
1320 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1323 case TDI_CONNECTION_FILE
:
1324 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1327 case TDI_CONTROL_CHANNEL_FILE
:
1328 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1332 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1333 Irp
->IoStatus
.Information
= 0;
1335 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1337 return IRPFinish(Irp
, STATUS_INVALID_PARAMETER
);
1340 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1341 if (NT_SUCCESS(Status
)) {
1342 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1343 Request
.RequestContext
= Irp
;
1345 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1346 &Info
->Buffer
, Info
->BufferSize
);
1348 if (Status
!= STATUS_PENDING
) {
1349 IoAcquireCancelSpinLock(&OldIrql
);
1350 IoSetCancelRoutine(Irp
, NULL
);
1351 IoReleaseCancelSpinLock(OldIrql
);