dll/win32/msafd/misc/dllmain.c | 220 ++++++++++++---- dll/win32/msafd/misc/event.c | 2 +- dll/win32/msafd/misc/sndrcv.c | 454 +++++++++++++++++++++++---------- dll/win32/msafd/msafd.h | 35 ++- drivers/network/afd/afd/tdi.c | 8 +- drivers/network/afd/afd/write.c | 12 +- sdk/lib/drivers/ip/transport/tcp/tcp.c | 8 +- 7 files changed, 537 insertions(+), 202 deletions(-) diff --git a/dll/win32/msafd/misc/dllmain.c b/dll/win32/msafd/misc/dllmain.c index 4f8e76c10a..6aa978dc26 100644 --- a/dll/win32/msafd/misc/dllmain.c +++ b/dll/win32/msafd/misc/dllmain.c @@ -174,6 +174,7 @@ WSPSocket(int AddressFamily, RtlInitUnicodeString(&DevName, L"\\Device\\Afd\\Endpoint"); /* Set Socket Data */ + DbgPrint("(dllmain.c:%d) Socket has been allocated.\n", __LINE__); Socket = HeapAlloc(GlobalHeap, 0, sizeof(*Socket)); if (!Socket) { @@ -191,6 +192,7 @@ WSPSocket(int AddressFamily, else { Socket->SharedDataHandle = INVALID_HANDLE_VALUE; + DbgPrint("(dllmain.c:%d) Socket->SharedData has been allocated.\n", __LINE__); Socket->SharedData = HeapAlloc(GlobalHeap, 0, sizeof(*Socket->SharedData)); if (!Socket->SharedData) { @@ -243,6 +245,7 @@ WSPSocket(int AddressFamily, SizeOfEA = SizeOfPacket + sizeof(FILE_FULL_EA_INFORMATION) + AFD_PACKET_COMMAND_LENGTH; /* Set up EA Buffer */ + DbgPrint("(dllmain.c:%d) EABuffer has been allocated.\n", __LINE__); EABuffer = HeapAlloc(GlobalHeap, 0, SizeOfEA); if (!EABuffer) { @@ -355,7 +358,7 @@ WSPSocket(int AddressFamily, 0, EABuffer, SizeOfEA); - + DbgPrint("(dllmain.c:%d) EABuffer has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, EABuffer); if (!NT_SUCCESS(Status)) @@ -418,7 +421,7 @@ ok: return (SOCKET)Sock; error: - ERR("Ending %x\n", Status); + TRACE("Ending %x\n", Status); if( SharedData ) { @@ -428,13 +431,16 @@ error: else { if( Socket && Socket->SharedData ) + DbgPrint("(dllmain.c:%d) Socket->SharedData has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, Socket->SharedData); } if( Socket ) + DbgPrint("(dllmain.c:%d) Socket has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, Socket); if( EABuffer ) + DbgPrint("(dllmain.c:%d) EABuffer has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, EABuffer); if( lpErrno ) @@ -489,6 +495,7 @@ WSPDuplicateSocket( RtlCopyMemory(pSharedData, Socket->SharedData, sizeof(SOCK_SHARED_INFO)); pOldSharedData = Socket->SharedData; Socket->SharedData = pSharedData; + DbgPrint("(dllmain.c:%d) pOldSharedData has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, pOldSharedData); } /* Duplicate the handles for the new process */ @@ -824,8 +831,10 @@ ok: } if( !References && Socket->SharedData ) { + DbgPrint("(dllmain.c:%d) Socket->SharedData has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, Socket->SharedData); } + DbgPrint("(dllmain.c:%d) Socket has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, Socket); return MsafdReturnWithErrno(Status, lpErrno, 0, NULL); } @@ -896,6 +905,7 @@ WSPBind(SOCKET Handle, } /* See below */ + DbgPrint("(dllmain.c:%d) BindData has been allocated.\n", __LINE__); BindData = HeapAlloc(GlobalHeap, 0, 0xA + SocketAddressLength); if (!BindData) { @@ -948,6 +958,7 @@ WSPBind(SOCKET Handle, } NtClose( SockEvent ); + DbgPrint("(dllmain.c:%d) BindData has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, BindData); Socket->SharedData->SocketLastError = TranslateNtStatusError(Status); @@ -1162,6 +1173,7 @@ WSPSelect(IN int nfds, } /* Allocate */ + DbgPrint("(dllmain.c:%d) PollBuffer has been allocated.\n", __LINE__); PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize); if (!PollBuffer) @@ -1196,6 +1208,7 @@ WSPSelect(IN int nfds, { ERR("Error while counting readfds %ld > %ld\n", j, HandleCount); if (lpErrno) *lpErrno = WSAEFAULT; + DbgPrint("(dllmain.c:%d) PollBuffer has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, PollBuffer); NtClose(SockEvent); return SOCKET_ERROR; @@ -1205,6 +1218,7 @@ WSPSelect(IN int nfds, { ERR("Invalid socket handle provided in readfds %d\n", readfds->fd_array[i]); if (lpErrno) *lpErrno = WSAENOTSOCK; + DbgPrint("(dllmain.c:%d) PollBuffer has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, PollBuffer); NtClose(SockEvent); return SOCKET_ERROR; @@ -1231,6 +1245,7 @@ WSPSelect(IN int nfds, { ERR("Error while counting writefds %ld > %ld\n", j, HandleCount); if (lpErrno) *lpErrno = WSAEFAULT; + DbgPrint("(dllmain.c:%d) PollBuffer has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, PollBuffer); NtClose(SockEvent); return SOCKET_ERROR; @@ -1240,6 +1255,7 @@ WSPSelect(IN int nfds, { ERR("Invalid socket handle provided in writefds %d\n", writefds->fd_array[i]); if (lpErrno) *lpErrno = WSAENOTSOCK; + DbgPrint("(dllmain.c:%d) PollBuffer has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, PollBuffer); NtClose(SockEvent); return SOCKET_ERROR; @@ -1263,6 +1279,7 @@ WSPSelect(IN int nfds, { ERR("Error while counting exceptfds %ld > %ld\n", j, HandleCount); if (lpErrno) *lpErrno = WSAEFAULT; + DbgPrint("(dllmain.c:%d) PollBuffer has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, PollBuffer); NtClose(SockEvent); return SOCKET_ERROR; @@ -1272,6 +1289,7 @@ WSPSelect(IN int nfds, { TRACE("Invalid socket handle provided in exceptfds %d\n", exceptfds->fd_array[i]); if (lpErrno) *lpErrno = WSAENOTSOCK; + DbgPrint("(dllmain.c:%d) PollBuffer has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, PollBuffer); NtClose(SockEvent); return SOCKET_ERROR; @@ -1331,6 +1349,7 @@ WSPSelect(IN int nfds, { TRACE("Invalid socket handle found %d\n", Handle); if (lpErrno) *lpErrno = WSAENOTSOCK; + DbgPrint("(dllmain.c:%d) PollBuffer has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, PollBuffer); NtClose(SockEvent); return SOCKET_ERROR; @@ -1385,7 +1404,7 @@ WSPSelect(IN int nfds, } } } - + DbgPrint("(dllmain.c:%d) PollBuffer has been freed.\n", __LINE__); HeapFree( GlobalHeap, 0, PollBuffer ); NtClose( SockEvent ); @@ -1577,6 +1596,7 @@ WSPAccept( if (PendingDataLength) { /* Allocate needed space */ + DbgPrint("(dllmain.c:%d) PendingData has been allocated.\n", __LINE__); PendingData = HeapAlloc(GlobalHeap, 0, PendingDataLength); if (!PendingData) { @@ -1622,6 +1642,7 @@ WSPAccept( CalleeID.buf = (PVOID)Socket->LocalAddress; CalleeID.len = Socket->SharedData->SizeOfLocalAddress; + DbgPrint("(dllmain.c:%d) RemoteAddress has been allocated.\n", __LINE__); RemoteAddress = HeapAlloc(GlobalHeap, 0, sizeof(*RemoteAddress)); if (!RemoteAddress) { @@ -1645,6 +1666,7 @@ WSPAccept( if (Socket->SharedData->UseDelayedAcceptance != 0) { /* Allocate Buffer for Callee Data */ + DbgPrint("(dllmain.c:%d) CalleeDataBuffer has been allocated.\n", __LINE__); CalleeDataBuffer = HeapAlloc(GlobalHeap, 0, 4096); if (!CalleeDataBuffer) { return MsafdReturnWithErrno( STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL ); @@ -1821,6 +1843,58 @@ WSPAccept( return AcceptSocket; } +VOID +NTAPI +AfdConnectAPC(PVOID ApcContext, + PIO_STATUS_BLOCK IoStatusBlock, + ULONG Reserved) +{ + PAFDCONNECTAPCCONTEXT Context = ApcContext; + + TRACE("AfdConnectAPC %p %lx %lx\n", ApcContext, IoStatusBlock->Status, IoStatusBlock->Information); + + if (Context->lpConnectInfo) + DbgPrint("(dllmain.c:%d) Context->lpConnectInfo has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, Context->lpConnectInfo); + if (!Context->lpSocket) + { + DbgPrint("(dllmain.c:%d) ApcContext has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, ApcContext); + return; + } + if (IoStatusBlock->Status == STATUS_SUCCESS) + { + Context->lpSocket->SharedData->ConnectTime = (GetTickCount() - Context->lpSocket->SharedData->ConnectTime) / 1000; + Context->lpSocket->SharedData->State = SocketConnected; + Context->lpSocket->TdiConnectionHandle = (HANDLE)IoStatusBlock->Information; + } + + /* Re-enable Async Event */ + SockReenableAsyncSelectEvent(Context->lpSocket, FD_WRITE); + + /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */ + SockReenableAsyncSelectEvent(Context->lpSocket, FD_CONNECT); + + if (IoStatusBlock->Status == STATUS_SUCCESS && (Context->lpSocket->HelperEvents & WSH_NOTIFY_CONNECT)) + { + Context->lpSocket->HelperData->WSHNotify(Context->lpSocket->HelperContext, + Context->lpSocket->Handle, + Context->lpSocket->TdiAddressHandle, + Context->lpSocket->TdiConnectionHandle, + WSH_NOTIFY_CONNECT); + } + else if (IoStatusBlock->Status != STATUS_SUCCESS && (Context->lpSocket->HelperEvents & WSH_NOTIFY_CONNECT_ERROR)) + { + Context->lpSocket->HelperData->WSHNotify(Context->lpSocket->HelperContext, + Context->lpSocket->Handle, + Context->lpSocket->TdiAddressHandle, + Context->lpSocket->TdiConnectionHandle, + WSH_NOTIFY_CONNECT_ERROR); + } + DbgPrint("(dllmain.c:%d) ApcContext has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, ApcContext); +} + int WSPAPI WSPConnect(SOCKET Handle, @@ -1832,7 +1906,8 @@ WSPConnect(SOCKET Handle, LPQOS lpGQOS, LPINT lpErrno) { - IO_STATUS_BLOCK IOSB; + IO_STATUS_BLOCK DummyIOSB; + PIO_STATUS_BLOCK IOSB = &DummyIOSB; PAFD_CONNECT_INFO ConnectInfo = NULL; PSOCKET_INFORMATION Socket; NTSTATUS Status; @@ -1843,8 +1918,10 @@ WSPConnect(SOCKET Handle, PSOCKADDR BindAddress; HANDLE SockEvent; int SocketDataLength; + PAFDCONNECTAPCCONTEXT APCContext = NULL; + PIO_APC_ROUTINE APCFunction = NULL; - TRACE("Called (%lx) %lx:%d\n", Handle, ((const struct sockaddr_in *)SocketAddress)->sin_addr, ((const struct sockaddr_in *)SocketAddress)->sin_port); + TRACE("WSPConnect (%lx)\n", Handle); /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); @@ -1868,6 +1945,7 @@ WSPConnect(SOCKET Handle, { /* Get the Wildcard Address */ BindAddressLength = Socket->HelperData->MaxWSAddressLength; + DbgPrint("(dllmain.c:%d) BindAddress has been allocated.\n", __LINE__); BindAddress = HeapAlloc(GetProcessHeap(), 0, BindAddressLength); if (!BindAddress) { @@ -1890,7 +1968,7 @@ WSPConnect(SOCKET Handle, SockEvent, NULL, NULL, - &IOSB, + IOSB, IOCTL_AFD_SET_CONNECT_DATA, lpCallerData->buf, ConnectDataLength, @@ -1900,7 +1978,7 @@ WSPConnect(SOCKET Handle, if (Status == STATUS_PENDING) { WaitForSingleObject(SockEvent, INFINITE); - Status = IOSB.Status; + Status = IOSB->Status; } if (Status != STATUS_SUCCESS) @@ -1911,7 +1989,8 @@ WSPConnect(SOCKET Handle, SocketDataLength = SocketAddressLength - FIELD_OFFSET(struct sockaddr, sa_data); /* Allocate a connection info buffer with SocketDataLength bytes of payload */ - ConnectInfo = HeapAlloc(GetProcessHeap(), 0, + DbgPrint("(dllmain.c:%d) ConnectInfo has been allocated.\n", __LINE__); + ConnectInfo = HeapAlloc(GlobalHeap, 0, FIELD_OFFSET(AFD_CONNECT_INFO, RemoteAddress.Address[0].Address[SocketDataLength])); if (!ConnectInfo) @@ -1934,7 +2013,7 @@ WSPConnect(SOCKET Handle, * at the end of this function right after the Async Thread disables it. * This should only happen at the *next* WSPConnect */ - if (Socket->SharedData->AsyncEvents & FD_CONNECT) + if ((Socket->SharedData->AsyncEvents & FD_CONNECT) != 0) { Socket->SharedData->AsyncDisabledEvents |= FD_CONNECT | FD_WRITE; } @@ -1947,7 +2026,7 @@ WSPConnect(SOCKET Handle, SockEvent, NULL, NULL, - &IOSB, + IOSB, IOCTL_AFD_SET_CONNECT_DATA_SIZE, &InConnectDataLength, sizeof(InConnectDataLength), @@ -1958,7 +2037,7 @@ WSPConnect(SOCKET Handle, if (Status == STATUS_PENDING) { WaitForSingleObject(SockEvent, INFINITE); - Status = IOSB.Status; + Status = IOSB->Status; } if (Status != STATUS_SUCCESS) @@ -1970,18 +2049,29 @@ WSPConnect(SOCKET Handle, ConnectInfo->UseSAN = FALSE; ConnectInfo->Unknown = 0; - /* FIXME: Handle Async Connect */ if (Socket->SharedData->NonBlocking) { - ERR("Async Connect UNIMPLEMENTED!\n"); + APCFunction = &AfdConnectAPC; // should be a private io completition function inside us + DbgPrint("(dllmain.c:%d) APCContext has been allocated.\n", __LINE__); + APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDCONNECTAPCCONTEXT)); + if (!APCContext) + { + ERR("Not enough memory for APC Context\n"); + return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL); + } + APCContext->lpConnectInfo = ConnectInfo; + APCContext->lpSocket = Socket; + IOSB = &APCContext->IoStatusBlock; } + IOSB->Status = STATUS_PENDING; + /* Send IOCTL */ Status = NtDeviceIoControlFile((HANDLE)Handle, - SockEvent, - NULL, - NULL, - &IOSB, + APCFunction != NULL ? NULL : SockEvent, + APCFunction, + APCContext, + IOSB, IOCTL_AFD_CONNECT, ConnectInfo, 0x22, @@ -1990,16 +2080,34 @@ WSPConnect(SOCKET Handle, /* Wait for return */ if (Status == STATUS_PENDING) { - WaitForSingleObject(SockEvent, INFINITE); - Status = IOSB.Status; + WaitForSingleObject(SockEvent, Socket->SharedData->NonBlocking ? 0 : INFINITE); + Status = IOSB->Status; + } + if (Status == STATUS_PENDING || Status == STATUS_CANT_WAIT) + { + NtClose(SockEvent); + if (Socket->SharedData->NonBlocking) + Status = STATUS_CANT_WAIT; + TRACE("Leaving (Pending)\n"); + return MsafdReturnWithErrno(Status, lpErrno, 0, NULL); + } + + if (APCFunction) + { + APCContext->lpConnectInfo = NULL; + APCContext->lpSocket = NULL; + /* This will be freed by the APC */ + //HeapFree(GlobalHeap, 0, APCContext); } + DbgPrint("(dllmain.c:%d) ConnectInfo has been freed.\n", __LINE__); + if (ConnectInfo) HeapFree(GlobalHeap, 0, ConnectInfo); Socket->SharedData->SocketLastError = TranslateNtStatusError(Status); if (Status != STATUS_SUCCESS) goto notify; Socket->SharedData->State = SocketConnected; - Socket->TdiConnectionHandle = (HANDLE)IOSB.Information; + Socket->TdiConnectionHandle = (HANDLE)IOSB->Information; Socket->SharedData->ConnectTime = GetCurrentTimeInSeconds(); /* Get any pending connect data */ @@ -2009,7 +2117,7 @@ WSPConnect(SOCKET Handle, SockEvent, NULL, NULL, - &IOSB, + IOSB, IOCTL_AFD_GET_CONNECT_DATA, NULL, 0, @@ -2019,14 +2127,12 @@ WSPConnect(SOCKET Handle, if (Status == STATUS_PENDING) { WaitForSingleObject(SockEvent, INFINITE); - Status = IOSB.Status; + Status = IOSB->Status; } } - TRACE("Ending %lx\n", IOSB.Status); - notify: - if (ConnectInfo) HeapFree(GetProcessHeap(), 0, ConnectInfo); + TRACE("Ending %lx\n", IOSB->Status); /* Re-enable Async Event */ SockReenableAsyncSelectEvent(Socket, FD_WRITE); @@ -2188,6 +2294,7 @@ WSPGetSockName(IN SOCKET Handle, /* Allocate a buffer for the address */ TdiAddressSize = sizeof(TRANSPORT_ADDRESS) + Socket->SharedData->SizeOfLocalAddress; + DbgPrint("(dllmain.c:%d) TdiAddress has been allocated.\n", __LINE__); TdiAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize); if ( TdiAddress == NULL ) @@ -2232,17 +2339,19 @@ WSPGetSockName(IN SOCKET Handle, TRACE("NameLength %d Address: %x Port %x\n", *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr, ((struct sockaddr_in *)Name)->sin_port); + DbgPrint("(dllmain.c:%d) TdiAddress has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, TdiAddress); return 0; } else { + DbgPrint("(dllmain.c:%d) TdiAddress has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, TdiAddress); if (lpErrno) *lpErrno = WSAEFAULT; return SOCKET_ERROR; } } - + DbgPrint("(dllmain.c:%d) TdiAddress has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, TdiAddress); return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL ); @@ -2294,6 +2403,7 @@ WSPGetPeerName(IN SOCKET s, /* Allocate a buffer for the address */ TdiAddressSize = sizeof(TRANSPORT_ADDRESS) + Socket->SharedData->SizeOfRemoteAddress; + DbgPrint("(dllmain.c:%d) SocketAddress has been allocated.\n", __LINE__); SocketAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize); if ( SocketAddress == NULL ) @@ -2336,17 +2446,19 @@ WSPGetPeerName(IN SOCKET s, TRACE("NameLength %d Address: %x Port %x\n", *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr, ((struct sockaddr_in *)Name)->sin_port); + DbgPrint("(dllmain.c:%d) SocketAddress has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, SocketAddress); return 0; } else { + DbgPrint("(dllmain.c:%d) SocketAddress has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, SocketAddress); if (lpErrno) *lpErrno = WSAEFAULT; return SOCKET_ERROR; } } - + DbgPrint("(dllmain.c:%d) SocketAddress has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, SocketAddress); return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL ); @@ -3058,6 +3170,9 @@ WSPAddressToString(IN LPSOCKADDR lpsaAddress, WCHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */ WCHAR *p; + /* Allow for APC to be processed */ + SleepEx(0, TRUE); + if (!lpsaAddress || !lpszAddressString || !lpdwAddressStringLength) { if (lpErrno) *lpErrno = WSAEFAULT; @@ -3247,9 +3362,11 @@ AfdInfoAPC(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved) { - PAFDAPCCONTEXT Context = ApcContext; + PAFDINFOAPCCONTEXT Context = ApcContext; - Context->lpCompletionRoutine(IoStatusBlock->Status, IoStatusBlock->Information, Context->lpOverlapped, 0); + if (Context->lpCompletionRoutine) + Context->lpCompletionRoutine(IoStatusBlock->Status, IoStatusBlock->Information, Context->lpOverlapped, 0); + DbgPrint("(dllmain.c:%d) ApcContext has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, ApcContext); } @@ -3266,7 +3383,7 @@ GetSocketInformation(PSOCKET_INFORMATION Socket, IO_STATUS_BLOCK DummyIOSB; AFD_INFO InfoData; NTSTATUS Status; - PAFDAPCCONTEXT APCContext; + PAFDINFOAPCCONTEXT APCContext; PIO_APC_ROUTINE APCFunction; HANDLE Event = NULL; HANDLE SockEvent; @@ -3299,12 +3416,12 @@ GetSocketInformation(PSOCKET_INFORMATION Socket, { TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n"); NtClose( SockEvent ); - return 0; + return MsafdReturnWithErrno(STATUS_SUCCESS, NULL, 0, NULL); } if (CompletionRoutine == NULL) { /* Using Overlapped Structure, but no Completition Routine, so no need for APC */ - APCContext = (PAFDAPCCONTEXT)Overlapped; + APCContext = (PAFDINFOAPCCONTEXT)Overlapped; APCFunction = NULL; Event = Overlapped->hEvent; } @@ -3312,16 +3429,16 @@ GetSocketInformation(PSOCKET_INFORMATION Socket, { /* Using Overlapped Structure and a Completition Routine, so use an APC */ APCFunction = &AfdInfoAPC; // should be a private io completition function inside us - APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT)); + DbgPrint("(dllmain.c:%d) APCContext has been allocated.\n", __LINE__); + APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDINFOAPCCONTEXT)); if (!APCContext) { ERR("Not enough memory for APC Context\n"); NtClose( SockEvent ); - return WSAEFAULT; + return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, NULL, 0, NULL); } APCContext->lpCompletionRoutine = CompletionRoutine; APCContext->lpOverlapped = Overlapped; - APCContext->lpSocket = Socket; } IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal; @@ -3342,9 +3459,9 @@ GetSocketInformation(PSOCKET_INFORMATION Socket, sizeof(InfoData)); /* Wait for return */ - if (Status == STATUS_PENDING && Overlapped == NULL) + if (Status == STATUS_PENDING) { - WaitForSingleObject(SockEvent, INFINITE); + WaitForSingleObject(SockEvent, Overlapped != NULL ? 0 : INFINITE); Status = IOSB->Status; } @@ -3355,11 +3472,11 @@ GetSocketInformation(PSOCKET_INFORMATION Socket, if (Status == STATUS_PENDING) { TRACE("Leaving (Pending)\n"); - return WSA_IO_PENDING; + return MsafdReturnWithErrno(Status, NULL, IOSB->Information, NULL); } if (Status != STATUS_SUCCESS) - return SOCKET_ERROR; + return MsafdReturnWithErrno(Status, NULL, IOSB->Information, NULL); /* Return Information */ if (Ulong != NULL) @@ -3375,8 +3492,7 @@ GetSocketInformation(PSOCKET_INFORMATION Socket, *Boolean = InfoData.Information.Boolean; } - return NO_ERROR; - + return MsafdReturnWithErrno(Status, NULL, IOSB->Information, NULL); } @@ -3393,7 +3509,7 @@ SetSocketInformation(PSOCKET_INFORMATION Socket, IO_STATUS_BLOCK DummyIOSB; AFD_INFO InfoData; NTSTATUS Status; - PAFDAPCCONTEXT APCContext; + PAFDINFOAPCCONTEXT APCContext; PIO_APC_ROUTINE APCFunction; HANDLE Event = NULL; HANDLE SockEvent; @@ -3440,12 +3556,12 @@ SetSocketInformation(PSOCKET_INFORMATION Socket, { TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n"); NtClose( SockEvent ); - return 0; + return MsafdReturnWithErrno(STATUS_SUCCESS, NULL, 0, NULL); } if (CompletionRoutine == NULL) { /* Using Overlapped Structure, but no Completition Routine, so no need for APC */ - APCContext = (PAFDAPCCONTEXT)Overlapped; + APCContext = (PAFDINFOAPCCONTEXT)Overlapped; APCFunction = NULL; Event = Overlapped->hEvent; } @@ -3453,16 +3569,16 @@ SetSocketInformation(PSOCKET_INFORMATION Socket, { /* Using Overlapped Structure and a Completition Routine, so use an APC */ APCFunction = &AfdInfoAPC; // should be a private io completition function inside us - APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT)); + DbgPrint("(dllmain.c:%d) APCContext has been allocated.\n", __LINE__); + APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDINFOAPCCONTEXT)); if (!APCContext) { ERR("Not enough memory for APC Context\n"); NtClose( SockEvent ); - return WSAEFAULT; + return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, NULL, 0, NULL); } APCContext->lpCompletionRoutine = CompletionRoutine; APCContext->lpOverlapped = Overlapped; - APCContext->lpSocket = Socket; } IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal; @@ -3483,9 +3599,9 @@ SetSocketInformation(PSOCKET_INFORMATION Socket, 0); /* Wait for return */ - if (Status == STATUS_PENDING && Overlapped == NULL) + if (Status == STATUS_PENDING) { - WaitForSingleObject(SockEvent, INFINITE); + WaitForSingleObject(SockEvent, Overlapped != NULL ? 0 : INFINITE); Status = IOSB->Status; } @@ -3496,10 +3612,10 @@ SetSocketInformation(PSOCKET_INFORMATION Socket, if (Status == STATUS_PENDING) { TRACE("Leaving (Pending)\n"); - return WSA_IO_PENDING; + //return MsafdReturnWithErrno(Status, NULL, IOSB->Information, NULL); } - return Status == STATUS_SUCCESS ? NO_ERROR : SOCKET_ERROR; + return MsafdReturnWithErrno(Status, NULL, IOSB->Information, NULL); } @@ -3973,6 +4089,7 @@ VOID SockProcessQueuedAsyncSelect(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock) /* Free the Context */ if (FreeContext) { + DbgPrint("(dllmain.c:%d) AsyncData has been freed.\n", __LINE__); HeapFree(GetProcessHeap(), 0, AsyncData); } @@ -4001,6 +4118,7 @@ SockReenableAsyncSelectEvent (IN PSOCKET_INFORMATION Socket, } /* Wait on new events */ + DbgPrint("(dllmain.c:%d) AsyncData has been allocated.\n", __LINE__); AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(ASYNC_DATA)); if (!AsyncData) return; diff --git a/dll/win32/msafd/misc/event.c b/dll/win32/msafd/misc/event.c index 581e4ee195..b3b0da2c74 100644 --- a/dll/win32/msafd/misc/event.c +++ b/dll/win32/msafd/misc/event.c @@ -189,7 +189,7 @@ WSPEnumNetworkEvents( if (Status != STATUS_SUCCESS) { - ERR("Status 0x%08x", Status); + ERR("Status 0x%08x\n", Status); return MsafdReturnWithErrno(Status, lpErrno, 0, NULL); } diff --git a/dll/win32/msafd/misc/sndrcv.c b/dll/win32/msafd/misc/sndrcv.c index 07fe8b1f1c..f1ebd29c7d 100644 --- a/dll/win32/msafd/misc/sndrcv.c +++ b/dll/win32/msafd/misc/sndrcv.c @@ -33,6 +33,7 @@ WSPAsyncSelect(IN SOCKET Handle, } /* Allocate the Async Data Structure to pass on to the Thread later */ + DbgPrint("(sndrcv.c:%d) AsyncData has been allocated.\n", __LINE__); AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(*AsyncData)); if (!AsyncData) { @@ -50,6 +51,7 @@ WSPAsyncSelect(IN SOCKET Handle, { if (WSPEventSelect(Handle, NULL, 0, lpErrno) == SOCKET_ERROR) { + DbgPrint("(sndrcv.c:%d) AsyncData has been freed.\n", __LINE__); HeapFree(GetProcessHeap(), 0, AsyncData); return SOCKET_ERROR; } @@ -71,6 +73,7 @@ WSPAsyncSelect(IN SOCKET Handle, /* Return if there are no more Events */ if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)) == 0) { + DbgPrint("(sndrcv.c:%d) AsyncData has been freed.\n", __LINE__); HeapFree(GetProcessHeap(), 0, AsyncData); return 0; } @@ -137,18 +140,53 @@ WSPGetOverlappedResult( VOID NTAPI -AfdAPC(PVOID ApcContext, +AfdRecvAPC(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved) { - PAFDAPCCONTEXT Context = ApcContext; + PAFDRECVAPCCONTEXT Context = ApcContext; - /* Re-enable Async Event */ - SockReenableAsyncSelectEvent(Context->lpSocket, FD_OOB); - SockReenableAsyncSelectEvent(Context->lpSocket, FD_READ); - SockReenableAsyncSelectEvent(Context->lpSocket, FD_WRITE); + TRACE("AfdRecvAPC %p %lx %lx\n", ApcContext, IoStatusBlock->Status, IoStatusBlock->Information); + if (Context->lpSocket && Context->lpSocket->SharedData) + { + /* Re-enable Async Event */ + SockReenableAsyncSelectEvent(Context->lpSocket, FD_OOB); + SockReenableAsyncSelectEvent(Context->lpSocket, FD_READ); + } + + if (Context->lpCompletionRoutine) + Context->lpCompletionRoutine(IoStatusBlock->Status, IoStatusBlock->Information, Context->lpOverlapped, 0); + if (Context->lpRecvInfo) + DbgPrint("(sndrcv.c:%d) Context->lpConnectInfo has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, Context->lpRecvInfo); + DbgPrint("(sndrcv.c:%d) ApcContext has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, ApcContext); +} + +VOID +NTAPI +AfdSendAPC(PVOID ApcContext, + PIO_STATUS_BLOCK IoStatusBlock, + ULONG Reserved) +{ + PAFDSENDAPCCONTEXT Context = ApcContext; + + TRACE("AfdSendAPC %p %lx %lx\n", ApcContext, IoStatusBlock->Status, IoStatusBlock->Information); + if (Context->lpSocket && Context->lpSocket->SharedData) + { + /* Re-enable Async Event */ + SockReenableAsyncSelectEvent(Context->lpSocket, FD_WRITE); + } - Context->lpCompletionRoutine(IoStatusBlock->Status, IoStatusBlock->Information, Context->lpOverlapped, 0); + if (Context->lpCompletionRoutine) + Context->lpCompletionRoutine(IoStatusBlock->Status, IoStatusBlock->Information, Context->lpOverlapped, 0); + if (Context->lpSendInfo) + DbgPrint("(sndrcv.c:%d) Context->lpSendInfo has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, Context->lpSendInfo); + if (Context->lpRemoteAddress) + DbgPrint("(sndrcv.c:%d) Context->lpRemoteAddress has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, Context->lpRemoteAddress); + DbgPrint("(sndrcv.c:%d) ApcContext has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, ApcContext); } @@ -166,9 +204,9 @@ WSPRecv(SOCKET Handle, { PIO_STATUS_BLOCK IOSB; IO_STATUS_BLOCK DummyIOSB; - AFD_RECV_INFO RecvInfo; + PAFD_RECV_INFO RecvInfo; NTSTATUS Status; - PVOID APCContext; + PAFDRECVAPCCONTEXT APCContext; PIO_APC_ROUTINE APCFunction; HANDLE Event = NULL; HANDLE SockEvent; @@ -197,38 +235,52 @@ WSPRecv(SOCKET Handle, return SOCKET_ERROR; } + /* Allocate a recv info buffer */ + DbgPrint("(sndrcv.c:%d) RecvInfo has been allocated.\n", __LINE__); + RecvInfo = HeapAlloc(GlobalHeap, 0, sizeof(AFD_RECV_INFO)); + if (!RecvInfo) + { + if (lpErrno) + *lpErrno = WSAENOBUFS; + return SOCKET_ERROR; + } + Status = NtCreateEvent( &SockEvent, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE ); - if( !NT_SUCCESS(Status) ) - return -1; + if (!NT_SUCCESS(Status)) + { + DbgPrint("(sndrcv.c:%d) RecvInfo has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, RecvInfo); + return SOCKET_ERROR; + } /* Set up the Receive Structure */ - RecvInfo.BufferArray = (PAFD_WSABUF)lpBuffers; - RecvInfo.BufferCount = dwBufferCount; - RecvInfo.TdiFlags = 0; - RecvInfo.AfdFlags = Socket->SharedData->NonBlocking ? AFD_IMMEDIATE : 0; + RecvInfo->BufferArray = (PAFD_WSABUF)lpBuffers; + RecvInfo->BufferCount = dwBufferCount; + RecvInfo->TdiFlags = 0; + RecvInfo->AfdFlags = Socket->SharedData->NonBlocking ? AFD_IMMEDIATE : 0; /* Set the TDI Flags */ - if (*ReceiveFlags == 0) + if (!ReceiveFlags || *ReceiveFlags == 0) { - RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; + RecvInfo->TdiFlags |= TDI_RECEIVE_NORMAL; } else { if (*ReceiveFlags & MSG_OOB) { - RecvInfo.TdiFlags |= TDI_RECEIVE_EXPEDITED; + RecvInfo->TdiFlags |= TDI_RECEIVE_EXPEDITED; } if (*ReceiveFlags & MSG_PEEK) { - RecvInfo.TdiFlags |= TDI_RECEIVE_PEEK; + RecvInfo->TdiFlags |= TDI_RECEIVE_PEEK; } if (*ReceiveFlags & MSG_PARTIAL) { - RecvInfo.TdiFlags |= TDI_RECEIVE_PARTIAL; + RecvInfo->TdiFlags |= TDI_RECEIVE_PARTIAL; } } @@ -248,35 +300,38 @@ WSPRecv(SOCKET Handle, if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0) { TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n"); - return MsafdReturnWithErrno(0, lpErrno, 0, lpNumberOfBytesRead); + return MsafdReturnWithErrno(STATUS_SUCCESS, lpErrno, 0, lpNumberOfBytesRead); } if (lpCompletionRoutine == NULL) { /* Using Overlapped Structure, but no Completion Routine, so no need for APC */ - APCContext = lpOverlapped; + APCContext = (PAFDRECVAPCCONTEXT)lpOverlapped; APCFunction = NULL; Event = lpOverlapped->hEvent; } else { /* Using Overlapped Structure and a Completion Routine, so use an APC */ - APCFunction = &AfdAPC; // should be a private io completion function inside us - APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT)); + APCFunction = &AfdRecvAPC; // should be a private io completion function inside us + DbgPrint("(sndrcv.c:%d) APCContext has been allocated.\n", __LINE__); + APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDRECVAPCCONTEXT)); if (!APCContext) { ERR("Not enough memory for APC Context\n"); return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, lpNumberOfBytesRead); } - ((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = lpCompletionRoutine; - ((PAFDAPCCONTEXT)APCContext)->lpOverlapped = lpOverlapped; - ((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket; - RecvInfo.AfdFlags |= AFD_SKIP_FIO; + APCContext->lpCompletionRoutine = lpCompletionRoutine; + APCContext->lpOverlapped = lpOverlapped; + APCContext->lpSocket = Socket; + APCContext->lpRecvInfo = RecvInfo; + RecvInfo->AfdFlags |= AFD_SKIP_FIO; } IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; - RecvInfo.AfdFlags |= AFD_OVERLAPPED; + RecvInfo->AfdFlags |= AFD_OVERLAPPED; } + IOSB->Information = 0; IOSB->Status = STATUS_PENDING; /* Send IOCTL */ @@ -286,36 +341,47 @@ WSPRecv(SOCKET Handle, APCContext, IOSB, IOCTL_AFD_RECV, - &RecvInfo, - sizeof(RecvInfo), + RecvInfo, + sizeof(AFD_RECV_INFO), NULL, 0); /* Wait for completion of not overlapped */ - if (Status == STATUS_PENDING && lpOverlapped == NULL) + if (Status == STATUS_PENDING) { /* It's up to the protocol to time out recv. We must wait * until the protocol decides it's had enough. */ - WaitForSingleObject(SockEvent, INFINITE); + WaitForSingleObject(SockEvent, (lpOverlapped || Socket->SharedData->NonBlocking) ? 0 : INFINITE); Status = IOSB->Status; } NtClose( SockEvent ); - TRACE("Status %x Information %d\n", Status, IOSB->Information); - if (Status == STATUS_PENDING) { TRACE("Leaving (Pending)\n"); return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesRead); } - /* Return the Flags */ - *ReceiveFlags = 0; + if (APCFunction) + { + APCContext->lpRecvInfo = NULL; + APCContext->lpCompletionRoutine = NULL; + APCContext->lpSocket = NULL; + /* This will be freed by the APC */ + //HeapFree(GlobalHeap, 0, APCContext); + } + DbgPrint("(sndrcv.c:%d) RecvInfo has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, RecvInfo); - switch (Status) + /* Return the Flags */ + if (ReceiveFlags) { + *ReceiveFlags = 0; + + switch (Status) + { case STATUS_RECEIVE_EXPEDITED: *ReceiveFlags = MSG_OOB; break; @@ -325,22 +391,27 @@ WSPRecv(SOCKET Handle, case STATUS_RECEIVE_PARTIAL: *ReceiveFlags = MSG_PARTIAL; break; + } } - /* Re-enable Async Event */ - if (*ReceiveFlags & MSG_OOB) + if (Status == STATUS_SUCCESS) { - SockReenableAsyncSelectEvent(Socket, FD_OOB); - } - else - { - SockReenableAsyncSelectEvent(Socket, FD_READ); + /* Re-enable Async Event */ + if (ReceiveFlags && *ReceiveFlags & MSG_OOB) + { + SockReenableAsyncSelectEvent(Socket, FD_OOB); + } + else + { + SockReenableAsyncSelectEvent(Socket, FD_READ); + } } + TRACE("Leaving (Success, %ld %ld)\n", Status, IOSB->Information); + if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine) { - lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, *ReceiveFlags); - HeapFree(GlobalHeap, 0, (PVOID)APCContext); + lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, ReceiveFlags != NULL ? *ReceiveFlags : 0); } return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead ); @@ -362,14 +433,16 @@ WSPRecvFrom(SOCKET Handle, { PIO_STATUS_BLOCK IOSB; IO_STATUS_BLOCK DummyIOSB; - AFD_RECV_INFO_UDP RecvInfo; + PAFD_RECV_INFO_UDP RecvInfo; NTSTATUS Status; - PVOID APCContext; - PVOID APCFunction; + PAFDRECVAPCCONTEXT APCContext; + PIO_APC_ROUTINE APCFunction; HANDLE Event = NULL; HANDLE SockEvent; PSOCKET_INFORMATION Socket; + TRACE("WSPRecvFrom Called (%x)\n", Handle); + /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); if (!Socket) @@ -416,40 +489,54 @@ WSPRecvFrom(SOCKET Handle, return SOCKET_ERROR; } + /* Allocate a recv info buffer */ + DbgPrint("(sndrcv.c:%d) RecvInfo has been allocated.\n", __LINE__); + RecvInfo = HeapAlloc(GlobalHeap, 0, sizeof(AFD_RECV_INFO_UDP)); + if (!RecvInfo) + { + if (lpErrno) + *lpErrno = WSAENOBUFS; + return SOCKET_ERROR; + } + Status = NtCreateEvent( &SockEvent, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE ); if( !NT_SUCCESS(Status) ) - return -1; + { + DbgPrint("(sndrcv.c:%d) RecvInfo has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, RecvInfo); + return SOCKET_ERROR; + } /* Set up the Receive Structure */ - RecvInfo.BufferArray = (PAFD_WSABUF)lpBuffers; - RecvInfo.BufferCount = dwBufferCount; - RecvInfo.TdiFlags = 0; - RecvInfo.AfdFlags = Socket->SharedData->NonBlocking ? AFD_IMMEDIATE : 0; - RecvInfo.AddressLength = SocketAddressLength; - RecvInfo.Address = SocketAddress; + RecvInfo->BufferArray = (PAFD_WSABUF)lpBuffers; + RecvInfo->BufferCount = dwBufferCount; + RecvInfo->TdiFlags = 0; + RecvInfo->AfdFlags = Socket->SharedData->NonBlocking ? AFD_IMMEDIATE : 0; + RecvInfo->AddressLength = SocketAddressLength; + RecvInfo->Address = SocketAddress; /* Set the TDI Flags */ - if (*ReceiveFlags == 0) + if (!ReceiveFlags || *ReceiveFlags == 0) { - RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; + RecvInfo->TdiFlags |= TDI_RECEIVE_NORMAL; } else { if (*ReceiveFlags & MSG_OOB) { - RecvInfo.TdiFlags |= TDI_RECEIVE_EXPEDITED; + RecvInfo->TdiFlags |= TDI_RECEIVE_EXPEDITED; } if (*ReceiveFlags & MSG_PEEK) { - RecvInfo.TdiFlags |= TDI_RECEIVE_PEEK; + RecvInfo->TdiFlags |= TDI_RECEIVE_PEEK; } if (*ReceiveFlags & MSG_PARTIAL) { - RecvInfo.TdiFlags |= TDI_RECEIVE_PARTIAL; + RecvInfo->TdiFlags |= TDI_RECEIVE_PARTIAL; } } @@ -469,35 +556,38 @@ WSPRecvFrom(SOCKET Handle, if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0) { TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n"); - return MsafdReturnWithErrno(0, lpErrno, 0, lpNumberOfBytesRead); + return MsafdReturnWithErrno(STATUS_SUCCESS, lpErrno, 0, lpNumberOfBytesRead); } if (lpCompletionRoutine == NULL) { /* Using Overlapped Structure, but no Completion Routine, so no need for APC */ - APCContext = lpOverlapped; + APCContext = (PAFDRECVAPCCONTEXT)lpOverlapped; APCFunction = NULL; Event = lpOverlapped->hEvent; } else { /* Using Overlapped Structure and a Completion Routine, so use an APC */ - APCFunction = &AfdAPC; // should be a private io completion function inside us - APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT)); + APCFunction = &AfdRecvAPC; // should be a private io completion function inside us + DbgPrint("(sndrcv.c:%d) APCContext has been allocated.\n", __LINE__); + APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDRECVAPCCONTEXT)); if (!APCContext) { ERR("Not enough memory for APC Context\n"); return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, lpNumberOfBytesRead); } - ((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = lpCompletionRoutine; - ((PAFDAPCCONTEXT)APCContext)->lpOverlapped = lpOverlapped; - ((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket; - RecvInfo.AfdFlags |= AFD_SKIP_FIO; + APCContext->lpCompletionRoutine = lpCompletionRoutine; + APCContext->lpOverlapped = lpOverlapped; + APCContext->lpSocket = Socket; + APCContext->lpRecvInfo = RecvInfo; + RecvInfo->AfdFlags |= AFD_SKIP_FIO; } IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; - RecvInfo.AfdFlags |= AFD_OVERLAPPED; + RecvInfo->AfdFlags |= AFD_OVERLAPPED; } + IOSB->Information = 0; IOSB->Status = STATUS_PENDING; /* Send IOCTL */ @@ -507,15 +597,15 @@ WSPRecvFrom(SOCKET Handle, APCContext, IOSB, IOCTL_AFD_RECV_DATAGRAM, - &RecvInfo, - sizeof(RecvInfo), + RecvInfo, + sizeof(AFD_RECV_INFO_UDP), NULL, 0); /* Wait for completion of not overlapped */ - if (Status == STATUS_PENDING && lpOverlapped == NULL) + if (Status == STATUS_PENDING) { - WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infinitely for receive... + WaitForSingleObject(SockEvent, (lpOverlapped || Socket->SharedData->NonBlocking) ? 0 : INFINITE); // BUGBUG, shouldn wait infintely for receive... Status = IOSB->Status; } @@ -527,11 +617,24 @@ WSPRecvFrom(SOCKET Handle, return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesRead); } - /* Return the Flags */ - *ReceiveFlags = 0; + if (APCFunction) + { + APCContext->lpRecvInfo = NULL; + APCContext->lpCompletionRoutine = NULL; + APCContext->lpSocket = NULL; + /* This will be freed by the APC */ + //HeapFree(GlobalHeap, 0, APCContext); + } + DbgPrint("(sndrcv.c:%d) RecvInfo has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, RecvInfo); - switch (Status) + if (ReceiveFlags) { + /* Return the Flags */ + *ReceiveFlags = 0; + + switch (Status) + { case STATUS_RECEIVE_EXPEDITED: *ReceiveFlags = MSG_OOB; break; @@ -541,22 +644,27 @@ WSPRecvFrom(SOCKET Handle, case STATUS_RECEIVE_PARTIAL: *ReceiveFlags = MSG_PARTIAL; break; + } } - /* Re-enable Async Event */ - if (*ReceiveFlags & MSG_OOB) + if (Status == STATUS_SUCCESS) { - SockReenableAsyncSelectEvent(Socket, FD_OOB); - } - else - { - SockReenableAsyncSelectEvent(Socket, FD_READ); + /* Re-enable Async Event */ + if (ReceiveFlags && *ReceiveFlags & MSG_OOB) + { + SockReenableAsyncSelectEvent(Socket, FD_OOB); + } + else + { + SockReenableAsyncSelectEvent(Socket, FD_READ); + } } + TRACE("Leaving (Success, %ld %ld)\n", Status, IOSB->Information); + if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine) { - lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, *ReceiveFlags); - HeapFree(GlobalHeap, 0, (PVOID)APCContext); + lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, ReceiveFlags != NULL ? *ReceiveFlags : 0); } return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead ); @@ -577,14 +685,16 @@ WSPSend(SOCKET Handle, { PIO_STATUS_BLOCK IOSB; IO_STATUS_BLOCK DummyIOSB; - AFD_SEND_INFO SendInfo; + PAFD_SEND_INFO SendInfo; NTSTATUS Status; - PVOID APCContext; - PVOID APCFunction; + PAFDSENDAPCCONTEXT APCContext; + PIO_APC_ROUTINE APCFunction; HANDLE Event = NULL; HANDLE SockEvent; PSOCKET_INFORMATION Socket; + TRACE("WSPSend Called (%x)\n", Handle); + /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); if (!Socket) @@ -600,30 +710,42 @@ WSPSend(SOCKET Handle, return SOCKET_ERROR; } + /* Allocate a send info buffer */ + DbgPrint("(sndrcv.c:%d) SendInfo has been allocated.\n", __LINE__); + SendInfo = HeapAlloc(GlobalHeap, 0, sizeof(AFD_SEND_INFO)); + if (!SendInfo) + { + if (lpErrno) + *lpErrno = WSAENOBUFS; + return SOCKET_ERROR; + } + Status = NtCreateEvent( &SockEvent, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE ); if( !NT_SUCCESS(Status) ) - return -1; - - TRACE("Called\n"); + { + DbgPrint("(sndrcv.c:%d) SendInfo has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, SendInfo); + return SOCKET_ERROR; + } /* Set up the Send Structure */ - SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers; - SendInfo.BufferCount = dwBufferCount; - SendInfo.TdiFlags = 0; - SendInfo.AfdFlags = Socket->SharedData->NonBlocking ? AFD_IMMEDIATE : 0; + SendInfo->BufferArray = (PAFD_WSABUF)lpBuffers; + SendInfo->BufferCount = dwBufferCount; + SendInfo->TdiFlags = 0; + SendInfo->AfdFlags = Socket->SharedData->NonBlocking ? AFD_IMMEDIATE : 0; /* Set the TDI Flags */ if (iFlags) { if (iFlags & MSG_OOB) { - SendInfo.TdiFlags |= TDI_SEND_EXPEDITED; + SendInfo->TdiFlags |= TDI_SEND_EXPEDITED; } if (iFlags & MSG_PARTIAL) { - SendInfo.TdiFlags |= TDI_SEND_PARTIAL; + SendInfo->TdiFlags |= TDI_SEND_PARTIAL; } } @@ -642,35 +764,39 @@ WSPSend(SOCKET Handle, if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0) { TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n"); - return MsafdReturnWithErrno(0, lpErrno, 0, lpNumberOfBytesSent); + return MsafdReturnWithErrno(STATUS_SUCCESS, lpErrno, 0, lpNumberOfBytesSent); } if (lpCompletionRoutine == NULL) { /* Using Overlapped Structure, but no Completion Routine, so no need for APC */ - APCContext = lpOverlapped; + APCContext = (PAFDSENDAPCCONTEXT)lpOverlapped; APCFunction = NULL; Event = lpOverlapped->hEvent; } else { /* Using Overlapped Structure and a Completion Routine, so use an APC */ - APCFunction = &AfdAPC; // should be a private io completion function inside us - APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT)); + APCFunction = &AfdSendAPC; // should be a private io completion function inside us + DbgPrint("(sndrcv.c:%d) APCContext has been allocated.\n", __LINE__); + APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDSENDAPCCONTEXT)); if (!APCContext) { ERR("Not enough memory for APC Context\n"); return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, lpNumberOfBytesSent); } - ((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = lpCompletionRoutine; - ((PAFDAPCCONTEXT)APCContext)->lpOverlapped = lpOverlapped; - ((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket; - SendInfo.AfdFlags |= AFD_SKIP_FIO; + APCContext->lpCompletionRoutine = lpCompletionRoutine; + APCContext->lpOverlapped = lpOverlapped; + APCContext->lpSocket = Socket; + APCContext->lpSendInfo = SendInfo; + APCContext->lpRemoteAddress = NULL; + SendInfo->AfdFlags |= AFD_SKIP_FIO; } IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; - SendInfo.AfdFlags |= AFD_OVERLAPPED; + SendInfo->AfdFlags |= AFD_OVERLAPPED; } + IOSB->Information = 0; IOSB->Status = STATUS_PENDING; /* Send IOCTL */ @@ -680,15 +806,15 @@ WSPSend(SOCKET Handle, APCContext, IOSB, IOCTL_AFD_SEND, - &SendInfo, - sizeof(SendInfo), + SendInfo, + sizeof(AFD_SEND_INFO), NULL, 0); /* Wait for completion of not overlapped */ - if (Status == STATUS_PENDING && lpOverlapped == NULL) + if (Status == STATUS_PENDING) { - WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infinitely for send... + WaitForSingleObject(SockEvent, (lpOverlapped || Socket->SharedData->NonBlocking) ? 0 : INFINITE); // BUGBUG, shouldn wait infintely for send... Status = IOSB->Status; } @@ -700,15 +826,25 @@ WSPSend(SOCKET Handle, return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent); } + if (APCFunction) + { + APCContext->lpSendInfo = NULL; + APCContext->lpCompletionRoutine = NULL; + APCContext->lpSocket = NULL; + /* This will be freed by the APC */ + //HeapFree(GlobalHeap, 0, APCContext); + } + DbgPrint("(sndrcv.c:%d) SendInfo has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, SendInfo); + /* Re-enable Async Event */ SockReenableAsyncSelectEvent(Socket, FD_WRITE); - TRACE("Leaving (Success, %d)\n", IOSB->Information); + TRACE("Leaving (%ld %ld)\n", Status, IOSB->Information); if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine) { lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, 0); - HeapFree(GlobalHeap, 0, (PVOID)APCContext); } return MsafdReturnWithErrno( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent ); @@ -730,10 +866,10 @@ WSPSendTo(SOCKET Handle, { PIO_STATUS_BLOCK IOSB; IO_STATUS_BLOCK DummyIOSB; - AFD_SEND_INFO_UDP SendInfo; + PAFD_SEND_INFO_UDP SendInfo; NTSTATUS Status; - PVOID APCContext; - PVOID APCFunction; + PAFDSENDAPCCONTEXT APCContext; + PIO_APC_ROUTINE APCFunction; HANDLE Event = NULL; PTRANSPORT_ADDRESS RemoteAddress; PSOCKADDR BindAddress = NULL; @@ -741,6 +877,8 @@ WSPSendTo(SOCKET Handle, HANDLE SockEvent; PSOCKET_INFORMATION Socket; + TRACE("WSPSendTo Called (%x)\n", Handle); + /* Get the Socket Structure associate to this Socket */ Socket = GetSocketStructure(Handle); if (!Socket) @@ -775,6 +913,7 @@ WSPSendTo(SOCKET Handle, { /* Get the Wildcard Address */ BindAddressLength = Socket->HelperData->MaxWSAddressLength; + DbgPrint("(sndrcv.c:%d) BindAddress has been allocated.\n", __LINE__); BindAddress = HeapAlloc(GlobalHeap, 0, BindAddressLength); if (!BindAddress) { @@ -790,11 +929,27 @@ WSPSendTo(SOCKET Handle, return SOCKET_ERROR; } + DbgPrint("(sndrcv.c:%d) RemoteAddress has been allocated.\n", __LINE__); RemoteAddress = HeapAlloc(GlobalHeap, 0, 0x6 + SocketAddressLength); if (!RemoteAddress) { if (BindAddress != NULL) { + DbgPrint("(sndrcv.c:%d) BindAddress has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, BindAddress); + } + return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL); + } + + DbgPrint("(sndrcv.c:%d) SendInfo has been allocated.\n", __LINE__); + SendInfo = HeapAlloc(GlobalHeap, 0, sizeof(AFD_SEND_INFO_UDP)); + if (!SendInfo) + { + DbgPrint("(sndrcv.c:%d) RemoteAddress has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, RemoteAddress); + if (BindAddress != NULL) + { + DbgPrint("(sndrcv.c:%d) BindAddress has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, BindAddress); } return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL); @@ -806,9 +961,13 @@ WSPSendTo(SOCKET Handle, if (!NT_SUCCESS(Status)) { + DbgPrint("(sndrcv.c:%d) SendInfo has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, SendInfo); + DbgPrint("(sndrcv.c:%d) RemoteAddress has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, RemoteAddress); if (BindAddress != NULL) { + DbgPrint("(sndrcv.c:%d) BindAddress has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, BindAddress); } return SOCKET_ERROR; @@ -820,11 +979,11 @@ WSPSendTo(SOCKET Handle, RtlCopyMemory(&RemoteAddress->Address[0].AddressType, SocketAddress, SocketAddressLength); /* Set up Structure */ - SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers; - SendInfo.AfdFlags = Socket->SharedData->NonBlocking ? AFD_IMMEDIATE : 0; - SendInfo.BufferCount = dwBufferCount; - SendInfo.TdiConnection.RemoteAddress = RemoteAddress; - SendInfo.TdiConnection.RemoteAddressLength = Socket->HelperData->MaxTDIAddressLength; + SendInfo->BufferArray = (PAFD_WSABUF)lpBuffers; + SendInfo->AfdFlags = Socket->SharedData->NonBlocking ? AFD_IMMEDIATE : 0; + SendInfo->BufferCount = dwBufferCount; + SendInfo->TdiConnection.RemoteAddress = RemoteAddress; + SendInfo->TdiConnection.RemoteAddressLength = Socket->HelperData->MaxTDIAddressLength; /* Verify if we should use APC */ if (lpOverlapped == NULL) @@ -841,35 +1000,41 @@ WSPSendTo(SOCKET Handle, if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0) { TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n"); - return MsafdReturnWithErrno(0, lpErrno, 0, lpNumberOfBytesSent); + return MsafdReturnWithErrno(STATUS_SUCCESS, lpErrno, 0, lpNumberOfBytesSent); } if (lpCompletionRoutine == NULL) { /* Using Overlapped Structure, but no Completion Routine, so no need for APC */ - APCContext = lpOverlapped; + APCContext = (PAFDSENDAPCCONTEXT)lpOverlapped; APCFunction = NULL; Event = lpOverlapped->hEvent; } else { /* Using Overlapped Structure and a Completion Routine, so use an APC */ - APCFunction = &AfdAPC; // should be a private io completion function inside us - APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT)); + APCFunction = &AfdSendAPC; // should be a private io completion function inside us + DbgPrint("(sndrcv.c:%d) APCContext has been allocated.\n", __LINE__); + APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDSENDAPCCONTEXT)); if (!APCContext) { ERR("Not enough memory for APC Context\n"); return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, lpNumberOfBytesSent); } - ((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = lpCompletionRoutine; - ((PAFDAPCCONTEXT)APCContext)->lpOverlapped = lpOverlapped; - ((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket; - SendInfo.AfdFlags |= AFD_SKIP_FIO; + APCContext->lpCompletionRoutine = lpCompletionRoutine; + APCContext->lpOverlapped = lpOverlapped; + APCContext->lpSocket = Socket; + APCContext->lpSendInfo = SendInfo; + APCContext->lpRemoteAddress = RemoteAddress; + SendInfo->AfdFlags |= AFD_SKIP_FIO; } IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; - SendInfo.AfdFlags |= AFD_OVERLAPPED; + SendInfo->AfdFlags |= AFD_OVERLAPPED; } + IOSB->Information = 0; + IOSB->Status = STATUS_PENDING; + /* Send IOCTL */ Status = NtDeviceIoControlFile((HANDLE)Handle, Event, @@ -877,23 +1042,24 @@ WSPSendTo(SOCKET Handle, APCContext, IOSB, IOCTL_AFD_SEND_DATAGRAM, - &SendInfo, - sizeof(SendInfo), + SendInfo, + sizeof(AFD_SEND_INFO_UDP), NULL, 0); /* Wait for completion of not overlapped */ - if (Status == STATUS_PENDING && lpOverlapped == NULL) + if (Status == STATUS_PENDING) { /* BUGBUG, shouldn't wait infinitely for send... */ - WaitForSingleObject(SockEvent, INFINITE); + WaitForSingleObject(SockEvent, (lpOverlapped || Socket->SharedData->NonBlocking) ? 0 : INFINITE); Status = IOSB->Status; } NtClose(SockEvent); - HeapFree(GlobalHeap, 0, RemoteAddress); + if (BindAddress != NULL) { + DbgPrint("(sndrcv.c:%d) BindAddress has been freed.\n", __LINE__); HeapFree(GlobalHeap, 0, BindAddress); } @@ -902,13 +1068,27 @@ WSPSendTo(SOCKET Handle, TRACE("Leaving (Pending)\n"); return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent); } + if (APCFunction) + { + APCContext->lpSendInfo = NULL; + APCContext->lpRemoteAddress = NULL; + APCContext->lpCompletionRoutine = NULL; + APCContext->lpSocket = NULL; + /* This will be freed by the APC */ + //HeapFree(GlobalHeap, 0, APCContext); + } + DbgPrint("(sndrcv.c:%d) SendInfo has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, SendInfo); + DbgPrint("(sndrcv.c:%d) RemoteAddress has been freed.\n", __LINE__); + HeapFree(GlobalHeap, 0, RemoteAddress); SockReenableAsyncSelectEvent(Socket, FD_WRITE); + TRACE("Leaving (%ld %ld)\n", Status, IOSB->Information); + if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine) { lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, 0); - HeapFree(GlobalHeap, 0, (PVOID)APCContext); } return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent); diff --git a/dll/win32/msafd/msafd.h b/dll/win32/msafd/msafd.h index 87b0125cc4..0b3531aac2 100644 --- a/dll/win32/msafd/msafd.h +++ b/dll/win32/msafd/msafd.h @@ -133,12 +133,38 @@ typedef struct _ASYNC_DATA { AFD_POLL_INFO AsyncSelectInfo; } ASYNC_DATA, *PASYNC_DATA; -typedef struct _AFDAPCCONTEXT +typedef struct _AFDINFOAPCCONTEXT +{ + LPWSAOVERLAPPED lpOverlapped; + LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine; +} AFDINFOAPCCONTEXT, *PAFDINFOAPCCONTEXT; + +typedef struct _AFDSENDAPCCONTEXT { LPWSAOVERLAPPED lpOverlapped; LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine; PSOCKET_INFORMATION lpSocket; -} AFDAPCCONTEXT, *PAFDAPCCONTEXT; + IO_STATUS_BLOCK IoStatusBlock; + LPVOID lpSendInfo; + PTRANSPORT_ADDRESS lpRemoteAddress; +} AFDSENDAPCCONTEXT, *PAFDSENDAPCCONTEXT; + +typedef struct _AFDRECVAPCCONTEXT +{ + LPWSAOVERLAPPED lpOverlapped; + LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine; + PSOCKET_INFORMATION lpSocket; + IO_STATUS_BLOCK IoStatusBlock; + LPVOID lpRecvInfo; +} AFDRECVAPCCONTEXT, *PAFDRECVAPCCONTEXT; + +typedef struct _AFDCONNECTAPCCONTEXT +{ + PAFD_CONNECT_INFO lpConnectInfo; + PSOCKET_INFORMATION lpSocket; + IO_STATUS_BLOCK IoStatusBlock; +} AFDCONNECTAPCCONTEXT, *PAFDCONNECTAPCCONTEXT; + _Must_inspect_result_ SOCKET @@ -548,6 +574,9 @@ MsafdReturnWithErrno(NTSTATUS Status, DWORD Received, LPDWORD ReturnedBytes) { + /* Allow for APC to be processed */ + SleepEx(0, TRUE); + if (Errno) { *Errno = TranslateNtStatusError(Status); @@ -559,7 +588,7 @@ MsafdReturnWithErrno(NTSTATUS Status, } else { - DbgPrint("%s: Received invalid lpErrno pointer!\n", __FUNCTION__); + //DbgPrint("%s: Received invalid lpErrno pointer!\n", __FUNCTION__); if (ReturnedBytes) *ReturnedBytes = (Status == STATUS_SUCCESS) ? Received : 0; diff --git a/drivers/network/afd/afd/tdi.c b/drivers/network/afd/afd/tdi.c index 75085bcc22..84e4384edc 100644 --- a/drivers/network/afd/afd/tdi.c +++ b/drivers/network/afd/afd/tdi.c @@ -966,11 +966,9 @@ NTSTATUS TdiSend( Flags, /* Flags */ BufferLength); /* Length of data */ - TdiCall(*Irp, DeviceObject, NULL, NULL); /* Does not block... The MDL is deleted in the receive completion routine. */ - - return STATUS_PENDING; + return TdiCall(*Irp, DeviceObject, NULL, NULL); } NTSTATUS TdiReceive( @@ -1239,11 +1237,9 @@ NTSTATUS TdiSendDatagram( BufferLength, /* Bytes to send */ Addr); /* Address */ - TdiCall(*Irp, DeviceObject, NULL, NULL); /* Does not block... The MDL is deleted in the send completion routine. */ - - return STATUS_PENDING; + return TdiCall(*Irp, DeviceObject, NULL, NULL); } NTSTATUS TdiDisconnect( diff --git a/drivers/network/afd/afd/write.c b/drivers/network/afd/afd/write.c index 29ad9501b7..f7cd38c6e5 100644 --- a/drivers/network/afd/afd/write.c +++ b/drivers/network/afd/afd/write.c @@ -379,6 +379,10 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, Status = QueueUserModeIrp(FCB, Irp, FUNCTION_SEND); if (Status == STATUS_PENDING) { + if (SendReq->BufferCount > 1) + { + AFD_DbgPrint(MIN_TRACE,("WARN: More than one buffer %ld!\n", SendReq->BufferCount)); + } Status = TdiSendDatagram(&FCB->SendIrp.InFlightRequest, FCB->AddressFile.Object, SendReq->BufferArray[0].buf, @@ -390,7 +394,7 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, { NT_VERIFY(RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]) == &Irp->Tail.Overlay.ListEntry); Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = 0; + Irp->IoStatus.Information = Status == STATUS_SUCCESS ? SendReq->BufferArray[0].len : 0; (void)IoSetCancelRoutine(Irp, NULL); UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); UnlockRequest(Irp, IoGetCurrentIrpStackLocation(Irp)); @@ -645,6 +649,10 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, Status = QueueUserModeIrp(FCB, Irp, FUNCTION_SEND); if (Status == STATUS_PENDING) { + if (SendReq->BufferCount > 1) + { + AFD_DbgPrint(MIN_TRACE,("WARN: More than one buffer %ld!\n", SendReq->BufferCount)); + } Status = TdiSendDatagram(&FCB->SendIrp.InFlightRequest, FCB->AddressFile.Object, SendReq->BufferArray[0].buf, @@ -656,7 +664,7 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, { NT_VERIFY(RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]) == &Irp->Tail.Overlay.ListEntry); Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = 0; + Irp->IoStatus.Information = Status == STATUS_SUCCESS ? SendReq->BufferArray[0].len : 0; (void)IoSetCancelRoutine(Irp, NULL); UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); UnlockRequest(Irp, IoGetCurrentIrpStackLocation(Irp)); diff --git a/sdk/lib/drivers/ip/transport/tcp/tcp.c b/sdk/lib/drivers/ip/transport/tcp/tcp.c index 675971bb2a..0bbd5db178 100644 --- a/sdk/lib/drivers/ip/transport/tcp/tcp.c +++ b/sdk/lib/drivers/ip/transport/tcp/tcp.c @@ -337,8 +337,12 @@ NTSTATUS TCPConnect if (NT_SUCCESS(Status)) { - /* Copy bind address into connection */ - Connection->AddressFile->Address.Address.IPv4Address = bindaddr.addr; + /* Check if we had an unspecified address */ + if (Connection->AddressFile->Address.Address.IPv4Address != bindaddr.addr) + { + /* We did, so we need to copy back the address */ + Connection->AddressFile->Address.Address.IPv4Address = bindaddr.addr; + } /* Check if we had an unspecified port */ if (!Connection->AddressFile->Port) {