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>
15 NTSTATUS
DispPrepareIrpForCancel(
16 PTRANSPORT_CONTEXT Context
,
18 PDRIVER_CANCEL CancelRoutine
)
20 * FUNCTION: Prepare an IRP for cancellation
22 * Context = Pointer to context information
23 * Irp = Pointer to an I/O request packet
24 * CancelRoutine = Routine to be called when I/O request is cancelled
30 PIO_STACK_LOCATION IrpSp
;
31 PTRANSPORT_CONTEXT TransContext
;
33 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
35 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
36 TransContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
38 IoAcquireCancelSpinLock(&OldIrql
);
40 if (!Irp
->Cancel
&& !TransContext
->CancelIrps
) {
41 (void)IoSetCancelRoutine(Irp
, CancelRoutine
);
42 IoReleaseCancelSpinLock(OldIrql
);
44 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
46 return STATUS_SUCCESS
;
49 /* IRP has already been cancelled */
51 IoReleaseCancelSpinLock(OldIrql
);
53 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
54 Irp
->IoStatus
.Information
= 0;
56 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
58 return Irp
->IoStatus
.Status
;
61 VOID
DispDataRequestComplete(
66 * FUNCTION: Completes a send/receive IRP
68 * Context = Pointer to context information (IRP)
69 * Status = Status of the request
70 * Count = Number of bytes sent or received
74 PIO_STACK_LOCATION IrpSp
;
75 PTRANSPORT_CONTEXT TranContext
;
78 TI_DbgPrint(DEBUG_IRP
, ("Called for irp %x (%x, %d).\n",
79 Context
, Status
, Count
));
82 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
83 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
85 IoAcquireCancelSpinLock(&OldIrql
);
87 (void)IoSetCancelRoutine(Irp
, NULL
);
89 IoReleaseCancelSpinLock(OldIrql
);
91 Irp
->IoStatus
.Status
= Status
;
92 Irp
->IoStatus
.Information
= Count
;
94 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
95 Irp
->IoStatus
.Status
));
96 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
97 Irp
->IoStatus
.Information
));
98 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
100 IRPFinish(Irp
, Status
);
102 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
105 VOID
DispDoDisconnect( PVOID Data
) {
106 PDISCONNECT_TYPE DisType
= (PDISCONNECT_TYPE
)Data
;
108 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect\n"));
109 TcpipRecursiveMutexEnter(&TCPLock
, TRUE
);
115 DispDataRequestComplete
,
117 TcpipRecursiveMutexLeave(&TCPLock
);
118 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect done\n"));
120 DispDataRequestComplete(DisType
->Irp
, STATUS_CANCELLED
, 0);
123 VOID NTAPI
DispCancelRequest(
124 PDEVICE_OBJECT Device
,
127 * FUNCTION: Cancels an IRP
129 * Device = Pointer to device object
130 * Irp = Pointer to an I/O request packet
133 PIO_STACK_LOCATION IrpSp
;
134 PTRANSPORT_CONTEXT TranContext
;
135 PFILE_OBJECT FileObject
;
137 DISCONNECT_TYPE DisType
;
139 /*NTSTATUS Status = STATUS_SUCCESS;*/
141 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
143 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
144 FileObject
= IrpSp
->FileObject
;
145 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
146 MinorFunction
= IrpSp
->MinorFunction
;
148 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
150 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
151 Irp
->IoStatus
.Information
= 0;
155 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
158 /* Try canceling the request */
159 switch(MinorFunction
) {
162 DisType
.Type
= TDI_DISCONNECT_RELEASE
|
163 ((MinorFunction
== TDI_RECEIVE
) ? TDI_DISCONNECT_ABORT
: 0);
164 DisType
.Context
= TranContext
->Handle
.ConnectionContext
;
166 DisType
.FileObject
= FileObject
;
168 TCPRemoveIRP( TranContext
->Handle
.ConnectionContext
, Irp
);
170 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
172 if( !ChewCreate( &WorkItem
, sizeof(DISCONNECT_TYPE
),
173 DispDoDisconnect
, &DisType
) )
177 case TDI_SEND_DATAGRAM
:
178 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
179 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
183 DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
186 case TDI_RECEIVE_DATAGRAM
:
187 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
188 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
192 DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
196 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
200 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
201 IRPFinish(Irp
, STATUS_CANCELLED
);
203 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
207 VOID NTAPI
DispCancelListenRequest(
208 PDEVICE_OBJECT Device
,
211 * FUNCTION: Cancels a listen IRP
213 * Device = Pointer to device object
214 * Irp = Pointer to an I/O request packet
217 PIO_STACK_LOCATION IrpSp
;
218 PTRANSPORT_CONTEXT TranContext
;
219 PFILE_OBJECT FileObject
;
220 PCONNECTION_ENDPOINT Connection
;
221 /*NTSTATUS Status = STATUS_SUCCESS;*/
223 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
225 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
226 FileObject
= IrpSp
->FileObject
;
227 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
228 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
230 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
234 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
237 /* Try canceling the request */
238 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
240 TCPRemoveIRP(Connection
, Irp
);
242 TCPAbortListenForSocket(
243 Connection
->AddressFile
->Listener
,
246 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
248 Irp
->IoStatus
.Information
= 0;
249 IRPFinish(Irp
, STATUS_CANCELLED
);
251 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
255 NTSTATUS
DispTdiAccept(
258 * FUNCTION: TDI_ACCEPT handler
260 * Irp = Pointer to an I/O request packet
262 * Status of operation
265 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
267 return STATUS_NOT_IMPLEMENTED
;
271 NTSTATUS
DispTdiAssociateAddress(
274 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
276 * Irp = Pointer to an I/O request packet
278 * Status of operation
281 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
282 PTRANSPORT_CONTEXT TranContext
;
283 PIO_STACK_LOCATION IrpSp
;
284 PCONNECTION_ENDPOINT Connection
;
285 PFILE_OBJECT FileObject
;
286 PADDRESS_FILE AddrFile
= NULL
;
289 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
291 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
293 /* Get associated connection endpoint file object. Quit if none exists */
295 TranContext
= IrpSp
->FileObject
->FsContext
;
297 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
298 return STATUS_INVALID_PARAMETER
;
301 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
303 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
304 return STATUS_INVALID_PARAMETER
;
307 if (Connection
->AddressFile
) {
308 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
309 return STATUS_INVALID_PARAMETER
;
312 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
314 Status
= ObReferenceObjectByHandle(
315 Parameters
->AddressHandle
,
321 if (!NT_SUCCESS(Status
)) {
322 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
323 Parameters
->AddressHandle
, Status
));
324 return STATUS_INVALID_PARAMETER
;
327 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
328 ObDereferenceObject(FileObject
);
329 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
330 FileObject
->FsContext2
));
331 return STATUS_INVALID_PARAMETER
;
334 /* Get associated address file object. Quit if none exists */
336 TranContext
= FileObject
->FsContext
;
338 ObDereferenceObject(FileObject
);
339 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
340 return STATUS_INVALID_PARAMETER
;
343 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
345 ObDereferenceObject(FileObject
);
346 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
347 return STATUS_INVALID_PARAMETER
;
350 Connection
->AddressFile
= AddrFile
;
352 /* Add connection endpoint to the address file */
353 AddrFile
->Connection
= Connection
;
355 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
356 ObDereferenceObject(FileObject
);
362 NTSTATUS
DispTdiConnect(
365 * FUNCTION: TDI_CONNECT handler
367 * Irp = Pointer to an I/O request packet
369 * Status of operation
372 PCONNECTION_ENDPOINT Connection
;
373 PTDI_REQUEST_KERNEL Parameters
;
374 PTRANSPORT_CONTEXT TranContext
;
375 PIO_STACK_LOCATION IrpSp
;
378 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
380 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
382 /* Get associated connection endpoint file object. Quit if none exists */
384 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
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
;
403 TranContext
->Handle
.ConnectionContext
,
404 Parameters
->RequestConnectionInformation
,
405 Parameters
->ReturnConnectionInformation
,
406 DispDataRequestComplete
,
410 TcpipRecursiveMutexLeave( &TCPLock
);
412 if (Status
!= STATUS_PENDING
) {
413 DispDataRequestComplete(Irp
, Status
, 0);
415 IoMarkIrpPending(Irp
);
417 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
423 NTSTATUS
DispTdiDisassociateAddress(
426 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
428 * Irp = Pointer to an I/O request packet
430 * Status of operation
433 PCONNECTION_ENDPOINT Connection
;
434 PTRANSPORT_CONTEXT TranContext
;
435 PIO_STACK_LOCATION IrpSp
;
437 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
439 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
441 /* Get associated connection endpoint file object. Quit if none exists */
443 TranContext
= IrpSp
->FileObject
->FsContext
;
445 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
446 return STATUS_INVALID_PARAMETER
;
449 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
451 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
452 return STATUS_INVALID_PARAMETER
;
455 if (!Connection
->AddressFile
) {
456 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
457 return STATUS_INVALID_PARAMETER
;
460 /* Remove this connection from the address file */
461 Connection
->AddressFile
->Connection
= NULL
;
463 /* Remove the address file from this connection */
464 Connection
->AddressFile
= NULL
;
466 return STATUS_SUCCESS
;
470 NTSTATUS
DispTdiDisconnect(
473 * FUNCTION: TDI_DISCONNECT handler
475 * Irp = Pointer to an I/O request packet
477 * Status of operation
481 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
482 PCONNECTION_ENDPOINT Connection
;
483 PTRANSPORT_CONTEXT TranContext
;
484 PIO_STACK_LOCATION IrpSp
;
486 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
488 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
489 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
491 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
493 /* Get associated connection endpoint file object. Quit if none exists */
495 TranContext
= IrpSp
->FileObject
->FsContext
;
497 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
498 Status
= STATUS_INVALID_PARAMETER
;
502 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
504 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
505 Status
= STATUS_INVALID_PARAMETER
;
509 Status
= TCPDisconnect(
510 TranContext
->Handle
.ConnectionContext
,
511 DisReq
->RequestFlags
,
512 DisReq
->RequestConnectionInformation
,
513 DisReq
->ReturnConnectionInformation
,
514 DispDataRequestComplete
,
518 TcpipRecursiveMutexLeave( &TCPLock
);
520 if (Status
!= STATUS_PENDING
) {
521 DispDataRequestComplete(Irp
, Status
, 0);
523 IoMarkIrpPending(Irp
);
525 TI_DbgPrint(MAX_TRACE
, ("TCP Disconnect returned %08x\n", Status
));
531 NTSTATUS
DispTdiListen(
534 * FUNCTION: TDI_LISTEN handler
536 * Irp = Pointer to an I/O request packet
538 * Status of operation
541 PCONNECTION_ENDPOINT Connection
;
542 PTDI_REQUEST_KERNEL Parameters
;
543 PTRANSPORT_CONTEXT TranContext
;
544 PIO_STACK_LOCATION IrpSp
;
545 NTSTATUS Status
= STATUS_SUCCESS
;
547 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
549 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
551 /* Get associated connection endpoint file object. Quit if none exists */
553 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
555 TranContext
= IrpSp
->FileObject
->FsContext
;
556 if (TranContext
== NULL
)
558 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
559 Status
= STATUS_INVALID_PARAMETER
;
563 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
564 if (Connection
== NULL
)
566 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
567 Status
= STATUS_INVALID_PARAMETER
;
571 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
573 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile: %x\n",
574 Connection
->AddressFile
));
575 if( Connection
->AddressFile
) {
576 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile->Listener: %x\n",
577 Connection
->AddressFile
->Listener
));
580 /* Listening will require us to create a listening socket and store it in
581 * the address file. It will be signalled, and attempt to complete an irp
582 * when a new connection arrives. */
583 /* The important thing to note here is that the irp we'll complete belongs
584 * to the socket to be accepted onto, not the listener */
585 if( !Connection
->AddressFile
->Listener
) {
586 Connection
->AddressFile
->Listener
=
587 TCPAllocateConnectionEndpoint( NULL
);
589 if( !Connection
->AddressFile
->Listener
)
590 Status
= STATUS_NO_MEMORY
;
592 if( NT_SUCCESS(Status
) ) {
593 Connection
->AddressFile
->Listener
->AddressFile
=
594 Connection
->AddressFile
;
596 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
597 Connection
->AddressFile
->Family
,
599 Connection
->AddressFile
->Protocol
);
602 if( NT_SUCCESS(Status
) )
603 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
606 if( NT_SUCCESS(Status
) ) {
607 Status
= DispPrepareIrpForCancel
608 (TranContext
->Handle
.ConnectionContext
,
610 (PDRIVER_CANCEL
)DispCancelListenRequest
);
613 if( NT_SUCCESS(Status
) ) {
615 ( (PTDI_REQUEST
)Parameters
,
616 Connection
->AddressFile
->Listener
,
618 DispDataRequestComplete
,
623 TcpipRecursiveMutexLeave( &TCPLock
);
625 if (Status
!= STATUS_PENDING
) {
626 DispDataRequestComplete(Irp
, Status
, 0);
628 IoMarkIrpPending(Irp
);
630 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
636 NTSTATUS
DispTdiQueryInformation(
637 PDEVICE_OBJECT DeviceObject
,
640 * FUNCTION: TDI_QUERY_INFORMATION handler
642 * DeviceObject = Pointer to device object structure
643 * Irp = Pointer to an I/O request packet
645 * Status of operation
648 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
649 PTRANSPORT_CONTEXT TranContext
;
650 PIO_STACK_LOCATION IrpSp
;
653 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
655 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
656 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
658 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
660 TranContext
= IrpSp
->FileObject
->FsContext
;
662 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
663 TcpipRecursiveMutexLeave(&TCPLock
);
664 return STATUS_INVALID_PARAMETER
;
667 switch (Parameters
->QueryType
)
669 case TDI_QUERY_ADDRESS_INFO
:
671 PTDI_ADDRESS_INFO AddressInfo
;
672 PADDRESS_FILE AddrFile
;
673 PTA_IP_ADDRESS Address
;
674 PCONNECTION_ENDPOINT Endpoint
= NULL
;
677 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
678 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
679 sizeof(TDI_ADDRESS_IP
))) {
680 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
681 TcpipRecursiveMutexLeave(&TCPLock
);
682 return STATUS_BUFFER_TOO_SMALL
;
685 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
686 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
688 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
689 case TDI_TRANSPORT_ADDRESS_FILE
:
690 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
692 Address
->TAAddressCount
= 1;
693 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
694 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
695 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
696 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->Address
.Address
.IPv4Address
;
698 &Address
->Address
[0].Address
[0].sin_zero
,
699 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
700 TcpipRecursiveMutexLeave(&TCPLock
);
701 return STATUS_SUCCESS
;
703 case TDI_CONNECTION_FILE
:
705 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
706 TCPGetSockAddress( Endpoint
, (PTRANSPORT_ADDRESS
)Address
, FALSE
);
707 DbgPrint("Returning socket address %x\n", Address
->Address
[0].Address
[0].in_addr
);
709 &Address
->Address
[0].Address
[0].sin_zero
,
710 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
711 TcpipRecursiveMutexLeave(&TCPLock
);
712 return STATUS_SUCCESS
;
715 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
716 TcpipRecursiveMutexLeave(&TCPLock
);
717 return STATUS_INVALID_PARAMETER
;
721 case TDI_QUERY_CONNECTION_INFO
:
723 PTDI_CONNECTION_INFORMATION AddressInfo
;
724 PADDRESS_FILE AddrFile
;
725 PCONNECTION_ENDPOINT Endpoint
= NULL
;
727 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
728 (FIELD_OFFSET(TDI_CONNECTION_INFORMATION
, RemoteAddress
) +
730 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small (ptr).\n"));
731 TcpipRecursiveMutexLeave(&TCPLock
);
732 return STATUS_BUFFER_TOO_SMALL
;
735 AddressInfo
= (PTDI_CONNECTION_INFORMATION
)
736 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
738 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
739 case TDI_TRANSPORT_ADDRESS_FILE
:
740 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
741 Endpoint
= AddrFile
? AddrFile
->Connection
: NULL
;
744 case TDI_CONNECTION_FILE
:
746 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
750 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
751 TcpipRecursiveMutexLeave(&TCPLock
);
752 return STATUS_INVALID_PARAMETER
;
756 TI_DbgPrint(MID_TRACE
, ("No connection object.\n"));
757 TcpipRecursiveMutexLeave(&TCPLock
);
758 return STATUS_INVALID_PARAMETER
;
761 Status
= TCPGetSockAddress( Endpoint
, AddressInfo
->RemoteAddress
, TRUE
);
763 TcpipRecursiveMutexLeave(&TCPLock
);
768 TcpipRecursiveMutexLeave(&TCPLock
);
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 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
796 TranContext
= IrpSp
->FileObject
->FsContext
;
797 if (TranContext
== NULL
)
799 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
800 Status
= STATUS_INVALID_PARAMETER
;
804 if (TranContext
->Handle
.ConnectionContext
== NULL
)
806 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
807 Status
= STATUS_INVALID_PARAMETER
;
811 /* Initialize a receive request */
812 Status
= DispPrepareIrpForCancel
813 (TranContext
->Handle
.ConnectionContext
,
815 (PDRIVER_CANCEL
)DispCancelRequest
);
817 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
818 if (NT_SUCCESS(Status
))
820 Status
= TCPReceiveData(
821 TranContext
->Handle
.ConnectionContext
,
822 (PNDIS_BUFFER
)Irp
->MdlAddress
,
823 ReceiveInfo
->ReceiveLength
,
825 ReceiveInfo
->ReceiveFlags
,
826 DispDataRequestComplete
,
831 TcpipRecursiveMutexLeave( &TCPLock
);
833 if (Status
!= STATUS_PENDING
) {
834 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
836 IoMarkIrpPending(Irp
);
838 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
844 NTSTATUS
DispTdiReceiveDatagram(
847 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
849 * Irp = Pointer to an I/O request packet
851 * Status of operation
854 PIO_STACK_LOCATION IrpSp
;
855 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
856 PTRANSPORT_CONTEXT TranContext
;
859 ULONG BytesReceived
= 0;
861 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
863 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
864 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
866 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
868 TranContext
= IrpSp
->FileObject
->FsContext
;
869 if (TranContext
== NULL
)
871 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
872 Status
= STATUS_INVALID_PARAMETER
;
876 /* Initialize a receive request */
877 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
878 Request
.RequestNotifyObject
= DispDataRequestComplete
;
879 Request
.RequestContext
= Irp
;
881 Status
= DispPrepareIrpForCancel(
882 IrpSp
->FileObject
->FsContext
,
884 (PDRIVER_CANCEL
)DispCancelRequest
);
886 if (NT_SUCCESS(Status
))
891 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
895 Status
= DGReceiveDatagram(
896 Request
.Handle
.AddressHandle
,
897 DgramInfo
->ReceiveDatagramInformation
,
899 DgramInfo
->ReceiveLength
,
900 DgramInfo
->ReceiveFlags
,
901 DgramInfo
->ReturnDatagramInformation
,
903 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
909 TcpipRecursiveMutexLeave( &TCPLock
);
911 if (Status
!= STATUS_PENDING
) {
912 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
914 IoMarkIrpPending(Irp
);
916 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
922 NTSTATUS
DispTdiSend(
925 * FUNCTION: TDI_SEND handler
927 * Irp = Pointer to an I/O request packet
929 * Status of operation
932 PIO_STACK_LOCATION IrpSp
;
933 PTDI_REQUEST_KERNEL_SEND SendInfo
;
934 PTRANSPORT_CONTEXT TranContext
;
938 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
940 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
941 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
943 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
945 TranContext
= IrpSp
->FileObject
->FsContext
;
946 if (TranContext
== NULL
)
948 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
949 Status
= STATUS_INVALID_PARAMETER
;
953 if (TranContext
->Handle
.ConnectionContext
== NULL
)
955 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
956 Status
= STATUS_INVALID_PARAMETER
;
960 Status
= DispPrepareIrpForCancel(
961 IrpSp
->FileObject
->FsContext
,
963 (PDRIVER_CANCEL
)DispCancelRequest
);
965 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
966 if (NT_SUCCESS(Status
))
971 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
973 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
974 Status
= TCPSendData(
975 TranContext
->Handle
.ConnectionContext
,
977 SendInfo
->SendLength
,
980 DispDataRequestComplete
,
985 TcpipRecursiveMutexLeave( &TCPLock
);
987 if (Status
!= STATUS_PENDING
) {
988 DispDataRequestComplete(Irp
, Status
, BytesSent
);
990 IoMarkIrpPending(Irp
);
992 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
998 NTSTATUS
DispTdiSendDatagram(
1001 * FUNCTION: TDI_SEND_DATAGRAM handler
1003 * Irp = Pointer to an I/O request packet
1005 * Status of operation
1008 PIO_STACK_LOCATION IrpSp
;
1009 TDI_REQUEST Request
;
1010 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
1011 PTRANSPORT_CONTEXT TranContext
;
1014 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1016 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1017 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
1019 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
1021 TranContext
= IrpSp
->FileObject
->FsContext
;
1022 if (TranContext
== NULL
)
1024 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
1025 Status
= STATUS_INVALID_PARAMETER
;
1029 /* Initialize a send request */
1030 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1031 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1032 Request
.RequestContext
= Irp
;
1034 Status
= DispPrepareIrpForCancel(
1035 IrpSp
->FileObject
->FsContext
,
1037 (PDRIVER_CANCEL
)DispCancelRequest
);
1039 if (NT_SUCCESS(Status
)) {
1043 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
1045 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
1049 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
1050 must be of type PTDI_ADDRESS_IP */
1051 TI_DbgPrint(MID_TRACE
,
1052 ("About to call send routine %x\n",
1053 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
1055 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
) )
1056 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
1057 Request
.Handle
.AddressHandle
,
1058 DgramInfo
->SendDatagramInformation
,
1061 &Irp
->IoStatus
.Information
);
1063 Status
= STATUS_UNSUCCESSFUL
;
1067 TcpipRecursiveMutexLeave( &TCPLock
);
1069 if (Status
!= STATUS_PENDING
) {
1070 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
1072 IoMarkIrpPending(Irp
);
1074 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
1080 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
1082 * FUNCTION: TDI_SET_EVENT_HANDER handler
1084 * Irp = Pointer to a I/O request packet
1086 * Status of operation
1089 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1090 PTRANSPORT_CONTEXT TranContext
;
1091 PIO_STACK_LOCATION IrpSp
;
1092 PADDRESS_FILE AddrFile
;
1096 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1098 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1100 /* Get associated address file object. Quit if none exists */
1102 TranContext
= IrpSp
->FileObject
->FsContext
;
1104 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1105 return STATUS_INVALID_PARAMETER
;
1108 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1110 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1111 return STATUS_INVALID_PARAMETER
;
1114 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1115 Status
= STATUS_SUCCESS
;
1117 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
1119 /* Set the event handler. if an event handler is associated with
1120 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1121 If an event handler is not used it's flag is FALSE */
1122 switch (Parameters
->EventType
) {
1123 case TDI_EVENT_CONNECT
:
1124 if (!Parameters
->EventHandler
) {
1125 AddrFile
->ConnectHandlerContext
= NULL
;
1126 AddrFile
->RegisteredConnectHandler
= FALSE
;
1128 AddrFile
->ConnectHandler
=
1129 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1130 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1131 AddrFile
->RegisteredConnectHandler
= TRUE
;
1135 case TDI_EVENT_DISCONNECT
:
1136 if (!Parameters
->EventHandler
) {
1137 AddrFile
->DisconnectHandlerContext
= NULL
;
1138 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1140 AddrFile
->DisconnectHandler
=
1141 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1142 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1143 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1147 case TDI_EVENT_ERROR
:
1148 if (Parameters
->EventHandler
== NULL
) {
1149 AddrFile
->ErrorHandlerContext
= NULL
;
1150 AddrFile
->RegisteredErrorHandler
= FALSE
;
1152 AddrFile
->ErrorHandler
=
1153 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1154 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1155 AddrFile
->RegisteredErrorHandler
= TRUE
;
1159 case TDI_EVENT_RECEIVE
:
1160 if (Parameters
->EventHandler
== NULL
) {
1161 AddrFile
->ReceiveHandlerContext
= NULL
;
1162 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1164 AddrFile
->ReceiveHandler
=
1165 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1166 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1167 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1171 case TDI_EVENT_RECEIVE_DATAGRAM
:
1172 if (Parameters
->EventHandler
== NULL
) {
1173 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1174 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1176 AddrFile
->ReceiveDatagramHandler
=
1177 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1178 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1179 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1183 case TDI_EVENT_RECEIVE_EXPEDITED
:
1184 if (Parameters
->EventHandler
== NULL
) {
1185 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1186 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1188 AddrFile
->ExpeditedReceiveHandler
=
1189 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1190 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1191 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1195 case TDI_EVENT_CHAINED_RECEIVE
:
1196 if (Parameters
->EventHandler
== NULL
) {
1197 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1198 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1200 AddrFile
->ChainedReceiveHandler
=
1201 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1202 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1203 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1207 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1208 if (Parameters
->EventHandler
== NULL
) {
1209 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1210 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1212 AddrFile
->ChainedReceiveDatagramHandler
=
1213 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1214 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1215 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1219 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1220 if (Parameters
->EventHandler
== NULL
) {
1221 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1222 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1224 AddrFile
->ChainedReceiveExpeditedHandler
=
1225 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1226 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1227 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1232 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1233 Parameters
->EventType
));
1235 Status
= STATUS_INVALID_PARAMETER
;
1238 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1244 NTSTATUS
DispTdiSetInformation(
1247 * FUNCTION: TDI_SET_INFORMATION handler
1249 * Irp = Pointer to an I/O request packet
1251 * Status of operation
1254 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1256 return STATUS_NOT_IMPLEMENTED
;
1260 VOID
DispTdiQueryInformationExComplete(
1265 * FUNCTION: Completes a TDI QueryInformationEx request
1267 * Context = Pointer to the IRP for the request
1268 * Status = TDI status of the request
1269 * ByteCount = Number of bytes returned in output buffer
1272 PTI_QUERY_CONTEXT QueryContext
;
1275 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1276 if (NT_SUCCESS(Status
)) {
1277 Count
= CopyBufferToBufferChain(
1278 QueryContext
->InputMdl
,
1279 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1280 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1284 MmUnlockPages(QueryContext
->InputMdl
);
1285 IoFreeMdl(QueryContext
->InputMdl
);
1286 if( QueryContext
->OutputMdl
) {
1287 MmUnlockPages(QueryContext
->OutputMdl
);
1288 IoFreeMdl(QueryContext
->OutputMdl
);
1291 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1292 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1294 exFreePool(QueryContext
);
1298 NTSTATUS
DispTdiQueryInformationEx(
1300 PIO_STACK_LOCATION IrpSp
)
1302 * FUNCTION: TDI QueryInformationEx handler
1304 * Irp = Pointer to I/O request packet
1305 * IrpSp = Pointer to current stack location of Irp
1307 * Status of operation
1310 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1311 PTRANSPORT_CONTEXT TranContext
;
1312 PTI_QUERY_CONTEXT QueryContext
;
1314 TDI_REQUEST Request
;
1316 UINT InputBufferLength
;
1317 UINT OutputBufferLength
;
1318 BOOLEAN InputMdlLocked
= FALSE
;
1319 BOOLEAN OutputMdlLocked
= FALSE
;
1320 PMDL InputMdl
= NULL
;
1321 PMDL OutputMdl
= NULL
;
1322 NTSTATUS Status
= STATUS_SUCCESS
;
1324 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1326 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1328 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1329 case TDI_TRANSPORT_ADDRESS_FILE
:
1330 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1333 case TDI_CONNECTION_FILE
:
1334 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1337 case TDI_CONTROL_CHANNEL_FILE
:
1338 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1342 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1343 return STATUS_INVALID_PARAMETER
;
1346 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1347 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1349 /* Validate parameters */
1350 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1351 (OutputBufferLength
!= 0)) {
1353 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1354 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1355 OutputBuffer
= Irp
->UserBuffer
;
1357 QueryContext
= exAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1360 InputMdl
= IoAllocateMdl(InputBuffer
,
1361 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1364 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1365 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1367 if (InputMdl
&& OutputMdl
) {
1369 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1372 InputMdlLocked
= TRUE
;
1374 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1377 OutputMdlLocked
= TRUE
;
1379 RtlCopyMemory(&QueryContext
->QueryInfo
,
1380 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1382 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1383 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1384 Status
= _SEH2_GetExceptionCode();
1387 if (NT_SUCCESS(Status
)) {
1388 Size
= MmGetMdlByteCount(OutputMdl
);
1390 QueryContext
->Irp
= Irp
;
1391 QueryContext
->InputMdl
= InputMdl
;
1392 QueryContext
->OutputMdl
= OutputMdl
;
1394 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1395 Request
.RequestContext
= QueryContext
;
1396 Status
= InfoTdiQueryInformationEx(&Request
,
1397 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1398 &Size
, &QueryContext
->QueryInfo
.Context
);
1399 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1401 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1406 /* An error occurred if we get here */
1410 MmUnlockPages(InputMdl
);
1411 IoFreeMdl(InputMdl
);
1415 if (OutputMdlLocked
)
1416 MmUnlockPages(OutputMdl
);
1417 IoFreeMdl(OutputMdl
);
1420 exFreePool(QueryContext
);
1422 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1423 } else if( InputBufferLength
==
1424 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1425 /* Handle the case where the user is probing the buffer for length */
1426 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1427 InputBufferLength
, OutputBufferLength
));
1428 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1429 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1433 QueryContext
= exAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1434 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1437 InputMdl
= IoAllocateMdl(InputBuffer
,
1438 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1441 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1444 InputMdlLocked
= TRUE
;
1445 Status
= STATUS_SUCCESS
;
1446 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1447 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1448 Status
= _SEH2_GetExceptionCode();
1451 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1452 if( InputMdl
) IoFreeMdl( InputMdl
);
1453 exFreePool(QueryContext
);
1457 RtlCopyMemory(&QueryContext
->QueryInfo
,
1458 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1460 QueryContext
->Irp
= Irp
;
1461 QueryContext
->InputMdl
= InputMdl
;
1462 QueryContext
->OutputMdl
= NULL
;
1464 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1465 Request
.RequestContext
= QueryContext
;
1466 Status
= InfoTdiQueryInformationEx(&Request
,
1467 &QueryContext
->QueryInfo
.ID
,
1470 &QueryContext
->QueryInfo
.Context
);
1471 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1472 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1473 } else Status
= STATUS_INVALID_PARAMETER
;
1475 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1481 NTSTATUS
DispTdiSetInformationEx(
1483 PIO_STACK_LOCATION IrpSp
)
1485 * FUNCTION: TDI SetInformationEx handler
1487 * Irp = Pointer to I/O request packet
1488 * IrpSp = Pointer to current stack location of Irp
1490 * Status of operation
1493 PTRANSPORT_CONTEXT TranContext
;
1494 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1495 TDI_REQUEST Request
;
1498 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1500 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1501 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1503 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1504 case TDI_TRANSPORT_ADDRESS_FILE
:
1505 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1508 case TDI_CONNECTION_FILE
:
1509 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1512 case TDI_CONTROL_CHANNEL_FILE
:
1513 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1517 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1518 Irp
->IoStatus
.Information
= 0;
1520 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1522 return Irp
->IoStatus
.Status
;
1525 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1526 if (NT_SUCCESS(Status
)) {
1527 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1528 Request
.RequestContext
= Irp
;
1530 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1531 &Info
->Buffer
, Info
->BufferSize
);
1537 /* TODO: Support multiple addresses per interface.
1538 * For now just set the nte context to the interface index.
1540 * Later on, create an NTE context and NTE instance
1543 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1544 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1545 PIP_SET_ADDRESS IpAddrChange
=
1546 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1549 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1550 IpAddrChange
->NteIndex
));
1552 ForEachInterface(IF
) {
1553 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1555 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1556 Status
= STATUS_DUPLICATE_OBJECTID
;
1559 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1560 IPRemoveInterfaceRoute( IF
);
1562 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1563 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1564 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1565 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1566 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1567 IF
->Broadcast
.Address
.IPv4Address
=
1568 IF
->Unicast
.Address
.IPv4Address
|
1569 ~IF
->Netmask
.Address
.IPv4Address
;
1571 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1572 IF
->Unicast
.Address
.IPv4Address
));
1573 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1574 IF
->Netmask
.Address
.IPv4Address
));
1576 IPAddInterfaceRoute( IF
);
1578 IpAddrChange
->Address
= IF
->Index
;
1579 Status
= STATUS_SUCCESS
;
1580 Irp
->IoStatus
.Information
= IF
->Index
;
1585 Irp
->IoStatus
.Status
= Status
;
1589 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1590 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1591 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1594 ForEachInterface(IF
) {
1595 if( IF
->Index
== *NteIndex
) {
1596 IPRemoveInterfaceRoute( IF
);
1597 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1598 IF
->Unicast
.Address
.IPv4Address
= 0;
1599 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1600 IF
->Netmask
.Address
.IPv4Address
= 0;
1601 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1602 IF
->Broadcast
.Address
.IPv4Address
= 0;
1603 Status
= STATUS_SUCCESS
;
1607 Irp
->IoStatus
.Status
= Status
;