mswsock.dll patch - Add simple TransmitFile functionality [2/2] - conformance tests

Łukasz Chróst lukost at gmail.com
Mon Jun 26 08:48:51 CDT 2006


changelog:
 - basic mswsock.dll TransmitFile tests created (both for overlapped and
non-overlapped).

--
Łukasz Chróst


-------------- next part --------------
? dlls/wineps
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-26 15:26:15.880481000 +0200
+++ dlls/mswsock/tests/Makefile.in	2006-06-25 21:55:24.000000000 +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-26 15:26:15.880481000 +0200
+++ dlls/mswsock/tests/.cvsignore	2006-06-25 22:43:44.000000000 +0200
@@ -0,0 +1,3 @@
+Makefile
+wsock.ok
+testlist.c
--- /dev/null	2006-06-26 15:26:15.880481000 +0200
+++ dlls/mswsock/tests/wsock.c	2006-06-26 14:55:01.500000000 +0200
@@ -0,0 +1,867 @@
+/*
+ * MSWSOCK specific functions tests
+ *
+ * Copyright (C) 2006 Łukasz Chróst
+ *
+ * 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);
+			exit(1); /*???*/
+			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);
+	
+	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)		
+}
+
+#undef TransmitFileCmpTest
+
+/*************************************************************************************/
+/* main job */
+START_TEST( wsock )
+{
+	/* Initialize Winsock */
+	WSADATA wsaData;
+	WSAStartup(MAKEWORD(2,2), &wsaData);
+
+	trace("Testing mswsock.dll TransmitXXX functions\n");
+	
+	TestTransmitFilePositiveNoFile();
+	TestTransmitFilePositiveFileOnly();
+	TestTransmitFilePositiveMixed();
+
+	todo_wine
+	{
+		TestTransmitFilePositiveNoFileOvl();
+		TestTransmitFilePositiveFileOnlyOvl();
+		TestTransmitFilePositiveMixedOvl();	
+	}
+	
+	trace("Deleting temporary files... ");
+	DeleteFile(FILENAME1_OUTPUT);
+	DeleteFile(FILENAME2_OUTPUT);
+	DeleteFile(FILENAME1_INPUT);
+	trace("OK\n");
+	WSACleanup();
+	return;
+}


More information about the wine-patches mailing list