diff --git a/debian/changelog b/debian/changelog index f1269f00..ce9b9dd7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ wine-staging (1.7.38) UNRELEASED; urgency=low * Various improvements to patchupdate.py. * Various improvements to dxva2 vaapi support. + * Long overdue update to the TransmitFile patches. * Disabled patchset for reg.exe cleanup (partially accepted upstream). * Disabled patchset for TransmitFile (rewrite in progress). * Added patch to mark DllCanUnloadNow and DllGetClassObject as private (by Amine Khaldi, wine-patched/pull/3). diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index a8e0e080..81612051 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -219,6 +219,7 @@ patch_enable_all () enable_wpcap_Dynamic_Linking="$1" enable_ws2_32_APC_Performance="$1" enable_ws2_32_Connect_Time="$1" + enable_ws2_32_TransmitFile="$1" enable_ws2_32_WriteWatches="$1" enable_ws2_32_getaddrinfo="$1" enable_wtsapi32_EnumerateProcesses="$1" @@ -699,6 +700,9 @@ patch_enable () ws2_32-Connect_Time) enable_ws2_32_Connect_Time="$2" ;; + ws2_32-TransmitFile) + enable_ws2_32_TransmitFile="$2" + ;; ws2_32-WriteWatches) enable_ws2_32_WriteWatches="$2" ;; @@ -4280,6 +4284,33 @@ if test "$enable_ws2_32_Connect_Time" -eq 1; then ) >> "$patchlist" fi +# Patchset ws2_32-TransmitFile +# | +# | This patchset fixes the following Wine bugs: +# | * [#5048] Support for TransmitFile +# | +# | Modified files: +# | * dlls/ws2_32/socket.c, dlls/ws2_32/tests/sock.c, include/winsock.h, server/protocol.def, server/sock.c +# | +if test "$enable_ws2_32_TransmitFile" -eq 1; then + patch_apply ws2_32-TransmitFile/0001-ws2_32-Add-stub-for-TransmitFile.patch + patch_apply ws2_32-TransmitFile/0002-ws2_32-Check-for-invalid-parameters-in-TransmitFile.patch + patch_apply ws2_32-TransmitFile/0003-ws2_32-Implement-a-basic-synchronous-TransmitFile.patch + patch_apply ws2_32-TransmitFile/0004-ws2_32-Add-support-for-TransmitFile-headers-and-foot.patch + patch_apply ws2_32-TransmitFile/0005-ws2_32-Add-asynchronous-support-for-TransmitFile.patch + patch_apply ws2_32-TransmitFile/0006-ws2_32-Add-support-for-TF_DISCONNECT-to-TransmitFile.patch + patch_apply ws2_32-TransmitFile/0007-ws2_32-Add-support-for-TF_REUSE_SOCKET-to-TransmitFi.patch + ( + echo '+ { "Erich E. Hoover", "ws2_32: Add stub for TransmitFile.", 1 },'; + echo '+ { "Erich E. Hoover", "ws2_32: Check for invalid parameters in TransmitFile.", 1 },'; + echo '+ { "Erich E. Hoover", "ws2_32: Implement a basic synchronous TransmitFile.", 1 },'; + echo '+ { "Erich E. Hoover", "ws2_32: Add support for TransmitFile headers and footers.", 1 },'; + echo '+ { "Erich E. Hoover", "ws2_32: Add asynchronous support for TransmitFile.", 1 },'; + echo '+ { "Erich E. Hoover", "ws2_32: Add support for TF_DISCONNECT to TransmitFile.", 1 },'; + echo '+ { "Erich E. Hoover", "ws2_32: Add support for TF_REUSE_SOCKET to TransmitFile.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ws2_32-getaddrinfo # | # | This patchset fixes the following Wine bugs: diff --git a/patches/ws2_32-TransmitFile/0001-ws2_32-Add-stub-for-TransmitFile.patch b/patches/ws2_32-TransmitFile/0001-ws2_32-Add-stub-for-TransmitFile.patch index 4dd45e85..37a76f95 100644 --- a/patches/ws2_32-TransmitFile/0001-ws2_32-Add-stub-for-TransmitFile.patch +++ b/patches/ws2_32-TransmitFile/0001-ws2_32-Add-stub-for-TransmitFile.patch @@ -1,27 +1,28 @@ -From 56a72cb0a034dd7b3cc6ac68ad2d296c7f2ac47b Mon Sep 17 00:00:00 2001 +From 503facafdcc2a11ed60058d86214f724ecbec851 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 16 Jan 2014 17:52:50 -0700 Subject: ws2_32: Add stub for TransmitFile. --- - dlls/ws2_32/socket.c | 15 ++++++++++++++- - 1 file changed, 14 insertions(+), 1 deletion(-) + dlls/ws2_32/socket.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c -index d5e9fd1..07d2a47 100644 +index 5bfdecf..536dbc9 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c -@@ -2485,6 +2485,18 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW +@@ -2538,6 +2538,19 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW } /*********************************************************************** + * TransmitFile + */ -+static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWORD bytes_per_send, -+ LPOVERLAPPED overlapped, LPTRANSMIT_FILE_BUFFERS buffers, DWORD flags ) ++static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD bytes_per_send, ++ LPOVERLAPPED overlapped, LPTRANSMIT_FILE_BUFFERS buffers, ++ DWORD flags ) +{ -+ FIXME("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, total_bytes, bytes_per_send, overlapped, buffers, -+ flags ); ++ FIXME("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, file_bytes, bytes_per_send, overlapped, ++ buffers, flags ); + WSASetLastError( WSAEOPNOTSUPP ); + return FALSE; +} @@ -30,7 +31,7 @@ index d5e9fd1..07d2a47 100644 * GetAcceptExSockaddrs */ static void WINAPI WS2_GetAcceptExSockaddrs(PVOID buffer, DWORD data_size, DWORD local_size, DWORD remote_size, -@@ -4031,7 +4043,8 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID +@@ -4163,7 +4176,8 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID } else if ( IsEqualGUID(&transmitfile_guid, in_buff) ) { @@ -41,5 +42,5 @@ index d5e9fd1..07d2a47 100644 else if ( IsEqualGUID(&transmitpackets_guid, in_buff) ) { -- -1.7.9.5 +1.9.1 diff --git a/patches/ws2_32-TransmitFile/0002-ws2_32-Check-for-invalid-parameters-in-TransmitFile.patch b/patches/ws2_32-TransmitFile/0002-ws2_32-Check-for-invalid-parameters-in-TransmitFile.patch index 635e21ac..c89b4d79 100644 --- a/patches/ws2_32-TransmitFile/0002-ws2_32-Check-for-invalid-parameters-in-TransmitFile.patch +++ b/patches/ws2_32-TransmitFile/0002-ws2_32-Check-for-invalid-parameters-in-TransmitFile.patch @@ -1,32 +1,32 @@ -From 75ceb8ccd7dcf5908f7a1fcf9ef4d20b71f4148a Mon Sep 17 00:00:00 2001 +From bc996ca58033c91065f86980d1fd3eac2dd8be66 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. --- - dlls/ws2_32/socket.c | 21 ++++++++++ - dlls/ws2_32/tests/sock.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++ + 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 07d2a47..597b248 100644 +index 536dbc9..5b4996e 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c -@@ -2490,8 +2490,29 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW - static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWORD bytes_per_send, - LPOVERLAPPED overlapped, LPTRANSMIT_FILE_BUFFERS buffers, DWORD flags ) +@@ -2544,8 +2544,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, total_bytes, bytes_per_send, overlapped, buffers, - flags ); + 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) + { -+ SetLastError( WSAENOTSOCK ); ++ WSASetLastError( WSAENOTSOCK ); + return FALSE; + } + if (getpeername( fd, &uaddr.addr, &uaddrlen ) != 0) @@ -43,10 +43,10 @@ index 07d2a47..597b248 100644 return FALSE; } diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c -index 8a9cbba..dc393e6 100644 +index 7155a09..0991e54 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c -@@ -6491,6 +6491,108 @@ end: +@@ -6906,6 +6906,108 @@ end: closesocket(connector2); } @@ -155,7 +155,7 @@ index 8a9cbba..dc393e6 100644 static void test_getpeername(void) { SOCKET sock; -@@ -7726,6 +7828,7 @@ START_TEST( sock ) +@@ -8266,6 +8368,7 @@ START_TEST( sock ) test_events(1); test_ipv6only(); @@ -164,5 +164,5 @@ index 8a9cbba..dc393e6 100644 test_getaddrinfo(); test_AcceptEx(); -- -1.7.9.5 +1.9.1 diff --git a/patches/ws2_32-TransmitFile/0003-ws2_32-Implement-a-basic-synchronous-TransmitFile.patch b/patches/ws2_32-TransmitFile/0003-ws2_32-Implement-a-basic-synchronous-TransmitFile.patch index da4a4ce1..5b9527f9 100644 --- a/patches/ws2_32-TransmitFile/0003-ws2_32-Implement-a-basic-synchronous-TransmitFile.patch +++ b/patches/ws2_32-TransmitFile/0003-ws2_32-Implement-a-basic-synchronous-TransmitFile.patch @@ -1,109 +1,194 @@ -From 0f64d07b3c3a28427b75cfa39b60274d9995dbc8 Mon Sep 17 00:00:00 2001 +From a48693d8345a2e8d45083e0746e1bf801f086aa6 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 16 Jan 2014 18:24:27 -0700 Subject: ws2_32: Implement a basic synchronous TransmitFile. --- - dlls/ws2_32/socket.c | 66 +++++++++++++++++++++++++++++++++++++++++++- - dlls/ws2_32/tests/sock.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 135 insertions(+), 2 deletions(-) + dlls/ws2_32/socket.c | 138 ++++++++++++++++++++++++++++++++++++++++++++--- + dlls/ws2_32/tests/sock.c | 36 ++++++++++++- + 2 files changed, 167 insertions(+), 7 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c -index f09de26..41026fd 100644 +index 5b4996e..6598f7c 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c -@@ -2487,6 +2487,65 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW +@@ -378,6 +378,18 @@ struct ws2_accept_async + struct ws2_async *read; + }; + ++typedef struct ws2_transmitfile_async ++{ ++ struct ws2_async_io io; ++ char *buffer; ++ HANDLE file; ++ DWORD file_read; ++ DWORD file_bytes; ++ DWORD bytes_per_send; ++ DWORD flags; ++ struct ws2_async write; ++} ws2_transmitfile_async; ++ + static struct ws2_async_io *async_io_freelist; + + static void release_async_io( struct ws2_async_io *io ) +@@ -2538,6 +2550,70 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW } /*********************************************************************** ++ * WS2_transmitfile_getbuffer (INTERNAL) ++ * ++ * Pick the appropriate buffer for a TransmitFile send operation. ++ */ ++static NTSTATUS WS2_transmitfile_getbuffer( int fd, struct ws2_transmitfile_async *wsa ) ++{ ++ /* send any incomplete writes from a previous iteration */ ++ if (wsa->write.first_iovec < wsa->write.n_iovecs) ++ return STATUS_PENDING; ++ ++ /* process the main file */ ++ if (wsa->file) ++ { ++ DWORD bytes_per_send = wsa->bytes_per_send; ++ IO_STATUS_BLOCK iosb; ++ NTSTATUS status; ++ ++ /* when the size of the transfer is limited ensure that we don't go past that limit */ ++ if (wsa->file_bytes != 0) ++ bytes_per_send = min(wsa->bytes_per_send, wsa->file_bytes - wsa->file_read); ++ status = NtReadFile( wsa->file, 0, NULL, NULL, &iosb, wsa->buffer, bytes_per_send, ++ NULL, NULL ); ++ if(status == STATUS_END_OF_FILE) ++ return STATUS_SUCCESS; ++ else if(status != STATUS_SUCCESS) ++ return status; ++ else ++ { ++ wsa->write.first_iovec = 0; ++ wsa->write.n_iovecs = 1; ++ wsa->write.iovec[0].iov_base = wsa->buffer; ++ wsa->write.iovec[0].iov_len = iosb.Information; ++ wsa->file_read += iosb.Information; ++ if (wsa->file_bytes != 0 && wsa->file_read >= wsa->file_bytes) ++ wsa->file = NULL; ++ return STATUS_PENDING; ++ } ++ } ++ ++ return STATUS_SUCCESS; ++} ++ ++/*********************************************************************** + * WS2_transmitfile_base (INTERNAL) + * + * Shared implementation for both synchronous and asynchronous TransmitFile. + */ -+static BOOL WS2_transmitfile_base( SOCKET s, HANDLE h, DWORD total_bytes, DWORD bytes_per_send, -+ LPOVERLAPPED overlapped, LPTRANSMIT_FILE_BUFFERS buffers, -+ DWORD flags ) ++static NTSTATUS WS2_transmitfile_base( int fd, struct ws2_transmitfile_async *wsa ) +{ -+ DWORD bytes_sent = 0; -+ char *buffer = NULL; -+ BOOL ret = FALSE; ++ NTSTATUS status; + -+ /* set reasonable defaults when requested */ -+ if (!bytes_per_send) -+ bytes_per_send = 1024; -+ -+ /* send the header (if applicable) */ -+ if (buffers && WS_send( s, buffers->Head, buffers->HeadLength, 0 ) == SOCKET_ERROR) -+ goto cleanup; -+ -+ /* process the main file */ -+ if (h) ++ status = WS2_transmitfile_getbuffer( fd, wsa ); ++ if (status == STATUS_PENDING) + { -+ buffer = HeapAlloc( GetProcessHeap(), 0, bytes_per_send ); -+ if (!buffer) goto cleanup; ++ DWORD n; + -+ /* read and send the data from the file */ -+ do -+ { -+ DWORD n = 0; -+ BOOL ok; -+ -+ /* when the size of the transfer is limited ensure that we don't go past that limit */ -+ if (total_bytes != 0) -+ bytes_per_send = min(bytes_per_send, total_bytes - bytes_sent); -+ ok = ReadFile( h, buffer, bytes_per_send, &n, NULL ); -+ if (ok && n == 0) -+ break; -+ else if(!ok) -+ goto cleanup; -+ n = WS_send( s, buffer, n, 0 ); -+ if (n == SOCKET_ERROR) -+ goto cleanup; -+ bytes_sent += n; -+ } while(total_bytes == 0 || bytes_sent < total_bytes); ++ n = WS2_send( fd, &wsa->write ); ++ if (n == -1) ++ return wsaErrStatus(); + } -+ -+ /* send the footer (if applicable) */ -+ if (buffers && WS_send( s, buffers->Tail, buffers->TailLength, 0 ) == SOCKET_ERROR) -+ goto cleanup; -+ -+ ret = TRUE; -+ -+cleanup: -+ HeapFree( GetProcessHeap(), 0, buffer ); -+ return ret; ++ return status; +} + +/*********************************************************************** * TransmitFile */ - static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWORD bytes_per_send, -@@ -2496,7 +2555,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR + static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD bytes_per_send, +@@ -2546,12 +2622,22 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD + { + union generic_unix_sockaddr uaddr; unsigned int uaddrlen = sizeof(uaddr); ++ struct ws2_transmitfile_async *wsa; ++ NTSTATUS status; int fd; -- FIXME("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, total_bytes, bytes_per_send, overlapped, buffers, -+ TRACE("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, total_bytes, bytes_per_send, overlapped, buffers, - flags ); +- FIXME("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, file_bytes, bytes_per_send, overlapped, +- buffers, flags ); ++ if (overlapped || buffers) ++ { ++ FIXME("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, file_bytes, bytes_per_send, ++ overlapped, buffers, flags); ++ WSASetLastError( WSAEOPNOTSUPP ); ++ return FALSE; ++ } - fd = get_sock_fd( s, 0, NULL ); -@@ -2515,6 +2574,11 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR +- fd = get_sock_fd( s, 0, NULL ); ++ TRACE("(%lx, %p, %d, %d, %p, %p, %d)\n", s, h, file_bytes, bytes_per_send, overlapped, ++ buffers, flags ); ++ ++ fd = get_sock_fd( s, FILE_WRITE_DATA, NULL ); + if (fd == -1) + { + WSASetLastError( WSAENOTSOCK ); +@@ -2563,12 +2649,52 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD + WSASetLastError( WSAENOTCONN ); + return FALSE; + } +- release_sock_fd( s, fd ); if (flags) FIXME("Flags are not currently supported (0x%x).\n", flags); -+ if (!overlapped) -+ return WS2_transmitfile_base( s, h, total_bytes, bytes_per_send, overlapped, buffers, flags ); +- WSASetLastError( WSAEOPNOTSUPP ); +- return FALSE; ++ /* set reasonable defaults when requested */ ++ if (!bytes_per_send) ++ bytes_per_send = 1024; + -+ FIXME("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, total_bytes, bytes_per_send, overlapped, buffers, -+ flags ); - WSASetLastError( WSAEOPNOTSUPP ); - return FALSE; ++ if (!(wsa = (struct ws2_transmitfile_async *)alloc_async_io( sizeof(*wsa) + bytes_per_send ))) ++ { ++ release_sock_fd( s, fd ); ++ WSASetLastError( WSAEFAULT ); ++ return FALSE; ++ } ++ wsa->buffer = (char *)(wsa + 1); ++ wsa->file = h; ++ wsa->file_read = 0; ++ wsa->file_bytes = file_bytes; ++ wsa->bytes_per_send = bytes_per_send; ++ wsa->flags = flags; ++ wsa->write.hSocket = SOCKET2HANDLE(s); ++ wsa->write.addr = NULL; ++ wsa->write.addrlen.val = 0; ++ wsa->write.flags = 0; ++ wsa->write.lpFlags = &wsa->flags; ++ wsa->write.control = NULL; ++ wsa->write.n_iovecs = 0; ++ wsa->write.first_iovec = 0; ++ wsa->write.user_overlapped = NULL; ++ ++ do ++ { ++ status = WS2_transmitfile_base( fd, wsa ); ++ if (status == STATUS_PENDING) ++ { ++ /* block here */ ++ do_block(fd, POLLOUT, -1); ++ _sync_sock_state(s); /* let wineserver notice connection */ ++ } ++ } ++ while (status == STATUS_PENDING); ++ release_sock_fd( s, fd ); ++ ++ if (status != STATUS_SUCCESS) ++ WSASetLastError( NtStatusToWSAError(status) ); ++ HeapFree( GetProcessHeap(), 0, wsa ); ++ return (status == STATUS_SUCCESS); } + + /*********************************************************************** diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c -index 93d6849..8a560f7 100644 +index 0991e54..1288694 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c -@@ -6905,15 +6905,45 @@ end: +@@ -6906,6 +6906,32 @@ end: closesocket(connector2); } @@ -136,20 +221,15 @@ index 93d6849..8a560f7 100644 static void test_TransmitFile(void) { GUID transmitFileGuid = WSAID_TRANSMITFILE; - LPFN_TRANSMITFILE pTransmitFile = NULL; - HANDLE file = INVALID_HANDLE_VALUE; -+ char header_msg[] = "hello world"; -+ char footer_msg[] = "goodbye!!!"; - char system_ini_path[MAX_PATH]; +@@ -6915,6 +6941,7 @@ static void test_TransmitFile(void) struct sockaddr_in bindAddress; -+ TRANSMIT_FILE_BUFFERS buffers; SOCKET client, server, dest; DWORD num_bytes, err; + char buf[256]; int iret, len; BOOL bret; -@@ -6991,7 +7021,46 @@ static void test_TransmitFile(void) +@@ -6992,7 +7019,14 @@ static void test_TransmitFile(void) /* Test TransmitFile with no possible buffer */ bret = pTransmitFile(client, NULL, 0, 0, NULL, NULL, 0); @@ -158,45 +238,13 @@ index 93d6849..8a560f7 100644 + iret = recv(dest, buf, sizeof(buf), 0); + ok(iret == -1, "Returned an unexpected buffer from TransmitFile (%d != -1).\n", iret); + -+ /* Test TransmitFile with only buffer data */ -+ buffers.Head = &header_msg[0]; -+ buffers.HeadLength = sizeof(header_msg)+1; -+ buffers.Tail = &footer_msg[0]; -+ buffers.TailLength = sizeof(footer_msg)+1; -+ bret = pTransmitFile(client, NULL, 0, 0, NULL, &buffers, 0); -+ ok(bret, "TransmitFile failed unexpectedly.\n"); -+ iret = recv(dest, buf, sizeof(buf), 0); -+ ok(iret == sizeof(header_msg)+sizeof(footer_msg)+2, -+ "Returned an unexpected buffer from TransmitFile (%d != %d).\n", iret, -+ (int)(sizeof(header_msg)+sizeof(footer_msg)+2)); -+ ok(memcmp(&buf[0], &header_msg[0], sizeof(header_msg)+1) == 0, -+ "TransmitFile header buffer did not match!\n"); -+ ok(memcmp(&buf[sizeof(header_msg)+1], &footer_msg[0], sizeof(footer_msg)+1) == 0, -+ "TransmitFile footer buffer did not match!\n"); -+ + /* Test TransmitFile with only file data */ + bret = pTransmitFile(client, file, 0, 0, NULL, NULL, 0); + ok(bret, "TransmitFile failed unexpectedly.\n"); + compare_file(file, dest); -+ -+ /* Test TransmitFile with both file and buffer data */ -+ buffers.Head = &header_msg[0]; -+ buffers.HeadLength = sizeof(header_msg)+1; -+ buffers.Tail = &footer_msg[0]; -+ buffers.TailLength = sizeof(footer_msg)+1; -+ SetFilePointer(file, 0, NULL, FILE_BEGIN); -+ bret = pTransmitFile(client, file, 0, 0, NULL, &buffers, 0); -+ ok(bret, "TransmitFile failed unexpectedly.\n"); -+ iret = recv(dest, buf, sizeof(header_msg)+1, 0); -+ ok(memcmp(buf, &header_msg[0], sizeof(header_msg)+1) == 0, -+ "TransmitFile header buffer did not match!\n"); -+ compare_file(file, dest); -+ iret = recv(dest, buf, sizeof(footer_msg)+1, 0); -+ ok(memcmp(buf, &footer_msg[0], sizeof(footer_msg)+1) == 0, -+ "TransmitFile footer buffer did not match!\n"); /* Test TransmitFile with a UDP datagram socket */ closesocket(client); -- -2.2.1 +1.9.1 diff --git a/patches/ws2_32-TransmitFile/0004-ws2_32-Add-asynchronous-support-for-TransmitFile.patch b/patches/ws2_32-TransmitFile/0004-ws2_32-Add-asynchronous-support-for-TransmitFile.patch deleted file mode 100644 index 4a18b9e0..00000000 --- a/patches/ws2_32-TransmitFile/0004-ws2_32-Add-asynchronous-support-for-TransmitFile.patch +++ /dev/null @@ -1,236 +0,0 @@ -From 0535832365c4fba553cfddd1546ce55d63b45510 Mon Sep 17 00:00:00 2001 -From: "Erich E. Hoover" -Date: Thu, 16 Jan 2014 18:24:53 -0700 -Subject: ws2_32: Add asynchronous support for TransmitFile. - ---- - dlls/ws2_32/socket.c | 86 +++++++++++++++++++++++++++++++++++++++++++--- - dlls/ws2_32/tests/sock.c | 47 ++++++++++++++++++++++--- - 2 files changed, 124 insertions(+), 9 deletions(-) - -diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c -index 322c5ed..42c7832 100644 ---- a/dlls/ws2_32/socket.c -+++ b/dlls/ws2_32/socket.c -@@ -365,4 +365,16 @@ typedef struct ws2_accept_async - } ws2_accept_async; - -+typedef struct ws2_transmitfile_async -+{ -+ HANDLE socket; -+ HANDLE file; -+ DWORD total_bytes; -+ DWORD bytes_per_send; -+ LPOVERLAPPED user_overlapped; -+ LPTRANSMIT_FILE_BUFFERS buffers; -+ DWORD flags; -+ ULONG_PTR cvalue; -+} ws2_transmitfile_async; -+ - /****************************************************************/ - -@@ -2511,6 +2523,16 @@ static BOOL WS2_transmitfile_base( SOCKET s, HANDLE h, DWORD total_bytes, DWORD - buffer = HeapAlloc( GetProcessHeap(), 0, bytes_per_send ); - if (!buffer) goto cleanup; - -+ /* handle the overlapped offset */ -+ if (overlapped) -+ { -+ LARGE_INTEGER offset; -+ -+ offset.u.LowPart = overlapped->u.s.Offset; -+ offset.u.HighPart = overlapped->u.s.OffsetHigh; -+ SetFilePointerEx( h, offset, NULL, FILE_BEGIN ); -+ } -+ - /* read and send the data from the file */ - do - { -@@ -2544,6 +2566,32 @@ cleanup: - } - - /*********************************************************************** -+ * WS2_async_transmitfile (INTERNAL) -+ * -+ * Asynchronous callback for overlapped TransmitFile operations. -+ */ -+static NTSTATUS WS2_async_transmitfile( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved, void **apc) -+{ -+ struct ws2_transmitfile_async *wsa = arg; -+ BOOL ret; -+ -+ ret = WS2_transmitfile_base( HANDLE2SOCKET(wsa->socket), wsa->file, wsa->total_bytes, wsa->bytes_per_send, -+ wsa->user_overlapped, wsa->buffers, wsa->flags ); -+ if (!ret) -+ iosb->u.Status = wsaErrStatus(); -+ else -+ iosb->u.Status = STATUS_SUCCESS; -+ iosb->Information = 0; -+ -+ if (wsa->user_overlapped->hEvent) -+ SetEvent(wsa->user_overlapped->hEvent); -+ if (wsa->cvalue) -+ WS_AddCompletion( HANDLE2SOCKET(wsa->socket), wsa->cvalue, iosb->u.Status, iosb->Information ); -+ -+ return iosb->u.Status; -+} -+ -+/*********************************************************************** - * TransmitFile - */ - static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWORD bytes_per_send, -@@ -2551,7 +2599,9 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR - { - union generic_unix_sockaddr uaddr; - unsigned int uaddrlen = sizeof(uaddr); -- int fd; -+ IO_STATUS_BLOCK *iosb = (IO_STATUS_BLOCK *)overlapped; -+ struct ws2_transmitfile_async *wsa; -+ int status, fd; - - TRACE("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, total_bytes, bytes_per_send, overlapped, buffers, - flags ); -@@ -2575,9 +2625,37 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR - if (!overlapped) - return WS2_transmitfile_base( s, h, total_bytes, bytes_per_send, overlapped, buffers, flags ); - -- FIXME("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, total_bytes, bytes_per_send, overlapped, buffers, -- flags ); -- WSASetLastError( WSAEOPNOTSUPP ); -+ iosb->u.Status = STATUS_PENDING; -+ iosb->Information = 0; -+ if (!(wsa = HeapAlloc( GetProcessHeap(), 0, sizeof(*wsa) ))) -+ { -+ SetLastError( WSAEFAULT ); -+ return FALSE; -+ } -+ wsa->socket = SOCKET2HANDLE(s); -+ wsa->file = h; -+ wsa->total_bytes = total_bytes; -+ wsa->bytes_per_send = bytes_per_send; -+ wsa->user_overlapped = overlapped; -+ wsa->buffers = buffers; -+ wsa->flags = flags; -+ wsa->cvalue = (((ULONG_PTR)overlapped->hEvent & 1) == 0) ? (ULONG_PTR)overlapped : 0; -+ -+ SERVER_START_REQ( register_async ) -+ { -+ req->type = ASYNC_TYPE_WRITE; -+ req->async.handle = wine_server_obj_handle( SOCKET2HANDLE(s) ); -+ req->async.callback = wine_server_client_ptr( WS2_async_transmitfile ); -+ req->async.iosb = wine_server_client_ptr( iosb ); -+ req->async.arg = wine_server_client_ptr( wsa ); -+ status = wine_server_call( req ); -+ } -+ SERVER_END_REQ; -+ -+ if(status != STATUS_PENDING) -+ HeapFree( GetProcessHeap(), 0, wsa ); -+ -+ SetLastError( NtStatusToWSAError(status) ); - return FALSE; - } - -diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c -index 2312f50..dbb762a 100644 ---- a/dlls/ws2_32/tests/sock.c -+++ b/dlls/ws2_32/tests/sock.c -@@ -6491,15 +6491,15 @@ end: - closesocket(connector2); - } - --#define compare_file(h,s) compare_file2(h,s,__FILE__,__LINE__) -+#define compare_file(h,s,o) compare_file2(h,s,o,__FILE__,__LINE__) - --static void compare_file2(HANDLE handle, SOCKET sock, const char *file, int line) -+static void compare_file2(HANDLE handle, SOCKET sock, int offset, const char *file, int line) - { - char buf1[256], buf2[256]; - BOOL success; - int i = 0; - -- SetFilePointer(handle, 0, NULL, FILE_BEGIN); -+ SetFilePointer(handle, offset, NULL, FILE_BEGIN); - while (1) - { - DWORD n1 = 0, n2 = 0; -@@ -6529,10 +6529,13 @@ static void test_TransmitFile(void) - TRANSMIT_FILE_BUFFERS buffers; - SOCKET client, server, dest; - DWORD num_bytes, err; -+ WSAOVERLAPPED ov; - char buf[256]; - int iret, len; - BOOL bret; - -+ memset( &ov, 0, sizeof(ov) ); -+ - /* Setup sockets for testing TransmitFile */ - client = socket(AF_INET, SOCK_STREAM, 0); - server = socket(AF_INET, SOCK_STREAM, 0); -@@ -6630,7 +6633,7 @@ static void test_TransmitFile(void) - /* Test TransmitFile with only file data */ - bret = pTransmitFile(client, file, 0, 0, NULL, NULL, 0); - ok(bret, "TransmitFile failed unexpectedly.\n"); -- compare_file(file, dest); -+ compare_file(file, dest, 0); - - /* Test TransmitFile with both file and buffer data */ - buffers.Head = &header_msg[0]; -@@ -6643,11 +6646,44 @@ static void test_TransmitFile(void) - iret = recv(dest, buf, sizeof(header_msg)+1, 0); - ok(memcmp(buf, &header_msg[0], sizeof(header_msg)+1) == 0, - "TransmitFile header buffer did not match!\n"); -- compare_file(file, dest); -+ compare_file(file, dest, 0); - iret = recv(dest, buf, sizeof(footer_msg)+1, 0); - ok(memcmp(buf, &footer_msg[0], sizeof(footer_msg)+1) == 0, - "TransmitFile footer buffer did not match!\n"); - -+ /* Test overlapped TransmitFile */ -+ ov.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); -+ if (ov.hEvent == INVALID_HANDLE_VALUE) -+ { -+ skip("Could not create event object, some tests will be skipped. errno = %d\n", GetLastError()); -+ goto cleanup; -+ } -+ SetFilePointer(file, 0, NULL, FILE_BEGIN); -+ bret = pTransmitFile(client, file, 0, 0, &ov, NULL, 0); -+ err = WSAGetLastError(); -+ ok(!bret, "TransmitFile succeeded unexpectedly.\n"); -+ ok(err == ERROR_IO_PENDING, "TransmitFile triggered unexpected errno (%d != %d)\n", err, ERROR_IO_PENDING); -+ iret = WaitForSingleObject(ov.hEvent, 100); -+ ok(iret == WAIT_OBJECT_0, "Overlapped TransmitFile failed.\n"); -+ compare_file(file, dest, 0); -+ -+ /* Test overlapped TransmitFile w/ start offset */ -+ ov.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); -+ if (ov.hEvent == INVALID_HANDLE_VALUE) -+ { -+ skip("Could not create event object, some tests will be skipped. errno = %d\n", GetLastError()); -+ goto cleanup; -+ } -+ SetFilePointer(file, 0, NULL, FILE_BEGIN); -+ ov.Offset = 10; -+ bret = pTransmitFile(client, file, 0, 0, &ov, NULL, 0); -+ err = WSAGetLastError(); -+ ok(!bret, "TransmitFile succeeded unexpectedly.\n"); -+ ok(err == ERROR_IO_PENDING, "TransmitFile triggered unexpected errno (%d != %d)\n", err, ERROR_IO_PENDING); -+ iret = WaitForSingleObject(ov.hEvent, 100); -+ ok(iret == WAIT_OBJECT_0, "Overlapped TransmitFile failed.\n"); -+ compare_file(file, dest, 10); -+ - /* Test TransmitFile with a UDP datagram socket */ - closesocket(client); - client = socket(AF_INET, SOCK_DGRAM, 0); -@@ -6658,6 +6694,7 @@ static void test_TransmitFile(void) - - cleanup: - CloseHandle(file); -+ CloseHandle(ov.hEvent); - closesocket(client); - closesocket(server); - } --- -1.7.9.5 - diff --git a/patches/ws2_32-TransmitFile/0004-ws2_32-Add-support-for-TransmitFile-headers-and-foot.patch b/patches/ws2_32-TransmitFile/0004-ws2_32-Add-support-for-TransmitFile-headers-and-foot.patch new file mode 100644 index 00000000..ffb6a867 --- /dev/null +++ b/patches/ws2_32-TransmitFile/0004-ws2_32-Add-support-for-TransmitFile-headers-and-foot.patch @@ -0,0 +1,150 @@ +From ccfa39a3110cf7fe425bb37fe4a9528215abacf4 Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +Date: Wed, 4 Mar 2015 15:10:43 -0700 +Subject: ws2_32: Add support for TransmitFile headers and footers. + +--- + dlls/ws2_32/socket.c | 31 +++++++++++++++++++++++++++++-- + dlls/ws2_32/tests/sock.c | 35 +++++++++++++++++++++++++++++++++++ + 2 files changed, 64 insertions(+), 2 deletions(-) + +diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c +index 6598f7c..115101c 100644 +--- a/dlls/ws2_32/socket.c ++++ b/dlls/ws2_32/socket.c +@@ -386,6 +386,7 @@ typedef struct ws2_transmitfile_async + DWORD file_read; + DWORD file_bytes; + DWORD bytes_per_send; ++ TRANSMIT_FILE_BUFFERS buffers; + DWORD flags; + struct ws2_async write; + } ws2_transmitfile_async; +@@ -2560,6 +2561,17 @@ static NTSTATUS WS2_transmitfile_getbuffer( int fd, struct ws2_transmitfile_asyn + if (wsa->write.first_iovec < wsa->write.n_iovecs) + return STATUS_PENDING; + ++ /* process the header (if applicable) */ ++ if (wsa->buffers.Head) ++ { ++ wsa->write.first_iovec = 0; ++ wsa->write.n_iovecs = 1; ++ wsa->write.iovec[0].iov_base = wsa->buffers.Head; ++ wsa->write.iovec[0].iov_len = wsa->buffers.HeadLength; ++ wsa->buffers.Head = NULL; ++ return STATUS_PENDING; ++ } ++ + /* process the main file */ + if (wsa->file) + { +@@ -2573,7 +2585,7 @@ static NTSTATUS WS2_transmitfile_getbuffer( int fd, struct ws2_transmitfile_asyn + status = NtReadFile( wsa->file, 0, NULL, NULL, &iosb, wsa->buffer, bytes_per_send, + NULL, NULL ); + if(status == STATUS_END_OF_FILE) +- return STATUS_SUCCESS; ++ wsa->file = NULL; /* continue on to the footer */ + else if(status != STATUS_SUCCESS) + return status; + else +@@ -2589,6 +2601,17 @@ static NTSTATUS WS2_transmitfile_getbuffer( int fd, struct ws2_transmitfile_asyn + } + } + ++ /* send the footer (if applicable) */ ++ if (wsa->buffers.Tail) ++ { ++ wsa->write.first_iovec = 0; ++ wsa->write.n_iovecs = 1; ++ wsa->write.iovec[0].iov_base = wsa->buffers.Tail; ++ wsa->write.iovec[0].iov_len = wsa->buffers.TailLength; ++ wsa->buffers.Tail = NULL; ++ return STATUS_PENDING; ++ } ++ + return STATUS_SUCCESS; + } + +@@ -2626,7 +2649,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD + NTSTATUS status; + int fd; + +- if (overlapped || buffers) ++ if (overlapped) + { + FIXME("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, file_bytes, bytes_per_send, + overlapped, buffers, flags); +@@ -2662,6 +2685,10 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD + WSASetLastError( WSAEFAULT ); + return FALSE; + } ++ if (buffers) ++ memcpy(&wsa->buffers, buffers, sizeof(wsa->buffers)); ++ else ++ memset(&wsa->buffers, 0x0, sizeof(wsa->buffers)); + wsa->buffer = (char *)(wsa + 1); + wsa->file = h; + wsa->file_read = 0; +diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c +index 1288694..a93dbe3 100644 +--- a/dlls/ws2_32/tests/sock.c ++++ b/dlls/ws2_32/tests/sock.c +@@ -6937,8 +6937,11 @@ static void test_TransmitFile(void) + GUID transmitFileGuid = WSAID_TRANSMITFILE; + LPFN_TRANSMITFILE pTransmitFile = NULL; + HANDLE file = INVALID_HANDLE_VALUE; ++ char header_msg[] = "hello world"; ++ char footer_msg[] = "goodbye!!!"; + char system_ini_path[MAX_PATH]; + struct sockaddr_in bindAddress; ++ TRANSMIT_FILE_BUFFERS buffers; + SOCKET client, server, dest; + DWORD num_bytes, err; + char buf[256]; +@@ -7023,11 +7026,43 @@ static void test_TransmitFile(void) + iret = recv(dest, buf, sizeof(buf), 0); + ok(iret == -1, "Returned an unexpected buffer from TransmitFile (%d != -1).\n", iret); + ++ /* Test TransmitFile with only buffer data */ ++ buffers.Head = &header_msg[0]; ++ buffers.HeadLength = sizeof(header_msg)+1; ++ buffers.Tail = &footer_msg[0]; ++ buffers.TailLength = sizeof(footer_msg)+1; ++ bret = pTransmitFile(client, NULL, 0, 0, NULL, &buffers, 0); ++ ok(bret, "TransmitFile failed unexpectedly.\n"); ++ iret = recv(dest, buf, sizeof(buf), 0); ++ ok(iret == sizeof(header_msg)+sizeof(footer_msg)+2, ++ "Returned an unexpected buffer from TransmitFile (%d != %d).\n", iret, ++ sizeof(header_msg)+sizeof(footer_msg)+2); ++ ok(memcmp(&buf[0], &header_msg[0], sizeof(header_msg)+1) == 0, ++ "TransmitFile header buffer did not match!\n"); ++ ok(memcmp(&buf[sizeof(header_msg)+1], &footer_msg[0], sizeof(footer_msg)+1) == 0, ++ "TransmitFile footer buffer did not match!\n"); ++ + /* Test TransmitFile with only file data */ + bret = pTransmitFile(client, file, 0, 0, NULL, NULL, 0); + ok(bret, "TransmitFile failed unexpectedly.\n"); + compare_file(file, dest); + ++ /* Test TransmitFile with both file and buffer data */ ++ buffers.Head = &header_msg[0]; ++ buffers.HeadLength = sizeof(header_msg)+1; ++ buffers.Tail = &footer_msg[0]; ++ buffers.TailLength = sizeof(footer_msg)+1; ++ SetFilePointer(file, 0, NULL, FILE_BEGIN); ++ bret = pTransmitFile(client, file, 0, 0, NULL, &buffers, 0); ++ ok(bret, "TransmitFile failed unexpectedly.\n"); ++ iret = recv(dest, buf, sizeof(header_msg)+1, 0); ++ ok(memcmp(buf, &header_msg[0], sizeof(header_msg)+1) == 0, ++ "TransmitFile header buffer did not match!\n"); ++ compare_file(file, dest); ++ iret = recv(dest, buf, sizeof(footer_msg)+1, 0); ++ ok(memcmp(buf, &footer_msg[0], sizeof(footer_msg)+1) == 0, ++ "TransmitFile footer buffer did not match!\n"); ++ + /* Test TransmitFile with a UDP datagram socket */ + closesocket(client); + client = socket(AF_INET, SOCK_DGRAM, 0); +-- +1.9.1 + diff --git a/patches/ws2_32-TransmitFile/0005-ws2_32-Add-asynchronous-support-for-TransmitFile.patch b/patches/ws2_32-TransmitFile/0005-ws2_32-Add-asynchronous-support-for-TransmitFile.patch new file mode 100644 index 00000000..5615bcbf --- /dev/null +++ b/patches/ws2_32-TransmitFile/0005-ws2_32-Add-asynchronous-support-for-TransmitFile.patch @@ -0,0 +1,278 @@ +From 33df3649a18892fb9da00fc0b545213dbe847f3b Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +Date: Tue, 3 Mar 2015 23:19:40 -0700 +Subject: ws2_32: Add asynchronous support for TransmitFile. + +--- + dlls/ws2_32/socket.c | 71 ++++++++++++++++++++++++++++++++----- + dlls/ws2_32/tests/sock.c | 91 ++++++++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 147 insertions(+), 15 deletions(-) + +diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c +index 115101c..de04d9b 100644 +--- a/dlls/ws2_32/socket.c ++++ b/dlls/ws2_32/socket.c +@@ -2627,36 +2627,60 @@ static NTSTATUS WS2_transmitfile_base( int fd, struct ws2_transmitfile_async *ws + status = WS2_transmitfile_getbuffer( fd, wsa ); + if (status == STATUS_PENDING) + { ++ IO_STATUS_BLOCK *iosb = (IO_STATUS_BLOCK *)wsa->write.user_overlapped; + DWORD n; + + n = WS2_send( fd, &wsa->write ); + if (n == -1) + return wsaErrStatus(); ++ if (iosb) iosb->Information += n; + } + return status; + } + + /*********************************************************************** ++ * WS2_async_transmitfile (INTERNAL) ++ * ++ * Asynchronous callback for overlapped TransmitFile operations. ++ */ ++static NTSTATUS WS2_async_transmitfile( void *user, IO_STATUS_BLOCK *iosb, ++ NTSTATUS status, void **apc, void **arg ) ++{ ++ struct ws2_transmitfile_async *wsa = user; ++ int fd; ++ ++ if (status != STATUS_ALERTED) ++ goto cleanup; ++ ++ if ((status = wine_server_handle_to_fd( wsa->write.hSocket, FILE_WRITE_DATA, &fd, NULL ) )) ++ goto cleanup; ++ status = WS2_transmitfile_base( fd, wsa ); ++ wine_server_release_fd( wsa->write.hSocket, fd ); ++ if (status == STATUS_PENDING) ++ return iosb->u.Status; ++ ++ if (wsa->write.user_overlapped->hEvent) ++ SetEvent(wsa->write.user_overlapped->hEvent); ++cleanup: ++ iosb->u.Status = status; ++ release_async_io( &wsa->io ); ++ return iosb->u.Status; ++} ++ ++/*********************************************************************** + * TransmitFile + */ + static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD bytes_per_send, + LPOVERLAPPED overlapped, LPTRANSMIT_FILE_BUFFERS buffers, + DWORD flags ) + { ++ IO_STATUS_BLOCK *iosb = (IO_STATUS_BLOCK *)overlapped; + union generic_unix_sockaddr uaddr; + unsigned int uaddrlen = sizeof(uaddr); + struct ws2_transmitfile_async *wsa; + NTSTATUS status; + int fd; + +- if (overlapped) +- { +- FIXME("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, file_bytes, bytes_per_send, +- overlapped, buffers, flags); +- WSASetLastError( WSAEOPNOTSUPP ); +- return FALSE; +- } +- + TRACE("(%lx, %p, %d, %d, %p, %p, %d)\n", s, h, file_bytes, bytes_per_send, overlapped, + buffers, flags ); + +@@ -2703,7 +2727,36 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD + wsa->write.control = NULL; + wsa->write.n_iovecs = 0; + wsa->write.first_iovec = 0; +- wsa->write.user_overlapped = NULL; ++ wsa->write.user_overlapped = overlapped; ++ ++ if (overlapped) ++ { ++ LARGE_INTEGER offset; ++ int status; ++ ++ /* set the file offset to the desired point */ ++ offset.u.LowPart = overlapped->u.s.Offset; ++ offset.u.HighPart = overlapped->u.s.OffsetHigh; ++ SetFilePointerEx( wsa->file, offset, NULL, FILE_BEGIN ); ++ ++ iosb->u.Status = STATUS_PENDING; ++ iosb->Information = 0; ++ SERVER_START_REQ( register_async ) ++ { ++ req->type = ASYNC_TYPE_WRITE; ++ req->async.handle = wine_server_obj_handle( SOCKET2HANDLE(s) ); ++ req->async.callback = wine_server_client_ptr( WS2_async_transmitfile ); ++ req->async.iosb = wine_server_client_ptr( iosb ); ++ req->async.arg = wine_server_client_ptr( wsa ); ++ status = wine_server_call( req ); ++ } ++ SERVER_END_REQ; ++ ++ if(status != STATUS_PENDING) HeapFree( GetProcessHeap(), 0, wsa ); ++ release_sock_fd( s, fd ); ++ WSASetLastError( NtStatusToWSAError(status) ); ++ return FALSE; ++ } + + do + { +diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c +index a93dbe3..4716b61 100644 +--- a/dlls/ws2_32/tests/sock.c ++++ b/dlls/ws2_32/tests/sock.c +@@ -6906,15 +6906,15 @@ end: + closesocket(connector2); + } + +-#define compare_file(h,s) compare_file2(h,s,__FILE__,__LINE__) ++#define compare_file(h,s,o) compare_file2(h,s,o,__FILE__,__LINE__) + +-static void compare_file2(HANDLE handle, SOCKET sock, const char *file, int line) ++static void compare_file2(HANDLE handle, SOCKET sock, int offset, const char *file, int line) + { + char buf1[256], buf2[256]; + BOOL success; + int i = 0; + +- SetFilePointer(handle, 0, NULL, FILE_BEGIN); ++ SetFilePointer(handle, offset, NULL, FILE_BEGIN); + while (1) + { + DWORD n1 = 0, n2 = 0; +@@ -6934,6 +6934,7 @@ static void compare_file2(HANDLE handle, SOCKET sock, const char *file, int line + + static void test_TransmitFile(void) + { ++ DWORD num_bytes, err, file_size, total_sent; + GUID transmitFileGuid = WSAID_TRANSMITFILE; + LPFN_TRANSMITFILE pTransmitFile = NULL; + HANDLE file = INVALID_HANDLE_VALUE; +@@ -6943,11 +6944,13 @@ static void test_TransmitFile(void) + struct sockaddr_in bindAddress; + TRANSMIT_FILE_BUFFERS buffers; + SOCKET client, server, dest; +- DWORD num_bytes, err; ++ WSAOVERLAPPED ov; + char buf[256]; + int iret, len; + BOOL bret; + ++ memset( &ov, 0, sizeof(ov) ); ++ + /* Setup sockets for testing TransmitFile */ + client = socket(AF_INET, SOCK_STREAM, 0); + server = socket(AF_INET, SOCK_STREAM, 0); +@@ -6971,6 +6974,7 @@ static void test_TransmitFile(void) + skip("Unable to open a file to transmit.\n"); + goto cleanup; + } ++ file_size = GetFileSize(file, NULL); + + /* Test TransmitFile with an invalid socket */ + bret = pTransmitFile(INVALID_SOCKET, file, 0, 0, NULL, NULL, 0); +@@ -7045,7 +7049,7 @@ static void test_TransmitFile(void) + /* Test TransmitFile with only file data */ + bret = pTransmitFile(client, file, 0, 0, NULL, NULL, 0); + ok(bret, "TransmitFile failed unexpectedly.\n"); +- compare_file(file, dest); ++ compare_file(file, dest, 0); + + /* Test TransmitFile with both file and buffer data */ + buffers.Head = &header_msg[0]; +@@ -7058,7 +7062,81 @@ static void test_TransmitFile(void) + iret = recv(dest, buf, sizeof(header_msg)+1, 0); + ok(memcmp(buf, &header_msg[0], sizeof(header_msg)+1) == 0, + "TransmitFile header buffer did not match!\n"); +- compare_file(file, dest); ++ compare_file(file, dest, 0); ++ iret = recv(dest, buf, sizeof(footer_msg)+1, 0); ++ ok(memcmp(buf, &footer_msg[0], sizeof(footer_msg)+1) == 0, ++ "TransmitFile footer buffer did not match!\n"); ++ ++ /* Test overlapped TransmitFile */ ++ ov.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); ++ if (ov.hEvent == INVALID_HANDLE_VALUE) ++ { ++ skip("Could not create event object, some tests will be skipped. errno = %d\n", ++ GetLastError()); ++ goto cleanup; ++ } ++ SetFilePointer(file, 0, NULL, FILE_BEGIN); ++ bret = pTransmitFile(client, file, 0, 0, &ov, NULL, 0); ++ err = WSAGetLastError(); ++ ok(!bret, "TransmitFile succeeded unexpectedly.\n"); ++ ok(err == ERROR_IO_PENDING, "TransmitFile triggered unexpected errno (%d != %d)\n", ++ err, ERROR_IO_PENDING); ++ iret = WaitForSingleObject(ov.hEvent, 2000); ++ ok(iret == WAIT_OBJECT_0, "Overlapped TransmitFile failed.\n"); ++ WSAGetOverlappedResult(client, &ov, &total_sent, FALSE, NULL); ++ ok(total_sent == file_size, ++ "Overlapped TransmitFile sent an unexpected number of bytes (%d != %d).\n", ++ total_sent, file_size); ++ compare_file(file, dest, 0); ++ ++ /* Test overlapped TransmitFile w/ start offset */ ++ ov.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); ++ if (ov.hEvent == INVALID_HANDLE_VALUE) ++ { ++ skip("Could not create event object, some tests will be skipped. errno = %d\n", GetLastError()); ++ goto cleanup; ++ } ++ SetFilePointer(file, 0, NULL, FILE_BEGIN); ++ ov.Offset = 10; ++ bret = pTransmitFile(client, file, 0, 0, &ov, NULL, 0); ++ err = WSAGetLastError(); ++ ok(!bret, "TransmitFile succeeded unexpectedly.\n"); ++ ok(err == ERROR_IO_PENDING, "TransmitFile triggered unexpected errno (%d != %d)\n", err, ERROR_IO_PENDING); ++ iret = WaitForSingleObject(ov.hEvent, 2000); ++ ok(iret == WAIT_OBJECT_0, "Overlapped TransmitFile failed.\n"); ++ WSAGetOverlappedResult(client, &ov, &total_sent, FALSE, NULL); ++ ok(total_sent == (file_size - ov.Offset), ++ "Overlapped TransmitFile sent an unexpected number of bytes (%d != %d).\n", ++ total_sent, file_size - ov.Offset); ++ compare_file(file, dest, ov.Offset); ++ ++ /* Test overlapped TransmitFile w/ file and buffer data */ ++ ov.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); ++ if (ov.hEvent == INVALID_HANDLE_VALUE) ++ { ++ skip("Could not create event object, some tests will be skipped. errno = %d\n", GetLastError()); ++ goto cleanup; ++ } ++ buffers.Head = &header_msg[0]; ++ buffers.HeadLength = sizeof(header_msg)+1; ++ buffers.Tail = &footer_msg[0]; ++ buffers.TailLength = sizeof(footer_msg)+1; ++ SetFilePointer(file, 0, NULL, FILE_BEGIN); ++ ov.Offset = 0; ++ bret = pTransmitFile(client, file, 0, 0, &ov, &buffers, 0); ++ err = WSAGetLastError(); ++ ok(!bret, "TransmitFile succeeded unexpectedly.\n"); ++ ok(err == ERROR_IO_PENDING, "TransmitFile triggered unexpected errno (%d != %d)\n", err, ERROR_IO_PENDING); ++ iret = WaitForSingleObject(ov.hEvent, 2000); ++ ok(iret == WAIT_OBJECT_0, "Overlapped TransmitFile failed.\n"); ++ WSAGetOverlappedResult(client, &ov, &total_sent, FALSE, NULL); ++ ok(total_sent == (file_size + buffers.HeadLength + buffers.TailLength), ++ "Overlapped TransmitFile sent an unexpected number of bytes (%d != %d).\n", ++ total_sent, file_size + buffers.HeadLength + buffers.TailLength); ++ iret = recv(dest, buf, sizeof(header_msg)+1, 0); ++ ok(memcmp(buf, &header_msg[0], sizeof(header_msg)+1) == 0, ++ "TransmitFile header buffer did not match!\n"); ++ compare_file(file, dest, 0); + iret = recv(dest, buf, sizeof(footer_msg)+1, 0); + ok(memcmp(buf, &footer_msg[0], sizeof(footer_msg)+1) == 0, + "TransmitFile footer buffer did not match!\n"); +@@ -7073,6 +7151,7 @@ static void test_TransmitFile(void) + + cleanup: + CloseHandle(file); ++ CloseHandle(ov.hEvent); + closesocket(client); + closesocket(server); + } +-- +1.9.1 + diff --git a/patches/ws2_32-TransmitFile/0006-ws2_32-Add-support-for-TF_DISCONNECT-to-TransmitFile.patch b/patches/ws2_32-TransmitFile/0006-ws2_32-Add-support-for-TF_DISCONNECT-to-TransmitFile.patch new file mode 100644 index 00000000..dd8969b3 --- /dev/null +++ b/patches/ws2_32-TransmitFile/0006-ws2_32-Add-support-for-TF_DISCONNECT-to-TransmitFile.patch @@ -0,0 +1,79 @@ +From b9da4e6bcf31ebb5669faa7a35fd85c907e4eed7 Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +Date: Wed, 4 Mar 2015 13:16:20 -0700 +Subject: ws2_32: Add support for TF_DISCONNECT to TransmitFile. + +--- + dlls/ws2_32/socket.c | 19 ++++++++++++++++--- + dlls/ws2_32/tests/sock.c | 11 +++++++++++ + 2 files changed, 27 insertions(+), 3 deletions(-) + +diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c +index de04d9b..b5b14c2 100644 +--- a/dlls/ws2_32/socket.c ++++ b/dlls/ws2_32/socket.c +@@ -2635,7 +2635,19 @@ static NTSTATUS WS2_transmitfile_base( int fd, struct ws2_transmitfile_async *ws + return wsaErrStatus(); + if (iosb) iosb->Information += n; + } +- return status; ++ if (status != STATUS_SUCCESS) ++ return status; ++ ++ if (wsa->flags & TF_DISCONNECT) ++ { ++ if (WS_closesocket( HANDLE2SOCKET(wsa->write.hSocket) ) != 0) ++ { ++ status = wsaErrStatus(); ++ return status; ++ } ++ } ++ ++ return STATUS_SUCCESS; + } + + /*********************************************************************** +@@ -2674,6 +2686,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD + LPOVERLAPPED overlapped, LPTRANSMIT_FILE_BUFFERS buffers, + DWORD flags ) + { ++ DWORD unsupported_flags = flags & ~(TF_DISCONNECT); + IO_STATUS_BLOCK *iosb = (IO_STATUS_BLOCK *)overlapped; + union generic_unix_sockaddr uaddr; + unsigned int uaddrlen = sizeof(uaddr); +@@ -2696,8 +2709,8 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD + WSASetLastError( WSAENOTCONN ); + return FALSE; + } +- if (flags) +- FIXME("Flags are not currently supported (0x%x).\n", flags); ++ if (unsupported_flags) ++ FIXME("Flags are not currently supported (0x%x).\n", unsupported_flags); + + /* set reasonable defaults when requested */ + if (!bytes_per_send) +diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c +index 4716b61..36920a7 100644 +--- a/dlls/ws2_32/tests/sock.c ++++ b/dlls/ws2_32/tests/sock.c +@@ -7141,6 +7141,17 @@ static void test_TransmitFile(void) + ok(memcmp(buf, &footer_msg[0], sizeof(footer_msg)+1) == 0, + "TransmitFile footer buffer did not match!\n"); + ++ /* Test TransmitFile w/ TF_DISCONNECT */ ++ SetFilePointer(file, 0, NULL, FILE_BEGIN); ++ bret = pTransmitFile(client, file, 0, 0, NULL, NULL, TF_DISCONNECT); ++ ok(bret, "TransmitFile failed unexpectedly.\n"); ++ compare_file(file, dest, 0); ++ closesocket(client); ++ ok(send(client, "test", 4, 0) == -1, "send() after TF_DISCONNECT succeeded unexpectedly.\n"); ++ err = WSAGetLastError(); ++ todo_wine ok(err == WSAENOTSOCK, "send() after TF_DISCONNECT triggered unexpected errno (%d != %d)\n", ++ err, WSAENOTSOCK); ++ + /* Test TransmitFile with a UDP datagram socket */ + closesocket(client); + client = socket(AF_INET, SOCK_DGRAM, 0); +-- +1.9.1 + diff --git a/patches/ws2_32-TransmitFile/0005-ws2_32-Add-support-for-TF_DISCONNECT-and-TF_REUSE_SO.patch b/patches/ws2_32-TransmitFile/0007-ws2_32-Add-support-for-TF_REUSE_SOCKET-to-TransmitFi.patch similarity index 66% rename from patches/ws2_32-TransmitFile/0005-ws2_32-Add-support-for-TF_DISCONNECT-and-TF_REUSE_SO.patch rename to patches/ws2_32-TransmitFile/0007-ws2_32-Add-support-for-TF_REUSE_SOCKET-to-TransmitFi.patch index e36ccfd7..cd005934 100644 --- a/patches/ws2_32-TransmitFile/0005-ws2_32-Add-support-for-TF_DISCONNECT-and-TF_REUSE_SO.patch +++ b/patches/ws2_32-TransmitFile/0007-ws2_32-Add-support-for-TF_REUSE_SOCKET-to-TransmitFi.patch @@ -1,79 +1,56 @@ -From 9986fca2fe9cc57f9c7a01f08fc6a826a398de47 Mon Sep 17 00:00:00 2001 +From 909b44b24c7654670db892d4d91f572dd09b3d56 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 16 Jan 2014 19:08:30 -0700 -Subject: ws2_32: Add support for TF_DISCONNECT and TF_REUSE_SOCKET to - TransmitFile. +Subject: ws2_32: Add support for TF_REUSE_SOCKET to TransmitFile. --- - dlls/ws2_32/socket.c | 17 +++++++++++-- - dlls/ws2_32/tests/sock.c | 11 +++++++- + dlls/ws2_32/socket.c | 13 +++++++++- + dlls/ws2_32/tests/sock.c | 1 - include/winsock.h | 1 + server/protocol.def | 6 +++++ server/sock.c | 65 +++++++++++++++++++++++++++++++++++++++++------- - 5 files changed, 88 insertions(+), 12 deletions(-) + 5 files changed, 75 insertions(+), 11 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c -index dbcadb3..e74aa7c 100644 +index b5b14c2..6188087 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c -@@ -2560,6 +2560,18 @@ static BOOL WS2_transmitfile_base( SOCKET s, HANDLE h, DWORD total_bytes, DWORD - if (buffers && WS_send( s, buffers->Tail, buffers->TailLength, 0 ) == SOCKET_ERROR) - goto cleanup; +@@ -2638,6 +2638,17 @@ static NTSTATUS WS2_transmitfile_base( int fd, struct ws2_transmitfile_async *ws + if (status != STATUS_SUCCESS) + return status; -+ if (flags & TF_REUSE_SOCKET) ++ if (wsa->flags & TF_REUSE_SOCKET) + { + SERVER_START_REQ( reuse_socket ) + { -+ req->handle = wine_server_obj_handle( SOCKET2HANDLE(s) ); -+ wine_server_call( req ); ++ req->handle = wine_server_obj_handle( wsa->write.hSocket ); ++ status = wine_server_call( req ); + } + SERVER_END_REQ; ++ if (status != STATUS_SUCCESS) ++ return status; + } -+ if (flags & TF_DISCONNECT) -+ WS_closesocket( s ); -+ - ret = TRUE; - - cleanup: -@@ -2601,6 +2613,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR + if (wsa->flags & TF_DISCONNECT) + { + if (WS_closesocket( HANDLE2SOCKET(wsa->write.hSocket) ) != 0) +@@ -2686,7 +2697,7 @@ 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); +- DWORD unsupported_flags = flags & ~(TF_DISCONNECT); + DWORD unsupported_flags = flags & ~(TF_DISCONNECT|TF_REUSE_SOCKET); IO_STATUS_BLOCK *iosb = (IO_STATUS_BLOCK *)overlapped; - struct ws2_transmitfile_async *wsa; - int status, fd; -@@ -2621,8 +2634,8 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD total_bytes, DWOR - return FALSE; - } - release_sock_fd( s, fd ); -- if (flags) -- FIXME("Flags are not currently supported (0x%x).\n", flags); -+ if (unsupported_flags) -+ FIXME("Flags are not currently supported (0x%x).\n", unsupported_flags); - - if (!overlapped) - return WS2_transmitfile_base( s, h, total_bytes, bytes_per_send, overlapped, buffers, flags ); + union generic_unix_sockaddr uaddr; + unsigned int uaddrlen = sizeof(uaddr); diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c -index 9708cf1..cf9ba23 100644 +index 36920a7..3fc8599 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c -@@ -7008,8 +7008,17 @@ static void test_TransmitFile(void) - ok(iret == WAIT_OBJECT_0, "Overlapped TransmitFile failed.\n"); - compare_file(file, dest, 10); +@@ -7153,7 +7153,6 @@ static void test_TransmitFile(void) + err, WSAENOTSOCK); -- /* Test TransmitFile with a UDP datagram socket */ -+ /* Test TransmitFile w/ TF_DISCONNECT */ -+ SetFilePointer(file, 0, NULL, FILE_BEGIN); -+ bret = pTransmitFile(client, file, 0, 0, NULL, NULL, TF_DISCONNECT); -+ ok(bret, "TransmitFile failed unexpectedly.\n"); -+ compare_file(file, dest, 0); - closesocket(client); -+ err = WSAGetLastError(); -+ ok(err == ERROR_INVALID_HANDLE, "TransmitFile triggered unexpected errno (%d != %d)\n", err, -+ ERROR_INVALID_HANDLE); -+ -+ /* Test TransmitFile with a UDP datagram socket */ + /* 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(); @@ -90,10 +67,10 @@ index 50237e8..e53aa1e 100644 #define FD_WINE_NONBLOCKING 0x20000000 #define FD_WINE_CONNECTED 0x40000000 diff --git a/server/protocol.def b/server/protocol.def -index fc6bec5..64e3f18 100644 +index 7ec380b..e76bcb1 100644 --- a/server/protocol.def +++ b/server/protocol.def -@@ -1208,6 +1208,12 @@ enum server_fd_type +@@ -1209,6 +1209,12 @@ enum server_fd_type @END @@ -107,10 +84,10 @@ index fc6bec5..64e3f18 100644 @REQ(set_socket_event) obj_handle_t handle; /* handle to the socket */ diff --git a/server/sock.c b/server/sock.c -index 7c0212e..4d51950 100644 +index f3bab85..46bd2f7 100644 --- a/server/sock.c +++ b/server/sock.c -@@ -80,6 +80,7 @@ +@@ -86,6 +86,7 @@ #define FD_CLOSE 0x00000020 /* internal per-socket flags */ @@ -118,7 +95,7 @@ index 7c0212e..4d51950 100644 #define FD_WINE_LISTENING 0x10000000 #define FD_WINE_NONBLOCKING 0x20000000 #define FD_WINE_CONNECTED 0x40000000 -@@ -124,6 +125,7 @@ static enum server_fd_type sock_get_fd_type( struct fd *fd ); +@@ -135,6 +136,7 @@ static obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_da static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); static void sock_reselect_async( struct fd *fd, struct async_queue *queue ); static void sock_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb ); @@ -126,7 +103,7 @@ index 7c0212e..4d51950 100644 static int sock_get_ntstatus( int err ); static int sock_get_error( int err ); -@@ -145,7 +147,7 @@ static const struct object_ops sock_ops = +@@ -156,7 +158,7 @@ static const struct object_ops sock_ops = default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ no_open_file, /* open_file */ @@ -135,7 +112,7 @@ index 7c0212e..4d51950 100644 sock_destroy /* destroy */ }; -@@ -585,6 +587,47 @@ static struct fd *sock_get_fd( struct object *obj ) +@@ -627,6 +629,47 @@ static struct fd *sock_get_fd( struct object *obj ) return (struct fd *)grab_object( sock->fd ); } @@ -183,7 +160,7 @@ index 7c0212e..4d51950 100644 static void sock_destroy( struct object *obj ) { struct sock *sock = (struct sock *)obj; -@@ -633,15 +676,8 @@ static struct object *create_socket( int family, int type, int protocol, unsigne +@@ -678,15 +721,8 @@ static struct object *create_socket( int family, int type, int protocol, unsigne struct sock *sock; int sockfd; @@ -200,7 +177,7 @@ index 7c0212e..4d51950 100644 if (!(sock = alloc_object( &sock_ops ))) { close( sockfd ); -@@ -969,6 +1005,17 @@ DECL_HANDLER(accept_into_socket) +@@ -1282,6 +1318,17 @@ DECL_HANDLER(accept_into_socket) release_object( sock ); } @@ -219,5 +196,5 @@ index 7c0212e..4d51950 100644 DECL_HANDLER(set_socket_event) { -- -2.1.3 +1.9.1 diff --git a/patches/ws2_32-TransmitFile/definition b/patches/ws2_32-TransmitFile/definition index dd405a2c..db18bda3 100644 --- a/patches/ws2_32-TransmitFile/definition +++ b/patches/ws2_32-TransmitFile/definition @@ -1,2 +1 @@ Fixes: [5048] Support for TransmitFile -Disabled: true