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