/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/connect.c * PURPOSE: Ancillary functions driver * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net) * UPDATE HISTORY: * 20040708 Created */ #include "afd.h" NTSTATUS NTAPI AfdGetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; UNREFERENCED_PARAMETER(DeviceObject); AFD_DbgPrint(1,("(PID %lx) AfdGetConnectOptions: Called on %p\n", PsGetCurrentProcessId(), FCB)); if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (FCB->ConnectOptionsSize == 0) { AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n")); return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0); } ASSERT(FCB->ConnectOptions); if (FCB->FilledConnectOptions < BufferSize) BufferSize = FCB->FilledConnectOptions; RtlCopyMemory(Irp->UserBuffer, FCB->ConnectOptions, BufferSize); return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, BufferSize); } NTSTATUS NTAPI AfdSetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; PVOID ConnectOptions = LockRequest(Irp, IrpSp, FALSE, NULL); UINT ConnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; UNREFERENCED_PARAMETER(DeviceObject); AFD_DbgPrint(1,("(PID %lx) AfdSetConnectOptions: Called on %p\n", PsGetCurrentProcessId(), FCB)); if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (!ConnectOptions) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); if (FCB->ConnectOptions) { ExFreePoolWithTag(FCB->ConnectOptions, TAG_AFD_CONNECT_OPTIONS); FCB->ConnectOptions = NULL; FCB->ConnectOptionsSize = 0; FCB->FilledConnectOptions = 0; } FCB->ConnectOptions = ExAllocatePoolWithTag(PagedPool, ConnectOptionsSize, TAG_AFD_CONNECT_OPTIONS); if (!FCB->ConnectOptions) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); RtlCopyMemory(FCB->ConnectOptions, ConnectOptions, ConnectOptionsSize); FCB->ConnectOptionsSize = ConnectOptionsSize; return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0); } NTSTATUS NTAPI AfdSetConnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; PUINT ConnectOptionsSize = LockRequest(Irp, IrpSp, FALSE, NULL); UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; UNREFERENCED_PARAMETER(DeviceObject); AFD_DbgPrint(1,("(PID %lx) AfdSetConnectOptionsSize: Called on %p\n", PsGetCurrentProcessId(), FCB)); if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (!ConnectOptionsSize) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); if (BufferSize < sizeof(UINT)) { AFD_DbgPrint(MIN_TRACE,("Buffer too small\n")); return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0); } if (FCB->ConnectOptions) { ExFreePoolWithTag(FCB->ConnectOptions, TAG_AFD_CONNECT_OPTIONS); FCB->ConnectOptionsSize = 0; FCB->FilledConnectOptions = 0; } FCB->ConnectOptions = ExAllocatePoolWithTag(PagedPool, *ConnectOptionsSize, TAG_AFD_CONNECT_OPTIONS); if (!FCB->ConnectOptions) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); FCB->ConnectOptionsSize = *ConnectOptionsSize; return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0); } NTSTATUS NTAPI AfdGetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; UNREFERENCED_PARAMETER(DeviceObject); AFD_DbgPrint(1,("(PID %lx) AfdGetConnectData: Called on %p\n", PsGetCurrentProcessId(), FCB)); if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (FCB->ConnectDataSize == 0) { AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n")); return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0); } ASSERT(FCB->ConnectData); if (FCB->FilledConnectData < BufferSize) BufferSize = FCB->FilledConnectData; RtlCopyMemory(Irp->UserBuffer, FCB->ConnectData, BufferSize); return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, BufferSize); } NTSTATUS NTAPI AfdSetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; PVOID ConnectData = LockRequest(Irp, IrpSp, FALSE, NULL); UINT ConnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; UNREFERENCED_PARAMETER(DeviceObject); AFD_DbgPrint(1,("(PID %lx) AfdSetConnectData: Called on %p\n", PsGetCurrentProcessId(), FCB)); if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (!ConnectData) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); if (FCB->ConnectData) { ExFreePoolWithTag(FCB->ConnectData, TAG_AFD_CONNECT_DATA); FCB->ConnectData = NULL; FCB->ConnectDataSize = 0; FCB->FilledConnectData = 0; } FCB->ConnectData = ExAllocatePoolWithTag(PagedPool, ConnectDataSize, TAG_AFD_CONNECT_DATA); if (!FCB->ConnectData) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); RtlCopyMemory(FCB->ConnectData, ConnectData, ConnectDataSize); FCB->ConnectDataSize = ConnectDataSize; return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0); } NTSTATUS NTAPI AfdSetConnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; PUINT ConnectDataSize = LockRequest(Irp, IrpSp, FALSE, NULL); UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; UNREFERENCED_PARAMETER(DeviceObject); AFD_DbgPrint(1,("(PID %lx) AfdSetConnectDataSize: Called on %p\n", PsGetCurrentProcessId(), FCB)); if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (!ConnectDataSize) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); if (BufferSize < sizeof(UINT)) { AFD_DbgPrint(MIN_TRACE,("Buffer too small\n")); return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0); } if (FCB->ConnectData) { ExFreePoolWithTag(FCB->ConnectData, TAG_AFD_CONNECT_DATA); FCB->ConnectDataSize = 0; FCB->FilledConnectData = 0; } FCB->ConnectData = ExAllocatePoolWithTag(PagedPool, *ConnectDataSize, TAG_AFD_CONNECT_DATA); if (!FCB->ConnectData) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); FCB->ConnectDataSize = *ConnectDataSize; return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0); } NTSTATUS WarmSocketForConnection(PAFD_FCB FCB) { NTSTATUS Status; AFD_DbgPrint(1,("(PID %lx) WarmSocketForConnection: Called on %p\n", PsGetCurrentProcessId(), FCB)); if( !FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer ) { AFD_DbgPrint(MIN_TRACE,("Null Device\n")); return STATUS_NO_SUCH_DEVICE; } Status = TdiOpenConnectionEndpointFile(&FCB->TdiDeviceName, &FCB->Connection.Handle, &FCB->Connection.Object ); if( NT_SUCCESS(Status) ) { Status = TdiAssociateAddressFile( FCB->AddressFile.Handle, FCB->Connection.Object ); } return Status; } NTSTATUS MakeSocketIntoConnection(PAFD_FCB FCB) { NTSTATUS Status; ASSERT(!FCB->Recv.Window); ASSERT(!FCB->Send.Window); AFD_DbgPrint(1,("(PID %lx) MakeSocketIntoConnection: Called on %p\n", PsGetCurrentProcessId(), FCB)); if (!FCB->Recv.Size) { Status = TdiQueryMaxDatagramLength(FCB->Connection.Object, &FCB->Recv.Size); if (!NT_SUCCESS(Status)) return Status; } if (!FCB->Send.Size) { Status = TdiQueryMaxDatagramLength(FCB->Connection.Object, &FCB->Send.Size); if (!NT_SUCCESS(Status)) return Status; } /* Allocate the receive area and start receiving */ if (!FCB->Recv.Window) { FCB->Recv.Window = ExAllocatePoolWithTag(PagedPool, FCB->Recv.Size, TAG_AFD_DATA_BUFFER); if( !FCB->Recv.Window ) return STATUS_NO_MEMORY; } if (!FCB->Send.Window) { FCB->Send.Window = ExAllocatePoolWithTag(PagedPool, FCB->Send.Size, TAG_AFD_DATA_BUFFER); if( !FCB->Send.Window ) return STATUS_NO_MEMORY; } AFD_DbgPrint(1,("(PID %lx) MakeSocketIntoConnection: setting FCB->State to SOCKET_STATE_CONNECTED and calling TdiReceive().\n", PsGetCurrentProcessId())); FCB->State = SOCKET_STATE_CONNECTED; Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest, FCB->Connection.Object, TDI_RECEIVE_NORMAL, FCB->Recv.Window, FCB->Recv.Size, ReceiveComplete, FCB ); if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS; FCB->PollState |= AFD_EVENT_CONNECT | AFD_EVENT_SEND; FCB->PollStatus[FD_CONNECT_BIT] = STATUS_SUCCESS; FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; AFD_DbgPrint(1,("(PID %lx) MakeSocketIntoConnection: Calling PollReeval().\n", PsGetCurrentProcessId())); PollReeval( FCB->DeviceExt, FCB->FileObject ); AFD_DbgPrint(1,("(PID %lx) MakeSocketIntoConnection: completed returning Status.\n", PsGetCurrentProcessId())); return Status; } static IO_COMPLETION_ROUTINE StreamSocketConnectComplete; static NTSTATUS NTAPI StreamSocketConnectComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context) { NTSTATUS Status = Irp->IoStatus.Status; PAFD_FCB FCB = (PAFD_FCB)Context; PLIST_ENTRY NextIrpEntry; PIRP NextIrp; /* AFD_DbgPrint(1,("(PID %lx) StreamSocketConnectComplete: Called: FCB %p, FO %p\n", Context, FCB->FileObject)); */ AFD_DbgPrint(1,("(PID %lx) StreamSocketConnectComplete: Called on %p, FO %p\n", PsGetCurrentProcessId(), Context, FCB->FileObject)); /* I was wrong about this before as we can have pending writes to a not * yet connected socket */ if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; AFD_DbgPrint(MID_TRACE,("Irp->IoStatus.Status = %x\n", Irp->IoStatus.Status)); ASSERT(FCB->ConnectIrp.InFlightRequest == Irp); FCB->ConnectIrp.InFlightRequest = NULL; if( FCB->State == SOCKET_STATE_CLOSED ) { /* Cleanup our IRP queue because the FCB is being destroyed */ while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_CONNECT] ) ) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_CONNECT]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; NextIrp->IoStatus.Information = 0; if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } SocketStateUnlock( FCB ); return STATUS_FILE_CLOSED; } if( !NT_SUCCESS(Irp->IoStatus.Status) ) { FCB->PollState |= AFD_EVENT_CONNECT_FAIL; FCB->PollStatus[FD_CONNECT_BIT] = Irp->IoStatus.Status; AFD_DbgPrint(MID_TRACE,("Going to bound state\n")); FCB->State = SOCKET_STATE_BOUND; PollReeval( FCB->DeviceExt, FCB->FileObject ); } /* Succeed pending irps on the FUNCTION_CONNECT list */ while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_CONNECT] ) ) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_CONNECT]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); AFD_DbgPrint(MID_TRACE,("Completing connect %p\n", NextIrp)); NextIrp->IoStatus.Status = Status; NextIrp->IoStatus.Information = NT_SUCCESS(Status) ? ((ULONG_PTR)FCB->Connection.Handle) : 0; if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } if( NT_SUCCESS(Status) ) { Status = MakeSocketIntoConnection( FCB ); if( !NT_SUCCESS(Status) ) { SocketStateUnlock( FCB ); return Status; } FCB->FilledConnectData = MIN(FCB->ConnectReturnInfo->UserDataLength, FCB->ConnectDataSize); if (FCB->FilledConnectData) { RtlCopyMemory(FCB->ConnectData, FCB->ConnectReturnInfo->UserData, FCB->FilledConnectData); } FCB->FilledConnectOptions = MIN(FCB->ConnectReturnInfo->OptionsLength, FCB->ConnectOptionsSize); if (FCB->FilledConnectOptions) { RtlCopyMemory(FCB->ConnectOptions, FCB->ConnectReturnInfo->Options, FCB->FilledConnectOptions); } if( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); AFD_DbgPrint(MID_TRACE,("Launching send request %p\n", NextIrp)); Status = AfdConnectedSocketWriteData ( DeviceObject, NextIrp, IoGetCurrentIrpStackLocation( NextIrp ), FALSE ); } if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS; } SocketStateUnlock( FCB ); AFD_DbgPrint(1,("(PID %lx) StreamSocketConnectComplete: Returning %x\n", PsGetCurrentProcessId(), Status)); return Status; } /* Return the socket object for ths request only if it is a connected or stream type. */ NTSTATUS NTAPI AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { NTSTATUS Status = STATUS_INVALID_PARAMETER; PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; PAFD_CONNECT_INFO ConnectReq; AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB)); AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: Called on %p\n", PsGetCurrentProcessId(), FCB )); UNREFERENCED_PARAMETER(DeviceObject); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); if( !(ConnectReq = LockRequest( Irp, IrpSp, FALSE, NULL )) ) return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 ); AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: ConnectRequest Type: %u Address: %s\n", PsGetCurrentProcessId(), ConnectReq->RemoteAddress.Address[0].AddressType , ConnectReq->RemoteAddress.Address[0] )); AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: Connect request:\n", PsGetCurrentProcessId())); /* if 0 // DLB enabled this buffer display for testing */ OskitDumpBuffer ( (PCHAR)ConnectReq, IrpSp->Parameters.DeviceIoControl.InputBufferLength ); /* endif */ if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS ) { AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: Connectionless mode.\n", PsGetCurrentProcessId())); if (FCB->RemoteAddress) { ExFreePoolWithTag(FCB->RemoteAddress, TAG_AFD_TRANSPORT_ADDRESS); } AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: Copy RemoteAddress.\n", PsGetCurrentProcessId())); FCB->RemoteAddress = TaCopyTransportAddress( &ConnectReq->RemoteAddress ); // <=== send REQUIRES THIS TO USE FCB->RemoteAddress if( !FCB->RemoteAddress ) Status = STATUS_NO_MEMORY; // START OF DLB HACK FOR STORING REMOTE ADDRESS FOR USE BY SENDTO else { /* DLB originally datagram code exited here, these are the next steps used in stream code, we do parts of it without actually calling tdiconnect(). We store target address info in FCB->ConnectCallInfo and FCB->ConnectReturnInfo so we can use it in sendto if the remoteaddress parameters are not populated. I'm not sure this is how Windows handles this, or if there's a better alternative in ReactOS, but this does work. In Sendto we try building from RemoteAddress first and only use these stored addresses if that fails. It would probably be more efficient to check RemoteAddress and decide based on its content, but it is populated with 'something' and non-empty so I'm not certain how to validate it by content, for now we validate it by failure which is far less efficient. THIS CODE WAS COPIED FROM STREAM CODE BELOW, SO IT SHOULD BE SAFE AND 'CORRECT', BUT MAY NOT BE OPTIMAL. */ AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: HACK01 starting cloned STREAM code, calling WarmSocketConnection(FCB).\n", PsGetCurrentProcessId())); if (FCB->State == SOCKET_STATE_CREATED) { // THIS SECTION NOT EXECUTED MAY BE POSSIBLE TO REMOVE, we decide wehter to run based on socket state AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: HACK02 SOCKET_STATE_CREATED found, setting LocalAddress and trying bind.\n", PsGetCurrentProcessId())); if (FCB->LocalAddress) { ExFreePoolWithTag(FCB->LocalAddress, TAG_AFD_TRANSPORT_ADDRESS); } AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: HACK03 setting LocalAddress.\n", PsGetCurrentProcessId())); FCB->LocalAddress = TaBuildNullTransportAddress( ConnectReq->RemoteAddress.Address[0].AddressType ); if( FCB->LocalAddress ) { AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: HACK04 calling WarmSocketForBind.\n", PsGetCurrentProcessId())); Status = WarmSocketForBind( FCB, AFD_SHARE_WILDCARD ); if( NT_SUCCESS(Status) ) { AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: HACK05 setting SOCKET_STATE_BOUND.\n", PsGetCurrentProcessId())); FCB->State = SOCKET_STATE_BOUND; // <=== send REQUIRES THIS TO USE FCB->RemoteAddress } } } if (FCB->State == SOCKET_STATE_BOUND) { // THIS SECTION EXECUTES AND HANDLES STORING TARGET ADDRESS, we decide wheter to run by socket state if (FCB->ConnectReturnInfo) { AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: HACK08a ConnectReturnInfo is set, so dispose of current allocated obect.\n", PsGetCurrentProcessId())); ExFreePoolWithTag(FCB->ConnectReturnInfo, TAG_AFD_TDI_CONNECTION_INFORMATION); } AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: HACK08 calling TdiBuildconnectionInfo to build new ConnectReturnInfo from RemoteAddress.\n", PsGetCurrentProcessId())); Status = TdiBuildConnectionInfo( &FCB->ConnectReturnInfo, &ConnectReq->RemoteAddress ); if( NT_SUCCESS(Status) ) { AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: HACK09 new ConnectReturnInfo placed in FCB.\n", PsGetCurrentProcessId())); if (FCB->ConnectCallInfo) { AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: HACK08a ConnectCallInfo is set, so dispose of current allocated obect.\n", PsGetCurrentProcessId())); ExFreePoolWithTag(FCB->ConnectCallInfo, TAG_AFD_TDI_CONNECTION_INFORMATION); } AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: HACK10 calling TdiBuildconnectionInfo to build new ConnectCallInfo from RemoteAddress.\n", PsGetCurrentProcessId())); Status = TdiBuildConnectionInfo(&FCB->ConnectCallInfo, &ConnectReq->RemoteAddress); if( NT_SUCCESS(Status) ) { AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: HACK11 TdiBuildconnectionInfo call for ConnectCallInfo succeeded, populating ConnectCallInfo in FCB.\n", PsGetCurrentProcessId())); FCB->ConnectCallInfo->UserData = FCB->ConnectData; FCB->ConnectCallInfo->UserDataLength = FCB->ConnectDataSize; FCB->ConnectCallInfo->Options = FCB->ConnectOptions; FCB->ConnectCallInfo->OptionsLength = FCB->ConnectOptionsSize; AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: HACK11a new ConnectCallInfo placed in FCB.\n", PsGetCurrentProcessId())); } } } AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: HACK99 cloned STREAM code complete.\n", PsGetCurrentProcessId())); // END OF DLB HACK FOR STORING REMOTE ADDRESS FOR USE BY SENDTO AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: completed successfully.\n", PsGetCurrentProcessId())); Status = STATUS_SUCCESS; } return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); } AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: reached switch( FCB->State ) [post patch code for stream mode.\n", PsGetCurrentProcessId())); switch( FCB->State ) { case SOCKET_STATE_CONNECTED: AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: SOCKET_STATE_CONNECTED found, setting Status = STATUS_SUCCESS.\n", PsGetCurrentProcessId())); Status = STATUS_SUCCESS; break; case SOCKET_STATE_CONNECTING: AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: SOCKET_STATE_CONNECTING found, calling LeaveIrpUnitlLater().\n", PsGetCurrentProcessId())); return LeaveIrpUntilLater( FCB, Irp, FUNCTION_CONNECT ); case SOCKET_STATE_CREATED: AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: SOCKET_STATE_CREATED found, setting LocalAddress and trying bind.\n", PsGetCurrentProcessId())); if (FCB->LocalAddress) { ExFreePoolWithTag(FCB->LocalAddress, TAG_AFD_TRANSPORT_ADDRESS); } FCB->LocalAddress = TaBuildNullTransportAddress( ConnectReq->RemoteAddress.Address[0].AddressType ); if( FCB->LocalAddress ) { Status = WarmSocketForBind( FCB, AFD_SHARE_WILDCARD ); if( NT_SUCCESS(Status) ) FCB->State = SOCKET_STATE_BOUND; else return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); } else return UnlockAndMaybeComplete ( FCB, STATUS_NO_MEMORY, Irp, 0 ); /* Drop through to SOCKET_STATE_BOUND */ case SOCKET_STATE_BOUND: AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: SOCKET_STATE_BOUND found, setting RemoteAddress and trying connect.\n", PsGetCurrentProcessId())); if (FCB->RemoteAddress) { ExFreePoolWithTag(FCB->RemoteAddress, TAG_AFD_TRANSPORT_ADDRESS); } FCB->RemoteAddress = TaCopyTransportAddress( &ConnectReq->RemoteAddress ); if( !FCB->RemoteAddress ) { Status = STATUS_NO_MEMORY; break; } AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: calling WarmSocketConnection.\n", PsGetCurrentProcessId())); Status = WarmSocketForConnection( FCB ); if( !NT_SUCCESS(Status) ) break; if (FCB->ConnectReturnInfo) { ExFreePoolWithTag(FCB->ConnectReturnInfo, TAG_AFD_TDI_CONNECTION_INFORMATION); } AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: calling TdiBuildconnectionInfo for ConnectReturnInfo.\n", PsGetCurrentProcessId())); Status = TdiBuildConnectionInfo( &FCB->ConnectReturnInfo, &ConnectReq->RemoteAddress ); if( NT_SUCCESS(Status) ) { if (FCB->ConnectCallInfo) { ExFreePoolWithTag(FCB->ConnectCallInfo, TAG_AFD_TDI_CONNECTION_INFORMATION); } AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: calling TdiBuildconnectionInfo for ConnectCallInfo.\n", PsGetCurrentProcessId())); Status = TdiBuildConnectionInfo(&FCB->ConnectCallInfo, &ConnectReq->RemoteAddress); } else break; if( NT_SUCCESS(Status) ) { AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: call succeeded, populating ConnectCallInfo.\n", PsGetCurrentProcessId())); FCB->ConnectCallInfo->UserData = FCB->ConnectData; FCB->ConnectCallInfo->UserDataLength = FCB->ConnectDataSize; FCB->ConnectCallInfo->Options = FCB->ConnectOptions; FCB->ConnectCallInfo->OptionsLength = FCB->ConnectOptionsSize; AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: setting FCB->State to SOCKET_STATE_CONNECTING.\n", PsGetCurrentProcessId())); FCB->State = SOCKET_STATE_CONNECTING; AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: Queueing IRP %p\n", PsGetCurrentProcessId(), Irp)); Status = QueueUserModeIrp( FCB, Irp, FUNCTION_CONNECT ); if (Status == STATUS_PENDING) { AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: STATUS_PENDING found, calling TdiConnect().\n", PsGetCurrentProcessId())); Status = TdiConnect( &FCB->ConnectIrp.InFlightRequest, FCB->Connection.Object, FCB->ConnectCallInfo, FCB->ConnectReturnInfo, StreamSocketConnectComplete, FCB ); } if (Status != STATUS_PENDING) { AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: STATUS_PENDING NOT found, setting FCB->State to SOCKET_STATE_BOUND.\n", PsGetCurrentProcessId())); FCB->State = SOCKET_STATE_BOUND; } SocketStateUnlock(FCB); AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: completed, returning Status.\n", PsGetCurrentProcessId())); return Status; } break; default: AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: Inappropriate socket state %u for connect\n", PsGetCurrentProcessId(), FCB->State)); break; } AFD_DbgPrint(1,("(PID %lx) AfdStreamSocketConnect: completed return UnlockAndMaybecomplete().\n", PsGetCurrentProcessId())); return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); }