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
17 NTSTATUS
DispPrepareIrpForCancel(
18 PTRANSPORT_CONTEXT Context
,
20 PDRIVER_CANCEL CancelRoutine
)
22 * FUNCTION: Prepare an IRP for cancellation
24 * Context = Pointer to context information
25 * Irp = Pointer to an I/O request packet
26 * CancelRoutine = Routine to be called when I/O request is cancelled
33 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
35 IoAcquireCancelSpinLock(&OldIrql
);
38 IoMarkIrpPending(Irp
);
39 IoSetCancelRoutine(Irp
, CancelRoutine
);
41 IoReleaseCancelSpinLock(OldIrql
);
43 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
45 return STATUS_SUCCESS
;
48 /* IRP has already been cancelled */
50 IoReleaseCancelSpinLock(OldIrql
);
52 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
53 Irp
->IoStatus
.Information
= 0;
55 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
57 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
59 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
61 return STATUS_CANCELLED
;
65 VOID
DispCancelComplete(
68 * FUNCTION: Completes a cancel request
70 * Context = Pointer to context information (FILE_OBJECT)
74 PFILE_OBJECT FileObject
;
75 PTRANSPORT_CONTEXT TranContext
;
77 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
79 FileObject
= (PFILE_OBJECT
)Context
;
80 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
82 IoAcquireCancelSpinLock(&OldIrql
);
84 /* Remove the reference placed on the endpoint by the cancel routine.
85 The cancelled IRP will be completed by the completion routine for
87 TranContext
->RefCount
--;
89 if (TranContext
->RefCount
== 0) {
90 TI_DbgPrint(DEBUG_IRP
, ("Setting TranContext->CleanupEvent to signaled.\n"));
91 /* Set the cleanup event */
92 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
95 TI_DbgPrint(DEBUG_REFCOUNT
, ("TranContext->RefCount (%d).\n", TranContext
->RefCount
));
97 IoReleaseCancelSpinLock(OldIrql
);
99 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
103 VOID
DispCancelRequest(
104 PDEVICE_OBJECT Device
,
107 * FUNCTION: Cancels an IRP
109 * Device = Pointer to device object
110 * Irp = Pointer to an I/O request packet
113 PIO_STACK_LOCATION IrpSp
;
114 PTRANSPORT_CONTEXT TranContext
;
115 PFILE_OBJECT FileObject
;
117 NTSTATUS Status
= STATUS_SUCCESS
;
119 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
121 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
122 FileObject
= IrpSp
->FileObject
;
123 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
124 MinorFunction
= IrpSp
->MinorFunction
;
126 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
130 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
133 /* Increase reference count to prevent accidential closure
134 of the object while inside the cancel routine */
135 TranContext
->RefCount
++;
137 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
139 /* Try canceling the request */
140 switch(MinorFunction
) {
144 /* FIXME: Close connection */
147 case TDI_SEND_DATAGRAM
:
148 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
149 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
153 DGCancelSendRequest(TranContext
->Handle
.AddressHandle
, Irp
);
156 case TDI_RECEIVE_DATAGRAM
:
157 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
158 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
162 DGCancelReceiveRequest(TranContext
->Handle
.AddressHandle
, Irp
);
166 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
170 if (Status
!= STATUS_PENDING
)
171 DispCancelComplete(FileObject
);
173 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
177 VOID
DispDataRequestComplete(
182 * FUNCTION: Completes a send/receive IRP
184 * Context = Pointer to context information (IRP)
185 * Status = Status of the request
186 * Count = Number of bytes sent or received
190 PIO_STACK_LOCATION IrpSp
;
191 PTRANSPORT_CONTEXT TranContext
;
194 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
197 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
198 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
200 IoAcquireCancelSpinLock(&OldIrql
);
202 IoSetCancelRoutine(Irp
, NULL
);
203 TranContext
->RefCount
--;
204 TI_DbgPrint(DEBUG_REFCOUNT
, ("TranContext->RefCount (%d).\n", TranContext
->RefCount
));
205 if (TranContext
->RefCount
== 0) {
206 TI_DbgPrint(DEBUG_IRP
, ("Setting TranContext->CleanupEvent to signaled.\n"));
208 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
211 if (Irp
->Cancel
|| TranContext
->CancelIrps
) {
212 /* The IRP has been cancelled */
214 TI_DbgPrint(DEBUG_IRP
, ("IRP is cancelled.\n"));
216 Status
= STATUS_CANCELLED
;
220 IoReleaseCancelSpinLock(OldIrql
);
222 Irp
->IoStatus
.Status
= Status
;
223 Irp
->IoStatus
.Information
= Count
;
225 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
227 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
231 NTSTATUS
DispTdiAccept(
234 * FUNCTION: TDI_ACCEPT handler
236 * Irp = Pointer to an I/O request packet
238 * Status of operation
241 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
243 return STATUS_NOT_IMPLEMENTED
;
247 NTSTATUS
DispTdiAssociateAddress(
250 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
252 * Irp = Pointer to an I/O request packet
254 * Status of operation
257 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
259 return STATUS_NOT_IMPLEMENTED
;
263 NTSTATUS
DispTdiConnect(
266 * FUNCTION: TDI_CONNECT handler
268 * Irp = Pointer to an I/O request packet
270 * Status of operation
273 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
275 return STATUS_NOT_IMPLEMENTED
;
279 NTSTATUS
DispTdiDisassociateAddress(
282 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
284 * Irp = Pointer to an I/O request packet
286 * Status of operation
289 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
291 return STATUS_NOT_IMPLEMENTED
;
295 NTSTATUS
DispTdiDisconnect(
298 * FUNCTION: TDI_DISCONNECT handler
300 * Irp = Pointer to an I/O request packet
302 * Status of operation
305 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
307 return STATUS_NOT_IMPLEMENTED
;
311 NTSTATUS
DispTdiListen(
314 * FUNCTION: TDI_LISTEN handler
316 * Irp = Pointer to an I/O request packet
318 * Status of operation
321 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
323 return STATUS_NOT_IMPLEMENTED
;
327 NTSTATUS
DispTdiQueryInformation(
328 PDEVICE_OBJECT DeviceObject
,
331 * FUNCTION: TDI_QUERY_INFORMATION handler
333 * DeviceObject = Pointer to device object structure
334 * Irp = Pointer to an I/O request packet
336 * Status of operation
339 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
341 return STATUS_NOT_IMPLEMENTED
;
345 NTSTATUS
DispTdiReceive(
348 * FUNCTION: TDI_RECEIVE handler
350 * Irp = Pointer to an I/O request packet
352 * Status of operation
355 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
357 return STATUS_NOT_IMPLEMENTED
;
361 NTSTATUS
DispTdiReceiveDatagram(
364 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
366 * Irp = Pointer to an I/O request packet
368 * Status of operation
371 PIO_STACK_LOCATION IrpSp
;
372 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
373 PTRANSPORT_CONTEXT TranContext
;
378 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
380 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
381 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
383 TranContext
= IrpSp
->FileObject
->FsContext
;
384 /* Initialize a receive request */
385 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
386 Request
.RequestNotifyObject
= DispDataRequestComplete
;
387 Request
.RequestContext
= Irp
;
388 Status
= DispPrepareIrpForCancel(IrpSp
->FileObject
->FsContext
, Irp
, (PDRIVER_CANCEL
)DispCancelRequest
);
389 if (NT_SUCCESS(Status
)) {
390 Status
= UDPReceiveDatagram(&Request
,
391 DgramInfo
->ReceiveDatagramInformation
,
392 (PNDIS_BUFFER
)Irp
->MdlAddress
,
393 DgramInfo
->ReceiveLength
,
394 DgramInfo
->ReceiveFlags
,
395 DgramInfo
->ReturnDatagramInformation
,
397 if (Status
!= STATUS_PENDING
) {
398 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
399 /* Return STATUS_PENDING because DispPrepareIrpForCancel marks Irp as pending */
400 Status
= STATUS_PENDING
;
404 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
410 NTSTATUS
DispTdiSend(
413 * FUNCTION: TDI_SEND handler
415 * Irp = Pointer to an I/O request packet
417 * Status of operation
420 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
422 return STATUS_NOT_IMPLEMENTED
;
426 NTSTATUS
DispTdiSendDatagram(
429 * FUNCTION: TDI_SEND_DATAGRAM handler
431 * Irp = Pointer to an I/O request packet
433 * Status of operation
436 PIO_STACK_LOCATION IrpSp
;
438 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
439 PTRANSPORT_CONTEXT TranContext
;
442 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
444 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
445 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
447 TranContext
= IrpSp
->FileObject
->FsContext
;
448 /* Initialize a send request */
449 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
450 Request
.RequestNotifyObject
= DispDataRequestComplete
;
451 Request
.RequestContext
= Irp
;
453 Status
= DispPrepareIrpForCancel(IrpSp
->FileObject
->FsContext
, Irp
, (PDRIVER_CANCEL
)DispCancelRequest
);
454 if (NT_SUCCESS(Status
)) {
456 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
457 must be of type PTDI_ADDRESS_IP */
459 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
460 &Request
, DgramInfo
->SendDatagramInformation
,
461 (PNDIS_BUFFER
)Irp
->MdlAddress
, DgramInfo
->SendLength
);
462 if (Status
!= STATUS_PENDING
) {
463 DispDataRequestComplete(Irp
, Status
, 0);
464 /* Return STATUS_PENDING because DispPrepareIrpForCancel marks Irp as pending */
465 Status
= STATUS_PENDING
;
469 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
475 NTSTATUS
DispTdiSetEventHandler(
478 * FUNCTION: TDI_SET_EVENT_HANDER handler
480 * Irp = Pointer to a I/O request packet
482 * Status of operation
486 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
487 PTRANSPORT_CONTEXT TranContext
;
488 PIO_STACK_LOCATION IrpSp
;
489 PADDRESS_FILE AddrFile
;
493 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
495 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
497 /* Get associated address file object. Quit if none exists */
498 TranContext
= IrpSp
->FileObject
->FsContext
;
500 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
501 return STATUS_INVALID_PARAMETER
;
504 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
506 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
507 return STATUS_INVALID_PARAMETER
;
510 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
511 Status
= STATUS_SUCCESS
;
513 KeAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
515 /* Set the event handler. if an event handler is associated with
516 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
517 If an event handler is not used it's flag is FALSE */
518 switch (Parameters
->EventType
) {
519 case TDI_EVENT_CONNECT
:
520 if (!Parameters
->EventHandler
) {
521 AddrFile
->ConnectionHandler
=
522 (PTDI_IND_CONNECT
)TdiDefaultConnectHandler
;
523 AddrFile
->ConnectionHandlerContext
= NULL
;
524 AddrFile
->RegisteredConnectionHandler
= FALSE
;
526 AddrFile
->ConnectionHandler
=
527 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
528 AddrFile
->ConnectionHandlerContext
= Parameters
->EventContext
;
529 AddrFile
->RegisteredConnectionHandler
= TRUE
;
533 case TDI_EVENT_DISCONNECT
:
534 if (!Parameters
->EventHandler
) {
535 AddrFile
->DisconnectHandler
=
536 (PTDI_IND_DISCONNECT
)TdiDefaultDisconnectHandler
;
537 AddrFile
->DisconnectHandlerContext
= NULL
;
538 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
540 AddrFile
->DisconnectHandler
=
541 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
542 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
543 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
547 case TDI_EVENT_RECEIVE
:
548 if (Parameters
->EventHandler
== NULL
) {
549 AddrFile
->ReceiveHandler
=
550 (PTDI_IND_RECEIVE
)TdiDefaultReceiveHandler
;
551 AddrFile
->ReceiveHandlerContext
= NULL
;
552 AddrFile
->RegisteredReceiveHandler
= FALSE
;
554 AddrFile
->ReceiveHandler
=
555 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
556 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
557 AddrFile
->RegisteredReceiveHandler
= TRUE
;
561 case TDI_EVENT_RECEIVE_EXPEDITED
:
562 if (Parameters
->EventHandler
== NULL
) {
563 AddrFile
->ExpeditedReceiveHandler
=
564 (PTDI_IND_RECEIVE_EXPEDITED
)TdiDefaultRcvExpeditedHandler
;
565 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
566 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
568 AddrFile
->ExpeditedReceiveHandler
=
569 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
570 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
571 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
575 case TDI_EVENT_RECEIVE_DATAGRAM
:
576 if (Parameters
->EventHandler
== NULL
) {
577 AddrFile
->ReceiveDatagramHandler
=
578 (PTDI_IND_RECEIVE_DATAGRAM
)TdiDefaultRcvDatagramHandler
;
579 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
580 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
582 AddrFile
->ReceiveDatagramHandler
=
583 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
584 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
585 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
589 case TDI_EVENT_ERROR
:
590 if (Parameters
->EventHandler
== NULL
) {
591 AddrFile
->ErrorHandler
=
592 (PTDI_IND_ERROR
)TdiDefaultErrorHandler
;
593 AddrFile
->ErrorHandlerContext
= NULL
;
594 AddrFile
->RegisteredErrorHandler
= FALSE
;
596 AddrFile
->ErrorHandler
=
597 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
598 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
599 AddrFile
->RegisteredErrorHandler
= TRUE
;
604 Status
= STATUS_INVALID_PARAMETER
;
607 KeReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
611 return STATUS_NOT_IMPLEMENTED
;
616 NTSTATUS
DispTdiSetInformation(
619 * FUNCTION: TDI_SET_INFORMATION handler
621 * Irp = Pointer to an I/O request packet
623 * Status of operation
626 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
628 return STATUS_NOT_IMPLEMENTED
;
632 VOID
DispTdiQueryInformationExComplete(
637 * FUNCTION: Completes a TDI QueryInformationEx request
639 * Context = Pointer to the IRP for the request
640 * Status = TDI status of the request
641 * ByteCount = Number of bytes returned in output buffer
644 PTI_QUERY_CONTEXT QueryContext
;
647 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
648 if (NT_SUCCESS(Status
)) {
649 Count
= CopyBufferToBufferChain(
650 QueryContext
->InputMdl
,
651 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
652 (PUCHAR
)&QueryContext
->QueryInfo
.Context
,
656 MmUnlockPages(QueryContext
->InputMdl
);
657 IoFreeMdl(QueryContext
->InputMdl
);
658 MmUnlockPages(QueryContext
->OutputMdl
);
659 IoFreeMdl(QueryContext
->OutputMdl
);
661 QueryContext
->Irp
->IoStatus
.Information
= Count
;
662 QueryContext
->Irp
->IoStatus
.Status
= Status
;
664 ExFreePool(QueryContext
);
668 NTSTATUS
DispTdiQueryInformationEx(
670 PIO_STACK_LOCATION IrpSp
)
672 * FUNCTION: TDI QueryInformationEx handler
674 * Irp = Pointer to I/O request packet
675 * IrpSp = Pointer to current stack location of Irp
677 * Status of operation
680 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
681 PTRANSPORT_CONTEXT TranContext
;
682 PTI_QUERY_CONTEXT QueryContext
;
686 UINT InputBufferLength
;
687 UINT OutputBufferLength
;
688 BOOLEAN InputMdlLocked
= FALSE
;
689 BOOLEAN OutputMdlLocked
= FALSE
;
690 PMDL InputMdl
= NULL
;
691 PMDL OutputMdl
= NULL
;
692 NTSTATUS Status
= STATUS_SUCCESS
;
694 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
696 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
698 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
699 case TDI_TRANSPORT_ADDRESS_FILE
:
700 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
703 case TDI_CONNECTION_FILE
:
704 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
707 case TDI_CONTROL_CHANNEL_FILE
:
708 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
712 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
713 return STATUS_INVALID_PARAMETER
;
716 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
717 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
719 /* Validate parameters */
720 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
721 (OutputBufferLength
!= 0)) {
723 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
724 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
725 OutputBuffer
= Irp
->UserBuffer
;
727 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
732 InputMdl
= IoAllocateMdl(InputBuffer
,
733 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
736 OutputMdl
= IoAllocateMdl(OutputBuffer
,
737 OutputBufferLength
, FALSE
, TRUE
, NULL
);
739 if (InputMdl
&& OutputMdl
) {
741 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
744 InputMdlLocked
= TRUE
;
746 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
749 OutputMdlLocked
= TRUE
;
751 RtlCopyMemory(&QueryContext
->QueryInfo
,
752 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
755 Status
= STATUS_INSUFFICIENT_RESOURCES
;
757 } except(EXCEPTION_EXECUTE_HANDLER
) {
758 Status
= GetExceptionCode();
761 if (NT_SUCCESS(Status
)) {
762 Size
= MmGetMdlByteCount(OutputMdl
);
764 QueryContext
->Irp
= Irp
;
765 QueryContext
->InputMdl
= InputMdl
;
766 QueryContext
->OutputMdl
= OutputMdl
;
768 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
769 Request
.RequestContext
= QueryContext
;
770 Status
= InfoTdiQueryInformationEx(&Request
,
771 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
772 &Size
, &QueryContext
->QueryInfo
.Context
);
773 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
775 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
780 /* An error occurred if we get here */
784 MmUnlockPages(InputMdl
);
790 MmUnlockPages(OutputMdl
);
791 IoFreeMdl(OutputMdl
);
794 ExFreePool(QueryContext
);
796 Status
= STATUS_INSUFFICIENT_RESOURCES
;
798 Status
= STATUS_INVALID_PARAMETER
;
800 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
806 NTSTATUS
DispTdiSetInformationEx(
808 PIO_STACK_LOCATION IrpSp
)
810 * FUNCTION: TDI SetInformationEx handler
812 * Irp = Pointer to I/O request packet
813 * IrpSp = Pointer to current stack location of Irp
815 * Status of operation
818 PTRANSPORT_CONTEXT TranContext
;
819 PTCP_REQUEST_SET_INFORMATION_EX Info
;
824 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
826 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
827 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
829 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
830 case TDI_TRANSPORT_ADDRESS_FILE
:
831 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
834 case TDI_CONNECTION_FILE
:
835 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
838 case TDI_CONTROL_CHANNEL_FILE
:
839 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
843 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
844 Irp
->IoStatus
.Information
= 0;
846 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
848 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
850 return STATUS_INVALID_PARAMETER
;
853 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
854 if (NT_SUCCESS(Status
)) {
855 Request
.RequestNotifyObject
= DispDataRequestComplete
;
856 Request
.RequestContext
= Irp
;
858 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
859 &Info
->Buffer
, Info
->BufferSize
);
861 if (Status
!= STATUS_PENDING
) {
862 IoAcquireCancelSpinLock(&OldIrql
);
863 IoSetCancelRoutine(Irp
, NULL
);
864 IoReleaseCancelSpinLock(OldIrql
);