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"));
109 TcpipRecursiveMutexEnter(&TCPLock
, TRUE
);
115 DispDataRequestComplete
,
117 TcpipRecursiveMutexLeave(&TCPLock
);
118 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect done\n"));
120 DispDataRequestComplete(DisType
->Irp
, STATUS_CANCELLED
, 0);
125 VOID NTAPI
DispCancelRequest(
126 PDEVICE_OBJECT Device
,
129 * FUNCTION: Cancels an IRP
131 * Device = Pointer to device object
132 * Irp = Pointer to an I/O request packet
135 PIO_STACK_LOCATION IrpSp
;
136 PTRANSPORT_CONTEXT TranContext
;
137 PFILE_OBJECT FileObject
;
139 PDISCONNECT_TYPE DisType
;
141 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
143 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
144 FileObject
= IrpSp
->FileObject
;
145 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
146 MinorFunction
= IrpSp
->MinorFunction
;
148 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
150 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
151 Irp
->IoStatus
.Information
= 0;
155 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
158 /* Try canceling the request */
159 switch(MinorFunction
) {
162 DisType
= exAllocatePool(NonPagedPool
, sizeof(DISCONNECT_TYPE
));
165 DisType
->Type
= TDI_DISCONNECT_RELEASE
|
166 ((MinorFunction
== TDI_RECEIVE
) ? TDI_DISCONNECT_ABORT
: 0);
167 DisType
->Context
= TranContext
->Handle
.ConnectionContext
;
170 TCPRemoveIRP( TranContext
->Handle
.ConnectionContext
, Irp
);
172 if (!ChewCreate(DispDoDisconnect
, DisType
))
176 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
179 case TDI_SEND_DATAGRAM
:
180 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
181 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
185 DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
188 case TDI_RECEIVE_DATAGRAM
:
189 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
190 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
194 DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
198 TCPRemoveIRP(TranContext
->Handle
.ConnectionContext
, Irp
);
202 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
206 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
207 IRPFinish(Irp
, STATUS_CANCELLED
);
209 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
213 VOID NTAPI
DispCancelListenRequest(
214 PDEVICE_OBJECT Device
,
217 * FUNCTION: Cancels a listen IRP
219 * Device = Pointer to device object
220 * Irp = Pointer to an I/O request packet
223 PIO_STACK_LOCATION IrpSp
;
224 PTRANSPORT_CONTEXT TranContext
;
225 PFILE_OBJECT FileObject
;
226 PCONNECTION_ENDPOINT Connection
;
227 /*NTSTATUS Status = STATUS_SUCCESS;*/
229 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
231 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
232 FileObject
= IrpSp
->FileObject
;
233 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
234 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
236 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
240 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
243 /* Try canceling the request */
244 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
246 TCPRemoveIRP(Connection
, Irp
);
248 TCPAbortListenForSocket(
249 Connection
->AddressFile
->Listener
,
252 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
254 Irp
->IoStatus
.Information
= 0;
255 IRPFinish(Irp
, STATUS_CANCELLED
);
257 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
261 NTSTATUS
DispTdiAccept(
264 * FUNCTION: TDI_ACCEPT handler
266 * Irp = Pointer to an I/O request packet
268 * Status of operation
271 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
273 return STATUS_NOT_IMPLEMENTED
;
277 NTSTATUS
DispTdiAssociateAddress(
280 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
282 * Irp = Pointer to an I/O request packet
284 * Status of operation
287 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
288 PTRANSPORT_CONTEXT TranContext
;
289 PIO_STACK_LOCATION IrpSp
;
290 PCONNECTION_ENDPOINT Connection
;
291 PFILE_OBJECT FileObject
;
292 PADDRESS_FILE AddrFile
= NULL
;
295 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
297 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
299 /* Get associated connection endpoint file object. Quit if none exists */
301 TranContext
= IrpSp
->FileObject
->FsContext
;
303 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
304 return STATUS_INVALID_PARAMETER
;
307 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
309 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
310 return STATUS_INVALID_PARAMETER
;
313 if (Connection
->AddressFile
) {
314 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
315 return STATUS_INVALID_PARAMETER
;
318 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
320 Status
= ObReferenceObjectByHandle(
321 Parameters
->AddressHandle
,
327 if (!NT_SUCCESS(Status
)) {
328 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
329 Parameters
->AddressHandle
, Status
));
330 return STATUS_INVALID_PARAMETER
;
333 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
334 ObDereferenceObject(FileObject
);
335 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
336 FileObject
->FsContext2
));
337 return STATUS_INVALID_PARAMETER
;
340 /* Get associated address file object. Quit if none exists */
342 TranContext
= FileObject
->FsContext
;
344 ObDereferenceObject(FileObject
);
345 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
346 return STATUS_INVALID_PARAMETER
;
349 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
351 ObDereferenceObject(FileObject
);
352 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
353 return STATUS_INVALID_PARAMETER
;
356 Connection
->AddressFile
= AddrFile
;
358 /* Add connection endpoint to the address file */
359 AddrFile
->Connection
= Connection
;
361 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
362 ObDereferenceObject(FileObject
);
368 NTSTATUS
DispTdiConnect(
371 * FUNCTION: TDI_CONNECT handler
373 * Irp = Pointer to an I/O request packet
375 * Status of operation
378 PCONNECTION_ENDPOINT Connection
;
379 PTDI_REQUEST_KERNEL Parameters
;
380 PTRANSPORT_CONTEXT TranContext
;
381 PIO_STACK_LOCATION IrpSp
;
384 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
386 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
388 /* Get associated connection endpoint file object. Quit if none exists */
390 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
392 TranContext
= IrpSp
->FileObject
->FsContext
;
394 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
395 Status
= STATUS_INVALID_PARAMETER
;
399 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
401 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
402 Status
= STATUS_INVALID_PARAMETER
;
406 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
408 Status
= DispPrepareIrpForCancel(TranContext
->Handle
.ConnectionContext
,
412 if (NT_SUCCESS(Status
)) {
414 TranContext
->Handle
.ConnectionContext
,
415 Parameters
->RequestConnectionInformation
,
416 Parameters
->ReturnConnectionInformation
,
417 DispDataRequestComplete
,
422 TcpipRecursiveMutexLeave( &TCPLock
);
424 if (Status
!= STATUS_PENDING
) {
425 DispDataRequestComplete(Irp
, Status
, 0);
427 IoMarkIrpPending(Irp
);
429 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
435 NTSTATUS
DispTdiDisassociateAddress(
438 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
440 * Irp = Pointer to an I/O request packet
442 * Status of operation
445 PCONNECTION_ENDPOINT Connection
;
446 PTRANSPORT_CONTEXT TranContext
;
447 PIO_STACK_LOCATION IrpSp
;
449 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
451 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
453 /* Get associated connection endpoint file object. Quit if none exists */
455 TranContext
= IrpSp
->FileObject
->FsContext
;
457 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
458 return STATUS_INVALID_PARAMETER
;
461 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
463 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
464 return STATUS_INVALID_PARAMETER
;
467 if (!Connection
->AddressFile
) {
468 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
469 return STATUS_INVALID_PARAMETER
;
472 /* Remove this connection from the address file */
473 Connection
->AddressFile
->Connection
= NULL
;
475 /* Remove the address file from this connection */
476 Connection
->AddressFile
= NULL
;
478 return STATUS_SUCCESS
;
482 NTSTATUS
DispTdiDisconnect(
485 * FUNCTION: TDI_DISCONNECT handler
487 * Irp = Pointer to an I/O request packet
489 * Status of operation
493 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
494 PCONNECTION_ENDPOINT Connection
;
495 PTRANSPORT_CONTEXT TranContext
;
496 PIO_STACK_LOCATION IrpSp
;
498 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
500 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
501 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
503 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
505 /* Get associated connection endpoint file object. Quit if none exists */
507 TranContext
= IrpSp
->FileObject
->FsContext
;
509 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
510 Status
= STATUS_INVALID_PARAMETER
;
514 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
516 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
517 Status
= STATUS_INVALID_PARAMETER
;
521 Status
= TCPDisconnect(
522 TranContext
->Handle
.ConnectionContext
,
523 DisReq
->RequestFlags
,
524 DisReq
->RequestConnectionInformation
,
525 DisReq
->ReturnConnectionInformation
,
526 DispDataRequestComplete
,
530 TcpipRecursiveMutexLeave( &TCPLock
);
532 if (Status
!= STATUS_PENDING
) {
533 DispDataRequestComplete(Irp
, Status
, 0);
535 IoMarkIrpPending(Irp
);
537 TI_DbgPrint(MAX_TRACE
, ("TCP Disconnect returned %08x\n", Status
));
543 NTSTATUS
DispTdiListen(
546 * FUNCTION: TDI_LISTEN handler
548 * Irp = Pointer to an I/O request packet
550 * Status of operation
553 PCONNECTION_ENDPOINT Connection
;
554 PTDI_REQUEST_KERNEL Parameters
;
555 PTRANSPORT_CONTEXT TranContext
;
556 PIO_STACK_LOCATION IrpSp
;
557 NTSTATUS Status
= STATUS_SUCCESS
;
559 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
561 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
563 /* Get associated connection endpoint file object. Quit if none exists */
565 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
567 TranContext
= IrpSp
->FileObject
->FsContext
;
568 if (TranContext
== NULL
)
570 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
571 Status
= STATUS_INVALID_PARAMETER
;
575 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
576 if (Connection
== NULL
)
578 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
579 Status
= STATUS_INVALID_PARAMETER
;
583 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
585 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile: %x\n",
586 Connection
->AddressFile
));
587 ASSERT(Connection
->AddressFile
);
589 Status
= DispPrepareIrpForCancel
590 (TranContext
->Handle
.ConnectionContext
,
592 (PDRIVER_CANCEL
)DispCancelListenRequest
);
594 /* Listening will require us to create a listening socket and store it in
595 * the address file. It will be signalled, and attempt to complete an irp
596 * when a new connection arrives. */
597 /* The important thing to note here is that the irp we'll complete belongs
598 * to the socket to be accepted onto, not the listener */
599 if( NT_SUCCESS(Status
) && !Connection
->AddressFile
->Listener
) {
600 Connection
->AddressFile
->Listener
=
601 TCPAllocateConnectionEndpoint( NULL
);
603 if( !Connection
->AddressFile
->Listener
)
604 Status
= STATUS_NO_MEMORY
;
606 if( NT_SUCCESS(Status
) ) {
607 Connection
->AddressFile
->Listener
->AddressFile
=
608 Connection
->AddressFile
;
610 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
611 Connection
->AddressFile
->Family
,
613 Connection
->AddressFile
->Protocol
);
616 if( NT_SUCCESS(Status
) )
617 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
621 if( NT_SUCCESS(Status
) ) {
623 ( (PTDI_REQUEST
)Parameters
,
624 Connection
->AddressFile
->Listener
,
626 DispDataRequestComplete
,
631 TcpipRecursiveMutexLeave( &TCPLock
);
633 if (Status
!= STATUS_PENDING
) {
634 DispDataRequestComplete(Irp
, Status
, 0);
636 IoMarkIrpPending(Irp
);
638 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
644 NTSTATUS
DispTdiQueryInformation(
645 PDEVICE_OBJECT DeviceObject
,
648 * FUNCTION: TDI_QUERY_INFORMATION handler
650 * DeviceObject = Pointer to device object structure
651 * Irp = Pointer to an I/O request packet
653 * Status of operation
656 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
657 PTRANSPORT_CONTEXT TranContext
;
658 PIO_STACK_LOCATION IrpSp
;
661 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
663 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
664 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
666 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
668 TranContext
= IrpSp
->FileObject
->FsContext
;
670 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
671 TcpipRecursiveMutexLeave(&TCPLock
);
672 return STATUS_INVALID_PARAMETER
;
675 switch (Parameters
->QueryType
)
677 case TDI_QUERY_ADDRESS_INFO
:
679 PTDI_ADDRESS_INFO AddressInfo
;
680 PADDRESS_FILE AddrFile
;
681 PTA_IP_ADDRESS Address
;
682 PCONNECTION_ENDPOINT Endpoint
= NULL
;
685 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
686 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
687 sizeof(TDI_ADDRESS_IP
))) {
688 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
689 TcpipRecursiveMutexLeave(&TCPLock
);
690 return STATUS_BUFFER_TOO_SMALL
;
693 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
694 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
696 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
697 case TDI_TRANSPORT_ADDRESS_FILE
:
698 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
700 Address
->TAAddressCount
= 1;
701 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
702 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
703 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
704 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->Address
.Address
.IPv4Address
;
706 &Address
->Address
[0].Address
[0].sin_zero
,
707 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
708 TcpipRecursiveMutexLeave(&TCPLock
);
709 return STATUS_SUCCESS
;
711 case TDI_CONNECTION_FILE
:
713 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
714 TCPGetSockAddress( Endpoint
, (PTRANSPORT_ADDRESS
)Address
, FALSE
);
715 DbgPrint("Returning socket address %x\n", Address
->Address
[0].Address
[0].in_addr
);
717 &Address
->Address
[0].Address
[0].sin_zero
,
718 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
719 TcpipRecursiveMutexLeave(&TCPLock
);
720 return STATUS_SUCCESS
;
723 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
724 TcpipRecursiveMutexLeave(&TCPLock
);
725 return STATUS_INVALID_PARAMETER
;
729 case TDI_QUERY_CONNECTION_INFO
:
731 PTDI_CONNECTION_INFORMATION AddressInfo
;
732 PADDRESS_FILE AddrFile
;
733 PCONNECTION_ENDPOINT Endpoint
= NULL
;
735 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
736 (FIELD_OFFSET(TDI_CONNECTION_INFORMATION
, RemoteAddress
) +
738 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small (ptr).\n"));
739 TcpipRecursiveMutexLeave(&TCPLock
);
740 return STATUS_BUFFER_TOO_SMALL
;
743 AddressInfo
= (PTDI_CONNECTION_INFORMATION
)
744 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
746 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
747 case TDI_TRANSPORT_ADDRESS_FILE
:
748 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
749 Endpoint
= AddrFile
? AddrFile
->Connection
: NULL
;
752 case TDI_CONNECTION_FILE
:
754 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
758 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
759 TcpipRecursiveMutexLeave(&TCPLock
);
760 return STATUS_INVALID_PARAMETER
;
764 TI_DbgPrint(MID_TRACE
, ("No connection object.\n"));
765 TcpipRecursiveMutexLeave(&TCPLock
);
766 return STATUS_INVALID_PARAMETER
;
769 Status
= TCPGetSockAddress( Endpoint
, AddressInfo
->RemoteAddress
, TRUE
);
771 TcpipRecursiveMutexLeave(&TCPLock
);
776 TcpipRecursiveMutexLeave(&TCPLock
);
777 return STATUS_NOT_IMPLEMENTED
;
781 NTSTATUS
DispTdiReceive(
784 * FUNCTION: TDI_RECEIVE handler
786 * Irp = Pointer to an I/O request packet
788 * Status of operation
791 PIO_STACK_LOCATION IrpSp
;
792 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
793 PTRANSPORT_CONTEXT TranContext
;
795 ULONG BytesReceived
= 0;
797 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
799 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
800 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
802 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
804 TranContext
= IrpSp
->FileObject
->FsContext
;
805 if (TranContext
== NULL
)
807 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
808 Status
= STATUS_INVALID_PARAMETER
;
812 if (TranContext
->Handle
.ConnectionContext
== NULL
)
814 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
815 Status
= STATUS_INVALID_PARAMETER
;
819 /* Initialize a receive request */
820 Status
= DispPrepareIrpForCancel
821 (TranContext
->Handle
.ConnectionContext
,
823 (PDRIVER_CANCEL
)DispCancelRequest
);
825 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
826 if (NT_SUCCESS(Status
))
828 Status
= TCPReceiveData(
829 TranContext
->Handle
.ConnectionContext
,
830 (PNDIS_BUFFER
)Irp
->MdlAddress
,
831 ReceiveInfo
->ReceiveLength
,
833 ReceiveInfo
->ReceiveFlags
,
834 DispDataRequestComplete
,
839 TcpipRecursiveMutexLeave( &TCPLock
);
841 if (Status
!= STATUS_PENDING
) {
842 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
844 IoMarkIrpPending(Irp
);
846 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
852 NTSTATUS
DispTdiReceiveDatagram(
855 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
857 * Irp = Pointer to an I/O request packet
859 * Status of operation
862 PIO_STACK_LOCATION IrpSp
;
863 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
864 PTRANSPORT_CONTEXT TranContext
;
867 ULONG BytesReceived
= 0;
869 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
871 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
872 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
874 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
876 TranContext
= IrpSp
->FileObject
->FsContext
;
877 if (TranContext
== NULL
)
879 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
880 Status
= STATUS_INVALID_PARAMETER
;
884 /* Initialize a receive request */
885 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
886 Request
.RequestNotifyObject
= DispDataRequestComplete
;
887 Request
.RequestContext
= Irp
;
889 Status
= DispPrepareIrpForCancel(
890 IrpSp
->FileObject
->FsContext
,
892 (PDRIVER_CANCEL
)DispCancelRequest
);
894 if (NT_SUCCESS(Status
))
899 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
903 Status
= DGReceiveDatagram(
904 Request
.Handle
.AddressHandle
,
905 DgramInfo
->ReceiveDatagramInformation
,
907 DgramInfo
->ReceiveLength
,
908 DgramInfo
->ReceiveFlags
,
909 DgramInfo
->ReturnDatagramInformation
,
911 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
917 TcpipRecursiveMutexLeave( &TCPLock
);
919 if (Status
!= STATUS_PENDING
) {
920 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
922 IoMarkIrpPending(Irp
);
924 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
930 NTSTATUS
DispTdiSend(
933 * FUNCTION: TDI_SEND handler
935 * Irp = Pointer to an I/O request packet
937 * Status of operation
940 PIO_STACK_LOCATION IrpSp
;
941 PTDI_REQUEST_KERNEL_SEND SendInfo
;
942 PTRANSPORT_CONTEXT TranContext
;
946 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
948 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
949 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
951 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
953 TranContext
= IrpSp
->FileObject
->FsContext
;
954 if (TranContext
== NULL
)
956 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
957 Status
= STATUS_INVALID_PARAMETER
;
961 if (TranContext
->Handle
.ConnectionContext
== NULL
)
963 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
964 Status
= STATUS_INVALID_PARAMETER
;
968 Status
= DispPrepareIrpForCancel(
969 IrpSp
->FileObject
->FsContext
,
971 (PDRIVER_CANCEL
)DispCancelRequest
);
973 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
974 if (NT_SUCCESS(Status
))
979 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
981 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
982 Status
= TCPSendData(
983 TranContext
->Handle
.ConnectionContext
,
985 SendInfo
->SendLength
,
988 DispDataRequestComplete
,
993 TcpipRecursiveMutexLeave( &TCPLock
);
995 if (Status
!= STATUS_PENDING
) {
996 DispDataRequestComplete(Irp
, Status
, BytesSent
);
998 IoMarkIrpPending(Irp
);
1000 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
1006 NTSTATUS
DispTdiSendDatagram(
1009 * FUNCTION: TDI_SEND_DATAGRAM handler
1011 * Irp = Pointer to an I/O request packet
1013 * Status of operation
1016 PIO_STACK_LOCATION IrpSp
;
1017 TDI_REQUEST Request
;
1018 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
1019 PTRANSPORT_CONTEXT TranContext
;
1022 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1024 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1025 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
1027 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
1029 TranContext
= IrpSp
->FileObject
->FsContext
;
1030 if (TranContext
== NULL
)
1032 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
1033 Status
= STATUS_INVALID_PARAMETER
;
1037 /* Initialize a send request */
1038 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1039 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1040 Request
.RequestContext
= Irp
;
1042 Status
= DispPrepareIrpForCancel(
1043 IrpSp
->FileObject
->FsContext
,
1045 (PDRIVER_CANCEL
)DispCancelRequest
);
1047 if (NT_SUCCESS(Status
)) {
1051 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
1053 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
1057 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
1058 must be of type PTDI_ADDRESS_IP */
1059 TI_DbgPrint(MID_TRACE
,
1060 ("About to call send routine %x\n",
1061 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
1063 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
!= NULL
) )
1066 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
1067 Request
.Handle
.AddressHandle
,
1068 DgramInfo
->SendDatagramInformation
,
1072 Irp
->IoStatus
.Information
= DataUsed
;
1075 Status
= STATUS_UNSUCCESSFUL
;
1079 TcpipRecursiveMutexLeave( &TCPLock
);
1081 if (Status
!= STATUS_PENDING
) {
1082 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
1084 IoMarkIrpPending(Irp
);
1086 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
1092 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
1094 * FUNCTION: TDI_SET_EVENT_HANDER handler
1096 * Irp = Pointer to a I/O request packet
1098 * Status of operation
1101 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1102 PTRANSPORT_CONTEXT TranContext
;
1103 PIO_STACK_LOCATION IrpSp
;
1104 PADDRESS_FILE AddrFile
;
1108 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1110 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1112 /* Get associated address file object. Quit if none exists */
1114 TranContext
= IrpSp
->FileObject
->FsContext
;
1116 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1117 return STATUS_INVALID_PARAMETER
;
1120 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1122 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1123 return STATUS_INVALID_PARAMETER
;
1126 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1127 Status
= STATUS_SUCCESS
;
1129 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
1131 /* Set the event handler. if an event handler is associated with
1132 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1133 If an event handler is not used it's flag is FALSE */
1134 switch (Parameters
->EventType
) {
1135 case TDI_EVENT_CONNECT
:
1136 if (!Parameters
->EventHandler
) {
1137 AddrFile
->ConnectHandlerContext
= NULL
;
1138 AddrFile
->RegisteredConnectHandler
= FALSE
;
1140 AddrFile
->ConnectHandler
=
1141 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1142 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1143 AddrFile
->RegisteredConnectHandler
= TRUE
;
1147 case TDI_EVENT_DISCONNECT
:
1148 if (!Parameters
->EventHandler
) {
1149 AddrFile
->DisconnectHandlerContext
= NULL
;
1150 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1152 AddrFile
->DisconnectHandler
=
1153 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1154 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1155 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1159 case TDI_EVENT_ERROR
:
1160 if (Parameters
->EventHandler
== NULL
) {
1161 AddrFile
->ErrorHandlerContext
= NULL
;
1162 AddrFile
->RegisteredErrorHandler
= FALSE
;
1164 AddrFile
->ErrorHandler
=
1165 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1166 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1167 AddrFile
->RegisteredErrorHandler
= TRUE
;
1171 case TDI_EVENT_RECEIVE
:
1172 if (Parameters
->EventHandler
== NULL
) {
1173 AddrFile
->ReceiveHandlerContext
= NULL
;
1174 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1176 AddrFile
->ReceiveHandler
=
1177 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1178 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1179 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1183 case TDI_EVENT_RECEIVE_DATAGRAM
:
1184 if (Parameters
->EventHandler
== NULL
) {
1185 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1186 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1188 AddrFile
->ReceiveDatagramHandler
=
1189 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1190 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1191 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1195 case TDI_EVENT_RECEIVE_EXPEDITED
:
1196 if (Parameters
->EventHandler
== NULL
) {
1197 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1198 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1200 AddrFile
->ExpeditedReceiveHandler
=
1201 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1202 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1203 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1207 case TDI_EVENT_CHAINED_RECEIVE
:
1208 if (Parameters
->EventHandler
== NULL
) {
1209 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1210 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1212 AddrFile
->ChainedReceiveHandler
=
1213 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1214 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1215 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1219 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1220 if (Parameters
->EventHandler
== NULL
) {
1221 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1222 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1224 AddrFile
->ChainedReceiveDatagramHandler
=
1225 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1226 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1227 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1231 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1232 if (Parameters
->EventHandler
== NULL
) {
1233 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1234 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1236 AddrFile
->ChainedReceiveExpeditedHandler
=
1237 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1238 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1239 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1244 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1245 Parameters
->EventType
));
1247 Status
= STATUS_INVALID_PARAMETER
;
1250 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1256 NTSTATUS
DispTdiSetInformation(
1259 * FUNCTION: TDI_SET_INFORMATION handler
1261 * Irp = Pointer to an I/O request packet
1263 * Status of operation
1266 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1268 return STATUS_NOT_IMPLEMENTED
;
1272 VOID
DispTdiQueryInformationExComplete(
1277 * FUNCTION: Completes a TDI QueryInformationEx request
1279 * Context = Pointer to the IRP for the request
1280 * Status = TDI status of the request
1281 * ByteCount = Number of bytes returned in output buffer
1284 PTI_QUERY_CONTEXT QueryContext
;
1287 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1288 if (NT_SUCCESS(Status
)) {
1289 Count
= CopyBufferToBufferChain(
1290 QueryContext
->InputMdl
,
1291 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1292 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1296 MmUnlockPages(QueryContext
->InputMdl
);
1297 IoFreeMdl(QueryContext
->InputMdl
);
1298 if( QueryContext
->OutputMdl
) {
1299 MmUnlockPages(QueryContext
->OutputMdl
);
1300 IoFreeMdl(QueryContext
->OutputMdl
);
1303 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1304 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1306 exFreePool(QueryContext
);
1310 NTSTATUS
DispTdiQueryInformationEx(
1312 PIO_STACK_LOCATION IrpSp
)
1314 * FUNCTION: TDI QueryInformationEx handler
1316 * Irp = Pointer to I/O request packet
1317 * IrpSp = Pointer to current stack location of Irp
1319 * Status of operation
1322 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1323 PTRANSPORT_CONTEXT TranContext
;
1324 PTI_QUERY_CONTEXT QueryContext
;
1326 TDI_REQUEST Request
;
1328 UINT InputBufferLength
;
1329 UINT OutputBufferLength
;
1330 BOOLEAN InputMdlLocked
= FALSE
;
1331 BOOLEAN OutputMdlLocked
= FALSE
;
1332 PMDL InputMdl
= NULL
;
1333 PMDL OutputMdl
= NULL
;
1334 NTSTATUS Status
= STATUS_SUCCESS
;
1336 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1338 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1340 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
1341 case TDI_TRANSPORT_ADDRESS_FILE
:
1342 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1345 case TDI_CONNECTION_FILE
:
1346 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1349 case TDI_CONTROL_CHANNEL_FILE
:
1350 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1354 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1355 return STATUS_INVALID_PARAMETER
;
1358 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1359 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1361 /* Validate parameters */
1362 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1363 (OutputBufferLength
!= 0)) {
1365 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1366 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1367 OutputBuffer
= Irp
->UserBuffer
;
1369 QueryContext
= exAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1372 InputMdl
= IoAllocateMdl(InputBuffer
,
1373 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1376 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1377 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1379 if (InputMdl
&& OutputMdl
) {
1381 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1384 InputMdlLocked
= TRUE
;
1386 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1389 OutputMdlLocked
= TRUE
;
1391 RtlCopyMemory(&QueryContext
->QueryInfo
,
1392 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1394 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1395 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1396 Status
= _SEH2_GetExceptionCode();
1399 if (NT_SUCCESS(Status
)) {
1400 Size
= MmGetMdlByteCount(OutputMdl
);
1402 QueryContext
->Irp
= Irp
;
1403 QueryContext
->InputMdl
= InputMdl
;
1404 QueryContext
->OutputMdl
= OutputMdl
;
1406 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1407 Request
.RequestContext
= QueryContext
;
1408 Status
= InfoTdiQueryInformationEx(&Request
,
1409 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1410 &Size
, &QueryContext
->QueryInfo
.Context
);
1411 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1413 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1418 /* An error occurred if we get here */
1422 MmUnlockPages(InputMdl
);
1423 IoFreeMdl(InputMdl
);
1427 if (OutputMdlLocked
)
1428 MmUnlockPages(OutputMdl
);
1429 IoFreeMdl(OutputMdl
);
1432 exFreePool(QueryContext
);
1434 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1435 } else if( InputBufferLength
==
1436 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1437 /* Handle the case where the user is probing the buffer for length */
1438 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1439 InputBufferLength
, OutputBufferLength
));
1440 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1441 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1445 QueryContext
= exAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1446 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1449 InputMdl
= IoAllocateMdl(InputBuffer
,
1450 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1453 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1456 InputMdlLocked
= TRUE
;
1457 Status
= STATUS_SUCCESS
;
1458 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1459 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1460 Status
= _SEH2_GetExceptionCode();
1463 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1464 if( InputMdl
) IoFreeMdl( InputMdl
);
1465 exFreePool(QueryContext
);
1469 RtlCopyMemory(&QueryContext
->QueryInfo
,
1470 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1472 QueryContext
->Irp
= Irp
;
1473 QueryContext
->InputMdl
= InputMdl
;
1474 QueryContext
->OutputMdl
= NULL
;
1476 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1477 Request
.RequestContext
= QueryContext
;
1478 Status
= InfoTdiQueryInformationEx(&Request
,
1479 &QueryContext
->QueryInfo
.ID
,
1482 &QueryContext
->QueryInfo
.Context
);
1483 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1484 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1485 } else Status
= STATUS_INVALID_PARAMETER
;
1487 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1493 NTSTATUS
DispTdiSetInformationEx(
1495 PIO_STACK_LOCATION IrpSp
)
1497 * FUNCTION: TDI SetInformationEx handler
1499 * Irp = Pointer to I/O request packet
1500 * IrpSp = Pointer to current stack location of Irp
1502 * Status of operation
1505 PTRANSPORT_CONTEXT TranContext
;
1506 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1507 TDI_REQUEST Request
;
1510 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1512 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1513 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1515 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
1516 case TDI_TRANSPORT_ADDRESS_FILE
:
1517 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1520 case TDI_CONNECTION_FILE
:
1521 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1524 case TDI_CONTROL_CHANNEL_FILE
:
1525 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1529 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1530 Irp
->IoStatus
.Information
= 0;
1532 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1534 return Irp
->IoStatus
.Status
;
1537 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1538 if (NT_SUCCESS(Status
)) {
1539 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1540 Request
.RequestContext
= Irp
;
1542 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1543 &Info
->Buffer
, Info
->BufferSize
);
1549 /* TODO: Support multiple addresses per interface.
1550 * For now just set the nte context to the interface index.
1552 * Later on, create an NTE context and NTE instance
1555 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1556 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1557 PIP_SET_ADDRESS IpAddrChange
=
1558 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1561 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1562 IpAddrChange
->NteIndex
));
1564 ForEachInterface(IF
) {
1565 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1567 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1568 Status
= STATUS_DUPLICATE_OBJECTID
;
1571 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1572 IPRemoveInterfaceRoute( IF
);
1574 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1575 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1576 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1577 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1578 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1579 IF
->Broadcast
.Address
.IPv4Address
=
1580 IF
->Unicast
.Address
.IPv4Address
|
1581 ~IF
->Netmask
.Address
.IPv4Address
;
1583 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1584 IF
->Unicast
.Address
.IPv4Address
));
1585 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1586 IF
->Netmask
.Address
.IPv4Address
));
1588 IPAddInterfaceRoute( IF
);
1590 IpAddrChange
->Address
= IF
->Index
;
1591 Status
= STATUS_SUCCESS
;
1592 Irp
->IoStatus
.Information
= IF
->Index
;
1597 Irp
->IoStatus
.Status
= Status
;
1601 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1602 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1603 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1606 ForEachInterface(IF
) {
1607 if( IF
->Index
== *NteIndex
) {
1608 IPRemoveInterfaceRoute( IF
);
1609 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1610 IF
->Unicast
.Address
.IPv4Address
= 0;
1611 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1612 IF
->Netmask
.Address
.IPv4Address
= 0;
1613 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1614 IF
->Broadcast
.Address
.IPv4Address
= 0;
1615 Status
= STATUS_SUCCESS
;
1619 Irp
->IoStatus
.Status
= Status
;