You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-09-12 18:50:20 -07:00
Rebase against 26094c5634b1f12d3f156a90a3e228513675cd63.
This commit is contained in:
@@ -1,18 +1,81 @@
|
||||
From 1677afa592e1bc7e81301592027dc641172a5bc4 Mon Sep 17 00:00:00 2001
|
||||
From 38e2c0d234e1d3615ac26eeb4808a0446a6c72de Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Tue, 3 Mar 2015 23:19:40 -0700
|
||||
Subject: ws2_32: Add asynchronous support for TransmitFile. (rev 2)
|
||||
Date: Wed, 7 Oct 2015 12:19:42 -0600
|
||||
Subject: ws2_32: Add asynchronous support for TransmitFile.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@wine-staging.com>
|
||||
---
|
||||
dlls/ws2_32/socket.c | 75 +++++++++++++++++++++++++++++++++------
|
||||
dlls/ws2_32/socket.c | 89 ++++++++++++++++++++++++++++++++++++++--------
|
||||
dlls/ws2_32/tests/sock.c | 91 ++++++++++++++++++++++++++++++++++++++++++++----
|
||||
2 files changed, 150 insertions(+), 16 deletions(-)
|
||||
2 files changed, 160 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
|
||||
index 7d4f112..ed3f806 100644
|
||||
index bc29f6d..4531b81 100644
|
||||
--- a/dlls/ws2_32/socket.c
|
||||
+++ b/dlls/ws2_32/socket.c
|
||||
@@ -2669,10 +2669,15 @@ static NTSTATUS WS2_transmitfile_base( int fd, struct ws2_transmitfile_async *ws
|
||||
@@ -177,6 +177,8 @@
|
||||
#define TCP_KEEPIDLE TCP_KEEPALIVE
|
||||
#endif
|
||||
|
||||
+#define FILE_USE_FILE_POINTER_POSITION ((LONGLONG)-2)
|
||||
+
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(winsock);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(winediag);
|
||||
|
||||
@@ -524,6 +526,7 @@ struct ws2_transmitfile_async
|
||||
DWORD bytes_per_send;
|
||||
TRANSMIT_FILE_BUFFERS buffers;
|
||||
DWORD flags;
|
||||
+ LARGE_INTEGER offset;
|
||||
struct ws2_async write;
|
||||
};
|
||||
|
||||
@@ -2742,9 +2745,10 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW
|
||||
*
|
||||
* Perform an APC-safe ReadFile operation
|
||||
*/
|
||||
-static NTSTATUS WS2_ReadFile(HANDLE hFile, PIO_STATUS_BLOCK io_status, char* buffer, ULONG length)
|
||||
+static NTSTATUS WS2_ReadFile(HANDLE hFile, PIO_STATUS_BLOCK io_status, char* buffer, ULONG length,
|
||||
+ PLARGE_INTEGER offset)
|
||||
{
|
||||
- int result, unix_handle;
|
||||
+ int result = -1, unix_handle;
|
||||
unsigned int options;
|
||||
NTSTATUS status;
|
||||
|
||||
@@ -2753,8 +2757,12 @@ static NTSTATUS WS2_ReadFile(HANDLE hFile, PIO_STATUS_BLOCK io_status, char* buf
|
||||
status = wine_server_handle_to_fd( hFile, FILE_READ_DATA, &unix_handle, &options );
|
||||
if (status) return status;
|
||||
|
||||
- while ((result = read( unix_handle, buffer, length )) == -1)
|
||||
+ while (result == -1)
|
||||
{
|
||||
+ if (offset && offset->QuadPart != FILE_USE_FILE_POINTER_POSITION)
|
||||
+ result = pread( unix_handle, buffer, length, offset->QuadPart );
|
||||
+ else
|
||||
+ result = read( unix_handle, buffer, length );
|
||||
if (errno != EINTR)
|
||||
break;
|
||||
}
|
||||
@@ -2772,6 +2780,8 @@ static NTSTATUS WS2_ReadFile(HANDLE hFile, PIO_STATUS_BLOCK io_status, char* buf
|
||||
TRACE("= 0x%08x (%d)\n", status, result);
|
||||
if (status == STATUS_SUCCESS || status == STATUS_END_OF_FILE)
|
||||
{
|
||||
+ if (offset && offset->QuadPart != FILE_USE_FILE_POINTER_POSITION)
|
||||
+ offset->QuadPart += result;
|
||||
io_status->u.Status = status;
|
||||
io_status->Information = result;
|
||||
}
|
||||
@@ -2811,7 +2821,7 @@ static NTSTATUS WS2_transmitfile_getbuffer( int fd, struct ws2_transmitfile_asyn
|
||||
/* 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(bytes_per_send, wsa->file_bytes - wsa->file_read);
|
||||
- status = WS2_ReadFile( wsa->file, &iosb, wsa->buffer, bytes_per_send );
|
||||
+ status = WS2_ReadFile( wsa->file, &iosb, wsa->buffer, bytes_per_send, &wsa->offset );
|
||||
if (status == STATUS_END_OF_FILE)
|
||||
wsa->file = NULL; /* continue on to the footer */
|
||||
else if (status != STATUS_SUCCESS)
|
||||
@@ -2860,10 +2870,15 @@ static NTSTATUS WS2_transmitfile_base( int fd, struct ws2_transmitfile_async *ws
|
||||
status = WS2_transmitfile_getbuffer( fd, wsa );
|
||||
if (status == STATUS_PENDING)
|
||||
{
|
||||
@@ -29,7 +92,7 @@ index 7d4f112..ed3f806 100644
|
||||
return wsaErrStatus();
|
||||
}
|
||||
|
||||
@@ -2680,26 +2685,46 @@ static NTSTATUS WS2_transmitfile_base( int fd, struct ws2_transmitfile_async *ws
|
||||
@@ -2871,26 +2886,46 @@ static NTSTATUS WS2_transmitfile_base( int fd, struct ws2_transmitfile_async *ws
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -84,23 +147,26 @@ index 7d4f112..ed3f806 100644
|
||||
TRACE("(%lx, %p, %d, %d, %p, %p, %d)\n", s, h, file_bytes, bytes_per_send, overlapped,
|
||||
buffers, flags );
|
||||
|
||||
@@ -2746,7 +2771,37 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD
|
||||
@@ -2937,6 +2972,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD
|
||||
wsa->file_bytes = file_bytes;
|
||||
wsa->bytes_per_send = bytes_per_send;
|
||||
wsa->flags = flags;
|
||||
+ wsa->offset.QuadPart = FILE_USE_FILE_POINTER_POSITION;
|
||||
wsa->write.hSocket = SOCKET2HANDLE(s);
|
||||
wsa->write.addr = NULL;
|
||||
wsa->write.addrlen.val = 0;
|
||||
@@ -2945,7 +2981,32 @@ 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 );
|
||||
+
|
||||
+ wsa->offset.u.LowPart = overlapped->u.s.Offset;
|
||||
+ wsa->offset.u.HighPart = overlapped->u.s.OffsetHigh;
|
||||
+ iosb->u.Status = STATUS_PENDING;
|
||||
+ iosb->Information = 0;
|
||||
+ SERVER_START_REQ( register_async )
|
||||
@@ -124,10 +190,10 @@ index 7d4f112..ed3f806 100644
|
||||
do
|
||||
{
|
||||
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
|
||||
index f4a0d55..a22ca94 100644
|
||||
index 3d20c89..29e20c3 100644
|
||||
--- a/dlls/ws2_32/tests/sock.c
|
||||
+++ b/dlls/ws2_32/tests/sock.c
|
||||
@@ -7115,15 +7115,15 @@ end:
|
||||
@@ -7429,15 +7429,15 @@ end:
|
||||
closesocket(connector2);
|
||||
}
|
||||
|
||||
@@ -146,7 +212,7 @@ index f4a0d55..a22ca94 100644
|
||||
while (1)
|
||||
{
|
||||
DWORD n1 = 0, n2 = 0;
|
||||
@@ -7143,6 +7143,7 @@ static void compare_file2(HANDLE handle, SOCKET sock, const char *file, int line
|
||||
@@ -7457,6 +7457,7 @@ static void compare_file2(HANDLE handle, SOCKET sock, const char *file, int line
|
||||
|
||||
static void test_TransmitFile(void)
|
||||
{
|
||||
@@ -154,7 +220,7 @@ index f4a0d55..a22ca94 100644
|
||||
GUID transmitFileGuid = WSAID_TRANSMITFILE;
|
||||
LPFN_TRANSMITFILE pTransmitFile = NULL;
|
||||
HANDLE file = INVALID_HANDLE_VALUE;
|
||||
@@ -7152,11 +7153,13 @@ static void test_TransmitFile(void)
|
||||
@@ -7466,11 +7467,13 @@ static void test_TransmitFile(void)
|
||||
struct sockaddr_in bindAddress;
|
||||
TRANSMIT_FILE_BUFFERS buffers;
|
||||
SOCKET client, server, dest;
|
||||
@@ -169,7 +235,7 @@ index f4a0d55..a22ca94 100644
|
||||
/* Setup sockets for testing TransmitFile */
|
||||
client = socket(AF_INET, SOCK_STREAM, 0);
|
||||
server = socket(AF_INET, SOCK_STREAM, 0);
|
||||
@@ -7180,6 +7183,7 @@ static void test_TransmitFile(void)
|
||||
@@ -7494,6 +7497,7 @@ static void test_TransmitFile(void)
|
||||
skip("Unable to open a file to transmit.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -177,7 +243,7 @@ index f4a0d55..a22ca94 100644
|
||||
|
||||
/* Test TransmitFile with an invalid socket */
|
||||
bret = pTransmitFile(INVALID_SOCKET, file, 0, 0, NULL, NULL, 0);
|
||||
@@ -7254,7 +7258,7 @@ static void test_TransmitFile(void)
|
||||
@@ -7567,7 +7571,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");
|
||||
@@ -186,7 +252,7 @@ index f4a0d55..a22ca94 100644
|
||||
|
||||
/* Test TransmitFile with both file and buffer data */
|
||||
buffers.Head = &header_msg[0];
|
||||
@@ -7267,7 +7271,81 @@ static void test_TransmitFile(void)
|
||||
@@ -7580,7 +7584,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");
|
||||
@@ -269,7 +335,7 @@ index f4a0d55..a22ca94 100644
|
||||
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");
|
||||
@@ -7282,6 +7360,7 @@ static void test_TransmitFile(void)
|
||||
@@ -7595,6 +7673,7 @@ static void test_TransmitFile(void)
|
||||
|
||||
cleanup:
|
||||
CloseHandle(file);
|
||||
@@ -278,5 +344,5 @@ index f4a0d55..a22ca94 100644
|
||||
closesocket(server);
|
||||
}
|
||||
--
|
||||
2.3.3
|
||||
2.6.1
|
||||
|
@@ -1,256 +0,0 @@
|
||||
From 146d61e6b045ffe102d05910fef73003f47e3a67 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 16 Jan 2014 18:24:27 -0700
|
||||
Subject: ws2_32: Implement a basic synchronous TransmitFile. (rev 2)
|
||||
|
||||
---
|
||||
dlls/ws2_32/socket.c | 144 +++++++++++++++++++++++++++++++++++++++++++++--
|
||||
dlls/ws2_32/tests/sock.c | 36 +++++++++++-
|
||||
2 files changed, 173 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
|
||||
index 049b9dc..5267e59 100644
|
||||
--- a/dlls/ws2_32/socket.c
|
||||
+++ b/dlls/ws2_32/socket.c
|
||||
@@ -378,6 +378,18 @@ struct ws2_accept_async
|
||||
struct ws2_async *read;
|
||||
};
|
||||
|
||||
+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;
|
||||
+};
|
||||
+
|
||||
static struct ws2_async_io *async_io_freelist;
|
||||
|
||||
static void release_async_io( struct ws2_async_io *io )
|
||||
@@ -2575,6 +2587,76 @@ 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(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
|
||||
+ {
|
||||
+ if (iosb.Information)
|
||||
+ {
|
||||
+ 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 NTSTATUS WS2_transmitfile_base( int fd, struct ws2_transmitfile_async *wsa )
|
||||
+{
|
||||
+ NTSTATUS status;
|
||||
+
|
||||
+ status = WS2_transmitfile_getbuffer( fd, wsa );
|
||||
+ if (status == STATUS_PENDING)
|
||||
+ {
|
||||
+ int n;
|
||||
+
|
||||
+ n = WS2_send( fd, &wsa->write, convert_flags(wsa->write.flags) );
|
||||
+ if (n == -1 && errno != EAGAIN)
|
||||
+ return wsaErrStatus();
|
||||
+ }
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+/***********************************************************************
|
||||
* TransmitFile
|
||||
*/
|
||||
static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD bytes_per_send,
|
||||
@@ -2583,12 +2665,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, 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 );
|
||||
+ 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 );
|
||||
@@ -2600,12 +2692,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);
|
||||
|
||||
- WSASetLastError( WSAEOPNOTSUPP );
|
||||
- return FALSE;
|
||||
+ /* set reasonable defaults when requested */
|
||||
+ if (!bytes_per_send)
|
||||
+ bytes_per_send = 1024;
|
||||
+
|
||||
+ 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 4180fb1..fb0b325 100644
|
||||
--- a/dlls/ws2_32/tests/sock.c
|
||||
+++ b/dlls/ws2_32/tests/sock.c
|
||||
@@ -7115,6 +7115,32 @@ end:
|
||||
closesocket(connector2);
|
||||
}
|
||||
|
||||
+#define compare_file(h,s) compare_file2(h,s,__FILE__,__LINE__)
|
||||
+
|
||||
+static void compare_file2(HANDLE handle, SOCKET sock, const char *file, int line)
|
||||
+{
|
||||
+ char buf1[256], buf2[256];
|
||||
+ BOOL success;
|
||||
+ int i = 0;
|
||||
+
|
||||
+ SetFilePointer(handle, 0, NULL, FILE_BEGIN);
|
||||
+ while (1)
|
||||
+ {
|
||||
+ DWORD n1 = 0, n2 = 0;
|
||||
+
|
||||
+ success = ReadFile(handle, buf1, sizeof(buf1), &n1, NULL);
|
||||
+ ok_(file,line)(success, "Failed to read from file.\n");
|
||||
+ if (success && n1 == 0)
|
||||
+ break;
|
||||
+ else if(!success)
|
||||
+ return;
|
||||
+ n2 = recv(sock, buf2, n1, 0);
|
||||
+ ok_(file,line)(n1 == n2, "Block %d size mismatch (%d != %d)\n", i, n1, n2);
|
||||
+ ok_(file,line)(memcmp(buf1, buf2, n2) == 0, "Block %d failed\n", i);
|
||||
+ i++;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void test_TransmitFile(void)
|
||||
{
|
||||
GUID transmitFileGuid = WSAID_TRANSMITFILE;
|
||||
@@ -7124,6 +7150,7 @@ static void test_TransmitFile(void)
|
||||
struct sockaddr_in bindAddress;
|
||||
SOCKET client, server, dest;
|
||||
DWORD num_bytes, err;
|
||||
+ char buf[256];
|
||||
int iret, len;
|
||||
BOOL bret;
|
||||
|
||||
@@ -7201,7 +7228,14 @@ static void test_TransmitFile(void)
|
||||
|
||||
/* Test TransmitFile with no possible buffer */
|
||||
bret = pTransmitFile(client, NULL, 0, 0, NULL, NULL, 0);
|
||||
- todo_wine ok(bret, "TransmitFile failed unexpectedly.\n");
|
||||
+ ok(bret, "TransmitFile failed unexpectedly.\n");
|
||||
+ iret = recv(dest, buf, sizeof(buf), 0);
|
||||
+ ok(iret == -1, "Returned an unexpected buffer from TransmitFile (%d != -1).\n", iret);
|
||||
+
|
||||
+ /* 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 a UDP datagram socket */
|
||||
closesocket(client);
|
||||
--
|
||||
2.3.3
|
||||
|
@@ -1,4 +1,4 @@
|
||||
From fc0e93449a708ce3f89ae87f107f07fbed452936 Mon Sep 17 00:00:00 2001
|
||||
From 0a0a7b4793378c54346cd0e9e7feae6eb2a89dc3 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Wed, 4 Mar 2015 13:16:20 -0700
|
||||
Subject: ws2_32: Add support for TF_DISCONNECT to TransmitFile.
|
||||
@@ -9,10 +9,10 @@ Subject: ws2_32: Add support for TF_DISCONNECT to TransmitFile.
|
||||
2 files changed, 24 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
|
||||
index 244f723..10d30bd 100644
|
||||
index 4531b81..0f94a57 100644
|
||||
--- a/dlls/ws2_32/socket.c
|
||||
+++ b/dlls/ws2_32/socket.c
|
||||
@@ -2644,7 +2644,16 @@ static NTSTATUS WS2_transmitfile_base( int fd, struct ws2_transmitfile_async *ws
|
||||
@@ -2882,7 +2882,16 @@ static NTSTATUS WS2_transmitfile_base( int fd, struct ws2_transmitfile_async *ws
|
||||
return wsaErrStatus();
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ index 244f723..10d30bd 100644
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -2683,6 +2692,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD
|
||||
@@ -2919,6 +2928,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD
|
||||
LPOVERLAPPED overlapped, LPTRANSMIT_FILE_BUFFERS buffers,
|
||||
DWORD flags )
|
||||
{
|
||||
@@ -38,7 +38,7 @@ index 244f723..10d30bd 100644
|
||||
IO_STATUS_BLOCK *iosb = (IO_STATUS_BLOCK *)overlapped;
|
||||
union generic_unix_sockaddr uaddr;
|
||||
unsigned int uaddrlen = sizeof(uaddr);
|
||||
@@ -2705,8 +2715,8 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD
|
||||
@@ -2941,8 +2951,8 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD
|
||||
WSASetLastError( WSAENOTCONN );
|
||||
return FALSE;
|
||||
}
|
||||
@@ -47,13 +47,13 @@ index 244f723..10d30bd 100644
|
||||
+ if (unsupported_flags)
|
||||
+ FIXME("Flags are not currently supported (0x%x).\n", unsupported_flags);
|
||||
|
||||
/* set reasonable defaults when requested */
|
||||
if (!bytes_per_send)
|
||||
if (h && GetFileType( h ) != FILE_TYPE_DISK)
|
||||
{
|
||||
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
|
||||
index 4716b61..36920a7 100644
|
||||
index 29e20c3..d5c206c 100644
|
||||
--- a/dlls/ws2_32/tests/sock.c
|
||||
+++ b/dlls/ws2_32/tests/sock.c
|
||||
@@ -7141,6 +7141,17 @@ static void test_TransmitFile(void)
|
||||
@@ -7663,6 +7663,17 @@ static void test_TransmitFile(void)
|
||||
ok(memcmp(buf, &footer_msg[0], sizeof(footer_msg)+1) == 0,
|
||||
"TransmitFile footer buffer did not match!\n");
|
||||
|
||||
@@ -72,5 +72,5 @@ index 4716b61..36920a7 100644
|
||||
closesocket(client);
|
||||
client = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
--
|
||||
2.3.0
|
||||
2.6.1
|
||||
|
@@ -1,150 +0,0 @@
|
||||
From 408befce279d57fe2f5e3e5ba12bae4a09456fda Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
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 36ce0dd..e45c838 100644
|
||||
--- a/dlls/ws2_32/socket.c
|
||||
+++ b/dlls/ws2_32/socket.c
|
||||
@@ -386,6 +386,7 @@ struct ws2_transmitfile_async
|
||||
DWORD file_read;
|
||||
DWORD file_bytes;
|
||||
DWORD bytes_per_send;
|
||||
+ TRANSMIT_FILE_BUFFERS buffers;
|
||||
DWORD flags;
|
||||
struct ws2_async write;
|
||||
};
|
||||
@@ -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
|
||||
@@ -2594,6 +2606,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;
|
||||
}
|
||||
|
||||
@@ -2632,7 +2655,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);
|
||||
@@ -2668,6 +2691,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);
|
||||
--
|
||||
2.3.0
|
||||
|
Reference in New Issue
Block a user