Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentcp.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: transport/tcp/tcp.c 00005 * PURPOSE: Transmission Control Protocol 00006 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) 00007 * Art Yerkes (arty@users.sf.net) 00008 * REVISIONS: 00009 * CSH 01/08-2000 Created 00010 * arty 12/21/2004 Added accept 00011 */ 00012 00013 #include "precomp.h" 00014 00015 LONG TCP_IPIdentification = 0; 00016 static BOOLEAN TCPInitialized = FALSE; 00017 PORT_SET TCPPorts; 00018 00019 #include "lwip/pbuf.h" 00020 #include "lwip/ip.h" 00021 #include "lwip/init.h" 00022 #include "lwip/arch.h" 00023 00024 #include "rosip.h" 00025 00026 NPAGED_LOOKASIDE_LIST TdiBucketLookasideList; 00027 00028 VOID NTAPI 00029 DisconnectTimeoutDpc(PKDPC Dpc, 00030 PVOID DeferredContext, 00031 PVOID SystemArgument1, 00032 PVOID SystemArgument2) 00033 { 00034 PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)DeferredContext; 00035 PLIST_ENTRY Entry; 00036 PTDI_BUCKET Bucket; 00037 00038 LockObjectAtDpcLevel(Connection); 00039 00040 /* We timed out waiting for pending sends so force it to shutdown */ 00041 TCPTranslateError(LibTCPShutdown(Connection, 0, 1)); 00042 00043 while (!IsListEmpty(&Connection->SendRequest)) 00044 { 00045 Entry = RemoveHeadList(&Connection->SendRequest); 00046 00047 Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry); 00048 00049 Bucket->Information = 0; 00050 Bucket->Status = STATUS_FILE_CLOSED; 00051 00052 CompleteBucket(Connection, Bucket, FALSE); 00053 } 00054 00055 while (!IsListEmpty(&Connection->ShutdownRequest)) 00056 { 00057 Entry = RemoveHeadList( &Connection->ShutdownRequest ); 00058 00059 Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); 00060 00061 Bucket->Status = STATUS_TIMEOUT; 00062 Bucket->Information = 0; 00063 00064 CompleteBucket(Connection, Bucket, FALSE); 00065 } 00066 00067 UnlockObjectFromDpcLevel(Connection); 00068 00069 DereferenceObject(Connection); 00070 } 00071 00072 VOID ConnectionFree(PVOID Object) 00073 { 00074 PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)Object; 00075 KIRQL OldIrql; 00076 00077 TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n")); 00078 00079 TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); 00080 RemoveEntryList(&Connection->ListEntry); 00081 TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); 00082 00083 ExFreePoolWithTag( Connection, CONN_ENDPT_TAG ); 00084 } 00085 00086 PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) 00087 { 00088 PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT) 00089 ExAllocatePoolWithTag(NonPagedPool, sizeof(CONNECTION_ENDPOINT), CONN_ENDPT_TAG); 00090 00091 if (!Connection) 00092 return Connection; 00093 00094 TI_DbgPrint(DEBUG_CPOINT, ("Connection point file object allocated at (0x%X).\n", Connection)); 00095 00096 RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT)); 00097 00098 /* Initialize spin lock that protects the connection endpoint file object */ 00099 KeInitializeSpinLock(&Connection->Lock); 00100 InitializeListHead(&Connection->ConnectRequest); 00101 InitializeListHead(&Connection->ListenRequest); 00102 InitializeListHead(&Connection->ReceiveRequest); 00103 InitializeListHead(&Connection->SendRequest); 00104 InitializeListHead(&Connection->ShutdownRequest); 00105 InitializeListHead(&Connection->PacketQueue); 00106 00107 /* Initialize disconnect timer */ 00108 KeInitializeTimer(&Connection->DisconnectTimer); 00109 KeInitializeDpc(&Connection->DisconnectDpc, DisconnectTimeoutDpc, Connection); 00110 00111 /* Save client context pointer */ 00112 Connection->ClientContext = ClientContext; 00113 00114 Connection->RefCount = 1; 00115 Connection->Free = ConnectionFree; 00116 00117 /* Add connection endpoint to global list */ 00118 ExInterlockedInsertTailList(&ConnectionEndpointListHead, 00119 &Connection->ListEntry, 00120 &ConnectionEndpointListLock); 00121 00122 return Connection; 00123 } 00124 00125 NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, 00126 UINT Family, UINT Type, UINT Proto ) 00127 { 00128 NTSTATUS Status; 00129 KIRQL OldIrql; 00130 00131 LockObject(Connection, &OldIrql); 00132 00133 TI_DbgPrint(DEBUG_TCP,("[IP, TCPSocket] Called: Connection %x, Family %d, Type %d, " 00134 "Proto %d, sizeof(CONNECTION_ENDPOINT) = %d\n", 00135 Connection, Family, Type, Proto, sizeof(CONNECTION_ENDPOINT))); 00136 00137 Connection->SocketContext = LibTCPSocket(Connection); 00138 if (Connection->SocketContext) 00139 Status = STATUS_SUCCESS; 00140 else 00141 Status = STATUS_INSUFFICIENT_RESOURCES; 00142 00143 UnlockObject(Connection, OldIrql); 00144 00145 TI_DbgPrint(DEBUG_TCP,("[IP, TCPSocket] Leaving. Status = 0x%x\n", Status)); 00146 00147 return Status; 00148 } 00149 00150 NTSTATUS TCPClose( PCONNECTION_ENDPOINT Connection ) 00151 { 00152 KIRQL OldIrql; 00153 00154 LockObject(Connection, &OldIrql); 00155 00156 FlushAllQueues(Connection, STATUS_CANCELLED); 00157 00158 LibTCPClose(Connection, FALSE, TRUE); 00159 00160 UnlockObject(Connection, OldIrql); 00161 00162 DereferenceObject(Connection); 00163 00164 return STATUS_SUCCESS; 00165 } 00166 00167 VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket) 00168 /* 00169 * FUNCTION: Receives and queues TCP data 00170 * ARGUMENTS: 00171 * IPPacket = Pointer to an IP packet that was received 00172 * NOTES: 00173 * This is the low level interface for receiving TCP data 00174 */ 00175 { 00176 TI_DbgPrint(DEBUG_TCP,("Sending packet %d (%d) to lwIP\n", 00177 IPPacket->TotalSize, 00178 IPPacket->HeaderSize)); 00179 00180 LibIPInsertPacket(Interface->TCPContext, IPPacket->Header, IPPacket->TotalSize); 00181 } 00182 00183 NTSTATUS TCPStartup(VOID) 00184 /* 00185 * FUNCTION: Initializes the TCP subsystem 00186 * RETURNS: 00187 * Status of operation 00188 */ 00189 { 00190 NTSTATUS Status; 00191 00192 Status = PortsStartup( &TCPPorts, 1, 0xfffe ); 00193 if (!NT_SUCCESS(Status)) 00194 { 00195 return Status; 00196 } 00197 00198 ExInitializeNPagedLookasideList(&TdiBucketLookasideList, 00199 NULL, 00200 NULL, 00201 0, 00202 sizeof(TDI_BUCKET), 00203 TDI_BUCKET_TAG, 00204 0); 00205 00206 /* Initialize our IP library */ 00207 LibIPInitialize(); 00208 00209 /* Register this protocol with IP layer */ 00210 IPRegisterProtocol(IPPROTO_TCP, TCPReceive); 00211 00212 TCPInitialized = TRUE; 00213 00214 return STATUS_SUCCESS; 00215 } 00216 00217 00218 NTSTATUS TCPShutdown(VOID) 00219 /* 00220 * FUNCTION: Shuts down the TCP subsystem 00221 * RETURNS: 00222 * Status of operation 00223 */ 00224 { 00225 if (!TCPInitialized) 00226 return STATUS_SUCCESS; 00227 00228 ExDeleteNPagedLookasideList(&TdiBucketLookasideList); 00229 00230 LibIPShutdown(); 00231 00232 /* Deregister this protocol with IP layer */ 00233 IPRegisterProtocol(IPPROTO_TCP, NULL); 00234 00235 TCPInitialized = FALSE; 00236 00237 PortsShutdown( &TCPPorts ); 00238 00239 return STATUS_SUCCESS; 00240 } 00241 00242 NTSTATUS TCPTranslateError(const err_t err) 00243 { 00244 NTSTATUS Status; 00245 00246 switch (err) 00247 { 00248 case ERR_OK: Status = STATUS_SUCCESS; return Status; //0 00249 case ERR_MEM: Status = STATUS_INSUFFICIENT_RESOURCES; break; //-1 00250 case ERR_BUF: Status = STATUS_BUFFER_TOO_SMALL; break; //-2 00251 case ERR_TIMEOUT: Status = STATUS_TIMEOUT; break; // -3 00252 case ERR_RTE: Status = STATUS_NETWORK_UNREACHABLE; break; //-4 00253 case ERR_INPROGRESS: Status = STATUS_PENDING; return Status; //-5 00254 case ERR_VAL: Status = STATUS_INVALID_PARAMETER; break; //-6 00255 case ERR_WOULDBLOCK: Status = STATUS_CANT_WAIT; break; //-7 00256 case ERR_USE: Status = STATUS_ADDRESS_ALREADY_EXISTS; break; //-8 00257 case ERR_ISCONN: Status = STATUS_UNSUCCESSFUL; break; //-9 (FIXME) 00258 case ERR_ABRT: Status = STATUS_LOCAL_DISCONNECT; break; //-10 00259 case ERR_RST: Status = STATUS_REMOTE_DISCONNECT; break; //-11 00260 case ERR_CLSD: Status = STATUS_FILE_CLOSED; break; //-12 00261 case ERR_CONN: Status = STATUS_INVALID_CONNECTION; break; //-13 00262 case ERR_ARG: Status = STATUS_INVALID_PARAMETER; break; //-14 00263 case ERR_IF: Status = STATUS_UNEXPECTED_NETWORK_ERROR; break; //-15 00264 default: 00265 DbgPrint("Invalid error value: %d\n", err); 00266 ASSERT(FALSE); 00267 Status = STATUS_UNSUCCESSFUL; 00268 break; 00269 } 00270 00271 DbgPrint("TCP operation failed: 0x%x (%d)\n", Status, err); 00272 00273 return Status; 00274 } 00275 00276 NTSTATUS TCPConnect 00277 ( PCONNECTION_ENDPOINT Connection, 00278 PTDI_CONNECTION_INFORMATION ConnInfo, 00279 PTDI_CONNECTION_INFORMATION ReturnInfo, 00280 PTCP_COMPLETION_ROUTINE Complete, 00281 PVOID Context ) 00282 { 00283 NTSTATUS Status; 00284 struct ip_addr bindaddr, connaddr; 00285 IP_ADDRESS RemoteAddress; 00286 USHORT RemotePort; 00287 TA_IP_ADDRESS LocalAddress; 00288 PTDI_BUCKET Bucket; 00289 PNEIGHBOR_CACHE_ENTRY NCE; 00290 KIRQL OldIrql; 00291 00292 TI_DbgPrint(DEBUG_TCP,("[IP, TCPConnect] Called\n")); 00293 00294 Status = AddrBuildAddress 00295 ((PTRANSPORT_ADDRESS)ConnInfo->RemoteAddress, 00296 &RemoteAddress, 00297 &RemotePort); 00298 00299 if (!NT_SUCCESS(Status)) 00300 { 00301 TI_DbgPrint(DEBUG_TCP, ("Could not AddrBuildAddress in TCPConnect\n")); 00302 return Status; 00303 } 00304 00305 /* Freed in TCPSocketState */ 00306 TI_DbgPrint(DEBUG_TCP, 00307 ("Connecting to address %x:%x\n", 00308 RemoteAddress.Address.IPv4Address, 00309 RemotePort)); 00310 00311 LockObject(Connection, &OldIrql); 00312 00313 if (!Connection->AddressFile) 00314 { 00315 UnlockObject(Connection, OldIrql); 00316 return STATUS_INVALID_PARAMETER; 00317 } 00318 00319 if (AddrIsUnspecified(&Connection->AddressFile->Address)) 00320 { 00321 if (!(NCE = RouteGetRouteToDestination(&RemoteAddress))) 00322 { 00323 UnlockObject(Connection, OldIrql); 00324 return STATUS_NETWORK_UNREACHABLE; 00325 } 00326 00327 bindaddr.addr = NCE->Interface->Unicast.Address.IPv4Address; 00328 } 00329 else 00330 { 00331 bindaddr.addr = Connection->AddressFile->Address.Address.IPv4Address; 00332 } 00333 00334 Status = TCPTranslateError(LibTCPBind(Connection, 00335 &bindaddr, 00336 Connection->AddressFile->Port)); 00337 00338 if (NT_SUCCESS(Status)) 00339 { 00340 /* Check if we had an unspecified port */ 00341 if (!Connection->AddressFile->Port) 00342 { 00343 /* We did, so we need to copy back the port */ 00344 Status = TCPGetSockAddress(Connection, (PTRANSPORT_ADDRESS)&LocalAddress, FALSE); 00345 if (NT_SUCCESS(Status)) 00346 { 00347 /* Allocate the port in the port bitmap */ 00348 Connection->AddressFile->Port = TCPAllocatePort(LocalAddress.Address[0].Address[0].sin_port); 00349 00350 /* This should never fail */ 00351 ASSERT(Connection->AddressFile->Port != 0xFFFF); 00352 } 00353 } 00354 00355 if (NT_SUCCESS(Status)) 00356 { 00357 connaddr.addr = RemoteAddress.Address.IPv4Address; 00358 00359 Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList); 00360 if (!Bucket) 00361 { 00362 UnlockObject(Connection, OldIrql); 00363 return STATUS_NO_MEMORY; 00364 } 00365 00366 Bucket->Request.RequestNotifyObject = (PVOID)Complete; 00367 Bucket->Request.RequestContext = Context; 00368 00369 InsertTailList( &Connection->ConnectRequest, &Bucket->Entry ); 00370 00371 Status = TCPTranslateError(LibTCPConnect(Connection, 00372 &connaddr, 00373 RemotePort)); 00374 } 00375 } 00376 00377 UnlockObject(Connection, OldIrql); 00378 00379 TI_DbgPrint(DEBUG_TCP,("[IP, TCPConnect] Leaving. Status = 0x%x\n", Status)); 00380 00381 return Status; 00382 } 00383 00384 NTSTATUS TCPDisconnect 00385 ( PCONNECTION_ENDPOINT Connection, 00386 UINT Flags, 00387 PLARGE_INTEGER Timeout, 00388 PTDI_CONNECTION_INFORMATION ConnInfo, 00389 PTDI_CONNECTION_INFORMATION ReturnInfo, 00390 PTCP_COMPLETION_ROUTINE Complete, 00391 PVOID Context ) 00392 { 00393 NTSTATUS Status = STATUS_INVALID_PARAMETER; 00394 PTDI_BUCKET Bucket; 00395 KIRQL OldIrql; 00396 LARGE_INTEGER ActualTimeout; 00397 00398 TI_DbgPrint(DEBUG_TCP,("[IP, TCPDisconnect] Called\n")); 00399 00400 LockObject(Connection, &OldIrql); 00401 00402 if (Connection->SocketContext) 00403 { 00404 if (Flags & TDI_DISCONNECT_RELEASE) 00405 { 00406 if (IsListEmpty(&Connection->SendRequest)) 00407 { 00408 Status = TCPTranslateError(LibTCPShutdown(Connection, 0, 1)); 00409 } 00410 else if (Timeout && Timeout->QuadPart == 0) 00411 { 00412 FlushSendQueue(Connection, STATUS_FILE_CLOSED, FALSE); 00413 TCPTranslateError(LibTCPShutdown(Connection, 0, 1)); 00414 Status = STATUS_TIMEOUT; 00415 } 00416 else 00417 { 00418 /* Use the timeout specified or 1 second if none was specified */ 00419 if (Timeout) 00420 { 00421 ActualTimeout = *Timeout; 00422 } 00423 else 00424 { 00425 ActualTimeout.QuadPart = -1000000; 00426 } 00427 00428 /* We couldn't complete the request now because we need to wait for outstanding I/O */ 00429 Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList); 00430 if (!Bucket) 00431 { 00432 UnlockObject(Connection, OldIrql); 00433 return STATUS_NO_MEMORY; 00434 } 00435 00436 Bucket->Request.RequestNotifyObject = (PVOID)Complete; 00437 Bucket->Request.RequestContext = Context; 00438 00439 InsertTailList(&Connection->ShutdownRequest, &Bucket->Entry); 00440 00441 ReferenceObject(Connection); 00442 if (KeCancelTimer(&Connection->DisconnectTimer)) 00443 { 00444 DereferenceObject(Connection); 00445 } 00446 KeSetTimer(&Connection->DisconnectTimer, ActualTimeout, &Connection->DisconnectDpc); 00447 00448 Status = STATUS_PENDING; 00449 } 00450 } 00451 00452 if ((Flags & TDI_DISCONNECT_ABORT) || !Flags) 00453 { 00454 FlushReceiveQueue(Connection, STATUS_FILE_CLOSED, FALSE); 00455 FlushSendQueue(Connection, STATUS_FILE_CLOSED, FALSE); 00456 FlushShutdownQueue(Connection, STATUS_FILE_CLOSED, FALSE); 00457 Status = TCPTranslateError(LibTCPShutdown(Connection, 1, 1)); 00458 } 00459 } 00460 else 00461 { 00462 /* We already got closed by the other side so just return success */ 00463 Status = STATUS_SUCCESS; 00464 } 00465 00466 UnlockObject(Connection, OldIrql); 00467 00468 TI_DbgPrint(DEBUG_TCP,("[IP, TCPDisconnect] Leaving. Status = 0x%x\n", Status)); 00469 00470 return Status; 00471 } 00472 00473 NTSTATUS TCPReceiveData 00474 ( PCONNECTION_ENDPOINT Connection, 00475 PNDIS_BUFFER Buffer, 00476 ULONG ReceiveLength, 00477 PULONG BytesReceived, 00478 ULONG ReceiveFlags, 00479 PTCP_COMPLETION_ROUTINE Complete, 00480 PVOID Context ) 00481 { 00482 PTDI_BUCKET Bucket; 00483 PUCHAR DataBuffer; 00484 UINT DataLen, Received; 00485 NTSTATUS Status; 00486 00487 TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Called for %d bytes (on socket %x)\n", 00488 ReceiveLength, Connection->SocketContext)); 00489 00490 NdisQueryBuffer(Buffer, &DataBuffer, &DataLen); 00491 00492 Status = LibTCPGetDataFromConnectionQueue(Connection, DataBuffer, DataLen, &Received); 00493 00494 if (Status == STATUS_PENDING) 00495 { 00496 Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList); 00497 if (!Bucket) 00498 { 00499 TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Failed to allocate bucket\n")); 00500 00501 return STATUS_NO_MEMORY; 00502 } 00503 00504 Bucket->Request.RequestNotifyObject = Complete; 00505 Bucket->Request.RequestContext = Context; 00506 00507 ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock ); 00508 TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Queued read irp\n")); 00509 00510 TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Leaving. Status = STATUS_PENDING\n")); 00511 00512 (*BytesReceived) = 0; 00513 } 00514 else 00515 { 00516 (*BytesReceived) = Received; 00517 } 00518 00519 return Status; 00520 } 00521 00522 NTSTATUS TCPSendData 00523 ( PCONNECTION_ENDPOINT Connection, 00524 PCHAR BufferData, 00525 ULONG SendLength, 00526 PULONG BytesSent, 00527 ULONG Flags, 00528 PTCP_COMPLETION_ROUTINE Complete, 00529 PVOID Context ) 00530 { 00531 NTSTATUS Status; 00532 PTDI_BUCKET Bucket; 00533 KIRQL OldIrql; 00534 00535 LockObject(Connection, &OldIrql); 00536 00537 TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Called for %d bytes (on socket %x)\n", 00538 SendLength, Connection->SocketContext)); 00539 00540 TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Connection = %x\n", Connection)); 00541 TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Connection->SocketContext = %x\n", 00542 Connection->SocketContext)); 00543 00544 Status = TCPTranslateError(LibTCPSend(Connection, 00545 BufferData, 00546 SendLength, 00547 FALSE)); 00548 00549 TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Send: %x, %d\n", Status, SendLength)); 00550 00551 /* Keep this request around ... there was no data yet */ 00552 if (Status == STATUS_PENDING) 00553 { 00554 /* Freed in TCPSocketState */ 00555 Bucket = ExAllocateFromNPagedLookasideList(&TdiBucketLookasideList); 00556 if (!Bucket) 00557 { 00558 UnlockObject(Connection, OldIrql); 00559 TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Failed to allocate bucket\n")); 00560 return STATUS_NO_MEMORY; 00561 } 00562 00563 Bucket->Request.RequestNotifyObject = Complete; 00564 Bucket->Request.RequestContext = Context; 00565 *BytesSent = 0; 00566 00567 InsertTailList( &Connection->SendRequest, &Bucket->Entry ); 00568 TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Queued write irp\n")); 00569 } 00570 else if (Status == STATUS_SUCCESS) 00571 { 00572 *BytesSent = SendLength; 00573 } 00574 else 00575 { 00576 *BytesSent = 0; 00577 } 00578 00579 UnlockObject(Connection, OldIrql); 00580 00581 TI_DbgPrint(DEBUG_TCP, ("[IP, TCPSendData] Leaving. Status = %x\n", Status)); 00582 00583 return Status; 00584 } 00585 00586 UINT TCPAllocatePort(const UINT HintPort) 00587 { 00588 if (HintPort) 00589 { 00590 if (AllocatePort(&TCPPorts, HintPort)) 00591 return HintPort; 00592 else 00593 { 00594 TI_DbgPrint(MID_TRACE,("We got a hint port but couldn't allocate it\n")); 00595 return (UINT)-1; 00596 } 00597 } 00598 else 00599 return AllocatePortFromRange( &TCPPorts, 1024, 5000 ); 00600 } 00601 00602 VOID TCPFreePort(const UINT Port) 00603 { 00604 DeallocatePort(&TCPPorts, Port); 00605 } 00606 00607 NTSTATUS TCPGetSockAddress 00608 ( PCONNECTION_ENDPOINT Connection, 00609 PTRANSPORT_ADDRESS Address, 00610 BOOLEAN GetRemote ) 00611 { 00612 PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address; 00613 struct ip_addr ipaddr; 00614 NTSTATUS Status; 00615 KIRQL OldIrql; 00616 00617 AddressIP->TAAddressCount = 1; 00618 AddressIP->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; 00619 AddressIP->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; 00620 00621 LockObject(Connection, &OldIrql); 00622 00623 if (GetRemote) 00624 { 00625 Status = TCPTranslateError(LibTCPGetPeerName(Connection->SocketContext, 00626 &ipaddr, 00627 &AddressIP->Address[0].Address[0].sin_port)); 00628 } 00629 else 00630 { 00631 Status = TCPTranslateError(LibTCPGetHostName(Connection->SocketContext, 00632 &ipaddr, 00633 &AddressIP->Address[0].Address[0].sin_port)); 00634 } 00635 00636 UnlockObject(Connection, OldIrql); 00637 00638 AddressIP->Address[0].Address[0].in_addr = ipaddr.addr; 00639 00640 RtlZeroMemory(&AddressIP->Address[0].Address[0].sin_zero, 00641 sizeof(AddressIP->Address[0].Address[0].sin_zero)); 00642 00643 return Status; 00644 } 00645 00646 BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) 00647 { 00648 PLIST_ENTRY Entry; 00649 PLIST_ENTRY ListHead[5]; 00650 KIRQL OldIrql; 00651 PTDI_BUCKET Bucket; 00652 UINT i = 0; 00653 BOOLEAN Found = FALSE; 00654 00655 ListHead[0] = &Endpoint->SendRequest; 00656 ListHead[1] = &Endpoint->ReceiveRequest; 00657 ListHead[2] = &Endpoint->ConnectRequest; 00658 ListHead[3] = &Endpoint->ListenRequest; 00659 ListHead[4] = &Endpoint->ShutdownRequest; 00660 00661 LockObject(Endpoint, &OldIrql); 00662 00663 for( i = 0; i < 5; i++ ) 00664 { 00665 for( Entry = ListHead[i]->Flink; 00666 Entry != ListHead[i]; 00667 Entry = Entry->Flink ) 00668 { 00669 Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); 00670 if( Bucket->Request.RequestContext == Irp ) 00671 { 00672 RemoveEntryList( &Bucket->Entry ); 00673 ExFreeToNPagedLookasideList(&TdiBucketLookasideList, Bucket); 00674 Found = TRUE; 00675 break; 00676 } 00677 } 00678 } 00679 00680 UnlockObject(Endpoint, OldIrql); 00681 00682 return Found; 00683 } 00684 00685 /* EOF */ Generated on Sun May 27 2012 04:17:11 for ReactOS by
1.7.6.1
|