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
14 NTSTATUS
IRPFinish( PIRP Irp
, NTSTATUS Status
) {
17 Irp
->IoStatus
.Status
= Status
;
19 if( Status
== STATUS_PENDING
)
20 IoMarkIrpPending( Irp
);
22 IoAcquireCancelSpinLock(&OldIrql
);
23 (void)IoSetCancelRoutine( Irp
, NULL
);
24 IoReleaseCancelSpinLock(OldIrql
);
26 IoCompleteRequest( Irp
, IO_NETWORK_INCREMENT
);
32 NTSTATUS
DispPrepareIrpForCancel(
33 PTRANSPORT_CONTEXT Context
,
35 PDRIVER_CANCEL CancelRoutine
)
37 * FUNCTION: Prepare an IRP for cancellation
39 * Context = Pointer to context information
40 * Irp = Pointer to an I/O request packet
41 * CancelRoutine = Routine to be called when I/O request is cancelled
47 PIO_STACK_LOCATION IrpSp
;
48 PTRANSPORT_CONTEXT TransContext
;
50 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
52 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
53 TransContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
55 IoAcquireCancelSpinLock(&OldIrql
);
57 if (!Irp
->Cancel
&& !TransContext
->CancelIrps
) {
58 (void)IoSetCancelRoutine(Irp
, CancelRoutine
);
59 IoReleaseCancelSpinLock(OldIrql
);
61 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
63 return STATUS_SUCCESS
;
66 /* IRP has already been cancelled */
68 IoReleaseCancelSpinLock(OldIrql
);
70 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
71 Irp
->IoStatus
.Information
= 0;
73 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
75 return Irp
->IoStatus
.Status
;
78 VOID
DispDataRequestComplete(
83 * FUNCTION: Completes a send/receive IRP
85 * Context = Pointer to context information (IRP)
86 * Status = Status of the request
87 * Count = Number of bytes sent or received
92 TI_DbgPrint(DEBUG_IRP
, ("Called for irp %x (%x, %d).\n",
95 Irp
->IoStatus
.Status
= Status
;
96 Irp
->IoStatus
.Information
= Count
;
98 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
99 Irp
->IoStatus
.Status
));
100 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
101 Irp
->IoStatus
.Information
));
102 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
104 IRPFinish(Irp
, Status
);
106 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
109 VOID NTAPI
DispCancelRequest(
110 PDEVICE_OBJECT Device
,
113 * FUNCTION: Cancels an IRP
115 * Device = Pointer to device object
116 * Irp = Pointer to an I/O request packet
119 PIO_STACK_LOCATION IrpSp
;
120 PTRANSPORT_CONTEXT TranContext
;
121 PFILE_OBJECT FileObject
;
123 PCONNECTION_ENDPOINT Connection
;
124 BOOLEAN DequeuedIrp
= TRUE
;
126 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
128 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
130 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
131 FileObject
= IrpSp
->FileObject
;
132 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
133 MinorFunction
= IrpSp
->MinorFunction
;
135 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
137 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
138 Irp
->IoStatus
.Information
= 0;
142 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
145 /* Try canceling the request */
146 switch(MinorFunction
) {
149 DequeuedIrp
= TCPRemoveIRP( TranContext
->Handle
.ConnectionContext
, Irp
);
152 case TDI_SEND_DATAGRAM
:
153 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
154 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
158 DequeuedIrp
= DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
161 case TDI_RECEIVE_DATAGRAM
:
162 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
163 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
167 DequeuedIrp
= DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
171 DequeuedIrp
= TCPRemoveIRP(TranContext
->Handle
.ConnectionContext
, Irp
);
175 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
177 DequeuedIrp
= TCPRemoveIRP(TranContext
->Handle
.ConnectionContext
, Irp
);
180 if (KeCancelTimer(&Connection
->DisconnectTimer
))
182 DereferenceObject(Connection
);
188 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
194 IRPFinish(Irp
, STATUS_CANCELLED
);
196 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
200 VOID NTAPI
DispCancelListenRequest(
201 PDEVICE_OBJECT Device
,
204 * FUNCTION: Cancels a listen IRP
206 * Device = Pointer to device object
207 * Irp = Pointer to an I/O request packet
210 PIO_STACK_LOCATION IrpSp
;
211 PTRANSPORT_CONTEXT TranContext
;
212 PFILE_OBJECT FileObject
;
213 PCONNECTION_ENDPOINT Connection
;
215 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
217 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
219 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
220 FileObject
= IrpSp
->FileObject
;
221 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
222 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
224 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
228 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
231 /* Try canceling the request */
232 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
234 if (TCPAbortListenForSocket(Connection
->AddressFile
->Listener
,
237 Irp
->IoStatus
.Information
= 0;
238 IRPFinish(Irp
, STATUS_CANCELLED
);
241 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
245 NTSTATUS
DispTdiAccept(
248 * FUNCTION: TDI_ACCEPT handler
250 * Irp = Pointer to an I/O request packet
252 * Status of operation
255 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
257 return STATUS_NOT_IMPLEMENTED
;
261 NTSTATUS
DispTdiAssociateAddress(
264 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
266 * Irp = Pointer to an I/O request packet
268 * Status of operation
271 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
272 PTRANSPORT_CONTEXT TranContext
;
273 PIO_STACK_LOCATION IrpSp
;
274 PCONNECTION_ENDPOINT Connection
, LastConnection
;
275 PFILE_OBJECT FileObject
;
276 PADDRESS_FILE AddrFile
= NULL
;
280 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
282 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
284 /* Get associated connection endpoint file object. Quit if none exists */
286 TranContext
= IrpSp
->FileObject
->FsContext
;
288 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
289 return STATUS_INVALID_PARAMETER
;
292 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
294 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
295 return STATUS_INVALID_PARAMETER
;
298 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
300 Status
= ObReferenceObjectByHandle(
301 Parameters
->AddressHandle
,
307 if (!NT_SUCCESS(Status
)) {
308 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
309 Parameters
->AddressHandle
, Status
));
310 return STATUS_INVALID_PARAMETER
;
313 LockObject(Connection
, &OldIrql
);
315 if (Connection
->AddressFile
) {
316 ObDereferenceObject(FileObject
);
317 UnlockObject(Connection
, OldIrql
);
318 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
319 return STATUS_INVALID_PARAMETER
;
322 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
323 ObDereferenceObject(FileObject
);
324 UnlockObject(Connection
, OldIrql
);
325 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
326 FileObject
->FsContext2
));
327 return STATUS_INVALID_PARAMETER
;
330 /* Get associated address file object. Quit if none exists */
332 TranContext
= FileObject
->FsContext
;
334 ObDereferenceObject(FileObject
);
335 UnlockObject(Connection
, OldIrql
);
336 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
337 return STATUS_INVALID_PARAMETER
;
340 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
342 UnlockObject(Connection
, OldIrql
);
343 ObDereferenceObject(FileObject
);
344 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
345 return STATUS_INVALID_PARAMETER
;
348 LockObjectAtDpcLevel(AddrFile
);
350 ReferenceObject(AddrFile
);
351 Connection
->AddressFile
= AddrFile
;
353 /* Add connection endpoint to the address file */
354 ReferenceObject(Connection
);
355 if (AddrFile
->Connection
== NULL
)
356 AddrFile
->Connection
= Connection
;
359 LastConnection
= AddrFile
->Connection
;
360 while (LastConnection
->Next
!= NULL
)
361 LastConnection
= LastConnection
->Next
;
362 LastConnection
->Next
= Connection
;
365 ObDereferenceObject(FileObject
);
367 UnlockObjectFromDpcLevel(AddrFile
);
368 UnlockObject(Connection
, OldIrql
);
370 return STATUS_SUCCESS
;
374 NTSTATUS
DispTdiConnect(
377 * FUNCTION: TDI_CONNECT handler
379 * Irp = Pointer to an I/O request packet
381 * Status of operation
384 PCONNECTION_ENDPOINT Connection
;
385 PTDI_REQUEST_KERNEL Parameters
;
386 PTRANSPORT_CONTEXT TranContext
;
387 PIO_STACK_LOCATION IrpSp
;
390 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
392 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
394 /* Get associated connection endpoint file object. Quit if none exists */
396 TranContext
= IrpSp
->FileObject
->FsContext
;
398 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
399 Status
= STATUS_INVALID_PARAMETER
;
403 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
405 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
406 Status
= STATUS_INVALID_PARAMETER
;
410 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
412 Status
= DispPrepareIrpForCancel(TranContext
->Handle
.ConnectionContext
,
416 if (NT_SUCCESS(Status
)) {
418 TranContext
->Handle
.ConnectionContext
,
419 Parameters
->RequestConnectionInformation
,
420 Parameters
->ReturnConnectionInformation
,
421 DispDataRequestComplete
,
426 if (Status
!= STATUS_PENDING
) {
427 DispDataRequestComplete(Irp
, Status
, 0);
429 IoMarkIrpPending(Irp
);
431 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
437 NTSTATUS
DispTdiDisassociateAddress(
440 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
442 * Irp = Pointer to an I/O request packet
444 * Status of operation
447 PCONNECTION_ENDPOINT Connection
;
448 PTRANSPORT_CONTEXT TranContext
;
449 PIO_STACK_LOCATION IrpSp
;
451 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
453 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
455 /* Get associated connection endpoint file object. Quit if none exists */
457 TranContext
= IrpSp
->FileObject
->FsContext
;
459 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
460 return STATUS_INVALID_PARAMETER
;
463 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
465 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
466 return STATUS_INVALID_PARAMETER
;
469 /* NO-OP because we need the address to deallocate the port when the connection closes */
471 return STATUS_SUCCESS
;
475 NTSTATUS
DispTdiDisconnect(
478 * FUNCTION: TDI_DISCONNECT handler
480 * Irp = Pointer to an I/O request packet
482 * Status of operation
486 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
487 PCONNECTION_ENDPOINT Connection
;
488 PTRANSPORT_CONTEXT TranContext
;
489 PIO_STACK_LOCATION IrpSp
;
491 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
493 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
494 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
496 /* Get associated connection endpoint file object. Quit if none exists */
498 TranContext
= IrpSp
->FileObject
->FsContext
;
500 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
501 Status
= STATUS_INVALID_PARAMETER
;
505 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
507 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
508 Status
= STATUS_INVALID_PARAMETER
;
512 Status
= DispPrepareIrpForCancel
513 (TranContext
->Handle
.ConnectionContext
,
515 (PDRIVER_CANCEL
)DispCancelRequest
);
517 if (NT_SUCCESS(Status
))
519 Status
= TCPDisconnect(TranContext
->Handle
.ConnectionContext
,
520 DisReq
->RequestFlags
,
521 DisReq
->RequestSpecific
,
522 DisReq
->RequestConnectionInformation
,
523 DisReq
->ReturnConnectionInformation
,
524 DispDataRequestComplete
,
529 if (Status
!= STATUS_PENDING
) {
530 DispDataRequestComplete(Irp
, Status
, 0);
532 IoMarkIrpPending(Irp
);
534 TI_DbgPrint(MAX_TRACE
, ("TCP Disconnect 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
;
557 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
559 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
561 /* Get associated connection endpoint file object. Quit if none exists */
563 TranContext
= IrpSp
->FileObject
->FsContext
;
564 if (TranContext
== NULL
)
566 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
567 Status
= STATUS_INVALID_PARAMETER
;
571 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
572 if (Connection
== NULL
)
574 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
575 Status
= STATUS_INVALID_PARAMETER
;
579 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
581 Status
= DispPrepareIrpForCancel
582 (TranContext
->Handle
.ConnectionContext
,
584 (PDRIVER_CANCEL
)DispCancelListenRequest
);
586 LockObject(Connection
, &OldIrql
);
588 if (Connection
->AddressFile
== NULL
)
590 TI_DbgPrint(MID_TRACE
, ("No associated address file\n"));
591 UnlockObject(Connection
, OldIrql
);
592 Status
= STATUS_INVALID_PARAMETER
;
596 LockObjectAtDpcLevel(Connection
->AddressFile
);
598 /* Listening will require us to create a listening socket and store it in
599 * the address file. It will be signalled, and attempt to complete an irp
600 * when a new connection arrives. */
601 /* The important thing to note here is that the irp we'll complete belongs
602 * to the socket to be accepted onto, not the listener */
603 if( NT_SUCCESS(Status
) && !Connection
->AddressFile
->Listener
) {
604 Connection
->AddressFile
->Listener
=
605 TCPAllocateConnectionEndpoint( NULL
);
607 if( !Connection
->AddressFile
->Listener
)
608 Status
= STATUS_NO_MEMORY
;
610 if( NT_SUCCESS(Status
) ) {
611 ReferenceObject(Connection
->AddressFile
);
612 Connection
->AddressFile
->Listener
->AddressFile
=
613 Connection
->AddressFile
;
615 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
616 Connection
->AddressFile
->Family
,
618 Connection
->AddressFile
->Protocol
);
621 if( NT_SUCCESS(Status
) )
622 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
626 if( NT_SUCCESS(Status
) ) {
628 ( (PTDI_REQUEST
)Parameters
,
629 Connection
->AddressFile
->Listener
,
631 DispDataRequestComplete
,
635 UnlockObjectFromDpcLevel(Connection
->AddressFile
);
636 UnlockObject(Connection
, OldIrql
);
639 if (Status
!= STATUS_PENDING
) {
640 DispDataRequestComplete(Irp
, Status
, 0);
642 IoMarkIrpPending(Irp
);
644 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
650 NTSTATUS
DispTdiQueryInformation(
651 PDEVICE_OBJECT DeviceObject
,
654 * FUNCTION: TDI_QUERY_INFORMATION handler
656 * DeviceObject = Pointer to device object structure
657 * Irp = Pointer to an I/O request packet
659 * Status of operation
662 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
663 PTRANSPORT_CONTEXT TranContext
;
664 PIO_STACK_LOCATION IrpSp
;
666 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
668 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
669 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
671 TranContext
= IrpSp
->FileObject
->FsContext
;
673 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
674 return STATUS_INVALID_PARAMETER
;
677 switch (Parameters
->QueryType
)
679 case TDI_QUERY_ADDRESS_INFO
:
681 PTDI_ADDRESS_INFO AddressInfo
;
682 PADDRESS_FILE AddrFile
;
683 PTA_IP_ADDRESS Address
;
684 PCONNECTION_ENDPOINT Endpoint
= NULL
;
687 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
688 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
689 sizeof(TDI_ADDRESS_IP
))) {
690 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
691 return STATUS_BUFFER_TOO_SMALL
;
694 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
695 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
697 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
698 case TDI_TRANSPORT_ADDRESS_FILE
:
699 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
701 Address
->TAAddressCount
= 1;
702 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
703 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
704 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
705 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->Address
.Address
.IPv4Address
;
707 &Address
->Address
[0].Address
[0].sin_zero
,
708 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
709 return STATUS_SUCCESS
;
711 case TDI_CONNECTION_FILE
:
713 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
715 Address
->TAAddressCount
= 1;
716 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
717 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
718 Address
->Address
[0].Address
[0].sin_port
= Endpoint
->AddressFile
->Port
;
719 Address
->Address
[0].Address
[0].in_addr
= Endpoint
->AddressFile
->Address
.Address
.IPv4Address
;
721 &Address
->Address
[0].Address
[0].sin_zero
,
722 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
723 return STATUS_SUCCESS
;
726 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
727 return STATUS_INVALID_PARAMETER
;
731 case TDI_QUERY_CONNECTION_INFO
:
733 PTDI_CONNECTION_INFO ConnectionInfo
;
734 //PCONNECTION_ENDPOINT Endpoint;
736 if (MmGetMdlByteCount(Irp
->MdlAddress
) < sizeof(*ConnectionInfo
)) {
737 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
738 return STATUS_BUFFER_TOO_SMALL
;
741 ConnectionInfo
= (PTDI_CONNECTION_INFO
)
742 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
744 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
745 case TDI_CONNECTION_FILE
:
746 //Endpoint = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
747 RtlZeroMemory(ConnectionInfo
, sizeof(*ConnectionInfo
));
748 return STATUS_SUCCESS
;
751 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
752 return STATUS_INVALID_PARAMETER
;
756 case TDI_QUERY_MAX_DATAGRAM_INFO
:
758 PTDI_MAX_DATAGRAM_INFO MaxDatagramInfo
;
760 if (MmGetMdlByteCount(Irp
->MdlAddress
) < sizeof(*MaxDatagramInfo
)) {
761 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
762 return STATUS_BUFFER_TOO_SMALL
;
765 MaxDatagramInfo
= (PTDI_MAX_DATAGRAM_INFO
)
766 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
768 MaxDatagramInfo
->MaxDatagramSize
= 0xFFFF;
770 return STATUS_SUCCESS
;
774 return STATUS_NOT_IMPLEMENTED
;
778 NTSTATUS
DispTdiReceive(
781 * FUNCTION: TDI_RECEIVE handler
783 * Irp = Pointer to an I/O request packet
785 * Status of operation
788 PIO_STACK_LOCATION IrpSp
;
789 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
790 PTRANSPORT_CONTEXT TranContext
;
792 ULONG BytesReceived
= 0;
794 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
796 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
797 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
799 TranContext
= IrpSp
->FileObject
->FsContext
;
800 if (TranContext
== NULL
)
802 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
803 Status
= STATUS_INVALID_PARAMETER
;
807 if (TranContext
->Handle
.ConnectionContext
== NULL
)
809 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
810 Status
= STATUS_INVALID_PARAMETER
;
814 /* Initialize a receive request */
815 Status
= DispPrepareIrpForCancel
816 (TranContext
->Handle
.ConnectionContext
,
818 (PDRIVER_CANCEL
)DispCancelRequest
);
820 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
821 if (NT_SUCCESS(Status
))
823 Status
= TCPReceiveData(
824 TranContext
->Handle
.ConnectionContext
,
825 (PNDIS_BUFFER
)Irp
->MdlAddress
,
826 ReceiveInfo
->ReceiveLength
,
828 ReceiveInfo
->ReceiveFlags
,
829 DispDataRequestComplete
,
834 if (Status
!= STATUS_PENDING
) {
835 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
837 IoMarkIrpPending(Irp
);
839 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
845 NTSTATUS
DispTdiReceiveDatagram(
848 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
850 * Irp = Pointer to an I/O request packet
852 * Status of operation
855 PIO_STACK_LOCATION IrpSp
;
856 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
857 PTRANSPORT_CONTEXT TranContext
;
860 ULONG BytesReceived
= 0;
862 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
864 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
865 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
867 TranContext
= IrpSp
->FileObject
->FsContext
;
868 if (TranContext
== NULL
)
870 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
871 Status
= STATUS_INVALID_PARAMETER
;
875 /* Initialize a receive request */
876 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
877 Request
.RequestNotifyObject
= DispDataRequestComplete
;
878 Request
.RequestContext
= Irp
;
880 Status
= DispPrepareIrpForCancel(
881 IrpSp
->FileObject
->FsContext
,
883 (PDRIVER_CANCEL
)DispCancelRequest
);
885 if (NT_SUCCESS(Status
))
890 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
894 Status
= DGReceiveDatagram(
895 Request
.Handle
.AddressHandle
,
896 DgramInfo
->ReceiveDatagramInformation
,
898 DgramInfo
->ReceiveLength
,
899 DgramInfo
->ReceiveFlags
,
900 DgramInfo
->ReturnDatagramInformation
,
902 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
908 if (Status
!= STATUS_PENDING
) {
909 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
911 IoMarkIrpPending(Irp
);
913 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
919 NTSTATUS
DispTdiSend(
922 * FUNCTION: TDI_SEND handler
924 * Irp = Pointer to an I/O request packet
926 * Status of operation
929 PIO_STACK_LOCATION IrpSp
;
930 PTDI_REQUEST_KERNEL_SEND SendInfo
;
931 PTRANSPORT_CONTEXT TranContext
;
935 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
937 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
938 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
940 TranContext
= IrpSp
->FileObject
->FsContext
;
941 if (TranContext
== NULL
)
943 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
944 Status
= STATUS_INVALID_PARAMETER
;
948 if (TranContext
->Handle
.ConnectionContext
== NULL
)
950 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
951 Status
= STATUS_INVALID_PARAMETER
;
955 Status
= DispPrepareIrpForCancel(
956 IrpSp
->FileObject
->FsContext
,
958 (PDRIVER_CANCEL
)DispCancelRequest
);
960 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
961 if (NT_SUCCESS(Status
))
966 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
968 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
969 Status
= TCPSendData(
970 TranContext
->Handle
.ConnectionContext
,
972 SendInfo
->SendLength
,
975 DispDataRequestComplete
,
980 if (Status
!= STATUS_PENDING
) {
981 DispDataRequestComplete(Irp
, Status
, BytesSent
);
983 IoMarkIrpPending(Irp
);
985 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
991 NTSTATUS
DispTdiSendDatagram(
994 * FUNCTION: TDI_SEND_DATAGRAM handler
996 * Irp = Pointer to an I/O request packet
998 * Status of operation
1001 PIO_STACK_LOCATION IrpSp
;
1002 TDI_REQUEST Request
;
1003 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
1004 PTRANSPORT_CONTEXT TranContext
;
1007 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1009 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1010 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
1012 TranContext
= IrpSp
->FileObject
->FsContext
;
1013 if (TranContext
== NULL
)
1015 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
1016 Status
= STATUS_INVALID_PARAMETER
;
1020 /* Initialize a send request */
1021 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1022 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1023 Request
.RequestContext
= Irp
;
1025 Status
= DispPrepareIrpForCancel(
1026 IrpSp
->FileObject
->FsContext
,
1028 (PDRIVER_CANCEL
)DispCancelRequest
);
1030 if (NT_SUCCESS(Status
)) {
1034 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
1036 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
1040 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
1041 must be of type PTDI_ADDRESS_IP */
1042 TI_DbgPrint(MID_TRACE
,
1043 ("About to call send routine %x\n",
1044 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
1046 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
!= NULL
) )
1049 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
1050 Request
.Handle
.AddressHandle
,
1051 DgramInfo
->SendDatagramInformation
,
1055 Irp
->IoStatus
.Information
= DataUsed
;
1058 Status
= STATUS_UNSUCCESSFUL
;
1064 if (Status
!= STATUS_PENDING
) {
1065 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
1067 IoMarkIrpPending(Irp
);
1069 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
1075 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
1077 * FUNCTION: TDI_SET_EVENT_HANDER handler
1079 * Irp = Pointer to a I/O request packet
1081 * Status of operation
1084 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1085 PTRANSPORT_CONTEXT TranContext
;
1086 PIO_STACK_LOCATION IrpSp
;
1087 PADDRESS_FILE AddrFile
;
1091 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1093 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1095 /* Get associated address file object. Quit if none exists */
1097 TranContext
= IrpSp
->FileObject
->FsContext
;
1099 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1100 return STATUS_INVALID_PARAMETER
;
1103 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1105 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1106 return STATUS_INVALID_PARAMETER
;
1109 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1110 Status
= STATUS_SUCCESS
;
1112 LockObject(AddrFile
, &OldIrql
);
1114 /* Set the event handler. if an event handler is associated with
1115 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1116 If an event handler is not used it's flag is FALSE */
1117 switch (Parameters
->EventType
) {
1118 case TDI_EVENT_CONNECT
:
1119 if (!Parameters
->EventHandler
) {
1120 AddrFile
->ConnectHandlerContext
= NULL
;
1121 AddrFile
->RegisteredConnectHandler
= FALSE
;
1123 AddrFile
->ConnectHandler
=
1124 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1125 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1126 AddrFile
->RegisteredConnectHandler
= TRUE
;
1130 case TDI_EVENT_DISCONNECT
:
1131 if (!Parameters
->EventHandler
) {
1132 AddrFile
->DisconnectHandlerContext
= NULL
;
1133 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1135 AddrFile
->DisconnectHandler
=
1136 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1137 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1138 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1142 case TDI_EVENT_ERROR
:
1143 if (Parameters
->EventHandler
== NULL
) {
1144 AddrFile
->ErrorHandlerContext
= NULL
;
1145 AddrFile
->RegisteredErrorHandler
= FALSE
;
1147 AddrFile
->ErrorHandler
=
1148 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1149 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1150 AddrFile
->RegisteredErrorHandler
= TRUE
;
1154 case TDI_EVENT_RECEIVE
:
1155 if (Parameters
->EventHandler
== NULL
) {
1156 AddrFile
->ReceiveHandlerContext
= NULL
;
1157 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1159 AddrFile
->ReceiveHandler
=
1160 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1161 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1162 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1166 case TDI_EVENT_RECEIVE_DATAGRAM
:
1167 if (Parameters
->EventHandler
== NULL
) {
1168 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1169 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1171 AddrFile
->ReceiveDatagramHandler
=
1172 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1173 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1174 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1178 case TDI_EVENT_RECEIVE_EXPEDITED
:
1179 if (Parameters
->EventHandler
== NULL
) {
1180 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1181 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1183 AddrFile
->ExpeditedReceiveHandler
=
1184 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1185 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1186 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1190 case TDI_EVENT_CHAINED_RECEIVE
:
1191 if (Parameters
->EventHandler
== NULL
) {
1192 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1193 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1195 AddrFile
->ChainedReceiveHandler
=
1196 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1197 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1198 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1202 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1203 if (Parameters
->EventHandler
== NULL
) {
1204 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1205 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1207 AddrFile
->ChainedReceiveDatagramHandler
=
1208 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1209 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1210 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1214 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1215 if (Parameters
->EventHandler
== NULL
) {
1216 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1217 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1219 AddrFile
->ChainedReceiveExpeditedHandler
=
1220 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1221 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1222 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1227 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1228 Parameters
->EventType
));
1230 Status
= STATUS_INVALID_PARAMETER
;
1233 UnlockObject(AddrFile
, OldIrql
);
1239 NTSTATUS
DispTdiSetInformation(
1242 * FUNCTION: TDI_SET_INFORMATION handler
1244 * Irp = Pointer to an I/O request packet
1246 * Status of operation
1249 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1251 return STATUS_NOT_IMPLEMENTED
;
1255 VOID
DispTdiQueryInformationExComplete(
1260 * FUNCTION: Completes a TDI QueryInformationEx request
1262 * Context = Pointer to the IRP for the request
1263 * Status = TDI status of the request
1264 * ByteCount = Number of bytes returned in output buffer
1267 PTI_QUERY_CONTEXT QueryContext
;
1269 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1270 if (NT_SUCCESS(Status
)) {
1271 CopyBufferToBufferChain(
1272 QueryContext
->InputMdl
,
1273 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1274 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1278 MmUnlockPages(QueryContext
->InputMdl
);
1279 IoFreeMdl(QueryContext
->InputMdl
);
1280 if( QueryContext
->OutputMdl
) {
1281 MmUnlockPages(QueryContext
->OutputMdl
);
1282 IoFreeMdl(QueryContext
->OutputMdl
);
1285 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1286 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1288 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1292 NTSTATUS
DispTdiQueryInformationEx(
1294 PIO_STACK_LOCATION IrpSp
)
1296 * FUNCTION: TDI QueryInformationEx handler
1298 * Irp = Pointer to I/O request packet
1299 * IrpSp = Pointer to current stack location of Irp
1301 * Status of operation
1304 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1305 PTRANSPORT_CONTEXT TranContext
;
1306 PTI_QUERY_CONTEXT QueryContext
;
1308 TDI_REQUEST Request
;
1310 UINT InputBufferLength
;
1311 UINT OutputBufferLength
;
1312 BOOLEAN InputMdlLocked
= FALSE
;
1313 BOOLEAN OutputMdlLocked
= FALSE
;
1314 PMDL InputMdl
= NULL
;
1315 PMDL OutputMdl
= NULL
;
1316 NTSTATUS Status
= STATUS_SUCCESS
;
1318 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1320 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1322 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
1323 case TDI_TRANSPORT_ADDRESS_FILE
:
1324 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1327 case TDI_CONNECTION_FILE
:
1328 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1331 case TDI_CONTROL_CHANNEL_FILE
:
1332 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1336 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1337 return STATUS_INVALID_PARAMETER
;
1340 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1341 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1343 /* Validate parameters */
1344 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1345 (OutputBufferLength
!= 0)) {
1347 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1348 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1349 OutputBuffer
= Irp
->UserBuffer
;
1351 QueryContext
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
), QUERY_CONTEXT_TAG
);
1354 InputMdl
= IoAllocateMdl(InputBuffer
,
1355 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1358 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1359 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1361 if (InputMdl
&& OutputMdl
) {
1363 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1366 InputMdlLocked
= TRUE
;
1368 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1371 OutputMdlLocked
= TRUE
;
1373 RtlCopyMemory(&QueryContext
->QueryInfo
,
1374 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1376 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1377 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1378 Status
= _SEH2_GetExceptionCode();
1381 if (NT_SUCCESS(Status
)) {
1382 Size
= MmGetMdlByteCount(OutputMdl
);
1384 QueryContext
->Irp
= Irp
;
1385 QueryContext
->InputMdl
= InputMdl
;
1386 QueryContext
->OutputMdl
= OutputMdl
;
1388 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1389 Request
.RequestContext
= QueryContext
;
1390 Status
= InfoTdiQueryInformationEx(&Request
,
1391 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1392 &Size
, &QueryContext
->QueryInfo
.Context
);
1393 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1395 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1400 /* An error occurred if we get here */
1404 MmUnlockPages(InputMdl
);
1405 IoFreeMdl(InputMdl
);
1409 if (OutputMdlLocked
)
1410 MmUnlockPages(OutputMdl
);
1411 IoFreeMdl(OutputMdl
);
1414 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1416 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1417 } else if( InputBufferLength
==
1418 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1419 /* Handle the case where the user is probing the buffer for length */
1420 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1421 InputBufferLength
, OutputBufferLength
));
1422 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1423 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1427 QueryContext
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
), QUERY_CONTEXT_TAG
);
1428 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1431 InputMdl
= IoAllocateMdl(InputBuffer
,
1432 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1435 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1438 InputMdlLocked
= TRUE
;
1439 Status
= STATUS_SUCCESS
;
1440 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1441 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1442 Status
= _SEH2_GetExceptionCode();
1445 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1446 if( InputMdl
) IoFreeMdl( InputMdl
);
1447 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1451 RtlCopyMemory(&QueryContext
->QueryInfo
,
1452 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1454 QueryContext
->Irp
= Irp
;
1455 QueryContext
->InputMdl
= InputMdl
;
1456 QueryContext
->OutputMdl
= NULL
;
1458 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1459 Request
.RequestContext
= QueryContext
;
1460 Status
= InfoTdiQueryInformationEx(&Request
,
1461 &QueryContext
->QueryInfo
.ID
,
1464 &QueryContext
->QueryInfo
.Context
);
1465 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1466 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1467 } else Status
= STATUS_INVALID_PARAMETER
;
1469 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1475 NTSTATUS
DispTdiSetInformationEx(
1477 PIO_STACK_LOCATION IrpSp
)
1479 * FUNCTION: TDI SetInformationEx handler
1481 * Irp = Pointer to I/O request packet
1482 * IrpSp = Pointer to current stack location of Irp
1484 * Status of operation
1487 PTRANSPORT_CONTEXT TranContext
;
1488 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1489 TDI_REQUEST Request
;
1492 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1494 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1495 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1497 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
1498 case TDI_TRANSPORT_ADDRESS_FILE
:
1499 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1502 case TDI_CONNECTION_FILE
:
1503 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1506 case TDI_CONTROL_CHANNEL_FILE
:
1507 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1511 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1512 Irp
->IoStatus
.Information
= 0;
1514 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1516 return Irp
->IoStatus
.Status
;
1519 Request
.RequestNotifyObject
= NULL
;
1520 Request
.RequestContext
= NULL
;
1522 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1523 &Info
->Buffer
, Info
->BufferSize
);
1528 /* TODO: Support multiple addresses per interface.
1529 * For now just set the nte context to the interface index.
1531 * Later on, create an NTE context and NTE instance
1534 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1535 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1536 PIP_SET_ADDRESS IpAddrChange
=
1537 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1540 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1541 IpAddrChange
->NteIndex
));
1543 ForEachInterface(IF
) {
1544 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1546 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1547 Status
= STATUS_DUPLICATE_OBJECTID
;
1550 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1551 IPRemoveInterfaceRoute( IF
);
1553 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1554 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1556 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1557 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1559 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1560 IF
->Broadcast
.Address
.IPv4Address
=
1561 IF
->Unicast
.Address
.IPv4Address
|
1562 ~IF
->Netmask
.Address
.IPv4Address
;
1564 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1565 IF
->Unicast
.Address
.IPv4Address
));
1566 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1567 IF
->Netmask
.Address
.IPv4Address
));
1569 IPAddInterfaceRoute( IF
);
1571 IpAddrChange
->Address
= IF
->Index
;
1572 Status
= STATUS_SUCCESS
;
1573 Irp
->IoStatus
.Information
= IF
->Index
;
1578 Irp
->IoStatus
.Status
= Status
;
1582 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1583 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1584 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1587 ForEachInterface(IF
) {
1588 if( IF
->Index
== *NteIndex
) {
1589 IPRemoveInterfaceRoute( IF
);
1590 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1591 IF
->Unicast
.Address
.IPv4Address
= 0;
1593 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1594 IF
->Netmask
.Address
.IPv4Address
= 0;
1596 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1597 IF
->Broadcast
.Address
.IPv4Address
= 0;
1599 Status
= STATUS_SUCCESS
;
1603 Irp
->IoStatus
.Status
= Status
;