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
->ADE
->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
;
499 PTDI_REQUEST Request
;
502 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
504 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
506 /* Get associated connection endpoint file object. Quit if none exists */
508 TranContext
= IrpSp
->FileObject
->FsContext
;
509 if (TranContext
== NULL
)
511 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
512 return STATUS_INVALID_CONNECTION
;
515 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
516 if (Connection
== NULL
)
518 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
519 return STATUS_INVALID_CONNECTION
;
522 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
524 Status
= TCPListen( Request
->Handle
.ConnectionContext
, 1024 /* BACKLOG */,
525 DispDataRequestComplete
,
532 NTSTATUS
DispTdiQueryInformation(
533 PDEVICE_OBJECT DeviceObject
,
536 * FUNCTION: TDI_QUERY_INFORMATION handler
538 * DeviceObject = Pointer to device object structure
539 * Irp = Pointer to an I/O request packet
541 * Status of operation
544 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
545 PTRANSPORT_CONTEXT TranContext
;
546 PIO_STACK_LOCATION IrpSp
;
548 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
550 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
551 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
553 TranContext
= IrpSp
->FileObject
->FsContext
;
555 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
556 return STATUS_INVALID_CONNECTION
;
559 switch (Parameters
->QueryType
)
561 case TDI_QUERY_ADDRESS_INFO
:
563 PTDI_ADDRESS_INFO AddressInfo
;
564 PADDRESS_FILE AddrFile
;
565 PTA_IP_ADDRESS Address
;
567 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
569 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
570 case TDI_TRANSPORT_ADDRESS_FILE
:
571 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
574 case TDI_CONNECTION_FILE
:
575 AddrFile
= ((PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
)->AddressFile
;
579 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
580 return STATUS_INVALID_PARAMETER
;
584 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
585 return STATUS_INVALID_PARAMETER
;
588 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
589 (sizeof(TDI_ADDRESS_INFO
) + sizeof(TDI_ADDRESS_IP
))) {
590 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
591 return STATUS_BUFFER_OVERFLOW
;
594 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
595 Address
->TAAddressCount
= 1;
596 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
597 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
598 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
599 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->ADE
->Address
.Address
.IPv4Address
;
601 &Address
->Address
[0].Address
[0].sin_zero
,
602 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
604 return STATUS_SUCCESS
;
608 return STATUS_NOT_IMPLEMENTED
;
612 NTSTATUS
DispTdiReceive(
615 * FUNCTION: TDI_RECEIVE handler
617 * Irp = Pointer to an I/O request packet
619 * Status of operation
622 PIO_STACK_LOCATION IrpSp
;
623 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
624 PTRANSPORT_CONTEXT TranContext
;
628 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
630 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
631 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
633 TranContext
= IrpSp
->FileObject
->FsContext
;
634 if (TranContext
== NULL
)
636 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
637 return STATUS_INVALID_CONNECTION
;
640 if (TranContext
->Handle
.ConnectionContext
== NULL
)
642 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
643 return STATUS_INVALID_CONNECTION
;
646 /* Initialize a receive request */
647 Status
= DispPrepareIrpForCancel(
648 IrpSp
->FileObject
->FsContext
,
650 (PDRIVER_CANCEL
)DispCancelRequest
);
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
)
665 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
669 if (Status
!= STATUS_PENDING
)
671 IrpSp
->Control
&= ~SL_PENDING_RETURNED
;
674 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
680 NTSTATUS
DispTdiReceiveDatagram(
683 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
685 * Irp = Pointer to an I/O request packet
687 * Status of operation
690 PIO_STACK_LOCATION IrpSp
;
691 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
692 PTRANSPORT_CONTEXT TranContext
;
697 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
699 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
700 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
702 TranContext
= IrpSp
->FileObject
->FsContext
;
703 if (TranContext
== NULL
)
705 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
706 return STATUS_INVALID_ADDRESS
;
709 /* Initialize a receive request */
710 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
711 Request
.RequestNotifyObject
= DispDataRequestComplete
;
712 Request
.RequestContext
= Irp
;
713 Status
= DispPrepareIrpForCancel(
714 IrpSp
->FileObject
->FsContext
,
716 (PDRIVER_CANCEL
)DispCancelRequest
);
717 if (NT_SUCCESS(Status
))
722 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
726 Status
= UDPReceiveDatagram(
727 Request
.Handle
.AddressHandle
,
728 DgramInfo
->ReceiveDatagramInformation
,
730 DgramInfo
->ReceiveLength
,
731 DgramInfo
->ReceiveFlags
,
732 DgramInfo
->ReturnDatagramInformation
,
734 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
736 if (Status
!= STATUS_PENDING
)
738 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
742 if (Status
!= STATUS_PENDING
)
744 IrpSp
->Control
&= ~SL_PENDING_RETURNED
;
747 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
753 NTSTATUS
DispTdiSend(
756 * FUNCTION: TDI_SEND handler
758 * Irp = Pointer to an I/O request packet
760 * Status of operation
763 PIO_STACK_LOCATION IrpSp
;
764 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
765 PTRANSPORT_CONTEXT TranContext
;
769 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
771 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
772 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
774 TranContext
= IrpSp
->FileObject
->FsContext
;
775 if (TranContext
== NULL
)
777 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
778 return STATUS_INVALID_CONNECTION
;
781 if (TranContext
->Handle
.ConnectionContext
== NULL
)
783 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
784 return STATUS_INVALID_CONNECTION
;
787 Status
= DispPrepareIrpForCancel(
788 IrpSp
->FileObject
->FsContext
,
790 (PDRIVER_CANCEL
)DispCancelRequest
);
791 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
792 if (NT_SUCCESS(Status
))
797 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
799 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
800 Status
= TCPSendData(
801 TranContext
->Handle
.ConnectionContext
,
803 ReceiveInfo
->ReceiveLength
,
805 ReceiveInfo
->ReceiveFlags
);
806 if (Status
!= STATUS_PENDING
)
808 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
812 if (Status
!= STATUS_PENDING
)
814 IrpSp
->Control
&= ~SL_PENDING_RETURNED
;
817 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
823 NTSTATUS
DispTdiSendDatagram(
826 * FUNCTION: TDI_SEND_DATAGRAM handler
828 * Irp = Pointer to an I/O request packet
830 * Status of operation
833 PIO_STACK_LOCATION IrpSp
;
835 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
836 PTRANSPORT_CONTEXT TranContext
;
839 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
841 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
842 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
843 TranContext
= IrpSp
->FileObject
->FsContext
;
845 /* Initialize a send request */
846 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
847 Request
.RequestNotifyObject
= DispDataRequestComplete
;
848 Request
.RequestContext
= Irp
;
850 Status
= DispPrepareIrpForCancel(
851 IrpSp
->FileObject
->FsContext
,
853 (PDRIVER_CANCEL
)DispCancelRequest
);
854 if (NT_SUCCESS(Status
)) {
858 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
860 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
864 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
865 must be of type PTDI_ADDRESS_IP */
866 TI_DbgPrint(MID_TRACE
,
867 ("About to call send routine %x\n",
868 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
870 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
871 Request
.Handle
.AddressHandle
,
872 DgramInfo
->SendDatagramInformation
,
875 &Irp
->IoStatus
.Information
);
877 if (Status
!= STATUS_PENDING
) {
878 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
879 /* Return STATUS_PENDING because DispPrepareIrpForCancel
880 marks Irp as pending */
881 Status
= STATUS_PENDING
;
885 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
891 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
893 * FUNCTION: TDI_SET_EVENT_HANDER handler
895 * Irp = Pointer to a I/O request packet
897 * Status of operation
900 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
901 PTRANSPORT_CONTEXT TranContext
;
902 PIO_STACK_LOCATION IrpSp
;
903 PADDRESS_FILE AddrFile
;
907 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
909 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
911 /* Get associated address file object. Quit if none exists */
913 TranContext
= IrpSp
->FileObject
->FsContext
;
915 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
916 return STATUS_INVALID_PARAMETER
;
919 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
921 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
922 return STATUS_INVALID_PARAMETER
;
925 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
926 Status
= STATUS_SUCCESS
;
928 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
930 /* Set the event handler. if an event handler is associated with
931 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
932 If an event handler is not used it's flag is FALSE */
933 switch (Parameters
->EventType
) {
934 case TDI_EVENT_CONNECT
:
935 if (!Parameters
->EventHandler
) {
936 AddrFile
->ConnectHandlerContext
= NULL
;
937 AddrFile
->RegisteredConnectHandler
= FALSE
;
939 AddrFile
->ConnectHandler
=
940 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
941 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
942 AddrFile
->RegisteredConnectHandler
= TRUE
;
946 case TDI_EVENT_DISCONNECT
:
947 if (!Parameters
->EventHandler
) {
948 AddrFile
->DisconnectHandlerContext
= NULL
;
949 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
951 AddrFile
->DisconnectHandler
=
952 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
953 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
954 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
958 case TDI_EVENT_ERROR
:
959 if (Parameters
->EventHandler
== NULL
) {
960 AddrFile
->ErrorHandlerContext
= NULL
;
961 AddrFile
->RegisteredErrorHandler
= FALSE
;
963 AddrFile
->ErrorHandler
=
964 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
965 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
966 AddrFile
->RegisteredErrorHandler
= TRUE
;
970 case TDI_EVENT_RECEIVE
:
971 if (Parameters
->EventHandler
== NULL
) {
972 AddrFile
->ReceiveHandlerContext
= NULL
;
973 AddrFile
->RegisteredReceiveHandler
= FALSE
;
975 AddrFile
->ReceiveHandler
=
976 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
977 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
978 AddrFile
->RegisteredReceiveHandler
= TRUE
;
982 case TDI_EVENT_RECEIVE_DATAGRAM
:
983 if (Parameters
->EventHandler
== NULL
) {
984 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
985 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
987 AddrFile
->ReceiveDatagramHandler
=
988 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
989 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
990 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
994 case TDI_EVENT_RECEIVE_EXPEDITED
:
995 if (Parameters
->EventHandler
== NULL
) {
996 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
997 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
999 AddrFile
->ExpeditedReceiveHandler
=
1000 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1001 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1002 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1006 case TDI_EVENT_CHAINED_RECEIVE
:
1007 if (Parameters
->EventHandler
== NULL
) {
1008 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1009 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1011 AddrFile
->ChainedReceiveHandler
=
1012 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1013 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1014 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1018 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1019 if (Parameters
->EventHandler
== NULL
) {
1020 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1021 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1023 AddrFile
->ChainedReceiveDatagramHandler
=
1024 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1025 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1026 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1030 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1031 if (Parameters
->EventHandler
== NULL
) {
1032 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1033 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1035 AddrFile
->ChainedReceiveExpeditedHandler
=
1036 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1037 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1038 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1043 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1044 Parameters
->EventType
));
1046 Status
= STATUS_INVALID_PARAMETER
;
1049 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1055 NTSTATUS
DispTdiSetInformation(
1058 * FUNCTION: TDI_SET_INFORMATION handler
1060 * Irp = Pointer to an I/O request packet
1062 * Status of operation
1065 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1067 return STATUS_NOT_IMPLEMENTED
;
1071 VOID
DispTdiQueryInformationExComplete(
1076 * FUNCTION: Completes a TDI QueryInformationEx request
1078 * Context = Pointer to the IRP for the request
1079 * Status = TDI status of the request
1080 * ByteCount = Number of bytes returned in output buffer
1083 PTI_QUERY_CONTEXT QueryContext
;
1086 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1087 if (NT_SUCCESS(Status
)) {
1088 Count
= CopyBufferToBufferChain(
1089 QueryContext
->InputMdl
,
1090 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1091 (PUCHAR
)&QueryContext
->QueryInfo
.Context
,
1095 MmUnlockPages(QueryContext
->InputMdl
);
1096 IoFreeMdl(QueryContext
->InputMdl
);
1097 MmUnlockPages(QueryContext
->OutputMdl
);
1098 IoFreeMdl(QueryContext
->OutputMdl
);
1100 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1101 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1103 ExFreePool(QueryContext
);
1107 NTSTATUS
DispTdiQueryInformationEx(
1109 PIO_STACK_LOCATION IrpSp
)
1111 * FUNCTION: TDI QueryInformationEx handler
1113 * Irp = Pointer to I/O request packet
1114 * IrpSp = Pointer to current stack location of Irp
1116 * Status of operation
1119 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1120 PTRANSPORT_CONTEXT TranContext
;
1121 PTI_QUERY_CONTEXT QueryContext
;
1123 TDI_REQUEST Request
;
1125 UINT InputBufferLength
;
1126 UINT OutputBufferLength
;
1127 BOOLEAN InputMdlLocked
= FALSE
;
1128 BOOLEAN OutputMdlLocked
= FALSE
;
1129 PMDL InputMdl
= NULL
;
1130 PMDL OutputMdl
= NULL
;
1131 NTSTATUS Status
= STATUS_SUCCESS
;
1133 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1135 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1137 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1138 case TDI_TRANSPORT_ADDRESS_FILE
:
1139 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1142 case TDI_CONNECTION_FILE
:
1143 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1146 case TDI_CONTROL_CHANNEL_FILE
:
1147 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1151 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1152 return STATUS_INVALID_PARAMETER
;
1155 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1156 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1158 /* Validate parameters */
1159 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1160 (OutputBufferLength
!= 0)) {
1162 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1163 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1164 OutputBuffer
= Irp
->UserBuffer
;
1166 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1171 InputMdl
= IoAllocateMdl(InputBuffer
,
1172 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1175 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1176 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1178 if (InputMdl
&& OutputMdl
) {
1180 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1183 InputMdlLocked
= TRUE
;
1185 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1188 OutputMdlLocked
= TRUE
;
1190 RtlCopyMemory(&QueryContext
->QueryInfo
,
1191 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1194 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1196 } except(EXCEPTION_EXECUTE_HANDLER
) {
1197 Status
= GetExceptionCode();
1200 if (NT_SUCCESS(Status
)) {
1201 Size
= MmGetMdlByteCount(OutputMdl
);
1203 QueryContext
->Irp
= Irp
;
1204 QueryContext
->InputMdl
= InputMdl
;
1205 QueryContext
->OutputMdl
= OutputMdl
;
1207 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1208 Request
.RequestContext
= QueryContext
;
1209 Status
= InfoTdiQueryInformationEx(&Request
,
1210 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1211 &Size
, &QueryContext
->QueryInfo
.Context
);
1212 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1214 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1219 /* An error occurred if we get here */
1223 MmUnlockPages(InputMdl
);
1224 IoFreeMdl(InputMdl
);
1228 if (OutputMdlLocked
)
1229 MmUnlockPages(OutputMdl
);
1230 IoFreeMdl(OutputMdl
);
1233 ExFreePool(QueryContext
);
1235 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1237 Status
= STATUS_INVALID_PARAMETER
;
1239 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1245 NTSTATUS
DispTdiSetInformationEx(
1247 PIO_STACK_LOCATION IrpSp
)
1249 * FUNCTION: TDI SetInformationEx handler
1251 * Irp = Pointer to I/O request packet
1252 * IrpSp = Pointer to current stack location of Irp
1254 * Status of operation
1257 PTRANSPORT_CONTEXT TranContext
;
1258 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1259 TDI_REQUEST Request
;
1263 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1265 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1266 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1268 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1269 case TDI_TRANSPORT_ADDRESS_FILE
:
1270 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1273 case TDI_CONNECTION_FILE
:
1274 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1277 case TDI_CONTROL_CHANNEL_FILE
:
1278 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1282 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1283 Irp
->IoStatus
.Information
= 0;
1285 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1287 return IRPFinish(Irp
, STATUS_INVALID_PARAMETER
);
1290 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1291 if (NT_SUCCESS(Status
)) {
1292 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1293 Request
.RequestContext
= Irp
;
1295 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1296 &Info
->Buffer
, Info
->BufferSize
);
1298 if (Status
!= STATUS_PENDING
) {
1299 IoAcquireCancelSpinLock(&OldIrql
);
1300 IoSetCancelRoutine(Irp
, NULL
);
1301 IoReleaseCancelSpinLock(OldIrql
);