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
13 #include <pseh/pseh.h>
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 (void)IoSetCancelRoutine(Irp
, CancelRoutine
);
37 IoReleaseCancelSpinLock(OldIrql
);
39 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
41 return STATUS_SUCCESS
;
44 /* IRP has already been cancelled */
46 IoReleaseCancelSpinLock(OldIrql
);
48 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
49 Irp
->IoStatus
.Information
= 0;
51 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
53 return Irp
->IoStatus
.Status
;
56 VOID
DispDataRequestComplete(
61 * FUNCTION: Completes a send/receive IRP
63 * Context = Pointer to context information (IRP)
64 * Status = Status of the request
65 * Count = Number of bytes sent or received
69 PIO_STACK_LOCATION IrpSp
;
70 PTRANSPORT_CONTEXT TranContext
;
73 TI_DbgPrint(DEBUG_IRP
, ("Called for irp %x (%x, %d).\n",
74 Context
, Status
, Count
));
77 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
78 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
80 IoAcquireCancelSpinLock(&OldIrql
);
82 (void)IoSetCancelRoutine(Irp
, NULL
);
84 if (Irp
->Cancel
|| TranContext
->CancelIrps
) {
85 /* The IRP has been cancelled */
87 TI_DbgPrint(DEBUG_IRP
, ("IRP is cancelled.\n"));
89 Status
= STATUS_CANCELLED
;
93 IoReleaseCancelSpinLock(OldIrql
);
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
, Irp
->IoStatus
.Status
);
106 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
109 typedef struct _DISCONNECT_TYPE
{
113 PFILE_OBJECT FileObject
;
114 } DISCONNECT_TYPE
, *PDISCONNECT_TYPE
;
116 VOID
DispDoDisconnect( PVOID Data
) {
117 PDISCONNECT_TYPE DisType
= (PDISCONNECT_TYPE
)Data
;
119 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect\n"));
125 DispDataRequestComplete
,
127 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect done\n"));
129 DispDataRequestComplete(DisType
->Irp
, STATUS_CANCELLED
, 0);
132 VOID NTAPI
DispCancelRequest(
133 PDEVICE_OBJECT Device
,
136 * FUNCTION: Cancels an IRP
138 * Device = Pointer to device object
139 * Irp = Pointer to an I/O request packet
142 PIO_STACK_LOCATION IrpSp
;
143 PTRANSPORT_CONTEXT TranContext
;
144 PFILE_OBJECT FileObject
;
146 DISCONNECT_TYPE DisType
;
148 /*NTSTATUS Status = STATUS_SUCCESS;*/
150 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
152 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
153 FileObject
= IrpSp
->FileObject
;
154 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
155 MinorFunction
= IrpSp
->MinorFunction
;
157 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
159 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
160 Irp
->IoStatus
.Information
= 0;
164 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
167 /* Try canceling the request */
168 switch(MinorFunction
) {
171 DisType
.Type
= TDI_DISCONNECT_RELEASE
|
172 ((MinorFunction
== TDI_RECEIVE
) ? TDI_DISCONNECT_ABORT
: 0);
173 DisType
.Context
= TranContext
->Handle
.ConnectionContext
;
175 DisType
.FileObject
= FileObject
;
177 TCPRemoveIRP( TranContext
->Handle
.ConnectionContext
, Irp
);
179 if( !ChewCreate( &WorkItem
, sizeof(DISCONNECT_TYPE
),
180 DispDoDisconnect
, &DisType
) )
183 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
186 case TDI_SEND_DATAGRAM
:
187 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
188 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
193 case TDI_RECEIVE_DATAGRAM
:
194 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
195 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
199 DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
203 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
207 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
208 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
210 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
214 VOID NTAPI
DispCancelListenRequest(
215 PDEVICE_OBJECT Device
,
218 * FUNCTION: Cancels a listen IRP
220 * Device = Pointer to device object
221 * Irp = Pointer to an I/O request packet
224 PIO_STACK_LOCATION IrpSp
;
225 PTRANSPORT_CONTEXT TranContext
;
226 PFILE_OBJECT FileObject
;
227 PCONNECTION_ENDPOINT Connection
;
228 /*NTSTATUS Status = STATUS_SUCCESS;*/
230 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
232 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
233 FileObject
= IrpSp
->FileObject
;
234 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
235 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
237 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
241 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
244 /* Try canceling the request */
245 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
246 TCPAbortListenForSocket(
247 Connection
->AddressFile
->Listener
,
250 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
252 DispDataRequestComplete(Irp
, STATUS_CANCELLED
, 0);
254 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
258 NTSTATUS
DispTdiAccept(
261 * FUNCTION: TDI_ACCEPT handler
263 * Irp = Pointer to an I/O request packet
265 * Status of operation
268 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
270 return STATUS_NOT_IMPLEMENTED
;
274 NTSTATUS
DispTdiAssociateAddress(
277 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
279 * Irp = Pointer to an I/O request packet
281 * Status of operation
284 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
285 PTRANSPORT_CONTEXT TranContext
;
286 PIO_STACK_LOCATION IrpSp
;
287 PCONNECTION_ENDPOINT Connection
;
288 PFILE_OBJECT FileObject
;
289 PADDRESS_FILE AddrFile
= NULL
;
292 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
294 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
296 /* Get associated connection endpoint file object. Quit if none exists */
298 TranContext
= IrpSp
->FileObject
->FsContext
;
300 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
301 return STATUS_INVALID_PARAMETER
;
304 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
306 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
307 return STATUS_INVALID_PARAMETER
;
310 if (Connection
->AddressFile
) {
311 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
312 return STATUS_INVALID_PARAMETER
;
315 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
317 Status
= ObReferenceObjectByHandle(
318 Parameters
->AddressHandle
,
324 if (!NT_SUCCESS(Status
)) {
325 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
326 Parameters
->AddressHandle
, Status
));
327 return STATUS_INVALID_PARAMETER
;
330 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
331 ObDereferenceObject(FileObject
);
332 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
333 FileObject
->FsContext2
));
334 return STATUS_INVALID_PARAMETER
;
337 /* Get associated address file object. Quit if none exists */
339 TranContext
= FileObject
->FsContext
;
341 ObDereferenceObject(FileObject
);
342 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
343 return STATUS_INVALID_PARAMETER
;
346 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
348 ObDereferenceObject(FileObject
);
349 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
350 return STATUS_INVALID_PARAMETER
;
353 Connection
->AddressFile
= AddrFile
;
355 /* Add connection endpoint to the address file */
356 AddrFile
->Connection
= Connection
;
358 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
359 ObDereferenceObject(FileObject
);
365 NTSTATUS
DispTdiConnect(
368 * FUNCTION: TDI_CONNECT handler
370 * Irp = Pointer to an I/O request packet
372 * Status of operation
375 PCONNECTION_ENDPOINT Connection
;
376 PTDI_REQUEST_KERNEL Parameters
;
377 PTRANSPORT_CONTEXT TranContext
;
378 PIO_STACK_LOCATION IrpSp
;
381 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
383 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
385 /* Get associated connection endpoint file object. Quit if none exists */
387 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
389 TranContext
= IrpSp
->FileObject
->FsContext
;
391 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
392 Status
= STATUS_INVALID_CONNECTION
;
396 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
398 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
399 Status
= STATUS_INVALID_CONNECTION
;
403 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
406 TranContext
->Handle
.ConnectionContext
,
407 Parameters
->RequestConnectionInformation
,
408 Parameters
->ReturnConnectionInformation
,
409 DispDataRequestComplete
,
413 if (Status
!= STATUS_PENDING
) {
414 DispDataRequestComplete(Irp
, Status
, 0);
416 IoMarkIrpPending(Irp
);
418 TcpipRecursiveMutexLeave( &TCPLock
);
420 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
426 NTSTATUS
DispTdiDisassociateAddress(
429 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
431 * Irp = Pointer to an I/O request packet
433 * Status of operation
436 PCONNECTION_ENDPOINT Connection
;
437 PTRANSPORT_CONTEXT TranContext
;
438 PIO_STACK_LOCATION IrpSp
;
440 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
442 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
444 /* Get associated connection endpoint file object. Quit if none exists */
446 TranContext
= IrpSp
->FileObject
->FsContext
;
448 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
449 return STATUS_INVALID_PARAMETER
;
452 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
454 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
455 return STATUS_INVALID_PARAMETER
;
458 if (!Connection
->AddressFile
) {
459 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
460 return STATUS_INVALID_PARAMETER
;
463 return STATUS_SUCCESS
;
467 NTSTATUS
DispTdiDisconnect(
470 * FUNCTION: TDI_DISCONNECT handler
472 * Irp = Pointer to an I/O request packet
474 * Status of operation
478 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
479 PCONNECTION_ENDPOINT Connection
;
480 PTRANSPORT_CONTEXT TranContext
;
481 PIO_STACK_LOCATION IrpSp
;
483 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
485 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
486 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
488 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
490 /* Get associated connection endpoint file object. Quit if none exists */
492 TranContext
= IrpSp
->FileObject
->FsContext
;
494 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
495 Status
= STATUS_INVALID_CONNECTION
;
499 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
501 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
502 Status
= STATUS_INVALID_CONNECTION
;
506 Status
= TCPDisconnect(
507 TranContext
->Handle
.ConnectionContext
,
508 DisReq
->RequestFlags
,
509 DisReq
->RequestConnectionInformation
,
510 DisReq
->ReturnConnectionInformation
,
511 DispDataRequestComplete
,
515 if (Status
!= STATUS_PENDING
) {
516 DispDataRequestComplete(Irp
, Status
, 0);
518 IoMarkIrpPending(Irp
);
520 TcpipRecursiveMutexLeave( &TCPLock
);
522 TI_DbgPrint(MAX_TRACE
, ("TCP Disconnect returned %08x\n", Status
));
528 NTSTATUS
DispTdiListen(
531 * FUNCTION: TDI_LISTEN handler
533 * Irp = Pointer to an I/O request packet
535 * Status of operation
538 PCONNECTION_ENDPOINT Connection
;
539 PTDI_REQUEST_KERNEL Parameters
;
540 PTRANSPORT_CONTEXT TranContext
;
541 PIO_STACK_LOCATION IrpSp
;
542 NTSTATUS Status
= STATUS_SUCCESS
;
544 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
546 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
548 /* Get associated connection endpoint file object. Quit if none exists */
550 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
552 TranContext
= IrpSp
->FileObject
->FsContext
;
553 if (TranContext
== NULL
)
555 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
556 Status
= STATUS_INVALID_CONNECTION
;
560 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
561 if (Connection
== NULL
)
563 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
564 Status
= STATUS_INVALID_CONNECTION
;
568 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
570 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile: %x\n",
571 Connection
->AddressFile
));
572 if( Connection
->AddressFile
) {
573 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile->Listener: %x\n",
574 Connection
->AddressFile
->Listener
));
577 /* Listening will require us to create a listening socket and store it in
578 * the address file. It will be signalled, and attempt to complete an irp
579 * when a new connection arrives. */
580 /* The important thing to note here is that the irp we'll complete belongs
581 * to the socket to be accepted onto, not the listener */
582 if( !Connection
->AddressFile
->Listener
) {
583 Connection
->AddressFile
->Listener
=
584 TCPAllocateConnectionEndpoint( NULL
);
586 if( !Connection
->AddressFile
->Listener
)
587 Status
= STATUS_NO_MEMORY
;
589 if( NT_SUCCESS(Status
) ) {
590 Connection
->AddressFile
->Listener
->AddressFile
=
591 Connection
->AddressFile
;
593 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
594 Connection
->AddressFile
->Family
,
596 Connection
->AddressFile
->Protocol
);
599 if( NT_SUCCESS(Status
) )
600 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
603 if( NT_SUCCESS(Status
) ) {
604 Status
= DispPrepareIrpForCancel
605 (TranContext
->Handle
.ConnectionContext
,
607 (PDRIVER_CANCEL
)DispCancelListenRequest
);
610 if( NT_SUCCESS(Status
) ) {
612 ( (PTDI_REQUEST
)Parameters
,
613 Connection
->AddressFile
->Listener
,
615 DispDataRequestComplete
,
620 if (Status
!= STATUS_PENDING
) {
621 DispDataRequestComplete(Irp
, Status
, 0);
623 IoMarkIrpPending(Irp
);
625 TcpipRecursiveMutexLeave( &TCPLock
);
627 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
633 NTSTATUS
DispTdiQueryInformation(
634 PDEVICE_OBJECT DeviceObject
,
637 * FUNCTION: TDI_QUERY_INFORMATION handler
639 * DeviceObject = Pointer to device object structure
640 * Irp = Pointer to an I/O request packet
642 * Status of operation
645 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
646 PTRANSPORT_CONTEXT TranContext
;
647 PIO_STACK_LOCATION IrpSp
;
649 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
651 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
652 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
654 TranContext
= IrpSp
->FileObject
->FsContext
;
656 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
657 return STATUS_INVALID_CONNECTION
;
660 switch (Parameters
->QueryType
)
662 case TDI_QUERY_ADDRESS_INFO
:
664 PTDI_ADDRESS_INFO AddressInfo
;
665 PADDRESS_FILE AddrFile
;
666 PTA_IP_ADDRESS Address
;
668 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
670 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
671 case TDI_TRANSPORT_ADDRESS_FILE
:
672 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
675 case TDI_CONNECTION_FILE
:
677 ((PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
)->
682 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
683 return STATUS_INVALID_PARAMETER
;
687 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
688 return STATUS_INVALID_PARAMETER
;
691 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
692 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
693 sizeof(TDI_ADDRESS_IP
))) {
694 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
695 return STATUS_BUFFER_OVERFLOW
;
698 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
699 Address
->TAAddressCount
= 1;
700 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
701 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
702 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
703 Address
->Address
[0].Address
[0].in_addr
=
704 AddrFile
->Address
.Address
.IPv4Address
;
706 &Address
->Address
[0].Address
[0].sin_zero
,
707 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
709 return STATUS_SUCCESS
;
712 case TDI_QUERY_CONNECTION_INFO
:
714 PTDI_CONNECTION_INFORMATION AddressInfo
;
715 PADDRESS_FILE AddrFile
;
716 PCONNECTION_ENDPOINT Endpoint
= NULL
;
718 AddressInfo
= (PTDI_CONNECTION_INFORMATION
)
719 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
721 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
722 case TDI_TRANSPORT_ADDRESS_FILE
:
723 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
726 case TDI_CONNECTION_FILE
:
728 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
732 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
733 return STATUS_INVALID_PARAMETER
;
737 TI_DbgPrint(MID_TRACE
, ("No connection object.\n"));
738 return STATUS_INVALID_PARAMETER
;
741 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
742 (FIELD_OFFSET(TDI_CONNECTION_INFORMATION
, RemoteAddress
) +
744 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small (ptr).\n"));
745 return STATUS_BUFFER_OVERFLOW
;
748 return TCPGetPeerAddress( Endpoint
, AddressInfo
->RemoteAddress
);
752 return STATUS_NOT_IMPLEMENTED
;
756 NTSTATUS
DispTdiReceive(
759 * FUNCTION: TDI_RECEIVE handler
761 * Irp = Pointer to an I/O request packet
763 * Status of operation
766 PIO_STACK_LOCATION IrpSp
;
767 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
768 PTRANSPORT_CONTEXT TranContext
;
772 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
774 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
775 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
777 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
779 TranContext
= IrpSp
->FileObject
->FsContext
;
780 if (TranContext
== NULL
)
782 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
783 Status
= STATUS_INVALID_CONNECTION
;
787 if (TranContext
->Handle
.ConnectionContext
== NULL
)
789 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
790 Status
= STATUS_INVALID_CONNECTION
;
794 /* Initialize a receive request */
795 Status
= DispPrepareIrpForCancel
796 (TranContext
->Handle
.ConnectionContext
,
798 (PDRIVER_CANCEL
)DispCancelRequest
);
800 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
801 if (NT_SUCCESS(Status
))
803 Status
= TCPReceiveData(
804 TranContext
->Handle
.ConnectionContext
,
805 (PNDIS_BUFFER
)Irp
->MdlAddress
,
806 ReceiveInfo
->ReceiveLength
,
808 ReceiveInfo
->ReceiveFlags
,
809 DispDataRequestComplete
,
814 if (Status
!= STATUS_PENDING
) {
815 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
817 IoMarkIrpPending(Irp
);
819 TcpipRecursiveMutexLeave( &TCPLock
);
821 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
827 NTSTATUS
DispTdiReceiveDatagram(
830 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
832 * Irp = Pointer to an I/O request packet
834 * Status of operation
837 PIO_STACK_LOCATION IrpSp
;
838 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
839 PTRANSPORT_CONTEXT TranContext
;
844 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
846 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
847 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
849 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
851 TranContext
= IrpSp
->FileObject
->FsContext
;
852 if (TranContext
== NULL
)
854 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
855 Status
= STATUS_INVALID_CONNECTION
;
859 /* Initialize a receive request */
860 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
861 Request
.RequestNotifyObject
= DispDataRequestComplete
;
862 Request
.RequestContext
= Irp
;
864 Status
= DispPrepareIrpForCancel(
865 IrpSp
->FileObject
->FsContext
,
867 (PDRIVER_CANCEL
)DispCancelRequest
);
869 if (NT_SUCCESS(Status
))
874 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
878 Status
= DGReceiveDatagram(
879 Request
.Handle
.AddressHandle
,
880 DgramInfo
->ReceiveDatagramInformation
,
882 DgramInfo
->ReceiveLength
,
883 DgramInfo
->ReceiveFlags
,
884 DgramInfo
->ReturnDatagramInformation
,
886 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
892 if (Status
!= STATUS_PENDING
) {
893 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
895 IoMarkIrpPending(Irp
);
897 TcpipRecursiveMutexLeave( &TCPLock
);
899 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
905 NTSTATUS
DispTdiSend(
908 * FUNCTION: TDI_SEND handler
910 * Irp = Pointer to an I/O request packet
912 * Status of operation
915 PIO_STACK_LOCATION IrpSp
;
916 PTDI_REQUEST_KERNEL_SEND SendInfo
;
917 PTRANSPORT_CONTEXT TranContext
;
921 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
923 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
924 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
926 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
928 TranContext
= IrpSp
->FileObject
->FsContext
;
929 if (TranContext
== NULL
)
931 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
932 Status
= STATUS_INVALID_CONNECTION
;
936 if (TranContext
->Handle
.ConnectionContext
== NULL
)
938 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
939 Status
= STATUS_INVALID_CONNECTION
;
943 Status
= DispPrepareIrpForCancel(
944 IrpSp
->FileObject
->FsContext
,
946 (PDRIVER_CANCEL
)DispCancelRequest
);
948 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
949 if (NT_SUCCESS(Status
))
954 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
956 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
957 Status
= TCPSendData(
958 TranContext
->Handle
.ConnectionContext
,
960 SendInfo
->SendLength
,
963 DispDataRequestComplete
,
968 if (Status
!= STATUS_PENDING
) {
969 DispDataRequestComplete(Irp
, Status
, BytesSent
);
971 IoMarkIrpPending(Irp
);
973 TcpipRecursiveMutexLeave( &TCPLock
);
975 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
981 NTSTATUS
DispTdiSendDatagram(
984 * FUNCTION: TDI_SEND_DATAGRAM handler
986 * Irp = Pointer to an I/O request packet
988 * Status of operation
991 PIO_STACK_LOCATION IrpSp
;
993 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
994 PTRANSPORT_CONTEXT TranContext
;
997 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
999 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1000 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
1002 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
1004 TranContext
= IrpSp
->FileObject
->FsContext
;
1005 if (TranContext
== NULL
)
1007 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
1008 Status
= STATUS_INVALID_CONNECTION
;
1012 /* Initialize a send request */
1013 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1014 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1015 Request
.RequestContext
= Irp
;
1017 Status
= DispPrepareIrpForCancel(
1018 IrpSp
->FileObject
->FsContext
,
1020 (PDRIVER_CANCEL
)DispCancelRequest
);
1022 if (NT_SUCCESS(Status
)) {
1026 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
1028 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
1032 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
1033 must be of type PTDI_ADDRESS_IP */
1034 TI_DbgPrint(MID_TRACE
,
1035 ("About to call send routine %x\n",
1036 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
1038 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
) )
1039 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
1040 Request
.Handle
.AddressHandle
,
1041 DgramInfo
->SendDatagramInformation
,
1044 &Irp
->IoStatus
.Information
);
1046 Status
= STATUS_UNSUCCESSFUL
;
1050 if (Status
!= STATUS_PENDING
) {
1051 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
1053 IoMarkIrpPending(Irp
);
1055 TcpipRecursiveMutexLeave( &TCPLock
);
1057 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
1063 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
1065 * FUNCTION: TDI_SET_EVENT_HANDER handler
1067 * Irp = Pointer to a I/O request packet
1069 * Status of operation
1072 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1073 PTRANSPORT_CONTEXT TranContext
;
1074 PIO_STACK_LOCATION IrpSp
;
1075 PADDRESS_FILE AddrFile
;
1079 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1081 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1083 /* Get associated address file object. Quit if none exists */
1085 TranContext
= IrpSp
->FileObject
->FsContext
;
1087 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1088 return STATUS_INVALID_PARAMETER
;
1091 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1093 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1094 return STATUS_INVALID_PARAMETER
;
1097 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1098 Status
= STATUS_SUCCESS
;
1100 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
1102 /* Set the event handler. if an event handler is associated with
1103 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1104 If an event handler is not used it's flag is FALSE */
1105 switch (Parameters
->EventType
) {
1106 case TDI_EVENT_CONNECT
:
1107 if (!Parameters
->EventHandler
) {
1108 AddrFile
->ConnectHandlerContext
= NULL
;
1109 AddrFile
->RegisteredConnectHandler
= FALSE
;
1111 AddrFile
->ConnectHandler
=
1112 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1113 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1114 AddrFile
->RegisteredConnectHandler
= TRUE
;
1118 case TDI_EVENT_DISCONNECT
:
1119 if (!Parameters
->EventHandler
) {
1120 AddrFile
->DisconnectHandlerContext
= NULL
;
1121 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1123 AddrFile
->DisconnectHandler
=
1124 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1125 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1126 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1130 case TDI_EVENT_ERROR
:
1131 if (Parameters
->EventHandler
== NULL
) {
1132 AddrFile
->ErrorHandlerContext
= NULL
;
1133 AddrFile
->RegisteredErrorHandler
= FALSE
;
1135 AddrFile
->ErrorHandler
=
1136 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1137 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1138 AddrFile
->RegisteredErrorHandler
= TRUE
;
1142 case TDI_EVENT_RECEIVE
:
1143 if (Parameters
->EventHandler
== NULL
) {
1144 AddrFile
->ReceiveHandlerContext
= NULL
;
1145 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1147 AddrFile
->ReceiveHandler
=
1148 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1149 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1150 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1154 case TDI_EVENT_RECEIVE_DATAGRAM
:
1155 if (Parameters
->EventHandler
== NULL
) {
1156 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1157 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1159 AddrFile
->ReceiveDatagramHandler
=
1160 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1161 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1162 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1166 case TDI_EVENT_RECEIVE_EXPEDITED
:
1167 if (Parameters
->EventHandler
== NULL
) {
1168 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1169 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1171 AddrFile
->ExpeditedReceiveHandler
=
1172 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1173 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1174 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1178 case TDI_EVENT_CHAINED_RECEIVE
:
1179 if (Parameters
->EventHandler
== NULL
) {
1180 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1181 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1183 AddrFile
->ChainedReceiveHandler
=
1184 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1185 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1186 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1190 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1191 if (Parameters
->EventHandler
== NULL
) {
1192 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1193 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1195 AddrFile
->ChainedReceiveDatagramHandler
=
1196 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1197 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1198 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1202 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1203 if (Parameters
->EventHandler
== NULL
) {
1204 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1205 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1207 AddrFile
->ChainedReceiveExpeditedHandler
=
1208 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1209 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1210 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1215 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1216 Parameters
->EventType
));
1218 Status
= STATUS_INVALID_PARAMETER
;
1221 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1227 NTSTATUS
DispTdiSetInformation(
1230 * FUNCTION: TDI_SET_INFORMATION handler
1232 * Irp = Pointer to an I/O request packet
1234 * Status of operation
1237 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1239 return STATUS_NOT_IMPLEMENTED
;
1243 VOID
DispTdiQueryInformationExComplete(
1248 * FUNCTION: Completes a TDI QueryInformationEx request
1250 * Context = Pointer to the IRP for the request
1251 * Status = TDI status of the request
1252 * ByteCount = Number of bytes returned in output buffer
1255 PTI_QUERY_CONTEXT QueryContext
;
1258 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1259 if (NT_SUCCESS(Status
)) {
1260 Count
= CopyBufferToBufferChain(
1261 QueryContext
->InputMdl
,
1262 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1263 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1267 MmUnlockPages(QueryContext
->InputMdl
);
1268 IoFreeMdl(QueryContext
->InputMdl
);
1269 if( QueryContext
->OutputMdl
) {
1270 MmUnlockPages(QueryContext
->OutputMdl
);
1271 IoFreeMdl(QueryContext
->OutputMdl
);
1274 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1275 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1277 ExFreePool(QueryContext
);
1281 NTSTATUS
DispTdiQueryInformationEx(
1283 PIO_STACK_LOCATION IrpSp
)
1285 * FUNCTION: TDI QueryInformationEx handler
1287 * Irp = Pointer to I/O request packet
1288 * IrpSp = Pointer to current stack location of Irp
1290 * Status of operation
1293 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1294 PTRANSPORT_CONTEXT TranContext
;
1295 PTI_QUERY_CONTEXT QueryContext
;
1297 TDI_REQUEST Request
;
1299 UINT InputBufferLength
;
1300 UINT OutputBufferLength
;
1301 BOOLEAN InputMdlLocked
= FALSE
;
1302 BOOLEAN OutputMdlLocked
= FALSE
;
1303 PMDL InputMdl
= NULL
;
1304 PMDL OutputMdl
= NULL
;
1305 NTSTATUS Status
= STATUS_SUCCESS
;
1307 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1309 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1311 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1312 case TDI_TRANSPORT_ADDRESS_FILE
:
1313 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1316 case TDI_CONNECTION_FILE
:
1317 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1320 case TDI_CONTROL_CHANNEL_FILE
:
1321 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1325 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1326 return STATUS_INVALID_PARAMETER
;
1329 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1330 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1332 /* Validate parameters */
1333 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1334 (OutputBufferLength
!= 0)) {
1336 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1337 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1338 OutputBuffer
= Irp
->UserBuffer
;
1340 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1343 InputMdl
= IoAllocateMdl(InputBuffer
,
1344 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1347 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1348 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1350 if (InputMdl
&& OutputMdl
) {
1352 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1355 InputMdlLocked
= TRUE
;
1357 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1360 OutputMdlLocked
= TRUE
;
1362 RtlCopyMemory(&QueryContext
->QueryInfo
,
1363 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1365 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1367 Status
= _SEH_GetExceptionCode();
1370 if (NT_SUCCESS(Status
)) {
1371 Size
= MmGetMdlByteCount(OutputMdl
);
1373 QueryContext
->Irp
= Irp
;
1374 QueryContext
->InputMdl
= InputMdl
;
1375 QueryContext
->OutputMdl
= OutputMdl
;
1377 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1378 Request
.RequestContext
= QueryContext
;
1379 Status
= InfoTdiQueryInformationEx(&Request
,
1380 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1381 &Size
, &QueryContext
->QueryInfo
.Context
);
1382 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1384 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1389 /* An error occurred if we get here */
1393 MmUnlockPages(InputMdl
);
1394 IoFreeMdl(InputMdl
);
1398 if (OutputMdlLocked
)
1399 MmUnlockPages(OutputMdl
);
1400 IoFreeMdl(OutputMdl
);
1403 ExFreePool(QueryContext
);
1405 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1406 } else if( InputBufferLength
==
1407 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1408 /* Handle the case where the user is probing the buffer for length */
1409 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1410 InputBufferLength
, OutputBufferLength
));
1411 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1412 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1416 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1417 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1420 InputMdl
= IoAllocateMdl(InputBuffer
,
1421 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1424 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1427 InputMdlLocked
= TRUE
;
1428 Status
= STATUS_SUCCESS
;
1430 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1431 Status
= _SEH_GetExceptionCode();
1434 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1435 if( InputMdl
) IoFreeMdl( InputMdl
);
1436 ExFreePool(QueryContext
);
1440 RtlCopyMemory(&QueryContext
->QueryInfo
,
1441 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1443 QueryContext
->Irp
= Irp
;
1444 QueryContext
->InputMdl
= InputMdl
;
1445 QueryContext
->OutputMdl
= NULL
;
1447 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1448 Request
.RequestContext
= QueryContext
;
1449 Status
= InfoTdiQueryInformationEx(&Request
,
1450 &QueryContext
->QueryInfo
.ID
,
1453 &QueryContext
->QueryInfo
.Context
);
1454 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1455 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1456 } else Status
= STATUS_INVALID_PARAMETER
;
1458 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1464 NTSTATUS
DispTdiSetInformationEx(
1466 PIO_STACK_LOCATION IrpSp
)
1468 * FUNCTION: TDI SetInformationEx handler
1470 * Irp = Pointer to I/O request packet
1471 * IrpSp = Pointer to current stack location of Irp
1473 * Status of operation
1476 PTRANSPORT_CONTEXT TranContext
;
1477 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1478 TDI_REQUEST Request
;
1481 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1483 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1484 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1486 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1487 case TDI_TRANSPORT_ADDRESS_FILE
:
1488 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1491 case TDI_CONNECTION_FILE
:
1492 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1495 case TDI_CONTROL_CHANNEL_FILE
:
1496 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1500 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1501 Irp
->IoStatus
.Information
= 0;
1503 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1505 return Irp
->IoStatus
.Status
;
1508 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1509 if (NT_SUCCESS(Status
)) {
1510 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1511 Request
.RequestContext
= Irp
;
1513 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1514 &Info
->Buffer
, Info
->BufferSize
);
1520 /* TODO: Support multiple addresses per interface.
1521 * For now just set the nte context to the interface index.
1523 * Later on, create an NTE context and NTE instance
1526 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1527 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1528 PIP_SET_ADDRESS IpAddrChange
=
1529 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1532 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1533 IpAddrChange
->NteIndex
));
1535 ForEachInterface(IF
) {
1536 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1538 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1539 Status
= STATUS_DUPLICATE_OBJECTID
;
1542 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1543 IPRemoveInterfaceRoute( IF
);
1545 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1546 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1547 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1548 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1549 IF
->Broadcast
.Address
.IPv4Address
=
1550 IF
->Unicast
.Address
.IPv4Address
|
1551 ~IF
->Netmask
.Address
.IPv4Address
;
1553 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1554 IF
->Unicast
.Address
.IPv4Address
));
1555 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1556 IF
->Netmask
.Address
.IPv4Address
));
1558 IPAddInterfaceRoute( IF
);
1560 IpAddrChange
->Address
= IF
->Index
;
1561 Status
= STATUS_SUCCESS
;
1562 Irp
->IoStatus
.Information
= IF
->Index
;
1567 Irp
->IoStatus
.Status
= Status
;
1571 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1572 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1573 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1576 ForEachInterface(IF
) {
1577 if( IF
->Index
== *NteIndex
) {
1578 IPRemoveInterfaceRoute( IF
);
1579 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1580 IF
->Unicast
.Address
.IPv4Address
= 0;
1581 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1582 IF
->Netmask
.Address
.IPv4Address
= 0;
1583 Status
= STATUS_SUCCESS
;
1587 Irp
->IoStatus
.Status
= Status
;