UDP working.
[reactos.git] / reactos / drivers / net / tcpip / tcpip / dispatch.c
1 /*
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)
7 * REVISIONS:
8 * CSH 01/08-2000 Created
9 * TODO: Validate device object in all dispatch routines
10 */
11
12 #include "precomp.h"
13
14 NTSTATUS DispPrepareIrpForCancel(
15 PTRANSPORT_CONTEXT Context,
16 PIRP Irp,
17 PDRIVER_CANCEL CancelRoutine)
18 /*
19 * FUNCTION: Prepare an IRP for cancellation
20 * ARGUMENTS:
21 * Context = Pointer to context information
22 * Irp = Pointer to an I/O request packet
23 * CancelRoutine = Routine to be called when I/O request is cancelled
24 * RETURNS:
25 * Status of operation
26 */
27 {
28 KIRQL OldIrql;
29
30 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
31
32 IoAcquireCancelSpinLock(&OldIrql);
33
34 if (!Irp->Cancel) {
35 IoMarkIrpPending(Irp);
36 IoSetCancelRoutine(Irp, CancelRoutine);
37 IoReleaseCancelSpinLock(OldIrql);
38
39 TI_DbgPrint(DEBUG_IRP, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp));
40
41 return STATUS_SUCCESS;
42 }
43
44 /* IRP has already been cancelled */
45
46 IoReleaseCancelSpinLock(OldIrql);
47
48 Irp->IoStatus.Status = STATUS_CANCELLED;
49 Irp->IoStatus.Information = 0;
50
51 TI_DbgPrint(DEBUG_IRP, ("Leaving (IRP was already cancelled).\n"));
52
53 return IRPFinish(Irp, STATUS_CANCELLED);
54 }
55
56
57 VOID DispCancelComplete(
58 PVOID Context)
59 /*
60 * FUNCTION: Completes a cancel request
61 * ARGUMENTS:
62 * Context = Pointer to context information (FILE_OBJECT)
63 */
64 {
65 KIRQL OldIrql;
66 PFILE_OBJECT FileObject;
67 PTRANSPORT_CONTEXT TranContext;
68
69 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
70
71 FileObject = (PFILE_OBJECT)Context;
72 TranContext = (PTRANSPORT_CONTEXT)FileObject->FsContext;
73
74 IoAcquireCancelSpinLock(&OldIrql);
75
76 TI_DbgPrint(DEBUG_IRP, ("Setting TranContext->CleanupEvent to signaled.\n"));
77 /* Set the cleanup event */
78 KeSetEvent(&TranContext->CleanupEvent, 0, FALSE);
79
80 IoReleaseCancelSpinLock(OldIrql);
81
82 TI_DbgPrint(DEBUG_IRP, ("Leaving.\n"));
83 }
84
85
86 VOID DispCancelRequest(
87 PDEVICE_OBJECT Device,
88 PIRP Irp)
89 /*
90 * FUNCTION: Cancels an IRP
91 * ARGUMENTS:
92 * Device = Pointer to device object
93 * Irp = Pointer to an I/O request packet
94 */
95 {
96 PIO_STACK_LOCATION IrpSp;
97 PTRANSPORT_CONTEXT TranContext;
98 PFILE_OBJECT FileObject;
99 UCHAR MinorFunction;
100 NTSTATUS Status = STATUS_SUCCESS;
101
102 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
103
104 IrpSp = IoGetCurrentIrpStackLocation(Irp);
105 FileObject = IrpSp->FileObject;
106 TranContext = (PTRANSPORT_CONTEXT)FileObject->FsContext;
107 MinorFunction = IrpSp->MinorFunction;
108
109 TI_DbgPrint(DEBUG_IRP, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp, MinorFunction, IrpSp));
110
111 #ifdef DBG
112 if (!Irp->Cancel)
113 TI_DbgPrint(MIN_TRACE, ("Irp->Cancel is FALSE, should be TRUE.\n"));
114 #endif
115
116 IoReleaseCancelSpinLock(Irp->CancelIrql);
117
118 /* Try canceling the request */
119 switch(MinorFunction) {
120 case TDI_SEND:
121 case TDI_RECEIVE:
122 /* FIXME: Close connection */
123 break;
124
125 case TDI_SEND_DATAGRAM:
126 if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
127 TI_DbgPrint(MIN_TRACE, ("TDI_SEND_DATAGRAM, but no address file.\n"));
128 break;
129 }
130
131 /*DGCancelSendRequest(TranContext->Handle.AddressHandle, Irp);*/
132 break;
133
134 case TDI_RECEIVE_DATAGRAM:
135 if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
136 TI_DbgPrint(MIN_TRACE, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
137 break;
138 }
139
140 /*DGCancelReceiveRequest(TranContext->Handle.AddressHandle, Irp);*/
141 break;
142
143 default:
144 TI_DbgPrint(MIN_TRACE, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction));
145 break;
146 }
147
148 if (Status != STATUS_PENDING)
149 DispCancelComplete(FileObject);
150
151 TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
152 }
153
154 VOID DispDataRequestComplete(
155 PVOID Context,
156 NTSTATUS Status,
157 ULONG Count)
158 /*
159 * FUNCTION: Completes a send/receive IRP
160 * ARGUMENTS:
161 * Context = Pointer to context information (IRP)
162 * Status = Status of the request
163 * Count = Number of bytes sent or received
164 */
165 {
166 PIRP Irp;
167 PIO_STACK_LOCATION IrpSp;
168 PTRANSPORT_CONTEXT TranContext;
169 KIRQL OldIrql;
170
171 TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n",
172 Context, Status, Count));
173
174 Irp = Context;
175 IrpSp = IoGetCurrentIrpStackLocation(Irp);
176 TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
177
178 IoAcquireCancelSpinLock(&OldIrql);
179
180 IoSetCancelRoutine(Irp, NULL);
181
182 KeSetEvent(&TranContext->CleanupEvent, 0, FALSE);
183
184 if (Irp->Cancel || TranContext->CancelIrps) {
185 /* The IRP has been cancelled */
186
187 TI_DbgPrint(DEBUG_IRP, ("IRP is cancelled.\n"));
188
189 Status = STATUS_CANCELLED;
190 Count = 0;
191 }
192
193 IoReleaseCancelSpinLock(OldIrql);
194
195 Irp->IoStatus.Status = Status;
196 Irp->IoStatus.Information = Count;
197
198 TI_DbgPrint(MID_TRACE, ("Irp->IoStatus.Status = %x\n",
199 Irp->IoStatus.Status));
200 TI_DbgPrint(MID_TRACE, ("Irp->IoStatus.Information = %d\n",
201 Irp->IoStatus.Information));
202 TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
203
204 IRPFinish(Irp, Irp->IoStatus.Status);
205
206 TI_DbgPrint(DEBUG_IRP, ("Done Completing IRP\n"));
207 }
208
209
210 NTSTATUS DispTdiAccept(
211 PIRP Irp)
212 /*
213 * FUNCTION: TDI_ACCEPT handler
214 * ARGUMENTS:
215 * Irp = Pointer to an I/O request packet
216 * RETURNS:
217 * Status of operation
218 */
219 {
220 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
221
222 return STATUS_NOT_IMPLEMENTED;
223 }
224
225
226 NTSTATUS DispTdiAssociateAddress(
227 PIRP Irp)
228 /*
229 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
230 * ARGUMENTS:
231 * Irp = Pointer to an I/O request packet
232 * RETURNS:
233 * Status of operation
234 */
235 {
236 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters;
237 PTRANSPORT_CONTEXT TranContext;
238 PIO_STACK_LOCATION IrpSp;
239 PCONNECTION_ENDPOINT Connection;
240 PFILE_OBJECT FileObject;
241 PADDRESS_FILE AddrFile = NULL;
242 NTSTATUS Status;
243
244 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
245
246 IrpSp = IoGetCurrentIrpStackLocation(Irp);
247
248 /* Get associated connection endpoint file object. Quit if none exists */
249
250 TranContext = IrpSp->FileObject->FsContext;
251 if (!TranContext) {
252 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
253 return STATUS_INVALID_PARAMETER;
254 }
255
256 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
257 if (!Connection) {
258 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
259 return STATUS_INVALID_PARAMETER;
260 }
261
262 if (Connection->AddressFile) {
263 TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n"));
264 return STATUS_INVALID_PARAMETER;
265 }
266
267 Parameters = (PTDI_REQUEST_KERNEL_ASSOCIATE)&IrpSp->Parameters;
268
269 Status = ObReferenceObjectByHandle(
270 Parameters->AddressHandle,
271 0,
272 IoFileObjectType,
273 KernelMode,
274 (PVOID*)&FileObject,
275 NULL);
276 if (!NT_SUCCESS(Status)) {
277 TI_DbgPrint(MID_TRACE, ("Bad address file object handle (0x%X).\n",
278 Parameters->AddressHandle));
279 return STATUS_INVALID_PARAMETER;
280 }
281
282 if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
283 ObDereferenceObject(FileObject);
284 TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n",
285 FileObject->FsContext2));
286 return STATUS_INVALID_PARAMETER;
287 }
288
289 /* Get associated address file object. Quit if none exists */
290
291 TranContext = FileObject->FsContext;
292 if (!TranContext) {
293 ObDereferenceObject(FileObject);
294 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
295 return STATUS_INVALID_PARAMETER;
296 }
297
298 AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
299 if (!AddrFile) {
300 ObDereferenceObject(FileObject);
301 TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
302 return STATUS_INVALID_PARAMETER;
303 }
304
305 Connection->AddressFile = AddrFile;
306
307 /* Add connection endpoint to the address file */
308 AddrFile->Connection = Connection;
309
310 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
311 ObDereferenceObject(FileObject);
312
313 return Status;
314 }
315
316
317 NTSTATUS DispTdiConnect(
318 PIRP Irp)
319 /*
320 * FUNCTION: TDI_CONNECT handler
321 * ARGUMENTS:
322 * Irp = Pointer to an I/O request packet
323 * RETURNS:
324 * Status of operation
325 */
326 {
327 PCONNECTION_ENDPOINT Connection;
328 PTDI_REQUEST_KERNEL Parameters;
329 PTRANSPORT_CONTEXT TranContext;
330 PIO_STACK_LOCATION IrpSp;
331 NTSTATUS Status;
332
333 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
334
335 IrpSp = IoGetCurrentIrpStackLocation(Irp);
336
337 /* Get associated connection endpoint file object. Quit if none exists */
338
339 TranContext = IrpSp->FileObject->FsContext;
340 if (!TranContext) {
341 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
342 return STATUS_INVALID_CONNECTION;
343 }
344
345 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
346 if (!Connection) {
347 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
348 return STATUS_INVALID_CONNECTION;
349 }
350
351 Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
352
353 Status = TCPConnect(
354 TranContext->Handle.ConnectionContext,
355 Parameters->RequestConnectionInformation,
356 Parameters->ReturnConnectionInformation,
357 DispDataRequestComplete,
358 Irp );
359
360 TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status));
361
362 return Status;
363 }
364
365
366 NTSTATUS DispTdiDisassociateAddress(
367 PIRP Irp)
368 /*
369 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
370 * ARGUMENTS:
371 * Irp = Pointer to an I/O request packet
372 * RETURNS:
373 * Status of operation
374 */
375 {
376 PCONNECTION_ENDPOINT Connection;
377 PTRANSPORT_CONTEXT TranContext;
378 PIO_STACK_LOCATION IrpSp;
379
380 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
381
382 IrpSp = IoGetCurrentIrpStackLocation(Irp);
383
384 /* Get associated connection endpoint file object. Quit if none exists */
385
386 TranContext = IrpSp->FileObject->FsContext;
387 if (!TranContext) {
388 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
389 return STATUS_INVALID_PARAMETER;
390 }
391
392 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
393 if (!Connection) {
394 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
395 return STATUS_INVALID_PARAMETER;
396 }
397
398 if (!Connection->AddressFile) {
399 TI_DbgPrint(MID_TRACE, ("No address file is asscociated.\n"));
400 return STATUS_INVALID_PARAMETER;
401 }
402
403 return STATUS_SUCCESS;
404 }
405
406
407 NTSTATUS DispTdiDisconnect(
408 PIRP Irp)
409 /*
410 * FUNCTION: TDI_DISCONNECT handler
411 * ARGUMENTS:
412 * Irp = Pointer to an I/O request packet
413 * RETURNS:
414 * Status of operation
415 */
416 {
417 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters;
418 PTRANSPORT_CONTEXT TranContext;
419 PIO_STACK_LOCATION IrpSp;
420
421 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
422
423 IrpSp = IoGetCurrentIrpStackLocation(Irp);
424 Parameters = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters;
425
426 TranContext = IrpSp->FileObject->FsContext;
427 if (!TranContext) {
428 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
429 return STATUS_INVALID_CONNECTION;
430 }
431
432 switch (Parameters->QueryType)
433 {
434 case TDI_QUERY_ADDRESS_INFO:
435 {
436 PTDI_ADDRESS_INFO AddressInfo;
437 PADDRESS_FILE AddrFile;
438 PTA_IP_ADDRESS Address;
439
440 AddressInfo = (PTDI_ADDRESS_INFO)MmGetSystemAddressForMdl(Irp->MdlAddress);
441
442 switch ((ULONG)IrpSp->FileObject->FsContext2) {
443 case TDI_TRANSPORT_ADDRESS_FILE:
444 AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
445 break;
446
447 case TDI_CONNECTION_FILE:
448 AddrFile = ((PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext)->AddressFile;
449 break;
450
451 default:
452 TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
453 return STATUS_INVALID_PARAMETER;
454 }
455
456 if (!AddrFile) {
457 TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
458 return STATUS_INVALID_PARAMETER;
459 }
460
461 if (MmGetMdlByteCount(Irp->MdlAddress) <
462 (sizeof(TDI_ADDRESS_INFO) + sizeof(TDI_ADDRESS_IP))) {
463 TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n"));
464 return STATUS_BUFFER_OVERFLOW;
465 }
466
467 Address = (PTA_IP_ADDRESS)&AddressInfo->Address;
468 Address->TAAddressCount = 1;
469 Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
470 Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
471 Address->Address[0].Address[0].sin_port = AddrFile->Port;
472 Address->Address[0].Address[0].in_addr = AddrFile->ADE->Address.Address.IPv4Address;
473 RtlZeroMemory(
474 &Address->Address[0].Address[0].sin_zero,
475 sizeof(Address->Address[0].Address[0].sin_zero));
476
477 return STATUS_SUCCESS;
478 }
479 }
480
481 return STATUS_NOT_IMPLEMENTED;
482 }
483
484
485 NTSTATUS DispTdiListen(
486 PIRP Irp)
487 /*
488 * FUNCTION: TDI_LISTEN handler
489 * ARGUMENTS:
490 * Irp = Pointer to an I/O request packet
491 * RETURNS:
492 * Status of operation
493 */
494 {
495 PCONNECTION_ENDPOINT Connection;
496 PTDI_REQUEST_KERNEL Parameters;
497 PTRANSPORT_CONTEXT TranContext;
498 PIO_STACK_LOCATION IrpSp;
499 PTDI_REQUEST Request;
500 NTSTATUS Status;
501
502 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
503
504 IrpSp = IoGetCurrentIrpStackLocation(Irp);
505
506 /* Get associated connection endpoint file object. Quit if none exists */
507
508 TranContext = IrpSp->FileObject->FsContext;
509 if (TranContext == NULL)
510 {
511 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
512 return STATUS_INVALID_CONNECTION;
513 }
514
515 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
516 if (Connection == NULL)
517 {
518 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
519 return STATUS_INVALID_CONNECTION;
520 }
521
522 Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
523
524 Status = TCPListen( Request->Handle.ConnectionContext, 1024 /* BACKLOG */,
525 DispDataRequestComplete,
526 Irp );
527
528 return Status;
529 }
530
531
532 NTSTATUS DispTdiQueryInformation(
533 PDEVICE_OBJECT DeviceObject,
534 PIRP Irp)
535 /*
536 * FUNCTION: TDI_QUERY_INFORMATION handler
537 * ARGUMENTS:
538 * DeviceObject = Pointer to device object structure
539 * Irp = Pointer to an I/O request packet
540 * RETURNS:
541 * Status of operation
542 */
543 {
544 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters;
545 PTRANSPORT_CONTEXT TranContext;
546 PIO_STACK_LOCATION IrpSp;
547
548 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
549
550 IrpSp = IoGetCurrentIrpStackLocation(Irp);
551 Parameters = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters;
552
553 TranContext = IrpSp->FileObject->FsContext;
554 if (!TranContext) {
555 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
556 return STATUS_INVALID_CONNECTION;
557 }
558
559 switch (Parameters->QueryType)
560 {
561 case TDI_QUERY_ADDRESS_INFO:
562 {
563 PTDI_ADDRESS_INFO AddressInfo;
564 PADDRESS_FILE AddrFile;
565 PTA_IP_ADDRESS Address;
566
567 AddressInfo = (PTDI_ADDRESS_INFO)MmGetSystemAddressForMdl(Irp->MdlAddress);
568
569 switch ((ULONG)IrpSp->FileObject->FsContext2) {
570 case TDI_TRANSPORT_ADDRESS_FILE:
571 AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
572 break;
573
574 case TDI_CONNECTION_FILE:
575 AddrFile = ((PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext)->AddressFile;
576 break;
577
578 default:
579 TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
580 return STATUS_INVALID_PARAMETER;
581 }
582
583 if (!AddrFile) {
584 TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
585 return STATUS_INVALID_PARAMETER;
586 }
587
588 if (MmGetMdlByteCount(Irp->MdlAddress) <
589 (sizeof(TDI_ADDRESS_INFO) + sizeof(TDI_ADDRESS_IP))) {
590 TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n"));
591 return STATUS_BUFFER_OVERFLOW;
592 }
593
594 Address = (PTA_IP_ADDRESS)&AddressInfo->Address;
595 Address->TAAddressCount = 1;
596 Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
597 Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
598 Address->Address[0].Address[0].sin_port = AddrFile->Port;
599 Address->Address[0].Address[0].in_addr = AddrFile->ADE->Address.Address.IPv4Address;
600 RtlZeroMemory(
601 &Address->Address[0].Address[0].sin_zero,
602 sizeof(Address->Address[0].Address[0].sin_zero));
603
604 return STATUS_SUCCESS;
605 }
606 }
607
608 return STATUS_NOT_IMPLEMENTED;
609 }
610
611
612 NTSTATUS DispTdiReceive(
613 PIRP Irp)
614 /*
615 * FUNCTION: TDI_RECEIVE handler
616 * ARGUMENTS:
617 * Irp = Pointer to an I/O request packet
618 * RETURNS:
619 * Status of operation
620 */
621 {
622 PIO_STACK_LOCATION IrpSp;
623 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo;
624 PTRANSPORT_CONTEXT TranContext;
625 NTSTATUS Status;
626 ULONG BytesReceived;
627
628 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
629
630 IrpSp = IoGetCurrentIrpStackLocation(Irp);
631 ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters);
632
633 TranContext = IrpSp->FileObject->FsContext;
634 if (TranContext == NULL)
635 {
636 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
637 return STATUS_INVALID_CONNECTION;
638 }
639
640 if (TranContext->Handle.ConnectionContext == NULL)
641 {
642 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
643 return STATUS_INVALID_CONNECTION;
644 }
645
646 /* Initialize a receive request */
647 Status = DispPrepareIrpForCancel(
648 IrpSp->FileObject->FsContext,
649 Irp,
650 (PDRIVER_CANCEL)DispCancelRequest);
651 TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress));
652 if (NT_SUCCESS(Status))
653 {
654 Status = TCPReceiveData(
655 TranContext->Handle.ConnectionContext,
656 (PNDIS_BUFFER)Irp->MdlAddress,
657 ReceiveInfo->ReceiveLength,
658 &BytesReceived,
659 ReceiveInfo->ReceiveFlags,
660 DispDataRequestComplete,
661 Irp);
662 if (Status != STATUS_PENDING)
663 {
664 ASSERT(0);
665 DispDataRequestComplete(Irp, Status, BytesReceived);
666 }
667 }
668
669 if (Status != STATUS_PENDING)
670 {
671 IrpSp->Control &= ~SL_PENDING_RETURNED;
672 }
673
674 TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
675
676 return Status;
677 }
678
679
680 NTSTATUS DispTdiReceiveDatagram(
681 PIRP Irp)
682 /*
683 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
684 * ARGUMENTS:
685 * Irp = Pointer to an I/O request packet
686 * RETURNS:
687 * Status of operation
688 */
689 {
690 PIO_STACK_LOCATION IrpSp;
691 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo;
692 PTRANSPORT_CONTEXT TranContext;
693 TDI_REQUEST Request;
694 NTSTATUS Status;
695 ULONG BytesReceived;
696
697 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
698
699 IrpSp = IoGetCurrentIrpStackLocation(Irp);
700 DgramInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&(IrpSp->Parameters);
701
702 TranContext = IrpSp->FileObject->FsContext;
703 if (TranContext == NULL)
704 {
705 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
706 return STATUS_INVALID_ADDRESS;
707 }
708
709 /* Initialize a receive request */
710 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
711 Request.RequestNotifyObject = DispDataRequestComplete;
712 Request.RequestContext = Irp;
713 Status = DispPrepareIrpForCancel(
714 IrpSp->FileObject->FsContext,
715 Irp,
716 (PDRIVER_CANCEL)DispCancelRequest);
717 if (NT_SUCCESS(Status))
718 {
719 PCHAR DataBuffer;
720 UINT BufferSize;
721
722 NdisQueryBuffer( (PNDIS_BUFFER)Irp->MdlAddress,
723 &DataBuffer,
724 &BufferSize );
725
726 Status = UDPReceiveDatagram(
727 Request.Handle.AddressHandle,
728 DgramInfo->ReceiveDatagramInformation,
729 DataBuffer,
730 DgramInfo->ReceiveLength,
731 DgramInfo->ReceiveFlags,
732 DgramInfo->ReturnDatagramInformation,
733 &BytesReceived,
734 (PDATAGRAM_COMPLETION_ROUTINE)DispDataRequestComplete,
735 Irp);
736 if (Status != STATUS_PENDING)
737 {
738 DispDataRequestComplete(Irp, Status, BytesReceived);
739 }
740 }
741
742 if (Status != STATUS_PENDING)
743 {
744 IrpSp->Control &= ~SL_PENDING_RETURNED;
745 }
746
747 TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
748
749 return Status;
750 }
751
752
753 NTSTATUS DispTdiSend(
754 PIRP Irp)
755 /*
756 * FUNCTION: TDI_SEND handler
757 * ARGUMENTS:
758 * Irp = Pointer to an I/O request packet
759 * RETURNS:
760 * Status of operation
761 */
762 {
763 PIO_STACK_LOCATION IrpSp;
764 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo;
765 PTRANSPORT_CONTEXT TranContext;
766 NTSTATUS Status;
767 ULONG BytesReceived;
768
769 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
770
771 IrpSp = IoGetCurrentIrpStackLocation(Irp);
772 ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters);
773
774 TranContext = IrpSp->FileObject->FsContext;
775 if (TranContext == NULL)
776 {
777 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
778 return STATUS_INVALID_CONNECTION;
779 }
780
781 if (TranContext->Handle.ConnectionContext == NULL)
782 {
783 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
784 return STATUS_INVALID_CONNECTION;
785 }
786
787 Status = DispPrepareIrpForCancel(
788 IrpSp->FileObject->FsContext,
789 Irp,
790 (PDRIVER_CANCEL)DispCancelRequest);
791 TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress));
792 if (NT_SUCCESS(Status))
793 {
794 PCHAR Data;
795 UINT Len;
796
797 NdisQueryBuffer( Irp->MdlAddress, &Data, &Len );
798
799 TI_DbgPrint(MID_TRACE,("About to TCPSendData\n"));
800 Status = TCPSendData(
801 TranContext->Handle.ConnectionContext,
802 Data,
803 ReceiveInfo->ReceiveLength,
804 &BytesReceived,
805 ReceiveInfo->ReceiveFlags);
806 if (Status != STATUS_PENDING)
807 {
808 DispDataRequestComplete(Irp, Status, BytesReceived);
809 }
810 }
811
812 if (Status != STATUS_PENDING)
813 {
814 IrpSp->Control &= ~SL_PENDING_RETURNED;
815 }
816
817 TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
818
819 return Status;
820 }
821
822
823 NTSTATUS DispTdiSendDatagram(
824 PIRP Irp)
825 /*
826 * FUNCTION: TDI_SEND_DATAGRAM handler
827 * ARGUMENTS:
828 * Irp = Pointer to an I/O request packet
829 * RETURNS:
830 * Status of operation
831 */
832 {
833 PIO_STACK_LOCATION IrpSp;
834 TDI_REQUEST Request;
835 PTDI_REQUEST_KERNEL_SENDDG DgramInfo;
836 PTRANSPORT_CONTEXT TranContext;
837 NTSTATUS Status;
838
839 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
840
841 IrpSp = IoGetCurrentIrpStackLocation(Irp);
842 DgramInfo = (PTDI_REQUEST_KERNEL_SENDDG)&(IrpSp->Parameters);
843 TranContext = IrpSp->FileObject->FsContext;
844
845 /* Initialize a send request */
846 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
847 Request.RequestNotifyObject = DispDataRequestComplete;
848 Request.RequestContext = Irp;
849
850 Status = DispPrepareIrpForCancel(
851 IrpSp->FileObject->FsContext,
852 Irp,
853 (PDRIVER_CANCEL)DispCancelRequest);
854 if (NT_SUCCESS(Status)) {
855 PCHAR DataBuffer;
856 UINT BufferSize;
857
858 TI_DbgPrint(MID_TRACE,("About to query buffer %x\n", Irp->MdlAddress));
859
860 NdisQueryBuffer( (PNDIS_BUFFER)Irp->MdlAddress,
861 &DataBuffer,
862 &BufferSize );
863
864 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
865 must be of type PTDI_ADDRESS_IP */
866 TI_DbgPrint(MID_TRACE,
867 ("About to call send routine %x\n",
868 (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)));
869
870 Status = (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)(
871 Request.Handle.AddressHandle,
872 DgramInfo->SendDatagramInformation,
873 DataBuffer,
874 BufferSize,
875 &Irp->IoStatus.Information);
876
877 if (Status != STATUS_PENDING) {
878 DispDataRequestComplete(Irp, Status, Irp->IoStatus.Information);
879 /* Return STATUS_PENDING because DispPrepareIrpForCancel
880 marks Irp as pending */
881 Status = STATUS_PENDING;
882 }
883 }
884
885 TI_DbgPrint(DEBUG_IRP, ("Leaving.\n"));
886
887 return Status;
888 }
889
890
891 NTSTATUS DispTdiSetEventHandler(PIRP Irp)
892 /*
893 * FUNCTION: TDI_SET_EVENT_HANDER handler
894 * ARGUMENTS:
895 * Irp = Pointer to a I/O request packet
896 * RETURNS:
897 * Status of operation
898 */
899 {
900 PTDI_REQUEST_KERNEL_SET_EVENT Parameters;
901 PTRANSPORT_CONTEXT TranContext;
902 PIO_STACK_LOCATION IrpSp;
903 PADDRESS_FILE AddrFile;
904 NTSTATUS Status;
905 KIRQL OldIrql;
906
907 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
908
909 IrpSp = IoGetCurrentIrpStackLocation(Irp);
910
911 /* Get associated address file object. Quit if none exists */
912
913 TranContext = IrpSp->FileObject->FsContext;
914 if (!TranContext) {
915 TI_DbgPrint(MIN_TRACE, ("Bad transport context.\n"));
916 return STATUS_INVALID_PARAMETER;
917 }
918
919 AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
920 if (!AddrFile) {
921 TI_DbgPrint(MIN_TRACE, ("No address file object.\n"));
922 return STATUS_INVALID_PARAMETER;
923 }
924
925 Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
926 Status = STATUS_SUCCESS;
927
928 TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
929
930 /* Set the event handler. if an event handler is associated with
931 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
932 If an event handler is not used it's flag is FALSE */
933 switch (Parameters->EventType) {
934 case TDI_EVENT_CONNECT:
935 if (!Parameters->EventHandler) {
936 AddrFile->ConnectHandlerContext = NULL;
937 AddrFile->RegisteredConnectHandler = FALSE;
938 } else {
939 AddrFile->ConnectHandler =
940 (PTDI_IND_CONNECT)Parameters->EventHandler;
941 AddrFile->ConnectHandlerContext = Parameters->EventContext;
942 AddrFile->RegisteredConnectHandler = TRUE;
943 }
944 break;
945
946 case TDI_EVENT_DISCONNECT:
947 if (!Parameters->EventHandler) {
948 AddrFile->DisconnectHandlerContext = NULL;
949 AddrFile->RegisteredDisconnectHandler = FALSE;
950 } else {
951 AddrFile->DisconnectHandler =
952 (PTDI_IND_DISCONNECT)Parameters->EventHandler;
953 AddrFile->DisconnectHandlerContext = Parameters->EventContext;
954 AddrFile->RegisteredDisconnectHandler = TRUE;
955 }
956 break;
957
958 case TDI_EVENT_ERROR:
959 if (Parameters->EventHandler == NULL) {
960 AddrFile->ErrorHandlerContext = NULL;
961 AddrFile->RegisteredErrorHandler = FALSE;
962 } else {
963 AddrFile->ErrorHandler =
964 (PTDI_IND_ERROR)Parameters->EventHandler;
965 AddrFile->ErrorHandlerContext = Parameters->EventContext;
966 AddrFile->RegisteredErrorHandler = TRUE;
967 }
968 break;
969
970 case TDI_EVENT_RECEIVE:
971 if (Parameters->EventHandler == NULL) {
972 AddrFile->ReceiveHandlerContext = NULL;
973 AddrFile->RegisteredReceiveHandler = FALSE;
974 } else {
975 AddrFile->ReceiveHandler =
976 (PTDI_IND_RECEIVE)Parameters->EventHandler;
977 AddrFile->ReceiveHandlerContext = Parameters->EventContext;
978 AddrFile->RegisteredReceiveHandler = TRUE;
979 }
980 break;
981
982 case TDI_EVENT_RECEIVE_DATAGRAM:
983 if (Parameters->EventHandler == NULL) {
984 AddrFile->ReceiveDatagramHandlerContext = NULL;
985 AddrFile->RegisteredReceiveDatagramHandler = FALSE;
986 } else {
987 AddrFile->ReceiveDatagramHandler =
988 (PTDI_IND_RECEIVE_DATAGRAM)Parameters->EventHandler;
989 AddrFile->ReceiveDatagramHandlerContext = Parameters->EventContext;
990 AddrFile->RegisteredReceiveDatagramHandler = TRUE;
991 }
992 break;
993
994 case TDI_EVENT_RECEIVE_EXPEDITED:
995 if (Parameters->EventHandler == NULL) {
996 AddrFile->ExpeditedReceiveHandlerContext = NULL;
997 AddrFile->RegisteredExpeditedReceiveHandler = FALSE;
998 } else {
999 AddrFile->ExpeditedReceiveHandler =
1000 (PTDI_IND_RECEIVE_EXPEDITED)Parameters->EventHandler;
1001 AddrFile->ExpeditedReceiveHandlerContext = Parameters->EventContext;
1002 AddrFile->RegisteredExpeditedReceiveHandler = TRUE;
1003 }
1004 break;
1005
1006 case TDI_EVENT_CHAINED_RECEIVE:
1007 if (Parameters->EventHandler == NULL) {
1008 AddrFile->ChainedReceiveHandlerContext = NULL;
1009 AddrFile->RegisteredChainedReceiveHandler = FALSE;
1010 } else {
1011 AddrFile->ChainedReceiveHandler =
1012 (PTDI_IND_CHAINED_RECEIVE)Parameters->EventHandler;
1013 AddrFile->ChainedReceiveHandlerContext = Parameters->EventContext;
1014 AddrFile->RegisteredChainedReceiveHandler = TRUE;
1015 }
1016 break;
1017
1018 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM:
1019 if (Parameters->EventHandler == NULL) {
1020 AddrFile->ChainedReceiveDatagramHandlerContext = NULL;
1021 AddrFile->RegisteredChainedReceiveDatagramHandler = FALSE;
1022 } else {
1023 AddrFile->ChainedReceiveDatagramHandler =
1024 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM)Parameters->EventHandler;
1025 AddrFile->ChainedReceiveDatagramHandlerContext = Parameters->EventContext;
1026 AddrFile->RegisteredChainedReceiveDatagramHandler = TRUE;
1027 }
1028 break;
1029
1030 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED:
1031 if (Parameters->EventHandler == NULL) {
1032 AddrFile->ChainedReceiveExpeditedHandlerContext = NULL;
1033 AddrFile->RegisteredChainedReceiveExpeditedHandler = FALSE;
1034 } else {
1035 AddrFile->ChainedReceiveExpeditedHandler =
1036 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED)Parameters->EventHandler;
1037 AddrFile->ChainedReceiveExpeditedHandlerContext = Parameters->EventContext;
1038 AddrFile->RegisteredChainedReceiveExpeditedHandler = TRUE;
1039 }
1040 break;
1041
1042 default:
1043 TI_DbgPrint(MIN_TRACE, ("Unknown event type (0x%X).\n",
1044 Parameters->EventType));
1045
1046 Status = STATUS_INVALID_PARAMETER;
1047 }
1048
1049 TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
1050
1051 return Status;
1052 }
1053
1054
1055 NTSTATUS DispTdiSetInformation(
1056 PIRP Irp)
1057 /*
1058 * FUNCTION: TDI_SET_INFORMATION handler
1059 * ARGUMENTS:
1060 * Irp = Pointer to an I/O request packet
1061 * RETURNS:
1062 * Status of operation
1063 */
1064 {
1065 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
1066
1067 return STATUS_NOT_IMPLEMENTED;
1068 }
1069
1070
1071 VOID DispTdiQueryInformationExComplete(
1072 PVOID Context,
1073 ULONG Status,
1074 UINT ByteCount)
1075 /*
1076 * FUNCTION: Completes a TDI QueryInformationEx request
1077 * ARGUMENTS:
1078 * Context = Pointer to the IRP for the request
1079 * Status = TDI status of the request
1080 * ByteCount = Number of bytes returned in output buffer
1081 */
1082 {
1083 PTI_QUERY_CONTEXT QueryContext;
1084 UINT Count = 0;
1085
1086 QueryContext = (PTI_QUERY_CONTEXT)Context;
1087 if (NT_SUCCESS(Status)) {
1088 Count = CopyBufferToBufferChain(
1089 QueryContext->InputMdl,
1090 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX, Context),
1091 (PUCHAR)&QueryContext->QueryInfo.Context,
1092 CONTEXT_SIZE);
1093 }
1094
1095 MmUnlockPages(QueryContext->InputMdl);
1096 IoFreeMdl(QueryContext->InputMdl);
1097 MmUnlockPages(QueryContext->OutputMdl);
1098 IoFreeMdl(QueryContext->OutputMdl);
1099
1100 QueryContext->Irp->IoStatus.Information = ByteCount;
1101 QueryContext->Irp->IoStatus.Status = Status;
1102
1103 ExFreePool(QueryContext);
1104 }
1105
1106
1107 NTSTATUS DispTdiQueryInformationEx(
1108 PIRP Irp,
1109 PIO_STACK_LOCATION IrpSp)
1110 /*
1111 * FUNCTION: TDI QueryInformationEx handler
1112 * ARGUMENTS:
1113 * Irp = Pointer to I/O request packet
1114 * IrpSp = Pointer to current stack location of Irp
1115 * RETURNS:
1116 * Status of operation
1117 */
1118 {
1119 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer;
1120 PTRANSPORT_CONTEXT TranContext;
1121 PTI_QUERY_CONTEXT QueryContext;
1122 PVOID OutputBuffer;
1123 TDI_REQUEST Request;
1124 UINT Size;
1125 UINT InputBufferLength;
1126 UINT OutputBufferLength;
1127 BOOLEAN InputMdlLocked = FALSE;
1128 BOOLEAN OutputMdlLocked = FALSE;
1129 PMDL InputMdl = NULL;
1130 PMDL OutputMdl = NULL;
1131 NTSTATUS Status = STATUS_SUCCESS;
1132
1133 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
1134
1135 TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
1136
1137 switch ((ULONG)IrpSp->FileObject->FsContext2) {
1138 case TDI_TRANSPORT_ADDRESS_FILE:
1139 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
1140 break;
1141
1142 case TDI_CONNECTION_FILE:
1143 Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
1144 break;
1145
1146 case TDI_CONTROL_CHANNEL_FILE:
1147 Request.Handle.ControlChannel = TranContext->Handle.ControlChannel;
1148 break;
1149
1150 default:
1151 TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
1152 return STATUS_INVALID_PARAMETER;
1153 }
1154
1155 InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
1156 OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
1157
1158 /* Validate parameters */
1159 if ((InputBufferLength == sizeof(TCP_REQUEST_QUERY_INFORMATION_EX)) &&
1160 (OutputBufferLength != 0)) {
1161
1162 InputBuffer = (PTCP_REQUEST_QUERY_INFORMATION_EX)
1163 IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
1164 OutputBuffer = Irp->UserBuffer;
1165
1166 QueryContext = ExAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT));
1167 if (QueryContext) {
1168 #ifdef _MSC_VER
1169 try {
1170 #endif
1171 InputMdl = IoAllocateMdl(InputBuffer,
1172 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX),
1173 FALSE, TRUE, NULL);
1174
1175 OutputMdl = IoAllocateMdl(OutputBuffer,
1176 OutputBufferLength, FALSE, TRUE, NULL);
1177
1178 if (InputMdl && OutputMdl) {
1179
1180 MmProbeAndLockPages(InputMdl, Irp->RequestorMode,
1181 IoModifyAccess);
1182
1183 InputMdlLocked = TRUE;
1184
1185 MmProbeAndLockPages(OutputMdl, Irp->RequestorMode,
1186 IoWriteAccess);
1187
1188 OutputMdlLocked = TRUE;
1189
1190 RtlCopyMemory(&QueryContext->QueryInfo,
1191 InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
1192
1193 } else
1194 Status = STATUS_INSUFFICIENT_RESOURCES;
1195 #ifdef _MSC_VER
1196 } except(EXCEPTION_EXECUTE_HANDLER) {
1197 Status = GetExceptionCode();
1198 }
1199 #endif
1200 if (NT_SUCCESS(Status)) {
1201 Size = MmGetMdlByteCount(OutputMdl);
1202
1203 QueryContext->Irp = Irp;
1204 QueryContext->InputMdl = InputMdl;
1205 QueryContext->OutputMdl = OutputMdl;
1206
1207 Request.RequestNotifyObject = DispTdiQueryInformationExComplete;
1208 Request.RequestContext = QueryContext;
1209 Status = InfoTdiQueryInformationEx(&Request,
1210 &QueryContext->QueryInfo.ID, OutputMdl,
1211 &Size, &QueryContext->QueryInfo.Context);
1212 DispTdiQueryInformationExComplete(QueryContext, Status, Size);
1213
1214 TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status));
1215
1216 return Status;
1217 }
1218
1219 /* An error occurred if we get here */
1220
1221 if (InputMdl) {
1222 if (InputMdlLocked)
1223 MmUnlockPages(InputMdl);
1224 IoFreeMdl(InputMdl);
1225 }
1226
1227 if (OutputMdl) {
1228 if (OutputMdlLocked)
1229 MmUnlockPages(OutputMdl);
1230 IoFreeMdl(OutputMdl);
1231 }
1232
1233 ExFreePool(QueryContext);
1234 } else
1235 Status = STATUS_INSUFFICIENT_RESOURCES;
1236 } else
1237 Status = STATUS_INVALID_PARAMETER;
1238
1239 TI_DbgPrint(MIN_TRACE, ("Leaving. Status = (0x%X)\n", Status));
1240
1241 return Status;
1242 }
1243
1244
1245 NTSTATUS DispTdiSetInformationEx(
1246 PIRP Irp,
1247 PIO_STACK_LOCATION IrpSp)
1248 /*
1249 * FUNCTION: TDI SetInformationEx handler
1250 * ARGUMENTS:
1251 * Irp = Pointer to I/O request packet
1252 * IrpSp = Pointer to current stack location of Irp
1253 * RETURNS:
1254 * Status of operation
1255 */
1256 {
1257 PTRANSPORT_CONTEXT TranContext;
1258 PTCP_REQUEST_SET_INFORMATION_EX Info;
1259 TDI_REQUEST Request;
1260 TDI_STATUS Status;
1261 KIRQL OldIrql;
1262
1263 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
1264
1265 TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
1266 Info = (PTCP_REQUEST_SET_INFORMATION_EX)Irp->AssociatedIrp.SystemBuffer;
1267
1268 switch ((ULONG)IrpSp->FileObject->FsContext2) {
1269 case TDI_TRANSPORT_ADDRESS_FILE:
1270 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
1271 break;
1272
1273 case TDI_CONNECTION_FILE:
1274 Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
1275 break;
1276
1277 case TDI_CONTROL_CHANNEL_FILE:
1278 Request.Handle.ControlChannel = TranContext->Handle.ControlChannel;
1279 break;
1280
1281 default:
1282 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1283 Irp->IoStatus.Information = 0;
1284
1285 TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
1286
1287 return IRPFinish(Irp, STATUS_INVALID_PARAMETER);
1288 }
1289
1290 Status = DispPrepareIrpForCancel(TranContext, Irp, NULL);
1291 if (NT_SUCCESS(Status)) {
1292 Request.RequestNotifyObject = DispDataRequestComplete;
1293 Request.RequestContext = Irp;
1294
1295 Status = InfoTdiSetInformationEx(&Request, &Info->ID,
1296 &Info->Buffer, Info->BufferSize);
1297
1298 if (Status != STATUS_PENDING) {
1299 IoAcquireCancelSpinLock(&OldIrql);
1300 IoSetCancelRoutine(Irp, NULL);
1301 IoReleaseCancelSpinLock(OldIrql);
1302 }
1303 }
1304
1305 return Status;
1306 }
1307
1308 /* EOF */