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
94 TI_DbgPrint(DEBUG_IRP
, ("Called for irp %x (%x, %d).\n",
97 Irp
->IoStatus
.Status
= Status
;
98 Irp
->IoStatus
.Information
= Count
;
100 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
101 Irp
->IoStatus
.Status
));
102 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
103 Irp
->IoStatus
.Information
));
104 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
106 IRPFinish(Irp
, Status
);
108 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
111 VOID NTAPI
DispCancelRequest(
112 PDEVICE_OBJECT Device
,
115 * FUNCTION: Cancels an IRP
117 * Device = Pointer to device object
118 * Irp = Pointer to an I/O request packet
121 PIO_STACK_LOCATION IrpSp
;
122 PTRANSPORT_CONTEXT TranContext
;
123 PFILE_OBJECT FileObject
;
125 BOOLEAN DequeuedIrp
= TRUE
;
127 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
129 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
131 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
132 FileObject
= IrpSp
->FileObject
;
133 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
134 MinorFunction
= IrpSp
->MinorFunction
;
136 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
138 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
139 Irp
->IoStatus
.Information
= 0;
143 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
146 /* Try canceling the request */
147 switch(MinorFunction
) {
150 DequeuedIrp
= TCPRemoveIRP( TranContext
->Handle
.ConnectionContext
, Irp
);
153 case TDI_SEND_DATAGRAM
:
154 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
155 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
159 DequeuedIrp
= DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
162 case TDI_RECEIVE_DATAGRAM
:
163 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
164 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
168 DequeuedIrp
= DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
172 DequeuedIrp
= TCPRemoveIRP(TranContext
->Handle
.ConnectionContext
, Irp
);
176 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
182 IRPFinish(Irp
, STATUS_CANCELLED
);
184 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
188 VOID NTAPI
DispCancelListenRequest(
189 PDEVICE_OBJECT Device
,
192 * FUNCTION: Cancels a listen IRP
194 * Device = Pointer to device object
195 * Irp = Pointer to an I/O request packet
198 PIO_STACK_LOCATION IrpSp
;
199 PTRANSPORT_CONTEXT TranContext
;
200 PFILE_OBJECT FileObject
;
201 PCONNECTION_ENDPOINT Connection
;
203 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
205 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
207 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
208 FileObject
= IrpSp
->FileObject
;
209 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
210 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
212 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
216 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
219 /* Try canceling the request */
220 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
222 if (TCPAbortListenForSocket(Connection
->AddressFile
->Listener
,
225 Irp
->IoStatus
.Information
= 0;
226 IRPFinish(Irp
, STATUS_CANCELLED
);
229 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
233 NTSTATUS
DispTdiAccept(
236 * FUNCTION: TDI_ACCEPT handler
238 * Irp = Pointer to an I/O request packet
240 * Status of operation
243 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
245 return STATUS_NOT_IMPLEMENTED
;
249 NTSTATUS
DispTdiAssociateAddress(
252 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
254 * Irp = Pointer to an I/O request packet
256 * Status of operation
259 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
260 PTRANSPORT_CONTEXT TranContext
;
261 PIO_STACK_LOCATION IrpSp
;
262 PCONNECTION_ENDPOINT Connection
;
263 PFILE_OBJECT FileObject
;
264 PADDRESS_FILE AddrFile
= NULL
;
268 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
270 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
272 /* Get associated connection endpoint file object. Quit if none exists */
274 TranContext
= IrpSp
->FileObject
->FsContext
;
276 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
277 return STATUS_INVALID_PARAMETER
;
280 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
282 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
283 return STATUS_INVALID_PARAMETER
;
286 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
288 Status
= ObReferenceObjectByHandle(
289 Parameters
->AddressHandle
,
295 if (!NT_SUCCESS(Status
)) {
296 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
297 Parameters
->AddressHandle
, Status
));
298 return STATUS_INVALID_PARAMETER
;
301 LockObject(Connection
, &OldIrql
);
303 if (Connection
->AddressFile
) {
304 ObDereferenceObject(FileObject
);
305 UnlockObject(Connection
, OldIrql
);
306 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
307 return STATUS_INVALID_PARAMETER
;
310 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
311 ObDereferenceObject(FileObject
);
312 UnlockObject(Connection
, OldIrql
);
313 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
314 FileObject
->FsContext2
));
315 return STATUS_INVALID_PARAMETER
;
318 /* Get associated address file object. Quit if none exists */
320 TranContext
= FileObject
->FsContext
;
322 ObDereferenceObject(FileObject
);
323 UnlockObject(Connection
, OldIrql
);
324 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
325 return STATUS_INVALID_PARAMETER
;
328 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
330 UnlockObject(Connection
, OldIrql
);
331 ObDereferenceObject(FileObject
);
332 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
333 return STATUS_INVALID_PARAMETER
;
336 LockObjectAtDpcLevel(AddrFile
);
338 ReferenceObject(AddrFile
);
339 Connection
->AddressFile
= AddrFile
;
341 /* Add connection endpoint to the address file */
342 ReferenceObject(Connection
);
343 AddrFile
->Connection
= Connection
;
345 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
346 ObDereferenceObject(FileObject
);
348 UnlockObjectFromDpcLevel(AddrFile
);
349 UnlockObject(Connection
, OldIrql
);
355 NTSTATUS
DispTdiConnect(
358 * FUNCTION: TDI_CONNECT handler
360 * Irp = Pointer to an I/O request packet
362 * Status of operation
365 PCONNECTION_ENDPOINT Connection
;
366 PTDI_REQUEST_KERNEL Parameters
;
367 PTRANSPORT_CONTEXT TranContext
;
368 PIO_STACK_LOCATION IrpSp
;
371 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
373 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
375 /* Get associated connection endpoint file object. Quit if none exists */
377 TranContext
= IrpSp
->FileObject
->FsContext
;
379 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
380 Status
= STATUS_INVALID_PARAMETER
;
384 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
386 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
387 Status
= STATUS_INVALID_PARAMETER
;
391 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
393 Status
= DispPrepareIrpForCancel(TranContext
->Handle
.ConnectionContext
,
397 if (NT_SUCCESS(Status
)) {
399 TranContext
->Handle
.ConnectionContext
,
400 Parameters
->RequestConnectionInformation
,
401 Parameters
->ReturnConnectionInformation
,
402 DispDataRequestComplete
,
407 if (Status
!= STATUS_PENDING
) {
408 DispDataRequestComplete(Irp
, Status
, 0);
410 IoMarkIrpPending(Irp
);
412 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
418 NTSTATUS
DispTdiDisassociateAddress(
421 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
423 * Irp = Pointer to an I/O request packet
425 * Status of operation
428 PCONNECTION_ENDPOINT Connection
;
429 PTRANSPORT_CONTEXT TranContext
;
430 PIO_STACK_LOCATION IrpSp
;
433 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
435 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
437 /* Get associated connection endpoint file object. Quit if none exists */
439 TranContext
= IrpSp
->FileObject
->FsContext
;
441 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
442 return STATUS_INVALID_PARAMETER
;
445 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
447 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
448 return STATUS_INVALID_PARAMETER
;
451 LockObject(Connection
, &OldIrql
);
453 if (!Connection
->AddressFile
) {
454 UnlockObject(Connection
, OldIrql
);
455 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
456 return STATUS_INVALID_PARAMETER
;
459 LockObjectAtDpcLevel(Connection
->AddressFile
);
461 /* Remove this connection from the address file */
462 DereferenceObject(Connection
->AddressFile
->Connection
);
463 Connection
->AddressFile
->Connection
= NULL
;
465 UnlockObjectFromDpcLevel(Connection
->AddressFile
);
467 /* Remove the address file from this connection */
468 DereferenceObject(Connection
->AddressFile
);
469 Connection
->AddressFile
= NULL
;
471 UnlockObject(Connection
, OldIrql
);
473 return STATUS_SUCCESS
;
477 NTSTATUS
DispTdiDisconnect(
480 * FUNCTION: TDI_DISCONNECT handler
482 * Irp = Pointer to an I/O request packet
484 * Status of operation
488 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
489 PCONNECTION_ENDPOINT Connection
;
490 PTRANSPORT_CONTEXT TranContext
;
491 PIO_STACK_LOCATION IrpSp
;
493 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
495 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
496 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
498 /* Get associated connection endpoint file object. Quit if none exists */
500 TranContext
= IrpSp
->FileObject
->FsContext
;
502 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
503 Status
= STATUS_INVALID_PARAMETER
;
507 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
509 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
510 Status
= STATUS_INVALID_PARAMETER
;
514 Status
= TCPDisconnect(
515 TranContext
->Handle
.ConnectionContext
,
516 DisReq
->RequestFlags
,
517 DisReq
->RequestConnectionInformation
,
518 DisReq
->ReturnConnectionInformation
,
519 DispDataRequestComplete
,
523 if (Status
!= STATUS_PENDING
) {
524 DispDataRequestComplete(Irp
, Status
, 0);
526 IoMarkIrpPending(Irp
);
528 TI_DbgPrint(MAX_TRACE
, ("TCP Disconnect returned %08x\n", Status
));
534 NTSTATUS
DispTdiListen(
537 * FUNCTION: TDI_LISTEN handler
539 * Irp = Pointer to an I/O request packet
541 * Status of operation
544 PCONNECTION_ENDPOINT Connection
;
545 PTDI_REQUEST_KERNEL Parameters
;
546 PTRANSPORT_CONTEXT TranContext
;
547 PIO_STACK_LOCATION IrpSp
;
548 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 Status
= STATUS_INVALID_PARAMETER
;
565 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
566 if (Connection
== NULL
)
568 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
569 Status
= STATUS_INVALID_PARAMETER
;
573 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
575 Status
= DispPrepareIrpForCancel
576 (TranContext
->Handle
.ConnectionContext
,
578 (PDRIVER_CANCEL
)DispCancelListenRequest
);
580 LockObject(Connection
, &OldIrql
);
582 if (Connection
->AddressFile
== NULL
)
584 TI_DbgPrint(MID_TRACE
, ("No associated address file\n"));
585 UnlockObject(Connection
, OldIrql
);
586 Status
= STATUS_INVALID_PARAMETER
;
590 LockObjectAtDpcLevel(Connection
->AddressFile
);
592 /* Listening will require us to create a listening socket and store it in
593 * the address file. It will be signalled, and attempt to complete an irp
594 * when a new connection arrives. */
595 /* The important thing to note here is that the irp we'll complete belongs
596 * to the socket to be accepted onto, not the listener */
597 if( NT_SUCCESS(Status
) && !Connection
->AddressFile
->Listener
) {
598 Connection
->AddressFile
->Listener
=
599 TCPAllocateConnectionEndpoint( NULL
);
601 if( !Connection
->AddressFile
->Listener
)
602 Status
= STATUS_NO_MEMORY
;
604 if( NT_SUCCESS(Status
) ) {
605 ReferenceObject(Connection
->AddressFile
);
606 Connection
->AddressFile
->Listener
->AddressFile
=
607 Connection
->AddressFile
;
609 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
610 Connection
->AddressFile
->Family
,
612 Connection
->AddressFile
->Protocol
);
615 if( NT_SUCCESS(Status
) )
616 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
620 if( NT_SUCCESS(Status
) ) {
622 ( (PTDI_REQUEST
)Parameters
,
623 Connection
->AddressFile
->Listener
,
625 DispDataRequestComplete
,
629 UnlockObjectFromDpcLevel(Connection
->AddressFile
);
630 UnlockObject(Connection
, OldIrql
);
633 if (Status
!= STATUS_PENDING
) {
634 DispDataRequestComplete(Irp
, Status
, 0);
636 IoMarkIrpPending(Irp
);
638 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
644 NTSTATUS
DispTdiQueryInformation(
645 PDEVICE_OBJECT DeviceObject
,
648 * FUNCTION: TDI_QUERY_INFORMATION handler
650 * DeviceObject = Pointer to device object structure
651 * Irp = Pointer to an I/O request packet
653 * Status of operation
656 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
657 PTRANSPORT_CONTEXT TranContext
;
658 PIO_STACK_LOCATION IrpSp
;
660 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
662 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
663 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
665 TranContext
= IrpSp
->FileObject
->FsContext
;
667 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
668 return STATUS_INVALID_PARAMETER
;
671 switch (Parameters
->QueryType
)
673 case TDI_QUERY_ADDRESS_INFO
:
675 PTDI_ADDRESS_INFO AddressInfo
;
676 PADDRESS_FILE AddrFile
;
677 PTA_IP_ADDRESS Address
;
678 PCONNECTION_ENDPOINT Endpoint
= NULL
;
681 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
682 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
683 sizeof(TDI_ADDRESS_IP
))) {
684 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
685 return STATUS_BUFFER_TOO_SMALL
;
688 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
689 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
691 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
692 case TDI_TRANSPORT_ADDRESS_FILE
:
693 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
695 Address
->TAAddressCount
= 1;
696 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
697 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
698 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
699 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->Address
.Address
.IPv4Address
;
701 &Address
->Address
[0].Address
[0].sin_zero
,
702 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
703 return STATUS_SUCCESS
;
705 case TDI_CONNECTION_FILE
:
707 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
709 &Address
->Address
[0].Address
[0].sin_zero
,
710 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
711 return TCPGetSockAddress( Endpoint
, (PTRANSPORT_ADDRESS
)Address
, FALSE
);
714 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
715 return STATUS_INVALID_PARAMETER
;
719 case TDI_QUERY_CONNECTION_INFO
:
721 PTDI_CONNECTION_INFORMATION AddressInfo
;
722 PADDRESS_FILE AddrFile
;
723 PCONNECTION_ENDPOINT Endpoint
= NULL
;
725 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
726 (FIELD_OFFSET(TDI_CONNECTION_INFORMATION
, RemoteAddress
) +
728 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small (ptr).\n"));
729 return STATUS_BUFFER_TOO_SMALL
;
732 AddressInfo
= (PTDI_CONNECTION_INFORMATION
)
733 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
735 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
736 case TDI_TRANSPORT_ADDRESS_FILE
:
737 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
738 Endpoint
= AddrFile
? AddrFile
->Connection
: NULL
;
741 case TDI_CONNECTION_FILE
:
743 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
747 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
748 return STATUS_INVALID_PARAMETER
;
752 TI_DbgPrint(MID_TRACE
, ("No connection object.\n"));
753 return STATUS_INVALID_PARAMETER
;
756 return TCPGetSockAddress( Endpoint
, AddressInfo
->RemoteAddress
, TRUE
);
759 case TDI_QUERY_MAX_DATAGRAM_INFO
:
761 PTDI_MAX_DATAGRAM_INFO MaxDatagramInfo
= MmGetSystemAddressForMdl(Irp
->MdlAddress
);
763 MaxDatagramInfo
->MaxDatagramSize
= 0xFFFF;
765 return STATUS_SUCCESS
;
769 return STATUS_NOT_IMPLEMENTED
;
773 NTSTATUS
DispTdiReceive(
776 * FUNCTION: TDI_RECEIVE handler
778 * Irp = Pointer to an I/O request packet
780 * Status of operation
783 PIO_STACK_LOCATION IrpSp
;
784 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
785 PTRANSPORT_CONTEXT TranContext
;
787 ULONG BytesReceived
= 0;
789 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
791 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
792 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
794 TranContext
= IrpSp
->FileObject
->FsContext
;
795 if (TranContext
== NULL
)
797 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
798 Status
= STATUS_INVALID_PARAMETER
;
802 if (TranContext
->Handle
.ConnectionContext
== NULL
)
804 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
805 Status
= STATUS_INVALID_PARAMETER
;
809 /* Initialize a receive request */
810 Status
= DispPrepareIrpForCancel
811 (TranContext
->Handle
.ConnectionContext
,
813 (PDRIVER_CANCEL
)DispCancelRequest
);
815 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
816 if (NT_SUCCESS(Status
))
818 Status
= TCPReceiveData(
819 TranContext
->Handle
.ConnectionContext
,
820 (PNDIS_BUFFER
)Irp
->MdlAddress
,
821 ReceiveInfo
->ReceiveLength
,
823 ReceiveInfo
->ReceiveFlags
,
824 DispDataRequestComplete
,
829 if (Status
!= STATUS_PENDING
) {
830 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
832 IoMarkIrpPending(Irp
);
834 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
840 NTSTATUS
DispTdiReceiveDatagram(
843 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
845 * Irp = Pointer to an I/O request packet
847 * Status of operation
850 PIO_STACK_LOCATION IrpSp
;
851 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
852 PTRANSPORT_CONTEXT TranContext
;
855 ULONG BytesReceived
= 0;
857 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
859 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
860 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
862 TranContext
= IrpSp
->FileObject
->FsContext
;
863 if (TranContext
== NULL
)
865 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
866 Status
= STATUS_INVALID_PARAMETER
;
870 /* Initialize a receive request */
871 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
872 Request
.RequestNotifyObject
= DispDataRequestComplete
;
873 Request
.RequestContext
= Irp
;
875 Status
= DispPrepareIrpForCancel(
876 IrpSp
->FileObject
->FsContext
,
878 (PDRIVER_CANCEL
)DispCancelRequest
);
880 if (NT_SUCCESS(Status
))
885 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
889 Status
= DGReceiveDatagram(
890 Request
.Handle
.AddressHandle
,
891 DgramInfo
->ReceiveDatagramInformation
,
893 DgramInfo
->ReceiveLength
,
894 DgramInfo
->ReceiveFlags
,
895 DgramInfo
->ReturnDatagramInformation
,
897 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
903 if (Status
!= STATUS_PENDING
) {
904 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
906 IoMarkIrpPending(Irp
);
908 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
914 NTSTATUS
DispTdiSend(
917 * FUNCTION: TDI_SEND handler
919 * Irp = Pointer to an I/O request packet
921 * Status of operation
924 PIO_STACK_LOCATION IrpSp
;
925 PTDI_REQUEST_KERNEL_SEND SendInfo
;
926 PTRANSPORT_CONTEXT TranContext
;
930 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
932 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
933 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
935 TranContext
= IrpSp
->FileObject
->FsContext
;
936 if (TranContext
== NULL
)
938 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
939 Status
= STATUS_INVALID_PARAMETER
;
943 if (TranContext
->Handle
.ConnectionContext
== NULL
)
945 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
946 Status
= STATUS_INVALID_PARAMETER
;
950 Status
= DispPrepareIrpForCancel(
951 IrpSp
->FileObject
->FsContext
,
953 (PDRIVER_CANCEL
)DispCancelRequest
);
955 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
956 if (NT_SUCCESS(Status
))
961 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
963 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
964 Status
= TCPSendData(
965 TranContext
->Handle
.ConnectionContext
,
967 SendInfo
->SendLength
,
970 DispDataRequestComplete
,
975 if (Status
!= STATUS_PENDING
) {
976 DispDataRequestComplete(Irp
, Status
, BytesSent
);
978 IoMarkIrpPending(Irp
);
980 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
986 NTSTATUS
DispTdiSendDatagram(
989 * FUNCTION: TDI_SEND_DATAGRAM handler
991 * Irp = Pointer to an I/O request packet
993 * Status of operation
996 PIO_STACK_LOCATION IrpSp
;
998 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
999 PTRANSPORT_CONTEXT TranContext
;
1002 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1004 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1005 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
1007 TranContext
= IrpSp
->FileObject
->FsContext
;
1008 if (TranContext
== NULL
)
1010 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
1011 Status
= STATUS_INVALID_PARAMETER
;
1015 /* Initialize a send request */
1016 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1017 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1018 Request
.RequestContext
= Irp
;
1020 Status
= DispPrepareIrpForCancel(
1021 IrpSp
->FileObject
->FsContext
,
1023 (PDRIVER_CANCEL
)DispCancelRequest
);
1025 if (NT_SUCCESS(Status
)) {
1029 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
1031 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
1035 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
1036 must be of type PTDI_ADDRESS_IP */
1037 TI_DbgPrint(MID_TRACE
,
1038 ("About to call send routine %x\n",
1039 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
1041 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
!= NULL
) )
1044 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
1045 Request
.Handle
.AddressHandle
,
1046 DgramInfo
->SendDatagramInformation
,
1050 Irp
->IoStatus
.Information
= DataUsed
;
1053 Status
= STATUS_UNSUCCESSFUL
;
1059 if (Status
!= STATUS_PENDING
) {
1060 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
1062 IoMarkIrpPending(Irp
);
1064 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
1070 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
1072 * FUNCTION: TDI_SET_EVENT_HANDER handler
1074 * Irp = Pointer to a I/O request packet
1076 * Status of operation
1079 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1080 PTRANSPORT_CONTEXT TranContext
;
1081 PIO_STACK_LOCATION IrpSp
;
1082 PADDRESS_FILE AddrFile
;
1086 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1088 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1090 /* Get associated address file object. Quit if none exists */
1092 TranContext
= IrpSp
->FileObject
->FsContext
;
1094 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1095 return STATUS_INVALID_PARAMETER
;
1098 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1100 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1101 return STATUS_INVALID_PARAMETER
;
1104 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1105 Status
= STATUS_SUCCESS
;
1107 LockObject(AddrFile
, &OldIrql
);
1109 /* Set the event handler. if an event handler is associated with
1110 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1111 If an event handler is not used it's flag is FALSE */
1112 switch (Parameters
->EventType
) {
1113 case TDI_EVENT_CONNECT
:
1114 if (!Parameters
->EventHandler
) {
1115 AddrFile
->ConnectHandlerContext
= NULL
;
1116 AddrFile
->RegisteredConnectHandler
= FALSE
;
1118 AddrFile
->ConnectHandler
=
1119 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1120 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1121 AddrFile
->RegisteredConnectHandler
= TRUE
;
1125 case TDI_EVENT_DISCONNECT
:
1126 if (!Parameters
->EventHandler
) {
1127 AddrFile
->DisconnectHandlerContext
= NULL
;
1128 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1130 AddrFile
->DisconnectHandler
=
1131 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1132 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1133 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1137 case TDI_EVENT_ERROR
:
1138 if (Parameters
->EventHandler
== NULL
) {
1139 AddrFile
->ErrorHandlerContext
= NULL
;
1140 AddrFile
->RegisteredErrorHandler
= FALSE
;
1142 AddrFile
->ErrorHandler
=
1143 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1144 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1145 AddrFile
->RegisteredErrorHandler
= TRUE
;
1149 case TDI_EVENT_RECEIVE
:
1150 if (Parameters
->EventHandler
== NULL
) {
1151 AddrFile
->ReceiveHandlerContext
= NULL
;
1152 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1154 AddrFile
->ReceiveHandler
=
1155 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1156 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1157 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1161 case TDI_EVENT_RECEIVE_DATAGRAM
:
1162 if (Parameters
->EventHandler
== NULL
) {
1163 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1164 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1166 AddrFile
->ReceiveDatagramHandler
=
1167 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1168 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1169 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1173 case TDI_EVENT_RECEIVE_EXPEDITED
:
1174 if (Parameters
->EventHandler
== NULL
) {
1175 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1176 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1178 AddrFile
->ExpeditedReceiveHandler
=
1179 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1180 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1181 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1185 case TDI_EVENT_CHAINED_RECEIVE
:
1186 if (Parameters
->EventHandler
== NULL
) {
1187 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1188 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1190 AddrFile
->ChainedReceiveHandler
=
1191 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1192 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1193 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1197 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1198 if (Parameters
->EventHandler
== NULL
) {
1199 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1200 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1202 AddrFile
->ChainedReceiveDatagramHandler
=
1203 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1204 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1205 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1209 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1210 if (Parameters
->EventHandler
== NULL
) {
1211 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1212 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1214 AddrFile
->ChainedReceiveExpeditedHandler
=
1215 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1216 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1217 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1222 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1223 Parameters
->EventType
));
1225 Status
= STATUS_INVALID_PARAMETER
;
1228 UnlockObject(AddrFile
, OldIrql
);
1234 NTSTATUS
DispTdiSetInformation(
1237 * FUNCTION: TDI_SET_INFORMATION handler
1239 * Irp = Pointer to an I/O request packet
1241 * Status of operation
1244 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1246 return STATUS_NOT_IMPLEMENTED
;
1250 VOID
DispTdiQueryInformationExComplete(
1255 * FUNCTION: Completes a TDI QueryInformationEx request
1257 * Context = Pointer to the IRP for the request
1258 * Status = TDI status of the request
1259 * ByteCount = Number of bytes returned in output buffer
1262 PTI_QUERY_CONTEXT QueryContext
;
1264 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1265 if (NT_SUCCESS(Status
)) {
1266 CopyBufferToBufferChain(
1267 QueryContext
->InputMdl
,
1268 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1269 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1273 MmUnlockPages(QueryContext
->InputMdl
);
1274 IoFreeMdl(QueryContext
->InputMdl
);
1275 if( QueryContext
->OutputMdl
) {
1276 MmUnlockPages(QueryContext
->OutputMdl
);
1277 IoFreeMdl(QueryContext
->OutputMdl
);
1280 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1281 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1283 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1287 NTSTATUS
DispTdiQueryInformationEx(
1289 PIO_STACK_LOCATION IrpSp
)
1291 * FUNCTION: TDI QueryInformationEx handler
1293 * Irp = Pointer to I/O request packet
1294 * IrpSp = Pointer to current stack location of Irp
1296 * Status of operation
1299 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1300 PTRANSPORT_CONTEXT TranContext
;
1301 PTI_QUERY_CONTEXT QueryContext
;
1303 TDI_REQUEST Request
;
1305 UINT InputBufferLength
;
1306 UINT OutputBufferLength
;
1307 BOOLEAN InputMdlLocked
= FALSE
;
1308 BOOLEAN OutputMdlLocked
= FALSE
;
1309 PMDL InputMdl
= NULL
;
1310 PMDL OutputMdl
= NULL
;
1311 NTSTATUS Status
= STATUS_SUCCESS
;
1313 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1315 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1317 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
1318 case TDI_TRANSPORT_ADDRESS_FILE
:
1319 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1322 case TDI_CONNECTION_FILE
:
1323 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1326 case TDI_CONTROL_CHANNEL_FILE
:
1327 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1331 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1332 return STATUS_INVALID_PARAMETER
;
1335 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1336 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1338 /* Validate parameters */
1339 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1340 (OutputBufferLength
!= 0)) {
1342 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1343 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1344 OutputBuffer
= Irp
->UserBuffer
;
1346 QueryContext
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
), QUERY_CONTEXT_TAG
);
1349 InputMdl
= IoAllocateMdl(InputBuffer
,
1350 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1353 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1354 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1356 if (InputMdl
&& OutputMdl
) {
1358 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1361 InputMdlLocked
= TRUE
;
1363 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1366 OutputMdlLocked
= TRUE
;
1368 RtlCopyMemory(&QueryContext
->QueryInfo
,
1369 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1371 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1372 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1373 Status
= _SEH2_GetExceptionCode();
1376 if (NT_SUCCESS(Status
)) {
1377 Size
= MmGetMdlByteCount(OutputMdl
);
1379 QueryContext
->Irp
= Irp
;
1380 QueryContext
->InputMdl
= InputMdl
;
1381 QueryContext
->OutputMdl
= OutputMdl
;
1383 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1384 Request
.RequestContext
= QueryContext
;
1385 Status
= InfoTdiQueryInformationEx(&Request
,
1386 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1387 &Size
, &QueryContext
->QueryInfo
.Context
);
1388 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1390 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1395 /* An error occurred if we get here */
1399 MmUnlockPages(InputMdl
);
1400 IoFreeMdl(InputMdl
);
1404 if (OutputMdlLocked
)
1405 MmUnlockPages(OutputMdl
);
1406 IoFreeMdl(OutputMdl
);
1409 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1411 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1412 } else if( InputBufferLength
==
1413 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1414 /* Handle the case where the user is probing the buffer for length */
1415 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1416 InputBufferLength
, OutputBufferLength
));
1417 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1418 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1422 QueryContext
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
), QUERY_CONTEXT_TAG
);
1423 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1426 InputMdl
= IoAllocateMdl(InputBuffer
,
1427 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1430 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1433 InputMdlLocked
= TRUE
;
1434 Status
= STATUS_SUCCESS
;
1435 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1436 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1437 Status
= _SEH2_GetExceptionCode();
1440 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1441 if( InputMdl
) IoFreeMdl( InputMdl
);
1442 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1446 RtlCopyMemory(&QueryContext
->QueryInfo
,
1447 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1449 QueryContext
->Irp
= Irp
;
1450 QueryContext
->InputMdl
= InputMdl
;
1451 QueryContext
->OutputMdl
= NULL
;
1453 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1454 Request
.RequestContext
= QueryContext
;
1455 Status
= InfoTdiQueryInformationEx(&Request
,
1456 &QueryContext
->QueryInfo
.ID
,
1459 &QueryContext
->QueryInfo
.Context
);
1460 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1461 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1462 } else Status
= STATUS_INVALID_PARAMETER
;
1464 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1470 NTSTATUS
DispTdiSetInformationEx(
1472 PIO_STACK_LOCATION IrpSp
)
1474 * FUNCTION: TDI SetInformationEx handler
1476 * Irp = Pointer to I/O request packet
1477 * IrpSp = Pointer to current stack location of Irp
1479 * Status of operation
1482 PTRANSPORT_CONTEXT TranContext
;
1483 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1484 TDI_REQUEST Request
;
1487 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1489 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1490 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1492 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
1493 case TDI_TRANSPORT_ADDRESS_FILE
:
1494 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1497 case TDI_CONNECTION_FILE
:
1498 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1501 case TDI_CONTROL_CHANNEL_FILE
:
1502 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1506 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1507 Irp
->IoStatus
.Information
= 0;
1509 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1511 return Irp
->IoStatus
.Status
;
1514 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1515 if (NT_SUCCESS(Status
)) {
1516 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1517 Request
.RequestContext
= Irp
;
1519 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1520 &Info
->Buffer
, Info
->BufferSize
);
1526 /* TODO: Support multiple addresses per interface.
1527 * For now just set the nte context to the interface index.
1529 * Later on, create an NTE context and NTE instance
1532 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1533 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1534 PIP_SET_ADDRESS IpAddrChange
=
1535 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1538 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1539 IpAddrChange
->NteIndex
));
1541 ForEachInterface(IF
) {
1542 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1544 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1545 Status
= STATUS_DUPLICATE_OBJECTID
;
1548 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1549 IPRemoveInterfaceRoute( IF
);
1551 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1552 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1553 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1554 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1555 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1556 IF
->Broadcast
.Address
.IPv4Address
=
1557 IF
->Unicast
.Address
.IPv4Address
|
1558 ~IF
->Netmask
.Address
.IPv4Address
;
1560 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1561 IF
->Unicast
.Address
.IPv4Address
));
1562 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1563 IF
->Netmask
.Address
.IPv4Address
));
1565 IPAddInterfaceRoute( IF
);
1567 IpAddrChange
->Address
= IF
->Index
;
1568 Status
= STATUS_SUCCESS
;
1569 Irp
->IoStatus
.Information
= IF
->Index
;
1574 Irp
->IoStatus
.Status
= Status
;
1578 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1579 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1580 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1583 ForEachInterface(IF
) {
1584 if( IF
->Index
== *NteIndex
) {
1585 IPRemoveInterfaceRoute( IF
);
1586 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1587 IF
->Unicast
.Address
.IPv4Address
= 0;
1588 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1589 IF
->Netmask
.Address
.IPv4Address
= 0;
1590 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1591 IF
->Broadcast
.Address
.IPv4Address
= 0;
1592 Status
= STATUS_SUCCESS
;
1596 Irp
->IoStatus
.Status
= Status
;