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 (void)IoSetCancelRoutine(Irp
, CancelRoutine
);
37 IoReleaseCancelSpinLock(OldIrql
);
39 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
41 return STATUS_SUCCESS
;
44 /* IRP has already been cancelled */
46 IoReleaseCancelSpinLock(OldIrql
);
48 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
49 Irp
->IoStatus
.Information
= 0;
51 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
53 return IRPFinish(Irp
, STATUS_CANCELLED
);
57 VOID
DispCancelComplete(
60 * FUNCTION: Completes a cancel request
62 * Context = Pointer to context information (FILE_OBJECT)
66 PFILE_OBJECT FileObject
;
67 PTRANSPORT_CONTEXT TranContext
;
69 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
71 FileObject
= (PFILE_OBJECT
)Context
;
72 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
74 /* Set the cleanup event */
75 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
77 /* We are expected to release the cancel spin lock */
78 /*IoReleaseCancelSpinLock(OldIrql);*/
80 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
84 VOID
DispDataRequestComplete(
89 * FUNCTION: Completes a send/receive IRP
91 * Context = Pointer to context information (IRP)
92 * Status = Status of the request
93 * Count = Number of bytes sent or received
97 PIO_STACK_LOCATION IrpSp
;
98 PTRANSPORT_CONTEXT TranContext
;
101 TI_DbgPrint(DEBUG_IRP
, ("Called for irp %x (%x, %d).\n",
102 Context
, Status
, Count
));
105 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
106 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
108 IoAcquireCancelSpinLock(&OldIrql
);
110 (void)IoSetCancelRoutine(Irp
, NULL
);
112 if (Irp
->Cancel
|| TranContext
->CancelIrps
) {
113 /* The IRP has been cancelled */
115 TI_DbgPrint(DEBUG_IRP
, ("IRP is cancelled.\n"));
117 Status
= STATUS_CANCELLED
;
121 IoReleaseCancelSpinLock(OldIrql
);
123 Irp
->IoStatus
.Status
= Status
;
124 Irp
->IoStatus
.Information
= Count
;
126 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
127 Irp
->IoStatus
.Status
));
128 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
129 Irp
->IoStatus
.Information
));
130 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
132 IRPFinish(Irp
, Irp
->IoStatus
.Status
);
134 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
137 typedef struct _DISCONNECT_TYPE
{
141 PFILE_OBJECT FileObject
;
142 } DISCONNECT_TYPE
, *PDISCONNECT_TYPE
;
144 VOID
DispDoDisconnect( PVOID Data
) {
145 PDISCONNECT_TYPE DisType
= (PDISCONNECT_TYPE
)Data
;
147 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect\n"));
153 DispDataRequestComplete
,
155 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect done\n"));
157 DispDataRequestComplete(DisType
->Irp
, STATUS_CANCELLED
, 0);
159 DispCancelComplete(DisType
->FileObject
);
162 VOID NTAPI
DispCancelRequest(
163 PDEVICE_OBJECT Device
,
166 * FUNCTION: Cancels an IRP
168 * Device = Pointer to device object
169 * Irp = Pointer to an I/O request packet
172 PIO_STACK_LOCATION IrpSp
;
173 PTRANSPORT_CONTEXT TranContext
;
174 PFILE_OBJECT FileObject
;
176 DISCONNECT_TYPE DisType
;
178 /*NTSTATUS Status = STATUS_SUCCESS;*/
180 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
182 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
183 FileObject
= IrpSp
->FileObject
;
184 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
185 MinorFunction
= IrpSp
->MinorFunction
;
187 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
189 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
190 Irp
->IoStatus
.Information
= 0;
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 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
216 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
220 /*DGCancelSendRequest(TranContext->Handle.AddressHandle, Irp);*/
223 case TDI_RECEIVE_DATAGRAM
:
224 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
225 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
229 /*DGCancelReceiveRequest(TranContext->Handle.AddressHandle, Irp);*/
233 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
237 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
239 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
243 VOID NTAPI
DispCancelListenRequest(
244 PDEVICE_OBJECT Device
,
247 * FUNCTION: Cancels a listen IRP
249 * Device = Pointer to device object
250 * Irp = Pointer to an I/O request packet
253 PIO_STACK_LOCATION IrpSp
;
254 PTRANSPORT_CONTEXT TranContext
;
255 PFILE_OBJECT FileObject
;
256 PCONNECTION_ENDPOINT Connection
;
257 /*NTSTATUS Status = STATUS_SUCCESS;*/
259 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
261 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
262 FileObject
= IrpSp
->FileObject
;
263 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
264 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
266 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
270 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
273 /* Try canceling the request */
274 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
275 TCPAbortListenForSocket(
276 Connection
->AddressFile
->Listener
,
279 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
281 DispDataRequestComplete(Irp
, STATUS_CANCELLED
, 0);
283 DispCancelComplete(FileObject
);
285 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
289 NTSTATUS
DispTdiAccept(
292 * FUNCTION: TDI_ACCEPT handler
294 * Irp = Pointer to an I/O request packet
296 * Status of operation
299 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
301 return STATUS_NOT_IMPLEMENTED
;
305 NTSTATUS
DispTdiAssociateAddress(
308 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
310 * Irp = Pointer to an I/O request packet
312 * Status of operation
315 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
316 PTRANSPORT_CONTEXT TranContext
;
317 PIO_STACK_LOCATION IrpSp
;
318 PCONNECTION_ENDPOINT Connection
;
319 PFILE_OBJECT FileObject
;
320 PADDRESS_FILE AddrFile
= NULL
;
323 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
325 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
327 /* Get associated connection endpoint file object. Quit if none exists */
329 TranContext
= IrpSp
->FileObject
->FsContext
;
331 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
332 return STATUS_INVALID_PARAMETER
;
335 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
337 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
338 return STATUS_INVALID_PARAMETER
;
341 if (Connection
->AddressFile
) {
342 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
343 return STATUS_INVALID_PARAMETER
;
346 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
348 Status
= ObReferenceObjectByHandle(
349 Parameters
->AddressHandle
,
355 if (!NT_SUCCESS(Status
)) {
356 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
357 Parameters
->AddressHandle
, Status
));
358 return STATUS_INVALID_PARAMETER
;
361 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
362 ObDereferenceObject(FileObject
);
363 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
364 FileObject
->FsContext2
));
365 return STATUS_INVALID_PARAMETER
;
368 /* Get associated address file object. Quit if none exists */
370 TranContext
= FileObject
->FsContext
;
372 ObDereferenceObject(FileObject
);
373 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
374 return STATUS_INVALID_PARAMETER
;
377 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
379 ObDereferenceObject(FileObject
);
380 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
381 return STATUS_INVALID_PARAMETER
;
384 Connection
->AddressFile
= AddrFile
;
386 /* Add connection endpoint to the address file */
387 AddrFile
->Connection
= Connection
;
389 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
390 ObDereferenceObject(FileObject
);
396 NTSTATUS
DispTdiConnect(
399 * FUNCTION: TDI_CONNECT handler
401 * Irp = Pointer to an I/O request packet
403 * Status of operation
406 PCONNECTION_ENDPOINT Connection
;
407 PTDI_REQUEST_KERNEL Parameters
;
408 PTRANSPORT_CONTEXT TranContext
;
409 PIO_STACK_LOCATION IrpSp
;
412 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
414 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
416 /* Get associated connection endpoint file object. Quit if none exists */
418 TranContext
= IrpSp
->FileObject
->FsContext
;
420 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
421 return STATUS_INVALID_CONNECTION
;
424 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
426 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
427 return STATUS_INVALID_CONNECTION
;
430 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
433 TranContext
->Handle
.ConnectionContext
,
434 Parameters
->RequestConnectionInformation
,
435 Parameters
->ReturnConnectionInformation
,
436 DispDataRequestComplete
,
439 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
445 NTSTATUS
DispTdiDisassociateAddress(
448 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
450 * Irp = Pointer to an I/O request packet
452 * Status of operation
455 PCONNECTION_ENDPOINT Connection
;
456 PTRANSPORT_CONTEXT TranContext
;
457 PIO_STACK_LOCATION IrpSp
;
459 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
461 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
463 /* Get associated connection endpoint file object. Quit if none exists */
465 TranContext
= IrpSp
->FileObject
->FsContext
;
467 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
468 return STATUS_INVALID_PARAMETER
;
471 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
473 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
474 return STATUS_INVALID_PARAMETER
;
477 if (!Connection
->AddressFile
) {
478 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
479 return STATUS_INVALID_PARAMETER
;
482 return STATUS_SUCCESS
;
486 NTSTATUS
DispTdiDisconnect(
489 * FUNCTION: TDI_DISCONNECT handler
491 * Irp = Pointer to an I/O request packet
493 * Status of operation
497 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
498 PCONNECTION_ENDPOINT Connection
;
499 PTRANSPORT_CONTEXT TranContext
;
500 PIO_STACK_LOCATION IrpSp
;
502 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
504 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
505 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
507 /* Get associated connection endpoint file object. Quit if none exists */
509 TranContext
= IrpSp
->FileObject
->FsContext
;
511 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
512 return STATUS_INVALID_CONNECTION
;
515 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
517 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
518 return STATUS_INVALID_CONNECTION
;
521 Status
= TCPDisconnect(
522 TranContext
->Handle
.ConnectionContext
,
523 DisReq
->RequestFlags
,
524 DisReq
->RequestConnectionInformation
,
525 DisReq
->ReturnConnectionInformation
,
526 DispDataRequestComplete
,
529 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
535 NTSTATUS
DispTdiListen(
538 * FUNCTION: TDI_LISTEN handler
540 * Irp = Pointer to an I/O request packet
542 * Status of operation
545 PCONNECTION_ENDPOINT Connection
;
546 PTDI_REQUEST_KERNEL Parameters
;
547 PTRANSPORT_CONTEXT TranContext
;
548 PIO_STACK_LOCATION IrpSp
;
549 NTSTATUS Status
= STATUS_SUCCESS
;
551 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
553 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
555 /* Get associated connection endpoint file object. Quit if none exists */
557 TranContext
= IrpSp
->FileObject
->FsContext
;
558 if (TranContext
== NULL
)
560 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
561 return STATUS_INVALID_CONNECTION
;
564 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
565 if (Connection
== NULL
)
567 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
568 return STATUS_INVALID_CONNECTION
;
571 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
573 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile: %x\n",
574 Connection
->AddressFile
));
575 if( Connection
->AddressFile
) {
576 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile->Listener: %x\n",
577 Connection
->AddressFile
->Listener
));
580 /* Listening will require us to create a listening socket and store it in
581 * the address file. It will be signalled, and attempt to complete an irp
582 * when a new connection arrives. */
583 /* The important thing to note here is that the irp we'll complete belongs
584 * to the socket to be accepted onto, not the listener */
585 if( !Connection
->AddressFile
->Listener
) {
586 Connection
->AddressFile
->Listener
=
587 TCPAllocateConnectionEndpoint( NULL
);
589 if( !Connection
->AddressFile
->Listener
)
590 Status
= STATUS_NO_MEMORY
;
592 if( NT_SUCCESS(Status
) ) {
593 Connection
->AddressFile
->Listener
->AddressFile
=
594 Connection
->AddressFile
;
596 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
597 Connection
->AddressFile
->Family
,
599 Connection
->AddressFile
->Protocol
);
602 if( NT_SUCCESS(Status
) )
603 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
606 if( NT_SUCCESS(Status
) ) {
607 Status
= DispPrepareIrpForCancel
608 (TranContext
->Handle
.ConnectionContext
,
610 (PDRIVER_CANCEL
)DispCancelListenRequest
);
613 if( NT_SUCCESS(Status
) ) {
615 ( (PTDI_REQUEST
)Parameters
,
616 Connection
->AddressFile
->Listener
,
618 DispDataRequestComplete
,
622 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
628 NTSTATUS
DispTdiQueryInformation(
629 PDEVICE_OBJECT DeviceObject
,
632 * FUNCTION: TDI_QUERY_INFORMATION handler
634 * DeviceObject = Pointer to device object structure
635 * Irp = Pointer to an I/O request packet
637 * Status of operation
640 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
641 PTRANSPORT_CONTEXT TranContext
;
642 PIO_STACK_LOCATION IrpSp
;
644 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
646 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
647 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
649 TranContext
= IrpSp
->FileObject
->FsContext
;
651 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
652 return STATUS_INVALID_CONNECTION
;
655 switch (Parameters
->QueryType
)
657 case TDI_QUERY_ADDRESS_INFO
:
659 PTDI_ADDRESS_INFO AddressInfo
;
660 PADDRESS_FILE AddrFile
;
661 PTA_IP_ADDRESS Address
;
663 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
665 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
666 case TDI_TRANSPORT_ADDRESS_FILE
:
667 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
670 case TDI_CONNECTION_FILE
:
672 ((PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
)->
677 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
678 return STATUS_INVALID_PARAMETER
;
682 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
683 return STATUS_INVALID_PARAMETER
;
686 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
687 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
688 sizeof(TDI_ADDRESS_IP
))) {
689 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
690 return STATUS_BUFFER_OVERFLOW
;
693 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
694 Address
->TAAddressCount
= 1;
695 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
696 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
697 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
698 Address
->Address
[0].Address
[0].in_addr
=
699 AddrFile
->Address
.Address
.IPv4Address
;
701 &Address
->Address
[0].Address
[0].sin_zero
,
702 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
704 return STATUS_SUCCESS
;
707 case TDI_QUERY_CONNECTION_INFO
:
709 PTDI_CONNECTION_INFORMATION AddressInfo
;
710 PADDRESS_FILE AddrFile
;
711 PCONNECTION_ENDPOINT Endpoint
= NULL
;
713 AddressInfo
= (PTDI_CONNECTION_INFORMATION
)
714 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
716 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
717 case TDI_TRANSPORT_ADDRESS_FILE
:
718 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
721 case TDI_CONNECTION_FILE
:
723 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
727 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
728 return STATUS_INVALID_PARAMETER
;
732 TI_DbgPrint(MID_TRACE
, ("No connection object.\n"));
733 return STATUS_INVALID_PARAMETER
;
736 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
737 (FIELD_OFFSET(TDI_CONNECTION_INFORMATION
, RemoteAddress
) +
739 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small (ptr).\n"));
740 return STATUS_BUFFER_OVERFLOW
;
743 return TCPGetPeerAddress( Endpoint
, AddressInfo
->RemoteAddress
);
747 return STATUS_NOT_IMPLEMENTED
;
751 NTSTATUS
DispTdiReceive(
754 * FUNCTION: TDI_RECEIVE handler
756 * Irp = Pointer to an I/O request packet
758 * Status of operation
761 PIO_STACK_LOCATION IrpSp
;
762 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
763 PTRANSPORT_CONTEXT TranContext
;
767 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
769 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
770 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
772 TranContext
= IrpSp
->FileObject
->FsContext
;
773 if (TranContext
== NULL
)
775 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
776 return STATUS_INVALID_CONNECTION
;
779 if (TranContext
->Handle
.ConnectionContext
== NULL
)
781 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
782 return STATUS_INVALID_CONNECTION
;
785 /* Initialize a receive request */
786 Status
= DispPrepareIrpForCancel
787 (TranContext
->Handle
.ConnectionContext
,
789 (PDRIVER_CANCEL
)DispCancelRequest
);
791 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
792 if (NT_SUCCESS(Status
))
794 /* Lock here so we're sure we've got the following 'mark pending' */
795 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
797 Status
= TCPReceiveData(
798 TranContext
->Handle
.ConnectionContext
,
799 (PNDIS_BUFFER
)Irp
->MdlAddress
,
800 ReceiveInfo
->ReceiveLength
,
802 ReceiveInfo
->ReceiveFlags
,
803 DispDataRequestComplete
,
805 if (Status
!= STATUS_PENDING
)
807 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
809 IoMarkIrpPending(Irp
);
812 TcpipRecursiveMutexLeave( &TCPLock
);
815 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
821 NTSTATUS
DispTdiReceiveDatagram(
824 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
826 * Irp = Pointer to an I/O request packet
828 * Status of operation
831 PIO_STACK_LOCATION IrpSp
;
832 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
833 PTRANSPORT_CONTEXT TranContext
;
838 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
840 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
841 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
843 TranContext
= IrpSp
->FileObject
->FsContext
;
844 if (TranContext
== NULL
)
846 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
847 return STATUS_INVALID_ADDRESS
;
850 /* Initialize a receive request */
851 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
852 Request
.RequestNotifyObject
= DispDataRequestComplete
;
853 Request
.RequestContext
= Irp
;
855 Status
= DispPrepareIrpForCancel(
856 IrpSp
->FileObject
->FsContext
,
858 (PDRIVER_CANCEL
)DispCancelRequest
);
860 if (NT_SUCCESS(Status
))
865 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
869 Status
= DGReceiveDatagram(
870 Request
.Handle
.AddressHandle
,
871 DgramInfo
->ReceiveDatagramInformation
,
873 DgramInfo
->ReceiveLength
,
874 DgramInfo
->ReceiveFlags
,
875 DgramInfo
->ReturnDatagramInformation
,
877 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
880 if (Status
!= STATUS_PENDING
) {
881 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
883 IoMarkIrpPending(Irp
);
886 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
892 NTSTATUS
DispTdiSend(
895 * FUNCTION: TDI_SEND handler
897 * Irp = Pointer to an I/O request packet
899 * Status of operation
902 PIO_STACK_LOCATION IrpSp
;
903 PTDI_REQUEST_KERNEL_SEND SendInfo
;
904 PTRANSPORT_CONTEXT TranContext
;
908 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
910 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
911 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
913 TranContext
= IrpSp
->FileObject
->FsContext
;
914 if (TranContext
== NULL
)
916 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
917 return STATUS_INVALID_CONNECTION
;
920 if (TranContext
->Handle
.ConnectionContext
== NULL
)
922 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
923 return STATUS_INVALID_CONNECTION
;
926 Status
= DispPrepareIrpForCancel(
927 IrpSp
->FileObject
->FsContext
,
929 (PDRIVER_CANCEL
)DispCancelRequest
);
931 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
932 if (NT_SUCCESS(Status
))
937 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
939 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
940 Status
= TCPSendData(
941 TranContext
->Handle
.ConnectionContext
,
943 SendInfo
->SendLength
,
946 DispDataRequestComplete
,
948 if (Status
!= STATUS_PENDING
)
950 DispDataRequestComplete(Irp
, Status
, BytesSent
);
952 IoMarkIrpPending( Irp
);
955 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
961 NTSTATUS
DispTdiSendDatagram(
964 * FUNCTION: TDI_SEND_DATAGRAM handler
966 * Irp = Pointer to an I/O request packet
968 * Status of operation
971 PIO_STACK_LOCATION IrpSp
;
973 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
974 PTRANSPORT_CONTEXT TranContext
;
977 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
979 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
980 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
981 TranContext
= IrpSp
->FileObject
->FsContext
;
983 /* Initialize a send request */
984 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
985 Request
.RequestNotifyObject
= DispDataRequestComplete
;
986 Request
.RequestContext
= Irp
;
988 Status
= DispPrepareIrpForCancel(
989 IrpSp
->FileObject
->FsContext
,
991 (PDRIVER_CANCEL
)DispCancelRequest
);
993 if (NT_SUCCESS(Status
)) {
997 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
999 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
1003 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
1004 must be of type PTDI_ADDRESS_IP */
1005 TI_DbgPrint(MID_TRACE
,
1006 ("About to call send routine %x\n",
1007 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
1009 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
) )
1012 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
1013 Request
.Handle
.AddressHandle
,
1014 DgramInfo
->SendDatagramInformation
,
1018 Irp
->IoStatus
.Information
= DataUsed
;
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
;
1269 PTRANSPORT_CONTEXT TranContext
;
1270 PTI_QUERY_CONTEXT QueryContext
;
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_PTR
)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
;
1456 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1458 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1459 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1461 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
1462 case TDI_TRANSPORT_ADDRESS_FILE
:
1463 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1466 case TDI_CONNECTION_FILE
:
1467 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1470 case TDI_CONTROL_CHANNEL_FILE
:
1471 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1475 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1476 Irp
->IoStatus
.Information
= 0;
1478 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1480 return IRPFinish(Irp
, STATUS_INVALID_PARAMETER
);
1483 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1484 if (NT_SUCCESS(Status
)) {
1485 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1486 Request
.RequestContext
= Irp
;
1488 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1489 &Info
->Buffer
, Info
->BufferSize
);
1495 /* TODO: Support multiple addresses per interface.
1496 * For now just set the nte context to the interface index.
1498 * Later on, create an NTE context and NTE instance
1501 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1502 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1503 PIP_SET_ADDRESS IpAddrChange
=
1504 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1507 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1508 IpAddrChange
->NteIndex
));
1510 ForEachInterface(IF
) {
1511 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1513 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1514 Status
= STATUS_DUPLICATE_OBJECTID
;
1517 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1518 IPRemoveInterfaceRoute( IF
);
1520 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1521 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1522 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1523 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1524 IF
->Broadcast
.Address
.IPv4Address
=
1525 IF
->Unicast
.Address
.IPv4Address
|
1526 ~IF
->Netmask
.Address
.IPv4Address
;
1528 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1529 IF
->Unicast
.Address
.IPv4Address
));
1530 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1531 IF
->Netmask
.Address
.IPv4Address
));
1533 IPAddInterfaceRoute( IF
);
1535 IpAddrChange
->Address
= IF
->Index
;
1536 Status
= STATUS_SUCCESS
;
1537 Irp
->IoStatus
.Information
= IF
->Index
;
1542 Irp
->IoStatus
.Status
= Status
;
1546 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1547 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1548 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1551 ForEachInterface(IF
) {
1552 if( IF
->Index
== *NteIndex
) {
1553 IPRemoveInterfaceRoute( IF
);
1554 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1555 IF
->Unicast
.Address
.IPv4Address
= 0;
1556 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1557 IF
->Netmask
.Address
.IPv4Address
= 0;
1558 Status
= STATUS_SUCCESS
;
1562 Irp
->IoStatus
.Status
= Status
;