- Removed prefix.c and the prefix list. Adapter and route netmasks are now
[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->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 NTSTATUS Status;
500
501 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
502
503 IrpSp = IoGetCurrentIrpStackLocation(Irp);
504
505 /* Get associated connection endpoint file object. Quit if none exists */
506
507 TranContext = IrpSp->FileObject->FsContext;
508 if (TranContext == NULL)
509 {
510 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
511 return STATUS_INVALID_CONNECTION;
512 }
513
514 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
515 if (Connection == NULL)
516 {
517 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
518 return STATUS_INVALID_CONNECTION;
519 }
520
521 Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
522
523 Status = TCPListen( Connection, 1024 /* BACKLOG */,
524 DispDataRequestComplete,
525 Irp );
526
527 return Status;
528 }
529
530
531 NTSTATUS DispTdiQueryInformation(
532 PDEVICE_OBJECT DeviceObject,
533 PIRP Irp)
534 /*
535 * FUNCTION: TDI_QUERY_INFORMATION handler
536 * ARGUMENTS:
537 * DeviceObject = Pointer to device object structure
538 * Irp = Pointer to an I/O request packet
539 * RETURNS:
540 * Status of operation
541 */
542 {
543 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters;
544 PTRANSPORT_CONTEXT TranContext;
545 PIO_STACK_LOCATION IrpSp;
546
547 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
548
549 IrpSp = IoGetCurrentIrpStackLocation(Irp);
550 Parameters = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters;
551
552 TranContext = IrpSp->FileObject->FsContext;
553 if (!TranContext) {
554 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
555 return STATUS_INVALID_CONNECTION;
556 }
557
558 switch (Parameters->QueryType)
559 {
560 case TDI_QUERY_ADDRESS_INFO:
561 {
562 PTDI_ADDRESS_INFO AddressInfo;
563 PADDRESS_FILE AddrFile;
564 PTA_IP_ADDRESS Address;
565
566 AddressInfo = (PTDI_ADDRESS_INFO)MmGetSystemAddressForMdl(Irp->MdlAddress);
567
568 switch ((ULONG)IrpSp->FileObject->FsContext2) {
569 case TDI_TRANSPORT_ADDRESS_FILE:
570 AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
571 break;
572
573 case TDI_CONNECTION_FILE:
574 AddrFile = ((PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext)->AddressFile;
575 break;
576
577 default:
578 TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
579 return STATUS_INVALID_PARAMETER;
580 }
581
582 if (!AddrFile) {
583 TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
584 return STATUS_INVALID_PARAMETER;
585 }
586
587 if (MmGetMdlByteCount(Irp->MdlAddress) <
588 (sizeof(TDI_ADDRESS_INFO) + sizeof(TDI_ADDRESS_IP))) {
589 TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n"));
590 return STATUS_BUFFER_OVERFLOW;
591 }
592
593 Address = (PTA_IP_ADDRESS)&AddressInfo->Address;
594 Address->TAAddressCount = 1;
595 Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
596 Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
597 Address->Address[0].Address[0].sin_port = AddrFile->Port;
598 Address->Address[0].Address[0].in_addr = AddrFile->Address.Address.IPv4Address;
599 RtlZeroMemory(
600 &Address->Address[0].Address[0].sin_zero,
601 sizeof(Address->Address[0].Address[0].sin_zero));
602
603 return STATUS_SUCCESS;
604 }
605 }
606
607 return STATUS_NOT_IMPLEMENTED;
608 }
609
610
611 NTSTATUS DispTdiReceive(
612 PIRP Irp)
613 /*
614 * FUNCTION: TDI_RECEIVE handler
615 * ARGUMENTS:
616 * Irp = Pointer to an I/O request packet
617 * RETURNS:
618 * Status of operation
619 */
620 {
621 PIO_STACK_LOCATION IrpSp;
622 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo;
623 PTRANSPORT_CONTEXT TranContext;
624 NTSTATUS Status;
625 ULONG BytesReceived;
626
627 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
628
629 IrpSp = IoGetCurrentIrpStackLocation(Irp);
630 ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters);
631
632 TranContext = IrpSp->FileObject->FsContext;
633 if (TranContext == NULL)
634 {
635 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
636 return STATUS_INVALID_CONNECTION;
637 }
638
639 if (TranContext->Handle.ConnectionContext == NULL)
640 {
641 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
642 return STATUS_INVALID_CONNECTION;
643 }
644
645 /* Initialize a receive request */
646 Status = DispPrepareIrpForCancel
647 (TranContext->Handle.ConnectionContext,
648 Irp,
649 (PDRIVER_CANCEL)TCPCancelReceiveRequest);
650
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 DispDataRequestComplete(Irp, Status, BytesReceived);
665 }
666 }
667
668 if (Status != STATUS_PENDING)
669 {
670 IrpSp->Control &= ~SL_PENDING_RETURNED;
671 }
672
673 TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
674
675 return Status;
676 }
677
678
679 NTSTATUS DispTdiReceiveDatagram(
680 PIRP Irp)
681 /*
682 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
683 * ARGUMENTS:
684 * Irp = Pointer to an I/O request packet
685 * RETURNS:
686 * Status of operation
687 */
688 {
689 PIO_STACK_LOCATION IrpSp;
690 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo;
691 PTRANSPORT_CONTEXT TranContext;
692 TDI_REQUEST Request;
693 NTSTATUS Status;
694 ULONG BytesReceived;
695
696 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
697
698 IrpSp = IoGetCurrentIrpStackLocation(Irp);
699 DgramInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&(IrpSp->Parameters);
700
701 TranContext = IrpSp->FileObject->FsContext;
702 if (TranContext == NULL)
703 {
704 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
705 return STATUS_INVALID_ADDRESS;
706 }
707
708 /* Initialize a receive request */
709 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
710 Request.RequestNotifyObject = DispDataRequestComplete;
711 Request.RequestContext = Irp;
712
713 Status = DispPrepareIrpForCancel(
714 IrpSp->FileObject->FsContext,
715 Irp,
716 (PDRIVER_CANCEL)DispCancelRequest);
717
718 if (NT_SUCCESS(Status))
719 {
720 PCHAR DataBuffer;
721 UINT BufferSize;
722
723 NdisQueryBuffer( (PNDIS_BUFFER)Irp->MdlAddress,
724 &DataBuffer,
725 &BufferSize );
726
727 Status = UDPReceiveDatagram(
728 Request.Handle.AddressHandle,
729 DgramInfo->ReceiveDatagramInformation->RemoteAddress,
730 DataBuffer,
731 DgramInfo->ReceiveLength,
732 DgramInfo->ReceiveFlags,
733 DgramInfo->ReturnDatagramInformation->RemoteAddress,
734 &BytesReceived,
735 (PDATAGRAM_COMPLETION_ROUTINE)DispDataRequestComplete,
736 Irp);
737 if (Status != STATUS_PENDING)
738 {
739 DispDataRequestComplete(Irp, Status, BytesReceived);
740 }
741 }
742
743 if (Status != STATUS_PENDING)
744 {
745 IrpSp->Control &= ~SL_PENDING_RETURNED;
746 }
747
748 TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
749
750 return Status;
751 }
752
753
754 NTSTATUS DispTdiSend(
755 PIRP Irp)
756 /*
757 * FUNCTION: TDI_SEND handler
758 * ARGUMENTS:
759 * Irp = Pointer to an I/O request packet
760 * RETURNS:
761 * Status of operation
762 */
763 {
764 PIO_STACK_LOCATION IrpSp;
765 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo;
766 PTRANSPORT_CONTEXT TranContext;
767 NTSTATUS Status;
768 ULONG BytesReceived;
769
770 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
771
772 IrpSp = IoGetCurrentIrpStackLocation(Irp);
773 ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters);
774
775 TranContext = IrpSp->FileObject->FsContext;
776 if (TranContext == NULL)
777 {
778 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
779 return STATUS_INVALID_CONNECTION;
780 }
781
782 if (TranContext->Handle.ConnectionContext == NULL)
783 {
784 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
785 return STATUS_INVALID_CONNECTION;
786 }
787
788 Status = DispPrepareIrpForCancel(
789 IrpSp->FileObject->FsContext,
790 Irp,
791 (PDRIVER_CANCEL)DispCancelRequest);
792
793 TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress));
794 if (NT_SUCCESS(Status))
795 {
796 PCHAR Data;
797 UINT Len;
798
799 NdisQueryBuffer( Irp->MdlAddress, &Data, &Len );
800
801 TI_DbgPrint(MID_TRACE,("About to TCPSendData\n"));
802 Status = TCPSendData(
803 TranContext->Handle.ConnectionContext,
804 Data,
805 ReceiveInfo->ReceiveLength,
806 &BytesReceived,
807 ReceiveInfo->ReceiveFlags);
808 if (Status != STATUS_PENDING)
809 {
810 DispDataRequestComplete(Irp, Status, BytesReceived);
811 }
812 }
813
814 if (Status != STATUS_PENDING)
815 {
816 IrpSp->Control &= ~SL_PENDING_RETURNED;
817 }
818
819 TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
820
821 return Status;
822 }
823
824
825 NTSTATUS DispTdiSendDatagram(
826 PIRP Irp)
827 /*
828 * FUNCTION: TDI_SEND_DATAGRAM handler
829 * ARGUMENTS:
830 * Irp = Pointer to an I/O request packet
831 * RETURNS:
832 * Status of operation
833 */
834 {
835 PIO_STACK_LOCATION IrpSp;
836 TDI_REQUEST Request;
837 PTDI_REQUEST_KERNEL_SENDDG DgramInfo;
838 PTRANSPORT_CONTEXT TranContext;
839 NTSTATUS Status;
840
841 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
842
843 IrpSp = IoGetCurrentIrpStackLocation(Irp);
844 DgramInfo = (PTDI_REQUEST_KERNEL_SENDDG)&(IrpSp->Parameters);
845 TranContext = IrpSp->FileObject->FsContext;
846
847 /* Initialize a send request */
848 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
849 Request.RequestNotifyObject = DispDataRequestComplete;
850 Request.RequestContext = Irp;
851
852 Status = DispPrepareIrpForCancel(
853 IrpSp->FileObject->FsContext,
854 Irp,
855 (PDRIVER_CANCEL)DispCancelRequest);
856
857 if (NT_SUCCESS(Status)) {
858 PCHAR DataBuffer;
859 UINT BufferSize;
860
861 TI_DbgPrint(MID_TRACE,("About to query buffer %x\n", Irp->MdlAddress));
862
863 NdisQueryBuffer( (PNDIS_BUFFER)Irp->MdlAddress,
864 &DataBuffer,
865 &BufferSize );
866
867 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
868 must be of type PTDI_ADDRESS_IP */
869 TI_DbgPrint(MID_TRACE,
870 ("About to call send routine %x\n",
871 (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)));
872
873 Status = (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)(
874 Request.Handle.AddressHandle,
875 DgramInfo->SendDatagramInformation,
876 DataBuffer,
877 BufferSize,
878 &Irp->IoStatus.Information);
879
880 if (Status != STATUS_PENDING) {
881 DispDataRequestComplete(Irp, Status, Irp->IoStatus.Information);
882 /* Return STATUS_PENDING because DispPrepareIrpForCancel
883 marks Irp as pending */
884 Status = STATUS_PENDING;
885 }
886 }
887
888 TI_DbgPrint(DEBUG_IRP, ("Leaving.\n"));
889
890 return Status;
891 }
892
893
894 NTSTATUS DispTdiSetEventHandler(PIRP Irp)
895 /*
896 * FUNCTION: TDI_SET_EVENT_HANDER handler
897 * ARGUMENTS:
898 * Irp = Pointer to a I/O request packet
899 * RETURNS:
900 * Status of operation
901 */
902 {
903 PTDI_REQUEST_KERNEL_SET_EVENT Parameters;
904 PTRANSPORT_CONTEXT TranContext;
905 PIO_STACK_LOCATION IrpSp;
906 PADDRESS_FILE AddrFile;
907 NTSTATUS Status;
908 KIRQL OldIrql;
909
910 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
911
912 IrpSp = IoGetCurrentIrpStackLocation(Irp);
913
914 /* Get associated address file object. Quit if none exists */
915
916 TranContext = IrpSp->FileObject->FsContext;
917 if (!TranContext) {
918 TI_DbgPrint(MIN_TRACE, ("Bad transport context.\n"));
919 return STATUS_INVALID_PARAMETER;
920 }
921
922 AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
923 if (!AddrFile) {
924 TI_DbgPrint(MIN_TRACE, ("No address file object.\n"));
925 return STATUS_INVALID_PARAMETER;
926 }
927
928 Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
929 Status = STATUS_SUCCESS;
930
931 TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
932
933 /* Set the event handler. if an event handler is associated with
934 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
935 If an event handler is not used it's flag is FALSE */
936 switch (Parameters->EventType) {
937 case TDI_EVENT_CONNECT:
938 if (!Parameters->EventHandler) {
939 AddrFile->ConnectHandlerContext = NULL;
940 AddrFile->RegisteredConnectHandler = FALSE;
941 } else {
942 AddrFile->ConnectHandler =
943 (PTDI_IND_CONNECT)Parameters->EventHandler;
944 AddrFile->ConnectHandlerContext = Parameters->EventContext;
945 AddrFile->RegisteredConnectHandler = TRUE;
946 }
947 break;
948
949 case TDI_EVENT_DISCONNECT:
950 if (!Parameters->EventHandler) {
951 AddrFile->DisconnectHandlerContext = NULL;
952 AddrFile->RegisteredDisconnectHandler = FALSE;
953 } else {
954 AddrFile->DisconnectHandler =
955 (PTDI_IND_DISCONNECT)Parameters->EventHandler;
956 AddrFile->DisconnectHandlerContext = Parameters->EventContext;
957 AddrFile->RegisteredDisconnectHandler = TRUE;
958 }
959 break;
960
961 case TDI_EVENT_ERROR:
962 if (Parameters->EventHandler == NULL) {
963 AddrFile->ErrorHandlerContext = NULL;
964 AddrFile->RegisteredErrorHandler = FALSE;
965 } else {
966 AddrFile->ErrorHandler =
967 (PTDI_IND_ERROR)Parameters->EventHandler;
968 AddrFile->ErrorHandlerContext = Parameters->EventContext;
969 AddrFile->RegisteredErrorHandler = TRUE;
970 }
971 break;
972
973 case TDI_EVENT_RECEIVE:
974 if (Parameters->EventHandler == NULL) {
975 AddrFile->ReceiveHandlerContext = NULL;
976 AddrFile->RegisteredReceiveHandler = FALSE;
977 } else {
978 AddrFile->ReceiveHandler =
979 (PTDI_IND_RECEIVE)Parameters->EventHandler;
980 AddrFile->ReceiveHandlerContext = Parameters->EventContext;
981 AddrFile->RegisteredReceiveHandler = TRUE;
982 }
983 break;
984
985 case TDI_EVENT_RECEIVE_DATAGRAM:
986 if (Parameters->EventHandler == NULL) {
987 AddrFile->ReceiveDatagramHandlerContext = NULL;
988 AddrFile->RegisteredReceiveDatagramHandler = FALSE;
989 } else {
990 AddrFile->ReceiveDatagramHandler =
991 (PTDI_IND_RECEIVE_DATAGRAM)Parameters->EventHandler;
992 AddrFile->ReceiveDatagramHandlerContext = Parameters->EventContext;
993 AddrFile->RegisteredReceiveDatagramHandler = TRUE;
994 }
995 break;
996
997 case TDI_EVENT_RECEIVE_EXPEDITED:
998 if (Parameters->EventHandler == NULL) {
999 AddrFile->ExpeditedReceiveHandlerContext = NULL;
1000 AddrFile->RegisteredExpeditedReceiveHandler = FALSE;
1001 } else {
1002 AddrFile->ExpeditedReceiveHandler =
1003 (PTDI_IND_RECEIVE_EXPEDITED)Parameters->EventHandler;
1004 AddrFile->ExpeditedReceiveHandlerContext = Parameters->EventContext;
1005 AddrFile->RegisteredExpeditedReceiveHandler = TRUE;
1006 }
1007 break;
1008
1009 case TDI_EVENT_CHAINED_RECEIVE:
1010 if (Parameters->EventHandler == NULL) {
1011 AddrFile->ChainedReceiveHandlerContext = NULL;
1012 AddrFile->RegisteredChainedReceiveHandler = FALSE;
1013 } else {
1014 AddrFile->ChainedReceiveHandler =
1015 (PTDI_IND_CHAINED_RECEIVE)Parameters->EventHandler;
1016 AddrFile->ChainedReceiveHandlerContext = Parameters->EventContext;
1017 AddrFile->RegisteredChainedReceiveHandler = TRUE;
1018 }
1019 break;
1020
1021 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM:
1022 if (Parameters->EventHandler == NULL) {
1023 AddrFile->ChainedReceiveDatagramHandlerContext = NULL;
1024 AddrFile->RegisteredChainedReceiveDatagramHandler = FALSE;
1025 } else {
1026 AddrFile->ChainedReceiveDatagramHandler =
1027 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM)Parameters->EventHandler;
1028 AddrFile->ChainedReceiveDatagramHandlerContext = Parameters->EventContext;
1029 AddrFile->RegisteredChainedReceiveDatagramHandler = TRUE;
1030 }
1031 break;
1032
1033 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED:
1034 if (Parameters->EventHandler == NULL) {
1035 AddrFile->ChainedReceiveExpeditedHandlerContext = NULL;
1036 AddrFile->RegisteredChainedReceiveExpeditedHandler = FALSE;
1037 } else {
1038 AddrFile->ChainedReceiveExpeditedHandler =
1039 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED)Parameters->EventHandler;
1040 AddrFile->ChainedReceiveExpeditedHandlerContext = Parameters->EventContext;
1041 AddrFile->RegisteredChainedReceiveExpeditedHandler = TRUE;
1042 }
1043 break;
1044
1045 default:
1046 TI_DbgPrint(MIN_TRACE, ("Unknown event type (0x%X).\n",
1047 Parameters->EventType));
1048
1049 Status = STATUS_INVALID_PARAMETER;
1050 }
1051
1052 TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
1053
1054 return Status;
1055 }
1056
1057
1058 NTSTATUS DispTdiSetInformation(
1059 PIRP Irp)
1060 /*
1061 * FUNCTION: TDI_SET_INFORMATION handler
1062 * ARGUMENTS:
1063 * Irp = Pointer to an I/O request packet
1064 * RETURNS:
1065 * Status of operation
1066 */
1067 {
1068 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
1069
1070 return STATUS_NOT_IMPLEMENTED;
1071 }
1072
1073
1074 VOID DispTdiQueryInformationExComplete(
1075 PVOID Context,
1076 ULONG Status,
1077 UINT ByteCount)
1078 /*
1079 * FUNCTION: Completes a TDI QueryInformationEx request
1080 * ARGUMENTS:
1081 * Context = Pointer to the IRP for the request
1082 * Status = TDI status of the request
1083 * ByteCount = Number of bytes returned in output buffer
1084 */
1085 {
1086 PTI_QUERY_CONTEXT QueryContext;
1087 UINT Count = 0;
1088
1089 QueryContext = (PTI_QUERY_CONTEXT)Context;
1090 if (NT_SUCCESS(Status)) {
1091 Count = CopyBufferToBufferChain(
1092 QueryContext->InputMdl,
1093 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX, Context),
1094 (PUCHAR)&QueryContext->QueryInfo.Context,
1095 CONTEXT_SIZE);
1096 }
1097
1098 MmUnlockPages(QueryContext->InputMdl);
1099 IoFreeMdl(QueryContext->InputMdl);
1100 if( QueryContext->OutputMdl ) {
1101 MmUnlockPages(QueryContext->OutputMdl);
1102 IoFreeMdl(QueryContext->OutputMdl);
1103 }
1104
1105 QueryContext->Irp->IoStatus.Information = ByteCount;
1106 QueryContext->Irp->IoStatus.Status = Status;
1107
1108 ExFreePool(QueryContext);
1109 }
1110
1111
1112 NTSTATUS DispTdiQueryInformationEx(
1113 PIRP Irp,
1114 PIO_STACK_LOCATION IrpSp)
1115 /*
1116 * FUNCTION: TDI QueryInformationEx handler
1117 * ARGUMENTS:
1118 * Irp = Pointer to I/O request packet
1119 * IrpSp = Pointer to current stack location of Irp
1120 * RETURNS:
1121 * Status of operation
1122 */
1123 {
1124 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer;
1125 PTRANSPORT_CONTEXT TranContext;
1126 PTI_QUERY_CONTEXT QueryContext;
1127 PVOID OutputBuffer;
1128 TDI_REQUEST Request;
1129 UINT Size;
1130 UINT InputBufferLength;
1131 UINT OutputBufferLength;
1132 BOOLEAN InputMdlLocked = FALSE;
1133 BOOLEAN OutputMdlLocked = FALSE;
1134 PMDL InputMdl = NULL;
1135 PMDL OutputMdl = NULL;
1136 NTSTATUS Status = STATUS_SUCCESS;
1137
1138 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
1139
1140 TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
1141
1142 switch ((ULONG)IrpSp->FileObject->FsContext2) {
1143 case TDI_TRANSPORT_ADDRESS_FILE:
1144 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
1145 break;
1146
1147 case TDI_CONNECTION_FILE:
1148 Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
1149 break;
1150
1151 case TDI_CONTROL_CHANNEL_FILE:
1152 Request.Handle.ControlChannel = TranContext->Handle.ControlChannel;
1153 break;
1154
1155 default:
1156 TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
1157 return STATUS_INVALID_PARAMETER;
1158 }
1159
1160 InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
1161 OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
1162
1163 /* Validate parameters */
1164 if ((InputBufferLength == sizeof(TCP_REQUEST_QUERY_INFORMATION_EX)) &&
1165 (OutputBufferLength != 0)) {
1166
1167 InputBuffer = (PTCP_REQUEST_QUERY_INFORMATION_EX)
1168 IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
1169 OutputBuffer = Irp->UserBuffer;
1170
1171 QueryContext = ExAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT));
1172 if (QueryContext) {
1173 _SEH_TRY {
1174 InputMdl = IoAllocateMdl(InputBuffer,
1175 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX),
1176 FALSE, TRUE, NULL);
1177
1178 OutputMdl = IoAllocateMdl(OutputBuffer,
1179 OutputBufferLength, FALSE, TRUE, NULL);
1180
1181 if (InputMdl && OutputMdl) {
1182
1183 MmProbeAndLockPages(InputMdl, Irp->RequestorMode,
1184 IoModifyAccess);
1185
1186 InputMdlLocked = TRUE;
1187
1188 MmProbeAndLockPages(OutputMdl, Irp->RequestorMode,
1189 IoWriteAccess);
1190
1191 OutputMdlLocked = TRUE;
1192
1193 RtlCopyMemory(&QueryContext->QueryInfo,
1194 InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
1195 } else
1196 Status = STATUS_INSUFFICIENT_RESOURCES;
1197 } _SEH_HANDLE {
1198 Status = _SEH_GetExceptionCode();
1199 } _SEH_END;
1200
1201 if (NT_SUCCESS(Status)) {
1202 Size = MmGetMdlByteCount(OutputMdl);
1203
1204 QueryContext->Irp = Irp;
1205 QueryContext->InputMdl = InputMdl;
1206 QueryContext->OutputMdl = OutputMdl;
1207
1208 Request.RequestNotifyObject = DispTdiQueryInformationExComplete;
1209 Request.RequestContext = QueryContext;
1210 Status = InfoTdiQueryInformationEx(&Request,
1211 &QueryContext->QueryInfo.ID, OutputMdl,
1212 &Size, &QueryContext->QueryInfo.Context);
1213 DispTdiQueryInformationExComplete(QueryContext, Status, Size);
1214
1215 TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status));
1216
1217 return Status;
1218 }
1219
1220 /* An error occurred if we get here */
1221
1222 if (InputMdl) {
1223 if (InputMdlLocked)
1224 MmUnlockPages(InputMdl);
1225 IoFreeMdl(InputMdl);
1226 }
1227
1228 if (OutputMdl) {
1229 if (OutputMdlLocked)
1230 MmUnlockPages(OutputMdl);
1231 IoFreeMdl(OutputMdl);
1232 }
1233
1234 ExFreePool(QueryContext);
1235 } else
1236 Status = STATUS_INSUFFICIENT_RESOURCES;
1237 } else if( InputBufferLength ==
1238 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX) ) {
1239 /* Handle the case where the user is probing the buffer for length */
1240 TI_DbgPrint(MAX_TRACE, ("InputBufferLength %d OutputBufferLength %d\n",
1241 InputBufferLength, OutputBufferLength));
1242 InputBuffer = (PTCP_REQUEST_QUERY_INFORMATION_EX)
1243 IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
1244
1245 Size = 0;
1246
1247 QueryContext = ExAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT));
1248 if (!QueryContext) return STATUS_INSUFFICIENT_RESOURCES;
1249
1250 _SEH_TRY {
1251 InputMdl = IoAllocateMdl(InputBuffer,
1252 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX),
1253 FALSE, TRUE, NULL);
1254
1255 MmProbeAndLockPages(InputMdl, Irp->RequestorMode,
1256 IoModifyAccess);
1257
1258 InputMdlLocked = TRUE;
1259 Status = STATUS_SUCCESS;
1260 } _SEH_HANDLE {
1261 TI_DbgPrint(MAX_TRACE, ("Failed to acquire client buffer\n"));
1262 Status = _SEH_GetExceptionCode();
1263 } _SEH_END;
1264
1265 if( !NT_SUCCESS(Status) || !InputMdl ) {
1266 if( InputMdl ) IoFreeMdl( InputMdl );
1267 ExFreePool(QueryContext);
1268 return Status;
1269 }
1270
1271 RtlCopyMemory(&QueryContext->QueryInfo,
1272 InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
1273
1274 QueryContext->Irp = Irp;
1275 QueryContext->InputMdl = InputMdl;
1276 QueryContext->OutputMdl = NULL;
1277
1278 Request.RequestNotifyObject = DispTdiQueryInformationExComplete;
1279 Request.RequestContext = QueryContext;
1280 Status = InfoTdiQueryInformationEx(&Request,
1281 &QueryContext->QueryInfo.ID,
1282 NULL,
1283 &Size,
1284 &QueryContext->QueryInfo.Context);
1285 DispTdiQueryInformationExComplete(QueryContext, Status, Size);
1286 TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status));
1287 } else Status = STATUS_INVALID_PARAMETER;
1288
1289 TI_DbgPrint(MIN_TRACE, ("Leaving. Status = (0x%X)\n", Status));
1290
1291 return Status;
1292 }
1293
1294
1295 NTSTATUS DispTdiSetInformationEx(
1296 PIRP Irp,
1297 PIO_STACK_LOCATION IrpSp)
1298 /*
1299 * FUNCTION: TDI SetInformationEx handler
1300 * ARGUMENTS:
1301 * Irp = Pointer to I/O request packet
1302 * IrpSp = Pointer to current stack location of Irp
1303 * RETURNS:
1304 * Status of operation
1305 */
1306 {
1307 PTRANSPORT_CONTEXT TranContext;
1308 PTCP_REQUEST_SET_INFORMATION_EX Info;
1309 TDI_REQUEST Request;
1310 TDI_STATUS Status;
1311 KIRQL OldIrql;
1312
1313 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
1314
1315 TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
1316 Info = (PTCP_REQUEST_SET_INFORMATION_EX)Irp->AssociatedIrp.SystemBuffer;
1317
1318 switch ((ULONG)IrpSp->FileObject->FsContext2) {
1319 case TDI_TRANSPORT_ADDRESS_FILE:
1320 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
1321 break;
1322
1323 case TDI_CONNECTION_FILE:
1324 Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
1325 break;
1326
1327 case TDI_CONTROL_CHANNEL_FILE:
1328 Request.Handle.ControlChannel = TranContext->Handle.ControlChannel;
1329 break;
1330
1331 default:
1332 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1333 Irp->IoStatus.Information = 0;
1334
1335 TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
1336
1337 return IRPFinish(Irp, STATUS_INVALID_PARAMETER);
1338 }
1339
1340 Status = DispPrepareIrpForCancel(TranContext, Irp, NULL);
1341 if (NT_SUCCESS(Status)) {
1342 Request.RequestNotifyObject = DispDataRequestComplete;
1343 Request.RequestContext = Irp;
1344
1345 Status = InfoTdiSetInformationEx(&Request, &Info->ID,
1346 &Info->Buffer, Info->BufferSize);
1347
1348 if (Status != STATUS_PENDING) {
1349 IoAcquireCancelSpinLock(&OldIrql);
1350 IoSetCancelRoutine(Irp, NULL);
1351 IoReleaseCancelSpinLock(OldIrql);
1352 }
1353 }
1354
1355 return Status;
1356 }
1357
1358 /* EOF */