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
);
58 VOID
DispCancelComplete(
61 * FUNCTION: Completes a cancel request
63 * Context = Pointer to context information (FILE_OBJECT)
67 PFILE_OBJECT FileObject
;
68 PTRANSPORT_CONTEXT TranContext
;
70 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
72 FileObject
= (PFILE_OBJECT
)Context
;
73 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
75 /* Set the cleanup event */
76 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
78 /* We are expected to release the cancel spin lock */
79 /*IoReleaseCancelSpinLock(OldIrql);*/
81 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
85 VOID
DispDataRequestComplete(
90 * FUNCTION: Completes a send/receive IRP
92 * Context = Pointer to context information (IRP)
93 * Status = Status of the request
94 * Count = Number of bytes sent or received
98 PIO_STACK_LOCATION IrpSp
;
99 PTRANSPORT_CONTEXT TranContext
;
102 TI_DbgPrint(DEBUG_IRP
, ("Called for irp %x (%x, %d).\n",
103 Context
, Status
, Count
));
106 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
107 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
109 IoAcquireCancelSpinLock(&OldIrql
);
111 (void)IoSetCancelRoutine(Irp
, NULL
);
113 if (Irp
->Cancel
|| TranContext
->CancelIrps
) {
114 /* The IRP has been cancelled */
116 TI_DbgPrint(DEBUG_IRP
, ("IRP is cancelled.\n"));
118 Status
= STATUS_CANCELLED
;
122 IoReleaseCancelSpinLock(OldIrql
);
124 Irp
->IoStatus
.Status
= Status
;
125 Irp
->IoStatus
.Information
= Count
;
127 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
128 Irp
->IoStatus
.Status
));
129 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
130 Irp
->IoStatus
.Information
));
131 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
133 IRPFinish(Irp
, Irp
->IoStatus
.Status
);
135 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
138 typedef struct _DISCONNECT_TYPE
{
142 PFILE_OBJECT FileObject
;
143 } DISCONNECT_TYPE
, *PDISCONNECT_TYPE
;
145 VOID
DispDoDisconnect( PVOID Data
) {
146 PDISCONNECT_TYPE DisType
= (PDISCONNECT_TYPE
)Data
;
148 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect\n"));
154 DispDataRequestComplete
,
156 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect done\n"));
158 DispDataRequestComplete(DisType
->Irp
, STATUS_CANCELLED
, 0);
160 DispCancelComplete(DisType
->FileObject
);
163 VOID NTAPI
DispCancelRequest(
164 PDEVICE_OBJECT Device
,
167 * FUNCTION: Cancels an IRP
169 * Device = Pointer to device object
170 * Irp = Pointer to an I/O request packet
173 PIO_STACK_LOCATION IrpSp
;
174 PTRANSPORT_CONTEXT TranContext
;
175 PFILE_OBJECT FileObject
;
177 DISCONNECT_TYPE DisType
;
179 /*NTSTATUS Status = STATUS_SUCCESS;*/
181 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
183 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
184 FileObject
= IrpSp
->FileObject
;
185 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
186 MinorFunction
= IrpSp
->MinorFunction
;
188 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
190 Irp
->IoStatus
.Status
= STATUS_PENDING
;
194 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
197 /* Try canceling the request */
198 switch(MinorFunction
) {
201 DisType
.Type
= TDI_DISCONNECT_RELEASE
|
202 ((MinorFunction
== TDI_RECEIVE
) ? TDI_DISCONNECT_ABORT
: 0);
203 DisType
.Context
= TranContext
->Handle
.ConnectionContext
;
205 DisType
.FileObject
= FileObject
;
207 TCPRemoveIRP( TranContext
->Handle
.ConnectionContext
, Irp
);
209 if( !ChewCreate( &WorkItem
, sizeof(DISCONNECT_TYPE
),
210 DispDoDisconnect
, &DisType
) )
214 case TDI_SEND_DATAGRAM
:
215 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
216 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
217 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
221 /*DGCancelSendRequest(TranContext->Handle.AddressHandle, Irp);*/
224 case TDI_RECEIVE_DATAGRAM
:
225 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
226 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
227 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
231 /*DGCancelReceiveRequest(TranContext->Handle.AddressHandle, Irp);*/
235 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
239 if( Irp
->IoStatus
.Status
== STATUS_PENDING
)
240 IoMarkIrpPending(Irp
);
242 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
244 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
248 VOID NTAPI
DispCancelListenRequest(
249 PDEVICE_OBJECT Device
,
252 * FUNCTION: Cancels a listen IRP
254 * Device = Pointer to device object
255 * Irp = Pointer to an I/O request packet
258 PIO_STACK_LOCATION IrpSp
;
259 PTRANSPORT_CONTEXT TranContext
;
260 PFILE_OBJECT FileObject
;
261 PCONNECTION_ENDPOINT Connection
;
262 /*NTSTATUS Status = STATUS_SUCCESS;*/
264 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
266 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
267 FileObject
= IrpSp
->FileObject
;
268 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
269 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
271 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
275 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
278 /* Try canceling the request */
279 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
280 TCPAbortListenForSocket(
281 Connection
->AddressFile
->Listener
,
284 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
286 DispDataRequestComplete(Irp
, STATUS_CANCELLED
, 0);
288 DispCancelComplete(FileObject
);
290 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
294 NTSTATUS
DispTdiAccept(
297 * FUNCTION: TDI_ACCEPT handler
299 * Irp = Pointer to an I/O request packet
301 * Status of operation
304 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
306 return STATUS_NOT_IMPLEMENTED
;
310 NTSTATUS
DispTdiAssociateAddress(
313 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
315 * Irp = Pointer to an I/O request packet
317 * Status of operation
320 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
321 PTRANSPORT_CONTEXT TranContext
;
322 PIO_STACK_LOCATION IrpSp
;
323 PCONNECTION_ENDPOINT Connection
;
324 PFILE_OBJECT FileObject
;
325 PADDRESS_FILE AddrFile
= NULL
;
328 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
330 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
332 /* Get associated connection endpoint file object. Quit if none exists */
334 TranContext
= IrpSp
->FileObject
->FsContext
;
336 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
337 return STATUS_INVALID_PARAMETER
;
340 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
342 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
343 return STATUS_INVALID_PARAMETER
;
346 if (Connection
->AddressFile
) {
347 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
348 return STATUS_INVALID_PARAMETER
;
351 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
353 Status
= ObReferenceObjectByHandle(
354 Parameters
->AddressHandle
,
360 if (!NT_SUCCESS(Status
)) {
361 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
362 Parameters
->AddressHandle
, Status
));
363 return STATUS_INVALID_PARAMETER
;
366 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
367 ObDereferenceObject(FileObject
);
368 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
369 FileObject
->FsContext2
));
370 return STATUS_INVALID_PARAMETER
;
373 /* Get associated address file object. Quit if none exists */
375 TranContext
= FileObject
->FsContext
;
377 ObDereferenceObject(FileObject
);
378 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
379 return STATUS_INVALID_PARAMETER
;
382 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
384 ObDereferenceObject(FileObject
);
385 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
386 return STATUS_INVALID_PARAMETER
;
389 Connection
->AddressFile
= AddrFile
;
391 /* Add connection endpoint to the address file */
392 AddrFile
->Connection
= Connection
;
394 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
395 ObDereferenceObject(FileObject
);
401 NTSTATUS
DispTdiConnect(
404 * FUNCTION: TDI_CONNECT handler
406 * Irp = Pointer to an I/O request packet
408 * Status of operation
411 PCONNECTION_ENDPOINT Connection
;
412 PTDI_REQUEST_KERNEL Parameters
;
413 PTRANSPORT_CONTEXT TranContext
;
414 PIO_STACK_LOCATION IrpSp
;
417 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
419 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
421 /* Get associated connection endpoint file object. Quit if none exists */
423 TranContext
= IrpSp
->FileObject
->FsContext
;
425 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
426 return STATUS_INVALID_CONNECTION
;
429 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
431 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
432 return STATUS_INVALID_CONNECTION
;
435 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
438 TranContext
->Handle
.ConnectionContext
,
439 Parameters
->RequestConnectionInformation
,
440 Parameters
->ReturnConnectionInformation
,
441 DispDataRequestComplete
,
444 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
450 NTSTATUS
DispTdiDisassociateAddress(
453 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
455 * Irp = Pointer to an I/O request packet
457 * Status of operation
460 PCONNECTION_ENDPOINT Connection
;
461 PTRANSPORT_CONTEXT TranContext
;
462 PIO_STACK_LOCATION IrpSp
;
464 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
466 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
468 /* Get associated connection endpoint file object. Quit if none exists */
470 TranContext
= IrpSp
->FileObject
->FsContext
;
472 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
473 return STATUS_INVALID_PARAMETER
;
476 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
478 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
479 return STATUS_INVALID_PARAMETER
;
482 if (!Connection
->AddressFile
) {
483 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
484 return STATUS_INVALID_PARAMETER
;
487 return STATUS_SUCCESS
;
491 NTSTATUS
DispTdiDisconnect(
494 * FUNCTION: TDI_DISCONNECT handler
496 * Irp = Pointer to an I/O request packet
498 * Status of operation
502 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
503 PCONNECTION_ENDPOINT Connection
;
504 PTRANSPORT_CONTEXT TranContext
;
505 PIO_STACK_LOCATION IrpSp
;
507 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
509 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
510 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
512 /* Get associated connection endpoint file object. Quit if none exists */
514 TranContext
= IrpSp
->FileObject
->FsContext
;
516 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
517 return STATUS_INVALID_CONNECTION
;
520 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
522 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
523 return STATUS_INVALID_CONNECTION
;
526 Status
= TCPDisconnect(
527 TranContext
->Handle
.ConnectionContext
,
528 DisReq
->RequestFlags
,
529 DisReq
->RequestConnectionInformation
,
530 DisReq
->ReturnConnectionInformation
,
531 DispDataRequestComplete
,
534 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
540 NTSTATUS
DispTdiListen(
543 * FUNCTION: TDI_LISTEN handler
545 * Irp = Pointer to an I/O request packet
547 * Status of operation
550 PCONNECTION_ENDPOINT Connection
;
551 PTDI_REQUEST_KERNEL Parameters
;
552 PTRANSPORT_CONTEXT TranContext
;
553 PIO_STACK_LOCATION IrpSp
;
554 NTSTATUS Status
= STATUS_SUCCESS
;
556 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
558 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
560 /* Get associated connection endpoint file object. Quit if none exists */
562 TranContext
= IrpSp
->FileObject
->FsContext
;
563 if (TranContext
== NULL
)
565 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
566 return STATUS_INVALID_CONNECTION
;
569 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
570 if (Connection
== NULL
)
572 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
573 return STATUS_INVALID_CONNECTION
;
576 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
578 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile: %x\n",
579 Connection
->AddressFile
));
580 if( Connection
->AddressFile
) {
581 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile->Listener: %x\n",
582 Connection
->AddressFile
->Listener
));
585 /* Listening will require us to create a listening socket and store it in
586 * the address file. It will be signalled, and attempt to complete an irp
587 * when a new connection arrives. */
588 /* The important thing to note here is that the irp we'll complete belongs
589 * to the socket to be accepted onto, not the listener */
590 if( !Connection
->AddressFile
->Listener
) {
591 Connection
->AddressFile
->Listener
=
592 TCPAllocateConnectionEndpoint( NULL
);
594 if( !Connection
->AddressFile
->Listener
)
595 Status
= STATUS_NO_MEMORY
;
597 if( NT_SUCCESS(Status
) ) {
598 Connection
->AddressFile
->Listener
->AddressFile
=
599 Connection
->AddressFile
;
601 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
602 Connection
->AddressFile
->Family
,
604 Connection
->AddressFile
->Protocol
);
607 if( NT_SUCCESS(Status
) )
608 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
611 if( NT_SUCCESS(Status
) ) {
612 Status
= DispPrepareIrpForCancel
613 (TranContext
->Handle
.ConnectionContext
,
615 (PDRIVER_CANCEL
)DispCancelListenRequest
);
618 if( NT_SUCCESS(Status
) ) {
620 ( (PTDI_REQUEST
)Parameters
,
621 Connection
->AddressFile
->Listener
,
623 DispDataRequestComplete
,
627 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
633 NTSTATUS
DispTdiQueryInformation(
634 PDEVICE_OBJECT DeviceObject
,
637 * FUNCTION: TDI_QUERY_INFORMATION handler
639 * DeviceObject = Pointer to device object structure
640 * Irp = Pointer to an I/O request packet
642 * Status of operation
645 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
646 PTRANSPORT_CONTEXT TranContext
;
647 PIO_STACK_LOCATION IrpSp
;
649 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
651 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
652 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
654 TranContext
= IrpSp
->FileObject
->FsContext
;
656 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
657 return STATUS_INVALID_CONNECTION
;
660 switch (Parameters
->QueryType
)
662 case TDI_QUERY_ADDRESS_INFO
:
664 PTDI_ADDRESS_INFO AddressInfo
;
665 PADDRESS_FILE AddrFile
;
666 PTA_IP_ADDRESS Address
;
668 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
670 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
671 case TDI_TRANSPORT_ADDRESS_FILE
:
672 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
675 case TDI_CONNECTION_FILE
:
677 ((PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
)->
682 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
683 return STATUS_INVALID_PARAMETER
;
687 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
688 return STATUS_INVALID_PARAMETER
;
691 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
692 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
693 sizeof(TDI_ADDRESS_IP
))) {
694 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
695 return STATUS_BUFFER_OVERFLOW
;
698 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
699 Address
->TAAddressCount
= 1;
700 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
701 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
702 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
703 Address
->Address
[0].Address
[0].in_addr
=
704 AddrFile
->Address
.Address
.IPv4Address
;
706 &Address
->Address
[0].Address
[0].sin_zero
,
707 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
709 return STATUS_SUCCESS
;
712 case TDI_QUERY_CONNECTION_INFO
:
714 PTDI_CONNECTION_INFORMATION AddressInfo
;
715 PADDRESS_FILE AddrFile
;
716 PCONNECTION_ENDPOINT Endpoint
= NULL
;
718 AddressInfo
= (PTDI_CONNECTION_INFORMATION
)
719 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
721 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
722 case TDI_TRANSPORT_ADDRESS_FILE
:
723 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
726 case TDI_CONNECTION_FILE
:
728 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
732 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
733 return STATUS_INVALID_PARAMETER
;
737 TI_DbgPrint(MID_TRACE
, ("No connection object.\n"));
738 return STATUS_INVALID_PARAMETER
;
741 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
742 (FIELD_OFFSET(TDI_CONNECTION_INFORMATION
, RemoteAddress
) +
744 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small (ptr).\n"));
745 return STATUS_BUFFER_OVERFLOW
;
748 return TCPGetPeerAddress( Endpoint
, AddressInfo
->RemoteAddress
);
752 return STATUS_NOT_IMPLEMENTED
;
756 NTSTATUS
DispTdiReceive(
759 * FUNCTION: TDI_RECEIVE handler
761 * Irp = Pointer to an I/O request packet
763 * Status of operation
766 PIO_STACK_LOCATION IrpSp
;
767 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
768 PTRANSPORT_CONTEXT TranContext
;
772 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
774 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
775 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
777 TranContext
= IrpSp
->FileObject
->FsContext
;
778 if (TranContext
== NULL
)
780 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
781 return STATUS_INVALID_CONNECTION
;
784 if (TranContext
->Handle
.ConnectionContext
== NULL
)
786 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
787 return STATUS_INVALID_CONNECTION
;
790 /* Initialize a receive request */
791 Status
= DispPrepareIrpForCancel
792 (TranContext
->Handle
.ConnectionContext
,
794 (PDRIVER_CANCEL
)DispCancelRequest
);
796 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
797 if (NT_SUCCESS(Status
))
799 /* Lock here so we're sure we've got the following 'mark pending' */
800 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
802 Status
= TCPReceiveData(
803 TranContext
->Handle
.ConnectionContext
,
804 (PNDIS_BUFFER
)Irp
->MdlAddress
,
805 ReceiveInfo
->ReceiveLength
,
807 ReceiveInfo
->ReceiveFlags
,
808 DispDataRequestComplete
,
810 if (Status
!= STATUS_PENDING
)
812 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
814 IoMarkIrpPending(Irp
);
817 TcpipRecursiveMutexLeave( &TCPLock
);
820 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
826 NTSTATUS
DispTdiReceiveDatagram(
829 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
831 * Irp = Pointer to an I/O request packet
833 * Status of operation
836 PIO_STACK_LOCATION IrpSp
;
837 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
838 PTRANSPORT_CONTEXT TranContext
;
843 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
845 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
846 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
848 TranContext
= IrpSp
->FileObject
->FsContext
;
849 if (TranContext
== NULL
)
851 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
852 return STATUS_INVALID_ADDRESS
;
855 /* Initialize a receive request */
856 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
857 Request
.RequestNotifyObject
= DispDataRequestComplete
;
858 Request
.RequestContext
= Irp
;
860 Status
= DispPrepareIrpForCancel(
861 IrpSp
->FileObject
->FsContext
,
863 (PDRIVER_CANCEL
)DispCancelRequest
);
865 if (NT_SUCCESS(Status
))
870 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
874 Status
= UDPReceiveDatagram(
875 Request
.Handle
.AddressHandle
,
876 DgramInfo
->ReceiveDatagramInformation
,
878 DgramInfo
->ReceiveLength
,
879 DgramInfo
->ReceiveFlags
,
880 DgramInfo
->ReturnDatagramInformation
,
882 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
884 if (Status
!= STATUS_PENDING
) {
885 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
887 IoMarkIrpPending(Irp
);
890 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
896 NTSTATUS
DispTdiSend(
899 * FUNCTION: TDI_SEND handler
901 * Irp = Pointer to an I/O request packet
903 * Status of operation
906 PIO_STACK_LOCATION IrpSp
;
907 PTDI_REQUEST_KERNEL_SEND SendInfo
;
908 PTRANSPORT_CONTEXT TranContext
;
912 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
914 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
915 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
917 TranContext
= IrpSp
->FileObject
->FsContext
;
918 if (TranContext
== NULL
)
920 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
921 return STATUS_INVALID_CONNECTION
;
924 if (TranContext
->Handle
.ConnectionContext
== NULL
)
926 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
927 return STATUS_INVALID_CONNECTION
;
930 Status
= DispPrepareIrpForCancel(
931 IrpSp
->FileObject
->FsContext
,
933 (PDRIVER_CANCEL
)DispCancelRequest
);
935 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
936 if (NT_SUCCESS(Status
))
941 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
943 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
944 Status
= TCPSendData(
945 TranContext
->Handle
.ConnectionContext
,
947 SendInfo
->SendLength
,
950 DispDataRequestComplete
,
952 if (Status
!= STATUS_PENDING
)
954 DispDataRequestComplete(Irp
, Status
, BytesSent
);
956 IoMarkIrpPending( Irp
);
959 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
965 NTSTATUS
DispTdiSendDatagram(
968 * FUNCTION: TDI_SEND_DATAGRAM handler
970 * Irp = Pointer to an I/O request packet
972 * Status of operation
975 PIO_STACK_LOCATION IrpSp
;
977 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
978 PTRANSPORT_CONTEXT TranContext
;
981 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
983 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
984 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
985 TranContext
= IrpSp
->FileObject
->FsContext
;
987 /* Initialize a send request */
988 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
989 Request
.RequestNotifyObject
= DispDataRequestComplete
;
990 Request
.RequestContext
= Irp
;
992 Status
= DispPrepareIrpForCancel(
993 IrpSp
->FileObject
->FsContext
,
995 (PDRIVER_CANCEL
)DispCancelRequest
);
997 if (NT_SUCCESS(Status
)) {
1001 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
1003 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
1007 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
1008 must be of type PTDI_ADDRESS_IP */
1009 TI_DbgPrint(MID_TRACE
,
1010 ("About to call send routine %x\n",
1011 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
1013 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
) )
1014 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
1015 Request
.Handle
.AddressHandle
,
1016 DgramInfo
->SendDatagramInformation
,
1019 &Irp
->IoStatus
.Information
);
1021 Status
= STATUS_UNSUCCESSFUL
;
1023 if (Status
!= STATUS_PENDING
) {
1024 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
1025 /* Return STATUS_PENDING because DispPrepareIrpForCancel
1026 marks Irp as pending */
1027 Status
= STATUS_PENDING
;
1029 IoMarkIrpPending( Irp
);
1032 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
1038 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
1040 * FUNCTION: TDI_SET_EVENT_HANDER handler
1042 * Irp = Pointer to a I/O request packet
1044 * Status of operation
1047 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1048 PTRANSPORT_CONTEXT TranContext
;
1049 PIO_STACK_LOCATION IrpSp
;
1050 PADDRESS_FILE AddrFile
;
1054 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1056 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1058 /* Get associated address file object. Quit if none exists */
1060 TranContext
= IrpSp
->FileObject
->FsContext
;
1062 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1063 return STATUS_INVALID_PARAMETER
;
1066 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1068 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1069 return STATUS_INVALID_PARAMETER
;
1072 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1073 Status
= STATUS_SUCCESS
;
1075 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
1077 /* Set the event handler. if an event handler is associated with
1078 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1079 If an event handler is not used it's flag is FALSE */
1080 switch (Parameters
->EventType
) {
1081 case TDI_EVENT_CONNECT
:
1082 if (!Parameters
->EventHandler
) {
1083 AddrFile
->ConnectHandlerContext
= NULL
;
1084 AddrFile
->RegisteredConnectHandler
= FALSE
;
1086 AddrFile
->ConnectHandler
=
1087 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1088 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1089 AddrFile
->RegisteredConnectHandler
= TRUE
;
1093 case TDI_EVENT_DISCONNECT
:
1094 if (!Parameters
->EventHandler
) {
1095 AddrFile
->DisconnectHandlerContext
= NULL
;
1096 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1098 AddrFile
->DisconnectHandler
=
1099 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1100 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1101 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1105 case TDI_EVENT_ERROR
:
1106 if (Parameters
->EventHandler
== NULL
) {
1107 AddrFile
->ErrorHandlerContext
= NULL
;
1108 AddrFile
->RegisteredErrorHandler
= FALSE
;
1110 AddrFile
->ErrorHandler
=
1111 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1112 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1113 AddrFile
->RegisteredErrorHandler
= TRUE
;
1117 case TDI_EVENT_RECEIVE
:
1118 if (Parameters
->EventHandler
== NULL
) {
1119 AddrFile
->ReceiveHandlerContext
= NULL
;
1120 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1122 AddrFile
->ReceiveHandler
=
1123 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1124 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1125 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1129 case TDI_EVENT_RECEIVE_DATAGRAM
:
1130 if (Parameters
->EventHandler
== NULL
) {
1131 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1132 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1134 AddrFile
->ReceiveDatagramHandler
=
1135 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1136 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1137 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1141 case TDI_EVENT_RECEIVE_EXPEDITED
:
1142 if (Parameters
->EventHandler
== NULL
) {
1143 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1144 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1146 AddrFile
->ExpeditedReceiveHandler
=
1147 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1148 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1149 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1153 case TDI_EVENT_CHAINED_RECEIVE
:
1154 if (Parameters
->EventHandler
== NULL
) {
1155 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1156 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1158 AddrFile
->ChainedReceiveHandler
=
1159 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1160 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1161 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1165 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1166 if (Parameters
->EventHandler
== NULL
) {
1167 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1168 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1170 AddrFile
->ChainedReceiveDatagramHandler
=
1171 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1172 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1173 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1177 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1178 if (Parameters
->EventHandler
== NULL
) {
1179 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1180 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1182 AddrFile
->ChainedReceiveExpeditedHandler
=
1183 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1184 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1185 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1190 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1191 Parameters
->EventType
));
1193 Status
= STATUS_INVALID_PARAMETER
;
1196 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1202 NTSTATUS
DispTdiSetInformation(
1205 * FUNCTION: TDI_SET_INFORMATION handler
1207 * Irp = Pointer to an I/O request packet
1209 * Status of operation
1212 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1214 return STATUS_NOT_IMPLEMENTED
;
1218 VOID
DispTdiQueryInformationExComplete(
1223 * FUNCTION: Completes a TDI QueryInformationEx request
1225 * Context = Pointer to the IRP for the request
1226 * Status = TDI status of the request
1227 * ByteCount = Number of bytes returned in output buffer
1230 PTI_QUERY_CONTEXT QueryContext
;
1233 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1234 if (NT_SUCCESS(Status
)) {
1235 Count
= CopyBufferToBufferChain(
1236 QueryContext
->InputMdl
,
1237 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1238 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1242 MmUnlockPages(QueryContext
->InputMdl
);
1243 IoFreeMdl(QueryContext
->InputMdl
);
1244 if( QueryContext
->OutputMdl
) {
1245 MmUnlockPages(QueryContext
->OutputMdl
);
1246 IoFreeMdl(QueryContext
->OutputMdl
);
1249 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1250 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1252 ExFreePool(QueryContext
);
1256 NTSTATUS
DispTdiQueryInformationEx(
1258 PIO_STACK_LOCATION IrpSp
)
1260 * FUNCTION: TDI QueryInformationEx handler
1262 * Irp = Pointer to I/O request packet
1263 * IrpSp = Pointer to current stack location of Irp
1265 * Status of operation
1268 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
= NULL
;
1269 PTRANSPORT_CONTEXT TranContext
;
1270 PTI_QUERY_CONTEXT QueryContext
= NULL
;
1272 TDI_REQUEST Request
;
1274 UINT InputBufferLength
;
1275 UINT OutputBufferLength
;
1276 BOOLEAN InputMdlLocked
= FALSE
;
1277 BOOLEAN OutputMdlLocked
= FALSE
;
1278 PMDL InputMdl
= NULL
;
1279 PMDL OutputMdl
= NULL
;
1280 NTSTATUS Status
= STATUS_SUCCESS
;
1282 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1284 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1286 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1287 case TDI_TRANSPORT_ADDRESS_FILE
:
1288 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1291 case TDI_CONNECTION_FILE
:
1292 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1295 case TDI_CONTROL_CHANNEL_FILE
:
1296 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1300 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1301 return STATUS_INVALID_PARAMETER
;
1304 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1305 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1307 /* Validate parameters */
1308 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1309 (OutputBufferLength
!= 0)) {
1311 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1312 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1313 OutputBuffer
= Irp
->UserBuffer
;
1315 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1318 InputMdl
= IoAllocateMdl(InputBuffer
,
1319 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1322 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1323 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1325 if (InputMdl
&& OutputMdl
) {
1327 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1330 InputMdlLocked
= TRUE
;
1332 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1335 OutputMdlLocked
= TRUE
;
1337 RtlCopyMemory(&QueryContext
->QueryInfo
,
1338 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1340 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1342 Status
= _SEH_GetExceptionCode();
1345 if (NT_SUCCESS(Status
)) {
1346 Size
= MmGetMdlByteCount(OutputMdl
);
1348 QueryContext
->Irp
= Irp
;
1349 QueryContext
->InputMdl
= InputMdl
;
1350 QueryContext
->OutputMdl
= OutputMdl
;
1352 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1353 Request
.RequestContext
= QueryContext
;
1354 Status
= InfoTdiQueryInformationEx(&Request
,
1355 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1356 &Size
, &QueryContext
->QueryInfo
.Context
);
1357 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1359 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1364 /* An error occurred if we get here */
1368 MmUnlockPages(InputMdl
);
1369 IoFreeMdl(InputMdl
);
1373 if (OutputMdlLocked
)
1374 MmUnlockPages(OutputMdl
);
1375 IoFreeMdl(OutputMdl
);
1378 ExFreePool(QueryContext
);
1380 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1381 } else if( InputBufferLength
==
1382 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1383 /* Handle the case where the user is probing the buffer for length */
1384 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1385 InputBufferLength
, OutputBufferLength
));
1386 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1387 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1391 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1392 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1395 InputMdl
= IoAllocateMdl(InputBuffer
,
1396 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1399 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1402 InputMdlLocked
= TRUE
;
1403 Status
= STATUS_SUCCESS
;
1405 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1406 Status
= _SEH_GetExceptionCode();
1409 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1410 if( InputMdl
) IoFreeMdl( InputMdl
);
1411 ExFreePool(QueryContext
);
1415 RtlCopyMemory(&QueryContext
->QueryInfo
,
1416 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1418 QueryContext
->Irp
= Irp
;
1419 QueryContext
->InputMdl
= InputMdl
;
1420 QueryContext
->OutputMdl
= NULL
;
1422 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1423 Request
.RequestContext
= QueryContext
;
1424 Status
= InfoTdiQueryInformationEx(&Request
,
1425 &QueryContext
->QueryInfo
.ID
,
1428 &QueryContext
->QueryInfo
.Context
);
1429 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1430 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1431 } else Status
= STATUS_INVALID_PARAMETER
;
1433 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1439 NTSTATUS
DispTdiSetInformationEx(
1441 PIO_STACK_LOCATION IrpSp
)
1443 * FUNCTION: TDI SetInformationEx handler
1445 * Irp = Pointer to I/O request packet
1446 * IrpSp = Pointer to current stack location of Irp
1448 * Status of operation
1451 PTRANSPORT_CONTEXT TranContext
;
1452 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1453 TDI_REQUEST Request
;
1457 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1459 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1460 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1462 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1463 case TDI_TRANSPORT_ADDRESS_FILE
:
1464 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1467 case TDI_CONNECTION_FILE
:
1468 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1471 case TDI_CONTROL_CHANNEL_FILE
:
1472 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1476 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1477 Irp
->IoStatus
.Information
= 0;
1479 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1481 return IRPFinish(Irp
, STATUS_INVALID_PARAMETER
);
1484 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1485 if (NT_SUCCESS(Status
)) {
1486 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1487 Request
.RequestContext
= Irp
;
1489 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1490 &Info
->Buffer
, Info
->BufferSize
);
1492 if (Status
!= STATUS_PENDING
) {
1493 IoAcquireCancelSpinLock(&OldIrql
);
1494 (void)IoSetCancelRoutine(Irp
, NULL
);
1495 IoReleaseCancelSpinLock(OldIrql
);
1502 /* TODO: Support multiple addresses per interface.
1503 * For now just set the nte context to the interface index.
1505 * Later on, create an NTE context and NTE instance
1508 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1509 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1510 PIP_SET_ADDRESS IpAddrChange
=
1511 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1514 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1515 IpAddrChange
->NteIndex
));
1517 ForEachInterface(IF
) {
1518 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1520 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1521 Status
= STATUS_DUPLICATE_OBJECTID
;
1524 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1525 IPRemoveInterfaceRoute( IF
);
1527 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1528 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1529 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1530 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1531 IF
->Broadcast
.Address
.IPv4Address
=
1532 IF
->Unicast
.Address
.IPv4Address
|
1533 ~IF
->Netmask
.Address
.IPv4Address
;
1535 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1536 IF
->Unicast
.Address
.IPv4Address
));
1537 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1538 IF
->Netmask
.Address
.IPv4Address
));
1540 IPAddInterfaceRoute( IF
);
1542 IpAddrChange
->Address
= IF
->Index
;
1543 Status
= STATUS_SUCCESS
;
1544 Irp
->IoStatus
.Information
= IF
->Index
;
1549 Irp
->IoStatus
.Status
= Status
;
1553 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1554 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1555 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1558 ForEachInterface(IF
) {
1559 if( IF
->Index
== *NteIndex
) {
1560 IPRemoveInterfaceRoute( IF
);
1561 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1562 IF
->Unicast
.Address
.IPv4Address
= 0;
1563 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1564 IF
->Netmask
.Address
.IPv4Address
= 0;
1565 Status
= STATUS_SUCCESS
;
1569 Irp
->IoStatus
.Status
= Status
;