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
15 NTSTATUS
DispPrepareIrpForCancel(
16 PTRANSPORT_CONTEXT Context
,
18 PDRIVER_CANCEL CancelRoutine
)
20 * FUNCTION: Prepare an IRP for cancellation
22 * Context = Pointer to context information
23 * Irp = Pointer to an I/O request packet
24 * CancelRoutine = Routine to be called when I/O request is cancelled
31 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
33 IoAcquireCancelSpinLock(&OldIrql
);
36 IoMarkIrpPending(Irp
);
37 IoSetCancelRoutine(Irp
, CancelRoutine
);
38 IoReleaseCancelSpinLock(OldIrql
);
40 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
42 return STATUS_SUCCESS
;
45 /* IRP has already been cancelled */
47 IoReleaseCancelSpinLock(OldIrql
);
49 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
50 Irp
->IoStatus
.Information
= 0;
52 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
54 return IRPFinish(Irp
, STATUS_CANCELLED
);
58 VOID
DispCancelComplete(
61 * FUNCTION: Completes a cancel request
63 * Context = Pointer to context information (FILE_OBJECT)
67 PFILE_OBJECT FileObject
;
68 PTRANSPORT_CONTEXT TranContext
;
70 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
72 FileObject
= (PFILE_OBJECT
)Context
;
73 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
75 /* Set the cleanup event */
76 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
78 /* We are expected to release the cancel spin lock */
79 IoReleaseCancelSpinLock(OldIrql
);
81 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
85 VOID DDKAPI
DispCancelRequest(
86 PDEVICE_OBJECT Device
,
89 * FUNCTION: Cancels an IRP
91 * Device = Pointer to device object
92 * Irp = Pointer to an I/O request packet
95 PIO_STACK_LOCATION IrpSp
;
96 PTRANSPORT_CONTEXT TranContext
;
97 PFILE_OBJECT FileObject
;
99 NTSTATUS Status
= STATUS_SUCCESS
;
101 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
103 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
104 FileObject
= IrpSp
->FileObject
;
105 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
106 MinorFunction
= IrpSp
->MinorFunction
;
108 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
112 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
115 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
117 /* Try canceling the request */
118 switch(MinorFunction
) {
121 /* FIXME: Close connection */
124 case TDI_SEND_DATAGRAM
:
125 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
126 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
130 /*DGCancelSendRequest(TranContext->Handle.AddressHandle, Irp);*/
133 case TDI_RECEIVE_DATAGRAM
:
134 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
135 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
139 /*DGCancelReceiveRequest(TranContext->Handle.AddressHandle, Irp);*/
143 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
147 if (Status
!= STATUS_PENDING
)
148 DispCancelComplete(FileObject
);
150 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
153 VOID
DispDataRequestComplete(
158 * FUNCTION: Completes a send/receive IRP
160 * Context = Pointer to context information (IRP)
161 * Status = Status of the request
162 * Count = Number of bytes sent or received
166 PIO_STACK_LOCATION IrpSp
;
167 PTRANSPORT_CONTEXT TranContext
;
170 TI_DbgPrint(DEBUG_IRP
, ("Called for irp %x (%x, %d).\n",
171 Context
, Status
, Count
));
174 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
175 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
177 IoAcquireCancelSpinLock(&OldIrql
);
179 IoSetCancelRoutine(Irp
, NULL
);
181 if (Irp
->Cancel
|| TranContext
->CancelIrps
) {
182 /* The IRP has been cancelled */
184 TI_DbgPrint(DEBUG_IRP
, ("IRP is cancelled.\n"));
186 Status
= STATUS_CANCELLED
;
190 IoReleaseCancelSpinLock(OldIrql
);
192 Irp
->IoStatus
.Status
= Status
;
193 Irp
->IoStatus
.Information
= Count
;
195 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
196 Irp
->IoStatus
.Status
));
197 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
198 Irp
->IoStatus
.Information
));
199 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
201 IRPFinish(Irp
, Irp
->IoStatus
.Status
);
203 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
207 NTSTATUS
DispTdiAccept(
210 * FUNCTION: TDI_ACCEPT handler
212 * Irp = Pointer to an I/O request packet
214 * Status of operation
217 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
219 return STATUS_NOT_IMPLEMENTED
;
223 NTSTATUS
DispTdiAssociateAddress(
226 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
228 * Irp = Pointer to an I/O request packet
230 * Status of operation
233 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
234 PTRANSPORT_CONTEXT TranContext
;
235 PIO_STACK_LOCATION IrpSp
;
236 PCONNECTION_ENDPOINT Connection
;
237 PFILE_OBJECT FileObject
;
238 PADDRESS_FILE AddrFile
= NULL
;
241 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
243 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
245 /* Get associated connection endpoint file object. Quit if none exists */
247 TranContext
= IrpSp
->FileObject
->FsContext
;
249 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
250 return STATUS_INVALID_PARAMETER
;
253 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
255 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
256 return STATUS_INVALID_PARAMETER
;
259 if (Connection
->AddressFile
) {
260 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
261 return STATUS_INVALID_PARAMETER
;
264 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
266 Status
= ObReferenceObjectByHandle(
267 Parameters
->AddressHandle
,
273 if (!NT_SUCCESS(Status
)) {
274 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
275 Parameters
->AddressHandle
, Status
));
276 return STATUS_INVALID_PARAMETER
;
279 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
280 ObDereferenceObject(FileObject
);
281 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
282 FileObject
->FsContext2
));
283 return STATUS_INVALID_PARAMETER
;
286 /* Get associated address file object. Quit if none exists */
288 TranContext
= FileObject
->FsContext
;
290 ObDereferenceObject(FileObject
);
291 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
292 return STATUS_INVALID_PARAMETER
;
295 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
297 ObDereferenceObject(FileObject
);
298 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
299 return STATUS_INVALID_PARAMETER
;
302 Connection
->AddressFile
= AddrFile
;
304 /* Add connection endpoint to the address file */
305 AddrFile
->Connection
= Connection
;
307 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
308 ObDereferenceObject(FileObject
);
314 NTSTATUS
DispTdiConnect(
317 * FUNCTION: TDI_CONNECT handler
319 * Irp = Pointer to an I/O request packet
321 * Status of operation
324 PCONNECTION_ENDPOINT Connection
;
325 PTDI_REQUEST_KERNEL Parameters
;
326 PTRANSPORT_CONTEXT TranContext
;
327 PIO_STACK_LOCATION IrpSp
;
330 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
332 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
334 /* Get associated connection endpoint file object. Quit if none exists */
336 TranContext
= IrpSp
->FileObject
->FsContext
;
338 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
339 return STATUS_INVALID_CONNECTION
;
342 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
344 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
345 return STATUS_INVALID_CONNECTION
;
348 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
351 TranContext
->Handle
.ConnectionContext
,
352 Parameters
->RequestConnectionInformation
,
353 Parameters
->ReturnConnectionInformation
,
354 DispDataRequestComplete
,
357 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
363 NTSTATUS
DispTdiDisassociateAddress(
366 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
368 * Irp = Pointer to an I/O request packet
370 * Status of operation
373 PCONNECTION_ENDPOINT Connection
;
374 PTRANSPORT_CONTEXT TranContext
;
375 PIO_STACK_LOCATION IrpSp
;
377 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
379 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
381 /* Get associated connection endpoint file object. Quit if none exists */
383 TranContext
= IrpSp
->FileObject
->FsContext
;
385 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
386 return STATUS_INVALID_PARAMETER
;
389 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
391 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
392 return STATUS_INVALID_PARAMETER
;
395 if (!Connection
->AddressFile
) {
396 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
397 return STATUS_INVALID_PARAMETER
;
400 return STATUS_SUCCESS
;
404 NTSTATUS
DispTdiDisconnect(
407 * FUNCTION: TDI_DISCONNECT handler
409 * Irp = Pointer to an I/O request packet
411 * Status of operation
415 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
416 PCONNECTION_ENDPOINT Connection
;
417 PTRANSPORT_CONTEXT TranContext
;
418 PIO_STACK_LOCATION IrpSp
;
420 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
422 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
423 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
425 /* Get associated connection endpoint file object. Quit if none exists */
427 TranContext
= IrpSp
->FileObject
->FsContext
;
429 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
430 return STATUS_INVALID_CONNECTION
;
433 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
435 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
436 return STATUS_INVALID_CONNECTION
;
439 Status
= TCPDisconnect(
440 TranContext
->Handle
.ConnectionContext
,
441 DisReq
->RequestFlags
,
442 DisReq
->RequestConnectionInformation
,
443 DisReq
->ReturnConnectionInformation
,
444 DispDataRequestComplete
,
447 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
453 NTSTATUS
DispTdiListen(
456 * FUNCTION: TDI_LISTEN handler
458 * Irp = Pointer to an I/O request packet
460 * Status of operation
463 PCONNECTION_ENDPOINT Connection
;
464 PTDI_REQUEST_KERNEL Parameters
;
465 PTRANSPORT_CONTEXT TranContext
;
466 PIO_STACK_LOCATION IrpSp
;
467 NTSTATUS Status
= STATUS_SUCCESS
;
469 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
471 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
473 /* Get associated connection endpoint file object. Quit if none exists */
475 TranContext
= IrpSp
->FileObject
->FsContext
;
476 if (TranContext
== NULL
)
478 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
479 return STATUS_INVALID_CONNECTION
;
482 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
483 if (Connection
== NULL
)
485 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
486 return STATUS_INVALID_CONNECTION
;
489 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
491 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile: %x\n",
492 Connection
->AddressFile
));
493 if( Connection
->AddressFile
) {
494 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile->Listener: %x\n",
495 Connection
->AddressFile
->Listener
));
498 /* Listening will require us to create a listening socket and store it in
499 * the address file. It will be signalled, and attempt to complete an irp
500 * when a new connection arrives. */
501 /* The important thing to note here is that the irp we'll complete belongs
502 * to the socket to be accepted onto, not the listener */
503 if( !Connection
->AddressFile
->Listener
) {
504 Connection
->AddressFile
->Listener
=
505 TCPAllocateConnectionEndpoint( NULL
);
507 if( !Connection
->AddressFile
->Listener
)
508 Status
= STATUS_NO_MEMORY
;
510 if( NT_SUCCESS(Status
) ) {
511 Connection
->AddressFile
->Listener
->AddressFile
=
512 Connection
->AddressFile
;
514 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
515 Connection
->AddressFile
->Family
,
517 Connection
->AddressFile
->Protocol
);
520 if( NT_SUCCESS(Status
) )
521 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
525 if( NT_SUCCESS(Status
) ) {
527 ( (PTDI_REQUEST
)Parameters
,
528 Connection
->AddressFile
->Listener
,
530 DispDataRequestComplete
,
534 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
540 NTSTATUS
DispTdiQueryInformation(
541 PDEVICE_OBJECT DeviceObject
,
544 * FUNCTION: TDI_QUERY_INFORMATION handler
546 * DeviceObject = Pointer to device object structure
547 * Irp = Pointer to an I/O request packet
549 * Status of operation
552 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
553 PTRANSPORT_CONTEXT TranContext
;
554 PIO_STACK_LOCATION IrpSp
;
556 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
558 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
559 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
561 TranContext
= IrpSp
->FileObject
->FsContext
;
563 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
564 return STATUS_INVALID_CONNECTION
;
567 switch (Parameters
->QueryType
)
569 case TDI_QUERY_ADDRESS_INFO
:
571 PTDI_ADDRESS_INFO AddressInfo
;
572 PADDRESS_FILE AddrFile
;
573 PTA_IP_ADDRESS Address
;
575 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
577 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
578 case TDI_TRANSPORT_ADDRESS_FILE
:
579 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
582 case TDI_CONNECTION_FILE
:
583 AddrFile
= ((PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
)->AddressFile
;
587 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
588 return STATUS_INVALID_PARAMETER
;
592 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
593 return STATUS_INVALID_PARAMETER
;
596 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
597 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
598 sizeof(TDI_ADDRESS_IP
))) {
599 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
600 return STATUS_BUFFER_OVERFLOW
;
603 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
604 Address
->TAAddressCount
= 1;
605 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
606 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
607 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
608 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->Address
.Address
.IPv4Address
;
610 &Address
->Address
[0].Address
[0].sin_zero
,
611 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
613 return STATUS_SUCCESS
;
617 return STATUS_NOT_IMPLEMENTED
;
621 NTSTATUS
DispTdiReceive(
624 * FUNCTION: TDI_RECEIVE handler
626 * Irp = Pointer to an I/O request packet
628 * Status of operation
631 PIO_STACK_LOCATION IrpSp
;
632 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
633 PTRANSPORT_CONTEXT TranContext
;
637 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
639 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
640 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
642 TranContext
= IrpSp
->FileObject
->FsContext
;
643 if (TranContext
== NULL
)
645 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
646 return STATUS_INVALID_CONNECTION
;
649 if (TranContext
->Handle
.ConnectionContext
== NULL
)
651 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
652 return STATUS_INVALID_CONNECTION
;
655 /* Initialize a receive request */
656 Status
= DispPrepareIrpForCancel
657 (TranContext
->Handle
.ConnectionContext
,
659 (PDRIVER_CANCEL
)DispCancelRequest
);
661 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
662 if (NT_SUCCESS(Status
))
664 Status
= TCPReceiveData(
665 TranContext
->Handle
.ConnectionContext
,
666 (PNDIS_BUFFER
)Irp
->MdlAddress
,
667 ReceiveInfo
->ReceiveLength
,
669 ReceiveInfo
->ReceiveFlags
,
670 DispDataRequestComplete
,
672 if (Status
!= STATUS_PENDING
)
674 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
676 IoMarkIrpPending(Irp
);
679 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
685 NTSTATUS
DispTdiReceiveDatagram(
688 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
690 * Irp = Pointer to an I/O request packet
692 * Status of operation
695 PIO_STACK_LOCATION IrpSp
;
696 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
697 PTRANSPORT_CONTEXT TranContext
;
702 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
704 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
705 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
707 TranContext
= IrpSp
->FileObject
->FsContext
;
708 if (TranContext
== NULL
)
710 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
711 return STATUS_INVALID_ADDRESS
;
714 /* Initialize a receive request */
715 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
716 Request
.RequestNotifyObject
= DispDataRequestComplete
;
717 Request
.RequestContext
= Irp
;
719 Status
= DispPrepareIrpForCancel(
720 IrpSp
->FileObject
->FsContext
,
722 (PDRIVER_CANCEL
)DispCancelRequest
);
724 if (NT_SUCCESS(Status
))
729 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
733 Status
= UDPReceiveDatagram(
734 Request
.Handle
.AddressHandle
,
735 DgramInfo
->ReceiveDatagramInformation
,
737 DgramInfo
->ReceiveLength
,
738 DgramInfo
->ReceiveFlags
,
739 DgramInfo
->ReturnDatagramInformation
,
741 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
743 if (Status
!= STATUS_PENDING
) {
744 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
746 IoMarkIrpPending(Irp
);
749 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
755 NTSTATUS
DispTdiSend(
758 * FUNCTION: TDI_SEND handler
760 * Irp = Pointer to an I/O request packet
762 * Status of operation
765 PIO_STACK_LOCATION IrpSp
;
766 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
767 PTRANSPORT_CONTEXT TranContext
;
771 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
773 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
774 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
776 TranContext
= IrpSp
->FileObject
->FsContext
;
777 if (TranContext
== NULL
)
779 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
780 return STATUS_INVALID_CONNECTION
;
783 if (TranContext
->Handle
.ConnectionContext
== NULL
)
785 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
786 return STATUS_INVALID_CONNECTION
;
789 Status
= DispPrepareIrpForCancel(
790 IrpSp
->FileObject
->FsContext
,
792 (PDRIVER_CANCEL
)DispCancelRequest
);
794 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
795 if (NT_SUCCESS(Status
))
800 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
802 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
803 Status
= TCPSendData(
804 TranContext
->Handle
.ConnectionContext
,
806 ReceiveInfo
->ReceiveLength
,
808 ReceiveInfo
->ReceiveFlags
);
809 if (Status
!= STATUS_PENDING
)
811 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
813 IoMarkIrpPending( Irp
);
816 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
822 NTSTATUS
DispTdiSendDatagram(
825 * FUNCTION: TDI_SEND_DATAGRAM handler
827 * Irp = Pointer to an I/O request packet
829 * Status of operation
832 PIO_STACK_LOCATION IrpSp
;
834 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
835 PTRANSPORT_CONTEXT TranContext
;
838 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
840 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
841 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
842 TranContext
= IrpSp
->FileObject
->FsContext
;
844 /* Initialize a send request */
845 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
846 Request
.RequestNotifyObject
= DispDataRequestComplete
;
847 Request
.RequestContext
= Irp
;
849 Status
= DispPrepareIrpForCancel(
850 IrpSp
->FileObject
->FsContext
,
852 (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
;
883 IoMarkIrpPending( Irp
);
886 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
892 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
894 * FUNCTION: TDI_SET_EVENT_HANDER handler
896 * Irp = Pointer to a I/O request packet
898 * Status of operation
901 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
902 PTRANSPORT_CONTEXT TranContext
;
903 PIO_STACK_LOCATION IrpSp
;
904 PADDRESS_FILE AddrFile
;
908 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
910 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
912 /* Get associated address file object. Quit if none exists */
914 TranContext
= IrpSp
->FileObject
->FsContext
;
916 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
917 return STATUS_INVALID_PARAMETER
;
920 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
922 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
923 return STATUS_INVALID_PARAMETER
;
926 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
927 Status
= STATUS_SUCCESS
;
929 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
931 /* Set the event handler. if an event handler is associated with
932 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
933 If an event handler is not used it's flag is FALSE */
934 switch (Parameters
->EventType
) {
935 case TDI_EVENT_CONNECT
:
936 if (!Parameters
->EventHandler
) {
937 AddrFile
->ConnectHandlerContext
= NULL
;
938 AddrFile
->RegisteredConnectHandler
= FALSE
;
940 AddrFile
->ConnectHandler
=
941 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
942 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
943 AddrFile
->RegisteredConnectHandler
= TRUE
;
947 case TDI_EVENT_DISCONNECT
:
948 if (!Parameters
->EventHandler
) {
949 AddrFile
->DisconnectHandlerContext
= NULL
;
950 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
952 AddrFile
->DisconnectHandler
=
953 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
954 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
955 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
959 case TDI_EVENT_ERROR
:
960 if (Parameters
->EventHandler
== NULL
) {
961 AddrFile
->ErrorHandlerContext
= NULL
;
962 AddrFile
->RegisteredErrorHandler
= FALSE
;
964 AddrFile
->ErrorHandler
=
965 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
966 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
967 AddrFile
->RegisteredErrorHandler
= TRUE
;
971 case TDI_EVENT_RECEIVE
:
972 if (Parameters
->EventHandler
== NULL
) {
973 AddrFile
->ReceiveHandlerContext
= NULL
;
974 AddrFile
->RegisteredReceiveHandler
= FALSE
;
976 AddrFile
->ReceiveHandler
=
977 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
978 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
979 AddrFile
->RegisteredReceiveHandler
= TRUE
;
983 case TDI_EVENT_RECEIVE_DATAGRAM
:
984 if (Parameters
->EventHandler
== NULL
) {
985 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
986 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
988 AddrFile
->ReceiveDatagramHandler
=
989 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
990 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
991 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
995 case TDI_EVENT_RECEIVE_EXPEDITED
:
996 if (Parameters
->EventHandler
== NULL
) {
997 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
998 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1000 AddrFile
->ExpeditedReceiveHandler
=
1001 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1002 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1003 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1007 case TDI_EVENT_CHAINED_RECEIVE
:
1008 if (Parameters
->EventHandler
== NULL
) {
1009 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1010 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1012 AddrFile
->ChainedReceiveHandler
=
1013 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1014 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1015 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1019 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1020 if (Parameters
->EventHandler
== NULL
) {
1021 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1022 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1024 AddrFile
->ChainedReceiveDatagramHandler
=
1025 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1026 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1027 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1031 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1032 if (Parameters
->EventHandler
== NULL
) {
1033 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1034 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1036 AddrFile
->ChainedReceiveExpeditedHandler
=
1037 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1038 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1039 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1044 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1045 Parameters
->EventType
));
1047 Status
= STATUS_INVALID_PARAMETER
;
1050 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1056 NTSTATUS
DispTdiSetInformation(
1059 * FUNCTION: TDI_SET_INFORMATION handler
1061 * Irp = Pointer to an I/O request packet
1063 * Status of operation
1066 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1068 return STATUS_NOT_IMPLEMENTED
;
1072 VOID
DispTdiQueryInformationExComplete(
1077 * FUNCTION: Completes a TDI QueryInformationEx request
1079 * Context = Pointer to the IRP for the request
1080 * Status = TDI status of the request
1081 * ByteCount = Number of bytes returned in output buffer
1084 PTI_QUERY_CONTEXT QueryContext
;
1087 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1088 if (NT_SUCCESS(Status
)) {
1089 Count
= CopyBufferToBufferChain(
1090 QueryContext
->InputMdl
,
1091 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1092 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1096 MmUnlockPages(QueryContext
->InputMdl
);
1097 IoFreeMdl(QueryContext
->InputMdl
);
1098 if( QueryContext
->OutputMdl
) {
1099 MmUnlockPages(QueryContext
->OutputMdl
);
1100 IoFreeMdl(QueryContext
->OutputMdl
);
1103 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1104 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1106 ExFreePool(QueryContext
);
1110 NTSTATUS
DispTdiQueryInformationEx(
1112 PIO_STACK_LOCATION IrpSp
)
1114 * FUNCTION: TDI QueryInformationEx handler
1116 * Irp = Pointer to I/O request packet
1117 * IrpSp = Pointer to current stack location of Irp
1119 * Status of operation
1122 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1123 PTRANSPORT_CONTEXT TranContext
;
1124 PTI_QUERY_CONTEXT QueryContext
;
1126 TDI_REQUEST Request
;
1128 UINT InputBufferLength
;
1129 UINT OutputBufferLength
;
1130 BOOLEAN InputMdlLocked
= FALSE
;
1131 BOOLEAN OutputMdlLocked
= FALSE
;
1132 PMDL InputMdl
= NULL
;
1133 PMDL OutputMdl
= NULL
;
1134 NTSTATUS Status
= STATUS_SUCCESS
;
1136 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1138 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1140 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1141 case TDI_TRANSPORT_ADDRESS_FILE
:
1142 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1145 case TDI_CONNECTION_FILE
:
1146 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1149 case TDI_CONTROL_CHANNEL_FILE
:
1150 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1154 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1155 return STATUS_INVALID_PARAMETER
;
1158 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1159 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1161 /* Validate parameters */
1162 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1163 (OutputBufferLength
!= 0)) {
1165 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1166 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1167 OutputBuffer
= Irp
->UserBuffer
;
1169 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1172 InputMdl
= IoAllocateMdl(InputBuffer
,
1173 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1176 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1177 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1179 if (InputMdl
&& OutputMdl
) {
1181 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1184 InputMdlLocked
= TRUE
;
1186 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1189 OutputMdlLocked
= TRUE
;
1191 RtlCopyMemory(&QueryContext
->QueryInfo
,
1192 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1194 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1196 Status
= _SEH_GetExceptionCode();
1199 if (NT_SUCCESS(Status
)) {
1200 Size
= MmGetMdlByteCount(OutputMdl
);
1202 QueryContext
->Irp
= Irp
;
1203 QueryContext
->InputMdl
= InputMdl
;
1204 QueryContext
->OutputMdl
= OutputMdl
;
1206 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1207 Request
.RequestContext
= QueryContext
;
1208 Status
= InfoTdiQueryInformationEx(&Request
,
1209 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1210 &Size
, &QueryContext
->QueryInfo
.Context
);
1211 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1213 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1218 /* An error occurred if we get here */
1222 MmUnlockPages(InputMdl
);
1223 IoFreeMdl(InputMdl
);
1227 if (OutputMdlLocked
)
1228 MmUnlockPages(OutputMdl
);
1229 IoFreeMdl(OutputMdl
);
1232 ExFreePool(QueryContext
);
1234 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1235 } else if( InputBufferLength
==
1236 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1237 /* Handle the case where the user is probing the buffer for length */
1238 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1239 InputBufferLength
, OutputBufferLength
));
1240 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1241 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1245 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1246 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1249 InputMdl
= IoAllocateMdl(InputBuffer
,
1250 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1253 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1256 InputMdlLocked
= TRUE
;
1257 Status
= STATUS_SUCCESS
;
1259 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1260 Status
= _SEH_GetExceptionCode();
1263 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1264 if( InputMdl
) IoFreeMdl( InputMdl
);
1265 ExFreePool(QueryContext
);
1269 RtlCopyMemory(&QueryContext
->QueryInfo
,
1270 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1272 QueryContext
->Irp
= Irp
;
1273 QueryContext
->InputMdl
= InputMdl
;
1274 QueryContext
->OutputMdl
= NULL
;
1276 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1277 Request
.RequestContext
= QueryContext
;
1278 Status
= InfoTdiQueryInformationEx(&Request
,
1279 &QueryContext
->QueryInfo
.ID
,
1282 &QueryContext
->QueryInfo
.Context
);
1283 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1284 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1285 } else Status
= STATUS_INVALID_PARAMETER
;
1287 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1293 NTSTATUS
DispTdiSetInformationEx(
1295 PIO_STACK_LOCATION IrpSp
)
1297 * FUNCTION: TDI SetInformationEx handler
1299 * Irp = Pointer to I/O request packet
1300 * IrpSp = Pointer to current stack location of Irp
1302 * Status of operation
1305 PTRANSPORT_CONTEXT TranContext
;
1306 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1307 TDI_REQUEST Request
;
1311 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1313 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1314 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1316 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1317 case TDI_TRANSPORT_ADDRESS_FILE
:
1318 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1321 case TDI_CONNECTION_FILE
:
1322 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1325 case TDI_CONTROL_CHANNEL_FILE
:
1326 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1330 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1331 Irp
->IoStatus
.Information
= 0;
1333 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1335 return IRPFinish(Irp
, STATUS_INVALID_PARAMETER
);
1338 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1339 if (NT_SUCCESS(Status
)) {
1340 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1341 Request
.RequestContext
= Irp
;
1343 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1344 &Info
->Buffer
, Info
->BufferSize
);
1346 if (Status
!= STATUS_PENDING
) {
1347 IoAcquireCancelSpinLock(&OldIrql
);
1348 IoSetCancelRoutine(Irp
, NULL
);
1349 IoReleaseCancelSpinLock(OldIrql
);