2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: tcpip/dispatch.h
5 * PURPOSE: TDI dispatch routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/08-2000 Created
9 * TODO: Validate device object in all dispatch routines
13 #include <pseh/pseh2.h>
16 NTSTATUS
IRPFinish( PIRP Irp
, NTSTATUS Status
) {
19 Irp
->IoStatus
.Status
= Status
;
21 if( Status
== STATUS_PENDING
)
22 IoMarkIrpPending( Irp
);
24 IoAcquireCancelSpinLock(&OldIrql
);
25 (void)IoSetCancelRoutine( Irp
, NULL
);
26 IoReleaseCancelSpinLock(OldIrql
);
28 IoCompleteRequest( Irp
, IO_NETWORK_INCREMENT
);
34 NTSTATUS
DispPrepareIrpForCancel(
35 PTRANSPORT_CONTEXT Context
,
37 PDRIVER_CANCEL CancelRoutine
)
39 * FUNCTION: Prepare an IRP for cancellation
41 * Context = Pointer to context information
42 * Irp = Pointer to an I/O request packet
43 * CancelRoutine = Routine to be called when I/O request is cancelled
49 PIO_STACK_LOCATION IrpSp
;
50 PTRANSPORT_CONTEXT TransContext
;
52 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
54 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
55 TransContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
57 IoAcquireCancelSpinLock(&OldIrql
);
59 if (!Irp
->Cancel
&& !TransContext
->CancelIrps
) {
60 (void)IoSetCancelRoutine(Irp
, CancelRoutine
);
61 IoReleaseCancelSpinLock(OldIrql
);
63 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
65 return STATUS_SUCCESS
;
68 /* IRP has already been cancelled */
70 IoReleaseCancelSpinLock(OldIrql
);
72 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
73 Irp
->IoStatus
.Information
= 0;
75 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
77 return Irp
->IoStatus
.Status
;
80 VOID
DispDataRequestComplete(
85 * FUNCTION: Completes a send/receive IRP
87 * Context = Pointer to context information (IRP)
88 * Status = Status of the request
89 * Count = Number of bytes sent or received
93 PIO_STACK_LOCATION IrpSp
;
96 TI_DbgPrint(DEBUG_IRP
, ("Called for irp %x (%x, %d).\n",
97 Context
, Status
, Count
));
100 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
102 IoAcquireCancelSpinLock(&OldIrql
);
104 (void)IoSetCancelRoutine(Irp
, NULL
);
106 IoReleaseCancelSpinLock(OldIrql
);
108 Irp
->IoStatus
.Status
= Status
;
109 Irp
->IoStatus
.Information
= Count
;
111 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
112 Irp
->IoStatus
.Status
));
113 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
114 Irp
->IoStatus
.Information
));
115 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
117 IRPFinish(Irp
, Status
);
119 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
122 VOID NTAPI
DispCancelRequest(
123 PDEVICE_OBJECT Device
,
126 * FUNCTION: Cancels an IRP
128 * Device = Pointer to device object
129 * Irp = Pointer to an I/O request packet
132 PIO_STACK_LOCATION IrpSp
;
133 PTRANSPORT_CONTEXT TranContext
;
134 PFILE_OBJECT FileObject
;
137 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
139 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
141 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
142 FileObject
= IrpSp
->FileObject
;
143 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
144 MinorFunction
= IrpSp
->MinorFunction
;
146 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
148 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
149 Irp
->IoStatus
.Information
= 0;
153 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
156 /* Try canceling the request */
157 switch(MinorFunction
) {
160 TCPRemoveIRP( TranContext
->Handle
.ConnectionContext
, Irp
);
163 case TDI_SEND_DATAGRAM
:
164 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
165 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
169 DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
172 case TDI_RECEIVE_DATAGRAM
:
173 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
174 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
178 DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
182 TCPRemoveIRP(TranContext
->Handle
.ConnectionContext
, Irp
);
186 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
190 IRPFinish(Irp
, STATUS_CANCELLED
);
192 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
196 VOID NTAPI
DispCancelListenRequest(
197 PDEVICE_OBJECT Device
,
200 * FUNCTION: Cancels a listen IRP
202 * Device = Pointer to device object
203 * Irp = Pointer to an I/O request packet
206 PIO_STACK_LOCATION IrpSp
;
207 PTRANSPORT_CONTEXT TranContext
;
208 PFILE_OBJECT FileObject
;
209 PCONNECTION_ENDPOINT Connection
;
210 /*NTSTATUS Status = STATUS_SUCCESS;*/
212 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
214 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
216 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
217 FileObject
= IrpSp
->FileObject
;
218 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
219 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
221 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
225 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
228 /* Try canceling the request */
229 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
231 TCPRemoveIRP(Connection
, Irp
);
233 TCPAbortListenForSocket(Connection
->AddressFile
->Listener
,
236 Irp
->IoStatus
.Information
= 0;
237 IRPFinish(Irp
, STATUS_CANCELLED
);
239 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
243 NTSTATUS
DispTdiAccept(
246 * FUNCTION: TDI_ACCEPT handler
248 * Irp = Pointer to an I/O request packet
250 * Status of operation
253 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
255 return STATUS_NOT_IMPLEMENTED
;
259 NTSTATUS
DispTdiAssociateAddress(
262 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
264 * Irp = Pointer to an I/O request packet
266 * Status of operation
269 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
270 PTRANSPORT_CONTEXT TranContext
;
271 PIO_STACK_LOCATION IrpSp
;
272 PCONNECTION_ENDPOINT Connection
;
273 PFILE_OBJECT FileObject
;
274 PADDRESS_FILE AddrFile
= NULL
;
278 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
280 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
282 /* Get associated connection endpoint file object. Quit if none exists */
284 TranContext
= IrpSp
->FileObject
->FsContext
;
286 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
287 return STATUS_INVALID_PARAMETER
;
290 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
292 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
293 return STATUS_INVALID_PARAMETER
;
296 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
298 Status
= ObReferenceObjectByHandle(
299 Parameters
->AddressHandle
,
305 if (!NT_SUCCESS(Status
)) {
306 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
307 Parameters
->AddressHandle
, Status
));
308 return STATUS_INVALID_PARAMETER
;
311 KeAcquireSpinLock(&Connection
->Lock
, &OldIrql
);
313 if (Connection
->AddressFile
) {
314 ObDereferenceObject(FileObject
);
315 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
316 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
317 return STATUS_INVALID_PARAMETER
;
320 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
321 ObDereferenceObject(FileObject
);
322 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
323 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
324 FileObject
->FsContext2
));
325 return STATUS_INVALID_PARAMETER
;
328 /* Get associated address file object. Quit if none exists */
330 TranContext
= FileObject
->FsContext
;
332 ObDereferenceObject(FileObject
);
333 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
334 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
335 return STATUS_INVALID_PARAMETER
;
338 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
340 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
341 ObDereferenceObject(FileObject
);
342 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
343 return STATUS_INVALID_PARAMETER
;
346 KeAcquireSpinLockAtDpcLevel(&AddrFile
->Lock
);
348 Connection
->AddressFile
= AddrFile
;
350 /* Add connection endpoint to the address file */
351 AddrFile
->Connection
= Connection
;
353 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
354 ObDereferenceObject(FileObject
);
356 KeReleaseSpinLockFromDpcLevel(&AddrFile
->Lock
);
357 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
363 NTSTATUS
DispTdiConnect(
366 * FUNCTION: TDI_CONNECT handler
368 * Irp = Pointer to an I/O request packet
370 * Status of operation
373 PCONNECTION_ENDPOINT Connection
;
374 PTDI_REQUEST_KERNEL Parameters
;
375 PTRANSPORT_CONTEXT TranContext
;
376 PIO_STACK_LOCATION IrpSp
;
379 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
381 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
383 /* Get associated connection endpoint file object. Quit if none exists */
385 TranContext
= IrpSp
->FileObject
->FsContext
;
387 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
388 Status
= STATUS_INVALID_PARAMETER
;
392 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
394 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
395 Status
= STATUS_INVALID_PARAMETER
;
399 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
401 Status
= DispPrepareIrpForCancel(TranContext
->Handle
.ConnectionContext
,
405 if (NT_SUCCESS(Status
)) {
407 TranContext
->Handle
.ConnectionContext
,
408 Parameters
->RequestConnectionInformation
,
409 Parameters
->ReturnConnectionInformation
,
410 DispDataRequestComplete
,
415 if (Status
!= STATUS_PENDING
) {
416 DispDataRequestComplete(Irp
, Status
, 0);
418 IoMarkIrpPending(Irp
);
420 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
426 NTSTATUS
DispTdiDisassociateAddress(
429 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
431 * Irp = Pointer to an I/O request packet
433 * Status of operation
436 PCONNECTION_ENDPOINT Connection
;
437 PTRANSPORT_CONTEXT TranContext
;
438 PIO_STACK_LOCATION IrpSp
;
441 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
443 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
445 /* Get associated connection endpoint file object. Quit if none exists */
447 TranContext
= IrpSp
->FileObject
->FsContext
;
449 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
450 return STATUS_INVALID_PARAMETER
;
453 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
455 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
456 return STATUS_INVALID_PARAMETER
;
459 KeAcquireSpinLock(&Connection
->Lock
, &OldIrql
);
461 if (!Connection
->AddressFile
) {
462 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
463 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
464 return STATUS_INVALID_PARAMETER
;
467 KeAcquireSpinLockAtDpcLevel(&Connection
->AddressFile
->Lock
);
469 /* Remove this connection from the address file */
470 Connection
->AddressFile
->Connection
= NULL
;
472 KeReleaseSpinLockFromDpcLevel(&Connection
->AddressFile
->Lock
);
474 /* Remove the address file from this connection */
475 Connection
->AddressFile
= NULL
;
477 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
479 return STATUS_SUCCESS
;
483 NTSTATUS
DispTdiDisconnect(
486 * FUNCTION: TDI_DISCONNECT handler
488 * Irp = Pointer to an I/O request packet
490 * Status of operation
494 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
495 PCONNECTION_ENDPOINT Connection
;
496 PTRANSPORT_CONTEXT TranContext
;
497 PIO_STACK_LOCATION IrpSp
;
499 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
501 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
502 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
504 /* Get associated connection endpoint file object. Quit if none exists */
506 TranContext
= IrpSp
->FileObject
->FsContext
;
508 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
509 Status
= STATUS_INVALID_PARAMETER
;
513 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
515 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
516 Status
= STATUS_INVALID_PARAMETER
;
520 Status
= TCPDisconnect(
521 TranContext
->Handle
.ConnectionContext
,
522 DisReq
->RequestFlags
,
523 DisReq
->RequestConnectionInformation
,
524 DisReq
->ReturnConnectionInformation
,
525 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 KeAcquireSpinLock(&Connection
->Lock
, &OldIrql
);
588 if (Connection
->AddressFile
== NULL
)
590 TI_DbgPrint(MID_TRACE
, ("No associated address file\n"));
591 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
592 Status
= STATUS_INVALID_PARAMETER
;
596 KeAcquireSpinLockAtDpcLevel(&Connection
->AddressFile
->Lock
);
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 Connection
->AddressFile
->Listener
->AddressFile
=
612 Connection
->AddressFile
;
614 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
615 Connection
->AddressFile
->Family
,
617 Connection
->AddressFile
->Protocol
);
620 if( NT_SUCCESS(Status
) )
621 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
625 if( NT_SUCCESS(Status
) ) {
627 ( (PTDI_REQUEST
)Parameters
,
628 Connection
->AddressFile
->Listener
,
630 DispDataRequestComplete
,
634 KeReleaseSpinLockFromDpcLevel(&Connection
->AddressFile
->Lock
);
635 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
638 if (Status
!= STATUS_PENDING
) {
639 DispDataRequestComplete(Irp
, Status
, 0);
641 IoMarkIrpPending(Irp
);
643 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
649 NTSTATUS
DispTdiQueryInformation(
650 PDEVICE_OBJECT DeviceObject
,
653 * FUNCTION: TDI_QUERY_INFORMATION handler
655 * DeviceObject = Pointer to device object structure
656 * Irp = Pointer to an I/O request packet
658 * Status of operation
661 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
662 PTRANSPORT_CONTEXT TranContext
;
663 PIO_STACK_LOCATION IrpSp
;
665 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
667 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
668 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
670 TranContext
= IrpSp
->FileObject
->FsContext
;
672 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
673 return STATUS_INVALID_PARAMETER
;
676 switch (Parameters
->QueryType
)
678 case TDI_QUERY_ADDRESS_INFO
:
680 PTDI_ADDRESS_INFO AddressInfo
;
681 PADDRESS_FILE AddrFile
;
682 PTA_IP_ADDRESS Address
;
683 PCONNECTION_ENDPOINT Endpoint
= NULL
;
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_TOO_SMALL
;
693 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
694 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
696 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
697 case TDI_TRANSPORT_ADDRESS_FILE
:
698 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
700 Address
->TAAddressCount
= 1;
701 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
702 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
703 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
704 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->Address
.Address
.IPv4Address
;
706 &Address
->Address
[0].Address
[0].sin_zero
,
707 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
708 return STATUS_SUCCESS
;
710 case TDI_CONNECTION_FILE
:
712 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
714 &Address
->Address
[0].Address
[0].sin_zero
,
715 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
716 return TCPGetSockAddress( Endpoint
, (PTRANSPORT_ADDRESS
)Address
, FALSE
);
719 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
720 return STATUS_INVALID_PARAMETER
;
724 case TDI_QUERY_CONNECTION_INFO
:
726 PTDI_CONNECTION_INFORMATION AddressInfo
;
727 PADDRESS_FILE AddrFile
;
728 PCONNECTION_ENDPOINT Endpoint
= NULL
;
730 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
731 (FIELD_OFFSET(TDI_CONNECTION_INFORMATION
, RemoteAddress
) +
733 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small (ptr).\n"));
734 return STATUS_BUFFER_TOO_SMALL
;
737 AddressInfo
= (PTDI_CONNECTION_INFORMATION
)
738 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
740 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
741 case TDI_TRANSPORT_ADDRESS_FILE
:
742 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
743 Endpoint
= AddrFile
? AddrFile
->Connection
: NULL
;
746 case TDI_CONNECTION_FILE
:
748 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
752 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
753 return STATUS_INVALID_PARAMETER
;
757 TI_DbgPrint(MID_TRACE
, ("No connection object.\n"));
758 return STATUS_INVALID_PARAMETER
;
761 return TCPGetSockAddress( Endpoint
, AddressInfo
->RemoteAddress
, TRUE
);
765 return STATUS_NOT_IMPLEMENTED
;
769 NTSTATUS
DispTdiReceive(
772 * FUNCTION: TDI_RECEIVE handler
774 * Irp = Pointer to an I/O request packet
776 * Status of operation
779 PIO_STACK_LOCATION IrpSp
;
780 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
781 PTRANSPORT_CONTEXT TranContext
;
783 ULONG BytesReceived
= 0;
785 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
787 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
788 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
790 TranContext
= IrpSp
->FileObject
->FsContext
;
791 if (TranContext
== NULL
)
793 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
794 Status
= STATUS_INVALID_PARAMETER
;
798 if (TranContext
->Handle
.ConnectionContext
== NULL
)
800 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
801 Status
= STATUS_INVALID_PARAMETER
;
805 /* Initialize a receive request */
806 Status
= DispPrepareIrpForCancel
807 (TranContext
->Handle
.ConnectionContext
,
809 (PDRIVER_CANCEL
)DispCancelRequest
);
811 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
812 if (NT_SUCCESS(Status
))
814 Status
= TCPReceiveData(
815 TranContext
->Handle
.ConnectionContext
,
816 (PNDIS_BUFFER
)Irp
->MdlAddress
,
817 ReceiveInfo
->ReceiveLength
,
819 ReceiveInfo
->ReceiveFlags
,
820 DispDataRequestComplete
,
825 if (Status
!= STATUS_PENDING
) {
826 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
828 IoMarkIrpPending(Irp
);
830 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
836 NTSTATUS
DispTdiReceiveDatagram(
839 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
841 * Irp = Pointer to an I/O request packet
843 * Status of operation
846 PIO_STACK_LOCATION IrpSp
;
847 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
848 PTRANSPORT_CONTEXT TranContext
;
851 ULONG BytesReceived
= 0;
853 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
855 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
856 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
858 TranContext
= IrpSp
->FileObject
->FsContext
;
859 if (TranContext
== NULL
)
861 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
862 Status
= STATUS_INVALID_PARAMETER
;
866 /* Initialize a receive request */
867 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
868 Request
.RequestNotifyObject
= DispDataRequestComplete
;
869 Request
.RequestContext
= Irp
;
871 Status
= DispPrepareIrpForCancel(
872 IrpSp
->FileObject
->FsContext
,
874 (PDRIVER_CANCEL
)DispCancelRequest
);
876 if (NT_SUCCESS(Status
))
881 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
885 Status
= DGReceiveDatagram(
886 Request
.Handle
.AddressHandle
,
887 DgramInfo
->ReceiveDatagramInformation
,
889 DgramInfo
->ReceiveLength
,
890 DgramInfo
->ReceiveFlags
,
891 DgramInfo
->ReturnDatagramInformation
,
893 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
899 if (Status
!= STATUS_PENDING
) {
900 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
902 IoMarkIrpPending(Irp
);
904 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
910 NTSTATUS
DispTdiSend(
913 * FUNCTION: TDI_SEND handler
915 * Irp = Pointer to an I/O request packet
917 * Status of operation
920 PIO_STACK_LOCATION IrpSp
;
921 PTDI_REQUEST_KERNEL_SEND SendInfo
;
922 PTRANSPORT_CONTEXT TranContext
;
926 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
928 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
929 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
931 TranContext
= IrpSp
->FileObject
->FsContext
;
932 if (TranContext
== NULL
)
934 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
935 Status
= STATUS_INVALID_PARAMETER
;
939 if (TranContext
->Handle
.ConnectionContext
== NULL
)
941 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
942 Status
= STATUS_INVALID_PARAMETER
;
946 Status
= DispPrepareIrpForCancel(
947 IrpSp
->FileObject
->FsContext
,
949 (PDRIVER_CANCEL
)DispCancelRequest
);
951 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
952 if (NT_SUCCESS(Status
))
957 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
959 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
960 Status
= TCPSendData(
961 TranContext
->Handle
.ConnectionContext
,
963 SendInfo
->SendLength
,
966 DispDataRequestComplete
,
971 if (Status
!= STATUS_PENDING
) {
972 DispDataRequestComplete(Irp
, Status
, BytesSent
);
974 IoMarkIrpPending(Irp
);
976 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
982 NTSTATUS
DispTdiSendDatagram(
985 * FUNCTION: TDI_SEND_DATAGRAM handler
987 * Irp = Pointer to an I/O request packet
989 * Status of operation
992 PIO_STACK_LOCATION IrpSp
;
994 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
995 PTRANSPORT_CONTEXT TranContext
;
998 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1000 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1001 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
1003 TranContext
= IrpSp
->FileObject
->FsContext
;
1004 if (TranContext
== NULL
)
1006 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
1007 Status
= STATUS_INVALID_PARAMETER
;
1011 /* Initialize a send request */
1012 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1013 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1014 Request
.RequestContext
= Irp
;
1016 Status
= DispPrepareIrpForCancel(
1017 IrpSp
->FileObject
->FsContext
,
1019 (PDRIVER_CANCEL
)DispCancelRequest
);
1021 if (NT_SUCCESS(Status
)) {
1025 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
1027 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
1031 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
1032 must be of type PTDI_ADDRESS_IP */
1033 TI_DbgPrint(MID_TRACE
,
1034 ("About to call send routine %x\n",
1035 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
1037 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
!= NULL
) )
1038 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
1039 Request
.Handle
.AddressHandle
,
1040 DgramInfo
->SendDatagramInformation
,
1043 &Irp
->IoStatus
.Information
);
1045 Status
= STATUS_UNSUCCESSFUL
;
1051 if (Status
!= STATUS_PENDING
) {
1052 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
1054 IoMarkIrpPending(Irp
);
1056 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
1062 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
1064 * FUNCTION: TDI_SET_EVENT_HANDER handler
1066 * Irp = Pointer to a I/O request packet
1068 * Status of operation
1071 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1072 PTRANSPORT_CONTEXT TranContext
;
1073 PIO_STACK_LOCATION IrpSp
;
1074 PADDRESS_FILE AddrFile
;
1078 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1080 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1082 /* Get associated address file object. Quit if none exists */
1084 TranContext
= IrpSp
->FileObject
->FsContext
;
1086 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1087 return STATUS_INVALID_PARAMETER
;
1090 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1092 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1093 return STATUS_INVALID_PARAMETER
;
1096 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1097 Status
= STATUS_SUCCESS
;
1099 KeAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
1101 /* Set the event handler. if an event handler is associated with
1102 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1103 If an event handler is not used it's flag is FALSE */
1104 switch (Parameters
->EventType
) {
1105 case TDI_EVENT_CONNECT
:
1106 if (!Parameters
->EventHandler
) {
1107 AddrFile
->ConnectHandlerContext
= NULL
;
1108 AddrFile
->RegisteredConnectHandler
= FALSE
;
1110 AddrFile
->ConnectHandler
=
1111 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1112 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1113 AddrFile
->RegisteredConnectHandler
= TRUE
;
1117 case TDI_EVENT_DISCONNECT
:
1118 if (!Parameters
->EventHandler
) {
1119 AddrFile
->DisconnectHandlerContext
= NULL
;
1120 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1122 AddrFile
->DisconnectHandler
=
1123 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1124 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1125 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1129 case TDI_EVENT_ERROR
:
1130 if (Parameters
->EventHandler
== NULL
) {
1131 AddrFile
->ErrorHandlerContext
= NULL
;
1132 AddrFile
->RegisteredErrorHandler
= FALSE
;
1134 AddrFile
->ErrorHandler
=
1135 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1136 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1137 AddrFile
->RegisteredErrorHandler
= TRUE
;
1141 case TDI_EVENT_RECEIVE
:
1142 if (Parameters
->EventHandler
== NULL
) {
1143 AddrFile
->ReceiveHandlerContext
= NULL
;
1144 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1146 AddrFile
->ReceiveHandler
=
1147 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1148 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1149 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1153 case TDI_EVENT_RECEIVE_DATAGRAM
:
1154 if (Parameters
->EventHandler
== NULL
) {
1155 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1156 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1158 AddrFile
->ReceiveDatagramHandler
=
1159 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1160 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1161 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1165 case TDI_EVENT_RECEIVE_EXPEDITED
:
1166 if (Parameters
->EventHandler
== NULL
) {
1167 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1168 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1170 AddrFile
->ExpeditedReceiveHandler
=
1171 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1172 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1173 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1177 case TDI_EVENT_CHAINED_RECEIVE
:
1178 if (Parameters
->EventHandler
== NULL
) {
1179 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1180 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1182 AddrFile
->ChainedReceiveHandler
=
1183 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1184 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1185 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1189 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1190 if (Parameters
->EventHandler
== NULL
) {
1191 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1192 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1194 AddrFile
->ChainedReceiveDatagramHandler
=
1195 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1196 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1197 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1201 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1202 if (Parameters
->EventHandler
== NULL
) {
1203 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1204 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1206 AddrFile
->ChainedReceiveExpeditedHandler
=
1207 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1208 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1209 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1214 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1215 Parameters
->EventType
));
1217 Status
= STATUS_INVALID_PARAMETER
;
1220 KeReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1226 NTSTATUS
DispTdiSetInformation(
1229 * FUNCTION: TDI_SET_INFORMATION handler
1231 * Irp = Pointer to an I/O request packet
1233 * Status of operation
1236 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1238 return STATUS_NOT_IMPLEMENTED
;
1242 VOID
DispTdiQueryInformationExComplete(
1247 * FUNCTION: Completes a TDI QueryInformationEx request
1249 * Context = Pointer to the IRP for the request
1250 * Status = TDI status of the request
1251 * ByteCount = Number of bytes returned in output buffer
1254 PTI_QUERY_CONTEXT QueryContext
;
1256 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1257 if (NT_SUCCESS(Status
)) {
1258 CopyBufferToBufferChain(
1259 QueryContext
->InputMdl
,
1260 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1261 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1265 MmUnlockPages(QueryContext
->InputMdl
);
1266 IoFreeMdl(QueryContext
->InputMdl
);
1267 if( QueryContext
->OutputMdl
) {
1268 MmUnlockPages(QueryContext
->OutputMdl
);
1269 IoFreeMdl(QueryContext
->OutputMdl
);
1272 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1273 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1275 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1279 NTSTATUS
DispTdiQueryInformationEx(
1281 PIO_STACK_LOCATION IrpSp
)
1283 * FUNCTION: TDI QueryInformationEx handler
1285 * Irp = Pointer to I/O request packet
1286 * IrpSp = Pointer to current stack location of Irp
1288 * Status of operation
1291 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1292 PTRANSPORT_CONTEXT TranContext
;
1293 PTI_QUERY_CONTEXT QueryContext
;
1295 TDI_REQUEST Request
;
1297 UINT InputBufferLength
;
1298 UINT OutputBufferLength
;
1299 BOOLEAN InputMdlLocked
= FALSE
;
1300 BOOLEAN OutputMdlLocked
= FALSE
;
1301 PMDL InputMdl
= NULL
;
1302 PMDL OutputMdl
= NULL
;
1303 NTSTATUS Status
= STATUS_SUCCESS
;
1305 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1307 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1309 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1310 case TDI_TRANSPORT_ADDRESS_FILE
:
1311 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1314 case TDI_CONNECTION_FILE
:
1315 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1318 case TDI_CONTROL_CHANNEL_FILE
:
1319 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1323 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1324 return STATUS_INVALID_PARAMETER
;
1327 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1328 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1330 /* Validate parameters */
1331 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1332 (OutputBufferLength
!= 0)) {
1334 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1335 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1336 OutputBuffer
= Irp
->UserBuffer
;
1338 QueryContext
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
), QUERY_CONTEXT_TAG
);
1341 InputMdl
= IoAllocateMdl(InputBuffer
,
1342 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1345 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1346 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1348 if (InputMdl
&& OutputMdl
) {
1350 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1353 InputMdlLocked
= TRUE
;
1355 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1358 OutputMdlLocked
= TRUE
;
1360 RtlCopyMemory(&QueryContext
->QueryInfo
,
1361 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1363 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1364 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1365 Status
= _SEH2_GetExceptionCode();
1368 if (NT_SUCCESS(Status
)) {
1369 Size
= MmGetMdlByteCount(OutputMdl
);
1371 QueryContext
->Irp
= Irp
;
1372 QueryContext
->InputMdl
= InputMdl
;
1373 QueryContext
->OutputMdl
= OutputMdl
;
1375 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1376 Request
.RequestContext
= QueryContext
;
1377 Status
= InfoTdiQueryInformationEx(&Request
,
1378 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1379 &Size
, &QueryContext
->QueryInfo
.Context
);
1380 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1382 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1387 /* An error occurred if we get here */
1391 MmUnlockPages(InputMdl
);
1392 IoFreeMdl(InputMdl
);
1396 if (OutputMdlLocked
)
1397 MmUnlockPages(OutputMdl
);
1398 IoFreeMdl(OutputMdl
);
1401 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1403 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1404 } else if( InputBufferLength
==
1405 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1406 /* Handle the case where the user is probing the buffer for length */
1407 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1408 InputBufferLength
, OutputBufferLength
));
1409 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1410 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1414 QueryContext
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
), QUERY_CONTEXT_TAG
);
1415 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1418 InputMdl
= IoAllocateMdl(InputBuffer
,
1419 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1422 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1425 InputMdlLocked
= TRUE
;
1426 Status
= STATUS_SUCCESS
;
1427 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1428 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1429 Status
= _SEH2_GetExceptionCode();
1432 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1433 if( InputMdl
) IoFreeMdl( InputMdl
);
1434 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1438 RtlCopyMemory(&QueryContext
->QueryInfo
,
1439 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1441 QueryContext
->Irp
= Irp
;
1442 QueryContext
->InputMdl
= InputMdl
;
1443 QueryContext
->OutputMdl
= NULL
;
1445 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1446 Request
.RequestContext
= QueryContext
;
1447 Status
= InfoTdiQueryInformationEx(&Request
,
1448 &QueryContext
->QueryInfo
.ID
,
1451 &QueryContext
->QueryInfo
.Context
);
1452 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1453 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1454 } else Status
= STATUS_INVALID_PARAMETER
;
1456 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1462 NTSTATUS
DispTdiSetInformationEx(
1464 PIO_STACK_LOCATION IrpSp
)
1466 * FUNCTION: TDI SetInformationEx handler
1468 * Irp = Pointer to I/O request packet
1469 * IrpSp = Pointer to current stack location of Irp
1471 * Status of operation
1474 PTRANSPORT_CONTEXT TranContext
;
1475 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1476 TDI_REQUEST Request
;
1479 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1481 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1482 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1484 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1485 case TDI_TRANSPORT_ADDRESS_FILE
:
1486 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1489 case TDI_CONNECTION_FILE
:
1490 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1493 case TDI_CONTROL_CHANNEL_FILE
:
1494 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1498 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1499 Irp
->IoStatus
.Information
= 0;
1501 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1503 return Irp
->IoStatus
.Status
;
1506 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1507 if (NT_SUCCESS(Status
)) {
1508 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1509 Request
.RequestContext
= Irp
;
1511 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1512 &Info
->Buffer
, Info
->BufferSize
);
1518 /* TODO: Support multiple addresses per interface.
1519 * For now just set the nte context to the interface index.
1521 * Later on, create an NTE context and NTE instance
1524 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1525 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1526 PIP_SET_ADDRESS IpAddrChange
=
1527 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1530 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1531 IpAddrChange
->NteIndex
));
1533 ForEachInterface(IF
) {
1534 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1536 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1537 Status
= STATUS_DUPLICATE_OBJECTID
;
1540 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1541 IPRemoveInterfaceRoute( IF
);
1543 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1544 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1545 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1546 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1547 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1548 IF
->Broadcast
.Address
.IPv4Address
=
1549 IF
->Unicast
.Address
.IPv4Address
|
1550 ~IF
->Netmask
.Address
.IPv4Address
;
1552 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1553 IF
->Unicast
.Address
.IPv4Address
));
1554 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1555 IF
->Netmask
.Address
.IPv4Address
));
1557 IPAddInterfaceRoute( IF
);
1559 IpAddrChange
->Address
= IF
->Index
;
1560 Status
= STATUS_SUCCESS
;
1561 Irp
->IoStatus
.Information
= IF
->Index
;
1566 Irp
->IoStatus
.Status
= Status
;
1570 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1571 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1572 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1575 ForEachInterface(IF
) {
1576 if( IF
->Index
== *NteIndex
) {
1577 IPRemoveInterfaceRoute( IF
);
1578 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1579 IF
->Unicast
.Address
.IPv4Address
= 0;
1580 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1581 IF
->Netmask
.Address
.IPv4Address
= 0;
1582 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1583 IF
->Broadcast
.Address
.IPv4Address
= 0;
1584 Status
= STATUS_SUCCESS
;
1588 Irp
->IoStatus
.Status
= Status
;