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