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/pseh2.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
30 PIO_STACK_LOCATION IrpSp
;
31 PTRANSPORT_CONTEXT TransContext
;
33 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
35 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
36 TransContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
38 IoAcquireCancelSpinLock(&OldIrql
);
40 if (!Irp
->Cancel
&& !TransContext
->CancelIrps
) {
41 (void)IoSetCancelRoutine(Irp
, CancelRoutine
);
42 IoReleaseCancelSpinLock(OldIrql
);
44 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
46 return STATUS_SUCCESS
;
49 /* IRP has already been cancelled */
51 IoReleaseCancelSpinLock(OldIrql
);
53 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
54 Irp
->IoStatus
.Information
= 0;
56 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
58 return Irp
->IoStatus
.Status
;
61 VOID
DispDataRequestComplete(
66 * FUNCTION: Completes a send/receive IRP
68 * Context = Pointer to context information (IRP)
69 * Status = Status of the request
70 * Count = Number of bytes sent or received
74 PIO_STACK_LOCATION IrpSp
;
75 PTRANSPORT_CONTEXT TranContext
;
78 TI_DbgPrint(DEBUG_IRP
, ("Called for irp %x (%x, %d).\n",
79 Context
, Status
, Count
));
82 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
83 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
85 IoAcquireCancelSpinLock(&OldIrql
);
87 (void)IoSetCancelRoutine(Irp
, NULL
);
89 if (Irp
->Cancel
|| TranContext
->CancelIrps
) {
90 /* The IRP has been cancelled */
92 TI_DbgPrint(DEBUG_IRP
, ("IRP is cancelled.\n"));
94 Status
= STATUS_CANCELLED
;
98 IoReleaseCancelSpinLock(OldIrql
);
100 Irp
->IoStatus
.Status
= Status
;
101 Irp
->IoStatus
.Information
= Count
;
103 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
104 Irp
->IoStatus
.Status
));
105 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
106 Irp
->IoStatus
.Information
));
107 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
109 IRPFinish(Irp
, Irp
->IoStatus
.Status
);
111 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
114 typedef struct _DISCONNECT_TYPE
{
118 PFILE_OBJECT FileObject
;
119 } DISCONNECT_TYPE
, *PDISCONNECT_TYPE
;
121 VOID
DispDoDisconnect( PVOID Data
) {
122 PDISCONNECT_TYPE DisType
= (PDISCONNECT_TYPE
)Data
;
124 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect\n"));
130 DispDataRequestComplete
,
132 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect done\n"));
134 DispDataRequestComplete(DisType
->Irp
, STATUS_CANCELLED
, 0);
137 VOID NTAPI
DispCancelRequest(
138 PDEVICE_OBJECT Device
,
141 * FUNCTION: Cancels an IRP
143 * Device = Pointer to device object
144 * Irp = Pointer to an I/O request packet
147 PIO_STACK_LOCATION IrpSp
;
148 PTRANSPORT_CONTEXT TranContext
;
149 PFILE_OBJECT FileObject
;
151 DISCONNECT_TYPE DisType
;
153 /*NTSTATUS Status = STATUS_SUCCESS;*/
155 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
157 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
158 FileObject
= IrpSp
->FileObject
;
159 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
160 MinorFunction
= IrpSp
->MinorFunction
;
162 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
164 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
165 Irp
->IoStatus
.Information
= 0;
169 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
172 /* Try canceling the request */
173 switch(MinorFunction
) {
176 DisType
.Type
= TDI_DISCONNECT_RELEASE
|
177 ((MinorFunction
== TDI_RECEIVE
) ? TDI_DISCONNECT_ABORT
: 0);
178 DisType
.Context
= TranContext
->Handle
.ConnectionContext
;
180 DisType
.FileObject
= FileObject
;
182 TCPRemoveIRP( TranContext
->Handle
.ConnectionContext
, Irp
);
184 if( !ChewCreate( &WorkItem
, sizeof(DISCONNECT_TYPE
),
185 DispDoDisconnect
, &DisType
) )
188 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
191 case TDI_SEND_DATAGRAM
:
192 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
193 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
197 DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
200 case TDI_RECEIVE_DATAGRAM
:
201 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
202 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
206 DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
210 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
214 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
215 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
217 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
221 VOID NTAPI
DispCancelListenRequest(
222 PDEVICE_OBJECT Device
,
225 * FUNCTION: Cancels a listen IRP
227 * Device = Pointer to device object
228 * Irp = Pointer to an I/O request packet
231 PIO_STACK_LOCATION IrpSp
;
232 PTRANSPORT_CONTEXT TranContext
;
233 PFILE_OBJECT FileObject
;
234 PCONNECTION_ENDPOINT Connection
;
235 /*NTSTATUS Status = STATUS_SUCCESS;*/
237 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
239 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
240 FileObject
= IrpSp
->FileObject
;
241 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
242 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
244 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
248 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
251 /* Try canceling the request */
252 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
253 TCPAbortListenForSocket(
254 Connection
->AddressFile
->Listener
,
257 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
259 DispDataRequestComplete(Irp
, STATUS_CANCELLED
, 0);
261 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
265 NTSTATUS
DispTdiAccept(
268 * FUNCTION: TDI_ACCEPT handler
270 * Irp = Pointer to an I/O request packet
272 * Status of operation
275 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
277 return STATUS_NOT_IMPLEMENTED
;
281 NTSTATUS
DispTdiAssociateAddress(
284 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
286 * Irp = Pointer to an I/O request packet
288 * Status of operation
291 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
292 PTRANSPORT_CONTEXT TranContext
;
293 PIO_STACK_LOCATION IrpSp
;
294 PCONNECTION_ENDPOINT Connection
;
295 PFILE_OBJECT FileObject
;
296 PADDRESS_FILE AddrFile
= NULL
;
299 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
301 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
303 /* Get associated connection endpoint file object. Quit if none exists */
305 TranContext
= IrpSp
->FileObject
->FsContext
;
307 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
308 return STATUS_INVALID_PARAMETER
;
311 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
313 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
314 return STATUS_INVALID_PARAMETER
;
317 if (Connection
->AddressFile
) {
318 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
319 return STATUS_INVALID_PARAMETER
;
322 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
324 Status
= ObReferenceObjectByHandle(
325 Parameters
->AddressHandle
,
331 if (!NT_SUCCESS(Status
)) {
332 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
333 Parameters
->AddressHandle
, Status
));
334 return STATUS_INVALID_PARAMETER
;
337 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
338 ObDereferenceObject(FileObject
);
339 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
340 FileObject
->FsContext2
));
341 return STATUS_INVALID_PARAMETER
;
344 /* Get associated address file object. Quit if none exists */
346 TranContext
= FileObject
->FsContext
;
348 ObDereferenceObject(FileObject
);
349 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
350 return STATUS_INVALID_PARAMETER
;
353 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
355 ObDereferenceObject(FileObject
);
356 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
357 return STATUS_INVALID_PARAMETER
;
360 Connection
->AddressFile
= AddrFile
;
362 /* Add connection endpoint to the address file */
363 AddrFile
->Connection
= Connection
;
365 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
366 ObDereferenceObject(FileObject
);
372 NTSTATUS
DispTdiConnect(
375 * FUNCTION: TDI_CONNECT handler
377 * Irp = Pointer to an I/O request packet
379 * Status of operation
382 PCONNECTION_ENDPOINT Connection
;
383 PTDI_REQUEST_KERNEL Parameters
;
384 PTRANSPORT_CONTEXT TranContext
;
385 PIO_STACK_LOCATION IrpSp
;
388 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
390 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
392 /* Get associated connection endpoint file object. Quit if none exists */
394 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
396 TranContext
= IrpSp
->FileObject
->FsContext
;
398 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
399 Status
= STATUS_INVALID_CONNECTION
;
403 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
405 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
406 Status
= STATUS_INVALID_CONNECTION
;
410 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
413 TranContext
->Handle
.ConnectionContext
,
414 Parameters
->RequestConnectionInformation
,
415 Parameters
->ReturnConnectionInformation
,
416 DispDataRequestComplete
,
420 if (Status
!= STATUS_PENDING
) {
421 DispDataRequestComplete(Irp
, Status
, 0);
423 IoMarkIrpPending(Irp
);
425 TcpipRecursiveMutexLeave( &TCPLock
);
427 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
433 NTSTATUS
DispTdiDisassociateAddress(
436 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
438 * Irp = Pointer to an I/O request packet
440 * Status of operation
443 PCONNECTION_ENDPOINT Connection
;
444 PTRANSPORT_CONTEXT TranContext
;
445 PIO_STACK_LOCATION IrpSp
;
447 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
449 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
451 /* Get associated connection endpoint file object. Quit if none exists */
453 TranContext
= IrpSp
->FileObject
->FsContext
;
455 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
456 return STATUS_INVALID_PARAMETER
;
459 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
461 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
462 return STATUS_INVALID_PARAMETER
;
465 if (!Connection
->AddressFile
) {
466 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
467 return STATUS_INVALID_PARAMETER
;
470 return STATUS_SUCCESS
;
474 NTSTATUS
DispTdiDisconnect(
477 * FUNCTION: TDI_DISCONNECT handler
479 * Irp = Pointer to an I/O request packet
481 * Status of operation
485 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
486 PCONNECTION_ENDPOINT Connection
;
487 PTRANSPORT_CONTEXT TranContext
;
488 PIO_STACK_LOCATION IrpSp
;
490 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
492 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
493 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
495 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
497 /* Get associated connection endpoint file object. Quit if none exists */
499 TranContext
= IrpSp
->FileObject
->FsContext
;
501 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
502 Status
= STATUS_INVALID_CONNECTION
;
506 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
508 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
509 Status
= STATUS_INVALID_CONNECTION
;
513 Status
= TCPDisconnect(
514 TranContext
->Handle
.ConnectionContext
,
515 DisReq
->RequestFlags
,
516 DisReq
->RequestConnectionInformation
,
517 DisReq
->ReturnConnectionInformation
,
518 DispDataRequestComplete
,
522 if (Status
!= STATUS_PENDING
) {
523 DispDataRequestComplete(Irp
, Status
, 0);
525 IoMarkIrpPending(Irp
);
527 TcpipRecursiveMutexLeave( &TCPLock
);
529 TI_DbgPrint(MAX_TRACE
, ("TCP Disconnect returned %08x\n", Status
));
535 NTSTATUS
DispTdiListen(
538 * FUNCTION: TDI_LISTEN handler
540 * Irp = Pointer to an I/O request packet
542 * Status of operation
545 PCONNECTION_ENDPOINT Connection
;
546 PTDI_REQUEST_KERNEL Parameters
;
547 PTRANSPORT_CONTEXT TranContext
;
548 PIO_STACK_LOCATION IrpSp
;
549 NTSTATUS Status
= STATUS_SUCCESS
;
551 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
553 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
555 /* Get associated connection endpoint file object. Quit if none exists */
557 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
559 TranContext
= IrpSp
->FileObject
->FsContext
;
560 if (TranContext
== NULL
)
562 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
563 Status
= STATUS_INVALID_CONNECTION
;
567 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
568 if (Connection
== NULL
)
570 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
571 Status
= STATUS_INVALID_CONNECTION
;
575 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
577 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile: %x\n",
578 Connection
->AddressFile
));
579 if( Connection
->AddressFile
) {
580 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile->Listener: %x\n",
581 Connection
->AddressFile
->Listener
));
584 /* Listening will require us to create a listening socket and store it in
585 * the address file. It will be signalled, and attempt to complete an irp
586 * when a new connection arrives. */
587 /* The important thing to note here is that the irp we'll complete belongs
588 * to the socket to be accepted onto, not the listener */
589 if( !Connection
->AddressFile
->Listener
) {
590 Connection
->AddressFile
->Listener
=
591 TCPAllocateConnectionEndpoint( NULL
);
593 if( !Connection
->AddressFile
->Listener
)
594 Status
= STATUS_NO_MEMORY
;
596 if( NT_SUCCESS(Status
) ) {
597 Connection
->AddressFile
->Listener
->AddressFile
=
598 Connection
->AddressFile
;
600 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
601 Connection
->AddressFile
->Family
,
603 Connection
->AddressFile
->Protocol
);
606 if( NT_SUCCESS(Status
) )
607 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
610 if( NT_SUCCESS(Status
) ) {
611 Status
= DispPrepareIrpForCancel
612 (TranContext
->Handle
.ConnectionContext
,
614 (PDRIVER_CANCEL
)DispCancelListenRequest
);
617 if( NT_SUCCESS(Status
) ) {
619 ( (PTDI_REQUEST
)Parameters
,
620 Connection
->AddressFile
->Listener
,
622 DispDataRequestComplete
,
627 if (Status
!= STATUS_PENDING
) {
628 DispDataRequestComplete(Irp
, Status
, 0);
630 IoMarkIrpPending(Irp
);
632 TcpipRecursiveMutexLeave( &TCPLock
);
634 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
640 NTSTATUS
DispTdiQueryInformation(
641 PDEVICE_OBJECT DeviceObject
,
644 * FUNCTION: TDI_QUERY_INFORMATION handler
646 * DeviceObject = Pointer to device object structure
647 * Irp = Pointer to an I/O request packet
649 * Status of operation
652 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
653 PTRANSPORT_CONTEXT TranContext
;
654 PIO_STACK_LOCATION IrpSp
;
656 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
658 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
659 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
661 TranContext
= IrpSp
->FileObject
->FsContext
;
663 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
664 return STATUS_INVALID_CONNECTION
;
667 switch (Parameters
->QueryType
)
669 case TDI_QUERY_ADDRESS_INFO
:
671 PTDI_ADDRESS_INFO AddressInfo
;
672 PADDRESS_FILE AddrFile
;
673 PTA_IP_ADDRESS Address
;
675 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
677 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
678 case TDI_TRANSPORT_ADDRESS_FILE
:
679 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
682 case TDI_CONNECTION_FILE
:
684 ((PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
)->
689 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
690 return STATUS_INVALID_PARAMETER
;
694 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
695 return STATUS_INVALID_PARAMETER
;
698 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
699 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
700 sizeof(TDI_ADDRESS_IP
))) {
701 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
702 return STATUS_BUFFER_OVERFLOW
;
705 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
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
=
711 AddrFile
->Address
.Address
.IPv4Address
;
713 &Address
->Address
[0].Address
[0].sin_zero
,
714 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
716 return STATUS_SUCCESS
;
719 case TDI_QUERY_CONNECTION_INFO
:
721 PTDI_CONNECTION_INFORMATION AddressInfo
;
722 PADDRESS_FILE AddrFile
;
723 PCONNECTION_ENDPOINT Endpoint
= NULL
;
725 AddressInfo
= (PTDI_CONNECTION_INFORMATION
)
726 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
728 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
729 case TDI_TRANSPORT_ADDRESS_FILE
:
730 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
733 case TDI_CONNECTION_FILE
:
735 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
739 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
740 return STATUS_INVALID_PARAMETER
;
744 TI_DbgPrint(MID_TRACE
, ("No connection object.\n"));
745 return STATUS_INVALID_PARAMETER
;
748 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
749 (FIELD_OFFSET(TDI_CONNECTION_INFORMATION
, RemoteAddress
) +
751 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small (ptr).\n"));
752 return STATUS_BUFFER_OVERFLOW
;
755 return TCPGetPeerAddress( Endpoint
, AddressInfo
->RemoteAddress
);
759 return STATUS_NOT_IMPLEMENTED
;
763 NTSTATUS
DispTdiReceive(
766 * FUNCTION: TDI_RECEIVE handler
768 * Irp = Pointer to an I/O request packet
770 * Status of operation
773 PIO_STACK_LOCATION IrpSp
;
774 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
775 PTRANSPORT_CONTEXT TranContext
;
777 ULONG BytesReceived
= 0;
779 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
781 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
782 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
784 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
786 TranContext
= IrpSp
->FileObject
->FsContext
;
787 if (TranContext
== NULL
)
789 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
790 Status
= STATUS_INVALID_CONNECTION
;
794 if (TranContext
->Handle
.ConnectionContext
== NULL
)
796 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
797 Status
= STATUS_INVALID_CONNECTION
;
801 /* Initialize a receive request */
802 Status
= DispPrepareIrpForCancel
803 (TranContext
->Handle
.ConnectionContext
,
805 (PDRIVER_CANCEL
)DispCancelRequest
);
807 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
808 if (NT_SUCCESS(Status
))
810 Status
= TCPReceiveData(
811 TranContext
->Handle
.ConnectionContext
,
812 (PNDIS_BUFFER
)Irp
->MdlAddress
,
813 ReceiveInfo
->ReceiveLength
,
815 ReceiveInfo
->ReceiveFlags
,
816 DispDataRequestComplete
,
821 if (Status
!= STATUS_PENDING
) {
822 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
824 IoMarkIrpPending(Irp
);
826 TcpipRecursiveMutexLeave( &TCPLock
);
828 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
834 NTSTATUS
DispTdiReceiveDatagram(
837 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
839 * Irp = Pointer to an I/O request packet
841 * Status of operation
844 PIO_STACK_LOCATION IrpSp
;
845 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
846 PTRANSPORT_CONTEXT TranContext
;
849 ULONG BytesReceived
= 0;
851 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
853 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
854 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
856 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
858 TranContext
= IrpSp
->FileObject
->FsContext
;
859 if (TranContext
== NULL
)
861 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
862 Status
= STATUS_INVALID_CONNECTION
;
866 /* Initialize a receive request */
867 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
868 Request
.RequestNotifyObject
= DispDataRequestComplete
;
869 Request
.RequestContext
= Irp
;
871 Status
= DispPrepareIrpForCancel(
872 IrpSp
->FileObject
->FsContext
,
874 (PDRIVER_CANCEL
)DispCancelRequest
);
876 if (NT_SUCCESS(Status
))
881 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
885 Status
= DGReceiveDatagram(
886 Request
.Handle
.AddressHandle
,
887 DgramInfo
->ReceiveDatagramInformation
,
889 DgramInfo
->ReceiveLength
,
890 DgramInfo
->ReceiveFlags
,
891 DgramInfo
->ReturnDatagramInformation
,
893 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
899 if (Status
!= STATUS_PENDING
) {
900 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
902 IoMarkIrpPending(Irp
);
904 TcpipRecursiveMutexLeave( &TCPLock
);
906 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
912 NTSTATUS
DispTdiSend(
915 * FUNCTION: TDI_SEND handler
917 * Irp = Pointer to an I/O request packet
919 * Status of operation
922 PIO_STACK_LOCATION IrpSp
;
923 PTDI_REQUEST_KERNEL_SEND SendInfo
;
924 PTRANSPORT_CONTEXT TranContext
;
928 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
930 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
931 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
933 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
935 TranContext
= IrpSp
->FileObject
->FsContext
;
936 if (TranContext
== NULL
)
938 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
939 Status
= STATUS_INVALID_CONNECTION
;
943 if (TranContext
->Handle
.ConnectionContext
== NULL
)
945 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
946 Status
= STATUS_INVALID_CONNECTION
;
950 Status
= DispPrepareIrpForCancel(
951 IrpSp
->FileObject
->FsContext
,
953 (PDRIVER_CANCEL
)DispCancelRequest
);
955 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
956 if (NT_SUCCESS(Status
))
961 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
963 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
964 Status
= TCPSendData(
965 TranContext
->Handle
.ConnectionContext
,
967 SendInfo
->SendLength
,
970 DispDataRequestComplete
,
975 if (Status
!= STATUS_PENDING
) {
976 DispDataRequestComplete(Irp
, Status
, BytesSent
);
978 IoMarkIrpPending(Irp
);
980 TcpipRecursiveMutexLeave( &TCPLock
);
982 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
988 NTSTATUS
DispTdiSendDatagram(
991 * FUNCTION: TDI_SEND_DATAGRAM handler
993 * Irp = Pointer to an I/O request packet
995 * Status of operation
998 PIO_STACK_LOCATION IrpSp
;
1000 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
1001 PTRANSPORT_CONTEXT TranContext
;
1004 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1006 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1007 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
1009 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
1011 TranContext
= IrpSp
->FileObject
->FsContext
;
1012 if (TranContext
== NULL
)
1014 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
1015 Status
= STATUS_INVALID_CONNECTION
;
1019 /* Initialize a send request */
1020 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1021 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1022 Request
.RequestContext
= Irp
;
1024 Status
= DispPrepareIrpForCancel(
1025 IrpSp
->FileObject
->FsContext
,
1027 (PDRIVER_CANCEL
)DispCancelRequest
);
1029 if (NT_SUCCESS(Status
)) {
1033 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
1035 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
1039 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
1040 must be of type PTDI_ADDRESS_IP */
1041 TI_DbgPrint(MID_TRACE
,
1042 ("About to call send routine %x\n",
1043 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
1045 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
) )
1046 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
1047 Request
.Handle
.AddressHandle
,
1048 DgramInfo
->SendDatagramInformation
,
1051 &Irp
->IoStatus
.Information
);
1053 Status
= STATUS_UNSUCCESSFUL
;
1057 if (Status
!= STATUS_PENDING
) {
1058 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
1060 IoMarkIrpPending(Irp
);
1062 TcpipRecursiveMutexLeave( &TCPLock
);
1064 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
1070 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
1072 * FUNCTION: TDI_SET_EVENT_HANDER handler
1074 * Irp = Pointer to a I/O request packet
1076 * Status of operation
1079 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1080 PTRANSPORT_CONTEXT TranContext
;
1081 PIO_STACK_LOCATION IrpSp
;
1082 PADDRESS_FILE AddrFile
;
1086 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1088 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1090 /* Get associated address file object. Quit if none exists */
1092 TranContext
= IrpSp
->FileObject
->FsContext
;
1094 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1095 return STATUS_INVALID_PARAMETER
;
1098 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1100 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1101 return STATUS_INVALID_PARAMETER
;
1104 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1105 Status
= STATUS_SUCCESS
;
1107 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
1109 /* Set the event handler. if an event handler is associated with
1110 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1111 If an event handler is not used it's flag is FALSE */
1112 switch (Parameters
->EventType
) {
1113 case TDI_EVENT_CONNECT
:
1114 if (!Parameters
->EventHandler
) {
1115 AddrFile
->ConnectHandlerContext
= NULL
;
1116 AddrFile
->RegisteredConnectHandler
= FALSE
;
1118 AddrFile
->ConnectHandler
=
1119 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1120 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1121 AddrFile
->RegisteredConnectHandler
= TRUE
;
1125 case TDI_EVENT_DISCONNECT
:
1126 if (!Parameters
->EventHandler
) {
1127 AddrFile
->DisconnectHandlerContext
= NULL
;
1128 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1130 AddrFile
->DisconnectHandler
=
1131 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1132 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1133 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1137 case TDI_EVENT_ERROR
:
1138 if (Parameters
->EventHandler
== NULL
) {
1139 AddrFile
->ErrorHandlerContext
= NULL
;
1140 AddrFile
->RegisteredErrorHandler
= FALSE
;
1142 AddrFile
->ErrorHandler
=
1143 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1144 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1145 AddrFile
->RegisteredErrorHandler
= TRUE
;
1149 case TDI_EVENT_RECEIVE
:
1150 if (Parameters
->EventHandler
== NULL
) {
1151 AddrFile
->ReceiveHandlerContext
= NULL
;
1152 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1154 AddrFile
->ReceiveHandler
=
1155 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1156 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1157 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1161 case TDI_EVENT_RECEIVE_DATAGRAM
:
1162 if (Parameters
->EventHandler
== NULL
) {
1163 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1164 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1166 AddrFile
->ReceiveDatagramHandler
=
1167 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1168 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1169 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1173 case TDI_EVENT_RECEIVE_EXPEDITED
:
1174 if (Parameters
->EventHandler
== NULL
) {
1175 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1176 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1178 AddrFile
->ExpeditedReceiveHandler
=
1179 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1180 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1181 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1185 case TDI_EVENT_CHAINED_RECEIVE
:
1186 if (Parameters
->EventHandler
== NULL
) {
1187 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1188 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1190 AddrFile
->ChainedReceiveHandler
=
1191 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1192 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1193 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1197 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1198 if (Parameters
->EventHandler
== NULL
) {
1199 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1200 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1202 AddrFile
->ChainedReceiveDatagramHandler
=
1203 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1204 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1205 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1209 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1210 if (Parameters
->EventHandler
== NULL
) {
1211 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1212 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1214 AddrFile
->ChainedReceiveExpeditedHandler
=
1215 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1216 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1217 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1222 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1223 Parameters
->EventType
));
1225 Status
= STATUS_INVALID_PARAMETER
;
1228 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1234 NTSTATUS
DispTdiSetInformation(
1237 * FUNCTION: TDI_SET_INFORMATION handler
1239 * Irp = Pointer to an I/O request packet
1241 * Status of operation
1244 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1246 return STATUS_NOT_IMPLEMENTED
;
1250 VOID
DispTdiQueryInformationExComplete(
1255 * FUNCTION: Completes a TDI QueryInformationEx request
1257 * Context = Pointer to the IRP for the request
1258 * Status = TDI status of the request
1259 * ByteCount = Number of bytes returned in output buffer
1262 PTI_QUERY_CONTEXT QueryContext
;
1265 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1266 if (NT_SUCCESS(Status
)) {
1267 Count
= CopyBufferToBufferChain(
1268 QueryContext
->InputMdl
,
1269 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1270 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1274 MmUnlockPages(QueryContext
->InputMdl
);
1275 IoFreeMdl(QueryContext
->InputMdl
);
1276 if( QueryContext
->OutputMdl
) {
1277 MmUnlockPages(QueryContext
->OutputMdl
);
1278 IoFreeMdl(QueryContext
->OutputMdl
);
1281 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1282 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1284 exFreePool(QueryContext
);
1288 NTSTATUS
DispTdiQueryInformationEx(
1290 PIO_STACK_LOCATION IrpSp
)
1292 * FUNCTION: TDI QueryInformationEx handler
1294 * Irp = Pointer to I/O request packet
1295 * IrpSp = Pointer to current stack location of Irp
1297 * Status of operation
1300 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1301 PTRANSPORT_CONTEXT TranContext
;
1302 PTI_QUERY_CONTEXT QueryContext
;
1304 TDI_REQUEST Request
;
1306 UINT InputBufferLength
;
1307 UINT OutputBufferLength
;
1308 BOOLEAN InputMdlLocked
= FALSE
;
1309 BOOLEAN OutputMdlLocked
= FALSE
;
1310 PMDL InputMdl
= NULL
;
1311 PMDL OutputMdl
= NULL
;
1312 NTSTATUS Status
= STATUS_SUCCESS
;
1314 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1316 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1318 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1319 case TDI_TRANSPORT_ADDRESS_FILE
:
1320 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1323 case TDI_CONNECTION_FILE
:
1324 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1327 case TDI_CONTROL_CHANNEL_FILE
:
1328 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1332 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1333 return STATUS_INVALID_PARAMETER
;
1336 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1337 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1339 /* Validate parameters */
1340 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1341 (OutputBufferLength
!= 0)) {
1343 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1344 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1345 OutputBuffer
= Irp
->UserBuffer
;
1347 QueryContext
= exAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1350 InputMdl
= IoAllocateMdl(InputBuffer
,
1351 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1354 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1355 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1357 if (InputMdl
&& OutputMdl
) {
1359 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1362 InputMdlLocked
= TRUE
;
1364 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1367 OutputMdlLocked
= TRUE
;
1369 RtlCopyMemory(&QueryContext
->QueryInfo
,
1370 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1372 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1373 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1374 Status
= _SEH2_GetExceptionCode();
1377 if (NT_SUCCESS(Status
)) {
1378 Size
= MmGetMdlByteCount(OutputMdl
);
1380 QueryContext
->Irp
= Irp
;
1381 QueryContext
->InputMdl
= InputMdl
;
1382 QueryContext
->OutputMdl
= OutputMdl
;
1384 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1385 Request
.RequestContext
= QueryContext
;
1386 Status
= InfoTdiQueryInformationEx(&Request
,
1387 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1388 &Size
, &QueryContext
->QueryInfo
.Context
);
1389 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1391 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1396 /* An error occurred if we get here */
1400 MmUnlockPages(InputMdl
);
1401 IoFreeMdl(InputMdl
);
1405 if (OutputMdlLocked
)
1406 MmUnlockPages(OutputMdl
);
1407 IoFreeMdl(OutputMdl
);
1410 exFreePool(QueryContext
);
1412 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1413 } else if( InputBufferLength
==
1414 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1415 /* Handle the case where the user is probing the buffer for length */
1416 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1417 InputBufferLength
, OutputBufferLength
));
1418 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1419 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1423 QueryContext
= exAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1424 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1427 InputMdl
= IoAllocateMdl(InputBuffer
,
1428 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1431 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1434 InputMdlLocked
= TRUE
;
1435 Status
= STATUS_SUCCESS
;
1436 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1437 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1438 Status
= _SEH2_GetExceptionCode();
1441 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1442 if( InputMdl
) IoFreeMdl( InputMdl
);
1443 exFreePool(QueryContext
);
1447 RtlCopyMemory(&QueryContext
->QueryInfo
,
1448 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1450 QueryContext
->Irp
= Irp
;
1451 QueryContext
->InputMdl
= InputMdl
;
1452 QueryContext
->OutputMdl
= NULL
;
1454 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1455 Request
.RequestContext
= QueryContext
;
1456 Status
= InfoTdiQueryInformationEx(&Request
,
1457 &QueryContext
->QueryInfo
.ID
,
1460 &QueryContext
->QueryInfo
.Context
);
1461 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1462 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1463 } else Status
= STATUS_INVALID_PARAMETER
;
1465 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1471 NTSTATUS
DispTdiSetInformationEx(
1473 PIO_STACK_LOCATION IrpSp
)
1475 * FUNCTION: TDI SetInformationEx handler
1477 * Irp = Pointer to I/O request packet
1478 * IrpSp = Pointer to current stack location of Irp
1480 * Status of operation
1483 PTRANSPORT_CONTEXT TranContext
;
1484 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1485 TDI_REQUEST Request
;
1488 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1490 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1491 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1493 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1494 case TDI_TRANSPORT_ADDRESS_FILE
:
1495 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1498 case TDI_CONNECTION_FILE
:
1499 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1502 case TDI_CONTROL_CHANNEL_FILE
:
1503 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1507 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1508 Irp
->IoStatus
.Information
= 0;
1510 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1512 return Irp
->IoStatus
.Status
;
1515 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1516 if (NT_SUCCESS(Status
)) {
1517 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1518 Request
.RequestContext
= Irp
;
1520 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1521 &Info
->Buffer
, Info
->BufferSize
);
1527 /* TODO: Support multiple addresses per interface.
1528 * For now just set the nte context to the interface index.
1530 * Later on, create an NTE context and NTE instance
1533 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1534 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1535 PIP_SET_ADDRESS IpAddrChange
=
1536 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1539 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1540 IpAddrChange
->NteIndex
));
1542 ForEachInterface(IF
) {
1543 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1545 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1546 Status
= STATUS_DUPLICATE_OBJECTID
;
1549 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1550 IPRemoveInterfaceRoute( IF
);
1552 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1553 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1554 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1555 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1556 IF
->Broadcast
.Address
.IPv4Address
=
1557 IF
->Unicast
.Address
.IPv4Address
|
1558 ~IF
->Netmask
.Address
.IPv4Address
;
1560 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1561 IF
->Unicast
.Address
.IPv4Address
));
1562 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1563 IF
->Netmask
.Address
.IPv4Address
));
1565 IPAddInterfaceRoute( IF
);
1567 IpAddrChange
->Address
= IF
->Index
;
1568 Status
= STATUS_SUCCESS
;
1569 Irp
->IoStatus
.Information
= IF
->Index
;
1574 Irp
->IoStatus
.Status
= Status
;
1578 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1579 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1580 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1583 ForEachInterface(IF
) {
1584 if( IF
->Index
== *NteIndex
) {
1585 IPRemoveInterfaceRoute( IF
);
1586 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1587 IF
->Unicast
.Address
.IPv4Address
= 0;
1588 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1589 IF
->Netmask
.Address
.IPv4Address
= 0;
1590 Status
= STATUS_SUCCESS
;
1594 Irp
->IoStatus
.Status
= Status
;