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_PTR
)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_PTR
)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
) )
1041 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
1042 Request
.Handle
.AddressHandle
,
1043 DgramInfo
->SendDatagramInformation
,
1047 Irp
->IoStatus
.Information
= DataUsed
;
1050 Status
= STATUS_UNSUCCESSFUL
;
1054 if (Status
!= STATUS_PENDING
) {
1055 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
1057 IoMarkIrpPending(Irp
);
1059 TcpipRecursiveMutexLeave( &TCPLock
);
1061 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
1067 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
1069 * FUNCTION: TDI_SET_EVENT_HANDER handler
1071 * Irp = Pointer to a I/O request packet
1073 * Status of operation
1076 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1077 PTRANSPORT_CONTEXT TranContext
;
1078 PIO_STACK_LOCATION IrpSp
;
1079 PADDRESS_FILE AddrFile
;
1083 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1085 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1087 /* Get associated address file object. Quit if none exists */
1089 TranContext
= IrpSp
->FileObject
->FsContext
;
1091 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1092 return STATUS_INVALID_PARAMETER
;
1095 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1097 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1098 return STATUS_INVALID_PARAMETER
;
1101 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1102 Status
= STATUS_SUCCESS
;
1104 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
1106 /* Set the event handler. if an event handler is associated with
1107 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1108 If an event handler is not used it's flag is FALSE */
1109 switch (Parameters
->EventType
) {
1110 case TDI_EVENT_CONNECT
:
1111 if (!Parameters
->EventHandler
) {
1112 AddrFile
->ConnectHandlerContext
= NULL
;
1113 AddrFile
->RegisteredConnectHandler
= FALSE
;
1115 AddrFile
->ConnectHandler
=
1116 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1117 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1118 AddrFile
->RegisteredConnectHandler
= TRUE
;
1122 case TDI_EVENT_DISCONNECT
:
1123 if (!Parameters
->EventHandler
) {
1124 AddrFile
->DisconnectHandlerContext
= NULL
;
1125 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1127 AddrFile
->DisconnectHandler
=
1128 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1129 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1130 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1134 case TDI_EVENT_ERROR
:
1135 if (Parameters
->EventHandler
== NULL
) {
1136 AddrFile
->ErrorHandlerContext
= NULL
;
1137 AddrFile
->RegisteredErrorHandler
= FALSE
;
1139 AddrFile
->ErrorHandler
=
1140 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1141 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1142 AddrFile
->RegisteredErrorHandler
= TRUE
;
1146 case TDI_EVENT_RECEIVE
:
1147 if (Parameters
->EventHandler
== NULL
) {
1148 AddrFile
->ReceiveHandlerContext
= NULL
;
1149 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1151 AddrFile
->ReceiveHandler
=
1152 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1153 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1154 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1158 case TDI_EVENT_RECEIVE_DATAGRAM
:
1159 if (Parameters
->EventHandler
== NULL
) {
1160 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1161 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1163 AddrFile
->ReceiveDatagramHandler
=
1164 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1165 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1166 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1170 case TDI_EVENT_RECEIVE_EXPEDITED
:
1171 if (Parameters
->EventHandler
== NULL
) {
1172 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1173 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1175 AddrFile
->ExpeditedReceiveHandler
=
1176 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1177 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1178 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1182 case TDI_EVENT_CHAINED_RECEIVE
:
1183 if (Parameters
->EventHandler
== NULL
) {
1184 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1185 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1187 AddrFile
->ChainedReceiveHandler
=
1188 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1189 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1190 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1194 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1195 if (Parameters
->EventHandler
== NULL
) {
1196 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1197 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1199 AddrFile
->ChainedReceiveDatagramHandler
=
1200 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1201 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1202 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1206 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1207 if (Parameters
->EventHandler
== NULL
) {
1208 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1209 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1211 AddrFile
->ChainedReceiveExpeditedHandler
=
1212 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1213 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1214 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1219 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1220 Parameters
->EventType
));
1222 Status
= STATUS_INVALID_PARAMETER
;
1225 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1231 NTSTATUS
DispTdiSetInformation(
1234 * FUNCTION: TDI_SET_INFORMATION handler
1236 * Irp = Pointer to an I/O request packet
1238 * Status of operation
1241 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1243 return STATUS_NOT_IMPLEMENTED
;
1247 VOID
DispTdiQueryInformationExComplete(
1252 * FUNCTION: Completes a TDI QueryInformationEx request
1254 * Context = Pointer to the IRP for the request
1255 * Status = TDI status of the request
1256 * ByteCount = Number of bytes returned in output buffer
1259 PTI_QUERY_CONTEXT QueryContext
;
1262 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1263 if (NT_SUCCESS(Status
)) {
1264 Count
= CopyBufferToBufferChain(
1265 QueryContext
->InputMdl
,
1266 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1267 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1271 MmUnlockPages(QueryContext
->InputMdl
);
1272 IoFreeMdl(QueryContext
->InputMdl
);
1273 if( QueryContext
->OutputMdl
) {
1274 MmUnlockPages(QueryContext
->OutputMdl
);
1275 IoFreeMdl(QueryContext
->OutputMdl
);
1278 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1279 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1281 ExFreePool(QueryContext
);
1285 NTSTATUS
DispTdiQueryInformationEx(
1287 PIO_STACK_LOCATION IrpSp
)
1289 * FUNCTION: TDI QueryInformationEx handler
1291 * Irp = Pointer to I/O request packet
1292 * IrpSp = Pointer to current stack location of Irp
1294 * Status of operation
1297 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1298 PTRANSPORT_CONTEXT TranContext
;
1299 PTI_QUERY_CONTEXT QueryContext
;
1301 TDI_REQUEST Request
;
1303 UINT InputBufferLength
;
1304 UINT OutputBufferLength
;
1305 BOOLEAN InputMdlLocked
= FALSE
;
1306 BOOLEAN OutputMdlLocked
= FALSE
;
1307 PMDL InputMdl
= NULL
;
1308 PMDL OutputMdl
= NULL
;
1309 NTSTATUS Status
= STATUS_SUCCESS
;
1311 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1313 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1315 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
1316 case TDI_TRANSPORT_ADDRESS_FILE
:
1317 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1320 case TDI_CONNECTION_FILE
:
1321 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1324 case TDI_CONTROL_CHANNEL_FILE
:
1325 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1329 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1330 return STATUS_INVALID_PARAMETER
;
1333 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1334 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1336 /* Validate parameters */
1337 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1338 (OutputBufferLength
!= 0)) {
1340 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1341 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1342 OutputBuffer
= Irp
->UserBuffer
;
1344 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1347 InputMdl
= IoAllocateMdl(InputBuffer
,
1348 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1351 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1352 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1354 if (InputMdl
&& OutputMdl
) {
1356 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1359 InputMdlLocked
= TRUE
;
1361 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1364 OutputMdlLocked
= TRUE
;
1366 RtlCopyMemory(&QueryContext
->QueryInfo
,
1367 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1369 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1371 Status
= _SEH_GetExceptionCode();
1374 if (NT_SUCCESS(Status
)) {
1375 Size
= MmGetMdlByteCount(OutputMdl
);
1377 QueryContext
->Irp
= Irp
;
1378 QueryContext
->InputMdl
= InputMdl
;
1379 QueryContext
->OutputMdl
= OutputMdl
;
1381 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1382 Request
.RequestContext
= QueryContext
;
1383 Status
= InfoTdiQueryInformationEx(&Request
,
1384 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1385 &Size
, &QueryContext
->QueryInfo
.Context
);
1386 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1388 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1393 /* An error occurred if we get here */
1397 MmUnlockPages(InputMdl
);
1398 IoFreeMdl(InputMdl
);
1402 if (OutputMdlLocked
)
1403 MmUnlockPages(OutputMdl
);
1404 IoFreeMdl(OutputMdl
);
1407 ExFreePool(QueryContext
);
1409 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1410 } else if( InputBufferLength
==
1411 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1412 /* Handle the case where the user is probing the buffer for length */
1413 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1414 InputBufferLength
, OutputBufferLength
));
1415 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1416 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1420 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1421 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1424 InputMdl
= IoAllocateMdl(InputBuffer
,
1425 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1428 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1431 InputMdlLocked
= TRUE
;
1432 Status
= STATUS_SUCCESS
;
1434 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1435 Status
= _SEH_GetExceptionCode();
1438 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1439 if( InputMdl
) IoFreeMdl( InputMdl
);
1440 ExFreePool(QueryContext
);
1444 RtlCopyMemory(&QueryContext
->QueryInfo
,
1445 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1447 QueryContext
->Irp
= Irp
;
1448 QueryContext
->InputMdl
= InputMdl
;
1449 QueryContext
->OutputMdl
= NULL
;
1451 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1452 Request
.RequestContext
= QueryContext
;
1453 Status
= InfoTdiQueryInformationEx(&Request
,
1454 &QueryContext
->QueryInfo
.ID
,
1457 &QueryContext
->QueryInfo
.Context
);
1458 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1459 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1460 } else Status
= STATUS_INVALID_PARAMETER
;
1462 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1468 NTSTATUS
DispTdiSetInformationEx(
1470 PIO_STACK_LOCATION IrpSp
)
1472 * FUNCTION: TDI SetInformationEx handler
1474 * Irp = Pointer to I/O request packet
1475 * IrpSp = Pointer to current stack location of Irp
1477 * Status of operation
1480 PTRANSPORT_CONTEXT TranContext
;
1481 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1482 TDI_REQUEST Request
;
1485 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1487 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1488 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1490 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
1491 case TDI_TRANSPORT_ADDRESS_FILE
:
1492 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1495 case TDI_CONNECTION_FILE
:
1496 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1499 case TDI_CONTROL_CHANNEL_FILE
:
1500 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1504 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1505 Irp
->IoStatus
.Information
= 0;
1507 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1509 return Irp
->IoStatus
.Status
;
1512 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1513 if (NT_SUCCESS(Status
)) {
1514 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1515 Request
.RequestContext
= Irp
;
1517 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1518 &Info
->Buffer
, Info
->BufferSize
);
1524 /* TODO: Support multiple addresses per interface.
1525 * For now just set the nte context to the interface index.
1527 * Later on, create an NTE context and NTE instance
1530 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1531 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1532 PIP_SET_ADDRESS IpAddrChange
=
1533 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1536 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1537 IpAddrChange
->NteIndex
));
1539 ForEachInterface(IF
) {
1540 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1542 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1543 Status
= STATUS_DUPLICATE_OBJECTID
;
1546 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1547 IPRemoveInterfaceRoute( IF
);
1549 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1550 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1551 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1552 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1553 IF
->Broadcast
.Address
.IPv4Address
=
1554 IF
->Unicast
.Address
.IPv4Address
|
1555 ~IF
->Netmask
.Address
.IPv4Address
;
1557 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1558 IF
->Unicast
.Address
.IPv4Address
));
1559 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1560 IF
->Netmask
.Address
.IPv4Address
));
1562 IPAddInterfaceRoute( IF
);
1564 IpAddrChange
->Address
= IF
->Index
;
1565 Status
= STATUS_SUCCESS
;
1566 Irp
->IoStatus
.Information
= IF
->Index
;
1571 Irp
->IoStatus
.Status
= Status
;
1575 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1576 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1577 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1580 ForEachInterface(IF
) {
1581 if( IF
->Index
== *NteIndex
) {
1582 IPRemoveInterfaceRoute( IF
);
1583 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1584 IF
->Unicast
.Address
.IPv4Address
= 0;
1585 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1586 IF
->Netmask
.Address
.IPv4Address
= 0;
1587 Status
= STATUS_SUCCESS
;
1591 Irp
->IoStatus
.Status
= Status
;