2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: tcpip/dispatch.h
5 * PURPOSE: TDI dispatch routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/08-2000 Created
9 * TODO: Validate device object in all dispatch routines
13 #include <pseh/pseh.h>
15 NTSTATUS
DispPrepareIrpForCancel(
16 PTRANSPORT_CONTEXT Context
,
18 PDRIVER_CANCEL CancelRoutine
)
20 * FUNCTION: Prepare an IRP for cancellation
22 * Context = Pointer to context information
23 * Irp = Pointer to an I/O request packet
24 * CancelRoutine = Routine to be called when I/O request is cancelled
31 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
33 IoAcquireCancelSpinLock(&OldIrql
);
36 IoMarkIrpPending(Irp
);
37 (void)IoSetCancelRoutine(Irp
, CancelRoutine
);
38 IoReleaseCancelSpinLock(OldIrql
);
40 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
42 return STATUS_SUCCESS
;
45 /* IRP has already been cancelled */
47 IoReleaseCancelSpinLock(OldIrql
);
49 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
50 Irp
->IoStatus
.Information
= 0;
52 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
54 return IRPFinish(Irp
, STATUS_CANCELLED
);
57 VOID
DispDataRequestComplete(
62 * FUNCTION: Completes a send/receive IRP
64 * Context = Pointer to context information (IRP)
65 * Status = Status of the request
66 * Count = Number of bytes sent or received
70 PIO_STACK_LOCATION IrpSp
;
71 PTRANSPORT_CONTEXT TranContext
;
74 TI_DbgPrint(DEBUG_IRP
, ("Called for irp %x (%x, %d).\n",
75 Context
, Status
, Count
));
78 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
79 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
81 IoAcquireCancelSpinLock(&OldIrql
);
83 (void)IoSetCancelRoutine(Irp
, NULL
);
85 if (Irp
->Cancel
|| TranContext
->CancelIrps
) {
86 /* The IRP has been cancelled */
88 TI_DbgPrint(DEBUG_IRP
, ("IRP is cancelled.\n"));
90 Status
= STATUS_CANCELLED
;
94 IoReleaseCancelSpinLock(OldIrql
);
96 Irp
->IoStatus
.Status
= Status
;
97 Irp
->IoStatus
.Information
= Count
;
99 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
100 Irp
->IoStatus
.Status
));
101 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
102 Irp
->IoStatus
.Information
));
103 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
105 IRPFinish(Irp
, Irp
->IoStatus
.Status
);
107 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
110 typedef struct _DISCONNECT_TYPE
{
114 PFILE_OBJECT FileObject
;
115 } DISCONNECT_TYPE
, *PDISCONNECT_TYPE
;
117 VOID
DispDoDisconnect( PVOID Data
) {
118 PDISCONNECT_TYPE DisType
= (PDISCONNECT_TYPE
)Data
;
120 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect\n"));
126 DispDataRequestComplete
,
128 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect done\n"));
130 DispDataRequestComplete(DisType
->Irp
, STATUS_CANCELLED
, 0);
133 VOID
DispDoPacketCancel( PVOID Data
) {
134 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
135 PIRP
*IrpP
= (PIRP
*)Data
, Irp
= *IrpP
;
136 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
137 Irp
->IoStatus
.Information
= 0;
138 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
141 VOID NTAPI
DispCancelRequest(
142 PDEVICE_OBJECT Device
,
145 * FUNCTION: Cancels an IRP
147 * Device = Pointer to device object
148 * Irp = Pointer to an I/O request packet
151 PIO_STACK_LOCATION IrpSp
;
152 PTRANSPORT_CONTEXT TranContext
;
153 PFILE_OBJECT FileObject
;
155 DISCONNECT_TYPE DisType
;
157 PADDRESS_FILE AddrFile
;
158 /*NTSTATUS Status = STATUS_SUCCESS;*/
160 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
162 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
163 FileObject
= IrpSp
->FileObject
;
164 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
165 MinorFunction
= IrpSp
->MinorFunction
;
167 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
169 Irp
->IoStatus
.Status
= STATUS_PENDING
;
173 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
176 /* Try canceling the request */
177 switch(MinorFunction
) {
180 DisType
.Type
= TDI_DISCONNECT_RELEASE
|
181 ((MinorFunction
== TDI_RECEIVE
) ? TDI_DISCONNECT_ABORT
: 0);
182 DisType
.Context
= TranContext
->Handle
.ConnectionContext
;
184 DisType
.FileObject
= FileObject
;
186 TCPRemoveIRP( TranContext
->Handle
.ConnectionContext
, Irp
);
188 if( !ChewCreate( &WorkItem
, sizeof(DISCONNECT_TYPE
),
189 DispDoDisconnect
, &DisType
) )
193 case TDI_SEND_DATAGRAM
:
194 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
195 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
196 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
197 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
200 /* Nothing to do. We don't keep them around. */
203 case TDI_RECEIVE_DATAGRAM
:
204 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
205 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
206 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
207 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
210 DGRemoveIRP(AddrFile
, Irp
);
214 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
218 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
219 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
221 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
225 VOID NTAPI
DispCancelListenRequest(
226 PDEVICE_OBJECT Device
,
229 * FUNCTION: Cancels a listen IRP
231 * Device = Pointer to device object
232 * Irp = Pointer to an I/O request packet
235 PIO_STACK_LOCATION IrpSp
;
236 PTRANSPORT_CONTEXT TranContext
;
237 PFILE_OBJECT FileObject
;
238 PCONNECTION_ENDPOINT Connection
;
239 /*NTSTATUS Status = STATUS_SUCCESS;*/
241 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
243 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
244 FileObject
= IrpSp
->FileObject
;
245 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
246 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
248 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
252 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
255 /* Try canceling the request */
256 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
257 TCPAbortListenForSocket(
258 Connection
->AddressFile
->Listener
,
261 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
263 DispDataRequestComplete(Irp
, STATUS_CANCELLED
, 0);
264 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
268 NTSTATUS
DispTdiAccept(
271 * FUNCTION: TDI_ACCEPT handler
273 * Irp = Pointer to an I/O request packet
275 * Status of operation
278 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
280 return STATUS_NOT_IMPLEMENTED
;
284 NTSTATUS
DispTdiAssociateAddress(
287 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
289 * Irp = Pointer to an I/O request packet
291 * Status of operation
294 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
295 PTRANSPORT_CONTEXT TranContext
;
296 PIO_STACK_LOCATION IrpSp
;
297 PCONNECTION_ENDPOINT Connection
;
298 PFILE_OBJECT FileObject
;
299 PADDRESS_FILE AddrFile
= NULL
;
302 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
304 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
306 /* Get associated connection endpoint file object. Quit if none exists */
308 TranContext
= IrpSp
->FileObject
->FsContext
;
310 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
311 return STATUS_INVALID_PARAMETER
;
314 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
316 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
317 return STATUS_INVALID_PARAMETER
;
320 if (Connection
->AddressFile
) {
321 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
322 return STATUS_INVALID_PARAMETER
;
325 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
327 Status
= ObReferenceObjectByHandle(
328 Parameters
->AddressHandle
,
334 if (!NT_SUCCESS(Status
)) {
335 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
336 Parameters
->AddressHandle
, Status
));
337 return STATUS_INVALID_PARAMETER
;
340 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
341 ObDereferenceObject(FileObject
);
342 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
343 FileObject
->FsContext2
));
344 return STATUS_INVALID_PARAMETER
;
347 /* Get associated address file object. Quit if none exists */
349 TranContext
= FileObject
->FsContext
;
351 ObDereferenceObject(FileObject
);
352 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
353 return STATUS_INVALID_PARAMETER
;
356 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
358 ObDereferenceObject(FileObject
);
359 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
360 return STATUS_INVALID_PARAMETER
;
363 Connection
->AddressFile
= AddrFile
;
365 /* Add connection endpoint to the address file */
366 AddrFile
->Connection
= Connection
;
368 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
369 ObDereferenceObject(FileObject
);
375 NTSTATUS
DispTdiConnect(
378 * FUNCTION: TDI_CONNECT handler
380 * Irp = Pointer to an I/O request packet
382 * Status of operation
385 PCONNECTION_ENDPOINT Connection
;
386 PTDI_REQUEST_KERNEL Parameters
;
387 PTRANSPORT_CONTEXT TranContext
;
388 PIO_STACK_LOCATION IrpSp
;
391 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
393 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
395 /* Get associated connection endpoint file object. Quit if none exists */
397 TranContext
= IrpSp
->FileObject
->FsContext
;
399 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
400 return STATUS_INVALID_CONNECTION
;
403 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
405 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
406 return STATUS_INVALID_CONNECTION
;
409 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
412 TranContext
->Handle
.ConnectionContext
,
413 Parameters
->RequestConnectionInformation
,
414 Parameters
->ReturnConnectionInformation
,
415 DispDataRequestComplete
,
418 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
424 NTSTATUS
DispTdiDisassociateAddress(
427 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
429 * Irp = Pointer to an I/O request packet
431 * Status of operation
434 PCONNECTION_ENDPOINT Connection
;
435 PTRANSPORT_CONTEXT TranContext
;
436 PIO_STACK_LOCATION IrpSp
;
438 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
440 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
442 /* Get associated connection endpoint file object. Quit if none exists */
444 TranContext
= IrpSp
->FileObject
->FsContext
;
446 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
447 return STATUS_INVALID_PARAMETER
;
450 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
452 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
453 return STATUS_INVALID_PARAMETER
;
456 if (!Connection
->AddressFile
) {
457 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
458 return STATUS_INVALID_PARAMETER
;
461 return STATUS_SUCCESS
;
465 NTSTATUS
DispTdiDisconnect(
468 * FUNCTION: TDI_DISCONNECT handler
470 * Irp = Pointer to an I/O request packet
472 * Status of operation
476 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
477 PCONNECTION_ENDPOINT Connection
;
478 PTRANSPORT_CONTEXT TranContext
;
479 PIO_STACK_LOCATION IrpSp
;
481 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
483 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
484 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
486 /* Get associated connection endpoint file object. Quit if none exists */
488 TranContext
= IrpSp
->FileObject
->FsContext
;
490 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
491 return STATUS_INVALID_CONNECTION
;
494 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
496 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
497 return STATUS_INVALID_CONNECTION
;
500 Status
= TCPDisconnect(
501 TranContext
->Handle
.ConnectionContext
,
502 DisReq
->RequestFlags
,
503 DisReq
->RequestConnectionInformation
,
504 DisReq
->ReturnConnectionInformation
,
505 DispDataRequestComplete
,
508 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
514 NTSTATUS
DispTdiListen(
517 * FUNCTION: TDI_LISTEN handler
519 * Irp = Pointer to an I/O request packet
521 * Status of operation
524 PCONNECTION_ENDPOINT Connection
;
525 PTDI_REQUEST_KERNEL Parameters
;
526 PTRANSPORT_CONTEXT TranContext
;
527 PIO_STACK_LOCATION IrpSp
;
528 NTSTATUS Status
= STATUS_SUCCESS
;
530 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
532 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
534 /* Get associated connection endpoint file object. Quit if none exists */
536 TranContext
= IrpSp
->FileObject
->FsContext
;
537 if (TranContext
== NULL
)
539 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
540 return STATUS_INVALID_CONNECTION
;
543 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
544 if (Connection
== NULL
)
546 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
547 return STATUS_INVALID_CONNECTION
;
550 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
552 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile: %x\n",
553 Connection
->AddressFile
));
554 if( Connection
->AddressFile
) {
555 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile->Listener: %x\n",
556 Connection
->AddressFile
->Listener
));
559 /* Listening will require us to create a listening socket and store it in
560 * the address file. It will be signalled, and attempt to complete an irp
561 * when a new connection arrives. */
562 /* The important thing to note here is that the irp we'll complete belongs
563 * to the socket to be accepted onto, not the listener */
564 if( !Connection
->AddressFile
->Listener
) {
565 Connection
->AddressFile
->Listener
=
566 TCPAllocateConnectionEndpoint( NULL
);
568 if( !Connection
->AddressFile
->Listener
)
569 Status
= STATUS_NO_MEMORY
;
571 if( NT_SUCCESS(Status
) ) {
572 Connection
->AddressFile
->Listener
->AddressFile
=
573 Connection
->AddressFile
;
575 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
576 Connection
->AddressFile
->Family
,
578 Connection
->AddressFile
->Protocol
);
581 if( NT_SUCCESS(Status
) )
582 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
585 if( NT_SUCCESS(Status
) ) {
586 Status
= DispPrepareIrpForCancel
587 (TranContext
->Handle
.ConnectionContext
,
589 (PDRIVER_CANCEL
)DispCancelListenRequest
);
592 if( NT_SUCCESS(Status
) ) {
594 ( (PTDI_REQUEST
)Parameters
,
595 Connection
->AddressFile
->Listener
,
597 DispDataRequestComplete
,
601 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
607 NTSTATUS
DispTdiQueryInformation(
608 PDEVICE_OBJECT DeviceObject
,
611 * FUNCTION: TDI_QUERY_INFORMATION handler
613 * DeviceObject = Pointer to device object structure
614 * Irp = Pointer to an I/O request packet
616 * Status of operation
619 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
620 PTRANSPORT_CONTEXT TranContext
;
621 PIO_STACK_LOCATION IrpSp
;
623 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
625 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
626 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
628 TranContext
= IrpSp
->FileObject
->FsContext
;
630 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
631 return STATUS_INVALID_CONNECTION
;
634 switch (Parameters
->QueryType
)
636 case TDI_QUERY_ADDRESS_INFO
:
638 PTDI_ADDRESS_INFO AddressInfo
;
639 PADDRESS_FILE AddrFile
;
640 PTA_IP_ADDRESS Address
;
642 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
644 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
645 case TDI_TRANSPORT_ADDRESS_FILE
:
646 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
649 case TDI_CONNECTION_FILE
:
651 ((PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
)->
656 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
657 return STATUS_INVALID_PARAMETER
;
661 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
662 return STATUS_INVALID_PARAMETER
;
665 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
666 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
667 sizeof(TDI_ADDRESS_IP
))) {
668 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
669 return STATUS_BUFFER_OVERFLOW
;
672 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
673 Address
->TAAddressCount
= 1;
674 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
675 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
676 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
677 Address
->Address
[0].Address
[0].in_addr
=
678 AddrFile
->Address
.Address
.IPv4Address
;
680 &Address
->Address
[0].Address
[0].sin_zero
,
681 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
683 return STATUS_SUCCESS
;
686 case TDI_QUERY_CONNECTION_INFO
:
688 PTDI_CONNECTION_INFORMATION AddressInfo
;
689 PADDRESS_FILE AddrFile
;
690 PCONNECTION_ENDPOINT Endpoint
= NULL
;
692 AddressInfo
= (PTDI_CONNECTION_INFORMATION
)
693 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
695 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
696 case TDI_TRANSPORT_ADDRESS_FILE
:
697 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
700 case TDI_CONNECTION_FILE
:
702 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
706 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
707 return STATUS_INVALID_PARAMETER
;
711 TI_DbgPrint(MID_TRACE
, ("No connection object.\n"));
712 return STATUS_INVALID_PARAMETER
;
715 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
716 (FIELD_OFFSET(TDI_CONNECTION_INFORMATION
, RemoteAddress
) +
718 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small (ptr).\n"));
719 return STATUS_BUFFER_OVERFLOW
;
722 return TCPGetPeerAddress( Endpoint
, AddressInfo
->RemoteAddress
);
726 return STATUS_NOT_IMPLEMENTED
;
730 NTSTATUS
DispTdiReceive(
733 * FUNCTION: TDI_RECEIVE handler
735 * Irp = Pointer to an I/O request packet
737 * Status of operation
740 PIO_STACK_LOCATION IrpSp
;
741 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
742 PTRANSPORT_CONTEXT TranContext
;
746 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
748 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
749 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
751 TranContext
= IrpSp
->FileObject
->FsContext
;
752 if (TranContext
== NULL
)
754 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
755 return STATUS_INVALID_CONNECTION
;
758 if (TranContext
->Handle
.ConnectionContext
== NULL
)
760 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
761 return STATUS_INVALID_CONNECTION
;
764 /* Initialize a receive request */
765 Status
= DispPrepareIrpForCancel
766 (TranContext
->Handle
.ConnectionContext
,
768 (PDRIVER_CANCEL
)DispCancelRequest
);
770 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
771 if (NT_SUCCESS(Status
))
773 /* Lock here so we're sure we've got the following 'mark pending' */
774 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
776 Status
= TCPReceiveData(
777 TranContext
->Handle
.ConnectionContext
,
778 (PNDIS_BUFFER
)Irp
->MdlAddress
,
779 ReceiveInfo
->ReceiveLength
,
781 ReceiveInfo
->ReceiveFlags
,
782 DispDataRequestComplete
,
784 if (Status
!= STATUS_PENDING
)
786 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
788 IoMarkIrpPending(Irp
);
791 TcpipRecursiveMutexLeave( &TCPLock
);
794 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
799 NTSTATUS
DispTdiReceiveDatagram(
802 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
804 * Irp = Pointer to an I/O request packet
806 * Status of operation
809 PIO_STACK_LOCATION IrpSp
;
810 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
811 PTRANSPORT_CONTEXT TranContext
;
815 PADDRESS_FILE AddrFile
;
817 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
819 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
820 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
822 TranContext
= IrpSp
->FileObject
->FsContext
;
823 if (TranContext
== NULL
)
825 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
826 return STATUS_INVALID_ADDRESS
;
829 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
831 /* Initialize a receive request */
832 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
833 Request
.RequestNotifyObject
= DispDataRequestComplete
;
834 Request
.RequestContext
= Irp
;
836 Status
= DispPrepareIrpForCancel(
837 IrpSp
->FileObject
->FsContext
,
839 (PDRIVER_CANCEL
)DispCancelRequest
);
841 if (NT_SUCCESS(Status
))
846 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
850 Status
= DGReceiveDatagram(
852 DgramInfo
->ReceiveDatagramInformation
,
854 DgramInfo
->ReceiveLength
,
855 DgramInfo
->ReceiveFlags
,
856 DgramInfo
->ReturnDatagramInformation
,
858 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
861 if (Status
!= STATUS_PENDING
) {
862 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
864 IoMarkIrpPending(Irp
);
867 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
873 NTSTATUS
DispTdiSend(
876 * FUNCTION: TDI_SEND handler
878 * Irp = Pointer to an I/O request packet
880 * Status of operation
883 PIO_STACK_LOCATION IrpSp
;
884 PTDI_REQUEST_KERNEL_SEND SendInfo
;
885 PTRANSPORT_CONTEXT TranContext
;
889 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
891 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
892 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
894 TranContext
= IrpSp
->FileObject
->FsContext
;
895 if (TranContext
== NULL
)
897 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
898 return STATUS_INVALID_CONNECTION
;
901 if (TranContext
->Handle
.ConnectionContext
== NULL
)
903 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
904 return STATUS_INVALID_CONNECTION
;
907 Status
= DispPrepareIrpForCancel(
908 IrpSp
->FileObject
->FsContext
,
910 (PDRIVER_CANCEL
)DispCancelRequest
);
912 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
913 if (NT_SUCCESS(Status
))
918 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
920 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
921 Status
= TCPSendData(
922 TranContext
->Handle
.ConnectionContext
,
924 SendInfo
->SendLength
,
927 DispDataRequestComplete
,
929 if (Status
!= STATUS_PENDING
)
931 DispDataRequestComplete(Irp
, Status
, BytesSent
);
933 IoMarkIrpPending( Irp
);
936 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
942 NTSTATUS
DispTdiSendDatagram(
945 * FUNCTION: TDI_SEND_DATAGRAM handler
947 * Irp = Pointer to an I/O request packet
949 * Status of operation
952 PIO_STACK_LOCATION IrpSp
;
954 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
955 PTRANSPORT_CONTEXT TranContext
;
958 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
960 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
961 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
962 TranContext
= IrpSp
->FileObject
->FsContext
;
964 /* Initialize a send request */
965 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
966 Request
.RequestNotifyObject
= DispDataRequestComplete
;
967 Request
.RequestContext
= Irp
;
969 Status
= DispPrepareIrpForCancel(
970 IrpSp
->FileObject
->FsContext
,
972 (PDRIVER_CANCEL
)DispCancelRequest
);
974 if (NT_SUCCESS(Status
)) {
978 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
980 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
984 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
985 must be of type PTDI_ADDRESS_IP */
986 TI_DbgPrint(MID_TRACE
,
987 ("About to call send routine %x\n",
988 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
990 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
) )
991 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
992 Request
.Handle
.AddressHandle
,
993 DgramInfo
->SendDatagramInformation
,
996 &Irp
->IoStatus
.Information
);
998 Status
= STATUS_UNSUCCESSFUL
;
1000 if (Status
!= STATUS_PENDING
) {
1001 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
1002 /* Return STATUS_PENDING because DispPrepareIrpForCancel
1003 marks Irp as pending */
1004 Status
= STATUS_PENDING
;
1006 IoMarkIrpPending( Irp
);
1009 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
1015 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
1017 * FUNCTION: TDI_SET_EVENT_HANDER handler
1019 * Irp = Pointer to a I/O request packet
1021 * Status of operation
1024 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1025 PTRANSPORT_CONTEXT TranContext
;
1026 PIO_STACK_LOCATION IrpSp
;
1027 PADDRESS_FILE AddrFile
;
1031 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1033 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1035 /* Get associated address file object. Quit if none exists */
1037 TranContext
= IrpSp
->FileObject
->FsContext
;
1039 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1040 return STATUS_INVALID_PARAMETER
;
1043 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1045 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1046 return STATUS_INVALID_PARAMETER
;
1049 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1050 Status
= STATUS_SUCCESS
;
1052 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
1054 /* Set the event handler. if an event handler is associated with
1055 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1056 If an event handler is not used it's flag is FALSE */
1057 switch (Parameters
->EventType
) {
1058 case TDI_EVENT_CONNECT
:
1059 if (!Parameters
->EventHandler
) {
1060 AddrFile
->ConnectHandlerContext
= NULL
;
1061 AddrFile
->RegisteredConnectHandler
= FALSE
;
1063 AddrFile
->ConnectHandler
=
1064 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1065 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1066 AddrFile
->RegisteredConnectHandler
= TRUE
;
1070 case TDI_EVENT_DISCONNECT
:
1071 if (!Parameters
->EventHandler
) {
1072 AddrFile
->DisconnectHandlerContext
= NULL
;
1073 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1075 AddrFile
->DisconnectHandler
=
1076 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1077 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1078 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1082 case TDI_EVENT_ERROR
:
1083 if (Parameters
->EventHandler
== NULL
) {
1084 AddrFile
->ErrorHandlerContext
= NULL
;
1085 AddrFile
->RegisteredErrorHandler
= FALSE
;
1087 AddrFile
->ErrorHandler
=
1088 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1089 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1090 AddrFile
->RegisteredErrorHandler
= TRUE
;
1094 case TDI_EVENT_RECEIVE
:
1095 if (Parameters
->EventHandler
== NULL
) {
1096 AddrFile
->ReceiveHandlerContext
= NULL
;
1097 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1099 AddrFile
->ReceiveHandler
=
1100 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1101 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1102 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1106 case TDI_EVENT_RECEIVE_DATAGRAM
:
1107 if (Parameters
->EventHandler
== NULL
) {
1108 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1109 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1111 AddrFile
->ReceiveDatagramHandler
=
1112 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1113 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1114 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1118 case TDI_EVENT_RECEIVE_EXPEDITED
:
1119 if (Parameters
->EventHandler
== NULL
) {
1120 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1121 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1123 AddrFile
->ExpeditedReceiveHandler
=
1124 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1125 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1126 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1130 case TDI_EVENT_CHAINED_RECEIVE
:
1131 if (Parameters
->EventHandler
== NULL
) {
1132 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1133 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1135 AddrFile
->ChainedReceiveHandler
=
1136 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1137 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1138 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1142 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1143 if (Parameters
->EventHandler
== NULL
) {
1144 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1145 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1147 AddrFile
->ChainedReceiveDatagramHandler
=
1148 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1149 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1150 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1154 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1155 if (Parameters
->EventHandler
== NULL
) {
1156 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1157 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1159 AddrFile
->ChainedReceiveExpeditedHandler
=
1160 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1161 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1162 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1167 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1168 Parameters
->EventType
));
1170 Status
= STATUS_INVALID_PARAMETER
;
1173 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1179 NTSTATUS
DispTdiSetInformation(
1182 * FUNCTION: TDI_SET_INFORMATION handler
1184 * Irp = Pointer to an I/O request packet
1186 * Status of operation
1189 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1191 return STATUS_NOT_IMPLEMENTED
;
1195 VOID
DispTdiQueryInformationExComplete(
1200 * FUNCTION: Completes a TDI QueryInformationEx request
1202 * Context = Pointer to the IRP for the request
1203 * Status = TDI status of the request
1204 * ByteCount = Number of bytes returned in output buffer
1207 PTI_QUERY_CONTEXT QueryContext
;
1210 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1211 if (NT_SUCCESS(Status
)) {
1212 Count
= CopyBufferToBufferChain(
1213 QueryContext
->InputMdl
,
1214 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1215 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1219 MmUnlockPages(QueryContext
->InputMdl
);
1220 IoFreeMdl(QueryContext
->InputMdl
);
1221 if( QueryContext
->OutputMdl
) {
1222 MmUnlockPages(QueryContext
->OutputMdl
);
1223 IoFreeMdl(QueryContext
->OutputMdl
);
1226 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1227 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1229 ExFreePool(QueryContext
);
1233 NTSTATUS
DispTdiQueryInformationEx(
1235 PIO_STACK_LOCATION IrpSp
)
1237 * FUNCTION: TDI QueryInformationEx handler
1239 * Irp = Pointer to I/O request packet
1240 * IrpSp = Pointer to current stack location of Irp
1242 * Status of operation
1245 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1246 PTRANSPORT_CONTEXT TranContext
;
1247 PTI_QUERY_CONTEXT QueryContext
;
1249 TDI_REQUEST Request
;
1251 UINT InputBufferLength
;
1252 UINT OutputBufferLength
;
1253 BOOLEAN InputMdlLocked
= FALSE
;
1254 BOOLEAN OutputMdlLocked
= FALSE
;
1255 PMDL InputMdl
= NULL
;
1256 PMDL OutputMdl
= NULL
;
1257 NTSTATUS Status
= STATUS_SUCCESS
;
1259 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1261 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1263 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1264 case TDI_TRANSPORT_ADDRESS_FILE
:
1265 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1268 case TDI_CONNECTION_FILE
:
1269 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1272 case TDI_CONTROL_CHANNEL_FILE
:
1273 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1277 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1278 return STATUS_INVALID_PARAMETER
;
1281 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1282 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1284 /* Validate parameters */
1285 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1286 (OutputBufferLength
!= 0)) {
1288 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1289 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1290 OutputBuffer
= Irp
->UserBuffer
;
1292 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1295 InputMdl
= IoAllocateMdl(InputBuffer
,
1296 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1299 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1300 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1302 if (InputMdl
&& OutputMdl
) {
1304 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1307 InputMdlLocked
= TRUE
;
1309 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1312 OutputMdlLocked
= TRUE
;
1314 RtlCopyMemory(&QueryContext
->QueryInfo
,
1315 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1317 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1319 Status
= _SEH_GetExceptionCode();
1322 if (NT_SUCCESS(Status
)) {
1323 Size
= MmGetMdlByteCount(OutputMdl
);
1325 QueryContext
->Irp
= Irp
;
1326 QueryContext
->InputMdl
= InputMdl
;
1327 QueryContext
->OutputMdl
= OutputMdl
;
1329 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1330 Request
.RequestContext
= QueryContext
;
1331 Status
= InfoTdiQueryInformationEx(&Request
,
1332 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1333 &Size
, &QueryContext
->QueryInfo
.Context
);
1334 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1336 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1341 /* An error occurred if we get here */
1345 MmUnlockPages(InputMdl
);
1346 IoFreeMdl(InputMdl
);
1350 if (OutputMdlLocked
)
1351 MmUnlockPages(OutputMdl
);
1352 IoFreeMdl(OutputMdl
);
1355 ExFreePool(QueryContext
);
1357 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1358 } else if( InputBufferLength
==
1359 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1360 /* Handle the case where the user is probing the buffer for length */
1361 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1362 InputBufferLength
, OutputBufferLength
));
1363 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1364 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1368 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1369 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1372 InputMdl
= IoAllocateMdl(InputBuffer
,
1373 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1376 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1379 InputMdlLocked
= TRUE
;
1380 Status
= STATUS_SUCCESS
;
1382 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1383 Status
= _SEH_GetExceptionCode();
1386 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1387 if( InputMdl
) IoFreeMdl( InputMdl
);
1388 ExFreePool(QueryContext
);
1392 RtlCopyMemory(&QueryContext
->QueryInfo
,
1393 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1395 QueryContext
->Irp
= Irp
;
1396 QueryContext
->InputMdl
= InputMdl
;
1397 QueryContext
->OutputMdl
= NULL
;
1399 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1400 Request
.RequestContext
= QueryContext
;
1401 Status
= InfoTdiQueryInformationEx(&Request
,
1402 &QueryContext
->QueryInfo
.ID
,
1405 &QueryContext
->QueryInfo
.Context
);
1406 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1407 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1408 } else Status
= STATUS_INVALID_PARAMETER
;
1410 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1416 NTSTATUS
DispTdiSetInformationEx(
1418 PIO_STACK_LOCATION IrpSp
)
1420 * FUNCTION: TDI SetInformationEx handler
1422 * Irp = Pointer to I/O request packet
1423 * IrpSp = Pointer to current stack location of Irp
1425 * Status of operation
1428 PTRANSPORT_CONTEXT TranContext
;
1429 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1430 TDI_REQUEST Request
;
1434 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1436 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1437 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1439 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1440 case TDI_TRANSPORT_ADDRESS_FILE
:
1441 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1444 case TDI_CONNECTION_FILE
:
1445 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1448 case TDI_CONTROL_CHANNEL_FILE
:
1449 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1453 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1454 Irp
->IoStatus
.Information
= 0;
1456 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1458 return IRPFinish(Irp
, STATUS_INVALID_PARAMETER
);
1461 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1462 if (NT_SUCCESS(Status
)) {
1463 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1464 Request
.RequestContext
= Irp
;
1466 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1467 &Info
->Buffer
, Info
->BufferSize
);
1469 if (Status
!= STATUS_PENDING
) {
1470 IoAcquireCancelSpinLock(&OldIrql
);
1471 (void)IoSetCancelRoutine(Irp
, NULL
);
1472 IoReleaseCancelSpinLock(OldIrql
);
1479 /* TODO: Support multiple addresses per interface.
1480 * For now just set the nte context to the interface index.
1482 * Later on, create an NTE context and NTE instance
1485 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1486 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1487 PIP_SET_ADDRESS IpAddrChange
=
1488 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1491 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1492 IpAddrChange
->NteIndex
));
1494 ForEachInterface(IF
) {
1495 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1497 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1498 Status
= STATUS_DUPLICATE_OBJECTID
;
1501 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1502 IPRemoveInterfaceRoute( IF
);
1504 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1505 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1506 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1507 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1508 IF
->Broadcast
.Address
.IPv4Address
=
1509 IF
->Unicast
.Address
.IPv4Address
|
1510 ~IF
->Netmask
.Address
.IPv4Address
;
1512 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1513 IF
->Unicast
.Address
.IPv4Address
));
1514 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1515 IF
->Netmask
.Address
.IPv4Address
));
1517 IPAddInterfaceRoute( IF
);
1519 IpAddrChange
->Address
= IF
->Index
;
1520 Status
= STATUS_SUCCESS
;
1521 Irp
->IoStatus
.Information
= IF
->Index
;
1526 Irp
->IoStatus
.Status
= Status
;
1530 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1531 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1532 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1535 ForEachInterface(IF
) {
1536 if( IF
->Index
== *NteIndex
) {
1537 IPRemoveInterfaceRoute( IF
);
1538 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1539 IF
->Unicast
.Address
.IPv4Address
= 0;
1540 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1541 IF
->Netmask
.Address
.IPv4Address
= 0;
1542 Status
= STATUS_SUCCESS
;
1546 Irp
->IoStatus
.Status
= Status
;