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
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 IoMarkIrpPending(Irp
);
37 IoSetCancelRoutine(Irp
, CancelRoutine
);
38 IoReleaseCancelSpinLock(OldIrql
);
40 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp
));
42 return STATUS_SUCCESS
;
45 /* IRP has already been cancelled */
47 IoReleaseCancelSpinLock(OldIrql
);
49 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
50 Irp
->IoStatus
.Information
= 0;
52 TI_DbgPrint(DEBUG_IRP
, ("Leaving (IRP was already cancelled).\n"));
54 return IRPFinish(Irp
, STATUS_CANCELLED
);
58 VOID
DispCancelComplete(
61 * FUNCTION: Completes a cancel request
63 * Context = Pointer to context information (FILE_OBJECT)
67 PFILE_OBJECT FileObject
;
68 PTRANSPORT_CONTEXT TranContext
;
70 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
72 FileObject
= (PFILE_OBJECT
)Context
;
73 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
75 /* Set the cleanup event */
76 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
78 /* We are expected to release the cancel spin lock */
79 IoReleaseCancelSpinLock(OldIrql
);
81 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
85 VOID DDKAPI
DispCancelRequest(
86 PDEVICE_OBJECT Device
,
89 * FUNCTION: Cancels an IRP
91 * Device = Pointer to device object
92 * Irp = Pointer to an I/O request packet
95 PIO_STACK_LOCATION IrpSp
;
96 PTRANSPORT_CONTEXT TranContext
;
97 PFILE_OBJECT FileObject
;
99 NTSTATUS Status
= STATUS_SUCCESS
;
101 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
103 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
104 FileObject
= IrpSp
->FileObject
;
105 TranContext
= (PTRANSPORT_CONTEXT
)FileObject
->FsContext
;
106 MinorFunction
= IrpSp
->MinorFunction
;
108 TI_DbgPrint(DEBUG_IRP
, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp
, MinorFunction
, IrpSp
));
112 TI_DbgPrint(MIN_TRACE
, ("Irp->Cancel is FALSE, should be TRUE.\n"));
115 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
117 /* Try canceling the request */
118 switch(MinorFunction
) {
121 /* FIXME: Close connection */
124 case TDI_SEND_DATAGRAM
:
125 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
126 TI_DbgPrint(MIN_TRACE
, ("TDI_SEND_DATAGRAM, but no address file.\n"));
130 /*DGCancelSendRequest(TranContext->Handle.AddressHandle, Irp);*/
133 case TDI_RECEIVE_DATAGRAM
:
134 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
135 TI_DbgPrint(MIN_TRACE
, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
139 /*DGCancelReceiveRequest(TranContext->Handle.AddressHandle, Irp);*/
143 TI_DbgPrint(MIN_TRACE
, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction
));
147 if (Status
!= STATUS_PENDING
)
148 DispCancelComplete(FileObject
);
150 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
153 VOID
DispDataRequestComplete(
158 * FUNCTION: Completes a send/receive IRP
160 * Context = Pointer to context information (IRP)
161 * Status = Status of the request
162 * Count = Number of bytes sent or received
166 PIO_STACK_LOCATION IrpSp
;
167 PTRANSPORT_CONTEXT TranContext
;
170 TI_DbgPrint(DEBUG_IRP
, ("Called for irp %x (%x, %d).\n",
171 Context
, Status
, Count
));
174 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
175 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
177 IoAcquireCancelSpinLock(&OldIrql
);
179 IoSetCancelRoutine(Irp
, NULL
);
181 if (Irp
->Cancel
|| TranContext
->CancelIrps
) {
182 /* The IRP has been cancelled */
184 TI_DbgPrint(DEBUG_IRP
, ("IRP is cancelled.\n"));
186 Status
= STATUS_CANCELLED
;
190 IoReleaseCancelSpinLock(OldIrql
);
192 Irp
->IoStatus
.Status
= Status
;
193 Irp
->IoStatus
.Information
= Count
;
195 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Status = %x\n",
196 Irp
->IoStatus
.Status
));
197 TI_DbgPrint(MID_TRACE
, ("Irp->IoStatus.Information = %d\n",
198 Irp
->IoStatus
.Information
));
199 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
201 IRPFinish(Irp
, Irp
->IoStatus
.Status
);
203 TI_DbgPrint(DEBUG_IRP
, ("Done Completing IRP\n"));
207 NTSTATUS
DispTdiAccept(
210 * FUNCTION: TDI_ACCEPT handler
212 * Irp = Pointer to an I/O request packet
214 * Status of operation
217 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
219 return STATUS_NOT_IMPLEMENTED
;
223 NTSTATUS
DispTdiAssociateAddress(
226 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
228 * Irp = Pointer to an I/O request packet
230 * Status of operation
233 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters
;
234 PTRANSPORT_CONTEXT TranContext
;
235 PIO_STACK_LOCATION IrpSp
;
236 PCONNECTION_ENDPOINT Connection
;
237 PFILE_OBJECT FileObject
;
238 PADDRESS_FILE AddrFile
= NULL
;
241 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
243 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
245 /* Get associated connection endpoint file object. Quit if none exists */
247 TranContext
= IrpSp
->FileObject
->FsContext
;
249 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
250 return STATUS_INVALID_PARAMETER
;
253 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
255 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
256 return STATUS_INVALID_PARAMETER
;
259 if (Connection
->AddressFile
) {
260 TI_DbgPrint(MID_TRACE
, ("An address file is already asscociated.\n"));
261 return STATUS_INVALID_PARAMETER
;
264 Parameters
= (PTDI_REQUEST_KERNEL_ASSOCIATE
)&IrpSp
->Parameters
;
266 Status
= ObReferenceObjectByHandle(
267 Parameters
->AddressHandle
,
273 if (!NT_SUCCESS(Status
)) {
274 TI_DbgPrint(MID_TRACE
, ("Bad address file object handle (0x%X): %x.\n",
275 Parameters
->AddressHandle
, Status
));
276 return STATUS_INVALID_PARAMETER
;
279 if (FileObject
->FsContext2
!= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
) {
280 ObDereferenceObject(FileObject
);
281 TI_DbgPrint(MID_TRACE
, ("Bad address file object. Magic (0x%X).\n",
282 FileObject
->FsContext2
));
283 return STATUS_INVALID_PARAMETER
;
286 /* Get associated address file object. Quit if none exists */
288 TranContext
= FileObject
->FsContext
;
290 ObDereferenceObject(FileObject
);
291 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
292 return STATUS_INVALID_PARAMETER
;
295 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
297 ObDereferenceObject(FileObject
);
298 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
299 return STATUS_INVALID_PARAMETER
;
302 Connection
->AddressFile
= AddrFile
;
304 /* Add connection endpoint to the address file */
305 AddrFile
->Connection
= Connection
;
307 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
308 ObDereferenceObject(FileObject
);
314 NTSTATUS
DispTdiConnect(
317 * FUNCTION: TDI_CONNECT handler
319 * Irp = Pointer to an I/O request packet
321 * Status of operation
324 PCONNECTION_ENDPOINT Connection
;
325 PTDI_REQUEST_KERNEL Parameters
;
326 PTRANSPORT_CONTEXT TranContext
;
327 PIO_STACK_LOCATION IrpSp
;
330 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
332 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
334 /* Get associated connection endpoint file object. Quit if none exists */
336 TranContext
= IrpSp
->FileObject
->FsContext
;
338 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
339 return STATUS_INVALID_CONNECTION
;
342 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
344 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
345 return STATUS_INVALID_CONNECTION
;
348 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
351 TranContext
->Handle
.ConnectionContext
,
352 Parameters
->RequestConnectionInformation
,
353 Parameters
->ReturnConnectionInformation
,
354 DispDataRequestComplete
,
357 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
363 NTSTATUS
DispTdiDisassociateAddress(
366 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
368 * Irp = Pointer to an I/O request packet
370 * Status of operation
373 PCONNECTION_ENDPOINT Connection
;
374 PTRANSPORT_CONTEXT TranContext
;
375 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_PARAMETER
;
389 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
391 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
392 return STATUS_INVALID_PARAMETER
;
395 if (!Connection
->AddressFile
) {
396 TI_DbgPrint(MID_TRACE
, ("No address file is asscociated.\n"));
397 return STATUS_INVALID_PARAMETER
;
400 return STATUS_SUCCESS
;
404 NTSTATUS
DispTdiDisconnect(
407 * FUNCTION: TDI_DISCONNECT handler
409 * Irp = Pointer to an I/O request packet
411 * Status of operation
415 PTDI_REQUEST_KERNEL_DISCONNECT DisReq
;
416 PCONNECTION_ENDPOINT Connection
;
417 PTRANSPORT_CONTEXT TranContext
;
418 PIO_STACK_LOCATION IrpSp
;
420 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
422 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
423 DisReq
= (PTDI_REQUEST_KERNEL_DISCONNECT
)&IrpSp
->Parameters
;
425 /* Get associated connection endpoint file object. Quit if none exists */
427 TranContext
= IrpSp
->FileObject
->FsContext
;
429 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
430 return STATUS_INVALID_CONNECTION
;
433 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
435 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
436 return STATUS_INVALID_CONNECTION
;
439 Status
= TCPDisconnect(
440 TranContext
->Handle
.ConnectionContext
,
441 DisReq
->RequestFlags
,
442 DisReq
->RequestConnectionInformation
,
443 DisReq
->ReturnConnectionInformation
,
444 DispDataRequestComplete
,
447 TI_DbgPrint(MAX_TRACE
, ("TCP Connect returned %08x\n", Status
));
453 NTSTATUS
DispTdiListen(
456 * FUNCTION: TDI_LISTEN handler
458 * Irp = Pointer to an I/O request packet
460 * Status of operation
463 PCONNECTION_ENDPOINT Connection
;
464 PTDI_REQUEST_KERNEL Parameters
;
465 PTRANSPORT_CONTEXT TranContext
;
466 PIO_STACK_LOCATION IrpSp
;
467 NTSTATUS Status
= STATUS_SUCCESS
;
469 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
471 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
473 /* Get associated connection endpoint file object. Quit if none exists */
475 TranContext
= IrpSp
->FileObject
->FsContext
;
476 if (TranContext
== NULL
)
478 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
479 return STATUS_INVALID_CONNECTION
;
482 Connection
= (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
483 if (Connection
== NULL
)
485 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
486 return STATUS_INVALID_CONNECTION
;
489 Parameters
= (PTDI_REQUEST_KERNEL
)&IrpSp
->Parameters
;
491 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile: %x\n",
492 Connection
->AddressFile
));
493 if( Connection
->AddressFile
) {
494 TI_DbgPrint(MIN_TRACE
, ("Connection->AddressFile->Listener: %x\n",
495 Connection
->AddressFile
->Listener
));
498 /* Listening will require us to create a listening socket and store it in
499 * the address file. It will be signalled, and attempt to complete an irp
500 * when a new connection arrives. */
501 /* The important thing to note here is that the irp we'll complete belongs
502 * to the socket to be accepted onto, not the listener */
503 if( !Connection
->AddressFile
->Listener
) {
504 Connection
->AddressFile
->Listener
=
505 TCPAllocateConnectionEndpoint( NULL
);
507 if( !Connection
->AddressFile
->Listener
)
508 Status
= STATUS_NO_MEMORY
;
510 if( NT_SUCCESS(Status
) ) {
511 Connection
->AddressFile
->Listener
->AddressFile
=
512 Connection
->AddressFile
;
514 Status
= TCPSocket( Connection
->AddressFile
->Listener
,
515 Connection
->AddressFile
->Family
,
517 Connection
->AddressFile
->Protocol
);
520 if( NT_SUCCESS(Status
) )
521 Status
= TCPListen( Connection
->AddressFile
->Listener
, 1024 );
525 if( NT_SUCCESS(Status
) ) {
527 ( (PTDI_REQUEST
)Parameters
,
528 Connection
->AddressFile
->Listener
,
530 DispDataRequestComplete
,
534 TI_DbgPrint(MID_TRACE
,("Leaving %x\n", Status
));
540 NTSTATUS
DispTdiQueryInformation(
541 PDEVICE_OBJECT DeviceObject
,
544 * FUNCTION: TDI_QUERY_INFORMATION handler
546 * DeviceObject = Pointer to device object structure
547 * Irp = Pointer to an I/O request packet
549 * Status of operation
552 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters
;
553 PTRANSPORT_CONTEXT TranContext
;
554 PIO_STACK_LOCATION IrpSp
;
556 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
558 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
559 Parameters
= (PTDI_REQUEST_KERNEL_QUERY_INFORMATION
)&IrpSp
->Parameters
;
561 TranContext
= IrpSp
->FileObject
->FsContext
;
563 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
564 return STATUS_INVALID_CONNECTION
;
567 switch (Parameters
->QueryType
)
569 case TDI_QUERY_ADDRESS_INFO
:
571 PTDI_ADDRESS_INFO AddressInfo
;
572 PADDRESS_FILE AddrFile
;
573 PTA_IP_ADDRESS Address
;
575 AddressInfo
= (PTDI_ADDRESS_INFO
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
577 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
578 case TDI_TRANSPORT_ADDRESS_FILE
:
579 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
582 case TDI_CONNECTION_FILE
:
584 ((PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
)->
589 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
590 return STATUS_INVALID_PARAMETER
;
594 TI_DbgPrint(MID_TRACE
, ("No address file object.\n"));
595 return STATUS_INVALID_PARAMETER
;
598 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
599 (FIELD_OFFSET(TDI_ADDRESS_INFO
, Address
.Address
[0].Address
) +
600 sizeof(TDI_ADDRESS_IP
))) {
601 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small.\n"));
602 return STATUS_BUFFER_OVERFLOW
;
605 Address
= (PTA_IP_ADDRESS
)&AddressInfo
->Address
;
606 Address
->TAAddressCount
= 1;
607 Address
->Address
[0].AddressLength
= TDI_ADDRESS_LENGTH_IP
;
608 Address
->Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
609 Address
->Address
[0].Address
[0].sin_port
= AddrFile
->Port
;
610 Address
->Address
[0].Address
[0].in_addr
=
611 AddrFile
->Address
.Address
.IPv4Address
;
613 &Address
->Address
[0].Address
[0].sin_zero
,
614 sizeof(Address
->Address
[0].Address
[0].sin_zero
));
616 return STATUS_SUCCESS
;
619 case TDI_QUERY_CONNECTION_INFO
:
621 PTDI_CONNECTION_INFORMATION AddressInfo
;
622 PADDRESS_FILE AddrFile
;
623 PCONNECTION_ENDPOINT Endpoint
= NULL
;
625 AddressInfo
= (PTDI_CONNECTION_INFORMATION
)
626 MmGetSystemAddressForMdl(Irp
->MdlAddress
);
628 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
629 case TDI_TRANSPORT_ADDRESS_FILE
:
630 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
633 case TDI_CONNECTION_FILE
:
635 (PCONNECTION_ENDPOINT
)TranContext
->Handle
.ConnectionContext
;
639 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
640 return STATUS_INVALID_PARAMETER
;
644 TI_DbgPrint(MID_TRACE
, ("No connection object.\n"));
645 return STATUS_INVALID_PARAMETER
;
648 if (MmGetMdlByteCount(Irp
->MdlAddress
) <
649 (FIELD_OFFSET(TDI_CONNECTION_INFORMATION
, RemoteAddress
) +
651 TI_DbgPrint(MID_TRACE
, ("MDL buffer too small (ptr).\n"));
652 return STATUS_BUFFER_OVERFLOW
;
655 return TCPGetPeerAddress( Endpoint
, AddressInfo
->RemoteAddress
);
659 return STATUS_NOT_IMPLEMENTED
;
663 NTSTATUS
DispTdiReceive(
666 * FUNCTION: TDI_RECEIVE handler
668 * Irp = Pointer to an I/O request packet
670 * Status of operation
673 PIO_STACK_LOCATION IrpSp
;
674 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
675 PTRANSPORT_CONTEXT TranContext
;
679 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
681 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
682 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
684 TranContext
= IrpSp
->FileObject
->FsContext
;
685 if (TranContext
== NULL
)
687 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
688 return STATUS_INVALID_CONNECTION
;
691 if (TranContext
->Handle
.ConnectionContext
== NULL
)
693 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
694 return STATUS_INVALID_CONNECTION
;
697 /* Initialize a receive request */
698 Status
= DispPrepareIrpForCancel
699 (TranContext
->Handle
.ConnectionContext
,
701 (PDRIVER_CANCEL
)DispCancelRequest
);
703 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
704 if (NT_SUCCESS(Status
))
706 Status
= TCPReceiveData(
707 TranContext
->Handle
.ConnectionContext
,
708 (PNDIS_BUFFER
)Irp
->MdlAddress
,
709 ReceiveInfo
->ReceiveLength
,
711 ReceiveInfo
->ReceiveFlags
,
712 DispDataRequestComplete
,
714 if (Status
!= STATUS_PENDING
)
716 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
718 IoMarkIrpPending(Irp
);
721 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
727 NTSTATUS
DispTdiReceiveDatagram(
730 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
732 * Irp = Pointer to an I/O request packet
734 * Status of operation
737 PIO_STACK_LOCATION IrpSp
;
738 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo
;
739 PTRANSPORT_CONTEXT TranContext
;
744 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
746 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
747 DgramInfo
= (PTDI_REQUEST_KERNEL_RECEIVEDG
)&(IrpSp
->Parameters
);
749 TranContext
= IrpSp
->FileObject
->FsContext
;
750 if (TranContext
== NULL
)
752 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
753 return STATUS_INVALID_ADDRESS
;
756 /* Initialize a receive request */
757 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
758 Request
.RequestNotifyObject
= DispDataRequestComplete
;
759 Request
.RequestContext
= Irp
;
761 Status
= DispPrepareIrpForCancel(
762 IrpSp
->FileObject
->FsContext
,
764 (PDRIVER_CANCEL
)DispCancelRequest
);
766 if (NT_SUCCESS(Status
))
771 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
775 Status
= UDPReceiveDatagram(
776 Request
.Handle
.AddressHandle
,
777 DgramInfo
->ReceiveDatagramInformation
,
779 DgramInfo
->ReceiveLength
,
780 DgramInfo
->ReceiveFlags
,
781 DgramInfo
->ReturnDatagramInformation
,
783 (PDATAGRAM_COMPLETION_ROUTINE
)DispDataRequestComplete
,
785 if (Status
!= STATUS_PENDING
) {
786 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
788 IoMarkIrpPending(Irp
);
791 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
797 NTSTATUS
DispTdiSend(
800 * FUNCTION: TDI_SEND handler
802 * Irp = Pointer to an I/O request packet
804 * Status of operation
807 PIO_STACK_LOCATION IrpSp
;
808 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo
;
809 PTRANSPORT_CONTEXT TranContext
;
813 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
815 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
816 ReceiveInfo
= (PTDI_REQUEST_KERNEL_RECEIVE
)&(IrpSp
->Parameters
);
818 TranContext
= IrpSp
->FileObject
->FsContext
;
819 if (TranContext
== NULL
)
821 TI_DbgPrint(MID_TRACE
, ("Bad transport context.\n"));
822 return STATUS_INVALID_CONNECTION
;
825 if (TranContext
->Handle
.ConnectionContext
== NULL
)
827 TI_DbgPrint(MID_TRACE
, ("No connection endpoint file object.\n"));
828 return STATUS_INVALID_CONNECTION
;
831 Status
= DispPrepareIrpForCancel(
832 IrpSp
->FileObject
->FsContext
,
834 (PDRIVER_CANCEL
)DispCancelRequest
);
836 TI_DbgPrint(MID_TRACE
,("TCPIP<<< Got an MDL: %x\n", Irp
->MdlAddress
));
837 if (NT_SUCCESS(Status
))
842 NdisQueryBuffer( Irp
->MdlAddress
, &Data
, &Len
);
844 TI_DbgPrint(MID_TRACE
,("About to TCPSendData\n"));
845 Status
= TCPSendData(
846 TranContext
->Handle
.ConnectionContext
,
848 ReceiveInfo
->ReceiveLength
,
850 ReceiveInfo
->ReceiveFlags
);
851 if (Status
!= STATUS_PENDING
)
853 DispDataRequestComplete(Irp
, Status
, BytesReceived
);
855 IoMarkIrpPending( Irp
);
858 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
864 NTSTATUS
DispTdiSendDatagram(
867 * FUNCTION: TDI_SEND_DATAGRAM handler
869 * Irp = Pointer to an I/O request packet
871 * Status of operation
874 PIO_STACK_LOCATION IrpSp
;
876 PTDI_REQUEST_KERNEL_SENDDG DgramInfo
;
877 PTRANSPORT_CONTEXT TranContext
;
880 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
882 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
883 DgramInfo
= (PTDI_REQUEST_KERNEL_SENDDG
)&(IrpSp
->Parameters
);
884 TranContext
= IrpSp
->FileObject
->FsContext
;
886 /* Initialize a send request */
887 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
888 Request
.RequestNotifyObject
= DispDataRequestComplete
;
889 Request
.RequestContext
= Irp
;
891 Status
= DispPrepareIrpForCancel(
892 IrpSp
->FileObject
->FsContext
,
894 (PDRIVER_CANCEL
)DispCancelRequest
);
896 if (NT_SUCCESS(Status
)) {
900 TI_DbgPrint(MID_TRACE
,("About to query buffer %x\n", Irp
->MdlAddress
));
902 NdisQueryBuffer( (PNDIS_BUFFER
)Irp
->MdlAddress
,
906 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
907 must be of type PTDI_ADDRESS_IP */
908 TI_DbgPrint(MID_TRACE
,
909 ("About to call send routine %x\n",
910 (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)));
912 Status
= (*((PADDRESS_FILE
)Request
.Handle
.AddressHandle
)->Send
)(
913 Request
.Handle
.AddressHandle
,
914 DgramInfo
->SendDatagramInformation
,
917 &Irp
->IoStatus
.Information
);
919 if (Status
!= STATUS_PENDING
) {
920 DispDataRequestComplete(Irp
, Status
, Irp
->IoStatus
.Information
);
921 /* Return STATUS_PENDING because DispPrepareIrpForCancel
922 marks Irp as pending */
923 Status
= STATUS_PENDING
;
925 IoMarkIrpPending( Irp
);
928 TI_DbgPrint(DEBUG_IRP
, ("Leaving.\n"));
934 NTSTATUS
DispTdiSetEventHandler(PIRP Irp
)
936 * FUNCTION: TDI_SET_EVENT_HANDER handler
938 * Irp = Pointer to a I/O request packet
940 * Status of operation
943 PTDI_REQUEST_KERNEL_SET_EVENT Parameters
;
944 PTRANSPORT_CONTEXT TranContext
;
945 PIO_STACK_LOCATION IrpSp
;
946 PADDRESS_FILE AddrFile
;
950 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
952 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
954 /* Get associated address file object. Quit if none exists */
956 TranContext
= IrpSp
->FileObject
->FsContext
;
958 TI_DbgPrint(MIN_TRACE
, ("Bad transport context.\n"));
959 return STATUS_INVALID_PARAMETER
;
962 AddrFile
= (PADDRESS_FILE
)TranContext
->Handle
.AddressHandle
;
964 TI_DbgPrint(MIN_TRACE
, ("No address file object.\n"));
965 return STATUS_INVALID_PARAMETER
;
968 Parameters
= (PTDI_REQUEST_KERNEL_SET_EVENT
)&IrpSp
->Parameters
;
969 Status
= STATUS_SUCCESS
;
971 TcpipAcquireSpinLock(&AddrFile
->Lock
, &OldIrql
);
973 /* Set the event handler. if an event handler is associated with
974 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
975 If an event handler is not used it's flag is FALSE */
976 switch (Parameters
->EventType
) {
977 case TDI_EVENT_CONNECT
:
978 if (!Parameters
->EventHandler
) {
979 AddrFile
->ConnectHandlerContext
= NULL
;
980 AddrFile
->RegisteredConnectHandler
= FALSE
;
982 AddrFile
->ConnectHandler
=
983 (PTDI_IND_CONNECT
)Parameters
->EventHandler
;
984 AddrFile
->ConnectHandlerContext
= Parameters
->EventContext
;
985 AddrFile
->RegisteredConnectHandler
= TRUE
;
989 case TDI_EVENT_DISCONNECT
:
990 if (!Parameters
->EventHandler
) {
991 AddrFile
->DisconnectHandlerContext
= NULL
;
992 AddrFile
->RegisteredDisconnectHandler
= FALSE
;
994 AddrFile
->DisconnectHandler
=
995 (PTDI_IND_DISCONNECT
)Parameters
->EventHandler
;
996 AddrFile
->DisconnectHandlerContext
= Parameters
->EventContext
;
997 AddrFile
->RegisteredDisconnectHandler
= TRUE
;
1001 case TDI_EVENT_ERROR
:
1002 if (Parameters
->EventHandler
== NULL
) {
1003 AddrFile
->ErrorHandlerContext
= NULL
;
1004 AddrFile
->RegisteredErrorHandler
= FALSE
;
1006 AddrFile
->ErrorHandler
=
1007 (PTDI_IND_ERROR
)Parameters
->EventHandler
;
1008 AddrFile
->ErrorHandlerContext
= Parameters
->EventContext
;
1009 AddrFile
->RegisteredErrorHandler
= TRUE
;
1013 case TDI_EVENT_RECEIVE
:
1014 if (Parameters
->EventHandler
== NULL
) {
1015 AddrFile
->ReceiveHandlerContext
= NULL
;
1016 AddrFile
->RegisteredReceiveHandler
= FALSE
;
1018 AddrFile
->ReceiveHandler
=
1019 (PTDI_IND_RECEIVE
)Parameters
->EventHandler
;
1020 AddrFile
->ReceiveHandlerContext
= Parameters
->EventContext
;
1021 AddrFile
->RegisteredReceiveHandler
= TRUE
;
1025 case TDI_EVENT_RECEIVE_DATAGRAM
:
1026 if (Parameters
->EventHandler
== NULL
) {
1027 AddrFile
->ReceiveDatagramHandlerContext
= NULL
;
1028 AddrFile
->RegisteredReceiveDatagramHandler
= FALSE
;
1030 AddrFile
->ReceiveDatagramHandler
=
1031 (PTDI_IND_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1032 AddrFile
->ReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1033 AddrFile
->RegisteredReceiveDatagramHandler
= TRUE
;
1037 case TDI_EVENT_RECEIVE_EXPEDITED
:
1038 if (Parameters
->EventHandler
== NULL
) {
1039 AddrFile
->ExpeditedReceiveHandlerContext
= NULL
;
1040 AddrFile
->RegisteredExpeditedReceiveHandler
= FALSE
;
1042 AddrFile
->ExpeditedReceiveHandler
=
1043 (PTDI_IND_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1044 AddrFile
->ExpeditedReceiveHandlerContext
= Parameters
->EventContext
;
1045 AddrFile
->RegisteredExpeditedReceiveHandler
= TRUE
;
1049 case TDI_EVENT_CHAINED_RECEIVE
:
1050 if (Parameters
->EventHandler
== NULL
) {
1051 AddrFile
->ChainedReceiveHandlerContext
= NULL
;
1052 AddrFile
->RegisteredChainedReceiveHandler
= FALSE
;
1054 AddrFile
->ChainedReceiveHandler
=
1055 (PTDI_IND_CHAINED_RECEIVE
)Parameters
->EventHandler
;
1056 AddrFile
->ChainedReceiveHandlerContext
= Parameters
->EventContext
;
1057 AddrFile
->RegisteredChainedReceiveHandler
= TRUE
;
1061 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM
:
1062 if (Parameters
->EventHandler
== NULL
) {
1063 AddrFile
->ChainedReceiveDatagramHandlerContext
= NULL
;
1064 AddrFile
->RegisteredChainedReceiveDatagramHandler
= FALSE
;
1066 AddrFile
->ChainedReceiveDatagramHandler
=
1067 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM
)Parameters
->EventHandler
;
1068 AddrFile
->ChainedReceiveDatagramHandlerContext
= Parameters
->EventContext
;
1069 AddrFile
->RegisteredChainedReceiveDatagramHandler
= TRUE
;
1073 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED
:
1074 if (Parameters
->EventHandler
== NULL
) {
1075 AddrFile
->ChainedReceiveExpeditedHandlerContext
= NULL
;
1076 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= FALSE
;
1078 AddrFile
->ChainedReceiveExpeditedHandler
=
1079 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED
)Parameters
->EventHandler
;
1080 AddrFile
->ChainedReceiveExpeditedHandlerContext
= Parameters
->EventContext
;
1081 AddrFile
->RegisteredChainedReceiveExpeditedHandler
= TRUE
;
1086 TI_DbgPrint(MIN_TRACE
, ("Unknown event type (0x%X).\n",
1087 Parameters
->EventType
));
1089 Status
= STATUS_INVALID_PARAMETER
;
1092 TcpipReleaseSpinLock(&AddrFile
->Lock
, OldIrql
);
1098 NTSTATUS
DispTdiSetInformation(
1101 * FUNCTION: TDI_SET_INFORMATION handler
1103 * Irp = Pointer to an I/O request packet
1105 * Status of operation
1108 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1110 return STATUS_NOT_IMPLEMENTED
;
1114 VOID
DispTdiQueryInformationExComplete(
1119 * FUNCTION: Completes a TDI QueryInformationEx request
1121 * Context = Pointer to the IRP for the request
1122 * Status = TDI status of the request
1123 * ByteCount = Number of bytes returned in output buffer
1126 PTI_QUERY_CONTEXT QueryContext
;
1129 QueryContext
= (PTI_QUERY_CONTEXT
)Context
;
1130 if (NT_SUCCESS(Status
)) {
1131 Count
= CopyBufferToBufferChain(
1132 QueryContext
->InputMdl
,
1133 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX
, Context
),
1134 (PCHAR
)&QueryContext
->QueryInfo
.Context
,
1138 MmUnlockPages(QueryContext
->InputMdl
);
1139 IoFreeMdl(QueryContext
->InputMdl
);
1140 if( QueryContext
->OutputMdl
) {
1141 MmUnlockPages(QueryContext
->OutputMdl
);
1142 IoFreeMdl(QueryContext
->OutputMdl
);
1145 QueryContext
->Irp
->IoStatus
.Information
= ByteCount
;
1146 QueryContext
->Irp
->IoStatus
.Status
= Status
;
1148 ExFreePool(QueryContext
);
1152 NTSTATUS
DispTdiQueryInformationEx(
1154 PIO_STACK_LOCATION IrpSp
)
1156 * FUNCTION: TDI QueryInformationEx handler
1158 * Irp = Pointer to I/O request packet
1159 * IrpSp = Pointer to current stack location of Irp
1161 * Status of operation
1164 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer
;
1165 PTRANSPORT_CONTEXT TranContext
;
1166 PTI_QUERY_CONTEXT QueryContext
;
1168 TDI_REQUEST Request
;
1170 UINT InputBufferLength
;
1171 UINT OutputBufferLength
;
1172 BOOLEAN InputMdlLocked
= FALSE
;
1173 BOOLEAN OutputMdlLocked
= FALSE
;
1174 PMDL InputMdl
= NULL
;
1175 PMDL OutputMdl
= NULL
;
1176 NTSTATUS Status
= STATUS_SUCCESS
;
1178 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1180 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1182 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1183 case TDI_TRANSPORT_ADDRESS_FILE
:
1184 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1187 case TDI_CONNECTION_FILE
:
1188 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1191 case TDI_CONTROL_CHANNEL_FILE
:
1192 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1196 TI_DbgPrint(MIN_TRACE
, ("Invalid transport context\n"));
1197 return STATUS_INVALID_PARAMETER
;
1200 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
1201 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1203 /* Validate parameters */
1204 if ((InputBufferLength
== sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
)) &&
1205 (OutputBufferLength
!= 0)) {
1207 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1208 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1209 OutputBuffer
= Irp
->UserBuffer
;
1211 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1214 InputMdl
= IoAllocateMdl(InputBuffer
,
1215 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1218 OutputMdl
= IoAllocateMdl(OutputBuffer
,
1219 OutputBufferLength
, FALSE
, TRUE
, NULL
);
1221 if (InputMdl
&& OutputMdl
) {
1223 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1226 InputMdlLocked
= TRUE
;
1228 MmProbeAndLockPages(OutputMdl
, Irp
->RequestorMode
,
1231 OutputMdlLocked
= TRUE
;
1233 RtlCopyMemory(&QueryContext
->QueryInfo
,
1234 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1236 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1238 Status
= _SEH_GetExceptionCode();
1241 if (NT_SUCCESS(Status
)) {
1242 Size
= MmGetMdlByteCount(OutputMdl
);
1244 QueryContext
->Irp
= Irp
;
1245 QueryContext
->InputMdl
= InputMdl
;
1246 QueryContext
->OutputMdl
= OutputMdl
;
1248 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1249 Request
.RequestContext
= QueryContext
;
1250 Status
= InfoTdiQueryInformationEx(&Request
,
1251 &QueryContext
->QueryInfo
.ID
, OutputMdl
,
1252 &Size
, &QueryContext
->QueryInfo
.Context
);
1253 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1255 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1260 /* An error occurred if we get here */
1264 MmUnlockPages(InputMdl
);
1265 IoFreeMdl(InputMdl
);
1269 if (OutputMdlLocked
)
1270 MmUnlockPages(OutputMdl
);
1271 IoFreeMdl(OutputMdl
);
1274 ExFreePool(QueryContext
);
1276 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1277 } else if( InputBufferLength
==
1278 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
) ) {
1279 /* Handle the case where the user is probing the buffer for length */
1280 TI_DbgPrint(MAX_TRACE
, ("InputBufferLength %d OutputBufferLength %d\n",
1281 InputBufferLength
, OutputBufferLength
));
1282 InputBuffer
= (PTCP_REQUEST_QUERY_INFORMATION_EX
)
1283 IrpSp
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1287 QueryContext
= ExAllocatePool(NonPagedPool
, sizeof(TI_QUERY_CONTEXT
));
1288 if (!QueryContext
) return STATUS_INSUFFICIENT_RESOURCES
;
1291 InputMdl
= IoAllocateMdl(InputBuffer
,
1292 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
),
1295 MmProbeAndLockPages(InputMdl
, Irp
->RequestorMode
,
1298 InputMdlLocked
= TRUE
;
1299 Status
= STATUS_SUCCESS
;
1301 TI_DbgPrint(MAX_TRACE
, ("Failed to acquire client buffer\n"));
1302 Status
= _SEH_GetExceptionCode();
1305 if( !NT_SUCCESS(Status
) || !InputMdl
) {
1306 if( InputMdl
) IoFreeMdl( InputMdl
);
1307 ExFreePool(QueryContext
);
1311 RtlCopyMemory(&QueryContext
->QueryInfo
,
1312 InputBuffer
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
1314 QueryContext
->Irp
= Irp
;
1315 QueryContext
->InputMdl
= InputMdl
;
1316 QueryContext
->OutputMdl
= NULL
;
1318 Request
.RequestNotifyObject
= DispTdiQueryInformationExComplete
;
1319 Request
.RequestContext
= QueryContext
;
1320 Status
= InfoTdiQueryInformationEx(&Request
,
1321 &QueryContext
->QueryInfo
.ID
,
1324 &QueryContext
->QueryInfo
.Context
);
1325 DispTdiQueryInformationExComplete(QueryContext
, Status
, Size
);
1326 TI_DbgPrint(MAX_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1327 } else Status
= STATUS_INVALID_PARAMETER
;
1329 TI_DbgPrint(MIN_TRACE
, ("Leaving. Status = (0x%X)\n", Status
));
1335 NTSTATUS
DispTdiSetInformationEx(
1337 PIO_STACK_LOCATION IrpSp
)
1339 * FUNCTION: TDI SetInformationEx handler
1341 * Irp = Pointer to I/O request packet
1342 * IrpSp = Pointer to current stack location of Irp
1344 * Status of operation
1347 PTRANSPORT_CONTEXT TranContext
;
1348 PTCP_REQUEST_SET_INFORMATION_EX Info
;
1349 TDI_REQUEST Request
;
1353 TI_DbgPrint(DEBUG_IRP
, ("Called.\n"));
1355 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
1356 Info
= (PTCP_REQUEST_SET_INFORMATION_EX
)Irp
->AssociatedIrp
.SystemBuffer
;
1358 switch ((ULONG
)IrpSp
->FileObject
->FsContext2
) {
1359 case TDI_TRANSPORT_ADDRESS_FILE
:
1360 Request
.Handle
.AddressHandle
= TranContext
->Handle
.AddressHandle
;
1363 case TDI_CONNECTION_FILE
:
1364 Request
.Handle
.ConnectionContext
= TranContext
->Handle
.ConnectionContext
;
1367 case TDI_CONTROL_CHANNEL_FILE
:
1368 Request
.Handle
.ControlChannel
= TranContext
->Handle
.ControlChannel
;
1372 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
1373 Irp
->IoStatus
.Information
= 0;
1375 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
1377 return IRPFinish(Irp
, STATUS_INVALID_PARAMETER
);
1380 Status
= DispPrepareIrpForCancel(TranContext
, Irp
, NULL
);
1381 if (NT_SUCCESS(Status
)) {
1382 Request
.RequestNotifyObject
= DispDataRequestComplete
;
1383 Request
.RequestContext
= Irp
;
1385 Status
= InfoTdiSetInformationEx(&Request
, &Info
->ID
,
1386 &Info
->Buffer
, Info
->BufferSize
);
1388 if (Status
!= STATUS_PENDING
) {
1389 IoAcquireCancelSpinLock(&OldIrql
);
1390 IoSetCancelRoutine(Irp
, NULL
);
1391 IoReleaseCancelSpinLock(OldIrql
);