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/pseh.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
31 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
33 IoAcquireCancelSpinLock(&OldIrql
);
36 (void)IoSetCancelRoutine(Irp
, CancelRoutine
);
37 IoReleaseCancelSpinLock(OldIrql
);
39 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
41 return STATUS_SUCCESS
;
44 /* IRP has already been cancelled */
46 IoReleaseCancelSpinLock(OldIrql
);
48 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
49 Irp
->IoStatus
.Information
= 0;
51 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
53 return IRPFinish(Irp
, STATUS_CANCELLED
);
56 VOID
DispDataRequestComplete(
61 * FUNCTION: Completes a send/receive IRP
63 * Context = Pointer to context information (IRP)
64 * Status = Status of the request
65 * Count = Number of bytes sent or received
69 PIO_STACK_LOCATION IrpSp
;
70 PTRANSPORT_CONTEXT TranContext
;
73 TI_DbgPrint(DEBUG_IRP
, ("Called for irp %x (%x, %d).\n",
74 Context
, Status
, Count
));
77 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
78 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
80 IoAcquireCancelSpinLock(&OldIrql
);
82 (void)IoSetCancelRoutine(Irp
, NULL
);
84 if (Irp
->Cancel
|| TranContext
->CancelIrps
) {
85 /* The IRP has been cancelled */
87 TI_DbgPrint(DEBUG_IRP
, ("IRP is cancelled.\n"));
89 Status
= STATUS_CANCELLED
;
93 IoReleaseCancelSpinLock(OldIrql
);
95 Irp
->IoStatus
.Status
= Status
;
96 Irp
->IoStatus
.Information
= Count
;
98 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
99 Irp
->IoStatus
.Status
));
100 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
101 Irp
->IoStatus
.Information
));
102 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
104 IRPFinish(Irp
, Irp
->IoStatus
.Status
);
106 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
109 typedef struct _DISCONNECT_TYPE
{
113 PFILE_OBJECT FileObject
;
114 } DISCONNECT_TYPE
, *PDISCONNECT_TYPE
;
116 VOID
DispDoDisconnect( PVOID Data
) {
117 PDISCONNECT_TYPE DisType
= (PDISCONNECT_TYPE
)Data
;
119 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect\n"));
125 DispDataRequestComplete
,
127 TI_DbgPrint(DEBUG_IRP
, ("PostCancel: DoDisconnect done\n"));
129 DispDataRequestComplete(DisType
->Irp
, STATUS_CANCELLED
, 0);
132 VOID NTAPI
DispCancelRequest(
133 PDEVICE_OBJECT Device
,
136 * FUNCTION: Cancels an IRP
138 * Device = Pointer to device object
139 * Irp = Pointer to an I/O request packet
142 PIO_STACK_LOCATION IrpSp
;
143 PTRANSPORT_CONTEXT TranContext
;
144 PFILE_OBJECT FileObject
;
146 DISCONNECT_TYPE DisType
;
148 /*NTSTATUS Status = STATUS_SUCCESS;*/
150 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
152 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
153 FileObject
= IrpSp
->FileObject
;
154 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
155 MinorFunction
= IrpSp
->MinorFunction
;
157 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
159 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
160 Irp
->IoStatus
.Information
= 0;
164 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
167 /* Try canceling the request */
168 switch(MinorFunction
) {
171 DisType
.Type
= TDI_DISCONNECT_RELEASE
|
172 ((MinorFunction
== TDI_RECEIVE
) ? TDI_DISCONNECT_ABORT
: 0);
173 DisType
.Context
= TranContext
->Handle
.ConnectionContext
;
175 DisType
.FileObject
= FileObject
;
177 TCPRemoveIRP( TranContext
->Handle
.ConnectionContext
, Irp
);
179 if( !ChewCreate( &WorkItem
, sizeof(DISCONNECT_TYPE
),
180 DispDoDisconnect
, &DisType
) )
184 case TDI_SEND_DATAGRAM
:
185 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
186 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
190 case TDI_RECEIVE_DATAGRAM
:
191 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
192 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
195 DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
199 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
203 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
204 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
206 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
210 VOID NTAPI
DispCancelListenRequest(
211 PDEVICE_OBJECT Device
,
214 * FUNCTION: Cancels a listen IRP
216 * Device = Pointer to device object
217 * Irp = Pointer to an I/O request packet
220 PIO_STACK_LOCATION IrpSp
;
221 PTRANSPORT_CONTEXT TranContext
;
222 PFILE_OBJECT FileObject
;
223 PCONNECTION_ENDPOINT Connection
;
224 /*NTSTATUS Status = STATUS_SUCCESS;*/
226 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
228 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
229 FileObject
= IrpSp
->FileObject
;
230 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
231 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
233 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
237 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
240 /* Try canceling the request */
241 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
242 TCPAbortListenForSocket(
243 Connection
->AddressFile
->Listener
,
246 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
248 DispDataRequestComplete(Irp
, STATUS_CANCELLED
, 0);
250 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
254 NTSTATUS
DispTdiAccept(
257 * FUNCTION: TDI_ACCEPT handler
259 * Irp = Pointer to an I/O request packet
261 * Status of operation
264 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
266 return STATUS_NOT_IMPLEMENTED
;
270 NTSTATUS
DispTdiAssociateAddress(
273 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
275 * Irp = Pointer to an I/O request packet
277 * Status of operation
280 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
281 PTRANSPORT_CONTEXT TranContext
;
282 PIO_STACK_LOCATION IrpSp
;
283 PCONNECTION_ENDPOINT Connection
;
284 PFILE_OBJECT FileObject
;
285 PADDRESS_FILE AddrFile
= NULL
;
288 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
290 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
292 /* Get associated connection endpoint file object. Quit if none exists */
294 TranContext
= IrpSp
->FileObject
->FsContext
;
296 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
297 return STATUS_INVALID_PARAMETER
;
300 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
302 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
303 return STATUS_INVALID_PARAMETER
;
306 if (Connection
->AddressFile
) {
307 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
308 return STATUS_INVALID_PARAMETER
;
311 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
313 Status
= ObReferenceObjectByHandle(
314 Parameters
->AddressHandle
,
320 if (!NT_SUCCESS(Status
)) {
321 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
322 Parameters
->AddressHandle
, Status
));
323 return STATUS_INVALID_PARAMETER
;
326 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
327 ObDereferenceObject(FileObject
);
328 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
329 FileObject
->FsContext2
));
330 return STATUS_INVALID_PARAMETER
;
333 /* Get associated address file object. Quit if none exists */
335 TranContext
= FileObject
->FsContext
;
337 ObDereferenceObject(FileObject
);
338 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
339 return STATUS_INVALID_PARAMETER
;
342 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
344 ObDereferenceObject(FileObject
);
345 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
346 return STATUS_INVALID_PARAMETER
;
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
);
361 NTSTATUS
DispTdiConnect(
364 * FUNCTION: TDI_CONNECT handler
366 * Irp = Pointer to an I/O request packet
368 * Status of operation
371 PCONNECTION_ENDPOINT Connection
;
372 PTDI_REQUEST_KERNEL Parameters
;
373 PTRANSPORT_CONTEXT TranContext
;
374 PIO_STACK_LOCATION IrpSp
;
377 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
379 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
381 /* Get associated connection endpoint file object. Quit if none exists */
383 TranContext
= IrpSp
->FileObject
->FsContext
;
385 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
386 return STATUS_INVALID_CONNECTION
;
389 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
391 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
392 return STATUS_INVALID_CONNECTION
;
395 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
398 TranContext
->Handle
.ConnectionContext
,
399 Parameters
->RequestConnectionInformation
,
400 Parameters
->ReturnConnectionInformation
,
401 DispDataRequestComplete
,
404 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
410 NTSTATUS
DispTdiDisassociateAddress(
413 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
415 * Irp = Pointer to an I/O request packet
417 * Status of operation
420 PCONNECTION_ENDPOINT Connection
;
421 PTRANSPORT_CONTEXT TranContext
;
422 PIO_STACK_LOCATION IrpSp
;
424 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
426 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
428 /* Get associated connection endpoint file object. Quit if none exists */
430 TranContext
= IrpSp
->FileObject
->FsContext
;
432 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
433 return STATUS_INVALID_PARAMETER
;
436 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
438 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
439 return STATUS_INVALID_PARAMETER
;
442 if (!Connection
->AddressFile
) {
443 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
444 return STATUS_INVALID_PARAMETER
;
447 return STATUS_SUCCESS
;
451 NTSTATUS
DispTdiDisconnect(
454 * FUNCTION: TDI_DISCONNECT handler
456 * Irp = Pointer to an I/O request packet
458 * Status of operation
462 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
463 PCONNECTION_ENDPOINT Connection
;
464 PTRANSPORT_CONTEXT TranContext
;
465 PIO_STACK_LOCATION IrpSp
;
467 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
469 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
470 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
472 /* Get associated connection endpoint file object. Quit if none exists */
474 TranContext
= IrpSp
->FileObject
->FsContext
;
476 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
477 return STATUS_INVALID_CONNECTION
;
480 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
482 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
483 return STATUS_INVALID_CONNECTION
;
486 Status
= TCPDisconnect(
487 TranContext
->Handle
.ConnectionContext
,
488 DisReq
->RequestFlags
,
489 DisReq
->RequestConnectionInformation
,
490 DisReq
->ReturnConnectionInformation
,
491 DispDataRequestComplete
,
494 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
500 NTSTATUS
DispTdiListen(
503 * FUNCTION: TDI_LISTEN handler
505 * Irp = Pointer to an I/O request packet
507 * Status of operation
510 PCONNECTION_ENDPOINT Connection
;
511 PTDI_REQUEST_KERNEL Parameters
;
512 PTRANSPORT_CONTEXT TranContext
;
513 PIO_STACK_LOCATION IrpSp
;
514 NTSTATUS Status
= STATUS_SUCCESS
;
516 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
518 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
520 /* Get associated connection endpoint file object. Quit if none exists */
522 TranContext
= IrpSp
->FileObject
->FsContext
;
523 if (TranContext
== NULL
)
525 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
526 return STATUS_INVALID_CONNECTION
;
529 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
530 if (Connection
== NULL
)
532 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
533 return STATUS_INVALID_CONNECTION
;
536 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
538 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile: %x\n",
539 Connection
->AddressFile
));
540 if( Connection
->AddressFile
) {
541 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile->Listener: %x\n",
542 Connection
->AddressFile
->Listener
));
545 /* Listening will require us to create a listening socket and store it in
546 * the address file. It will be signalled, and attempt to complete an irp
547 * when a new connection arrives. */
548 /* The important thing to note here is that the irp we'll complete belongs
549 * to the socket to be accepted onto, not the listener */
550 if( !Connection
->AddressFile
->Listener
) {
551 Connection
->AddressFile
->Listener
=
552 TCPAllocateConnectionEndpoint( NULL
);
554 if( !Connection
->AddressFile
->Listener
)
555 Status
= STATUS_NO_MEMORY
;
557 if( NT_SUCCESS(Status
) ) {
558 Connection
->AddressFile
->Listener
->AddressFile
=
559 Connection
->AddressFile
;
561 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
562 Connection
->AddressFile
->Family
,
564 Connection
->AddressFile
->Protocol
);
567 if( NT_SUCCESS(Status
) )
568 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
571 if( NT_SUCCESS(Status
) ) {
572 Status
= DispPrepareIrpForCancel
573 (TranContext
->Handle
.ConnectionContext
,
575 (PDRIVER_CANCEL
)DispCancelListenRequest
);
578 if( NT_SUCCESS(Status
) ) {
580 ( (PTDI_REQUEST
)Parameters
,
581 Connection
->AddressFile
->Listener
,
583 DispDataRequestComplete
,
587 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
593 NTSTATUS
DispTdiQueryInformation(
594 PDEVICE_OBJECT DeviceObject
,
597 * FUNCTION: TDI_QUERY_INFORMATION handler
599 * DeviceObject = Pointer to device object structure
600 * Irp = Pointer to an I/O request packet
602 * Status of operation
605 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
606 PTRANSPORT_CONTEXT TranContext
;
607 PIO_STACK_LOCATION IrpSp
;
609 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
611 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
612 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
614 TranContext
= IrpSp
->FileObject
->FsContext
;
616 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
617 return STATUS_INVALID_CONNECTION
;
620 switch (Parameters
->QueryType
)
622 case TDI_QUERY_ADDRESS_INFO
:
624 PTDI_ADDRESS_INFO AddressInfo
;
625 PADDRESS_FILE AddrFile
;
626 PTA_IP_ADDRESS Address
;
628 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
630 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
631 case TDI_TRANSPORT_ADDRESS_FILE
:
632 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
635 case TDI_CONNECTION_FILE
:
637 ((PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
)->
642 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
643 return STATUS_INVALID_PARAMETER
;
647 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
648 return STATUS_INVALID_PARAMETER
;
651 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
652 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
653 sizeof(TDI_ADDRESS_IP
))) {
654 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
655 return STATUS_BUFFER_OVERFLOW
;
658 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
659 Address
->TAAddressCount
= 1;
660 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
661 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
662 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
663 Address
->Address
[0].Address
[0].in_addr
=
664 AddrFile
->Address
.Address
.IPv4Address
;
666 &Address
->Address
[0].Address
[0].sin_zero
,
667 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
669 return STATUS_SUCCESS
;
672 case TDI_QUERY_CONNECTION_INFO
:
674 PTDI_CONNECTION_INFORMATION AddressInfo
;
675 PADDRESS_FILE AddrFile
;
676 PCONNECTION_ENDPOINT Endpoint
= NULL
;
678 AddressInfo
= (PTDI_CONNECTION_INFORMATION
)
679 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
681 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
682 case TDI_TRANSPORT_ADDRESS_FILE
:
683 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
686 case TDI_CONNECTION_FILE
:
688 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
692 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
693 return STATUS_INVALID_PARAMETER
;
697 TI_DbgPrint(MID_TRACE
, ("No connection object.\n"));
698 return STATUS_INVALID_PARAMETER
;
701 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
702 (FIELD_OFFSET(TDI_CONNECTION_INFORMATION
, RemoteAddress
) +
704 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small (ptr).\n"));
705 return STATUS_BUFFER_OVERFLOW
;
708 return TCPGetPeerAddress( Endpoint
, AddressInfo
->RemoteAddress
);
712 return STATUS_NOT_IMPLEMENTED
;
716 NTSTATUS
DispTdiReceive(
719 * FUNCTION: TDI_RECEIVE handler
721 * Irp = Pointer to an I/O request packet
723 * Status of operation
726 PIO_STACK_LOCATION IrpSp
;
727 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
728 PTRANSPORT_CONTEXT TranContext
;
732 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
734 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
735 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
737 TranContext
= IrpSp
->FileObject
->FsContext
;
738 if (TranContext
== NULL
)
740 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
741 return STATUS_INVALID_CONNECTION
;
744 if (TranContext
->Handle
.ConnectionContext
== NULL
)
746 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
747 return STATUS_INVALID_CONNECTION
;
750 /* Initialize a receive request */
751 Status
= DispPrepareIrpForCancel
752 (TranContext
->Handle
.ConnectionContext
,
754 (PDRIVER_CANCEL
)DispCancelRequest
);
756 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
757 if (NT_SUCCESS(Status
))
759 /* Lock here so we're sure we've got the following 'mark pending' */
760 TcpipRecursiveMutexEnter( &TCPLock
, TRUE
);
762 Status
= TCPReceiveData(
763 TranContext
->Handle
.ConnectionContext
,
764 (PNDIS_BUFFER
)Irp
->MdlAddress
,
765 ReceiveInfo
->ReceiveLength
,
767 ReceiveInfo
->ReceiveFlags
,
768 DispDataRequestComplete
,
770 if (Status
!= STATUS_PENDING
)
772 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
774 IoMarkIrpPending(Irp
);
777 TcpipRecursiveMutexLeave( &TCPLock
);
780 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
786 NTSTATUS
DispTdiReceiveDatagram(
789 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
791 * Irp = Pointer to an I/O request packet
793 * Status of operation
796 PIO_STACK_LOCATION IrpSp
;
797 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
798 PTRANSPORT_CONTEXT TranContext
;
803 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
805 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
806 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
808 TranContext
= IrpSp
->FileObject
->FsContext
;
809 if (TranContext
== NULL
)
811 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
812 return STATUS_INVALID_ADDRESS
;
815 /* Initialize a receive request */
816 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
817 Request
.RequestNotifyObject
= DispDataRequestComplete
;
818 Request
.RequestContext
= Irp
;
820 Status
= DispPrepareIrpForCancel(
821 IrpSp
->FileObject
->FsContext
,
823 (PDRIVER_CANCEL
)DispCancelRequest
);
825 if (NT_SUCCESS(Status
))
830 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
834 Status
= DGReceiveDatagram(
835 Request
.Handle
.AddressHandle
,
836 DgramInfo
->ReceiveDatagramInformation
,
838 DgramInfo
->ReceiveLength
,
839 DgramInfo
->ReceiveFlags
,
840 DgramInfo
->ReturnDatagramInformation
,
842 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
845 if (Status
!= STATUS_PENDING
) {
846 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
848 IoMarkIrpPending(Irp
);
851 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
857 NTSTATUS
DispTdiSend(
860 * FUNCTION: TDI_SEND handler
862 * Irp = Pointer to an I/O request packet
864 * Status of operation
867 PIO_STACK_LOCATION IrpSp
;
868 PTDI_REQUEST_KERNEL_SEND SendInfo
;
869 PTRANSPORT_CONTEXT TranContext
;
873 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
875 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
876 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
878 TranContext
= IrpSp
->FileObject
->FsContext
;
879 if (TranContext
== NULL
)
881 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
882 return STATUS_INVALID_CONNECTION
;
885 if (TranContext
->Handle
.ConnectionContext
== NULL
)
887 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
888 return STATUS_INVALID_CONNECTION
;
891 Status
= DispPrepareIrpForCancel(
892 IrpSp
->FileObject
->FsContext
,
894 (PDRIVER_CANCEL
)DispCancelRequest
);
896 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
897 if (NT_SUCCESS(Status
))
902 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
904 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
905 Status
= TCPSendData(
906 TranContext
->Handle
.ConnectionContext
,
908 SendInfo
->SendLength
,
911 DispDataRequestComplete
,
913 if (Status
!= STATUS_PENDING
)
915 DispDataRequestComplete(Irp
, Status
, BytesSent
);
917 IoMarkIrpPending( Irp
);
920 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
926 NTSTATUS
DispTdiSendDatagram(
929 * FUNCTION: TDI_SEND_DATAGRAM handler
931 * Irp = Pointer to an I/O request packet
933 * Status of operation
936 PIO_STACK_LOCATION IrpSp
;
938 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
939 PTRANSPORT_CONTEXT TranContext
;
942 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
944 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
945 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
946 TranContext
= IrpSp
->FileObject
->FsContext
;
948 /* Initialize a send request */
949 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
950 Request
.RequestNotifyObject
= DispDataRequestComplete
;
951 Request
.RequestContext
= Irp
;
953 Status
= DispPrepareIrpForCancel(
954 IrpSp
->FileObject
->FsContext
,
956 (PDRIVER_CANCEL
)DispCancelRequest
);
958 if (NT_SUCCESS(Status
)) {
962 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
964 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
968 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
969 must be of type PTDI_ADDRESS_IP */
970 TI_DbgPrint(MID_TRACE
,
971 ("About to call send routine %x\n",
972 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
974 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
) )
975 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
976 Request
.Handle
.AddressHandle
,
977 DgramInfo
->SendDatagramInformation
,
980 &Irp
->IoStatus
.Information
);
982 Status
= STATUS_UNSUCCESSFUL
;
984 if (Status
!= STATUS_PENDING
) {
985 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
987 IoMarkIrpPending( Irp
);
990 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
996 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
998 * FUNCTION: TDI_SET_EVENT_HANDER handler
1000 * Irp = Pointer to a I/O request packet
1002 * Status of operation
1005 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1006 PTRANSPORT_CONTEXT TranContext
;
1007 PIO_STACK_LOCATION IrpSp
;
1008 PADDRESS_FILE AddrFile
;
1012 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1014 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1016 /* Get associated address file object. Quit if none exists */
1018 TranContext
= IrpSp
->FileObject
->FsContext
;
1020 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1021 return STATUS_INVALID_PARAMETER
;
1024 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1026 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1027 return STATUS_INVALID_PARAMETER
;
1030 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1031 Status
= STATUS_SUCCESS
;
1033 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
1035 /* Set the event handler. if an event handler is associated with
1036 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1037 If an event handler is not used it's flag is FALSE */
1038 switch (Parameters
->EventType
) {
1039 case TDI_EVENT_CONNECT
:
1040 if (!Parameters
->EventHandler
) {
1041 AddrFile
->ConnectHandlerContext
= NULL
;
1042 AddrFile
->RegisteredConnectHandler
= FALSE
;
1044 AddrFile
->ConnectHandler
=
1045 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1046 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1047 AddrFile
->RegisteredConnectHandler
= TRUE
;
1051 case TDI_EVENT_DISCONNECT
:
1052 if (!Parameters
->EventHandler
) {
1053 AddrFile
->DisconnectHandlerContext
= NULL
;
1054 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1056 AddrFile
->DisconnectHandler
=
1057 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1058 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1059 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1063 case TDI_EVENT_ERROR
:
1064 if (Parameters
->EventHandler
== NULL
) {
1065 AddrFile
->ErrorHandlerContext
= NULL
;
1066 AddrFile
->RegisteredErrorHandler
= FALSE
;
1068 AddrFile
->ErrorHandler
=
1069 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1070 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1071 AddrFile
->RegisteredErrorHandler
= TRUE
;
1075 case TDI_EVENT_RECEIVE
:
1076 if (Parameters
->EventHandler
== NULL
) {
1077 AddrFile
->ReceiveHandlerContext
= NULL
;
1078 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1080 AddrFile
->ReceiveHandler
=
1081 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1082 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1083 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1087 case TDI_EVENT_RECEIVE_DATAGRAM
:
1088 if (Parameters
->EventHandler
== NULL
) {
1089 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1090 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1092 AddrFile
->ReceiveDatagramHandler
=
1093 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1094 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1095 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1099 case TDI_EVENT_RECEIVE_EXPEDITED
:
1100 if (Parameters
->EventHandler
== NULL
) {
1101 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1102 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1104 AddrFile
->ExpeditedReceiveHandler
=
1105 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1106 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1107 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1111 case TDI_EVENT_CHAINED_RECEIVE
:
1112 if (Parameters
->EventHandler
== NULL
) {
1113 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1114 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1116 AddrFile
->ChainedReceiveHandler
=
1117 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1118 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1119 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1123 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1124 if (Parameters
->EventHandler
== NULL
) {
1125 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1126 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1128 AddrFile
->ChainedReceiveDatagramHandler
=
1129 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1130 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1131 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1135 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1136 if (Parameters
->EventHandler
== NULL
) {
1137 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1138 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1140 AddrFile
->ChainedReceiveExpeditedHandler
=
1141 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1142 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1143 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1148 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1149 Parameters
->EventType
));
1151 Status
= STATUS_INVALID_PARAMETER
;
1154 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1160 NTSTATUS
DispTdiSetInformation(
1163 * FUNCTION: TDI_SET_INFORMATION handler
1165 * Irp = Pointer to an I/O request packet
1167 * Status of operation
1170 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1172 return STATUS_NOT_IMPLEMENTED
;
1176 VOID
DispTdiQueryInformationExComplete(
1181 * FUNCTION: Completes a TDI QueryInformationEx request
1183 * Context = Pointer to the IRP for the request
1184 * Status = TDI status of the request
1185 * ByteCount = Number of bytes returned in output buffer
1188 PTI_QUERY_CONTEXT QueryContext
;
1191 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1192 if (NT_SUCCESS(Status
)) {
1193 Count
= CopyBufferToBufferChain(
1194 QueryContext
->InputMdl
,
1195 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1196 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1200 MmUnlockPages(QueryContext
->InputMdl
);
1201 IoFreeMdl(QueryContext
->InputMdl
);
1202 if( QueryContext
->OutputMdl
) {
1203 MmUnlockPages(QueryContext
->OutputMdl
);
1204 IoFreeMdl(QueryContext
->OutputMdl
);
1207 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1208 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1210 ExFreePool(QueryContext
);
1214 NTSTATUS
DispTdiQueryInformationEx(
1216 PIO_STACK_LOCATION IrpSp
)
1218 * FUNCTION: TDI QueryInformationEx handler
1220 * Irp = Pointer to I/O request packet
1221 * IrpSp = Pointer to current stack location of Irp
1223 * Status of operation
1226 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1227 PTRANSPORT_CONTEXT TranContext
;
1228 PTI_QUERY_CONTEXT QueryContext
;
1230 TDI_REQUEST Request
;
1232 UINT InputBufferLength
;
1233 UINT OutputBufferLength
;
1234 BOOLEAN InputMdlLocked
= FALSE
;
1235 BOOLEAN OutputMdlLocked
= FALSE
;
1236 PMDL InputMdl
= NULL
;
1237 PMDL OutputMdl
= NULL
;
1238 NTSTATUS Status
= STATUS_SUCCESS
;
1240 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1242 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1244 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1245 case TDI_TRANSPORT_ADDRESS_FILE
:
1246 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1249 case TDI_CONNECTION_FILE
:
1250 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1253 case TDI_CONTROL_CHANNEL_FILE
:
1254 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1258 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1259 return STATUS_INVALID_PARAMETER
;
1262 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1263 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1265 /* Validate parameters */
1266 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1267 (OutputBufferLength
!= 0)) {
1269 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1270 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1271 OutputBuffer
= Irp
->UserBuffer
;
1273 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1276 InputMdl
= IoAllocateMdl(InputBuffer
,
1277 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1280 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1281 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1283 if (InputMdl
&& OutputMdl
) {
1285 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1288 InputMdlLocked
= TRUE
;
1290 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1293 OutputMdlLocked
= TRUE
;
1295 RtlCopyMemory(&QueryContext
->QueryInfo
,
1296 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1298 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1300 Status
= _SEH_GetExceptionCode();
1303 if (NT_SUCCESS(Status
)) {
1304 Size
= MmGetMdlByteCount(OutputMdl
);
1306 QueryContext
->Irp
= Irp
;
1307 QueryContext
->InputMdl
= InputMdl
;
1308 QueryContext
->OutputMdl
= OutputMdl
;
1310 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1311 Request
.RequestContext
= QueryContext
;
1312 Status
= InfoTdiQueryInformationEx(&Request
,
1313 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1314 &Size
, &QueryContext
->QueryInfo
.Context
);
1315 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1317 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1322 /* An error occurred if we get here */
1326 MmUnlockPages(InputMdl
);
1327 IoFreeMdl(InputMdl
);
1331 if (OutputMdlLocked
)
1332 MmUnlockPages(OutputMdl
);
1333 IoFreeMdl(OutputMdl
);
1336 ExFreePool(QueryContext
);
1338 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1339 } else if( InputBufferLength
==
1340 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1341 /* Handle the case where the user is probing the buffer for length */
1342 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1343 InputBufferLength
, OutputBufferLength
));
1344 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1345 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1349 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1350 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1353 InputMdl
= IoAllocateMdl(InputBuffer
,
1354 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1357 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1360 InputMdlLocked
= TRUE
;
1361 Status
= STATUS_SUCCESS
;
1363 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1364 Status
= _SEH_GetExceptionCode();
1367 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1368 if( InputMdl
) IoFreeMdl( InputMdl
);
1369 ExFreePool(QueryContext
);
1373 RtlCopyMemory(&QueryContext
->QueryInfo
,
1374 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1376 QueryContext
->Irp
= Irp
;
1377 QueryContext
->InputMdl
= InputMdl
;
1378 QueryContext
->OutputMdl
= NULL
;
1380 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1381 Request
.RequestContext
= QueryContext
;
1382 Status
= InfoTdiQueryInformationEx(&Request
,
1383 &QueryContext
->QueryInfo
.ID
,
1386 &QueryContext
->QueryInfo
.Context
);
1387 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1388 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1389 } else Status
= STATUS_INVALID_PARAMETER
;
1391 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1397 NTSTATUS
DispTdiSetInformationEx(
1399 PIO_STACK_LOCATION IrpSp
)
1401 * FUNCTION: TDI SetInformationEx handler
1403 * Irp = Pointer to I/O request packet
1404 * IrpSp = Pointer to current stack location of Irp
1406 * Status of operation
1409 PTRANSPORT_CONTEXT TranContext
;
1410 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1411 TDI_REQUEST Request
;
1414 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1416 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1417 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1419 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1420 case TDI_TRANSPORT_ADDRESS_FILE
:
1421 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1424 case TDI_CONNECTION_FILE
:
1425 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1428 case TDI_CONTROL_CHANNEL_FILE
:
1429 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1433 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1434 Irp
->IoStatus
.Information
= 0;
1436 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1438 return IRPFinish(Irp
, STATUS_INVALID_PARAMETER
);
1441 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1442 if (NT_SUCCESS(Status
)) {
1443 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1444 Request
.RequestContext
= Irp
;
1446 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1447 &Info
->Buffer
, Info
->BufferSize
);
1453 /* TODO: Support multiple addresses per interface.
1454 * For now just set the nte context to the interface index.
1456 * Later on, create an NTE context and NTE instance
1459 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1460 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1461 PIP_SET_ADDRESS IpAddrChange
=
1462 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1465 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1466 IpAddrChange
->NteIndex
));
1468 ForEachInterface(IF
) {
1469 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1471 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1472 Status
= STATUS_DUPLICATE_OBJECTID
;
1475 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1476 IPRemoveInterfaceRoute( IF
);
1478 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1479 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1480 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1481 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1482 IF
->Broadcast
.Address
.IPv4Address
=
1483 IF
->Unicast
.Address
.IPv4Address
|
1484 ~IF
->Netmask
.Address
.IPv4Address
;
1486 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1487 IF
->Unicast
.Address
.IPv4Address
));
1488 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1489 IF
->Netmask
.Address
.IPv4Address
));
1491 IPAddInterfaceRoute( IF
);
1493 IpAddrChange
->Address
= IF
->Index
;
1494 Status
= STATUS_SUCCESS
;
1495 Irp
->IoStatus
.Information
= IF
->Index
;
1500 Irp
->IoStatus
.Status
= Status
;
1504 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1505 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1506 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1509 ForEachInterface(IF
) {
1510 if( IF
->Index
== *NteIndex
) {
1511 IPRemoveInterfaceRoute( IF
);
1512 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1513 IF
->Unicast
.Address
.IPv4Address
= 0;
1514 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1515 IF
->Netmask
.Address
.IPv4Address
= 0;
1516 Status
= STATUS_SUCCESS
;
1520 Irp
->IoStatus
.Status
= Status
;