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
;
136 BOOLEAN DequeuedIrp
= TRUE
;
138 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
140 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
142 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
143 FileObject
= IrpSp
->FileObject
;
144 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
145 MinorFunction
= IrpSp
->MinorFunction
;
147 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
149 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
150 Irp
->IoStatus
.Information
= 0;
154 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
157 /* Try canceling the request */
158 switch(MinorFunction
) {
161 DequeuedIrp
= TCPRemoveIRP( TranContext
->Handle
.ConnectionContext
, Irp
);
164 case TDI_SEND_DATAGRAM
:
165 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
166 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
170 DequeuedIrp
= DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
173 case TDI_RECEIVE_DATAGRAM
:
174 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
175 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
179 DequeuedIrp
= DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
183 DequeuedIrp
= TCPRemoveIRP(TranContext
->Handle
.ConnectionContext
, Irp
);
187 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
193 IRPFinish(Irp
, STATUS_CANCELLED
);
195 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
199 VOID NTAPI
DispCancelListenRequest(
200 PDEVICE_OBJECT Device
,
203 * FUNCTION: Cancels a listen IRP
205 * Device = Pointer to device object
206 * Irp = Pointer to an I/O request packet
209 PIO_STACK_LOCATION IrpSp
;
210 PTRANSPORT_CONTEXT TranContext
;
211 PFILE_OBJECT FileObject
;
212 PCONNECTION_ENDPOINT Connection
;
214 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
216 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
218 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
219 FileObject
= IrpSp
->FileObject
;
220 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
221 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
223 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
227 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
230 /* Try canceling the request */
231 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
233 if (TCPAbortListenForSocket(Connection
->AddressFile
->Listener
,
236 Irp
->IoStatus
.Information
= 0;
237 IRPFinish(Irp
, STATUS_CANCELLED
);
240 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
244 NTSTATUS
DispTdiAccept(
247 * FUNCTION: TDI_ACCEPT handler
249 * Irp = Pointer to an I/O request packet
251 * Status of operation
254 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
256 return STATUS_NOT_IMPLEMENTED
;
260 NTSTATUS
DispTdiAssociateAddress(
263 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
265 * Irp = Pointer to an I/O request packet
267 * Status of operation
270 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
271 PTRANSPORT_CONTEXT TranContext
;
272 PIO_STACK_LOCATION IrpSp
;
273 PCONNECTION_ENDPOINT Connection
;
274 PFILE_OBJECT FileObject
;
275 PADDRESS_FILE AddrFile
= NULL
;
279 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
281 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
283 /* Get associated connection endpoint file object. Quit if none exists */
285 TranContext
= IrpSp
->FileObject
->FsContext
;
287 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
288 return STATUS_INVALID_PARAMETER
;
291 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
293 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
294 return STATUS_INVALID_PARAMETER
;
297 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
299 Status
= ObReferenceObjectByHandle(
300 Parameters
->AddressHandle
,
306 if (!NT_SUCCESS(Status
)) {
307 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
308 Parameters
->AddressHandle
, Status
));
309 return STATUS_INVALID_PARAMETER
;
312 KeAcquireSpinLock(&Connection
->Lock
, &OldIrql
);
314 if (Connection
->AddressFile
) {
315 ObDereferenceObject(FileObject
);
316 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
317 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
318 return STATUS_INVALID_PARAMETER
;
321 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
322 ObDereferenceObject(FileObject
);
323 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
324 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
325 FileObject
->FsContext2
));
326 return STATUS_INVALID_PARAMETER
;
329 /* Get associated address file object. Quit if none exists */
331 TranContext
= FileObject
->FsContext
;
333 ObDereferenceObject(FileObject
);
334 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
335 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
336 return STATUS_INVALID_PARAMETER
;
339 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
341 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
342 ObDereferenceObject(FileObject
);
343 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
344 return STATUS_INVALID_PARAMETER
;
347 KeAcquireSpinLockAtDpcLevel(&AddrFile
->Lock
);
349 Connection
->AddressFile
= AddrFile
;
351 /* Add connection endpoint to the address file */
352 AddrFile
->Connection
= Connection
;
354 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
355 ObDereferenceObject(FileObject
);
357 KeReleaseSpinLockFromDpcLevel(&AddrFile
->Lock
);
358 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
364 NTSTATUS
DispTdiConnect(
367 * FUNCTION: TDI_CONNECT handler
369 * Irp = Pointer to an I/O request packet
371 * Status of operation
374 PCONNECTION_ENDPOINT Connection
;
375 PTDI_REQUEST_KERNEL Parameters
;
376 PTRANSPORT_CONTEXT TranContext
;
377 PIO_STACK_LOCATION IrpSp
;
380 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
382 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
384 /* Get associated connection endpoint file object. Quit if none exists */
386 TranContext
= IrpSp
->FileObject
->FsContext
;
388 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
389 Status
= STATUS_INVALID_PARAMETER
;
393 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
395 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
396 Status
= STATUS_INVALID_PARAMETER
;
400 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
402 Status
= DispPrepareIrpForCancel(TranContext
->Handle
.ConnectionContext
,
406 if (NT_SUCCESS(Status
)) {
408 TranContext
->Handle
.ConnectionContext
,
409 Parameters
->RequestConnectionInformation
,
410 Parameters
->ReturnConnectionInformation
,
411 DispDataRequestComplete
,
416 if (Status
!= STATUS_PENDING
) {
417 DispDataRequestComplete(Irp
, Status
, 0);
419 IoMarkIrpPending(Irp
);
421 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
427 NTSTATUS
DispTdiDisassociateAddress(
430 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
432 * Irp = Pointer to an I/O request packet
434 * Status of operation
437 PCONNECTION_ENDPOINT Connection
;
438 PTRANSPORT_CONTEXT TranContext
;
439 PIO_STACK_LOCATION IrpSp
;
442 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
444 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
446 /* Get associated connection endpoint file object. Quit if none exists */
448 TranContext
= IrpSp
->FileObject
->FsContext
;
450 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
451 return STATUS_INVALID_PARAMETER
;
454 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
456 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
457 return STATUS_INVALID_PARAMETER
;
460 KeAcquireSpinLock(&Connection
->Lock
, &OldIrql
);
462 if (!Connection
->AddressFile
) {
463 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
464 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
465 return STATUS_INVALID_PARAMETER
;
468 KeAcquireSpinLockAtDpcLevel(&Connection
->AddressFile
->Lock
);
470 /* Remove this connection from the address file */
471 Connection
->AddressFile
->Connection
= NULL
;
473 KeReleaseSpinLockFromDpcLevel(&Connection
->AddressFile
->Lock
);
475 /* Remove the address file from this connection */
476 Connection
->AddressFile
= NULL
;
478 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
480 return STATUS_SUCCESS
;
484 NTSTATUS
DispTdiDisconnect(
487 * FUNCTION: TDI_DISCONNECT handler
489 * Irp = Pointer to an I/O request packet
491 * Status of operation
495 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
496 PCONNECTION_ENDPOINT Connection
;
497 PTRANSPORT_CONTEXT TranContext
;
498 PIO_STACK_LOCATION IrpSp
;
500 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
502 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
503 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
505 /* Get associated connection endpoint file object. Quit if none exists */
507 TranContext
= IrpSp
->FileObject
->FsContext
;
509 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
510 Status
= STATUS_INVALID_PARAMETER
;
514 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
516 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
517 Status
= STATUS_INVALID_PARAMETER
;
521 Status
= TCPDisconnect(
522 TranContext
->Handle
.ConnectionContext
,
523 DisReq
->RequestFlags
,
524 DisReq
->RequestConnectionInformation
,
525 DisReq
->ReturnConnectionInformation
,
526 DispDataRequestComplete
,
530 if (Status
!= STATUS_PENDING
) {
531 DispDataRequestComplete(Irp
, Status
, 0);
533 IoMarkIrpPending(Irp
);
535 TI_DbgPrint(MAX_TRACE
, ("TCP Disconnect returned %08x\n", Status
));
541 NTSTATUS
DispTdiListen(
544 * FUNCTION: TDI_LISTEN handler
546 * Irp = Pointer to an I/O request packet
548 * Status of operation
551 PCONNECTION_ENDPOINT Connection
;
552 PTDI_REQUEST_KERNEL Parameters
;
553 PTRANSPORT_CONTEXT TranContext
;
554 PIO_STACK_LOCATION IrpSp
;
555 NTSTATUS Status
= STATUS_SUCCESS
;
558 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
560 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
562 /* Get associated connection endpoint file object. Quit if none exists */
564 TranContext
= IrpSp
->FileObject
->FsContext
;
565 if (TranContext
== NULL
)
567 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
568 Status
= STATUS_INVALID_PARAMETER
;
572 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
573 if (Connection
== NULL
)
575 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
576 Status
= STATUS_INVALID_PARAMETER
;
580 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
582 Status
= DispPrepareIrpForCancel
583 (TranContext
->Handle
.ConnectionContext
,
585 (PDRIVER_CANCEL
)DispCancelListenRequest
);
587 KeAcquireSpinLock(&Connection
->Lock
, &OldIrql
);
589 if (Connection
->AddressFile
== NULL
)
591 TI_DbgPrint(MID_TRACE
, ("No associated address file\n"));
592 KeReleaseSpinLock(&Connection
->Lock
, OldIrql
);
593 Status
= STATUS_INVALID_PARAMETER
;
597 KeAcquireSpinLockAtDpcLevel(&Connection
->AddressFile
->Lock
);
599 /* Listening will require us to create a listening socket and store it in
600 * the address file. It will be signalled, and attempt to complete an irp
601 * when a new connection arrives. */
602 /* The important thing to note here is that the irp we'll complete belongs
603 * to the socket to be accepted onto, not the listener */
604 if( NT_SUCCESS(Status
) && !Connection
->AddressFile
->Listener
) {
605 Connection
->AddressFile
->Listener
=
606 TCPAllocateConnectionEndpoint( NULL
);
608 if( !Connection
->AddressFile
->Listener
)
609 Status
= STATUS_NO_MEMORY
;
611 if( NT_SUCCESS(Status
) ) {
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 KeReleaseSpinLockFromDpcLevel(&Connection
->AddressFile
->Lock
);
636 KeReleaseSpinLock(&Connection
->Lock
, 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
)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
->Address
[0].Address
[0].sin_zero
,
716 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
717 return TCPGetSockAddress( Endpoint
, (PTRANSPORT_ADDRESS
)Address
, FALSE
);
720 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
721 return STATUS_INVALID_PARAMETER
;
725 case TDI_QUERY_CONNECTION_INFO
:
727 PTDI_CONNECTION_INFORMATION AddressInfo
;
728 PADDRESS_FILE AddrFile
;
729 PCONNECTION_ENDPOINT Endpoint
= NULL
;
731 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
732 (FIELD_OFFSET(TDI_CONNECTION_INFORMATION
, RemoteAddress
) +
734 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small (ptr).\n"));
735 return STATUS_BUFFER_TOO_SMALL
;
738 AddressInfo
= (PTDI_CONNECTION_INFORMATION
)
739 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
741 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
742 case TDI_TRANSPORT_ADDRESS_FILE
:
743 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
744 Endpoint
= AddrFile
? AddrFile
->Connection
: NULL
;
747 case TDI_CONNECTION_FILE
:
749 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
753 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
754 return STATUS_INVALID_PARAMETER
;
758 TI_DbgPrint(MID_TRACE
, ("No connection object.\n"));
759 return STATUS_INVALID_PARAMETER
;
762 return TCPGetSockAddress( Endpoint
, AddressInfo
->RemoteAddress
, TRUE
);
766 return STATUS_NOT_IMPLEMENTED
;
770 NTSTATUS
DispTdiReceive(
773 * FUNCTION: TDI_RECEIVE handler
775 * Irp = Pointer to an I/O request packet
777 * Status of operation
780 PIO_STACK_LOCATION IrpSp
;
781 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
782 PTRANSPORT_CONTEXT TranContext
;
784 ULONG BytesReceived
= 0;
786 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
788 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
789 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
791 TranContext
= IrpSp
->FileObject
->FsContext
;
792 if (TranContext
== NULL
)
794 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
795 Status
= STATUS_INVALID_PARAMETER
;
799 if (TranContext
->Handle
.ConnectionContext
== NULL
)
801 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
802 Status
= STATUS_INVALID_PARAMETER
;
806 /* Initialize a receive request */
807 Status
= DispPrepareIrpForCancel
808 (TranContext
->Handle
.ConnectionContext
,
810 (PDRIVER_CANCEL
)DispCancelRequest
);
812 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
813 if (NT_SUCCESS(Status
))
815 Status
= TCPReceiveData(
816 TranContext
->Handle
.ConnectionContext
,
817 (PNDIS_BUFFER
)Irp
->MdlAddress
,
818 ReceiveInfo
->ReceiveLength
,
820 ReceiveInfo
->ReceiveFlags
,
821 DispDataRequestComplete
,
826 if (Status
!= STATUS_PENDING
) {
827 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
829 IoMarkIrpPending(Irp
);
831 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
837 NTSTATUS
DispTdiReceiveDatagram(
840 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
842 * Irp = Pointer to an I/O request packet
844 * Status of operation
847 PIO_STACK_LOCATION IrpSp
;
848 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
849 PTRANSPORT_CONTEXT TranContext
;
852 ULONG BytesReceived
= 0;
854 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
856 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
857 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
859 TranContext
= IrpSp
->FileObject
->FsContext
;
860 if (TranContext
== NULL
)
862 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
863 Status
= STATUS_INVALID_PARAMETER
;
867 /* Initialize a receive request */
868 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
869 Request
.RequestNotifyObject
= DispDataRequestComplete
;
870 Request
.RequestContext
= Irp
;
872 Status
= DispPrepareIrpForCancel(
873 IrpSp
->FileObject
->FsContext
,
875 (PDRIVER_CANCEL
)DispCancelRequest
);
877 if (NT_SUCCESS(Status
))
882 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
886 Status
= DGReceiveDatagram(
887 Request
.Handle
.AddressHandle
,
888 DgramInfo
->ReceiveDatagramInformation
,
890 DgramInfo
->ReceiveLength
,
891 DgramInfo
->ReceiveFlags
,
892 DgramInfo
->ReturnDatagramInformation
,
894 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
900 if (Status
!= STATUS_PENDING
) {
901 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
903 IoMarkIrpPending(Irp
);
905 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
911 NTSTATUS
DispTdiSend(
914 * FUNCTION: TDI_SEND handler
916 * Irp = Pointer to an I/O request packet
918 * Status of operation
921 PIO_STACK_LOCATION IrpSp
;
922 PTDI_REQUEST_KERNEL_SEND SendInfo
;
923 PTRANSPORT_CONTEXT TranContext
;
927 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
929 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
930 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
932 TranContext
= IrpSp
->FileObject
->FsContext
;
933 if (TranContext
== NULL
)
935 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
936 Status
= STATUS_INVALID_PARAMETER
;
940 if (TranContext
->Handle
.ConnectionContext
== NULL
)
942 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
943 Status
= STATUS_INVALID_PARAMETER
;
947 Status
= DispPrepareIrpForCancel(
948 IrpSp
->FileObject
->FsContext
,
950 (PDRIVER_CANCEL
)DispCancelRequest
);
952 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
953 if (NT_SUCCESS(Status
))
958 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
960 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
961 Status
= TCPSendData(
962 TranContext
->Handle
.ConnectionContext
,
964 SendInfo
->SendLength
,
967 DispDataRequestComplete
,
972 if (Status
!= STATUS_PENDING
) {
973 DispDataRequestComplete(Irp
, Status
, BytesSent
);
975 IoMarkIrpPending(Irp
);
977 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
983 NTSTATUS
DispTdiSendDatagram(
986 * FUNCTION: TDI_SEND_DATAGRAM handler
988 * Irp = Pointer to an I/O request packet
990 * Status of operation
993 PIO_STACK_LOCATION IrpSp
;
995 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
996 PTRANSPORT_CONTEXT TranContext
;
999 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1001 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1002 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
1004 TranContext
= IrpSp
->FileObject
->FsContext
;
1005 if (TranContext
== NULL
)
1007 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
1008 Status
= STATUS_INVALID_PARAMETER
;
1012 /* Initialize a send request */
1013 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1014 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1015 Request
.RequestContext
= Irp
;
1017 Status
= DispPrepareIrpForCancel(
1018 IrpSp
->FileObject
->FsContext
,
1020 (PDRIVER_CANCEL
)DispCancelRequest
);
1022 if (NT_SUCCESS(Status
)) {
1026 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
1028 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
1032 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
1033 must be of type PTDI_ADDRESS_IP */
1034 TI_DbgPrint(MID_TRACE
,
1035 ("About to call send routine %x\n",
1036 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
1038 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
!= NULL
) )
1039 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
1040 Request
.Handle
.AddressHandle
,
1041 DgramInfo
->SendDatagramInformation
,
1044 &Irp
->IoStatus
.Information
);
1046 Status
= STATUS_UNSUCCESSFUL
;
1052 if (Status
!= STATUS_PENDING
) {
1053 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
1055 IoMarkIrpPending(Irp
);
1057 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
1063 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
1065 * FUNCTION: TDI_SET_EVENT_HANDER handler
1067 * Irp = Pointer to a I/O request packet
1069 * Status of operation
1072 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1073 PTRANSPORT_CONTEXT TranContext
;
1074 PIO_STACK_LOCATION IrpSp
;
1075 PADDRESS_FILE AddrFile
;
1079 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1081 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1083 /* Get associated address file object. Quit if none exists */
1085 TranContext
= IrpSp
->FileObject
->FsContext
;
1087 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1088 return STATUS_INVALID_PARAMETER
;
1091 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1093 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1094 return STATUS_INVALID_PARAMETER
;
1097 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1098 Status
= STATUS_SUCCESS
;
1100 KeAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
1102 /* Set the event handler. if an event handler is associated with
1103 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1104 If an event handler is not used it's flag is FALSE */
1105 switch (Parameters
->EventType
) {
1106 case TDI_EVENT_CONNECT
:
1107 if (!Parameters
->EventHandler
) {
1108 AddrFile
->ConnectHandlerContext
= NULL
;
1109 AddrFile
->RegisteredConnectHandler
= FALSE
;
1111 AddrFile
->ConnectHandler
=
1112 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1113 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1114 AddrFile
->RegisteredConnectHandler
= TRUE
;
1118 case TDI_EVENT_DISCONNECT
:
1119 if (!Parameters
->EventHandler
) {
1120 AddrFile
->DisconnectHandlerContext
= NULL
;
1121 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1123 AddrFile
->DisconnectHandler
=
1124 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1125 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1126 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1130 case TDI_EVENT_ERROR
:
1131 if (Parameters
->EventHandler
== NULL
) {
1132 AddrFile
->ErrorHandlerContext
= NULL
;
1133 AddrFile
->RegisteredErrorHandler
= FALSE
;
1135 AddrFile
->ErrorHandler
=
1136 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1137 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1138 AddrFile
->RegisteredErrorHandler
= TRUE
;
1142 case TDI_EVENT_RECEIVE
:
1143 if (Parameters
->EventHandler
== NULL
) {
1144 AddrFile
->ReceiveHandlerContext
= NULL
;
1145 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1147 AddrFile
->ReceiveHandler
=
1148 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1149 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1150 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1154 case TDI_EVENT_RECEIVE_DATAGRAM
:
1155 if (Parameters
->EventHandler
== NULL
) {
1156 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1157 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1159 AddrFile
->ReceiveDatagramHandler
=
1160 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1161 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1162 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1166 case TDI_EVENT_RECEIVE_EXPEDITED
:
1167 if (Parameters
->EventHandler
== NULL
) {
1168 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1169 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1171 AddrFile
->ExpeditedReceiveHandler
=
1172 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1173 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1174 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1178 case TDI_EVENT_CHAINED_RECEIVE
:
1179 if (Parameters
->EventHandler
== NULL
) {
1180 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1181 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1183 AddrFile
->ChainedReceiveHandler
=
1184 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1185 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1186 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1190 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1191 if (Parameters
->EventHandler
== NULL
) {
1192 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1193 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1195 AddrFile
->ChainedReceiveDatagramHandler
=
1196 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1197 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1198 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1202 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1203 if (Parameters
->EventHandler
== NULL
) {
1204 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1205 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1207 AddrFile
->ChainedReceiveExpeditedHandler
=
1208 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1209 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1210 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1215 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1216 Parameters
->EventType
));
1218 Status
= STATUS_INVALID_PARAMETER
;
1221 KeReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1227 NTSTATUS
DispTdiSetInformation(
1230 * FUNCTION: TDI_SET_INFORMATION handler
1232 * Irp = Pointer to an I/O request packet
1234 * Status of operation
1237 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1239 return STATUS_NOT_IMPLEMENTED
;
1243 VOID
DispTdiQueryInformationExComplete(
1248 * FUNCTION: Completes a TDI QueryInformationEx request
1250 * Context = Pointer to the IRP for the request
1251 * Status = TDI status of the request
1252 * ByteCount = Number of bytes returned in output buffer
1255 PTI_QUERY_CONTEXT QueryContext
;
1257 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1258 if (NT_SUCCESS(Status
)) {
1259 CopyBufferToBufferChain(
1260 QueryContext
->InputMdl
,
1261 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1262 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1266 MmUnlockPages(QueryContext
->InputMdl
);
1267 IoFreeMdl(QueryContext
->InputMdl
);
1268 if( QueryContext
->OutputMdl
) {
1269 MmUnlockPages(QueryContext
->OutputMdl
);
1270 IoFreeMdl(QueryContext
->OutputMdl
);
1273 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1274 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1276 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1280 NTSTATUS
DispTdiQueryInformationEx(
1282 PIO_STACK_LOCATION IrpSp
)
1284 * FUNCTION: TDI QueryInformationEx handler
1286 * Irp = Pointer to I/O request packet
1287 * IrpSp = Pointer to current stack location of Irp
1289 * Status of operation
1292 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1293 PTRANSPORT_CONTEXT TranContext
;
1294 PTI_QUERY_CONTEXT QueryContext
;
1296 TDI_REQUEST Request
;
1298 UINT InputBufferLength
;
1299 UINT OutputBufferLength
;
1300 BOOLEAN InputMdlLocked
= FALSE
;
1301 BOOLEAN OutputMdlLocked
= FALSE
;
1302 PMDL InputMdl
= NULL
;
1303 PMDL OutputMdl
= NULL
;
1304 NTSTATUS Status
= STATUS_SUCCESS
;
1306 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1308 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1310 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1311 case TDI_TRANSPORT_ADDRESS_FILE
:
1312 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1315 case TDI_CONNECTION_FILE
:
1316 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1319 case TDI_CONTROL_CHANNEL_FILE
:
1320 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1324 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1325 return STATUS_INVALID_PARAMETER
;
1328 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1329 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1331 /* Validate parameters */
1332 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1333 (OutputBufferLength
!= 0)) {
1335 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1336 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1337 OutputBuffer
= Irp
->UserBuffer
;
1339 QueryContext
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
), QUERY_CONTEXT_TAG
);
1342 InputMdl
= IoAllocateMdl(InputBuffer
,
1343 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1346 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1347 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1349 if (InputMdl
&& OutputMdl
) {
1351 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1354 InputMdlLocked
= TRUE
;
1356 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1359 OutputMdlLocked
= TRUE
;
1361 RtlCopyMemory(&QueryContext
->QueryInfo
,
1362 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1364 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1365 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1366 Status
= _SEH2_GetExceptionCode();
1369 if (NT_SUCCESS(Status
)) {
1370 Size
= MmGetMdlByteCount(OutputMdl
);
1372 QueryContext
->Irp
= Irp
;
1373 QueryContext
->InputMdl
= InputMdl
;
1374 QueryContext
->OutputMdl
= OutputMdl
;
1376 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1377 Request
.RequestContext
= QueryContext
;
1378 Status
= InfoTdiQueryInformationEx(&Request
,
1379 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1380 &Size
, &QueryContext
->QueryInfo
.Context
);
1381 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1383 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1388 /* An error occurred if we get here */
1392 MmUnlockPages(InputMdl
);
1393 IoFreeMdl(InputMdl
);
1397 if (OutputMdlLocked
)
1398 MmUnlockPages(OutputMdl
);
1399 IoFreeMdl(OutputMdl
);
1402 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1404 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1405 } else if( InputBufferLength
==
1406 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1407 /* Handle the case where the user is probing the buffer for length */
1408 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1409 InputBufferLength
, OutputBufferLength
));
1410 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1411 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1415 QueryContext
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
), QUERY_CONTEXT_TAG
);
1416 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1419 InputMdl
= IoAllocateMdl(InputBuffer
,
1420 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1423 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1426 InputMdlLocked
= TRUE
;
1427 Status
= STATUS_SUCCESS
;
1428 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1429 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1430 Status
= _SEH2_GetExceptionCode();
1433 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1434 if( InputMdl
) IoFreeMdl( InputMdl
);
1435 ExFreePoolWithTag(QueryContext
, QUERY_CONTEXT_TAG
);
1439 RtlCopyMemory(&QueryContext
->QueryInfo
,
1440 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1442 QueryContext
->Irp
= Irp
;
1443 QueryContext
->InputMdl
= InputMdl
;
1444 QueryContext
->OutputMdl
= NULL
;
1446 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1447 Request
.RequestContext
= QueryContext
;
1448 Status
= InfoTdiQueryInformationEx(&Request
,
1449 &QueryContext
->QueryInfo
.ID
,
1452 &QueryContext
->QueryInfo
.Context
);
1453 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1454 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1455 } else Status
= STATUS_INVALID_PARAMETER
;
1457 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1463 NTSTATUS
DispTdiSetInformationEx(
1465 PIO_STACK_LOCATION IrpSp
)
1467 * FUNCTION: TDI SetInformationEx handler
1469 * Irp = Pointer to I/O request packet
1470 * IrpSp = Pointer to current stack location of Irp
1472 * Status of operation
1475 PTRANSPORT_CONTEXT TranContext
;
1476 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1477 TDI_REQUEST Request
;
1480 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1482 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1483 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1485 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1486 case TDI_TRANSPORT_ADDRESS_FILE
:
1487 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1490 case TDI_CONNECTION_FILE
:
1491 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1494 case TDI_CONTROL_CHANNEL_FILE
:
1495 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1499 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1500 Irp
->IoStatus
.Information
= 0;
1502 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1504 return Irp
->IoStatus
.Status
;
1507 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1508 if (NT_SUCCESS(Status
)) {
1509 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1510 Request
.RequestContext
= Irp
;
1512 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1513 &Info
->Buffer
, Info
->BufferSize
);
1519 /* TODO: Support multiple addresses per interface.
1520 * For now just set the nte context to the interface index.
1522 * Later on, create an NTE context and NTE instance
1525 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1526 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1527 PIP_SET_ADDRESS IpAddrChange
=
1528 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1531 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1532 IpAddrChange
->NteIndex
));
1534 ForEachInterface(IF
) {
1535 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1537 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1538 Status
= STATUS_DUPLICATE_OBJECTID
;
1541 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1542 IPRemoveInterfaceRoute( IF
);
1544 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1545 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1546 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1547 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1548 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1549 IF
->Broadcast
.Address
.IPv4Address
=
1550 IF
->Unicast
.Address
.IPv4Address
|
1551 ~IF
->Netmask
.Address
.IPv4Address
;
1553 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1554 IF
->Unicast
.Address
.IPv4Address
));
1555 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1556 IF
->Netmask
.Address
.IPv4Address
));
1558 IPAddInterfaceRoute( IF
);
1560 IpAddrChange
->Address
= IF
->Index
;
1561 Status
= STATUS_SUCCESS
;
1562 Irp
->IoStatus
.Information
= IF
->Index
;
1567 Irp
->IoStatus
.Status
= Status
;
1571 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1572 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1573 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1576 ForEachInterface(IF
) {
1577 if( IF
->Index
== *NteIndex
) {
1578 IPRemoveInterfaceRoute( IF
);
1579 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1580 IF
->Unicast
.Address
.IPv4Address
= 0;
1581 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1582 IF
->Netmask
.Address
.IPv4Address
= 0;
1583 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1584 IF
->Broadcast
.Address
.IPv4Address
= 0;
1585 Status
= STATUS_SUCCESS
;
1589 Irp
->IoStatus
.Status
= Status
;