mswsock.dll: TranmitFile - new way [2/2] (tests)

Łukasz Chróst lukost at gmail.com
Tue Jun 27 18:20:25 CDT 2006


Tests should pass (but overlapped operation performs just like immediate
completion has succeed. The problem is this can take very long...)

--
Lukasz Chrost

-------------- next part --------------
Index: configure.ac
===================================================================
RCS file: /home/wine/wine/configure.ac,v
retrieving revision 1.508
diff -u -r1.508 configure.ac
--- configure.ac	22 Jun 2006 11:19:38 -0000	1.508
+++ configure.ac	25 Jun 2006 09:06:06 -0000
@@ -1668,6 +1668,7 @@
 dlls/msvfw32/Makefile
 dlls/msvidc32/Makefile
 dlls/mswsock/Makefile
+dlls/mswsock/tests/Makefile
 dlls/msxml3/Makefile
 dlls/msxml3/tests/Makefile
 dlls/netapi32/Makefile

--- /dev/null	2006-06-27 15:09:45.552523000 +0200
+++ dlls/mswsock/tests/Makefile.in	2006-06-28 00:55:32.781250000 +0200
@@ -0,0 +1,13 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+TESTDLL   = mswsock.dll
+IMPORTS   = ws2_32 mswsock kernel32
+
+CTESTS = \
+	wsock.c
+
+ at MAKE_TEST_RULES@
+
+### Dependencies:
--- /dev/null	2006-06-27 15:09:45.552523000 +0200
+++ dlls/mswsock/tests/wsock.c	2006-06-28 00:54:18.000000000 +0200
@@ -0,0 +1,889 @@
+/*
+* MSWSOCK specific functions tests
+*
+* Copyright (C) 2006 Lukasz Chrost
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+*/ 
+#include <stdarg.h>
+#include <windows.h>
+
+#include <stdio.h>
+
+#include <winsock2.h>
+#include <mswsock.h>
+#include <assert.h>
+
+#include "wine/test.h"
+
+
+/* some of my favourite #defines */
+#define HANDLE_VALID(x) (!(x==INVALID_HANDLE_VALUE))
+
+/* free memory and set pointer to NULL */
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(x) {if(x) {free(x); x=NULL;}}
+#endif
+
+#ifndef SAFE_HRELEASE
+#define SAFE_HRELEASE(x) {if(x!=INVALID_HANDLE_VALUE) {CloseHandle(x); x=INVALID_HANDLE_VALUE;}}
+#endif
+
+#define MAX_DATA_JUNK 2048 /* should exceed the one set inside mswsock */
+
+#define FILENAME1_OUTPUT         "testfile1.out"
+#define FILENAME2_OUTPUT         "testfile2.out"
+#define FILENAME1_INPUT          "testfile1.in"
+
+#define TESTFILE_SIZE_EMPTY         0l
+#define TESTFILE_SIZE_SMALL      512l
+#define TESTFILE_SIZE_MEDIUM     8l * TESTFILE_SIZE_SMALL
+#define TESTFILE_SIZE_BIG        406l * TESTFILE_SIZE_SMALL
+/*uncomment  the line below if you want to make the long test (it takes really a lot of time) */
+/** #define RUN_BIG_FILE_TEST  /**/
+
+#define DATA_BUF_SIZE_EMPTY        0l      /* test will use an empty tfb.head data */
+#define DATA_BUF_SIZE_SMALL        1024l /* test will use an  tfb.head data  <=  expected max data junk*/
+#define DATA_BUF_SIZE_BIG        4123l /* test will use an  tfb.head data  >  expected max data junk*/
+
+#define MAX_FILENAME             40
+#define TESTFILE_PATTERN        "TESTFILE"
+
+#define TESTMODE_HEAD            0x0001 /* for TransmitFile - test with head TFB field   */
+#define TESTMODE_FILE             0x0002 /* for TransmitFile - test with valid file handle */
+#define TESTMODE_TAIL             0x0004 /* for TransmitFile - test with tail TFB field set */
+#define TESTMODE_OVL             0x0008 /* test using overlapped IO */
+#define TESTMODE_INVALIDFILE     0x0010 /* test using INVALID_HANDLE_VALUE */
+#define TESTMODE_USERANDOM        0x0020 /* fill memory buffers with random data instead of fixed pattern */
+
+#define BASE_PORT_NUM             3421
+#define SHIFT_PORT_NUM            1 /*every test should use different port number. We will increase it by the value every time */
+
+
+/*************************************************************************************/
+/* Structures  */
+typedef struct ThreadParams
+{
+    char     name[MAX_FILENAME + 1];
+    UINT     nPortNumber;
+    HANDLE   hServerStopped;
+    HANDLE   hListenerStarted;    
+}ThreadParams, *lpThreadParams;
+
+/*************************************************************************************/
+/* Globals */
+static HANDLE     hThReceiver     = INVALID_HANDLE_VALUE;
+static UINT        nLastPortNumber = BASE_PORT_NUM - 1;
+
+/*************************************************************************************/
+/* ReceiverFunction - should be started in new thread or can cause program exit */
+static DWORD WINAPI ReceiverFunction(LPVOID params)
+{
+    SOCKET   server, connection;
+    DWORD    reclen, writelen;
+    char     tempbuf[MAX_DATA_JUNK];
+    struct   sockaddr_in local;
+    HANDLE   hFOutput;
+    struct   sockaddr_in their_addr; 
+    int      sin_size;
+    struct   ThreadParams * lpParams;
+    int      nIntRetval = 0;
+    lpParams  = (ThreadParams*)params;
+    
+    hFOutput = CreateFile((char *)lpParams->name, 
+        GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 
+        FILE_ATTRIBUTE_NORMAL,  0);
+    
+    ok(HANDLE_VALID(hFOutput),"Can't create output file in server thread, errno: %ld\n", GetLastError());
+    if(!HANDLE_VALID(hFOutput))
+        goto error;
+    
+    local.sin_family=AF_INET; 
+    local.sin_addr.s_addr=INADDR_ANY; 
+    local.sin_port=htons(lpParams->nPortNumber); 
+
+    server=socket(AF_INET,SOCK_STREAM,0);
+
+    ok((server != INVALID_SOCKET),
+        "Can't create socket in server thread, errno: %d\n", WSAGetLastError());
+    if(server == INVALID_SOCKET)
+        goto error_close_file;
+    
+    ok (((nIntRetval = bind(server,(struct sockaddr*)&local,sizeof(local))) == 0 ),
+        "Can't bind socket in server thread, errno: %d\n", WSAGetLastError());
+    if(nIntRetval)
+        goto error_close_file;
+        
+    ok(((nIntRetval = listen(server,1)) == 0),
+        "Can't listen on socket in server thread, errno: %d\n", WSAGetLastError());
+        
+    if(nIntRetval)
+        goto error_close_file;    
+        
+    SetEvent(lpParams->hListenerStarted);
+    
+    sin_size = sizeof(struct sockaddr_in);
+    
+    ok(((connection = accept(server, (struct sockaddr *)&their_addr,    &sin_size)) != -1),
+        "Error on call to accept in server thread, errno: %d\n", WSAGetLastError());
+    if ( connection == -1)
+        goto error_close_file;
+    
+    trace    ("server: got connection from %s\n", inet_ntoa(their_addr.sin_addr));
+    closesocket(server);    
+
+    do
+    {
+        reclen=recv(connection,tempbuf,MAX_DATA_JUNK,0); 
+        ok((reclen != -1), "Error while receiving data in server thread, errno: %d\n",
+            WSAGetLastError()) ;
+        if(reclen == -1)
+            goto error_close_file;
+        ok((nIntRetval = WriteFile(hFOutput, (char *)tempbuf, reclen, &writelen, 0)),
+            "Failed writing to output file in server thread, errno: %d\n", WSAGetLastError());
+        if(!nIntRetval)
+            goto error_close_file;
+        /* this shouldn't happen but is possible - TODO: service it */
+        ok((reclen == writelen), "Failed writing input file data in server thread (read != written\n");
+        if(reclen != writelen)
+            goto error_close_file;
+    }while(reclen);
+
+    trace    ("Stopping listener thread\n");
+    
+    CloseHandle(hFOutput);
+    
+    SetEvent(lpParams->hServerStopped);
+    ExitThread(TRUE);
+
+error_close_file:
+    CloseHandle(hFOutput);
+error:
+    SetEvent(lpParams->hListenerStarted);
+    SetEvent(lpParams->hServerStopped);
+    ExitThread(FALSE);
+}
+
+/*************************************************************************************/
+/* Prepare input files */
+static DWORD PrepareInputFiles(DWORD filelen)
+{
+    HANDLE    hFOutput     = INVALID_HANDLE_VALUE;
+    int     i             = 0;
+    int     size        = 0;
+    DWORD   written      = 0;
+    DWORD   filesize      = 0;
+    BOOL    nBoolRetval = FALSE;
+    
+    trace    ("Creating temporary input file, length: %ld\n", filelen);
+
+    hFOutput = CreateFile(FILENAME1_INPUT, 
+        GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 
+        FILE_ATTRIBUTE_NORMAL,  0);
+
+    ok(HANDLE_VALID(hFOutput), "Error creating input file, errno: %ld\n", GetLastError());
+    if(!HANDLE_VALID(hFOutput))
+        return FALSE;
+    
+    filesize = filelen;
+    size = filesize / (sizeof(TESTFILE_PATTERN) - 1);
+    for(i = 0; i < size; i++)
+    {
+        ok((nBoolRetval = WriteFile(hFOutput, (const char *)TESTFILE_PATTERN, 
+                                    sizeof(TESTFILE_PATTERN) - 1, &written, 0)),
+            "Failed writing to temporary input file, errno: %ld\n", GetLastError());
+        
+        if(!nBoolRetval)
+        {
+            CloseHandle(hFOutput);
+            trace    ("FAILED\n");
+            return FALSE;
+        }
+        
+        ok((written == sizeof(TESTFILE_PATTERN) - 1), "WARNING: Failed writing to"
+            "temporary input file (written less than wanted)\n");        
+            
+        if(!(i % (sizeof(TESTFILE_PATTERN) - 1) * 1024 * 1024))
+            trace    (".");
+    }
+
+    if(filesize % (sizeof(TESTFILE_PATTERN) -1) )
+    {
+        ok((nBoolRetval = WriteFile(hFOutput, (const char *)TESTFILE_PATTERN, 
+                        filesize % (sizeof(TESTFILE_PATTERN) - 1), &written, 0)),
+        "Failed writing to temporary input file, errno: %ld", GetLastError());
+        ok((written == filesize % sizeof(TESTFILE_PATTERN) - 1), "WARNING: Failed writing to"
+            "temporary input file (written less than wanted)\n");
+        if(!nBoolRetval)
+        {
+            CloseHandle(hFOutput);
+            trace    ("\nFAILED\n");
+            return FALSE;
+        }
+    }
+    
+    trace    ("OK\n");
+    CloseHandle(hFOutput);
+    return TRUE;
+}
+
+
+/*************************************************************************************/
+/* A 'fast' file byte-by-byte file compare. It exits on first failure */
+static DWORD FileCmp( const char *f1, const char *f2)
+{
+    HANDLE hf1, hf2;
+    DWORD position = 0;
+    int char1 = 0;
+    int char2 = 0;
+    DWORD readlen1, readlen2;
+
+    hf1 = CreateFile(f1, 
+        GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 
+        FILE_ATTRIBUTE_NORMAL,  0);    
+
+    if(!HANDLE_VALID(hf1))
+    {
+        trace    ("Can't open input file 1\n");
+        return FALSE;
+    }
+    
+    hf2 =     CreateFile(f2, 
+        GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 
+        FILE_ATTRIBUTE_NORMAL,  0);    
+    
+    if(!HANDLE_VALID(hf2))
+    {
+        trace    ("Can't open input file 2\n");
+        CloseHandle(hf1);
+        return FALSE;
+    }
+    
+    trace    ("Starting file comparison...\n");
+    while(1)
+    { 
+        position++;
+        
+        ReadFile(hf1, &char1, 1, &readlen1,0);
+        ReadFile(hf2, &char2, 1, &readlen2,0);
+
+        ok((readlen1 == readlen1), "File comparison failed file sizes differ\n");
+        
+        ok((char1 == char2), "File comparison failed, pos: %ld, ch1: %04x, ch2: %04x\n",
+            position, char1, char2);
+            
+        if(char1 != char2 || readlen1 != readlen2) 
+        {
+            CloseHandle(hf1);
+            CloseHandle(hf2);
+            return FALSE;
+        }
+        
+        if(!readlen1 || !readlen2)
+            break;
+        
+        if(!(position %  1024))
+            trace    ("%ld ",position);
+            
+    }
+    
+    trace    ("\nComparison OK! \n" );
+    CloseHandle(hf1);
+    CloseHandle(hf2);
+    return TRUE;
+}
+/*************************************************************************************/
+/* PrepareDataBuf */
+static DWORD PrepareDataBuf(LPVOID *buf, DWORD len, DWORD mode, char pattern)
+{
+    int i;
+    if(!len)
+    {
+        *buf = 0;
+        return TRUE;
+    }
+   
+    ok((*buf = malloc(len)) != NULL, "Can't allocate memory\n");
+    if(!*buf)
+        return FALSE;
+    
+    if(mode & TESTMODE_USERANDOM)
+        for(i=0; i< len; i++)
+            ((unsigned char *)*buf)[i] = rand() % 255;
+    else
+        memset(*buf, pattern, len);
+    return TRUE;
+}
+
+/*************************************************************************************/
+/* TestPositiveTransmitFileOverlapped */
+/* We pass such information that  TransmitFile should deal with no problem */
+static int TestTransmitFileOverlapped(UCHAR mode, DWORD headlen, DWORD filelen, DWORD taillen ) 
+{
+    WSAOVERLAPPED Overlapped;
+    SOCKET     SendSocket = INVALID_SOCKET;
+    struct sockaddr_in RecvAddr;
+    struct sockaddr_in LocalAddr;
+    int  LocalAddrSize = sizeof(LocalAddr);
+    int  Port;
+    DWORD writelen, readlen;
+    char *ip;
+    struct hostent* localHost;
+    char fbuff[1024];
+    struct ThreadParams tp;    
+    
+    HANDLE hFile     = INVALID_HANDLE_VALUE; 
+    HANDLE hOutFile = INVALID_HANDLE_VALUE;
+    
+    TRANSMIT_FILE_BUFFERS tfb;
+    DWORD     dwRetVal = 0, tmp = 0;
+    LPOVERLAPPED lpOverlapped     = 0;
+    LPTRANSMIT_FILE_BUFFERS lptfb = 0;
+    
+    static int testno = 0;
+    testno++;
+    
+    trace    ("Testing simple use of TransmitFile. test number: %02d\n", testno);
+    
+    memset(&tfb, 0, sizeof( TRANSMIT_FILE_BUFFERS));
+
+    /* we shift the port as there is possibility we cannot reuse it at the time we want  random gives even bigger chance on different systems*/
+    nLastPortNumber += SHIFT_PORT_NUM;
+    Port = nLastPortNumber ;
+    
+    if(mode & TESTMODE_HEAD)
+    {
+        tfb.HeadLength = headlen;
+        ok((dwRetVal = PrepareDataBuf(&tfb.Head, tfb.HeadLength, mode, 'H')),
+            "Can't create data buffer for tfb.Head\n");
+        
+        if(!dwRetVal)
+            goto e_exit;
+
+        trace    ("tfb.HeadLength: %ld\n", tfb.HeadLength);
+    }
+    
+    if(mode & TESTMODE_TAIL)
+    {
+        tfb.TailLength = taillen;
+        ok((dwRetVal = PrepareDataBuf(&tfb.Tail, tfb.TailLength, mode, 'T')),
+            "Can't create data buffer for tfb.Tail\n");
+        
+        if(!dwRetVal)
+            goto e_exit;
+        trace    ("tfb.TailLength: %ld\n", tfb.TailLength);
+    }
+    
+    if(mode & TESTMODE_FILE)
+    {
+        ok((dwRetVal = PrepareInputFiles(filelen)), "Couldn't create input file!\n");
+        if(!dwRetVal)
+            goto e_exit;
+    
+        hFile =  CreateFile(FILENAME1_INPUT, 
+            GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 
+            FILE_ATTRIBUTE_NORMAL,  0);
+        
+        ok(HANDLE_VALID(hFile), "Couldn't open input file, errno: %ld\n", GetLastError());
+        if(!HANDLE_VALID(hFile))
+            goto e_exit;
+    }
+    else if(mode & TESTMODE_INVALIDFILE)
+    {
+        hFile = INVALID_HANDLE_VALUE;
+    }
+    else
+    {
+        hFile = 0;
+    }
+        
+    hOutFile  = CreateFile((const char*)FILENAME1_OUTPUT, 
+        GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, 
+        FILE_ATTRIBUTE_NORMAL,  0);
+
+    ok(HANDLE_VALID(hOutFile), "Can't create output file, errno: %ld\n", GetLastError());
+    if(!HANDLE_VALID(hOutFile))
+        goto e_exit;
+    
+    /* Copy data to output file. The same data should arrive on the server side... */
+    trace    ("Writing output file information...\n (the same data would be expected on the other side)\n");
+    
+    ok((dwRetVal = WriteFile(hOutFile, tfb.Head, tfb.HeadLength, &writelen, 0)),
+        "Write operation to output file failed, (head) errno: %ld\n", GetLastError());
+    if(!dwRetVal)
+        goto e_exit;
+    
+    ok((writelen == tfb.HeadLength), "written len != write len, (head) this is critical here :-(\n");
+    if(writelen != tfb.HeadLength)
+        goto e_exit;
+    
+    if(mode & TESTMODE_FILE)
+    {
+        ok((dwRetVal = ReadFile(hFile, fbuff, sizeof(fbuff), &readlen,0)),"Can't read from input file\n");
+        if(!dwRetVal)
+            goto e_exit;
+            
+        while(readlen)
+        {
+            ok((dwRetVal = WriteFile(hOutFile, fbuff, readlen, &writelen, 0)),
+                "Can't write to output file, (file) errno: %ld\n", GetLastError());
+            if(!dwRetVal)
+                goto e_exit;
+
+            ok((writelen == readlen), "written len != write len (file), this is critical here :-(\n");
+            if(writelen != readlen)
+                goto e_exit;
+                
+            ok((dwRetVal = ReadFile(hFile, fbuff, sizeof(fbuff), &readlen,0)),"Can't read from input file\n");
+            if(!dwRetVal)
+                goto e_exit;
+        }
+    }
+    ok((dwRetVal = WriteFile(hOutFile, tfb.Tail, tfb.TailLength, &writelen, 0)),
+        "Write operation to output file failed (tail), errno: %ld\n", GetLastError());
+    if(!dwRetVal)
+        goto e_exit;
+    
+    ok((writelen == tfb.TailLength), "written len != write len (tail), this is critical here :-(\n");
+    if(writelen != tfb.TailLength)
+        goto e_exit;
+    
+    CloseHandle(hOutFile);
+    
+    /* rewind the input file pointer */
+    if(mode & TESTMODE_FILE)
+        SetFilePointer(hFile,0,0,FILE_BEGIN);
+
+    /* start the server - it will create the second file to compare from the recived data */
+    strcpy(tp.name,FILENAME2_OUTPUT);
+
+    tp.nPortNumber         = Port;
+    tp.hListenerStarted = CreateEvent(0,1,0,0);
+    tp.hServerStopped   = CreateEvent(0,1,0,0);
+    
+    hThReceiver  = CreateThread(0, 0, ReceiverFunction, (void *) &tp, 0, 0);
+
+    ok(HANDLE_VALID(hThReceiver), "Can't start server thread, errno: %ld\n",
+        GetLastError());
+        
+    if(!HANDLE_VALID(hThReceiver))
+        goto e_exit;
+    
+    /* do not want to try to connect before we are listening */
+    WaitForSingleObject(tp.hListenerStarted, INFINITE);
+
+    /* Create a socket for sending data */
+    if(mode & TESTMODE_OVL)
+        SendSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
+    else
+        SendSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
+    
+    ok((SendSocket  != INVALID_SOCKET),
+        "Can't create socket, errno: %d\n", WSAGetLastError());
+    if(SendSocket  == INVALID_SOCKET)
+        goto e_exit;
+        
+    /* Set up the RecvAddr structure with the IP address of
+    the receiver (in this example case "123.123.123.1")
+    and the specified port number.*/
+    RecvAddr.sin_family = AF_INET;
+    RecvAddr.sin_port = htons(Port);
+    RecvAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+    /* Set up the LocalAddr structure with the local IP address
+    and the specified port number.    */
+    localHost = gethostbyname("127.0.0.1");
+    ip = inet_ntoa (*(struct in_addr *)*localHost->h_addr_list);
+
+    LocalAddr.sin_family = AF_INET;
+    LocalAddr.sin_addr.s_addr = inet_addr(ip);
+    LocalAddr.sin_port = htons(0);
+
+    /* Bind the sending socket to the LocalAddr structure
+    that has the internet address family, local IP addrfcess
+    and specified port number.  */
+    ok (((dwRetVal = bind(SendSocket, (struct sockaddr*) &LocalAddr, LocalAddrSize)) == 0 ),
+        "Can't bind socket in server thread, errno: %d\n", WSAGetLastError());
+    if(dwRetVal)
+        goto e_exit;
+            
+    ok((dwRetVal = connect(SendSocket, (struct sockaddr *)&RecvAddr,    
+                            sizeof(struct sockaddr)) != -1),
+        "Can't connect to server, errno: %d\n", WSAGetLastError());
+    
+    if (dwRetVal == -1) 
+        goto e_exit;
+
+    memset(&Overlapped, 0, sizeof(OVERLAPPED));
+    Overlapped.hEvent = CreateEvent(0,1,0,0);
+
+    ResetEvent(Overlapped.hEvent);
+
+    /* some help variables */
+    if(TESTMODE_OVL & mode)
+        lpOverlapped = &Overlapped;
+    else
+        lpOverlapped = 0;
+    
+    if(TESTMODE_HEAD || TESTMODE_TAIL)
+        lptfb = &tfb;
+    else
+        lptfb = 0;
+
+    /* run the test */
+    dwRetVal = TransmitFile(SendSocket, hFile, 0, 0, lpOverlapped, lptfb, 0);
+    
+    if(TESTMODE_OVL & mode)
+    {
+        if(!dwRetVal) /* TransmitFile didn't finnish */
+        {
+            dwRetVal = WSAGetOverlappedResult(SendSocket, lpOverlapped, &writelen,
+                1, &readlen);
+            
+            if(!dwRetVal )
+            {
+                ok(((dwRetVal = WSAGetLastError()) == WSA_IO_INCOMPLETE), 
+                    "WSAGetOverlappedResult errno: %ld\n", dwRetVal);
+        
+                if(dwRetVal != WSA_IO_INCOMPLETE)
+                    goto e_exit;
+            }
+        }
+    }    
+    
+    trace    ("Finished sending. Closing socket.\n");
+    closesocket(SendSocket);
+    /* wait for the listening server to close */
+    WaitForSingleObject(tp.hServerStopped, INFINITE);    
+
+
+    
+    /* Check for server function return value */
+    if(dwRetVal)
+    {
+        ok(GetExitCodeThread(hThReceiver, &tmp), 
+            "Can't get thread return value, errno: %ld\n", GetLastError());
+        if(!GetExitCodeThread(hThReceiver, &tmp))
+            goto e_exit;
+        ok(tmp, "ServerThread exited with error \n");
+        if(!tmp)
+            goto e_exit;
+    }
+    
+    SAFE_HRELEASE(hThReceiver);
+    SAFE_HRELEASE(tp.hListenerStarted);
+    SAFE_HRELEASE(tp.hServerStopped);
+    SAFE_HRELEASE(hFile);
+
+    SAFE_RELEASE(tfb.Head);
+    SAFE_RELEASE(tfb.Tail);
+    
+    return dwRetVal;
+        
+e_exit:
+    closesocket(SendSocket);                                        
+    trace    ("Failed!\n");
+    
+    WaitForSingleObject(tp.hServerStopped, INFINITE);
+    SAFE_HRELEASE(hThReceiver);
+    SAFE_HRELEASE(tp.hListenerStarted);
+    SAFE_HRELEASE(tp.hServerStopped);
+    SAFE_HRELEASE(hFile);
+
+    SAFE_RELEASE(tfb.Head);
+    SAFE_RELEASE(tfb.Tail);
+    return FALSE;
+}
+
+/* ****************************************************************************************** */
+#define TransmitFileCmpTest(mode, headlen, filelen, taillen) \
+    { \
+        ok((dwRetVal = \
+            TestTransmitFileOverlapped(mode,headlen, filelen,taillen)), \ 
+            "TransmitFile(%04x, %ld, %ld, %ld)  failed\n", mode, headlen, filelen, taillen); \
+            if(dwRetVal){    \
+            ok(FileCmp( FILENAME1_OUTPUT, FILENAME2_OUTPUT), \
+                "TransmitFile(%04x, %ld, %ld, %ld) exited with TRUE status but produced bad output!\n", \
+                mode, headlen, filelen, taillen);}}
+
+static void TestTransmitFilePositiveFileOnly(void)
+{
+    DWORD dwRetVal = 0;
+    
+    /* test non-overlapped TransmitFile (file) */
+
+    TransmitFileCmpTest(TESTMODE_FILE | TESTMODE_INVALIDFILE, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+        
+    TransmitFileCmpTest(TESTMODE_FILE, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+        
+    TransmitFileCmpTest(TESTMODE_FILE, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_SMALL, DATA_BUF_SIZE_EMPTY)
+        
+    TransmitFileCmpTest(TESTMODE_FILE, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_MEDIUM, DATA_BUF_SIZE_EMPTY)
+
+    TransmitFileCmpTest(TESTMODE_FILE, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_BIG, DATA_BUF_SIZE_EMPTY)
+    
+}
+/* *********************************************************************************** */
+static void TestTransmitFilePositiveNoFile(void)
+{
+    DWORD dwRetVal = 0;
+
+    /* test head - only */
+    TransmitFileCmpTest(TESTMODE_HEAD, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+
+    TransmitFileCmpTest(TESTMODE_HEAD, 
+        DATA_BUF_SIZE_SMALL, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+
+    TransmitFileCmpTest(TESTMODE_HEAD, 
+        DATA_BUF_SIZE_BIG, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+
+    /* test tail-only */
+    TransmitFileCmpTest(TESTMODE_TAIL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+
+    TransmitFileCmpTest(TESTMODE_TAIL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_SMALL)        
+
+    TransmitFileCmpTest(TESTMODE_TAIL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_BIG)        
+
+    /* test tail-and-head */
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_TAIL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+    
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_TAIL, 
+        DATA_BUF_SIZE_SMALL, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_SMALL)        
+
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_TAIL, 
+        DATA_BUF_SIZE_BIG, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_BIG)        
+}
+
+static void TestTransmitFilePositiveMixed(void)
+{
+    DWORD dwRetVal = 0;
+
+    /* test head null_send */
+    TransmitFileCmpTest(0, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+    
+    /* test head empty_send */
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_TAIL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+
+    /* test head+ file  */
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE, 
+        DATA_BUF_SIZE_SMALL, TESTFILE_SIZE_SMALL, DATA_BUF_SIZE_EMPTY)        
+
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_SMALL, DATA_BUF_SIZE_EMPTY)        
+
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE, 
+        DATA_BUF_SIZE_BIG, TESTFILE_SIZE_MEDIUM, DATA_BUF_SIZE_EMPTY)        
+        
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE, 
+        DATA_BUF_SIZE_BIG, TESTFILE_SIZE_BIG, DATA_BUF_SIZE_EMPTY)        
+
+        
+    /* test tail + file */
+    TransmitFileCmpTest(TESTMODE_TAIL | TESTMODE_FILE, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_SMALL)        
+
+    TransmitFileCmpTest(TESTMODE_TAIL | TESTMODE_FILE, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_SMALL, DATA_BUF_SIZE_SMALL)        
+
+    TransmitFileCmpTest(TESTMODE_TAIL | TESTMODE_FILE, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_MEDIUM, DATA_BUF_SIZE_BIG)        
+        
+    TransmitFileCmpTest(TESTMODE_TAIL | TESTMODE_FILE, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_BIG, DATA_BUF_SIZE_BIG)        
+
+    /* test tail-file-head */
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_TAIL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_SMALL, DATA_BUF_SIZE_EMPTY)        
+    
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_TAIL, 
+        DATA_BUF_SIZE_SMALL, TESTFILE_SIZE_SMALL, DATA_BUF_SIZE_SMALL)        
+
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_TAIL, 
+        DATA_BUF_SIZE_BIG, TESTFILE_SIZE_SMALL, DATA_BUF_SIZE_BIG)        
+
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_TAIL, 
+        DATA_BUF_SIZE_BIG, TESTFILE_SIZE_MEDIUM, DATA_BUF_SIZE_BIG)        
+
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_TAIL, 
+        DATA_BUF_SIZE_BIG, TESTFILE_SIZE_BIG, DATA_BUF_SIZE_BIG)        
+        
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_TAIL, 
+        DATA_BUF_SIZE_SMALL, TESTFILE_SIZE_BIG, DATA_BUF_SIZE_SMALL)        
+}
+
+/* *********************************************************************************** */
+static void TestTransmitFilePositiveFileOnlyOvl(void)
+{
+    DWORD dwRetVal = 0;
+    
+    /* test non-overlapped TransmitFile (file) */
+
+    TransmitFileCmpTest(TESTMODE_FILE | TESTMODE_INVALIDFILE | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+        
+    TransmitFileCmpTest(TESTMODE_FILE | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+        
+    TransmitFileCmpTest(TESTMODE_FILE | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_SMALL, DATA_BUF_SIZE_EMPTY)
+        
+    TransmitFileCmpTest(TESTMODE_FILE | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_MEDIUM, DATA_BUF_SIZE_EMPTY)
+
+    TransmitFileCmpTest(TESTMODE_FILE | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_BIG, DATA_BUF_SIZE_EMPTY)
+}
+/* *********************************************************************************** */
+static void TestTransmitFilePositiveNoFileOvl(void)
+{
+    DWORD dwRetVal = 0;
+
+        
+    /* test head - only */
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_OVL,
+        DATA_BUF_SIZE_SMALL, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)    
+    
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_OVL, 
+        DATA_BUF_SIZE_BIG, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+
+    /* test tail-only */
+    TransmitFileCmpTest(TESTMODE_TAIL | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+
+    TransmitFileCmpTest(TESTMODE_TAIL | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_SMALL)        
+
+    TransmitFileCmpTest(TESTMODE_TAIL | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_BIG)        
+
+    /* test tail-and-head */
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_TAIL | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+    
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_TAIL | TESTMODE_OVL, 
+        DATA_BUF_SIZE_SMALL, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_SMALL)        
+
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_TAIL | TESTMODE_OVL, 
+        DATA_BUF_SIZE_BIG, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_BIG)        
+}
+
+static void TestTransmitFilePositiveMixedOvl(void)
+{
+    DWORD dwRetVal = 0;
+
+    /* test head null_send */
+    TransmitFileCmpTest(TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+    
+    /* test head empty_send */
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_TAIL | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_EMPTY)        
+
+    /* test head+ file  */
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_OVL, 
+        DATA_BUF_SIZE_SMALL, TESTFILE_SIZE_SMALL, DATA_BUF_SIZE_EMPTY)        
+
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_SMALL, DATA_BUF_SIZE_EMPTY)        
+
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_OVL, 
+        DATA_BUF_SIZE_BIG, TESTFILE_SIZE_MEDIUM, DATA_BUF_SIZE_EMPTY)        
+        
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_OVL, 
+        DATA_BUF_SIZE_BIG, TESTFILE_SIZE_BIG, DATA_BUF_SIZE_EMPTY)        
+
+        
+    /* test tail + file */
+    TransmitFileCmpTest(TESTMODE_TAIL | TESTMODE_FILE | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_EMPTY, DATA_BUF_SIZE_SMALL)        
+
+    TransmitFileCmpTest(TESTMODE_TAIL | TESTMODE_FILE | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_SMALL, DATA_BUF_SIZE_SMALL)        
+
+    TransmitFileCmpTest(TESTMODE_TAIL | TESTMODE_FILE | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_MEDIUM, DATA_BUF_SIZE_BIG)        
+        
+    TransmitFileCmpTest(TESTMODE_TAIL | TESTMODE_FILE | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_BIG, DATA_BUF_SIZE_BIG)        
+
+    /* test tail-file-head */
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_TAIL | TESTMODE_OVL, 
+        DATA_BUF_SIZE_EMPTY, TESTFILE_SIZE_SMALL, DATA_BUF_SIZE_EMPTY)        
+    
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_TAIL | TESTMODE_OVL, 
+        DATA_BUF_SIZE_SMALL, TESTFILE_SIZE_SMALL, DATA_BUF_SIZE_SMALL)        
+
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_TAIL | TESTMODE_OVL, 
+        DATA_BUF_SIZE_BIG, TESTFILE_SIZE_SMALL, DATA_BUF_SIZE_BIG)        
+
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_TAIL | TESTMODE_OVL, 
+        DATA_BUF_SIZE_BIG, TESTFILE_SIZE_MEDIUM, DATA_BUF_SIZE_BIG)        
+
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_TAIL | TESTMODE_OVL, 
+        DATA_BUF_SIZE_BIG, TESTFILE_SIZE_BIG, DATA_BUF_SIZE_BIG)        
+        
+    TransmitFileCmpTest(TESTMODE_HEAD | TESTMODE_FILE | TESTMODE_TAIL | TESTMODE_OVL, 
+        DATA_BUF_SIZE_SMALL, TESTFILE_SIZE_BIG, DATA_BUF_SIZE_SMALL)        
+}
+
+
+/*************************************************************************************/
+/* main job */
+START_TEST( wsock )
+{
+    /* Initialize Winsock */
+    WSADATA wsaData;
+    WSAStartup(MAKEWORD(2,2), &wsaData);
+
+    trace    ("Testing mswsock.dll TransmitXXX functions\n");
+
+    TestTransmitFilePositiveNoFile();
+    TestTransmitFilePositiveFileOnly();
+    TestTransmitFilePositiveMixed();
+
+    TestTransmitFilePositiveNoFileOvl();
+    TestTransmitFilePositiveFileOnlyOvl();
+    TestTransmitFilePositiveMixedOvl();        
+    
+    todo_wine
+    {
+    }
+    
+    trace    ("Deleting temporary files... ");
+    DeleteFile(FILENAME1_OUTPUT);
+    DeleteFile(FILENAME2_OUTPUT);
+    DeleteFile(FILENAME1_INPUT);
+    trace    ("OK\n");
+    WSACleanup();
+    return;
+}
+
+#undef TransmitFileCmpTest
--- /dev/null	2006-06-27 15:09:45.552523000 +0200
+++ dlls/mswsock/tests/.cvsignore	2006-06-28 01:08:04.000000000 +0200
@@ -0,0 +1,4 @@
+Makefile
+wsock.ok
+testlist.c
+


More information about the wine-patches mailing list