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 #include <pseh/pseh2.h>
17 NTSTATUS
IRPFinish( PIRP Irp
, NTSTATUS Status
) {
20 Irp
->IoStatus
.Status
= Status
;
22 if( Status
== STATUS_PENDING
)
23 IoMarkIrpPending( Irp
);
25 IoAcquireCancelSpinLock(&OldIrql
);
26 (void)IoSetCancelRoutine( Irp
, NULL
);
27 IoReleaseCancelSpinLock(OldIrql
);
29 IoCompleteRequest( Irp
, IO_NETWORK_INCREMENT
);
35 NTSTATUS
DispPrepareIrpForCancel(
36 PTRANSPORT_CONTEXT Context
,
38 PDRIVER_CANCEL CancelRoutine
)
40 * FUNCTION: Prepare an IRP for cancellation
42 * Context = Pointer to context information
43 * Irp = Pointer to an I/O request packet
44 * CancelRoutine = Routine to be called when I/O request is cancelled
50 PIO_STACK_LOCATION IrpSp
;
51 PTRANSPORT_CONTEXT TransContext
;
53 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
55 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
56 TransContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
58 IoAcquireCancelSpinLock(&OldIrql
);
60 if (!Irp
->Cancel
&& !TransContext
->CancelIrps
) {
61 (void)IoSetCancelRoutine(Irp
, CancelRoutine
);
62 IoReleaseCancelSpinLock(OldIrql
);
64 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
66 return STATUS_SUCCESS
;
69 /* IRP has already been cancelled */
71 IoReleaseCancelSpinLock(OldIrql
);
73 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
74 Irp
->IoStatus
.Information
= 0;
76 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
78 return Irp
->IoStatus
.Status
;
81 VOID
DispDataRequestComplete(
86 * FUNCTION: Completes a send/receive IRP
88 * Context = Pointer to context information (IRP)
89 * Status = Status of the request
90 * Count = Number of bytes sent or received
95 TI_DbgPrint(DEBUG_IRP
, ("Called for irp %x (%x, %d).\n",
98 Irp
->IoStatus
.Status
= Status
;
99 Irp
->IoStatus
.Information
= Count
;
101 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
102 Irp
->IoStatus
.Status
));
103 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
104 Irp
->IoStatus
.Information
));
105 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
107 IRPFinish(Irp
, Status
);
109 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
112 VOID NTAPI
DispCancelRequest(
113 PDEVICE_OBJECT Device
,
116 * FUNCTION: Cancels an IRP
118 * Device = Pointer to device object
119 * Irp = Pointer to an I/O request packet
122 PIO_STACK_LOCATION IrpSp
;
123 PTRANSPORT_CONTEXT TranContext
;
124 PFILE_OBJECT FileObject
;
126 PCONNECTION_ENDPOINT Connection
;
127 BOOLEAN DequeuedIrp
= TRUE
;
129 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
131 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
133 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
134 FileObject
= IrpSp
->FileObject
;
135 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
136 MinorFunction
= IrpSp
->MinorFunction
;
138 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
140 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
141 Irp
->IoStatus
.Information
= 0;
145 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
148 /* Try canceling the request */
149 switch(MinorFunction
) {
152 DequeuedIrp
= TCPRemoveIRP( TranContext
->Handle
.ConnectionContext
, Irp
);
155 case TDI_SEND_DATAGRAM
:
156 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
157 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
161 DequeuedIrp
= DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
164 case TDI_RECEIVE_DATAGRAM
:
165 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
166 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
170 DequeuedIrp
= DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
174 DequeuedIrp
= TCPRemoveIRP(TranContext
->Handle
.ConnectionContext
, Irp
);
178 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
180 DequeuedIrp
= TCPRemoveIRP(TranContext
->Handle
.ConnectionContext
, Irp
);
183 if (KeCancelTimer(&Connection
->DisconnectTimer
))
185 DereferenceObject(Connection
);
191 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
197 IRPFinish(Irp
, STATUS_CANCELLED
);
199 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
203 VOID NTAPI
DispCancelListenRequest(
204 PDEVICE_OBJECT Device
,
207 * FUNCTION: Cancels a listen IRP
209 * Device = Pointer to device object
210 * Irp = Pointer to an I/O request packet
213 PIO_STACK_LOCATION IrpSp
;
214 PTRANSPORT_CONTEXT TranContext
;
215 PFILE_OBJECT FileObject
;
216 PCONNECTION_ENDPOINT Connection
;
218 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
220 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
222 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
223 FileObject
= IrpSp
->FileObject
;
224 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
225 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
227 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
231 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
234 /* Try canceling the request */
235 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
237 if (TCPAbortListenForSocket(Connection
->AddressFile
->Listener
,
240 Irp
->IoStatus
.Information
= 0;
241 IRPFinish(Irp
, STATUS_CANCELLED
);
244 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
248 NTSTATUS
DispTdiAccept(
251 * FUNCTION: TDI_ACCEPT handler
253 * Irp = Pointer to an I/O request packet
255 * Status of operation
258 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
260 return STATUS_NOT_IMPLEMENTED
;
264 NTSTATUS
DispTdiAssociateAddress(
267 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
269 * Irp = Pointer to an I/O request packet
271 * Status of operation
274 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
275 PTRANSPORT_CONTEXT TranContext
;
276 PIO_STACK_LOCATION IrpSp
;
277 PCONNECTION_ENDPOINT Connection
, LastConnection
;
278 PFILE_OBJECT FileObject
;
279 PADDRESS_FILE AddrFile
= NULL
;
283 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
285 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
287 /* Get associated connection endpoint file object. Quit if none exists */
289 TranContext
= IrpSp
->FileObject
->FsContext
;
291 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
292 return STATUS_INVALID_PARAMETER
;
295 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
297 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
298 return STATUS_INVALID_PARAMETER
;
301 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
303 Status
= ObReferenceObjectByHandle(
304 Parameters
->AddressHandle
,
310 if (!NT_SUCCESS(Status
)) {
311 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
312 Parameters
->AddressHandle
, Status
));
313 return STATUS_INVALID_PARAMETER
;
316 LockObject(Connection
, &OldIrql
);
318 if (Connection
->AddressFile
) {
319 ObDereferenceObject(FileObject
);
320 UnlockObject(Connection
, OldIrql
);
321 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
322 return STATUS_INVALID_PARAMETER
;
325 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
326 ObDereferenceObject(FileObject
);
327 UnlockObject(Connection
, OldIrql
);
328 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
329 FileObject
->FsContext2
));
330 return STATUS_INVALID_PARAMETER
;
333 /* Get associated address file object. Quit if none exists */
335 TranContext
= FileObject
->FsContext
;
337 ObDereferenceObject(FileObject
);
338 UnlockObject(Connection
, OldIrql
);
339 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
340 return STATUS_INVALID_PARAMETER
;
343 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
345 UnlockObject(Connection
, OldIrql
);
346 ObDereferenceObject(FileObject
);
347 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
348 return STATUS_INVALID_PARAMETER
;
351 LockObjectAtDpcLevel(AddrFile
);
353 ReferenceObject(AddrFile
);
354 Connection
->AddressFile
= AddrFile
;
356 /* Add connection endpoint to the address file */
357 ReferenceObject(Connection
);
358 if (AddrFile
->Connection
== NULL
)
359 AddrFile
->Connection
= Connection
;
362 LastConnection
= AddrFile
->Connection
;
363 while (LastConnection
->Next
!= NULL
)
364 LastConnection
= LastConnection
->Next
;
365 LastConnection
->Next
= Connection
;
368 ObDereferenceObject(FileObject
);
370 UnlockObjectFromDpcLevel(AddrFile
);
371 UnlockObject(Connection
, OldIrql
);
373 return STATUS_SUCCESS
;
377 NTSTATUS
DispTdiConnect(
380 * FUNCTION: TDI_CONNECT handler
382 * Irp = Pointer to an I/O request packet
384 * Status of operation
387 PCONNECTION_ENDPOINT Connection
;
388 PTDI_REQUEST_KERNEL Parameters
;
389 PTRANSPORT_CONTEXT TranContext
;
390 PIO_STACK_LOCATION IrpSp
;
393 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
395 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
397 /* Get associated connection endpoint file object. Quit if none exists */
399 TranContext
= IrpSp
->FileObject
->FsContext
;
401 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
402 Status
= STATUS_INVALID_PARAMETER
;
406 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
408 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
409 Status
= STATUS_INVALID_PARAMETER
;
413 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
415 Status
= DispPrepareIrpForCancel(TranContext
->Handle
.ConnectionContext
,
419 if (NT_SUCCESS(Status
)) {
421 TranContext
->Handle
.ConnectionContext
,
422 Parameters
->RequestConnectionInformation
,
423 Parameters
->ReturnConnectionInformation
,
424 DispDataRequestComplete
,
429 if (Status
!= STATUS_PENDING
) {
430 DispDataRequestComplete(Irp
, Status
, 0);
432 IoMarkIrpPending(Irp
);
434 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
440 NTSTATUS
DispTdiDisassociateAddress(
443 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
445 * Irp = Pointer to an I/O request packet
447 * Status of operation
450 PCONNECTION_ENDPOINT Connection
;
451 PTRANSPORT_CONTEXT TranContext
;
452 PIO_STACK_LOCATION IrpSp
;
454 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
456 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
458 /* Get associated connection endpoint file object. Quit if none exists */
460 TranContext
= IrpSp
->FileObject
->FsContext
;
462 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
463 return STATUS_INVALID_PARAMETER
;
466 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
468 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
469 return STATUS_INVALID_PARAMETER
;
472 /* NO-OP because we need the address to deallocate the port when the connection closes */
474 return STATUS_SUCCESS
;
478 NTSTATUS
DispTdiDisconnect(
481 * FUNCTION: TDI_DISCONNECT handler
483 * Irp = Pointer to an I/O request packet
485 * Status of operation
489 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
490 PCONNECTION_ENDPOINT Connection
;
491 PTRANSPORT_CONTEXT TranContext
;
492 PIO_STACK_LOCATION IrpSp
;
494 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
496 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
497 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
499 /* Get associated connection endpoint file object. Quit if none exists */
501 TranContext
= IrpSp
->FileObject
->FsContext
;
503 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
504 Status
= STATUS_INVALID_PARAMETER
;
508 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
510 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
511 Status
= STATUS_INVALID_PARAMETER
;
515 Status
= DispPrepareIrpForCancel
516 (TranContext
->Handle
.ConnectionContext
,
518 (PDRIVER_CANCEL
)DispCancelRequest
);
520 if (NT_SUCCESS(Status
))
522 Status
= TCPDisconnect(TranContext
->Handle
.ConnectionContext
,
523 DisReq
->RequestFlags
,
524 DisReq
->RequestSpecific
,
525 DisReq
->RequestConnectionInformation
,
526 DisReq
->ReturnConnectionInformation
,
527 DispDataRequestComplete
,
532 if (Status
!= STATUS_PENDING
) {
533 DispDataRequestComplete(Irp
, Status
, 0);
535 IoMarkIrpPending(Irp
);
537 TI_DbgPrint(MAX_TRACE
, ("TCP Disconnect returned %08x\n", Status
));
543 NTSTATUS
DispTdiListen(
546 * FUNCTION: TDI_LISTEN handler
548 * Irp = Pointer to an I/O request packet
550 * Status of operation
553 PCONNECTION_ENDPOINT Connection
;
554 PTDI_REQUEST_KERNEL Parameters
;
555 PTRANSPORT_CONTEXT TranContext
;
556 PIO_STACK_LOCATION IrpSp
;
557 NTSTATUS Status
= STATUS_SUCCESS
;
560 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
562 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
564 /* Get associated connection endpoint file object. Quit if none exists */
566 TranContext
= IrpSp
->FileObject
->FsContext
;
567 if (TranContext
== NULL
)
569 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
570 Status
= STATUS_INVALID_PARAMETER
;
574 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
575 if (Connection
== NULL
)
577 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
578 Status
= STATUS_INVALID_PARAMETER
;
582 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
584 Status
= DispPrepareIrpForCancel
585 (TranContext
->Handle
.ConnectionContext
,
587 (PDRIVER_CANCEL
)DispCancelListenRequest
);
589 LockObject(Connection
, &OldIrql
);
591 if (Connection
->AddressFile
== NULL
)
593 TI_DbgPrint(MID_TRACE
, ("No associated address file\n"));
594 UnlockObject(Connection
, OldIrql
);
595 Status
= STATUS_INVALID_PARAMETER
;
599 LockObjectAtDpcLevel(Connection
->AddressFile
);
601 /* Listening will require us to create a listening socket and store it in
602 * the address file. It will be signalled, and attempt to complete an irp
603 * when a new connection arrives. */
604 /* The important thing to note here is that the irp we'll complete belongs
605 * to the socket to be accepted onto, not the listener */
606 if( NT_SUCCESS(Status
) && !Connection
->AddressFile
->Listener
) {
607 Connection
->AddressFile
->Listener
=
608 TCPAllocateConnectionEndpoint( NULL
);
610 if( !Connection
->AddressFile
->Listener
)
611 Status
= STATUS_NO_MEMORY
;
613 if( NT_SUCCESS(Status
) ) {
614 ReferenceObject(Connection
->AddressFile
);
615 Connection
->AddressFile
->Listener
->AddressFile
=
616 Connection
->AddressFile
;
618 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
619 Connection
->AddressFile
->Family
,
621 Connection
->AddressFile
->Protocol
);
624 if( NT_SUCCESS(Status
) ) {
625 ReferenceObject(Connection
->AddressFile
->Listener
);
626 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
631 if( NT_SUCCESS(Status
) ) {
633 ( (PTDI_REQUEST
)Parameters
,
634 Connection
->AddressFile
->Listener
,
636 DispDataRequestComplete
,
640 UnlockObjectFromDpcLevel(Connection
->AddressFile
);
641 UnlockObject(Connection
, OldIrql
);
644 if (Status
!= STATUS_PENDING
) {
645 DispDataRequestComplete(Irp
, Status
, 0);
647 IoMarkIrpPending(Irp
);
649 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
655 NTSTATUS
DispTdiQueryInformation(
656 PDEVICE_OBJECT DeviceObject
,
659 * FUNCTION: TDI_QUERY_INFORMATION handler
661 * DeviceObject = Pointer to device object structure
662 * Irp = Pointer to an I/O request packet
664 * Status of operation
667 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
668 PTRANSPORT_CONTEXT TranContext
;
669 PIO_STACK_LOCATION IrpSp
;
671 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
673 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
674 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
676 TranContext
= IrpSp
->FileObject
->FsContext
;
678 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
679 return STATUS_INVALID_PARAMETER
;
682 switch (Parameters
->QueryType
)
684 case TDI_QUERY_ADDRESS_INFO
:
686 PTDI_ADDRESS_INFO AddressInfo
;
687 PADDRESS_FILE AddrFile
;
688 PTA_IP_ADDRESS Address
;
689 PCONNECTION_ENDPOINT Endpoint
= NULL
;
692 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
693 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
694 sizeof(TDI_ADDRESS_IP
))) {
695 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
696 return STATUS_BUFFER_TOO_SMALL
;
699 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
700 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
702 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
703 case TDI_TRANSPORT_ADDRESS_FILE
:
704 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
706 Address
->TAAddressCount
= 1;
707 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
708 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
709 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
710 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->Address
.Address
.IPv4Address
;
712 &Address
->Address
[0].Address
[0].sin_zero
,
713 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
714 return STATUS_SUCCESS
;
716 case TDI_CONNECTION_FILE
:
718 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
720 Address
->TAAddressCount
= 1;
721 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
722 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
723 Address
->Address
[0].Address
[0].sin_port
= Endpoint
->AddressFile
->Port
;
724 Address
->Address
[0].Address
[0].in_addr
= Endpoint
->AddressFile
->Address
.Address
.IPv4Address
;
726 &Address
->Address
[0].Address
[0].sin_zero
,
727 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
728 return STATUS_SUCCESS
;
731 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
732 return STATUS_INVALID_PARAMETER
;
736 case TDI_QUERY_CONNECTION_INFO
:
738 PTDI_CONNECTION_INFO ConnectionInfo
;
739 //PCONNECTION_ENDPOINT Endpoint;
741 if (MmGetMdlByteCount(Irp
->MdlAddress
) < sizeof(*ConnectionInfo
)) {
742 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
743 return STATUS_BUFFER_TOO_SMALL
;
746 ConnectionInfo
= (PTDI_CONNECTION_INFO
)
747 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
749 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
750 case TDI_CONNECTION_FILE
:
751 //Endpoint = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
752 RtlZeroMemory(ConnectionInfo
, sizeof(*ConnectionInfo
));
753 return STATUS_SUCCESS
;
756 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
757 return STATUS_INVALID_PARAMETER
;
761 case TDI_QUERY_MAX_DATAGRAM_INFO
:
763 PTDI_MAX_DATAGRAM_INFO MaxDatagramInfo
;
765 if (MmGetMdlByteCount(Irp
->MdlAddress
) < sizeof(*MaxDatagramInfo
)) {
766 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
767 return STATUS_BUFFER_TOO_SMALL
;
770 MaxDatagramInfo
= (PTDI_MAX_DATAGRAM_INFO
)
771 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
773 MaxDatagramInfo
->MaxDatagramSize
= 0xFFFF;
775 return STATUS_SUCCESS
;
779 return STATUS_NOT_IMPLEMENTED
;
783 NTSTATUS
DispTdiReceive(
786 * FUNCTION: TDI_RECEIVE handler
788 * Irp = Pointer to an I/O request packet
790 * Status of operation
793 PIO_STACK_LOCATION IrpSp
;
794 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
795 PTRANSPORT_CONTEXT TranContext
;
797 ULONG BytesReceived
= 0;
799 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
801 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
802 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
804 TranContext
= IrpSp
->FileObject
->FsContext
;
805 if (TranContext
== NULL
)
807 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
808 Status
= STATUS_INVALID_PARAMETER
;
812 if (TranContext
->Handle
.ConnectionContext
== NULL
)
814 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
815 Status
= STATUS_INVALID_PARAMETER
;
819 /* Initialize a receive request */
820 Status
= DispPrepareIrpForCancel
821 (TranContext
->Handle
.ConnectionContext
,
823 (PDRIVER_CANCEL
)DispCancelRequest
);
825 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
826 if (NT_SUCCESS(Status
))
828 Status
= TCPReceiveData(
829 TranContext
->Handle
.ConnectionContext
,
830 (PNDIS_BUFFER
)Irp
->MdlAddress
,
831 ReceiveInfo
->ReceiveLength
,
833 ReceiveInfo
->ReceiveFlags
,
834 DispDataRequestComplete
,
839 if (Status
!= STATUS_PENDING
) {
840 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
842 IoMarkIrpPending(Irp
);
844 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
850 NTSTATUS
DispTdiReceiveDatagram(
853 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
855 * Irp = Pointer to an I/O request packet
857 * Status of operation
860 PIO_STACK_LOCATION IrpSp
;
861 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
862 PTRANSPORT_CONTEXT TranContext
;
865 ULONG BytesReceived
= 0;
867 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
869 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
870 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
872 TranContext
= IrpSp
->FileObject
->FsContext
;
873 if (TranContext
== NULL
)
875 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
876 Status
= STATUS_INVALID_PARAMETER
;
880 /* Initialize a receive request */
881 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
882 Request
.RequestNotifyObject
= DispDataRequestComplete
;
883 Request
.RequestContext
= Irp
;
885 Status
= DispPrepareIrpForCancel(
886 IrpSp
->FileObject
->FsContext
,
888 (PDRIVER_CANCEL
)DispCancelRequest
);
890 if (NT_SUCCESS(Status
))
895 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
899 Status
= DGReceiveDatagram(
900 Request
.Handle
.AddressHandle
,
901 DgramInfo
->ReceiveDatagramInformation
,
903 DgramInfo
->ReceiveLength
,
904 DgramInfo
->ReceiveFlags
,
905 DgramInfo
->ReturnDatagramInformation
,
907 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
913 if (Status
!= STATUS_PENDING
) {
914 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
916 IoMarkIrpPending(Irp
);
918 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
924 NTSTATUS
DispTdiSend(
927 * FUNCTION: TDI_SEND handler
929 * Irp = Pointer to an I/O request packet
931 * Status of operation
934 PIO_STACK_LOCATION IrpSp
;
935 PTDI_REQUEST_KERNEL_SEND SendInfo
;
936 PTRANSPORT_CONTEXT TranContext
;
940 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
942 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
943 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
945 TranContext
= IrpSp
->FileObject
->FsContext
;
946 if (TranContext
== NULL
)
948 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
949 Status
= STATUS_INVALID_PARAMETER
;
953 if (TranContext
->Handle
.ConnectionContext
== NULL
)
955 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
956 Status
= STATUS_INVALID_PARAMETER
;
960 Status
= DispPrepareIrpForCancel(
961 IrpSp
->FileObject
->FsContext
,
963 (PDRIVER_CANCEL
)DispCancelRequest
);
965 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
966 if (NT_SUCCESS(Status
))
971 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
973 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
974 Status
= TCPSendData(
975 TranContext
->Handle
.ConnectionContext
,
977 SendInfo
->SendLength
,
980 DispDataRequestComplete
,
985 if (Status
!= STATUS_PENDING
) {
986 DispDataRequestComplete(Irp
, Status
, BytesSent
);
988 IoMarkIrpPending(Irp
);
990 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
996 NTSTATUS
DispTdiSendDatagram(
999 * FUNCTION: TDI_SEND_DATAGRAM handler
1001 * Irp = Pointer to an I/O request packet
1003 * Status of operation
1006 PIO_STACK_LOCATION IrpSp
;
1007 TDI_REQUEST Request
;
1008 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
1009 PTRANSPORT_CONTEXT TranContext
;
1012 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1014 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1015 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
1017 TranContext
= IrpSp
->FileObject
->FsContext
;
1018 if (TranContext
== NULL
)
1020 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
1021 Status
= STATUS_INVALID_PARAMETER
;
1025 /* Initialize a send request */
1026 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1027 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1028 Request
.RequestContext
= Irp
;
1030 Status
= DispPrepareIrpForCancel(
1031 IrpSp
->FileObject
->FsContext
,
1033 (PDRIVER_CANCEL
)DispCancelRequest
);
1035 if (NT_SUCCESS(Status
)) {
1039 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
1041 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
1045 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
1046 must be of type PTDI_ADDRESS_IP */
1047 TI_DbgPrint(MID_TRACE
,
1048 ("About to call send routine %x\n",
1049 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
1051 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
!= NULL
) )
1054 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
1055 Request
.Handle
.AddressHandle
,
1056 DgramInfo
->SendDatagramInformation
,
1060 Irp
->IoStatus
.Information
= DataUsed
;
1063 Status
= STATUS_UNSUCCESSFUL
;
1069 if (Status
!= STATUS_PENDING
) {
1070 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
1072 IoMarkIrpPending(Irp
);
1074 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
1080 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
1082 * FUNCTION: TDI_SET_EVENT_HANDER handler
1084 * Irp = Pointer to a I/O request packet
1086 * Status of operation
1089 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1090 PTRANSPORT_CONTEXT TranContext
;
1091 PIO_STACK_LOCATION IrpSp
;
1092 PADDRESS_FILE AddrFile
;
1096 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1098 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1100 /* Get associated address file object. Quit if none exists */
1102 TranContext
= IrpSp
->FileObject
->FsContext
;
1104 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1105 return STATUS_INVALID_PARAMETER
;
1108 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1110 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1111 return STATUS_INVALID_PARAMETER
;
1114 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1115 Status
= STATUS_SUCCESS
;
1117 LockObject(AddrFile
, &OldIrql
);
1119 /* Set the event handler. if an event handler is associated with
1120 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1121 If an event handler is not used it's flag is FALSE */
1122 switch (Parameters
->EventType
) {
1123 case TDI_EVENT_CONNECT
:
1124 if (!Parameters
->EventHandler
) {
1125 AddrFile
->ConnectHandlerContext
= NULL
;
1126 AddrFile
->RegisteredConnectHandler
= FALSE
;
1128 AddrFile
->ConnectHandler
=
1129 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1130 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1131 AddrFile
->RegisteredConnectHandler
= TRUE
;
1135 case TDI_EVENT_DISCONNECT
:
1136 if (!Parameters
->EventHandler
) {
1137 AddrFile
->DisconnectHandlerContext
= NULL
;
1138 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1140 AddrFile
->DisconnectHandler
=
1141 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1142 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1143 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1147 case TDI_EVENT_ERROR
:
1148 if (Parameters
->EventHandler
== NULL
) {
1149 AddrFile
->ErrorHandlerContext
= NULL
;
1150 AddrFile
->RegisteredErrorHandler
= FALSE
;
1152 AddrFile
->ErrorHandler
=
1153 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1154 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1155 AddrFile
->RegisteredErrorHandler
= TRUE
;
1159 case TDI_EVENT_RECEIVE
:
1160 if (Parameters
->EventHandler
== NULL
) {
1161 AddrFile
->ReceiveHandlerContext
= NULL
;
1162 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1164 AddrFile
->ReceiveHandler
=
1165 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1166 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1167 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1171 case TDI_EVENT_RECEIVE_DATAGRAM
:
1172 if (Parameters
->EventHandler
== NULL
) {
1173 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1174 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1176 AddrFile
->ReceiveDatagramHandler
=
1177 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1178 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1179 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1183 case TDI_EVENT_RECEIVE_EXPEDITED
:
1184 if (Parameters
->EventHandler
== NULL
) {
1185 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1186 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1188 AddrFile
->ExpeditedReceiveHandler
=
1189 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1190 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1191 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1195 case TDI_EVENT_CHAINED_RECEIVE
:
1196 if (Parameters
->EventHandler
== NULL
) {
1197 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1198 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1200 AddrFile
->ChainedReceiveHandler
=
1201 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1202 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1203 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1207 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1208 if (Parameters
->EventHandler
== NULL
) {
1209 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1210 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1212 AddrFile
->ChainedReceiveDatagramHandler
=
1213 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1214 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1215 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1219 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1220 if (Parameters
->EventHandler
== NULL
) {
1221 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1222 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1224 AddrFile
->ChainedReceiveExpeditedHandler
=
1225 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1226 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1227 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1232 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1233 Parameters
->EventType
));
1235 Status
= STATUS_INVALID_PARAMETER
;
1238 UnlockObject(AddrFile
, OldIrql
);
1244 NTSTATUS
DispTdiSetInformation(
1247 * FUNCTION: TDI_SET_INFORMATION handler
1249 * Irp = Pointer to an I/O request packet
1251 * Status of operation
1254 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1256 return STATUS_NOT_IMPLEMENTED
;
1260 VOID
DispTdiQueryInformationExComplete(
1265 * FUNCTION: Completes a TDI QueryInformationEx request
1267 * Context = Pointer to the IRP for the request
1268 * Status = TDI status of the request
1269 * ByteCount = Number of bytes returned in output buffer
1272 PTI_QUERY_CONTEXT QueryContext
;
1274 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1275 if (NT_SUCCESS(Status
)) {
1276 CopyBufferToBufferChain(
1277 QueryContext
->InputMdl
,
1278 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1279 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1283 MmUnlockPages(QueryContext
->InputMdl
);
1284 IoFreeMdl(QueryContext
->InputMdl
);
1285 if( QueryContext
->OutputMdl
) {
1286 MmUnlockPages(QueryContext
->OutputMdl
);
1287 IoFreeMdl(QueryContext
->OutputMdl
);
1290 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1291 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1293 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1297 NTSTATUS
DispTdiQueryInformationEx(
1299 PIO_STACK_LOCATION IrpSp
)
1301 * FUNCTION: TDI QueryInformationEx handler
1303 * Irp = Pointer to I/O request packet
1304 * IrpSp = Pointer to current stack location of Irp
1306 * Status of operation
1309 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1310 PTRANSPORT_CONTEXT TranContext
;
1311 PTI_QUERY_CONTEXT QueryContext
;
1313 TDI_REQUEST Request
;
1315 UINT InputBufferLength
;
1316 UINT OutputBufferLength
;
1317 BOOLEAN InputMdlLocked
= FALSE
;
1318 BOOLEAN OutputMdlLocked
= FALSE
;
1319 PMDL InputMdl
= NULL
;
1320 PMDL OutputMdl
= NULL
;
1321 NTSTATUS Status
= STATUS_SUCCESS
;
1323 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1325 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1327 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
1328 case TDI_TRANSPORT_ADDRESS_FILE
:
1329 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1332 case TDI_CONNECTION_FILE
:
1333 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1336 case TDI_CONTROL_CHANNEL_FILE
:
1337 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1341 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1342 return STATUS_INVALID_PARAMETER
;
1345 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1346 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1348 /* Validate parameters */
1349 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1350 (OutputBufferLength
!= 0)) {
1352 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1353 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1354 OutputBuffer
= Irp
->UserBuffer
;
1356 QueryContext
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
), QUERY_CONTEXT_TAG
);
1359 InputMdl
= IoAllocateMdl(InputBuffer
,
1360 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1363 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1364 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1366 if (InputMdl
&& OutputMdl
) {
1368 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1371 InputMdlLocked
= TRUE
;
1373 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1376 OutputMdlLocked
= TRUE
;
1378 RtlCopyMemory(&QueryContext
->QueryInfo
,
1379 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1381 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1382 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1383 Status
= _SEH2_GetExceptionCode();
1386 if (NT_SUCCESS(Status
)) {
1387 Size
= MmGetMdlByteCount(OutputMdl
);
1389 QueryContext
->Irp
= Irp
;
1390 QueryContext
->InputMdl
= InputMdl
;
1391 QueryContext
->OutputMdl
= OutputMdl
;
1393 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1394 Request
.RequestContext
= QueryContext
;
1395 Status
= InfoTdiQueryInformationEx(&Request
,
1396 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1397 &Size
, &QueryContext
->QueryInfo
.Context
);
1398 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1400 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1405 /* An error occurred if we get here */
1409 MmUnlockPages(InputMdl
);
1410 IoFreeMdl(InputMdl
);
1414 if (OutputMdlLocked
)
1415 MmUnlockPages(OutputMdl
);
1416 IoFreeMdl(OutputMdl
);
1419 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1421 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1422 } else if( InputBufferLength
==
1423 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1424 /* Handle the case where the user is probing the buffer for length */
1425 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1426 InputBufferLength
, OutputBufferLength
));
1427 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1428 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1432 QueryContext
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
), QUERY_CONTEXT_TAG
);
1433 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1436 InputMdl
= IoAllocateMdl(InputBuffer
,
1437 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1440 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1443 InputMdlLocked
= TRUE
;
1444 Status
= STATUS_SUCCESS
;
1445 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1446 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1447 Status
= _SEH2_GetExceptionCode();
1450 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1451 if( InputMdl
) IoFreeMdl( InputMdl
);
1452 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1456 RtlCopyMemory(&QueryContext
->QueryInfo
,
1457 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1459 QueryContext
->Irp
= Irp
;
1460 QueryContext
->InputMdl
= InputMdl
;
1461 QueryContext
->OutputMdl
= NULL
;
1463 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1464 Request
.RequestContext
= QueryContext
;
1465 Status
= InfoTdiQueryInformationEx(&Request
,
1466 &QueryContext
->QueryInfo
.ID
,
1469 &QueryContext
->QueryInfo
.Context
);
1470 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1471 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1472 } else Status
= STATUS_INVALID_PARAMETER
;
1474 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1480 NTSTATUS
DispTdiSetInformationEx(
1482 PIO_STACK_LOCATION IrpSp
)
1484 * FUNCTION: TDI SetInformationEx handler
1486 * Irp = Pointer to I/O request packet
1487 * IrpSp = Pointer to current stack location of Irp
1489 * Status of operation
1492 PTRANSPORT_CONTEXT TranContext
;
1493 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1494 TDI_REQUEST Request
;
1497 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1499 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1500 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1502 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
1503 case TDI_TRANSPORT_ADDRESS_FILE
:
1504 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1507 case TDI_CONNECTION_FILE
:
1508 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1511 case TDI_CONTROL_CHANNEL_FILE
:
1512 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1516 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1517 Irp
->IoStatus
.Information
= 0;
1519 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1521 return Irp
->IoStatus
.Status
;
1524 Request
.RequestNotifyObject
= NULL
;
1525 Request
.RequestContext
= NULL
;
1527 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1528 &Info
->Buffer
, Info
->BufferSize
);
1533 /* TODO: Support multiple addresses per interface.
1534 * For now just set the nte context to the interface index.
1536 * Later on, create an NTE context and NTE instance
1539 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1540 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1541 PIP_SET_ADDRESS IpAddrChange
=
1542 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1545 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1546 IpAddrChange
->NteIndex
));
1548 ForEachInterface(IF
) {
1549 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1551 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1552 Status
= STATUS_DUPLICATE_OBJECTID
;
1555 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1556 IPRemoveInterfaceRoute( IF
);
1558 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1559 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1561 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1562 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1564 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1565 IF
->Broadcast
.Address
.IPv4Address
=
1566 IF
->Unicast
.Address
.IPv4Address
|
1567 ~IF
->Netmask
.Address
.IPv4Address
;
1569 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1570 IF
->Unicast
.Address
.IPv4Address
));
1571 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1572 IF
->Netmask
.Address
.IPv4Address
));
1574 IPAddInterfaceRoute( IF
);
1576 IpAddrChange
->Address
= IF
->Index
;
1577 Status
= STATUS_SUCCESS
;
1578 Irp
->IoStatus
.Information
= IF
->Index
;
1583 Irp
->IoStatus
.Status
= Status
;
1587 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1588 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1589 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1592 ForEachInterface(IF
) {
1593 if( IF
->Index
== *NteIndex
) {
1594 IPRemoveInterfaceRoute( IF
);
1595 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1596 IF
->Unicast
.Address
.IPv4Address
= 0;
1598 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1599 IF
->Netmask
.Address
.IPv4Address
= 0;
1601 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1602 IF
->Broadcast
.Address
.IPv4Address
= 0;
1604 Status
= STATUS_SUCCESS
;
1608 Irp
->IoStatus
.Status
= Status
;