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 IoReleaseCancelSpinLock(OldIrql
);
91 Irp
->IoStatus
.Status
= Status
;
92 Irp
->IoStatus
.Information
= Count
;
94 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
95 Irp
->IoStatus
.Status
));
96 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
97 Irp
->IoStatus
.Information
));
98 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
100 IRPFinish(Irp
, Status
);
102 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
105 VOID
DispDoDisconnect( PVOID Data
) {
106 PDISCONNECT_TYPE DisType
= (PDISCONNECT_TYPE
)Data
;
108 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect\n"));
114 DispDataRequestComplete
,
116 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect done\n"));
118 DispDataRequestComplete(DisType
->Irp
, STATUS_CANCELLED
, 0);
121 VOID NTAPI
DispCancelRequest(
122 PDEVICE_OBJECT Device
,
125 * FUNCTION: Cancels an IRP
127 * Device = Pointer to device object
128 * Irp = Pointer to an I/O request packet
131 PIO_STACK_LOCATION IrpSp
;
132 PTRANSPORT_CONTEXT TranContext
;
133 PFILE_OBJECT FileObject
;
135 DISCONNECT_TYPE DisType
;
137 /*NTSTATUS Status = STATUS_SUCCESS;*/
139 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
141 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
142 FileObject
= IrpSp
->FileObject
;
143 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
144 MinorFunction
= IrpSp
->MinorFunction
;
146 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
148 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
149 Irp
->IoStatus
.Information
= 0;
153 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
156 /* Try canceling the request */
157 switch(MinorFunction
) {
160 DisType
.Type
= TDI_DISCONNECT_RELEASE
|
161 ((MinorFunction
== TDI_RECEIVE
) ? TDI_DISCONNECT_ABORT
: 0);
162 DisType
.Context
= TranContext
->Handle
.ConnectionContext
;
164 DisType
.FileObject
= FileObject
;
166 TCPRemoveIRP( TranContext
->Handle
.ConnectionContext
, Irp
);
168 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
170 if( !ChewCreate( &WorkItem
, sizeof(DISCONNECT_TYPE
),
171 DispDoDisconnect
, &DisType
) )
175 case TDI_SEND_DATAGRAM
:
176 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
177 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
181 DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
184 case TDI_RECEIVE_DATAGRAM
:
185 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
186 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
190 DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
194 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
198 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
199 IRPFinish(Irp
, STATUS_CANCELLED
);
201 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
205 VOID NTAPI
DispCancelListenRequest(
206 PDEVICE_OBJECT Device
,
209 * FUNCTION: Cancels a listen IRP
211 * Device = Pointer to device object
212 * Irp = Pointer to an I/O request packet
215 PIO_STACK_LOCATION IrpSp
;
216 PTRANSPORT_CONTEXT TranContext
;
217 PFILE_OBJECT FileObject
;
218 PCONNECTION_ENDPOINT Connection
;
219 /*NTSTATUS Status = STATUS_SUCCESS;*/
221 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
223 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
224 FileObject
= IrpSp
->FileObject
;
225 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
226 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
228 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
232 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
235 /* Try canceling the request */
236 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
238 TCPRemoveIRP(Connection
, Irp
);
240 TCPAbortListenForSocket(
241 Connection
->AddressFile
->Listener
,
244 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
246 Irp
->IoStatus
.Information
= 0;
247 IRPFinish(Irp
, STATUS_CANCELLED
);
249 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
253 NTSTATUS
DispTdiAccept(
256 * FUNCTION: TDI_ACCEPT handler
258 * Irp = Pointer to an I/O request packet
260 * Status of operation
263 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
265 return STATUS_NOT_IMPLEMENTED
;
269 NTSTATUS
DispTdiAssociateAddress(
272 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
274 * Irp = Pointer to an I/O request packet
276 * Status of operation
279 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
280 PTRANSPORT_CONTEXT TranContext
;
281 PIO_STACK_LOCATION IrpSp
;
282 PCONNECTION_ENDPOINT Connection
;
283 PFILE_OBJECT FileObject
;
284 PADDRESS_FILE AddrFile
= NULL
;
287 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
289 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
291 /* Get associated connection endpoint file object. Quit if none exists */
293 TranContext
= IrpSp
->FileObject
->FsContext
;
295 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
296 return STATUS_INVALID_PARAMETER
;
299 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
301 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
302 return STATUS_INVALID_PARAMETER
;
305 if (Connection
->AddressFile
) {
306 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
307 return STATUS_INVALID_PARAMETER
;
310 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
312 Status
= ObReferenceObjectByHandle(
313 Parameters
->AddressHandle
,
319 if (!NT_SUCCESS(Status
)) {
320 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
321 Parameters
->AddressHandle
, Status
));
322 return STATUS_INVALID_PARAMETER
;
325 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
326 ObDereferenceObject(FileObject
);
327 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
328 FileObject
->FsContext2
));
329 return STATUS_INVALID_PARAMETER
;
332 /* Get associated address file object. Quit if none exists */
334 TranContext
= FileObject
->FsContext
;
336 ObDereferenceObject(FileObject
);
337 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
338 return STATUS_INVALID_PARAMETER
;
341 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
343 ObDereferenceObject(FileObject
);
344 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
345 return STATUS_INVALID_PARAMETER
;
348 Connection
->AddressFile
= AddrFile
;
350 /* Add connection endpoint to the address file */
351 AddrFile
->Connection
= Connection
;
353 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
354 ObDereferenceObject(FileObject
);
360 NTSTATUS
DispTdiConnect(
363 * FUNCTION: TDI_CONNECT handler
365 * Irp = Pointer to an I/O request packet
367 * Status of operation
370 PCONNECTION_ENDPOINT Connection
;
371 PTDI_REQUEST_KERNEL Parameters
;
372 PTRANSPORT_CONTEXT TranContext
;
373 PIO_STACK_LOCATION IrpSp
;
376 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
378 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
380 /* Get associated connection endpoint file object. Quit if none exists */
382 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
384 TranContext
= IrpSp
->FileObject
->FsContext
;
386 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
387 Status
= STATUS_INVALID_PARAMETER
;
391 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
393 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
394 Status
= STATUS_INVALID_PARAMETER
;
398 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
401 TranContext
->Handle
.ConnectionContext
,
402 Parameters
->RequestConnectionInformation
,
403 Parameters
->ReturnConnectionInformation
,
404 DispDataRequestComplete
,
408 if (Status
!= STATUS_PENDING
) {
409 DispDataRequestComplete(Irp
, Status
, 0);
411 IoMarkIrpPending(Irp
);
413 TcpipRecursiveMutexLeave( &TCPLock
);
415 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
421 NTSTATUS
DispTdiDisassociateAddress(
424 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
426 * Irp = Pointer to an I/O request packet
428 * Status of operation
431 PCONNECTION_ENDPOINT Connection
;
432 PTRANSPORT_CONTEXT TranContext
;
433 PIO_STACK_LOCATION IrpSp
;
435 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
437 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
439 /* Get associated connection endpoint file object. Quit if none exists */
441 TranContext
= IrpSp
->FileObject
->FsContext
;
443 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
444 return STATUS_INVALID_PARAMETER
;
447 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
449 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
450 return STATUS_INVALID_PARAMETER
;
453 if (!Connection
->AddressFile
) {
454 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
455 return STATUS_INVALID_PARAMETER
;
458 /* Remove this connection from the address file */
459 Connection
->AddressFile
->Connection
= NULL
;
461 /* Remove the address file from this connection */
462 Connection
->AddressFile
= NULL
;
464 return STATUS_SUCCESS
;
468 NTSTATUS
DispTdiDisconnect(
471 * FUNCTION: TDI_DISCONNECT handler
473 * Irp = Pointer to an I/O request packet
475 * Status of operation
479 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
480 PCONNECTION_ENDPOINT Connection
;
481 PTRANSPORT_CONTEXT TranContext
;
482 PIO_STACK_LOCATION IrpSp
;
484 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
486 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
487 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
489 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
491 /* Get associated connection endpoint file object. Quit if none exists */
493 TranContext
= IrpSp
->FileObject
->FsContext
;
495 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
496 Status
= STATUS_INVALID_PARAMETER
;
500 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
502 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
503 Status
= STATUS_INVALID_PARAMETER
;
507 Status
= TCPDisconnect(
508 TranContext
->Handle
.ConnectionContext
,
509 DisReq
->RequestFlags
,
510 DisReq
->RequestConnectionInformation
,
511 DisReq
->ReturnConnectionInformation
,
512 DispDataRequestComplete
,
516 if (Status
!= STATUS_PENDING
) {
517 DispDataRequestComplete(Irp
, Status
, 0);
519 IoMarkIrpPending(Irp
);
521 TcpipRecursiveMutexLeave( &TCPLock
);
523 TI_DbgPrint(MAX_TRACE
, ("TCP Disconnect returned %08x\n", Status
));
529 NTSTATUS
DispTdiListen(
532 * FUNCTION: TDI_LISTEN handler
534 * Irp = Pointer to an I/O request packet
536 * Status of operation
539 PCONNECTION_ENDPOINT Connection
;
540 PTDI_REQUEST_KERNEL Parameters
;
541 PTRANSPORT_CONTEXT TranContext
;
542 PIO_STACK_LOCATION IrpSp
;
543 NTSTATUS Status
= STATUS_SUCCESS
;
545 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
547 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
549 /* Get associated connection endpoint file object. Quit if none exists */
551 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
553 TranContext
= IrpSp
->FileObject
->FsContext
;
554 if (TranContext
== NULL
)
556 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
557 Status
= STATUS_INVALID_PARAMETER
;
561 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
562 if (Connection
== NULL
)
564 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
565 Status
= STATUS_INVALID_PARAMETER
;
569 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
571 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile: %x\n",
572 Connection
->AddressFile
));
573 if( Connection
->AddressFile
) {
574 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile->Listener: %x\n",
575 Connection
->AddressFile
->Listener
));
578 /* Listening will require us to create a listening socket and store it in
579 * the address file. It will be signalled, and attempt to complete an irp
580 * when a new connection arrives. */
581 /* The important thing to note here is that the irp we'll complete belongs
582 * to the socket to be accepted onto, not the listener */
583 if( !Connection
->AddressFile
->Listener
) {
584 Connection
->AddressFile
->Listener
=
585 TCPAllocateConnectionEndpoint( NULL
);
587 if( !Connection
->AddressFile
->Listener
)
588 Status
= STATUS_NO_MEMORY
;
590 if( NT_SUCCESS(Status
) ) {
591 Connection
->AddressFile
->Listener
->AddressFile
=
592 Connection
->AddressFile
;
594 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
595 Connection
->AddressFile
->Family
,
597 Connection
->AddressFile
->Protocol
);
600 if( NT_SUCCESS(Status
) )
601 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
604 if( NT_SUCCESS(Status
) ) {
605 Status
= DispPrepareIrpForCancel
606 (TranContext
->Handle
.ConnectionContext
,
608 (PDRIVER_CANCEL
)DispCancelListenRequest
);
611 if( NT_SUCCESS(Status
) ) {
613 ( (PTDI_REQUEST
)Parameters
,
614 Connection
->AddressFile
->Listener
,
616 DispDataRequestComplete
,
621 if (Status
!= STATUS_PENDING
) {
622 DispDataRequestComplete(Irp
, Status
, 0);
624 IoMarkIrpPending(Irp
);
626 TcpipRecursiveMutexLeave( &TCPLock
);
628 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
634 NTSTATUS
DispTdiQueryInformation(
635 PDEVICE_OBJECT DeviceObject
,
638 * FUNCTION: TDI_QUERY_INFORMATION handler
640 * DeviceObject = Pointer to device object structure
641 * Irp = Pointer to an I/O request packet
643 * Status of operation
646 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
647 PTRANSPORT_CONTEXT TranContext
;
648 PIO_STACK_LOCATION IrpSp
;
651 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
653 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
654 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
656 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
658 TranContext
= IrpSp
->FileObject
->FsContext
;
660 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
661 TcpipRecursiveMutexLeave(&TCPLock
);
662 return STATUS_INVALID_PARAMETER
;
665 switch (Parameters
->QueryType
)
667 case TDI_QUERY_ADDRESS_INFO
:
669 PTDI_ADDRESS_INFO AddressInfo
;
670 PADDRESS_FILE AddrFile
;
671 PTA_IP_ADDRESS Address
;
672 PCONNECTION_ENDPOINT Endpoint
= NULL
;
675 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
676 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
677 sizeof(TDI_ADDRESS_IP
))) {
678 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
679 TcpipRecursiveMutexLeave(&TCPLock
);
680 return STATUS_BUFFER_TOO_SMALL
;
683 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
684 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
686 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
687 case TDI_TRANSPORT_ADDRESS_FILE
:
688 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
690 Address
->TAAddressCount
= 1;
691 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
692 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
693 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
694 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->Address
.Address
.IPv4Address
;
696 &Address
->Address
[0].Address
[0].sin_zero
,
697 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
698 TcpipRecursiveMutexLeave(&TCPLock
);
699 return STATUS_SUCCESS
;
701 case TDI_CONNECTION_FILE
:
703 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
704 TCPGetSockAddress( Endpoint
, (PTRANSPORT_ADDRESS
)Address
, FALSE
);
705 DbgPrint("Returning socket address %x\n", Address
->Address
[0].Address
[0].in_addr
);
707 &Address
->Address
[0].Address
[0].sin_zero
,
708 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
709 TcpipRecursiveMutexLeave(&TCPLock
);
710 return STATUS_SUCCESS
;
713 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
714 TcpipRecursiveMutexLeave(&TCPLock
);
715 return STATUS_INVALID_PARAMETER
;
719 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
720 TcpipRecursiveMutexLeave(&TCPLock
);
721 return STATUS_INVALID_PARAMETER
;
724 TcpipRecursiveMutexLeave(&TCPLock
);
725 return STATUS_SUCCESS
;
728 case TDI_QUERY_CONNECTION_INFO
:
730 PTDI_CONNECTION_INFORMATION AddressInfo
;
731 PADDRESS_FILE AddrFile
;
732 PCONNECTION_ENDPOINT Endpoint
= NULL
;
734 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
735 (FIELD_OFFSET(TDI_CONNECTION_INFORMATION
, RemoteAddress
) +
737 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small (ptr).\n"));
738 TcpipRecursiveMutexLeave(&TCPLock
);
739 return STATUS_BUFFER_TOO_SMALL
;
742 AddressInfo
= (PTDI_CONNECTION_INFORMATION
)
743 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
745 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
746 case TDI_TRANSPORT_ADDRESS_FILE
:
747 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
750 case TDI_CONNECTION_FILE
:
752 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
756 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
757 TcpipRecursiveMutexLeave(&TCPLock
);
758 return STATUS_INVALID_PARAMETER
;
762 TI_DbgPrint(MID_TRACE
, ("No connection object.\n"));
763 TcpipRecursiveMutexLeave(&TCPLock
);
764 return STATUS_INVALID_PARAMETER
;
767 Status
= TCPGetSockAddress( Endpoint
, AddressInfo
->RemoteAddress
, TRUE
);
769 TcpipRecursiveMutexLeave(&TCPLock
);
774 TcpipRecursiveMutexLeave(&TCPLock
);
775 return STATUS_NOT_IMPLEMENTED
;
779 NTSTATUS
DispTdiReceive(
782 * FUNCTION: TDI_RECEIVE handler
784 * Irp = Pointer to an I/O request packet
786 * Status of operation
789 PIO_STACK_LOCATION IrpSp
;
790 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
791 PTRANSPORT_CONTEXT TranContext
;
793 ULONG BytesReceived
= 0;
795 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
797 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
798 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
800 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
802 TranContext
= IrpSp
->FileObject
->FsContext
;
803 if (TranContext
== NULL
)
805 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
806 Status
= STATUS_INVALID_PARAMETER
;
810 if (TranContext
->Handle
.ConnectionContext
== NULL
)
812 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
813 Status
= STATUS_INVALID_PARAMETER
;
817 /* Initialize a receive request */
818 Status
= DispPrepareIrpForCancel
819 (TranContext
->Handle
.ConnectionContext
,
821 (PDRIVER_CANCEL
)DispCancelRequest
);
823 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
824 if (NT_SUCCESS(Status
))
826 Status
= TCPReceiveData(
827 TranContext
->Handle
.ConnectionContext
,
828 (PNDIS_BUFFER
)Irp
->MdlAddress
,
829 ReceiveInfo
->ReceiveLength
,
831 ReceiveInfo
->ReceiveFlags
,
832 DispDataRequestComplete
,
837 if (Status
!= STATUS_PENDING
) {
838 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
840 IoMarkIrpPending(Irp
);
842 TcpipRecursiveMutexLeave( &TCPLock
);
844 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
850 NTSTATUS
DispTdiReceiveDatagram(
853 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
855 * Irp = Pointer to an I/O request packet
857 * Status of operation
860 PIO_STACK_LOCATION IrpSp
;
861 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
862 PTRANSPORT_CONTEXT TranContext
;
865 ULONG BytesReceived
= 0;
867 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
869 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
870 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
872 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
874 TranContext
= IrpSp
->FileObject
->FsContext
;
875 if (TranContext
== NULL
)
877 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
878 Status
= STATUS_INVALID_PARAMETER
;
882 /* Initialize a receive request */
883 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
884 Request
.RequestNotifyObject
= DispDataRequestComplete
;
885 Request
.RequestContext
= Irp
;
887 Status
= DispPrepareIrpForCancel(
888 IrpSp
->FileObject
->FsContext
,
890 (PDRIVER_CANCEL
)DispCancelRequest
);
892 if (NT_SUCCESS(Status
))
897 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
901 Status
= DGReceiveDatagram(
902 Request
.Handle
.AddressHandle
,
903 DgramInfo
->ReceiveDatagramInformation
,
905 DgramInfo
->ReceiveLength
,
906 DgramInfo
->ReceiveFlags
,
907 DgramInfo
->ReturnDatagramInformation
,
909 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
915 if (Status
!= STATUS_PENDING
) {
916 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
918 IoMarkIrpPending(Irp
);
920 TcpipRecursiveMutexLeave( &TCPLock
);
922 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
928 NTSTATUS
DispTdiSend(
931 * FUNCTION: TDI_SEND handler
933 * Irp = Pointer to an I/O request packet
935 * Status of operation
938 PIO_STACK_LOCATION IrpSp
;
939 PTDI_REQUEST_KERNEL_SEND SendInfo
;
940 PTRANSPORT_CONTEXT TranContext
;
944 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
946 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
947 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
949 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
951 TranContext
= IrpSp
->FileObject
->FsContext
;
952 if (TranContext
== NULL
)
954 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
955 Status
= STATUS_INVALID_PARAMETER
;
959 if (TranContext
->Handle
.ConnectionContext
== NULL
)
961 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
962 Status
= STATUS_INVALID_PARAMETER
;
966 Status
= DispPrepareIrpForCancel(
967 IrpSp
->FileObject
->FsContext
,
969 (PDRIVER_CANCEL
)DispCancelRequest
);
971 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
972 if (NT_SUCCESS(Status
))
977 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
979 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
980 Status
= TCPSendData(
981 TranContext
->Handle
.ConnectionContext
,
983 SendInfo
->SendLength
,
986 DispDataRequestComplete
,
991 if (Status
!= STATUS_PENDING
) {
992 DispDataRequestComplete(Irp
, Status
, BytesSent
);
994 IoMarkIrpPending(Irp
);
996 TcpipRecursiveMutexLeave( &TCPLock
);
998 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
1004 NTSTATUS
DispTdiSendDatagram(
1007 * FUNCTION: TDI_SEND_DATAGRAM handler
1009 * Irp = Pointer to an I/O request packet
1011 * Status of operation
1014 PIO_STACK_LOCATION IrpSp
;
1015 TDI_REQUEST Request
;
1016 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
1017 PTRANSPORT_CONTEXT TranContext
;
1020 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1022 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1023 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
1025 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
1027 TranContext
= IrpSp
->FileObject
->FsContext
;
1028 if (TranContext
== NULL
)
1030 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
1031 Status
= STATUS_INVALID_PARAMETER
;
1035 /* Initialize a send request */
1036 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1037 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1038 Request
.RequestContext
= Irp
;
1040 Status
= DispPrepareIrpForCancel(
1041 IrpSp
->FileObject
->FsContext
,
1043 (PDRIVER_CANCEL
)DispCancelRequest
);
1045 if (NT_SUCCESS(Status
)) {
1049 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
1051 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
1055 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
1056 must be of type PTDI_ADDRESS_IP */
1057 TI_DbgPrint(MID_TRACE
,
1058 ("About to call send routine %x\n",
1059 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
1061 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
) )
1062 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
1063 Request
.Handle
.AddressHandle
,
1064 DgramInfo
->SendDatagramInformation
,
1067 &Irp
->IoStatus
.Information
);
1069 Status
= STATUS_UNSUCCESSFUL
;
1073 if (Status
!= STATUS_PENDING
) {
1074 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
1076 IoMarkIrpPending(Irp
);
1078 TcpipRecursiveMutexLeave( &TCPLock
);
1080 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
1086 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
1088 * FUNCTION: TDI_SET_EVENT_HANDER handler
1090 * Irp = Pointer to a I/O request packet
1092 * Status of operation
1095 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1096 PTRANSPORT_CONTEXT TranContext
;
1097 PIO_STACK_LOCATION IrpSp
;
1098 PADDRESS_FILE AddrFile
;
1102 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1104 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1106 /* Get associated address file object. Quit if none exists */
1108 TranContext
= IrpSp
->FileObject
->FsContext
;
1110 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1111 return STATUS_INVALID_PARAMETER
;
1114 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1116 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1117 return STATUS_INVALID_PARAMETER
;
1120 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1121 Status
= STATUS_SUCCESS
;
1123 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
1125 /* Set the event handler. if an event handler is associated with
1126 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1127 If an event handler is not used it's flag is FALSE */
1128 switch (Parameters
->EventType
) {
1129 case TDI_EVENT_CONNECT
:
1130 if (!Parameters
->EventHandler
) {
1131 AddrFile
->ConnectHandlerContext
= NULL
;
1132 AddrFile
->RegisteredConnectHandler
= FALSE
;
1134 AddrFile
->ConnectHandler
=
1135 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1136 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1137 AddrFile
->RegisteredConnectHandler
= TRUE
;
1141 case TDI_EVENT_DISCONNECT
:
1142 if (!Parameters
->EventHandler
) {
1143 AddrFile
->DisconnectHandlerContext
= NULL
;
1144 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1146 AddrFile
->DisconnectHandler
=
1147 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1148 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1149 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1153 case TDI_EVENT_ERROR
:
1154 if (Parameters
->EventHandler
== NULL
) {
1155 AddrFile
->ErrorHandlerContext
= NULL
;
1156 AddrFile
->RegisteredErrorHandler
= FALSE
;
1158 AddrFile
->ErrorHandler
=
1159 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1160 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1161 AddrFile
->RegisteredErrorHandler
= TRUE
;
1165 case TDI_EVENT_RECEIVE
:
1166 if (Parameters
->EventHandler
== NULL
) {
1167 AddrFile
->ReceiveHandlerContext
= NULL
;
1168 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1170 AddrFile
->ReceiveHandler
=
1171 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1172 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1173 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1177 case TDI_EVENT_RECEIVE_DATAGRAM
:
1178 if (Parameters
->EventHandler
== NULL
) {
1179 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1180 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1182 AddrFile
->ReceiveDatagramHandler
=
1183 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1184 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1185 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1189 case TDI_EVENT_RECEIVE_EXPEDITED
:
1190 if (Parameters
->EventHandler
== NULL
) {
1191 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1192 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1194 AddrFile
->ExpeditedReceiveHandler
=
1195 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1196 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1197 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1201 case TDI_EVENT_CHAINED_RECEIVE
:
1202 if (Parameters
->EventHandler
== NULL
) {
1203 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1204 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1206 AddrFile
->ChainedReceiveHandler
=
1207 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1208 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1209 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1213 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1214 if (Parameters
->EventHandler
== NULL
) {
1215 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1216 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1218 AddrFile
->ChainedReceiveDatagramHandler
=
1219 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1220 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1221 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1225 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1226 if (Parameters
->EventHandler
== NULL
) {
1227 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1228 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1230 AddrFile
->ChainedReceiveExpeditedHandler
=
1231 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1232 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1233 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1238 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1239 Parameters
->EventType
));
1241 Status
= STATUS_INVALID_PARAMETER
;
1244 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1250 NTSTATUS
DispTdiSetInformation(
1253 * FUNCTION: TDI_SET_INFORMATION handler
1255 * Irp = Pointer to an I/O request packet
1257 * Status of operation
1260 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1262 return STATUS_NOT_IMPLEMENTED
;
1266 VOID
DispTdiQueryInformationExComplete(
1271 * FUNCTION: Completes a TDI QueryInformationEx request
1273 * Context = Pointer to the IRP for the request
1274 * Status = TDI status of the request
1275 * ByteCount = Number of bytes returned in output buffer
1278 PTI_QUERY_CONTEXT QueryContext
;
1281 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1282 if (NT_SUCCESS(Status
)) {
1283 Count
= CopyBufferToBufferChain(
1284 QueryContext
->InputMdl
,
1285 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1286 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1290 MmUnlockPages(QueryContext
->InputMdl
);
1291 IoFreeMdl(QueryContext
->InputMdl
);
1292 if( QueryContext
->OutputMdl
) {
1293 MmUnlockPages(QueryContext
->OutputMdl
);
1294 IoFreeMdl(QueryContext
->OutputMdl
);
1297 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1298 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1300 exFreePool(QueryContext
);
1304 NTSTATUS
DispTdiQueryInformationEx(
1306 PIO_STACK_LOCATION IrpSp
)
1308 * FUNCTION: TDI QueryInformationEx handler
1310 * Irp = Pointer to I/O request packet
1311 * IrpSp = Pointer to current stack location of Irp
1313 * Status of operation
1316 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1317 PTRANSPORT_CONTEXT TranContext
;
1318 PTI_QUERY_CONTEXT QueryContext
;
1320 TDI_REQUEST Request
;
1322 UINT InputBufferLength
;
1323 UINT OutputBufferLength
;
1324 BOOLEAN InputMdlLocked
= FALSE
;
1325 BOOLEAN OutputMdlLocked
= FALSE
;
1326 PMDL InputMdl
= NULL
;
1327 PMDL OutputMdl
= NULL
;
1328 NTSTATUS Status
= STATUS_SUCCESS
;
1330 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1332 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1334 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1335 case TDI_TRANSPORT_ADDRESS_FILE
:
1336 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1339 case TDI_CONNECTION_FILE
:
1340 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1343 case TDI_CONTROL_CHANNEL_FILE
:
1344 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1348 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1349 return STATUS_INVALID_PARAMETER
;
1352 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1353 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1355 /* Validate parameters */
1356 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1357 (OutputBufferLength
!= 0)) {
1359 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1360 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1361 OutputBuffer
= Irp
->UserBuffer
;
1363 QueryContext
= exAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1366 InputMdl
= IoAllocateMdl(InputBuffer
,
1367 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1370 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1371 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1373 if (InputMdl
&& OutputMdl
) {
1375 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1378 InputMdlLocked
= TRUE
;
1380 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1383 OutputMdlLocked
= TRUE
;
1385 RtlCopyMemory(&QueryContext
->QueryInfo
,
1386 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1388 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1389 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1390 Status
= _SEH2_GetExceptionCode();
1393 if (NT_SUCCESS(Status
)) {
1394 Size
= MmGetMdlByteCount(OutputMdl
);
1396 QueryContext
->Irp
= Irp
;
1397 QueryContext
->InputMdl
= InputMdl
;
1398 QueryContext
->OutputMdl
= OutputMdl
;
1400 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1401 Request
.RequestContext
= QueryContext
;
1402 Status
= InfoTdiQueryInformationEx(&Request
,
1403 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1404 &Size
, &QueryContext
->QueryInfo
.Context
);
1405 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1407 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1412 /* An error occurred if we get here */
1416 MmUnlockPages(InputMdl
);
1417 IoFreeMdl(InputMdl
);
1421 if (OutputMdlLocked
)
1422 MmUnlockPages(OutputMdl
);
1423 IoFreeMdl(OutputMdl
);
1426 exFreePool(QueryContext
);
1428 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1429 } else if( InputBufferLength
==
1430 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1431 /* Handle the case where the user is probing the buffer for length */
1432 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1433 InputBufferLength
, OutputBufferLength
));
1434 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1435 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1439 QueryContext
= exAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1440 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1443 InputMdl
= IoAllocateMdl(InputBuffer
,
1444 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1447 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1450 InputMdlLocked
= TRUE
;
1451 Status
= STATUS_SUCCESS
;
1452 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1453 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1454 Status
= _SEH2_GetExceptionCode();
1457 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1458 if( InputMdl
) IoFreeMdl( InputMdl
);
1459 exFreePool(QueryContext
);
1463 RtlCopyMemory(&QueryContext
->QueryInfo
,
1464 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1466 QueryContext
->Irp
= Irp
;
1467 QueryContext
->InputMdl
= InputMdl
;
1468 QueryContext
->OutputMdl
= NULL
;
1470 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1471 Request
.RequestContext
= QueryContext
;
1472 Status
= InfoTdiQueryInformationEx(&Request
,
1473 &QueryContext
->QueryInfo
.ID
,
1476 &QueryContext
->QueryInfo
.Context
);
1477 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1478 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1479 } else Status
= STATUS_INVALID_PARAMETER
;
1481 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1487 NTSTATUS
DispTdiSetInformationEx(
1489 PIO_STACK_LOCATION IrpSp
)
1491 * FUNCTION: TDI SetInformationEx handler
1493 * Irp = Pointer to I/O request packet
1494 * IrpSp = Pointer to current stack location of Irp
1496 * Status of operation
1499 PTRANSPORT_CONTEXT TranContext
;
1500 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1501 TDI_REQUEST Request
;
1504 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1506 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1507 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1509 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1510 case TDI_TRANSPORT_ADDRESS_FILE
:
1511 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1514 case TDI_CONNECTION_FILE
:
1515 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1518 case TDI_CONTROL_CHANNEL_FILE
:
1519 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1523 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1524 Irp
->IoStatus
.Information
= 0;
1526 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1528 return Irp
->IoStatus
.Status
;
1531 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1532 if (NT_SUCCESS(Status
)) {
1533 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1534 Request
.RequestContext
= Irp
;
1536 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1537 &Info
->Buffer
, Info
->BufferSize
);
1543 /* TODO: Support multiple addresses per interface.
1544 * For now just set the nte context to the interface index.
1546 * Later on, create an NTE context and NTE instance
1549 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1550 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1551 PIP_SET_ADDRESS IpAddrChange
=
1552 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1555 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1556 IpAddrChange
->NteIndex
));
1558 ForEachInterface(IF
) {
1559 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1561 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1562 Status
= STATUS_DUPLICATE_OBJECTID
;
1565 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1566 IPRemoveInterfaceRoute( IF
);
1568 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1569 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1570 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1571 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1572 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1573 IF
->Broadcast
.Address
.IPv4Address
=
1574 IF
->Unicast
.Address
.IPv4Address
|
1575 ~IF
->Netmask
.Address
.IPv4Address
;
1577 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1578 IF
->Unicast
.Address
.IPv4Address
));
1579 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1580 IF
->Netmask
.Address
.IPv4Address
));
1582 IPAddInterfaceRoute( IF
);
1584 IpAddrChange
->Address
= IF
->Index
;
1585 Status
= STATUS_SUCCESS
;
1586 Irp
->IoStatus
.Information
= IF
->Index
;
1591 Irp
->IoStatus
.Status
= Status
;
1595 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1596 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1597 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1600 ForEachInterface(IF
) {
1601 if( IF
->Index
== *NteIndex
) {
1602 IPRemoveInterfaceRoute( IF
);
1603 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1604 IF
->Unicast
.Address
.IPv4Address
= 0;
1605 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1606 IF
->Netmask
.Address
.IPv4Address
= 0;
1607 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1608 IF
->Broadcast
.Address
.IPv4Address
= 0;
1609 Status
= STATUS_SUCCESS
;
1613 Irp
->IoStatus
.Status
= Status
;