Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendispatch.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS TCP/IP protocol driver 00004 * FILE: tcpip/dispatch.h 00005 * PURPOSE: TDI dispatch routines 00006 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) 00007 * REVISIONS: 00008 * CSH 01/08-2000 Created 00009 * TODO: Validate device object in all dispatch routines 00010 */ 00011 00012 #include "precomp.h" 00013 00014 NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) { 00015 KIRQL OldIrql; 00016 00017 Irp->IoStatus.Status = Status; 00018 00019 if( Status == STATUS_PENDING ) 00020 IoMarkIrpPending( Irp ); 00021 else { 00022 IoAcquireCancelSpinLock(&OldIrql); 00023 (void)IoSetCancelRoutine( Irp, NULL ); 00024 IoReleaseCancelSpinLock(OldIrql); 00025 00026 IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); 00027 } 00028 00029 return Status; 00030 } 00031 00032 NTSTATUS DispPrepareIrpForCancel( 00033 PTRANSPORT_CONTEXT Context, 00034 PIRP Irp, 00035 PDRIVER_CANCEL CancelRoutine) 00036 /* 00037 * FUNCTION: Prepare an IRP for cancellation 00038 * ARGUMENTS: 00039 * Context = Pointer to context information 00040 * Irp = Pointer to an I/O request packet 00041 * CancelRoutine = Routine to be called when I/O request is cancelled 00042 * RETURNS: 00043 * Status of operation 00044 */ 00045 { 00046 KIRQL OldIrql; 00047 PIO_STACK_LOCATION IrpSp; 00048 PTRANSPORT_CONTEXT TransContext; 00049 00050 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 00051 00052 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00053 TransContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext; 00054 00055 IoAcquireCancelSpinLock(&OldIrql); 00056 00057 if (!Irp->Cancel && !TransContext->CancelIrps) { 00058 (void)IoSetCancelRoutine(Irp, CancelRoutine); 00059 IoReleaseCancelSpinLock(OldIrql); 00060 00061 TI_DbgPrint(DEBUG_IRP, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp)); 00062 00063 return STATUS_SUCCESS; 00064 } 00065 00066 /* IRP has already been cancelled */ 00067 00068 IoReleaseCancelSpinLock(OldIrql); 00069 00070 Irp->IoStatus.Status = STATUS_CANCELLED; 00071 Irp->IoStatus.Information = 0; 00072 00073 TI_DbgPrint(DEBUG_IRP, ("Leaving (IRP was already cancelled).\n")); 00074 00075 return Irp->IoStatus.Status; 00076 } 00077 00078 VOID DispDataRequestComplete( 00079 PVOID Context, 00080 NTSTATUS Status, 00081 ULONG Count) 00082 /* 00083 * FUNCTION: Completes a send/receive IRP 00084 * ARGUMENTS: 00085 * Context = Pointer to context information (IRP) 00086 * Status = Status of the request 00087 * Count = Number of bytes sent or received 00088 */ 00089 { 00090 PIRP Irp = Context; 00091 00092 TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n", 00093 Irp, Status, Count)); 00094 00095 Irp->IoStatus.Status = Status; 00096 Irp->IoStatus.Information = Count; 00097 00098 TI_DbgPrint(MID_TRACE, ("Irp->IoStatus.Status = %x\n", 00099 Irp->IoStatus.Status)); 00100 TI_DbgPrint(MID_TRACE, ("Irp->IoStatus.Information = %d\n", 00101 Irp->IoStatus.Information)); 00102 TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp)); 00103 00104 IRPFinish(Irp, Status); 00105 00106 TI_DbgPrint(DEBUG_IRP, ("Done Completing IRP\n")); 00107 } 00108 00109 VOID NTAPI DispCancelRequest( 00110 PDEVICE_OBJECT Device, 00111 PIRP Irp) 00112 /* 00113 * FUNCTION: Cancels an IRP 00114 * ARGUMENTS: 00115 * Device = Pointer to device object 00116 * Irp = Pointer to an I/O request packet 00117 */ 00118 { 00119 PIO_STACK_LOCATION IrpSp; 00120 PTRANSPORT_CONTEXT TranContext; 00121 PFILE_OBJECT FileObject; 00122 UCHAR MinorFunction; 00123 PCONNECTION_ENDPOINT Connection; 00124 BOOLEAN DequeuedIrp = TRUE; 00125 00126 IoReleaseCancelSpinLock(Irp->CancelIrql); 00127 00128 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 00129 00130 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00131 FileObject = IrpSp->FileObject; 00132 TranContext = (PTRANSPORT_CONTEXT)FileObject->FsContext; 00133 MinorFunction = IrpSp->MinorFunction; 00134 00135 TI_DbgPrint(DEBUG_IRP, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp, MinorFunction, IrpSp)); 00136 00137 Irp->IoStatus.Status = STATUS_CANCELLED; 00138 Irp->IoStatus.Information = 0; 00139 00140 #if DBG 00141 if (!Irp->Cancel) 00142 TI_DbgPrint(MIN_TRACE, ("Irp->Cancel is FALSE, should be TRUE.\n")); 00143 #endif 00144 00145 /* Try canceling the request */ 00146 switch(MinorFunction) { 00147 case TDI_SEND: 00148 case TDI_RECEIVE: 00149 DequeuedIrp = TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp ); 00150 break; 00151 00152 case TDI_SEND_DATAGRAM: 00153 if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) { 00154 TI_DbgPrint(MIN_TRACE, ("TDI_SEND_DATAGRAM, but no address file.\n")); 00155 break; 00156 } 00157 00158 DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp); 00159 break; 00160 00161 case TDI_RECEIVE_DATAGRAM: 00162 if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) { 00163 TI_DbgPrint(MIN_TRACE, ("TDI_RECEIVE_DATAGRAM, but no address file.\n")); 00164 break; 00165 } 00166 00167 DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp); 00168 break; 00169 00170 case TDI_CONNECT: 00171 DequeuedIrp = TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp); 00172 break; 00173 00174 case TDI_DISCONNECT: 00175 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; 00176 00177 DequeuedIrp = TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp); 00178 if (DequeuedIrp) 00179 { 00180 if (KeCancelTimer(&Connection->DisconnectTimer)) 00181 { 00182 DereferenceObject(Connection); 00183 } 00184 } 00185 break; 00186 00187 default: 00188 TI_DbgPrint(MIN_TRACE, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction)); 00189 ASSERT(FALSE); 00190 break; 00191 } 00192 00193 if (DequeuedIrp) 00194 IRPFinish(Irp, STATUS_CANCELLED); 00195 00196 TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); 00197 } 00198 00199 00200 VOID NTAPI DispCancelListenRequest( 00201 PDEVICE_OBJECT Device, 00202 PIRP Irp) 00203 /* 00204 * FUNCTION: Cancels a listen IRP 00205 * ARGUMENTS: 00206 * Device = Pointer to device object 00207 * Irp = Pointer to an I/O request packet 00208 */ 00209 { 00210 PIO_STACK_LOCATION IrpSp; 00211 PTRANSPORT_CONTEXT TranContext; 00212 PFILE_OBJECT FileObject; 00213 PCONNECTION_ENDPOINT Connection; 00214 00215 IoReleaseCancelSpinLock(Irp->CancelIrql); 00216 00217 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 00218 00219 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00220 FileObject = IrpSp->FileObject; 00221 TranContext = (PTRANSPORT_CONTEXT)FileObject->FsContext; 00222 ASSERT( TDI_LISTEN == IrpSp->MinorFunction); 00223 00224 TI_DbgPrint(DEBUG_IRP, ("IRP at (0x%X).\n", Irp)); 00225 00226 #if DBG 00227 if (!Irp->Cancel) 00228 TI_DbgPrint(MIN_TRACE, ("Irp->Cancel is FALSE, should be TRUE.\n")); 00229 #endif 00230 00231 /* Try canceling the request */ 00232 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; 00233 00234 if (TCPAbortListenForSocket(Connection->AddressFile->Listener, 00235 Connection)) 00236 { 00237 Irp->IoStatus.Information = 0; 00238 IRPFinish(Irp, STATUS_CANCELLED); 00239 } 00240 00241 TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); 00242 } 00243 00244 00245 NTSTATUS DispTdiAccept( 00246 PIRP Irp) 00247 /* 00248 * FUNCTION: TDI_ACCEPT handler 00249 * ARGUMENTS: 00250 * Irp = Pointer to an I/O request packet 00251 * RETURNS: 00252 * Status of operation 00253 */ 00254 { 00255 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 00256 00257 return STATUS_NOT_IMPLEMENTED; 00258 } 00259 00260 00261 NTSTATUS DispTdiAssociateAddress( 00262 PIRP Irp) 00263 /* 00264 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler 00265 * ARGUMENTS: 00266 * Irp = Pointer to an I/O request packet 00267 * RETURNS: 00268 * Status of operation 00269 */ 00270 { 00271 PTDI_REQUEST_KERNEL_ASSOCIATE Parameters; 00272 PTRANSPORT_CONTEXT TranContext; 00273 PIO_STACK_LOCATION IrpSp; 00274 PCONNECTION_ENDPOINT Connection, LastConnection; 00275 PFILE_OBJECT FileObject; 00276 PADDRESS_FILE AddrFile = NULL; 00277 NTSTATUS Status; 00278 KIRQL OldIrql; 00279 00280 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 00281 00282 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00283 00284 /* Get associated connection endpoint file object. Quit if none exists */ 00285 00286 TranContext = IrpSp->FileObject->FsContext; 00287 if (!TranContext) { 00288 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); 00289 return STATUS_INVALID_PARAMETER; 00290 } 00291 00292 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; 00293 if (!Connection) { 00294 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n")); 00295 return STATUS_INVALID_PARAMETER; 00296 } 00297 00298 Parameters = (PTDI_REQUEST_KERNEL_ASSOCIATE)&IrpSp->Parameters; 00299 00300 Status = ObReferenceObjectByHandle( 00301 Parameters->AddressHandle, 00302 0, 00303 IoFileObjectType, 00304 KernelMode, 00305 (PVOID*)&FileObject, 00306 NULL); 00307 if (!NT_SUCCESS(Status)) { 00308 TI_DbgPrint(MID_TRACE, ("Bad address file object handle (0x%X): %x.\n", 00309 Parameters->AddressHandle, Status)); 00310 return STATUS_INVALID_PARAMETER; 00311 } 00312 00313 LockObject(Connection, &OldIrql); 00314 00315 if (Connection->AddressFile) { 00316 ObDereferenceObject(FileObject); 00317 UnlockObject(Connection, OldIrql); 00318 TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n")); 00319 return STATUS_INVALID_PARAMETER; 00320 } 00321 00322 if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) { 00323 ObDereferenceObject(FileObject); 00324 UnlockObject(Connection, OldIrql); 00325 TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n", 00326 FileObject->FsContext2)); 00327 return STATUS_INVALID_PARAMETER; 00328 } 00329 00330 /* Get associated address file object. Quit if none exists */ 00331 00332 TranContext = FileObject->FsContext; 00333 if (!TranContext) { 00334 ObDereferenceObject(FileObject); 00335 UnlockObject(Connection, OldIrql); 00336 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); 00337 return STATUS_INVALID_PARAMETER; 00338 } 00339 00340 AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; 00341 if (!AddrFile) { 00342 UnlockObject(Connection, OldIrql); 00343 ObDereferenceObject(FileObject); 00344 TI_DbgPrint(MID_TRACE, ("No address file object.\n")); 00345 return STATUS_INVALID_PARAMETER; 00346 } 00347 00348 LockObjectAtDpcLevel(AddrFile); 00349 00350 ReferenceObject(AddrFile); 00351 Connection->AddressFile = AddrFile; 00352 00353 /* Add connection endpoint to the address file */ 00354 ReferenceObject(Connection); 00355 if (AddrFile->Connection == NULL) 00356 AddrFile->Connection = Connection; 00357 else 00358 { 00359 LastConnection = AddrFile->Connection; 00360 while (LastConnection->Next != NULL) 00361 LastConnection = LastConnection->Next; 00362 LastConnection->Next = Connection; 00363 } 00364 00365 ObDereferenceObject(FileObject); 00366 00367 UnlockObjectFromDpcLevel(AddrFile); 00368 UnlockObject(Connection, OldIrql); 00369 00370 return STATUS_SUCCESS; 00371 } 00372 00373 00374 NTSTATUS DispTdiConnect( 00375 PIRP Irp) 00376 /* 00377 * FUNCTION: TDI_CONNECT handler 00378 * ARGUMENTS: 00379 * Irp = Pointer to an I/O request packet 00380 * RETURNS: 00381 * Status of operation 00382 */ 00383 { 00384 PCONNECTION_ENDPOINT Connection; 00385 PTDI_REQUEST_KERNEL Parameters; 00386 PTRANSPORT_CONTEXT TranContext; 00387 PIO_STACK_LOCATION IrpSp; 00388 NTSTATUS Status; 00389 00390 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 00391 00392 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00393 00394 /* Get associated connection endpoint file object. Quit if none exists */ 00395 00396 TranContext = IrpSp->FileObject->FsContext; 00397 if (!TranContext) { 00398 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); 00399 Status = STATUS_INVALID_PARAMETER; 00400 goto done; 00401 } 00402 00403 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; 00404 if (!Connection) { 00405 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n")); 00406 Status = STATUS_INVALID_PARAMETER; 00407 goto done; 00408 } 00409 00410 Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters; 00411 00412 Status = DispPrepareIrpForCancel(TranContext->Handle.ConnectionContext, 00413 Irp, 00414 DispCancelRequest); 00415 00416 if (NT_SUCCESS(Status)) { 00417 Status = TCPConnect( 00418 TranContext->Handle.ConnectionContext, 00419 Parameters->RequestConnectionInformation, 00420 Parameters->ReturnConnectionInformation, 00421 DispDataRequestComplete, 00422 Irp ); 00423 } 00424 00425 done: 00426 if (Status != STATUS_PENDING) { 00427 DispDataRequestComplete(Irp, Status, 0); 00428 } else 00429 IoMarkIrpPending(Irp); 00430 00431 TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status)); 00432 00433 return Status; 00434 } 00435 00436 00437 NTSTATUS DispTdiDisassociateAddress( 00438 PIRP Irp) 00439 /* 00440 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler 00441 * ARGUMENTS: 00442 * Irp = Pointer to an I/O request packet 00443 * RETURNS: 00444 * Status of operation 00445 */ 00446 { 00447 PCONNECTION_ENDPOINT Connection; 00448 PTRANSPORT_CONTEXT TranContext; 00449 PIO_STACK_LOCATION IrpSp; 00450 00451 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 00452 00453 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00454 00455 /* Get associated connection endpoint file object. Quit if none exists */ 00456 00457 TranContext = IrpSp->FileObject->FsContext; 00458 if (!TranContext) { 00459 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); 00460 return STATUS_INVALID_PARAMETER; 00461 } 00462 00463 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; 00464 if (!Connection) { 00465 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n")); 00466 return STATUS_INVALID_PARAMETER; 00467 } 00468 00469 /* NO-OP because we need the address to deallocate the port when the connection closes */ 00470 00471 return STATUS_SUCCESS; 00472 } 00473 00474 00475 NTSTATUS DispTdiDisconnect( 00476 PIRP Irp) 00477 /* 00478 * FUNCTION: TDI_DISCONNECT handler 00479 * ARGUMENTS: 00480 * Irp = Pointer to an I/O request packet 00481 * RETURNS: 00482 * Status of operation 00483 */ 00484 { 00485 NTSTATUS Status; 00486 PTDI_REQUEST_KERNEL_DISCONNECT DisReq; 00487 PCONNECTION_ENDPOINT Connection; 00488 PTRANSPORT_CONTEXT TranContext; 00489 PIO_STACK_LOCATION IrpSp; 00490 00491 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 00492 00493 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00494 DisReq = (PTDI_REQUEST_KERNEL_DISCONNECT)&IrpSp->Parameters; 00495 00496 /* Get associated connection endpoint file object. Quit if none exists */ 00497 00498 TranContext = IrpSp->FileObject->FsContext; 00499 if (!TranContext) { 00500 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); 00501 Status = STATUS_INVALID_PARAMETER; 00502 goto done; 00503 } 00504 00505 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; 00506 if (!Connection) { 00507 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n")); 00508 Status = STATUS_INVALID_PARAMETER; 00509 goto done; 00510 } 00511 00512 Status = DispPrepareIrpForCancel 00513 (TranContext->Handle.ConnectionContext, 00514 Irp, 00515 (PDRIVER_CANCEL)DispCancelRequest); 00516 00517 if (NT_SUCCESS(Status)) 00518 { 00519 Status = TCPDisconnect(TranContext->Handle.ConnectionContext, 00520 DisReq->RequestFlags, 00521 DisReq->RequestSpecific, 00522 DisReq->RequestConnectionInformation, 00523 DisReq->ReturnConnectionInformation, 00524 DispDataRequestComplete, 00525 Irp); 00526 } 00527 00528 done: 00529 if (Status != STATUS_PENDING) { 00530 DispDataRequestComplete(Irp, Status, 0); 00531 } else 00532 IoMarkIrpPending(Irp); 00533 00534 TI_DbgPrint(MAX_TRACE, ("TCP Disconnect returned %08x\n", Status)); 00535 00536 return Status; 00537 } 00538 00539 00540 NTSTATUS DispTdiListen( 00541 PIRP Irp) 00542 /* 00543 * FUNCTION: TDI_LISTEN handler 00544 * ARGUMENTS: 00545 * Irp = Pointer to an I/O request packet 00546 * RETURNS: 00547 * Status of operation 00548 */ 00549 { 00550 PCONNECTION_ENDPOINT Connection; 00551 PTDI_REQUEST_KERNEL Parameters; 00552 PTRANSPORT_CONTEXT TranContext; 00553 PIO_STACK_LOCATION IrpSp; 00554 NTSTATUS Status = STATUS_SUCCESS; 00555 KIRQL OldIrql; 00556 00557 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 00558 00559 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00560 00561 /* Get associated connection endpoint file object. Quit if none exists */ 00562 00563 TranContext = IrpSp->FileObject->FsContext; 00564 if (TranContext == NULL) 00565 { 00566 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); 00567 Status = STATUS_INVALID_PARAMETER; 00568 goto done; 00569 } 00570 00571 Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; 00572 if (Connection == NULL) 00573 { 00574 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n")); 00575 Status = STATUS_INVALID_PARAMETER; 00576 goto done; 00577 } 00578 00579 Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters; 00580 00581 Status = DispPrepareIrpForCancel 00582 (TranContext->Handle.ConnectionContext, 00583 Irp, 00584 (PDRIVER_CANCEL)DispCancelListenRequest); 00585 00586 LockObject(Connection, &OldIrql); 00587 00588 if (Connection->AddressFile == NULL) 00589 { 00590 TI_DbgPrint(MID_TRACE, ("No associated address file\n")); 00591 UnlockObject(Connection, OldIrql); 00592 Status = STATUS_INVALID_PARAMETER; 00593 goto done; 00594 } 00595 00596 LockObjectAtDpcLevel(Connection->AddressFile); 00597 00598 /* Listening will require us to create a listening socket and store it in 00599 * the address file. It will be signalled, and attempt to complete an irp 00600 * when a new connection arrives. */ 00601 /* The important thing to note here is that the irp we'll complete belongs 00602 * to the socket to be accepted onto, not the listener */ 00603 if( NT_SUCCESS(Status) && !Connection->AddressFile->Listener ) { 00604 Connection->AddressFile->Listener = 00605 TCPAllocateConnectionEndpoint( NULL ); 00606 00607 if( !Connection->AddressFile->Listener ) 00608 Status = STATUS_NO_MEMORY; 00609 00610 if( NT_SUCCESS(Status) ) { 00611 ReferenceObject(Connection->AddressFile); 00612 Connection->AddressFile->Listener->AddressFile = 00613 Connection->AddressFile; 00614 00615 Status = TCPSocket( Connection->AddressFile->Listener, 00616 Connection->AddressFile->Family, 00617 SOCK_STREAM, 00618 Connection->AddressFile->Protocol ); 00619 } 00620 00621 if( NT_SUCCESS(Status) ) 00622 Status = TCPListen( Connection->AddressFile->Listener, 1024 ); 00623 /* BACKLOG */ 00624 } 00625 00626 if( NT_SUCCESS(Status) ) { 00627 Status = TCPAccept 00628 ( (PTDI_REQUEST)Parameters, 00629 Connection->AddressFile->Listener, 00630 Connection, 00631 DispDataRequestComplete, 00632 Irp ); 00633 } 00634 00635 UnlockObjectFromDpcLevel(Connection->AddressFile); 00636 UnlockObject(Connection, OldIrql); 00637 00638 done: 00639 if (Status != STATUS_PENDING) { 00640 DispDataRequestComplete(Irp, Status, 0); 00641 } else 00642 IoMarkIrpPending(Irp); 00643 00644 TI_DbgPrint(MID_TRACE,("Leaving %x\n", Status)); 00645 00646 return Status; 00647 } 00648 00649 00650 NTSTATUS DispTdiQueryInformation( 00651 PDEVICE_OBJECT DeviceObject, 00652 PIRP Irp) 00653 /* 00654 * FUNCTION: TDI_QUERY_INFORMATION handler 00655 * ARGUMENTS: 00656 * DeviceObject = Pointer to device object structure 00657 * Irp = Pointer to an I/O request packet 00658 * RETURNS: 00659 * Status of operation 00660 */ 00661 { 00662 PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters; 00663 PTRANSPORT_CONTEXT TranContext; 00664 PIO_STACK_LOCATION IrpSp; 00665 00666 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 00667 00668 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00669 Parameters = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters; 00670 00671 TranContext = IrpSp->FileObject->FsContext; 00672 if (!TranContext) { 00673 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); 00674 return STATUS_INVALID_PARAMETER; 00675 } 00676 00677 switch (Parameters->QueryType) 00678 { 00679 case TDI_QUERY_ADDRESS_INFO: 00680 { 00681 PTDI_ADDRESS_INFO AddressInfo; 00682 PADDRESS_FILE AddrFile; 00683 PTA_IP_ADDRESS Address; 00684 PCONNECTION_ENDPOINT Endpoint = NULL; 00685 00686 00687 if (MmGetMdlByteCount(Irp->MdlAddress) < 00688 (FIELD_OFFSET(TDI_ADDRESS_INFO, Address.Address[0].Address) + 00689 sizeof(TDI_ADDRESS_IP))) { 00690 TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n")); 00691 return STATUS_BUFFER_TOO_SMALL; 00692 } 00693 00694 AddressInfo = (PTDI_ADDRESS_INFO)MmGetSystemAddressForMdl(Irp->MdlAddress); 00695 Address = (PTA_IP_ADDRESS)&AddressInfo->Address; 00696 00697 switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) { 00698 case TDI_TRANSPORT_ADDRESS_FILE: 00699 AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; 00700 00701 Address->TAAddressCount = 1; 00702 Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; 00703 Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; 00704 Address->Address[0].Address[0].sin_port = AddrFile->Port; 00705 Address->Address[0].Address[0].in_addr = AddrFile->Address.Address.IPv4Address; 00706 RtlZeroMemory( 00707 &Address->Address[0].Address[0].sin_zero, 00708 sizeof(Address->Address[0].Address[0].sin_zero)); 00709 return STATUS_SUCCESS; 00710 00711 case TDI_CONNECTION_FILE: 00712 Endpoint = 00713 (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; 00714 00715 Address->TAAddressCount = 1; 00716 Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; 00717 Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; 00718 Address->Address[0].Address[0].sin_port = Endpoint->AddressFile->Port; 00719 Address->Address[0].Address[0].in_addr = Endpoint->AddressFile->Address.Address.IPv4Address; 00720 RtlZeroMemory( 00721 &Address->Address[0].Address[0].sin_zero, 00722 sizeof(Address->Address[0].Address[0].sin_zero)); 00723 return STATUS_SUCCESS; 00724 00725 default: 00726 TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n")); 00727 return STATUS_INVALID_PARAMETER; 00728 } 00729 } 00730 00731 case TDI_QUERY_CONNECTION_INFO: 00732 { 00733 PTDI_CONNECTION_INFO ConnectionInfo; 00734 //PCONNECTION_ENDPOINT Endpoint; 00735 00736 if (MmGetMdlByteCount(Irp->MdlAddress) < sizeof(*ConnectionInfo)) { 00737 TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n")); 00738 return STATUS_BUFFER_TOO_SMALL; 00739 } 00740 00741 ConnectionInfo = (PTDI_CONNECTION_INFO) 00742 MmGetSystemAddressForMdl(Irp->MdlAddress); 00743 00744 switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) { 00745 case TDI_CONNECTION_FILE: 00746 //Endpoint = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; 00747 RtlZeroMemory(ConnectionInfo, sizeof(*ConnectionInfo)); 00748 return STATUS_SUCCESS; 00749 00750 default: 00751 TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n")); 00752 return STATUS_INVALID_PARAMETER; 00753 } 00754 } 00755 00756 case TDI_QUERY_MAX_DATAGRAM_INFO: 00757 { 00758 PTDI_MAX_DATAGRAM_INFO MaxDatagramInfo; 00759 00760 if (MmGetMdlByteCount(Irp->MdlAddress) < sizeof(*MaxDatagramInfo)) { 00761 TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n")); 00762 return STATUS_BUFFER_TOO_SMALL; 00763 } 00764 00765 MaxDatagramInfo = (PTDI_MAX_DATAGRAM_INFO) 00766 MmGetSystemAddressForMdl(Irp->MdlAddress); 00767 00768 MaxDatagramInfo->MaxDatagramSize = 0xFFFF; 00769 00770 return STATUS_SUCCESS; 00771 } 00772 } 00773 00774 return STATUS_NOT_IMPLEMENTED; 00775 } 00776 00777 00778 NTSTATUS DispTdiReceive( 00779 PIRP Irp) 00780 /* 00781 * FUNCTION: TDI_RECEIVE handler 00782 * ARGUMENTS: 00783 * Irp = Pointer to an I/O request packet 00784 * RETURNS: 00785 * Status of operation 00786 */ 00787 { 00788 PIO_STACK_LOCATION IrpSp; 00789 PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo; 00790 PTRANSPORT_CONTEXT TranContext; 00791 NTSTATUS Status; 00792 ULONG BytesReceived = 0; 00793 00794 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 00795 00796 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00797 ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters); 00798 00799 TranContext = IrpSp->FileObject->FsContext; 00800 if (TranContext == NULL) 00801 { 00802 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); 00803 Status = STATUS_INVALID_PARAMETER; 00804 goto done; 00805 } 00806 00807 if (TranContext->Handle.ConnectionContext == NULL) 00808 { 00809 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n")); 00810 Status = STATUS_INVALID_PARAMETER; 00811 goto done; 00812 } 00813 00814 /* Initialize a receive request */ 00815 Status = DispPrepareIrpForCancel 00816 (TranContext->Handle.ConnectionContext, 00817 Irp, 00818 (PDRIVER_CANCEL)DispCancelRequest); 00819 00820 TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress)); 00821 if (NT_SUCCESS(Status)) 00822 { 00823 Status = TCPReceiveData( 00824 TranContext->Handle.ConnectionContext, 00825 (PNDIS_BUFFER)Irp->MdlAddress, 00826 ReceiveInfo->ReceiveLength, 00827 &BytesReceived, 00828 ReceiveInfo->ReceiveFlags, 00829 DispDataRequestComplete, 00830 Irp); 00831 } 00832 00833 done: 00834 if (Status != STATUS_PENDING) { 00835 DispDataRequestComplete(Irp, Status, BytesReceived); 00836 } else 00837 IoMarkIrpPending(Irp); 00838 00839 TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status)); 00840 00841 return Status; 00842 } 00843 00844 00845 NTSTATUS DispTdiReceiveDatagram( 00846 PIRP Irp) 00847 /* 00848 * FUNCTION: TDI_RECEIVE_DATAGRAM handler 00849 * ARGUMENTS: 00850 * Irp = Pointer to an I/O request packet 00851 * RETURNS: 00852 * Status of operation 00853 */ 00854 { 00855 PIO_STACK_LOCATION IrpSp; 00856 PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo; 00857 PTRANSPORT_CONTEXT TranContext; 00858 TDI_REQUEST Request; 00859 NTSTATUS Status; 00860 ULONG BytesReceived = 0; 00861 00862 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 00863 00864 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00865 DgramInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&(IrpSp->Parameters); 00866 00867 TranContext = IrpSp->FileObject->FsContext; 00868 if (TranContext == NULL) 00869 { 00870 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); 00871 Status = STATUS_INVALID_PARAMETER; 00872 goto done; 00873 } 00874 00875 /* Initialize a receive request */ 00876 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle; 00877 Request.RequestNotifyObject = DispDataRequestComplete; 00878 Request.RequestContext = Irp; 00879 00880 Status = DispPrepareIrpForCancel( 00881 IrpSp->FileObject->FsContext, 00882 Irp, 00883 (PDRIVER_CANCEL)DispCancelRequest); 00884 00885 if (NT_SUCCESS(Status)) 00886 { 00887 PVOID DataBuffer; 00888 UINT BufferSize; 00889 00890 NdisQueryBuffer( (PNDIS_BUFFER)Irp->MdlAddress, 00891 &DataBuffer, 00892 &BufferSize ); 00893 00894 Status = DGReceiveDatagram( 00895 Request.Handle.AddressHandle, 00896 DgramInfo->ReceiveDatagramInformation, 00897 DataBuffer, 00898 DgramInfo->ReceiveLength, 00899 DgramInfo->ReceiveFlags, 00900 DgramInfo->ReturnDatagramInformation, 00901 &BytesReceived, 00902 (PDATAGRAM_COMPLETION_ROUTINE)DispDataRequestComplete, 00903 Irp, 00904 Irp); 00905 } 00906 00907 done: 00908 if (Status != STATUS_PENDING) { 00909 DispDataRequestComplete(Irp, Status, BytesReceived); 00910 } else 00911 IoMarkIrpPending(Irp); 00912 00913 TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status)); 00914 00915 return Status; 00916 } 00917 00918 00919 NTSTATUS DispTdiSend( 00920 PIRP Irp) 00921 /* 00922 * FUNCTION: TDI_SEND handler 00923 * ARGUMENTS: 00924 * Irp = Pointer to an I/O request packet 00925 * RETURNS: 00926 * Status of operation 00927 */ 00928 { 00929 PIO_STACK_LOCATION IrpSp; 00930 PTDI_REQUEST_KERNEL_SEND SendInfo; 00931 PTRANSPORT_CONTEXT TranContext; 00932 NTSTATUS Status; 00933 ULONG BytesSent = 0; 00934 00935 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 00936 00937 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00938 SendInfo = (PTDI_REQUEST_KERNEL_SEND)&(IrpSp->Parameters); 00939 00940 TranContext = IrpSp->FileObject->FsContext; 00941 if (TranContext == NULL) 00942 { 00943 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); 00944 Status = STATUS_INVALID_PARAMETER; 00945 goto done; 00946 } 00947 00948 if (TranContext->Handle.ConnectionContext == NULL) 00949 { 00950 TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n")); 00951 Status = STATUS_INVALID_PARAMETER; 00952 goto done; 00953 } 00954 00955 Status = DispPrepareIrpForCancel( 00956 IrpSp->FileObject->FsContext, 00957 Irp, 00958 (PDRIVER_CANCEL)DispCancelRequest); 00959 00960 TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress)); 00961 if (NT_SUCCESS(Status)) 00962 { 00963 PVOID Data; 00964 UINT Len; 00965 00966 NdisQueryBuffer( Irp->MdlAddress, &Data, &Len ); 00967 00968 TI_DbgPrint(MID_TRACE,("About to TCPSendData\n")); 00969 Status = TCPSendData( 00970 TranContext->Handle.ConnectionContext, 00971 Data, 00972 SendInfo->SendLength, 00973 &BytesSent, 00974 SendInfo->SendFlags, 00975 DispDataRequestComplete, 00976 Irp); 00977 } 00978 00979 done: 00980 if (Status != STATUS_PENDING) { 00981 DispDataRequestComplete(Irp, Status, BytesSent); 00982 } else 00983 IoMarkIrpPending(Irp); 00984 00985 TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status)); 00986 00987 return Status; 00988 } 00989 00990 00991 NTSTATUS DispTdiSendDatagram( 00992 PIRP Irp) 00993 /* 00994 * FUNCTION: TDI_SEND_DATAGRAM handler 00995 * ARGUMENTS: 00996 * Irp = Pointer to an I/O request packet 00997 * RETURNS: 00998 * Status of operation 00999 */ 01000 { 01001 PIO_STACK_LOCATION IrpSp; 01002 TDI_REQUEST Request; 01003 PTDI_REQUEST_KERNEL_SENDDG DgramInfo; 01004 PTRANSPORT_CONTEXT TranContext; 01005 NTSTATUS Status; 01006 01007 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 01008 01009 IrpSp = IoGetCurrentIrpStackLocation(Irp); 01010 DgramInfo = (PTDI_REQUEST_KERNEL_SENDDG)&(IrpSp->Parameters); 01011 01012 TranContext = IrpSp->FileObject->FsContext; 01013 if (TranContext == NULL) 01014 { 01015 TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); 01016 Status = STATUS_INVALID_PARAMETER; 01017 goto done; 01018 } 01019 01020 /* Initialize a send request */ 01021 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle; 01022 Request.RequestNotifyObject = DispDataRequestComplete; 01023 Request.RequestContext = Irp; 01024 01025 Status = DispPrepareIrpForCancel( 01026 IrpSp->FileObject->FsContext, 01027 Irp, 01028 (PDRIVER_CANCEL)DispCancelRequest); 01029 01030 if (NT_SUCCESS(Status)) { 01031 PVOID DataBuffer; 01032 UINT BufferSize; 01033 01034 TI_DbgPrint(MID_TRACE,("About to query buffer %x\n", Irp->MdlAddress)); 01035 01036 NdisQueryBuffer( (PNDIS_BUFFER)Irp->MdlAddress, 01037 &DataBuffer, 01038 &BufferSize ); 01039 01040 /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress 01041 must be of type PTDI_ADDRESS_IP */ 01042 TI_DbgPrint(MID_TRACE, 01043 ("About to call send routine %x\n", 01044 (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send))); 01045 01046 if( (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send != NULL) ) 01047 { 01048 ULONG DataUsed = 0; 01049 Status = (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)( 01050 Request.Handle.AddressHandle, 01051 DgramInfo->SendDatagramInformation, 01052 DataBuffer, 01053 BufferSize, 01054 &DataUsed); 01055 Irp->IoStatus.Information = DataUsed; 01056 } 01057 else { 01058 Status = STATUS_UNSUCCESSFUL; 01059 ASSERT(FALSE); 01060 } 01061 } 01062 01063 done: 01064 if (Status != STATUS_PENDING) { 01065 DispDataRequestComplete(Irp, Status, Irp->IoStatus.Information); 01066 } else 01067 IoMarkIrpPending(Irp); 01068 01069 TI_DbgPrint(DEBUG_IRP, ("Leaving.\n")); 01070 01071 return Status; 01072 } 01073 01074 01075 NTSTATUS DispTdiSetEventHandler(PIRP Irp) 01076 /* 01077 * FUNCTION: TDI_SET_EVENT_HANDER handler 01078 * ARGUMENTS: 01079 * Irp = Pointer to a I/O request packet 01080 * RETURNS: 01081 * Status of operation 01082 */ 01083 { 01084 PTDI_REQUEST_KERNEL_SET_EVENT Parameters; 01085 PTRANSPORT_CONTEXT TranContext; 01086 PIO_STACK_LOCATION IrpSp; 01087 PADDRESS_FILE AddrFile; 01088 NTSTATUS Status; 01089 KIRQL OldIrql; 01090 01091 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 01092 01093 IrpSp = IoGetCurrentIrpStackLocation(Irp); 01094 01095 /* Get associated address file object. Quit if none exists */ 01096 01097 TranContext = IrpSp->FileObject->FsContext; 01098 if (!TranContext) { 01099 TI_DbgPrint(MIN_TRACE, ("Bad transport context.\n")); 01100 return STATUS_INVALID_PARAMETER; 01101 } 01102 01103 AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; 01104 if (!AddrFile) { 01105 TI_DbgPrint(MIN_TRACE, ("No address file object.\n")); 01106 return STATUS_INVALID_PARAMETER; 01107 } 01108 01109 Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters; 01110 Status = STATUS_SUCCESS; 01111 01112 LockObject(AddrFile, &OldIrql); 01113 01114 /* Set the event handler. if an event handler is associated with 01115 a specific event, it's flag (RegisteredXxxHandler) is TRUE. 01116 If an event handler is not used it's flag is FALSE */ 01117 switch (Parameters->EventType) { 01118 case TDI_EVENT_CONNECT: 01119 if (!Parameters->EventHandler) { 01120 AddrFile->ConnectHandlerContext = NULL; 01121 AddrFile->RegisteredConnectHandler = FALSE; 01122 } else { 01123 AddrFile->ConnectHandler = 01124 (PTDI_IND_CONNECT)Parameters->EventHandler; 01125 AddrFile->ConnectHandlerContext = Parameters->EventContext; 01126 AddrFile->RegisteredConnectHandler = TRUE; 01127 } 01128 break; 01129 01130 case TDI_EVENT_DISCONNECT: 01131 if (!Parameters->EventHandler) { 01132 AddrFile->DisconnectHandlerContext = NULL; 01133 AddrFile->RegisteredDisconnectHandler = FALSE; 01134 } else { 01135 AddrFile->DisconnectHandler = 01136 (PTDI_IND_DISCONNECT)Parameters->EventHandler; 01137 AddrFile->DisconnectHandlerContext = Parameters->EventContext; 01138 AddrFile->RegisteredDisconnectHandler = TRUE; 01139 } 01140 break; 01141 01142 case TDI_EVENT_ERROR: 01143 if (Parameters->EventHandler == NULL) { 01144 AddrFile->ErrorHandlerContext = NULL; 01145 AddrFile->RegisteredErrorHandler = FALSE; 01146 } else { 01147 AddrFile->ErrorHandler = 01148 (PTDI_IND_ERROR)Parameters->EventHandler; 01149 AddrFile->ErrorHandlerContext = Parameters->EventContext; 01150 AddrFile->RegisteredErrorHandler = TRUE; 01151 } 01152 break; 01153 01154 case TDI_EVENT_RECEIVE: 01155 if (Parameters->EventHandler == NULL) { 01156 AddrFile->ReceiveHandlerContext = NULL; 01157 AddrFile->RegisteredReceiveHandler = FALSE; 01158 } else { 01159 AddrFile->ReceiveHandler = 01160 (PTDI_IND_RECEIVE)Parameters->EventHandler; 01161 AddrFile->ReceiveHandlerContext = Parameters->EventContext; 01162 AddrFile->RegisteredReceiveHandler = TRUE; 01163 } 01164 break; 01165 01166 case TDI_EVENT_RECEIVE_DATAGRAM: 01167 if (Parameters->EventHandler == NULL) { 01168 AddrFile->ReceiveDatagramHandlerContext = NULL; 01169 AddrFile->RegisteredReceiveDatagramHandler = FALSE; 01170 } else { 01171 AddrFile->ReceiveDatagramHandler = 01172 (PTDI_IND_RECEIVE_DATAGRAM)Parameters->EventHandler; 01173 AddrFile->ReceiveDatagramHandlerContext = Parameters->EventContext; 01174 AddrFile->RegisteredReceiveDatagramHandler = TRUE; 01175 } 01176 break; 01177 01178 case TDI_EVENT_RECEIVE_EXPEDITED: 01179 if (Parameters->EventHandler == NULL) { 01180 AddrFile->ExpeditedReceiveHandlerContext = NULL; 01181 AddrFile->RegisteredExpeditedReceiveHandler = FALSE; 01182 } else { 01183 AddrFile->ExpeditedReceiveHandler = 01184 (PTDI_IND_RECEIVE_EXPEDITED)Parameters->EventHandler; 01185 AddrFile->ExpeditedReceiveHandlerContext = Parameters->EventContext; 01186 AddrFile->RegisteredExpeditedReceiveHandler = TRUE; 01187 } 01188 break; 01189 01190 case TDI_EVENT_CHAINED_RECEIVE: 01191 if (Parameters->EventHandler == NULL) { 01192 AddrFile->ChainedReceiveHandlerContext = NULL; 01193 AddrFile->RegisteredChainedReceiveHandler = FALSE; 01194 } else { 01195 AddrFile->ChainedReceiveHandler = 01196 (PTDI_IND_CHAINED_RECEIVE)Parameters->EventHandler; 01197 AddrFile->ChainedReceiveHandlerContext = Parameters->EventContext; 01198 AddrFile->RegisteredChainedReceiveHandler = TRUE; 01199 } 01200 break; 01201 01202 case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM: 01203 if (Parameters->EventHandler == NULL) { 01204 AddrFile->ChainedReceiveDatagramHandlerContext = NULL; 01205 AddrFile->RegisteredChainedReceiveDatagramHandler = FALSE; 01206 } else { 01207 AddrFile->ChainedReceiveDatagramHandler = 01208 (PTDI_IND_CHAINED_RECEIVE_DATAGRAM)Parameters->EventHandler; 01209 AddrFile->ChainedReceiveDatagramHandlerContext = Parameters->EventContext; 01210 AddrFile->RegisteredChainedReceiveDatagramHandler = TRUE; 01211 } 01212 break; 01213 01214 case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED: 01215 if (Parameters->EventHandler == NULL) { 01216 AddrFile->ChainedReceiveExpeditedHandlerContext = NULL; 01217 AddrFile->RegisteredChainedReceiveExpeditedHandler = FALSE; 01218 } else { 01219 AddrFile->ChainedReceiveExpeditedHandler = 01220 (PTDI_IND_CHAINED_RECEIVE_EXPEDITED)Parameters->EventHandler; 01221 AddrFile->ChainedReceiveExpeditedHandlerContext = Parameters->EventContext; 01222 AddrFile->RegisteredChainedReceiveExpeditedHandler = TRUE; 01223 } 01224 break; 01225 01226 default: 01227 TI_DbgPrint(MIN_TRACE, ("Unknown event type (0x%X).\n", 01228 Parameters->EventType)); 01229 01230 Status = STATUS_INVALID_PARAMETER; 01231 } 01232 01233 UnlockObject(AddrFile, OldIrql); 01234 01235 return Status; 01236 } 01237 01238 01239 NTSTATUS DispTdiSetInformation( 01240 PIRP Irp) 01241 /* 01242 * FUNCTION: TDI_SET_INFORMATION handler 01243 * ARGUMENTS: 01244 * Irp = Pointer to an I/O request packet 01245 * RETURNS: 01246 * Status of operation 01247 */ 01248 { 01249 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 01250 01251 return STATUS_NOT_IMPLEMENTED; 01252 } 01253 01254 01255 VOID DispTdiQueryInformationExComplete( 01256 PVOID Context, 01257 ULONG Status, 01258 UINT ByteCount) 01259 /* 01260 * FUNCTION: Completes a TDI QueryInformationEx request 01261 * ARGUMENTS: 01262 * Context = Pointer to the IRP for the request 01263 * Status = TDI status of the request 01264 * ByteCount = Number of bytes returned in output buffer 01265 */ 01266 { 01267 PTI_QUERY_CONTEXT QueryContext; 01268 01269 QueryContext = (PTI_QUERY_CONTEXT)Context; 01270 if (NT_SUCCESS(Status)) { 01271 CopyBufferToBufferChain( 01272 QueryContext->InputMdl, 01273 FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX, Context), 01274 (PCHAR)&QueryContext->QueryInfo.Context, 01275 CONTEXT_SIZE); 01276 } 01277 01278 MmUnlockPages(QueryContext->InputMdl); 01279 IoFreeMdl(QueryContext->InputMdl); 01280 if( QueryContext->OutputMdl ) { 01281 MmUnlockPages(QueryContext->OutputMdl); 01282 IoFreeMdl(QueryContext->OutputMdl); 01283 } 01284 01285 QueryContext->Irp->IoStatus.Information = ByteCount; 01286 QueryContext->Irp->IoStatus.Status = Status; 01287 01288 ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG); 01289 } 01290 01291 01292 NTSTATUS DispTdiQueryInformationEx( 01293 PIRP Irp, 01294 PIO_STACK_LOCATION IrpSp) 01295 /* 01296 * FUNCTION: TDI QueryInformationEx handler 01297 * ARGUMENTS: 01298 * Irp = Pointer to I/O request packet 01299 * IrpSp = Pointer to current stack location of Irp 01300 * RETURNS: 01301 * Status of operation 01302 */ 01303 { 01304 PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer; 01305 PTRANSPORT_CONTEXT TranContext; 01306 PTI_QUERY_CONTEXT QueryContext; 01307 PVOID OutputBuffer; 01308 TDI_REQUEST Request; 01309 UINT Size; 01310 UINT InputBufferLength; 01311 UINT OutputBufferLength; 01312 BOOLEAN InputMdlLocked = FALSE; 01313 BOOLEAN OutputMdlLocked = FALSE; 01314 PMDL InputMdl = NULL; 01315 PMDL OutputMdl = NULL; 01316 NTSTATUS Status = STATUS_SUCCESS; 01317 01318 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 01319 01320 TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext; 01321 01322 switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) { 01323 case TDI_TRANSPORT_ADDRESS_FILE: 01324 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle; 01325 break; 01326 01327 case TDI_CONNECTION_FILE: 01328 Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext; 01329 break; 01330 01331 case TDI_CONTROL_CHANNEL_FILE: 01332 Request.Handle.ControlChannel = TranContext->Handle.ControlChannel; 01333 break; 01334 01335 default: 01336 TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n")); 01337 return STATUS_INVALID_PARAMETER; 01338 } 01339 01340 InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength; 01341 OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; 01342 01343 /* Validate parameters */ 01344 if ((InputBufferLength == sizeof(TCP_REQUEST_QUERY_INFORMATION_EX)) && 01345 (OutputBufferLength != 0)) { 01346 01347 InputBuffer = (PTCP_REQUEST_QUERY_INFORMATION_EX) 01348 IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; 01349 OutputBuffer = Irp->UserBuffer; 01350 01351 QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG); 01352 if (QueryContext) { 01353 _SEH2_TRY { 01354 InputMdl = IoAllocateMdl(InputBuffer, 01355 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX), 01356 FALSE, TRUE, NULL); 01357 01358 OutputMdl = IoAllocateMdl(OutputBuffer, 01359 OutputBufferLength, FALSE, TRUE, NULL); 01360 01361 if (InputMdl && OutputMdl) { 01362 01363 MmProbeAndLockPages(InputMdl, Irp->RequestorMode, 01364 IoModifyAccess); 01365 01366 InputMdlLocked = TRUE; 01367 01368 MmProbeAndLockPages(OutputMdl, Irp->RequestorMode, 01369 IoWriteAccess); 01370 01371 OutputMdlLocked = TRUE; 01372 01373 RtlCopyMemory(&QueryContext->QueryInfo, 01374 InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX)); 01375 } else 01376 Status = STATUS_INSUFFICIENT_RESOURCES; 01377 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { 01378 Status = _SEH2_GetExceptionCode(); 01379 } _SEH2_END; 01380 01381 if (NT_SUCCESS(Status)) { 01382 Size = MmGetMdlByteCount(OutputMdl); 01383 01384 QueryContext->Irp = Irp; 01385 QueryContext->InputMdl = InputMdl; 01386 QueryContext->OutputMdl = OutputMdl; 01387 01388 Request.RequestNotifyObject = DispTdiQueryInformationExComplete; 01389 Request.RequestContext = QueryContext; 01390 Status = InfoTdiQueryInformationEx(&Request, 01391 &QueryContext->QueryInfo.ID, OutputMdl, 01392 &Size, &QueryContext->QueryInfo.Context); 01393 DispTdiQueryInformationExComplete(QueryContext, Status, Size); 01394 01395 TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status)); 01396 01397 return Status; 01398 } 01399 01400 /* An error occurred if we get here */ 01401 01402 if (InputMdl) { 01403 if (InputMdlLocked) 01404 MmUnlockPages(InputMdl); 01405 IoFreeMdl(InputMdl); 01406 } 01407 01408 if (OutputMdl) { 01409 if (OutputMdlLocked) 01410 MmUnlockPages(OutputMdl); 01411 IoFreeMdl(OutputMdl); 01412 } 01413 01414 ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG); 01415 } else 01416 Status = STATUS_INSUFFICIENT_RESOURCES; 01417 } else if( InputBufferLength == 01418 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX) ) { 01419 /* Handle the case where the user is probing the buffer for length */ 01420 TI_DbgPrint(MAX_TRACE, ("InputBufferLength %d OutputBufferLength %d\n", 01421 InputBufferLength, OutputBufferLength)); 01422 InputBuffer = (PTCP_REQUEST_QUERY_INFORMATION_EX) 01423 IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; 01424 01425 Size = 0; 01426 01427 QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG); 01428 if (!QueryContext) return STATUS_INSUFFICIENT_RESOURCES; 01429 01430 _SEH2_TRY { 01431 InputMdl = IoAllocateMdl(InputBuffer, 01432 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX), 01433 FALSE, TRUE, NULL); 01434 01435 MmProbeAndLockPages(InputMdl, Irp->RequestorMode, 01436 IoModifyAccess); 01437 01438 InputMdlLocked = TRUE; 01439 Status = STATUS_SUCCESS; 01440 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { 01441 TI_DbgPrint(MAX_TRACE, ("Failed to acquire client buffer\n")); 01442 Status = _SEH2_GetExceptionCode(); 01443 } _SEH2_END; 01444 01445 if( !NT_SUCCESS(Status) || !InputMdl ) { 01446 if( InputMdl ) IoFreeMdl( InputMdl ); 01447 ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG); 01448 return Status; 01449 } 01450 01451 RtlCopyMemory(&QueryContext->QueryInfo, 01452 InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX)); 01453 01454 QueryContext->Irp = Irp; 01455 QueryContext->InputMdl = InputMdl; 01456 QueryContext->OutputMdl = NULL; 01457 01458 Request.RequestNotifyObject = DispTdiQueryInformationExComplete; 01459 Request.RequestContext = QueryContext; 01460 Status = InfoTdiQueryInformationEx(&Request, 01461 &QueryContext->QueryInfo.ID, 01462 NULL, 01463 &Size, 01464 &QueryContext->QueryInfo.Context); 01465 DispTdiQueryInformationExComplete(QueryContext, Status, Size); 01466 TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status)); 01467 } else Status = STATUS_INVALID_PARAMETER; 01468 01469 TI_DbgPrint(MIN_TRACE, ("Leaving. Status = (0x%X)\n", Status)); 01470 01471 return Status; 01472 } 01473 01474 01475 NTSTATUS DispTdiSetInformationEx( 01476 PIRP Irp, 01477 PIO_STACK_LOCATION IrpSp) 01478 /* 01479 * FUNCTION: TDI SetInformationEx handler 01480 * ARGUMENTS: 01481 * Irp = Pointer to I/O request packet 01482 * IrpSp = Pointer to current stack location of Irp 01483 * RETURNS: 01484 * Status of operation 01485 */ 01486 { 01487 PTRANSPORT_CONTEXT TranContext; 01488 PTCP_REQUEST_SET_INFORMATION_EX Info; 01489 TDI_REQUEST Request; 01490 TDI_STATUS Status; 01491 01492 TI_DbgPrint(DEBUG_IRP, ("Called.\n")); 01493 01494 TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext; 01495 Info = (PTCP_REQUEST_SET_INFORMATION_EX)Irp->AssociatedIrp.SystemBuffer; 01496 01497 switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) { 01498 case TDI_TRANSPORT_ADDRESS_FILE: 01499 Request.Handle.AddressHandle = TranContext->Handle.AddressHandle; 01500 break; 01501 01502 case TDI_CONNECTION_FILE: 01503 Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext; 01504 break; 01505 01506 case TDI_CONTROL_CHANNEL_FILE: 01507 Request.Handle.ControlChannel = TranContext->Handle.ControlChannel; 01508 break; 01509 01510 default: 01511 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 01512 Irp->IoStatus.Information = 0; 01513 01514 TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp)); 01515 01516 return Irp->IoStatus.Status; 01517 } 01518 01519 Request.RequestNotifyObject = NULL; 01520 Request.RequestContext = NULL; 01521 01522 Status = InfoTdiSetInformationEx(&Request, &Info->ID, 01523 &Info->Buffer, Info->BufferSize); 01524 01525 return Status; 01526 } 01527 01528 /* TODO: Support multiple addresses per interface. 01529 * For now just set the nte context to the interface index. 01530 * 01531 * Later on, create an NTE context and NTE instance 01532 */ 01533 01534 NTSTATUS DispTdiSetIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) { 01535 NTSTATUS Status = STATUS_DEVICE_DOES_NOT_EXIST; 01536 PIP_SET_ADDRESS IpAddrChange = 01537 (PIP_SET_ADDRESS)Irp->AssociatedIrp.SystemBuffer; 01538 IF_LIST_ITER(IF); 01539 01540 TI_DbgPrint(MID_TRACE,("Setting IP Address for adapter %d\n", 01541 IpAddrChange->NteIndex)); 01542 01543 ForEachInterface(IF) { 01544 TI_DbgPrint(MID_TRACE,("Looking at adapter %d\n", IF->Index)); 01545 01546 if( IF->Unicast.Address.IPv4Address == IpAddrChange->Address ) { 01547 Status = STATUS_DUPLICATE_OBJECTID; 01548 break; 01549 } 01550 if( IF->Index == IpAddrChange->NteIndex ) { 01551 IPRemoveInterfaceRoute( IF ); 01552 01553 IF->Unicast.Type = IP_ADDRESS_V4; 01554 IF->Unicast.Address.IPv4Address = IpAddrChange->Address; 01555 01556 IF->Netmask.Type = IP_ADDRESS_V4; 01557 IF->Netmask.Address.IPv4Address = IpAddrChange->Netmask; 01558 01559 IF->Broadcast.Type = IP_ADDRESS_V4; 01560 IF->Broadcast.Address.IPv4Address = 01561 IF->Unicast.Address.IPv4Address | 01562 ~IF->Netmask.Address.IPv4Address; 01563 01564 TI_DbgPrint(MID_TRACE,("New Unicast Address: %x\n", 01565 IF->Unicast.Address.IPv4Address)); 01566 TI_DbgPrint(MID_TRACE,("New Netmask : %x\n", 01567 IF->Netmask.Address.IPv4Address)); 01568 01569 IPAddInterfaceRoute( IF ); 01570 01571 IpAddrChange->Address = IF->Index; 01572 Status = STATUS_SUCCESS; 01573 Irp->IoStatus.Information = IF->Index; 01574 break; 01575 } 01576 } EndFor(IF); 01577 01578 Irp->IoStatus.Status = Status; 01579 return Status; 01580 } 01581 01582 NTSTATUS DispTdiDeleteIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) { 01583 NTSTATUS Status = STATUS_UNSUCCESSFUL; 01584 PUSHORT NteIndex = Irp->AssociatedIrp.SystemBuffer; 01585 IF_LIST_ITER(IF); 01586 01587 ForEachInterface(IF) { 01588 if( IF->Index == *NteIndex ) { 01589 IPRemoveInterfaceRoute( IF ); 01590 IF->Unicast.Type = IP_ADDRESS_V4; 01591 IF->Unicast.Address.IPv4Address = 0; 01592 01593 IF->Netmask.Type = IP_ADDRESS_V4; 01594 IF->Netmask.Address.IPv4Address = 0; 01595 01596 IF->Broadcast.Type = IP_ADDRESS_V4; 01597 IF->Broadcast.Address.IPv4Address = 0; 01598 01599 Status = STATUS_SUCCESS; 01600 } 01601 } EndFor(IF); 01602 01603 Irp->IoStatus.Status = Status; 01604 return Status; 01605 } 01606 01607 /* EOF */ Generated on Thu May 24 2012 04:20:31 for ReactOS by
1.7.6.1
|