Delete all Trailing spaces in code.
[reactos.git] / reactos / drivers / network / 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/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 (void)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 DispDataRequestComplete(
86 PVOID Context,
87 NTSTATUS Status,
88 ULONG Count)
89 /*
90 * FUNCTION: Completes a send/receive IRP
91 * ARGUMENTS:
92 * Context = Pointer to context information (IRP)
93 * Status = Status of the request
94 * Count = Number of bytes sent or received
95 */
96 {
97 PIRP Irp;
98 PIO_STACK_LOCATION IrpSp;
99 PTRANSPORT_CONTEXT TranContext;
100 KIRQL OldIrql;
101
102 TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n",
103 Context, Status, Count));
104
105 Irp = Context;
106 IrpSp = IoGetCurrentIrpStackLocation(Irp);
107 TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
108
109 IoAcquireCancelSpinLock(&OldIrql);
110
111 (void)IoSetCancelRoutine(Irp, NULL);
112
113 if (Irp->Cancel || TranContext->CancelIrps) {
114 /* The IRP has been cancelled */
115
116 TI_DbgPrint(DEBUG_IRP, ("IRP is cancelled.\n"));
117
118 Status = STATUS_CANCELLED;
119 Count = 0;
120 }
121
122 IoReleaseCancelSpinLock(OldIrql);
123
124 Irp->IoStatus.Status = Status;
125 Irp->IoStatus.Information = Count;
126
127 TI_DbgPrint(MID_TRACE, ("Irp->IoStatus.Status = %x\n",
128 Irp->IoStatus.Status));
129 TI_DbgPrint(MID_TRACE, ("Irp->IoStatus.Information = %d\n",
130 Irp->IoStatus.Information));
131 TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
132
133 IRPFinish(Irp, Irp->IoStatus.Status);
134
135 TI_DbgPrint(DEBUG_IRP, ("Done Completing IRP\n"));
136 }
137
138 typedef struct _DISCONNECT_TYPE {
139 UINT Type;
140 PVOID Context;
141 PIRP Irp;
142 PFILE_OBJECT FileObject;
143 } DISCONNECT_TYPE, *PDISCONNECT_TYPE;
144
145 VOID DispDoDisconnect( PVOID Data ) {
146 PDISCONNECT_TYPE DisType = (PDISCONNECT_TYPE)Data;
147
148 TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect\n"));
149 TCPDisconnect
150 ( DisType->Context,
151 DisType->Type,
152 NULL,
153 NULL,
154 DispDataRequestComplete,
155 DisType->Irp );
156 TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect done\n"));
157
158 DispDataRequestComplete(DisType->Irp, STATUS_CANCELLED, 0);
159
160 DispCancelComplete(DisType->FileObject);
161 }
162
163 VOID NTAPI DispCancelRequest(
164 PDEVICE_OBJECT Device,
165 PIRP Irp)
166 /*
167 * FUNCTION: Cancels an IRP
168 * ARGUMENTS:
169 * Device = Pointer to device object
170 * Irp = Pointer to an I/O request packet
171 */
172 {
173 PIO_STACK_LOCATION IrpSp;
174 PTRANSPORT_CONTEXT TranContext;
175 PFILE_OBJECT FileObject;
176 UCHAR MinorFunction;
177 DISCONNECT_TYPE DisType;
178 PVOID WorkItem;
179 /*NTSTATUS Status = STATUS_SUCCESS;*/
180
181 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
182
183 IrpSp = IoGetCurrentIrpStackLocation(Irp);
184 FileObject = IrpSp->FileObject;
185 TranContext = (PTRANSPORT_CONTEXT)FileObject->FsContext;
186 MinorFunction = IrpSp->MinorFunction;
187
188 TI_DbgPrint(DEBUG_IRP, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp, MinorFunction, IrpSp));
189
190 Irp->IoStatus.Status = STATUS_PENDING;
191
192 #ifdef DBG
193 if (!Irp->Cancel)
194 TI_DbgPrint(MIN_TRACE, ("Irp->Cancel is FALSE, should be TRUE.\n"));
195 #endif
196
197 /* Try canceling the request */
198 switch(MinorFunction) {
199 case TDI_SEND:
200 case TDI_RECEIVE:
201 DisType.Type = TDI_DISCONNECT_RELEASE |
202 ((MinorFunction == TDI_RECEIVE) ? TDI_DISCONNECT_ABORT : 0);
203 DisType.Context = TranContext->Handle.ConnectionContext;
204 DisType.Irp = Irp;
205 DisType.FileObject = FileObject;
206
207 TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
208
209 if( !ChewCreate( &WorkItem, sizeof(DISCONNECT_TYPE),
210 DispDoDisconnect, &DisType ) )
211 ASSERT(0);
212 break;
213
214 case TDI_SEND_DATAGRAM:
215 Irp->IoStatus.Status = STATUS_CANCELLED;
216 if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
217 TI_DbgPrint(MIN_TRACE, ("TDI_SEND_DATAGRAM, but no address file.\n"));
218 break;
219 }
220
221 /*DGCancelSendRequest(TranContext->Handle.AddressHandle, Irp);*/
222 break;
223
224 case TDI_RECEIVE_DATAGRAM:
225 Irp->IoStatus.Status = STATUS_CANCELLED;
226 if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
227 TI_DbgPrint(MIN_TRACE, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
228 break;
229 }
230
231 /*DGCancelReceiveRequest(TranContext->Handle.AddressHandle, Irp);*/
232 break;
233
234 default:
235 TI_DbgPrint(MIN_TRACE, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction));
236 break;
237 }
238
239 if( Irp->IoStatus.Status == STATUS_PENDING )
240 IoMarkIrpPending(Irp);
241
242 IoReleaseCancelSpinLock(Irp->CancelIrql);
243
244 TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
245 }
246
247
248 VOID NTAPI DispCancelListenRequest(
249 PDEVICE_OBJECT Device,
250 PIRP Irp)
251 /*
252 * FUNCTION: Cancels a listen IRP
253 * ARGUMENTS:
254 * Device = Pointer to device object
255 * Irp = Pointer to an I/O request packet
256 */
257 {
258 PIO_STACK_LOCATION IrpSp;
259 PTRANSPORT_CONTEXT TranContext;
260 PFILE_OBJECT FileObject;
261 PCONNECTION_ENDPOINT Connection;
262 /*NTSTATUS Status = STATUS_SUCCESS;*/
263
264 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
265
266 IrpSp = IoGetCurrentIrpStackLocation(Irp);
267 FileObject = IrpSp->FileObject;
268 TranContext = (PTRANSPORT_CONTEXT)FileObject->FsContext;
269 ASSERT( TDI_LISTEN == IrpSp->MinorFunction);
270
271 TI_DbgPrint(DEBUG_IRP, ("IRP at (0x%X).\n", Irp));
272
273 #ifdef DBG
274 if (!Irp->Cancel)
275 TI_DbgPrint(MIN_TRACE, ("Irp->Cancel is FALSE, should be TRUE.\n"));
276 #endif
277
278 /* Try canceling the request */
279 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
280 TCPAbortListenForSocket(
281 Connection->AddressFile->Listener,
282 Connection );
283
284 IoReleaseCancelSpinLock(Irp->CancelIrql);
285
286 DispDataRequestComplete(Irp, STATUS_CANCELLED, 0);
287
288 DispCancelComplete(FileObject);
289
290 TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
291 }
292
293
294 NTSTATUS DispTdiAccept(
295 PIRP Irp)
296 /*
297 * FUNCTION: TDI_ACCEPT handler
298 * ARGUMENTS:
299 * Irp = Pointer to an I/O request packet
300 * RETURNS:
301 * Status of operation
302 */
303 {
304 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
305
306 return STATUS_NOT_IMPLEMENTED;
307 }
308
309
310 NTSTATUS DispTdiAssociateAddress(
311 PIRP Irp)
312 /*
313 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
314 * ARGUMENTS:
315 * Irp = Pointer to an I/O request packet
316 * RETURNS:
317 * Status of operation
318 */
319 {
320 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters;
321 PTRANSPORT_CONTEXT TranContext;
322 PIO_STACK_LOCATION IrpSp;
323 PCONNECTION_ENDPOINT Connection;
324 PFILE_OBJECT FileObject;
325 PADDRESS_FILE AddrFile = NULL;
326 NTSTATUS Status;
327
328 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
329
330 IrpSp = IoGetCurrentIrpStackLocation(Irp);
331
332 /* Get associated connection endpoint file object. Quit if none exists */
333
334 TranContext = IrpSp->FileObject->FsContext;
335 if (!TranContext) {
336 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
337 return STATUS_INVALID_PARAMETER;
338 }
339
340 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
341 if (!Connection) {
342 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
343 return STATUS_INVALID_PARAMETER;
344 }
345
346 if (Connection->AddressFile) {
347 TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n"));
348 return STATUS_INVALID_PARAMETER;
349 }
350
351 Parameters = (PTDI_REQUEST_KERNEL_ASSOCIATE)&IrpSp->Parameters;
352
353 Status = ObReferenceObjectByHandle(
354 Parameters->AddressHandle,
355 0,
356 IoFileObjectType,
357 KernelMode,
358 (PVOID*)&FileObject,
359 NULL);
360 if (!NT_SUCCESS(Status)) {
361 TI_DbgPrint(MID_TRACE, ("Bad address file object handle (0x%X): %x.\n",
362 Parameters->AddressHandle, Status));
363 return STATUS_INVALID_PARAMETER;
364 }
365
366 if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
367 ObDereferenceObject(FileObject);
368 TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n",
369 FileObject->FsContext2));
370 return STATUS_INVALID_PARAMETER;
371 }
372
373 /* Get associated address file object. Quit if none exists */
374
375 TranContext = FileObject->FsContext;
376 if (!TranContext) {
377 ObDereferenceObject(FileObject);
378 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
379 return STATUS_INVALID_PARAMETER;
380 }
381
382 AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
383 if (!AddrFile) {
384 ObDereferenceObject(FileObject);
385 TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
386 return STATUS_INVALID_PARAMETER;
387 }
388
389 Connection->AddressFile = AddrFile;
390
391 /* Add connection endpoint to the address file */
392 AddrFile->Connection = Connection;
393
394 /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
395 ObDereferenceObject(FileObject);
396
397 return Status;
398 }
399
400
401 NTSTATUS DispTdiConnect(
402 PIRP Irp)
403 /*
404 * FUNCTION: TDI_CONNECT handler
405 * ARGUMENTS:
406 * Irp = Pointer to an I/O request packet
407 * RETURNS:
408 * Status of operation
409 */
410 {
411 PCONNECTION_ENDPOINT Connection;
412 PTDI_REQUEST_KERNEL Parameters;
413 PTRANSPORT_CONTEXT TranContext;
414 PIO_STACK_LOCATION IrpSp;
415 NTSTATUS Status;
416
417 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
418
419 IrpSp = IoGetCurrentIrpStackLocation(Irp);
420
421 /* Get associated connection endpoint file object. Quit if none exists */
422
423 TranContext = IrpSp->FileObject->FsContext;
424 if (!TranContext) {
425 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
426 return STATUS_INVALID_CONNECTION;
427 }
428
429 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
430 if (!Connection) {
431 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
432 return STATUS_INVALID_CONNECTION;
433 }
434
435 Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
436
437 Status = TCPConnect(
438 TranContext->Handle.ConnectionContext,
439 Parameters->RequestConnectionInformation,
440 Parameters->ReturnConnectionInformation,
441 DispDataRequestComplete,
442 Irp );
443
444 TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status));
445
446 return Status;
447 }
448
449
450 NTSTATUS DispTdiDisassociateAddress(
451 PIRP Irp)
452 /*
453 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
454 * ARGUMENTS:
455 * Irp = Pointer to an I/O request packet
456 * RETURNS:
457 * Status of operation
458 */
459 {
460 PCONNECTION_ENDPOINT Connection;
461 PTRANSPORT_CONTEXT TranContext;
462 PIO_STACK_LOCATION IrpSp;
463
464 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
465
466 IrpSp = IoGetCurrentIrpStackLocation(Irp);
467
468 /* Get associated connection endpoint file object. Quit if none exists */
469
470 TranContext = IrpSp->FileObject->FsContext;
471 if (!TranContext) {
472 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
473 return STATUS_INVALID_PARAMETER;
474 }
475
476 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
477 if (!Connection) {
478 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
479 return STATUS_INVALID_PARAMETER;
480 }
481
482 if (!Connection->AddressFile) {
483 TI_DbgPrint(MID_TRACE, ("No address file is asscociated.\n"));
484 return STATUS_INVALID_PARAMETER;
485 }
486
487 return STATUS_SUCCESS;
488 }
489
490
491 NTSTATUS DispTdiDisconnect(
492 PIRP Irp)
493 /*
494 * FUNCTION: TDI_DISCONNECT handler
495 * ARGUMENTS:
496 * Irp = Pointer to an I/O request packet
497 * RETURNS:
498 * Status of operation
499 */
500 {
501 NTSTATUS Status;
502 PTDI_REQUEST_KERNEL_DISCONNECT DisReq;
503 PCONNECTION_ENDPOINT Connection;
504 PTRANSPORT_CONTEXT TranContext;
505 PIO_STACK_LOCATION IrpSp;
506
507 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
508
509 IrpSp = IoGetCurrentIrpStackLocation(Irp);
510 DisReq = (PTDI_REQUEST_KERNEL_DISCONNECT)&IrpSp->Parameters;
511
512 /* Get associated connection endpoint file object. Quit if none exists */
513
514 TranContext = IrpSp->FileObject->FsContext;
515 if (!TranContext) {
516 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
517 return STATUS_INVALID_CONNECTION;
518 }
519
520 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
521 if (!Connection) {
522 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
523 return STATUS_INVALID_CONNECTION;
524 }
525
526 Status = TCPDisconnect(
527 TranContext->Handle.ConnectionContext,
528 DisReq->RequestFlags,
529 DisReq->RequestConnectionInformation,
530 DisReq->ReturnConnectionInformation,
531 DispDataRequestComplete,
532 Irp );
533
534 TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status));
535
536 return Status;
537 }
538
539
540 NTSTATUS DispTdiListen(
541 PIRP Irp)
542 /*
543 * FUNCTION: TDI_LISTEN handler
544 * ARGUMENTS:
545 * Irp = Pointer to an I/O request packet
546 * RETURNS:
547 * Status of operation
548 */
549 {
550 PCONNECTION_ENDPOINT Connection;
551 PTDI_REQUEST_KERNEL Parameters;
552 PTRANSPORT_CONTEXT TranContext;
553 PIO_STACK_LOCATION IrpSp;
554 NTSTATUS Status = STATUS_SUCCESS;
555
556 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
557
558 IrpSp = IoGetCurrentIrpStackLocation(Irp);
559
560 /* Get associated connection endpoint file object. Quit if none exists */
561
562 TranContext = IrpSp->FileObject->FsContext;
563 if (TranContext == NULL)
564 {
565 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
566 return STATUS_INVALID_CONNECTION;
567 }
568
569 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
570 if (Connection == NULL)
571 {
572 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
573 return STATUS_INVALID_CONNECTION;
574 }
575
576 Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
577
578 TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile: %x\n",
579 Connection->AddressFile ));
580 if( Connection->AddressFile ) {
581 TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile->Listener: %x\n",
582 Connection->AddressFile->Listener));
583 }
584
585 /* Listening will require us to create a listening socket and store it in
586 * the address file. It will be signalled, and attempt to complete an irp
587 * when a new connection arrives. */
588 /* The important thing to note here is that the irp we'll complete belongs
589 * to the socket to be accepted onto, not the listener */
590 if( !Connection->AddressFile->Listener ) {
591 Connection->AddressFile->Listener =
592 TCPAllocateConnectionEndpoint( NULL );
593
594 if( !Connection->AddressFile->Listener )
595 Status = STATUS_NO_MEMORY;
596
597 if( NT_SUCCESS(Status) ) {
598 Connection->AddressFile->Listener->AddressFile =
599 Connection->AddressFile;
600
601 Status = TCPSocket( Connection->AddressFile->Listener,
602 Connection->AddressFile->Family,
603 SOCK_STREAM,
604 Connection->AddressFile->Protocol );
605 }
606
607 if( NT_SUCCESS(Status) )
608 Status = TCPListen( Connection->AddressFile->Listener, 1024 );
609 /* BACKLOG */
610 }
611 if( NT_SUCCESS(Status) ) {
612 Status = DispPrepareIrpForCancel
613 (TranContext->Handle.ConnectionContext,
614 Irp,
615 (PDRIVER_CANCEL)DispCancelListenRequest);
616 }
617
618 if( NT_SUCCESS(Status) ) {
619 Status = TCPAccept
620 ( (PTDI_REQUEST)Parameters,
621 Connection->AddressFile->Listener,
622 Connection,
623 DispDataRequestComplete,
624 Irp );
625 }
626
627 TI_DbgPrint(MID_TRACE,("Leaving %x\n", Status));
628
629 return Status;
630 }
631
632
633 NTSTATUS DispTdiQueryInformation(
634 PDEVICE_OBJECT DeviceObject,
635 PIRP Irp)
636 /*
637 * FUNCTION: TDI_QUERY_INFORMATION handler
638 * ARGUMENTS:
639 * DeviceObject = Pointer to device object structure
640 * Irp = Pointer to an I/O request packet
641 * RETURNS:
642 * Status of operation
643 */
644 {
645 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters;
646 PTRANSPORT_CONTEXT TranContext;
647 PIO_STACK_LOCATION IrpSp;
648
649 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
650
651 IrpSp = IoGetCurrentIrpStackLocation(Irp);
652 Parameters = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters;
653
654 TranContext = IrpSp->FileObject->FsContext;
655 if (!TranContext) {
656 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
657 return STATUS_INVALID_CONNECTION;
658 }
659
660 switch (Parameters->QueryType)
661 {
662 case TDI_QUERY_ADDRESS_INFO:
663 {
664 PTDI_ADDRESS_INFO AddressInfo;
665 PADDRESS_FILE AddrFile;
666 PTA_IP_ADDRESS Address;
667
668 AddressInfo = (PTDI_ADDRESS_INFO)MmGetSystemAddressForMdl(Irp->MdlAddress);
669
670 switch ((ULONG)IrpSp->FileObject->FsContext2) {
671 case TDI_TRANSPORT_ADDRESS_FILE:
672 AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
673 break;
674
675 case TDI_CONNECTION_FILE:
676 AddrFile =
677 ((PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext)->
678 AddressFile;
679 break;
680
681 default:
682 TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
683 return STATUS_INVALID_PARAMETER;
684 }
685
686 if (!AddrFile) {
687 TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
688 return STATUS_INVALID_PARAMETER;
689 }
690
691 if (MmGetMdlByteCount(Irp->MdlAddress) <
692 (FIELD_OFFSET(TDI_ADDRESS_INFO, Address.Address[0].Address) +
693 sizeof(TDI_ADDRESS_IP))) {
694 TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n"));
695 return STATUS_BUFFER_OVERFLOW;
696 }
697
698 Address = (PTA_IP_ADDRESS)&AddressInfo->Address;
699 Address->TAAddressCount = 1;
700 Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
701 Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
702 Address->Address[0].Address[0].sin_port = AddrFile->Port;
703 Address->Address[0].Address[0].in_addr =
704 AddrFile->Address.Address.IPv4Address;
705 RtlZeroMemory(
706 &Address->Address[0].Address[0].sin_zero,
707 sizeof(Address->Address[0].Address[0].sin_zero));
708
709 return STATUS_SUCCESS;
710 }
711
712 case TDI_QUERY_CONNECTION_INFO:
713 {
714 PTDI_CONNECTION_INFORMATION AddressInfo;
715 PADDRESS_FILE AddrFile;
716 PCONNECTION_ENDPOINT Endpoint = NULL;
717
718 AddressInfo = (PTDI_CONNECTION_INFORMATION)
719 MmGetSystemAddressForMdl(Irp->MdlAddress);
720
721 switch ((ULONG)IrpSp->FileObject->FsContext2) {
722 case TDI_TRANSPORT_ADDRESS_FILE:
723 AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
724 break;
725
726 case TDI_CONNECTION_FILE:
727 Endpoint =
728 (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
729 break;
730
731 default:
732 TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
733 return STATUS_INVALID_PARAMETER;
734 }
735
736 if (!Endpoint) {
737 TI_DbgPrint(MID_TRACE, ("No connection object.\n"));
738 return STATUS_INVALID_PARAMETER;
739 }
740
741 if (MmGetMdlByteCount(Irp->MdlAddress) <
742 (FIELD_OFFSET(TDI_CONNECTION_INFORMATION, RemoteAddress) +
743 sizeof(PVOID))) {
744 TI_DbgPrint(MID_TRACE, ("MDL buffer too small (ptr).\n"));
745 return STATUS_BUFFER_OVERFLOW;
746 }
747
748 return TCPGetPeerAddress( Endpoint, AddressInfo->RemoteAddress );
749 }
750 }
751
752 return STATUS_NOT_IMPLEMENTED;
753 }
754
755
756 NTSTATUS DispTdiReceive(
757 PIRP Irp)
758 /*
759 * FUNCTION: TDI_RECEIVE handler
760 * ARGUMENTS:
761 * Irp = Pointer to an I/O request packet
762 * RETURNS:
763 * Status of operation
764 */
765 {
766 PIO_STACK_LOCATION IrpSp;
767 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo;
768 PTRANSPORT_CONTEXT TranContext;
769 NTSTATUS Status;
770 ULONG BytesReceived;
771
772 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
773
774 IrpSp = IoGetCurrentIrpStackLocation(Irp);
775 ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters);
776
777 TranContext = IrpSp->FileObject->FsContext;
778 if (TranContext == NULL)
779 {
780 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
781 return STATUS_INVALID_CONNECTION;
782 }
783
784 if (TranContext->Handle.ConnectionContext == NULL)
785 {
786 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
787 return STATUS_INVALID_CONNECTION;
788 }
789
790 /* Initialize a receive request */
791 Status = DispPrepareIrpForCancel
792 (TranContext->Handle.ConnectionContext,
793 Irp,
794 (PDRIVER_CANCEL)DispCancelRequest);
795
796 TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress));
797 if (NT_SUCCESS(Status))
798 {
799 /* Lock here so we're sure we've got the following 'mark pending' */
800 TcpipRecursiveMutexEnter( &TCPLock, TRUE );
801
802 Status = TCPReceiveData(
803 TranContext->Handle.ConnectionContext,
804 (PNDIS_BUFFER)Irp->MdlAddress,
805 ReceiveInfo->ReceiveLength,
806 &BytesReceived,
807 ReceiveInfo->ReceiveFlags,
808 DispDataRequestComplete,
809 Irp);
810 if (Status != STATUS_PENDING)
811 {
812 DispDataRequestComplete(Irp, Status, BytesReceived);
813 } else {
814 IoMarkIrpPending(Irp);
815 }
816
817 TcpipRecursiveMutexLeave( &TCPLock );
818 }
819
820 TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
821
822 return Status;
823 }
824
825
826 NTSTATUS DispTdiReceiveDatagram(
827 PIRP Irp)
828 /*
829 * FUNCTION: TDI_RECEIVE_DATAGRAM handler
830 * ARGUMENTS:
831 * Irp = Pointer to an I/O request packet
832 * RETURNS:
833 * Status of operation
834 */
835 {
836 PIO_STACK_LOCATION IrpSp;
837 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo;
838 PTRANSPORT_CONTEXT TranContext;
839 TDI_REQUEST Request;
840 NTSTATUS Status;
841 ULONG BytesReceived;
842
843 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
844
845 IrpSp = IoGetCurrentIrpStackLocation(Irp);
846 DgramInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&(IrpSp->Parameters);
847
848 TranContext = IrpSp->FileObject->FsContext;
849 if (TranContext == NULL)
850 {
851 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
852 return STATUS_INVALID_ADDRESS;
853 }
854
855 /* Initialize a receive request */
856 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
857 Request.RequestNotifyObject = DispDataRequestComplete;
858 Request.RequestContext = Irp;
859
860 Status = DispPrepareIrpForCancel(
861 IrpSp->FileObject->FsContext,
862 Irp,
863 (PDRIVER_CANCEL)DispCancelRequest);
864
865 if (NT_SUCCESS(Status))
866 {
867 PCHAR DataBuffer;
868 UINT BufferSize;
869
870 NdisQueryBuffer( (PNDIS_BUFFER)Irp->MdlAddress,
871 &DataBuffer,
872 &BufferSize );
873
874 Status = UDPReceiveDatagram(
875 Request.Handle.AddressHandle,
876 DgramInfo->ReceiveDatagramInformation,
877 DataBuffer,
878 DgramInfo->ReceiveLength,
879 DgramInfo->ReceiveFlags,
880 DgramInfo->ReturnDatagramInformation,
881 &BytesReceived,
882 (PDATAGRAM_COMPLETION_ROUTINE)DispDataRequestComplete,
883 Irp);
884 if (Status != STATUS_PENDING) {
885 DispDataRequestComplete(Irp, Status, BytesReceived);
886 } else
887 IoMarkIrpPending(Irp);
888 }
889
890 TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
891
892 return Status;
893 }
894
895
896 NTSTATUS DispTdiSend(
897 PIRP Irp)
898 /*
899 * FUNCTION: TDI_SEND handler
900 * ARGUMENTS:
901 * Irp = Pointer to an I/O request packet
902 * RETURNS:
903 * Status of operation
904 */
905 {
906 PIO_STACK_LOCATION IrpSp;
907 PTDI_REQUEST_KERNEL_SEND SendInfo;
908 PTRANSPORT_CONTEXT TranContext;
909 NTSTATUS Status;
910 ULONG BytesSent;
911
912 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
913
914 IrpSp = IoGetCurrentIrpStackLocation(Irp);
915 SendInfo = (PTDI_REQUEST_KERNEL_SEND)&(IrpSp->Parameters);
916
917 TranContext = IrpSp->FileObject->FsContext;
918 if (TranContext == NULL)
919 {
920 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
921 return STATUS_INVALID_CONNECTION;
922 }
923
924 if (TranContext->Handle.ConnectionContext == NULL)
925 {
926 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
927 return STATUS_INVALID_CONNECTION;
928 }
929
930 Status = DispPrepareIrpForCancel(
931 IrpSp->FileObject->FsContext,
932 Irp,
933 (PDRIVER_CANCEL)DispCancelRequest);
934
935 TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress));
936 if (NT_SUCCESS(Status))
937 {
938 PCHAR Data;
939 UINT Len;
940
941 NdisQueryBuffer( Irp->MdlAddress, &Data, &Len );
942
943 TI_DbgPrint(MID_TRACE,("About to TCPSendData\n"));
944 Status = TCPSendData(
945 TranContext->Handle.ConnectionContext,
946 Data,
947 SendInfo->SendLength,
948 &BytesSent,
949 SendInfo->SendFlags,
950 DispDataRequestComplete,
951 Irp);
952 if (Status != STATUS_PENDING)
953 {
954 DispDataRequestComplete(Irp, Status, BytesSent);
955 } else
956 IoMarkIrpPending( Irp );
957 }
958
959 TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
960
961 return Status;
962 }
963
964
965 NTSTATUS DispTdiSendDatagram(
966 PIRP Irp)
967 /*
968 * FUNCTION: TDI_SEND_DATAGRAM handler
969 * ARGUMENTS:
970 * Irp = Pointer to an I/O request packet
971 * RETURNS:
972 * Status of operation
973 */
974 {
975 PIO_STACK_LOCATION IrpSp;
976 TDI_REQUEST Request;
977 PTDI_REQUEST_KERNEL_SENDDG DgramInfo;
978 PTRANSPORT_CONTEXT TranContext;
979 NTSTATUS Status;
980
981 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
982
983 IrpSp = IoGetCurrentIrpStackLocation(Irp);
984 DgramInfo = (PTDI_REQUEST_KERNEL_SENDDG)&(IrpSp->Parameters);
985 TranContext = IrpSp->FileObject->FsContext;
986
987 /* Initialize a send request */
988 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
989 Request.RequestNotifyObject = DispDataRequestComplete;
990 Request.RequestContext = Irp;
991
992 Status = DispPrepareIrpForCancel(
993 IrpSp->FileObject->FsContext,
994 Irp,
995 (PDRIVER_CANCEL)DispCancelRequest);
996
997 if (NT_SUCCESS(Status)) {
998 PCHAR DataBuffer;
999 UINT BufferSize;
1000
1001 TI_DbgPrint(MID_TRACE,("About to query buffer %x\n", Irp->MdlAddress));
1002
1003 NdisQueryBuffer( (PNDIS_BUFFER)Irp->MdlAddress,
1004 &DataBuffer,
1005 &BufferSize );
1006
1007 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
1008 must be of type PTDI_ADDRESS_IP */
1009 TI_DbgPrint(MID_TRACE,
1010 ("About to call send routine %x\n",
1011 (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)));
1012
1013 if( (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send) )
1014 Status = (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)(
1015 Request.Handle.AddressHandle,
1016 DgramInfo->SendDatagramInformation,
1017 DataBuffer,
1018 BufferSize,
1019 &Irp->IoStatus.Information);
1020 else
1021 Status = STATUS_UNSUCCESSFUL;
1022
1023 if (Status != STATUS_PENDING) {
1024 DispDataRequestComplete(Irp, Status, Irp->IoStatus.Information);
1025 /* Return STATUS_PENDING because DispPrepareIrpForCancel
1026 marks Irp as pending */
1027 Status = STATUS_PENDING;
1028 } else
1029 IoMarkIrpPending( Irp );
1030 }
1031
1032 TI_DbgPrint(DEBUG_IRP, ("Leaving.\n"));
1033
1034 return Status;
1035 }
1036
1037
1038 NTSTATUS DispTdiSetEventHandler(PIRP Irp)
1039 /*
1040 * FUNCTION: TDI_SET_EVENT_HANDER handler
1041 * ARGUMENTS:
1042 * Irp = Pointer to a I/O request packet
1043 * RETURNS:
1044 * Status of operation
1045 */
1046 {
1047 PTDI_REQUEST_KERNEL_SET_EVENT Parameters;
1048 PTRANSPORT_CONTEXT TranContext;
1049 PIO_STACK_LOCATION IrpSp;
1050 PADDRESS_FILE AddrFile;
1051 NTSTATUS Status;
1052 KIRQL OldIrql;
1053
1054 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
1055
1056 IrpSp = IoGetCurrentIrpStackLocation(Irp);
1057
1058 /* Get associated address file object. Quit if none exists */
1059
1060 TranContext = IrpSp->FileObject->FsContext;
1061 if (!TranContext) {
1062 TI_DbgPrint(MIN_TRACE, ("Bad transport context.\n"));
1063 return STATUS_INVALID_PARAMETER;
1064 }
1065
1066 AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
1067 if (!AddrFile) {
1068 TI_DbgPrint(MIN_TRACE, ("No address file object.\n"));
1069 return STATUS_INVALID_PARAMETER;
1070 }
1071
1072 Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
1073 Status = STATUS_SUCCESS;
1074
1075 TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
1076
1077 /* Set the event handler. if an event handler is associated with
1078 a specific event, it's flag (RegisteredXxxHandler) is TRUE.
1079 If an event handler is not used it's flag is FALSE */
1080 switch (Parameters->EventType) {
1081 case TDI_EVENT_CONNECT:
1082 if (!Parameters->EventHandler) {
1083 AddrFile->ConnectHandlerContext = NULL;
1084 AddrFile->RegisteredConnectHandler = FALSE;
1085 } else {
1086 AddrFile->ConnectHandler =
1087 (PTDI_IND_CONNECT)Parameters->EventHandler;
1088 AddrFile->ConnectHandlerContext = Parameters->EventContext;
1089 AddrFile->RegisteredConnectHandler = TRUE;
1090 }
1091 break;
1092
1093 case TDI_EVENT_DISCONNECT:
1094 if (!Parameters->EventHandler) {
1095 AddrFile->DisconnectHandlerContext = NULL;
1096 AddrFile->RegisteredDisconnectHandler = FALSE;
1097 } else {
1098 AddrFile->DisconnectHandler =
1099 (PTDI_IND_DISCONNECT)Parameters->EventHandler;
1100 AddrFile->DisconnectHandlerContext = Parameters->EventContext;
1101 AddrFile->RegisteredDisconnectHandler = TRUE;
1102 }
1103 break;
1104
1105 case TDI_EVENT_ERROR:
1106 if (Parameters->EventHandler == NULL) {
1107 AddrFile->ErrorHandlerContext = NULL;
1108 AddrFile->RegisteredErrorHandler = FALSE;
1109 } else {
1110 AddrFile->ErrorHandler =
1111 (PTDI_IND_ERROR)Parameters->EventHandler;
1112 AddrFile->ErrorHandlerContext = Parameters->EventContext;
1113 AddrFile->RegisteredErrorHandler = TRUE;
1114 }
1115 break;
1116
1117 case TDI_EVENT_RECEIVE:
1118 if (Parameters->EventHandler == NULL) {
1119 AddrFile->ReceiveHandlerContext = NULL;
1120 AddrFile->RegisteredReceiveHandler = FALSE;
1121 } else {
1122 AddrFile->ReceiveHandler =
1123 (PTDI_IND_RECEIVE)Parameters->EventHandler;
1124 AddrFile->ReceiveHandlerContext = Parameters->EventContext;
1125 AddrFile->RegisteredReceiveHandler = TRUE;
1126 }
1127 break;
1128
1129 case TDI_EVENT_RECEIVE_DATAGRAM:
1130 if (Parameters->EventHandler == NULL) {
1131 AddrFile->ReceiveDatagramHandlerContext = NULL;
1132 AddrFile->RegisteredReceiveDatagramHandler = FALSE;
1133 } else {
1134 AddrFile->ReceiveDatagramHandler =
1135 (PTDI_IND_RECEIVE_DATAGRAM)Parameters->EventHandler;
1136 AddrFile->ReceiveDatagramHandlerContext = Parameters->EventContext;
1137 AddrFile->RegisteredReceiveDatagramHandler = TRUE;
1138 }
1139 break;
1140
1141 case TDI_EVENT_RECEIVE_EXPEDITED:
1142 if (Parameters->EventHandler == NULL) {
1143 AddrFile->ExpeditedReceiveHandlerContext = NULL;
1144 AddrFile->RegisteredExpeditedReceiveHandler = FALSE;
1145 } else {
1146 AddrFile->ExpeditedReceiveHandler =
1147 (PTDI_IND_RECEIVE_EXPEDITED)Parameters->EventHandler;
1148 AddrFile->ExpeditedReceiveHandlerContext = Parameters->EventContext;
1149 AddrFile->RegisteredExpeditedReceiveHandler = TRUE;
1150 }
1151 break;
1152
1153 case TDI_EVENT_CHAINED_RECEIVE:
1154 if (Parameters->EventHandler == NULL) {
1155 AddrFile->ChainedReceiveHandlerContext = NULL;
1156 AddrFile->RegisteredChainedReceiveHandler = FALSE;
1157 } else {
1158 AddrFile->ChainedReceiveHandler =
1159 (PTDI_IND_CHAINED_RECEIVE)Parameters->EventHandler;
1160 AddrFile->ChainedReceiveHandlerContext = Parameters->EventContext;
1161 AddrFile->RegisteredChainedReceiveHandler = TRUE;
1162 }
1163 break;
1164
1165 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM:
1166 if (Parameters->EventHandler == NULL) {
1167 AddrFile->ChainedReceiveDatagramHandlerContext = NULL;
1168 AddrFile->RegisteredChainedReceiveDatagramHandler = FALSE;
1169 } else {
1170 AddrFile->ChainedReceiveDatagramHandler =
1171 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM)Parameters->EventHandler;
1172 AddrFile->ChainedReceiveDatagramHandlerContext = Parameters->EventContext;
1173 AddrFile->RegisteredChainedReceiveDatagramHandler = TRUE;
1174 }
1175 break;
1176
1177 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED:
1178 if (Parameters->EventHandler == NULL) {
1179 AddrFile->ChainedReceiveExpeditedHandlerContext = NULL;
1180 AddrFile->RegisteredChainedReceiveExpeditedHandler = FALSE;
1181 } else {
1182 AddrFile->ChainedReceiveExpeditedHandler =
1183 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED)Parameters->EventHandler;
1184 AddrFile->ChainedReceiveExpeditedHandlerContext = Parameters->EventContext;
1185 AddrFile->RegisteredChainedReceiveExpeditedHandler = TRUE;
1186 }
1187 break;
1188
1189 default:
1190 TI_DbgPrint(MIN_TRACE, ("Unknown event type (0x%X).\n",
1191 Parameters->EventType));
1192
1193 Status = STATUS_INVALID_PARAMETER;
1194 }
1195
1196 TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
1197
1198 return Status;
1199 }
1200
1201
1202 NTSTATUS DispTdiSetInformation(
1203 PIRP Irp)
1204 /*
1205 * FUNCTION: TDI_SET_INFORMATION handler
1206 * ARGUMENTS:
1207 * Irp = Pointer to an I/O request packet
1208 * RETURNS:
1209 * Status of operation
1210 */
1211 {
1212 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
1213
1214 return STATUS_NOT_IMPLEMENTED;
1215 }
1216
1217
1218 VOID DispTdiQueryInformationExComplete(
1219 PVOID Context,
1220 ULONG Status,
1221 UINT ByteCount)
1222 /*
1223 * FUNCTION: Completes a TDI QueryInformationEx request
1224 * ARGUMENTS:
1225 * Context = Pointer to the IRP for the request
1226 * Status = TDI status of the request
1227 * ByteCount = Number of bytes returned in output buffer
1228 */
1229 {
1230 PTI_QUERY_CONTEXT QueryContext;
1231 UINT Count = 0;
1232
1233 QueryContext = (PTI_QUERY_CONTEXT)Context;
1234 if (NT_SUCCESS(Status)) {
1235 Count = CopyBufferToBufferChain(
1236 QueryContext->InputMdl,
1237 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX, Context),
1238 (PCHAR)&QueryContext->QueryInfo.Context,
1239 CONTEXT_SIZE);
1240 }
1241
1242 MmUnlockPages(QueryContext->InputMdl);
1243 IoFreeMdl(QueryContext->InputMdl);
1244 if( QueryContext->OutputMdl ) {
1245 MmUnlockPages(QueryContext->OutputMdl);
1246 IoFreeMdl(QueryContext->OutputMdl);
1247 }
1248
1249 QueryContext->Irp->IoStatus.Information = ByteCount;
1250 QueryContext->Irp->IoStatus.Status = Status;
1251
1252 ExFreePool(QueryContext);
1253 }
1254
1255
1256 NTSTATUS DispTdiQueryInformationEx(
1257 PIRP Irp,
1258 PIO_STACK_LOCATION IrpSp)
1259 /*
1260 * FUNCTION: TDI QueryInformationEx handler
1261 * ARGUMENTS:
1262 * Irp = Pointer to I/O request packet
1263 * IrpSp = Pointer to current stack location of Irp
1264 * RETURNS:
1265 * Status of operation
1266 */
1267 {
1268 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer;
1269 PTRANSPORT_CONTEXT TranContext;
1270 PTI_QUERY_CONTEXT QueryContext;
1271 PVOID OutputBuffer;
1272 TDI_REQUEST Request;
1273 UINT Size;
1274 UINT InputBufferLength;
1275 UINT OutputBufferLength;
1276 BOOLEAN InputMdlLocked = FALSE;
1277 BOOLEAN OutputMdlLocked = FALSE;
1278 PMDL InputMdl = NULL;
1279 PMDL OutputMdl = NULL;
1280 NTSTATUS Status = STATUS_SUCCESS;
1281
1282 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
1283
1284 TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
1285
1286 switch ((ULONG)IrpSp->FileObject->FsContext2) {
1287 case TDI_TRANSPORT_ADDRESS_FILE:
1288 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
1289 break;
1290
1291 case TDI_CONNECTION_FILE:
1292 Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
1293 break;
1294
1295 case TDI_CONTROL_CHANNEL_FILE:
1296 Request.Handle.ControlChannel = TranContext->Handle.ControlChannel;
1297 break;
1298
1299 default:
1300 TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
1301 return STATUS_INVALID_PARAMETER;
1302 }
1303
1304 InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
1305 OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
1306
1307 /* Validate parameters */
1308 if ((InputBufferLength == sizeof(TCP_REQUEST_QUERY_INFORMATION_EX)) &&
1309 (OutputBufferLength != 0)) {
1310
1311 InputBuffer = (PTCP_REQUEST_QUERY_INFORMATION_EX)
1312 IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
1313 OutputBuffer = Irp->UserBuffer;
1314
1315 QueryContext = ExAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT));
1316 if (QueryContext) {
1317 _SEH_TRY {
1318 InputMdl = IoAllocateMdl(InputBuffer,
1319 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX),
1320 FALSE, TRUE, NULL);
1321
1322 OutputMdl = IoAllocateMdl(OutputBuffer,
1323 OutputBufferLength, FALSE, TRUE, NULL);
1324
1325 if (InputMdl && OutputMdl) {
1326
1327 MmProbeAndLockPages(InputMdl, Irp->RequestorMode,
1328 IoModifyAccess);
1329
1330 InputMdlLocked = TRUE;
1331
1332 MmProbeAndLockPages(OutputMdl, Irp->RequestorMode,
1333 IoWriteAccess);
1334
1335 OutputMdlLocked = TRUE;
1336
1337 RtlCopyMemory(&QueryContext->QueryInfo,
1338 InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
1339 } else
1340 Status = STATUS_INSUFFICIENT_RESOURCES;
1341 } _SEH_HANDLE {
1342 Status = _SEH_GetExceptionCode();
1343 } _SEH_END;
1344
1345 if (NT_SUCCESS(Status)) {
1346 Size = MmGetMdlByteCount(OutputMdl);
1347
1348 QueryContext->Irp = Irp;
1349 QueryContext->InputMdl = InputMdl;
1350 QueryContext->OutputMdl = OutputMdl;
1351
1352 Request.RequestNotifyObject = DispTdiQueryInformationExComplete;
1353 Request.RequestContext = QueryContext;
1354 Status = InfoTdiQueryInformationEx(&Request,
1355 &QueryContext->QueryInfo.ID, OutputMdl,
1356 &Size, &QueryContext->QueryInfo.Context);
1357 DispTdiQueryInformationExComplete(QueryContext, Status, Size);
1358
1359 TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status));
1360
1361 return Status;
1362 }
1363
1364 /* An error occurred if we get here */
1365
1366 if (InputMdl) {
1367 if (InputMdlLocked)
1368 MmUnlockPages(InputMdl);
1369 IoFreeMdl(InputMdl);
1370 }
1371
1372 if (OutputMdl) {
1373 if (OutputMdlLocked)
1374 MmUnlockPages(OutputMdl);
1375 IoFreeMdl(OutputMdl);
1376 }
1377
1378 ExFreePool(QueryContext);
1379 } else
1380 Status = STATUS_INSUFFICIENT_RESOURCES;
1381 } else if( InputBufferLength ==
1382 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX) ) {
1383 /* Handle the case where the user is probing the buffer for length */
1384 TI_DbgPrint(MAX_TRACE, ("InputBufferLength %d OutputBufferLength %d\n",
1385 InputBufferLength, OutputBufferLength));
1386 InputBuffer = (PTCP_REQUEST_QUERY_INFORMATION_EX)
1387 IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
1388
1389 Size = 0;
1390
1391 QueryContext = ExAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT));
1392 if (!QueryContext) return STATUS_INSUFFICIENT_RESOURCES;
1393
1394 _SEH_TRY {
1395 InputMdl = IoAllocateMdl(InputBuffer,
1396 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX),
1397 FALSE, TRUE, NULL);
1398
1399 MmProbeAndLockPages(InputMdl, Irp->RequestorMode,
1400 IoModifyAccess);
1401
1402 InputMdlLocked = TRUE;
1403 Status = STATUS_SUCCESS;
1404 } _SEH_HANDLE {
1405 TI_DbgPrint(MAX_TRACE, ("Failed to acquire client buffer\n"));
1406 Status = _SEH_GetExceptionCode();
1407 } _SEH_END;
1408
1409 if( !NT_SUCCESS(Status) || !InputMdl ) {
1410 if( InputMdl ) IoFreeMdl( InputMdl );
1411 ExFreePool(QueryContext);
1412 return Status;
1413 }
1414
1415 RtlCopyMemory(&QueryContext->QueryInfo,
1416 InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
1417
1418 QueryContext->Irp = Irp;
1419 QueryContext->InputMdl = InputMdl;
1420 QueryContext->OutputMdl = NULL;
1421
1422 Request.RequestNotifyObject = DispTdiQueryInformationExComplete;
1423 Request.RequestContext = QueryContext;
1424 Status = InfoTdiQueryInformationEx(&Request,
1425 &QueryContext->QueryInfo.ID,
1426 NULL,
1427 &Size,
1428 &QueryContext->QueryInfo.Context);
1429 DispTdiQueryInformationExComplete(QueryContext, Status, Size);
1430 TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status));
1431 } else Status = STATUS_INVALID_PARAMETER;
1432
1433 TI_DbgPrint(MIN_TRACE, ("Leaving. Status = (0x%X)\n", Status));
1434
1435 return Status;
1436 }
1437
1438
1439 NTSTATUS DispTdiSetInformationEx(
1440 PIRP Irp,
1441 PIO_STACK_LOCATION IrpSp)
1442 /*
1443 * FUNCTION: TDI SetInformationEx handler
1444 * ARGUMENTS:
1445 * Irp = Pointer to I/O request packet
1446 * IrpSp = Pointer to current stack location of Irp
1447 * RETURNS:
1448 * Status of operation
1449 */
1450 {
1451 PTRANSPORT_CONTEXT TranContext;
1452 PTCP_REQUEST_SET_INFORMATION_EX Info;
1453 TDI_REQUEST Request;
1454 TDI_STATUS Status;
1455 KIRQL OldIrql;
1456
1457 TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
1458
1459 TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
1460 Info = (PTCP_REQUEST_SET_INFORMATION_EX)Irp->AssociatedIrp.SystemBuffer;
1461
1462 switch ((ULONG)IrpSp->FileObject->FsContext2) {
1463 case TDI_TRANSPORT_ADDRESS_FILE:
1464 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
1465 break;
1466
1467 case TDI_CONNECTION_FILE:
1468 Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
1469 break;
1470
1471 case TDI_CONTROL_CHANNEL_FILE:
1472 Request.Handle.ControlChannel = TranContext->Handle.ControlChannel;
1473 break;
1474
1475 default:
1476 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1477 Irp->IoStatus.Information = 0;
1478
1479 TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
1480
1481 return IRPFinish(Irp, STATUS_INVALID_PARAMETER);
1482 }
1483
1484 Status = DispPrepareIrpForCancel(TranContext, Irp, NULL);
1485 if (NT_SUCCESS(Status)) {
1486 Request.RequestNotifyObject = DispDataRequestComplete;
1487 Request.RequestContext = Irp;
1488
1489 Status = InfoTdiSetInformationEx(&Request, &Info->ID,
1490 &Info->Buffer, Info->BufferSize);
1491
1492 if (Status != STATUS_PENDING) {
1493 IoAcquireCancelSpinLock(&OldIrql);
1494 (void)IoSetCancelRoutine(Irp, NULL);
1495 IoReleaseCancelSpinLock(OldIrql);
1496 }
1497 }
1498
1499 return Status;
1500 }
1501
1502 /* TODO: Support multiple addresses per interface.
1503 * For now just set the nte context to the interface index.
1504 *
1505 * Later on, create an NTE context and NTE instance
1506 */
1507
1508 NTSTATUS DispTdiSetIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
1509 NTSTATUS Status = STATUS_DEVICE_DOES_NOT_EXIST;
1510 PIP_SET_ADDRESS IpAddrChange =
1511 (PIP_SET_ADDRESS)Irp->AssociatedIrp.SystemBuffer;
1512 IF_LIST_ITER(IF);
1513
1514 TI_DbgPrint(MID_TRACE,("Setting IP Address for adapter %d\n",
1515 IpAddrChange->NteIndex));
1516
1517 ForEachInterface(IF) {
1518 TI_DbgPrint(MID_TRACE,("Looking at adapter %d\n", IF->Index));
1519
1520 if( IF->Unicast.Address.IPv4Address == IpAddrChange->Address ) {
1521 Status = STATUS_DUPLICATE_OBJECTID;
1522 break;
1523 }
1524 if( IF->Index == IpAddrChange->NteIndex ) {
1525 IPRemoveInterfaceRoute( IF );
1526
1527 IF->Unicast.Type = IP_ADDRESS_V4;
1528 IF->Unicast.Address.IPv4Address = IpAddrChange->Address;
1529 IF->Netmask.Type = IP_ADDRESS_V4;
1530 IF->Netmask.Address.IPv4Address = IpAddrChange->Netmask;
1531 IF->Broadcast.Address.IPv4Address =
1532 IF->Unicast.Address.IPv4Address |
1533 ~IF->Netmask.Address.IPv4Address;
1534
1535 TI_DbgPrint(MID_TRACE,("New Unicast Address: %x\n",
1536 IF->Unicast.Address.IPv4Address));
1537 TI_DbgPrint(MID_TRACE,("New Netmask : %x\n",
1538 IF->Netmask.Address.IPv4Address));
1539
1540 IPAddInterfaceRoute( IF );
1541
1542 IpAddrChange->Address = IF->Index;
1543 Status = STATUS_SUCCESS;
1544 Irp->IoStatus.Information = IF->Index;
1545 break;
1546 }
1547 } EndFor(IF);
1548
1549 Irp->IoStatus.Status = Status;
1550 return Status;
1551 }
1552
1553 NTSTATUS DispTdiDeleteIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
1554 NTSTATUS Status = STATUS_UNSUCCESSFUL;
1555 PUSHORT NteIndex = Irp->AssociatedIrp.SystemBuffer;
1556 IF_LIST_ITER(IF);
1557
1558 ForEachInterface(IF) {
1559 if( IF->Index == *NteIndex ) {
1560 IPRemoveInterfaceRoute( IF );
1561 IF->Unicast.Type = IP_ADDRESS_V4;
1562 IF->Unicast.Address.IPv4Address = 0;
1563 IF->Netmask.Type = IP_ADDRESS_V4;
1564 IF->Netmask.Address.IPv4Address = 0;
1565 Status = STATUS_SUCCESS;
1566 }
1567 } EndFor(IF);
1568
1569 Irp->IoStatus.Status = Status;
1570 return Status;
1571 }
1572
1573 /* EOF */