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 NTAPI
DispCancelRequest(
106 PDEVICE_OBJECT Device
,
109 * FUNCTION: Cancels an IRP
111 * Device = Pointer to device object
112 * Irp = Pointer to an I/O request packet
115 PIO_STACK_LOCATION IrpSp
;
116 PTRANSPORT_CONTEXT TranContext
;
117 PFILE_OBJECT FileObject
;
120 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
122 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
123 FileObject
= IrpSp
->FileObject
;
124 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
125 MinorFunction
= IrpSp
->MinorFunction
;
127 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
129 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
130 Irp
->IoStatus
.Information
= 0;
134 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
137 /* Try canceling the request */
138 switch(MinorFunction
) {
141 TCPRemoveIRP( TranContext
->Handle
.ConnectionContext
, Irp
);
144 case TDI_SEND_DATAGRAM
:
145 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
146 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
150 DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
153 case TDI_RECEIVE_DATAGRAM
:
154 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
155 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
159 DGRemoveIRP(TranContext
->Handle
.AddressHandle
, Irp
);
163 TCPRemoveIRP(TranContext
->Handle
.ConnectionContext
, Irp
);
167 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
171 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
172 IRPFinish(Irp
, STATUS_CANCELLED
);
174 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
178 VOID NTAPI
DispCancelListenRequest(
179 PDEVICE_OBJECT Device
,
182 * FUNCTION: Cancels a listen IRP
184 * Device = Pointer to device object
185 * Irp = Pointer to an I/O request packet
188 PIO_STACK_LOCATION IrpSp
;
189 PTRANSPORT_CONTEXT TranContext
;
190 PFILE_OBJECT FileObject
;
191 PCONNECTION_ENDPOINT Connection
;
192 /*NTSTATUS Status = STATUS_SUCCESS;*/
194 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
196 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
197 FileObject
= IrpSp
->FileObject
;
198 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
199 ASSERT( TDI_LISTEN
== IrpSp
->MinorFunction
);
201 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X).\n", Irp
));
205 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
208 /* Try canceling the request */
209 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
211 TCPRemoveIRP(Connection
, Irp
);
213 TCPAbortListenForSocket(
214 Connection
->AddressFile
->Listener
,
217 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
219 Irp
->IoStatus
.Information
= 0;
220 IRPFinish(Irp
, STATUS_CANCELLED
);
222 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
226 NTSTATUS
DispTdiAccept(
229 * FUNCTION: TDI_ACCEPT handler
231 * Irp = Pointer to an I/O request packet
233 * Status of operation
236 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
238 return STATUS_NOT_IMPLEMENTED
;
242 NTSTATUS
DispTdiAssociateAddress(
245 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
247 * Irp = Pointer to an I/O request packet
249 * Status of operation
252 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
253 PTRANSPORT_CONTEXT TranContext
;
254 PIO_STACK_LOCATION IrpSp
;
255 PCONNECTION_ENDPOINT Connection
;
256 PFILE_OBJECT FileObject
;
257 PADDRESS_FILE AddrFile
= NULL
;
260 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
262 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
264 /* Get associated connection endpoint file object. Quit if none exists */
266 TranContext
= IrpSp
->FileObject
->FsContext
;
268 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
269 return STATUS_INVALID_PARAMETER
;
272 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
274 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
275 return STATUS_INVALID_PARAMETER
;
278 if (Connection
->AddressFile
) {
279 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
280 return STATUS_INVALID_PARAMETER
;
283 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
285 Status
= ObReferenceObjectByHandle(
286 Parameters
->AddressHandle
,
292 if (!NT_SUCCESS(Status
)) {
293 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
294 Parameters
->AddressHandle
, Status
));
295 return STATUS_INVALID_PARAMETER
;
298 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
299 ObDereferenceObject(FileObject
);
300 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
301 FileObject
->FsContext2
));
302 return STATUS_INVALID_PARAMETER
;
305 /* Get associated address file object. Quit if none exists */
307 TranContext
= FileObject
->FsContext
;
309 ObDereferenceObject(FileObject
);
310 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
311 return STATUS_INVALID_PARAMETER
;
314 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
316 ObDereferenceObject(FileObject
);
317 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
318 return STATUS_INVALID_PARAMETER
;
321 Connection
->AddressFile
= AddrFile
;
323 /* Add connection endpoint to the address file */
324 AddrFile
->Connection
= Connection
;
326 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
327 ObDereferenceObject(FileObject
);
333 NTSTATUS
DispTdiConnect(
336 * FUNCTION: TDI_CONNECT handler
338 * Irp = Pointer to an I/O request packet
340 * Status of operation
343 PCONNECTION_ENDPOINT Connection
;
344 PTDI_REQUEST_KERNEL Parameters
;
345 PTRANSPORT_CONTEXT TranContext
;
346 PIO_STACK_LOCATION IrpSp
;
349 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
351 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
353 /* Get associated connection endpoint file object. Quit if none exists */
355 TranContext
= IrpSp
->FileObject
->FsContext
;
357 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
358 Status
= STATUS_INVALID_PARAMETER
;
362 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
364 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
365 Status
= STATUS_INVALID_PARAMETER
;
369 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
371 Status
= DispPrepareIrpForCancel(TranContext
->Handle
.ConnectionContext
,
375 if (NT_SUCCESS(Status
)) {
377 TranContext
->Handle
.ConnectionContext
,
378 Parameters
->RequestConnectionInformation
,
379 Parameters
->ReturnConnectionInformation
,
380 DispDataRequestComplete
,
385 if (Status
!= STATUS_PENDING
) {
386 DispDataRequestComplete(Irp
, Status
, 0);
388 IoMarkIrpPending(Irp
);
390 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
396 NTSTATUS
DispTdiDisassociateAddress(
399 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
401 * Irp = Pointer to an I/O request packet
403 * Status of operation
406 PCONNECTION_ENDPOINT Connection
;
407 PTRANSPORT_CONTEXT TranContext
;
408 PIO_STACK_LOCATION IrpSp
;
410 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
412 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
414 /* Get associated connection endpoint file object. Quit if none exists */
416 TranContext
= IrpSp
->FileObject
->FsContext
;
418 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
419 return STATUS_INVALID_PARAMETER
;
422 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
424 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
425 return STATUS_INVALID_PARAMETER
;
428 if (!Connection
->AddressFile
) {
429 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
430 return STATUS_INVALID_PARAMETER
;
433 /* Remove this connection from the address file */
434 Connection
->AddressFile
->Connection
= NULL
;
436 /* Remove the address file from this connection */
437 Connection
->AddressFile
= NULL
;
439 return STATUS_SUCCESS
;
443 NTSTATUS
DispTdiDisconnect(
446 * FUNCTION: TDI_DISCONNECT handler
448 * Irp = Pointer to an I/O request packet
450 * Status of operation
454 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
455 PCONNECTION_ENDPOINT Connection
;
456 PTRANSPORT_CONTEXT TranContext
;
457 PIO_STACK_LOCATION IrpSp
;
459 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
461 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
462 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
464 /* Get associated connection endpoint file object. Quit if none exists */
466 TranContext
= IrpSp
->FileObject
->FsContext
;
468 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
469 Status
= STATUS_INVALID_PARAMETER
;
473 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
475 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
476 Status
= STATUS_INVALID_PARAMETER
;
480 Status
= TCPDisconnect(
481 TranContext
->Handle
.ConnectionContext
,
482 DisReq
->RequestFlags
,
483 DisReq
->RequestConnectionInformation
,
484 DisReq
->ReturnConnectionInformation
,
485 DispDataRequestComplete
,
489 if (Status
!= STATUS_PENDING
) {
490 DispDataRequestComplete(Irp
, Status
, 0);
492 IoMarkIrpPending(Irp
);
494 TI_DbgPrint(MAX_TRACE
, ("TCP Disconnect 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 Status
= STATUS_INVALID_PARAMETER
;
530 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
531 if (Connection
== NULL
)
533 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
534 Status
= STATUS_INVALID_PARAMETER
;
538 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
540 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile: %x\n",
541 Connection
->AddressFile
));
542 ASSERT(Connection
->AddressFile
);
544 Status
= DispPrepareIrpForCancel
545 (TranContext
->Handle
.ConnectionContext
,
547 (PDRIVER_CANCEL
)DispCancelListenRequest
);
549 /* Listening will require us to create a listening socket and store it in
550 * the address file. It will be signalled, and attempt to complete an irp
551 * when a new connection arrives. */
552 /* The important thing to note here is that the irp we'll complete belongs
553 * to the socket to be accepted onto, not the listener */
554 if( NT_SUCCESS(Status
) && !Connection
->AddressFile
->Listener
) {
555 Connection
->AddressFile
->Listener
=
556 TCPAllocateConnectionEndpoint( NULL
);
558 if( !Connection
->AddressFile
->Listener
)
559 Status
= STATUS_NO_MEMORY
;
561 if( NT_SUCCESS(Status
) ) {
562 Connection
->AddressFile
->Listener
->AddressFile
=
563 Connection
->AddressFile
;
565 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
566 Connection
->AddressFile
->Family
,
568 Connection
->AddressFile
->Protocol
);
571 if( NT_SUCCESS(Status
) )
572 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
576 if( NT_SUCCESS(Status
) ) {
578 ( (PTDI_REQUEST
)Parameters
,
579 Connection
->AddressFile
->Listener
,
581 DispDataRequestComplete
,
586 if (Status
!= STATUS_PENDING
) {
587 DispDataRequestComplete(Irp
, Status
, 0);
589 IoMarkIrpPending(Irp
);
591 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
597 NTSTATUS
DispTdiQueryInformation(
598 PDEVICE_OBJECT DeviceObject
,
601 * FUNCTION: TDI_QUERY_INFORMATION handler
603 * DeviceObject = Pointer to device object structure
604 * Irp = Pointer to an I/O request packet
606 * Status of operation
609 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
610 PTRANSPORT_CONTEXT TranContext
;
611 PIO_STACK_LOCATION IrpSp
;
613 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
615 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
616 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
618 TranContext
= IrpSp
->FileObject
->FsContext
;
620 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
621 return STATUS_INVALID_PARAMETER
;
624 switch (Parameters
->QueryType
)
626 case TDI_QUERY_ADDRESS_INFO
:
628 PTDI_ADDRESS_INFO AddressInfo
;
629 PADDRESS_FILE AddrFile
;
630 PTA_IP_ADDRESS Address
;
631 PCONNECTION_ENDPOINT Endpoint
= NULL
;
634 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
635 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
636 sizeof(TDI_ADDRESS_IP
))) {
637 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
638 return STATUS_BUFFER_TOO_SMALL
;
641 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
642 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
644 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
645 case TDI_TRANSPORT_ADDRESS_FILE
:
646 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
648 Address
->TAAddressCount
= 1;
649 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
650 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
651 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
652 Address
->Address
[0].Address
[0].in_addr
= AddrFile
->Address
.Address
.IPv4Address
;
654 &Address
->Address
[0].Address
[0].sin_zero
,
655 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
656 return STATUS_SUCCESS
;
658 case TDI_CONNECTION_FILE
:
660 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
661 TCPGetSockAddress( Endpoint
, (PTRANSPORT_ADDRESS
)Address
, FALSE
);
662 DbgPrint("Returning socket address %x\n", Address
->Address
[0].Address
[0].in_addr
);
664 &Address
->Address
[0].Address
[0].sin_zero
,
665 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
666 return STATUS_SUCCESS
;
669 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
670 return STATUS_INVALID_PARAMETER
;
674 case TDI_QUERY_CONNECTION_INFO
:
676 PTDI_CONNECTION_INFORMATION AddressInfo
;
677 PADDRESS_FILE AddrFile
;
678 PCONNECTION_ENDPOINT Endpoint
= NULL
;
680 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
681 (FIELD_OFFSET(TDI_CONNECTION_INFORMATION
, RemoteAddress
) +
683 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small (ptr).\n"));
684 return STATUS_BUFFER_TOO_SMALL
;
687 AddressInfo
= (PTDI_CONNECTION_INFORMATION
)
688 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
690 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
691 case TDI_TRANSPORT_ADDRESS_FILE
:
692 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
693 Endpoint
= AddrFile
? AddrFile
->Connection
: NULL
;
696 case TDI_CONNECTION_FILE
:
698 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
702 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
703 return STATUS_INVALID_PARAMETER
;
707 TI_DbgPrint(MID_TRACE
, ("No connection object.\n"));
708 return STATUS_INVALID_PARAMETER
;
711 return TCPGetSockAddress( Endpoint
, AddressInfo
->RemoteAddress
, TRUE
);
715 return STATUS_NOT_IMPLEMENTED
;
719 NTSTATUS
DispTdiReceive(
722 * FUNCTION: TDI_RECEIVE handler
724 * Irp = Pointer to an I/O request packet
726 * Status of operation
729 PIO_STACK_LOCATION IrpSp
;
730 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
731 PTRANSPORT_CONTEXT TranContext
;
733 ULONG BytesReceived
= 0;
735 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
737 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
738 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
740 TranContext
= IrpSp
->FileObject
->FsContext
;
741 if (TranContext
== NULL
)
743 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
744 Status
= STATUS_INVALID_PARAMETER
;
748 if (TranContext
->Handle
.ConnectionContext
== NULL
)
750 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
751 Status
= STATUS_INVALID_PARAMETER
;
755 /* Initialize a receive request */
756 Status
= DispPrepareIrpForCancel
757 (TranContext
->Handle
.ConnectionContext
,
759 (PDRIVER_CANCEL
)DispCancelRequest
);
761 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
762 if (NT_SUCCESS(Status
))
764 Status
= TCPReceiveData(
765 TranContext
->Handle
.ConnectionContext
,
766 (PNDIS_BUFFER
)Irp
->MdlAddress
,
767 ReceiveInfo
->ReceiveLength
,
769 ReceiveInfo
->ReceiveFlags
,
770 DispDataRequestComplete
,
775 if (Status
!= STATUS_PENDING
) {
776 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
778 IoMarkIrpPending(Irp
);
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
;
801 ULONG BytesReceived
= 0;
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 Status
= STATUS_INVALID_PARAMETER
;
816 /* Initialize a receive request */
817 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
818 Request
.RequestNotifyObject
= DispDataRequestComplete
;
819 Request
.RequestContext
= Irp
;
821 Status
= DispPrepareIrpForCancel(
822 IrpSp
->FileObject
->FsContext
,
824 (PDRIVER_CANCEL
)DispCancelRequest
);
826 if (NT_SUCCESS(Status
))
831 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
835 Status
= DGReceiveDatagram(
836 Request
.Handle
.AddressHandle
,
837 DgramInfo
->ReceiveDatagramInformation
,
839 DgramInfo
->ReceiveLength
,
840 DgramInfo
->ReceiveFlags
,
841 DgramInfo
->ReturnDatagramInformation
,
843 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
849 if (Status
!= STATUS_PENDING
) {
850 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
852 IoMarkIrpPending(Irp
);
854 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
860 NTSTATUS
DispTdiSend(
863 * FUNCTION: TDI_SEND handler
865 * Irp = Pointer to an I/O request packet
867 * Status of operation
870 PIO_STACK_LOCATION IrpSp
;
871 PTDI_REQUEST_KERNEL_SEND SendInfo
;
872 PTRANSPORT_CONTEXT TranContext
;
876 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
878 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
879 SendInfo
= (PTDI_REQUEST_KERNEL_SEND
)&(IrpSp
->Parameters
);
881 TranContext
= IrpSp
->FileObject
->FsContext
;
882 if (TranContext
== NULL
)
884 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
885 Status
= STATUS_INVALID_PARAMETER
;
889 if (TranContext
->Handle
.ConnectionContext
== NULL
)
891 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
892 Status
= STATUS_INVALID_PARAMETER
;
896 Status
= DispPrepareIrpForCancel(
897 IrpSp
->FileObject
->FsContext
,
899 (PDRIVER_CANCEL
)DispCancelRequest
);
901 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
902 if (NT_SUCCESS(Status
))
907 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
909 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
910 Status
= TCPSendData(
911 TranContext
->Handle
.ConnectionContext
,
913 SendInfo
->SendLength
,
916 DispDataRequestComplete
,
921 if (Status
!= STATUS_PENDING
) {
922 DispDataRequestComplete(Irp
, Status
, BytesSent
);
924 IoMarkIrpPending(Irp
);
926 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
932 NTSTATUS
DispTdiSendDatagram(
935 * FUNCTION: TDI_SEND_DATAGRAM handler
937 * Irp = Pointer to an I/O request packet
939 * Status of operation
942 PIO_STACK_LOCATION IrpSp
;
944 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
945 PTRANSPORT_CONTEXT TranContext
;
948 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
950 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
951 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
953 TranContext
= IrpSp
->FileObject
->FsContext
;
954 if (TranContext
== NULL
)
956 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
957 Status
= STATUS_INVALID_PARAMETER
;
961 /* Initialize a send request */
962 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
963 Request
.RequestNotifyObject
= DispDataRequestComplete
;
964 Request
.RequestContext
= Irp
;
966 Status
= DispPrepareIrpForCancel(
967 IrpSp
->FileObject
->FsContext
,
969 (PDRIVER_CANCEL
)DispCancelRequest
);
971 if (NT_SUCCESS(Status
)) {
975 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
977 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
981 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
982 must be of type PTDI_ADDRESS_IP */
983 TI_DbgPrint(MID_TRACE
,
984 ("About to call send routine %x\n",
985 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
987 if( (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
!= NULL
) )
990 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
991 Request
.Handle
.AddressHandle
,
992 DgramInfo
->SendDatagramInformation
,
996 Irp
->IoStatus
.Information
= DataUsed
;
999 Status
= STATUS_UNSUCCESSFUL
;
1003 if (Status
!= STATUS_PENDING
) {
1004 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
1006 IoMarkIrpPending(Irp
);
1008 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
1014 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
1016 * FUNCTION: TDI_SET_EVENT_HANDER handler
1018 * Irp = Pointer to a I/O request packet
1020 * Status of operation
1023 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
1024 PTRANSPORT_CONTEXT TranContext
;
1025 PIO_STACK_LOCATION IrpSp
;
1026 PADDRESS_FILE AddrFile
;
1030 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1032 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1034 /* Get associated address file object. Quit if none exists */
1036 TranContext
= IrpSp
->FileObject
->FsContext
;
1038 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
1039 return STATUS_INVALID_PARAMETER
;
1042 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
1044 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
1045 return STATUS_INVALID_PARAMETER
;
1048 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
1049 Status
= STATUS_SUCCESS
;
1051 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
1053 /* Set the event handler. if an event handler is associated with
1054 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1055 If an event handler is not used it's flag is FALSE */
1056 switch (Parameters
->EventType
) {
1057 case TDI_EVENT_CONNECT
:
1058 if (!Parameters
->EventHandler
) {
1059 AddrFile
->ConnectHandlerContext
= NULL
;
1060 AddrFile
->RegisteredConnectHandler
= FALSE
;
1062 AddrFile
->ConnectHandler
=
1063 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
1064 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
1065 AddrFile
->RegisteredConnectHandler
= TRUE
;
1069 case TDI_EVENT_DISCONNECT
:
1070 if (!Parameters
->EventHandler
) {
1071 AddrFile
->DisconnectHandlerContext
= NULL
;
1072 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
1074 AddrFile
->DisconnectHandler
=
1075 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
1076 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
1077 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1081 case TDI_EVENT_ERROR
:
1082 if (Parameters
->EventHandler
== NULL
) {
1083 AddrFile
->ErrorHandlerContext
= NULL
;
1084 AddrFile
->RegisteredErrorHandler
= FALSE
;
1086 AddrFile
->ErrorHandler
=
1087 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1088 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1089 AddrFile
->RegisteredErrorHandler
= TRUE
;
1093 case TDI_EVENT_RECEIVE
:
1094 if (Parameters
->EventHandler
== NULL
) {
1095 AddrFile
->ReceiveHandlerContext
= NULL
;
1096 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1098 AddrFile
->ReceiveHandler
=
1099 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1100 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1101 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1105 case TDI_EVENT_RECEIVE_DATAGRAM
:
1106 if (Parameters
->EventHandler
== NULL
) {
1107 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1108 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1110 AddrFile
->ReceiveDatagramHandler
=
1111 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1112 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1113 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1117 case TDI_EVENT_RECEIVE_EXPEDITED
:
1118 if (Parameters
->EventHandler
== NULL
) {
1119 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1120 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1122 AddrFile
->ExpeditedReceiveHandler
=
1123 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1124 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1125 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1129 case TDI_EVENT_CHAINED_RECEIVE
:
1130 if (Parameters
->EventHandler
== NULL
) {
1131 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1132 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1134 AddrFile
->ChainedReceiveHandler
=
1135 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1136 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1137 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1141 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1142 if (Parameters
->EventHandler
== NULL
) {
1143 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1144 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1146 AddrFile
->ChainedReceiveDatagramHandler
=
1147 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1148 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1149 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1153 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1154 if (Parameters
->EventHandler
== NULL
) {
1155 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1156 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1158 AddrFile
->ChainedReceiveExpeditedHandler
=
1159 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1160 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1161 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1166 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1167 Parameters
->EventType
));
1169 Status
= STATUS_INVALID_PARAMETER
;
1172 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1178 NTSTATUS
DispTdiSetInformation(
1181 * FUNCTION: TDI_SET_INFORMATION handler
1183 * Irp = Pointer to an I/O request packet
1185 * Status of operation
1188 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1190 return STATUS_NOT_IMPLEMENTED
;
1194 VOID
DispTdiQueryInformationExComplete(
1199 * FUNCTION: Completes a TDI QueryInformationEx request
1201 * Context = Pointer to the IRP for the request
1202 * Status = TDI status of the request
1203 * ByteCount = Number of bytes returned in output buffer
1206 PTI_QUERY_CONTEXT QueryContext
;
1209 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1210 if (NT_SUCCESS(Status
)) {
1211 Count
= CopyBufferToBufferChain(
1212 QueryContext
->InputMdl
,
1213 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1214 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1218 MmUnlockPages(QueryContext
->InputMdl
);
1219 IoFreeMdl(QueryContext
->InputMdl
);
1220 if( QueryContext
->OutputMdl
) {
1221 MmUnlockPages(QueryContext
->OutputMdl
);
1222 IoFreeMdl(QueryContext
->OutputMdl
);
1225 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1226 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1228 exFreePool(QueryContext
);
1232 NTSTATUS
DispTdiQueryInformationEx(
1234 PIO_STACK_LOCATION IrpSp
)
1236 * FUNCTION: TDI QueryInformationEx handler
1238 * Irp = Pointer to I/O request packet
1239 * IrpSp = Pointer to current stack location of Irp
1241 * Status of operation
1244 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1245 PTRANSPORT_CONTEXT TranContext
;
1246 PTI_QUERY_CONTEXT QueryContext
;
1248 TDI_REQUEST Request
;
1250 UINT InputBufferLength
;
1251 UINT OutputBufferLength
;
1252 BOOLEAN InputMdlLocked
= FALSE
;
1253 BOOLEAN OutputMdlLocked
= FALSE
;
1254 PMDL InputMdl
= NULL
;
1255 PMDL OutputMdl
= NULL
;
1256 NTSTATUS Status
= STATUS_SUCCESS
;
1258 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1260 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1262 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
1263 case TDI_TRANSPORT_ADDRESS_FILE
:
1264 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1267 case TDI_CONNECTION_FILE
:
1268 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1271 case TDI_CONTROL_CHANNEL_FILE
:
1272 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1276 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1277 return STATUS_INVALID_PARAMETER
;
1280 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1281 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1283 /* Validate parameters */
1284 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1285 (OutputBufferLength
!= 0)) {
1287 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1288 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1289 OutputBuffer
= Irp
->UserBuffer
;
1291 QueryContext
= exAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1294 InputMdl
= IoAllocateMdl(InputBuffer
,
1295 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1298 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1299 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1301 if (InputMdl
&& OutputMdl
) {
1303 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1306 InputMdlLocked
= TRUE
;
1308 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1311 OutputMdlLocked
= TRUE
;
1313 RtlCopyMemory(&QueryContext
->QueryInfo
,
1314 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1316 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1317 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1318 Status
= _SEH2_GetExceptionCode();
1321 if (NT_SUCCESS(Status
)) {
1322 Size
= MmGetMdlByteCount(OutputMdl
);
1324 QueryContext
->Irp
= Irp
;
1325 QueryContext
->InputMdl
= InputMdl
;
1326 QueryContext
->OutputMdl
= OutputMdl
;
1328 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1329 Request
.RequestContext
= QueryContext
;
1330 Status
= InfoTdiQueryInformationEx(&Request
,
1331 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1332 &Size
, &QueryContext
->QueryInfo
.Context
);
1333 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1335 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1340 /* An error occurred if we get here */
1344 MmUnlockPages(InputMdl
);
1345 IoFreeMdl(InputMdl
);
1349 if (OutputMdlLocked
)
1350 MmUnlockPages(OutputMdl
);
1351 IoFreeMdl(OutputMdl
);
1354 exFreePool(QueryContext
);
1356 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1357 } else if( InputBufferLength
==
1358 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1359 /* Handle the case where the user is probing the buffer for length */
1360 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1361 InputBufferLength
, OutputBufferLength
));
1362 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1363 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1367 QueryContext
= exAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1368 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1371 InputMdl
= IoAllocateMdl(InputBuffer
,
1372 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1375 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1378 InputMdlLocked
= TRUE
;
1379 Status
= STATUS_SUCCESS
;
1380 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
1381 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1382 Status
= _SEH2_GetExceptionCode();
1385 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1386 if( InputMdl
) IoFreeMdl( InputMdl
);
1387 exFreePool(QueryContext
);
1391 RtlCopyMemory(&QueryContext
->QueryInfo
,
1392 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1394 QueryContext
->Irp
= Irp
;
1395 QueryContext
->InputMdl
= InputMdl
;
1396 QueryContext
->OutputMdl
= NULL
;
1398 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1399 Request
.RequestContext
= QueryContext
;
1400 Status
= InfoTdiQueryInformationEx(&Request
,
1401 &QueryContext
->QueryInfo
.ID
,
1404 &QueryContext
->QueryInfo
.Context
);
1405 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1406 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1407 } else Status
= STATUS_INVALID_PARAMETER
;
1409 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1415 NTSTATUS
DispTdiSetInformationEx(
1417 PIO_STACK_LOCATION IrpSp
)
1419 * FUNCTION: TDI SetInformationEx handler
1421 * Irp = Pointer to I/O request packet
1422 * IrpSp = Pointer to current stack location of Irp
1424 * Status of operation
1427 PTRANSPORT_CONTEXT TranContext
;
1428 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1429 TDI_REQUEST Request
;
1432 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1434 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1435 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1437 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
1438 case TDI_TRANSPORT_ADDRESS_FILE
:
1439 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1442 case TDI_CONNECTION_FILE
:
1443 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1446 case TDI_CONTROL_CHANNEL_FILE
:
1447 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1451 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1452 Irp
->IoStatus
.Information
= 0;
1454 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1456 return Irp
->IoStatus
.Status
;
1459 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1460 if (NT_SUCCESS(Status
)) {
1461 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1462 Request
.RequestContext
= Irp
;
1464 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1465 &Info
->Buffer
, Info
->BufferSize
);
1471 /* TODO: Support multiple addresses per interface.
1472 * For now just set the nte context to the interface index.
1474 * Later on, create an NTE context and NTE instance
1477 NTSTATUS
DispTdiSetIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1478 NTSTATUS Status
= STATUS_DEVICE_DOES_NOT_EXIST
;
1479 PIP_SET_ADDRESS IpAddrChange
=
1480 (PIP_SET_ADDRESS
)Irp
->AssociatedIrp
.SystemBuffer
;
1483 TI_DbgPrint(MID_TRACE
,("Setting IP Address for adapter %d\n",
1484 IpAddrChange
->NteIndex
));
1486 ForEachInterface(IF
) {
1487 TI_DbgPrint(MID_TRACE
,("Looking at adapter %d\n", IF
->Index
));
1489 if( IF
->Unicast
.Address
.IPv4Address
== IpAddrChange
->Address
) {
1490 Status
= STATUS_DUPLICATE_OBJECTID
;
1493 if( IF
->Index
== IpAddrChange
->NteIndex
) {
1494 IPRemoveInterfaceRoute( IF
);
1496 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1497 IF
->Unicast
.Address
.IPv4Address
= IpAddrChange
->Address
;
1498 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1499 IF
->Netmask
.Address
.IPv4Address
= IpAddrChange
->Netmask
;
1500 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1501 IF
->Broadcast
.Address
.IPv4Address
=
1502 IF
->Unicast
.Address
.IPv4Address
|
1503 ~IF
->Netmask
.Address
.IPv4Address
;
1505 TI_DbgPrint(MID_TRACE
,("New Unicast Address: %x\n",
1506 IF
->Unicast
.Address
.IPv4Address
));
1507 TI_DbgPrint(MID_TRACE
,("New Netmask : %x\n",
1508 IF
->Netmask
.Address
.IPv4Address
));
1510 IPAddInterfaceRoute( IF
);
1512 IpAddrChange
->Address
= IF
->Index
;
1513 Status
= STATUS_SUCCESS
;
1514 Irp
->IoStatus
.Information
= IF
->Index
;
1519 Irp
->IoStatus
.Status
= Status
;
1523 NTSTATUS
DispTdiDeleteIPAddress( PIRP Irp
, PIO_STACK_LOCATION IrpSp
) {
1524 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1525 PUSHORT NteIndex
= Irp
->AssociatedIrp
.SystemBuffer
;
1528 ForEachInterface(IF
) {
1529 if( IF
->Index
== *NteIndex
) {
1530 IPRemoveInterfaceRoute( IF
);
1531 IF
->Unicast
.Type
= IP_ADDRESS_V4
;
1532 IF
->Unicast
.Address
.IPv4Address
= 0;
1533 IF
->Netmask
.Type
= IP_ADDRESS_V4
;
1534 IF
->Netmask
.Address
.IPv4Address
= 0;
1535 IF
->Broadcast
.Type
= IP_ADDRESS_V4
;
1536 IF
->Broadcast
.Address
.IPv4Address
= 0;
1537 Status
= STATUS_SUCCESS
;
1541 Irp
->IoStatus
.Status
= Status
;