From: "Erich E. Hoover" Subject: [PATCH 2/5] ws2_32: Check for invalid parameters in TransmitFile. Message-Id: Date: Sat, 3 Oct 2015 14:38:05 -0600 This patch adds some validation to the socket passed for TransmitFile operations. There's no point in going to the trouble to perform a TransmitFile operation on a socket that's not setup correctly. From 8d64fb12697735fc401b6f03eb59a78518089cb6 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Fri, 17 Jan 2014 12:35:57 -0700 Subject: ws2_32: Check for invalid parameters in TransmitFile. Signed-off-by: Erich E. Hoover --- dlls/ws2_32/socket.c | 21 ++++++++++ dlls/ws2_32/tests/sock.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index a5f83aa..1e7e133 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -2731,8 +2731,29 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD LPOVERLAPPED overlapped, LPTRANSMIT_FILE_BUFFERS buffers, DWORD flags ) { + union generic_unix_sockaddr uaddr; + unsigned int uaddrlen = sizeof(uaddr); + int fd; + FIXME("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, file_bytes, bytes_per_send, overlapped, buffers, flags ); + + fd = get_sock_fd( s, 0, NULL ); + if (fd == -1) + { + WSASetLastError( WSAENOTSOCK ); + return FALSE; + } + if (getpeername( fd, &uaddr.addr, &uaddrlen ) != 0) + { + release_sock_fd( s, fd ); + WSASetLastError( WSAENOTCONN ); + return FALSE; + } + release_sock_fd( s, fd ); + if (flags) + FIXME("Flags are not currently supported (0x%x).\n", flags); + WSASetLastError( WSAEOPNOTSUPP ); return FALSE; } diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 8a0e375..3c5d352 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -7403,6 +7403,108 @@ end: closesocket(connector2); } +static void test_TransmitFile(void) +{ + GUID transmitFileGuid = WSAID_TRANSMITFILE; + LPFN_TRANSMITFILE pTransmitFile = NULL; + HANDLE file = INVALID_HANDLE_VALUE; + char system_ini_path[MAX_PATH]; + struct sockaddr_in bindAddress; + SOCKET client, server, dest; + DWORD num_bytes, err; + int iret, len; + BOOL bret; + + /* Setup sockets for testing TransmitFile */ + client = socket(AF_INET, SOCK_STREAM, 0); + server = socket(AF_INET, SOCK_STREAM, 0); + if (client == INVALID_SOCKET || server == INVALID_SOCKET) + { + skip("could not create acceptor socket, error %d\n", WSAGetLastError()); + goto cleanup; + } + iret = WSAIoctl(client, SIO_GET_EXTENSION_FUNCTION_POINTER, &transmitFileGuid, sizeof(transmitFileGuid), + &pTransmitFile, sizeof(pTransmitFile), &num_bytes, NULL, NULL); + if (iret) + { + skip("WSAIoctl failed to get TransmitFile with ret %d + errno %d\n", iret, WSAGetLastError()); + goto cleanup; + } + GetSystemWindowsDirectoryA(system_ini_path, MAX_PATH ); + strcat(system_ini_path, "\\system.ini"); + file = CreateFileA(system_ini_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0x0, NULL); + if (file == INVALID_HANDLE_VALUE) + { + skip("Unable to open a file to transmit.\n"); + goto cleanup; + } + + /* Test TransmitFile with an invalid socket */ + bret = pTransmitFile(INVALID_SOCKET, file, 0, 0, NULL, NULL, 0); + err = WSAGetLastError(); + ok(!bret, "TransmitFile succeeded unexpectedly.\n"); + ok(err == WSAENOTSOCK, "TransmitFile triggered unexpected errno (%d != %d)\n", err, WSAENOTSOCK); + + /* Test a bogus TransmitFile without a connected socket */ + bret = pTransmitFile(client, NULL, 0, 0, NULL, NULL, TF_REUSE_SOCKET); + err = WSAGetLastError(); + ok(!bret, "TransmitFile succeeded unexpectedly.\n"); + ok(err == WSAENOTCONN, "TransmitFile triggered unexpected errno (%d != %d)\n", err, WSAENOTCONN); + + /* Setup a properly connected socket for transfers */ + memset(&bindAddress, 0, sizeof(bindAddress)); + bindAddress.sin_family = AF_INET; + bindAddress.sin_port = htons(9375); + bindAddress.sin_addr.s_addr = inet_addr("127.0.0.1"); + iret = bind(server, (struct sockaddr*)&bindAddress, sizeof(bindAddress)); + if (iret != 0) + { + skip("failed to bind(), error %d\n", WSAGetLastError()); + goto cleanup; + } + iret = listen(server, 1); + if (iret != 0) + { + skip("failed to listen(), error %d\n", WSAGetLastError()); + goto cleanup; + } + iret = connect(client, (struct sockaddr*)&bindAddress, sizeof(bindAddress)); + if (iret != 0) + { + skip("failed to connect(), error %d\n", WSAGetLastError()); + goto cleanup; + } + len = sizeof(bindAddress); + dest = accept(server, (struct sockaddr*)&bindAddress, &len); + if (dest == INVALID_SOCKET) + { + skip("failed to accept(), error %d\n", WSAGetLastError()); + goto cleanup; + } + if (set_blocking(dest, FALSE)) + { + skip("couldn't make socket non-blocking, error %d\n", WSAGetLastError()); + goto cleanup; + } + + /* Test TransmitFile with no possible buffer */ + bret = pTransmitFile(client, NULL, 0, 0, NULL, NULL, 0); + todo_wine ok(bret, "TransmitFile failed unexpectedly.\n"); + + /* Test TransmitFile with a UDP datagram socket */ + closesocket(client); + client = socket(AF_INET, SOCK_DGRAM, 0); + bret = pTransmitFile(client, NULL, 0, 0, NULL, NULL, 0); + err = WSAGetLastError(); + ok(!bret, "TransmitFile succeeded unexpectedly.\n"); + ok(err == WSAENOTCONN, "TransmitFile triggered unexpected errno (%d != %d)\n", err, WSAENOTCONN); + +cleanup: + CloseHandle(file); + closesocket(client); + closesocket(server); +} + static void test_getpeername(void) { SOCKET sock; @@ -8771,6 +8873,7 @@ START_TEST( sock ) test_events(1); test_ipv6only(); + test_TransmitFile(); test_GetAddrInfoW(); test_getaddrinfo(); test_AcceptEx(); -- 1.9.1