BuildCommDCB conformance test

Kevin Groeneveld kgroeneveld at mcmaster.ca
Thu Sep 11 00:32:01 CDT 2003


Here is my first attempt at a conformance test for the BuildCommDCB
functions.  It does not cover very many cases yet, but I thought I would
post what I have so far in case I am going about this the wrong way.

I compiled this with MSVC and it ran with no errors on both Windows 95
and Windows 2000.

It also compiles with libwine in Linux, but for this to work you need to
add a missing member to the DCB structure in winbase.h.  If I run this
test with the existing implementation of BuildCommDCB it page faults,
probably because it is writing to a constant string.  If my previous
patch to BuildCommDCB is applied, then the test runs ok.


Kevin


-------------- next part --------------
diff -urN wine-20030813/dlls/kernel/tests/Makefile.in wine-20030813.patched/dlls/kernel/tests/Makefile.in
--- wine-20030813/dlls/kernel/tests/Makefile.in	2003-08-23 23:12:31.000000000 -0400
+++ wine-20030813.patched/dlls/kernel/tests/Makefile.in	2003-09-10 23:31:59.000000000 -0400
@@ -8,6 +8,7 @@
 CTESTS = \
 	alloc.c \
 	atom.c \
+	build_dcb.c \
 	codepage.c \
 	console.c \
 	directory.c \
diff -urN wine-20030813/dlls/kernel/tests/build_dcb.c wine-20030813.patched/dlls/kernel/tests/build_dcb.c
--- wine-20030813/dlls/kernel/tests/build_dcb.c	1969-12-31 19:00:00.000000000 -0500
+++ wine-20030813.patched/dlls/kernel/tests/build_dcb.c	2003-09-11 01:00:19.000000000 -0400
@@ -0,0 +1,171 @@
+/* Unit test suite for BuildCommDCBA/W & BuildCommDCBAndTimeoutsA/W
+ *
+ * Copyright 2003 Kevin Groeneveld
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "wine/test.h"
+#include "winbase.h"
+
+typedef struct
+{
+	char *string;
+	BOOL result;
+	DCB dcb1, dcb2;
+	COMMTIMEOUTS timeouts1, timeouts2;
+} TEST;
+
+TEST test[] =
+{
+	{
+		"baud=9600",
+		TRUE,
+		{ 0x00000000, 9600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 0x0000 },
+		{ 0xffffffff, 9600, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0x00, (char)0xff, (char)0xff, (char)0xff, (char)0xff, (char)0xff, 0xffff },
+		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+		{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
+	},
+	{
+		" baud=9600",
+		FALSE,
+		{ 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 0x0000 },
+		{ 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, (char)0xff, (char)0xff, (char)0xff, (char)0xff, (char)0xff, 0xffff },
+		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+		{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
+	},
+	{
+		"to=on",
+		TRUE,
+		{ 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, 0x0000 },
+		{ 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0x00, (char)0xff, (char)0xff, (char)0xff, (char)0xff, (char)0xff, 0xffff },
+		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000EA60 },
+		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000EA60 }
+	},
+};
+
+#define TEST_COUNT (sizeof(test) / sizeof(TEST))
+
+void check_result(char *function, char *string, int initial_value, BOOL result1, BOOL result2)
+{
+	DWORD LastError = GetLastError();
+	DWORD CorrectError = (result2 ? 0xdeadbeef : ERROR_INVALID_PARAMETER);
+
+	ok(LastError == CorrectError, "%s(\"%s\"), 0x%02x: GetLastError() returned 0x%08lx, should be 0x%08lx", function, string, initial_value, LastError, CorrectError);
+	ok(result1 == result2, "%s(\"%s\"), 0x%02x: return value should be %s", function, string, initial_value, result2 ? "TRUE" : "FALSE");
+}
+
+#define check_dcb_member(a,b) ok(pdcb1->a == pdcb2->a, "%s(\"%s\"), 0x%02x: "#a" is "b", should be "b, function, string, initial_value, pdcb1->a, pdcb2->a);
+
+void check_dcb(char *function, char *string, int initial_value, DCB *pdcb1, DCB *pdcb2)
+{
+	/* DCBlength is a special case since Win 9x sets it but NT does not.
+	   We will accept either as correct. */
+	ok(pdcb1->DCBlength == pdcb2->DCBlength || pdcb1->DCBlength == sizeof(DCB), "%s(\"%s\"), 0x%02x: DCBlength is %lu, should be %lu or %lu", function, string, initial_value, pdcb1->DCBlength, pdcb2->DCBlength, (DWORD)sizeof(DCB));
+	
+	/* Check all other DCB members */
+	check_dcb_member(BaudRate, "%lu");
+	check_dcb_member(fBinary, "%u");
+	check_dcb_member(fParity, "%u");
+	check_dcb_member(fOutxCtsFlow, "%u");
+	check_dcb_member(fOutxDsrFlow, "%u");
+	check_dcb_member(fParity, "%u");
+	check_dcb_member(fOutxCtsFlow, "%u");
+	check_dcb_member(fOutxDsrFlow, "%u");
+	check_dcb_member(fDtrControl, "%u");
+	check_dcb_member(fDsrSensitivity, "%u");
+	check_dcb_member(fTXContinueOnXoff, "%u");
+	check_dcb_member(fOutX, "%u");
+	check_dcb_member(fInX, "%u");
+	check_dcb_member(fErrorChar, "%u");
+	check_dcb_member(fNull, "%u");
+	check_dcb_member(fRtsControl, "%u");
+	check_dcb_member(fAbortOnError, "%u");
+	check_dcb_member(fDummy2, "%u");
+	check_dcb_member(wReserved, "%u");
+	check_dcb_member(XonLim, "%u");
+	check_dcb_member(XoffLim, "%u");
+	check_dcb_member(ByteSize, "%u");
+	check_dcb_member(Parity, "%u");
+	check_dcb_member(StopBits, "%u");
+	check_dcb_member(XonChar, "%d");
+	check_dcb_member(XoffChar, "%d");
+	check_dcb_member(ErrorChar, "%d");
+	check_dcb_member(EofChar, "%d");
+	check_dcb_member(EvtChar, "%d");
+	check_dcb_member(wReserved1, "%u");
+}
+
+#define check_timeouts_member(a) ok(ptimeouts1->a == ptimeouts2->a, "%s(\"%s\"), 0x%02x: "#a" is %lu, should be %lu", function, string, initial_value, ptimeouts1->a, ptimeouts2->a);
+
+void check_timeouts(char *function, char *string, int initial_value, COMMTIMEOUTS *ptimeouts1, COMMTIMEOUTS *ptimeouts2)
+{
+	check_timeouts_member(ReadIntervalTimeout);
+	check_timeouts_member(ReadTotalTimeoutMultiplier);
+	check_timeouts_member(ReadTotalTimeoutConstant);
+	check_timeouts_member(WriteTotalTimeoutMultiplier);
+	check_timeouts_member(WriteTotalTimeoutConstant);
+}
+
+void test_BuildCommDCBA(char* string, BOOL expected_result, DCB *pexpected_dcb, int initial_value)
+{
+	BOOL result;
+	DCB dcb;
+
+	/* set initial conditions */
+	memset(&dcb, initial_value, sizeof(DCB));
+	SetLastError(0xdeadbeef);
+
+	result = BuildCommDCBA(string, &dcb);
+
+	/* check results */
+	check_result("BuildCommDCBA", string, initial_value, result, expected_result);
+	check_dcb("BuildCommDCBA", string, initial_value, &dcb, pexpected_dcb);
+}
+
+void test_BuildCommDCBAndTimeoutsA(char* string, BOOL expected_result, DCB *pexpected_dcb, COMMTIMEOUTS *pexpected_timeouts, int initial_value)
+{
+	BOOL result;
+	DCB dcb;
+	COMMTIMEOUTS timeouts;
+
+	/* set initial conditions */
+	memset(&dcb, initial_value, sizeof(DCB));
+	memset(&timeouts, initial_value, sizeof(COMMTIMEOUTS));
+	SetLastError(0xdeadbeef);
+
+	result = BuildCommDCBAndTimeoutsA(string, &dcb, &timeouts);
+
+	/* check results */
+	check_result("BuildCommDCBAndTimeoutsA", string, initial_value, result, expected_result);
+	check_dcb("BuildCommDCBAndTimeoutsA", string, initial_value, &dcb, pexpected_dcb);
+	check_timeouts("BuildCommDCBAndTimeoutsA", string, initial_value, &timeouts, pexpected_timeouts);
+}
+
+void do_test(TEST *ptest)
+{
+	test_BuildCommDCBA(ptest->string, ptest->result, &ptest->dcb1, 0x00);
+	test_BuildCommDCBA(ptest->string, ptest->result, &ptest->dcb2, 0xFF);
+	test_BuildCommDCBAndTimeoutsA(ptest->string, ptest->result, &ptest->dcb1, &ptest->timeouts1, 0x00);
+	test_BuildCommDCBAndTimeoutsA(ptest->string, ptest->result, &ptest->dcb2, &ptest->timeouts2, 0xFF);
+}
+
+START_TEST(build_dcb)
+{
+	int i;
+
+	for(i = 0; i < TEST_COUNT; i++)
+		do_test(&test[i]);
+}
diff -urN wine-20030813/include/winbase.h wine-20030813.patched/include/winbase.h
--- wine-20030813/include/winbase.h	2003-08-23 23:12:51.000000000 -0400
+++ wine-20030813.patched/include/winbase.h	2003-09-08 20:19:39.000000000 -0400
@@ -976,6 +976,7 @@
     char ErrorChar;
     char EofChar;
     char EvtChar;
+    WORD wReserved1;
 } DCB, *LPDCB;
 
 typedef struct tagCOMMCONFIG {



More information about the wine-devel mailing list