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
IRPFinish( PIRP Irp
, NTSTATUS Status
) {
17 Irp
->IoStatus
.Status
= Status
;
19 if( Status
== STATUS_PENDING
)
20 IoMarkIrpPending( Irp
);
22 IoAcquireCancelSpinLock(&OldIrql
);
23 (void)IoSetCancelRoutine( Irp
, NULL
);
24 IoReleaseCancelSpinLock(OldIrql
);
26 IoCompleteRequest( Irp
, IO_NETWORK_INCREMENT
);
32 NTSTATUS
DispPrepareIrpForCancel(
33 PTRANSPORT_CONTEXT Context
,
35 PDRIVER_CANCEL CancelRoutine
)
37 * FUNCTION: Prepare an IRP for cancellation
39 * Context = Pointer to context information
40 * Irp = Pointer to an I/O request packet
41 * CancelRoutine = Routine to be called when I/O request is cancelled
47 PIO_STACK_LOCATION IrpSp
;
48 PTRANSPORT_CONTEXT TransContext
;
50 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
52 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
53 TransContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
55 IoAcquireCancelSpinLock(&OldIrql
);
57 if (!Irp
->Cancel
&& !TransContext
->CancelIrps
) {
58 (void)IoSetCancelRoutine(Irp
, CancelRoutine
);
59 IoReleaseCancelSpinLock(OldIrql
);
61 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
63 return STATUS_SUCCESS
;
66 /* IRP has already been cancelled */
68 IoReleaseCancelSpinLock(OldIrql
);
70 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
71 Irp
->IoStatus
.Information
= 0;
73 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
75 return Irp
->IoStatus
.Status
;
78 VOID
DispDataRequestComplete(
83 * FUNCTION: Completes a send/receive IRP
85 * Context = Pointer to context information (IRP)
86 * Status = Status of the request
87 * Count = Number of bytes sent or received
92 TI_DbgPrint(DEBUG_IRP
, ("Called for irp %x (%x, %d).\n",
95 Irp
->IoStatus
.Status
= Status
;
96 Irp
->IoStatus
.Information
= Count
;
98 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
99 Irp
->IoStatus
.Status
));
100 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
101 Irp
->IoStatus
.Information
));
102 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
104 IRPFinish(Irp
, Status
);
106 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
109 VOID NTAPI
DispCancelRequest(
110 PDEVICE_OBJECT Device
,
113 * FUNCTION: Cancels an IRP
115 * Device = Pointer to device object
116 * Irp = Pointer to an I/O request packet
119 PIO_STACK_LOCATION IrpSp
;
120 PTRANSPORT_CONTEXT TranContext
;
121 PFILE_OBJECT FileObject
;
123 PCONNECTION_ENDPOINT Connection
;
124 BOOLEAN DequeuedIrp
= TRUE
;
126 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
128 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
130 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
131 FileObject
= IrpSp
->FileObject
;
132 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
133 MinorFunction
= IrpSp
->MinorFunction
;
135 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
137 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
138 Irp
->IoStatus
.Information
= 0;
142 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
145 /* Try canceling the request */
146 switch(MinorFunction
) {
149 DequeuedIrp
= TCPRemoveIRP( TranContext
->Handle
.ConnectionContext
, Irp
);
152 case TDI_SEND_DATAGRAM
:
153 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
154 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
158 DequeuedIrp
= DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
161 case TDI_RECEIVE_DATAGRAM
:
162 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
163 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
167 DequeuedIrp
= DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
171 DequeuedIrp
= TCPRemoveIRP(TranContext
->Handle
.ConnectionContext
, Irp
);
175 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
177 DequeuedIrp
= TCPRemoveIRP(TranContext
->Handle
.ConnectionContext
, Irp
);
180 if (KeCancelTimer(&Connection
->DisconnectTimer
))
182 DereferenceObject(Connection
);
188 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
194 IRPFinish(Irp
, STATUS_CANCELLED
);
196 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
200 VOID NTAPI
DispCancelListenRequest(
201 PDEVICE_OBJECT Device
,
204 * FUNCTION: Cancels a listen IRP
206 * Device = Pointer to device object
207 * Irp = Pointer to an I/O request packet
210 PIO_STACK_LOCATION IrpSp
;
211 PTRANSPORT_CONTEXT TranContext
;
212 PFILE_OBJECT FileObject
;
213 PCONNECTION_ENDPOINT Connection
;
215 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
217 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
219 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
220 FileObject
= IrpSp
->FileObject
;
221 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
222 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
224 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
228 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
231 /* Try canceling the request */
232 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
234 if (TCPAbortListenForSocket(Connection
->AddressFile
->Listener
,
237 Irp
->IoStatus
.Information
= 0;
238 IRPFinish(Irp
, STATUS_CANCELLED
);
241 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
245 NTSTATUS
DispTdiAccept(
248 * FUNCTION: TDI_ACCEPT handler
250 * Irp = Pointer to an I/O request packet
252 * Status of operation
255 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
257 return STATUS_NOT_IMPLEMENTED
;
261 NTSTATUS
DispTdiAssociateAddress(
264 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
266 * Irp = Pointer to an I/O request packet
268 * Status of operation
271 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
272 PTRANSPORT_CONTEXT TranContext
;
273 PIO_STACK_LOCATION IrpSp
;
274 PCONNECTION_ENDPOINT Connection
, LastConnection
;
275 PFILE_OBJECT FileObject
;
276 PADDRESS_FILE AddrFile
= NULL
;
280 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
282 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
284 /* Get associated connection endpoint file object. Quit if none exists */
286 TranContext
= IrpSp
->FileObject
->FsContext
;
288 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
289 return STATUS_INVALID_PARAMETER
;
292 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
294 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
295 return STATUS_INVALID_PARAMETER
;
298 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
300 Status
= ObReferenceObjectByHandle(
301 Parameters
->AddressHandle
,
307 if (!NT_SUCCESS(Status
)) {
308 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
309 Parameters
->AddressHandle
, Status
));
310 return STATUS_INVALID_PARAMETER
;
313 LockObject(Connection
, &OldIrql
);
315 if (Connection
->AddressFile
) {
316 ObDereferenceObject(FileObject
);
317 UnlockObject(Connection
, OldIrql
);
318 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
319 return STATUS_INVALID_PARAMETER
;
322 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
323 ObDereferenceObject(FileObject
);
324 UnlockObject(Connection
, OldIrql
);
325 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
326 FileObject
->FsContext2
));
327 return STATUS_INVALID_PARAMETER
;
330 /* Get associated address file object. Quit if none exists */
332 TranContext
= FileObject
->FsContext
;
334 ObDereferenceObject(FileObject
);
335 UnlockObject(Connection
, OldIrql
);
336 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
337 return STATUS_INVALID_PARAMETER
;
340 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
342 UnlockObject(Connection
, OldIrql
);
343 ObDereferenceObject(FileObject
);
344 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
345 return STATUS_INVALID_PARAMETER
;
348 LockObjectAtDpcLevel(AddrFile
);
350 ReferenceObject(AddrFile
);
351 Connection
->AddressFile
= AddrFile
;
353 /* Add connection endpoint to the address file */
354 ReferenceObject(Connection
);
355 if (AddrFile
->Connection
== NULL
)
356 AddrFile
->Connection
= Connection
;
359 LastConnection
= AddrFile
->Connection
;
360 while (LastConnection
->Next
!= NULL
)
361 LastConnection
= LastConnection
->Next
;
362 LastConnection
->Next
= Connection
;
365 ObDereferenceObject(FileObject
);
367 UnlockObjectFromDpcLevel(AddrFile
);
368 UnlockObject(Connection
, OldIrql
);
370 return STATUS_SUCCESS
;
374 NTSTATUS
DispTdiConnect(
377 * FUNCTION: TDI_CONNECT handler
379 * Irp = Pointer to an I/O request packet
381 * Status of operation
384 PCONNECTION_ENDPOINT Connection
;
385 PTDI_REQUEST_KERNEL Parameters
;
386 PTRANSPORT_CONTEXT TranContext
;
387 PIO_STACK_LOCATION IrpSp
;
390 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
392 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
394 /* Get associated connection endpoint file object. Quit if none exists */
396 TranContext
= IrpSp
->FileObject
->FsContext
;
398 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
399 Status
= STATUS_INVALID_PARAMETER
;
403 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
405 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
406 Status
= STATUS_INVALID_PARAMETER
;
410 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
412 Status
= DispPrepareIrpForCancel(TranContext
->Handle
.ConnectionContext
,
416 if (NT_SUCCESS(Status
)) {
418 TranContext
->Handle
.ConnectionContext
,
419 Parameters
->RequestConnectionInformation
,
420 Parameters
->ReturnConnectionInformation
,
421 DispDataRequestComplete
,
426 if (Status
!= STATUS_PENDING
) {
427 DispDataRequestComplete(Irp
, Status
, 0);
429 IoMarkIrpPending(Irp
);
431 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
437 NTSTATUS
DispTdiDisassociateAddress(
440 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
442 * Irp = Pointer to an I/O request packet
444 * Status of operation
447 PCONNECTION_ENDPOINT Connection
, LastConnection
;
448 PTRANSPORT_CONTEXT TranContext
;
449 PIO_STACK_LOCATION IrpSp
;
453 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
455 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
457 /* Get associated connection endpoint file object. Quit if none exists */
459 TranContext
= IrpSp
->FileObject
->FsContext
;
461 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
462 return STATUS_INVALID_PARAMETER
;
465 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
467 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
468 return STATUS_INVALID_PARAMETER
;
471 LockObject(Connection
, &OldIrql
);
473 if (!Connection
->AddressFile
) {
474 UnlockObject(Connection
, OldIrql
);
475 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
476 return STATUS_INVALID_PARAMETER
;
479 LockObjectAtDpcLevel(Connection
->AddressFile
);
481 /* Unlink this connection from the address file */
482 if (Connection
->AddressFile
->Connection
== Connection
)
484 Connection
->AddressFile
->Connection
= Connection
->Next
;
485 DereferenceObject(Connection
);
486 Status
= STATUS_SUCCESS
;
490 LastConnection
= Connection
->AddressFile
->Connection
;
491 while (LastConnection
->Next
!= Connection
&& LastConnection
->Next
!= NULL
)
492 LastConnection
= LastConnection
->Next
;
493 if (LastConnection
->Next
== Connection
)
495 LastConnection
->Next
= Connection
->Next
;
496 DereferenceObject(Connection
);
497 Status
= STATUS_SUCCESS
;
501 Status
= STATUS_INVALID_PARAMETER
;
505 UnlockObjectFromDpcLevel(Connection
->AddressFile
);
507 if (Status
== STATUS_SUCCESS
)
509 /* Remove the address file from this connection */
510 DereferenceObject(Connection
->AddressFile
);
511 Connection
->AddressFile
= NULL
;
514 UnlockObject(Connection
, OldIrql
);
520 NTSTATUS
DispTdiDisconnect(
523 * FUNCTION: TDI_DISCONNECT handler
525 * Irp = Pointer to an I/O request packet
527 * Status of operation
531 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
532 PCONNECTION_ENDPOINT Connection
;
533 PTRANSPORT_CONTEXT TranContext
;
534 PIO_STACK_LOCATION IrpSp
;
536 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
538 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
539 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
541 /* Get associated connection endpoint file object. Quit if none exists */
543 TranContext
= IrpSp
->FileObject
->FsContext
;
545 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
546 Status
= STATUS_INVALID_PARAMETER
;
550 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
552 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
553 Status
= STATUS_INVALID_PARAMETER
;
557 Status
= DispPrepareIrpForCancel
558 (TranContext
->Handle
.ConnectionContext
,
560 (PDRIVER_CANCEL
)DispCancelRequest
);
562 if (NT_SUCCESS(Status
))
564 Status
= TCPDisconnect(TranContext
->Handle
.ConnectionContext
,
565 DisReq
->RequestFlags
,
566 DisReq
->RequestSpecific
,
567 DisReq
->RequestConnectionInformation
,
568 DisReq
->ReturnConnectionInformation
,
569 DispDataRequestComplete
,
574 if (Status
!= STATUS_PENDING
) {
575 DispDataRequestComplete(Irp
, Status
, 0);
577 IoMarkIrpPending(Irp
);
579 TI_DbgPrint(MAX_TRACE
, ("TCP Disconnect returned %08x\n", Status
));
585 NTSTATUS
DispTdiListen(
588 * FUNCTION: TDI_LISTEN handler
590 * Irp = Pointer to an I/O request packet
592 * Status of operation
595 PCONNECTION_ENDPOINT Connection
;
596 PTDI_REQUEST_KERNEL Parameters
;
597 PTRANSPORT_CONTEXT TranContext
;
598 PIO_STACK_LOCATION IrpSp
;
599 NTSTATUS Status
= STATUS_SUCCESS
;
602 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
604 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
606 /* Get associated connection endpoint file object. Quit if none exists */
608 TranContext
= IrpSp
->FileObject
->FsContext
;
609 if (TranContext
== NULL
)
611 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
612 Status
= STATUS_INVALID_PARAMETER
;
616 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
617 if (Connection
== NULL
)
619 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
620 Status
= STATUS_INVALID_PARAMETER
;
624 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
626 Status
= DispPrepareIrpForCancel
627 (TranContext
->Handle
.ConnectionContext
,
629 (PDRIVER_CANCEL
)DispCancelListenRequest
);
631 LockObject(Connection
, &OldIrql
);
633 if (Connection
->AddressFile
== NULL
)
635 TI_DbgPrint(MID_TRACE
, ("No associated address file\n"));
636 UnlockObject(Connection
, OldIrql
);
637 Status
= STATUS_INVALID_PARAMETER
;
641 LockObjectAtDpcLevel(Connection
->AddressFile
);
643 /* Listening will require us to create a listening socket and store it in
644 * the address file. It will be signalled, and attempt to complete an irp
645 * when a new connection arrives. */
646 /* The important thing to note here is that the irp we'll complete belongs
647 * to the socket to be accepted onto, not the listener */
648 if( NT_SUCCESS(Status
) && !Connection
->AddressFile
->Listener
) {
649 Connection
->AddressFile
->Listener
=
650 TCPAllocateConnectionEndpoint( NULL
);
652 if( !Connection
->AddressFile
->Listener
)
653 Status
= STATUS_NO_MEMORY
;
655 if( NT_SUCCESS(Status
) ) {
656 Connection
->AddressFile
->Listener
->AddressFile
=
657 Connection
->AddressFile
;
659 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
660 Connection
->AddressFile
->Family
,
662 Connection
->AddressFile
->Protocol
);
665 if( NT_SUCCESS(Status
) )
666 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
670 if( NT_SUCCESS(Status
) ) {
672 ( (PTDI_REQUEST
)Parameters
,
673 Connection
->AddressFile
->Listener
,
675 DispDataRequestComplete
,
679 UnlockObjectFromDpcLevel(Connection
->AddressFile
);
680 UnlockObject(Connection
, OldIrql
);
683 if (Status
!= STATUS_PENDING
) {
684 DispDataRequestComplete(Irp
, Status
, 0);
686 IoMarkIrpPending(Irp
);
688 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
694 NTSTATUS
DispTdiQueryInformation(
695 PDEVICE_OBJECT DeviceObject
,
698 * FUNCTION: TDI_QUERY_INFORMATION handler
700 * DeviceObject = Pointer to device object structure
701 * Irp = Pointer to an I/O request packet
703 * Status of operation
706 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
707 PTRANSPORT_CONTEXT TranContext
;
708 PIO_STACK_LOCATION IrpSp
;
710 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
712 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
713 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
715 TranContext
= IrpSp
->FileObject
->FsContext
;
717 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
718 return STATUS_INVALID_PARAMETER
;
721 switch (Parameters
->QueryType
)
723 case TDI_QUERY_ADDRESS_INFO
:
725 PTDI_ADDRESS_INFO AddressInfo
;
726 PADDRESS_FILE AddrFile
;
727 PTA_IP_ADDRESS Address
;
728 PCONNECTION_ENDPOINT Endpoint
= NULL
;
731 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
732 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
733 sizeof(TDI_ADDRESS_IP
))) {
734 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
735 return STATUS_BUFFER_TOO_SMALL
;
738 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
739 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
741 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
742 case TDI_TRANSPORT_ADDRESS_FILE
:
743 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
745 Address
->TAAddressCount
= 1;
746 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
747 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
748 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
749 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->Address
.Address
.IPv4Address
;
751 &Address
->Address
[0].Address
[0].sin_zero
,
752 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
753 return STATUS_SUCCESS
;
755 case TDI_CONNECTION_FILE
:
757 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
759 Address
->TAAddressCount
= 1;
760 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
761 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
762 Address
->Address
[0].Address
[0].sin_port
= Endpoint
->AddressFile
->Port
;
763 Address
->Address
[0].Address
[0].in_addr
= Endpoint
->AddressFile
->Address
.Address
.IPv4Address
;
765 &Address
->Address
[0].Address
[0].sin_zero
,
766 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
767 return STATUS_SUCCESS
;
770 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
771 return STATUS_INVALID_PARAMETER
;
775 case TDI_QUERY_CONNECTION_INFO
:
777 PTDI_CONNECTION_INFO ConnectionInfo
;
778 PCONNECTION_ENDPOINT Endpoint
;
780 if (MmGetMdlByteCount(Irp
->MdlAddress
) < sizeof(*ConnectionInfo
)) {
781 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
782 return STATUS_BUFFER_TOO_SMALL
;
785 ConnectionInfo
= (PTDI_CONNECTION_INFO
)
786 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
788 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
789 case TDI_CONNECTION_FILE
:
791 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
792 RtlZeroMemory(ConnectionInfo
, sizeof(*ConnectionInfo
));
793 return STATUS_SUCCESS
;
796 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
797 return STATUS_INVALID_PARAMETER
;
801 case TDI_QUERY_MAX_DATAGRAM_INFO
:
803 PTDI_MAX_DATAGRAM_INFO MaxDatagramInfo
;
805 if (MmGetMdlByteCount(Irp
->MdlAddress
) < sizeof(*MaxDatagramInfo
)) {
806 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
807 return STATUS_BUFFER_TOO_SMALL
;
810 MaxDatagramInfo
= (PTDI_MAX_DATAGRAM_INFO
)
811 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
813 MaxDatagramInfo
->MaxDatagramSize
= 0xFFFF;
815 return STATUS_SUCCESS
;
819 return STATUS_NOT_IMPLEMENTED
;
823 NTSTATUS
DispTdiReceive(
826 * FUNCTION: TDI_RECEIVE handler
828 * Irp = Pointer to an I/O request packet
830 * Status of operation
833 PIO_STACK_LOCATION IrpSp
;
834 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
835 PTRANSPORT_CONTEXT TranContext
;
837 ULONG BytesReceived
= 0;
839 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
841 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
842 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
844 TranContext
= IrpSp
->FileObject
->FsContext
;
845 if (TranContext
== NULL
)
847 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
848 Status
= STATUS_INVALID_PARAMETER
;
852 if (TranContext
->Handle
.ConnectionContext
== NULL
)
854 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
855 Status
= STATUS_INVALID_PARAMETER
;
859 /* Initialize a receive request */
860 Status
= DispPrepareIrpForCancel
861 (TranContext
->Handle
.ConnectionContext
,
863 (PDRIVER_CANCEL
)DispCancelRequest
);
865 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
866 if (NT_SUCCESS(Status
))
868 Status
= TCPReceiveData(
869 TranContext
->Handle
.ConnectionContext
,
870 (PNDIS_BUFFER
)Irp
->MdlAddress
,
871 ReceiveInfo
->ReceiveLength
,
873 ReceiveInfo
->ReceiveFlags
,
874 DispDataRequestComplete
,
879 if (Status
!= STATUS_PENDING
) {
880 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
882 IoMarkIrpPending(Irp
);
884 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
890 NTSTATUS
DispTdiReceiveDatagram(
893 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
895 * Irp = Pointer to an I/O request packet
897 * Status of operation
900 PIO_STACK_LOCATION IrpSp
;
901 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
902 PTRANSPORT_CONTEXT TranContext
;
905 ULONG BytesReceived
= 0;
907 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
909 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
910 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
912 TranContext
= IrpSp
->FileObject
->FsContext
;
913 if (TranContext
== NULL
)
915 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
916 Status
= STATUS_INVALID_PARAMETER
;
920 /* Initialize a receive request */
921 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
922 Request
.RequestNotifyObject
= DispDataRequestComplete
;
923 Request
.RequestContext
= Irp
;
925 Status
= DispPrepareIrpForCancel(
926 IrpSp
->FileObject
->FsContext
,
928 (PDRIVER_CANCEL
)DispCancelRequest
);
930 if (NT_SUCCESS(Status
))
935 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
939 Status
= DGReceiveDatagram(
940 Request
.Handle
.AddressHandle
,
941 DgramInfo
->ReceiveDatagramInformation
,
943 DgramInfo
->ReceiveLength
,
944 DgramInfo
->ReceiveFlags
,
945 DgramInfo
->ReturnDatagramInformation
,
947 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
953 if (Status
!= STATUS_PENDING
) {
954 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
956 IoMarkIrpPending(Irp
);
958 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
964 NTSTATUS
DispTdiSend(
967 * FUNCTION: TDI_SEND handler
969 * Irp = Pointer to an I/O request packet
971 * Status of operation
974 PIO_STACK_LOCATION IrpSp
;
975 PTDI_REQUEST_KERNEL_SEND SendInfo
;
976 PTRANSPORT_CONTEXT TranContext
;
980 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
982 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
983 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
985 TranContext
= IrpSp
->FileObject
->FsContext
;
986 if (TranContext
== NULL
)
988 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
989 Status
= STATUS_INVALID_PARAMETER
;
993 if (TranContext
->Handle
.ConnectionContext
== NULL
)
995 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
996 Status
= STATUS_INVALID_PARAMETER
;
1000 Status
= DispPrepareIrpForCancel(
1001 IrpSp
->FileObject
->FsContext
,
1003 (PDRIVER_CANCEL
)DispCancelRequest
);
1005 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
1006 if (NT_SUCCESS(Status
))
1011 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
1013 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
1014 Status
= TCPSendData(
1015 TranContext
->Handle
.ConnectionContext
,
1017 SendInfo
->SendLength
,
1019 SendInfo
->SendFlags
,
1020 DispDataRequestComplete
,
1025 if (Status
!= STATUS_PENDING
) {
1026 DispDataRequestComplete(Irp
, Status
, BytesSent
);
1028 IoMarkIrpPending(Irp
);
1030 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
1036 NTSTATUS
DispTdiSendDatagram(
1039 * FUNCTION: TDI_SEND_DATAGRAM handler
1041 * Irp = Pointer to an I/O request packet
1043 * Status of operation
1046 PIO_STACK_LOCATION IrpSp
;
1047 TDI_REQUEST Request
;
1048 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
1049 PTRANSPORT_CONTEXT TranContext
;
1052 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1054 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1055 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
1057 TranContext
= IrpSp
->FileObject
->FsContext
;
1058 if (TranContext
== NULL
)
1060 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
1061 Status
= STATUS_INVALID_PARAMETER
;
1065 /* Initialize a send request */
1066 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1067 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1068 Request
.RequestContext
= Irp
;
1070 Status
= DispPrepareIrpForCancel(
1071 IrpSp
->FileObject
->FsContext
,
1073 (PDRIVER_CANCEL
)DispCancelRequest
);
1075 if (NT_SUCCESS(Status
)) {
1079 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
1081 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
1085 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
1086 must be of type PTDI_ADDRESS_IP */
1087 TI_DbgPrint(MID_TRACE
,
1088 ("About to call send routine %x\n",
1089 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
1091 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
!= NULL
) )
1094 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
1095 Request
.Handle
.AddressHandle
,
1096 DgramInfo
->SendDatagramInformation
,
1100 Irp
->IoStatus
.Information
= DataUsed
;
1103 Status
= STATUS_UNSUCCESSFUL
;
1109 if (Status
!= STATUS_PENDING
) {
1110 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
1112 IoMarkIrpPending(Irp
);
1114 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
1120 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
1122 * FUNCTION: TDI_SET_EVENT_HANDER handler
1124 * Irp = Pointer to a I/O request packet
1126 * Status of operation
1129 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1130 PTRANSPORT_CONTEXT TranContext
;
1131 PIO_STACK_LOCATION IrpSp
;
1132 PADDRESS_FILE AddrFile
;
1136 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1138 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1140 /* Get associated address file object. Quit if none exists */
1142 TranContext
= IrpSp
->FileObject
->FsContext
;
1144 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1145 return STATUS_INVALID_PARAMETER
;
1148 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1150 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1151 return STATUS_INVALID_PARAMETER
;
1154 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1155 Status
= STATUS_SUCCESS
;
1157 LockObject(AddrFile
, &OldIrql
);
1159 /* Set the event handler. if an event handler is associated with
1160 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1161 If an event handler is not used it's flag is FALSE */
1162 switch (Parameters
->EventType
) {
1163 case TDI_EVENT_CONNECT
:
1164 if (!Parameters
->EventHandler
) {
1165 AddrFile
->ConnectHandlerContext
= NULL
;
1166 AddrFile
->RegisteredConnectHandler
= FALSE
;
1168 AddrFile
->ConnectHandler
=
1169 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1170 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1171 AddrFile
->RegisteredConnectHandler
= TRUE
;
1175 case TDI_EVENT_DISCONNECT
:
1176 if (!Parameters
->EventHandler
) {
1177 AddrFile
->DisconnectHandlerContext
= NULL
;
1178 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1180 AddrFile
->DisconnectHandler
=
1181 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1182 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1183 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1187 case TDI_EVENT_ERROR
:
1188 if (Parameters
->EventHandler
== NULL
) {
1189 AddrFile
->ErrorHandlerContext
= NULL
;
1190 AddrFile
->RegisteredErrorHandler
= FALSE
;
1192 AddrFile
->ErrorHandler
=
1193 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1194 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1195 AddrFile
->RegisteredErrorHandler
= TRUE
;
1199 case TDI_EVENT_RECEIVE
:
1200 if (Parameters
->EventHandler
== NULL
) {
1201 AddrFile
->ReceiveHandlerContext
= NULL
;
1202 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1204 AddrFile
->ReceiveHandler
=
1205 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1206 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1207 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1211 case TDI_EVENT_RECEIVE_DATAGRAM
:
1212 if (Parameters
->EventHandler
== NULL
) {
1213 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1214 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1216 AddrFile
->ReceiveDatagramHandler
=
1217 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1218 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1219 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1223 case TDI_EVENT_RECEIVE_EXPEDITED
:
1224 if (Parameters
->EventHandler
== NULL
) {
1225 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1226 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1228 AddrFile
->ExpeditedReceiveHandler
=
1229 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1230 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1231 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1235 case TDI_EVENT_CHAINED_RECEIVE
:
1236 if (Parameters
->EventHandler
== NULL
) {
1237 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1238 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1240 AddrFile
->ChainedReceiveHandler
=
1241 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1242 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1243 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1247 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1248 if (Parameters
->EventHandler
== NULL
) {
1249 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1250 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1252 AddrFile
->ChainedReceiveDatagramHandler
=
1253 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1254 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1255 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1259 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1260 if (Parameters
->EventHandler
== NULL
) {
1261 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1262 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1264 AddrFile
->ChainedReceiveExpeditedHandler
=
1265 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1266 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1267 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1272 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1273 Parameters
->EventType
));
1275 Status
= STATUS_INVALID_PARAMETER
;
1278 UnlockObject(AddrFile
, OldIrql
);
1284 NTSTATUS
DispTdiSetInformation(
1287 * FUNCTION: TDI_SET_INFORMATION handler
1289 * Irp = Pointer to an I/O request packet
1291 * Status of operation
1294 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1296 return STATUS_NOT_IMPLEMENTED
;
1300 VOID
DispTdiQueryInformationExComplete(
1305 * FUNCTION: Completes a TDI QueryInformationEx request
1307 * Context = Pointer to the IRP for the request
1308 * Status = TDI status of the request
1309 * ByteCount = Number of bytes returned in output buffer
1312 PTI_QUERY_CONTEXT QueryContext
;
1314 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1315 if (NT_SUCCESS(Status
)) {
1316 CopyBufferToBufferChain(
1317 QueryContext
->InputMdl
,
1318 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1319 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1323 MmUnlockPages(QueryContext
->InputMdl
);
1324 IoFreeMdl(QueryContext
->InputMdl
);
1325 if( QueryContext
->OutputMdl
) {
1326 MmUnlockPages(QueryContext
->OutputMdl
);
1327 IoFreeMdl(QueryContext
->OutputMdl
);
1330 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1331 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1333 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1337 NTSTATUS
DispTdiQueryInformationEx(
1339 PIO_STACK_LOCATION IrpSp
)
1341 * FUNCTION: TDI QueryInformationEx handler
1343 * Irp = Pointer to I/O request packet
1344 * IrpSp = Pointer to current stack location of Irp
1346 * Status of operation
1349 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1350 PTRANSPORT_CONTEXT TranContext
;
1351 PTI_QUERY_CONTEXT QueryContext
;
1353 TDI_REQUEST Request
;
1355 UINT InputBufferLength
;
1356 UINT OutputBufferLength
;
1357 BOOLEAN InputMdlLocked
= FALSE
;
1358 BOOLEAN OutputMdlLocked
= FALSE
;
1359 PMDL InputMdl
= NULL
;
1360 PMDL OutputMdl
= NULL
;
1361 NTSTATUS Status
= STATUS_SUCCESS
;
1363 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1365 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1367 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
1368 case TDI_TRANSPORT_ADDRESS_FILE
:
1369 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1372 case TDI_CONNECTION_FILE
:
1373 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1376 case TDI_CONTROL_CHANNEL_FILE
:
1377 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1381 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1382 return STATUS_INVALID_PARAMETER
;
1385 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1386 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1388 /* Validate parameters */
1389 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1390 (OutputBufferLength
!= 0)) {
1392 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1393 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1394 OutputBuffer
= Irp
->UserBuffer
;
1396 QueryContext
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
), QUERY_CONTEXT_TAG
);
1399 InputMdl
= IoAllocateMdl(InputBuffer
,
1400 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1403 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1404 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1406 if (InputMdl
&& OutputMdl
) {
1408 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1411 InputMdlLocked
= TRUE
;
1413 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1416 OutputMdlLocked
= TRUE
;
1418 RtlCopyMemory(&QueryContext
->QueryInfo
,
1419 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1421 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1422 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1423 Status
= _SEH2_GetExceptionCode();
1426 if (NT_SUCCESS(Status
)) {
1427 Size
= MmGetMdlByteCount(OutputMdl
);
1429 QueryContext
->Irp
= Irp
;
1430 QueryContext
->InputMdl
= InputMdl
;
1431 QueryContext
->OutputMdl
= OutputMdl
;
1433 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1434 Request
.RequestContext
= QueryContext
;
1435 Status
= InfoTdiQueryInformationEx(&Request
,
1436 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1437 &Size
, &QueryContext
->QueryInfo
.Context
);
1438 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1440 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1445 /* An error occurred if we get here */
1449 MmUnlockPages(InputMdl
);
1450 IoFreeMdl(InputMdl
);
1454 if (OutputMdlLocked
)
1455 MmUnlockPages(OutputMdl
);
1456 IoFreeMdl(OutputMdl
);
1459 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1461 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1462 } else if( InputBufferLength
==
1463 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1464 /* Handle the case where the user is probing the buffer for length */
1465 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1466 InputBufferLength
, OutputBufferLength
));
1467 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1468 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1472 QueryContext
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
), QUERY_CONTEXT_TAG
);
1473 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1476 InputMdl
= IoAllocateMdl(InputBuffer
,
1477 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1480 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1483 InputMdlLocked
= TRUE
;
1484 Status
= STATUS_SUCCESS
;
1485 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1486 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1487 Status
= _SEH2_GetExceptionCode();
1490 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1491 if( InputMdl
) IoFreeMdl( InputMdl
);
1492 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1496 RtlCopyMemory(&QueryContext
->QueryInfo
,
1497 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1499 QueryContext
->Irp
= Irp
;
1500 QueryContext
->InputMdl
= InputMdl
;
1501 QueryContext
->OutputMdl
= NULL
;
1503 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1504 Request
.RequestContext
= QueryContext
;
1505 Status
= InfoTdiQueryInformationEx(&Request
,
1506 &QueryContext
->QueryInfo
.ID
,
1509 &QueryContext
->QueryInfo
.Context
);
1510 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1511 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1512 } else Status
= STATUS_INVALID_PARAMETER
;
1514 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1520 NTSTATUS
DispTdiSetInformationEx(
1522 PIO_STACK_LOCATION IrpSp
)
1524 * FUNCTION: TDI SetInformationEx handler
1526 * Irp = Pointer to I/O request packet
1527 * IrpSp = Pointer to current stack location of Irp
1529 * Status of operation
1532 PTRANSPORT_CONTEXT TranContext
;
1533 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1534 TDI_REQUEST Request
;
1537 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1539 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1540 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1542 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
1543 case TDI_TRANSPORT_ADDRESS_FILE
:
1544 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1547 case TDI_CONNECTION_FILE
:
1548 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1551 case TDI_CONTROL_CHANNEL_FILE
:
1552 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1556 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1557 Irp
->IoStatus
.Information
= 0;
1559 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1561 return Irp
->IoStatus
.Status
;
1564 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1565 if (NT_SUCCESS(Status
)) {
1566 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1567 Request
.RequestContext
= Irp
;
1569 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1570 &Info
->Buffer
, Info
->BufferSize
);
1576 /* TODO: Support multiple addresses per interface.
1577 * For now just set the nte context to the interface index.
1579 * Later on, create an NTE context and NTE instance
1582 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1583 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1584 PIP_SET_ADDRESS IpAddrChange
=
1585 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1588 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1589 IpAddrChange
->NteIndex
));
1591 ForEachInterface(IF
) {
1592 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1594 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1595 Status
= STATUS_DUPLICATE_OBJECTID
;
1598 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1599 IPRemoveInterfaceRoute( IF
);
1601 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1602 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1603 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1604 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1605 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1606 IF
->Broadcast
.Address
.IPv4Address
=
1607 IF
->Unicast
.Address
.IPv4Address
|
1608 ~IF
->Netmask
.Address
.IPv4Address
;
1610 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1611 IF
->Unicast
.Address
.IPv4Address
));
1612 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1613 IF
->Netmask
.Address
.IPv4Address
));
1615 IPAddInterfaceRoute( IF
);
1617 IpAddrChange
->Address
= IF
->Index
;
1618 Status
= STATUS_SUCCESS
;
1619 Irp
->IoStatus
.Information
= IF
->Index
;
1624 Irp
->IoStatus
.Status
= Status
;
1628 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1629 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1630 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1633 ForEachInterface(IF
) {
1634 if( IF
->Index
== *NteIndex
) {
1635 IPRemoveInterfaceRoute( IF
);
1636 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1637 IF
->Unicast
.Address
.IPv4Address
= 0;
1638 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1639 IF
->Netmask
.Address
.IPv4Address
= 0;
1640 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1641 IF
->Broadcast
.Address
.IPv4Address
= 0;
1642 Status
= STATUS_SUCCESS
;
1646 Irp
->IoStatus
.Status
= Status
;