Erich E. Hoover : ws2_32: Add support for TransmitFile headers and footers.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Oct 19 11:34:21 CDT 2015


Module: wine
Branch: master
Commit: f1ebc93603058ee07b5b496d635bbd46e809f14d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f1ebc93603058ee07b5b496d635bbd46e809f14d

Author: Erich E. Hoover <erich.e.hoover at wine-staging.com>
Date:   Wed Oct  7 12:15:28 2015 -0600

ws2_32: Add support for TransmitFile headers and footers.

Signed-off-by: Erich E. Hoover <erich.e.hoover at wine-staging.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ws2_32/socket.c     | 31 +++++++++++++++++++++++++++++--
 dlls/ws2_32/tests/sock.c | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index f107d32..bc29f6d 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -522,6 +522,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;
 };
@@ -2789,6 +2790,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)
     {
@@ -2801,7 +2813,7 @@ static NTSTATUS WS2_transmitfile_getbuffer( int fd, struct ws2_transmitfile_asyn
             bytes_per_send = min(bytes_per_send, wsa->file_bytes - wsa->file_read);
         status = WS2_ReadFile( wsa->file, &iosb, wsa->buffer, bytes_per_send );
         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
@@ -2822,6 +2834,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;
 }
 
@@ -2860,7 +2883,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);
@@ -2904,6 +2927,10 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD
         WSASetLastError( WSAEFAULT );
         return FALSE;
     }
+    if (buffers)
+        wsa->buffers = *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 478a5fe..3d20c89 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -7460,8 +7460,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];
@@ -7546,11 +7549,42 @@ 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\n", iret );
+    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);




More information about the wine-cvs mailing list